RK3588 IO-domain开发
一个外设模块的Logic和IO部分一般是分开独立、单独供电的。一般 IO 电源的电压有 1.8v,3.3v,2.5v,5.0v 等。
有些 IO 同时支持多种电压,io-domain 就是配置 IO 电源域的寄存器,依据实际电路的硬件电压范围来配置对应的电压寄存器,确保正常工作。IO-domain在设备树文件中的示例:
&io_domains {
status = "okay";
dvp-supply = <&vcc_18>;
audio-supply = <&vcc_io>;
gpio30-supply = <&vcc_io>;
gpio1830-supply = <&vcc_io>;
sdcard-supply = <&vccio_sd>;
wifi-supply = <&vccio_wl>;
};
//PMUGRF 中的 io-domain 是用来控制 PMU IO
&pmu_io_domains {
status = "okay";
pmu-supply = <&vcc_io>;
vop-supply = <&vcc_io>;
};
可以通过 TRM 来搜索需要配置的 io-domain 寄存器描述,在 GRF/PMUGRF 章节搜索 ’vsel‘ , ‘VSEL’ 或者 ‘volsel’ 索引,支持配置的两种电压 1.8v / 3.3v:
- 寄存器配置成 1,一般对应的电压范围是 1.62v ~ 1.98v,typical 电压 1.8v;
- 寄存器配置成 0,一般对应的电压范围是 3.00v ~ 3.60v,typical 电压 3.3v。
在驱动的 probe 函数中的 supply name,获取 dts 中对应 supply name 定义的 regulator,再根据 regulator 的电压配置 io-domain 寄存器,如果是 1.8v 那一档,该 bit 配置为 1;如果是 3.3v 那一档,该 bit 配置为0。
如何配置IO-domain
不是每个 IO 电源域都需要配置,有些 IO 的电源域是固定的,不需要配置。下面 3 个步骤描述如何通过软件配置 io-domian:
- 通过 rockchip-io-domain.txt 文档寻找名称:找到需要配置的电源域(supply)
- 通过硬件原理图寻找 io-domain 配置的真实电压:各个输入电压域的引脚,连接的实际供电源头,一般通过PMIC或直接引出
- 通过 DTS 配置:找到了需要配置的名称和供电源头,就可以在DTS中找到对应的属性进行修改,比如:
audio-supply = <&vcc1v8_dvp>
通过硬件PIN管脚控制电源域
在 RK Soc 中的一些 IO 电源域在硬件上已经通过某个 Pin 脚来控制的,这种情况下我们 kernel 的 DTS 一般不去配置,不破坏当前的硬件状态,像 flash 和 emmc 这些模块的 IO 电源域一般都是 Pin 脚来控制的。
在 TRM 的 io-domain 寄存器描述中,我们可以看到哪些电源域是可以通过 Pin 脚来控制的,以及通过硬件上这个 Pin 脚的输入电压状态来确认当前这个电压域的配置;也可以通过 GRF 寄存器来配置。例如,RK3368 Soc 的 TRM 和 RK3368-evb 的硬件原理图上有下面寄存器的描述和硬件上 Pin 脚的配置。
无PMIC的DTS配置
如果项目上面未使用 pmic 等电源,只是简单的拉了一个电源过来,dts 上找不到 regulator 的定义,那么你需要在 dts 文件里面增加 fixed regulator的定义,一般 3.3v 和 1.8v 两个 regulator 就够用了。
regulators {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
vccio_1v8_reg: regulator@0 {
compatible = "regulator-fixed";
regulator-name = "vccio_1v8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
vccio_3v3_reg: regulator@1 {
compatible = "regulator-fixed";
regulator-name = "vccio_3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
};
&io_domains {
status = "okay";
vccio1-supply = <&vccio_3v3_reg>;
vccio2-supply = <&vccio_1v8_reg>;
vccio4-supply = <&vccio_3v3_reg>;
}