首页/目录/全部文章

全部文章

八个专题的源码、算法与协议笔记都在这里。

笔记列表

并发、锁、寄存器写与生命周期

并发、锁、寄存器写与生命周期

1. Core锁

  • controller/consumer全局表由 mutex保护;
  • controller、consumer和map分别有全局mutex,controller还有自身mutex;
  • pin mux owner和GPIO owner在 Core中记录;
  • map注册/注销需遵守引用关系。

pinctrl_select_state()的commit路径并不持有pctldev->mutex,而GPIO direction/config路径会持有;两者缺少统一大锁,consumer必须在设备层串行化状态切换,避免与GPIO操作竞态。

2. Rockchip锁

gpio-rockchip.c的每个GPIO bank用raw spinlock保护GPIO/IRQ寄存器;pinctrl侧deferred output另有mutex。Syscon regmap负责pad寄存器访问序列化。

3. Write-mask

Rockchip GRF/IOC通常高16位作为低16位的写使能,可避免普通 read-modify-write竞态。跨16位边界字段或特殊寄存器仍需 driver单独处理。

4. Ordering

输出功能切换的安全顺序依设备:

1
2
3
4
先设置安全输出值/方向
再切 mux
或先切 GPIO
再设置方向和值

Rockchip deferred output用于协调 pinconf output与 GPIO bank尚未probe的时序。

5. IRQ并发

IRQ mask/type/ack在spinlock/irqchip约束下执行。RK3588 GPIO V2使用原生both-edge;旧版GPIO的软件polarity翻转才存在采样竞态。

6. Clock

GPIO bank register访问依赖 PCLK;debounce依赖 DBCLK。Runtime/system PM不能在仍有 IRQ/GPIO操作时关闭必要 clock。

7. Probe顺序

Pinctrl controller早期注册;GPIO bank为子节点并关联共同数据。Consumer可能 deferred probe直到 controller/map可用。

8. Remove

SoC pinctrl通常常驻。模块卸载需无 active consumer/GPIO/IRQ;生产内核宜 built-in,防止基础 pins在运行中失去管理。

9. Firmware

Bootloader先配置 pins,Linux接管时 default state会覆盖。若 Linux没有描述某 pin,它可能保持 firmware值,但这不是稳定ABI,休眠/复位后可能变化。

10. Direct register access

用户态 /dev/mem或其它驱动直接写 IOC会绕过 ownership、锁和状态缓存,造成不可诊断竞态,禁止用于产品方案。

RK3588 Pinctrl 调试、冲突排查与安全

RK3588 Pinctrl 调试、冲突排查与安全

1. Debugfs

挂载:

1
2
mount -t debugfs none /sys/kernel/debug
ls /sys/kernel/debug/pinctrl

常用文件:

1
2
3
4
5
6
7
pins
pingroups
pinmux-functions
pinmux-pins
pinconf-pins
pinconf-groups
pinctrl-maps

实际目录名由 controller device决定。

2. GPIO

1
2
3
gpioinfo
cat /sys/kernel/debug/gpio
cat /proc/interrupts

gpioinfo显示 consumer和方向,但不完整显示外设 mux;需结合 pinctrl debugfs。

3. DT

1
2
dtc -I fs -O dts /sys/firmware/devicetree/base > /tmp/running.dts
dmesg | grep -Ei 'pinctrl|gpio|defer|conflict'

核对运行 DTB,不只看源码目录中的某个板型。

4. 冲突排查

1.确定异常信号和物理 pin;
2.转换 bank/port/index;
3.查看 pinmux owner;
4.搜索最终 DTS全部引用;
5.确认两个 consumer是否均 enabled;
6.核对 M0/M1 route;
7.核对 pull/drive/VCCIO;
8.检查 bootloader与 sleep state;
9.示波器验证电平/边沿。

5. 常见现象

