2. DRM框架基础:DRM架构与KMS组件模型

在SA8155 DPU驱动开发中,DRM(Direct Rendering Manager)框架是Linux图形子系统的核心基础设施。本章深入剖析DRM架构分层、KMS组件职责以及CRTC/Encoder/Connector/Plane对象模型,为后续DPU中断与时序配置奠定理论基础。

2.1 DRM架构分层

DRM框架采用三层架构设计,从用户态到硬件逐层抽象:

层级 组件 职责 典型接口
用户态 libdrm / Mesa 提供标准API,封装ioctl调用 drmModeGetResources()
内核态 DRM Core 设备管理、文件操作、缓冲区管理 drm_open() / drm_ioctl()
硬件层 GPU/DPU驱动 寄存器编程、中断处理、时序控制 drm_crtc_helper_funcs
关键点:DRM Core负责通用逻辑,硬件差异由驱动层通过回调函数实现。SA8155的DPU驱动主要工作在硬件层,实现KMS回调与中断服务。
开发提示:在SA8155平台上,DRM主设备号为226,次设备号0-63对应不同GPU/DPU节点。通过cat /proc/devices | grep drm可确认设备注册状态。

2.2 KMS组件模型

KMS(Kernel Mode Setting)是DRM框架中负责显示模式设置与输出的子系统。其核心对象模型包含四个基本组件:

DRM KMS 核心对象模型 Plane 像素数据源 FB绑定 / 缩放 / 裁剪 CRTC 显示控制器 时序生成 / 扫描输出 Encoder 数据编码器 DSI/DP/HDMI协议 Connector 物理连接器 EDID / 热插拔检测 绑定 连接 输出 数据流方向 FB → Plane → CRTC → Encoder → Connector → 显示器 每个CRTC可绑定多个Plane,实现图层合成

2.2.1 Plane(图层平面)

Plane是像素数据的来源,每个Plane关联一个framebuffer对象。SA8155 DPU支持主Plane(Primary Plane)和叠加Plane(Overlay Plane),前者用于主显示内容,后者用于画中画或UI叠加层。

SA8155注意:DPU硬件支持最多4个硬件Plane,但驱动层需通过drm_universal_plane_init()注册。Plane的格式支持列表必须包含RGB888和NV12,否则Android HWComposer无法正常工作。

2.2.2 CRTC(显示控制器)

CRTC是KMS模型的核心,负责生成显示时序、读取Plane数据并输出像素流。每个CRTC对应一个独立的显示管道,包含以下关键时序参数:

参数 含义 SA8155典型值(1080p60)
htotal 水平总像素(HActive + HBlank) 2200
vtotal 垂直总行数(VActive + VBlank) 1125
clock 像素时钟频率(MHz) 148.5
hdisplay 水平有效像素 1920
vdisplay 垂直有效行数 1080

2.2.3 Encoder(编码器)

Encoder将CRTC输出的并行像素数据转换为特定显示接口的串行协议。SA8155集成了多种Encoder:

  • DSI Encoder:用于MIPI DSI接口,支持4通道1.5Gbps
  • DP Encoder:用于DisplayPort,支持eDP和DP输出
  • HDMI Encoder:通过外部桥接芯片实现

2.2.4 Connector(连接器)

Connector代表物理显示接口,负责检测显示器连接状态和读取EDID数据。KMS通过Connector的状态变化触发热插拔事件,驱动层需实现.detect()回调。

2.3 对象注册与生命周期

在SA8155 DPU驱动中,KMS对象的注册遵循固定顺序:

// 1. 分配CRTC
struct drm_crtc *crtc;
drm_crtc_init_with_planes(drm_dev, crtc, primary, cursor, &dpu_crtc_funcs, NULL);

// 2. 注册Encoder
struct drm_encoder *encoder;
drm_encoder_init(drm_dev, encoder, &dpu_encoder_funcs, DRM_MODE_ENCODER_DSI, NULL);

// 3. 注册Connector
struct drm_connector *connector;
drm_connector_init(drm_dev, connector, &dpu_connector_funcs, DRM_MODE_CONNECTOR_DSI);
drm_connector_attach_encoder(connector, encoder);

// 4. 注册Plane
struct drm_plane *plane;
drm_universal_plane_init(drm_dev, plane, possible_crtcs, &dpu_plane_funcs,
                         formats, num_formats, NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
注册顺序约束:必须先注册CRTC和Encoder,再注册Connector并建立连接关系。Plane的注册可在CRTC之前或之后,但必须在drm_crtc_init_with_planes()之前准备好plane指针。

2.4 原子模式设置(Atomic Modeset)

KMS的原子操作是SA8155 DPU驱动的核心机制,它保证多个显示属性的更新在同一个VBlank周期内同步生效:

原子模式设置流程 用户态应用 DRM Core DPU驱动 ① drmModeAtomicCommit() → ② drm_atomic_check_only() → ③ drm_atomic_commit() ④ dpu_crtc_atomic_check() → ⑤ dpu_crtc_atomic_flush() → ⑥ 等待VBlank ⑦ 硬件寄存器一次性更新 → ⑧ 触发完成事件 → ⑨ 用户态收到page_flip事件

2.5 SA8155 DPU驱动中的KMS实现要点

  • CRTC回调:实现.atomic_check()验证时序参数,.atomic_flush()编程DPU寄存器
  • Plane更新:通过.atomic_update()设置源矩形和目标矩形,支持YUV/RGB格式转换
  • Encoder桥接:SA8155使用drm_bridge框架连接Encoder和Connector,便于支持多种显示接口
  • VBlank处理:在dpu_crtc_vblank_irq_handler()中调用drm_crtc_handle_vblank()触发事件
调试技巧:使用echo 0x1ff > /sys/module/drm/parameters/debug可开启DRM内核日志,观察KMS对象注册和原子提交的详细流程。

2.6 本章小结

DRM/KMS框架为SA8155 DPU驱动提供了标准化的对象模型和操作接口。CRTC/Encoder/Connector/Plane四元组完整描述了从framebuffer到物理显示器的数据通路,原子模式设置保证了多属性更新的同步性。理解这些基础组件是后续配置DPU中断和显示时序的前提。