Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/usb Add preliminary support for Embedded Transaction...



details:   https://anonhg.NetBSD.org/src/rev/a6f0ab31311e
branches:  trunk
changeset: 760992:a6f0ab31311e
user:      matt <matt%NetBSD.org@localhost>
date:      Tue Jan 18 08:29:24 2011 +0000

description:
Add preliminary support for Embedded Transaction Translator Function (as
found on the MPC8536 and AR9334) which allows low/full devices to be
connected to an EHCI root hub.

diffstat:

 sys/dev/usb/ehci.c    |  75 +++++++++++++++++++++++++++++++++++++++++---------
 sys/dev/usb/ehcireg.h |  17 ++++++++++-
 sys/dev/usb/ehcivar.h |   3 +-
 sys/dev/usb/usb.h     |   3 +-
 4 files changed, 81 insertions(+), 17 deletions(-)

diffs (211 lines):

diff -r 72a5e5517837 -r a6f0ab31311e sys/dev/usb/ehci.c
--- a/sys/dev/usb/ehci.c        Tue Jan 18 08:21:03 2011 +0000
+++ b/sys/dev/usb/ehci.c        Tue Jan 18 08:29:24 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ehci.c,v 1.171 2010/11/03 22:34:23 dyoung Exp $ */
+/*     $NetBSD: ehci.c,v 1.172 2011/01/18 08:29:24 matt Exp $ */
 
 /*
  * Copyright (c) 2004-2008 The NetBSD Foundation, Inc.
@@ -52,7 +52,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.171 2010/11/03 22:34:23 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.172 2011/01/18 08:29:24 matt Exp $");
 
 #include "ohci.h"
 #include "uhci.h"
@@ -354,6 +354,7 @@
                        sc->sc_ncomp = ncomp;
        }
        if (sc->sc_ncomp > 0) {
+               KASSERT(!(sc->sc_flags & EHCIF_ETTF));
                aprint_normal("%s: companion controller%s, %d port%s each:",
                    device_xname(sc->sc_dev), sc->sc_ncomp!=1 ? "s" : "",
                    EHCI_HCS_N_PCC(sparams),
@@ -395,6 +396,17 @@
        if (sc->sc_vendor_init)
                sc->sc_vendor_init(sc);
 
+       /*
+        * If we are doing embedded transaction translation function, force
+        * the controller to host mode.
+        */
+       if (sc->sc_flags & EHCIF_ETTF) {
+               uint32_t usbmode = EREAD4(sc, EHCI_USBMODE);
+               usbmode &= ~EHCI_USBMODE_CM;
+               usbmode |= EHCI_USBMODE_CM_HOST;
+               EWRITE4(sc, EHCI_USBMODE, usbmode);
+       }
+
        /* XXX need proper intr scheduling */
        sc->sc_rand = 96;
 
