RK3562 +RK817的dts布尔属性解析(uboot基础知识)

关键函数: val = dev_read_bool(dev, "vccsys-shutdown-in-poweroff-mode");

因为rk提供了一个修复漏电的patch,如下:

复制代码
From 273c2528ca9a1db484f188533d446231d15dc49f Mon Sep 17 00:00:00 2001
From: shengfei Xu <xsf@rock-chips.com>
Date: Tue, 13 Dec 2022 07:00:30 +0000
Subject: [PATCH] pmic: rk8xx: control the vccsys on/off in PWR_OFF mode

whether the system voltage can be shutdown in PWR_OFF mode config from dts

Signed-off-by: shengfei Xu <xsf@rock-chips.com>
Change-Id: I806d7c78fd37758e2a8637203b640dec9fb9f839
---
 drivers/power/pmic/rk8xx.c | 23 +++++++++++++++++++++++
 include/power/rk8xx_pmic.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
index e361015337..abd42085c4 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -408,6 +408,9 @@ static int rk8xx_ofdata_to_platdata(struct udevice *dev)
 	val = dev_read_u32_default(dev, "not-save-power-en", 0);
 	rk8xx->not_save_power_en = val;
 
+	val = dev_read_bool(dev, "vccsys-shutdown-in-poweroff-mode");
+	rk8xx->sys_can_sd = val;
+
 	return 0;
 }
 
@@ -541,6 +544,26 @@ static int rk8xx_probe(struct udevice *dev)
 		lp_act_msk = RK8XX_LP_ACTION_MSK;
 		init_data = rk817_init_reg;
 		init_data_num = ARRAY_SIZE(rk817_init_reg);
+
+		/* whether the system voltage can be shutdown in PWR_off mode */
+		if (priv->sys_can_sd) {
+			ret = rk8xx_read(dev, RK817_PMIC_CHRG_TERM, &value, 1);
+			if (ret)
+				return ret;
+			value |= 0x80;
+			ret = rk8xx_write(dev, RK817_PMIC_CHRG_TERM, &value, 1);
+			if (ret)
+				return ret;
+		} else {
+			ret = rk8xx_read(dev, RK817_PMIC_CHRG_TERM, &value, 1);
+			if (ret)
+				return ret;
+			value &= 0x7f;
+			ret = rk8xx_write(dev, RK817_PMIC_CHRG_TERM, &value, 1);
+			if (ret)
+				return ret;
+		}
+
 		/* judge whether save the PMIC_POWER_EN register */
 		if (priv->not_save_power_en)
 			break;
diff --git a/include/power/rk8xx_pmic.h b/include/power/rk8xx_pmic.h
index aa51e887e4..84d1104dab 100644
--- a/include/power/rk8xx_pmic.h
+++ b/include/power/rk8xx_pmic.h
@@ -206,6 +206,7 @@ enum {
 #define RK817_ID_LSB	0xee
 #define RK8XX_ID_MSK	0xfff0
 
+#define RK817_PMIC_CHRG_TERM	0xe6
 #define RK817_PMIC_SYS_CFG1	0xf1
 #define RK817_PMIC_SYS_CFG3	0xf4
 #define RK817_GPIO_INT_CFG	0xfe
@@ -287,6 +288,7 @@ struct rk8xx_priv {
 	uint8_t sleep_pin;
 	uint8_t rst_fun;
 	int not_save_power_en;
+	int sys_can_sd;
 };
 
 int rk8xx_spl_configure_buck(struct udevice *pmic, int buck, int uvolt);
-- 
2.17.1

其中逻辑上:

if (priv->sys_can_sd) 这个逻辑判断是来自priv->sys_can_sd的属性,那么结合上面的

复制代码
+	val = dev_read_bool(dev, "vccsys-shutdown-in-poweroff-mode");
+	rk8xx->sys_can_sd = val;

就看起来很清晰易懂,这两行代码是一个设备驱动中读取设备树配置的常见操作:

1. dev_read_bool(dev, "vccsys-shutdown-in-poweroff-mode")

功能:
从设备树(Device Tree)中读取一个布尔属性值。

参数解析:

  • dev: 指向设备结构体的指针,通常代表一个硬件设备

  • "vccsys-shutdown-in-poweroff-mode": 设备树中的属性名

工作原理:

  1. 在设备树(.dts文件)中查找当前设备节点

  2. 查找该节点下名为 vccsys-shutdown-in-poweroff-mode 的属性

  3. 如果属性存在且为 true,返回 true

  4. 如果属性不存在或为 false,返回 false

设备树示例:

复制代码
&rk808 {
    vccsys-shutdown-in-poweroff-mode = <1>;  // 1表示true
    // 或者
    // vccsys-shutdown-in-poweroff-mode;
};

2. rk8xx->sys_can_sd = val

功能:

将读取到的布尔值存储到驱动数据结构中。

参数解析:

  • rk8xx: 指向设备私有数据结构的指针

  • sys_can_sd: 结构体成员,可能是 "system can shutdown" 的缩写

  • val: 从设备树读取的布尔值

整体功能

这两行代码组合起来的意思是:

  1. 从设备树配置中读取系统是否支持在关机模式下关闭VCCSYS电源

  2. 将这个配置保存到驱动的内部状态中,供后续的电源管理逻辑使用

实际应用场景

这在RK8xx系列电源管理芯片(PMIC)驱动中很常见,用于控制:

  • 系统关机时是否完全切断电源

  • 低功耗模式下的电源管理策略

  • 系统唤醒和休眠的电源控制

这样设计的好处是:

  1. 灵活性:通过设备树配置,同一个驱动可以适应不同的硬件设计

  2. 可移植性:不同板级配置只需修改设备树,无需修改驱动代码

  3. 运行时配置:系统可以根据配置决定最优的电源管理策略

实测验证;

复制代码
hzs@sr658:~/rk3562-optmv-idd1/u-boot$ git diff ./
diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
index 64c48f8a2d..06e67b692a 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -604,6 +604,12 @@ static int rk8xx_ofdata_to_platdata(struct udevice *dev)
        rk8xx->pwr_ctr[1] = dev_read_u32_default(dev, "pwrctrl2_output", -1);
        rk8xx->pwr_ctr[2] = dev_read_u32_default(dev, "pwrctrl3_output", -1);

+       //Add by rk for 11mA patch
+       val = dev_read_bool(dev, "vccsys-shutdown-in-poweroff-mode");
+       rk8xx->sys_can_sd = val;
+       printf("[%s] val = %d, rk8xx->sys_can_sd = %d \n", __func__, val, rk8xx->sys_can_sd);
+       //end by rk
+
        return 0;
 }

