[PATCH 6.18 124/752] drm/amd/display: Don't disable DPCD mst_en if sink connected

Sasha Levin
2026-02-28T17:49:53Z

From: Peichen Huang <PeiChen.Huang@amd.com>

[ Upstream commit 9aeb31b2456452257ad1ff7ec566f21bab1f3e8a ]

[WHY]
User may connect mst dock with multi monitors and do quick unplug
and plug in one of the monitor. This operatioin may create CSN from
dock to display driver. Then display driver would disable and then enable
mst link and also disable/enable DPCD mst_en bit in dock RX. However,
when mst_en bit being disabled, if dock has another CSN message to
transmit then the message would be removed because of the disabling of
mst_en. In this case, the message is missing and it ends up no display in
the replugged monitor.

[HOW]
Don't disable mst_en bit when link still has sink connected.

Reviewed-by: Wenjing Liu <wenjing.liu@amd.com>
Signed-off-by: Peichen Huang <PeiChen.Huang@amd.com>
Signed-off-by: Chenyu Chen <chen-yu.chen@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
index b66fbcb0040d6..a084c698ed6ef 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
@@ -1928,7 +1928,7 @@ static void disable_link_dp(struct dc_link *link,
link->dc->hwss.edp_power_control(link, false);
}

- if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
+ if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST && link->sink_count == 0)
/* set the sink to SST mode after disabling the link */
enable_mst_on_sink(link, false);

@@ -2079,7 +2079,12 @@ static enum dc_status enable_link_dp(struct dc_state *state,
pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
link->dc->debug.set_mst_en_for_sst) {
enable_mst_on_sink(link, true);
+ } else if (link->dpcd_caps.is_mst_capable &&
+ pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT) {
+ /* disable mst on sink */
+ enable_mst_on_sink(link, false);
}
+
if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) {
/*in case it is not on*/
if (!link->dc->config.edp_no_power_sequencing)
@@ -2358,9 +2363,9 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
if (pipe_ctx->stream->sink) {
if (pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_NONE) {
- DC_LOG_DC("%s pipe_ctx dispname=%s signal=%x link=%d\n", __func__,
+ DC_LOG_DC("%s pipe_ctx dispname=%s signal=%x link=%d sink_count=%d\n", __func__,
pipe_ctx->stream->sink->edid_caps.display_name,
- pipe_ctx->stream->signal, link->link_index);
+ pipe_ctx->stream->signal, link->link_index, link->sink_count);
}
}

@@ -2474,10 +2479,11 @@ void link_set_dpms_on(
if (pipe_ctx->stream->sink) {
if (pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_NONE) {
- DC_LOG_DC("%s pipe_ctx dispname=%s signal=%x link=%d\n", __func__,
+ DC_LOG_DC("%s pipe_ctx dispname=%s signal=%x link=%d sink_count=%d\n", __func__,
pipe_ctx->stream->sink->edid_caps.display_name,
pipe_ctx->stream->signal,
- link->link_index);
+ link->link_index,
+ link->sink_count);
}
}

--
2.51.0