Thermal Management 使用参考¶
REVISION HISTORY¶
| Revision No. | Description |
Date |
|---|---|---|
| 1.0 | 10/08/2026 |
1. 概述¶
SGS thermal management 子系统是维持 SoC 工作在安全温度范围内的软件层。它构建在标准 Linux thermal 框架之上,复用片上 Tsensor 作为温度源。
默认策略是带滞回的双状态循环(详见第 3 章):温度低于 115°C 时 CPU 可使用全 DVFS 范围;温度一旦达到 115°C 即被强制降到最低 OPP,只有当温度回落到 100°C 以下时才恢复全 DVFS 范围。
本子系统将 Linux thermal 的三个概念串联起来:
- 一个绑定到 SGS Tsensor 的 thermal zone(
soc-thermal)。 - 一组 trip point(被动降频点 + 临界关机点)。
- 由自定义 governor
sgs_highest驱动的 cooling device(CPU DVFS 和 IPU 加速器),在跨越 trip 时被调用。
2. 关键字说明¶
-
Thermal zone(热区)
一个逻辑对象,聚合了一个温度传感器、一组 trip point 和绑定到这些 trip 的 cooling device。具体定义见
<Kernel>/Documentation/devicetree/bindings/thermal/thermal-zones.yaml。 -
Trip point(触发点)
thermal zone 内部的温度阈值。每个 trip 包含温度、滞回值和类型(
passive、critical、hot等)。 -
Cooling device(降温设备)
被触发后可以散热的设备。mhera 上绑定到 SoC thermal zone 的 cooling device 有两个:CPU DVFS(通过降低 CPU 频率/电压降频)和 IPU 加速器(通过降低 IPU 时钟降频)。IPU 节点在 DTS 中标签为
dla,因此 cooling-device 引用写作<&dla ...>。 -
Governor(策略模块)
决定当 trip 被跨越时 cooling device 应处于哪个 cooling state 的策略模块。内核原生提供
step_wise、power_allocator、user_space等多个 governor;SGS 在此基础上新增了sgs_highest,并在 mhera 上选为默认 governor。 -
sgs_highestgovernorSGS 贡献的双点 governor:一旦到达 trip 温度就立即把 cooling device 推到上界(
instance->upper),只有当温度回落到trip_temp - hysteresis以下时才释放回 state 0。详细行为见 3.1 节。
3. 功能描述¶
3.1. 双状态降频策略¶
下图说明了 mhera 默认的 thermal 策略。阈值取自 arch/arm64/boot/dts/sgs/mhera.dtsi(target trip = 115000 m°C,hysteresis = 15000 m°C):
Full DVFS Range Lowest Frequency
(No Throttling) (Throttled)
+--------------+ +--------------+
| | Temp >= 115 C | |
| CPU runs | ----------------> | CPU runs |
| at any freq | | at min freq |
| | Temp <= 100 C | |
| | <---------------- | |
+--------------+ +--------------+
(State 0) (State MAX)
故意选取了 15°C 这个较大的滞回值,避免温度在 trip 附近反复震荡 —— 之前 10°C 的滞回会让 CPU 在 115°C 附近反复进出降频状态。整个循环包含三个阶段:
- 温度低于 115°C 时 cooling device 停在 state 0 —— cpufreq 表中所有 OPP 均可使用。
- 到达 115°C 时,
sgs_highestgovernor 把 cooling device 一次性推到上界(instance->upper)。对 CPU DVFS 而言,upper对应 OPP 表中的最低频率,因此 CPU 被钉在最低 OPP。 - CPU 会停在最低 OPP,直到温度回落到
115 - 15 = 100°C,governor 才把 cooling device 释放回 state 0。
3.2. 临界 trip¶
另设一个 125°C 的 critical trip,会触发内核的 thermal 关机路径(thermal_zone_device_check() → orderly poweroff)。该 trip 的 hysteresis = <0>,因为它是一刀切的硬关机点,不是恢复点。
3.3. 内核态温度 API¶
Tsensor 驱动导出了一个辅助函数,任何树内内核模块都可以调用它读取当前 SoC 温度:
其内部查找 soc-thermal zone,读取温度,并以摄氏度(整数)返回。详见 7.1 节。
4. 硬件连接介绍¶
无。Thermal management 复用片上 Tsensor,不涉及任何外部管脚或元件。
5. Uboot 用法介绍¶
不支持。Thermal management 完全运行在 kernel 中。
6. Kernel 用法介绍¶
6.1. Kernel Config 配置¶
menuconfig 中相关选项分布在两个菜单下:
Device Drivers --->
[*] Thermal drivers --->
[*] Enable writable trip points (THERMAL_WRITABLE_TRIPS)
[*] Generic cpu cooling support (CPU_THERMAL)
() Default Thermal governor ---> sgs_highest
(THERMAL_DEFAULT_GOV_SGS_HIGHEST)
[*] sgs_highest (THERMAL_GOV_SGS_HIGHEST)
[*] step_wise (THERMAL_GOV_STEP_WISE)
[*] User_space thermal governor (THERMAL_GOV_USER_SPACE)
[*] Sgs SoC platform drivers --->
<*> SGS T-sensor driver (SGS_TSENSOR)
每个发布的 mhera defconfig 中均显式打开了以下配置(见 arch/arm64/configs/mhera_ssm004a_*_defconfig):
CONFIG_THERMAL_DEFAULT_GOV_SGS_HIGHEST=y
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_GOV_SGS_HIGHEST=y
CONFIG_CPU_THERMAL=y
CONFIG_THERMAL_WRITABLE_TRIPS=y
CONFIG_SGS_TSENSOR=y
CONFIG_THERMAL_DEFAULT_GOV_SGS_HIGHEST会让drivers/thermal/thermal_core.h中的DEFAULT_THERMAL_GOVERNOR宏展开为"sgs_highest"。如果未设置,内核会回退到原生默认 governor(step_wise),后者并不实现 3.1 节描述的策略。
6.2. DTS 配置¶
Thermal management 需要两部分设备树:sgs_thermal 传感器节点(已在 Tsensor 文档中说明)和 thermal-zones 块。
6.2.1. CPU 和 IPU 节点 —— 声明为 cooling device¶
在 CPU 节点中加入 #cooling-cells = <2>,cpufreq 驱动才能将其注册为 cooling device:
cpu0: cpu@0 {
compatible = "arm,cortex-a53";
clocks = <&CLK_cpu_pll>, <&CLK_cpu_pll>;
operating-points-v2 = <&cpu0_opp_table>;
#cooling-cells = <2>; /* CPU_THERMAL 必需 */
reg = <0x000>;
};
sgs cpufreq 驱动在其 cpufreq_driver 结构体上设置了 .flags = CPUFREQ_IS_COOLING_DEV,因此只要存在该 cell,内核就会自动把 CPU 注册为 cooling device。
IPU 加速器(DTS 节点标签为 dla,compatible = "sgs,dla")以同样方式注册为第二个 cooling device —— 给节点加上 label 并添加 #cooling-cells = <2>:
dla: dla {
compatible = "sgs,dla";
interrupts = <GIC_SPI INT_IRQ_IPU2TOP0 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI INT_IRQ_IPU2TOP1 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&CLK_ipupll_clk>;
status = "ok";
#cooling-cells = <2>; /* CPU_THERMAL 必需 */
};
当 trip 被跨越时,sgs_highest governor 会把所有绑定的 cooling device 都推到各自上界,因此 CPU 被钉在最低 OPP 的同时 IPU 也会被降频。
6.2.2. thermal-zones 块¶
thermal_zones: thermal-zones {
soc_thermal: soc-thermal {
polling-delay-passive = <100>;
polling-delay = <1000>;
thermal-sensors = <&sgs_thermal 0>;
trips {
target: trip-point-0 {
temperature = <115000>; /* mC */
hysteresis = <15000>; /* mC,100 C 时恢复 */
type = "passive";
};
soc_crit: soc-crit {
temperature = <125000>; /* mC */
hysteresis = <0>;
type = "critical";
};
};
cooling-maps {
map0 {
trip = <&target>;
cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&dla 0 1>;
};
};
};
};
thermal 驱动支持的属性:
| 属性 | 说明 |
|---|---|
| thermal-sensors | 温度传感器的 phandle,此处为 sgs_thermal 节点。 |
| polling-delay | 没有被动 trip 触发时的轮询周期(ms)。 |
| polling-delay-passive | 被动 trip 触发后的轮询周期(ms)。 |
| trips/temperature | trip 阈值,单位 millicelsius。 |
| trips/hysteresis | governor 释放 cooling device 前需要回落的温度差。 |
| trips/type | passive 表示降频点,critical 表示关机点。 |
| cooling-maps | trip 与 cooling device 的绑定。每条写作 <&dev min_state max_state>;THERMAL_NO_LIMIT 让 governor 任意选取设备支持的 state。CPU 用 THERMAL_NO_LIMIT THERMAL_NO_LIMIT(全 DVFS 范围),IPU 用 0 1(两个 state:0 = 满速,1 = 降频)。 |
实际的 mhera.dtsi 用
#ifdef CONFIG_CPU_THERMAL把trip-point-0和cooling-maps块包了起来,因此若CONFIG_CPU_THERMAL被关闭,编译出的 DTB 里只剩criticaltrip —— 没有 DVFS 降频。criticaltrip 始终存在,是最后一道防线。
完整的 thermal-zone 绑定语法请参考:<Kernel>/Documentation/devicetree/bindings/thermal/thermal-zones.yaml
6.3. Padmux 配置¶
无。
6.4. 模块使用介绍¶
6.4.1. SYSFS —— 读取温度¶
Linux thermal 框架为每个 thermal zone 暴露一组 sysfs 节点。SoC zone 的名称为 soc-thermal:
# 读取当前温度(millicelsius)
cat /sys/class/thermal/thermal_zone0/temp
# 读取 type 字符串
cat /sys/class/thermal/thermal_zone0/type
# -> soc-thermal
# 列出 cooling device 及其当前 state
cat /sys/class/thermal/cooling_device0/cur_state
cat /sys/class/thermal/cooling_device0/max_state
每个 trip 也有独立的 sysfs 属性,例如 /sys/class/thermal/thermal_zone0/trip_point_0_temp、/sys/class/thermal/thermal_zone0/trip_point_0_type。由于打开了 CONFIG_THERMAL_WRITABLE_TRIPS=y,这些节点运行时可写。
6.4.2. SYSFS —— 强制注入温度(调试用)¶
Tsensor 驱动在 thermal-zone 设备上注册了一个只写的 test_temp 属性。写入非零值(单位 millicelsius)后,驱动会把这个值当作温度上报,而不是真实的 Tsensor 读数。这样在一块实际上达不到 115°C 的板子上也能完整验证 thermal 策略:
# 强制 SoC 上报 120 C —— governor 应该把 CPU 钉在最低频
echo 120000 > /sys/class/thermal/thermal_zone0/test_temp
# 恢复真实 Tsensor 读数
echo 0 > /sys/class/thermal/thermal_zone0/test_temp
test_temp 仅用于 EVB 调试和自动化测试,对量产部署没有影响。
6.4.3. 运行时切换 governor¶
governor 可以按 zone 在运行时通过 sysfs 切换,便于在同一块板子上对比 sgs_highest 与 step_wise:
# 可选 governor 列表
cat /sys/class/thermal/thermal_zone0/available_policies
# 当前 governor
cat /sys/class/thermal/thermal_zone0/policy
# 切换到 step_wise
echo step_wise > /sys/class/thermal/thermal_zone0/policy
# 切回 sgs_highest
echo sgs_highest > /sys/class/thermal/thermal_zone0/policy
6.5. Sample code¶
6.5.1. 用户空间读取温度¶
6.5.2. 内核模块读取温度¶
#include <linux/thermal.h>
int soc_temp_degC(void)
{
struct thermal_zone_device *tzd;
int temp, ret;
tzd = thermal_zone_get_zone_by_name("soc-thermal");
if (IS_ERR(tzd))
return -ENODEV;
ret = thermal_zone_get_temp(tzd, &temp);
if (ret)
return ret;
return temp / 1000; /* millicelsius -> 摄氏度 */
}
或者直接调用 Tsensor 驱动导出的辅助函数:
7. API 参考¶
内核态 API 声明于 drivers/sgs_common/tsensor/drv/src/drv_tsensor_lnx.c,对任何依赖 SGS Tsensor 驱动的模块可用。
7.1. sgs_get_temp¶
-
功能
从
soc-thermalzone 读取当前 SoC 温度。 -
语法
int sgs_get_temp(void) -
参数
参数 说明 无 无 -
返回值
返回值 说明 N >= 0 当前 SoC 温度,单位摄氏度。 0 当找不到 soc-thermalzone 或thermal_zone_get_temp失败时返回。
8. FAQ¶
Q1:为什么需要 sgs_highest?内核不是已经有 step_wise 了吗?
step_wise 每个轮询周期只走一步,无法立即把 CPU 降到最低 OPP。要强制降到最低 OPP,cooling-device 绑定里需要硬编码 min_state/max_state,但 mhera 使用一张统一的 OPP 表,其有效长度由 cpufreq_cfg 根据芯片型号在运行时裁剪,DTS 中的硬编码范围无法跟随这种变化,因此需要一个总是直接跳到 instance->upper 的 governor。
Q2:滞回值为什么从 10°C 调到 15°C?
10°C(即 105°C 恢复)的滞回让 CPU 在阈值附近反复切换最低 OPP 和全 OPP 表,产生大量 thermal 事件,肉眼可见的频率抖动也很明显。15°C(100°C 恢复)在 EVB 上验证更稳定。
Q3:如果 CONFIG_CPU_THERMAL 关掉会怎样?
target 被动 trip 和 cooling-maps 块会从 DTB 中编译排除。只剩 125°C 的 critical trip,SoC 仍能在过温时关机,但不会有 DVFS 降频。mhera 默认 defconfig 全部打开了 CONFIG_CPU_THERMAL。
Q4:板子永远达不到 115°C,如何在 EVB 上验证策略?
用 test_temp 调试节点(6.4.2 节)注入伪造温度,然后观察 /sys/class/thermal/cooling_device0/cur_state 和 /sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq,确认 cooling state 和 CPU 频率按预期变化。