当前位置:首页>Linux>Linux下CPU与DDR定频/变频的方法

Linux下CPU与DDR定频/变频的方法

  • 2026-10-11 06:13:30
Linux下CPU与DDR定频/变频的方法

一、CPU 频率管理

1.1 Linux 下 CPU 频率的几种方式及其作用

Linux 通过cpufreq 框架管理 CPU 频率,调频策略由governor决定。频率控制的几个层次(自底向上):

  1. driver / OPP 表:芯片支持哪些频率点(cpu-opp 节点,device tree 中定义)
  2. policy:每个 policy 对应一组同频的 CPU 核(RK3572 大小核有多个 policy),含 min/max 频率范围
  3. governor:决定在 min~max 之间如何选取频率(调频策略)
  4. 用户态 / sysfs:echo 写入,临时生效;要持久化需开机脚本或内核默认配置
governor
作用
适用场景
schedutil
与调度器联动,按实时调度负载动态调频(Linux 4.7+ 引入,ARM64 默认)
默认推荐,能效均衡
performance
固定在最高频,不调频
追求极致性能 / 定频
powersave
固定在最低频,不调频
最低功耗
userspace
由用户态指定目标频率(配合 scaling_setspeed)
调试 / 定频到具体频率
ondemand
按 CPU 负载跳变调频,负载上来立刻拉高频
老式平台
conservative
按负载渐进调频,频率平滑变化
追求调频平滑
interactive
基于输入事件交互式调频(旧 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 定频构建与验证

  1. 重编 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 属性来控制:

需求
配置
enable 变频
dmc 节点 status = "okay"
disable 变频
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 固定频率要点:

  1. auto-freq-en = <0>
    :关闭负载变频(否则会动态变频)
  2. system-status-freq
     只留 SYS_STATUS_NORMAL,并设为目标频率(其他场景全部注释掉)
  3. auto-min-freq
     设为目标频率
  4. 若目标频率超出 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 能运行的最高频率

三、操作速查汇总

目的
模块
操作
CPU enable 变频
CPU
默认即 schedutil 动态调频,无需改
CPU 临时定频(最高频)
CPU
echo performance > /sys/.../policy*/scaling_governor
CPU 临时定频(具体频率)
CPU
governor=userspace
 + scaling_setspeed(KHz)
CPU 永久定频
CPU
kernel defconfig 加 CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
DDR enable 变频
DDR
dmc(及 dfi)节点 status="okay",RK3576 检查 center-supply/mem-supply
DDR disable 变频
DDR
dmc(及 dfi)节点 status="disabled"
DDR 临时定频
DDR
governor=userspace
 + userspace/set_freq(Hz),频率需在 available_frequencies
DDR 添加新频率
DDR
dts dmc_opp_table 增加 opp-hz + opp-microvolt
DDR 永久定频
DDR
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

最新文章

随机文章