全志DRM移植中显示缓存管理与DMA-BUF调试 - 第1节

1.1 DRM 架构概述

DRM (Direct Rendering Manager) 是 Linux 内核中负责图形显示与渲染管理的核心框架。它向上为用户空间提供统一的显示控制接口(通过 /dev/dri/card0 设备节点),向下抽象不同 GPU 和显示控制器的硬件差异。DRM 架构由三层组成:

  • 核心层 (DRM Core):提供通用框架、文件操作、内存管理、对象模型和 ioctl 分发。
  • 驱动层 (Driver):各厂商实现具体的硬件操作函数,如全志、Rockchip、NXP 等。
  • 用户空间层 (libdrm / Mesa / Weston):通过 libdrm 库调用内核接口,实现合成、渲染和显示。

DRM 将显示硬件抽象为四个核心对象:CRTC、Encoder、Connector 和 Plane。它们之间的连接关系构成了显示管线的数据流。

💡 关键概念: DRM 采用“对象 + 属性”模型,所有显示资源都是 DRM 对象,通过通用属性接口进行配置,这使得驱动代码高度可复用。
DRM 架构分层 用户空间层 libdrm / Mesa / Weston / Kodi / 应用 DRM 核心层 (Core) 对象模型 / ioctl 分发 / FB 管理 / DMA-BUF / 属性系统 驱动层 (Driver) 全志 sun4i-drm / Rockchip / i915 / vc4 等具体实现

1.2 CRTC / Encoder / Connector / Plane 角色

这四个对象构成了 DRM 显示管线的核心骨架。理解它们各自的职责以及连接方式,是进行驱动移植和调试的基础。

对象 角色 硬件对应 关键操作
CRTC 显示控制器,负责扫描输出、时序生成、帧同步 全志 TCON (Timing Controller) 设置模式、开启/关闭显示、VBLANK 控制
Encoder 编码器,将 CRTC 输出的并行信号转换为外部接口信号 HDMI 编码器、LVDS 发送器、MIPI DSI 控制器 编码格式转换、信号电平调整
Connector 物理连接器,代表实际的显示接口和检测状态 HDMI 座、VGA 座、eDP 座、DSI 接口 热插拔检测、EDID 读取、物理连接状态
Plane 硬件图层,支持独立缩放、色彩空间和合成 全志 DE2/DE3 的 UI 层、视频层、OSD 层 设置 framebuffer、位置、大小、透明度、Z-order

显示管线的数据流方向为:Plane → CRTC → Encoder → Connector → 显示器。用户空间通过 atomic commit 一次性提交所有对象的属性变更,驱动在 commit 回调中完成硬件配置。

🔧 调试提示: 在 /sys/kernel/debug/dri/0/ 下可以查看每个对象的当前状态。使用 cat state 可以 dump 出完整的管线拓扑和属性值,是排查连接错误的利器。
DRM 显示管线对象关系 Plane 硬件图层 CRTC 显示控制器 Encoder 编码器 Connector 连接器 显示器 数据流方向: 用户空间提交 Framebuffer → Plane 合成 → CRTC 扫描 → Encoder 编码 → Connector 输出

1.3 全志平台 DRM 驱动特点

