Skip to content

Commit e7031d8

Browse files
Nicholas Kazlauskasalexdeucher
authored andcommitted
drm/amd/display: Add pstate verification and recovery for DCN31
[Why] To debug when p-state is being blocked and avoid PMFW hangs when it does occur. [How] Re-use the DCN10 hardware sequencer by adding a new interface for verifying p-state high on the hubbub. The interface is mostly the same as the DCN10 interface, but the bit definitions have changed for the debug bus. Signed-off-by: Nicholas Kazlauskas <[email protected]> Reviewed-by: Eric Yang <[email protected]> Reviewed-by: Harry Wentland <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 65722ff commit e7031d8

File tree

7 files changed

+73
-4
lines changed

7 files changed

+73
-4
lines changed

drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,7 @@ static const struct hubbub_funcs hubbub1_funcs = {
940940
.program_watermarks = hubbub1_program_watermarks,
941941
.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
942942
.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
943+
.verify_allow_pstate_change_high = hubbub1_verify_allow_pstate_change_high,
943944
};
944945

945946
void hubbub1_construct(struct hubbub *hubbub,

drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,9 +1112,13 @@ static bool dcn10_hw_wa_force_recovery(struct dc *dc)
11121112

11131113
void dcn10_verify_allow_pstate_change_high(struct dc *dc)
11141114
{
1115+
struct hubbub *hubbub = dc->res_pool->hubbub;
11151116
static bool should_log_hw_state; /* prevent hw state log by default */
11161117

1117-
if (!hubbub1_verify_allow_pstate_change_high(dc->res_pool->hubbub)) {
1118+
if (!hubbub->funcs->verify_allow_pstate_change_high)
1119+
return;
1120+
1121+
if (!hubbub->funcs->verify_allow_pstate_change_high(hubbub)) {
11181122
int i = 0;
11191123

11201124
if (should_log_hw_state)
@@ -1123,8 +1127,8 @@ void dcn10_verify_allow_pstate_change_high(struct dc *dc)
11231127
TRACE_DC_PIPE_STATE(pipe_ctx, i, MAX_PIPES);
11241128
BREAK_TO_DEBUGGER();
11251129
if (dcn10_hw_wa_force_recovery(dc)) {
1126-
/*check again*/
1127-
if (!hubbub1_verify_allow_pstate_change_high(dc->res_pool->hubbub))
1130+
/*check again*/
1131+
if (!hubbub->funcs->verify_allow_pstate_change_high(hubbub))
11281132
BREAK_TO_DEBUGGER();
11291133
}
11301134
}

drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ static const struct hubbub_funcs hubbub30_funcs = {
448448
.program_watermarks = hubbub3_program_watermarks,
449449
.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
450450
.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
451+
.verify_allow_pstate_change_high = hubbub1_verify_allow_pstate_change_high,
451452
.force_wm_propagate_to_pipes = hubbub3_force_wm_propagate_to_pipes,
452453
.force_pstate_change_control = hubbub3_force_pstate_change_control,
453454
.init_watermarks = hubbub3_init_watermarks,

drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hubbub.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ static const struct hubbub_funcs hubbub301_funcs = {
6060
.program_watermarks = hubbub3_program_watermarks,
6161
.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
6262
.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
63+
.verify_allow_pstate_change_high = hubbub1_verify_allow_pstate_change_high,
6364
.force_wm_propagate_to_pipes = hubbub3_force_wm_propagate_to_pipes,
6465
.force_pstate_change_control = hubbub3_force_pstate_change_control,
6566
.hubbub_read_state = hubbub2_read_state,

drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,65 @@ static void hubbub31_get_dchub_ref_freq(struct hubbub *hubbub,
949949
}
950950
}
951951

952+
static bool hubbub31_verify_allow_pstate_change_high(struct hubbub *hubbub)
953+
{
954+
struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
955+
956+
/*
957+
* Pstate latency is ~20us so if we wait over 40us and pstate allow
958+
* still not asserted, we are probably stuck and going to hang
959+
*/
960+
const unsigned int pstate_wait_timeout_us = 100;
961+
const unsigned int pstate_wait_expected_timeout_us = 40;
962+
963+
static unsigned int max_sampled_pstate_wait_us; /* data collection */
964+
static bool forced_pstate_allow; /* help with revert wa */
965+
966+
unsigned int debug_data = 0;
967+
unsigned int i;
968+
969+
if (forced_pstate_allow) {
970+
/* we hacked to force pstate allow to prevent hang last time
971+
* we verify_allow_pstate_change_high. so disable force
972+
* here so we can check status
973+
*/
974+
REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
975+
DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0,
976+
DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 0);
977+
forced_pstate_allow = false;
978+
}
979+
980+
REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, hubbub2->debug_test_index_pstate);
981+
982+
for (i = 0; i < pstate_wait_timeout_us; i++) {
983+
debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA);
984+
985+
/* Debug bit is specific to ASIC. */
986+
if (debug_data & (1 << 26)) {
987+
if (i > pstate_wait_expected_timeout_us)
988+
DC_LOG_WARNING("pstate took longer than expected ~%dus\n", i);
989+
return true;
990+
}
991+
if (max_sampled_pstate_wait_us < i)
992+
max_sampled_pstate_wait_us = i;
993+
994+
udelay(1);
995+
}
996+
997+
/* force pstate allow to prevent system hang
998+
* and break to debugger to investigate
999+
*/
1000+
REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
1001+
DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 1,
1002+
DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1);
1003+
forced_pstate_allow = true;
1004+
1005+
DC_LOG_WARNING("pstate TEST_DEBUG_DATA: 0x%X\n",
1006+
debug_data);
1007+
1008+
return false;
1009+
}
1010+
9521011
static const struct hubbub_funcs hubbub31_funcs = {
9531012
.update_dchub = hubbub2_update_dchub,
9541013
.init_dchub_sys_ctx = hubbub31_init_dchub_sys_ctx,
@@ -961,6 +1020,7 @@ static const struct hubbub_funcs hubbub31_funcs = {
9611020
.program_watermarks = hubbub31_program_watermarks,
9621021
.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
9631022
.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
1023+
.verify_allow_pstate_change_high = hubbub31_verify_allow_pstate_change_high,
9641024
.program_det_size = dcn31_program_det_size,
9651025
.program_compbuf_size = dcn31_program_compbuf_size,
9661026
.init_crb = dcn31_init_crb,

drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1011,7 +1011,7 @@ static const struct dc_debug_options debug_defaults_drv = {
10111011
.max_downscale_src_width = 4096,/*upto true 4K*/
10121012
.disable_pplib_wm_range = false,
10131013
.scl_reset_length10 = true,
1014-
.sanity_checks = false,
1014+
.sanity_checks = true,
10151015
.underflow_assert_delay_us = 0xFFFFFFFF,
10161016
.dwb_fi_phase = -1, // -1 = disable,
10171017
.dmub_command_table = true,

drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ struct hubbub_funcs {
154154
bool (*is_allow_self_refresh_enabled)(struct hubbub *hubbub);
155155
void (*allow_self_refresh_control)(struct hubbub *hubbub, bool allow);
156156

157+
bool (*verify_allow_pstate_change_high)(struct hubbub *hubbub);
158+
157159
void (*apply_DEDCN21_147_wa)(struct hubbub *hubbub);
158160

159161
void (*force_wm_propagate_to_pipes)(struct hubbub *hubbub);

0 commit comments

Comments
 (0)