From: Mark Kettenis Subject: Re: support MediaTek xHCI USB controller To: James Hastings Cc: moosetek4@gmail.com,kettenis@openbsd.org,tech@openbsd.org Date: Mon, 24 Mar 2025 11:43:30 +0100 > From: James Hastings > Date: Mon, 24 Mar 2025 01:25:39 -0400 (EDT) > > Diff v2 with changes from kettenis@. > > ok? ok kettenis@ > Index: sys/dev/fdt/mtxhci.c > =================================================================== > RCS file: sys/dev/fdt/mtxhci.c > diff -N sys/dev/fdt/mtxhci.c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ sys/dev/fdt/mtxhci.c 24 Mar 2025 01:53:18 -0000 > @@ -0,0 +1,252 @@ > +/* $OpenBSD$ */ > +/* > + * Copyright (c) 2025 James Hastings > + * > + * Permission to use, copy, modify, and 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 > +#include > +#include > + > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > + > +#include > +#include > + > +#define MTXHCI_MAX_PORTS 4 > + > +/* registers */ > +#define MTXHCI_RESET 0x00 > +#define RESET_ASSERT (1 << 0) > +#define MTXHCI_CFG_HOST 0x04 > +#define MTXHCI_CFG_DEV 0x08 > +#define MTXHCI_CFG_PCIE 0x0c > +#define CFG_PWRDN (1 << 0) > +#define MTXHCI_STA 0x10 > +#define STA_USB3 (1 << 16) > +#define STA_XHCI (1 << 11) > +#define STA_SYS (1 << 10) > +#define STA_REF (1 << 8) > +#define STA_PLL (1 << 0) > +#define MTXHCI_CAPS 0x24 > +#define CAP_USB2_PORTS(x) (((x) >> 8) & 0x7) > +#define CAP_USB3_PORTS(x) (((x) >> 0) & 0x7) > +#define MTXHCI_USB3_PORT(x) 0x30 + (x) * 8 > +#define MTXHCI_USB2_PORT(x) 0x50 + (x) * 8 > +#define CFG_PORT_HOST (1 << 2) > +#define CFG_PORT_PWRDN (1 << 1) > +#define CFG_PORT_DISABLE (1 << 0) > + > +#define HREAD4(sc, reg) \ > + bus_space_read_4((sc)->sc.iot, (sc)->sc_port_ioh, (reg)) > +#define HWRITE4(sc, reg, val) \ > + bus_space_write_4((sc)->sc.iot, (sc)->sc_port_ioh, (reg), (val)) > + > +struct mtxhci_softc { > + struct xhci_softc sc; > + int sc_node; > + > + bus_space_handle_t sc_port_ioh; > + bus_size_t sc_port_ios; > + int sc_port_node; > + > + int sc_ports_usb2; > + int sc_ports_usb3; > + > + void *sc_ih; > +}; > + > +int mtxhci_match(struct device *, void *, void *); > +void mtxhci_attach(struct device *, struct device *, void *); > + > +const struct cfattach mtxhci_ca = { > + sizeof(struct mtxhci_softc), mtxhci_match, mtxhci_attach > +}; > + > +struct cfdriver mtxhci_cd = { > + NULL, "mtxhci", DV_DULL > +}; > + > +int mtxhci_host_init(struct mtxhci_softc *); > + > +int > +mtxhci_match(struct device *parent, void *match, void *aux) > +{ > + struct fdt_attach_args *faa = aux; > + > + if (OF_is_compatible(faa->fa_node, "mediatek,mtk-xhci")) > + return 1; > + > + return 0; > +} > + > +void > +mtxhci_attach(struct device *parent, struct device *self, void *aux) > +{ > + struct mtxhci_softc *sc = (struct mtxhci_softc *)self; > + struct fdt_attach_args *faa = aux; > + int error = 0, idx; > + > + idx = OF_getindex(faa->fa_node, "ippc", "reg-names"); > + if (idx < 0 || idx >= faa->fa_nreg) { > + printf(": no ippc registers\n"); > + return; > + } > + > + if (bus_space_map(faa->fa_iot, faa->fa_reg[idx].addr, > + faa->fa_reg[idx].size, 0, &sc->sc_port_ioh)) { > + printf(": can't map registers\n"); > + return; > + } > + > + sc->sc_port_node = faa->fa_node; > + sc->sc_port_ios = faa->fa_reg[idx].size; > + > + idx = OF_getindex(faa->fa_node, "mac", "reg-names"); > + if (idx < 0 || idx >= faa->fa_nreg) { > + printf(": no mac registers\n"); > + goto unmap_port; > + } > + > + if (bus_space_map(faa->fa_iot, faa->fa_reg[idx].addr, > + faa->fa_reg[idx].size, 0, &sc->sc.ioh)) { > + printf(": can't map registers\n"); > + goto unmap_port; > + } > + > + sc->sc_node = faa->fa_node; > + sc->sc.iot = faa->fa_iot; > + sc->sc.sc_size = faa->fa_reg[idx].size; > + sc->sc.sc_bus.dmatag = faa->fa_dmat; > + > + sc->sc_ih = fdt_intr_establish(sc->sc_node, IPL_USB, > + xhci_intr, sc, sc->sc.sc_bus.bdev.dv_xname); > + if (sc->sc_ih == NULL) { > + printf(": can't establish interrupt\n"); > + goto unmap; > + } > + > + power_domain_enable(sc->sc_node); > + reset_deassert_all(sc->sc_node); > + clock_set_assigned(sc->sc_node); > + clock_enable_all(sc->sc_node); > + > + if ((error = mtxhci_host_init(sc)) != 0) { > + printf(": host init failed, error=%d\n", error); > + goto disestablish_ret; > + } > + > + strlcpy(sc->sc.sc_vendor, "MediaTek", sizeof(sc->sc.sc_vendor)); > + if ((error = xhci_init(&sc->sc)) != 0) { > + printf("%s: init failed, error=%d\n", > + sc->sc.sc_bus.bdev.dv_xname, error); > + goto disestablish_ret; > + } > + > + config_found(self, &sc->sc.sc_bus, usbctlprint); > + > + xhci_config(&sc->sc); > + > + return; > + > +disestablish_ret: > + fdt_intr_disestablish(sc->sc_ih); > +unmap: > + bus_space_unmap(faa->fa_iot, sc->sc.ioh, sc->sc.sc_size); > +unmap_port: > + bus_space_unmap(faa->fa_iot, sc->sc_port_ioh, sc->sc_port_ios); > +} > + > +int > +mtxhci_host_init(struct mtxhci_softc *sc) > +{ > + uint32_t mask, val; > + int i, ntries; > + > + /* port capabilities */ > + val = HREAD4(sc, MTXHCI_CAPS); > + sc->sc_ports_usb3 = MIN(MTXHCI_MAX_PORTS, CAP_USB3_PORTS(val)); > + sc->sc_ports_usb2 = MIN(MTXHCI_MAX_PORTS, CAP_USB2_PORTS(val)); > + > + if (sc->sc_ports_usb3 == 0 && sc->sc_ports_usb2 == 0) > + return ENXIO; > + > + /* enable phys */ > + phy_enable_idx(sc->sc_port_node, -1); > + > + /* reset */ > + val = HREAD4(sc, MTXHCI_RESET); > + val |= RESET_ASSERT; > + HWRITE4(sc, MTXHCI_RESET, val); > + delay(10); > + val &= ~RESET_ASSERT; > + HWRITE4(sc, MTXHCI_RESET, val); > + delay(10); > + > + /* disable device mode */ > + val = HREAD4(sc, MTXHCI_CFG_DEV); > + val |= CFG_PWRDN; > + HWRITE4(sc, MTXHCI_CFG_DEV, val); > + > + /* enable host mode */ > + val = HREAD4(sc, MTXHCI_CFG_HOST); > + val &= ~CFG_PWRDN; > + HWRITE4(sc, MTXHCI_CFG_HOST, val); > + > + mask = (STA_XHCI | STA_PLL | STA_SYS | STA_REF); > + if (sc->sc_ports_usb3) { > + mask |= STA_USB3; > + > + /* disable PCIe mode */ > + val = HREAD4(sc, MTXHCI_CFG_PCIE); > + val |= CFG_PWRDN; > + HWRITE4(sc, MTXHCI_CFG_PCIE, val); > + } > + > + /* configure host ports */ > + for (i = 0; i < sc->sc_ports_usb3; i++) { > + val = HREAD4(sc, MTXHCI_USB3_PORT(i)); > + val &= ~(CFG_PORT_DISABLE | CFG_PORT_PWRDN); > + val |= CFG_PORT_HOST; > + HWRITE4(sc, MTXHCI_USB3_PORT(i), val); > + } > + for (i = 0; i < sc->sc_ports_usb2; i++) { > + val = HREAD4(sc, MTXHCI_USB2_PORT(i)); > + val &= ~(CFG_PORT_DISABLE | CFG_PORT_PWRDN); > + val |= CFG_PORT_HOST; > + HWRITE4(sc, MTXHCI_USB2_PORT(i), val); > + } > + > + for (ntries = 0; ntries < 100; ntries++) { > + val = HREAD4(sc, MTXHCI_STA); > + if ((val & mask) == mask) > + break; > + delay(50); > + } > + if (ntries == 100) > + return ETIMEDOUT; > + > + return 0; > +} > Index: sys/dev/fdt/files.fdt > =================================================================== > RCS file: /cvs/src/sys/dev/fdt/files.fdt,v > retrieving revision 1.206 > diff -u -p -r1.206 files.fdt > --- sys/dev/fdt/files.fdt 14 Feb 2025 03:11:05 -0000 1.206 > +++ sys/dev/fdt/files.fdt 24 Mar 2025 01:53:18 -0000 > @@ -344,6 +344,10 @@ device mtrng > attach mtrng at fdt > file dev/fdt/mtrng.c mtrng > > +device mtxhci: usbus > +attach mtxhci at fdt > +file dev/fdt/mtxhci.c mtxhci > + > device rkanxdp > attach rkanxdp at fdt > file dev/fdt/rkanxdp.c rkanxdp > Index: share/man/man4/mtxhci.4 > =================================================================== > RCS file: share/man/man4/mtxhci.4 > diff -N share/man/man4/mtxhci.4 > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ share/man/man4/mtxhci.4 24 Mar 2025 01:53:18 -0000 > @@ -0,0 +1,49 @@ > +.\" $OpenBSD$ > +.\" > +.\" Copyright (c) 2025 James Hastings > +.\" > +.\" Permission to use, copy, modify, and 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. > +.\" > +.Dd $Mdocdate$ > +.Dt MTXHCI 4 > +.Os > +.Sh NAME > +.Nm mtxhci > +.Nd MediaTek USB xHCI controller > +.Sh SYNOPSIS > +.Cd "mtxhci* at fdt?" > +.Cd "usb* at mtxhci?" > +.Sh DESCRIPTION > +The > +.Nm > +driver controls the interface logic and supports > +the USB eXtensible Host Controller Interface > +integrated on MediaTek SoCs. > +.Pp > +It provides an interface to > +.Xr usb 4 > +devices and supports all USB 3.0, 2.0 and 1.x device speeds. > +.Sh SEE ALSO > +.Xr intro 4 , > +.Xr usb 4 > +.Sh HISTORY > +The > +.Nm > +device driver first appeared in > +.Ox 7.7 . > +.Sh AUTHORS > +.An -nosplit > +The > +.Nm > +driver was written by > +.An James Hastings Aq Mt hastings@openbsd.org . > Index: share/man/man4/Makefile > =================================================================== > RCS file: /cvs/src/share/man/man4/Makefile,v > retrieving revision 1.859 > diff -u -p -r1.859 Makefile > --- share/man/man4/Makefile 14 Feb 2025 03:15:06 -0000 1.859 > +++ share/man/man4/Makefile 24 Mar 2025 01:53:18 -0000 > @@ -59,7 +59,7 @@ MAN= aac.4 abcrtc.4 abl.4 ac97.4 acphy.4 > mcprtc.4 mcx.4 midi.4 mii.4 mfi.4 mfii.4 mfokrtc.4 \ > mlphy.4 moscom.4 mos.4 mpe.4 mpath.4 mpi.4 mpii.4 \ > mpip.4 mpu.4 msk.4 mpw.4 msts.4 mtd.4 mtdphy.4 \ > - mtintc.4 mtio.4 mtrng.4 mtw.4 mue.4 \ > + mtintc.4 mtio.4 mtrng.4 mtw.4 mtxhci.4 mue.4 \ > multicast.4 mvclock.4 mvdog.4 mvgicp.4 mvgpio.4 mvicu.4 mviic.4 \ > mvkpcie.4 mvneta.4 mvpinctrl.4 mvpp.4 mvrng.4 mvrtc.4 mvspi.4 \ > mvtemp.4 mvsw.4 mvuart.4 myx.4 \ > Index: sys/arch/arm64/conf/GENERIC > =================================================================== > RCS file: /cvs/src/sys/arch/arm64/conf/GENERIC,v > retrieving revision 1.292 > diff -u -p -r1.292 GENERIC > --- sys/arch/arm64/conf/GENERIC 14 Feb 2025 04:56:26 -0000 1.292 > +++ sys/arch/arm64/conf/GENERIC 24 Mar 2025 01:53:18 -0000 > @@ -275,6 +275,8 @@ hitemp* at fdt? > # MediaTek SoCs > mtintc* at fdt? > mtrng* at fdt? > +mtxhci* at fdt? > +usb* at mtxhci? > > # Marvell SoCs > mvclock* at fdt? early 1 > Index: sys/arch/arm64/conf/RAMDISK > =================================================================== > RCS file: /cvs/src/sys/arch/arm64/conf/RAMDISK,v > retrieving revision 1.221 > diff -u -p -r1.221 RAMDISK > --- sys/arch/arm64/conf/RAMDISK 14 Feb 2025 04:56:26 -0000 1.221 > +++ sys/arch/arm64/conf/RAMDISK 24 Mar 2025 01:53:18 -0000 > @@ -207,6 +207,8 @@ hireset* at fdt? early 1 > # MediaTek SoCs > mtintc* at fdt? > mtrng* at fdt? > +mtxhci* at fdt? > +usb* at mtxhci? > > # Marvell SoCs > mvclock* at fdt? early 1 > Index: sys/arch/armv7/conf/GENERIC > =================================================================== > RCS file: /cvs/src/sys/arch/armv7/conf/GENERIC,v > retrieving revision 1.144 > diff -u -p -r1.144 GENERIC > --- sys/arch/armv7/conf/GENERIC 14 Feb 2025 04:56:34 -0000 1.144 > +++ sys/arch/armv7/conf/GENERIC 24 Mar 2025 01:53:19 -0000 > @@ -187,6 +187,8 @@ usb* at dwctwo? > # MediaTek SoCs > mtintc* at fdt? > mtrng* at fdt? > +mtxhci* at fdt? > +usb* at mtxhci? > > # Marvell SoC > mvacc* at fdt? early 1 > Index: sys/arch/armv7/conf/RAMDISK > =================================================================== > RCS file: /cvs/src/sys/arch/armv7/conf/RAMDISK,v > retrieving revision 1.132 > diff -u -p -r1.132 RAMDISK > --- sys/arch/armv7/conf/RAMDISK 14 Feb 2025 04:56:34 -0000 1.132 > +++ sys/arch/armv7/conf/RAMDISK 24 Mar 2025 01:53:19 -0000 > @@ -173,6 +173,8 @@ usb* at dwctwo? > # MediaTek SoCs > mtintc* at fdt? > mtrng* at fdt? > +mtxhci* at fdt? > +usb* at mtxhci? > > # Marvell SoC > mvacc* at fdt? early 1 > >