All of lore.kernel.org
 help / color / mirror / Atom feed
* [Intel-gfx] [PATCH v13 1/2] drm/i915/display: Support PSR Multiple Instances
@ 2021-01-27 17:23 Gwan-gyeong Mun
  2021-01-27 17:23 ` [Intel-gfx] [PATCH v13 2/2] drm/i915/display: Support Multiple Transcoders' PSR status on debugfs Gwan-gyeong Mun
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Gwan-gyeong Mun @ 2021-01-27 17:23 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

It is a preliminary work for supporting multiple EDP PSR and
DP PanelReplay. And it refactors singleton PSR to Multi Transcoder
supportable PSR.
And this moves and renames the i915_psr structure of drm_i915_private's to
intel_dp's intel_psr structure.
It also causes changes in PSR interrupt handling routine for supporting
multiple transcoders. But it does not change the scenario and timing of
enabling and disabling PSR. And it not support multiple pipes with
a single transcoder PSR case yet.

v2: Fix indentation and add comments
v3: Remove Blank line
v4: Rebased
v5: Rebased and Addressed Anshuman's review comment.
    - Move calling of intel_psr_init() to intel_dp_init_connector()
v6: Address Anshuman's review comments
   - Remove wrong comments and add comments for a limit of supporting of
     a single pipe PSR
v7: Update intel_psr_compute_config() for supporting multiple transcoder
    PSR on BDW+
v8: Address Anshuman's review comments
   - Replace DRM_DEBUG_KMS with drm_dbg_kms() / DRM_WARN with drm_warn()
v9: Fix commit message
v10: Rebased
v11: Address Jose's review comment.
  - Reorder calling order of intel_psr2_program_trans_man_trk_ctl().
  - In order to reduce changes keep the old name for drm_i915_private.
  - Change restrictions of multiple instances of PSR.
v12: Address Jose's review comment.
  - Change the calling of intel_psr2_program_trans_man_trk_ctl() into
    commit_pipe_config().
  - Change a checking order of CAN_PSR() and connector_status to original
    on i915_psr_sink_status_show().
  - Drop unneeded intel_dp_update_pipe() function.
  - In order to wait a specific encoder which belong to crtc_state on
    intel_psr_wait_for_idle(), add checking of encoder.
  - Add an whitespace to comments.
v13: Rebased and Address Jose's review comment.
  - Add and use for_each_intel_psr_enabled_encoder() macro.
  - In order to use correct frontbuffer_bit for each pipe,
    fix intel_psr_invalidate() and intel_psr_flush().
  - Remove redundant or unneeded codes.
  - Update comments.

Signed-off-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Cc: José Roberto de Souza <jose.souza@intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Anshuman Gupta <anshuman.gupta@intel.com>
Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  |   2 -
 drivers/gpu/drm/i915/display/intel_display.h  |   8 +
 .../drm/i915/display/intel_display_debugfs.c  | 105 +++-
 .../drm/i915/display/intel_display_types.h    |  46 ++
 drivers/gpu/drm/i915/display/intel_dp.c       |  10 +-
 drivers/gpu/drm/i915/display/intel_psr.c      | 576 ++++++++++--------
 drivers/gpu/drm/i915/display/intel_psr.h      |  11 +-
 drivers/gpu/drm/i915/display/intel_sprite.c   |   6 +-
 drivers/gpu/drm/i915/i915_drv.h               |  38 --
 drivers/gpu/drm/i915/i915_irq.c               |  48 +-
 10 files changed, 485 insertions(+), 365 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 667d941878a3..24df9dfb57fb 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -14135,8 +14135,6 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
 		intel_dvo_init(dev_priv);
 	}
 
-	intel_psr_init(dev_priv);
-
 	for_each_intel_encoder(&dev_priv->drm, encoder) {
 		encoder->base.possible_crtcs =
 			intel_encoder_possible_crtcs(encoder);
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index 64ffa34544a7..fc41d0d9e5a5 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -417,6 +417,14 @@ enum phy_fia {
 		for_each_if((encoder_mask) &				\
 			    drm_encoder_mask(&intel_encoder->base))
 
+#define for_each_intel_encoder_is_psr_enabled(dev, intel_encoder, encoder_mask) \
+	list_for_each_entry(intel_encoder,				\
+			    &(dev)->mode_config.encoder_list,		\
+			    base.head)					\
+		for_each_if(((encoder_mask) &				\
+			     drm_encoder_mask(&intel_encoder->base)) &&	\
+			    intel_encoder_is_psr_enabled(intel_encoder))
+
 #define for_each_intel_dp(dev, intel_encoder)			\
 	for_each_intel_encoder(dev, intel_encoder)		\
 		for_each_if(intel_encoder_is_dp(intel_encoder))
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index d62b18d5ecd8..9868253df61f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -249,12 +249,11 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data)
 		"sink internal error",
 	};
 	struct drm_connector *connector = m->private;
-	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	struct intel_dp *intel_dp =
 		intel_attached_dp(to_intel_connector(connector));
 	int ret;
 
-	if (!CAN_PSR(dev_priv)) {
+	if (!CAN_PSR(intel_dp)) {
 		seq_puts(m, "PSR Unsupported\n");
 		return -ENODEV;
 	}
@@ -280,12 +279,13 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data)
 DEFINE_SHOW_ATTRIBUTE(i915_psr_sink_status);
 
 static void
-psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m)
+psr_source_status(struct intel_dp *intel_dp, struct seq_file *m)
 {
 	u32 val, status_val;
 	const char *status = "unknown";
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
-	if (dev_priv->psr.psr2_enabled) {
+	if (intel_dp->psr.psr2_enabled) {
 		static const char * const live_status[] = {
 			"IDLE",
 			"CAPTURE",
@@ -300,7 +300,7 @@ psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m)
 			"TG_ON"
 		};
 		val = intel_de_read(dev_priv,
-				    EDP_PSR2_STATUS(dev_priv->psr.transcoder));
+				    EDP_PSR2_STATUS(intel_dp->psr.transcoder));
 		status_val = (val & EDP_PSR2_STATUS_STATE_MASK) >>
 			      EDP_PSR2_STATUS_STATE_SHIFT;
 		if (status_val < ARRAY_SIZE(live_status))
@@ -317,7 +317,7 @@ psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m)
 			"SRDENT_ON",
 		};
 		val = intel_de_read(dev_priv,
-				    EDP_PSR_STATUS(dev_priv->psr.transcoder));
+				    EDP_PSR_STATUS(intel_dp->psr.transcoder));
 		status_val = (val & EDP_PSR_STATUS_STATE_MASK) >>
 			      EDP_PSR_STATUS_STATE_SHIFT;
 		if (status_val < ARRAY_SIZE(live_status))
@@ -327,21 +327,18 @@ psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m)
 	seq_printf(m, "Source PSR status: %s [0x%08x]\n", status, val);
 }
 
-static int i915_edp_psr_status(struct seq_file *m, void *data)
+static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
 {
-	struct drm_i915_private *dev_priv = node_to_i915(m->private);
-	struct i915_psr *psr = &dev_priv->psr;
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	struct intel_psr *psr = &intel_dp->psr;
 	intel_wakeref_t wakeref;
 	const char *status;
 	bool enabled;
 	u32 val;
 
-	if (!HAS_PSR(dev_priv))
-		return -ENODEV;
-
 	seq_printf(m, "Sink support: %s", yesno(psr->sink_support));
-	if (psr->dp)
-		seq_printf(m, " [0x%02x]", psr->dp->psr_dpcd[0]);
+	if (psr->sink_support)
+		seq_printf(m, " [0x%02x]", intel_dp->psr_dpcd[0]);
 	seq_puts(m, "\n");
 
 	if (!psr->sink_support)
@@ -365,16 +362,16 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
 
 	if (psr->psr2_enabled) {
 		val = intel_de_read(dev_priv,
-				    EDP_PSR2_CTL(dev_priv->psr.transcoder));
+				    EDP_PSR2_CTL(intel_dp->psr.transcoder));
 		enabled = val & EDP_PSR2_ENABLE;
 	} else {
 		val = intel_de_read(dev_priv,
-				    EDP_PSR_CTL(dev_priv->psr.transcoder));
+				    EDP_PSR_CTL(intel_dp->psr.transcoder));
 		enabled = val & EDP_PSR_ENABLE;
 	}
 	seq_printf(m, "Source PSR ctl: %s [0x%08x]\n",
 		   enableddisabled(enabled), val);
-	psr_source_status(dev_priv, m);
+	psr_source_status(intel_dp, m);
 	seq_printf(m, "Busy frontbuffer bits: 0x%08x\n",
 		   psr->busy_frontbuffer_bits);
 
@@ -383,7 +380,7 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
 	 */
 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
 		val = intel_de_read(dev_priv,
-				    EDP_PSR_PERF_CNT(dev_priv->psr.transcoder));
+				    EDP_PSR_PERF_CNT(intel_dp->psr.transcoder));
 		val &= EDP_PSR_PERF_CNT_MASK;
 		seq_printf(m, "Performance counter: %u\n", val);
 	}
@@ -404,7 +401,7 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
 		 */
 		for (frame = 0; frame < PSR2_SU_STATUS_FRAMES; frame += 3) {
 			val = intel_de_read(dev_priv,
-					    PSR2_SU_STATUS(dev_priv->psr.transcoder, frame));
+					    PSR2_SU_STATUS(intel_dp->psr.transcoder, frame));
 			su_frames_val[frame / 3] = val;
 		}
 
@@ -430,23 +427,57 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
 	return 0;
 }
 
+static int i915_edp_psr_status(struct seq_file *m, void *data)
+{
+	struct drm_i915_private *dev_priv = node_to_i915(m->private);
+	struct intel_encoder *encoder;
+	struct intel_dp *intel_dp = NULL;
+
+	if (!HAS_PSR(dev_priv))
+		return -ENODEV;
+
+	/* Find the first EDP */
+	for_each_intel_dp(&dev_priv->drm, encoder) {
+		if (encoder->type == INTEL_OUTPUT_EDP) {
+			intel_dp = enc_to_intel_dp(encoder);
+			break;
+		}
+	}
+
+	if (!intel_dp)
+		return -ENODEV;
+
+	return intel_psr_status(m, intel_dp);
+}
+
 static int
 i915_edp_psr_debug_set(void *data, u64 val)
 {
 	struct drm_i915_private *dev_priv = data;
 	intel_wakeref_t wakeref;
-	int ret;
+	int ret = -ENODEV;
+	struct intel_encoder *encoder;
 
-	if (!CAN_PSR(dev_priv))
-		return -ENODEV;
+	if (!HAS_PSR(dev_priv))
+		return ret;
 
-	drm_dbg_kms(&dev_priv->drm, "Setting PSR debug to %llx\n", val);
+	for_each_intel_dp(&dev_priv->drm, encoder) {
+		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
-	wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
+		if (!CAN_PSR(intel_dp))
+			continue;
 
-	ret = intel_psr_debug_set(dev_priv, val);
+		if (encoder->type == INTEL_OUTPUT_EDP) {
+			drm_dbg_kms(&dev_priv->drm, "Setting PSR debug to %llx\n", val);
 
-	intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
+			wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
+
+			// TODO: split to each transcoder's PSR debug state
+			ret = intel_psr_debug_set(intel_dp, val);
+
+			intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
+		}
+	}
 
 	return ret;
 }
@@ -455,12 +486,25 @@ static int
 i915_edp_psr_debug_get(void *data, u64 *val)
 {
 	struct drm_i915_private *dev_priv = data;
+	struct intel_encoder *encoder;
 
-	if (!CAN_PSR(dev_priv))
+	if (!HAS_PSR(dev_priv))
 		return -ENODEV;
 
-	*val = READ_ONCE(dev_priv->psr.debug);
-	return 0;
+	for_each_intel_dp(&dev_priv->drm, encoder) {
+		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+		if (!CAN_PSR(intel_dp))
+			continue;
+
+		// TODO: split to each transcoder's PSR debug state
+		if (encoder->type == INTEL_OUTPUT_EDP) {
+			*val = READ_ONCE(intel_dp->psr.debug);
+			return 0;
+		}
+	}
+
+	return -ENODEV;
 }
 
 DEFINE_SIMPLE_ATTRIBUTE(i915_edp_psr_debug_fops,
@@ -1233,9 +1277,6 @@ static void drrs_status_per_crtc(struct seq_file *m,
 		/* disable_drrs() will make drrs->dp NULL */
 		if (!drrs->dp) {
 			seq_puts(m, "Idleness DRRS: Disabled\n");
-			if (dev_priv->psr.enabled)
-				seq_puts(m,
-				"\tAs PSR is enabled, DRRS is not enabled\n");
 			mutex_unlock(&drrs->mutex);
 			return;
 		}
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 39397748b4b0..63daf8b45941 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1415,6 +1415,42 @@ struct intel_pps {
 	struct edp_power_seq pps_delays;
 };
 
+struct intel_psr {
+	/* Mutex for PSR state of the transcoder */
+	struct mutex lock;
+
+#define I915_PSR_DEBUG_MODE_MASK	0x0f
+#define I915_PSR_DEBUG_DEFAULT		0x00
+#define I915_PSR_DEBUG_DISABLE		0x01
+#define I915_PSR_DEBUG_ENABLE		0x02
+#define I915_PSR_DEBUG_FORCE_PSR1	0x03
+#define I915_PSR_DEBUG_IRQ		0x10
+
+	u32 debug;
+	bool sink_support;
+	bool enabled;
+	enum pipe pipe;
+	enum transcoder transcoder;
+	bool active;
+	struct work_struct work;
+	unsigned int busy_frontbuffer_bits;
+	bool sink_psr2_support;
+	bool link_standby;
+	bool colorimetry_support;
+	bool psr2_enabled;
+	bool psr2_sel_fetch_enabled;
+	u8 sink_sync_latency;
+	ktime_t last_entry_attempt;
+	ktime_t last_exit;
+	bool sink_not_reliable;
+	bool irq_aux_error;
+	u16 su_x_granularity;
+	bool dc3co_enabled;
+	u32 dc3co_exit_delay;
+	struct delayed_work dc3co_work;
+	struct drm_dp_vsc_sdp vsc;
+};
+
 struct intel_dp {
 	i915_reg_t output_reg;
 	u32 DP;
@@ -1517,6 +1553,8 @@ struct intel_dp {
 	bool hobl_active;
 
 	struct intel_dp_pcon_frl frl;
+
+	struct intel_psr psr;
 };
 
 enum lspcon_vendor {
@@ -1729,6 +1767,14 @@ static inline bool intel_encoder_is_dp(struct intel_encoder *encoder)
 	}
 }
 
+static inline bool intel_encoder_is_psr_enabled(struct intel_encoder *encoder)
+{
+	if (!intel_encoder_is_dp(encoder))
+		return false;
+
+	return enc_to_intel_dp(encoder)->psr.enabled;
+}
+
 static inline struct intel_lspcon *
 enc_to_intel_lspcon(struct intel_encoder *encoder)
 {
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 8c12d5375607..d532bd56250f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1663,12 +1663,10 @@ void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp,
 				  const struct drm_connector_state *conn_state,
 				  struct drm_dp_vsc_sdp *vsc)
 {
-	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-
 	vsc->sdp_type = DP_SDP_VSC;
 
-	if (dev_priv->psr.psr2_enabled) {
-		if (dev_priv->psr.colorimetry_support &&
+	if (intel_dp->psr.psr2_enabled) {
+		if (intel_dp->psr.colorimetry_support &&
 		    intel_dp_needs_vsc_sdp(crtc_state, conn_state)) {
 			/* [PSR2, +Colorimetry] */
 			intel_dp_compute_vsc_colorimetry(crtc_state, conn_state,
@@ -2359,7 +2357,7 @@ bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
 		return false;
 	}
 
-	if (CAN_PSR(i915) && intel_dp_is_edp(intel_dp)) {
+	if (CAN_PSR(intel_dp) && intel_dp_is_edp(intel_dp)) {
 		drm_dbg_kms(&i915->drm, "Forcing full modeset to compute PSR state\n");
 		crtc_state->uapi.mode_changed = true;
 		return false;
@@ -6641,6 +6639,8 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
 	intel_dp->frl.is_trained = false;
 	intel_dp->frl.trained_rate_gbps = 0;
 
+	intel_psr_init(intel_dp);
+
 	return true;
 
 fail:
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 2c365b778f74..925c0c6d92cd 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -80,9 +80,11 @@
  * use page flips.
  */
 
-static bool psr_global_enabled(struct drm_i915_private *i915)
+static bool psr_global_enabled(struct intel_dp *intel_dp)
 {
-	switch (i915->psr.debug & I915_PSR_DEBUG_MODE_MASK) {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+	switch (intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK) {
 	case I915_PSR_DEBUG_DEFAULT:
 		return i915->params.enable_psr;
 	case I915_PSR_DEBUG_DISABLE:
@@ -92,9 +94,9 @@ static bool psr_global_enabled(struct drm_i915_private *i915)
 	}
 }
 
-static bool psr2_global_enabled(struct drm_i915_private *dev_priv)
+static bool psr2_global_enabled(struct intel_dp *intel_dp)
 {
-	switch (dev_priv->psr.debug & I915_PSR_DEBUG_MODE_MASK) {
+	switch (intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK) {
 	case I915_PSR_DEBUG_DISABLE:
 	case I915_PSR_DEBUG_FORCE_PSR1:
 		return false;
@@ -103,11 +105,12 @@ static bool psr2_global_enabled(struct drm_i915_private *dev_priv)
 	}
 }
 
-static void psr_irq_control(struct drm_i915_private *dev_priv)
+static void psr_irq_control(struct intel_dp *intel_dp)
 {
 	enum transcoder trans_shift;
 	u32 mask, val;
 	i915_reg_t imr_reg;
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
 	/*
 	 * gen12+ has registers relative to transcoder and one per transcoder
@@ -116,14 +119,14 @@ static void psr_irq_control(struct drm_i915_private *dev_priv)
 	 */
 	if (INTEL_GEN(dev_priv) >= 12) {
 		trans_shift = 0;
-		imr_reg = TRANS_PSR_IMR(dev_priv->psr.transcoder);
+		imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder);
 	} else {
-		trans_shift = dev_priv->psr.transcoder;
+		trans_shift = intel_dp->psr.transcoder;
 		imr_reg = EDP_PSR_IMR;
 	}
 
 	mask = EDP_PSR_ERROR(trans_shift);
-	if (dev_priv->psr.debug & I915_PSR_DEBUG_IRQ)
+	if (intel_dp->psr.debug & I915_PSR_DEBUG_IRQ)
 		mask |= EDP_PSR_POST_EXIT(trans_shift) |
 			EDP_PSR_PRE_ENTRY(trans_shift);
 
@@ -172,30 +175,31 @@ static void psr_event_print(struct drm_i915_private *i915,
 		drm_dbg_kms(&i915->drm, "\tPSR disabled\n");
 }
 
-void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir)
+void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
 {
-	enum transcoder cpu_transcoder = dev_priv->psr.transcoder;
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
 	enum transcoder trans_shift;
 	i915_reg_t imr_reg;
 	ktime_t time_ns =  ktime_get();
 
 	if (INTEL_GEN(dev_priv) >= 12) {
 		trans_shift = 0;
-		imr_reg = TRANS_PSR_IMR(dev_priv->psr.transcoder);
+		imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder);
 	} else {
-		trans_shift = dev_priv->psr.transcoder;
+		trans_shift = intel_dp->psr.transcoder;
 		imr_reg = EDP_PSR_IMR;
 	}
 
 	if (psr_iir & EDP_PSR_PRE_ENTRY(trans_shift)) {
-		dev_priv->psr.last_entry_attempt = time_ns;
+		intel_dp->psr.last_entry_attempt = time_ns;
 		drm_dbg_kms(&dev_priv->drm,
 			    "[transcoder %s] PSR entry attempt in 2 vblanks\n",
 			    transcoder_name(cpu_transcoder));
 	}
 
 	if (psr_iir & EDP_PSR_POST_EXIT(trans_shift)) {
-		dev_priv->psr.last_exit = time_ns;
+		intel_dp->psr.last_exit = time_ns;
 		drm_dbg_kms(&dev_priv->drm,
 			    "[transcoder %s] PSR exit completed\n",
 			    transcoder_name(cpu_transcoder));
@@ -203,7 +207,7 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir)
 		if (INTEL_GEN(dev_priv) >= 9) {
 			u32 val = intel_de_read(dev_priv,
 						PSR_EVENT(cpu_transcoder));
-			bool psr2_enabled = dev_priv->psr.psr2_enabled;
+			bool psr2_enabled = intel_dp->psr.psr2_enabled;
 
 			intel_de_write(dev_priv, PSR_EVENT(cpu_transcoder),
 				       val);
@@ -217,7 +221,7 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir)
 		drm_warn(&dev_priv->drm, "[transcoder %s] PSR aux error\n",
 			 transcoder_name(cpu_transcoder));
 
-		dev_priv->psr.irq_aux_error = true;
+		intel_dp->psr.irq_aux_error = true;
 
 		/*
 		 * If this interruption is not masked it will keep
@@ -231,7 +235,7 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir)
 		val |= EDP_PSR_ERROR(trans_shift);
 		intel_de_write(dev_priv, imr_reg, val);
 
-		schedule_work(&dev_priv->psr.work);
+		schedule_work(&intel_dp->psr.work);
 	}
 }
 
@@ -292,12 +296,6 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp)
 	struct drm_i915_private *dev_priv =
 		to_i915(dp_to_dig_port(intel_dp)->base.base.dev);
 
-	if (dev_priv->psr.dp) {
-		drm_warn(&dev_priv->drm,
-			 "More than one eDP panel found, PSR support should be extended\n");
-		return;
-	}
-
 	drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT, intel_dp->psr_dpcd,
 			 sizeof(intel_dp->psr_dpcd));
 
@@ -318,12 +316,10 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp)
 		return;
 	}
 
-	dev_priv->psr.sink_support = true;
-	dev_priv->psr.sink_sync_latency =
+	intel_dp->psr.sink_support = true;
+	intel_dp->psr.sink_sync_latency =
 		intel_dp_get_sink_sync_latency(intel_dp);
 
-	dev_priv->psr.dp = intel_dp;
-
 	if (INTEL_GEN(dev_priv) >= 9 &&
 	    (intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_IS_SUPPORTED)) {
 		bool y_req = intel_dp->psr_dpcd[1] &
@@ -341,14 +337,14 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp)
 		 * Y-coordinate requirement panels we would need to enable
 		 * GTC first.
 		 */
-		dev_priv->psr.sink_psr2_support = y_req && alpm;
+		intel_dp->psr.sink_psr2_support = y_req && alpm;
 		drm_dbg_kms(&dev_priv->drm, "PSR2 %ssupported\n",
-			    dev_priv->psr.sink_psr2_support ? "" : "not ");
+			    intel_dp->psr.sink_psr2_support ? "" : "not ");
 
-		if (dev_priv->psr.sink_psr2_support) {
-			dev_priv->psr.colorimetry_support =
+		if (intel_dp->psr.sink_psr2_support) {
+			intel_dp->psr.colorimetry_support =
 				intel_dp_get_colorimetry_status(intel_dp);
-			dev_priv->psr.su_x_granularity =
+			intel_dp->psr.su_x_granularity =
 				intel_dp_get_su_x_granulartiy(intel_dp);
 		}
 	}
@@ -374,7 +370,7 @@ static void hsw_psr_setup_aux(struct intel_dp *intel_dp)
 	BUILD_BUG_ON(sizeof(aux_msg) > 20);
 	for (i = 0; i < sizeof(aux_msg); i += 4)
 		intel_de_write(dev_priv,
-			       EDP_PSR_AUX_DATA(dev_priv->psr.transcoder, i >> 2),
+			       EDP_PSR_AUX_DATA(intel_dp->psr.transcoder, i >> 2),
 			       intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i));
 
 	aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0);
@@ -385,7 +381,7 @@ static void hsw_psr_setup_aux(struct intel_dp *intel_dp)
 
 	/* Select only valid bits for SRD_AUX_CTL */
 	aux_ctl &= psr_aux_mask;
-	intel_de_write(dev_priv, EDP_PSR_AUX_CTL(dev_priv->psr.transcoder),
+	intel_de_write(dev_priv, EDP_PSR_AUX_CTL(intel_dp->psr.transcoder),
 		       aux_ctl);
 }
 
@@ -395,14 +391,14 @@ static void intel_psr_enable_sink(struct intel_dp *intel_dp)
 	u8 dpcd_val = DP_PSR_ENABLE;
 
 	/* Enable ALPM at sink for psr2 */
-	if (dev_priv->psr.psr2_enabled) {
+	if (intel_dp->psr.psr2_enabled) {
 		drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG,
 				   DP_ALPM_ENABLE |
 				   DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE);
 
 		dpcd_val |= DP_PSR_ENABLE_PSR2 | DP_PSR_IRQ_HPD_WITH_CRC_ERRORS;
 	} else {
-		if (dev_priv->psr.link_standby)
+		if (intel_dp->psr.link_standby)
 			dpcd_val |= DP_PSR_MAIN_LINK_ACTIVE;
 
 		if (INTEL_GEN(dev_priv) >= 8)
@@ -465,7 +461,7 @@ static u8 psr_compute_idle_frames(struct intel_dp *intel_dp)
 	 * off-by-one issue that HW has in some cases.
 	 */
 	idle_frames = max(6, dev_priv->vbt.psr.idle_frames);
-	idle_frames = max(idle_frames, dev_priv->psr.sink_sync_latency + 1);
+	idle_frames = max(idle_frames, intel_dp->psr.sink_sync_latency + 1);
 
 	if (drm_WARN_ON(&dev_priv->drm, idle_frames > 0xf))
 		idle_frames = 0xf;
@@ -485,7 +481,7 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp)
 	if (IS_HASWELL(dev_priv))
 		val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES;
 
-	if (dev_priv->psr.link_standby)
+	if (intel_dp->psr.link_standby)
 		val |= EDP_PSR_LINK_STANDBY;
 
 	val |= intel_psr1_get_tp_time(intel_dp);
@@ -493,9 +489,9 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp)
 	if (INTEL_GEN(dev_priv) >= 8)
 		val |= EDP_PSR_CRC_ENABLE;
 
-	val |= (intel_de_read(dev_priv, EDP_PSR_CTL(dev_priv->psr.transcoder)) &
+	val |= (intel_de_read(dev_priv, EDP_PSR_CTL(intel_dp->psr.transcoder)) &
 		EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK);
-	intel_de_write(dev_priv, EDP_PSR_CTL(dev_priv->psr.transcoder), val);
+	intel_de_write(dev_priv, EDP_PSR_CTL(intel_dp->psr.transcoder), val);
 }
 
 static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp)
@@ -530,7 +526,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
 		val |= EDP_Y_COORDINATE_ENABLE;
 
-	val |= EDP_PSR2_FRAME_BEFORE_SU(dev_priv->psr.sink_sync_latency + 1);
+	val |= EDP_PSR2_FRAME_BEFORE_SU(intel_dp->psr.sink_sync_latency + 1);
 	val |= intel_psr2_get_tp_time(intel_dp);
 
 	if (INTEL_GEN(dev_priv) >= 12) {
@@ -549,7 +545,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
 		val |= EDP_PSR2_FAST_WAKE(7);
 	}
 
-	if (dev_priv->psr.psr2_sel_fetch_enabled) {
+	if (intel_dp->psr.psr2_sel_fetch_enabled) {
 		/* WA 1408330847 */
 		if (IS_TGL_DISP_STEPPING(dev_priv, STEP_A0, STEP_A0) ||
 		    IS_RKL_REVID(dev_priv, RKL_REVID_A0, RKL_REVID_A0))
@@ -558,20 +554,20 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
 				     DIS_RAM_BYPASS_PSR2_MAN_TRACK);
 
 		intel_de_write(dev_priv,
-			       PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder),
+			       PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder),
 			       PSR2_MAN_TRK_CTL_ENABLE);
 	} else if (HAS_PSR2_SEL_FETCH(dev_priv)) {
 		intel_de_write(dev_priv,
-			       PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder), 0);
+			       PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder), 0);
 	}
 
 	/*
 	 * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and BSpec is
 	 * recommending keep this bit unset while PSR2 is enabled.
 	 */
-	intel_de_write(dev_priv, EDP_PSR_CTL(dev_priv->psr.transcoder), 0);
+	intel_de_write(dev_priv, EDP_PSR_CTL(intel_dp->psr.transcoder), 0);
 
-	intel_de_write(dev_priv, EDP_PSR2_CTL(dev_priv->psr.transcoder), val);
+	intel_de_write(dev_priv, EDP_PSR2_CTL(intel_dp->psr.transcoder), val);
 }
 
 static bool
@@ -594,55 +590,58 @@ static u32 intel_get_frame_time_us(const struct intel_crtc_state *cstate)
 			    drm_mode_vrefresh(&cstate->hw.adjusted_mode));
 }
 
-static void psr2_program_idle_frames(struct drm_i915_private *dev_priv,
+static void psr2_program_idle_frames(struct intel_dp *intel_dp,
 				     u32 idle_frames)
 {
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	u32 val;
 
 	idle_frames <<=  EDP_PSR2_IDLE_FRAME_SHIFT;
-	val = intel_de_read(dev_priv, EDP_PSR2_CTL(dev_priv->psr.transcoder));
+	val = intel_de_read(dev_priv, EDP_PSR2_CTL(intel_dp->psr.transcoder));
 	val &= ~EDP_PSR2_IDLE_FRAME_MASK;
 	val |= idle_frames;
-	intel_de_write(dev_priv, EDP_PSR2_CTL(dev_priv->psr.transcoder), val);
+	intel_de_write(dev_priv, EDP_PSR2_CTL(intel_dp->psr.transcoder), val);
 }
 
-static void tgl_psr2_enable_dc3co(struct drm_i915_private *dev_priv)
+static void tgl_psr2_enable_dc3co(struct intel_dp *intel_dp)
 {
-	psr2_program_idle_frames(dev_priv, 0);
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+
+	psr2_program_idle_frames(intel_dp, 0);
 	intel_display_power_set_target_dc_state(dev_priv, DC_STATE_EN_DC3CO);
 }
 
-static void tgl_psr2_disable_dc3co(struct drm_i915_private *dev_priv)
+static void tgl_psr2_disable_dc3co(struct intel_dp *intel_dp)
 {
-	struct intel_dp *intel_dp = dev_priv->psr.dp;
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
 	intel_display_power_set_target_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6);
-	psr2_program_idle_frames(dev_priv, psr_compute_idle_frames(intel_dp));
+	psr2_program_idle_frames(intel_dp, psr_compute_idle_frames(intel_dp));
 }
 
 static void tgl_dc3co_disable_work(struct work_struct *work)
 {
-	struct drm_i915_private *dev_priv =
-		container_of(work, typeof(*dev_priv), psr.dc3co_work.work);
+	struct intel_dp *intel_dp =
+		container_of(work, typeof(*intel_dp), psr.dc3co_work.work);
 
-	mutex_lock(&dev_priv->psr.lock);
+	mutex_lock(&intel_dp->psr.lock);
 	/* If delayed work is pending, it is not idle */
-	if (delayed_work_pending(&dev_priv->psr.dc3co_work))
+	if (delayed_work_pending(&intel_dp->psr.dc3co_work))
 		goto unlock;
 
-	tgl_psr2_disable_dc3co(dev_priv);
+	tgl_psr2_disable_dc3co(intel_dp);
 unlock:
-	mutex_unlock(&dev_priv->psr.lock);
+	mutex_unlock(&intel_dp->psr.lock);
 }
 
-static void tgl_disallow_dc3co_on_psr2_exit(struct drm_i915_private *dev_priv)
+static void tgl_disallow_dc3co_on_psr2_exit(struct intel_dp *intel_dp)
 {
-	if (!dev_priv->psr.dc3co_enabled)
+	if (!intel_dp->psr.dc3co_enabled)
 		return;
 
-	cancel_delayed_work(&dev_priv->psr.dc3co_work);
+	cancel_delayed_work(&intel_dp->psr.dc3co_work);
 	/* Before PSR2 exit disallow dc3co*/
-	tgl_psr2_disable_dc3co(dev_priv);
+	tgl_psr2_disable_dc3co(intel_dp);
 }
 
 static void
@@ -715,7 +714,7 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
 	int crtc_vdisplay = crtc_state->hw.adjusted_mode.crtc_vdisplay;
 	int psr_max_h = 0, psr_max_v = 0, max_bpp = 0;
 
-	if (!dev_priv->psr.sink_psr2_support)
+	if (!intel_dp->psr.sink_psr2_support)
 		return false;
 
 	if (!transcoder_has_psr2(dev_priv, crtc_state->cpu_transcoder)) {
@@ -725,7 +724,7 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
 		return false;
 	}
 
-	if (!psr2_global_enabled(dev_priv)) {
+	if (!psr2_global_enabled(intel_dp)) {
 		drm_dbg_kms(&dev_priv->drm, "PSR2 disabled by flag\n");
 		return false;
 	}
@@ -774,10 +773,10 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
 	 * only need to validate the SU block width is a multiple of
 	 * x granularity.
 	 */
-	if (crtc_hdisplay % dev_priv->psr.su_x_granularity) {
+	if (crtc_hdisplay % intel_dp->psr.su_x_granularity) {
 		drm_dbg_kms(&dev_priv->drm,
 			    "PSR2 not enabled, hdisplay(%d) not multiple of %d\n",
-			    crtc_hdisplay, dev_priv->psr.su_x_granularity);
+			    crtc_hdisplay, intel_dp->psr.su_x_granularity);
 		return false;
 	}
 
@@ -819,13 +818,10 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
 	if (crtc_state->vrr.enable)
 		return;
 
-	if (!CAN_PSR(dev_priv))
+	if (!CAN_PSR(intel_dp))
 		return;
 
-	if (intel_dp != dev_priv->psr.dp)
-		return;
-
-	if (!psr_global_enabled(dev_priv)) {
+	if (!psr_global_enabled(intel_dp)) {
 		drm_dbg_kms(&dev_priv->drm, "PSR disabled by flag\n");
 		return;
 	}
@@ -833,16 +829,19 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
 	/*
 	 * HSW spec explicitly says PSR is tied to port A.
 	 * BDW+ platforms have a instance of PSR registers per transcoder but
-	 * for now it only supports one instance of PSR, so lets keep it
-	 * hardcoded to PORT_A
+	 * BDW, GEN9 and GEN11 are not validated by HW team in other transcoder
+	 * than eDP one.
+	 * For now it only supports one instance of PSR for BDW, GEN9 and GEN11.
+	 * So lets keep it hardcoded to PORT_A for BDW, GEN9 and GEN11.
+	 * But GEN12 supports a instance of PSR registers per transcoder.
 	 */
-	if (dig_port->base.port != PORT_A) {
+	if (INTEL_GEN(dev_priv) < 12 && dig_port->base.port != PORT_A) {
 		drm_dbg_kms(&dev_priv->drm,
 			    "PSR condition failed: Port not supported\n");
 		return;
 	}
 
-	if (dev_priv->psr.sink_not_reliable) {
+	if (intel_dp->psr.sink_not_reliable) {
 		drm_dbg_kms(&dev_priv->drm,
 			    "PSR sink implementation is not reliable\n");
 		return;
@@ -878,23 +877,24 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
 static void intel_psr_activate(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	enum transcoder transcoder = intel_dp->psr.transcoder;
 
-	if (transcoder_has_psr2(dev_priv, dev_priv->psr.transcoder))
+	if (transcoder_has_psr2(dev_priv, transcoder))
 		drm_WARN_ON(&dev_priv->drm,
-			    intel_de_read(dev_priv, EDP_PSR2_CTL(dev_priv->psr.transcoder)) & EDP_PSR2_ENABLE);
+			    intel_de_read(dev_priv, EDP_PSR2_CTL(transcoder)) & EDP_PSR2_ENABLE);
 
 	drm_WARN_ON(&dev_priv->drm,
-		    intel_de_read(dev_priv, EDP_PSR_CTL(dev_priv->psr.transcoder)) & EDP_PSR_ENABLE);
-	drm_WARN_ON(&dev_priv->drm, dev_priv->psr.active);
-	lockdep_assert_held(&dev_priv->psr.lock);
+		    intel_de_read(dev_priv, EDP_PSR_CTL(transcoder)) & EDP_PSR_ENABLE);
+	drm_WARN_ON(&dev_priv->drm, intel_dp->psr.active);
+	lockdep_assert_held(&intel_dp->psr.lock);
 
 	/* psr1 and psr2 are mutually exclusive.*/
-	if (dev_priv->psr.psr2_enabled)
+	if (intel_dp->psr.psr2_enabled)
 		hsw_activate_psr2(intel_dp);
 	else
 		hsw_activate_psr1(intel_dp);
 
-	dev_priv->psr.active = true;
+	intel_dp->psr.active = true;
 }
 
 static void intel_psr_enable_source(struct intel_dp *intel_dp,
@@ -910,7 +910,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
 		hsw_psr_setup_aux(intel_dp);
 
-	if (dev_priv->psr.psr2_enabled && (IS_GEN(dev_priv, 9) &&
+	if (intel_dp->psr.psr2_enabled && (IS_GEN(dev_priv, 9) &&
 					   !IS_GEMINILAKE(dev_priv))) {
 		i915_reg_t reg = CHICKEN_TRANS(cpu_transcoder);
 		u32 chicken = intel_de_read(dev_priv, reg);
@@ -934,10 +934,10 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
 	if (INTEL_GEN(dev_priv) < 11)
 		mask |= EDP_PSR_DEBUG_MASK_DISP_REG_WRITE;
 
-	intel_de_write(dev_priv, EDP_PSR_DEBUG(dev_priv->psr.transcoder),
+	intel_de_write(dev_priv, EDP_PSR_DEBUG(intel_dp->psr.transcoder),
 		       mask);
 
-	psr_irq_control(dev_priv);
+	psr_irq_control(intel_dp);
 
 	if (crtc_state->dc3co_exitline) {
 		u32 val;
@@ -955,30 +955,30 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
 
 	if (HAS_PSR_HW_TRACKING(dev_priv) && HAS_PSR2_SEL_FETCH(dev_priv))
 		intel_de_rmw(dev_priv, CHICKEN_PAR1_1, IGNORE_PSR2_HW_TRACKING,
-			     dev_priv->psr.psr2_sel_fetch_enabled ?
+			     intel_dp->psr.psr2_sel_fetch_enabled ?
 			     IGNORE_PSR2_HW_TRACKING : 0);
 }
 
-static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
+static void intel_psr_enable_locked(struct intel_dp *intel_dp,
 				    const struct intel_crtc_state *crtc_state,
 				    const struct drm_connector_state *conn_state)
 {
-	struct intel_dp *intel_dp = dev_priv->psr.dp;
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
 	struct intel_encoder *encoder = &dig_port->base;
 	u32 val;
 
-	drm_WARN_ON(&dev_priv->drm, dev_priv->psr.enabled);
+	drm_WARN_ON(&dev_priv->drm, intel_dp->psr.enabled);
 
-	dev_priv->psr.psr2_enabled = crtc_state->has_psr2;
-	dev_priv->psr.busy_frontbuffer_bits = 0;
-	dev_priv->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
-	dev_priv->psr.dc3co_enabled = !!crtc_state->dc3co_exitline;
-	dev_priv->psr.transcoder = crtc_state->cpu_transcoder;
+	intel_dp->psr.psr2_enabled = crtc_state->has_psr2;
+	intel_dp->psr.busy_frontbuffer_bits = 0;
+	intel_dp->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
+	intel_dp->psr.dc3co_enabled = !!crtc_state->dc3co_exitline;
+	intel_dp->psr.transcoder = crtc_state->cpu_transcoder;
 	/* DC5/DC6 requires at least 6 idle frames */
 	val = usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 6);
-	dev_priv->psr.dc3co_exit_delay = val;
-	dev_priv->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch;
+	intel_dp->psr.dc3co_exit_delay = val;
+	intel_dp->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch;
 
 	/*
 	 * If a PSR error happened and the driver is reloaded, the EDP_PSR_IIR
@@ -990,27 +990,27 @@ static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
 	 */
 	if (INTEL_GEN(dev_priv) >= 12) {
 		val = intel_de_read(dev_priv,
-				    TRANS_PSR_IIR(dev_priv->psr.transcoder));
+				    TRANS_PSR_IIR(intel_dp->psr.transcoder));
 		val &= EDP_PSR_ERROR(0);
 	} else {
 		val = intel_de_read(dev_priv, EDP_PSR_IIR);
-		val &= EDP_PSR_ERROR(dev_priv->psr.transcoder);
+		val &= EDP_PSR_ERROR(intel_dp->psr.transcoder);
 	}
 	if (val) {
-		dev_priv->psr.sink_not_reliable = true;
+		intel_dp->psr.sink_not_reliable = true;
 		drm_dbg_kms(&dev_priv->drm,
 			    "PSR interruption error set, not enabling PSR\n");
 		return;
 	}
 
 	drm_dbg_kms(&dev_priv->drm, "Enabling PSR%s\n",
-		    dev_priv->psr.psr2_enabled ? "2" : "1");
+		    intel_dp->psr.psr2_enabled ? "2" : "1");
 	intel_dp_compute_psr_vsc_sdp(intel_dp, crtc_state, conn_state,
-				     &dev_priv->psr.vsc);
-	intel_write_dp_vsc_sdp(encoder, crtc_state, &dev_priv->psr.vsc);
+				     &intel_dp->psr.vsc);
+	intel_write_dp_vsc_sdp(encoder, crtc_state, &intel_dp->psr.vsc);
 	intel_psr_enable_sink(intel_dp);
 	intel_psr_enable_source(intel_dp, crtc_state);
-	dev_priv->psr.enabled = true;
+	intel_dp->psr.enabled = true;
 
 	intel_psr_activate(intel_dp);
 }
@@ -1029,7 +1029,7 @@ void intel_psr_enable(struct intel_dp *intel_dp,
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
-	if (!CAN_PSR(dev_priv) || dev_priv->psr.dp != intel_dp)
+	if (!CAN_PSR(intel_dp))
 		return;
 
 	if (!crtc_state->has_psr)
@@ -1037,46 +1037,47 @@ void intel_psr_enable(struct intel_dp *intel_dp,
 
 	drm_WARN_ON(&dev_priv->drm, dev_priv->drrs.dp);
 
-	mutex_lock(&dev_priv->psr.lock);
-	intel_psr_enable_locked(dev_priv, crtc_state, conn_state);
-	mutex_unlock(&dev_priv->psr.lock);
+	mutex_lock(&intel_dp->psr.lock);
+	intel_psr_enable_locked(intel_dp, crtc_state, conn_state);
+	mutex_unlock(&intel_dp->psr.lock);
 }
 
-static void intel_psr_exit(struct drm_i915_private *dev_priv)
+static void intel_psr_exit(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	u32 val;
 
-	if (!dev_priv->psr.active) {
-		if (transcoder_has_psr2(dev_priv, dev_priv->psr.transcoder)) {
+	if (!intel_dp->psr.active) {
+		if (transcoder_has_psr2(dev_priv, intel_dp->psr.transcoder)) {
 			val = intel_de_read(dev_priv,
-					    EDP_PSR2_CTL(dev_priv->psr.transcoder));
+					    EDP_PSR2_CTL(intel_dp->psr.transcoder));
 			drm_WARN_ON(&dev_priv->drm, val & EDP_PSR2_ENABLE);
 		}
 
 		val = intel_de_read(dev_priv,
-				    EDP_PSR_CTL(dev_priv->psr.transcoder));
+				    EDP_PSR_CTL(intel_dp->psr.transcoder));
 		drm_WARN_ON(&dev_priv->drm, val & EDP_PSR_ENABLE);
 
 		return;
 	}
 
-	if (dev_priv->psr.psr2_enabled) {
-		tgl_disallow_dc3co_on_psr2_exit(dev_priv);
+	if (intel_dp->psr.psr2_enabled) {
+		tgl_disallow_dc3co_on_psr2_exit(intel_dp);
 		val = intel_de_read(dev_priv,
-				    EDP_PSR2_CTL(dev_priv->psr.transcoder));
+				    EDP_PSR2_CTL(intel_dp->psr.transcoder));
 		drm_WARN_ON(&dev_priv->drm, !(val & EDP_PSR2_ENABLE));
 		val &= ~EDP_PSR2_ENABLE;
 		intel_de_write(dev_priv,
-			       EDP_PSR2_CTL(dev_priv->psr.transcoder), val);
+			       EDP_PSR2_CTL(intel_dp->psr.transcoder), val);
 	} else {
 		val = intel_de_read(dev_priv,
-				    EDP_PSR_CTL(dev_priv->psr.transcoder));
+				    EDP_PSR_CTL(intel_dp->psr.transcoder));
 		drm_WARN_ON(&dev_priv->drm, !(val & EDP_PSR_ENABLE));
 		val &= ~EDP_PSR_ENABLE;
 		intel_de_write(dev_priv,
-			       EDP_PSR_CTL(dev_priv->psr.transcoder), val);
+			       EDP_PSR_CTL(intel_dp->psr.transcoder), val);
 	}
-	dev_priv->psr.active = false;
+	intel_dp->psr.active = false;
 }
 
 static void intel_psr_disable_locked(struct intel_dp *intel_dp)
@@ -1085,21 +1086,21 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
 	i915_reg_t psr_status;
 	u32 psr_status_mask;
 
-	lockdep_assert_held(&dev_priv->psr.lock);
+	lockdep_assert_held(&intel_dp->psr.lock);
 
-	if (!dev_priv->psr.enabled)
+	if (!intel_dp->psr.enabled)
 		return;
 
 	drm_dbg_kms(&dev_priv->drm, "Disabling PSR%s\n",
-		    dev_priv->psr.psr2_enabled ? "2" : "1");
+		    intel_dp->psr.psr2_enabled ? "2" : "1");
 
-	intel_psr_exit(dev_priv);
+	intel_psr_exit(intel_dp);
 
-	if (dev_priv->psr.psr2_enabled) {
-		psr_status = EDP_PSR2_STATUS(dev_priv->psr.transcoder);
+	if (intel_dp->psr.psr2_enabled) {
+		psr_status = EDP_PSR2_STATUS(intel_dp->psr.transcoder);
 		psr_status_mask = EDP_PSR2_STATUS_STATE_MASK;
 	} else {
-		psr_status = EDP_PSR_STATUS(dev_priv->psr.transcoder);
+		psr_status = EDP_PSR_STATUS(intel_dp->psr.transcoder);
 		psr_status_mask = EDP_PSR_STATUS_STATE_MASK;
 	}
 
@@ -1109,7 +1110,7 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
 		drm_err(&dev_priv->drm, "Timed out waiting PSR idle state\n");
 
 	/* WA 1408330847 */
-	if (dev_priv->psr.psr2_sel_fetch_enabled &&
+	if (intel_dp->psr.psr2_sel_fetch_enabled &&
 	    (IS_TGL_DISP_STEPPING(dev_priv, STEP_A0, STEP_A0) ||
 	     IS_RKL_REVID(dev_priv, RKL_REVID_A0, RKL_REVID_A0)))
 		intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
@@ -1118,10 +1119,10 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
 	/* Disable PSR on Sink */
 	drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0);
 
-	if (dev_priv->psr.psr2_enabled)
+	if (intel_dp->psr.psr2_enabled)
 		drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, 0);
 
-	dev_priv->psr.enabled = false;
+	intel_dp->psr.enabled = false;
 }
 
 /**
@@ -1139,20 +1140,22 @@ void intel_psr_disable(struct intel_dp *intel_dp,
 	if (!old_crtc_state->has_psr)
 		return;
 
-	if (drm_WARN_ON(&dev_priv->drm, !CAN_PSR(dev_priv)))
+	if (drm_WARN_ON(&dev_priv->drm, !CAN_PSR(intel_dp)))
 		return;
 
-	mutex_lock(&dev_priv->psr.lock);
+	mutex_lock(&intel_dp->psr.lock);
 
 	intel_psr_disable_locked(intel_dp);
 
-	mutex_unlock(&dev_priv->psr.lock);
-	cancel_work_sync(&dev_priv->psr.work);
-	cancel_delayed_work_sync(&dev_priv->psr.dc3co_work);
+	mutex_unlock(&intel_dp->psr.lock);
+	cancel_work_sync(&intel_dp->psr.work);
+	cancel_delayed_work_sync(&intel_dp->psr.dc3co_work);
 }
 
-static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv)
+static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+
 	if (IS_TIGERLAKE(dev_priv))
 		/*
 		 * Writes to CURSURFLIVE in TGL are causing IOMMU errors and
@@ -1166,7 +1169,7 @@ static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv)
 		 * So using this workaround until this issue is root caused
 		 * and a better fix is found.
 		 */
-		intel_psr_exit(dev_priv);
+		intel_psr_exit(intel_dp);
 	else if (INTEL_GEN(dev_priv) >= 9)
 		/*
 		 * Display WA #0884: skl+
@@ -1177,13 +1180,13 @@ static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv)
 		 * but it makes more sense write to the current active
 		 * pipe.
 		 */
-		intel_de_write(dev_priv, CURSURFLIVE(dev_priv->psr.pipe), 0);
+		intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
 	else
 		/*
 		 * A write to CURSURFLIVE do not cause HW tracking to exit PSR
 		 * on older gens so doing the manual exit instead.
 		 */
-		intel_psr_exit(dev_priv);
+		intel_psr_exit(intel_dp);
 }
 
 void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
@@ -1231,16 +1234,19 @@ void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
 
 void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	struct i915_psr *psr = &dev_priv->psr;
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+	struct intel_encoder *encoder;
 
 	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
 	    !crtc_state->enable_psr2_sel_fetch)
 		return;
 
-	intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(psr->transcoder),
-		       crtc_state->psr2_man_track_ctl);
+	for_each_intel_encoder_is_psr_enabled(&dev_priv->drm, encoder,
+					      crtc_state->uapi.encoder_mask) {
+		intel_de_write(dev_priv,
+			       PSR2_MAN_TRK_CTL(crtc_state->cpu_transcoder),
+			       crtc_state->psr2_man_track_ctl);
+	}
 }
 
 static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state,
@@ -1435,13 +1441,13 @@ void intel_psr_update(struct intel_dp *intel_dp,
 		      const struct drm_connector_state *conn_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-	struct i915_psr *psr = &dev_priv->psr;
+	struct intel_psr *psr = &intel_dp->psr;
 	bool enable, psr2_enable;
 
-	if (!CAN_PSR(dev_priv) || READ_ONCE(psr->dp) != intel_dp)
+	if (!CAN_PSR(intel_dp))
 		return;
 
-	mutex_lock(&dev_priv->psr.lock);
+	mutex_lock(&intel_dp->psr.lock);
 
 	enable = crtc_state->has_psr;
 	psr2_enable = crtc_state->has_psr2;
@@ -1449,15 +1455,15 @@ void intel_psr_update(struct intel_dp *intel_dp,
 	if (enable == psr->enabled && psr2_enable == psr->psr2_enabled) {
 		/* Force a PSR exit when enabling CRC to avoid CRC timeouts */
 		if (crtc_state->crc_enabled && psr->enabled)
-			psr_force_hw_tracking_exit(dev_priv);
+			psr_force_hw_tracking_exit(intel_dp);
 		else if (INTEL_GEN(dev_priv) < 9 && psr->enabled) {
 			/*
 			 * Activate PSR again after a force exit when enabling
 			 * CRC in older gens
 			 */
-			if (!dev_priv->psr.active &&
-			    !dev_priv->psr.busy_frontbuffer_bits)
-				schedule_work(&dev_priv->psr.work);
+			if (!intel_dp->psr.active &&
+			    !intel_dp->psr.busy_frontbuffer_bits)
+				schedule_work(&intel_dp->psr.work);
 		}
 
 		goto unlock;
@@ -1467,34 +1473,23 @@ void intel_psr_update(struct intel_dp *intel_dp,
 		intel_psr_disable_locked(intel_dp);
 
 	if (enable)
-		intel_psr_enable_locked(dev_priv, crtc_state, conn_state);
+		intel_psr_enable_locked(intel_dp, crtc_state, conn_state);
 
 unlock:
-	mutex_unlock(&dev_priv->psr.lock);
+	mutex_unlock(&intel_dp->psr.lock);
 }
 
 /**
- * intel_psr_wait_for_idle - wait for PSR1 to idle
- * @new_crtc_state: new CRTC state
+ * psr_wait_for_idle - wait for PSR1 to idle
+ * @intel_dp: Intel DP
  * @out_value: PSR status in case of failure
  *
- * This function is expected to be called from pipe_update_start() where it is
- * not expected to race with PSR enable or disable.
- *
  * Returns: 0 on success or -ETIMEOUT if PSR status does not idle.
+ *
  */
-int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state,
-			    u32 *out_value)
+static int psr_wait_for_idle(struct intel_dp *intel_dp, u32 *out_value)
 {
-	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-
-	if (!dev_priv->psr.enabled || !new_crtc_state->has_psr)
-		return 0;
-
-	/* FIXME: Update this for PSR2 if we need to wait for idle */
-	if (READ_ONCE(dev_priv->psr.psr2_enabled))
-		return 0;
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
 	/*
 	 * From bspec: Panel Self Refresh (BDW+)
@@ -1502,32 +1497,63 @@ int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state,
 	 * 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(dev_priv->psr.transcoder),
+					 EDP_PSR_STATUS(intel_dp->psr.transcoder),
 					 EDP_PSR_STATUS_STATE_MASK,
 					 EDP_PSR_STATUS_STATE_IDLE, 2, 50,
 					 out_value);
 }
 
-static bool __psr_wait_for_idle_locked(struct drm_i915_private *dev_priv)
+/**
+ * intel_psr_wait_for_idle - wait for PSR1 to idle
+ * @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)
+{
+	struct drm_i915_private *dev_priv = to_i915(new_crtc_state->uapi.crtc->dev);
+	struct intel_encoder *encoder;
+
+	if (!new_crtc_state->has_psr)
+		return;
+
+	for_each_intel_encoder_is_psr_enabled(&dev_priv->drm, encoder,
+					      new_crtc_state->uapi.encoder_mask) {
+		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+		/* when the PSR1 is enabled */
+		if (!intel_dp->psr.psr2_enabled) {
+			u32 psr_status;
+
+			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);
+		}
+	}
+}
+
+static bool __psr_wait_for_idle_locked(struct intel_dp *intel_dp)
 {
 	i915_reg_t reg;
 	u32 mask;
 	int err;
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
-	if (!dev_priv->psr.enabled)
+	if (!intel_dp->psr.enabled)
 		return false;
 
-	if (dev_priv->psr.psr2_enabled) {
-		reg = EDP_PSR2_STATUS(dev_priv->psr.transcoder);
+	if (intel_dp->psr.psr2_enabled) {
+		reg = EDP_PSR2_STATUS(intel_dp->psr.transcoder);
 		mask = EDP_PSR2_STATUS_STATE_MASK;
 	} else {
-		reg = EDP_PSR_STATUS(dev_priv->psr.transcoder);
+		reg = EDP_PSR_STATUS(intel_dp->psr.transcoder);
 		mask = EDP_PSR_STATUS_STATE_MASK;
 	}
 
-	mutex_unlock(&dev_priv->psr.lock);
+	mutex_unlock(&intel_dp->psr.lock);
 
 	err = intel_de_wait_for_clear(dev_priv, reg, mask, 50);
 	if (err)
@@ -1535,8 +1561,8 @@ static bool __psr_wait_for_idle_locked(struct drm_i915_private *dev_priv)
 			"Timed out waiting for PSR Idle for re-enable\n");
 
 	/* After the unlocked wait, verify that PSR is still wanted! */
-	mutex_lock(&dev_priv->psr.lock);
-	return err == 0 && dev_priv->psr.enabled;
+	mutex_lock(&intel_dp->psr.lock);
+	return err == 0 && intel_dp->psr.enabled;
 }
 
 static int intel_psr_fastset_force(struct drm_i915_private *dev_priv)
@@ -1602,11 +1628,12 @@ static int intel_psr_fastset_force(struct drm_i915_private *dev_priv)
 	return err;
 }
 
-int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 val)
+int intel_psr_debug_set(struct intel_dp *intel_dp, u64 val)
 {
 	const u32 mode = val & I915_PSR_DEBUG_MODE_MASK;
 	u32 old_mode;
 	int ret;
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
 	if (val & ~(I915_PSR_DEBUG_IRQ | I915_PSR_DEBUG_MODE_MASK) ||
 	    mode > I915_PSR_DEBUG_FORCE_PSR1) {
@@ -1614,21 +1641,21 @@ int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 val)
 		return -EINVAL;
 	}
 
-	ret = mutex_lock_interruptible(&dev_priv->psr.lock);
+	ret = mutex_lock_interruptible(&intel_dp->psr.lock);
 	if (ret)
 		return ret;
 
-	old_mode = dev_priv->psr.debug & I915_PSR_DEBUG_MODE_MASK;
-	dev_priv->psr.debug = val;
+	old_mode = intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK;
+	intel_dp->psr.debug = val;
 
 	/*
 	 * Do it right away if it's already enabled, otherwise it will be done
 	 * when enabling the source.
 	 */
-	if (dev_priv->psr.enabled)
-		psr_irq_control(dev_priv);
+	if (intel_dp->psr.enabled)
+		psr_irq_control(intel_dp);
 
-	mutex_unlock(&dev_priv->psr.lock);
+	mutex_unlock(&intel_dp->psr.lock);
 
 	if (old_mode != mode)
 		ret = intel_psr_fastset_force(dev_priv);
@@ -1636,28 +1663,28 @@ int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 val)
 	return ret;
 }
 
-static void intel_psr_handle_irq(struct drm_i915_private *dev_priv)
+static void intel_psr_handle_irq(struct intel_dp *intel_dp)
 {
-	struct i915_psr *psr = &dev_priv->psr;
+	struct intel_psr *psr = &intel_dp->psr;
 
-	intel_psr_disable_locked(psr->dp);
+	intel_psr_disable_locked(intel_dp);
 	psr->sink_not_reliable = true;
 	/* let's make sure that sink is awaken */
-	drm_dp_dpcd_writeb(&psr->dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
+	drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
 }
 
 static void intel_psr_work(struct work_struct *work)
 {
-	struct drm_i915_private *dev_priv =
-		container_of(work, typeof(*dev_priv), psr.work);
+	struct intel_dp *intel_dp =
+		container_of(work, typeof(*intel_dp), psr.work);
 
-	mutex_lock(&dev_priv->psr.lock);
+	mutex_lock(&intel_dp->psr.lock);
 
-	if (!dev_priv->psr.enabled)
+	if (!intel_dp->psr.enabled)
 		goto unlock;
 
-	if (READ_ONCE(dev_priv->psr.irq_aux_error))
-		intel_psr_handle_irq(dev_priv);
+	if (READ_ONCE(intel_dp->psr.irq_aux_error))
+		intel_psr_handle_irq(intel_dp);
 
 	/*
 	 * We have to make sure PSR is ready for re-enable
@@ -1665,7 +1692,7 @@ static void intel_psr_work(struct work_struct *work)
 	 * PSR might take some time to get fully disabled
 	 * and be ready for re-enable.
 	 */
-	if (!__psr_wait_for_idle_locked(dev_priv))
+	if (!__psr_wait_for_idle_locked(intel_dp))
 		goto unlock;
 
 	/*
@@ -1673,12 +1700,12 @@ static void intel_psr_work(struct work_struct *work)
 	 * recheck. Since psr_flush first clears this and then reschedules we
 	 * won't ever miss a flush when bailing out here.
 	 */
-	if (dev_priv->psr.busy_frontbuffer_bits || dev_priv->psr.active)
+	if (intel_dp->psr.busy_frontbuffer_bits || intel_dp->psr.active)
 		goto unlock;
 
-	intel_psr_activate(dev_priv->psr.dp);
+	intel_psr_activate(intel_dp);
 unlock:
-	mutex_unlock(&dev_priv->psr.lock);
+	mutex_unlock(&intel_dp->psr.lock);
 }
 
 /**
@@ -1697,27 +1724,35 @@ static void intel_psr_work(struct work_struct *work)
 void intel_psr_invalidate(struct drm_i915_private *dev_priv,
 			  unsigned frontbuffer_bits, enum fb_op_origin origin)
 {
-	if (!CAN_PSR(dev_priv))
-		return;
+	struct intel_encoder *encoder;
+	struct intel_dp *intel_dp;
 
-	if (origin == ORIGIN_FLIP)
-		return;
+	for_each_intel_dp(&dev_priv->drm, encoder) {
+		unsigned pipe_frontbuffer_bits = frontbuffer_bits;
 
-	mutex_lock(&dev_priv->psr.lock);
-	if (!dev_priv->psr.enabled) {
-		mutex_unlock(&dev_priv->psr.lock);
-		return;
-	}
+		intel_dp = enc_to_intel_dp(encoder);
+		if (!CAN_PSR(intel_dp))
+			continue;
+
+		if (origin == ORIGIN_FLIP)
+			continue;
+
+		mutex_lock(&intel_dp->psr.lock);
+		if (!intel_dp->psr.enabled) {
+			mutex_unlock(&intel_dp->psr.lock);
+			continue;
+		}
 
-	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(dev_priv->psr.pipe);
-	dev_priv->psr.busy_frontbuffer_bits |= frontbuffer_bits;
+		pipe_frontbuffer_bits &=
+			INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe);
+		intel_dp->psr.busy_frontbuffer_bits |= pipe_frontbuffer_bits;
 
-	if (frontbuffer_bits)
-		intel_psr_exit(dev_priv);
+		if (pipe_frontbuffer_bits)
+			intel_psr_exit(intel_dp);
 
-	mutex_unlock(&dev_priv->psr.lock);
+		mutex_unlock(&intel_dp->psr.lock);
+	}
 }
-
 /*
  * When we will be completely rely on PSR2 S/W tracking in future,
  * intel_psr_flush() will invalidate and flush the PSR for ORIGIN_FLIP
@@ -1725,15 +1760,15 @@ void intel_psr_invalidate(struct drm_i915_private *dev_priv,
  * accordingly in future.
  */
 static void
-tgl_dc3co_flush(struct drm_i915_private *dev_priv,
-		unsigned int frontbuffer_bits, enum fb_op_origin origin)
+tgl_dc3co_flush(struct intel_dp *intel_dp, unsigned int frontbuffer_bits,
+		enum fb_op_origin origin)
 {
-	mutex_lock(&dev_priv->psr.lock);
+	mutex_lock(&intel_dp->psr.lock);
 
-	if (!dev_priv->psr.dc3co_enabled)
+	if (!intel_dp->psr.dc3co_enabled)
 		goto unlock;
 
-	if (!dev_priv->psr.psr2_enabled || !dev_priv->psr.active)
+	if (!intel_dp->psr.psr2_enabled || !intel_dp->psr.active)
 		goto unlock;
 
 	/*
@@ -1741,15 +1776,15 @@ tgl_dc3co_flush(struct drm_i915_private *dev_priv,
 	 * when delayed work schedules that means display has been idle.
 	 */
 	if (!(frontbuffer_bits &
-	    INTEL_FRONTBUFFER_ALL_MASK(dev_priv->psr.pipe)))
+	    INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe)))
 		goto unlock;
 
-	tgl_psr2_enable_dc3co(dev_priv);
-	mod_delayed_work(system_wq, &dev_priv->psr.dc3co_work,
-			 dev_priv->psr.dc3co_exit_delay);
+	tgl_psr2_enable_dc3co(intel_dp);
+	mod_delayed_work(system_wq, &intel_dp->psr.dc3co_work,
+			 intel_dp->psr.dc3co_exit_delay);
 
 unlock:
-	mutex_unlock(&dev_priv->psr.lock);
+	mutex_unlock(&intel_dp->psr.lock);
 }
 
 /**
@@ -1768,45 +1803,57 @@ tgl_dc3co_flush(struct drm_i915_private *dev_priv,
 void intel_psr_flush(struct drm_i915_private *dev_priv,
 		     unsigned frontbuffer_bits, enum fb_op_origin origin)
 {
-	if (!CAN_PSR(dev_priv))
-		return;
+	struct intel_encoder *encoder;
+	struct intel_dp *intel_dp;
 
-	if (origin == ORIGIN_FLIP) {
-		tgl_dc3co_flush(dev_priv, frontbuffer_bits, origin);
-		return;
-	}
+	for_each_intel_dp(&dev_priv->drm, encoder) {
+		intel_dp = enc_to_intel_dp(encoder);
 
-	mutex_lock(&dev_priv->psr.lock);
-	if (!dev_priv->psr.enabled) {
-		mutex_unlock(&dev_priv->psr.lock);
-		return;
-	}
+		if (CAN_PSR(intel_dp)) {
+			unsigned pipe_frontbuffer_bits = frontbuffer_bits;
 
-	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(dev_priv->psr.pipe);
-	dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits;
+			if (origin == ORIGIN_FLIP) {
+				tgl_dc3co_flush(intel_dp, frontbuffer_bits, origin);
+				continue;
+			}
+
+			mutex_lock(&intel_dp->psr.lock);
+			if (!intel_dp->psr.enabled) {
+				mutex_unlock(&intel_dp->psr.lock);
+				continue;
+			}
 
-	/* By definition flush = invalidate + flush */
-	if (frontbuffer_bits)
-		psr_force_hw_tracking_exit(dev_priv);
+			pipe_frontbuffer_bits &=
+				INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe);
+			intel_dp->psr.busy_frontbuffer_bits &= ~pipe_frontbuffer_bits;
 
-	if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits)
-		schedule_work(&dev_priv->psr.work);
-	mutex_unlock(&dev_priv->psr.lock);
+			/* By definition flush = invalidate + flush */
+			if (pipe_frontbuffer_bits)
+				psr_force_hw_tracking_exit(intel_dp);
+
+			if (!intel_dp->psr.active && !intel_dp->psr.busy_frontbuffer_bits)
+				schedule_work(&intel_dp->psr.work);
+			mutex_unlock(&intel_dp->psr.lock);
+		}
+	}
 }
 
 /**
  * intel_psr_init - Init basic PSR work and mutex.
- * @dev_priv: i915 device private
+ * @intel_dp: Intel DP
  *
- * This function is  called only once at driver load to initialize basic
- * PSR stuff.
+ * This function is called after the initializing connector.
+ * (the initializing of connector treats the handling of connector capabilities)
+ * And it initializes basic PSR stuff for each DP Encoder.
  */
-void intel_psr_init(struct drm_i915_private *dev_priv)
+void intel_psr_init(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+
 	if (!HAS_PSR(dev_priv))
 		return;
 
-	if (!dev_priv->psr.sink_support)
+	if (!intel_dp->psr.sink_support)
 		return;
 
 	if (IS_HASWELL(dev_priv))
@@ -1824,14 +1871,14 @@ void intel_psr_init(struct drm_i915_private *dev_priv)
 	/* Set link_standby x link_off defaults */
 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
 		/* HSW and BDW require workarounds that we don't implement. */
-		dev_priv->psr.link_standby = false;
+		intel_dp->psr.link_standby = false;
 	else if (INTEL_GEN(dev_priv) < 12)
 		/* For new platforms up to TGL let's respect VBT back again */
-		dev_priv->psr.link_standby = dev_priv->vbt.psr.full_link;
+		intel_dp->psr.link_standby = dev_priv->vbt.psr.full_link;
 
-	INIT_WORK(&dev_priv->psr.work, intel_psr_work);
-	INIT_DELAYED_WORK(&dev_priv->psr.dc3co_work, tgl_dc3co_disable_work);
-	mutex_init(&dev_priv->psr.lock);
+	INIT_WORK(&intel_dp->psr.work, intel_psr_work);
+	INIT_DELAYED_WORK(&intel_dp->psr.dc3co_work, tgl_dc3co_disable_work);
+	mutex_init(&intel_dp->psr.lock);
 }
 
 static int psr_get_status_and_error_status(struct intel_dp *intel_dp,
@@ -1857,7 +1904,7 @@ static void psr_alpm_check(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	struct drm_dp_aux *aux = &intel_dp->aux;
-	struct i915_psr *psr = &dev_priv->psr;
+	struct intel_psr *psr = &intel_dp->psr;
 	u8 val;
 	int r;
 
@@ -1884,7 +1931,7 @@ static void psr_alpm_check(struct intel_dp *intel_dp)
 static void psr_capability_changed_check(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-	struct i915_psr *psr = &dev_priv->psr;
+	struct intel_psr *psr = &intel_dp->psr;
 	u8 val;
 	int r;
 
@@ -1908,18 +1955,18 @@ static void psr_capability_changed_check(struct intel_dp *intel_dp)
 void intel_psr_short_pulse(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-	struct i915_psr *psr = &dev_priv->psr;
+	struct intel_psr *psr = &intel_dp->psr;
 	u8 status, error_status;
 	const u8 errors = DP_PSR_RFB_STORAGE_ERROR |
 			  DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR |
 			  DP_PSR_LINK_CRC_ERROR;
 
-	if (!CAN_PSR(dev_priv) || !intel_dp_is_edp(intel_dp))
+	if (!CAN_PSR(intel_dp) || !intel_dp_is_edp(intel_dp))
 		return;
 
 	mutex_lock(&psr->lock);
 
-	if (!psr->enabled || psr->dp != intel_dp)
+	if (!psr->enabled)
 		goto exit;
 
 	if (psr_get_status_and_error_status(intel_dp, &status, &error_status)) {
@@ -1962,15 +2009,14 @@ void intel_psr_short_pulse(struct intel_dp *intel_dp)
 
 bool intel_psr_enabled(struct intel_dp *intel_dp)
 {
-	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	bool ret;
 
-	if (!CAN_PSR(dev_priv) || !intel_dp_is_edp(intel_dp))
+	if (!CAN_PSR(intel_dp) || !intel_dp_is_edp(intel_dp))
 		return false;
 
-	mutex_lock(&dev_priv->psr.lock);
-	ret = (dev_priv->psr.dp == intel_dp && dev_priv->psr.enabled);
-	mutex_unlock(&dev_priv->psr.lock);
+	mutex_lock(&intel_dp->psr.lock);
+	ret = intel_dp->psr.enabled;
+	mutex_unlock(&intel_dp->psr.lock);
 
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
index 0a517978e8af..2753976acc26 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.h
+++ b/drivers/gpu/drm/i915/display/intel_psr.h
@@ -18,7 +18,7 @@ struct intel_atomic_state;
 struct intel_plane_state;
 struct intel_plane;
 
-#define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support)
+#define CAN_PSR(intel_dp) (HAS_PSR(dp_to_i915(intel_dp)) && intel_dp->psr.sink_support)
 void intel_psr_init_dpcd(struct intel_dp *intel_dp);
 void intel_psr_enable(struct intel_dp *intel_dp,
 		      const struct intel_crtc_state *crtc_state,
@@ -28,20 +28,19 @@ void intel_psr_disable(struct intel_dp *intel_dp,
 void intel_psr_update(struct intel_dp *intel_dp,
 		      const struct intel_crtc_state *crtc_state,
 		      const struct drm_connector_state *conn_state);
-int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 value);
+int intel_psr_debug_set(struct intel_dp *intel_dp, u64 value);
 void intel_psr_invalidate(struct drm_i915_private *dev_priv,
 			  unsigned frontbuffer_bits,
 			  enum fb_op_origin origin);
 void intel_psr_flush(struct drm_i915_private *dev_priv,
 		     unsigned frontbuffer_bits,
 		     enum fb_op_origin origin);
-void intel_psr_init(struct drm_i915_private *dev_priv);
+void intel_psr_init(struct intel_dp *intel_dp);
 void intel_psr_compute_config(struct intel_dp *intel_dp,
 			      struct intel_crtc_state *crtc_state);
-void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir);
+void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir);
 void intel_psr_short_pulse(struct intel_dp *intel_dp);
-int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state,
-			    u32 *out_value);
+void intel_psr_wait_for_idle(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);
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index 52120f56dc54..986028deffd2 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -96,7 +96,6 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
 	bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
 		intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);
 	DEFINE_WAIT(wait);
-	u32 psr_status;
 
 	if (new_crtc_state->uapi.async_flip)
 		return;
@@ -122,10 +121,7 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
 	 * VBL interrupts will start the PSR exit and prevent a PSR
 	 * re-entry as well.
 	 */
-	if (intel_psr_wait_for_idle(new_crtc_state, &psr_status))
-		drm_err(&dev_priv->drm,
-			"PSR idle timed out 0x%x, atomic update may fail\n",
-			psr_status);
+	intel_psr_wait_for_idle(new_crtc_state);
 
 	local_irq_disable();
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 3edc9c4f2d21..3816b12aac0c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -478,42 +478,6 @@ struct i915_drrs {
 	enum drrs_support_type type;
 };
 
-struct i915_psr {
-	struct mutex lock;
-
-#define I915_PSR_DEBUG_MODE_MASK	0x0f
-#define I915_PSR_DEBUG_DEFAULT		0x00
-#define I915_PSR_DEBUG_DISABLE		0x01
-#define I915_PSR_DEBUG_ENABLE		0x02
-#define I915_PSR_DEBUG_FORCE_PSR1	0x03
-#define I915_PSR_DEBUG_IRQ		0x10
-
-	u32 debug;
-	bool sink_support;
-	bool enabled;
-	struct intel_dp *dp;
-	enum pipe pipe;
-	enum transcoder transcoder;
-	bool active;
-	struct work_struct work;
-	unsigned busy_frontbuffer_bits;
-	bool sink_psr2_support;
-	bool link_standby;
-	bool colorimetry_support;
-	bool psr2_enabled;
-	bool psr2_sel_fetch_enabled;
-	u8 sink_sync_latency;
-	ktime_t last_entry_attempt;
-	ktime_t last_exit;
-	bool sink_not_reliable;
-	bool irq_aux_error;
-	u16 su_x_granularity;
-	bool dc3co_enabled;
-	u32 dc3co_exit_delay;
-	struct delayed_work dc3co_work;
-	struct drm_dp_vsc_sdp vsc;
-};
-
 #define QUIRK_LVDS_SSC_DISABLE (1<<1)
 #define QUIRK_INVERT_BRIGHTNESS (1<<2)
 #define QUIRK_BACKLIGHT_PRESENT (1<<3)
@@ -1041,8 +1005,6 @@ struct drm_i915_private {
 
 	struct i915_power_domains power_domains;
 
-	struct i915_psr psr;
-
 	struct i915_gpu_error gpu_error;
 
 	struct drm_i915_gem_object *vlv_pctx;
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index a31980f69120..907a366e9c32 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2088,10 +2088,22 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
 		ivb_err_int_handler(dev_priv);
 
 	if (de_iir & DE_EDP_PSR_INT_HSW) {
-		u32 psr_iir = intel_uncore_read(&dev_priv->uncore, EDP_PSR_IIR);
+		struct intel_encoder *encoder;
 
-		intel_psr_irq_handler(dev_priv, psr_iir);
-		intel_uncore_write(&dev_priv->uncore, EDP_PSR_IIR, psr_iir);
+		for_each_intel_dp(&dev_priv->drm, encoder) {
+			struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+			if (encoder->type == INTEL_OUTPUT_EDP &&
+			    CAN_PSR(intel_dp)) {
+				u32 psr_iir = intel_uncore_read(&dev_priv->uncore,
+								EDP_PSR_IIR);
+
+				intel_psr_irq_handler(intel_dp, psr_iir);
+				intel_uncore_write(&dev_priv->uncore,
+						   EDP_PSR_IIR, psr_iir);
+				break;
+			}
+		}
 	}
 
 	if (de_iir & DE_AUX_CHANNEL_A_IVB)
@@ -2301,21 +2313,33 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir)
 	}
 
 	if (iir & GEN8_DE_EDP_PSR) {
+		struct intel_encoder *encoder;
 		u32 psr_iir;
 		i915_reg_t iir_reg;
 
-		if (INTEL_GEN(dev_priv) >= 12)
-			iir_reg = TRANS_PSR_IIR(dev_priv->psr.transcoder);
-		else
-			iir_reg = EDP_PSR_IIR;
+		for_each_intel_dp(&dev_priv->drm, encoder) {
+			struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+			if (!CAN_PSR(intel_dp))
+				continue;
+
+			if (INTEL_GEN(dev_priv) >= 12)
+				iir_reg = TRANS_PSR_IIR(intel_dp->psr.transcoder);
+			else
+				iir_reg = EDP_PSR_IIR;
 
-		psr_iir = intel_uncore_read(&dev_priv->uncore, iir_reg);
-		intel_uncore_write(&dev_priv->uncore, iir_reg, psr_iir);
+			psr_iir = intel_uncore_read(&dev_priv->uncore, iir_reg);
+			intel_uncore_write(&dev_priv->uncore, iir_reg, psr_iir);
 
-		if (psr_iir)
-			found = true;
+			if (psr_iir)
+				found = true;
 
-		intel_psr_irq_handler(dev_priv, psr_iir);
+			intel_psr_irq_handler(intel_dp, psr_iir);
+
+			/* prior GEN12 only have one EDP PSR */
+			if (INTEL_GEN(dev_priv) < 12)
+				break;
+		}
 	}
 
 	if (!found)
-- 
2.30.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Intel-gfx] [PATCH v13 2/2] drm/i915/display: Support Multiple Transcoders' PSR status on debugfs
  2021-01-27 17:23 [Intel-gfx] [PATCH v13 1/2] drm/i915/display: Support PSR Multiple Instances Gwan-gyeong Mun
@ 2021-01-27 17:23 ` Gwan-gyeong Mun
  2021-01-27 19:03 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v13,1/2] drm/i915/display: Support PSR Multiple Instances Patchwork
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Gwan-gyeong Mun @ 2021-01-27 17:23 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

