Index: sxiccmu.c =================================================================== RCS file: /cvs/src/sys/dev/fdt/sxiccmu.c,v retrieving revision 1.21 diff -u -p -u -r1.21 sxiccmu.c --- sxiccmu.c 3 Aug 2018 21:28:28 -0000 1.21 +++ sxiccmu.c 6 Feb 2019 00:42:27 -0000 @@ -103,6 +103,8 @@ int sxiccmu_h3_set_frequency(struct sxic 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 @@ sxiccmu_match(struct device *parent, voi 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 @@ sxiccmu_match(struct device *parent, voi 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 @@ sxiccmu_attach(struct device *parent, st 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 @@ sxiccmu_r40_get_frequency(struct sxiccmu } 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 @@ sxiccmu_r40_set_frequency(struct sxiccmu 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 -p -u -r1.23 sxiccmu_clocks.h --- sxiccmu_clocks.h 15 Jan 2019 16:07:42 -0000 1.23 +++ sxiccmu_clocks.h 6 Feb 2019 00:42:30 -0000 @@ -473,6 +473,58 @@ struct sxiccmu_ccu_bit sun8i_r40_gates[] [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 + +#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 @@ struct sxiccmu_ccu_bit sun8i_r40_resets[ [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 }, }; Index: sximmc.c =================================================================== RCS file: /cvs/src/sys/dev/fdt/sximmc.c,v retrieving revision 1.8 diff -u -p -u -r1.8 sximmc.c --- sximmc.c 29 Dec 2018 14:09:00 -0000 1.8 +++ sximmc.c 6 Feb 2019 00:42:33 -0000 @@ -646,7 +646,9 @@ sximmc_card_detect(sdmmc_chipset_handle_ struct sximmc_softc *sc = sch; int inverted, val; - if (OF_getproplen(sc->sc_node, "non-removable") == 0) + /* XXX treat broken-cd as non-removable */ + if (OF_getproplen(sc->sc_node, "non-removable") == 0 || + OF_getproplen(sc->sc_node, "broken-cd") == 0) return 1; val = gpio_controller_get_pin(sc->sc_gpio); Index: sxipio.c =================================================================== RCS file: /cvs/src/sys/dev/fdt/sxipio.c,v retrieving revision 1.9 diff -u -p -u -r1.9 sxipio.c --- sxipio.c 28 Dec 2017 18:05:09 -0000 1.9 +++ sxipio.c 6 Feb 2019 00:42:33 -0000 @@ -154,6 +154,10 @@ struct sxipio_pins sxipio_pins[] = { sun8i_h3_r_pins, nitems(sun8i_h3_r_pins) }, { + "allwinner,sun8i-v3s-pinctrl", + sun8i_v3s_pins, nitems(sun8i_v3s_pins) + }, + { "allwinner,sun9i-a80-pinctrl", sun9i_a80_pins, nitems(sun9i_a80_pins) }, Index: sxipio_pins.h =================================================================== RCS file: /cvs/src/sys/dev/fdt/sxipio_pins.h,v retrieving revision 1.5 diff -u -p -u -r1.5 sxipio_pins.h --- sxipio_pins.h 28 Dec 2017 18:05:09 -0000 1.5 +++ sxipio_pins.h 6 Feb 2019 00:43:08 -0000 @@ -6485,6 +6485,323 @@ struct sxipio_pin sun8i_h3_r_pins[] = { } }, }; +struct sxipio_pin sun8i_v3s_pins[] = { + { SXIPIO_PIN(B, 0), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "uart2", 2 }, + { "irq", 6 }, + } }, + { SXIPIO_PIN(B, 1), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "uart2", 2 }, + { "irq", 6 }, + } }, + { SXIPIO_PIN(B, 2), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "uart2", 2 }, + { "irq", 6 }, + } }, + { SXIPIO_PIN(B, 3), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "uart2", 2 }, + { "irq", 6 }, + } }, + { SXIPIO_PIN(B, 4), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "pwm0", 2 }, + { "irq", 6 }, + } }, + { SXIPIO_PIN(B, 5), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "pwm1", 2 }, + { "irq", 6 }, + } }, + { SXIPIO_PIN(B, 6), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "i2c0", 2 }, + { "irq", 6 }, + } }, + { SXIPIO_PIN(B, 7), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "i2c0", 2 }, + { "irq", 6 }, + } }, + { SXIPIO_PIN(B, 8), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "i2c1", 2 }, + { "uart0", 3 }, + { "irq", 6 }, + } }, + { SXIPIO_PIN(B, 9), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "i2c1", 2 }, + { "uart0", 3 }, + { "irq", 6 }, + } }, + { SXIPIO_PIN(C, 0), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc2", 2 }, + { "spi0", 3 }, + } }, + { SXIPIO_PIN(C, 1), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc2", 2 }, + { "spi0", 3 }, + } }, + { SXIPIO_PIN(C, 2), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc2", 2 }, + { "spi0", 3 }, + } }, + { SXIPIO_PIN(C, 3), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc2", 2 }, + { "spi0", 3 }, + } }, + { SXIPIO_PIN(E, 0), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 1), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 2), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 3), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 4), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 5), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 6), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 7), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 8), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 9), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 10), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 11), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 12), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 13), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 14), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 15), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 16), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 17), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 18), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 19), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "lcd0", 3 }, + } }, + { SXIPIO_PIN(E, 20), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "mcsi", 3 }, + } }, + { SXIPIO_PIN(E, 21), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "i2c1", 3 }, + { "uart1", 4 }, + } }, + { SXIPIO_PIN(E, 22), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "csi", 2 }, + { "i2c1", 3 }, + { "uart1", 4 }, + } }, + { SXIPIO_PIN(E, 23), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "lcd0", 3 }, + { "uart1", 4 }, + } }, + { SXIPIO_PIN(E, 24), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "lcd0", 3 }, + { "uart1", 4 }, + } }, + { SXIPIO_PIN(F, 0), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc0", 2 }, + { "jtag", 3 }, + } }, + { SXIPIO_PIN(F, 1), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc0", 2 }, + { "jtag", 3 }, + } }, + { SXIPIO_PIN(F, 2), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc0", 2 }, + { "uart0", 3 }, + } }, + { SXIPIO_PIN(F, 3), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc0", 2 }, + { "jtag", 3 }, + } }, + { SXIPIO_PIN(F, 4), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc0", 2 }, + { "uart0", 3 }, + } }, + { SXIPIO_PIN(F, 5), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc0", 2 }, + { "jtag", 3 }, + } }, + { SXIPIO_PIN(F, 6), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + } }, + { SXIPIO_PIN(G, 0), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc1", 2 }, + { "irq", 6 }, + } }, + { SXIPIO_PIN(G, 1), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc1", 2 }, + { "irq", 6 }, + } }, + { SXIPIO_PIN(G, 2), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc1", 2 }, + { "irq", 6 }, + } }, + { SXIPIO_PIN(G, 3), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc1", 2 }, + { "irq", 6 }, + } }, + { SXIPIO_PIN(G, 4), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc1", 2 }, + { "irq", 6 }, + } }, + { SXIPIO_PIN(G, 5), { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc1", 2 }, + { "irq", 6 }, + } }, +}; + struct sxipio_pin sun9i_a80_pins[] = { { SXIPIO_PIN(A, 0), { { "gpio_in", 0 },