一、视频处理单元(VPU):硬解码/编码引擎

1.1 VPU架构与设备树集成

RK3568的VPU子系统基于Rockchip自主研发的视频编解码IP核,支持H.264/H.265/VP9等主流格式。其架构设计将硬件描述、驱动框架和用户空间API清晰分层。

// VPU设备树节点定义
vpu: video-codec@fdea0400 {
    compatible = "rockchip,rk3568-vpu"; // 硬件标识符
    reg = <0x0 0xfdea0400 0x0 0x400>;   // 寄存器地址范围
    interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>; // 中断139
    clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; // 工作时钟与总线时钟
    clock-names = "aclk", "hclk";
    power-domains = <&power RK3568_PD_VPU>; // 绑定到VPU电源域
    iommus = <&vpu_iommu>; // 专用IOMMU,提升内存安全性
    rockchip,srv = <&mpp_srv>; // 指向媒体处理服务
    rockchip,taskqueue-node = <0>; // 任务队列节点
    rockchip,resetgroup-node = <0>; // 复位组节点
    status = "okay";
};
​
// 预留VPU专用内存(减少DMA延迟)
reserved-memory {
    vpu_reserved: vpu_region@90800000 {
        reg = <0x0 0x90800000 0x0 0x800000>; // 8MB
        no-map; // 操作系统不映射此区域,由VPU直接访问
    };
};

1.2 VPU驱动架构:V4L2 M2M框架

Linux内核通过V4L2(Video for Linux 2) 框架的Memory-to-Memory(M2M) 设备类型来抽象VPU,这使得用户空间应用可以使用标准API进行视频编解码。

// VPU驱动初始化与V4L2集成
// drivers/staging/media/rkvdec/rk_vdec.c
static int rk_vdec_probe(struct platform_device *pdev)
{
    struct rk_vdec *vdec;
    struct video_device *vfd;
    int ret;
    
    // 1. 分配驱动私有数据结构
    vdec = devm_kzalloc(&pdev->dev, sizeof(*vdec), GFP_KERNEL);
    
    // 2. 映射硬件寄存器
    vdec->regs = devm_platform_ioremap_resource(pdev, 0);
    
    // 3. 获取时钟和中断
    vdec->aclk = devm_clk_get(&pdev->dev, "aclk");
    vdec->hclk = devm_clk_get(&pdev->dev, "hclk");
    vdec->irq = platform_get_irq(pdev, 0);
    
    // 4. 初始化V4L2 M2M设备
    vdec->m2m_dev = v4l2_m2m_init(&rk_vdec_m2m_ops);
    
    // 5. 注册视频设备
    vfd = &vdec->vfd;
    vfd->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
    video_set_drvdata(vfd, vdec);
    ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
    
    // 6. 注册到媒体控制器框架(用于复杂媒体链路)
    vdec->mdev.dev = &pdev->dev;
    strscpy(vdec->mdev.model, "rk3568-vdec", sizeof(vdec->mdev.model));
    media_device_init(&vdec->mdev);
    vdec->v4l2_dev.mdev = &vdec->mdev;
    
    return 0;
}
​
// V4L2 M2M操作集定义
static const struct v4l2_m2m_ops rk_vdec_m2m_ops = {
    .device_run = rk_vdec_device_run,      // 启动硬件处理
    .job_ready = rk_vdec_job_ready,        // 检查任务就绪
    .job_abort = rk_vdec_job_abort,        // 中止任务
};

1.3 VPU工作流程与缓冲区管理

VPU使用双缓冲区环形队列来管理输入/输出数据,结合DMA进行高效数据传输。

