RK3568 MIPI DSI屏调试:uboot正常内核黑屏的软硬件全链路排查
RK3568 这块板子最近调 MIPI DSI 屏的时候遇到一个特别典型的启动异常uboot 阶段 logo 亮得好好的一跳到内核屏幕直接黑掉串口还看不出明显 panic。这种“一半好一半坏”的问题最磨人因为它涉及 uboot、内核 DRM、MIPI DSI 控制器、面板驱动和背光时序一整条链路。这篇文章就把我这次从现象到修复的完整排查过程写出来包括为什么 uboot 能亮而内核不能亮、怎么定位卡点、设备树怎么对齐、屏参和时序参数有哪些坑以及背光复位这几个“非驱动”环节要怎么处理。不管是 RK3568 还是其他瑞芯微平台遇到类似“uboot 有 logo、内核黑屏”的 MIPI 屏问题都可以照着这个思路走一遍。1. 从 uboot logo 到内核黑屏这条启动链路上到底发生了什么先说结论uboot 阶段能显示不等于内核阶段就一定能显示。RK3568 这类 SoC 的显示链路从上电到系统起来要经历两套完全独立的显示初始化体系。上电之后首先是 BootROM 加载 ubootuboot 自身带了一套独立的显示驱动。它会根据 uboot 设备树里的 panel 配置直接操作 MIPI DSI 控制器寄存器把初始化序列发给屏幕点亮背光然后显示 logo。这一阶段用的是 uboot 自己的代码和驱动模型跟内核完全是两回事。接下来内核启动此时显示子系统会重新初始化。内核 DRM/KMS 框架接管整个显示链路它会重新申请内存、重新初始化 DSI 控制器、重新匹配 panel 驱动、重新走一遍 panel 的 probe 和 prepare 流程。如果这一步任何环节出错就会出现“uboot 亮得好好的内核一上来就黑屏”的现象。很多人会问uboot 不是已经把屏点亮了吗为什么内核不能直接接着用原因很简单uboot 的显示资源在内核初始化时会被释放并重新申请内核不会信任 uboot 留下的任何寄存器状态全部重来。如果内核的设备树配置和 uboot 不一致比如屏参不对、compatible 不匹配、reset 引脚配置不一样那内核初始化的结果就和 uboot 完全不同黑屏就成了大概率事件。这个切换过程里常见的问题点我归纳了一下基本跑不出这几类内核设备树和 uboot 设备树的 panel 配置不一致包括 compatible、时序参数、lane 数、时钟频率内核没有正确匹配到 panel 驱动导致 panel probe 失败DSI 控制器在内核里初始化顺序问题或者 DSI 时钟配置不对背光、复位 GPIO 等电源时序问题导致面板处于未就绪状态内核 DRM 框架里连接器/面板状态机没走到 on 状态。所以遇到这类问题第一步不是改代码而是先搞清楚内核到底卡在哪个环节。后面我会按实际排查顺序来讲先看日志再查设备树再查驱动参数最后查时序。2. 先抓串口日志再动手三分钟定位“黑屏到底卡在哪一步”RK3568 调试显示问题串口日志是最重要的工具。别上来就改代码、改参数先看内核日志里显示子系统的输出确认 LCD 初始化走到了哪一步。2.1 打开 DRM 调试信息RK3568 的内核默认 drm.debug 可能是关闭的。如果看不到详细日志可以在内核启动参数里加 drm.debug0x1f或者运行时通过 debugfs 开启。我习惯先在 uboot 环境变量里加上在 kernel command line 中追加drm.debug0x1f loglevel8如果是 android 系统在 BoardConfig 或 dtb 的 chosen 节点里加也成。重启之后串口日志里就能看到 DRM 子系统的启动过程。关键是要确认几件事rockchipdrm 是否 probe 成功、DSI controller 是否 probe 成功、panel 是否匹配到驱动、mode set 是否完成。2.2 从日志中判断卡点把日志打开后重点看这几类关键词。我整理了一个速查表实际排查时可以对照着看日志关键词含义说明rockchip-drmDRM 主设备初始化若 probe 失败问题在 DRM 框架或内存节点dw-mipi-dsiDSI 控制器初始化若失败查 dts 中 dsi 节点配置panel-simple或panel-xxxpanel 驱动 probe 信息若找不到说明 compatible 没匹配上drm_panelpanel 生命周期日志能看到 prepare/enable 是否被调用fail to get获取某个资源失败通常缺 gpio/clock/regulatortimeout等待超时一般是 panel 初始化序列或 DSI 读写失败Connector连接器状态能看到 connector 是否 connectedmode 是否有效如果日志里能看到rockchip-drm display-subsystem bound之类的输出说明 DRM 主链路是通的。接下来看 DSI 的 probe 日志如果连 DSI 都没绑定那问题多半在 dts 的 dsi 节点或者时钟配置上。如果 DSI 已绑定接下来看 panel 驱动。日志里搜 panel看有没有成功加载。如果看到类似panel-simple: probe failed或者no panel driver found那就是 dts 里的 panel compatible 与内核驱动对不上。2.3 一个典型日志场景panel 驱动根本没被调用我这次遇到的问题日志里就是非常干净干净到让人抓狂DRM、DSI 全都正常初始化日志显示[drm] Initialized rockchip 3.0.0但死活没有 panel 相关的 probe 信息。这种情况下说明 panel 节点没有被 DSI 总线扫描到。原因大概率是 dsi 节点下的 panel compatible 写错了或者 panel 节点 reg 地址不对又或者 DSI 的子节点格式不对。在我这个例子里uboot 和内核的 dts 是从两个仓库拉出来的uboot 的 dts 上 panel 的 compatible 写的是xx,yyy而内核驱动里注册的 compatible 写的是xx,yyy-v1差个后缀内核就匹配不上。这种问题从日志看不出来只能靠对比 uboot 和内核两边的设备树来定位。2.4 排查时的一个有效动作先加打印如果日志看不出来我建议在 panel 驱动的 probe 函数里临时加 dev_info确认有没有走到。比如在 panel_simple_probe 入口加一行dev_info(dev, panel-simple probe enter\n);加了之后启动看串口。如果连这行都没有说明内核根本没匹配到这个驱动。如果这行有但后面 enable 没走那就是状态机或资源的问题。这一步能快速把问题圈定在“匹配”还是“后续初始化”。3. 设备树对齐与屏参修正uboot 能亮而内核不亮的头号原因RK3568 的 uboot 和内核设备树是两套但它们描述的是同一个硬件。很多“uboot 亮、内核黑”的问题归根结底就是两套设备树没对齐。3.1 uboot dts 与内核 dts 的常见差异先明确一下文件路径uboot 设备树u-boot/arch/arm/dts/rk3568-evb.dts这类文件内核设备树kernel/arch/arm64/boot/dts/rockchip/rk3568-evb.dts两个文件可能同源也可能各自维护。瑞芯微官方 SDK 里 uboot 和内核的 dts 经常是分开的且同一份 dts 里可能有成百上千行肉眼对比不现实建议用 diff 或者 grep 定位。最容易出问题的几个字段配置项uboot dts内核 dts不一致的后果compatible需匹配 uboot panel 驱动需匹配内核 panel 驱动驱动加载失败lane 数>cat /sys/kernel/debug/dri/0/state在 DRM state 里能看到 connector 的 mode 信息确认活时钟、porch 等参数是不是和 dts 里一致。如果这里显示不对说明 dts 没生效可能是编译缓存问题也可能是 dtb 没更新。3.5 一个容易被忽略的问题uboot dts 里的 panel 节点和内核不同名有的 SDK 里uboot dts 的 panel 节点叫panel0内核 dts 里同一个屏写的是panel1或者反过来。节点名字不同但 compatible 相同一般问题不大只要 reg 和 compatible 对就行。但如果你把 compatible 改了、reg 又没对齐就容易出现“uboot 认这个屏、内核认那个屏”的情况。我的经验是在排查时把 dts 相关的关键差异全部列成表一项项核对不要凭感觉改。一次改一处改完重启验证别一次性改好几个变量否则出问题都不知道是哪步引入的。4. panel 驱动与 DSI 时序关键参数内核 DRM 的初始化顺序和坑设备树对齐之后接下来要看内核侧 panel 驱动的实现。RK3568 平台最常见的是使用panel-simple驱动如果你的屏不是标准的 generic panel可能会自己写一个 panel 驱动。不管是哪种初始化顺序和 DSI 时序参数都是决定成败的关键。4.1 panel-simple 驱动的初始化流程以 panel-simple 为例内核里它的 probe 流程是获取 reset gpio、获取 enable gpio、获取 regulator、获取 backlight 设备然后注册 drm_panel。在 drm_panel_prepare 时会执行上下电时序包括设置 regulator、拉 reset、发送初始化序列在 drm_panel_enable 时会打开背光。如果面板是 DSI 接口且用 panel-simple通常还需要在 panel 节点中配置panel-init-sequence或者直接由 DSI 控制器在 video mode 下处理。要注意的是RK3568 的 dsi 驱动和 panel 驱动的配合依赖 prepare/enable 的调用顺序。如果顺序反了屏幕可能根本没有初始化命令或者命令发早了。4.2 从 dmesg 确认 prepare/enable 顺序日志里搜drm_panel_prepare和drm_panel_enable如果驱动里加了打印。正常情况下顺序应该是 prepare - 等待足够延时 - enable。如果 enable 先于 prepare 被调用说明 dts 或驱动里对准备和使能的映射关系写错了。RK3568 的 DSI video mode 下内核在 mode_set 阶段会配置 DSI 控制器参数包括 lane 数、时钟、像素格式。这些参数如果和 panel 实际能力不匹配屏幕一样不亮。4.3 常见 DSI 参数核对点看 dsi 节点的rockchip,lane-routes、>cat /sys/class/backlight/backlight/brightness如果这个值为 0或者不存在说明背光驱动没起来。再查 dts 里的 pwm 节点pwm3 { status okay; }; backlight: backlight { compatible pwm-backlight; pwms pwm3 0 25000 0; brightness-levels 0 255; default-brightness-level 200; status okay; };如果 pwm 没配 pinctrl对应引脚可能处于默认状态背光信号没有输出。还要确认背光电源 GPIO 是否设置为高电平有效如果背光 enable 脚接的是低有效而 dts 里没写enable-gpios或者 polarity 反了背光也起不来。5.3 reset 引脚的时序影响panel 的复位时序要求很严格。有的屏要求复位信号 low 至少 10ms再拉 high再等待 120ms 才能发送 DCS 命令。如果 dts 里reset-gpios没配或者reset-delay-ms不够panel 可能处于异常状态收不到初始化命令。我在调试时遇到过一种情况uboot 拉到 high 的复位引脚在内核接管后先拉 low 再拉 high 的时序里low 的时间太短屏的控制器没完成复位。这个在日志里完全看不出来最后是拿示波器量复位引脚才发现低电平只维持了 1ms屏 IC 规格书要求是 10ms。把reset-delay-ms改成 20ms 后问题解决。5.4 电源轨的完整顺序有些 MIPI 屏需要多路电源比如 VCC、VCI、VDDIO这三路的上下电顺序也有讲究。如果 dts 里 regulator 配置不对屏幕上电时面板 IC 可能处于欠压状态。检查方法cat /sys/kernel/debug/regulator/regulator_summary看对应 regulator 是否 enable电压是否正常。如果 regulator 配置没问题但电压不对可能硬件上电源芯片的反馈电阻有问题软硬件一起排查。5.5 从 uboot 到内核的电源交接问题这是 RK3568 平台特有的一类问题。uboot 里已经把 panel 的电源打开了内核启动时不会主动关掉但如果内核重新 probe panel 时先执行了 unprepare再执行 prepare而 unprepare 里把 regulator 关了之后 prepare 又重新打开中间时序不够屏可能没有正确进入 ready 状态。这类问题比较难查通常表现为“每次冷启动黑屏reboot 后正常”或者反过来。我遇到过一次是 dts 里 panel 的unprepare-delay-ms设得太小导致 regulator 关掉后还没来得及稳定又被打开。改大延时之后恢复。5.6 背光与 DPMS 的配合DRM 的 DPMS 流程中panel_enable 和 backlight 打开的顺序有讲究。以 rockchip drm 为例正常是 connector 状态切到 on 时先调用drm_panel_enable再打开 backlight。如果你的平台里顺序反了就会出现背光先亮、panel 还没出图或者 panel 先出图、背光没反应。这个顺序如果不对屏幕要么闪烁一下黑屏要么一直黑屏。排查方法在 panel 驱动的 enable 函数里加打印同时把 backlight 驱动的 brightness 写入函数加打印看两者调用顺序。如果不一致需要通过 dts 或驱动调用顺序来修正。6. 常见问题速查表与我的排查心得以下是我在 RK3568 MIPI 屏调试中整理出的高频问题速查表覆盖了从 uboot 到内核的大部分现象现象可能原因排查重点解决办法示例uboot 有 logo内核黑屏两套 dts 不一致diff uboot/内核 dts 的 panel 节点统一 compatible、timing、lane、gpio内核黑屏但串口无 errorpanel compatible 不匹配搜日志里的 panel 信息修正 dts compatible屏幕灰屏/白屏DSI 参数不对或 init seq 没发示波器量 clock/data检查 panel init 命令增加 init sequence 发送时机检查背光不亮pwm/GPIO 配置问题查看 backlight 节点和 regulator修正 pwm 和 enable-gpios 配置偶发黑屏上下电时序余量不足检查 regulator、reset 信号时序增大 reset-delay-ms 或 regulator settle time开机动画不显示DRM 模式设置失败检查 drm.debug 日志的 mode set 流程修 timing确保 mode 有效竖屏显示但应用是横屏panel 方向配置问题确认 panel 的逻辑分辨率修改 dts 中的 rotation 或方向属性6.1 再分享两个排查小技巧第一如果手头有逻辑分析仪或示波器把 MIPI DSI 的 clock lane 拉出来看。黑屏状态下clock lane 有波形不代表数据正常但如果有稳定的 HS 时钟波形至少说明 DSI 控制器是在工作的问题更可能在 panel 侧的时序或初始化命令上。如果 clock lane 都没有那就是 DSI 控制器没正常工作回到 dts 和驱动层面查。第二uboot 能点亮的屏尽量让 uboot 和内核共用一份 panel 配置。瑞芯微平台支持 uboot 和内核用同一个设备树源文件的情况虽然这在量产中不一定方便但在调试阶段非常有用。你可以把 uboot 里能正常点屏的 dts 内容复制到内核 dts然后编译验证能快速排除大量参数问题。6.2 我的调试顺序总结按效率高低我最后形成的固定排查顺序是先开 drm.debug 看日志确认卡点再对比 uboot 与内核的 dts统一配置检查 panel 驱动是否匹配、init seq 是否发送检查背光与电源时序最后才考虑修改时序参数。每次只改一个变量改完必须串口日志复核。这套流程调过 ST7701S、HX8399、NV3052 等多颗常见 MIPI 屏都能在半天内定位到问题比之前凭感觉改配置要快得多。RK3568 的 MIPI 显示链路并不可怕可怕的是 uboot 和内核两套配置互相“打架”。把这两套配置对齐再调好上下电时序黑屏问题基本都能解决。6.3 最后补一个实用命令清单调试时我会把下面这些命令放在手边方便随时确认状态dmesg | grep -i drm dmesg | grep -i panel dmesg | grep -i dsidmesg | grep -i backlight cat /sys/kernel/debug/dri/0/state cat /sys/kernel/debug/dri/0/summary cat /sys/kernel/debug/regulator/regulator_summary cat /sys/class/backlight/backlight/brightness cat /sys/class/backlight/backlight/max_brightness cat /sys/kernel/debug/gpio每次重启后按顺序抓一遍日志问题范围基本就能圈定。不要指望看一眼日志就出结论多抓几次把正常和不正常的状态对比一下差异点通常就是问题点。这篇文章写到这里核心的排查思路和实操方法都讲完了。我自己实际操作中最大的体会是RK3568 的 MIPI 屏问题绝大多数不是“硬件坏了”而是“两套软件配置的交接没做好”。希望大家调试时能少走弯路一次点亮。