usb: xhci: Support enabling of compliance mode for xhci 1.1
authorJack Pham <jackp@codeaurora.org>
Wed, 23 Aug 2017 07:35:29 +0000 (00:35 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 28 Aug 2017 09:43:39 +0000 (11:43 +0200)
To perform SuperSpeed compliance testing the port should first
be placed into compliance mode. For xHCI 1.0 and prior this
transition happens automatically when the port is in Training
and encounters an LFPS timeout. Thus running compliance tests
against a test appliance may simply just work by simply plugging
in to the downstream port.

However starting with xHCI 1.1 the transition from Polling.LFPS
to compliance mode may be disabled by default and needs to be
explicitly enabled by writing to the PLS field of the PORTSC
register, which sets an internal 'CTE' (Compliance Transition
Enabled) flag so that the port will perform the transition the
next time it encounters LFPS timeout. Whether this is disabled or
not is determined by the 'CTC' (Compliance Transition Capability)
bit in the HCCPARAMS2 capability register.

In order to allow a test operator to change this if needed, allow
a test driver (such as drivers/usb/misc/lvstest.c) to send a
SET_FEATURE(PORT_LINK_STATE) control message to the root hub to
update the link state prior to connecting to the port. Subsequently,
placing the port in warm reset would then disable the flag.

Signed-off-by: Jack Pham <jackp@codeaurora.org>
Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/xhci-hub.c

index 4bc6f42..ad89a6d 100644 (file)
@@ -1179,6 +1179,39 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                                break;
                        }
 
+                       /*
+                        * For xHCI 1.1 according to section 4.19.1.2.4.1 a
+                        * root hub port's transition to compliance mode upon
+                        * detecting LFPS timeout may be controlled by an
+                        * Compliance Transition Enabled (CTE) flag (not
+                        * software visible). This flag is set by writing 0xA
+                        * to PORTSC PLS field which will allow transition to
+                        * compliance mode the next time LFPS timeout is
+                        * encountered. A warm reset will clear it.
+                        *
+                        * The CTE flag is only supported if the HCCPARAMS2 CTC
+                        * flag is set, otherwise, the compliance substate is
+                        * automatically entered as on 1.0 and prior.
+                        */
+                       if (link_state == USB_SS_PORT_LS_COMP_MOD) {
+                               if (!HCC2_CTC(xhci->hcc_params2)) {
+                                       xhci_dbg(xhci, "CTC flag is 0, port already supports entering compliance mode\n");
+                                       break;
+                               }
+
+                               if ((temp & PORT_CONNECT)) {
+                                       xhci_warn(xhci, "Can't set compliance mode when port is connected\n");
+                                       goto error;
+                               }
+
+                               xhci_dbg(xhci, "Enable compliance mode transition for port %d\n",
+                                               wIndex);
+                               xhci_set_link_state(xhci, port_array, wIndex,
+                                               link_state);
+                               temp = readl(port_array[wIndex]);
+                               break;
+                       }
+
                        /* Software should not attempt to set
                         * port link state above '3' (U3) and the port
                         * must be enabled.