ARM: perf: Only reset PMxEVCNTCR registers on reset
[deliverable/linux.git] / arch / arm / kernel / perf_event_v7.c
CommitLineData
43eab878
WD
1/*
2 * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code.
3 *
4 * ARMv7 support: Jean Pihet <jpihet@mvista.com>
5 * 2010 (c) MontaVista Software, LLC.
6 *
7 * Copied from ARMv6 code, with the low level code inspired
8 * by the ARMv7 Oprofile code.
9 *
10 * Cortex-A8 has up to 4 configurable performance counters and
11 * a single cycle counter.
12 * Cortex-A9 has up to 31 configurable performance counters and
13 * a single cycle counter.
14 *
15 * All counters can be enabled/disabled and IRQ masked separately. The cycle
16 * counter and all 4 performance counters together can be reset separately.
17 */
18
19#ifdef CONFIG_CPU_V7
a505addc 20
b7aafe99
SB
21#include <asm/cp15.h>
22#include <asm/vfp.h>
23#include "../vfp/vfpinstr.h"
24
6d4eaf99
WD
25/*
26 * Common ARMv7 event types
27 *
28 * Note: An implementation may not be able to count all of these events
29 * but the encodings are considered to be `reserved' in the case that
30 * they are not available.
31 */
43eab878 32enum armv7_perf_types {
4d301512
WD
33 ARMV7_PERFCTR_PMNC_SW_INCR = 0x00,
34 ARMV7_PERFCTR_L1_ICACHE_REFILL = 0x01,
35 ARMV7_PERFCTR_ITLB_REFILL = 0x02,
36 ARMV7_PERFCTR_L1_DCACHE_REFILL = 0x03,
37 ARMV7_PERFCTR_L1_DCACHE_ACCESS = 0x04,
38 ARMV7_PERFCTR_DTLB_REFILL = 0x05,
39 ARMV7_PERFCTR_MEM_READ = 0x06,
40 ARMV7_PERFCTR_MEM_WRITE = 0x07,
41 ARMV7_PERFCTR_INSTR_EXECUTED = 0x08,
42 ARMV7_PERFCTR_EXC_TAKEN = 0x09,
43 ARMV7_PERFCTR_EXC_EXECUTED = 0x0A,
44 ARMV7_PERFCTR_CID_WRITE = 0x0B,
45
46 /*
47 * ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
43eab878 48 * It counts:
4d301512 49 * - all (taken) branch instructions,
43eab878
WD
50 * - instructions that explicitly write the PC,
51 * - exception generating instructions.
52 */
4d301512
WD
53 ARMV7_PERFCTR_PC_WRITE = 0x0C,
54 ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D,
55 ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E,
56 ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS = 0x0F,
57 ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
58 ARMV7_PERFCTR_CLOCK_CYCLES = 0x11,
59 ARMV7_PERFCTR_PC_BRANCH_PRED = 0x12,
6d4eaf99
WD
60
61 /* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
4d301512
WD
62 ARMV7_PERFCTR_MEM_ACCESS = 0x13,
63 ARMV7_PERFCTR_L1_ICACHE_ACCESS = 0x14,
64 ARMV7_PERFCTR_L1_DCACHE_WB = 0x15,
65 ARMV7_PERFCTR_L2_CACHE_ACCESS = 0x16,
66 ARMV7_PERFCTR_L2_CACHE_REFILL = 0x17,
67 ARMV7_PERFCTR_L2_CACHE_WB = 0x18,
68 ARMV7_PERFCTR_BUS_ACCESS = 0x19,
69 ARMV7_PERFCTR_MEM_ERROR = 0x1A,
70 ARMV7_PERFCTR_INSTR_SPEC = 0x1B,
71 ARMV7_PERFCTR_TTBR_WRITE = 0x1C,
72 ARMV7_PERFCTR_BUS_CYCLES = 0x1D,
73
74 ARMV7_PERFCTR_CPU_CYCLES = 0xFF
43eab878
WD
75};
76
77/* ARMv7 Cortex-A8 specific event types */
78enum armv7_a8_perf_types {
4d301512
WD
79 ARMV7_A8_PERFCTR_L2_CACHE_ACCESS = 0x43,
80 ARMV7_A8_PERFCTR_L2_CACHE_REFILL = 0x44,
81 ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS = 0x50,
0445e7a5 82 ARMV7_A8_PERFCTR_STALL_ISIDE = 0x56,
43eab878
WD
83};
84
85/* ARMv7 Cortex-A9 specific event types */
86enum armv7_a9_perf_types {
4d301512 87 ARMV7_A9_PERFCTR_INSTR_CORE_RENAME = 0x68,
0445e7a5
WD
88 ARMV7_A9_PERFCTR_STALL_ICACHE = 0x60,
89 ARMV7_A9_PERFCTR_STALL_DISPATCH = 0x66,
43eab878
WD
90};
91
0c205cbe
WD
92/* ARMv7 Cortex-A5 specific event types */
93enum armv7_a5_perf_types {
4d301512
WD
94 ARMV7_A5_PERFCTR_PREFETCH_LINEFILL = 0xc2,
95 ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP = 0xc3,
0c205cbe
WD
96};
97
14abd038
WD
98/* ARMv7 Cortex-A15 specific event types */
99enum armv7_a15_perf_types {
4d301512
WD
100 ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ = 0x40,
101 ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE = 0x41,
102 ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ = 0x42,
103 ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE = 0x43,
14abd038 104
4d301512
WD
105 ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ = 0x4C,
106 ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE = 0x4D,
14abd038 107
4d301512
WD
108 ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ = 0x50,
109 ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE = 0x51,
110 ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ = 0x52,
111 ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE = 0x53,
14abd038 112
4d301512 113 ARMV7_A15_PERFCTR_PC_WRITE_SPEC = 0x76,
14abd038
WD
114};
115
8e781f65
AT
116/* ARMv7 Cortex-A12 specific event types */
117enum armv7_a12_perf_types {
118 ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ = 0x40,
119 ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE = 0x41,
120
121 ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ = 0x50,
122 ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE = 0x51,
123
124 ARMV7_A12_PERFCTR_PC_WRITE_SPEC = 0x76,
125
126 ARMV7_A12_PERFCTR_PF_TLB_REFILL = 0xe7,
127};
128
b7aafe99
SB
129/* ARMv7 Krait specific event types */
130enum krait_perf_types {
131 KRAIT_PMRESR0_GROUP0 = 0xcc,
132 KRAIT_PMRESR1_GROUP0 = 0xd0,
133 KRAIT_PMRESR2_GROUP0 = 0xd4,
134 KRAIT_VPMRESR0_GROUP0 = 0xd8,
135
136 KRAIT_PERFCTR_L1_ICACHE_ACCESS = 0x10011,
137 KRAIT_PERFCTR_L1_ICACHE_MISS = 0x10010,
138
139 KRAIT_PERFCTR_L1_ITLB_ACCESS = 0x12222,
140 KRAIT_PERFCTR_L1_DTLB_ACCESS = 0x12210,
141};
142
43eab878
WD
143/*
144 * Cortex-A8 HW events mapping
145 *
146 * The hardware events that we support. We do support cache operations but
147 * we have harvard caches and no way to combine instruction and data
148 * accesses/misses in hardware.
149 */
150static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = {
6b7658ec 151 PERF_MAP_ALL_UNSUPPORTED,
0445e7a5
WD
152 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
153 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
154 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
155 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
156 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
157 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
0445e7a5 158 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV7_A8_PERFCTR_STALL_ISIDE,
43eab878
WD
159};
160
161static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
162 [PERF_COUNT_HW_CACHE_OP_MAX]
163 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
6b7658ec
MR
164 PERF_CACHE_MAP_ALL_UNSUPPORTED,
165
166 /*
167 * The performance counters don't differentiate between read and write
168 * accesses/misses so this isn't strictly correct, but it's the best we
169 * can do. Writes and reads get combined.
170 */
171 [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
172 [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
173 [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
174 [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
175
176 [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS,
177 [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
178
179 [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS,
180 [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL,
181 [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS,
182 [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL,
183
184 [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
185 [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
186
187 [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
188 [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
189
190 [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
191 [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
192 [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
193 [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
43eab878
WD
194};
195
196/*
197 * Cortex-A9 HW events mapping
198 */
199static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
6b7658ec 200 PERF_MAP_ALL_UNSUPPORTED,
0445e7a5
WD
201 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
202 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_A9_PERFCTR_INSTR_CORE_RENAME,
203 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
204 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
205 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
206 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
0445e7a5
WD
207 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV7_A9_PERFCTR_STALL_ICACHE,
208 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV7_A9_PERFCTR_STALL_DISPATCH,
43eab878
WD
209};
210
211static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
212 [PERF_COUNT_HW_CACHE_OP_MAX]
213 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
6b7658ec
MR
214 PERF_CACHE_MAP_ALL_UNSUPPORTED,
215
216 /*
217 * The performance counters don't differentiate between read and write
218 * accesses/misses so this isn't strictly correct, but it's the best we
219 * can do. Writes and reads get combined.
220 */
221 [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
222 [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
223 [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
224 [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
225
226 [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
227
228 [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
229 [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
230
231 [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
232 [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
233
234 [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
235 [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
236 [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
237 [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
43eab878
WD
238};
239
0c205cbe
WD
240/*
241 * Cortex-A5 HW events mapping
242 */
243static const unsigned armv7_a5_perf_map[PERF_COUNT_HW_MAX] = {
6b7658ec 244 PERF_MAP_ALL_UNSUPPORTED,
0445e7a5
WD
245 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
246 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
247 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
248 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
249 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
250 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
0c205cbe
WD
251};
252
253static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
254 [PERF_COUNT_HW_CACHE_OP_MAX]
255 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
6b7658ec
MR
256 PERF_CACHE_MAP_ALL_UNSUPPORTED,
257
258 [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
259 [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
260 [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
261 [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
262 [C(L1D)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL,
263 [C(L1D)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP,
264
265 [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
266 [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
267 /*
268 * The prefetch counters don't differentiate between the I side and the
269 * D side.
270 */
271 [C(L1I)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL,
272 [C(L1I)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP,
273
274 [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
275 [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
276
277 [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
278 [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
279
280 [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
281 [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
282 [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
283 [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
0c205cbe
WD
284};
285
14abd038
WD
286/*
287 * Cortex-A15 HW events mapping
288 */
289static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = {
6b7658ec 290 PERF_MAP_ALL_UNSUPPORTED,
0445e7a5
WD
291 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
292 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
293 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
294 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
295 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A15_PERFCTR_PC_WRITE_SPEC,
296 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
297 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
14abd038
WD
298};
299
300static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
301 [PERF_COUNT_HW_CACHE_OP_MAX]
302 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
6b7658ec
MR
303 PERF_CACHE_MAP_ALL_UNSUPPORTED,
304
305 [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ,
306 [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ,
307 [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE,
308 [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE,
309
310 /*
311 * Not all performance counters differentiate between read and write
312 * accesses/misses so we're not always strictly correct, but it's the
313 * best we can do. Writes and reads get combined in these cases.
314 */
315 [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
316 [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
317
318 [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ,
319 [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ,
320 [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE,
321 [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE,
322
323 [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ,
324 [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE,
325
326 [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
327 [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
328
329 [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
330 [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
331 [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
332 [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
14abd038
WD
333};
334
d33c88c6
WD
335/*
336 * Cortex-A7 HW events mapping
337 */
338static const unsigned armv7_a7_perf_map[PERF_COUNT_HW_MAX] = {
6b7658ec 339 PERF_MAP_ALL_UNSUPPORTED,
d33c88c6
WD
340 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
341 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
342 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
343 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
344 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
345 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
346 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
d33c88c6
WD
347};
348
349static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
350 [PERF_COUNT_HW_CACHE_OP_MAX]
351 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
6b7658ec
MR
352 PERF_CACHE_MAP_ALL_UNSUPPORTED,
353
354 /*
355 * The performance counters don't differentiate between read and write
356 * accesses/misses so this isn't strictly correct, but it's the best we
357 * can do. Writes and reads get combined.
358 */
359 [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
360 [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
361 [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
362 [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
363
364 [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
365 [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
366
367 [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS,
368 [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
369 [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS,
370 [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
371
372 [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
373 [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
374
375 [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
376 [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
377
378 [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
379 [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
380 [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
381 [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
d33c88c6
WD
382};
383
8e781f65
AT
384/*
385 * Cortex-A12 HW events mapping
386 */
387static const unsigned armv7_a12_perf_map[PERF_COUNT_HW_MAX] = {
6b7658ec 388 PERF_MAP_ALL_UNSUPPORTED,
8e781f65
AT
389 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
390 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
391 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
392 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
393 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A12_PERFCTR_PC_WRITE_SPEC,
394 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
395 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
8e781f65
AT
396};
397
398static const unsigned armv7_a12_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
399 [PERF_COUNT_HW_CACHE_OP_MAX]
400 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
6b7658ec
MR
401 PERF_CACHE_MAP_ALL_UNSUPPORTED,
402
403 [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ,
404 [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
405 [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE,
406 [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
407
408 /*
409 * Not all performance counters differentiate between read and write
410 * accesses/misses so we're not always strictly correct, but it's the
411 * best we can do. Writes and reads get combined in these cases.
412 */
413 [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
414 [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
415
416 [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ,
417 [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
418 [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE,
419 [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
420
421 [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
422 [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
423 [C(DTLB)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV7_A12_PERFCTR_PF_TLB_REFILL,
424
425 [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
426 [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
427
428 [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
429 [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
430 [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
431 [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
8e781f65
AT
432};
433
2a3391cd
SB
434/*
435 * Krait HW events mapping
436 */
437static const unsigned krait_perf_map[PERF_COUNT_HW_MAX] = {
6b7658ec 438 PERF_MAP_ALL_UNSUPPORTED,
2a3391cd
SB
439 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
440 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
2a3391cd
SB
441 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
442 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
443 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
444};
445
446static const unsigned krait_perf_map_no_branch[PERF_COUNT_HW_MAX] = {
6b7658ec 447 PERF_MAP_ALL_UNSUPPORTED,
2a3391cd
SB
448 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
449 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
2a3391cd
SB
450 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
451 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
452};
453
454static const unsigned krait_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
455 [PERF_COUNT_HW_CACHE_OP_MAX]
456 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
6b7658ec
MR
457 PERF_CACHE_MAP_ALL_UNSUPPORTED,
458
459 /*
460 * The performance counters don't differentiate between read and write
461 * accesses/misses so this isn't strictly correct, but it's the best we
462 * can do. Writes and reads get combined.
463 */
464 [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
465 [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
466 [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
467 [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
468
469 [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ICACHE_ACCESS,
470 [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = KRAIT_PERFCTR_L1_ICACHE_MISS,
471
472 [C(DTLB)][C(OP_READ)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_DTLB_ACCESS,
473 [C(DTLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_DTLB_ACCESS,
474
475 [C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ITLB_ACCESS,
476 [C(ITLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ITLB_ACCESS,
477
478 [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
479 [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
480 [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
481 [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
2a3391cd
SB
482};
483
43eab878 484/*
c691bb62 485 * Perf Events' indices
43eab878 486 */
c691bb62
WD
487#define ARMV7_IDX_CYCLE_COUNTER 0
488#define ARMV7_IDX_COUNTER0 1
7279adbd
SK
489#define ARMV7_IDX_COUNTER_LAST(cpu_pmu) \
490 (ARMV7_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1)
c691bb62
WD
491
492#define ARMV7_MAX_COUNTERS 32
493#define ARMV7_COUNTER_MASK (ARMV7_MAX_COUNTERS - 1)
43eab878
WD
494
495/*
c691bb62 496 * ARMv7 low level PMNC access
43eab878 497 */
43eab878
WD
498
499/*
c691bb62 500 * Perf Event to low level counters mapping
43eab878 501 */
c691bb62
WD
502#define ARMV7_IDX_TO_COUNTER(x) \
503 (((x) - ARMV7_IDX_COUNTER0) & ARMV7_COUNTER_MASK)
43eab878
WD
504
505/*
506 * Per-CPU PMNC: config reg
507 */
508#define ARMV7_PMNC_E (1 << 0) /* Enable all counters */
509#define ARMV7_PMNC_P (1 << 1) /* Reset all counters */
510#define ARMV7_PMNC_C (1 << 2) /* Cycle counter reset */
511#define ARMV7_PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
512#define ARMV7_PMNC_X (1 << 4) /* Export to ETM */
513#define ARMV7_PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
514#define ARMV7_PMNC_N_SHIFT 11 /* Number of counters supported */
515#define ARMV7_PMNC_N_MASK 0x1f
516#define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */
517
518/*
43eab878 519 * FLAG: counters overflow flag status reg
43eab878 520 */
43eab878
WD
521#define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */
522#define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK
43eab878
WD
523
524/*
a505addc 525 * PMXEVTYPER: Event selection reg
43eab878 526 */
f2fe09b0 527#define ARMV7_EVTYPE_MASK 0xc80000ff /* Mask for writable bits */
a505addc 528#define ARMV7_EVTYPE_EVENT 0xff /* Mask for EVENT bits */
43eab878
WD
529
530/*
a505addc 531 * Event filters for PMUv2
43eab878 532 */
a505addc
WD
533#define ARMV7_EXCLUDE_PL1 (1 << 31)
534#define ARMV7_EXCLUDE_USER (1 << 30)
535#define ARMV7_INCLUDE_HYP (1 << 27)
43eab878 536
6330aae7 537static inline u32 armv7_pmnc_read(void)
43eab878
WD
538{
539 u32 val;
540 asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
541 return val;
542}
543
6330aae7 544static inline void armv7_pmnc_write(u32 val)
43eab878
WD
545{
546 val &= ARMV7_PMNC_MASK;
d25d3b4c 547 isb();
43eab878
WD
548 asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
549}
550
6330aae7 551static inline int armv7_pmnc_has_overflowed(u32 pmnc)
43eab878
WD
552{
553 return pmnc & ARMV7_OVERFLOWED_MASK;
554}
555
7279adbd 556static inline int armv7_pmnc_counter_valid(struct arm_pmu *cpu_pmu, int idx)
c691bb62 557{
7279adbd
SK
558 return idx >= ARMV7_IDX_CYCLE_COUNTER &&
559 idx <= ARMV7_IDX_COUNTER_LAST(cpu_pmu);
c691bb62
WD
560}
561
562static inline int armv7_pmnc_counter_has_overflowed(u32 pmnc, int idx)
43eab878 563{
7279adbd 564 return pmnc & BIT(ARMV7_IDX_TO_COUNTER(idx));
43eab878
WD
565}
566
cb6eb108 567static inline void armv7_pmnc_select_counter(int idx)
43eab878 568{
7279adbd 569 u32 counter = ARMV7_IDX_TO_COUNTER(idx);
c691bb62 570 asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (counter));
d25d3b4c 571 isb();
43eab878
WD
572}
573
ed6f2a52 574static inline u32 armv7pmu_read_counter(struct perf_event *event)
43eab878 575{
7279adbd 576 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
ed6f2a52
SK
577 struct hw_perf_event *hwc = &event->hw;
578 int idx = hwc->idx;
6330aae7 579 u32 value = 0;
43eab878 580
cb6eb108 581 if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
43eab878
WD
582 pr_err("CPU%u reading wrong counter %d\n",
583 smp_processor_id(), idx);
cb6eb108 584 } else if (idx == ARMV7_IDX_CYCLE_COUNTER) {
c691bb62 585 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
cb6eb108 586 } else {
587 armv7_pmnc_select_counter(idx);
c691bb62 588 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (value));
cb6eb108 589 }
43eab878
WD
590
591 return value;
592}
593
ed6f2a52 594static inline void armv7pmu_write_counter(struct perf_event *event, u32 value)
43eab878 595{
7279adbd 596 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
ed6f2a52
SK
597 struct hw_perf_event *hwc = &event->hw;
598 int idx = hwc->idx;
599
cb6eb108 600 if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
43eab878
WD
601 pr_err("CPU%u writing wrong counter %d\n",
602 smp_processor_id(), idx);
cb6eb108 603 } else if (idx == ARMV7_IDX_CYCLE_COUNTER) {
c691bb62 604 asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
cb6eb108 605 } else {
606 armv7_pmnc_select_counter(idx);
c691bb62 607 asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (value));
cb6eb108 608 }
43eab878
WD
609}
610
25e29c7c 611static inline void armv7_pmnc_write_evtsel(int idx, u32 val)
43eab878 612{
cb6eb108 613 armv7_pmnc_select_counter(idx);
614 val &= ARMV7_EVTYPE_MASK;
615 asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
43eab878
WD
616}
617
cb6eb108 618static inline void armv7_pmnc_enable_counter(int idx)
43eab878 619{
7279adbd 620 u32 counter = ARMV7_IDX_TO_COUNTER(idx);
c691bb62 621 asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(counter)));
43eab878
WD
622}
623
cb6eb108 624static inline void armv7_pmnc_disable_counter(int idx)
43eab878 625{
7279adbd 626 u32 counter = ARMV7_IDX_TO_COUNTER(idx);
c691bb62 627 asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(counter)));
43eab878
WD
628}
629
cb6eb108 630static inline void armv7_pmnc_enable_intens(int idx)
43eab878 631{
7279adbd 632 u32 counter = ARMV7_IDX_TO_COUNTER(idx);
c691bb62 633 asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(counter)));
43eab878
WD
634}
635
cb6eb108 636static inline void armv7_pmnc_disable_intens(int idx)
43eab878 637{
7279adbd 638 u32 counter = ARMV7_IDX_TO_COUNTER(idx);
c691bb62 639 asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(counter)));
99c1745b
WD
640 isb();
641 /* Clear the overflow flag in case an interrupt is pending. */
642 asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (BIT(counter)));
643 isb();
43eab878
WD
644}
645
646static inline u32 armv7_pmnc_getreset_flags(void)
647{
648 u32 val;
649
650 /* Read */
651 asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
652
653 /* Write to clear flags */
654 val &= ARMV7_FLAG_MASK;
655 asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
656
657 return val;
658}
659
660#ifdef DEBUG
7279adbd 661static void armv7_pmnc_dump_regs(struct arm_pmu *cpu_pmu)
43eab878
WD
662{
663 u32 val;
664 unsigned int cnt;
665
52a5566e 666 pr_info("PMNC registers dump:\n");
43eab878
WD
667
668 asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
52a5566e 669 pr_info("PMNC =0x%08x\n", val);
43eab878
WD
670
671 asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
52a5566e 672 pr_info("CNTENS=0x%08x\n", val);
43eab878
WD
673
674 asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
52a5566e 675 pr_info("INTENS=0x%08x\n", val);
43eab878
WD
676
677 asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
52a5566e 678 pr_info("FLAGS =0x%08x\n", val);
43eab878
WD
679
680 asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
52a5566e 681 pr_info("SELECT=0x%08x\n", val);
43eab878
WD
682
683 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
52a5566e 684 pr_info("CCNT =0x%08x\n", val);
43eab878 685
7279adbd
SK
686 for (cnt = ARMV7_IDX_COUNTER0;
687 cnt <= ARMV7_IDX_COUNTER_LAST(cpu_pmu); cnt++) {
43eab878
WD
688 armv7_pmnc_select_counter(cnt);
689 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
52a5566e 690 pr_info("CNT[%d] count =0x%08x\n",
c691bb62 691 ARMV7_IDX_TO_COUNTER(cnt), val);
43eab878 692 asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
52a5566e 693 pr_info("CNT[%d] evtsel=0x%08x\n",
c691bb62 694 ARMV7_IDX_TO_COUNTER(cnt), val);
43eab878
WD
695 }
696}
697#endif
698
ed6f2a52 699static void armv7pmu_enable_event(struct perf_event *event)
43eab878
WD
700{
701 unsigned long flags;
ed6f2a52
SK
702 struct hw_perf_event *hwc = &event->hw;
703 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
11679250 704 struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
ed6f2a52 705 int idx = hwc->idx;
43eab878 706
7279adbd
SK
707 if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
708 pr_err("CPU%u enabling wrong PMNC counter IRQ enable %d\n",
709 smp_processor_id(), idx);
710 return;
711 }
712
43eab878
WD
713 /*
714 * Enable counter and interrupt, and set the counter to count
715 * the event that we're interested in.
716 */
0f78d2d5 717 raw_spin_lock_irqsave(&events->pmu_lock, flags);
43eab878
WD
718
719 /*
720 * Disable counter
721 */
722 armv7_pmnc_disable_counter(idx);
723
724 /*
725 * Set event (if destined for PMNx counters)
a505addc
WD
726 * We only need to set the event for the cycle counter if we
727 * have the ability to perform event filtering.
43eab878 728 */
513c99ce 729 if (cpu_pmu->set_event_filter || idx != ARMV7_IDX_CYCLE_COUNTER)
43eab878
WD
730 armv7_pmnc_write_evtsel(idx, hwc->config_base);
731
732 /*
733 * Enable interrupt for this counter
734 */
735 armv7_pmnc_enable_intens(idx);
736
737 /*
738 * Enable counter
739 */
740 armv7_pmnc_enable_counter(idx);
741
0f78d2d5 742 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
43eab878
WD
743}
744
ed6f2a52 745static void armv7pmu_disable_event(struct perf_event *event)
43eab878
WD
746{
747 unsigned long flags;
ed6f2a52
SK
748 struct hw_perf_event *hwc = &event->hw;
749 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
11679250 750 struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
ed6f2a52 751 int idx = hwc->idx;
43eab878 752
7279adbd
SK
753 if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
754 pr_err("CPU%u disabling wrong PMNC counter IRQ enable %d\n",
755 smp_processor_id(), idx);
756 return;
757 }
758
43eab878
WD
759 /*
760 * Disable counter and interrupt
761 */
0f78d2d5 762 raw_spin_lock_irqsave(&events->pmu_lock, flags);
43eab878
WD
763
764 /*
765 * Disable counter
766 */
767 armv7_pmnc_disable_counter(idx);
768
769 /*
770 * Disable interrupt for this counter
771 */
772 armv7_pmnc_disable_intens(idx);
773
0f78d2d5 774 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
43eab878
WD
775}
776
777static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
778{
6330aae7 779 u32 pmnc;
43eab878 780 struct perf_sample_data data;
ed6f2a52 781 struct arm_pmu *cpu_pmu = (struct arm_pmu *)dev;
11679250 782 struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
43eab878
WD
783 struct pt_regs *regs;
784 int idx;
785
786 /*
787 * Get and reset the IRQ flags
788 */
789 pmnc = armv7_pmnc_getreset_flags();
790
791 /*
792 * Did an overflow occur?
793 */
794 if (!armv7_pmnc_has_overflowed(pmnc))
795 return IRQ_NONE;
796
797 /*
798 * Handle the counter(s) overflow(s)
799 */
800 regs = get_irq_regs();
801
8be3f9a2 802 for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
43eab878
WD
803 struct perf_event *event = cpuc->events[idx];
804 struct hw_perf_event *hwc;
805
f6f5a30c
WD
806 /* Ignore if we don't have an event. */
807 if (!event)
808 continue;
809
43eab878
WD
810 /*
811 * We have a single interrupt for all counters. Check that
812 * each counter has overflowed before we process it.
813 */
814 if (!armv7_pmnc_counter_has_overflowed(pmnc, idx))
815 continue;
816
817 hwc = &event->hw;
ed6f2a52 818 armpmu_event_update(event);
fd0d000b 819 perf_sample_data_init(&data, 0, hwc->last_period);
ed6f2a52 820 if (!armpmu_event_set_period(event))
43eab878
WD
821 continue;
822
a8b0ca17 823 if (perf_event_overflow(event, &data, regs))
ed6f2a52 824 cpu_pmu->disable(event);
43eab878
WD
825 }
826
827 /*
828 * Handle the pending perf events.
829 *
830 * Note: this call *must* be run with interrupts disabled. For
831 * platforms that can have the PMU interrupts raised as an NMI, this
832 * will not work.
833 */
834 irq_work_run();
835
836 return IRQ_HANDLED;
837}
838
ed6f2a52 839static void armv7pmu_start(struct arm_pmu *cpu_pmu)
43eab878
WD
840{
841 unsigned long flags;
11679250 842 struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
43eab878 843
0f78d2d5 844 raw_spin_lock_irqsave(&events->pmu_lock, flags);
43eab878
WD
845 /* Enable all counters */
846 armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
0f78d2d5 847 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
43eab878
WD
848}
849
ed6f2a52 850static void armv7pmu_stop(struct arm_pmu *cpu_pmu)
43eab878
WD
851{
852 unsigned long flags;
11679250 853 struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
43eab878 854
0f78d2d5 855 raw_spin_lock_irqsave(&events->pmu_lock, flags);
43eab878
WD
856 /* Disable all counters */
857 armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E);
0f78d2d5 858 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
43eab878
WD
859}
860
8be3f9a2 861static int armv7pmu_get_event_idx(struct pmu_hw_events *cpuc,
ed6f2a52 862 struct perf_event *event)
43eab878
WD
863{
864 int idx;
ed6f2a52
SK
865 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
866 struct hw_perf_event *hwc = &event->hw;
867 unsigned long evtype = hwc->config_base & ARMV7_EVTYPE_EVENT;
43eab878
WD
868
869 /* Always place a cycle counter into the cycle counter. */
a505addc 870 if (evtype == ARMV7_PERFCTR_CPU_CYCLES) {
c691bb62 871 if (test_and_set_bit(ARMV7_IDX_CYCLE_COUNTER, cpuc->used_mask))
43eab878
WD
872 return -EAGAIN;
873
c691bb62
WD
874 return ARMV7_IDX_CYCLE_COUNTER;
875 }
43eab878 876
c691bb62
WD
877 /*
878 * For anything other than a cycle counter, try and use
879 * the events counters
880 */
8be3f9a2 881 for (idx = ARMV7_IDX_COUNTER0; idx < cpu_pmu->num_events; ++idx) {
c691bb62
WD
882 if (!test_and_set_bit(idx, cpuc->used_mask))
883 return idx;
43eab878 884 }
c691bb62
WD
885
886 /* The counters are all in use. */
887 return -EAGAIN;
43eab878
WD
888}
889
a505addc
WD
890/*
891 * Add an event filter to a given event. This will only work for PMUv2 PMUs.
892 */
893static int armv7pmu_set_event_filter(struct hw_perf_event *event,
894 struct perf_event_attr *attr)
895{
896 unsigned long config_base = 0;
897
898 if (attr->exclude_idle)
899 return -EPERM;
900 if (attr->exclude_user)
901 config_base |= ARMV7_EXCLUDE_USER;
902 if (attr->exclude_kernel)
903 config_base |= ARMV7_EXCLUDE_PL1;
904 if (!attr->exclude_hv)
905 config_base |= ARMV7_INCLUDE_HYP;
906
907 /*
908 * Install the filter into config_base as this is used to
909 * construct the event type.
910 */
911 event->config_base = config_base;
912
913 return 0;
43eab878
WD
914}
915
574b69cb
WD
916static void armv7pmu_reset(void *info)
917{
ed6f2a52 918 struct arm_pmu *cpu_pmu = (struct arm_pmu *)info;
8be3f9a2 919 u32 idx, nb_cnt = cpu_pmu->num_events;
574b69cb
WD
920
921 /* The counter and interrupt enable registers are unknown at reset. */
ed6f2a52
SK
922 for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) {
923 armv7_pmnc_disable_counter(idx);
924 armv7_pmnc_disable_intens(idx);
925 }
574b69cb
WD
926
927 /* Initialize & Reset PMNC: C and P bits */
928 armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
929}
930
e1f431b5
MR
931static int armv7_a8_map_event(struct perf_event *event)
932{
6dbc0029 933 return armpmu_map_event(event, &armv7_a8_perf_map,
e1f431b5
MR
934 &armv7_a8_perf_cache_map, 0xFF);
935}
936
937static int armv7_a9_map_event(struct perf_event *event)
938{
6dbc0029 939 return armpmu_map_event(event, &armv7_a9_perf_map,
e1f431b5
MR
940 &armv7_a9_perf_cache_map, 0xFF);
941}
942
943static int armv7_a5_map_event(struct perf_event *event)
944{
6dbc0029 945 return armpmu_map_event(event, &armv7_a5_perf_map,
e1f431b5
MR
946 &armv7_a5_perf_cache_map, 0xFF);
947}
948
949static int armv7_a15_map_event(struct perf_event *event)
950{
6dbc0029 951 return armpmu_map_event(event, &armv7_a15_perf_map,
e1f431b5
MR
952 &armv7_a15_perf_cache_map, 0xFF);
953}
954
d33c88c6
WD
955static int armv7_a7_map_event(struct perf_event *event)
956{
6dbc0029 957 return armpmu_map_event(event, &armv7_a7_perf_map,
d33c88c6
WD
958 &armv7_a7_perf_cache_map, 0xFF);
959}
960
8e781f65
AT
961static int armv7_a12_map_event(struct perf_event *event)
962{
963 return armpmu_map_event(event, &armv7_a12_perf_map,
964 &armv7_a12_perf_cache_map, 0xFF);
965}
966
2a3391cd
SB
967static int krait_map_event(struct perf_event *event)
968{
969 return armpmu_map_event(event, &krait_perf_map,
970 &krait_perf_cache_map, 0xFFFFF);
971}
972
973static int krait_map_event_no_branch(struct perf_event *event)
974{
975 return armpmu_map_event(event, &krait_perf_map_no_branch,
976 &krait_perf_cache_map, 0xFFFFF);
977}
978
513c99ce
SK
979static void armv7pmu_init(struct arm_pmu *cpu_pmu)
980{
981 cpu_pmu->handle_irq = armv7pmu_handle_irq;
982 cpu_pmu->enable = armv7pmu_enable_event;
983 cpu_pmu->disable = armv7pmu_disable_event;
984 cpu_pmu->read_counter = armv7pmu_read_counter;
985 cpu_pmu->write_counter = armv7pmu_write_counter;
986 cpu_pmu->get_event_idx = armv7pmu_get_event_idx;
987 cpu_pmu->start = armv7pmu_start;
988 cpu_pmu->stop = armv7pmu_stop;
989 cpu_pmu->reset = armv7pmu_reset;
990 cpu_pmu->max_period = (1LLU << 32) - 1;
43eab878
WD
991};
992
351a102d 993static u32 armv7_read_num_pmnc_events(void)
43eab878
WD
994{
995 u32 nb_cnt;
996
43eab878
WD
997 /* Read the nb of CNTx counters supported from PMNC */
998 nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
999
1000 /* Add the CPU cycles counter and return */
1001 return nb_cnt + 1;
1002}
1003
351a102d 1004static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
43eab878 1005{
513c99ce 1006 armv7pmu_init(cpu_pmu);
3d1ff755 1007 cpu_pmu->name = "armv7_cortex_a8";
513c99ce
SK
1008 cpu_pmu->map_event = armv7_a8_map_event;
1009 cpu_pmu->num_events = armv7_read_num_pmnc_events();
1010 return 0;
43eab878
WD
1011}
1012
351a102d 1013static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
43eab878 1014{
513c99ce 1015 armv7pmu_init(cpu_pmu);
3d1ff755 1016 cpu_pmu->name = "armv7_cortex_a9";
513c99ce
SK
1017 cpu_pmu->map_event = armv7_a9_map_event;
1018 cpu_pmu->num_events = armv7_read_num_pmnc_events();
1019 return 0;
43eab878 1020}
0c205cbe 1021
351a102d 1022static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
0c205cbe 1023{
513c99ce 1024 armv7pmu_init(cpu_pmu);
3d1ff755 1025 cpu_pmu->name = "armv7_cortex_a5";
513c99ce
SK
1026 cpu_pmu->map_event = armv7_a5_map_event;
1027 cpu_pmu->num_events = armv7_read_num_pmnc_events();
1028 return 0;
0c205cbe 1029}
14abd038 1030
351a102d 1031static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
14abd038 1032{
513c99ce 1033 armv7pmu_init(cpu_pmu);
3d1ff755 1034 cpu_pmu->name = "armv7_cortex_a15";
513c99ce
SK
1035 cpu_pmu->map_event = armv7_a15_map_event;
1036 cpu_pmu->num_events = armv7_read_num_pmnc_events();
1037 cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
1038 return 0;
14abd038 1039}
d33c88c6 1040
351a102d 1041static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
d33c88c6 1042{
513c99ce 1043 armv7pmu_init(cpu_pmu);
3d1ff755 1044 cpu_pmu->name = "armv7_cortex_a7";
513c99ce
SK
1045 cpu_pmu->map_event = armv7_a7_map_event;
1046 cpu_pmu->num_events = armv7_read_num_pmnc_events();
1047 cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
1048 return 0;
d33c88c6 1049}
2a3391cd 1050
8e781f65
AT
1051static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
1052{
1053 armv7pmu_init(cpu_pmu);
3d1ff755 1054 cpu_pmu->name = "armv7_cortex_a12";
8e781f65
AT
1055 cpu_pmu->map_event = armv7_a12_map_event;
1056 cpu_pmu->num_events = armv7_read_num_pmnc_events();
1057 cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
1058 return 0;
1059}
1060
03eff46c
WD
1061static int armv7_a17_pmu_init(struct arm_pmu *cpu_pmu)
1062{
1063 armv7_a12_pmu_init(cpu_pmu);
3d1ff755 1064 cpu_pmu->name = "armv7_cortex_a17";
03eff46c
WD
1065 return 0;
1066}
1067
b7aafe99
SB
1068/*
1069 * Krait Performance Monitor Region Event Selection Register (PMRESRn)
1070 *
1071 * 31 30 24 16 8 0
1072 * +--------------------------------+
1073 * PMRESR0 | EN | CC | CC | CC | CC | N = 1, R = 0
1074 * +--------------------------------+
1075 * PMRESR1 | EN | CC | CC | CC | CC | N = 1, R = 1
1076 * +--------------------------------+
1077 * PMRESR2 | EN | CC | CC | CC | CC | N = 1, R = 2
1078 * +--------------------------------+
1079 * VPMRESR0 | EN | CC | CC | CC | CC | N = 2, R = ?
1080 * +--------------------------------+
1081 * EN | G=3 | G=2 | G=1 | G=0
1082 *
1083 * Event Encoding:
1084 *
1085 * hwc->config_base = 0xNRCCG
1086 *
1087 * N = prefix, 1 for Krait CPU (PMRESRn), 2 for Venum VFP (VPMRESR)
1088 * R = region register
1089 * CC = class of events the group G is choosing from
1090 * G = group or particular event
1091 *
1092 * Example: 0x12021 is a Krait CPU event in PMRESR2's group 1 with code 2
1093 *
1094 * A region (R) corresponds to a piece of the CPU (execution unit, instruction
1095 * unit, etc.) while the event code (CC) corresponds to a particular class of
1096 * events (interrupts for example). An event code is broken down into
1097 * groups (G) that can be mapped into the PMU (irq, fiqs, and irq+fiqs for
1098 * example).
1099 */
1100
1101#define KRAIT_EVENT (1 << 16)
1102#define VENUM_EVENT (2 << 16)
1103#define KRAIT_EVENT_MASK (KRAIT_EVENT | VENUM_EVENT)
1104#define PMRESRn_EN BIT(31)
1105
65bab451
SB
1106#define EVENT_REGION(event) (((event) >> 12) & 0xf) /* R */
1107#define EVENT_GROUP(event) ((event) & 0xf) /* G */
1108#define EVENT_CODE(event) (((event) >> 4) & 0xff) /* CC */
1109#define EVENT_VENUM(event) (!!(event & VENUM_EVENT)) /* N=2 */
1110#define EVENT_CPU(event) (!!(event & KRAIT_EVENT)) /* N=1 */
1111
b7aafe99
SB
1112static u32 krait_read_pmresrn(int n)
1113{
1114 u32 val;
1115
1116 switch (n) {
1117 case 0:
1118 asm volatile("mrc p15, 1, %0, c9, c15, 0" : "=r" (val));
1119 break;
1120 case 1:
1121 asm volatile("mrc p15, 1, %0, c9, c15, 1" : "=r" (val));
1122 break;
1123 case 2:
1124 asm volatile("mrc p15, 1, %0, c9, c15, 2" : "=r" (val));
1125 break;
1126 default:
1127 BUG(); /* Should be validated in krait_pmu_get_event_idx() */
1128 }
1129
1130 return val;
1131}
1132
1133static void krait_write_pmresrn(int n, u32 val)
1134{
1135 switch (n) {
1136 case 0:
1137 asm volatile("mcr p15, 1, %0, c9, c15, 0" : : "r" (val));
1138 break;
1139 case 1:
1140 asm volatile("mcr p15, 1, %0, c9, c15, 1" : : "r" (val));
1141 break;
1142 case 2:
1143 asm volatile("mcr p15, 1, %0, c9, c15, 2" : : "r" (val));
1144 break;
1145 default:
1146 BUG(); /* Should be validated in krait_pmu_get_event_idx() */
1147 }
1148}
1149
65bab451 1150static u32 venum_read_pmresr(void)
b7aafe99
SB
1151{
1152 u32 val;
1153 asm volatile("mrc p10, 7, %0, c11, c0, 0" : "=r" (val));
1154 return val;
1155}
1156
65bab451 1157static void venum_write_pmresr(u32 val)
b7aafe99
SB
1158{
1159 asm volatile("mcr p10, 7, %0, c11, c0, 0" : : "r" (val));
1160}
1161
65bab451 1162static void venum_pre_pmresr(u32 *venum_orig_val, u32 *fp_orig_val)
b7aafe99
SB
1163{
1164 u32 venum_new_val;
1165 u32 fp_new_val;
1166
1167 BUG_ON(preemptible());
1168 /* CPACR Enable CP10 and CP11 access */
1169 *venum_orig_val = get_copro_access();
1170 venum_new_val = *venum_orig_val | CPACC_SVC(10) | CPACC_SVC(11);
1171 set_copro_access(venum_new_val);
1172
1173 /* Enable FPEXC */
1174 *fp_orig_val = fmrx(FPEXC);
1175 fp_new_val = *fp_orig_val | FPEXC_EN;
1176 fmxr(FPEXC, fp_new_val);
1177}
1178
65bab451 1179static void venum_post_pmresr(u32 venum_orig_val, u32 fp_orig_val)
b7aafe99
SB
1180{
1181 BUG_ON(preemptible());
1182 /* Restore FPEXC */
1183 fmxr(FPEXC, fp_orig_val);
1184 isb();
1185 /* Restore CPACR */
1186 set_copro_access(venum_orig_val);
1187}
1188
1189static u32 krait_get_pmresrn_event(unsigned int region)
1190{
1191 static const u32 pmresrn_table[] = { KRAIT_PMRESR0_GROUP0,
1192 KRAIT_PMRESR1_GROUP0,
1193 KRAIT_PMRESR2_GROUP0 };
1194 return pmresrn_table[region];
1195}
1196
1197static void krait_evt_setup(int idx, u32 config_base)
1198{
1199 u32 val;
1200 u32 mask;
1201 u32 vval, fval;
65bab451
SB
1202 unsigned int region = EVENT_REGION(config_base);
1203 unsigned int group = EVENT_GROUP(config_base);
1204 unsigned int code = EVENT_CODE(config_base);
b7aafe99 1205 unsigned int group_shift;
65bab451 1206 bool venum_event = EVENT_VENUM(config_base);
b7aafe99
SB
1207
1208 group_shift = group * 8;
1209 mask = 0xff << group_shift;
1210
1211 /* Configure evtsel for the region and group */
1212 if (venum_event)
1213 val = KRAIT_VPMRESR0_GROUP0;
1214 else
1215 val = krait_get_pmresrn_event(region);
1216 val += group;
1217 /* Mix in mode-exclusion bits */
1218 val |= config_base & (ARMV7_EXCLUDE_USER | ARMV7_EXCLUDE_PL1);
1219 armv7_pmnc_write_evtsel(idx, val);
1220
b7aafe99 1221 if (venum_event) {
65bab451
SB
1222 venum_pre_pmresr(&vval, &fval);
1223 val = venum_read_pmresr();
b7aafe99
SB
1224 val &= ~mask;
1225 val |= code << group_shift;
1226 val |= PMRESRn_EN;
65bab451
SB
1227 venum_write_pmresr(val);
1228 venum_post_pmresr(vval, fval);
b7aafe99
SB
1229 } else {
1230 val = krait_read_pmresrn(region);
1231 val &= ~mask;
1232 val |= code << group_shift;
1233 val |= PMRESRn_EN;
1234 krait_write_pmresrn(region, val);
1235 }
1236}
1237
65bab451 1238static u32 clear_pmresrn_group(u32 val, int group)
b7aafe99
SB
1239{
1240 u32 mask;
1241 int group_shift;
1242
1243 group_shift = group * 8;
1244 mask = 0xff << group_shift;
1245 val &= ~mask;
1246
1247 /* Don't clear enable bit if entire region isn't disabled */
1248 if (val & ~PMRESRn_EN)
1249 return val |= PMRESRn_EN;
1250
1251 return 0;
1252}
1253
1254static void krait_clearpmu(u32 config_base)
1255{
1256 u32 val;
1257 u32 vval, fval;
65bab451
SB
1258 unsigned int region = EVENT_REGION(config_base);
1259 unsigned int group = EVENT_GROUP(config_base);
1260 bool venum_event = EVENT_VENUM(config_base);
b7aafe99
SB
1261
1262 if (venum_event) {
65bab451
SB
1263 venum_pre_pmresr(&vval, &fval);
1264 val = venum_read_pmresr();
1265 val = clear_pmresrn_group(val, group);
1266 venum_write_pmresr(val);
1267 venum_post_pmresr(vval, fval);
b7aafe99
SB
1268 } else {
1269 val = krait_read_pmresrn(region);
65bab451 1270 val = clear_pmresrn_group(val, group);
b7aafe99
SB
1271 krait_write_pmresrn(region, val);
1272 }
1273}
1274
1275static void krait_pmu_disable_event(struct perf_event *event)
1276{
1277 unsigned long flags;
1278 struct hw_perf_event *hwc = &event->hw;
1279 int idx = hwc->idx;
037e79aa 1280 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
11679250 1281 struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
b7aafe99
SB
1282
1283 /* Disable counter and interrupt */
1284 raw_spin_lock_irqsave(&events->pmu_lock, flags);
1285
1286 /* Disable counter */
1287 armv7_pmnc_disable_counter(idx);
1288
1289 /*
1290 * Clear pmresr code (if destined for PMNx counters)
1291 */
1292 if (hwc->config_base & KRAIT_EVENT_MASK)
1293 krait_clearpmu(hwc->config_base);
1294
1295 /* Disable interrupt for this counter */
1296 armv7_pmnc_disable_intens(idx);
1297
1298 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1299}
1300
1301static void krait_pmu_enable_event(struct perf_event *event)
1302{
1303 unsigned long flags;
1304 struct hw_perf_event *hwc = &event->hw;
1305 int idx = hwc->idx;
037e79aa 1306 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
11679250 1307 struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
b7aafe99
SB
1308
1309 /*
1310 * Enable counter and interrupt, and set the counter to count
1311 * the event that we're interested in.
1312 */
1313 raw_spin_lock_irqsave(&events->pmu_lock, flags);
1314
1315 /* Disable counter */
1316 armv7_pmnc_disable_counter(idx);
1317
1318 /*
1319 * Set event (if destined for PMNx counters)
1320 * We set the event for the cycle counter because we
1321 * have the ability to perform event filtering.
1322 */
1323 if (hwc->config_base & KRAIT_EVENT_MASK)
1324 krait_evt_setup(idx, hwc->config_base);
1325 else
1326 armv7_pmnc_write_evtsel(idx, hwc->config_base);
1327
1328 /* Enable interrupt for this counter */
1329 armv7_pmnc_enable_intens(idx);
1330
1331 /* Enable counter */
1332 armv7_pmnc_enable_counter(idx);
1333
1334 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1335}
1336
1337static void krait_pmu_reset(void *info)
1338{
1339 u32 vval, fval;
93499918
SB
1340 struct arm_pmu *cpu_pmu = info;
1341 u32 idx, nb_cnt = cpu_pmu->num_events;
b7aafe99
SB
1342
1343 armv7pmu_reset(info);
1344
1345 /* Clear all pmresrs */
1346 krait_write_pmresrn(0, 0);
1347 krait_write_pmresrn(1, 0);
1348 krait_write_pmresrn(2, 0);
1349
65bab451
SB
1350 venum_pre_pmresr(&vval, &fval);
1351 venum_write_pmresr(0);
1352 venum_post_pmresr(vval, fval);
93499918
SB
1353
1354 /* Reset PMxEVNCTCR to sane default */
1355 for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) {
1356 armv7_pmnc_select_counter(idx);
1357 asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
1358 }
1359
b7aafe99
SB
1360}
1361
1362static int krait_event_to_bit(struct perf_event *event, unsigned int region,
1363 unsigned int group)
1364{
1365 int bit;
1366 struct hw_perf_event *hwc = &event->hw;
1367 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
1368
1369 if (hwc->config_base & VENUM_EVENT)
1370 bit = KRAIT_VPMRESR0_GROUP0;
1371 else
1372 bit = krait_get_pmresrn_event(region);
1373 bit -= krait_get_pmresrn_event(0);
1374 bit += group;
1375 /*
1376 * Lower bits are reserved for use by the counters (see
1377 * armv7pmu_get_event_idx() for more info)
1378 */
1379 bit += ARMV7_IDX_COUNTER_LAST(cpu_pmu) + 1;
1380
1381 return bit;
1382}
1383
1384/*
1385 * We check for column exclusion constraints here.
1386 * Two events cant use the same group within a pmresr register.
1387 */
1388static int krait_pmu_get_event_idx(struct pmu_hw_events *cpuc,
1389 struct perf_event *event)
1390{
1391 int idx;
6a78371a 1392 int bit = -1;
b7aafe99 1393 struct hw_perf_event *hwc = &event->hw;
65bab451
SB
1394 unsigned int region = EVENT_REGION(hwc->config_base);
1395 unsigned int code = EVENT_CODE(hwc->config_base);
1396 unsigned int group = EVENT_GROUP(hwc->config_base);
1397 bool venum_event = EVENT_VENUM(hwc->config_base);
1398 bool krait_event = EVENT_CPU(hwc->config_base);
b7aafe99 1399
65bab451 1400 if (venum_event || krait_event) {
b7aafe99
SB
1401 /* Ignore invalid events */
1402 if (group > 3 || region > 2)
1403 return -EINVAL;
65bab451 1404 if (venum_event && (code & 0xe0))
b7aafe99
SB
1405 return -EINVAL;
1406
1407 bit = krait_event_to_bit(event, region, group);
1408 if (test_and_set_bit(bit, cpuc->used_mask))
1409 return -EAGAIN;
1410 }
1411
1412 idx = armv7pmu_get_event_idx(cpuc, event);
6a78371a 1413 if (idx < 0 && bit >= 0)
b7aafe99
SB
1414 clear_bit(bit, cpuc->used_mask);
1415
1416 return idx;
1417}
1418
1419static void krait_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
1420 struct perf_event *event)
1421{
1422 int bit;
1423 struct hw_perf_event *hwc = &event->hw;
65bab451
SB
1424 unsigned int region = EVENT_REGION(hwc->config_base);
1425 unsigned int group = EVENT_GROUP(hwc->config_base);
1426 bool venum_event = EVENT_VENUM(hwc->config_base);
1427 bool krait_event = EVENT_CPU(hwc->config_base);
b7aafe99 1428
65bab451 1429 if (venum_event || krait_event) {
b7aafe99
SB
1430 bit = krait_event_to_bit(event, region, group);
1431 clear_bit(bit, cpuc->used_mask);
1432 }
1433}
1434
2a3391cd
SB
1435static int krait_pmu_init(struct arm_pmu *cpu_pmu)
1436{
1437 armv7pmu_init(cpu_pmu);
3d1ff755 1438 cpu_pmu->name = "armv7_krait";
2a3391cd
SB
1439 /* Some early versions of Krait don't support PC write events */
1440 if (of_property_read_bool(cpu_pmu->plat_device->dev.of_node,
1441 "qcom,no-pc-write"))
1442 cpu_pmu->map_event = krait_map_event_no_branch;
1443 else
1444 cpu_pmu->map_event = krait_map_event;
1445 cpu_pmu->num_events = armv7_read_num_pmnc_events();
1446 cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
b7aafe99
SB
1447 cpu_pmu->reset = krait_pmu_reset;
1448 cpu_pmu->enable = krait_pmu_enable_event;
1449 cpu_pmu->disable = krait_pmu_disable_event;
1450 cpu_pmu->get_event_idx = krait_pmu_get_event_idx;
1451 cpu_pmu->clear_event_idx = krait_pmu_clear_event_idx;
2a3391cd
SB
1452 return 0;
1453}
43eab878 1454#else
513c99ce 1455static inline int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
43eab878 1456{
513c99ce 1457 return -ENODEV;
43eab878
WD
1458}
1459
513c99ce 1460static inline int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
43eab878 1461{
513c99ce 1462 return -ENODEV;
43eab878 1463}
0c205cbe 1464
513c99ce 1465static inline int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
0c205cbe 1466{
513c99ce 1467 return -ENODEV;
0c205cbe 1468}
14abd038 1469
513c99ce 1470static inline int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
14abd038 1471{
513c99ce 1472 return -ENODEV;
14abd038 1473}
d33c88c6 1474
513c99ce 1475static inline int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
d33c88c6 1476{
513c99ce 1477 return -ENODEV;
d33c88c6 1478}
2a3391cd 1479
8e781f65
AT
1480static inline int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
1481{
1482 return -ENODEV;
1483}
1484
03eff46c
WD
1485static inline int armv7_a17_pmu_init(struct arm_pmu *cpu_pmu)
1486{
1487 return -ENODEV;
1488}
1489
2a3391cd
SB
1490static inline int krait_pmu_init(struct arm_pmu *cpu_pmu)
1491{
1492 return -ENODEV;
1493}
43eab878 1494#endif /* CONFIG_CPU_V7 */
This page took 0.30777 seconds and 5 git commands to generate.