diff options
author | 2016-10-02 06:36:39 +0000 | |
---|---|---|
committer | 2016-10-02 06:36:39 +0000 | |
commit | 9d524485a10715d8a443d4868a6899a3cf53e004 (patch) | |
tree | 0be1fb7deb73c72e414f4d76a323a3c5725cb519 | |
parent | some minor tweaks; ok yasuoka (diff) | |
download | wireguard-openbsd-9d524485a10715d8a443d4868a6899a3cf53e004.tar.xz wireguard-openbsd-9d524485a10715d8a443d4868a6899a3cf53e004.zip |
Save and restore the (non-standard) USBMODE register around a reset of the
controller. This register controls whether the controller is in device or
host mode on many dual role controllers and gets reset during a reset of
the controller, placing the controller in (non-functional) idle mode. By
saving and restoring it, we keep the controller in host mode. Since this is
a non-standard register, add a new EHCIF_USBMODE flag and only do the save and
restore if it has been set.
Makes the upper "OTG" port of the Cubox-i work.
ok mpi@, jsg@
-rw-r--r-- | sys/arch/armv7/imx/imxehci.c | 10 | ||||
-rw-r--r-- | sys/dev/usb/ehci.c | 10 | ||||
-rw-r--r-- | sys/dev/usb/ehcireg.h | 9 | ||||
-rw-r--r-- | sys/dev/usb/ehcivar.h | 3 |
4 files changed, 22 insertions, 10 deletions
diff --git a/sys/arch/armv7/imx/imxehci.c b/sys/arch/armv7/imx/imxehci.c index 89fe44d0edd..a76d477f5e6 100644 --- a/sys/arch/armv7/imx/imxehci.c +++ b/sys/arch/armv7/imx/imxehci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: imxehci.c,v 1.17 2016/08/13 11:08:58 kettenis Exp $ */ +/* $OpenBSD: imxehci.c,v 1.18 2016/10/02 06:36:39 kettenis Exp $ */ /* * Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se> * @@ -58,9 +58,6 @@ /* ehci */ #define USB_EHCI_OFFSET 0x100 -#define EHCI_USBMODE 0xa8 - -#define EHCI_USBMODE_HOST (3 << 0) #define EHCI_PS_PTS_UTMI_MASK ((1 << 25) | (3 << 30)) /* usb non-core */ @@ -144,6 +141,7 @@ imxehci_attach(struct device *parent, struct device *self, void *aux) sc->sc.iot = faa->fa_iot; sc->sc.sc_bus.dmatag = faa->fa_dmat; sc->sc.sc_size = faa->fa_reg[0].size - USB_EHCI_OFFSET; + sc->sc.sc_flags = EHCIF_USBMODE; /* Map I/O space */ if (bus_space_map(sc->sc.iot, faa->fa_reg[0].addr, @@ -247,8 +245,8 @@ imxehci_attach(struct device *parent, struct device *self, void *aux) USBPHY_CTRL_ENUTMILEVEL2 | USBPHY_CTRL_ENUTMILEVEL3); /* set host mode */ - EWRITE4(&sc->sc, EHCI_USBMODE, - EREAD4(&sc->sc, EHCI_USBMODE) | EHCI_USBMODE_HOST); + EOWRITE4(&sc->sc, EHCI_USBMODE, + EOREAD4(&sc->sc, EHCI_USBMODE) | EHCI_USBMODE_CM_HOST); /* set to UTMI mode */ EOWRITE4(&sc->sc, EHCI_PORTSC(1), diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c index 2d5c461cdad..5b5ddbebaff 100644 --- a/sys/dev/usb/ehci.c +++ b/sys/dev/usb/ehci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ehci.c,v 1.193 2016/09/15 02:00:17 dlg Exp $ */ +/* $OpenBSD: ehci.c,v 1.194 2016/10/02 06:36:39 kettenis Exp $ */ /* $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $ */ /* @@ -1114,7 +1114,7 @@ ehci_activate(struct device *self, int act) usbd_status ehci_reset(struct ehci_softc *sc) { - u_int32_t hcr; + u_int32_t hcr, usbmode; int i; EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */ @@ -1128,6 +1128,9 @@ ehci_reset(struct ehci_softc *sc) if (!hcr) printf("%s: halt timeout\n", sc->sc_bus.bdev.dv_xname); + if (sc->sc_flags & EHCIF_USBMODE) + usbmode = EOREAD4(sc, EHCI_USBMODE); + EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET); for (i = 0; i < 100; i++) { usb_delay_ms(&sc->sc_bus, 1); @@ -1141,6 +1144,9 @@ ehci_reset(struct ehci_softc *sc) return (USBD_IOERROR); } + if (sc->sc_flags & EHCIF_USBMODE) + EOWRITE4(sc, EHCI_USBMODE, usbmode); + return (USBD_NORMAL_COMPLETION); } diff --git a/sys/dev/usb/ehcireg.h b/sys/dev/usb/ehcireg.h index f88c8f93d14..10c50a5cd4e 100644 --- a/sys/dev/usb/ehcireg.h +++ b/sys/dev/usb/ehcireg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ehcireg.h,v 1.20 2015/04/10 13:56:42 mpi Exp $ */ +/* $OpenBSD: ehcireg.h,v 1.21 2016/10/02 06:36:39 kettenis Exp $ */ /* $NetBSD: ehcireg.h,v 1.17 2004/06/23 06:45:56 mycroft Exp $ */ /* @@ -162,6 +162,13 @@ #define EHCI_PORT_RESET_COMPLETE 2 /* ms */ +/* Nonstandard register to set controller mode. */ +#define EHCI_USBMODE 0x68 +#define EHCI_USBMODE_CM_M 0x00000003 +#define EHCI_USBMODE_CM_IDLE 0x00000000 +#define EHCI_USBMODE_CM_DEVICE 0x00000002 +#define EHCI_USBMODE_CM_HOST 0x00000003 + #define EHCI_FLALIGN_ALIGN 0x1000 /* No data structure may cross a page boundary. */ diff --git a/sys/dev/usb/ehcivar.h b/sys/dev/usb/ehcivar.h index 86b36405ecc..8fd2c89e8da 100644 --- a/sys/dev/usb/ehcivar.h +++ b/sys/dev/usb/ehcivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ehcivar.h,v 1.36 2015/11/02 14:55:41 mpi Exp $ */ +/* $OpenBSD: ehcivar.h,v 1.37 2016/10/02 06:36:39 kettenis Exp $ */ /* $NetBSD: ehcivar.h,v 1.19 2005/04/29 15:04:29 augustss Exp $ */ /* @@ -130,6 +130,7 @@ struct ehci_softc { int sc_flags; /* misc flags */ #define EHCIF_DROPPED_INTR_WORKAROUND 0x01 #define EHCIF_PCB_INTR 0x02 +#define EHCIF_USBMODE 0x04 char sc_vendor[16]; /* vendor string for root hub */ int sc_id_vendor; /* vendor ID for root hub */ |