RK628 Linux 内核驱动开发指南

RK628 Linux 内核驱动开发指南

基于源码分析 | Kernel 6.12 | 作者

1. 项目概述

RK628 是 Rockchip 推出的一款多功能显示桥接芯片(Bridge IC),核心功能是将 HDMI 输入信号转换为多种输出格式,广泛应用于 IPTV 机顶盒、中屏显示、视频采集等场景。

主要特性

  • ✅ HDMI 接收(HDMI 1.4 / HDMI 2.0),支持 HDCP
  • ✅ MIPI CSI-2 TX 输出(1~4 lane),用于视频采集
  • ✅ MIPI DSI TX 输出,用于驱动 MIPI 屏
  • ✅ BT1120 输出,用于连接外部视频处理器
  • ✅ 支持 RGB / YUV422 / YUV444 多种色彩空间
  • ✅ 内置 Scaler(缩放器),支持分辨率转换
  • ✅ 内置 CSC(色彩空间转换),RGB ↔ YUV 互转
  • ✅ 内置 CRU(时钟复位单元),可独立生成所需时钟
  • ✅ MIPI D-PHY TX/RX,支持双通道 MIPI
  • ✅ 支持 EDID 读取和 HDCP 密钥管理
  • ✅ CEC(Consumer Electronics Control)支持
  • ✅ I2C 控制接口,DebugFS 调试支持

芯片版本

版本 枚举值 说明
RK628D RK628D_VERSION 基础版本
RK628F RK628F_VERSION 增强版本,支持 HDMI 2.0

驱动模块划分

驱动在内核中编译为三个独立的可加载模块:

模块名 Kconfig 选项 编译产物 功能
video-rk628 CONFIG_VIDEO_RK628 video-rk628.ko 核心驱动(GRF/CRU/PHY/Scaler/DSI 等)
rk628-csi CONFIG_VIDEO_RK628_CSI rk628-csi.ko HDMI → MIPI CSI-2 桥接(V4L2 subdev)
rk628-bt1120 CONFIG_VIDEO_RK628_BT1120 rk628-bt1120.ko HDMI → BT1120 桥接(V4L2 subdev)

2. 目录结构

复制代码
drivers/media/i2c/rk628/
├── Makefile                  # 模块编译定义(3 个 ko 目标)
├── Kconfig                   # 内核配置选项
├── rk628.c                   # 核心驱动:I2C 注册、regmap、debugfs、scaler
├── rk628.h                   # 核心头文件:寄存器定义、结构体、API 声明
├── rk628_hdmirx.c            # HDMI RX 子模块:HDMI 接收、EDID、HDCP、音频
├── rk628_hdmirx.h            # HDMI RX 寄存器定义和数据结构
├── rk628_csi_v4l2.c          # CSI V4L2 子设备:HDMI→MIPI CSI-2 桥接
├── rk628_csi.h               # CSI TX 寄存器定义
├── rk628_bt1120_v4l2.c       # BT1120 V4L2 子设备:HDMI→BT1120 桥接
├── rk628_dsi.c               # MIPI DSI TX 控制器
├── rk628_dsi.h               # DSI 寄存器定义
├── rk628_mipi_dphy.c         # MIPI D-PHY 配置(HS 频率范围初始化)
├── rk628_mipi_dphy.h         # D-PHY 测试接口定义
├── rk628_cru.c               # CRU(时钟复位单元)驱动
├── rk628_cru.h               # CRU 寄存器定义(PLL/Gate/SoftRST)
├── rk628_combrxphy.c         # Combo PHY RX 驱动(接收端物理层)
├── rk628_combrxphy.h         # Combo PHY RX 寄存器定义
├── rk628_combtxphy.c         # Combo PHY TX 驱动(发送端物理层)
├── rk628_combtxphy.h         # Combo PHY TX 寄存器定义
├── rk628_post_process.c      # 后处理:CSC 色彩转换、测试图案
└── rk628_post_process.h      # 后处理接口声明

3. 架构设计

