Loading...
Note: File does not exist in v4.17.
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 */
89struct 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 */
102struct 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 */
121struct 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 */
140struct 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 */
153struct 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 * @upper_bdf: the upper BDF range of the PCI devices managed by this PTT device
170 * @lower_bdf: the lower BDF range of the PCI devices managed by this PTT device
171 * @port_filters: the filter list of root ports
172 * @req_filters: the filter list of requester ID
173 * @port_mask: port mask of the managed root ports
174 */
175struct hisi_ptt {
176 struct hisi_ptt_trace_ctrl trace_ctrl;
177 struct hlist_node hotplug_node;
178 struct pmu hisi_ptt_pmu;
179 void __iomem *iobase;
180 struct pci_dev *pdev;
181 struct mutex tune_lock;
182 spinlock_t pmu_lock;
183 u32 upper_bdf;
184 u32 lower_bdf;
185
186 /*
187 * The trace TLP headers can either be filtered by certain
188 * root port, or by the requester ID. Organize the filters
189 * by @port_filters and @req_filters here. The mask of all
190 * the valid ports is also cached for doing sanity check
191 * of user input.
192 */
193 struct list_head port_filters;
194 struct list_head req_filters;
195 u16 port_mask;
196};
197
198#define to_hisi_ptt(pmu) container_of(pmu, struct hisi_ptt, hisi_ptt_pmu)
199
200#endif /* _HISI_PTT_H */