I've had this sitting around for a while and I figure it's time to get it in
the tree.  Octeon II sensibly got rid of the DWC USB controller and put in ehci
and ohci compliant controllers instead, so all we need to do here is set up a
few registers in the usb controller interface and attach the standard drivers.
The diff below adds octuctl, a driver for the usb controller interface, and 
octehci and octohci, which are attachments for ehci and ohci.

I've tested this on a Lanner MR326b, where it allows me to boot off a usb
stick, and on an Edgerouter Lite, where it makes no difference at all.

ok?

Index: conf/GENERIC
===================================================================
RCS file: /cvs/src/sys/arch/octeon/conf/GENERIC,v
retrieving revision 1.24
diff -u -p -u -p -r1.24 GENERIC
--- conf/GENERIC        14 Jan 2016 17:20:34 -0000      1.24
+++ conf/GENERIC        17 Mar 2016 01:43:51 -0000
@@ -64,9 +64,14 @@ wd*          at pciide? flags 0x0000
 
 # USB Controllers
 dwctwo0        at iobus? irq 56
+octuctl0       at iobus? irq 56
+ehci0          at octuctl?
+ohci0          at octuctl?
 
 # USB bus support
 usb*           at dwctwo?
+usb*           at ehci?
+usb*           at ohci?
 
 # USB devices
 uhub*          at usb?         # USB Hubs
Index: conf/RAMDISK
===================================================================
RCS file: /cvs/src/sys/arch/octeon/conf/RAMDISK,v
retrieving revision 1.23
diff -u -p -u -p -r1.23 RAMDISK
--- conf/RAMDISK        14 Jan 2016 17:20:34 -0000      1.23
+++ conf/RAMDISK        17 Mar 2016 01:43:51 -0000
@@ -55,7 +55,14 @@ pciide*              at pci? flags 0x0000
 wd*            at pciide? flags 0x0000
 
 dwctwo0                at iobus0 irq 56
+octuctl0       at iobus0 irq 56
+ehci0          at octuctl?
+ohci0          at octuctl?
+
 usb*           at dwctwo?
+usb*           at ehci?
+usb*           at ohci?
+
 uhub*          at usb?
 uhub*          at uhub?
 umass*         at uhub?
Index: conf/files.octeon
===================================================================
RCS file: /cvs/src/sys/arch/octeon/conf/files.octeon,v
retrieving revision 1.28
diff -u -p -u -p -r1.28 files.octeon
--- conf/files.octeon   14 Jan 2016 17:20:34 -0000      1.28
+++ conf/files.octeon   17 Mar 2016 01:43:51 -0000
@@ -71,6 +71,14 @@ file arch/octeon/dev/cn30xxsmi.c                     iobus
 attach dwctwo at iobus with octdwctwo
 file   arch/octeon/dev/octdwctwo.c                     octdwctwo       
needs-flag
 
+device octuctl {}
+attach octuctl at iobus
+file   arch/octeon/dev/octuctl.c                       octuctl         
needs-flag
+attach ehci at octuctl with octehci
+file   arch/octeon/dev/octehci.c                       octehci
+attach ohci at octuctl with octohci
+file   arch/octeon/dev/octohci.c                       octohci
+
 # On-board CF
 device octcf: disk
 attach octcf at iobus
