2. Linux DRM 框架简介:DRM/KMS 架构、CRTC/Encoder/Connector/Plane 概念、设备树与驱动绑定

DRM(Direct Rendering Manager)是 Linux 内核中负责图形显示与渲染的核心框架。自内核 2.6.9 引入以来,DRM 已从最初的 GPU 管理扩展为包含 KMS(Kernel Mode Setting)的完整显示栈。对于 MIPI DSI 嵌入式显示驱动开发,理解 DRM/KMS 架构是编写高质量驱动的基石。

2.1 DRM/KMS 整体架构

DRM 框架分为两层:DRM Core 提供用户空间接口(/dev/dri/card0)、GEM 内存管理、Fence 同步机制;KMS 负责显示模式设置、扫描输出、显示流水线控制。KMS 是驱动开发者最常打交道的部分,它抽象了显示硬件为四个核心对象:CRTC、Encoder、Connector、Plane。

架构要点: DRM 驱动通过注册 struct drm_driver 和 struct drm_mode_config_funcs 向核心层暴露硬件能力。KMS 对象通过 drm_mode_config 统一管理,用户空间通过 Atomic API 或 Legacy API 提交显示状态。
DRM/KMS 整体架构 用户空间 (libdrm / Mesa / Wayland / Weston) 内核空间 DRM Core /dev/dri/card0 · GEM · Fence drm_driver · drm_file KMS (Kernel Mode Setting) drm_mode_config · Atomic API CRTC · Encoder · Connector · Plane 硬件抽象层 (GPU / Display Controller / DSI Host / PHY) 硬件 (LCD Panel / MIPI DSI Device / eDP / HDMI)

2.2 核心 KMS 对象:CRTC / Encoder / Connector / Plane

KMS 将显示流水线拆解为四个职责明确的对象。理解它们之间的关系是调试 MIPI DSI 显示的关键。

KMS 对象 内核结构体 职责描述 MIPI DSI 场景对应
CRTC struct drm_crtc 扫描输出控制:时序生成、帧缓冲切换、VBLANK 中断 DSI 主机控制器的时序引擎
Encoder struct drm_encoder 像素数据编码转换:RGB → MIPI DSI / LVDS / HDMI DSI D-PHY 发送器 + 协议打包
Connector struct drm_connector 物理连接检测:EDID 读取、热插拔、显示参数 DSI 面板设备(固定连接,无热插拔)
Plane struct drm_plane 图层叠加:缩放、旋转、色彩空间转换、Alpha 混合 硬件图层(主图层 / 光标图层 / 视频图层)
调试提示: 在 MIPI DSI 驱动中,Connector 通常不实现热插拔检测(HPD),而是通过 drm_connector_init() 固定为 connector_type = DRM_MODE_CONNECTOR_DSI。CRTC 和 Encoder 之间通过 drm_crtc_init_with_planes() 绑定。
KMS 核心对象关系与数据流 Plane 帧缓冲 · 图层 缩放 · Alpha CRTC 时序生成 VBLANK · 扫描 Encoder 编码转换 DSI/LVDS/HDMI Connector 物理连接 EDID · 热插拔 像素数据 RGB 流 编码后信号 🔗 绑定关系: Plane → CRTC → Encoder → Connector → Panel 一个 CRTC 可绑定多个 Plane(主图层 + 光标);一个 Encoder 通常对应一个 Connector。

2.3 设备树与驱动绑定

在嵌入式 Linux 中,DRM 驱动通过设备树(Device Tree)描述硬件拓扑,驱动核心通过 of_match_table 匹配设备节点。MIPI DSI 的设备树绑定遵循 Documentation/devicetree/bindings/display/ 下的规范。

2.3.1 典型 MIPI DSI 设备树结构

