diff mbox series

[v2] drm/i915/display: Wait PSR2 get out of deep sleep to update pipe

Message ID 20211001011218.276557-1-jose.souza@intel.com (mailing list archive)
State New, archived
Headers show
Series [v2] drm/i915/display: Wait PSR2 get out of deep sleep to update pipe | expand

Commit Message

Souza, Jose Oct. 1, 2021, 1:12 a.m. UTC
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.

To do so it was necessary to add intel_wait_for_condition_atomic(),
this takes as parameter a function that will return true when the
desidered condition is meet.

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

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>
---
 .../drm/i915/display/intel_display_debugfs.c  |  3 +-
 drivers/gpu/drm/i915/display/intel_psr.c      | 63 ++++++++++++-------
 drivers/gpu/drm/i915/i915_reg.h               | 10 +--
 drivers/gpu/drm/i915/intel_uncore.c           | 19 ++++++
 drivers/gpu/drm/i915/intel_uncore.h           |  4 ++
 5 files changed, 70 insertions(+), 29 deletions(-)

Comments

Souza, Jose Oct. 26, 2021, 5:35 p.m. UTC | #1
On Wed, 2021-10-06 at 06:49 +0000, Patchwork wrote:

> Patch Details
> Series:	drm/i915/display: Wait PSR2 get out of deep sleep to update pipe (rev3)
> URL:	https://patchwork.freedesktop.org/series/95309/
> State:	failure
> Details:	https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21259/index.html
> CI Bug Log - changes from CI_DRM_10685_full -> Patchwork_21259_full
> 
> Summary
> 
> FAILURE
> 
> Serious unknown changes coming with Patchwork_21259_full absolutely need to be
> verified manually.
> 
> If you think the reported changes have nothing to do with the changes
> introduced in Patchwork_21259_full, please notify your bug team to allow them
> to document this new failure mode, which will reduce false positives in CI.
> 
> Possible new issues
> 
> Here are the unknown changes that may have been introduced in Patchwork_21259_full:
> 
> IGT changes
> 
> Possible regressions
> 
> igt@i915_pm_dc@dc9-dpms:
> shard-iclb: PASS -> FAIL

Not related.

Patch pushed, thanks for the review GG.

