mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-27 15:05:03 +07:00
drm/amd/display: Add some hardware status in DTN log debugfs
[Why] For debug purpose, we need to check the following hardware status in DTN log debugfs: 1.dpp & hubp clock enable; 2.crtc blank enable; 3.link phy status; [How] Add the upper information in the amdgpu_dm_dtn_log debugfs. For CRTC blanked status, since DCN2 and greater reports it on the OPP instead of OTG, we patch it in after calling optc1_read_otg_states. Ideally, this should be done in the DCN version specific function hooks. It has been left as a TODO item. Signed-off-by: Leo (Hanghong) Ma <hanghong.ma@amd.com> Reviewed-by: Mikita Lipski <Mikita.Lipski@amd.com> Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> Acked-by: Harry Wentland <Harry.Wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
eb7d81af3c
commit
ae8cf9774e
@ -1014,6 +1014,9 @@ void hubp1_read_state_common(struct hubp *hubp)
|
|||||||
HUBP_TTU_DISABLE, &s->ttu_disable,
|
HUBP_TTU_DISABLE, &s->ttu_disable,
|
||||||
HUBP_UNDERFLOW_STATUS, &s->underflow_status);
|
HUBP_UNDERFLOW_STATUS, &s->underflow_status);
|
||||||
|
|
||||||
|
REG_GET(HUBP_CLK_CNTL,
|
||||||
|
HUBP_CLOCK_ENABLE, &s->clock_en);
|
||||||
|
|
||||||
REG_GET(DCN_GLOBAL_TTU_CNTL,
|
REG_GET(DCN_GLOBAL_TTU_CNTL,
|
||||||
MIN_TTU_VBLANK, &s->min_ttu_vblank);
|
MIN_TTU_VBLANK, &s->min_ttu_vblank);
|
||||||
|
|
||||||
|
@ -670,6 +670,7 @@ struct dcn_hubp_state {
|
|||||||
uint32_t sw_mode;
|
uint32_t sw_mode;
|
||||||
uint32_t dcc_en;
|
uint32_t dcc_en;
|
||||||
uint32_t blank_en;
|
uint32_t blank_en;
|
||||||
|
uint32_t clock_en;
|
||||||
uint32_t underflow_status;
|
uint32_t underflow_status;
|
||||||
uint32_t ttu_disable;
|
uint32_t ttu_disable;
|
||||||
uint32_t min_ttu_vblank;
|
uint32_t min_ttu_vblank;
|
||||||
|
@ -129,9 +129,8 @@ static void dcn10_log_hubp_states(struct dc *dc, void *log_ctx)
|
|||||||
struct resource_pool *pool = dc->res_pool;
|
struct resource_pool *pool = dc->res_pool;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DTN_INFO("HUBP: format addr_hi width height"
|
DTN_INFO(
|
||||||
" rot mir sw_mode dcc_en blank_en ttu_dis underflow"
|
"HUBP: format addr_hi width height rot mir sw_mode dcc_en blank_en clock_en ttu_dis underflow min_ttu_vblank qos_low_wm qos_high_wm\n");
|
||||||
" min_ttu_vblank qos_low_wm qos_high_wm\n");
|
|
||||||
for (i = 0; i < pool->pipe_count; i++) {
|
for (i = 0; i < pool->pipe_count; i++) {
|
||||||
struct hubp *hubp = pool->hubps[i];
|
struct hubp *hubp = pool->hubps[i];
|
||||||
struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state);
|
struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state);
|
||||||
@ -139,8 +138,7 @@ static void dcn10_log_hubp_states(struct dc *dc, void *log_ctx)
|
|||||||
hubp->funcs->hubp_read_state(hubp);
|
hubp->funcs->hubp_read_state(hubp);
|
||||||
|
|
||||||
if (!s->blank_en) {
|
if (!s->blank_en) {
|
||||||
DTN_INFO("[%2d]: %5xh %6xh %5d %6d %2xh %2xh %6xh"
|
DTN_INFO("[%2d]: %5xh %6xh %5d %6d %2xh %2xh %6xh %6d %8d %8d %7d %8xh",
|
||||||
" %6d %8d %7d %8xh",
|
|
||||||
hubp->inst,
|
hubp->inst,
|
||||||
s->pixel_format,
|
s->pixel_format,
|
||||||
s->inuse_addr_hi,
|
s->inuse_addr_hi,
|
||||||
@ -151,6 +149,7 @@ static void dcn10_log_hubp_states(struct dc *dc, void *log_ctx)
|
|||||||
s->sw_mode,
|
s->sw_mode,
|
||||||
s->dcc_en,
|
s->dcc_en,
|
||||||
s->blank_en,
|
s->blank_en,
|
||||||
|
s->clock_en,
|
||||||
s->ttu_disable,
|
s->ttu_disable,
|
||||||
s->underflow_status);
|
s->underflow_status);
|
||||||
DTN_INFO_MICRO_SEC(s->min_ttu_vblank);
|
DTN_INFO_MICRO_SEC(s->min_ttu_vblank);
|
||||||
@ -308,21 +307,35 @@ void dcn10_log_hw_state(struct dc *dc,
|
|||||||
}
|
}
|
||||||
DTN_INFO("\n");
|
DTN_INFO("\n");
|
||||||
|
|
||||||
DTN_INFO("OTG: v_bs v_be v_ss v_se vpol vmax vmin vmax_sel vmin_sel"
|
DTN_INFO("OTG: v_bs v_be v_ss v_se vpol vmax vmin vmax_sel vmin_sel h_bs h_be h_ss h_se hpol htot vtot underflow blank_en\n");
|
||||||
" h_bs h_be h_ss h_se hpol htot vtot underflow\n");
|
|
||||||
|
|
||||||
for (i = 0; i < pool->timing_generator_count; i++) {
|
for (i = 0; i < pool->timing_generator_count; i++) {
|
||||||
struct timing_generator *tg = pool->timing_generators[i];
|
struct timing_generator *tg = pool->timing_generators[i];
|
||||||
struct dcn_otg_state s = {0};
|
struct dcn_otg_state s = {0};
|
||||||
|
/* Read shared OTG state registers for all DCNx */
|
||||||
optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s);
|
optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s);
|
||||||
|
|
||||||
|
#ifdef CONFIG_DRM_AMD_DC_DCN2_0
|
||||||
|
/*
|
||||||
|
* For DCN2 and greater, a register on the OPP is used to
|
||||||
|
* determine if the CRTC is blanked instead of the OTG. So use
|
||||||
|
* dpg_is_blanked() if exists, otherwise fallback on otg.
|
||||||
|
*
|
||||||
|
* TODO: Implement DCN-specific read_otg_state hooks.
|
||||||
|
*/
|
||||||
|
if (pool->opps[i]->funcs->dpg_is_blanked)
|
||||||
|
s.blank_enabled = pool->opps[i]->funcs->dpg_is_blanked(pool->opps[i]);
|
||||||
|
else
|
||||||
|
s.blank_enabled = tg->funcs->is_blanked(tg);
|
||||||
|
#else
|
||||||
|
s.blank_enabled = tg->funcs->is_blanked(tg);
|
||||||
|
#endif
|
||||||
|
|
||||||
//only print if OTG master is enabled
|
//only print if OTG master is enabled
|
||||||
if ((s.otg_enabled & 1) == 0)
|
if ((s.otg_enabled & 1) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
DTN_INFO("[%d]: %5d %5d %5d %5d %5d %5d %5d %9d %9d %5d %5d %5d"
|
DTN_INFO("[%d]: %5d %5d %5d %5d %5d %5d %5d %9d %9d %5d %5d %5d %5d %5d %5d %5d %9d %8d\n",
|
||||||
" %5d %5d %5d %5d %9d\n",
|
|
||||||
tg->inst,
|
tg->inst,
|
||||||
s.v_blank_start,
|
s.v_blank_start,
|
||||||
s.v_blank_end,
|
s.v_blank_end,
|
||||||
@ -340,7 +353,8 @@ void dcn10_log_hw_state(struct dc *dc,
|
|||||||
s.h_sync_a_pol,
|
s.h_sync_a_pol,
|
||||||
s.h_total,
|
s.h_total,
|
||||||
s.v_total,
|
s.v_total,
|
||||||
s.underflow_occurred_status);
|
s.underflow_occurred_status,
|
||||||
|
s.blank_enabled);
|
||||||
|
|
||||||
// Clear underflow for debug purposes
|
// Clear underflow for debug purposes
|
||||||
// We want to keep underflow sticky bit on for the longevity tests outside of test environment.
|
// We want to keep underflow sticky bit on for the longevity tests outside of test environment.
|
||||||
@ -387,7 +401,7 @@ void dcn10_log_hw_state(struct dc *dc,
|
|||||||
}
|
}
|
||||||
DTN_INFO("\n");
|
DTN_INFO("\n");
|
||||||
|
|
||||||
DTN_INFO("L_ENC: DPHY_FEC_EN DPHY_FEC_READY_SHADOW DPHY_FEC_ACTIVE_STATUS\n");
|
DTN_INFO("L_ENC: DPHY_FEC_EN DPHY_FEC_READY_SHADOW DPHY_FEC_ACTIVE_STATUS DP_LINK_TRAINING_COMPLETE\n");
|
||||||
for (i = 0; i < dc->link_count; i++) {
|
for (i = 0; i < dc->link_count; i++) {
|
||||||
struct link_encoder *lenc = dc->links[i]->link_enc;
|
struct link_encoder *lenc = dc->links[i]->link_enc;
|
||||||
|
|
||||||
@ -395,11 +409,12 @@ void dcn10_log_hw_state(struct dc *dc,
|
|||||||
|
|
||||||
if (lenc->funcs->read_state) {
|
if (lenc->funcs->read_state) {
|
||||||
lenc->funcs->read_state(lenc, &s);
|
lenc->funcs->read_state(lenc, &s);
|
||||||
DTN_INFO("[%-3d]: %-12d %-22d %-22d\n",
|
DTN_INFO("[%-3d]: %-12d %-22d %-22d %-25d\n",
|
||||||
i,
|
i,
|
||||||
s.dphy_fec_en,
|
s.dphy_fec_en,
|
||||||
s.dphy_fec_ready_shadow,
|
s.dphy_fec_ready_shadow,
|
||||||
s.dphy_fec_active_status);
|
s.dphy_fec_active_status,
|
||||||
|
s.dp_link_training_complete);
|
||||||
DTN_INFO("\n");
|
DTN_INFO("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -406,6 +406,7 @@ static const struct opp_funcs dcn10_opp_funcs = {
|
|||||||
.opp_pipe_clock_control = opp1_pipe_clock_control,
|
.opp_pipe_clock_control = opp1_pipe_clock_control,
|
||||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
|
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
|
||||||
.opp_set_disp_pattern_generator = NULL,
|
.opp_set_disp_pattern_generator = NULL,
|
||||||
|
.dpg_is_blanked = NULL,
|
||||||
#endif
|
#endif
|
||||||
.opp_destroy = opp1_destroy
|
.opp_destroy = opp1_destroy
|
||||||
};
|
};
|
||||||
|
@ -542,6 +542,7 @@ struct dcn_otg_state {
|
|||||||
uint32_t h_total;
|
uint32_t h_total;
|
||||||
uint32_t underflow_occurred_status;
|
uint32_t underflow_occurred_status;
|
||||||
uint32_t otg_enabled;
|
uint32_t otg_enabled;
|
||||||
|
uint32_t blank_enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
void optc1_read_otg_state(struct optc *optc1,
|
void optc1_read_otg_state(struct optc *optc1,
|
||||||
|
@ -203,6 +203,7 @@ void link_enc2_read_state(struct link_encoder *enc, struct link_enc_state *s)
|
|||||||
REG_GET(DP_DPHY_CNTL, DPHY_FEC_EN, &s->dphy_fec_en);
|
REG_GET(DP_DPHY_CNTL, DPHY_FEC_EN, &s->dphy_fec_en);
|
||||||
REG_GET(DP_DPHY_CNTL, DPHY_FEC_READY_SHADOW, &s->dphy_fec_ready_shadow);
|
REG_GET(DP_DPHY_CNTL, DPHY_FEC_READY_SHADOW, &s->dphy_fec_ready_shadow);
|
||||||
REG_GET(DP_DPHY_CNTL, DPHY_FEC_ACTIVE_STATUS, &s->dphy_fec_active_status);
|
REG_GET(DP_DPHY_CNTL, DPHY_FEC_ACTIVE_STATUS, &s->dphy_fec_active_status);
|
||||||
|
REG_GET(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, &s->dp_link_training_complete);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -124,6 +124,7 @@ struct link_enc_state {
|
|||||||
uint32_t dphy_fec_en;
|
uint32_t dphy_fec_en;
|
||||||
uint32_t dphy_fec_ready_shadow;
|
uint32_t dphy_fec_ready_shadow;
|
||||||
uint32_t dphy_fec_active_status;
|
uint32_t dphy_fec_active_status;
|
||||||
|
uint32_t dp_link_training_complete;
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user