[PATCH 3/5] drm/amd/display: remove duplicated program_front_end_for_ctx code
Melissa Wen
mwen at igalia.com
Wed Apr 30 14:20:09 UTC 2025
Add detect_pipe_changes hook to dcn20_program_front_end_for_ctx and hook
the later to program_front_end_for_ctx in dcn401, then remove
dcn401_program_front_end_for_ctx duplicated code.
Signed-off-by: Melissa Wen <mwen at igalia.com>
---
.../amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 13 +-
.../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 166 ------------------
.../amd/display/dc/hwss/dcn401/dcn401_hwseq.h | 1 -
.../amd/display/dc/hwss/dcn401/dcn401_init.c | 2 +-
4 files changed, 11 insertions(+), 171 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
index 1be9be74564e..b5fc96338229 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
@@ -2082,9 +2082,16 @@ void dcn20_program_front_end_for_ctx(
}
/* Set pipe update flags and lock pipes */
- for (i = 0; i < dc->res_pool->pipe_count; i++)
- dcn20_detect_pipe_changes(dc->current_state, context, &dc->current_state->res_ctx.pipe_ctx[i],
- &context->res_ctx.pipe_ctx[i]);
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ if (dc->hwss.detect_pipe_changes)
+ dc->hwss.detect_pipe_changes(dc->current_state, context,
+ &dc->current_state->res_ctx.pipe_ctx[i],
+ &context->res_ctx.pipe_ctx[i]);
+ else
+ dcn20_detect_pipe_changes(dc->current_state, context,
+ &dc->current_state->res_ctx.pipe_ctx[i],
+ &context->res_ctx.pipe_ctx[i]);
+ }
/* When disabling phantom pipes, turn on phantom OTG first (so we can get double
* buffer updates properly)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 06190c73c22c..f3ff144ce9a7 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -2340,172 +2340,6 @@ void dcn401_program_pipe(
}
}
-void dcn401_program_front_end_for_ctx(
- struct dc *dc,
- struct dc_state *context)
-{
- int i;
- unsigned int prev_hubp_count = 0;
- unsigned int hubp_count = 0;
- struct dce_hwseq *hws = dc->hwseq;
- struct pipe_ctx *pipe = NULL;
-
- DC_LOGGER_INIT(dc->ctx->logger);
-
- if (resource_is_pipe_topology_changed(dc->current_state, context))
- resource_log_pipe_topology_update(dc, context);
-
- if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) {
- for (i = 0; i < dc->res_pool->pipe_count; i++) {
- pipe = &context->res_ctx.pipe_ctx[i];
-
- if (!pipe->top_pipe && !pipe->prev_odm_pipe && pipe->plane_state) {
- if (pipe->plane_state->triplebuffer_flips)
- BREAK_TO_DEBUGGER();
-
- /*turn off triple buffer for full update*/
- dc->hwss.program_triplebuffer(
- dc, pipe, pipe->plane_state->triplebuffer_flips);
- }
- }
- }
-
- for (i = 0; i < dc->res_pool->pipe_count; i++) {
- if (dc->current_state->res_ctx.pipe_ctx[i].plane_state)
- prev_hubp_count++;
- if (context->res_ctx.pipe_ctx[i].plane_state)
- hubp_count++;
- }
-
- if (prev_hubp_count == 0 && hubp_count > 0) {
- if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
- dc->res_pool->hubbub->funcs->force_pstate_change_control(
- dc->res_pool->hubbub, true, false);
- udelay(500);
- }
-
- /* Set pipe update flags and lock pipes */
- for (i = 0; i < dc->res_pool->pipe_count; i++)
- dc->hwss.detect_pipe_changes(dc->current_state, context, &dc->current_state->res_ctx.pipe_ctx[i],
- &context->res_ctx.pipe_ctx[i]);
-
- /* When disabling phantom pipes, turn on phantom OTG first (so we can get double
- * buffer updates properly)
- */
- for (i = 0; i < dc->res_pool->pipe_count; i++) {
- struct dc_stream_state *stream = dc->current_state->res_ctx.pipe_ctx[i].stream;
-
- pipe = &dc->current_state->res_ctx.pipe_ctx[i];
-
- if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable && stream &&
- dc_state_get_pipe_subvp_type(dc->current_state, pipe) == SUBVP_PHANTOM) {
- struct timing_generator *tg = dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg;
-
- if (tg->funcs->enable_crtc) {
- if (dc->hwseq->funcs.blank_pixel_data)
- dc->hwseq->funcs.blank_pixel_data(dc, pipe, true);
-
- tg->funcs->enable_crtc(tg);
- }
- }
- }
- /* OTG blank before disabling all front ends */
- for (i = 0; i < dc->res_pool->pipe_count; i++)
- if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable
- && !context->res_ctx.pipe_ctx[i].top_pipe
- && !context->res_ctx.pipe_ctx[i].prev_odm_pipe
- && context->res_ctx.pipe_ctx[i].stream)
- hws->funcs.blank_pixel_data(dc, &context->res_ctx.pipe_ctx[i], true);
-
-
- /* Disconnect mpcc */
- for (i = 0; i < dc->res_pool->pipe_count; i++)
- if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable
- || context->res_ctx.pipe_ctx[i].update_flags.bits.opp_changed) {
- struct hubbub *hubbub = dc->res_pool->hubbub;
-
- /* Phantom pipe DET should be 0, but if a pipe in use is being transitioned to phantom
- * then we want to do the programming here (effectively it's being disabled). If we do
- * the programming later the DET won't be updated until the OTG for the phantom pipe is
- * turned on (i.e. in an MCLK switch) which can come in too late and cause issues with
- * DET allocation.
- */
- if ((context->res_ctx.pipe_ctx[i].update_flags.bits.disable ||
- (context->res_ctx.pipe_ctx[i].plane_state &&
- dc_state_get_pipe_subvp_type(context, &context->res_ctx.pipe_ctx[i]) ==
- SUBVP_PHANTOM))) {
- if (hubbub->funcs->program_det_size)
- hubbub->funcs->program_det_size(hubbub,
- dc->current_state->res_ctx.pipe_ctx[i].plane_res.hubp->inst, 0);
- if (dc->res_pool->hubbub->funcs->program_det_segments)
- dc->res_pool->hubbub->funcs->program_det_segments(
- hubbub, dc->current_state->res_ctx.pipe_ctx[i].plane_res.hubp->inst, 0);
- }
- hws->funcs.plane_atomic_disconnect(dc, dc->current_state,
- &dc->current_state->res_ctx.pipe_ctx[i]);
- DC_LOG_DC("Reset mpcc for pipe %d\n", dc->current_state->res_ctx.pipe_ctx[i].pipe_idx);
- }
-
- /* update ODM for blanked OTG master pipes */
- for (i = 0; i < dc->res_pool->pipe_count; i++) {
- pipe = &context->res_ctx.pipe_ctx[i];
- if (resource_is_pipe_type(pipe, OTG_MASTER) &&
- !resource_is_pipe_type(pipe, DPP_PIPE) &&
- pipe->update_flags.bits.odm &&
- hws->funcs.update_odm)
- hws->funcs.update_odm(dc, context, pipe);
- }
-
- /*
- * Program all updated pipes, order matters for mpcc setup. Start with
- * top pipe and program all pipes that follow in order
- */
- for (i = 0; i < dc->res_pool->pipe_count; i++) {
- pipe = &context->res_ctx.pipe_ctx[i];
-
- if (pipe->plane_state && !pipe->top_pipe) {
- while (pipe) {
- if (hws->funcs.program_pipe)
- hws->funcs.program_pipe(dc, pipe, context);
- else {
- /* Don't program phantom pipes in the regular front end programming sequence.
- * There is an MPO transition case where a pipe being used by a video plane is
- * transitioned directly to be a phantom pipe when closing the MPO video.
- * However the phantom pipe will program a new HUBP_VTG_SEL (update takes place
- * right away) but the MPO still exists until the double buffered update of the
- * main pipe so we will get a frame of underflow if the phantom pipe is
- * programmed here.
- */
- if (pipe->stream &&
- dc_state_get_pipe_subvp_type(context, pipe) != SUBVP_PHANTOM)
- dcn401_program_pipe(dc, pipe, context);
- }
-
- pipe = pipe->bottom_pipe;
- }
- }
-
- /* Program secondary blending tree and writeback pipes */
- pipe = &context->res_ctx.pipe_ctx[i];
- if (!pipe->top_pipe && !pipe->prev_odm_pipe
- && pipe->stream && pipe->stream->num_wb_info > 0
- && (pipe->update_flags.raw || (pipe->plane_state && pipe->plane_state->update_flags.raw)
- || pipe->stream->update_flags.raw)
- && hws->funcs.program_all_writeback_pipes_in_tree)
- hws->funcs.program_all_writeback_pipes_in_tree(dc, pipe->stream, context);
-
- /* Avoid underflow by check of pipe line read when adding 2nd plane. */
- if (hws->wa.wait_hubpret_read_start_during_mpo_transition &&
- !pipe->top_pipe &&
- pipe->stream &&
- pipe->plane_res.hubp->funcs->hubp_wait_pipe_read_start &&
- dc->current_state->stream_status[0].plane_count == 1 &&
- context->stream_status[0].plane_count > 1) {
- pipe->plane_res.hubp->funcs->hubp_wait_pipe_read_start(pipe->plane_res.hubp);
- }
- }
-}
-
void dcn401_post_unlock_program_front_end(
struct dc *dc,
struct dc_state *context)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
index 26c350efb1c2..50fa08098449 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
@@ -102,7 +102,6 @@ void dcn401_program_pipe(
struct pipe_ctx *pipe_ctx,
struct dc_state *context);
void dcn401_perform_3dlut_wa_unlock(struct pipe_ctx *pipe_ctx);
-void dcn401_program_front_end_for_ctx(struct dc *dc, struct dc_state *context);
void dcn401_post_unlock_program_front_end(struct dc *dc, struct dc_state *context);
bool dcn401_update_bandwidth(struct dc *dc, struct dc_state *context);
void dcn401_detect_pipe_changes(
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
index 65c551895ac9..848d8a74e6c5 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
@@ -17,7 +17,7 @@ static const struct hw_sequencer_funcs dcn401_funcs = {
.init_hw = dcn401_init_hw,
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
.apply_ctx_for_surface = NULL,
- .program_front_end_for_ctx = dcn401_program_front_end_for_ctx,
+ .program_front_end_for_ctx = dcn20_program_front_end_for_ctx,
.clear_surface_dcc_and_tiling = dcn10_reset_surface_dcc_and_tiling,
.wait_for_pending_cleared = dcn10_wait_for_pending_cleared,
.post_unlock_program_front_end = dcn401_post_unlock_program_front_end,
--
2.47.2
More information about the dri-devel
mailing list