> Date: Tue, 05 Feb 2019 00:41:01 +0900
> From: SASANO Takayoshi <[email protected]>
>
> 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 },
> };