功耗调整指引

1. 概述

本文档用于指导 Sigmastar PureLinux & DualOs 平台的功耗优化,主要介绍各模块功耗调试方法。

2. 配置说明

目前 PureLinux & DualOs 平台已接入 CCF (Common Clock Framework),默认未使用的模块均会在 Linux 系统启动阶段进行关闭。

但需要确保开启如下配置:

PureLinux:

Symbol: COMMON_CLK [=y]
Type  : bool
Defined at drivers/clk/Kconfig:25
  Prompt: Common Clock Framework
  Depends on: !HAVE_LEGACY_CLK [=n]

DualOs:

Symbol: SSTAR_CLK_OS_MANAGE [=y]
Type  : tristate
Defined at drivers/sstar/clk/Kconfig:4
  Prompt: Sstar CLK OS Manage
  Depends on: SSTAR_DRIVERS [=y]
  Location:
    -> Device Drivers
      -> Sstar SoC platform drivers (SSTAR_DRIVERS [=y])

开启上述配置之后,时钟使能/失能以及时钟之前的依赖会由 CCF 接管,各模块仅需使用 CCF 提供的接口对接即可,而对于用户,需要关注的点主要会分为:

  1. 模块增删

    大部分 BSP 模块在使用的时候才会将时钟开启,但部分模块会在加载阶段(probe)就将时钟开启,这些模块在没有使用的时候需要确保是没有被装载的,例如 usb 模块。

  2. 模块调频

    这部分主要针对功耗较高的串流模块,用户可以调到适合场景的合适频率,以降低功耗。

此外,还会对一些比较特殊的模块作专门的介绍,例如:CPUDDR

2.1. 模块增删

该章节介绍的是模块的增加与移除的配置操作,主要是针对部分在模块加载时就会开启时钟的模块进行功耗调试时的参考。

2.1.1. usb

usb 这边会分为 host 端控制器和 device 端控制器,这里边会分别介绍其编译控制的 config。

usb 2.0 主机端控制器:

1. 控制器驱动:

Symbol: USB_EHCI_HCD [=m]
Type  : tristate
Defined at drivers/usb/host/Kconfig:129
  Prompt: EHCI HCD (USB 2.0) support
  Depends on: USB_SUPPORT [=y] && USB [=y] && HAS_DMA [=y] && HAS_IOMEM [=y]
  Location:
    -> Device Drivers
      -> USB support (USB_SUPPORT [=y])
  模块化对应驱动:ehci-hcd.ko

2. PHY 驱动:

Symbol: SSTAR_USB2_PHY [=m]
Type  : tristate
Defined at drivers/sstar/usb/phy/Kconfig:13
  Prompt: SStar USB2 PHY Driver
  Depends on: SSTAR_DRIVERS [=y]
  Location:
    -> Device Drivers
(2)   -> Sstar SoC platform drivers (SSTAR_DRIVERS [=y])
Selects: GENERIC_PHY [=y] && USB_PHY [=y] && MFD_SYSCON [=y]
  模块化对应的驱动有:sstar-usb2-phy.ko

usb 2.0 设备端控制器:

Symbol: USB_SSTAR_MSB250X_UDC [=m]
Type  : tristate
Defined at drivers/sstar/usb/gadget/udc/usb20/Kconfig:1
  Prompt: Sstar MSB250X USB 2.0 Device Controller
  Depends on: USB_SUPPORT [=y] && USB_GADGET [=m]
  Location:
    -> Device Drivers
      -> USB support (USB_SUPPORT [=y])
        -> USB Gadget Support (USB_GADGET [=m])
          -> USB Peripheral Controller
  模块化对应的驱动有:udc-msb250x.ko

2.1.2. sdmmc

Symbol: SSTAR_SDMMC [=m]
Type  : tristate
Defined at drivers/sstar/sdmmc/Kconfig:1
  Prompt: SStar SD/MMC Card Interface Support
  Depends on: SSTAR_DRIVERS [=y] && MMC [=m]
  Location:
    -> Device Drivers
      -> Sstar SoC platform drivers (SSTAR_DRIVERS [=y])
  模块化对应的驱动有:kdrv_sdmmc.ko

