1 /*
2  * ARMv5 [xscale] Performance counter handling code.
3  *
4  * Copyright (C) 2010, ARM Ltd., Will Deacon <will.deacon@arm.com>
5  *
6  * Based on the previous xscale OProfile code.
7  *
8  * There are two variants of the xscale PMU that we support:
9  * 	- xscale1pmu: 2 event counters and a cycle counter
10  * 	- xscale2pmu: 4 event counters and a cycle counter
11  * The two variants share event definitions, but have different
12  * PMU structures.
13  */
14 
15 #ifdef CONFIG_CPU_XSCALE
16 enum xscale_perf_types {
17 	XSCALE_PERFCTR_ICACHE_MISS		= 0x00,
18 	XSCALE_PERFCTR_ICACHE_NO_DELIVER	= 0x01,
19 	XSCALE_PERFCTR_DATA_STALL		= 0x02,
20 	XSCALE_PERFCTR_ITLB_MISS		= 0x03,
21 	XSCALE_PERFCTR_DTLB_MISS		= 0x04,
22 	XSCALE_PERFCTR_BRANCH			= 0x05,
23 	XSCALE_PERFCTR_BRANCH_MISS		= 0x06,
24 	XSCALE_PERFCTR_INSTRUCTION		= 0x07,
25 	XSCALE_PERFCTR_DCACHE_FULL_STALL	= 0x08,
26 	XSCALE_PERFCTR_DCACHE_FULL_STALL_CONTIG	= 0x09,
27 	XSCALE_PERFCTR_DCACHE_ACCESS		= 0x0A,
28 	XSCALE_PERFCTR_DCACHE_MISS		= 0x0B,
29 	XSCALE_PERFCTR_DCACHE_WRITE_BACK	= 0x0C,
30 	XSCALE_PERFCTR_PC_CHANGED		= 0x0D,
31 	XSCALE_PERFCTR_BCU_REQUEST		= 0x10,
32 	XSCALE_PERFCTR_BCU_FULL			= 0x11,
33 	XSCALE_PERFCTR_BCU_DRAIN		= 0x12,
34 	XSCALE_PERFCTR_BCU_ECC_NO_ELOG		= 0x14,
35 	XSCALE_PERFCTR_BCU_1_BIT_ERR		= 0x15,
36 	XSCALE_PERFCTR_RMW			= 0x16,
37 	/* XSCALE_PERFCTR_CCNT is not hardware defined */
38 	XSCALE_PERFCTR_CCNT			= 0xFE,
39 	XSCALE_PERFCTR_UNUSED			= 0xFF,
40 };
41 
42 enum xscale_counters {
43 	XSCALE_CYCLE_COUNTER	= 0,
44 	XSCALE_COUNTER0,
45 	XSCALE_COUNTER1,
46 	XSCALE_COUNTER2,
47 	XSCALE_COUNTER3,
48 };
49 
50 static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = {
51 	[PERF_COUNT_HW_CPU_CYCLES]		= XSCALE_PERFCTR_CCNT,
52 	[PERF_COUNT_HW_INSTRUCTIONS]		= XSCALE_PERFCTR_INSTRUCTION,
53 	[PERF_COUNT_HW_CACHE_REFERENCES]	= HW_OP_UNSUPPORTED,
54 	[PERF_COUNT_HW_CACHE_MISSES]		= HW_OP_UNSUPPORTED,
55 	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= XSCALE_PERFCTR_BRANCH,
56 	[PERF_COUNT_HW_BRANCH_MISSES]		= XSCALE_PERFCTR_BRANCH_MISS,
57 	[PERF_COUNT_HW_BUS_CYCLES]		= HW_OP_UNSUPPORTED,
58 	[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND]	= XSCALE_PERFCTR_ICACHE_NO_DELIVER,
59 	[PERF_COUNT_HW_STALLED_CYCLES_BACKEND]	= HW_OP_UNSUPPORTED,
60 };
61 
62 static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
63 					   [PERF_COUNT_HW_CACHE_OP_MAX]
64 					   [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
65 	[C(L1D)] = {
66 		[C(OP_READ)] = {
67 			[C(RESULT_ACCESS)]	= XSCALE_PERFCTR_DCACHE_ACCESS,
68 			[C(RESULT_MISS)]	= XSCALE_PERFCTR_DCACHE_MISS,
69 		},
70 		[C(OP_WRITE)] = {
71 			[C(RESULT_ACCESS)]	= XSCALE_PERFCTR_DCACHE_ACCESS,
72 			[C(RESULT_MISS)]	= XSCALE_PERFCTR_DCACHE_MISS,
73 		},
74 		[C(OP_PREFETCH)] = {
75 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
76 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
77 		},
78 	},
79 	[C(L1I)] = {
80 		[C(OP_READ)] = {
81 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
82 			[C(RESULT_MISS)]	= XSCALE_PERFCTR_ICACHE_MISS,
83 		},
84 		[C(OP_WRITE)] = {
85 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
86 			[C(RESULT_MISS)]	= XSCALE_PERFCTR_ICACHE_MISS,
87 		},
88 		[C(OP_PREFETCH)] = {
89 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
90 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
91 		},
92 	},
93 	[C(LL)] = {
94 		[C(OP_READ)] = {
95 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
96 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
97 		},
98 		[C(OP_WRITE)] = {
99 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
100 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
101 		},
102 		[C(OP_PREFETCH)] = {
103 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
104 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
105 		},
106 	},
107 	[C(DTLB)] = {
108 		[C(OP_READ)] = {
109 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
110 			[C(RESULT_MISS)]	= XSCALE_PERFCTR_DTLB_MISS,
111 		},
112 		[C(OP_WRITE)] = {
113 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
114 			[C(RESULT_MISS)]	= XSCALE_PERFCTR_DTLB_MISS,
115 		},
116 		[C(OP_PREFETCH)] = {
117 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
118 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
119 		},
120 	},
121 	[C(ITLB)] = {
122 		[C(OP_READ)] = {
123 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
124 			[C(RESULT_MISS)]	= XSCALE_PERFCTR_ITLB_MISS,
125 		},
126 		[C(OP_WRITE)] = {
127 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
128 			[C(RESULT_MISS)]	= XSCALE_PERFCTR_ITLB_MISS,
129 		},
130 		[C(OP_PREFETCH)] = {
131 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
132 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
133 		},
134 	},
135 	[C(BPU)] = {
136 		[C(OP_READ)] = {
137 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
138 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
139 		},
140 		[C(OP_WRITE)] = {
141 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
142 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
143 		},
144 		[C(OP_PREFETCH)] = {
145 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
146 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
147 		},
148 	},
149 	[C(NODE)] = {
150 		[C(OP_READ)] = {
151 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
152 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
153 		},
154 		[C(OP_WRITE)] = {
155 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
156 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
157 		},
158 		[C(OP_PREFETCH)] = {
159 			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
160 			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
161 		},
162 	},
163 };
164 
165 #define	XSCALE_PMU_ENABLE	0x001
166 #define XSCALE_PMN_RESET	0x002
167 #define	XSCALE_CCNT_RESET	0x004
168 #define	XSCALE_PMU_RESET	(CCNT_RESET | PMN_RESET)
169 #define XSCALE_PMU_CNT64	0x008
170 
171 #define XSCALE1_OVERFLOWED_MASK	0x700
172 #define XSCALE1_CCOUNT_OVERFLOW	0x400
173 #define XSCALE1_COUNT0_OVERFLOW	0x100
174 #define XSCALE1_COUNT1_OVERFLOW	0x200
175 #define XSCALE1_CCOUNT_INT_EN	0x040
176 #define XSCALE1_COUNT0_INT_EN	0x010
177 #define XSCALE1_COUNT1_INT_EN	0x020
178 #define XSCALE1_COUNT0_EVT_SHFT	12
179 #define XSCALE1_COUNT0_EVT_MASK	(0xff << XSCALE1_COUNT0_EVT_SHFT)
180 #define XSCALE1_COUNT1_EVT_SHFT	20
181 #define XSCALE1_COUNT1_EVT_MASK	(0xff << XSCALE1_COUNT1_EVT_SHFT)
182 
183 static inline u32
184 xscale1pmu_read_pmnc(void)
185 {
186 	u32 val;
187 	asm volatile("mrc p14, 0, %0, c0, c0, 0" : "=r" (val));
188 	return val;
189 }
190 
191 static inline void
192 xscale1pmu_write_pmnc(u32 val)
193 {
194 	/* upper 4bits and 7, 11 are write-as-0 */
195 	val &= 0xffff77f;
196 	asm volatile("mcr p14, 0, %0, c0, c0, 0" : : "r" (val));
197 }
198 
199 static inline int
200 xscale1_pmnc_counter_has_overflowed(unsigned long pmnc,
201 					enum xscale_counters counter)
202 {
203 	int ret = 0;
204 
205 	switch (counter) {
206 	case XSCALE_CYCLE_COUNTER:
207 		ret = pmnc & XSCALE1_CCOUNT_OVERFLOW;
208 		break;
209 	case XSCALE_COUNTER0:
210 		ret = pmnc & XSCALE1_COUNT0_OVERFLOW;
211 		break;
212 	case XSCALE_COUNTER1:
213 		ret = pmnc & XSCALE1_COUNT1_OVERFLOW;
214 		break;
215 	default:
216 		WARN_ONCE(1, "invalid counter number (%d)\n", counter);
217 	}
218 
219 	return ret;
220 }
221 
222 static irqreturn_t
223 xscale1pmu_handle_irq(int irq_num, void *dev)
224 {
225 	unsigned long pmnc;
226 	struct perf_sample_data data;
227 	struct pmu_hw_events *cpuc;
228 	struct pt_regs *regs;
229 	int idx;
230 
231 	/*
232 	 * NOTE: there's an A stepping erratum that states if an overflow
233 	 *       bit already exists and another occurs, the previous
234 	 *       Overflow bit gets cleared. There's no workaround.
235 	 *	 Fixed in B stepping or later.
236 	 */
237 	pmnc = xscale1pmu_read_pmnc();
238 
239 	/*
240 	 * Write the value back to clear the overflow flags. Overflow
241 	 * flags remain in pmnc for use below. We also disable the PMU
242 	 * while we process the interrupt.
243 	 */
244 	xscale1pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
245 
246 	if (!(pmnc & XSCALE1_OVERFLOWED_MASK))
247 		return IRQ_NONE;
248 
249 	regs = get_irq_regs();
250 
251 	perf_sample_data_init(&data, 0);
252 
253 	cpuc = &__get_cpu_var(cpu_hw_events);
254 	for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
255 		struct perf_event *event = cpuc->events[idx];
256 		struct hw_perf_event *hwc;
257 
258 		if (!event)
259 			continue;
260 
261 		if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx))
262 			continue;
263 
264 		hwc = &event->hw;
265 		armpmu_event_update(event, hwc, idx);
266 		data.period = event->hw.last_period;
267 		if (!armpmu_event_set_period(event, hwc, idx))
268 			continue;
269 
270 		if (perf_event_overflow(event, &data, regs))
271 			cpu_pmu->disable(hwc, idx);
272 	}
273 
274 	irq_work_run();
275 
276 	/*
277 	 * Re-enable the PMU.
278 	 */
279 	pmnc = xscale1pmu_read_pmnc() | XSCALE_PMU_ENABLE;
280 	xscale1pmu_write_pmnc(pmnc);
281 
282 	return IRQ_HANDLED;
283 }
284 
285 static void
286 xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx)
287 {
288 	unsigned long val, mask, evt, flags;
289 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
290 
291 	switch (idx) {
292 	case XSCALE_CYCLE_COUNTER:
293 		mask = 0;
294 		evt = XSCALE1_CCOUNT_INT_EN;
295 		break;
296 	case XSCALE_COUNTER0:
297 		mask = XSCALE1_COUNT0_EVT_MASK;
298 		evt = (hwc->config_base << XSCALE1_COUNT0_EVT_SHFT) |
299 			XSCALE1_COUNT0_INT_EN;
300 		break;
301 	case XSCALE_COUNTER1:
302 		mask = XSCALE1_COUNT1_EVT_MASK;
303 		evt = (hwc->config_base << XSCALE1_COUNT1_EVT_SHFT) |
304 			XSCALE1_COUNT1_INT_EN;
305 		break;
306 	default:
307 		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
308 		return;
309 	}
310 
311 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
312 	val = xscale1pmu_read_pmnc();
313 	val &= ~mask;
314 	val |= evt;
315 	xscale1pmu_write_pmnc(val);
316 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
317 }
318 
319 static void
320 xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx)
321 {
322 	unsigned long val, mask, evt, flags;
323 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
324 
325 	switch (idx) {
326 	case XSCALE_CYCLE_COUNTER:
327 		mask = XSCALE1_CCOUNT_INT_EN;
328 		evt = 0;
329 		break;
330 	case XSCALE_COUNTER0:
331 		mask = XSCALE1_COUNT0_INT_EN | XSCALE1_COUNT0_EVT_MASK;
332 		evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT0_EVT_SHFT;
333 		break;
334 	case XSCALE_COUNTER1:
335 		mask = XSCALE1_COUNT1_INT_EN | XSCALE1_COUNT1_EVT_MASK;
336 		evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT1_EVT_SHFT;
337 		break;
338 	default:
339 		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
340 		return;
341 	}
342 
343 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
344 	val = xscale1pmu_read_pmnc();
345 	val &= ~mask;
346 	val |= evt;
347 	xscale1pmu_write_pmnc(val);
348 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
349 }
350 
351 static int
352 xscale1pmu_get_event_idx(struct pmu_hw_events *cpuc,
353 			struct hw_perf_event *event)
354 {
355 	if (XSCALE_PERFCTR_CCNT == event->config_base) {
356 		if (test_and_set_bit(XSCALE_CYCLE_COUNTER, cpuc->used_mask))
357 			return -EAGAIN;
358 
359 		return XSCALE_CYCLE_COUNTER;
360 	} else {
361 		if (!test_and_set_bit(XSCALE_COUNTER1, cpuc->used_mask))
362 			return XSCALE_COUNTER1;
363 
364 		if (!test_and_set_bit(XSCALE_COUNTER0, cpuc->used_mask))
365 			return XSCALE_COUNTER0;
366 
367 		return -EAGAIN;
368 	}
369 }
370 
371 static void
372 xscale1pmu_start(void)
373 {
374 	unsigned long flags, val;
375 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
376 
377 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
378 	val = xscale1pmu_read_pmnc();
379 	val |= XSCALE_PMU_ENABLE;
380 	xscale1pmu_write_pmnc(val);
381 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
382 }
383 
384 static void
385 xscale1pmu_stop(void)
386 {
387 	unsigned long flags, val;
388 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
389 
390 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
391 	val = xscale1pmu_read_pmnc();
392 	val &= ~XSCALE_PMU_ENABLE;
393 	xscale1pmu_write_pmnc(val);
394 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
395 }
396 
397 static inline u32
398 xscale1pmu_read_counter(int counter)
399 {
400 	u32 val = 0;
401 
402 	switch (counter) {
403 	case XSCALE_CYCLE_COUNTER:
404 		asm volatile("mrc p14, 0, %0, c1, c0, 0" : "=r" (val));
405 		break;
406 	case XSCALE_COUNTER0:
407 		asm volatile("mrc p14, 0, %0, c2, c0, 0" : "=r" (val));
408 		break;
409 	case XSCALE_COUNTER1:
410 		asm volatile("mrc p14, 0, %0, c3, c0, 0" : "=r" (val));
411 		break;
412 	}
413 
414 	return val;
415 }
416 
417 static inline void
418 xscale1pmu_write_counter(int counter, u32 val)
419 {
420 	switch (counter) {
421 	case XSCALE_CYCLE_COUNTER:
422 		asm volatile("mcr p14, 0, %0, c1, c0, 0" : : "r" (val));
423 		break;
424 	case XSCALE_COUNTER0:
425 		asm volatile("mcr p14, 0, %0, c2, c0, 0" : : "r" (val));
426 		break;
427 	case XSCALE_COUNTER1:
428 		asm volatile("mcr p14, 0, %0, c3, c0, 0" : : "r" (val));
429 		break;
430 	}
431 }
432 
433 static int xscale_map_event(struct perf_event *event)
434 {
435 	return map_cpu_event(event, &xscale_perf_map,
436 				&xscale_perf_cache_map, 0xFF);
437 }
438 
439 static struct arm_pmu xscale1pmu = {
440 	.id		= ARM_PERF_PMU_ID_XSCALE1,
441 	.name		= "xscale1",
442 	.handle_irq	= xscale1pmu_handle_irq,
443 	.enable		= xscale1pmu_enable_event,
444 	.disable	= xscale1pmu_disable_event,
445 	.read_counter	= xscale1pmu_read_counter,
446 	.write_counter	= xscale1pmu_write_counter,
447 	.get_event_idx	= xscale1pmu_get_event_idx,
448 	.start		= xscale1pmu_start,
449 	.stop		= xscale1pmu_stop,
450 	.map_event	= xscale_map_event,
451 	.num_events	= 3,
452 	.max_period	= (1LLU << 32) - 1,
453 };
454 
455 static struct arm_pmu *__init xscale1pmu_init(void)
456 {
457 	return &xscale1pmu;
458 }
459 
460 #define XSCALE2_OVERFLOWED_MASK	0x01f
461 #define XSCALE2_CCOUNT_OVERFLOW	0x001
462 #define XSCALE2_COUNT0_OVERFLOW	0x002
463 #define XSCALE2_COUNT1_OVERFLOW	0x004
464 #define XSCALE2_COUNT2_OVERFLOW	0x008
465 #define XSCALE2_COUNT3_OVERFLOW	0x010
466 #define XSCALE2_CCOUNT_INT_EN	0x001
467 #define XSCALE2_COUNT0_INT_EN	0x002
468 #define XSCALE2_COUNT1_INT_EN	0x004
469 #define XSCALE2_COUNT2_INT_EN	0x008
470 #define XSCALE2_COUNT3_INT_EN	0x010
471 #define XSCALE2_COUNT0_EVT_SHFT	0
472 #define XSCALE2_COUNT0_EVT_MASK	(0xff << XSCALE2_COUNT0_EVT_SHFT)
473 #define XSCALE2_COUNT1_EVT_SHFT	8
474 #define XSCALE2_COUNT1_EVT_MASK	(0xff << XSCALE2_COUNT1_EVT_SHFT)
475 #define XSCALE2_COUNT2_EVT_SHFT	16
476 #define XSCALE2_COUNT2_EVT_MASK	(0xff << XSCALE2_COUNT2_EVT_SHFT)
477 #define XSCALE2_COUNT3_EVT_SHFT	24
478 #define XSCALE2_COUNT3_EVT_MASK	(0xff << XSCALE2_COUNT3_EVT_SHFT)
479 
480 static inline u32
481 xscale2pmu_read_pmnc(void)
482 {
483 	u32 val;
484 	asm volatile("mrc p14, 0, %0, c0, c1, 0" : "=r" (val));
485 	/* bits 1-2 and 4-23 are read-unpredictable */
486 	return val & 0xff000009;
487 }
488 
489 static inline void
490 xscale2pmu_write_pmnc(u32 val)
491 {
492 	/* bits 4-23 are write-as-0, 24-31 are write ignored */
493 	val &= 0xf;
494 	asm volatile("mcr p14, 0, %0, c0, c1, 0" : : "r" (val));
495 }
496 
497 static inline u32
498 xscale2pmu_read_overflow_flags(void)
499 {
500 	u32 val;
501 	asm volatile("mrc p14, 0, %0, c5, c1, 0" : "=r" (val));
502 	return val;
503 }
504 
505 static inline void
506 xscale2pmu_write_overflow_flags(u32 val)
507 {
508 	asm volatile("mcr p14, 0, %0, c5, c1, 0" : : "r" (val));
509 }
510 
511 static inline u32
512 xscale2pmu_read_event_select(void)
513 {
514 	u32 val;
515 	asm volatile("mrc p14, 0, %0, c8, c1, 0" : "=r" (val));
516 	return val;
517 }
518 
519 static inline void
520 xscale2pmu_write_event_select(u32 val)
521 {
522 	asm volatile("mcr p14, 0, %0, c8, c1, 0" : : "r"(val));
523 }
524 
525 static inline u32
526 xscale2pmu_read_int_enable(void)
527 {
528 	u32 val;
529 	asm volatile("mrc p14, 0, %0, c4, c1, 0" : "=r" (val));
530 	return val;
531 }
532 
533 static void
534 xscale2pmu_write_int_enable(u32 val)
535 {
536 	asm volatile("mcr p14, 0, %0, c4, c1, 0" : : "r" (val));
537 }
538 
539 static inline int
540 xscale2_pmnc_counter_has_overflowed(unsigned long of_flags,
541 					enum xscale_counters counter)
542 {
543 	int ret = 0;
544 
545 	switch (counter) {
546 	case XSCALE_CYCLE_COUNTER:
547 		ret = of_flags & XSCALE2_CCOUNT_OVERFLOW;
548 		break;
549 	case XSCALE_COUNTER0:
550 		ret = of_flags & XSCALE2_COUNT0_OVERFLOW;
551 		break;
552 	case XSCALE_COUNTER1:
553 		ret = of_flags & XSCALE2_COUNT1_OVERFLOW;
554 		break;
555 	case XSCALE_COUNTER2:
556 		ret = of_flags & XSCALE2_COUNT2_OVERFLOW;
557 		break;
558 	case XSCALE_COUNTER3:
559 		ret = of_flags & XSCALE2_COUNT3_OVERFLOW;
560 		break;
561 	default:
562 		WARN_ONCE(1, "invalid counter number (%d)\n", counter);
563 	}
564 
565 	return ret;
566 }
567 
568 static irqreturn_t
569 xscale2pmu_handle_irq(int irq_num, void *dev)
570 {
571 	unsigned long pmnc, of_flags;
572 	struct perf_sample_data data;
573 	struct pmu_hw_events *cpuc;
574 	struct pt_regs *regs;
575 	int idx;
576 
577 	/* Disable the PMU. */
578 	pmnc = xscale2pmu_read_pmnc();
579 	xscale2pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
580 
581 	/* Check the overflow flag register. */
582 	of_flags = xscale2pmu_read_overflow_flags();
583 	if (!(of_flags & XSCALE2_OVERFLOWED_MASK))
584 		return IRQ_NONE;
585 
586 	/* Clear the overflow bits. */
587 	xscale2pmu_write_overflow_flags(of_flags);
588 
589 	regs = get_irq_regs();
590 
591 	perf_sample_data_init(&data, 0);
592 
593 	cpuc = &__get_cpu_var(cpu_hw_events);
594 	for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
595 		struct perf_event *event = cpuc->events[idx];
596 		struct hw_perf_event *hwc;
597 
598 		if (!event)
599 			continue;
600 
601 		if (!xscale2_pmnc_counter_has_overflowed(of_flags, idx))
602 			continue;
603 
604 		hwc = &event->hw;
605 		armpmu_event_update(event, hwc, idx);
606 		data.period = event->hw.last_period;
607 		if (!armpmu_event_set_period(event, hwc, idx))
608 			continue;
609 
610 		if (perf_event_overflow(event, &data, regs))
611 			cpu_pmu->disable(hwc, idx);
612 	}
613 
614 	irq_work_run();
615 
616 	/*
617 	 * Re-enable the PMU.
618 	 */
619 	pmnc = xscale2pmu_read_pmnc() | XSCALE_PMU_ENABLE;
620 	xscale2pmu_write_pmnc(pmnc);
621 
622 	return IRQ_HANDLED;
623 }
624 
625 static void
626 xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx)
627 {
628 	unsigned long flags, ien, evtsel;
629 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
630 
631 	ien = xscale2pmu_read_int_enable();
632 	evtsel = xscale2pmu_read_event_select();
633 
634 	switch (idx) {
635 	case XSCALE_CYCLE_COUNTER:
636 		ien |= XSCALE2_CCOUNT_INT_EN;
637 		break;
638 	case XSCALE_COUNTER0:
639 		ien |= XSCALE2_COUNT0_INT_EN;
640 		evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
641 		evtsel |= hwc->config_base << XSCALE2_COUNT0_EVT_SHFT;
642 		break;
643 	case XSCALE_COUNTER1:
644 		ien |= XSCALE2_COUNT1_INT_EN;
645 		evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
646 		evtsel |= hwc->config_base << XSCALE2_COUNT1_EVT_SHFT;
647 		break;
648 	case XSCALE_COUNTER2:
649 		ien |= XSCALE2_COUNT2_INT_EN;
650 		evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
651 		evtsel |= hwc->config_base << XSCALE2_COUNT2_EVT_SHFT;
652 		break;
653 	case XSCALE_COUNTER3:
654 		ien |= XSCALE2_COUNT3_INT_EN;
655 		evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
656 		evtsel |= hwc->config_base << XSCALE2_COUNT3_EVT_SHFT;
657 		break;
658 	default:
659 		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
660 		return;
661 	}
662 
663 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
664 	xscale2pmu_write_event_select(evtsel);
665 	xscale2pmu_write_int_enable(ien);
666 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
667 }
668 
669 static void
670 xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx)
671 {
672 	unsigned long flags, ien, evtsel, of_flags;
673 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
674 
675 	ien = xscale2pmu_read_int_enable();
676 	evtsel = xscale2pmu_read_event_select();
677 
678 	switch (idx) {
679 	case XSCALE_CYCLE_COUNTER:
680 		ien &= ~XSCALE2_CCOUNT_INT_EN;
681 		of_flags = XSCALE2_CCOUNT_OVERFLOW;
682 		break;
683 	case XSCALE_COUNTER0:
684 		ien &= ~XSCALE2_COUNT0_INT_EN;
685 		evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
686 		evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT0_EVT_SHFT;
687 		of_flags = XSCALE2_COUNT0_OVERFLOW;
688 		break;
689 	case XSCALE_COUNTER1:
690 		ien &= ~XSCALE2_COUNT1_INT_EN;
691 		evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
692 		evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT1_EVT_SHFT;
693 		of_flags = XSCALE2_COUNT1_OVERFLOW;
694 		break;
695 	case XSCALE_COUNTER2:
696 		ien &= ~XSCALE2_COUNT2_INT_EN;
697 		evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
698 		evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT2_EVT_SHFT;
699 		of_flags = XSCALE2_COUNT2_OVERFLOW;
700 		break;
701 	case XSCALE_COUNTER3:
702 		ien &= ~XSCALE2_COUNT3_INT_EN;
703 		evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
704 		evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT3_EVT_SHFT;
705 		of_flags = XSCALE2_COUNT3_OVERFLOW;
706 		break;
707 	default:
708 		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
709 		return;
710 	}
711 
712 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
713 	xscale2pmu_write_event_select(evtsel);
714 	xscale2pmu_write_int_enable(ien);
715 	xscale2pmu_write_overflow_flags(of_flags);
716 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
717 }
718 
719 static int
720 xscale2pmu_get_event_idx(struct pmu_hw_events *cpuc,
721 			struct hw_perf_event *event)
722 {
723 	int idx = xscale1pmu_get_event_idx(cpuc, event);
724 	if (idx >= 0)
725 		goto out;
726 
727 	if (!test_and_set_bit(XSCALE_COUNTER3, cpuc->used_mask))
728 		idx = XSCALE_COUNTER3;
729 	else if (!test_and_set_bit(XSCALE_COUNTER2, cpuc->used_mask))
730 		idx = XSCALE_COUNTER2;
731 out:
732 	return idx;
733 }
734 
735 static void
736 xscale2pmu_start(void)
737 {
738 	unsigned long flags, val;
739 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
740 
741 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
742 	val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64;
743 	val |= XSCALE_PMU_ENABLE;
744 	xscale2pmu_write_pmnc(val);
745 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
746 }
747 
748 static void
749 xscale2pmu_stop(void)
750 {
751 	unsigned long flags, val;
752 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
753 
754 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
755 	val = xscale2pmu_read_pmnc();
756 	val &= ~XSCALE_PMU_ENABLE;
757 	xscale2pmu_write_pmnc(val);
758 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
759 }
760 
761 static inline u32
762 xscale2pmu_read_counter(int counter)
763 {
764 	u32 val = 0;
765 
766 	switch (counter) {
767 	case XSCALE_CYCLE_COUNTER:
768 		asm volatile("mrc p14, 0, %0, c1, c1, 0" : "=r" (val));
769 		break;
770 	case XSCALE_COUNTER0:
771 		asm volatile("mrc p14, 0, %0, c0, c2, 0" : "=r" (val));
772 		break;
773 	case XSCALE_COUNTER1:
774 		asm volatile("mrc p14, 0, %0, c1, c2, 0" : "=r" (val));
775 		break;
776 	case XSCALE_COUNTER2:
777 		asm volatile("mrc p14, 0, %0, c2, c2, 0" : "=r" (val));
778 		break;
779 	case XSCALE_COUNTER3:
780 		asm volatile("mrc p14, 0, %0, c3, c2, 0" : "=r" (val));
781 		break;
782 	}
783 
784 	return val;
785 }
786 
787 static inline void
788 xscale2pmu_write_counter(int counter, u32 val)
789 {
790 	switch (counter) {
791 	case XSCALE_CYCLE_COUNTER:
792 		asm volatile("mcr p14, 0, %0, c1, c1, 0" : : "r" (val));
793 		break;
794 	case XSCALE_COUNTER0:
795 		asm volatile("mcr p14, 0, %0, c0, c2, 0" : : "r" (val));
796 		break;
797 	case XSCALE_COUNTER1:
798 		asm volatile("mcr p14, 0, %0, c1, c2, 0" : : "r" (val));
799 		break;
800 	case XSCALE_COUNTER2:
801 		asm volatile("mcr p14, 0, %0, c2, c2, 0" : : "r" (val));
802 		break;
803 	case XSCALE_COUNTER3:
804 		asm volatile("mcr p14, 0, %0, c3, c2, 0" : : "r" (val));
805 		break;
806 	}
807 }
808 
809 static struct arm_pmu xscale2pmu = {
810 	.id		= ARM_PERF_PMU_ID_XSCALE2,
811 	.name		= "xscale2",
812 	.handle_irq	= xscale2pmu_handle_irq,
813 	.enable		= xscale2pmu_enable_event,
814 	.disable	= xscale2pmu_disable_event,
815 	.read_counter	= xscale2pmu_read_counter,
816 	.write_counter	= xscale2pmu_write_counter,
817 	.get_event_idx	= xscale2pmu_get_event_idx,
818 	.start		= xscale2pmu_start,
819 	.stop		= xscale2pmu_stop,
820 	.map_event	= xscale_map_event,
821 	.num_events	= 5,
822 	.max_period	= (1LLU << 32) - 1,
823 };
824 
825 static struct arm_pmu *__init xscale2pmu_init(void)
826 {
827 	return &xscale2pmu;
828 }
829 #else
830 static struct arm_pmu *__init xscale1pmu_init(void)
831 {
832 	return NULL;
833 }
834 
835 static struct arm_pmu *__init xscale2pmu_init(void)
836 {
837 	return NULL;
838 }
839 #endif	/* CONFIG_CPU_XSCALE */
840