]> git.ipfire.org Git - thirdparty/kernel/stable.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)
committerLuis Henriques <luis.henriques@canonical.com>
Wed, 28 Oct 2015 10:33:15 +0000 (10:33 +0000)
commit f8786a91548df6930643a052e40e5c0b7a8403a5 upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
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 c412c4f35007c4c154d4d4d2170bc8ab554d9038..0b5b95e350dc59700ca4b4a1da193e443c90291c 100644 (file)
@@ -298,6 +298,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 837a1edd33e251d9fccb271f66e7d9863fc150ca..f82bc5cded08574056810db070a080dc9d1009b7 100644 (file)
@@ -1218,6 +1218,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 eee228a26a0e71795b472218feefa7c5380e62d0..1c57b4a148e491d114feb33dfeb20746464cac11 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 4d03afb7cf4a15335419f172137ab5bcb2cf1567..21dcdc8f95c2aa769ddcdcfaae0949172996493e 100644 (file)
@@ -211,6 +211,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;
 
        if (pdata->have_sysif_regs) {
                if (pdata->controller_ver < 0) {
index 0f17316ce42082f17d39b0147893b7d066b6a07e..f7103ba6e50965ea41f2dc2b2d3825ac48c671f5 100644 (file)
@@ -93,6 +93,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;
 
        /* register save area for suspend/resume */
        u32             pm_command;