RK3568 SoC Linux BSP架构深度分析 - 第四部分:多媒体子系统与异构计算
一、视频处理单元(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标准多媒体框架深度集成。
优势分析:
-
性能最大化:编解码、ISP处理等计算密集型任务由硬件加速
-
API标准化:通过V4L2、DRM/KMS提供统一接口,简化应用开发
-
框架可扩展:新硬件特性可通过扩展框架支持,保持向后兼容
// 多媒体框架层次结构 +-----------------------------------------------+ | 用户空间应用程序 | | (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等计算单元协同工作,形成异构计算流水线。
优势分析:
-
任务卸载:CPU将视频编解码、图像处理等任务卸载到专用硬件
-
并行处理:多个硬件单元可并行处理不同任务
-
能效优化:专用硬件比通用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 电源与性能的动态平衡
设计理念:根据工作负载动态调整多媒体硬件的性能状态。
优势分析:
-
精细功耗控制:每个多媒体模块可独立进行DVFS
-
按需性能:轻负载时降频节能,重负载时全力运行
-
热管理集成:多媒体工作负载参与系统热管理决策
// 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在专用计算、异构协同和能效管理方面的先进设计:
-
专用硬件加速:VPU、ISP、VOP等专用模块提供高效多媒体处理
-
标准框架集成:通过V4L2、DRM/KMS等标准框架提供统一接口
-
异构计算协同:CPU与专用硬件形成高效处理流水线
-
动态能效管理:根据工作负载智能调整性能与功耗
这种架构的核心价值在于:
-
高性能多媒体处理:满足4K视频、高清图像等现代应用需求
-
开发便利性:标准API降低应用开发门槛
-
能效优化:专用硬件提供高性能的同时保持低功耗
-
生态兼容性:与Linux多媒体生态无缝集成
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)