现象 可能原因
probe成功但总线无波形 pinctrl缺失/错误route
GPIO set无效 pin仍为外设mux或被占用
启动后串口消失 default state覆盖debug UART
suspend不能唤醒 sleep mux/pull或IRQ wake错误
GPIO IRQ风暴 floating/polarity/debounce错误
SD高速失败 drive、VCCIO、时序或布线
I2C卡低 mux错误、无外部上拉或设备拉低

6. 构建检查

1
2
make ARCH=arm64 dtbs_check
make ARCH=arm64 W=1 drivers/pinctrl/

本树 RK3588 mux 11/12与 binding最大10有已知不一致,schema告警应通过更新 binding解决并核对硬件。

7. 安全边界

Pinctrl不是访问控制系统。错误或恶意配置可:

-禁用 console/JTAG策略;
-拉动 reset/power-enable;
-争用总线;
-破坏存储访问;
-造成外部器件异常;
-绕过板级安全假设。

限制 /dev/mem、debugfs和GPIO设备权限;敏感 pins由 kernel driver占用并通过 locked-down DT/boot chain管理。

8. 量产原则

-以原理图和 TRM为准;
-每个 enabled外设明确 default/sleep;
-关键控制线定义安全上电状态;
-不要把开发板 pin group机械复制到不同PCB;
-对高速信号做电气测量;
-保留运行 DTB和 pinctrl dump作为版本证据。

Pinctrl 子系统架构与源码总览

Pinctrl 子系统架构与源码总览

1. 三项职责

1
2
3
pinctrl: 描述 pin和group
pinmux : 在GPIO/外设function之间选择
pinconf: 配置pull/drive/input/output/schmitt等电气属性

GPIO负责读写和中断;Pinctrl负责 pad复用/电气状态,二者通过 gpio-ranges连接。

2. 对象

  • pinctrl_dev:控制器实例;
  • pinctrl_desc:pins、ops、owner;
  • pinctrl:consumer handle;
  • pinctrl_state:default/sleep等状态;
  • pinctrl_setting:mux/config设置;
  • pinctrl_map:consumer、state到 controller/group/function/config的映射;
  • pinctrl_gpio_range:GPIO offset到 pin number。

3. Controller注册

1
2
3
4
5
6
7
8
devm_pinctrl_register(desc, driver_data)
-> pinctrl_register
-> pinctrl_init_controller
-> register pins
-> create pinctrl_dev
-> pinctrl_enable
-> hog maps
-> add controller list/debugfs

新驱动更推荐 devm_pinctrl_register_and_init()后在硬件准备完成时显式pinctrl_enable();本树Rockchip仍使用上述旧的一体式接口。

4. Consumer

1
2
3
4
5
6
7
8
devm_pinctrl_get(dev)
-> create handle
-> parse DT mappings
-> states/settings
pinctrl_lookup_state("default")
pinctrl_select_state()
-> mux enable
-> pinconf apply

Driver Core在 probe前由 pinctrl_bind_pins()自动选择 init/default。

5. Device Tree

Consumer:

1
2
3
pinctrl-names = "default", "sleep";
pinctrl-0 = <&uart2m0_xfer>;
pinctrl-1 = <&uart2_sleep>;

Rockchip group:

1
rockchip,pins = <bank pin mux &config>;

6. RK3588

RK3588由两个驱动协作:

  • pinctrl-rockchip.c:pinctrl、IOMUX、pull/drive/schmitt;
  • drivers/gpio/gpio-rockchip.c:五个GPIO bank、方向/数据、IRQ和GPIO PM。

IOMUX和pad config位于IOC syscon区域,GPIO data/IRQ位于各bank MMIO。RK3588没有route/recalced/slew表;GPIO0 B4–D7的高mux功能由PMU2/BUS双IOMUX路径表达。

7. 配置

PINCTRL_ROCKCHIP默认随 ARCH_ROCKCHIP启用,并 select GPIOLIB、PINMUX、GENERIC_PINCONF、OF_GPIO和 IRQ support。RK805/RK806 PMIC还有独立 pinctrl/GPIO driver。

8. 风险

