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 <m...@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