6666 */
6767#define DSU_PMU_IDX_CYCLE_COUNTER 31
6868
69- /* All event counters are 32bit, with a 64bit Cycle counter */
70- #define DSU_PMU_COUNTER_WIDTH (idx ) \
71- (((idx) == DSU_PMU_IDX_CYCLE_COUNTER) ? 64 : 32)
72-
73- #define DSU_PMU_COUNTER_MASK (idx ) \
74- GENMASK_ULL((DSU_PMU_COUNTER_WIDTH((idx)) - 1), 0)
75-
7669#define DSU_EXT_ATTR (_name , _func , _config ) \
7770 (&((struct dev_ext_attribute[]) { \
7871 { \
@@ -107,6 +100,8 @@ struct dsu_hw_events {
107100 * @num_counters : Number of event counters implemented by the PMU,
108101 * excluding the cycle counter.
109102 * @irq : Interrupt line for counter overflow.
103+ * @has_32b_pmevcntr : Are the non-cycle counters only 32-bit?
104+ * @has_pmccntr : Do we even have a dedicated cycle counter?
110105 * @cpmceid_bitmap : Bitmap for the availability of architected common
111106 * events (event_code < 0x40).
112107 */
@@ -120,6 +115,8 @@ struct dsu_pmu {
120115 struct hlist_node cpuhp_node ;
121116 s8 num_counters ;
122117 int irq ;
118+ bool has_32b_pmevcntr ;
119+ bool has_pmccntr ;
123120 DECLARE_BITMAP (cpmceid_bitmap , DSU_PMU_MAX_COMMON_EVENTS );
124121};
125122
@@ -286,10 +283,9 @@ static int dsu_pmu_get_event_idx(struct dsu_hw_events *hw_events,
286283 struct dsu_pmu * dsu_pmu = to_dsu_pmu (event -> pmu );
287284 unsigned long * used_mask = hw_events -> used_mask ;
288285
289- if (evtype == DSU_PMU_EVT_CYCLES ) {
290- if (test_and_set_bit (DSU_PMU_IDX_CYCLE_COUNTER , used_mask ))
291- return - EAGAIN ;
292- return DSU_PMU_IDX_CYCLE_COUNTER ;
286+ if (evtype == DSU_PMU_EVT_CYCLES && dsu_pmu -> has_pmccntr ) {
287+ if (!test_and_set_bit (DSU_PMU_IDX_CYCLE_COUNTER , used_mask ))
288+ return DSU_PMU_IDX_CYCLE_COUNTER ;
293289 }
294290
295291 idx = find_first_zero_bit (used_mask , dsu_pmu -> num_counters );
@@ -328,6 +324,11 @@ static inline void dsu_pmu_set_event(struct dsu_pmu *dsu_pmu,
328324 raw_spin_unlock_irqrestore (& dsu_pmu -> pmu_lock , flags );
329325}
330326
327+ static u64 dsu_pmu_counter_mask (struct hw_perf_event * hw )
328+ {
329+ return (hw -> flags && hw -> idx != DSU_PMU_IDX_CYCLE_COUNTER ) ? U32_MAX : U64_MAX ;
330+ }
331+
331332static void dsu_pmu_event_update (struct perf_event * event )
332333{
333334 struct hw_perf_event * hwc = & event -> hw ;
@@ -339,7 +340,7 @@ static void dsu_pmu_event_update(struct perf_event *event)
339340 new_count = dsu_pmu_read_counter (event );
340341 } while (local64_cmpxchg (& hwc -> prev_count , prev_count , new_count ) !=
341342 prev_count );
342- delta = (new_count - prev_count ) & DSU_PMU_COUNTER_MASK (hwc -> idx );
343+ delta = (new_count - prev_count ) & dsu_pmu_counter_mask (hwc );
343344 local64_add (delta , & event -> count );
344345}
345346
@@ -362,8 +363,7 @@ static inline u32 dsu_pmu_get_reset_overflow(void)
362363 */
363364static void dsu_pmu_set_event_period (struct perf_event * event )
364365{
365- int idx = event -> hw .idx ;
366- u64 val = DSU_PMU_COUNTER_MASK (idx ) >> 1 ;
366+ u64 val = dsu_pmu_counter_mask (& event -> hw ) >> 1 ;
367367
368368 local64_set (& event -> hw .prev_count , val );
369369 dsu_pmu_write_counter (event , val );
@@ -564,6 +564,7 @@ static int dsu_pmu_event_init(struct perf_event *event)
564564 return - EINVAL ;
565565
566566 event -> hw .config_base = event -> attr .config ;
567+ event -> hw .flags = dsu_pmu -> has_32b_pmevcntr ;
567568 return 0 ;
568569}
569570
@@ -664,6 +665,14 @@ static void dsu_pmu_probe_pmu(struct dsu_pmu *dsu_pmu)
664665 cpmceid [1 ] = __dsu_pmu_read_pmceid (1 );
665666 bitmap_from_arr32 (dsu_pmu -> cpmceid_bitmap , cpmceid ,
666667 DSU_PMU_MAX_COMMON_EVENTS );
668+ /* Newer DSUs have 64-bit counters */
669+ __dsu_pmu_write_counter (0 , U64_MAX );
670+ if (__dsu_pmu_read_counter (0 ) != U64_MAX )
671+ dsu_pmu -> has_32b_pmevcntr = true;
672+ /* On even newer DSUs, PMCCNTR is RAZ/WI */
673+ __dsu_pmu_write_pmccntr (U64_MAX );
674+ if (__dsu_pmu_read_pmccntr () == U64_MAX )
675+ dsu_pmu -> has_pmccntr = true;
667676}
668677
669678static void dsu_pmu_set_active_cpu (int cpu , struct dsu_pmu * dsu_pmu )
0 commit comments