All of lore.kernel.org
 help / color / mirror / Atom feed
* [v2] drm/i915/dp: Add FEC Enable Retry mechanism
@ 2024-10-08 12:53 Chaitanya Kumar Borah
  2024-10-08 13:28 ` ✓ CI.Patch_applied: success for drm/i915/dp: Add FEC Enable Retry mechanism (rev2) Patchwork
                   ` (10 more replies)
  0 siblings, 11 replies; 13+ messages in thread
From: Chaitanya Kumar Borah @ 2024-10-08 12:53 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: nagavenkata.srikanth.v, jani.nikula

From PTL, FEC_DECODE_EN sequence can be sent to a DPRX independent
of TRANS_CONF enable. This allows us to re-issue an FEC_DECODE_EN
sequence without re-doing the whole mode set sequence. This separate
control over FEC_ECODE_EN/DIS sequence enables us to have a retry
mechanism in case the DPRX does not respond with an FEC_ENABLE
within the stipulated 5ms.

v2:
 - Refactor code to avoid duplication and improve readability [Jani]
 - In case of PTL, wait for FEC status directly after FEC enable [Srikanth]
 - Wait for FEC_ENABLE_LIVE_STATUS to be cleared before
   re-enabling FEC [Srikanth]

Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c    | 79 +++++++++++++++++----
 drivers/gpu/drm/i915/display/intel_ddi.h    |  2 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  4 +-
 3 files changed, 67 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index fe1ded6707f9..047816a427d5 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -2256,30 +2256,74 @@ static int read_fec_detected_status(struct drm_dp_aux *aux)
 	return status;
 }
 
