3. FRL链路速率与通道

HDMI 2.1 FRL 引入了 5 种链路速率,通道也能灵活配。这和 TMDS 时代完全不同——以前就一种速率跑到底,现在你得根据场景自己选。

我记得刚开始做 HDMI 2.1 项目时,看到这么多速率选项确实有点懵。后来调了几个板子,发现其实就几个固定搭配,摸清规律就好办了。

3.1 五种速率与三种通道

FRL 支持 3、6、8、10、12 Gbps 这五种速率。通道数支持 1、2、4 三种配置。注意,没有 3 通道,这点和 DP 不太一样。

每个速率都能配 1、2 或 4 条通道。但不同搭配下,总带宽差很多。你想想看,同样是 4 条通道,3Gbps 只能跑 12Gbps,12Gbps 却能跑到 48Gbps,差了四倍。

速率 (Gbps) 支持通道数 最大总带宽 (Gbps) 典型应用场景
3 1, 2, 4 12 1080p@240Hz, 4K@30Hz
6 1, 2, 4 24 4K@60Hz, 5K@30Hz
8 1, 2, 4 32 4K@120Hz, 8K@30Hz
10 1, 2, 4 40 8K@30Hz, 4K@144Hz
12 1, 2, 4 48 8K@60Hz, 10K@30Hz

我个人习惯这样记:3 和 6 是"基础档",8 和 10 是"性能档",12 是"旗舰档"。项目选型时心里先划个档,再细配通道数。

3.2 速率与通道的搭配逻辑

选速率不是拍脑袋决定的。源端和显示端得先互相"握手",看看对方能跑多快。这个握手过程叫 LTTP (Link Training and Timing Protocol),后面会细讲。

搭配的核心原则就一条:用最少的通道数,跑够目标带宽。为什么?通道数越少,功耗越低,信号完整性也越容易保证。

带宽计算公式:

总带宽 = 速率 × 通道数 × (16/18)

那个 16/18 是 FRL 的编码效率(16b/18b 编码),去掉 2bit 开销才是实际有效数据。

举个例子。4K@120Hz 需要约 32Gbps 有效带宽。

  • 用 8Gbps × 4 通道 = 28.4Gbps(不够,得升速率)
  • 用 10Gbps × 4 通道 = 35.6Gbps(够用,还留余量)
  • 用 12Gbps × 3 通道?不行,FRL 没有 3 通道模式。

所以实际项目中 4K120 基本都用 10Gbps × 4 或者 12Gbps × 4。

FRL 链路速率与通道训练流程 源端发起LTTP 读取显示端FRL能力 选择FRL速率 3G 6G 8G 10G 12G 配置FRL通道数 1 Lane 2 Lanes 4 Lanes 执行FRL链路训练 训练成功? 稳定传输 降级重试 是 否 说明 源端与显示端共同协商 速率和通道组合

这个流程图展示了 FRL 训练的核心路径。源端先发起 LTTP,拿到显示端的能力信息,然后选速率、配通道,最后执行训练。训练不成功就降级重试。

3.3 实战中的选择策略

说实话,大部分消费电子产品不会把所有速率都开放。我见过很多设计为了兼容性,直接固定用 12Gbps × 4 通道。这种做法省事,但功耗和成本都偏高。

真正讲究的做法是根据目标分辨率动态切换。我在项目中用过一套策略,分享给你参考:

  • 1080p 及以下:3Gbps × 1 通道就够,省电第一。
  • 4K@60:6Gbps × 4 通道,或者 8Gbps × 2 通道。后者的信号质量更好,因为通道数少,串扰小。
  • 4K@120:10Gbps × 4 通道是甜点区,12Gbps 虽然也行但发热明显。
  • 8K@60:12Gbps × 4 通道,没得选。线缆质量必须过硬,否则训练很难通过。

小技巧:调试时先用低速率验证通道连通性,再逐步提速率。这样可以快速定位瓶颈是出在线缆还是出在芯片。

3.4 训练流程中的速率协商

速率协商不是一次完成的。LTTP 过程中,源端会先发一个"探测包",显示端回应自己能支持的速率列表。源端从高到低逐个尝试,直到找到一个双方都支持的速率。

通道数的协商也类似。但通道数一般先配 4 条,如果训练失败,再降为 2 条或 1 条。

注意:降通道数是为了应急,不能作为常规方案。比如 12Gbps × 1 通道只能跑 12Gbps,连 4K60 都跑不满,只能点亮屏幕。

下面是一个简化版的速率协商代码示例,我在调试工具里经常这么写:

# 伪代码:FRL速率协商流程
def frl_ltpp_negotiate(source, sink):
    # 1. 读取显示端能力
    caps = sink.read_frl_caps()
    # caps.rates: 支持速率列表 [3, 6, 8, 10, 12]
    # caps.lanes: 支持通道数 [1, 2, 4]
    
    # 2. 从高到低尝试速率
    for rate in sorted(caps.rates, reverse=True):
        # 3. 从多到少尝试通道数
        for lanes in sorted(caps.lanes, reverse=True):
            if try_link(source, sink, rate, lanes):
                # 训练成功,锁定配置
                return (rate, lanes)
            # 训练失败,尝试下一种组合
    # 所有组合都失败,报错
    raise FRLTrainingError("无法建立FRL链路")

实际项目里,这个循环不会写得这么简单。每次尝试都要做完整的时钟恢复和符号锁定检测,超时时间一般控制在 10ms 以内。

3.5 避坑指南

做 FRL 调试这几年,我踩过不少坑。挑几个典型的说说:

坑一:速率和通道数不匹配,EDID 里没写清楚。

我曾经遇到一个显示器,EDID 里声称支持 8K@60,但实际 FRL 能力只开到 10Gbps × 2 通道。结果源端按 12Gbps × 4 去训练,反复失败。查了两天才发现是 EDID 的 FRL 块写错了。

坑二:降级策略没做超时保护。

如果训练失败立刻降级,没有等待时间,源端和显示端会陷入"死循环"——失败-降级-重试-再失败-再降级。我建议每次降级后至少等 50ms 再发起下一次训练,给链路一个稳定窗口。

一个实在的建议:量产前把 5 种速率 × 3 种通道组合全部遍历测试一遍。虽然耗时,但能筛出很多边缘情况。我们在实验室跑过一轮完整的组合测试,抓出来 7 个隐蔽的兼容性问题。

嗯,最后还是那句话——速率和通道是 FRL 链路的基础