xref: /linux/drivers/perf/arm_cspmu/nvidia_cspmu.c (revision c43267e6794a36013fd495a4d81bf7f748fe4615)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2022-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4  *
5  */
6 
7 /* Support for NVIDIA specific attributes. */
8 
9 #include <linux/io.h>
10 #include <linux/module.h>
11 #include <linux/property.h>
12 #include <linux/topology.h>
13 
14 #include "arm_cspmu.h"
15 
16 #define NV_PCIE_PORT_COUNT           10ULL
17 #define NV_PCIE_FILTER_ID_MASK       GENMASK_ULL(NV_PCIE_PORT_COUNT - 1, 0)
18 
19 #define NV_NVL_C2C_PORT_COUNT        2ULL
20 #define NV_NVL_C2C_FILTER_ID_MASK    GENMASK_ULL(NV_NVL_C2C_PORT_COUNT - 1, 0)
21 
22 #define NV_CNVL_PORT_COUNT           4ULL
23 #define NV_CNVL_FILTER_ID_MASK       GENMASK_ULL(NV_CNVL_PORT_COUNT - 1, 0)
24 
25 #define NV_UCF_SRC_COUNT             3ULL
26 #define NV_UCF_DST_COUNT             4ULL
27 #define NV_UCF_FILTER_ID_MASK        GENMASK_ULL(11, 0)
28 #define NV_UCF_FILTER_SRC            GENMASK_ULL(2, 0)
29 #define NV_UCF_FILTER_DST            GENMASK_ULL(11, 8)
30 #define NV_UCF_FILTER_DEFAULT        (NV_UCF_FILTER_SRC | NV_UCF_FILTER_DST)
31 
32 #define NV_PCIE_V2_PORT_COUNT        8ULL
33 #define NV_PCIE_V2_FILTER_ID_MASK    GENMASK_ULL(24, 0)
34 #define NV_PCIE_V2_FILTER_PORT       GENMASK_ULL(NV_PCIE_V2_PORT_COUNT - 1, 0)
35 #define NV_PCIE_V2_FILTER_BDF_VAL    GENMASK_ULL(23, NV_PCIE_V2_PORT_COUNT)
36 #define NV_PCIE_V2_FILTER_BDF_EN     BIT(24)
37 #define NV_PCIE_V2_FILTER_BDF_VAL_EN GENMASK_ULL(24, NV_PCIE_V2_PORT_COUNT)
38 #define NV_PCIE_V2_FILTER_DEFAULT    NV_PCIE_V2_FILTER_PORT
39 
40 #define NV_PCIE_V2_DST_COUNT         5ULL
41 #define NV_PCIE_V2_FILTER2_ID_MASK   GENMASK_ULL(4, 0)
42 #define NV_PCIE_V2_FILTER2_DST       GENMASK_ULL(NV_PCIE_V2_DST_COUNT - 1, 0)
43 #define NV_PCIE_V2_FILTER2_DEFAULT   NV_PCIE_V2_FILTER2_DST
44 
45 #define NV_PCIE_TGT_PORT_COUNT       8ULL
46 #define NV_PCIE_TGT_EV_TYPE_CC       0x4
47 #define NV_PCIE_TGT_EV_TYPE_COUNT    3ULL
48 #define NV_PCIE_TGT_EV_TYPE_MASK     GENMASK_ULL(NV_PCIE_TGT_EV_TYPE_COUNT - 1, 0)
49 #define NV_PCIE_TGT_FILTER2_MASK     GENMASK_ULL(NV_PCIE_TGT_PORT_COUNT, 0)
50 #define NV_PCIE_TGT_FILTER2_PORT     GENMASK_ULL(NV_PCIE_TGT_PORT_COUNT - 1, 0)
51 #define NV_PCIE_TGT_FILTER2_ADDR_EN  BIT(NV_PCIE_TGT_PORT_COUNT)
52 #define NV_PCIE_TGT_FILTER2_ADDR     GENMASK_ULL(15, NV_PCIE_TGT_PORT_COUNT)
53 #define NV_PCIE_TGT_FILTER2_DEFAULT  NV_PCIE_TGT_FILTER2_PORT
54 
55 #define NV_PCIE_TGT_ADDR_COUNT       8ULL
56 #define NV_PCIE_TGT_ADDR_STRIDE      20
57 #define NV_PCIE_TGT_ADDR_CTRL        0xD38
58 #define NV_PCIE_TGT_ADDR_BASE_LO     0xD3C
59 #define NV_PCIE_TGT_ADDR_BASE_HI     0xD40
60 #define NV_PCIE_TGT_ADDR_MASK_LO     0xD44
61 #define NV_PCIE_TGT_ADDR_MASK_HI     0xD48
62 
63 #define NV_GENERIC_FILTER_ID_MASK    GENMASK_ULL(31, 0)
64 
65 #define NV_PRODID_MASK	(PMIIDR_PRODUCTID | PMIIDR_VARIANT | PMIIDR_REVISION)
66 
67 #define NV_FORMAT_NAME_GENERIC	0
68 
69 #define to_nv_cspmu_ctx(cspmu)	((struct nv_cspmu_ctx *)(cspmu->impl.ctx))
70 
71 #define NV_CSPMU_EVENT_ATTR_4_INNER(_pref, _num, _suff, _config)	\
72 	ARM_CSPMU_EVENT_ATTR(_pref##_num##_suff, _config)
73 
74 #define NV_CSPMU_EVENT_ATTR_4(_pref, _suff, _config)			\
75 	NV_CSPMU_EVENT_ATTR_4_INNER(_pref, _0_, _suff, _config),	\
76 	NV_CSPMU_EVENT_ATTR_4_INNER(_pref, _1_, _suff, _config + 1),	\
77 	NV_CSPMU_EVENT_ATTR_4_INNER(_pref, _2_, _suff, _config + 2),	\
78 	NV_CSPMU_EVENT_ATTR_4_INNER(_pref, _3_, _suff, _config + 3)
79 
80 struct nv_cspmu_ctx {
81 	const char *name;
82 
83 	struct attribute **event_attr;
84 	struct attribute **format_attr;
85 
86 	u32 filter_mask;
87 	u32 filter_default_val;
88 	u32 filter2_mask;
89 	u32 filter2_default_val;
90 
91 	u32 (*get_filter)(const struct perf_event *event);
92 	u32 (*get_filter2)(const struct perf_event *event);
93 
94 	void *data;
95 
96 	int (*init_data)(struct arm_cspmu *cspmu);
97 };
98 
99 static struct attribute *scf_pmu_event_attrs[] = {
100 	ARM_CSPMU_EVENT_ATTR(bus_cycles,			0x1d),
101 
102 	ARM_CSPMU_EVENT_ATTR(scf_cache_allocate,		0xF0),
103 	ARM_CSPMU_EVENT_ATTR(scf_cache_refill,			0xF1),
104 	ARM_CSPMU_EVENT_ATTR(scf_cache,				0xF2),
105 	ARM_CSPMU_EVENT_ATTR(scf_cache_wb,			0xF3),
106 
107 	NV_CSPMU_EVENT_ATTR_4(socket, rd_data,			0x101),
108 	NV_CSPMU_EVENT_ATTR_4(socket, wb_data,			0x109),
109 
110 	NV_CSPMU_EVENT_ATTR_4(socket, rd_outstanding,		0x115),
111 
112 	NV_CSPMU_EVENT_ATTR_4(socket, rd_access,		0x12d),
113 	NV_CSPMU_EVENT_ATTR_4(socket, wb_access,		0x135),
114 	NV_CSPMU_EVENT_ATTR_4(socket, wr_access,		0x139),
115 
116 	ARM_CSPMU_EVENT_ATTR(gmem_rd_data,			0x16d),
117 	ARM_CSPMU_EVENT_ATTR(gmem_rd_access,			0x16e),
118 	ARM_CSPMU_EVENT_ATTR(gmem_rd_outstanding,		0x16f),
119 	ARM_CSPMU_EVENT_ATTR(gmem_wb_data,			0x173),
120 	ARM_CSPMU_EVENT_ATTR(gmem_wb_access,			0x174),
121 	ARM_CSPMU_EVENT_ATTR(gmem_wr_data,			0x179),
122 	ARM_CSPMU_EVENT_ATTR(gmem_wr_access,			0x17b),
123 
124 	NV_CSPMU_EVENT_ATTR_4(socket, wr_data,			0x17c),
125 
126 	ARM_CSPMU_EVENT_ATTR(gmem_wr_total_bytes,		0x1a0),
127 	ARM_CSPMU_EVENT_ATTR(remote_socket_wr_total_bytes,	0x1a1),
128 	ARM_CSPMU_EVENT_ATTR(remote_socket_rd_data,		0x1a2),
129 	ARM_CSPMU_EVENT_ATTR(remote_socket_rd_outstanding,	0x1a3),
130 	ARM_CSPMU_EVENT_ATTR(remote_socket_rd_access,		0x1a4),
131 
132 	ARM_CSPMU_EVENT_ATTR(cmem_rd_data,			0x1a5),
133 	ARM_CSPMU_EVENT_ATTR(cmem_rd_access,			0x1a6),
134 	ARM_CSPMU_EVENT_ATTR(cmem_rd_outstanding,		0x1a7),
135 	ARM_CSPMU_EVENT_ATTR(cmem_wb_data,			0x1ab),
136 	ARM_CSPMU_EVENT_ATTR(cmem_wb_access,			0x1ac),
137 	ARM_CSPMU_EVENT_ATTR(cmem_wr_data,			0x1b1),
138 
139 	ARM_CSPMU_EVENT_ATTR(cmem_wr_access,			0x1ca),
140 
141 	ARM_CSPMU_EVENT_ATTR(cmem_wr_total_bytes,		0x1db),
142 
143 	ARM_CSPMU_EVENT_ATTR(cycles, ARM_CSPMU_EVT_CYCLES_DEFAULT),
144 	NULL,
145 };
146 
147 static struct attribute *mcf_pmu_event_attrs[] = {
148 	ARM_CSPMU_EVENT_ATTR(rd_bytes_loc,			0x0),
149 	ARM_CSPMU_EVENT_ATTR(rd_bytes_rem,			0x1),
150 	ARM_CSPMU_EVENT_ATTR(wr_bytes_loc,			0x2),
151 	ARM_CSPMU_EVENT_ATTR(wr_bytes_rem,			0x3),
152 	ARM_CSPMU_EVENT_ATTR(total_bytes_loc,			0x4),
153 	ARM_CSPMU_EVENT_ATTR(total_bytes_rem,			0x5),
154 	ARM_CSPMU_EVENT_ATTR(rd_req_loc,			0x6),
155 	ARM_CSPMU_EVENT_ATTR(rd_req_rem,			0x7),
156 	ARM_CSPMU_EVENT_ATTR(wr_req_loc,			0x8),
157 	ARM_CSPMU_EVENT_ATTR(wr_req_rem,			0x9),
158 	ARM_CSPMU_EVENT_ATTR(total_req_loc,			0xa),
159 	ARM_CSPMU_EVENT_ATTR(total_req_rem,			0xb),
160 	ARM_CSPMU_EVENT_ATTR(rd_cum_outs_loc,			0xc),
161 	ARM_CSPMU_EVENT_ATTR(rd_cum_outs_rem,			0xd),
162 	ARM_CSPMU_EVENT_ATTR(cycles, ARM_CSPMU_EVT_CYCLES_DEFAULT),
163 	NULL,
164 };
165 
166 static struct attribute *ucf_pmu_event_attrs[] = {
167 	ARM_CSPMU_EVENT_ATTR(bus_cycles,            0x1D),
168 
169 	ARM_CSPMU_EVENT_ATTR(slc_allocate,          0xF0),
170 	ARM_CSPMU_EVENT_ATTR(slc_wb,                0xF3),
171 	ARM_CSPMU_EVENT_ATTR(slc_refill_rd,         0x109),
172 	ARM_CSPMU_EVENT_ATTR(slc_refill_wr,         0x10A),
173 	ARM_CSPMU_EVENT_ATTR(slc_hit_rd,            0x119),
174 
175 	ARM_CSPMU_EVENT_ATTR(slc_access_dataless,   0x183),
176 	ARM_CSPMU_EVENT_ATTR(slc_access_atomic,     0x184),
177 
178 	ARM_CSPMU_EVENT_ATTR(slc_access_rd,         0x111),
179 	ARM_CSPMU_EVENT_ATTR(slc_access_wr,         0x112),
180 	ARM_CSPMU_EVENT_ATTR(slc_bytes_rd,          0x113),
181 	ARM_CSPMU_EVENT_ATTR(slc_bytes_wr,          0x114),
182 
183 	ARM_CSPMU_EVENT_ATTR(mem_access_rd,         0x121),
184 	ARM_CSPMU_EVENT_ATTR(mem_access_wr,         0x122),
185 	ARM_CSPMU_EVENT_ATTR(mem_bytes_rd,          0x123),
186 	ARM_CSPMU_EVENT_ATTR(mem_bytes_wr,          0x124),
187 
188 	ARM_CSPMU_EVENT_ATTR(local_snoop,           0x180),
189 	ARM_CSPMU_EVENT_ATTR(ext_snp_access,        0x181),
190 	ARM_CSPMU_EVENT_ATTR(ext_snp_evict,         0x182),
191 
192 	ARM_CSPMU_EVENT_ATTR(cycles, ARM_CSPMU_EVT_CYCLES_DEFAULT),
193 	NULL
194 };
195 
196 static struct attribute *pcie_v2_pmu_event_attrs[] = {
197 	ARM_CSPMU_EVENT_ATTR(rd_bytes,		0x0),
198 	ARM_CSPMU_EVENT_ATTR(wr_bytes,		0x1),
199 	ARM_CSPMU_EVENT_ATTR(rd_req,		0x2),
200 	ARM_CSPMU_EVENT_ATTR(wr_req,		0x3),
201 	ARM_CSPMU_EVENT_ATTR(rd_cum_outs,	0x4),
202 	ARM_CSPMU_EVENT_ATTR(cycles, ARM_CSPMU_EVT_CYCLES_DEFAULT),
203 	NULL
204 };
205 
206 static struct attribute *pcie_tgt_pmu_event_attrs[] = {
207 	ARM_CSPMU_EVENT_ATTR(rd_bytes,		0x0),
208 	ARM_CSPMU_EVENT_ATTR(wr_bytes,		0x1),
209 	ARM_CSPMU_EVENT_ATTR(rd_req,		0x2),
210 	ARM_CSPMU_EVENT_ATTR(wr_req,		0x3),
211 	ARM_CSPMU_EVENT_ATTR(cycles, NV_PCIE_TGT_EV_TYPE_CC),
212 	NULL
213 };
214 
215 static struct attribute *generic_pmu_event_attrs[] = {
216 	ARM_CSPMU_EVENT_ATTR(cycles, ARM_CSPMU_EVT_CYCLES_DEFAULT),
217 	NULL,
218 };
219 
220 static struct attribute *scf_pmu_format_attrs[] = {
221 	ARM_CSPMU_FORMAT_EVENT_ATTR,
222 	NULL,
223 };
224 
225 static struct attribute *pcie_pmu_format_attrs[] = {
226 	ARM_CSPMU_FORMAT_EVENT_ATTR,
227 	ARM_CSPMU_FORMAT_ATTR(root_port, "config1:0-9"),
228 	NULL,
229 };
230 
231 static struct attribute *nvlink_c2c_pmu_format_attrs[] = {
232 	ARM_CSPMU_FORMAT_EVENT_ATTR,
233 	ARM_CSPMU_FORMAT_ATTR(port, "config1:0-1"),
234 	NULL,
235 };
236 
237 static struct attribute *cnvlink_pmu_format_attrs[] = {
238 	ARM_CSPMU_FORMAT_EVENT_ATTR,
239 	ARM_CSPMU_FORMAT_ATTR(rem_socket, "config1:0-3"),
240 	NULL,
241 };
242 
243 static struct attribute *ucf_pmu_format_attrs[] = {
244 	ARM_CSPMU_FORMAT_EVENT_ATTR,
245 	ARM_CSPMU_FORMAT_ATTR(src_loc_noncpu, "config1:0"),
246 	ARM_CSPMU_FORMAT_ATTR(src_loc_cpu, "config1:1"),
247 	ARM_CSPMU_FORMAT_ATTR(src_rem, "config1:2"),
248 	ARM_CSPMU_FORMAT_ATTR(dst_loc_cmem, "config1:8"),
249 	ARM_CSPMU_FORMAT_ATTR(dst_loc_gmem, "config1:9"),
250 	ARM_CSPMU_FORMAT_ATTR(dst_loc_other, "config1:10"),
251 	ARM_CSPMU_FORMAT_ATTR(dst_rem, "config1:11"),
252 	NULL
253 };
254 
255 static struct attribute *pcie_v2_pmu_format_attrs[] = {
256 	ARM_CSPMU_FORMAT_EVENT_ATTR,
257 	ARM_CSPMU_FORMAT_ATTR(src_rp_mask, "config1:0-7"),
258 	ARM_CSPMU_FORMAT_ATTR(src_bdf, "config1:8-23"),
259 	ARM_CSPMU_FORMAT_ATTR(src_bdf_en, "config1:24"),
260 	ARM_CSPMU_FORMAT_ATTR(dst_loc_cmem, "config2:0"),
261 	ARM_CSPMU_FORMAT_ATTR(dst_loc_gmem, "config2:1"),
262 	ARM_CSPMU_FORMAT_ATTR(dst_loc_pcie_p2p, "config2:2"),
263 	ARM_CSPMU_FORMAT_ATTR(dst_loc_pcie_cxl, "config2:3"),
264 	ARM_CSPMU_FORMAT_ATTR(dst_rem, "config2:4"),
265 	NULL
266 };
267 
268 static struct attribute *pcie_tgt_pmu_format_attrs[] = {
269 	ARM_CSPMU_FORMAT_ATTR(event, "config:0-2"),
270 	ARM_CSPMU_FORMAT_ATTR(dst_rp_mask, "config:3-10"),
271 	ARM_CSPMU_FORMAT_ATTR(dst_addr_en, "config:11"),
272 	ARM_CSPMU_FORMAT_ATTR(dst_addr_base, "config1:0-63"),
273 	ARM_CSPMU_FORMAT_ATTR(dst_addr_mask, "config2:0-63"),
274 	NULL
275 };
276 
277 static struct attribute *generic_pmu_format_attrs[] = {
278 	ARM_CSPMU_FORMAT_EVENT_ATTR,
279 	ARM_CSPMU_FORMAT_FILTER_ATTR,
280 	ARM_CSPMU_FORMAT_FILTER2_ATTR,
281 	NULL,
282 };
283 
284 static struct attribute **
nv_cspmu_get_event_attrs(const struct arm_cspmu * cspmu)285 nv_cspmu_get_event_attrs(const struct arm_cspmu *cspmu)
286 {
287 	const struct nv_cspmu_ctx *ctx = to_nv_cspmu_ctx(cspmu);
288 
289 	return ctx->event_attr;
290 }
291 
292 static struct attribute **
nv_cspmu_get_format_attrs(const struct arm_cspmu * cspmu)293 nv_cspmu_get_format_attrs(const struct arm_cspmu *cspmu)
294 {
295 	const struct nv_cspmu_ctx *ctx = to_nv_cspmu_ctx(cspmu);
296 
297 	return ctx->format_attr;
298 }
299 
300 static const char *
nv_cspmu_get_name(const struct arm_cspmu * cspmu)301 nv_cspmu_get_name(const struct arm_cspmu *cspmu)
302 {
303 	const struct nv_cspmu_ctx *ctx = to_nv_cspmu_ctx(cspmu);
304 
305 	return ctx->name;
306 }
307 
308 #if defined(CONFIG_ACPI) && defined(CONFIG_ARM64)
nv_cspmu_get_inst_id(const struct arm_cspmu * cspmu,u32 * id)309 static int nv_cspmu_get_inst_id(const struct arm_cspmu *cspmu, u32 *id)
310 {
311 	struct fwnode_handle *fwnode;
312 	struct acpi_device *adev;
313 	int ret;
314 
315 	adev = arm_cspmu_acpi_dev_get(cspmu);
316 	if (!adev)
317 		return -ENODEV;
318 
319 	fwnode = acpi_fwnode_handle(adev);
320 	ret = fwnode_property_read_u32(fwnode, "instance_id", id);
321 	if (ret)
322 		dev_err(cspmu->dev, "Failed to get instance ID\n");
323 
324 	acpi_dev_put(adev);
325 	return ret;
326 }
327 #else
nv_cspmu_get_inst_id(const struct arm_cspmu * cspmu,u32 * id)328 static int nv_cspmu_get_inst_id(const struct arm_cspmu *cspmu, u32 *id)
329 {
330 	return -EINVAL;
331 }
332 #endif
333 
nv_cspmu_event_filter(const struct perf_event * event)334 static u32 nv_cspmu_event_filter(const struct perf_event *event)
335 {
336 	const struct nv_cspmu_ctx *ctx =
337 		to_nv_cspmu_ctx(to_arm_cspmu(event->pmu));
338 
339 	const u32 filter_val = event->attr.config1 & ctx->filter_mask;
340 
341 	if (filter_val == 0)
342 		return ctx->filter_default_val;
343 
344 	return filter_val;
345 }
346 
nv_cspmu_event_filter2(const struct perf_event * event)347 static u32 nv_cspmu_event_filter2(const struct perf_event *event)
348 {
349 	const struct nv_cspmu_ctx *ctx =
350 		to_nv_cspmu_ctx(to_arm_cspmu(event->pmu));
351 
352 	const u32 filter_val = event->attr.config2 & ctx->filter2_mask;
353 
354 	if (filter_val == 0)
355 		return ctx->filter2_default_val;
356 
357 	return filter_val;
358 }
359 
nv_cspmu_set_ev_filter(struct arm_cspmu * cspmu,const struct perf_event * event)360 static void nv_cspmu_set_ev_filter(struct arm_cspmu *cspmu,
361 				   const struct perf_event *event)
362 {
363 	u32 filter, offset;
364 	const struct nv_cspmu_ctx *ctx =
365 		to_nv_cspmu_ctx(to_arm_cspmu(event->pmu));
366 	offset = 4 * event->hw.idx;
367 
368 	if (ctx->get_filter) {
369 		filter = ctx->get_filter(event);
370 		writel(filter, cspmu->base0 + PMEVFILTR + offset);
371 	}
372 
373 	if (ctx->get_filter2) {
374 		filter = ctx->get_filter2(event);
375 		writel(filter, cspmu->base0 + PMEVFILT2R + offset);
376 	}
377 }
378 
nv_cspmu_reset_ev_filter(struct arm_cspmu * cspmu,const struct perf_event * event)379 static void nv_cspmu_reset_ev_filter(struct arm_cspmu *cspmu,
380 				     const struct perf_event *event)
381 {
382 	const struct nv_cspmu_ctx *ctx =
383 		to_nv_cspmu_ctx(to_arm_cspmu(event->pmu));
384 	const u32 offset = 4 * event->hw.idx;
385 
386 	if (ctx->get_filter)
387 		writel(0, cspmu->base0 + PMEVFILTR + offset);
388 
389 	if (ctx->get_filter2)
390 		writel(0, cspmu->base0 + PMEVFILT2R + offset);
391 }
392 
nv_cspmu_set_cc_filter(struct arm_cspmu * cspmu,const struct perf_event * event)393 static void nv_cspmu_set_cc_filter(struct arm_cspmu *cspmu,
394 				   const struct perf_event *event)
395 {
396 	u32 filter = nv_cspmu_event_filter(event);
397 
398 	writel(filter, cspmu->base0 + PMCCFILTR);
399 }
400 
ucf_pmu_event_filter(const struct perf_event * event)401 static u32 ucf_pmu_event_filter(const struct perf_event *event)
402 {
403 	u32 ret, filter, src, dst;
404 
405 	filter = nv_cspmu_event_filter(event);
406 
407 	/* Monitor all sources if none is selected. */
408 	src = FIELD_GET(NV_UCF_FILTER_SRC, filter);
409 	if (src == 0)
410 		src = GENMASK_ULL(NV_UCF_SRC_COUNT - 1, 0);
411 
412 	/* Monitor all destinations if none is selected. */
413 	dst = FIELD_GET(NV_UCF_FILTER_DST, filter);
414 	if (dst == 0)
415 		dst = GENMASK_ULL(NV_UCF_DST_COUNT - 1, 0);
416 
417 	ret = FIELD_PREP(NV_UCF_FILTER_SRC, src);
418 	ret |= FIELD_PREP(NV_UCF_FILTER_DST, dst);
419 
420 	return ret;
421 }
422 
pcie_v2_pmu_bdf_val_en(u32 filter)423 static u32 pcie_v2_pmu_bdf_val_en(u32 filter)
424 {
425 	const u32 bdf_en = FIELD_GET(NV_PCIE_V2_FILTER_BDF_EN, filter);
426 
427 	/* Returns both BDF value and enable bit if BDF filtering is enabled. */
428 	if (bdf_en)
429 		return FIELD_GET(NV_PCIE_V2_FILTER_BDF_VAL_EN, filter);
430 
431 	/* Ignore the BDF value if BDF filter is not enabled. */
432 	return 0;
433 }
434 
pcie_v2_pmu_event_filter(const struct perf_event * event)435 static u32 pcie_v2_pmu_event_filter(const struct perf_event *event)
436 {
437 	u32 filter, lead_filter, lead_bdf;
438 	struct perf_event *leader;
439 	const struct nv_cspmu_ctx *ctx =
440 		to_nv_cspmu_ctx(to_arm_cspmu(event->pmu));
441 
442 	filter = event->attr.config1 & ctx->filter_mask;
443 	if (filter != 0)
444 		return filter;
445 
446 	leader = event->group_leader;
447 
448 	/* Use leader's filter value if its BDF filtering is enabled. */
449 	if (event != leader) {
450 		lead_filter = pcie_v2_pmu_event_filter(leader);
451 		lead_bdf = pcie_v2_pmu_bdf_val_en(lead_filter);
452 		if (lead_bdf != 0)
453 			return lead_filter;
454 	}
455 
456 	/* Otherwise, return default filter value. */
457 	return ctx->filter_default_val;
458 }
459 
pcie_v2_pmu_validate_event(struct arm_cspmu * cspmu,struct perf_event * new_ev)460 static int pcie_v2_pmu_validate_event(struct arm_cspmu *cspmu,
461 				   struct perf_event *new_ev)
462 {
463 	/*
464 	 * Make sure the events are using same BDF filter since the PCIE-SRC PMU
465 	 * only supports one common BDF filter setting for all of the counters.
466 	 */
467 
468 	int idx;
469 	u32 new_filter, new_rp, new_bdf, new_lead_filter, new_lead_bdf;
470 	struct perf_event *new_leader;
471 
472 	if (cspmu->impl.ops.is_cycle_counter_event(new_ev))
473 		return 0;
474 
475 	new_leader = new_ev->group_leader;
476 
477 	new_filter = pcie_v2_pmu_event_filter(new_ev);
478 	new_lead_filter = pcie_v2_pmu_event_filter(new_leader);
479 
480 	new_bdf = pcie_v2_pmu_bdf_val_en(new_filter);
481 	new_lead_bdf = pcie_v2_pmu_bdf_val_en(new_lead_filter);
482 
483 	new_rp = FIELD_GET(NV_PCIE_V2_FILTER_PORT, new_filter);
484 
485 	if (new_rp != 0 && new_bdf != 0) {
486 		dev_err(cspmu->dev,
487 			"RP and BDF filtering are mutually exclusive\n");
488 		return -EINVAL;
489 	}
490 
491 	if (new_bdf != new_lead_bdf) {
492 		dev_err(cspmu->dev,
493 			"sibling and leader BDF value should be equal\n");
494 		return -EINVAL;
495 	}
496 
497 	/* Compare BDF filter on existing events. */
498 	idx = find_first_bit(cspmu->hw_events.used_ctrs,
499 			     cspmu->cycle_counter_logical_idx);
500 
501 	if (idx != cspmu->cycle_counter_logical_idx) {
502 		struct perf_event *leader = cspmu->hw_events.events[idx]->group_leader;
503 
504 		const u32 lead_filter = pcie_v2_pmu_event_filter(leader);
505 		const u32 lead_bdf = pcie_v2_pmu_bdf_val_en(lead_filter);
506 
507 		if (new_lead_bdf != lead_bdf) {
508 			dev_err(cspmu->dev, "only one BDF value is supported\n");
509 			return -EINVAL;
510 		}
511 	}
512 
513 	return 0;
514 }
515 
516 struct pcie_tgt_addr_filter {
517 	u32 refcount;
518 	u64 base;
519 	u64 mask;
520 };
521 
522 struct pcie_tgt_data {
523 	struct pcie_tgt_addr_filter addr_filter[NV_PCIE_TGT_ADDR_COUNT];
524 	void __iomem *addr_filter_reg;
525 };
526 
527 #if defined(CONFIG_ACPI) && defined(CONFIG_ARM64)
pcie_tgt_init_data(struct arm_cspmu * cspmu)528 static int pcie_tgt_init_data(struct arm_cspmu *cspmu)
529 {
530 	int ret;
531 	struct acpi_device *adev;
532 	struct pcie_tgt_data *data;
533 	struct list_head resource_list;
534 	struct resource_entry *rentry;
535 	struct nv_cspmu_ctx *ctx = to_nv_cspmu_ctx(cspmu);
536 	struct device *dev = cspmu->dev;
537 
538 	data = devm_kzalloc(dev, sizeof(struct pcie_tgt_data), GFP_KERNEL);
539 	if (!data)
540 		return -ENOMEM;
541 
542 	adev = arm_cspmu_acpi_dev_get(cspmu);
543 	if (!adev) {
544 		dev_err(dev, "failed to get associated PCIE-TGT device\n");
545 		return -ENODEV;
546 	}
547 
548 	INIT_LIST_HEAD(&resource_list);
549 	ret = acpi_dev_get_memory_resources(adev, &resource_list);
550 	if (ret < 0) {
551 		dev_err(dev, "failed to get PCIE-TGT device memory resources\n");
552 		acpi_dev_put(adev);
553 		return ret;
554 	}
555 
556 	rentry = list_first_entry_or_null(
557 		&resource_list, struct resource_entry, node);
558 	if (rentry) {
559 		data->addr_filter_reg = devm_ioremap_resource(dev, rentry->res);
560 		ret = 0;
561 	}
562 
563 	if (IS_ERR(data->addr_filter_reg)) {
564 		dev_err(dev, "failed to get address filter resource\n");
565 		ret = PTR_ERR(data->addr_filter_reg);
566 	}
567 
568 	acpi_dev_free_resource_list(&resource_list);
569 	acpi_dev_put(adev);
570 
571 	ctx->data = data;
572 
573 	return ret;
574 }
575 #else
pcie_tgt_init_data(struct arm_cspmu * cspmu)576 static int pcie_tgt_init_data(struct arm_cspmu *cspmu)
577 {
578 	return -ENODEV;
579 }
580 #endif
581 
pcie_tgt_get_data(struct arm_cspmu * cspmu)582 static struct pcie_tgt_data *pcie_tgt_get_data(struct arm_cspmu *cspmu)
583 {
584 	struct nv_cspmu_ctx *ctx = to_nv_cspmu_ctx(cspmu);
585 
586 	return ctx->data;
587 }
588 
589 /* Find the first available address filter slot. */
pcie_tgt_find_addr_idx(struct arm_cspmu * cspmu,u64 base,u64 mask,bool is_reset)590 static int pcie_tgt_find_addr_idx(struct arm_cspmu *cspmu, u64 base, u64 mask,
591 	bool is_reset)
592 {
593 	int i;
594 	struct pcie_tgt_data *data = pcie_tgt_get_data(cspmu);
595 
596 	for (i = 0; i < NV_PCIE_TGT_ADDR_COUNT; i++) {
597 		if (!is_reset && data->addr_filter[i].refcount == 0)
598 			return i;
599 
600 		if (data->addr_filter[i].base == base &&
601 			data->addr_filter[i].mask == mask)
602 			return i;
603 	}
604 
605 	return -ENODEV;
606 }
607 
pcie_tgt_pmu_event_filter(const struct perf_event * event)608 static u32 pcie_tgt_pmu_event_filter(const struct perf_event *event)
609 {
610 	u32 filter;
611 
612 	filter = (event->attr.config >> NV_PCIE_TGT_EV_TYPE_COUNT) &
613 		NV_PCIE_TGT_FILTER2_MASK;
614 
615 	return filter;
616 }
617 
pcie_tgt_pmu_addr_en(const struct perf_event * event)618 static bool pcie_tgt_pmu_addr_en(const struct perf_event *event)
619 {
620 	u32 filter = pcie_tgt_pmu_event_filter(event);
621 
622 	return FIELD_GET(NV_PCIE_TGT_FILTER2_ADDR_EN, filter) != 0;
623 }
624 
pcie_tgt_pmu_port_filter(const struct perf_event * event)625 static u32 pcie_tgt_pmu_port_filter(const struct perf_event *event)
626 {
627 	u32 filter = pcie_tgt_pmu_event_filter(event);
628 
629 	return FIELD_GET(NV_PCIE_TGT_FILTER2_PORT, filter);
630 }
631 
pcie_tgt_pmu_dst_addr_base(const struct perf_event * event)632 static u64 pcie_tgt_pmu_dst_addr_base(const struct perf_event *event)
633 {
634 	return event->attr.config1;
635 }
636 
pcie_tgt_pmu_dst_addr_mask(const struct perf_event * event)637 static u64 pcie_tgt_pmu_dst_addr_mask(const struct perf_event *event)
638 {
639 	return event->attr.config2;
640 }
641 
pcie_tgt_pmu_validate_event(struct arm_cspmu * cspmu,struct perf_event * new_ev)642 static int pcie_tgt_pmu_validate_event(struct arm_cspmu *cspmu,
643 				   struct perf_event *new_ev)
644 {
645 	u64 base, mask;
646 	int idx;
647 
648 	if (!pcie_tgt_pmu_addr_en(new_ev))
649 		return 0;
650 
651 	/* Make sure there is a slot available for the address filter. */
652 	base = pcie_tgt_pmu_dst_addr_base(new_ev);
653 	mask = pcie_tgt_pmu_dst_addr_mask(new_ev);
654 	idx = pcie_tgt_find_addr_idx(cspmu, base, mask, false);
655 	if (idx < 0)
656 		return -EINVAL;
657 
658 	return 0;
659 }
660 
pcie_tgt_pmu_config_addr_filter(struct arm_cspmu * cspmu,bool en,u64 base,u64 mask,int idx)661 static void pcie_tgt_pmu_config_addr_filter(struct arm_cspmu *cspmu,
662 	bool en, u64 base, u64 mask, int idx)
663 {
664 	struct pcie_tgt_data *data;
665 	struct pcie_tgt_addr_filter *filter;
666 	void __iomem *filter_reg;
667 
668 	data = pcie_tgt_get_data(cspmu);
669 	filter = &data->addr_filter[idx];
670 	filter_reg = data->addr_filter_reg + (idx * NV_PCIE_TGT_ADDR_STRIDE);
671 
672 	if (en) {
673 		filter->refcount++;
674 		if (filter->refcount == 1) {
675 			filter->base = base;
676 			filter->mask = mask;
677 
678 			writel(lower_32_bits(base), filter_reg + NV_PCIE_TGT_ADDR_BASE_LO);
679 			writel(upper_32_bits(base), filter_reg + NV_PCIE_TGT_ADDR_BASE_HI);
680 			writel(lower_32_bits(mask), filter_reg + NV_PCIE_TGT_ADDR_MASK_LO);
681 			writel(upper_32_bits(mask), filter_reg + NV_PCIE_TGT_ADDR_MASK_HI);
682 			writel(1, filter_reg + NV_PCIE_TGT_ADDR_CTRL);
683 		}
684 	} else {
685 		filter->refcount--;
686 		if (filter->refcount == 0) {
687 			writel(0, filter_reg + NV_PCIE_TGT_ADDR_CTRL);
688 			writel(0, filter_reg + NV_PCIE_TGT_ADDR_BASE_LO);
689 			writel(0, filter_reg + NV_PCIE_TGT_ADDR_BASE_HI);
690 			writel(0, filter_reg + NV_PCIE_TGT_ADDR_MASK_LO);
691 			writel(0, filter_reg + NV_PCIE_TGT_ADDR_MASK_HI);
692 
693 			filter->base = 0;
694 			filter->mask = 0;
695 		}
696 	}
697 }
698 
pcie_tgt_pmu_set_ev_filter(struct arm_cspmu * cspmu,const struct perf_event * event)699 static void pcie_tgt_pmu_set_ev_filter(struct arm_cspmu *cspmu,
700 				const struct perf_event *event)
701 {
702 	bool addr_filter_en;
703 	int idx;
704 	u32 filter2_val, filter2_offset, port_filter;
705 	u64 base, mask;
706 
707 	filter2_val = 0;
708 	filter2_offset = PMEVFILT2R + (4 * event->hw.idx);
709 
710 	addr_filter_en = pcie_tgt_pmu_addr_en(event);
711 	if (addr_filter_en) {
712 		base = pcie_tgt_pmu_dst_addr_base(event);
713 		mask = pcie_tgt_pmu_dst_addr_mask(event);
714 		idx = pcie_tgt_find_addr_idx(cspmu, base, mask, false);
715 
716 		if (idx < 0) {
717 			dev_err(cspmu->dev,
718 				"Unable to find a slot for address filtering\n");
719 			writel(0, cspmu->base0 + filter2_offset);
720 			return;
721 		}
722 
723 		/* Configure address range filter registers.*/
724 		pcie_tgt_pmu_config_addr_filter(cspmu, true, base, mask, idx);
725 
726 		/* Config the counter to use the selected address filter slot. */
727 		filter2_val |= FIELD_PREP(NV_PCIE_TGT_FILTER2_ADDR, 1U << idx);
728 	}
729 
730 	port_filter = pcie_tgt_pmu_port_filter(event);
731 
732 	/* Monitor all ports if no filter is selected. */
733 	if (!addr_filter_en && port_filter == 0)
734 		port_filter = NV_PCIE_TGT_FILTER2_PORT;
735 
736 	filter2_val |= FIELD_PREP(NV_PCIE_TGT_FILTER2_PORT, port_filter);
737 
738 	writel(filter2_val, cspmu->base0 + filter2_offset);
739 }
740 
pcie_tgt_pmu_reset_ev_filter(struct arm_cspmu * cspmu,const struct perf_event * event)741 static void pcie_tgt_pmu_reset_ev_filter(struct arm_cspmu *cspmu,
742 				     const struct perf_event *event)
743 {
744 	bool addr_filter_en;
745 	u64 base, mask;
746 	int idx;
747 
748 	addr_filter_en = pcie_tgt_pmu_addr_en(event);
749 	if (!addr_filter_en)
750 		return;
751 
752 	base = pcie_tgt_pmu_dst_addr_base(event);
753 	mask = pcie_tgt_pmu_dst_addr_mask(event);
754 	idx = pcie_tgt_find_addr_idx(cspmu, base, mask, true);
755 
756 	if (idx < 0) {
757 		dev_err(cspmu->dev,
758 			"Unable to find the address filter slot to reset\n");
759 		return;
760 	}
761 
762 	pcie_tgt_pmu_config_addr_filter(cspmu, false, base, mask, idx);
763 }
764 
pcie_tgt_pmu_event_type(const struct perf_event * event)765 static u32 pcie_tgt_pmu_event_type(const struct perf_event *event)
766 {
767 	return event->attr.config & NV_PCIE_TGT_EV_TYPE_MASK;
768 }
769 
pcie_tgt_pmu_is_cycle_counter_event(const struct perf_event * event)770 static bool pcie_tgt_pmu_is_cycle_counter_event(const struct perf_event *event)
771 {
772 	u32 event_type = pcie_tgt_pmu_event_type(event);
773 
774 	return event_type == NV_PCIE_TGT_EV_TYPE_CC;
775 }
776 
777 enum nv_cspmu_name_fmt {
778 	NAME_FMT_GENERIC,
779 	NAME_FMT_SOCKET,
780 	NAME_FMT_SOCKET_INST,
781 };
782 
783 struct nv_cspmu_match {
784 	u32 prodid;
785 	u32 prodid_mask;
786 	const char *name_pattern;
787 	enum nv_cspmu_name_fmt name_fmt;
788 	struct nv_cspmu_ctx template_ctx;
789 	struct arm_cspmu_impl_ops ops;
790 };
791 
792 static const struct nv_cspmu_match nv_cspmu_match[] = {
793 	{
794 	  .prodid = 0x10300000,
795 	  .prodid_mask = NV_PRODID_MASK,
796 	  .name_pattern = "nvidia_pcie_pmu_%u",
797 	  .name_fmt = NAME_FMT_SOCKET,
798 	  .template_ctx = {
799 		.event_attr = mcf_pmu_event_attrs,
800 		.format_attr = pcie_pmu_format_attrs,
801 		.filter_mask = NV_PCIE_FILTER_ID_MASK,
802 		.filter_default_val = NV_PCIE_FILTER_ID_MASK,
803 		.filter2_mask = 0x0,
804 		.filter2_default_val = 0x0,
805 		.get_filter = nv_cspmu_event_filter,
806 		.get_filter2 = NULL,
807 		.data = NULL,
808 		.init_data = NULL
809 	  },
810 	},
811 	{
812 	  .prodid = 0x10400000,
813 	  .prodid_mask = NV_PRODID_MASK,
814 	  .name_pattern = "nvidia_nvlink_c2c1_pmu_%u",
815 	  .name_fmt = NAME_FMT_SOCKET,
816 	  .template_ctx = {
817 		.event_attr = mcf_pmu_event_attrs,
818 		.format_attr = nvlink_c2c_pmu_format_attrs,
819 		.filter_mask = NV_NVL_C2C_FILTER_ID_MASK,
820 		.filter_default_val = NV_NVL_C2C_FILTER_ID_MASK,
821 		.filter2_mask = 0x0,
822 		.filter2_default_val = 0x0,
823 		.get_filter = nv_cspmu_event_filter,
824 		.get_filter2 = NULL,
825 		.data = NULL,
826 		.init_data = NULL
827 	  },
828 	},
829 	{
830 	  .prodid = 0x10500000,
831 	  .prodid_mask = NV_PRODID_MASK,
832 	  .name_pattern = "nvidia_nvlink_c2c0_pmu_%u",
833 	  .name_fmt = NAME_FMT_SOCKET,
834 	  .template_ctx = {
835 		.event_attr = mcf_pmu_event_attrs,
836 		.format_attr = nvlink_c2c_pmu_format_attrs,
837 		.filter_mask = NV_NVL_C2C_FILTER_ID_MASK,
838 		.filter_default_val = NV_NVL_C2C_FILTER_ID_MASK,
839 		.filter2_mask = 0x0,
840 		.filter2_default_val = 0x0,
841 		.get_filter = nv_cspmu_event_filter,
842 		.get_filter2 = NULL,
843 		.data = NULL,
844 		.init_data = NULL
845 	  },
846 	},
847 	{
848 	  .prodid = 0x10600000,
849 	  .prodid_mask = NV_PRODID_MASK,
850 	  .name_pattern = "nvidia_cnvlink_pmu_%u",
851 	  .name_fmt = NAME_FMT_SOCKET,
852 	  .template_ctx = {
853 		.event_attr = mcf_pmu_event_attrs,
854 		.format_attr = cnvlink_pmu_format_attrs,
855 		.filter_mask = NV_CNVL_FILTER_ID_MASK,
856 		.filter_default_val = NV_CNVL_FILTER_ID_MASK,
857 		.filter2_mask = 0x0,
858 		.filter2_default_val = 0x0,
859 		.get_filter = nv_cspmu_event_filter,
860 		.get_filter2 = NULL,
861 		.data = NULL,
862 		.init_data = NULL
863 	  },
864 	},
865 	{
866 	  .prodid = 0x2CF00000,
867 	  .prodid_mask = NV_PRODID_MASK,
868 	  .name_pattern = "nvidia_scf_pmu_%u",
869 	  .name_fmt = NAME_FMT_SOCKET,
870 	  .template_ctx = {
871 		.event_attr = scf_pmu_event_attrs,
872 		.format_attr = scf_pmu_format_attrs,
873 		.filter_mask = 0x0,
874 		.filter_default_val = 0x0,
875 		.filter2_mask = 0x0,
876 		.filter2_default_val = 0x0,
877 		.get_filter = nv_cspmu_event_filter,
878 		.get_filter2 = NULL,
879 		.data = NULL,
880 		.init_data = NULL
881 	  },
882 	},
883 	{
884 	  .prodid = 0x2CF20000,
885 	  .prodid_mask = NV_PRODID_MASK,
886 	  .name_pattern = "nvidia_ucf_pmu_%u",
887 	  .name_fmt = NAME_FMT_SOCKET,
888 	  .template_ctx = {
889 		.event_attr = ucf_pmu_event_attrs,
890 		.format_attr = ucf_pmu_format_attrs,
891 		.filter_mask = NV_UCF_FILTER_ID_MASK,
892 		.filter_default_val = NV_UCF_FILTER_DEFAULT,
893 		.filter2_mask = 0x0,
894 		.filter2_default_val = 0x0,
895 		.get_filter = ucf_pmu_event_filter,
896 	  },
897 	},
898 	{
899 	  .prodid = 0x10301000,
900 	  .prodid_mask = NV_PRODID_MASK,
901 	  .name_pattern = "nvidia_pcie_pmu_%u_rc_%u",
902 	  .name_fmt = NAME_FMT_SOCKET_INST,
903 	  .template_ctx = {
904 		.event_attr = pcie_v2_pmu_event_attrs,
905 		.format_attr = pcie_v2_pmu_format_attrs,
906 		.filter_mask = NV_PCIE_V2_FILTER_ID_MASK,
907 		.filter_default_val = NV_PCIE_V2_FILTER_DEFAULT,
908 		.filter2_mask = NV_PCIE_V2_FILTER2_ID_MASK,
909 		.filter2_default_val = NV_PCIE_V2_FILTER2_DEFAULT,
910 		.get_filter = pcie_v2_pmu_event_filter,
911 		.get_filter2 = nv_cspmu_event_filter2,
912 	  },
913 	  .ops = {
914 		.validate_event = pcie_v2_pmu_validate_event,
915 		.reset_ev_filter = nv_cspmu_reset_ev_filter,
916 	  }
917 	},
918 	{
919 	  .prodid = 0x10700000,
920 	  .prodid_mask = NV_PRODID_MASK,
921 	  .name_pattern = "nvidia_pcie_tgt_pmu_%u_rc_%u",
922 	  .name_fmt = NAME_FMT_SOCKET_INST,
923 	  .template_ctx = {
924 		.event_attr = pcie_tgt_pmu_event_attrs,
925 		.format_attr = pcie_tgt_pmu_format_attrs,
926 		.filter_mask = 0x0,
927 		.filter_default_val = 0x0,
928 		.filter2_mask = NV_PCIE_TGT_FILTER2_MASK,
929 		.filter2_default_val = NV_PCIE_TGT_FILTER2_DEFAULT,
930 		.init_data = pcie_tgt_init_data
931 	  },
932 	  .ops = {
933 		.is_cycle_counter_event = pcie_tgt_pmu_is_cycle_counter_event,
934 		.event_type = pcie_tgt_pmu_event_type,
935 		.validate_event = pcie_tgt_pmu_validate_event,
936 		.set_ev_filter = pcie_tgt_pmu_set_ev_filter,
937 		.reset_ev_filter = pcie_tgt_pmu_reset_ev_filter,
938 	  }
939 	},
940 	{
941 	  .prodid = 0,
942 	  .prodid_mask = 0,
943 	  .name_pattern = "nvidia_uncore_pmu_%u",
944 	  .name_fmt = NAME_FMT_GENERIC,
945 	  .template_ctx = {
946 		.event_attr = generic_pmu_event_attrs,
947 		.format_attr = generic_pmu_format_attrs,
948 		.filter_mask = NV_GENERIC_FILTER_ID_MASK,
949 		.filter_default_val = NV_GENERIC_FILTER_ID_MASK,
950 		.filter2_mask = NV_GENERIC_FILTER_ID_MASK,
951 		.filter2_default_val = NV_GENERIC_FILTER_ID_MASK,
952 		.get_filter = nv_cspmu_event_filter,
953 		.get_filter2 = nv_cspmu_event_filter2,
954 		.data = NULL,
955 		.init_data = NULL
956 	  },
957 	},
958 };
959 
nv_cspmu_format_name(const struct arm_cspmu * cspmu,const struct nv_cspmu_match * match)960 static char *nv_cspmu_format_name(const struct arm_cspmu *cspmu,
961 				  const struct nv_cspmu_match *match)
962 {
963 	char *name = NULL;
964 	struct device *dev = cspmu->dev;
965 
966 	static atomic_t pmu_generic_idx = {0};
967 
968 	switch (match->name_fmt) {
969 	case NAME_FMT_SOCKET: {
970 		const int cpu = cpumask_first(&cspmu->associated_cpus);
971 		const int socket = cpu_to_node(cpu);
972 
973 		name = devm_kasprintf(dev, GFP_KERNEL, match->name_pattern,
974 				       socket);
975 		break;
976 	}
977 	case NAME_FMT_SOCKET_INST: {
978 		const int cpu = cpumask_first(&cspmu->associated_cpus);
979 		const int socket = cpu_to_node(cpu);
980 		u32 inst_id;
981 
982 		if (!nv_cspmu_get_inst_id(cspmu, &inst_id))
983 			name = devm_kasprintf(dev, GFP_KERNEL,
984 					match->name_pattern, socket, inst_id);
985 		break;
986 	}
987 	case NAME_FMT_GENERIC:
988 		name = devm_kasprintf(dev, GFP_KERNEL, match->name_pattern,
989 				       atomic_fetch_inc(&pmu_generic_idx));
990 		break;
991 	}
992 
993 	return name;
994 }
995 
996 #define SET_OP(name, impl, match, default_op) \
997 	do { \
998 		if (match->ops.name) \
999 			impl->name = match->ops.name; \
1000 		else if (default_op != NULL) \
1001 			impl->name = default_op; \
1002 	} while (false)
1003 
nv_cspmu_init_ops(struct arm_cspmu * cspmu)1004 static int nv_cspmu_init_ops(struct arm_cspmu *cspmu)
1005 {
1006 	struct nv_cspmu_ctx *ctx;
1007 	struct device *dev = cspmu->dev;
1008 	struct arm_cspmu_impl_ops *impl_ops = &cspmu->impl.ops;
1009 	const struct nv_cspmu_match *match = nv_cspmu_match;
1010 
1011 	ctx = devm_kzalloc(dev, sizeof(struct nv_cspmu_ctx), GFP_KERNEL);
1012 	if (!ctx)
1013 		return -ENOMEM;
1014 
1015 	/* Find matching PMU. */
1016 	for (; match->prodid; match++) {
1017 		const u32 prodid_mask = match->prodid_mask;
1018 
1019 		if ((match->prodid & prodid_mask) ==
1020 		    (cspmu->impl.pmiidr & prodid_mask))
1021 			break;
1022 	}
1023 
1024 	/* Initialize the context with the matched template. */
1025 	memcpy(ctx, &match->template_ctx, sizeof(struct nv_cspmu_ctx));
1026 	ctx->name = nv_cspmu_format_name(cspmu, match);
1027 
1028 	cspmu->impl.ctx = ctx;
1029 
1030 	/* NVIDIA specific callbacks. */
1031 	SET_OP(validate_event, impl_ops, match, NULL);
1032 	SET_OP(event_type, impl_ops, match, NULL);
1033 	SET_OP(is_cycle_counter_event, impl_ops, match, NULL);
1034 	SET_OP(set_cc_filter, impl_ops, match, nv_cspmu_set_cc_filter);
1035 	SET_OP(set_ev_filter, impl_ops, match, nv_cspmu_set_ev_filter);
1036 	SET_OP(reset_ev_filter, impl_ops, match, NULL);
1037 	SET_OP(get_event_attrs, impl_ops, match, nv_cspmu_get_event_attrs);
1038 	SET_OP(get_format_attrs, impl_ops, match, nv_cspmu_get_format_attrs);
1039 	SET_OP(get_name, impl_ops, match, nv_cspmu_get_name);
1040 
1041 	if (ctx->init_data)
1042 		return ctx->init_data(cspmu);
1043 
1044 	return 0;
1045 }
1046 
1047 /* Match all NVIDIA Coresight PMU devices */
1048 static const struct arm_cspmu_impl_match nv_cspmu_param = {
1049 	.pmiidr_val	= ARM_CSPMU_IMPL_ID_NVIDIA,
1050 	.module		= THIS_MODULE,
1051 	.impl_init_ops	= nv_cspmu_init_ops
1052 };
1053 
nvidia_cspmu_init(void)1054 static int __init nvidia_cspmu_init(void)
1055 {
1056 	int ret;
1057 
1058 	ret = arm_cspmu_impl_register(&nv_cspmu_param);
1059 	if (ret)
1060 		pr_err("nvidia_cspmu backend registration error: %d\n", ret);
1061 
1062 	return ret;
1063 }
1064 
nvidia_cspmu_exit(void)1065 static void __exit nvidia_cspmu_exit(void)
1066 {
1067 	arm_cspmu_impl_unregister(&nv_cspmu_param);
1068 }
1069 
1070 module_init(nvidia_cspmu_init);
1071 module_exit(nvidia_cspmu_exit);
1072 
1073 MODULE_DESCRIPTION("NVIDIA Coresight Architecture Performance Monitor Driver");
1074 MODULE_LICENSE("GPL v2");
1075