From: Wenjing Liu <[email protected]> [Why] Peak bandwidth samples could intermittently report invalid counter values because completion and stale stop events were not isolated. The default measurement window also made completion less likely within the available sampling period.
[How] Clear indirect counter state while masking stop output, use one counter as the sole measurement completion source, and shorten the default measurement window to 5000 events. Reviewed-by: Alvin Lee <[email protected]> Signed-off-by: Wenjing Liu <[email protected]> Signed-off-by: Chenyu Chen <[email protected]> --- .../display/dc/hubbub/dcn60/dcn60_hubbub.c | 44 ++++++++++++------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.c index 0169ffcd9343..c89c8ff42185 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.c @@ -742,9 +742,19 @@ static void hubbub60_wm_read_state(struct hubbub *hubbub, static void hubbub60_perfmon_reset(struct hubbub *hubbub) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); + unsigned int counter; REG_WRITE(DC_PERFMON5_PERFMON_CNTL, 0); REG_WRITE(DC_PERFMON5_PERFMON_CNTL2, 0); + + for (counter = 0; counter < 8; counter++) { + REG_SET_2(DC_PERFMON5_PERFCOUNTER_CNTL, 0, + PERFCOUNTER_CNTL_SEL, counter, + PERFCOUNTER_OFF_MASK, 0x1); + REG_SET(DC_PERFMON5_PERFCOUNTER_CNTL2, 0, + PERFCOUNTER_CNTL2_SEL, counter); + } + REG_WRITE(DC_PERFMON5_PERFCOUNTER_STATE, 0); REG_WRITE(DC_PERFMON5_PERFMON_CVALUE_INT_MISC, 0xFF00); REG_WRITE(DC_PERFMON5_PERFMON_CVALUE_LOW, 0); @@ -1381,7 +1391,7 @@ static uint32_t hubbub60_perfmon_get_urgent_ramp_latency_ns( * Counter 1: data counter — tracks total data received during the measurement * period. * Counter 2: target-reached generator — duplicates counter 1's event/target - * and generates the interrupt that stops counters 1 and 4. + * and generates the counter-off event that stops counters 1 and 4. * Counter 4: duration timer — measures elapsed time in refclk cycles. * * UTM_FILTER_SEL is set to 0 so that isolation comes from OTG-vblank gating @@ -1396,7 +1406,7 @@ static uint32_t hubbub60_perfmon_get_urgent_ramp_latency_ns( * windbg (ed dcn60_debug_peak_bw_ramp_size / ed dcn60_debug_peak_bw_window_size). */ static unsigned int dcn60_debug_peak_bw_ramp_size = 0x100; -static unsigned int dcn60_debug_peak_bw_window_size = 0x2500; +static unsigned int dcn60_debug_peak_bw_window_size = 5000; /* Minimum count4 (refclk ticks) for a peak-BW sample to be trusted. */ #define DCN60_OUT_OF_ORDER_BW_MIN_DURATION_TICKS 20 @@ -1419,7 +1429,7 @@ static void hubbub60_perfmon_arm_measuring_out_of_order_bandwidth( UTM_FILTER_SEL, 0x0); /* Program counter 0 as the count off counter */ - REG_SET_8(DC_PERFMON5_PERFCOUNTER_CNTL, 0, + REG_SET_9(DC_PERFMON5_PERFCOUNTER_CNTL, 0, PERFCOUNTER_CNTL_SEL, 0x0, // select counter 0 PERFCOUNTER_EVENT_SEL, 259, // response vld PERFCOUNTER_CVALUE_SEL, 0x1, // use cvalue bits 15-0 @@ -1427,7 +1437,8 @@ static void hubbub60_perfmon_arm_measuring_out_of_order_bandwidth( PERFCOUNTER_HW_CNTL_SEL, 0x0, // simutaneous mode PERFCOUNTER_RUNEN_MODE, 0x0, // counter runs as long as run_enable is high PERFCOUNTER_RESTART_EN, 0x0, // stop after counting is done - PERFCOUNTER_ACTIVE, 1); + PERFCOUNTER_OFF_MASK, 0x1, // do not generate pmon_counter_off_out + PERFCOUNTER_ACTIVE, 0x1); REG_SET_4(DC_PERFMON5_PERFCOUNTER_CNTL2, 0, PERFCOUNTER_CNTL2_SEL, 0x0, // select counter 0 PERFCOUNTER_COUNTED_VALUE_TYPE, 0x0, // count the accumulated value @@ -1436,7 +1447,7 @@ static void hubbub60_perfmon_arm_measuring_out_of_order_bandwidth( /* Program counter 1 as a passive data accumulator, slaved to the same * external stop signal as counter 4 (generated by counter 2 below). */ - REG_SET_9(DC_PERFMON5_PERFCOUNTER_CNTL, 0, + REG_SET_10(DC_PERFMON5_PERFCOUNTER_CNTL, 0, PERFCOUNTER_CNTL_SEL, 0x1, // select counter 1 PERFCOUNTER_EVENT_SEL, 259, // response vld PERFCOUNTER_CVALUE_SEL, 0x2, // use cvalue bits 31-16 @@ -1444,7 +1455,8 @@ static void hubbub60_perfmon_arm_measuring_out_of_order_bandwidth( PERFCOUNTER_HW_CNTL_SEL, 0x1, // independent mode PERFCOUNTER_RUNEN_MODE, 0x0, // counter runs as long as run_enable is high PERFCOUNTER_RESTART_EN, 0x0, // stop after counting is done - PERFCOUNTER_INT_EN, 0, // counter 2 now generates the interrupt + PERFCOUNTER_INT_EN, 0, // counter 2 is the completion source + PERFCOUNTER_OFF_MASK, 0x1, // do not generate pmon_counter_off_out PERFCOUNTER_ACTIVE, 0x1); REG_SET_5(DC_PERFMON5_PERFCOUNTER_CNTL2, 0, PERFCOUNTER_CNTL2_SEL, 0x1, @@ -1454,9 +1466,9 @@ static void hubbub60_perfmon_arm_measuring_out_of_order_bandwidth( PERFCOUNTER_HW_STOP2_SEL, 0x1); // stop via the same external signal as counter 4 /* Counter 2 is a dedicated "target reached" generator: it duplicates - * counter 1's event/target and is the sole source of the completion - * interrupt driving PERFMON_RUN_ENABLE_STOP_SEL. */ - REG_SET_9(DC_PERFMON5_PERFCOUNTER_CNTL, 0, + * counter 1's event/target and is the sole source of the counter-off + * event driving PERFMON_RUN_ENABLE_STOP_SEL. */ + REG_SET_10(DC_PERFMON5_PERFCOUNTER_CNTL, 0, PERFCOUNTER_CNTL_SEL, 0x2, // select counter 2 PERFCOUNTER_EVENT_SEL, 259, // response vld PERFCOUNTER_CVALUE_SEL, 0x2, // use cvalue bits 31-16 (same window target as counter 1) @@ -1464,7 +1476,8 @@ static void hubbub60_perfmon_arm_measuring_out_of_order_bandwidth( PERFCOUNTER_HW_CNTL_SEL, 0x1, // independent mode PERFCOUNTER_RUNEN_MODE, 0x0, // counter runs as long as run_enable is high PERFCOUNTER_RESTART_EN, 0x0, // stop after counting is done - PERFCOUNTER_INT_EN, 1, // signal when the measurement is complete + PERFCOUNTER_INT_EN, 0, // counter-off is the completion source + PERFCOUNTER_OFF_MASK, 0x0, // generate pmon_counter_off_out at CVALUE PERFCOUNTER_ACTIVE, 0x1); REG_SET_5(DC_PERFMON5_PERFCOUNTER_CNTL2, 0, PERFCOUNTER_CNTL2_SEL, 0x2, @@ -1474,7 +1487,7 @@ static void hubbub60_perfmon_arm_measuring_out_of_order_bandwidth( PERFCOUNTER_HW_STOP2_SEL, 0x0); // the stop trigger is that perfcounter meet the target CVALUE /* Program counter 4 to count the measuring time */ - REG_SET_8(DC_PERFMON5_PERFCOUNTER_CNTL, 0, + REG_SET_9(DC_PERFMON5_PERFCOUNTER_CNTL, 0, PERFCOUNTER_CNTL_SEL, 0x4, // select counter 4 PERFCOUNTER_EVENT_SEL, 19, // always 1 event PERFCOUNTER_CVALUE_SEL, 0x0, // ignored @@ -1482,6 +1495,7 @@ static void hubbub60_perfmon_arm_measuring_out_of_order_bandwidth( PERFCOUNTER_HW_CNTL_SEL, 0x1, // independent mode PERFCOUNTER_RUNEN_MODE, 0x0, // counter runs as long as run_enable is high PERFCOUNTER_RESTART_EN, 0x0, // stop after counting is done + PERFCOUNTER_OFF_MASK, 0x1, // do not generate pmon_counter_off_out PERFCOUNTER_ACTIVE, 1); REG_SET_5(DC_PERFMON5_PERFCOUNTER_CNTL2, 0, PERFCOUNTER_CNTL2_SEL, 0x4, // select counter 4 @@ -1509,7 +1523,7 @@ static void hubbub60_perfmon_arm_measuring_out_of_order_bandwidth( REG_SET_2(DC_PERFMON5_PERFMON_CNTL2, 0, PERFMON_RUN_ENABLE_START_SEL, 0x0, - PERFMON_RUN_ENABLE_STOP_SEL, 11); // perfmon counter off event + PERFMON_RUN_ENABLE_STOP_SEL, 10); // stop on counter-off event } /** @@ -1517,9 +1531,9 @@ static void hubbub60_perfmon_arm_measuring_out_of_order_bandwidth( * @hubbub: pointer to the hubbub hardware instance * * Enables the performance monitor counters previously configured by - * hubbub60_perfmon_arm_measuring_out_of_order_bandwidth(). The counter - * self-stops once the count-off counter reaches its target; there is no - * explicit stop step for the peak-BW path. + * hubbub60_perfmon_arm_measuring_out_of_order_bandwidth(). Counter 2 stops + * the measurement once it reaches its target; there is no explicit stop + * step for the peak-BW path. */ static void hubbub60_perfmon_start_measuring_out_of_order_bandwidth( struct hubbub *hubbub) -- 2.43.0
