2. 显示驱动框架解析:DRM/KMS 与 RK3399 实现

在嵌入式显示性能调优中,理解驱动框架是定位瓶颈的前提。RK3399 的显示驱动基于 Linux 内核标准 DRM (Direct Rendering Manager) 和 KMS (Kernel Mode Setting) 框架构建。本章从框架分层、核心对象、RK3399 硬件适配三个维度展开,为后续 FPS 和延迟优化打下基础。

2.1 DRM/KMS 框架分层架构

DRM/KMS 将显示驱动分为 UAPI (用户空间 API)、核心层 (Core)、硬件驱动层 (Driver) 三层。用户空间通过 drmModeSetCrtc、drmModePageFlip 等 ioctl 与内核交互,核心层管理资源与状态机,驱动层直接操作寄存器。

关键分层: 用户空间 (libdrm / Weston / SurfaceFlinger) → DRM 核心 (drm_crtc.c / drm_plane.c) → KMS 辅助 (drm_atomic_helper.c) → 硬件驱动 (rockchip_drm_vop.c)
DRM/KMS 三层架构与 RK3399 适配 用户空间 (Userspace) libdrm / Weston / SurfaceFlinger / DRM-HWC DRM 核心层 (Core) drm_crtc / drm_plane / drm_encoder / drm_connector Atomic Modeset / Page Flip / Vblank 管理 硬件驱动层 (Driver) rockchip_drm_vop.c / rockchip_drm_dsi.c / rockchip_drm_hdmi.c VOP 寄存器配置 / 时钟频率 / 显示接口控制 RK3399 驱动位于最底层,通过 drm_register_driver() 注册到 DRM 核心

2.2 DRM 核心对象模型

DRM/KMS 使用 五类核心对象 描述显示流水线。每个对象对应一个内核结构体,通过 drm_mode_object 基类统一管理 ID 与属性。

对象 内核结构体 功能描述 RK3399 对应硬件
CRTC drm_crtc 扫描输出控制器,生成时序信号 VOP (Video Output Processor) 0/1
Plane drm_plane 硬件图层,支持叠加与 Alpha 混合 VOP 的 Win0~Win4 图层
Encoder drm_encoder 像素数据编码,转换为接口信号 DSI / eDP / HDMI / DP 编码器
Connector drm_connector 物理连接器,检测热插拔与 EDID HDMI 连接器 / MIPI DSI 连接器
Bridge drm_bridge 外部桥接芯片,如 LVDS 转 eDP I2C 桥接芯片 (如 LT8911)
调优切入点: Plane 的数量和格式直接影响合成效率。RK3399 VOP 支持最多 5 个硬件图层,合理分配图层可减少 GPU 合成开销,提升 FPS。

2.3 RK3399 VOP 硬件流水线

RK3399 集成两个 VOP (Video Output Processor) 模块:VOPB 支持 4K@60,VOPL 支持 2K@60。每个 VOP 内部包含多个 Win (Window) 图层、一个 DMA 引擎 和一个 时序发生器。

RK3399 VOP 内部显示流水线 DDR 帧缓冲 DMA 引擎 Win 图层 (Win0~Win4) Win0: 主图层 (RGB/YUV) Win1: 光标/OSD 图层 Win2~4: 视频叠加层 Alpha 混合 全局 Alpha 时序 VOP 关键性能参数 VOPB: 最大 4K@60 / 8 位色深 / 5 个 Win 图层 / 支持 AFBC 压缩 VOPL: 最大 2K@60 / 8 位色深 / 3 个 Win 图层 / 无 AFBC

2.4 RK3399 DRM 驱动注册流程

RK3399 显示驱动的初始化遵循 DRM 框架的标准流程。以下代码展示了驱动入口与 CRTC 注册的关键步骤:

// drivers/gpu/drm/rockchip/rockchip_drm_drv.c
static int rockchip_drm_bind(struct device *dev)
{
    struct drm_device *drm_dev;
    int ret;

    // 1. 分配 drm_device
    drm_dev = drm_dev_alloc(&rockchip_drm_driver, dev);
    if (IS_ERR(drm_dev))
        return PTR_ERR(drm_dev);

    // 2. 绑定组件 (VOP, HDMI, DSI 等)
    ret = component_bind_all(dev, drm_dev);
    if (ret)
        goto err_free;

    // 3. 注册 modeset 配置
    ret = drm_mode_config_init(drm_dev);
    if (ret)
        goto err_unbind;

    // 4. 创建 CRTC (VOP)
    ret = rockchip_vop_create_crtc(drm_dev, vop);
    if (ret)
        goto err_config;

    // 5. 注册 DRM 设备
    ret = drm_dev_register(drm_dev, 0);
    if (ret)
        goto err_config;

    return 0;
}
性能陷阱: component_bind_all 的绑定顺序影响 VOP 与 Encoder 的连接。如果 DSI 编码器在 VOP 之前绑定,可能导致时序配置失败,造成首次显示延迟增加 50ms 以上。

2.5 Atomic Modeset 与 Page Flip

RK3399 驱动完整支持 Atomic Modeset 接口。用户空间通过 DRM_IOCTL_MODE_ATOMIC 提交一个原子请求,包含多个对象的属性变更。驱动在 atomic_check 阶段验证资源,在 atomic_commit 阶段一次性应用。

Page Flip 是帧切换的核心路径,直接决定 FPS 上限:

  • 同步 Flip: 在 Vblank 期间切换显示缓冲区地址,无撕裂。
  • 异步 Flip: 立即切换,可能产生撕裂,但降低延迟。
  • VOP 硬件支持: RK3399 VOP 内置 Frame Counter 和 Line Counter,可精确控制切换时机。
Flip 模式 延迟 撕裂风险 适用场景
同步 Flip (Vblank 等待) 1~2 Vblank 周期 (16~33ms @60Hz) 无 UI 界面、视频播放
异步 Flip (立即切换) <1ms 高 游戏、VR 低延迟模式
硬件自动 Flip (VOP 自刷新) 0.5~1 Vblank 周期 低 静态画面、AOD 显示

2.6 RK3399 显示驱动关键文件清单

调优过程中需要重点关注以下源文件:

  • rockchip_drm_drv.c — 驱动入口与组件绑定
  • rockchip_drm_vop.c — VOP 核心控制,CRTC 实现
  • rockchip_vop_reg.c — VOP 寄存器定义与配置
  • rockchip_drm_dsi.c — MIPI DSI 编码器驱动
  • rockchip_drm_hdmi.c — HDMI 编码器驱动
  • rockchip_drm_fb.c — 帧缓冲管理与 AFBC 压缩
调优第一步: 在 rockchip_vop_reg.c 中检查 vop_ctrl 寄存器的 standby 位。如果 VOP 频繁进入待机状态,会增加帧切换延迟。建议在连续渲染时保持 VOP 活跃。

2.7 本章小结