From c106a565f611a1be863caa372cc68a00eabd6bd3 Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Mon, 16 May 2022 14:52:24 +0800 Subject: [PATCH] pinctrl: rockchip: fix drive strength set for rk3308bs/px30s/rk3326s Sync driver with v4.4 and v4.19, support rk3308bs/px30s/rk3326s whose io type is new called as smic type. The smic type io configure drive strength with 3 bit, the highest bit is from slew rate bit for the origin io type, that also means the smic io not support slew rate setting. The drive strength setting difference: regval RK3308B RK3308BS 0 2mA 0mA 1 4mA 2mA 2 8mA 4mA 3 12mA 6mA 4 6mA 5 8mA 6 10mA 7 12mA Signed-off-by: Jianqun Xu Change-Id: Ibcbdc06eefa819dae114a4b9adc32cdff42d32f2 --- drivers/pinctrl/pinctrl-rockchip.c | 110 +++++++++++++++++++++++++---- drivers/pinctrl/pinctrl-rockchip.h | 1 + 2 files changed, 98 insertions(+), 13 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 43df36e54bc2..9d82bc5da112 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -223,6 +223,12 @@ .route_location = FLAG, \ } +#define S_PIN_BANK_FLAGS(ID, PIN, LABEL, MTYPE, DTYPE) \ + PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(ID, PIN, LABEL, \ + MTYPE, MTYPE, MTYPE, MTYPE, \ + DTYPE, DTYPE, DTYPE, DTYPE, \ + -1, -1, -1, -1) + #define RK_MUXROUTE_SAME(ID, PIN, FUNC, REG, VAL) \ PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_SAME) @@ -2056,6 +2062,29 @@ static void rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, *bit *= RK3288_DRV_BITS_PER_PIN; } +#define RK3308_SLEW_RATE_GRF_OFFSET 0x150 +#define RK3308_SLEW_RATE_BANK_STRIDE 16 +#define RK3308_SLEW_RATE_PINS_PER_GRF_REG 8 + +static int rk3308_calc_slew_rate_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, + struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + int pins_per_reg; + + *regmap = info->regmap_base; + *reg = RK3308_SLEW_RATE_GRF_OFFSET; + *reg += (bank->bank_num) * RK3308_SLEW_RATE_BANK_STRIDE; + pins_per_reg = RK3308_SLEW_RATE_PINS_PER_GRF_REG; + + *reg += ((pin_num / pins_per_reg) * 4); + *bit = pin_num % pins_per_reg; + + return 0; +} + #define RK3368_PULL_GRF_OFFSET 0x100 #define RK3368_PULL_PMU_OFFSET 0x10 @@ -2459,7 +2488,8 @@ static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = { { 3, 6, 9, 12, -1, -1, -1, -1 }, { 5, 10, 15, 20, -1, -1, -1, -1 }, { 4, 6, 8, 10, 12, 14, 16, 18 }, - { 4, 7, 10, 13, 16, 19, 22, 26 } + { 4, 7, 10, 13, 16, 19, 22, 26 }, + { 0, 2, 4, 6, 6, 8, 10, 12 } }; static int rockchip_get_drive_perpin(struct rockchip_pin_bank *bank, @@ -2521,6 +2551,7 @@ static int rockchip_get_drive_perpin(struct rockchip_pin_bank *bank, case DRV_TYPE_IO_DEFAULT: case DRV_TYPE_IO_1V8_OR_3V0: case DRV_TYPE_IO_1V8_ONLY: + case DRV_TYPE_IO_SMIC: rmask_bits = RK3288_DRV_BITS_PER_PIN; break; default: @@ -2536,6 +2567,20 @@ static int rockchip_get_drive_perpin(struct rockchip_pin_bank *bank, data >>= bit; data &= (1 << rmask_bits) - 1; + if (drv_type == DRV_TYPE_IO_SMIC) { + u32 tmp = 0; + + ctrl->slew_rate_calc_reg(bank, pin_num, ®map, ®, &bit); + ret = regmap_read(regmap, reg, &tmp); + if (ret) + return ret; + + tmp >>= bit; + tmp &= 0x1; + + data |= tmp << 2; + } + return rockchip_perpin_drv_list[drv_type][data]; } @@ -2545,7 +2590,7 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, struct rockchip_pinctrl *info = bank->drvdata; struct rockchip_pin_ctrl *ctrl = info->ctrl; struct regmap *regmap; - int reg, ret, i; + int reg, ret, i, err; u32 data, rmask, rmask_bits, temp; u8 bit; int drv_type = bank->drv[pin_num / 8].drv_type; @@ -2600,16 +2645,16 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, rmask = BIT(15) | BIT(31); data |= BIT(31); - ret = regmap_update_bits(regmap, reg, rmask, data); - if (ret) - return ret; + err = regmap_update_bits(regmap, reg, rmask, data); + if (err) + return err; rmask = 0x3 | (0x3 << 16); temp |= (0x3 << 16); reg += 0x4; - ret = regmap_update_bits(regmap, reg, rmask, temp); + err = regmap_update_bits(regmap, reg, rmask, temp); - return ret; + return err; case 18 ... 21: /* setting fully enclosed in the second register */ reg += 4; @@ -2624,6 +2669,7 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, case DRV_TYPE_IO_DEFAULT: case DRV_TYPE_IO_1V8_OR_3V0: case DRV_TYPE_IO_1V8_ONLY: + case DRV_TYPE_IO_SMIC: rmask_bits = RK3288_DRV_BITS_PER_PIN; break; default: @@ -2638,9 +2684,9 @@ config: rmask = data | (data >> 16); data |= (ret << bit); - ret = regmap_update_bits(regmap, reg, rmask, data); - if (ret) - return ret; + err = regmap_update_bits(regmap, reg, rmask, data); + if (err) + return err; if (ctrl->type == RK3568 && rockchip_get_cpu_version() == 0) { if (bank->bank_num == 1 && pin_num == 21) @@ -2662,9 +2708,17 @@ config: rmask = data | (data >> 16); data |= (1 << (strength + 1)) - 1; - ret = regmap_update_bits(regmap, reg, rmask, data); - if (ret) - return ret; + err = regmap_update_bits(regmap, reg, rmask, data); + if (err) + return err; + } + + if (drv_type == DRV_TYPE_IO_SMIC) { + ctrl->slew_rate_calc_reg(bank, pin_num, ®map, ®, &bit); + data = BIT(bit + 16) | (((ret >> 2) & 0x1) << bit); + err = regmap_write(regmap, reg, data); + if (err) + return err; } return 0; @@ -2961,6 +3015,10 @@ static int rockchip_get_slew_rate(struct rockchip_pin_bank *bank, int pin_num) int reg, ret; u8 bit; u32 data; + int drv_type = bank->drv[pin_num / 8].drv_type; + + if (drv_type == DRV_TYPE_IO_SMIC) + return 0; ret = ctrl->slew_rate_calc_reg(bank, pin_num, ®map, ®, &bit); if (ret) @@ -2983,6 +3041,10 @@ static int rockchip_set_slew_rate(struct rockchip_pin_bank *bank, int reg, ret; u8 bit; u32 data, rmask; + int drv_type = bank->drv[pin_num / 8].drv_type; + + if (drv_type == DRV_TYPE_IO_SMIC) + return 0; dev_dbg(info->dev, "setting slew rate of GPIO%d-%d to %d\n", bank->bank_num, pin_num, speed); @@ -3535,6 +3597,8 @@ static int rockchip_pinctrl_register(struct platform_device *pdev, } static const struct of_device_id rockchip_pinctrl_dt_match[]; +static struct rockchip_pin_bank rk3308bs_pin_banks[]; +static struct rockchip_pin_bank px30s_pin_banks[]; /* retrieve the soc specific data */ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( @@ -3549,6 +3613,10 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( match = of_match_node(rockchip_pinctrl_dt_match, node); ctrl = (struct rockchip_pin_ctrl *)match->data; + if (IS_ENABLED(CONFIG_CPU_RK3308) && soc_is_rk3308bs()) + ctrl->pin_banks = rk3308bs_pin_banks; + if (IS_ENABLED(CONFIG_CPU_PX30) && soc_is_px30s()) + ctrl->pin_banks = px30s_pin_banks; grf_offs = ctrl->grf_mux_offset; pmu_offs = ctrl->pmu_mux_offset; @@ -3861,6 +3929,13 @@ static int rockchip_pinctrl_remove(struct platform_device *pdev) return 0; } +static struct rockchip_pin_bank px30s_pin_banks[] __maybe_unused = { + S_PIN_BANK_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, DRV_TYPE_IO_SMIC), + S_PIN_BANK_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, DRV_TYPE_IO_SMIC), + S_PIN_BANK_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, DRV_TYPE_IO_SMIC), + S_PIN_BANK_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, DRV_TYPE_IO_SMIC), +}; + static struct rockchip_pin_bank px30_pin_banks[] = { PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, IOMUX_SOURCE_PMU, @@ -4211,6 +4286,14 @@ static struct rockchip_pin_ctrl rk3288_pin_ctrl __maybe_unused = { .drv_calc_reg = rk3288_calc_drv_reg_and_bit, }; +static struct rockchip_pin_bank rk3308bs_pin_banks[] __maybe_unused = { + S_PIN_BANK_FLAGS(0, 32, "gpio0", IOMUX_WIDTH_2BIT, DRV_TYPE_IO_SMIC), + S_PIN_BANK_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_2BIT, DRV_TYPE_IO_SMIC), + S_PIN_BANK_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_2BIT, DRV_TYPE_IO_SMIC), + S_PIN_BANK_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_2BIT, DRV_TYPE_IO_SMIC), + S_PIN_BANK_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_2BIT, DRV_TYPE_IO_SMIC), +}; + static struct rockchip_pin_bank rk3308_pin_banks[] = { PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT, @@ -4248,6 +4331,7 @@ static struct rockchip_pin_ctrl rk3308_pin_ctrl __maybe_unused = { .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, + .slew_rate_calc_reg = rk3308_calc_slew_rate_reg_and_bit, }; static struct rockchip_pin_bank rk3328_pin_banks[] = { diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h index 2dfc7de84287..de40db3244fc 100644 --- a/drivers/pinctrl/pinctrl-rockchip.h +++ b/drivers/pinctrl/pinctrl-rockchip.h @@ -260,6 +260,7 @@ enum rockchip_pin_drv_type { DRV_TYPE_IO_1V8_ONLY, DRV_TYPE_IO_1V8_3V0_AUTO, DRV_TYPE_IO_3V3_ONLY, + DRV_TYPE_IO_SMIC, DRV_TYPE_MAX };