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 电源配置如下:

io-IO_DOMAIN_AON

设备树中 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_0aon_gpio_1两个 GPIO 引脚设置别名。它们分别描述两个物理 GPIO 引脚, aon_gpio_0 和 aon_gpio_1 ,对应是 AON_GPIO0_PIN0 和 AON_GPIO0_PIN1 。

  • `horizon,pins 是一个属性,定义每个引脚配置信息。

  • AON_GPIO0_PIN0AON_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_flow_chart

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_OFFSET20BIT_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_CTRL_DOMAIN HSIO_CTRL_DOMAIN

:在 硬件原理图中 HSIO_SD_XX 引脚相关电压由 VDDIO_SD 提供,那么如何实现 3v3 和 1v8 电压切换呢,可以发现设备树定义power-gpiosvoltage-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。