// VPU缓冲区处理流程
static void rk_vdec_device_run(void *priv)
{
    struct rk_vdec_ctx *ctx = priv;
    struct rk_vdec *vdec = ctx->dev;
    struct vb2_v4l2_buffer *src_buf, *dst_buf;
    
    // 1. 从队列中获取缓冲区
    src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
    dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
    
    // 2. 配置VPU硬件寄存器
    // 源缓冲区地址(编码输入/解码码流)
    writeq(vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0),
           vdec->regs + VDEC_REG_SRC_ADDR);
    
    // 目标缓冲区地址(编码输出/解码图像)
    writeq(vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0),
           vdec->regs + VDEC_REG_DST_ADDR);
    
    // 3. 配置编解码参数
    rk_vdec_set_params(vdec, ctx);
    
    // 4. 启动VPU硬件处理
    writel(VDEC_START, vdec->regs + VDEC_REG_EN);
    
    // 5. 记录缓冲区关联(用于完成中断处理)
    ctx->cur_src_buf = src_buf;
    ctx->cur_dst_buf = dst_buf;
}
​
// VPU中断处理(任务完成)
static irqreturn_t rk_vdec_irq_handler(int irq, void *dev_id)
{
    struct rk_vdec *vdec = dev_id;
    struct rk_vdec_ctx *ctx;
    u32 status;
    
    // 1. 读取中断状态
    status = readl(vdec->regs + VDEC_REG_INT);
    
    // 2. 检查是否为任务完成中断
    if (status & VDEC_INT_FRAME_DONE) {
        ctx = v4l2_m2m_get_curr_priv(vdec->m2m_dev);
        
        // 3. 标记缓冲区为完成
        ctx->cur_src_buf->vb2_buf.timestamp = ktime_get_ns();
        ctx->cur_dst_buf->vb2_buf.timestamp = ktime_get_ns();
        
        v4l2_m2m_buf_done(ctx->cur_src_buf, VB2_BUF_STATE_DONE);
        v4l2_m2m_buf_done(ctx->cur_dst_buf, VB2_BUF_STATE_DONE);
        
        // 4. 通知V4L2框架处理下一个任务
        v4l2_m2m_job_finish(vdec->m2m_dev, ctx->fh.m2m_ctx);
        
        // 5. 清除中断标志
        writel(VDEC_INT_FRAME_DONE, vdec->regs + VDEC_REG_INT_CLR);
    }
    
    return IRQ_HANDLED;
}

二、图像信号处理器(ISP):从原始数据到优质图像

2.1 ISP硬件流水线

RK3568的ISP是一个复杂的图像处理流水线,包含多个可配置的处理阶段,每个阶段对应特定的图像质量优化算法。

// ISP设备树定义
isp: isp@fdb00000 {
    compatible = "rockchip,rk3568-isp";
    reg = <0x0 0xfdb00000 0x0 0x10000>;
    interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&cru CLK_ISP>, <&cru HCLK_ISP>;
    clock-names = "isp", "aclk";
    power-domains = <&power RK3568_PD_VI>;
    iommus = <&isp_iommu>;
    rockchip,grf = <&grf>;
    phys = <&csi_dphy0>; // 连接CSI-2物理层
    phy-names = "dphy";
    status = "okay";
    
    // ISP子设备(多个处理单元)
    ports {
        #address-cells = <1>;
        #size-cells = <0>;
        
        port@0 {
            reg = <0>;
            #address-cells = <1>;
            #size-cells = <0>;
            
            // CSI输入
            isp_in_csi: endpoint@0 {
                reg = <0>;
                remote-endpoint = <&csi_out_isp>;
                data-lanes = <1 2 3 4>; // 支持4数据通道
            };
        };
        
        port@1 {
            reg = <1>;
            #address-cells = <1>;
            #size-cells = <0>;
            
            // 内存输出
            isp_out: endpoint@0 {
                reg = <0>;
                remote-endpoint = <&isp_input>;
            };
        };
    };
};

2.2 ISP处理链配置

ISP驱动使用V4L2子设备(subdev)框架来抽象每个处理单元,形成可动态配置的处理流水线。

