在当今的电子设备领域,显示驱动技术至关重要,尤其是对于 Rockchip 平台而言。Rockchip 显示子系统并非简单的 “屏驱动”,而是一条涵盖图像生产、内存缓冲、VOP/VOP2 扫描合成、显示接口控制器、PHY、电源与屏端的完整链路。Linux DRM/KMS 框架则将这条链路抽象为一组可组合的对象,通过 Atomic 状态提交保证多对象切换的一致性。本教程将围绕四条主线展开,深入探讨 Rockchip 平台 DRM/KMS 显示驱动的相关知识。
学习主线与目标
本教程旨在帮助读者建立从像素到屏幕的完整架构认识,理解 CRTC、Plane、Framebuffer、Encoder、Connector、Bridge、Panel、GEM 与 Property 等概念,掌握 Rockchip VOP 1.0、VOP 2.0、Video Port、Window 与显示接口之间的对应关系,并形成可复用的点屏、调试、故障隔离和源码阅读方法。完成全文和实验后,读者应能够独立回答一系列关键问题,例如一帧图像从 DDR 到屏幕经过哪些硬件模块,VOP、VP、CRTC、Plane、Window 之间如何对应等。
显示系统总架构
数据通路与路径:显示链路可分为图像生产、内存承载、扫描合成、协议输出和电气传输与显示五个阶段。在这个过程中,显示系统同时存在数据面和控制面两条路径。数据面涉及 Buffer → Plane → VOP/VP → Interface → PHY → Panel 的数据传输,而控制面则包括 Mode、Property、Clock、Reset、Power、GPIO、HPD、EDID、DPCD、Atomic State 等控制信息。点屏时,不能只关注数据面,应同时验证两类路径,否则可能会忽略诸如 CRTC Mode 或 Panel 时序错误、电源顺序不满足屏端规格等问题。
DRM/KMS 框架的作用:DRM 作为 Linux 图形子系统的内核框架,KMS 负责显示模式设置与扫描输出管理。其价值在于将复杂显示硬件抽象成统一对象,并定义对象之间的约束、状态和提交方式。在 Rockchip 平台上,DRM 设备表现为 /dev/dri/card0 /dev/dri/card1 等,编号与驱动加载顺序相关。为了确保准确使用 DRM 驱动,可通过 drmIsKMS (fd) 判断是否具备 KMS 能力,或通过 drmOpen ("rockchip", NULL) 打开 Rockchip DRM 驱动,调试时还可同时检查 /sys/kernel/debug/dri/*/name、summary 或 modetest -M rockchip。

对象解析:DRM/KMS 包含多个对象,如 drm_device 代表一个完整的 DRM 设备,内部包含 Mode Config、CRTC、Plane、Encoder、Connector 列表、GEM/PRIME 能力等;CRTC 是独立扫描输出流水线的逻辑抽象,负责保存并应用 drm_display_mode、选择与合成 Plane 等;Plane 是可被 CRTC 扫描和合成的图层,包括 Primary Plane、Overlay Plane 和 Cursor Plane 等类型;Framebuffer 是对一幅可扫描图像内存布局的描述,包含宽高、 FourCC 像素格式等信息。这些对象之间相互关联,共同构成了 DRM/KMS 显示驱动的基础。
三个 “掩码” 的意义:在对象关系中,存在 possible_crtcs、Plane Mask 和 Clone 与 Mirror 三个 “掩码”。possible_crtcs 本质是位图,用于表示 Encoder 和 Plane 可连接的 CRTC;Plane Mask 用于决定每个 VP 能使用的 Window;Clone 与 Mirror 表示 Encoder 之间的克隆能力,但实际配置还受到 VOP2 与接口实现的约束。
VOP 1.0 与 VOP 2.0 的差异:VOP 1.0 常见于 RK3288、RK3399、PX30 等平台,多屏主要依靠多个独立 VOP,每个 VOP 独立产生扫描时序,具有自己的 Window,但跨 VOP 共享能力有限。VOP 2.0 采用统一 VOP 与多个 Video Port,一个 VOP2 内部维护多个 Window/Plane,Plane 可按策略分配到不同 VP,但接口到 VP 的路由受硬件矩阵限制,且 DCLK、ACLK、AFBC、DSC、HDR 等资源可能存在共享约束。
DRM 在 Linux 图形栈中的位置:从应用层到硬件,DRM 软件栈包括应用层、libdrm、DRM Core、GEM/PRIME、KMS/Atomic、Rockchip DRM 驱动和硬件等部分。应用层通过 libdrm 与内核交互,DRM Core 提供通用对象和状态机,Rockchip 驱动则提供硬件实现。在系统运行 Weston、Xorg 或 SurfaceFlinger 等 compositor 时,需要注意避免直接执行 modeset 失败,可采用切换到无图形服务的终端、停止或暂停 compositor 等调试方式。
显示原理与 Atomic KMS
扫描时序的原理:显示接口在发送有效像素的同时,每行和每帧还包含同步与消隐区间。扫描时序由水平参数(如 htotal、hsync_start、hsync_end 等)、垂直参数(如 vtotal、vsync_start、vsync_end 等)、帧率与 Pixel Clock 以及极性与采样边沿等因素组成。不同的参数配置会影响显示效果,极性错误可能导致无图、画面滚动、颜色随机等问题。Mode 来源有固定 Timing 和 EDID 两种,固定 Timing 可避开 EDID 损坏,但参数错误会导致链路训练失败或图像异常,EDID 方式灵活,但依赖 HPD、电源、AUX/DDC 和屏端存储器正常。
带宽问题分析:带宽是影响显示质量的重要因素,包括图像读带宽和接口带宽。未压缩图像的理论读带宽可近似为宽度 × 高度 × fps × bytes_per_pixel,但实际系统还需考虑多 Plane 叠加、缩放、DDR 竞争等因素。不同接口的编码开销不同,以 DP/eDP 为例,必须满足有效视频带宽 < Lane 数 × Link Rate × 编码效率。VOP FIFO 得不到数据时可能出现 POST_BUF_EMPTY 问题,需要优先排查 DDR/AXI 带宽是否不足、ACLK 是否满足要求等因素。
Plane 合成、缩放与颜色处理:Plane 配置包含源矩形和目标矩形两套坐标,若二者大小不同,硬件会执行缩放。多个 Plane 的合成顺序由 Zpos 决定,Alpha 混合依赖全局 Alpha、每像素 Alpha 等因素。视频 Plane 常以 NV12/NV16 输入,显示接口通常输出 RGB 或 YUV,CSC 需要明确 BT.601、BT.709、BT.2020 等色彩标准和 Full Range 或 Limited Range 等范围。颜色异常可能是 Color Encoding/Range 配置不一致导致的。
GEM、IOMMU、CMA 与缓存一致性:Buffer 从生产到扫描输出涉及 GEM Object、IOMMU、CMA 与缓存一致性等问题。GEM Object 保存 Buffer 的内核表示,其后端可能来自连续 CMA、页数组 + IOMMU 映射等。启用 IOMMU 后,VOP 使用 IOVA 访问离散物理页,但映射与生命周期错误会产生 Page Fault。关闭 VOP IOMMU 后,DRM Buffer 往往从 CMA 分配,需确保 CMA 足够大。DMA 设备之间共享 Buffer 时,需要通过 IN_FENCE_FD 与 OUT_FENCE_PTR 建立同步关系,确保生产端完成写入、缓存同步正确、扫描端在 Fence 之后开始读取以及 Buffer 释放晚于扫描结束。
Legacy KMS 与 Atomic KMS 的比较:Legacy KMS 接口概念直观,适合点屏实验,但多个对象分步修改可能导致短暂不一致。Atomic KMS 将多个对象的新状态性提交,通过 TEST_ONLY 验证路由、Mode、带宽等约束,确保提交的一致性。Property 以 Object ID + Property ID + Value 的形式描述状态变化,Atomic 提交过程包括 State 复制、atomic_check 和 Commit 顺序等步骤。
Atomic 驱动的内部工作机制:Atomic 提交先复制旧状态形成候选新状态,各对象执行校验,包括 Plane check、CRTC check 等。典型的 Commit 顺序包括等待依赖 Fence、关闭旧路径、设置时钟和接口、配置 Plane 等步骤。具体回调名随内核版本变化,阅读代码时应围绕 “检查、关闭、配置、使能、完成” 五个阶段追踪。
VBlank、Page Flip 与 Tear-free:VBlank 是一帧有效区结束后的垂直消隐阶段,Page Flip 通常在 VBlank 边界切换 Buffer,避免屏幕上半部分来自旧帧、下半部分来自新帧。调试 VBlank 时需要注意 DRM debug 的 VBL 类日志量很大、CRTC 未激活时不会产生正常 VBlank 等问题。Variable Refresh、PSR 等特性会改变传统固定 VBlank 模型。
Rockchip 驱动实现与设备树
驱动源码的阅读顺序:Rockchip DRM 驱动源码分布在多个目录中,推荐的阅读顺序为 rockchip_drm_drv.c、rockchip_drm_vop2.c 或 rockchip_drm_vop.c、对应接口驱动、panel-simple.c 或具体 Panel、Bridge 驱动、rockchip_drm_gem.c 以及 Binding YAML 与板级 DTS。不同模块的典型文件有不同的阅读重点,例如 Core 模块的 rockchip_drm_drv.c 需要关注 bind、mode_config 等内容。
Component Framework 与 Deferred Probe:Rockchip DRM 由多个组件共同绑定完成初始化,包括 VOP/VOP2、显示接口控制器、PHY、Bridge、Panel、Backlight 等。启动早期出现 -EPROBE_DEFER 不一定是终故障,判断标准包括后续是否成功 bind、是否出现 Rockchip DRM 初始化完成日志等。若始终不收敛,需要重点检查 Panel compatible、remote-endpoint 等因素。
设备树 Graph 的作用:设备树 Graph 用于描述显示通路的拓扑结构,通过 port、endpoint 与 remote-endpoint 描述模块连接。VOP2 到接口的路由通过特定节点选择 VP,display-subsystem 维护 route 节点描述 U-Boot/Kernel Logo 使用的显示路径。启用 Logo 时需要核对 route 状态、connect 指向等信息。
Panel、Bridge、Backlight 与电源顺序:Panel 典型的上电与下电顺序包括电源上电、释放 Reset / Enable、接口初始化、VOP 开始输出有效视频和背光开启等步骤。Panel 状态机有 prepare、enable、disable、unprepare 等通用语义,背光的开启和关闭需要考虑避免白闪、残影和异常亮线等问题。panel-simple 常见属性包括 power-supply、backlight、enable-gpios 等,应根据屏规格填写。Bridge 驱动需要处理 Mode 校验、输入 / 输出 Bus Format、电源初始化等关键责任。
各显示接口的位置与调试重点:不同显示接口在 DRM 链路中具有不同的控制信息、视频链路和常见调试重点。例如,HDMI 需要关注 DDC/EDID、HPD、TMDS/FRL 等;DP 需要关注 AUX/DPCD、HPD、Main Link 等;eDP 需要关注 AUX/DPCD、HPD、Panel Timing 等;MIPI DSI 需要关注 DCS/Generic Command、D-PHY/C-PHY Lane 等;LVDS 需要关注 Bus Format、单双通道、奇偶像素等;RGB/TTL 需要关注 Pinmux、Data 位宽等。
DP/eDP 的关键因素:Rockchip eDP 指南将典型接口拆分为 Main-Link、AUX CH 和 HPD。HPD 高表示 Sink 已就绪,AUX 用于读取 DPCD 和 EDID 等信息,Link Training 包括 Clock Recovery 与 Channel Equalization。失败时可按顺序尝试检查 DPCD 能力读取、降低 Link Rate 等方法。Controller BIST 与 Panel Self-Test 可用于判断链路故障位置。
LVDS 的特点与问题排查:LVDS 是物理层传输技术,有不同的 Bus Format 映射。单通道需要确认 Panel Timing、Bus Format 等因素;Dual LVDS 将像素拆到两组通道,若两路顺序反了会出现画面锯齿等问题,应优先交换 odd/even 属性。黑白或颜色异常时,需要检查 JEIDA/VESA 选择、Bus Format 等因素。
MIPI DSI、HDMI、RGB 的学习要点:MIPI DSI 的学习顺序包括 Video Mode 与 Command Mode、D-PHY Lane 等;HDMI 需要关注 HPD、DDC/EDID、Mode 选择等;RGB/TTL 更依赖基础电气和 Timing,如 Pinmux、Data 位宽等。