18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * xhci-dbc.h - xHCI debug capability early driver
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2016 Intel Corporation
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Author: Lu Baolu <baolu.lu@linux.intel.com>
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#ifndef __LINUX_XHCI_DBC_H
118c2ecf20Sopenharmony_ci#define __LINUX_XHCI_DBC_H
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include <linux/types.h>
148c2ecf20Sopenharmony_ci#include <linux/usb/ch9.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci/*
178c2ecf20Sopenharmony_ci * xHCI Debug Capability Register interfaces:
188c2ecf20Sopenharmony_ci */
198c2ecf20Sopenharmony_cistruct xdbc_regs {
208c2ecf20Sopenharmony_ci	__le32	capability;
218c2ecf20Sopenharmony_ci	__le32	doorbell;
228c2ecf20Sopenharmony_ci	__le32	ersts;		/* Event Ring Segment Table Size*/
238c2ecf20Sopenharmony_ci	__le32	__reserved_0;	/* 0c~0f reserved bits */
248c2ecf20Sopenharmony_ci	__le64	erstba;		/* Event Ring Segment Table Base Address */
258c2ecf20Sopenharmony_ci	__le64	erdp;		/* Event Ring Dequeue Pointer */
268c2ecf20Sopenharmony_ci	__le32	control;
278c2ecf20Sopenharmony_ci	__le32	status;
288c2ecf20Sopenharmony_ci	__le32	portsc;		/* Port status and control */
298c2ecf20Sopenharmony_ci	__le32	__reserved_1;	/* 2b~28 reserved bits */
308c2ecf20Sopenharmony_ci	__le64	dccp;		/* Debug Capability Context Pointer */
318c2ecf20Sopenharmony_ci	__le32	devinfo1;	/* Device Descriptor Info Register 1 */
328c2ecf20Sopenharmony_ci	__le32	devinfo2;	/* Device Descriptor Info Register 2 */
338c2ecf20Sopenharmony_ci};
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#define DEBUG_MAX_BURST(p)	(((p) >> 16) & 0xff)
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#define CTRL_DBC_RUN		BIT(0)
388c2ecf20Sopenharmony_ci#define CTRL_PORT_ENABLE	BIT(1)
398c2ecf20Sopenharmony_ci#define CTRL_HALT_OUT_TR	BIT(2)
408c2ecf20Sopenharmony_ci#define CTRL_HALT_IN_TR		BIT(3)
418c2ecf20Sopenharmony_ci#define CTRL_DBC_RUN_CHANGE	BIT(4)
428c2ecf20Sopenharmony_ci#define CTRL_DBC_ENABLE		BIT(31)
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci#define DCST_DEBUG_PORT(p)	(((p) >> 24) & 0xff)
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci#define PORTSC_CONN_STATUS	BIT(0)
478c2ecf20Sopenharmony_ci#define PORTSC_CONN_CHANGE	BIT(17)
488c2ecf20Sopenharmony_ci#define PORTSC_RESET_CHANGE	BIT(21)
498c2ecf20Sopenharmony_ci#define PORTSC_LINK_CHANGE	BIT(22)
508c2ecf20Sopenharmony_ci#define PORTSC_CONFIG_CHANGE	BIT(23)
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci/*
538c2ecf20Sopenharmony_ci * xHCI Debug Capability data structures:
548c2ecf20Sopenharmony_ci */
558c2ecf20Sopenharmony_cistruct xdbc_trb {
568c2ecf20Sopenharmony_ci	__le32 field[4];
578c2ecf20Sopenharmony_ci};
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cistruct xdbc_erst_entry {
608c2ecf20Sopenharmony_ci	__le64	seg_addr;
618c2ecf20Sopenharmony_ci	__le32	seg_size;
628c2ecf20Sopenharmony_ci	__le32	__reserved_0;
638c2ecf20Sopenharmony_ci};
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_cistruct xdbc_info_context {
668c2ecf20Sopenharmony_ci	__le64	string0;
678c2ecf20Sopenharmony_ci	__le64	manufacturer;
688c2ecf20Sopenharmony_ci	__le64	product;
698c2ecf20Sopenharmony_ci	__le64	serial;
708c2ecf20Sopenharmony_ci	__le32	length;
718c2ecf20Sopenharmony_ci	__le32	__reserved_0[7];
728c2ecf20Sopenharmony_ci};
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_cistruct xdbc_ep_context {
758c2ecf20Sopenharmony_ci	__le32	ep_info1;
768c2ecf20Sopenharmony_ci	__le32	ep_info2;
778c2ecf20Sopenharmony_ci	__le64	deq;
788c2ecf20Sopenharmony_ci	__le32	tx_info;
798c2ecf20Sopenharmony_ci	__le32	__reserved_0[11];
808c2ecf20Sopenharmony_ci};
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_cistruct xdbc_context {
838c2ecf20Sopenharmony_ci	struct xdbc_info_context	info;
848c2ecf20Sopenharmony_ci	struct xdbc_ep_context		out;
858c2ecf20Sopenharmony_ci	struct xdbc_ep_context		in;
868c2ecf20Sopenharmony_ci};
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci#define XDBC_INFO_CONTEXT_SIZE		48
898c2ecf20Sopenharmony_ci#define XDBC_MAX_STRING_LENGTH		64
908c2ecf20Sopenharmony_ci#define XDBC_STRING_MANUFACTURER	"Linux Foundation"
918c2ecf20Sopenharmony_ci#define XDBC_STRING_PRODUCT		"Linux USB GDB Target"
928c2ecf20Sopenharmony_ci#define XDBC_STRING_SERIAL		"0001"
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_cistruct xdbc_strings {
958c2ecf20Sopenharmony_ci	char	string0[XDBC_MAX_STRING_LENGTH];
968c2ecf20Sopenharmony_ci	char	manufacturer[XDBC_MAX_STRING_LENGTH];
978c2ecf20Sopenharmony_ci	char	product[XDBC_MAX_STRING_LENGTH];
988c2ecf20Sopenharmony_ci	char	serial[XDBC_MAX_STRING_LENGTH];
998c2ecf20Sopenharmony_ci};
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci#define XDBC_PROTOCOL		1	/* GNU Remote Debug Command Set */
1028c2ecf20Sopenharmony_ci#define XDBC_VENDOR_ID		0x1d6b	/* Linux Foundation 0x1d6b */
1038c2ecf20Sopenharmony_ci#define XDBC_PRODUCT_ID		0x0011	/* __le16 idProduct; device 0011 */
1048c2ecf20Sopenharmony_ci#define XDBC_DEVICE_REV		0x0010	/* 0.10 */
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci/*
1078c2ecf20Sopenharmony_ci * xHCI Debug Capability software state structures:
1088c2ecf20Sopenharmony_ci */
1098c2ecf20Sopenharmony_cistruct xdbc_segment {
1108c2ecf20Sopenharmony_ci	struct xdbc_trb		*trbs;
1118c2ecf20Sopenharmony_ci	dma_addr_t		dma;
1128c2ecf20Sopenharmony_ci};
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci#define XDBC_TRBS_PER_SEGMENT	256
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_cistruct xdbc_ring {
1178c2ecf20Sopenharmony_ci	struct xdbc_segment	*segment;
1188c2ecf20Sopenharmony_ci	struct xdbc_trb		*enqueue;
1198c2ecf20Sopenharmony_ci	struct xdbc_trb		*dequeue;
1208c2ecf20Sopenharmony_ci	u32			cycle_state;
1218c2ecf20Sopenharmony_ci};
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci/*
1248c2ecf20Sopenharmony_ci * These are the "Endpoint ID" (also known as "Context Index") values for the
1258c2ecf20Sopenharmony_ci * OUT Transfer Ring and the IN Transfer Ring of a Debug Capability Context data
1268c2ecf20Sopenharmony_ci * structure.
1278c2ecf20Sopenharmony_ci * According to the "eXtensible Host Controller Interface for Universal Serial
1288c2ecf20Sopenharmony_ci * Bus (xHCI)" specification, section "7.6.3.2 Endpoint Contexts and Transfer
1298c2ecf20Sopenharmony_ci * Rings", these should be 0 and 1, and those are the values AMD machines give
1308c2ecf20Sopenharmony_ci * you; but Intel machines seem to use the formula from section "4.5.1 Device
1318c2ecf20Sopenharmony_ci * Context Index", which is supposed to be used for the Device Context only.
1328c2ecf20Sopenharmony_ci * Luckily the values from Intel don't overlap with those from AMD, so we can
1338c2ecf20Sopenharmony_ci * just test for both.
1348c2ecf20Sopenharmony_ci */
1358c2ecf20Sopenharmony_ci#define XDBC_EPID_OUT		0
1368c2ecf20Sopenharmony_ci#define XDBC_EPID_IN		1
1378c2ecf20Sopenharmony_ci#define XDBC_EPID_OUT_INTEL	2
1388c2ecf20Sopenharmony_ci#define XDBC_EPID_IN_INTEL	3
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_cistruct xdbc_state {
1418c2ecf20Sopenharmony_ci	u16			vendor;
1428c2ecf20Sopenharmony_ci	u16			device;
1438c2ecf20Sopenharmony_ci	u32			bus;
1448c2ecf20Sopenharmony_ci	u32			dev;
1458c2ecf20Sopenharmony_ci	u32			func;
1468c2ecf20Sopenharmony_ci	void __iomem		*xhci_base;
1478c2ecf20Sopenharmony_ci	u64			xhci_start;
1488c2ecf20Sopenharmony_ci	size_t			xhci_length;
1498c2ecf20Sopenharmony_ci	int			port_number;
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci	/* DbC register base */
1528c2ecf20Sopenharmony_ci	struct xdbc_regs __iomem *xdbc_reg;
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci	/* DbC table page */
1558c2ecf20Sopenharmony_ci	dma_addr_t		table_dma;
1568c2ecf20Sopenharmony_ci	void			*table_base;
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci	/* event ring segment table */
1598c2ecf20Sopenharmony_ci	dma_addr_t		erst_dma;
1608c2ecf20Sopenharmony_ci	size_t			erst_size;
1618c2ecf20Sopenharmony_ci	void			*erst_base;
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci	/* event ring segments */
1648c2ecf20Sopenharmony_ci	struct xdbc_ring	evt_ring;
1658c2ecf20Sopenharmony_ci	struct xdbc_segment	evt_seg;
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci	/* debug capability contexts */
1688c2ecf20Sopenharmony_ci	dma_addr_t		dbcc_dma;
1698c2ecf20Sopenharmony_ci	size_t			dbcc_size;
1708c2ecf20Sopenharmony_ci	void			*dbcc_base;
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	/* descriptor strings */
1738c2ecf20Sopenharmony_ci	dma_addr_t		string_dma;
1748c2ecf20Sopenharmony_ci	size_t			string_size;
1758c2ecf20Sopenharmony_ci	void			*string_base;
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci	/* bulk OUT endpoint */
1788c2ecf20Sopenharmony_ci	struct xdbc_ring	out_ring;
1798c2ecf20Sopenharmony_ci	struct xdbc_segment	out_seg;
1808c2ecf20Sopenharmony_ci	void			*out_buf;
1818c2ecf20Sopenharmony_ci	dma_addr_t		out_dma;
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ci	/* bulk IN endpoint */
1848c2ecf20Sopenharmony_ci	struct xdbc_ring	in_ring;
1858c2ecf20Sopenharmony_ci	struct xdbc_segment	in_seg;
1868c2ecf20Sopenharmony_ci	void			*in_buf;
1878c2ecf20Sopenharmony_ci	dma_addr_t		in_dma;
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci	u32			flags;
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci	/* spinlock for early_xdbc_write() reentrancy */
1928c2ecf20Sopenharmony_ci	raw_spinlock_t		lock;
1938c2ecf20Sopenharmony_ci};
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci#define XDBC_PCI_MAX_BUSES	256
1968c2ecf20Sopenharmony_ci#define XDBC_PCI_MAX_DEVICES	32
1978c2ecf20Sopenharmony_ci#define XDBC_PCI_MAX_FUNCTION	8
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ci#define XDBC_TABLE_ENTRY_SIZE	64
2008c2ecf20Sopenharmony_ci#define XDBC_ERST_ENTRY_NUM	1
2018c2ecf20Sopenharmony_ci#define XDBC_DBCC_ENTRY_NUM	3
2028c2ecf20Sopenharmony_ci#define XDBC_STRING_ENTRY_NUM	4
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci/* Bits definitions for xdbc_state.flags: */
2058c2ecf20Sopenharmony_ci#define XDBC_FLAGS_INITIALIZED	BIT(0)
2068c2ecf20Sopenharmony_ci#define XDBC_FLAGS_IN_STALL	BIT(1)
2078c2ecf20Sopenharmony_ci#define XDBC_FLAGS_OUT_STALL	BIT(2)
2088c2ecf20Sopenharmony_ci#define XDBC_FLAGS_IN_PROCESS	BIT(3)
2098c2ecf20Sopenharmony_ci#define XDBC_FLAGS_OUT_PROCESS	BIT(4)
2108c2ecf20Sopenharmony_ci#define XDBC_FLAGS_CONFIGURED	BIT(5)
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci#define XDBC_MAX_PACKET		1024
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci/* Door bell target: */
2158c2ecf20Sopenharmony_ci#define OUT_EP_DOORBELL		0
2168c2ecf20Sopenharmony_ci#define IN_EP_DOORBELL		1
2178c2ecf20Sopenharmony_ci#define DOOR_BELL_TARGET(p)	(((p) & 0xff) << 8)
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ci#define xdbc_read64(regs)	xhci_read_64(NULL, (regs))
2208c2ecf20Sopenharmony_ci#define xdbc_write64(val, regs)	xhci_write_64(NULL, (val), (regs))
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci#endif /* __LINUX_XHCI_DBC_H */
223