全志 (Allwinner) 平台的 DRM 驱动主要位于内核源码 drivers/gpu/drm/sun4i/ 目录下,驱动名称通常为 sun4i-drm。其设计具有鲜明的 SoC 特色:

  • 显示引擎分离架构: 全志 SoC 将显示控制器 (TCON) 和显示引擎 (DE2/DE3) 分为独立 IP 模块。DE 负责图层合成和缩放,TCON 负责时序生成和输出。驱动中对应为两个独立的平台驱动,通过 DRM 框架组合。
  • 多管线支持: 同一颗 SoC 可能包含多个 TCON 和多个 DE 通道,支持同时驱动 LCD 屏幕和 HDMI 输出。驱动通过设备树中的 ports 节点描述管线拓扑。
  • 硬件图层 (Plane) 丰富: DE2/DE3 通常提供 4 个 UI 层和 1 个视频层,支持 YUV 和 RGB 格式、全局 alpha、像素 alpha、颜色键等特性。驱动将这些硬件通道直接映射为 DRM Plane。
  • DMA-BUF 与 CMA 紧密耦合: 全志平台默认使用 CONFIG_DRM_GEM_CMA_HELPER,通过连续内存分配器 (CMA) 分配显存。DMA-BUF 用于在不同驱动模块(如 VPU、GPU、显示)之间共享缓冲区。
  • 驱动代码复用度高: sun4i-drm 驱动通过 sun4i_backend、sun4i_tcon、sun4i_crtc 等子模块组合,支持从 H3、H5 到 H6、H616 等多代 SoC,差异通过设备树和 compatible 字符串区分。
⚠️ 移植常见陷阱: 全志不同 SoC 的 DE 版本差异较大(DE1.0 / DE2.0 / DE3.0),寄存器布局和图层数量不同。移植时务必确认 sun4i_backend.h 中的图层寄存器偏移是否匹配,否则会导致图层无法显示或花屏。
全志 sun4i-drm 驱动模块结构 DRM Core sun4i-drm (主驱动入口) sun4i_backend DE2/DE3 图层引擎 sun4i_tcon 时序控制器 sun4i_hdmi / lvds 编码器 + 连接器 设备树连接方式: tcon 的 output port 连接到 encoder 的 input port,encoder 的 output port 连接到 connector 的 input port

1.3.1 全志平台特有的 DRM 对象映射

在全志平台上,DRM 对象与硬件 IP 的对应关系如下表所示,理解这个映射是进行驱动配置和设备树编写的关键:

DRM 对象 全志硬件模块 设备树节点 备注
CRTC TCON0 / TCON1 tcon0: lcd-controller@... TCON0 通常用于 LCD,TCON1 用于 HDMI
Plane DE2/DE3 的 UI 层 (0~3) 和 VI 层 display-engine@... 内部通道 通过 sun4i_backend 驱动注册
Encoder HDMI 控制器 / LVDS 发送器 / MIPI DSI hdmi@... / lvds@... 每个物理接口对应一个 encoder
Connector HDMI 座 / LVDS 座 / DSI 面板 connector@... 或 panel 节点 HDMI 通常内嵌 connector,LVDS/DSI 使用外部 panel
📌 调试要点: 在 drivers/gpu/drm/sun4i/sun4i_crtc.c 中,CRTC 的 mode_set 回调会调用 TCON 的时序配置函数。如果屏幕无显示,优先检查 TCON 的时钟频率和极性设置是否与面板规格匹配。

1.3.2 全志 DMA-BUF 与显示缓存管理特点

全志平台的显示缓存管理基于 DRM GEM CMA 辅助框架,但针对多媒体场景做了特殊优化:

  • 物理连续内存: CMA 区域在内核启动时预留,通过 dma_alloc_writecombine 分配,保证显示控制器可以直接通过 DMA 访问。
  • DMA-BUF 导出/导入: 全志的 VPU (视频处理单元) 和 GPU (如 Mali) 通过 DMA-BUF 与 DRM 共享缓冲区。视频解码后的 YUV 数据通过 DMA-BUF 直接传递给 DRM Plane 显示,避免内存拷贝。
  • 缓存同步问题: 由于显示控制器通常不具备 cache coherency,驱动需要在 prepare_fb 和 cleanup_fb 回调中调用 dma_sync_sg_for_device 或 dma_buf_begin_cpu_access 来保证数据一致性。
⚠️ 性能陷阱: 在全志 H6 等平台上,如果使用 dma_alloc_attrs 分配了非连续内存,显示控制器可能无法正确扫描输出,导致画面撕裂或黑屏。务必确认 framebuffer 的物理地址是否在 CMA 区域内。