RK3576 屏幕点不亮?从 dmesg 到 debugfs 的 VOP 调试路线图 电子说
适用场景:新板子回来,屏幕啥也不显示。或者之前好使的,改完 DTS 显示乱了。又或者某些图层叠上去看不见。
VOP 的问题归根到底就三件事:时钟、图层分配、中断。这条线串起来,按顺序查,不绕弯子。
第一步:dmesg 先过筛子
dmesg | grep -i "vop|vop2|drm"
你会看到以下情况之一:
# 正常:VOP probe + CRTC 注册[ 1.456789] rockchip-vop2 27d00000.vop: Adding to iommu group 0[ 1.457200] rockchip-drm drm: bound 27d00000.vop (ops vop2_component_ops)[ 1.462000] rockchip-drm drm: Registered 3 video ports (VP0/VP1/VP2)# 异常一:component 未绑定[ 1.457200] rockchip-vop2 27d00000.vop: probe with driver rockchip-vop2 failed, error -517[ 1.460000] rockchip-drm drm: failed to bind 27d00000.vop (ops vop2_component_ops): -517# 异常二:电源域超时[ 1.870000] rockchip-vop2 27d00000.vop: failed to get power domain status[ 1.870100] rockchip-vop2 27d00000.vop: vop2_pd_data_init: pd init timeout
-517 是什么? -EPROBE_DEFER,不是真失败。VOP 依赖的某个 PHY 或时钟驱动还没就绪,等几秒会重新 probe。但如果一直反复出现,说明有依赖被永久 defer 了。
电源域超时呢? 通常是 PMU GRF 的 syscon引用错了。RK3576 的 Cluster/ESMART 有内部电源域,状态从 PMU 寄存器读,引用不对就卡死。
# 确认 PMU GRF 是否正确cat /sys/firmware/devicetree/base/vop/pmu-grf# 如果文件不存在 → DTS 少了 pmu-grf 引用# summary 存在才说明 VOP bind 成功cat /sys/kernel/debug/dri/0/summary 2>/dev/null # 需开启 CONFIG_DEBUG_FS# 输出 "VOP: rk3576-vop" 为正常
dmesg 关键词速查
| 关键词 | 含义 | 行动 |
| error -517 | 依赖未就绪 | 查 PHY / 时钟 / 电源域 DTS |
| pd init timeout | 电源域超时 | 查 PMU GRF |
| vop2_create_crtc failed | CRTC 注册失败 | 查 plane-mask |
| failed to get edid | 没读到 EDID | 查 HDMI/DP 连接 |
| axi bus error | 带宽或地址异常 | 查 iommu /aclk |
| Win ... already used by VP | 窗口冲突 | 查 plane-mask 重叠 |
第二步:时钟排查
VOP 三个时钟:dclk(像素输出)、aclk(总线 DMA)、hclk(寄存器访问)。任何一个不对,效果都一样:屏幕不亮。
# 看 VOP 所有时钟cat /sys/kernel/debug/clk/clk_summary 2>/dev/null | grep -E "vop|aclk_vop|hclk_vop|dclk" # 需开启 CONFIG_DEBUG_FS
正常:
aclk_vop 1 1 500000000hclk_vop 1 1 200000000dclk_vp0 1 1 594000000dclk_vp1 0 0 148500000
异常:
aclk_vop 0 0 500000000 # 没 enablehclk_vop 0 0 200000000dclk_vp0 0 0 0 # 频率为 0
aclk/hclk 没 enable→ 查 DTS clocks 属性:
cat /sys/firmware/devicetree/base/vop/clock-names# 应该输出: aclk_vophclk_vopdclk_vp0dclk_vp1dclk_vp2...# 和驱动里 devm_clk_get(dev, "aclk_vop") 对不上就会 -ENOENT
dclk 为 0 但 aclk/hclk 正常→ mode set 没触发,大概率 EDID 没读到:
# 看 dclkcat /sys/kernel/debug/dri/0/video_port0/calculated_dclk_rate 2>/dev/null || echo "(需开启 CONFIG_DEBUG_FS)" # 需开启 CONFIG_DEBUG_FS# 正常: 594000 KHz | 异常: 0 或 -1# 看 EDIDcat /sys/kernel/debug/dri/0/HDMI-A-1/edid 2>/dev/null | hexdump -C | head # 需开启 CONFIG_DEBUG_FS# 空输出 → HDMI/DP PHY 可能有问题
dmesg 里的时钟线索:
[ 1.456000] rockchip-vop2: failed to get clk 'aclk_vop': -ENOENT
这就是 DTS clock-names 和驱动的名字没对上,打开 DTS 核对即可。
第三步:Layer/Plane 分配
RK3576 有 8 个硬件窗口,每个 VP 最多 4 层。窗口分配在 DTS 的 plane-mask里定义。背光亮了但没画面,大概率是这个环节。
cat /sys/kernel/debug/dri/0/summary 2>/dev/null # 需开启 CONFIG_DEBUG_FS
正常输出:
VOP: rk3576-vopVP0: 3840x2160@60, HDR: off, dclk: 594000 KHz Layer0: Cluster0-win0 (zpos=0, enable) Layer1: Cluster1-win0 (zpos=1, disable) Layer2: Esmart0-win0 (zpos=2, enable) Layer3: Esmart2-win0 (zpos=3, disable)
异常:全部 (none)→ plane 分配失败,最常见两个原因:
一、plane-mask 配反了或与其他 VP 冲突:
plane-mask = <0x15>; // 二进制 010101 // bit0=Cluster0 bit2=Esmart0 bit4=Esmart2
如果 VP0 和 VP1 的 plane-mask 有重叠,dmesg 会报:
[ 1.480000] rockchip-vop2: *ERROR* Win Cluster0 already used by VP0, can't assign to VP1
二、primary-plane 没配:
vp0: port@0 { rockchip,primary-plane = <2>; // ESMART0 rockchip,plane-mask = <0x15>;};
不配的话驱动自动找 Primary 类型窗口,可能被其他 VP 占用了。
详细检查
# 确认窗口分配cat /sys/kernel/debug/dri/0/video_port0/plane_mask 2>/dev/null # 需开启 CONFIG_DEBUG_FS# 正常: plane_mask = 0x15, primary = 2 (Esmart0-win0)cat /sys/kernel/debug/dri/0/video_port0/connected_planes 2>/dev/null # 需开启 CONFIG_DEBUG_FS# 正常: Cluster0-win0 Esmart0-win0 Esmart2-win0
reserved-plane的坑:如果把某个窗口设为保留(比如光标层),应用没用它,这个窗口就浪费了。reserved-plane = <0>保留 Cluster0,实际可用层只剩 2 个。
第四步:debugfs 实战
VOP 在 debugfs 暴露了大量信息,大部分问题不加打印就能定位。
核心节点一览
| 节点 | 用途 | 异常特征 |
| dri/0/summary | 全局状态 | 文件不存在 = VOP 没注册 |
| dri/0/video_portN/color_bar | 彩条测试 | 写 1 没反应 = CRTC 异常 |
| dri/0/video_portN/calculated_dclk_rate | dclk 频率 | 0或-1 |
| dri/0/video_portN/plane_mask | 窗口掩码 | (none) |
| dri/0/vop_devfreq/cur_freq | aclk 实时频率 | 0 |
| dri/0/video_portN/vop_dump/dump | 帧缓冲 dump | 空文件 |
color_bar:硬件有没有问题一试便知
color_bar 直接从 VOP 硬件生成彩条,不经过 DRM 合成器。能出彩条说明 VOP 硬件、CRTC、时钟、连接器全正常。
# 开彩条echo 1 > /sys/kernel/debug/dri/0/video_port0/color_bar # 需开启 CONFIG_DEBUG_FS# 有彩条 → 问题在应用层 | 无彩条 → VOP 硬件本身有问题# 关彩条echo 0 > /sys/kernel/debug/dri/0/video_port0/color_bar # 需开启 CONFIG_DEBUG_FS
summary 逐行解读
# 寄存器基地址在 summary 头部# 检查 VOP 是否处于 standby(bit0 = 1 就是待机中)# 正常情况下 mode set 完成后 standby 应被清除为 0
寄存器直接读写
# 寄存器基地址在 summary 头部# 检查 VOP 是否处于 standby(bit0 = 1 就是待机中)# 正常情况下 mode set 完成后 standby 应被清除为 0
实战案例
案例一:新板子 HDMI 不显示,dmesg 全是 -517
现象:系统启动正常,HDMI 接显示器无输出。dmesg 反复出现 VOP probe error -517。
排查:
dmesg | grep "probe defer"[ 1.450000] driver rockchip-vop2: deferring due to missing phy# 追根溯源dmesg | grep -i "hdmi|drm"[ 1.350000] dwhdmi-rockchip: deferring due to missing hdmi phy
是 HDMI PHY 没加载导致整条链 defer。查 PHY 的时钟:
cat /sys/firmware/devicetree/base/hdmi@.../clocks
根因:DTS 中 HDMI PHY 的 clocks引用了&cru PLL_HPLL,但该 DTSI 里叫 HPLL。名字对不上,PHY probe 失败,整条链 cascade defer。
修复:DTS 修正 clock 引用名。重启后:
[ 1.350000] dwhdmi-rockchip: bound to vp0[ 1.450000] rockchip-vop2 27d00000.vop: bound to drm[ 1.460000] rockchip-drm drm: Registered 3 video ports
案例二:双屏显示,副屏有背光但无画面
现象:VP0(HDMI)正常出图,VP1(DP)背光亮了但屏幕黑的。dmesg 没有明显错误。
排查:
cat /sys/kernel/debug/dri/0/summary 2>/dev/null # 需开启 CONFIG_DEBUG_FSVP1: 1920x1080@60, HDR: off, dclk: 148500 KHz Layer0: (none) ← VP1 的 plane 全是 none! Layer1: (none) Layer2: (none) Layer3: (none)
cat /sys/kernel/debug/dri/0/video_port1/plane_mask 2>/dev/null # 需开启 CONFIG_DEBUG_FS# plane_mask = 0x00 ← 没有任何窗口!
查 DTS,VP1 配了 plane-mask = <0x0a>(Cluster1 + Esmart1),VP0 配了 0x15(Cluster0 + Esmart0 + Esmart2),看起来不重叠。但 dmesg 有线索:
[ 1.480000] rockchip-vop2: Cluster1-win1 can't find available VP
根因:每个 Cluster 含两个子窗口(win0/win1)。plane-mask = <0x0a>分配了物理 ID 1(Cluster1),但 Cluster1-win0 和 Cluster1-win1 共享这个 ID。两者都试图绑到 VP1,VP1 只有 4 层,其中一个分配不下。
修复:调整 VP1 只保留 Esmart 窗口,Cluster 全部留给 VP0:
vp0: port@0 { rockchip,plane-mask = <0x17>; }; // Cluster0+Cluster1+Esmart0+Esmart2vp1: port@1 { rockchip,plane-mask = <0x28>; }; // Esmart1+Esmart3
重启后 VP1 正常输出。
案例三:4K@60 花屏,1080p 正常
现象:HDMI 4K@60 花屏或闪烁,降到 1080p 完全正常。
排查:
# 4K 时 dclkcat /sys/kernel/debug/dri/0/video_port0/calculated_dclk_rate 2>/dev/null || echo "(需开启 CONFIG_DEBUG_FS)" # 需开启 CONFIG_DEBUG_FS# 594000 KHz# 查 aclk 实时频率watch -n 1 'cat /sys/kernel/debug/dri/0/vop_devfreq/cur_freq' # 需开启 CONFIG_DEBUG_FS# 一直停在 500000000 → 没升频!
根因:devfreq 的带宽评估在 AFBC 压缩场景下低估了需求,aclk 跑 500MHz 带不动 4K@60 的带宽。
修复:短期应急—— DTS 强制锁高频:
&vop { rockchip,aclk-normal-mode-rates = <702000000>; };
根本解决—— 修正 rockchip_vop2_devfreq.c中 4K@60 + AFBC 的带宽计算公式。
案例四:应用配了 4 层,有一层不显示
现象:用户态应用提交了 4 个 layer,其中一个始终画不出来。dmesg 无异常。
排查:
cat /sys/kernel/debug/dri/0/summary 2>/dev/null # 需开启 CONFIG_DEBUG_FSVP0: 1920x1080@60, dclk: 148500 KHz Layer0: Cluster0-win0 (zpos=0, enable) Layer1: Cluster1-win0 (zpos=1, enable) Layer2: Esmart0-win0 (zpos=2, enable) Layer3: (none) ← 第 4 层没分配窗口!
检查 plane_mask:
cat /sys/kernel/debug/dri/0/video_port0/plane_mask 2>/dev/null # 需开启 CONFIG_DEBUG_FS# plane_mask = 0x15 → bit0=Cluster0, bit2=Esmart0, bit4=Esmart2# Esmart1(bit3)不在 VP0 的 mask 中
根因:应用在第 4 层用了 Esmart1(物理 ID 3),但 VP0 的 plane-mask = 0x15没包含 Esmart1。vop2_atomic_commit()检查发现该窗口不属于 VP0,直接跳过。
修复:DTS 加入 Esmart1,同时调整 VP1 避免冲突:
vp0: port@0 { rockchip,plane-mask = <0x1d>; }; // Cluster0 + Esmart0~2vp1: port@1 { rockchip,plane-mask = <0x22>; }; // Cluster1 + Esmart3
调试命令收藏
| 目标 | 命令 | 关键输出 |
| VOP 注册 | dmesg | grep -i "vop|drm" | bound 27d00000.vop |
| 时钟概览 | cat /sys/kernel/debug/clk/clk_summary 2>/dev/null | grep -E "vop|aclk|dclk"# 需开启 CONFIG_DEBUG_FS | 非 0 频率 + enable 计数 |
| 图层分配 | cat /sys/kernel/debug/dri/0/summary 2>/dev/null# 需开启 CONFIG_DEBUG_FS | 各 VP layer 列表 |
| 窗口掩码 | cat /sys/kernel/debug/dri/0/video_port*/plane_mask 2>/dev/null# 需开启 CONFIG_DEBUG_FS | 与 DTS 一致 |
| dclk | cat /sys/kernel/debug/dri/0/video_port*/calculated_dclk_rate 2>/dev/null# 需开启 CONFIG_DEBUG_FS | 0 = 异常 |
| 彩条测试 | echo 1 > /d/dri/0/video_port0/color_bar# 需开启 CONFIG_DEBUG_FS | 出图 = 硬件正常 |
| aclk 调频 | cat /sys/kernel/debug/dri/0/vop_devfreq/cur_freq 2>/dev/null# 需开启 CONFIG_DEBUG_FS | 4K 需 >= 594MHz |
| DTS 状态 | cat /sys/firmware/devicetree/base/vop/status | okay |
| EDID | cat /sys/kernel/debug/dri/0/HDMI-A-1/edid | hexdump | head# 需开启 CONFIG_DEBUG_FS | 非空 = 已读 |
排查流程图

90% 的问题在前三步能定位。剩下 10% 需要翻寄存器手册,但 debugfs 已经把范围缩到具体模块了。
审核编辑 黄宇
全部0条评论
快来发表一下你的评论吧 !