2. CRTC 核心概念:时序生成、扫描输出模型与同步机制

CRTC(Cathode Ray Tube Controller,阴极射线管控制器)是 DRM/KMS 显示子系统的核心调度单元,负责将 内存中的帧缓冲区(Framebuffer) 转换为 显示面板所需的时序信号,并驱动像素从 CRTC 经编码器(Encoder)最终到达连接器(Connector)。理解 CRTC 的时序生成模型与同步机制,是开发多图层显示驱动的基础。

核心认知:CRTC 本质上是一个“像素时钟发生器 + 扫描控制器”。它不直接操作像素数据,而是通过生成精确的同步信号(HSync、VSync、DE)来协调显示控制器逐行逐帧地从内存中取出像素数据,并发送给显示面板。

2.1 CRTC 的作用与职责

在 DRM/KMS 架构中,CRTC 处于 Plane(图层)与 Encoder(编码器)之间的枢纽位置。其主要职责包括:

  • 时序生成:根据显示模式(如 1920x1080@60Hz)生成水平同步(HSync)、垂直同步(VSync)和数据使能(DE)信号。
  • 扫描输出:控制从帧缓冲区到显示面板的像素扫描顺序(从左到右、从上到下),并处理消隐区(Blanking)的插入。
  • 图层合成:接收来自多个 Plane 的像素数据,在内部进行 Alpha 混合或叠加,生成最终的合成帧。
  • 模式设置:响应应用层通过 DRM IOCTL 提交的 drm_mode_set 请求,切换分辨率、刷新率或色彩深度。
  • Vblank 管理:在每帧扫描结束后的垂直消隐期(VBlank)触发中断,通知 GPU 或应用层更新帧缓冲区,避免撕裂(Tearing)。
CRTC 在 DRM/KMS 中的枢纽位置 CRTC 在 DRM/KMS 显示流水线中的枢纽位置 Plane 0 (主图层) Plane 1 (光标) Plane 2 (视频) CRTC 时序生成 + 合成 VBlank 中断管理 Encoder (eDP/HDMI/DP) 说明: CRTC 从多个 Plane 接收像素数据,合成后生成带时序信号的像素流,传递给 Encoder 进行串行化传输。 VBlank 中断由 CRTC 在垂直消隐期触发,是驱动更新帧缓冲区的关键同步点。

2.2 时序生成模型:VESA 标准与消隐区

CRTC 的时序生成严格遵循 VESA(Video Electronics Standards Association)标准。一个完整的显示帧由 有效显示区(Active Area) 和 消隐区(Blanking Area) 组成。消隐区又细分为前肩(Front Porch)、同步脉冲(Sync Pulse)和后肩(Back Porch)。

时序参数 符号 说明 典型值 (1920x1080@60Hz)
水平有效像素 HActive 一行中实际显示的像素数 1920
水平前肩 HFP 有效像素结束到 HSync 脉冲开始 88
水平同步宽度 HSync HSync 脉冲持续宽度 44
水平后肩 HBP HSync 脉冲结束到下一行有效像素开始 148
水平总像素 HTotal HActive + HFP + HSync + HBP 2200
垂直有效行数 VActive 一帧中实际显示的行数 1080
垂直前肩 VFP 有效行结束到 VSync 脉冲开始 4
垂直同步宽度 VSync VSync 脉冲持续行数 5
垂直后肩 VBP VSync 脉冲结束到下一帧有效行开始 36
垂直总行数 VTotal VActive + VFP + VSync + VBP 1125
驱动开发提示:在实现 CRTC 的 mode_set 回调时,必须将上述时序参数正确写入显示控制器的硬件寄存器。常见的错误是 HTotal/VTotal 计算错误,导致显示偏移或刷新率不准确。建议使用 drm_mode_vrefresh() 辅助函数验证时序。
CRTC 水平时序与垂直时序示意图 CRTC 水平时序与垂直时序示意图 水平时序 (一行) HActive (1920) HFP HSync HBP → HTotal = 2200 垂直时序 (一帧) VActive (1080) VFP VSync VBP → VTotal = 1125 关键点: 消隐区(HFP+HSync+HBP / VFP+VSync+VBP)不传输有效像素数据,但用于同步和恢复。CRTC 在消隐期不读取内存, 因此 VBlank 期间是更新帧缓冲区的最佳时机,可避免撕裂。

2.3 扫描输出模型:从内存到像素

CRTC 的扫描输出模型描述了像素数据如何从帧缓冲区(Framebuffer)经过扫描转换,最终形成显示面板所需的像素流。该模型包含三个关键阶段:

  1. 内存读取(Fetch):CRTC 根据当前扫描位置(行、列)计算帧缓冲区中的像素地址,通过 DMA 引擎读取像素数据。对于多 Plane 场景,CRTC 需要同时从多个缓冲区读取数据。
  2. 合成与混合(Blend):如果硬件支持,CRTC 内部会执行 Alpha 混合,将主图层、光标图层、视频图层等叠加为单一像素流。混合顺序通常由 Z-order 决定。
  3. 时序封装(Timing Insertion):在有效像素之间插入 HSync、VSync 和 DE 信号,形成符合面板规格的并行像素接口(如 RGB/DPI)或串行接口(如 LVDS/eDP)。
