void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state)
 {
        struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+       struct intel_encoder *encoder;
 
        if (!crtc_state->enable_psr2_sel_fetch)
                return;
 
+       for_each_intel_encoder_mask_with_psr(&dev_priv->drm, encoder,
+                                            crtc_state->uapi.encoder_mask) {
+               struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+               lockdep_assert_held(&intel_dp->psr.lock);
+               break;
+       }
+
        intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(crtc_state->cpu_transcoder),
                       crtc_state->psr2_man_track_ctl);
 }
 }
 
 /**
- * intel_psr_wait_for_idle - wait for PSR be ready for a pipe update
+ * intel_psr_wait_for_idle_locked - 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
  * not expected to race with PSR enable or disable.
  */
-void intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state)
+void intel_psr_wait_for_idle_locked(const struct intel_crtc_state *new_crtc_state)
 {
        struct drm_i915_private *dev_priv = to_i915(new_crtc_state->uapi.crtc->dev);
        struct intel_encoder *encoder;
                struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
                int ret;
 
-               mutex_lock(&intel_dp->psr.lock);
+               lockdep_assert_held(&intel_dp->psr.lock);
 
-               if (!intel_dp->psr.enabled) {
-                       mutex_unlock(&intel_dp->psr.lock);
+               if (!intel_dp->psr.enabled)
                        continue;
-               }
 
                if (intel_dp->psr.psr2_enabled)
                        ret = _psr2_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);
        }
 }
 
 
        return ret;
 }
+
+/**
+ * intel_psr_lock - grab PSR lock
+ * @crtc_state: the crtc state
+ *
+ * This is initially meant to be used by around CRTC update, when
+ * vblank sensitive registers are updated and we need grab the lock
+ * before it to avoid vblank evasion.
+ */
+void intel_psr_lock(const struct intel_crtc_state *crtc_state)
+{
+       struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+       struct intel_encoder *encoder;
+
+       if (!crtc_state->has_psr)
+               return;
+
+       for_each_intel_encoder_mask_with_psr(&i915->drm, encoder,
+                                            crtc_state->uapi.encoder_mask) {
+               struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+               mutex_lock(&intel_dp->psr.lock);
+               break;
+       }
+}
+
+/**
+ * intel_psr_unlock - release PSR lock
+ * @crtc_state: the crtc state
+ *
+ * Release the PSR lock that was held during pipe update.
+ */
+void intel_psr_unlock(const struct intel_crtc_state *crtc_state)
+{
+       struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+       struct intel_encoder *encoder;
+
+       if (!crtc_state->has_psr)
+               return;
+
+       for_each_intel_encoder_mask_with_psr(&i915->drm, encoder,
+                                            crtc_state->uapi.encoder_mask) {
+               struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+               mutex_unlock(&intel_dp->psr.lock);
+               break;
+       }
+}
 
                          struct intel_crtc_state *pipe_config);
 void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir);
 void intel_psr_short_pulse(struct intel_dp *intel_dp);
-void intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state);
+void intel_psr_wait_for_idle_locked(const struct intel_crtc_state *new_crtc_state);
 bool intel_psr_enabled(struct intel_dp *intel_dp);
 int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
                                struct intel_crtc *crtc);
 void intel_psr_pause(struct intel_dp *intel_dp);
 void intel_psr_resume(struct intel_dp *intel_dp);
 
+void intel_psr_lock(const struct intel_crtc_state *crtc_state);
+void intel_psr_unlock(const struct intel_crtc_state *crtc_state);
+
 #endif /* __INTEL_PSR_H__ */