*/
#define DSU_PMU_IDX_CYCLE_COUNTER 31
-/* All event counters are 32bit, with a 64bit Cycle counter */
-#define DSU_PMU_COUNTER_WIDTH(idx) \
- (((idx) == DSU_PMU_IDX_CYCLE_COUNTER) ? 64 : 32)
-
-#define DSU_PMU_COUNTER_MASK(idx) \
- GENMASK_ULL((DSU_PMU_COUNTER_WIDTH((idx)) - 1), 0)
-
#define DSU_EXT_ATTR(_name, _func, _config) \
(&((struct dev_ext_attribute[]) { \
{ \
* @num_counters : Number of event counters implemented by the PMU,
* excluding the cycle counter.
* @irq : Interrupt line for counter overflow.
+ * @has_32b_pmevcntr : Are the non-cycle counters only 32-bit?
* @cpmceid_bitmap : Bitmap for the availability of architected common
* events (event_code < 0x40).
*/
struct hlist_node cpuhp_node;
s8 num_counters;
int irq;
+ bool has_32b_pmevcntr;
DECLARE_BITMAP(cpmceid_bitmap, DSU_PMU_MAX_COMMON_EVENTS);
};
raw_spin_unlock_irqrestore(&dsu_pmu->pmu_lock, flags);
}
+static u64 dsu_pmu_counter_mask(struct hw_perf_event *hw)
+{
+ return (hw->flags && hw->idx != DSU_PMU_IDX_CYCLE_COUNTER) ? U32_MAX : U64_MAX;
+}
+
static void dsu_pmu_event_update(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
new_count = dsu_pmu_read_counter(event);
} while (local64_cmpxchg(&hwc->prev_count, prev_count, new_count) !=
prev_count);
- delta = (new_count - prev_count) & DSU_PMU_COUNTER_MASK(hwc->idx);
+ delta = (new_count - prev_count) & dsu_pmu_counter_mask(hwc);
local64_add(delta, &event->count);
}
*/
static void dsu_pmu_set_event_period(struct perf_event *event)
{
- int idx = event->hw.idx;
- u64 val = DSU_PMU_COUNTER_MASK(idx) >> 1;
+ u64 val = dsu_pmu_counter_mask(&event->hw) >> 1;
local64_set(&event->hw.prev_count, val);
dsu_pmu_write_counter(event, val);
return -EINVAL;
event->hw.config_base = event->attr.config;
+ event->hw.flags = dsu_pmu->has_32b_pmevcntr;
return 0;
}
cpmceid[1] = __dsu_pmu_read_pmceid(1);
bitmap_from_arr32(dsu_pmu->cpmceid_bitmap, cpmceid,
DSU_PMU_MAX_COMMON_EVENTS);
+ /* Newer DSUs have 64-bit counters */
+ __dsu_pmu_write_counter(0, U64_MAX);
+ if (__dsu_pmu_read_counter(0) != U64_MAX)
+ dsu_pmu->has_32b_pmevcntr = true;
}
static void dsu_pmu_set_active_cpu(int cpu, struct dsu_pmu *dsu_pmu)