---
title: Tina Linux 快启功耗管理
subtitle: 开发指南
author: Allwinner
changelog:
- ver: 1.0
  date: 2024.10.25
  author: AWA1812  
  desc: |
		初始版本	            

---

# Tina_Linux_快启功耗管理_开发指南


(前言)=
## 前言


(文档简介)=
### 文档简介

介绍 V821 平台快启功耗管理功能，及其配置项与软件流程。


(目标读者)=
### 目标读者

V821 快启功耗管理的开发、维护及测试人员


(适用范围)=
### 适用范围

Table:适用产品列表

| 产品名称   | 内核版本 |
| ------ | --------- |
| V821   | Linux-5.4 |


(文档约定)=
### 文档约定


(标志说明)=
#### 标志说明

:::warning
* 提醒操作中应注意的事项。不当的操作可能会损坏器件，影响可靠性、降低性能等。
:::


:::note
为准确理解文中指令、正确实施操作而提供的补充或强调信息。
:::

:::tip
一些容易忽视的小功能、技巧。了解这些功能或技巧能帮助解决特定问题或者节省操作时间。
:::


(地址与数据描述方法约定)=
#### 地址与数据描述方法约定
本文档在描述地址、数据时遵循如下约定：

Table:地址与数据描述方法约定

-------------------------------------------------------------------------------------
**符号**   **例子**                **说明**
---------- ----------------------- --------------------------------------------------
0x         0x0200，0x79            地址或数据以16进制表示。

0b         0b010，0b00 000 111     数据采用二进制表示(寄存器描述除外)。

X          00X，XX1                数据描述中，X代表 0或1。

                                   例如，00X代表000或001；XX1代表001，011，101或111。
-------------------------------------------------------------------------------------



(数值单位约定)=
#### 数值单位约定

本文档在描述数据容量（如NAND容量）时，单位词头代表的是1024的倍数；描述频率、数据速率等时则代表的是1000的倍数。具体如下：

Table:数值单位约定

-------------------------------------------------------------------------------------
**类型**                **符号**    **对应数值**
----------------------- ----------- -------------------------------------------------
数据容量（如NAND容量）   1 K        1024                                          

                         1 M        1 048 576

                         1 G        1 073 741 824

频率，数据速率等         1 k        1000

                         1 M        1 000 000

                         1 G        1 000 000 000
-------------------------------------------------------------------------------------


(相关术语介绍)=
### 相关术语介绍

Table:术语说明

----------------------------------------------------------------------------------------------------
**术语**                **解释说明**   
----------------------- ----------------------------------------------------------------------------
CPUS                    全志平台上，用于低功耗管理的协处理器单元。

CPUX                    主处理器单元，被协处理器控制进入低功耗的处理器。

CSI                     图像传感器接口。

ultra standby           V821的一种低功耗场景，功耗尽量接近关机的同时启动时间较冷启动快。
----------------------------------------------------------------------------------------------------


(模块介绍)=
## 模块介绍


(模块功能)=
### 模块功能

V821 平台支持三种低功耗场景，功耗从高到低（同时退出场景的耗时从快到慢）排序分别称为super standby、ultra standby、hibernation。其中super standby属于系统休眠场景，系统走唤醒流程退出该场景，恢复休眠前的现场。ultra standby与hibernation属于系统关机场景，退出关机场景需要系统走开机流程重新启动。

super standby是一种CPUX域供电关闭的休眠场景，休眠期间dram数据保持，随时可恢复成休眠前的状态。关于super standby的详细说明请参考《Tina_Linux_功耗管理_开发指南》。

hibernation即是完全关机场景，只保留RTC域电源，dram掉电，仅RTC闹钟、RTC域的wakeup io与wakeup timer能触发开机。开机后所有软硬件会被重新初始化。

ultra standby是完全关机场景的基础上额外保留了小部分供电资源，在功耗尽量接近关机场景的同时，提供更快的启动速度。

ultra standby模式下，除了RTC域电源，额外保留了AON域电源，dram仍掉电，但sram保持工作。开机后CPUX重启，但RISCV协处理器从低功耗断点处恢复现场，执行开机前期的准备工作，以加速系统启动。此外，ultra standby除了支持关机场景已有的开机源外，还能支持IC内部无线模块保活，以及根据Sensor供电的需求配置保留IC的LDO_1V8与LDO_2V8两路供电。遗留工作的模块越多，功耗越高。

