diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt index 0e0527b5e0fb..ba85c1f73747 100644 --- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt @@ -28,6 +28,7 @@ Required properties for iomux controller: "rockchip,rk3188-pinctrl": for Rockchip RK3188 "rockchip,rk3228-pinctrl": for Rockchip RK3228 "rockchip,rk3288-pinctrl": for Rockchip RK3288 + "rockchip,rk3308-pinctrl": for Rockchip RK3308 "rockchip,rk3328-pinctrl": for Rockchip RK3328 "rockchip,rk3366-pinctrl": for Rockchip RK3366 "rockchip,rk3368-pinctrl": for Rockchip RK3368 diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 10e458f56830..a5bc6a101a2c 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -65,6 +65,7 @@ enum rockchip_pinctrl_type { RK3128, RK3188, RK3288, + RK3308, RK3366, RK3368, RK3399, @@ -78,6 +79,7 @@ enum rockchip_pinctrl_type { #define IOMUX_SOURCE_PMU BIT(2) #define IOMUX_UNROUTED BIT(3) #define IOMUX_WIDTH_3BIT BIT(4) +#define IOMUX_8WIDTH_2BIT BIT(5) /** * @type: iomux variant using IOMUX_* constants @@ -650,6 +652,70 @@ static struct rockchip_mux_recalced_data rk3128_mux_recalced_data[] = { }, }; +static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = { + { + .num = 1, + .pin = 14, + .reg = 0x28, + .bit = 12, + .mask = 0x7 + }, { + .num = 1, + .pin = 15, + .reg = 0x2c, + .bit = 0, + .mask = 0x3 + }, { + .num = 1, + .pin = 18, + .reg = 0x30, + .bit = 4, + .mask = 0x7 + }, { + .num = 1, + .pin = 19, + .reg = 0x30, + .bit = 8, + .mask = 0x7 + }, { + .num = 1, + .pin = 20, + .reg = 0x30, + .bit = 12, + .mask = 0x7 + }, { + .num = 1, + .pin = 21, + .reg = 0x34, + .bit = 0, + .mask = 0x7 + }, { + .num = 1, + .pin = 22, + .reg = 0x34, + .bit = 4, + .mask = 0x7 + }, { + .num = 1, + .pin = 23, + .reg = 0x34, + .bit = 8, + .mask = 0x7 + }, { + .num = 3, + .pin = 12, + .reg = 0x68, + .bit = 8, + .mask = 0x7 + }, { + .num = 3, + .pin = 13, + .reg = 0x68, + .bit = 12, + .mask = 0x7 + }, +}; + static struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = { { .num = 2, @@ -938,6 +1004,38 @@ static struct rockchip_mux_route_data rk3228_mux_route_data[] = { }, }; +static struct rockchip_mux_route_data rk3308_mux_route_data[] = { + { + /* uart2_rxm0 */ + .bank_num = 1, + .pin = 22, + .func = 2, + .route_offset = 0x314, + .route_val = BIT(16 + 2) | BIT(16 + 3), + }, { + /* uart2_rxm1 */ + .bank_num = 4, + .pin = 26, + .func = 2, + .route_offset = 0x314, + .route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2), + }, { + /* i2c3_sdam0 */ + .bank_num = 0, + .pin = 23, + .func = 2, + .route_offset = 0x314, + .route_val = BIT(16 + 4), + }, { + /* i2c3_sdam1 */ + .bank_num = 3, + .pin = 12, + .func = 2, + .route_offset = 0x314, + .route_val = BIT(16 + 4) | BIT(4), + }, +}; + static struct rockchip_mux_route_data rk3328_mux_route_data[] = { { /* uart2dbg_rxm0 */ @@ -1478,6 +1576,43 @@ static enum rockchip_pin_drv_type rk3228_calc_drv_reg_and_bit( return DRV_TYPE_IO_DEFAULT; } +#define RK3308_PULL_OFFSET 0xa0 + +static void rk3308_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; + + *regmap = info->regmap_base; + *reg = RK3308_PULL_OFFSET; + *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; + *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); + + *bit = (pin_num % RK3188_PULL_PINS_PER_REG); + *bit *= RK3188_PULL_BITS_PER_PIN; +} + +#define RK3308_DRV_GRF_OFFSET 0x100 + +static enum rockchip_pin_drv_type rk3308_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; + + *regmap = info->regmap_base; + *reg = RK3308_DRV_GRF_OFFSET; + *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; + *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); + + *bit = (pin_num % RK3288_DRV_PINS_PER_REG); + *bit *= RK3288_DRV_BITS_PER_PIN; + + return DRV_TYPE_IO_DEFAULT; +} + #define RK3366_PULL_GRF_OFFSET 0x110 #define RK3366_PULL_PMU_OFFSET 0x10 @@ -2085,6 +2220,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) case PX30: case RK3188: case RK3288: + case RK3308: case RK3366: case RK3368: case RK3399: @@ -2129,6 +2265,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, case PX30: case RK3188: case RK3288: + case RK3308: case RK3366: case RK3368: case RK3399: @@ -2192,6 +2329,27 @@ static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, return 0; } +#define RK3308_SCHMITT_PINS_PER_REG 8 +#define RK3308_SCHMITT_BANK_STRIDE 16 +#define RK3308_SCHMITT_GRF_OFFSET 0x1a0 + +static int rk3308_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; + + *regmap = info->regmap_base; + *reg = RK3308_SCHMITT_GRF_OFFSET; + + *reg += bank->bank_num * RK3308_SCHMITT_BANK_STRIDE; + *reg += ((pin_num / RK3308_SCHMITT_PINS_PER_REG) * 4); + *bit = pin_num % RK3308_SCHMITT_PINS_PER_REG; + + return 0; +} + #define RK3328_SCHMITT_BITS_PER_PIN 1 #define RK3328_SCHMITT_PINS_PER_REG 16 #define RK3328_SCHMITT_BANK_STRIDE 8 @@ -2421,6 +2579,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, case PX30: case RK3188: case RK3288: + case RK3308: case RK3366: case RK3368: case RK3399: @@ -3374,7 +3533,8 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( * 4bit iomux'es are spread over two registers. */ inc = (iom->type & (IOMUX_WIDTH_4BIT | - IOMUX_WIDTH_3BIT)) ? 8 : 4; + IOMUX_WIDTH_3BIT | + IOMUX_8WIDTH_2BIT)) ? 8 : 4; if (iom->type & IOMUX_SOURCE_PMU) pmu_offs += inc; else @@ -3752,6 +3912,44 @@ static struct rockchip_pin_ctrl rk3288_pin_ctrl = { .drv_calc_reg = rk3288_calc_drv_reg_and_bit, }; +static struct rockchip_pin_bank rk3308_pin_banks[] = { + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_8WIDTH_2BIT, + IOMUX_8WIDTH_2BIT, + IOMUX_8WIDTH_2BIT, + IOMUX_8WIDTH_2BIT), + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_8WIDTH_2BIT, + IOMUX_8WIDTH_2BIT, + IOMUX_8WIDTH_2BIT, + IOMUX_8WIDTH_2BIT), + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_8WIDTH_2BIT, + IOMUX_8WIDTH_2BIT, + IOMUX_8WIDTH_2BIT, + IOMUX_8WIDTH_2BIT), + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_8WIDTH_2BIT, + IOMUX_8WIDTH_2BIT, + IOMUX_8WIDTH_2BIT, + IOMUX_8WIDTH_2BIT), + PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_8WIDTH_2BIT, + IOMUX_8WIDTH_2BIT, + IOMUX_8WIDTH_2BIT, + IOMUX_8WIDTH_2BIT), +}; + +static struct rockchip_pin_ctrl rk3308_pin_ctrl = { + .pin_banks = rk3308_pin_banks, + .nr_banks = ARRAY_SIZE(rk3308_pin_banks), + .label = "RK3308-GPIO", + .type = RK3308, + .grf_mux_offset = 0x0, + .iomux_recalced = rk3308_mux_recalced_data, + .niomux_recalced = ARRAY_SIZE(rk3308_mux_recalced_data), + .iomux_routes = rk3308_mux_route_data, + .niomux_routes = ARRAY_SIZE(rk3308_mux_route_data), + .pull_calc_reg = rk3308_calc_pull_reg_and_bit, + .drv_calc_reg = rk3308_calc_drv_reg_and_bit, + .schmitt_calc_reg = rk3308_calc_schmitt_reg_and_bit, +}; + static struct rockchip_pin_bank rk3328_pin_banks[] = { PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0), PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), @@ -3952,6 +4150,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = { .data = &rk3228_pin_ctrl }, { .compatible = "rockchip,rk3288-pinctrl", .data = &rk3288_pin_ctrl }, + { .compatible = "rockchip,rk3308-pinctrl", + .data = &rk3308_pin_ctrl }, { .compatible = "rockchip,rk3328-pinctrl", .data = &rk3328_pin_ctrl }, { .compatible = "rockchip,rk3366-pinctrl",