Skip to content

Commit

Permalink
xhci: Read and parse new xhci 1.1 capability register
Browse files Browse the repository at this point in the history
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 <[email protected]>
[modified and left out parts not related to HCCPARAMS2 -Mathias]
Signed-off-by: Mathias Nyman <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
LuBaolu authored and gregkh committed Oct 4, 2015
1 parent 07294cc commit 04abb6d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
17 changes: 15 additions & 2 deletions drivers/usb/host/xhci-dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion drivers/usb/host/xhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
24 changes: 23 additions & 1 deletion drivers/usb/host/xhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) */
};

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -1465,6 +1486,7 @@ struct xhci_hcd {
__u32 hcs_params2;
__u32 hcs_params3;
__u32 hcc_params;
__u32 hcc_params2;

spinlock_t lock;

Expand Down

0 comments on commit 04abb6d

Please sign in to comment.