Index: dev/octehci.c
===================================================================
RCS file: dev/octehci.c
diff -N dev/octehci.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ dev/octehci.c       17 Mar 2016 01:43:52 -0000
@@ -0,0 +1,118 @@
+/*     $OpenBSD$ */
+
+/*
+ * Copyright (c) 2015 Jonathan Matthew  <jmatt...@openbsd.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/intr.h>
+#include <machine/bus.h>
+#include <machine/octeonreg.h>
+#include <machine/octeonvar.h>
+
+#include <octeon/dev/octuctlreg.h>
+#include <octeon/dev/octuctlvar.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
+
+#include <sys/rwlock.h>
+#include <dev/usb/ehcireg.h>
+#include <dev/usb/ehcivar.h>
+
+struct octehci_softc {
+       struct ehci_softc       sc_ehci;
+
+       void                    *sc_ih;
+};
+
+int            octehci_match(struct device *, void *, void *);
+void           octehci_attach(struct device *, struct device *, void *);
+
+const struct cfattach octehci_ca = {
+       sizeof(struct octehci_softc), octehci_match, octehci_attach,
+};
+
+struct cfdriver octehci_cd = {
+       NULL, "ehci", DV_DULL
+};
+
+int
+octehci_match(struct device *parent, void *match, void *aux)
+{
+       struct octuctl_attach_args *aa = aux;
+
+       if (strcmp(aa->aa_name, "ehci") != 0)
+               return (0);
+
+       return (1);
+}
+
+void
+octehci_attach(struct device *parent, struct device *self, void *aux)
+{
+       struct octehci_softc *sc = (struct octehci_softc *)self;
+       struct octuctl_attach_args *aa = aux;
+       uint64_t port_ctl;
+       int rc;
+       int s;
+
+       sc->sc_ehci.iot = aa->aa_bust;
+       sc->sc_ehci.sc_bus.pipe_size = sizeof(struct usbd_pipe);
+       sc->sc_ehci.sc_bus.dmatag = aa->aa_dmat;
+
+       rc = bus_space_map(sc->sc_ehci.iot, UCTL_EHCI_BASE, UCTL_EHCI_SIZE,
+           0, &sc->sc_ehci.ioh);
+       KASSERT(rc == 0);
+
+       port_ctl = bus_space_read_8(aa->aa_octuctl_bust, aa->aa_ioh,
+           UCTL_EHCI_CTL);
+       port_ctl &= ~UCTL_EHCI_CTL_L2C_ADDR_MSB_MASK;
+       port_ctl |= (1 << UCTL_EHCI_CTL_L2C_DESC_EMOD_SHIFT);
+       port_ctl |= (1 << UCTL_EHCI_CTL_L2C_BUFF_EMOD_SHIFT);
+       port_ctl |= UCTL_EHCI_CTL_EHCI_64B_ADDR_EN;
+       bus_space_write_8(aa->aa_octuctl_bust, aa->aa_ioh, UCTL_EHCI_CTL,
+           port_ctl);
+
+       s = splhardusb();
+       sc->sc_ehci.sc_offs = EREAD1(&sc->sc_ehci, EHCI_CAPLENGTH);
+       EOWRITE2(&sc->sc_ehci, EHCI_USBINTR, 0);
+
+       sc->sc_ehci.sc_id_vendor = 0;
+       strlcpy(sc->sc_ehci.sc_vendor, "Octeon", sizeof(sc->sc_ehci.sc_vendor));
+
+       sc->sc_ih = octeon_intr_establish(CIU_INT_USB, IPL_USB, ehci_intr,
+           (void *)&sc->sc_ehci, sc->sc_ehci.sc_bus.bdev.dv_xname);
+       KASSERT(sc->sc_ih != NULL);
+
+       rc = ehci_init(&sc->sc_ehci);
+       if (rc != USBD_NORMAL_COMPLETION) {
+               printf(": init failed, error=%d\n", rc);
+               octeon_intr_disestablish(sc->sc_ih);
+               bus_space_unmap(sc->sc_ehci.iot, sc->sc_ehci.ioh,
+                   UCTL_EHCI_SIZE);
+               splx(s);
+               return;
+       }
+
+       splx(s);
+       printf("\n");
+       if (rc == 0)
+               config_found(self, &sc->sc_ehci.sc_bus, usbctlprint);
+}
Index: dev/octeon_iobus.c
===================================================================
RCS file: /cvs/src/sys/arch/octeon/dev/octeon_iobus.c,v
retrieving revision 1.14
diff -u -p -u -p -r1.14 octeon_iobus.c
--- dev/octeon_iobus.c  20 Jul 2015 19:44:32 -0000      1.14
+++ dev/octeon_iobus.c  17 Mar 2016 01:43:52 -0000
@@ -48,6 +48,7 @@
 #include <octeon/dev/iobusvar.h>
 #include <octeon/dev/cn30xxgmxreg.h>
 #include <octeon/dev/octhcireg.h>      /* USBN_BASE */
+#include <octeon/dev/octuctlreg.h>
 
 int    iobusmatch(struct device *, void *, void *);
 void   iobusattach(struct device *, struct device *, void *);
