个人观点,仅供参考......
个人观点,仅供参考......
个人观点,仅供参考......
在嵌入式开发中,RK3588 作为高性能主控,常需搭配 BT1120 接口实现 YCbCr 4:2:2 视频输出,尤其对接 GS2972(SDI 编码芯片)这类场景,调试过程中容易遇到各种报错,比如 DRM 驱动加载失败、PHY 绑定异常、语法错误等。本文结合实际调试经历,从报错定位、配置修正、验证测试三个维度,完整拆解 RK3588 BT1120 输出的调试流程,帮你避开所有坑,实现稳定输出。
适用场景:RK3588 平台 + BT1120 输出 + GS2972 接收、嵌入式 Linux 系统、设备树配置开发,尤其适合刚接触 RK3588 显示 subsystem 的开发者。
一、调试背景与核心需求
需求:RK3588 通过 BT1120 接口输出 YCbCr 4:2:2 格式视频(1080p60),对接 GS2972 SDI 编码芯片,实现视频信号的 SDI 转发。
初始状态:驱动未加载、设备树配置不匹配,出现多种报错(下文逐一拆解),最终通过设备树精细化配置、报错针对性解决,实现 BT1120 正常输出,GS2972 稳定接收。
核心前提:确认硬件连接无误(VP3 引脚与 BT1120 引脚对应、GS2972 供电与复位正常),内核已启用 DRM 驱动(CONFIG_DRM_ROCKCHIP、CONFIG_DRM_ROCKCHIP_VOP2 已开启)。
二、调试过程中遇到的核心报错及解决(重点!)
调试过程中,先后遇到 5 类典型报错,每类报错对应明确的配置问题,以下是报错解析和解决方案,均经过实际验证可直接复用。同时补充常见日志解析,帮助快速判断驱动状态。
报错1:no atomic modesetting support + RK_MPI_VO_GetPubAttr failed
【报错原因】DRM 显示框架未正常加载,VOP(视频输出处理器)与 RGB/BT1120 驱动未绑定,核心是设备树中 VOP 与 RGB 节点的 ports 链路被注释,导致 VP3(BT1120 专用端口)与 RGB 驱动断开连接。
【解决方案】恢复 VOP 与 RGB 节点的 ports 链路,确保 VP3 与 RGB 正确绑定:
// 1. VOP 节点启用 VP3 端口(port@3 对应 VP3)
&vop {
status = "okay";
ports {
port@3 { // VP3 是 BT1120 专用输出端口
reg = <3>;
vp3_out_rgb: endpoint@2 {
reg = <2>;
remote-endpoint = <&rgb_in_vp3>; // 绑定 RGB 输入端点
};
};
};
};
// 2. RGB 节点启用 ports 链路(不可注释)
&rgb {
status = "okay";
pinctrl-0 = <&bt1120_pins>;
// 后续 BT1120 格式配置将补充
ports {
port@0 { // 输入:来自 VOP VP3
reg = <0>;
rgb_in_vp3: endpoint@2 {
reg = <2>;
remote-endpoint = <&vp3_out_rgb>; // 与 VOP 端点对应
};
};
port@1 { // 输出:到 GS2972(需绑定虚拟 panel)
reg = <1>;
rgb_out_panel: endpoint {
remote-endpoint = <&panel_in_rgb>;
};
};
};
};
报错2:remote-endpoint 不匹配(链路断连)
【报错原因】VOP 节点中 vp3_out_rgb 的 remote-endpoint 名称,与 RGB 节点中 endpoint 名称不一致,导致链路绑定失败(比如 VOP 写 &rgb_in_vp3,RGB 节点实际是 rgb_in_vop)。
【解决方案】统一端点名称,确保 VOP 与 RGB 节点的 remote-endpoint 相互对应(核心规则:VOP 的 vp3_out_rgb 指向 RGB 的 rgb_in_vp3,反之亦然)。
报错3:rockchip-rgb: failed to find panel or bridge: -19 / -517
【报错原因】Linux DRM 框架要求,VO 输出(RGB/BT1120)必须连接一个 panel(显示器)或 bridge 节点,否则驱动无法加载;-19 是未找到节点,-517 是节点配置错误(如 ports 嵌套错误)。
【解决方案】添加虚拟 dummy panel(无需实际硬件,仅用于驱动加载),注意 ports 节点格式(复数 ports,单层 port@0,无嵌套错误):
// 根节点下添加虚拟 panel(GS2972 专用,BT1120 内嵌同步)
/ {
bt1120_panel: bt1120-panel {
status = "okay";
compatible = "simple-panel";
display-timings {
native-mode = <&timing_bt1120_1080p60>;
timing_bt1120_1080p60: timing-1080p60 {
clock-frequency = <148500000>; // 1080p60 标准时钟
hactive = <1920>;
vactive = <1080>;
// BT1120 内嵌同步,消隐期可随意填写(内核不使用)
hback-porch = <10>;
hfront-porch = <10>;
hsync-len = <10>;
vback-porch = <10>;
vfront-porch = <10>;
vsync-len = <10>;
// 核心:BT1120 无需独立同步信号,全部设为 0
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <1>; // GS2972 采样沿,默认 1 即可
};
};
ports { // 注意是复数 ports,不可嵌套 port@0
port@0 {
panel_in_rgb: endpoint {
remote-endpoint = <&rgb_out_panel>; // 与 RGB 输出端点对应
};
};
};
};
};
报错4:modetest: undefined symbol: drmModeGetConnectorTypeName
【报错原因】系统自带 modetest 工具版本过旧,不兼容当前 DRM 库,无法用于 BT1120 验证,并非驱动配置问题。
【解决方案】放弃 modetest,使用 RK 原厂工具或 gstreamer 进行验证(下文会详细说明)。
报错5:bus-format = <MEDIA_BUS_FMT_YUYV8_1X16>; 语法错误
【报错原因】MEDIA_BUS_FMT_YUYV8_1X16 是内核头文件中的宏,设备树(DTS)无法识别,直接使用会导致编译报错。
【解决方案】用宏对应的十六进制数值代替,BT1120 YCbCr 4:2:2 格式(YUYV8_1X16)对应的数值为 0x2006(RK3588 官方标准值)。
日志解析:rockchip-drm display-subsystem: bound fd58c000.syscon:rgb (ops 0xffffffc011126960)
【日志含义】这是 正常日志,并非报错!表示 RK3588 的 DRM 显示子系统已成功绑定 RGB/BT1120 驱动,驱动加载正常,无需排查驱动绑定问题。
【关键提示】出现该日志,说明:
-
RGB/BT1120 驱动已被 DRM 框架识别并绑定,无驱动加载失败问题;
-
设备树中 &rgb 节点 status = "okay" 配置生效,链路未断开;
-
若此时仍无法正常输出(如 gstreamer 报错),需排查 VP3 链路绑定 、虚拟 panel 配置 或 视频格式协商(与驱动加载无关)。
【后续排查方向】出现该日志后,若输出异常,优先执行以下操作:
-
检查 &vp3_out_rgb 和 &rgb_in_vp3 节点 status = "okay",且 remote-endpoint 相互对应;
-
确认虚拟 panel 配置无误(hsync-active、vsync-active、de-active 均为 0,无 ports 嵌套错误);
-
用修正后的 gstreamer 命令验证(指定 connector_id 和格式),避开格式协商问题。
三、RK3588 + GS2972 BT1120 最终完整配置(可直接编译)
整合所有修正点,给出完整可直接复用的设备树配置,适配 1080p60 BT1120 输出,对接 GS2972 芯片,无任何语法错误和链路问题。
1. 虚拟 panel 配置(根节点下)
/ {
bt1120_panel: bt1120-panel {
status = "okay";
compatible = "simple-panel";
display-timings {
native-mode = <&timing_bt1120_1080p60>;
timing_bt1120_1080p60: timing-1080p60 {
clock-frequency = <148500000>;
hactive = <1920>;
vactive = <1080>;
hback-porch = <10>;
hfront-porch = <10>;
hsync-len = <10>;
vback-porch = <10>;
vfront-porch = <10>;
vsync-len = <10>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <1>;
};
};
ports {
port@0 {
panel_in_rgb: endpoint {
remote-endpoint = <&rgb_out_panel>;
};
};
};
};
};
2. RGB 节点配置(BT1120 模式)
&rgb {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&bt1120_pins>;
// BT1120 YCbCr 4:2:2 配置(GS2972 标准输入)
bus-format = <0x2006>; // 替代 MEDIA_BUS_FMT_YUYV8_1X16
rockchip,mode = "bt1120";
rockchip,bits = <8>;
rockchip,data-sync-bypass; // 开启 BT1120 内嵌同步(关键)
ports {
// 输入:来自 VOP VP3
port@0 {
reg = <0>;
rgb_in_vp3: endpoint@2 {
reg = <2>;
remote-endpoint = <&vp3_out_rgb>;
};
};
// 输出:到 GS2972(绑定虚拟 panel)
port@1 {
reg = <1>;
rgb_out_panel: endpoint {
remote-endpoint = <&panel_in_rgb>;
};
};
};
};
3. VOP 节点配置(启用 VP3)
&vop {
status = "okay";
};
// 确保 VP3 与 RGB 链路启用
&vp3_out_rgb {
remote-endpoint = <&rgb_in_vp3>;
status = "okay";
};
&rgb_in_vp3 {
status = "okay";
};
// 启用 RGB 路由
&route_rgb {
status = "okay";
};
4. 补充说明(GS2972 适配关键)
-
GS2972 是 SDI 编码芯片,仅支持 BT1120 内嵌同步(SAV/EAV),无需独立 HS/VS/DE 信号,因此 panel 中 hsync-active、vsync-active、de-active 必须设为 0;
-
pixelclk-active 为数据采样沿,若 GS2972 接收不到信号,可切换为 0 尝试;
-
无需给 GS2972 单独配置设备树,硬件电阻上下拉即可完成配置,只需确保 RK3588 BT1120 输出格式正确。
四、验证测试(确保 BT1120 正常输出)
配置编译完成后,重启设备,通过以下命令验证驱动加载和输出状态,确保 GS2972 能稳定接收信号。
1. 驱动加载验证
# 查看 RGB 驱动加载状态
dmesg | grep rgb
若出现以下日志,说明驱动加载成功:
rockchip-rgb fd58c000.syscon:rgb: probe success
rockchip-drm display-subsystem: bound fd58c000.syscon:rgb (ops 0xffffffc011126960)
2. 视频输出验证(替代 modetest)
由于 modetest 工具兼容问题,使用 gstreamer 输出测试,直接验证 BT1120 输出是否正常:
# 输出 YCbCr 4:2:2 彩条(GS2972 可直接接收)
gst-launch-1.0 videotestsrc ! video/x-raw,format=YUY2,width=1920,height=1080,framerate=60/1 ! kmssink connector_id=3
# 输出纯红色测试(方便观察 GS2972 接收状态)
gst-launch-1.0 videotestsrc pattern=solid color=0xff0000 ! video/x-raw,format=YUY2 ! kmssink
# 播放本地 MP4(自动转为 YCbCr 格式输出)
gst-launch-1.0 filesrc location=/test.mp4 ! qtdemux ! h264parse ! v4l2h264dec ! videoconvert ! video/x-raw,format=YUY2 ! kmssink
3. DRM 状态验证
# 查看 DRM 显示状态,确认 BT1120 格式
cat /sys/kernel/debug/dri/0/summary
若出现以下内容,说明 BT1120 输出正常:
bus_format: YUYV8_1X16
output_mode: BT1120
五、常见问题补充(避坑指南)
1. GS2972 接收不到信号?
排查要点:① 检查 pixelclk-active 采样沿(切换 0/1);② 确认 RK3588 BT1120 引脚与 GS2972 输入引脚对应;③ 检查 GS2972 供电、复位是否正常;④ 确认 bus-format 为 0x2006(YUYV8_1X16)。
2. 编译设备树报错?
排查要点:① 确保 bus-format 使用十六进制数值(0x2006),不使用宏;② 检查 ports 节点格式(复数 ports,无嵌套);③ 确认所有 endpoint 的 remote-endpoint 名称一致;④ 检查节点闭合(无语法错误)。
3. 驱动加载成功,但无输出?
排查要点:① 确认 route_rgb 节点 status 为 okay;② 检查 VOP 与 RGB 的 endpoint 状态为 okay;③ 用 gstreamer 重新执行输出命令,确认视频格式为 YUY2、指定正确的 connector_id。
4. 切换为 RGB888 输出?
若需切换为 RGB888 并行输出,只需修改 RGB 节点配置:
&rgb {
status = "okay";
pinctrl-0 = <&bt1120_pins>;
bus-format = <0x100a>; // RGB888_1X24 对应数值
rockchip,mode = "rgb"; // 切换为 rgb 模式
rockchip,bits = <8>;
// ports 链路保持不变
};
5. gstreamer 报错:Internal data stream error, reason not-negotiated (-4)?
【报错原因】视频流格式与 BT1120 输出不匹配,或 DRM 未识别输出端口(未指定 connector_id)。
【解决方案】① 执行 `cat /sys/kernel/debug/dri/0/summary` 查看 BT1120 对应的 connector_id;② 用指定 connector_id 的命令:`gst-launch-1.0 videotestsrc ! video/x-raw,format=YUY2,width=1920,height=1080,framerate=60/1 ! kmssink connector_id=3`(替换 3 为实际 connector_id);③ 若仍报错,用简化命令:`gst-launch-1.0 videotestsrc pattern=0 ! kmssink`。
六、总结
RK3588 BT1120 输出调试的核心,在于「链路绑定正确、格式配置匹配、驱动加载正常」,其中最容易踩坑的是:设备树 ports 链路注释、remote-endpoint 名称不匹配、bus-format 宏使用错误、虚拟 panel 配置不当。