跳到主要内容

IO-Domain 开发指南

:::info 文档信息

文档标识:RK-KF-YF-085 · 发布版本:V1.0.1 · 发布日期:2021-05-28 · 页数:12 · 语言:中文

原始文档:Rockchip_Developer_Guide_Linux_IO_DOMAIN_CN.pdf

:::

章节大纲​

  • IO-Domain 开发指南(P1)
    • 驱动文件与 DTS 节点(P4)
      • 驱动文件(P4)
      • DTS 节点(P4)
    • TRM 中的描述(P5)
    • 驱动软件流程(P5)
      • 初始化配置(P5)
      • 动态配置(P6)
    • 如何配置 io-domain(P6)
      • 通过 rockchip-io-domain.txt 文档寻找名称(P7)
      • 通过硬件原理图寻找 io-domain 配置的真实电压(P7)
      • 通过 DTS 配置(P8)
    • 通过硬件 Pin 脚控制的电源域一般不做配置(P8)
    • DTS 中无定义 Regulator 情况处理(P9)
    • 常见问题(P10)
      • 如何确定某个 Pin 脚所在的电源域寄存器是否配置正确(P10)
      • io-domain 的寄存器不正确(P12)

在线预览​

若预览无法显示,请直接下载 PDF 后用本地阅读器打开。


1. 驱动文件与 DTS 节点​

1.1 驱动文件​

驱动文件所在位置: drivers/power/avs/rockchip-io-domain.c

1.2 DTS 节点​

内核 3.10 版本的 DTS 节点合并:

1 io-domains { 2 compatible = "rockchip,rk3368-io-voltage-domain"; 3 rockchip,grf = <&grf>; 4 rockchip,pmugrf = <&pmugrf>; 5 6 /*GRF IO VSEL*/ _ _ 7 dvp-supply = <&ldo7 reg>; /* DVPIO VDD */ _ _ 8 wifi-supply = <&ldo7 reg>; /* APIO2 VDD */ _ _ 9 audio-supply = <&dcdc2 reg>; /* APIO3 VDD */ _ _ 10 sdcard-supply = <&ldo1 reg>; /* SDMMC0 VDD */ _ _ 11 gpio30-supply = <&dcdc2 reg>; /* APIO1 VDD */ _ _ 12 gpio1830-supply = <&dcdc2 reg>;/* ADIO4 VDD */ _ _ 13 14 /*PMU GRF IO VSEL*/ _ _ _ 15 pmu-supply = <&ldo5 reg>; /* PMUIO VDD */ _ _ 16 vop-supply = <&ldo5 reg>; /* LCDC VDD */ _ _ 17 };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17io-domains { compatible = "rockchip,rk3368-io-voltage-domain"; rockchip,grf = <&grf>; rockchip,pmugrf = <&pmugrf>; /*GRF IO VSEL*/ _ _ dvp-supply = <&ldo7 reg>; /* DVPIO VDD */ _ _ wifi-supply = <&ldo7 reg>; /* APIO2 VDD */ _ _ audio-supply = <&dcdc2 reg>; /* APIO3 VDD */ _ _ sdcard-supply = <&ldo1 reg>; /* SDMMC0 VDD */ _ _ gpio30-supply = <&dcdc2 reg>; /* APIO1 VDD */ _ _ gpio1830-supply = <&dcdc2 reg>;/* ADIO4 VDD */ _ _ /*PMU GRF IO VSEL*/ _ _ _ pmu-supply = <&ldo5 reg>; /* PMUIO VDD */ _ _ vop-supply = <&ldo5 reg>; /* LCDC VDD */ _ _ };
内
&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>; _ }; &pmu io domains { _ _ status = "okay"; pmu-supply = <&vcc io>; _ vop-supply = <&vcc io>; _ };
1&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>; _ }; &pmu io domains { _ _ status = "okay"; pmu-supply = <&vcc io>; _ vop-supply = <&vcc io>; _ };
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

2. TRM 中的描述​

很多工程师反映在 TRM 中找不到 io-domain 相关的寄存器,可以通过 TRM 来搜索需要配置的 io-domain寄存器描述,在 GRF/PMUGRF 章节搜索 ’vsel‘ , ‘VSEL’ 或者 ‘volsel’ 索引,PMUGRF 中的 io-domain是用来控制 PMU IO。

支持配置的两种电压 1.8v / 3.3v:

寄存器配置成 1,一般对应的电压范围是 1.62v ~ 1.98v,typical 电压 1.8v;寄存器配置成 0,一般对应的电压范围是 3.00v ~ 3.60v,typical 电压 3.3v。

具体电压范围要以实际芯片的 Datasheet 为准。

3. 驱动软件流程​

下面是 rockchip-io-domain.c 驱动的软件流程图,主要分为两个方面:

3.1 初始化配置​

在驱动的 probe 函数中的 supply name,获取 dts 中对应 supply name 定义的 regulator,再根据 regulator 的电压配置 io-domain 寄存器,如果是 1.8v 那一档,该 bit 配置为 1;如果是 3.3v 那一档,该 bit 配置为0。开始

匹配 Supply_Name

no丢弃获取 Regulator 成功?

yes

配置 io-domain

no继续?结束

yes

3.2 动态配置​

在初始化的过程中,会绑定 regulator,通过注册 notify 的方式,一旦这个 regulator 的电压发生变化,就会通知 io-domain 驱动更新成对应的寄存器,做到动态更新寄存器的效果。

4. 如何配置 io-domain​

