[Intel-gfx] [PATCH] drm/i915: Pass pipe_config to DP link training functions

ville.syrjala at linux.intel.com ville.syrjala at linux.intel.com
Mon Aug 17 05:18:59 PDT 2015


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

With MST the primary encoder doesn't have a crtc, so trying to dig out
the pipe config via that is going to explode. Insted pass the pipe
config in so that the MST code can pass in what it wants.

It's still a huge mess since the MST code recomputes the main link
parameters for every stream. We should really aim to split the main link
setup so that we'd compute it only once.

Fixes a regression with MST caused by:
 commit 90a6b7b052b1aa17fbb98b049e9c8b7f729c35a7
 Author: Ville Syrjälä <ville.syrjala at linux.intel.com>
 Date:   Mon Jul 6 16:39:15 2015 +0300

    drm/i915: Move intel_dp->lane_count into pipe_config

Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Reported-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c    | 12 +++++------
 drivers/gpu/drm/i915/intel_dp.c     | 42 ++++++++++++++++++-------------------
 drivers/gpu/drm/i915/intel_dp_mst.c |  7 ++++---
 drivers/gpu/drm/i915/intel_drv.h    |  9 +++++---
 4 files changed, 36 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 56d778f..9b1a538 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -723,16 +723,16 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
 	DRM_ERROR("FDI link training failed!\n");
 }
 
-void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
+void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder,
+			       const struct intel_crtc_state *pipe_config)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 	struct intel_digital_port *intel_dig_port =
 		enc_to_dig_port(&encoder->base);
-	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
 
 	intel_dp->DP = intel_dig_port->saved_port_bits |
 		DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
-	intel_dp->DP |= DDI_PORT_WIDTH(crtc->config->lane_count);
+	intel_dp->DP |= DDI_PORT_WIDTH(pipe_config->lane_count);
 }
 
 static struct intel_encoder *
@@ -2314,11 +2314,11 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
 		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
-		intel_ddi_init_dp_buf_reg(intel_encoder);
+		intel_ddi_init_dp_buf_reg(intel_encoder, crtc->config);
 
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
-		intel_dp_start_link_train(intel_dp);
-		intel_dp_complete_link_train(intel_dp);
+		intel_dp_start_link_train(intel_dp, crtc->config);
+		intel_dp_complete_link_train(intel_dp, crtc->config);
 		if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
 			intel_dp_stop_link_train(intel_dp);
 	} else if (type == INTEL_OUTPUT_HDMI) {
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index b905c19..c5d85d8 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2576,8 +2576,8 @@ static void intel_enable_dp(struct intel_encoder *encoder)
 				    lane_mask);
 
 	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
