--- 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 暂无