tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

EHCI of SoC



Hi! all,


We know these fixes to be necessary for some EHCI core of SoC.


Index: ehci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/ehci.c,v
retrieving revision 1.169
diff -u -r1.169 ehci.c
--- ehci.c      7 Jul 2010 03:55:01 -0000       1.169
+++ ehci.c      8 Sep 2010 14:16:51 -0000
@@ -2247,8 +2255,27 @@
                v = EOREAD4(sc, EHCI_PORTSC(index));
                DPRINTFN(8,("ehci_root_ctrl_start: port status=0x%04x\n",
                            v));
-               i = UPS_HIGH_SPEED;
-               if (v & EHCI_PS_CS)     i |= UPS_CURRENT_CONNECT_STATUS;
+               i = 0;
+               if (v & EHCI_PS_CS) {
+                       if (sc->sc_flags & EHCIF_HAVE_TT)
+#define EHCI_PS_PSPD   0x0c000000      /* Port speed */
+#define EHCI_PS_PSPD_FS        0x00000000      /*  Full speed */
+#define EHCI_PS_PSPD_LS        0x04000000      /*  Low speed */
+#define EHCI_PS_PSPD_HS        0x08000000      /*  High speed */
+                               switch (v & EHCI_PS_PSPD) {
+                               case EHCI_PS_PSPD_FS:
+                                       break;
+                               case EHCI_PS_PSPD_LS:
+                                       i |= UPS_LOW_SPEED;
+                                       break;
+                               case EHCI_PS_PSPD_HS:
+                               default:
+                                       i |= UPS_HIGH_SPEED;
+                               }
+                       else
+                               i |= UPS_HIGH_SPEED;
+                       i |= UPS_CURRENT_CONNECT_STATUS;
+               }
                if (v & EHCI_PS_PE)     i |= UPS_PORT_ENABLED;
                if (v & EHCI_PS_SUSP)   i |= UPS_SUSPEND;
                if (v & EHCI_PS_OCA)    i |= UPS_OVERCURRENT_INDICATOR;

I think that this EHCIF_HAVE_TT is not a better name.  This is necessary
in Marvell SoC.  i.MX35 is also necessary.  In addition, Oxford OXU210HP
is set in Linux.
Or, it is a condition "Companion is 0" and there is a possibility enough.

-               i = UPS_HIGH_SPEED;
-               if (v & EHCI_PS_CS)     i |= UPS_CURRENT_CONNECT_STATUS;
+               i = 0;
+               if (v & EHCI_PS_CS) {
+                       if (sc->sc_ncomp == 0) {
+                               /*
+                                * We do not have a companion.  However, we have
+                                * Transaction Translator built into the root
+                                * hub maybe.
+                                */
+                               switch (v & EHCI_PS_PSPD) {
                                :
+                               }
+                        } else
                                :
+                }


And,

@@ -2304,7 +2331,8 @@
                                goto ret;
                        }
                        /* Terminate reset sequence. */
-                       EOWRITE4(sc, port, v);
+                       v = EOREAD4(sc, port);
+                       EOWRITE4(sc, port, v & ~EHCI_PS_PR);
                        /* Wait for HC to complete reset. */
                        usb_delay_ms(&sc->sc_bus, EHCI_PORT_RESET_COMPLETE);
                        if (sc->sc_dying) {



In addition, some SoC loses some flags. Please know the newest flag.
For instance, it is Kirkwood, Orion, and i.MX35.
Moreover, this change was able to be accepted also with my ehci@pci.

  ehci0 at pci0 dev 2 function 2: NVIDIA nForce3 USB2 Host Controller



Next, this additional initialization is necessary for Marvell SoC
(eg. Kirkwood, Orion, ...).  I understood that it was initialization
for USB IP Core of ARC and TransDimension(TDI) from the source of
Linux.

@@ -392,6 +392,17 @@
                aprint_error("%s: reset timeout\n", device_xname(sc->sc_dev));
                return (USBD_IOERROR);
        }
+       if (sc->sc_flags & EHCIF_MARVELL) {
+               /* put TDI/ARC silicon into EHCI mode */
+               mode = EOREAD4(sc, EHCI_USBMODE);
+               mode &= ~EHCI_MODE_HDMASK;      /* Host/Device Mask */
+               mode |= EHCI_MODE_HOST;
+               mode |= EHCI_MODE_STRMDIS;
+               EOWRITE4(sc, EHCI_USBMODE, mode);
+       }
 
        /* XXX need proper intr scheduling */
        sc->sc_rand = 96;


I know different additional initialization to be necessary for i.MX35.
We also should initialize to LSI dependent registers by callback
function.

@@ -392,6 +392,17 @@
                aprint_error("%s: reset timeout\n", device_xname(sc->sc_dev));
                return (USBD_IOERROR);
        }
+       if (sc->sc_lsidep_init != NULL)
+               sc->sc_lsidep_init(sc);
 
        /* XXX need proper intr scheduling */
        sc->sc_rand = 96;


Plaese give me your idei.  ;-)

Thanks,
--
kiyohara


Home | Main Index | Thread Index | Old Index