* [PATCH 0/2] drm/msm/mdp4: fix intermittent blue screen on Galaxy S4
@ 2026-06-11 6:07 Alexandre MINETTE via B4 Relay
2026-06-11 6:07 ` [PATCH 1/2] drm/msm/mdp4: keep the bus clock enabled while a CRTC is active Alexandre MINETTE via B4 Relay
2026-06-11 6:07 ` [PATCH 2/2] drm/msm/mdp4: keep inherited display clocks enabled until modeset Alexandre MINETTE via B4 Relay
0 siblings, 2 replies; 6+ messages in thread
From: Alexandre MINETTE via B4 Relay @ 2026-06-11 6:07 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, phone-devel,
Alexandre MINETTE
This series fixes an intermittent blue screen seen on the Samsung
Galaxy S4 with the MDP4 display controller. The issue happens on roughly
half of boots.
The first patch keeps the AXI/bus clock enabled while a CRTC is active,
so scanout does not lose bus access while the display pipeline is still
running.
The second patch handles the case where firmware left the display
pipeline enabled before Linux takes over. In that case, the required
display clocks are kept enabled until the first DRM modeset, where the
driver takes ownership of the pipeline.
Tested on a Samsung Galaxy S4 GT-I9505, codename jflte.
Signed-off-by: Alexandre MINETTE <contact@alex-min.fr>
---
Alexandre MINETTE (2):
drm/msm/mdp4: keep the bus clock enabled while a CRTC is active
drm/msm/mdp4: keep inherited display clocks enabled until modeset
drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c | 3 +
drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 108 +++++++++++++++++++++++++++++-
drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h | 8 +++
3 files changed, 118 insertions(+), 1 deletion(-)
---
base-commit: acb7500801e98639f6d8c2d796ed9f64cba83d3a
change-id: 20260610-mainline-fix-mdp4-blue-screen-sending-v1-0637d7a6c355
Best regards,
--
Alexandre MINETTE <contact@alex-min.fr>
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 1/2] drm/msm/mdp4: keep the bus clock enabled while a CRTC is active 2026-06-11 6:07 [PATCH 0/2] drm/msm/mdp4: fix intermittent blue screen on Galaxy S4 Alexandre MINETTE via B4 Relay @ 2026-06-11 6:07 ` Alexandre MINETTE via B4 Relay 2026-06-11 7:51 ` Konrad Dybcio 2026-06-12 7:23 ` Dmitry Baryshkov 2026-06-11 6:07 ` [PATCH 2/2] drm/msm/mdp4: keep inherited display clocks enabled until modeset Alexandre MINETTE via B4 Relay 1 sibling, 2 replies; 6+ messages in thread From: Alexandre MINETTE via B4 Relay @ 2026-06-11 6:07 UTC (permalink / raw) To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, phone-devel, Alexandre MINETTE From: Alexandre MINETTE <contact@alex-min.fr> MDP4 scanout continues to fetch framebuffer data while the CRTC is active. Keep the AXI/bus clock enabled for the lifetime of each active CRTC so that temporary MDP4 disable paths do not gate the bus clock while scanout is still running. This avoids display corruption seen on the Samsung Galaxy S4 when the display pipeline is active. Signed-off-by: Alexandre MINETTE <contact@alex-min.fr> --- drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c | 2 ++ drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 42 +++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h | 6 +++++ 3 files changed, 50 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c index e8066f9fd534..9e53c9d956ca 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c @@ -271,6 +271,7 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc, mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err); mdp4_disable(mdp4_kms); + mdp4_crtc_bus_put(mdp4_kms); if (crtc->state->event && !crtc->state->active) { WARN_ON(mdp4_crtc->event); @@ -295,6 +296,7 @@ static void mdp4_crtc_atomic_enable(struct drm_crtc *crtc, return; mdp4_enable(mdp4_kms); + mdp4_crtc_bus_get(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 809ca191e9de..4c60b49fb784 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -118,6 +118,39 @@ static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate, } } +void mdp4_crtc_bus_get(struct mdp4_kms *mdp4_kms) +{ + int ret = 0; + + mutex_lock(&mdp4_kms->clock_lock); + + if (!mdp4_kms->crtc_bus_count) + ret = clk_prepare_enable(mdp4_kms->axi_clk); + + if (!ret) + mdp4_kms->crtc_bus_count++; + + mutex_unlock(&mdp4_kms->clock_lock); + + WARN_ON(ret); +} + +void mdp4_crtc_bus_put(struct mdp4_kms *mdp4_kms) +{ + mutex_lock(&mdp4_kms->clock_lock); + if (!mdp4_kms->crtc_bus_count) + goto unlock; + + mdp4_kms->crtc_bus_count--; + if (mdp4_kms->crtc_bus_count) + goto unlock; + + clk_disable_unprepare(mdp4_kms->axi_clk); + +unlock: + mutex_unlock(&mdp4_kms->clock_lock); +} + static void mdp4_destroy(struct msm_kms *kms) { struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); @@ -137,6 +170,13 @@ static void mdp4_destroy(struct msm_kms *kms) if (mdp4_kms->rpm_enabled) pm_runtime_disable(dev); + mutex_lock(&mdp4_kms->clock_lock); + if (mdp4_kms->crtc_bus_count) { + clk_disable_unprepare(mdp4_kms->axi_clk); + mdp4_kms->crtc_bus_count = 0; + } + mutex_unlock(&mdp4_kms->clock_lock); + mdp_kms_destroy(&mdp4_kms->base); } @@ -514,6 +554,8 @@ static int mdp4_probe(struct platform_device *pdev) if (!mdp4_kms) return -ENOMEM; + mutex_init(&mdp4_kms->clock_lock); + mdp4_kms->mmio = msm_ioremap(pdev, NULL); if (IS_ERR(mdp4_kms->mmio)) return PTR_ERR(mdp4_kms->mmio); diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h index 06458d4ee48c..86391d9bc55f 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h @@ -7,6 +7,8 @@ #ifndef __MDP4_KMS_H__ #define __MDP4_KMS_H__ +#include <linux/mutex.h> + #include <drm/drm_panel.h> #include "msm_drv.h" @@ -31,6 +33,8 @@ struct mdp4_kms { struct clk *pclk; struct clk *lut_clk; struct clk *axi_clk; + struct mutex clock_lock; + unsigned int crtc_bus_count; struct mdp_irq error_handler; @@ -148,6 +152,8 @@ static inline uint32_t mixercfg(uint32_t mixer_cfg, int mixer, int mdp4_disable(struct mdp4_kms *mdp4_kms); int mdp4_enable(struct mdp4_kms *mdp4_kms); +void mdp4_crtc_bus_get(struct mdp4_kms *mdp4_kms); +void mdp4_crtc_bus_put(struct mdp4_kms *mdp4_kms); void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask, uint32_t old_irqmask); -- 2.43.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] drm/msm/mdp4: keep the bus clock enabled while a CRTC is active 2026-06-11 6:07 ` [PATCH 1/2] drm/msm/mdp4: keep the bus clock enabled while a CRTC is active Alexandre MINETTE via B4 Relay @ 2026-06-11 7:51 ` Konrad Dybcio 2026-06-12 7:23 ` Dmitry Baryshkov 1 sibling, 0 replies; 6+ messages in thread From: Konrad Dybcio @ 2026-06-11 7:51 UTC (permalink / raw) To: contact, Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, phone-devel On 6/11/26 8:07 AM, Alexandre MINETTE via B4 Relay wrote: > From: Alexandre MINETTE <contact@alex-min.fr> > > MDP4 scanout continues to fetch framebuffer data while the CRTC is > active. Keep the AXI/bus clock enabled for the lifetime of each active > CRTC so that temporary MDP4 disable paths do not gate the bus clock > while scanout is still running. > > This avoids display corruption seen on the Samsung Galaxy S4 when the > display pipeline is active. > > Signed-off-by: Alexandre MINETTE <contact@alex-min.fr> > --- [...] > +void mdp4_crtc_bus_put(struct mdp4_kms *mdp4_kms) > +{ > + mutex_lock(&mdp4_kms->clock_lock); If you use guard(mutex)(&mdp4_kms->lock_lock), you can drop the manual _unlock() calls (the lock will be dropped once you exit the scope Konrad ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] drm/msm/mdp4: keep the bus clock enabled while a CRTC is active 2026-06-11 6:07 ` [PATCH 1/2] drm/msm/mdp4: keep the bus clock enabled while a CRTC is active Alexandre MINETTE via B4 Relay 2026-06-11 7:51 ` Konrad Dybcio @ 2026-06-12 7:23 ` Dmitry Baryshkov 1 sibling, 0 replies; 6+ messages in thread From: Dmitry Baryshkov @ 2026-06-12 7:23 UTC (permalink / raw) To: contact Cc: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel, phone-devel On Thu, Jun 11, 2026 at 08:07:46AM +0200, Alexandre MINETTE via B4 Relay wrote: > From: Alexandre MINETTE <contact@alex-min.fr> > > MDP4 scanout continues to fetch framebuffer data while the CRTC is > active. Keep the AXI/bus clock enabled for the lifetime of each active > CRTC so that temporary MDP4 disable paths do not gate the bus clock > while scanout is still running. > > This avoids display corruption seen on the Samsung Galaxy S4 when the > display pipeline is active. Please describe, when do you observe a corruption? > > Signed-off-by: Alexandre MINETTE <contact@alex-min.fr> > --- > drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c | 2 ++ > drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 42 +++++++++++++++++++++++++++++++ > drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h | 6 +++++ > 3 files changed, 50 insertions(+) > > diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c > index e8066f9fd534..9e53c9d956ca 100644 > --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c > +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c > @@ -271,6 +271,7 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc, > > mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err); > mdp4_disable(mdp4_kms); > + mdp4_crtc_bus_put(mdp4_kms); > > if (crtc->state->event && !crtc->state->active) { > WARN_ON(mdp4_crtc->event); > @@ -295,6 +296,7 @@ static void mdp4_crtc_atomic_enable(struct drm_crtc *crtc, > return; > > mdp4_enable(mdp4_kms); > + mdp4_crtc_bus_get(mdp4_kms); This is a bit suspicious. mdp4_enable() already votes on the AXI clock. As the CCF has enable count for each clock, it should be enough to keep the vote for as long as the CRTC is active. My only assumption would be that the CRTC scanout happens for some time even after the atomic_disable(), but without a description of the issue it's hard to determine the cause. > > /* Restore vblank irq handling after power is enabled */ > drm_crtc_vblank_on(crtc); > @@ -137,6 +170,13 @@ static void mdp4_destroy(struct msm_kms *kms) > if (mdp4_kms->rpm_enabled) > pm_runtime_disable(dev); > > + mutex_lock(&mdp4_kms->clock_lock); > + if (mdp4_kms->crtc_bus_count) { > + clk_disable_unprepare(mdp4_kms->axi_clk); > + mdp4_kms->crtc_bus_count = 0; > + } Is it not taken care by drm_atomic_helper_shutdown()? > + mutex_unlock(&mdp4_kms->clock_lock); > + > mdp_kms_destroy(&mdp4_kms->base); > } > -- With best wishes Dmitry ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] drm/msm/mdp4: keep inherited display clocks enabled until modeset 2026-06-11 6:07 [PATCH 0/2] drm/msm/mdp4: fix intermittent blue screen on Galaxy S4 Alexandre MINETTE via B4 Relay 2026-06-11 6:07 ` [PATCH 1/2] drm/msm/mdp4: keep the bus clock enabled while a CRTC is active Alexandre MINETTE via B4 Relay @ 2026-06-11 6:07 ` Alexandre MINETTE via B4 Relay 2026-06-12 7:27 ` Dmitry Baryshkov 1 sibling, 1 reply; 6+ messages in thread From: Alexandre MINETTE via B4 Relay @ 2026-06-11 6:07 UTC (permalink / raw) To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, phone-devel, Alexandre MINETTE From: Alexandre MINETTE <contact@alex-min.fr> 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@alex-min.fr> --- 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); + + 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); + + inherited_display = mdp4_has_inherited_display_state(mdp4_kms); + + if (inherited_display) { + clk_prepare_enable(mdp4_kms->clk); + clk_prepare_enable(mdp4_kms->lut_clk); + mdp4_kms->inherited_display_clocks_held = true; + } + + clk_disable_unprepare(mdp4_kms->clk); + clk_disable_unprepare(mdp4_kms->pclk); + clk_disable_unprepare(mdp4_kms->lut_clk); + clk_disable_unprepare(mdp4_kms->axi_clk); + + mutex_unlock(&mdp4_kms->clock_lock); +} + +void mdp4_inherited_display_clocks_put(struct mdp4_kms *mdp4_kms) +{ + mutex_lock(&mdp4_kms->clock_lock); + if (!mdp4_kms->inherited_display_clocks_held) + goto unlock; + + clk_disable_unprepare(mdp4_kms->clk); + clk_disable_unprepare(mdp4_kms->lut_clk); + mdp4_kms->inherited_display_clocks_held = false; + +unlock: + mutex_unlock(&mdp4_kms->clock_lock); +} + static void mdp4_destroy(struct msm_kms *kms) { struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); @@ -171,6 +223,11 @@ static void mdp4_destroy(struct msm_kms *kms) pm_runtime_disable(dev); mutex_lock(&mdp4_kms->clock_lock); + if (mdp4_kms->inherited_display_clocks_held) { + clk_disable_unprepare(mdp4_kms->clk); + clk_disable_unprepare(mdp4_kms->lut_clk); + mdp4_kms->inherited_display_clocks_held = false; + } if (mdp4_kms->crtc_bus_count) { clk_disable_unprepare(mdp4_kms->axi_clk); mdp4_kms->crtc_bus_count = 0; @@ -549,6 +606,7 @@ static int mdp4_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct mdp4_kms *mdp4_kms; int irq; + int ret; mdp4_kms = devm_kzalloc(dev, sizeof(*mdp4_kms), GFP_KERNEL); if (!mdp4_kms) @@ -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) diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h index 86391d9bc55f..289b5b476d99 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h @@ -34,6 +34,7 @@ struct mdp4_kms { struct clk *lut_clk; struct clk *axi_clk; struct mutex clock_lock; + bool inherited_display_clocks_held; unsigned int crtc_bus_count; struct mdp_irq error_handler; @@ -152,6 +153,7 @@ static inline uint32_t mixercfg(uint32_t mixer_cfg, int mixer, int mdp4_disable(struct mdp4_kms *mdp4_kms); int mdp4_enable(struct mdp4_kms *mdp4_kms); +void mdp4_inherited_display_clocks_put(struct mdp4_kms *mdp4_kms); void mdp4_crtc_bus_get(struct mdp4_kms *mdp4_kms); void mdp4_crtc_bus_put(struct mdp4_kms *mdp4_kms); -- 2.43.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] drm/msm/mdp4: keep inherited display clocks enabled until modeset 2026-06-11 6:07 ` [PATCH 2/2] drm/msm/mdp4: keep inherited display clocks enabled until modeset Alexandre MINETTE via B4 Relay @ 2026-06-12 7:27 ` Dmitry Baryshkov 0 siblings, 0 replies; 6+ messages in thread From: Dmitry Baryshkov @ 2026-06-12 7:27 UTC (permalink / raw) To: contact Cc: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel, phone-devel On Thu, Jun 11, 2026 at 08:07:47AM +0200, Alexandre MINETTE via B4 Relay wrote: > From: Alexandre MINETTE <contact@alex-min.fr> > > 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@alex-min.fr> > --- > 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 ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-06-12 7:27 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-06-11 6:07 [PATCH 0/2] drm/msm/mdp4: fix intermittent blue screen on Galaxy S4 Alexandre MINETTE via B4 Relay 2026-06-11 6:07 ` [PATCH 1/2] drm/msm/mdp4: keep the bus clock enabled while a CRTC is active Alexandre MINETTE via B4 Relay 2026-06-11 7:51 ` Konrad Dybcio 2026-06-12 7:23 ` Dmitry Baryshkov 2026-06-11 6:07 ` [PATCH 2/2] drm/msm/mdp4: keep inherited display clocks enabled until modeset Alexandre MINETTE via B4 Relay 2026-06-12 7:27 ` Dmitry Baryshkov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®