一、整体思路
dts已经配置好了电源域,软件和硬件上的电源配置已确认一致,GPIO在uboot阶段无法正常拉高拉低,所用的pmic是rk808,经排查是rk808的驱动没有配置电源域。
结合查看原理图和TRM手册,查看对应的寄存器,直接在rk808的驱动源码中使用io接口写入寄存器进行配置即可。
二、步骤
就已GPIO4_D3为例,配置GPIO4的电源域。
1.1 打开原理图,搜GPIO4_D3
可以看到,GPIO4的电源由APIO4提供,而且硬件上配置为3V
1.2 打开内核的绑定文档,查看软件上APIO4这路电源是如何配置
RK电源域的配置文档路径在:kernel/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
打开文档,可以看到:
于是可以在对应的dts中搜“io_domain”,可以看到:
&io_domains {
status = "okay";
bt656-supply = <&vcc_3v0>;
audio-supply = <&vcca1v8_codec>;
sdmmc-supply = <&vccio_sd>;
gpio1830-supply = <&vcc_3v0>;
wifi-supply = <&vcc_1v8>;
};
可见软件上的电源配置为3V,跟硬件上是一样,没有问题。
1.3 打开主控芯片的TRM手册,查看io-domains的关键寄存器
搜 “vsel” ,可以看到:
从该图,可以获取很多有用的信息:
1、寄存器名称为 GRF_IO_VSEL,基地址名称为GRF
2、该寄存器相对基地址的偏移量为 0x0e640
3、GPIO4的所有pin的电压由寄存器的第3bit控制:设为0电压为3.0V,设为1电压为1.8V
4、根据16~31bit的Description,要想让第3bit的值写入有效,则第19bit必须是1
1.4 查GRF的地址,得到寄存器GRF_IO_VSEL的完整地址
在主控芯片的TRM手册中搜GRF,如下图:
GRF的地址为0xff770000
所有寄存器GRF_IO_VSEL的完整地址是 0xff770000 + 0x0e640 = 0xff77e640
1.5 在rk808驱动源码中,使用io函数写入寄存器
我的源码路径: uboot/drivers/power/pmic/pmic_rk808.c
根据上述,我们要往寄存器GRF_IO_VSEL的第3bit写入0(因为原理图上硬件的电压配置为3.0V),第19bit要写入1(使能第3bit写入有效)。
结论就是写入的二进制数为:1000 0000 0000 0000 0000 ,转为HEX为0x80000
代码如下:
static int rk808_parse_dt(const void* blob)
{
//此处省略
node_io = fdt_node_offset_by_compatible(blob, -1, "rockchip,rk3399-io-voltage-domain");
if (node_io < 0) {
return -ENODEV;
} else {
writel(0x8000,0xff77e640);
}
}
return 0;
}