drm/amd/display: Do not enable replay when vtotal update is pending.
[ Upstream commit bd00b29b5f236dce677089319176dee5872b5a7a ] [Why&How] Vtotal is not applied to HW when handling vsync interrupt. Make sure vtotal is aligned before enable replay. Reviewed-by: Anthony Koo <anthony.koo@amd.com> Reviewed-by: Robin Chen <robin.chen@amd.com> Signed-off-by: Danny Wang <danny.wang@amd.com> Signed-off-by: Zhongwei Zhang <Zhongwei.Zhang@amd.com> Signed-off-by: Tom Chung <chiahsuan.chung@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Stable-dep-of: 874697e12793 ("drm/amd/display: Defer BW-optimization-blocked DRR adjustments") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
892f054b3f
commit
839b2350b8
@@ -452,6 +452,7 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
||||
|
||||
if (dc->caps.max_v_total != 0 &&
|
||||
(adjust->v_total_max > dc->caps.max_v_total || adjust->v_total_min > dc->caps.max_v_total)) {
|
||||
stream->adjust.timing_adjust_pending = false;
|
||||
if (adjust->allow_otg_v_count_halt)
|
||||
return set_long_vtotal(dc, stream, adjust);
|
||||
else
|
||||
@@ -465,7 +466,7 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
||||
dc->hwss.set_drr(&pipe,
|
||||
1,
|
||||
*adjust);
|
||||
|
||||
stream->adjust.timing_adjust_pending = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2975,8 +2976,12 @@ static void copy_stream_update_to_stream(struct dc *dc,
|
||||
if (update->vrr_active_fixed)
|
||||
stream->vrr_active_fixed = *update->vrr_active_fixed;
|
||||
|
||||
if (update->crtc_timing_adjust)
|
||||
if (update->crtc_timing_adjust) {
|
||||
if (stream->adjust.v_total_min != update->crtc_timing_adjust->v_total_min ||
|
||||
stream->adjust.v_total_max != update->crtc_timing_adjust->v_total_max)
|
||||
stream->adjust.timing_adjust_pending = true;
|
||||
stream->adjust = *update->crtc_timing_adjust;
|
||||
}
|
||||
|
||||
if (update->dpms_off)
|
||||
stream->dpms_off = *update->dpms_off;
|
||||
|
||||
@@ -554,6 +554,21 @@ void set_p_state_switch_method(
|
||||
}
|
||||
}
|
||||
|
||||
void set_drr_and_clear_adjust_pending(
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct dc_stream_state *stream,
|
||||
struct drr_params *params)
|
||||
{
|
||||
/* params can be null.*/
|
||||
if (pipe_ctx && pipe_ctx->stream_res.tg &&
|
||||
pipe_ctx->stream_res.tg->funcs->set_drr)
|
||||
pipe_ctx->stream_res.tg->funcs->set_drr(
|
||||
pipe_ctx->stream_res.tg, params);
|
||||
|
||||
if (stream)
|
||||
stream->adjust.timing_adjust_pending = false;
|
||||
}
|
||||
|
||||
void get_fams2_visual_confirm_color(
|
||||
struct dc *dc,
|
||||
struct dc_state *context,
|
||||
|
||||
@@ -1000,6 +1000,7 @@ struct dc_crtc_timing_adjust {
|
||||
uint32_t v_total_mid;
|
||||
uint32_t v_total_mid_frame_num;
|
||||
uint32_t allow_otg_v_count_halt;
|
||||
uint8_t timing_adjust_pending;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1653,9 +1653,7 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw(
|
||||
|
||||
params.vertical_total_min = stream->adjust.v_total_min;
|
||||
params.vertical_total_max = stream->adjust.v_total_max;
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_drr)
|
||||
pipe_ctx->stream_res.tg->funcs->set_drr(
|
||||
pipe_ctx->stream_res.tg, ¶ms);
|
||||
set_drr_and_clear_adjust_pending(pipe_ctx, stream, ¶ms);
|
||||
|
||||
// DRR should set trigger event to monitor surface update event
|
||||
if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0)
|
||||
@@ -2103,8 +2101,7 @@ static void set_drr(struct pipe_ctx **pipe_ctx,
|
||||
struct timing_generator *tg = pipe_ctx[i]->stream_res.tg;
|
||||
|
||||
if ((tg != NULL) && tg->funcs) {
|
||||
if (tg->funcs->set_drr)
|
||||
tg->funcs->set_drr(tg, ¶ms);
|
||||
set_drr_and_clear_adjust_pending(pipe_ctx[i], pipe_ctx[i]->stream, ¶ms);
|
||||
if (adjust.v_total_max != 0 && adjust.v_total_min != 0)
|
||||
if (tg->funcs->set_static_screen_control)
|
||||
tg->funcs->set_static_screen_control(
|
||||
|
||||
@@ -1112,9 +1112,7 @@ static void dcn10_reset_back_end_for_pipe(
|
||||
pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
|
||||
|
||||
pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_drr)
|
||||
pipe_ctx->stream_res.tg->funcs->set_drr(
|
||||
pipe_ctx->stream_res.tg, NULL);
|
||||
set_drr_and_clear_adjust_pending(pipe_ctx, pipe_ctx->stream, NULL);
|
||||
if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal))
|
||||
pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0;
|
||||
}
|
||||
@@ -3217,8 +3215,7 @@ void dcn10_set_drr(struct pipe_ctx **pipe_ctx,
|
||||
struct timing_generator *tg = pipe_ctx[i]->stream_res.tg;
|
||||
|
||||
if ((tg != NULL) && tg->funcs) {
|
||||
if (tg->funcs->set_drr)
|
||||
tg->funcs->set_drr(tg, ¶ms);
|
||||
set_drr_and_clear_adjust_pending(pipe_ctx[i], pipe_ctx[i]->stream, ¶ms);
|
||||
if (adjust.v_total_max != 0 && adjust.v_total_min != 0)
|
||||
if (tg->funcs->set_static_screen_control)
|
||||
tg->funcs->set_static_screen_control(
|
||||
|
||||
@@ -952,9 +952,7 @@ enum dc_status dcn20_enable_stream_timing(
|
||||
params.vertical_total_max = stream->adjust.v_total_max;
|
||||
params.vertical_total_mid = stream->adjust.v_total_mid;
|
||||
params.vertical_total_mid_frame_num = stream->adjust.v_total_mid_frame_num;
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_drr)
|
||||
pipe_ctx->stream_res.tg->funcs->set_drr(
|
||||
pipe_ctx->stream_res.tg, ¶ms);
|
||||
set_drr_and_clear_adjust_pending(pipe_ctx, stream, ¶ms);
|
||||
|
||||
// DRR should set trigger event to monitor surface update event
|
||||
if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0)
|
||||
@@ -2822,9 +2820,7 @@ void dcn20_reset_back_end_for_pipe(
|
||||
pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
|
||||
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
|
||||
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_drr)
|
||||
pipe_ctx->stream_res.tg->funcs->set_drr(
|
||||
pipe_ctx->stream_res.tg, NULL);
|
||||
set_drr_and_clear_adjust_pending(pipe_ctx, pipe_ctx->stream, NULL);
|
||||
/* TODO - convert symclk_ref_cnts for otg to a bit map to solve
|
||||
* the case where the same symclk is shared across multiple otg
|
||||
* instances
|
||||
|
||||
@@ -528,9 +528,7 @@ static void dcn31_reset_back_end_for_pipe(
|
||||
if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal))
|
||||
pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0;
|
||||
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_drr)
|
||||
pipe_ctx->stream_res.tg->funcs->set_drr(
|
||||
pipe_ctx->stream_res.tg, NULL);
|
||||
set_drr_and_clear_adjust_pending(pipe_ctx, pipe_ctx->stream, NULL);
|
||||
|
||||
link = pipe_ctx->stream->link;
|
||||
/* DPMS may already disable or */
|
||||
|
||||
@@ -1452,8 +1452,7 @@ void dcn35_set_drr(struct pipe_ctx **pipe_ctx,
|
||||
num_frames = 2 * (frame_rate % 60);
|
||||
}
|
||||
}
|
||||
if (tg->funcs->set_drr)
|
||||
tg->funcs->set_drr(tg, ¶ms);
|
||||
set_drr_and_clear_adjust_pending(pipe_ctx[i], pipe_ctx[i]->stream, ¶ms);
|
||||
if (adjust.v_total_max != 0 && adjust.v_total_min != 0)
|
||||
if (tg->funcs->set_static_screen_control)
|
||||
tg->funcs->set_static_screen_control(
|
||||
|
||||
@@ -902,10 +902,7 @@ enum dc_status dcn401_enable_stream_timing(
|
||||
}
|
||||
|
||||
hws->funcs.wait_for_blank_complete(pipe_ctx->stream_res.opp);
|
||||
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_drr)
|
||||
pipe_ctx->stream_res.tg->funcs->set_drr(
|
||||
pipe_ctx->stream_res.tg, ¶ms);
|
||||
set_drr_and_clear_adjust_pending(pipe_ctx, stream, ¶ms);
|
||||
|
||||
/* Event triggers and num frames initialized for DRR, but can be
|
||||
* later updated for PSR use. Note DRR trigger events are generated
|
||||
@@ -1835,9 +1832,8 @@ void dcn401_reset_back_end_for_pipe(
|
||||
pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
|
||||
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
|
||||
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_drr)
|
||||
pipe_ctx->stream_res.tg->funcs->set_drr(
|
||||
pipe_ctx->stream_res.tg, NULL);
|
||||
set_drr_and_clear_adjust_pending(pipe_ctx, pipe_ctx->stream, NULL);
|
||||
|
||||
/* TODO - convert symclk_ref_cnts for otg to a bit map to solve
|
||||
* the case where the same symclk is shared across multiple otg
|
||||
* instances
|
||||
|
||||
@@ -46,6 +46,7 @@ struct dce_hwseq;
|
||||
struct link_resource;
|
||||
struct dc_dmub_cmd;
|
||||
struct pg_block_update;
|
||||
struct drr_params;
|
||||
|
||||
struct subvp_pipe_control_lock_fast_params {
|
||||
struct dc *dc;
|
||||
@@ -509,6 +510,11 @@ void set_p_state_switch_method(
|
||||
struct dc_state *context,
|
||||
struct pipe_ctx *pipe_ctx);
|
||||
|
||||
void set_drr_and_clear_adjust_pending(
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct dc_stream_state *stream,
|
||||
struct drr_params *params);
|
||||
|
||||
void hwss_execute_sequence(struct dc *dc,
|
||||
struct block_sequence block_sequence[],
|
||||
int num_steps);
|
||||
|
||||
Reference in New Issue
Block a user