drm/i915/psr: Always wait for idle state when disabling PSR
authorJosé Roberto de Souza <jose.souza@intel.com>
Tue, 6 Nov 2018 19:08:41 +0000 (11:08 -0800)
committerJosé Roberto de Souza <jose.souza@intel.com>
Fri, 9 Nov 2018 18:49:38 +0000 (10:49 -0800)
It should always wait for idle state when disabling PSR because PSR
could be inactive due a call to intel_psr_exit() and while PSR is
still being disabled asynchronously userspace could change the
modeset causing a call to psr_disable() that will not wait for PSR
idle and then PSR will be enabled again while PSR is still not idle.

v2: rebased on top of the patch reusing psr_exit()

Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Reviewed-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181106190843.18009-2-jose.souza@intel.com
drivers/gpu/drm/i915/intel_psr.c

index 2ecc2db..81ec317 100644 (file)
@@ -661,8 +661,12 @@ static void intel_psr_exit(struct drm_i915_private *dev_priv)
 {
        u32 val;
 
-       if (!dev_priv->psr.active)
+       if (!dev_priv->psr.active) {
+               if (INTEL_GEN(dev_priv) >= 9)
+                       WARN_ON(I915_READ(EDP_PSR2_CTL) & EDP_PSR2_ENABLE);
+               WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE);
                return;
+       }
 
        if (dev_priv->psr.psr2_enabled) {
                val = I915_READ(EDP_PSR2_CTL);
@@ -680,32 +684,23 @@ static void
 intel_psr_disable_source(struct intel_dp *intel_dp)
 {
        struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+       i915_reg_t psr_status;
+       u32 psr_status_mask;
 
-       if (dev_priv->psr.active) {
-               i915_reg_t psr_status;
-               u32 psr_status_mask;
-
-               intel_psr_exit(dev_priv);
+       intel_psr_exit(dev_priv);
 
-               if (dev_priv->psr.psr2_enabled) {
-                       psr_status = EDP_PSR2_STATUS;
-                       psr_status_mask = EDP_PSR2_STATUS_STATE_MASK;
-               } else {
-                       psr_status = EDP_PSR_STATUS;
-                       psr_status_mask = EDP_PSR_STATUS_STATE_MASK;
-               }
-
-               /* Wait till PSR is idle */
-               if (intel_wait_for_register(dev_priv,
-                                           psr_status, psr_status_mask, 0,
-                                           2000))
-                       DRM_ERROR("Timed out waiting for PSR Idle State\n");
+       if (dev_priv->psr.psr2_enabled) {
+               psr_status = EDP_PSR2_STATUS;
+               psr_status_mask = EDP_PSR2_STATUS_STATE_MASK;
        } else {
-               if (dev_priv->psr.psr2_enabled)
-                       WARN_ON(I915_READ(EDP_PSR2_CTL) & EDP_PSR2_ENABLE);
-               else
-                       WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE);
+               psr_status = EDP_PSR_STATUS;
+               psr_status_mask = EDP_PSR_STATUS_STATE_MASK;
        }
+
+       /* Wait till PSR is idle */
+       if (intel_wait_for_register(dev_priv, psr_status, psr_status_mask, 0,
+                                   2000))
+               DRM_ERROR("Timed out waiting PSR idle state\n");
 }
 
 static void intel_psr_disable_locked(struct intel_dp *intel_dp)