Message ID | 20210319081441.368358-1-jay.xu@rock-chips.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v4] pinctrl: rockchip: add support for rk3568 | expand |
Tested on rockchip,rk3568-evb1-ddr4-v10 / # cat /sys/firmware/devicetree/base/compatible rockchip,rk3568-evb1-ddr4-v10rockchip,rk3568/ # / # cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/gpio-ranges GPIO ranges handled: 0: gpio0 GPIOS [0 - 31] PINS [0 - 31] 1: gpio1 GPIOS [32 - 63] PINS [32 - 63] 2: gpio2 GPIOS [64 - 95] PINS [64 - 95] 3: gpio3 GPIOS [96 - 127] PINS [96 - 127] 4: gpio4 GPIOS [128 - 159] PINS [128 - 159] -------------- jay.xu@rock-chips.com >RK3568 SoCs have 5 gpio controllers, each gpio has 32 pins. GPIO supports >set iomux, pull, drive strength and schmitt. > >Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com> >--- >v3: >- fix route_type to route_location, compile error fix >- remove slewrate option >v2: >- fix mux route grf base for gpio bank 0 >v1: >- modify _GENMASK to WRITE_MASK_VAL, and add comment for the define >- modify MR_GRF to RK_MUXROUTE_GRF, also for MR_SAME and MR_PMU >- add comment for pull setting for GPIO0_D0-D6 > > drivers/pinctrl/pinctrl-rockchip.c | 292 ++++++++++++++++++++++++++++- > 1 file changed, 290 insertions(+), 2 deletions(-) > >diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c >index deabfbc74a01..2eb51ddfca02 100644 >--- a/drivers/pinctrl/pinctrl-rockchip.c >+++ b/drivers/pinctrl/pinctrl-rockchip.c >@@ -63,8 +63,17 @@ enum rockchip_pinctrl_type { > RK3308, > RK3368, > RK3399, >+ RK3568, > }; > >+ >+/** >+ * Generate a bitmask for setting a value (v) with a write mask bit in hiword >+ * register 31:16 area. >+ */ >+#define WRITE_MASK_VAL(h, l, v) \ >+ (GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & GENMASK((h), (l)))) >+ > /* > * Encode variants of iomux registers into a type variable > */ >@@ -292,6 +301,25 @@ struct rockchip_pin_bank { > .pull_type[3] = pull3, \ > } > >+#define PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, FLAG) \ >+ { \ >+ .bank_num = ID, \ >+ .pin = PIN, \ >+ .func = FUNC, \ >+ .route_offset = REG, \ >+ .route_val = VAL, \ >+ .route_location = FLAG, \ >+ } >+ >+#define RK_MUXROUTE_SAME(ID, PIN, FUNC, REG, VAL) \ >+ PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_SAME) >+ >+#define RK_MUXROUTE_GRF(ID, PIN, FUNC, REG, VAL) \ >+ PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_GRF) >+ >+#define RK_MUXROUTE_PMU(ID, PIN, FUNC, REG, VAL) \ >+ PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_PMU) >+ > /** > * struct rockchip_mux_recalced_data: represent a pin iomux data. > * @num: bank number. >@@ -1396,6 +1424,102 @@ static struct rockchip_mux_route_data rk3399_mux_route_data[] = { > }, > }; > >+static struct rockchip_mux_route_data rk3568_mux_route_data[] = { >+ RK_MUXROUTE_PMU(0, RK_PB7, 1, 0x0110, WRITE_MASK_VAL(1, 0, 0)), /* PWM0 IO mux M0 */ >+ RK_MUXROUTE_PMU(0, RK_PC7, 2, 0x0110, WRITE_MASK_VAL(1, 0, 1)), /* PWM0 IO mux M1 */ >+ RK_MUXROUTE_PMU(0, RK_PC0, 1, 0x0110, WRITE_MASK_VAL(3, 2, 0)), /* PWM1 IO mux M0 */ >+ RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */ >+ RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */ >+ RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */ >+ RK_MUXROUTE_PMU(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */ >+ RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */ >+ RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */ >+ RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */ >+ RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */ >+ RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */ >+ RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */ >+ RK_MUXROUTE_PMU(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */ >+ RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */ >+ RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */ >+ RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */ >+ RK_MUXROUTE_PMU(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */ >+ RK_MUXROUTE_PMU(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */ >+ RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */ >+ RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */ >+ RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */ >+ RK_MUXROUTE_GRF(4, RK_PB2, 1, 0x0304, WRITE_MASK_VAL(2, 2, 0)), /* I2C4 IO mux M0 */ >+ RK_MUXROUTE_GRF(2, RK_PB1, 2, 0x0304, WRITE_MASK_VAL(2, 2, 1)), /* I2C4 IO mux M1 */ >+ RK_MUXROUTE_GRF(3, RK_PB4, 4, 0x0304, WRITE_MASK_VAL(4, 4, 0)), /* I2C5 IO mux M0 */ >+ RK_MUXROUTE_GRF(4, RK_PD0, 2, 0x0304, WRITE_MASK_VAL(4, 4, 1)), /* I2C5 IO mux M1 */ >+ RK_MUXROUTE_GRF(3, RK_PB1, 5, 0x0304, WRITE_MASK_VAL(14, 14, 0)), /* PWM8 IO mux M0 */ >+ RK_MUXROUTE_GRF(1, RK_PD5, 4, 0x0304, WRITE_MASK_VAL(14, 14, 1)), /* PWM8 IO mux M1 */ >+ RK_MUXROUTE_GRF(3, RK_PB2, 5, 0x0308, WRITE_MASK_VAL(0, 0, 0)), /* PWM9 IO mux M0 */ >+ RK_MUXROUTE_GRF(1, RK_PD6, 4, 0x0308, WRITE_MASK_VAL(0, 0, 1)), /* PWM9 IO mux M1 */ >+ RK_MUXROUTE_GRF(3, RK_PB5, 5, 0x0308, WRITE_MASK_VAL(2, 2, 0)), /* PWM10 IO mux M0 */ >+ RK_MUXROUTE_GRF(2, RK_PA1, 2, 0x0308, WRITE_MASK_VAL(2, 2, 1)), /* PWM10 IO mux M1 */ >+ RK_MUXROUTE_GRF(3, RK_PB6, 5, 0x0308, WRITE_MASK_VAL(4, 4, 0)), /* PWM11 IO mux M0 */ >+ RK_MUXROUTE_GRF(4, RK_PC0, 3, 0x0308, WRITE_MASK_VAL(4, 4, 1)), /* PWM11 IO mux M1 */ >+ RK_MUXROUTE_GRF(3, RK_PB7, 2, 0x0308, WRITE_MASK_VAL(6, 6, 0)), /* PWM12 IO mux M0 */ >+ RK_MUXROUTE_GRF(4, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(6, 6, 1)), /* PWM12 IO mux M1 */ >+ RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x0308, WRITE_MASK_VAL(8, 8, 0)), /* PWM13 IO mux M0 */ >+ RK_MUXROUTE_GRF(4, RK_PC6, 1, 0x0308, WRITE_MASK_VAL(8, 8, 1)), /* PWM13 IO mux M1 */ >+ RK_MUXROUTE_GRF(3, RK_PC4, 1, 0x0308, WRITE_MASK_VAL(10, 10, 0)), /* PWM14 IO mux M0 */ >+ RK_MUXROUTE_GRF(4, RK_PC2, 1, 0x0308, WRITE_MASK_VAL(10, 10, 1)), /* PWM14 IO mux M1 */ >+ RK_MUXROUTE_GRF(3, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(12, 12, 0)), /* PWM15 IO mux M0 */ >+ RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */ >+ RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */ >+ RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */ >+ RK_MUXROUTE_PMU(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */ >+ RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */ >+ RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */ >+ RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */ >+ RK_MUXROUTE_GRF(2, RK_PC1, 4, 0x030c, WRITE_MASK_VAL(4, 4, 0)), /* SPI2 IO mux M0 */ >+ RK_MUXROUTE_GRF(3, RK_PA0, 3, 0x030c, WRITE_MASK_VAL(4, 4, 1)), /* SPI2 IO mux M1 */ >+ RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */ >+ RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */ >+ RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */ >+ RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */ >+ RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */ >+ RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */ >+ RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */ >+ RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */ >+ RK_MUXROUTE_GRF(1, RK_PA6, 2, 0x030c, WRITE_MASK_VAL(14, 14, 0)), /* UART4 IO mux M0 */ >+ RK_MUXROUTE_GRF(3, RK_PB2, 4, 0x030c, WRITE_MASK_VAL(14, 14, 1)), /* UART4 IO mux M1 */ >+ RK_MUXROUTE_GRF(2, RK_PA2, 3, 0x0310, WRITE_MASK_VAL(0, 0, 0)), /* UART5 IO mux M0 */ >+ RK_MUXROUTE_GRF(3, RK_PC2, 4, 0x0310, WRITE_MASK_VAL(0, 0, 1)), /* UART5 IO mux M1 */ >+ RK_MUXROUTE_GRF(2, RK_PA4, 3, 0x0310, WRITE_MASK_VAL(2, 2, 0)), /* UART6 IO mux M0 */ >+ RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x0310, WRITE_MASK_VAL(2, 2, 1)), /* UART6 IO mux M1 */ >+ RK_MUXROUTE_GRF(2, RK_PA6, 3, 0x0310, WRITE_MASK_VAL(5, 4, 0)), /* UART7 IO mux M0 */ >+ RK_MUXROUTE_GRF(3, RK_PC4, 4, 0x0310, WRITE_MASK_VAL(5, 4, 1)), /* UART7 IO mux M1 */ >+ RK_MUXROUTE_GRF(4, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(5, 4, 2)), /* UART7 IO mux M2 */ >+ RK_MUXROUTE_GRF(2, RK_PC5, 3, 0x0310, WRITE_MASK_VAL(6, 6, 0)), /* UART8 IO mux M0 */ >+ RK_MUXROUTE_GRF(2, RK_PD7, 4, 0x0310, WRITE_MASK_VAL(6, 6, 1)), /* UART8 IO mux M1 */ >+ RK_MUXROUTE_GRF(2, RK_PB0, 3, 0x0310, WRITE_MASK_VAL(9, 8, 0)), /* UART9 IO mux M0 */ >+ RK_MUXROUTE_GRF(4, RK_PC5, 4, 0x0310, WRITE_MASK_VAL(9, 8, 1)), /* UART9 IO mux M1 */ >+ RK_MUXROUTE_GRF(4, RK_PA4, 4, 0x0310, WRITE_MASK_VAL(9, 8, 2)), /* UART9 IO mux M2 */ >+ RK_MUXROUTE_GRF(1, RK_PA2, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 IO mux M0 */ >+ RK_MUXROUTE_GRF(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux M1 */ >+ RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux M2 */ >+ RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux M0 */ >+ RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 IO mux M1 */ >+ RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO mux M0 */ >+ RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO mux M1 */ >+ RK_MUXROUTE_GRF(1, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ >+ RK_MUXROUTE_GRF(1, RK_PA6, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ >+ RK_MUXROUTE_GRF(3, RK_PD6, 5, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ >+ RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ >+ RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */ >+ RK_MUXROUTE_PMU(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */ >+ RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */ >+ RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */ >+ RK_MUXROUTE_PMU(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */ >+ RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */ >+ RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */ >+ RK_MUXROUTE_PMU(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */ >+ RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */ >+ RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */ >+}; >+ > static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin, > int mux, u32 *loc, u32 *reg, u32 *value) > { >@@ -2104,6 +2228,68 @@ static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, > *bit = (pin_num % 8) * 2; > } > >+#define RK3568_PULL_PMU_OFFSET 0x20 >+#define RK3568_PULL_GRF_OFFSET 0x80 >+#define RK3568_PULL_BITS_PER_PIN 2 >+#define RK3568_PULL_PINS_PER_REG 8 >+#define RK3568_PULL_BANK_STRIDE 0x10 >+ >+static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, >+ int pin_num, struct regmap **regmap, >+ int *reg, u8 *bit) >+{ >+ struct rockchip_pinctrl *info = bank->drvdata; >+ >+ if (bank->bank_num == 0) { >+ *regmap = info->regmap_pmu; >+ *reg = RK3568_PULL_PMU_OFFSET; >+ *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE; >+ *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); >+ >+ *bit = pin_num % RK3568_PULL_PINS_PER_REG; >+ *bit *= RK3568_PULL_BITS_PER_PIN; >+ } else { >+ *regmap = info->regmap_base; >+ *reg = RK3568_PULL_GRF_OFFSET; >+ *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE; >+ *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); >+ >+ *bit = (pin_num % RK3568_PULL_PINS_PER_REG); >+ *bit *= RK3568_PULL_BITS_PER_PIN; >+ } >+} >+ >+#define RK3568_DRV_PMU_OFFSET 0x70 >+#define RK3568_DRV_GRF_OFFSET 0x200 >+#define RK3568_DRV_BITS_PER_PIN 8 >+#define RK3568_DRV_PINS_PER_REG 2 >+#define RK3568_DRV_BANK_STRIDE 0x40 >+ >+static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, >+ int pin_num, struct regmap **regmap, >+ int *reg, u8 *bit) >+{ >+ struct rockchip_pinctrl *info = bank->drvdata; >+ >+ /* The first 32 pins of the first bank are located in PMU */ >+ if (bank->bank_num == 0) { >+ *regmap = info->regmap_pmu; >+ *reg = RK3568_DRV_PMU_OFFSET; >+ *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); >+ >+ *bit = pin_num % RK3568_DRV_PINS_PER_REG; >+ *bit *= RK3568_DRV_BITS_PER_PIN; >+ } else { >+ *regmap = info->regmap_base; >+ *reg = RK3568_DRV_GRF_OFFSET; >+ *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE; >+ *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); >+ >+ *bit = (pin_num % RK3568_DRV_PINS_PER_REG); >+ *bit *= RK3568_DRV_BITS_PER_PIN; >+ } >+} >+ > static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = { > { 2, 4, 8, 12, -1, -1, -1, -1 }, > { 3, 6, 9, 12, -1, -1, -1, -1 }, >@@ -2204,6 +2390,11 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, > bank->bank_num, pin_num, strength); > > ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); >+ if (ctrl->type == RK3568) { >+ rmask_bits = RK3568_DRV_BITS_PER_PIN; >+ ret = (1 << (strength + 1)) - 1; >+ goto config; >+ } > > ret = -EINVAL; > for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) { >@@ -2273,6 +2464,7 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, > return -EINVAL; > } > >+config: > /* enable the write to the equivalent lower bits */ > data = ((1 << rmask_bits) - 1) << (bit + 16); > rmask = data | (data >> 16); >@@ -2375,6 +2567,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, > case RK3308: > case RK3368: > case RK3399: >+ case RK3568: > pull_type = bank->pull_type[pin_num / 8]; > ret = -EINVAL; > for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]); >@@ -2384,6 +2577,14 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, > break; > } > } >+ /* >+ * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6, >+ * where that pull up value becomes 3. >+ */ >+ if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) { >+ if (ret == 1) >+ ret = 3; >+ } > > if (ret < 0) { > dev_err(info->dev, "unsupported pull setting %d\n", >@@ -2428,6 +2629,35 @@ static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, > return 0; > } > >+#define RK3568_SCHMITT_BITS_PER_PIN 2 >+#define RK3568_SCHMITT_PINS_PER_REG 8 >+#define RK3568_SCHMITT_BANK_STRIDE 0x10 >+#define RK3568_SCHMITT_GRF_OFFSET 0xc0 >+#define RK3568_SCHMITT_PMUGRF_OFFSET 0x30 >+ >+static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, >+ int pin_num, >+ struct regmap **regmap, >+ int *reg, u8 *bit) >+{ >+ struct rockchip_pinctrl *info = bank->drvdata; >+ >+ if (bank->bank_num == 0) { >+ *regmap = info->regmap_pmu; >+ *reg = RK3568_SCHMITT_PMUGRF_OFFSET; >+ } else { >+ *regmap = info->regmap_base; >+ *reg = RK3568_SCHMITT_GRF_OFFSET; >+ *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE; >+ } >+ >+ *reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4); >+ *bit = pin_num % RK3568_SCHMITT_PINS_PER_REG; >+ *bit *= RK3568_SCHMITT_BITS_PER_PIN; >+ >+ return 0; >+} >+ > static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num) > { > struct rockchip_pinctrl *info = bank->drvdata; >@@ -2446,6 +2676,13 @@ static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num) > return ret; > > data >>= bit; >+ switch (ctrl->type) { >+ case RK3568: >+ return data & ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1); >+ default: >+ break; >+ } >+ > return data & 0x1; > } > >@@ -2467,8 +2704,17 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank, > return ret; > > /* enable the write to the equivalent lower bits */ >- data = BIT(bit + 16) | (enable << bit); >- rmask = BIT(bit + 16) | BIT(bit); >+ switch (ctrl->type) { >+ case RK3568: >+ data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16); >+ rmask = data | (data >> 16); >+ data |= ((enable ? 0x2 : 0x1) << bit); >+ break; >+ default: >+ data = BIT(bit + 16) | (enable << bit); >+ rmask = BIT(bit + 16) | BIT(bit); >+ break; >+ } > > return regmap_update_bits(regmap, reg, rmask, data); > } >@@ -2642,6 +2888,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, > case RK3308: > case RK3368: > case RK3399: >+ case RK3568: > return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); > } > >@@ -4216,6 +4463,45 @@ static struct rockchip_pin_ctrl rk3399_pin_ctrl = { > .drv_calc_reg = rk3399_calc_drv_reg_and_bit, > }; > >+static struct rockchip_pin_bank rk3568_pin_banks[] = { >+ PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, >+ IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, >+ IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, >+ IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT), >+ PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, >+ IOMUX_WIDTH_4BIT, >+ IOMUX_WIDTH_4BIT, >+ IOMUX_WIDTH_4BIT), >+ PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, >+ IOMUX_WIDTH_4BIT, >+ IOMUX_WIDTH_4BIT, >+ IOMUX_WIDTH_4BIT), >+ PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, >+ IOMUX_WIDTH_4BIT, >+ IOMUX_WIDTH_4BIT, >+ IOMUX_WIDTH_4BIT), >+ PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, >+ IOMUX_WIDTH_4BIT, >+ IOMUX_WIDTH_4BIT, >+ IOMUX_WIDTH_4BIT), >+}; >+ >+static struct rockchip_pin_ctrl rk3568_pin_ctrl = { >+ .pin_banks = rk3568_pin_banks, >+ .nr_banks = ARRAY_SIZE(rk3568_pin_banks), >+ .label = "RK3568-GPIO", >+ .type = RK3568, >+ .grf_mux_offset = 0x0, >+ .pmu_mux_offset = 0x0, >+ .grf_drv_offset = 0x0200, >+ .pmu_drv_offset = 0x0070, >+ .iomux_routes = rk3568_mux_route_data, >+ .niomux_routes = ARRAY_SIZE(rk3568_mux_route_data), >+ .pull_calc_reg = rk3568_calc_pull_reg_and_bit, >+ .drv_calc_reg = rk3568_calc_drv_reg_and_bit, >+ .schmitt_calc_reg = rk3568_calc_schmitt_reg_and_bit, >+}; >+ > static const struct of_device_id rockchip_pinctrl_dt_match[] = { > { .compatible = "rockchip,px30-pinctrl", > .data = &px30_pin_ctrl }, >@@ -4245,6 +4531,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = { > .data = &rk3368_pin_ctrl }, > { .compatible = "rockchip,rk3399-pinctrl", > .data = &rk3399_pin_ctrl }, >+ { .compatible = "rockchip,rk3568-pinctrl", >+ .data = &rk3568_pin_ctrl }, > {}, > }; > >-- >2.25.1 > > > >
On Fri, Mar 19, 2021 at 9:14 AM Jianqun Xu <jay.xu@rock-chips.com> wrote: > RK3568 SoCs have 5 gpio controllers, each gpio has 32 pins. GPIO supports > set iomux, pull, drive strength and schmitt. > > Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com> > --- > v3: > - fix route_type to route_location, compile error fix > - remove slewrate option This v3 applied. Any additional review comments can be fixed in follow-up patches. Yours, Linus Walleij
Hi Linus, Jianqun, On Thu, 8 Apr 2021 at 10:41, Linus Walleij <linus.walleij@linaro.org> wrote: > > On Fri, Mar 19, 2021 at 9:14 AM Jianqun Xu <jay.xu@rock-chips.com> wrote: > > > RK3568 SoCs have 5 gpio controllers, each gpio has 32 pins. GPIO supports > > set iomux, pull, drive strength and schmitt. > > > > Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com> > > --- > > v3: > > - fix route_type to route_location, compile error fix > > - remove slewrate option > > This v3 applied. Any additional review comments can be fixed in follow-up > patches. > I'm really glad to see RK3568 happening this early :-) Seems we are missing the dt-bindings for the new compatible string "rockchip,rk3568-pinctrl". Is there a patch for it somewhere? Thanks a lot! Ezequiel
On Fri, Apr 9, 2021 at 6:17 AM Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> wrote: > Seems we are missing the dt-bindings for the new compatible string > "rockchip,rk3568-pinctrl". Is there a patch for it somewhere? Nope please send one :) Yours, Linus Walleij
Good Afternoon, I'm currently working on the rk3566 early bringup support in mainline and encountered an issue with this patch set. Unfortunately in the rk3568/rk3566 the gpio registers switched to the (16 bits write enable / 16 bits config) register format that other rockchip registers use. This differs from previous chips where all 32 bits were used for gpio configuration. The patch fails to account for this, which causes all gpios to fail to function. For clarity, this only affects GPIO_SWPORT_DR and GPIO_SWPORT_DDR. I'm currently working on a patch to fix this issue, but I know that you are planning on breaking out the gpio functions into a separate driver and wanted to make you aware of this immediately. Very Respectfully, Peter Geis On Fri, Apr 9, 2021 at 8:38 AM Linus Walleij <linus.walleij@linaro.org> wrote: > > On Fri, Apr 9, 2021 at 6:17 AM Ezequiel Garcia > <ezequiel@vanguardiasur.com.ar> wrote: > > > Seems we are missing the dt-bindings for the new compatible string > > "rockchip,rk3568-pinctrl". Is there a patch for it somewhere? > > Nope please send one :) > > Yours, > Linus Walleij > > _______________________________________________ > Linux-rockchip mailing list > Linux-rockchip@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-rockchip
Hi Peter, Am Samstag, 10. April 2021, 20:30:52 CEST schrieb Peter Geis: > Good Afternoon, > > I'm currently working on the rk3566 early bringup support in mainline > and encountered an issue with this patch set. > Unfortunately in the rk3568/rk3566 the gpio registers switched to the > (16 bits write enable / 16 bits config) register format that other > rockchip registers use. > This differs from previous chips where all 32 bits were used for gpio > configuration. > The patch fails to account for this, which causes all gpios to fail to function. > > For clarity, this only affects GPIO_SWPORT_DR and GPIO_SWPORT_DDR. > > I'm currently working on a patch to fix this issue, but I know that > you are planning on breaking out the gpio functions into a separate > driver and wanted to make you aware of this immediately. just pointing to Jianqun's series providing the gpio controller support: https://lore.kernel.org/r/20210324064704.950104-1-jay.xu@rock-chips.com which introduces the necessary writemask-handling but seems to need an update, judging by Ezequiel's reply to it. Heiko > Very Respectfully, > Peter Geis > > On Fri, Apr 9, 2021 at 8:38 AM Linus Walleij <linus.walleij@linaro.org> wrote: > > > > On Fri, Apr 9, 2021 at 6:17 AM Ezequiel Garcia > > <ezequiel@vanguardiasur.com.ar> wrote: > > > > > Seems we are missing the dt-bindings for the new compatible string > > > "rockchip,rk3568-pinctrl". Is there a patch for it somewhere? > > > > Nope please send one :) > > > > Yours, > > Linus Walleij > > > > _______________________________________________ > > Linux-rockchip mailing list > > Linux-rockchip@lists.infradead.org > > http://lists.infradead.org/mailman/listinfo/linux-rockchip >
On Sat, Apr 10, 2021 at 11:10 PM Heiko Stübner <heiko@sntech.de> wrote: > Am Samstag, 10. April 2021, 20:30:52 CEST schrieb Peter Geis: > > Good Afternoon, > > > > I'm currently working on the rk3566 early bringup support in mainline > > and encountered an issue with this patch set. > > Unfortunately in the rk3568/rk3566 the gpio registers switched to the > > (16 bits write enable / 16 bits config) register format that other > > rockchip registers use. > > This differs from previous chips where all 32 bits were used for gpio > > configuration. > > The patch fails to account for this, which causes all gpios to fail to function. > > > > For clarity, this only affects GPIO_SWPORT_DR and GPIO_SWPORT_DDR. > > > > I'm currently working on a patch to fix this issue, but I know that > > you are planning on breaking out the gpio functions into a separate > > driver and wanted to make you aware of this immediately. > > just pointing to Jianqun's series providing the gpio controller support: > > https://lore.kernel.org/r/20210324064704.950104-1-jay.xu@rock-chips.com > > which introduces the necessary writemask-handling but seems to need an > update, judging by Ezequiel's reply to it. Does this mean that if we get a speedy and nice looking respin of the GPIO series we probably got this problem covered? The merge window is getting close but it would be nice to get this in. Yours, Linus Walleij
On Sat, Apr 10, 2021 at 8:40 PM Linus Walleij <linus.walleij@linaro.org> wrote: > > On Sat, Apr 10, 2021 at 11:10 PM Heiko Stübner <heiko@sntech.de> wrote: > > Am Samstag, 10. April 2021, 20:30:52 CEST schrieb Peter Geis: > > > Good Afternoon, > > > > > > I'm currently working on the rk3566 early bringup support in mainline > > > and encountered an issue with this patch set. > > > Unfortunately in the rk3568/rk3566 the gpio registers switched to the > > > (16 bits write enable / 16 bits config) register format that other > > > rockchip registers use. > > > This differs from previous chips where all 32 bits were used for gpio > > > configuration. > > > The patch fails to account for this, which causes all gpios to fail to function. > > > > > > For clarity, this only affects GPIO_SWPORT_DR and GPIO_SWPORT_DDR. > > > > > > I'm currently working on a patch to fix this issue, but I know that > > > you are planning on breaking out the gpio functions into a separate > > > driver and wanted to make you aware of this immediately. > > > > just pointing to Jianqun's series providing the gpio controller support: > > > > https://lore.kernel.org/r/20210324064704.950104-1-jay.xu@rock-chips.com > > > > which introduces the necessary writemask-handling but seems to need an > > update, judging by Ezequiel's reply to it. > > Does this mean that if we get a speedy and nice looking respin of the > GPIO series we probably got this problem covered? > > The merge window is getting close but it would be nice to get this in. Thank you for the responses! With a bit of effort and a quick build fix, I've successfully rebased the gpio patch set to the latest linux-next. I now have functional gpio control on the rk3566. I haven't tested them on older devices yet though. With your blessing I can send in the rebased patches in the morning, unless Jianqun wants to handle it. > > Yours, > Linus Walleij
Hi Peter, Am Sonntag, 11. April 2021, 05:40:05 CEST schrieb Peter Geis: > On Sat, Apr 10, 2021 at 8:40 PM Linus Walleij <linus.walleij@linaro.org> wrote: > > > > On Sat, Apr 10, 2021 at 11:10 PM Heiko Stübner <heiko@sntech.de> wrote: > > > Am Samstag, 10. April 2021, 20:30:52 CEST schrieb Peter Geis: > > > > Good Afternoon, > > > > > > > > I'm currently working on the rk3566 early bringup support in mainline > > > > and encountered an issue with this patch set. > > > > Unfortunately in the rk3568/rk3566 the gpio registers switched to the > > > > (16 bits write enable / 16 bits config) register format that other > > > > rockchip registers use. > > > > This differs from previous chips where all 32 bits were used for gpio > > > > configuration. > > > > The patch fails to account for this, which causes all gpios to fail to function. > > > > > > > > For clarity, this only affects GPIO_SWPORT_DR and GPIO_SWPORT_DDR. > > > > > > > > I'm currently working on a patch to fix this issue, but I know that > > > > you are planning on breaking out the gpio functions into a separate > > > > driver and wanted to make you aware of this immediately. > > > > > > just pointing to Jianqun's series providing the gpio controller support: > > > > > > https://lore.kernel.org/r/20210324064704.950104-1-jay.xu@rock-chips.com > > > > > > which introduces the necessary writemask-handling but seems to need an > > > update, judging by Ezequiel's reply to it. > > > > Does this mean that if we get a speedy and nice looking respin of the > > GPIO series we probably got this problem covered? > > > > The merge window is getting close but it would be nice to get this in. > > Thank you for the responses! > With a bit of effort and a quick build fix, I've successfully rebased > the gpio patch set to the latest linux-next. > I now have functional gpio control on the rk3566. > I haven't tested them on older devices yet though. > > With your blessing I can send in the rebased patches in the morning, > unless Jianqun wants to handle it. I don't know which blessing you need, but from my POV - please do that :-D Especially as Jianqun already submitted where he wants to go with that and you just rebased it there shouldn't be any opposing directions here. I can give it a test on other platforms when you submit if needed. Heiko > > > > > Yours, > > Linus Walleij >
On Sun, Apr 11, 2021 at 5:40 AM Peter Geis <pgwipeout@gmail.com> wrote: > Thank you for the responses! > With a bit of effort and a quick build fix, I've successfully rebased > the gpio patch set to the latest linux-next. Ooops maybe I should have been clear, since I need to merge it into the pinctrl tree I need it to be based on the pinctrl "devel" branch. Sorry if I wasn't clear, no maintainers work on top of linux-next, only individual developers do... Yours, Linus Walleij
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index deabfbc74a01..2eb51ddfca02 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -63,8 +63,17 @@ enum rockchip_pinctrl_type { RK3308, RK3368, RK3399, + RK3568, }; + +/** + * Generate a bitmask for setting a value (v) with a write mask bit in hiword + * register 31:16 area. + */ +#define WRITE_MASK_VAL(h, l, v) \ + (GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & GENMASK((h), (l)))) + /* * Encode variants of iomux registers into a type variable */ @@ -292,6 +301,25 @@ struct rockchip_pin_bank { .pull_type[3] = pull3, \ } +#define PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, FLAG) \ + { \ + .bank_num = ID, \ + .pin = PIN, \ + .func = FUNC, \ + .route_offset = REG, \ + .route_val = VAL, \ + .route_location = FLAG, \ + } + +#define RK_MUXROUTE_SAME(ID, PIN, FUNC, REG, VAL) \ + PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_SAME) + +#define RK_MUXROUTE_GRF(ID, PIN, FUNC, REG, VAL) \ + PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_GRF) + +#define RK_MUXROUTE_PMU(ID, PIN, FUNC, REG, VAL) \ + PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_PMU) + /** * struct rockchip_mux_recalced_data: represent a pin iomux data. * @num: bank number. @@ -1396,6 +1424,102 @@ static struct rockchip_mux_route_data rk3399_mux_route_data[] = { }, }; +static struct rockchip_mux_route_data rk3568_mux_route_data[] = { + RK_MUXROUTE_PMU(0, RK_PB7, 1, 0x0110, WRITE_MASK_VAL(1, 0, 0)), /* PWM0 IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PC7, 2, 0x0110, WRITE_MASK_VAL(1, 0, 1)), /* PWM0 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PC0, 1, 0x0110, WRITE_MASK_VAL(3, 2, 0)), /* PWM1 IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PB2, 1, 0x0304, WRITE_MASK_VAL(2, 2, 0)), /* I2C4 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PB1, 2, 0x0304, WRITE_MASK_VAL(2, 2, 1)), /* I2C4 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB4, 4, 0x0304, WRITE_MASK_VAL(4, 4, 0)), /* I2C5 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PD0, 2, 0x0304, WRITE_MASK_VAL(4, 4, 1)), /* I2C5 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB1, 5, 0x0304, WRITE_MASK_VAL(14, 14, 0)), /* PWM8 IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PD5, 4, 0x0304, WRITE_MASK_VAL(14, 14, 1)), /* PWM8 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB2, 5, 0x0308, WRITE_MASK_VAL(0, 0, 0)), /* PWM9 IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PD6, 4, 0x0308, WRITE_MASK_VAL(0, 0, 1)), /* PWM9 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB5, 5, 0x0308, WRITE_MASK_VAL(2, 2, 0)), /* PWM10 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PA1, 2, 0x0308, WRITE_MASK_VAL(2, 2, 1)), /* PWM10 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB6, 5, 0x0308, WRITE_MASK_VAL(4, 4, 0)), /* PWM11 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC0, 3, 0x0308, WRITE_MASK_VAL(4, 4, 1)), /* PWM11 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB7, 2, 0x0308, WRITE_MASK_VAL(6, 6, 0)), /* PWM12 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(6, 6, 1)), /* PWM12 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x0308, WRITE_MASK_VAL(8, 8, 0)), /* PWM13 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC6, 1, 0x0308, WRITE_MASK_VAL(8, 8, 1)), /* PWM13 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC4, 1, 0x0308, WRITE_MASK_VAL(10, 10, 0)), /* PWM14 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC2, 1, 0x0308, WRITE_MASK_VAL(10, 10, 1)), /* PWM14 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(12, 12, 0)), /* PWM15 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PC1, 4, 0x030c, WRITE_MASK_VAL(4, 4, 0)), /* SPI2 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PA0, 3, 0x030c, WRITE_MASK_VAL(4, 4, 1)), /* SPI2 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA6, 2, 0x030c, WRITE_MASK_VAL(14, 14, 0)), /* UART4 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PB2, 4, 0x030c, WRITE_MASK_VAL(14, 14, 1)), /* UART4 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PA2, 3, 0x0310, WRITE_MASK_VAL(0, 0, 0)), /* UART5 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC2, 4, 0x0310, WRITE_MASK_VAL(0, 0, 1)), /* UART5 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PA4, 3, 0x0310, WRITE_MASK_VAL(2, 2, 0)), /* UART6 IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x0310, WRITE_MASK_VAL(2, 2, 1)), /* UART6 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PA6, 3, 0x0310, WRITE_MASK_VAL(5, 4, 0)), /* UART7 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC4, 4, 0x0310, WRITE_MASK_VAL(5, 4, 1)), /* UART7 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(5, 4, 2)), /* UART7 IO mux M2 */ + RK_MUXROUTE_GRF(2, RK_PC5, 3, 0x0310, WRITE_MASK_VAL(6, 6, 0)), /* UART8 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD7, 4, 0x0310, WRITE_MASK_VAL(6, 6, 1)), /* UART8 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PB0, 3, 0x0310, WRITE_MASK_VAL(9, 8, 0)), /* UART9 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC5, 4, 0x0310, WRITE_MASK_VAL(9, 8, 1)), /* UART9 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PA4, 4, 0x0310, WRITE_MASK_VAL(9, 8, 2)), /* UART9 IO mux M2 */ + RK_MUXROUTE_GRF(1, RK_PA2, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux M2 */ + RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PA6, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PD6, 5, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */ + RK_MUXROUTE_PMU(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */ + RK_MUXROUTE_PMU(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */ + RK_MUXROUTE_PMU(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */ +}; + static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin, int mux, u32 *loc, u32 *reg, u32 *value) { @@ -2104,6 +2228,68 @@ static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, *bit = (pin_num % 8) * 2; } +#define RK3568_PULL_PMU_OFFSET 0x20 +#define RK3568_PULL_GRF_OFFSET 0x80 +#define RK3568_PULL_BITS_PER_PIN 2 +#define RK3568_PULL_PINS_PER_REG 8 +#define RK3568_PULL_BANK_STRIDE 0x10 + +static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK3568_PULL_PMU_OFFSET; + *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE; + *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); + + *bit = pin_num % RK3568_PULL_PINS_PER_REG; + *bit *= RK3568_PULL_BITS_PER_PIN; + } else { + *regmap = info->regmap_base; + *reg = RK3568_PULL_GRF_OFFSET; + *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE; + *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); + + *bit = (pin_num % RK3568_PULL_PINS_PER_REG); + *bit *= RK3568_PULL_BITS_PER_PIN; + } +} + +#define RK3568_DRV_PMU_OFFSET 0x70 +#define RK3568_DRV_GRF_OFFSET 0x200 +#define RK3568_DRV_BITS_PER_PIN 8 +#define RK3568_DRV_PINS_PER_REG 2 +#define RK3568_DRV_BANK_STRIDE 0x40 + +static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + /* The first 32 pins of the first bank are located in PMU */ + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK3568_DRV_PMU_OFFSET; + *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); + + *bit = pin_num % RK3568_DRV_PINS_PER_REG; + *bit *= RK3568_DRV_BITS_PER_PIN; + } else { + *regmap = info->regmap_base; + *reg = RK3568_DRV_GRF_OFFSET; + *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE; + *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); + + *bit = (pin_num % RK3568_DRV_PINS_PER_REG); + *bit *= RK3568_DRV_BITS_PER_PIN; + } +} + static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = { { 2, 4, 8, 12, -1, -1, -1, -1 }, { 3, 6, 9, 12, -1, -1, -1, -1 }, @@ -2204,6 +2390,11 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, bank->bank_num, pin_num, strength); ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); + if (ctrl->type == RK3568) { + rmask_bits = RK3568_DRV_BITS_PER_PIN; + ret = (1 << (strength + 1)) - 1; + goto config; + } ret = -EINVAL; for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) { @@ -2273,6 +2464,7 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, return -EINVAL; } +config: /* enable the write to the equivalent lower bits */ data = ((1 << rmask_bits) - 1) << (bit + 16); rmask = data | (data >> 16); @@ -2375,6 +2567,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, case RK3308: case RK3368: case RK3399: + case RK3568: pull_type = bank->pull_type[pin_num / 8]; ret = -EINVAL; for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]); @@ -2384,6 +2577,14 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, break; } } + /* + * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6, + * where that pull up value becomes 3. + */ + if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) { + if (ret == 1) + ret = 3; + } if (ret < 0) { dev_err(info->dev, "unsupported pull setting %d\n", @@ -2428,6 +2629,35 @@ static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, return 0; } +#define RK3568_SCHMITT_BITS_PER_PIN 2 +#define RK3568_SCHMITT_PINS_PER_REG 8 +#define RK3568_SCHMITT_BANK_STRIDE 0x10 +#define RK3568_SCHMITT_GRF_OFFSET 0xc0 +#define RK3568_SCHMITT_PMUGRF_OFFSET 0x30 + +static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, + struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK3568_SCHMITT_PMUGRF_OFFSET; + } else { + *regmap = info->regmap_base; + *reg = RK3568_SCHMITT_GRF_OFFSET; + *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE; + } + + *reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4); + *bit = pin_num % RK3568_SCHMITT_PINS_PER_REG; + *bit *= RK3568_SCHMITT_BITS_PER_PIN; + + return 0; +} + static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num) { struct rockchip_pinctrl *info = bank->drvdata; @@ -2446,6 +2676,13 @@ static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num) return ret; data >>= bit; + switch (ctrl->type) { + case RK3568: + return data & ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1); + default: + break; + } + return data & 0x1; } @@ -2467,8 +2704,17 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank, return ret; /* enable the write to the equivalent lower bits */ - data = BIT(bit + 16) | (enable << bit); - rmask = BIT(bit + 16) | BIT(bit); + switch (ctrl->type) { + case RK3568: + data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16); + rmask = data | (data >> 16); + data |= ((enable ? 0x2 : 0x1) << bit); + break; + default: + data = BIT(bit + 16) | (enable << bit); + rmask = BIT(bit + 16) | BIT(bit); + break; + } return regmap_update_bits(regmap, reg, rmask, data); } @@ -2642,6 +2888,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, case RK3308: case RK3368: case RK3399: + case RK3568: return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); } @@ -4216,6 +4463,45 @@ static struct rockchip_pin_ctrl rk3399_pin_ctrl = { .drv_calc_reg = rk3399_calc_drv_reg_and_bit, }; +static struct rockchip_pin_bank rk3568_pin_banks[] = { + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), +}; + +static struct rockchip_pin_ctrl rk3568_pin_ctrl = { + .pin_banks = rk3568_pin_banks, + .nr_banks = ARRAY_SIZE(rk3568_pin_banks), + .label = "RK3568-GPIO", + .type = RK3568, + .grf_mux_offset = 0x0, + .pmu_mux_offset = 0x0, + .grf_drv_offset = 0x0200, + .pmu_drv_offset = 0x0070, + .iomux_routes = rk3568_mux_route_data, + .niomux_routes = ARRAY_SIZE(rk3568_mux_route_data), + .pull_calc_reg = rk3568_calc_pull_reg_and_bit, + .drv_calc_reg = rk3568_calc_drv_reg_and_bit, + .schmitt_calc_reg = rk3568_calc_schmitt_reg_and_bit, +}; + static const struct of_device_id rockchip_pinctrl_dt_match[] = { { .compatible = "rockchip,px30-pinctrl", .data = &px30_pin_ctrl }, @@ -4245,6 +4531,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = { .data = &rk3368_pin_ctrl }, { .compatible = "rockchip,rk3399-pinctrl", .data = &rk3399_pin_ctrl }, + { .compatible = "rockchip,rk3568-pinctrl", + .data = &rk3568_pin_ctrl }, {}, };
RK3568 SoCs have 5 gpio controllers, each gpio has 32 pins. GPIO supports set iomux, pull, drive strength and schmitt. Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com> --- v3: - fix route_type to route_location, compile error fix - remove slewrate option v2: - fix mux route grf base for gpio bank 0 v1: - modify _GENMASK to WRITE_MASK_VAL, and add comment for the define - modify MR_GRF to RK_MUXROUTE_GRF, also for MR_SAME and MR_PMU - add comment for pull setting for GPIO0_D0-D6 drivers/pinctrl/pinctrl-rockchip.c | 292 ++++++++++++++++++++++++++++- 1 file changed, 290 insertions(+), 2 deletions(-)