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