4. ARM平台I2C控制器概述:常见SoC特性对比

在嵌入式ARM Linux系统中,I2C控制器作为芯片内部的一个I2C总线主机(Master)外设,负责在硬件层面实现I2C协议的时序、仲裁、中断和DMA传输。不同厂商的ARM SoC(如STM32MP1、i.MX6、RK3399)在I2C控制器的寄存器模型、时钟管理、中断机制和DMA支持上存在显著差异,这些差异直接影响设备树绑定和驱动适配策略。

核心认知: 设备树中的I2C节点本质上是描述控制器硬件特性的“寄存器地图”和“资源清单”。理解控制器差异,是正确编写和调试设备树的前提。

4.1 三大主流SoC I2C控制器特性总览

下表从IP核来源、位宽、时钟、中断、DMA、地址模式、传输速率等关键维度,对比STM32MP1、i.MX6和RK3399的I2C控制器。

特性维度 STM32MP1 (I2C) i.MX6 (I2C) RK3399 (I2C)
IP核来源 ST 自研 (I2Cv2) NXP (飞思卡尔) VF610 Rockchip 自研 (APB)
寄存器位宽 32-bit 8-bit (部分32-bit对齐) 32-bit
时钟源 PCLK (APB总线时钟) IPG_CLK (外设时钟) PCLK (APB总线时钟)
中断类型 单中断线 (事件+错误合并) 单中断线 单中断线
DMA支持 支持 (TX/RX独立DMA请求) 支持 (需外置DMA引擎) 支持 (内置DMA控制器)
地址模式 7-bit / 10-bit 7-bit / 10-bit 7-bit / 10-bit
最大传输速率 Fast-mode Plus (1 Mbps) Fast-mode (400 Kbps) Fast-mode (400 Kbps)
从机模式 支持 (多主模式) 支持 (从机模式) 支持 (从机模式)
总线仲裁 硬件自动仲裁 硬件自动仲裁 硬件自动仲裁
电源管理 支持时钟门控 支持时钟门控 支持时钟门控 + 唤醒
关键差异点: STM32MP1的I2C控制器支持Fast-mode Plus(1Mbps),适合高速传感器;i.MX6的寄存器为8位宽,在设备树中需要特别注意地址对齐;RK3399的I2C控制器内置了DMA请求逻辑,在设备树中需要额外配置dmas属性。

4.2 控制器内部架构对比

下图展示了三种SoC I2C控制器的内部模块架构差异,重点突出时钟域、数据路径和中断/DMA请求路径。

三种ARM SoC I2C控制器内部架构对比 STM32MP1 I2Cv2 APB 总线接口 (32-bit 寄存器) 时钟发生器 (PCLK) 支持 Fast-mode+ 数据路径 (TX/RX FIFO) 8字节深度 中断控制器 事件+错误合并中断 DMA 请求接口 TX/RX 独立请求 SDA/SCL 引脚控制 GPIO 复用 i.MX6 VF610 I2C IPG 总线接口 (8-bit 寄存器) 时钟发生器 (IPG_CLK) Fast-mode 400Kbps 数据路径 (TX/RX 移位) 无硬件 FIFO 中断控制器 单中断线 DMA 请求接口 需外部 DMA 引擎 SDA/SCL 引脚控制 IOMUX 配置 RK3399 Rockchip I2C APB 总线接口 (32-bit 寄存器) 时钟发生器 (PCLK) Fast-mode 400Kbps 数据路径 (TX/RX FIFO) 16字节深度 中断控制器 单中断线 DMA 请求接口 内置 DMA 控制器 SDA/SCL 引脚控制 GRF 寄存器配置
架构差异解读: STM32MP1和RK3399都具备硬件FIFO,能有效减少中断频率,适合高吞吐量场景;i.MX6的VF610 I2C没有FIFO,每次传输都需要CPU逐字节干预,在设备树中需要配置更小的传输超时。RK3399的DMA请求直接连接到内部DMA控制器,延迟更低。

4.3 时钟树与速率计算差异

I2C控制器的时钟源和分频逻辑直接影响总线速率。三种SoC的时钟树结构不同,设备树中clock-frequency属性的实际效果也不同。

4.3.1 时钟路径对比

