1/* SPDX-License-Identifier: GPL-2.0 2 * 3 * ARM CoreSight Architecture PMU driver. 4 * Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. 5 * 6 */ 7 8#ifndef __ARM_CSPMU_H__ 9#define __ARM_CSPMU_H__ 10 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) \ 31 ARM_CSPMU_EXT_ATTR(_name, arm_cspmu_sysfs_format_show, (char *)_config) 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 72/* JEDEC-assigned JEP106 identification code */ 73#define ARM_CSPMU_IMPL_ID_NVIDIA 0x36B 74#define ARM_CSPMU_IMPL_ID_AMPERE 0xA16 75 76struct arm_cspmu; 77 78/* This tracks the events assigned to each counter in the PMU. */ 79struct 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. */ 93struct 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); 117}; 118 119/* Vendor/implementer registration parameter. */ 120struct 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 131/* Vendor/implementer descriptor. */ 132struct arm_cspmu_impl { 133 u32 pmiidr; 134 struct module *module; 135 struct arm_cspmu_impl_match *match; 136 struct arm_cspmu_impl_ops ops; 137 void *ctx; 138}; 139 140/* Coresight PMU descriptor. */ 141struct arm_cspmu { 142 struct pmu pmu; 143 struct device *dev; 144 const char *name; 145 const char *identifier; 146 void __iomem *base0; 147 void __iomem *base1; 148 cpumask_t associated_cpus; 149 cpumask_t active_cpu; 150 struct hlist_node cpuhp_node; 151 int irq; 152 153 bool has_atomic_dword; 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; 160 const struct attribute_group *attr_groups[5]; 161 162 struct arm_cspmu_impl impl; 163}; 164 165/* Default function to show event attribute in sysfs. */ 166ssize_t arm_cspmu_sysfs_event_show(struct device *dev, 167 struct device_attribute *attr, 168 char *buf); 169 170/* Default function to show format attribute in sysfs. */ 171ssize_t arm_cspmu_sysfs_format_show(struct device *dev, 172 struct device_attribute *attr, 173 char *buf); 174 175/* Register vendor backend. */ 176int arm_cspmu_impl_register(const struct arm_cspmu_impl_match *impl_match); 177 178/* Unregister vendor backend. */ 179void arm_cspmu_impl_unregister(const struct arm_cspmu_impl_match *impl_match); 180 181#endif /* __ARM_CSPMU_H__ */ 182