perf: Use device_show_string() helper for sysfs attributes
[linux-block.git] / drivers / perf / hisilicon / hisi_pcie_pmu.c
CommitLineData
8404b0fb
QL
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * This driver adds support for PCIe PMU RCiEP device. Related
4 * perf events are bandwidth, latency etc.
5 *
6 * Copyright (C) 2021 HiSilicon Limited
7 * Author: Qi Liu <liuqi115@huawei.com>
8 */
9#include <linux/bitfield.h>
10#include <linux/bitmap.h>
11#include <linux/bug.h>
12#include <linux/device.h>
13#include <linux/err.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/kernel.h>
17#include <linux/list.h>
18#include <linux/module.h>
19#include <linux/pci.h>
20#include <linux/perf_event.h>
21
22#define DRV_NAME "hisi_pcie_pmu"
23/* Define registers */
24#define HISI_PCIE_GLOBAL_CTRL 0x00
25#define HISI_PCIE_EVENT_CTRL 0x010
26#define HISI_PCIE_CNT 0x090
27#define HISI_PCIE_EXT_CNT 0x110
28#define HISI_PCIE_INT_STAT 0x150
29#define HISI_PCIE_INT_MASK 0x154
30#define HISI_PCIE_REG_BDF 0xfe0
31#define HISI_PCIE_REG_VERSION 0xfe4
32#define HISI_PCIE_REG_INFO 0xfe8
33
34/* Define command in HISI_PCIE_GLOBAL_CTRL */
35#define HISI_PCIE_GLOBAL_EN 0x01
36#define HISI_PCIE_GLOBAL_NONE 0
37
38/* Define command in HISI_PCIE_EVENT_CTRL */
39#define HISI_PCIE_EVENT_EN BIT_ULL(20)
40#define HISI_PCIE_RESET_CNT BIT_ULL(22)
41#define HISI_PCIE_INIT_SET BIT_ULL(34)
42#define HISI_PCIE_THR_EN BIT_ULL(26)
43#define HISI_PCIE_TARGET_EN BIT_ULL(32)
44#define HISI_PCIE_TRIG_EN BIT_ULL(52)
45
46/* Define offsets in HISI_PCIE_EVENT_CTRL */
47#define HISI_PCIE_EVENT_M GENMASK_ULL(15, 0)
48#define HISI_PCIE_THR_MODE_M GENMASK_ULL(27, 27)
49#define HISI_PCIE_THR_M GENMASK_ULL(31, 28)
17d57398 50#define HISI_PCIE_LEN_M GENMASK_ULL(35, 34)
8404b0fb
QL
51#define HISI_PCIE_TARGET_M GENMASK_ULL(52, 36)
52#define HISI_PCIE_TRIG_MODE_M GENMASK_ULL(53, 53)
53#define HISI_PCIE_TRIG_M GENMASK_ULL(59, 56)
54
17d57398
YY
55/* Default config of TLP length mode, will count both TLP headers and payloads */
56#define HISI_PCIE_LEN_M_DEFAULT 3ULL
57
8404b0fb
QL
58#define HISI_PCIE_MAX_COUNTERS 8
59#define HISI_PCIE_REG_STEP 8
60#define HISI_PCIE_THR_MAX_VAL 10
61#define HISI_PCIE_TRIG_MAX_VAL 10
62#define HISI_PCIE_MAX_PERIOD (GENMASK_ULL(63, 0))
63#define HISI_PCIE_INIT_VAL BIT_ULL(63)
64
65struct hisi_pcie_pmu {
66 struct perf_event *hw_events[HISI_PCIE_MAX_COUNTERS];
67 struct hlist_node node;
68 struct pci_dev *pdev;
69 struct pmu pmu;
70 void __iomem *base;
71 int irq;
72 u32 identifier;
73 /* Minimum and maximum BDF of root ports monitored by PMU */
74 u16 bdf_min;
75 u16 bdf_max;
76 int on_cpu;
77};
78
79struct hisi_pcie_reg_pair {
80 u16 lo;
81 u16 hi;
82};
83
84#define to_pcie_pmu(p) (container_of((p), struct hisi_pcie_pmu, pmu))
85#define GET_PCI_DEVFN(bdf) ((bdf) & 0xff)
86
87#define HISI_PCIE_PMU_FILTER_ATTR(_name, _config, _hi, _lo) \
88 static u64 hisi_pcie_get_##_name(struct perf_event *event) \
89 { \
90 return FIELD_GET(GENMASK(_hi, _lo), event->attr._config); \
91 } \
92
93HISI_PCIE_PMU_FILTER_ATTR(event, config, 16, 0);
94HISI_PCIE_PMU_FILTER_ATTR(thr_len, config1, 3, 0);
95HISI_PCIE_PMU_FILTER_ATTR(thr_mode, config1, 4, 4);
96HISI_PCIE_PMU_FILTER_ATTR(trig_len, config1, 8, 5);
97HISI_PCIE_PMU_FILTER_ATTR(trig_mode, config1, 9, 9);
17d57398 98HISI_PCIE_PMU_FILTER_ATTR(len_mode, config1, 11, 10);
8404b0fb
QL
99HISI_PCIE_PMU_FILTER_ATTR(port, config2, 15, 0);
100HISI_PCIE_PMU_FILTER_ATTR(bdf, config2, 31, 16);
101
8404b0fb
QL
102static ssize_t hisi_pcie_event_sysfs_show(struct device *dev, struct device_attribute *attr,
103 char *buf)
104{
105 struct perf_pmu_events_attr *pmu_attr =
106 container_of(attr, struct perf_pmu_events_attr, attr);
107
108 return sysfs_emit(buf, "config=0x%llx\n", pmu_attr->id);
109}
110
111#define HISI_PCIE_PMU_FORMAT_ATTR(_name, _format) \
112 (&((struct dev_ext_attribute[]){ \
b91b73a4 113 { .attr = __ATTR(_name, 0444, device_show_string, NULL), \
8404b0fb
QL
114 .var = (void *)_format } \
115 })[0].attr.attr)
116
117#define HISI_PCIE_PMU_EVENT_ATTR(_name, _id) \
118 PMU_EVENT_ATTR_ID(_name, hisi_pcie_event_sysfs_show, _id)
119
120static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr, char *buf)
121{
122 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(dev_get_drvdata(dev));
123
124 return cpumap_print_to_pagebuf(true, buf, cpumask_of(pcie_pmu->on_cpu));
125}
126static DEVICE_ATTR_RO(cpumask);
127
128static ssize_t identifier_show(struct device *dev, struct device_attribute *attr, char *buf)
129{
130 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(dev_get_drvdata(dev));
131
132 return sysfs_emit(buf, "%#x\n", pcie_pmu->identifier);
133}
134static DEVICE_ATTR_RO(identifier);
135
136static ssize_t bus_show(struct device *dev, struct device_attribute *attr, char *buf)
137{
138 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(dev_get_drvdata(dev));
139
140 return sysfs_emit(buf, "%#04x\n", PCI_BUS_NUM(pcie_pmu->bdf_min));
141}
142static DEVICE_ATTR_RO(bus);
143
144static struct hisi_pcie_reg_pair
145hisi_pcie_parse_reg_value(struct hisi_pcie_pmu *pcie_pmu, u32 reg_off)
146{
147 u32 val = readl_relaxed(pcie_pmu->base + reg_off);
148 struct hisi_pcie_reg_pair regs = {
149 .lo = val,
150 .hi = val >> 16,
151 };
152
153 return regs;
154}
155
156/*
157 * Hardware counter and ext_counter work together for bandwidth, latency, bus
158 * utilization and buffer occupancy events. For example, RX memory write latency
159 * events(index = 0x0010), counter counts total delay cycles and ext_counter
160 * counts RX memory write PCIe packets number.
161 *
162 * As we don't want PMU driver to process these two data, "delay cycles" can
163 * be treated as an independent event(index = 0x0010), "RX memory write packets
164 * number" as another(index = 0x10010). BIT 16 is used to distinguish and 0-15
165 * bits are "real" event index, which can be used to set HISI_PCIE_EVENT_CTRL.
166 */
167#define EXT_COUNTER_IS_USED(idx) ((idx) & BIT(16))
168
169static u32 hisi_pcie_get_real_event(struct perf_event *event)
170{
171 return hisi_pcie_get_event(event) & GENMASK(15, 0);
172}
173
174static u32 hisi_pcie_pmu_get_offset(u32 offset, u32 idx)
175{
176 return offset + HISI_PCIE_REG_STEP * idx;
177}
178
179static u32 hisi_pcie_pmu_readl(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset,
180 u32 idx)
181{
182 u32 offset = hisi_pcie_pmu_get_offset(reg_offset, idx);
183
184 return readl_relaxed(pcie_pmu->base + offset);
185}
186
187static void hisi_pcie_pmu_writel(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset, u32 idx, u32 val)
188{
189 u32 offset = hisi_pcie_pmu_get_offset(reg_offset, idx);
190
191 writel_relaxed(val, pcie_pmu->base + offset);
192}
193
194static u64 hisi_pcie_pmu_readq(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset, u32 idx)
195{
196 u32 offset = hisi_pcie_pmu_get_offset(reg_offset, idx);
197
198 return readq_relaxed(pcie_pmu->base + offset);
199}
200
201static void hisi_pcie_pmu_writeq(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset, u32 idx, u64 val)
202{
203 u32 offset = hisi_pcie_pmu_get_offset(reg_offset, idx);
204
205 writeq_relaxed(val, pcie_pmu->base + offset);
206}
207
4d473461 208static u64 hisi_pcie_pmu_get_event_ctrl_val(struct perf_event *event)
8404b0fb 209{
17d57398 210 u64 port, trig_len, thr_len, len_mode;
8404b0fb 211 u64 reg = HISI_PCIE_INIT_SET;
8404b0fb
QL
212
213 /* Config HISI_PCIE_EVENT_CTRL according to event. */
214 reg |= FIELD_PREP(HISI_PCIE_EVENT_M, hisi_pcie_get_real_event(event));
215
216 /* Config HISI_PCIE_EVENT_CTRL according to root port or EP device. */
217 port = hisi_pcie_get_port(event);
218 if (port)
219 reg |= FIELD_PREP(HISI_PCIE_TARGET_M, port);
220 else
221 reg |= HISI_PCIE_TARGET_EN |
222 FIELD_PREP(HISI_PCIE_TARGET_M, hisi_pcie_get_bdf(event));
223
224 /* Config HISI_PCIE_EVENT_CTRL according to trigger condition. */
225 trig_len = hisi_pcie_get_trig_len(event);
226 if (trig_len) {
227 reg |= FIELD_PREP(HISI_PCIE_TRIG_M, trig_len);
228 reg |= FIELD_PREP(HISI_PCIE_TRIG_MODE_M, hisi_pcie_get_trig_mode(event));
229 reg |= HISI_PCIE_TRIG_EN;
230 }
231
232 /* Config HISI_PCIE_EVENT_CTRL according to threshold condition. */
233 thr_len = hisi_pcie_get_thr_len(event);
234 if (thr_len) {
235 reg |= FIELD_PREP(HISI_PCIE_THR_M, thr_len);
236 reg |= FIELD_PREP(HISI_PCIE_THR_MODE_M, hisi_pcie_get_thr_mode(event));
237 reg |= HISI_PCIE_THR_EN;
238 }
239
17d57398
YY
240 len_mode = hisi_pcie_get_len_mode(event);
241 if (len_mode)
242 reg |= FIELD_PREP(HISI_PCIE_LEN_M, len_mode);
243 else
244 reg |= FIELD_PREP(HISI_PCIE_LEN_M, HISI_PCIE_LEN_M_DEFAULT);
245
4d473461
YY
246 return reg;
247}
248
249static void hisi_pcie_pmu_config_event_ctrl(struct perf_event *event)
250{
251 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
252 struct hw_perf_event *hwc = &event->hw;
253 u64 reg = hisi_pcie_pmu_get_event_ctrl_val(event);
254
8404b0fb
QL
255 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, hwc->idx, reg);
256}
257
54a9e47e 258static void hisi_pcie_pmu_clear_event_ctrl(struct perf_event *event)
8404b0fb
QL
259{
260 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
261 struct hw_perf_event *hwc = &event->hw;
262
263 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, hwc->idx, HISI_PCIE_INIT_SET);
264}
265
266static bool hisi_pcie_pmu_valid_requester_id(struct hisi_pcie_pmu *pcie_pmu, u32 bdf)
267{
268 struct pci_dev *root_port, *pdev;
269 u16 rp_bdf;
270
271 pdev = pci_get_domain_bus_and_slot(pci_domain_nr(pcie_pmu->pdev->bus), PCI_BUS_NUM(bdf),
272 GET_PCI_DEVFN(bdf));
273 if (!pdev)
274 return false;
275
276 root_port = pcie_find_root_port(pdev);
277 if (!root_port) {
278 pci_dev_put(pdev);
279 return false;
280 }
281
282 pci_dev_put(pdev);
283 rp_bdf = pci_dev_id(root_port);
284 return rp_bdf >= pcie_pmu->bdf_min && rp_bdf <= pcie_pmu->bdf_max;
285}
286
287static bool hisi_pcie_pmu_valid_filter(struct perf_event *event,
288 struct hisi_pcie_pmu *pcie_pmu)
289{
290 u32 requester_id = hisi_pcie_get_bdf(event);
291
292 if (hisi_pcie_get_thr_len(event) > HISI_PCIE_THR_MAX_VAL)
293 return false;
294
295 if (hisi_pcie_get_trig_len(event) > HISI_PCIE_TRIG_MAX_VAL)
296 return false;
297
2f864fee
JH
298 /* Need to explicitly set filter of "port" or "bdf" */
299 if (!hisi_pcie_get_port(event) &&
300 !hisi_pcie_pmu_valid_requester_id(pcie_pmu, requester_id))
301 return false;
8404b0fb
QL
302
303 return true;
304}
305
b6693ad6
YY
306/*
307 * Check Whether two events share the same config. The same config means not
308 * only the event code, but also the filter settings of the two events are
309 * the same.
310 */
8404b0fb
QL
311static bool hisi_pcie_pmu_cmp_event(struct perf_event *target,
312 struct perf_event *event)
313{
b6693ad6
YY
314 return hisi_pcie_pmu_get_event_ctrl_val(target) ==
315 hisi_pcie_pmu_get_event_ctrl_val(event);
8404b0fb
QL
316}
317
318static bool hisi_pcie_pmu_validate_event_group(struct perf_event *event)
319{
320 struct perf_event *sibling, *leader = event->group_leader;
321 struct perf_event *event_group[HISI_PCIE_MAX_COUNTERS];
322 int counters = 1;
323 int num;
324
325 event_group[0] = leader;
326 if (!is_software_event(leader)) {
327 if (leader->pmu != event->pmu)
328 return false;
329
330 if (leader != event && !hisi_pcie_pmu_cmp_event(leader, event))
331 event_group[counters++] = event;
332 }
333
334 for_each_sibling_event(sibling, event->group_leader) {
335 if (is_software_event(sibling))
336 continue;
337
338 if (sibling->pmu != event->pmu)
339 return false;
340
341 for (num = 0; num < counters; num++) {
342 if (hisi_pcie_pmu_cmp_event(event_group[num], sibling))
343 break;
344 }
345
346 if (num == counters)
347 event_group[counters++] = sibling;
348 }
349
350 return counters <= HISI_PCIE_MAX_COUNTERS;
351}
352
353static int hisi_pcie_pmu_event_init(struct perf_event *event)
354{
355 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
356 struct hw_perf_event *hwc = &event->hw;
357
6d7d51e8
YY
358 /* Check the type first before going on, otherwise it's not our event */
359 if (event->attr.type != event->pmu->type)
360 return -ENOENT;
361
8404b0fb
QL
362 if (EXT_COUNTER_IS_USED(hisi_pcie_get_event(event)))
363 hwc->event_base = HISI_PCIE_EXT_CNT;
364 else
365 hwc->event_base = HISI_PCIE_CNT;
366
8404b0fb
QL
367 /* Sampling is not supported. */
368 if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
369 return -EOPNOTSUPP;
370
371 if (!hisi_pcie_pmu_valid_filter(event, pcie_pmu))
372 return -EINVAL;
373
374 if (!hisi_pcie_pmu_validate_event_group(event))
375 return -EINVAL;
376
868f8a70
YY
377 event->cpu = pcie_pmu->on_cpu;
378
8404b0fb
QL
379 return 0;
380}
381
382static u64 hisi_pcie_pmu_read_counter(struct perf_event *event)
383{
384 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
385 u32 idx = event->hw.idx;
386
387 return hisi_pcie_pmu_readq(pcie_pmu, event->hw.event_base, idx);
388}
389
7da37705
JH
390/*
391 * Check all work events, if a relevant event is found then we return it
392 * first, otherwise return the first idle counter (need to reset).
393 */
394static int hisi_pcie_pmu_get_event_idx(struct hisi_pcie_pmu *pcie_pmu,
395 struct perf_event *event)
8404b0fb 396{
7da37705 397 int first_idle = -EAGAIN;
8404b0fb
QL
398 struct perf_event *sibling;
399 int idx;
400
401 for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
402 sibling = pcie_pmu->hw_events[idx];
7da37705
JH
403 if (!sibling) {
404 if (first_idle == -EAGAIN)
405 first_idle = idx;
8404b0fb 406 continue;
7da37705 407 }
8404b0fb 408
8404b0fb 409 /* Related events must be used in group */
2fbf96ed
JH
410 if (hisi_pcie_pmu_cmp_event(sibling, event) &&
411 sibling->group_leader == event->group_leader)
8404b0fb 412 return idx;
8404b0fb
QL
413 }
414
7da37705 415 return first_idle;
8404b0fb
QL
416}
417
418static void hisi_pcie_pmu_event_update(struct perf_event *event)
419{
420 struct hw_perf_event *hwc = &event->hw;
421 u64 new_cnt, prev_cnt, delta;
422
423 do {
424 prev_cnt = local64_read(&hwc->prev_count);
425 new_cnt = hisi_pcie_pmu_read_counter(event);
426 } while (local64_cmpxchg(&hwc->prev_count, prev_cnt,
427 new_cnt) != prev_cnt);
428
429 delta = (new_cnt - prev_cnt) & HISI_PCIE_MAX_PERIOD;
430 local64_add(delta, &event->count);
431}
432
433static void hisi_pcie_pmu_read(struct perf_event *event)
434{
435 hisi_pcie_pmu_event_update(event);
436}
437
438static void hisi_pcie_pmu_set_period(struct perf_event *event)
439{
440 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
441 struct hw_perf_event *hwc = &event->hw;
442 int idx = hwc->idx;
443
444 local64_set(&hwc->prev_count, HISI_PCIE_INIT_VAL);
445 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_CNT, idx, HISI_PCIE_INIT_VAL);
446 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EXT_CNT, idx, HISI_PCIE_INIT_VAL);
447}
448
449static void hisi_pcie_pmu_enable_counter(struct hisi_pcie_pmu *pcie_pmu, struct hw_perf_event *hwc)
450{
451 u32 idx = hwc->idx;
452 u64 val;
453
454 val = hisi_pcie_pmu_readq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx);
455 val |= HISI_PCIE_EVENT_EN;
456 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx, val);
457}
458
459static void hisi_pcie_pmu_disable_counter(struct hisi_pcie_pmu *pcie_pmu, struct hw_perf_event *hwc)
460{
461 u32 idx = hwc->idx;
462 u64 val;
463
464 val = hisi_pcie_pmu_readq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx);
465 val &= ~HISI_PCIE_EVENT_EN;
466 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx, val);
467}
468
469static void hisi_pcie_pmu_enable_int(struct hisi_pcie_pmu *pcie_pmu, struct hw_perf_event *hwc)
470{
471 u32 idx = hwc->idx;
472
473 hisi_pcie_pmu_writel(pcie_pmu, HISI_PCIE_INT_MASK, idx, 0);
474}
475
476static void hisi_pcie_pmu_disable_int(struct hisi_pcie_pmu *pcie_pmu, struct hw_perf_event *hwc)
477{
478 u32 idx = hwc->idx;
479
480 hisi_pcie_pmu_writel(pcie_pmu, HISI_PCIE_INT_MASK, idx, 1);
481}
482
483static void hisi_pcie_pmu_reset_counter(struct hisi_pcie_pmu *pcie_pmu, int idx)
484{
485 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx, HISI_PCIE_RESET_CNT);
486 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx, HISI_PCIE_INIT_SET);
487}
488
489static void hisi_pcie_pmu_start(struct perf_event *event, int flags)
490{
491 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
492 struct hw_perf_event *hwc = &event->hw;
493 int idx = hwc->idx;
494 u64 prev_cnt;
495
496 if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
497 return;
498
499 WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
500 hwc->state = 0;
501
54a9e47e 502 hisi_pcie_pmu_config_event_ctrl(event);
8404b0fb
QL
503 hisi_pcie_pmu_enable_counter(pcie_pmu, hwc);
504 hisi_pcie_pmu_enable_int(pcie_pmu, hwc);
505 hisi_pcie_pmu_set_period(event);
506
507 if (flags & PERF_EF_RELOAD) {
508 prev_cnt = local64_read(&hwc->prev_count);
509 hisi_pcie_pmu_writeq(pcie_pmu, hwc->event_base, idx, prev_cnt);
510 }
511
512 perf_event_update_userpage(event);
513}
514
515static void hisi_pcie_pmu_stop(struct perf_event *event, int flags)
516{
517 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
518 struct hw_perf_event *hwc = &event->hw;
519
520 hisi_pcie_pmu_event_update(event);
521 hisi_pcie_pmu_disable_int(pcie_pmu, hwc);
522 hisi_pcie_pmu_disable_counter(pcie_pmu, hwc);
54a9e47e 523 hisi_pcie_pmu_clear_event_ctrl(event);
8404b0fb
QL
524 WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
525 hwc->state |= PERF_HES_STOPPED;
526
527 if (hwc->state & PERF_HES_UPTODATE)
528 return;
529
530 hwc->state |= PERF_HES_UPTODATE;
531}
532
533static int hisi_pcie_pmu_add(struct perf_event *event, int flags)
534{
535 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
536 struct hw_perf_event *hwc = &event->hw;
537 int idx;
538
539 hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
540
7da37705 541 idx = hisi_pcie_pmu_get_event_idx(pcie_pmu, event);
8404b0fb
QL
542 if (idx < 0)
543 return idx;
544
545 hwc->idx = idx;
8404b0fb 546
7da37705
JH
547 /* No enabled counter found with related event, reset it */
548 if (!pcie_pmu->hw_events[idx]) {
549 hisi_pcie_pmu_reset_counter(pcie_pmu, idx);
550 pcie_pmu->hw_events[idx] = event;
551 }
552
8404b0fb
QL
553 if (flags & PERF_EF_START)
554 hisi_pcie_pmu_start(event, PERF_EF_RELOAD);
555
556 return 0;
557}
558
559static void hisi_pcie_pmu_del(struct perf_event *event, int flags)
560{
561 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
562 struct hw_perf_event *hwc = &event->hw;
563
564 hisi_pcie_pmu_stop(event, PERF_EF_UPDATE);
565 pcie_pmu->hw_events[hwc->idx] = NULL;
566 perf_event_update_userpage(event);
567}
568
569static void hisi_pcie_pmu_enable(struct pmu *pmu)
570{
571 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(pmu);
572 int num;
573
574 for (num = 0; num < HISI_PCIE_MAX_COUNTERS; num++) {
575 if (pcie_pmu->hw_events[num])
576 break;
577 }
578
579 if (num == HISI_PCIE_MAX_COUNTERS)
580 return;
581
582 writel(HISI_PCIE_GLOBAL_EN, pcie_pmu->base + HISI_PCIE_GLOBAL_CTRL);
583}
584
585static void hisi_pcie_pmu_disable(struct pmu *pmu)
586{
587 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(pmu);
588
589 writel(HISI_PCIE_GLOBAL_NONE, pcie_pmu->base + HISI_PCIE_GLOBAL_CTRL);
590}
591
592static irqreturn_t hisi_pcie_pmu_irq(int irq, void *data)
593{
594 struct hisi_pcie_pmu *pcie_pmu = data;
595 irqreturn_t ret = IRQ_NONE;
596 struct perf_event *event;
597 u32 overflown;
598 int idx;
599
600 for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
601 overflown = hisi_pcie_pmu_readl(pcie_pmu, HISI_PCIE_INT_STAT, idx);
602 if (!overflown)
603 continue;
604
605 /* Clear status of interrupt. */
606 hisi_pcie_pmu_writel(pcie_pmu, HISI_PCIE_INT_STAT, idx, 1);
607 event = pcie_pmu->hw_events[idx];
608 if (!event)
609 continue;
610
611 hisi_pcie_pmu_event_update(event);
612 hisi_pcie_pmu_set_period(event);
613 ret = IRQ_HANDLED;
614 }
615
616 return ret;
617}
618
619static int hisi_pcie_pmu_irq_register(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_pmu)
620{
621 int irq, ret;
622
623 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
624 if (ret < 0) {
625 pci_err(pdev, "Failed to enable MSI vectors: %d\n", ret);
626 return ret;
627 }
628
629 irq = pci_irq_vector(pdev, 0);
630 ret = request_irq(irq, hisi_pcie_pmu_irq, IRQF_NOBALANCING | IRQF_NO_THREAD, DRV_NAME,
631 pcie_pmu);
632 if (ret) {
633 pci_err(pdev, "Failed to register IRQ: %d\n", ret);
634 pci_free_irq_vectors(pdev);
635 return ret;
636 }
637
638 pcie_pmu->irq = irq;
639
640 return 0;
641}
642
643static void hisi_pcie_pmu_irq_unregister(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_pmu)
644{
645 free_irq(pcie_pmu->irq, pcie_pmu);
646 pci_free_irq_vectors(pdev);
647}
648
649static int hisi_pcie_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
650{
651 struct hisi_pcie_pmu *pcie_pmu = hlist_entry_safe(node, struct hisi_pcie_pmu, node);
652
653 if (pcie_pmu->on_cpu == -1) {
83a6d80c
YY
654 pcie_pmu->on_cpu = cpumask_local_spread(0, dev_to_node(&pcie_pmu->pdev->dev));
655 WARN_ON(irq_set_affinity(pcie_pmu->irq, cpumask_of(pcie_pmu->on_cpu)));
8404b0fb
QL
656 }
657
658 return 0;
659}
660
661static int hisi_pcie_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
662{
663 struct hisi_pcie_pmu *pcie_pmu = hlist_entry_safe(node, struct hisi_pcie_pmu, node);
664 unsigned int target;
83a6d80c
YY
665 cpumask_t mask;
666 int numa_node;
8404b0fb
QL
667
668 /* Nothing to do if this CPU doesn't own the PMU */
669 if (pcie_pmu->on_cpu != cpu)
670 return 0;
671
672 pcie_pmu->on_cpu = -1;
83a6d80c
YY
673
674 /* Choose a local CPU from all online cpus. */
675 numa_node = dev_to_node(&pcie_pmu->pdev->dev);
676 if (cpumask_and(&mask, cpumask_of_node(numa_node), cpu_online_mask) &&
677 cpumask_andnot(&mask, &mask, cpumask_of(cpu)))
678 target = cpumask_any(&mask);
679 else
680 target = cpumask_any_but(cpu_online_mask, cpu);
681
8404b0fb
QL
682 if (target >= nr_cpu_ids) {
683 pci_err(pcie_pmu->pdev, "There is no CPU to set\n");
684 return 0;
685 }
686
687 perf_pmu_migrate_context(&pcie_pmu->pmu, cpu, target);
688 /* Use this CPU for event counting */
689 pcie_pmu->on_cpu = target;
690 WARN_ON(irq_set_affinity(pcie_pmu->irq, cpumask_of(target)));
691
692 return 0;
693}
694
695static struct attribute *hisi_pcie_pmu_events_attr[] = {
696 HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_latency, 0x0010),
697 HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_cnt, 0x10010),
698 HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_latency, 0x0210),
699 HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_cnt, 0x10210),
700 HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_latency, 0x0011),
701 HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_cnt, 0x10011),
00ca69b8
YY
702 HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_flux, 0x0104),
703 HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_time, 0x10104),
6b4bb4f3
YY
704 HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_flux, 0x0804),
705 HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_time, 0x10804),
00ca69b8
YY
706 HISI_PCIE_PMU_EVENT_ATTR(rx_cpl_flux, 0x2004),
707 HISI_PCIE_PMU_EVENT_ATTR(rx_cpl_time, 0x12004),
708 HISI_PCIE_PMU_EVENT_ATTR(tx_mwr_flux, 0x0105),
709 HISI_PCIE_PMU_EVENT_ATTR(tx_mwr_time, 0x10105),
6b4bb4f3
YY
710 HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_flux, 0x0405),
711 HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_time, 0x10405),
00ca69b8
YY
712 HISI_PCIE_PMU_EVENT_ATTR(tx_cpl_flux, 0x1005),
713 HISI_PCIE_PMU_EVENT_ATTR(tx_cpl_time, 0x11005),
8404b0fb
QL
714 NULL
715};
716
717static struct attribute_group hisi_pcie_pmu_events_group = {
718 .name = "events",
719 .attrs = hisi_pcie_pmu_events_attr,
720};
721
722static struct attribute *hisi_pcie_pmu_format_attr[] = {
723 HISI_PCIE_PMU_FORMAT_ATTR(event, "config:0-16"),
724 HISI_PCIE_PMU_FORMAT_ATTR(thr_len, "config1:0-3"),
725 HISI_PCIE_PMU_FORMAT_ATTR(thr_mode, "config1:4"),
726 HISI_PCIE_PMU_FORMAT_ATTR(trig_len, "config1:5-8"),
727 HISI_PCIE_PMU_FORMAT_ATTR(trig_mode, "config1:9"),
17d57398 728 HISI_PCIE_PMU_FORMAT_ATTR(len_mode, "config1:10-11"),
8404b0fb
QL
729 HISI_PCIE_PMU_FORMAT_ATTR(port, "config2:0-15"),
730 HISI_PCIE_PMU_FORMAT_ATTR(bdf, "config2:16-31"),
731 NULL
732};
733
734static const struct attribute_group hisi_pcie_pmu_format_group = {
735 .name = "format",
736 .attrs = hisi_pcie_pmu_format_attr,
737};
738
739static struct attribute *hisi_pcie_pmu_bus_attrs[] = {
740 &dev_attr_bus.attr,
741 NULL
742};
743
744static const struct attribute_group hisi_pcie_pmu_bus_attr_group = {
745 .attrs = hisi_pcie_pmu_bus_attrs,
746};
747
748static struct attribute *hisi_pcie_pmu_cpumask_attrs[] = {
749 &dev_attr_cpumask.attr,
750 NULL
751};
752
753static const struct attribute_group hisi_pcie_pmu_cpumask_attr_group = {
754 .attrs = hisi_pcie_pmu_cpumask_attrs,
755};
756
757static struct attribute *hisi_pcie_pmu_identifier_attrs[] = {
758 &dev_attr_identifier.attr,
759 NULL
760};
761
762static const struct attribute_group hisi_pcie_pmu_identifier_attr_group = {
763 .attrs = hisi_pcie_pmu_identifier_attrs,
764};
765
766static const struct attribute_group *hisi_pcie_pmu_attr_groups[] = {
767 &hisi_pcie_pmu_events_group,
768 &hisi_pcie_pmu_format_group,
769 &hisi_pcie_pmu_bus_attr_group,
770 &hisi_pcie_pmu_cpumask_attr_group,
771 &hisi_pcie_pmu_identifier_attr_group,
772 NULL
773};
774
775static int hisi_pcie_alloc_pmu(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_pmu)
776{
777 struct hisi_pcie_reg_pair regs;
778 u16 sicl_id, core_id;
779 char *name;
780
781 regs = hisi_pcie_parse_reg_value(pcie_pmu, HISI_PCIE_REG_BDF);
782 pcie_pmu->bdf_min = regs.lo;
783 pcie_pmu->bdf_max = regs.hi;
784
785 regs = hisi_pcie_parse_reg_value(pcie_pmu, HISI_PCIE_REG_INFO);
786 sicl_id = regs.hi;
787 core_id = regs.lo;
788
789 name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_pcie%u_core%u", sicl_id, core_id);
790 if (!name)
791 return -ENOMEM;
792
793 pcie_pmu->pdev = pdev;
794 pcie_pmu->on_cpu = -1;
795 pcie_pmu->identifier = readl(pcie_pmu->base + HISI_PCIE_REG_VERSION);
796 pcie_pmu->pmu = (struct pmu) {
797 .name = name,
798 .module = THIS_MODULE,
799 .event_init = hisi_pcie_pmu_event_init,
800 .pmu_enable = hisi_pcie_pmu_enable,
801 .pmu_disable = hisi_pcie_pmu_disable,
802 .add = hisi_pcie_pmu_add,
803 .del = hisi_pcie_pmu_del,
804 .start = hisi_pcie_pmu_start,
805 .stop = hisi_pcie_pmu_stop,
806 .read = hisi_pcie_pmu_read,
807 .task_ctx_nr = perf_invalid_context,
808 .attr_groups = hisi_pcie_pmu_attr_groups,
809 .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
810 };
811
812 return 0;
813}
814
815static int hisi_pcie_init_pmu(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_pmu)
816{
817 int ret;
818
819 pcie_pmu->base = pci_ioremap_bar(pdev, 2);
820 if (!pcie_pmu->base) {
821 pci_err(pdev, "Ioremap failed for pcie_pmu resource\n");
822 return -ENOMEM;
823 }
824
825 ret = hisi_pcie_alloc_pmu(pdev, pcie_pmu);
826 if (ret)
827 goto err_iounmap;
828
829 ret = hisi_pcie_pmu_irq_register(pdev, pcie_pmu);
830 if (ret)
831 goto err_iounmap;
832
833 ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE, &pcie_pmu->node);
834 if (ret) {
835 pci_err(pdev, "Failed to register hotplug: %d\n", ret);
836 goto err_irq_unregister;
837 }
838
839 ret = perf_pmu_register(&pcie_pmu->pmu, pcie_pmu->pmu.name, -1);
840 if (ret) {
841 pci_err(pdev, "Failed to register PCIe PMU: %d\n", ret);
842 goto err_hotplug_unregister;
843 }
844
845 return ret;
846
847err_hotplug_unregister:
848 cpuhp_state_remove_instance_nocalls(
849 CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE, &pcie_pmu->node);
850
851err_irq_unregister:
852 hisi_pcie_pmu_irq_unregister(pdev, pcie_pmu);
853
854err_iounmap:
855 iounmap(pcie_pmu->base);
856
857 return ret;
858}
859
860static void hisi_pcie_uninit_pmu(struct pci_dev *pdev)
861{
862 struct hisi_pcie_pmu *pcie_pmu = pci_get_drvdata(pdev);
863
864 perf_pmu_unregister(&pcie_pmu->pmu);
865 cpuhp_state_remove_instance_nocalls(
866 CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE, &pcie_pmu->node);
867 hisi_pcie_pmu_irq_unregister(pdev, pcie_pmu);
868 iounmap(pcie_pmu->base);
869}
870
871static int hisi_pcie_init_dev(struct pci_dev *pdev)
872{
873 int ret;
874
875 ret = pcim_enable_device(pdev);
876 if (ret) {
877 pci_err(pdev, "Failed to enable PCI device: %d\n", ret);
878 return ret;
879 }
880
881 ret = pcim_iomap_regions(pdev, BIT(2), DRV_NAME);
882 if (ret < 0) {
883 pci_err(pdev, "Failed to request PCI mem regions: %d\n", ret);
884 return ret;
885 }
886
887 pci_set_master(pdev);
888
889 return 0;
890}
891
892static int hisi_pcie_pmu_probe(struct pci_dev *pdev, const struct pci_device_id *id)
893{
894 struct hisi_pcie_pmu *pcie_pmu;
895 int ret;
896
897 pcie_pmu = devm_kzalloc(&pdev->dev, sizeof(*pcie_pmu), GFP_KERNEL);
898 if (!pcie_pmu)
899 return -ENOMEM;
900
901 ret = hisi_pcie_init_dev(pdev);
902 if (ret)
903 return ret;
904
905 ret = hisi_pcie_init_pmu(pdev, pcie_pmu);
906 if (ret)
907 return ret;
908
909 pci_set_drvdata(pdev, pcie_pmu);
910
911 return ret;
912}
913
914static void hisi_pcie_pmu_remove(struct pci_dev *pdev)
915{
916 hisi_pcie_uninit_pmu(pdev);
917 pci_set_drvdata(pdev, NULL);
918}
919
920static const struct pci_device_id hisi_pcie_pmu_ids[] = {
921 { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, 0xa12d) },
922 { 0, }
923};
924MODULE_DEVICE_TABLE(pci, hisi_pcie_pmu_ids);
925
926static struct pci_driver hisi_pcie_pmu_driver = {
927 .name = DRV_NAME,
928 .id_table = hisi_pcie_pmu_ids,
929 .probe = hisi_pcie_pmu_probe,
930 .remove = hisi_pcie_pmu_remove,
931};
932
933static int __init hisi_pcie_module_init(void)
934{
935 int ret;
936
937 ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE,
938 "AP_PERF_ARM_HISI_PCIE_PMU_ONLINE",
939 hisi_pcie_pmu_online_cpu,
940 hisi_pcie_pmu_offline_cpu);
941 if (ret) {
942 pr_err("Failed to setup PCIe PMU hotplug: %d\n", ret);
943 return ret;
944 }
945
946 ret = pci_register_driver(&hisi_pcie_pmu_driver);
947 if (ret)
948 cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE);
949
950 return ret;
951}
952module_init(hisi_pcie_module_init);
953
954static void __exit hisi_pcie_module_exit(void)
955{
956 pci_unregister_driver(&hisi_pcie_pmu_driver);
957 cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE);
958}
959module_exit(hisi_pcie_module_exit);
960
961MODULE_DESCRIPTION("HiSilicon PCIe PMU driver");
962MODULE_LICENSE("GPL v2");
963MODULE_AUTHOR("Qi Liu <liuqi115@huawei.com>");