xref: /openbmc/linux/arch/arm/kernel/perf_event_v6.c (revision 81d67439)
1 /*
2  * ARMv6 Performance counter handling code.
3  *
4  * Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles
5  *
6  * ARMv6 has 2 configurable performance counters and a single cycle counter.
7  * They all share a single reset bit but can be written to zero so we can use
8  * that for a reset.
9  *
10  * The counters can't be individually enabled or disabled so when we remove
11  * one event and replace it with another we could get spurious counts from the
12  * wrong event. However, we can take advantage of the fact that the
13  * performance counters can export events to the event bus, and the event bus
14  * itself can be monitored. This requires that we *don't* export the events to
15  * the event bus. The procedure for disabling a configurable counter is:
16  *	- change the counter to count the ETMEXTOUT[0] signal (0x20). This
17  *	  effectively stops the counter from counting.
18  *	- disable the counter's interrupt generation (each counter has it's
19  *	  own interrupt enable bit).
20  * Once stopped, the counter value can be written as 0 to reset.
21  *
22  * To enable a counter:
23  *	- enable the counter's interrupt generation.
24  *	- set the new event type.
25  *
26  * Note: the dedicated cycle counter only counts cycles and can't be
27  * enabled/disabled independently of the others. When we want to disable the
28  * cycle counter, we have to just disable the interrupt reporting and start
29  * ignoring that counter. When re-enabling, we have to reset the value and
30  * enable the interrupt.
31  */
32 
33 #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
34 enum armv6_perf_types {
35 	ARMV6_PERFCTR_ICACHE_MISS	    = 0x0,
36 	ARMV6_PERFCTR_IBUF_STALL	    = 0x1,
37 	ARMV6_PERFCTR_DDEP_STALL	    = 0x2,
38 	ARMV6_PERFCTR_ITLB_MISS		    = 0x3,
39 	ARMV6_PERFCTR_DTLB_MISS		    = 0x4,
40 	ARMV6_PERFCTR_BR_EXEC		    = 0x5,
41 	ARMV6_PERFCTR_BR_MISPREDICT	    = 0x6,
42 	ARMV6_PERFCTR_INSTR_EXEC	    = 0x7,
43 	ARMV6_PERFCTR_DCACHE_HIT	    = 0x9,
44 	ARMV6_PERFCTR_DCACHE_ACCESS	    = 0xA,
45 	ARMV6_PERFCTR_DCACHE_MISS	    = 0xB,
46 	ARMV6_PERFCTR_DCACHE_WBACK	    = 0xC,
47 	ARMV6_PERFCTR_SW_PC_CHANGE	    = 0xD,
48 	ARMV6_PERFCTR_MAIN_TLB_MISS	    = 0xF,
49 	ARMV6_PERFCTR_EXPL_D_ACCESS	    = 0x10,
50 	ARMV6_PERFCTR_LSU_FULL_STALL	    = 0x11,
51 	ARMV6_PERFCTR_WBUF_DRAINED	    = 0x12,
52 	ARMV6_PERFCTR_CPU_CYCLES	    = 0xFF,
53 	ARMV6_PERFCTR_NOP		    = 0x20,
54 };
55 
56 enum armv6_counters {
57 	ARMV6_CYCLE_COUNTER = 1,
58 	ARMV6_COUNTER0,
59 	ARMV6_COUNTER1,
60 };
61 
62 /*
63  * The hardware events that we support. We do support cache operations but
64  * we have harvard caches and no way to combine instruction and data
65  * accesses/misses in hardware.
66  */
67 static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = {
68 	[PERF_COUNT_HW_CPU_CYCLES]	    = ARMV6_PERFCTR_CPU_CYCLES,
69 	[PERF_COUNT_HW_INSTRUCTIONS]	    = ARMV6_PERFCTR_INSTR_EXEC,
70 	[PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
71 	[PERF_COUNT_HW_CACHE_MISSES]	    = HW_OP_UNSUPPORTED,
72 	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC,
73 	[PERF_COUNT_HW_BRANCH_MISSES]	    = ARMV6_PERFCTR_BR_MISPREDICT,
74 	[PERF_COUNT_HW_BUS_CYCLES]	    = HW_OP_UNSUPPORTED,
75 };
76 
77 static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
78 					  [PERF_COUNT_HW_CACHE_OP_MAX]
79 					  [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
80 	[C(L1D)] = {
81 		/*
82 		 * The performance counters don't differentiate between read
83 		 * and write accesses/misses so this isn't strictly correct,
84 		 * but it's the best we can do. Writes and reads get
85 		 * combined.
86 		 */
87 		[C(OP_READ)] = {
88 			[C(RESULT_ACCESS)]	= ARMV6_PERFCTR_DCACHE_ACCESS,
89 			[C(RESULT_MISS)]	= ARMV6_PERFCTR_DCACHE_MISS,
90 		},
91 		[C(OP_WRITE)] = {
92 			[C(RESULT_ACCESS)]	= ARMV6_PERFCTR_DCACHE_ACCESS,
93 			[C(RESULT_MISS)]	= ARMV6_PERFCTR_DCACHE_MISS,
94 		},
95 		[C(OP_PREFETCH)] = {
96 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
97 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
98 		},
99 	},
100 	[C(L1I)] = {
101 		[C(OP_READ)] = {
102 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
103 			[C(RESULT_MISS)]	= ARMV6_PERFCTR_ICACHE_MISS,
104 		},
105 		[C(OP_WRITE)] = {
106 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
107 			[C(RESULT_MISS)]	= ARMV6_PERFCTR_ICACHE_MISS,
108 		},
109 		[C(OP_PREFETCH)] = {
110 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
111 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
112 		},
113 	},
114 	[C(LL)] = {
115 		[C(OP_READ)] = {
116 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
117 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
118 		},
119 		[C(OP_WRITE)] = {
120 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
121 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
122 		},
123 		[C(OP_PREFETCH)] = {
124 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
125 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
126 		},
127 	},
128 	[C(DTLB)] = {
129 		/*
130 		 * The ARM performance counters can count micro DTLB misses,
131 		 * micro ITLB misses and main TLB misses. There isn't an event
132 		 * for TLB misses, so use the micro misses here and if users
133 		 * want the main TLB misses they can use a raw counter.
134 		 */
135 		[C(OP_READ)] = {
136 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
137 			[C(RESULT_MISS)]	= ARMV6_PERFCTR_DTLB_MISS,
138 		},
139 		[C(OP_WRITE)] = {
140 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
141 			[C(RESULT_MISS)]	= ARMV6_PERFCTR_DTLB_MISS,
142 		},
143 		[C(OP_PREFETCH)] = {
144 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
145 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
146 		},
147 	},
148 	[C(ITLB)] = {
149 		[C(OP_READ)] = {
150 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
151 			[C(RESULT_MISS)]	= ARMV6_PERFCTR_ITLB_MISS,
152 		},
153 		[C(OP_WRITE)] = {
154 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
155 			[C(RESULT_MISS)]	= ARMV6_PERFCTR_ITLB_MISS,
156 		},
157 		[C(OP_PREFETCH)] = {
158 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
159 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
160 		},
161 	},
162 	[C(BPU)] = {
163 		[C(OP_READ)] = {
164 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
165 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
166 		},
167 		[C(OP_WRITE)] = {
168 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
169 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
170 		},
171 		[C(OP_PREFETCH)] = {
172 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
173 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
174 		},
175 	},
176 	[C(NODE)] = {
177 		[C(OP_READ)] = {
178 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
179 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
180 		},
181 		[C(OP_WRITE)] = {
182 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
183 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
184 		},
185 		[C(OP_PREFETCH)] = {
186 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
187 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
188 		},
189 	},
190 };
191 
192 enum armv6mpcore_perf_types {
193 	ARMV6MPCORE_PERFCTR_ICACHE_MISS	    = 0x0,
194 	ARMV6MPCORE_PERFCTR_IBUF_STALL	    = 0x1,
195 	ARMV6MPCORE_PERFCTR_DDEP_STALL	    = 0x2,
196 	ARMV6MPCORE_PERFCTR_ITLB_MISS	    = 0x3,
197 	ARMV6MPCORE_PERFCTR_DTLB_MISS	    = 0x4,
198 	ARMV6MPCORE_PERFCTR_BR_EXEC	    = 0x5,
199 	ARMV6MPCORE_PERFCTR_BR_NOTPREDICT   = 0x6,
200 	ARMV6MPCORE_PERFCTR_BR_MISPREDICT   = 0x7,
201 	ARMV6MPCORE_PERFCTR_INSTR_EXEC	    = 0x8,
202 	ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS = 0xA,
203 	ARMV6MPCORE_PERFCTR_DCACHE_RDMISS   = 0xB,
204 	ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS = 0xC,
205 	ARMV6MPCORE_PERFCTR_DCACHE_WRMISS   = 0xD,
206 	ARMV6MPCORE_PERFCTR_DCACHE_EVICTION = 0xE,
207 	ARMV6MPCORE_PERFCTR_SW_PC_CHANGE    = 0xF,
208 	ARMV6MPCORE_PERFCTR_MAIN_TLB_MISS   = 0x10,
209 	ARMV6MPCORE_PERFCTR_EXPL_MEM_ACCESS = 0x11,
210 	ARMV6MPCORE_PERFCTR_LSU_FULL_STALL  = 0x12,
211 	ARMV6MPCORE_PERFCTR_WBUF_DRAINED    = 0x13,
212 	ARMV6MPCORE_PERFCTR_CPU_CYCLES	    = 0xFF,
213 };
214 
215 /*
216  * The hardware events that we support. We do support cache operations but
217  * we have harvard caches and no way to combine instruction and data
218  * accesses/misses in hardware.
219  */
220 static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX] = {
221 	[PERF_COUNT_HW_CPU_CYCLES]	    = ARMV6MPCORE_PERFCTR_CPU_CYCLES,
222 	[PERF_COUNT_HW_INSTRUCTIONS]	    = ARMV6MPCORE_PERFCTR_INSTR_EXEC,
223 	[PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
224 	[PERF_COUNT_HW_CACHE_MISSES]	    = HW_OP_UNSUPPORTED,
225 	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC,
226 	[PERF_COUNT_HW_BRANCH_MISSES]	    = ARMV6MPCORE_PERFCTR_BR_MISPREDICT,
227 	[PERF_COUNT_HW_BUS_CYCLES]	    = HW_OP_UNSUPPORTED,
228 };
229 
230 static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
231 					[PERF_COUNT_HW_CACHE_OP_MAX]
232 					[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
233 	[C(L1D)] = {
234 		[C(OP_READ)] = {
235 			[C(RESULT_ACCESS)]  =
236 				ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS,
237 			[C(RESULT_MISS)]    =
238 				ARMV6MPCORE_PERFCTR_DCACHE_RDMISS,
239 		},
240 		[C(OP_WRITE)] = {
241 			[C(RESULT_ACCESS)]  =
242 				ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS,
243 			[C(RESULT_MISS)]    =
244 				ARMV6MPCORE_PERFCTR_DCACHE_WRMISS,
245 		},
246 		[C(OP_PREFETCH)] = {
247 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
248 			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
249 		},
250 	},
251 	[C(L1I)] = {
252 		[C(OP_READ)] = {
253 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
254 			[C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
255 		},
256 		[C(OP_WRITE)] = {
257 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
258 			[C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
259 		},
260 		[C(OP_PREFETCH)] = {
261 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
262 			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
263 		},
264 	},
265 	[C(LL)] = {
266 		[C(OP_READ)] = {
267 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
268 			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
269 		},
270 		[C(OP_WRITE)] = {
271 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
272 			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
273 		},
274 		[C(OP_PREFETCH)] = {
275 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
276 			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
277 		},
278 	},
279 	[C(DTLB)] = {
280 		/*
281 		 * The ARM performance counters can count micro DTLB misses,
282 		 * micro ITLB misses and main TLB misses. There isn't an event
283 		 * for TLB misses, so use the micro misses here and if users
284 		 * want the main TLB misses they can use a raw counter.
285 		 */
286 		[C(OP_READ)] = {
287 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
288 			[C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_DTLB_MISS,
289 		},
290 		[C(OP_WRITE)] = {
291 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
292 			[C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_DTLB_MISS,
293 		},
294 		[C(OP_PREFETCH)] = {
295 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
296 			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
297 		},
298 	},
299 	[C(ITLB)] = {
300 		[C(OP_READ)] = {
301 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
302 			[C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_ITLB_MISS,
303 		},
304 		[C(OP_WRITE)] = {
305 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
306 			[C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_ITLB_MISS,
307 		},
308 		[C(OP_PREFETCH)] = {
309 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
310 			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
311 		},
312 	},
313 	[C(BPU)] = {
314 		[C(OP_READ)] = {
315 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
316 			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
317 		},
318 		[C(OP_WRITE)] = {
319 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
320 			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
321 		},
322 		[C(OP_PREFETCH)] = {
323 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
324 			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
325 		},
326 	},
327 	[C(NODE)] = {
328 		[C(OP_READ)] = {
329 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
330 			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
331 		},
332 		[C(OP_WRITE)] = {
333 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
334 			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
335 		},
336 		[C(OP_PREFETCH)] = {
337 			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
338 			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
339 		},
340 	},
341 };
342 
343 static inline unsigned long
344 armv6_pmcr_read(void)
345 {
346 	u32 val;
347 	asm volatile("mrc   p15, 0, %0, c15, c12, 0" : "=r"(val));
348 	return val;
349 }
350 
351 static inline void
352 armv6_pmcr_write(unsigned long val)
353 {
354 	asm volatile("mcr   p15, 0, %0, c15, c12, 0" : : "r"(val));
355 }
356 
357 #define ARMV6_PMCR_ENABLE		(1 << 0)
358 #define ARMV6_PMCR_CTR01_RESET		(1 << 1)
359 #define ARMV6_PMCR_CCOUNT_RESET		(1 << 2)
360 #define ARMV6_PMCR_CCOUNT_DIV		(1 << 3)
361 #define ARMV6_PMCR_COUNT0_IEN		(1 << 4)
362 #define ARMV6_PMCR_COUNT1_IEN		(1 << 5)
363 #define ARMV6_PMCR_CCOUNT_IEN		(1 << 6)
364 #define ARMV6_PMCR_COUNT0_OVERFLOW	(1 << 8)
365 #define ARMV6_PMCR_COUNT1_OVERFLOW	(1 << 9)
366 #define ARMV6_PMCR_CCOUNT_OVERFLOW	(1 << 10)
367 #define ARMV6_PMCR_EVT_COUNT0_SHIFT	20
368 #define ARMV6_PMCR_EVT_COUNT0_MASK	(0xFF << ARMV6_PMCR_EVT_COUNT0_SHIFT)
369 #define ARMV6_PMCR_EVT_COUNT1_SHIFT	12
370 #define ARMV6_PMCR_EVT_COUNT1_MASK	(0xFF << ARMV6_PMCR_EVT_COUNT1_SHIFT)
371 
372 #define ARMV6_PMCR_OVERFLOWED_MASK \
373 	(ARMV6_PMCR_COUNT0_OVERFLOW | ARMV6_PMCR_COUNT1_OVERFLOW | \
374 	 ARMV6_PMCR_CCOUNT_OVERFLOW)
375 
376 static inline int
377 armv6_pmcr_has_overflowed(unsigned long pmcr)
378 {
379 	return pmcr & ARMV6_PMCR_OVERFLOWED_MASK;
380 }
381 
382 static inline int
383 armv6_pmcr_counter_has_overflowed(unsigned long pmcr,
384 				  enum armv6_counters counter)
385 {
386 	int ret = 0;
387 
388 	if (ARMV6_CYCLE_COUNTER == counter)
389 		ret = pmcr & ARMV6_PMCR_CCOUNT_OVERFLOW;
390 	else if (ARMV6_COUNTER0 == counter)
391 		ret = pmcr & ARMV6_PMCR_COUNT0_OVERFLOW;
392 	else if (ARMV6_COUNTER1 == counter)
393 		ret = pmcr & ARMV6_PMCR_COUNT1_OVERFLOW;
394 	else
395 		WARN_ONCE(1, "invalid counter number (%d)\n", counter);
396 
397 	return ret;
398 }
399 
400 static inline u32
401 armv6pmu_read_counter(int counter)
402 {
403 	unsigned long value = 0;
404 
405 	if (ARMV6_CYCLE_COUNTER == counter)
406 		asm volatile("mrc   p15, 0, %0, c15, c12, 1" : "=r"(value));
407 	else if (ARMV6_COUNTER0 == counter)
408 		asm volatile("mrc   p15, 0, %0, c15, c12, 2" : "=r"(value));
409 	else if (ARMV6_COUNTER1 == counter)
410 		asm volatile("mrc   p15, 0, %0, c15, c12, 3" : "=r"(value));
411 	else
412 		WARN_ONCE(1, "invalid counter number (%d)\n", counter);
413 
414 	return value;
415 }
416 
417 static inline void
418 armv6pmu_write_counter(int counter,
419 		       u32 value)
420 {
421 	if (ARMV6_CYCLE_COUNTER == counter)
422 		asm volatile("mcr   p15, 0, %0, c15, c12, 1" : : "r"(value));
423 	else if (ARMV6_COUNTER0 == counter)
424 		asm volatile("mcr   p15, 0, %0, c15, c12, 2" : : "r"(value));
425 	else if (ARMV6_COUNTER1 == counter)
426 		asm volatile("mcr   p15, 0, %0, c15, c12, 3" : : "r"(value));
427 	else
428 		WARN_ONCE(1, "invalid counter number (%d)\n", counter);
429 }
430 
431 static void
432 armv6pmu_enable_event(struct hw_perf_event *hwc,
433 		      int idx)
434 {
435 	unsigned long val, mask, evt, flags;
436 
437 	if (ARMV6_CYCLE_COUNTER == idx) {
438 		mask	= 0;
439 		evt	= ARMV6_PMCR_CCOUNT_IEN;
440 	} else if (ARMV6_COUNTER0 == idx) {
441 		mask	= ARMV6_PMCR_EVT_COUNT0_MASK;
442 		evt	= (hwc->config_base << ARMV6_PMCR_EVT_COUNT0_SHIFT) |
443 			  ARMV6_PMCR_COUNT0_IEN;
444 	} else if (ARMV6_COUNTER1 == idx) {
445 		mask	= ARMV6_PMCR_EVT_COUNT1_MASK;
446 		evt	= (hwc->config_base << ARMV6_PMCR_EVT_COUNT1_SHIFT) |
447 			  ARMV6_PMCR_COUNT1_IEN;
448 	} else {
449 		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
450 		return;
451 	}
452 
453 	/*
454 	 * Mask out the current event and set the counter to count the event
455 	 * that we're interested in.
456 	 */
457 	raw_spin_lock_irqsave(&pmu_lock, flags);
458 	val = armv6_pmcr_read();
459 	val &= ~mask;
460 	val |= evt;
461 	armv6_pmcr_write(val);
462 	raw_spin_unlock_irqrestore(&pmu_lock, flags);
463 }
464 
465 static irqreturn_t
466 armv6pmu_handle_irq(int irq_num,
467 		    void *dev)
468 {
469 	unsigned long pmcr = armv6_pmcr_read();
470 	struct perf_sample_data data;
471 	struct cpu_hw_events *cpuc;
472 	struct pt_regs *regs;
473 	int idx;
474 
475 	if (!armv6_pmcr_has_overflowed(pmcr))
476 		return IRQ_NONE;
477 
478 	regs = get_irq_regs();
479 
480 	/*
481 	 * The interrupts are cleared by writing the overflow flags back to
482 	 * the control register. All of the other bits don't have any effect
483 	 * if they are rewritten, so write the whole value back.
484 	 */
485 	armv6_pmcr_write(pmcr);
486 
487 	perf_sample_data_init(&data, 0);
488 
489 	cpuc = &__get_cpu_var(cpu_hw_events);
490 	for (idx = 0; idx <= armpmu->num_events; ++idx) {
491 		struct perf_event *event = cpuc->events[idx];
492 		struct hw_perf_event *hwc;
493 
494 		if (!test_bit(idx, cpuc->active_mask))
495 			continue;
496 
497 		/*
498 		 * We have a single interrupt for all counters. Check that
499 		 * each counter has overflowed before we process it.
500 		 */
501 		if (!armv6_pmcr_counter_has_overflowed(pmcr, idx))
502 			continue;
503 
504 		hwc = &event->hw;
505 		armpmu_event_update(event, hwc, idx, 1);
506 		data.period = event->hw.last_period;
507 		if (!armpmu_event_set_period(event, hwc, idx))
508 			continue;
509 
510 		if (perf_event_overflow(event, &data, regs))
511 			armpmu->disable(hwc, idx);
512 	}
513 
514 	/*
515 	 * Handle the pending perf events.
516 	 *
517 	 * Note: this call *must* be run with interrupts disabled. For
518 	 * platforms that can have the PMU interrupts raised as an NMI, this
519 	 * will not work.
520 	 */
521 	irq_work_run();
522 
523 	return IRQ_HANDLED;
524 }
525 
526 static void
527 armv6pmu_start(void)
528 {
529 	unsigned long flags, val;
530 
531 	raw_spin_lock_irqsave(&pmu_lock, flags);
532 	val = armv6_pmcr_read();
533 	val |= ARMV6_PMCR_ENABLE;
534 	armv6_pmcr_write(val);
535 	raw_spin_unlock_irqrestore(&pmu_lock, flags);
536 }
537 
538 static void
539 armv6pmu_stop(void)
540 {
541 	unsigned long flags, val;
542 
543 	raw_spin_lock_irqsave(&pmu_lock, flags);
544 	val = armv6_pmcr_read();
545 	val &= ~ARMV6_PMCR_ENABLE;
546 	armv6_pmcr_write(val);
547 	raw_spin_unlock_irqrestore(&pmu_lock, flags);
548 }
549 
550 static int
551 armv6pmu_get_event_idx(struct cpu_hw_events *cpuc,
552 		       struct hw_perf_event *event)
553 {
554 	/* Always place a cycle counter into the cycle counter. */
555 	if (ARMV6_PERFCTR_CPU_CYCLES == event->config_base) {
556 		if (test_and_set_bit(ARMV6_CYCLE_COUNTER, cpuc->used_mask))
557 			return -EAGAIN;
558 
559 		return ARMV6_CYCLE_COUNTER;
560 	} else {
561 		/*
562 		 * For anything other than a cycle counter, try and use
563 		 * counter0 and counter1.
564 		 */
565 		if (!test_and_set_bit(ARMV6_COUNTER1, cpuc->used_mask))
566 			return ARMV6_COUNTER1;
567 
568 		if (!test_and_set_bit(ARMV6_COUNTER0, cpuc->used_mask))
569 			return ARMV6_COUNTER0;
570 
571 		/* The counters are all in use. */
572 		return -EAGAIN;
573 	}
574 }
575 
576 static void
577 armv6pmu_disable_event(struct hw_perf_event *hwc,
578 		       int idx)
579 {
580 	unsigned long val, mask, evt, flags;
581 
582 	if (ARMV6_CYCLE_COUNTER == idx) {
583 		mask	= ARMV6_PMCR_CCOUNT_IEN;
584 		evt	= 0;
585 	} else if (ARMV6_COUNTER0 == idx) {
586 		mask	= ARMV6_PMCR_COUNT0_IEN | ARMV6_PMCR_EVT_COUNT0_MASK;
587 		evt	= ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT0_SHIFT;
588 	} else if (ARMV6_COUNTER1 == idx) {
589 		mask	= ARMV6_PMCR_COUNT1_IEN | ARMV6_PMCR_EVT_COUNT1_MASK;
590 		evt	= ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT1_SHIFT;
591 	} else {
592 		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
593 		return;
594 	}
595 
596 	/*
597 	 * Mask out the current event and set the counter to count the number
598 	 * of ETM bus signal assertion cycles. The external reporting should
599 	 * be disabled and so this should never increment.
600 	 */
601 	raw_spin_lock_irqsave(&pmu_lock, flags);
602 	val = armv6_pmcr_read();
603 	val &= ~mask;
604 	val |= evt;
605 	armv6_pmcr_write(val);
606 	raw_spin_unlock_irqrestore(&pmu_lock, flags);
607 }
608 
609 static void
610 armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,
611 			      int idx)
612 {
613 	unsigned long val, mask, flags, evt = 0;
614 
615 	if (ARMV6_CYCLE_COUNTER == idx) {
616 		mask	= ARMV6_PMCR_CCOUNT_IEN;
617 	} else if (ARMV6_COUNTER0 == idx) {
618 		mask	= ARMV6_PMCR_COUNT0_IEN;
619 	} else if (ARMV6_COUNTER1 == idx) {
620 		mask	= ARMV6_PMCR_COUNT1_IEN;
621 	} else {
622 		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
623 		return;
624 	}
625 
626 	/*
627 	 * Unlike UP ARMv6, we don't have a way of stopping the counters. We
628 	 * simply disable the interrupt reporting.
629 	 */
630 	raw_spin_lock_irqsave(&pmu_lock, flags);
631 	val = armv6_pmcr_read();
632 	val &= ~mask;
633 	val |= evt;
634 	armv6_pmcr_write(val);
635 	raw_spin_unlock_irqrestore(&pmu_lock, flags);
636 }
637 
638 static const struct arm_pmu armv6pmu = {
639 	.id			= ARM_PERF_PMU_ID_V6,
640 	.name			= "v6",
641 	.handle_irq		= armv6pmu_handle_irq,
642 	.enable			= armv6pmu_enable_event,
643 	.disable		= armv6pmu_disable_event,
644 	.read_counter		= armv6pmu_read_counter,
645 	.write_counter		= armv6pmu_write_counter,
646 	.get_event_idx		= armv6pmu_get_event_idx,
647 	.start			= armv6pmu_start,
648 	.stop			= armv6pmu_stop,
649 	.cache_map		= &armv6_perf_cache_map,
650 	.event_map		= &armv6_perf_map,
651 	.raw_event_mask		= 0xFF,
652 	.num_events		= 3,
653 	.max_period		= (1LLU << 32) - 1,
654 };
655 
656 static const struct arm_pmu *__init armv6pmu_init(void)
657 {
658 	return &armv6pmu;
659 }
660 
661 /*
662  * ARMv6mpcore is almost identical to single core ARMv6 with the exception
663  * that some of the events have different enumerations and that there is no
664  * *hack* to stop the programmable counters. To stop the counters we simply
665  * disable the interrupt reporting and update the event. When unthrottling we
666  * reset the period and enable the interrupt reporting.
667  */
668 static const struct arm_pmu armv6mpcore_pmu = {
669 	.id			= ARM_PERF_PMU_ID_V6MP,
670 	.name			= "v6mpcore",
671 	.handle_irq		= armv6pmu_handle_irq,
672 	.enable			= armv6pmu_enable_event,
673 	.disable		= armv6mpcore_pmu_disable_event,
674 	.read_counter		= armv6pmu_read_counter,
675 	.write_counter		= armv6pmu_write_counter,
676 	.get_event_idx		= armv6pmu_get_event_idx,
677 	.start			= armv6pmu_start,
678 	.stop			= armv6pmu_stop,
679 	.cache_map		= &armv6mpcore_perf_cache_map,
680 	.event_map		= &armv6mpcore_perf_map,
681 	.raw_event_mask		= 0xFF,
682 	.num_events		= 3,
683 	.max_period		= (1LLU << 32) - 1,
684 };
685 
686 static const struct arm_pmu *__init armv6mpcore_pmu_init(void)
687 {
688 	return &armv6mpcore_pmu;
689 }
690 #else
691 static const struct arm_pmu *__init armv6pmu_init(void)
692 {
693 	return NULL;
694 }
695 
696 static const struct arm_pmu *__init armv6mpcore_pmu_init(void)
697 {
698 	return NULL;
699 }
700 #endif	/* CONFIG_CPU_V6 || CONFIG_CPU_V6K */
701