Table:ultra standby低功耗场景与关机场景差异

| 场景  | RTC域  | AON域 |  LDO1V8与LDO2V8 | dram | sram | wlan保活 | CSI sensor工作 | 场景退出动作 |
| ---   | ------ | ---- | ---- | ---- | ---- | ---- | ---- |
| hibernation  | 保留 | 掉电   | 掉电 | 掉电 | 掉电 | 不支持 | 不支持 | 不支持 | 从休眠处唤醒 |
| ultra standby  | 保留  | 保留 | 可配置保留 | 掉电 | 保留 | 可支持 | 可支持 | 重启 |
| super standby  | 保留  | 保留 | 可配置保留 | 保留 | 保留 | 可支持 | 可支持 | 重启 |


(模块配置)=
### 模块配置


(Device Tree配置)=
#### Device Tree配置

1， 在设备树中，存在hibernation场景与ultra standby场景的开机源信息配置：

```
poweron‑source {
    hib_poweron_source = <0x000007FF>;      //hibernation场景 开机源配置
    ultra_poweron_source = <0x000007FF>;    //ultra standby场景 开机源配置
};

hib_poweron_source、ultra_poweron_source均作为32位数，每个bit表示一种特定开机源，bit为1表示支持该开机源。

bit与开机源的对应关系如下：
bit0-7： wakeup IO 0-7
bit9  :  rtc alarm0
bit10 :  rtc alarm1
bit11 :  wakeup timer

注：不需要配置wlan开机源：wlan保活是低功耗协处理器上的功能，保活时由wlan模块自行判断是否需要拉起系统。
```

2， 此外，使用wakeup IO触发开机时，需要增加以下对wakeup IO的配置项：

```
&wakeup_io {
    status = "okay";
    wakeup_pins {
        wakeup_pin1:wakeup‑pin@1 {      //若有多个wakeupIO，响应增加序号，例如wakeup_pin2/3/4
            gpio_info = <&rtc_pio PL 03 GPIO_ACTIVE_LOW>;   //GPIO标准配置，此处使用了PL3
            edge_mode = "negative";     //事件触发类型，positive 表示高电平，negative 表示低电平
            clk_src = <0>;              //时钟源选择，用于与debounce_us组合配置硬件，可任写 0 和 1 两种，驱动会自动配置
            debounce_us = <2000000>;    //保持事件触发类型多久后，触发事件，此处表示低电平持续2秒后触发事件
        };
    };
};

注：
（1）只有PL0-7可被配置为wakeup IO；
（2）选定PL不能被其他模块复用，若存在复用，请失能使用了选定PL的模块；
（3）内核menuconfig配置需使能wakeupIO驱动宏 AW_WUPIO 。
```


(Menuconfig配置)=
#### Menuconfig配置

内核Menuconfig配置项：

* 休眠框架配置

```
(1)
Power management options ‑‑‑>
    [*] Suspend to RAM and standby             # suspend to ram 休眠功能
    [ ] 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  # 调试节点

（2）
Allwinner BSP ‑‑‑>
    Device Drivers ‑‑‑>
      RISCV suspend Drivers ‑‑‑>
        [*] Allwinner sunxi riscv suspend support     # 全志平台休眠驱动
```

* wakeup IO配置

```
Allwinner BSP ‑‑‑>
    Device Drivers ‑‑‑>
        WUPIO Drivers ‑‑‑>
            <*> WUPIO Support for Allwinner SoCs    # wakeup IO驱动
```


(软件框架)=
### 软件框架


(ultra standby快启执行流程)=
#### ultra standby快启执行流程

ultra standby被触发开机后，低功耗协处理首先恢复自身现场，并初始化外部存储介质及DRAM，为CPUX的运行准备环境，随后拉起CPUX，此后如有必要，执行快启出图的准备工作。CPUX启动后对自身运行环境进行初始化，加载并初始化Linux系统，此后执行正常的开机流程。若有出图需求，CPUX会在初始化过程中，与协处理器通信同步信息，并完成出图工作。因协处理器的协助初始化，CPUX的早期初始化执行内容较之冷启动有所精简，例如移除了dram初始化、协处理器加载、必要的时钟电源配置等内容。

![ultra standby快启执行流程图](figures/ultra_standbykuaiqizhixingliuchengtu.png)



(功能开发)=
## 功能开发


