]> git.hungrycats.org Git - linux/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)
committerBen Hutchings <ben@decadent.org.uk>
Tue, 13 Oct 2015 02:46:05 +0000 (03:46 +0100)
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>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
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 da487fde475f867691d3f470cdde15b6f524021b..cf995d4d0c200cb639d1a0d585ab69a274b2d4eb 100644 (file)
@@ -272,6 +272,10 @@ static void ehci_fsl_usb_setup(struct ehci_hcd *ehci)
        out_be32(non_ehci + FSL_SOC_USB_SNOOP2, 0x80000000 | SNOOP_SIZE_2GB);
 #endif
 
+       /* 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))
                ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
index 4527b90332c8dd49d1cabace39a29660be20fe18..313a47d8a3df2e436f275be24d5fba5c18812e7a 100644 (file)
@@ -1049,6 +1049,13 @@ static 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 b65912d567ef321c666908282e5761001b2c85d3..bd8adbb4d315696cf1e7d3227f66be292c2720fc 100644 (file)
@@ -136,6 +136,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;
@@ -612,6 +613,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 5a42cf0c9bb6747498222b7c340a832f51ad9a54..ac19ee5c04f3488e0009513153c40a83f3d5fbaa 100644 (file)
@@ -166,6 +166,10 @@ static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
 
        prop = of_get_property(np, "phy_type", NULL);
        pdata->phy_mode = determine_usb_phy(prop);
+       if (of_get_property(np, "fsl,usb-erratum-a005275", NULL))
+               pdata->has_fsl_erratum_a005275 = 1;
+       else
+               pdata->has_fsl_erratum_a005275 = 0;
 
        for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) {
                if (!dev_data->drivers[i])
index fffdf00f87b91bd94f09071db3b999f7e5e5d210..2fe0d22a52604d83556d3defb8fa3107029779f1 100644 (file)
@@ -83,6 +83,7 @@ struct fsl_usb2_platform_data {
 
        unsigned        suspended:1;
        unsigned        already_suspended:1;
+       unsigned        has_fsl_erratum_a005275:1;
 
        /* register save area for suspend/resume */
        u32             pm_command;