3. KMS (Kernel Mode Setting) 详解

KMS(Kernel Mode Setting)是 DRM 框架的核心子系统,负责在内核空间管理显示模式、分辨率、刷新率以及显示管线的连接状态。与传统的用户态模式设置(UMS)不同,KMS 将模式设置与显示缓冲区管理(GEM)分离,确保多应用环境下显示状态的一致性,并消除模式切换时的闪烁问题。

3.1 KMS 初始化流程

KMS 初始化发生在 DRM 设备驱动的 bind() 或 probe() 阶段,主要完成以下步骤:

  1. CRTC 初始化:创建 CRTC 对象,注册 mode_set、enable、disable 等回调函数。
  2. Encoder 初始化:创建 Encoder 对象,指定可能的 CRTC 掩码(possible_crtcs)。
  3. Connector 初始化:创建 Connector 对象,注册 get_modes、detect 等回调。
  4. Plane 初始化:创建主平面(Primary Plane)和可能的叠加平面(Overlay/Cursor Plane)。
  5. 模式读取:通过 Connector 的 get_modes 回调从 EDID 或固定时序表中读取显示模式。
  6. 默认模式设置:选择一个初始模式并调用 CRTC 的 mode_set 进行首次配置。
关键点:KMS 初始化必须在 drm_dev_register() 之前完成,否则用户态无法通过 drmModeGetResources() 获取到有效的显示资源。
嵌入式提示:对于不带 EDID 的 LCD 面板,驱动需要在 Connector 的 get_modes 回调中手动添加 drm_mode_create() 创建的显示模式,并设置 type 为 DRM_MODE_TYPE_PREFERRED。
KMS 初始化流程 drm_dev_alloc() CRTC 初始化 Encoder 初始化 Connector 初始化 Plane 初始化 drm_dev_register() 回调注册 mode_set / enable / disable get_modes / detect update_plane / disable_plane

3.2 模式设置(Mode Setting)

模式设置是 KMS 的核心功能,指将一组显示参数(分辨率、刷新率、时钟、时序)应用到 CRTC 和 Encoder/Connector 链路的过程。用户态通过 drmModeSetCrtc() 或原子提交(Atomic Commit)触发模式设置。

3.2.1 显示模式结构

每个显示模式由 drm_display_mode 结构体描述,关键字段如下:

字段 含义 典型值(1080p60)
hdisplay 水平有效像素 1920
vdisplay 垂直有效像素 1080
htotal 水平总像素(含消隐) 2200
vtotal 垂直总像素(含消隐) 1125
clock 像素时钟(kHz) 148500
vrefresh 垂直刷新率(Hz) 60
flags 同步极性标志 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC

3.2.2 模式设置流程

  1. 模式选择:从 Connector 的模式列表中选择一个匹配的 drm_display_mode。
  2. CRTC 配置:调用 CRTC 的 mode_set 回调,配置时序发生器(TG)和像素时钟。
  3. Encoder 配置:调用 Encoder 的 mode_set 回调,配置数据映射和编码格式。
  4. Connector 配置:调用 Connector 的 mode_set 回调,配置物理接口参数(如 LVDS 电压、MIPI DSI 时序)。
  5. CRTC 使能:调用 CRTC 的 enable 回调,启动时序输出。
常见错误:模式设置失败通常由以下原因引起:
- 像素时钟超出 LCD 控制器或面板的 PLL 范围。
- 水平/垂直消隐参数不符合面板规格。
- Encoder 的 possible_crtcs 掩码未正确设置,导致 CRTC 与 Encoder 不匹配。
模式设置数据流 用户态应用 DRM Core CRTC Encoder Connector LCD 面板 IOCTL 调用 DRM_IOCTL_MODE_SETCRTC DRM_IOCTL_MODE_ATOMIC

3.3 显示参数配置

显示参数配置涉及 LCD 控制器硬件寄存器的设置,主要包括以下方面:

3.3.1 时序参数配置

LCD 控制器需要根据 drm_display_mode 计算并配置以下时序寄存器:

参数 寄存器字段 计算方式
水平同步宽度(HSPW) HSYNC 脉冲宽度 mode->hsync_end - mode->hsync_start
水平后肩(HBP) HSYNC 结束到有效数据 mode->htotal - mode->hsync_end
水平前肩(HFP) 有效数据到 HSYNC 开始 mode->hsync_start - mode->hdisplay
垂直同步宽度(VSPW) VSYNC 脉冲宽度 mode->vsync_end - mode->vsync_start
垂直后肩(VBP) VSYNC 结束到有效数据 mode->vtotal - mode->vsync_end
垂直前肩(VFP) 有效数据到 VSYNC 开始 mode->vsync_start - mode->vdisplay

3.3.2 像素时钟配置

