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