> Date: Tue, 05 Feb 2019 00:41:01 +0900 > From: SASANO Takayoshi <u...@mx5.nisiq.net> > > Hi, > > > There is no support for v3s in sxiccmu(4) and sxipio(4). > > There is no driver for mentor usb otg "allwinner,sun8i-h3-musb" > > I added v3s support code to sxiccmu(4) and sxipio(4), > but hangs up at attaching root device.
I have some code that generates the tables used by sxipio(4). I've updated that code and committed the sxipio(4) changes. I have one request for a change in the sxiccmu(4) code. See the comment below. Can you make that change and send an updated diff? Thanks, Mark > Index: sxiccmu.c > =================================================================== > RCS file: /cvs/src/sys/dev/fdt/sxiccmu.c,v > retrieving revision 1.21 > diff -u -r1.21 sxiccmu.c > --- sxiccmu.c 3 Aug 2018 21:28:28 -0000 1.21 > +++ sxiccmu.c 4 Feb 2019 13:47:35 -0000 > @@ -103,6 +103,8 @@ > uint32_t sxiccmu_h3_r_get_frequency(struct sxiccmu_softc *, uint32_t); > uint32_t sxiccmu_r40_get_frequency(struct sxiccmu_softc *, uint32_t); > int sxiccmu_r40_set_frequency(struct sxiccmu_softc *, uint32_t, uint32_t); > +int sxiccmu_v3s_set_frequency(struct sxiccmu_softc *, uint32_t, uint32_t); > +uint32_t sxiccmu_v3s_get_frequency(struct sxiccmu_softc *, uint32_t); > uint32_t sxiccmu_nop_get_frequency(struct sxiccmu_softc *, uint32_t); > int sxiccmu_nop_set_frequency(struct sxiccmu_softc *, uint32_t, uint32_t); > > @@ -122,6 +124,7 @@ > OF_is_compatible(node, "allwinner,sun8i-a23") || > OF_is_compatible(node, "allwinner,sun8i-a33") || > OF_is_compatible(node, "allwinner,sun8i-h3") || > + OF_is_compatible(node, "allwinner,sun8i-v3s") || > OF_is_compatible(node, "allwinner,sun9i-a80") || > OF_is_compatible(node, "allwinner,sun50i-a64") || > OF_is_compatible(node, "allwinner,sun50i-h5")); > @@ -135,6 +138,7 @@ > OF_is_compatible(node, "allwinner,sun8i-h3-ccu") || > OF_is_compatible(node, "allwinner,sun8i-h3-r-ccu") || > OF_is_compatible(node, "allwinner,sun8i-r40-ccu") || > + OF_is_compatible(node, "allwinner,sun8i-v3s-ccu") || > OF_is_compatible(node, "allwinner,sun9i-a80-ccu") || > OF_is_compatible(node, "allwinner,sun9i-a80-usb-clks") || > OF_is_compatible(node, "allwinner,sun9i-a80-mmc-config-clk") || > @@ -211,6 +215,14 @@ > sc->sc_nresets = nitems(sun8i_r40_resets); > sc->sc_get_frequency = sxiccmu_r40_get_frequency; > sc->sc_set_frequency = sxiccmu_r40_set_frequency; > + } else if (OF_is_compatible(node, "allwinner,sun8i-v3s-ccu")) { > + KASSERT(faa->fa_nreg > 0); > + sc->sc_gates = sun8i_v3s_gates; > + sc->sc_ngates = nitems(sun8i_v3s_gates); > + sc->sc_resets = sun8i_v3s_resets; > + sc->sc_nresets = nitems(sun8i_v3s_resets); > + sc->sc_get_frequency = sxiccmu_v3s_get_frequency; > + sc->sc_set_frequency = sxiccmu_v3s_set_frequency; > } else if (OF_is_compatible(node, "allwinner,sun9i-a80-ccu")) { > KASSERT(faa->fa_nreg > 0); > sc->sc_gates = sun9i_a80_gates; > @@ -1233,6 +1245,65 @@ > } > > uint32_t > +sxiccmu_v3s_get_frequency(struct sxiccmu_softc *sc, uint32_t idx) > +{ > + uint32_t parent; > + uint32_t reg, div; > + > + switch (idx) { > + case V3S_CLK_LOSC: > + return clock_get_frequency(sc->sc_node, "losc"); > + case V3S_CLK_HOSC: > + return clock_get_frequency(sc->sc_node, "hosc"); > + case V3S_CLK_PLL_PERIPH0: > + /* Not hardcoded, but recommended. */ > + return 600000000; > + case V3S_CLK_APB2: > + /* XXX Controlled by a MUX. */ > + return 24000000; > + case V3S_CLK_AHB1: > + reg = SXIREAD4(sc, CCU_AHB1_APB1_CFG_REG); > + div = CCU_AHB1_CLK_DIV_RATIO(reg); > + switch (reg & CCU_AHB1_CLK_SRC_SEL) { > + case CCU_AHB1_CLK_SRC_SEL_LOSC: > + parent = V3S_CLK_LOSC; > + break; > + case CCU_AHB1_CLK_SRC_SEL_OSC24M: > + parent = V3S_CLK_HOSC; > + break; > + case CCU_AHB1_CLK_SRC_SEL_AXI: > + parent = V3S_CLK_AXI; > + break; > + case CCU_AHB1_CLK_SRC_SEL_PERIPH0: > + parent = V3S_CLK_PLL_PERIPH0; > + div *= CCU_AHB1_PRE_DIV(reg); > + break; > + default: > + return 0; > + } > + return sxiccmu_ccu_get_frequency(sc, &parent) / div; > + case V3S_CLK_AHB2: > + reg = SXIREAD4(sc, CCU_AHB2_CFG_REG); > + switch (reg & CCU_AHB2_CLK_CFG) { > + case 0: > + parent = V3S_CLK_AHB1; > + div = 1; > + break; > + case 1: > + parent = V3S_CLK_PLL_PERIPH0; > + div = 2; > + break; > + default: > + return 0; > + } > + return sxiccmu_ccu_get_frequency(sc, &parent) / div; > + } > + > + printf("%s: 0x%08x\n", __func__, idx); > + return 0; > +} > + > +uint32_t > sxiccmu_nop_get_frequency(struct sxiccmu_softc *sc, uint32_t idx) > { > printf("%s: 0x%08x\n", __func__, idx); > @@ -1414,6 +1485,28 @@ > bus_space_subregion(sc->sc_iot, sc->sc_ioh, > sc->sc_gates[idx].reg, 4, &clock.sc_ioh); > parent = R40_CLK_PLL_PERIPH0_2X; > + parent_freq = sxiccmu_ccu_get_frequency(sc, &parent); > + return sxiccmu_mmc_do_set_frequency(&clock, freq, parent_freq); > + } > + > + printf("%s: 0x%08x\n", __func__, idx); > + return -1; > +} > + > +int > +sxiccmu_v3s_set_frequency(struct sxiccmu_softc *sc, uint32_t idx, uint32_t > freq) > +{ > + struct sxiccmu_clock clock; > + uint32_t parent, parent_freq; > + > + switch (idx) { > + case V3S_CLK_MMC0: > + case V3S_CLK_MMC1: > + case V3S_CLK_MMC2: > + clock.sc_iot = sc->sc_iot; > + bus_space_subregion(sc->sc_iot, sc->sc_ioh, > + sc->sc_gates[idx].reg, 4, &clock.sc_ioh); > + parent = V3S_CLK_PLL_PERIPH0; > parent_freq = sxiccmu_ccu_get_frequency(sc, &parent); > return sxiccmu_mmc_do_set_frequency(&clock, freq, parent_freq); > } > Index: sxiccmu_clocks.h > =================================================================== > RCS file: /cvs/src/sys/dev/fdt/sxiccmu_clocks.h,v > retrieving revision 1.23 > diff -u -r1.23 sxiccmu_clocks.h > --- sxiccmu_clocks.h 15 Jan 2019 16:07:42 -0000 1.23 > +++ sxiccmu_clocks.h 4 Feb 2019 13:47:35 -0000 > @@ -473,6 +473,58 @@ > [R40_CLK_USB_PHY2] = { 0x00cc, 10 }, > }; > > +/* V3s */ > + > +#define V3S_CLK_PLL_PERIPH0 5 // XXX > +#define V3S_CLK_AXI 6 // XXX > +#define V3S_CLK_AHB1 7 // XXX > +#define V3S_CLK_AHB2 8 // XXX > +#define V3S_CLK_APB2 9 // XXX Probably best to use the same numbers as the Linux kernel uses, in case these get exported for use in device trees. V3S_CLK_PLL_PERIPH0 -> 9 V3S_CLK_AXI -> 15 V3S_CLK_AHB1 -> 16 V3S_CLK_APB2 -> 18 V3S_CLK_AHB2 -> 19 > + > +#define V3S_CLK_BUS_MMC0 22 > +#define V3S_CLK_BUS_MMC1 23 > +#define V3S_CLK_BUS_MMC2 24 > +#define V3S_CLK_BUS_EMAC 26 > +#define V3S_CLK_BUS_EHCI0 30 > +#define V3S_CLK_BUS_OHCI0 31 > +#define V3S_CLK_BUS_PIO 37 > +#define V3S_CLK_BUS_I2C0 38 > +#define V3S_CLK_BUS_I2C1 39 > +#define V3S_CLK_BUS_UART0 40 > +#define V3S_CLK_BUS_UART1 41 > +#define V3S_CLK_BUS_UART2 42 > +#define V3S_CLK_BUS_EPHY 43 > + > +#define V3S_CLK_MMC0 45 > +#define V3S_CLK_MMC1 48 > +#define V3S_CLK_MMC2 51 > +#define V3S_CLK_USB_PHY0 56 > +#define V3S_CLK_USB_OHCI0 57 > + > +#define V3S_CLK_LOSC 254 > +#define V3S_CLK_HOSC 253 > + > +struct sxiccmu_ccu_bit sun8i_v3s_gates[] = { > + [V3S_CLK_BUS_OHCI0] = { 0x0060, 29 }, > + [V3S_CLK_BUS_EHCI0] = { 0x0060, 26 }, > + [V3S_CLK_BUS_EMAC] = { 0x0060, 17, V3S_CLK_AHB2 }, > + [V3S_CLK_BUS_MMC2] = { 0x0060, 10 }, > + [V3S_CLK_BUS_MMC1] = { 0x0060, 9 }, > + [V3S_CLK_BUS_MMC0] = { 0x0060, 8 }, > + [V3S_CLK_BUS_PIO] = { 0x0068, 5 }, > + [V3S_CLK_BUS_UART2] = { 0x006c, 18, V3S_CLK_APB2 }, > + [V3S_CLK_BUS_UART1] = { 0x006c, 17, V3S_CLK_APB2 }, > + [V3S_CLK_BUS_UART0] = { 0x006c, 16, V3S_CLK_APB2 }, > + [V3S_CLK_BUS_I2C1] = { 0x006c, 1, V3S_CLK_APB2 }, > + [V3S_CLK_BUS_I2C0] = { 0x006c, 0, V3S_CLK_APB2 }, > + [V3S_CLK_BUS_EPHY] = { 0x0070, 0 }, > + [V3S_CLK_MMC0] = { 0x0088, 31 }, > + [V3S_CLK_MMC1] = { 0x008c, 31 }, > + [V3S_CLK_MMC2] = { 0x0090, 31 }, > + [V3S_CLK_USB_OHCI0] = { 0x00cc, 16 }, > + [V3S_CLK_USB_PHY0] = { 0x00cc, 8 }, > +}; > + > /* > * Reset Signals > */ > @@ -726,4 +778,37 @@ > [R40_RST_BUS_UART5] = { 0x02d8, 21 }, > [R40_RST_BUS_UART6] = { 0x02d8, 22 }, > [R40_RST_BUS_UART7] = { 0x02d8, 23 }, > +}; > + > +/* V3s */ > + > +#define V3S_RST_USB_PHY0 0 > + > +#define V3S_RST_BUS_MMC0 7 > +#define V3S_RST_BUS_MMC1 8 > +#define V3S_RST_BUS_MMC2 9 > +#define V3S_RST_BUS_EMAC 12 > +#define V3S_RST_BUS_EHCI0 18 > +#define V3S_RST_BUS_OHCI0 22 > +#define V3S_RST_BUS_EPHY 39 > +#define V3S_RST_BUS_I2C0 46 > +#define V3S_RST_BUS_I2C1 47 > +#define V3S_RST_BUS_UART0 49 > +#define V3S_RST_BUS_UART1 50 > +#define V3S_RST_BUS_UART2 51 > + > +struct sxiccmu_ccu_bit sun8i_v3s_resets[] = { > + [V3S_RST_USB_PHY0] = { 0x00cc, 0 }, > + [V3S_RST_BUS_OHCI0] = { 0x02c0, 29 }, > + [V3S_RST_BUS_EHCI0] = { 0x02c0, 26 }, > + [V3S_RST_BUS_EMAC] = { 0x02c0, 17 }, > + [V3S_RST_BUS_MMC2] = { 0x02c0, 10 }, > + [V3S_RST_BUS_MMC1] = { 0x02c0, 9 }, > + [V3S_RST_BUS_MMC0] = { 0x02c0, 8 }, > + [V3S_RST_BUS_EPHY] = { 0x02c8, 2 }, > + [V3S_RST_BUS_UART2] = { 0x02d8, 18 }, > + [V3S_RST_BUS_UART1] = { 0x02d8, 17 }, > + [V3S_RST_BUS_UART0] = { 0x02d8, 16 }, > + [V3S_RST_BUS_I2C1] = { 0x02d8, 1 }, > + [V3S_RST_BUS_I2C0] = { 0x02d8, 0 }, > };