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