1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (C) 2008-2018 Andes Technology Corporation */
3
4 #ifndef __ASM_PMU_H
5 #define __ASM_PMU_H
6
7 #include <linux/interrupt.h>
8 #include <linux/perf_event.h>
9 #include <asm/unistd.h>
10 #include <asm/bitfield.h>
11
12 /* Has special meaning for perf core implementation */
13 #define HW_OP_UNSUPPORTED 0x0
14 #define C(_x) PERF_COUNT_HW_CACHE_##_x
15 #define CACHE_OP_UNSUPPORTED 0x0
16
17 /* Enough for both software and hardware defined events */
18 #define SOFTWARE_EVENT_MASK 0xFF
19
20 #define PFM_OFFSET_MAGIC_0 2 /* DO NOT START FROM 0 */
21 #define PFM_OFFSET_MAGIC_1 (PFM_OFFSET_MAGIC_0 + 36)
22 #define PFM_OFFSET_MAGIC_2 (PFM_OFFSET_MAGIC_1 + 36)
23
24 enum { PFMC0, PFMC1, PFMC2, MAX_COUNTERS };
25
26 u32 PFM_CTL_OVF[3] = { PFM_CTL_mskOVF0, PFM_CTL_mskOVF1,
27 PFM_CTL_mskOVF2 };
28 u32 PFM_CTL_EN[3] = { PFM_CTL_mskEN0, PFM_CTL_mskEN1,
29 PFM_CTL_mskEN2 };
30 u32 PFM_CTL_OFFSEL[3] = { PFM_CTL_offSEL0, PFM_CTL_offSEL1,
31 PFM_CTL_offSEL2 };
32 u32 PFM_CTL_IE[3] = { PFM_CTL_mskIE0, PFM_CTL_mskIE1, PFM_CTL_mskIE2 };
33 u32 PFM_CTL_KS[3] = { PFM_CTL_mskKS0, PFM_CTL_mskKS1, PFM_CTL_mskKS2 };
34 u32 PFM_CTL_KU[3] = { PFM_CTL_mskKU0, PFM_CTL_mskKU1, PFM_CTL_mskKU2 };
35 u32 PFM_CTL_SEL[3] = { PFM_CTL_mskSEL0, PFM_CTL_mskSEL1, PFM_CTL_mskSEL2 };
36 /*
37 * Perf Events' indices
38 */
39 #define NDS32_IDX_CYCLE_COUNTER 0
40 #define NDS32_IDX_COUNTER0 1
41 #define NDS32_IDX_COUNTER1 2
42
43 /* The events for a given PMU register set. */
44 struct pmu_hw_events {
45 /*
46 * The events that are active on the PMU for the given index.
47 */
48 struct perf_event *events[MAX_COUNTERS];
49
50 /*
51 * A 1 bit for an index indicates that the counter is being used for
52 * an event. A 0 means that the counter can be used.
53 */
54 unsigned long used_mask[BITS_TO_LONGS(MAX_COUNTERS)];
55
56 /*
57 * Hardware lock to serialize accesses to PMU registers. Needed for the
58 * read/modify/write sequences.
59 */
60 raw_spinlock_t pmu_lock;
61 };
62
63 struct nds32_pmu {
64 struct pmu pmu;
65 cpumask_t active_irqs;
66 char *name;
67 irqreturn_t (*handle_irq)(int irq_num, void *dev);
68 void (*enable)(struct perf_event *event);
69 void (*disable)(struct perf_event *event);
70 int (*get_event_idx)(struct pmu_hw_events *hw_events,
71 struct perf_event *event);
72 int (*set_event_filter)(struct hw_perf_event *evt,
73 struct perf_event_attr *attr);
74 u32 (*read_counter)(struct perf_event *event);
75 void (*write_counter)(struct perf_event *event, u32 val);
76 void (*start)(struct nds32_pmu *nds32_pmu);
77 void (*stop)(struct nds32_pmu *nds32_pmu);
78 void (*reset)(void *data);
79 int (*request_irq)(struct nds32_pmu *nds32_pmu, irq_handler_t handler);
80 void (*free_irq)(struct nds32_pmu *nds32_pmu);
81 int (*map_event)(struct perf_event *event);
82 int num_events;
83 atomic_t active_events;
84 u64 max_period;
85 struct platform_device *plat_device;
86 struct pmu_hw_events *(*get_hw_events)(void);
87 };
88
89 #define to_nds32_pmu(p) (container_of(p, struct nds32_pmu, pmu))
90
91 int nds32_pmu_register(struct nds32_pmu *nds32_pmu, int type);
92
93 u64 nds32_pmu_event_update(struct perf_event *event);
94
95 int nds32_pmu_event_set_period(struct perf_event *event);
96
97 /*
98 * Common NDS32 SPAv3 event types
99 *
100 * Note: An implementation may not be able to count all of these events
101 * but the encodings are considered to be `reserved' in the case that
102 * they are not available.
103 *
104 * SEL_TOTAL_CYCLES will add an offset is due to ZERO is defined as
105 * NOT_SUPPORTED EVENT mapping in generic perf code.
106 * You will need to deal it in the event writing implementation.
107 */
108 enum spav3_counter_0_perf_types {
109 SPAV3_0_SEL_BASE = -1 + PFM_OFFSET_MAGIC_0, /* counting symbol */
110 SPAV3_0_SEL_TOTAL_CYCLES = 0 + PFM_OFFSET_MAGIC_0,
111 SPAV3_0_SEL_COMPLETED_INSTRUCTION = 1 + PFM_OFFSET_MAGIC_0,
112 SPAV3_0_SEL_LAST /* counting symbol */
113 };
114
115 enum spav3_counter_1_perf_types {
116 SPAV3_1_SEL_BASE = -1 + PFM_OFFSET_MAGIC_1, /* counting symbol */
117 SPAV3_1_SEL_TOTAL_CYCLES = 0 + PFM_OFFSET_MAGIC_1,
118 SPAV3_1_SEL_COMPLETED_INSTRUCTION = 1 + PFM_OFFSET_MAGIC_1,
119 SPAV3_1_SEL_CONDITIONAL_BRANCH = 2 + PFM_OFFSET_MAGIC_1,
120 SPAV3_1_SEL_TAKEN_CONDITIONAL_BRANCH = 3 + PFM_OFFSET_MAGIC_1,
121 SPAV3_1_SEL_PREFETCH_INSTRUCTION = 4 + PFM_OFFSET_MAGIC_1,
122 SPAV3_1_SEL_RET_INST = 5 + PFM_OFFSET_MAGIC_1,
123 SPAV3_1_SEL_JR_INST = 6 + PFM_OFFSET_MAGIC_1,
124 SPAV3_1_SEL_JAL_JRAL_INST = 7 + PFM_OFFSET_MAGIC_1,
125 SPAV3_1_SEL_NOP_INST = 8 + PFM_OFFSET_MAGIC_1,
126 SPAV3_1_SEL_SCW_INST = 9 + PFM_OFFSET_MAGIC_1,
127 SPAV3_1_SEL_ISB_DSB_INST = 10 + PFM_OFFSET_MAGIC_1,
128 SPAV3_1_SEL_CCTL_INST = 11 + PFM_OFFSET_MAGIC_1,
129 SPAV3_1_SEL_TAKEN_INTERRUPTS = 12 + PFM_OFFSET_MAGIC_1,
130 SPAV3_1_SEL_LOADS_COMPLETED = 13 + PFM_OFFSET_MAGIC_1,
131 SPAV3_1_SEL_UITLB_ACCESS = 14 + PFM_OFFSET_MAGIC_1,
132 SPAV3_1_SEL_UDTLB_ACCESS = 15 + PFM_OFFSET_MAGIC_1,
133 SPAV3_1_SEL_MTLB_ACCESS = 16 + PFM_OFFSET_MAGIC_1,
134 SPAV3_1_SEL_CODE_CACHE_ACCESS = 17 + PFM_OFFSET_MAGIC_1,
135 SPAV3_1_SEL_DATA_DEPENDENCY_STALL_CYCLES = 18 + PFM_OFFSET_MAGIC_1,
136 SPAV3_1_SEL_DATA_CACHE_MISS_STALL_CYCLES = 19 + PFM_OFFSET_MAGIC_1,
137 SPAV3_1_SEL_DATA_CACHE_ACCESS = 20 + PFM_OFFSET_MAGIC_1,
138 SPAV3_1_SEL_DATA_CACHE_MISS = 21 + PFM_OFFSET_MAGIC_1,
139 SPAV3_1_SEL_LOAD_DATA_CACHE_ACCESS = 22 + PFM_OFFSET_MAGIC_1,
140 SPAV3_1_SEL_STORE_DATA_CACHE_ACCESS = 23 + PFM_OFFSET_MAGIC_1,
141 SPAV3_1_SEL_ILM_ACCESS = 24 + PFM_OFFSET_MAGIC_1,
142 SPAV3_1_SEL_LSU_BIU_CYCLES = 25 + PFM_OFFSET_MAGIC_1,
143 SPAV3_1_SEL_HPTWK_BIU_CYCLES = 26 + PFM_OFFSET_MAGIC_1,
144 SPAV3_1_SEL_DMA_BIU_CYCLES = 27 + PFM_OFFSET_MAGIC_1,
145 SPAV3_1_SEL_CODE_CACHE_FILL_BIU_CYCLES = 28 + PFM_OFFSET_MAGIC_1,
146 SPAV3_1_SEL_LEGAL_UNALIGN_DCACHE_ACCESS = 29 + PFM_OFFSET_MAGIC_1,
147 SPAV3_1_SEL_PUSH25 = 30 + PFM_OFFSET_MAGIC_1,
148 SPAV3_1_SEL_SYSCALLS_INST = 31 + PFM_OFFSET_MAGIC_1,
149 SPAV3_1_SEL_LAST /* counting symbol */
150 };
151
152 enum spav3_counter_2_perf_types {
153 SPAV3_2_SEL_BASE = -1 + PFM_OFFSET_MAGIC_2, /* counting symbol */
154 SPAV3_2_SEL_TOTAL_CYCLES = 0 + PFM_OFFSET_MAGIC_2,
155 SPAV3_2_SEL_COMPLETED_INSTRUCTION = 1 + PFM_OFFSET_MAGIC_2,
156 SPAV3_2_SEL_CONDITIONAL_BRANCH_MISPREDICT = 2 + PFM_OFFSET_MAGIC_2,
157 SPAV3_2_SEL_TAKEN_CONDITIONAL_BRANCH_MISPREDICT =
158 3 + PFM_OFFSET_MAGIC_2,
159 SPAV3_2_SEL_PREFETCH_INSTRUCTION_CACHE_HIT = 4 + PFM_OFFSET_MAGIC_2,
160 SPAV3_1_SEL_RET_MISPREDICT = 5 + PFM_OFFSET_MAGIC_2,
161 SPAV3_1_SEL_IMMEDIATE_J_INST = 6 + PFM_OFFSET_MAGIC_2,
162 SPAV3_1_SEL_MULTIPLY_INST = 7 + PFM_OFFSET_MAGIC_2,
163 SPAV3_1_SEL_16_BIT_INST = 8 + PFM_OFFSET_MAGIC_2,
164 SPAV3_1_SEL_FAILED_SCW_INST = 9 + PFM_OFFSET_MAGIC_2,
165 SPAV3_1_SEL_LD_AFTER_ST_CONFLICT_REPLAYS = 10 + PFM_OFFSET_MAGIC_2,
166 SPAV3_1_SEL_TAKEN_EXCEPTIONS = 12 + PFM_OFFSET_MAGIC_2,
167 SPAV3_1_SEL_STORES_COMPLETED = 13 + PFM_OFFSET_MAGIC_2,
168 SPAV3_2_SEL_UITLB_MISS = 14 + PFM_OFFSET_MAGIC_2,
169 SPAV3_2_SEL_UDTLB_MISS = 15 + PFM_OFFSET_MAGIC_2,
170 SPAV3_2_SEL_MTLB_MISS = 16 + PFM_OFFSET_MAGIC_2,
171 SPAV3_2_SEL_CODE_CACHE_MISS = 17 + PFM_OFFSET_MAGIC_2,
172 SPAV3_1_SEL_EMPTY_INST_QUEUE_STALL_CYCLES = 18 + PFM_OFFSET_MAGIC_2,
173 SPAV3_1_SEL_DATA_WRITE_BACK = 19 + PFM_OFFSET_MAGIC_2,
174 SPAV3_2_SEL_DATA_CACHE_MISS = 21 + PFM_OFFSET_MAGIC_2,
175 SPAV3_2_SEL_LOAD_DATA_CACHE_MISS = 22 + PFM_OFFSET_MAGIC_2,
176 SPAV3_2_SEL_STORE_DATA_CACHE_MISS = 23 + PFM_OFFSET_MAGIC_2,
177 SPAV3_1_SEL_DLM_ACCESS = 24 + PFM_OFFSET_MAGIC_2,
178 SPAV3_1_SEL_LSU_BIU_REQUEST = 25 + PFM_OFFSET_MAGIC_2,
179 SPAV3_1_SEL_HPTWK_BIU_REQUEST = 26 + PFM_OFFSET_MAGIC_2,
180 SPAV3_1_SEL_DMA_BIU_REQUEST = 27 + PFM_OFFSET_MAGIC_2,
181 SPAV3_1_SEL_CODE_CACHE_FILL_BIU_REQUEST = 28 + PFM_OFFSET_MAGIC_2,
182 SPAV3_1_SEL_EXTERNAL_EVENTS = 29 + PFM_OFFSET_MAGIC_2,
183 SPAV3_1_SEL_POP25 = 30 + PFM_OFFSET_MAGIC_2,
184 SPAV3_2_SEL_LAST /* counting symbol */
185 };
186
187 /* Get converted event counter index */
get_converted_event_idx(unsigned long event)188 static inline int get_converted_event_idx(unsigned long event)
189 {
190 int idx;
191
192 if ((event) > SPAV3_0_SEL_BASE && event < SPAV3_0_SEL_LAST) {
193 idx = 0;
194 } else if ((event) > SPAV3_1_SEL_BASE && event < SPAV3_1_SEL_LAST) {
195 idx = 1;
196 } else if ((event) > SPAV3_2_SEL_BASE && event < SPAV3_2_SEL_LAST) {
197 idx = 2;
198 } else {
199 pr_err("GET_CONVERTED_EVENT_IDX PFM counter range error\n");
200 return -EPERM;
201 }
202
203 return idx;
204 }
205
206 /* Get converted hardware event number */
get_converted_evet_hw_num(u32 event)207 static inline u32 get_converted_evet_hw_num(u32 event)
208 {
209 if (event > SPAV3_0_SEL_BASE && event < SPAV3_0_SEL_LAST)
210 event -= PFM_OFFSET_MAGIC_0;
211 else if (event > SPAV3_1_SEL_BASE && event < SPAV3_1_SEL_LAST)
212 event -= PFM_OFFSET_MAGIC_1;
213 else if (event > SPAV3_2_SEL_BASE && event < SPAV3_2_SEL_LAST)
214 event -= PFM_OFFSET_MAGIC_2;
215 else if (event != 0)
216 pr_err("GET_CONVERTED_EVENT_HW_NUM PFM counter range error\n");
217
218 return event;
219 }
220
221 /*
222 * NDS32 HW events mapping
223 *
224 * The hardware events that we support. We do support cache operations but
225 * we have harvard caches and no way to combine instruction and data
226 * accesses/misses in hardware.
227 */
228 static const unsigned int nds32_pfm_perf_map[PERF_COUNT_HW_MAX] = {
229 [PERF_COUNT_HW_CPU_CYCLES] = SPAV3_0_SEL_TOTAL_CYCLES,
230 [PERF_COUNT_HW_INSTRUCTIONS] = SPAV3_1_SEL_COMPLETED_INSTRUCTION,
231 [PERF_COUNT_HW_CACHE_REFERENCES] = SPAV3_1_SEL_DATA_CACHE_ACCESS,
232 [PERF_COUNT_HW_CACHE_MISSES] = SPAV3_2_SEL_DATA_CACHE_MISS,
233 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = HW_OP_UNSUPPORTED,
234 [PERF_COUNT_HW_BRANCH_MISSES] = HW_OP_UNSUPPORTED,
235 [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
236 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
237 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
238 [PERF_COUNT_HW_REF_CPU_CYCLES] = HW_OP_UNSUPPORTED
239 };
240
241 static const unsigned int nds32_pfm_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
242 [PERF_COUNT_HW_CACHE_OP_MAX]
243 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
244 [C(L1D)] = {
245 [C(OP_READ)] = {
246 [C(RESULT_ACCESS)] =
247 SPAV3_1_SEL_LOAD_DATA_CACHE_ACCESS,
248 [C(RESULT_MISS)] =
249 SPAV3_2_SEL_LOAD_DATA_CACHE_MISS,
250 },
251 [C(OP_WRITE)] = {
252 [C(RESULT_ACCESS)] =
253 SPAV3_1_SEL_STORE_DATA_CACHE_ACCESS,
254 [C(RESULT_MISS)] =
255 SPAV3_2_SEL_STORE_DATA_CACHE_MISS,
256 },
257 [C(OP_PREFETCH)] = {
258 [C(RESULT_ACCESS)] =
259 CACHE_OP_UNSUPPORTED,
260 [C(RESULT_MISS)] =
261 CACHE_OP_UNSUPPORTED,
262 },
263 },
264 [C(L1I)] = {
265 [C(OP_READ)] = {
266 [C(RESULT_ACCESS)] =
267 SPAV3_1_SEL_CODE_CACHE_ACCESS,
268 [C(RESULT_MISS)] =
269 SPAV3_2_SEL_CODE_CACHE_MISS,
270 },
271 [C(OP_WRITE)] = {
272 [C(RESULT_ACCESS)] =
273 SPAV3_1_SEL_CODE_CACHE_ACCESS,
274 [C(RESULT_MISS)] =
275 SPAV3_2_SEL_CODE_CACHE_MISS,
276 },
277 [C(OP_PREFETCH)] = {
278 [C(RESULT_ACCESS)] =
279 CACHE_OP_UNSUPPORTED,
280 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
281 },
282 },
283 /* TODO: L2CC */
284 [C(LL)] = {
285 [C(OP_READ)] = {
286 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
287 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
288 },
289 [C(OP_WRITE)] = {
290 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
291 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
292 },
293 [C(OP_PREFETCH)] = {
294 [C(RESULT_ACCESS)] =
295 CACHE_OP_UNSUPPORTED,
296 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
297 },
298 },
299 /* NDS32 PMU does not support TLB read/write hit/miss,
300 * However, it can count access/miss, which mixed with read and write.
301 * Therefore, only READ counter will use it.
302 * We do as possible as we can.
303 */
304 [C(DTLB)] = {
305 [C(OP_READ)] = {
306 [C(RESULT_ACCESS)] =
307 SPAV3_1_SEL_UDTLB_ACCESS,
308 [C(RESULT_MISS)] =
309 SPAV3_2_SEL_UDTLB_MISS,
310 },
311 [C(OP_WRITE)] = {
312 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
313 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
314 },
315 [C(OP_PREFETCH)] = {
316 [C(RESULT_ACCESS)] =
317 CACHE_OP_UNSUPPORTED,
318 [C(RESULT_MISS)] =
319 CACHE_OP_UNSUPPORTED,
320 },
321 },
322 [C(ITLB)] = {
323 [C(OP_READ)] = {
324 [C(RESULT_ACCESS)] =
325 SPAV3_1_SEL_UITLB_ACCESS,
326 [C(RESULT_MISS)] =
327 SPAV3_2_SEL_UITLB_MISS,
328 },
329 [C(OP_WRITE)] = {
330 [C(RESULT_ACCESS)] =
331 CACHE_OP_UNSUPPORTED,
332 [C(RESULT_MISS)] =
333 CACHE_OP_UNSUPPORTED,
334 },
335 [C(OP_PREFETCH)] = {
336 [C(RESULT_ACCESS)] =
337 CACHE_OP_UNSUPPORTED,
338 [C(RESULT_MISS)] =
339 CACHE_OP_UNSUPPORTED,
340 },
341 },
342 [C(BPU)] = { /* What is BPU? */
343 [C(OP_READ)] = {
344 [C(RESULT_ACCESS)] =
345 CACHE_OP_UNSUPPORTED,
346 [C(RESULT_MISS)] =
347 CACHE_OP_UNSUPPORTED,
348 },
349 [C(OP_WRITE)] = {
350 [C(RESULT_ACCESS)] =
351 CACHE_OP_UNSUPPORTED,
352 [C(RESULT_MISS)] =
353 CACHE_OP_UNSUPPORTED,
354 },
355 [C(OP_PREFETCH)] = {
356 [C(RESULT_ACCESS)] =
357 CACHE_OP_UNSUPPORTED,
358 [C(RESULT_MISS)] =
359 CACHE_OP_UNSUPPORTED,
360 },
361 },
362 [C(NODE)] = { /* What is NODE? */
363 [C(OP_READ)] = {
364 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
365 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
366 },
367 [C(OP_WRITE)] = {
368 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
369 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
370 },
371 [C(OP_PREFETCH)] = {
372 [C(RESULT_ACCESS)] =
373 CACHE_OP_UNSUPPORTED,
374 [C(RESULT_MISS)] =
375 CACHE_OP_UNSUPPORTED,
376 },
377 },
378 };
379
380 int nds32_pmu_map_event(struct perf_event *event,
381 const unsigned int (*event_map)[PERF_COUNT_HW_MAX],
382 const unsigned int (*cache_map)[PERF_COUNT_HW_CACHE_MAX]
383 [PERF_COUNT_HW_CACHE_OP_MAX]
384 [PERF_COUNT_HW_CACHE_RESULT_MAX], u32 raw_event_mask);
385
386 #endif /* __ASM_PMU_H */
387