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