// ISP处理链初始化
// drivers/media/platform/rockchip/isp/isp.c
static int rkisp_initialize_pipeline(struct rkisp_device *isp)
{
    // 1. 创建媒体设备(整合所有ISP子设备)
    isp->media_dev.dev = isp->dev;
    strscpy(isp->media_dev.model, "rk3568-isp", 
            sizeof(isp->media_dev.model));
    media_device_init(&isp->media_dev);
    
    // 2. 初始化ISP核心
    rkisp_init_isp(isp);
    
    // 3. 初始化CSI接收器
    rkisp_init_csi(isp);
    
    // 4. 初始化图像处理单元
    rkisp_init_isp_proc(isp);   // 主ISP处理
    rkisp_init_stats(isp);      // 统计单元(用于3A算法)
    rkisp_init_params(isp);     // 参数单元
    
    // 5. 注册子设备
    v4l2_device_register_subdev(&isp->v4l2_dev, &isp->isp_sd);
    v4l2_device_register_subdev(&isp->v4l2_dev, &isp->csi_sd);
    v4l2_device_register_subdev(&isp->v4l2_dev, &isp->proc_sd);
    
    // 6. 创建媒体链路(连接各处理单元)
    media_create_pad_link(&isp->csi_sd.entity, CSI_PAD_SOURCE,
                         &isp->isp_sd.entity, ISP_PAD_SINK, 0);
    media_create_pad_link(&isp->isp_sd.entity, ISP_PAD_SOURCE,
                         &isp->proc_sd.entity, PROC_PAD_SINK, 0);
    
    return 0;
}
​
// ISP统计单元(3A算法支持)
static int rkisp_stats_init(struct rkisp_device *isp)
{
    struct rkisp_stats *stats = &isp->stats;
    
    // 分配统计缓冲区(用于AE/AF/AWB算法)
    stats->buf = dma_alloc_coherent(isp->dev, STATS_BUF_SIZE,
                                   &stats->dma_addr, GFP_KERNEL);
    
    // 配置统计区域
    for (i = 0; i < NUM_STATS_ZONES; i++) {
        stats->zones[i].offset = i * ZONE_SIZE;
        stats->zones[i].size = ZONE_SIZE;
        
        // 设置到硬件寄存器
        writel(stats->dma_addr + stats->zones[i].offset,
               isp->regs + STATS_ZONE_BASE(i));
        writel(stats->zones[i].size,
               isp->regs + STATS_ZONE_SIZE(i));
    }
    
    return 0;
}

2.3 自动控制算法(3A)集成

ISP的关键功能是通过自动曝光(AE)、自动对焦(AF)、自动白平衡(AWB) 算法实时优化图像质量。

// 3A算法框架集成
static void rkisp_3a_algorithms_process(struct rkisp_device *isp)
{
    struct rkisp_stats *stats = &isp->stats;
    
    // 1. 从硬件读取统计信息
    dma_sync_single_for_cpu(isp->dev, stats->dma_addr,
                           STATS_BUF_SIZE, DMA_FROM_DEVICE);
    
    // 2. 自动曝光算法
    rkisp_ae_process(isp, &stats->ae_data);
    if (isp->ae.new_exposure != isp->ae.current_exposure) {
        // 更新传感器曝光参数
        rkisp_set_sensor_exposure(isp, isp->ae.new_exposure);
    }
    
    // 3. 自动白平衡算法
    rkisp_awb_process(isp, &stats->awb_data);
    if (isp->awb.new_gains != isp->awb.current_gains) {
        // 更新ISP白平衡增益
        rkisp_set_white_balance(isp, isp->awb.new_gains);
    }
    
    // 4. 自动对焦算法(如果支持)
    if (isp->has_af) {
        rkisp_af_process(isp, &stats->af_data);
        if (isp->af.new_position != isp->af.current_position) {
            rkisp_set_focus_position(isp, isp->af.new_position);
        }
    }
    
    // 5. 同步统计缓冲区回设备
    dma_sync_single_for_device(isp->dev, stats->dma_addr,
                              STATS_BUF_SIZE, DMA_TO_DEVICE);
}

三、显示子系统:多显示输出与叠加

3.1 VOP(视频输出处理器)架构

RK3568的显示子系统基于VOP(Video Output Processor) 硬件,支持多图层叠加、缩放、旋转等高级显示功能。

// VOP设备树定义
vop: vop@fe040000 {
    compatible = "rockchip,rk3568-vop";
    reg = <0x0 0xfe040000 0x0 0x3000>, // VOP主寄存器
          <0x0 0xfe044000 0x0 0x1000>; // VOP副寄存器
    reg-names = "regs", "gamma_lut";
    interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>, 
             <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
    clock-names = "aclk", "hclk", "dclk_vp0", "dclk_vp1";
    iommus = <&vop_iommu>;
    power-domains = <&power RK3568_PD_VO>;
    rockchip,grf = <&grf>;
    
    // 两个显示管线(支持双屏异显)
    vop_out: ports {
        #address-cells = <1>;
        #size-cells = <0>;
        
        port@0 {
            reg = <0>;
            #address-cells = <1>;
            #size-cells = <0>;
            
            // HDMI输出
            vp0_out_hdmi: endpoint@0 {
                reg = <0>;
                remote-endpoint = <&hdmi_in_vp0>;
            };
            
            // eDP输出
            vp0_out_edp: endpoint@1 {
                reg = <1>;
                remote-endpoint = <&edp_in_vp0>;
            };
        };
        
        port@1 {
            reg = <1>;
            #address-cells = <1>;
            #size-cells = <0>;
            
            // MIPI DSI输出
            vp1_out_dsi: endpoint@0 {
                reg = <0>;
                remote-endpoint = <&dsi_in_vp1>;
            };
        };
    };
};

