usb: phy: Workaround for USB erratum-A005728
PHY_CLK_VALID bit for UTMI PHY in USBDR does not set even if PHY is providing valid clock. Workaround for this involves resetting of PHY and check PHY_CLK_VALID bit multiple times. If PHY_CLK_VALID bit is still not set even after 5 retries, it would be safe to deaclare that PHY clock is not available. This erratum is applicable for USBDR less then ver 2.4. Signed-off-by: Suresh Gupta <B42813@freescale.com> Signed-off-by: Yinbo Zhu <yinbo.zhu@nxp.com> Link: https://lore.kernel.org/r/20190624072219.15258-2-yinbo.zhu@nxp.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
4f18283550
commit
5dfff995f9
|
@ -183,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)
|
||||
|
@ -226,6 +237,16 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd,
|
|||
/* fall through */
|
||||
case FSL_USB2_PHY_UTMI:
|
||||
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);
|
||||
|
@ -249,17 +270,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]);
|
||||
|
|
|
@ -50,4 +50,7 @@
|
|||
#define UTMI_PHY_EN (1<<9)
|
||||
#define ULPI_PHY_CLK_SEL (1<<10)
|
||||
#define PHY_CLK_VALID (1<<17)
|
||||
|
||||
/* Retry count for checking UTMI PHY CLK validity */
|
||||
#define UTMI_PHY_CLK_VALID_CHK_RETRY 5
|
||||
#endif /* _EHCI_FSL_H */
|
||||
|
|
Loading…
Reference in New Issue
Block a user