[Intel-gfx] [PATCH 6/8] drm/i915: Plumb crtc_state to PSR enable/disable

ville.syrjala at linux.intel.com ville.syrjala at linux.intel.com
Fri May 19 13:17:23 UTC 2017


From: Ville Syrjälä <ville.syrjala at linux.intel.com>

The PSR enable/disable need to know things about the crtc state, so
plumb it through. This will become even more important when we start
to reuse the generic infoframe code for the VSC DIP programming as the
infoframe code wants the crtc state as well.

Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c |  4 +--
 drivers/gpu/drm/i915/intel_dp.c  |  4 +--
 drivers/gpu/drm/i915/intel_drv.h |  6 ++--
 drivers/gpu/drm/i915/intel_psr.c | 77 +++++++++++++++++++++-------------------
 4 files changed, 48 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 5dbbfedfbb06..6203c2da3daf 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1847,7 +1847,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder,
 			intel_dp_stop_link_train(intel_dp);
 
 		intel_edp_backlight_on(intel_dp);
-		intel_psr_enable(intel_dp);
+		intel_psr_enable(intel_dp, pipe_config);
 		intel_edp_drrs_enable(intel_dp, pipe_config);
 	}
 
@@ -1875,7 +1875,7 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder,
 		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
 		intel_edp_drrs_disable(intel_dp, old_crtc_state);
