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