[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