3.2 DRM/KMS驱动框架集成

RK3568的显示驱动基于Linux标准的DRM(Direct Rendering Manager)/KMS(Kernel Mode Setting) 框架,提供统一的显示管理接口。

// VOP DRM驱动组件
// drivers/gpu/drm/rockchip/rockchip_drm_vop.c
static const struct drm_plane_helper_funcs vop_plane_helper_funcs = {
    .prepare_fb = vop_plane_prepare_fb,    // 缓冲区准备
    .cleanup_fb = vop_plane_cleanup_fb,    // 缓冲区清理
    .atomic_check = vop_plane_atomic_check, // 参数检查
    .atomic_update = vop_plane_atomic_update, // 更新显示
    .atomic_disable = vop_plane_atomic_disable, // 禁用平面
};
​
// VOP图层(plane)管理
struct vop_plane {
    struct drm_plane base;          // DRM平面基类
    enum vop_plane_id id;           // 平面ID
    const struct vop_plane_data *data; // 平面能力数据
    
    // 硬件寄存器
    void __iomem *regs;
    
    // 当前显示缓冲区
    struct drm_framebuffer *fb;
    dma_addr_t dma_addr;
    
    // 显示参数
    int x, y;           // 屏幕位置
    int w, h;           // 显示尺寸
    bool enabled;       // 启用状态
};
​
// 平面更新操作(原子提交)
static void vop_plane_atomic_update(struct drm_plane *plane,
                                   struct drm_plane_state *old_state)
{
    struct vop_plane *vop_plane = to_vop_plane(plane);
    struct drm_plane_state *state = plane->state;
    struct drm_framebuffer *fb = state->fb;
    struct drm_rect *dest = &state->dst;
    
    // 1. 配置缓冲区地址
    dma_addr_t addr = rockchip_fb_get_dma_addr(fb, 0);
    writel(addr, vop_plane->regs + VOP_PLANE_ADDR);
    
    // 2. 配置显示位置和尺寸
    writel(dest->x1, vop_plane->regs + VOP_PLANE_XPOS);
    writel(dest->y1, vop_plane->regs + VOP_PLANE_YPOS);
    writel(dest->x2 - dest->x1, vop_plane->regs + VOP_PLANE_WIDTH);
    writel(dest->y2 - dest->y1, vop_plane->regs + VOP_PLANE_HEIGHT);
    
    // 3. 配置格式和混合
    u32 fmt = vop_convert_format(fb->format->format);
    writel(fmt, vop_plane->regs + VOP_PLANE_FORMAT);
    
    // 4. 配置混合参数(透明度等)
    u32 blend = VOP_BLEND_PREMULTIPLIED;
    blend |= (state->alpha >> 8) << VOP_BLEND_ALPHA_SHIFT;
    writel(blend, vop_plane->regs + VOP_PLANE_BLEND);
    
    // 5. 启用平面
    writel(VOP_PLANE_ENABLE, vop_plane->regs + VOP_PLANE_CTRL);
}

四、为什么这么设计:多媒体子系统的架构优势

4.1 硬件加速与软件框架的完美结合

设计理念:将专用硬件加速与Linux标准多媒体框架深度集成。

优势分析

  1. 性能最大化:编解码、ISP处理等计算密集型任务由硬件加速

  2. API标准化:通过V4L2、DRM/KMS提供统一接口,简化应用开发

  3. 框架可扩展:新硬件特性可通过扩展框架支持,保持向后兼容

