Skip to content

Commit 5a3ccb1

Browse files
Gabe Teegeralexdeucher
authored andcommitted
drm/amd/display: Remove wait while locked
[Why] We wait for mpc idle while in a locked state, leading to potential deadlock. [What] Move the wait_for_idle call to outside of HW lock. This and a call to wait_drr_doublebuffer_pending_clear are moved added to a new static helper function called wait_for_outstanding_hw_updates, to make the interface clearer. Cc: [email protected] Fixes: 8f0d304 ("drm/amd/display: Do not commit pipe when updating DRR") Reviewed-by: Jun Lei <[email protected]> Acked-by: Hamza Mahfooz <[email protected]> Signed-off-by: Gabe Teeger <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 1482650 commit 5a3ccb1

File tree

3 files changed

+42
-28
lines changed

3 files changed

+42
-28
lines changed

drivers/gpu/drm/amd/display/dc/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,4 @@ DC_EDID += dc_edid_parser.o
7878
AMD_DISPLAY_DMUB = $(addprefix $(AMDDALPATH)/dc/,$(DC_DMUB))
7979
AMD_DISPLAY_EDID = $(addprefix $(AMDDALPATH)/dc/,$(DC_EDID))
8080
AMD_DISPLAY_FILES += $(AMD_DISPLAY_DMUB) $(AMD_DISPLAY_EDID)
81+

drivers/gpu/drm/amd/display/dc/core/dc.c

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3501,6 +3501,45 @@ static void commit_planes_for_stream_fast(struct dc *dc,
35013501
top_pipe_to_program->stream->update_flags.raw = 0;
35023502
}
35033503

3504+
static void wait_for_outstanding_hw_updates(struct dc *dc, const struct dc_state *dc_context)
3505+
{
3506+
/*
3507+
* This function calls HWSS to wait for any potentially double buffered
3508+
* operations to complete. It should be invoked as a pre-amble prior
3509+
* to full update programming before asserting any HW locks.
3510+
*/
3511+
int pipe_idx;
3512+
int opp_inst;
3513+
int opp_count = dc->res_pool->pipe_count;
3514+
struct hubp *hubp;
3515+
int mpcc_inst;
3516+
const struct pipe_ctx *pipe_ctx;
3517+
3518+
for (pipe_idx = 0; pipe_idx < dc->res_pool->pipe_count; pipe_idx++) {
3519+
pipe_ctx = &dc_context->res_ctx.pipe_ctx[pipe_idx];
3520+
3521+
if (!pipe_ctx->stream)
3522+
continue;
3523+
3524+
if (pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear)
3525+
pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear(pipe_ctx->stream_res.tg);
3526+
3527+
hubp = pipe_ctx->plane_res.hubp;
3528+
if (!hubp)
3529+
continue;
3530+
3531+
mpcc_inst = hubp->inst;
3532+
// MPCC inst is equal to pipe index in practice
3533+
for (opp_inst = 0; opp_inst < opp_count; opp_inst++) {
3534+
if (dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst]) {
3535+
dc->res_pool->mpc->funcs->wait_for_idle(dc->res_pool->mpc, mpcc_inst);
3536+
dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst] = false;
3537+
break;
3538+
}
3539+
}
3540+
}
3541+
}
3542+
35043543
static void commit_planes_for_stream(struct dc *dc,
35053544
struct dc_surface_update *srf_updates,
35063545
int surface_count,
@@ -3519,24 +3558,9 @@ static void commit_planes_for_stream(struct dc *dc,
35193558
// dc->current_state anymore, so we have to cache it before we apply
35203559
// the new SubVP context
35213560
subvp_prev_use = false;
3522-
3523-
35243561
dc_z10_restore(dc);
3525-
3526-
if (update_type == UPDATE_TYPE_FULL) {
3527-
/* wait for all double-buffer activity to clear on all pipes */
3528-
int pipe_idx;
3529-
3530-
for (pipe_idx = 0; pipe_idx < dc->res_pool->pipe_count; pipe_idx++) {
3531-
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
3532-
3533-
if (!pipe_ctx->stream)
3534-
continue;
3535-
3536-
if (pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear)
3537-
pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear(pipe_ctx->stream_res.tg);
3538-
}
3539-
}
3562+
if (update_type == UPDATE_TYPE_FULL)
3563+
wait_for_outstanding_hw_updates(dc, context);
35403564

35413565
if (update_type == UPDATE_TYPE_FULL) {
35423566
dc_allow_idle_optimizations(dc, false);

drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,17 +1561,6 @@ static void dcn20_update_dchubp_dpp(
15611561
|| plane_state->update_flags.bits.global_alpha_change
15621562
|| plane_state->update_flags.bits.per_pixel_alpha_change) {
15631563
// MPCC inst is equal to pipe index in practice
1564-
int mpcc_inst = hubp->inst;
1565-
int opp_inst;
1566-
int opp_count = dc->res_pool->pipe_count;
1567-
1568-
for (opp_inst = 0; opp_inst < opp_count; opp_inst++) {
1569-
if (dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst]) {
1570-
dc->res_pool->mpc->funcs->wait_for_idle(dc->res_pool->mpc, mpcc_inst);
1571-
dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst] = false;
1572-
break;
1573-
}
1574-
}
15751564
hws->funcs.update_mpcc(dc, pipe_ctx);
15761565
}
15771566

0 commit comments

Comments
 (0)