像素时钟由 LCD 控制器的 PLL 产生,配置步骤通常为:

  1. 根据 mode->clock(单位 kHz)计算目标频率。
  2. 选择 PLL 的参考时钟源(如 24MHz 晶振)。
  3. 计算分频系数(M、N、K、OD)使输出频率接近目标值。
  4. 配置 PLL 寄存器并等待锁定。
  5. 将 PLL 输出连接到 LCD 控制器的像素时钟域。
精度要求:像素时钟误差应控制在 ±0.5% 以内,否则可能导致行频或场频偏移,引起画面抖动或闪烁。

3.3.3 接口时序配置

对于不同的 LCD 接口,需要额外配置:

  • RGB 并行接口:数据使能(DE)极性、HSYNC/VSYNC 极性、数据位宽(16/18/24bit)。
  • LVDS 接口:通道数(4/8 lane)、数据映射格式(JEIDA/VESA)、时钟相位。
  • MIPI DSI 接口:虚拟通道、数据包格式、LP/HS 模式切换、时钟频率。
  • eDP 接口:链路速率(1.62/2.7/5.4Gbps)、通道数、训练模式。
显示参数配置结构 drm_display_mode 时序参数 像素时钟 接口配置 同步极性 硬件寄存器映射 HSPW/HBP/HFP → 时序发生器 → VSPW/VBP/VFP → 帧同步 → PLL 分频 → 像素时钟 → 接口格式选择

3.4 Vblank 同步机制

Vblank(垂直消隐期)是帧与帧之间的时间间隔,在此期间不会向 LCD 面板传输像素数据。KMS 利用 Vblank 实现以下关键功能:

  • 页面翻转(Page Flip):在 Vblank 期间切换显示缓冲区,避免撕裂(Tearing)。
  • 垂直同步(VSync):同步应用渲染帧率与显示刷新率。
  • 帧统计:提供帧序号和时间戳,用于性能分析和自适应同步。

3.4.1 Vblank 中断处理

LCD 控制器在每帧的 Vblank 起始时刻产生硬件中断,KMS 的中断处理流程如下:

  1. 硬件触发 Vblank 中断。
  2. 中断服务程序(ISR)调用 drm_crtc_handle_vblank()。
  3. DRM 核心更新 CRTC 的 Vblank 计数和时间戳。
  4. 唤醒等待 Vblank 事件的用户态进程(通过 DRM_IOCTL_WAIT_VBLANK)。
  5. 触发已注册的 Vblank 回调(如页面翻转完成回调)。

3.4.2 Vblank 相关 API

函数/IOCTL 用途 调用时机
drm_crtc_vblank_get() 获取 Vblank 引用计数,使能 Vblank 中断 驱动初始化或页面翻转前
drm_crtc_vblank_put() 释放 Vblank 引用计数,可关闭中断 页面翻转完成或 CRTC 关闭
drm_crtc_handle_vblank() 通知 DRM 核心 Vblank 事件发生 ISR 中调用
DRM_IOCTL_WAIT_VBLANK 用户态等待下一个 Vblank 应用渲染循环
DRM_IOCTL_PAGE_FLIP 请求在下一个 Vblank 切换缓冲区 应用提交新帧
嵌入式优化:对于低功耗场景,可以在 CRTC 关闭时调用 drm_crtc_vblank_off() 禁用 Vblank 中断,避免不必要的唤醒。在 CRTC 重新使能时调用 drm_crtc_vblank_on() 恢复。
Vblank 同步时序与中断处理 帧 N(显示) 有效像素区域 Vblank 消隐 帧 N+1(显示) 有效像素区域 Vblank 消隐 帧 N+2 ... 中断 中断 ISR 入口 drm_crtc_handle_vblank() 更新计数/时间戳 唤醒等待队列 页面翻转回调 用户态通知 Vblank 同步关键作用 页面翻转在 Vblank 期间完成 → 无撕裂 | 帧率同步 → 消除画面抖动 | 时间戳 → 性能统计与自适应同步

3.5 原子模式设置(Atomic Mode Setting)

原子模式设置是 KMS 的进阶特性,允许在一次事务中同时提交多个 CRTC、Plane、Connector 的状态变更,确保所有变更同时生效或全部回滚。原子操作的核心数据结构为 drm_atomic_state,包含:

  • CRTC 状态:模式、使能状态、Gamma 表。
  • Plane 状态:Framebuffer、裁剪区域、位置、透明度。
  • Connector 状态:连接状态、EDID 变更。
原子提交流程:
1. 用户态分配 drm_atomic_state 并添加对象。
2. 调用 drm_atomic_check_only() 验证状态合法性。
3. 调用 drm_atomic_commit() 提交变更。
4. 驱动在 Vblank 中应用所有硬件寄存器更新。
5. 提交完成后通知用户态。

原子模式设置是现代 DRM 驱动(如 i915、msm、vc4)的标准实现方式,嵌入式 LCD 控制器驱动也逐步从传统 mode_set 回调迁移到