模块介绍
2 模块介绍
2.1 模块功能介绍
• 休眠唤醒指系统进入低功耗和退出低功耗模式,一般称之为 Standby。standby 分为 super standby 和 normal standby,区别是 cpu 是否掉电。
• 假关机是类似 standby 的一种低功耗模式。进入假关机,系统会先复位,再进入低功耗模式,等待唤醒源;检测到唤醒源,系统退出假关机,直接从低功耗模式复位重启。适用于 OTT 类产品代替常规的关机,实现红外/蓝牙开机功能。
2.2 相关术语介绍
表 2-1: 术语介绍
术语 | 说明 |
---|---|
Super standby | Vdd_cpu 掉电或 Core 掉电,dram 进入 self refresh 状态 |
Normal standby | CPUX WFI,dram 进入 self refresh 状态 |
Fake Poweroff | 假关机,类似 standby,主要区别是系统退出假关机会重启,而不是唤醒 |
SCP/CPUS | 全志平台辅助进行电源管理的协处理器 |
2.3 模块配置介绍
2.3.1 Device Tree 配置说明
设备树中存在的是该类芯片所有平台的模块配置,设备树文件的路径为:kernel/linux-4.9/arch/arm64(32 位平台为 arm)/boot/dts/sunxi/CHIP.dtsi(CHIP 为研发代号,如sun50iw10p1 等)。Standby 模块在 dtsi 中无用户可用配置。
2.3.2 board.dts 配置说明
board.dts 用于保存每一个板级平台的设备信息(如 demo 板,perf1 板等),里面的配置信息会覆盖上面的 Device Tree 默认配置信息。
• standby 参数配置
描述系统资源的相关信息。例如,“vdd-cpu = <0x00000006>;”,其中各个 bit 代表 PMU 的各路供电,则 vdd-cpu 使用 PMU的第二、三路供电。
“osc24m-on = <0x1>;”,表示系统休眠后 osc24m 是否关闭,0x0 表示关闭,0x1 表示不关闭。
standby_param: standby_param {
vdd-cpu = <0x00000006>;
vdd-sys = <0x00000008>;
vcc-pll = <0x00000100>;
osc24m-on = <0x1>;
...
};
注:由于 r528/v853 部分方案, 没有外挂 PMU,即硬件上不支持 vdd-sys/vdd-cpu 掉电,故R528/v853 board.dts 不需要该信息(standby_param)。
• 唤醒源配置
以 RTC 模块为例,RTC 驱动支持通过 “wakeup-source” 配置是否作为唤醒源;在 RTC 模块节点下添加 “wakeup-source” 属性,则可以设置为唤醒源。
• GPIO 为唤醒源配置
下面以 gpio-key 驱动为例, 演示一下 gpio 作为 wakeup-source 的代码编写:
keys {
compatible = "gpio-keys";
status = "okay";
wakeup {
wakeup-source; (1)
gpios = <&pio PH 9 6 2 2 1>; (2)
label = "wakeup";
linux,code = <KEY_WAKEUP>;
};
};
1.wakeup-source:device的wakeup source属性.需要设备驱动自己去解析该属性,如果有,则表示设备具有wakeup source功能.
2.gpios:配置gpio的mux,pull,drive,data等属性,如上的配置代表把PH9设置为6号功能(中断功能),下拉,驱动能力为2,data值为1.
• 假关机参数配置
描述系统关机的方式及假关机时需要用到的系统资源。如:
box_start_os0 {
compatible = "allwinner,box_start_os";
start_type = <0x1>;
irkey_used = <0x0>;
pmukey_used = <0x0>;
pmukey_num = <0x0>;
led_power = <0x0>;
led_state = <0x0>;
pinctrl-0 = <&standby_blue>;
pinctrl-1 = <&standby_red>;
pinctrl-2 = <&standby_bt>;
/*pinctrl-3 = <&standby_bt>;*/
}
...
s_cir0 {
s_cir0_used = <1>;
ir_power_key_code0 = <0x40>;
ir_addr_code0 = <0xfe01>;
ir_power_key_code1 = <0x1a>;
ir_addr_code1 = <0xfb04>;
ir_power_key_code2 = <0xf2>;
ir_addr_code2 = <0x2992>;
ir_power_key_code3 = <0x57>;
ir_addr_code3 = <0x9f00>;
ir_power_key_code4 = <0xdc>;
ir_addr_code4 = <0x4cb3>;
ir_power_key_code5 = <0x18>;
ir_addr_code5 = <0xff00>;
ir_power_key_code6 = <0xdc>;
ir_addr_code6 = <0xdd22>;
ir_power_key_code7 = <0x0d>;
ir_addr_code7 = <0xbc00>;
ir_power_key_code8 = <0x4d>;
ir_addr_code8 = <0x4040>;
wakeup-source;
}
“start_type = <0x1>;”,0x0 代表当系统启动时检测到是适配器上电启动则进入假关机(H700 TV);0x1 不做适配器上电检测判断,按普通的假关机判断流程;
“irkey_used = <0x0>;”,当前代码并未解析该节点,为无用节点,不影响假关机流程;
“pmukey_used = <0x0>;”,当前代码并未解析该节点,为无用节点,不影响假关机流程;
“pmukey_num = <0x0>;”,当前代码并未解析该节点,为无用节点,不影响假关机流程;
“led_power = <0x0>;”,当前代码并未解析该节点,为无用节点,不影响假关机流程;
“led_state = <0x0>;”,当前代码并未解析该节点,为无用节点,不影响假关机流程;
“pinctrl-0 = <&standby_blue>;”,LED 显示需要用到的 pinctrl 配置(其中一种颜色);
“pinctrl-1 = <&standby_red>;”,LED 显示需要用到的 pinctrl 配置(其中一种颜色);
“pinctrl-2 = <&standby_bt>;”,外部唤醒源(如蓝牙/wifi/rtc 模块)唤醒系统时拉对应 gpio,高脉冲有效,高脉冲持续时间需要大于 200 ms;
“pinctrl-3 = <&standby_bt>;”,外部唤醒源(如蓝牙/wifi/rtc 模块)唤醒系统时拉对应 gpio,低脉冲有效,低脉冲持续时间需要大于 200 ms;
“ir_power_key_code = <0x40>;”,ir 模块特定数据的码值,根据方案需求进行配置;
“ir_addr_code = <0xfe01>;”,ir 模块特定地址的码值,根据方案需求进行配置。
表 2-2: 平台支持唤醒源列表
平台/唤醒源 | 非CPUS域GPIO | CPUS域GPIO | POWER-KEY | RTC | USB | 红外 | 蓝牙/WiFi | MAD |
---|---|---|---|---|---|---|---|---|
T509 | 不支持 | super standby | super standby | super standby | super standby | 不支持 | super standby | 不支持 |
H616 | normal standby | 不支持 | normal standby | normal standby | normal standby | normal standby | normal standby | 不支持 |
V853 | normal standby | 不支持 | super standby | super standby | super standby | 不支持 | normal standby | 不支持 |
T113 | normal standby | 不支持 | 不支持 | normal standby | 不支持 | 不支持 | normal standby | 不支持 |
2.3.3 kernel menuconfig 配置说明
linux-4.9 内核版本:在命令行中进入 linux 目录,执行 make ARCH=arm64 menuconfig(32 位系统为 make ARCH=arm menuconfig) 进入配置主界面 (Linux-5.4 内核版本执行:./build.sh menuconfig),并按以下步骤作。
• 内核 PSCI 选项
• 内核 CPUIDLE 相关选项(可选)
CPU Power Management --->
CPU Idle --->
[*] CPU idle PM support
ARM CPU Idle Drivers --->
[*] Generic ARM/ARM64 CPU idle Driver
• 内核 POWER 相关选项
Power management options --->
[*] Suspend to RAM and standby
[ ] Opportunistic sleep
[*] User space wakeup sources interface
(100) Maximum number of user space wakeup sources (0 = no limit)
-*- Device power management core functionality
[*] Power Management Debug Support
[*] Extra PM attributes in sysfs for low-level debugging/testing
• 内核 FAKE_POWEROFF 相关选项
2.3.4 uboot-2018 配置
• uboot-2018 FAKE_POWEROFF 相关配置
在平台的 defconfig 中,将 CONFIG_ATF_BOX_STANDBY 配置为 Y
2.4 源码结构介绍
Standby 的源代码位于内核 kernel/power/目录下:
kernel/power/
├── autosleep.c
├── console.c
├── hibernate.c
├── Kconfig
├── main.c
├── Makefile
├── modules.builtin
├── modules.order
├── power.h
├── poweroff.c
├── process.c
├── qos.c
├── snapshot.c
├── suspend.c
├── suspend_test.c
├── swap.c
├── user.c
├── wakelock.c
└── wakeup_reason.c
2.5 驱动框架介绍
休眠唤醒指系统进入低功耗和退出低功耗模式,一般称之为 Standby。休眠过程由应用发起,经由内核的电源管理框架来进行休眠唤醒管理工作,如果存在 CPUS(一颗集成在 IC 内部的对电源进行管理的 openrisc 核,是 SoC 内置的超低功耗硬件管理模块),最终会传递到到 CPUS。因此休眠唤醒类出现问题的可能为应用层、内核层、CPUS 层,如果不存在 CPUS,则 CPU 进入WFI。休眠唤醒流程图如下,虚线部分为部分内核实现。
图 2-1: standby 驱动总体结构
图 2-2: linux standby 流程