xref: /openbmc/linux/arch/arm/kernel/perf_event_v7.c (revision 565d76cb)
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 /* Common ARMv7 event types */
21 enum armv7_perf_types {
22 	ARMV7_PERFCTR_PMNC_SW_INCR		= 0x00,
23 	ARMV7_PERFCTR_IFETCH_MISS		= 0x01,
24 	ARMV7_PERFCTR_ITLB_MISS			= 0x02,
25 	ARMV7_PERFCTR_DCACHE_REFILL		= 0x03,
26 	ARMV7_PERFCTR_DCACHE_ACCESS		= 0x04,
27 	ARMV7_PERFCTR_DTLB_REFILL		= 0x05,
28 	ARMV7_PERFCTR_DREAD			= 0x06,
29 	ARMV7_PERFCTR_DWRITE			= 0x07,
30 
31 	ARMV7_PERFCTR_EXC_TAKEN			= 0x09,
32 	ARMV7_PERFCTR_EXC_EXECUTED		= 0x0A,
33 	ARMV7_PERFCTR_CID_WRITE			= 0x0B,
34 	/* ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
35 	 * It counts:
36 	 *  - all branch instructions,
37 	 *  - instructions that explicitly write the PC,
38 	 *  - exception generating instructions.
39 	 */
40 	ARMV7_PERFCTR_PC_WRITE			= 0x0C,
41 	ARMV7_PERFCTR_PC_IMM_BRANCH		= 0x0D,
42 	ARMV7_PERFCTR_UNALIGNED_ACCESS		= 0x0F,
43 	ARMV7_PERFCTR_PC_BRANCH_MIS_PRED	= 0x10,
44 	ARMV7_PERFCTR_CLOCK_CYCLES		= 0x11,
45 
46 	ARMV7_PERFCTR_PC_BRANCH_MIS_USED	= 0x12,
47 
48 	ARMV7_PERFCTR_CPU_CYCLES		= 0xFF
49 };
50 
51 /* ARMv7 Cortex-A8 specific event types */
52 enum armv7_a8_perf_types {
53 	ARMV7_PERFCTR_INSTR_EXECUTED		= 0x08,
54 
55 	ARMV7_PERFCTR_PC_PROC_RETURN		= 0x0E,
56 
57 	ARMV7_PERFCTR_WRITE_BUFFER_FULL		= 0x40,
58 	ARMV7_PERFCTR_L2_STORE_MERGED		= 0x41,
59 	ARMV7_PERFCTR_L2_STORE_BUFF		= 0x42,
60 	ARMV7_PERFCTR_L2_ACCESS			= 0x43,
61 	ARMV7_PERFCTR_L2_CACH_MISS		= 0x44,
62 	ARMV7_PERFCTR_AXI_READ_CYCLES		= 0x45,
63 	ARMV7_PERFCTR_AXI_WRITE_CYCLES		= 0x46,
64 	ARMV7_PERFCTR_MEMORY_REPLAY		= 0x47,
65 	ARMV7_PERFCTR_UNALIGNED_ACCESS_REPLAY	= 0x48,
66 	ARMV7_PERFCTR_L1_DATA_MISS		= 0x49,
67 	ARMV7_PERFCTR_L1_INST_MISS		= 0x4A,
68 	ARMV7_PERFCTR_L1_DATA_COLORING		= 0x4B,
69 	ARMV7_PERFCTR_L1_NEON_DATA		= 0x4C,
70 	ARMV7_PERFCTR_L1_NEON_CACH_DATA		= 0x4D,
71 	ARMV7_PERFCTR_L2_NEON			= 0x4E,
72 	ARMV7_PERFCTR_L2_NEON_HIT		= 0x4F,
73 	ARMV7_PERFCTR_L1_INST			= 0x50,
74 	ARMV7_PERFCTR_PC_RETURN_MIS_PRED	= 0x51,
75 	ARMV7_PERFCTR_PC_BRANCH_FAILED		= 0x52,
76 	ARMV7_PERFCTR_PC_BRANCH_TAKEN		= 0x53,
77 	ARMV7_PERFCTR_PC_BRANCH_EXECUTED	= 0x54,
78 	ARMV7_PERFCTR_OP_EXECUTED		= 0x55,
79 	ARMV7_PERFCTR_CYCLES_INST_STALL		= 0x56,
80 	ARMV7_PERFCTR_CYCLES_INST		= 0x57,
81 	ARMV7_PERFCTR_CYCLES_NEON_DATA_STALL	= 0x58,
82 	ARMV7_PERFCTR_CYCLES_NEON_INST_STALL	= 0x59,
83 	ARMV7_PERFCTR_NEON_CYCLES		= 0x5A,
84 
85 	ARMV7_PERFCTR_PMU0_EVENTS		= 0x70,
86 	ARMV7_PERFCTR_PMU1_EVENTS		= 0x71,
87 	ARMV7_PERFCTR_PMU_EVENTS		= 0x72,
88 };
89 
90 /* ARMv7 Cortex-A9 specific event types */
91 enum armv7_a9_perf_types {
92 	ARMV7_PERFCTR_JAVA_HW_BYTECODE_EXEC	= 0x40,
93 	ARMV7_PERFCTR_JAVA_SW_BYTECODE_EXEC	= 0x41,
94 	ARMV7_PERFCTR_JAZELLE_BRANCH_EXEC	= 0x42,
95 
96 	ARMV7_PERFCTR_COHERENT_LINE_MISS	= 0x50,
97 	ARMV7_PERFCTR_COHERENT_LINE_HIT		= 0x51,
98 
99 	ARMV7_PERFCTR_ICACHE_DEP_STALL_CYCLES	= 0x60,
100 	ARMV7_PERFCTR_DCACHE_DEP_STALL_CYCLES	= 0x61,
101 	ARMV7_PERFCTR_TLB_MISS_DEP_STALL_CYCLES	= 0x62,
102 	ARMV7_PERFCTR_STREX_EXECUTED_PASSED	= 0x63,
103 	ARMV7_PERFCTR_STREX_EXECUTED_FAILED	= 0x64,
104 	ARMV7_PERFCTR_DATA_EVICTION		= 0x65,
105 	ARMV7_PERFCTR_ISSUE_STAGE_NO_INST	= 0x66,
106 	ARMV7_PERFCTR_ISSUE_STAGE_EMPTY		= 0x67,
107 	ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE	= 0x68,
108 
109 	ARMV7_PERFCTR_PREDICTABLE_FUNCT_RETURNS	= 0x6E,
110 
111 	ARMV7_PERFCTR_MAIN_UNIT_EXECUTED_INST	= 0x70,
112 	ARMV7_PERFCTR_SECOND_UNIT_EXECUTED_INST	= 0x71,
113 	ARMV7_PERFCTR_LD_ST_UNIT_EXECUTED_INST	= 0x72,
114 	ARMV7_PERFCTR_FP_EXECUTED_INST		= 0x73,
115 	ARMV7_PERFCTR_NEON_EXECUTED_INST	= 0x74,
116 
117 	ARMV7_PERFCTR_PLD_FULL_DEP_STALL_CYCLES	= 0x80,
118 	ARMV7_PERFCTR_DATA_WR_DEP_STALL_CYCLES	= 0x81,
119 	ARMV7_PERFCTR_ITLB_MISS_DEP_STALL_CYCLES	= 0x82,
120 	ARMV7_PERFCTR_DTLB_MISS_DEP_STALL_CYCLES	= 0x83,
121 	ARMV7_PERFCTR_MICRO_ITLB_MISS_DEP_STALL_CYCLES	= 0x84,
122 	ARMV7_PERFCTR_MICRO_DTLB_MISS_DEP_STALL_CYCLES	= 0x85,
123 	ARMV7_PERFCTR_DMB_DEP_STALL_CYCLES	= 0x86,
124 
125 	ARMV7_PERFCTR_INTGR_CLK_ENABLED_CYCLES	= 0x8A,
126 	ARMV7_PERFCTR_DATA_ENGINE_CLK_EN_CYCLES	= 0x8B,
127 
128 	ARMV7_PERFCTR_ISB_INST			= 0x90,
129 	ARMV7_PERFCTR_DSB_INST			= 0x91,
130 	ARMV7_PERFCTR_DMB_INST			= 0x92,
131 	ARMV7_PERFCTR_EXT_INTERRUPTS		= 0x93,
132 
133 	ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_COMPLETED	= 0xA0,
134 	ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_SKIPPED	= 0xA1,
135 	ARMV7_PERFCTR_PLE_FIFO_FLUSH		= 0xA2,
136 	ARMV7_PERFCTR_PLE_RQST_COMPLETED	= 0xA3,
137 	ARMV7_PERFCTR_PLE_FIFO_OVERFLOW		= 0xA4,
138 	ARMV7_PERFCTR_PLE_RQST_PROG		= 0xA5
139 };
140 
141 /*
142  * Cortex-A8 HW events mapping
143  *
144  * The hardware events that we support. We do support cache operations but
145  * we have harvard caches and no way to combine instruction and data
146  * accesses/misses in hardware.
147  */
148 static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = {
149 	[PERF_COUNT_HW_CPU_CYCLES]	    = ARMV7_PERFCTR_CPU_CYCLES,
150 	[PERF_COUNT_HW_INSTRUCTIONS]	    = ARMV7_PERFCTR_INSTR_EXECUTED,
151 	[PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
152 	[PERF_COUNT_HW_CACHE_MISSES]	    = HW_OP_UNSUPPORTED,
153 	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
154 	[PERF_COUNT_HW_BRANCH_MISSES]	    = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
155 	[PERF_COUNT_HW_BUS_CYCLES]	    = ARMV7_PERFCTR_CLOCK_CYCLES,
156 };
157 
158 static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
159 					  [PERF_COUNT_HW_CACHE_OP_MAX]
160 					  [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
161 	[C(L1D)] = {
162 		/*
163 		 * The performance counters don't differentiate between read
164 		 * and write accesses/misses so this isn't strictly correct,
165 		 * but it's the best we can do. Writes and reads get
166 		 * combined.
167 		 */
168 		[C(OP_READ)] = {
169 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_DCACHE_ACCESS,
170 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DCACHE_REFILL,
171 		},
172 		[C(OP_WRITE)] = {
173 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_DCACHE_ACCESS,
174 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DCACHE_REFILL,
175 		},
176 		[C(OP_PREFETCH)] = {
177 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
178 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
179 		},
180 	},
181 	[C(L1I)] = {
182 		[C(OP_READ)] = {
183 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_INST,
184 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L1_INST_MISS,
185 		},
186 		[C(OP_WRITE)] = {
187 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_INST,
188 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L1_INST_MISS,
189 		},
190 		[C(OP_PREFETCH)] = {
191 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
192 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
193 		},
194 	},
195 	[C(LL)] = {
196 		[C(OP_READ)] = {
197 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L2_ACCESS,
198 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L2_CACH_MISS,
199 		},
200 		[C(OP_WRITE)] = {
201 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L2_ACCESS,
202 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L2_CACH_MISS,
203 		},
204 		[C(OP_PREFETCH)] = {
205 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
206 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
207 		},
208 	},
209 	[C(DTLB)] = {
210 		/*
211 		 * Only ITLB misses and DTLB refills are supported.
212 		 * If users want the DTLB refills misses a raw counter
213 		 * must be used.
214 		 */
215 		[C(OP_READ)] = {
216 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
217 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DTLB_REFILL,
218 		},
219 		[C(OP_WRITE)] = {
220 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
221 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DTLB_REFILL,
222 		},
223 		[C(OP_PREFETCH)] = {
224 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
225 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
226 		},
227 	},
228 	[C(ITLB)] = {
229 		[C(OP_READ)] = {
230 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
231 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_MISS,
232 		},
233 		[C(OP_WRITE)] = {
234 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
235 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_MISS,
236 		},
237 		[C(OP_PREFETCH)] = {
238 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
239 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
240 		},
241 	},
242 	[C(BPU)] = {
243 		[C(OP_READ)] = {
244 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_WRITE,
245 			[C(RESULT_MISS)]
246 					= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
247 		},
248 		[C(OP_WRITE)] = {
249 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_WRITE,
250 			[C(RESULT_MISS)]
251 					= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
252 		},
253 		[C(OP_PREFETCH)] = {
254 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
255 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
256 		},
257 	},
258 };
259 
260 /*
261  * Cortex-A9 HW events mapping
262  */
263 static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
264 	[PERF_COUNT_HW_CPU_CYCLES]	    = ARMV7_PERFCTR_CPU_CYCLES,
265 	[PERF_COUNT_HW_INSTRUCTIONS]	    =
266 					ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE,
267 	[PERF_COUNT_HW_CACHE_REFERENCES]    = ARMV7_PERFCTR_COHERENT_LINE_HIT,
268 	[PERF_COUNT_HW_CACHE_MISSES]	    = ARMV7_PERFCTR_COHERENT_LINE_MISS,
269 	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
270 	[PERF_COUNT_HW_BRANCH_MISSES]	    = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
271 	[PERF_COUNT_HW_BUS_CYCLES]	    = ARMV7_PERFCTR_CLOCK_CYCLES,
272 };
273 
274 static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
275 					  [PERF_COUNT_HW_CACHE_OP_MAX]
276 					  [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
277 	[C(L1D)] = {
278 		/*
279 		 * The performance counters don't differentiate between read
280 		 * and write accesses/misses so this isn't strictly correct,
281 		 * but it's the best we can do. Writes and reads get
282 		 * combined.
283 		 */
284 		[C(OP_READ)] = {
285 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_DCACHE_ACCESS,
286 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DCACHE_REFILL,
287 		},
288 		[C(OP_WRITE)] = {
289 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_DCACHE_ACCESS,
290 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DCACHE_REFILL,
291 		},
292 		[C(OP_PREFETCH)] = {
293 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
294 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
295 		},
296 	},
297 	[C(L1I)] = {
298 		[C(OP_READ)] = {
299 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
300 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_IFETCH_MISS,
301 		},
302 		[C(OP_WRITE)] = {
303 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
304 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_IFETCH_MISS,
305 		},
306 		[C(OP_PREFETCH)] = {
307 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
308 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
309 		},
310 	},
311 	[C(LL)] = {
312 		[C(OP_READ)] = {
313 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
314 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
315 		},
316 		[C(OP_WRITE)] = {
317 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
318 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
319 		},
320 		[C(OP_PREFETCH)] = {
321 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
322 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
323 		},
324 	},
325 	[C(DTLB)] = {
326 		/*
327 		 * Only ITLB misses and DTLB refills are supported.
328 		 * If users want the DTLB refills misses a raw counter
329 		 * must be used.
330 		 */
331 		[C(OP_READ)] = {
332 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
333 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DTLB_REFILL,
334 		},
335 		[C(OP_WRITE)] = {
336 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
337 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DTLB_REFILL,
338 		},
339 		[C(OP_PREFETCH)] = {
340 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
341 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
342 		},
343 	},
344 	[C(ITLB)] = {
345 		[C(OP_READ)] = {
346 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
347 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_MISS,
348 		},
349 		[C(OP_WRITE)] = {
350 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
351 			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_MISS,
352 		},
353 		[C(OP_PREFETCH)] = {
354 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
355 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
356 		},
357 	},
358 	[C(BPU)] = {
359 		[C(OP_READ)] = {
360 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_WRITE,
361 			[C(RESULT_MISS)]
362 					= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
363 		},
364 		[C(OP_WRITE)] = {
365 			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_WRITE,
366 			[C(RESULT_MISS)]
367 					= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
368 		},
369 		[C(OP_PREFETCH)] = {
370 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
371 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
372 		},
373 	},
374 };
375 
376 /*
377  * Perf Events counters
378  */
379 enum armv7_counters {
380 	ARMV7_CYCLE_COUNTER		= 1,	/* Cycle counter */
381 	ARMV7_COUNTER0			= 2,	/* First event counter */
382 };
383 
384 /*
385  * The cycle counter is ARMV7_CYCLE_COUNTER.
386  * The first event counter is ARMV7_COUNTER0.
387  * The last event counter is (ARMV7_COUNTER0 + armpmu->num_events - 1).
388  */
389 #define	ARMV7_COUNTER_LAST	(ARMV7_COUNTER0 + armpmu->num_events - 1)
390 
391 /*
392  * ARMv7 low level PMNC access
393  */
394 
395 /*
396  * Per-CPU PMNC: config reg
397  */
398 #define ARMV7_PMNC_E		(1 << 0) /* Enable all counters */
399 #define ARMV7_PMNC_P		(1 << 1) /* Reset all counters */
400 #define ARMV7_PMNC_C		(1 << 2) /* Cycle counter reset */
401 #define ARMV7_PMNC_D		(1 << 3) /* CCNT counts every 64th cpu cycle */
402 #define ARMV7_PMNC_X		(1 << 4) /* Export to ETM */
403 #define ARMV7_PMNC_DP		(1 << 5) /* Disable CCNT if non-invasive debug*/
404 #define	ARMV7_PMNC_N_SHIFT	11	 /* Number of counters supported */
405 #define	ARMV7_PMNC_N_MASK	0x1f
406 #define	ARMV7_PMNC_MASK		0x3f	 /* Mask for writable bits */
407 
408 /*
409  * Available counters
410  */
411 #define ARMV7_CNT0		0	/* First event counter */
412 #define ARMV7_CCNT		31	/* Cycle counter */
413 
414 /* Perf Event to low level counters mapping */
415 #define ARMV7_EVENT_CNT_TO_CNTx	(ARMV7_COUNTER0 - ARMV7_CNT0)
416 
417 /*
418  * CNTENS: counters enable reg
419  */
420 #define ARMV7_CNTENS_P(idx)	(1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
421 #define ARMV7_CNTENS_C		(1 << ARMV7_CCNT)
422 
423 /*
424  * CNTENC: counters disable reg
425  */
426 #define ARMV7_CNTENC_P(idx)	(1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
427 #define ARMV7_CNTENC_C		(1 << ARMV7_CCNT)
428 
429 /*
430  * INTENS: counters overflow interrupt enable reg
431  */
432 #define ARMV7_INTENS_P(idx)	(1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
433 #define ARMV7_INTENS_C		(1 << ARMV7_CCNT)
434 
435 /*
436  * INTENC: counters overflow interrupt disable reg
437  */
438 #define ARMV7_INTENC_P(idx)	(1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
439 #define ARMV7_INTENC_C		(1 << ARMV7_CCNT)
440 
441 /*
442  * EVTSEL: Event selection reg
443  */
444 #define	ARMV7_EVTSEL_MASK	0xff		/* Mask for writable bits */
445 
446 /*
447  * SELECT: Counter selection reg
448  */
449 #define	ARMV7_SELECT_MASK	0x1f		/* Mask for writable bits */
450 
451 /*
452  * FLAG: counters overflow flag status reg
453  */
454 #define ARMV7_FLAG_P(idx)	(1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
455 #define ARMV7_FLAG_C		(1 << ARMV7_CCNT)
456 #define	ARMV7_FLAG_MASK		0xffffffff	/* Mask for writable bits */
457 #define	ARMV7_OVERFLOWED_MASK	ARMV7_FLAG_MASK
458 
459 static inline unsigned long armv7_pmnc_read(void)
460 {
461 	u32 val;
462 	asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
463 	return val;
464 }
465 
466 static inline void armv7_pmnc_write(unsigned long val)
467 {
468 	val &= ARMV7_PMNC_MASK;
469 	asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
470 }
471 
472 static inline int armv7_pmnc_has_overflowed(unsigned long pmnc)
473 {
474 	return pmnc & ARMV7_OVERFLOWED_MASK;
475 }
476 
477 static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc,
478 					enum armv7_counters counter)
479 {
480 	int ret = 0;
481 
482 	if (counter == ARMV7_CYCLE_COUNTER)
483 		ret = pmnc & ARMV7_FLAG_C;
484 	else if ((counter >= ARMV7_COUNTER0) && (counter <= ARMV7_COUNTER_LAST))
485 		ret = pmnc & ARMV7_FLAG_P(counter);
486 	else
487 		pr_err("CPU%u checking wrong counter %d overflow status\n",
488 			smp_processor_id(), counter);
489 
490 	return ret;
491 }
492 
493 static inline int armv7_pmnc_select_counter(unsigned int idx)
494 {
495 	u32 val;
496 
497 	if ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST)) {
498 		pr_err("CPU%u selecting wrong PMNC counter"
499 			" %d\n", smp_processor_id(), idx);
500 		return -1;
501 	}
502 
503 	val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK;
504 	asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
505 
506 	return idx;
507 }
508 
509 static inline u32 armv7pmu_read_counter(int idx)
510 {
511 	unsigned long value = 0;
512 
513 	if (idx == ARMV7_CYCLE_COUNTER)
514 		asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
515 	else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
516 		if (armv7_pmnc_select_counter(idx) == idx)
517 			asm volatile("mrc p15, 0, %0, c9, c13, 2"
518 				     : "=r" (value));
519 	} else
520 		pr_err("CPU%u reading wrong counter %d\n",
521 			smp_processor_id(), idx);
522 
523 	return value;
524 }
525 
526 static inline void armv7pmu_write_counter(int idx, u32 value)
527 {
528 	if (idx == ARMV7_CYCLE_COUNTER)
529 		asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
530 	else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
531 		if (armv7_pmnc_select_counter(idx) == idx)
532 			asm volatile("mcr p15, 0, %0, c9, c13, 2"
533 				     : : "r" (value));
534 	} else
535 		pr_err("CPU%u writing wrong counter %d\n",
536 			smp_processor_id(), idx);
537 }
538 
539 static inline void armv7_pmnc_write_evtsel(unsigned int idx, u32 val)
540 {
541 	if (armv7_pmnc_select_counter(idx) == idx) {
542 		val &= ARMV7_EVTSEL_MASK;
543 		asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
544 	}
545 }
546 
547 static inline u32 armv7_pmnc_enable_counter(unsigned int idx)
548 {
549 	u32 val;
550 
551 	if ((idx != ARMV7_CYCLE_COUNTER) &&
552 	    ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
553 		pr_err("CPU%u enabling wrong PMNC counter"
554 			" %d\n", smp_processor_id(), idx);
555 		return -1;
556 	}
557 
558 	if (idx == ARMV7_CYCLE_COUNTER)
559 		val = ARMV7_CNTENS_C;
560 	else
561 		val = ARMV7_CNTENS_P(idx);
562 
563 	asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val));
564 
565 	return idx;
566 }
567 
568 static inline u32 armv7_pmnc_disable_counter(unsigned int idx)
569 {
570 	u32 val;
571 
572 
573 	if ((idx != ARMV7_CYCLE_COUNTER) &&
574 	    ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
575 		pr_err("CPU%u disabling wrong PMNC counter"
576 			" %d\n", smp_processor_id(), idx);
577 		return -1;
578 	}
579 
580 	if (idx == ARMV7_CYCLE_COUNTER)
581 		val = ARMV7_CNTENC_C;
582 	else
583 		val = ARMV7_CNTENC_P(idx);
584 
585 	asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val));
586 
587 	return idx;
588 }
589 
590 static inline u32 armv7_pmnc_enable_intens(unsigned int idx)
591 {
592 	u32 val;
593 
594 	if ((idx != ARMV7_CYCLE_COUNTER) &&
595 	    ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
596 		pr_err("CPU%u enabling wrong PMNC counter"
597 			" interrupt enable %d\n", smp_processor_id(), idx);
598 		return -1;
599 	}
600 
601 	if (idx == ARMV7_CYCLE_COUNTER)
602 		val = ARMV7_INTENS_C;
603 	else
604 		val = ARMV7_INTENS_P(idx);
605 
606 	asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val));
607 
608 	return idx;
609 }
610 
611 static inline u32 armv7_pmnc_disable_intens(unsigned int idx)
612 {
613 	u32 val;
614 
615 	if ((idx != ARMV7_CYCLE_COUNTER) &&
616 	    ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
617 		pr_err("CPU%u disabling wrong PMNC counter"
618 			" interrupt enable %d\n", smp_processor_id(), idx);
619 		return -1;
620 	}
621 
622 	if (idx == ARMV7_CYCLE_COUNTER)
623 		val = ARMV7_INTENC_C;
624 	else
625 		val = ARMV7_INTENC_P(idx);
626 
627 	asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (val));
628 
629 	return idx;
630 }
631 
632 static inline u32 armv7_pmnc_getreset_flags(void)
633 {
634 	u32 val;
635 
636 	/* Read */
637 	asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
638 
639 	/* Write to clear flags */
640 	val &= ARMV7_FLAG_MASK;
641 	asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
642 
643 	return val;
644 }
645 
646 #ifdef DEBUG
647 static void armv7_pmnc_dump_regs(void)
648 {
649 	u32 val;
650 	unsigned int cnt;
651 
652 	printk(KERN_INFO "PMNC registers dump:\n");
653 
654 	asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
655 	printk(KERN_INFO "PMNC  =0x%08x\n", val);
656 
657 	asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
658 	printk(KERN_INFO "CNTENS=0x%08x\n", val);
659 
660 	asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
661 	printk(KERN_INFO "INTENS=0x%08x\n", val);
662 
663 	asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
664 	printk(KERN_INFO "FLAGS =0x%08x\n", val);
665 
666 	asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
667 	printk(KERN_INFO "SELECT=0x%08x\n", val);
668 
669 	asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
670 	printk(KERN_INFO "CCNT  =0x%08x\n", val);
671 
672 	for (cnt = ARMV7_COUNTER0; cnt < ARMV7_COUNTER_LAST; cnt++) {
673 		armv7_pmnc_select_counter(cnt);
674 		asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
675 		printk(KERN_INFO "CNT[%d] count =0x%08x\n",
676 			cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
677 		asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
678 		printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n",
679 			cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
680 	}
681 }
682 #endif
683 
684 static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)
685 {
686 	unsigned long flags;
687 
688 	/*
689 	 * Enable counter and interrupt, and set the counter to count
690 	 * the event that we're interested in.
691 	 */
692 	raw_spin_lock_irqsave(&pmu_lock, flags);
693 
694 	/*
695 	 * Disable counter
696 	 */
697 	armv7_pmnc_disable_counter(idx);
698 
699 	/*
700 	 * Set event (if destined for PMNx counters)
701 	 * We don't need to set the event if it's a cycle count
702 	 */
703 	if (idx != ARMV7_CYCLE_COUNTER)
704 		armv7_pmnc_write_evtsel(idx, hwc->config_base);
705 
706 	/*
707 	 * Enable interrupt for this counter
708 	 */
709 	armv7_pmnc_enable_intens(idx);
710 
711 	/*
712 	 * Enable counter
713 	 */
714 	armv7_pmnc_enable_counter(idx);
715 
716 	raw_spin_unlock_irqrestore(&pmu_lock, flags);
717 }
718 
719 static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx)
720 {
721 	unsigned long flags;
722 
723 	/*
724 	 * Disable counter and interrupt
725 	 */
726 	raw_spin_lock_irqsave(&pmu_lock, flags);
727 
728 	/*
729 	 * Disable counter
730 	 */
731 	armv7_pmnc_disable_counter(idx);
732 
733 	/*
734 	 * Disable interrupt for this counter
735 	 */
736 	armv7_pmnc_disable_intens(idx);
737 
738 	raw_spin_unlock_irqrestore(&pmu_lock, flags);
739 }
740 
741 static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
742 {
743 	unsigned long pmnc;
744 	struct perf_sample_data data;
745 	struct cpu_hw_events *cpuc;
746 	struct pt_regs *regs;
747 	int idx;
748 
749 	/*
750 	 * Get and reset the IRQ flags
751 	 */
752 	pmnc = armv7_pmnc_getreset_flags();
753 
754 	/*
755 	 * Did an overflow occur?
756 	 */
757 	if (!armv7_pmnc_has_overflowed(pmnc))
758 		return IRQ_NONE;
759 
760 	/*
761 	 * Handle the counter(s) overflow(s)
762 	 */
763 	regs = get_irq_regs();
764 
765 	perf_sample_data_init(&data, 0);
766 
767 	cpuc = &__get_cpu_var(cpu_hw_events);
768 	for (idx = 0; idx <= armpmu->num_events; ++idx) {
769 		struct perf_event *event = cpuc->events[idx];
770 		struct hw_perf_event *hwc;
771 
772 		if (!test_bit(idx, cpuc->active_mask))
773 			continue;
774 
775 		/*
776 		 * We have a single interrupt for all counters. Check that
777 		 * each counter has overflowed before we process it.
778 		 */
779 		if (!armv7_pmnc_counter_has_overflowed(pmnc, idx))
780 			continue;
781 
782 		hwc = &event->hw;
783 		armpmu_event_update(event, hwc, idx);
784 		data.period = event->hw.last_period;
785 		if (!armpmu_event_set_period(event, hwc, idx))
786 			continue;
787 
788 		if (perf_event_overflow(event, 0, &data, regs))
789 			armpmu->disable(hwc, idx);
790 	}
791 
792 	/*
793 	 * Handle the pending perf events.
794 	 *
795 	 * Note: this call *must* be run with interrupts disabled. For
796 	 * platforms that can have the PMU interrupts raised as an NMI, this
797 	 * will not work.
798 	 */
799 	irq_work_run();
800 
801 	return IRQ_HANDLED;
802 }
803 
804 static void armv7pmu_start(void)
805 {
806 	unsigned long flags;
807 
808 	raw_spin_lock_irqsave(&pmu_lock, flags);
809 	/* Enable all counters */
810 	armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
811 	raw_spin_unlock_irqrestore(&pmu_lock, flags);
812 }
813 
814 static void armv7pmu_stop(void)
815 {
816 	unsigned long flags;
817 
818 	raw_spin_lock_irqsave(&pmu_lock, flags);
819 	/* Disable all counters */
820 	armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E);
821 	raw_spin_unlock_irqrestore(&pmu_lock, flags);
822 }
823 
824 static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc,
825 				  struct hw_perf_event *event)
826 {
827 	int idx;
828 
829 	/* Always place a cycle counter into the cycle counter. */
830 	if (event->config_base == ARMV7_PERFCTR_CPU_CYCLES) {
831 		if (test_and_set_bit(ARMV7_CYCLE_COUNTER, cpuc->used_mask))
832 			return -EAGAIN;
833 
834 		return ARMV7_CYCLE_COUNTER;
835 	} else {
836 		/*
837 		 * For anything other than a cycle counter, try and use
838 		 * the events counters
839 		 */
840 		for (idx = ARMV7_COUNTER0; idx <= armpmu->num_events; ++idx) {
841 			if (!test_and_set_bit(idx, cpuc->used_mask))
842 				return idx;
843 		}
844 
845 		/* The counters are all in use. */
846 		return -EAGAIN;
847 	}
848 }
849 
850 static struct arm_pmu armv7pmu = {
851 	.handle_irq		= armv7pmu_handle_irq,
852 	.enable			= armv7pmu_enable_event,
853 	.disable		= armv7pmu_disable_event,
854 	.read_counter		= armv7pmu_read_counter,
855 	.write_counter		= armv7pmu_write_counter,
856 	.get_event_idx		= armv7pmu_get_event_idx,
857 	.start			= armv7pmu_start,
858 	.stop			= armv7pmu_stop,
859 	.raw_event_mask		= 0xFF,
860 	.max_period		= (1LLU << 32) - 1,
861 };
862 
863 static u32 __init armv7_reset_read_pmnc(void)
864 {
865 	u32 nb_cnt;
866 
867 	/* Initialize & Reset PMNC: C and P bits */
868 	armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
869 
870 	/* Read the nb of CNTx counters supported from PMNC */
871 	nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
872 
873 	/* Add the CPU cycles counter and return */
874 	return nb_cnt + 1;
875 }
876 
877 static const struct arm_pmu *__init armv7_a8_pmu_init(void)
878 {
879 	armv7pmu.id		= ARM_PERF_PMU_ID_CA8;
880 	armv7pmu.name		= "ARMv7 Cortex-A8";
881 	armv7pmu.cache_map	= &armv7_a8_perf_cache_map;
882 	armv7pmu.event_map	= &armv7_a8_perf_map;
883 	armv7pmu.num_events	= armv7_reset_read_pmnc();
884 	return &armv7pmu;
885 }
886 
887 static const struct arm_pmu *__init armv7_a9_pmu_init(void)
888 {
889 	armv7pmu.id		= ARM_PERF_PMU_ID_CA9;
890 	armv7pmu.name		= "ARMv7 Cortex-A9";
891 	armv7pmu.cache_map	= &armv7_a9_perf_cache_map;
892 	armv7pmu.event_map	= &armv7_a9_perf_map;
893 	armv7pmu.num_events	= armv7_reset_read_pmnc();
894 	return &armv7pmu;
895 }
896 #else
897 static const struct arm_pmu *__init armv7_a8_pmu_init(void)
898 {
899 	return NULL;
900 }
901 
902 static const struct arm_pmu *__init armv7_a9_pmu_init(void)
903 {
904 	return NULL;
905 }
906 #endif	/* CONFIG_CPU_V7 */
907