@@ -647,6 +653,7 @@ static int rk8xx_probe(struct udevice *dev)
        uint8_t on, off;
        uint8_t value;

+       printf("[%s] enter 2025-12-23 14:16 \n", __func__);
        /* read Chip variant */
        if (device_is_compatible(dev, "rockchip,rk817") ||
            device_is_compatible(dev, "rockchip,rk809")) {
@@ -757,7 +764,9 @@ static int rk8xx_probe(struct udevice *dev)
                init_data_num = ARRAY_SIZE(rk817_init_reg);

                /* whether the system voltage can be shutdown in PWR_off mode */
-               if (priv->sys_can_sd) {
+               //if (priv->sys_can_sd) {
+               if (1) {  //add by rk for 11mA BUG
+                       printf("[%s] RK817_ID = %x LINE = %d \n", __func__, RK817_ID, __LINE__);
                        ret = rk8xx_read(dev, RK817_PMIC_CHRG_TERM, &value, 1);
                        if (ret)
                                return ret;
hzs@sr658:~/rk3562-optmv-idd1/u-boot$

DTS部分的修改:

复制代码
rk817: pmic@20 {
		compatible = "rockchip,rk817";
		reg = <0x20>;
		interrupt-parent = <&gpio0>;
		interrupts = <3 IRQ_TYPE_LEVEL_LOW>;

		pinctrl-names = "default", "pmic-sleep",
			"pmic-power-off", "pmic-reset";
		pinctrl-0 = <&pmic_int>;
		pinctrl-1 = <&soc_slppin_slp>, <&rk817_slppin_slp>;
		pinctrl-2 = <&soc_slppin_gpio>, <&rk817_slppin_pwrdn>;
		pinctrl-3 = <&soc_slppin_gpio>, <&rk817_slppin_rst>;
		rockchip,system-power-controller;
		vccsys-shutdown-in-poweroff-mode = <1>;  // 1表示true
		wakeup-source;
		#clock-cells = <1>;
		clock-output-names = "rk808-clkout1", "rk808-clkout2";
		/* 1: rst regs (default in codes), 0: rst the pmic */
		pmic-reset-func = <0>;
		vcc1-supply = <&vcc_sys>;
		vcc2-supply = <&vcc_sys>;
		vcc3-supply = <&vcc_sys>;
		vcc4-supply = <&vcc_sys>;
		vcc5-supply = <&vcc_sys>;
		vcc6-supply = <&vcc_sys>;
		vcc7-supply = <&vcc_sys>;
		vcc8-supply = <&vcc_sys>;
		vcc9-supply = <&dcdc_boost>;
		pwrkey {
			status = "okay";
		};

那么编译烧录uboot和kernel,通过串口可以获取到:

尝试一下另外一个语法的修改也都是能正常获取:

注意:

复制代码
vccsys-shutdown-in-poweroff-mode = \<1\>; // 1表示true
复制代码
vccsys-shutdown-in-poweroff-mode = \<0\>; // 0也表示true,val获取回来的值就是为1

但如果dts移除相关属性,则获取回来的是为0:

补充一下RK817的寄存器操作:

先写

echo w 0xe6 0x42 > sys/rk8xx/rk8xx_dbg

再读

echo r 0xe6 > sys/rk8xx/rk8xx_dbg

读出来的值bit7为0后,再走关机流程看关机电流。

相关推荐
逐梦之程2 小时前
STM32的串口通讯--DMA接收和CPU接收不定长数据帧对比
stm32·单片机·嵌入式硬件
广州灵眸科技有限公司2 小时前
瑞芯微(EASY EAI)RV1126B 音频输入
linux·开发语言·网络·音视频
文弱书生6563 小时前
2-electronbot主控免驱工程结构
linux·单片机·嵌入式硬件
求知喻3 小时前
LCD真值表
单片机·嵌入式硬件
铜豌豆_Y4 小时前
【实用】GDB调试保姆级教程|常用操作|附笔记
linux·c语言·驱动开发·笔记·嵌入式
csg11074 小时前
高效驱动,灵活控制:深度解析RZ7899大电流DC双向马达驱动芯片及其创新应用
单片机·嵌入式硬件·物联网
m0_485614674 小时前
Linux--Docker网络管理
linux·docker·eureka
石像鬼₧魂石4 小时前
HexStrike AI 理想操作流程清单(完整功能版)
linux·人工智能·windows·学习·ubuntu
Xの哲學5 小时前
Linux UPnP技术深度解析: 从设计哲学到实现细节
linux·服务器·网络·算法·边缘计算