整体数据流

复制代码
┌──────────────────────────────────────────────────────────────┐
│                       RK628 芯片                              │
│                                                              │
│  ┌─────────┐    ┌──────────────┐    ┌──────────────────┐    │
│  │ HDMI RX │───▶│   GRF +      │───▶│  后处理模块       │    │
│  │ (输入)   │    │   Scaler +   │    │ (CSC / 缩放)     │    │
│  └─────────┘    │   CSC        │    └───────┬──────────┘    │
│       │         │              │            │               │
│  ┌────┴───┐     │  ┌────────┐  │    ┌───────┴──────────┐   │
│  │ComboRX │     │  │  CRU   │  │    │  输出路径选择     │   │
│  │PHY     │     │  │ (时钟)  │  │    └──┬────┬────┬────┘   │
│  └────────┘     │  └────────┘  │       │    │    │        │
│                 └──────────────┘   ┌────┴┐ ┌┴───┐ ┌┴────┐ │
│                                    │ CSI │ │DSI │ │BT   │ │
│                                    │ TX  │ │ TX │ │1120 │ │
│                                    └──┬──┘ └─┬──┘ └──┬──┘ │
│                                       │      │      │    │
│  ┌─────────────┐              ┌───────┘      │      │    │
│  │ MIPI D-PHY  │              ┌──────────────┘      │    │
│  │ TX + RX     │              │  ComboTX PHY        │    │
│  └─────────────┘              └─────────────────────┘    │
│                                                      └──┘
└──────────────────────────────────────────────────────────────┘

I2C 寄存器分区

RK628 通过 I2C 总线控制,内部寄存器空间按功能分区,驱动使用 regmap 框架统一管理:

分区 ID 名称 基地址 说明
RK628_DEV_GRF grf 0x0000xxxx 通用寄存器文件(系统控制、Scaler、LVDS、中断等)
RK628_DEV_COMBRXPHY combrxphy 0x0006xxxx Combo PHY 接收端
RK628_DEV_HDMIRX hdmirx 0x0003xxxx HDMI 接收控制器
RK628_DEV_CSI csi 0x0004xxxx MIPI CSI TX 控制器
RK628_DEV_CSI1 csi1 0x0004xxxx 第二路 MIPI CSI TX
RK628_DEV_DSI0 dsi0 0x0005xxxx MIPI DSI TX 控制器 0
RK628_DEV_DSI1 dsi1 0x0006xxxx MIPI DSI TX 控制器 1
RK628_DEV_COMBTXPHY combtxphy --- Combo PHY 发送端
RK628_DEV_ADAPTER adapter 0x000axxxx EDID / HDCP Key 存储
RK628_DEV_CRU cru --- 时钟复位单元

寄存器访问通过寄存器高字节自动路由到对应分区,无需手动切换 bank。


4. 核心模块详解

4.1 核心框架(rk628.c / rk628.h)

入口函数rk628_i2c_register(struct i2c_client *client)

负责:

  • 通过 devm_regmap_init_i2c() 为所有寄存器分区初始化 regmap 实例
  • 初始化 rst_lock 互斥锁(保护 HDMI RX 寄存器访问)
  • 创建 DebugFS 调试节点

关键 API

c 复制代码
// I2C 寄存器读写(根据寄存器地址高字节自动路由分区)
int rk628_media_i2c_write(struct rk628 *rk628, u32 reg, u32 val);
int rk628_media_i2c_read(struct rk628 *rk628, u32 reg, u32 *val);
int rk628_media_i2c_update_bits(struct rk628 *rk628, u32 reg, u32 mask, u32 val);

// 便捷封装(内联函数)
static inline int rk628_i2c_write(struct rk628 *rk628, u32 reg, u32 val);
static inline int rk628_i2c_read(struct rk628 *rk628, u32 reg, u32 *val);

核心数据结构

