Skip to content

Commit 85c0dbd

Browse files
rmurphy-armwilldeacon
authored andcommitted
perf/arm_dsu: Support DSU-120
DSU-120 has the same system register interface as previous DSUs, but no longer offers a dedicated cycle counter. While this is not directly discoverable via PMCR, the PMCCNTR register is still defined to exist with RAZ/WI behaviour, allowing for a straightforward heuristic. Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Will Deacon <will@kernel.org>
1 parent 0113aff commit 85c0dbd

1 file changed

Lines changed: 7 additions & 1 deletion

File tree

drivers/perf/arm_dsu_pmu.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ struct dsu_hw_events {
101101
* excluding the cycle counter.
102102
* @irq : Interrupt line for counter overflow.
103103
* @has_32b_pmevcntr : Are the non-cycle counters only 32-bit?
104+
* @has_pmccntr : Do we even have a dedicated cycle counter?
104105
* @cpmceid_bitmap : Bitmap for the availability of architected common
105106
* events (event_code < 0x40).
106107
*/
@@ -115,6 +116,7 @@ struct dsu_pmu {
115116
s8 num_counters;
116117
int irq;
117118
bool has_32b_pmevcntr;
119+
bool has_pmccntr;
118120
DECLARE_BITMAP(cpmceid_bitmap, DSU_PMU_MAX_COMMON_EVENTS);
119121
};
120122

@@ -281,7 +283,7 @@ static int dsu_pmu_get_event_idx(struct dsu_hw_events *hw_events,
281283
struct dsu_pmu *dsu_pmu = to_dsu_pmu(event->pmu);
282284
unsigned long *used_mask = hw_events->used_mask;
283285

284-
if (evtype == DSU_PMU_EVT_CYCLES) {
286+
if (evtype == DSU_PMU_EVT_CYCLES && dsu_pmu->has_pmccntr) {
285287
if (test_and_set_bit(DSU_PMU_IDX_CYCLE_COUNTER, used_mask))
286288
return -EAGAIN;
287289
return DSU_PMU_IDX_CYCLE_COUNTER;
@@ -668,6 +670,10 @@ static void dsu_pmu_probe_pmu(struct dsu_pmu *dsu_pmu)
668670
__dsu_pmu_write_counter(0, U64_MAX);
669671
if (__dsu_pmu_read_counter(0) != U64_MAX)
670672
dsu_pmu->has_32b_pmevcntr = true;
673+
/* On even newer DSUs, PMCCNTR is RAZ/WI */
674+
__dsu_pmu_write_pmccntr(U64_MAX);
675+
if (__dsu_pmu_read_pmccntr() == U64_MAX)
676+
dsu_pmu->has_pmccntr = true;
671677
}
672678

673679
static void dsu_pmu_set_active_cpu(int cpu, struct dsu_pmu *dsu_pmu)

0 commit comments

Comments
 (0)