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

相关推荐
十日十行7 小时前
Linux和window共享文件夹
linux
木心月转码ing15 小时前
WSL+Cpp开发环境配置
linux
崔小汤呀2 天前
最全的docker安装笔记,包含CentOS和Ubuntu
linux·后端
何中应2 天前
vi编辑器使用
linux·后端·操作系统
何中应2 天前
Linux进程无法被kill
linux·后端·操作系统
何中应2 天前
rm-rf /命令操作介绍
linux·后端·操作系统
何中应2 天前
Linux常用命令
linux·操作系统
葛立国2 天前
从 / 和 /dev 说起:Linux 文件系统与挂载点一文理清
linux
哇哈哈20212 天前
信号量和信号
linux·c++
不是二师兄的八戒2 天前
Linux服务器挂载OSS存储的完整实践指南
linux·运维·服务器