[PATCH AUTOSEL 6.19-6.6] drm/amd/display: Ensure link output is disabled in backend reset for PLL_ON

Sasha Levin
2026-02-14T01:06:10Z

From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>

[ Upstream commit 4589712e0111352973131bad975023b25569287c ]

[Why]
We're missing the code to actually disable the link output when we have
to leave the SYMCLK_ON but the TX remains OFF.

[How]
Port the code from DCN401 that detects SYMCLK_ON_TX_OFF and disable
the link output when the backend is reset.

Reviewed-by: Ovidiu (Ovi) Bunea <ovidiu.bunea@amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Matthew Stewart <matthew.stewart2@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

Both DCN20 and DCN401 already have this code. DCN31 was missing it,
which confirms this is a genuine omission/bug. The fix brings DCN31 in
line with other display controller versions.

### 8. SUMMARY

**What it fixes**: DCN31 was missing link output disable logic during
backend reset when in `SYMCLK_ON_TX_OFF` state. This left the hardware
in an inconsistent state where the symbolic clock was active but the
transmitter was off and the link output wasn't properly disabled.

**Impact**: This affects AMD display hardware using DCN31
(Rembrandt/Yellow Carp APUs, Van Gogh, etc. - widely deployed in laptops
and desktops). The incomplete state transition could cause display
issues during mode changes, hotplug, or suspend/resume.

**Meets stable criteria**:
- Fixes a real bug (missing hardware state transition)
- Small and contained (one file, ~14 lines added)
- Obviously correct (ported from DCN401/DCN20 which already have this
code)
- Tested-by and Reviewed-by tags present
- No new features or API changes

**Risk**: Very low. The code is guarded by specific state checks
(`SYMCLK_ON_TX_OFF`, `top_pipe == NULL`) and uses existing, well-tested
APIs. The same pattern exists in DCN20 and DCN401.

**Dependencies**: The required APIs (`get_link_hwss`,
`disable_link_output`, `SYMCLK_ON_TX_OFF` enum) already exist in the
codebase and should be available in stable trees that have DCN31
support.

This is a straightforward bug fix that brings DCN31 into consistency
with other DCN versions, fixing a missing hardware state transition that
could cause display issues for real users.

**YES**

.../drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
index d1ecdb92b072b..20f700b59847c 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
@@ -546,8 +546,22 @@ static void dcn31_reset_back_end_for_pipe(
if (pipe_ctx->stream_res.tg->funcs->set_odm_bypass)
pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
+ /*
+ * TODO - convert symclk_ref_cnts for otg to a bit map to solve
+ * the case where the same symclk is shared across multiple otg
+ * instances
+ */
if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal))
- pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0;
+ link->phy_state.symclk_ref_cnts.otg = 0;
+
+ if (pipe_ctx->top_pipe == NULL) {
+ if (link->phy_state.symclk_state == SYMCLK_ON_TX_OFF) {
+ const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
+
+ link_hwss->disable_link_output(link, &pipe_ctx->link_res, pipe_ctx->stream->signal);
+ link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+ }
+ }

set_drr_and_clear_adjust_pending(pipe_ctx, pipe_ctx->stream, NULL);

--
2.51.0