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