RK3576 开机黑屏只有背光?从 dmesg 到 DTS 的显示排查实战 电子说
适用场景:拿到 RK3576 板子,系统跑起来了,UART 能敲命令,但屏幕不亮 —— 要么黑漆漆一片,要么只有背光没内容,要么副屏死活不出来。
先搞清显示链路有几段
RK3576 的显示链路从上到下分四段,哪段断了都会黑屏:
•SurfaceFlinger / Android 应用层 → 图层没送过来,屏幕空转
•HWComposer (HWC) → Plane 分错了,图层堆不上去
•DRM/KMS (CRTC + Encoder + Connector) → 模式没设对,显示器不认
•VOP2 / VOPL (硬件合成 + 时序) → 时钟没开、MMU 报错、寄存器没配
排查的第一件事:先确认问题是硬件没输出,还是软件层把画面吞了。
# DRM 整体状态——所有 CRTC、Plane、Connector 一目了然cat /sys/kernel/debug/dri/ 2>/dev/null # 需开启 CONFIG_DEBUG_FS0/state# 正常:每个 CRTC 有 enable=1,connector 有 connected 状态# 异常:全是 disabled,或者 connector 显示 disconnected# 内核 dmesg 先扫一遍dmesg | grep -iE "vop|drm|hdmi|edp|dsi"
如果state 显示 enabled 但屏幕不亮,问题在物理层(HDMI/eDP PHY)。如果 state 本身就是 disabled,往下走。
第一步:dmesg 先过一遍
显示初始化失败,dmesg 一定会留痕迹。重点关注这三类日志:
VOP2 (Main VOP) 初始化
# 正常[ 1.224567] rockchip-vop2 fdd90000.vop: Adding to iommu group 0[ 1.224600] rockchip-vop2 fdd90000.vop: [drm:vop2_bind] vop2 bind success, vps:3# 时钟没拿到[ 1.224567] rockchip-vop2 fdd90000.vop: failed to get aclk_vop[ 1.224568] rockchip-vop2 fdd90000.vop: vop2_bind failed: -ENOENT# 寄存器资源被占[ 1.224567] rockchip-vop2 fdd90000.vop: failed to get regs[ 1.224568] rockchip-vop2 fdd90000.vop: vop2_bind failed: -EBUSY
VOPL (Lite VOP) 初始化
# 正常[ 1.225000] rockchip-vop fdd80000.vop: Adding to iommu group 0# 电源域或时钟没就绪[ 1.225000] rockchip-vop fdd80000.vop: failed to get hclk_vop[ 1.225001] rockchip-vop fdd80000.vop: vop_bind failed: -EPROBE_DEFER
DRM component bind — 最关键的一步
VOP 是 DRM 的一个 component,所有 component 必须全部就绪,DRM 主驱动才会完成绑定:
# 正常:所有 component 都 bound 上了[ 1.230000] rockchip-drm display-subsystem: bound fdd90000.vop (ops vop2_component_ops)[ 1.230100] rockchip-drm display-subsystem: bound fdd80000.vop (ops vop_component_ops)[ 1.230200] rockchip-drm display-subsystem: bound fdd60000.hdmi (ops dw_hdmi_rockchip_ops)[ 1.235000] rockchip-drm display-subsystem: [drm] fb0: rockchipdrmfb frame buffer device# 超时,component 没到齐[ 5.000000] rockchip-drm display-subsystem: failed to bind all components[ 5.000100] rockchip-drm display-subsystem: [drm] *ERROR* failed to load rockchip drm driver.# 其中一个 component bind 失败[ 1.230000] rockchip-drm display-subsystem: failed to bind fdd80000.vop: -ENODEV
逐行解读
① Adding to iommu group 0 → VOP 已加入 IOMMU 组。如果这行都没有,说明设备根本就没 probe—— 去 DTS 里看 status 是不是 "okay"。
② failed to get xxx → 时钟或寄存器缺失。最常见的坑是 DTS 的 clock-names 写错了:
cat /sys/kernel/debug/clk/ 2>/dev/null # 需开启 CONFIG_DEBUG_FSclk_summary | grep vop# 正常:aclk_vop、hclk_vop、dclk_vp0 的 enable count 应该 >= 1# 异常:missing 某些时钟,或 enable count 全是 0
③ failed to bind all components → 5 秒超时。DRM 主驱动最多等 5 秒让所有 component 就绪。有任何一个 component 返回 -EPROBE_DEFER,超时后就报这个。
# 看哪些 component 没 bound 上dmesg | grep "component"
④ fb0: rockchipdrmfb frame buffer device → 这行出现说明 DRM 初始化基本完成。如果没有这行,显示子系统根本没启动成功。
第二步:VP 路由配错了
dmesg 没有报错,VOP 初始化看着正常,但屏幕还是不亮。这种情况八成是 VP 路由配错了。
RK3576 有三个 VP(Video Port),各有各的能力约束:
| VP | 最大分辨率 | DCLK 上限 | 能接谁 |
| VP0 | 4096x4096 | 1.2 GHz | HDMI/DP/eDP(主屏,功能最全) |
| VP1 | 2560x2560 | 300 MHz | eDP/DP/MIPI DSI |
| VP2 | 1920x1920 | 150 MHz | RGB/BT1120(纯基础功能) |
路由定义在 SoC DTSI (rk3576.dtsi) 的 display-subsystem 节点里:
display_subsystem: display-subsystem { ports = <&vop_out>, <&vopl_out>; route { route_hdmi: route-hdmi { status = "disabled"; connect = <&vp0_out_hdmi>; // HDMI 默认连 VP0 }; route_edp: route-edp { status = "disabled"; connect = <&vp1_out_edp>; // eDP 默认连 VP1 }; route_dsi: route-dsi { status = "disabled"; connect = <&vp1_out_dsi>; // MIPI DSI 也连 VP1 }; route_rgb: route-rgb { status = "disabled"; connect = <&vp2_out_rgb>; // RGB 连 VP2 }; };};
// 真正的路由在 board DTS 中开启。比如 HDMI 主输出 + eDP 副屏:&route_hdmi { status = "okay"; connect = <&vp0_out_hdmi>; // VP0 → HDMI};&route_edp { status = "okay"; connect = <&vp1_out_edp>; // VP1 → eDP};
最容易出错的三种情况:
① 开了 route 但没开对应的显示接口:route_hdmi 配了 okay,但 &hdmi 节点还是status = "disabled"。驱动不会报错,它只是跳过初始化。
cat /sys/firmware/devicetree/base/hdmi@27da0000/status# 应该输出: okay
② VP 能力不够:VP2 最大只支持 1920x1920。如果 route 把 VP2 连到 4K 屏:
[ 1.235000] rockchip-vop2 fdd90000.vop: failed to set mode 3840x2160 on vp2[ 1.235001] rockchip-vop2 fdd90000.vop: vp2 max output is 1920x1920
③ 两个 route 同时连到同一个 VP:没有竞争逻辑,只有一个生效。双屏必须分别连 VP0 和 VP1。
确认当前路由
# 看 CRTC 与 Connector 的绑定关系cat /sys/kernel/debug/dri/ 2>/dev/null # 需开启 CONFIG_DEBUG_FS0/state# 重点关注:# CRTC-0 (VP0) → connector 是 HDMI-A-1 → VP0 驱动 HDMI# CRTC-1 (VP1) → connector 是 eDP-1 → VP1 驱动 eDP# 看 connector 连接状态cat /sys/kernel/debug/dri/ 2>/dev/null # 需开启 CONFIG_DEBUG_FS0/connectors# 正常:connector HDMI-A-1 (connected)# 异常:connector HDMI-A-1 (disconnected)
第三步:各层调试方法
dmesg 和路由都检查过了,还是黑屏?逐层往下透。
DRM 层
# CRTC 具体状态cat /sys/kernel/debug/dri/ 2>/dev/null # 需开启 CONFIG_DEBUG_FS0/crtc-0/state# 关键字段:# enable=1# active=1# mode: 1920x1080@60# plane_mask=0x1# 如果 enable=0 → CRTC 没使能# 所有 Plane 列表cat /sys/kernel/debug/dri/ 2>/dev/null # 需开启 CONFIG_DEBUG_FS0/planes# Framebuffercat /sys/kernel/debug/dri/ 2>/dev/null # 需开启 CONFIG_DEBUG_FS0/framebuffers# 正常:fb:1, format:XR24, 1920x1080, size:8294400
HWC 层
# HWC dumpdumpsys hwcomposer# 关注:# Display: 0 → 主屏# Display: 1 → 副屏# Plane assignment → 每个 CRTC 分到了哪些 plane# 如果 dumpsys hwcomposer 输出为空 → HWC 服务没起来ps -A | grep hwc# 正常:hwcomposer.rockchip 或 android.hardware.graphics.composer
RK3576 的 Plane 分配策略定义在 drmhwc3576.cpp 的assignPlaneByHWC():
| 端口组合 | VP0 | VP1 | VP2 |
| 单 VP0 | All Cluster + Esmart0/2 | - | - |
| 单 VP1 | - | All Cluster + Esmart1/3 | - |
| VP0+VP1 | Cluster+Esmart0/2 | Esmart1/3 | - |
| 三屏全开 | Cluster0+Esmart0 | Cluster1+Esmart1 | Esmart2/3 |
关键约束:VP2 不能接 Cluster 类 Plane,只能接 Esmart。如果 HWC 把 Cluster 分给了 VP2,VP2 的屏幕就是空白。
SurfaceFlinger 层
# SF 全局信息dumpsys SurfaceFlinger# 只看显示设备dumpsys SurfaceFlinger --displays# 正常:至少有一个 display,connected=true# 如果只有一个 display 但你有两个屏 → 副屏没被 SF 识别
寄存器层
# RK3576 VOP2 基地址 0xfdd90000# 读 VOP 版本寄存器# 正常:0x97650050(VOP_VERSION_RK3576)# 读 VP0 使能状态# bit 0: VP0 enable(1=使能)# bit 8: VP0 standby(1=待机)
IOMMU —— 隐蔽的黑屏原因
VOP 通过 IOMMU 读 framebuffer。IOMMU 出问题会导致 page fault:
dmesg | grep -E "iommu|mmu|page fault"# 错误示例:# rk_iommu fdd97e00.iommu: page fault at 0x00000000# rk_iommu fdd97e00.iommu: read from VP0, irq:0x000001
IOMMU page fault 的原因:
•Gralloc 分配的 buffer 没正确映射到 IOMMU 地址空间
•buffer 被释放了但 VOP 还在读
•VOP MMU 节点被 disable 了
cat /sys/firmware/devicetree/base/iommu@fdd97e00/status# 应该输出: okay
实战案例
案例一:HDMI 只有背光没有画面
现象:上电后背光亮了,一直黑屏。UART 能登录,系统正常运行,但没有任何显示。
排查过程:
# dmesg 看驱动状态dmesg | grep -iE "vop|drm|hdmi"# 输出:# rockchip-vop2 fdd90000.vop: vop2 bind success# rockchip-drm display-subsystem: bound fdd90000.vop# rockchip-drm display-subsystem: bound fdd60000.hdmi# rockchip-drm display-subsystem: fb0: rockchipdrmfb# → 驱动初始化正常# DRM connector 状态cat /sys/kernel/debug/dri/ 2>/dev/null # 需开启 CONFIG_DEBUG_FS0/connectors# HDMI-A-1 (connected) → 连接正常# CRTC 状态cat /sys/kernel/debug/dri/ 2>/dev/null # 需开启 CONFIG_DEBUG_FS0/crtc-0/state# enable=1, mode: 0x0 ← mode 是 0!没设有效分辨率
根因:&hdmi 节点没配pinctrl-0。HDMI 的 I2C 引脚(DDC)没有被配置,读不到显示器的 EDID。没有 EDID,VOP 不知道输出什么分辨率。
# 验证cat /sys/class/drm/card0-HDMI-A-1/edid | hexdump -C# 输出为空 → 确实读不到 EDIDcat /sys/firmware/devicetree/base/hdmi@fdd60000/pinctrl-0# 输出为空 → pinctrl 没配
修复:补齐 pinctrl:
&hdmi { pinctrl-0 = <&hdmim0_tx0_cec &hdmim1_tx1_hpd &hdmim1_tx0_sda &hdmim1_tx0_scl>; pinctrl-names = "default"; status = "okay";};
重启后:
# EDID 正常读取cat /sys/class/drm/card0-HDMI-A-1/edid | hexdump -C# mode 正常了cat /sys/kernel/debug/dri/ 2>/dev/null # 需开启 CONFIG_DEBUG_FS0/crtc-0/state | grep mode# mode: 1920x1080@60
案例二:eDP 屏分辨率不对,内容偏移
现象:eDP 副屏有显示,但分辨率只有 1024x768(屏是 1920x1080),内容偏移半个屏。
排查过程:
# CRTC 状态cat /sys/kernel/debug/dri/ 2>/dev/null # 需开启 CONFIG_DEBUG_FS0/crtc-1/state | grep mode# mode: 1024x768@60# 查 EDIDcat /sys/class/drm/card0-eDP-1/edid | hexdump -C# 有数据,但 timing 是 1024x768# 看 dmesg 中 eDP 协商过程dmesg | grep -i "panel|edp"# panel-simple edp-panel: panel has no eDP EDID, using fixed-mode# panel-simple edp-panel: size 1024x768
根因:DTS 中 eDP 配的是 panel-simple,靠 DTS 里的 display-timings 固定时序。但 DTS 写的是参考设计的分辨率,不是实际屏的。
修复:两个方案选一个。
方案 A(修正 DTS timing):
&edp_panel { width-mm = <256>; height-mm = <144>; display-timings { timing0 { clock-frequency = <148500000>; hactive = <1920>; vactive = <1080>; hfront-porch = <88>; hsync-len = <44>; hback-porch = <148>; vfront-porch = <4>; vsync-len = <5>; vback-porch = <36>; }; };};
方案 B(改用 panel-edp,支持 EDID 自动识别,换屏不用改 DTS):
// 去掉固定 display-timings,让 eDP 控制器自己读 EDID// 前提是你的 eDP 屏支持 EDID(大部分都支持)
案例三:双屏异显,副屏死活不出来
现象:主屏 HDMI 正常,eDP 副屏背光亮但不显示。dumpsys SurfaceFlinger --displays 只看得到一个屏。
排查过程:
dumpsys SurfaceFlinger --displays# Display 0: HDMI-A-1 (connected)# → 只有主屏cat /sys/kernel/debug/dri/ 2>/dev/null # 需开启 CONFIG_DEBUG_FS0/connectors# HDMI-A-1 (connected)# eDP-1 (connected)# → DRM 层识别到了,但 SF 没收到通知cat /sys/kernel/debug/dri/ 2>/dev/null # 需开启 CONFIG_DEBUG_FS0/crtc-1/state | grep plane_mask# plane_mask=0x0 ← VP1 没分到任何 plane!
根因:VP1 的 rockchip,plane-mask 在 DTS 中没配或配成了 0。没有 plane mask,HWC 不知道 VP1 能用哪些硬件管线。
修复:在 DTS 中给每个 VP 配 plane mask:
&vop { vp0: vp0 { rockchip,plane-mask = <(ROCKCHIP_VOP2_CLUSTER0 | ROCKCHIP_VOP2_ESMART0 | ROCKCHIP_VOP2_ESMART2)>; rockchip,primary-plane = ; }; vp1: vp1 { rockchip,plane-mask = <(ROCKCHIP_VOP2_CLUSTER1 | ROCKCHIP_VOP2_ESMART1 | ROCKCHIP_VOP2_ESMART3)>; rockchip,primary-plane = ; };};
plane-mask 决定了 VP 能用哪些管线。不配的话默认为 0,HWC 分不到 plane,屏幕出不来。
修复后验证:
dumpsys SurfaceFlinger --displays# Display 0: HDMI-A-1 (connected)# Display 1: eDP-1 (connected) ← 出来了
调试命令收藏
| 目标 | 命令 | 正常输出示例 |
| DRM 全状态 | cat /sys/kernel/debug/dri/ 2>/dev/null # 需开启 CONFIG_DEBUG_FS0/state | CRTC enabled, connector connected |
| CRTC 状态 | cat /sys/kernel/debug/dri/ 2>/dev/null # 需开启 CONFIG_DEBUG_FS0/crtc-0/state | mode:1920x1080 enable=1 |
| Connector 列表 | cat /sys/kernel/debug/dri/ 2>/dev/null # 需开启 CONFIG_DEBUG_FS0/connectors | HDMI-A-1 (connected) |
| Framebuffer | cat /sys/kernel/debug/dri/ 2>/dev/null # 需开启 CONFIG_DEBUG_FS0/framebuffers | fb:1 format:XR24 1920x1080 |
| EDID 读取 | cat /sys/class/drm/card0-HDMI-A-1/edid | hexdump -C | 非空数据 |
| SurfaceFlinger | dumpsys SurfaceFlinger --displays | Display 0/1 connected |
| HWC dump | dumpsys hwcomposer | Plane assignment 信息 |
| 时钟状态 | cat /sys/kernel/debug/clk/ 2>/dev/null # 需开启 CONFIG_DEBUG_FSclk_summary | grep vop | enable count >= 1 |
| DTS 状态 | cat /sys/firmware/devicetree/base/vop@fdd90000/status | okay |
| IOMMU 错误 | dmesg | grep -E "iommu|page fault" | 无输出(没错误就是最好) |
常规排查流程

审核编辑 黄宇
全部0条评论
快来发表一下你的评论吧 !