2.1.3. crypto

该模块主要用于加解密操作。

Symbol: SSTAR_CRYPTO [=y]
Type  : tristate
Defined at drivers/sstar/crypto/Kconfig:1
  Prompt: SigmaStar Crypto driver
  Depends on: MSTAR_DRIVERS [=y]
  Location:
    -> Device Drivers
      -> SStar SoC platform drivers (MSTAR_DRIVERS [=y])
 模块化对应的驱动有:mdrv_crypto.ko

2.2. 模块时钟调频

该章节所列举模块均支持频率的调节,串流相关的模块会分为 调试接口 以及 正式接口,调试阶段可以通过调试接口动态调整并测试功耗,确认最终配置之后再使用正式接口生效配置。

2.2.1. 调试接口

调试接口 支持 档位查看 以及 档位配置

接口仅用于调节合适时钟频率时使用。展示的时钟分为两部分,时钟源档位和当前时钟频率,因模块时钟可能支持 divider,实际时钟可能为时钟源细分档位。

2.2.2. 正式接口

正式接口 通过 modparam.json 来进行设定:

在通过调试接口确认好时钟之后通过该接口配置生效,该接口支持 DualOs 以及 PureLinux 的设定,modparam.json 为统一初始化接口,详细使用方法请查看 mi_common 使用介绍。

2.2.3. 时钟调试技巧

时钟档位:模块时钟档位查看仅提供时钟源的档位,部分模块支持 divider,所以会有更多的时钟档位(基于时钟源分频),实际配置时,可先确认大的时钟源档位下是否满足需求,再细分配置更小的时钟档位。

模块处理任务需要的时钟频率会跟硬件处理的帧率、图像分辨率有关,所以没办法给出一个比较统一的公式化档位来预估时钟频率,所以目前的获取时钟频率的方式是不断的尝试进行档位配置,确认模块是否工作正常,逐步接近最终档位,大致可以分为下面几个步骤进行:

  1. 在串好的完整场景下,以场景正常工作的情况为准,获取此时的基础时钟频率;

  2. 从最前端模块(sensor)开始调节时钟频率,需要基于基础时钟频率,由高档位往低档位进行,直到获取合适时钟。如果模块出现帧率降低,或者出现 fifo full 等问题,说明时钟频率已经到底了,此时需要将相关的时钟档位往高一档调;如果场景是硬件直连模式,可以将直连模式切换为 frame 模式,以避免前后级相互的影响;

  3. 将所获得的时钟频率增加余量,因为该时钟频率为不断调试出来的频率,会趋于硬件在该场景处理的极限频率值,如果遇到带宽减少或者场景微调的情况,可能会出现模块处理的帧率不足,所以此时需要给第二步调出来的频率适当增加余量。

2.2.4. Sensor 时钟调试

档位查看:

/ # cat /proc/mi_modules/mi_sensor/debug_hal/csi_clk0
[0] 432000000 <--
[1] 288000000
[2] 320000000
[3] 172000000
Current CLK:432000000

csi_clk0 对应 sensor0,csi_clk1 对应 sensor1

档位配置:

/ # echo 226000000 > /proc/mi_modules/mi_sensor/debug_hal/csi_clk0
/ # cat /proc/mi_modules/mi_sensor/debug_hal/csi_clk0
[0] 432000000
[1] 288000000
[2] 320000000
[3] 172000000
Extend CLK 234000000:288000000 * 26 / 32

Extend CLK:代表有使用 dfs 进行细分档位

正式接口:

{
    "E_MI_MODULE_ID_SNR" :
    {
        "csi_clk": [234000000,234000000]
    }
}

csi_clk:这里面配置的两项分别代表:csi_clk0、csi_clk1

2.2.5. VIF 时钟调试

档位查看:

/ # cat /proc/mi_modules/mi_vif/debug_hal/vif_clk
[0] 288000000 <--
[1] 240000000
[2] 192000000
[3] 320000000
Current CLK:288000000

档位配置:

/ # echo 140000000 > /proc/mi_modules/mi_vif/debug_hal/vif_clk
/ # cat /proc/mi_modules/mi_vif/debug_hal/vif_clk
[0] 288000000
[1] 240000000
[2] 192000000
[3] 320000000
Extend CLK 144000000:192000000 * 24 / 32

正式接口:

{
    "E_MI_MODULE_ID_VIF" :
    {
        "vif_clk": 144000000
    }
}

2.2.6. ISP 时钟调试

档位查看:

/ # cat /proc/mi_modules/mi_isp/debug_hal/isp_clk
[0] 288000000
[1] 240000000
[2] 192000000
[3] 320000000
Extend CLK:144000000 = 192000000 * 24 / 32

档位配置:

/ # echo 123000000 > /proc/mi_modules/mi_isp/debug_hal/isp_clk
/ # cat /proc/mi_modules/mi_isp/debug_hal/isp_clk
[0] 288000000
[1] 240000000
[2] 192000000
[3] 320000000
Extend CLK:126000000 = 192000000 * 21 / 32

正式接口:

{
    "E_MI_MODULE_ID_ISP" :
    {
        "isp_clk": 126000000
    }
}

2.2.7. SCL 时钟调试

档位查看:

/ # cat /proc/mi_modules/mi_scl/debug_hal/clk
[0] 144000000
[1] 192000000
[2] 216000000
[3] 240000000
[4] 288000000
[5] 320000000
ExtClock[121500000]:
[0] [144000000 * 27 / 32] =  121500000 <-------

档位配置:

/ # echo 152000000 >  /proc/mi_modules/mi_scl/debug_hal/clk
/ # cat /proc/mi_modules/mi_scl/debug_hal/clk
[0] 144000000
[1] 192000000
[2] 216000000
[3] 240000000
[4] 288000000
[5] 320000000
ExtClock[152000000]:
[1] [192000000 * 26 / 32] =  156000000 <-------

正式接口:

{
    "E_MI_MODULE_ID_SCL" :
    {
        "u32FClk1RateHz": 156000000
    }
}

2.2.8. IPU 时钟调试

档位查看:

/ # cat  /proc/mi_modules/mi_ipu/debug_hal/freq
current ipu clock frequency: 400MHz
available frequency:
600MHz
500MHz
400MHz
300MHz

档位配置:

/ # echo 500 >  /proc/mi_modules/mi_ipu/debug_hal/freq
/ # cat  /proc/mi_modules/mi_ipu/debug_hal/freq
current ipu clock frequency: 500MHz
available frequency:
600MHz
500MHz
400MHz
300MHz

正式接口:

{
    "E_MI_MODULE_ID_IPU" :
    {
        "ipu_clk": 400000000
    }
}

2.2.9. IVE 时钟调试

档位查看:

/ # cat /proc/mi_modules/mi_ive/debug_hal/ive_clk

---------- IVE clock -----------
288000000 <--
216000000
384000000
432000000 od
Current CLK: 288000000 dfs(0/0, source=288000000)

档位配置:

/ # echo 266000000 > /proc/mi_modules/mi_ive/debug_hal/ive_clk
/ # cat /proc/mi_modules/mi_ive/debug_hal/ive_clk

---------- IVE clock -----------
288000000 <--
216000000
384000000
432000000 od
Current CLK: 288000000 dfs(0/0, source=288000000)

正式接口:

{
    "E_MI_MODULE_ID_IVE" :
    {
        "ive_clk": 288000000
    }
}

2.3. CPU 调频和热拔插

2.3.1. CPU 调频

CPU 调频目前是通过 Linuxcpufreq 子系统进行的,所以这边主要会对 cpufreq 开出来的接口做介绍。

需要确保有开启配置 CONFIG_SSTAR_CPU_FREQ

2.3.1.1. 节点介绍

节点路径:/sys/devices/system/cpu/cpufreq/policy0

