aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikhil Badola <nikhil.badola@freescale.com>2015-08-06 14:51:27 +0530
committerBen Hutchings <ben@decadent.org.uk>2015-10-13 03:46:05 +0100
commit79fcb25fc499554d030d562c33a6f1adc72c2ebd (patch)
treec9612d7aaea6e60919a5d93f41fce20075ede8d9
parent090e974e340408eaa8d42afe3bb2016be8f3523e (diff)
downloadkernel_samsung_smdk4412-79fcb25fc499554d030d562c33a6f1adc72c2ebd.zip
kernel_samsung_smdk4412-79fcb25fc499554d030d562c33a6f1adc72c2ebd.tar.gz
kernel_samsung_smdk4412-79fcb25fc499554d030d562c33a6f1adc72c2ebd.tar.bz2
drivers: usb: fsl: Workaround for USB erratum-A005275
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>
-rw-r--r--drivers/usb/host/ehci-fsl.c4
-rw-r--r--drivers/usb/host/ehci-hub.c7
-rw-r--r--drivers/usb/host/ehci.h12
-rw-r--r--drivers/usb/host/fsl-mph-dr-of.c4
-rw-r--r--include/linux/fsl_devices.h1
5 files changed, 28 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index da487fd..cf995d4 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -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);
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 4527b90..313a47d 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -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;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index b65912d..bd8adbb 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -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
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c
index 5a42cf0..ac19ee5 100644
--- a/drivers/usb/host/fsl-mph-dr-of.c
+++ b/drivers/usb/host/fsl-mph-dr-of.c
@@ -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])
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index fffdf00..2fe0d22 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -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;