Commit | Line | Data |
---|---|---|
e37dfd65 BW |
1 | /* SPDX-License-Identifier: GPL-2.0 |
2 | * | |
3 | * ARM CoreSight Architecture PMU driver. | |
bfc653aa | 4 | * Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. |
e37dfd65 BW |
5 | * |
6 | */ | |
7 | ||
8 | #ifndef __ARM_CSPMU_H__ | |
9 | #define __ARM_CSPMU_H__ | |
10 | ||
e37dfd65 BW |
11 | #include <linux/bitfield.h> |
12 | #include <linux/cpumask.h> | |
13 | #include <linux/device.h> | |
14 | #include <linux/kernel.h> | |
15 | #include <linux/module.h> | |
16 | #include <linux/perf_event.h> | |
17 | #include <linux/platform_device.h> | |
18 | #include <linux/types.h> | |
19 | ||
20 | #define to_arm_cspmu(p) (container_of(p, struct arm_cspmu, pmu)) | |
21 | ||
22 | #define ARM_CSPMU_EXT_ATTR(_name, _func, _config) \ | |
23 | (&((struct dev_ext_attribute[]){ \ | |
24 | { \ | |
25 | .attr = __ATTR(_name, 0444, _func, NULL), \ | |
26 | .var = (void *)_config \ | |
27 | } \ | |
28 | })[0].attr.attr) | |
29 | ||
30 | #define ARM_CSPMU_FORMAT_ATTR(_name, _config) \ | |
b91b73a4 | 31 | ARM_CSPMU_EXT_ATTR(_name, device_show_string, _config) |
e37dfd65 BW |
32 | |
33 | #define ARM_CSPMU_EVENT_ATTR(_name, _config) \ | |
34 | PMU_EVENT_ATTR_ID(_name, arm_cspmu_sysfs_event_show, _config) | |
35 | ||
36 | ||
37 | /* Default event id mask */ | |
38 | #define ARM_CSPMU_EVENT_MASK GENMASK_ULL(63, 0) | |
39 | ||
40 | /* Default filter value mask */ | |
41 | #define ARM_CSPMU_FILTER_MASK GENMASK_ULL(63, 0) | |
42 | ||
43 | /* Default event format */ | |
44 | #define ARM_CSPMU_FORMAT_EVENT_ATTR \ | |
45 | ARM_CSPMU_FORMAT_ATTR(event, "config:0-32") | |
46 | ||
47 | /* Default filter format */ | |
48 | #define ARM_CSPMU_FORMAT_FILTER_ATTR \ | |
49 | ARM_CSPMU_FORMAT_ATTR(filter, "config1:0-31") | |
50 | ||
51 | /* | |
52 | * This is the default event number for cycle count, if supported, since the | |
53 | * ARM Coresight PMU specification does not define a standard event code | |
54 | * for cycle count. | |
55 | */ | |
56 | #define ARM_CSPMU_EVT_CYCLES_DEFAULT (0x1ULL << 32) | |
57 | ||
58 | /* | |
59 | * The ARM Coresight PMU supports up to 256 event counters. | |
60 | * If the counters are larger-than 32-bits, then the PMU includes at | |
61 | * most 128 counters. | |
62 | */ | |
63 | #define ARM_CSPMU_MAX_HW_CNTRS 256 | |
64 | ||
65 | /* The cycle counter, if implemented, is located at counter[31]. */ | |
66 | #define ARM_CSPMU_CYCLE_CNTR_IDX 31 | |
67 | ||
68 | /* PMIIDR register field */ | |
69 | #define ARM_CSPMU_PMIIDR_IMPLEMENTER GENMASK(11, 0) | |
70 | #define ARM_CSPMU_PMIIDR_PRODUCTID GENMASK(31, 20) | |
71 | ||
bfc653aa BW |
72 | /* JEDEC-assigned JEP106 identification code */ |
73 | #define ARM_CSPMU_IMPL_ID_NVIDIA 0x36B | |
53a810ad | 74 | #define ARM_CSPMU_IMPL_ID_AMPERE 0xA16 |
bfc653aa | 75 | |
e37dfd65 BW |
76 | struct arm_cspmu; |
77 | ||
78 | /* This tracks the events assigned to each counter in the PMU. */ | |
79 | struct arm_cspmu_hw_events { | |
80 | /* The events that are active on the PMU for a given logical index. */ | |
81 | struct perf_event **events; | |
82 | ||
83 | /* | |
84 | * Each bit indicates a logical counter is being used (or not) for an | |
85 | * event. If cycle counter is supported and there is a gap between | |
86 | * regular and cycle counter, the last logical counter is mapped to | |
87 | * cycle counter. Otherwise, logical and physical have 1-to-1 mapping. | |
88 | */ | |
89 | DECLARE_BITMAP(used_ctrs, ARM_CSPMU_MAX_HW_CNTRS); | |
90 | }; | |
91 | ||
92 | /* Contains ops to query vendor/implementer specific attribute. */ | |
93 | struct arm_cspmu_impl_ops { | |
94 | /* Get event attributes */ | |
95 | struct attribute **(*get_event_attrs)(const struct arm_cspmu *cspmu); | |
96 | /* Get format attributes */ | |
97 | struct attribute **(*get_format_attrs)(const struct arm_cspmu *cspmu); | |
98 | /* Get string identifier */ | |
99 | const char *(*get_identifier)(const struct arm_cspmu *cspmu); | |
100 | /* Get PMU name to register to core perf */ | |
101 | const char *(*get_name)(const struct arm_cspmu *cspmu); | |
102 | /* Check if the event corresponds to cycle count event */ | |
103 | bool (*is_cycle_counter_event)(const struct perf_event *event); | |
104 | /* Decode event type/id from configs */ | |
105 | u32 (*event_type)(const struct perf_event *event); | |
106 | /* Decode filter value from configs */ | |
107 | u32 (*event_filter)(const struct perf_event *event); | |
0a7603ab IK |
108 | /* Set event filter */ |
109 | void (*set_ev_filter)(struct arm_cspmu *cspmu, | |
110 | struct hw_perf_event *hwc, u32 filter); | |
647d5c5a IK |
111 | /* Implementation specific event validation */ |
112 | int (*validate_event)(struct arm_cspmu *cspmu, | |
113 | struct perf_event *event); | |
e37dfd65 BW |
114 | /* Hide/show unsupported events */ |
115 | umode_t (*event_attr_is_visible)(struct kobject *kobj, | |
116 | struct attribute *attr, int unused); | |
117 | }; | |
118 | ||
bfc653aa BW |
119 | /* Vendor/implementer registration parameter. */ |
120 | struct arm_cspmu_impl_match { | |
121 | /* Backend module. */ | |
122 | struct module *module; | |
123 | const char *module_name; | |
124 | /* PMIIDR value/mask. */ | |
125 | u32 pmiidr_val; | |
126 | u32 pmiidr_mask; | |
127 | /* Callback to vendor backend to init arm_cspmu_impl::ops. */ | |
128 | int (*impl_init_ops)(struct arm_cspmu *cspmu); | |
129 | }; | |
130 | ||
e37dfd65 BW |
131 | /* Vendor/implementer descriptor. */ |
132 | struct arm_cspmu_impl { | |
133 | u32 pmiidr; | |
bfc653aa BW |
134 | struct module *module; |
135 | struct arm_cspmu_impl_match *match; | |
e37dfd65 BW |
136 | struct arm_cspmu_impl_ops ops; |
137 | void *ctx; | |
138 | }; | |
139 | ||
140 | /* Coresight PMU descriptor. */ | |
141 | struct arm_cspmu { | |
142 | struct pmu pmu; | |
143 | struct device *dev; | |
e37dfd65 BW |
144 | const char *name; |
145 | const char *identifier; | |
146 | void __iomem *base0; | |
147 | void __iomem *base1; | |
e37dfd65 BW |
148 | cpumask_t associated_cpus; |
149 | cpumask_t active_cpu; | |
150 | struct hlist_node cpuhp_node; | |
d2e3bb51 | 151 | int irq; |
e37dfd65 | 152 | |
d2e3bb51 | 153 | bool has_atomic_dword; |
e37dfd65 BW |
154 | u32 pmcfgr; |
155 | u32 num_logical_ctrs; | |
156 | u32 num_set_clr_reg; | |
157 | int cycle_counter_logical_idx; | |
158 | ||
159 | struct arm_cspmu_hw_events hw_events; | |
7e6a3c3f | 160 | const struct attribute_group *attr_groups[5]; |
e37dfd65 BW |
161 | |
162 | struct arm_cspmu_impl impl; | |
163 | }; | |
164 | ||
165 | /* Default function to show event attribute in sysfs. */ | |
166 | ssize_t arm_cspmu_sysfs_event_show(struct device *dev, | |
167 | struct device_attribute *attr, | |
168 | char *buf); | |
169 | ||
bfc653aa BW |
170 | /* Register vendor backend. */ |
171 | int arm_cspmu_impl_register(const struct arm_cspmu_impl_match *impl_match); | |
172 | ||
173 | /* Unregister vendor backend. */ | |
174 | void arm_cspmu_impl_unregister(const struct arm_cspmu_impl_match *impl_match); | |
175 | ||
e37dfd65 | 176 | #endif /* __ARM_CSPMU_H__ */ |