diff options
Diffstat (limited to 'drivers/usb/host/ehci-fsl.c')
-rw-r--r-- | drivers/usb/host/ehci-fsl.c | 52 |
1 files changed, 41 insertions, 11 deletions
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index e3d0c1c25160..9e9c232e896f 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -122,6 +122,12 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev) tmp |= 0x4; iowrite32be(tmp, hcd->regs + FSL_SOC_USB_CTRL); } + + /* Set USB_EN bit to select ULPI phy for USB controller version 2.5 */ + if (pdata->controller_ver == FSL_USB_VER_2_5 && + pdata->phy_mode == FSL_USB2_PHY_ULPI) + iowrite32be(USB_CTRL_USB_EN, hcd->regs + FSL_SOC_USB_CTRL); + /* * Enable UTMI phy and program PTS field in UTMI mode before asserting * controller reset for USB Controller version 2.5 @@ -177,6 +183,17 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev) return retval; } +static bool usb_phy_clk_valid(struct usb_hcd *hcd) +{ + void __iomem *non_ehci = hcd->regs; + bool ret = true; + + if (!(ioread32be(non_ehci + FSL_SOC_USB_CTRL) & PHY_CLK_VALID)) + ret = false; + + return ret; +} + static int ehci_fsl_setup_phy(struct usb_hcd *hcd, enum fsl_usb2_phy_modes phy_mode, unsigned int port_offset) @@ -219,7 +236,26 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, portsc |= PORT_PTS_PTW; /* fall through */ case FSL_USB2_PHY_UTMI: + /* Presence of this node "has_fsl_erratum_a006918" + * in device-tree is used to stop USB controller + * initialization in Linux + */ + if (pdata->has_fsl_erratum_a006918) { + dev_warn(dev, "USB PHY clock invalid\n"); + return -EINVAL; + } + /* fall through */ case FSL_USB2_PHY_UTMI_DUAL: + /* PHY_CLK_VALID bit is de-featured from all controller + * versions below 2.4 and is to be checked only for + * internal UTMI phy + */ + if (pdata->controller_ver > FSL_USB_VER_2_4 && + pdata->have_sysif_regs && !usb_phy_clk_valid(hcd)) { + dev_err(dev, "USB PHY clock invalid\n"); + return -EINVAL; + } + if (pdata->have_sysif_regs && pdata->controller_ver) { /* controller version 1.6 or above */ tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); @@ -243,17 +279,11 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, break; } - /* - * check PHY_CLK_VALID to determine phy clock presence before writing - * to portsc - */ - if (pdata->check_phy_clk_valid) { - if (!(ioread32be(non_ehci + FSL_SOC_USB_CTRL) & - PHY_CLK_VALID)) { - dev_warn(hcd->self.controller, - "USB PHY clock invalid\n"); - return -EINVAL; - } + if (pdata->have_sysif_regs && + pdata->controller_ver > FSL_USB_VER_1_6 && + !usb_phy_clk_valid(hcd)) { + dev_warn(hcd->self.controller, "USB PHY clock invalid\n"); + return -EINVAL; } ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]); |