mirror of
https://github.com/torvalds/linux.git
synced 2026-11-10 08:53:02 +01:00
drm/amd/display: Move periodic interrupt calculations to HWSS
[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 <alvin.lee2@amd.com> Signed-off-by: Tomasz Siemek <tomasz.siemek@amd.com> Signed-off-by: James Lin <pinglei.lin@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
5ea44e1347
commit
d24695f377
|
|
@ -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 ||
|
||||
|
|
|
|||
|
|
@ -754,6 +754,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)
|
||||
{
|
||||
|
|
@ -1182,8 +1214,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)++;
|
||||
}
|
||||
|
|
@ -1677,7 +1717,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);
|
||||
|
|
@ -3331,12 +3375,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)
|
||||
|
|
@ -5943,9 +5993,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)++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user