RK3568 GPIO驱动强度
概要:本文探讨了RK3568 GPIO驱动强度的设置方法,分析了相关代码实现及驱动强度的特性。文中指出驱动强度的设置与引脚类型有关,并提到官方文档中驱动能力与level的对应关系存在特殊情况。
1. 驱动强度设置背景
1.1 文件位置
- 设备树文件:
kernel/arch/arm64/boot/dts/rockchip/rockchip-pinconf.dtsi
定义了与驱动强度相关的内容,例如:pcfg_pull_none_drv_level_0: pcfg-pull-none-drv-level-0 { bias-disable; drive-strength = <0>; };
2. 驱动强度设置代码分析
2.1 核心代码片段
- 驱动代码文件:
kernel/drivers/pinctrl/pinctrl-rockchip.c
以下是删除与RK3568无关内容后的驱动强度设置代码:
static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
int pin_num, int strength)
{
struct rockchip_pinctrl *info = bank->drvdata;
struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct regmap *regmap;
int reg, ret, i, err;
u32 data, rmask, rmask_bits, temp;
u8 bit;
int drv_type = bank->drv[pin_num / 8].drv_type;
dev_dbg(info->dev, "setting drive of GPIO%d-%d to %d\n",
bank->bank_num, pin_num, strength);
ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit);
if (ctrl->type == RV1126) {
rmask_bits = RV1126_DRV_BITS_PER_PIN;
ret = strength;
goto config;
} else if (ctrl->type == RK3568) {
rmask_bits = RK3568_DRV_BITS_PER_PIN;
ret = (1 << (strength + 1)) - 1;
goto config;
}
...
config:
/* enable the write to the equivalent lower bits */
data = ((1 << rmask_bits) - 1) << (bit + 16);
rmask = data | (data >> 16);
data |= (ret << bit);
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)
reg = 0x0840;
else if (bank->bank_num == 2 && pin_num == 2)
reg = 0x0844;
else if (bank->bank_num == 2 && pin_num == 8)
reg = 0x0848;
else if (bank->bank_num == 3 && pin_num == 0)
reg = 0x084c;
else if (bank->bank_num == 3 && pin_num == 6)
reg = 0x0850;
else if (bank->bank_num == 4 && pin_num == 0)
reg = 0x0854;
else
return 0;
data = ((1 << rmask_bits) - 1) << 16;
rmask = data | (data >> 16);
data |= (1 << (strength + 1)) - 1;
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;
}
2.2 驱动强度设置的关键逻辑
rmask_bits:- 对于RK3568,
rmask_bits的值为8。
- 对于RK3568,
- 驱动强度计算:
- 假设设置驱动强度为1:
data = ((1 << rmask_bits) - 1) << 16; // data = 11111111 00000000 00000000 rmask = data | (data >> 16); // rmask = 11111111 00000000 11111111 data |= (1 << (strength + 1)) - 1; // data = 0000 0011
- 假设设置驱动强度为1:
- 寄存器更新:
- 使用
regmap_update_bits更新寄存器值。
- 使用
3. 驱动强度的特性
3.1 不同引脚的驱动强度支持
-
GPIO3A6:

- 从手册中可以看到,GPIO3A6 double bonding PAD Strength control,DS[11:6]
- 也就是说GPIO3A6是支持双键合驱动强度控制,0-11共十二级
-
GPIO1B1:

- 仅支持6级驱动强度。
3.2 官方文档中的驱动强度表
- 在文件
RK3568_PinOut_V1.1_20210202.xlsx中,可以查到每个引脚支持的驱动强度及默认值。
3.3 驱动能力与level的特殊对应关系
- 在官方文档
RK官方文档\01、Linux\Common\Pin-Ctrl\Rockchip_Developer_Guide_Linux_Pinctrl_CN.pdf中,驱动能力与level的对应关系如下:
- 驱动能力由小到大依次是:
level0、level4、level2、level6、level1、level5。 - 这表明驱动能力似乎并非随着level的增大而线性增强,而是存在特定的映射关系。
- 驱动能力由小到大依次是:
留下评论