VeriSilicon DRM 驱动深度解析:StarFive JH7100 显示子系统实现

2026-03-23

一、驱动概述

该驱动是面向 StarFive JH7100 SoC 的 DRM 显示子系统驱动,由 VeriSilicon(芯动科技) 开发。驱动基于 Linux 5.15+ 内核,支持多路显示输出、硬件图层叠加、色彩空间转换等功能。

// vs_drv.c
#define DRV_NAME    "vs-drm"
#define DRV_DESC    "VeriSilicon DRM driver"

主要特性

  • DRM Atomic 模式设置
  • GEM DMA 内存管理
  • IOMMU 支持(可选)
  • 多输出接口:HDMI、DP、MIPI DSI
  • 硬件图层叠加(Overlay)

二、系统架构

graph TB
    subgraph "User Space"
        APP[Applications]
    end
    
    subgraph "DRM Framework"
        DRM[DRM Core]
        GEM[GEM Manager]
        KMS[KMS Subsystem]
    end
    
    subgraph "VeriSilicon Display Subsystem"
        DC[Display Controller]
        MMU[IOMMU]
        PLANE[Plane Layers]
    end
    
    subgraph "Output Encoders"
        HDMI[HDMI Transmitter]
        DP[DisplayPort]
        DSI[MIPI DSI]
    end
    
    APP --> DRM
    DRM --> GEM
    DRM --> KMS
    DC --> PLANE
    DC --> MMU
    PLANE --> HDMI
    PLANE --> DP
    PLANE --> DSI

显示数据流

Framebuffer (GEM)
    ↓
Plane (Primary/Overlay/Cursor)
    ↓
Display Controller (硬件叠加与缩放)
    ↓
Output Encoder (HDMI/DP/DSI)
    ↓
Display Device

三、核心组件分析

3.1 主驱动模块 (vs_drv.c)

主驱动负责 DRM 设备初始化和组件管理:

static struct drm_driver vs_drm_driver = {
    .driver_features = DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_GEM,
    .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
    .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
    .gem_prime_import   = vs_gem_prime_import,
    .gem_prime_import_sg_table = vs_gem_prime_import_sg_table,
    .dumb_create        = vs_gem_dumb_create,
    .fops               = &fops,
};

关键实现

static int vs_drm_bind(struct device *dev)
{
    // 1. 分配 DRM 设备
    drm_dev = drm_dev_alloc(&vs_drm_driver, dev);
    
    // 2. 初始化私有数据
    priv->pitch_alignment = 64;
    priv->dma_dev->coherent_dma_mask = DMA_BIT_MASK(40);
    
    // 3. 模式配置初始化
    drm_mode_config_init(drm_dev);
    
    // 4. 绑定子组件
    component_bind_all(dev, drm_dev);
    
    // 5. 扩展模式配置
    vs_mode_config_init(drm_dev);
    
    // 6. 注册 DRM 设备
    drm_dev_register(drm_dev, 0);
    
    // 7. 初始化 fbdev
    drm_fbdev_generic_setup(drm_dev, 32);
}

Component 框架

static struct platform_driver *drm_sub_drivers[] = {
    &dc_platform_driver,           // 显示控制器
#ifdef CONFIG_STARFIVE_INNO_HDMI
    &inno_hdmi_driver,              // HDMI 连接器
#endif
#ifdef CONFIG_STARFIVE_DW_DP
    &dw_dp_driver,                  // DP 连接器
#endif
#ifdef CONFIG_VERISILICON_VIRTUAL_DISPLAY
    &virtual_display_platform_driver,
#endif
};

3.2 显示控制器 (vs_dc.c)

显示控制器是硬件的核心,负责:

  • 帧缓冲读取
  • 图层混合
  • 色彩空间转换
  • 扫描时序生成
