From: Linus Walleij linus.walleij@linaro.org
stable inclusion from stable-v5.10.44 commit 5a61f69da3b8d735b01dddee72fee4671510d907 bugzilla: https://bugzilla.openeuler.org/show_bug.cgi?id=402 CVE: NA
-------------------------------------------------
commit c8a570443943304cac2e4186dbce6989b6c2b8b5 upstream.
The calclulation of how many bytes we stuff into the DSI pipeline for video mode panels is off by three orders of magnitude because we did not account for the fact that the DRM mode clock is in kilohertz rather than hertz.
This used to be: drm_mode_vrefresh(mode) * mode->htotal * mode->vtotal which would become for example for s6e63m0: 60 x 514 x 831 = 25628040 Hz, but mode->clock is 25628 as it is in kHz.
This affects only the Samsung GT-I8190 "Golden" phone right now since it is the only MCDE device with a video mode display.
Curiously some specimen work with this code and wild settings in the EOL and empty packets at the end of the display, but I have noticed an eeire flicker until now. Others were not so lucky and got black screens.
Cc: Ville Syrjälä ville.syrjala@linux.intel.com Reported-by: Stephan Gerhold stephan@gerhold.net Fixes: 920dd1b1425b ("drm/mcde: Use mode->clock instead of reverse calculating it from the vrefresh") Signed-off-by: Linus Walleij linus.walleij@linaro.org Tested-by: Stephan Gerhold stephan@gerhold.net Reviewed-by: Stephan Gerhold stephan@gerhold.net Link: https://patchwork.freedesktop.org/patch/msgid/20210608213318.3897858-1-linus... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Jiaoyu 895515570@qq.com --- drivers/gpu/drm/mcde/mcde_dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c index b3fd3501c412..5275b2723293 100644 --- a/drivers/gpu/drm/mcde/mcde_dsi.c +++ b/drivers/gpu/drm/mcde/mcde_dsi.c @@ -577,7 +577,7 @@ static void mcde_dsi_setup_video_mode(struct mcde_dsi *d, * porches and sync. */ /* (ps/s) / (pixels/s) = ps/pixels */ - pclk = DIV_ROUND_UP_ULL(1000000000000, mode->clock); + pclk = DIV_ROUND_UP_ULL(1000000000000, (mode->clock * 1000)); dev_dbg(d->dev, "picoseconds between two pixels: %llu\n", pclk);