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后,再走关机流程看关机电流。

相关推荐
ltl11 分钟前
向量库与图 RAG:HNSW、DiskANN 到 GraphRAG
linux
学代码的CJY1 小时前
Linux 库制作与原理:静态库、动态库、ELF 与动态链接完全指南
linux·运维·服务器
沸速存储2 小时前
CPU 和 GPU 核心差别在哪?为什么 AI 训练离不开 GPU
服务器·人工智能·科技·嵌入式硬件·电脑
呱呱巨基3 小时前
Linux 查找命令
linux·笔记·学习·查找命令
basketball6163 小时前
软考中级网络工程师 第4章 无线通信网 备考总结
linux·服务器·网络·网络工程师·软考
我不会JAVA!3 小时前
【无标题】
嵌入式硬件·h.264
芯岭技术郦3 小时前
OM6625A芯片 Timer 定时器计数模式使用说明
stm32·单片机·嵌入式硬件
好评1243 小时前
【Linux】进程信号
linux·运维·服务器
zhangrelay4 小时前
ROS 2 Lyrical 第4章 URDF机器人建模与Gazebo Garden仿真
linux·笔记·学习·ubuntu·机器人·ros2
wuminyu4 小时前
JVM利用io_uring优化堆外内存性能原理剖析
java·linux·c语言·jvm·c++