目录
[4,pmu kernel 驱动代码](#4,pmu kernel 驱动代码)
[1,power mode](#1,power mode)
[2,ddr self refresh](#2,ddr self refresh)
[3,power kernel 代码](#3,power kernel 代码)
一,PMIC电源管理方案
rk3288 的电源管理方案有多种,本文学习PMIC(ACT8846QM490+2*SYR82X)方案

二,PMU
1,Pmu总体说明
RK3288 PMU的核心功能包括多电压域支持和低功耗模式。 它支持4个电压域(VD_CORE、VD_LOGIC、VD_GPU、VD_PMU)和15个独立电源域,软件可按应用场景动态启停电源域以节省功耗;在低功耗模式下,PMU可自动控制特定电源域(如pd_A17_0、pd_scu、vd_core、pd_bus)的电源开关,并支持CORTEX-A17核心时钟门控、全局中断禁用、PLL电源开关、DDR自刷新及IO保留等功能,同时提供可配置计数器和多种唤醒源。
PMU的硬件架构由三个主要部分组成:
APB接口与寄存器
低功耗状态控制
电源开关控制
这些部分协同工作,通过寄存器配置(如PMU_PWRMODE_CON用于进入低功耗模式,PMU_PWRDN_CON用于电源域开关)实现电源管理。
在软件配置方面,PMU通过设备树(DTS)和寄存器操作实现。设备树中需定义PMIC的电源参数,例如设置DCDC或LDO的电压范围、工作模式及休眠状态;寄存器操作可通过I2C接口直接读写。功耗优化需注意时序和配置细节。 电源开关时序需遵循芯片电气参数(如电源域上电/掉电时间),软件应通过状态寄存器确认电源域状态而非依赖时序;优化时需避免关闭关键电源域(如pd_A17_0和pd_bus),并确保DDR操作(如自刷新)的代码不在DDR中执行。



2,Pmu的寄存器组
|------------------------|--------|----|------------|---------------------------|
| 名称 | 偏移 | 读写 | 复位后的默认值 | 功能说明 |
| PMU_WAKEUP_CFG0 | 0x0000 | W | 0x00000000 | 唤醒源使能,每一位代表一个唤醒源使能 |
| PMU_WAKEUP_CFG1 | 0x0004 | W | 0x00000000 | 唤醒源使能,每一位代表一个唤醒源使能 |
| PMU_PWRDN_CON | 0x0008 | W | 0x00000000 | 电源门控配置寄存器 |
| PMU_PWRDN_ST | 0x000c | W | 0x00000000 | 电源门控状态寄存器 |
| PMU_IDLE_REQ | 0x0010 | W | 0x00000000 | 空闲请求控制寄存器 |
| PMU_IDLE_ST | 0x0014 | W | 0x00000000 | 空闲状态寄存器,高16位响应状态,低16位空闲状态 |
| PMU_PWRMODE_CON | 0x0018 | W | 0x00000000 | 不同电源工作方式下配置寄存器 |
| PMU_PWR_STATE | 0x001c | W | 0x00000000 | 低功耗模式状态下配置 |
| PMU_OSC_CNT | 0x0020 | W | 0x00005dc0 | |
| PMU_PLL_CNT | 0x0024 | W | 0x10004000 | |
| PMU_STABL_CNT | 0x0028 | W | 0x00005dc0 | |
| PMU_DDR0IO_PWRON_CNT | 0x002c | W | 0x00005dc0 | |
| PMU_DDR1IO_PWRON_CNT | 0x0030 | W | 0x00005dc0 | |
| PMU_CORE_PWRDWN_CNT | 0x0034 | W | 0x00005dc0 | |
| PMU_CORE_PWRUP_CNT | 0x0038 | W | 0x00005dc0 | |
| PMU_GPU_PWRDWN_CNT | 0x003c | W | 0x00005dc0 | |
| PMU_GPU_PWRUP_CNT | 0x0040 | W | 0x00005dc0 | |
| PMU_WAKEUP_RST_CLR_CNT | 0x0044 | W | 0x00005dc0 | |
| PMU_SFT_CON | 0x0048 | W | 0x00000000 | 正常模式下的软件控制 |
| PMU_DDR_SREF_ST | 0x004c | W | 0x00000000 | DDR自刷新状态 |
| PMU_INT_CON | 0x0050 | W | 0x00000000 | 中断配置寄存器 |
| PMU_INT_ST | 0x0054 | W | 0x00000000 | 中断状态寄存器 |
| PMU_BOOT_ADDR_SEL | 0x0058 | W | 0x00005dc0 | 从电源模式唤醒时的启动地址选择 |
| PMU_GRF_CON | 0x005c | W | 0x00000008 | |
| PMU_PWRMODE_CON1 | 0x0090 | W | 0x00000000 | 在低功耗模式下发出闲置请求 |
uboot打印寄存器

PMU_PWR_STATE配置成了0x80000001 低功耗模式下这两个状态可以发生
L2MEM_PWRUP state happened|NORMAL state happened
PMU_DDR_SREF_ST配置成了0x0000000f ddr子刷新全打开
ff730060到ff73008c是uart的配置,uart里面有介绍,这里不再展开
3,低功耗模式
PMU 可通过设置PMU_PWRMODE_CON寄存器的bit[0]进入低功耗模式。完成寄存器设置后, PMU 将自动进入低功耗模式。在此模式下,pmu将自动控制指定电源域的开关状态,向该电源域发送空闲请求,并关闭或启动PLL等。上述功能均可通过配置对应寄存器实现。
低功耗模式包含三个步骤: l
进入低功耗模式,该步骤包含若干子步骤,每个子步骤可通过设置对应寄存器来启用或禁用。 等待唤醒,可通过设置 PMU_WAKEUP_CFG0 /1寄存器选择唤醒源。 l
退出低功耗模式,具体执行的子步骤取决于是否在进入低功耗步骤时已执行。

4,pmu kernel 驱动代码
static const struct platform_suspend_ops rk3288_suspend_ops = {
.enter = rk3288_suspend_enter,
.valid = suspend_valid_only_mem,
.prepare = rk3288_suspend_prepare,
.finish = rk3288_suspend_finish,
};
static const struct rockchip_pm_data rk3288_pm_data __initconst = {
.ops = &rk3288_suspend_ops,
.init = rk3288_suspend_init,
};
static int rk3288_suspend_enter(suspend_state_t state)
{
local_fiq_disable();
rk3288_slp_mode_set(ROCKCHIP_ARM_OFF_LOGIC_NORMAL);
cpu_suspend(0, rockchip_lpmode_enter);
rk3288_slp_mode_set_resume();
local_fiq_enable();
return 0;
}
rk3288_slp_mode_set
读写PMU寄存器
rk3288_slp_mode_set_resume
读写PMU寄存器
三,POWER
1,power mode
RK3288支持以下5种推荐的电源模式:
正常模式
In this mode, you can power off/on or enable/disable the following power domain to save power: PD_PERI/PD_VIO/PD_VIDEO/PD_HEVC/PD_GPU
空闲模式
This mode is used when the core do not have load for a shot while such as waiting for interrupt and the software want to save power by gating Cortex-A17 source clock.
In idle mode, core1/2/3 of Cortex-A17 should be either power off or in WFI/WFE state. The core0 of A17 should be in WFI/WFE state. The configurations of core clock source gating and disable global interrupt are presented. The Cortex-A17 can waked up by an interrupt
深度空闲模式
Deep idle mode is used in the scenario of audio player. In deep idle mode, powering off Cortex-A17 cores or VD_CORE voltage domain is operational, and others are same as normal mode.
In deep idle mode, you can set ddr enter the self-refresh, and power off DDRIO and enable DDR retention function in this mode, but it will takes a longer time for the recovery of DDR IO
睡眠模式
The sleep mode can power off all power domains except PD_ALIVE. The VD_CORE is turned off externally, PD_BUS power off by hardware, and other domains power off by software.
In sleep mode the clock of PD_ALIVE can be switched from 24MHz to 32.768kHz optionally by hardware.
In sleep mode all PLLs power down mandatorily to save power by hardware.
In sleep mode OSC can be disabled optionally by hardware.
In sleep mode DDR self-refresh can be issued by hardware mandatorily.
In sleep mode DDR IO can power off and enter retention optionally by hardware
关机模式
The power off mode turns off the power of all VD_LOGIC externally.
In power off mode all PLLs power down mandatorily to save power by hardware.
In power off mode OSC disable request should be send by hardware.
In power off mode DDR self-refresh should be issued mandatorily by hardware.
In power off mode DDR IO can power off and enter retention optionally by hardware

2,ddr self refresh
工作场景:系统休眠/低功耗模式(如笔记本待机、手机锁屏)
触发机制:CKE置为低电平,内存芯片切断外部时钟,启动内部振荡器芯片自主管理刷新节奏(无需控制器干预)
功耗表现:功耗降至 1-10mW(仅为工作状态的0.1%)
温度升高时自动提高刷新频率(如LPDDR4在85°C时刷新周期缩至32ms)
当系统进入深度睡眠状态以节约电能消耗时,不会产生 DRAM 读写请求。此时使用控制器来维持 DRAM 状态已经没有必要。因此可以关闭控制器,并停止 DRAM 的外部时钟,使用自刷新状态来维持 DRAM 中的数据,以节约电能。
自刷新状态用于在系统异常掉电或者低功耗状态下,保持 DRAM 中的数据。 自刷新状态需要根据工作温度选择不同模式,发出足够密度的自刷新命令,以维持数据。
3,power kernel 代码
这个是控制PD_VIO PD_HEVC PD_VIDEO PD_GPU的状态,uboot因为不关心这几个 电源域,所以dts看不到,所以通过kernel的代码学习power功能
power: power-controller {
compatible = "rockchip,rk3288-power-controller";
#power-domain-cells = <1>;/**is a provider, is a power domain**/
#address-cells = <1>;
#size-cells = <0>;
assigned-clocks = <&cru SCLK_EDP_24M>;
assigned-clock-parents = <&xin24m>;
};
跟踪rockchip,rk3288-power-controller的probe代码
struct rockchip_domain_info {
const char *name;
int pwr_mask;
int status_mask;
int req_mask;
int idle_mask;
int ack_mask;
bool active_wakeup;
int pwr_w_mask;
int req_w_mask;
};
#define DOMAIN_RK3288(name, pwr, status, req, wakeup) \
DOMAIN(name, pwr, status, req, req, (req) << 16, wakeup)
static const struct rockchip_domain_info rk3288_pm_domains[] = {
RK3288_PD_VIO\] = DOMAIN_RK3288("vio", BIT(7), BIT(7), BIT(4), false), \[RK3288_PD_HEVC\] = DOMAIN_RK3288("hevc", BIT(14), BIT(10), BIT(9), false), \[RK3288_PD_VIDEO\] = DOMAIN_RK3288("video", BIT(8), BIT(8), BIT(3), false), \[RK3288_PD_GPU\] = DOMAIN_RK3288("gpu", BIT(9), BIT(9), BIT(2), false), }; static const struct rockchip_pmu_info rk3288_pmu = { .pwr_offset = 0x08,设置power on .status_offset = 0x0c,查询power状态,结合idle状态返回 .req_offset = 0x10,设置它实现切idle请求 .idle_offset = 0x14,读取它判断是否是idle .ack_offset = 0x14,设置完切idle,读取直到ack_offset为1表示切换成功 .core_pwrcnt_offset = 0x34,core power切换时延时使电源稳定 .gpu_pwrcnt_offset = 0x3c,gpu power切换时延时使电源稳定 .core_power_transition_time = 24, /\* 1us \*/延时时间 .gpu_power_transition_time = 24, /\* 1us \*/ .num_domains = ARRAY_SIZE(rk3288_pm_domains), .domain_info = rk3288_pm_domains, }; ## 四,Power相关命令 cat /sys/power/state //查看linux支持的休眠方式 freeze:冻结所有的进程,包括用户空间进程及内核线程,CPU进入IDLE态 standby:除了冻结I/O设备外,还会暂停系统。由于系统核心逻辑单元保持上电状态,操作的状态不会丢失,也会很容易恢复到之前的状态。 mem:运行状态数据存到内存,并关闭外设,进入等待模式,除了Memory需要进行自刷新来保持数据外,其他的所有设备都需要进入到低功耗状态,就是STR(Suspend to RAM)。 disk:这个操作会将运行时的context保存在Disk这种非易失的存储器中,然后进行掉电操作,就是STD(Suspend-to-Disk)。比如当按下电源键进行唤醒时,然后恢复,唤醒过程最慢。