xhci: Read and parse new xhci 1.1 capability register
authorLu Baolu <baolu.lu@linux.intel.com>
Thu, 1 Oct 2015 15:40:31 +0000 (18:40 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 4 Oct 2015 09:34:17 +0000 (10:34 +0100)
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 <baolu.lu@linux.intel.com>
[modified and left out parts not related to HCCPARAMS2 -Mathias]
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/xhci-dbg.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h

index 2d16faefb429b03a529304136c1eaf19deb15572..74c42f7226780b4c6a4924489f711d27a1b90f37 100644 (file)
@@ -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)
index 9957bd96d4bc383dd9f27a557af157c8d7343fc8..0ba6c1cc90b4b6e511c49c50b51580cab4321cc8 100644 (file)
@@ -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);
index dbda41e91c843f2e289c4a4aa0d4129f2641f2a9..17d4d440863766b2242c336e4f9c4e8973b22960 100644 (file)
@@ -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;