> Known issues
> 
> Here are the changes found in Patchwork_21259_full that come from known issues:
> 
> IGT changes
> 
> Issues hit
> 
> igt@feature_discovery@display-2x:
> 
> shard-tglb: NOTRUN -> SKIP ([i915#1839])
> igt@gem_ctx_persistence@legacy-engines-mixed-process:
> 
> shard-snb: NOTRUN -> SKIP ([fdo#109271] / [i915#1099]) +1 similar issue
> igt@gem_eio@unwedge-stress:
> 
> shard-iclb: PASS -> TIMEOUT ([i915#2369] / [i915#2481] / [i915#3070])
> igt@gem_exec_fair@basic-deadline:
> 
> shard-apl: NOTRUN -> FAIL ([i915#2846])
> igt@gem_exec_fair@basic-flow@rcs0:
> 
> shard-tglb: PASS -> FAIL ([i915#2842])
> igt@gem_exec_fair@basic-none-share@rcs0:
> 
> shard-iclb: PASS -> FAIL ([i915#2842])
> igt@gem_exec_fair@basic-none@vcs0:
> 
> shard-apl: PASS -> FAIL ([i915#2842])
> igt@gem_exec_fair@basic-none@vcs1:
> 
> shard-kbl: PASS -> FAIL ([i915#2842])
> igt@gem_exec_fair@basic-pace-share@rcs0:
> 
> shard-tglb: NOTRUN -> FAIL ([i915#2842])
> igt@gem_exec_fair@basic-pace@vcs1:
> 
> shard-iclb: NOTRUN -> FAIL ([i915#2842])
> igt@gem_workarounds@suspend-resume-context:
> 
> shard-apl: PASS -> DMESG-WARN ([i915#180]) +1 similar issue
> igt@gem_workarounds@suspend-resume-fd:
> 
> shard-kbl: NOTRUN -> DMESG-WARN ([i915#180])
> igt@gen3_render_tiledy_blits:
> 
> shard-tglb: NOTRUN -> SKIP ([fdo#109289]) +1 similar issue
> igt@gen9_exec_parse@bb-secure:
> 
> shard-tglb: NOTRUN -> SKIP ([i915#2856]) +1 similar issue
> igt@i915_pm_lpsp@screens-disabled:
> 
> shard-tglb: NOTRUN -> SKIP ([i915#1902])
> igt@i915_pm_rc6_residency@media-rc6-accuracy:
> 
> shard-tglb: NOTRUN -> SKIP ([fdo#109289] / [fdo#111719])
> igt@i915_pm_rpm@pc8-residency:
> 
> shard-tglb: NOTRUN -> SKIP ([fdo#109506] / [i915#2411])
> igt@i915_selftest@mock@requests:
> 
> shard-skl: PASS -> INCOMPLETE ([i915#198])
> igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-hflip:
> 
> shard-apl: NOTRUN -> SKIP ([fdo#109271] / [i915#3777]) +1 similar issue
> igt@kms_big_fb@yf-tiled-addfb:
> 
> shard-tglb: NOTRUN -> SKIP ([fdo#111615]) +2 similar issues
> igt@kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-0-hflip:
> 
> shard-kbl: NOTRUN -> SKIP ([fdo#109271] / [i915#3777])
> igt@kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-0:
> 
> shard-apl: NOTRUN -> SKIP ([fdo#109271]) +208 similar issues
> igt@kms_ccs@pipe-a-ccs-on-another-bo-y_tiled_gen12_mc_ccs:
> 
> shard-apl: NOTRUN -> SKIP ([fdo#109271] / [i915#3886]) +10 similar issues
> igt@kms_ccs@pipe-a-crc-sprite-planes-basic-y_tiled_gen12_rc_ccs_cc:
> 
> shard-kbl: NOTRUN -> SKIP ([fdo#109271] / [i915#3886]) +10 similar issues
> igt@kms_ccs@pipe-b-ccs-on-another-bo-y_tiled_gen12_mc_ccs:
> 
> shard-tglb: NOTRUN -> SKIP ([i915#3689] / [i915#3886]) +4 similar issues
> igt@kms_ccs@pipe-d-bad-pixel-format-y_tiled_ccs:
> 
> shard-snb: NOTRUN -> SKIP ([fdo#109271]) +144 similar issues
> igt@kms_ccs@pipe-d-missing-ccs-buffer-yf_tiled_ccs:
> 
> shard-tglb: NOTRUN -> SKIP ([i915#3689]) +3 similar issues
> igt@kms_cdclk@plane-scaling:
> 
> shard-tglb: NOTRUN -> SKIP ([i915#3742])
> igt@kms_chamelium@hdmi-hpd-enable-disable-mode:
> 
> shard-kbl: NOTRUN -> SKIP ([fdo#109271] / [fdo#111827]) +13 similar issues
> igt@kms_color@pipe-c-ctm-0-5:
> 
> shard-skl: PASS -> DMESG-WARN ([i915#1982])
> igt@kms_color_chamelium@pipe-b-ctm-max:
> 
> shard-snb: NOTRUN -> SKIP ([fdo#109271] / [fdo#111827]) +6 similar issues
> igt@kms_color_chamelium@pipe-c-ctm-max:
> 
> shard-apl: NOTRUN -> SKIP ([fdo#109271] / [fdo#111827]) +18 similar issues
> igt@kms_color_chamelium@pipe-d-ctm-red-to-blue:
> 
> shard-tglb: NOTRUN -> SKIP ([fdo#109284] / [fdo#111827]) +6 similar issues
> igt@kms_content_protection@atomic-dpms:
> 
> shard-apl: NOTRUN -> TIMEOUT ([i915#1319])
> igt@kms_content_protection@srm:
> 
> shard-kbl: NOTRUN -> TIMEOUT ([i915#1319])
> igt@kms_cursor_crc@pipe-a-cursor-suspend:
> 
> shard-tglb: PASS -> INCOMPLETE ([i915#2828] / [i915#456])
> igt@kms_cursor_crc@pipe-d-cursor-32x10-offscreen:
> 
> shard-tglb: NOTRUN -> SKIP ([i915#3359]) +3 similar issues
> igt@kms_cursor_crc@pipe-d-cursor-32x32-rapid-movement:
> 
> shard-tglb: NOTRUN -> SKIP ([i915#3319])
> igt@kms_cursor_crc@pipe-d-cursor-512x170-offscreen:
> 
> shard-tglb: NOTRUN -> SKIP ([fdo#109279] / [i915#3359]) +1 similar issue
> igt@kms_cursor_edge_walk@pipe-d-64x64-right-edge:
> 
> shard-skl: NOTRUN -> SKIP ([fdo#109271]) +4 similar issues
> igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
> 
> shard-tglb: NOTRUN -> SKIP ([i915#4103])
> igt@kms_cursor_legacy@pipe-d-single-bo:
> 
> shard-apl: NOTRUN -> SKIP ([fdo#109271] / [i915#533])
> igt@kms_flip@flip-vs-suspend@c-dp1:
> 
> shard-kbl: PASS -> DMESG-WARN ([i915#180]) +6 similar issues
> igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytilegen12rcccs:
> 
> shard-apl: NOTRUN -> SKIP ([fdo#109271] / [i915#2672])
> igt@kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile:
> 
> shard-iclb: PASS -> SKIP ([i915#3701]) +1 similar issue
> igt@kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs:
> 
> shard-kbl: NOTRUN -> SKIP ([fdo#109271] / [i915#2672])
> igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-mmap-wc:
> 
> shard-glk: PASS -> FAIL ([i915#2546])
> igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-move:
> 
> shard-tglb: NOTRUN -> SKIP ([fdo#111825]) +22 similar issues
> igt@kms_frontbuffer_tracking@fbc-suspend:
> 
> shard-tglb: PASS -> INCOMPLETE ([i915#2411] / [i915#456])
> igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-wc:
> 
> shard-kbl: NOTRUN -> SKIP ([fdo#109271]) +147 similar issues
> igt@kms_hdr@bpc-switch-dpms:
> 
> shard-skl: PASS -> FAIL ([i915#1188]) +1 similar issue
> igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c:
> 
> shard-apl: NOTRUN -> DMESG-WARN ([i915#180])
> igt@kms_plane_alpha_blend@pipe-a-alpha-opaque-fb:
> 
> shard-apl: NOTRUN -> FAIL ([fdo#108145] / [i915#265]) +2 similar issues
> igt@kms_plane_alpha_blend@pipe-c-alpha-transparent-fb:
> 
> shard-apl: NOTRUN -> FAIL ([i915#265])
> igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
> 
> shard-skl: PASS -> FAIL ([fdo#108145] / [i915#265])
> igt@kms_plane_lowres@pipe-a-tiling-none:
> 
> shard-tglb: NOTRUN -> SKIP ([i915#3536]) +1 similar issue
> igt@kms_psr2_sf@cursor-plane-update-sf:
> 
> shard-tglb: NOTRUN -> SKIP ([i915#2920]) +1 similar issue
> igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-4:
> 
> shard-apl: NOTRUN -> SKIP ([fdo#109271] / [i915#658]) +4 similar issues
> igt@kms_psr2_sf@plane-move-sf-dmg-area-3:
> 
> shard-kbl: NOTRUN -> SKIP ([fdo#109271] / [i915#658]) +4 similar issues
> igt@kms_psr2_su@frontbuffer:
> 
> shard-iclb: PASS -> SKIP ([fdo#109642] / [fdo#111068] / [i915#658])
> igt@kms_psr@psr2_cursor_mmap_gtt:
> 
> shard-tglb: NOTRUN -> FAIL ([i915#132] / [i915#3467])
> igt@kms_psr@psr2_sprite_blt:
> 
> shard-iclb: PASS -> SKIP ([fdo#109441]) +1 similar issue
> igt@kms_vblank@pipe-a-ts-continuation-suspend:
> 
> shard-kbl: PASS -> DMESG-WARN ([i915#180] / [i915#295])
> igt@kms_writeback@writeback-fb-id:
> 
> shard-apl: NOTRUN -> SKIP ([fdo#109271] / [i915#2437])
> igt@nouveau_crc@pipe-b-ctx-flip-detection:
> 
> shard-tglb: NOTRUN -> SKIP ([i915#2530]) +2 similar issues
> igt@prime_nv_pcopy@test1_macro:
> 
> shard-tglb: NOTRUN -> SKIP ([fdo#109291])
> igt@prime_vgem@coherency-gtt:
> 
> shard-tglb: NOTRUN -> SKIP ([fdo#111656])
> igt@prime_vgem@fence-flip-hang:
> 
> shard-tglb: NOTRUN -> SKIP ([fdo#109295])
> igt@sysfs_clients@create:
> 
> shard-apl: NOTRUN -> SKIP ([fdo#109271] / [i915#2994]) +1 similar issue
> igt@sysfs_clients@fair-0:
> 
> shard-tglb: NOTRUN -> SKIP ([i915#2994]) +1 similar issue
> igt@sysfs_clients@split-50:
> 
> shard-kbl: NOTRUN -> SKIP ([fdo#109271] / [i915#2994]) +2 similar issues
> Possible fixes
> 
> igt@gem_eio@unwedge-stress:
> 
> shard-tglb: TIMEOUT ([i915#2369] / [i915#3063] / [i915#3648]) -> PASS
> igt@gem_exec_fair@basic-deadline:
> 
> shard-kbl: FAIL ([i915#2846]) -> PASS
> igt@gem_exec_fair@basic-none-vip@rcs0:
> 
> shard-iclb: FAIL ([i915#2842]) -> PASS
> igt@gem_exec_fair@basic-throttle@rcs0:
> 
> shard-iclb: FAIL ([i915#2849]) -> PASS
> igt@gem_exec_whisper@basic-fds-priority:
> 
> shard-glk: DMESG-WARN ([i915#118] / [i915#95]) -> PASS
> igt@i915_pm_rpm@system-suspend-execbuf:
> 
> shard-tglb: INCOMPLETE ([i915#2411] / [i915#456] / [i915#750]) -> PASS
> igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size:
> 
> shard-skl: FAIL ([i915#2346] / [i915#533]) -> PASS
> igt@kms_fbcon_fbt@fbc-suspend:
> 
> shard-kbl: INCOMPLETE ([i915#155] / [i915#180] / [i915#636]) -> PASS
> igt@kms_flip@flip-vs-expired-vblank-interruptible@b-dp1:
> 
> shard-kbl: FAIL ([i915#79]) -> PASS
> igt@kms_flip@flip-vs-expired-vblank@c-edp1:
> 
> shard-skl: FAIL ([i915#79]) -> PASS
> igt@kms_flip@flip-vs-suspend-interruptible@a-dp1:
> 
> shard-kbl: DMESG-WARN ([i915#180]) -> PASS +5 similar issues
> igt@kms_flip@flip-vs-suspend-interruptible@a-edp1:
> 
> shard-tglb: INCOMPLETE ([i915#2411] / [i915#456]) -> PASS
> igt@kms_hdr@bpc-switch-suspend:
> 
> shard-apl: DMESG-WARN ([i915#180]) -> PASS
> igt@kms_plane_alpha_blend@pipe-a-coverage-7efc:
> 
> shard-skl: FAIL ([fdo#108145] / [i915#265]) -> PASS
> igt@kms_prop_blob@blob-multiple:
> 
> shard-skl: DMESG-WARN ([i915#1982]) -> PASS
> igt@kms_psr@psr2_primary_mmap_cpu:
> 
> shard-iclb: SKIP ([fdo#109441]) -> PASS +1 similar issue
> igt@perf@short-reads:
> 
> shard-skl: FAIL ([i915#51]) -> PASS
> Warnings
> 
> igt@gem_exec_fair@basic-pace-solo@rcs0:
> 
> shard-iclb: FAIL ([i915#2842]) -> FAIL ([i915#2851])
> igt@i915_pm_rc6_residency@rc6-fence:
> 
> shard-iclb: WARN ([i915#2684]) -> WARN ([i915#1804] / [i915#2684])
> igt@kms_psr2_sf@plane-move-sf-dmg-area-3:
> 
> shard-iclb: SKIP ([i915#2920]) -> SKIP ([i915#658]) +1 similar issue
> igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-5:
> 
> shard-iclb: SKIP ([i915#658]) -> SKIP ([i915#2920]) +1 similar issue
> igt@runner@aborted:
> 
> shard-kbl: (FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, [FAIL][141], [FAIL][142]) ([i915#1436] / [i915#180] / [i915#1814] / [i915#3002] / [i915#3363]
/ [i915#602] / [i915#92]) -> ([FAIL][143], [FAIL][144], [FAIL][145], [FAIL][146], [FAIL][147], [FAIL][148], [FAIL][149], [FAIL][150], [FAIL][151])
([i915#180] / [i915#1814] / [i915#3002] / [i915#3363] / [i915#602])
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 68f4ba8c46e75..662596adb1da6 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -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 {
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 7a205fd5023bb..2b6868fdc3c08 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1809,15 +1809,32 @@  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 bool _is_psr2_read_for_pipe_update(void *data)
+{
+	struct intel_dp *intel_dp = data;
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	u32 val;
+
+	val = intel_uncore_read_fw(&dev_priv->uncore,
+				   EDP_PSR2_STATUS(intel_dp->psr.transcoder));
+	val &= EDP_PSR2_STATUS_STATE_MASK;
+	return val < EDP_PSR2_STATUS_STATE_DEEP_SLEEP;
+}
+
+static int _psr2_ready_for_pipe_update_locked(struct intel_dp *intel_dp)
+{
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	unsigned int fw;
+
+	fw = intel_uncore_forcewake_for_reg(&dev_priv->uncore,
+					    EDP_PSR2_STATUS(intel_dp->psr.transcoder),
+					    FW_REG_READ);
+	return intel_wait_for_condition_atomic(&dev_priv->uncore,
+					       _is_psr2_read_for_pipe_update,
+					       intel_dp, fw, 20);
+}
+
+static int _psr1_ready_for_pipe_update_locked(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
@@ -1827,15 +1844,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
@@ -1852,19 +1867,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);
 	}
 }
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 3a20a55d25124..de0a253a0b0d2 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4700,11 +4700,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
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index aee572af80527..b7bb91e8c1c8f 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -2450,6 +2450,25 @@  int __intel_wait_for_register(struct intel_uncore *uncore,
 	return ret;
 }
 
+int intel_wait_for_condition_atomic(struct intel_uncore *uncore,
+				    bool (*func)(void *data), void *data,
+				    unsigned int fw, unsigned int timeout_ms)
+{
+	int ret;
+
+	might_sleep_if(timeout_ms);
+
+	spin_lock_irq(&uncore->lock);
+	intel_uncore_forcewake_get__locked(uncore, fw);
+
+	ret = _wait_for_atomic(func(data), timeout_ms * USEC_PER_MSEC, 0);
+
+	intel_uncore_forcewake_put__locked(uncore, fw);
+	spin_unlock_irq(&uncore->lock);
+
+	return ret;
+}
+
 bool intel_uncore_unclaimed_mmio(struct intel_uncore *uncore)
 {
 	bool ret;
diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h
index 3248e4e2c540c..da5cefc8fa222 100644
--- a/drivers/gpu/drm/i915/intel_uncore.h
+++ b/drivers/gpu/drm/i915/intel_uncore.h
@@ -294,6 +294,10 @@  intel_wait_for_register_fw(struct intel_uncore *uncore,
 					    2, timeout_ms, NULL);
 }
 
+int intel_wait_for_condition_atomic(struct intel_uncore *uncore,
+				    bool (*func)(void *data), void *data,
+				    unsigned int fw, unsigned int timeout_ms);
+
 /* register access functions */
 #define __raw_read(x__, s__) \
 static inline u##x__ __raw_uncore_read##x__(const struct intel_uncore *uncore, \