3. SA8155 DPU驱动架构:DPU驱动在DRM框架中的位置、msm_dpu驱动模块、dpu_kms核心结构体

SA8155的显示子系统基于高通骁龙平台的Display Processing Unit (DPU) 硬件模块。在Linux内核中,DPU驱动被封装为msm_dpu驱动模块,并作为DRM/KMS框架的一个具体实现。理解DPU驱动在DRM框架中的位置、模块组成以及核心结构体dpu_kms,是进行DPU中断配置与显示时序开发的基础。

架构定位提示: DRM框架提供设备无关的显示抽象层,而msm_dpu驱动则负责将SA8155的DPU硬件能力映射到DRM的KMS接口上。所有显示时序、中断、图层合成等底层操作,最终都通过dpu_kms结构体进行管理。

3.1 DPU驱动在DRM框架中的位置

在DRM框架中,msm_dpu驱动位于DRM Core与硬件抽象层之间。它向上通过struct drm_driver和struct drm_mode_config_funcs注册到DRM核心,向下直接操作DPU硬件寄存器。

下图展示了DPU驱动在DRM软件栈中的层级关系:

DPU驱动在DRM框架中的位置 用户空间 (Weston / SurfaceFlinger / DRM应用) DRM Core (drm.ko) KMS Helper (drm_kms_helper.ko) msm_dpu 驱动模块 (dpu_kms.c / dpu_encoder.c / dpu_crtc.c / dpu_plane.c) DPU 硬件寄存器映射 / MMIO SA8155 DPU 硬件 用户空间 内核空间 硬件层

从图中可以看出,msm_dpu驱动模块是连接DRM核心与DPU硬件的桥梁。它实现了DRM框架定义的struct drm_mode_config_funcs回调,包括fb_create、output_poll_changed等,并管理着dpu_kms这一核心结构体。

3.2 msm_dpu驱动模块

msm_dpu驱动模块是SA8155显示驱动的核心实现。它由多个子模块组成,每个子模块对应DRM框架中的一个组件。下表列出了主要子模块及其职责:

子模块文件 对应DRM组件 核心职责
dpu_kms.c DRM设备 (struct drm_device) 初始化/销毁DPU KMS实例,管理全局资源,注册中断处理
dpu_encoder.c DRM编码器 (struct drm_encoder) 管理显示时序输出,控制物理接口(DSI/DP/eDP),处理VSYNC中断
dpu_crtc.c DRM CRTC (struct drm_crtc) 管理显示流水线,协调图层合成,处理帧完成中断
dpu_plane.c DRM平面 (struct drm_plane) 管理硬件图层(VIG/DMA),处理图层属性更新,支持缩放/旋转
dpu_hw_intf.c 硬件接口层 封装DPU硬件接口寄存器操作,包括时序生成器、中断控制器
模块依赖关系: dpu_kms作为顶层管理者,在初始化时会依次创建dpu_encoder、dpu_crtc和dpu_plane实例。这些子模块通过dpu_kms提供的dpu_hw_intf接口访问硬件寄存器,实现显示时序配置与中断控制。

msm_dpu驱动模块的初始化流程如下:

  1. 平台驱动探测: 内核调用dpu_kms_probe(),匹配设备树节点,获取MMIO基地址和中断号。
  2. DRM设备注册: 调用drm_dev_alloc()分配struct drm_device,并将dpu_kms结构体关联到drm_device->dev_private。
  3. 模式配置初始化: 设置drm_mode_config的min_width、max_width、funcs等参数。
  4. 子模块创建: 依次创建dpu_encoder、dpu_crtc、dpu_plane,并注册到DRM框架。
  5. 中断注册: 通过devm_request_irq()注册DPU中断处理函数,包括VSYNC、帧完成、错误中断等。
  6. DRM设备注册: 调用drm_dev_register(),使设备对用户空间可见。

3.3 dpu_kms核心结构体

dpu_kms是msm_dpu驱动中最重要的数据结构,它封装了整个DPU显示子系统的状态和控制信息。该结构体定义在drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h中。

以下是dpu_kms结构体的核心字段及其作用:

struct dpu_kms {
    struct drm_device *dev;           // 关联的DRM设备
    struct platform_device *pdev;     // 平台设备指针

    void __iomem *mmio;               // DPU寄存器MMIO基地址
    unsigned long mmio_size;          // MMIO区域大小

    struct dpu_hw_catalog *catalog;   // 硬件能力描述表
    struct dpu_rm *rm;                // 资源管理器

    struct dpu_irq_controller irq_ctrl; // 中断控制器

    struct dpu_encoder *encoders[DPU_MAX_ENCODERS]; // 编码器数组
    struct dpu_crtc *crtcs[DPU_MAX_CRTCS];         // CRTC数组
    struct dpu_plane *planes[DPU_MAX_PLANES];       // 平面数组

    struct clk *core_clk;             // DPU核心时钟
    struct clk *vsync_clk;            // VSYNC时钟
    struct clk *axi_clk;              // AXI总线时钟

    struct regulator *vdd;            // DPU电源域

    bool has_danger_ctrl;             // 是否支持危险控制
    bool has_idle_pc;                 // 是否支持空闲电源管理
};

下表对关键字段进行详细说明:

字段 类型 说明
mmio void __iomem * DPU硬件寄存器的虚拟地址基址,所有寄存器读写操作都通过此指针进行
catalog struct dpu_hw_catalog * 描述SA8155 DPU硬件能力,包括支持的最大分辨率、图层数、混色器数量等
rm struct dpu_rm * 资源管理器,负责分配和回收硬件资源(如混色器、接口、图层管道)
irq_ctrl struct dpu_irq_controller 中断控制器,管理DPU所有中断的注册、使能、处理和清理
encoders struct dpu_encoder *[] 编码器数组,每个编码器对应一个物理显示接口(如DSI0、DSI1、DP)
core_clk struct clk * DPU核心时钟,控制显示处理单元的运行频率,直接影响显示时序

下图展示了dpu_kms结构体与各子模块之间的关系:

dpu_kms 核心结构体关系图 struct dpu_kms (全局显示状态管理器) dpu_hw_catalog 硬件能力描述 dpu_rm 资源管理器 dpu_irq_controller 中断控制器 dpu_encoder[] 编码器数组 dpu_crtc[] CRTC数组 dpu_plane[] 平面数组 clk (core/vsync/axi) 时钟管理 regulator (vdd) 电源管理
开发注意事项: 在编写DPU中断处理函数时,必须通过dpu_kms->irq_ctrl来注册和注销中断,而不是直接调用request_irq。因为dpu_irq_controller封装了中断的共享处理逻辑,确保多个子模块(如encoder和crtc)可以安全地共享同一个硬件中断线。