4、MIPI CSI-2接口配置:D-PHY参数配置、Lane映射与极性、时钟连续与非连续模式

好,咱们接着往下聊。上一节我们把CSI主控的顶层配置搞定了,这一节要深入到底层物理层——D-PHY。说白了,MIPI CSI-2的物理层就是D-PHY,它负责把摄像头传过来的高速串行数据,转成控制器能理解的并行数据。

我个人觉得,D-PHY配置是整个Camera驱动里最容易踩坑的地方。为什么?因为它是模拟电路,参数稍微偏一点,图像就可能出现条纹、花屏,甚至完全没信号。我刚开始做驱动时,就因为这个折腾了整整三天。

4.1 D-PHY参数配置

D-PHY的核心参数,说白了就两个:一个是速率,一个是时序。速率决定了摄像头能跑多快,时序决定了信号能不能稳定锁住。

先看速率。每个Lane的数据速率,由phy-clock-frequency这个属性决定。单位是Hz。比如你的摄像头输出1080P@30fps,用4个Lane,每个Lane的速率大概在400Mbps左右。那这个属性就设成400000000。

/* 设备树中D-PHY速率配置示例 */
&csi_phy {
    phy-clock-frequency = <400000000>;  /* 每个Lane 400Mbps */
    status = "okay";
};

嗯,这里要注意:这个速率不是随便写的。你得根据摄像头的规格书和实际的像素时钟算出来。我见过有人直接抄别的项目的参数,结果图像全是噪点。后来一查,速率差了50MHz。

再来看时序。D-PHY的时序参数包括:

参数名 说明 典型值
hs-clk-prepare 时钟进入高速模式前的准备时间 40ns ~ 85ns
hs-clk-zero 时钟进入高速模式后的稳定时间 145ns ~ 300ns
hs-prepare 数据进入高速模式前的准备时间 40ns ~ 85ns
hs-zero 数据进入高速模式后的稳定时间 105ns ~ 220ns
hs-trail 高速模式结束后的拖尾时间 60ns ~ 105ns

这些时序参数,不同的SoC厂商封装方式不一样。有的直接写在设备树里,有的在驱动里写死。我个人习惯是:如果SoC的参考手册里有时序计算公式,就按公式算;如果没有,就用摄像头模组厂商提供的参考值。

关键点:时序参数的单位是纳秒(ns),但设备树里通常用时钟周期数来表示。你需要把纳秒转换成时钟周期。公式很简单:周期数 = 时间(ns) × 时钟频率(GHz)。比如400MHz时钟,1ns就是0.4个周期。

4.2 Lane映射与极性

这个知识点,说白了就是:PCB上怎么走线,软件里就得怎么配。你想想看,摄像头模组出来的4个数据Lane,在PCB上可能因为走线方便,把Lane0和Lane3交换了位置。这时候软件不跟着换,信号就乱了。

Lane映射在设备树里通常用data-lanes属性来表示。它是一个数组,数组的索引是物理Lane号,值是对应的逻辑Lane号。

/* Lane映射示例:物理Lane0对应逻辑Lane2 */
&csi_phy {
    data-lanes = <2 1 0 3>;
    /* 解释:物理Lane0 -> 逻辑Lane2
             物理Lane1 -> 逻辑Lane1
             物理Lane2 -> 逻辑Lane0
             物理Lane3 -> 逻辑Lane3 */
};

我曾经在一个项目里遇到过:图像能出来,但颜色不对。排查了三天,最后发现是Lane映射配错了。物理Lane0和Lane2交换了,导致数据字节顺序全乱了。从那以后,我每次配Lane映射都会拿示波器先量一下,确认物理连接顺序。

再说极性。D-PHY的差分信号有正负两根线:DP和DN。如果PCB上不小心把这两根线接反了,就需要在软件里翻转极性。设备树里用lane-polarities属性,0表示不翻转,1表示翻转。

/* 极性配置示例:时钟Lane翻转,数据Lane不翻转 */
&csi_phy {
    lane-polarities = <1 0 0 0 0>;
    /* 第一个值是时钟Lane,后面依次是数据Lane0~3 */
};

警告:极性翻转不是万能的。如果PCB上DP和DN接反了,虽然软件能翻转,但信号质量会下降。我建议:能改板子就别靠软件。实在改不了板子,再考虑软件翻转。

4.3 时钟连续与非连续模式

这个知识点,很多初学者容易忽略。MIPI D-PHY的时钟有两种工作模式:连续模式和非连续模式。

连续模式:时钟Lane一直有信号,不管有没有数据传输。优点是接收端容易锁定时钟,缺点是功耗高。

非连续模式:只有传输数据时,时钟Lane才工作。平时时钟Lane处于低功耗状态。优点是省电,缺点是需要额外的时钟恢复时间。

设备树里怎么配?通常用clock-continuous这个属性。如果设成<1>,就是连续模式;设成<0>或者不设,就是非连续模式。

/* 连续模式配置 */
&csi_phy {
    clock-continuous = <1>;  /* 时钟一直跑 */
};

/* 非连续模式配置(默认) */
&csi_phy {
    /* 不设这个属性,或者设成0 */
    clock-continuous = <0>;
};

我个人建议:调试阶段用连续模式。为什么?因为连续模式下时钟一直有,示波器好抓信号,逻辑分析仪也好触发。等调试通过了,再改成非连续模式省电。

小技巧:如果你发现摄像头偶尔能出图,偶尔出不来,而且出不来的时候报"PHY timeout"错误,多半是时钟模式的问题。试试改成连续模式,如果问题消失,那就是非连续模式下的时钟恢复时间没配够。

嗯,这里还要提一句:非连续模式下,每次从低功耗切换到高速模式,都需要重新锁定时钟。这个锁定时间由hs-clk-preparehs-clk-zero这两个参数决定。如果配得太短,时钟还没稳定就开始传数据,那数据肯定错。

我记得有一次,客户反馈摄像头在低帧率下工作正常,高帧率下就花屏。我一看,他们用的是非连续模式,而且时序参数是按低帧率调的。高帧率下切换频率变高,时钟恢复时间不够,就出问题了。后来把时序参数放宽,问题解决。

最后总结一下D-PHY配置的几个要点:

  • 速率要准:根据摄像头规格书和实际像素时钟计算,别瞎抄
  • 时序要够:宁长勿短,特别是非连续模式下
  • 映射要对:物理连接和软件配置必须一致,拿示波器确认
  • 极性慎用:能改板子就别靠软件翻转
  • 模式选好:调试用连续,量产用非连续

下一节,我们会聊到CSI-2协议层的数据格式配置,包括数据类型、虚拟通道、包长度这些。到时候你会发现,D-PHY这层配好了,协议层反而简单很多。