162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * xhci-dbc.h - xHCI debug capability early driver
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2016 Intel Corporation
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Author: Lu Baolu <baolu.lu@linux.intel.com>
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#ifndef __LINUX_XHCI_DBC_H
1162306a36Sopenharmony_ci#define __LINUX_XHCI_DBC_H
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/types.h>
1462306a36Sopenharmony_ci#include <linux/usb/ch9.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci/*
1762306a36Sopenharmony_ci * xHCI Debug Capability Register interfaces:
1862306a36Sopenharmony_ci */
1962306a36Sopenharmony_cistruct xdbc_regs {
2062306a36Sopenharmony_ci	__le32	capability;
2162306a36Sopenharmony_ci	__le32	doorbell;
2262306a36Sopenharmony_ci	__le32	ersts;		/* Event Ring Segment Table Size*/
2362306a36Sopenharmony_ci	__le32	__reserved_0;	/* 0c~0f reserved bits */
2462306a36Sopenharmony_ci	__le64	erstba;		/* Event Ring Segment Table Base Address */
2562306a36Sopenharmony_ci	__le64	erdp;		/* Event Ring Dequeue Pointer */
2662306a36Sopenharmony_ci	__le32	control;
2762306a36Sopenharmony_ci	__le32	status;
2862306a36Sopenharmony_ci	__le32	portsc;		/* Port status and control */
2962306a36Sopenharmony_ci	__le32	__reserved_1;	/* 2b~28 reserved bits */
3062306a36Sopenharmony_ci	__le64	dccp;		/* Debug Capability Context Pointer */
3162306a36Sopenharmony_ci	__le32	devinfo1;	/* Device Descriptor Info Register 1 */
3262306a36Sopenharmony_ci	__le32	devinfo2;	/* Device Descriptor Info Register 2 */
3362306a36Sopenharmony_ci};
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#define DEBUG_MAX_BURST(p)	(((p) >> 16) & 0xff)
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define CTRL_DBC_RUN		BIT(0)
3862306a36Sopenharmony_ci#define CTRL_PORT_ENABLE	BIT(1)
3962306a36Sopenharmony_ci#define CTRL_HALT_OUT_TR	BIT(2)
4062306a36Sopenharmony_ci#define CTRL_HALT_IN_TR		BIT(3)
4162306a36Sopenharmony_ci#define CTRL_DBC_RUN_CHANGE	BIT(4)
4262306a36Sopenharmony_ci#define CTRL_DBC_ENABLE		BIT(31)
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci#define DCST_DEBUG_PORT(p)	(((p) >> 24) & 0xff)
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci#define PORTSC_CONN_STATUS	BIT(0)
4762306a36Sopenharmony_ci#define PORTSC_CONN_CHANGE	BIT(17)
4862306a36Sopenharmony_ci#define PORTSC_RESET_CHANGE	BIT(21)
4962306a36Sopenharmony_ci#define PORTSC_LINK_CHANGE	BIT(22)
5062306a36Sopenharmony_ci#define PORTSC_CONFIG_CHANGE	BIT(23)
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci/*
5362306a36Sopenharmony_ci * xHCI Debug Capability data structures:
5462306a36Sopenharmony_ci */
5562306a36Sopenharmony_cistruct xdbc_trb {
5662306a36Sopenharmony_ci	__le32 field[4];
5762306a36Sopenharmony_ci};
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cistruct xdbc_erst_entry {
6062306a36Sopenharmony_ci	__le64	seg_addr;
6162306a36Sopenharmony_ci	__le32	seg_size;
6262306a36Sopenharmony_ci	__le32	__reserved_0;
6362306a36Sopenharmony_ci};
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_cistruct xdbc_info_context {
6662306a36Sopenharmony_ci	__le64	string0;
6762306a36Sopenharmony_ci	__le64	manufacturer;
6862306a36Sopenharmony_ci	__le64	product;
6962306a36Sopenharmony_ci	__le64	serial;
7062306a36Sopenharmony_ci	__le32	length;
7162306a36Sopenharmony_ci	__le32	__reserved_0[7];
7262306a36Sopenharmony_ci};
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cistruct xdbc_ep_context {
7562306a36Sopenharmony_ci	__le32	ep_info1;
7662306a36Sopenharmony_ci	__le32	ep_info2;
7762306a36Sopenharmony_ci	__le64	deq;
7862306a36Sopenharmony_ci	__le32	tx_info;
7962306a36Sopenharmony_ci	__le32	__reserved_0[11];
8062306a36Sopenharmony_ci};
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistruct xdbc_context {
8362306a36Sopenharmony_ci	struct xdbc_info_context	info;
8462306a36Sopenharmony_ci	struct xdbc_ep_context		out;
8562306a36Sopenharmony_ci	struct xdbc_ep_context		in;
8662306a36Sopenharmony_ci};
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci#define XDBC_INFO_CONTEXT_SIZE		48
8962306a36Sopenharmony_ci#define XDBC_MAX_STRING_LENGTH		64
9062306a36Sopenharmony_ci#define XDBC_STRING_MANUFACTURER	"Linux Foundation"
9162306a36Sopenharmony_ci#define XDBC_STRING_PRODUCT		"Linux USB GDB Target"
9262306a36Sopenharmony_ci#define XDBC_STRING_SERIAL		"0001"
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_cistruct xdbc_strings {
9562306a36Sopenharmony_ci	char	string0[XDBC_MAX_STRING_LENGTH];
9662306a36Sopenharmony_ci	char	manufacturer[XDBC_MAX_STRING_LENGTH];
9762306a36Sopenharmony_ci	char	product[XDBC_MAX_STRING_LENGTH];
9862306a36Sopenharmony_ci	char	serial[XDBC_MAX_STRING_LENGTH];
9962306a36Sopenharmony_ci};
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci#define XDBC_PROTOCOL		1	/* GNU Remote Debug Command Set */
10262306a36Sopenharmony_ci#define XDBC_VENDOR_ID		0x1d6b	/* Linux Foundation 0x1d6b */
10362306a36Sopenharmony_ci#define XDBC_PRODUCT_ID		0x0011	/* __le16 idProduct; device 0011 */
10462306a36Sopenharmony_ci#define XDBC_DEVICE_REV		0x0010	/* 0.10 */
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci/*
10762306a36Sopenharmony_ci * xHCI Debug Capability software state structures:
10862306a36Sopenharmony_ci */
10962306a36Sopenharmony_cistruct xdbc_segment {
11062306a36Sopenharmony_ci	struct xdbc_trb		*trbs;
11162306a36Sopenharmony_ci	dma_addr_t		dma;
11262306a36Sopenharmony_ci};
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci#define XDBC_TRBS_PER_SEGMENT	256
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_cistruct xdbc_ring {
11762306a36Sopenharmony_ci	struct xdbc_segment	*segment;
11862306a36Sopenharmony_ci	struct xdbc_trb		*enqueue;
11962306a36Sopenharmony_ci	struct xdbc_trb		*dequeue;
12062306a36Sopenharmony_ci	u32			cycle_state;
12162306a36Sopenharmony_ci};
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci/*
12462306a36Sopenharmony_ci * These are the "Endpoint ID" (also known as "Context Index") values for the
12562306a36Sopenharmony_ci * OUT Transfer Ring and the IN Transfer Ring of a Debug Capability Context data
12662306a36Sopenharmony_ci * structure.
12762306a36Sopenharmony_ci * According to the "eXtensible Host Controller Interface for Universal Serial
12862306a36Sopenharmony_ci * Bus (xHCI)" specification, section "7.6.3.2 Endpoint Contexts and Transfer
12962306a36Sopenharmony_ci * Rings", these should be 0 and 1, and those are the values AMD machines give
13062306a36Sopenharmony_ci * you; but Intel machines seem to use the formula from section "4.5.1 Device
13162306a36Sopenharmony_ci * Context Index", which is supposed to be used for the Device Context only.
13262306a36Sopenharmony_ci * Luckily the values from Intel don't overlap with those from AMD, so we can
13362306a36Sopenharmony_ci * just test for both.
13462306a36Sopenharmony_ci */
13562306a36Sopenharmony_ci#define XDBC_EPID_OUT		0
13662306a36Sopenharmony_ci#define XDBC_EPID_IN		1
13762306a36Sopenharmony_ci#define XDBC_EPID_OUT_INTEL	2
13862306a36Sopenharmony_ci#define XDBC_EPID_IN_INTEL	3
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cistruct xdbc_state {
14162306a36Sopenharmony_ci	u16			vendor;
14262306a36Sopenharmony_ci	u16			device;
14362306a36Sopenharmony_ci	u32			bus;
14462306a36Sopenharmony_ci	u32			dev;
14562306a36Sopenharmony_ci	u32			func;
14662306a36Sopenharmony_ci	void __iomem		*xhci_base;
14762306a36Sopenharmony_ci	u64			xhci_start;
14862306a36Sopenharmony_ci	size_t			xhci_length;
14962306a36Sopenharmony_ci	int			port_number;
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	/* DbC register base */
15262306a36Sopenharmony_ci	struct xdbc_regs __iomem *xdbc_reg;
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci	/* DbC table page */
15562306a36Sopenharmony_ci	dma_addr_t		table_dma;
15662306a36Sopenharmony_ci	void			*table_base;
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci	/* event ring segment table */
15962306a36Sopenharmony_ci	dma_addr_t		erst_dma;
16062306a36Sopenharmony_ci	size_t			erst_size;
16162306a36Sopenharmony_ci	void			*erst_base;
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	/* event ring segments */
16462306a36Sopenharmony_ci	struct xdbc_ring	evt_ring;
16562306a36Sopenharmony_ci	struct xdbc_segment	evt_seg;
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci	/* debug capability contexts */
16862306a36Sopenharmony_ci	dma_addr_t		dbcc_dma;
16962306a36Sopenharmony_ci	size_t			dbcc_size;
17062306a36Sopenharmony_ci	void			*dbcc_base;
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci	/* descriptor strings */
17362306a36Sopenharmony_ci	dma_addr_t		string_dma;
17462306a36Sopenharmony_ci	size_t			string_size;
17562306a36Sopenharmony_ci	void			*string_base;
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci	/* bulk OUT endpoint */
17862306a36Sopenharmony_ci	struct xdbc_ring	out_ring;
17962306a36Sopenharmony_ci	struct xdbc_segment	out_seg;
18062306a36Sopenharmony_ci	void			*out_buf;
18162306a36Sopenharmony_ci	dma_addr_t		out_dma;
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci	/* bulk IN endpoint */
18462306a36Sopenharmony_ci	struct xdbc_ring	in_ring;
18562306a36Sopenharmony_ci	struct xdbc_segment	in_seg;
18662306a36Sopenharmony_ci	void			*in_buf;
18762306a36Sopenharmony_ci	dma_addr_t		in_dma;
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci	u32			flags;
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	/* spinlock for early_xdbc_write() reentrancy */
19262306a36Sopenharmony_ci	raw_spinlock_t		lock;
19362306a36Sopenharmony_ci};
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci#define XDBC_PCI_MAX_BUSES	256
19662306a36Sopenharmony_ci#define XDBC_PCI_MAX_DEVICES	32
19762306a36Sopenharmony_ci#define XDBC_PCI_MAX_FUNCTION	8
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci#define XDBC_TABLE_ENTRY_SIZE	64
20062306a36Sopenharmony_ci#define XDBC_ERST_ENTRY_NUM	1
20162306a36Sopenharmony_ci#define XDBC_DBCC_ENTRY_NUM	3
20262306a36Sopenharmony_ci#define XDBC_STRING_ENTRY_NUM	4
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci/* Bits definitions for xdbc_state.flags: */
20562306a36Sopenharmony_ci#define XDBC_FLAGS_INITIALIZED	BIT(0)
20662306a36Sopenharmony_ci#define XDBC_FLAGS_IN_STALL	BIT(1)
20762306a36Sopenharmony_ci#define XDBC_FLAGS_OUT_STALL	BIT(2)
20862306a36Sopenharmony_ci#define XDBC_FLAGS_IN_PROCESS	BIT(3)
20962306a36Sopenharmony_ci#define XDBC_FLAGS_OUT_PROCESS	BIT(4)
21062306a36Sopenharmony_ci#define XDBC_FLAGS_CONFIGURED	BIT(5)
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci#define XDBC_MAX_PACKET		1024
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci/* Door bell target: */
21562306a36Sopenharmony_ci#define OUT_EP_DOORBELL		0
21662306a36Sopenharmony_ci#define IN_EP_DOORBELL		1
21762306a36Sopenharmony_ci#define DOOR_BELL_TARGET(p)	(((p) & 0xff) << 8)
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci#define xdbc_read64(regs)	xhci_read_64(NULL, (regs))
22062306a36Sopenharmony_ci#define xdbc_write64(val, regs)	xhci_write_64(NULL, (val), (regs))
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci#endif /* __LINUX_XHCI_DBC_H */
223