@@ -150,6 +151,7 @@ static const struct octeon_iobus_addrs i
        { "octrng",     OCTEON_RNG_BASE },
        { "dwctwo",     USBN_BASE       },
        { "amdcf",      OCTEON_AMDCF_BASE},
+       { "octuctl",    UCTL_BASE       },
 };
 
 /* There can only be one. */
Index: dev/octohci.c
===================================================================
RCS file: dev/octohci.c
diff -N dev/octohci.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ dev/octohci.c       17 Mar 2016 01:43:52 -0000
@@ -0,0 +1,142 @@
+/*     $OpenBSD$ */
+
+/*
+ * Copyright (c) 2015 Jonathan Matthew  <jmatt...@openbsd.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/intr.h>
+#include <machine/bus.h>
+#include <machine/octeonreg.h>
+#include <machine/octeonvar.h>
+
+#include <octeon/dev/octuctlreg.h>
+#include <octeon/dev/octuctlvar.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
+
+#include <dev/usb/ohcireg.h>
+#include <dev/usb/ohcivar.h>
+
+struct octohci_softc {
+       struct ohci_softc       sc_ohci;
+
+       void                    *sc_ih;
+};
+
+int            octohci_match(struct device *, void *, void *);
+void           octohci_attach(struct device *, struct device *, void *);
+void           octohci_attach_deferred(struct device *);
+
+const struct cfattach octohci_ca = {
+       sizeof(struct octohci_softc), octohci_match, octohci_attach,
+};
+
+struct cfdriver octohci_cd = {
+       NULL, "ohci", DV_DULL
+};
+
+int
+octohci_match(struct device *parent, void *match, void *aux)
+{
+       struct octuctl_attach_args *aa = aux;
+
+       if (strcmp(aa->aa_name, "ohci") != 0)
+               return (0);
+
+       return (1);
+}
+
+void
+octohci_attach(struct device *parent, struct device *self, void *aux)
+{
+       struct octohci_softc *sc = (struct octohci_softc *)self;
+       struct octuctl_attach_args *aa = aux;
+       char *devname;
+       uint64_t port_ctl;
+       int rc;
+       int s;
+
+       sc->sc_ohci.iot = aa->aa_bust;
+       sc->sc_ohci.sc_bus.pipe_size = sizeof(struct usbd_pipe);
+       sc->sc_ohci.sc_bus.dmatag = aa->aa_dmat;
+
+       rc = bus_space_map(sc->sc_ohci.iot, UCTL_OHCI_BASE, UCTL_OHCI_SIZE,
+           0, &sc->sc_ohci.ioh);
+       KASSERT(rc == 0);
+
+       port_ctl = bus_space_read_8(aa->aa_octuctl_bust, aa->aa_ioh,
+           UCTL_OHCI_CTL);
+       port_ctl &= ~UCTL_OHCI_CTL_L2C_ADDR_MSB_MASK;
+       port_ctl |= (1 << UCTL_OHCI_CTL_L2C_DESC_EMOD_SHIFT);
+       port_ctl |= (1 << UCTL_OHCI_CTL_L2C_BUFF_EMOD_SHIFT);
+       bus_space_write_8(aa->aa_octuctl_bust, aa->aa_ioh, UCTL_OHCI_CTL,
+           port_ctl);
+
+       s = splusb();
+
+       sc->sc_ohci.sc_id_vendor = 0;
+       strlcpy(sc->sc_ohci.sc_vendor, "Octeon", sizeof(sc->sc_ohci.sc_vendor));
+
+       sc->sc_ih = octeon_intr_establish(CIU_INT_USB, IPL_USB, ohci_intr,
+           (void *)&sc->sc_ohci, devname);
+       KASSERT(sc->sc_ih != NULL);
+
+       if ((ohci_checkrev(&sc->sc_ohci) != USBD_NORMAL_COMPLETION) ||
+           (ohci_handover(&sc->sc_ohci) != USBD_NORMAL_COMPLETION))
+               goto failed;
+
+       /* ignore interrupts for now */
+       sc->sc_ohci.sc_bus.dying = 1;
+       config_defer(self, octohci_attach_deferred);
+
+       splx(s);
+       return;
+
+failed:
+       octeon_intr_disestablish(sc->sc_ih);
+       bus_space_unmap(sc->sc_ohci.iot, sc->sc_ohci.ioh, UCTL_OHCI_SIZE);
+       splx(s);
+       return;
+}
+
+void
+octohci_attach_deferred(struct device *self)
+{
+       struct octohci_softc *sc = (struct octohci_softc *)self;
+       usbd_status r;
+       int s;
+
+       s = splusb();
+       sc->sc_ohci.sc_bus.dying = 0;
+
+       r = ohci_init(&sc->sc_ohci);
+       splx(s);
+
+       if (r != USBD_NORMAL_COMPLETION) {
+               printf("%s: init failed, error=%d\n",
+                   sc->sc_ohci.sc_bus.bdev.dv_xname, r);
+               octeon_intr_disestablish(sc->sc_ih);
+               bus_space_unmap(sc->sc_ohci.iot, sc->sc_ohci.ioh,
+                   UCTL_OHCI_SIZE);
+       } else {
+               config_found(self, &sc->sc_ohci.sc_bus, usbctlprint);
+       }
+}
Index: dev/octuctl.c
===================================================================
RCS file: dev/octuctl.c
diff -N dev/octuctl.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ dev/octuctl.c       17 Mar 2016 01:43:52 -0000
@@ -0,0 +1,266 @@
+/*     $OpenBSD$ */
+
+/*
+ * Copyright (c) 2015 Jonathan Matthew  <jmatt...@openbsd.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/rwlock.h>
+
+#include <machine/intr.h>
+#include <machine/bus.h>
+#include <machine/octeonreg.h>
+#include <machine/octeonvar.h>
+#include <machine/octeon_model.h>
+
+#include <octeon/dev/iobusvar.h>
+#include <octeon/dev/octuctlreg.h>
+#include <octeon/dev/octuctlvar.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
+
+#include <dev/usb/ehcireg.h>
+#include <dev/usb/ehcivar.h>
+#include <dev/usb/ohcireg.h>
+#include <dev/usb/ohcivar.h>
+
+struct octuctl_softc {
+       bus_space_tag_t         sc_iot;
+       bus_space_handle_t      sc_ioh;
+
+       void *                  sc_ehci_ih;
+       void *                  sc_ohci_ih;
+       struct ehci_softc       sc_ehci;
+       struct ohci_softc       sc_ohci;
+};
+
+int    octuctl_match(struct device *, void *, void *);
+void   octuctl_attach(struct device *, struct device *, void *);
+
+const struct cfattach octuctl_ca = {
+       sizeof(struct octuctl_softc), octuctl_match, octuctl_attach,
+};
+
+struct cfdriver octuctl_cd = {
+       NULL, "octuctl", DV_DULL
+};
+
+uint8_t octuctl_read_1(bus_space_tag_t, bus_space_handle_t, bus_size_t);
+uint16_t octuctl_read_2(bus_space_tag_t, bus_space_handle_t, bus_size_t);
+uint32_t octuctl_read_4(bus_space_tag_t, bus_space_handle_t, bus_size_t);
+void octuctl_write_1(bus_space_tag_t, bus_space_handle_t, bus_size_t, uint8_t);
+void octuctl_write_2(bus_space_tag_t, bus_space_handle_t, bus_size_t, 
uint16_t);
+void octuctl_write_4(bus_space_tag_t, bus_space_handle_t, bus_size_t, 
uint32_t);
+
+bus_space_t octuctl_tag = {
+       .bus_base = PHYS_TO_XKPHYS(0, CCA_NC),
+       .bus_private = NULL,
+       ._space_read_1 = octuctl_read_1,
+       ._space_write_1 = octuctl_write_1,
+       ._space_read_2 = octuctl_read_2,
+       ._space_write_2 = octuctl_write_2,
+       ._space_read_4 = octuctl_read_4,
+       ._space_write_4 = octuctl_write_4,
+       ._space_map = iobus_space_map,
+       ._space_unmap = iobus_space_unmap,
+       ._space_subregion = generic_space_region,
+       ._space_vaddr = generic_space_vaddr
+};
+
+uint8_t
+octuctl_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
+{
+       return *(volatile uint8_t *)(h + (o^3));
+}
+
+uint16_t
+octuctl_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
+{
+       return *(volatile uint16_t *)(h + (o^2));
+}
+
+uint32_t
+octuctl_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
+{
+       return *(volatile uint32_t *)(h + o);
+}
+
+void
+octuctl_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, uint8_t 
v)
+{
+       *(volatile uint8_t *)(h + (o^3)) = v;
+}
+
+void
+octuctl_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 
uint16_t v)
+{
+       *(volatile uint16_t *)(h + (o^2)) = v;
+}
+
+void
+octuctl_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 
uint32_t v)
+{
+       *(volatile uint32_t *)(h + o) = v;
+}
+
+int
+octuctl_match(struct device *parent, void *match, void *aux)
+{
+       int id;
+
+       id = octeon_get_chipid();
+       switch (octeon_model_family(id)) {
+       case OCTEON_MODEL_FAMILY_CN61XX:
+               return (1);
+       default:
+               return (0);
+       }
+}
+
+int
+octuctlprint(void *aux, const char *parentname)
+{
+       return (QUIET);
+}
+
+void
+octuctl_clock_setup(struct octuctl_softc *sc, uint64_t ctl)
+{
+       int ioclockdelay;
+       int div;
+       int lastdiv;
+       int validdiv[] = { 1, 2, 3, 4, 6, 8, 12, INT_MAX };
+       int i;
+
+       ioclockdelay = 64000000ull / octeon_ioclock_speed();
+       div = octeon_ioclock_speed() / 130000000ull;
+
+       /* start usb controller reset */
+       ctl |= UCTL_CLK_RST_CTL_P_POR;
+       ctl &= ~(UCTL_CLK_RST_CTL_HRST |
+           UCTL_CLK_RST_CTL_P_PRST |
+           UCTL_CLK_RST_CTL_O_CLKDIV_EN |
+           UCTL_CLK_RST_CTL_H_CLKDIV_EN |
+           UCTL_CLK_RST_CTL_H_CLKDIV_RST |
+           UCTL_CLK_RST_CTL_O_CLKDIV_RST);
+       bus_space_write_8(sc->sc_iot, sc->sc_ioh, UCTL_CLK_RST_CTL, ctl);
+
+       /* set up for 12mhz crystal */
+       ctl &= ~((3 << UCTL_CLK_RST_CTL_P_REFCLK_DIV_SHIFT) |
+           (3 << UCTL_CLK_RST_CTL_P_REFCLK_SEL_SHIFT));
+       bus_space_write_8(sc->sc_iot, sc->sc_ioh, UCTL_CLK_RST_CTL, ctl);
+
+       /* set clock divider */
+       lastdiv = 1;
+       for (i = 0; i < nitems(validdiv); i++) {
+               if (div < validdiv[i]) {
+                       div = lastdiv;
+                       break;
+               }
+               lastdiv = validdiv[i];
+       }
+
+       ctl &= ~(0xf << UCTL_CLK_RST_CTL_H_DIV_SHIFT);
+       ctl |= (div << UCTL_CLK_RST_CTL_H_DIV_SHIFT);
+       bus_space_write_8(sc->sc_iot, sc->sc_ioh, UCTL_CLK_RST_CTL, ctl);
+
+       /* turn hclk on */
+       ctl = bus_space_read_8(sc->sc_iot, sc->sc_ioh,
+           UCTL_CLK_RST_CTL);
+       ctl |= UCTL_CLK_RST_CTL_H_CLKDIV_EN;
+       bus_space_write_8(sc->sc_iot, sc->sc_ioh, UCTL_CLK_RST_CTL, ctl);
+       ctl |= UCTL_CLK_RST_CTL_H_CLKDIV_RST;
+       bus_space_write_8(sc->sc_iot, sc->sc_ioh, UCTL_CLK_RST_CTL, ctl);
+
+       delay(ioclockdelay);
+
+       /* power-on-reset finished */
+       ctl &= ~UCTL_CLK_RST_CTL_P_POR;
+       bus_space_write_8(sc->sc_iot, sc->sc_ioh, UCTL_CLK_RST_CTL, ctl);
+       
+       delay(1000);
+
+       /* set up ohci clocks */
+       ctl |= UCTL_CLK_RST_CTL_O_CLKDIV_RST;
+       bus_space_write_8(sc->sc_iot, sc->sc_ioh, UCTL_CLK_RST_CTL, ctl);
+       ctl |= UCTL_CLK_RST_CTL_O_CLKDIV_EN;
+       bus_space_write_8(sc->sc_iot, sc->sc_ioh, UCTL_CLK_RST_CTL, ctl);
+       
+       delay(ioclockdelay);
+
+       /* phy reset */
+       ctl |= UCTL_CLK_RST_CTL_P_PRST;
+       bus_space_write_8(sc->sc_iot, sc->sc_ioh, UCTL_CLK_RST_CTL, ctl);
+
+       delay(1);
+
+       /* clear host reset */
+       ctl |= UCTL_CLK_RST_CTL_HRST;
+       bus_space_write_8(sc->sc_iot, sc->sc_ioh, UCTL_CLK_RST_CTL, ctl);
+}
+
+void
+octuctl_attach(struct device *parent, struct device *self, void *aux)
+{
+       struct octuctl_softc *sc = (struct octuctl_softc *)self;
+       struct iobus_attach_args *aa = aux;
+       struct octuctl_attach_args uaa;
+       uint64_t port_ctl;
+       uint64_t ctl;
+       uint64_t preg;
+       uint64_t txvref;
+       int rc;
+       int port;
+
+       sc->sc_iot = aa->aa_bust;
+       rc = bus_space_map(sc->sc_iot, UCTL_BASE, UCTL_SIZE,
+           0, &sc->sc_ioh);
+       KASSERT(rc == 0);
+
+       /* do clock setup if not already done */
+       bus_space_write_8(sc->sc_iot, sc->sc_ioh, UCTL_IF_ENA,
+           UCTL_IF_ENA_EN);
+       ctl = bus_space_read_8(sc->sc_iot, sc->sc_ioh, UCTL_CLK_RST_CTL);
+       if ((ctl & UCTL_CLK_RST_CTL_HRST) == 0)
+               octuctl_clock_setup(sc, ctl);
+
+       /* port phy settings */
+       for (port = 0; port < 2; port++) {
+               preg = UCTL_UPHY_PORTX_STATUS + (port * 8);
+               port_ctl = bus_space_read_8(sc->sc_iot, sc->sc_ioh, preg);
+               txvref = 0xf;
+               port_ctl |= (UCTL_UPHY_PORTX_STATUS_TXPREEMPHTUNE |
+                   UCTL_UPHY_PORTX_STATUS_TXRISETUNE |
+                   (txvref << UCTL_UPHY_PORTX_STATUS_TXVREF_SHIFT));
+               bus_space_write_8(sc->sc_iot, sc->sc_ioh, preg, port_ctl);
+       }
+
+       printf("\n");
+
+       uaa.aa_octuctl_bust = aa->aa_bust;
+       uaa.aa_bust = &octuctl_tag;
+       uaa.aa_dmat = aa->aa_dmat;
+       uaa.aa_ioh = sc->sc_ioh;
+
+       uaa.aa_name = "ehci";
+       config_found(self, &uaa, octuctlprint);
+
+       uaa.aa_name = "ohci";
+       config_found(self, &uaa, octuctlprint);
+}
Index: dev/octuctlreg.h
===================================================================
RCS file: dev/octuctlreg.h
diff -N dev/octuctlreg.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ dev/octuctlreg.h    17 Mar 2016 01:43:52 -0000
@@ -0,0 +1,88 @@
+/*     $OpenBSD$ */
+
+/*
+ * Copyright (c) 2015 Jonathan Matthew  <jmatt...@openbsd.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+#ifndef _OCTUCTLREG_H_
+#define _OCTUCTLREG_H_
+
+#include <sys/stdint.h>
+
+/*
+ * UCTL - octeon II usb controller interface
+ */
+#define UCTL_BASE                              0x000118006f000000ull
+#define UCTL_SIZE                              0x100
+
+#define UCTL_EHCI_BASE                         0x00016f0000000000ull
+#define UCTL_EHCI_SIZE                         0x100
+#define UCTL_OHCI_BASE                         0x00016f0000000400ull
+#define UCTL_OHCI_SIZE                         0x100
+
+#define UCTL_CLK_RST_CTL                       0x00
+#define UCTL_CLK_RST_CTL_HRST                  (1 << 0)
+#define UCTL_CLK_RST_CTL_P_PRST                (1 << 1)
+#define UCTL_CLK_RST_CTL_P_POR                 (1 << 2)
+#define UCTL_CLK_RST_CTL_P_COM_ON              (1 << 3)
+#define UCTL_CLK_RST_CTL_P_REFCLK_DIV_SHIFT    5
+#define UCTL_CLK_RST_CTL_P_REFCLK_SEL_SHIFT    7
+#define UCTL_CLK_RST_CTL_H_DIV_SHIFT           9
+#define UCTL_CLK_RST_CTL_O_CLKDIV_EN           (1 << 13)
+#define UCTL_CLK_RST_CTL_H_CLKDIV_EN           (1 << 14)
+#define UCTL_CLK_RST_CTL_H_CLKDIV_RST          (1 << 15)
+#define UCTL_CLK_RST_CTL_H_CLKDIV_BYP          (1 << 16)
+#define UCTL_CLK_RST_CTL_O_CLKDIV_RST          (1 << 17)
+#define UCTL_CLK_RST_CTL_APP_START_CLK         (1 << 18)
+#define UCTL_CLK_RST_CTL_OHCI_SUSP_LGCY        (1 << 19)
+#define UCTL_CLK_RST_CTL_OHCI_SM               (1 << 20)
+#define UCTL_CLK_RST_CTL_OHCI_CLKCKTRST        (1 << 21)
+#define UCTL_CLK_RST_CTL_EHCI_SM               (1 << 22)
+
+#define UCTL_UPHY_STATUS                       0x08
+
+#define UCTL_UPHY_PORTX_STATUS                 0x10
+#define UCTL_UPHY_PORTX_STATUS_TXVREF_SHIFT    28
+#define UCTL_UPHY_PORTX_STATUS_TXRISETUNE      (1 << 27)
+#define UCTL_UPHY_PORTX_STATUS_TXPREEMPHTUNE   (1 << 26)
+
+#define UCTL_IF_ENA                            0x30
+#define UCTL_IF_ENA_EN                         (1 << 0)
+
+#define UCTL_EHCI_CTL                          0x80
+#define UCTL_EHCI_CTL_L2C_ADDR_MSB_MASK        0xff
+#define UCTL_EHCI_CTL_L2C_ADDR_MSB_SHIFT       0
+#define UCTL_EHCI_CTL_EHCI_64B_ADDR_EN         (1 << 8)
+#define UCTL_EHCI_CTL_L2C_DESC_EMOD_SHIFT      10
+#define UCTL_EHCI_CTL_L2C_BUFF_EMOD_SHIFT      12
+
+#define UCTL_OHCI_CTL                          0x88
+#define UCTL_OHCI_CTL_L2C_ADDR_MSB_MASK        0xff
+#define UCTL_OHCI_CTL_L2C_ADDR_MSB_SHIFT       0
+#define UCTL_OHCI_CTL_L2C_DESC_EMOD_SHIFT      10
+#define UCTL_OHCI_CTL_L2C_BUFF_EMOD_SHIFT      12
+
+#endif /* _OCTUCTLREG_H_ */
Index: dev/octuctlvar.h
===================================================================
RCS file: dev/octuctlvar.h
diff -N dev/octuctlvar.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ dev/octuctlvar.h    17 Mar 2016 01:43:52 -0000
@@ -0,0 +1,42 @@
+/*     $OpenBSD$ */
+
+/*
+ * Copyright (c) 2015 Jonathan Matthew  <jmatt...@openbsd.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef        _OCTUCTLVAR_H_
+#define        _OCTUCTLVAR_H_
+
+#include <machine/bus.h>
+
+struct octuctl_attach_args {
+       char                    *aa_name;
+       bus_space_tag_t         aa_octuctl_bust;
+       bus_space_tag_t         aa_bust;
+       bus_dma_tag_t           aa_dmat;
+       bus_space_handle_t      aa_ioh;
+};
+
+#endif /* _OCTUCTLVAR_H_ */

Reply via email to