(功能概述)=
### 功能概述

快启功耗管理主要提供了一种低功耗场景，从该场景下启动系统的耗时较冷启动更少。

本章节主要介绍进入ultra standby的方式，以及相关配置命令。


(进入ultra standby场景)=
### 进入ultra standby场景

* 进入ultra standby：

```
(1) 使能ultra standby功能
echo 1 > /sys/class/ae350_standby/use_ultra_standby

(2) 关机，若执行过第一步，此次关机将会进入ultra standby，否则进入hibernation
poweroff
```

* LDO1V8与LDO2V8的保留配置

```
进入ultra standby后，同时保留LDO1V8与LDO2V8供电：
echo 3 > /sys/class/ae350_standby/standby_ldo_onoff
此处输入的数值 3 可以是 0~3，将其以16进制表示，该数值的bit0为1表示保留LDO1V8，bit1为1表示保留LDO2V8
```

* 设置开机源

```
(1) 设置wakeup timer
echo 7000 > /sys/class/ae350_standby/time_to_wakeup_ms
7000 表示进入ultra standby 7000 ms后，触发开机，用于短时间定时，若以天为单位，请使用RTC闹钟

(2) 设置rtc闹钟
echo +10 > /sys/class/rtc/rtc0/wakealarm
10 表示命令输入 10 秒后，触发开机

(3) 设置wakeup io
请参考 “模块配置” 章节，完成wakeup IO的dts配置，并使能驱动，系统启动后由wakeup IO驱动完成配置；
将配置对象的IO按配置触发方式拉高或拉低指定时间，触发开机

(4) wlan触发开机
wifi连接服务器后，进入ultra standby前需要设置低功耗命令，输入：
wifi ‑e “xrlink user: wlan set_lp_param p=10”
进入ultra standby后，wlan会与服务器保持连接，并在收到数据包后自行判断是否拉起系统
注：该命令需要编译wifimanager软件包前，使能CONFIG_WMG_SUPPORT_EXPAND宏

```


(调试方法)=
## 调试方法


(ultra standby执行日志)=
### ultra standby执行日志

若出现问题，可通过执行日志初步判断出错流程阶段，请提供CPUX与协处理器的执行日志信息，联系全志进一步处理。

执行日志说明如下：

* 流程第一部分 CPUX关机日志

```
root@(none):/# echo 1 > /sys/class/ae350_standby/use_ultra_standby      # 使能 ultra standby
ac327 send hard syn message: 0x300202
ac327 receive hard syn message feedback: 0x300202
root@(none):/# echo +10 > /sys/class/rtc/rtc0/wakealarm     # 设置RTC闹钟
root@(none):/# poweroff                                    # 触发关机
The system is going down NOW!
Sent SIGTERM to all processes
Requesting system poweroff
[  218.364539] sunxi:rtc:[INFO]: reboot_deal(): empty arg
[  218.370410] sunxi:sunxi_riscv_pm:[INFO]: hib poweron_source is 0x7ff
ac327 send hard syn message: 0x260202
ac327 receive hard syn message feedback: 0x260202
[  218.380856] sunxi:sunxi_riscv_pm:[INFO]: hib ultra_poweron_source is 0x7ff
ac327 send hard syn message: 0x260202
ac327 receive hard syn message feedback: 0x260202
[  218.402577] sunxi:twi-42502000.twi0:[INFO]: shutdown finish
[  218.412871] sunxi-rproc 43030000.e907_rproc: skip shutdown
[  218.419122] sunxi:vin:[WARN]: video4 device have been closed!
[  218.425636] sunxi:vin:[WARN]: video0 device have been closed!
[  218.432300] reboot: Power down
ae350_system_reset(): CPU[0] SHUTDOWN
ac327 send hard syn message: 0x80240202
ac327 receive hard syn message feedback: 0x240202
///////////////////////////////  CPUX 关闭 ////////////////
```

* 流程第二部分 低功耗协处理器关机日志

