[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