Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5f981073 authored by Yoshihiro Shimoda's avatar Yoshihiro Shimoda Committed by Greg Kroah-Hartman
Browse files

usb: host: xhci-rcar: Add a condition check about PLL active



This patch adds a condition check about the PLL acvice of this
controller. Otherwise, the controller might cause hang when
any USB clocks are not supplied yet and accesses the xHCI registers.

Signed-off-by: default avatarYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ed8603e1
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ MODULE_FIRMWARE(XHCI_RCAR_FIRMWARE_NAME_V2);
MODULE_FIRMWARE(XHCI_RCAR_FIRMWARE_NAME_V3);

/*** Register Offset ***/
#define RCAR_USB3_AXH_STA	0x104	/* AXI Host Control Status */
#define RCAR_USB3_INT_ENA	0x224	/* Interrupt Enable */
#define RCAR_USB3_DL_CTRL	0x250	/* FW Download Control & Status */
#define RCAR_USB3_FW_DATA0	0x258	/* FW Data0 */
@@ -41,6 +42,12 @@ MODULE_FIRMWARE(XHCI_RCAR_FIRMWARE_NAME_V3);
#define RCAR_USB3_TX_POL	0xab8	/* USB3.0 TX Polarity */

/*** Register Settings ***/
/* AXI Host Control Status */
#define RCAR_USB3_AXH_STA_B3_PLL_ACTIVE		0x00010000
#define RCAR_USB3_AXH_STA_B2_PLL_ACTIVE		0x00000001
#define RCAR_USB3_AXH_STA_PLL_ACTIVE_MASK (RCAR_USB3_AXH_STA_B3_PLL_ACTIVE | \
					   RCAR_USB3_AXH_STA_B2_PLL_ACTIVE)

/* Interrupt Enable */
#define RCAR_USB3_INT_XHC_ENA	0x00000001
#define RCAR_USB3_INT_PME_ENA	0x00000002
@@ -200,6 +207,22 @@ static int xhci_rcar_download_firmware(struct usb_hcd *hcd)
	return retval;
}

static bool xhci_rcar_wait_for_pll_active(struct usb_hcd *hcd)
{
	int timeout = 1000;
	u32 val, mask = RCAR_USB3_AXH_STA_PLL_ACTIVE_MASK;

	while (timeout > 0) {
		val = readl(hcd->regs + RCAR_USB3_AXH_STA);
		if ((val & mask) == mask)
			return true;
		udelay(1);
		timeout--;
	}

	return false;
}

/* This function needs to initialize a "phy" of usb before */
int xhci_rcar_init_quirk(struct usb_hcd *hcd)
{
@@ -220,6 +243,9 @@ int xhci_rcar_init_quirk(struct usb_hcd *hcd)
			xhci_rcar_is_gen3(hcd->self.controller))
		xhci->quirks |= XHCI_NO_64BIT_SUPPORT;

	if (!xhci_rcar_wait_for_pll_active(hcd))
		return -ETIMEDOUT;

	return xhci_rcar_download_firmware(hcd);
}