usb: ehci-fsl: set INCR8 mode for system bus interface on MPC512x
authorAnatolij Gustschin <agust@denx.de>
Tue, 24 Jan 2012 21:17:38 +0000 (22:17 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 24 Jan 2012 23:04:01 +0000 (15:04 -0800)
Use INCR8 mode for system bus interface of the USB controller
on MPC512x. This is a work-around for the AHB bus lock up
problem observed on MPC512x when there is heavy simultaneous
PATA write or network (FEC) activity.

See also "12.4 The USB controller can issue transactions that lock
up the AHB bus under certain conditions" in MPC5121e (M36P) Errata.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
Tested-by: Matthias Fuchs <matthias.fuchs@esd.ue>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-fsl.h

index e90344a1763173e4c49c9099ecf65a7609aad358..42414cd73571edcdbba31c327c1736b00092dd66 100644 (file)
@@ -316,7 +316,9 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
        struct ehci_hcd *ehci = hcd_to_ehci(hcd);
        int retval;
        struct fsl_usb2_platform_data *pdata;
+       struct device *dev;
 
+       dev = hcd->self.controller;
        pdata = hcd->self.controller->platform_data;
        ehci->big_endian_desc = pdata->big_endian_desc;
        ehci->big_endian_mmio = pdata->big_endian_mmio;
@@ -346,6 +348,16 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
 
        ehci_reset(ehci);
 
+       if (of_device_is_compatible(dev->parent->of_node,
+                                   "fsl,mpc5121-usb2-dr")) {
+               /*
+                * set SBUSCFG:AHBBRST so that control msgs don't
+                * fail when doing heavy PATA writes.
+                */
+               ehci_writel(ehci, SBUSCFG_INCR8,
+                           hcd->regs + FSL_SOC_USB_SBUSCFG);
+       }
+
        retval = ehci_fsl_reinit(ehci);
        return retval;
 }
@@ -469,6 +481,8 @@ static int ehci_fsl_mpc512x_drv_resume(struct device *dev)
        ehci_writel(ehci, ISIPHYCTRL_PXE | ISIPHYCTRL_PHYE,
                    hcd->regs + FSL_SOC_USB_ISIPHYCTRL);
 
+       ehci_writel(ehci, SBUSCFG_INCR8, hcd->regs + FSL_SOC_USB_SBUSCFG);
+
        /* restore EHCI registers */
        ehci_writel(ehci, pdata->pm_command, &ehci->regs->command);
        ehci_writel(ehci, pdata->pm_intr_enable, &ehci->regs->intr_enable);
index 4918062211656c276f5904cc50d45605076ed026..0855be8b5b475caba9a2e2b77ee100c0646f25a5 100644 (file)
@@ -19,6 +19,8 @@
 #define _EHCI_FSL_H
 
 /* offsets for the non-ehci registers in the FSL SOC USB controller */
+#define FSL_SOC_USB_SBUSCFG    0x90
+#define SBUSCFG_INCR8          0x02    /* INCR8, specified */
 #define FSL_SOC_USB_ULPIVP     0x170
 #define FSL_SOC_USB_PORTSC1    0x184
 #define PORT_PTS_MSK           (3<<30)