1 /* SPDX-License-Identifier: GPL-2.0
3 * ARM CoreSight Architecture PMU driver.
4 * Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
8 #ifndef __ARM_CSPMU_H__
9 #define __ARM_CSPMU_H__
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>
20 #define to_arm_cspmu(p) (container_of(p, struct arm_cspmu, pmu))
22 #define ARM_CSPMU_EXT_ATTR(_name, _func, _config) \
23 (&((struct dev_ext_attribute[]){ \
25 .attr = __ATTR(_name, 0444, _func, NULL), \
26 .var = (void *)_config \
30 #define ARM_CSPMU_FORMAT_ATTR(_name, _config) \
31 ARM_CSPMU_EXT_ATTR(_name, device_show_string, _config)
33 #define ARM_CSPMU_EVENT_ATTR(_name, _config) \
34 PMU_EVENT_ATTR_ID(_name, arm_cspmu_sysfs_event_show, _config)
37 /* Default event id mask */
38 #define ARM_CSPMU_EVENT_MASK GENMASK_ULL(63, 0)
40 /* Default filter value mask */
41 #define ARM_CSPMU_FILTER_MASK GENMASK_ULL(63, 0)
43 /* Default event format */
44 #define ARM_CSPMU_FORMAT_EVENT_ATTR \
45 ARM_CSPMU_FORMAT_ATTR(event, "config:0-32")
47 /* Default filter format */
48 #define ARM_CSPMU_FORMAT_FILTER_ATTR \
49 ARM_CSPMU_FORMAT_ATTR(filter, "config1:0-31")
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
56 #define ARM_CSPMU_EVT_CYCLES_DEFAULT (0x1ULL << 32)
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
63 #define ARM_CSPMU_MAX_HW_CNTRS 256
65 /* The cycle counter, if implemented, is located at counter[31]. */
66 #define ARM_CSPMU_CYCLE_CNTR_IDX 31
68 /* PMIIDR register field */
69 #define ARM_CSPMU_PMIIDR_IMPLEMENTER GENMASK(11, 0)
70 #define ARM_CSPMU_PMIIDR_PRODUCTID GENMASK(31, 20)
72 /* JEDEC-assigned JEP106 identification code */
73 #define ARM_CSPMU_IMPL_ID_NVIDIA 0x36B
74 #define ARM_CSPMU_IMPL_ID_AMPERE 0xA16
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
;
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.
89 DECLARE_BITMAP(used_ctrs
, ARM_CSPMU_MAX_HW_CNTRS
);
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
);
108 /* Set event filter */
109 void (*set_ev_filter
)(struct arm_cspmu
*cspmu
,
110 struct hw_perf_event
*hwc
, u32 filter
);
111 /* Implementation specific event validation */
112 int (*validate_event
)(struct arm_cspmu
*cspmu
,
113 struct perf_event
*event
);
114 /* Hide/show unsupported events */
115 umode_t (*event_attr_is_visible
)(struct kobject
*kobj
,
116 struct attribute
*attr
, int unused
);
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. */
127 /* Callback to vendor backend to init arm_cspmu_impl::ops. */
128 int (*impl_init_ops
)(struct arm_cspmu
*cspmu
);
131 /* Vendor/implementer descriptor. */
132 struct arm_cspmu_impl
{
134 struct module
*module
;
135 struct arm_cspmu_impl_match
*match
;
136 struct arm_cspmu_impl_ops ops
;
140 /* Coresight PMU descriptor. */
145 const char *identifier
;
148 cpumask_t associated_cpus
;
149 cpumask_t active_cpu
;
150 struct hlist_node cpuhp_node
;
153 bool has_atomic_dword
;
155 u32 num_logical_ctrs
;
157 int cycle_counter_logical_idx
;
159 struct arm_cspmu_hw_events hw_events
;
160 const struct attribute_group
*attr_groups
[5];
162 struct arm_cspmu_impl impl
;
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
,
170 /* Register vendor backend. */
171 int arm_cspmu_impl_register(const struct arm_cspmu_impl_match
*impl_match
);
173 /* Unregister vendor backend. */
174 void arm_cspmu_impl_unregister(const struct arm_cspmu_impl_match
*impl_match
);
176 #endif /* __ARM_CSPMU_H__ */