4.3.6. IO-Domain 调试指南
4.3.6.1. IO-Domain 概述
在嵌入式系统中,电压域( Voltage Domain)指的是为某一部分硬件或电路提供特定电压的电源区域。一个系统可能包含多个电压域,每个电压域会根据不同模块的需要提供不同的电压。这些电压域通常通过不同的模块或子系统进行管理与控制
注意:
电压域配置:如果硬件设计外接电压域为 3.3V, IO-Domain 需要配置为 3.3V;如果外接电压域为 1.8V, IO-Domain 需要配置为 1.8V。
电压不匹配问题:外接电压域为 3.3V,而 IO-Domain 配置为 1.8V,可能会对芯片造成损伤;如果外接电压域为 1.8V,而 IO-Domain 配置为 3.3V,相关模块可能无法正常工作。
4.3.6.2. IO-Domain 特点
在芯片中,电源管理通常按不同的功能域划分,每个功能域根据需求管理不同的电源:
AON (Always On) Power Domain:该电源域负责总是处于活动状态的电源管理,保证即使在设备休眠时也能保持某些基本功能(例如,唤醒和时间跟踪)正常工作。
DSP (DSP Subsystem) Power Domain:负责数字信号处理器( DSP)子系统的电源管理。 DSP 是处理数字信号(如音频、视频、语音识别等)的专用硬件模块,通常在特定的多媒体应用中使用。
SOC (System on Chip) Power Domain:包括整个芯片的管理,负责与芯片的主要控制器、总线以及其他基本功能模块相关的电源供应。
CPU (CPU Subsystem) Power Domain:该电源域管理 CPU 子系统的电源, CPU 是执行大部分计算任务的核心单元。
BPU (BPU Subsystem) Power Domain: BPU(即神经网络处理单元或智能处理单元)负责处理与人工智能( AI)、机器学习( ML)等相关的任务。
DDR (DDR Subsystem) Power Domain:负责动态随机访问内存( DDR)的电源管理。 DDR 存储器用于系统数据存取,在大部分应用中占用较大功耗。
VIDEO (Video Subsystem) Power Domain:该电源域负责视频处理模块的电源供应,包括视频解码、编码、显示等功能。
GPU (GPU Subsystem) Power Domain:负责图形处理单元( GPU)的电源管理。 GPU 主要用于图形渲染、图像处理、计算加速等任务,在图形密集型应用中发挥重要作用。
ISP (ISP Subsystem) Power Domain:该电源域管理图像信号处理器( ISP)的电源供应。 ISP 通常用于处理从相机传感器获取的原始图像数据,执行图像的滤波、降噪、白平衡等处理。
4.3.6.3. 功能描述
IO-Domain 典型应用
在芯片中通常使用设备树来配置 IO-Domain , 但不同引脚使用的 IO-Domain 与硬件原理图强相关,查看原理图, AON GPIO 电源域配置如下:

设备树中 AON Domain 对应上图中原理图 AON_GPIO_XX 的引脚,配置如下:
/* AON_GPIO 0-7 */
aon_gpio_0: aon_gpio_0 {
horizon,pins = <
AON_GPIO0_PIN0 INVALID_PINMUX BIT_OFFSET0 MUX_ALT0 &pconf_input_en_1v8
>;
};
aon_gpio_1: aon_gpio_1 {
horizon,pins = <
AON_GPIO0_PIN1 INVALID_PINMUX BIT_OFFSET0 MUX_ALT0 &pconf_input_en_1v8
>;
};
pconf_input_en_1v8: pconf-input-en-1v8 {
input-enable;
power-source = <HORIZON_IO_PAD_VOLTAGE_1V8>;
drive-strength = <3>;
};
这段代码描述了与 AON_GPIO( Always On GPIO)复用引脚 的相关配置和使用的电源域:
aon_gpio_0和aon_gpio_1是为两个 GPIO 引脚设置的别名。它们分别描述了两个物理 GPIO 引脚, aon_gpio_0 和 aon_gpio_1 ,对应的是 AON_GPIO0_PIN0 和 AON_GPIO0_PIN1 。`horizon,pins 是一个属性,定义了每个引脚的配置信息。
AON_GPIO0_PIN0和AON_GPIO0_PIN1:这些是设备树中定义的物理 GPIO 引脚标识符。INVALID_PINMUX:表示该引脚的默认引脚复用( Pin Muxing)配置无效或没有被设置。通常, Pin Muxing 用于设置一个引脚的功能,例如作为输入、输出、或者特定功能(如 UART、 SPI 等)的引脚。BIT_OFFSET0:这个字段可能是指定该引脚的位偏移量。位偏移用于指示该引脚在寄存器或内存中的位置,通常用于位掩码操作。MUX_ALT0:表示引脚复用的选择。 MUX_ALT0 指该引脚被配置为某个特定的备用功能。&pconf_input_en_1v8:这个是一个引用,指向在设备树中定义的另一个节点 pconf-input-en-1v8 ,它表示此引脚的电源配置 1.8V 输入启用。
其中 pinmux-func 中 pconf_input_en_1v8 节点定义了电源配置与驱动能力:
input-enable:这个属性表示启用了输入功能,即该引脚将作为输入引脚工作power-source= <HORIZON_IO_PAD_VOLTAGE_1V8>:指定该引脚的电源电压为 1.8V,表明该引脚需要一个 1.8V 的电源电压来正常工作。drive-strength= <3>:表示驱动强度的设置。驱动强度指的是引脚在驱动信号时能够提供的电流,其中高低电平输出电流对应驱动级如下表:
IOL Low Level Output Current @VOL (max) = 0.125*VDDIO
| DS (Drive Strength) | Typical Current | Unit |
|---|---|---|
| 0b0000 | 3.8 | mA |
| 0b0001 | 5.7 | mA |
| 0b0010 | 7.5 | mA |
| 0b0011 | 9.4 | mA |
| 0b0100 | 11.3 | mA |
| 0b0101 | 13.2 | mA |
| 0b0110 | 15.0 | mA |
| 0b0111 | 16.9 | mA |
| 0b1000 | 18.8 | mA |
| 0b1001 | 20.7 | mA |
| 0b1010 | 22.6 | mA |
| 0b1011 | 24.4 | mA |
| 0b1100 | 26.3 | mA |
| 0b1101 | 28.2 | mA |
| 0b1110 | 30.0 | mA |
| 0b1111 | 31.9 | mA |
IOH High Level Output Current @VOH (min) = 0.75*VDDIO
| DS (Drive Strength) | Typical Current | Unit |
|---|---|---|
| 0b0000 | 5.3 | mA |
| 0b0001 | 7.9 | mA |
| 0b0010 | 10.6 | mA |
| 0b0011 | 13.2 | mA |
| 0b0100 | 15.8 | mA |
| 0b0101 | 18.5 | mA |
| 0b0110 | 21.1 | mA |
| 0b0111 | 23.7 | mA |
| 0b1000 | 26.3 | mA |
| 0b1001 | 29.0 | mA |
| 0b1010 | 31.6 | mA |
| 0b1011 | 34.2 | mA |
| 0b1100 | 36.9 | mA |
| 0b1101 | 39.5 | mA |
| 0b1110 | 42.1 | mA |
| 0b1111 | 44.7 | mA |
IO-Domain 功能原理
设备树中的 GPIO 复用配置与 IO-DOMAIN 都需要通过 pinctrl 子系统来完成,在 Pinctrl_select_state 中 使用 pinconf_apply_setting 来完成电气属性的配置, 具体内核调用过程如图:

IO-Domain 工作方式
在驱动的实现中, IO Domain 的流程可以概括为以下几个步骤
1. 引脚配置(Pin Configuration)
通过硬件原理图编写设备树,驱动程序能够读取引脚配置。每个引脚都有一组与之相关的配置参数,包括复用功能(如 GPIO、 UART、 SPI 等)、电压配置(如 1.8V、 3.3V)以及其他电气特性。
horizon,pins = < AON_GPIO0_PIN0 INVALID_PINMUX BIT_OFFSET0 MUX_ALT0 &pconf_input_en_1v8 >;
上述设备树配置指定了 AON_GPIO0_PIN0 引脚的复用方式为 MUX_ALT0 ( GPIO 功能),并且指定了该引脚的电压为 1.8V(通过 &pconf_input_en_1v8 )。
2. IO Domain 的初始化
在驱动中, horizon_pinctrl_probe 函数会读取设备树的配置,并将相关的引脚和硬件资源进行初始化。此时,驱动会为每个引脚分配资源、配置寄存器以及设置相应的电气参数。
ret = horizon_pinctrl_parse_gpio_bank(pdev, ipctl);
3. 电源管理和电气设置
驱动程序通过对 IO Domain 控制寄存器的操作,管理引脚的电气特性(例如电压和电流)。 horizon_pin_power_source 函数会根据传入的标志位设置相应的电压源:
if (flags == HORIZON_IO_PAD_VOLTAGE_IP_CTRL) {
val |= MS_BIT_CTRL;
}
4. 引脚方向控制(Input/Output Direction Control)
在配置完引脚的电气特性后,驱动程序还会根据需要设置引脚的输入或输出方向。 horizon_gpio_set_direction 用于控制引脚的工作模式:
ret = horizon_gpio_set_direction(pctldev, pin, true, arg);
5. 引脚多路复用(Pin Multiplexing)
通过设备树和驱动的配置,系统能够将一个引脚分配给不同的外设功能。多路复用配置会根据需求切换引脚的功能。例如,某个引脚可能同时支持 GPIO 和 UART 功能,通过设置 MUX_ALT 复用寄存器来进行切换。
pinmux_enable_setting(const struct pinctrl_setting *setting)
4.3.6.4. 驱动代码
Kernel Space
代码位置
drivers/pinctrl/hobot/ # pinctrl 驱动代码源文件所在文件夹
include/linux/platform_data/pinctrl-single.h # pinctrl 驱动代码头文件
IO-Domain 的 DTS
Pinctrl 功能相关定义位于 BSP 源码包的 kernel 文件夹下的 arch/arm64/boot/dts/hobot/pinmux-func.dtsi 文件内。
由于 IO-Domain 在 pinctrl-single 的框架下实现,因此其 DTS 和 pinctrl 的类似,在 IO-Domain 的 DTS 里已经列出了所有模块 1.8V 和 3.3V 的配置组,一般不需要修改,在具体开发时根据实际情况选择使用即可。
pconf_bias_disabled_ds2_1v8: pconf-bias-disabled-ds2-1v8 {
bias-disable;
power-source = <HORIZON_IO_PAD_VOLTAGE_1V8>;
drive-strength = <2>;
};
pinctrl_enet: enetgrp {
horizon,pins = <
HSIO_ENET_MDC HSIO_PINMUX_1 BIT_OFFSET30 MUX_ALT0 &pconf_bias_disabled_ds2_1v8
HSIO_ENET_MDIO HSIO_PINMUX_1 BIT_OFFSET28 MUX_ALT0 &pconf_bias_disabled_ds2_1v8
HSIO_ENET_TXD_0 HSIO_PINMUX_1 BIT_OFFSET26 MUX_ALT0 &pconf_bias_disabled_ds2_1v8
HSIO_ENET_TXD_1 HSIO_PINMUX_1 BIT_OFFSET24 MUX_ALT0 &pconf_bias_disabled_ds2_1v8
HSIO_ENET_TXD_2 HSIO_PINMUX_1 BIT_OFFSET22 MUX_ALT0 &pconf_bias_disabled_ds2_1v8
HSIO_ENET_TXD_3 HSIO_PINMUX_1 BIT_OFFSET20 MUX_ALT0 &pconf_bias_disabled_ds2_1v8
HSIO_ENET_TXEN HSIO_PINMUX_1 BIT_OFFSET18 MUX_ALT0 &pconf_bias_disabled_ds2_1v8
HSIO_ENET_TX_CLK HSIO_PINMUX_1 BIT_OFFSET16 MUX_ALT0 &pconf_bias_disabled_ds2_1v8
HSIO_ENET_RX_CLK HSIO_PINMUX_1 BIT_OFFSET14 MUX_ALT0 &pconf_bias_disabled_ds2_1v8
HSIO_ENET_RXD_0 HSIO_PINMUX_1 BIT_OFFSET12 MUX_ALT0 &pconf_bias_disabled_ds2_1v8
HSIO_ENET_RXD_1 HSIO_PINMUX_1 BIT_OFFSET10 MUX_ALT0 &pconf_bias_disabled_ds2_1v8
HSIO_ENET_RXD_2 HSIO_PINMUX_1 BIT_OFFSET8 MUX_ALT0 &pconf_bias_disabled_ds2_1v8
HSIO_ENET_RXD_3 HSIO_PINMUX_1 BIT_OFFSET6 MUX_ALT0 &pconf_bias_disabled_ds2_1v8
HSIO_ENET_RXDV HSIO_PINMUX_1 BIT_OFFSET4 MUX_ALT0 &pconf_bias_disabled_ds2_1v8
HSIO_ENET_PHY_CLK HSIO_PINMUX_1 BIT_OFFSET2 MUX_ALT0 &pconf_bias_disabled_ds2_1v8
>;
};
pinctrl_enet: enetgrp
pinctrl_enet 是一个引脚控制配置组, enetgrp 是该配置组的名称。这个组主要用于定义与以太网( Ethernet)相关的引脚设置。
horizon,pins = < … >:
引脚名称:(例如 HSIO_ENET_MDC、 HSIO_ENET_MDIO、 HSIO_ENET_TXD_0 等)。
复用组:(例如 HSIO_PINMUX_1 )表示引脚复用的硬件资源组,决定该引脚的具体用途。
位偏移:(例如 BIT_OFFSET30 )引脚控制寄存器的偏移值,指定引脚在寄存器中的位置。
复用模式:(如 MUX_ALT0 )指引脚的复用模式,例如使用 MUX_ALT0 来表示该引脚的特定功能。
配置参数引用:(例如 &pconf_bias_disabled_ds2_1v8 ) 引脚的电气特性配置,通过引用其他的配置结构来设置,比如禁用偏置电流、设定驱动能力等。
这里主要详细介绍电压域在设备树中的解析,pconf_bias_disabled_ds2_1v8) 详细信息如下:
pconf_bias_disabled_ds2_1v8: pconf-bias-disabled-ds2-1v8 {
bias-disable;
power-source = <HORIZON_IO_PAD_VOLTAGE_1V8>;
drive-strength = <2>;
};
pconf_bias_disabled_ds2_1v8:这是设备树中的一个节点名称,用于定义与某些硬件引脚相关的电源配置和驱动特性。这个名称可能是一个通用配置,用于多个引脚或设备模块的电气特性设置。
bias-disable:此属性表示禁用该引脚的电气偏置( bias)。在许多硬件设计中,某些引脚可能需要使用偏置(例如上拉电阻或下拉电阻),用于确保引脚处于稳定状态。禁用偏置意味着该引脚不会使用上拉或下拉电阻,而是保持无偏置的状态,通常用于需要高阻抗或浮空状态的情况。
power-source:此属性指定了该引脚的电源电压。 HORIZON_IO_PAD_VOLTAGE_1V8 表示该引脚的电源电压为 1.8V,
drive-strength:此属性定义了引脚的驱动强度,表示引脚能够提供的电流大小或驱动能力。
备注: 电气属性的具体配置应参考 《X5 PIN SW Reg.xlsx》 文档
| RW | [30] | hsio_enet_rxd_3_pu | 0x0 | hsio_enet_rxd_3 pull up enable: 1: pull up enable; 0: pull up disable; |
|---|---|---|---|---|
| RW | [29] | hsio_enet_rxd_3_pd | 0x0 | hsio_enet_rxd_3 pull down enable: 1: pull down enable; 0: pull down disable; |
| RW | [28:25] | hsio_enet_rxd_3_ds | 0x8 | hsio_enet_rxd_3 driving selector; |
| RW | [24] | hsio_enet_rxd_3_st | 0x0 | hsio_enet_rxd_3; Schmitt trigger enable. 1: enables Schmitt trigger input function; 0: no Schmitt trigger input function; |
该手册提供了不同 GPIO 的硬件寄存器位配置的详细信息。每一行代表寄存器中的一个特定位或一组位,并包含以下信息:
访问类型 (RW/RSV):表示该位是可读写的( Read/Write)。
位宽或位范围 [ 起始 : 结束 ]: 指明了该配置项在寄存器中的具体位置。例如,[6] 表示第 6 位,[4:1] 表示从第 4 位到第 1 位的一组位。
配置项名称 : 描述了该位或位组的功能,如 hsio_enet_rx_clk_pu 表示以太网接收时钟线上拉使能。
默认值 (Default Value): 显示了在寄存器复位或初始化时该位或位组的值
提供了关于该位或位组功能的详细描述,包括它们如何影响硬件的行为,例如,上拉或下拉使能,施密特触发,电流驱动能力等。
驱动调用示例代码
和 pinctrl 调用方法一致,驱动先通过 pinctrl-names 查找对应的 pinctrl state,然后再切换到对应的 state,具体调用流程可看 功能原理 章节。
static int hobot_pinctrl_probe(struct platform_device *pdev)
{
...
g_xxx_dev->pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(g_xxx_dev->pinctrl)) {
dev_warn(&pdev->dev, "pinctrl get none\n");
g_xxx_dev->pins_voltage = NULL;
}
...
/* 按照 pinctrl-names lookup state */
g_xxx_dev->pins_voltage = pinctrl_lookup_state(g_xxx_dev->pinctrl,
"xxx_voltage_func");
if (IS_ERR(g_xxx_dev->pins_voltage)) {
dev_info(&pdev->dev, "xxx_voltage_func get error %ld\n",
PTR_ERR(g_xxx_dev->pins_voltage));
g_xxx_dev->pins_voltage = NULL;
}
...
/* select state */
if (g_xxx_dev->pins_voltage) {
ret = pinctrl_select_state(g_xxx_dev->pinctrl, g_xxx_dev->pins_voltage);
if (ret) {
dev_info(&pdev->dev, "xxx_voltage_func set error %d\n", ret);
}
}
...
}
4.3.6.5. 功能使用
User Space
根据 《X5 PIN SW Reg.xlsx》 文档,举例将 HSIO_ENET_RX_CLK(即 HSIO_GPIO0_PIN08 )配置为输出 GPIO 的步骤
1. 设置 HSIO_GPIO0_PIN08 为输出模式:
读取寄存器 GPIO_SWPORTA_DDR(地址 0x35060004 )的值
将寄存器 GPIO_SWPORTA_DDR 的 bit8 设置为 1 ,以将引脚配置为输出模式。
devmem 0x35060004 # 读取寄存器 0x35060004
devmem 0x35060004 32 0xxxxxxxxx # 写寄存器 0x35060004 ,将 bit8 设置为 0x1
2. 设置 HSIO_ENET_RX_CLK 输出电平:
读取寄存器 GPIO_SWPORTA_DR(地址 0x35060000 )的值。
将寄存器 GPIO_SWPORTA_DR 的 bit8 设置为 1 ,将输出电平设置为 1 ;或者将其设置为 0 ,将输出电平设置为 0 。
devmem 0x35060000 # 读取寄存器 0x35060000
devmem 0x35060000 32 0xxxxxxxxx # 写寄存器 0x35060000 ,将 bit8 设置为所需电平( 0 或 1 )
3. 设置 HSIO_ENET_RX_CLK 输出电平:
读取寄存器 hsio_pin_ctrl_1 (地址 0x35050018 )的值。
将寄存器 hsio_pin_ctrl_1 的 bit[4:1] 设置为 0x2 ,以设置驱动强度为 7.5mA/10.6mA(具体驱动强度与硬件文档中的映射有关)。
devmem 0x35050018 # 读取寄存器 0x35050018
devmem 0x35050018 32 0xxxxxxxxx # 写寄存器 0x35050018 ,将 bit[4:1] 设置为 0x2
4. 设置引脚为 GPIO 功能模式::
读取寄存器 hsio_pinmux_ctl_1 (地址 0x3505005c)的值。
将寄存器 hsio_pinmux_ctl_1 的 bit[15:14] 设置为 0x2 ,以将引脚设置为 GPIO 功能模式。
devmem 0x3505005c # 读取寄存器 0x3505005c
devmem 0x3505005c 32 0xxxxxxxxx # 写寄存器 0x3505005c,将 bit[15:14] 设置为 0x2
Uboot Space
Uboot 内已实现了 Pinctrl 驱动,使用方法与内核一致,在设备树内进行配置和使用,这里主要示例如何在 Uboot 下修改设备树和使用命令查看 IO-Domain 寄存器。
代码位置
/uboot/arch/arm/dts/pinmux-func.dtsi # uboot 设备树 pinctrl 复用关系位置
/uboot/arch/arm/dts/x5.dtsi # uboot 设备树引用节点位置
IO-Domain 的 DTS
配置选项为自定义的“ power-source”宏,如下所示。
...
pconf_drv_pu_3v3_max: pconf-dev-pu-max-high {
bias-pull-up;
power-source = <HORIZON_IO_PAD_VOLTAGE_3V3>;
drive-strength = <15>;
};
pconf_drv_pu_1v8_max: pconf-dev-pu-max-low {
bias-pull-up;
power-source = <HORIZON_IO_PAD_VOLTAGE_1V8>;
drive-strength = <15>;
};
...
pinctrl_uart7: uart7grp {
horizon,pins = <
LSIO_UART7_RX LSIO_PINMUX_3 BIT_OFFSET4 MUX_ALT0 &pconf_drv_pu_1v8_max
LSIO_UART7_TX LSIO_PINMUX_3 BIT_OFFSET6 MUX_ALT0 &pconf_drv_pu_1v8_max
LSIO_UART7_CTS LSIO_PINMUX_3 BIT_OFFSET8 MUX_ALT0 &pconf_drv_pu_1v8_max
LSIO_UART7_RTS LSIO_PINMUX_3 BIT_OFFSET10 MUX_ALT0 &pconf_drv_pu_1v8_max
>;
};
...
驱动调用时 DTS 配置
首先,在 DTS 内定义当前硬件的电压域配置,以配置 i2c 为 1.8V 为例:
pinctrl_i2c1: i2c1grp {
horizon,pins = <
LSIO_I2C1_SCL LSIO_PINMUX_2 BIT_OFFSET20 MUX_ALT0 &pconf_drv_pu_1v8_max
LSIO_I2C1_SDA LSIO_PINMUX_2 BIT_OFFSET22 MUX_ALT0 &pconf_drv_pu_1v8_max
>;
};
UBOOT 中设备树与内核中设备树基本一致, pinctrl 是用于配置引脚复用和电气特性的机制。在设备树中, pinctrl 节点指定了与特定硬件外设相关的引脚配置。在这里, pinctrl_i2c1 节点定义了与 I2C1 外设相关的引脚配置。
horizon,pins:这个属性定义了与 I2C1 相关的引脚配置。这里的每个项都是一个特定引脚的设置。
LSIO_I2C1_SCL:代表 I2C1 的时钟引脚( SCL)。
LSIO_I2C1_SDA:代表 I2C1 的数据引脚( SDA)。
LSIO_PINMUX_2:指定了一个特定的引脚复用组,用来配置这些引脚的功能。
BIT_OFFSET20 和 BIT_OFFSET22:这些指定了具体引脚在寄存器中的位置偏移。
MUX_ALT0:设置引脚的复用功能为 I2C,即将引脚配置为 I2C 通信。
&pconf_drv_pu_1v8_max:引用外部的配置节点,通常定义了与引脚相关的电气特性,比如上拉电阻和驱动电压。
和 pinctrl 的使用方法类似,驱动在自己的 DTS 中引用需要配置的 IO-Domain ,以 i2c1 为例,配置如下:
i2c1: i2c@340c0000 {
compatible = "snps,designware-i2c";
status = "okay";
reg = <0x340c0000 0x10000>;
#address-cells = <1>;
#size-cells = <0>;
#clock-names = "i2c-clk";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
};
这个节点描述了硬件外设 I2C1 本身,提供了外设的基地址、配置和状态信息 :
i2c@340c0000:节点的名称,标识了 I2C1 外设在系统中的位置。地址 0x340c0000 是该外设在内存中的起始地址。
compatible = “snps,designware-i2c”:这个属性指定了与该外设兼容的驱动程序。 snps,designware-i2c 是一个常见的 I2C 控制器 IP 核的兼容标识,表示这个 I2C 外设使用 Synopsys 的设计。
status = “okay”:启用该外设的状态。”okay” 表示启用该 I2C 外设, U-Boot 会为此外设加载相应的驱动程序。
reg = <0x340c0000 0x10000>:指定该外设的物理地址范围。 0x340c0000 是外设的起始地址, 0x10000 是外设的地址范围( 16KB)。
#address-cells = <1> 和 #size-cells = <0>:这两个属性定义了地址和大小单元的数量。#address-cells = <1> 表示外设的地址由一个单元( 32 位)表示,#size-cells = <0> 表示没有额外的大小信息。
#clock-names = “i2c-clk”:指定与该外设相关的时钟名称,通常用来引用系统时钟。
pinctrl-names = “default”:指定使用默认的引脚控制配置。
pinctrl-0 = <&pinctrl_i2c1>:将前面定义的 pinctrl_i2c1 引脚配置应用于此 I2C 外设,确保该外设的引脚配置为 I2C1 引脚。
命令查询与使用方式
进入 UBOOT 时输入 I2C BUS 命令来查询 uboot 设备树中添加修改的 I2C1 配置是否生效。
Hobot>i2c bus
Bus 0: i2c@340d0000
Bus 1: i2c@340c0000
可以发现在 Uboot 中除了默认的 I2C2 总线外,额外探测到 I2C1 总线,地址为 0X340C 0000 ,说明 Uboot 中设备树的配置已生效,继续输入 MD 命令来查询电压域的寄存器 。
Hobot>md 0x34180080 1
34180080: 50555555
通过查询 Pin_Mux_List 手册, I2C1 的属性如下,通过 MD 输出结果对应电压域的偏移位 bit = 1 ,电压域为 1.8V ,与 Uboot 中设备树配置的电压域一致。
| PinName | Default IO Domain | IO Domain Reg | Reg Offset | Reg Value |
|---|---|---|---|---|
| LSIO_I2C1_SCL | 3.3v | 0x34180080 | 21:20 | 1: 1.8V |
| LSIO_I2C1_SDA | 3.3v | 0x34180080 | 23:22 | 0: 3.3V |
注意:
以上 I2C 电源域修改仅为示例,实际电压域修改需要和实际硬件需求来修改对应的 dts 配置
4.3.6.6. FAQ
1、为什么 pinmux-func.dtsi 中 pinctrl_sd 和 pinctrl_sdio 中的电压域使用的配置为 pconf_sd_sdio_pu_ds3_ipctrl , 没有明确指明电压域的具体电压
pconf_sd_sdio_pu_ds3_ipctrl: pconf-sd-sdio-pu-ds3-ipctrl {
bias-pull-up;
drive-strength = <3>;
power-source = <HORIZON_IO_PAD_VOLTAGE_IP_CTRL>;
};
答:在 pinmux-func.dtsi 中,只有 pinctrl_sd 和 pinctrl_sdio 节点使用了相关的电压域配置,HORIZON_IO_PAD_VOLTAGE_IP_CTRL 代表此模块的电压域由硬件中配置引脚的电压而改变,通常主控在启动时首先以 3.3V 电压与 SDIO 设备进行通信, SDIO 设备会通过主控发出的命令确认其支持的电压,并决定是否切换到 1.8V 电压。
2、SDIO 设备的电压域是如何进行切换的
&sdio_0 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sd &hsio_gpio0_26 &hsio_gpio1_1>;
power-gpios = <&hs_gpio0_porta 26 GPIO_ACTIVE_HIGH>;
/* Drive voltage gpio to 0 to switch to 1.8V */
voltage-gpios = <&hs_gpio1_porta 1 GPIO_ACTIVE_LOW>;
};

答:在 硬件原理图中 HSIO_SD_XX 引脚相关的电压域由 VDDIO_SD 提供,那么如何实现 3v3 和 1v8 电压间的切换呢,可以发现在设备树中定义了 power-gpios 和 voltage-gpios ,其配置中的引脚都被复用为 GPIO 功能,当此设备数的节点被内核 SDIO 控制器解析时,hsio_gpio0_26 用来控制 SD 卡 VDD 的电压开关,当引脚为高时开关打开 3.3V ,hsio_gpio1_1 默认状态的电压域为 3.3v,当引脚被拉低时硬件设计切换为 1.8v。这里列出手册中部分相关参数分别为 引脚名 ,默认电压 ,电源域偏移位 ,当第一位 bit 为 1 则代表 1.8v,为 0 则代表 3.3v。
| 引脚名 | 电压域默认值 | 偏移位 0:1.8v 1:3.3v |
|---|---|---|
| HSIO_SD_SDCLK | 3.3V | 1 |
| HSIO_SD_CMD | 3.3V | 1 |
| HSIO_SD_CDN | 3.3V | 1 |
| HSIO_SD_DATA_0 | 3.3V | 1 |
| HSIO_SD_DATA_1 | 3.3V | 1 |
| HSIO_SD_DATA_2 | 3.3V | 1 |
| HSIO_SD_DATA_3 | 3.3V | 1 |
| HSIO_SDIO_WP | 3.3V | 1 |
| HSIO_SDIO_SDCLK | 3.3V | 1 |
| HSIO_SDIO_CMD | 3.3V | 1 |
| HSIO_SDIO_CDN | 3.3V | 1 |
| HSIO_SDIO_DATA_0 | 3.3V | 1 |
| HSIO_SDIO_DATA_1 | 3.3V | 1 |
| HSIO_SDIO_DATA_2 | 3.3V | 1 |
| HSIO_SDIO_DATA_3 | 3.3V | 1 |
在内核驱动中 horizon_pin_power_source 添加打印,内核日志如下
[ 2.236243] horizon-hsio-pinctrl 35050000.hsio_iomuxc: Read value from register: 0xd
[ 2.248841] horizon-hsio-pinctrl 35050000.hsio_iomuxc: ms_bits_offset: 0x2
[ 2.261723] horizon-hsio-pinctrl 35050000.hsio_iomuxc: flags: 0x2
[ 2.277303] horizon-hsio-pinctrl 35050000.hsio_iomuxc: Read value from register: 0xf
[ 3.915439] horizon-hsio-pinctrl 35050000.hsio_iomuxc: Modified value for register: 0xf
[ 3.930253] horizon-hsio-pinctrl 35050000.hsio_iomuxc: ms_bits_offset: 0x2
[ 3.930258] horizon-hsio-pinctrl 35050000.hsio_iomuxc: flags: 0x2
[ 3.930262] horizon-hsio-pinctrl 35050000.hsio_iomuxc: Read value from register: 0xf
Read value from register: 代表读当前电压域地址的值。
ms_bits_offset:代表电压域地址的偏移。
flags:代表设备树中电压域使用的是 power-source = <HORIZON_IO_PAD_VOLTAGE_IP_CTRL>。
HORIZON_IO_PAD_VOLTAGE_3V3 : 0
HORIZON_IO_PAD_VOLTAGE_1V8 : 1
HORIZON_IO_PAD_CTRL_VOLTAGE_1V8 : 3
HORIZON_IO_PAD_CTRL_VOLTAGE_3V3 : 4
Modified value for register: 代表位操作后电压域地址的值。
通过 dmesg 打印信息可以发现 HSIO_SD_XX 引脚的电压域由 3.3v 切换至了 1.8v。