--- sys/dev/fdt/rkpinctrl.c | 305 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 303 insertions(+), 2 deletions(-)
diff --git a/sys/dev/fdt/rkpinctrl.c b/sys/dev/fdt/rkpinctrl.c index 6e747d5987b..18353e9bdfe 100644 --- a/sys/dev/fdt/rkpinctrl.c +++ b/sys/dev/fdt/rkpinctrl.c @@ -65,6 +65,10 @@ #define RK_PD6 30 #define RK_PD7 31 +/* RK3128 registers */ +#define RK3128_GRF_GPIO0A_IOMUX 0x00a8 +#define RK3128_GRF_GPIO0L_PULL 0x0118 + /* RK3288 registers */ #define RK3288_GRF_GPIO1A_IOMUX 0x0000 #define RK3288_PMUGRF_GPIO0A_IOMUX 0x0084 @@ -141,6 +145,7 @@ struct cfdriver rkpinctrl_cd = { NULL, "rkpinctrl", DV_DULL }; +int rk3128_pinctrl(uint32_t, void *); int rk3288_pinctrl(uint32_t, void *); int rk3308_pinctrl(uint32_t, void *); int rk3328_pinctrl(uint32_t, void *); @@ -154,7 +159,8 @@ rkpinctrl_match(struct device *parent, void *match, void *aux) { struct fdt_attach_args *faa = aux; - return (OF_is_compatible(faa->fa_node, "rockchip,rk3288-pinctrl") || + return (OF_is_compatible(faa->fa_node, "rockchip,rk3128-pinctrl") || + OF_is_compatible(faa->fa_node, "rockchip,rk3288-pinctrl") || OF_is_compatible(faa->fa_node, "rockchip,rk3308-pinctrl") || OF_is_compatible(faa->fa_node, "rockchip,rk3328-pinctrl") || OF_is_compatible(faa->fa_node, "rockchip,rk3399-pinctrl") || @@ -180,7 +186,9 @@ rkpinctrl_attach(struct device *parent, struct device *self, void *aux) return; } - if (OF_is_compatible(faa->fa_node, "rockchip,rk3288-pinctrl")) + if (OF_is_compatible(faa->fa_node, "rockchip,rk3128-pinctrl")) + pinctrl_register(faa->fa_node, rk3128_pinctrl, sc); + else if (OF_is_compatible(faa->fa_node, "rockchip,rk3288-pinctrl")) pinctrl_register(faa->fa_node, rk3288_pinctrl, sc); else if (OF_is_compatible(faa->fa_node, "rockchip,rk3308-pinctrl")) pinctrl_register(faa->fa_node, rk3308_pinctrl, sc); @@ -199,6 +207,299 @@ rkpinctrl_attach(struct device *parent, struct device *self, void *aux) simplebus_attach(parent, &sc->sc_sbus.sc_dev, faa); } +/* + * Rockchip RK3128 + */ + +int +rk3128_pull(uint32_t bank, uint32_t idx, uint32_t phandle) +{ + int node; + + node = OF_getnodebyphandle(phandle); + if (node == 0) + return -1; + + if (OF_getproplen(node, "bias-pull-pin-default") == 0) + return -1; + if (OF_getproplen(node, "bias-disable") == 0) + return 0; + if (OF_getproplen(node, "bias-pull-up") == 0) + return 1; + if (OF_getproplen(node, "bias-pull-down") == 0) + return 2; + + return -1; +} + +static struct rk3128_gpio_pin { + int bank; + int pin; + int func; + int start; + int bits; +} rk3128_gpio_pins[] = { + /* GRF_GPIO0A_IOMUX */ + { 0, RK_PA0, 1, 0, 1 }, /* i2c0_scl */ + { 0, RK_PA1, 1, 2, 1 }, /* i2c0_sda */ + { 0, RK_PA2, 1, 4, 1 }, /* i2c1_scl */ + { 0, RK_PA3, 1, 6, 2 }, /* i2c1_sda */ + { 0, RK_PA3, 2, 6, 2 }, /* mmc1_cmd */ + { 0, RK_PA6, 1, 12, 2 }, /* i2c3_scl */ + { 0, RK_PA6, 2, 12, 2 }, /* hdmi_ddcscl */ + { 0, RK_PA7, 1, 14, 2 }, /* i2c3_sda */ + { 0, RK_PA7, 2, 14, 2 }, /* hdmi_ddcsda */ + /* GRF_GPIO0B_IOMUX */ + { 0, RK_PB0, 1, 0, 1 }, /* i2s_mclk */ + { 0, RK_PB1, 1, 2, 2 }, /* i2s_sclk */ + { 0, RK_PB1, 2, 2, 2 }, /* spi_clk */ + { 0, RK_PB3, 1, 6, 2 }, /* i2s_lrckrx */ + { 0, RK_PB3, 2, 6, 2 }, /* spi_txd */ + { 0, RK_PB4, 1, 8, 1 }, /* i2s_lrcktx */ + { 0, RK_PB5, 1, 10, 2 }, /* i2s_sdo */ + { 0, RK_PB5, 1, 10, 2 }, /* spi_rxd */ + { 0, RK_PB6, 1, 12, 2 }, /* i2s_sdi */ + { 0, RK_PB6, 2, 12, 2 }, /* spi_csn0 */ + { 0, RK_PB7, 1, 14, 1 }, /* hdmi_hotplugin */ + /* GRF_GPIO0C_IOMUX */ + { 0, RK_PC1, 1, 2, 2 }, /* sc_io */ + { 0, RK_PC1, 2, 2, 2 }, /* uart0_rstn */ + { 0, RK_PC4, 1, 8, 1 }, /* hdmi_cecsda */ + { 0, RK_PC7, 1, 14, 1 }, /* nand_cs1 */ + /* GRF_GPIO0D_IOMUX */ + { 0, RK_PD0, 1, 0, 2 }, /* uart2_rtsn */ + { 0, RK_PD0, 2, 0, 2 }, /* pmic_sleep */ + { 0, RK_PD1, 1, 2, 1 }, /* uart2_ctsn */ + { 0, RK_PD2, 1, 4, 1 }, /* pwm_0 */ + { 0, RK_PD3, 1, 6, 1 }, /* pwm_1 */ + { 0, RK_PD4, 1, 8, 1 }, /* pwm_2 */ + { 0, RK_PD6, 1, 12, 1 }, /* mmc1_pwren */ + + /* GRF_GPIO1A_IOMUX */ + { 1, RK_PA0, 1, 0, 2 }, /* i2s_mclk */ + { 1, RK_PA0, 2, 0, 2 }, /* sdmmc_clkout */ + { 1, RK_PA0, 3, 0, 2 }, /* xin32k */ + { 1, RK_PA1, 1, 2, 2 }, /* i2s_sclk */ + { 1, RK_PA1, 2, 2, 2 }, /* sdmmc_data0 */ + { 1, RK_PA1, 3, 2, 2 }, /* pmic_sleep */ + { 1, RK_PA2, 1, 4, 2 }, /* i2s_lrckrx */ + { 1, RK_PA2, 2, 4, 2 }, /* sdmmc_data1 */ + { 1, RK_PA3, 1, 6, 1 }, /* i2s_lrcktx */ + { 1, RK_PA4, 1, 8, 2 }, /* i2s_sdo */ + { 1, RK_PA4, 2, 8, 2 }, /* sdmmc_data2 */ + { 1, RK_PA5, 1, 10, 2 }, /* i2s_sdi */ + { 1, RK_PA5, 2, 10, 2 }, /* sdmmc_data3 */ + { 1, RK_PA7, 1, 14, 1 }, /* mmc0_wrprt */ + /* GRF_GPIO1B_IOMUX */ + { 1, RK_PB0, 1, 0, 2 }, /* spi_clk */ + { 1, RK_PB0, 2, 0, 2 }, /* uart1_ctsn */ + { 1, RK_PB1, 1, 2, 2 }, /* spi_txd */ + { 1, RK_PB1, 2, 2, 2 }, /* uart1_sout */ + { 1, RK_PB2, 1, 4, 2 }, /* spi_rxd */ + { 1, RK_PB2, 2, 4, 2 }, /* uart1_sin */ + { 1, RK_PB3, 1, 6, 2 }, /* spi_csn0 */ + { 1, RK_PB3, 2, 6, 2 }, /* uart1_rtsn */ + { 1, RK_PB4, 1, 8, 1 }, /* spi_csn1 */ + { 1, RK_PB6, 1, 12, 1 }, /* mmc0_pwren */ + { 1, RK_PB7, 1, 14, 1 }, /* mmc0_cmd */ + /* GRF_GPIO1C_IOMUX */ + { 1, RK_PC0, 1, 0, 1 }, /* mmc0_clkout */ + { 1, RK_PC1, 1, 2, 1 }, /* mmc0_detn */ + { 1, RK_PC2, 1, 4, 2 }, /* mmc0_d0 */ + { 1, RK_PC2, 2, 4, 2 }, /* uart2_tx */ + { 1, RK_PC3, 1, 6, 2 }, /* mmc0_d1 */ + { 1, RK_PC3, 2, 6, 2 }, /* uart2_rx */ + { 1, RK_PC4, 1, 8, 2 }, /* jtag_tck */ + { 1, RK_PC4, 2, 8, 2 }, /* mmc0_d2 */ + { 1, RK_PC5, 1, 10, 2 }, /* jtag_tms */ + { 1, RK_PC5, 2, 10, 2 }, /* mmc0_d3 */ + { 1, RK_PC6, 1, 12, 2 }, /* nand_cs2 */ + { 1, RK_PC6, 2, 12, 2 }, /* emmc_cmd */ + { 1, RK_PC7, 1, 14, 2 }, /* nand_cs3 */ + { 1, RK_PC7, 2, 14, 2 }, /* emmc_rstnout */ + /* GRF_GPIO1D_IOMUX */ + { 1, RK_PD0, 1, 0, 2 }, /* nand_d0 */ + { 1, RK_PD0, 2, 0, 2 }, /* emmc_d0 */ + { 1, RK_PD0, 3, 0, 2 }, /* sfc_d0 */ + { 1, RK_PD1, 1, 2, 2 }, /* nand_d1 */ + { 1, RK_PD1, 2, 2, 2 }, /* emmc_d1 */ + { 1, RK_PD1, 3, 2, 2 }, /* sfc_d1 */ + { 1, RK_PD2, 1, 4, 2 }, /* nand_d2 */ + { 1, RK_PD2, 2, 4, 2 }, /* emmc_d2 */ + { 1, RK_PD2, 3, 4, 2 }, /* sfc_d2 */ + { 1, RK_PD3, 1, 6, 2 }, /* nand_d3 */ + { 1, RK_PD3, 2, 6, 2 }, /* emmc_d3 */ + { 1, RK_PD3, 3, 6, 2 }, /* sfc_d3 */ + { 1, RK_PD4, 1, 8, 2 }, /* nand_d4 */ + { 1, RK_PD4, 2, 8, 2 }, /* emmc_d4 */ + { 1, RK_PD4, 3, 8, 2 }, /* spi_rxd1 */ + { 1, RK_PD5, 1, 10, 2 }, /* nand_d5 */ + { 1, RK_PD5, 2, 10, 2 }, /* emmc_d5 */ + { 1, RK_PD5, 3, 10, 2 }, /* spi_txd1 */ + { 1, RK_PD6, 1, 12, 2 }, /* nand_d6 */ + { 1, RK_PD6, 2, 12, 2 }, /* emmc_d6 */ + { 1, RK_PD6, 3, 12, 2 }, /* spi_csn0 */ + { 1, RK_PD7, 1, 14, 2 }, /* nand_d7 */ + { 1, RK_PD7, 2, 14, 2 }, /* emmc_d7 */ + { 1, RK_PD7, 3, 14, 2 }, /* spi_csn1 */ + + /* GRF_GPIO2A_IOMUX */ + { 2, RK_PA0, 1, 0, 2 }, /* nand_ale */ + { 2, RK_PA0, 2, 0, 2 }, /* spi_clk */ + { 2, RK_PA1, 1, 2, 2 }, /* nand_cle */ + { 2, RK_PA2, 1, 4, 2 }, /* nand_wrn */ + { 2, RK_PA2, 2, 4, 2 }, /* sfc_csn0 */ + { 2, RK_PA3, 1, 6, 2 }, /* nand_rdn */ + { 2, RK_PA3, 2, 6, 2 }, /* sfc_csn1 */ + { 2, RK_PA4, 1, 8, 2 }, /* nand_rdy */ + { 2, RK_PA4, 2, 8, 2 }, /* emmc_cmd */ + { 2, RK_PA4, 3, 8, 2 }, /* sfc_clk */ + { 2, RK_PA5, 1, 10, 2 }, /* nand_wp */ + { 2, RK_PA5, 2, 10, 2 }, /* emmc_pwren */ + { 2, RK_PA6, 1, 12, 1 }, /* nand_cs0 */ + { 2, RK_PA7, 1, 14, 2 }, /* nand_dqs */ + { 2, RK_PA7, 2, 14, 2 }, /* emmc_clkout */ + /* GRF_GPIO2B_IOMUX */ + { 2, RK_PB0, 1, 0, 2 }, /* lcdc0_dclk */ + { 2, RK_PB0, 2, 0, 2 }, /* ebc_sdclk */ + { 2, RK_PB0, 3, 0, 2 }, /* gmac_rxdv */ + { 2, RK_PB1, 1, 2, 2 }, /* lcdc0_hsync */ + { 2, RK_PB1, 2, 2, 2 }, /* ebc_sdle */ + { 2, RK_PB1, 3, 2, 2 }, /* gmac_txclk */ + { 2, RK_PB2, 1, 4, 2 }, /* lcdc0_vsync */ + { 2, RK_PB2, 2, 4, 2 }, /* ebc_sdoe */ + { 2, RK_PB2, 3, 4, 2 }, /* gmac_crs */ + { 2, RK_PB3, 1, 6, 2 }, /* lcdc0_den */ + { 2, RK_PB3, 2, 6, 2 }, /* ebc_gdclk */ + { 2, RK_PB3, 3, 6, 2 }, /* gmac_rxclk */ + { 2, RK_PB4, 1, 8, 2 }, /* lcdc0_d10 */ + { 2, RK_PB4, 2, 8, 2 }, /* ebc_sdce2 */ + { 2, RK_PB4, 3, 8, 2 }, /* gmac_mdio */ + { 2, RK_PB5, 1, 10, 2 }, /* lcdc0_d11 */ + { 2, RK_PB5, 2, 10, 2 }, /* ebc_sdce3 */ + { 2, RK_PB5, 3, 10, 2 }, /* gmac_txen */ + { 2, RK_PB6, 1, 12, 2 }, /* lcdc0_d12 */ + { 2, RK_PB6, 2, 12, 2 }, /* ebc_sdce4 */ + { 2, RK_PB6, 3, 12, 2 }, /* gmac_clk */ + { 2, RK_PB7, 1, 14, 2 }, /* lcdc0_d13 */ + { 2, RK_PB7, 2, 14, 2 }, /* ebc_sdce5 */ + { 2, RK_PB7, 3, 14, 2 }, /* gmac_rxer */ + /* GRF_GPIO2C_IOMUX */ + { 2, RK_PC0, 1, 0, 2 }, /* lcdc0_d14 */ + { 2, RK_PC0, 2, 0, 2 }, /* ebc_vcom */ + { 2, RK_PC0, 3, 0, 2 }, /* gmac_rxd1 */ + { 2, RK_PC1, 1, 2, 2 }, /* lcdc0_d15 */ + { 2, RK_PC1, 2, 2, 2 }, /* ebc_gdoe */ + { 2, RK_PC1, 3, 2, 2 }, /* gmac_rxd0 */ + { 2, RK_PC2, 1, 4, 2 }, /* lcdc0_d16 */ + { 2, RK_PC2, 2, 4, 2 }, /* ebc_gdsp */ + { 2, RK_PC2, 3, 4, 2 }, /* gmac_txd1 */ + { 2, RK_PC3, 1, 6, 2 }, /* lcdc0_d17 */ + { 2, RK_PC3, 2, 6, 2 }, /* ebc_gdpwr0 */ + { 2, RK_PC3, 3, 6, 2 }, /* gmac_txd0 */ + /* GRF_GPIO2D_IOMUX */ + { 2, RK_PD1, 1, 2, 2 }, /* lcdc0_d23 */ + { 2, RK_PD1, 1, 2, 2 }, /* lcdc0_d23 */ + { 2, RK_PD1, 2, 2, 2 }, /* ebc_gdpwr2 */ + { 2, RK_PD1, 3, 2, 2 }, /* gmac_mdc */ + { 2, RK_PD2, 1, 4, 2 }, /* sc_rst */ + { 2, RK_PD2, 2, 4, 2 }, /* uart0_sout */ + { 2, RK_PD3, 1, 6, 2 }, /* sc_clk */ + { 2, RK_PD3, 2, 6, 2 }, /* uart0_sin */ + { 2, RK_PD4, 1, 10, 2 }, /* sc_det */ + { 2, RK_PD4, 2, 10, 2 }, /* uart0_ctsn */ + { 2, RK_PD0, 1, 12, 3 }, /* lcdc0_d22 */ + { 2, RK_PD0, 2, 12, 3 }, /* ebc_gdpwr1 */ + { 2, RK_PD0, 3, 12, 3 }, /* gps_clk */ + { 2, RK_PD0, 4, 12, 3 }, /* gmac_col */ + + /* GRF_GPIO3A_IOMUX */ + /* GRF_GPIO3B_IOMUX */ + { 3, RK_PA3, 1, 6, 2 }, /* testclk_out, why A3 on gpioB? */ + /* GRF_GPIO3C_IOMUX */ + { 3, RK_PC1, 1, 2, 2 }, /* otg_drvvbus */ + /* GRF_GPIO3D_IOMUX */ + { 3, RK_PD2, 1, 4, 1 }, /* pwm_irin */ + { 3, RK_PD3, 1, 6, 1 }, /* spdif_tx */ +}; + +int +rk3128_pinctrl(uint32_t phandle, void *cookie) +{ + struct rkpinctrl_softc *sc = cookie; + uint32_t *pins; + int node, len, i; + + KASSERT(sc->sc_grf); + + node = OF_getnodebyphandle(phandle); + if (node == 0) + return -1; + + len = OF_getproplen(node, "rockchip,pins"); + if (len <= 0) + return -1; + + pins = malloc(len, M_TEMP, M_WAITOK); + if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len) + goto fail; + + for (i = 0; i < len / sizeof(uint32_t); i += 4) { + struct regmap *rm = sc->sc_grf; + struct rk3128_gpio_pin *pin = NULL; + bus_size_t off; + uint32_t bank, idx, func; + int pull, s, n; + + bank = pins[i]; + idx = pins[i + 1]; + func = pins[i + 2]; + + pin = NULL; + for (n = 0; n < nitems(rk3128_gpio_pins); n++) { + if (rk3128_gpio_pins[n].bank == bank && + rk3128_gpio_pins[n].pin == idx && + rk3128_gpio_pins[n].func == func) { + pin = &rk3128_gpio_pins[n]; + break; + } + } + + if (!pin) { + printf("%s: missing def for bank %d pin %d func %d\n", + __func__, bank, idx, func); + continue; + } + + off = RK3128_GRF_GPIO0A_IOMUX + (bank * 0x10) + + ((idx / 8) * 0x04); + pull = rk3128_pull(bank, func, pins[i + 3]); + + s = splhigh(); + + /* 3@5:4 -> 0b0000000000110000 0000000000110000 */ + regmap_write_4(rm, off, + (((1 << pin->bits) - 1) << pin->start) << 16 | + (pin->func << pin->start)); + + /* GPIO pad pull down and pull up control */ + if (pull >= 0) + /* 2 pin 17 (pc1) -> 0b00000010 0b000000?0 */ + regmap_write_4(rm, RK3128_GRF_GPIO0L_PULL + + ((idx / 16) * 0x4), + ((idx % 16) << 16) | (pull << (idx % 16))); + + splx(s); + } + + free(pins, M_TEMP, len); + return 0; + +fail: + free(pins, M_TEMP, len); + return -1; +} + /* * Rockchip RK3288 */ -- 2.47.1