mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
drm/amd/display: Enable additional wait for pipe pending checks
[why] In cases where there are two FULL updates within the same display frame, it's possible for some blocks to be programmed a second time without having been latched completely from the first programming. DCN 3.5 and up already work around this with additional validation checks for frame count and defer as needed via fsleep. [how] Enabled existing pipe checks generically for all DCN versions to avoid HW programming hazards. Also removed redundant max_frame_count which can be determined by the register mask and shift. Reviewed-by: Alvin Lee <alvin.lee2@amd.com> Signed-off-by: Aric Cyr <Aric.Cyr@amd.com> Signed-off-by: Ivan Lipski <ivan.lipski@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
2f28f0063a
commit
e91130c016
|
|
@ -181,6 +181,7 @@ void dcn10_set_wait_for_update_needed_for_pipe(struct dc *dc, struct pipe_ctx *p
|
|||
uint32_t vupdate_start, vupdate_end;
|
||||
struct crtc_position position;
|
||||
unsigned int vpos, cur_frame;
|
||||
uint32_t max_frame_count;
|
||||
|
||||
if (!pipe_ctx->stream ||
|
||||
!pipe_ctx->stream_res.tg ||
|
||||
|
|
@ -197,7 +198,8 @@ void dcn10_set_wait_for_update_needed_for_pipe(struct dc *dc, struct pipe_ctx *p
|
|||
|
||||
struct optc *optc1 = DCN10TG_FROM_TG(tg);
|
||||
|
||||
ASSERT(optc1->max_frame_count != 0);
|
||||
max_frame_count = optc1->tg_mask->OTG_FRAME_COUNT >> optc1->tg_shift->OTG_FRAME_COUNT;
|
||||
ASSERT(max_frame_count != 0);
|
||||
|
||||
if (tg->funcs->is_tg_enabled && !tg->funcs->is_tg_enabled(tg))
|
||||
return;
|
||||
|
|
@ -209,8 +211,8 @@ void dcn10_set_wait_for_update_needed_for_pipe(struct dc *dc, struct pipe_ctx *p
|
|||
if (vpos < vupdate_start) {
|
||||
pipe_ctx->wait_frame_count = cur_frame;
|
||||
} else {
|
||||
if (cur_frame + 1 > optc1->max_frame_count)
|
||||
pipe_ctx->wait_frame_count = cur_frame + 1 - optc1->max_frame_count;
|
||||
if (cur_frame + 1 > max_frame_count)
|
||||
pipe_ctx->wait_frame_count = cur_frame + 1 - max_frame_count;
|
||||
else
|
||||
pipe_ctx->wait_frame_count = cur_frame + 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,6 +118,8 @@ static const struct hwseq_private_funcs dcn10_private_funcs = {
|
|||
.dsc_pg_control = NULL,
|
||||
.set_hdr_multiplier = dcn10_set_hdr_multiplier,
|
||||
.verify_allow_pstate_change_high = dcn10_verify_allow_pstate_change_high,
|
||||
.wait_for_pipe_update_if_needed = dcn10_wait_for_pipe_update_if_needed,
|
||||
.set_wait_for_update_needed_for_pipe = dcn10_set_wait_for_update_needed_for_pipe,
|
||||
};
|
||||
|
||||
void dcn10_hw_sequencer_construct(struct dc *dc)
|
||||
|
|
|
|||
|
|
@ -136,6 +136,8 @@ static const struct hwseq_private_funcs dcn20_private_funcs = {
|
|||
.dccg_init = dcn20_dccg_init,
|
||||
.set_blend_lut = dcn20_set_blend_lut,
|
||||
.set_shaper_3dlut = dcn20_set_shaper_3dlut,
|
||||
.wait_for_pipe_update_if_needed = dcn10_wait_for_pipe_update_if_needed,
|
||||
.set_wait_for_update_needed_for_pipe = dcn10_set_wait_for_update_needed_for_pipe,
|
||||
};
|
||||
|
||||
void dcn20_hw_sequencer_construct(struct dc *dc)
|
||||
|
|
|
|||
|
|
@ -145,6 +145,8 @@ static const struct hwseq_private_funcs dcn30_private_funcs = {
|
|||
.wait_for_blank_complete = dcn20_wait_for_blank_complete,
|
||||
.set_blend_lut = dcn30_set_blend_lut,
|
||||
.set_shaper_3dlut = dcn20_set_shaper_3dlut,
|
||||
.wait_for_pipe_update_if_needed = dcn10_wait_for_pipe_update_if_needed,
|
||||
.set_wait_for_update_needed_for_pipe = dcn10_set_wait_for_update_needed_for_pipe,
|
||||
};
|
||||
|
||||
void dcn30_hw_sequencer_construct(struct dc *dc)
|
||||
|
|
|
|||
|
|
@ -142,6 +142,8 @@ static const struct hwseq_private_funcs dcn301_private_funcs = {
|
|||
.wait_for_blank_complete = dcn20_wait_for_blank_complete,
|
||||
.set_blend_lut = dcn30_set_blend_lut,
|
||||
.set_shaper_3dlut = dcn20_set_shaper_3dlut,
|
||||
.wait_for_pipe_update_if_needed = dcn10_wait_for_pipe_update_if_needed,
|
||||
.set_wait_for_update_needed_for_pipe = dcn10_set_wait_for_update_needed_for_pipe,
|
||||
};
|
||||
|
||||
void dcn301_hw_sequencer_construct(struct dc *dc)
|
||||
|
|
|
|||
|
|
@ -147,6 +147,8 @@ static const struct hwseq_private_funcs dcn31_private_funcs = {
|
|||
.set_blend_lut = dcn30_set_blend_lut,
|
||||
.set_shaper_3dlut = dcn20_set_shaper_3dlut,
|
||||
.setup_hpo_hw_control = dcn31_setup_hpo_hw_control,
|
||||
.wait_for_pipe_update_if_needed = dcn10_wait_for_pipe_update_if_needed,
|
||||
.set_wait_for_update_needed_for_pipe = dcn10_set_wait_for_update_needed_for_pipe,
|
||||
};
|
||||
|
||||
void dcn31_hw_sequencer_construct(struct dc *dc)
|
||||
|
|
|
|||
|
|
@ -154,6 +154,8 @@ static const struct hwseq_private_funcs dcn314_private_funcs = {
|
|||
.setup_hpo_hw_control = dcn31_setup_hpo_hw_control,
|
||||
.calculate_dccg_k1_k2_values = dcn314_calculate_dccg_k1_k2_values,
|
||||
.resync_fifo_dccg_dio = dcn314_resync_fifo_dccg_dio,
|
||||
.wait_for_pipe_update_if_needed = dcn10_wait_for_pipe_update_if_needed,
|
||||
.set_wait_for_update_needed_for_pipe = dcn10_set_wait_for_update_needed_for_pipe,
|
||||
};
|
||||
|
||||
void dcn314_hw_sequencer_construct(struct dc *dc)
|
||||
|
|
|
|||
|
|
@ -163,6 +163,8 @@ static const struct hwseq_private_funcs dcn32_private_funcs = {
|
|||
.is_dp_dig_pixel_rate_div_policy = dcn32_is_dp_dig_pixel_rate_div_policy,
|
||||
.apply_single_controller_ctx_to_hw = dce110_apply_single_controller_ctx_to_hw,
|
||||
.reset_back_end_for_pipe = dcn20_reset_back_end_for_pipe,
|
||||
.wait_for_pipe_update_if_needed = dcn10_wait_for_pipe_update_if_needed,
|
||||
.set_wait_for_update_needed_for_pipe = dcn10_set_wait_for_update_needed_for_pipe,
|
||||
};
|
||||
|
||||
void dcn32_hw_sequencer_init_functions(struct dc *dc)
|
||||
|
|
|
|||
|
|
@ -167,6 +167,8 @@ static const struct hwseq_private_funcs dcn401_private_funcs = {
|
|||
.perform_3dlut_wa_unlock = dcn401_perform_3dlut_wa_unlock,
|
||||
.program_pipe_sequence = dcn401_program_pipe_sequence,
|
||||
.dc_ip_request_cntl = dcn401_dc_ip_request_cntl,
|
||||
.wait_for_pipe_update_if_needed = dcn10_wait_for_pipe_update_if_needed,
|
||||
.set_wait_for_update_needed_for_pipe = dcn10_set_wait_for_update_needed_for_pipe,
|
||||
};
|
||||
|
||||
void dcn401_hw_sequencer_init_functions(struct dc *dc)
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ struct optc {
|
|||
int pstate_keepout;
|
||||
struct dc_crtc_timing orginal_patched_timing;
|
||||
enum signal_type signal;
|
||||
uint32_t max_frame_count;
|
||||
};
|
||||
|
||||
void optc1_read_otg_state(struct timing_generator *optc, struct dcn_otg_state *s);
|
||||
|
|
|
|||
|
|
@ -621,7 +621,6 @@ void dcn35_timing_generator_init(struct optc *optc1)
|
|||
optc1->min_v_blank_interlace = 5;
|
||||
optc1->min_h_sync_width = 4;
|
||||
optc1->min_v_sync_width = 1;
|
||||
optc1->max_frame_count = 0xFFFFFF;
|
||||
|
||||
dcn35_timing_generator_set_fgcg(
|
||||
optc1, CTX->dc->debug.enable_fine_grain_clock_gating.bits.optc);
|
||||
|
|
|
|||
|
|
@ -283,9 +283,7 @@ void dcn42_timing_generator_init(struct optc *optc1)
|
|||
optc1->min_v_blank_interlace = 5;
|
||||
optc1->min_h_sync_width = 4;
|
||||
optc1->min_v_sync_width = 1;
|
||||
optc1->max_frame_count = 0xFFFFFF;
|
||||
|
||||
dcn35_timing_generator_set_fgcg(
|
||||
optc1, CTX->dc->debug.enable_fine_grain_clock_gating.bits.optc);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user