ARM: perf: consistently use struct perf_event in arm_pmu functions
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / kernel / perf_event_v7.c
1 /*
2 * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code.
3 *
4 * ARMv7 support: Jean Pihet <jpihet@mvista.com>
5 * 2010 (c) MontaVista Software, LLC.
6 *
7 * Copied from ARMv6 code, with the low level code inspired
8 * by the ARMv7 Oprofile code.
9 *
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.
14 *
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.
17 */
18
19 #ifdef CONFIG_CPU_V7
20
21 /*
22 * Common ARMv7 event types
23 *
24 * Note: An implementation may not be able to count all of these events
25 * but the encodings are considered to be `reserved' in the case that
26 * they are not available.
27 */
28 enum armv7_perf_types {
29 ARMV7_PERFCTR_PMNC_SW_INCR = 0x00,
30 ARMV7_PERFCTR_L1_ICACHE_REFILL = 0x01,
31 ARMV7_PERFCTR_ITLB_REFILL = 0x02,
32 ARMV7_PERFCTR_L1_DCACHE_REFILL = 0x03,
33 ARMV7_PERFCTR_L1_DCACHE_ACCESS = 0x04,
34 ARMV7_PERFCTR_DTLB_REFILL = 0x05,
35 ARMV7_PERFCTR_MEM_READ = 0x06,
36 ARMV7_PERFCTR_MEM_WRITE = 0x07,
37 ARMV7_PERFCTR_INSTR_EXECUTED = 0x08,
38 ARMV7_PERFCTR_EXC_TAKEN = 0x09,
39 ARMV7_PERFCTR_EXC_EXECUTED = 0x0A,
40 ARMV7_PERFCTR_CID_WRITE = 0x0B,
41
42 /*
43 * ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
44 * It counts:
45 * - all (taken) branch instructions,
46 * - instructions that explicitly write the PC,
47 * - exception generating instructions.
48 */
49 ARMV7_PERFCTR_PC_WRITE = 0x0C,
50 ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D,
51 ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E,
52 ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS = 0x0F,
53 ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
54 ARMV7_PERFCTR_CLOCK_CYCLES = 0x11,
55 ARMV7_PERFCTR_PC_BRANCH_PRED = 0x12,
56
57 /* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
58 ARMV7_PERFCTR_MEM_ACCESS = 0x13,
59 ARMV7_PERFCTR_L1_ICACHE_ACCESS = 0x14,
60 ARMV7_PERFCTR_L1_DCACHE_WB = 0x15,
61 ARMV7_PERFCTR_L2_CACHE_ACCESS = 0x16,
62 ARMV7_PERFCTR_L2_CACHE_REFILL = 0x17,
63 ARMV7_PERFCTR_L2_CACHE_WB = 0x18,
64 ARMV7_PERFCTR_BUS_ACCESS = 0x19,
65 ARMV7_PERFCTR_MEM_ERROR = 0x1A,
66 ARMV7_PERFCTR_INSTR_SPEC = 0x1B,
67 ARMV7_PERFCTR_TTBR_WRITE = 0x1C,
68 ARMV7_PERFCTR_BUS_CYCLES = 0x1D,
69
70 ARMV7_PERFCTR_CPU_CYCLES = 0xFF
71 };
72
73 /* ARMv7 Cortex-A8 specific event types */
74 enum armv7_a8_perf_types {
75 ARMV7_A8_PERFCTR_L2_CACHE_ACCESS = 0x43,
76 ARMV7_A8_PERFCTR_L2_CACHE_REFILL = 0x44,
77 ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS = 0x50,
78 ARMV7_A8_PERFCTR_STALL_ISIDE = 0x56,
79 };
80
81 /* ARMv7 Cortex-A9 specific event types */
82 enum armv7_a9_perf_types {
83 ARMV7_A9_PERFCTR_INSTR_CORE_RENAME = 0x68,
84 ARMV7_A9_PERFCTR_STALL_ICACHE = 0x60,
85 ARMV7_A9_PERFCTR_STALL_DISPATCH = 0x66,
86 };
87
88 /* ARMv7 Cortex-A5 specific event types */
89 enum armv7_a5_perf_types {
90 ARMV7_A5_PERFCTR_PREFETCH_LINEFILL = 0xc2,
91 ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP = 0xc3,
92 };
93
94 /* ARMv7 Cortex-A15 specific event types */
95 enum armv7_a15_perf_types {
96 ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ = 0x40,
97 ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE = 0x41,
98 ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ = 0x42,
99 ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE = 0x43,
100
101 ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ = 0x4C,
102 ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE = 0x4D,
103
104 ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ = 0x50,
105 ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE = 0x51,
106 ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ = 0x52,
107 ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE = 0x53,
108
109 ARMV7_A15_PERFCTR_PC_WRITE_SPEC = 0x76,
110 };
111
112 /*
113 * Cortex-A8 HW events mapping
114 *
115 * The hardware events that we support. We do support cache operations but
116 * we have harvard caches and no way to combine instruction and data
117 * accesses/misses in hardware.
118 */
119 static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = {
120 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
121 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
122 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
123 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
124 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
125 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
126 [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
127 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV7_A8_PERFCTR_STALL_ISIDE,
128 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
129 };
130
131 static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
132 [PERF_COUNT_HW_CACHE_OP_MAX]
133 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
134 [C(L1D)] = {
135 /*
136 * The performance counters don't differentiate between read
137 * and write accesses/misses so this isn't strictly correct,
138 * but it's the best we can do. Writes and reads get
139 * combined.
140 */
141 [C(OP_READ)] = {
142 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
143 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
144 },
145 [C(OP_WRITE)] = {
146 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
147 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
148 },
149 [C(OP_PREFETCH)] = {
150 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
151 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
152 },
153 },
154 [C(L1I)] = {
155 [C(OP_READ)] = {
156 [C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS,
157 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
158 },
159 [C(OP_WRITE)] = {
160 [C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS,
161 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
162 },
163 [C(OP_PREFETCH)] = {
164 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
165 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
166 },
167 },
168 [C(LL)] = {
169 [C(OP_READ)] = {
170 [C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS,
171 [C(RESULT_MISS)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL,
172 },
173 [C(OP_WRITE)] = {
174 [C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS,
175 [C(RESULT_MISS)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL,
176 },
177 [C(OP_PREFETCH)] = {
178 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
179 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
180 },
181 },
182 [C(DTLB)] = {
183 [C(OP_READ)] = {
184 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
185 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
186 },
187 [C(OP_WRITE)] = {
188 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
189 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
190 },
191 [C(OP_PREFETCH)] = {
192 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
193 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
194 },
195 },
196 [C(ITLB)] = {
197 [C(OP_READ)] = {
198 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
199 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
200 },
201 [C(OP_WRITE)] = {
202 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
203 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
204 },
205 [C(OP_PREFETCH)] = {
206 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
207 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
208 },
209 },
210 [C(BPU)] = {
211 [C(OP_READ)] = {
212 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
213 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
214 },
215 [C(OP_WRITE)] = {
216 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
217 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
218 },
219 [C(OP_PREFETCH)] = {
220 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
221 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
222 },
223 },
224 [C(NODE)] = {
225 [C(OP_READ)] = {
226 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
227 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
228 },
229 [C(OP_WRITE)] = {
230 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
231 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
232 },
233 [C(OP_PREFETCH)] = {
234 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
235 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
236 },
237 },
238 };
239
240 /*
241 * Cortex-A9 HW events mapping
242 */
243 static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
244 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
245 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_A9_PERFCTR_INSTR_CORE_RENAME,
246 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
247 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
248 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
249 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
250 [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
251 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV7_A9_PERFCTR_STALL_ICACHE,
252 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV7_A9_PERFCTR_STALL_DISPATCH,
253 };
254
255 static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
256 [PERF_COUNT_HW_CACHE_OP_MAX]
257 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
258 [C(L1D)] = {
259 /*
260 * The performance counters don't differentiate between read
261 * and write accesses/misses so this isn't strictly correct,
262 * but it's the best we can do. Writes and reads get
263 * combined.
264 */
265 [C(OP_READ)] = {
266 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
267 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
268 },
269 [C(OP_WRITE)] = {
270 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
271 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
272 },
273 [C(OP_PREFETCH)] = {
274 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
275 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
276 },
277 },
278 [C(L1I)] = {
279 [C(OP_READ)] = {
280 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
281 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
282 },
283 [C(OP_WRITE)] = {
284 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
285 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
286 },
287 [C(OP_PREFETCH)] = {
288 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
289 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
290 },
291 },
292 [C(LL)] = {
293 [C(OP_READ)] = {
294 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
295 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
296 },
297 [C(OP_WRITE)] = {
298 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
299 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
300 },
301 [C(OP_PREFETCH)] = {
302 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
303 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
304 },
305 },
306 [C(DTLB)] = {
307 [C(OP_READ)] = {
308 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
309 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
310 },
311 [C(OP_WRITE)] = {
312 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
313 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
314 },
315 [C(OP_PREFETCH)] = {
316 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
317 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
318 },
319 },
320 [C(ITLB)] = {
321 [C(OP_READ)] = {
322 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
323 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
324 },
325 [C(OP_WRITE)] = {
326 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
327 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
328 },
329 [C(OP_PREFETCH)] = {
330 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
331 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
332 },
333 },
334 [C(BPU)] = {
335 [C(OP_READ)] = {
336 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
337 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
338 },
339 [C(OP_WRITE)] = {
340 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
341 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
342 },
343 [C(OP_PREFETCH)] = {
344 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
345 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
346 },
347 },
348 [C(NODE)] = {
349 [C(OP_READ)] = {
350 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
351 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
352 },
353 [C(OP_WRITE)] = {
354 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
355 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
356 },
357 [C(OP_PREFETCH)] = {
358 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
359 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
360 },
361 },
362 };
363
364 /*
365 * Cortex-A5 HW events mapping
366 */
367 static const unsigned armv7_a5_perf_map[PERF_COUNT_HW_MAX] = {
368 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
369 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
370 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
371 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
372 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
373 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
374 [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
375 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
376 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
377 };
378
379 static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
380 [PERF_COUNT_HW_CACHE_OP_MAX]
381 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
382 [C(L1D)] = {
383 [C(OP_READ)] = {
384 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
385 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
386 },
387 [C(OP_WRITE)] = {
388 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
389 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
390 },
391 [C(OP_PREFETCH)] = {
392 [C(RESULT_ACCESS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL,
393 [C(RESULT_MISS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP,
394 },
395 },
396 [C(L1I)] = {
397 [C(OP_READ)] = {
398 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
399 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
400 },
401 [C(OP_WRITE)] = {
402 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
403 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
404 },
405 /*
406 * The prefetch counters don't differentiate between the I
407 * side and the D side.
408 */
409 [C(OP_PREFETCH)] = {
410 [C(RESULT_ACCESS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL,
411 [C(RESULT_MISS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP,
412 },
413 },
414 [C(LL)] = {
415 [C(OP_READ)] = {
416 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
417 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
418 },
419 [C(OP_WRITE)] = {
420 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
421 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
422 },
423 [C(OP_PREFETCH)] = {
424 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
425 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
426 },
427 },
428 [C(DTLB)] = {
429 [C(OP_READ)] = {
430 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
431 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
432 },
433 [C(OP_WRITE)] = {
434 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
435 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
436 },
437 [C(OP_PREFETCH)] = {
438 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
439 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
440 },
441 },
442 [C(ITLB)] = {
443 [C(OP_READ)] = {
444 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
445 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
446 },
447 [C(OP_WRITE)] = {
448 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
449 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
450 },
451 [C(OP_PREFETCH)] = {
452 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
453 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
454 },
455 },
456 [C(BPU)] = {
457 [C(OP_READ)] = {
458 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
459 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
460 },
461 [C(OP_WRITE)] = {
462 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
463 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
464 },
465 [C(OP_PREFETCH)] = {
466 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
467 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
468 },
469 },
470 [C(NODE)] = {
471 [C(OP_READ)] = {
472 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
473 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
474 },
475 [C(OP_WRITE)] = {
476 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
477 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
478 },
479 [C(OP_PREFETCH)] = {
480 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
481 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
482 },
483 },
484 };
485
486 /*
487 * Cortex-A15 HW events mapping
488 */
489 static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = {
490 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
491 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
492 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
493 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
494 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A15_PERFCTR_PC_WRITE_SPEC,
495 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
496 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
497 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
498 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
499 };
500
501 static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
502 [PERF_COUNT_HW_CACHE_OP_MAX]
503 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
504 [C(L1D)] = {
505 [C(OP_READ)] = {
506 [C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ,
507 [C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ,
508 },
509 [C(OP_WRITE)] = {
510 [C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE,
511 [C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE,
512 },
513 [C(OP_PREFETCH)] = {
514 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
515 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
516 },
517 },
518 [C(L1I)] = {
519 /*
520 * Not all performance counters differentiate between read
521 * and write accesses/misses so we're not always strictly
522 * correct, but it's the best we can do. Writes and reads get
523 * combined in these cases.
524 */
525 [C(OP_READ)] = {
526 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
527 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
528 },
529 [C(OP_WRITE)] = {
530 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
531 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
532 },
533 [C(OP_PREFETCH)] = {
534 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
535 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
536 },
537 },
538 [C(LL)] = {
539 [C(OP_READ)] = {
540 [C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ,
541 [C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ,
542 },
543 [C(OP_WRITE)] = {
544 [C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE,
545 [C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE,
546 },
547 [C(OP_PREFETCH)] = {
548 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
549 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
550 },
551 },
552 [C(DTLB)] = {
553 [C(OP_READ)] = {
554 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
555 [C(RESULT_MISS)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ,
556 },
557 [C(OP_WRITE)] = {
558 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
559 [C(RESULT_MISS)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE,
560 },
561 [C(OP_PREFETCH)] = {
562 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
563 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
564 },
565 },
566 [C(ITLB)] = {
567 [C(OP_READ)] = {
568 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
569 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
570 },
571 [C(OP_WRITE)] = {
572 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
573 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
574 },
575 [C(OP_PREFETCH)] = {
576 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
577 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
578 },
579 },
580 [C(BPU)] = {
581 [C(OP_READ)] = {
582 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
583 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
584 },
585 [C(OP_WRITE)] = {
586 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
587 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
588 },
589 [C(OP_PREFETCH)] = {
590 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
591 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
592 },
593 },
594 [C(NODE)] = {
595 [C(OP_READ)] = {
596 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
597 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
598 },
599 [C(OP_WRITE)] = {
600 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
601 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
602 },
603 [C(OP_PREFETCH)] = {
604 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
605 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
606 },
607 },
608 };
609
610 /*
611 * Cortex-A7 HW events mapping
612 */
613 static const unsigned armv7_a7_perf_map[PERF_COUNT_HW_MAX] = {
614 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
615 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
616 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
617 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
618 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
619 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
620 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
621 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
622 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
623 };
624
625 static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
626 [PERF_COUNT_HW_CACHE_OP_MAX]
627 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
628 [C(L1D)] = {
629 /*
630 * The performance counters don't differentiate between read
631 * and write accesses/misses so this isn't strictly correct,
632 * but it's the best we can do. Writes and reads get
633 * combined.
634 */
635 [C(OP_READ)] = {
636 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
637 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
638 },
639 [C(OP_WRITE)] = {
640 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
641 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
642 },
643 [C(OP_PREFETCH)] = {
644 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
645 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
646 },
647 },
648 [C(L1I)] = {
649 [C(OP_READ)] = {
650 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
651 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
652 },
653 [C(OP_WRITE)] = {
654 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
655 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
656 },
657 [C(OP_PREFETCH)] = {
658 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
659 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
660 },
661 },
662 [C(LL)] = {
663 [C(OP_READ)] = {
664 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS,
665 [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
666 },
667 [C(OP_WRITE)] = {
668 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS,
669 [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
670 },
671 [C(OP_PREFETCH)] = {
672 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
673 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
674 },
675 },
676 [C(DTLB)] = {
677 [C(OP_READ)] = {
678 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
679 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
680 },
681 [C(OP_WRITE)] = {
682 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
683 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
684 },
685 [C(OP_PREFETCH)] = {
686 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
687 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
688 },
689 },
690 [C(ITLB)] = {
691 [C(OP_READ)] = {
692 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
693 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
694 },
695 [C(OP_WRITE)] = {
696 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
697 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
698 },
699 [C(OP_PREFETCH)] = {
700 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
701 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
702 },
703 },
704 [C(BPU)] = {
705 [C(OP_READ)] = {
706 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
707 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
708 },
709 [C(OP_WRITE)] = {
710 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
711 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
712 },
713 [C(OP_PREFETCH)] = {
714 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
715 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
716 },
717 },
718 [C(NODE)] = {
719 [C(OP_READ)] = {
720 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
721 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
722 },
723 [C(OP_WRITE)] = {
724 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
725 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
726 },
727 [C(OP_PREFETCH)] = {
728 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
729 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
730 },
731 },
732 };
733
734 /*
735 * Perf Events' indices
736 */
737 #define ARMV7_IDX_CYCLE_COUNTER 0
738 #define ARMV7_IDX_COUNTER0 1
739 #define ARMV7_IDX_COUNTER_LAST (ARMV7_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1)
740
741 #define ARMV7_MAX_COUNTERS 32
742 #define ARMV7_COUNTER_MASK (ARMV7_MAX_COUNTERS - 1)
743
744 /*
745 * ARMv7 low level PMNC access
746 */
747
748 /*
749 * Perf Event to low level counters mapping
750 */
751 #define ARMV7_IDX_TO_COUNTER(x) \
752 (((x) - ARMV7_IDX_COUNTER0) & ARMV7_COUNTER_MASK)
753
754 /*
755 * Per-CPU PMNC: config reg
756 */
757 #define ARMV7_PMNC_E (1 << 0) /* Enable all counters */
758 #define ARMV7_PMNC_P (1 << 1) /* Reset all counters */
759 #define ARMV7_PMNC_C (1 << 2) /* Cycle counter reset */
760 #define ARMV7_PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
761 #define ARMV7_PMNC_X (1 << 4) /* Export to ETM */
762 #define ARMV7_PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
763 #define ARMV7_PMNC_N_SHIFT 11 /* Number of counters supported */
764 #define ARMV7_PMNC_N_MASK 0x1f
765 #define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */
766
767 /*
768 * FLAG: counters overflow flag status reg
769 */
770 #define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */
771 #define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK
772
773 /*
774 * PMXEVTYPER: Event selection reg
775 */
776 #define ARMV7_EVTYPE_MASK 0xc00000ff /* Mask for writable bits */
777 #define ARMV7_EVTYPE_EVENT 0xff /* Mask for EVENT bits */
778
779 /*
780 * Event filters for PMUv2
781 */
782 #define ARMV7_EXCLUDE_PL1 (1 << 31)
783 #define ARMV7_EXCLUDE_USER (1 << 30)
784 #define ARMV7_INCLUDE_HYP (1 << 27)
785
786 static inline u32 armv7_pmnc_read(void)
787 {
788 u32 val;
789 asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
790 return val;
791 }
792
793 static inline void armv7_pmnc_write(u32 val)
794 {
795 val &= ARMV7_PMNC_MASK;
796 isb();
797 asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
798 }
799
800 static inline int armv7_pmnc_has_overflowed(u32 pmnc)
801 {
802 return pmnc & ARMV7_OVERFLOWED_MASK;
803 }
804
805 static inline int armv7_pmnc_counter_valid(int idx)
806 {
807 return idx >= ARMV7_IDX_CYCLE_COUNTER && idx <= ARMV7_IDX_COUNTER_LAST;
808 }
809
810 static inline int armv7_pmnc_counter_has_overflowed(u32 pmnc, int idx)
811 {
812 int ret = 0;
813 u32 counter;
814
815 if (!armv7_pmnc_counter_valid(idx)) {
816 pr_err("CPU%u checking wrong counter %d overflow status\n",
817 smp_processor_id(), idx);
818 } else {
819 counter = ARMV7_IDX_TO_COUNTER(idx);
820 ret = pmnc & BIT(counter);
821 }
822
823 return ret;
824 }
825
826 static inline int armv7_pmnc_select_counter(int idx)
827 {
828 u32 counter;
829
830 if (!armv7_pmnc_counter_valid(idx)) {
831 pr_err("CPU%u selecting wrong PMNC counter %d\n",
832 smp_processor_id(), idx);
833 return -EINVAL;
834 }
835
836 counter = ARMV7_IDX_TO_COUNTER(idx);
837 asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (counter));
838 isb();
839
840 return idx;
841 }
842
843 static inline u32 armv7pmu_read_counter(struct perf_event *event)
844 {
845 struct hw_perf_event *hwc = &event->hw;
846 int idx = hwc->idx;
847 u32 value = 0;
848
849 if (!armv7_pmnc_counter_valid(idx))
850 pr_err("CPU%u reading wrong counter %d\n",
851 smp_processor_id(), idx);
852 else if (idx == ARMV7_IDX_CYCLE_COUNTER)
853 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
854 else if (armv7_pmnc_select_counter(idx) == idx)
855 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (value));
856
857 return value;
858 }
859
860 static inline void armv7pmu_write_counter(struct perf_event *event, u32 value)
861 {
862 struct hw_perf_event *hwc = &event->hw;
863 int idx = hwc->idx;
864
865 if (!armv7_pmnc_counter_valid(idx))
866 pr_err("CPU%u writing wrong counter %d\n",
867 smp_processor_id(), idx);
868 else if (idx == ARMV7_IDX_CYCLE_COUNTER)
869 asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
870 else if (armv7_pmnc_select_counter(idx) == idx)
871 asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (value));
872 }
873
874 static inline void armv7_pmnc_write_evtsel(int idx, u32 val)
875 {
876 if (armv7_pmnc_select_counter(idx) == idx) {
877 val &= ARMV7_EVTYPE_MASK;
878 asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
879 }
880 }
881
882 static inline int armv7_pmnc_enable_counter(int idx)
883 {
884 u32 counter;
885
886 if (!armv7_pmnc_counter_valid(idx)) {
887 pr_err("CPU%u enabling wrong PMNC counter %d\n",
888 smp_processor_id(), idx);
889 return -EINVAL;
890 }
891
892 counter = ARMV7_IDX_TO_COUNTER(idx);
893 asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(counter)));
894 return idx;
895 }
896
897 static inline int armv7_pmnc_disable_counter(int idx)
898 {
899 u32 counter;
900
901 if (!armv7_pmnc_counter_valid(idx)) {
902 pr_err("CPU%u disabling wrong PMNC counter %d\n",
903 smp_processor_id(), idx);
904 return -EINVAL;
905 }
906
907 counter = ARMV7_IDX_TO_COUNTER(idx);
908 asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(counter)));
909 return idx;
910 }
911
912 static inline int armv7_pmnc_enable_intens(int idx)
913 {
914 u32 counter;
915
916 if (!armv7_pmnc_counter_valid(idx)) {
917 pr_err("CPU%u enabling wrong PMNC counter IRQ enable %d\n",
918 smp_processor_id(), idx);
919 return -EINVAL;
920 }
921
922 counter = ARMV7_IDX_TO_COUNTER(idx);
923 asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(counter)));
924 return idx;
925 }
926
927 static inline int armv7_pmnc_disable_intens(int idx)
928 {
929 u32 counter;
930
931 if (!armv7_pmnc_counter_valid(idx)) {
932 pr_err("CPU%u disabling wrong PMNC counter IRQ enable %d\n",
933 smp_processor_id(), idx);
934 return -EINVAL;
935 }
936
937 counter = ARMV7_IDX_TO_COUNTER(idx);
938 asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(counter)));
939 isb();
940 /* Clear the overflow flag in case an interrupt is pending. */
941 asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (BIT(counter)));
942 isb();
943
944 return idx;
945 }
946
947 static inline u32 armv7_pmnc_getreset_flags(void)
948 {
949 u32 val;
950
951 /* Read */
952 asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
953
954 /* Write to clear flags */
955 val &= ARMV7_FLAG_MASK;
956 asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
957
958 return val;
959 }
960
961 #ifdef DEBUG
962 static void armv7_pmnc_dump_regs(void)
963 {
964 u32 val;
965 unsigned int cnt;
966
967 printk(KERN_INFO "PMNC registers dump:\n");
968
969 asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
970 printk(KERN_INFO "PMNC =0x%08x\n", val);
971
972 asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
973 printk(KERN_INFO "CNTENS=0x%08x\n", val);
974
975 asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
976 printk(KERN_INFO "INTENS=0x%08x\n", val);
977
978 asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
979 printk(KERN_INFO "FLAGS =0x%08x\n", val);
980
981 asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
982 printk(KERN_INFO "SELECT=0x%08x\n", val);
983
984 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
985 printk(KERN_INFO "CCNT =0x%08x\n", val);
986
987 for (cnt = ARMV7_IDX_COUNTER0; cnt <= ARMV7_IDX_COUNTER_LAST; cnt++) {
988 armv7_pmnc_select_counter(cnt);
989 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
990 printk(KERN_INFO "CNT[%d] count =0x%08x\n",
991 ARMV7_IDX_TO_COUNTER(cnt), val);
992 asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
993 printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n",
994 ARMV7_IDX_TO_COUNTER(cnt), val);
995 }
996 }
997 #endif
998
999 static void armv7pmu_enable_event(struct perf_event *event)
1000 {
1001 unsigned long flags;
1002 struct hw_perf_event *hwc = &event->hw;
1003 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
1004 struct pmu_hw_events *events = cpu_pmu->get_hw_events();
1005 int idx = hwc->idx;
1006
1007 /*
1008 * Enable counter and interrupt, and set the counter to count
1009 * the event that we're interested in.
1010 */
1011 raw_spin_lock_irqsave(&events->pmu_lock, flags);
1012
1013 /*
1014 * Disable counter
1015 */
1016 armv7_pmnc_disable_counter(idx);
1017
1018 /*
1019 * Set event (if destined for PMNx counters)
1020 * We only need to set the event for the cycle counter if we
1021 * have the ability to perform event filtering.
1022 */
1023 if (cpu_pmu->set_event_filter || idx != ARMV7_IDX_CYCLE_COUNTER)
1024 armv7_pmnc_write_evtsel(idx, hwc->config_base);
1025
1026 /*
1027 * Enable interrupt for this counter
1028 */
1029 armv7_pmnc_enable_intens(idx);
1030
1031 /*
1032 * Enable counter
1033 */
1034 armv7_pmnc_enable_counter(idx);
1035
1036 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1037 }
1038
1039 static void armv7pmu_disable_event(struct perf_event *event)
1040 {
1041 unsigned long flags;
1042 struct hw_perf_event *hwc = &event->hw;
1043 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
1044 struct pmu_hw_events *events = cpu_pmu->get_hw_events();
1045 int idx = hwc->idx;
1046
1047 /*
1048 * Disable counter and interrupt
1049 */
1050 raw_spin_lock_irqsave(&events->pmu_lock, flags);
1051
1052 /*
1053 * Disable counter
1054 */
1055 armv7_pmnc_disable_counter(idx);
1056
1057 /*
1058 * Disable interrupt for this counter
1059 */
1060 armv7_pmnc_disable_intens(idx);
1061
1062 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1063 }
1064
1065 static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
1066 {
1067 u32 pmnc;
1068 struct perf_sample_data data;
1069 struct arm_pmu *cpu_pmu = (struct arm_pmu *)dev;
1070 struct pmu_hw_events *cpuc = cpu_pmu->get_hw_events();
1071 struct pt_regs *regs;
1072 int idx;
1073
1074 /*
1075 * Get and reset the IRQ flags
1076 */
1077 pmnc = armv7_pmnc_getreset_flags();
1078
1079 /*
1080 * Did an overflow occur?
1081 */
1082 if (!armv7_pmnc_has_overflowed(pmnc))
1083 return IRQ_NONE;
1084
1085 /*
1086 * Handle the counter(s) overflow(s)
1087 */
1088 regs = get_irq_regs();
1089
1090 for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
1091 struct perf_event *event = cpuc->events[idx];
1092 struct hw_perf_event *hwc;
1093
1094 /* Ignore if we don't have an event. */
1095 if (!event)
1096 continue;
1097
1098 /*
1099 * We have a single interrupt for all counters. Check that
1100 * each counter has overflowed before we process it.
1101 */
1102 if (!armv7_pmnc_counter_has_overflowed(pmnc, idx))
1103 continue;
1104
1105 hwc = &event->hw;
1106 armpmu_event_update(event);
1107 perf_sample_data_init(&data, 0, hwc->last_period);
1108 if (!armpmu_event_set_period(event))
1109 continue;
1110
1111 if (perf_event_overflow(event, &data, regs))
1112 cpu_pmu->disable(event);
1113 }
1114
1115 /*
1116 * Handle the pending perf events.
1117 *
1118 * Note: this call *must* be run with interrupts disabled. For
1119 * platforms that can have the PMU interrupts raised as an NMI, this
1120 * will not work.
1121 */
1122 irq_work_run();
1123
1124 return IRQ_HANDLED;
1125 }
1126
1127 static void armv7pmu_start(struct arm_pmu *cpu_pmu)
1128 {
1129 unsigned long flags;
1130 struct pmu_hw_events *events = cpu_pmu->get_hw_events();
1131
1132 raw_spin_lock_irqsave(&events->pmu_lock, flags);
1133 /* Enable all counters */
1134 armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
1135 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1136 }
1137
1138 static void armv7pmu_stop(struct arm_pmu *cpu_pmu)
1139 {
1140 unsigned long flags;
1141 struct pmu_hw_events *events = cpu_pmu->get_hw_events();
1142
1143 raw_spin_lock_irqsave(&events->pmu_lock, flags);
1144 /* Disable all counters */
1145 armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E);
1146 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1147 }
1148
1149 static int armv7pmu_get_event_idx(struct pmu_hw_events *cpuc,
1150 struct perf_event *event)
1151 {
1152 int idx;
1153 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
1154 struct hw_perf_event *hwc = &event->hw;
1155 unsigned long evtype = hwc->config_base & ARMV7_EVTYPE_EVENT;
1156
1157 /* Always place a cycle counter into the cycle counter. */
1158 if (evtype == ARMV7_PERFCTR_CPU_CYCLES) {
1159 if (test_and_set_bit(ARMV7_IDX_CYCLE_COUNTER, cpuc->used_mask))
1160 return -EAGAIN;
1161
1162 return ARMV7_IDX_CYCLE_COUNTER;
1163 }
1164
1165 /*
1166 * For anything other than a cycle counter, try and use
1167 * the events counters
1168 */
1169 for (idx = ARMV7_IDX_COUNTER0; idx < cpu_pmu->num_events; ++idx) {
1170 if (!test_and_set_bit(idx, cpuc->used_mask))
1171 return idx;
1172 }
1173
1174 /* The counters are all in use. */
1175 return -EAGAIN;
1176 }
1177
1178 /*
1179 * Add an event filter to a given event. This will only work for PMUv2 PMUs.
1180 */
1181 static int armv7pmu_set_event_filter(struct hw_perf_event *event,
1182 struct perf_event_attr *attr)
1183 {
1184 unsigned long config_base = 0;
1185
1186 if (attr->exclude_idle)
1187 return -EPERM;
1188 if (attr->exclude_user)
1189 config_base |= ARMV7_EXCLUDE_USER;
1190 if (attr->exclude_kernel)
1191 config_base |= ARMV7_EXCLUDE_PL1;
1192 if (!attr->exclude_hv)
1193 config_base |= ARMV7_INCLUDE_HYP;
1194
1195 /*
1196 * Install the filter into config_base as this is used to
1197 * construct the event type.
1198 */
1199 event->config_base = config_base;
1200
1201 return 0;
1202 }
1203
1204 static void armv7pmu_reset(void *info)
1205 {
1206 struct arm_pmu *cpu_pmu = (struct arm_pmu *)info;
1207 u32 idx, nb_cnt = cpu_pmu->num_events;
1208
1209 /* The counter and interrupt enable registers are unknown at reset. */
1210 for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) {
1211 armv7_pmnc_disable_counter(idx);
1212 armv7_pmnc_disable_intens(idx);
1213 }
1214
1215 /* Initialize & Reset PMNC: C and P bits */
1216 armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
1217 }
1218
1219 static int armv7_a8_map_event(struct perf_event *event)
1220 {
1221 return armpmu_map_event(event, &armv7_a8_perf_map,
1222 &armv7_a8_perf_cache_map, 0xFF);
1223 }
1224
1225 static int armv7_a9_map_event(struct perf_event *event)
1226 {
1227 return armpmu_map_event(event, &armv7_a9_perf_map,
1228 &armv7_a9_perf_cache_map, 0xFF);
1229 }
1230
1231 static int armv7_a5_map_event(struct perf_event *event)
1232 {
1233 return armpmu_map_event(event, &armv7_a5_perf_map,
1234 &armv7_a5_perf_cache_map, 0xFF);
1235 }
1236
1237 static int armv7_a15_map_event(struct perf_event *event)
1238 {
1239 return armpmu_map_event(event, &armv7_a15_perf_map,
1240 &armv7_a15_perf_cache_map, 0xFF);
1241 }
1242
1243 static int armv7_a7_map_event(struct perf_event *event)
1244 {
1245 return armpmu_map_event(event, &armv7_a7_perf_map,
1246 &armv7_a7_perf_cache_map, 0xFF);
1247 }
1248
1249 static void armv7pmu_init(struct arm_pmu *cpu_pmu)
1250 {
1251 cpu_pmu->handle_irq = armv7pmu_handle_irq;
1252 cpu_pmu->enable = armv7pmu_enable_event;
1253 cpu_pmu->disable = armv7pmu_disable_event;
1254 cpu_pmu->read_counter = armv7pmu_read_counter;
1255 cpu_pmu->write_counter = armv7pmu_write_counter;
1256 cpu_pmu->get_event_idx = armv7pmu_get_event_idx;
1257 cpu_pmu->start = armv7pmu_start;
1258 cpu_pmu->stop = armv7pmu_stop;
1259 cpu_pmu->reset = armv7pmu_reset;
1260 cpu_pmu->max_period = (1LLU << 32) - 1;
1261 };
1262
1263 static u32 __devinit armv7_read_num_pmnc_events(void)
1264 {
1265 u32 nb_cnt;
1266
1267 /* Read the nb of CNTx counters supported from PMNC */
1268 nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
1269
1270 /* Add the CPU cycles counter and return */
1271 return nb_cnt + 1;
1272 }
1273
1274 static int __devinit armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
1275 {
1276 armv7pmu_init(cpu_pmu);
1277 cpu_pmu->name = "ARMv7 Cortex-A8";
1278 cpu_pmu->map_event = armv7_a8_map_event;
1279 cpu_pmu->num_events = armv7_read_num_pmnc_events();
1280 return 0;
1281 }
1282
1283 static int __devinit armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
1284 {
1285 armv7pmu_init(cpu_pmu);
1286 cpu_pmu->name = "ARMv7 Cortex-A9";
1287 cpu_pmu->map_event = armv7_a9_map_event;
1288 cpu_pmu->num_events = armv7_read_num_pmnc_events();
1289 return 0;
1290 }
1291
1292 static int __devinit armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
1293 {
1294 armv7pmu_init(cpu_pmu);
1295 cpu_pmu->name = "ARMv7 Cortex-A5";
1296 cpu_pmu->map_event = armv7_a5_map_event;
1297 cpu_pmu->num_events = armv7_read_num_pmnc_events();
1298 return 0;
1299 }
1300
1301 static int __devinit armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
1302 {
1303 armv7pmu_init(cpu_pmu);
1304 cpu_pmu->name = "ARMv7 Cortex-A15";
1305 cpu_pmu->map_event = armv7_a15_map_event;
1306 cpu_pmu->num_events = armv7_read_num_pmnc_events();
1307 cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
1308 return 0;
1309 }
1310
1311 static int __devinit armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
1312 {
1313 armv7pmu_init(cpu_pmu);
1314 cpu_pmu->name = "ARMv7 Cortex-A7";
1315 cpu_pmu->map_event = armv7_a7_map_event;
1316 cpu_pmu->num_events = armv7_read_num_pmnc_events();
1317 cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
1318 return 0;
1319 }
1320 #else
1321 static inline int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
1322 {
1323 return -ENODEV;
1324 }
1325
1326 static inline int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
1327 {
1328 return -ENODEV;
1329 }
1330
1331 static inline int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
1332 {
1333 return -ENODEV;
1334 }
1335
1336 static inline int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
1337 {
1338 return -ENODEV;
1339 }
1340
1341 static inline int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
1342 {
1343 return -ENODEV;
1344 }
1345 #endif /* CONFIG_CPU_V7 */