// vs_dc.c - 格式映射
static inline void update_format(u32 format, u64 mod, struct dc_hw_fb *fb)
{
    u8 f = FORMAT_A8R8G8B8;
    
    switch (format) {
    case DRM_FORMAT_XRGB8888:
    case DRM_FORMAT_RGBX8888:
        f = FORMAT_X8R8G8B8;
        break;
    case DRM_FORMAT_ARGB8888:
    case DRM_FORMAT_RGBA8888:
        f = FORMAT_A8R8G8B8;
        break;
    case DRM_FORMAT_YUYV:
    case DRM_FORMAT_YVYU:
        f = FORMAT_YUY2;
        break;
    case DRM_FORMAT_UYVY:
    case DRM_FORMAT_VYUY:
        f = FORMAT_UYVY;
        break;
    case DRM_FORMAT_YUV420:
    case DRM_FORMAT_YVU420:
        f = FORMAT_YV12;
        break;
    case DRM_FORMAT_NV12:
        if (fourcc_mod_vs_get_type(mod) == DRM_FORMAT_MOD_VS_TYPE_CUSTOM_10BIT)
            f = FORMAT_NV12_10BIT;
        else
            f = FORMAT_NV12;
        break;
    // ... 更多格式
    }
    
    fb->format = f;
}

支持的颜色格式

DRM Format Hardware Format 说明
XRGB8888 FORMAT_X8R8G8B8 24bpp RGB
ARGB8888 FORMAT_A8R8G8B8 32bpp ARGB
RGB565 FORMAT_R5G6B5 16bpp
YUYV FORMAT_YUY2 YUV422
NV12 FORMAT_NV12 YUV420 Semi-planar
P010 FORMAT_P010 10-bit YUV420

3.3 CRTC 实现 (vs_crtc.c)

static void vs_crtc_reset(struct drm_crtc *crtc)
{
    struct vs_crtc_state *state;
    
    state = kzalloc(sizeof(*state), GFP_KERNEL);
    __drm_atomic_helper_crtc_reset(crtc, &state->base);
    
    state->sync_mode = VS_SINGLE_DC;
    state->output_fmt = MEDIA_BUS_FMT_YUV8_1X24;
    state->encoder_type = DRM_MODE_ENCODER_NONE;
    
#ifdef CONFIG_VERISILICON_MMU
    state->mmu_prefetch = VS_MMU_PREFETCH_DISABLE;
#endif
}

CRTC 状态跟踪

  • sync_mode:同步模式(单DC/双DC级联)
  • output_fmt:输出格式(YUV/RGB)
  • mmu_prefetch:MMU 预取设置

四、Plane 与图层管理

// vs_plane.c - Plane 辅助函数
static const struct drm_plane_helper_funcs vs_plane_helper_funcs = {
    .prepare_fb = vs_plane_prepare_fb,
    .atomic_check = vs_plane_atomic_check,
    .atomic_update = vs_plane_atomic_update,
    .atomic_disable = vs_plane_atomic_disable,
};

Plane 类型

  • Primary Plane:主图层,用于显示
  • Overlay Plane:叠加图层,支持混合
  • Cursor Plane:光标图层
static int vs_plane_atomic_update(struct drm_plane *plane,
                                   struct drm_atomic_state *state)
{
    struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane);
    struct vs_plane *vs_plane = to_vs_plane(plane);
    struct vs_plane_state *vs_state = to_vs_plane_state(new_state);
    
    // 1. 解析帧缓冲信息
    // 2. 配置硬件图层参数
    // 3. 设置缩放和裁剪
    // 4. 配置色彩混合
}

五、输出接口支持

5.1 HDMI 输出

// inno_hdmi.c - HDMI 连接器实现
static const struct drm_connector_funcs inno_hdmi_connector_funcs = {
    .detect = inno_hdmi_connector_detect,
    .fill_modes = drm_helper_probe_single_connector_modes,
    .destroy = inno_hdmi_connector_destroy,
    .reset = drm_atomic_helper_connector_reset,
    .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
    .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};

特点

  • 支持 EDID 读取
  • 固定分辨率:1920x1080
  • 支持 YUV 输出

5.2 DP 输出

// dw-dp.c - DisplayPort 驱动
static struct platform_driver dw_dp_driver = {
    .probe = dw_dp_probe,
    .remove = dw_dp_remove,
    .driver = {
        .name = "dw-dp",
        .of_match_table = dw_dp_of_table,
    },
};

5.3 MIPI DSI

