xref: /openbmc/linux/arch/arm/kernel/perf_event_v7.c (revision d33c88c6)
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 };
473 
474 /*
475  * Cortex-A15 HW events mapping
476  */
477 static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = {
478 	[PERF_COUNT_HW_CPU_CYCLES]		= ARMV7_PERFCTR_CPU_CYCLES,
479 	[PERF_COUNT_HW_INSTRUCTIONS]		= ARMV7_PERFCTR_INSTR_EXECUTED,
480 	[PERF_COUNT_HW_CACHE_REFERENCES]	= ARMV7_PERFCTR_L1_DCACHE_ACCESS,
481 	[PERF_COUNT_HW_CACHE_MISSES]		= ARMV7_PERFCTR_L1_DCACHE_REFILL,
482 	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= ARMV7_A15_PERFCTR_PC_WRITE_SPEC,
483 	[PERF_COUNT_HW_BRANCH_MISSES]		= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
484 	[PERF_COUNT_HW_BUS_CYCLES]		= ARMV7_PERFCTR_BUS_CYCLES,
485 	[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND]	= HW_OP_UNSUPPORTED,
486 	[PERF_COUNT_HW_STALLED_CYCLES_BACKEND]	= HW_OP_UNSUPPORTED,
487 };
488 
489 static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
490 					[PERF_COUNT_HW_CACHE_OP_MAX]
491 					[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
492 	[C(L1D)] = {
493 		[C(OP_READ)] = {
494 			[C(RESULT_ACCESS)]	= ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ,
495 			[C(RESULT_MISS)]	= ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ,
496 		},
497 		[C(OP_WRITE)] = {
498 			[C(RESULT_ACCESS)]	= ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE,
499 			[C(RESULT_MISS)]	= ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE,
500 		},
501 		[C(OP_PREFETCH)] = {
502 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
503 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
504 		},
505 	},
506 	[C(L1I)] = {
507 		/*
508 		 * Not all performance counters differentiate between read
509 		 * and write accesses/misses so we're not always strictly
510 		 * correct, but it's the best we can do. Writes and reads get
511 		 * combined in these cases.
512 		 */
513 		[C(OP_READ)] = {
514 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_ICACHE_ACCESS,
515 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L1_ICACHE_REFILL,
516 		},
517 		[C(OP_WRITE)] = {
518 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_ICACHE_ACCESS,
519 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L1_ICACHE_REFILL,
520 		},
521 		[C(OP_PREFETCH)] = {
522 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
523 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
524 		},
525 	},
526 	[C(LL)] = {
527 		[C(OP_READ)] = {
528 			[C(RESULT_ACCESS)]	= ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ,
529 			[C(RESULT_MISS)]	= ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ,
530 		},
531 		[C(OP_WRITE)] = {
532 			[C(RESULT_ACCESS)]	= ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE,
533 			[C(RESULT_MISS)]	= ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE,
534 		},
535 		[C(OP_PREFETCH)] = {
536 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
537 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
538 		},
539 	},
540 	[C(DTLB)] = {
541 		[C(OP_READ)] = {
542 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
543 			[C(RESULT_MISS)]	= ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ,
544 		},
545 		[C(OP_WRITE)] = {
546 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
547 			[C(RESULT_MISS)]	= ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE,
548 		},
549 		[C(OP_PREFETCH)] = {
550 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
551 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
552 		},
553 	},
554 	[C(ITLB)] = {
555 		[C(OP_READ)] = {
556 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
557 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_REFILL,
558 		},
559 		[C(OP_WRITE)] = {
560 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
561 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_REFILL,
562 		},
563 		[C(OP_PREFETCH)] = {
564 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
565 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
566 		},
567 	},
568 	[C(BPU)] = {
569 		[C(OP_READ)] = {
570 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_BRANCH_PRED,
571 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
572 		},
573 		[C(OP_WRITE)] = {
574 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_BRANCH_PRED,
575 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
576 		},
577 		[C(OP_PREFETCH)] = {
578 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
579 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
580 		},
581 	},
582 };
583 
584 /*
585  * Cortex-A7 HW events mapping
586  */
587 static const unsigned armv7_a7_perf_map[PERF_COUNT_HW_MAX] = {
588 	[PERF_COUNT_HW_CPU_CYCLES]		= ARMV7_PERFCTR_CPU_CYCLES,
589 	[PERF_COUNT_HW_INSTRUCTIONS]		= ARMV7_PERFCTR_INSTR_EXECUTED,
590 	[PERF_COUNT_HW_CACHE_REFERENCES]	= ARMV7_PERFCTR_L1_DCACHE_ACCESS,
591 	[PERF_COUNT_HW_CACHE_MISSES]		= ARMV7_PERFCTR_L1_DCACHE_REFILL,
592 	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= ARMV7_PERFCTR_PC_WRITE,
593 	[PERF_COUNT_HW_BRANCH_MISSES]		= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
594 	[PERF_COUNT_HW_BUS_CYCLES]		= ARMV7_PERFCTR_BUS_CYCLES,
595 	[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND]	= HW_OP_UNSUPPORTED,
596 	[PERF_COUNT_HW_STALLED_CYCLES_BACKEND]	= HW_OP_UNSUPPORTED,
597 };
598 
599 static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
600 					[PERF_COUNT_HW_CACHE_OP_MAX]
601 					[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
602 	[C(L1D)] = {
603 		/*
604 		 * The performance counters don't differentiate between read
605 		 * and write accesses/misses so this isn't strictly correct,
606 		 * but it's the best we can do. Writes and reads get
607 		 * combined.
608 		 */
609 		[C(OP_READ)] = {
610 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_DCACHE_ACCESS,
611 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L1_DCACHE_REFILL,
612 		},
613 		[C(OP_WRITE)] = {
614 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_DCACHE_ACCESS,
615 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L1_DCACHE_REFILL,
616 		},
617 		[C(OP_PREFETCH)] = {
618 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
619 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
620 		},
621 	},
622 	[C(L1I)] = {
623 		[C(OP_READ)] = {
624 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_ICACHE_ACCESS,
625 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L1_ICACHE_REFILL,
626 		},
627 		[C(OP_WRITE)] = {
628 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_ICACHE_ACCESS,
629 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L1_ICACHE_REFILL,
630 		},
631 		[C(OP_PREFETCH)] = {
632 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
633 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
634 		},
635 	},
636 	[C(LL)] = {
637 		[C(OP_READ)] = {
638 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L2_CACHE_ACCESS,
639 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L2_CACHE_REFILL,
640 		},
641 		[C(OP_WRITE)] = {
642 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L2_CACHE_ACCESS,
643 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L2_CACHE_REFILL,
644 		},
645 		[C(OP_PREFETCH)] = {
646 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
647 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
648 		},
649 	},
650 	[C(DTLB)] = {
651 		[C(OP_READ)] = {
652 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
653 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DTLB_REFILL,
654 		},
655 		[C(OP_WRITE)] = {
656 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
657 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DTLB_REFILL,
658 		},
659 		[C(OP_PREFETCH)] = {
660 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
661 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
662 		},
663 	},
664 	[C(ITLB)] = {
665 		[C(OP_READ)] = {
666 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
667 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_REFILL,
668 		},
669 		[C(OP_WRITE)] = {
670 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
671 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_REFILL,
672 		},
673 		[C(OP_PREFETCH)] = {
674 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
675 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
676 		},
677 	},
678 	[C(BPU)] = {
679 		[C(OP_READ)] = {
680 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_BRANCH_PRED,
681 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
682 		},
683 		[C(OP_WRITE)] = {
684 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_BRANCH_PRED,
685 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
686 		},
687 		[C(OP_PREFETCH)] = {
688 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
689 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
690 		},
691 	},
692 	[C(NODE)] = {
693 		[C(OP_READ)] = {
694 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
695 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
696 		},
697 		[C(OP_WRITE)] = {
698 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
699 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
700 		},
701 		[C(OP_PREFETCH)] = {
702 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
703 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
704 		},
705 	},
706 };
707 
708 /*
709  * Perf Events' indices
710  */
711 #define	ARMV7_IDX_CYCLE_COUNTER	0
712 #define	ARMV7_IDX_COUNTER0	1
713 #define	ARMV7_IDX_COUNTER_LAST	(ARMV7_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1)
714 
715 #define	ARMV7_MAX_COUNTERS	32
716 #define	ARMV7_COUNTER_MASK	(ARMV7_MAX_COUNTERS - 1)
717 
718 /*
719  * ARMv7 low level PMNC access
720  */
721 
722 /*
723  * Perf Event to low level counters mapping
724  */
725 #define	ARMV7_IDX_TO_COUNTER(x)	\
726 	(((x) - ARMV7_IDX_COUNTER0) & ARMV7_COUNTER_MASK)
727 
728 /*
729  * Per-CPU PMNC: config reg
730  */
731 #define ARMV7_PMNC_E		(1 << 0) /* Enable all counters */
732 #define ARMV7_PMNC_P		(1 << 1) /* Reset all counters */
733 #define ARMV7_PMNC_C		(1 << 2) /* Cycle counter reset */
734 #define ARMV7_PMNC_D		(1 << 3) /* CCNT counts every 64th cpu cycle */
735 #define ARMV7_PMNC_X		(1 << 4) /* Export to ETM */
736 #define ARMV7_PMNC_DP		(1 << 5) /* Disable CCNT if non-invasive debug*/
737 #define	ARMV7_PMNC_N_SHIFT	11	 /* Number of counters supported */
738 #define	ARMV7_PMNC_N_MASK	0x1f
739 #define	ARMV7_PMNC_MASK		0x3f	 /* Mask for writable bits */
740 
741 /*
742  * FLAG: counters overflow flag status reg
743  */
744 #define	ARMV7_FLAG_MASK		0xffffffff	/* Mask for writable bits */
745 #define	ARMV7_OVERFLOWED_MASK	ARMV7_FLAG_MASK
746 
747 /*
748  * PMXEVTYPER: Event selection reg
749  */
750 #define	ARMV7_EVTYPE_MASK	0xc00000ff	/* Mask for writable bits */
751 #define	ARMV7_EVTYPE_EVENT	0xff		/* Mask for EVENT bits */
752 
753 /*
754  * Event filters for PMUv2
755  */
756 #define	ARMV7_EXCLUDE_PL1	(1 << 31)
757 #define	ARMV7_EXCLUDE_USER	(1 << 30)
758 #define	ARMV7_INCLUDE_HYP	(1 << 27)
759 
760 static inline u32 armv7_pmnc_read(void)
761 {
762 	u32 val;
763 	asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
764 	return val;
765 }
766 
767 static inline void armv7_pmnc_write(u32 val)
768 {
769 	val &= ARMV7_PMNC_MASK;
770 	isb();
771 	asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
772 }
773 
774 static inline int armv7_pmnc_has_overflowed(u32 pmnc)
775 {
776 	return pmnc & ARMV7_OVERFLOWED_MASK;
777 }
778 
779 static inline int armv7_pmnc_counter_valid(int idx)
780 {
781 	return idx >= ARMV7_IDX_CYCLE_COUNTER && idx <= ARMV7_IDX_COUNTER_LAST;
782 }
783 
784 static inline int armv7_pmnc_counter_has_overflowed(u32 pmnc, int idx)
785 {
786 	int ret = 0;
787 	u32 counter;
788 
789 	if (!armv7_pmnc_counter_valid(idx)) {
790 		pr_err("CPU%u checking wrong counter %d overflow status\n",
791 			smp_processor_id(), idx);
792 	} else {
793 		counter = ARMV7_IDX_TO_COUNTER(idx);
794 		ret = pmnc & BIT(counter);
795 	}
796 
797 	return ret;
798 }
799 
800 static inline int armv7_pmnc_select_counter(int idx)
801 {
802 	u32 counter;
803 
804 	if (!armv7_pmnc_counter_valid(idx)) {
805 		pr_err("CPU%u selecting wrong PMNC counter %d\n",
806 			smp_processor_id(), idx);
807 		return -EINVAL;
808 	}
809 
810 	counter = ARMV7_IDX_TO_COUNTER(idx);
811 	asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (counter));
812 	isb();
813 
814 	return idx;
815 }
816 
817 static inline u32 armv7pmu_read_counter(int idx)
818 {
819 	u32 value = 0;
820 
821 	if (!armv7_pmnc_counter_valid(idx))
822 		pr_err("CPU%u reading wrong counter %d\n",
823 			smp_processor_id(), idx);
824 	else if (idx == ARMV7_IDX_CYCLE_COUNTER)
825 		asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
826 	else if (armv7_pmnc_select_counter(idx) == idx)
827 		asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (value));
828 
829 	return value;
830 }
831 
832 static inline void armv7pmu_write_counter(int idx, u32 value)
833 {
834 	if (!armv7_pmnc_counter_valid(idx))
835 		pr_err("CPU%u writing wrong counter %d\n",
836 			smp_processor_id(), idx);
837 	else if (idx == ARMV7_IDX_CYCLE_COUNTER)
838 		asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
839 	else if (armv7_pmnc_select_counter(idx) == idx)
840 		asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (value));
841 }
842 
843 static inline void armv7_pmnc_write_evtsel(int idx, u32 val)
844 {
845 	if (armv7_pmnc_select_counter(idx) == idx) {
846 		val &= ARMV7_EVTYPE_MASK;
847 		asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
848 	}
849 }
850 
851 static inline int armv7_pmnc_enable_counter(int idx)
852 {
853 	u32 counter;
854 
855 	if (!armv7_pmnc_counter_valid(idx)) {
856 		pr_err("CPU%u enabling wrong PMNC counter %d\n",
857 			smp_processor_id(), idx);
858 		return -EINVAL;
859 	}
860 
861 	counter = ARMV7_IDX_TO_COUNTER(idx);
862 	asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(counter)));
863 	return idx;
864 }
865 
866 static inline int armv7_pmnc_disable_counter(int idx)
867 {
868 	u32 counter;
869 
870 	if (!armv7_pmnc_counter_valid(idx)) {
871 		pr_err("CPU%u disabling wrong PMNC counter %d\n",
872 			smp_processor_id(), idx);
873 		return -EINVAL;
874 	}
875 
876 	counter = ARMV7_IDX_TO_COUNTER(idx);
877 	asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(counter)));
878 	return idx;
879 }
880 
881 static inline int armv7_pmnc_enable_intens(int idx)
882 {
883 	u32 counter;
884 
885 	if (!armv7_pmnc_counter_valid(idx)) {
886 		pr_err("CPU%u enabling wrong PMNC counter IRQ enable %d\n",
887 			smp_processor_id(), idx);
888 		return -EINVAL;
889 	}
890 
891 	counter = ARMV7_IDX_TO_COUNTER(idx);
892 	asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(counter)));
893 	return idx;
894 }
895 
896 static inline int armv7_pmnc_disable_intens(int idx)
897 {
898 	u32 counter;
899 
900 	if (!armv7_pmnc_counter_valid(idx)) {
901 		pr_err("CPU%u disabling wrong PMNC counter IRQ enable %d\n",
902 			smp_processor_id(), idx);
903 		return -EINVAL;
904 	}
905 
906 	counter = ARMV7_IDX_TO_COUNTER(idx);
907 	asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(counter)));
908 	return idx;
909 }
910 
911 static inline u32 armv7_pmnc_getreset_flags(void)
912 {
913 	u32 val;
914 
915 	/* Read */
916 	asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
917 
918 	/* Write to clear flags */
919 	val &= ARMV7_FLAG_MASK;
920 	asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
921 
922 	return val;
923 }
924 
925 #ifdef DEBUG
926 static void armv7_pmnc_dump_regs(void)
927 {
928 	u32 val;
929 	unsigned int cnt;
930 
931 	printk(KERN_INFO "PMNC registers dump:\n");
932 
933 	asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
934 	printk(KERN_INFO "PMNC  =0x%08x\n", val);
935 
936 	asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
937 	printk(KERN_INFO "CNTENS=0x%08x\n", val);
938 
939 	asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
940 	printk(KERN_INFO "INTENS=0x%08x\n", val);
941 
942 	asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
943 	printk(KERN_INFO "FLAGS =0x%08x\n", val);
944 
945 	asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
946 	printk(KERN_INFO "SELECT=0x%08x\n", val);
947 
948 	asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
949 	printk(KERN_INFO "CCNT  =0x%08x\n", val);
950 
951 	for (cnt = ARMV7_IDX_COUNTER0; cnt <= ARMV7_IDX_COUNTER_LAST; cnt++) {
952 		armv7_pmnc_select_counter(cnt);
953 		asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
954 		printk(KERN_INFO "CNT[%d] count =0x%08x\n",
955 			ARMV7_IDX_TO_COUNTER(cnt), val);
956 		asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
957 		printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n",
958 			ARMV7_IDX_TO_COUNTER(cnt), val);
959 	}
960 }
961 #endif
962 
963 static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)
964 {
965 	unsigned long flags;
966 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
967 
968 	/*
969 	 * Enable counter and interrupt, and set the counter to count
970 	 * the event that we're interested in.
971 	 */
972 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
973 
974 	/*
975 	 * Disable counter
976 	 */
977 	armv7_pmnc_disable_counter(idx);
978 
979 	/*
980 	 * Set event (if destined for PMNx counters)
981 	 * We only need to set the event for the cycle counter if we
982 	 * have the ability to perform event filtering.
983 	 */
984 	if (armv7pmu.set_event_filter || idx != ARMV7_IDX_CYCLE_COUNTER)
985 		armv7_pmnc_write_evtsel(idx, hwc->config_base);
986 
987 	/*
988 	 * Enable interrupt for this counter
989 	 */
990 	armv7_pmnc_enable_intens(idx);
991 
992 	/*
993 	 * Enable counter
994 	 */
995 	armv7_pmnc_enable_counter(idx);
996 
997 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
998 }
999 
1000 static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx)
1001 {
1002 	unsigned long flags;
1003 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
1004 
1005 	/*
1006 	 * Disable counter and interrupt
1007 	 */
1008 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
1009 
1010 	/*
1011 	 * Disable counter
1012 	 */
1013 	armv7_pmnc_disable_counter(idx);
1014 
1015 	/*
1016 	 * Disable interrupt for this counter
1017 	 */
1018 	armv7_pmnc_disable_intens(idx);
1019 
1020 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1021 }
1022 
1023 static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
1024 {
1025 	u32 pmnc;
1026 	struct perf_sample_data data;
1027 	struct pmu_hw_events *cpuc;
1028 	struct pt_regs *regs;
1029 	int idx;
1030 
1031 	/*
1032 	 * Get and reset the IRQ flags
1033 	 */
1034 	pmnc = armv7_pmnc_getreset_flags();
1035 
1036 	/*
1037 	 * Did an overflow occur?
1038 	 */
1039 	if (!armv7_pmnc_has_overflowed(pmnc))
1040 		return IRQ_NONE;
1041 
1042 	/*
1043 	 * Handle the counter(s) overflow(s)
1044 	 */
1045 	regs = get_irq_regs();
1046 
1047 	perf_sample_data_init(&data, 0);
1048 
1049 	cpuc = &__get_cpu_var(cpu_hw_events);
1050 	for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
1051 		struct perf_event *event = cpuc->events[idx];
1052 		struct hw_perf_event *hwc;
1053 
1054 		/*
1055 		 * We have a single interrupt for all counters. Check that
1056 		 * each counter has overflowed before we process it.
1057 		 */
1058 		if (!armv7_pmnc_counter_has_overflowed(pmnc, idx))
1059 			continue;
1060 
1061 		hwc = &event->hw;
1062 		armpmu_event_update(event, hwc, idx, 1);
1063 		data.period = event->hw.last_period;
1064 		if (!armpmu_event_set_period(event, hwc, idx))
1065 			continue;
1066 
1067 		if (perf_event_overflow(event, &data, regs))
1068 			cpu_pmu->disable(hwc, idx);
1069 	}
1070 
1071 	/*
1072 	 * Handle the pending perf events.
1073 	 *
1074 	 * Note: this call *must* be run with interrupts disabled. For
1075 	 * platforms that can have the PMU interrupts raised as an NMI, this
1076 	 * will not work.
1077 	 */
1078 	irq_work_run();
1079 
1080 	return IRQ_HANDLED;
1081 }
1082 
1083 static void armv7pmu_start(void)
1084 {
1085 	unsigned long flags;
1086 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
1087 
1088 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
1089 	/* Enable all counters */
1090 	armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
1091 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1092 }
1093 
1094 static void armv7pmu_stop(void)
1095 {
1096 	unsigned long flags;
1097 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
1098 
1099 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
1100 	/* Disable all counters */
1101 	armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E);
1102 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1103 }
1104 
1105 static int armv7pmu_get_event_idx(struct pmu_hw_events *cpuc,
1106 				  struct hw_perf_event *event)
1107 {
1108 	int idx;
1109 	unsigned long evtype = event->config_base & ARMV7_EVTYPE_EVENT;
1110 
1111 	/* Always place a cycle counter into the cycle counter. */
1112 	if (evtype == ARMV7_PERFCTR_CPU_CYCLES) {
1113 		if (test_and_set_bit(ARMV7_IDX_CYCLE_COUNTER, cpuc->used_mask))
1114 			return -EAGAIN;
1115 
1116 		return ARMV7_IDX_CYCLE_COUNTER;
1117 	}
1118 
1119 	/*
1120 	 * For anything other than a cycle counter, try and use
1121 	 * the events counters
1122 	 */
1123 	for (idx = ARMV7_IDX_COUNTER0; idx < cpu_pmu->num_events; ++idx) {
1124 		if (!test_and_set_bit(idx, cpuc->used_mask))
1125 			return idx;
1126 	}
1127 
1128 	/* The counters are all in use. */
1129 	return -EAGAIN;
1130 }
1131 
1132 /*
1133  * Add an event filter to a given event. This will only work for PMUv2 PMUs.
1134  */
1135 static int armv7pmu_set_event_filter(struct hw_perf_event *event,
1136 				     struct perf_event_attr *attr)
1137 {
1138 	unsigned long config_base = 0;
1139 
1140 	if (attr->exclude_idle)
1141 		return -EPERM;
1142 	if (attr->exclude_user)
1143 		config_base |= ARMV7_EXCLUDE_USER;
1144 	if (attr->exclude_kernel)
1145 		config_base |= ARMV7_EXCLUDE_PL1;
1146 	if (!attr->exclude_hv)
1147 		config_base |= ARMV7_INCLUDE_HYP;
1148 
1149 	/*
1150 	 * Install the filter into config_base as this is used to
1151 	 * construct the event type.
1152 	 */
1153 	event->config_base = config_base;
1154 
1155 	return 0;
1156 }
1157 
1158 static void armv7pmu_reset(void *info)
1159 {
1160 	u32 idx, nb_cnt = cpu_pmu->num_events;
1161 
1162 	/* The counter and interrupt enable registers are unknown at reset. */
1163 	for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx)
1164 		armv7pmu_disable_event(NULL, idx);
1165 
1166 	/* Initialize & Reset PMNC: C and P bits */
1167 	armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
1168 }
1169 
1170 static int armv7_a8_map_event(struct perf_event *event)
1171 {
1172 	return map_cpu_event(event, &armv7_a8_perf_map,
1173 				&armv7_a8_perf_cache_map, 0xFF);
1174 }
1175 
1176 static int armv7_a9_map_event(struct perf_event *event)
1177 {
1178 	return map_cpu_event(event, &armv7_a9_perf_map,
1179 				&armv7_a9_perf_cache_map, 0xFF);
1180 }
1181 
1182 static int armv7_a5_map_event(struct perf_event *event)
1183 {
1184 	return map_cpu_event(event, &armv7_a5_perf_map,
1185 				&armv7_a5_perf_cache_map, 0xFF);
1186 }
1187 
1188 static int armv7_a15_map_event(struct perf_event *event)
1189 {
1190 	return map_cpu_event(event, &armv7_a15_perf_map,
1191 				&armv7_a15_perf_cache_map, 0xFF);
1192 }
1193 
1194 static int armv7_a7_map_event(struct perf_event *event)
1195 {
1196 	return map_cpu_event(event, &armv7_a7_perf_map,
1197 				&armv7_a7_perf_cache_map, 0xFF);
1198 }
1199 
1200 static struct arm_pmu armv7pmu = {
1201 	.handle_irq		= armv7pmu_handle_irq,
1202 	.enable			= armv7pmu_enable_event,
1203 	.disable		= armv7pmu_disable_event,
1204 	.read_counter		= armv7pmu_read_counter,
1205 	.write_counter		= armv7pmu_write_counter,
1206 	.get_event_idx		= armv7pmu_get_event_idx,
1207 	.start			= armv7pmu_start,
1208 	.stop			= armv7pmu_stop,
1209 	.reset			= armv7pmu_reset,
1210 	.max_period		= (1LLU << 32) - 1,
1211 };
1212 
1213 static u32 __init armv7_read_num_pmnc_events(void)
1214 {
1215 	u32 nb_cnt;
1216 
1217 	/* Read the nb of CNTx counters supported from PMNC */
1218 	nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
1219 
1220 	/* Add the CPU cycles counter and return */
1221 	return nb_cnt + 1;
1222 }
1223 
1224 static struct arm_pmu *__init armv7_a8_pmu_init(void)
1225 {
1226 	armv7pmu.id		= ARM_PERF_PMU_ID_CA8;
1227 	armv7pmu.name		= "ARMv7 Cortex-A8";
1228 	armv7pmu.map_event	= armv7_a8_map_event;
1229 	armv7pmu.num_events	= armv7_read_num_pmnc_events();
1230 	return &armv7pmu;
1231 }
1232 
1233 static struct arm_pmu *__init armv7_a9_pmu_init(void)
1234 {
1235 	armv7pmu.id		= ARM_PERF_PMU_ID_CA9;
1236 	armv7pmu.name		= "ARMv7 Cortex-A9";
1237 	armv7pmu.map_event	= armv7_a9_map_event;
1238 	armv7pmu.num_events	= armv7_read_num_pmnc_events();
1239 	return &armv7pmu;
1240 }
1241 
1242 static struct arm_pmu *__init armv7_a5_pmu_init(void)
1243 {
1244 	armv7pmu.id		= ARM_PERF_PMU_ID_CA5;
1245 	armv7pmu.name		= "ARMv7 Cortex-A5";
1246 	armv7pmu.map_event	= armv7_a5_map_event;
1247 	armv7pmu.num_events	= armv7_read_num_pmnc_events();
1248 	return &armv7pmu;
1249 }
1250 
1251 static struct arm_pmu *__init armv7_a15_pmu_init(void)
1252 {
1253 	armv7pmu.id		= ARM_PERF_PMU_ID_CA15;
1254 	armv7pmu.name		= "ARMv7 Cortex-A15";
1255 	armv7pmu.map_event	= armv7_a15_map_event;
1256 	armv7pmu.num_events	= armv7_read_num_pmnc_events();
1257 	armv7pmu.set_event_filter = armv7pmu_set_event_filter;
1258 	return &armv7pmu;
1259 }
1260 
1261 static struct arm_pmu *__init armv7_a7_pmu_init(void)
1262 {
1263 	armv7pmu.id		= ARM_PERF_PMU_ID_CA7;
1264 	armv7pmu.name		= "ARMv7 Cortex-A7";
1265 	armv7pmu.map_event	= armv7_a7_map_event;
1266 	armv7pmu.num_events	= armv7_read_num_pmnc_events();
1267 	armv7pmu.set_event_filter = armv7pmu_set_event_filter;
1268 	return &armv7pmu;
1269 }
1270 #else
1271 static struct arm_pmu *__init armv7_a8_pmu_init(void)
1272 {
1273 	return NULL;
1274 }
1275 
1276 static struct arm_pmu *__init armv7_a9_pmu_init(void)
1277 {
1278 	return NULL;
1279 }
1280 
1281 static struct arm_pmu *__init armv7_a5_pmu_init(void)
1282 {
1283 	return NULL;
1284 }
1285 
1286 static struct arm_pmu *__init armv7_a15_pmu_init(void)
1287 {
1288 	return NULL;
1289 }
1290 
1291 static struct arm_pmu *__init armv7_a7_pmu_init(void)
1292 {
1293 	return NULL;
1294 }
1295 #endif	/* CONFIG_CPU_V7 */
1296