hisi_ptt.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Driver for HiSilicon PCIe tune and trace device
  4. *
  5. * Copyright (c) 2022 HiSilicon Technologies Co., Ltd.
  6. * Author: Yicong Yang <yangyicong@hisilicon.com>
  7. */
  8. #ifndef _HISI_PTT_H
  9. #define _HISI_PTT_H
  10. #include <linux/bits.h>
  11. #include <linux/cpumask.h>
  12. #include <linux/device.h>
  13. #include <linux/kfifo.h>
  14. #include <linux/list.h>
  15. #include <linux/mutex.h>
  16. #include <linux/notifier.h>
  17. #include <linux/pci.h>
  18. #include <linux/perf_event.h>
  19. #include <linux/spinlock.h>
  20. #include <linux/types.h>
  21. #include <linux/workqueue.h>
  22. #define DRV_NAME "hisi_ptt"
  23. /*
  24. * The definition of the device registers and register fields.
  25. */
  26. #define HISI_PTT_TUNING_CTRL 0x0000
  27. #define HISI_PTT_TUNING_CTRL_CODE GENMASK(15, 0)
  28. #define HISI_PTT_TUNING_CTRL_SUB GENMASK(23, 16)
  29. #define HISI_PTT_TUNING_DATA 0x0004
  30. #define HISI_PTT_TUNING_DATA_VAL_MASK GENMASK(15, 0)
  31. #define HISI_PTT_TRACE_ADDR_SIZE 0x0800
  32. #define HISI_PTT_TRACE_ADDR_BASE_LO_0 0x0810
  33. #define HISI_PTT_TRACE_ADDR_BASE_HI_0 0x0814
  34. #define HISI_PTT_TRACE_ADDR_STRIDE 0x8
  35. #define HISI_PTT_TRACE_CTRL 0x0850
  36. #define HISI_PTT_TRACE_CTRL_EN BIT(0)
  37. #define HISI_PTT_TRACE_CTRL_RST BIT(1)
  38. #define HISI_PTT_TRACE_CTRL_RXTX_SEL GENMASK(3, 2)
  39. #define HISI_PTT_TRACE_CTRL_TYPE_SEL GENMASK(7, 4)
  40. #define HISI_PTT_TRACE_CTRL_DATA_FORMAT BIT(14)
  41. #define HISI_PTT_TRACE_CTRL_FILTER_MODE BIT(15)
  42. #define HISI_PTT_TRACE_CTRL_TARGET_SEL GENMASK(31, 16)
  43. #define HISI_PTT_TRACE_INT_STAT 0x0890
  44. #define HISI_PTT_TRACE_INT_STAT_MASK GENMASK(3, 0)
  45. #define HISI_PTT_TRACE_INT_MASK 0x0894
  46. #define HISI_PTT_TRACE_INT_MASK_ALL GENMASK(3, 0)
  47. #define HISI_PTT_TUNING_INT_STAT 0x0898
  48. #define HISI_PTT_TUNING_INT_STAT_MASK BIT(0)
  49. #define HISI_PTT_TRACE_WR_STS 0x08a0
  50. #define HISI_PTT_TRACE_WR_STS_WRITE GENMASK(27, 0)
  51. #define HISI_PTT_TRACE_WR_STS_BUFFER GENMASK(29, 28)
  52. #define HISI_PTT_TRACE_STS 0x08b0
  53. #define HISI_PTT_TRACE_IDLE BIT(0)
  54. #define HISI_PTT_DEVICE_RANGE 0x0fe0
  55. #define HISI_PTT_DEVICE_RANGE_UPPER GENMASK(31, 16)
  56. #define HISI_PTT_DEVICE_RANGE_LOWER GENMASK(15, 0)
  57. #define HISI_PTT_LOCATION 0x0fe8
  58. #define HISI_PTT_CORE_ID GENMASK(15, 0)
  59. #define HISI_PTT_SICL_ID GENMASK(31, 16)
  60. /* Parameters of PTT trace DMA part. */
  61. #define HISI_PTT_TRACE_DMA_IRQ 0
  62. #define HISI_PTT_TRACE_BUF_CNT 4
  63. #define HISI_PTT_TRACE_BUF_SIZE SZ_4M
  64. #define HISI_PTT_TRACE_TOTAL_BUF_SIZE (HISI_PTT_TRACE_BUF_SIZE * \
  65. HISI_PTT_TRACE_BUF_CNT)
  66. /* Wait time for hardware DMA to reset */
  67. #define HISI_PTT_RESET_TIMEOUT_US 10UL
  68. #define HISI_PTT_RESET_POLL_INTERVAL_US 1UL
  69. /* Poll timeout and interval for waiting hardware work to finish */
  70. #define HISI_PTT_WAIT_TUNE_TIMEOUT_US 1000000UL
  71. #define HISI_PTT_WAIT_TRACE_TIMEOUT_US 100UL
  72. #define HISI_PTT_WAIT_POLL_INTERVAL_US 10UL
  73. /* FIFO size for dynamically updating the PTT trace filter list. */
  74. #define HISI_PTT_FILTER_UPDATE_FIFO_SIZE 16
  75. /* Delay time for filter updating work */
  76. #define HISI_PTT_WORK_DELAY_MS 100UL
  77. #define HISI_PCIE_CORE_PORT_ID(devfn) ((PCI_SLOT(devfn) & 0x7) << 1)
  78. /* Definition of the PMU configs */
  79. #define HISI_PTT_PMU_FILTER_IS_PORT BIT(19)
  80. #define HISI_PTT_PMU_FILTER_VAL_MASK GENMASK(15, 0)
  81. #define HISI_PTT_PMU_DIRECTION_MASK GENMASK(23, 20)
  82. #define HISI_PTT_PMU_TYPE_MASK GENMASK(31, 24)
  83. #define HISI_PTT_PMU_FORMAT_MASK GENMASK(35, 32)
  84. /**
  85. * struct hisi_ptt_tune_desc - Describe tune event for PTT tune
  86. * @hisi_ptt: PTT device this tune event belongs to
  87. * @name: name of this event
  88. * @event_code: code of the event
  89. */
  90. struct hisi_ptt_tune_desc {
  91. struct hisi_ptt *hisi_ptt;
  92. const char *name;
  93. u32 event_code;
  94. };
  95. /**
  96. * struct hisi_ptt_dma_buffer - Describe a single trace buffer of PTT trace.
  97. * The detail of the data format is described
  98. * in the documentation of PTT device.
  99. * @dma: DMA address of this buffer visible to the device
  100. * @addr: virtual address of this buffer visible to the cpu
  101. */
  102. struct hisi_ptt_dma_buffer {
  103. dma_addr_t dma;
  104. void *addr;
  105. };
  106. /**
  107. * struct hisi_ptt_trace_ctrl - Control and status of PTT trace
  108. * @trace_buf: array of the trace buffers for holding the trace data.
  109. * the length will be HISI_PTT_TRACE_BUF_CNT.
  110. * @handle: perf output handle of current trace session
  111. * @buf_index: the index of current using trace buffer
  112. * @on_cpu: current tracing cpu
  113. * @started: current trace status, true for started
  114. * @is_port: whether we're tracing root port or not
  115. * @direction: direction of the TLP headers to trace
  116. * @filter: filter value for tracing the TLP headers
  117. * @format: format of the TLP headers to trace
  118. * @type: type of the TLP headers to trace
  119. */
  120. struct hisi_ptt_trace_ctrl {
  121. struct hisi_ptt_dma_buffer *trace_buf;
  122. struct perf_output_handle handle;
  123. u32 buf_index;
  124. int on_cpu;
  125. bool started;
  126. bool is_port;
  127. u32 direction:2;
  128. u32 filter:16;
  129. u32 format:1;
  130. u32 type:4;
  131. };
  132. /*
  133. * sysfs attribute group name for root port filters and requester filters:
  134. * /sys/devices/hisi_ptt<sicl_id>_<core_id>/root_port_filters
  135. * and
  136. * /sys/devices/hisi_ptt<sicl_id>_<core_id>/requester_filters
  137. */
  138. #define HISI_PTT_RP_FILTERS_GRP_NAME "root_port_filters"
  139. #define HISI_PTT_REQ_FILTERS_GRP_NAME "requester_filters"
  140. /**
  141. * struct hisi_ptt_filter_desc - Descriptor of the PTT trace filter
  142. * @attr: sysfs attribute of this filter
  143. * @list: entry of this descriptor in the filter list
  144. * @is_port: the PCI device of the filter is a Root Port or not
  145. * @name: name of this filter, same as the name of the related PCI device
  146. * @devid: the PCI device's devid of the filter
  147. */
  148. struct hisi_ptt_filter_desc {
  149. struct device_attribute attr;
  150. struct list_head list;
  151. bool is_port;
  152. char *name;
  153. u16 devid;
  154. };
  155. /**
  156. * struct hisi_ptt_filter_update_info - Information for PTT filter updating
  157. * @is_port: the PCI device to update is a Root Port or not
  158. * @is_add: adding to the filter or not
  159. * @devid: the PCI device's devid of the filter
  160. */
  161. struct hisi_ptt_filter_update_info {
  162. bool is_port;
  163. bool is_add;
  164. u16 devid;
  165. };
  166. /**
  167. * struct hisi_ptt_pmu_buf - Descriptor of the AUX buffer of PTT trace
  168. * @length: size of the AUX buffer
  169. * @nr_pages: number of pages of the AUX buffer
  170. * @base: start address of AUX buffer
  171. * @pos: position in the AUX buffer to commit traced data
  172. */
  173. struct hisi_ptt_pmu_buf {
  174. size_t length;
  175. int nr_pages;
  176. void *base;
  177. long pos;
  178. };
  179. /**
  180. * struct hisi_ptt - Per PTT device data
  181. * @trace_ctrl: the control information of PTT trace
  182. * @hisi_ptt_nb: dynamic filter update notifier
  183. * @hotplug_node: node for register cpu hotplug event
  184. * @hisi_ptt_pmu: the pum device of trace
  185. * @iobase: base IO address of the device
  186. * @pdev: pci_dev of this PTT device
  187. * @tune_lock: lock to serialize the tune process
  188. * @pmu_lock: lock to serialize the perf process
  189. * @trace_irq: interrupt number used by trace
  190. * @upper_bdf: the upper BDF range of the PCI devices managed by this PTT device
  191. * @lower_bdf: the lower BDF range of the PCI devices managed by this PTT device
  192. * @port_filters: the filter list of root ports
  193. * @req_filters: the filter list of requester ID
  194. * @filter_lock: lock to protect the filters
  195. * @sysfs_inited: whether the filters' sysfs entries has been initialized
  196. * @port_mask: port mask of the managed root ports
  197. * @work: delayed work for filter updating
  198. * @filter_update_lock: spinlock to protect the filter update fifo
  199. * @filter_update_fifo: fifo of the filters waiting to update the filter list
  200. */
  201. struct hisi_ptt {
  202. struct hisi_ptt_trace_ctrl trace_ctrl;
  203. struct notifier_block hisi_ptt_nb;
  204. struct hlist_node hotplug_node;
  205. struct pmu hisi_ptt_pmu;
  206. void __iomem *iobase;
  207. struct pci_dev *pdev;
  208. struct mutex tune_lock;
  209. spinlock_t pmu_lock;
  210. int trace_irq;
  211. u32 upper_bdf;
  212. u32 lower_bdf;
  213. /*
  214. * The trace TLP headers can either be filtered by certain
  215. * root port, or by the requester ID. Organize the filters
  216. * by @port_filters and @req_filters here. The mask of all
  217. * the valid ports is also cached for doing sanity check
  218. * of user input.
  219. */
  220. struct list_head port_filters;
  221. struct list_head req_filters;
  222. struct mutex filter_lock;
  223. bool sysfs_inited;
  224. u16 port_mask;
  225. /*
  226. * We use a delayed work here to avoid indefinitely waiting for
  227. * the hisi_ptt->mutex which protecting the filter list. The
  228. * work will be delayed only if the mutex can not be held,
  229. * otherwise no delay will be applied.
  230. */
  231. struct delayed_work work;
  232. spinlock_t filter_update_lock;
  233. DECLARE_KFIFO(filter_update_kfifo, struct hisi_ptt_filter_update_info,
  234. HISI_PTT_FILTER_UPDATE_FIFO_SIZE);
  235. };
  236. #define to_hisi_ptt(pmu) container_of(pmu, struct hisi_ptt, hisi_ptt_pmu)
  237. #endif /* _HISI_PTT_H */