4. FRL链路训练状态机与协议交互流程
FRL训练,说白了就是TX和RX在正式传数据前先“对表”。
我刚开始接触HDMI 2.1时,觉得这步就是走个过场,直到在项目里遇到某颗芯片死活不进FRL模式……嗯,从那以后,我把FRL状态机默写了好几十遍。
4.1 状态机全景:一条必走的路
整个FRL训练由一组严格的状态构成,任何一步跳错,HDMI认证都过不了。我个人习惯把状态机拆成三大阶段:
- 握手与SCR —— 确认双方都支持FRL,并校准参考时钟。
- 通道均衡 —— 调整TX幅度与RX均衡器,让4条lane上的眼图张开。
- 锁定时钟与数据 —— 对齐lane间skew,进入正常运行。
记住:FRL状态机是 双向驱动 的——TX和RX各自管理自己的状态,但又通过SCDC寄存器来同步。
4.2 状态机详解:每个状态里的门道
4.2.1 TrainRequest —— 先打招呼
TX向RX发送一个“我想切FRL”的信号。怎么发?通过SCDC的FRL_Start位握手。
我记得第一次调FRL时,发现RX一直不回复FRL_Start=1,后来用逻辑分析仪抓SCDC I²C,才发现是RX的EDID里没声明支持FRL……你说搞笑不?
- TX动作:置位SCDC地址0x30 bit0 (FRL_Start=1),开始发送FRL Training Pattern。
- RX动作:检测到FRL_Start后,将SCDC的
FRL_Start=1写回(表示确认),同时进入TrainCR状态。
曾经踩过的坑: 某些HDMI 2.1 RX芯片需要等50ms才应答FRL_Start。如果你的TX等不及就超时重试,会陷入无限循环。我的建议是:把超时设到100ms以上。
4.2.2 TrainCR —— 对表对频率
TX发送CR(Clock Reference)pattern,本质是一个固定频率的方波。RX用来恢复出参考时钟,并把内部PLL锁定到FRL lane rate。
这个阶段最容易出问题的是 扩频时钟(SSC)。HDMI 2.1允许±0.5%的扩频,有些RX的PLL带宽不够会被晃掉。我个人习惯在测试时分别关/开SSC跑一次,确保都稳定。
4.2.3 TrainEQ —— 均衡大考
TX发出EQ pattern(PRBS7伪随机序列),RX通过眼图监测自动调整CTLE和DFE系数。FRL要求每条lane独立均衡,最终要达到BER<1e-9。
你想想看,4条lane,每根线的焊接质量、PCB走线长度不同,均衡值必然不一样。所以协议允许RX在读Training_LANEx_CTLE寄存器时动态反馈给TX。
| 寄存器 | 作用 | 读写 |
|---|---|---|
| 0x31 (Training_LANE0_CTLE) | Lane0均衡系数(0~63) | RX→TX读 |
| 0x32 (Training_LANE1_CTLE) | Lane1均衡系数 | RX→TX读 |
| 0x33 | Lane2 | 读取 |
| 0x34 | Lane3 | 读取 |
| 0x35 (FRL_CTL) | 控制FRL开始/重置 | TX写, RX读 |
4.2.4 TrainPostEQ —— 临门一脚
RX在TrainEQ完成后会进入PostEQ,此时TX切换为另一种pattern(FRL PostEQ Pattern),进一步优化skew对齐。这阶段RX会测量lane间延迟差异,并补偿到低于1个UI(单位间隔)。
Training_LANEx_OFFSET寄存器记录了每根lane的skew值,如果你做多芯片兼容性测试,会发现不同厂家的RX对skew容忍度差别很大。
4.2.5 Success / Fail
当RX锁定了所有4条lane的同步,它将SCDC的FRL_Ready位置1。TX读到后就知道训练成功,可以开始发TMDS或FRL data了。
如果超时(通常是1~2秒)还没收到FRL_Ready,TX应回到TrainRequest重试。记得我在某个项目中,RX固件bug导致PostEQ阶段卡死,最后通过强制reset SCDC才恢复。经验教训:训练失败后要把SCDC全清(写入0x30=0,延时50ms再置1)。
4.3 协议交互流程:谁先动,谁回应
整个训练时序严格依赖SCDC的I²C读写。以下是标准流程,我用表格列出来方便你对照:
| 步骤 | TX动作 | RX动作 | 超时/异常 |
|---|---|---|---|
| 1 | 读EDID,确认RX支持FRL | 返回EDID FRL字段 | 不支持则留在TMDS |
| 2 | 写0x30=1,开始发送CR pattern | 检测FRL_Start,写0x30=1回应 | TX轮询等待,超时10ms重试 |
| 3 | 发送EQ pattern,持续至少2ms | 均衡训练,写CTLE寄存器 | TX读CTLE若为0则继续等待 |
| 4 | 切换到PostEQ pattern | 锁lane同步,准备FRL_Ready | 最多等待100ms |
| 5 | 轮询0x40 bit0 (FRL_Ready) | 准备好后置1 | 超时回到第一步 |
| 6 | 开始传输FRL数据 | 正常接收 | — |
调试图省心小窍门: 用HDMI分析仪抓SCDC总线,同时观察TX和RX各自的状态寄存器。我习惯在源码里加个调试打印,每次SMC(状态机改变)都输出当前step count,这样能一眼看出卡在哪个阶段。
4.4 跨芯片适配的“潜规则”
不同厂商的FRL实现差距主要在三点——
- TrainEQ时长:某品牌IP要求至少5ms的EQ pattern,另一家却说2ms够用。兼容性测试时建议取最大值。
- CTLE反馈粒度:有的RX用6bit,有的只支持4bit范围,TX读到了0x3F但RX实际只看到0x0F,你想想看会怎样?均衡直接崩。
- PostEQ的skew补偿:某款国内RX芯片只能容忍±3UI的lane skew,而国际大厂可以做到±5UI。如果你的PCB走线不等长,可能在这颗上失败。
所以,做FRL兼容性测试时,我强烈建议拿着三颗不同供应商的RX芯片,用同一块TX板子反复跑训练,把SCDC日志全抓下来比对。哪颗失败了,就把对应寄存器值写死在TX固件里做个workaround。
4.5 小结
FRL训练状态机不是死板的模板,它是TX和RX通过SCDC细粒度交互的过程。你调试时记住一个原则:RX永远是主导,它说“准备好了”TX才能动。