From c8d3d795dd40c7fb35b39ebcb99ae5f2f1884b48 Mon Sep 17 00:00:00 2001 From: Hsin-Te Yuan Date: Mon, 3 Aug 2026 17:47:19 +0800 Subject: [PATCH] drm/panel-edp: Add pre_unprepare delay In eDP power-off timing specifications, T10 defines the minimum delay required between the end of valid video data from the source and panel power-down (main VDD off). Currently, panel-edp only supports the 'disable' delay, which corresponds to T9 (backlight off to end of video data) and runs in panel_edp_disable() while video data is still active. For panels that require a delay after video data has stopped before cutting power, this delay must occur in panel_edp_unprepare() before turning off power rails. Add a 'pre_unprepare' field to struct panel_delay to model T10-min, and delay for this duration in panel_edp_unprepare() before calling pm_runtime_put_sync_suspend(). Additionally, adjust the timing entry for TM156VDXP25 to use delay_200_500_e80_pu100 (enable = 80ms, pre_unprepare = 100ms) to match its panel specification, replacing the previous delay_200_500_e50_d100. Fixes: b9e2d5cdaab0 ("drm/panel-edp: Support NV140FHM-N5B and TM156VDXP25") Signed-off-by: Hsin-Te Yuan Reviewed-by: Douglas Anderson Signed-off-by: Douglas Anderson Link: https://patch.msgid.link/20260803-edp-v1-1-3e92dec1d56c@chromium.org --- drivers/gpu/drm/panel/panel-edp.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index 3aa51ad21305..2b455369ed70 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -144,6 +144,16 @@ struct panel_delay { */ unsigned int disable; + /** + * @pre_unprepare: Time for the end of video data to power off. + * + * The time (in milliseconds) that it needs to have passed between + * the end of valid video data from source and start powering off. + * + * This is T10-min on eDP timing diagrams. It is not common to set. + */ + unsigned int pre_unprepare; + /** * @unprepare: Time to power down completely. * @@ -413,8 +423,12 @@ static int panel_edp_suspend(struct device *dev) static int panel_edp_unprepare(struct drm_panel *panel) { + struct panel_edp *p = to_panel_edp(panel); int ret; + if (p->desc->delay.pre_unprepare) + msleep(p->desc->delay.pre_unprepare); + ret = pm_runtime_put_sync_suspend(panel->dev); if (ret < 0) return ret; @@ -1810,6 +1824,13 @@ static const struct panel_delay delay_80_500_e80_p2e200 = { .prepare_to_enable = 200, }; +static const struct panel_delay delay_200_500_e80_pu100 = { + .hpd_absent = 200, + .unprepare = 500, + .enable = 80, + .pre_unprepare = 100, +}; + static const struct panel_delay delay_100_500_e200 = { .hpd_absent = 100, .unprepare = 500, @@ -2182,7 +2203,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('T', 'M', 'A', 0x0811, &delay_200_500_e80_d50, "TM140VDXP01-04"), EDP_PANEL_ENTRY('T', 'M', 'A', 0x2094, &delay_200_500_e50_d100, "TL140VDMS03-01"), - EDP_PANEL_ENTRY('T', 'M', 'A', 0x2139, &delay_200_500_e50_d100, "TM156VDXP25"), + EDP_PANEL_ENTRY('T', 'M', 'A', 0x2139, &delay_200_500_e80_pu100, "TM156VDXP25"), { /* sentinal */ } };