3. DRM 核心概念:CRTC、Encoder、Connector、Plane、FB、Vblank
DRM (Direct Rendering Manager) 是 Linux 内核中负责显示输出的核心框架。在瑞芯微平台驱动开发中,理解 DRM 的六大核心对象是编写显示驱动的基石。本章将逐一剖析这些对象的功能、协作关系以及在 RK 平台上的典型实现。
3.1 六大核心对象概览
DRM 框架将显示输出链路抽象为一条“数据管道”:从内存中的图像数据开始,经过图形处理、格式转换、时序生成,最终输出到物理显示设备。下表总结了每个核心对象在管道中的角色:
| 对象 | 全称 | 核心职责 | 瑞芯微平台对应硬件 |
|---|---|---|---|
| CRTC | Cathode Ray Tube Controller | 生成显示时序、扫描控制、帧切换 | VOP (Video Output Processor) |
| Encoder | Encoder | 将 CRTC 输出的并行信号编码为外部接口协议 | HDMI TX、DP PHY、MIPI DSI |
| Connector | Connector | 物理连接器检测、EDID 读取、热插拔管理 | HDMI Connector、DP Connector |
| Plane | Plane | 图像层管理、Alpha 混合、缩放、旋转 | VOP 的 Win0/Win1/Win2 图层 |
| FB | Framebuffer | 物理内存中的像素数据缓冲区 | DDR 中的 DMA Buffer |
| Vblank | Vertical Blanking Interval | 帧消隐期中断与同步信号 | VOP 的帧中断 |
3.2 核心对象详解
3.2.1 CRTC — 显示控制核心
CRTC 是显示管道的“大脑”,负责生成像素时钟、行同步、场同步等时序信号,并控制帧缓冲区的切换。在瑞芯微平台上,CRTC 对应 VOP (Video Output Processor) 模块。
CRTC 的主要功能包括:
- 时序生成: 根据 Modeline 参数生成 HFP、HBP、VFP、VBP 等时序。
- 帧切换: 在 Vblank 期间安全切换 Framebuffer 地址,防止画面撕裂。
- Gamma 校正: 对输出像素进行颜色查找表 (LUT) 映射。
- 电源管理: 控制 VOP 模块的时钟门控与电源域。
struct rockchip_crtc_state 扩展了 DRM 原生的 struct drm_crtc_state,用于保存 VOP 特有的输出模式、图层配置和时钟参数。
3.2.2 Encoder — 信号编码器
Encoder 负责将 CRTC 输出的并行 RGB/YCbCr 信号转换为特定显示接口的串行协议。RK 平台常见的 Encoder 类型包括:
- HDMI Encoder: 将并行数据编码为 TMDS 差分信号,支持音频嵌入。
- DP Encoder: 将数据打包为 DisplayPort 微包,支持更高带宽。
- MIPI DSI Encoder: 将数据转换为 DSI 协议包,用于连接 MIPI 屏幕。
- LVDS Encoder: 将并行数据转换为 LVDS 差分对,用于工控屏。
Encoder 与 CRTC 之间通过 drm_encoder.crtc 指针建立连接。在 RK 驱动中,通常使用 dw_hdmi 或 analogix_dp 等桥接驱动来实现 Encoder 功能。
3.2.3 Connector — 物理连接器
Connector 代表物理显示接口,负责检测设备连接状态、读取显示器 EDID 数据以及提供物理属性(如最大分辨率、接口类型)。
Connector 的核心操作:
- 热插拔检测: 通过 GPIO 中断或 I2C 检测显示器插入/拔出。
- EDID 读取: 通过 DDC 通道读取显示器支持的时序列表。
- 状态上报: 将连接状态和显示模式上报给 DRM 核心。
3.2.4 Plane — 显示图层
Plane 是 DRM 中负责图像合成的基本单元。每个 Plane 对应一个独立的显示层,支持独立的 Framebuffer、位置、大小、Alpha 值和像素格式。RK VOP 通常提供 3 个硬件图层:
- Win0: 主图层,支持 RGB 和 YUV 格式,支持缩放。
- Win1: 辅助图层,支持 RGB 格式,支持 Alpha 混合。
- Win2: 光标层,支持 ARGB 格式,通常用于鼠标指针。
Plane 的类型:
| 类型 | 用途 | 典型限制 |
|---|---|---|
| DRM_PLANE_TYPE_PRIMARY | 主显示层,必须存在 | 通常绑定 CRTC,不可移动 |
| DRM_PLANE_TYPE_OVERLAY | 叠加层,用于画中画、字幕 | 数量有限,受硬件图层数限制 |
| DRM_PLANE_TYPE_CURSOR | 硬件光标层 | 尺寸小(通常 64x64),格式受限 |
3.2.5 FB — 帧缓冲区
Framebuffer (FB) 是 DRM 中表示物理内存中图像数据的对象。它封装了像素数据的物理地址、格式、步长和尺寸信息。FB 通过 drm_framebuffer 结构体管理,其生命周期由 DRM 核心的引用计数控制。
FB 的关键属性:
- 像素格式: DRM_FORMAT_XRGB8888、DRM_FORMAT_NV12 等。
- pitches: 每行像素的字节数(步长)。
- offsets: 各颜色分量的偏移地址(用于 YUV 格式)。
- modifier: 内存布局修饰符(如 DRM_FORMAT_MOD_LINEAR、AFBC)。
drm_fb_cma_get_gem_obj 获取 DMA-BUF 并配置 VOP 的 AFBC 解码器。
3.2.6 Vblank — 垂直消隐期
Vblank 是 CRTC 在完成一帧扫描后、开始下一帧扫描前的短暂间隔。在此期间更新 Framebuffer 地址或 Plane 属性可以避免画面撕裂 (Tearing)。
Vblank 在驱动中的典型用途:
- 帧同步: 用户态程序通过
DRM_IOCTL_WAIT_VBLANK等待 Vblank 事件。 - Page Flip: 在 Vblank 中断中安全切换 FB 地址。
- 统计 FPS: 通过 Vblank 中断计数计算刷新率。
RK 平台 Vblank 中断处理流程:
// 在 VOP 驱动中注册 Vblank 中断处理函数
static irqreturn_t vop_isr(int irq, void *dev_id)
{
struct vop *vop = dev_id;
uint32_t intr_status;
intr_status = vop_readl(vop, VOP_INTR_STATUS);
if (intr_status & FS_INTR) {
// 通知 DRM 核心 Vblank 事件发生
drm_crtc_handle_vblank(&vop->crtc);
// 处理 Page Flip 回调
if (vop->pending_flip)
vop_flip_done(vop);
}
return IRQ_HANDLED;
}
3.3 核心对象协作关系
下图展示了 DRM 核心对象在显示输出管道中的完整协作流程:
3.4 对象注册与绑定流程
在 RK 平台驱动初始化时,需要按照特定顺序注册这些 DRM 对象。典型的 Probe 函数流程如下:
- 分配 CRTC: 调用
drm_crtc_init_with_planes()注册 VOP 为 CRTC。 - 注册 Plane: 调用
drm_universal_plane_init()注册 Win0/Win1/Win2 图层。 - 注册 Encoder: 调用
drm_encoder_init()注册 HDMI/DP/MIPI 编码器。 - 注册 Connector: 调用
drm_connector_init()注册物理连接器,并绑定drm_connector_funcs回调。 - 建立连接: 通过
drm_mode_connector_attach_encoder()将 Connector 绑定到 Encoder。 - 注册 Vblank 处理: 调用
drm_vblank_init()初始化 Vblank 支持,并注册中断处理函数。
rockchip_drm_bind() 函数中,会先通过 component_bind_all() 绑定所有 VOP 子节点,然后按上述顺序完成 DRM 对象的注册。这种设计利用了 Linux 组件框架来管理 VOP 内部的多个硬件模块。
3.5 Atomic 模式下的对象交互
现代 DRM 驱动(包括 RK 平台)使用 Atomic 模式 管理显示状态更新。在 Atomic 模式下,所有对象的状态变更被收集到一个 drm_atomic_state 事务中,然后一次性提交。关键交互点包括:
- CRTC 状态检查:
atomic_check回调验证时序和时钟可行性。 - Plane 状态更新:
atomic_update回调配置 VOP 图层寄存器。 - FB 引用管理: Atomic 框架自动处理 FB 的引用计数,确保在 Vblank 完成前 FB 不会被释放。
- Vblank 同步:
drm_atomic_helper_commit在 Vblank 期间执行硬件寄存器更新。
下表总结了 Atomic 模式下各对象的回调函数:
| 对象 | Atomic Check 回调 | Atomic Commit 回调 |
|---|---|---|
| CRTC | crtc_helper->atomic_check |
crtc_helper->atomic_flush |
| Plane | plane_helper->atomic_check |
plane_helper->atomic_update |
| Encoder | encoder_helper->atomic_check |
encoder_helper->atomic_mode_set |
| Connector | connector_helper->atomic_check |
connector_helper->atomic_commit |
cat /sys/kernel/debug/dri/0/state 查看当前 Atomic 状态树,确认 CRTC、Plane、Connector 的绑定关系是否正确。