Commit 4ce7cff5 authored by Imre Deak's avatar Imre Deak

drm/i915/dp: Use a commit modeset for link retraining MST links

Instead of direct calls to the link train functions, retrain the link
via a commit modeset. The direct call means that the output port will be
disabled/re-enabled while the rest of the pipeline (transcoder) is
active, which doesn't seem to work on MST at least. It leads to
underruns and black screen, presumedly because the transcoder is not
disabled/re-enabled along the port.

Leave switching to a commit modeset on SST for a later patchset, as that
seems to work ok currently (though better to using a commit there too,
due to the suppressed underruns).

v2: Keep reverse line length order for local variables. (Ville)
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240610164933.2947366-7-imre.deak@intel.com
parent e5bf189a
...@@ -5164,6 +5164,7 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, ...@@ -5164,6 +5164,7 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_crtc *crtc; struct intel_crtc *crtc;
bool mst_output = false;
u8 pipe_mask; u8 pipe_mask;
int ret; int ret;
...@@ -5195,6 +5196,11 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, ...@@ -5195,6 +5196,11 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state = const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state); to_intel_crtc_state(crtc->base.state);
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
mst_output = true;
break;
}
/* Suppress underruns caused by re-training */ /* Suppress underruns caused by re-training */
intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false); intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false);
if (crtc_state->has_pch_encoder) if (crtc_state->has_pch_encoder)
...@@ -5202,16 +5208,23 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, ...@@ -5202,16 +5208,23 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
intel_crtc_pch_transcoder(crtc), false); intel_crtc_pch_transcoder(crtc), false);
} }
/* TODO: use a modeset for SST as well. */
if (mst_output) {
ret = intel_modeset_commit_pipes(dev_priv, pipe_mask, ctx);
if (ret && ret != -EDEADLK)
drm_dbg_kms(&dev_priv->drm,
"[ENCODER:%d:%s] link retraining failed: %pe\n",
encoder->base.base.id, encoder->base.name,
ERR_PTR(ret));
return ret;
}
for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask) { for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask) {
const struct intel_crtc_state *crtc_state = const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state); to_intel_crtc_state(crtc->base.state);
/* retrain on the MST master transcoder */
if (DISPLAY_VER(dev_priv) >= 12 &&
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
!intel_dp_mst_is_master_trans(crtc_state))
continue;
intel_dp_check_frl_training(intel_dp); intel_dp_check_frl_training(intel_dp);
intel_dp_pcon_dsc_configure(intel_dp, crtc_state); intel_dp_pcon_dsc_configure(intel_dp, crtc_state);
intel_dp_start_link_train(intel_dp, crtc_state); intel_dp_start_link_train(intel_dp, crtc_state);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment