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