RK3588 IO-domain开发

更多资料下载,冲击月薪过万,一线经验工程师录制, 干货满满的嵌入式视频教程,请点击淘宝店:wanglitao.taobao.com

一个外设模块的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>;
}