错误 mux可失去 console、存储、PMIC、PCIe reset或显示;错误 pull/drive/IO voltage可能造成信号完整性问题甚至硬件损伤。

Linux 6.1 Pinctrl 文档索引

Linux 6.1 Pinctrl 文档索引

源码:rk3588/kernel-6.1/drivers/pinctrl/

文档 内容
Pinctrl子系统架构与源码总览.md Core、mux、config和GPIO关系
源码目录与控制器索引.md 文件、Kconfig、平台驱动
01-Pinctrl-Core对象注册与生命周期.md controller/consumer/state/map
02-Pinmux功能组与GPIO所有权.md function/group、strict、gpio range
03-Pinconf通用参数与电气属性.md bias、drive、schmitt、output
04-DeviceTree映射与状态选择.md pinctrl-0、rockchip,pins、hog
05-设备Probe休眠与状态切换.md default/init/sleep/idle
06-Rockchip-Pinctrl驱动架构.md GRF、banks、ops和probe
07-RK3588-IOMUX-Pull-Drive-Schmitt.md IOC寄存器布局
08-RK3588-GPIO中断与Debounce.md gpiochip、irqchip、双边沿
09-RK3588引脚组与外设复用.md UART/I2C/SPI/PWM/存储等
10-并发锁寄存器写与生命周期.md regmap、write-mask和锁
11-RK3588调试冲突排查与安全.md debugfs、gpioinfo、冲突和安全

RK3588由 rockchip,rk3588-pinctrl驱动,包含 GPIO0–GPIO4五个32-pin bank,共160个 pin编号。

drivers/pinctrl 源码目录与控制器索引

drivers/pinctrl 源码目录与控制器索引

Core文件

文件 作用
core.c controller/consumer/state/map
pinmux.c function/group和mux ownership
pinconf.c pin/group config
pinconf-generic.c 通用参数、DT解析、debug
devicetree.c pinctrl-N到 maps
pinctrl-utils.c map内存辅助

Rockchip

  • pinctrl-rockchip.c:SoC pinmux/pinconf;
  • pinctrl-rockchip.h:bank/register/SoC结构;
  • pinctrl-rk805.c
  • pinctrl-rk806.c

更准确地说,pinctrl-rockchip.c实现SoC pinmux/pinconf,GPIO data/IRQ/debounce位于目录外的 drivers/gpio/gpio-rockchip.c。RK3588没有单独 pinctrl-rk3588.c,pinctrl数据表和算法内嵌于通用Rockchip文件。

其它平台

目录约500文件,包括 Qualcomm、Samsung、Tegra、Renesas、Sunxi、Intel、STM32等。它们不参与 RK3588构建。

Makefile

1
2
3
4
5
6
core.o + pinctrl-utils.o
PINMUX -> pinmux.o
PINCONF -> pinconf.o
GENERIC_PINCONF -> pinconf-generic.o
OF -> devicetree.o
PINCTRL_ROCKCHIP -> pinctrl-rockchip.o

Kconfig

PINCTRL_ROCKCHIP

  • depends ARCH_ROCKCHIP/COMPILE_TEST;
  • depends OF;
  • select GPIOLIB;
  • select PINMUX;
  • select GENERIC_PINCONF;
  • select GENERIC_IRQ_CHIP;
  • select MFD_SYSCON;
  • select OF_GPIO;
  • default ARCH_ROCKCHIP。

主 defconfig只显式出现 RK805/RK806 pinctrl,但 SoC pinctrl由 ARCH_ROCKCHIP默认选中,不能因文本未出现就判断关闭。

DT文件

  • controller binding:rockchip,pinctrl.yaml
  • GPIO bank binding:rockchip,gpio-bank.yaml
  • pin definitions:rk3588s-pinctrl.dtsi
  • config nodes通常来自公共 Rockchip pinctrl include。

Binding差异

当前 binding对 mux字段声明最大10,但 rk3588s-pinctrl.dtsi中存在 mux 11/12。说明该厂商树的 schema与RK3588数据未完全同步;应以驱动和芯片 TRM验证,同时修订 schema,而非删除有效组。

