blob: 8e94a4b033384d0f3ce89ff7d94bc4e6224baf3c [file] [log] [blame]
/******************************************************************************
* 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, aligned(4)));
/* 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, aligned(4)));
struct port_state {
bool PP;
bool CCS;
bool PED;
bool PR;
uint8_t PLS;
char *state;
};
/* 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 44
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, aligned(8)));
/*
* 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, aligned(8)));
/* 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, aligned(8)));
/* 5.6 Doorbell Registers*/
struct xhci_db_regs {
uint32_t db[256];
} __attribute__ ((packed, aligned(4)));
#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_INTR_TRBS_SIZE 4096
#define XHCI_ERST_NUM_SEGS 1
#define XHCI_POLL_NO_WAIT 1
#define XHCI_MAX_BULK_SIZE 0xF000
struct xhci_erst_entry {
uint64_t addr;
uint32_t size;
uint32_t reserved;
} __attribute__ ((packed, aligned(8)));
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 intr;
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;
void *buf;
long buf_phys;
uint32_t buflen;
};
extern bool usb3_dev_init(struct xhci_hcd *xhcd, struct usb_dev *hub,
uint32_t port, uint32_t slotspeed);
#endif /* USB_XHCI_H */