2. Linux DRM/KMS 框架基础

DRM (Direct Rendering Manager) 与 KMS (Kernel Mode Setting) 是 Linux 图形显示子系统的核心框架。在 RK3588 平台上,所有显示输出(HDMI、DP、MIPI DSI、eDP)均通过 DRM/KMS 统一管理。理解其核心对象及关系,是进行显示驱动故障排查的前提。

2.1 DRM 核心概念

DRM 框架将显示流水线抽象为五个核心对象:CRTC、Encoder、Connector、Plane 和 Framebuffer。此外,Bridge 作为可选的中间节点,常用于外接转换芯片(如 LT6911C、IT66121)。

核心对象 功能描述 RK3588 典型实例
CRTC 显示控制器,负责扫描输出、时序生成、图层混合 VP0 ~ VP3(4 个视频通路)
Encoder 编码器,将 CRTC 输出的并行数据转换为串行信号 DP0、HDMI_TX0、DSI0
Connector 物理连接器,代表实际的显示接口,检测热插拔与 EDID HDMI-A-1、DP-1、DSI-1
Plane 硬件图层,每个 Plane 可绑定一个 Framebuffer Primary、Overlay、Cursor
Framebuffer 内存中的帧缓冲区,存储像素数据 dma-buf 分配,格式 ARGB8888
Bridge 桥接芯片,位于 Encoder 与 Connector 之间 LT6911C (HDMI→MIPI)
排查要点: 在 RK3588 上,CRTC 对应 VP(Video Port),每个 VP 可独立绑定一个 Encoder。故障时首先检查 /sys/kernel/debug/dri/0/state 确认各对象连接状态。

2.2 对象关系图

下图展示了 DRM/KMS 核心对象之间的数据流与控制流关系。数据从 Framebuffer 出发,经 Plane 合成,由 CRTC 控制时序,通过 Encoder 编码,最终经 Connector 输出到显示器。Bridge 作为可选节点插入在 Encoder 与 Connector 之间。

DRM/KMS 核心对象关系图 DRM/KMS 核心对象关系图 Framebuffer Plane CRTC (VP0~VP3) Encoder Bridge (可选) Connector 显示器 数据流方向 Framebuffer → Plane → CRTC → Encoder → [Bridge] → Connector

2.3 对象绑定与拓扑

在 RK3588 上,DRM 对象通过 atomic commit 建立绑定关系。一个典型的显示拓扑如下:

  1. Framebuffer 绑定到 Plane:通过 drmModeSetPlane() 或 atomic 接口设置。
  2. Plane 绑定到 CRTC:每个 CRTC 可关联多个 Plane(主层、覆盖层、光标层)。
  3. CRTC 绑定到 Encoder:通过 drmModeSetCrtc() 建立连接。
  4. Encoder 绑定到 Connector:Encoder 与 Connector 通过 possible_clones 和 possible_crtcs 掩码匹配。
  5. Bridge 插入在 Encoder 与 Connector 之间:通过 drm_bridge_add() 注册,自动参与链路。
RK3588 实战提示: 使用 modetest -M rockchip -p 可以查看当前 DRM 对象的绑定关系。若某个 Connector 显示 "connected" 但无 CRTC 绑定,通常表示显示链路未完成初始化。

2.4 Plane 与 Framebuffer 详解

Plane 是 DRM 中负责图层合成的硬件单元。RK3588 的 VOP (Video Output Processor) 支持多个硬件层,每个层对应一个 Plane。Framebuffer 则代表内存中的具体帧数据。

Plane 类型 用途 RK3588 数量 常见格式
Primary 主显示层,必须存在 每 VP 1 个 ARGB8888, XRGB8888
Overlay 叠加层,用于视频或 UI 叠加 每 VP 2~3 个 NV12, YUYV, ARGB8888
Cursor 硬件光标层 每 VP 1 个 ARGB8888 (64x64)

Framebuffer 的创建流程:

// 分配 dma-buf 内存
int fd = open("/dev/dri/card0", O_RDWR);
struct drm_mode_create_dumb create = {0};
create.width = 1920;
create.height = 1080;
create.bpp = 32;
ioctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);

// 添加 Framebuffer
uint32_t fb_id;
drmModeAddFB(fd, create.width, create.height, 24, 32,
              create.pitch, create.handle, &fb_id);

2.5 Bridge 在 RK3588 中的角色

Bridge 是 DRM 框架中用于连接 Encoder 与 Connector 的抽象层,特别适用于外接转换芯片场景。RK3588 的显示链路中,Bridge 的典型应用包括:

  • HDMI 转 MIPI DSI:如 LT6911C,将 HDMI 信号转换为 MIPI DSI 驱动液晶屏。
  • eDP 转 LVDS:如 SN65DSI84,将 eDP 信号转换为 LVDS 驱动老式屏。
  • DP 转 HDMI 2.0:如 IT66121,用于扩展 HDMI 输出。

Bridge 的注册与链路建立:

// 在设备树中定义 bridge 节点
<span class="hljs-attr">hdmi_to_mipi_bridge: lt6911c@2b {</span>
    compatible = "lontium,lt6911c";
    reg = <0x2b>;
    pinctrl-names = "default";
    pinctrl-0 = <&lt6911c_int>;
    interrupt-parent = <&gpio1>;
    interrupts = <RK_PA5 IRQ_TYPE_LEVEL_LOW>;
    ports {
        #address-cells = <1>;
        #size-cells = <0>;
        port@0 {
            reg = <0>;
            lt6911c_in: endpoint {
                remote-endpoint = <&hdmi_out>;
            };
        };
        port@1 {
            reg = <1>;
            lt6911c_out: endpoint {
                remote-endpoint = <&dsi_in>;
            };
        };
    };
};
常见故障: Bridge 初始化失败通常导致 "No connector found" 或 "EDID read failed"。排查时检查 dmesg 中 bridge 驱动的 probe 日志,确认 I2C 通信是否正常。

2.6 对象关系总结

DRM/KMS 框架通过清晰的层次化对象管理显示流水线。在 RK3588 平台上,理解以下关系是故障排查的基础:

  • 数据流:Framebuffer → Plane → CRTC → Encoder → [Bridge] → Connector → 显示器
  • 控制流:用户空间通过 DRM ioctl 设置每个对象的属性,atomic commit 一次性提交所有变更。
  • 调试入口:/sys/kernel/debug/dri/0/state 显示完整对象拓扑,modetest 提供用户空间验证手段。