@@ -1535,7 +1547,17 @@
                     pipe, addr, ed->bEndpointAddress, sc->sc_addr));
 
        if (dev->myhsport) {
-               hshubaddr = dev->myhsport->parent->address;
+               /*
+                * When directly attached FS/LS device while doing embedded
+                * transaction translations and we are the hub, set the hub
+                * adddress to 0 (us).
+                */
+               if (!(sc->sc_flags & EHCIF_ETTF)
+                   || (dev->myhsport->parent->address != sc->sc_addr)) {
+                       hshubaddr = dev->myhsport->parent->address;
+               } else {
+                       hshubaddr = 0;
+               }
                hshubport = dev->myhsport->portno;
        } else {
                hshubaddr = 0;
@@ -2249,7 +2271,18 @@
                v = EOREAD4(sc, EHCI_PORTSC(index));
                DPRINTFN(8,("ehci_root_ctrl_start: port status=0x%04x\n",
                            v));
-               i = UPS_HIGH_SPEED;
+
+               if (sc->sc_flags & EHCIF_ETTF) {
+                       /*
+                        * If we are doing embedded transaction translation,
+                        * then directly attached LS/FS devices are reset by
+                        * the EHCI controller itself.  PSPD is encoded
+                        * the same way as in USBSTATUS. 
+                        */
+                       i = __SHIFTOUT(v, EHCI_PS_PSPD) * UPS_LOW_SPEED;
+               } else {
+                       i = UPS_HIGH_SPEED;
+               }
                if (v & EHCI_PS_CS)     i |= UPS_CURRENT_CONNECT_STATUS;
                if (v & EHCI_PS_PE)     i |= UPS_PORT_ENABLED;
                if (v & EHCI_PS_SUSP)   i |= UPS_SUSPEND;
@@ -2293,8 +2326,13 @@
                case UHF_PORT_RESET:
                        DPRINTFN(5,("ehci_root_ctrl_start: reset port %d\n",
                                    index));
-                       if (EHCI_PS_IS_LOWSPEED(v) && sc->sc_ncomp > 0) {
-                               /* Low speed device, give up ownership. */
+                       if (EHCI_PS_IS_LOWSPEED(v)
+                           && sc->sc_ncomp > 0
+                           && !(sc->sc_flags & EHCIF_ETTF)) {
+                               /*
+                                * Low speed device on non-ETTF controller or
+                                * unaccompanied controller, give up ownership.
+                                */
                                ehci_disown(sc, index, 1);
                                break;
                        }
@@ -2307,15 +2345,24 @@
                                err = USBD_IOERROR;
                                goto ret;
                        }
-                       /* Terminate reset sequence. */
-                       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) {
-                               err = USBD_IOERROR;
-                               goto ret;
+                       /*
+                        * An embedded transaction translater will automatically
+                        * terminate the reset sequence so there's no need to
+                        * it.
+                        */
+                       if (!(sc->sc_flags & EHCIF_ETTF)) {
+                               /* Terminate reset sequence. */
+                               v = EOREAD4(sc, port);
+                               EOWRITE4(sc, port, v);
+                               /* Wait for HC to complete reset. */
+                               usb_delay_ms(&sc->sc_bus,
+                                   EHCI_PORT_RESET_COMPLETE);
+                               if (sc->sc_dying) {
+                                       err = USBD_IOERROR;
+                                       goto ret;
+                               }
                        }
+
                        v = EOREAD4(sc, port);
                        DPRINTF(("ehci after reset, status=0x%08x\n", v));
                        if (v & EHCI_PS_PR) {
diff -r 72a5e5517837 -r a6f0ab31311e sys/dev/usb/ehcireg.h
--- a/sys/dev/usb/ehcireg.h     Tue Jan 18 08:21:03 2011 +0000
+++ b/sys/dev/usb/ehcireg.h     Tue Jan 18 08:29:24 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ehcireg.h,v 1.31 2010/06/02 18:53:39 jakllsch Exp $    */
+/*     $NetBSD: ehcireg.h,v 1.32 2011/01/18 08:29:24 matt Exp $        */
 
 /*
  * Copyright (c) 2001, 2004 The NetBSD Foundation, Inc.
@@ -76,6 +76,8 @@
 #define EHCI_HCIVERSION                0x02    /* RO Interface version number */
 
 #define EHCI_HCSPARAMS         0x04    /* RO Structural parameters */
+#define  EHCI_HCS_N_TT(x)      (((x) >> 20) & 0xf) /* # of xacts xlater ETTF */
+#define  EHCI_HCS_N_PTT(x)     (((x) >> 20) & 0xf) /* ports per xlater ETTF */
 #define  EHCI_HCS_DEBUGPORT(x) (((x) >> 20) & 0xf)
 #define  EHCI_HCS_P_INDICATOR(x) ((x) & 0x10000)
 #define  EHCI_HCS_N_CC(x)      (((x) >> 12) & 0xf) /* # of companion ctlrs */
@@ -147,6 +149,10 @@
 #define  EHCI_CONF_CF          0x00000001 /* RW configure flag */
 
 #define EHCI_PORTSC(n)         (0x40+4*(n)) /* RO, RW, RWC Port Status reg */
+#define  EHCI_PS_PSPD          0x03000000 /* RO port speed (ETTF) */
+#define  EHCI_PS_PSPD_FS       0x00000000 /* Full speed (ETTF) */
+#define  EHCI_PS_PSPD_LS       0x01000000 /* Low speed (ETTF) */
+#define  EHCI_PS_PSPD_HS       0x02000000 /* High speed (ETTF) */
 #define  EHCI_PS_WKOC_E                0x00400000 /* RW wake on over current ena */
 #define  EHCI_PS_WKDSCNNT_E    0x00200000 /* RW wake on disconnect ena */
 #define  EHCI_PS_WKCNNT_E      0x00100000 /* RW wake on connect ena */
@@ -169,6 +175,15 @@
 
 #define EHCI_PORT_RESET_COMPLETE 2 /* ms */
 
+#define        EHCI_USBMODE            0xa8            /* USB Device mode */
+#define          EHCI_USBMODE_SDIS     __BIT(4)        /* Stream disable mode 1=act */
+#define          EHCI_USBMODE_SLOM     __BIT(3)        /* setup lockouts on */
+#define          EHCI_USBMODE_ES       __BIT(2)        /* Endian Select ES=1 */
+#define          EHCI_USBMODE_CM       __BITS(0,1)     /* Controller Mode */
+#define          EHCI_USBMODE_CM_IDLE  0x00            /* Idle (combo host/device) */
+#define          EHCI_USBMODE_CM_DEV   0x02            /* Device Controller */
+#define          EHCI_USBMODE_CM_HOST  0x03            /* Host Controller */
+
 #define EHCI_FLALIGN_ALIGN     0x1000
 #define EHCI_MAX_PORTS         16 /* only 4 bits available in EHCI_HCS_N_PORTS */
 
diff -r 72a5e5517837 -r a6f0ab31311e sys/dev/usb/ehcivar.h
--- a/sys/dev/usb/ehcivar.h     Tue Jan 18 08:21:03 2011 +0000
+++ b/sys/dev/usb/ehcivar.h     Tue Jan 18 08:29:24 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ehcivar.h,v 1.37 2010/10/16 05:23:42 kiyohara Exp $ */
+/*     $NetBSD: ehcivar.h,v 1.38 2011/01/18 08:29:24 matt Exp $ */
 
 /*
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -116,6 +116,7 @@
        u_int sc_offs;                  /* offset to operational regs */
        int sc_flags;                   /* misc flags */
 #define EHCIF_DROPPED_INTR_WORKAROUND  0x01
+#define EHCIF_ETTF                     0x02 /* Emb. Transaction Translater func. */
 
        char sc_vendor[32];             /* vendor string for root hub */
        int sc_id_vendor;               /* vendor ID for root hub */
diff -r 72a5e5517837 -r a6f0ab31311e sys/dev/usb/usb.h
--- a/sys/dev/usb/usb.h Tue Jan 18 08:21:03 2011 +0000
+++ b/sys/dev/usb/usb.h Tue Jan 18 08:29:24 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: usb.h,v 1.90 2010/12/25 15:27:08 wiz Exp $     */
+/*     $NetBSD: usb.h,v 1.91 2011/01/18 08:29:24 matt Exp $    */
 /*     $FreeBSD: src/sys/dev/usb/usb.h,v 1.14 1999/11/17 22:33:46 n_hibma Exp $        */
 
 /*
@@ -436,6 +436,7 @@
 #define UPS_OVERCURRENT_INDICATOR      0x0008
 #define UPS_RESET                      0x0010
 #define UPS_PORT_POWER                 0x0100
+#define UPS_FULL_SPEED                 0x0000  /* for completeness */
 #define UPS_LOW_SPEED                  0x0200
 #define UPS_HIGH_SPEED                 0x0400
 #define UPS_PORT_TEST                  0x0800



Home | Main Index | Thread Index | Old Index