> Date: Tue, 06 Feb 2024 22:37:50 +0900 > From: SASANO Takayoshi <u...@mx5.nisiq.net> > > Hello, > > I am working for H616 since OrangePi Zero2... > > Here's the diff. sximmc.c is reconstructed.
Hi, > Index: ehci_fdt.c > =================================================================== > RCS file: /cvs/src/sys/dev/fdt/ehci_fdt.c,v > diff -u -p -r1.11 ehci_fdt.c > --- ehci_fdt.c 26 Jan 2024 17:11:50 -0000 1.11 > +++ ehci_fdt.c 6 Feb 2024 12:48:22 -0000 > @@ -207,6 +207,7 @@ struct ehci_phy ehci_phys[] = { > { "allwinner,sun8i-v3s-usb-phy", sun4i_phy_init }, > { "allwinner,sun20i-d1-usb-phy", sun4i_phy_init }, > { "allwinner,sun50i-h6-usb-phy", sun4i_phy_init }, > + { "allwinner,sun50i-h616-usb-phy", sun4i_phy_init }, > { "allwinner,sun50i-a64-usb-phy", sun4i_phy_init }, > { "allwinner,sun9i-a80-usb-phy", sun9i_phy_init }, > }; > @@ -287,6 +288,62 @@ ehci_init_phys(struct ehci_fdt_softc *sc > #define SUNXI_AHB_INCR16 (1 << 11) > > void > +sun50i_h616_phy2_init(struct ehci_fdt_softc *sc, int node) > +{ > + int len, idx; > + uint32_t *reg, val; > + bus_size_t size; > + bus_space_handle_t ioh; > + > + /* > + * to access USB2-PHY register, get address from "reg" property of > + * current "allwinner,...-usb-phy" node > + */ > + len = OF_getproplen(node, "reg"); > + if (len <= 0) > + goto out; > + > + reg = malloc(len, M_TEMP, M_WAITOK); > + OF_getpropintarray(node, "reg", reg, len); > + > + idx = OF_getindex(node, "pmu2", "reg-names"); > + if (idx < 0 || (idx + 1) > (len / (sizeof(uint32_t) * 2))) { > + printf(": no phy2 register\n"); > + goto free; > + } > + > + /* convert "reg-names" index to "reg" (address-size pair) index */ > + idx *= 2; > + > + size = reg[idx + 1]; > + if (bus_space_map(sc->sc.iot, reg[idx], size, 0, &ioh)) { > + printf(": can't map phy2 registers\n"); > + goto free; > + } > + > + clock_enable(node, "usb2_phy"); > + reset_deassert(node, "usb2_reset"); > + clock_enable(node, "pmu2_clk"); > + > + /* > + * address is offset from "pmu2", not EHCI2 base address > + * (normally it points EHCI2 base address + 0x810) > + */ > + val = bus_space_read_4(sc->sc.iot, ioh, 0x10); > + val &= ~(1 << 3); /* clear SIDDQ */ > + bus_space_write_4(sc->sc.iot, ioh, 0x10, val); > + > + clock_disable(node, "pmu2_clk"); > + /* "usb2_reset" and "usb2_phy" unchanged */ > + > + bus_space_unmap(sc->sc.iot, ioh, size); > +free: > + free(reg, M_TEMP, len); > +out: > + return; > +} This will be easier if we turn the Allwinner USB PHY code into a proper driver, but it is fine for now. > + > +void > sun4i_phy_init(struct ehci_fdt_softc *sc, uint32_t *cells) > { > uint32_t vbus_supply; > @@ -298,6 +355,11 @@ sun4i_phy_init(struct ehci_fdt_softc *sc > if (node == -1) > return; > > + /* Allwinner H616 needs to clear PHY2's SIDDQ flag */ > + if (OF_is_compatible(node, "allwinner,sun50i-h616-usb-phy") && > + cells[1] != 2) > + sun50i_h616_phy2_init(sc, node); > + > val = bus_space_read_4(sc->sc.iot, sc->sc.ioh, SUNXI_HCI_ICR); > val |= SUNXI_AHB_INCR8 | SUNXI_AHB_INCR4; > val |= SUNXI_AHB_INCRX_ALIGN; > @@ -318,6 +380,13 @@ sun4i_phy_init(struct ehci_fdt_softc *sc > } else if (OF_is_compatible(node, "allwinner,sun20i-d1-usb-phy")) { > val = bus_space_read_4(sc->sc.iot, sc->sc.ioh, 0x810); > val &= ~(1 << 3); > + bus_space_write_4(sc->sc.iot, sc->sc.ioh, 0x810, val); > + } > + if (OF_is_compatible(node, "allwinner,sun50i-h616-usb-phy") || > + OF_is_compatible(node, "allwinner,sun50i-a83t-usb-phy")) { There is no sun50i-a83t; you probably meant sun8i-a83t here, but I don't think it is worth bothering about the A83T SoC, since it is armv7 and pretty old. > + val = bus_space_read_4(sc->sc.iot, sc->sc.ioh, 0x810); > + val |= 1 << 5; /* set VBUSVLDEXT */ The Linux driver sets this bit for Allwinner D1 too, so you can simply merge this with the sun50i-d1 case. > + val &= ~(1 << 3); /* clear SIDDQ */ > bus_space_write_4(sc->sc.iot, sc->sc.ioh, 0x810, val); > } >