2 * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code.
4 * ARMv7 support: Jean Pihet <jpihet@mvista.com>
5 * 2010 (c) MontaVista Software, LLC.
7 * Copied from ARMv6 code, with the low level code inspired
8 * by the ARMv7 Oprofile code.
10 * Cortex-A8 has up to 4 configurable performance counters and
11 * a single cycle counter.
12 * Cortex-A9 has up to 31 configurable performance counters and
13 * a single cycle counter.
15 * All counters can be enabled/disabled and IRQ masked separately. The cycle
16 * counter and all 4 performance counters together can be reset separately.
22 #include <asm/cputype.h>
23 #include <asm/irq_regs.h>
25 #include "../vfp/vfpinstr.h"
28 #include <linux/perf/arm_pmu.h>
29 #include <linux/platform_device.h>
32 * Common ARMv7 event types
34 * Note: An implementation may not be able to count all of these events
35 * but the encodings are considered to be `reserved' in the case that
36 * they are not available.
38 enum armv7_perf_types
{
39 ARMV7_PERFCTR_PMNC_SW_INCR
= 0x00,
40 ARMV7_PERFCTR_L1_ICACHE_REFILL
= 0x01,
41 ARMV7_PERFCTR_ITLB_REFILL
= 0x02,
42 ARMV7_PERFCTR_L1_DCACHE_REFILL
= 0x03,
43 ARMV7_PERFCTR_L1_DCACHE_ACCESS
= 0x04,
44 ARMV7_PERFCTR_DTLB_REFILL
= 0x05,
45 ARMV7_PERFCTR_MEM_READ
= 0x06,
46 ARMV7_PERFCTR_MEM_WRITE
= 0x07,
47 ARMV7_PERFCTR_INSTR_EXECUTED
= 0x08,
48 ARMV7_PERFCTR_EXC_TAKEN
= 0x09,
49 ARMV7_PERFCTR_EXC_EXECUTED
= 0x0A,
50 ARMV7_PERFCTR_CID_WRITE
= 0x0B,
53 * ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
55 * - all (taken) branch instructions,
56 * - instructions that explicitly write the PC,
57 * - exception generating instructions.
59 ARMV7_PERFCTR_PC_WRITE
= 0x0C,
60 ARMV7_PERFCTR_PC_IMM_BRANCH
= 0x0D,
61 ARMV7_PERFCTR_PC_PROC_RETURN
= 0x0E,
62 ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS
= 0x0F,
63 ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
= 0x10,
64 ARMV7_PERFCTR_CLOCK_CYCLES
= 0x11,
65 ARMV7_PERFCTR_PC_BRANCH_PRED
= 0x12,
67 /* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
68 ARMV7_PERFCTR_MEM_ACCESS
= 0x13,
69 ARMV7_PERFCTR_L1_ICACHE_ACCESS
= 0x14,
70 ARMV7_PERFCTR_L1_DCACHE_WB
= 0x15,
71 ARMV7_PERFCTR_L2_CACHE_ACCESS
= 0x16,
72 ARMV7_PERFCTR_L2_CACHE_REFILL
= 0x17,
73 ARMV7_PERFCTR_L2_CACHE_WB
= 0x18,
74 ARMV7_PERFCTR_BUS_ACCESS
= 0x19,
75 ARMV7_PERFCTR_MEM_ERROR
= 0x1A,
76 ARMV7_PERFCTR_INSTR_SPEC
= 0x1B,
77 ARMV7_PERFCTR_TTBR_WRITE
= 0x1C,
78 ARMV7_PERFCTR_BUS_CYCLES
= 0x1D,
80 ARMV7_PERFCTR_CPU_CYCLES
= 0xFF
83 /* ARMv7 Cortex-A8 specific event types */
84 enum armv7_a8_perf_types
{
85 ARMV7_A8_PERFCTR_L2_CACHE_ACCESS
= 0x43,
86 ARMV7_A8_PERFCTR_L2_CACHE_REFILL
= 0x44,
87 ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS
= 0x50,
88 ARMV7_A8_PERFCTR_STALL_ISIDE
= 0x56,
91 /* ARMv7 Cortex-A9 specific event types */
92 enum armv7_a9_perf_types
{
93 ARMV7_A9_PERFCTR_INSTR_CORE_RENAME
= 0x68,
94 ARMV7_A9_PERFCTR_STALL_ICACHE
= 0x60,
95 ARMV7_A9_PERFCTR_STALL_DISPATCH
= 0x66,
98 /* ARMv7 Cortex-A5 specific event types */
99 enum armv7_a5_perf_types
{
100 ARMV7_A5_PERFCTR_PREFETCH_LINEFILL
= 0xc2,
101 ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP
= 0xc3,
104 /* ARMv7 Cortex-A15 specific event types */
105 enum armv7_a15_perf_types
{
106 ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ
= 0x40,
107 ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE
= 0x41,
108 ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ
= 0x42,
109 ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE
= 0x43,
111 ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ
= 0x4C,
112 ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE
= 0x4D,
114 ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ
= 0x50,
115 ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE
= 0x51,
116 ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ
= 0x52,
117 ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE
= 0x53,
119 ARMV7_A15_PERFCTR_PC_WRITE_SPEC
= 0x76,
122 /* ARMv7 Cortex-A12 specific event types */
123 enum armv7_a12_perf_types
{
124 ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ
= 0x40,
125 ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE
= 0x41,
127 ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ
= 0x50,
128 ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE
= 0x51,
130 ARMV7_A12_PERFCTR_PC_WRITE_SPEC
= 0x76,
132 ARMV7_A12_PERFCTR_PF_TLB_REFILL
= 0xe7,
135 /* ARMv7 Krait specific event types */
136 enum krait_perf_types
{
137 KRAIT_PMRESR0_GROUP0
= 0xcc,
138 KRAIT_PMRESR1_GROUP0
= 0xd0,
139 KRAIT_PMRESR2_GROUP0
= 0xd4,
140 KRAIT_VPMRESR0_GROUP0
= 0xd8,
142 KRAIT_PERFCTR_L1_ICACHE_ACCESS
= 0x10011,
143 KRAIT_PERFCTR_L1_ICACHE_MISS
= 0x10010,
145 KRAIT_PERFCTR_L1_ITLB_ACCESS
= 0x12222,
146 KRAIT_PERFCTR_L1_DTLB_ACCESS
= 0x12210,
149 /* ARMv7 Scorpion specific event types */
150 enum scorpion_perf_types
{
151 SCORPION_LPM0_GROUP0
= 0x4c,
152 SCORPION_LPM1_GROUP0
= 0x50,
153 SCORPION_LPM2_GROUP0
= 0x54,
154 SCORPION_L2LPM_GROUP0
= 0x58,
155 SCORPION_VLPM_GROUP0
= 0x5c,
157 SCORPION_ICACHE_ACCESS
= 0x10053,
158 SCORPION_ICACHE_MISS
= 0x10052,
160 SCORPION_DTLB_ACCESS
= 0x12013,
161 SCORPION_DTLB_MISS
= 0x12012,
163 SCORPION_ITLB_MISS
= 0x12021,
167 * Cortex-A8 HW events mapping
169 * The hardware events that we support. We do support cache operations but
170 * we have harvard caches and no way to combine instruction and data
171 * accesses/misses in hardware.
173 static const unsigned armv7_a8_perf_map
[PERF_COUNT_HW_MAX
] = {
174 PERF_MAP_ALL_UNSUPPORTED
,
175 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
176 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_PERFCTR_INSTR_EXECUTED
,
177 [PERF_COUNT_HW_CACHE_REFERENCES
] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
178 [PERF_COUNT_HW_CACHE_MISSES
] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
179 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = ARMV7_PERFCTR_PC_WRITE
,
180 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
181 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
] = ARMV7_A8_PERFCTR_STALL_ISIDE
,
184 static const unsigned armv7_a8_perf_cache_map
[PERF_COUNT_HW_CACHE_MAX
]
185 [PERF_COUNT_HW_CACHE_OP_MAX
]
186 [PERF_COUNT_HW_CACHE_RESULT_MAX
] = {
187 PERF_CACHE_MAP_ALL_UNSUPPORTED
,
190 * The performance counters don't differentiate between read and write
191 * accesses/misses so this isn't strictly correct, but it's the best we
192 * can do. Writes and reads get combined.
194 [C(L1D
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
195 [C(L1D
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
196 [C(L1D
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
197 [C(L1D
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
199 [C(L1I
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS
,
200 [C(L1I
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_ICACHE_REFILL
,
202 [C(LL
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS
,
203 [C(LL
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL
,
204 [C(LL
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS
,
205 [C(LL
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL
,
207 [C(DTLB
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
208 [C(DTLB
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
210 [C(ITLB
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
211 [C(ITLB
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
213 [C(BPU
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
214 [C(BPU
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
215 [C(BPU
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
216 [C(BPU
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
220 * Cortex-A9 HW events mapping
222 static const unsigned armv7_a9_perf_map
[PERF_COUNT_HW_MAX
] = {
223 PERF_MAP_ALL_UNSUPPORTED
,
224 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
225 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_A9_PERFCTR_INSTR_CORE_RENAME
,
226 [PERF_COUNT_HW_CACHE_REFERENCES
] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
227 [PERF_COUNT_HW_CACHE_MISSES
] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
228 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = ARMV7_PERFCTR_PC_WRITE
,
229 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
230 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
] = ARMV7_A9_PERFCTR_STALL_ICACHE
,
231 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND
] = ARMV7_A9_PERFCTR_STALL_DISPATCH
,
234 static const unsigned armv7_a9_perf_cache_map
[PERF_COUNT_HW_CACHE_MAX
]
235 [PERF_COUNT_HW_CACHE_OP_MAX
]
236 [PERF_COUNT_HW_CACHE_RESULT_MAX
] = {
237 PERF_CACHE_MAP_ALL_UNSUPPORTED
,
240 * The performance counters don't differentiate between read and write
241 * accesses/misses so this isn't strictly correct, but it's the best we
242 * can do. Writes and reads get combined.
244 [C(L1D
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
245 [C(L1D
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
246 [C(L1D
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
247 [C(L1D
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
249 [C(L1I
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_ICACHE_REFILL
,
251 [C(DTLB
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
252 [C(DTLB
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
254 [C(ITLB
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
255 [C(ITLB
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
257 [C(BPU
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
258 [C(BPU
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
259 [C(BPU
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
260 [C(BPU
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
264 * Cortex-A5 HW events mapping
266 static const unsigned armv7_a5_perf_map
[PERF_COUNT_HW_MAX
] = {
267 PERF_MAP_ALL_UNSUPPORTED
,
268 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
269 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_PERFCTR_INSTR_EXECUTED
,
270 [PERF_COUNT_HW_CACHE_REFERENCES
] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
271 [PERF_COUNT_HW_CACHE_MISSES
] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
272 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = ARMV7_PERFCTR_PC_WRITE
,
273 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
276 static const unsigned armv7_a5_perf_cache_map
[PERF_COUNT_HW_CACHE_MAX
]
277 [PERF_COUNT_HW_CACHE_OP_MAX
]
278 [PERF_COUNT_HW_CACHE_RESULT_MAX
] = {
279 PERF_CACHE_MAP_ALL_UNSUPPORTED
,
281 [C(L1D
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
282 [C(L1D
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
283 [C(L1D
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
284 [C(L1D
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
285 [C(L1D
)][C(OP_PREFETCH
)][C(RESULT_ACCESS
)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL
,
286 [C(L1D
)][C(OP_PREFETCH
)][C(RESULT_MISS
)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP
,
288 [C(L1I
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS
,
289 [C(L1I
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_ICACHE_REFILL
,
291 * The prefetch counters don't differentiate between the I side and the
294 [C(L1I
)][C(OP_PREFETCH
)][C(RESULT_ACCESS
)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL
,
295 [C(L1I
)][C(OP_PREFETCH
)][C(RESULT_MISS
)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP
,
297 [C(DTLB
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
298 [C(DTLB
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
300 [C(ITLB
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
301 [C(ITLB
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
303 [C(BPU
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
304 [C(BPU
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
305 [C(BPU
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
306 [C(BPU
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
310 * Cortex-A15 HW events mapping
312 static const unsigned armv7_a15_perf_map
[PERF_COUNT_HW_MAX
] = {
313 PERF_MAP_ALL_UNSUPPORTED
,
314 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
315 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_PERFCTR_INSTR_EXECUTED
,
316 [PERF_COUNT_HW_CACHE_REFERENCES
] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
317 [PERF_COUNT_HW_CACHE_MISSES
] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
318 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = ARMV7_A15_PERFCTR_PC_WRITE_SPEC
,
319 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
320 [PERF_COUNT_HW_BUS_CYCLES
] = ARMV7_PERFCTR_BUS_CYCLES
,
323 static const unsigned armv7_a15_perf_cache_map
[PERF_COUNT_HW_CACHE_MAX
]
324 [PERF_COUNT_HW_CACHE_OP_MAX
]
325 [PERF_COUNT_HW_CACHE_RESULT_MAX
] = {
326 PERF_CACHE_MAP_ALL_UNSUPPORTED
,
328 [C(L1D
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ
,
329 [C(L1D
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ
,
330 [C(L1D
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE
,
331 [C(L1D
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE
,
334 * Not all performance counters differentiate between read and write
335 * accesses/misses so we're not always strictly correct, but it's the
336 * best we can do. Writes and reads get combined in these cases.
338 [C(L1I
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS
,
339 [C(L1I
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_ICACHE_REFILL
,
341 [C(LL
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ
,
342 [C(LL
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ
,
343 [C(LL
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE
,
344 [C(LL
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE
,
346 [C(DTLB
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ
,
347 [C(DTLB
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE
,
349 [C(ITLB
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
350 [C(ITLB
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
352 [C(BPU
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
353 [C(BPU
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
354 [C(BPU
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
355 [C(BPU
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
359 * Cortex-A7 HW events mapping
361 static const unsigned armv7_a7_perf_map
[PERF_COUNT_HW_MAX
] = {
362 PERF_MAP_ALL_UNSUPPORTED
,
363 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
364 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_PERFCTR_INSTR_EXECUTED
,
365 [PERF_COUNT_HW_CACHE_REFERENCES
] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
366 [PERF_COUNT_HW_CACHE_MISSES
] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
367 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = ARMV7_PERFCTR_PC_WRITE
,
368 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
369 [PERF_COUNT_HW_BUS_CYCLES
] = ARMV7_PERFCTR_BUS_CYCLES
,
372 static const unsigned armv7_a7_perf_cache_map
[PERF_COUNT_HW_CACHE_MAX
]
373 [PERF_COUNT_HW_CACHE_OP_MAX
]
374 [PERF_COUNT_HW_CACHE_RESULT_MAX
] = {
375 PERF_CACHE_MAP_ALL_UNSUPPORTED
,
378 * The performance counters don't differentiate between read and write
379 * accesses/misses so this isn't strictly correct, but it's the best we
380 * can do. Writes and reads get combined.
382 [C(L1D
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
383 [C(L1D
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
384 [C(L1D
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
385 [C(L1D
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
387 [C(L1I
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS
,
388 [C(L1I
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_ICACHE_REFILL
,
390 [C(LL
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L2_CACHE_ACCESS
,
391 [C(LL
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L2_CACHE_REFILL
,
392 [C(LL
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L2_CACHE_ACCESS
,
393 [C(LL
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L2_CACHE_REFILL
,
395 [C(DTLB
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
396 [C(DTLB
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
398 [C(ITLB
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
399 [C(ITLB
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
401 [C(BPU
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
402 [C(BPU
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
403 [C(BPU
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
404 [C(BPU
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
408 * Cortex-A12 HW events mapping
410 static const unsigned armv7_a12_perf_map
[PERF_COUNT_HW_MAX
] = {
411 PERF_MAP_ALL_UNSUPPORTED
,
412 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
413 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_PERFCTR_INSTR_EXECUTED
,
414 [PERF_COUNT_HW_CACHE_REFERENCES
] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
415 [PERF_COUNT_HW_CACHE_MISSES
] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
416 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = ARMV7_A12_PERFCTR_PC_WRITE_SPEC
,
417 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
418 [PERF_COUNT_HW_BUS_CYCLES
] = ARMV7_PERFCTR_BUS_CYCLES
,
421 static const unsigned armv7_a12_perf_cache_map
[PERF_COUNT_HW_CACHE_MAX
]
422 [PERF_COUNT_HW_CACHE_OP_MAX
]
423 [PERF_COUNT_HW_CACHE_RESULT_MAX
] = {
424 PERF_CACHE_MAP_ALL_UNSUPPORTED
,
426 [C(L1D
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ
,
427 [C(L1D
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
428 [C(L1D
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE
,
429 [C(L1D
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
432 * Not all performance counters differentiate between read and write
433 * accesses/misses so we're not always strictly correct, but it's the
434 * best we can do. Writes and reads get combined in these cases.
436 [C(L1I
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS
,
437 [C(L1I
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_ICACHE_REFILL
,
439 [C(LL
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ
,
440 [C(LL
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L2_CACHE_REFILL
,
441 [C(LL
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE
,
442 [C(LL
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L2_CACHE_REFILL
,
444 [C(DTLB
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
445 [C(DTLB
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
446 [C(DTLB
)][C(OP_PREFETCH
)][C(RESULT_MISS
)] = ARMV7_A12_PERFCTR_PF_TLB_REFILL
,
448 [C(ITLB
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
449 [C(ITLB
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
451 [C(BPU
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
452 [C(BPU
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
453 [C(BPU
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
454 [C(BPU
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
458 * Krait HW events mapping
460 static const unsigned krait_perf_map
[PERF_COUNT_HW_MAX
] = {
461 PERF_MAP_ALL_UNSUPPORTED
,
462 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
463 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_PERFCTR_INSTR_EXECUTED
,
464 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = ARMV7_PERFCTR_PC_WRITE
,
465 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
466 [PERF_COUNT_HW_BUS_CYCLES
] = ARMV7_PERFCTR_CLOCK_CYCLES
,
469 static const unsigned krait_perf_map_no_branch
[PERF_COUNT_HW_MAX
] = {
470 PERF_MAP_ALL_UNSUPPORTED
,
471 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
472 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_PERFCTR_INSTR_EXECUTED
,
473 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
474 [PERF_COUNT_HW_BUS_CYCLES
] = ARMV7_PERFCTR_CLOCK_CYCLES
,
477 static const unsigned krait_perf_cache_map
[PERF_COUNT_HW_CACHE_MAX
]
478 [PERF_COUNT_HW_CACHE_OP_MAX
]
479 [PERF_COUNT_HW_CACHE_RESULT_MAX
] = {
480 PERF_CACHE_MAP_ALL_UNSUPPORTED
,
483 * The performance counters don't differentiate between read and write
484 * accesses/misses so this isn't strictly correct, but it's the best we
485 * can do. Writes and reads get combined.
487 [C(L1D
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
488 [C(L1D
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
489 [C(L1D
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
490 [C(L1D
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
492 [C(L1I
)][C(OP_READ
)][C(RESULT_ACCESS
)] = KRAIT_PERFCTR_L1_ICACHE_ACCESS
,
493 [C(L1I
)][C(OP_READ
)][C(RESULT_MISS
)] = KRAIT_PERFCTR_L1_ICACHE_MISS
,
495 [C(DTLB
)][C(OP_READ
)][C(RESULT_ACCESS
)] = KRAIT_PERFCTR_L1_DTLB_ACCESS
,
496 [C(DTLB
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = KRAIT_PERFCTR_L1_DTLB_ACCESS
,
498 [C(ITLB
)][C(OP_READ
)][C(RESULT_ACCESS
)] = KRAIT_PERFCTR_L1_ITLB_ACCESS
,
499 [C(ITLB
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = KRAIT_PERFCTR_L1_ITLB_ACCESS
,
501 [C(BPU
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
502 [C(BPU
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
503 [C(BPU
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
504 [C(BPU
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
508 * Scorpion HW events mapping
510 static const unsigned scorpion_perf_map
[PERF_COUNT_HW_MAX
] = {
511 PERF_MAP_ALL_UNSUPPORTED
,
512 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
513 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_PERFCTR_INSTR_EXECUTED
,
514 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = ARMV7_PERFCTR_PC_WRITE
,
515 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
516 [PERF_COUNT_HW_BUS_CYCLES
] = ARMV7_PERFCTR_CLOCK_CYCLES
,
519 static const unsigned scorpion_perf_cache_map
[PERF_COUNT_HW_CACHE_MAX
]
520 [PERF_COUNT_HW_CACHE_OP_MAX
]
521 [PERF_COUNT_HW_CACHE_RESULT_MAX
] = {
522 PERF_CACHE_MAP_ALL_UNSUPPORTED
,
524 * The performance counters don't differentiate between read and write
525 * accesses/misses so this isn't strictly correct, but it's the best we
526 * can do. Writes and reads get combined.
528 [C(L1D
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
529 [C(L1D
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
530 [C(L1D
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
531 [C(L1D
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
532 [C(L1I
)][C(OP_READ
)][C(RESULT_ACCESS
)] = SCORPION_ICACHE_ACCESS
,
533 [C(L1I
)][C(OP_READ
)][C(RESULT_MISS
)] = SCORPION_ICACHE_MISS
,
535 * Only ITLB misses and DTLB refills are supported. If users want the
536 * DTLB refills misses a raw counter must be used.
538 [C(DTLB
)][C(OP_READ
)][C(RESULT_ACCESS
)] = SCORPION_DTLB_ACCESS
,
539 [C(DTLB
)][C(OP_READ
)][C(RESULT_MISS
)] = SCORPION_DTLB_MISS
,
540 [C(DTLB
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = SCORPION_DTLB_ACCESS
,
541 [C(DTLB
)][C(OP_WRITE
)][C(RESULT_MISS
)] = SCORPION_DTLB_MISS
,
542 [C(ITLB
)][C(OP_READ
)][C(RESULT_MISS
)] = SCORPION_ITLB_MISS
,
543 [C(ITLB
)][C(OP_WRITE
)][C(RESULT_MISS
)] = SCORPION_ITLB_MISS
,
544 [C(BPU
)][C(OP_READ
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
545 [C(BPU
)][C(OP_READ
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
546 [C(BPU
)][C(OP_WRITE
)][C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
547 [C(BPU
)][C(OP_WRITE
)][C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
551 * Perf Events' indices
553 #define ARMV7_IDX_CYCLE_COUNTER 0
554 #define ARMV7_IDX_COUNTER0 1
555 #define ARMV7_IDX_COUNTER_LAST(cpu_pmu) \
556 (ARMV7_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1)
558 #define ARMV7_MAX_COUNTERS 32
559 #define ARMV7_COUNTER_MASK (ARMV7_MAX_COUNTERS - 1)
562 * ARMv7 low level PMNC access
566 * Perf Event to low level counters mapping
568 #define ARMV7_IDX_TO_COUNTER(x) \
569 (((x) - ARMV7_IDX_COUNTER0) & ARMV7_COUNTER_MASK)
572 * Per-CPU PMNC: config reg
574 #define ARMV7_PMNC_E (1 << 0) /* Enable all counters */
575 #define ARMV7_PMNC_P (1 << 1) /* Reset all counters */
576 #define ARMV7_PMNC_C (1 << 2) /* Cycle counter reset */
577 #define ARMV7_PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
578 #define ARMV7_PMNC_X (1 << 4) /* Export to ETM */
579 #define ARMV7_PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
580 #define ARMV7_PMNC_N_SHIFT 11 /* Number of counters supported */
581 #define ARMV7_PMNC_N_MASK 0x1f
582 #define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */
585 * FLAG: counters overflow flag status reg
587 #define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */
588 #define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK
591 * PMXEVTYPER: Event selection reg
593 #define ARMV7_EVTYPE_MASK 0xc80000ff /* Mask for writable bits */
594 #define ARMV7_EVTYPE_EVENT 0xff /* Mask for EVENT bits */
597 * Event filters for PMUv2
599 #define ARMV7_EXCLUDE_PL1 (1 << 31)
600 #define ARMV7_EXCLUDE_USER (1 << 30)
601 #define ARMV7_INCLUDE_HYP (1 << 27)
603 static inline u32
armv7_pmnc_read(void)
606 asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val
));
610 static inline void armv7_pmnc_write(u32 val
)
612 val
&= ARMV7_PMNC_MASK
;
614 asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val
));
617 static inline int armv7_pmnc_has_overflowed(u32 pmnc
)
619 return pmnc
& ARMV7_OVERFLOWED_MASK
;
622 static inline int armv7_pmnc_counter_valid(struct arm_pmu
*cpu_pmu
, int idx
)
624 return idx
>= ARMV7_IDX_CYCLE_COUNTER
&&
625 idx
<= ARMV7_IDX_COUNTER_LAST(cpu_pmu
);
628 static inline int armv7_pmnc_counter_has_overflowed(u32 pmnc
, int idx
)
630 return pmnc
& BIT(ARMV7_IDX_TO_COUNTER(idx
));
633 static inline void armv7_pmnc_select_counter(int idx
)
635 u32 counter
= ARMV7_IDX_TO_COUNTER(idx
);
636 asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (counter
));
640 static inline u32
armv7pmu_read_counter(struct perf_event
*event
)
642 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
643 struct hw_perf_event
*hwc
= &event
->hw
;
647 if (!armv7_pmnc_counter_valid(cpu_pmu
, idx
)) {
648 pr_err("CPU%u reading wrong counter %d\n",
649 smp_processor_id(), idx
);
650 } else if (idx
== ARMV7_IDX_CYCLE_COUNTER
) {
651 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value
));
653 armv7_pmnc_select_counter(idx
);
654 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (value
));
660 static inline void armv7pmu_write_counter(struct perf_event
*event
, u32 value
)
662 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
663 struct hw_perf_event
*hwc
= &event
->hw
;
666 if (!armv7_pmnc_counter_valid(cpu_pmu
, idx
)) {
667 pr_err("CPU%u writing wrong counter %d\n",
668 smp_processor_id(), idx
);
669 } else if (idx
== ARMV7_IDX_CYCLE_COUNTER
) {
670 asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value
));
672 armv7_pmnc_select_counter(idx
);
673 asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (value
));
677 static inline void armv7_pmnc_write_evtsel(int idx
, u32 val
)
679 armv7_pmnc_select_counter(idx
);
680 val
&= ARMV7_EVTYPE_MASK
;
681 asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val
));
684 static inline void armv7_pmnc_enable_counter(int idx
)
686 u32 counter
= ARMV7_IDX_TO_COUNTER(idx
);
687 asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(counter
)));
690 static inline void armv7_pmnc_disable_counter(int idx
)
692 u32 counter
= ARMV7_IDX_TO_COUNTER(idx
);
693 asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(counter
)));
696 static inline void armv7_pmnc_enable_intens(int idx
)
698 u32 counter
= ARMV7_IDX_TO_COUNTER(idx
);
699 asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(counter
)));
702 static inline void armv7_pmnc_disable_intens(int idx
)
704 u32 counter
= ARMV7_IDX_TO_COUNTER(idx
);
705 asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(counter
)));
707 /* Clear the overflow flag in case an interrupt is pending. */
708 asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (BIT(counter
)));
712 static inline u32
armv7_pmnc_getreset_flags(void)
717 asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val
));
719 /* Write to clear flags */
720 val
&= ARMV7_FLAG_MASK
;
721 asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val
));
727 static void armv7_pmnc_dump_regs(struct arm_pmu
*cpu_pmu
)
732 pr_info("PMNC registers dump:\n");
734 asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val
));
735 pr_info("PMNC =0x%08x\n", val
);
737 asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val
));
738 pr_info("CNTENS=0x%08x\n", val
);
740 asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val
));
741 pr_info("INTENS=0x%08x\n", val
);
743 asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val
));
744 pr_info("FLAGS =0x%08x\n", val
);
746 asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val
));
747 pr_info("SELECT=0x%08x\n", val
);
749 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val
));
750 pr_info("CCNT =0x%08x\n", val
);
752 for (cnt
= ARMV7_IDX_COUNTER0
;
753 cnt
<= ARMV7_IDX_COUNTER_LAST(cpu_pmu
); cnt
++) {
754 armv7_pmnc_select_counter(cnt
);
755 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val
));
756 pr_info("CNT[%d] count =0x%08x\n",
757 ARMV7_IDX_TO_COUNTER(cnt
), val
);
758 asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val
));
759 pr_info("CNT[%d] evtsel=0x%08x\n",
760 ARMV7_IDX_TO_COUNTER(cnt
), val
);
765 static void armv7pmu_enable_event(struct perf_event
*event
)
768 struct hw_perf_event
*hwc
= &event
->hw
;
769 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
770 struct pmu_hw_events
*events
= this_cpu_ptr(cpu_pmu
->hw_events
);
773 if (!armv7_pmnc_counter_valid(cpu_pmu
, idx
)) {
774 pr_err("CPU%u enabling wrong PMNC counter IRQ enable %d\n",
775 smp_processor_id(), idx
);
780 * Enable counter and interrupt, and set the counter to count
781 * the event that we're interested in.
783 raw_spin_lock_irqsave(&events
->pmu_lock
, flags
);
788 armv7_pmnc_disable_counter(idx
);
791 * Set event (if destined for PMNx counters)
792 * We only need to set the event for the cycle counter if we
793 * have the ability to perform event filtering.
795 if (cpu_pmu
->set_event_filter
|| idx
!= ARMV7_IDX_CYCLE_COUNTER
)
796 armv7_pmnc_write_evtsel(idx
, hwc
->config_base
);
799 * Enable interrupt for this counter
801 armv7_pmnc_enable_intens(idx
);
806 armv7_pmnc_enable_counter(idx
);
808 raw_spin_unlock_irqrestore(&events
->pmu_lock
, flags
);
811 static void armv7pmu_disable_event(struct perf_event
*event
)
814 struct hw_perf_event
*hwc
= &event
->hw
;
815 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
816 struct pmu_hw_events
*events
= this_cpu_ptr(cpu_pmu
->hw_events
);
819 if (!armv7_pmnc_counter_valid(cpu_pmu
, idx
)) {
820 pr_err("CPU%u disabling wrong PMNC counter IRQ enable %d\n",
821 smp_processor_id(), idx
);
826 * Disable counter and interrupt
828 raw_spin_lock_irqsave(&events
->pmu_lock
, flags
);
833 armv7_pmnc_disable_counter(idx
);
836 * Disable interrupt for this counter
838 armv7_pmnc_disable_intens(idx
);
840 raw_spin_unlock_irqrestore(&events
->pmu_lock
, flags
);
843 static irqreturn_t
armv7pmu_handle_irq(int irq_num
, void *dev
)
846 struct perf_sample_data data
;
847 struct arm_pmu
*cpu_pmu
= (struct arm_pmu
*)dev
;
848 struct pmu_hw_events
*cpuc
= this_cpu_ptr(cpu_pmu
->hw_events
);
849 struct pt_regs
*regs
;
853 * Get and reset the IRQ flags
855 pmnc
= armv7_pmnc_getreset_flags();
858 * Did an overflow occur?
860 if (!armv7_pmnc_has_overflowed(pmnc
))
864 * Handle the counter(s) overflow(s)
866 regs
= get_irq_regs();
868 for (idx
= 0; idx
< cpu_pmu
->num_events
; ++idx
) {
869 struct perf_event
*event
= cpuc
->events
[idx
];
870 struct hw_perf_event
*hwc
;
872 /* Ignore if we don't have an event. */
877 * We have a single interrupt for all counters. Check that
878 * each counter has overflowed before we process it.
880 if (!armv7_pmnc_counter_has_overflowed(pmnc
, idx
))
884 armpmu_event_update(event
);
885 perf_sample_data_init(&data
, 0, hwc
->last_period
);
886 if (!armpmu_event_set_period(event
))
889 if (perf_event_overflow(event
, &data
, regs
))
890 cpu_pmu
->disable(event
);
894 * Handle the pending perf events.
896 * Note: this call *must* be run with interrupts disabled. For
897 * platforms that can have the PMU interrupts raised as an NMI, this
905 static void armv7pmu_start(struct arm_pmu
*cpu_pmu
)
908 struct pmu_hw_events
*events
= this_cpu_ptr(cpu_pmu
->hw_events
);
910 raw_spin_lock_irqsave(&events
->pmu_lock
, flags
);
911 /* Enable all counters */
912 armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E
);
913 raw_spin_unlock_irqrestore(&events
->pmu_lock
, flags
);
916 static void armv7pmu_stop(struct arm_pmu
*cpu_pmu
)
919 struct pmu_hw_events
*events
= this_cpu_ptr(cpu_pmu
->hw_events
);
921 raw_spin_lock_irqsave(&events
->pmu_lock
, flags
);
922 /* Disable all counters */
923 armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E
);
924 raw_spin_unlock_irqrestore(&events
->pmu_lock
, flags
);
927 static int armv7pmu_get_event_idx(struct pmu_hw_events
*cpuc
,
928 struct perf_event
*event
)
931 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
932 struct hw_perf_event
*hwc
= &event
->hw
;
933 unsigned long evtype
= hwc
->config_base
& ARMV7_EVTYPE_EVENT
;
935 /* Always place a cycle counter into the cycle counter. */
936 if (evtype
== ARMV7_PERFCTR_CPU_CYCLES
) {
937 if (test_and_set_bit(ARMV7_IDX_CYCLE_COUNTER
, cpuc
->used_mask
))
940 return ARMV7_IDX_CYCLE_COUNTER
;
944 * For anything other than a cycle counter, try and use
945 * the events counters
947 for (idx
= ARMV7_IDX_COUNTER0
; idx
< cpu_pmu
->num_events
; ++idx
) {
948 if (!test_and_set_bit(idx
, cpuc
->used_mask
))
952 /* The counters are all in use. */
957 * Add an event filter to a given event. This will only work for PMUv2 PMUs.
959 static int armv7pmu_set_event_filter(struct hw_perf_event
*event
,
960 struct perf_event_attr
*attr
)
962 unsigned long config_base
= 0;
964 if (attr
->exclude_idle
)
966 if (attr
->exclude_user
)
967 config_base
|= ARMV7_EXCLUDE_USER
;
968 if (attr
->exclude_kernel
)
969 config_base
|= ARMV7_EXCLUDE_PL1
;
970 if (!attr
->exclude_hv
)
971 config_base
|= ARMV7_INCLUDE_HYP
;
974 * Install the filter into config_base as this is used to
975 * construct the event type.
977 event
->config_base
= config_base
;
982 static void armv7pmu_reset(void *info
)
984 struct arm_pmu
*cpu_pmu
= (struct arm_pmu
*)info
;
985 u32 idx
, nb_cnt
= cpu_pmu
->num_events
;
987 /* The counter and interrupt enable registers are unknown at reset. */
988 for (idx
= ARMV7_IDX_CYCLE_COUNTER
; idx
< nb_cnt
; ++idx
) {
989 armv7_pmnc_disable_counter(idx
);
990 armv7_pmnc_disable_intens(idx
);
993 /* Initialize & Reset PMNC: C and P bits */
994 armv7_pmnc_write(ARMV7_PMNC_P
| ARMV7_PMNC_C
);
997 static int armv7_a8_map_event(struct perf_event
*event
)
999 return armpmu_map_event(event
, &armv7_a8_perf_map
,
1000 &armv7_a8_perf_cache_map
, 0xFF);
1003 static int armv7_a9_map_event(struct perf_event
*event
)
1005 return armpmu_map_event(event
, &armv7_a9_perf_map
,
1006 &armv7_a9_perf_cache_map
, 0xFF);
1009 static int armv7_a5_map_event(struct perf_event
*event
)
1011 return armpmu_map_event(event
, &armv7_a5_perf_map
,
1012 &armv7_a5_perf_cache_map
, 0xFF);
1015 static int armv7_a15_map_event(struct perf_event
*event
)
1017 return armpmu_map_event(event
, &armv7_a15_perf_map
,
1018 &armv7_a15_perf_cache_map
, 0xFF);
1021 static int armv7_a7_map_event(struct perf_event
*event
)
1023 return armpmu_map_event(event
, &armv7_a7_perf_map
,
1024 &armv7_a7_perf_cache_map
, 0xFF);
1027 static int armv7_a12_map_event(struct perf_event
*event
)
1029 return armpmu_map_event(event
, &armv7_a12_perf_map
,
1030 &armv7_a12_perf_cache_map
, 0xFF);
1033 static int krait_map_event(struct perf_event
*event
)
1035 return armpmu_map_event(event
, &krait_perf_map
,
1036 &krait_perf_cache_map
, 0xFFFFF);
1039 static int krait_map_event_no_branch(struct perf_event
*event
)
1041 return armpmu_map_event(event
, &krait_perf_map_no_branch
,
1042 &krait_perf_cache_map
, 0xFFFFF);
1045 static int scorpion_map_event(struct perf_event
*event
)
1047 return armpmu_map_event(event
, &scorpion_perf_map
,
1048 &scorpion_perf_cache_map
, 0xFFFFF);
1051 static void armv7pmu_init(struct arm_pmu
*cpu_pmu
)
1053 cpu_pmu
->handle_irq
= armv7pmu_handle_irq
;
1054 cpu_pmu
->enable
= armv7pmu_enable_event
;
1055 cpu_pmu
->disable
= armv7pmu_disable_event
;
1056 cpu_pmu
->read_counter
= armv7pmu_read_counter
;
1057 cpu_pmu
->write_counter
= armv7pmu_write_counter
;
1058 cpu_pmu
->get_event_idx
= armv7pmu_get_event_idx
;
1059 cpu_pmu
->start
= armv7pmu_start
;
1060 cpu_pmu
->stop
= armv7pmu_stop
;
1061 cpu_pmu
->reset
= armv7pmu_reset
;
1062 cpu_pmu
->max_period
= (1LLU << 32) - 1;
1065 static void armv7_read_num_pmnc_events(void *info
)
1069 /* Read the nb of CNTx counters supported from PMNC */
1070 *nb_cnt
= (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT
) & ARMV7_PMNC_N_MASK
;
1072 /* Add the CPU cycles counter */
1076 static int armv7_probe_num_events(struct arm_pmu
*arm_pmu
)
1078 return smp_call_function_any(&arm_pmu
->supported_cpus
,
1079 armv7_read_num_pmnc_events
,
1080 &arm_pmu
->num_events
, 1);
1083 static int armv7_a8_pmu_init(struct arm_pmu
*cpu_pmu
)
1085 armv7pmu_init(cpu_pmu
);
1086 cpu_pmu
->name
= "armv7_cortex_a8";
1087 cpu_pmu
->map_event
= armv7_a8_map_event
;
1088 return armv7_probe_num_events(cpu_pmu
);
1091 static int armv7_a9_pmu_init(struct arm_pmu
*cpu_pmu
)
1093 armv7pmu_init(cpu_pmu
);
1094 cpu_pmu
->name
= "armv7_cortex_a9";
1095 cpu_pmu
->map_event
= armv7_a9_map_event
;
1096 return armv7_probe_num_events(cpu_pmu
);
1099 static int armv7_a5_pmu_init(struct arm_pmu
*cpu_pmu
)
1101 armv7pmu_init(cpu_pmu
);
1102 cpu_pmu
->name
= "armv7_cortex_a5";
1103 cpu_pmu
->map_event
= armv7_a5_map_event
;
1104 return armv7_probe_num_events(cpu_pmu
);
1107 static int armv7_a15_pmu_init(struct arm_pmu
*cpu_pmu
)
1109 armv7pmu_init(cpu_pmu
);
1110 cpu_pmu
->name
= "armv7_cortex_a15";
1111 cpu_pmu
->map_event
= armv7_a15_map_event
;
1112 cpu_pmu
->set_event_filter
= armv7pmu_set_event_filter
;
1113 return armv7_probe_num_events(cpu_pmu
);
1116 static int armv7_a7_pmu_init(struct arm_pmu
*cpu_pmu
)
1118 armv7pmu_init(cpu_pmu
);
1119 cpu_pmu
->name
= "armv7_cortex_a7";
1120 cpu_pmu
->map_event
= armv7_a7_map_event
;
1121 cpu_pmu
->set_event_filter
= armv7pmu_set_event_filter
;
1122 return armv7_probe_num_events(cpu_pmu
);
1125 static int armv7_a12_pmu_init(struct arm_pmu
*cpu_pmu
)
1127 armv7pmu_init(cpu_pmu
);
1128 cpu_pmu
->name
= "armv7_cortex_a12";
1129 cpu_pmu
->map_event
= armv7_a12_map_event
;
1130 cpu_pmu
->set_event_filter
= armv7pmu_set_event_filter
;
1131 return armv7_probe_num_events(cpu_pmu
);
1134 static int armv7_a17_pmu_init(struct arm_pmu
*cpu_pmu
)
1136 int ret
= armv7_a12_pmu_init(cpu_pmu
);
1137 cpu_pmu
->name
= "armv7_cortex_a17";
1142 * Krait Performance Monitor Region Event Selection Register (PMRESRn)
1145 * +--------------------------------+
1146 * PMRESR0 | EN | CC | CC | CC | CC | N = 1, R = 0
1147 * +--------------------------------+
1148 * PMRESR1 | EN | CC | CC | CC | CC | N = 1, R = 1
1149 * +--------------------------------+
1150 * PMRESR2 | EN | CC | CC | CC | CC | N = 1, R = 2
1151 * +--------------------------------+
1152 * VPMRESR0 | EN | CC | CC | CC | CC | N = 2, R = ?
1153 * +--------------------------------+
1154 * EN | G=3 | G=2 | G=1 | G=0
1158 * hwc->config_base = 0xNRCCG
1160 * N = prefix, 1 for Krait CPU (PMRESRn), 2 for Venum VFP (VPMRESR)
1161 * R = region register
1162 * CC = class of events the group G is choosing from
1163 * G = group or particular event
1165 * Example: 0x12021 is a Krait CPU event in PMRESR2's group 1 with code 2
1167 * A region (R) corresponds to a piece of the CPU (execution unit, instruction
1168 * unit, etc.) while the event code (CC) corresponds to a particular class of
1169 * events (interrupts for example). An event code is broken down into
1170 * groups (G) that can be mapped into the PMU (irq, fiqs, and irq+fiqs for
1174 #define KRAIT_EVENT (1 << 16)
1175 #define VENUM_EVENT (2 << 16)
1176 #define KRAIT_EVENT_MASK (KRAIT_EVENT | VENUM_EVENT)
1177 #define PMRESRn_EN BIT(31)
1179 #define EVENT_REGION(event) (((event) >> 12) & 0xf) /* R */
1180 #define EVENT_GROUP(event) ((event) & 0xf) /* G */
1181 #define EVENT_CODE(event) (((event) >> 4) & 0xff) /* CC */
1182 #define EVENT_VENUM(event) (!!(event & VENUM_EVENT)) /* N=2 */
1183 #define EVENT_CPU(event) (!!(event & KRAIT_EVENT)) /* N=1 */
1185 static u32
krait_read_pmresrn(int n
)
1191 asm volatile("mrc p15, 1, %0, c9, c15, 0" : "=r" (val
));
1194 asm volatile("mrc p15, 1, %0, c9, c15, 1" : "=r" (val
));
1197 asm volatile("mrc p15, 1, %0, c9, c15, 2" : "=r" (val
));
1200 BUG(); /* Should be validated in krait_pmu_get_event_idx() */
1206 static void krait_write_pmresrn(int n
, u32 val
)
1210 asm volatile("mcr p15, 1, %0, c9, c15, 0" : : "r" (val
));
1213 asm volatile("mcr p15, 1, %0, c9, c15, 1" : : "r" (val
));
1216 asm volatile("mcr p15, 1, %0, c9, c15, 2" : : "r" (val
));
1219 BUG(); /* Should be validated in krait_pmu_get_event_idx() */
1223 static u32
venum_read_pmresr(void)
1226 asm volatile("mrc p10, 7, %0, c11, c0, 0" : "=r" (val
));
1230 static void venum_write_pmresr(u32 val
)
1232 asm volatile("mcr p10, 7, %0, c11, c0, 0" : : "r" (val
));
1235 static void venum_pre_pmresr(u32
*venum_orig_val
, u32
*fp_orig_val
)
1240 BUG_ON(preemptible());
1241 /* CPACR Enable CP10 and CP11 access */
1242 *venum_orig_val
= get_copro_access();
1243 venum_new_val
= *venum_orig_val
| CPACC_SVC(10) | CPACC_SVC(11);
1244 set_copro_access(venum_new_val
);
1247 *fp_orig_val
= fmrx(FPEXC
);
1248 fp_new_val
= *fp_orig_val
| FPEXC_EN
;
1249 fmxr(FPEXC
, fp_new_val
);
1252 static void venum_post_pmresr(u32 venum_orig_val
, u32 fp_orig_val
)
1254 BUG_ON(preemptible());
1256 fmxr(FPEXC
, fp_orig_val
);
1259 set_copro_access(venum_orig_val
);
1262 static u32
krait_get_pmresrn_event(unsigned int region
)
1264 static const u32 pmresrn_table
[] = { KRAIT_PMRESR0_GROUP0
,
1265 KRAIT_PMRESR1_GROUP0
,
1266 KRAIT_PMRESR2_GROUP0
};
1267 return pmresrn_table
[region
];
1270 static void krait_evt_setup(int idx
, u32 config_base
)
1275 unsigned int region
= EVENT_REGION(config_base
);
1276 unsigned int group
= EVENT_GROUP(config_base
);
1277 unsigned int code
= EVENT_CODE(config_base
);
1278 unsigned int group_shift
;
1279 bool venum_event
= EVENT_VENUM(config_base
);
1281 group_shift
= group
* 8;
1282 mask
= 0xff << group_shift
;
1284 /* Configure evtsel for the region and group */
1286 val
= KRAIT_VPMRESR0_GROUP0
;
1288 val
= krait_get_pmresrn_event(region
);
1290 /* Mix in mode-exclusion bits */
1291 val
|= config_base
& (ARMV7_EXCLUDE_USER
| ARMV7_EXCLUDE_PL1
);
1292 armv7_pmnc_write_evtsel(idx
, val
);
1295 venum_pre_pmresr(&vval
, &fval
);
1296 val
= venum_read_pmresr();
1298 val
|= code
<< group_shift
;
1300 venum_write_pmresr(val
);
1301 venum_post_pmresr(vval
, fval
);
1303 val
= krait_read_pmresrn(region
);
1305 val
|= code
<< group_shift
;
1307 krait_write_pmresrn(region
, val
);
1311 static u32
clear_pmresrn_group(u32 val
, int group
)
1316 group_shift
= group
* 8;
1317 mask
= 0xff << group_shift
;
1320 /* Don't clear enable bit if entire region isn't disabled */
1321 if (val
& ~PMRESRn_EN
)
1322 return val
|= PMRESRn_EN
;
1327 static void krait_clearpmu(u32 config_base
)
1331 unsigned int region
= EVENT_REGION(config_base
);
1332 unsigned int group
= EVENT_GROUP(config_base
);
1333 bool venum_event
= EVENT_VENUM(config_base
);
1336 venum_pre_pmresr(&vval
, &fval
);
1337 val
= venum_read_pmresr();
1338 val
= clear_pmresrn_group(val
, group
);
1339 venum_write_pmresr(val
);
1340 venum_post_pmresr(vval
, fval
);
1342 val
= krait_read_pmresrn(region
);
1343 val
= clear_pmresrn_group(val
, group
);
1344 krait_write_pmresrn(region
, val
);
1348 static void krait_pmu_disable_event(struct perf_event
*event
)
1350 unsigned long flags
;
1351 struct hw_perf_event
*hwc
= &event
->hw
;
1353 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
1354 struct pmu_hw_events
*events
= this_cpu_ptr(cpu_pmu
->hw_events
);
1356 /* Disable counter and interrupt */
1357 raw_spin_lock_irqsave(&events
->pmu_lock
, flags
);
1359 /* Disable counter */
1360 armv7_pmnc_disable_counter(idx
);
1363 * Clear pmresr code (if destined for PMNx counters)
1365 if (hwc
->config_base
& KRAIT_EVENT_MASK
)
1366 krait_clearpmu(hwc
->config_base
);
1368 /* Disable interrupt for this counter */
1369 armv7_pmnc_disable_intens(idx
);
1371 raw_spin_unlock_irqrestore(&events
->pmu_lock
, flags
);
1374 static void krait_pmu_enable_event(struct perf_event
*event
)
1376 unsigned long flags
;
1377 struct hw_perf_event
*hwc
= &event
->hw
;
1379 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
1380 struct pmu_hw_events
*events
= this_cpu_ptr(cpu_pmu
->hw_events
);
1383 * Enable counter and interrupt, and set the counter to count
1384 * the event that we're interested in.
1386 raw_spin_lock_irqsave(&events
->pmu_lock
, flags
);
1388 /* Disable counter */
1389 armv7_pmnc_disable_counter(idx
);
1392 * Set event (if destined for PMNx counters)
1393 * We set the event for the cycle counter because we
1394 * have the ability to perform event filtering.
1396 if (hwc
->config_base
& KRAIT_EVENT_MASK
)
1397 krait_evt_setup(idx
, hwc
->config_base
);
1399 armv7_pmnc_write_evtsel(idx
, hwc
->config_base
);
1401 /* Enable interrupt for this counter */
1402 armv7_pmnc_enable_intens(idx
);
1404 /* Enable counter */
1405 armv7_pmnc_enable_counter(idx
);
1407 raw_spin_unlock_irqrestore(&events
->pmu_lock
, flags
);
1410 static void krait_pmu_reset(void *info
)
1413 struct arm_pmu
*cpu_pmu
= info
;
1414 u32 idx
, nb_cnt
= cpu_pmu
->num_events
;
1416 armv7pmu_reset(info
);
1418 /* Clear all pmresrs */
1419 krait_write_pmresrn(0, 0);
1420 krait_write_pmresrn(1, 0);
1421 krait_write_pmresrn(2, 0);
1423 venum_pre_pmresr(&vval
, &fval
);
1424 venum_write_pmresr(0);
1425 venum_post_pmresr(vval
, fval
);
1427 /* Reset PMxEVNCTCR to sane default */
1428 for (idx
= ARMV7_IDX_CYCLE_COUNTER
; idx
< nb_cnt
; ++idx
) {
1429 armv7_pmnc_select_counter(idx
);
1430 asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
1435 static int krait_event_to_bit(struct perf_event
*event
, unsigned int region
,
1439 struct hw_perf_event
*hwc
= &event
->hw
;
1440 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
1442 if (hwc
->config_base
& VENUM_EVENT
)
1443 bit
= KRAIT_VPMRESR0_GROUP0
;
1445 bit
= krait_get_pmresrn_event(region
);
1446 bit
-= krait_get_pmresrn_event(0);
1449 * Lower bits are reserved for use by the counters (see
1450 * armv7pmu_get_event_idx() for more info)
1452 bit
+= ARMV7_IDX_COUNTER_LAST(cpu_pmu
) + 1;
1458 * We check for column exclusion constraints here.
1459 * Two events cant use the same group within a pmresr register.
1461 static int krait_pmu_get_event_idx(struct pmu_hw_events
*cpuc
,
1462 struct perf_event
*event
)
1466 struct hw_perf_event
*hwc
= &event
->hw
;
1467 unsigned int region
= EVENT_REGION(hwc
->config_base
);
1468 unsigned int code
= EVENT_CODE(hwc
->config_base
);
1469 unsigned int group
= EVENT_GROUP(hwc
->config_base
);
1470 bool venum_event
= EVENT_VENUM(hwc
->config_base
);
1471 bool krait_event
= EVENT_CPU(hwc
->config_base
);
1473 if (venum_event
|| krait_event
) {
1474 /* Ignore invalid events */
1475 if (group
> 3 || region
> 2)
1477 if (venum_event
&& (code
& 0xe0))
1480 bit
= krait_event_to_bit(event
, region
, group
);
1481 if (test_and_set_bit(bit
, cpuc
->used_mask
))
1485 idx
= armv7pmu_get_event_idx(cpuc
, event
);
1486 if (idx
< 0 && bit
>= 0)
1487 clear_bit(bit
, cpuc
->used_mask
);
1492 static void krait_pmu_clear_event_idx(struct pmu_hw_events
*cpuc
,
1493 struct perf_event
*event
)
1496 struct hw_perf_event
*hwc
= &event
->hw
;
1497 unsigned int region
= EVENT_REGION(hwc
->config_base
);
1498 unsigned int group
= EVENT_GROUP(hwc
->config_base
);
1499 bool venum_event
= EVENT_VENUM(hwc
->config_base
);
1500 bool krait_event
= EVENT_CPU(hwc
->config_base
);
1502 if (venum_event
|| krait_event
) {
1503 bit
= krait_event_to_bit(event
, region
, group
);
1504 clear_bit(bit
, cpuc
->used_mask
);
1508 static int krait_pmu_init(struct arm_pmu
*cpu_pmu
)
1510 armv7pmu_init(cpu_pmu
);
1511 cpu_pmu
->name
= "armv7_krait";
1512 /* Some early versions of Krait don't support PC write events */
1513 if (of_property_read_bool(cpu_pmu
->plat_device
->dev
.of_node
,
1514 "qcom,no-pc-write"))
1515 cpu_pmu
->map_event
= krait_map_event_no_branch
;
1517 cpu_pmu
->map_event
= krait_map_event
;
1518 cpu_pmu
->set_event_filter
= armv7pmu_set_event_filter
;
1519 cpu_pmu
->reset
= krait_pmu_reset
;
1520 cpu_pmu
->enable
= krait_pmu_enable_event
;
1521 cpu_pmu
->disable
= krait_pmu_disable_event
;
1522 cpu_pmu
->get_event_idx
= krait_pmu_get_event_idx
;
1523 cpu_pmu
->clear_event_idx
= krait_pmu_clear_event_idx
;
1524 return armv7_probe_num_events(cpu_pmu
);
1528 * Scorpion Local Performance Monitor Register (LPMn)
1531 * +--------------------------------+
1532 * LPM0 | EN | CC | CC | CC | CC | N = 1, R = 0
1533 * +--------------------------------+
1534 * LPM1 | EN | CC | CC | CC | CC | N = 1, R = 1
1535 * +--------------------------------+
1536 * LPM2 | EN | CC | CC | CC | CC | N = 1, R = 2
1537 * +--------------------------------+
1538 * L2LPM | EN | CC | CC | CC | CC | N = 1, R = 3
1539 * +--------------------------------+
1540 * VLPM | EN | CC | CC | CC | CC | N = 2, R = ?
1541 * +--------------------------------+
1542 * EN | G=3 | G=2 | G=1 | G=0
1547 * hwc->config_base = 0xNRCCG
1549 * N = prefix, 1 for Scorpion CPU (LPMn/L2LPM), 2 for Venum VFP (VLPM)
1550 * R = region register
1551 * CC = class of events the group G is choosing from
1552 * G = group or particular event
1554 * Example: 0x12021 is a Scorpion CPU event in LPM2's group 1 with code 2
1556 * A region (R) corresponds to a piece of the CPU (execution unit, instruction
1557 * unit, etc.) while the event code (CC) corresponds to a particular class of
1558 * events (interrupts for example). An event code is broken down into
1559 * groups (G) that can be mapped into the PMU (irq, fiqs, and irq+fiqs for
1563 static u32
scorpion_read_pmresrn(int n
)
1569 asm volatile("mrc p15, 0, %0, c15, c0, 0" : "=r" (val
));
1572 asm volatile("mrc p15, 1, %0, c15, c0, 0" : "=r" (val
));
1575 asm volatile("mrc p15, 2, %0, c15, c0, 0" : "=r" (val
));
1578 asm volatile("mrc p15, 3, %0, c15, c2, 0" : "=r" (val
));
1581 BUG(); /* Should be validated in scorpion_pmu_get_event_idx() */
1587 static void scorpion_write_pmresrn(int n
, u32 val
)
1591 asm volatile("mcr p15, 0, %0, c15, c0, 0" : : "r" (val
));
1594 asm volatile("mcr p15, 1, %0, c15, c0, 0" : : "r" (val
));
1597 asm volatile("mcr p15, 2, %0, c15, c0, 0" : : "r" (val
));
1600 asm volatile("mcr p15, 3, %0, c15, c2, 0" : : "r" (val
));
1603 BUG(); /* Should be validated in scorpion_pmu_get_event_idx() */
1607 static u32
scorpion_get_pmresrn_event(unsigned int region
)
1609 static const u32 pmresrn_table
[] = { SCORPION_LPM0_GROUP0
,
1610 SCORPION_LPM1_GROUP0
,
1611 SCORPION_LPM2_GROUP0
,
1612 SCORPION_L2LPM_GROUP0
};
1613 return pmresrn_table
[region
];
1616 static void scorpion_evt_setup(int idx
, u32 config_base
)
1621 unsigned int region
= EVENT_REGION(config_base
);
1622 unsigned int group
= EVENT_GROUP(config_base
);
1623 unsigned int code
= EVENT_CODE(config_base
);
1624 unsigned int group_shift
;
1625 bool venum_event
= EVENT_VENUM(config_base
);
1627 group_shift
= group
* 8;
1628 mask
= 0xff << group_shift
;
1630 /* Configure evtsel for the region and group */
1632 val
= SCORPION_VLPM_GROUP0
;
1634 val
= scorpion_get_pmresrn_event(region
);
1636 /* Mix in mode-exclusion bits */
1637 val
|= config_base
& (ARMV7_EXCLUDE_USER
| ARMV7_EXCLUDE_PL1
);
1638 armv7_pmnc_write_evtsel(idx
, val
);
1640 asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
1643 venum_pre_pmresr(&vval
, &fval
);
1644 val
= venum_read_pmresr();
1646 val
|= code
<< group_shift
;
1648 venum_write_pmresr(val
);
1649 venum_post_pmresr(vval
, fval
);
1651 val
= scorpion_read_pmresrn(region
);
1653 val
|= code
<< group_shift
;
1655 scorpion_write_pmresrn(region
, val
);
1659 static void scorpion_clearpmu(u32 config_base
)
1663 unsigned int region
= EVENT_REGION(config_base
);
1664 unsigned int group
= EVENT_GROUP(config_base
);
1665 bool venum_event
= EVENT_VENUM(config_base
);
1668 venum_pre_pmresr(&vval
, &fval
);
1669 val
= venum_read_pmresr();
1670 val
= clear_pmresrn_group(val
, group
);
1671 venum_write_pmresr(val
);
1672 venum_post_pmresr(vval
, fval
);
1674 val
= scorpion_read_pmresrn(region
);
1675 val
= clear_pmresrn_group(val
, group
);
1676 scorpion_write_pmresrn(region
, val
);
1680 static void scorpion_pmu_disable_event(struct perf_event
*event
)
1682 unsigned long flags
;
1683 struct hw_perf_event
*hwc
= &event
->hw
;
1685 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
1686 struct pmu_hw_events
*events
= this_cpu_ptr(cpu_pmu
->hw_events
);
1688 /* Disable counter and interrupt */
1689 raw_spin_lock_irqsave(&events
->pmu_lock
, flags
);
1691 /* Disable counter */
1692 armv7_pmnc_disable_counter(idx
);
1695 * Clear pmresr code (if destined for PMNx counters)
1697 if (hwc
->config_base
& KRAIT_EVENT_MASK
)
1698 scorpion_clearpmu(hwc
->config_base
);
1700 /* Disable interrupt for this counter */
1701 armv7_pmnc_disable_intens(idx
);
1703 raw_spin_unlock_irqrestore(&events
->pmu_lock
, flags
);
1706 static void scorpion_pmu_enable_event(struct perf_event
*event
)
1708 unsigned long flags
;
1709 struct hw_perf_event
*hwc
= &event
->hw
;
1711 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
1712 struct pmu_hw_events
*events
= this_cpu_ptr(cpu_pmu
->hw_events
);
1715 * Enable counter and interrupt, and set the counter to count
1716 * the event that we're interested in.
1718 raw_spin_lock_irqsave(&events
->pmu_lock
, flags
);
1720 /* Disable counter */
1721 armv7_pmnc_disable_counter(idx
);
1724 * Set event (if destined for PMNx counters)
1725 * We don't set the event for the cycle counter because we
1726 * don't have the ability to perform event filtering.
1728 if (hwc
->config_base
& KRAIT_EVENT_MASK
)
1729 scorpion_evt_setup(idx
, hwc
->config_base
);
1730 else if (idx
!= ARMV7_IDX_CYCLE_COUNTER
)
1731 armv7_pmnc_write_evtsel(idx
, hwc
->config_base
);
1733 /* Enable interrupt for this counter */
1734 armv7_pmnc_enable_intens(idx
);
1736 /* Enable counter */
1737 armv7_pmnc_enable_counter(idx
);
1739 raw_spin_unlock_irqrestore(&events
->pmu_lock
, flags
);
1742 static void scorpion_pmu_reset(void *info
)
1745 struct arm_pmu
*cpu_pmu
= info
;
1746 u32 idx
, nb_cnt
= cpu_pmu
->num_events
;
1748 armv7pmu_reset(info
);
1750 /* Clear all pmresrs */
1751 scorpion_write_pmresrn(0, 0);
1752 scorpion_write_pmresrn(1, 0);
1753 scorpion_write_pmresrn(2, 0);
1754 scorpion_write_pmresrn(3, 0);
1756 venum_pre_pmresr(&vval
, &fval
);
1757 venum_write_pmresr(0);
1758 venum_post_pmresr(vval
, fval
);
1760 /* Reset PMxEVNCTCR to sane default */
1761 for (idx
= ARMV7_IDX_CYCLE_COUNTER
; idx
< nb_cnt
; ++idx
) {
1762 armv7_pmnc_select_counter(idx
);
1763 asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
1767 static int scorpion_event_to_bit(struct perf_event
*event
, unsigned int region
,
1771 struct hw_perf_event
*hwc
= &event
->hw
;
1772 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
1774 if (hwc
->config_base
& VENUM_EVENT
)
1775 bit
= SCORPION_VLPM_GROUP0
;
1777 bit
= scorpion_get_pmresrn_event(region
);
1778 bit
-= scorpion_get_pmresrn_event(0);
1781 * Lower bits are reserved for use by the counters (see
1782 * armv7pmu_get_event_idx() for more info)
1784 bit
+= ARMV7_IDX_COUNTER_LAST(cpu_pmu
) + 1;
1790 * We check for column exclusion constraints here.
1791 * Two events cant use the same group within a pmresr register.
1793 static int scorpion_pmu_get_event_idx(struct pmu_hw_events
*cpuc
,
1794 struct perf_event
*event
)
1798 struct hw_perf_event
*hwc
= &event
->hw
;
1799 unsigned int region
= EVENT_REGION(hwc
->config_base
);
1800 unsigned int group
= EVENT_GROUP(hwc
->config_base
);
1801 bool venum_event
= EVENT_VENUM(hwc
->config_base
);
1802 bool scorpion_event
= EVENT_CPU(hwc
->config_base
);
1804 if (venum_event
|| scorpion_event
) {
1805 /* Ignore invalid events */
1806 if (group
> 3 || region
> 3)
1809 bit
= scorpion_event_to_bit(event
, region
, group
);
1810 if (test_and_set_bit(bit
, cpuc
->used_mask
))
1814 idx
= armv7pmu_get_event_idx(cpuc
, event
);
1815 if (idx
< 0 && bit
>= 0)
1816 clear_bit(bit
, cpuc
->used_mask
);
1821 static void scorpion_pmu_clear_event_idx(struct pmu_hw_events
*cpuc
,
1822 struct perf_event
*event
)
1825 struct hw_perf_event
*hwc
= &event
->hw
;
1826 unsigned int region
= EVENT_REGION(hwc
->config_base
);
1827 unsigned int group
= EVENT_GROUP(hwc
->config_base
);
1828 bool venum_event
= EVENT_VENUM(hwc
->config_base
);
1829 bool scorpion_event
= EVENT_CPU(hwc
->config_base
);
1831 if (venum_event
|| scorpion_event
) {
1832 bit
= scorpion_event_to_bit(event
, region
, group
);
1833 clear_bit(bit
, cpuc
->used_mask
);
1837 static int scorpion_pmu_init(struct arm_pmu
*cpu_pmu
)
1839 armv7pmu_init(cpu_pmu
);
1840 cpu_pmu
->name
= "armv7_scorpion";
1841 cpu_pmu
->map_event
= scorpion_map_event
;
1842 cpu_pmu
->reset
= scorpion_pmu_reset
;
1843 cpu_pmu
->enable
= scorpion_pmu_enable_event
;
1844 cpu_pmu
->disable
= scorpion_pmu_disable_event
;
1845 cpu_pmu
->get_event_idx
= scorpion_pmu_get_event_idx
;
1846 cpu_pmu
->clear_event_idx
= scorpion_pmu_clear_event_idx
;
1847 return armv7_probe_num_events(cpu_pmu
);
1850 static int scorpion_mp_pmu_init(struct arm_pmu
*cpu_pmu
)
1852 armv7pmu_init(cpu_pmu
);
1853 cpu_pmu
->name
= "armv7_scorpion_mp";
1854 cpu_pmu
->map_event
= scorpion_map_event
;
1855 cpu_pmu
->reset
= scorpion_pmu_reset
;
1856 cpu_pmu
->enable
= scorpion_pmu_enable_event
;
1857 cpu_pmu
->disable
= scorpion_pmu_disable_event
;
1858 cpu_pmu
->get_event_idx
= scorpion_pmu_get_event_idx
;
1859 cpu_pmu
->clear_event_idx
= scorpion_pmu_clear_event_idx
;
1860 return armv7_probe_num_events(cpu_pmu
);
1863 static const struct of_device_id armv7_pmu_of_device_ids
[] = {
1864 {.compatible
= "arm,cortex-a17-pmu", .data
= armv7_a17_pmu_init
},
1865 {.compatible
= "arm,cortex-a15-pmu", .data
= armv7_a15_pmu_init
},
1866 {.compatible
= "arm,cortex-a12-pmu", .data
= armv7_a12_pmu_init
},
1867 {.compatible
= "arm,cortex-a9-pmu", .data
= armv7_a9_pmu_init
},
1868 {.compatible
= "arm,cortex-a8-pmu", .data
= armv7_a8_pmu_init
},
1869 {.compatible
= "arm,cortex-a7-pmu", .data
= armv7_a7_pmu_init
},
1870 {.compatible
= "arm,cortex-a5-pmu", .data
= armv7_a5_pmu_init
},
1871 {.compatible
= "qcom,krait-pmu", .data
= krait_pmu_init
},
1872 {.compatible
= "qcom,scorpion-pmu", .data
= scorpion_pmu_init
},
1873 {.compatible
= "qcom,scorpion-mp-pmu", .data
= scorpion_mp_pmu_init
},
1877 static const struct pmu_probe_info armv7_pmu_probe_table
[] = {
1878 ARM_PMU_PROBE(ARM_CPU_PART_CORTEX_A8
, armv7_a8_pmu_init
),
1879 ARM_PMU_PROBE(ARM_CPU_PART_CORTEX_A9
, armv7_a9_pmu_init
),
1880 { /* sentinel value */ }
1884 static int armv7_pmu_device_probe(struct platform_device
*pdev
)
1886 return arm_pmu_device_probe(pdev
, armv7_pmu_of_device_ids
,
1887 armv7_pmu_probe_table
);
1890 static struct platform_driver armv7_pmu_driver
= {
1892 .name
= "armv7-pmu",
1893 .of_match_table
= armv7_pmu_of_device_ids
,
1895 .probe
= armv7_pmu_device_probe
,
1898 static int __init
register_armv7_pmu_driver(void)
1900 return platform_driver_register(&armv7_pmu_driver
);
1902 device_initcall(register_armv7_pmu_driver
);
1903 #endif /* CONFIG_CPU_V7 */