diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/xhci_reg.h b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/xhci_reg.h index 0d9aede23..e3148ed8f 100644 --- a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/xhci_reg.h +++ b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/xhci_reg.h @@ -1,9 +1,504 @@ +/* + * Copyright?: (C)?2022?Phytium?Information?Technology,?Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: xhci_reg.h + * Date: 2022-07-19 09:26:25 + * LastEditTime: 2022-07-19 09:26:25 + * Description: ?This file is for xhci register definition. + * + * Modify?History: + * Ver???Who????????Date?????????Changes + * -----?------?????--------????-------------------------------------- + * 1.0 zhugengyu 2022/9/19 init commit + * 2.0 zhugengyu 2023/3/29 support usb3.0 device attached at roothub + */ + #ifndef XHCI_REG_H_ #define XHCI_REG_H_ +#include + +#if defined(__aarch64__) +#define BITS_PER_LONG 64U +#define XHCI_AARCH64 +#else +#define BITS_PER_LONG 32U +#define XHCI_AARCH32 +#endif + + +#define XHCI_GENMASK(h, l) \ + (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) + +#define XHCI_GENMASK_ULL(h, l) \ + (((~0ULL) - (1ULL << (l)) + 1) & \ + (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h)))) + +#define XHCI32_GET_BITS(x, a, b) (uint32_t)((((uint32_t)(x)) & XHCI_GENMASK(a, b)) >> b) +#define XHCI32_SET_BITS(x, a, b) (uint32_t)((((uint32_t)(x)) << b) & XHCI_GENMASK(a, b)) +#define XHCI64_GET_BITS(x, a, b) (uint64_t)((((uint64_t)(x)) & XHCI_GENMASK_ULL(a, b)) >> b) +#define XHCI64_SET_BITS(x, a, b) (uint64_t)((((uint64_t)(x)) << b) & XHCI_GENMASK_ULL(a, b)) + +/** Capability register length */ +#define XHCI_CAP_CAPLENGTH 0x00 + +/** Host controller interface version number */ +#define XHCI_CAP_HCIVERSION 0x02 + +/** Structural parameters 1 */ +#define XHCI_CAP_HCSPARAMS1 0x04 + +/** Number of device slots */ +#define XHCI_HCSPARAMS1_SLOTS(params) ( ( (params) >> 0 ) & 0xff ) + +/** Number of interrupters */ +#define XHCI_HCSPARAMS1_INTRS(params) ( ( (params) >> 8 ) & 0x3ff ) + +/** Number of ports */ +#define XHCI_HCSPARAMS1_PORTS(params) ( ( (params) >> 24 ) & 0xff ) + +/** Structural parameters 2 */ +#define XHCI_CAP_HCSPARAMS2 0x08 + +/** Number of page-sized scratchpad buffers */ +#define XHCI_HCSPARAMS2_SCRATCHPADS(params) \ + ( ( ( (params) >> 16 ) & 0x3e0 ) | ( ( (params) >> 27 ) & 0x1f ) ) + +/** Capability parameters */ +#define XHCI_CAP_HCCPARAMS1 0x10 + +/** 64-bit addressing capability */ +#define XHCI_HCCPARAMS1_ADDR64(params) ( ( (params) >> 0 ) & 0x1 ) + +/** Context size shift */ +#define XHCI_HCCPARAMS1_CSZ_SHIFT(params) ( 5 + ( ( (params) >> 2 ) & 0x1 ) ) + +/** xHCI extended capabilities pointer */ +#define XHCI_HCCPARAMS1_XECP(params) ( ( ( (params) >> 16 ) & 0xffff ) << 2 ) + +/** Doorbell offset */ +#define XHCI_CAP_DBOFF 0x14 + +/** Runtime register space offset */ +#define XHCI_CAP_RTSOFF 0x18 + +/** xHCI extended capability ID */ +#define XHCI_XECP_ID(xecp) ( ( (xecp) >> 0 ) & 0xff ) + +/** Next xHCI extended capability pointer */ +#define XHCI_XECP_NEXT(xecp) ( ( ( (xecp) >> 8 ) & 0xff ) << 2 ) + +/** USB legacy support extended capability */ +#define XHCI_XECP_ID_LEGACY 1 + +/** USB legacy support BIOS owned semaphore */ +#define XHCI_USBLEGSUP_BIOS 0x02 + +/** USB legacy support BIOS ownership flag */ +#define XHCI_USBLEGSUP_BIOS_OWNED 0x01 + +/** USB legacy support OS owned semaphore */ +#define XHCI_USBLEGSUP_OS 0x03 + +/** USB legacy support OS ownership flag */ +#define XHCI_USBLEGSUP_OS_OWNED 0x01 + +/** USB legacy support control/status */ +#define XHCI_USBLEGSUP_CTLSTS 0x04 + +/** Supported protocol extended capability */ +#define XHCI_XECP_ID_SUPPORTED 2 + +/** Supported protocol revision */ +#define XHCI_SUPPORTED_REVISION 0x00 + +/** Supported protocol minor revision */ +#define XHCI_SUPPORTED_REVISION_VER(revision) ( ( (revision) >> 16 ) & 0xffff ) + +/** Supported protocol name */ +#define XHCI_SUPPORTED_NAME 0x04 + +/** Supported protocol ports */ +#define XHCI_SUPPORTED_PORTS 0x08 + +/** Supported protocol port offset */ +#define XHCI_SUPPORTED_PORTS_OFFSET(ports) ( ( (ports) >> 0 ) & 0xff ) + +/** Supported protocol port count */ +#define XHCI_SUPPORTED_PORTS_COUNT(ports) ( ( (ports) >> 8 ) & 0xff ) + +/** Supported protocol PSI count */ +#define XHCI_SUPPORTED_PORTS_PSIC(ports) ( ( (ports) >> 28 ) & 0x0f ) + +/** Supported protocol slot */ +#define XHCI_SUPPORTED_SLOT 0x0c + +/** Supported protocol slot type */ +#define XHCI_SUPPORTED_SLOT_TYPE(slot) ( ( (slot) >> 0 ) & 0x1f ) + +/** Supported protocol PSI */ +#define XHCI_SUPPORTED_PSI(index) ( 0x10 + ( (index) * 4 ) ) + +/** Supported protocol PSI value */ +#define XHCI_SUPPORTED_PSI_VALUE(psi) ( ( (psi) >> 0 ) & 0x0f ) + +/** Supported protocol PSI mantissa */ +#define XHCI_SUPPORTED_PSI_MANTISSA(psi) ( ( (psi) >> 16 ) & 0xffff ) + +/** Supported protocol PSI exponent */ +#define XHCI_SUPPORTED_PSI_EXPONENT(psi) ( ( (psi) >> 4 ) & 0x03 ) + +/** Default PSI values */ +enum { + /** Full speed (12Mbps) */ + XHCI_SPEED_FULL = 1, + /** Low speed (1.5Mbps) */ + XHCI_SPEED_LOW = 2, + /** High speed (480Mbps) */ + XHCI_SPEED_HIGH = 3, + /** Super speed */ + XHCI_SPEED_SUPER = 4, +}; + +/** USB command register */ +#define XHCI_OP_USBCMD 0x00 + +/** Run/stop */ +#define XHCI_USBCMD_RUN 0x00000001UL + +/* Interrupter Enable (INTE) 1: enabled - RW */ +#define XHCI_USBCMD_INTE (1UL << 2) + +/** Host controller reset */ +#define XHCI_USBCMD_HCRST 0x00000002UL + +/** USB status register */ +#define XHCI_OP_USBSTS 0x04 + +/** Host controller halted */ +#define XHCI_USBSTS_HCH 0x00000001UL + +/** Interrupt Pending (IP) */ +#define XHCI_USBSTS_EINT (1UL << 3) + +/** Page size register */ +#define XHCI_OP_PAGESIZE 0x08 + +/** Page size */ +#define XHCI_PAGESIZE(pagesize) ( (pagesize) << 12 ) + +/** Device notifcation control register */ +#define XHCI_OP_DNCTRL 0x14 + +/** Command ring control register */ +#define XHCI_OP_CRCR 0x18 + +/** Command ring cycle state */ +#define XHCI_CRCR_RCS 0x00000001UL + +/** Command abort */ +#define XHCI_CRCR_CA 0x00000004UL + +/** Command ring running */ +#define XHCI_CRCR_CRR 0x00000008UL + +/** Device context base address array pointer */ +#define XHCI_OP_DCBAAP 0x30 + +/** Configure register */ +#define XHCI_OP_CONFIG 0x38 + +/** Maximum device slots enabled */ +#define XHCI_CONFIG_MAX_SLOTS_EN(slots) ( (slots) << 0 ) + +/** Maximum device slots enabled mask */ +#define XHCI_CONFIG_MAX_SLOTS_EN_MASK \ + XHCI_CONFIG_MAX_SLOTS_EN ( 0xff ) + +/** Port status and control register */ +#define XHCI_OP_PORTSC(port) ( 0x400 - 0x10 + ( (port) << 4 ) ) + +/** Current connect status */ +#define XHCI_PORTSC_CCS 0x00000001UL + +/** Port enabled */ +#define XHCI_PORTSC_PED 0x00000002UL + +#define XHCI_PORTSC_OCA (1 << 3) + +/** Port reset */ +#define XHCI_PORTSC_PR 0x00000010UL + +/** Port link state */ +#define XHCI_PORTSC_PLS(pls) ( (pls) << 5 ) + +/** U0 state */ +#define XHCI_PORTSC_PLS_U0 XHCI_PORTSC_PLS ( 0 ) + +/** Disabled port link state */ +#define XHCI_PORTSC_PLS_DISABLED XHCI_PORTSC_PLS ( 4 ) + +/** RxDetect port link state */ +#define XHCI_PORTSC_PLS_RXDETECT XHCI_PORTSC_PLS ( 5 ) + +/** Polling state */ +#define XHCI_PORTSC_PLS_POLLING XHCI_PORTSC_PLS ( 7 ) + +/** Port link state mask */ +#define XHCI_PORTSC_PLS_MASK XHCI_PORTSC_PLS ( 0xf ) + +/** Port power */ +#define XHCI_PORTSC_PP 0x00000200UL + +/** Time to delay after enabling power to a port */ +#define XHCI_PORT_POWER_DELAY_MS 20 + +/** Port speed ID value */ +#define XHCI_PORTSC_PSIV(portsc) ( ( (portsc) >> 10 ) & 0xf ) + +/** Port indicator control */ +#define XHCI_PORTSC_PIC(indicators) ( (indicators) << 14 ) + +/** Port indicator control mask */ +#define XHCI_PORTSC_PIC_MASK XHCI_PORTSC_PIC ( 3 ) + +/** Port link state write strobe */ +#define XHCI_PORTSC_LWS 0x00010000UL + +/** Time to delay after writing the port link state */ +#define XHCI_LINK_STATE_DELAY_MS 100 + +/** Connect status change */ +#define XHCI_PORTSC_CSC (1 << 17) + +/** Port enabled/disabled change */ +#define XHCI_PORTSC_PEC (1 << 18) + +/** Warm port reset change */ +#define XHCI_PORTSC_WRC (1 << 19) + +/** Over-current change */ +#define XHCI_PORTSC_OCC (1 << 20) + +/** Port reset change */ +#define XHCI_PORTSC_PRC (1 << 21) + +/** Port link state change */ +#define XHCI_PORTSC_PLC (1 << 22) + +/** Port config error change */ +#define XHCI_PORTSC_CEC (1 << 23) + +/* Cold Attach Status 1: Far-end Receiver Terminations were detected */ +#define XHCI_PORTSC_CAS (1 << 24) + +/* Wake on Connect Enable 1: enable port to be sensitive to device connects */ +#define XHCI_PORTSC_WCE (1 << 25) + +/* Wake on Disconnect Enable 1: enable port to be sensitive to device disconnects */ +#define XHCI_PORTSC_WDE (1 << 26) + +/* Wake on Over-current Enable 1: enable port to be sensitive to over-current conditions */ +#define XHCI_PORTSC_WOE (1 << 27) + +/* Device Removable, 0: Device is removable. 1: Device is non-removable */ +#define XHCI_PORTSC_DR (1 << 30) + +/* Warm Port Reset 1: follow Warm Reset sequence */ +#define XHCI_PORTSC_WPR (1 << 31) + +/** Port status change mask */ +#define XHCI_PORTSC_CHANGE \ + ( XHCI_PORTSC_CSC | XHCI_PORTSC_PEC | XHCI_PORTSC_WRC | \ + XHCI_PORTSC_OCC | XHCI_PORTSC_PRC | XHCI_PORTSC_PLC | \ + XHCI_PORTSC_CEC ) + +#define XHCI_PORTSC_RW_MASK (XHCI_PORTSC_PR | XHCI_PORTSC_PLS_MASK | XHCI_PORTSC_PP \ + | XHCI_PORTSC_PIC_MASK | XHCI_PORTSC_LWS | XHCI_PORTSC_WCE \ + | XHCI_PORTSC_WDE | XHCI_PORTSC_WOE) + +/** Port status and control bits which should be preserved + * + * The port status and control register is a horrendous mix of + * differing semantics. Some bits are written to only when a separate + * write strobe bit is set. Some bits should be preserved when + * modifying other bits. Some bits will be cleared if written back as + * a one. Most excitingly, the "port enabled" bit has the semantics + * that 1=enabled, 0=disabled, yet writing a 1 will disable the port. + */ +#define XHCI_PORTSC_PRESERVE ( XHCI_PORTSC_PP | XHCI_PORTSC_PIC_MASK ) + +/** Port power management status and control register */ +#define XHCI_OP_PORTPMSC(port) ( 0x404 - 0x10 + ( (port) << 4 ) ) + +/** Port link info register */ +#define XHCI_OP_PORTLI(port) ( 0x408 - 0x10 + ( (port) << 4 ) ) + +/** Port hardware link power management control register */ +#define XHCI_OP_PORTHLPMC(port) ( 0x40c - 0x10 + ( (port) << 4 ) ) + +/* Doorbell registers are 32 bits in length */ +#define XHCI_REG_DB_SIZE 4 + +/** Interrupter Management Register */ +#define XHCI_RUN_IR_IMAN(intr) ( 0x20 + ( (intr) << 5 ) ) + +/* Interrupt Pending, 1: an interrupt is pending for this Interrupter */ +#define XHCI_RUN_IR_IMAN_IP (1 << 0) + +/* Interrupt Enable, 1: capable of generating an interrupt. */ +#define XHCI_RUN_IR_IMAN_IE (1 << 1) + +/** Interrupter Moderation Register */ +#define XHCI_RUN_IR_IMOD(intr) ( 0x24 + ( (intr) << 5 ) ) + +/** Event ring segment table size register */ +#define XHCI_RUN_ERSTSZ(intr) ( 0x28 + ( (intr) << 5 ) ) + +/** Event ring segment table base address register */ +#define XHCI_RUN_ERSTBA(intr) ( 0x30 + ( (intr) << 5 ) ) + +/** Event ring dequeue pointer register */ +#define XHCI_RUN_ERDP(intr) ( 0x38 + ( (intr) << 5 ) ) + +/** Event Handler Busy */ +#define XHCI_RUN_ERDP_EHB (1 << 3) + +/** Minimum alignment required for data structures + * + * With the exception of the scratchpad buffer pages (which are + * page-aligned), data structures used by xHCI generally require from + * 16 to 64 byte alignment and must not cross an (xHCI) page boundary. + * We simplify this requirement by aligning each structure on its own + * size, with a minimum of a 64 byte alignment. + */ +#define XHCI_MIN_ALIGN 64 + +/** Maximum transfer size */ +#define XHCI_MTU 65536 + +/** Read/Write Data Barrier for ARM */ +#define BARRIER() __asm__ __volatile__("": : :"memory") + +#ifdef XHCI_AARCH64 +#define DSB() __asm__ __volatile__("dsb sy": : : "memory") +#else +#define DSB() __asm__ __volatile__("dsb": : : "memory") +#endif +/** + * Read byte from memory-mapped device + * + * @v io_addr I/O address + * @ret data Value read + */ +static inline uint8_t readb(void *io_addr ) { + uint8_t val = *(volatile const uint8_t *)io_addr; + BARRIER(); + return val; +} + +/** + * Read 16-bit word from memory-mapped device + * + * @v io_addr I/O address + * @ret data Value read + */ +static inline uint16_t readw(void * io_addr ) { + uint16_t val = *(volatile const uint16_t *)io_addr; + BARRIER(); + return val; +} + +/** + * Read 32-bit dword from memory-mapped device + * + * @v io_addr I/O address + * @ret data Value read + */ +static inline uint32_t readl(void * io_addr ) { + uint32_t val = *(volatile const uint32_t *)io_addr; + BARRIER(); + return val; +} + +/** + * Read 64-bit qword from memory-mapped device + * + * @v io_addr I/O address + * @ret data Value read + */ +static inline uint64_t readq(void * io_addr ) { + uint64_t val = *(volatile const uint64_t *)io_addr; + BARRIER(); + return val; +} + +/** + * Write byte to memory-mapped device + * + * @v data Value to write + * @v io_addr I/O address + */ +static inline void writeb(uint8_t data, void * io_addr ) { + BARRIER(); + *(volatile uint8_t *)io_addr = data; +} + +/** + * Write 16-bit word to memory-mapped device + * + * @v data Value to write + * @v io_addr I/O address + */ +static inline void writew(uint16_t data, void * io_addr ) { + BARRIER(); + *(volatile uint16_t *)io_addr = data; +} + +/** + * Write 32-bit dword to memory-mapped device + * + * @v data Value to writed + * @v io_addr I/O address + */ +static inline void writel(uint32_t data, void * io_addr ) { + BARRIER(); + *(volatile uint32_t *)io_addr = data; +} + +/** + * Write 64-bit qword to memory-mapped device + * + * @v data Value to write + * @v io_addr I/O address + */ +static inline void writeq(uint64_t data, void * io_addr ) { + BARRIER(); + *(volatile uint64_t *)io_addr = data; +} + +/** + * Byte-order converter for ARM-Little-End + */ +#define CPU_TO_LE64(x) ((uint64_t)(x)) +#define LE64_to_CPU(x) ((uint64_t)(x)) +#define CPU_TO_LE32(x) ((uint32_t)(x)) +#define LE32_TO_CPU(x) ((uint32_t)(x)) +#define CPU_TO_LE16(x) ((uint16_t)(x)) +#define LE16_TO_CPU(x) ((uint16_t)(x)) #endif