```
[T(pm)] at pm_suspend_task:191 suspend begin.   # 协处理器开始关机流程
xrlink txrx deinit finish.
[RPBUF_INFO][rpbuf_free_buffer_internal:1350]buffer "xradio_mtx" (id:0): buffers -> remote_dummy_buffers
[RPBUF_INFO][rpbuf_free_buffer_internal:1350]buffer "xradio_mrx" (id:1): buffers -> remote_dummy_buffers
rpmsg_xradio_deinit
[RV] [AMP_INFO][rpmsg_unregister_driver:186]Unsupport rpmsg_unregister_driver
[RV] [AMP_INFO][rproc_common_remove:68]remove rproc...
[L(pm)] pm task start freeze
[L(pm)] pm task task num: 11
[L(pm)] skip suspend task: pm_suspend
[L(pm)] skip suspend task: IDLE
[L(pm)] skip suspend task: BH
[L(pm)] skip suspend task: wpas
[L(pm)] skip suspend task: Tmr Svc
[L(pm)] skip suspend task: tcpip
[L(pm)] skip suspend task: workqueue
[L(pm)] skip suspend task: rx_proc
[L(pm)] skip suspend task: umac
[L(pm)] freeze task: pm_client
[L(pm)] skip suspend task: Looper
[L(pm)] pm task end freeze
gpt get partition success: riscv0
sector: 13952 sector_num: 2432
gpt get partition success: riscv0
sector: 13952 sector_num: 2432
bootpkg init malloc_1: 0x00000200
bootpkg init malloc_2: 0x00000620
find bootpkt success: pmboot
data_offset: 0x000b9c00
data_len: 0x00007000
[L(pm)] a27l2 enter wfi success
[L(pm)] a27l2 reset and power down           # 协处理器关闭CPUX
[L(pm)] e907 deinit pm client
[L(pm)] real_wakeup_mask: 0x000007ff
[L(pm)] pm enable wakesrc irq
[T(pm)] call pm_devops_call(0, 2)
[STAGE(pm)] PM: PM_DEVOPS_TYPE_PREPARED of devices complete after 3 msecs
[T(pm)] call pm_devops_call(1, 2)
[T(pm)(devops)]: calling msgbox ...
[T(pm)(devops)]: call msgbox return 0 after 58 usec.
[STAGE(pm)] PM: PM_DEVOPS_TYPE_SUSPEND of devices complete after 10 msecs
[L(pm)] ##image standby_boot0 info##
[L(pm)] dst_addr: 0x80f80000
[L(pm)] src_addr: 0x000c9c00
[L(pm)] size: 0x00007000
[L(pm)] ##image rtos fw info##
[L(pm)] dst_addr: 0x81444000
[L(pm)] src_addr: 0x006d0000
[L(pm)] size: 0x00130000
[L(pm)] ##image rtos elf info##
[L(pm)] section_num: 0x00000001
[L(pm)] section[0].dst_addr: 0x81000000
[L(pm)] section[0].src_addr: 0x006d1000
[L(pm)] section[0].file_size: 0x0012a660
[L(pm)] section[0].mem_size: 0x00132c54
[L(pm)] dram_size: 0x00000040
[W(pm)] ##ccu_app clock and reset check##
[W(pm)] reg(0x42001004) - value: 0x81000000 - mask: 0x80000000
[W(pm)] reg(0x4200100c) - value: 0x80000000 - mask: 0x80000000
[W(pm)] reg(0x42001040) - value: 0x80000000 - mask: 0x80000000
[W(pm)] reg(0x42001064) - value: 0x82000002 - mask: 0x80000000
[W(pm)] reg(0x42001074) - value: 0x82010013 - mask: 0x80000000
[W(pm)] reg(0x4200107c) - value: 0x00000198 - mask: 0x0000006f
[W(pm)] reg(0x42001080) - value: 0x401aa299 - mask: 0xfff7effd
[W(pm)] reg(0x42001084) - value: 0x00086143 - mask: 0xe3ffe17f
[W(pm)] reg(0x42001088) - value: 0x00000404 - mask: 0x1c00073f
[W(pm)] reg(0x42001090) - value: 0x099aa29b - mask: 0x9fffefff
[W(pm)] reg(0x42001094) - value: 0x1008114b - mask: 0x1fbc1d7b
[W(pm)] reg(0x42001098) - value: 0x00000005 - mask: 0x80000007
[T(pm)] call pm_devops_call(2, 2)
[T(pm)(devops)]: calling xradio ...
[T(pm)(devops)]: call xradio return 0 after 11760 usec.
[T(pm)(devops)]: calling xrlink ...
[TXRX ERR] xrlink_tranc_early_deinit():1278, xrlink_tranc is null.
[T(pm)(devops)]: call xrlink return 0 after 2098 usec.
[STAGE(pm)] PM: PM_DEVOPS_TYPE_SUSPEND_LATE of devices complete after 25 msecs
[T(pm)] call pm_devops_call(3, 2)
[T(pm)(devops)]: calling xradio ...
[T(pm)(devops)]: call xradio return 0 after 7 usec.
[T(pm)(devops)]: calling lwip ...
func:lwip_suspend has run
[T(pm)(devops)]: call lwip return 0
//////////////////// 协处理器关闭 //////////////

```

