JasonWang's Blog

高通QNX平台DCVS介绍

字数统计: 1.9k阅读时长: 8 min
2024/07/24

目前智能座舱领域的方案中,高通的两大平台8155/8295占据了大部分的市场份额,这两个硬件平台都是基于QNX系统的虚拟化方案实现的,就是说中控域与仪表域都跑在一个系统上了-座舱通常是Android系统,实际是QNX上的一个虚拟机;而仪表通常是运行在QNX侧。跟传统的单Android系统比较来看,QNX虚拟化平台有很多的变化,比如很多物理驱动与系统服务都跑在了QNX上,而Android上看到的只是一个虚拟的设备,或者压根就去掉了,比如本文要讲到的动态调频与调压功能DCVS(Dynamic Clock and Voltage Scaling)就是一个例子,这个功能在Android上已经没有了,所有的调频与调压功能都在QNX上实现。

DCVS也可将其称为DVFS(Dynamic Voltage and Frequency Scaling)实际都是根据系统负载动态调整CPU/GPU/DDR等工作频率与电压,从而减少功耗

接下来,我们就一起看看高通QNX平台的DCVS功能是如何实现的,以及如何在QNX平台查看CPU, GPU,UFS,DDR的频率。

QNX的DCVS实现原理

CPU DCVS

DCVS是一种电源管理的策略,用于根据系统负载状态动态的调整系统核心频率,以减少功耗,节省电能,这个在如手机这样的移动平台使用的最为广泛。下图是CPU DCVS的的原理框图,其核心的功能都是在一个后台服务dcvs_service中实现的,该服务负责与其他模块如kernel, qcoreio_service进行交互:

  • 根据系统负载来选择相应频率的算法是在QNX内核实现的;一旦决定选择某个频率,内核会发送请求给qcore进程来进行频率的设定
  • 如果系统负载过高导致触发高温保护,此时调频策略完全由LMH(Limit Management Hardware)模块负责执行;而等到系统温度降低到设定的阈值,则DCVS重新交由内核进行处理;dcvs_service服务注册热管理模块(Thermal LMH)的事件回调;在收到开启与关闭事件回调的时间窗口内,会关闭内核的动态调频功能,由LMH硬件负责管理CPU的频率
  • QNX内核中包含一个负责调皮策略的管理者(governor), 其负责监控系统负载,一旦某个CPU簇(cluster, 8285上有两个簇,对应大小两个核心)的负载在一定的时间内持续超过了设定的阈值-高负载(overflow)或者低负载(underflow),内核的管理者就会触发一个事件;DCVS服务收到该事件后,会主动将频率调整为内核推荐的频率

qnx-dcvs

  • qcore是QNX上的电源管理核心服务
  • DLPMP(Dynamic power performance levels and multiprocessor control):动态调整性能模式
  • LMH(Limit Management Hardware): 用于系统高低温保护

如何进行DCVS参数设定

8295平台为例,有两个CPU簇(分别有4个大核,4个小核),每个簇的频率共有10个等级(如下表所示):

SA8295 clusters Levels
cluster0 10(1017MHZ~2131MHZ)
cluster1 10(1280MHZ~2380MHZ)

QNX提供了pdbg接口用于DCVS的参数设定,每个频点主要有如下4个重要的参数:

  • up_pct_thr: 当前频率的CPU使用率上限阈值,对freq10来说,默认值是90
  • up_time_thr_ms: 当前频率的CPU使用率(持续)时间上限阈值,对freq10来说,默认值是100(ms)
  • down_pct_thr: 当前频率的CPU使用率下限阈值,对freq10来说,默认值是10
  • down_time_thr_ms: 当前频率的CPU使用率(持续)时间下限阈值,对freq10来说,默认值是200(ms)

如果想要更好的性能,尽量将up_pct_thr的阈值降低点,确保系统负载超过该阈值后可以快速调频;反之,如果更多的考虑是节省功耗,则应该将down_pct_thr的阈值提高一点,这样可以在系统负载降低时能触发降频,减少能耗。例如,在车载上更多的考虑是性能,我们可以适当提升CPU调频的上限阈值:

1
2
3
4

echo 80 > /dev/pdbg/qcore/dcvs/kdcvs/cluster0/freq10/up_pct_thr
echo 80 > /dev/pdbg/qcore/dcvs/kdcvs/cluster1/freq10/up_pct_thr

如果要关闭DCVS功能,将CPU设定在最高或者最低的频点,可以通过如下接口设定:

1
2
3
4
5
6
7

# 设置为最高频
echo 1 > /dev/pdbg/qcore/dcvs/force_max_freqency

# 设置为最低频
echo 1 > /dev/pdbg/qcore/dcvs/force_min_freqency

另外,在分析问题时,可以通过slog2info查看DCVS的日志信息:

1
2
3
4
5
6
7
8
9
# slog2info -w |grep dcvs
Jan 01 08:00:26.274 frpc_lib.233538 frpc_lib 16135 cdsp_service[fastrpc_farf.c:409]: CDSP:fastrpc_kpower.c:1440:0xdc:6: fastrpc_kpower_set: Request = HAP_power_set_DCVS_v2, Client ID = 15, Client ID for adsp dcvs = 7
Jan 01 08:00:26.279 frpc_lib.233538 frpc_lib 16135 cdsp_service[fastrpc_farf.c:409]: CDSP:fastrpc_kpower.c:1440:0xdc:6: fastrpc_kpower_set: Request = HAP_power_set_DCVS_v2, Client ID = 14, Client ID for adsp dcvs = 6
Jan 01 08:00:26.279 frpc_lib.233538 frpc_lib 16135 cdsp_service[fastrpc_farf.c:409]: CDSP:fastrpc_kpower.c:1440:0xdc:6: fastrpc_kpower_set: Request = HAP_power_set_DCVS_v2, Client ID = 15, Client ID for adsp dcvs = 7
Jan 01 08:00:26.298 frpc_lib.233538 frpc_lib 16135 cdsp_service[fastrpc_farf.c:409]: CDSP:fastrpc_kpower.c:1440:0xdc:6: fastrpc_kpower_set: Request = HAP_power_set_DCVS_v2, Client ID = 14, Client ID for adsp dcvs = 6
Jan 01 08:00:26.298 frpc_lib.233538 frpc_lib 16135 cdsp_service[fastrpc_farf.c:409]: CDSP:fastrpc_kpower.c:1440:0xdc:6: fastrpc_kpower_set: Request = HAP_power_set_DCVS_v2, Client ID = 15, Client ID for adsp dcvs = 7
Jan 01 08:00:26.322 frpc_lib.233538 frpc_lib 16135 cdsp_service[fastrpc_farf.c:409]: CDSP:fastrpc_kpower.c:1440:0xdc:6: fastrpc_kpower_set: Request = HAP_power_set_DCVS_v2, Client ID = 14, Client ID for adsp dcvs = 6
Jan 01 08:00:26.322 frpc_lib.233538 frpc_lib 16135 cdsp_service[fastrpc_farf.c:409]: CDSP:fastrpc_kpower.c:1440:0xdc:6: fastrpc_kpower_set: Request = HAP_power_set_DCVS_v2, Client ID = 15, Client ID for adsp dcvs = 7

GPU DCVS

GPUDCVS主要是通过一个工作队列线程来获取GPU负载信息从而实施DCVS动态调频-通过当前的负载信息来调整GPU的核心工作频率。与CPU的频点类似,GPU的工作频率也分位好几个档次,如SA8155平台对应的GPU工作频率有7个档次:

8155 gpu frequency levels

GPUDCVS来说都是通过内部的算法完成调频策略执行,无需进行调优;不过,QNX提供了开关DCVS的接口:

1
2
3
4
5
6
7

# enable performance governor
echo gpu_perf_governor 1 > /dev/kgsl-control

# disable performance governor
echo gpu_perf_governor 0 > /dev/kgsl-control

也可以选择将GPU频点设定在指定的档次:

1
2
3
4
5

# 设置GPU频率为500MHZ(level 3)
echo gpu_perf_governor 1 > /dev/kgsl-control
echo gpu_gfx_core_clock_level 3 > /dev/kgsl-control

如果需要实时查看当前GPU的工作频率与负载,可以通过设定日志等级,然后通过slog2info查看:

1
2
3
4
5
6
7
8
9

# 设置GPU日志等级
echo gpu_set_log_level 4 > /dev/kgsl-control
echo gpubusystats 100 > /dev/kgsl-control


# 查看GPU实时负载
slog2info -w |grep -i gsl

QNX中查看系统工作频率

高通平台的QNX系统中有一个clock.sh脚本,可以用来读取、设定系统核心的工作频率,比如CPU, GPU, DDR, UFS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# clock.sh -h
clock debug tool
usage: clock.sh <command> <[arg]> [options]

Provides an interface to the qcore clock driver. Results are stored
in /tmp/clockdebug_log, which is then printed to stdout.

global options:
-b,--batch enable batch commands

commands:
enable <clock || powerdomain || dcvs || avs>
disable <clock || powerdomain || dcvs> [--force]
getfreq <clock>
setfreq <clock> <frequency (min KHz)>
setdiv <clock> <div>
setflags <clock || powerdomain || top> <mask>
setlimit <clock> [--min, --max (default)] <frequency (KHz)>
config <clock> <val>
reset <clock> [--assert, --deassert, --pulse (default)]
info <clock || powerdomain || top || list> [--enabled, --on, --ref, --xovote, --cached]
freqplan <clock>
maxperf <cluster_name>
minperf <cluster_name>
perfinfo <cluster_name>
gpio [--off]
debugmux <clocck_name>
getrefcount <clock_name>
log

具体查看各个系统的频率的方法如下,这个可以看到所有系统核心域的频率信息:

1
2
3
4
5
6
7
8
9
10
11
12
13

# cpu
clock.sh info|grep apcs

# gpu
clock.sh info|grep gpu

# ufs
clock.sh info|grep ufs

# ufs
clock.sh info|grep ddr

如果我们要查看某个具体系统时钟的频率信息,可以通过如下命令:

1
2
3
4
5
6

# clock.sh info gpu_cc_gx_gfx3d_clk
Clock State Freq (Hz) EN RST Flags VDD_CX/MMCX Sources
--------------------------------------------------------------------
gpu_cc_gx_gfx3d_clk ON (0) 730995848 1 n/a 0x0 OFF /pmic/client/xo

原文作者:Jason Wang

更新日期:2024-07-25, 11:57:20

版权声明:本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可

CATALOG
  1. 1. QNX的DCVS实现原理
    1. 1.1. CPU DCVS
    2. 1.2. 如何进行DCVS参数设定
    3. 1.3. GPU DCVS
  2. 2. QNX中查看系统工作频率