节点名 作用
cpuinfo_cur_freq CPU 当前正在运行的工作频率,一般与 scaling_cur_freq 相等
cpuinfo_max_freq CPU 能够支持的最高工作频率
cpuinfo_min_freq CPU 能够支持的最低工作频率
scaling_available_frequencies 调节器支持的频率档位:
200000 400000 500000 600000 700000 800000 900000 1000000 1100000 1200000 1300000 1400000 1500000
scaling_cur_freq 调节器决定的当前 CPU 工作频率
scaling_available_governors 支持的调节策略:
1. performance:性能优先模式,不考虑耗电,只用最高频率
2. powersave:节能模式,通常以最低频率运行
3. userspace:用户自定义模式, 支持在用户空间手动调节频率
4. ondemand:按需模式,定期检查负载,根据负载来调节频率
scaling_governor 查看当前调节策略以及设定调节策略,默认为 userspace
scaling_max_freq 调节器支持的最高 CPU 工作频率
scaling_min_freq 调节器支持的最低 CPU 工作频率
scaling_setspeed 如果选择的调节策略为 userspace,那么可以设置 CPU 的工作主频为某个值
2.3.1.2. 配置约束
  1. scaling_min_freq 必须小于等于 scaling_max_freq
  2. scaling_min_freq 必须大于等于 cpuinfo_min_freq
  3. scaling_max_freq 必须小于等于 cpuinfo_max_freq
  4. scaling_setspeed 必须在 scaling_min_freq 和 scaling_max_freq 范围内
2.3.1.3. 用户设置频率
# 配置当前的 governor 为 userspace
/sys/devices/system/cpu/cpufreq/policy0/ # echo userspace > scaling_governor

# 确认需要配置的频率是否在范围内:
/sys/devices/system/cpu/cpufreq/policy0 # cat scaling_min_freq
200000
/sys/devices/system/cpu/cpufreq/policy0 # cat scaling_max_freq
1200000

# 配置当前的频率
/sys/devices/system/cpu/cpufreq/policy0 # echo  1000000 > scaling_setspeed
/sys/devices/system/cpu/cpufreq/policy0 # cat scaling_cur_freq
1000000

2.3.2. CPU 热拔插

CPU 热拔插目前是通过 Linuxhotplug 子系统进行的,所以这边主要会对 hotplug 针对 CPU 开出来的接口进行介绍。

需要确保有开启配置 CONFIG_HOTPLUG_CPU

节点路径:/sys/devices/system/cpu/cpu(x)/online,其中 x 为具体需要控制哪个 CPU。配置方法如下(以热拔出 CPU1 为例):

# 获取当前 CPU1 热拔插状态
/sys/devices/system/cpu/cpu1 # cat online
1

# 热拔出 CPU1
/sys/devices/system/cpu/cpu1 # echo 0 > online

# 再次获取当前 CPU1 热拔插状态
/sys/devices/system/cpu/cpu1 # cat online
0

2.4. DDR auto str 和调频

DDR auto str 和调频的控制需要确保有开启配置 MIU_AUTO_STR,控制节点如为 /sys/devices/system/miu/miu0/autostr,配置方法如下:

# echo timeslot [tslot]  [passcnt] >  /sys/devices/system/miu/miu0/autostr
# [tslot]   auto str 以 tslot us 进行循环
# [passcnt] auto str 在 tslot 中有 passcnt us 时间能够 pass cmd
echo timeslot 100 80 > /sys/devices/system/miu/miu0/autostr

# echo urgent [urgent] > /sys/devices/system/miu/miu0/autostr
# urgent: bit0 cpu, bit1 gop, bit2 cmdq,bit 置 1 使能
echo urgent 7 > /sys/devices/system/miu/miu0/autostr

# trigger 操作进行 DFS1 <-> DFS0,默认处于DFS0
# DFS0 一般是高频,DFS1 一般是低频
echo trigger > /sys/devices/system/miu/miu0/autostr

# auto str on
echo on > /sys/devices/system/miu/miu0/autostr
# auto str off
echo off > /sys/devices/system/miu/miu0/autostr

# 会打印当前的 auto str 状态
# DFS%d freq:%d, autostr:%s, urgent[cmdq:%d, gop:%d, cpu:%d], timeslot:%d, passwindow:%d
# 其中,timeslot/passcnt 是 clk 数,根据设定的 us 进行换算过后的数值
cat /sys/devices/system/miu/miu0/autostr

主要注意的是所有参数调整都需要保证 auto str 处于 off 状态。