[PATCH 02/23] drm/i915: Enable FEC later on during enable

Maarten Lankhorst maarten.lankhorst at linux.intel.com
Tue Sep 17 08:30:29 UTC 2019


It seems that we get a persistent FIFO underrun when we enable FEC
too early. I tried enabling it after intel_ddi_enable_transcoder_func(),
but was still hitting a FIFO underrun.

Move it to after intel_enable_pipe(), using the encoder->enable()
callback to set FEC.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Fixes: d9218c8f6cf4 ("drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC")
Cc: <stable at vger.kernel.org> # v5.0+
Cc: Manasi Navare <manasi.d.navare at intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c      | 57 ++-----------------
 .../drm/i915/display/intel_display_types.h    |  1 +
 drivers/gpu/drm/i915/display/intel_dp.c       | 52 +++++++++++++++++
 drivers/gpu/drm/i915/display/intel_dp.h       |  6 ++
 4 files changed, 65 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 1b59b852874b..ac6f97033325 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3157,53 +3157,6 @@ static void icl_program_mg_dp_mode(struct intel_digital_port *intel_dig_port)
 	I915_WRITE(MG_DP_MODE(1, port), ln1);
 }
 
-static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp,
-					const struct intel_crtc_state *crtc_state)
-{
-	if (!crtc_state->fec_enable)
-		return;
-
-	if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_FEC_CONFIGURATION, DP_FEC_READY) <= 0)
-		DRM_DEBUG_KMS("Failed to set FEC_READY in the sink\n");
-}
-
-static void intel_ddi_enable_fec(struct intel_encoder *encoder,
-				 const struct intel_crtc_state *crtc_state)
-{
-	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_dp *intel_dp;
-	u32 val;
-
-	if (!crtc_state->fec_enable)
-		return;
-
-	intel_dp = enc_to_intel_dp(&encoder->base);
-	val = I915_READ(intel_dp->regs.dp_tp_ctl);
-	val |= DP_TP_CTL_FEC_ENABLE;
-	I915_WRITE(intel_dp->regs.dp_tp_ctl, val);
-
-	if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
-				  DP_TP_STATUS_FEC_ENABLE_LIVE, 1))
-		DRM_ERROR("Timed out waiting for FEC Enable Status\n");
-}
-
-static void intel_ddi_disable_fec_state(struct intel_encoder *encoder,
-					const struct intel_crtc_state *crtc_state)
-{
-	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_dp *intel_dp;
-	u32 val;
-
-	if (!crtc_state->fec_enable)
-		return;
-
-	intel_dp = enc_to_intel_dp(&encoder->base);
-	val = I915_READ(intel_dp->regs.dp_tp_ctl);
-	val &= ~DP_TP_CTL_FEC_ENABLE;
-	I915_WRITE(intel_dp->regs.dp_tp_ctl, val);
-	POSTING_READ(intel_dp->regs.dp_tp_ctl);
-}
-
 static void tgl_ddi_pre_enable_dp(struct intel_encoder *encoder,
 				  const struct intel_crtc_state *crtc_state,
 				  const struct drm_connector_state *conn_state)
@@ -3289,7 +3242,6 @@ static void tgl_ddi_pre_enable_dp(struct intel_encoder *encoder,
 	intel_dp_stop_link_train(intel_dp);
 
 	/* 7.l */
-	intel_ddi_enable_fec(encoder, crtc_state);
 	intel_dsc_enable(encoder, crtc_state);
 }
 
@@ -3354,8 +3306,6 @@ static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
 	if (port != PORT_A || INTEL_GEN(dev_priv) >= 9)
 		intel_dp_stop_link_train(intel_dp);
 
-	intel_ddi_enable_fec(encoder, crtc_state);
-
 	icl_enable_phy_clock_gating(dig_port);
 
 	if (!is_mst)
@@ -3488,7 +3438,7 @@ static void intel_disable_ddi_buf(struct intel_encoder *encoder,
 	}
 
 	/* Disable FEC in DP Sink */
-	intel_ddi_disable_fec_state(encoder, crtc_state);
+	intel_dp_disable_fec_state(encoder, crtc_state);
 
 	if (wait)
 		intel_wait_ddi_buf_idle(dev_priv, port);