Thermal Core 对象、注册与更新路径

Thermal Core 对象、注册与更新路径

1. Zone注册

现代路径:

1
thermal_zone_device_register_with_trips()

OF sensor driver通常调用 devm_thermal_of_zone_register()thermal_of.c 找到引用该 sensor/index的 zone,解析 trips和 cooling maps后创建 zone。

2. Zone ops

核心回调:

  • get_temp;
  • set_trips;
  • get_trend;
  • set_emul_temp;
  • change_mode;
  • bind/unbind(legacy)。

RK TSADC实现 get_temp和 set_trips。

3. Cooling device注册

1
2
thermal_cooling_device_register()
devm_thermal_of_cooling_device_register()

ops:

  • get_max_state;
  • get_cur_state;
  • set_cur_state;
  • power2state/state2power/get_requested_power(power actor可选)。

4. 绑定

thermal_zone_bind_cooling_device() 创建 thermal_instance

  • trip index;
  • lower/upper;
  • weight;
  • target;
  • initialized;
  • zone/cdev双向 list/RB tree关联。

同一 cdev可绑定多个 zone/trip。

5. Update

thermal_zone_device_update(tz, event)

  1. 检查 enabled;
  2. get_temp;
  3. 更新 last_temperature;
  4. netlink/trace notification;
  5. 遍历 trips;
  6. critical/hot处理;
  7. governor throttle;
  8. 安排下一次 polling。

6. Cooling state聚合

多个 instance对同一 cdev提出 target,__thermal_cdev_update() 聚合为最终 state并调用 set_cur_state()。一个 zone降温不保证 cdev立即解除限制,另一 zone可能仍要求高 state。

7. Polling

  • polling_delay:正常;
  • passive_delay:passive trip active期间;
  • delayed work;
  • sensor IRQ可主动 update;
  • set_trips可编程硬件 window减少轮询。

8. Mode/policy

zone可 enabled/disabled,policy决定 governor。切换 governor会 unbind旧策略、bind新策略并重新 update。

9. 生命周期

unregister时:

  • cancel polling;
    -解除 cooling instances;
    -移除 sysfs/netlink/hwmon;
    -释放 ID;
    -等待活动引用/锁;
  • driver停止 IRQ后释放 sensor。

10. 单位

温度统一 milli-Celsius,power通常 milliwatt,state是无量纲离散等级。driver返回错误不能伪造低温。

Device Tree 温区、Trip 与 Cooling Map

Device Tree 温区、Trip 与 Cooling Map

1. 结构

1
2
3
4
5
6
7
8
9
10
thermal-zones {
zone-name {
polling-delay-passive = <...>;
polling-delay = <...>;
thermal-sensors = <&sensor index>;
sustainable-power = <...>;
trips { ... };
cooling-maps { ... };
};
};

2. Sensor provider

TSADC提供:

1
#thermal-sensor-cells = <1>

argument是 channel index。RK3588使用0~6。

3. Trips

1
2
3
4
5
trip {
temperature = <85000>;
hysteresis = <2000>;
type = "passive";
};

2°C hysteresis意味着上穿85°C激活,下降到约83°C以下才清除,具体状态由 Core的 trip crossed逻辑处理。

4. Cooling map

1
2
3
4
5
map {
trip = <&target>;
cooling-device = <&cpu_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
contribution = <1024>;
};

两个 cells为 lower/upper cooling state。NO_LIMIT由注册后设备最大状态替换/限制。

5. 解析

thermal_of.c

  1. 找到引用 sensor phandle/index的 zone;
  2. 解析 delays、sustainable power;
  3. 解析 trips;
  4. 注册 zone;
  5. cooling device出现时按 phandle匹配;
  6. 创建 instance。

probe顺序不同可后续绑定。

6. Writable trips

主配置启用 THERMAL_WRITABLE_TRIPS,但只有 zone注册 mask允许的 trip才可写;Kconfig只是允许能力,不代表所有 trip_point_*_temp 可写。

