]> git.itanic.dy.fi Git - linux-stable/commitdiff
drm/i915/display: Wait PSR2 get out of deep sleep to update pipe
authorJosé Roberto de Souza <jose.souza@intel.com>
Tue, 5 Oct 2021 23:18:51 +0000 (16:18 -0700)
committerJosé Roberto de Souza <jose.souza@intel.com>
Tue, 26 Oct 2021 17:30:51 +0000 (10:30 -0700)
Alderlake-P was getting 'max time under evasion' messages when PSR2
is enabled, this is due PIPE_SCANLINE/PIPEDSL returning 0 over a
period of time longer than VBLANK_EVASION_TIME_US.

For PSR1 we had the same issue so intel_psr_wait_for_idle() was
implemented to wait for PSR1 to get into idle state but nothing was
done for PSR2.

For PSR2 we can't only wait for idle state as PSR2 tends to keep
into sleep state(ready to send selective updates).
Waiting for any state below deep sleep proved to be effective in
avoiding the evasion messages and also not wasted a lot of time.

v2:
- dropping the additional wait_for loops, only the _wait_for_atomic()
is necessary
- waiting for states below EDP_PSR2_STATUS_STATE_DEEP_SLEEP

v3:
- dropping intel_wait_for_condition_atomic() function

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Reviewed-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211005231851.67698-1-jose.souza@intel.com
drivers/gpu/drm/i915/display/intel_display_debugfs.c
drivers/gpu/drm/i915/display/intel_psr.c
drivers/gpu/drm/i915/i915_reg.h

index e04767695530df571c96346afca36cba5d1d8e96..d7d6dde518a31eb8a6df2509b83edc1a32dd2e32 100644 (file)
@@ -303,8 +303,7 @@ psr_source_status(struct intel_dp *intel_dp, struct seq_file *m)
                };
                val = intel_de_read(dev_priv,
                                    EDP_PSR2_STATUS(intel_dp->psr.transcoder));
-               status_val = (val & EDP_PSR2_STATUS_STATE_MASK) >>
-                             EDP_PSR2_STATUS_STATE_SHIFT;
+               status_val = REG_FIELD_GET(EDP_PSR2_STATUS_STATE_MASK, val);
                if (status_val < ARRAY_SIZE(live_status))
                        status = live_status[status_val];
        } else {
index ccffe05784d3c9cab5a2860d136c81ee659723ca..d35db50ef967a8ce01359ed3b7b19a8e9cd41cb9 100644 (file)
@@ -1813,15 +1813,21 @@ void intel_psr_post_plane_update(const struct intel_atomic_state *state)
                _intel_psr_post_plane_update(state, crtc_state);
 }
 
-/**
- * psr_wait_for_idle - wait for PSR1 to idle
- * @intel_dp: Intel DP
- * @out_value: PSR status in case of failure
- *
- * Returns: 0 on success or -ETIMEOUT if PSR status does not idle.
- *
- */
-static int psr_wait_for_idle(struct intel_dp *intel_dp, u32 *out_value)
+static int _psr2_ready_for_pipe_update_locked(struct intel_dp *intel_dp)
+{
+       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+
+       /*
+        * Any state lower than EDP_PSR2_STATUS_STATE_DEEP_SLEEP is enough.
+        * As all higher states has bit 4 of PSR2 state set we can just wait for
+        * EDP_PSR2_STATUS_STATE_DEEP_SLEEP to be cleared.
+        */
+       return intel_de_wait_for_clear(dev_priv,
+                                      EDP_PSR2_STATUS(intel_dp->psr.transcoder),
+                                      EDP_PSR2_STATUS_STATE_DEEP_SLEEP, 50);
+}
+
+static int _psr1_ready_for_pipe_update_locked(struct intel_dp *intel_dp)
 {
        struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
@@ -1831,15 +1837,13 @@ static int psr_wait_for_idle(struct intel_dp *intel_dp, u32 *out_value)
         * exit training time + 1.5 ms of aux channel handshake. 50 ms is
         * defensive enough to cover everything.
         */
-       return __intel_wait_for_register(&dev_priv->uncore,
-                                        EDP_PSR_STATUS(intel_dp->psr.transcoder),
-                                        EDP_PSR_STATUS_STATE_MASK,
-                                        EDP_PSR_STATUS_STATE_IDLE, 2, 50,
-                                        out_value);
+       return intel_de_wait_for_clear(dev_priv,
+                                      EDP_PSR_STATUS(intel_dp->psr.transcoder),
+                                      EDP_PSR_STATUS_STATE_MASK, 50);
 }
 
 /**
- * intel_psr_wait_for_idle - wait for PSR1 to idle
+ * intel_psr_wait_for_idle - wait for PSR be ready for a pipe update
  * @new_crtc_state: new CRTC state
  *
  * This function is expected to be called from pipe_update_start() where it is
@@ -1856,19 +1860,23 @@ void intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state)
        for_each_intel_encoder_mask_with_psr(&dev_priv->drm, encoder,
                                             new_crtc_state->uapi.encoder_mask) {
                struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-               u32 psr_status;
+               int ret;
 
                mutex_lock(&intel_dp->psr.lock);
-               if (!intel_dp->psr.enabled || intel_dp->psr.psr2_enabled) {
+
+               if (!intel_dp->psr.enabled) {
                        mutex_unlock(&intel_dp->psr.lock);
                        continue;
                }
 
-               /* when the PSR1 is enabled */
-               if (psr_wait_for_idle(intel_dp, &psr_status))
-                       drm_err(&dev_priv->drm,
-                               "PSR idle timed out 0x%x, atomic update may fail\n",
-                               psr_status);
+               if (intel_dp->psr.psr2_enabled)
+                       ret = _psr2_ready_for_pipe_update_locked(intel_dp);
+               else
+                       ret = _psr1_ready_for_pipe_update_locked(intel_dp);
+
+               if (ret)
+                       drm_err(&dev_priv->drm, "PSR wait timed out, atomic update may fail\n");
+
                mutex_unlock(&intel_dp->psr.lock);
        }
 }
index d9f7a729333fa0efed5a49a6ae81a9887f7e5cac..7c97bc352497d08dd574a36cb7006d6186b8e1b8 100644 (file)
@@ -4698,11 +4698,11 @@ enum {
 #define  PSR_EVENT_LPSP_MODE_EXIT              (1 << 1)
 #define  PSR_EVENT_PSR_DISABLE                 (1 << 0)
 
-#define _PSR2_STATUS_A                 0x60940
-#define _PSR2_STATUS_EDP               0x6f940
-#define EDP_PSR2_STATUS(tran)          _MMIO_TRANS2(tran, _PSR2_STATUS_A)
-#define EDP_PSR2_STATUS_STATE_MASK     (0xf << 28)
-#define EDP_PSR2_STATUS_STATE_SHIFT    28
+#define _PSR2_STATUS_A                         0x60940
+#define _PSR2_STATUS_EDP                       0x6f940
+#define EDP_PSR2_STATUS(tran)                  _MMIO_TRANS2(tran, _PSR2_STATUS_A)
+#define EDP_PSR2_STATUS_STATE_MASK             REG_GENMASK(31, 28)
+#define EDP_PSR2_STATUS_STATE_DEEP_SLEEP       REG_FIELD_PREP(EDP_PSR2_STATUS_STATE_MASK, 0x8)
 
 #define _PSR2_SU_STATUS_A              0x60914
 #define _PSR2_SU_STATUS_EDP            0x6f914