SoC 时钟源 分频方式 设备树时钟属性
STM32MP1 PCLK (APB) → 预分频器 → 时序寄存器 通过 TIMINGR 寄存器配置 SCL 高低电平时间 clock-frequency + st,i2c-timing
i.MX6 IPG_CLK → IFDR 分频寄存器 6位分频因子 (0x00~0x3F) clock-frequency (驱动自动计算 IFDR)
RK3399 PCLK → CLKDIV 寄存器 8位分频因子 (0x00~0xFF) clock-frequency + rockchip,clk-div
常见陷阱: 在STM32MP1上,仅设置clock-frequency而不配置st,i2c-timing可能导致时序违规,因为驱动需要精确的时序参数来计算SCL高低电平。i.MX6的IFDR分频值不是线性映射,驱动中有一个查找表,设备树中不要手动设置IFDR值。

4.3.2 速率计算示例

以100Kbps标准模式为例,三种SoC的时钟配置差异:

// STM32MP1: 需要计算 TIMINGR 寄存器值
// PCLK = 54 MHz, 目标 100Kbps
// 驱动通过 st,i2c-timing 属性传入预计算值
i2c2: i2c@40012000 {
    compatible = "st,stm32mp15-i2c";
    clock-frequency = <100000>;
    st,i2c-timing = <0x00303D5B>;  // 预计算时序
};

// i.MX6: 驱动自动选择 IFDR 分频因子
i2c1: i2c@21a0000 {
    compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
    clock-frequency = <100000>;  // 驱动自动匹配 IFDR
};

// RK3399: 需要配置 CLKDIV
i2c0: i2c@ff3c0000 {
    compatible = "rockchip,rk3399-i2c";
    clock-frequency = <100000>;
    rockchip,clk-div = <0x42>;  // 手动或自动计算
};

4.4 中断与DMA机制差异

中断和DMA是I2C控制器实现非阻塞传输的关键。下表对比三种SoC的中断事件和DMA请求线。

SoC 中断事件 DMA请求线数 设备树中断属性
STM32MP1 TXIS, RXNE, TC, NACKF, STOPF, ARLO, BERR, OVR 2 (TX + RX) interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>
i.MX6 IIC_IF (传输完成/错误) 1 (共享) interrupts = <0 54 IRQ_TYPE_LEVEL_HIGH>
RK3399 MSTX_FIFO_EMPTY, MSRX_FIFO_FULL, ARBITRATION_LOST, NAK 2 (TX + RX) interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>
调试建议: 在STM32MP1上,如果遇到NACK中断,需要检查st,i2c-timing是否匹配实际PCLK频率。i.MX6的IIC_IF中断是边沿触发还是电平触发取决于芯片版本,设备树中建议使用IRQ_TYPE_LEVEL_HIGH以保证兼容性。

4.5 设备树绑定差异总结

下表汇总了三种SoC在设备树中描述I2C控制器时的关键属性差异,是编写和移植设备树时的快速参考。

设备树属性 STM32MP1 i.MX6 RK3399
compatible st,stm32mp15-i2c fsl,imx6q-i2c rockchip,rk3399-i2c
reg 寄存器基址 + 大小 (0x400) 寄存器基址 + 大小 (0x4000) 寄存器基址 + 大小 (0x1000)
clocks 1个 (PCLK) 1个 (IPG_CLK) 1个 (PCLK)
dmas 2个 (tx, rx) 可选 (需外部DMA) 2个 (tx, rx)
pinctrl 必须配置 必须配置 必须配置
wakeup-source 支持 不支持 支持
移植要点: 当从i.MX6向RK3399移植I2C设备时,需要特别注意dmas属性的添加,因为RK3399的I2C控制器默认使用DMA传输,而i.MX6的I2C控制器在设备树中通常不配置DMA。同时,pinctrl的引脚配置需要根据SoC的GPIO复用表重新定义。

4.6 本章小结

  • STM32MP1:I2Cv2控制器,32位寄存器,支持Fast-mode+,需要精确的时序配置(st,i2c-timing),适合高速传感器场景。
  • i.MX6:VF610 I2C控制器,8位寄存器,无硬件FIFO,时钟分频通过IFDR查找表实现,设备树配置相对简单。
  • RK3399:Rockchip自研I2C控制器,32位寄存器,16字节FIFO,内置DMA控制器,设备树需要配置dmas和rockchip,clk-div。
  • 共性:三者都支持7/10位地址、多主模式、硬件仲裁,设备树中都需要配置compatible、reg、interrupts、clocks和pinctrl。