> Feedback-ID: i5cf14421:Fastmail
> From: joshua stein <j...@jcs.org>
> 
> ---
>  sys/dev/fdt/rkpinctrl.c | 305 +++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 303 insertions(+), 2 deletions(-)

A few comments on this one.

> 
> 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;

This one isn't really needed, and we don't include it for the other
SoCs.

> +     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;

There is only 1 "pull" bit per pin.  So you can't return 2 here.  It
seems that the hardware doesn't let you control up or down.  So this
should probably return 1 for pull-down.

> +
> +     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 */
> +};

This large table does not really provide much benefit; if we're
setting an unsupported value that just means the device tree is wrong.

It is true that there are a few "weird" muxes in there that don't
follow the standard pattern of having 2 bits per pin.  But I think
those could be handled with a few lines of code.  Or a smaller table
that just has the exceptions.

> +
> +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 */

Leftover note-to-self?

> +             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 */

Likewise?

> +                     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
> 
> 

Reply via email to