]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
drivers: usb: fsl: Workaround for USB erratum-A005275
authorNikhil Badola <nikhil.badola@freescale.com>
Thu, 6 Aug 2015 09:21:27 +0000 (14:51 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 14 Aug 2015 23:50:36 +0000 (16:50 -0700)
Incoming packets in high speed are randomly corrupted by h/w
resulting in multiple errors. This workaround makes FS as
default mode in all affected socs by disabling HS chirp
signalling.This errata does not affect FS and LS mode.

Forces all HS devices to connect in FS mode for all socs
affected by this erratum:
P3041 and P2041 rev 1.0 and 1.1
P5020 and P5010 rev 1.0 and 2.0
P5040, P1010 and T4240 rev 1.0

Signed-off-by: Ramneek Mehresh <ramneek.mehresh@freescale.com>
Signed-off-by: Nikhil Badola <nikhil.badola@freescale.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci.h
drivers/usb/host/fsl-mph-dr-of.c
include/linux/fsl_devices.h

index 202dafb7d0cb78897ad2404a50706475d30193d1..3b6eb219de1a714d31fc843718472efc6ab615f4 100644 (file)
@@ -278,6 +278,10 @@ static int ehci_fsl_usb_setup(struct ehci_hcd *ehci)
                out_be32(non_ehci + FSL_SOC_USB_SNOOP2, 0x80000000 | SNOOP_SIZE_2GB);
        }
 
+       /* Deal with USB erratum A-005275 */
+       if (pdata->has_fsl_erratum_a005275 == 1)
+               ehci->has_fsl_hs_errata = 1;
+
        if ((pdata->operating_mode == FSL_USB2_DR_HOST) ||
                        (pdata->operating_mode == FSL_USB2_DR_OTG))
                if (ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0))
index 22abb6830dfa9e33ca7e1a4cc56c28b2b4a3f662..086a7115d263c673ec4a4e10abe1a386546b8338 100644 (file)
@@ -1221,6 +1221,13 @@ int ehci_hub_control(
                                 */
                                ehci->reset_done [wIndex] = jiffies
                                                + msecs_to_jiffies (50);
+
+                               /*
+                                * Force full-speed connect for FSL high-speed
+                                * erratum; disable HS Chirp by setting PFSC bit
+                                */
+                               if (ehci_has_fsl_hs_errata(ehci))
+                                       temp |= (1 << PORTSC_FSL_PFSC);
                        }
                        ehci_writel(ehci, temp, status_reg);
                        break;
index f700157cd084bfdc76eb8630cdea5b8e3796f338..46f62e41bcde984ad2cf7d91e1461bf3f60f7e3c 100644 (file)
@@ -215,6 +215,7 @@ struct ehci_hcd {                   /* one per controller */
        /* SILICON QUIRKS */
        unsigned                no_selective_suspend:1;
        unsigned                has_fsl_port_bug:1; /* FreeScale */
+       unsigned                has_fsl_hs_errata:1;    /* Freescale HS quirk */
        unsigned                big_endian_mmio:1;
        unsigned                big_endian_desc:1;
        unsigned                big_endian_capbase:1;
@@ -686,6 +687,17 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
 #define        ehci_has_fsl_portno_bug(e)              (0)
 #endif
 
+#define PORTSC_FSL_PFSC        24      /* Port Force Full-Speed Connect */
+
+#if defined(CONFIG_PPC_85xx)
+/* Some Freescale processors have an erratum (USB A-005275) in which
+ * incoming packets get corrupted in HS mode
+ */
+#define ehci_has_fsl_hs_errata(e)      ((e)->has_fsl_hs_errata)
+#else
+#define ehci_has_fsl_hs_errata(e)      (0)
+#endif
+
 /*
  * While most USB host controllers implement their registers in
  * little-endian format, a minority (celleb companion chip) implement
index 9f731413ab3edd7f25ab139e39409c9f2c63dc61..534c4c5d278a31838f9afe7a7421a4397aa3d431 100644 (file)
@@ -221,6 +221,10 @@ static int fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
                pdata->has_fsl_erratum_a007792 = 1;
        else
                pdata->has_fsl_erratum_a007792 = 0;
+       if (of_get_property(np, "fsl,usb-erratum-a005275", NULL))
+               pdata->has_fsl_erratum_a005275 = 1;
+       else
+               pdata->has_fsl_erratum_a005275 = 0;
 
        /*
         * Determine whether phy_clk_valid needs to be checked
index cebdbbb4aa6901870fd0706b4434f4f676f3176c..f2912914141a83df04090ab1f95b04521517188a 100644 (file)
@@ -99,6 +99,7 @@ struct fsl_usb2_platform_data {
        unsigned        suspended:1;
        unsigned        already_suspended:1;
        unsigned        has_fsl_erratum_a007792:1;
+       unsigned        has_fsl_erratum_a005275:1;
        unsigned        check_phy_clk_valid:1;
 
        /* register save area for suspend/resume */