@@ -3625,6 +3575,7 @@ static void intel_enable_ddi_dp(struct intel_encoder *encoder,
 	if (port == PORT_A && INTEL_GEN(dev_priv) < 9)
 		intel_dp_stop_link_train(intel_dp);
 
+	intel_dp_enable_fec_state(encoder, crtc_state);
 	intel_edp_backlight_on(crtc_state, conn_state);
 	intel_psr_enable(intel_dp, crtc_state);
 	intel_dp_ycbcr_420_enable(intel_dp, crtc_state);
@@ -3940,6 +3891,10 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
 		if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
 			val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
 	}
+
+	if (intel_dp->link_fec)
+		val |= DP_TP_CTL_FEC_ENABLE;
+
 	I915_WRITE(intel_dp->regs.dp_tp_ctl, val);
 	POSTING_READ(intel_dp->regs.dp_tp_ctl);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index d5cc4b810d9e..a5096e91cb58 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1158,6 +1158,7 @@ struct intel_dp {
 	u8 sink_count;
 	bool link_mst;
 	bool link_trained;
+	bool link_fec;
 	bool has_audio;
 	bool reset_link_params;
 	u8 dpcd[DP_RECEIVER_CAP_SIZE];
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 25723f634b91..6243d5cdb2cf 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2382,8 +2382,60 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp,
 	intel_dp->link_rate = link_rate;
 	intel_dp->lane_count = lane_count;
 	intel_dp->link_mst = link_mst;
+	intel_dp->link_fec = false;
 }
 
+void intel_dp_enable_fec_state(struct intel_encoder *encoder,
+			       const struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	u32 val;
+
+	if (!crtc_state->fec_enable)
+		return;
+
+	intel_dp->link_fec = true;
+
+	val = I915_READ(intel_dp->regs.dp_tp_ctl);
+	val |= DP_TP_CTL_FEC_ENABLE;
+	I915_WRITE(intel_dp->regs.dp_tp_ctl, val);
+	POSTING_READ(intel_dp->regs.dp_tp_ctl);
+
+	if (intel_de_wait_for_set(dev_priv, DP_TP_STATUS(encoder->port),
+				  DP_TP_STATUS_FEC_ENABLE_LIVE, 1))
+		DRM_ERROR("Timed out waiting for FEC Enable Status\n");
+}
+
+void intel_dp_disable_fec_state(struct intel_encoder *encoder,
+				const struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	u32 val;
+
+	if (!crtc_state->fec_enable)
+		return;
+
+	intel_dp->link_fec = false;
+
+	val = I915_READ(intel_dp->regs.dp_tp_ctl);
+	val &= ~DP_TP_CTL_FEC_ENABLE;
+	I915_WRITE(intel_dp->regs.dp_tp_ctl, val);
+	POSTING_READ(intel_dp->regs.dp_tp_ctl);
+}
+
+void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp,
+				 const struct intel_crtc_state *crtc_state)
+{
+	if (!crtc_state->fec_enable)
+		return;
+
+	if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_FEC_CONFIGURATION, DP_FEC_READY) <= 0)
+		DRM_DEBUG_KMS("Failed to set FEC_READY in the sink\n");
+}
+
+
 static void intel_dp_prepare(struct intel_encoder *encoder,
 			     const struct intel_crtc_state *pipe_config)
 {
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index e9f11e698697..54bb647554c6 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -54,6 +54,12 @@ void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
 void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
 					   const struct intel_crtc_state *crtc_state,
 					   bool enable);
+void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp,
+				 const struct intel_crtc_state *crtc_state);
+void intel_dp_enable_fec_state(struct intel_encoder *encoder,
+			       const struct intel_crtc_state *crtc_state);
+void intel_dp_disable_fec_state(struct intel_encoder *encoder,
+				const struct intel_crtc_state *crtc_state);
 void intel_dp_encoder_reset(struct drm_encoder *encoder);
 void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder);
 void intel_dp_encoder_flush_work(struct drm_encoder *encoder);
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list