* 流程第三部分 低功耗协处理器开机日志

```
[T(pm)] call pm_devops_call(4, 2)
[T(pm)(devops)]: calling lwip ...
func:lwip_pool_resume has run
func:lwip_resume has run
[T(pm)(devops)]: call lwip return 0 after 501 usec.
[T(pm)(devops)]: calling xradio ...
[T(pm)(devops)]: call xradio return 0 after 22 usec.
[STAGE(pm)] PM: PM_DEVOPS_TYPE_RESUME_NOIRQ of devices complete after 12 msecs
[T(pm)] call pm_devops_call(5, 2)
[T(pm)(devops)]: calling xrlink ...
xrlink_tranc_early_init init sucess.
[T(pm)(devops)]: call xrlink return 0 after 3294 usec.
[T(pm)(devops)]: calling xradio ...
[T(pm)(devops)]: call xradio return 0 after 11555 usec.
[STAGE(pm)] PM: PM_DEVOPS_TYPE_RESUME_EARLY of devices complete after 29 msecs
[T(pm)] at pm_suspend_devices_and_enter:352 suspend resume.
[L(pm)] ##memory backup info##
[L(pm)] __firmware_size__: 0x000056a8
[L(pm)] __bss_size__: 0x000085f4
[L(pm)] __data_size__: 0x000017dc
[L(pm)] __heap_payload_size__: 0x0000d3a8
[L(pm)] __heap_backup_size__: 0x0000d970
[L(pm)] __sram_backup_size__: 0x0001cde8
[L(pm)] __bss_unsaved_size__: 0x00022b7c
[L(pm)] __data_unsaved_size__: 0x00005fc0
[T(pm)] call pm_devops_call(6, 2)
[T(pm)(devops)]: calling msgbox ...
[T(pm)(devops)]: call msgbox return 0 after 64 usec.
[STAGE(pm)] PM: PM_DEVOPS_TYPE_RESUME of devices complete after 10 msecs
[T(pm)] call pm_devops_call(7, 2)
[STAGE(pm)] PM: PM_DEVOPS_TYPE_COMPLETE of devices complete after 3 msecs
[L(pm)] pm disable wakesrc irq
[L(pm)] rtos_fw_info->src_addr: 0x006d0000
[L(pm)] rtos_fw_info->dst_addr: 0x81444000
[L(pm)] rtos_fw_info->size: 0x00130000
[L(pm)] standby_boot0->src_addr: 0x000c9c00
[L(pm)] standby_boot0->dst_addr: 0x80f80000
[L(pm)] standby_boot0->size: 0x00007000
[L(pm)] standby_boot0 dram_size: 0x00000040
[L(pm)] e907 init pm client
[L(pm)] power up and release a27l2 0x80f80000     # 协处理器开启CPUX
[L(pm)] pm task start restore
[L(pm)] pm task num: 11
[L(pm)] pm task end restore
///////////// 协处理器恢复 ///////////////////////
```

* 流程第四部分 CPUX开机

```
[1]HELLO! PMBOOT is starting!           # CPUX开始初始化自身运行环境
[3]PMBOOT commit : b628c72c9c
[6]set pll end
[7]board init ok: use hosc 40M
[10]rtc[0] value = 0x1
[12]rtc[7] value = 0x2
[14]dram size =64
[17]set spif freq:100000000
[19]spi sample_mode:0 sample_delay:15
[23]spinor id is: 20 40 18, read cmd: ed
[27]Succeed in reading toc file head.
[30]The size of toc is c4000.
[43]Entry_name        = opensbi
[46]Entry_name        = u-boot
[50]Entry_name        = pmboot
[52]Jump to OpenSBI: opensbi_base = 0x80fc0000, dtb_base = 0x0, uboot_base = 0x82000000
//////// CPUX早期初始化完毕，后续继续执行正常启动流程 ///////
```


(FAQ)=
## FAQ

暂无

