Re: [PATCH 2/2] drm/msm/mdp4: keep inherited display clocks enabled until modeset

From: Dmitry Baryshkov

Date: Fri Jun 12 2026 - 03:28:51 EST


On Thu, Jun 11, 2026 at 08:07:47AM +0200, Alexandre MINETTE via B4 Relay wrote:
> From: Alexandre MINETTE <contact@xxxxxxxxxxx>
>
> Some devices boot with the MDP4 display pipeline already enabled by
> firmware. On the Samsung Galaxy S4, disabling clocks used by that
> inherited pipeline before DRM takes over can leave the panel showing a
> blue screen.
>
> Keep the required display clocks prepared when an inherited
> DSI/LCDC/DTV enable state is detected, and drop the extra clock
> references on the first DRM CRTC enable. At that point the driver owns
> the display pipeline.
>
> Signed-off-by: Alexandre MINETTE <contact@xxxxxxxxxxx>
> ---
> drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c | 1 +
> drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 66 ++++++++++++++++++++++++++++++-
> drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h | 2 +
> 3 files changed, 68 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
> index 9e53c9d956ca..0aeefd48be1f 100644
> --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
> @@ -297,6 +297,7 @@ static void mdp4_crtc_atomic_enable(struct drm_crtc *crtc,
>
> mdp4_enable(mdp4_kms);
> mdp4_crtc_bus_get(mdp4_kms);
> + mdp4_inherited_display_clocks_put(mdp4_kms);
>
> /* Restore vblank irq handling after power is enabled */
> drm_crtc_vblank_on(crtc);
> diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
> index 4c60b49fb784..1264ce7e8459 100644
> --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
> +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
> @@ -151,6 +151,58 @@ void mdp4_crtc_bus_put(struct mdp4_kms *mdp4_kms)
> mutex_unlock(&mdp4_kms->clock_lock);
> }
>
> +static bool mdp4_has_inherited_display_state(struct mdp4_kms *mdp4_kms)
> +{
> + return mdp4_read(mdp4_kms, REG_MDP4_DSI_ENABLE) ||
> + mdp4_read(mdp4_kms, REG_MDP4_LCDC_ENABLE) ||
> + mdp4_read(mdp4_kms, REG_MDP4_DTV_ENABLE);
> +}
> +
> +/*
> + * If firmware left MDP4 scanout enabled, preserve the core/LUT clocks until
> + * the first DRM CRTC enable takes ownership of the display pipeline.
> + */
> +static void mdp4_inherited_display_clocks_get(struct mdp4_kms *mdp4_kms)
> +{
> + bool inherited_display;
> +
> + mutex_lock(&mdp4_kms->clock_lock);

Please use guard(mutex)(...);

> +
> + clk_prepare_enable(mdp4_kms->clk);
> + clk_prepare_enable(mdp4_kms->pclk);
> + clk_prepare_enable(mdp4_kms->lut_clk);
> + clk_prepare_enable(mdp4_kms->axi_clk);
> +
> @@ -594,7 +652,13 @@ static int mdp4_probe(struct platform_device *pdev)
> if (IS_ERR(mdp4_kms->lut_clk))
> return dev_err_probe(dev, PTR_ERR(mdp4_kms->lut_clk), "failed to get lut_clk\n");
>
> - return msm_drv_probe(&pdev->dev, mdp4_kms_init, &mdp4_kms->base.base);
> + mdp4_inherited_display_clocks_get(mdp4_kms);
> +
> + ret = msm_drv_probe(&pdev->dev, mdp4_kms_init, &mdp4_kms->base.base);
> + if (ret)
> + mdp4_inherited_display_clocks_put(mdp4_kms);
> +
> + return ret;
> }
>
> static void mdp4_remove(struct platform_device *pdev)

The clocks should also be put in the mdp4_remove() path.


--
With best wishes
Dmitry