/* 示例:i.MX8M Plus MIPI DSI 设备树节点 */
&mipi_dsi {
    status = "okay";
    #address-cells = <1>;
    #size-cells = <0>;

    panel@0 {
        compatible = "boe,tv110c9m-ll08";
        reg = <0>;
        reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
        backlight = <&backlight_lcd0>;
        dsi-lanes = <4>;
        rotation = <0>;

        port {
            panel_in: endpoint {
                remote-endpoint = <&mipi_dsi_out>;
            };
        };
    };

    ports {
        port@1 {
            reg = <1>;
            mipi_dsi_out: endpoint {
                remote-endpoint = <&panel_in>;
            };
        };
    };
};
常见绑定错误: 忘记设置 dsi-lanes 属性会导致 D-PHY 初始化失败;reset-gpios 极性错误(GPIO_ACTIVE_LOW vs GPIO_ACTIVE_HIGH)会导致面板无法退出复位状态。务必对照面板数据手册确认时序和 GPIO 极性。

2.3.2 驱动绑定流程

DRM 驱动通过 component 框架或 drm_bridge 框架实现模块化绑定。MIPI DSI 主机控制器驱动通常实现 struct mipi_dsi_host_ops,面板驱动实现 struct mipi_dsi_driver。

步骤 驱动侧 关键函数 / 回调 说明
1 DSI 主机控制器 probe() → mipi_dsi_host_register() 注册 DSI 主机,初始化 D-PHY 和时钟
2 DSI 面板 probe() → mipi_dsi_device_register_full() 解析设备树,分配 DSI 设备 ID
3 DSI 主机控制器 host_ops.attach() 建立 DSI 总线连接,配置传输模式
4 DRM 桥接 / 组件 drm_bridge_add() / component_add() 将面板作为 DRM 桥接器加入显示链
5 DRM CRTC drm_crtc_init_with_planes() 初始化 CRTC 并关联主 Plane
6 DRM Connector drm_connector_init() + drm_connector_attach_encoder() 注册 Connector 并绑定到 Encoder
设备树 → 驱动绑定流程 设备树 (DTB) mipi_dsi + panel 节点 of_match_table 匹配 compatible 属性比对 DSI 主机驱动 mipi_dsi_host_register DSI 面板驱动 mipi_dsi_driver.probe DRM 组件绑定 drm_bridge / component 显示链就绪:CRTC → Encoder → Connector → Panel

2.4 关键数据结构与 API 速查

驱动开发中频繁使用的 DRM 核心 API 和数据结构如下表所示。建议在编写驱动时参考内核源码 include/drm/drm_* 头文件。

类别 结构体 / 函数 用途
CRTC drm_crtc_init_with_planes() 初始化 CRTC 并绑定主 Plane 和光标 Plane
CRTC struct drm_crtc_funcs 实现 .set_config、.page_flip、.atomic_begin 等回调
Encoder drm_encoder_init() 注册 Encoder,指定可能的 CRTC 掩码
Connector drm_connector_init() 注册 Connector,指定类型(DSI/eDP/HDMI)
Connector drm_connector_attach_encoder() 将 Connector 绑定到 Encoder
Plane drm_universal_plane_init() 初始化 Plane,支持格式列表和属性
Bridge drm_bridge_add() / drm_bridge_attach() 桥接器模式,用于面板或转换芯片
Atomic drm_atomic_state_alloc() / drm_atomic_commit() 原子模式设置,保证显示状态切换无撕裂
调试切入点: 当 MIPI DSI 面板无显示时,首先检查 /sys/kernel/debug/dri/0/ 下的 KMS 对象状态:cat state 查看 CRTC/Encoder/Connector 连接关系;cat clients 查看用户空间占用。使用 modetest 工具可以手动设置模式测试显示链是否完整。

2.5 本章小结

  • DRM/KMS 是 Linux 显示驱动的标准框架,KMS 提供 CRTC、Encoder、Connector、Plane 四个核心抽象。
  • MIPI DSI 驱动中,CRTC 对应时序引擎,Encoder 对应 D-PHY 编码,Connector 对应面板设备,Plane 对应硬件图层。
  • 设备树通过 compatible 属性匹配驱动,DSI 主机和面板通过 mipi_dsi_host_ops 和 mipi_dsi_driver 实现总线绑定。
  • 驱动绑定流程遵循:设备树解析 → 主机注册 → 面板探测 → DRM 组件聚合 → 显示链就绪。
  • 调试时善用 /sys/kernel/debug/dri/ 和 modetest 工具验证 KMS 对象状态。