Accessing registers for an unclocked block is an insta-reboot on snapdragon devices. So add a bit of logic to track the enable_count so we can WARN_ON() unclocked register writes. This makes it much easier to track down mistakes.
Signed-off-by: Rob Clark robdclark@gmail.com --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 5 +++++ drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 4 ++++ 2 files changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index d3d6b4c..1189128 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -249,6 +249,9 @@ int mdp5_disable(struct mdp5_kms *mdp5_kms) { DBG("");
+ mdp5_kms->enable_count--; + WARN_ON(mdp5_kms->enable_count < 0); + clk_disable_unprepare(mdp5_kms->ahb_clk); clk_disable_unprepare(mdp5_kms->axi_clk); clk_disable_unprepare(mdp5_kms->core_clk); @@ -262,6 +265,8 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms) { DBG("");
+ mdp5_kms->enable_count++; + clk_prepare_enable(mdp5_kms->ahb_clk); clk_prepare_enable(mdp5_kms->axi_clk); clk_prepare_enable(mdp5_kms->core_clk); diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index 8bdb7ee..c78faf0 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -80,6 +80,8 @@ struct mdp5_kms { bool rpm_enabled;
struct mdp_irq error_handler; + + int enable_count; }; #define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base)
@@ -171,11 +173,13 @@ struct mdp5_encoder {
static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data) { + WARN_ON(mdp5_kms->enable_count <= 0); msm_writel(data, mdp5_kms->mmio + reg); }
static inline u32 mdp5_read(struct mdp5_kms *mdp5_kms, u32 reg) { + WARN_ON(mdp5_kms->enable_count <= 0); return msm_readl(mdp5_kms->mmio + reg); }
Fixes an insta-reboot when screen-blanking kicks in, due to cursor updates without clocks enabled.
Signed-off-by: Rob Clark robdclark@gmail.com --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 9217e0d..41a0775 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -751,6 +751,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, if (!handle) { DBG("Cursor off"); cursor_enable = false; + mdp5_enable(mdp5_kms); goto set_cursor; }
@@ -774,6 +775,8 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
get_roi(crtc, &roi_w, &roi_h);
+ mdp5_enable(mdp5_kms); + mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_STRIDE(lm), stride); mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_FORMAT(lm), MDP5_LM_CURSOR_FORMAT_FORMAT(CURSOR_FMT_ARGB8888)); @@ -802,6 +805,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, crtc_flush(crtc, flush_mask);
end: + mdp5_disable(mdp5_kms); if (old_bo) { drm_flip_work_queue(&mdp5_crtc->unref_cursor_work, old_bo); /* enable vblank to complete cursor work: */ @@ -834,6 +838,8 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
get_roi(crtc, &roi_w, &roi_h);
+ mdp5_enable(mdp5_kms); + spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags); mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(lm), MDP5_LM_CURSOR_SIZE_ROI_H(roi_h) | @@ -845,6 +851,8 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
crtc_flush(crtc, flush_mask);
+ mdp5_disable(mdp5_kms); + return 0; }
dri-devel@lists.freedesktop.org