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 	cpuc = &__get_cpu_var(cpu_hw_events);
252 	for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
253 		struct perf_event *event = cpuc->events[idx];
254 		struct hw_perf_event *hwc;
255 
256 		if (!event)
257 			continue;
258 
259 		if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx))
260 			continue;
261 
262 		hwc = &event->hw;
263 		armpmu_event_update(event, hwc, idx);
264 		perf_sample_data_init(&data, 0, hwc->last_period);
265 		if (!armpmu_event_set_period(event, hwc, idx))
266 			continue;
267 
268 		if (perf_event_overflow(event, &data, regs))
269 			cpu_pmu->disable(hwc, idx);
270 	}
271 
272 	irq_work_run();
273 
274 	/*
275 	 * Re-enable the PMU.
276 	 */
277 	pmnc = xscale1pmu_read_pmnc() | XSCALE_PMU_ENABLE;
278 	xscale1pmu_write_pmnc(pmnc);
279 
280 	return IRQ_HANDLED;
281 }
282 
283 static void
284 xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx)
285 {
286 	unsigned long val, mask, evt, flags;
287 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
288 
289 	switch (idx) {
290 	case XSCALE_CYCLE_COUNTER:
291 		mask = 0;
292 		evt = XSCALE1_CCOUNT_INT_EN;
293 		break;
294 	case XSCALE_COUNTER0:
295 		mask = XSCALE1_COUNT0_EVT_MASK;
296 		evt = (hwc->config_base << XSCALE1_COUNT0_EVT_SHFT) |
297 			XSCALE1_COUNT0_INT_EN;
298 		break;
299 	case XSCALE_COUNTER1:
300 		mask = XSCALE1_COUNT1_EVT_MASK;
301 		evt = (hwc->config_base << XSCALE1_COUNT1_EVT_SHFT) |
302 			XSCALE1_COUNT1_INT_EN;
303 		break;
304 	default:
305 		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
306 		return;
307 	}
308 
309 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
310 	val = xscale1pmu_read_pmnc();
311 	val &= ~mask;
312 	val |= evt;
313 	xscale1pmu_write_pmnc(val);
314 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
315 }
316 
317 static void
318 xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx)
319 {
320 	unsigned long val, mask, evt, flags;
321 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
322 
323 	switch (idx) {
324 	case XSCALE_CYCLE_COUNTER:
325 		mask = XSCALE1_CCOUNT_INT_EN;
326 		evt = 0;
327 		break;
328 	case XSCALE_COUNTER0:
329 		mask = XSCALE1_COUNT0_INT_EN | XSCALE1_COUNT0_EVT_MASK;
330 		evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT0_EVT_SHFT;
331 		break;
332 	case XSCALE_COUNTER1:
333 		mask = XSCALE1_COUNT1_INT_EN | XSCALE1_COUNT1_EVT_MASK;
334 		evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT1_EVT_SHFT;
335 		break;
336 	default:
337 		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
338 		return;
339 	}
340 
341 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
342 	val = xscale1pmu_read_pmnc();
343 	val &= ~mask;
344 	val |= evt;
345 	xscale1pmu_write_pmnc(val);
346 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
347 }
348 
349 static int
350 xscale1pmu_get_event_idx(struct pmu_hw_events *cpuc,
351 			struct hw_perf_event *event)
352 {
353 	if (XSCALE_PERFCTR_CCNT == event->config_base) {
354 		if (test_and_set_bit(XSCALE_CYCLE_COUNTER, cpuc->used_mask))
355 			return -EAGAIN;
356 
357 		return XSCALE_CYCLE_COUNTER;
358 	} else {
359 		if (!test_and_set_bit(XSCALE_COUNTER1, cpuc->used_mask))
360 			return XSCALE_COUNTER1;
361 
362 		if (!test_and_set_bit(XSCALE_COUNTER0, cpuc->used_mask))
363 			return XSCALE_COUNTER0;
364 
365 		return -EAGAIN;
366 	}
367 }
368 
369 static void
370 xscale1pmu_start(void)
371 {
372 	unsigned long flags, val;
373 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
374 
375 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
376 	val = xscale1pmu_read_pmnc();
377 	val |= XSCALE_PMU_ENABLE;
378 	xscale1pmu_write_pmnc(val);
379 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
380 }
381 
382 static void
383 xscale1pmu_stop(void)
384 {
385 	unsigned long flags, val;
386 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
387 
388 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
389 	val = xscale1pmu_read_pmnc();
390 	val &= ~XSCALE_PMU_ENABLE;
391 	xscale1pmu_write_pmnc(val);
392 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
393 }
394 
395 static inline u32
396 xscale1pmu_read_counter(int counter)
397 {
398 	u32 val = 0;
399 
400 	switch (counter) {
401 	case XSCALE_CYCLE_COUNTER:
402 		asm volatile("mrc p14, 0, %0, c1, c0, 0" : "=r" (val));
403 		break;
404 	case XSCALE_COUNTER0:
405 		asm volatile("mrc p14, 0, %0, c2, c0, 0" : "=r" (val));
406 		break;
407 	case XSCALE_COUNTER1:
408 		asm volatile("mrc p14, 0, %0, c3, c0, 0" : "=r" (val));
409 		break;
410 	}
411 
412 	return val;
413 }
414 
415 static inline void
416 xscale1pmu_write_counter(int counter, u32 val)
417 {
418 	switch (counter) {
419 	case XSCALE_CYCLE_COUNTER:
420 		asm volatile("mcr p14, 0, %0, c1, c0, 0" : : "r" (val));
421 		break;
422 	case XSCALE_COUNTER0:
423 		asm volatile("mcr p14, 0, %0, c2, c0, 0" : : "r" (val));
424 		break;
425 	case XSCALE_COUNTER1:
426 		asm volatile("mcr p14, 0, %0, c3, c0, 0" : : "r" (val));
427 		break;
428 	}
429 }
430 
431 static int xscale_map_event(struct perf_event *event)
432 {
433 	return armpmu_map_event(event, &xscale_perf_map,
434 				&xscale_perf_cache_map, 0xFF);
435 }
436 
437 static struct arm_pmu xscale1pmu = {
438 	.name		= "xscale1",
439 	.handle_irq	= xscale1pmu_handle_irq,
440 	.enable		= xscale1pmu_enable_event,
441 	.disable	= xscale1pmu_disable_event,
442 	.read_counter	= xscale1pmu_read_counter,
443 	.write_counter	= xscale1pmu_write_counter,
444 	.get_event_idx	= xscale1pmu_get_event_idx,
445 	.start		= xscale1pmu_start,
446 	.stop		= xscale1pmu_stop,
447 	.map_event	= xscale_map_event,
448 	.num_events	= 3,
449 	.max_period	= (1LLU << 32) - 1,
450 };
451 
452 static struct arm_pmu *__devinit xscale1pmu_init(void)
453 {
454 	return &xscale1pmu;
455 }
456 
457 #define XSCALE2_OVERFLOWED_MASK	0x01f
458 #define XSCALE2_CCOUNT_OVERFLOW	0x001
459 #define XSCALE2_COUNT0_OVERFLOW	0x002
460 #define XSCALE2_COUNT1_OVERFLOW	0x004
461 #define XSCALE2_COUNT2_OVERFLOW	0x008
462 #define XSCALE2_COUNT3_OVERFLOW	0x010
463 #define XSCALE2_CCOUNT_INT_EN	0x001
464 #define XSCALE2_COUNT0_INT_EN	0x002
465 #define XSCALE2_COUNT1_INT_EN	0x004
466 #define XSCALE2_COUNT2_INT_EN	0x008
467 #define XSCALE2_COUNT3_INT_EN	0x010
468 #define XSCALE2_COUNT0_EVT_SHFT	0
469 #define XSCALE2_COUNT0_EVT_MASK	(0xff << XSCALE2_COUNT0_EVT_SHFT)
470 #define XSCALE2_COUNT1_EVT_SHFT	8
471 #define XSCALE2_COUNT1_EVT_MASK	(0xff << XSCALE2_COUNT1_EVT_SHFT)
472 #define XSCALE2_COUNT2_EVT_SHFT	16
473 #define XSCALE2_COUNT2_EVT_MASK	(0xff << XSCALE2_COUNT2_EVT_SHFT)
474 #define XSCALE2_COUNT3_EVT_SHFT	24
475 #define XSCALE2_COUNT3_EVT_MASK	(0xff << XSCALE2_COUNT3_EVT_SHFT)
476 
477 static inline u32
478 xscale2pmu_read_pmnc(void)
479 {
480 	u32 val;
481 	asm volatile("mrc p14, 0, %0, c0, c1, 0" : "=r" (val));
482 	/* bits 1-2 and 4-23 are read-unpredictable */
483 	return val & 0xff000009;
484 }
485 
486 static inline void
487 xscale2pmu_write_pmnc(u32 val)
488 {
489 	/* bits 4-23 are write-as-0, 24-31 are write ignored */
490 	val &= 0xf;
491 	asm volatile("mcr p14, 0, %0, c0, c1, 0" : : "r" (val));
492 }
493 
494 static inline u32
495 xscale2pmu_read_overflow_flags(void)
496 {
497 	u32 val;
498 	asm volatile("mrc p14, 0, %0, c5, c1, 0" : "=r" (val));
499 	return val;
500 }
501 
502 static inline void
503 xscale2pmu_write_overflow_flags(u32 val)
504 {
505 	asm volatile("mcr p14, 0, %0, c5, c1, 0" : : "r" (val));
506 }
507 
508 static inline u32
509 xscale2pmu_read_event_select(void)
510 {
511 	u32 val;
512 	asm volatile("mrc p14, 0, %0, c8, c1, 0" : "=r" (val));
513 	return val;
514 }
515 
516 static inline void
517 xscale2pmu_write_event_select(u32 val)
518 {
519 	asm volatile("mcr p14, 0, %0, c8, c1, 0" : : "r"(val));
520 }
521 
522 static inline u32
523 xscale2pmu_read_int_enable(void)
524 {
525 	u32 val;
526 	asm volatile("mrc p14, 0, %0, c4, c1, 0" : "=r" (val));
527 	return val;
528 }
529 
530 static void
531 xscale2pmu_write_int_enable(u32 val)
532 {
533 	asm volatile("mcr p14, 0, %0, c4, c1, 0" : : "r" (val));
534 }
535 
536 static inline int
537 xscale2_pmnc_counter_has_overflowed(unsigned long of_flags,
538 					enum xscale_counters counter)
539 {
540 	int ret = 0;
541 
542 	switch (counter) {
543 	case XSCALE_CYCLE_COUNTER:
544 		ret = of_flags & XSCALE2_CCOUNT_OVERFLOW;
545 		break;
546 	case XSCALE_COUNTER0:
547 		ret = of_flags & XSCALE2_COUNT0_OVERFLOW;
548 		break;
549 	case XSCALE_COUNTER1:
550 		ret = of_flags & XSCALE2_COUNT1_OVERFLOW;
551 		break;
552 	case XSCALE_COUNTER2:
553 		ret = of_flags & XSCALE2_COUNT2_OVERFLOW;
554 		break;
555 	case XSCALE_COUNTER3:
556 		ret = of_flags & XSCALE2_COUNT3_OVERFLOW;
557 		break;
558 	default:
559 		WARN_ONCE(1, "invalid counter number (%d)\n", counter);
560 	}
561 
562 	return ret;
563 }
564 
565 static irqreturn_t
566 xscale2pmu_handle_irq(int irq_num, void *dev)
567 {
568 	unsigned long pmnc, of_flags;
569 	struct perf_sample_data data;
570 	struct pmu_hw_events *cpuc;
571 	struct pt_regs *regs;
572 	int idx;
573 
574 	/* Disable the PMU. */
575 	pmnc = xscale2pmu_read_pmnc();
576 	xscale2pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
577 
578 	/* Check the overflow flag register. */
579 	of_flags = xscale2pmu_read_overflow_flags();
580 	if (!(of_flags & XSCALE2_OVERFLOWED_MASK))
581 		return IRQ_NONE;
582 
583 	/* Clear the overflow bits. */
584 	xscale2pmu_write_overflow_flags(of_flags);
585 
586 	regs = get_irq_regs();
587 
588 	cpuc = &__get_cpu_var(cpu_hw_events);
589 	for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
590 		struct perf_event *event = cpuc->events[idx];
591 		struct hw_perf_event *hwc;
592 
593 		if (!event)
594 			continue;
595 
596 		if (!xscale2_pmnc_counter_has_overflowed(of_flags, idx))
597 			continue;
598 
599 		hwc = &event->hw;
600 		armpmu_event_update(event, hwc, idx);
601 		perf_sample_data_init(&data, 0, hwc->last_period);
602 		if (!armpmu_event_set_period(event, hwc, idx))
603 			continue;
604 
605 		if (perf_event_overflow(event, &data, regs))
606 			cpu_pmu->disable(hwc, idx);
607 	}
608 
609 	irq_work_run();
610 
611 	/*
612 	 * Re-enable the PMU.
613 	 */
614 	pmnc = xscale2pmu_read_pmnc() | XSCALE_PMU_ENABLE;
615 	xscale2pmu_write_pmnc(pmnc);
616 
617 	return IRQ_HANDLED;
618 }
619 
620 static void
621 xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx)
622 {
623 	unsigned long flags, ien, evtsel;
624 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
625 
626 	ien = xscale2pmu_read_int_enable();
627 	evtsel = xscale2pmu_read_event_select();
628 
629 	switch (idx) {
630 	case XSCALE_CYCLE_COUNTER:
631 		ien |= XSCALE2_CCOUNT_INT_EN;
632 		break;
633 	case XSCALE_COUNTER0:
634 		ien |= XSCALE2_COUNT0_INT_EN;
635 		evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
636 		evtsel |= hwc->config_base << XSCALE2_COUNT0_EVT_SHFT;
637 		break;
638 	case XSCALE_COUNTER1:
639 		ien |= XSCALE2_COUNT1_INT_EN;
640 		evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
641 		evtsel |= hwc->config_base << XSCALE2_COUNT1_EVT_SHFT;
642 		break;
643 	case XSCALE_COUNTER2:
644 		ien |= XSCALE2_COUNT2_INT_EN;
645 		evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
646 		evtsel |= hwc->config_base << XSCALE2_COUNT2_EVT_SHFT;
647 		break;
648 	case XSCALE_COUNTER3:
649 		ien |= XSCALE2_COUNT3_INT_EN;
650 		evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
651 		evtsel |= hwc->config_base << XSCALE2_COUNT3_EVT_SHFT;
652 		break;
653 	default:
654 		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
655 		return;
656 	}
657 
658 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
659 	xscale2pmu_write_event_select(evtsel);
660 	xscale2pmu_write_int_enable(ien);
661 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
662 }
663 
664 static void
665 xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx)
666 {
667 	unsigned long flags, ien, evtsel, of_flags;
668 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
669 
670 	ien = xscale2pmu_read_int_enable();
671 	evtsel = xscale2pmu_read_event_select();
672 
673 	switch (idx) {
674 	case XSCALE_CYCLE_COUNTER:
675 		ien &= ~XSCALE2_CCOUNT_INT_EN;
676 		of_flags = XSCALE2_CCOUNT_OVERFLOW;
677 		break;
678 	case XSCALE_COUNTER0:
679 		ien &= ~XSCALE2_COUNT0_INT_EN;
680 		evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
681 		evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT0_EVT_SHFT;
682 		of_flags = XSCALE2_COUNT0_OVERFLOW;
683 		break;
684 	case XSCALE_COUNTER1:
685 		ien &= ~XSCALE2_COUNT1_INT_EN;
686 		evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
687 		evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT1_EVT_SHFT;
688 		of_flags = XSCALE2_COUNT1_OVERFLOW;
689 		break;
690 	case XSCALE_COUNTER2:
691 		ien &= ~XSCALE2_COUNT2_INT_EN;
692 		evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
693 		evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT2_EVT_SHFT;
694 		of_flags = XSCALE2_COUNT2_OVERFLOW;
695 		break;
696 	case XSCALE_COUNTER3:
697 		ien &= ~XSCALE2_COUNT3_INT_EN;
698 		evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
699 		evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT3_EVT_SHFT;
700 		of_flags = XSCALE2_COUNT3_OVERFLOW;
701 		break;
702 	default:
703 		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
704 		return;
705 	}
706 
707 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
708 	xscale2pmu_write_event_select(evtsel);
709 	xscale2pmu_write_int_enable(ien);
710 	xscale2pmu_write_overflow_flags(of_flags);
711 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
712 }
713 
714 static int
715 xscale2pmu_get_event_idx(struct pmu_hw_events *cpuc,
716 			struct hw_perf_event *event)
717 {
718 	int idx = xscale1pmu_get_event_idx(cpuc, event);
719 	if (idx >= 0)
720 		goto out;
721 
722 	if (!test_and_set_bit(XSCALE_COUNTER3, cpuc->used_mask))
723 		idx = XSCALE_COUNTER3;
724 	else if (!test_and_set_bit(XSCALE_COUNTER2, cpuc->used_mask))
725 		idx = XSCALE_COUNTER2;
726 out:
727 	return idx;
728 }
729 
730 static void
731 xscale2pmu_start(void)
732 {
733 	unsigned long flags, val;
734 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
735 
736 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
737 	val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64;
738 	val |= XSCALE_PMU_ENABLE;
739 	xscale2pmu_write_pmnc(val);
740 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
741 }
742 
743 static void
744 xscale2pmu_stop(void)
745 {
746 	unsigned long flags, val;
747 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
748 
749 	raw_spin_lock_irqsave(&events->pmu_lock, flags);
750 	val = xscale2pmu_read_pmnc();
751 	val &= ~XSCALE_PMU_ENABLE;
752 	xscale2pmu_write_pmnc(val);
753 	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
754 }
755 
756 static inline u32
757 xscale2pmu_read_counter(int counter)
758 {
759 	u32 val = 0;
760 
761 	switch (counter) {
762 	case XSCALE_CYCLE_COUNTER:
763 		asm volatile("mrc p14, 0, %0, c1, c1, 0" : "=r" (val));
764 		break;
765 	case XSCALE_COUNTER0:
766 		asm volatile("mrc p14, 0, %0, c0, c2, 0" : "=r" (val));
767 		break;
768 	case XSCALE_COUNTER1:
769 		asm volatile("mrc p14, 0, %0, c1, c2, 0" : "=r" (val));
770 		break;
771 	case XSCALE_COUNTER2:
772 		asm volatile("mrc p14, 0, %0, c2, c2, 0" : "=r" (val));
773 		break;
774 	case XSCALE_COUNTER3:
775 		asm volatile("mrc p14, 0, %0, c3, c2, 0" : "=r" (val));
776 		break;
777 	}
778 
779 	return val;
780 }
781 
782 static inline void
783 xscale2pmu_write_counter(int counter, u32 val)
784 {
785 	switch (counter) {
786 	case XSCALE_CYCLE_COUNTER:
787 		asm volatile("mcr p14, 0, %0, c1, c1, 0" : : "r" (val));
788 		break;
789 	case XSCALE_COUNTER0:
790 		asm volatile("mcr p14, 0, %0, c0, c2, 0" : : "r" (val));
791 		break;
792 	case XSCALE_COUNTER1:
793 		asm volatile("mcr p14, 0, %0, c1, c2, 0" : : "r" (val));
794 		break;
795 	case XSCALE_COUNTER2:
796 		asm volatile("mcr p14, 0, %0, c2, c2, 0" : : "r" (val));
797 		break;
798 	case XSCALE_COUNTER3:
799 		asm volatile("mcr p14, 0, %0, c3, c2, 0" : : "r" (val));
800 		break;
801 	}
802 }
803 
804 static struct arm_pmu xscale2pmu = {
805 	.name		= "xscale2",
806 	.handle_irq	= xscale2pmu_handle_irq,
807 	.enable		= xscale2pmu_enable_event,
808 	.disable	= xscale2pmu_disable_event,
809 	.read_counter	= xscale2pmu_read_counter,
810 	.write_counter	= xscale2pmu_write_counter,
811 	.get_event_idx	= xscale2pmu_get_event_idx,
812 	.start		= xscale2pmu_start,
813 	.stop		= xscale2pmu_stop,
814 	.map_event	= xscale_map_event,
815 	.num_events	= 5,
816 	.max_period	= (1LLU << 32) - 1,
817 };
818 
819 static struct arm_pmu *__devinit xscale2pmu_init(void)
820 {
821 	return &xscale2pmu;
822 }
823 #else
824 static struct arm_pmu *__devinit xscale1pmu_init(void)
825 {
826 	return NULL;
827 }
828 
829 static struct arm_pmu *__devinit xscale2pmu_init(void)
830 {
831 	return NULL;
832 }
833 #endif	/* CONFIG_CPU_XSCALE */
834