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.
This commit is contained in:
matt 2011-01-18 08:29:24 +00:00
parent 748b8f0d25
commit 09db588a4e
4 changed files with 81 additions and 17 deletions

View File

@ -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 @@ ehci_init(ehci_softc_t *sc)
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 @@ ehci_init(ehci_softc_t *sc)
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 @@ ehci_open(usbd_pipe_handle pipe)
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 @@ ehci_root_ctrl_start(usbd_xfer_handle xfer)
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 @@ ehci_root_ctrl_start(usbd_xfer_handle xfer)
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 @@ ehci_root_ctrl_start(usbd_xfer_handle xfer)
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) {

View File

@ -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 */

View File

@ -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 @@ typedef struct ehci_softc {
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 */

View File

@ -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 @@ typedef struct {
#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