[PATCH 8/8] drm/i915/psr: Use SFF_CTL and CFF_CTL for LunarLake onwards

Jouni Högander jouni.hogander at intel.com
Wed Dec 4 10:38:00 UTC 2024


In LunarLake we have SFF_CTL can CFF_CTL registers that contain SFF and CFF
bits that are ored with the respective ones in PSR2_MAN_TRK_CTL
register. Use these registers instead of bits in PSR2_MAN_TRK_CTL. This
 helps us avoiding taking psr mutex when performing atomic commit.

Signed-off-by: Jouni Högander <jouni.hogander at intel.com>
---
 drivers/gpu/drm/i915/display/intel_psr.c | 74 ++++++++++++++++++++----
 1 file changed, 63 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 55fe827efec4..309da8b951ff 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -26,6 +26,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_damage_helper.h>
 #include <drm/drm_debugfs.h>
+#include <drm/drm_vblank.h>
 
 #include "i915_drv.h"
 #include "i915_reg.h"
@@ -44,6 +45,7 @@
 #include "intel_psr.h"
 #include "intel_psr_regs.h"
 #include "intel_snps_phy.h"
+#include "intel_vblank.h"
 #include "skl_universal_plane.h"
 
 /**
@@ -2349,7 +2351,7 @@ void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_st
 		if (!crtc_state->use_dsb)
 			lockdep_assert_held(&intel_dp->psr.lock);
 
-		if (intel_dp->psr.psr2_sel_fetch_cff_enabled)
+		if (DISPLAY_VER(display) < 20 && intel_dp->psr.psr2_sel_fetch_cff_enabled)
 			return;
 		break;
 	}
@@ -3140,15 +3142,58 @@ static void psr_set_for_full_frame_update(struct intel_dp *intel_dp, bool sff,
 		       cff ? man_trk_ctl_continuos_full_frame(display) : 0);
 }
 
+static void lnl_psr_set_for_full_frame_update(struct intel_dp *intel_dp,
+					      bool set_sff, bool clr_cff,
+					      bool set_cff)
+{
+	struct intel_display *display = to_intel_display(intel_dp);
+	enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
+	struct intel_crtc *crtc =
+		to_intel_crtc(intel_dp->attached_connector->base.state->crtc);
+	struct intel_crtc_state *crtc_state =
+		to_intel_crtc_state(crtc->base.state);
+	struct intel_vblank_evade_ctx evade;
+
+	if (!intel_dp->psr.psr2_sel_fetch_enabled)
+		return;
+
+	intel_vblank_evade_init(crtc_state, crtc_state, &evade);
+
+	drm_crtc_vblank_get(&crtc->base);
+
+	local_irq_disable();
+
+	intel_vblank_evade(&evade);
+
+	drm_crtc_vblank_put(&crtc->base);
+
+	if (set_sff)
+		intel_de_write(display, LNL_SFF_CTL(display, cpu_transcoder),
+			       LNL_SFF_CTL_SF_SINGLE_FULL_FRAME);
+	if (clr_cff)
+		intel_de_write(display, LNL_CFF_CTL(display, cpu_transcoder), 0);
+	else if (set_cff)
+		intel_de_write(display, LNL_CFF_CTL(display, cpu_transcoder),
+			       LNL_CFF_CTL_SF_CONTINUOUS_FULL_FRAME);
+
+	local_irq_enable();
+}
+
 static void _psr_invalidate_handle(struct intel_dp *intel_dp)
 {
+	struct intel_display *display = to_intel_display(intel_dp);
+
 	if (intel_dp->psr.psr2_sel_fetch_enabled) {
 		if (!intel_dp->psr.psr2_sel_fetch_cff_enabled) {
 			intel_dp->psr.psr2_sel_fetch_cff_enabled = true;
-			psr_set_for_full_frame_update(intel_dp, false,
-						      true);
+			if (DISPLAY_VER(display) >= 20)
+				lnl_psr_set_for_full_frame_update(intel_dp,
+								  false, false,
+								  true);
+			else
+				psr_set_for_full_frame_update(intel_dp, false,
+							      true);
 		}
-
 		psr_force_exit(intel_dp);
 	} else {
 		intel_psr_exit(intel_dp);
@@ -3232,18 +3277,25 @@ static void _psr_flush_handle(struct intel_dp *intel_dp)
 	struct drm_i915_private *dev_priv = to_i915(display->drm);
 
 	if (intel_dp->psr.psr2_sel_fetch_enabled) {
+		bool clr_cff = false;
 		if (intel_dp->psr.psr2_sel_fetch_cff_enabled) {
 			/* can we turn CFF off? */
-			if (intel_dp->psr.busy_frontbuffer_bits == 0)
+			if (intel_dp->psr.busy_frontbuffer_bits == 0) {
 				intel_dp->psr.psr2_sel_fetch_cff_enabled = false;
+				clr_cff = true;
+			}
 		}
 
-		/*
-		 * Still keep cff bit enabled as we don't have proper SU
-		 * configuration in case update is sent for any reason after
-		 * sff bit gets cleared by the HW on next vblank.
-		 */
-		psr_set_for_full_frame_update(intel_dp, true, true);
+		if (DISPLAY_VER(display) >= 20)
+			lnl_psr_set_for_full_frame_update(intel_dp, true,
+							  clr_cff, false);
+		else
+			/*
+			 * Still keep cff bit enabled as we don't have proper SU
+			 * configuration in case update is sent for any reason after
+			 * sff bit gets cleared by the HW on next vblank.
+			 */
+			psr_set_for_full_frame_update(intel_dp, true, true);
 	}
 
 	psr_force_exit(intel_dp);
-- 
2.34.1



More information about the Intel-gfx-trybot mailing list