不是每个 IO 电源域都需要配置,有些 IO 的电源域是固定的,不需要配置。下面 3 个步骤描述如何通过软件配置 io-domian:

4.1 通过 rockchip-io-domain.txt 文档寻找名称​

需要在软件上通过 dts 配置的 IO 电源域在 Linux Kernel 的目录下的文件都有描述:Documentation/devicetree/bindings/power/rockchip-io-domain.txt;由于 TRM 文档和硬件原理图上对同一个io-domain 名称描述可能有差异,在 rockchip-io-domain.txt 文档上统一描述了 TRM 与硬件原理图上 io- domain 名称的对应关系。

例如 RK3399 Soc,通过查看 rockchip-io-domain.txt 文档,我们知道了 RK3399 的电源域需要配置包含bt565,audio,sdmmc,gpio1830,以及 PMUGRF 下面的 pmu1830 这几个 supply,后面的 The supply connected to “***_VDD” 表示在硬件原理图上对应的名称。

Possible supplies for rk3399:

bt656-supply: The supply connected to APIO2_VDD. audio-supply: The supply connected to APIO5_VDD. sdmmc-supply: The supply connected to SDMMC0_VDD. gpio1830-supply: The supply connected to APIO4_VDD.

Possible supplies for rk3399 pmu-domains:

pmu1830-supply:The supply connected to PMUIO2_VDD.

4.2 通过硬件原理图寻找 io-domain 配置的真实电压​

仍以 RK3399-EVB 原理图和 bt656 IO 电源域为例,我们在 rockchip-io-domain.txt 中找到了 bt656 对应的硬件原理图上表示为 APIO2_VDD。所以通过逆向搜索 ‘APIO2_VDD’ 得到 RK3399-EVB 硬件原理图上的 APIO2_VDD 电源是由 RK808 下的 VCC1V8_DVP 供给。

4.3 通过 DTS 配置​

以上两步做完后,得到了配置的名称和供电源头,在 DTS 里面找到对应的 regulator: vcc1v8_dvp,就可以在 rk3399-evb.dtsi 配置上 “bt656-supply = <&vcc1v8_dvp>;”,其他的电源域配置类似。

5. 通过硬件 Pin 脚控制的电源域一般不做配置​

在 RK Soc 中的一些 IO 电源域在硬件上已经通过某个 Pin 脚来控制的,这种情况下我们 kernel 的 DTS 一般不去配置,不破坏当前的硬件状态,像 flash 和 emmc 这些模块的 IO 电源域一般都是 Pin 脚来控制的。

在 TRM 的 io-domain 寄存器描述中,我们可以看到哪些电源域是可以通过 Pin 脚来控制的,以及通过硬件上这个 Pin 脚的输入电压状态来确认当前这个电压域的配置;也可以通过 GRF 寄存器来配置,两种选择。

例如,RK3368 Soc 的 TRM 和 RK3368-evb 的硬件原理图上有下面寄存器的描述和硬件上 Pin 脚的配置。

TRM 寄存器描述:

硬件原理图:

6. DTS 中无定义 Regulator 情况处理​

在使用的过程中可能会遇到,你找不到相应的 regulator 来配置,可能项目上面未使用 pmic 等电源,只是简单的拉了一个电源过来,dts 上找不到 regulator 的定义,那么你需要在 dts 文件里面增加 fixed regulator的定义,一般 3.3v 和 1.8v 两个 regulator 就够用了。

下面是 rk3229-evb.dts 的配置例子,确定硬件上的电压是用 1.8v 还是 3.3v,配置成相应的 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>;
};

7. 常见问题​

7.1 如何确定某个 Pin 脚所在的电源域寄存器是否配置正确​

经常遇到客户报的问题是某 pin 脚的电压与所期望的不符,很有可能就是电源域配置问题。例如,在RK3399 上,软件上代码已经让 GPIO2_B1 输出高,但是实际通过量测发现电压不对;通过读取寄存器已经确认该 pin 脚已经将 iomux 配置成 gpio,并且也设置成输出高,这就很有可能是 io-domain 没有配置正确。那么这时候就要确认电源域寄存器是否配置正确,方法就是上面介绍的如何配置电源域的相反步骤。

先确定这个 io 所在的电源域,一般是看硬件原理图或者 Datasheet 来确定。例如,RK3399 下面通过硬件原理如图发现 GPIO2_B1 所在的电源域硬件上表示为 APIO2_VDD,并且 APIO2_VDD 是接的电压是 VCC1V8_DVP 。通过 rockchip-io-domain.txt 文档找到对应的名称。例如,在 rockchip-io-domain.txt 文档上找到的电源域对应的名称是 “bt656”。

在 TRM 上找到这个寄存器,通过 io 命令或者其他方式读取这个寄存器的值,一般基地址是 GRF或者 PMUGRF。例如,在 TRM 文档上搜索到 “bt656” 寄存器描述,为 bit0,查看寄存器偏移为0xe640,GRF 基地址为 0xff770000。在串口终端输入 “io -4 0xff77e640”,得到 io-domain 寄存器值,如果该寄存器值 bit0 为 1,表示 1.8v,与硬件实际电压 VCC1V8_DVP,dts 中该项配置正确;如果 bit0 为 0,则表示 3.3v,与硬件实际电压 VCC1V8_DVP 不符,dts 中该项配置不正确。

7.2 io-domain 的寄存器不正确​

常见的寄存器错误,可能是以下几个问题

所配置的 regulator 电压不对;未配置 Regulator 或 Regulator 未使能;Regulator 比 io-domain 驱动加载更慢,获取 regulator 失败。