2022-11-10 22:22:48 +08:00
/*
* 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 : fxhci_hw . h
* Date : 2022 - 02 - 11 13 : 33 : 12
* LastEditTime : 2022 - 02 - 18 09 : 13 : 47
* Description : This files is for definition of XHCI hardware register interface
*
* Modify History :
* Ver Who Date Changes
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2023-05-11 10:25:21 +08:00
* 1.0 zhugengyu 2022 / 2 / 7 init commit
2022-11-10 22:22:48 +08:00
*/
2023-05-11 10:25:21 +08:00
# ifndef FXHCI_HW_H
# define FXHCI_HW_H
2022-11-10 22:22:48 +08:00
/***************************** Include Files *********************************/
# include "fio.h"
# include "fassert.h"
# include "fkernel.h"
2023-05-11 10:25:21 +08:00
# ifdef __cplusplus
extern " C "
{
# endif
2022-11-10 22:22:48 +08:00
/************************** Constant Definitions *****************************/
/** @name Register Map
*
* Register offsets from the base address of an SD device .
* @ {
*/
/***************** eXtensible Host Controller Capability Registers ***********************/
# define FXHCI_REG_CAP_CAPLENGTH 0x00 /* specify the limits, restrictions and capabilities */
# define FXHCI_REG_CAP_HCIVERSION 0x02 /* Interface Version Number */
# define FXHCI_REG_CAP_HCSPARAMS1 0x04 /* Host Controller Structural Parameters 1 */
# define FXHCI_REG_CAP_HCSPARAMS2 0x08 /* Host Controller Structural Parameters 2 */
# define FXHCI_REG_CAP_HCSPARAMS3 0x0C /* Host Controller Structural Parameters 3 */
# define FXHCI_REG_CAP_HCCPARAMS 0x10 /* Capability Parameters 1 */
# define FXHCI_REG_CAP_DBOFF 0x14 /* Doorbell Offset Register */
# define FXHCI_REG_CAP_RTSOFF 0x18 /* Runtime Register Space Offset Register */
/***************** Host Controller Operational Registers ***********************/
# define FXHCI_REG_OP_USBCMD 0x00 /* USB Command Register */
# define FXHCI_REG_OP_USBSTS 0x04 /* USB Status Register */
# define FXHCI_REG_OP_PAGESIZE 0x08 /* Page Size Register */
# define FXHCI_REG_OP_DNCTRL 0x14 /* Device Notification Control Register */
# define FXHCI_REG_OP_CRCR 0x18 /* Command Ring Control Register */
# define FXHCI_REG_OP_DCBAAP 0x30 /* Device Context Base Address Array Pointer Register */
# define FXHCI_REG_OP_CONFIG 0x38 /* Configure Register */
/* Port Status and Ctrl Register : OP Base + (400h + (10h * (n– 1))) 'n' is port num */
# define FXHCI_REG_OP_PORTS_BASE 0x400 /* Port Status and Control Register Base */
# define FXHCI_REG_OP_PORTS_SIZE 0x10 /* Size of one Port SC Register */
# define FXHCI_REG_OP_PORTS_PORTSC 0x00 /* Port Status and Control Register */
# define FXHCI_REG_OP_PORTS_PORTPMSC 0x04 /* USB3 Port Power Management Status and Control Register */
# define FXHCI_REG_OP_PORTS_PORTLI 0x08 /* Port Link Info Register */
/***************** Host Controller Runtime Registers ***********************/
# define FXHCI_REG_RT_MFINDEX 0x00 /* Microframe Index */
# define FXHCI_REG_RT_IR0 0x20 /* Interrupter Register Set 0 */
# define FXHCI_REG_RT_IR1023 0x8000 /* Interrupter Register Set 1023 */
/* Interrupter Register Set : RT Base + 020h + (32 * Interrupter) */
# define FXHCI_REG_RT_IR_SIZE 0x20 /* Size of one IR Register */
# define FXHCI_REG_RT_IR_IMAN 0x00 /* Interrupter Management Register */
# define FXHCI_REG_RT_IR_IMOD 0x04 /* Interrupter Moderation Register */
# define FXHCI_REG_RT_IR_ERSTSZ 0x08 /* Event Ring Segment Table Size Register */
# define FXHCI_REG_RT_IR_ERSTBA 0x10 /* Event Ring Segment Table Base Address Register */
# define FXHCI_REG_RT_IR_ERDP 0x18 /* Event Ring Dequeue Pointer Register */
/***************** Doorbell Register ***********************/
# define FXHCI_REG_DB_SIZE 4 /* Doorbell registers are 32 bits in length */
/***************** eXtensible Host Controller Capability Registers ***********************/
/** @name FXHCI_REG_CAP_HCSPARAMS1 Register
*/
# define FXHCI_REG_CAP_HCSPARAMS1_MAX_SLOTS_GET(x) FUSB_REG32_GET_BITS(x, 7, 0) /* Number of Device Slots (MaxSlots) */
# define FXHCI_REG_CAP_HCSPARAMS1_MAX_INTRS_GET(x) FUSB_REG32_GET_BITS(x, 18, 8) /* Number of Interrupters (MaxIntrs) */
# define FXHCI_REG_CAP_HCSPARAMS1_MAX_PORTS_GET(x) FUSB_REG32_GET_BITS(x, 31, 24) /* Number of Ports (MaxPorts) */
/** @name FXHCI_REG_CAP_HCSPARAMS2 Register
*/
# define FXHCI_REG_CAP_HCSPARAMS2_IST_GET(x) FUSB_REG32_GET_BITS(x, 3, 0) /* Isochronous Scheduling Threshold (IST) */
# define FXHCI_REG_CAP_HCSPARAMS2_ERST_MAX_GET(x) FUSB_REG32_GET_BITS(x, 7, 4) /* Event Ring Segment Table Max (ERST Max) */
# define FXHCI_REG_CAP_HCSPARAMS2_SPR (1 << 26) /* Scratchpad Restore (SPR) */
# define FXHCI_REG_CAP_HCSPARAMS2_MAX_SCRATCHPAD_BUFS_GET(x) FUSB_REG32_GET_BITS(x, 31, 27) /* Max Scratchpad Buffers (Max Scratchpad Bufs) */
/** @name FXHCI_REG_CAP_HCSPARAMS3 Register
*/
# define FXHCI_REG_CAP_HCSPARAMS3_U1_DEV_EXIT_LATENCY_GET(x) FUSB_REG32_GET_BITS(x, 7, 0) /* U1 Device Exit Latency */
# define FXHCI_REG_CAP_HCSPARAMS3_U2_DEV_EXIT_LATENCY_GET(x) FUSB_REG32_GET_BITS(x, 31, 16) /* U2 Device Exit Latency */
/** @name FXHCI_REG_CAP_HCCPARAMS Register
*/
# define FXHCI_REG_CAP_HCCPARAMS_AC64 (1 << 0) /* 64-bit Addressing Capabilitya 1: 64-bit */
# define FXHCI_REG_CAP_HCCPARAMS_BNC (1 << 1) /* BW Negotiation Capability (BNC) 1: support */
# define FXHCI_REG_CAP_HCCPARAMS_CSZ (1 << 2) /* Context Size (CSZ) 1: 64 byte context data */
# define FXHCI_REG_CAP_HCCPARAMS_PPC (1 << 3) /* Port Power Control (PPC) 1: support */
# define FXHCI_REG_CAP_HCCPARAMS_PIND (1 << 4) /* Port Indicators (PIND) 1: support */
# define FXHCI_REG_CAP_HCCPARAMS_LHRC (1 << 5) /* Light HC Reset Capability (LHRC) 1: support */
# define FXHCI_REG_CAP_HCCPARAMS_LTC (1 << 6) /* Latency Tolerance Messaging Capability (LTC) */
# define FXHCI_REG_CAP_HCCPARAMS_NSS (1 << 7) /* No Secondary SID Support (NSS) */
# define FXHCI_REG_CAP_HCCPARAMS_MAX_PSA_SIZE_GET(x) FUSB_REG32_GET_BITS(x, 15, 12) /* Maximum Primary Stream Array Size (MaxPSASize) */
# define FXHCI_REG_CAP_HCCPARAMS_XECP_GET(x) FUSB_REG32_GET_BITS(x, 31, 16) /* xHCI Extended Capabilities Pointer (xECP) */
/** @name FXHCI_REG_CAP_DBOFF Register
*/
# define FXHCI_REG_CAP_DBOFF_GET(x) ((x) & GENMASK(31, 2)) /* 32-byte offset of the Doorbell Array base address from the Base */
/** @name FXHCI_REG_CAP_RTSOFF Register
*/
# define FXHCI_REG_CAP_RTSOFF_GET(x) ((x) & GENMASK(31, 5)) /* 32-byte offset of the xHCI Runtime Registers */
/***************** Host Controller Operational Registers ***********************/
/** @name FXHCI_REG_OP_USBCMD Register
*/
# define FXHCI_REG_OP_USBCMD_RUN_STOP (1 << 0) /* Run/Stop (R/S) 1: RUN, 0: STOP - RW */
# define FXHCI_REG_OP_USBCMD_HCRST (1 << 1) /* Host Controller Reset (HCRST) 1: RESET - RW */
# define FXHCI_REG_OP_USBCMD_INTE (1 << 2) /* Interrupter Enable (INTE) 1: enabled - RW */
# define FXHCI_REG_OP_USBCMD_HSEE (1 << 3) /* Host System Error Enable (HSEE) - RW */
# define FXHCI_REG_OP_USBCMD_LHCRST (1 << 7) /* Light Host Controller Reset (LHCRST) - RW */
# define FXHCI_REG_OP_USBCMD_CSS (1 << 8) /* Controller Save State (CSS) - RW */
# define FXHCI_REG_OP_USBCMD_CRS (1 << 9) /* Controller Restore State (CRS) - RW */
# define FXHCI_REG_OP_USBCMD_EWE (1 << 10) /* Enable Wrap Event (EWE) - RW */
# define FXHCI_REG_OP_USBCMD_EU3S (1 << 11) /* Enable U3 MFINDEX Stop (EU3S) - RW */
/** @name FXHCI_REG_OP_USBSTS Register
*/
# define FXHCI_REG_OP_USBSTS_HCH (1 << 0) /* 1: Stopped executing */
# define FXHCI_REG_OP_USBSTS_HSE (1 << 2) /* 1: Serious error detected */
# define FXHCI_REG_OP_USBSTS_EINT (1 << 3) /* 1: Interrupt Pending (IP) */
# define FXHCI_REG_OP_USBSTS_PCD (1 << 4) /* 1: Port Change Detect */
# define FXHCI_REG_OP_USBSTS_SSS (1 << 8) /* remain 1 while the xHC saves its internal state */
# define FXHCI_REG_OP_USBSTS_RSS (1 << 9) /* remain 1 while the xHC restores its internal state */
# define FXHCI_REG_OP_USBSTS_SRE (1 << 10) /* if error occurs during a Save or Restore operation this bit shall be set to ‘ 1’ . */
# define FXHCI_REG_OP_USBSTS_CNR (1 << 11) /* 1: Controller Not Ready */
# define FXHCI_REG_OP_USBSTS_HCE (1 << 12) /* 1: Internal xHC error condition */
# define FXHCI_REG_OP_USBSTS_PRSRV_MASK ((1 << 1) | 0xffffe000) /* Rsvd bits */
/** @name FXHCI_REG_OP_PAGESIZE Register
*/
/* This xHC supports a page size of 2^(n+12) if bit n is Set */
# define FXHCI_REG_OP_PAGESIZE_4K (1 << 0) /* if bit 0 is Set, the xHC supports 4k byte page sizes */
/** @name FXHCI_REG_OP_CRCR Register
*/
# define FXHCI_REG_OP_CRCR_RCS (1 << 0) /* Ring Cycle State, value of the xHC Consumer Cycle State (CCS) flag */
# define FXHCI_REG_OP_CRCR_CS (1 << 1) /* Command Stop, 1 */
# define FXHCI_REG_OP_CRCR_CA (1 << 2) /* Command Abort, 1 */
# define FXHCI_REG_OP_CRCR_CRR (1 << 3) /* Command Ring Running */
# define FXHCI_REG_OP_CRCR_CR_PTR_MASK GENMASK_ULL(63, 6) /* Command Ring Pointer, Dequeue Ptr of Command Ring */
/** @name FXHCI_REG_OP_DCBAAP Register
*/
# define FXHCI_REG_OP_DCBAAP_MASK GENMASK_ULL(63, 6) /* bit[31:6] Ptr of DCBAA */
/** @name FXHCI_REG_OP_CONFIG Register
*/
# define FXHCI_REG_OP_CONFIG_MAX_SLOTS_EN_MASK GENMASK(7, 0) /* Max Device Slots Enabled (MaxSlotsEn) – RW */
# define FXHCI_REG_OP_CONFIG_MAX_SLOTS_EN_SET(x) FUSB_REG32_SET_BITS(x, 7, 0) /* bit[7:0] Max Device Slots Enabled */
# define FXHCI_REG_OP_CONFIG_MAX_SLOTS_EN_GET(x) FUSB_REG32_GET_BITS(x, 7, 0)
/** @name FXHCI_REG_OP_PORTS_PORTSC Register
*/
# define FXHCI_REG_OP_PORTS_PORTSC_CCS (1 << 0) /* Current Connect Status (CCS) – ROS */
# define FXHCI_REG_OP_PORTS_PORTSC_PED (1 << 1) /* Port Enabled/Disabled (PED) – RW1CS */
# define FXHCI_REG_OP_PORTS_PORTSC_OCA (1 << 3) /* Over-current Active (OCA) – RO */
# define FXHCI_REG_OP_PORTS_PORTSC_PR (1 << 4) /* Port Reset (PR) – RW1S */
# define FXHCI_REG_OP_PORTS_PORTSC_PLS_GET(x) FUSB_REG32_GET_BITS(x, 8, 5) /* Port Link State (PLS) – RWS */
# define FXHCI_REG_OP_PORTS_PORTSC_PLS_SET(x) FUSB_REG32_SET_BITS(x, 8, 5)
# define FXHCI_REG_OP_PORTS_PORTSC_PLS_MASK GENMASK(8, 5)
# define FXHCI_REG_OP_PORTS_PORTSC_PLS(x) (x << 5)
/* Read value of Port Link State (PLS) */
/* refer to FXHCI doc page-408 for details (Port Link State) */
enum
{
FXHCI_LINK_STATE_U0 = 0 , /* U0 State */
FXHCI_LINK_STATE_U1 = 1 , /* U1 State */
FXHCI_LINK_STATE_U2 = 2 , /* U2 State */
FXHCI_LINK_STATE_U3 = 3 , /* U3 State (Device Suspended) */
FXHCI_LINK_STATE_DISABLED = 4 , /* Disabled State */
FXHCI_LINK_STATE_RX_DETECT = 5 , /* RxDetect State (Disconnected) */
FXHCI_LINK_STATE_INACTIVE = 6 , /* Inactive State */
FXHCI_LINK_STATE_POLLING = 7 , /* Polling State */
FXHCI_LINK_STATE_RECOVERY = 8 , /* Recovery State */
FXHCI_LINK_STATE_HOT_RESET = 9 , /* Hot Reset State */
FXHCI_LINK_STATE_COMPLIANCE_MODE = 10 , /* Compliance Mode State */
FXHCI_LINK_STATE_TEST_MODE = 11 , /* Test Mode State */
FXHCI_LINK_STATE_RESUME = 15 , /* Resume State */
FXHCI_LINK_STATE_MAX
} ;
# define FXHCI_REG_OP_PORTS_PORTSC_PLS_SET(x) FUSB_REG32_SET_BITS(x, 8, 5)
# define FXHCI_REG_OP_PORTS_PORTSC_PP (1 << 9) /* Port Power (PP) – RWS */
# define FXHCI_REG_OP_PORTS_PORTSC_PORT_SPEED_GET(x) FUSB_REG32_GET_BITS(x, 13, 10) /* Port Speed (Port Speed) – ROS */
/* Protocol Speed ID (PSI) 1~15 */
enum
{
FXHCI_PORT_SPEED_UNDEFINED = 0 ,
FXHCI_PORT_SPEED_1 = 1 ,
FXHCI_PORT_SPEED_15 = 15 ,
} ;
# define FXHCI_REG_OP_PORTS_PORTSC_PIC_SET(x) FUSB_REG32_SET_BITS(x, 15, 14)
# define FXHCI_REG_OP_PORTS_PORTSC_PIC_MASK GENMASK(15, 14)
enum
{
FXHCI_PORT_INDICATOR_OFF = 0 ,
FXHCI_PORT_INDICATOR_AMBER = 1 ,
FXHCI_PORT_INDICATOR_GREEN = 2 ,
FXHCI_PORT_INDICATOR_UNDEFINED = 3
} ;
# define FXHCI_REG_OP_PORTS_PORTSC_LWS (1 << 16) /* Port Link State Write Strobe (LWS) */
# define FXHCI_REG_OP_PORTS_PORTSC_CSC (1 << 17) /* Connect Status Change (CSC) */
# define FXHCI_REG_OP_PORTS_PORTSC_PEC (1 << 18) /* Port Enabled/Disabled Change (PEC) 1: clear PED */
# define FXHCI_REG_OP_PORTS_PORTSC_WRC (1 << 19) /* Warm Port Reset Change 1: Warm Reset complete */
# define FXHCI_REG_OP_PORTS_PORTSC_OCC (1 << 20) /* Over-current Change 1: Over-current Active */
# define FXHCI_REG_OP_PORTS_PORTSC_PRC (1 << 21) /* Port Reset Change 1: Transition of Port Reset */
# define FXHCI_REG_OP_PORTS_PORTSC_PLC (1 << 22) /* Port Link State Change 1: PLS transition */
# define FXHCI_REG_OP_PORTS_PORTSC_CEC (1 << 23) /* Port Config Error Change 1: Port Config Error detected */
# define FXHCI_REG_OP_PORTS_PORTSC_CAS (1 << 24) /* Cold Attach Status 1: Far-end Receiver Terminations were detected */
# define FXHCI_REG_OP_PORTS_PORTSC_WCE (1 << 25) /* Wake on Connect Enable 1: enable port to be sensitive to device connects */
# define FXHCI_REG_OP_PORTS_PORTSC_WDE (1 << 26) /* Wake on Disconnect Enable 1: enable port to be sensitive to device disconnects */
# define FXHCI_REG_OP_PORTS_PORTSC_WOE (1 << 27) /* Wake on Over-current Enable 1: enable port to be sensitive to over-current conditions */
# define FXHCI_REG_OP_PORTS_PORTSC_DR (1 << 30) /* Device Removable, 0: Device is removable. 1: Device is non-removable */
# define FXHCI_REG_OP_PORTS_PORTSC_WPR (1 << 31) /* Warm Port Reset 1: follow Warm Reset sequence */
# define FXHCI_REG_OP_PORTS_PORTSC_RW_MASK (FXHCI_REG_OP_PORTS_PORTSC_PR | FXHCI_REG_OP_PORTS_PORTSC_PLS_MASK | FXHCI_REG_OP_PORTS_PORTSC_PP \
2023-05-11 10:25:21 +08:00
| FXHCI_REG_OP_PORTS_PORTSC_PIC_MASK | FXHCI_REG_OP_PORTS_PORTSC_LWS | FXHCI_REG_OP_PORTS_PORTSC_WCE \
| FXHCI_REG_OP_PORTS_PORTSC_WDE | FXHCI_REG_OP_PORTS_PORTSC_WOE )
2022-11-10 22:22:48 +08:00
/***************** Host Controller Runtime Registers ***********************/
/** @name FXHCI_REG_RT_IR_IMAN Register
*/
# define FXHCI_REG_RT_IR_IMAN_IP (1 << 0) /* Interrupt Pending, 1: an interrupt is pending for this Interrupter */
# define FXHCI_REG_RT_IR_IMAN_IE (1 << 1) /* Interrupt Enable, 1: capable of generating an interrupt. */
/** @name FXHCI_REG_RT_IR_IMOD Register
*/
# define FXHCI_REG_RT_IR_IMOD_IMODI_MASK GENMASK(15, 0) /* bit[15:0] Interrupt Moderation Interval default 4000 ==> 1ms */
# define FXHCI_REG_RT_IR_IMOD_IMODC_MASK GENMASK(31, 16) /* bit[31:16] Interrupt Moderation Counter(Down counter) */
/** @name FXHCI_REG_RT_IR_ERSTSZ Register
*/
# define FXHCI_REG_RT_IR_ERSTSZ_MASK GENMASK(15, 0) /* bit[15:0] the number of valid Event Ring Segment Table entries */
/** @name FXHCI_REG_RT_IR_ERSTBA Register
*/
# define FXHCI_REG_RT_IR_ERSTBA_MASK GENMASK_ULL(63, 6) /* Event Ring Segment Table Base Address */
/** @name FXHCI_REG_RT_IR_ERDP Register
*/
# define FXHCI_REG_RT_IR_ERDP_DESI_MASK GENMASK_ULL(2, 0) /* bit[2:0] Dequeue ERST Segment Index */
# define FXHCI_REG_RT_IR_ERDP_EHB (1 << 3) /* Event Handler Busy */
# define FXHCI_REG_RT_IR_ERDP_MASK GENMASK_ULL(63, 4) /* Event Ring Dequeue Pointer */
/***************** Doorbell Register ***********************/
# define FXHCI_REG_DB_TARGET_HC_COMMAND 0 /* Host Controller Doorbell (0) Command Doorbell */
# define FXHCI_REG_DB_TARGET_EP0 1 /* Device Context Doorbells Control EP 0 Enqueue Pointer Update */
# define FXHCI_REG_DB_TARGET_EP1_OUT 2 /* EP 1 OUT Enqueue Pointer Update */
# define FXHCI_REG_DB_TARGET_EP1_IN 3 /* EP 1 IN Enqueue Pointer Update */
# define FXHCI_REG_DB_TARGET_EP15_OUT 30 /* EP 15 OUT Enqueue Pointer Update */
# define FXHCI_REG_DB_TARGET_EP15_IN 31 /* EP 15 IN Enqueue Pointer Update */
/***************** xHCI Extended Capabilities Registers ***********************/
# define FXHCI_REG_EXT_CAP_CAP_ID_GET(x) FUSB_REG32_GET_BITS(x, 7, 0)
/* refer to 'Table 138: xHCI Extended Capability Codes' for more details */
enum
{
FXHCI_EXT_CAP_ID_USB_LEGACY_SUPPORT = 1 ,
FXHCI_EXT_CAP_ID_SUPPORT_PROTOCOL = 2 ,
FXHCI_EXT_CAP_ID_EXTEND_POWER_MANAGEMENT = 3 ,
FXHCI_EXT_CAP_ID_IO_VIRTUALIZATION = 4 ,
FXHCI_EXT_CAP_ID_MESSAGE_INTERRUPT = 5 ,
FXHCI_EXT_CAP_ID_LOCAL_MEMORY = 6 ,
FXHCI_EXT_CAP_ID_USB_DEBUG_CAPABILITY = 10 ,
FXHCI_EXT_CAP_ID_EXT_MESSAGE_INTERRUPT = 17 ,
FXHCI_EXT_CAP_ID_VENDOR_DEFINED_MIN = 192 ,
FXHCI_EXT_CAP_ID_VENDOR_DEFINED_MAX = 255
} ;
# define FXHCI_REG_EXT_CAP_NEXT_CAP_PTR_GET(x) FUSB_REG32_GET_BITS(x, 15, 8)
# define FXHCI_REG_EXT_CAP_CAP_SPEC_GET(x) FUSB_REG32_GET_BITS(x, 31, 16)
/* Ext capabilities specific definitions */
/* USB Legacy Support Capability */
# define FXHCI_REG_EXT_CAP_USBLEGSUP_OFFSET 0x0 /* used by pre-OS software (BIOS) and the operating system to coordinate ownership of the xHC. */
# define FXHCI_USBLEGSUP_BIOS_OWNED_SEMAPHORE (1 << 16) /* RW, The BIOS sets this bit to establish ownership of the xHC */
# define FXHCI_USBLEGSUP_OS_OWNED_SEMAPHORE (1 << 24) /* RW, System software sets this bit to request ownership of the xHC */
# define FXHCI_REG_EXT_CAP_USBLEGCTLSTS_OFFSET 0x4 /* uses this register to enable System Management Interrupts (SMIs) for every xHCI/USB event it needs to track */
# define FXHCI_USBLEGCTLSTS_USB_SMI_EN (1 << 0) /* RW, enable interrupts to trach event */
# define FXHCI_USBLEGCTLSTS_SMI_HC_ERR_EN (1 << 4) /* RW */
# define FXHCI_USBLEGCTLSTS_SMI_OS_OWE_EN (1 << 13) /* RW */
# define FXHCI_USBLEGCTLSTS_SMI_PCI_CMD_EN (1 << 14) /* RW */
# define FXHCI_USBLEGCTLSTS_SMI_BAR_EN (1 << 15) /* RW */
# define FXHCI_USBLEGCTLSTS_SMI_EVT_INTERRUPT (1 << 16) /* RO */
# define FXHCI_USBLEGCTLSTS_SMI_HC_SYS_ERR (1 << 20) /* RO */
# define FXHCI_USBLEGCTLSTS_SMI_OS_OWN_CHG (1 << 29) /* RW1C */
# define FXHCI_USBLEGCTLSTS_SMI_PCI_CMD (1 << 30) /* RW1C */
# define FXHCI_USBLEGCTLSTS_SMI_BAR (1 << 31) /* RW1C */
/* xHCI Supported Protocol Capability */
# define FXHCI_REG_EXT_CAP_USBSPCF_OFFSET 0x0
# define FXHCI_USBSPCF_MINOR_REVERSION_GET(x) FUSB_REG32_GET_BITS(x, 23, 16)
# define FXHCI_USBSPCF_MAJOR_REVERSION_GET(x) FUSB_REG32_GET_BITS(x, 31, 24)
enum
{
FXHCI_MAJOR_REVERSION_USB2 = 2 ,
FXHCI_MAJOR_REVERSION_USB3 = 3
} ;
# define FXHCI_REG_EXT_CAP_USBSPCFDEF_OFFSET 0x4
# define FXHCI_USBSPCFDEF_NAME_STRING_GET(x) FUSB_REG32_GET_BITS(x, 31, 0) /* four ASCII characters may be defined */
# define FXHCI_USBSPCFDEF_NAME_STRING_USB 0x20425355 /* ASCII = "USB" */
# define FXHCI_REG_EXT_CAP_USBSPCFDEF2_OFFSET 0x8
# define FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_OFF_GET(x) FUSB_REG32_GET_BITS(x, 7, 0)
# define FXHCI_USBSPCFDEF2_COMPATIBLE_PORT_CNT_GET(x) FUSB_REG32_GET_BITS(x, 15, 8)
# define FXHCI_USBSPCFDEF2_PROTOCOL_DEFINED_GET(x) FUSB_REG32_GET_BITS(x, 27, 16)
/* USB3 - No Protocol Defined fields */
/* USB2 */
# define FXHCI_USBSPCFDEF2_USB2_HIGH_SPEED_ONLY (1 << 17) /* High-speed Only (HSO) - RO */
# define FXHCI_USBSPCFDEF2_USB2_INTERGRATED_HUB (1 << 18) /* Integrated Hub Implemented (IHI) - RO */
# define FXHCI_USBSPCFDEF2_USB2_HW_LMP_CAP (1 << 19) /* Hardware LMP Capability (HLC) - RO */
# define FXHCI_USBSPCFDEF2_PROTOCOL_SPEED_ID_CNT_GET(x) FUSB_REG32_GET_BITS(x, 31, 28)
/* Protocol Speed ID (PSI) */
# define FXHCI_REG_PROTOCOL_SPEED_ID_OFFSET(psic) (0xc + ((psic) * sizeof(u32)))
# define FXHCI_PROTOCOL_SPEED_ID_VALUE_GET(x) FUSB_REG32_GET_BITS(x, 3, 0) /* Protocol Speed ID Value (PSIV) */
# define FXHCI_PROTOCOL_SPEED_ID_EXPONENT_GET(x) FUSB_REG32_GET_BITS(x, 5, 4) /* Protocol Speed ID Exponent (PSIE) */
# define FXHCI_PROTOCOL_SPEED_ID_PSI_TYPE_GET(x) FUSB_REG32_GET_BITS(x, 7, 6) /* PSI Type (PLT) */
enum
{
FXHCI_PROTOCOL_SPEED_ID_PSI_SYMMETRIC = 0 ,
FXHCI_PROTOCOL_SPEED_ID_PSI_ASYMMETRIC_RX = 2 ,
FXHCI_PROTOCOL_SPEED_ID_PSI_ASYMMETRIC_TX = 3
} ;
# define FXHCI_PROTOCOL_SPEED_ID_PSI_FULL_DUPLEX (1 << 8)
# define FXHCI_PROTOCOL_SPEED_ID_MANTISSA_GET(x) FUSB_REG32_GET_BITS(x, 31, 16) /* Protocol Speed ID Mantissa (PSIM) */
/**************************** Type Definitions *******************************/
/* Device Context Base Address Array */
# define FXHCI_SCRATCHPAD_BUF_ARRAY_BASE_ADDR_MASK GENMASK_ULL(63, 6) /* Array Element 0 Field Bit */
# define FXHCI_DEVICE_CONTEXT_BASE_ADDR_MASK GENMASK_ULL(63, 6) /* Array Element 1-n Field Bit */
/* Slot index */
# define FXHCI_REG_DB_HOST_CONTROLLER 0
# define FXHCI_REG_DB_DEVICE_CONTEXT1 1
# define FXHCI_REG_DB_DEVICE_CONTEXT255 255
typedef struct
{
u8 port_beg ;
u8 port_end ;
} FXhciPortRange ;
typedef enum
{
FXHCI_USB2_COMPATIBLE_PORT ,
FXHCI_USB3_COMPATIBLE_PORT ,
FXHCI_NONE_COMPATIBLE_PORT
} FXhciPortCompatible ;
typedef struct
{
uintptr base ; /* Capability registers offset */
uintptr oper_base ; /* Operational registers offset */
uintptr doorbell_base ; /* Doorbell registers offset */
uintptr runtime_base ; /* Runtime registers offset */
uintptr port_base ; /* Port register set offset */
uintptr xecp_base ; /* xHCI Extended Capabilities register offset */
u32 hcx_params [ 4 ] ; /* Capability cache */
FXhciPortRange usb2_ports ;
FXhciPortRange usb3_ports ;
} FXhciMMIO ;
/************************** Variable Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
static inline FXhciPortCompatible FUsb3CheckPortCompatible ( FXhciMMIO * mmio , u8 port_id )
{
FASSERT ( mmio ) ;
if ( ( port_id > = mmio - > usb3_ports . port_beg ) & & ( port_id < = mmio - > usb3_ports . port_end ) )
{
return FXHCI_USB3_COMPATIBLE_PORT ;
}
else if ( ( port_id > = mmio - > usb2_ports . port_beg ) & & ( port_id < = mmio - > usb2_ports . port_end ) )
{
return FXHCI_USB2_COMPATIBLE_PORT ;
}
FASSERT ( 0 ) ; /* must not reach there */
return FXHCI_NONE_COMPATIBLE_PORT ;
}
static inline u32 FXhciReadCap ( const FXhciMMIO * mmio )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
return FtIn32 ( mmio - > base + FXHCI_REG_CAP_CAPLENGTH ) ;
}
static inline u8 FXhciReadCaplen ( const FXhciMMIO * mmio )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
u32 reg_val = FXhciReadCap ( mmio ) ;
/* get lower 8-bits */
return ( u8 ) ( reg_val & 0xff ) ;
}
static inline u16 FXhciReadHcVersion ( const FXhciMMIO * mmio )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
u32 reg_val = FXhciReadCap ( mmio ) ;
/* get upper 16 bits */
return ( u16 ) ( ( reg_val > > 16 ) & 0xffff ) ;
}
static inline u32 FXhciReadCap32 ( const FXhciMMIO * mmio , u32 offset )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
offset - = FXHCI_REG_CAP_HCSPARAMS1 ;
offset / = 4 ;
FASSERT ( offset < 4 ) ;
return mmio - > hcx_params [ offset ] ; /* read caps from cache */
}
static inline u32 FXhciReadOper32 ( const FXhciMMIO * mmio , u32 offset )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
return FtIn32 ( mmio - > oper_base + offset ) ;
}
static inline u64 FXhciReadOper64 ( const FXhciMMIO * mmio , u32 offset )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
uintptr addr = mmio - > oper_base + offset ;
u64 val = FtIn32 ( addr ) ;
val | = ( ( u64 ) FtIn32 ( addr + 4 ) ) < < 32 ;
return val ;
}
static inline void FXhciWriteOper32 ( const FXhciMMIO * mmio , u32 offset , u32 val )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
FtOut32 ( mmio - > oper_base + offset , val ) ;
}
static inline void FXhciWriteOper64 ( const FXhciMMIO * mmio , u32 offset , u64 val )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
FXhciWriteOper32 ( mmio , offset , LOWER_32_BITS ( val ) ) ;
FXhciWriteOper32 ( mmio , offset + 4 , UPPER_32_BITS ( val ) ) ;
}
static inline u32 FXhciReadPort32 ( const FXhciMMIO * mmio , u32 port , u32 offset )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
/* Operational Base + (400h + (10h * (n– 1))) */
return FtIn32 ( mmio - > port_base + port * FXHCI_REG_OP_PORTS_SIZE + offset ) ;
}
static inline void FXhciWritePort32 ( const FXhciMMIO * mmio , u32 port , u32 offset , u32 val )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
FtOut32 ( mmio - > port_base + port * FXHCI_REG_OP_PORTS_SIZE + offset , val ) ;
}
static inline u32 FXhciReadRt32 ( const FXhciMMIO * mmio , u32 interrupt , u32 offset )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
/* Runtime Base + 020h + (32 * Interrupter) */
return FtIn32 ( mmio - > runtime_base + FXHCI_REG_RT_IR0 + interrupt * FXHCI_REG_RT_IR_SIZE + offset ) ;
}
static inline u64 FXhciReadRt64 ( const FXhciMMIO * mmio , u32 interrupt , u32 offset )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
uintptr addr = mmio - > runtime_base + FXHCI_REG_RT_IR0 + interrupt * FXHCI_REG_RT_IR_SIZE + offset ;
u64 reg_val = FtIn32 ( addr ) ;
reg_val | = ( u64 ) FtIn32 ( addr + 4 ) < < 32 ;
return reg_val ;
}
static inline void FXhciWriteRt32 ( const FXhciMMIO * mmio , u32 interrupt , u32 offset , u32 val )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
FtOut32 ( mmio - > runtime_base + FXHCI_REG_RT_IR0 + interrupt * FXHCI_REG_RT_IR_SIZE + offset , val ) ;
}
static inline void FXhciWriteRt64 ( const FXhciMMIO * mmio , u32 interrupt , u32 offset , u64 val )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
FXhciWriteRt32 ( mmio , interrupt , offset , ( u32 ) val ) ;
FXhciWriteRt32 ( mmio , interrupt , offset + 4 , ( u32 ) ( val > > 32 ) ) ;
}
static inline u32 FXhciReadExtCap32 ( const FXhciMMIO * mmio , u32 offset )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
FASSERT ( mmio - > xecp_base ! = 0 ) ;
return FtIn32 ( mmio - > xecp_base + offset ) ;
}
static inline void FXhciWriteDb32 ( const FXhciMMIO * mmio , u32 slot , u32 val )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
FtOut32 ( mmio - > doorbell_base + slot * FXHCI_REG_DB_SIZE , val ) ;
}
static inline int FXhciGetCtxSize ( const FXhciMMIO * mmio )
{
FASSERT ( mmio ) ;
FASSERT ( mmio - > base ! = 0 ) ;
u32 reg_val = FXhciReadCap32 ( mmio , FXHCI_REG_CAP_HCCPARAMS ) ;
return ( ( reg_val & FXHCI_REG_CAP_HCCPARAMS_CSZ ) = = FXHCI_REG_CAP_HCCPARAMS_CSZ ) ? 64 : 32 ;
}
/************************** Function Prototypes ******************************/
FError FXhciSetupMMIO ( FXhciMMIO * mmio , uintptr base_addr ) ;
void FXhciListExtCap ( FXhciMMIO * mmio ) ;
FError FXhciWaitOper32 ( FXhciMMIO * mmio , u32 offset , u32 mask , u32 exp_val , u32 timeout_tick ) ;
# ifdef __cplusplus
}
# endif
# endif