From 04abb6de28250d619ec5aa53695f12a1e4265e1a Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Thu, 1 Oct 2015 18:40:31 +0300 Subject: [PATCH] xhci: Read and parse new xhci 1.1 capability register xhci 1.1 capable controllers have a new HCCPARAMS2 registers with bits indicating support for new xhci 1.1 capabilities. Also add support for the new xhci 1.1 bits in the config operational opertational register that used to be reserved Signed-off-by: Lu Baolu [modified and left out parts not related to HCCPARAMS2 -Mathias] Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-dbg.c | 17 +++++++++++++++-- drivers/usb/host/xhci.c | 4 +++- drivers/usb/host/xhci.h | 24 +++++++++++++++++++++++- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index 2d16faefb429..74c42f722678 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c @@ -58,16 +58,17 @@ void xhci_dbg_regs(struct xhci_hcd *xhci) static void xhci_print_cap_regs(struct xhci_hcd *xhci) { u32 temp; + u32 hci_version; xhci_dbg(xhci, "xHCI capability registers at %p:\n", xhci->cap_regs); temp = readl(&xhci->cap_regs->hc_capbase); + hci_version = HC_VERSION(temp); xhci_dbg(xhci, "CAPLENGTH AND HCIVERSION 0x%x:\n", (unsigned int) temp); xhci_dbg(xhci, "CAPLENGTH: 0x%x\n", (unsigned int) HC_LENGTH(temp)); - xhci_dbg(xhci, "HCIVERSION: 0x%x\n", - (unsigned int) HC_VERSION(temp)); + xhci_dbg(xhci, "HCIVERSION: 0x%x\n", hci_version); temp = readl(&xhci->cap_regs->hcs_params1); xhci_dbg(xhci, "HCSPARAMS 1: 0x%x\n", @@ -108,6 +109,18 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci) temp = readl(&xhci->cap_regs->run_regs_off); xhci_dbg(xhci, "RTSOFF 0x%x:\n", temp & RTSOFF_MASK); + + /* xhci 1.1 controllers have the HCCPARAMS2 register */ + if (hci_version > 100) { + temp = readl(&xhci->cap_regs->hcc_params2); + xhci_dbg(xhci, "HCC PARAMS2 0x%x:\n", (unsigned int) temp); + xhci_dbg(xhci, " HC %s Force save context capability", + HCC2_FSC(temp) ? "supports" : "doesn't support"); + xhci_dbg(xhci, " HC %s Large ESIT Payload Capability", + HCC2_LEC(temp) ? "supports" : "doesn't support"); + xhci_dbg(xhci, " HC %s Extended TBC capability", + HCC2_ETC(temp) ? "supports" : "doesn't support"); + } } static void xhci_print_command_reg(struct xhci_hcd *xhci) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 9957bd96d4bc..0ba6c1cc90b4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -4875,6 +4875,8 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) xhci->hcc_params = readl(&xhci->cap_regs->hc_capbase); xhci->hci_version = HC_VERSION(xhci->hcc_params); xhci->hcc_params = readl(&xhci->cap_regs->hcc_params); + if (xhci->hci_version > 0x100) + xhci->hcc_params2 = readl(&xhci->cap_regs->hcc_params2); xhci_print_registers(xhci); xhci->quirks = quirks; @@ -5020,7 +5022,7 @@ static int __init xhci_hcd_init(void) BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8); BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8); BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8); - BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 7*32/8); + BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 8*32/8); BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8); /* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */ BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index dbda41e91c84..17d4d4408637 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -56,6 +56,7 @@ * @hcc_params: HCCPARAMS - Capability Parameters * @db_off: DBOFF - Doorbell array offset * @run_regs_off: RTSOFF - Runtime register space offset + * @hcc_params2: HCCPARAMS2 Capability Parameters 2, xhci 1.1 only */ struct xhci_cap_regs { __le32 hc_capbase; @@ -65,6 +66,7 @@ struct xhci_cap_regs { __le32 hcc_params; __le32 db_off; __le32 run_regs_off; + __le32 hcc_params2; /* xhci 1.1 */ /* Reserved up to (CAPLENGTH - 0x1C) */ }; @@ -134,6 +136,21 @@ struct xhci_cap_regs { /* run_regs_off bitmask - bits 0:4 reserved */ #define RTSOFF_MASK (~0x1f) +/* HCCPARAMS2 - hcc_params2 - bitmasks */ +/* true: HC supports U3 entry Capability */ +#define HCC2_U3C(p) ((p) & (1 << 0)) +/* true: HC supports Configure endpoint command Max exit latency too large */ +#define HCC2_CMC(p) ((p) & (1 << 1)) +/* true: HC supports Force Save context Capability */ +#define HCC2_FSC(p) ((p) & (1 << 2)) +/* true: HC supports Compliance Transition Capability */ +#define HCC2_CTC(p) ((p) & (1 << 3)) +/* true: HC support Large ESIT payload Capability > 48k */ +#define HCC2_LEC(p) ((p) & (1 << 4)) +/* true: HC support Configuration Information Capability */ +#define HCC2_CIC(p) ((p) & (1 << 5)) +/* true: HC support Extended TBC Capability, Isoc burst count > 65535 */ +#define HCC2_ETC(p) ((p) & (1 << 6)) /* Number of registers per port */ #define NUM_PORT_REGS 4 @@ -269,7 +286,11 @@ struct xhci_op_regs { /* CONFIG - Configure Register - config_reg bitmasks */ /* bits 0:7 - maximum number of device slots enabled (NumSlotsEn) */ #define MAX_DEVS(p) ((p) & 0xff) -/* bits 8:31 - reserved and should be preserved */ +/* bit 8: U3 Entry Enabled, assert PLC when root port enters U3, xhci 1.1 */ +#define CONFIG_U3E (1 << 8) +/* bit 9: Configuration Information Enable, xhci 1.1 */ +#define CONFIG_CIE (1 << 9) +/* bits 10:31 - reserved and should be preserved */ /* PORTSC - Port Status and Control Register - port_status_base bitmasks */ /* true: device connected */ @@ -1465,6 +1486,7 @@ struct xhci_hcd { __u32 hcs_params2; __u32 hcs_params3; __u32 hcc_params; + __u32 hcc_params2; spinlock_t lock; -- GitLab