brintos

brintos / linux-shallow public Read only

0
0
Text · 8.6 KiB · 46030aa Raw
258 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * Driver for HiSilicon PCIe tune and trace device4 *5 * Copyright (c) 2022 HiSilicon Technologies Co., Ltd.6 * Author: Yicong Yang <yangyicong@hisilicon.com>7 */8 9#ifndef _HISI_PTT_H10#define _HISI_PTT_H11 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		0x000031#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		0x000434#define   HISI_PTT_TUNING_DATA_VAL_MASK	GENMASK(15, 0)35#define HISI_PTT_TRACE_ADDR_SIZE	0x080036#define HISI_PTT_TRACE_ADDR_BASE_LO_0	0x081037#define HISI_PTT_TRACE_ADDR_BASE_HI_0	0x081438#define HISI_PTT_TRACE_ADDR_STRIDE	0x839#define HISI_PTT_TRACE_CTRL		0x085040#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		0x089048#define   HISI_PTT_TRACE_INT_STAT_MASK	GENMASK(3, 0)49#define HISI_PTT_TRACE_INT_MASK		0x089450#define   HISI_PTT_TRACE_INT_MASK_ALL	GENMASK(3, 0)51#define HISI_PTT_TUNING_INT_STAT	0x089852#define   HISI_PTT_TUNING_INT_STAT_MASK	BIT(0)53#define HISI_PTT_TRACE_WR_STS		0x08a054#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		0x08b057#define   HISI_PTT_TRACE_IDLE		BIT(0)58#define HISI_PTT_DEVICE_RANGE		0x0fe059#define   HISI_PTT_DEVICE_RANGE_UPPER	GENMASK(31, 16)60#define   HISI_PTT_DEVICE_RANGE_LOWER	GENMASK(15, 0)61#define HISI_PTT_LOCATION		0x0fe862#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			067#define HISI_PTT_TRACE_BUF_CNT			468#define HISI_PTT_TRACE_BUF_SIZE			SZ_4M69#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	10UL73#define HISI_PTT_RESET_POLL_INTERVAL_US	1UL74/* Poll timeout and interval for waiting hardware work to finish */75#define HISI_PTT_WAIT_TUNE_TIMEOUT_US	1000000UL76#define HISI_PTT_WAIT_TRACE_TIMEOUT_US	100UL77#define HISI_PTT_WAIT_POLL_INTERVAL_US	10UL78 79/* FIFO size for dynamically updating the PTT trace filter list. */80#define HISI_PTT_FILTER_UPDATE_FIFO_SIZE	1681/* Delay time for filter updating work */82#define HISI_PTT_WORK_DELAY_MS			100UL83 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 tune95 * @hisi_ptt:   PTT device this tune event belongs to96 * @name:       name of this event97 * @event_code: code of the event98 */99struct 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 described108 *                              in the documentation of PTT device.109 * @dma:   DMA address of this buffer visible to the device110 * @addr:  virtual address of this buffer visible to the cpu111 */112struct 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 trace119 * @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 session122 * @buf_index: the index of current using trace buffer123 * @on_cpu:    current tracing cpu124 * @started:   current trace status, true for started125 * @is_port:   whether we're tracing root port or not126 * @direction: direction of the TLP headers to trace127 * @filter:    filter value for tracing the TLP headers128 * @format:    format of the TLP headers to trace129 * @type:      type of the TLP headers to trace130 */131struct 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_filters147 * and148 * /sys/devices/hisi_ptt<sicl_id>_<core_id>/requester_filters149 */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 filter155 * @attr:    sysfs attribute of this filter156 * @list:    entry of this descriptor in the filter list157 * @is_port: the PCI device of the filter is a Root Port or not158 * @name:    name of this filter, same as the name of the related PCI device159 * @devid:   the PCI device's devid of the filter160 */161struct 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 updating171 * @is_port:    the PCI device to update is a Root Port or not172 * @is_add:     adding to the filter or not173 * @devid:      the PCI device's devid of the filter174 */175struct 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 trace183 * @length:   size of the AUX buffer184 * @nr_pages: number of pages of the AUX buffer185 * @base:     start address of AUX buffer186 * @pos:      position in the AUX buffer to commit traced data187 */188struct 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 data197 * @trace_ctrl:   the control information of PTT trace198 * @hisi_ptt_nb:  dynamic filter update notifier199 * @hotplug_node: node for register cpu hotplug event200 * @hisi_ptt_pmu: the pum device of trace201 * @iobase:       base IO address of the device202 * @pdev:         pci_dev of this PTT device203 * @tune_lock:    lock to serialize the tune process204 * @pmu_lock:     lock to serialize the perf process205 * @trace_irq:    interrupt number used by trace206 * @upper_bdf:    the upper BDF range of the PCI devices managed by this PTT device207 * @lower_bdf:    the lower BDF range of the PCI devices managed by this PTT device208 * @port_filters: the filter list of root ports209 * @req_filters:  the filter list of requester ID210 * @filter_lock:  lock to protect the filters211 * @sysfs_inited: whether the filters' sysfs entries has been initialized212 * @port_mask:    port mask of the managed root ports213 * @work:         delayed work for filter updating214 * @filter_update_lock: spinlock to protect the filter update fifo215 * @filter_update_fifo: fifo of the filters waiting to update the filter list216 */217struct 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 certain232	 * root port, or by the requester ID. Organize the filters233	 * by @port_filters and @req_filters here. The mask of all234	 * the valid ports is also cached for doing sanity check235	 * 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 for245	 * the hisi_ptt->mutex which protecting the filter list. The246	 * 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