CRTC 扫描输出模型流水线 CRTC 扫描输出模型流水线 阶段 1: 内存读取 DMA 从 Framebuffer 取像素 地址 = base + y × stride + x × bpp 阶段 2: 合成混合 Alpha 混合多个 Plane 输出 = Σ(α_i × Pixel_i) 阶段 3: 时序封装 插入 HSync/VSync/DE 输出并行/串行像素流 驱动实现要点: • 阶段1:CRTC 的 atomic_update 回调中需配置帧缓冲区地址、跨度(stride)和像素格式。 • 阶段2:如果硬件不支持硬件混合,驱动需在 CRTC 中禁用多余 Plane,由用户空间通过 GPU 合成。 • 阶段3:时序参数通过 drm_display_mode 结构体传递,驱动需将其转换为硬件寄存器值。

2.4 与显示面板的同步机制

CRTC 与显示面板之间的同步通过 硬件握手信号 实现,确保像素流与面板的扫描节奏一致。同步机制分为两种模式:

同步模式 信号线 工作原理 典型场景
内同步(PCLK + HSync + VSync) Pixel Clock, HSync, VSync, DE CRTC 主动生成所有时序信号,面板被动接收。CRTC 控制扫描节奏,面板只需在 DE 有效时锁存像素。 LCD 显示屏、eDP、HDMI
外同步(TE/VSync 输入) TE (Tearing Effect) 或 VSync 输入 面板主动发送同步脉冲(如 TE 信号),CRTC 等待该信号后再开始下一帧的扫描输出。用于避免撕裂。 MIPI DSI 面板、部分 OLED
常见陷阱:在内同步模式下,如果 CRTC 的像素时钟(PCLK)与面板的规格不匹配(例如 PCLK 频率偏差超过 ±1%),会导致显示闪烁或黑屏。在外同步模式下,如果 TE 信号丢失或频率异常,CRTC 可能陷入死等状态,驱动需实现超时恢复机制。
CRTC 与面板同步机制对比 CRTC 与面板同步机制对比 内同步模式 (Master) CRTC → 面板:PCLK + HSync + VSync + DE CRTC 主动驱动所有时序信号 面板仅作为像素接收端 外同步模式 (Slave) 面板 → CRTC:TE/VSync 脉冲 CRTC 等待 TE 信号后开始扫描 用于避免撕裂,适合低刷新率面板 像素流 + 时序 显示面板 TE 同步脉冲 显示面板 选择建议: 内同步适用于标准显示器;外同步适用于需要精确帧同步的嵌入式面板(如 MIPI DSI),驱动需注册 TE 中断处理函数。

2.5 CRTC 与 VBlank 中断

VBlank(垂直消隐期)是 CRTC 驱动开发中最重要的同步事件。当 CRTC 完成一帧的有效像素扫描后,进入垂直消隐期(VTotal - VActive 行),此时硬件会触发 VBlank 中断。驱动利用该中断完成以下操作:

  • 帧缓冲区切换:在 VBlank 期间更新 CRTC 的帧缓冲区地址寄存器,确保下一帧使用新缓冲区,避免撕裂。
  • Plane 更新:应用层通过 drmModeAtomicCommit 提交的 Plane 状态变更,在 VBlank 中断中一次性生效。
  • 性能统计:记录帧率、VBlank 时间戳,用于调试和性能分析。
驱动实现示例:在 CRTC 的 enable_vblank 回调中使能硬件 VBlank 中断,在 disable_vblank 中关闭。中断处理函数中调用 drm_crtc_handle_vblank() 通知 DRM 核心层。
// CRTC VBlank 中断处理函数示例
static irqreturn_t crtc_vblank_handler(int irq, void *dev_id)
{
    struct drm_crtc *crtc = dev_id;
    struct my_crtc_state *state = to_my_crtc_state(crtc->state);

    // 清除硬件中断状态位
    writel(1, state->mmio + VBLANK_STATUS_REG);

    // 通知 DRM 核心层 VBlank 事件
    drm_crtc_handle_vblank(crtc);

    // 如果有等待的 atomic 提交,在此处应用
    if (state->pending_update)
        apply_pending_plane_updates(crtc);

    return IRQ_HANDLED;
}

通过以上机制,CRTC 实现了从内存到面板的完整像素传输控制,成为 DRM/KMS 显示流水线的“心脏”。理解 CRTC 的时序生成、扫描模型和同步机制,是后续实现多 Plane 联动和复杂显示效果的基础。