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/list.h> 15 #include <linux/mutex.h> 16 #include <linux/pci.h> 17 #include <linux/perf_event.h> 18 #include <linux/spinlock.h> 19 #include <linux/types.h> 20 21 #define DRV_NAME "hisi_ptt" 22 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_TUNING_INT_STAT 0x0898 47 #define HISI_PTT_TUNING_INT_STAT_MASK BIT(0) 48 #define HISI_PTT_TRACE_WR_STS 0x08a0 49 #define HISI_PTT_TRACE_WR_STS_WRITE GENMASK(27, 0) 50 #define HISI_PTT_TRACE_WR_STS_BUFFER GENMASK(29, 28) 51 #define HISI_PTT_TRACE_STS 0x08b0 52 #define HISI_PTT_TRACE_IDLE BIT(0) 53 #define HISI_PTT_DEVICE_RANGE 0x0fe0 54 #define HISI_PTT_DEVICE_RANGE_UPPER GENMASK(31, 16) 55 #define HISI_PTT_DEVICE_RANGE_LOWER GENMASK(15, 0) 56 #define HISI_PTT_LOCATION 0x0fe8 57 #define HISI_PTT_CORE_ID GENMASK(15, 0) 58 #define HISI_PTT_SICL_ID GENMASK(31, 16) 59 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 74 #define HISI_PCIE_CORE_PORT_ID(devfn) ((PCI_SLOT(devfn) & 0x7) << 1) 75 76 /* Definition of the PMU configs */ 77 #define HISI_PTT_PMU_FILTER_IS_PORT BIT(19) 78 #define HISI_PTT_PMU_FILTER_VAL_MASK GENMASK(15, 0) 79 #define HISI_PTT_PMU_DIRECTION_MASK GENMASK(23, 20) 80 #define HISI_PTT_PMU_TYPE_MASK GENMASK(31, 24) 81 #define HISI_PTT_PMU_FORMAT_MASK GENMASK(35, 32) 82 83 /** 84 * struct hisi_ptt_tune_desc - Describe tune event for PTT tune 85 * @hisi_ptt: PTT device this tune event belongs to 86 * @name: name of this event 87 * @event_code: code of the event 88 */ 89 struct hisi_ptt_tune_desc { 90 struct hisi_ptt *hisi_ptt; 91 const char *name; 92 u32 event_code; 93 }; 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 /** 108 * struct hisi_ptt_trace_ctrl - Control and status of PTT trace 109 * @trace_buf: array of the trace buffers for holding the trace data. 110 * the length will be HISI_PTT_TRACE_BUF_CNT. 111 * @handle: perf output handle of current trace session 112 * @buf_index: the index of current using trace buffer 113 * @on_cpu: current tracing cpu 114 * @started: current trace status, true for started 115 * @is_port: whether we're tracing root port or not 116 * @direction: direction of the TLP headers to trace 117 * @filter: filter value for tracing the TLP headers 118 * @format: format of the TLP headers to trace 119 * @type: type of the TLP headers to trace 120 */ 121 struct hisi_ptt_trace_ctrl { 122 struct hisi_ptt_dma_buffer *trace_buf; 123 struct perf_output_handle handle; 124 u32 buf_index; 125 int on_cpu; 126 bool started; 127 bool is_port; 128 u32 direction:2; 129 u32 filter:16; 130 u32 format:1; 131 u32 type:4; 132 }; 133 134 /** 135 * struct hisi_ptt_filter_desc - Descriptor of the PTT trace filter 136 * @list: entry of this descriptor in the filter list 137 * @is_port: the PCI device of the filter is a Root Port or not 138 * @devid: the PCI device's devid of the filter 139 */ 140 struct hisi_ptt_filter_desc { 141 struct list_head list; 142 bool is_port; 143 u16 devid; 144 }; 145 146 /** 147 * struct hisi_ptt_pmu_buf - Descriptor of the AUX buffer of PTT trace 148 * @length: size of the AUX buffer 149 * @nr_pages: number of pages of the AUX buffer 150 * @base: start address of AUX buffer 151 * @pos: position in the AUX buffer to commit traced data 152 */ 153 struct hisi_ptt_pmu_buf { 154 size_t length; 155 int nr_pages; 156 void *base; 157 long pos; 158 }; 159 160 /** 161 * struct hisi_ptt - Per PTT device data 162 * @trace_ctrl: the control information of PTT trace 163 * @hotplug_node: node for register cpu hotplug event 164 * @hisi_ptt_pmu: the pum device of trace 165 * @iobase: base IO address of the device 166 * @pdev: pci_dev of this PTT device 167 * @tune_lock: lock to serialize the tune process 168 * @pmu_lock: lock to serialize the perf process 169 * @trace_irq: interrupt number used by trace 170 * @upper_bdf: the upper BDF range of the PCI devices managed by this PTT device 171 * @lower_bdf: the lower BDF range of the PCI devices managed by this PTT device 172 * @port_filters: the filter list of root ports 173 * @req_filters: the filter list of requester ID 174 * @port_mask: port mask of the managed root ports 175 */ 176 struct hisi_ptt { 177 struct hisi_ptt_trace_ctrl trace_ctrl; 178 struct hlist_node hotplug_node; 179 struct pmu hisi_ptt_pmu; 180 void __iomem *iobase; 181 struct pci_dev *pdev; 182 struct mutex tune_lock; 183 spinlock_t pmu_lock; 184 int trace_irq; 185 u32 upper_bdf; 186 u32 lower_bdf; 187 188 /* 189 * The trace TLP headers can either be filtered by certain 190 * root port, or by the requester ID. Organize the filters 191 * by @port_filters and @req_filters here. The mask of all 192 * the valid ports is also cached for doing sanity check 193 * of user input. 194 */ 195 struct list_head port_filters; 196 struct list_head req_filters; 197 u16 port_mask; 198 }; 199 200 #define to_hisi_ptt(pmu) container_of(pmu, struct hisi_ptt, hisi_ptt_pmu) 201 202 #endif /* _HISI_PTT_H */ 203