[PATCH 6.19 160/844] drm/amd/display: Fix mismatched unlock for DMUB HW lock in HWSS fast path

From: Sasha Levin

Date: Sat Feb 28 2026 - 13:32:17 EST


From: Nicholas Kazlauskas <nicholas.kazlauskas@xxxxxxx>

[ Upstream commit af3303970da5ce5bfe6dffdd07f38f42aad603e0 ]

[Why]
The evaluation for whether we need to use the DMUB HW lock isn't the
same as whether we need to unlock which results in a hang when the
fast path is used for ASIC without FAMS support.

[How]
Store a flag that indicates whether we should use the lock and use
that same flag to specify whether unlocking is needed.

Reviewed-by: Swapnil Patel <swapnil.patel@xxxxxxx>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@xxxxxxx>
Signed-off-by: Chenyu Chen <chen-yu.chen@xxxxxxx>
Tested-by: Daniel Wheeler <daniel.wheeler@xxxxxxx>
Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx>
Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
---
drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index e2763b60482a0..052d573408c3e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -741,6 +741,7 @@ void hwss_build_fast_sequence(struct dc *dc,
struct dce_hwseq *hws = dc->hwseq;
struct pipe_ctx *current_pipe = NULL;
struct pipe_ctx *current_mpc_pipe = NULL;
+ bool is_dmub_lock_required = false;
unsigned int i = 0;

*num_steps = 0; // Initialize to 0
@@ -763,11 +764,12 @@ void hwss_build_fast_sequence(struct dc *dc,
(*num_steps)++;
}
if (dc->hwss.dmub_hw_control_lock_fast) {
+ is_dmub_lock_required = dc_state_is_fams2_in_use(dc, context) ||
+ dmub_hw_lock_mgr_does_link_require_lock(dc, stream->link);
+
block_sequence[*num_steps].params.dmub_hw_control_lock_fast_params.dc = dc;
block_sequence[*num_steps].params.dmub_hw_control_lock_fast_params.lock = true;
- block_sequence[*num_steps].params.dmub_hw_control_lock_fast_params.is_required =
- dc_state_is_fams2_in_use(dc, context) ||
- dmub_hw_lock_mgr_does_link_require_lock(dc, stream->link);
+ block_sequence[*num_steps].params.dmub_hw_control_lock_fast_params.is_required = is_dmub_lock_required;
block_sequence[*num_steps].func = DMUB_HW_CONTROL_LOCK_FAST;
(*num_steps)++;
}
@@ -906,7 +908,7 @@ void hwss_build_fast_sequence(struct dc *dc,
if (dc->hwss.dmub_hw_control_lock_fast) {
block_sequence[*num_steps].params.dmub_hw_control_lock_fast_params.dc = dc;
block_sequence[*num_steps].params.dmub_hw_control_lock_fast_params.lock = false;
- block_sequence[*num_steps].params.dmub_hw_control_lock_fast_params.is_required = dc_state_is_fams2_in_use(dc, context);
+ block_sequence[*num_steps].params.dmub_hw_control_lock_fast_params.is_required = is_dmub_lock_required;
block_sequence[*num_steps].func = DMUB_HW_CONTROL_LOCK_FAST;
(*num_steps)++;
}
--
2.51.0