1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (C) 2008-2018 Andes Technology Corporation */
7 #include <linux/interrupt.h>
8 #include <linux/perf_event.h>
9 #include <asm/unistd.h>
10 #include <asm/bitfield.h>
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
17 /* Enough for both software and hardware defined events */
18 #define SOFTWARE_EVENT_MASK 0xFF
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)
24 enum { PFMC0, PFMC1, PFMC2, MAX_COUNTERS };
26 u32 PFM_CTL_OVF[3] = { PFM_CTL_mskOVF0, PFM_CTL_mskOVF1,
28 u32 PFM_CTL_EN[3] = { PFM_CTL_mskEN0, PFM_CTL_mskEN1,
30 u32 PFM_CTL_OFFSEL[3] = { PFM_CTL_offSEL0, PFM_CTL_offSEL1,
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 };
37 * Perf Events' indices
39 #define NDS32_IDX_CYCLE_COUNTER 0
40 #define NDS32_IDX_COUNTER0 1
41 #define NDS32_IDX_COUNTER1 2
43 /* The events for a given PMU register set. */
44 struct pmu_hw_events {
46 * The events that are active on the PMU for the given index.
48 struct perf_event *events[MAX_COUNTERS];
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.
54 unsigned long used_mask[BITS_TO_LONGS(MAX_COUNTERS)];
57 * Hardware lock to serialize accesses to PMU registers. Needed for the
58 * read/modify/write sequences.
60 raw_spinlock_t pmu_lock;
65 cpumask_t active_irqs;
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);
83 atomic_t active_events;
85 struct platform_device *plat_device;
86 struct pmu_hw_events *(*get_hw_events)(void);
89 #define to_nds32_pmu(p) (container_of(p, struct nds32_pmu, pmu))
91 int nds32_pmu_register(struct nds32_pmu *nds32_pmu, int type);
93 u64 nds32_pmu_event_update(struct perf_event *event);
95 int nds32_pmu_event_set_period(struct perf_event *event);
98 * Common NDS32 SPAv3 event types
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.
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.
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 */
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 */
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 */
187 /* Get converted event counter index */
188 static inline int get_converted_event_idx(unsigned long event)
192 if ((event) > SPAV3_0_SEL_BASE && event < SPAV3_0_SEL_LAST) {
194 } else if ((event) > SPAV3_1_SEL_BASE && event < SPAV3_1_SEL_LAST) {
196 } else if ((event) > SPAV3_2_SEL_BASE && event < SPAV3_2_SEL_LAST) {
199 pr_err("GET_CONVERTED_EVENT_IDX PFM counter range error\n");
206 /* Get converted hardware event number */
207 static inline u32 get_converted_evet_hw_num(u32 event)
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;
216 pr_err("GET_CONVERTED_EVENT_HW_NUM PFM counter range error\n");
222 * NDS32 HW events mapping
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.
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
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] = {
247 SPAV3_1_SEL_LOAD_DATA_CACHE_ACCESS,
249 SPAV3_2_SEL_LOAD_DATA_CACHE_MISS,
253 SPAV3_1_SEL_STORE_DATA_CACHE_ACCESS,
255 SPAV3_2_SEL_STORE_DATA_CACHE_MISS,
259 CACHE_OP_UNSUPPORTED,
261 CACHE_OP_UNSUPPORTED,
267 SPAV3_1_SEL_CODE_CACHE_ACCESS,
269 SPAV3_2_SEL_CODE_CACHE_MISS,
273 SPAV3_1_SEL_CODE_CACHE_ACCESS,
275 SPAV3_2_SEL_CODE_CACHE_MISS,
279 CACHE_OP_UNSUPPORTED,
280 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
286 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
287 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
290 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
291 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
295 CACHE_OP_UNSUPPORTED,
296 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
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.
307 SPAV3_1_SEL_UDTLB_ACCESS,
309 SPAV3_2_SEL_UDTLB_MISS,
312 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
313 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
317 CACHE_OP_UNSUPPORTED,
319 CACHE_OP_UNSUPPORTED,
325 SPAV3_1_SEL_UITLB_ACCESS,
327 SPAV3_2_SEL_UITLB_MISS,
331 CACHE_OP_UNSUPPORTED,
333 CACHE_OP_UNSUPPORTED,
337 CACHE_OP_UNSUPPORTED,
339 CACHE_OP_UNSUPPORTED,
342 [C(BPU)] = { /* What is BPU? */
345 CACHE_OP_UNSUPPORTED,
347 CACHE_OP_UNSUPPORTED,
351 CACHE_OP_UNSUPPORTED,
353 CACHE_OP_UNSUPPORTED,
357 CACHE_OP_UNSUPPORTED,
359 CACHE_OP_UNSUPPORTED,
362 [C(NODE)] = { /* What is NODE? */
364 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
365 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
368 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
369 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
373 CACHE_OP_UNSUPPORTED,
375 CACHE_OP_UNSUPPORTED,
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);
386 #endif /* __ASM_PMU_H */