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