summaryrefslogtreecommitdiffstats
path: root/drivers/usb/early/xhci-dbc.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--drivers/usb/early/xhci-dbc.h222
1 files changed, 222 insertions, 0 deletions
diff --git a/drivers/usb/early/xhci-dbc.h b/drivers/usb/early/xhci-dbc.h
new file mode 100644
index 0000000000..8b4d71de45
--- /dev/null
+++ b/drivers/usb/early/xhci-dbc.h
@@ -0,0 +1,222 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * xhci-dbc.h - xHCI debug capability early driver
+ *
+ * Copyright (C) 2016 Intel Corporation
+ *
+ * Author: Lu Baolu <baolu.lu@linux.intel.com>
+ */
+
+#ifndef __LINUX_XHCI_DBC_H
+#define __LINUX_XHCI_DBC_H
+
+#include <linux/types.h>
+#include <linux/usb/ch9.h>
+
+/*
+ * xHCI Debug Capability Register interfaces:
+ */
+struct xdbc_regs {
+ __le32 capability;
+ __le32 doorbell;
+ __le32 ersts; /* Event Ring Segment Table Size*/
+ __le32 __reserved_0; /* 0c~0f reserved bits */
+ __le64 erstba; /* Event Ring Segment Table Base Address */
+ __le64 erdp; /* Event Ring Dequeue Pointer */
+ __le32 control;
+ __le32 status;
+ __le32 portsc; /* Port status and control */
+ __le32 __reserved_1; /* 2b~28 reserved bits */
+ __le64 dccp; /* Debug Capability Context Pointer */
+ __le32 devinfo1; /* Device Descriptor Info Register 1 */
+ __le32 devinfo2; /* Device Descriptor Info Register 2 */
+};
+
+#define DEBUG_MAX_BURST(p) (((p) >> 16) & 0xff)
+
+#define CTRL_DBC_RUN BIT(0)
+#define CTRL_PORT_ENABLE BIT(1)
+#define CTRL_HALT_OUT_TR BIT(2)
+#define CTRL_HALT_IN_TR BIT(3)
+#define CTRL_DBC_RUN_CHANGE BIT(4)
+#define CTRL_DBC_ENABLE BIT(31)
+
+#define DCST_DEBUG_PORT(p) (((p) >> 24) & 0xff)
+
+#define PORTSC_CONN_STATUS BIT(0)
+#define PORTSC_CONN_CHANGE BIT(17)
+#define PORTSC_RESET_CHANGE BIT(21)
+#define PORTSC_LINK_CHANGE BIT(22)
+#define PORTSC_CONFIG_CHANGE BIT(23)
+
+/*
+ * xHCI Debug Capability data structures:
+ */
+struct xdbc_trb {
+ __le32 field[4];
+};
+
+struct xdbc_erst_entry {
+ __le64 seg_addr;
+ __le32 seg_size;
+ __le32 __reserved_0;
+};
+
+struct xdbc_info_context {
+ __le64 string0;
+ __le64 manufacturer;
+ __le64 product;
+ __le64 serial;
+ __le32 length;
+ __le32 __reserved_0[7];
+};
+
+struct xdbc_ep_context {
+ __le32 ep_info1;
+ __le32 ep_info2;
+ __le64 deq;
+ __le32 tx_info;
+ __le32 __reserved_0[11];
+};
+
+struct xdbc_context {
+ struct xdbc_info_context info;
+ struct xdbc_ep_context out;
+ struct xdbc_ep_context in;
+};
+
+#define XDBC_INFO_CONTEXT_SIZE 48
+#define XDBC_MAX_STRING_LENGTH 64
+#define XDBC_STRING_MANUFACTURER "Linux Foundation"
+#define XDBC_STRING_PRODUCT "Linux USB GDB Target"
+#define XDBC_STRING_SERIAL "0001"
+
+struct xdbc_strings {
+ char string0[XDBC_MAX_STRING_LENGTH];
+ char manufacturer[XDBC_MAX_STRING_LENGTH];
+ char product[XDBC_MAX_STRING_LENGTH];
+ char serial[XDBC_MAX_STRING_LENGTH];
+};
+
+#define XDBC_PROTOCOL 1 /* GNU Remote Debug Command Set */
+#define XDBC_VENDOR_ID 0x1d6b /* Linux Foundation 0x1d6b */
+#define XDBC_PRODUCT_ID 0x0011 /* __le16 idProduct; device 0011 */
+#define XDBC_DEVICE_REV 0x0010 /* 0.10 */
+
+/*
+ * xHCI Debug Capability software state structures:
+ */
+struct xdbc_segment {
+ struct xdbc_trb *trbs;
+ dma_addr_t dma;
+};
+
+#define XDBC_TRBS_PER_SEGMENT 256
+
+struct xdbc_ring {
+ struct xdbc_segment *segment;
+ struct xdbc_trb *enqueue;
+ struct xdbc_trb *dequeue;
+ u32 cycle_state;
+};
+
+/*
+ * These are the "Endpoint ID" (also known as "Context Index") values for the
+ * OUT Transfer Ring and the IN Transfer Ring of a Debug Capability Context data
+ * structure.
+ * According to the "eXtensible Host Controller Interface for Universal Serial
+ * Bus (xHCI)" specification, section "7.6.3.2 Endpoint Contexts and Transfer
+ * Rings", these should be 0 and 1, and those are the values AMD machines give
+ * you; but Intel machines seem to use the formula from section "4.5.1 Device
+ * Context Index", which is supposed to be used for the Device Context only.
+ * Luckily the values from Intel don't overlap with those from AMD, so we can
+ * just test for both.
+ */
+#define XDBC_EPID_OUT 0
+#define XDBC_EPID_IN 1
+#define XDBC_EPID_OUT_INTEL 2
+#define XDBC_EPID_IN_INTEL 3
+
+struct xdbc_state {
+ u16 vendor;
+ u16 device;
+ u32 bus;
+ u32 dev;
+ u32 func;
+ void __iomem *xhci_base;
+ u64 xhci_start;
+ size_t xhci_length;
+ int port_number;
+
+ /* DbC register base */
+ struct xdbc_regs __iomem *xdbc_reg;
+
+ /* DbC table page */
+ dma_addr_t table_dma;
+ void *table_base;
+
+ /* event ring segment table */
+ dma_addr_t erst_dma;
+ size_t erst_size;
+ void *erst_base;
+
+ /* event ring segments */
+ struct xdbc_ring evt_ring;
+ struct xdbc_segment evt_seg;
+
+ /* debug capability contexts */
+ dma_addr_t dbcc_dma;
+ size_t dbcc_size;
+ void *dbcc_base;
+
+ /* descriptor strings */
+ dma_addr_t string_dma;
+ size_t string_size;
+ void *string_base;
+
+ /* bulk OUT endpoint */
+ struct xdbc_ring out_ring;
+ struct xdbc_segment out_seg;
+ void *out_buf;
+ dma_addr_t out_dma;
+
+ /* bulk IN endpoint */
+ struct xdbc_ring in_ring;
+ struct xdbc_segment in_seg;
+ void *in_buf;
+ dma_addr_t in_dma;
+
+ u32 flags;
+
+ /* spinlock for early_xdbc_write() reentrancy */
+ raw_spinlock_t lock;
+};
+
+#define XDBC_PCI_MAX_BUSES 256
+#define XDBC_PCI_MAX_DEVICES 32
+#define XDBC_PCI_MAX_FUNCTION 8
+
+#define XDBC_TABLE_ENTRY_SIZE 64
+#define XDBC_ERST_ENTRY_NUM 1
+#define XDBC_DBCC_ENTRY_NUM 3
+#define XDBC_STRING_ENTRY_NUM 4
+
+/* Bits definitions for xdbc_state.flags: */
+#define XDBC_FLAGS_INITIALIZED BIT(0)
+#define XDBC_FLAGS_IN_STALL BIT(1)
+#define XDBC_FLAGS_OUT_STALL BIT(2)
+#define XDBC_FLAGS_IN_PROCESS BIT(3)
+#define XDBC_FLAGS_OUT_PROCESS BIT(4)
+#define XDBC_FLAGS_CONFIGURED BIT(5)
+
+#define XDBC_MAX_PACKET 1024
+
+/* Door bell target: */
+#define OUT_EP_DOORBELL 0
+#define IN_EP_DOORBELL 1
+#define DOOR_BELL_TARGET(p) (((p) & 0xff) << 8)
+
+#define xdbc_read64(regs) xhci_read_64(NULL, (regs))
+#define xdbc_write64(val, regs) xhci_write_64(NULL, (val), (regs))
+
+#endif /* __LINUX_XHCI_DBC_H */