-	intel_dp_start_link_train(intel_dp);
-	intel_dp_complete_link_train(intel_dp);
+	intel_dp_start_link_train(intel_dp, crtc->config);
+	intel_dp_complete_link_train(intel_dp, crtc->config);
 	intel_dp_stop_link_train(intel_dp);
 
 	if (crtc->config->has_audio) {
@@ -3620,11 +3620,10 @@ static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
 
 /* Enable corresponding port and start training pattern 1 */
 void
-intel_dp_start_link_train(struct intel_dp *intel_dp)
+intel_dp_start_link_train(struct intel_dp *intel_dp,
+			  const struct intel_crtc_state *pipe_config)
 {
 	struct drm_encoder *encoder = &dp_to_dig_port(intel_dp)->base.base;
-	struct intel_crtc *crtc =
-		to_intel_crtc(dp_to_dig_port(intel_dp)->base.base.crtc);
 	struct drm_device *dev = encoder->dev;
 	int i;
 	uint8_t voltage;
@@ -3636,12 +3635,12 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 	if (HAS_DDI(dev))
 		intel_ddi_prepare_link_retrain(encoder);
 
-	intel_dp_compute_rate(intel_dp, crtc->config->port_clock,
+	intel_dp_compute_rate(intel_dp, pipe_config->port_clock,
 			      &link_bw, &rate_select);
 
 	/* Write the link configuration data */
 	link_config[0] = link_bw;
-	link_config[1] = crtc->config->lane_count;
+	link_config[1] = pipe_config->lane_count;
 	if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
 		link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
 	drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config, 2);
@@ -3675,7 +3674,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 			break;
 		}
 
-		if (drm_dp_clock_recovery_ok(link_status, crtc->config->lane_count)) {
+		if (drm_dp_clock_recovery_ok(link_status, pipe_config->lane_count)) {
 			DRM_DEBUG_KMS("clock recovery OK\n");
 			break;
 		}
@@ -3698,10 +3697,10 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 		}
 
 		/* Check to see if we've tried the max voltage */
-		for (i = 0; i < crtc->config->lane_count; i++)
+		for (i = 0; i < pipe_config->lane_count; i++)
 			if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
 				break;
-		if (i == crtc->config->lane_count) {
+		if (i == pipe_config->lane_count) {
 			++loop_tries;
 			if (loop_tries == 5) {
 				DRM_ERROR("too many full retries, give up\n");
@@ -3736,17 +3735,16 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 }
 
 void
-intel_dp_complete_link_train(struct intel_dp *intel_dp)
+intel_dp_complete_link_train(struct intel_dp *intel_dp,
+			     const struct intel_crtc_state *pipe_config)
 {
-	struct intel_crtc *crtc =
-		to_intel_crtc(dp_to_dig_port(intel_dp)->base.base.crtc);
 	bool channel_eq = false;
 	int tries, cr_tries;
 	uint32_t DP = intel_dp->DP;
 	uint32_t training_pattern = DP_TRAINING_PATTERN_2;
 
 	/* Training Pattern 3 for HBR2 or 1.2 devices that support it*/
-	if (crtc->config->port_clock == 540000 || intel_dp->use_tps3)
+	if (pipe_config->port_clock == 540000 || intel_dp->use_tps3)
 		training_pattern = DP_TRAINING_PATTERN_3;
 
 	/* channel equalization */
@@ -3776,9 +3774,9 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
 
 		/* Make sure clock is still ok */
 		if (!drm_dp_clock_recovery_ok(link_status,
-					      crtc->config->lane_count)) {
+					      pipe_config->lane_count)) {
 			intel_dp->train_set_valid = false;
-			intel_dp_start_link_train(intel_dp);
+			intel_dp_start_link_train(intel_dp, pipe_config);
 			intel_dp_set_link_train(intel_dp, &DP,
 						training_pattern |
 						DP_LINK_SCRAMBLING_DISABLE);
@@ -3787,7 +3785,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
 		}
 
 		if (drm_dp_channel_eq_ok(link_status,
-					 crtc->config->lane_count)) {
+					 pipe_config->lane_count)) {
 			channel_eq = true;
 			break;
 		}
@@ -3795,7 +3793,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
 		/* Try 5 times, then try clock recovery if that fails */
 		if (tries > 5) {
 			intel_dp->train_set_valid = false;
-			intel_dp_start_link_train(intel_dp);
+			intel_dp_start_link_train(intel_dp, pipe_config);
 			intel_dp_set_link_train(intel_dp, &DP,
 						training_pattern |
 						DP_LINK_SCRAMBLING_DISABLE);
@@ -4302,8 +4300,8 @@ go_again:
 			if (intel_dp->active_mst_links &&
 			    !drm_dp_channel_eq_ok(&esi[10], crtc->config->lane_count)) {
 				DRM_DEBUG_KMS("channel EQ not ok, retraining\n");
-				intel_dp_start_link_train(intel_dp);
-				intel_dp_complete_link_train(intel_dp);
+				intel_dp_start_link_train(intel_dp, crtc->config);
+				intel_dp_complete_link_train(intel_dp, crtc->config);
 				intel_dp_stop_link_train(intel_dp);
 			}
 
@@ -4395,8 +4393,8 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
 	if (!drm_dp_channel_eq_ok(link_status, crtc->config->lane_count)) {
 		DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
 			      intel_encoder->base.name);
-		intel_dp_start_link_train(intel_dp);
-		intel_dp_complete_link_train(intel_dp);
+		intel_dp_start_link_train(intel_dp, crtc->config);
+		intel_dp_complete_link_train(intel_dp, crtc->config);
 		intel_dp_stop_link_train(intel_dp);
 	}
 }
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 9ec5c20..4c0304a 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -170,13 +170,14 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
 			I915_WRITE(PORT_CLK_SEL(port),
 				   intel_crtc->config->ddi_pll_sel);
 
-		intel_ddi_init_dp_buf_reg(&intel_dig_port->base);
+		intel_ddi_init_dp_buf_reg(&intel_dig_port->base,
+					  intel_crtc->config);
 
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
 
 
-		intel_dp_start_link_train(intel_dp);
-		intel_dp_complete_link_train(intel_dp);
+		intel_dp_start_link_train(intel_dp, intel_crtc->config);
+		intel_dp_complete_link_train(intel_dp, intel_crtc->config);
 		intel_dp_stop_link_train(intel_dp);
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 81b7d77..8e3ccd8 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -958,7 +958,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 struct intel_encoder *
 intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state);
 
-void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder);
+void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder,
+			       const struct intel_crtc_state *pipe_config);
 void intel_ddi_clock_get(struct intel_encoder *encoder,
 			 struct intel_crtc_state *pipe_config);
 void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
@@ -1161,8 +1162,10 @@ void assert_csr_loaded(struct drm_i915_private *dev_priv);
 void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
 bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 			     struct intel_connector *intel_connector);
-void intel_dp_start_link_train(struct intel_dp *intel_dp);
-void intel_dp_complete_link_train(struct intel_dp *intel_dp);
+void intel_dp_start_link_train(struct intel_dp *intel_dp,
+			       const struct intel_crtc_state *pipe_config);
+void intel_dp_complete_link_train(struct intel_dp *intel_dp,
+				  const struct intel_crtc_state *pipe_config);
 void intel_dp_stop_link_train(struct intel_dp *intel_dp);
 void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
 void intel_dp_encoder_destroy(struct drm_encoder *encoder);
-- 
2.4.6



More information about the Intel-gfx mailing list