[PATCH] USB: EHCI and Freescale 83xx quirk
authorKumar Gala <galak@gate.crashing.org>
Fri, 20 Jan 2006 21:57:52 +0000 (13:57 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 20 Mar 2006 22:49:55 +0000 (14:49 -0800)
On the MPC834x processors the multiport host (MPH) EHCI controller has an
erratum in which the port number in the queue head expects to be 0..N-1
instead of 1..N.  If we are on one of these chips we subtract one from
the port number before putting it into the queue head.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci.h

index c6012d6cd527d2e444be07ecf9dd29b450f60390..59f90f76ee31a9cacc8878dd0a8b82b6ec0de3a9 100644 (file)
@@ -198,6 +198,16 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
                mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
 
        if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
+               unsigned int chip, rev, svr;
+
+               svr = mfspr(SPRN_SVR);
+               chip = svr >> 16;
+               rev = (svr >> 4) & 0xf;
+
+               /* Deal with USB Erratum #14 on MPC834x Rev 1.0 & 1.1 chips */
+               if ((rev == 1) && (chip >= 0x8050) && (chip <= 0x8055))
+                       ehci->has_fsl_port_bug = 1;
+
                if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
                        mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
                if (pdata->port_enables & FSL_USB2_PORT1_ENABLED)
index 9b13bf2fa98d2c3bab626642a1ea925e183ed9e9..6e28e593c044db89ef93b364b4a6eb4a14ee1e24 100644 (file)
@@ -721,7 +721,14 @@ qh_make (
                info1 |= maxp << 16;
 
                info2 |= (EHCI_TUNE_MULT_TT << 30);
-               info2 |= urb->dev->ttport << 23;
+
+               /* Some Freescale processors have an erratum in which the
+                * port number in the queue head was 0..N-1 instead of 1..N.
+                */
+               if (ehci_has_fsl_portno_bug(ehci))
+                       info2 |= (urb->dev->ttport-1) << 23;
+               else
+                       info2 |= urb->dev->ttport << 23;
 
                /* set the address of the TT; for TDI's integrated
                 * root hub tt, leave it zeroed.
index 86af41c41de123eeada9d7499e9d53f4fb41e7dd..679c1cdcc9154d286235cbe99c7451cf26751e65 100644 (file)
@@ -88,8 +88,11 @@ struct ehci_hcd {                    /* one per controller */
        unsigned long           next_statechange;
        u32                     command;
 
+       /* SILICON QUIRKS */
        unsigned                is_tdi_rh_tt:1; /* TDI roothub with TT */
        unsigned                no_selective_suspend:1;
+       unsigned                has_fsl_port_bug:1; /* FreeScale */
+
        u8                      sbrn;           /* packed release number */
 
        /* irq statistics */
@@ -637,6 +640,18 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
 #define        ehci_port_speed(ehci, portsc)   (1<<USB_PORT_FEAT_HIGHSPEED)
 #endif
 
+/*-------------------------------------------------------------------------*/
+
+#ifdef CONFIG_PPC_83xx
+/* Some Freescale processors have an erratum in which the TT
+ * port number in the queue head was 0..N-1 instead of 1..N.
+ */
+#define        ehci_has_fsl_portno_bug(e)              ((e)->has_fsl_port_bug)
+#else
+#define        ehci_has_fsl_portno_bug(e)              (0)
+#endif
+
+
 /*-------------------------------------------------------------------------*/
 
 #ifndef DEBUG