-static void wait_for_fec_detected(struct drm_dp_aux *aux, bool enabled)
+static void retry_fec_enable(struct intel_encoder *encoder,
+			     const struct intel_crtc_state *crtc_state,
+		struct drm_dp_aux *aux)
+{
+	struct drm_i915_private *i915 = to_i915(aux->drm_dev);
+	int ret = 0;
+
+	ret = intel_de_wait_for_clear(i915, dp_tp_status_reg(encoder, crtc_state),
+				      DP_TP_STATUS_FEC_ENABLE_LIVE, 1);
+
+	if (ret)
+		drm_err(&i915->drm,
+			"Timeout waiting for FEC live state to get disabled during retry\n");
+
+	/* Clear FEC enable */
+	intel_de_rmw(i915, dp_tp_ctl_reg(encoder, crtc_state),
+		     DP_TP_CTL_FEC_ENABLE, 0);
+
+	/* Set FEC enable */
+	intel_de_rmw(i915, dp_tp_ctl_reg(encoder, crtc_state),
+		     0, DP_TP_CTL_FEC_ENABLE);
+
+	ret = intel_de_wait_for_set(i915, dp_tp_status_reg(encoder, crtc_state),
+				    DP_TP_STATUS_FEC_ENABLE_LIVE, 1);
+	if (!ret)
+		drm_dbg_kms(&i915->drm,
+			    "Timeout waiting for FEC live state to get enabled");
+}
+
+static void wait_for_fec_detected(struct intel_encoder *encoder,
+				  const struct intel_crtc_state *crtc_state,
+		struct drm_dp_aux *aux, bool enabled, bool retry)
 {
 	struct drm_i915_private *i915 = to_i915(aux->drm_dev);
 	int mask = enabled ? DP_FEC_DECODE_EN_DETECTED : DP_FEC_DECODE_DIS_DETECTED;
 	int status;
 	int err;
+	int max_retries = retry ? 3 : 1;
 
-	err = readx_poll_timeout(read_fec_detected_status, aux, status,
-				 status & mask || status < 0,
-				 10000, 200000);
+	for (int retrycount = 0; retrycount < max_retries; retrycount++) {
+		err = readx_poll_timeout(read_fec_detected_status, aux, status,
+					 status & mask || status < 0,
+					 retry ? 500 : 10000,
+					 retry ? 5000 : 200000);
 
-	if (!err && status >= 0)
-		return;
+		if (!err && status >= 0)
+			return;
 
-	if (err == -ETIMEDOUT)
-		drm_dbg_kms(&i915->drm, "Timeout waiting for FEC %s to get detected\n",
-			    str_enabled_disabled(enabled));
-	else
-		drm_dbg_kms(&i915->drm, "FEC detected status read error: %d\n", status);
+		if (err == -ETIMEDOUT) {
+			drm_dbg_kms(&i915->drm,
+				    "Timeout waiting for FEC %s to get detected, retrying (%d/%d)\n",
+				    str_enabled_disabled(enabled), retrycount + 1, max_retries);
+
+			if (retry && enabled)
+				retry_fec_enable(encoder, crtc_state, aux);
+		} else {
+			drm_dbg_kms(&i915->drm, "FEC detected status read error: %d\n", status);
+			return;
+		}
+	}
+
+	drm_err(&i915->drm, "FEC %s Failed after %d attempts\n",
+		str_enabled_disabled(enabled), max_retries);
 }
 
 void intel_ddi_wait_for_fec_status(struct intel_encoder *encoder,
 				   const struct intel_crtc_state *crtc_state,
-				   bool enabled)
+				   bool enabled, bool retry)
 {
 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
@@ -2305,7 +2349,7 @@ void intel_ddi_wait_for_fec_status(struct intel_encoder *encoder,
 	 * FEC decoding disabling so skip waiting for that.
 	 */
 	if (enabled)
-		wait_for_fec_detected(&intel_dp->aux, enabled);
+		wait_for_fec_detected(encoder, crtc_state, &intel_dp->aux, enabled, retry);
 }
 
 static void intel_ddi_enable_fec(struct intel_encoder *encoder,
@@ -2318,6 +2362,9 @@ static void intel_ddi_enable_fec(struct intel_encoder *encoder,
 
 	intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state),
 		     0, DP_TP_CTL_FEC_ENABLE);
+
+	if (DISPLAY_VER(dev_priv) >= 30)
+		intel_ddi_wait_for_fec_status(encoder, crtc_state, true, true);
 }
 
 static void intel_ddi_disable_fec(struct intel_encoder *encoder,
@@ -3010,7 +3057,7 @@ static void intel_disable_ddi_buf(struct intel_encoder *encoder,
 		disable_ddi_buf(encoder, crtc_state);
 	}
 
-	intel_ddi_wait_for_fec_status(encoder, crtc_state, false);
+	intel_ddi_wait_for_fec_status(encoder, crtc_state, false, false);
 }
 
 static void intel_ddi_post_disable_dp(struct intel_atomic_state *state,
@@ -3383,6 +3430,7 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
 			     const struct intel_crtc_state *crtc_state,
 			     const struct drm_connector_state *conn_state)
 {
+	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
 	struct intel_display *display = to_intel_display(encoder);
 	struct intel_crtc *pipe_crtc;
 	int i;
@@ -3394,7 +3442,8 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
 
 	intel_enable_transcoder(crtc_state);
 
-	intel_ddi_wait_for_fec_status(encoder, crtc_state, true);
+	if (DISPLAY_VER(i915) < 30)
+		intel_ddi_wait_for_fec_status(encoder, crtc_state, true, false);
 
 	for_each_pipe_crtc_modeset_enable(display, pipe_crtc, crtc_state, i) {
 		const struct intel_crtc_state *pipe_crtc_state =
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h
index 6d85422bdefe..981e7702e11e 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.h
+++ b/drivers/gpu/drm/i915/display/intel_ddi.h
@@ -65,7 +65,7 @@ void intel_ddi_enable_transcoder_clock(struct intel_encoder *encoder,
 void intel_ddi_disable_transcoder_clock(const  struct intel_crtc_state *crtc_state);
 void intel_ddi_wait_for_fec_status(struct intel_encoder *encoder,
 				   const struct intel_crtc_state *crtc_state,
-				   bool enabled);
+				   bool enabled, bool retry);
 void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state,
 			  const struct drm_connector_state *conn_state);
 bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 732d7543ad06..226ac9a73a55 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -1289,8 +1289,8 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
 
 	wait_for_act_sent(encoder, pipe_config);
 
-	if (first_mst_stream)
-		intel_ddi_wait_for_fec_status(encoder, pipe_config, true);
+	if (first_mst_stream && DISPLAY_VER(dev_priv) < 30)
+		intel_ddi_wait_for_fec_status(encoder, pipe_config, true, false);
 
 	ret = drm_dp_add_payload_part2(&intel_dp->mst_mgr,
 				       drm_atomic_get_mst_payload_state(mst_state,
-- 
2.25.1


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

end of thread, other threads:[~2024-10-14 12:05 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-08 12:53 [v2] drm/i915/dp: Add FEC Enable Retry mechanism Chaitanya Kumar Borah
2024-10-08 13:28 ` ✓ CI.Patch_applied: success for drm/i915/dp: Add FEC Enable Retry mechanism (rev2) Patchwork
2024-10-08 13:28 ` ✓ CI.checkpatch: " Patchwork
2024-10-08 13:29 ` ✓ CI.KUnit: " Patchwork
2024-10-08 13:41 ` ✓ CI.Build: " Patchwork
2024-10-08 13:43 ` ✓ CI.Hooks: " Patchwork
2024-10-08 13:45 ` ✗ CI.checksparse: warning " Patchwork
2024-10-08 14:02 ` ✓ CI.BAT: success " Patchwork
2024-10-08 14:17 ` ✓ Fi.CI.BAT: " Patchwork
2024-10-08 22:00 ` ✗ CI.FULL: failure " Patchwork
2024-10-09 15:16 ` [v2] drm/i915/dp: Add FEC Enable Retry mechanism Jani Nikula
2024-10-14 12:05   ` Borah, Chaitanya Kumar
2024-10-09 20:12 ` ✗ Fi.CI.IGT: failure for drm/i915/dp: Add FEC Enable Retry mechanism (rev2) 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.