diff options
Diffstat (limited to 'qemu/roms/SLOF/lib/libusb/usb-xhci.h')
-rw-r--r-- | qemu/roms/SLOF/lib/libusb/usb-xhci.h | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/qemu/roms/SLOF/lib/libusb/usb-xhci.h b/qemu/roms/SLOF/lib/libusb/usb-xhci.h new file mode 100644 index 000000000..faeb07ead --- /dev/null +++ b/qemu/roms/SLOF/lib/libusb/usb-xhci.h @@ -0,0 +1,386 @@ +/****************************************************************************** + * Copyright (c) 2013 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ +/* + * Definitions for XHCI Controller - Revision 1.0 (5/21/10) + * + */ + +#ifndef USB_XHCI_H +#define USB_XHCI_H + +#include <stdint.h> +#include "usb-core.h" + +#define BIT(x) (1 << x) + +/* 5.3 Host Controller Capability Registers + * Table 19 + */ +struct xhci_cap_regs { + uint8_t caplength; + uint8_t reserved; + uint16_t hciversion; + uint32_t hcsparams1; + uint32_t hcsparams2; + uint32_t hcsparams3; + uint32_t hccparams; +#define XHCI_HCCPARAMS_CSZ BIT(2) +#define XHCI_HCCPARAMS_XECP(x) ((x & 0xFFFF0000) >> 16) + uint32_t dboff; + uint32_t rtsoff; +} __attribute__ ((packed)); + +/* USB 3.0: Section 7 and 7.2 */ +#define XHCI_XECP_CAP_ID(x) ((x & 0xF)) +#define XHCI_XECP_CAP_SP 2 +#define XHCI_XECP_CAP_SP_MN(x) ((x & 0xFF0000) >> 16) +#define XHCI_XECP_CAP_SP_MJ(x) ((x & 0xFF000000) >> 24) +#define XHCI_XECP_CAP_SP_PC(x) ((x & 0xFF00) >> 8) +#define XHCI_XECP_CAP_SP_PO(x) (x & 0xFF) +#define XHCI_XECP_NEXT_PTR(x) ((x & 0xFF00) >> 8) + +/* Table 27: Host Controller USB Port Register Set */ +struct xhci_port_regs { + uint32_t portsc; +#define PORTSC_CCS BIT(0) +#define PORTSC_PED BIT(1) +#define PORTSC_OCA BIT(3) +#define PORTSC_PR BIT(4) +#define PORTSC_PLS_MASK (0xF << 5) +#define PORTSC_PLS_U0 0 +#define PORTSC_PLS_U1 1 +#define PORTSC_PLS_U2 2 +#define PORTSC_PLS_U3 3 +#define PORTSC_PLS_DISABLED 4 +#define PORTSC_PLS_RXDETECT 5 +#define PORTSC_PLS_INACTIVE 6 +#define PORTSC_PLS_POLLING 7 +#define PORTSC_PLS_RECOVERY 8 +#define PORTSC_PLS_HOTRESET 9 +#define PORTSC_PLS_COMP_MODE 10 +#define PORTSC_PLS_TEST_MODE 11 +#define PORTSC_PLS_RESUME 15 +#define PORTSC_PP BIT(9) +#define PORTSC_PS_MASK (0xF << 10) +#define PORTSC_PIC_MASK (0x3 << 14) +#define PORTSC_LWS BIT(16) +#define PORTSC_CSC BIT(17) +#define PORTSC_PEC BIT(18) +#define PORTSC_WRC BIT(19) +#define PORTSC_OCC BIT(20) +#define PORTSC_PRC BIT(21) +#define PORTSC_PLC BIT(22) +#define PORTSC_CEC BIT(23) +#define PORTSC_CAS BIT(24) +#define PORTSC_WCE BIT(25) +#define PORTSC_WDE BIT(26) +#define PORTSC_WOE BIT(27) +#define PORTSC_DR BIT(30) +#define PORTSC_WPR BIT(31) + + uint32_t portpmsc; + uint32_t portli; + uint32_t reserved; +} __attribute__ ((packed)); + +struct port_state { + bool PP; + bool CCS; + bool PED; + bool PR; + uint8_t PLS; + char *state; +}; + + +struct port_state ps_array_usb2[] = { + {1, 0, 0, 0, PORTSC_PLS_U0, "ERROR"} +}; + +struct port_state ps_array_usb3[] = { + {0, 0, 0, 0, PORTSC_PLS_DISABLED, "Powered-OFF"}, + {1, 0, 0, 0, PORTSC_PLS_POLLING, "Polling"}, + {1, 0, 0, 0, PORTSC_PLS_U0, "Polling"}, + {1, 0, 0, 0, PORTSC_PLS_RXDETECT, "*** Disconnected ***"}, + {1, 0, 0, 0, PORTSC_PLS_DISABLED, "Disabled"}, + {1, 0, 0, 0, PORTSC_PLS_INACTIVE, "Error"}, + {1, 0, 0, 0, PORTSC_PLS_TEST_MODE,"Loopback"}, + {1, 0, 0, 0, PORTSC_PLS_COMP_MODE,"Compliancek"}, + {1, 1, 0, 1, PORTSC_PLS_U0, "****** Reset ******"}, + {1, 1, 1, 0, PORTSC_PLS_U0, "****** Enabled ******"}, +}; + +/* 5.4 Host Controller Operational Registers + * Table 26 + */ +struct xhci_op_regs { + uint32_t usbcmd; +#define XHCI_USBCMD_RS BIT(0) +#define XHCI_USBCMD_HCRST BIT(1) + + uint32_t usbsts; +#define XHCI_USBSTS_HCH BIT(0) +#define XHCI_USBSTS_CNR BIT(11) + + uint32_t pagesize; + uint8_t reserved[8]; /* 0C - 13 */ + uint32_t dnctrl; /* Device notification control */ + uint64_t crcr; /* Command ring control */ +#define XHCI_CRCR_CRP_MASK 0xFFFFFFFFFFFFFFC0 +#define XHCI_CRCR_CRR BIT(3) +#define XHCI_CRCR_CRP_SIZE 4096 + + uint8_t reserved1[16]; /* 20 - 2F */ + uint64_t dcbaap; /* Device Context Base Address Array Pointer */ +#define XHCI_DCBAAP_MAX_SIZE 2048 + + uint32_t config; /* Configure */ +#define XHCI_CONFIG_MAX_SLOT 4 + + uint8_t reserved2[964]; /* 3C - 3FF */ + /* USB Port register set */ +#define XHCI_PORT_MAX 256 + struct xhci_port_regs prs[XHCI_PORT_MAX]; +} __attribute__ ((packed)); + +/* + * 5.5.2 Interrupter Register Set + * Table 42: Interrupter Registers + */ +struct xhci_int_regs { + uint32_t iman; + uint32_t imod; + uint32_t erstsz; +#define XHCI_ERST_SIZE_MASK 0xFFFF + uint32_t reserved; + uint64_t erstba; +#define XHCI_ERST_ADDR_MASK (~(0x3FUL)) + uint64_t erdp; +#define XHCI_ERDP_MASK (~(0xFUL)) +} __attribute__ ((packed)); + +/* 5.5 Host Controller Runtime Registers */ +struct xhci_run_regs { + uint32_t mfindex; /* microframe index */ + uint8_t reserved[28]; +#define XHCI_IRS_MAX 1024 + struct xhci_int_regs irs[XHCI_IRS_MAX]; +} __attribute__ ((packed)); + +/* 5.6 Doorbell Registers*/ +struct xhci_db_regs { + uint32_t db[256]; +} __attribute__ ((packed)); + +#define COMP_SUCCESS 1 + +#define TRB_SLOT_ID(x) (((x) & (0xFF << 24)) >> 24) +#define TRB_CMD_SLOT_ID(x) ((x & 0xFF) << 24) +#define TRB_TYPE(x) (((x) & (0x3F << 10)) >> 10) +#define TRB_CMD_TYPE(x) ((x & 0x3F) << 10) +#define TRB_STATUS(x) (((x) & (0xFF << 24)) >> 24) +#define TRB_ADDR_LOW(x) ((uint32_t)((uint64_t)(x))) +#define TRB_ADDR_HIGH(x) ((uint32_t)((uint64_t)(x) >> 32)) +#define TRB_TRT(x) (((x) & 0x3) << 16 ) +#define TRB_DIR_IN BIT(16) +#define TRB_IOC BIT(5) +#define TRB_IDT BIT(6) + +#define TRB_CYCLE_STATE BIT(0) + +struct xhci_transfer_trb { + uint64_t addr; + uint32_t len; + uint32_t flags; +} __attribute__ ((packed)); + +struct xhci_link_trb { + uint64_t addr; + uint32_t field2; + uint32_t field3; +} __attribute__ ((packed)); + +/* Event TRB */ +struct xhci_event_trb { + uint64_t addr; + uint32_t status; + uint32_t flags; +} __attribute__ ((packed)); + +#define TRB_NORMAL 1 +#define TRB_SETUP_STAGE 2 +#define TRB_DATA_STAGE 3 +#define TRB_STATUS_STAGE 4 +#define TRB_ISOCH 5 +#define TRB_LINK 6 +#define TRB_EVENT_DATA 7 +#define TRB_NOOP 8 +#define TRB_ENABLE_SLOT 9 +#define TRB_DISABLE_SLOT 10 +#define TRB_ADDRESS_DEV 11 +#define TRB_CONFIG_EP 12 +#define TRB_EVAL_CNTX 13 +#define TRB_TRANSFER_EVENT 32 +#define TRB_CMD_COMPLETION 33 +#define TRB_PORT_STATUS 34 + +struct xhci_command_trb { + uint32_t field[4]; +}__attribute__ ((packed)); + +union xhci_trb { + struct xhci_event_trb event; + struct xhci_transfer_trb xfer; + struct xhci_command_trb cmd; + struct xhci_link_trb link; +}; + +enum xhci_seg_type { + TYPE_CTRL = 0, + TYPE_BULK, + TYPE_COMMAND, + TYPE_EVENT, +}; + +struct xhci_seg { + union xhci_trb *trbs; + struct xhci_seg *next; + uint64_t enq; + uint64_t deq; + uint64_t trbs_dma; + uint32_t size; + uint32_t cycle_state; + enum xhci_seg_type type; +}; + +#define XHCI_TRB_SIZE 16 +#define XHCI_EVENT_TRBS_SIZE 4096 +#define XHCI_CONTROL_TRBS_SIZE 4096 +#define XHCI_DATA_TRBS_SIZE 4096 +#define XHCI_ERST_NUM_SEGS 1 + +#define XHCI_MAX_BULK_SIZE 0xF000 + +struct xhci_erst_entry { + uint64_t addr; + uint32_t size; + uint32_t reserved; +} __attribute__ ((packed)); + +struct xhci_erst { + struct xhci_erst_entry *entries; + uint64_t dma; + uint32_t num_segs; /* number of segments */ +}; + +struct xhci_control_ctx { + uint32_t d_flags; + uint32_t a_flags; + uint32_t reserved[6]; +} __attribute__ ((packed)); + +struct xhci_slot_ctx { + uint32_t field1; +#define SLOT_SPEED_FS BIT(20) +#define SLOT_SPEED_LS BIT(21) +#define SLOT_SPEED_HS BIT(22) +#define SLOT_SPEED_SS BIT(23) +#define LAST_CONTEXT(x) (x << 27) + + uint32_t field2; +#define ROOT_HUB_PORT(x) ((x & 0xff) << 16) + + uint32_t field3; + uint32_t field4; +#define USB_DEV_ADDRESS(x) (x & 0xFFU) +#define SLOT_STATE(x) ((x >> 27) & 0x1FU) +#define SLOT_STATE_DIS_ENA 0 +#define SLOT_STATE_DEFAULT 1 +#define SLOT_STATE_ADDRESSED 2 +#define SLOT_STATE_CONFIGURED 3 + + + uint32_t reserved[4]; +} __attribute__ ((packed)); + +struct xhci_ep_ctx { + uint32_t field1; + uint32_t field2; +#define MAX_PACKET_SIZE(x) (((x) & 0xFFFF) << 16) +#define MAX_BURST(x) (((x) & 0xFF) << 8) +#define EP_TYPE(x) (((x) & 0x07) << 3) +#define EP_ISOC_OUT 1 +#define EP_BULK_OUT 2 +#define EP_INT_OUT 3 +#define EP_CTRL 4 +#define EP_ISOC_IN 5 +#define EP_BULK_IN 6 +#define EP_INT_IN 7 + +#define ERROR_COUNT(x) (((x) & 0x03) << 1) + + uint64_t deq_addr; + uint32_t field4; + uint32_t reserved[3]; +} __attribute__ ((packed)); + +struct xhci_ctx { + uint8_t type; +#define XHCI_CTX_TYPE_DEVICE 0x1 +#define XHCI_CTX_TYPE_INPUT 0x2 + uint32_t size; + uint8_t *addr; +#define XHCI_CTX_BUF_SIZE 4096 + uint64_t dma_addr; +}; + +struct xhci_dev { + struct usb_dev *dev; + uint32_t slot_id; + struct xhci_ctx in_ctx; + struct xhci_ctx out_ctx; + struct xhci_seg control; + struct xhci_seg bulk_in; + struct xhci_seg bulk_out; + uint32_t ctx_size; +}; + +struct xhci_hcd { + struct xhci_cap_regs *cap_regs; + struct xhci_op_regs *op_regs; + struct xhci_run_regs *run_regs; + struct xhci_db_regs *db_regs; + struct usb_hcd_dev *hcidev; + struct xhci_dev xdevs[XHCI_CONFIG_MAX_SLOT + 1]; + struct usb_pipe *freelist; + struct usb_pipe *end; + uint64_t *dcbaap; + uint64_t dcbaap_dma; + struct xhci_seg ering; + struct xhci_seg crseg; + struct xhci_erst erst; + uint64_t erds_dma; + uint32_t erds_size; + uint32_t slot_id; + uint32_t hcc_csz_64; + void *pool; +#define XHCI_PIPE_POOL_SIZE 4096 + + long pool_phys; +}; + +struct xhci_pipe { + struct usb_pipe pipe; + struct xhci_seg *seg; +}; + +#endif /* USB_XHCI_H */ |