// dw_mipi_dsi.c - MIPI DSI 主机控制器
struct dw_mipi_dsi {
    struct device *dev;
    void __iomem *base;
    struct clk *pclk;
    struct reset_control *rst;
    // ...
};

六、内存管理与 IOMMU

// vs_drm_iommu_attach_device
int vs_drm_iommu_attach_device(struct drm_device *drm_dev, struct device *dev)
{
    struct vs_drm_private *priv = drm_dev->dev_private;
    
    if (!has_iommu)
        return 0;
    
    if (!priv->domain) {
        priv->domain = iommu_get_domain_for_dev(dev);
        priv->dma_dev = dev;
    }
    
    return iommu_attach_device(priv->domain, dev);
}

IOMMU 配置检测

static int vs_drm_platform_of_probe(struct device *dev)
{
    for (i = 0;; i++) {
        port = of_parse_phandle(np, "ports", i);
        iommu = of_parse_phandle(port->parent, "iommus", 0);
        
        // 如果任一 CRTC 不支持 IOMMU,则禁用全局 IOMMU
        if (!iommu || !of_device_is_available(iommu->parent))
            has_iommu = false;
    }
}

七、格式支持与转换

// vs_dc_swizzle - Swizzle 模式配置
static inline void update_swizzle(u32 format, struct dc_hw_fb *fb)
{
    fb->swizzle = SWIZZLE_ARGB;
    fb->uv_swizzle = 0;
    
    switch (format) {
    case DRM_FORMAT_RGBX8888:
    case DRM_FORMAT_RGBA8888:
    case DRM_FORMAT_RGBA1010102:
        fb->swizzle = SWIZZLE_RGBA;
        break;
    // ...
    }
}

硬件 Swizzle 模式

  • SWIZZLE_ARGB:标准 ARGB 顺序
  • SWIZZLE_RGBA:RGBA 顺序交换
  • SWIZZLE_XRGB:XBGR 顺序

八、调试与调试功能

#ifdef CONFIG_DEBUG_FS
static int vs_debugfs_planes_show(struct seq_file *s, void *data)
{
    struct drm_plane *plane;
    
    list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
        struct drm_plane_state *state = plane->state;
        struct vs_plane_state *plane_state = to_vs_plane_state(state);
        
        seq_printf(s, "plane[%u]: %s\n", plane->base.id, plane->name);
        seq_printf(s, "\tcrtc = %s\n", state->crtc ? state->crtc->name : "(null)");
        seq_printf(s, "\tcrtc-pos = " DRM_RECT_FMT "\n", DRM_RECT_ARG(&plane_state->status.dest));
        seq_printf(s, "\tsrc-pos = " DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&plane_state->status.src));
        seq_printf(s, "\trotation = 0x%x\n", state->rotation);
        seq_printf(s, "\ttiling = %u\n", plane_state->status.tile_mode);
    }
    
    return 0;
}
#endif

九、高级特性详解

9.1 DRM Property 系统

驱动实现了完善的 Property 状态管理系统,用于配置硬件参数:

// vs_dc_property.c - Property 状态初始化
bool vs_dc_initialize_property_states(struct vs_dc_property_state_group *states)
{
    const struct vs_dc_property_proto *proto = NULL;
    struct vs_dc_property_state *item = NULL;
    
    // 支持多种属性类型
    switch (proto->type) {
    case VS_DC_PROPERTY_BLOB:    // BLOB 数据
    case VS_DC_PROPERTY_ARRAY:    // 数组
    case VS_DC_PROPERTY_ENUM:    // 枚举值
    case VS_DC_PROPERTY_RANGE:   // 范围值
    case VS_DC_PROPERTY_BITMASK: // 位掩码
    case VS_DC_PROPERTY_BOOL:    // 布尔值
        // ...
    }
}

Property 类型

  • VS_DC_PROPERTY_BLOB:用于 gamma/degamma LUT、3D LUT 等大数据块
  • VS_DC_PROPERTY_ENUM:枚举类型属性
  • VS_DC_PROPERTY_RANGE:数值范围属性
  • VS_DC_PROPERTY_BITMASK:位掩码属性

9.2 高级 Plane 功能

