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:
Suresh Gupta 2019-06-24 15:22:16 +08:00 committed by Greg Kroah-Hartman
parent 4f18283550
commit 5dfff995f9
2 changed files with 29 additions and 11 deletions

View File

@ -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,18 +270,12 @@ 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");
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]);

View File

@ -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 */