ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

RK3588 VOP图层分配实战:从plane-mask到primary-plane的配置验证

RK3588 VOP图层分配实战:从plane-mask到primary-plane的配置验证 1. RK3588 VOP 图层分配到底在解决什么问题如果你正在调试 RK3588 的多屏显示大概率遇到过这类现象HDMI 能出图但 MIPI DSI 黑屏、副屏只能显示一个纯色背景、视频层跑到错误的屏幕上、或者 dmesg 里报no available plane之类的错误。这些问题十有八九不是屏幕时序没配对而是 VOP 图层分配没理清楚。RK3588 的 VOP2 是一个统一显示架构内部一共有 8 个图层资源分成 Cluster 0/1/2/3 和 Esmart 0/1/2/3 两组。这些图层不是每个 Video Port 私有的而是所有 VP 共享并且同一时刻一个图层只能被一个 VP 独占。所以当你的板子同时点亮 HDMI、DP、MIPI DSI 三路输出时谁拿 Cluster、谁拿 Esmart、谁是 primary就必须在设备树里明确指定否则 U-Boot 会按默认策略分配一旦默认策略和你的硬件接口数量对不上就会出现图层冲突或者某个屏幕没有可用图层。rockchip,plane-mask和rockchip,primary-plane这两个属性就是干这个的。plane-mask 用位掩码的方式告诉驱动「这个 VP 能用哪些图层」primary-plane 则指定这个 VP 的主图层是哪一个。主图层很关键因为 legacy 的显示 API比如很多 Linux 桌面环境会默认把背景画在 primary 上如果 primary 选错或者没分配桌面背景就出不来。这篇文章面向的是正在做 RK3588 多屏产品、需要自己定制图层分配策略的驱动和应用工程师。我会从图层资源的基本盘讲起给出可以直接抄进 dts 的配置片段然后一步步用 dmesg 验证分配结果最后把常见的报错和排查路径理一遍。目标很明确让你一次性把 VOP 图层分配链路走通不用再靠猜。先明确一个前提RK3588 的图层 ID 定义在dt-bindings/display/rockchip_vop.h这个头文件里配置之前先确认你的内核版本里这个文件存在路径一般是include/dt-bindings/display/rockchip_vop.h。里面会定义类似ROCKCHIP_VOP2_CLUSTER0、ROCKCHIP_VOP2_ESMART0、ROCKCHIP_VOP2_SMART0这样的宏后面写 plane-mask 全靠它们。2. TaoToken 前置准备把模型对话和接入文档放到手边调试 VOP 图层分配的过程中你会频繁需要查寄存器手册、对 dts 语法、看驱动源码里的绑定逻辑。这些资料分散在内核文档、Rockchip 的 SDK 和一堆论坛帖子里来回切换很费时间。我的做法是把常用的查询入口固定下来遇到不确定的宏定义或者属性含义直接开一个模型对话窗口问比翻 PDF 快得多。TaoToken 在这里的角色就是一个统一的模型调用入口。你可以通过它的模型对话页面直接问「RK3588 VOP2 的 plane-mask 位掩码怎么算」「primary-plane 能不能选 Cluster 图层」这类具体问题它会结合上下文给出可操作的答案。对于驱动开发来说这种即时问答能省掉大量 grep 源码的时间。具体入口我列一下你按需取用模型对话入口在https://taotoken.net/api对应的对话服务里适合临时查概念、对报错。接入文档在https://taotoken.net/api的 doc 路径下里面有完整的 API 说明和示例如果你想把模型能力集成到自己的调试脚本里从这里开始看。API Keys 管理在 console 里生成 key 之后就可以在脚本里调用。如果你是要长期做 RK3588 驱动开发建议直接上 Coding Plan把模型对话和代码补全绑在一起用写 dts 和排查驱动问题时效率会高不少。Coding Plan 的入口在官网导航里能找到这里不展开。需要提醒一点TaoToken 只是帮你查资料和验证思路的工具它不替代你本地的交叉编译环境和硬件调试。图层分配最终还是要落到 dts 修改、编译、烧录、看 log 这个闭环上。模型能告诉你「应该怎么配」但「配了之后板子出不出图」得你自己上电验证。另外如果你在配置过程中遇到 OAuth 相关的报错比如某些工具链在拉取依赖时提示认证失败那通常是本地凭证过期和 VOP 配置本身无关重新走一遍授权流程即可。这个坑我在后面排障章节会再提一次。3. 可复制的设备树配置plane-mask 与 primary-plane 写法这一节是核心直接给可以抄的配置。先讲清楚位掩码怎么算再给三屏异显的完整示例最后说几个容易写错的细节。图层 ID 的宏定义在rockchip_vop.h里RK3588 的 8 个图层对应的宏大致是图层类型宏名说明ClusterROCKCHIP_VOP2_CLUSTER0 ~ CLUSTER3高性能层支持缩放、旋转、AFBCEsmartROCKCHIP_VOP2_ESMART0 ~ ESMART3支持缩放和多区域适合视频SmartROCKCHIP_VOP2_SMART0 ~ SMART3基础层通常做 primaryplane-mask 是一个位掩码第 N 位为 1 表示该 VP 可以使用第 N 号图层。写法是1 ROCKCHIP_VOP2_XXX多个图层用按位或连起来。比如要分配 Cluster1 和 Smart1 给 vp0就是rockchip,plane-mask (1 ROCKCHIP_VOP2_CLUSTER1 | 1 ROCKCHIP_VOP2_SMART1);primary-plane 直接写图层宏注意它必须是 plane-mask 里的一个rockchip,primary-plane ROCKCHIP_VOP2_SMART1;下面是一个 RK3588 三屏异显的完整参考配置。假设你有 HDMI、DP、MIPI DSI 三路输出分别对应 vp0、vp1、vp2主屏是 MIPI DSIvp2给它多分图层#include dt-bindings/display/rockchip_vop.h vp0 { rockchip,plane-mask (1 ROCKCHIP_VOP2_CLUSTER0 | 1 ROCKCHIP_VOP2_ESMART0); rockchip,primary-plane ROCKCHIP_VOP2_ESMART0; }; vp1 { rockchip,plane-mask (1 ROCKCHIP_VOP2_CLUSTER1 | 1 ROCKCHIP_VOP2_ESMART1); rockchip,primary-plane ROCKCHIP_VOP2_ESMART1; }; vp2 { rockchip,plane-mask (1 ROCKCHIP_VOP2_CLUSTER2 | 1 ROCKCHIP_VOP2_ESMART2 | 1 ROCKCHIP_VOP2_SMART0); rockchip,primary-plane ROCKCHIP_VOP2_SMART0; };这里 vp2 分了三个图层因为它是主屏应用场景最多。vp0 和 vp1 各分两个满足基本显示需求。注意 primary-plane 我选了 Esmart 和 Smart没有选 Cluster原因是 Cluster 图层性能强但资源紧张通常留给视频或者需要缩放的场景做 overlayprimary 用 Esmart 或 Smart 更稳妥。如果你需要把某个图层设成鼠标层cursor在对应的 vp 节点下加cursor-win-idvp0 { cursor-win-id ROCKCHIP_VOP2_CLUSTER0; };但要注意Linux 系统非 Android下指定 Cluster 做鼠标层需要配合 SDK 提供的libdrm-cursor库否则鼠标可能显示异常。这个细节在 Rockchip 的 Debian 开发指南里有说明。还有一个属性值得关注disable-win-move。某些 Linux 系统希望每个 crtc 的图层独占不允许在 crtc 之间迁移图层可以在 vop 节点下打开vop { disable-win-move; };打开之后图层分配就完全按 plane-mask 来不会出现运行时动态迁移导致的显示抖动。配置写完之后编译 dtb 并烧录。如果你用的是 Rockchip 的 SDK编译命令一般是./build.sh kernel或者单独编译 dtbmake ARCHarm64 rk3588-your-board.dtb烧录之后重启进入下一步验证。4. 验证请求与成功结果从 dmesg 确认图层分配生效配置写完不代表生效必须从启动 log 里确认驱动真的按你的意图分配了图层。RK3588 的 VOP 驱动在 bind 阶段会打印每个 VP 的 plane mask 和 primary plane 的物理 ID这是最直接的验证依据。先看 U-Boot 阶段的 log。U-Boot 的 DRM 驱动会先做一次分配输出类似这样的信息VOP have 3 active VP vp0 have layer nr:2[1 5 ], primary plane: 5 vp1 have layer nr:2[0 4 ], primary plane: 4 vp2 have layer nr:3[2 3 6 ], primary plane: 6方括号里的数字是图层 IDlayer nr是数量primary plane是主图层的 ID。你可以对照自己的 plane-mask 配置看数量对不对、primary 是不是你指定的那个。然后是 Linux kernel 阶段的 log这个更详细会直接打印 mask 的十六进制值[2.315764] rockchip-vop2 : [drm:vop2_bind] vp0 assign plane mask: 0x22, primary plane phy id: 5 [2.315807] rockchip-vop2 : [drm:vop2_bind] vp1 assign plane mask: 0x15, primary plane phy id: 4 [2.315828] rockchip-vop2 : [drm:vop2_bind] vp2 assign plane mask: 0x8, primary plane phy id: 3这里的plane mask是十六进制primary plane phy id是物理图层号。你可以把 mask 转成二进制看哪些位是 1再对照rockchip_vop.h里的宏定义确认分配是否符合预期。抓 log 的命令很简单dmesg | grep -i vop2_bind或者直接看完整启动 logdmesg | grep -i assign plane mask如果 log 里出现了no available plane或者failed to assign plane说明你的 plane-mask 配置有问题可能是图层 ID 写错、或者多个 VP 抢同一个图层。这时候回到 dts 检查位掩码确保每个图层只出现在一个 VP 的 mask 里。验证通过之后你还可以用 modetest 工具看当前 crtc 和 plane 的绑定关系modetest -M rockchip -p输出里会列出每个 crtc 支持的 plane以及当前 primary plane 是哪个。如果 modetest 显示某个 crtc 没有 primary plane那桌面背景肯定出不来需要回头改 primary-plane。实测下来只要 dmesg 里的 mask 和 primary id 和你 dts 里写的一致多屏显示基本就稳了。剩下的就是应用层怎么用这些图层的问题。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth这一节把调试过程中最容易撞上的几类报错集中说一下。有些是 VOP 配置本身的有些是工具链或者环境问题但都会让你误以为是图层分配错了。报错一no available plane for crtc这是最典型的图层分配错误。dmesg 里会看到类似rockchip-vop2: no available plane for vp2原因通常是 plane-mask 里指定的图层已经被别的 VP 占用了或者 mask 写成了 0。排查方法检查每个 VP 的 plane-mask确保没有重叠。RK3588 的 8 个图层要平均分给使用的 VP不用的 VP 不要分配。如果你只点亮两路输出第三路 VP 的 plane-mask 应该留空或者不配置。报错二local proxy failed这个报错和 VOP 无关通常出现在你用某些工具拉取依赖或者访问模型服务时。意思是本地代理配置有问题导致请求发不出去。如果你在调试脚本里调用了模型 API遇到这个报错先检查环境变量里的代理设置确认没有残留的失效配置。TaoToken 的 API 调用不需要额外代理直接走https://taotoken.net/api即可。报错三401 Unauthorized调用模型 API 时返回 401说明 API Key 无效或者没带上。检查你的请求头里有没有正确设置Authorization: Bearer your-keykey 是不是从 console 里新生成的。如果 key 刚生成就用有时候会有几秒的生效延迟等一下再试。报错四reading choices相关错误这个通常出现在用某些 CLI 工具比如 Claude Code 或者类似的 coding agent时工具在解析模型返回的 choices 字段时出错。原因可能是返回格式和工具预期的不一致或者模型 ID 填错了。如果你在配置里写了 Model ID确认它和 TaoToken 支持的模型列表一致。Base URL、Key、Model ID 这三件套要配套缺一个都会出问题。报错五OAuth 认证失败如果你用的工具链需要 OAuth 授权比如某些 Git 操作或者包管理报 OAuth 错误说明本地 token 过期了。重新走一遍授权流程即可和 VOP 图层分配没有关系。但如果你在 dts 编译过程中遇到认证问题那可能是 SDK 的 repo 同步需要重新登录检查一下.repo目录下的配置。排查顺序建议先看 dmesg 里的 vop2_bind 输出确认 mask 和 primary 是否符合预期如果 log 正常但屏幕不亮再查屏幕时序和接口配置如果 log 里根本没有 vop2_bind说明 VOP 驱动没加载检查内核配置里CONFIG_ROCKCHIP_VOP2有没有打开。6. 语义一致 CTA把图层分配链路固化下来图层分配这件事配一次能管很久但前提是你把验证方法也固化下来。我的习惯是在板子 bringup 阶段就把 dmesg 里的 vop2_bind 输出存一份基线后面每次改 dts 都 diff 一下确认没有意外变化。如果你在调试过程中需要频繁查驱动源码里的绑定逻辑或者想快速确认某个图层宏的定义可以用 TaoToken 的模型对话来加速。入口在https://taotoken.net/api直接问「RK3588 ROCKCHIP_VOP2_ESMART2 对应哪个物理图层」这类问题比翻头文件快。需要长期做 RK3588 驱动开发的话Coding Plan 能把模型对话和代码补全串起来写 dts 和排查 log 时省不少切换成本。API Keys 在 console 里管理接入文档在 doc 路径下按需取用。最后留一个实用技巧改完 plane-mask 之后先别急着烧录整包单独编译 dtb 替换进去重启验证通过再合入完整固件。这样一轮调试能省好几分钟多试几次就回本了。
返回列表