When the last MST stream is disabled, i915 sends SET_POWER D3 to the MST trunk while MSTM_CTRL (DPCD 0x111) still has MST mode enabled. On re-enable, POWER_UP_PHY is sent before MSTM_CTRL is restored, so the hub may process the PHY power-up in an inconsistent state and fail to retrain its downstream links.
Fix this by clearing MSTM_CTRL before sending D3 on the last stream disable, mirroring what drm_dp_mst_topology_mgr_set_mst() does on MST disconnect. On re-enable, restore MSTM_CTRL after writing D0 and before sending POWER_UP_PHY, so the hub is back in MST mode when it processes the PHY power-up and retrains its downstream links. Signed-off-by: Xiao Lu <[email protected]> --- drivers/gpu/drm/i915/display/intel_ddi.c | 2 ++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index a46ab5d3d..7e4e18345 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3163,6 +3163,8 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, * Power down sink before disabling the port, otherwise we end * up getting interrupts from the sink on detecting link loss. */ + if (is_mst) + drm_dp_dpcd_write_byte(&intel_dp->aux, DP_MSTM_CTRL, 0); intel_dp_set_power(intel_dp, DP_SET_POWER_D3); if (DISPLAY_VER(display) >= 12) { diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 7023619aa..4109bb928 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1270,8 +1270,12 @@ static void mst_stream_pre_enable(struct intel_atomic_state *state, drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 12 && first_mst_stream && !intel_dp_mst_is_master_trans(pipe_config)); - if (first_mst_stream) + if (first_mst_stream) { intel_dp_set_power(intel_dp, DP_SET_POWER_D0); + drm_dp_dpcd_write_byte(&intel_dp->aux, DP_MSTM_CTRL, + DP_MST_EN | DP_UP_REQ_EN | + DP_UPSTREAM_IS_SRC); + } drm_dp_send_power_updown_phy(&intel_dp->mst.mgr, connector->mst.port, true); -- 2.43.0
