]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/display: Don't disable DPCD mst_en if sink connected
authorPeichen Huang <PeiChen.Huang@amd.com>
Tue, 18 Nov 2025 03:19:36 +0000 (11:19 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 16 Dec 2025 18:25:45 +0000 (13:25 -0500)
[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>
drivers/gpu/drm/amd/display/dc/link/link_dpms.c

index 87f9ceebe26a413fb9aaba4066fc5711e30fb36b..7384676e646d6df83af09e8c11d77b04c2a2d12d 100644 (file)
@@ -1931,7 +1931,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);
 
@@ -2082,7 +2082,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)
@@ -2368,9 +2373,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);
                }
        }
 
@@ -2484,10 +2489,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);
                }
        }