diff options
author | Imre Deak <imre.deak@intel.com> | 2024-06-10 19:49:18 +0300 |
---|---|---|
committer | Imre Deak <imre.deak@intel.com> | 2024-06-13 21:26:49 +0300 |
commit | 4ce7cff538cda112891d9baab703529bfed15d7d (patch) | |
tree | 5119ce216ded0186c031a04d609ab5700e2933ce /drivers/gpu/drm/i915/display/intel_dp.c | |
parent | e5bf189a0f2508ec6e72926728aec35f806dca76 (diff) |
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: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240610164933.2947366-7-imre.deak@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dp.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_dp.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 7386c1050d4f..edd3e0e7085f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -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 intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_crtc *crtc; + bool mst_output = false; u8 pipe_mask; int ret; @@ -5195,6 +5196,11 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_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 */ intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false); if (crtc_state->has_pch_encoder) @@ -5202,16 +5208,23 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, 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) { const struct intel_crtc_state *crtc_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_pcon_dsc_configure(intel_dp, crtc_state); intel_dp_start_link_train(intel_dp, crtc_state); |