In order to support the PSR state of each transcoder, it adds
i915_psr_status to sub-directory of each transcoder.

v2: Change using of Symbolic permissions 'S_IRUGO' to using of octal
    permissions '0444'
v5: Addressed JJani Nikula's review comments
 - Remove checking of Gen12 for i915_psr_status.
 - Add check of HAS_PSR()
 - Remove meaningless check routine.

Signed-off-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Cc: José Roberto de Souza <jose.souza@intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Anshuman Gupta <anshuman.gupta@intel.com>
Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>
---
 .../gpu/drm/i915/display/intel_display_debugfs.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 9868253df61f..c3ffa50d92b1 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -2223,6 +2223,16 @@ static int i915_hdcp_sink_capability_show(struct seq_file *m, void *data)
 }
 DEFINE_SHOW_ATTRIBUTE(i915_hdcp_sink_capability);
 
+static int i915_psr_status_show(struct seq_file *m, void *data)
+{
+	struct drm_connector *connector = m->private;
+	struct intel_dp *intel_dp =
+		intel_attached_dp(to_intel_connector(connector));
+
+	return intel_psr_status(m, intel_dp);
+}
+DEFINE_SHOW_ATTRIBUTE(i915_psr_status);
+
 #define LPSP_CAPABLE(COND) (COND ? seq_puts(m, "LPSP: capable\n") : \
 				seq_puts(m, "LPSP: incapable\n"))
 
@@ -2398,6 +2408,12 @@ int intel_connector_debugfs_add(struct drm_connector *connector)
 				    connector, &i915_psr_sink_status_fops);
 	}
 
+	if (HAS_PSR(dev_priv) &&
+	    connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+		debugfs_create_file("i915_psr_status", 0444, root,
+				    connector, &i915_psr_status_fops);
+	}
+
 	if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
 	    connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
 	    connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
-- 
2.30.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v13,1/2] drm/i915/display: Support PSR Multiple Instances
  2021-01-27 17:23 [Intel-gfx] [PATCH v13 1/2] drm/i915/display: Support PSR Multiple Instances Gwan-gyeong Mun
  2021-01-27 17:23 ` [Intel-gfx] [PATCH v13 2/2] drm/i915/display: Support Multiple Transcoders' PSR status on debugfs Gwan-gyeong Mun
@ 2021-01-27 19:03 ` Patchwork
  2021-01-27 19:04 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Patchwork @ 2021-01-27 19:03 UTC (permalink / raw)
  To: Gwan-gyeong Mun; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v13,1/2] drm/i915/display: Support PSR Multiple Instances
URL   : https://patchwork.freedesktop.org/series/86361/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
a69d1c74e99d drm/i915/display: Support PSR Multiple Instances
-:80: ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#80: FILE: drivers/gpu/drm/i915/display/intel_display.h:420:
+#define for_each_intel_encoder_is_psr_enabled(dev, intel_encoder, encoder_mask) \
+	list_for_each_entry(intel_encoder,				\
+			    &(dev)->mode_config.encoder_list,		\
+			    base.head)					\
+		for_each_if(((encoder_mask) &				\
+			     drm_encoder_mask(&intel_encoder->base)) &&	\
+			    intel_encoder_is_psr_enabled(intel_encoder))

-:80: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'intel_encoder' - possible side-effects?
#80: FILE: drivers/gpu/drm/i915/display/intel_display.h:420:
+#define for_each_intel_encoder_is_psr_enabled(dev, intel_encoder, encoder_mask) \
+	list_for_each_entry(intel_encoder,				\
+			    &(dev)->mode_config.encoder_list,		\
+			    base.head)					\
+		for_each_if(((encoder_mask) &				\
+			     drm_encoder_mask(&intel_encoder->base)) &&	\
+			    intel_encoder_is_psr_enabled(intel_encoder))

-:1464: WARNING:UNSPECIFIED_INT: Prefer 'unsigned int' to bare use of 'unsigned'
#1464: FILE: drivers/gpu/drm/i915/display/intel_psr.c:1731:
+		unsigned pipe_frontbuffer_bits = frontbuffer_bits;

-:1567: WARNING:UNSPECIFIED_INT: Prefer 'unsigned int' to bare use of 'unsigned'
#1567: FILE: drivers/gpu/drm/i915/display/intel_psr.c:1813:
+			unsigned pipe_frontbuffer_bits = frontbuffer_bits;

-:1716: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'intel_dp' - possible side-effects?
#1716: FILE: drivers/gpu/drm/i915/display/intel_psr.h:21:
+#define CAN_PSR(intel_dp) (HAS_PSR(dp_to_i915(intel_dp)) && intel_dp->psr.sink_support)

total: 1 errors, 2 warnings, 2 checks, 1713 lines checked
250803287c38 drm/i915/display: Support Multiple Transcoders' PSR status on debugfs


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for series starting with [v13,1/2] drm/i915/display: Support PSR Multiple Instances
  2021-01-27 17:23 [Intel-gfx] [PATCH v13 1/2] drm/i915/display: Support PSR Multiple Instances Gwan-gyeong Mun
  2021-01-27 17:23 ` [Intel-gfx] [PATCH v13 2/2] drm/i915/display: Support Multiple Transcoders' PSR status on debugfs Gwan-gyeong Mun
  2021-01-27 19:03 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v13,1/2] drm/i915/display: Support PSR Multiple Instances Patchwork
@ 2021-01-27 19:04 ` Patchwork
  2021-01-27 19:33 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Patchwork @ 2021-01-27 19:04 UTC (permalink / raw)
  To: Gwan-gyeong Mun; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v13,1/2] drm/i915/display: Support PSR Multiple Instances
URL   : https://patchwork.freedesktop.org/series/86361/
State : warning

== Summary ==

$ dim sparse --fast origin/drm-tip
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.
-
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:27:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:27:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:27:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:32:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:32:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:49:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:49:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:49:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:56:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:56:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_reset.c:1327:5: warning: context imbalance in 'intel_gt_reset_trylock' - different lock contexts for basic block
+drivers/gpu/drm/i915/gvt/mmio.c:295:23: warning: memcpy with byte count of 279040
+drivers/gpu/drm/i915/i915_perf.c:1450:15: warning: memset with byte count of 16777216
+drivers/gpu/drm/i915/i915_perf.c:1504:15: warning: memset with byte count of 16777216
+drivers/gpu/drm/i915/intel_wakeref.c:137:19: warning: context imbalance in 'wakeref_auto_timeout' - unexpected unlock
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_read16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_read32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_read64' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_read8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_read16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_read32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_read64' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_read8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_read16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_read32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_read64' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_read8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_read16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_read32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_read64' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_read8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen8_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen8_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen8_write8' - different lock contexts for basic block


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Intel-gfx] ✓ Fi.CI.BAT: success for series starting with [v13,1/2] drm/i915/display: Support PSR Multiple Instances
  2021-01-27 17:23 [Intel-gfx] [PATCH v13 1/2] drm/i915/display: Support PSR Multiple Instances Gwan-gyeong Mun
                   ` (2 preceding siblings ...)
  2021-01-27 19:04 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
@ 2021-01-27 19:33 ` Patchwork
  2021-01-27 20:43 ` [Intel-gfx] [PATCH v13 1/2] " Souza, Jose
  2021-01-27 23:39 ` [Intel-gfx] ✓ Fi.CI.IGT: success for series starting with [v13,1/2] " Patchwork
  5 siblings, 0 replies; 8+ messages in thread
From: Patchwork @ 2021-01-27 19:33 UTC (permalink / raw)
  To: Gwan-gyeong Mun; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 7888 bytes --]

== Series Details ==

Series: series starting with [v13,1/2] drm/i915/display: Support PSR Multiple Instances
URL   : https://patchwork.freedesktop.org/series/86361/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_9688 -> Patchwork_19523
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/index.html

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_19523:

### IGT changes ###

