drivers: usb :fsl: Implement Workaround for USB Erratum A007792
authorNikhil Badola <nikhil.badola@freescale.com>
Mon, 15 Jun 2015 10:17:29 +0000 (15:47 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 22 Jul 2015 23:37:32 +0000 (16:37 -0700)
USB controller version-2.5 requires to enable internal UTMI
phy and program PTS field in PORTSC register before asserting
controller reset. This is must for successful resetting of the
controller and subsequent enumeration of usb devices

Signed-off-by: Nikhil Badola <nikhil.badola@freescale.com>
Signed-off-by: Suresh Gupta <suresh.gupta@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/ehci-fsl.c
drivers/usb/host/fsl-mph-dr-of.c
include/linux/fsl_devices.h

index 5352e74b92e2112c273c4e0a2c43387a8bd0a105..716aa8be1d6f6aa1ebab3be946cd1c55f2f4e944 100644 (file)
@@ -129,6 +129,15 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
        if (pdata->have_sysif_regs && pdata->controller_ver < FSL_USB_VER_1_6)
                setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4);
 
+       /*
+        * Enable UTMI phy and program PTS field in UTMI mode before asserting
+        * controller reset for USB Controller version 2.5
+        */
+       if (pdata->has_fsl_erratum_a007792) {
+               writel_be(CTRL_UTMI_PHY_EN, hcd->regs + FSL_SOC_USB_CTRL);
+               writel(PORT_PTS_UTMI, hcd->regs + FSL_SOC_USB_PORTSC1);
+       }
+
        /* Don't need to set host mode here. It will be done by tdi_reset() */
 
        retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
index 219595637cb185d83160062eda600c6d36a56de2..17e1e6b7a03569ab36f2c9d91d6fb86abcf33ef9 100644 (file)
@@ -214,6 +214,12 @@ static int fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
        pdata->phy_mode = determine_usb_phy(prop);
        pdata->controller_ver = usb_get_ver_info(np);
 
+       /* Activate Erratum by reading property in device tree */
+       if (of_get_property(np, "fsl,usb-erratum-a007792", NULL))
+               pdata->has_fsl_erratum_a007792 = 1;
+       else
+               pdata->has_fsl_erratum_a007792 = 0;
+
        if (pdata->have_sysif_regs) {
                if (pdata->controller_ver == FSL_USB_VER_NONE) {
                        dev_warn(&ofdev->dev, "Could not get controller version\n");
index 0d4855cd53309bfe2429c44863d612549f1d6206..bdb40f67180cb4a10bfc39a09ba28da6f1b70479 100644 (file)
@@ -97,6 +97,7 @@ struct fsl_usb2_platform_data {
 
        unsigned        suspended:1;
        unsigned        already_suspended:1;
+       unsigned        has_fsl_erratum_a007792:1;
 
        /* register save area for suspend/resume */
        u32             pm_command;