c 复制代码
struct rk628 {
    struct device *dev;
    struct i2c_client *client;
    struct regmap *regmap[RK628_DEV_MAX];  // 各分区 regmap 实例
    u8 version;           // RK628D / RK628F
    u8 color_format;      // 色彩格式
    u8 color_range;       // 色彩范围(full/limited)
    u8 color_space;       // 色彩空间
    int dvi_mode;         // DVI/HDMI 模式
    int vic;              // Video Identification Code
    int tx_mode;          // 发送模式(CSI/DSI/BT1120)
    bool dual_mipi;       // 双通道 MIPI
    bool hdr_support;     // HDR 支持
    struct dentry *debug_dir;
    // ... 更多字段
};

4.2 HDMI RX 子模块(rk628_hdmirx.c / rk628_hdmirx.h)

功能:接收 HDMI 信号,解析音视频数据。

子功能 说明
TMDS 解码 解析 HDMI/DVI 的 TMDS 编码信号
EDID 管理 读取/写入 EDID 数据(EDID_BASE = 0x000a0000
HDCP 支持 HDCP 密钥存储和认证(HDCP_KEY_BASE = 0x000a8000
音频提取 支持 I2S 音频输出,含 FIFO 管理和采样率检测
CEC 消费电子控制协议
热插拔检测 HPD(Hot Plug Detect)GPIO 和中断处理
HDMI 2.0 支持 SCDC(Status and Control Data Channel)

色彩格式枚举

c 复制代码
enum hdmirx_pix_fmt {
    HDMIRX_RGB888 = 0,
    HDMIRX_YUV422 = 1,
    HDMIRX_YUV444 = 2,
    HDMIRX_YUV420 = 3,
};

4.3 MIPI CSI-2 输出(rk628_csi_v4l2.c / rk628_csi.h)

功能:将 HDMI 接收的视频数据打包为 MIPI CSI-2 协议输出。

实现为 V4L2 subdev,向上对接 CIF(Camera Interface)控制器。

关键配置

寄存器 说明
CSITX_CSITX_EN CSI TX 使能,配置 lane 数、DPHY 使能
CSITX_VOP_PATH_CTRL 像素格式、数据类型、WC 用户自定义
CSITX_VOP_FILTER_CTRL VOP 滤波器控制
CSITX_SYS_CTRL2 VSYNC 使能、帧使能、非连续模式

支持的像素格式:RGB888、YUV422(多种排列)、RAW 等。

4.4 MIPI DSI 输出(rk628_dsi.c / rk628_dsi.h)

功能:通过 MIPI DSI 协议驱动 MIPI 屏幕,支持两路独立 DSI 控制器(DSI0/DSI1)。

配置项 说明
DSI_DPI_COLOR_CODING 输入色彩编码(16/18/24 bit)
DSI_VID_MODE_CFG 视频模式配置(同步脉冲/事件/突发模式)
DSI_VID_PKT_SIZE 视频包大小
DSI_CLKMGR_CFG 时钟分频配置

支持 命令模式视频模式 两种 DSI 工作模式。

4.5 BT1120 输出(rk628_bt1120_v4l2.c)

功能:将 HDMI 视频以 BT1120 并行数字接口格式输出,同样实现为 V4L2 subdev。

适用于连接外部视频处理器或 FPGA。

4.6 后处理模块(rk628_post_process.c / rk628_post_process.h)

功能

  • CSC(Color Space Conversion):RGB ↔ YUV 色彩空间转换

    c 复制代码
    void rk628_post_process_csc_en(struct rk628 *rk628,
                                    bool input_full_range, bool output_full_range);
    void rk628_post_process_csc_dis(struct rk628 *rk628);
    u8 rk628_csc_color_space_convert(u8 in_color_space, u8 format);
  • Scaler(缩放) :在 rk628.c 中实现,支持水平/垂直缩放

    • 缩放因子精度 14-bit
    • 支持缩放因子 ≤ 2 和 > 2 两种算法
    • 自动计算帧起始位置以匹配源端时序
  • 测试图案:通过 DebugFS 控制输出彩色条纹等测试图案

4.7 CRU 时钟模块(rk628_cru.c / rk628_cru.h)

功能:管理 RK628 内部 PLL 和时钟分频。

时钟 说明
CPLL 通用 PLL
GPLL 通用 PLL
APLL 音频 PLL

通过 CRU_CLKSEL_CONCRU_GATE_CONCRU_SOFTRST_CON 寄存器组控制。

4.8 MIPI D-PHY(rk628_mipi_dphy.c / rk628_mipi_dphy.h)

功能:配置 MIPI D-PHY 的 HS 频率范围参数。

c 复制代码
// 核心接口
void rk628_mipi_dphy_init_hsfreqrange(struct rk628 *rk628, int lane_mbps, uint8_t mipi_id);
int rk628_mipi_dphy_reset_assert(struct rk628 *rk628);
int rk628_mipi_dphy_reset_deassert(struct rk628 *rk628);

// D-PHY 测试接口(Test Code 读写)
u8 rk628_testif_write(struct rk628 *rk628, u8 test_code, u8 test_data, uint8_t mipi_id);
u8 rk628_testif_read(struct rk628 *rk628, u8 test_code, uint8_t mipi_id);

5. 构建与编译

内核配置

在 Kernel 6.12 的 make menuconfig 中:

复制代码
Device Drivers  --->
    Multimedia support  --->
        Media ancillary drivers  --->
            I2C Encoders, decoders, sensors and other helper chips  --->
                <M> Rockchip RK628_CSI decoder
                <M> Rockchip RK628_BT1120 decoder

或直接修改 .config

bash 复制代码
CONFIG_VIDEO_RK628=m
CONFIG_VIDEO_RK628_CSI=m
CONFIG_VIDEO_RK628_BT1120=m

编译

bash 复制代码
# 编译为模块
make M=drivers/media/i2c/rk628

# 或完整内核编译
make -j$(nproc)

编译依赖

复制代码
CONFIG_I2C=y
CONFIG_REGMAP=y
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_CEC_CORE=y
CONFIG_HDMI=y

加载模块

bash 复制代码
# 先加载核心模块
insmod video-rk628.ko

# 再加载具体输出模块(按需)
insmod rk628-csi.ko         # HDMI → MIPI CSI-2
insmod rk628-bt1120.ko      # HDMI → BT1120

6. DTS 配置

RK628 作为 I2C 设备挂载,典型 DTS 节点:

dts 复制代码
&i2c1 {
    status = "okay";

    rk628: rk628@50 {
        compatible = "rockchip,rk628";
        reg = <0x50>;
        reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
        hdmirx-det-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
        pinctrl-names = "default";
        pinctrl-0 = <&rk628_pins>;

        /* 端口定义 */
        ports {
            #address-cells = <1>;
            #size-cells = <0>;

            /* HDMI RX 输入端口(可选,连接 HDMI 连接器) */
            port@0 {
                reg = <0>;
                rk628_hdmirx_in: endpoint {
                    remote-endpoint = <&hdmi_con_in>;
                };
            };

            /* CSI TX 输出端口 → CIF/ISP */
            port@1 {
                reg = <1>;
                rk628_csi_out: endpoint {
                    remote-endpoint = <&cif_in>;
                    data-lanes = <1 2 3 4>;
                    clock-lanes = <0>;
                };
            };
        };
    };
};

GRF 系统控制寄存器配置(通常在 SoC GRF 中配置):

c 复制代码
// 输入模式选择
SW_INPUT_MODE(HDMI / BT1120 / RGB / YUV)

// 输出模式选择
SW_OUTPUT_MODE(GVI / LVDS / HDMI / CSI / DSI / BT1120 / RGB / YUV)

7. 调试指南

DebugFS 接口

驱动注册了丰富的 DebugFS 节点,路径为 /sys/kernel/debug/rk628/<device>/

复制代码
/sys/kernel/debug/rk628/<device>/
├── debug                    # 调试开关(写入 1 开启详细日志)
└── registers/               # 寄存器读写节点
    ├── grf                  # GRF 寄存器
    ├── cru                  # CRU 寄存器
    ├── combrxphy            # Combo RX PHY 寄存器
    ├── combtxphy            # Combo TX PHY 寄存器
    ├── hdmirx               # HDMI RX 寄存器
    ├── dsi0                 # DSI0 寄存器
    ├── dsi1                 # DSI1 寄存器
    └── csi                  # CSI 寄存器

读取寄存器

bash 复制代码
cat /sys/kernel/debug/rk628/<device>/registers/grf

写入寄存器

bash 复制代码
echo "0x0010 0x00000005" > /sys/kernel/debug/rk628/<device>/registers/grf
# 格式: addr(十六进制) val(十六进制)

开启调试日志

bash 复制代码
echo 1 > /sys/kernel/debug/rk628/<device>/debug
# 查看内核日志
cat /proc/kmsg | grep rk628

内核模块参数

bash 复制代码
# CSI 模块调试级别(0-3)
insmod rk628-csi.ko debug=3

# BT1120 模块调试级别
insmod rk628-bt1120.ko debug=3

常用调试方法

方法 命令/说明
查看模块加载 `lsmod
查看 I2C 设备 i2cdetect -y <bus>
查看 V4L2 设备 v4l2-ctl --list-devices
查看支持的时序 v4l2-ctl -d /dev/video0 --list-dv-timings
寄存器 dump DebugFS registers/ 节点
测试图案输出 echo 1 > /sys/kernel/debug/rk628/<dev>/pattern

8. 常见问题 FAQ

Q: insmod video-rk628.ko 后无反应?

A: 检查 DTS 中 I2C 地址是否匹配(默认 0x50),使用 i2cdetect 确认设备在总线上可见。

Q: HDMI 接入后无画面输出?

A: 1) 检查 HPD GPIO 是否正确配置;2) 检查 GRF 的 SW_INPUT_MODESW_OUTPUT_MODE 是否匹配;3) 开启 debug 日志查看 HDMI RX 状态。

Q: CSI 输出花屏或色彩异常?

A: 1) 确认 CSI lane 数配置正确;2) 检查 CSITX_VOP_PATH_CTRL 的像素格式是否与实际色彩格式一致;3) 检查 CSC 是否正确启用。

Q: 缩放后画面撕裂?

A: Scaler 的帧起始计算依赖精确的源端/目标端 pixelclock,确认两端 videomode 参数配置正确。查看 dsp_frame_vstdsp_frame_hst 的调试日志。

Q: 如何确认芯片版本?

A: 驱动启动时调用 rk628_version_parse() 读取 GRF_SOC_VERSION 寄存器,版本信息会打印在内核日志中。

Q: 双通道 MIPI 如何配置?

A: 设置 dual_mipi = true,并确保 DSI0 和 DSI1 均已配置,GRF 中启用 GRF_DPHY_CH1_EN


9. 版本与作者

项目 信息
芯片 Rockchip RK628
内核版本 Linux 6.12
许可证 GPL-2.0
相关推荐
代码AC不AC2 小时前
【Linux】命名管道
linux·命名管道
陌上花开缓缓归以2 小时前
linux boot 烧写纪要以及内存相关分析
linux·服务器·网络
yy_xzz2 小时前
【Linux开发】 04 Linux UDP 网络编程
linux·网络·udp
123过去2 小时前
mdb-sql使用教程
linux·网络·数据库·sql
hweiyu002 小时前
Linux命令:pgrep
linux·运维·服务器
文人sec3 小时前
【Linux 服务器上搭建 JMeter 性能测试与监控环境(实战版)】
linux·运维·服务器·jmeter·性能测试
papaofdoudou3 小时前
Linux内核的边界在哪里?
linux·运维·服务器
zzzsde3 小时前
【Linux】文件:基础IO
linux·运维·服务器
Yupureki3 小时前
《Linux系统编程》15.进程间通信-管道
linux·运维·服务器·c语言·c++