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

Reply via email to