7. RK3588 soc zone

  • polling 1000ms;
  • passive polling 20ms;
  • sustainable power 2100mW;
  • 75°C passive threshold,无 cooling map;
  • 85°C passive target,绑定三组 CPU和 GPU;
  • 115°C critical。

在本版 power_allocator 中,第一个 passive trip作为 trip_switch_on,最后一个 passive trip作为 trip_max_desired_temperature。因此75°C是开启分配器的 switch-on温度,85°C是控制目标;75°C即使没有直接 cooling map也有明确作用。

8. 其它 zones

bigcore0/1、littlecore、center、GPU、NPU仅有115°C critical trip。它们提供局部热点安全监控,但公共 DTS没有各自降频 cooling map。

9. 常见错误

  • channel index错;
  • trip单位误写成°C而不是m°C;
  • cooling phandle无 #cooling-cells
  • lower > upper;
  • missing Energy Model/OPP;
  • zone node disabled;
  • sustainable power不符合板级散热;
  • hysteresis过小产生抖动。

Thermal Governor 算法详解

Thermal Governor 算法详解

1. 作用

Governor不读取寄存器,也不直接改频率;它根据 zone温度/trip/trend计算各 thermal_instance.target,再由 cooling device执行。

2. Step-wise

温度上升且越过 trip时逐步增加 cooling state;下降时逐步解除。优点简单稳健,缺点响应/解除速度依赖 update周期和 step。

3. Fair-share

根据 zone温度相对 trip的 level、cdev最大状态和 contribution分配状态。适合多个 actor粗粒度分担,但不是精确功率模型。

4. Bang-bang

两态控制:

1
2
above trip -> max/on
below trip-hysteresis -> min/off

适合风扇、继电器,不适合需要平滑 DVFS的场景。

5. User-space

内核发送 trip事件,用户态写 cdev state。优点策略灵活;缺点 daemon崩溃/调度延迟可能失控,critical trip仍应留在内核/硬件。

6. Power allocator

PID型功率预算:

1
2
error = control_temp - current_temp
budget = sustainable_power + P + I + D-like terms

再按各 power actor requested power/weight分配预算并换算 cooling state。

要求:

  • Energy Model/OPP;
  • cdev power API;
    -合理 sustainable power;
    -稳定 update interval;
    -正确 actor power model。

7. RK3588默认

主配置默认 power_allocatorsoc-thermal 的 2100mW sustainable power是控制核心参数。该值是平台热设计输入,不是 SoC瞬时实测功耗。

8. 参数

power allocator sysfs可能提供:

  • k_po;
  • k_pu;
  • k_i;
  • k_d;
  • integral_cutoff;
  • sustainable_power。

实际可见性取决于版本和 policy。

9. 调参

  1. 先验证温度与 cooling actor;
  2. 测稳态可持续总功率;
  3. 设 control trip;
  4. 从保守增益开始;
  5. 测升温、过冲、恢复;
  6. 覆盖环境高温和风扇故障;
  7. 记录频率、power budget和温度。

10. 风险

  • gain过大:频率/温度振荡;
  • gain过小:过冲至 critical;
  • sustainable power过高:长期升温;
    -过低:无谓降频;
    -多个独立 controller同时控同一 actor:策略冲突;
  • update周期过短:噪声和开销。

CPUFreq、Devfreq 与功率 Cooling

CPUFreq、Devfreq 与功率 Cooling

1. Cooling state

state 0通常代表无额外限制,state增大代表更强限制。具体频率表由 driver生成,不能假设 state等于频率索引的固定方向。

2. CPUFreq cooling

1
2
3
4
5
6
7
cpufreq_cooling_register()
-> collect policy/frequency/EM
-> thermal_cooling_device

set_cur_state()
-> update max frequency QoS/clip
-> cpufreq policy transition

同一 policy的 CPUs共享 cooling device。

3. CPU power actor

