From: Tomasz Siemek <[email protected]> [why] Periodic interrupt line calculations depends on stream and pipe state, not ASIC-specific register programming. Keeping it in the DCN10 implementation also prevents block-sequence callers from carrying fully resolved parameters. We want HWSS block parameters to not include complex structures like pipe_ctx.
[how] - Move the vertical interrupt line calculation into common HWSS code. - Update the periodic interrupt callback. - Calculate the values before direct or block-sequence execution. Reviewed-by: Alvin Lee <[email protected]> Signed-off-by: Tomasz Siemek <[email protected]> Signed-off-by: James Lin <[email protected]> --- drivers/gpu/drm/amd/display/dc/core/dc.c | 4 +- .../drm/amd/display/dc/core/dc_hw_sequencer.c | 76 ++++++++++++++++--- .../amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 41 +--------- .../amd/display/dc/hwss/dcn10/dcn10_hwseq.h | 5 +- .../drm/amd/display/dc/hwss/hw_sequencer.h | 12 +-- 5 files changed, 83 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 68f228014305..bc2207d29954 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -4367,8 +4367,8 @@ static void commit_planes_do_stream_update(struct dc *dc, if (resource_is_pipe_type(pipe_ctx, OTG_MASTER) && pipe_ctx->stream == stream) { - if (stream_update->periodic_interrupt && dc->hwss.setup_periodic_interrupt) - dc->hwss.setup_periodic_interrupt(dc, pipe_ctx); + if (stream_update->periodic_interrupt) + hwss_setup_periodic_interrupt(dc, pipe_ctx); if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) || stream_update->vrr_infopacket || 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 90d754d192f1..bfb598a22c26 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 @@ -745,6 +745,38 @@ static bool get_update_dchubp_dpp_flags_status(struct pipe_ctx *pipe) return false; } +static void calc_vline_position( + struct dc *dc, + struct pipe_ctx *pipe_ctx, + uint32_t *start_line, + uint32_t *end_line) +{ + if (!dc->hwss.get_vupdate_offset_from_vsync) + return; + + const struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; + int vline_pos = pipe_ctx->stream->periodic_interrupt.lines_offset; + + if (pipe_ctx->stream->periodic_interrupt.ref_point == START_V_UPDATE) { + if (vline_pos > 0) + vline_pos--; + else if (vline_pos < 0) + vline_pos++; + + vline_pos += dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx); + if (vline_pos >= 0) + *start_line = vline_pos - ((vline_pos / timing->v_total) * timing->v_total); + else + *start_line = vline_pos + ((-vline_pos / timing->v_total) + 1) * timing->v_total - 1; + *end_line = (*start_line + 2) % timing->v_total; + } else if (pipe_ctx->stream->periodic_interrupt.ref_point == START_V_SYNC) { + // vsync is line 0 so start_line is just the requested line offset + *start_line = vline_pos; + *end_line = (*start_line + 2) % timing->v_total; + } else + ASSERT(0); +} + // Function to check if any update flags are set static bool get_pipe_update_bits_status(struct pipe_ctx *pipe, struct dc_plane_state *plane, struct dc_stream_state *stream) { @@ -1173,8 +1205,16 @@ void hwss_build_fast_sequence(struct dc *dc, } if (dc->hwss.setup_periodic_interrupt && stream->update_flags.bits.periodic_interrupt) { - block_sequence[*num_steps].params.setup_periodic_interrupt_params.dc = dc; - block_sequence[*num_steps].params.setup_periodic_interrupt_params.pipe_ctx = pipe_ctx; + uint32_t start_line = 0; + uint32_t end_line = 0; + + calc_vline_position(dc, pipe_ctx, &start_line, &end_line); + block_sequence[*num_steps].params.setup_periodic_interrupt_params.tg = + pipe_ctx->stream_res.tg; + block_sequence[*num_steps].params.setup_periodic_interrupt_params.start_line = + start_line; + block_sequence[*num_steps].params.setup_periodic_interrupt_params.end_line = + end_line; block_sequence[*num_steps].func = HWSS_SETUP_PERIODIC_INTERRUPT; (*num_steps)++; } @@ -1668,7 +1708,11 @@ void hwss_execute_sequence(struct dc *dc, hwss_tg_setup_vertical_interrupt0(params); break; case HWSS_SETUP_PERIODIC_INTERRUPT: - hwss_setup_periodic_interrupt(dc, params); + if (dc->hwss.setup_periodic_interrupt) + dc->hwss.setup_periodic_interrupt( + params->setup_periodic_interrupt_params.tg, + params->setup_periodic_interrupt_params.start_line, + params->setup_periodic_interrupt_params.end_line); break; case HWSS_UPDATE_INFO_FRAME: hwss_update_info_frame(dc, params); @@ -3322,12 +3366,18 @@ void hwss_update_info_frame(struct dc *dc, union block_sequence_params *params) dc->hwss.update_info_frame(pipe_ctx); } -void hwss_setup_periodic_interrupt(struct dc *dc, union block_sequence_params *params) +void hwss_setup_periodic_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx) { - struct pipe_ctx *pipe_ctx = params->setup_periodic_interrupt_params.pipe_ctx; + uint32_t start_line = 0; + uint32_t end_line = 0; - if (dc->hwss.setup_periodic_interrupt) - dc->hwss.setup_periodic_interrupt(dc, pipe_ctx); + if (dc->hwss.setup_periodic_interrupt) { + calc_vline_position(dc, pipe_ctx, &start_line, &end_line); + dc->hwss.setup_periodic_interrupt( + pipe_ctx->stream_res.tg, + start_line, + end_line); + } } void hwss_tg_setup_vertical_interrupt0(union block_sequence_params *params) @@ -5934,9 +5984,17 @@ void hwss_add_setup_periodic_interrupt(struct block_sequence_state *seq_state, struct pipe_ctx *pipe_ctx) { if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) { + uint32_t start_line = 0; + uint32_t end_line = 0; + + calc_vline_position(dc, pipe_ctx, &start_line, &end_line); seq_state->steps[*seq_state->num_steps].func = HWSS_SETUP_PERIODIC_INTERRUPT; - seq_state->steps[*seq_state->num_steps].params.setup_periodic_interrupt_params.dc = dc; - seq_state->steps[*seq_state->num_steps].params.setup_periodic_interrupt_params.pipe_ctx = pipe_ctx; + seq_state->steps[*seq_state->num_steps].params.setup_periodic_interrupt_params.tg = + pipe_ctx->stream_res.tg; + seq_state->steps[*seq_state->num_steps].params.setup_periodic_interrupt_params.start_line = + start_line; + seq_state->steps[*seq_state->num_steps].params.setup_periodic_interrupt_params.end_line = + end_line; (*seq_state->num_steps)++; } } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c index 097e4ac2df05..850639b6fd9b 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c @@ -4026,45 +4026,12 @@ void dcn10_calc_vupdate_position( *end_line = (*start_line + 2) % timing->v_total; } -static void dcn10_cal_vline_position( - struct dc *dc, - struct pipe_ctx *pipe_ctx, - uint32_t *start_line, - uint32_t *end_line) -{ - const struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; - int vline_pos = pipe_ctx->stream->periodic_interrupt.lines_offset; - - if (pipe_ctx->stream->periodic_interrupt.ref_point == START_V_UPDATE) { - if (vline_pos > 0) - vline_pos--; - else if (vline_pos < 0) - vline_pos++; - - vline_pos += dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx); - if (vline_pos >= 0) - *start_line = vline_pos - ((vline_pos / timing->v_total) * timing->v_total); - else - *start_line = vline_pos + ((-vline_pos / timing->v_total) + 1) * timing->v_total - 1; - *end_line = (*start_line + 2) % timing->v_total; - } else if (pipe_ctx->stream->periodic_interrupt.ref_point == START_V_SYNC) { - // vsync is line 0 so start_line is just the requested line offset - *start_line = vline_pos; - *end_line = (*start_line + 2) % timing->v_total; - } else - ASSERT(0); -} - void dcn10_setup_periodic_interrupt( - struct dc *dc, - struct pipe_ctx *pipe_ctx) + struct timing_generator *tg, + uint32_t start_line, + uint32_t end_line + ) { - struct timing_generator *tg = pipe_ctx->stream_res.tg; - uint32_t start_line = 0; - uint32_t end_line = 0; - - dcn10_cal_vline_position(dc, pipe_ctx, &start_line, &end_line); - tg->funcs->setup_vertical_interrupt0(tg, start_line, end_line); } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h index 2cb674ba54e1..a93109c2199b 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h @@ -183,8 +183,9 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx); void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx); void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx); void dcn10_setup_periodic_interrupt( - struct dc *dc, - struct pipe_ctx *pipe_ctx); + struct timing_generator *tg, + uint32_t start_line, + uint32_t end_line); enum dc_status dcn10_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h index cdf2562a9a40..129120ac6d9e 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h @@ -819,8 +819,9 @@ struct cursor_lock_params { }; struct setup_periodic_interrupt_params { - struct dc *dc; - struct pipe_ctx *pipe_ctx; + struct timing_generator *tg; + uint32_t start_line; + uint32_t end_line; }; struct send_cursor_info_to_dmu_params { @@ -1452,8 +1453,9 @@ struct hw_sequencer_funcs { void (*enable_vblanks_synchronization)(struct dc *dc, int group_index, int group_size, struct pipe_ctx *grouped_pipes[]); - void (*setup_periodic_interrupt)(struct dc *dc, - struct pipe_ctx *pipe_ctx); + void (*setup_periodic_interrupt)(struct timing_generator *tg, + uint32_t start_line, + uint32_t end_line); void (*set_drr)(struct pipe_ctx **pipe_ctx, int num_pipes, struct dc_crtc_timing_adjust adjust); void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx, @@ -2113,7 +2115,7 @@ void hwss_commit_cursor_offload_update(union block_sequence_params *params); void hwss_update_cursor_offload_pipe(union block_sequence_params *params); -void hwss_setup_periodic_interrupt(struct dc *dc, union block_sequence_params *params); +void hwss_setup_periodic_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx); void hwss_disable_audio_stream(struct dc *dc, union block_sequence_params *params); -- 2.43.0
