Commit 79fcb25f authored by Nikhil Badola's avatar Nikhil Badola Committed by Ben Hutchings

drivers: usb: fsl: Workaround for USB erratum-A005275

commit f8786a91 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: default avatarRamneek Mehresh <ramneek.mehresh@freescale.com>
Signed-off-by: default avatarNikhil Badola <nikhil.badola@freescale.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent 090e974e
...@@ -272,6 +272,10 @@ static void ehci_fsl_usb_setup(struct ehci_hcd *ehci) ...@@ -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); out_be32(non_ehci + FSL_SOC_USB_SNOOP2, 0x80000000 | SNOOP_SIZE_2GB);
#endif #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) || if ((pdata->operating_mode == FSL_USB2_DR_HOST) ||
(pdata->operating_mode == FSL_USB2_DR_OTG)) (pdata->operating_mode == FSL_USB2_DR_OTG))
ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0); ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
......
...@@ -1049,6 +1049,13 @@ static int ehci_hub_control ( ...@@ -1049,6 +1049,13 @@ static int ehci_hub_control (
*/ */
ehci->reset_done [wIndex] = jiffies ehci->reset_done [wIndex] = jiffies
+ msecs_to_jiffies (50); + 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); ehci_writel(ehci, temp, status_reg);
break; break;
......
...@@ -136,6 +136,7 @@ struct ehci_hcd { /* one per controller */ ...@@ -136,6 +136,7 @@ struct ehci_hcd { /* one per controller */
/* SILICON QUIRKS */ /* SILICON QUIRKS */
unsigned no_selective_suspend:1; unsigned no_selective_suspend:1;
unsigned has_fsl_port_bug:1; /* FreeScale */ unsigned has_fsl_port_bug:1; /* FreeScale */
unsigned has_fsl_hs_errata:1; /* Freescale HS quirk */
unsigned big_endian_mmio:1; unsigned big_endian_mmio:1;
unsigned big_endian_desc:1; unsigned big_endian_desc:1;
unsigned big_endian_capbase:1; unsigned big_endian_capbase:1;
...@@ -612,6 +613,17 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) ...@@ -612,6 +613,17 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
#define ehci_has_fsl_portno_bug(e) (0) #define ehci_has_fsl_portno_bug(e) (0)
#endif #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 * While most USB host controllers implement their registers in
* little-endian format, a minority (celleb companion chip) implement * little-endian format, a minority (celleb companion chip) implement
......
...@@ -166,6 +166,10 @@ static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) ...@@ -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); prop = of_get_property(np, "phy_type", NULL);
pdata->phy_mode = determine_usb_phy(prop); 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++) { for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) {
if (!dev_data->drivers[i]) if (!dev_data->drivers[i])
......
...@@ -83,6 +83,7 @@ struct fsl_usb2_platform_data { ...@@ -83,6 +83,7 @@ struct fsl_usb2_platform_data {
unsigned suspended:1; unsigned suspended:1;
unsigned already_suspended:1; unsigned already_suspended:1;
unsigned has_fsl_erratum_a005275:1;
/* register save area for suspend/resume */ /* register save area for suspend/resume */
u32 pm_command; u32 pm_command;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment