brintos

brintos / linux-shallow public Read only

0
0
Text · 5.2 KiB · 2621f31 Raw
177 lines · c
1/* SPDX-License-Identifier: GPL-2.02 *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, device_show_string, _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 the53 * ARM Coresight PMU specification does not define a standard event code54 * 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 at61 * most 128 counters.62 */63#define ARM_CSPMU_MAX_HW_CNTRS		25664 65/* The cycle counter, if implemented, is located at counter[31]. */66#define ARM_CSPMU_CYCLE_CNTR_IDX	3167 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	0x36B74#define ARM_CSPMU_IMPL_ID_AMPERE	0xA1675 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 an85	 * event. If cycle counter is supported and there is a gap between86	 * regular and cycle counter, the last logical counter is mapped to87	 * 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/* Register vendor backend. */171int arm_cspmu_impl_register(const struct arm_cspmu_impl_match *impl_match);172 173/* Unregister vendor backend. */174void arm_cspmu_impl_unregister(const struct arm_cspmu_impl_match *impl_match);175 176#endif /* __ARM_CSPMU_H__ */177