-		intel_psr_disable(intel_dp);
+		intel_psr_disable(intel_dp, old_crtc_state);
 		intel_edp_backlight_off(intel_dp);
 	}
 }
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 62084e350f58..1784989ca478 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2669,7 +2669,7 @@ static void intel_disable_dp(struct intel_encoder *encoder,
 		intel_audio_codec_disable(encoder);
 
 	if (HAS_PSR(dev_priv) && !HAS_DDI(dev_priv))
-		intel_psr_disable(intel_dp);
+		intel_psr_disable(intel_dp, old_crtc_state);
 
 	/* Make sure the panel is off before trying to change the mode. But also
 	 * ensure that we have vdd while we switch off the panel. */
@@ -2901,7 +2901,7 @@ static void vlv_enable_dp(struct intel_encoder *encoder,
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 
 	intel_edp_backlight_on(intel_dp);
-	intel_psr_enable(intel_dp);
+	intel_psr_enable(intel_dp, pipe_config);
 }
 
 static void g4x_pre_enable_dp(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index de2288f78961..a3d66ccafa5e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1740,8 +1740,10 @@ static inline void intel_backlight_device_unregister(struct intel_connector *con
 
 
 /* intel_psr.c */
-void intel_psr_enable(struct intel_dp *intel_dp);
-void intel_psr_disable(struct intel_dp *intel_dp);
+void intel_psr_enable(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state);
+void intel_psr_disable(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *old_crtc_state);
 void intel_psr_invalidate(struct drm_i915_private *dev_priv,
 			  unsigned frontbuffer_bits);
 void intel_psr_flush(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index c3780d0d2baf..f976aa865ef9 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -103,28 +103,26 @@ static void intel_psr_write_vsc(struct intel_dp *intel_dp,
 	POSTING_READ(ctl_reg);
 }
 
-static void vlv_psr_setup_vsc(struct intel_dp *intel_dp)
+static void vlv_psr_setup_vsc(struct intel_dp *intel_dp,
+			      const struct intel_crtc_state *crtc_state)
 {
-	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-	struct drm_device *dev = intel_dig_port->base.base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
-	enum pipe pipe = to_intel_crtc(crtc)->pipe;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	uint32_t val;
 
 	/* VLV auto-generate VSC package as per EDP 1.3 spec, Table 3.10 */
-	val  = I915_READ(VLV_VSCSDP(pipe));
+	val  = I915_READ(VLV_VSCSDP(crtc->pipe));
 	val &= ~VLV_EDP_PSR_SDP_FREQ_MASK;
 	val |= VLV_EDP_PSR_SDP_FREQ_EVFRAME;
-	I915_WRITE(VLV_VSCSDP(pipe), val);
+	I915_WRITE(VLV_VSCSDP(crtc->pipe), val);
 }
 
-static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp)
+static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp,
+				 const struct intel_crtc_state *crtc_state)
 {
-	struct edp_vsc_psr psr_vsc;
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-	struct drm_device *dev = intel_dig_port->base.base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
+	struct edp_vsc_psr psr_vsc;
 
 	/* Prepare VSC Header for SU as per EDP 1.4 spec, Table 6.11 */
 	memset(&psr_vsc, 0, sizeof(psr_vsc));
@@ -145,7 +143,8 @@ static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp)
 	intel_psr_write_vsc(intel_dp, &psr_vsc);
 }
 
-static void hsw_psr_setup_vsc(struct intel_dp *intel_dp)
+static void hsw_psr_setup_vsc(struct intel_dp *intel_dp,
+			      const struct intel_crtc_state *crtc_state)
 {
 	struct edp_vsc_psr psr_vsc;
 
@@ -233,16 +232,15 @@ static void hsw_psr_enable_sink(struct intel_dp *intel_dp)
 	I915_WRITE(aux_ctl_reg, aux_ctl);
 }
 
-static void vlv_psr_enable_source(struct intel_dp *intel_dp)
+static void vlv_psr_enable_source(struct intel_dp *intel_dp,
+				  const struct intel_crtc_state *crtc_state)
 {
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-	struct drm_device *dev = dig_port->base.base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct drm_crtc *crtc = dig_port->base.base.crtc;
-	enum pipe pipe = to_intel_crtc(crtc)->pipe;
+	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 
 	/* Transition from PSR_state 0 to PSR_state 1, i.e. PSR Inactive */
-	I915_WRITE(VLV_PSRCTL(pipe),
+	I915_WRITE(VLV_PSRCTL(crtc->pipe),
 		   VLV_EDP_PSR_MODE_SW_TIMER |
 		   VLV_EDP_PSR_SRC_TRANSMITTER_STATE |
 		   VLV_EDP_PSR_ENABLE);
@@ -486,13 +484,13 @@ static void intel_psr_activate(struct intel_dp *intel_dp)
  *
  * This function can only be called after the pipe is fully trained and enabled.
  */
-void intel_psr_enable(struct intel_dp *intel_dp)
+void intel_psr_enable(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = intel_dig_port->base.base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc);
-	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
+	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 	u32 chicken;
 
 	if (!HAS_PSR(dev_priv)) {
@@ -518,11 +516,13 @@ void intel_psr_enable(struct intel_dp *intel_dp)
 
 	if (HAS_DDI(dev_priv)) {
 		if (dev_priv->psr.psr2_support) {
-			skl_psr_setup_su_vsc(intel_dp);
+			skl_psr_setup_su_vsc(intel_dp, crtc_state);
+
 			chicken = PSR2_VSC_ENABLE_PROG_HEADER;
 			if (dev_priv->psr.y_cord_support)
 				chicken |= PSR2_ADD_VERTICAL_LINE_COUNT;
 			I915_WRITE(CHICKEN_TRANS(cpu_transcoder), chicken);
+
 			I915_WRITE(EDP_PSR_DEBUG_CTL,
 				   EDP_PSR_DEBUG_MASK_MEMUP |
 				   EDP_PSR_DEBUG_MASK_HPD |
@@ -531,7 +531,8 @@ void intel_psr_enable(struct intel_dp *intel_dp)
 				   EDP_PSR_DEBUG_MASK_DISP_REG_WRITE);
 		} else {
 			/* set up vsc header for psr1 */
-			hsw_psr_setup_vsc(intel_dp);
+			hsw_psr_setup_vsc(intel_dp, crtc_state);
+
 			/*
 			 * Per Spec: Avoid continuous PSR exit by masking MEMUP
 			 * and HPD. also mask LPSP to avoid dependency on other
@@ -551,7 +552,7 @@ void intel_psr_enable(struct intel_dp *intel_dp)
 		if (INTEL_GEN(dev_priv) >= 9)
 			intel_psr_activate(intel_dp);
 	} else {
-		vlv_psr_setup_vsc(intel_dp);
+		vlv_psr_setup_vsc(intel_dp, crtc_state);
 
 		/* Enable PSR on the panel */
 		vlv_psr_enable_sink(intel_dp);
@@ -562,7 +563,7 @@ void intel_psr_enable(struct intel_dp *intel_dp)
 		 * but let it on inactive state. So we might do this prior
 		 * to active transition, i.e. here.
 		 */
-		vlv_psr_enable_source(intel_dp);
+		vlv_psr_enable_source(intel_dp, crtc_state);
 	}
 
 	/*
@@ -583,37 +584,38 @@ void intel_psr_enable(struct intel_dp *intel_dp)
 	mutex_unlock(&dev_priv->psr.lock);
 }
 
-static void vlv_psr_disable(struct intel_dp *intel_dp)
+static void vlv_psr_disable(struct intel_dp *intel_dp,
+			    const struct intel_crtc_state *old_crtc_state)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = intel_dig_port->base.base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct intel_crtc *intel_crtc =
-		to_intel_crtc(intel_dig_port->base.base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
 	uint32_t val;
 
 	if (dev_priv->psr.active) {
 		/* Put VLV PSR back to PSR_state 0 that is PSR Disabled. */
 		if (intel_wait_for_register(dev_priv,
-					    VLV_PSRSTAT(intel_crtc->pipe),
+					    VLV_PSRSTAT(crtc->pipe),
 					    VLV_EDP_PSR_IN_TRANS,
 					    0,
 					    1))
 			WARN(1, "PSR transition took longer than expected\n");
 
-		val = I915_READ(VLV_PSRCTL(intel_crtc->pipe));
+		val = I915_READ(VLV_PSRCTL(crtc->pipe));
 		val &= ~VLV_EDP_PSR_ACTIVE_ENTRY;
 		val &= ~VLV_EDP_PSR_ENABLE;
 		val &= ~VLV_EDP_PSR_MODE_MASK;
-		I915_WRITE(VLV_PSRCTL(intel_crtc->pipe), val);
+		I915_WRITE(VLV_PSRCTL(crtc->pipe), val);
 
 		dev_priv->psr.active = false;
 	} else {
-		WARN_ON(vlv_is_psr_active_on_pipe(dev, intel_crtc->pipe));
+		WARN_ON(vlv_is_psr_active_on_pipe(dev, crtc->pipe));
 	}
 }
 
-static void hsw_psr_disable(struct intel_dp *intel_dp)
+static void hsw_psr_disable(struct intel_dp *intel_dp,
+			    const struct intel_crtc_state *old_crtc_state)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = intel_dig_port->base.base.dev;
@@ -665,7 +667,8 @@ static void hsw_psr_disable(struct intel_dp *intel_dp)
  *
  * This function needs to be called before disabling pipe.
  */
-void intel_psr_disable(struct intel_dp *intel_dp)
+void intel_psr_disable(struct intel_dp *intel_dp,
+		       const struct intel_crtc_state *old_crtc_state)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = intel_dig_port->base.base.dev;
@@ -679,9 +682,9 @@ void intel_psr_disable(struct intel_dp *intel_dp)
 
 	/* Disable PSR on Source */
 	if (HAS_DDI(dev_priv))
-		hsw_psr_disable(intel_dp);
+		hsw_psr_disable(intel_dp, old_crtc_state);
 	else
-		vlv_psr_disable(intel_dp);
+		vlv_psr_disable(intel_dp, old_crtc_state);
 
 	/* Disable PSR on Sink */
 	drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0);
-- 
2.10.2



More information about the Intel-gfx mailing list