2. 显示驱动框架:Linux DRM/KMS框架介绍、高通msm_drm驱动架构、显示管道(Display Pipeline)概念
2.1 Linux DRM/KMS 框架概述
DRM (Direct Rendering Manager) 是 Linux 内核中负责图形显示和 GPU 管理的子系统。KMS (Kernel Mode Setting) 是 DRM 的核心组件,负责显示模式设置、帧缓冲管理和显示管线的控制。在高通 SA8155 平台上,显示驱动完全基于 DRM/KMS 框架实现。
核心设计思想: DRM/KMS 将显示控制从用户态(X Server/Wayland)移入内核态,提供统一的接口,避免多进程并发访问显示硬件时的竞态条件。
2.1.1 DRM/KMS 关键对象
| 对象 | 角色 | 对应硬件 |
|---|---|---|
| CRTC | 显示控制器,负责扫描输出和时序生成 | MDP (Mobile Display Processor) 接口 |
| Plane | 硬件图层,支持叠加和 Alpha 混合 | MDP 图层管道 (Layer Mixer) |
| Encoder | 数据编码/转换,如 RGB→LVDS/DSI/DP | DSI/DP/eDP 发送器 |
| Connector | 物理连接器,检测热插拔和 EDID | HDMI/DP/USB-C 物理接口 |
| FB (Framebuffer) | 内存中的像素数据缓冲区 | DDR 中的连续物理内存 |
实战提示: 在 SA8155 上调试显示时,最常通过
/sys/kernel/debug/dri/0/ 下的 debugfs 节点查看这些对象的状态,例如 cat state 可以 dump 当前 KMS 对象树。
2.1.2 DRM/KMS 软件架构图
2.2 高通 msm_drm 驱动架构
高通平台的 DRM 驱动位于 drivers/gpu/drm/msm/ 目录下,核心模块包括 msm_drm、msm_kms 和 msm_gpu。SA8155 使用 DPU (Display Processing Unit) 作为显示后端,取代了早期的 MDP5。
2.2.1 msm_drm 驱动模块组成
| 模块文件 | 功能 | 关键数据结构 |
|---|---|---|
msm_drv.c |
DRM 驱动入口,注册 platform_driver | struct msm_drm_private |
msm_kms.c |
KMS 核心,管理 CRTC/Plane/Encoder | struct msm_kms |
dpu_kms.c |
DPU 硬件后端,SA8155 显示核心 | struct dpu_kms |
dpu_crtc.c |
CRTC 实现,管理 Mixer 和接口 | struct dpu_crtc |
dpu_plane.c |
硬件图层 Plane 实现 | struct dpu_plane |
dpu_encoder.c |
Encoder 实现,连接 CRTC 和 Connector | struct dpu_encoder |
dpu_connector.c |
Connector 实现,处理热插拔和 EDID | struct dpu_connector |
2.2.2 msm_drm 驱动初始化流程
- platform_driver 注册:
msm_drm_init()注册msm_drm_platform_driver,匹配设备树节点qcom,mdss。 - KMS 组件绑定: 通过
component_bind_all()绑定 DPU、DSI、HDMI 等子设备。 - DRM 设备注册:
drm_dev_register()创建/dev/dri/card0节点。 - KMS 初始化:
msm_kms_init()创建 CRTC、Plane、Encoder、Connector 对象。 - Atomic 支持: 注册
drm_atomic_helper回调,支持事务性提交。
常见问题: SA8155 上如果设备树中
qcom,mdss 节点下的 interconnects 属性配置错误,会导致 msm_drm 在 probe 阶段返回 -EPROBE_DEFER,显示驱动无法加载。务必检查 dmesg 中的 probe 顺序。
2.2.3 msm_drm 驱动架构图
2.3 显示管道(Display Pipeline)概念
显示管道(Display Pipeline)是 DRM/KMS 框架中描述数据从内存到屏幕的完整路径。在 SA8155 的 DPU 中,显示管道由多个硬件阶段组成,每个阶段对应一个 KMS 对象。
2.3.1 显示管道核心阶段
| 阶段 | KMS 对象 | 硬件单元 | 功能描述 |
|---|---|---|---|
| 1. 帧缓冲读取 | FB + Plane | SSPP (Source Surface Pipe) | 从 DDR 读取像素数据,支持格式转换和缩放 |
| 2. 图层混合 | CRTC | Layer Mixer (LM) | 将多个 Plane 按 Z-order 进行 Alpha 混合 |
| 3. 后处理 | CRTC | PingPong (PP) + DSPP | 色彩校正、Gamma、Dither、HDR 处理 |
| 4. 时序生成 | CRTC | INTF (Interface) | 生成 VBlank/HSync 时序,控制像素时钟 |
| 5. 数据发送 | Encoder + Connector | DSI/DP/eDP PHY | 将像素数据编码为 DSI/DP 协议,通过物理层发送 |
2.3.2 显示管道数据流图
2.3.3 显示管道配置示例
以下代码展示了在 SA8155 上通过 DRM atomic API 配置显示管道的典型流程:
// 显示管道配置示例:设置 1080p@60 显示
struct drm_mode_create_dumb dumb = {0};
struct drm_framebuffer *fb;
struct drm_atomic_state *state;
struct drm_plane *plane;
struct drm_crtc *crtc;
// 1. 创建帧缓冲
dumb.width = 1920;
dumb.height = 1080;
dumb.bpp = 32;
ioctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &dumb);
// 2. 添加 FB
fb = drm_framebuffer_create(fd, &dumb);
// 3. 获取 CRTC 和 Plane
crtc = drm_crtc_find(fd, 0); // CRTC 0
plane = drm_plane_find(fd, 0); // Plane 0 (Primary)
// 4. Atomic 提交
state = drm_atomic_state_alloc(NULL);
drm_atomic_set_crtc_for_plane(state, plane, crtc);
drm_atomic_set_fb_for_plane(state, plane, fb);
drm_atomic_commit(state);
drm_atomic_state_free(state);
调试技巧: 使用
modetest -M msm_drm -p 可以列出所有 Plane 及其支持的格式。SA8155 的 DPU 支持 NV12、P010、RGBA8888 等格式,但不同 Plane 的格式支持列表不同,务必先查询再配置。
2.4 本章小结
- DRM/KMS 框架 是 Linux 显示驱动的标准,核心对象包括 CRTC、Plane、Encoder、Connector、FB。
- msm_drm 驱动 是高通平台实现,SA8155 使用 DPU 后端,模块化设计便于扩展。
- 显示管道 描述了数据从内存到屏幕的完整路径,每个阶段对应特定的硬件单元和 KMS 对象。
- 理解显示管道是进行显示驱动开发和调试的基础,后续章节将深入每个阶段的实现细节。