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