xref: /openbmc/linux/arch/arm/kernel/perf_event_v7.c (revision 513c99ce)
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(int idx)
844 {
845 	u32 value = 0;
846 
847 	if (!armv7_pmnc_counter_valid(idx))
848 		pr_err("CPU%u reading wrong counter %d\n",
849 			smp_processor_id(), idx);
850 	else if (idx == ARMV7_IDX_CYCLE_COUNTER)
851 		asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
852 	else if (armv7_pmnc_select_counter(idx) == idx)
853 		asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (value));
854 
855 	return value;
856 }
857 
858 static inline void armv7pmu_write_counter(int idx, u32 value)
859 {
860 	if (!armv7_pmnc_counter_valid(idx))
861 		pr_err("CPU%u writing wrong counter %d\n",
862 			smp_processor_id(), idx);
863 	else if (idx == ARMV7_IDX_CYCLE_COUNTER)
864 		asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
865 	else if (armv7_pmnc_select_counter(idx) == idx)
866 		asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (value));
867 }
868 
869 static inline void armv7_pmnc_write_evtsel(int idx, u32 val)
870 {
871 	if (armv7_pmnc_select_counter(idx) == idx) {
872 		val &= ARMV7_EVTYPE_MASK;
873 		asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
874 	}
875 }
876 
877 static inline int armv7_pmnc_enable_counter(int idx)
878 {
879 	u32 counter;
880 
881 	if (!armv7_pmnc_counter_valid(idx)) {
882 		pr_err("CPU%u enabling wrong PMNC counter %d\n",
883 			smp_processor_id(), idx);
884 		return -EINVAL;
885 	}
886 
887 	counter = ARMV7_IDX_TO_COUNTER(idx);
888 	asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(counter)));
889 	return idx;
890 }
891 
892 static inline int armv7_pmnc_disable_counter(int idx)
893 {
894 	u32 counter;
895 
896 	if (!armv7_pmnc_counter_valid(idx)) {
897 		pr_err("CPU%u disabling wrong PMNC counter %d\n",
898 			smp_processor_id(), idx);
899 		return -EINVAL;
900 	}
901 
902 	counter = ARMV7_IDX_TO_COUNTER(idx);
903 	asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(counter)));
904 	return idx;
905 }
906 
907 static inline int armv7_pmnc_enable_intens(int idx)
908 {
909 	u32 counter;
910 
911 	if (!armv7_pmnc_counter_valid(idx)) {
912 		pr_err("CPU%u enabling wrong PMNC counter IRQ enable %d\n",
913 			smp_processor_id(), idx);
914 		return -EINVAL;
915 	}
916 
917 	counter = ARMV7_IDX_TO_COUNTER(idx);
918 	asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(counter)));
919 	return idx;
920 }
921 
922 static inline int armv7_pmnc_disable_intens(int idx)
923 {
924 	u32 counter;
925 
926 	if (!armv7_pmnc_counter_valid(idx)) {
927 		pr_err("CPU%u disabling wrong PMNC counter IRQ enable %d\n",
928 			smp_processor_id(), idx);
929 		return -EINVAL;
930 	}
931 
932 	counter = ARMV7_IDX_TO_COUNTER(idx);
933 	asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(counter)));
934 	isb();
935 	/* Clear the overflow flag in case an interrupt is pending. */
936 	asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (BIT(counter)));
937 	isb();
938 
939 	return idx;
940 }
941 
942 static inline u32 armv7_pmnc_getreset_flags(void)
943 {
944 	u32 val;
945 
946 	/* Read */
947 	asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
948 
949 	/* Write to clear flags */
950 	val &= ARMV7_FLAG_MASK;
951 	asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
952 
953 	return val;
954 }
955 
956 #ifdef DEBUG
957 static void armv7_pmnc_dump_regs(void)
958 {
959 	u32 val;
960 	unsigned int cnt;
961 
962 	printk(KERN_INFO "PMNC registers dump:\n");
963 
964 	asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
965 	printk(KERN_INFO "PMNC  =0x%08x\n", val);
966 
967 	asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
968 	printk(KERN_INFO "CNTENS=0x%08x\n", val);
969 
970 	asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
971 	printk(KERN_INFO "INTENS=0x%08x\n", val);
972 
973 	asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
974 	printk(KERN_INFO "FLAGS =0x%08x\n", val);
975 
976 	asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
977 	printk(KERN_INFO "SELECT=0x%08x\n", val);
978 
979 	asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
980 	printk(KERN_INFO "CCNT  =0x%08x\n", val);
981 
982 	for (cnt = ARMV7_IDX_COUNTER0; cnt <= ARMV7_IDX_COUNTER_LAST; cnt++) {
983 		armv7_pmnc_select_counter(cnt);
984 		asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
985 		printk(KERN_INFO "CNT[%d] count =0x%08x\n",
986 			ARMV7_IDX_TO_COUNTER(cnt), val);
987 		asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
988 		printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n",
989 			ARMV7_IDX_TO_COUNTER(cnt), val);
990 	}
991 }
992 #endif
993 
994 static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)
995 {
996 	unsigned long flags;
997 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
998 
999 	/*
1000 	 * Enable counter and interrupt, and set the counter to count
1001 	 * the event that we're interested in.
1002 	 */
1003 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
1004 
1005 	/*
1006 	 * Disable counter
1007 	 */
1008 	armv7_pmnc_disable_counter(idx);
1009 
1010 	/*
1011 	 * Set event (if destined for PMNx counters)
1012 	 * We only need to set the event for the cycle counter if we
1013 	 * have the ability to perform event filtering.
1014 	 */
1015 	if (cpu_pmu->set_event_filter || idx != ARMV7_IDX_CYCLE_COUNTER)
1016 		armv7_pmnc_write_evtsel(idx, hwc->config_base);
1017 
1018 	/*
1019 	 * Enable interrupt for this counter
1020 	 */
1021 	armv7_pmnc_enable_intens(idx);
1022 
1023 	/*
1024 	 * Enable counter
1025 	 */
1026 	armv7_pmnc_enable_counter(idx);
1027 
1028 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1029 }
1030 
1031 static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx)
1032 {
1033 	unsigned long flags;
1034 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
1035 
1036 	/*
1037 	 * Disable counter and interrupt
1038 	 */
1039 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
1040 
1041 	/*
1042 	 * Disable counter
1043 	 */
1044 	armv7_pmnc_disable_counter(idx);
1045 
1046 	/*
1047 	 * Disable interrupt for this counter
1048 	 */
1049 	armv7_pmnc_disable_intens(idx);
1050 
1051 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1052 }
1053 
1054 static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
1055 {
1056 	u32 pmnc;
1057 	struct perf_sample_data data;
1058 	struct pmu_hw_events *cpuc;
1059 	struct pt_regs *regs;
1060 	int idx;
1061 
1062 	/*
1063 	 * Get and reset the IRQ flags
1064 	 */
1065 	pmnc = armv7_pmnc_getreset_flags();
1066 
1067 	/*
1068 	 * Did an overflow occur?
1069 	 */
1070 	if (!armv7_pmnc_has_overflowed(pmnc))
1071 		return IRQ_NONE;
1072 
1073 	/*
1074 	 * Handle the counter(s) overflow(s)
1075 	 */
1076 	regs = get_irq_regs();
1077 
1078 	cpuc = &__get_cpu_var(cpu_hw_events);
1079 	for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
1080 		struct perf_event *event = cpuc->events[idx];
1081 		struct hw_perf_event *hwc;
1082 
1083 		/* Ignore if we don't have an event. */
1084 		if (!event)
1085 			continue;
1086 
1087 		/*
1088 		 * We have a single interrupt for all counters. Check that
1089 		 * each counter has overflowed before we process it.
1090 		 */
1091 		if (!armv7_pmnc_counter_has_overflowed(pmnc, idx))
1092 			continue;
1093 
1094 		hwc = &event->hw;
1095 		armpmu_event_update(event, hwc, idx);
1096 		perf_sample_data_init(&data, 0, hwc->last_period);
1097 		if (!armpmu_event_set_period(event, hwc, idx))
1098 			continue;
1099 
1100 		if (perf_event_overflow(event, &data, regs))
1101 			cpu_pmu->disable(hwc, idx);
1102 	}
1103 
1104 	/*
1105 	 * Handle the pending perf events.
1106 	 *
1107 	 * Note: this call *must* be run with interrupts disabled. For
1108 	 * platforms that can have the PMU interrupts raised as an NMI, this
1109 	 * will not work.
1110 	 */
1111 	irq_work_run();
1112 
1113 	return IRQ_HANDLED;
1114 }
1115 
1116 static void armv7pmu_start(void)
1117 {
1118 	unsigned long flags;
1119 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
1120 
1121 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
1122 	/* Enable all counters */
1123 	armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
1124 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1125 }
1126 
1127 static void armv7pmu_stop(void)
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 	/* Disable 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 int armv7pmu_get_event_idx(struct pmu_hw_events *cpuc,
1139 				  struct hw_perf_event *event)
1140 {
1141 	int idx;
1142 	unsigned long evtype = event->config_base & ARMV7_EVTYPE_EVENT;
1143 
1144 	/* Always place a cycle counter into the cycle counter. */
1145 	if (evtype == ARMV7_PERFCTR_CPU_CYCLES) {
1146 		if (test_and_set_bit(ARMV7_IDX_CYCLE_COUNTER, cpuc->used_mask))
1147 			return -EAGAIN;
1148 
1149 		return ARMV7_IDX_CYCLE_COUNTER;
1150 	}
1151 
1152 	/*
1153 	 * For anything other than a cycle counter, try and use
1154 	 * the events counters
1155 	 */
1156 	for (idx = ARMV7_IDX_COUNTER0; idx < cpu_pmu->num_events; ++idx) {
1157 		if (!test_and_set_bit(idx, cpuc->used_mask))
1158 			return idx;
1159 	}
1160 
1161 	/* The counters are all in use. */
1162 	return -EAGAIN;
1163 }
1164 
1165 /*
1166  * Add an event filter to a given event. This will only work for PMUv2 PMUs.
1167  */
1168 static int armv7pmu_set_event_filter(struct hw_perf_event *event,
1169 				     struct perf_event_attr *attr)
1170 {
1171 	unsigned long config_base = 0;
1172 
1173 	if (attr->exclude_idle)
1174 		return -EPERM;
1175 	if (attr->exclude_user)
1176 		config_base |= ARMV7_EXCLUDE_USER;
1177 	if (attr->exclude_kernel)
1178 		config_base |= ARMV7_EXCLUDE_PL1;
1179 	if (!attr->exclude_hv)
1180 		config_base |= ARMV7_INCLUDE_HYP;
1181 
1182 	/*
1183 	 * Install the filter into config_base as this is used to
1184 	 * construct the event type.
1185 	 */
1186 	event->config_base = config_base;
1187 
1188 	return 0;
1189 }
1190 
1191 static void armv7pmu_reset(void *info)
1192 {
1193 	u32 idx, nb_cnt = cpu_pmu->num_events;
1194 
1195 	/* The counter and interrupt enable registers are unknown at reset. */
1196 	for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx)
1197 		armv7pmu_disable_event(NULL, idx);
1198 
1199 	/* Initialize & Reset PMNC: C and P bits */
1200 	armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
1201 }
1202 
1203 static int armv7_a8_map_event(struct perf_event *event)
1204 {
1205 	return armpmu_map_event(event, &armv7_a8_perf_map,
1206 				&armv7_a8_perf_cache_map, 0xFF);
1207 }
1208 
1209 static int armv7_a9_map_event(struct perf_event *event)
1210 {
1211 	return armpmu_map_event(event, &armv7_a9_perf_map,
1212 				&armv7_a9_perf_cache_map, 0xFF);
1213 }
1214 
1215 static int armv7_a5_map_event(struct perf_event *event)
1216 {
1217 	return armpmu_map_event(event, &armv7_a5_perf_map,
1218 				&armv7_a5_perf_cache_map, 0xFF);
1219 }
1220 
1221 static int armv7_a15_map_event(struct perf_event *event)
1222 {
1223 	return armpmu_map_event(event, &armv7_a15_perf_map,
1224 				&armv7_a15_perf_cache_map, 0xFF);
1225 }
1226 
1227 static int armv7_a7_map_event(struct perf_event *event)
1228 {
1229 	return armpmu_map_event(event, &armv7_a7_perf_map,
1230 				&armv7_a7_perf_cache_map, 0xFF);
1231 }
1232 
1233 static void armv7pmu_init(struct arm_pmu *cpu_pmu)
1234 {
1235 	cpu_pmu->handle_irq	= armv7pmu_handle_irq;
1236 	cpu_pmu->enable		= armv7pmu_enable_event;
1237 	cpu_pmu->disable	= armv7pmu_disable_event;
1238 	cpu_pmu->read_counter	= armv7pmu_read_counter;
1239 	cpu_pmu->write_counter	= armv7pmu_write_counter;
1240 	cpu_pmu->get_event_idx	= armv7pmu_get_event_idx;
1241 	cpu_pmu->start		= armv7pmu_start;
1242 	cpu_pmu->stop		= armv7pmu_stop;
1243 	cpu_pmu->reset		= armv7pmu_reset;
1244 	cpu_pmu->max_period	= (1LLU << 32) - 1;
1245 };
1246 
1247 static u32 __devinit armv7_read_num_pmnc_events(void)
1248 {
1249 	u32 nb_cnt;
1250 
1251 	/* Read the nb of CNTx counters supported from PMNC */
1252 	nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
1253 
1254 	/* Add the CPU cycles counter and return */
1255 	return nb_cnt + 1;
1256 }
1257 
1258 static int __devinit armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
1259 {
1260 	armv7pmu_init(cpu_pmu);
1261 	cpu_pmu->name		= "ARMv7 Cortex-A8";
1262 	cpu_pmu->map_event	= armv7_a8_map_event;
1263 	cpu_pmu->num_events	= armv7_read_num_pmnc_events();
1264 	return 0;
1265 }
1266 
1267 static int __devinit armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
1268 {
1269 	armv7pmu_init(cpu_pmu);
1270 	cpu_pmu->name		= "ARMv7 Cortex-A9";
1271 	cpu_pmu->map_event	= armv7_a9_map_event;
1272 	cpu_pmu->num_events	= armv7_read_num_pmnc_events();
1273 	return 0;
1274 }
1275 
1276 static int __devinit armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
1277 {
1278 	armv7pmu_init(cpu_pmu);
1279 	cpu_pmu->name		= "ARMv7 Cortex-A5";
1280 	cpu_pmu->map_event	= armv7_a5_map_event;
1281 	cpu_pmu->num_events	= armv7_read_num_pmnc_events();
1282 	return 0;
1283 }
1284 
1285 static int __devinit armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
1286 {
1287 	armv7pmu_init(cpu_pmu);
1288 	cpu_pmu->name		= "ARMv7 Cortex-A15";
1289 	cpu_pmu->map_event	= armv7_a15_map_event;
1290 	cpu_pmu->num_events	= armv7_read_num_pmnc_events();
1291 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
1292 	return 0;
1293 }
1294 
1295 static int __devinit armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
1296 {
1297 	armv7pmu_init(cpu_pmu);
1298 	cpu_pmu->name		= "ARMv7 Cortex-A7";
1299 	cpu_pmu->map_event	= armv7_a7_map_event;
1300 	cpu_pmu->num_events	= armv7_read_num_pmnc_events();
1301 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
1302 	return 0;
1303 }
1304 #else
1305 static inline int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
1306 {
1307 	return -ENODEV;
1308 }
1309 
1310 static inline int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
1311 {
1312 	return -ENODEV;
1313 }
1314 
1315 static inline int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
1316 {
1317 	return -ENODEV;
1318 }
1319 
1320 static inline int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
1321 {
1322 	return -ENODEV;
1323 }
1324 
1325 static inline int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
1326 {
1327 	return -ENODEV;
1328 }
1329 #endif	/* CONFIG_CPU_V7 */
1330