mirror of https://gitee.com/openkylin/linux.git
drm/amd/display: Add Underflow Asserts to dc
[Why] For debugging underflow issues it can be useful to have asserts when the underflow initially occurs. [How] Read the underflow status registers after actions that have a high risk of causing underflow and assert that no underflow occurred. If underflow occurred, clear the bit. Signed-off-by: Thomas Lim <Thomas.Lim@amd.com> Reviewed-by: Eric Yang <eric.yang2@amd.com> Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
bda9afdacf
commit
1a7d296d16
|
@ -346,6 +346,7 @@ struct dc_debug_options {
|
|||
int sr_exit_time_ns;
|
||||
int sr_enter_plus_exit_time_ns;
|
||||
int urgent_latency_ns;
|
||||
uint32_t underflow_assert_delay_us;
|
||||
int percent_of_ideal_drambw;
|
||||
int dram_clock_change_latency_ns;
|
||||
bool optimized_watermark;
|
||||
|
|
|
@ -421,6 +421,23 @@ void dcn10_log_hw_state(struct dc *dc,
|
|||
DTN_INFO_END();
|
||||
}
|
||||
|
||||
bool dcn10_did_underflow_occur(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct hubp *hubp = pipe_ctx->plane_res.hubp;
|
||||
struct timing_generator *tg = pipe_ctx->stream_res.tg;
|
||||
|
||||
if (tg->funcs->is_optc_underflow_occurred(tg)) {
|
||||
tg->funcs->clear_optc_underflow(tg);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hubp->funcs->hubp_get_underflow_status(hubp)) {
|
||||
hubp->funcs->hubp_clear_underflow(hubp);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void enable_power_gating_plane(
|
||||
struct dce_hwseq *hws,
|
||||
bool enable)
|
||||
|
@ -2398,6 +2415,7 @@ static void dcn10_apply_ctx_for_surface(
|
|||
{
|
||||
int i;
|
||||
struct timing_generator *tg;
|
||||
uint32_t underflow_check_delay_us;
|
||||
bool removed_pipe[4] = { false };
|
||||
bool interdependent_update = false;
|
||||
struct pipe_ctx *top_pipe_to_program =
|
||||
|
@ -2412,11 +2430,22 @@ static void dcn10_apply_ctx_for_surface(
|
|||
interdependent_update = top_pipe_to_program->plane_state &&
|
||||
top_pipe_to_program->plane_state->update_flags.bits.full_update;
|
||||
|
||||
underflow_check_delay_us = dc->debug.underflow_assert_delay_us;
|
||||
|
||||
if (underflow_check_delay_us != 0xFFFFFFFF && dc->hwss.did_underflow_occur)
|
||||
ASSERT(dc->hwss.did_underflow_occur(dc, top_pipe_to_program));
|
||||
|
||||
if (interdependent_update)
|
||||
lock_all_pipes(dc, context, true);
|
||||
else
|
||||
dcn10_pipe_control_lock(dc, top_pipe_to_program, true);
|
||||
|
||||
if (underflow_check_delay_us != 0xFFFFFFFF)
|
||||
udelay(underflow_check_delay_us);
|
||||
|
||||
if (underflow_check_delay_us != 0xFFFFFFFF && dc->hwss.did_underflow_occur)
|
||||
ASSERT(dc->hwss.did_underflow_occur(dc, top_pipe_to_program));
|
||||
|
||||
if (num_planes == 0) {
|
||||
/* OTG blank before remove all front end */
|
||||
dc->hwss.blank_pixel_data(dc, top_pipe_to_program, true);
|
||||
|
@ -3093,7 +3122,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
|
|||
.disable_stream_gating = NULL,
|
||||
.enable_stream_gating = NULL,
|
||||
.setup_periodic_interrupt = dcn10_setup_periodic_interrupt,
|
||||
.setup_vupdate_interrupt = dcn10_setup_vupdate_interrupt
|
||||
.setup_vupdate_interrupt = dcn10_setup_vupdate_interrupt,
|
||||
.did_underflow_occur = dcn10_did_underflow_occur
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -71,6 +71,8 @@ void dcn10_get_hdr_visual_confirm_color(
|
|||
struct pipe_ctx *pipe_ctx,
|
||||
struct tg_color *color);
|
||||
|
||||
bool dcn10_did_underflow_occur(struct dc *dc, struct pipe_ctx *pipe_ctx);
|
||||
|
||||
void update_dchubp_dpp(
|
||||
struct dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
|
|
|
@ -560,6 +560,7 @@ static const struct dc_debug_options debug_defaults_drv = {
|
|||
.az_endpoint_mute_only = true,
|
||||
.recovery_enabled = false, /*enable this by default after testing.*/
|
||||
.max_downscale_src_width = 3840,
|
||||
.underflow_assert_delay_us = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
static const struct dc_debug_options debug_defaults_diags = {
|
||||
|
@ -569,7 +570,8 @@ static const struct dc_debug_options debug_defaults_diags = {
|
|||
.clock_trace = true,
|
||||
.disable_stutter = true,
|
||||
.disable_pplib_clock_request = true,
|
||||
.disable_pplib_wm_range = true
|
||||
.disable_pplib_wm_range = true,
|
||||
.underflow_assert_delay_us = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
static void dcn10_dpp_destroy(struct dpp **dpp)
|
||||
|
|
|
@ -2003,4 +2003,5 @@ void dcn20_hw_sequencer_construct(struct dc *dc)
|
|||
dc->hwss.reset_hw_ctx_wrap = dcn20_reset_hw_ctx_wrap;
|
||||
dc->hwss.update_mpcc = dcn20_update_mpcc;
|
||||
dc->hwss.set_flip_control_gsl = dcn20_set_flip_control_gsl;
|
||||
dc->hwss.did_underflow_occur = dcn10_did_underflow_occur;
|
||||
}
|
||||
|
|
|
@ -710,6 +710,7 @@ static const struct dc_debug_options debug_defaults_drv = {
|
|||
.scl_reset_length10 = true,
|
||||
.sanity_checks = false,
|
||||
.disable_tri_buf = true,
|
||||
.underflow_assert_delay_us = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
static const struct dc_debug_options debug_defaults_diags = {
|
||||
|
@ -724,6 +725,7 @@ static const struct dc_debug_options debug_defaults_diags = {
|
|||
.disable_pplib_wm_range = true,
|
||||
.disable_stutter = true,
|
||||
.scl_reset_length10 = true,
|
||||
.underflow_assert_delay_us = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
void dcn20_dpp_destroy(struct dpp **dpp)
|
||||
|
|
|
@ -277,6 +277,7 @@ struct hw_sequencer_funcs {
|
|||
|
||||
void (*setup_periodic_interrupt)(struct pipe_ctx *pipe_ctx, enum vline_select vline);
|
||||
void (*setup_vupdate_interrupt)(struct pipe_ctx *pipe_ctx);
|
||||
bool (*did_underflow_occur)(struct dc *dc, struct pipe_ctx *pipe_ctx);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
|
||||
void (*update_odm)(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx);
|
||||
|
|
Loading…
Reference in New Issue