#### Suppressed ####

  The following results come from untrusted machines, tests, or statuses.
  They do not affect the overall result.

  * igt@kms_psr@cursor_plane_move:
    - {fi-rkl-11500t}:    [SKIP][1] ([i915#1072]) -> [SKIP][2] +3 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/fi-rkl-11500t/igt@kms_psr@cursor_plane_move.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/fi-rkl-11500t/igt@kms_psr@cursor_plane_move.html

  * igt@kms_psr@primary_mmap_gtt:
    - {fi-tgl-dsi}:       [SKIP][3] ([fdo#110189]) -> [SKIP][4] +3 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/fi-tgl-dsi/igt@kms_psr@primary_mmap_gtt.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/fi-tgl-dsi/igt@kms_psr@primary_mmap_gtt.html

  
Known issues
------------

  Here are the changes found in Patchwork_19523 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@debugfs_test@read_all_entries:
    - fi-tgl-y:           [PASS][5] -> [DMESG-WARN][6] ([i915#1982] / [i915#402])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/fi-tgl-y/igt@debugfs_test@read_all_entries.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/fi-tgl-y/igt@debugfs_test@read_all_entries.html

  * igt@gem_exec_suspend@basic-s0:
    - fi-tgl-u2:          [PASS][7] -> [FAIL][8] ([i915#1888])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/fi-tgl-u2/igt@gem_exec_suspend@basic-s0.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/fi-tgl-u2/igt@gem_exec_suspend@basic-s0.html

  * igt@gem_exec_suspend@basic-s3:
    - fi-tgl-y:           [PASS][9] -> [DMESG-WARN][10] ([i915#2411] / [i915#402])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/fi-tgl-y/igt@gem_exec_suspend@basic-s3.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/fi-tgl-y/igt@gem_exec_suspend@basic-s3.html

  * igt@gem_flink_basic@bad-flink:
    - fi-tgl-y:           [PASS][11] -> [DMESG-WARN][12] ([i915#402])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/fi-tgl-y/igt@gem_flink_basic@bad-flink.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/fi-tgl-y/igt@gem_flink_basic@bad-flink.html

  * igt@gem_huc_copy@huc-copy:
    - fi-byt-j1900:       NOTRUN -> [SKIP][13] ([fdo#109271]) +27 similar issues
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/fi-byt-j1900/igt@gem_huc_copy@huc-copy.html

  * igt@i915_selftest@live@execlists:
    - fi-bsw-n3050:       [PASS][14] -> [INCOMPLETE][15] ([i915#2940])
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/fi-bsw-n3050/igt@i915_selftest@live@execlists.html
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/fi-bsw-n3050/igt@i915_selftest@live@execlists.html

  * igt@kms_chamelium@hdmi-crc-fast:
    - fi-byt-j1900:       NOTRUN -> [SKIP][16] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/fi-byt-j1900/igt@kms_chamelium@hdmi-crc-fast.html

  * igt@runner@aborted:
    - fi-bsw-n3050:       NOTRUN -> [FAIL][17] ([i915#1436])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/fi-bsw-n3050/igt@runner@aborted.html

  
#### Possible fixes ####

  * igt@gem_basic@bad-close:
    - fi-tgl-y:           [DMESG-WARN][18] ([i915#402]) -> [PASS][19] +1 similar issue
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/fi-tgl-y/igt@gem_basic@bad-close.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/fi-tgl-y/igt@gem_basic@bad-close.html

  
#### Warnings ####

  * igt@i915_pm_backlight@basic-brightness:
    - fi-hsw-4770:        [SKIP][20] ([fdo#109271]) -> [SKIP][21] ([fdo#109271] / [i915#3012])
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/fi-hsw-4770/igt@i915_pm_backlight@basic-brightness.html
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/fi-hsw-4770/igt@i915_pm_backlight@basic-brightness.html

  * igt@kms_addfb_basic@addfb25-y-tiled-small-legacy:
    - fi-hsw-4770:        [SKIP][22] ([fdo#109271]) -> [SKIP][23] ([fdo#109271] / [fdo#109289])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/fi-hsw-4770/igt@kms_addfb_basic@addfb25-y-tiled-small-legacy.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/fi-hsw-4770/igt@kms_addfb_basic@addfb25-y-tiled-small-legacy.html

  * igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d:
    - fi-hsw-4770:        [SKIP][24] ([fdo#109271]) -> [SKIP][25] ([fdo#109271] / [i915#533])
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/fi-hsw-4770/igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d.html
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/fi-hsw-4770/igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d.html

  * igt@kms_psr@primary_mmap_gtt:
    - fi-hsw-4770:        [SKIP][26] ([fdo#109271] / [i915#1072]) -> [SKIP][27] ([fdo#109271]) +3 similar issues
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/fi-hsw-4770/igt@kms_psr@primary_mmap_gtt.html
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/fi-hsw-4770/igt@kms_psr@primary_mmap_gtt.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
  [fdo#110189]: https://bugs.freedesktop.org/show_bug.cgi?id=110189
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#1072]: https://gitlab.freedesktop.org/drm/intel/issues/1072
  [i915#1436]: https://gitlab.freedesktop.org/drm/intel/issues/1436
  [i915#1888]: https://gitlab.freedesktop.org/drm/intel/issues/1888
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#2411]: https://gitlab.freedesktop.org/drm/intel/issues/2411
  [i915#2601]: https://gitlab.freedesktop.org/drm/intel/issues/2601
  [i915#2940]: https://gitlab.freedesktop.org/drm/intel/issues/2940
  [i915#3011]: https://gitlab.freedesktop.org/drm/intel/issues/3011
  [i915#3012]: https://gitlab.freedesktop.org/drm/intel/issues/3012
  [i915#402]: https://gitlab.freedesktop.org/drm/intel/issues/402
  [i915#533]: https://gitlab.freedesktop.org/drm/intel/issues/533


Participating hosts (45 -> 39)
------------------------------

  Additional (1): fi-byt-j1900 
  Missing    (7): fi-jsl-1 fi-ilk-m540 fi-hsw-4200u fi-bsw-cyan fi-ctg-p8600 fi-cml-drallion fi-bdw-samus 


Build changes
-------------

  * Linux: CI_DRM_9688 -> Patchwork_19523

  CI-20190529: 20190529
  CI_DRM_9688: 43295c2b7bc37446a480bb5d42b03675baed171a @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5974: a85398dcae50930c0e27548cf8c9575ad0bf69d1 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_19523: 250803287c3872757c80d156180f520708efdd5e @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

250803287c38 drm/i915/display: Support Multiple Transcoders' PSR status on debugfs
a69d1c74e99d drm/i915/display: Support PSR Multiple Instances

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/index.html

[-- Attachment #1.2: Type: text/html, Size: 9590 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Intel-gfx] [PATCH v13 1/2] drm/i915/display: Support PSR Multiple Instances
  2021-01-27 17:23 [Intel-gfx] [PATCH v13 1/2] drm/i915/display: Support PSR Multiple Instances Gwan-gyeong Mun
                   ` (3 preceding siblings ...)
  2021-01-27 19:33 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
@ 2021-01-27 20:43 ` Souza, Jose
  2021-01-29  7:44   ` Mun, Gwan-gyeong
  2021-01-27 23:39 ` [Intel-gfx] ✓ Fi.CI.IGT: success for series starting with [v13,1/2] " Patchwork
  5 siblings, 1 reply; 8+ messages in thread
From: Souza, Jose @ 2021-01-27 20:43 UTC (permalink / raw)
  To: Mun, Gwan-gyeong, intel-gfx; +Cc: Nikula, Jani

On Wed, 2021-01-27 at 19:23 +0200, Gwan-gyeong Mun wrote:
> It is a preliminary work for supporting multiple EDP PSR and
> DP PanelReplay. And it refactors singleton PSR to Multi Transcoder
> supportable PSR.
> And this moves and renames the i915_psr structure of drm_i915_private's to
> intel_dp's intel_psr structure.
> It also causes changes in PSR interrupt handling routine for supporting
> multiple transcoders. But it does not change the scenario and timing of
> enabling and disabling PSR. And it not support multiple pipes with
> a single transcoder PSR case yet.
> 
> v2: Fix indentation and add comments
> v3: Remove Blank line
> v4: Rebased
> v5: Rebased and Addressed Anshuman's review comment.
>     - Move calling of intel_psr_init() to intel_dp_init_connector()
> v6: Address Anshuman's review comments
>    - Remove wrong comments and add comments for a limit of supporting of
>      a single pipe PSR
> v7: Update intel_psr_compute_config() for supporting multiple transcoder
>     PSR on BDW+
> v8: Address Anshuman's review comments
>    - Replace DRM_DEBUG_KMS with drm_dbg_kms() / DRM_WARN with drm_warn()
> v9: Fix commit message
> v10: Rebased
> v11: Address Jose's review comment.
>   - Reorder calling order of intel_psr2_program_trans_man_trk_ctl().
>   - In order to reduce changes keep the old name for drm_i915_private.
>   - Change restrictions of multiple instances of PSR.
> v12: Address Jose's review comment.
>   - Change the calling of intel_psr2_program_trans_man_trk_ctl() into
>     commit_pipe_config().
>   - Change a checking order of CAN_PSR() and connector_status to original
>     on i915_psr_sink_status_show().
>   - Drop unneeded intel_dp_update_pipe() function.
>   - In order to wait a specific encoder which belong to crtc_state on
>     intel_psr_wait_for_idle(), add checking of encoder.
>   - Add an whitespace to comments.
> v13: Rebased and Address Jose's review comment.
>   - Add and use for_each_intel_psr_enabled_encoder() macro.
>   - In order to use correct frontbuffer_bit for each pipe,
>     fix intel_psr_invalidate() and intel_psr_flush().
>   - Remove redundant or unneeded codes.
>   - Update comments.
> 
> Signed-off-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
> Cc: José Roberto de Souza <jose.souza@intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Anshuman Gupta <anshuman.gupta@intel.com>
> Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c  |   2 -
>  drivers/gpu/drm/i915/display/intel_display.h  |   8 +
>  .../drm/i915/display/intel_display_debugfs.c  | 105 +++-
>  .../drm/i915/display/intel_display_types.h    |  46 ++
>  drivers/gpu/drm/i915/display/intel_dp.c       |  10 +-
>  drivers/gpu/drm/i915/display/intel_psr.c      | 576 ++++++++++--------
>  drivers/gpu/drm/i915/display/intel_psr.h      |  11 +-
>  drivers/gpu/drm/i915/display/intel_sprite.c   |   6 +-
>  drivers/gpu/drm/i915/i915_drv.h               |  38 --
>  drivers/gpu/drm/i915/i915_irq.c               |  48 +-
>  10 files changed, 485 insertions(+), 365 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 667d941878a3..24df9dfb57fb 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -14135,8 +14135,6 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
>  		intel_dvo_init(dev_priv);
>  	}
>  
> 
> -	intel_psr_init(dev_priv);
> -
>  	for_each_intel_encoder(&dev_priv->drm, encoder) {
>  		encoder->base.possible_crtcs =
>  			intel_encoder_possible_crtcs(encoder);
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> index 64ffa34544a7..fc41d0d9e5a5 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -417,6 +417,14 @@ enum phy_fia {
>  		for_each_if((encoder_mask) &				\
>  			    drm_encoder_mask(&intel_encoder->base))
>  
> 
> +#define for_each_intel_encoder_is_psr_enabled(dev, intel_encoder, encoder_mask) \

I'm not a native speaker but "is" sounds wrong, maybe for_each_intel_encoder_with_psr_enabled()?


> +	list_for_each_entry(intel_encoder,				\
> +			    &(dev)->mode_config.encoder_list,		\
> +			    base.head)					\
> +		for_each_if(((encoder_mask) &				\
> +			     drm_encoder_mask(&intel_encoder->base)) &&	\
> +			    intel_encoder_is_psr_enabled(intel_encoder))

Looks like style is wrong here but bot will tell you if it is.

> +
>  #define for_each_intel_dp(dev, intel_encoder)			\
>  	for_each_intel_encoder(dev, intel_encoder)		\
>  		for_each_if(intel_encoder_is_dp(intel_encoder))
> diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> index d62b18d5ecd8..9868253df61f 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> @@ -249,12 +249,11 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data)
>  		"sink internal error",
>  	};
>  	struct drm_connector *connector = m->private;
> -	struct drm_i915_private *dev_priv = to_i915(connector->dev);
>  	struct intel_dp *intel_dp =
>  		intel_attached_dp(to_intel_connector(connector));
>  	int ret;
>  
> 
> -	if (!CAN_PSR(dev_priv)) {
> +	if (!CAN_PSR(intel_dp)) {
>  		seq_puts(m, "PSR Unsupported\n");
>  		return -ENODEV;
>  	}
> @@ -280,12 +279,13 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data)
>  DEFINE_SHOW_ATTRIBUTE(i915_psr_sink_status);
>  
> 
>  static void
> -psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m)
> +psr_source_status(struct intel_dp *intel_dp, struct seq_file *m)
>  {
>  	u32 val, status_val;
>  	const char *status = "unknown";
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  
> 
> -	if (dev_priv->psr.psr2_enabled) {
> +	if (intel_dp->psr.psr2_enabled) {
>  		static const char * const live_status[] = {
>  			"IDLE",
>  			"CAPTURE",
> @@ -300,7 +300,7 @@ psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m)
>  			"TG_ON"
>  		};
>  		val = intel_de_read(dev_priv,
> -				    EDP_PSR2_STATUS(dev_priv->psr.transcoder));
> +				    EDP_PSR2_STATUS(intel_dp->psr.transcoder));
>  		status_val = (val & EDP_PSR2_STATUS_STATE_MASK) >>
>  			      EDP_PSR2_STATUS_STATE_SHIFT;
>  		if (status_val < ARRAY_SIZE(live_status))
> @@ -317,7 +317,7 @@ psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m)
>  			"SRDENT_ON",
>  		};
>  		val = intel_de_read(dev_priv,
> -				    EDP_PSR_STATUS(dev_priv->psr.transcoder));
> +				    EDP_PSR_STATUS(intel_dp->psr.transcoder));
>  		status_val = (val & EDP_PSR_STATUS_STATE_MASK) >>
>  			      EDP_PSR_STATUS_STATE_SHIFT;
>  		if (status_val < ARRAY_SIZE(live_status))
> @@ -327,21 +327,18 @@ psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m)
>  	seq_printf(m, "Source PSR status: %s [0x%08x]\n", status, val);
>  }
>  
> 
> -static int i915_edp_psr_status(struct seq_file *m, void *data)
> +static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
>  {
> -	struct drm_i915_private *dev_priv = node_to_i915(m->private);
> -	struct i915_psr *psr = &dev_priv->psr;
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> +	struct intel_psr *psr = &intel_dp->psr;
>  	intel_wakeref_t wakeref;
>  	const char *status;
>  	bool enabled;
>  	u32 val;
>  
> 
> -	if (!HAS_PSR(dev_priv))
> -		return -ENODEV;
> -
>  	seq_printf(m, "Sink support: %s", yesno(psr->sink_support));
> -	if (psr->dp)
> -		seq_printf(m, " [0x%02x]", psr->dp->psr_dpcd[0]);
> +	if (psr->sink_support)
> +		seq_printf(m, " [0x%02x]", intel_dp->psr_dpcd[0]);
>  	seq_puts(m, "\n");
>  
> 
>  	if (!psr->sink_support)
> @@ -365,16 +362,16 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
>  
> 
>  	if (psr->psr2_enabled) {
>  		val = intel_de_read(dev_priv,
> -				    EDP_PSR2_CTL(dev_priv->psr.transcoder));
> +				    EDP_PSR2_CTL(intel_dp->psr.transcoder));
>  		enabled = val & EDP_PSR2_ENABLE;
>  	} else {
>  		val = intel_de_read(dev_priv,
> -				    EDP_PSR_CTL(dev_priv->psr.transcoder));
> +				    EDP_PSR_CTL(intel_dp->psr.transcoder));
>  		enabled = val & EDP_PSR_ENABLE;
>  	}
>  	seq_printf(m, "Source PSR ctl: %s [0x%08x]\n",
>  		   enableddisabled(enabled), val);
> -	psr_source_status(dev_priv, m);
> +	psr_source_status(intel_dp, m);
>  	seq_printf(m, "Busy frontbuffer bits: 0x%08x\n",
>  		   psr->busy_frontbuffer_bits);
>  
> 
> @@ -383,7 +380,7 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
>  	 */
>  	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
>  		val = intel_de_read(dev_priv,
> -				    EDP_PSR_PERF_CNT(dev_priv->psr.transcoder));
> +				    EDP_PSR_PERF_CNT(intel_dp->psr.transcoder));
>  		val &= EDP_PSR_PERF_CNT_MASK;
>  		seq_printf(m, "Performance counter: %u\n", val);
>  	}
> @@ -404,7 +401,7 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
>  		 */
>  		for (frame = 0; frame < PSR2_SU_STATUS_FRAMES; frame += 3) {
>  			val = intel_de_read(dev_priv,
> -					    PSR2_SU_STATUS(dev_priv->psr.transcoder, frame));
> +					    PSR2_SU_STATUS(intel_dp->psr.transcoder, frame));
>  			su_frames_val[frame / 3] = val;
>  		}
>  
> 
> @@ -430,23 +427,57 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
>  	return 0;
>  }
>  
> 
> +static int i915_edp_psr_status(struct seq_file *m, void *data)
> +{
> +	struct drm_i915_private *dev_priv = node_to_i915(m->private);
> +	struct intel_encoder *encoder;
> +	struct intel_dp *intel_dp = NULL;
> +
> +	if (!HAS_PSR(dev_priv))
> +		return -ENODEV;
> +
> +	/* Find the first EDP */
> +	for_each_intel_dp(&dev_priv->drm, encoder) {
> +		if (encoder->type == INTEL_OUTPUT_EDP) {
> +			intel_dp = enc_to_intel_dp(encoder);
> +			break;
> +		}
> +	}
> +
> +	if (!intel_dp)
> +		return -ENODEV;
> +
> +	return intel_psr_status(m, intel_dp);
> +}
> +
>  static int
>  i915_edp_psr_debug_set(void *data, u64 val)
>  {
>  	struct drm_i915_private *dev_priv = data;
>  	intel_wakeref_t wakeref;
> -	int ret;
> +	int ret = -ENODEV;
> +	struct intel_encoder *encoder;
>  
> 
> -	if (!CAN_PSR(dev_priv))
> -		return -ENODEV;
> +	if (!HAS_PSR(dev_priv))
> +		return ret;
>  
> 
> -	drm_dbg_kms(&dev_priv->drm, "Setting PSR debug to %llx\n", val);
> +	for_each_intel_dp(&dev_priv->drm, encoder) {
> +		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>  
> 
> -	wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
> +		if (!CAN_PSR(intel_dp))
> +			continue;
>  
> 
> -	ret = intel_psr_debug_set(dev_priv, val);
> +		if (encoder->type == INTEL_OUTPUT_EDP) {
> +			drm_dbg_kms(&dev_priv->drm, "Setting PSR debug to %llx\n", val);
>  
> 
> -	intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
> +			wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
> +
> +			// TODO: split to each transcoder's PSR debug state
> +			ret = intel_psr_debug_set(intel_dp, val);
> +
> +			intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
> +		}
> +	}
>  
> 
>  	return ret;
>  }
> @@ -455,12 +486,25 @@ static int
>  i915_edp_psr_debug_get(void *data, u64 *val)
>  {
>  	struct drm_i915_private *dev_priv = data;
> +	struct intel_encoder *encoder;
>  
> 
> -	if (!CAN_PSR(dev_priv))
> +	if (!HAS_PSR(dev_priv))
>  		return -ENODEV;
>  
> 
> -	*val = READ_ONCE(dev_priv->psr.debug);
> -	return 0;
> +	for_each_intel_dp(&dev_priv->drm, encoder) {
> +		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> +
> +		if (!CAN_PSR(intel_dp))
> +			continue;
> +
> +		// TODO: split to each transcoder's PSR debug state
> +		if (encoder->type == INTEL_OUTPUT_EDP) {
> +			*val = READ_ONCE(intel_dp->psr.debug);
> +			return 0;
> +		}
> +	}
> +
> +	return -ENODEV;
>  }
>  
> 
>  DEFINE_SIMPLE_ATTRIBUTE(i915_edp_psr_debug_fops,
> @@ -1233,9 +1277,6 @@ static void drrs_status_per_crtc(struct seq_file *m,
>  		/* disable_drrs() will make drrs->dp NULL */
>  		if (!drrs->dp) {
>  			seq_puts(m, "Idleness DRRS: Disabled\n");
> -			if (dev_priv->psr.enabled)
> -				seq_puts(m,
> -				"\tAs PSR is enabled, DRRS is not enabled\n");
>  			mutex_unlock(&drrs->mutex);
>  			return;
>  		}
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 39397748b4b0..63daf8b45941 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1415,6 +1415,42 @@ struct intel_pps {
>  	struct edp_power_seq pps_delays;
>  };
>  
> 
> +struct intel_psr {
> +	/* Mutex for PSR state of the transcoder */
> +	struct mutex lock;
> +
> +#define I915_PSR_DEBUG_MODE_MASK	0x0f
> +#define I915_PSR_DEBUG_DEFAULT		0x00
> +#define I915_PSR_DEBUG_DISABLE		0x01
> +#define I915_PSR_DEBUG_ENABLE		0x02
> +#define I915_PSR_DEBUG_FORCE_PSR1	0x03
> +#define I915_PSR_DEBUG_IRQ		0x10
> +
> +	u32 debug;
> +	bool sink_support;
> +	bool enabled;
> +	enum pipe pipe;
> +	enum transcoder transcoder;
> +	bool active;
> +	struct work_struct work;
> +	unsigned int busy_frontbuffer_bits;
> +	bool sink_psr2_support;
> +	bool link_standby;
> +	bool colorimetry_support;
> +	bool psr2_enabled;
> +	bool psr2_sel_fetch_enabled;
> +	u8 sink_sync_latency;
> +	ktime_t last_entry_attempt;
> +	ktime_t last_exit;
> +	bool sink_not_reliable;
> +	bool irq_aux_error;
> +	u16 su_x_granularity;
> +	bool dc3co_enabled;
> +	u32 dc3co_exit_delay;
> +	struct delayed_work dc3co_work;
> +	struct drm_dp_vsc_sdp vsc;
> +};
> +
>  struct intel_dp {
>  	i915_reg_t output_reg;
>  	u32 DP;
> @@ -1517,6 +1553,8 @@ struct intel_dp {
>  	bool hobl_active;
>  
> 
>  	struct intel_dp_pcon_frl frl;
> +
> +	struct intel_psr psr;
>  };
>  
> 
>  enum lspcon_vendor {
> @@ -1729,6 +1767,14 @@ static inline bool intel_encoder_is_dp(struct intel_encoder *encoder)
>  	}
>  }
>  
> 
> +static inline bool intel_encoder_is_psr_enabled(struct intel_encoder *encoder)
> +{
> +	if (!intel_encoder_is_dp(encoder))
> +		return false;
> +
> +	return enc_to_intel_dp(encoder)->psr.enabled;
> +}
> +
>  static inline struct intel_lspcon *
>  enc_to_intel_lspcon(struct intel_encoder *encoder)
>  {
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 8c12d5375607..d532bd56250f 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1663,12 +1663,10 @@ void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp,
>  				  const struct drm_connector_state *conn_state,
>  				  struct drm_dp_vsc_sdp *vsc)
>  {
> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -
>  	vsc->sdp_type = DP_SDP_VSC;
>  
> 
> -	if (dev_priv->psr.psr2_enabled) {
> -		if (dev_priv->psr.colorimetry_support &&
> +	if (intel_dp->psr.psr2_enabled) {
> +		if (intel_dp->psr.colorimetry_support &&
>  		    intel_dp_needs_vsc_sdp(crtc_state, conn_state)) {
>  			/* [PSR2, +Colorimetry] */
>  			intel_dp_compute_vsc_colorimetry(crtc_state, conn_state,
> @@ -2359,7 +2357,7 @@ bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
>  		return false;
>  	}
>  
> 
> -	if (CAN_PSR(i915) && intel_dp_is_edp(intel_dp)) {
> +	if (CAN_PSR(intel_dp) && intel_dp_is_edp(intel_dp)) {
>  		drm_dbg_kms(&i915->drm, "Forcing full modeset to compute PSR state\n");
>  		crtc_state->uapi.mode_changed = true;
>  		return false;
> @@ -6641,6 +6639,8 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
>  	intel_dp->frl.is_trained = false;
>  	intel_dp->frl.trained_rate_gbps = 0;
>  
> 
> +	intel_psr_init(intel_dp);
> +
>  	return true;
>  
> 
>  fail:
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
> index 2c365b778f74..925c0c6d92cd 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -80,9 +80,11 @@
>   * use page flips.
>   */
>  
> 
> -static bool psr_global_enabled(struct drm_i915_private *i915)
> +static bool psr_global_enabled(struct intel_dp *intel_dp)
>  {
> -	switch (i915->psr.debug & I915_PSR_DEBUG_MODE_MASK) {
> +	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> +
> +	switch (intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK) {
>  	case I915_PSR_DEBUG_DEFAULT:
>  		return i915->params.enable_psr;
>  	case I915_PSR_DEBUG_DISABLE:
> @@ -92,9 +94,9 @@ static bool psr_global_enabled(struct drm_i915_private *i915)
>  	}
>  }
>  
> 
> -static bool psr2_global_enabled(struct drm_i915_private *dev_priv)
> +static bool psr2_global_enabled(struct intel_dp *intel_dp)
>  {
> -	switch (dev_priv->psr.debug & I915_PSR_DEBUG_MODE_MASK) {
> +	switch (intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK) {
>  	case I915_PSR_DEBUG_DISABLE:
>  	case I915_PSR_DEBUG_FORCE_PSR1:
>  		return false;
> @@ -103,11 +105,12 @@ static bool psr2_global_enabled(struct drm_i915_private *dev_priv)
>  	}
>  }
>  
> 
> -static void psr_irq_control(struct drm_i915_private *dev_priv)
> +static void psr_irq_control(struct intel_dp *intel_dp)
>  {
>  	enum transcoder trans_shift;
>  	u32 mask, val;
>  	i915_reg_t imr_reg;
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  
> 
>  	/*
>  	 * gen12+ has registers relative to transcoder and one per transcoder
> @@ -116,14 +119,14 @@ static void psr_irq_control(struct drm_i915_private *dev_priv)
>  	 */
>  	if (INTEL_GEN(dev_priv) >= 12) {
>  		trans_shift = 0;
> -		imr_reg = TRANS_PSR_IMR(dev_priv->psr.transcoder);
> +		imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder);
>  	} else {
> -		trans_shift = dev_priv->psr.transcoder;
> +		trans_shift = intel_dp->psr.transcoder;
>  		imr_reg = EDP_PSR_IMR;
>  	}
>  
> 
>  	mask = EDP_PSR_ERROR(trans_shift);
> -	if (dev_priv->psr.debug & I915_PSR_DEBUG_IRQ)
> +	if (intel_dp->psr.debug & I915_PSR_DEBUG_IRQ)
>  		mask |= EDP_PSR_POST_EXIT(trans_shift) |
>  			EDP_PSR_PRE_ENTRY(trans_shift);
>  
> 
> @@ -172,30 +175,31 @@ static void psr_event_print(struct drm_i915_private *i915,
>  		drm_dbg_kms(&i915->drm, "\tPSR disabled\n");
>  }
>  
> 
> -void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir)
> +void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
>  {
> -	enum transcoder cpu_transcoder = dev_priv->psr.transcoder;
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> +	enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
>  	enum transcoder trans_shift;
>  	i915_reg_t imr_reg;
>  	ktime_t time_ns =  ktime_get();
>  
> 
>  	if (INTEL_GEN(dev_priv) >= 12) {
>  		trans_shift = 0;
> -		imr_reg = TRANS_PSR_IMR(dev_priv->psr.transcoder);
> +		imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder);
>  	} else {
> -		trans_shift = dev_priv->psr.transcoder;
> +		trans_shift = intel_dp->psr.transcoder;
>  		imr_reg = EDP_PSR_IMR;
>  	}
>  
> 
>  	if (psr_iir & EDP_PSR_PRE_ENTRY(trans_shift)) {
> -		dev_priv->psr.last_entry_attempt = time_ns;
> +		intel_dp->psr.last_entry_attempt = time_ns;
>  		drm_dbg_kms(&dev_priv->drm,
>  			    "[transcoder %s] PSR entry attempt in 2 vblanks\n",
>  			    transcoder_name(cpu_transcoder));
>  	}
>  
> 
>  	if (psr_iir & EDP_PSR_POST_EXIT(trans_shift)) {
> -		dev_priv->psr.last_exit = time_ns;
> +		intel_dp->psr.last_exit = time_ns;
>  		drm_dbg_kms(&dev_priv->drm,
>  			    "[transcoder %s] PSR exit completed\n",
>  			    transcoder_name(cpu_transcoder));
> @@ -203,7 +207,7 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir)
>  		if (INTEL_GEN(dev_priv) >= 9) {
>  			u32 val = intel_de_read(dev_priv,
>  						PSR_EVENT(cpu_transcoder));
> -			bool psr2_enabled = dev_priv->psr.psr2_enabled;
> +			bool psr2_enabled = intel_dp->psr.psr2_enabled;
>  
> 
>  			intel_de_write(dev_priv, PSR_EVENT(cpu_transcoder),
>  				       val);
> @@ -217,7 +221,7 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir)
>  		drm_warn(&dev_priv->drm, "[transcoder %s] PSR aux error\n",
>  			 transcoder_name(cpu_transcoder));
>  
> 
> -		dev_priv->psr.irq_aux_error = true;
> +		intel_dp->psr.irq_aux_error = true;
>  
> 
>  		/*
>  		 * If this interruption is not masked it will keep
> @@ -231,7 +235,7 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir)
>  		val |= EDP_PSR_ERROR(trans_shift);
>  		intel_de_write(dev_priv, imr_reg, val);
>  
> 
> -		schedule_work(&dev_priv->psr.work);
> +		schedule_work(&intel_dp->psr.work);
>  	}
>  }
>  
> 
> @@ -292,12 +296,6 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp)
>  	struct drm_i915_private *dev_priv =
>  		to_i915(dp_to_dig_port(intel_dp)->base.base.dev);
>  
> 
> -	if (dev_priv->psr.dp) {
> -		drm_warn(&dev_priv->drm,
> -			 "More than one eDP panel found, PSR support should be extended\n");
> -		return;
> -	}
> -
>  	drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT, intel_dp->psr_dpcd,
>  			 sizeof(intel_dp->psr_dpcd));
>  
> 
> @@ -318,12 +316,10 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp)
>  		return;
>  	}
>  
> 
> -	dev_priv->psr.sink_support = true;
> -	dev_priv->psr.sink_sync_latency =
> +	intel_dp->psr.sink_support = true;
> +	intel_dp->psr.sink_sync_latency =
>  		intel_dp_get_sink_sync_latency(intel_dp);
>  
> 
> -	dev_priv->psr.dp = intel_dp;
> -
>  	if (INTEL_GEN(dev_priv) >= 9 &&
>  	    (intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_IS_SUPPORTED)) {
>  		bool y_req = intel_dp->psr_dpcd[1] &
> @@ -341,14 +337,14 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp)
>  		 * Y-coordinate requirement panels we would need to enable
>  		 * GTC first.
>  		 */
> -		dev_priv->psr.sink_psr2_support = y_req && alpm;
> +		intel_dp->psr.sink_psr2_support = y_req && alpm;
>  		drm_dbg_kms(&dev_priv->drm, "PSR2 %ssupported\n",
> -			    dev_priv->psr.sink_psr2_support ? "" : "not ");
> +			    intel_dp->psr.sink_psr2_support ? "" : "not ");
>  
> 
> -		if (dev_priv->psr.sink_psr2_support) {
> -			dev_priv->psr.colorimetry_support =
> +		if (intel_dp->psr.sink_psr2_support) {
> +			intel_dp->psr.colorimetry_support =
>  				intel_dp_get_colorimetry_status(intel_dp);
> -			dev_priv->psr.su_x_granularity =
> +			intel_dp->psr.su_x_granularity =
>  				intel_dp_get_su_x_granulartiy(intel_dp);
>  		}
>  	}
> @@ -374,7 +370,7 @@ static void hsw_psr_setup_aux(struct intel_dp *intel_dp)
>  	BUILD_BUG_ON(sizeof(aux_msg) > 20);
>  	for (i = 0; i < sizeof(aux_msg); i += 4)
>  		intel_de_write(dev_priv,
> -			       EDP_PSR_AUX_DATA(dev_priv->psr.transcoder, i >> 2),
> +			       EDP_PSR_AUX_DATA(intel_dp->psr.transcoder, i >> 2),
>  			       intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i));
>  
> 
>  	aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0);
> @@ -385,7 +381,7 @@ static void hsw_psr_setup_aux(struct intel_dp *intel_dp)
>  
> 
>  	/* Select only valid bits for SRD_AUX_CTL */
>  	aux_ctl &= psr_aux_mask;
> -	intel_de_write(dev_priv, EDP_PSR_AUX_CTL(dev_priv->psr.transcoder),
> +	intel_de_write(dev_priv, EDP_PSR_AUX_CTL(intel_dp->psr.transcoder),
>  		       aux_ctl);
>  }
>  
> 
> @@ -395,14 +391,14 @@ static void intel_psr_enable_sink(struct intel_dp *intel_dp)
>  	u8 dpcd_val = DP_PSR_ENABLE;
>  
> 
>  	/* Enable ALPM at sink for psr2 */
> -	if (dev_priv->psr.psr2_enabled) {
> +	if (intel_dp->psr.psr2_enabled) {
>  		drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG,
>  				   DP_ALPM_ENABLE |
>  				   DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE);
>  
> 
>  		dpcd_val |= DP_PSR_ENABLE_PSR2 | DP_PSR_IRQ_HPD_WITH_CRC_ERRORS;
>  	} else {
> -		if (dev_priv->psr.link_standby)
> +		if (intel_dp->psr.link_standby)
>  			dpcd_val |= DP_PSR_MAIN_LINK_ACTIVE;
>  
> 
>  		if (INTEL_GEN(dev_priv) >= 8)
> @@ -465,7 +461,7 @@ static u8 psr_compute_idle_frames(struct intel_dp *intel_dp)
>  	 * off-by-one issue that HW has in some cases.
>  	 */
>  	idle_frames = max(6, dev_priv->vbt.psr.idle_frames);
> -	idle_frames = max(idle_frames, dev_priv->psr.sink_sync_latency + 1);
> +	idle_frames = max(idle_frames, intel_dp->psr.sink_sync_latency + 1);
>  
> 
>  	if (drm_WARN_ON(&dev_priv->drm, idle_frames > 0xf))
>  		idle_frames = 0xf;
> @@ -485,7 +481,7 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp)
>  	if (IS_HASWELL(dev_priv))
>  		val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES;
>  
> 
> -	if (dev_priv->psr.link_standby)
> +	if (intel_dp->psr.link_standby)
>  		val |= EDP_PSR_LINK_STANDBY;
>  
> 
>  	val |= intel_psr1_get_tp_time(intel_dp);
> @@ -493,9 +489,9 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp)
>  	if (INTEL_GEN(dev_priv) >= 8)
>  		val |= EDP_PSR_CRC_ENABLE;
>  
> 
> -	val |= (intel_de_read(dev_priv, EDP_PSR_CTL(dev_priv->psr.transcoder)) &
> +	val |= (intel_de_read(dev_priv, EDP_PSR_CTL(intel_dp->psr.transcoder)) &
>  		EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK);
> -	intel_de_write(dev_priv, EDP_PSR_CTL(dev_priv->psr.transcoder), val);
> +	intel_de_write(dev_priv, EDP_PSR_CTL(intel_dp->psr.transcoder), val);
>  }
>  
> 
>  static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp)
> @@ -530,7 +526,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
>  	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
>  		val |= EDP_Y_COORDINATE_ENABLE;
>  
> 
> -	val |= EDP_PSR2_FRAME_BEFORE_SU(dev_priv->psr.sink_sync_latency + 1);
> +	val |= EDP_PSR2_FRAME_BEFORE_SU(intel_dp->psr.sink_sync_latency + 1);
>  	val |= intel_psr2_get_tp_time(intel_dp);
>  
> 
>  	if (INTEL_GEN(dev_priv) >= 12) {
> @@ -549,7 +545,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
>  		val |= EDP_PSR2_FAST_WAKE(7);
>  	}
>  
> 
> -	if (dev_priv->psr.psr2_sel_fetch_enabled) {
> +	if (intel_dp->psr.psr2_sel_fetch_enabled) {
>  		/* WA 1408330847 */
>  		if (IS_TGL_DISP_STEPPING(dev_priv, STEP_A0, STEP_A0) ||
>  		    IS_RKL_REVID(dev_priv, RKL_REVID_A0, RKL_REVID_A0))
> @@ -558,20 +554,20 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
>  				     DIS_RAM_BYPASS_PSR2_MAN_TRACK);
>  
> 
>  		intel_de_write(dev_priv,
> -			       PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder),
> +			       PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder),
>  			       PSR2_MAN_TRK_CTL_ENABLE);
>  	} else if (HAS_PSR2_SEL_FETCH(dev_priv)) {
>  		intel_de_write(dev_priv,
> -			       PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder), 0);
> +			       PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder), 0);
>  	}
>  
> 
>  	/*
>  	 * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and BSpec is
>  	 * recommending keep this bit unset while PSR2 is enabled.
>  	 */
> -	intel_de_write(dev_priv, EDP_PSR_CTL(dev_priv->psr.transcoder), 0);
> +	intel_de_write(dev_priv, EDP_PSR_CTL(intel_dp->psr.transcoder), 0);
>  
> 
> -	intel_de_write(dev_priv, EDP_PSR2_CTL(dev_priv->psr.transcoder), val);
> +	intel_de_write(dev_priv, EDP_PSR2_CTL(intel_dp->psr.transcoder), val);
>  }
>  
> 
>  static bool
> @@ -594,55 +590,58 @@ static u32 intel_get_frame_time_us(const struct intel_crtc_state *cstate)
>  			    drm_mode_vrefresh(&cstate->hw.adjusted_mode));
>  }
>  
> 
> -static void psr2_program_idle_frames(struct drm_i915_private *dev_priv,
> +static void psr2_program_idle_frames(struct intel_dp *intel_dp,
>  				     u32 idle_frames)
>  {
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  	u32 val;
>  
> 
>  	idle_frames <<=  EDP_PSR2_IDLE_FRAME_SHIFT;
> -	val = intel_de_read(dev_priv, EDP_PSR2_CTL(dev_priv->psr.transcoder));
> +	val = intel_de_read(dev_priv, EDP_PSR2_CTL(intel_dp->psr.transcoder));
>  	val &= ~EDP_PSR2_IDLE_FRAME_MASK;
>  	val |= idle_frames;
> -	intel_de_write(dev_priv, EDP_PSR2_CTL(dev_priv->psr.transcoder), val);
> +	intel_de_write(dev_priv, EDP_PSR2_CTL(intel_dp->psr.transcoder), val);
>  }
>  
> 
> -static void tgl_psr2_enable_dc3co(struct drm_i915_private *dev_priv)
> +static void tgl_psr2_enable_dc3co(struct intel_dp *intel_dp)
>  {
> -	psr2_program_idle_frames(dev_priv, 0);
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> +
> +	psr2_program_idle_frames(intel_dp, 0);
>  	intel_display_power_set_target_dc_state(dev_priv, DC_STATE_EN_DC3CO);
>  }
>  
> 
> -static void tgl_psr2_disable_dc3co(struct drm_i915_private *dev_priv)
> +static void tgl_psr2_disable_dc3co(struct intel_dp *intel_dp)
>  {
> -	struct intel_dp *intel_dp = dev_priv->psr.dp;
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  
> 
>  	intel_display_power_set_target_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6);
> -	psr2_program_idle_frames(dev_priv, psr_compute_idle_frames(intel_dp));
> +	psr2_program_idle_frames(intel_dp, psr_compute_idle_frames(intel_dp));
>  }
>  
> 
>  static void tgl_dc3co_disable_work(struct work_struct *work)
>  {
> -	struct drm_i915_private *dev_priv =
> -		container_of(work, typeof(*dev_priv), psr.dc3co_work.work);
> +	struct intel_dp *intel_dp =
> +		container_of(work, typeof(*intel_dp), psr.dc3co_work.work);
>  
> 
> -	mutex_lock(&dev_priv->psr.lock);
> +	mutex_lock(&intel_dp->psr.lock);
>  	/* If delayed work is pending, it is not idle */
> -	if (delayed_work_pending(&dev_priv->psr.dc3co_work))
> +	if (delayed_work_pending(&intel_dp->psr.dc3co_work))
>  		goto unlock;
>  
> 
> -	tgl_psr2_disable_dc3co(dev_priv);
> +	tgl_psr2_disable_dc3co(intel_dp);
>  unlock:
> -	mutex_unlock(&dev_priv->psr.lock);
> +	mutex_unlock(&intel_dp->psr.lock);
>  }
>  
> 
> -static void tgl_disallow_dc3co_on_psr2_exit(struct drm_i915_private *dev_priv)
> +static void tgl_disallow_dc3co_on_psr2_exit(struct intel_dp *intel_dp)
>  {
> -	if (!dev_priv->psr.dc3co_enabled)
> +	if (!intel_dp->psr.dc3co_enabled)
>  		return;
>  
> 
> -	cancel_delayed_work(&dev_priv->psr.dc3co_work);
> +	cancel_delayed_work(&intel_dp->psr.dc3co_work);
>  	/* Before PSR2 exit disallow dc3co*/
> -	tgl_psr2_disable_dc3co(dev_priv);
> +	tgl_psr2_disable_dc3co(intel_dp);
>  }
>  
> 
>  static void
> @@ -715,7 +714,7 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
>  	int crtc_vdisplay = crtc_state->hw.adjusted_mode.crtc_vdisplay;
>  	int psr_max_h = 0, psr_max_v = 0, max_bpp = 0;
>  
> 
> -	if (!dev_priv->psr.sink_psr2_support)
> +	if (!intel_dp->psr.sink_psr2_support)
>  		return false;
>  
> 
>  	if (!transcoder_has_psr2(dev_priv, crtc_state->cpu_transcoder)) {
> @@ -725,7 +724,7 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
>  		return false;
>  	}
>  
> 
> -	if (!psr2_global_enabled(dev_priv)) {
> +	if (!psr2_global_enabled(intel_dp)) {
>  		drm_dbg_kms(&dev_priv->drm, "PSR2 disabled by flag\n");
>  		return false;
>  	}
> @@ -774,10 +773,10 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
>  	 * only need to validate the SU block width is a multiple of
>  	 * x granularity.
>  	 */
> -	if (crtc_hdisplay % dev_priv->psr.su_x_granularity) {
> +	if (crtc_hdisplay % intel_dp->psr.su_x_granularity) {
>  		drm_dbg_kms(&dev_priv->drm,
>  			    "PSR2 not enabled, hdisplay(%d) not multiple of %d\n",
> -			    crtc_hdisplay, dev_priv->psr.su_x_granularity);
> +			    crtc_hdisplay, intel_dp->psr.su_x_granularity);
>  		return false;
>  	}
>  
> 
> @@ -819,13 +818,10 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
>  	if (crtc_state->vrr.enable)
>  		return;
>  
> 
> -	if (!CAN_PSR(dev_priv))
> +	if (!CAN_PSR(intel_dp))
>  		return;
>  
> 
> -	if (intel_dp != dev_priv->psr.dp)
> -		return;
> -
> -	if (!psr_global_enabled(dev_priv)) {
> +	if (!psr_global_enabled(intel_dp)) {
>  		drm_dbg_kms(&dev_priv->drm, "PSR disabled by flag\n");
>  		return;
>  	}
> @@ -833,16 +829,19 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
>  	/*
>  	 * HSW spec explicitly says PSR is tied to port A.
>  	 * BDW+ platforms have a instance of PSR registers per transcoder but
> -	 * for now it only supports one instance of PSR, so lets keep it
> -	 * hardcoded to PORT_A
> +	 * BDW, GEN9 and GEN11 are not validated by HW team in other transcoder
> +	 * than eDP one.
> +	 * For now it only supports one instance of PSR for BDW, GEN9 and GEN11.
> +	 * So lets keep it hardcoded to PORT_A for BDW, GEN9 and GEN11.
> +	 * But GEN12 supports a instance of PSR registers per transcoder.
>  	 */

Almost there but the instances are there intel_psr_init() will be executed but intel_psr_compute_config() will not let PSR to be enabled in a
transcoder that is not eDP/port A for GEN11 and older.

> -	if (dig_port->base.port != PORT_A) {
> +	if (INTEL_GEN(dev_priv) < 12 && dig_port->base.port != PORT_A) {
>  		drm_dbg_kms(&dev_priv->drm,
>  			    "PSR condition failed: Port not supported\n");
>  		return;
>  	}
>  
> 
> -	if (dev_priv->psr.sink_not_reliable) {
> +	if (intel_dp->psr.sink_not_reliable) {
>  		drm_dbg_kms(&dev_priv->drm,
>  			    "PSR sink implementation is not reliable\n");
>  		return;
> @@ -878,23 +877,24 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
>  static void intel_psr_activate(struct intel_dp *intel_dp)
>  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> +	enum transcoder transcoder = intel_dp->psr.transcoder;
>  
> 
> -	if (transcoder_has_psr2(dev_priv, dev_priv->psr.transcoder))
> +	if (transcoder_has_psr2(dev_priv, transcoder))
>  		drm_WARN_ON(&dev_priv->drm,
> -			    intel_de_read(dev_priv, EDP_PSR2_CTL(dev_priv->psr.transcoder)) & EDP_PSR2_ENABLE);
> +			    intel_de_read(dev_priv, EDP_PSR2_CTL(transcoder)) & EDP_PSR2_ENABLE);
>  
> 
>  	drm_WARN_ON(&dev_priv->drm,
> -		    intel_de_read(dev_priv, EDP_PSR_CTL(dev_priv->psr.transcoder)) & EDP_PSR_ENABLE);
> -	drm_WARN_ON(&dev_priv->drm, dev_priv->psr.active);
> -	lockdep_assert_held(&dev_priv->psr.lock);
> +		    intel_de_read(dev_priv, EDP_PSR_CTL(transcoder)) & EDP_PSR_ENABLE);
> +	drm_WARN_ON(&dev_priv->drm, intel_dp->psr.active);
> +	lockdep_assert_held(&intel_dp->psr.lock);
>  
> 
>  	/* psr1 and psr2 are mutually exclusive.*/
> -	if (dev_priv->psr.psr2_enabled)
> +	if (intel_dp->psr.psr2_enabled)
>  		hsw_activate_psr2(intel_dp);
>  	else
>  		hsw_activate_psr1(intel_dp);
>  
> 
> -	dev_priv->psr.active = true;
> +	intel_dp->psr.active = true;
>  }
>  
> 
>  static void intel_psr_enable_source(struct intel_dp *intel_dp,
> @@ -910,7 +910,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
>  	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
>  		hsw_psr_setup_aux(intel_dp);
>  
> 
> -	if (dev_priv->psr.psr2_enabled && (IS_GEN(dev_priv, 9) &&
> +	if (intel_dp->psr.psr2_enabled && (IS_GEN(dev_priv, 9) &&
>  					   !IS_GEMINILAKE(dev_priv))) {
>  		i915_reg_t reg = CHICKEN_TRANS(cpu_transcoder);
>  		u32 chicken = intel_de_read(dev_priv, reg);
> @@ -934,10 +934,10 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
>  	if (INTEL_GEN(dev_priv) < 11)
>  		mask |= EDP_PSR_DEBUG_MASK_DISP_REG_WRITE;
>  
> 
> -	intel_de_write(dev_priv, EDP_PSR_DEBUG(dev_priv->psr.transcoder),
> +	intel_de_write(dev_priv, EDP_PSR_DEBUG(intel_dp->psr.transcoder),
>  		       mask);
>  
> 
> -	psr_irq_control(dev_priv);
> +	psr_irq_control(intel_dp);
>  
> 
>  	if (crtc_state->dc3co_exitline) {
>  		u32 val;
> @@ -955,30 +955,30 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
>  
> 
>  	if (HAS_PSR_HW_TRACKING(dev_priv) && HAS_PSR2_SEL_FETCH(dev_priv))
>  		intel_de_rmw(dev_priv, CHICKEN_PAR1_1, IGNORE_PSR2_HW_TRACKING,
> -			     dev_priv->psr.psr2_sel_fetch_enabled ?
> +			     intel_dp->psr.psr2_sel_fetch_enabled ?
>  			     IGNORE_PSR2_HW_TRACKING : 0);
>  }
>  
> 
> -static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
> +static void intel_psr_enable_locked(struct intel_dp *intel_dp,
>  				    const struct intel_crtc_state *crtc_state,
>  				    const struct drm_connector_state *conn_state)
>  {
> -	struct intel_dp *intel_dp = dev_priv->psr.dp;
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
>  	struct intel_encoder *encoder = &dig_port->base;
>  	u32 val;
>  
> 
> -	drm_WARN_ON(&dev_priv->drm, dev_priv->psr.enabled);
> +	drm_WARN_ON(&dev_priv->drm, intel_dp->psr.enabled);
>  
> 
> -	dev_priv->psr.psr2_enabled = crtc_state->has_psr2;
> -	dev_priv->psr.busy_frontbuffer_bits = 0;
> -	dev_priv->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
> -	dev_priv->psr.dc3co_enabled = !!crtc_state->dc3co_exitline;
> -	dev_priv->psr.transcoder = crtc_state->cpu_transcoder;
> +	intel_dp->psr.psr2_enabled = crtc_state->has_psr2;
> +	intel_dp->psr.busy_frontbuffer_bits = 0;
> +	intel_dp->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
> +	intel_dp->psr.dc3co_enabled = !!crtc_state->dc3co_exitline;
> +	intel_dp->psr.transcoder = crtc_state->cpu_transcoder;
>  	/* DC5/DC6 requires at least 6 idle frames */
>  	val = usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 6);
> -	dev_priv->psr.dc3co_exit_delay = val;
> -	dev_priv->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch;
> +	intel_dp->psr.dc3co_exit_delay = val;
> +	intel_dp->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch;
>  
> 
>  	/*
>  	 * If a PSR error happened and the driver is reloaded, the EDP_PSR_IIR
> @@ -990,27 +990,27 @@ static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
>  	 */
>  	if (INTEL_GEN(dev_priv) >= 12) {
>  		val = intel_de_read(dev_priv,
> -				    TRANS_PSR_IIR(dev_priv->psr.transcoder));
> +				    TRANS_PSR_IIR(intel_dp->psr.transcoder));
>  		val &= EDP_PSR_ERROR(0);
>  	} else {
>  		val = intel_de_read(dev_priv, EDP_PSR_IIR);
> -		val &= EDP_PSR_ERROR(dev_priv->psr.transcoder);
> +		val &= EDP_PSR_ERROR(intel_dp->psr.transcoder);
>  	}
>  	if (val) {
> -		dev_priv->psr.sink_not_reliable = true;
> +		intel_dp->psr.sink_not_reliable = true;
>  		drm_dbg_kms(&dev_priv->drm,
>  			    "PSR interruption error set, not enabling PSR\n");
>  		return;
>  	}
>  
> 
>  	drm_dbg_kms(&dev_priv->drm, "Enabling PSR%s\n",
> -		    dev_priv->psr.psr2_enabled ? "2" : "1");
> +		    intel_dp->psr.psr2_enabled ? "2" : "1");
>  	intel_dp_compute_psr_vsc_sdp(intel_dp, crtc_state, conn_state,
> -				     &dev_priv->psr.vsc);
> -	intel_write_dp_vsc_sdp(encoder, crtc_state, &dev_priv->psr.vsc);
> +				     &intel_dp->psr.vsc);
> +	intel_write_dp_vsc_sdp(encoder, crtc_state, &intel_dp->psr.vsc);
>  	intel_psr_enable_sink(intel_dp);
>  	intel_psr_enable_source(intel_dp, crtc_state);
> -	dev_priv->psr.enabled = true;
> +	intel_dp->psr.enabled = true;
>  
> 
>  	intel_psr_activate(intel_dp);
>  }
> @@ -1029,7 +1029,7 @@ void intel_psr_enable(struct intel_dp *intel_dp,
>  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  
> 
> -	if (!CAN_PSR(dev_priv) || dev_priv->psr.dp != intel_dp)
> +	if (!CAN_PSR(intel_dp))
>  		return;
>  
> 
>  	if (!crtc_state->has_psr)
> @@ -1037,46 +1037,47 @@ void intel_psr_enable(struct intel_dp *intel_dp,
>  
> 
>  	drm_WARN_ON(&dev_priv->drm, dev_priv->drrs.dp);
>  
> 
> -	mutex_lock(&dev_priv->psr.lock);
> -	intel_psr_enable_locked(dev_priv, crtc_state, conn_state);
> -	mutex_unlock(&dev_priv->psr.lock);
> +	mutex_lock(&intel_dp->psr.lock);
> +	intel_psr_enable_locked(intel_dp, crtc_state, conn_state);
> +	mutex_unlock(&intel_dp->psr.lock);
>  }
>  
> 
> -static void intel_psr_exit(struct drm_i915_private *dev_priv)
> +static void intel_psr_exit(struct intel_dp *intel_dp)
>  {
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  	u32 val;
>  
> 
> -	if (!dev_priv->psr.active) {
> -		if (transcoder_has_psr2(dev_priv, dev_priv->psr.transcoder)) {
> +	if (!intel_dp->psr.active) {
> +		if (transcoder_has_psr2(dev_priv, intel_dp->psr.transcoder)) {
>  			val = intel_de_read(dev_priv,
> -					    EDP_PSR2_CTL(dev_priv->psr.transcoder));
> +					    EDP_PSR2_CTL(intel_dp->psr.transcoder));
>  			drm_WARN_ON(&dev_priv->drm, val & EDP_PSR2_ENABLE);
>  		}
>  
> 
>  		val = intel_de_read(dev_priv,
> -				    EDP_PSR_CTL(dev_priv->psr.transcoder));
> +				    EDP_PSR_CTL(intel_dp->psr.transcoder));
>  		drm_WARN_ON(&dev_priv->drm, val & EDP_PSR_ENABLE);
>  
> 
>  		return;
>  	}
>  
> 
> -	if (dev_priv->psr.psr2_enabled) {
> -		tgl_disallow_dc3co_on_psr2_exit(dev_priv);
> +	if (intel_dp->psr.psr2_enabled) {
> +		tgl_disallow_dc3co_on_psr2_exit(intel_dp);
>  		val = intel_de_read(dev_priv,
> -				    EDP_PSR2_CTL(dev_priv->psr.transcoder));
> +				    EDP_PSR2_CTL(intel_dp->psr.transcoder));
>  		drm_WARN_ON(&dev_priv->drm, !(val & EDP_PSR2_ENABLE));
>  		val &= ~EDP_PSR2_ENABLE;
>  		intel_de_write(dev_priv,
> -			       EDP_PSR2_CTL(dev_priv->psr.transcoder), val);
> +			       EDP_PSR2_CTL(intel_dp->psr.transcoder), val);
>  	} else {
>  		val = intel_de_read(dev_priv,
> -				    EDP_PSR_CTL(dev_priv->psr.transcoder));
> +				    EDP_PSR_CTL(intel_dp->psr.transcoder));
>  		drm_WARN_ON(&dev_priv->drm, !(val & EDP_PSR_ENABLE));
>  		val &= ~EDP_PSR_ENABLE;
>  		intel_de_write(dev_priv,
> -			       EDP_PSR_CTL(dev_priv->psr.transcoder), val);
> +			       EDP_PSR_CTL(intel_dp->psr.transcoder), val);
>  	}
> -	dev_priv->psr.active = false;
> +	intel_dp->psr.active = false;
>  }
>  
> 
>  static void intel_psr_disable_locked(struct intel_dp *intel_dp)
> @@ -1085,21 +1086,21 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
>  	i915_reg_t psr_status;
>  	u32 psr_status_mask;
>  
> 
> -	lockdep_assert_held(&dev_priv->psr.lock);
> +	lockdep_assert_held(&intel_dp->psr.lock);
>  
> 
> -	if (!dev_priv->psr.enabled)
> +	if (!intel_dp->psr.enabled)
>  		return;
>  
> 
>  	drm_dbg_kms(&dev_priv->drm, "Disabling PSR%s\n",
> -		    dev_priv->psr.psr2_enabled ? "2" : "1");
> +		    intel_dp->psr.psr2_enabled ? "2" : "1");
>  
> 
> -	intel_psr_exit(dev_priv);
> +	intel_psr_exit(intel_dp);
>  
> 
> -	if (dev_priv->psr.psr2_enabled) {
> -		psr_status = EDP_PSR2_STATUS(dev_priv->psr.transcoder);
> +	if (intel_dp->psr.psr2_enabled) {
> +		psr_status = EDP_PSR2_STATUS(intel_dp->psr.transcoder);
>  		psr_status_mask = EDP_PSR2_STATUS_STATE_MASK;
>  	} else {
> -		psr_status = EDP_PSR_STATUS(dev_priv->psr.transcoder);
> +		psr_status = EDP_PSR_STATUS(intel_dp->psr.transcoder);
>  		psr_status_mask = EDP_PSR_STATUS_STATE_MASK;
>  	}
>  
> 
> @@ -1109,7 +1110,7 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
>  		drm_err(&dev_priv->drm, "Timed out waiting PSR idle state\n");
>  
> 
>  	/* WA 1408330847 */
> -	if (dev_priv->psr.psr2_sel_fetch_enabled &&
> +	if (intel_dp->psr.psr2_sel_fetch_enabled &&
>  	    (IS_TGL_DISP_STEPPING(dev_priv, STEP_A0, STEP_A0) ||
>  	     IS_RKL_REVID(dev_priv, RKL_REVID_A0, RKL_REVID_A0)))
>  		intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
> @@ -1118,10 +1119,10 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
>  	/* Disable PSR on Sink */
>  	drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0);
>  
> 
> -	if (dev_priv->psr.psr2_enabled)
> +	if (intel_dp->psr.psr2_enabled)
>  		drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, 0);
>  
> 
> -	dev_priv->psr.enabled = false;
> +	intel_dp->psr.enabled = false;
>  }
>  
> 
>  /**
> @@ -1139,20 +1140,22 @@ void intel_psr_disable(struct intel_dp *intel_dp,
>  	if (!old_crtc_state->has_psr)
>  		return;
>  
> 
> -	if (drm_WARN_ON(&dev_priv->drm, !CAN_PSR(dev_priv)))
> +	if (drm_WARN_ON(&dev_priv->drm, !CAN_PSR(intel_dp)))
>  		return;
>  
> 
> -	mutex_lock(&dev_priv->psr.lock);
> +	mutex_lock(&intel_dp->psr.lock);
>  
> 
>  	intel_psr_disable_locked(intel_dp);
>  
> 
> -	mutex_unlock(&dev_priv->psr.lock);
> -	cancel_work_sync(&dev_priv->psr.work);
> -	cancel_delayed_work_sync(&dev_priv->psr.dc3co_work);
> +	mutex_unlock(&intel_dp->psr.lock);
> +	cancel_work_sync(&intel_dp->psr.work);
> +	cancel_delayed_work_sync(&intel_dp->psr.dc3co_work);
>  }
>  
> 
> -static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv)
> +static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp)
>  {
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> +
>  	if (IS_TIGERLAKE(dev_priv))
>  		/*
>  		 * Writes to CURSURFLIVE in TGL are causing IOMMU errors and
> @@ -1166,7 +1169,7 @@ static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv)
>  		 * So using this workaround until this issue is root caused
>  		 * and a better fix is found.
>  		 */
> -		intel_psr_exit(dev_priv);
> +		intel_psr_exit(intel_dp);
>  	else if (INTEL_GEN(dev_priv) >= 9)
>  		/*
>  		 * Display WA #0884: skl+
> @@ -1177,13 +1180,13 @@ static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv)
>  		 * but it makes more sense write to the current active
>  		 * pipe.
>  		 */
> -		intel_de_write(dev_priv, CURSURFLIVE(dev_priv->psr.pipe), 0);
> +		intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
>  	else
>  		/*
>  		 * A write to CURSURFLIVE do not cause HW tracking to exit PSR
>  		 * on older gens so doing the manual exit instead.
>  		 */
> -		intel_psr_exit(dev_priv);
> +		intel_psr_exit(intel_dp);
>  }
>  
> 
>  void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
> @@ -1231,16 +1234,19 @@ void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
>  
> 
>  void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	struct i915_psr *psr = &dev_priv->psr;
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> +	struct intel_encoder *encoder;
>  
> 
>  	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
>  	    !crtc_state->enable_psr2_sel_fetch)
>  		return;
>  
> 
> -	intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(psr->transcoder),
> -		       crtc_state->psr2_man_track_ctl);
> +	for_each_intel_encoder_is_psr_enabled(&dev_priv->drm, encoder,
> +					      crtc_state->uapi.encoder_mask) {
> +		intel_de_write(dev_priv,
> +			       PSR2_MAN_TRK_CTL(crtc_state->cpu_transcoder),
> +			       crtc_state->psr2_man_track_ctl);
> +	}
>  }
>  
> 
>  static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state,
> @@ -1435,13 +1441,13 @@ void intel_psr_update(struct intel_dp *intel_dp,
>  		      const struct drm_connector_state *conn_state)
>  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -	struct i915_psr *psr = &dev_priv->psr;
> +	struct intel_psr *psr = &intel_dp->psr;
>  	bool enable, psr2_enable;
>  
> 
> -	if (!CAN_PSR(dev_priv) || READ_ONCE(psr->dp) != intel_dp)
> +	if (!CAN_PSR(intel_dp))
>  		return;
>  
> 
> -	mutex_lock(&dev_priv->psr.lock);
> +	mutex_lock(&intel_dp->psr.lock);
>  
> 
>  	enable = crtc_state->has_psr;
>  	psr2_enable = crtc_state->has_psr2;
> @@ -1449,15 +1455,15 @@ void intel_psr_update(struct intel_dp *intel_dp,
>  	if (enable == psr->enabled && psr2_enable == psr->psr2_enabled) {
>  		/* Force a PSR exit when enabling CRC to avoid CRC timeouts */
>  		if (crtc_state->crc_enabled && psr->enabled)
> -			psr_force_hw_tracking_exit(dev_priv);
> +			psr_force_hw_tracking_exit(intel_dp);
>  		else if (INTEL_GEN(dev_priv) < 9 && psr->enabled) {
>  			/*
>  			 * Activate PSR again after a force exit when enabling
>  			 * CRC in older gens
>  			 */
> -			if (!dev_priv->psr.active &&
> -			    !dev_priv->psr.busy_frontbuffer_bits)
> -				schedule_work(&dev_priv->psr.work);
> +			if (!intel_dp->psr.active &&
> +			    !intel_dp->psr.busy_frontbuffer_bits)
> +				schedule_work(&intel_dp->psr.work);
>  		}
>  
> 
>  		goto unlock;
> @@ -1467,34 +1473,23 @@ void intel_psr_update(struct intel_dp *intel_dp,
>  		intel_psr_disable_locked(intel_dp);
>  
> 
>  	if (enable)
> -		intel_psr_enable_locked(dev_priv, crtc_state, conn_state);
> +		intel_psr_enable_locked(intel_dp, crtc_state, conn_state);
>  
> 
>  unlock:
> -	mutex_unlock(&dev_priv->psr.lock);
> +	mutex_unlock(&intel_dp->psr.lock);
>  }
>  
> 
>  /**
> - * intel_psr_wait_for_idle - wait for PSR1 to idle
> - * @new_crtc_state: new CRTC state
> + * psr_wait_for_idle - wait for PSR1 to idle
> + * @intel_dp: Intel DP
>   * @out_value: PSR status in case of failure
>   *
> - * This function is expected to be called from pipe_update_start() where it is
> - * not expected to race with PSR enable or disable.
> - *
>   * Returns: 0 on success or -ETIMEOUT if PSR status does not idle.
> + *
>   */
> -int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state,
> -			    u32 *out_value)
> +static int psr_wait_for_idle(struct intel_dp *intel_dp, u32 *out_value)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -
> -	if (!dev_priv->psr.enabled || !new_crtc_state->has_psr)
> -		return 0;
> -
> -	/* FIXME: Update this for PSR2 if we need to wait for idle */
> -	if (READ_ONCE(dev_priv->psr.psr2_enabled))
> -		return 0;
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  
> 
>  	/*
>  	 * From bspec: Panel Self Refresh (BDW+)
> @@ -1502,32 +1497,63 @@ int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state,
>  	 * 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(dev_priv->psr.transcoder),
> +					 EDP_PSR_STATUS(intel_dp->psr.transcoder),
>  					 EDP_PSR_STATUS_STATE_MASK,
>  					 EDP_PSR_STATUS_STATE_IDLE, 2, 50,
>  					 out_value);
>  }
>  
> 
> -static bool __psr_wait_for_idle_locked(struct drm_i915_private *dev_priv)
> +/**
> + * intel_psr_wait_for_idle - wait for PSR1 to idle
> + * @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)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(new_crtc_state->uapi.crtc->dev);
> +	struct intel_encoder *encoder;
> +
> +	if (!new_crtc_state->has_psr)
> +		return;
> +
> +	for_each_intel_encoder_is_psr_enabled(&dev_priv->drm, encoder,
> +					      new_crtc_state->uapi.encoder_mask) {
> +		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> +
> +		/* when the PSR1 is enabled */
> +		if (!intel_dp->psr.psr2_enabled) {
> +			u32 psr_status;

Better do:

if (intel_dp->psr.psr2_enabled)
	continue;

if (psr_wait_for_idle(intel_dp, &psr_status))
	...
	
You get rid of one indentation and makes easier to read.


> +
> +			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);
> +		}
> +	}
> +}
> +
> +static bool __psr_wait_for_idle_locked(struct intel_dp *intel_dp)
>  {
>  	i915_reg_t reg;
>  	u32 mask;
>  	int err;
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  
> 
> -	if (!dev_priv->psr.enabled)
> +	if (!intel_dp->psr.enabled)
>  		return false;
>  
> 
> -	if (dev_priv->psr.psr2_enabled) {
> -		reg = EDP_PSR2_STATUS(dev_priv->psr.transcoder);
> +	if (intel_dp->psr.psr2_enabled) {
> +		reg = EDP_PSR2_STATUS(intel_dp->psr.transcoder);
>  		mask = EDP_PSR2_STATUS_STATE_MASK;
>  	} else {
> -		reg = EDP_PSR_STATUS(dev_priv->psr.transcoder);
> +		reg = EDP_PSR_STATUS(intel_dp->psr.transcoder);
>  		mask = EDP_PSR_STATUS_STATE_MASK;
>  	}
>  
> 
> -	mutex_unlock(&dev_priv->psr.lock);
> +	mutex_unlock(&intel_dp->psr.lock);
>  
> 
>  	err = intel_de_wait_for_clear(dev_priv, reg, mask, 50);
>  	if (err)
> @@ -1535,8 +1561,8 @@ static bool __psr_wait_for_idle_locked(struct drm_i915_private *dev_priv)
>  			"Timed out waiting for PSR Idle for re-enable\n");
>  
> 
>  	/* After the unlocked wait, verify that PSR is still wanted! */
> -	mutex_lock(&dev_priv->psr.lock);
> -	return err == 0 && dev_priv->psr.enabled;
> +	mutex_lock(&intel_dp->psr.lock);
> +	return err == 0 && intel_dp->psr.enabled;
>  }
>  
> 
>  static int intel_psr_fastset_force(struct drm_i915_private *dev_priv)
> @@ -1602,11 +1628,12 @@ static int intel_psr_fastset_force(struct drm_i915_private *dev_priv)
>  	return err;
>  }
>  
> 
> -int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 val)
> +int intel_psr_debug_set(struct intel_dp *intel_dp, u64 val)
>  {
>  	const u32 mode = val & I915_PSR_DEBUG_MODE_MASK;
>  	u32 old_mode;
>  	int ret;
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);

Nit pick but if you check in other places we try to leave the biggest declaration at the top kinda of following inverted pyramid style, you are doing
this in other functions as well.

>  
> 
>  	if (val & ~(I915_PSR_DEBUG_IRQ | I915_PSR_DEBUG_MODE_MASK) ||
>  	    mode > I915_PSR_DEBUG_FORCE_PSR1) {
> @@ -1614,21 +1641,21 @@ int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 val)
>  		return -EINVAL;
>  	}
>  
> 
> -	ret = mutex_lock_interruptible(&dev_priv->psr.lock);
> +	ret = mutex_lock_interruptible(&intel_dp->psr.lock);
>  	if (ret)
>  		return ret;
>  
> 
> -	old_mode = dev_priv->psr.debug & I915_PSR_DEBUG_MODE_MASK;
> -	dev_priv->psr.debug = val;
> +	old_mode = intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK;
> +	intel_dp->psr.debug = val;
>  
> 
>  	/*
>  	 * Do it right away if it's already enabled, otherwise it will be done
>  	 * when enabling the source.
>  	 */
> -	if (dev_priv->psr.enabled)
> -		psr_irq_control(dev_priv);
> +	if (intel_dp->psr.enabled)
> +		psr_irq_control(intel_dp);
>  
> 
> -	mutex_unlock(&dev_priv->psr.lock);
> +	mutex_unlock(&intel_dp->psr.lock);
>  
> 
>  	if (old_mode != mode)
>  		ret = intel_psr_fastset_force(dev_priv);
> @@ -1636,28 +1663,28 @@ int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 val)
>  	return ret;
>  }
>  
> 
> -static void intel_psr_handle_irq(struct drm_i915_private *dev_priv)
> +static void intel_psr_handle_irq(struct intel_dp *intel_dp)
>  {
> -	struct i915_psr *psr = &dev_priv->psr;
> +	struct intel_psr *psr = &intel_dp->psr;
>  
> 
> -	intel_psr_disable_locked(psr->dp);
> +	intel_psr_disable_locked(intel_dp);
>  	psr->sink_not_reliable = true;
>  	/* let's make sure that sink is awaken */
> -	drm_dp_dpcd_writeb(&psr->dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
> +	drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
>  }
>  
> 
>  static void intel_psr_work(struct work_struct *work)
>  {
> -	struct drm_i915_private *dev_priv =
> -		container_of(work, typeof(*dev_priv), psr.work);
> +	struct intel_dp *intel_dp =
> +		container_of(work, typeof(*intel_dp), psr.work);
>  
> 
> -	mutex_lock(&dev_priv->psr.lock);
> +	mutex_lock(&intel_dp->psr.lock);
>  
> 
> -	if (!dev_priv->psr.enabled)
> +	if (!intel_dp->psr.enabled)
>  		goto unlock;
>  
> 
> -	if (READ_ONCE(dev_priv->psr.irq_aux_error))
> -		intel_psr_handle_irq(dev_priv);
> +	if (READ_ONCE(intel_dp->psr.irq_aux_error))
> +		intel_psr_handle_irq(intel_dp);
>  
> 
>  	/*
>  	 * We have to make sure PSR is ready for re-enable
> @@ -1665,7 +1692,7 @@ static void intel_psr_work(struct work_struct *work)
>  	 * PSR might take some time to get fully disabled
>  	 * and be ready for re-enable.
>  	 */
> -	if (!__psr_wait_for_idle_locked(dev_priv))
> +	if (!__psr_wait_for_idle_locked(intel_dp))
>  		goto unlock;
>  
> 
>  	/*
> @@ -1673,12 +1700,12 @@ static void intel_psr_work(struct work_struct *work)
>  	 * recheck. Since psr_flush first clears this and then reschedules we
>  	 * won't ever miss a flush when bailing out here.
>  	 */
> -	if (dev_priv->psr.busy_frontbuffer_bits || dev_priv->psr.active)
> +	if (intel_dp->psr.busy_frontbuffer_bits || intel_dp->psr.active)
>  		goto unlock;
>  
> 
> -	intel_psr_activate(dev_priv->psr.dp);
> +	intel_psr_activate(intel_dp);
>  unlock:
> -	mutex_unlock(&dev_priv->psr.lock);
> +	mutex_unlock(&intel_dp->psr.lock);
>  }
>  
> 
>  /**
> @@ -1697,27 +1724,35 @@ static void intel_psr_work(struct work_struct *work)
>  void intel_psr_invalidate(struct drm_i915_private *dev_priv,
>  			  unsigned frontbuffer_bits, enum fb_op_origin origin)
>  {
> -	if (!CAN_PSR(dev_priv))
> -		return;
> +	struct intel_encoder *encoder;
> +	struct intel_dp *intel_dp;
>  
> 
> -	if (origin == ORIGIN_FLIP)
> -		return;
> +	for_each_intel_dp(&dev_priv->drm, encoder) {
> +		unsigned pipe_frontbuffer_bits = frontbuffer_bits;

You could use for_each_intel_encoder_is_psr_enabled(), just setting all bits of encoder_mask.
CPU time will be almost identical but we can save some lines of code and keep it consistent.

>  
> 
> -	mutex_lock(&dev_priv->psr.lock);
> -	if (!dev_priv->psr.enabled) {
> -		mutex_unlock(&dev_priv->psr.lock);
> -		return;
> -	}
> +		intel_dp = enc_to_intel_dp(encoder);
> +		if (!CAN_PSR(intel_dp))
> +			continue;
> +
> +		if (origin == ORIGIN_FLIP)
> +			continue;


If origin == ORIGIN_FLIP why waster time iterating over any intel_dp?

> +
> +		mutex_lock(&intel_dp->psr.lock);
> +		if (!intel_dp->psr.enabled) {
> +			mutex_unlock(&intel_dp->psr.lock);
> +			continue;
> +		}
>  
> 
> -	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(dev_priv->psr.pipe);
> -	dev_priv->psr.busy_frontbuffer_bits |= frontbuffer_bits;
> +		pipe_frontbuffer_bits &=
> +			INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe);
> +		intel_dp->psr.busy_frontbuffer_bits |= pipe_frontbuffer_bits;
>  
> 
> -	if (frontbuffer_bits)
> -		intel_psr_exit(dev_priv);
> +		if (pipe_frontbuffer_bits)
> +			intel_psr_exit(intel_dp);
>  
> 
> -	mutex_unlock(&dev_priv->psr.lock);
> +		mutex_unlock(&intel_dp->psr.lock);
> +	}
>  }
> -
>  /*
>   * When we will be completely rely on PSR2 S/W tracking in future,
>   * intel_psr_flush() will invalidate and flush the PSR for ORIGIN_FLIP
> @@ -1725,15 +1760,15 @@ void intel_psr_invalidate(struct drm_i915_private *dev_priv,
>   * accordingly in future.
>   */
>  static void
> -tgl_dc3co_flush(struct drm_i915_private *dev_priv,
> -		unsigned int frontbuffer_bits, enum fb_op_origin origin)
> +tgl_dc3co_flush(struct intel_dp *intel_dp, unsigned int frontbuffer_bits,
> +		enum fb_op_origin origin)
>  {
> -	mutex_lock(&dev_priv->psr.lock);
> +	mutex_lock(&intel_dp->psr.lock);
>  
> 
> -	if (!dev_priv->psr.dc3co_enabled)
> +	if (!intel_dp->psr.dc3co_enabled)
>  		goto unlock;
>  
> 
> -	if (!dev_priv->psr.psr2_enabled || !dev_priv->psr.active)
> +	if (!intel_dp->psr.psr2_enabled || !intel_dp->psr.active)
>  		goto unlock;
>  
> 
>  	/*
> @@ -1741,15 +1776,15 @@ tgl_dc3co_flush(struct drm_i915_private *dev_priv,
>  	 * when delayed work schedules that means display has been idle.
>  	 */
>  	if (!(frontbuffer_bits &
> -	    INTEL_FRONTBUFFER_ALL_MASK(dev_priv->psr.pipe)))
> +	    INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe)))
>  		goto unlock;
>  
> 
> -	tgl_psr2_enable_dc3co(dev_priv);
> -	mod_delayed_work(system_wq, &dev_priv->psr.dc3co_work,
> -			 dev_priv->psr.dc3co_exit_delay);
> +	tgl_psr2_enable_dc3co(intel_dp);
> +	mod_delayed_work(system_wq, &intel_dp->psr.dc3co_work,
> +			 intel_dp->psr.dc3co_exit_delay);
>  
> 
>  unlock:
> -	mutex_unlock(&dev_priv->psr.lock);
> +	mutex_unlock(&intel_dp->psr.lock);
>  }
>  
> 
>  /**
> @@ -1768,45 +1803,57 @@ tgl_dc3co_flush(struct drm_i915_private *dev_priv,
>  void intel_psr_flush(struct drm_i915_private *dev_priv,
>  		     unsigned frontbuffer_bits, enum fb_op_origin origin)
>  {
> -	if (!CAN_PSR(dev_priv))
> -		return;
> +	struct intel_encoder *encoder;
> +	struct intel_dp *intel_dp;
>  
> 
> -	if (origin == ORIGIN_FLIP) {
> -		tgl_dc3co_flush(dev_priv, frontbuffer_bits, origin);
> -		return;
> -	}
> +	for_each_intel_dp(&dev_priv->drm, encoder) {
> +		intel_dp = enc_to_intel_dp(encoder);
>  
> 
> -	mutex_lock(&dev_priv->psr.lock);
> -	if (!dev_priv->psr.enabled) {
> -		mutex_unlock(&dev_priv->psr.lock);
> -		return;
> -	}
> +		if (CAN_PSR(intel_dp)) {

Again keep it consistent, in intel_psr_invalidate() you are doing
if (CAN_PSR(intel_dp))
	continue....
I prefer do that and save one tab even better if you use for_each_intel_encoder_is_psr_enabled().

> +			unsigned pipe_frontbuffer_bits = frontbuffer_bits;
>  
> 
> -	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(dev_priv->psr.pipe);
> -	dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits;
> +			if (origin == ORIGIN_FLIP) {
> +				tgl_dc3co_flush(intel_dp, frontbuffer_bits, origin);
> +				continue;

Here makes sense check if origin == ORIGIN_FLIP in the loop but that is not the case in _invalidade()

> +			}
> +
> +			mutex_lock(&intel_dp->psr.lock);
> +			if (!intel_dp->psr.enabled) {
> +				mutex_unlock(&intel_dp->psr.lock);
> +				continue;
> +			}
>  
> 
> -	/* By definition flush = invalidate + flush */
> -	if (frontbuffer_bits)
> -		psr_force_hw_tracking_exit(dev_priv);
> +			pipe_frontbuffer_bits &=
> +				INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe);
> +			intel_dp->psr.busy_frontbuffer_bits &= ~pipe_frontbuffer_bits;
>  
> 
> -	if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits)
> -		schedule_work(&dev_priv->psr.work);
> -	mutex_unlock(&dev_priv->psr.lock);
> +			/* By definition flush = invalidate + flush */
> +			if (pipe_frontbuffer_bits)
> +				psr_force_hw_tracking_exit(intel_dp);
> +
> +			if (!intel_dp->psr.active && !intel_dp->psr.busy_frontbuffer_bits)
> +				schedule_work(&intel_dp->psr.work);
> +			mutex_unlock(&intel_dp->psr.lock);
> +		}
> +	}
>  }
>  
> 
>  /**
>   * intel_psr_init - Init basic PSR work and mutex.
> - * @dev_priv: i915 device private
> + * @intel_dp: Intel DP
>   *
> - * This function is  called only once at driver load to initialize basic
> - * PSR stuff.
> + * This function is called after the initializing connector.
> + * (the initializing of connector treats the handling of connector capabilities)
> + * And it initializes basic PSR stuff for each DP Encoder.
>   */
> -void intel_psr_init(struct drm_i915_private *dev_priv)
> +void intel_psr_init(struct intel_dp *intel_dp)
>  {
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> +
>  	if (!HAS_PSR(dev_priv))
>  		return;
>  
> 
> -	if (!dev_priv->psr.sink_support)
> +	if (!intel_dp->psr.sink_support)
>  		return;
>  
> 
>  	if (IS_HASWELL(dev_priv))
> @@ -1824,14 +1871,14 @@ void intel_psr_init(struct drm_i915_private *dev_priv)
>  	/* Set link_standby x link_off defaults */
>  	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
>  		/* HSW and BDW require workarounds that we don't implement. */
> -		dev_priv->psr.link_standby = false;
> +		intel_dp->psr.link_standby = false;
>  	else if (INTEL_GEN(dev_priv) < 12)
>  		/* For new platforms up to TGL let's respect VBT back again */
> -		dev_priv->psr.link_standby = dev_priv->vbt.psr.full_link;
> +		intel_dp->psr.link_standby = dev_priv->vbt.psr.full_link;
>  
> 
> -	INIT_WORK(&dev_priv->psr.work, intel_psr_work);
> -	INIT_DELAYED_WORK(&dev_priv->psr.dc3co_work, tgl_dc3co_disable_work);
> -	mutex_init(&dev_priv->psr.lock);
> +	INIT_WORK(&intel_dp->psr.work, intel_psr_work);
> +	INIT_DELAYED_WORK(&intel_dp->psr.dc3co_work, tgl_dc3co_disable_work);
> +	mutex_init(&intel_dp->psr.lock);
>  }
>  
> 
>  static int psr_get_status_and_error_status(struct intel_dp *intel_dp,
> @@ -1857,7 +1904,7 @@ static void psr_alpm_check(struct intel_dp *intel_dp)
>  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  	struct drm_dp_aux *aux = &intel_dp->aux;
> -	struct i915_psr *psr = &dev_priv->psr;
> +	struct intel_psr *psr = &intel_dp->psr;
>  	u8 val;
>  	int r;
>  
> 
> @@ -1884,7 +1931,7 @@ static void psr_alpm_check(struct intel_dp *intel_dp)
>  static void psr_capability_changed_check(struct intel_dp *intel_dp)
>  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -	struct i915_psr *psr = &dev_priv->psr;
> +	struct intel_psr *psr = &intel_dp->psr;
>  	u8 val;
>  	int r;
>  
> 
> @@ -1908,18 +1955,18 @@ static void psr_capability_changed_check(struct intel_dp *intel_dp)
>  void intel_psr_short_pulse(struct intel_dp *intel_dp)
>  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -	struct i915_psr *psr = &dev_priv->psr;
> +	struct intel_psr *psr = &intel_dp->psr;
>  	u8 status, error_status;
>  	const u8 errors = DP_PSR_RFB_STORAGE_ERROR |
>  			  DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR |
>  			  DP_PSR_LINK_CRC_ERROR;
>  
> 
> -	if (!CAN_PSR(dev_priv) || !intel_dp_is_edp(intel_dp))
> +	if (!CAN_PSR(intel_dp) || !intel_dp_is_edp(intel_dp))
>  		return;
>  
> 
>  	mutex_lock(&psr->lock);
>  
> 
> -	if (!psr->enabled || psr->dp != intel_dp)
> +	if (!psr->enabled)
>  		goto exit;
>  
> 
>  	if (psr_get_status_and_error_status(intel_dp, &status, &error_status)) {
> @@ -1962,15 +2009,14 @@ void intel_psr_short_pulse(struct intel_dp *intel_dp)
>  
> 
>  bool intel_psr_enabled(struct intel_dp *intel_dp)
>  {
> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  	bool ret;
>  
> 
> -	if (!CAN_PSR(dev_priv) || !intel_dp_is_edp(intel_dp))
> +	if (!CAN_PSR(intel_dp) || !intel_dp_is_edp(intel_dp))
>  		return false;
>  
> 
> -	mutex_lock(&dev_priv->psr.lock);
> -	ret = (dev_priv->psr.dp == intel_dp && dev_priv->psr.enabled);
> -	mutex_unlock(&dev_priv->psr.lock);
> +	mutex_lock(&intel_dp->psr.lock);
> +	ret = intel_dp->psr.enabled;
> +	mutex_unlock(&intel_dp->psr.lock);
>  
> 
>  	return ret;
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
> index 0a517978e8af..2753976acc26 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.h
> +++ b/drivers/gpu/drm/i915/display/intel_psr.h
> @@ -18,7 +18,7 @@ struct intel_atomic_state;
>  struct intel_plane_state;
>  struct intel_plane;
>  
> 
> -#define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support)
> +#define CAN_PSR(intel_dp) (HAS_PSR(dp_to_i915(intel_dp)) && intel_dp->psr.sink_support)
>  void intel_psr_init_dpcd(struct intel_dp *intel_dp);
>  void intel_psr_enable(struct intel_dp *intel_dp,
>  		      const struct intel_crtc_state *crtc_state,
> @@ -28,20 +28,19 @@ void intel_psr_disable(struct intel_dp *intel_dp,
>  void intel_psr_update(struct intel_dp *intel_dp,
>  		      const struct intel_crtc_state *crtc_state,
>  		      const struct drm_connector_state *conn_state);
> -int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 value);
> +int intel_psr_debug_set(struct intel_dp *intel_dp, u64 value);
>  void intel_psr_invalidate(struct drm_i915_private *dev_priv,
>  			  unsigned frontbuffer_bits,
>  			  enum fb_op_origin origin);
>  void intel_psr_flush(struct drm_i915_private *dev_priv,
>  		     unsigned frontbuffer_bits,
>  		     enum fb_op_origin origin);
> -void intel_psr_init(struct drm_i915_private *dev_priv);
> +void intel_psr_init(struct intel_dp *intel_dp);
>  void intel_psr_compute_config(struct intel_dp *intel_dp,
>  			      struct intel_crtc_state *crtc_state);
> -void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir);
> +void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir);
>  void intel_psr_short_pulse(struct intel_dp *intel_dp);
> -int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state,
> -			    u32 *out_value);
> +void intel_psr_wait_for_idle(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);
> diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
> index 52120f56dc54..986028deffd2 100644
> --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> @@ -96,7 +96,6 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
>  	bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
>  		intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);
>  	DEFINE_WAIT(wait);
> -	u32 psr_status;
>  
> 
>  	if (new_crtc_state->uapi.async_flip)
>  		return;
> @@ -122,10 +121,7 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
>  	 * VBL interrupts will start the PSR exit and prevent a PSR
>  	 * re-entry as well.
>  	 */
> -	if (intel_psr_wait_for_idle(new_crtc_state, &psr_status))
> -		drm_err(&dev_priv->drm,
> -			"PSR idle timed out 0x%x, atomic update may fail\n",
> -			psr_status);
> +	intel_psr_wait_for_idle(new_crtc_state);
>  
> 
>  	local_irq_disable();
>  
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 3edc9c4f2d21..3816b12aac0c 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -478,42 +478,6 @@ struct i915_drrs {
>  	enum drrs_support_type type;
>  };
>  
> 
> -struct i915_psr {
> -	struct mutex lock;
> -
> -#define I915_PSR_DEBUG_MODE_MASK	0x0f
> -#define I915_PSR_DEBUG_DEFAULT		0x00
> -#define I915_PSR_DEBUG_DISABLE		0x01
> -#define I915_PSR_DEBUG_ENABLE		0x02
> -#define I915_PSR_DEBUG_FORCE_PSR1	0x03
> -#define I915_PSR_DEBUG_IRQ		0x10
> -
> -	u32 debug;
> -	bool sink_support;
> -	bool enabled;
> -	struct intel_dp *dp;
> -	enum pipe pipe;
> -	enum transcoder transcoder;
> -	bool active;
> -	struct work_struct work;
> -	unsigned busy_frontbuffer_bits;
> -	bool sink_psr2_support;
> -	bool link_standby;
> -	bool colorimetry_support;
> -	bool psr2_enabled;
> -	bool psr2_sel_fetch_enabled;
> -	u8 sink_sync_latency;
> -	ktime_t last_entry_attempt;
> -	ktime_t last_exit;
> -	bool sink_not_reliable;
> -	bool irq_aux_error;
> -	u16 su_x_granularity;
> -	bool dc3co_enabled;
> -	u32 dc3co_exit_delay;
> -	struct delayed_work dc3co_work;
> -	struct drm_dp_vsc_sdp vsc;
> -};
> -
>  #define QUIRK_LVDS_SSC_DISABLE (1<<1)
>  #define QUIRK_INVERT_BRIGHTNESS (1<<2)
>  #define QUIRK_BACKLIGHT_PRESENT (1<<3)
> @@ -1041,8 +1005,6 @@ struct drm_i915_private {
>  
> 
>  	struct i915_power_domains power_domains;
>  
> 
> -	struct i915_psr psr;
> -
>  	struct i915_gpu_error gpu_error;
>  
> 
>  	struct drm_i915_gem_object *vlv_pctx;
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index a31980f69120..907a366e9c32 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -2088,10 +2088,22 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
>  		ivb_err_int_handler(dev_priv);
>  
> 
>  	if (de_iir & DE_EDP_PSR_INT_HSW) {
> -		u32 psr_iir = intel_uncore_read(&dev_priv->uncore, EDP_PSR_IIR);
> +		struct intel_encoder *encoder;
>  
> 
> -		intel_psr_irq_handler(dev_priv, psr_iir);
> -		intel_uncore_write(&dev_priv->uncore, EDP_PSR_IIR, psr_iir);
> +		for_each_intel_dp(&dev_priv->drm, encoder) {
> +			struct intel_dp *intel_dp = enc_to_intel_dp(encoder);

Another place that for_each_intel_encoder_is_psr_enabled() can be used.

> +
> +			if (encoder->type == INTEL_OUTPUT_EDP &&
> +			    CAN_PSR(intel_dp)) {

Again CAN_PSR() already takes care of == INTEL_OUTPUT_EDP.

> +				u32 psr_iir = intel_uncore_read(&dev_priv->uncore,
> +								EDP_PSR_IIR);
> +
> +				intel_psr_irq_handler(intel_dp, psr_iir);
> +				intel_uncore_write(&dev_priv->uncore,
> +						   EDP_PSR_IIR, psr_iir);
> +				break;
> +			}
> +		}
>  	}
>  
> 
>  	if (de_iir & DE_AUX_CHANNEL_A_IVB)
> @@ -2301,21 +2313,33 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir)
>  	}
>  
> 
>  	if (iir & GEN8_DE_EDP_PSR) {
> +		struct intel_encoder *encoder;
>  		u32 psr_iir;
>  		i915_reg_t iir_reg;
>  
> 
> -		if (INTEL_GEN(dev_priv) >= 12)
> -			iir_reg = TRANS_PSR_IIR(dev_priv->psr.transcoder);
> -		else
> -			iir_reg = EDP_PSR_IIR;
> +		for_each_intel_dp(&dev_priv->drm, encoder) {
> +			struct intel_dp *intel_dp = enc_to_intel_dp(encoder);

Another place that for_each_intel_encoder_is_psr_enabled() can be used.

We are almost there :D

> +
> +			if (!CAN_PSR(intel_dp))
> +				continue;
> +
> +			if (INTEL_GEN(dev_priv) >= 12)
> +				iir_reg = TRANS_PSR_IIR(intel_dp->psr.transcoder);
> +			else
> +				iir_reg = EDP_PSR_IIR;
>  
> 
> -		psr_iir = intel_uncore_read(&dev_priv->uncore, iir_reg);
> -		intel_uncore_write(&dev_priv->uncore, iir_reg, psr_iir);
> +			psr_iir = intel_uncore_read(&dev_priv->uncore, iir_reg);
> +			intel_uncore_write(&dev_priv->uncore, iir_reg, psr_iir);
>  
> 
> -		if (psr_iir)
> -			found = true;
> +			if (psr_iir)
> +				found = true;
>  
> 
> -		intel_psr_irq_handler(dev_priv, psr_iir);
> +			intel_psr_irq_handler(intel_dp, psr_iir);
> +
> +			/* prior GEN12 only have one EDP PSR */
> +			if (INTEL_GEN(dev_priv) < 12)
> +				break;
> +		}
>  	}
>  
> 
>  	if (!found)

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Intel-gfx] ✓ Fi.CI.IGT: success for series starting with [v13,1/2] drm/i915/display: Support PSR Multiple Instances
  2021-01-27 17:23 [Intel-gfx] [PATCH v13 1/2] drm/i915/display: Support PSR Multiple Instances Gwan-gyeong Mun
                   ` (4 preceding siblings ...)
  2021-01-27 20:43 ` [Intel-gfx] [PATCH v13 1/2] " Souza, Jose
@ 2021-01-27 23:39 ` Patchwork
  5 siblings, 0 replies; 8+ messages in thread
From: Patchwork @ 2021-01-27 23:39 UTC (permalink / raw)
  To: Gwan-gyeong Mun; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 20832 bytes --]

== Series Details ==

Series: series starting with [v13,1/2] drm/i915/display: Support PSR Multiple Instances
URL   : https://patchwork.freedesktop.org/series/86361/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_9688_full -> Patchwork_19523_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

Known issues
------------

  Here are the changes found in Patchwork_19523_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_fair@basic-deadline:
    - shard-glk:          [PASS][1] -> [FAIL][2] ([i915#2846])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-glk7/igt@gem_exec_fair@basic-deadline.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-glk2/igt@gem_exec_fair@basic-deadline.html

  * igt@gem_exec_fair@basic-flow@rcs0:
    - shard-tglb:         [PASS][3] -> [FAIL][4] ([i915#2842]) +2 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-tglb7/igt@gem_exec_fair@basic-flow@rcs0.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-tglb3/igt@gem_exec_fair@basic-flow@rcs0.html

  * igt@gem_exec_fair@basic-none@vcs1:
    - shard-iclb:         NOTRUN -> [FAIL][5] ([i915#2842])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-iclb2/igt@gem_exec_fair@basic-none@vcs1.html

  * igt@gem_exec_fair@basic-pace:
    - shard-hsw:          NOTRUN -> [SKIP][6] ([fdo#109271]) +27 similar issues
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-hsw1/igt@gem_exec_fair@basic-pace.html

  * igt@gem_exec_fair@basic-pace-solo@rcs0:
    - shard-kbl:          [PASS][7] -> [FAIL][8] ([i915#2842])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-kbl2/igt@gem_exec_fair@basic-pace-solo@rcs0.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-kbl3/igt@gem_exec_fair@basic-pace-solo@rcs0.html

  * igt@gem_exec_fair@basic-throttle@rcs0:
    - shard-glk:          [PASS][9] -> [FAIL][10] ([i915#2842])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-glk6/igt@gem_exec_fair@basic-throttle@rcs0.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-glk1/igt@gem_exec_fair@basic-throttle@rcs0.html

  * igt@gem_exec_params@no-vebox:
    - shard-iclb:         NOTRUN -> [SKIP][11] ([fdo#109283])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-iclb1/igt@gem_exec_params@no-vebox.html

  * igt@gem_exec_reloc@basic-wide-active@vcs1:
    - shard-iclb:         NOTRUN -> [FAIL][12] ([i915#2389]) +1 similar issue
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-iclb1/igt@gem_exec_reloc@basic-wide-active@vcs1.html

  * igt@gem_ppgtt@flink-and-close-vma-leak:
    - shard-glk:          [PASS][13] -> [FAIL][14] ([i915#644])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-glk1/igt@gem_ppgtt@flink-and-close-vma-leak.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-glk2/igt@gem_ppgtt@flink-and-close-vma-leak.html

  * igt@gen7_exec_parse@basic-allowed:
    - shard-skl:          NOTRUN -> [SKIP][15] ([fdo#109271]) +9 similar issues
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl8/igt@gen7_exec_parse@basic-allowed.html

  * igt@i915_pm_rpm@system-suspend-modeset:
    - shard-kbl:          [PASS][16] -> [INCOMPLETE][17] ([i915#151])
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-kbl7/igt@i915_pm_rpm@system-suspend-modeset.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-kbl4/igt@i915_pm_rpm@system-suspend-modeset.html

  * igt@kms_async_flips@alternate-sync-async-flip:
    - shard-skl:          [PASS][18] -> [FAIL][19] ([i915#2521])
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-skl6/igt@kms_async_flips@alternate-sync-async-flip.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl9/igt@kms_async_flips@alternate-sync-async-flip.html

  * igt@kms_chamelium@hdmi-cmp-planar-formats:
    - shard-glk:          NOTRUN -> [SKIP][20] ([fdo#109271] / [fdo#111827]) +1 similar issue
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-glk2/igt@kms_chamelium@hdmi-cmp-planar-formats.html

  * igt@kms_chamelium@hdmi-hpd-fast:
    - shard-hsw:          NOTRUN -> [SKIP][21] ([fdo#109271] / [fdo#111827]) +1 similar issue
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-hsw1/igt@kms_chamelium@hdmi-hpd-fast.html

  * igt@kms_color_chamelium@pipe-invalid-ctm-matrix-sizes:
    - shard-skl:          NOTRUN -> [SKIP][22] ([fdo#109271] / [fdo#111827]) +2 similar issues
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl8/igt@kms_color_chamelium@pipe-invalid-ctm-matrix-sizes.html

  * igt@kms_cursor_crc@pipe-b-cursor-suspend:
    - shard-skl:          [PASS][23] -> [FAIL][24] ([i915#54]) +5 similar issues
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-skl7/igt@kms_cursor_crc@pipe-b-cursor-suspend.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl8/igt@kms_cursor_crc@pipe-b-cursor-suspend.html

  * igt@kms_cursor_crc@pipe-d-cursor-128x128-sliding:
    - shard-hsw:          NOTRUN -> [SKIP][25] ([fdo#109271] / [i915#533]) +2 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-hsw1/igt@kms_cursor_crc@pipe-d-cursor-128x128-sliding.html

  * igt@kms_cursor_crc@pipe-d-cursor-128x42-random:
    - shard-glk:          NOTRUN -> [SKIP][26] ([fdo#109271]) +3 similar issues
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-glk2/igt@kms_cursor_crc@pipe-d-cursor-128x42-random.html

  * igt@kms_cursor_legacy@cursor-vs-flip-toggle:
    - shard-hsw:          [PASS][27] -> [FAIL][28] ([i915#2370])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-hsw4/igt@kms_cursor_legacy@cursor-vs-flip-toggle.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-hsw6/igt@kms_cursor_legacy@cursor-vs-flip-toggle.html

  * igt@kms_draw_crc@draw-method-xrgb2101010-blt-xtiled:
    - shard-skl:          [PASS][29] -> [FAIL][30] ([i915#52] / [i915#54])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-skl7/igt@kms_draw_crc@draw-method-xrgb2101010-blt-xtiled.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl8/igt@kms_draw_crc@draw-method-xrgb2101010-blt-xtiled.html

  * igt@kms_draw_crc@draw-method-xrgb2101010-pwrite-untiled:
    - shard-skl:          [PASS][31] -> [FAIL][32] ([i915#177] / [i915#52] / [i915#54])
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-skl4/igt@kms_draw_crc@draw-method-xrgb2101010-pwrite-untiled.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl3/igt@kms_draw_crc@draw-method-xrgb2101010-pwrite-untiled.html

  * igt@kms_flip@plain-flip-fb-recreate@a-edp1:
    - shard-skl:          [PASS][33] -> [FAIL][34] ([i915#2122])
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-skl2/igt@kms_flip@plain-flip-fb-recreate@a-edp1.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl10/igt@kms_flip@plain-flip-fb-recreate@a-edp1.html

  * igt@kms_flip@plain-flip-interruptible@a-edp1:
    - shard-skl:          [PASS][35] -> [DMESG-WARN][36] ([i915#1982])
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-skl10/igt@kms_flip@plain-flip-interruptible@a-edp1.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl7/igt@kms_flip@plain-flip-interruptible@a-edp1.html

  * igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-shrfb-msflip-blt:
    - shard-iclb:         NOTRUN -> [SKIP][37] ([fdo#109280]) +1 similar issue
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-iclb1/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-shrfb-msflip-blt.html

  * igt@kms_hdr@bpc-switch:
    - shard-skl:          NOTRUN -> [FAIL][38] ([i915#1188])
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl8/igt@kms_hdr@bpc-switch.html

  * igt@kms_plane_alpha_blend@pipe-a-alpha-7efc:
    - shard-skl:          NOTRUN -> [FAIL][39] ([fdo#108145] / [i915#265])
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl8/igt@kms_plane_alpha_blend@pipe-a-alpha-7efc.html

  * igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
    - shard-skl:          [PASS][40] -> [FAIL][41] ([fdo#108145] / [i915#265]) +1 similar issue
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-skl7/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl3/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html

  * igt@kms_psr@psr2_basic:
    - shard-iclb:         [PASS][42] -> [SKIP][43] ([fdo#109441]) +4 similar issues
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-iclb2/igt@kms_psr@psr2_basic.html
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-iclb3/igt@kms_psr@psr2_basic.html

  
#### Possible fixes ####

  * igt@gem_exec_fair@basic-none@rcs0:
    - shard-glk:          [FAIL][44] ([i915#2842]) -> [PASS][45]
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-glk9/igt@gem_exec_fair@basic-none@rcs0.html
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-glk5/igt@gem_exec_fair@basic-none@rcs0.html

  * igt@gem_exec_fair@basic-none@vcs0:
    - shard-kbl:          [FAIL][46] ([i915#2842]) -> [PASS][47] +4 similar issues
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-kbl7/igt@gem_exec_fair@basic-none@vcs0.html
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-kbl4/igt@gem_exec_fair@basic-none@vcs0.html

  * igt@gem_shrink@reclaim:
    - shard-iclb:         [INCOMPLETE][48] -> [PASS][49]
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-iclb4/igt@gem_shrink@reclaim.html
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-iclb1/igt@gem_shrink@reclaim.html

  * igt@gen9_exec_parse@allowed-all:
    - shard-glk:          [DMESG-WARN][50] ([i915#1436] / [i915#716]) -> [PASS][51]
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-glk7/igt@gen9_exec_parse@allowed-all.html
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-glk2/igt@gen9_exec_parse@allowed-all.html

  * igt@i915_selftest@live@hangcheck:
    - shard-hsw:          [INCOMPLETE][52] ([i915#2782]) -> [PASS][53]
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-hsw4/igt@i915_selftest@live@hangcheck.html
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-hsw1/igt@i915_selftest@live@hangcheck.html

  * igt@kms_cursor_crc@pipe-c-cursor-64x21-offscreen:
    - shard-skl:          [FAIL][54] ([i915#54]) -> [PASS][55] +10 similar issues
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-skl4/igt@kms_cursor_crc@pipe-c-cursor-64x21-offscreen.html
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl3/igt@kms_cursor_crc@pipe-c-cursor-64x21-offscreen.html

  * igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy:
    - shard-hsw:          [FAIL][56] ([i915#96]) -> [PASS][57]
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-hsw1/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-hsw2/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions:
    - shard-tglb:         [FAIL][58] ([i915#2346]) -> [PASS][59]
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-tglb6/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-tglb7/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html

  * igt@kms_draw_crc@draw-method-xrgb8888-mmap-wc-ytiled:
    - shard-skl:          [DMESG-WARN][60] ([i915#1982]) -> [PASS][61] +1 similar issue
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-skl4/igt@kms_draw_crc@draw-method-xrgb8888-mmap-wc-ytiled.html
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl3/igt@kms_draw_crc@draw-method-xrgb8888-mmap-wc-ytiled.html

  * igt@kms_flip@flip-vs-suspend@c-hdmi-a1:
    - shard-hsw:          [INCOMPLETE][62] ([i915#2055]) -> [PASS][63]
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-hsw4/igt@kms_flip@flip-vs-suspend@c-hdmi-a1.html
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-hsw1/igt@kms_flip@flip-vs-suspend@c-hdmi-a1.html

  * igt@kms_flip@plain-flip-fb-recreate-interruptible@c-edp1:
    - shard-skl:          [FAIL][64] ([i915#2122]) -> [PASS][65]
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-skl8/igt@kms_flip@plain-flip-fb-recreate-interruptible@c-edp1.html
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl8/igt@kms_flip@plain-flip-fb-recreate-interruptible@c-edp1.html

  * igt@kms_hdr@bpc-switch-dpms:
    - shard-skl:          [FAIL][66] ([i915#1188]) -> [PASS][67]
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-skl5/igt@kms_hdr@bpc-switch-dpms.html
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl4/igt@kms_hdr@bpc-switch-dpms.html

  * igt@kms_plane_alpha_blend@pipe-b-coverage-7efc:
    - shard-skl:          [FAIL][68] ([fdo#108145] / [i915#265]) -> [PASS][69]
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-skl8/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl9/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html

  * igt@kms_psr@psr2_sprite_plane_move:
    - shard-iclb:         [SKIP][70] ([fdo#109441]) -> [PASS][71] +3 similar issues
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-iclb3/igt@kms_psr@psr2_sprite_plane_move.html
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-iclb2/igt@kms_psr@psr2_sprite_plane_move.html

  * {igt@sysfs_clients@busy@bcs0}:
    - shard-skl:          [FAIL][72] -> [PASS][73]
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-skl6/igt@sysfs_clients@busy@bcs0.html
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-skl4/igt@sysfs_clients@busy@bcs0.html

  
#### Warnings ####

  * igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-1:
    - shard-iclb:         [SKIP][74] ([i915#658]) -> [SKIP][75] ([i915#2920]) +1 similar issue
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-iclb5/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-1.html
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-iclb2/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-1.html

  * igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-2:
    - shard-apl:          [SKIP][76] ([fdo#109271] / [i915#658]) -> [SKIP][77] ([fdo#109271]) +21 similar issues
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-apl6/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-2.html
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-apl8/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-2.html

  * igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-4:
    - shard-iclb:         [SKIP][78] ([i915#2920]) -> [SKIP][79] ([i915#658]) +2 similar issues
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-iclb2/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-4.html
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-iclb3/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-4.html

  * igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-3:
    - shard-kbl:          [SKIP][80] ([fdo#109271] / [i915#658]) -> [SKIP][81] ([fdo#109271]) +20 similar issues
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-kbl2/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-3.html
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-kbl1/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-3.html

  * igt@kms_psr2_su@frontbuffer:
    - shard-glk:          [SKIP][82] ([fdo#109271] / [i915#658]) -> [SKIP][83] ([fdo#109271]) +21 similar issues
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-glk1/igt@kms_psr2_su@frontbuffer.html
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-glk5/igt@kms_psr2_su@frontbuffer.html

  * igt@kms_psr@primary_page_flip:
    - shard-hsw:          [SKIP][84] ([fdo#109271] / [i915#1072]) -> [SKIP][85] ([fdo#109271]) +39 similar issues
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-hsw4/igt@kms_psr@primary_page_flip.html
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-hsw8/igt@kms_psr@primary_page_flip.html

  * igt@runner@aborted:
    - shard-kbl:          ([FAIL][86], [FAIL][87], [FAIL][88]) ([i915#2295] / [i915#2505]) -> ([FAIL][89], [FAIL][90], [FAIL][91]) ([i915#2295])
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-kbl6/igt@runner@aborted.html
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-kbl1/igt@runner@aborted.html
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9688/shard-kbl6/igt@runner@aborted.html
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-kbl3/igt@runner@aborted.html
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-kbl7/igt@runner@aborted.html
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/shard-kbl2/igt@runner@aborted.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109280]: https://bugs.freedesktop.org/show_bug.cgi?id=109280
  [fdo#109283]: https://bugs.freedesktop.org/show_bug.cgi?id=109283
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#1072]: https://gitlab.freedesktop.org/drm/intel/issues/1072
  [i915#1188]: https://gitlab.freedesktop.org/drm/intel/issues/1188
  [i915#1436]: https://gitlab.freedesktop.org/drm/intel/issues/1436
  [i915#151]: https://gitlab.freedesktop.org/drm/intel/issues/151
  [i915#177]: https://gitlab.freedesktop.org/drm/intel/issues/177
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#2055]: https://gitlab.freedesktop.org/drm/intel/issues/2055
  [i915#2122]: https://gitlab.freedesktop.org/drm/intel/issues/2122
  [i915#2295]: https://gitlab.freedesktop.org/drm/intel/issues/2295
  [i915#2346]: https://gitlab.freedesktop.org/drm/intel/issues/2346
  [i915#2370]: https://gitlab.freedesktop.org/drm/intel/issues/2370
  [i915#2389]: https://gitlab.freedesktop.org/drm/intel/issues/2389
  [i915#2505]: https://gitlab.freedesktop.org/drm/intel/issues/2505
  [i915#2521]: https://gitlab.freedesktop.org/drm/intel/issues/2521
  [i915#265]: https://gitlab.freedesktop.org/drm/intel/issues/265
  [i915#2782]: https://gitlab.freedesktop.org/drm/intel/issues/2782
  [i915#2842]: https://gitlab.freedesktop.org/drm/intel/issues/2842
  [i915#2846]: https://gitlab.freedesktop.org/drm/intel/issues/2846
  [i915#2920]: https://gitlab.freedesktop.org/drm/intel/issues/2920
  [i915#52]: https://gitlab.freedesktop.org/drm/intel/issues/52
  [i915#533]: https://gitlab.freedesktop.org/drm/intel/issues/533
  [i915#54]: https://gitlab.freedesktop.org/drm/intel/issues/54
  [i915#644]: https://gitlab.freedesktop.org/drm/intel/issues/644
  [i915#658]: https://gitlab.freedesktop.org/drm/intel/issues/658
  [i915#716]: https://gitlab.freedesktop.org/drm/intel/issues/716
  [i915#96]: https://gitlab.freedesktop.org/drm/intel/issues/96


Participating hosts (10 -> 10)
------------------------------

  No changes in participating hosts


Build changes
-------------

  * Linux: CI_DRM_9688 -> Patchwork_19523

  CI-20190529: 20190529
  CI_DRM_9688: 43295c2b7bc37446a480bb5d42b03675baed171a @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5974: a85398dcae50930c0e27548cf8c9575ad0bf69d1 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_19523: 250803287c3872757c80d156180f520708efdd5e @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19523/index.html

[-- Attachment #1.2: Type: text/html, Size: 25253 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Intel-gfx] [PATCH v13 1/2] drm/i915/display: Support PSR Multiple Instances
  2021-01-27 20:43 ` [Intel-gfx] [PATCH v13 1/2] " Souza, Jose
@ 2021-01-29  7:44   ` Mun, Gwan-gyeong
  0 siblings, 0 replies; 8+ messages in thread
From: Mun, Gwan-gyeong @ 2021-01-29  7:44 UTC (permalink / raw)
  To: intel-gfx, Souza, Jose; +Cc: Nikula, Jani

On Wed, 2021-01-27 at 12:43 -0800, Souza, Jose wrote:
> On Wed, 2021-01-27 at 19:23 +0200, Gwan-gyeong Mun wrote:
> > It is a preliminary work for supporting multiple EDP PSR and
> > DP PanelReplay. And it refactors singleton PSR to Multi Transcoder
> > supportable PSR.
> > And this moves and renames the i915_psr structure of
> > drm_i915_private's to
> > intel_dp's intel_psr structure.
> > It also causes changes in PSR interrupt handling routine for
> > supporting
> > multiple transcoders. But it does not change the scenario and
> > timing of
> > enabling and disabling PSR. And it not support multiple pipes with
> > a single transcoder PSR case yet.
> > 
> > v2: Fix indentation and add comments
> > v3: Remove Blank line
> > v4: Rebased
> > v5: Rebased and Addressed Anshuman's review comment.
> >     - Move calling of intel_psr_init() to intel_dp_init_connector()
> > v6: Address Anshuman's review comments
> >    - Remove wrong comments and add comments for a limit of
> > supporting of
> >      a single pipe PSR
> > v7: Update intel_psr_compute_config() for supporting multiple
> > transcoder
> >     PSR on BDW+
> > v8: Address Anshuman's review comments
> >    - Replace DRM_DEBUG_KMS with drm_dbg_kms() / DRM_WARN with
> > drm_warn()
> > v9: Fix commit message
> > v10: Rebased
> > v11: Address Jose's review comment.
> >   - Reorder calling order of
> > intel_psr2_program_trans_man_trk_ctl().
> >   - In order to reduce changes keep the old name for
> > drm_i915_private.
> >   - Change restrictions of multiple instances of PSR.
> > v12: Address Jose's review comment.
> >   - Change the calling of intel_psr2_program_trans_man_trk_ctl()
> > into
> >     commit_pipe_config().
> >   - Change a checking order of CAN_PSR() and connector_status to
> > original
> >     on i915_psr_sink_status_show().
> >   - Drop unneeded intel_dp_update_pipe() function.
> >   - In order to wait a specific encoder which belong to crtc_state
> > on
> >     intel_psr_wait_for_idle(), add checking of encoder.
> >   - Add an whitespace to comments.
> > v13: Rebased and Address Jose's review comment.
> >   - Add and use for_each_intel_psr_enabled_encoder() macro.
> >   - In order to use correct frontbuffer_bit for each pipe,
> >     fix intel_psr_invalidate() and intel_psr_flush().
> >   - Remove redundant or unneeded codes.
> >   - Update comments.
> > 
> > Signed-off-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
> > Cc: José Roberto de Souza <jose.souza@intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Anshuman Gupta <anshuman.gupta@intel.com>
> > Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c  |   2 -
> >  drivers/gpu/drm/i915/display/intel_display.h  |   8 +
> >  .../drm/i915/display/intel_display_debugfs.c  | 105 +++-
> >  .../drm/i915/display/intel_display_types.h    |  46 ++
> >  drivers/gpu/drm/i915/display/intel_dp.c       |  10 +-
> >  drivers/gpu/drm/i915/display/intel_psr.c      | 576 ++++++++++----
> > ----
> >  drivers/gpu/drm/i915/display/intel_psr.h      |  11 +-
> >  drivers/gpu/drm/i915/display/intel_sprite.c   |   6 +-
> >  drivers/gpu/drm/i915/i915_drv.h               |  38 --
> >  drivers/gpu/drm/i915/i915_irq.c               |  48 +-
> >  10 files changed, 485 insertions(+), 365 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index 667d941878a3..24df9dfb57fb 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -14135,8 +14135,6 @@ static void intel_setup_outputs(struct
> > drm_i915_private *dev_priv)
> >                 intel_dvo_init(dev_priv);
> >         }
> >  
> > 
> > -       intel_psr_init(dev_priv);
> > -
> >         for_each_intel_encoder(&dev_priv->drm, encoder) {
> >                 encoder->base.possible_crtcs =
> >                         intel_encoder_possible_crtcs(encoder);
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.h
> > b/drivers/gpu/drm/i915/display/intel_display.h
> > index 64ffa34544a7..fc41d0d9e5a5 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > @@ -417,6 +417,14 @@ enum phy_fia {
> >                 for_each_if((encoder_mask)
> > &                            \
> >                             drm_encoder_mask(&intel_encoder->base))
> >  
> > 
> > +#define for_each_intel_encoder_is_psr_enabled(dev, intel_encoder,
> > encoder_mask) \
> 
> I'm not a native speaker but "is" sounds wrong, maybe
> for_each_intel_encoder_with_psr_enabled()?
> 
> 
Okay, I'll update it.
But the previous version had a problem that did not handle mutex_lock
of psr.
In order to handle psr mutex_lock in the loop, I'll change it to
for_each_intel_encoder_mask_can_psr().
It'll use CAN_PSR() macro.
And I'll add new macro for_each_intel_encoder_can_psr() that traverses
all of DP encoder with CAN_PSR() too.
> > +       list_for_each_entry(intel_encoder,                         
> >      \
> > +                           &(dev)-
> > >mode_config.encoder_list,           \
> > +                          
> > base.head)                                  \
> > +               for_each_if(((encoder_mask)
> > &                           \
> > +                            drm_encoder_mask(&intel_encoder-
> > >base)) && \
> > +                          
> > intel_encoder_is_psr_enabled(intel_encoder))
> 
> Looks like style is wrong here but bot will tell you if it is.
> 
> > +
> >  #define for_each_intel_dp(dev, intel_encoder)                  \
> >         for_each_intel_encoder(dev, intel_encoder)              \
> >                 for_each_if(intel_encoder_is_dp(intel_encoder))
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > index d62b18d5ecd8..9868253df61f 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > @@ -249,12 +249,11 @@ static int i915_psr_sink_status_show(struct
> > seq_file *m, void *data)
> >                 "sink internal error",
> >         };
> >         struct drm_connector *connector = m->private;
> > -       struct drm_i915_private *dev_priv = to_i915(connector-
> > >dev);
> >         struct intel_dp *intel_dp =
> >                 intel_attached_dp(to_intel_connector(connector));
> >         int ret;
> >  
> > 
> > -       if (!CAN_PSR(dev_priv)) {
> > +       if (!CAN_PSR(intel_dp)) {
> >                 seq_puts(m, "PSR Unsupported\n");
> >                 return -ENODEV;
> >         }
> > @@ -280,12 +279,13 @@ static int i915_psr_sink_status_show(struct
> > seq_file *m, void *data)
> >  DEFINE_SHOW_ATTRIBUTE(i915_psr_sink_status);
> >  
> > 
> >  static void
> > -psr_source_status(struct drm_i915_private *dev_priv, struct
> > seq_file *m)
> > +psr_source_status(struct intel_dp *intel_dp, struct seq_file *m)
> >  {
> >         u32 val, status_val;
> >         const char *status = "unknown";
> > +       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> >  
> > 
> > -       if (dev_priv->psr.psr2_enabled) {
> > +       if (intel_dp->psr.psr2_enabled) {
> >                 static const char * const live_status[] = {
> >                         "IDLE",
> >                         "CAPTURE",
> > @@ -300,7 +300,7 @@ psr_source_status(struct drm_i915_private
> > *dev_priv, struct seq_file *m)
> >                         "TG_ON"
> >                 };
> >                 val = intel_de_read(dev_priv,
> > -                                   EDP_PSR2_STATUS(dev_priv-
> > >psr.transcoder));
> > +                                   EDP_PSR2_STATUS(intel_dp-
> > >psr.transcoder));
> >                 status_val = (val & EDP_PSR2_STATUS_STATE_MASK) >>
> >                               EDP_PSR2_STATUS_STATE_SHIFT;
> >                 if (status_val < ARRAY_SIZE(live_status))
> > @@ -317,7 +317,7 @@ psr_source_status(struct drm_i915_private
> > *dev_priv, struct seq_file *m)
> >                         "SRDENT_ON",
> >                 };
> >                 val = intel_de_read(dev_priv,
> > -                                   EDP_PSR_STATUS(dev_priv-
> > >psr.transcoder));
> > +                                   EDP_PSR_STATUS(intel_dp-
> > >psr.transcoder));
> >                 status_val = (val & EDP_PSR_STATUS_STATE_MASK) >>
> >                               EDP_PSR_STATUS_STATE_SHIFT;
> >                 if (status_val < ARRAY_SIZE(live_status))
> > @@ -327,21 +327,18 @@ psr_source_status(struct drm_i915_private
> > *dev_priv, struct seq_file *m)
> >         seq_printf(m, "Source PSR status: %s [0x%08x]\n", status,
> > val);
> >  }
> >  
> > 
> > -static int i915_edp_psr_status(struct seq_file *m, void *data)
> > +static int intel_psr_status(struct seq_file *m, struct intel_dp
> > *intel_dp)
> >  {
> > -       struct drm_i915_private *dev_priv = node_to_i915(m-
> > >private);
> > -       struct i915_psr *psr = &dev_priv->psr;
> > +       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > +       struct intel_psr *psr = &intel_dp->psr;
> >         intel_wakeref_t wakeref;
> >         const char *status;
> >         bool enabled;
> >         u32 val;
> >  
> > 
> > -       if (!HAS_PSR(dev_priv))
> > -               return -ENODEV;
> > -
> >         seq_printf(m, "Sink support: %s", yesno(psr-
> > >sink_support));
> > -       if (psr->dp)
> > -               seq_printf(m, " [0x%02x]", psr->dp->psr_dpcd[0]);
> > +       if (psr->sink_support)
> > +               seq_printf(m, " [0x%02x]", intel_dp->psr_dpcd[0]);
> >         seq_puts(m, "\n");
> >  
> > 
> >         if (!psr->sink_support)
> > @@ -365,16 +362,16 @@ static int i915_edp_psr_status(struct
> > seq_file *m, void *data)
> >  
> > 
> >         if (psr->psr2_enabled) {
> >                 val = intel_de_read(dev_priv,
> > -                                   EDP_PSR2_CTL(dev_priv-
> > >psr.transcoder));
> > +                                   EDP_PSR2_CTL(intel_dp-
> > >psr.transcoder));
> >                 enabled = val & EDP_PSR2_ENABLE;
> >         } else {
> >                 val = intel_de_read(dev_priv,
> > -                                   EDP_PSR_CTL(dev_priv-
> > >psr.transcoder));
> > +                                   EDP_PSR_CTL(intel_dp-
> > >psr.transcoder));
> >                 enabled = val & EDP_PSR_ENABLE;
> >         }
> >         seq_printf(m, "Source PSR ctl: %s [0x%08x]\n",
> >                    enableddisabled(enabled), val);
> > -       psr_source_status(dev_priv, m);
> > +       psr_source_status(intel_dp, m);
> >         seq_printf(m, "Busy frontbuffer bits: 0x%08x\n",
> >                    psr->busy_frontbuffer_bits);
> >  
> > 
> > @@ -383,7 +380,7 @@ static int i915_edp_psr_status(struct seq_file
> > *m, void *data)
> >          */
> >         if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
> >                 val = intel_de_read(dev_priv,
> > -                                   EDP_PSR_PERF_CNT(dev_priv-
> > >psr.transcoder));
> > +                                   EDP_PSR_PERF_CNT(intel_dp-
> > >psr.transcoder));
> >                 val &= EDP_PSR_PERF_CNT_MASK;
> >                 seq_printf(m, "Performance counter: %u\n", val);
> >         }
> > @@ -404,7 +401,7 @@ static int i915_edp_psr_status(struct seq_file
> > *m, void *data)
> >                  */
> >                 for (frame = 0; frame < PSR2_SU_STATUS_FRAMES;
> > frame += 3) {
> >                         val = intel_de_read(dev_priv,
> > -                                          
> > PSR2_SU_STATUS(dev_priv->psr.transcoder, frame));
> > +                                          
> > PSR2_SU_STATUS(intel_dp->psr.transcoder, frame));
> >                         su_frames_val[frame / 3] = val;
> >                 }
> >  
> > 
> > @@ -430,23 +427,57 @@ static int i915_edp_psr_status(struct
> > seq_file *m, void *data)
> >         return 0;
> >  }
> >  
> > 
> > +static int i915_edp_psr_status(struct seq_file *m, void *data)
> > +{
> > +       struct drm_i915_private *dev_priv = node_to_i915(m-
> > >private);
> > +       struct intel_encoder *encoder;
> > +       struct intel_dp *intel_dp = NULL;
> > +
> > +       if (!HAS_PSR(dev_priv))
> > +               return -ENODEV;
> > +
> > +       /* Find the first EDP */
> > +       for_each_intel_dp(&dev_priv->drm, encoder) {
> > +               if (encoder->type == INTEL_OUTPUT_EDP) {
> > +                       intel_dp = enc_to_intel_dp(encoder);
> > +                       break;
> > +               }
> > +       }
> > +
> > +       if (!intel_dp)
> > +               return -ENODEV;
> > +
> > +       return intel_psr_status(m, intel_dp);
> > +}
> > +
> >  static int
> >  i915_edp_psr_debug_set(void *data, u64 val)
> >  {
> >         struct drm_i915_private *dev_priv = data;
> >         intel_wakeref_t wakeref;
> > -       int ret;
> > +       int ret = -ENODEV;
> > +       struct intel_encoder *encoder;
> >  
> > 
> > -       if (!CAN_PSR(dev_priv))
> > -               return -ENODEV;
> > +       if (!HAS_PSR(dev_priv))
> > +               return ret;
> >  
> > 
> > -       drm_dbg_kms(&dev_priv->drm, "Setting PSR debug to %llx\n",
> > val);
> > +       for_each_intel_dp(&dev_priv->drm, encoder) {
> > +               struct intel_dp *intel_dp =
> > enc_to_intel_dp(encoder);
> >  
> > 
> > -       wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
> > +               if (!CAN_PSR(intel_dp))
> > +                       continue;
> >  
> > 
> > -       ret = intel_psr_debug_set(dev_priv, val);
> > +               if (encoder->type == INTEL_OUTPUT_EDP) {
> > +                       drm_dbg_kms(&dev_priv->drm, "Setting PSR
> > debug to %llx\n", val);
> >  
> > 
> > -       intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
> > +                       wakeref = intel_runtime_pm_get(&dev_priv-
> > >runtime_pm);
> > +
> > +                       // TODO: split to each transcoder's PSR
> > debug state
> > +                       ret = intel_psr_debug_set(intel_dp, val);
> > +
> > +                       intel_runtime_pm_put(&dev_priv->runtime_pm,
> > wakeref);
> > +               }
> > +       }
> >  
> > 
> >         return ret;
> >  }
> > @@ -455,12 +486,25 @@ static int
> >  i915_edp_psr_debug_get(void *data, u64 *val)
> >  {
> >         struct drm_i915_private *dev_priv = data;
> > +       struct intel_encoder *encoder;
> >  
> > 
> > -       if (!CAN_PSR(dev_priv))
> > +       if (!HAS_PSR(dev_priv))
> >                 return -ENODEV;
> >  
> > 
> > -       *val = READ_ONCE(dev_priv->psr.debug);
> > -       return 0;
> > +       for_each_intel_dp(&dev_priv->drm, encoder) {
> > +               struct intel_dp *intel_dp =
> > enc_to_intel_dp(encoder);
> > +
> > +               if (!CAN_PSR(intel_dp))
> > +                       continue;
> > +
> > +               // TODO: split to each transcoder's PSR debug state
> > +               if (encoder->type == INTEL_OUTPUT_EDP) {
> > +                       *val = READ_ONCE(intel_dp->psr.debug);
> > +                       return 0;
> > +               }
> > +       }
> > +
> > +       return -ENODEV;
> >  }
> >  
> > 
> >  DEFINE_SIMPLE_ATTRIBUTE(i915_edp_psr_debug_fops,
> > @@ -1233,9 +1277,6 @@ static void drrs_status_per_crtc(struct
> > seq_file *m,
> >                 /* disable_drrs() will make drrs->dp NULL */
> >                 if (!drrs->dp) {
> >                         seq_puts(m, "Idleness DRRS: Disabled\n");
> > -                       if (dev_priv->psr.enabled)
> > -                               seq_puts(m,
> > -                               "\tAs PSR is enabled, DRRS is not
> > enabled\n");
> >                         mutex_unlock(&drrs->mutex);
> >                         return;
> >                 }
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > index 39397748b4b0..63daf8b45941 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -1415,6 +1415,42 @@ struct intel_pps {
> >         struct edp_power_seq pps_delays;
> >  };
> >  
> > 
> > +struct intel_psr {
> > +       /* Mutex for PSR state of the transcoder */
> > +       struct mutex lock;
> > +
> > +#define I915_PSR_DEBUG_MODE_MASK       0x0f
> > +#define I915_PSR_DEBUG_DEFAULT         0x00
> > +#define I915_PSR_DEBUG_DISABLE         0x01
> > +#define I915_PSR_DEBUG_ENABLE          0x02
> > +#define I915_PSR_DEBUG_FORCE_PSR1      0x03
> > +#define I915_PSR_DEBUG_IRQ             0x10
> > +
> > +       u32 debug;
> > +       bool sink_support;
> > +       bool enabled;
> > +       enum pipe pipe;
> > +       enum transcoder transcoder;
> > +       bool active;
> > +       struct work_struct work;
> > +       unsigned int busy_frontbuffer_bits;
> > +       bool sink_psr2_support;
> > +       bool link_standby;
> > +       bool colorimetry_support;
> > +       bool psr2_enabled;
> > +       bool psr2_sel_fetch_enabled;
> > +       u8 sink_sync_latency;
> > +       ktime_t last_entry_attempt;
> > +       ktime_t last_exit;
> > +       bool sink_not_reliable;
> > +       bool irq_aux_error;
> > +       u16 su_x_granularity;
> > +       bool dc3co_enabled;
> > +       u32 dc3co_exit_delay;
> > +       struct delayed_work dc3co_work;
> > +       struct drm_dp_vsc_sdp vsc;
> > +};
> > +
> >  struct intel_dp {
> >         i915_reg_t output_reg;
> >         u32 DP;
> > @@ -1517,6 +1553,8 @@ struct intel_dp {
> >         bool hobl_active;
> >  
> > 
> >         struct intel_dp_pcon_frl frl;
> > +
> > +       struct intel_psr psr;
> >  };
> >  
> > 
> >  enum lspcon_vendor {
> > @@ -1729,6 +1767,14 @@ static inline bool
> > intel_encoder_is_dp(struct intel_encoder *encoder)
> >         }
> >  }
> >  
> > 
> > +static inline bool intel_encoder_is_psr_enabled(struct
> > intel_encoder *encoder)
> > +{
> > +       if (!intel_encoder_is_dp(encoder))
> > +               return false;
> > +
> > +       return enc_to_intel_dp(encoder)->psr.enabled;
> > +}
> > +
> >  static inline struct intel_lspcon *
> >  enc_to_intel_lspcon(struct intel_encoder *encoder)
> >  {
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> > b/drivers/gpu/drm/i915/display/intel_dp.c
> > index 8c12d5375607..d532bd56250f 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -1663,12 +1663,10 @@ void intel_dp_compute_psr_vsc_sdp(struct
> > intel_dp *intel_dp,
> >                                   const struct drm_connector_state
> > *conn_state,
> >                                   struct drm_dp_vsc_sdp *vsc)
> >  {
> > -       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > -
> >         vsc->sdp_type = DP_SDP_VSC;
> >  
> > 
> > -       if (dev_priv->psr.psr2_enabled) {
> > -               if (dev_priv->psr.colorimetry_support &&
> > +       if (intel_dp->psr.psr2_enabled) {
> > +               if (intel_dp->psr.colorimetry_support &&
> >                     intel_dp_needs_vsc_sdp(crtc_state, conn_state))
> > {
> >                         /* [PSR2, +Colorimetry] */
> >                         intel_dp_compute_vsc_colorimetry(crtc_state
> > , conn_state,
> > @@ -2359,7 +2357,7 @@ bool intel_dp_initial_fastset_check(struct
> > intel_encoder *encoder,
> >                 return false;
> >         }
> >  
> > 
> > -       if (CAN_PSR(i915) && intel_dp_is_edp(intel_dp)) {
> > +       if (CAN_PSR(intel_dp) && intel_dp_is_edp(intel_dp)) {
> >                 drm_dbg_kms(&i915->drm, "Forcing full modeset to
> > compute PSR state\n");
> >                 crtc_state->uapi.mode_changed = true;
> >                 return false;
> > @@ -6641,6 +6639,8 @@ intel_dp_init_connector(struct
> > intel_digital_port *dig_port,
> >         intel_dp->frl.is_trained = false;
> >         intel_dp->frl.trained_rate_gbps = 0;
> >  
> > 
> > +       intel_psr_init(intel_dp);
> > +
> >         return true;
> >  
> > 
> >  fail:
> > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> > b/drivers/gpu/drm/i915/display/intel_psr.c
> > index 2c365b778f74..925c0c6d92cd 100644
> > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > @@ -80,9 +80,11 @@
> >   * use page flips.
> >   */
> >  
> > 
> > -static bool psr_global_enabled(struct drm_i915_private *i915)
> > +static bool psr_global_enabled(struct intel_dp *intel_dp)
> >  {
> > -       switch (i915->psr.debug & I915_PSR_DEBUG_MODE_MASK) {
> > +       struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> > +
> > +       switch (intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK) {
> >         case I915_PSR_DEBUG_DEFAULT:
> >                 return i915->params.enable_psr;
> >         case I915_PSR_DEBUG_DISABLE:
> > @@ -92,9 +94,9 @@ static bool psr_global_enabled(struct
> > drm_i915_private *i915)
> >         }
> >  }
> >  
> > 
> > -static bool psr2_global_enabled(struct drm_i915_private *dev_priv)
> > +static bool psr2_global_enabled(struct intel_dp *intel_dp)
> >  {
> > -       switch (dev_priv->psr.debug & I915_PSR_DEBUG_MODE_MASK) {
> > +       switch (intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK) {
> >         case I915_PSR_DEBUG_DISABLE:
> >         case I915_PSR_DEBUG_FORCE_PSR1:
> >                 return false;
> > @@ -103,11 +105,12 @@ static bool psr2_global_enabled(struct
> > drm_i915_private *dev_priv)
> >         }
> >  }
> >  
> > 
> > -static void psr_irq_control(struct drm_i915_private *dev_priv)
> > +static void psr_irq_control(struct intel_dp *intel_dp)
> >  {
> >         enum transcoder trans_shift;
> >         u32 mask, val;
> >         i915_reg_t imr_reg;
> > +       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> >  
> > 
> >         /*
> >          * gen12+ has registers relative to transcoder and one per
> > transcoder
> > @@ -116,14 +119,14 @@ static void psr_irq_control(struct
> > drm_i915_private *dev_priv)
> >          */
> >         if (INTEL_GEN(dev_priv) >= 12) {
> >                 trans_shift = 0;
> > -               imr_reg = TRANS_PSR_IMR(dev_priv->psr.transcoder);
> > +               imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder);
> >         } else {
> > -               trans_shift = dev_priv->psr.transcoder;
> > +               trans_shift = intel_dp->psr.transcoder;
> >                 imr_reg = EDP_PSR_IMR;
> >         }
> >  
> > 
> >         mask = EDP_PSR_ERROR(trans_shift);
> > -       if (dev_priv->psr.debug & I915_PSR_DEBUG_IRQ)
> > +       if (intel_dp->psr.debug & I915_PSR_DEBUG_IRQ)
> >                 mask |= EDP_PSR_POST_EXIT(trans_shift) |
> >                         EDP_PSR_PRE_ENTRY(trans_shift);
> >  
> > 
> > @@ -172,30 +175,31 @@ static void psr_event_print(struct
> > drm_i915_private *i915,
> >                 drm_dbg_kms(&i915->drm, "\tPSR disabled\n");
> >  }
> >  
> > 
> > -void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32
> > psr_iir)
> > +void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
> >  {
> > -       enum transcoder cpu_transcoder = dev_priv->psr.transcoder;
> > +       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > +       enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
> >         enum transcoder trans_shift;
> >         i915_reg_t imr_reg;
> >         ktime_t time_ns =  ktime_get();
> >  
> > 
> >         if (INTEL_GEN(dev_priv) >= 12) {
> >                 trans_shift = 0;
> > -               imr_reg = TRANS_PSR_IMR(dev_priv->psr.transcoder);
> > +               imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder);
> >         } else {
> > -               trans_shift = dev_priv->psr.transcoder;
> > +               trans_shift = intel_dp->psr.transcoder;
> >                 imr_reg = EDP_PSR_IMR;
> >         }
> >  
> > 
> >         if (psr_iir & EDP_PSR_PRE_ENTRY(trans_shift)) {
> > -               dev_priv->psr.last_entry_attempt = time_ns;
> > +               intel_dp->psr.last_entry_attempt = time_ns;
> >                 drm_dbg_kms(&dev_priv->drm,
> >                             "[transcoder %s] PSR entry attempt in 2
> > vblanks\n",
> >                             transcoder_name(cpu_transcoder));
> >         }
> >  
> > 
> >         if (psr_iir & EDP_PSR_POST_EXIT(trans_shift)) {
> > -               dev_priv->psr.last_exit = time_ns;
> > +               intel_dp->psr.last_exit = time_ns;
> >                 drm_dbg_kms(&dev_priv->drm,
> >                             "[transcoder %s] PSR exit completed\n",
> >                             transcoder_name(cpu_transcoder));
> > @@ -203,7 +207,7 @@ void intel_psr_irq_handler(struct
> > drm_i915_private *dev_priv, u32 psr_iir)
> >                 if (INTEL_GEN(dev_priv) >= 9) {
> >                         u32 val = intel_de_read(dev_priv,
> >                                                 PSR_EVENT(cpu_trans
> > coder));
> > -                       bool psr2_enabled = dev_priv-
> > >psr.psr2_enabled;
> > +                       bool psr2_enabled = intel_dp-
> > >psr.psr2_enabled;
> >  
> > 
> >                         intel_de_write(dev_priv,
> > PSR_EVENT(cpu_transcoder),
> >                                        val);
> > @@ -217,7 +221,7 @@ void intel_psr_irq_handler(struct
> > drm_i915_private *dev_priv, u32 psr_iir)
> >                 drm_warn(&dev_priv->drm, "[transcoder %s] PSR aux
> > error\n",
> >                          transcoder_name(cpu_transcoder));
> >  
> > 
> > -               dev_priv->psr.irq_aux_error = true;
> > +               intel_dp->psr.irq_aux_error = true;
> >  
> > 
> >                 /*
> >                  * If this interruption is not masked it will keep
> > @@ -231,7 +235,7 @@ void intel_psr_irq_handler(struct
> > drm_i915_private *dev_priv, u32 psr_iir)
> >                 val |= EDP_PSR_ERROR(trans_shift);
> >                 intel_de_write(dev_priv, imr_reg, val);
> >  
> > 
> > -               schedule_work(&dev_priv->psr.work);
> > +               schedule_work(&intel_dp->psr.work);
> >         }
> >  }
> >  
> > 
> > @@ -292,12 +296,6 @@ void intel_psr_init_dpcd(struct intel_dp
> > *intel_dp)
> >         struct drm_i915_private *dev_priv =
> >                 to_i915(dp_to_dig_port(intel_dp)->base.base.dev);
> >  
> > 
> > -       if (dev_priv->psr.dp) {
> > -               drm_warn(&dev_priv->drm,
> > -                        "More than one eDP panel found, PSR
> > support should be extended\n");
> > -               return;
> > -       }
> > -
> >         drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT, intel_dp-
> > >psr_dpcd,
> >                          sizeof(intel_dp->psr_dpcd));
> >  
> > 
> > @@ -318,12 +316,10 @@ void intel_psr_init_dpcd(struct intel_dp
> > *intel_dp)
> >                 return;
> >         }
> >  
> > 
> > -       dev_priv->psr.sink_support = true;
> > -       dev_priv->psr.sink_sync_latency =
> > +       intel_dp->psr.sink_support = true;
> > +       intel_dp->psr.sink_sync_latency =
> >                 intel_dp_get_sink_sync_latency(intel_dp);
> >  
> > 
> > -       dev_priv->psr.dp = intel_dp;
> > -
> >         if (INTEL_GEN(dev_priv) >= 9 &&
> >             (intel_dp->psr_dpcd[0] ==
> > DP_PSR2_WITH_Y_COORD_IS_SUPPORTED)) {
> >                 bool y_req = intel_dp->psr_dpcd[1] &
> > @@ -341,14 +337,14 @@ void intel_psr_init_dpcd(struct intel_dp
> > *intel_dp)
> >                  * Y-coordinate requirement panels we would need to
> > enable
> >                  * GTC first.
> >                  */
> > -               dev_priv->psr.sink_psr2_support = y_req && alpm;
> > +               intel_dp->psr.sink_psr2_support = y_req && alpm;
> >                 drm_dbg_kms(&dev_priv->drm, "PSR2 %ssupported\n",
> > -                           dev_priv->psr.sink_psr2_support ? "" :
> > "not ");
> > +                           intel_dp->psr.sink_psr2_support ? "" :
> > "not ");
> >  
> > 
> > -               if (dev_priv->psr.sink_psr2_support) {
> > -                       dev_priv->psr.colorimetry_support =
> > +               if (intel_dp->psr.sink_psr2_support) {
> > +                       intel_dp->psr.colorimetry_support =
> >                                 intel_dp_get_colorimetry_status(int
> > el_dp);
> > -                       dev_priv->psr.su_x_granularity =
> > +                       intel_dp->psr.su_x_granularity =
> >                                 intel_dp_get_su_x_granulartiy(intel
> > _dp);
> >                 }
> >         }
> > @@ -374,7 +370,7 @@ static void hsw_psr_setup_aux(struct intel_dp
> > *intel_dp)
> >         BUILD_BUG_ON(sizeof(aux_msg) > 20);
> >         for (i = 0; i < sizeof(aux_msg); i += 4)
> >                 intel_de_write(dev_priv,
> > -                              EDP_PSR_AUX_DATA(dev_priv-
> > >psr.transcoder, i >> 2),
> > +                              EDP_PSR_AUX_DATA(intel_dp-
> > >psr.transcoder, i >> 2),
> >                                intel_dp_pack_aux(&aux_msg[i],
> > sizeof(aux_msg) - i));
> >  
> > 
> >         aux_clock_divider = intel_dp-
> > >get_aux_clock_divider(intel_dp, 0);
> > @@ -385,7 +381,7 @@ static void hsw_psr_setup_aux(struct intel_dp
> > *intel_dp)
> >  
> > 
> >         /* Select only valid bits for SRD_AUX_CTL */
> >         aux_ctl &= psr_aux_mask;
> > -       intel_de_write(dev_priv, EDP_PSR_AUX_CTL(dev_priv-
> > >psr.transcoder),
> > +       intel_de_write(dev_priv, EDP_PSR_AUX_CTL(intel_dp-
> > >psr.transcoder),
> >                        aux_ctl);
> >  }
> >  
> > 
> > @@ -395,14 +391,14 @@ static void intel_psr_enable_sink(struct
> > intel_dp *intel_dp)
> >         u8 dpcd_val = DP_PSR_ENABLE;
> >  
> > 
> >         /* Enable ALPM at sink for psr2 */
> > -       if (dev_priv->psr.psr2_enabled) {
> > +       if (intel_dp->psr.psr2_enabled) {
> >                 drm_dp_dpcd_writeb(&intel_dp->aux,
> > DP_RECEIVER_ALPM_CONFIG,
> >                                    DP_ALPM_ENABLE |
> >                                   
> > DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE);
> >  
> > 
> >                 dpcd_val |= DP_PSR_ENABLE_PSR2 |
> > DP_PSR_IRQ_HPD_WITH_CRC_ERRORS;
> >         } else {
> > -               if (dev_priv->psr.link_standby)
> > +               if (intel_dp->psr.link_standby)
> >                         dpcd_val |= DP_PSR_MAIN_LINK_ACTIVE;
> >  
> > 
> >                 if (INTEL_GEN(dev_priv) >= 8)
> > @@ -465,7 +461,7 @@ static u8 psr_compute_idle_frames(struct
> > intel_dp *intel_dp)
> >          * off-by-one issue that HW has in some cases.
> >          */
> >         idle_frames = max(6, dev_priv->vbt.psr.idle_frames);
> > -       idle_frames = max(idle_frames, dev_priv-
> > >psr.sink_sync_latency + 1);
> > +       idle_frames = max(idle_frames, intel_dp-
> > >psr.sink_sync_latency + 1);
> >  
> > 
> >         if (drm_WARN_ON(&dev_priv->drm, idle_frames > 0xf))
> >                 idle_frames = 0xf;
> > @@ -485,7 +481,7 @@ static void hsw_activate_psr1(struct intel_dp
> > *intel_dp)
> >         if (IS_HASWELL(dev_priv))
> >                 val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES;
> >  
> > 
> > -       if (dev_priv->psr.link_standby)
> > +       if (intel_dp->psr.link_standby)
> >                 val |= EDP_PSR_LINK_STANDBY;
> >  
> > 
> >         val |= intel_psr1_get_tp_time(intel_dp);
> > @@ -493,9 +489,9 @@ static void hsw_activate_psr1(struct intel_dp
> > *intel_dp)
> >         if (INTEL_GEN(dev_priv) >= 8)
> >                 val |= EDP_PSR_CRC_ENABLE;
> >  
> > 
> > -       val |= (intel_de_read(dev_priv, EDP_PSR_CTL(dev_priv-
> > >psr.transcoder)) &
> > +       val |= (intel_de_read(dev_priv, EDP_PSR_CTL(intel_dp-
> > >psr.transcoder)) &
> >                 EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK);
> > -       intel_de_write(dev_priv, EDP_PSR_CTL(dev_priv-
> > >psr.transcoder), val);
> > +       intel_de_write(dev_priv, EDP_PSR_CTL(intel_dp-
> > >psr.transcoder), val);
> >  }
> >  
> > 
> >  static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp)
> > @@ -530,7 +526,7 @@ static void hsw_activate_psr2(struct intel_dp
> > *intel_dp)
> >         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> >                 val |= EDP_Y_COORDINATE_ENABLE;
> >  
> > 
> > -       val |= EDP_PSR2_FRAME_BEFORE_SU(dev_priv-
> > >psr.sink_sync_latency + 1);
> > +       val |= EDP_PSR2_FRAME_BEFORE_SU(intel_dp-
> > >psr.sink_sync_latency + 1);
> >         val |= intel_psr2_get_tp_time(intel_dp);
> >  
> > 
> >         if (INTEL_GEN(dev_priv) >= 12) {
> > @@ -549,7 +545,7 @@ static void hsw_activate_psr2(struct intel_dp
> > *intel_dp)
> >                 val |= EDP_PSR2_FAST_WAKE(7);
> >         }
> >  
> > 
> > -       if (dev_priv->psr.psr2_sel_fetch_enabled) {
> > +       if (intel_dp->psr.psr2_sel_fetch_enabled) {
> >                 /* WA 1408330847 */
> >                 if (IS_TGL_DISP_STEPPING(dev_priv, STEP_A0,
> > STEP_A0) ||
> >                     IS_RKL_REVID(dev_priv, RKL_REVID_A0,
> > RKL_REVID_A0))
> > @@ -558,20 +554,20 @@ static void hsw_activate_psr2(struct intel_dp
> > *intel_dp)
> >                                     
> > DIS_RAM_BYPASS_PSR2_MAN_TRACK);
> >  
> > 
> >                 intel_de_write(dev_priv,
> > -                              PSR2_MAN_TRK_CTL(dev_priv-
> > >psr.transcoder),
> > +                              PSR2_MAN_TRK_CTL(intel_dp-
> > >psr.transcoder),
> >                                PSR2_MAN_TRK_CTL_ENABLE);
> >         } else if (HAS_PSR2_SEL_FETCH(dev_priv)) {
> >                 intel_de_write(dev_priv,
> > -                              PSR2_MAN_TRK_CTL(dev_priv-
> > >psr.transcoder), 0);
> > +                              PSR2_MAN_TRK_CTL(intel_dp-
> > >psr.transcoder), 0);
> >         }
> >  
> > 
> >         /*
> >          * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and
> > BSpec is
> >          * recommending keep this bit unset while PSR2 is enabled.
> >          */
> > -       intel_de_write(dev_priv, EDP_PSR_CTL(dev_priv-
> > >psr.transcoder), 0);
> > +       intel_de_write(dev_priv, EDP_PSR_CTL(intel_dp-
> > >psr.transcoder), 0);
> >  
> > 
> > -       intel_de_write(dev_priv, EDP_PSR2_CTL(dev_priv-
> > >psr.transcoder), val);
> > +       intel_de_write(dev_priv, EDP_PSR2_CTL(intel_dp-
> > >psr.transcoder), val);
> >  }
> >  
> > 
> >  static bool
> > @@ -594,55 +590,58 @@ static u32 intel_get_frame_time_us(const
> > struct intel_crtc_state *cstate)
> >                             drm_mode_vrefresh(&cstate-
> > >hw.adjusted_mode));
> >  }
> >  
> > 
> > -static void psr2_program_idle_frames(struct drm_i915_private
> > *dev_priv,
> > +static void psr2_program_idle_frames(struct intel_dp *intel_dp,
> >                                      u32 idle_frames)
> >  {
> > +       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> >         u32 val;
> >  
> > 
> >         idle_frames <<=  EDP_PSR2_IDLE_FRAME_SHIFT;
> > -       val = intel_de_read(dev_priv, EDP_PSR2_CTL(dev_priv-
> > >psr.transcoder));
> > +       val = intel_de_read(dev_priv, EDP_PSR2_CTL(intel_dp-
> > >psr.transcoder));
> >         val &= ~EDP_PSR2_IDLE_FRAME_MASK;
> >         val |= idle_frames;
> > -       intel_de_write(dev_priv, EDP_PSR2_CTL(dev_priv-
> > >psr.transcoder), val);
> > +       intel_de_write(dev_priv, EDP_PSR2_CTL(intel_dp-
> > >psr.transcoder), val);
> >  }
> >  
> > 
> > -static void tgl_psr2_enable_dc3co(struct drm_i915_private
> > *dev_priv)
> > +static void tgl_psr2_enable_dc3co(struct intel_dp *intel_dp)
> >  {
> > -       psr2_program_idle_frames(dev_priv, 0);
> > +       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > +
> > +       psr2_program_idle_frames(intel_dp, 0);
> >         intel_display_power_set_target_dc_state(dev_priv,
> > DC_STATE_EN_DC3CO);
> >  }
> >  
> > 
> > -static void tgl_psr2_disable_dc3co(struct drm_i915_private
> > *dev_priv)
> > +static void tgl_psr2_disable_dc3co(struct intel_dp *intel_dp)
> >  {
> > -       struct intel_dp *intel_dp = dev_priv->psr.dp;
> > +       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> >  
> > 
> >         intel_display_power_set_target_dc_state(dev_priv,
> > DC_STATE_EN_UPTO_DC6);
> > -       psr2_program_idle_frames(dev_priv,
> > psr_compute_idle_frames(intel_dp));
> > +       psr2_program_idle_frames(intel_dp,
> > psr_compute_idle_frames(intel_dp));
> >  }
> >  
> > 
> >  static void tgl_dc3co_disable_work(struct work_struct *work)
> >  {
> > -       struct drm_i915_private *dev_priv =
> > -               container_of(work, typeof(*dev_priv),
> > psr.dc3co_work.work);
> > +       struct intel_dp *intel_dp =
> > +               container_of(work, typeof(*intel_dp),
> > psr.dc3co_work.work);
> >  
> > 
> > -       mutex_lock(&dev_priv->psr.lock);
> > +       mutex_lock(&intel_dp->psr.lock);
> >         /* If delayed work is pending, it is not idle */
> > -       if (delayed_work_pending(&dev_priv->psr.dc3co_work))
> > +       if (delayed_work_pending(&intel_dp->psr.dc3co_work))
> >                 goto unlock;
> >  
> > 
> > -       tgl_psr2_disable_dc3co(dev_priv);
> > +       tgl_psr2_disable_dc3co(intel_dp);
> >  unlock:
> > -       mutex_unlock(&dev_priv->psr.lock);
> > +       mutex_unlock(&intel_dp->psr.lock);
> >  }
> >  
> > 
> > -static void tgl_disallow_dc3co_on_psr2_exit(struct
> > drm_i915_private *dev_priv)
> > +static void tgl_disallow_dc3co_on_psr2_exit(struct intel_dp
> > *intel_dp)
> >  {
> > -       if (!dev_priv->psr.dc3co_enabled)
> > +       if (!intel_dp->psr.dc3co_enabled)
> >                 return;
> >  
> > 
> > -       cancel_delayed_work(&dev_priv->psr.dc3co_work);
> > +       cancel_delayed_work(&intel_dp->psr.dc3co_work);
> >         /* Before PSR2 exit disallow dc3co*/
> > -       tgl_psr2_disable_dc3co(dev_priv);
> > +       tgl_psr2_disable_dc3co(intel_dp);
> >  }
> >  
> > 
> >  static void
> > @@ -715,7 +714,7 @@ static bool intel_psr2_config_valid(struct
> > intel_dp *intel_dp,
> >         int crtc_vdisplay = crtc_state-
> > >hw.adjusted_mode.crtc_vdisplay;
> >         int psr_max_h = 0, psr_max_v = 0, max_bpp = 0;
> >  
> > 
> > -       if (!dev_priv->psr.sink_psr2_support)
> > +       if (!intel_dp->psr.sink_psr2_support)
> >                 return false;
> >  
> > 
> >         if (!transcoder_has_psr2(dev_priv, crtc_state-
> > >cpu_transcoder)) {
> > @@ -725,7 +724,7 @@ static bool intel_psr2_config_valid(struct
> > intel_dp *intel_dp,
> >                 return false;
> >         }
> >  
> > 
> > -       if (!psr2_global_enabled(dev_priv)) {
> > +       if (!psr2_global_enabled(intel_dp)) {
> >                 drm_dbg_kms(&dev_priv->drm, "PSR2 disabled by
> > flag\n");
> >                 return false;
> >         }
> > @@ -774,10 +773,10 @@ static bool intel_psr2_config_valid(struct
> > intel_dp *intel_dp,
> >          * only need to validate the SU block width is a multiple
> > of
> >          * x granularity.
> >          */
> > -       if (crtc_hdisplay % dev_priv->psr.su_x_granularity) {
> > +       if (crtc_hdisplay % intel_dp->psr.su_x_granularity) {
> >                 drm_dbg_kms(&dev_priv->drm,
> >                             "PSR2 not enabled, hdisplay(%d) not
> > multiple of %d\n",
> > -                           crtc_hdisplay, dev_priv-
> > >psr.su_x_granularity);
> > +                           crtc_hdisplay, intel_dp-
> > >psr.su_x_granularity);
> >                 return false;
> >         }
> >  
> > 
> > @@ -819,13 +818,10 @@ void intel_psr_compute_config(struct intel_dp
> > *intel_dp,
> >         if (crtc_state->vrr.enable)
> >                 return;
> >  
> > 
> > -       if (!CAN_PSR(dev_priv))
> > +       if (!CAN_PSR(intel_dp))
> >                 return;
> >  
> > 
> > -       if (intel_dp != dev_priv->psr.dp)
> > -               return;
> > -
> > -       if (!psr_global_enabled(dev_priv)) {
> > +       if (!psr_global_enabled(intel_dp)) {
> >                 drm_dbg_kms(&dev_priv->drm, "PSR disabled by
> > flag\n");
> >                 return;
> >         }
> > @@ -833,16 +829,19 @@ void intel_psr_compute_config(struct intel_dp
> > *intel_dp,
> >         /*
> >          * HSW spec explicitly says PSR is tied to port A.
> >          * BDW+ platforms have a instance of PSR registers per
> > transcoder but
> > -        * for now it only supports one instance of PSR, so lets
> > keep it
> > -        * hardcoded to PORT_A
> > +        * BDW, GEN9 and GEN11 are not validated by HW team in
> > other transcoder
> > +        * than eDP one.
> > +        * For now it only supports one instance of PSR for BDW,
> > GEN9 and GEN11.
> > +        * So lets keep it hardcoded to PORT_A for BDW, GEN9 and
> > GEN11.
> > +        * But GEN12 supports a instance of PSR registers per
> > transcoder.
> >          */
> 
> Almost there but the instances are there intel_psr_init() will be
> executed but intel_psr_compute_config() will not let PSR to be
> enabled in a
> transcoder that is not eDP/port A for GEN11 and older.
> 

Ok, I'll move this check routine to intel_psr_init(). And after
checking it'll set source supports.
   And I'll make CAN_PSR() use it.

> > -       if (dig_port->base.port != PORT_A) {
> > +       if (INTEL_GEN(dev_priv) < 12 && dig_port->base.port !=
> > PORT_A) {
> >                 drm_dbg_kms(&dev_priv->drm,
> >                             "PSR condition failed: Port not
> > supported\n");
> >                 return;
> >         }
> >  
> > 
> > -       if (dev_priv->psr.sink_not_reliable) {
> > +       if (intel_dp->psr.sink_not_reliable) {
> >                 drm_dbg_kms(&dev_priv->drm,
> >                             "PSR sink implementation is not
> > reliable\n");
> >                 return;
> > @@ -878,23 +877,24 @@ void intel_psr_compute_config(struct intel_dp
> > *intel_dp,
> >  static void intel_psr_activate(struct intel_dp *intel_dp)
> >  {
> >         struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > +       enum transcoder transcoder = intel_dp->psr.transcoder;
> >  
> > 
> > -       if (transcoder_has_psr2(dev_priv, dev_priv-
> > >psr.transcoder))
> > +       if (transcoder_has_psr2(dev_priv, transcoder))
> >                 drm_WARN_ON(&dev_priv->drm,
> > -                           intel_de_read(dev_priv,
> > EDP_PSR2_CTL(dev_priv->psr.transcoder)) & EDP_PSR2_ENABLE);
> > +                           intel_de_read(dev_priv,
> > EDP_PSR2_CTL(transcoder)) & EDP_PSR2_ENABLE);
> >  
> > 
> >         drm_WARN_ON(&dev_priv->drm,
> > -                   intel_de_read(dev_priv, EDP_PSR_CTL(dev_priv-
> > >psr.transcoder)) & EDP_PSR_ENABLE);
> > -       drm_WARN_ON(&dev_priv->drm, dev_priv->psr.active);
> > -       lockdep_assert_held(&dev_priv->psr.lock);
> > +                   intel_de_read(dev_priv,
> > EDP_PSR_CTL(transcoder)) & EDP_PSR_ENABLE);
> > +       drm_WARN_ON(&dev_priv->drm, intel_dp->psr.active);
> > +       lockdep_assert_held(&intel_dp->psr.lock);
> >  
> > 
> >         /* psr1 and psr2 are mutually exclusive.*/
> > -       if (dev_priv->psr.psr2_enabled)
> > +       if (intel_dp->psr.psr2_enabled)
> >                 hsw_activate_psr2(intel_dp);
> >         else
> >                 hsw_activate_psr1(intel_dp);
> >  
> > 
> > -       dev_priv->psr.active = true;
> > +       intel_dp->psr.active = true;
> >  }
> >  
> > 
> >  static void intel_psr_enable_source(struct intel_dp *intel_dp,
> > @@ -910,7 +910,7 @@ static void intel_psr_enable_source(struct
> > intel_dp *intel_dp,
> >         if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
> >                 hsw_psr_setup_aux(intel_dp);
> >  
> > 
> > -       if (dev_priv->psr.psr2_enabled && (IS_GEN(dev_priv, 9) &&
> > +       if (intel_dp->psr.psr2_enabled && (IS_GEN(dev_priv, 9) &&
> >                                           
> > !IS_GEMINILAKE(dev_priv))) {
> >                 i915_reg_t reg = CHICKEN_TRANS(cpu_transcoder);
> >                 u32 chicken = intel_de_read(dev_priv, reg);
> > @@ -934,10 +934,10 @@ static void intel_psr_enable_source(struct
> > intel_dp *intel_dp,
> >         if (INTEL_GEN(dev_priv) < 11)
> >                 mask |= EDP_PSR_DEBUG_MASK_DISP_REG_WRITE;
> >  
> > 
> > -       intel_de_write(dev_priv, EDP_PSR_DEBUG(dev_priv-
> > >psr.transcoder),
> > +       intel_de_write(dev_priv, EDP_PSR_DEBUG(intel_dp-
> > >psr.transcoder),
> >                        mask);
> >  
> > 
> > -       psr_irq_control(dev_priv);
> > +       psr_irq_control(intel_dp);
> >  
> > 
> >         if (crtc_state->dc3co_exitline) {
> >                 u32 val;
> > @@ -955,30 +955,30 @@ static void intel_psr_enable_source(struct
> > intel_dp *intel_dp,
> >  
> > 
> >         if (HAS_PSR_HW_TRACKING(dev_priv) &&
> > HAS_PSR2_SEL_FETCH(dev_priv))
> >                 intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
> > IGNORE_PSR2_HW_TRACKING,
> > -                            dev_priv->psr.psr2_sel_fetch_enabled ?
> > +                            intel_dp->psr.psr2_sel_fetch_enabled ?
> >                              IGNORE_PSR2_HW_TRACKING : 0);
> >  }
> >  
> > 
> > -static void intel_psr_enable_locked(struct drm_i915_private
> > *dev_priv,
> > +static void intel_psr_enable_locked(struct intel_dp *intel_dp,
> >                                     const struct intel_crtc_state
> > *crtc_state,
> >                                     const struct
> > drm_connector_state *conn_state)
> >  {
> > -       struct intel_dp *intel_dp = dev_priv->psr.dp;
> > +       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> >         struct intel_digital_port *dig_port =
> > dp_to_dig_port(intel_dp);
> >         struct intel_encoder *encoder = &dig_port->base;
> >         u32 val;
> >  
> > 
> > -       drm_WARN_ON(&dev_priv->drm, dev_priv->psr.enabled);
> > +       drm_WARN_ON(&dev_priv->drm, intel_dp->psr.enabled);
> >  
> > 
> > -       dev_priv->psr.psr2_enabled = crtc_state->has_psr2;
> > -       dev_priv->psr.busy_frontbuffer_bits = 0;
> > -       dev_priv->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)-
> > >pipe;
> > -       dev_priv->psr.dc3co_enabled = !!crtc_state->dc3co_exitline;
> > -       dev_priv->psr.transcoder = crtc_state->cpu_transcoder;
> > +       intel_dp->psr.psr2_enabled = crtc_state->has_psr2;
> > +       intel_dp->psr.busy_frontbuffer_bits = 0;
> > +       intel_dp->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)-
> > >pipe;
> > +       intel_dp->psr.dc3co_enabled = !!crtc_state->dc3co_exitline;
> > +       intel_dp->psr.transcoder = crtc_state->cpu_transcoder;
> >         /* DC5/DC6 requires at least 6 idle frames */
> >         val = usecs_to_jiffies(intel_get_frame_time_us(crtc_state)
> > * 6);
> > -       dev_priv->psr.dc3co_exit_delay = val;
> > -       dev_priv->psr.psr2_sel_fetch_enabled = crtc_state-
> > >enable_psr2_sel_fetch;
> > +       intel_dp->psr.dc3co_exit_delay = val;
> > +       intel_dp->psr.psr2_sel_fetch_enabled = crtc_state-
> > >enable_psr2_sel_fetch;
> >  
> > 
> >         /*
> >          * If a PSR error happened and the driver is reloaded, the
> > EDP_PSR_IIR
> > @@ -990,27 +990,27 @@ static void intel_psr_enable_locked(struct
> > drm_i915_private *dev_priv,
> >          */
> >         if (INTEL_GEN(dev_priv) >= 12) {
> >                 val = intel_de_read(dev_priv,
> > -                                   TRANS_PSR_IIR(dev_priv-
> > >psr.transcoder));
> > +                                   TRANS_PSR_IIR(intel_dp-
> > >psr.transcoder));
> >                 val &= EDP_PSR_ERROR(0);
> >         } else {
> >                 val = intel_de_read(dev_priv, EDP_PSR_IIR);
> > -               val &= EDP_PSR_ERROR(dev_priv->psr.transcoder);
> > +               val &= EDP_PSR_ERROR(intel_dp->psr.transcoder);
> >         }
> >         if (val) {
> > -               dev_priv->psr.sink_not_reliable = true;
> > +               intel_dp->psr.sink_not_reliable = true;
> >                 drm_dbg_kms(&dev_priv->drm,
> >                             "PSR interruption error set, not
> > enabling PSR\n");
> >                 return;
> >         }
> >  
> > 
> >         drm_dbg_kms(&dev_priv->drm, "Enabling PSR%s\n",
> > -                   dev_priv->psr.psr2_enabled ? "2" : "1");
> > +                   intel_dp->psr.psr2_enabled ? "2" : "1");
> >         intel_dp_compute_psr_vsc_sdp(intel_dp, crtc_state,
> > conn_state,
> > -                                    &dev_priv->psr.vsc);
> > -       intel_write_dp_vsc_sdp(encoder, crtc_state, &dev_priv-
> > >psr.vsc);
> > +                                    &intel_dp->psr.vsc);
> > +       intel_write_dp_vsc_sdp(encoder, crtc_state, &intel_dp-
> > >psr.vsc);
> >         intel_psr_enable_sink(intel_dp);
> >         intel_psr_enable_source(intel_dp, crtc_state);
> > -       dev_priv->psr.enabled = true;
> > +       intel_dp->psr.enabled = true;
> >  
> > 
> >         intel_psr_activate(intel_dp);
> >  }
> > @@ -1029,7 +1029,7 @@ void intel_psr_enable(struct intel_dp
> > *intel_dp,
> >  {
> >         struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> >  
> > 
> > -       if (!CAN_PSR(dev_priv) || dev_priv->psr.dp != intel_dp)
> > +       if (!CAN_PSR(intel_dp))
> >                 return;
> >  
> > 
> >         if (!crtc_state->has_psr)
> > @@ -1037,46 +1037,47 @@ void intel_psr_enable(struct intel_dp
> > *intel_dp,
> >  
> > 
> >         drm_WARN_ON(&dev_priv->drm, dev_priv->drrs.dp);
> >  
> > 
> > -       mutex_lock(&dev_priv->psr.lock);
> > -       intel_psr_enable_locked(dev_priv, crtc_state, conn_state);
> > -       mutex_unlock(&dev_priv->psr.lock);
> > +       mutex_lock(&intel_dp->psr.lock);
> > +       intel_psr_enable_locked(intel_dp, crtc_state, conn_state);
> > +       mutex_unlock(&intel_dp->psr.lock);
> >  }
> >  
> > 
> > -static void intel_psr_exit(struct drm_i915_private *dev_priv)
> > +static void intel_psr_exit(struct intel_dp *intel_dp)
> >  {
> > +       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> >         u32 val;
> >  
> > 
> > -       if (!dev_priv->psr.active) {
> > -               if (transcoder_has_psr2(dev_priv, dev_priv-
> > >psr.transcoder)) {
> > +       if (!intel_dp->psr.active) {
> > +               if (transcoder_has_psr2(dev_priv, intel_dp-
> > >psr.transcoder)) {
> >                         val = intel_de_read(dev_priv,
> > -                                           EDP_PSR2_CTL(dev_priv-
> > >psr.transcoder));
> > +                                           EDP_PSR2_CTL(intel_dp-
> > >psr.transcoder));
> >                         drm_WARN_ON(&dev_priv->drm, val &
> > EDP_PSR2_ENABLE);
> >                 }
> >  
> > 
> >                 val = intel_de_read(dev_priv,
> > -                                   EDP_PSR_CTL(dev_priv-
> > >psr.transcoder));
> > +                                   EDP_PSR_CTL(intel_dp-
> > >psr.transcoder));
> >                 drm_WARN_ON(&dev_priv->drm, val & EDP_PSR_ENABLE);
> >  
> > 
> >                 return;
> >         }
> >  
> > 
> > -       if (dev_priv->psr.psr2_enabled) {
> > -               tgl_disallow_dc3co_on_psr2_exit(dev_priv);
> > +       if (intel_dp->psr.psr2_enabled) {
> > +               tgl_disallow_dc3co_on_psr2_exit(intel_dp);
> >                 val = intel_de_read(dev_priv,
> > -                                   EDP_PSR2_CTL(dev_priv-
> > >psr.transcoder));
> > +                                   EDP_PSR2_CTL(intel_dp-
> > >psr.transcoder));
> >                 drm_WARN_ON(&dev_priv->drm, !(val &
> > EDP_PSR2_ENABLE));
> >                 val &= ~EDP_PSR2_ENABLE;
> >                 intel_de_write(dev_priv,
> > -                              EDP_PSR2_CTL(dev_priv-
> > >psr.transcoder), val);
> > +                              EDP_PSR2_CTL(intel_dp-
> > >psr.transcoder), val);
> >         } else {
> >                 val = intel_de_read(dev_priv,
> > -                                   EDP_PSR_CTL(dev_priv-
> > >psr.transcoder));
> > +                                   EDP_PSR_CTL(intel_dp-
> > >psr.transcoder));
> >                 drm_WARN_ON(&dev_priv->drm, !(val &
> > EDP_PSR_ENABLE));
> >                 val &= ~EDP_PSR_ENABLE;
> >                 intel_de_write(dev_priv,
> > -                              EDP_PSR_CTL(dev_priv-
> > >psr.transcoder), val);
> > +                              EDP_PSR_CTL(intel_dp-
> > >psr.transcoder), val);
> >         }
> > -       dev_priv->psr.active = false;
> > +       intel_dp->psr.active = false;
> >  }
> >  
> > 
> >  static void intel_psr_disable_locked(struct intel_dp *intel_dp)
> > @@ -1085,21 +1086,21 @@ static void intel_psr_disable_locked(struct
> > intel_dp *intel_dp)
> >         i915_reg_t psr_status;
> >         u32 psr_status_mask;
> >  
> > 
> > -       lockdep_assert_held(&dev_priv->psr.lock);
> > +       lockdep_assert_held(&intel_dp->psr.lock);
> >  
> > 
> > -       if (!dev_priv->psr.enabled)
> > +       if (!intel_dp->psr.enabled)
> >                 return;
> >  
> > 
> >         drm_dbg_kms(&dev_priv->drm, "Disabling PSR%s\n",
> > -                   dev_priv->psr.psr2_enabled ? "2" : "1");
> > +                   intel_dp->psr.psr2_enabled ? "2" : "1");
> >  
> > 
> > -       intel_psr_exit(dev_priv);
> > +       intel_psr_exit(intel_dp);
> >  
> > 
> > -       if (dev_priv->psr.psr2_enabled) {
> > -               psr_status = EDP_PSR2_STATUS(dev_priv-
> > >psr.transcoder);
> > +       if (intel_dp->psr.psr2_enabled) {
> > +               psr_status = EDP_PSR2_STATUS(intel_dp-
> > >psr.transcoder);
> >                 psr_status_mask = EDP_PSR2_STATUS_STATE_MASK;
> >         } else {
> > -               psr_status = EDP_PSR_STATUS(dev_priv-
> > >psr.transcoder);
> > +               psr_status = EDP_PSR_STATUS(intel_dp-
> > >psr.transcoder);
> >                 psr_status_mask = EDP_PSR_STATUS_STATE_MASK;
> >         }
> >  
> > 
> > @@ -1109,7 +1110,7 @@ static void intel_psr_disable_locked(struct
> > intel_dp *intel_dp)
> >                 drm_err(&dev_priv->drm, "Timed out waiting PSR idle
> > state\n");
> >  
> > 
> >         /* WA 1408330847 */
> > -       if (dev_priv->psr.psr2_sel_fetch_enabled &&
> > +       if (intel_dp->psr.psr2_sel_fetch_enabled &&
> >             (IS_TGL_DISP_STEPPING(dev_priv, STEP_A0, STEP_A0) ||
> >              IS_RKL_REVID(dev_priv, RKL_REVID_A0, RKL_REVID_A0)))
> >                 intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
> > @@ -1118,10 +1119,10 @@ static void intel_psr_disable_locked(struct
> > intel_dp *intel_dp)
> >         /* Disable PSR on Sink */
> >         drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0);
> >  
> > 
> > -       if (dev_priv->psr.psr2_enabled)
> > +       if (intel_dp->psr.psr2_enabled)
> >                 drm_dp_dpcd_writeb(&intel_dp->aux,
> > DP_RECEIVER_ALPM_CONFIG, 0);
> >  
> > 
> > -       dev_priv->psr.enabled = false;
> > +       intel_dp->psr.enabled = false;
> >  }
> >  
> > 
> >  /**
> > @@ -1139,20 +1140,22 @@ void intel_psr_disable(struct intel_dp
> > *intel_dp,
> >         if (!old_crtc_state->has_psr)
> >                 return;
> >  
> > 
> > -       if (drm_WARN_ON(&dev_priv->drm, !CAN_PSR(dev_priv)))
> > +       if (drm_WARN_ON(&dev_priv->drm, !CAN_PSR(intel_dp)))
> >                 return;
> >  
> > 
> > -       mutex_lock(&dev_priv->psr.lock);
> > +       mutex_lock(&intel_dp->psr.lock);
> >  
> > 
> >         intel_psr_disable_locked(intel_dp);
> >  
> > 
> > -       mutex_unlock(&dev_priv->psr.lock);
> > -       cancel_work_sync(&dev_priv->psr.work);
> > -       cancel_delayed_work_sync(&dev_priv->psr.dc3co_work);
> > +       mutex_unlock(&intel_dp->psr.lock);
> > +       cancel_work_sync(&intel_dp->psr.work);
> > +       cancel_delayed_work_sync(&intel_dp->psr.dc3co_work);
> >  }
> >  
> > 
> > -static void psr_force_hw_tracking_exit(struct drm_i915_private
> > *dev_priv)
> > +static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp)
> >  {
> > +       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > +
> >         if (IS_TIGERLAKE(dev_priv))
> >                 /*
> >                  * Writes to CURSURFLIVE in TGL are causing IOMMU
> > errors and
> > @@ -1166,7 +1169,7 @@ static void psr_force_hw_tracking_exit(struct
> > drm_i915_private *dev_priv)
> >                  * So using this workaround until this issue is
> > root caused
> >                  * and a better fix is found.
> >                  */
> > -               intel_psr_exit(dev_priv);
> > +               intel_psr_exit(intel_dp);
> >         else if (INTEL_GEN(dev_priv) >= 9)
> >                 /*
> >                  * Display WA #0884: skl+
> > @@ -1177,13 +1180,13 @@ static void
> > psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv)
> >                  * but it makes more sense write to the current
> > active
> >                  * pipe.
> >                  */
> > -               intel_de_write(dev_priv, CURSURFLIVE(dev_priv-
> > >psr.pipe), 0);
> > +               intel_de_write(dev_priv, CURSURFLIVE(intel_dp-
> > >psr.pipe), 0);
> >         else
> >                 /*
> >                  * A write to CURSURFLIVE do not cause HW tracking
> > to exit PSR
> >                  * on older gens so doing the manual exit instead.
> >                  */
> > -               intel_psr_exit(dev_priv);
> > +               intel_psr_exit(intel_dp);
> >  }
> >  
> > 
> >  void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
> > @@ -1231,16 +1234,19 @@ void
> > intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
> >  
> > 
> >  void intel_psr2_program_trans_man_trk_ctl(const struct
> > intel_crtc_state *crtc_state)
> >  {
> > -       struct intel_crtc *crtc = to_intel_crtc(crtc_state-
> > >uapi.crtc);
> > -       struct drm_i915_private *dev_priv = to_i915(crtc-
> > >base.dev);
> > -       struct i915_psr *psr = &dev_priv->psr;
> > +       struct drm_i915_private *dev_priv = to_i915(crtc_state-
> > >uapi.crtc->dev);
> > +       struct intel_encoder *encoder;
> >  
> > 
> >         if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
> >             !crtc_state->enable_psr2_sel_fetch)
> >                 return;
> >  
> > 
> > -       intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(psr->transcoder),
> > -                      crtc_state->psr2_man_track_ctl);
> > +       for_each_intel_encoder_is_psr_enabled(&dev_priv->drm,
> > encoder,
> > +                                             crtc_state-
> > >uapi.encoder_mask) {
> > +               intel_de_write(dev_priv,
> > +                              PSR2_MAN_TRK_CTL(crtc_state-
> > >cpu_transcoder),
> > +                              crtc_state->psr2_man_track_ctl);
> > +       }
> >  }
> >  
> > 
> >  static void psr2_man_trk_ctl_calc(struct intel_crtc_state
> > *crtc_state,
> > @@ -1435,13 +1441,13 @@ void intel_psr_update(struct intel_dp
> > *intel_dp,
> >                       const struct drm_connector_state *conn_state)
> >  {
> >         struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > -       struct i915_psr *psr = &dev_priv->psr;
> > +       struct intel_psr *psr = &intel_dp->psr;
> >         bool enable, psr2_enable;
> >  
> > 
> > -       if (!CAN_PSR(dev_priv) || READ_ONCE(psr->dp) != intel_dp)
> > +       if (!CAN_PSR(intel_dp))
> >                 return;
> >  
> > 
> > -       mutex_lock(&dev_priv->psr.lock);
> > +       mutex_lock(&intel_dp->psr.lock);
> >  
> > 
> >         enable = crtc_state->has_psr;
> >         psr2_enable = crtc_state->has_psr2;
> > @@ -1449,15 +1455,15 @@ void intel_psr_update(struct intel_dp
> > *intel_dp,
> >         if (enable == psr->enabled && psr2_enable == psr-
> > >psr2_enabled) {
> >                 /* Force a PSR exit when enabling CRC to avoid CRC
> > timeouts */
> >                 if (crtc_state->crc_enabled && psr->enabled)
> > -                       psr_force_hw_tracking_exit(dev_priv);
> > +                       psr_force_hw_tracking_exit(intel_dp);
> >                 else if (INTEL_GEN(dev_priv) < 9 && psr->enabled) {
> >                         /*
> >                          * Activate PSR again after a force exit
> > when enabling
> >                          * CRC in older gens
> >                          */
> > -                       if (!dev_priv->psr.active &&
> > -                           !dev_priv->psr.busy_frontbuffer_bits)
> > -                               schedule_work(&dev_priv->psr.work);
> > +                       if (!intel_dp->psr.active &&
> > +                           !intel_dp->psr.busy_frontbuffer_bits)
> > +                               schedule_work(&intel_dp->psr.work);
> >                 }
> >  
> > 
> >                 goto unlock;
> > @@ -1467,34 +1473,23 @@ void intel_psr_update(struct intel_dp
> > *intel_dp,
> >                 intel_psr_disable_locked(intel_dp);
> >  
> > 
> >         if (enable)
> > -               intel_psr_enable_locked(dev_priv, crtc_state,
> > conn_state);
> > +               intel_psr_enable_locked(intel_dp, crtc_state,
> > conn_state);
> >  
> > 
> >  unlock:
> > -       mutex_unlock(&dev_priv->psr.lock);
> > +       mutex_unlock(&intel_dp->psr.lock);
> >  }
> >  
> > 
> >  /**
> > - * intel_psr_wait_for_idle - wait for PSR1 to idle
> > - * @new_crtc_state: new CRTC state
> > + * psr_wait_for_idle - wait for PSR1 to idle
> > + * @intel_dp: Intel DP
> >   * @out_value: PSR status in case of failure
> >   *
> > - * This function is expected to be called from pipe_update_start()
> > where it is
> > - * not expected to race with PSR enable or disable.
> > - *
> >   * Returns: 0 on success or -ETIMEOUT if PSR status does not idle.
> > + *
> >   */
> > -int intel_psr_wait_for_idle(const struct intel_crtc_state
> > *new_crtc_state,
> > -                           u32 *out_value)
> > +static int psr_wait_for_idle(struct intel_dp *intel_dp, u32
> > *out_value)
> >  {
> > -       struct intel_crtc *crtc = to_intel_crtc(new_crtc_state-
> > >uapi.crtc);
> > -       struct drm_i915_private *dev_priv = to_i915(crtc-
> > >base.dev);
> > -
> > -       if (!dev_priv->psr.enabled || !new_crtc_state->has_psr)
> > -               return 0;
> > -
> > -       /* FIXME: Update this for PSR2 if we need to wait for idle
> > */
> > -       if (READ_ONCE(dev_priv->psr.psr2_enabled))
> > -               return 0;
> > +       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> >  
> > 
> >         /*
> >          * From bspec: Panel Self Refresh (BDW+)
> > @@ -1502,32 +1497,63 @@ int intel_psr_wait_for_idle(const struct
> > intel_crtc_state *new_crtc_state,
> >          * 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(dev_priv-
> > >psr.transcoder),
> > +                                        EDP_PSR_STATUS(intel_dp-
> > >psr.transcoder),
> >                                          EDP_PSR_STATUS_STATE_MASK,
> >                                          EDP_PSR_STATUS_STATE_IDLE,
> > 2, 50,
> >                                          out_value);
> >  }
> >  
> > 
> > -static bool __psr_wait_for_idle_locked(struct drm_i915_private
> > *dev_priv)
> > +/**
> > + * intel_psr_wait_for_idle - wait for PSR1 to idle
> > + * @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)
> > +{
> > +       struct drm_i915_private *dev_priv = to_i915(new_crtc_state-
> > >uapi.crtc->dev);
> > +       struct intel_encoder *encoder;
> > +
> > +       if (!new_crtc_state->has_psr)
> > +               return;
> > +
> > +       for_each_intel_encoder_is_psr_enabled(&dev_priv->drm,
> > encoder,
> > +                                             new_crtc_state-
> > >uapi.encoder_mask) {
> > +               struct intel_dp *intel_dp =
> > enc_to_intel_dp(encoder);
> > +
> > +               /* when the PSR1 is enabled */
> > +               if (!intel_dp->psr.psr2_enabled) {
> > +                       u32 psr_status;
> 
> Better do:
> 
> if (intel_dp->psr.psr2_enabled)
>         continue;
> 
> if (psr_wait_for_idle(intel_dp, &psr_status))
>         ...
>         
> You get rid of one indentation and makes easier to read.
> 
> 
Thanks, I'll update it.
> > +
> > +                       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);
> > +               }
> > +       }
> > +}
> > +
> > +static bool __psr_wait_for_idle_locked(struct intel_dp *intel_dp)
> >  {
> >         i915_reg_t reg;
> >         u32 mask;
> >         int err;
> > +       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> >  
> > 
> > -       if (!dev_priv->psr.enabled)
> > +       if (!intel_dp->psr.enabled)
> >                 return false;
> >  
> > 
> > -       if (dev_priv->psr.psr2_enabled) {
> > -               reg = EDP_PSR2_STATUS(dev_priv->psr.transcoder);
> > +       if (intel_dp->psr.psr2_enabled) {
> > +               reg = EDP_PSR2_STATUS(intel_dp->psr.transcoder);
> >                 mask = EDP_PSR2_STATUS_STATE_MASK;
> >         } else {
> > -               reg = EDP_PSR_STATUS(dev_priv->psr.transcoder);
> > +               reg = EDP_PSR_STATUS(intel_dp->psr.transcoder);
> >                 mask = EDP_PSR_STATUS_STATE_MASK;
> >         }
> >  
> > 
> > -       mutex_unlock(&dev_priv->psr.lock);
> > +       mutex_unlock(&intel_dp->psr.lock);
> >  
> > 
> >         err = intel_de_wait_for_clear(dev_priv, reg, mask, 50);
> >         if (err)
> > @@ -1535,8 +1561,8 @@ static bool __psr_wait_for_idle_locked(struct
> > drm_i915_private *dev_priv)
> >                         "Timed out waiting for PSR Idle for re-
> > enable\n");
> >  
> > 
> >         /* After the unlocked wait, verify that PSR is still
> > wanted! */
> > -       mutex_lock(&dev_priv->psr.lock);
> > -       return err == 0 && dev_priv->psr.enabled;
> > +       mutex_lock(&intel_dp->psr.lock);
> > +       return err == 0 && intel_dp->psr.enabled;
> >  }
> >  
> > 
> >  static int intel_psr_fastset_force(struct drm_i915_private
> > *dev_priv)
> > @@ -1602,11 +1628,12 @@ static int intel_psr_fastset_force(struct
> > drm_i915_private *dev_priv)
> >         return err;
> >  }
> >  
> > 
> > -int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64
> > val)
> > +int intel_psr_debug_set(struct intel_dp *intel_dp, u64 val)
> >  {
> >         const u32 mode = val & I915_PSR_DEBUG_MODE_MASK;
> >         u32 old_mode;
> >         int ret;
> > +       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> 
> Nit pick but if you check in other places we try to leave the biggest
> declaration at the top kinda of following inverted pyramid style, you
> are doing
> this in other functions as well.
> 
Thanks for letting me know, I'll update it  where I modified the code
in this patch.
> >  
> > 
> >         if (val & ~(I915_PSR_DEBUG_IRQ | I915_PSR_DEBUG_MODE_MASK)
> > ||
> >             mode > I915_PSR_DEBUG_FORCE_PSR1) {
> > @@ -1614,21 +1641,21 @@ int intel_psr_debug_set(struct
> > drm_i915_private *dev_priv, u64 val)
> >                 return -EINVAL;
> >         }
> >  
> > 
> > -       ret = mutex_lock_interruptible(&dev_priv->psr.lock);
> > +       ret = mutex_lock_interruptible(&intel_dp->psr.lock);
> >         if (ret)
> >                 return ret;
> >  
> > 
> > -       old_mode = dev_priv->psr.debug & I915_PSR_DEBUG_MODE_MASK;
> > -       dev_priv->psr.debug = val;
> > +       old_mode = intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK;
> > +       intel_dp->psr.debug = val;
> >  
> > 
> >         /*
> >          * Do it right away if it's already enabled, otherwise it
> > will be done
> >          * when enabling the source.
> >          */
> > -       if (dev_priv->psr.enabled)
> > -               psr_irq_control(dev_priv);
> > +       if (intel_dp->psr.enabled)
> > +               psr_irq_control(intel_dp);
> >  
> > 
> > -       mutex_unlock(&dev_priv->psr.lock);
> > +       mutex_unlock(&intel_dp->psr.lock);
> >  
> > 
> >         if (old_mode != mode)
> >                 ret = intel_psr_fastset_force(dev_priv);
> > @@ -1636,28 +1663,28 @@ int intel_psr_debug_set(struct
> > drm_i915_private *dev_priv, u64 val)
> >         return ret;
> >  }
> >  
> > 
> > -static void intel_psr_handle_irq(struct drm_i915_private
> > *dev_priv)
> > +static void intel_psr_handle_irq(struct intel_dp *intel_dp)
> >  {
> > -       struct i915_psr *psr = &dev_priv->psr;
> > +       struct intel_psr *psr = &intel_dp->psr;
> >  
> > 
> > -       intel_psr_disable_locked(psr->dp);
> > +       intel_psr_disable_locked(intel_dp);
> >         psr->sink_not_reliable = true;
> >         /* let's make sure that sink is awaken */
> > -       drm_dp_dpcd_writeb(&psr->dp->aux, DP_SET_POWER,
> > DP_SET_POWER_D0);
> > +       drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER,
> > DP_SET_POWER_D0);
> >  }
> >  
> > 
> >  static void intel_psr_work(struct work_struct *work)
> >  {
> > -       struct drm_i915_private *dev_priv =
> > -               container_of(work, typeof(*dev_priv), psr.work);
> > +       struct intel_dp *intel_dp =
> > +               container_of(work, typeof(*intel_dp), psr.work);
> >  
> > 
> > -       mutex_lock(&dev_priv->psr.lock);
> > +       mutex_lock(&intel_dp->psr.lock);
> >  
> > 
> > -       if (!dev_priv->psr.enabled)
> > +       if (!intel_dp->psr.enabled)
> >                 goto unlock;
> >  
> > 
> > -       if (READ_ONCE(dev_priv->psr.irq_aux_error))
> > -               intel_psr_handle_irq(dev_priv);
> > +       if (READ_ONCE(intel_dp->psr.irq_aux_error))
> > +               intel_psr_handle_irq(intel_dp);
> >  
> > 
> >         /*
> >          * We have to make sure PSR is ready for re-enable
> > @@ -1665,7 +1692,7 @@ static void intel_psr_work(struct work_struct
> > *work)
> >          * PSR might take some time to get fully disabled
> >          * and be ready for re-enable.
> >          */
> > -       if (!__psr_wait_for_idle_locked(dev_priv))
> > +       if (!__psr_wait_for_idle_locked(intel_dp))
> >                 goto unlock;
> >  
> > 
> >         /*
> > @@ -1673,12 +1700,12 @@ static void intel_psr_work(struct
> > work_struct *work)
> >          * recheck. Since psr_flush first clears this and then
> > reschedules we
> >          * won't ever miss a flush when bailing out here.
> >          */
> > -       if (dev_priv->psr.busy_frontbuffer_bits || dev_priv-
> > >psr.active)
> > +       if (intel_dp->psr.busy_frontbuffer_bits || intel_dp-
> > >psr.active)
> >                 goto unlock;
> >  
> > 
> > -       intel_psr_activate(dev_priv->psr.dp);
> > +       intel_psr_activate(intel_dp);
> >  unlock:
> > -       mutex_unlock(&dev_priv->psr.lock);
> > +       mutex_unlock(&intel_dp->psr.lock);
> >  }
> >  
> > 
> >  /**
> > @@ -1697,27 +1724,35 @@ static void intel_psr_work(struct
> > work_struct *work)
> >  void intel_psr_invalidate(struct drm_i915_private *dev_priv,
> >                           unsigned frontbuffer_bits, enum
> > fb_op_origin origin)
> >  {
> > -       if (!CAN_PSR(dev_priv))
> > -               return;
> > +       struct intel_encoder *encoder;
> > +       struct intel_dp *intel_dp;
> >  
> > 
> > -       if (origin == ORIGIN_FLIP)
> > -               return;
> > +       for_each_intel_dp(&dev_priv->drm, encoder) {
> > +               unsigned pipe_frontbuffer_bits = frontbuffer_bits;
> 
> You could use for_each_intel_encoder_is_psr_enabled(), just setting
> all bits of encoder_mask.
> CPU time will be almost identical but we can save some lines of code
> and keep it consistent.
> 
The for_each_intel_encoder_mask_with_psr_enabled() macro checks only 
the enabled encoders (which is contained in crtc ).
For traversing all intel encoders which can use psr, I'll add new
for_each_intel_encoder_can_psr() macro.
( because in order to set enabled encoder mask, we need to add an
additional loop, I prefer to use new for_each_intel_encoder_can_psr()
here. 
cf. drm core code uses the full_encoder_mask() for setting full
encoder_mask. full_encoder_mask()function use loop for setting full
encoder mask.)

> >  
> > 
> > -       mutex_lock(&dev_priv->psr.lock);
> > -       if (!dev_priv->psr.enabled) {
> > -               mutex_unlock(&dev_priv->psr.lock);
> > -               return;
> > -       }
> > +               intel_dp = enc_to_intel_dp(encoder);
> > +               if (!CAN_PSR(intel_dp))
> > +                       continue;
> > +
> > +               if (origin == ORIGIN_FLIP)
> > +                       continue;
> 
> 
> If origin == ORIGIN_FLIP why waster time iterating over any intel_dp?
> 
 it's a wrong modification from the previous version. I'll fix it.
> > +
> > +               mutex_lock(&intel_dp->psr.lock);
> > +               if (!intel_dp->psr.enabled) {
> > +                       mutex_unlock(&intel_dp->psr.lock);
> > +                       continue;
> > +               }
> >  
> > 
> > -       frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(dev_priv-
> > >psr.pipe);
> > -       dev_priv->psr.busy_frontbuffer_bits |= frontbuffer_bits;
> > +               pipe_frontbuffer_bits &=
> > +                       INTEL_FRONTBUFFER_ALL_MASK(intel_dp-
> > >psr.pipe);
> > +               intel_dp->psr.busy_frontbuffer_bits |=
> > pipe_frontbuffer_bits;
> >  
> > 
> > -       if (frontbuffer_bits)
> > -               intel_psr_exit(dev_priv);
> > +               if (pipe_frontbuffer_bits)
> > +                       intel_psr_exit(intel_dp);
> >  
> > 
> > -       mutex_unlock(&dev_priv->psr.lock);
> > +               mutex_unlock(&intel_dp->psr.lock);
> > +       }
> >  }
> > -
> >  /*
> >   * When we will be completely rely on PSR2 S/W tracking in future,
> >   * intel_psr_flush() will invalidate and flush the PSR for
> > ORIGIN_FLIP
> > @@ -1725,15 +1760,15 @@ void intel_psr_invalidate(struct
> > drm_i915_private *dev_priv,
> >   * accordingly in future.
> >   */
> >  static void
> > -tgl_dc3co_flush(struct drm_i915_private *dev_priv,
> > -               unsigned int frontbuffer_bits, enum fb_op_origin
> > origin)
> > +tgl_dc3co_flush(struct intel_dp *intel_dp, unsigned int
> > frontbuffer_bits,
> > +               enum fb_op_origin origin)
> >  {
> > -       mutex_lock(&dev_priv->psr.lock);
> > +       mutex_lock(&intel_dp->psr.lock);
> >  
> > 
> > -       if (!dev_priv->psr.dc3co_enabled)
> > +       if (!intel_dp->psr.dc3co_enabled)
> >                 goto unlock;
> >  
> > 
> > -       if (!dev_priv->psr.psr2_enabled || !dev_priv->psr.active)
> > +       if (!intel_dp->psr.psr2_enabled || !intel_dp->psr.active)
> >                 goto unlock;
> >  
> > 
> >         /*
> > @@ -1741,15 +1776,15 @@ tgl_dc3co_flush(struct drm_i915_private
> > *dev_priv,
> >          * when delayed work schedules that means display has been
> > idle.
> >          */
> >         if (!(frontbuffer_bits &
> > -           INTEL_FRONTBUFFER_ALL_MASK(dev_priv->psr.pipe)))
> > +           INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe)))
> >                 goto unlock;
> >  
> > 
> > -       tgl_psr2_enable_dc3co(dev_priv);
> > -       mod_delayed_work(system_wq, &dev_priv->psr.dc3co_work,
> > -                        dev_priv->psr.dc3co_exit_delay);
> > +       tgl_psr2_enable_dc3co(intel_dp);
> > +       mod_delayed_work(system_wq, &intel_dp->psr.dc3co_work,
> > +                        intel_dp->psr.dc3co_exit_delay);
> >  
> > 
> >  unlock:
> > -       mutex_unlock(&dev_priv->psr.lock);
> > +       mutex_unlock(&intel_dp->psr.lock);
> >  }
> >  
> > 
> >  /**
> > @@ -1768,45 +1803,57 @@ tgl_dc3co_flush(struct drm_i915_private
> > *dev_priv,
> >  void intel_psr_flush(struct drm_i915_private *dev_priv,
> >                      unsigned frontbuffer_bits, enum fb_op_origin
> > origin)
> >  {
> > -       if (!CAN_PSR(dev_priv))
> > -               return;
> > +       struct intel_encoder *encoder;
> > +       struct intel_dp *intel_dp;
> >  
> > 
> > -       if (origin == ORIGIN_FLIP) {
> > -               tgl_dc3co_flush(dev_priv, frontbuffer_bits,
> > origin);
> > -               return;
> > -       }
> > +       for_each_intel_dp(&dev_priv->drm, encoder) {
> > +               intel_dp = enc_to_intel_dp(encoder);
> >  
> > 
> > -       mutex_lock(&dev_priv->psr.lock);
> > -       if (!dev_priv->psr.enabled) {
> > -               mutex_unlock(&dev_priv->psr.lock);
> > -               return;
> > -       }
> > +               if (CAN_PSR(intel_dp)) {
> 
> Again keep it consistent, in intel_psr_invalidate() you are doing
> if (CAN_PSR(intel_dp))
>         continue....
> I prefer do that and save one tab even better if you use
> for_each_intel_encoder_is_psr_enabled().
> 
will update.
> > +                       unsigned pipe_frontbuffer_bits =
> > frontbuffer_bits;
> >  
> > 
> > -       frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(dev_priv-
> > >psr.pipe);
> > -       dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits;
> > +                       if (origin == ORIGIN_FLIP) {
> > +                               tgl_dc3co_flush(intel_dp,
> > frontbuffer_bits, origin);
> > +                               continue;
> 
> Here makes sense check if origin == ORIGIN_FLIP in the loop but that
> is not the case in _invalidade()
> 
> > +                       }
> > +
> > +                       mutex_lock(&intel_dp->psr.lock);
> > +                       if (!intel_dp->psr.enabled) {
> > +                               mutex_unlock(&intel_dp->psr.lock);
> > +                               continue;
> > +                       }
> >  
> > 
> > -       /* By definition flush = invalidate + flush */
> > -       if (frontbuffer_bits)
> > -               psr_force_hw_tracking_exit(dev_priv);
> > +                       pipe_frontbuffer_bits &=
> > +                               INTEL_FRONTBUFFER_ALL_MASK(intel_dp
> > ->psr.pipe);
> > +                       intel_dp->psr.busy_frontbuffer_bits &=
> > ~pipe_frontbuffer_bits;
> >  
> > 
> > -       if (!dev_priv->psr.active && !dev_priv-
> > >psr.busy_frontbuffer_bits)
> > -               schedule_work(&dev_priv->psr.work);
> > -       mutex_unlock(&dev_priv->psr.lock);
> > +                       /* By definition flush = invalidate + flush
> > */
> > +                       if (pipe_frontbuffer_bits)
> > +                               psr_force_hw_tracking_exit(intel_dp
> > );
> > +
> > +                       if (!intel_dp->psr.active && !intel_dp-
> > >psr.busy_frontbuffer_bits)
> > +                               schedule_work(&intel_dp->psr.work);
> > +                       mutex_unlock(&intel_dp->psr.lock);
> > +               }
> > +       }
> >  }
> >  
> > 
> >  /**
> >   * intel_psr_init - Init basic PSR work and mutex.
> > - * @dev_priv: i915 device private
> > + * @intel_dp: Intel DP
> >   *
> > - * This function is  called only once at driver load to initialize
> > basic
> > - * PSR stuff.
> > + * This function is called after the initializing connector.
> > + * (the initializing of connector treats the handling of connector
> > capabilities)
> > + * And it initializes basic PSR stuff for each DP Encoder.
> >   */
> > -void intel_psr_init(struct drm_i915_private *dev_priv)
> > +void intel_psr_init(struct intel_dp *intel_dp)
> >  {
> > +       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > +
> >         if (!HAS_PSR(dev_priv))
> >                 return;
> >  
> > 
> > -       if (!dev_priv->psr.sink_support)
> > +       if (!intel_dp->psr.sink_support)
> >                 return;
> >  
> > 
> >         if (IS_HASWELL(dev_priv))
> > @@ -1824,14 +1871,14 @@ void intel_psr_init(struct drm_i915_private
> > *dev_priv)
> >         /* Set link_standby x link_off defaults */
> >         if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
> >                 /* HSW and BDW require workarounds that we don't
> > implement. */
> > -               dev_priv->psr.link_standby = false;
> > +               intel_dp->psr.link_standby = false;
> >         else if (INTEL_GEN(dev_priv) < 12)
> >                 /* For new platforms up to TGL let's respect VBT
> > back again */
> > -               dev_priv->psr.link_standby = dev_priv-
> > >vbt.psr.full_link;
> > +               intel_dp->psr.link_standby = dev_priv-
> > >vbt.psr.full_link;
> >  
> > 
> > -       INIT_WORK(&dev_priv->psr.work, intel_psr_work);
> > -       INIT_DELAYED_WORK(&dev_priv->psr.dc3co_work,
> > tgl_dc3co_disable_work);
> > -       mutex_init(&dev_priv->psr.lock);
> > +       INIT_WORK(&intel_dp->psr.work, intel_psr_work);
> > +       INIT_DELAYED_WORK(&intel_dp->psr.dc3co_work,
> > tgl_dc3co_disable_work);
> > +       mutex_init(&intel_dp->psr.lock);
> >  }
> >  
> > 
> >  static int psr_get_status_and_error_status(struct intel_dp
> > *intel_dp,
> > @@ -1857,7 +1904,7 @@ static void psr_alpm_check(struct intel_dp
> > *intel_dp)
> >  {
> >         struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> >         struct drm_dp_aux *aux = &intel_dp->aux;
> > -       struct i915_psr *psr = &dev_priv->psr;
> > +       struct intel_psr *psr = &intel_dp->psr;
> >         u8 val;
> >         int r;
> >  
> > 
> > @@ -1884,7 +1931,7 @@ static void psr_alpm_check(struct intel_dp
> > *intel_dp)
> >  static void psr_capability_changed_check(struct intel_dp
> > *intel_dp)
> >  {
> >         struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > -       struct i915_psr *psr = &dev_priv->psr;
> > +       struct intel_psr *psr = &intel_dp->psr;
> >         u8 val;
> >         int r;
> >  
> > 
> > @@ -1908,18 +1955,18 @@ static void
> > psr_capability_changed_check(struct intel_dp *intel_dp)
> >  void intel_psr_short_pulse(struct intel_dp *intel_dp)
> >  {
> >         struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > -       struct i915_psr *psr = &dev_priv->psr;
> > +       struct intel_psr *psr = &intel_dp->psr;
> >         u8 status, error_status;
> >         const u8 errors = DP_PSR_RFB_STORAGE_ERROR |
> >                           DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR |
> >                           DP_PSR_LINK_CRC_ERROR;
> >  
> > 
> > -       if (!CAN_PSR(dev_priv) || !intel_dp_is_edp(intel_dp))
> > +       if (!CAN_PSR(intel_dp) || !intel_dp_is_edp(intel_dp))
> >                 return;
> >  
> > 
> >         mutex_lock(&psr->lock);
> >  
> > 
> > -       if (!psr->enabled || psr->dp != intel_dp)
> > +       if (!psr->enabled)
> >                 goto exit;
> >  
> > 
> >         if (psr_get_status_and_error_status(intel_dp, &status,
> > &error_status)) {
> > @@ -1962,15 +2009,14 @@ void intel_psr_short_pulse(struct intel_dp
> > *intel_dp)
> >  
> > 
> >  bool intel_psr_enabled(struct intel_dp *intel_dp)
> >  {
> > -       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> >         bool ret;
> >  
> > 
> > -       if (!CAN_PSR(dev_priv) || !intel_dp_is_edp(intel_dp))
> > +       if (!CAN_PSR(intel_dp) || !intel_dp_is_edp(intel_dp))
> >                 return false;
> >  
> > 
> > -       mutex_lock(&dev_priv->psr.lock);
> > -       ret = (dev_priv->psr.dp == intel_dp && dev_priv-
> > >psr.enabled);
> > -       mutex_unlock(&dev_priv->psr.lock);
> > +       mutex_lock(&intel_dp->psr.lock);
> > +       ret = intel_dp->psr.enabled;
> > +       mutex_unlock(&intel_dp->psr.lock);
> >  
> > 
> >         return ret;
> >  }
> > diff --git a/drivers/gpu/drm/i915/display/intel_psr.h
> > b/drivers/gpu/drm/i915/display/intel_psr.h
> > index 0a517978e8af..2753976acc26 100644
> > --- a/drivers/gpu/drm/i915/display/intel_psr.h
> > +++ b/drivers/gpu/drm/i915/display/intel_psr.h
> > @@ -18,7 +18,7 @@ struct intel_atomic_state;
> >  struct intel_plane_state;
> >  struct intel_plane;
> >  
> > 
> > -#define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv-
> > >psr.sink_support)
> > +#define CAN_PSR(intel_dp) (HAS_PSR(dp_to_i915(intel_dp)) &&
> > intel_dp->psr.sink_support)
> >  void intel_psr_init_dpcd(struct intel_dp *intel_dp);
> >  void intel_psr_enable(struct intel_dp *intel_dp,
> >                       const struct intel_crtc_state *crtc_state,
> > @@ -28,20 +28,19 @@ void intel_psr_disable(struct intel_dp
> > *intel_dp,
> >  void intel_psr_update(struct intel_dp *intel_dp,
> >                       const struct intel_crtc_state *crtc_state,
> >                       const struct drm_connector_state
> > *conn_state);
> > -int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64
> > value);
> > +int intel_psr_debug_set(struct intel_dp *intel_dp, u64 value);
> >  void intel_psr_invalidate(struct drm_i915_private *dev_priv,
> >                           unsigned frontbuffer_bits,
> >                           enum fb_op_origin origin);
> >  void intel_psr_flush(struct drm_i915_private *dev_priv,
> >                      unsigned frontbuffer_bits,
> >                      enum fb_op_origin origin);
> > -void intel_psr_init(struct drm_i915_private *dev_priv);
> > +void intel_psr_init(struct intel_dp *intel_dp);
> >  void intel_psr_compute_config(struct intel_dp *intel_dp,
> >                               struct intel_crtc_state *crtc_state);
> > -void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32
> > psr_iir);
> > +void intel_psr_irq_handler(struct intel_dp *intel_dp, u32
> > psr_iir);
> >  void intel_psr_short_pulse(struct intel_dp *intel_dp);
> > -int intel_psr_wait_for_idle(const struct intel_crtc_state
> > *new_crtc_state,
> > -                           u32 *out_value);
> > +void intel_psr_wait_for_idle(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);
> > diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c
> > b/drivers/gpu/drm/i915/display/intel_sprite.c
> > index 52120f56dc54..986028deffd2 100644
> > --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> > @@ -96,7 +96,6 @@ void intel_pipe_update_start(const struct
> > intel_crtc_state *new_crtc_state)
> >         bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) ||
> > IS_CHERRYVIEW(dev_priv)) &&
> >                 intel_crtc_has_type(new_crtc_state,
> > INTEL_OUTPUT_DSI);
> >         DEFINE_WAIT(wait);
> > -       u32 psr_status;
> >  
> > 
> >         if (new_crtc_state->uapi.async_flip)
> >                 return;
> > @@ -122,10 +121,7 @@ void intel_pipe_update_start(const struct
> > intel_crtc_state *new_crtc_state)
> >          * VBL interrupts will start the PSR exit and prevent a PSR
> >          * re-entry as well.
> >          */
> > -       if (intel_psr_wait_for_idle(new_crtc_state, &psr_status))
> > -               drm_err(&dev_priv->drm,
> > -                       "PSR idle timed out 0x%x, atomic update may
> > fail\n",
> > -                       psr_status);
> > +       intel_psr_wait_for_idle(new_crtc_state);
> >  
> > 
> >         local_irq_disable();
> >  
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h
> > b/drivers/gpu/drm/i915/i915_drv.h
> > index 3edc9c4f2d21..3816b12aac0c 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -478,42 +478,6 @@ struct i915_drrs {
> >         enum drrs_support_type type;
> >  };
> >  
> > 
> > -struct i915_psr {
> > -       struct mutex lock;
> > -
> > -#define I915_PSR_DEBUG_MODE_MASK       0x0f
> > -#define I915_PSR_DEBUG_DEFAULT         0x00
> > -#define I915_PSR_DEBUG_DISABLE         0x01
> > -#define I915_PSR_DEBUG_ENABLE          0x02
> > -#define I915_PSR_DEBUG_FORCE_PSR1      0x03
> > -#define I915_PSR_DEBUG_IRQ             0x10
> > -
> > -       u32 debug;
> > -       bool sink_support;
> > -       bool enabled;
> > -       struct intel_dp *dp;
> > -       enum pipe pipe;
> > -       enum transcoder transcoder;
> > -       bool active;
> > -       struct work_struct work;
> > -       unsigned busy_frontbuffer_bits;
> > -       bool sink_psr2_support;
> > -       bool link_standby;
> > -       bool colorimetry_support;
> > -       bool psr2_enabled;
> > -       bool psr2_sel_fetch_enabled;
> > -       u8 sink_sync_latency;
> > -       ktime_t last_entry_attempt;
> > -       ktime_t last_exit;
> > -       bool sink_not_reliable;
> > -       bool irq_aux_error;
> > -       u16 su_x_granularity;
> > -       bool dc3co_enabled;
> > -       u32 dc3co_exit_delay;
> > -       struct delayed_work dc3co_work;
> > -       struct drm_dp_vsc_sdp vsc;
> > -};
> > -
> >  #define QUIRK_LVDS_SSC_DISABLE (1<<1)
> >  #define QUIRK_INVERT_BRIGHTNESS (1<<2)
> >  #define QUIRK_BACKLIGHT_PRESENT (1<<3)
> > @@ -1041,8 +1005,6 @@ struct drm_i915_private {
> >  
> > 
> >         struct i915_power_domains power_domains;
> >  
> > 
> > -       struct i915_psr psr;
> > -
> >         struct i915_gpu_error gpu_error;
> >  
> > 
> >         struct drm_i915_gem_object *vlv_pctx;
> > diff --git a/drivers/gpu/drm/i915/i915_irq.c
> > b/drivers/gpu/drm/i915/i915_irq.c
> > index a31980f69120..907a366e9c32 100644
> > --- a/drivers/gpu/drm/i915/i915_irq.c
> > +++ b/drivers/gpu/drm/i915/i915_irq.c
> > @@ -2088,10 +2088,22 @@ static void ivb_display_irq_handler(struct
> > drm_i915_private *dev_priv,
> >                 ivb_err_int_handler(dev_priv);
> >  
> > 
> >         if (de_iir & DE_EDP_PSR_INT_HSW) {
> > -               u32 psr_iir = intel_uncore_read(&dev_priv->uncore,
> > EDP_PSR_IIR);
> > +               struct intel_encoder *encoder;
> >  
> > 
> > -               intel_psr_irq_handler(dev_priv, psr_iir);
> > -               intel_uncore_write(&dev_priv->uncore, EDP_PSR_IIR,
> > psr_iir);
> > +               for_each_intel_dp(&dev_priv->drm, encoder) {
> > +                       struct intel_dp *intel_dp =
> > enc_to_intel_dp(encoder);
> 
> Another place that for_each_intel_encoder_is_psr_enabled() can be
> used.
> 
> > +
> > +                       if (encoder->type == INTEL_OUTPUT_EDP &&
> > +                           CAN_PSR(intel_dp)) {
> 
> Again CAN_PSR() already takes care of == INTEL_OUTPUT_EDP.
> 
> > +                               u32 psr_iir =
> > intel_uncore_read(&dev_priv->uncore,
> > +                                                               EDP
> > _PSR_IIR);
> > +
> > +                               intel_psr_irq_handler(intel_dp,
> > psr_iir);
> > +                               intel_uncore_write(&dev_priv-
> > >uncore,
> > +                                                  EDP_PSR_IIR,
> > psr_iir);
> > +                               break;
> > +                       }
> > +               }
> >         }
> >  
> > 
> >         if (de_iir & DE_AUX_CHANNEL_A_IVB)
> > @@ -2301,21 +2313,33 @@ gen8_de_misc_irq_handler(struct
> > drm_i915_private *dev_priv, u32 iir)
> >         }
> >  
> > 
> >         if (iir & GEN8_DE_EDP_PSR) {
> > +               struct intel_encoder *encoder;
> >                 u32 psr_iir;
> >                 i915_reg_t iir_reg;
> >  
> > 
> > -               if (INTEL_GEN(dev_priv) >= 12)
> > -                       iir_reg = TRANS_PSR_IIR(dev_priv-
> > >psr.transcoder);
> > -               else
> > -                       iir_reg = EDP_PSR_IIR;
> > +               for_each_intel_dp(&dev_priv->drm, encoder) {
> > +                       struct intel_dp *intel_dp =
> > enc_to_intel_dp(encoder);
> 
> Another place that for_each_intel_encoder_is_psr_enabled() can be
> used.
> 
> We are almost there :D
> 
> > +
> > +                       if (!CAN_PSR(intel_dp))
> > +                               continue;
> > +
> > +                       if (INTEL_GEN(dev_priv) >= 12)
> > +                               iir_reg = TRANS_PSR_IIR(intel_dp-
> > >psr.transcoder);
> > +                       else
> > +                               iir_reg = EDP_PSR_IIR;
> >  
> > 
> > -               psr_iir = intel_uncore_read(&dev_priv->uncore,
> > iir_reg);
> > -               intel_uncore_write(&dev_priv->uncore, iir_reg,
> > psr_iir);
> > +                       psr_iir = intel_uncore_read(&dev_priv-
> > >uncore, iir_reg);
> > +                       intel_uncore_write(&dev_priv->uncore,
> > iir_reg, psr_iir);
> >  
> > 
> > -               if (psr_iir)
> > -                       found = true;
> > +                       if (psr_iir)
> > +                               found = true;
> >  
> > 
> > -               intel_psr_irq_handler(dev_priv, psr_iir);
> > +                       intel_psr_irq_handler(intel_dp, psr_iir);
> > +
> > +                       /* prior GEN12 only have one EDP PSR */
> > +                       if (INTEL_GEN(dev_priv) < 12)
> > +                               break;
> > +               }
> >         }
> >  
> > 
> >         if (!found)
> 

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-01-29  7:44 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-27 17:23 [Intel-gfx] [PATCH v13 1/2] drm/i915/display: Support PSR Multiple Instances Gwan-gyeong Mun
2021-01-27 17:23 ` [Intel-gfx] [PATCH v13 2/2] drm/i915/display: Support Multiple Transcoders' PSR status on debugfs Gwan-gyeong Mun
2021-01-27 19:03 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v13,1/2] drm/i915/display: Support PSR Multiple Instances Patchwork
2021-01-27 19:04 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2021-01-27 19:33 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2021-01-27 20:43 ` [Intel-gfx] [PATCH v13 1/2] " Souza, Jose
2021-01-29  7:44   ` Mun, Gwan-gyeong
2021-01-27 23:39 ` [Intel-gfx] ✓ Fi.CI.IGT: success for series starting with [v13,1/2] " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.