// vs_plane.c - Plane 状态重置
static void vs_plane_reset(struct drm_plane *plane)
{
    state->base.color_encoding = DRM_COLOR_YCBCR_BT2020;
    state->base.zpos = vs_plane->id;
    
    // 色彩空间转换系数
    drm_property_blob_put(state->y2r_coef);
    // 3D LUT
    drm_property_blob_put(state->lut_3d);
    // PVRIC 压缩相关
    drm_property_blob_put(state->pvric_clear);
    drm_property_blob_put(state->pvric_const);
}

9.3 硬件能力定义

// vs_type.h - Plane 能力标志
struct vs_plane_info {
    u32 color_mgmt : 1;      // 色彩管理
    u32 program_csc : 1;    // 可编程色彩空间转换
    u32 roi : 1;            // 感兴趣区域
    u32 cgm_lut : 1;         // 3D LUT 色彩管理
    u32 alpha_ext : 1;      // 扩展 Alpha
    u32 demultiply : 1;      // Alpha 反预乘
    u32 hdr : 1;            // HDR 支持
    u32 tone_map : 1;       // 色调映射
    u32 watermark : 1;      // 水印
    u32 compressed : 1;     // 压缩格式支持
    u32 test_pattern : 1;   // 测试图案
};

struct vs_display_info {
    u32 bld_cgm : 1;        // 混合 EOTF/色域映射
    u32 gamma : 1;          // Gamma 校正
    u32 degamma : 1;        // Degamma 校正
    u32 ltm : 1;            // 本地色调映射
    u32 gtm : 1;            // 全局色调映射
    u32 cgm_lut : 1;        // 3D LUT
    u32 dsc : 1;            // Display Stream Compression
    u32 vrr : 1;            // 可变刷新率
    u32 decompress : 1;     // 解压支持
};

9.4 压缩格式支持

// 驱动支持的压缩格式修饰符
/*
 * cap_dec ===>
 *   (1 << DRM_FORMAT_MOD_VS_TYPE_COMPRESSED) = DEC400
 *   (1 << DRM_FORMAT_MOD_VS_TYPE_PVRIC) = PVRIC
 *   (1 << DRM_FORMAT_MOD_VS_TYPE_DECNANO) = DECNANO
 *   (1 << DRM_FORMAT_MOD_VS_TYPE_ETC2) = ETC2
 */
u32 cap_dec;

9.5 芯片信息

// 8x00/vs_dc_info.h
enum dc_chip_rev {
    DC_REV_0,  // HW_REV_5720, HW_REV_5721_311
    DC_REV_1,  // HW_REV_5721_30b
    DC_REV_2,  // HW_REV_5721_310
};

enum dc_hw_plane_id {
    PRIMARY_PLANE_0,
    OVERLAY_PLANE_0,
    OVERLAY_PLANE_1,
    PRIMARY_PLANE_1,
    OVERLAY_PLANE_2,
    // ... 最多 PLANE_NUM 个平面
};

#define DC_LAYER_NUM 8       // 最大图层数
#define DC_DISPLAY_NUM 2    // 显示输出数
#define DC_WB_NUM 2          // 写回通道数
#define DC_OUTPUT_NUM 4     // 输出接口数

十、总结

该 VeriSilicon DRM 驱动是面向 StarFive JH7100 的完整显示解决方案:

特性 实现方式
平台 StarFive JH7100 / VeriSilicon DC
内核版本 Linux 5.15+
模式设置 Atomic Mode Setting
内存管理 GEM DMA + IOMMU(可选)
输出接口 HDMI (Inno), DP (DesignWare), DSI (DesignWare)
图层支持 Primary + Overlay + Cursor (8层)
格式支持 ARGB8888, RGB565, YUV422, YUV420, NV12, P010
调试 DebugFS 支持
高级特性 HDR, 3D LUT, Gamma/Degamma, DSC, VRR, 压缩格式

该驱动展示了商用 DRM 子系统的完整实现,包括 Component 框架管理多设备、IOMMU 支持、丰富的格式转换能力、先进的色彩管理(HDR、色调映射、3D LUT)等。


感谢阅读!