usb: xhci: fix u2 bus suspend for Rockchip SNPS 3.0 xHC

Rockchip SNPS xHC 3.0 set USB 2.0 PHY enter suspend mode
from DWC3 core if the suspend conditions are valid (as per
DWC3 controller databook 6.3.46 GUSB2PHYCFG register bit6).
In this case, it needs to set the bus_suspended bit for
USB 2.0, so that in xhci_bus_resume, it can set the xHC
link state to XDEV_RESUME and send USB resume signal to
USB 2.0 device.

Test on RK3568 USB 3.0 Host interface with USB 2.0 Camera
or USB 2.0 HUB which support USB auto suspend. Without this
patch, the xHC fails to send USB resume signal on the USB
bus to wakeup the USB 2.0 devices, and cause xHC died.

Change-Id: Icb5a553d71a5f3144d77f8d5a5132892a5795285
Signed-off-by: William Wu <william.wu@rock-chips.com>
Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
This commit is contained in:
William Wu
2021-03-30 11:15:03 +08:00
committed by Tao Huang
parent 2a53c31cc9
commit f925e2b3ce
3 changed files with 19 additions and 0 deletions

View File

@@ -1676,7 +1676,21 @@ retry:
t2 &= ~PORT_PLS_MASK;
t2 |= PORT_LINK_STROBE | XDEV_U3;
set_bit(port_index, &bus_state->bus_suspended);
} else if ((xhci->quirks & XHCI_U2_BROKEN_SUSPEND) &&
(hcd->speed < HCD_USB3) &&
(t1 & PORT_PLS_MASK) == XDEV_U3) {
/*
* Rockchip SNPS xHC 3.0 set USB 2.0 PHY enter
* suspend mode from DWC3 core if the suspend
* conditions are valid. In this case, it need
* to set the bus_suspended bit for USB 2.0, so
* that in xhci_bus_resume, it can set the xHC
* link state to XDEV_RESUME and send USB resume
* signal to USB 2.0 device.
*/
set_bit(port_index, &bus_state->bus_suspended);
}
/* USB core sets remote wake mask for USB 3.0 hubs,
* including the USB 3.0 roothub, but only if CONFIG_PM
* is enabled, so also enable remote wake here.

View File

@@ -363,6 +363,10 @@ static int xhci_plat_probe(struct platform_device *pdev)
if (device_property_read_bool(tmpdev, "quirk-skip-phy-init"))
xhci->quirks |= XHCI_SKIP_PHY_INIT;
if (device_property_read_bool(tmpdev,
"xhci-u2-broken-suspend"))
xhci->quirks |= XHCI_U2_BROKEN_SUSPEND;
device_property_read_u32(tmpdev, "imod-interval-ns",
&xhci->imod_interval);
}

View File

@@ -1906,6 +1906,7 @@ struct xhci_hcd {
#define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39)
#define XHCI_NO_SOFT_RETRY BIT_ULL(40)
#define XHCI_EP_CTX_BROKEN_DCS BIT_ULL(42)
#define XHCI_U2_BROKEN_SUSPEND BIT_ULL(43)
unsigned int num_active_eps;
unsigned int limit_active_eps;