有 Energy Model时可:

  • state2power;
  • power2state;
  • get_requested_power;
  • static/dynamic power估算。

power allocator据此按 mW分配。

4. Devfreq cooling

适用于 GPU/NPU等 devfreq设备:

1
2
3
4
thermal state
-> devfreq cooling
-> max frequency constraint
-> devfreq governor选择不超过上限的 OPP

power extension需要 OPP/EM和兼容 devfreq governor。

5. RK3588 DTS

soc zone cooling map引用:

  • cpu_l0
  • cpu_b0
  • cpu_b2
  • gpu

NPU未在该 map内,即使有 npu-thermal zone,也不表示公共 DTS由 Thermal Core直接限制 NPU。

6. Cooling vs DVFS governor

Thermal设置上限,schedutil/simple_ondemand等在上限内选频。看到低频需区分:

  • workload不足;
  • thermal cap;
  • power/OPP constraint;
  • userspace QoS;
  • regulator;
  • scheduler。

7. Pressure

CPU thermal pressure向 scheduler描述因热限制损失的 capacity,帮助任务放置。它不是实际温度,也不是独立 cooling设备。

8. Idle cooling

CPU idle cooling通过注入 idle限制计算能力,依赖 IDLE_INJECT。本主配置未显式启用 CPU_IDLE_THERMAL,常规路径是 cpufreq cooling。

9. 风扇

PWM fan cdev把 thermal state映射到 duty levels。RK厂商 pwm-fan还可能走 system monitor notifier而不是 generic cdev;需避免和 Thermal governor双控。

10. 验证

同时观察:

1
2
3
4
5
6
thermal zone temp
cooling cur_state
cpufreq scaling_cur/max_freq
devfreq cur/max_freq
thermal pressure
workload throughput

只看温度无法证明 cooling动作正确。

Sysfs、Netlink、Hwmon 与用户接口

Sysfs、Netlink、Hwmon 与用户接口

1. Sysfs

1
2
3
4
5
6
7
8
/sys/class/thermal/thermal_zoneN/
type temp mode policy available_policies
trip_point_N_temp/type/hyst
passive polling_delay

/sys/class/thermal/cooling_deviceN/
type max_state cur_state
stats/...

具体文件随配置、ops和 governor变化。

2. 编号

thermal_zoneN/cooling_deviceN编号动态分配。程序按 type和 sysfs device关系识别,不能写死编号。

3. Writable

主配置允许 writable trips,但 zone mask仍决定每个 trip是否可写。写 mode/policy/trip/cdev可能破坏保护,权限必须收紧。

4. Emulation

THERMAL_EMULATION 提供 emul_temp。本主配置未显式启用。它适合验证策略,但量产开放会让用户伪造低温绕过软件 protection。

Thermal family提供:

  • zone/cdev/governor discovery;
  • temperature;
  • trip crossing;
  • cdev state;
  • governor change;
  • events multicast。

相较 uevent信息更结构化。是否存在取决于 THERMAL_NETLINK最终配置。

6. Hwmon bridge

THERMAL_HWMON 可把 zone温度暴露为 hwmon tempN_input。这只是另一观测 ABI,不复制 governor。RK3588是否出现 hwmon节点由最终配置和注册路径决定。

7. Uevent

user_space governor使用 uevent提示 crossing。用户 daemon失联时不会自动给出复杂 fallback,因此仍需 critical/TSHUT。

8. Trace

thermal tracepoints可观测:

  • temperature;
  • cooling state;
  • power allocator;
  • CPU frequency cooling;
  • thermal pressure。

适合定位振荡和响应延迟。

9. Android

Android thermal HAL可能读取 sysfs或 netlink/厂商接口,并对 framework报告 throttling severity。内核 policy与 HAL policy不应互相覆盖同一 cdev。

10. 权限

只读温度可开放;以下应 root-only:

  • trip temperature;
  • emul_temp;
  • policy;
  • mode;
  • cooling cur_state;
  • PID coefficients;
  • sustainable power。