On Wed, Feb 20, 2019 at 10:03:26PM +0900, SASANO Takayoshi wrote: > Hello, > > Allwinner V3s shares one USB port with MUSB OTG module and EHCI/OHCI. > The default route of USB-PHY is to OTG module so we have to add workaround > to sys/dev/fdt/ehci_fdt.c that the port connects to host controller. > > (reference: sun4i_usb_phy0_reroute() at drivers/phy/allwinner/phy-sun4i-usb.c, > Linux-5.0-RC6 code)
> + len = OF_getproplen(node, "reg"); > + if (len <= 0) > + return; > + > + reg = malloc(len, M_TEMP, M_WAITOK); > + OF_getpropintarray(node, "reg", reg, len); > + > + iot = sc->sc.iot; > + if (bus_space_map(iot, reg[idx], reg[idx + 1], 0, &ioh)) { > + free(reg, M_TEMP, len); > + return; > + } That's not right. The reg property needs to be translated through all necessary layers. This only works if the phy is in the same layer as the ehci. Feels like a hack. I have also done an attempt at fixing this not long ago, but I wasn't quite ready yet as this enable VBUS all the time and if there is a hw where someone tries to connect a host to the device... then there are two VBUSes, heh. But if (for now) that's fine, we could also just go ahead with it. diff --git a/sys/arch/arm64/conf/GENERIC b/sys/arch/arm64/conf/GENERIC index b85e1099412..edb785662c6 100644 --- a/sys/arch/arm64/conf/GENERIC +++ b/sys/arch/arm64/conf/GENERIC @@ -177,6 +177,7 @@ sdmmc* at sximmc? # SD/MMC bus sxitemp* at fdt? # Temperature sensor sxitwi* at fdt? # I2C controller iic* at sxitwi? # I2C bus +sxiuphy* at fdt? # USB Phy dwxe* at fdt? # PCI diff --git a/sys/arch/arm64/conf/RAMDISK b/sys/arch/arm64/conf/RAMDISK index 201a5f0fcb2..83ab6602c04 100644 --- a/sys/arch/arm64/conf/RAMDISK +++ b/sys/arch/arm64/conf/RAMDISK @@ -169,6 +169,7 @@ sximmc* at fdt? # SD/MMC card controller sdmmc* at sximmc? # SD/MMC bus sxitwi* at fdt? # I2C controller iic* at sxitwi? # I2C bus +sxiuphy* at fdt? # USB Phy dwxe* at fdt? # PCI diff --git a/sys/dev/fdt/files.fdt b/sys/dev/fdt/files.fdt index f90efcdf446..5d6bf652d47 100644 --- a/sys/dev/fdt/files.fdt +++ b/sys/dev/fdt/files.fdt @@ -44,6 +44,10 @@ device sxitwi: i2cbus attach sxitwi at fdt file dev/fdt/sxitwi.c sxitwi +device sxiuphy +attach sxiuphy at fdt +file dev/fdt/sxiuphy.c sxiuphy + device axppmic attach axppmic at i2c attach axppmic at rsb with axppmic_rsb diff --git a/sys/dev/fdt/sxiuphy.c b/sys/dev/fdt/sxiuphy.c new file mode 100644 index 00000000000..40d22bb2df5 --- /dev/null +++ b/sys/dev/fdt/sxiuphy.c @@ -0,0 +1,110 @@ +/* $OpenBSD$ */ +/* + * Copyright (c) 2019 Patrick Wildt <patr...@blueri.se> + * + * 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 <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> + +#include <machine/intr.h> +#include <machine/bus.h> +#include <machine/fdt.h> + +#include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_misc.h> +#include <dev/ofw/fdt.h> + +#define PHY_ISCR 0x00 +#define PHY_ISCR_DPDM_CHANGE_DET (1 << 4) +#define PHY_ISCR_ID_CHANGE_DET (1 << 5) +#define PHY_ISCR_VBUS_CHANGE_DET (1 << 6) +#define PHY_ISCR_VBUS_LOW (2 << 12) +#define PHY_ISCR_VBUS_HIGH (3 << 12) +#define PHY_ISCR_VBUS_MASK (3 << 12) +#define PHY_ISCR_ID_LOW (2 << 14) +#define PHY_ISCR_ID_HIGH (3 << 14) +#define PHY_ISCR_ID_MASK (3 << 14) +#define PHY_ISCR_DPDM_PULLUP (1 << 16) +#define PHY_ISCR_ID_PULLUP (1 << 17) +#define PHY_PHYCTL_A10 0x04 +#define PHY_PHYBIST 0x08 +#define PHY_PHYTUNE 0x0c +#define PHY_PHYCTL_A33 0x10 +#define PHY_OTGCTL 0x20 +#define PHY_OTGCTL_ROUTE_MUSB (1 << 0) + +#define PMU_UNK1 0x10 + +struct sxiuphy_softc { + struct device sc_dev; + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; +}; + +int sxiuphy_match(struct device *, void *, void *); +void sxiuphy_attach(struct device *, struct device *, void *); + +struct cfattach sxiuphy_ca = { + sizeof (struct sxiuphy_softc), sxiuphy_match, sxiuphy_attach +}; + +struct cfdriver sxiuphy_cd = { + NULL, "sxiuphy", DV_DULL +}; + +int +sxiuphy_match(struct device *parent, void *match, void *aux) +{ + struct fdt_attach_args *faa = aux; + + return (OF_is_compatible(faa->fa_node, "allwinner,sun8i-h3-usb-phy") || + OF_is_compatible(faa->fa_node, "allwinner,sun8i-r40-usb-phy") || + OF_is_compatible(faa->fa_node, "allwinner,sun8i-v3s-usb-phy") || + OF_is_compatible(faa->fa_node, "allwinner,sun50i-a64-usb-phy") || + OF_is_compatible(faa->fa_node, "allwinner,sun50i-h6-usb-phy")); +} + +void +sxiuphy_attach(struct device *parent, struct device *self, void *aux) +{ + struct sxiuphy_softc *sc = (struct sxiuphy_softc *)self; + struct fdt_attach_args *faa = aux; + uint32_t reg; + + if (faa->fa_nreg < 1) { + printf(": no registers\n"); + return; + } + + sc->sc_iot = faa->fa_iot; + + if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, + faa->fa_reg[0].size, 0, &sc->sc_ioh)) { + printf(": can't map registers\n"); + return; + } + + printf("\n"); + + reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, PHY_OTGCTL); + reg &= ~(PHY_ISCR_DPDM_CHANGE_DET | PHY_ISCR_ID_CHANGE_DET | + PHY_ISCR_VBUS_CHANGE_DET); + reg |= (PHY_ISCR_DPDM_PULLUP | PHY_ISCR_ID_PULLUP); + reg &= ~(PHY_ISCR_VBUS_MASK | PHY_ISCR_ID_MASK); + reg |= (PHY_ISCR_VBUS_HIGH | PHY_ISCR_ID_LOW); + reg &= ~PHY_OTGCTL_ROUTE_MUSB; + bus_space_write_4(sc->sc_iot, sc->sc_ioh, PHY_OTGCTL, reg); +}