RK3588 启动阶段 `rockchip_panel_probe -19` 真实根因排查与修复实战

📅 2026/8/4 4:29:12 👁️ 阅读次数 📝 编程学习
RK3588 启动阶段 `rockchip_panel_probe -19` 真实根因排查与修复实战

适用场景:RK3588 平台,U-Boot 阶段初始化显示面板时,出现Cannot get reset GPIO: ... -19
关键词:U-Boot、Device Tree、GPIO Expander、PCA9535、运行时 DTB、分区提取、问题闭环。


一、问题现象

在启动日志中反复出现:

  • rockchip_panel_probe: Cannot get reset GPIO: rockchip_panel_probe -19

同时显示链路后续会出现多路 VP/plane 的打印,但面板相关初始化并不稳定。

很多同学第一反应会怀疑是:

  1. reset-gpios在 DTS 没配;
  2. defconfig 没生效;
  3. 编译参数不一致。

这些方向都要查,但这次问题的“真正根因”比它们更深一层。


二、先把日志和代码对齐

日志来自 U-Boot 面板驱动:

  • 驱动函数在rockchip_panel_probe()
  • 调用gpio_request_by_name(dev, "reset-gpios", ...)
  • 返回-19(即-ENODEV)后打印该报错

这意味着:

  • 不是简单“字符串打印错误”,而是GPIO provider 设备没有被成功获取/探测

三、第一阶段:排除“DTB 没配”这个误区

仅看源码 DTS 不够,必须看设备运行时实际使用的 DTB。
实操中,建议从设备分区提取resource后解包,拿到运行中的rk-kernel.dtb再分析。

在运行时 DTB 中确认到:

  1. 面板节点存在且status = "okay"
  2. 面板reset-gpios存在;
  3. 该 GPIO 指向的是一个 I2C GPIO 扩展器节点;
  4. 扩展器节点compatible = "nxp,pca9535"status = "okay"
  5. 扩展器父 I2C 控制器也是status = "okay"

结论:

  • 这不是“DTB 缺失 reset-gpios”;
  • 是“读取 reset-gpios 对应 provider 时失败”。

四、第二阶段:为什么看起来配置对了,还是报错?

排查过程中通常会同时遇到三类问题(容易互相干扰):

  1. 构建入口不规范,沿用旧.config,导致产物目标板型错误;
  2. 新增 GPIO Expander 驱动后,SPL 依赖没补齐导致构建失败;
  3. 即使构建通过,运行仍报-19,说明还有代码级问题。

前两类解决后,第三类仍存在,才是这次核心。


五、真正根因:两棵代码树在 pca953x 驱动实现不一致

对比发现:

  • 树 A(可用)中,pca953x_probe()使用chip->chip_addr获取从设备地址;
  • 树 B(报错)中,pca953x_probe()通过gd->fdt_blob + dev_of_offset()读取reg

在本问题对应的运行时 DT 上下文里,后者可能读到无效值(0),直接返回-ENODEV,最终传导为:

  • rockchip_panel_probe ... -19

这就解释了为什么“你看起来配的一样”,实际行为却不一样:

  • 根因不是配置文本本身,而是驱动实现差异 + DT 上下文差异

六、修复方案(最终可落地)

1)配置层(保证能编译并带上 expander 能力)

在目标板 defconfig 中确保:

  • CONFIG_DM_PCA953X=y
  • CONFIG_SPL_I2C_SUPPORT=y
  • CONFIG_DEFAULT_DEVICE_TREE指向目标板 DT

说明:如果启用了 PCA953X 但没有 SPL I2C 支持,常见会在 SPL 链接阶段出现dm_i2c_read/write未定义。

2)驱动层(关键修复)

drivers/gpio/pca953x_gpio.cpca953x_probe()中:

  • 不再通过gd->fdt_blob解析reg
  • 改为使用 DM 已解析的chip->chip_addr
  • 保留无效地址保护(0 直接报错)。

七、验证闭环(建议按此顺序执行)

  1. distclean后重新走目标板 defconfig;
  2. 完整编译并打包 U-Boot;
  3. 确认最终产物 FIT 描述是目标板,而不是默认 EVB;
  4. 刷机后拉取设备uboot_a与本地产物做哈希比对;
  5. 重新抓启动日志,确认rockchip_panel_probe -19是否消失。

八、这次排查的经验总结

  1. “改了 defconfig”不等于“产物一定生效”,要看.config与最终镜像元数据。
  2. 只看源码 DTS 容易误判,必须看运行时 DTB。
  3. -19这种错误很容易被误解成“节点没配”,但也可能是 provider probe 失败。
  4. 同平台不同代码树,最容易踩的是“同名配置、不同驱动实现”。

九、一页结论(可直接贴到问题单)

  • 现象:U-Boot 面板探测 reset GPIO 失败,报-19
  • 误区:不是 DTB 缺少reset-gpios
  • 根因:PCA953x 驱动在某代码树中使用gd->fdt_blobreg,在当前运行 DT 上下文下取值失效,导致 provider 返回-ENODEV
  • 修复:改为chip->chip_addr,并补齐CONFIG_DM_PCA953X + CONFIG_SPL_I2C_SUPPORT
  • 状态:已完成编译与目标板产物验证,刷机后可做日志回归关单。

十、附:建议的团队化排查模板

  1. 先定位日志打印函数与返回码来源。
  2. 同步核对:源码 DTS、打包产物 DTB、设备运行 DTB。
  3. 对比不同代码树同文件实现差异。
  4. 产物层做 FIT 元数据 + 分区哈希双校验。
  5. 形成“配置修复 + 代码修复 + 验证闭环”三段式结论。