drm/msm: dpu: Move crtc runtime resume to encoder
authorSean Paul <seanpaul@chromium.org>
Fri, 16 Nov 2018 18:42:22 +0000 (13:42 -0500)
committerRob Clark <robdclark@gmail.com>
Tue, 11 Dec 2018 18:10:11 +0000 (13:10 -0500)
The crtc runtime resume doesn't actually operate on the crtc, but rather
its encoders. The problem with this is that we need to inspect the crtc
state to get the currently connected encoders. Since runtime resume
isn't guaranteed to be called while holding the modeset locks (although
it sometimes is), this presents a race condition.

Now that we have ->enabled on the virtual encoders, and a lock to
protect it, just call resume on each encoder and only restore the ones
that are enabled.

Changes in v2:
- None

Cc: Jeykumar Sankaran <jsanka@codeaurora.org>
Reviewed-by: Jeykumar Sankaran <jsanka@codeaurora.org>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c

index 61449e3..44bd3b8 100644 (file)
@@ -857,30 +857,6 @@ static struct drm_crtc_state *dpu_crtc_duplicate_state(struct drm_crtc *crtc)
        return &cstate->base;
 }
 
-void dpu_crtc_runtime_resume(struct drm_crtc *crtc)
-{
-       struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
-       struct drm_encoder *encoder;
-
-       mutex_lock(&dpu_crtc->crtc_lock);
-
-       if (!dpu_crtc->enabled)
-               goto end;
-
-       trace_dpu_crtc_runtime_resume(DRMID(crtc));
-
-       /* restore encoder; crtc will be programmed during commit */
-       drm_for_each_encoder(encoder, crtc->dev) {
-               if (encoder->crtc != crtc)
-                       continue;
-
-               dpu_encoder_virt_restore(encoder);
-       }
-
-end:
-       mutex_unlock(&dpu_crtc->crtc_lock);
-}
-
 static void dpu_crtc_disable(struct drm_crtc *crtc)
 {
        struct dpu_crtc *dpu_crtc;
index d5cd7a0..7617132 100644 (file)
@@ -330,10 +330,4 @@ static inline bool dpu_crtc_is_enabled(struct drm_crtc *crtc)
        return crtc ? crtc->enabled : false;
 }
 
-/**
- * dpu_crtc_runtime_resume - called by the top-level on pm_runtime_resume
- * @crtc: CRTC to resume
- */
-void dpu_crtc_runtime_resume(struct drm_crtc *crtc);
-
 #endif /* _DPU_CRTC_H_ */
index c1b32ef..83b25a1 100644 (file)
@@ -1089,28 +1089,24 @@ static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc)
        _dpu_encoder_update_vsync_source(dpu_enc, &dpu_enc->disp_info);
 }
 
-void dpu_encoder_virt_restore(struct drm_encoder *drm_enc)
+void dpu_encoder_virt_runtime_resume(struct drm_encoder *drm_enc)
 {
-       struct dpu_encoder_virt *dpu_enc = NULL;
-       int i;
-
-       if (!drm_enc) {
-               DPU_ERROR("invalid encoder\n");
-               return;
-       }
-       dpu_enc = to_dpu_encoder_virt(drm_enc);
+       struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
 
-       for (i = 0; i < dpu_enc->num_phys_encs; i++) {
-               struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+       mutex_lock(&dpu_enc->enc_lock);
 
-               if (phys && (phys != dpu_enc->cur_master) && phys->ops.restore)
-                       phys->ops.restore(phys);
-       }
+       if (!dpu_enc->enabled)
+               goto out;
 
+       if (dpu_enc->cur_slave && dpu_enc->cur_slave->ops.restore)
+               dpu_enc->cur_slave->ops.restore(dpu_enc->cur_slave);
        if (dpu_enc->cur_master && dpu_enc->cur_master->ops.restore)
                dpu_enc->cur_master->ops.restore(dpu_enc->cur_master);
 
        _dpu_encoder_virt_enable_helper(drm_enc);
+
+out:
+       mutex_unlock(&dpu_enc->enc_lock);
 }
 
 static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc)
index c204412..c9ebdf6 100644 (file)
@@ -128,10 +128,10 @@ int dpu_encoder_wait_for_event(struct drm_encoder *drm_encoder,
 enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder);
 
 /**
- * dpu_encoder_virt_restore - restore the encoder configs
+ * dpu_encoder_virt_runtime_resume - pm runtime resume the encoder configs
  * @encoder:   encoder pointer
  */
-void dpu_encoder_virt_restore(struct drm_encoder *encoder);
+void dpu_encoder_virt_runtime_resume(struct drm_encoder *encoder);
 
 /**
  * dpu_encoder_init - initialize virtual encoder object
index 610845b..606b284 100644 (file)
@@ -1133,7 +1133,7 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev)
        int rc = -1;
        struct platform_device *pdev = to_platform_device(dev);
        struct dpu_kms *dpu_kms = platform_get_drvdata(pdev);
-       struct drm_crtc *crtc;
+       struct drm_encoder *encoder;
        struct drm_device *ddev;
        struct dss_module_power *mp = &dpu_kms->mp;
 
@@ -1151,8 +1151,8 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev)
 
        dpu_vbif_init_memtypes(dpu_kms);
 
-       drm_for_each_crtc(crtc, ddev)
-               dpu_crtc_runtime_resume(crtc);
+       drm_for_each_encoder(encoder, ddev)
+               dpu_encoder_virt_runtime_resume(encoder);
 
        return rc;
 }