hisi_pcie_pmu.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949
  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 <[email protected]>
  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. #define DRV_NAME "hisi_pcie_pmu"
  22. /* Define registers */
  23. #define HISI_PCIE_GLOBAL_CTRL 0x00
  24. #define HISI_PCIE_EVENT_CTRL 0x010
  25. #define HISI_PCIE_CNT 0x090
  26. #define HISI_PCIE_EXT_CNT 0x110
  27. #define HISI_PCIE_INT_STAT 0x150
  28. #define HISI_PCIE_INT_MASK 0x154
  29. #define HISI_PCIE_REG_BDF 0xfe0
  30. #define HISI_PCIE_REG_VERSION 0xfe4
  31. #define HISI_PCIE_REG_INFO 0xfe8
  32. /* Define command in HISI_PCIE_GLOBAL_CTRL */
  33. #define HISI_PCIE_GLOBAL_EN 0x01
  34. #define HISI_PCIE_GLOBAL_NONE 0
  35. /* Define command in HISI_PCIE_EVENT_CTRL */
  36. #define HISI_PCIE_EVENT_EN BIT_ULL(20)
  37. #define HISI_PCIE_RESET_CNT BIT_ULL(22)
  38. #define HISI_PCIE_INIT_SET BIT_ULL(34)
  39. #define HISI_PCIE_THR_EN BIT_ULL(26)
  40. #define HISI_PCIE_TARGET_EN BIT_ULL(32)
  41. #define HISI_PCIE_TRIG_EN BIT_ULL(52)
  42. /* Define offsets in HISI_PCIE_EVENT_CTRL */
  43. #define HISI_PCIE_EVENT_M GENMASK_ULL(15, 0)
  44. #define HISI_PCIE_THR_MODE_M GENMASK_ULL(27, 27)
  45. #define HISI_PCIE_THR_M GENMASK_ULL(31, 28)
  46. #define HISI_PCIE_TARGET_M GENMASK_ULL(52, 36)
  47. #define HISI_PCIE_TRIG_MODE_M GENMASK_ULL(53, 53)
  48. #define HISI_PCIE_TRIG_M GENMASK_ULL(59, 56)
  49. #define HISI_PCIE_MAX_COUNTERS 8
  50. #define HISI_PCIE_REG_STEP 8
  51. #define HISI_PCIE_THR_MAX_VAL 10
  52. #define HISI_PCIE_TRIG_MAX_VAL 10
  53. #define HISI_PCIE_MAX_PERIOD (GENMASK_ULL(63, 0))
  54. #define HISI_PCIE_INIT_VAL BIT_ULL(63)
  55. struct hisi_pcie_pmu {
  56. struct perf_event *hw_events[HISI_PCIE_MAX_COUNTERS];
  57. struct hlist_node node;
  58. struct pci_dev *pdev;
  59. struct pmu pmu;
  60. void __iomem *base;
  61. int irq;
  62. u32 identifier;
  63. /* Minimum and maximum BDF of root ports monitored by PMU */
  64. u16 bdf_min;
  65. u16 bdf_max;
  66. int on_cpu;
  67. };
  68. struct hisi_pcie_reg_pair {
  69. u16 lo;
  70. u16 hi;
  71. };
  72. #define to_pcie_pmu(p) (container_of((p), struct hisi_pcie_pmu, pmu))
  73. #define GET_PCI_DEVFN(bdf) ((bdf) & 0xff)
  74. #define HISI_PCIE_PMU_FILTER_ATTR(_name, _config, _hi, _lo) \
  75. static u64 hisi_pcie_get_##_name(struct perf_event *event) \
  76. { \
  77. return FIELD_GET(GENMASK(_hi, _lo), event->attr._config); \
  78. } \
  79. HISI_PCIE_PMU_FILTER_ATTR(event, config, 16, 0);
  80. HISI_PCIE_PMU_FILTER_ATTR(thr_len, config1, 3, 0);
  81. HISI_PCIE_PMU_FILTER_ATTR(thr_mode, config1, 4, 4);
  82. HISI_PCIE_PMU_FILTER_ATTR(trig_len, config1, 8, 5);
  83. HISI_PCIE_PMU_FILTER_ATTR(trig_mode, config1, 9, 9);
  84. HISI_PCIE_PMU_FILTER_ATTR(port, config2, 15, 0);
  85. HISI_PCIE_PMU_FILTER_ATTR(bdf, config2, 31, 16);
  86. static ssize_t hisi_pcie_format_sysfs_show(struct device *dev, struct device_attribute *attr,
  87. char *buf)
  88. {
  89. struct dev_ext_attribute *eattr;
  90. eattr = container_of(attr, struct dev_ext_attribute, attr);
  91. return sysfs_emit(buf, "%s\n", (char *)eattr->var);
  92. }
  93. static ssize_t hisi_pcie_event_sysfs_show(struct device *dev, struct device_attribute *attr,
  94. char *buf)
  95. {
  96. struct perf_pmu_events_attr *pmu_attr =
  97. container_of(attr, struct perf_pmu_events_attr, attr);
  98. return sysfs_emit(buf, "config=0x%llx\n", pmu_attr->id);
  99. }
  100. #define HISI_PCIE_PMU_FORMAT_ATTR(_name, _format) \
  101. (&((struct dev_ext_attribute[]){ \
  102. { .attr = __ATTR(_name, 0444, hisi_pcie_format_sysfs_show, \
  103. NULL), \
  104. .var = (void *)_format } \
  105. })[0].attr.attr)
  106. #define HISI_PCIE_PMU_EVENT_ATTR(_name, _id) \
  107. PMU_EVENT_ATTR_ID(_name, hisi_pcie_event_sysfs_show, _id)
  108. static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr, char *buf)
  109. {
  110. struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(dev_get_drvdata(dev));
  111. return cpumap_print_to_pagebuf(true, buf, cpumask_of(pcie_pmu->on_cpu));
  112. }
  113. static DEVICE_ATTR_RO(cpumask);
  114. static ssize_t identifier_show(struct device *dev, struct device_attribute *attr, char *buf)
  115. {
  116. struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(dev_get_drvdata(dev));
  117. return sysfs_emit(buf, "%#x\n", pcie_pmu->identifier);
  118. }
  119. static DEVICE_ATTR_RO(identifier);
  120. static ssize_t bus_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. return sysfs_emit(buf, "%#04x\n", PCI_BUS_NUM(pcie_pmu->bdf_min));
  124. }
  125. static DEVICE_ATTR_RO(bus);
  126. static struct hisi_pcie_reg_pair
  127. hisi_pcie_parse_reg_value(struct hisi_pcie_pmu *pcie_pmu, u32 reg_off)
  128. {
  129. u32 val = readl_relaxed(pcie_pmu->base + reg_off);
  130. struct hisi_pcie_reg_pair regs = {
  131. .lo = val,
  132. .hi = val >> 16,
  133. };
  134. return regs;
  135. }
  136. /*
  137. * Hardware counter and ext_counter work together for bandwidth, latency, bus
  138. * utilization and buffer occupancy events. For example, RX memory write latency
  139. * events(index = 0x0010), counter counts total delay cycles and ext_counter
  140. * counts RX memory write PCIe packets number.
  141. *
  142. * As we don't want PMU driver to process these two data, "delay cycles" can
  143. * be treated as an independent event(index = 0x0010), "RX memory write packets
  144. * number" as another(index = 0x10010). BIT 16 is used to distinguish and 0-15
  145. * bits are "real" event index, which can be used to set HISI_PCIE_EVENT_CTRL.
  146. */
  147. #define EXT_COUNTER_IS_USED(idx) ((idx) & BIT(16))
  148. static u32 hisi_pcie_get_real_event(struct perf_event *event)
  149. {
  150. return hisi_pcie_get_event(event) & GENMASK(15, 0);
  151. }
  152. static u32 hisi_pcie_pmu_get_offset(u32 offset, u32 idx)
  153. {
  154. return offset + HISI_PCIE_REG_STEP * idx;
  155. }
  156. static u32 hisi_pcie_pmu_readl(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset,
  157. u32 idx)
  158. {
  159. u32 offset = hisi_pcie_pmu_get_offset(reg_offset, idx);
  160. return readl_relaxed(pcie_pmu->base + offset);
  161. }
  162. static void hisi_pcie_pmu_writel(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset, u32 idx, u32 val)
  163. {
  164. u32 offset = hisi_pcie_pmu_get_offset(reg_offset, idx);
  165. writel_relaxed(val, pcie_pmu->base + offset);
  166. }
  167. static u64 hisi_pcie_pmu_readq(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset, u32 idx)
  168. {
  169. u32 offset = hisi_pcie_pmu_get_offset(reg_offset, idx);
  170. return readq_relaxed(pcie_pmu->base + offset);
  171. }
  172. static void hisi_pcie_pmu_writeq(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset, u32 idx, u64 val)
  173. {
  174. u32 offset = hisi_pcie_pmu_get_offset(reg_offset, idx);
  175. writeq_relaxed(val, pcie_pmu->base + offset);
  176. }
  177. static void hisi_pcie_pmu_config_filter(struct perf_event *event)
  178. {
  179. struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
  180. struct hw_perf_event *hwc = &event->hw;
  181. u64 reg = HISI_PCIE_INIT_SET;
  182. u64 port, trig_len, thr_len;
  183. /* Config HISI_PCIE_EVENT_CTRL according to event. */
  184. reg |= FIELD_PREP(HISI_PCIE_EVENT_M, hisi_pcie_get_real_event(event));
  185. /* Config HISI_PCIE_EVENT_CTRL according to root port or EP device. */
  186. port = hisi_pcie_get_port(event);
  187. if (port)
  188. reg |= FIELD_PREP(HISI_PCIE_TARGET_M, port);
  189. else
  190. reg |= HISI_PCIE_TARGET_EN |
  191. FIELD_PREP(HISI_PCIE_TARGET_M, hisi_pcie_get_bdf(event));
  192. /* Config HISI_PCIE_EVENT_CTRL according to trigger condition. */
  193. trig_len = hisi_pcie_get_trig_len(event);
  194. if (trig_len) {
  195. reg |= FIELD_PREP(HISI_PCIE_TRIG_M, trig_len);
  196. reg |= FIELD_PREP(HISI_PCIE_TRIG_MODE_M, hisi_pcie_get_trig_mode(event));
  197. reg |= HISI_PCIE_TRIG_EN;
  198. }
  199. /* Config HISI_PCIE_EVENT_CTRL according to threshold condition. */
  200. thr_len = hisi_pcie_get_thr_len(event);
  201. if (thr_len) {
  202. reg |= FIELD_PREP(HISI_PCIE_THR_M, thr_len);
  203. reg |= FIELD_PREP(HISI_PCIE_THR_MODE_M, hisi_pcie_get_thr_mode(event));
  204. reg |= HISI_PCIE_THR_EN;
  205. }
  206. hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, hwc->idx, reg);
  207. }
  208. static void hisi_pcie_pmu_clear_filter(struct perf_event *event)
  209. {
  210. struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
  211. struct hw_perf_event *hwc = &event->hw;
  212. hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, hwc->idx, HISI_PCIE_INIT_SET);
  213. }
  214. static bool hisi_pcie_pmu_valid_requester_id(struct hisi_pcie_pmu *pcie_pmu, u32 bdf)
  215. {
  216. struct pci_dev *root_port, *pdev;
  217. u16 rp_bdf;
  218. pdev = pci_get_domain_bus_and_slot(pci_domain_nr(pcie_pmu->pdev->bus), PCI_BUS_NUM(bdf),
  219. GET_PCI_DEVFN(bdf));
  220. if (!pdev)
  221. return false;
  222. root_port = pcie_find_root_port(pdev);
  223. if (!root_port) {
  224. pci_dev_put(pdev);
  225. return false;
  226. }
  227. pci_dev_put(pdev);
  228. rp_bdf = pci_dev_id(root_port);
  229. return rp_bdf >= pcie_pmu->bdf_min && rp_bdf <= pcie_pmu->bdf_max;
  230. }
  231. static bool hisi_pcie_pmu_valid_filter(struct perf_event *event,
  232. struct hisi_pcie_pmu *pcie_pmu)
  233. {
  234. u32 requester_id = hisi_pcie_get_bdf(event);
  235. if (hisi_pcie_get_thr_len(event) > HISI_PCIE_THR_MAX_VAL)
  236. return false;
  237. if (hisi_pcie_get_trig_len(event) > HISI_PCIE_TRIG_MAX_VAL)
  238. return false;
  239. if (requester_id) {
  240. if (!hisi_pcie_pmu_valid_requester_id(pcie_pmu, requester_id))
  241. return false;
  242. }
  243. return true;
  244. }
  245. static bool hisi_pcie_pmu_cmp_event(struct perf_event *target,
  246. struct perf_event *event)
  247. {
  248. return hisi_pcie_get_real_event(target) == hisi_pcie_get_real_event(event);
  249. }
  250. static bool hisi_pcie_pmu_validate_event_group(struct perf_event *event)
  251. {
  252. struct perf_event *sibling, *leader = event->group_leader;
  253. struct perf_event *event_group[HISI_PCIE_MAX_COUNTERS];
  254. int counters = 1;
  255. int num;
  256. event_group[0] = leader;
  257. if (!is_software_event(leader)) {
  258. if (leader->pmu != event->pmu)
  259. return false;
  260. if (leader != event && !hisi_pcie_pmu_cmp_event(leader, event))
  261. event_group[counters++] = event;
  262. }
  263. for_each_sibling_event(sibling, event->group_leader) {
  264. if (is_software_event(sibling))
  265. continue;
  266. if (sibling->pmu != event->pmu)
  267. return false;
  268. for (num = 0; num < counters; num++) {
  269. if (hisi_pcie_pmu_cmp_event(event_group[num], sibling))
  270. break;
  271. }
  272. if (num == counters)
  273. event_group[counters++] = sibling;
  274. }
  275. return counters <= HISI_PCIE_MAX_COUNTERS;
  276. }
  277. static int hisi_pcie_pmu_event_init(struct perf_event *event)
  278. {
  279. struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
  280. struct hw_perf_event *hwc = &event->hw;
  281. /* Check the type first before going on, otherwise it's not our event */
  282. if (event->attr.type != event->pmu->type)
  283. return -ENOENT;
  284. event->cpu = pcie_pmu->on_cpu;
  285. if (EXT_COUNTER_IS_USED(hisi_pcie_get_event(event)))
  286. hwc->event_base = HISI_PCIE_EXT_CNT;
  287. else
  288. hwc->event_base = HISI_PCIE_CNT;
  289. /* Sampling is not supported. */
  290. if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
  291. return -EOPNOTSUPP;
  292. if (!hisi_pcie_pmu_valid_filter(event, pcie_pmu))
  293. return -EINVAL;
  294. if (!hisi_pcie_pmu_validate_event_group(event))
  295. return -EINVAL;
  296. return 0;
  297. }
  298. static u64 hisi_pcie_pmu_read_counter(struct perf_event *event)
  299. {
  300. struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
  301. u32 idx = event->hw.idx;
  302. return hisi_pcie_pmu_readq(pcie_pmu, event->hw.event_base, idx);
  303. }
  304. static int hisi_pcie_pmu_find_related_event(struct hisi_pcie_pmu *pcie_pmu,
  305. struct perf_event *event)
  306. {
  307. struct perf_event *sibling;
  308. int idx;
  309. for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
  310. sibling = pcie_pmu->hw_events[idx];
  311. if (!sibling)
  312. continue;
  313. if (!hisi_pcie_pmu_cmp_event(sibling, event))
  314. continue;
  315. /* Related events must be used in group */
  316. if (sibling->group_leader == event->group_leader)
  317. return idx;
  318. else
  319. return -EINVAL;
  320. }
  321. return idx;
  322. }
  323. static int hisi_pcie_pmu_get_event_idx(struct hisi_pcie_pmu *pcie_pmu)
  324. {
  325. int idx;
  326. for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
  327. if (!pcie_pmu->hw_events[idx])
  328. return idx;
  329. }
  330. return -EINVAL;
  331. }
  332. static void hisi_pcie_pmu_event_update(struct perf_event *event)
  333. {
  334. struct hw_perf_event *hwc = &event->hw;
  335. u64 new_cnt, prev_cnt, delta;
  336. do {
  337. prev_cnt = local64_read(&hwc->prev_count);
  338. new_cnt = hisi_pcie_pmu_read_counter(event);
  339. } while (local64_cmpxchg(&hwc->prev_count, prev_cnt,
  340. new_cnt) != prev_cnt);
  341. delta = (new_cnt - prev_cnt) & HISI_PCIE_MAX_PERIOD;
  342. local64_add(delta, &event->count);
  343. }
  344. static void hisi_pcie_pmu_read(struct perf_event *event)
  345. {
  346. hisi_pcie_pmu_event_update(event);
  347. }
  348. static void hisi_pcie_pmu_set_period(struct perf_event *event)
  349. {
  350. struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
  351. struct hw_perf_event *hwc = &event->hw;
  352. int idx = hwc->idx;
  353. local64_set(&hwc->prev_count, HISI_PCIE_INIT_VAL);
  354. hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_CNT, idx, HISI_PCIE_INIT_VAL);
  355. hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EXT_CNT, idx, HISI_PCIE_INIT_VAL);
  356. }
  357. static void hisi_pcie_pmu_enable_counter(struct hisi_pcie_pmu *pcie_pmu, struct hw_perf_event *hwc)
  358. {
  359. u32 idx = hwc->idx;
  360. u64 val;
  361. val = hisi_pcie_pmu_readq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx);
  362. val |= HISI_PCIE_EVENT_EN;
  363. hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx, val);
  364. }
  365. static void hisi_pcie_pmu_disable_counter(struct hisi_pcie_pmu *pcie_pmu, struct hw_perf_event *hwc)
  366. {
  367. u32 idx = hwc->idx;
  368. u64 val;
  369. val = hisi_pcie_pmu_readq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx);
  370. val &= ~HISI_PCIE_EVENT_EN;
  371. hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx, val);
  372. }
  373. static void hisi_pcie_pmu_enable_int(struct hisi_pcie_pmu *pcie_pmu, struct hw_perf_event *hwc)
  374. {
  375. u32 idx = hwc->idx;
  376. hisi_pcie_pmu_writel(pcie_pmu, HISI_PCIE_INT_MASK, idx, 0);
  377. }
  378. static void hisi_pcie_pmu_disable_int(struct hisi_pcie_pmu *pcie_pmu, struct hw_perf_event *hwc)
  379. {
  380. u32 idx = hwc->idx;
  381. hisi_pcie_pmu_writel(pcie_pmu, HISI_PCIE_INT_MASK, idx, 1);
  382. }
  383. static void hisi_pcie_pmu_reset_counter(struct hisi_pcie_pmu *pcie_pmu, int idx)
  384. {
  385. hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx, HISI_PCIE_RESET_CNT);
  386. hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx, HISI_PCIE_INIT_SET);
  387. }
  388. static void hisi_pcie_pmu_start(struct perf_event *event, int flags)
  389. {
  390. struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
  391. struct hw_perf_event *hwc = &event->hw;
  392. int idx = hwc->idx;
  393. u64 prev_cnt;
  394. if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
  395. return;
  396. WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
  397. hwc->state = 0;
  398. hisi_pcie_pmu_config_filter(event);
  399. hisi_pcie_pmu_enable_counter(pcie_pmu, hwc);
  400. hisi_pcie_pmu_enable_int(pcie_pmu, hwc);
  401. hisi_pcie_pmu_set_period(event);
  402. if (flags & PERF_EF_RELOAD) {
  403. prev_cnt = local64_read(&hwc->prev_count);
  404. hisi_pcie_pmu_writeq(pcie_pmu, hwc->event_base, idx, prev_cnt);
  405. }
  406. perf_event_update_userpage(event);
  407. }
  408. static void hisi_pcie_pmu_stop(struct perf_event *event, int flags)
  409. {
  410. struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
  411. struct hw_perf_event *hwc = &event->hw;
  412. hisi_pcie_pmu_event_update(event);
  413. hisi_pcie_pmu_disable_int(pcie_pmu, hwc);
  414. hisi_pcie_pmu_disable_counter(pcie_pmu, hwc);
  415. hisi_pcie_pmu_clear_filter(event);
  416. WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
  417. hwc->state |= PERF_HES_STOPPED;
  418. if (hwc->state & PERF_HES_UPTODATE)
  419. return;
  420. hwc->state |= PERF_HES_UPTODATE;
  421. }
  422. static int hisi_pcie_pmu_add(struct perf_event *event, int flags)
  423. {
  424. struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
  425. struct hw_perf_event *hwc = &event->hw;
  426. int idx;
  427. hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
  428. /* Check all working events to find a related event. */
  429. idx = hisi_pcie_pmu_find_related_event(pcie_pmu, event);
  430. if (idx < 0)
  431. return idx;
  432. /* Current event shares an enabled counter with the related event */
  433. if (idx < HISI_PCIE_MAX_COUNTERS) {
  434. hwc->idx = idx;
  435. goto start_count;
  436. }
  437. idx = hisi_pcie_pmu_get_event_idx(pcie_pmu);
  438. if (idx < 0)
  439. return idx;
  440. hwc->idx = idx;
  441. pcie_pmu->hw_events[idx] = event;
  442. /* Reset Counter to avoid previous statistic interference. */
  443. hisi_pcie_pmu_reset_counter(pcie_pmu, idx);
  444. start_count:
  445. if (flags & PERF_EF_START)
  446. hisi_pcie_pmu_start(event, PERF_EF_RELOAD);
  447. return 0;
  448. }
  449. static void hisi_pcie_pmu_del(struct perf_event *event, int flags)
  450. {
  451. struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
  452. struct hw_perf_event *hwc = &event->hw;
  453. hisi_pcie_pmu_stop(event, PERF_EF_UPDATE);
  454. pcie_pmu->hw_events[hwc->idx] = NULL;
  455. perf_event_update_userpage(event);
  456. }
  457. static void hisi_pcie_pmu_enable(struct pmu *pmu)
  458. {
  459. struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(pmu);
  460. int num;
  461. for (num = 0; num < HISI_PCIE_MAX_COUNTERS; num++) {
  462. if (pcie_pmu->hw_events[num])
  463. break;
  464. }
  465. if (num == HISI_PCIE_MAX_COUNTERS)
  466. return;
  467. writel(HISI_PCIE_GLOBAL_EN, pcie_pmu->base + HISI_PCIE_GLOBAL_CTRL);
  468. }
  469. static void hisi_pcie_pmu_disable(struct pmu *pmu)
  470. {
  471. struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(pmu);
  472. writel(HISI_PCIE_GLOBAL_NONE, pcie_pmu->base + HISI_PCIE_GLOBAL_CTRL);
  473. }
  474. static irqreturn_t hisi_pcie_pmu_irq(int irq, void *data)
  475. {
  476. struct hisi_pcie_pmu *pcie_pmu = data;
  477. irqreturn_t ret = IRQ_NONE;
  478. struct perf_event *event;
  479. u32 overflown;
  480. int idx;
  481. for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
  482. overflown = hisi_pcie_pmu_readl(pcie_pmu, HISI_PCIE_INT_STAT, idx);
  483. if (!overflown)
  484. continue;
  485. /* Clear status of interrupt. */
  486. hisi_pcie_pmu_writel(pcie_pmu, HISI_PCIE_INT_STAT, idx, 1);
  487. event = pcie_pmu->hw_events[idx];
  488. if (!event)
  489. continue;
  490. hisi_pcie_pmu_event_update(event);
  491. hisi_pcie_pmu_set_period(event);
  492. ret = IRQ_HANDLED;
  493. }
  494. return ret;
  495. }
  496. static int hisi_pcie_pmu_irq_register(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_pmu)
  497. {
  498. int irq, ret;
  499. ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
  500. if (ret < 0) {
  501. pci_err(pdev, "Failed to enable MSI vectors: %d\n", ret);
  502. return ret;
  503. }
  504. irq = pci_irq_vector(pdev, 0);
  505. ret = request_irq(irq, hisi_pcie_pmu_irq, IRQF_NOBALANCING | IRQF_NO_THREAD, DRV_NAME,
  506. pcie_pmu);
  507. if (ret) {
  508. pci_err(pdev, "Failed to register IRQ: %d\n", ret);
  509. pci_free_irq_vectors(pdev);
  510. return ret;
  511. }
  512. pcie_pmu->irq = irq;
  513. return 0;
  514. }
  515. static void hisi_pcie_pmu_irq_unregister(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_pmu)
  516. {
  517. free_irq(pcie_pmu->irq, pcie_pmu);
  518. pci_free_irq_vectors(pdev);
  519. }
  520. static int hisi_pcie_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
  521. {
  522. struct hisi_pcie_pmu *pcie_pmu = hlist_entry_safe(node, struct hisi_pcie_pmu, node);
  523. if (pcie_pmu->on_cpu == -1) {
  524. pcie_pmu->on_cpu = cpu;
  525. WARN_ON(irq_set_affinity(pcie_pmu->irq, cpumask_of(cpu)));
  526. }
  527. return 0;
  528. }
  529. static int hisi_pcie_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
  530. {
  531. struct hisi_pcie_pmu *pcie_pmu = hlist_entry_safe(node, struct hisi_pcie_pmu, node);
  532. unsigned int target;
  533. /* Nothing to do if this CPU doesn't own the PMU */
  534. if (pcie_pmu->on_cpu != cpu)
  535. return 0;
  536. pcie_pmu->on_cpu = -1;
  537. /* Choose a new CPU from all online cpus. */
  538. target = cpumask_any_but(cpu_online_mask, cpu);
  539. if (target >= nr_cpu_ids) {
  540. pci_err(pcie_pmu->pdev, "There is no CPU to set\n");
  541. return 0;
  542. }
  543. perf_pmu_migrate_context(&pcie_pmu->pmu, cpu, target);
  544. /* Use this CPU for event counting */
  545. pcie_pmu->on_cpu = target;
  546. WARN_ON(irq_set_affinity(pcie_pmu->irq, cpumask_of(target)));
  547. return 0;
  548. }
  549. static struct attribute *hisi_pcie_pmu_events_attr[] = {
  550. HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_latency, 0x0010),
  551. HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_cnt, 0x10010),
  552. HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_latency, 0x0210),
  553. HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_cnt, 0x10210),
  554. HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_latency, 0x0011),
  555. HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_cnt, 0x10011),
  556. HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_flux, 0x0804),
  557. HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_time, 0x10804),
  558. HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_flux, 0x0405),
  559. HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_time, 0x10405),
  560. NULL
  561. };
  562. static struct attribute_group hisi_pcie_pmu_events_group = {
  563. .name = "events",
  564. .attrs = hisi_pcie_pmu_events_attr,
  565. };
  566. static struct attribute *hisi_pcie_pmu_format_attr[] = {
  567. HISI_PCIE_PMU_FORMAT_ATTR(event, "config:0-16"),
  568. HISI_PCIE_PMU_FORMAT_ATTR(thr_len, "config1:0-3"),
  569. HISI_PCIE_PMU_FORMAT_ATTR(thr_mode, "config1:4"),
  570. HISI_PCIE_PMU_FORMAT_ATTR(trig_len, "config1:5-8"),
  571. HISI_PCIE_PMU_FORMAT_ATTR(trig_mode, "config1:9"),
  572. HISI_PCIE_PMU_FORMAT_ATTR(port, "config2:0-15"),
  573. HISI_PCIE_PMU_FORMAT_ATTR(bdf, "config2:16-31"),
  574. NULL
  575. };
  576. static const struct attribute_group hisi_pcie_pmu_format_group = {
  577. .name = "format",
  578. .attrs = hisi_pcie_pmu_format_attr,
  579. };
  580. static struct attribute *hisi_pcie_pmu_bus_attrs[] = {
  581. &dev_attr_bus.attr,
  582. NULL
  583. };
  584. static const struct attribute_group hisi_pcie_pmu_bus_attr_group = {
  585. .attrs = hisi_pcie_pmu_bus_attrs,
  586. };
  587. static struct attribute *hisi_pcie_pmu_cpumask_attrs[] = {
  588. &dev_attr_cpumask.attr,
  589. NULL
  590. };
  591. static const struct attribute_group hisi_pcie_pmu_cpumask_attr_group = {
  592. .attrs = hisi_pcie_pmu_cpumask_attrs,
  593. };
  594. static struct attribute *hisi_pcie_pmu_identifier_attrs[] = {
  595. &dev_attr_identifier.attr,
  596. NULL
  597. };
  598. static const struct attribute_group hisi_pcie_pmu_identifier_attr_group = {
  599. .attrs = hisi_pcie_pmu_identifier_attrs,
  600. };
  601. static const struct attribute_group *hisi_pcie_pmu_attr_groups[] = {
  602. &hisi_pcie_pmu_events_group,
  603. &hisi_pcie_pmu_format_group,
  604. &hisi_pcie_pmu_bus_attr_group,
  605. &hisi_pcie_pmu_cpumask_attr_group,
  606. &hisi_pcie_pmu_identifier_attr_group,
  607. NULL
  608. };
  609. static int hisi_pcie_alloc_pmu(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_pmu)
  610. {
  611. struct hisi_pcie_reg_pair regs;
  612. u16 sicl_id, core_id;
  613. char *name;
  614. regs = hisi_pcie_parse_reg_value(pcie_pmu, HISI_PCIE_REG_BDF);
  615. pcie_pmu->bdf_min = regs.lo;
  616. pcie_pmu->bdf_max = regs.hi;
  617. regs = hisi_pcie_parse_reg_value(pcie_pmu, HISI_PCIE_REG_INFO);
  618. sicl_id = regs.hi;
  619. core_id = regs.lo;
  620. name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_pcie%u_core%u", sicl_id, core_id);
  621. if (!name)
  622. return -ENOMEM;
  623. pcie_pmu->pdev = pdev;
  624. pcie_pmu->on_cpu = -1;
  625. pcie_pmu->identifier = readl(pcie_pmu->base + HISI_PCIE_REG_VERSION);
  626. pcie_pmu->pmu = (struct pmu) {
  627. .name = name,
  628. .module = THIS_MODULE,
  629. .event_init = hisi_pcie_pmu_event_init,
  630. .pmu_enable = hisi_pcie_pmu_enable,
  631. .pmu_disable = hisi_pcie_pmu_disable,
  632. .add = hisi_pcie_pmu_add,
  633. .del = hisi_pcie_pmu_del,
  634. .start = hisi_pcie_pmu_start,
  635. .stop = hisi_pcie_pmu_stop,
  636. .read = hisi_pcie_pmu_read,
  637. .task_ctx_nr = perf_invalid_context,
  638. .attr_groups = hisi_pcie_pmu_attr_groups,
  639. .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
  640. };
  641. return 0;
  642. }
  643. static int hisi_pcie_init_pmu(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_pmu)
  644. {
  645. int ret;
  646. pcie_pmu->base = pci_ioremap_bar(pdev, 2);
  647. if (!pcie_pmu->base) {
  648. pci_err(pdev, "Ioremap failed for pcie_pmu resource\n");
  649. return -ENOMEM;
  650. }
  651. ret = hisi_pcie_alloc_pmu(pdev, pcie_pmu);
  652. if (ret)
  653. goto err_iounmap;
  654. ret = hisi_pcie_pmu_irq_register(pdev, pcie_pmu);
  655. if (ret)
  656. goto err_iounmap;
  657. ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE, &pcie_pmu->node);
  658. if (ret) {
  659. pci_err(pdev, "Failed to register hotplug: %d\n", ret);
  660. goto err_irq_unregister;
  661. }
  662. ret = perf_pmu_register(&pcie_pmu->pmu, pcie_pmu->pmu.name, -1);
  663. if (ret) {
  664. pci_err(pdev, "Failed to register PCIe PMU: %d\n", ret);
  665. goto err_hotplug_unregister;
  666. }
  667. return ret;
  668. err_hotplug_unregister:
  669. cpuhp_state_remove_instance_nocalls(
  670. CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE, &pcie_pmu->node);
  671. err_irq_unregister:
  672. hisi_pcie_pmu_irq_unregister(pdev, pcie_pmu);
  673. err_iounmap:
  674. iounmap(pcie_pmu->base);
  675. return ret;
  676. }
  677. static void hisi_pcie_uninit_pmu(struct pci_dev *pdev)
  678. {
  679. struct hisi_pcie_pmu *pcie_pmu = pci_get_drvdata(pdev);
  680. perf_pmu_unregister(&pcie_pmu->pmu);
  681. cpuhp_state_remove_instance_nocalls(
  682. CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE, &pcie_pmu->node);
  683. hisi_pcie_pmu_irq_unregister(pdev, pcie_pmu);
  684. iounmap(pcie_pmu->base);
  685. }
  686. static int hisi_pcie_init_dev(struct pci_dev *pdev)
  687. {
  688. int ret;
  689. ret = pcim_enable_device(pdev);
  690. if (ret) {
  691. pci_err(pdev, "Failed to enable PCI device: %d\n", ret);
  692. return ret;
  693. }
  694. ret = pcim_iomap_regions(pdev, BIT(2), DRV_NAME);
  695. if (ret < 0) {
  696. pci_err(pdev, "Failed to request PCI mem regions: %d\n", ret);
  697. return ret;
  698. }
  699. pci_set_master(pdev);
  700. return 0;
  701. }
  702. static int hisi_pcie_pmu_probe(struct pci_dev *pdev, const struct pci_device_id *id)
  703. {
  704. struct hisi_pcie_pmu *pcie_pmu;
  705. int ret;
  706. pcie_pmu = devm_kzalloc(&pdev->dev, sizeof(*pcie_pmu), GFP_KERNEL);
  707. if (!pcie_pmu)
  708. return -ENOMEM;
  709. ret = hisi_pcie_init_dev(pdev);
  710. if (ret)
  711. return ret;
  712. ret = hisi_pcie_init_pmu(pdev, pcie_pmu);
  713. if (ret)
  714. return ret;
  715. pci_set_drvdata(pdev, pcie_pmu);
  716. return ret;
  717. }
  718. static void hisi_pcie_pmu_remove(struct pci_dev *pdev)
  719. {
  720. hisi_pcie_uninit_pmu(pdev);
  721. pci_set_drvdata(pdev, NULL);
  722. }
  723. static const struct pci_device_id hisi_pcie_pmu_ids[] = {
  724. { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, 0xa12d) },
  725. { 0, }
  726. };
  727. MODULE_DEVICE_TABLE(pci, hisi_pcie_pmu_ids);
  728. static struct pci_driver hisi_pcie_pmu_driver = {
  729. .name = DRV_NAME,
  730. .id_table = hisi_pcie_pmu_ids,
  731. .probe = hisi_pcie_pmu_probe,
  732. .remove = hisi_pcie_pmu_remove,
  733. };
  734. static int __init hisi_pcie_module_init(void)
  735. {
  736. int ret;
  737. ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE,
  738. "AP_PERF_ARM_HISI_PCIE_PMU_ONLINE",
  739. hisi_pcie_pmu_online_cpu,
  740. hisi_pcie_pmu_offline_cpu);
  741. if (ret) {
  742. pr_err("Failed to setup PCIe PMU hotplug: %d\n", ret);
  743. return ret;
  744. }
  745. ret = pci_register_driver(&hisi_pcie_pmu_driver);
  746. if (ret)
  747. cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE);
  748. return ret;
  749. }
  750. module_init(hisi_pcie_module_init);
  751. static void __exit hisi_pcie_module_exit(void)
  752. {
  753. pci_unregister_driver(&hisi_pcie_pmu_driver);
  754. cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE);
  755. }
  756. module_exit(hisi_pcie_module_exit);
  757. MODULE_DESCRIPTION("HiSilicon PCIe PMU driver");
  758. MODULE_LICENSE("GPL v2");
  759. MODULE_AUTHOR("Qi Liu <[email protected]>");