According to xHCI 1.1 CH4.19.4 Port Power: While Chip Hardware Reset or HCRST is asserted, the value of PP is undefined. If the xHC supports power switches (PPC = ‘1’) then VBus may be deasserted during this time. PP (and VBus) shall be enabled immediately upon exiting the reset condition. The VBus glitch may cause some USB devices work abnormal, we observe it at NXP LS1012AFWRY/LS1043ARDB/LX2160AQDS/LS1088ARDB platforms. To avoid this Vbus glitch, we could set PP as 0 before HCRST, and the PP will back to 1 after HCRST according to spec. Reported-by: Ran Wang <ran.wang_1@xxxxxxx> Signed-off-by: Peter Chen <peter.chen@xxxxxxx> --- drivers/usb/host/xhci.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 6b34a573c3d9..f5a7b5d63031 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -167,7 +167,8 @@ int xhci_reset(struct xhci_hcd *xhci) { u32 command; u32 state; - int ret; + int ret, i; + u32 portsc; state = readl(&xhci->op_regs->status); @@ -181,6 +182,18 @@ int xhci_reset(struct xhci_hcd *xhci) return 0; } + /* + * Keep PORTSC.PP as 0 before HCRST to eliminate + * Vbus glitch, see CH 4.19.4. + */ + for (i = 0; i < HCS_MAX_PORTS(xhci->hcs_params1); i++) { + __le32 __iomem *port_addr = &xhci->op_regs->port_status_base + + NUM_PORT_REGS * i; + portsc = readl(port_addr); + portsc &= ~PORT_POWER; + writel(portsc, port_addr); + } + xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Reset the HC"); command = readl(&xhci->op_regs->command); command |= CMD_RESET; -- 2.17.1