一、CPU 频率管理
1.1 Linux 下 CPU 频率的几种方式及其作用
Linux 通过cpufreq 框架管理 CPU 频率,调频策略由governor决定。频率控制的几个层次(自底向上):
- driver / OPP 表:芯片支持哪些频率点(
cpu-opp 节点,device tree 中定义) - policy:每个 policy 对应一组同频的 CPU 核(RK3572 大小核有多个 policy),含 min/max 频率范围
- governor:决定在 min~max 之间如何选取频率(调频策略)
- 用户态 / sysfs:
echo 写入,临时生效;要持久化需开机脚本或内核默认配置
| | |
|---|
| 与调度器联动,按实时调度负载动态调频(Linux 4.7+ 引入,ARM64 默认) | |
| | |
| | |
| 由用户态指定目标频率(配合 scaling_setspeed) | |
| | |
| | |
| 基于输入事件交互式调频(旧 Android 平台) | |
RK3572 内核(kernel 6.12)在 ARM64 上未显式指定时默认 governor 是schedutil(动态调频)——这是定频时要改掉的原因。
1.2 用户空间修改 CPU 频率
sysfs 接口位于 /sys/devices/system/cpu/cpufreq/policy*/。RK3572 大小核有多个 policy(policy0 / policy4 …),需逐个操作,可用 policy* 通配覆盖全部。
cat /sys/devices/system/cpu/cpufreq/policy0/scaling_available_governors# 支持的 governor 列表cat /sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies# 支持的频率点(KHz)cat /sys/devices/system/cpu/cpufreq/policy0/scaling_governor# 当前 governorcat /sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq# 当前频率(KHz)cat /sys/devices/system/cpu/cpufreq/policy0/cpuinfo_min_freq# 硬件最低频cat /sys/devices/system/cpu/cpufreq/policy0/cpuinfo_max_freq# 硬件最高频cat /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq# 软件最小频率cat /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq# 软件最大频率
echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor# 对所有 policy 生效:for g in /sys/devices/system/cpu/cpufreq/policy*/scaling_governor; do echo performance > ”$g”done
echo userspace > /sys/devices/system/cpu/cpufreq/policy0/scaling_governorecho 1800000 > /sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed# 单位 KHz,须在 available_frequencies 内
echo 1800000 > /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freqecho 1800000 > /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq# min = max 即锁死到该频率
- 以上
echo 均临时生效,重启失效;若要开机固定,需开机脚本(rcS / systemd service)在启动时执行,或直接改内核默认 governor(见 1.3)。 scaling_setspeed只在 userspace governor 下生效;performance/powersave 下无意义。- sysfs 中频率单位是 KHz(如
1800000 = 1.8 GHz)。 - 写入值必须在
scaling_available_frequencies 内,否则会被 clamp 到合法值。 - 多核多 policy:修改时要逐 policy 设置,注意大小核最高频不同。
1.3 RK3572 CPU 定频方案(kernel 配置法)
采用内核配置法:开机即为 performance,不依赖用户态、无启动时序问题。
sdk/kernel-6.12/drivers/cpufreq/Kconfig 中:
choice prompt ”Default CPUFreq governor” default CPU_FREQ_DEFAULT_GOV_USERSPACE if ARM_SA1100_CPUFREQ default CPU_FREQ_DEFAULT_GOV_SCHEDUTIL if ARM64 || ARM ... default CPU_FREQ_DEFAULT_GOV_PERFORMANCE
RK3572 是 ARM64,命中 default CPU_FREQ_DEFAULT_GOV_SCHEDUTIL if ARM64,所以未显式设置时开机默认是schedutil(动态调频)——这是要改的原因。
rockchip_linux_defconfig 原本编了 POWERSAVE/USERSPACE/ONDEMAND/CONSERVATIVE/INTERACTIVE 等 governor,但没设任何DEFAULT_GOV,因此走 ARM64 默认的 schedutil。
sdk/device/rockchip/common/configs/Config.in.kernel:
config RK_KERNEL_CFG string ”defconfig” ... default ”rockchip_linux_defconfig”
rk3572 命中最后一条 default,即用 rockchip_linux_defconfig。改此文件对本板生效。
文件:sdk/kernel-6.12/arch/arm64/configs/rockchip_linux_defconfig(CPU_FREQ 段)
CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y CONFIG_CPU_FREQ_GOV_INTERACTIVE=y+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y CONFIG_CPUFREQ_DT=y CONFIG_ARM_ROCKCHIP_CPUFREQ=y
- 该配置会
select CPU_FREQ_GOV_PERFORMANCE(把 performance governor 编进内核),并把 Kconfig 的 choice 从 schedutil 切到 performance。 - 其它 governor 保留
=y,运行时仍可手动切换;仅开机默认变 performance(= 锁定到各 policy 最高频)。
1.4 CPU 定频构建与验证
- 重编 kernel(SDK 根目录
make,或单独 make kernel),重新烧写。
2. 板子起来后验证:cat /sys/devices/system/cpu/cpufreq/policy*/scaling_governor# 期望: performancat /sys/devices/system/cpu/cpufreq/policy*/scaling_cur_freq # 期望: 等于 scaling_max_freq
1.5 CPU 备注
- RK3572 大小核会有多个 policy(policy0 / policy4 等),
policy* 通配可一次性覆盖。 - 若要锁到具体频率而非各自最高频:用 userspace governor +
scaling_setspeed(见 1.2),或设 scaling_min_freq = scaling_max_freq = 。 - 若不想改内核,可用开机脚本方案:在 rootfs overlay 的
/etc/init.d/ 加一个 S 脚本,开机时对 policy* 写入 performance(见 1.2 命令)。注意 rootfs 是 squashfs(只读)+ overlay,需在构建期通过 overlay 注入脚本,运行时改不了 /etc/init.d。
二、DDR 频率管理
2.1 如何 enable/disable kernel 中的 DDR 变频功能
先确认该芯片支持 kernel 中的 DDR 变频功能。支持的话,通过修改dts 中最终的 dmc 节点的 status 属性来控制:
| |
|---|
| |
| dmc 节点 status = "disabled" |
RK3576/RK3588 平台,enable DDR 变频后,必须根据实际硬件电源方案检查 DMC 节点下的 center-supply 和 mem-supply 属性是否配置正确。其值是对应供电的 regulator 节点名:
- RK3576 默认:
center-supply = <&vdd_ddr_s0>、mem-supply = <&vdd_logic_s0> - RK3588 默认:
center-supply = <&vdd_ddr_s0>、mem-supply = <&vdd_log_s0>
DMC 节点缺失该属性会导致 dmc 驱动加载失败,kernel log:
rockchip-dmc dmc: Cannot get the regulator ”center”
其他平台(RK3399 等)只需要 center-supply,例如 RK3399 默认 center-supply = <&vdd_center>;PX30/RK3568/RV1126 等其他平台默认 center-supply = <&vdd_logic>。
由于早期代码 dmc 节点有依赖 dfi 节点,如果 dfi 节点为 disabled,也会导致 dmc 节点无效。最好让 dfi 节点的 status 与 dmc 保持一致。
/* enable kernel DDR变频 */&dfi { status = ”okay”;};&dmc { center-supply = <&vdd_ddr_s0>; /* RK3576,需按实际硬件电路配置 */ mem-supply = <&vdd_logic_s0>; status = ”okay”; ...};/* disable kernel DDR变频 */&dfi { status = ”disabled”;};&dmc { status = ”disabled”; ...};
2.2 DDR 如何定频
# 1. 查看固件支持的所有 DDR 频率cat /sys/class/devfreq/dmc/available_frequencies# 2. 切到 userspace governor 并设置频率(单位 Hz)echo userspace > /sys/class/devfreq/dmc/governorecho 300000000 > /sys/class/devfreq/dmc/min_freq# 防止目标频率低于 min_freq 导致设置失败echo 300000000 > /sys/class/devfreq/dmc/userspace/set_freq
要设置的频率必须在cat /sys/class/devfreq/dmc/available_frequencies 的结果中,否则会失败。
找到板级 dts 文件中的 dmc_opp_table 节点,增加目标频率对应的 OPP。以增加 666MHz 为例:
dmc_opp_table: opp-table3 { compatible = ”operating-points-v2”; opp-200000000 { opp-hz = /bits/ 64 <200000000>; opp-microvolt = <825000>; /* vdd_ddr 电压 */ }; ... opp-666000000 { /* 当DDR频率等于666MHz时,使用这个电压 */ opp-hz = /bits/ 64 <666000000>; opp-microvolt = <900000>; }; opp-800000000 { opp-hz = /bits/ 64 <800000000>; opp-microvolt = <900000>; };};
dts 添加完重新编译烧录后,即可用 2.2.1 的命令固定频率。
希望开机后不输入命令、直接固定频率,需要同时改 dmc 节点的 system-status-freq、auto-min-freq、auto-freq-en 三项。以固定 666MHz 为例:
/* dfi 必须为 okay(dmc 依赖 dfi,dfi disabled 会导致 dmc 无效) */&dfi { status = ”okay”;};&dmc { status = ”okay”; ... system-status-freq = < /* system status freq(KHz) */ SYS_STATUS_NORMAL 666000 /* 去掉其他所有场景 */ /* SYS_STATUS_REBOOT 528000 SYS_STATUS_SUSPEND 200000 SYS_STATUS_VIDEO_1080P 200000 SYS_STATUS_VIDEO_4K 600000 SYS_STATUS_VIDEO_4K_10B 800000 SYS_STATUS_PERFORMANCE 800000 SYS_STATUS_BOOST 400000 SYS_STATUS_DUALVIEW 600000 SYS_STATUS_ISP 600000 */ >; ... auto-min-freq = <666000>; /* auto-freq-en 要为 0,否则会动态变频 */ auto-freq-en = <0>;};
DDR 固定频率要点:
auto-freq-en = <0>system-status-freq 只留 SYS_STATUS_NORMAL,并设为目标频率(其他场景全部注释掉)auto-min-freq- 若目标频率超出 OPP 表,需先在
dmc_opp_table 中添加对应频率电压(见 2.2.2)
2.3 DDR 相关章节索引
- DDR 开发指南 1.14 如何关闭 DDR 的负载变频功能,只留场景变频(
auto-freq-en = <0>) - DDR 开发指南 1.13 如何修改 DDR 某个频率对应的电压(
dmc_opp_table 的 opp-microvolt) - DDR 开发指南 1.16 如何查看 DDR 带宽利用率
- DDR 开发指南 1.18 如何确定 DDR 能运行的最高频率
三、操作速查汇总
| | |
|---|
| | |
| | echo performance > /sys/.../policy*/scaling_governor |
| | governor=userspace |
| | kernel defconfig 加 CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y |
| | dmc(及 dfi)节点 status="okay",RK3576 检查 center-supply/mem-supply |
| | dmc(及 dfi)节点 status="disabled" |
| | governor=userspace + userspace/set_freq(Hz),频率需在 available_frequencies |
| | dts dmc_opp_table 增加 opp-hz + opp-microvolt |
| | system-status-freq 只留 SYS_STATUS_NORMAL + auto-min-freq=目标频率 + auto-freq-en=<0> |
命令速查
# CPU:查看 / 修改cat /sys/devices/system/cpu/cpufreq/policy*/scaling_available_governorscat /sys/devices/system/cpu/cpufreq/policy*/scaling_available_frequenciescat /sys/devices/system/cpu/cpufreq/policy*/scaling_cur_freq# KHzfor g in /sys/devices/system/cpu/cpufreq/policy*/scaling_governor; do echo performance > ”$g”; done# DDR:查看 / 修改cat /sys/class/devfreq/dmc/available_frequencies# Hzcat /sys/class/devfreq/dmc/load# 形如 11@396000000Hz,11 为当前带宽利用率(%)echo userspace > /sys/class/devfreq/dmc/governorecho > /sys/class/devfreq/dmc/userspace/set_freq# Hz