File Index
Files and directories
Sign in
FILE

hisi_uncore_pmu.h

File preview with syntax highlighting.

linux-6.19.14/drivers/perf/hisilicon/hisi_uncore_pmu.h C
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * HiSilicon SoC Hardware event counters support
  4 *
  5 * Copyright (C) 2017 HiSilicon Limited
  6 * Author: Anurup M <anurup.m@huawei.com>
  7 *         Shaokun Zhang <zhangshaokun@hisilicon.com>
  8 *
  9 * This code is based on the uncore PMUs like arm-cci and arm-ccn.
 10 */
 11#ifndef __HISI_UNCORE_PMU_H__
 12#define __HISI_UNCORE_PMU_H__
 13
 14#include <linux/bitfield.h>
 15#include <linux/cpumask.h>
 16#include <linux/device.h>
 17#include <linux/kernel.h>
 18#include <linux/module.h>
 19#include <linux/perf_event.h>
 20#include <linux/platform_device.h>
 21#include <linux/types.h>
 22
 23#undef pr_fmt
 24#define pr_fmt(fmt)     "hisi_pmu: " fmt
 25
 26#define HISI_PMU_V2		0x30
 27#define HISI_MAX_COUNTERS	0x18
 28#define to_hisi_pmu(p)	(container_of(p, struct hisi_pmu, pmu))
 29
 30#define HISI_PMU_ATTR(_name, _func, _config)				\
 31	(&((struct dev_ext_attribute[]) {				\
 32		{ __ATTR(_name, 0444, _func, NULL), (void *)_config }   \
 33	})[0].attr.attr)
 34
 35#define HISI_PMU_FORMAT_ATTR(_name, _config)		\
 36	HISI_PMU_ATTR(_name, device_show_string, _config)
 37#define HISI_PMU_EVENT_ATTR(_name, _config)		\
 38	HISI_PMU_ATTR(_name, hisi_event_sysfs_show, (unsigned long)_config)
 39
 40#define HISI_PMU_EVENT_ATTR_EXTRACTOR(name, config, hi, lo)        \
 41	static inline u32 hisi_get_##name(struct perf_event *event)            \
 42	{                                                                  \
 43		return FIELD_GET(GENMASK_ULL(hi, lo), event->attr.config);  \
 44	}
 45
 46#define HISI_EVENTID_MASK		GENMASK(7, 0)
 47#define HISI_GET_EVENTID(ev)		((ev)->hw.config_base & HISI_EVENTID_MASK)
 48
 49#define HISI_PMU_EVTYPE_BITS		8
 50#define HISI_PMU_EVTYPE_SHIFT(idx)	((idx) % 4 * HISI_PMU_EVTYPE_BITS)
 51
 52struct hisi_pmu;
 53
 54struct hisi_uncore_ops {
 55	int (*check_filter)(struct perf_event *event);
 56	void (*write_evtype)(struct hisi_pmu *, int, u32);
 57	int (*get_event_idx)(struct perf_event *);
 58	u64 (*read_counter)(struct hisi_pmu *, struct hw_perf_event *);
 59	void (*write_counter)(struct hisi_pmu *, struct hw_perf_event *, u64);
 60	void (*enable_counter)(struct hisi_pmu *, struct hw_perf_event *);
 61	void (*disable_counter)(struct hisi_pmu *, struct hw_perf_event *);
 62	void (*enable_counter_int)(struct hisi_pmu *, struct hw_perf_event *);
 63	void (*disable_counter_int)(struct hisi_pmu *, struct hw_perf_event *);
 64	void (*start_counters)(struct hisi_pmu *);
 65	void (*stop_counters)(struct hisi_pmu *);
 66	u32 (*get_int_status)(struct hisi_pmu *hisi_pmu);
 67	void (*clear_int_status)(struct hisi_pmu *hisi_pmu, int idx);
 68	void (*enable_filter)(struct perf_event *event);
 69	void (*disable_filter)(struct perf_event *event);
 70};
 71
 72/* Describes the HISI PMU chip features information */
 73struct hisi_pmu_dev_info {
 74	const char *name;
 75	const struct attribute_group **attr_groups;
 76	u32 counter_bits;
 77	u32 check_event;
 78	void *private;
 79};
 80
 81struct hisi_pmu_hwevents {
 82	struct perf_event *hw_events[HISI_MAX_COUNTERS];
 83	DECLARE_BITMAP(used_mask, HISI_MAX_COUNTERS);
 84	const struct attribute_group **attr_groups;
 85};
 86
 87/**
 88 * struct hisi_pmu_topology - Describe the topology hierarchy on which the PMU
 89 *                            is located.
 90 * @sccl_id: ID of the SCCL on which the PMU locate is located.
 91 * @sicl_id: ID of the SICL on which the PMU locate is located.
 92 * @scl_id:  ID used by the core which is unaware of the SCCL/SICL.
 93 * @ccl_id: ID of the CCL (CPU cluster) on which the PMU is located.
 94 * @index_id: the ID of the PMU module if there're several PMUs at a
 95 *            particularly location in the topology.
 96 * @sub_id: submodule ID of the PMU. For example we use this for DDRC PMU v2
 97 *          since each DDRC has more than one DMC
 98 *
 99 * The ID will be -1 if the PMU isn't located on a certain topology.
100 */
101struct hisi_pmu_topology {
102	/*
103	 * SCCL (Super CPU CLuster) and SICL (Super I/O Cluster) are parallel
104	 * so a PMU cannot locate on a SCCL and a SICL. If the SCCL/SICL
105	 * distinction is not relevant, use scl_id instead.
106	 */
107	union {
108		int sccl_id;
109		int sicl_id;
110		int scl_id;
111	};
112	int ccl_id;
113	int index_id;
114	int sub_id;
115};
116
117/* Generic pmu struct for different pmu types */
118struct hisi_pmu {
119	struct pmu pmu;
120	const struct hisi_uncore_ops *ops;
121	const struct hisi_pmu_dev_info *dev_info;
122	struct hisi_pmu_hwevents pmu_events;
123	struct hisi_pmu_topology topo;
124	/*
125	 * CPUs associated to the PMU and are preferred to use for counting.
126	 * Could be empty if PMU has no association (e.g. PMU on SICL), in
127	 * which case any online CPU will be used.
128	 */
129	cpumask_t associated_cpus;
130	/* CPU used for counting */
131	int on_cpu;
132	int irq;
133	struct device *dev;
134	struct hlist_node node;
135	void __iomem *base;
136	int num_counters;
137	int counter_bits;
138	/* check event code range */
139	int check_event;
140	u32 identifier;
141};
142
143/* Generic implementation of cpumask/identifier group */
144extern const struct attribute_group hisi_pmu_cpumask_attr_group;
145extern const struct attribute_group hisi_pmu_identifier_group;
146
147int hisi_uncore_pmu_get_event_idx(struct perf_event *event);
148void hisi_uncore_pmu_read(struct perf_event *event);
149int hisi_uncore_pmu_add(struct perf_event *event, int flags);
150void hisi_uncore_pmu_del(struct perf_event *event, int flags);
151void hisi_uncore_pmu_start(struct perf_event *event, int flags);
152void hisi_uncore_pmu_stop(struct perf_event *event, int flags);
153void hisi_uncore_pmu_set_event_period(struct perf_event *event);
154void hisi_uncore_pmu_event_update(struct perf_event *event);
155int hisi_uncore_pmu_event_init(struct perf_event *event);
156void hisi_uncore_pmu_enable(struct pmu *pmu);
157void hisi_uncore_pmu_disable(struct pmu *pmu);
158ssize_t hisi_event_sysfs_show(struct device *dev,
159			      struct device_attribute *attr, char *buf);
160ssize_t hisi_cpumask_sysfs_show(struct device *dev,
161				struct device_attribute *attr, char *buf);
162int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node);
163int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node);
164
165ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
166					     struct device_attribute *attr,
167					     char *page);
168irqreturn_t hisi_uncore_pmu_isr(int irq, void *data);
169int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
170			     struct platform_device *pdev);
171void hisi_uncore_pmu_init_topology(struct hisi_pmu *hisi_pmu, struct device *dev);
172
173void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module);
174#endif /* __HISI_UNCORE_PMU_H__ */
~/ Read-only file preview.