// 多媒体框架层次结构
+-----------------------------------------------+
|             用户空间应用程序                   |
|   (GStreamer, FFmpeg, Android Camera HAL)    |
+-----------------------------------------------+
|              Linux标准多媒体框架               |
|   (V4L2, DRM/KMS, Media Controller)          |
+-----------------------------------------------+
|            Rockchip专用驱动层                 |
|   (VPU驱动, ISP驱动, VOP驱动)                 |
+-----------------------------------------------+
|             RK3568硬件加速单元                 |
|   (VPU, ISP, VOP硬件模块)                     |
+-----------------------------------------------+

// 与传统设计的对比
传统设计:
应用 -> 私有API -> 硬件驱动 -> 硬件
问题:应用与硬件强耦合,移植性差

RK3568设计:
应用 -> 标准V4L2/DRM API -> 框架层 -> 硬件驱动 -> 硬件
优势:应用与硬件解耦,支持多种硬件,生态丰富

4.2 异构计算资源的协同调度

设计理念:CPU、VPU、ISP等计算单元协同工作,形成异构计算流水线。

优势分析

  1. 任务卸载:CPU将视频编解码、图像处理等任务卸载到专用硬件

  2. 并行处理:多个硬件单元可并行处理不同任务

  3. 能效优化:专用硬件比通用CPU能效更高

// 视频处理流水线示例
static void video_processing_pipeline(struct camera_buffer *input)
{
    // 阶段1:ISP处理(专用硬件)
    struct image_buffer *processed = isp_process(input);
    
    // 阶段2:AI分析(可选的NPU加速)
    struct ai_results *results = NULL;
    if (has_npu_acceleration) {
        results = npu_analyze_image(processed);  // NPU加速
    } else {
        results = cpu_analyze_image(processed);  // CPU后备
    }
    
    // 阶段3:视频编码(VPU硬件加速)
    struct encoded_stream *stream = vpu_encode_video(processed);
    
    // 阶段4:显示输出(VOP硬件)
    vop_display_frame(processed);
    
    // 所有阶段可并行处理不同帧,形成流水线
    // 帧1:ISP -> 帧2:NPU -> 帧3:VPU -> 帧4:显示
}

4.3 电源与性能的动态平衡

设计理念:根据工作负载动态调整多媒体硬件的性能状态。

优势分析

  1. 精细功耗控制:每个多媒体模块可独立进行DVFS

  2. 按需性能:轻负载时降频节能,重负载时全力运行

  3. 热管理集成:多媒体工作负载参与系统热管理决策

// ISP电源性能配置示例
&isp {
    // 操作性能点定义
    operating-points = <
        /* kHz    电压(uV) */
        200000    800000
        400000    850000
        600000    900000
        800000    950000
    >;
    
    // 冷却设备绑定
    cooling-cells = <2>;
    
    // 热区关联
    thermal-zones = <&isp_thermal>;
};

// 根据场景选择性能点
static void configure_isp_performance(enum isp_scenario scenario)
{
    switch (scenario) {
    case SCENARIO_PREVIEW:
        // 预览模式:低功耗,低延迟
        set_isp_frequency(200000);
        set_isp_quality(ISP_QUALITY_LOW);
        break;
        
    case SCENARIO_CAPTURE:
        // 拍照模式:高质量,可接受较高延迟
        set_isp_frequency(800000);
        set_isp_quality(ISP_QUALITY_HIGH);
        break;
        
    case SCENARIO_VIDEO:
        // 录像模式:平衡质量与功耗
        set_isp_frequency(600000);
        set_isp_quality(ISP_QUALITY_MEDIUM);
        break;
    }
}

第四部分总结

RK3568的多媒体子系统体现了现代SoC在专用计算、异构协同和能效管理方面的先进设计:

  1. 专用硬件加速:VPU、ISP、VOP等专用模块提供高效多媒体处理

  2. 标准框架集成:通过V4L2、DRM/KMS等标准框架提供统一接口

  3. 异构计算协同:CPU与专用硬件形成高效处理流水线

  4. 动态能效管理:根据工作负载智能调整性能与功耗

这种架构的核心价值在于:

  • 高性能多媒体处理:满足4K视频、高清图像等现代应用需求

  • 开发便利性:标准API降低应用开发门槛

  • 能效优化:专用硬件提供高性能的同时保持低功耗

  • 生态兼容性:与Linux多媒体生态无缝集成

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