0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/bitfield.h>
0010 #include <linux/bitmap.h>
0011 #include <linux/bug.h>
0012 #include <linux/device.h>
0013 #include <linux/err.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/irq.h>
0016 #include <linux/kernel.h>
0017 #include <linux/list.h>
0018 #include <linux/module.h>
0019 #include <linux/pci.h>
0020 #include <linux/perf_event.h>
0021
0022 #define DRV_NAME "hisi_pcie_pmu"
0023
0024 #define HISI_PCIE_GLOBAL_CTRL 0x00
0025 #define HISI_PCIE_EVENT_CTRL 0x010
0026 #define HISI_PCIE_CNT 0x090
0027 #define HISI_PCIE_EXT_CNT 0x110
0028 #define HISI_PCIE_INT_STAT 0x150
0029 #define HISI_PCIE_INT_MASK 0x154
0030 #define HISI_PCIE_REG_BDF 0xfe0
0031 #define HISI_PCIE_REG_VERSION 0xfe4
0032 #define HISI_PCIE_REG_INFO 0xfe8
0033
0034
0035 #define HISI_PCIE_GLOBAL_EN 0x01
0036 #define HISI_PCIE_GLOBAL_NONE 0
0037
0038
0039 #define HISI_PCIE_EVENT_EN BIT_ULL(20)
0040 #define HISI_PCIE_RESET_CNT BIT_ULL(22)
0041 #define HISI_PCIE_INIT_SET BIT_ULL(34)
0042 #define HISI_PCIE_THR_EN BIT_ULL(26)
0043 #define HISI_PCIE_TARGET_EN BIT_ULL(32)
0044 #define HISI_PCIE_TRIG_EN BIT_ULL(52)
0045
0046
0047 #define HISI_PCIE_EVENT_M GENMASK_ULL(15, 0)
0048 #define HISI_PCIE_THR_MODE_M GENMASK_ULL(27, 27)
0049 #define HISI_PCIE_THR_M GENMASK_ULL(31, 28)
0050 #define HISI_PCIE_TARGET_M GENMASK_ULL(52, 36)
0051 #define HISI_PCIE_TRIG_MODE_M GENMASK_ULL(53, 53)
0052 #define HISI_PCIE_TRIG_M GENMASK_ULL(59, 56)
0053
0054 #define HISI_PCIE_MAX_COUNTERS 8
0055 #define HISI_PCIE_REG_STEP 8
0056 #define HISI_PCIE_THR_MAX_VAL 10
0057 #define HISI_PCIE_TRIG_MAX_VAL 10
0058 #define HISI_PCIE_MAX_PERIOD (GENMASK_ULL(63, 0))
0059 #define HISI_PCIE_INIT_VAL BIT_ULL(63)
0060
0061 struct hisi_pcie_pmu {
0062 struct perf_event *hw_events[HISI_PCIE_MAX_COUNTERS];
0063 struct hlist_node node;
0064 struct pci_dev *pdev;
0065 struct pmu pmu;
0066 void __iomem *base;
0067 int irq;
0068 u32 identifier;
0069
0070 u16 bdf_min;
0071 u16 bdf_max;
0072 int on_cpu;
0073 };
0074
0075 struct hisi_pcie_reg_pair {
0076 u16 lo;
0077 u16 hi;
0078 };
0079
0080 #define to_pcie_pmu(p) (container_of((p), struct hisi_pcie_pmu, pmu))
0081 #define GET_PCI_DEVFN(bdf) ((bdf) & 0xff)
0082
0083 #define HISI_PCIE_PMU_FILTER_ATTR(_name, _config, _hi, _lo) \
0084 static u64 hisi_pcie_get_##_name(struct perf_event *event) \
0085 { \
0086 return FIELD_GET(GENMASK(_hi, _lo), event->attr._config); \
0087 } \
0088
0089 HISI_PCIE_PMU_FILTER_ATTR(event, config, 16, 0);
0090 HISI_PCIE_PMU_FILTER_ATTR(thr_len, config1, 3, 0);
0091 HISI_PCIE_PMU_FILTER_ATTR(thr_mode, config1, 4, 4);
0092 HISI_PCIE_PMU_FILTER_ATTR(trig_len, config1, 8, 5);
0093 HISI_PCIE_PMU_FILTER_ATTR(trig_mode, config1, 9, 9);
0094 HISI_PCIE_PMU_FILTER_ATTR(port, config2, 15, 0);
0095 HISI_PCIE_PMU_FILTER_ATTR(bdf, config2, 31, 16);
0096
0097 static ssize_t hisi_pcie_format_sysfs_show(struct device *dev, struct device_attribute *attr,
0098 char *buf)
0099 {
0100 struct dev_ext_attribute *eattr;
0101
0102 eattr = container_of(attr, struct dev_ext_attribute, attr);
0103
0104 return sysfs_emit(buf, "%s\n", (char *)eattr->var);
0105 }
0106
0107 static ssize_t hisi_pcie_event_sysfs_show(struct device *dev, struct device_attribute *attr,
0108 char *buf)
0109 {
0110 struct perf_pmu_events_attr *pmu_attr =
0111 container_of(attr, struct perf_pmu_events_attr, attr);
0112
0113 return sysfs_emit(buf, "config=0x%llx\n", pmu_attr->id);
0114 }
0115
0116 #define HISI_PCIE_PMU_FORMAT_ATTR(_name, _format) \
0117 (&((struct dev_ext_attribute[]){ \
0118 { .attr = __ATTR(_name, 0444, hisi_pcie_format_sysfs_show, \
0119 NULL), \
0120 .var = (void *)_format } \
0121 })[0].attr.attr)
0122
0123 #define HISI_PCIE_PMU_EVENT_ATTR(_name, _id) \
0124 PMU_EVENT_ATTR_ID(_name, hisi_pcie_event_sysfs_show, _id)
0125
0126 static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr, char *buf)
0127 {
0128 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(dev_get_drvdata(dev));
0129
0130 return cpumap_print_to_pagebuf(true, buf, cpumask_of(pcie_pmu->on_cpu));
0131 }
0132 static DEVICE_ATTR_RO(cpumask);
0133
0134 static ssize_t identifier_show(struct device *dev, struct device_attribute *attr, char *buf)
0135 {
0136 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(dev_get_drvdata(dev));
0137
0138 return sysfs_emit(buf, "%#x\n", pcie_pmu->identifier);
0139 }
0140 static DEVICE_ATTR_RO(identifier);
0141
0142 static ssize_t bus_show(struct device *dev, struct device_attribute *attr, char *buf)
0143 {
0144 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(dev_get_drvdata(dev));
0145
0146 return sysfs_emit(buf, "%#04x\n", PCI_BUS_NUM(pcie_pmu->bdf_min));
0147 }
0148 static DEVICE_ATTR_RO(bus);
0149
0150 static struct hisi_pcie_reg_pair
0151 hisi_pcie_parse_reg_value(struct hisi_pcie_pmu *pcie_pmu, u32 reg_off)
0152 {
0153 u32 val = readl_relaxed(pcie_pmu->base + reg_off);
0154 struct hisi_pcie_reg_pair regs = {
0155 .lo = val,
0156 .hi = val >> 16,
0157 };
0158
0159 return regs;
0160 }
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173 #define EXT_COUNTER_IS_USED(idx) ((idx) & BIT(16))
0174
0175 static u32 hisi_pcie_get_real_event(struct perf_event *event)
0176 {
0177 return hisi_pcie_get_event(event) & GENMASK(15, 0);
0178 }
0179
0180 static u32 hisi_pcie_pmu_get_offset(u32 offset, u32 idx)
0181 {
0182 return offset + HISI_PCIE_REG_STEP * idx;
0183 }
0184
0185 static u32 hisi_pcie_pmu_readl(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset,
0186 u32 idx)
0187 {
0188 u32 offset = hisi_pcie_pmu_get_offset(reg_offset, idx);
0189
0190 return readl_relaxed(pcie_pmu->base + offset);
0191 }
0192
0193 static void hisi_pcie_pmu_writel(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset, u32 idx, u32 val)
0194 {
0195 u32 offset = hisi_pcie_pmu_get_offset(reg_offset, idx);
0196
0197 writel_relaxed(val, pcie_pmu->base + offset);
0198 }
0199
0200 static u64 hisi_pcie_pmu_readq(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset, u32 idx)
0201 {
0202 u32 offset = hisi_pcie_pmu_get_offset(reg_offset, idx);
0203
0204 return readq_relaxed(pcie_pmu->base + offset);
0205 }
0206
0207 static void hisi_pcie_pmu_writeq(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset, u32 idx, u64 val)
0208 {
0209 u32 offset = hisi_pcie_pmu_get_offset(reg_offset, idx);
0210
0211 writeq_relaxed(val, pcie_pmu->base + offset);
0212 }
0213
0214 static void hisi_pcie_pmu_config_filter(struct perf_event *event)
0215 {
0216 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
0217 struct hw_perf_event *hwc = &event->hw;
0218 u64 reg = HISI_PCIE_INIT_SET;
0219 u64 port, trig_len, thr_len;
0220
0221
0222 reg |= FIELD_PREP(HISI_PCIE_EVENT_M, hisi_pcie_get_real_event(event));
0223
0224
0225 port = hisi_pcie_get_port(event);
0226 if (port)
0227 reg |= FIELD_PREP(HISI_PCIE_TARGET_M, port);
0228 else
0229 reg |= HISI_PCIE_TARGET_EN |
0230 FIELD_PREP(HISI_PCIE_TARGET_M, hisi_pcie_get_bdf(event));
0231
0232
0233 trig_len = hisi_pcie_get_trig_len(event);
0234 if (trig_len) {
0235 reg |= FIELD_PREP(HISI_PCIE_TRIG_M, trig_len);
0236 reg |= FIELD_PREP(HISI_PCIE_TRIG_MODE_M, hisi_pcie_get_trig_mode(event));
0237 reg |= HISI_PCIE_TRIG_EN;
0238 }
0239
0240
0241 thr_len = hisi_pcie_get_thr_len(event);
0242 if (thr_len) {
0243 reg |= FIELD_PREP(HISI_PCIE_THR_M, thr_len);
0244 reg |= FIELD_PREP(HISI_PCIE_THR_MODE_M, hisi_pcie_get_thr_mode(event));
0245 reg |= HISI_PCIE_THR_EN;
0246 }
0247
0248 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, hwc->idx, reg);
0249 }
0250
0251 static void hisi_pcie_pmu_clear_filter(struct perf_event *event)
0252 {
0253 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
0254 struct hw_perf_event *hwc = &event->hw;
0255
0256 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, hwc->idx, HISI_PCIE_INIT_SET);
0257 }
0258
0259 static bool hisi_pcie_pmu_valid_requester_id(struct hisi_pcie_pmu *pcie_pmu, u32 bdf)
0260 {
0261 struct pci_dev *root_port, *pdev;
0262 u16 rp_bdf;
0263
0264 pdev = pci_get_domain_bus_and_slot(pci_domain_nr(pcie_pmu->pdev->bus), PCI_BUS_NUM(bdf),
0265 GET_PCI_DEVFN(bdf));
0266 if (!pdev)
0267 return false;
0268
0269 root_port = pcie_find_root_port(pdev);
0270 if (!root_port) {
0271 pci_dev_put(pdev);
0272 return false;
0273 }
0274
0275 pci_dev_put(pdev);
0276 rp_bdf = pci_dev_id(root_port);
0277 return rp_bdf >= pcie_pmu->bdf_min && rp_bdf <= pcie_pmu->bdf_max;
0278 }
0279
0280 static bool hisi_pcie_pmu_valid_filter(struct perf_event *event,
0281 struct hisi_pcie_pmu *pcie_pmu)
0282 {
0283 u32 requester_id = hisi_pcie_get_bdf(event);
0284
0285 if (hisi_pcie_get_thr_len(event) > HISI_PCIE_THR_MAX_VAL)
0286 return false;
0287
0288 if (hisi_pcie_get_trig_len(event) > HISI_PCIE_TRIG_MAX_VAL)
0289 return false;
0290
0291 if (requester_id) {
0292 if (!hisi_pcie_pmu_valid_requester_id(pcie_pmu, requester_id))
0293 return false;
0294 }
0295
0296 return true;
0297 }
0298
0299 static bool hisi_pcie_pmu_cmp_event(struct perf_event *target,
0300 struct perf_event *event)
0301 {
0302 return hisi_pcie_get_real_event(target) == hisi_pcie_get_real_event(event);
0303 }
0304
0305 static bool hisi_pcie_pmu_validate_event_group(struct perf_event *event)
0306 {
0307 struct perf_event *sibling, *leader = event->group_leader;
0308 struct perf_event *event_group[HISI_PCIE_MAX_COUNTERS];
0309 int counters = 1;
0310 int num;
0311
0312 event_group[0] = leader;
0313 if (!is_software_event(leader)) {
0314 if (leader->pmu != event->pmu)
0315 return false;
0316
0317 if (leader != event && !hisi_pcie_pmu_cmp_event(leader, event))
0318 event_group[counters++] = event;
0319 }
0320
0321 for_each_sibling_event(sibling, event->group_leader) {
0322 if (is_software_event(sibling))
0323 continue;
0324
0325 if (sibling->pmu != event->pmu)
0326 return false;
0327
0328 for (num = 0; num < counters; num++) {
0329 if (hisi_pcie_pmu_cmp_event(event_group[num], sibling))
0330 break;
0331 }
0332
0333 if (num == counters)
0334 event_group[counters++] = sibling;
0335 }
0336
0337 return counters <= HISI_PCIE_MAX_COUNTERS;
0338 }
0339
0340 static int hisi_pcie_pmu_event_init(struct perf_event *event)
0341 {
0342 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
0343 struct hw_perf_event *hwc = &event->hw;
0344
0345 event->cpu = pcie_pmu->on_cpu;
0346
0347 if (EXT_COUNTER_IS_USED(hisi_pcie_get_event(event)))
0348 hwc->event_base = HISI_PCIE_EXT_CNT;
0349 else
0350 hwc->event_base = HISI_PCIE_CNT;
0351
0352 if (event->attr.type != event->pmu->type)
0353 return -ENOENT;
0354
0355
0356 if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
0357 return -EOPNOTSUPP;
0358
0359 if (!hisi_pcie_pmu_valid_filter(event, pcie_pmu))
0360 return -EINVAL;
0361
0362 if (!hisi_pcie_pmu_validate_event_group(event))
0363 return -EINVAL;
0364
0365 return 0;
0366 }
0367
0368 static u64 hisi_pcie_pmu_read_counter(struct perf_event *event)
0369 {
0370 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
0371 u32 idx = event->hw.idx;
0372
0373 return hisi_pcie_pmu_readq(pcie_pmu, event->hw.event_base, idx);
0374 }
0375
0376 static int hisi_pcie_pmu_find_related_event(struct hisi_pcie_pmu *pcie_pmu,
0377 struct perf_event *event)
0378 {
0379 struct perf_event *sibling;
0380 int idx;
0381
0382 for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
0383 sibling = pcie_pmu->hw_events[idx];
0384 if (!sibling)
0385 continue;
0386
0387 if (!hisi_pcie_pmu_cmp_event(sibling, event))
0388 continue;
0389
0390
0391 if (sibling->group_leader == event->group_leader)
0392 return idx;
0393 else
0394 return -EINVAL;
0395 }
0396
0397 return idx;
0398 }
0399
0400 static int hisi_pcie_pmu_get_event_idx(struct hisi_pcie_pmu *pcie_pmu)
0401 {
0402 int idx;
0403
0404 for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
0405 if (!pcie_pmu->hw_events[idx])
0406 return idx;
0407 }
0408
0409 return -EINVAL;
0410 }
0411
0412 static void hisi_pcie_pmu_event_update(struct perf_event *event)
0413 {
0414 struct hw_perf_event *hwc = &event->hw;
0415 u64 new_cnt, prev_cnt, delta;
0416
0417 do {
0418 prev_cnt = local64_read(&hwc->prev_count);
0419 new_cnt = hisi_pcie_pmu_read_counter(event);
0420 } while (local64_cmpxchg(&hwc->prev_count, prev_cnt,
0421 new_cnt) != prev_cnt);
0422
0423 delta = (new_cnt - prev_cnt) & HISI_PCIE_MAX_PERIOD;
0424 local64_add(delta, &event->count);
0425 }
0426
0427 static void hisi_pcie_pmu_read(struct perf_event *event)
0428 {
0429 hisi_pcie_pmu_event_update(event);
0430 }
0431
0432 static void hisi_pcie_pmu_set_period(struct perf_event *event)
0433 {
0434 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
0435 struct hw_perf_event *hwc = &event->hw;
0436 int idx = hwc->idx;
0437
0438 local64_set(&hwc->prev_count, HISI_PCIE_INIT_VAL);
0439 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_CNT, idx, HISI_PCIE_INIT_VAL);
0440 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EXT_CNT, idx, HISI_PCIE_INIT_VAL);
0441 }
0442
0443 static void hisi_pcie_pmu_enable_counter(struct hisi_pcie_pmu *pcie_pmu, struct hw_perf_event *hwc)
0444 {
0445 u32 idx = hwc->idx;
0446 u64 val;
0447
0448 val = hisi_pcie_pmu_readq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx);
0449 val |= HISI_PCIE_EVENT_EN;
0450 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx, val);
0451 }
0452
0453 static void hisi_pcie_pmu_disable_counter(struct hisi_pcie_pmu *pcie_pmu, struct hw_perf_event *hwc)
0454 {
0455 u32 idx = hwc->idx;
0456 u64 val;
0457
0458 val = hisi_pcie_pmu_readq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx);
0459 val &= ~HISI_PCIE_EVENT_EN;
0460 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx, val);
0461 }
0462
0463 static void hisi_pcie_pmu_enable_int(struct hisi_pcie_pmu *pcie_pmu, struct hw_perf_event *hwc)
0464 {
0465 u32 idx = hwc->idx;
0466
0467 hisi_pcie_pmu_writel(pcie_pmu, HISI_PCIE_INT_MASK, idx, 0);
0468 }
0469
0470 static void hisi_pcie_pmu_disable_int(struct hisi_pcie_pmu *pcie_pmu, struct hw_perf_event *hwc)
0471 {
0472 u32 idx = hwc->idx;
0473
0474 hisi_pcie_pmu_writel(pcie_pmu, HISI_PCIE_INT_MASK, idx, 1);
0475 }
0476
0477 static void hisi_pcie_pmu_reset_counter(struct hisi_pcie_pmu *pcie_pmu, int idx)
0478 {
0479 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx, HISI_PCIE_RESET_CNT);
0480 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx, HISI_PCIE_INIT_SET);
0481 }
0482
0483 static void hisi_pcie_pmu_start(struct perf_event *event, int flags)
0484 {
0485 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
0486 struct hw_perf_event *hwc = &event->hw;
0487 int idx = hwc->idx;
0488 u64 prev_cnt;
0489
0490 if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
0491 return;
0492
0493 WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
0494 hwc->state = 0;
0495
0496 hisi_pcie_pmu_config_filter(event);
0497 hisi_pcie_pmu_enable_counter(pcie_pmu, hwc);
0498 hisi_pcie_pmu_enable_int(pcie_pmu, hwc);
0499 hisi_pcie_pmu_set_period(event);
0500
0501 if (flags & PERF_EF_RELOAD) {
0502 prev_cnt = local64_read(&hwc->prev_count);
0503 hisi_pcie_pmu_writeq(pcie_pmu, hwc->event_base, idx, prev_cnt);
0504 }
0505
0506 perf_event_update_userpage(event);
0507 }
0508
0509 static void hisi_pcie_pmu_stop(struct perf_event *event, int flags)
0510 {
0511 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
0512 struct hw_perf_event *hwc = &event->hw;
0513
0514 hisi_pcie_pmu_event_update(event);
0515 hisi_pcie_pmu_disable_int(pcie_pmu, hwc);
0516 hisi_pcie_pmu_disable_counter(pcie_pmu, hwc);
0517 hisi_pcie_pmu_clear_filter(event);
0518 WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
0519 hwc->state |= PERF_HES_STOPPED;
0520
0521 if (hwc->state & PERF_HES_UPTODATE)
0522 return;
0523
0524 hwc->state |= PERF_HES_UPTODATE;
0525 }
0526
0527 static int hisi_pcie_pmu_add(struct perf_event *event, int flags)
0528 {
0529 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
0530 struct hw_perf_event *hwc = &event->hw;
0531 int idx;
0532
0533 hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
0534
0535
0536 idx = hisi_pcie_pmu_find_related_event(pcie_pmu, event);
0537 if (idx < 0)
0538 return idx;
0539
0540
0541 if (idx < HISI_PCIE_MAX_COUNTERS) {
0542 hwc->idx = idx;
0543 goto start_count;
0544 }
0545
0546 idx = hisi_pcie_pmu_get_event_idx(pcie_pmu);
0547 if (idx < 0)
0548 return idx;
0549
0550 hwc->idx = idx;
0551 pcie_pmu->hw_events[idx] = event;
0552
0553 hisi_pcie_pmu_reset_counter(pcie_pmu, idx);
0554
0555 start_count:
0556 if (flags & PERF_EF_START)
0557 hisi_pcie_pmu_start(event, PERF_EF_RELOAD);
0558
0559 return 0;
0560 }
0561
0562 static void hisi_pcie_pmu_del(struct perf_event *event, int flags)
0563 {
0564 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
0565 struct hw_perf_event *hwc = &event->hw;
0566
0567 hisi_pcie_pmu_stop(event, PERF_EF_UPDATE);
0568 pcie_pmu->hw_events[hwc->idx] = NULL;
0569 perf_event_update_userpage(event);
0570 }
0571
0572 static void hisi_pcie_pmu_enable(struct pmu *pmu)
0573 {
0574 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(pmu);
0575 int num;
0576
0577 for (num = 0; num < HISI_PCIE_MAX_COUNTERS; num++) {
0578 if (pcie_pmu->hw_events[num])
0579 break;
0580 }
0581
0582 if (num == HISI_PCIE_MAX_COUNTERS)
0583 return;
0584
0585 writel(HISI_PCIE_GLOBAL_EN, pcie_pmu->base + HISI_PCIE_GLOBAL_CTRL);
0586 }
0587
0588 static void hisi_pcie_pmu_disable(struct pmu *pmu)
0589 {
0590 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(pmu);
0591
0592 writel(HISI_PCIE_GLOBAL_NONE, pcie_pmu->base + HISI_PCIE_GLOBAL_CTRL);
0593 }
0594
0595 static irqreturn_t hisi_pcie_pmu_irq(int irq, void *data)
0596 {
0597 struct hisi_pcie_pmu *pcie_pmu = data;
0598 irqreturn_t ret = IRQ_NONE;
0599 struct perf_event *event;
0600 u32 overflown;
0601 int idx;
0602
0603 for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
0604 overflown = hisi_pcie_pmu_readl(pcie_pmu, HISI_PCIE_INT_STAT, idx);
0605 if (!overflown)
0606 continue;
0607
0608
0609 hisi_pcie_pmu_writel(pcie_pmu, HISI_PCIE_INT_STAT, idx, 1);
0610 event = pcie_pmu->hw_events[idx];
0611 if (!event)
0612 continue;
0613
0614 hisi_pcie_pmu_event_update(event);
0615 hisi_pcie_pmu_set_period(event);
0616 ret = IRQ_HANDLED;
0617 }
0618
0619 return ret;
0620 }
0621
0622 static int hisi_pcie_pmu_irq_register(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_pmu)
0623 {
0624 int irq, ret;
0625
0626 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
0627 if (ret < 0) {
0628 pci_err(pdev, "Failed to enable MSI vectors: %d\n", ret);
0629 return ret;
0630 }
0631
0632 irq = pci_irq_vector(pdev, 0);
0633 ret = request_irq(irq, hisi_pcie_pmu_irq, IRQF_NOBALANCING | IRQF_NO_THREAD, DRV_NAME,
0634 pcie_pmu);
0635 if (ret) {
0636 pci_err(pdev, "Failed to register IRQ: %d\n", ret);
0637 pci_free_irq_vectors(pdev);
0638 return ret;
0639 }
0640
0641 pcie_pmu->irq = irq;
0642
0643 return 0;
0644 }
0645
0646 static void hisi_pcie_pmu_irq_unregister(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_pmu)
0647 {
0648 free_irq(pcie_pmu->irq, pcie_pmu);
0649 pci_free_irq_vectors(pdev);
0650 }
0651
0652 static int hisi_pcie_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
0653 {
0654 struct hisi_pcie_pmu *pcie_pmu = hlist_entry_safe(node, struct hisi_pcie_pmu, node);
0655
0656 if (pcie_pmu->on_cpu == -1) {
0657 pcie_pmu->on_cpu = cpu;
0658 WARN_ON(irq_set_affinity(pcie_pmu->irq, cpumask_of(cpu)));
0659 }
0660
0661 return 0;
0662 }
0663
0664 static int hisi_pcie_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
0665 {
0666 struct hisi_pcie_pmu *pcie_pmu = hlist_entry_safe(node, struct hisi_pcie_pmu, node);
0667 unsigned int target;
0668
0669
0670 if (pcie_pmu->on_cpu != cpu)
0671 return 0;
0672
0673 pcie_pmu->on_cpu = -1;
0674
0675 target = cpumask_first(cpu_online_mask);
0676 if (target >= nr_cpu_ids) {
0677 pci_err(pcie_pmu->pdev, "There is no CPU to set\n");
0678 return 0;
0679 }
0680
0681 perf_pmu_migrate_context(&pcie_pmu->pmu, cpu, target);
0682
0683 pcie_pmu->on_cpu = target;
0684 WARN_ON(irq_set_affinity(pcie_pmu->irq, cpumask_of(target)));
0685
0686 return 0;
0687 }
0688
0689 static struct attribute *hisi_pcie_pmu_events_attr[] = {
0690 HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_latency, 0x0010),
0691 HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_cnt, 0x10010),
0692 HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_latency, 0x0210),
0693 HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_cnt, 0x10210),
0694 HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_latency, 0x0011),
0695 HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_cnt, 0x10011),
0696 HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_flux, 0x1005),
0697 HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_time, 0x11005),
0698 HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_flux, 0x2004),
0699 HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_time, 0x12004),
0700 NULL
0701 };
0702
0703 static struct attribute_group hisi_pcie_pmu_events_group = {
0704 .name = "events",
0705 .attrs = hisi_pcie_pmu_events_attr,
0706 };
0707
0708 static struct attribute *hisi_pcie_pmu_format_attr[] = {
0709 HISI_PCIE_PMU_FORMAT_ATTR(event, "config:0-16"),
0710 HISI_PCIE_PMU_FORMAT_ATTR(thr_len, "config1:0-3"),
0711 HISI_PCIE_PMU_FORMAT_ATTR(thr_mode, "config1:4"),
0712 HISI_PCIE_PMU_FORMAT_ATTR(trig_len, "config1:5-8"),
0713 HISI_PCIE_PMU_FORMAT_ATTR(trig_mode, "config1:9"),
0714 HISI_PCIE_PMU_FORMAT_ATTR(port, "config2:0-15"),
0715 HISI_PCIE_PMU_FORMAT_ATTR(bdf, "config2:16-31"),
0716 NULL
0717 };
0718
0719 static const struct attribute_group hisi_pcie_pmu_format_group = {
0720 .name = "format",
0721 .attrs = hisi_pcie_pmu_format_attr,
0722 };
0723
0724 static struct attribute *hisi_pcie_pmu_bus_attrs[] = {
0725 &dev_attr_bus.attr,
0726 NULL
0727 };
0728
0729 static const struct attribute_group hisi_pcie_pmu_bus_attr_group = {
0730 .attrs = hisi_pcie_pmu_bus_attrs,
0731 };
0732
0733 static struct attribute *hisi_pcie_pmu_cpumask_attrs[] = {
0734 &dev_attr_cpumask.attr,
0735 NULL
0736 };
0737
0738 static const struct attribute_group hisi_pcie_pmu_cpumask_attr_group = {
0739 .attrs = hisi_pcie_pmu_cpumask_attrs,
0740 };
0741
0742 static struct attribute *hisi_pcie_pmu_identifier_attrs[] = {
0743 &dev_attr_identifier.attr,
0744 NULL
0745 };
0746
0747 static const struct attribute_group hisi_pcie_pmu_identifier_attr_group = {
0748 .attrs = hisi_pcie_pmu_identifier_attrs,
0749 };
0750
0751 static const struct attribute_group *hisi_pcie_pmu_attr_groups[] = {
0752 &hisi_pcie_pmu_events_group,
0753 &hisi_pcie_pmu_format_group,
0754 &hisi_pcie_pmu_bus_attr_group,
0755 &hisi_pcie_pmu_cpumask_attr_group,
0756 &hisi_pcie_pmu_identifier_attr_group,
0757 NULL
0758 };
0759
0760 static int hisi_pcie_alloc_pmu(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_pmu)
0761 {
0762 struct hisi_pcie_reg_pair regs;
0763 u16 sicl_id, core_id;
0764 char *name;
0765
0766 regs = hisi_pcie_parse_reg_value(pcie_pmu, HISI_PCIE_REG_BDF);
0767 pcie_pmu->bdf_min = regs.lo;
0768 pcie_pmu->bdf_max = regs.hi;
0769
0770 regs = hisi_pcie_parse_reg_value(pcie_pmu, HISI_PCIE_REG_INFO);
0771 sicl_id = regs.hi;
0772 core_id = regs.lo;
0773
0774 name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_pcie%u_core%u", sicl_id, core_id);
0775 if (!name)
0776 return -ENOMEM;
0777
0778 pcie_pmu->pdev = pdev;
0779 pcie_pmu->on_cpu = -1;
0780 pcie_pmu->identifier = readl(pcie_pmu->base + HISI_PCIE_REG_VERSION);
0781 pcie_pmu->pmu = (struct pmu) {
0782 .name = name,
0783 .module = THIS_MODULE,
0784 .event_init = hisi_pcie_pmu_event_init,
0785 .pmu_enable = hisi_pcie_pmu_enable,
0786 .pmu_disable = hisi_pcie_pmu_disable,
0787 .add = hisi_pcie_pmu_add,
0788 .del = hisi_pcie_pmu_del,
0789 .start = hisi_pcie_pmu_start,
0790 .stop = hisi_pcie_pmu_stop,
0791 .read = hisi_pcie_pmu_read,
0792 .task_ctx_nr = perf_invalid_context,
0793 .attr_groups = hisi_pcie_pmu_attr_groups,
0794 .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
0795 };
0796
0797 return 0;
0798 }
0799
0800 static int hisi_pcie_init_pmu(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_pmu)
0801 {
0802 int ret;
0803
0804 pcie_pmu->base = pci_ioremap_bar(pdev, 2);
0805 if (!pcie_pmu->base) {
0806 pci_err(pdev, "Ioremap failed for pcie_pmu resource\n");
0807 return -ENOMEM;
0808 }
0809
0810 ret = hisi_pcie_alloc_pmu(pdev, pcie_pmu);
0811 if (ret)
0812 goto err_iounmap;
0813
0814 ret = hisi_pcie_pmu_irq_register(pdev, pcie_pmu);
0815 if (ret)
0816 goto err_iounmap;
0817
0818 ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE, &pcie_pmu->node);
0819 if (ret) {
0820 pci_err(pdev, "Failed to register hotplug: %d\n", ret);
0821 goto err_irq_unregister;
0822 }
0823
0824 ret = perf_pmu_register(&pcie_pmu->pmu, pcie_pmu->pmu.name, -1);
0825 if (ret) {
0826 pci_err(pdev, "Failed to register PCIe PMU: %d\n", ret);
0827 goto err_hotplug_unregister;
0828 }
0829
0830 return ret;
0831
0832 err_hotplug_unregister:
0833 cpuhp_state_remove_instance_nocalls(
0834 CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE, &pcie_pmu->node);
0835
0836 err_irq_unregister:
0837 hisi_pcie_pmu_irq_unregister(pdev, pcie_pmu);
0838
0839 err_iounmap:
0840 iounmap(pcie_pmu->base);
0841
0842 return ret;
0843 }
0844
0845 static void hisi_pcie_uninit_pmu(struct pci_dev *pdev)
0846 {
0847 struct hisi_pcie_pmu *pcie_pmu = pci_get_drvdata(pdev);
0848
0849 perf_pmu_unregister(&pcie_pmu->pmu);
0850 cpuhp_state_remove_instance_nocalls(
0851 CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE, &pcie_pmu->node);
0852 hisi_pcie_pmu_irq_unregister(pdev, pcie_pmu);
0853 iounmap(pcie_pmu->base);
0854 }
0855
0856 static int hisi_pcie_init_dev(struct pci_dev *pdev)
0857 {
0858 int ret;
0859
0860 ret = pcim_enable_device(pdev);
0861 if (ret) {
0862 pci_err(pdev, "Failed to enable PCI device: %d\n", ret);
0863 return ret;
0864 }
0865
0866 ret = pcim_iomap_regions(pdev, BIT(2), DRV_NAME);
0867 if (ret < 0) {
0868 pci_err(pdev, "Failed to request PCI mem regions: %d\n", ret);
0869 return ret;
0870 }
0871
0872 pci_set_master(pdev);
0873
0874 return 0;
0875 }
0876
0877 static int hisi_pcie_pmu_probe(struct pci_dev *pdev, const struct pci_device_id *id)
0878 {
0879 struct hisi_pcie_pmu *pcie_pmu;
0880 int ret;
0881
0882 pcie_pmu = devm_kzalloc(&pdev->dev, sizeof(*pcie_pmu), GFP_KERNEL);
0883 if (!pcie_pmu)
0884 return -ENOMEM;
0885
0886 ret = hisi_pcie_init_dev(pdev);
0887 if (ret)
0888 return ret;
0889
0890 ret = hisi_pcie_init_pmu(pdev, pcie_pmu);
0891 if (ret)
0892 return ret;
0893
0894 pci_set_drvdata(pdev, pcie_pmu);
0895
0896 return ret;
0897 }
0898
0899 static void hisi_pcie_pmu_remove(struct pci_dev *pdev)
0900 {
0901 hisi_pcie_uninit_pmu(pdev);
0902 pci_set_drvdata(pdev, NULL);
0903 }
0904
0905 static const struct pci_device_id hisi_pcie_pmu_ids[] = {
0906 { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, 0xa12d) },
0907 { 0, }
0908 };
0909 MODULE_DEVICE_TABLE(pci, hisi_pcie_pmu_ids);
0910
0911 static struct pci_driver hisi_pcie_pmu_driver = {
0912 .name = DRV_NAME,
0913 .id_table = hisi_pcie_pmu_ids,
0914 .probe = hisi_pcie_pmu_probe,
0915 .remove = hisi_pcie_pmu_remove,
0916 };
0917
0918 static int __init hisi_pcie_module_init(void)
0919 {
0920 int ret;
0921
0922 ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE,
0923 "AP_PERF_ARM_HISI_PCIE_PMU_ONLINE",
0924 hisi_pcie_pmu_online_cpu,
0925 hisi_pcie_pmu_offline_cpu);
0926 if (ret) {
0927 pr_err("Failed to setup PCIe PMU hotplug: %d\n", ret);
0928 return ret;
0929 }
0930
0931 ret = pci_register_driver(&hisi_pcie_pmu_driver);
0932 if (ret)
0933 cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE);
0934
0935 return ret;
0936 }
0937 module_init(hisi_pcie_module_init);
0938
0939 static void __exit hisi_pcie_module_exit(void)
0940 {
0941 pci_unregister_driver(&hisi_pcie_pmu_driver);
0942 cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE);
0943 }
0944 module_exit(hisi_pcie_module_exit);
0945
0946 MODULE_DESCRIPTION("HiSilicon PCIe PMU driver");
0947 MODULE_LICENSE("GPL v2");
0948 MODULE_AUTHOR("Qi Liu <liuqi115@huawei.com>");