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 <jay.xu@rock-chips.com>
Change-Id: Ibcbdc06eefa819dae114a4b9adc32cdff42d32f2
This commit is contained in:
Jianqun Xu
2022-05-16 14:52:24 +08:00
committed by Tao Huang
parent 61a32e157e
commit c106a565f6
2 changed files with 98 additions and 13 deletions

View File

@@ -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, &regmap, &reg, &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, &regmap, &reg, &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, &regmap, &reg, &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[] = {

View File

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