HDMI DDC 从机地址与交互流程
HDMI 的 DDC(Display Data Channel)基于 I2C:源端(Source/TX)作为主机,显示设备或中继器作为从机。除 EDID 外,同一组 SCL/SDA 还承载 HDCP、SCDC,以及部分显示器支持的 DDC/CI。
本文按从机地址总览 → EDID → HDCP → SCDC → DDC/CI 的顺序整理,便于抓包、固件调试和 IP 集成时快速对照。不同版本规范与芯片 IP 可能存在能力差异,实现时仍应以目标规范版本和器件文档为准。
一、DDC 从机地址汇总
DDC 相关地址存在两种常见写法:8 位帧地址(含 R/W 位,如 0xA0)与 7 位从机地址(Linux 驱动、i2cdetect 常用,如 0x50)。下表同时给出两种表示。
| 功能 | 7 位地址 | 8 位写 / 读 | 访问特性 | 适用标准 / 说明 |
|---|---|---|---|---|
| E-EDID | 0x50 | 0xA0 / 0xA1 | 源端只读 | E-DDC;块 0 起每 128 字节为一 EDID 块 |
| E-DDC 段指针 | 0x30 | 0x60 / — | 只写段号 | 访问 256 字节以上的 EDID 空间 |
| HDCP | 0x3A | 0x74 / 0x75 | 读写 | HDCP 1.4 与 HDCP 2.x 共用地址,寄存器映射不同 |
| SCDC | 0x54 | 0xA8 / 0xA9 | 双向 | HDMI 2.0+;2.1 FRL 训练扩展同一地址空间 |
| DDC/CI | 0x37 | 0x6E / 0x6F | 双向 | 可选的 VESA 显示器控制通道 |
使用注意:
- 访问 EDID、SCDC 或 HDCP 前,通常需要 HPD 有效,且 DDC 上拉供电正常。
- HDCP 1.4 与 HDCP 2.x 的寄存器布局不同;若要使用 HDCP 2.x,应先检查
HDCP2Version的支持位。 - SCDC 仅在 Sink EDID 的 HF-VSDB 中
SCDC_Present = 1时方可访问;FRL 能力另由Max_FRL_Rate等字段声明。 - DDC/CI 是可选功能,显示器可能不支持、默认关闭,或不通过中继器转发。
二、EDID 读取
2.1 数据结构与容量
- 每个 EDID 块 固定 128 字节。
- 块 0 字节 126 为扩展块数量
N,总长度为(N + 1) × 128字节。不要假定N ≤ 3;读取上限应由实现能力和数据有效性共同决定。 - 块 0 字节 127、各扩展块字节 127 为 128 字节累加和校验(模 256 为 0)。
- 块 0 头 8 字节固定为:
00 FF FF FF FF FF FF 00。
HD 相关扩展块常见类型:
| 扩展块类型 | Tag(字节 0) | 作用 |
|---|---|---|
| CEA-861 扩展 | 0x02 | 音视频格式、HDMI VSDB、HDR 等 |
| HF-VSDB | 位于 CEA 块内 | SCDC_Present、Max_FRL_Rate、ALLM/VRR 等 2.0/2.1 能力 |
2.2 基本读流程(≤256 字节)
- I2C 写 从机
0x50,发送起始偏移0x00(设置片内地址指针)。 - I2C 读 从机
0x50,读取 128 字节块。 - 根据块 0 的扩展块数量继续读取,并逐块校验 checksum。
2.3 E-DDC 扩展读(>256 字节)
当 N ≥ 2(总长度 ≥ 384 字节)时,使用 段指针:
对于块号 B,段号为 B / 2(向下取整),段内偏移为偶数块 0x00、奇数块 0x80:
- 向
0x30写入段号(每段覆盖 256 字节,即两个 EDID 块)。 - 向
0x50写入段内偏移0x00或0x80。 - 从
0x50读取 128 字节。 - 重复以上步骤,直至读完所需扩展块。
段指针是独立状态,不能假定它会在 STOP 后自动回到 0。读取基础段前也应确保段号正确。
2.4 调试要点
- 热插拔后应等待 HPD 稳定再读;部分 Sink 在 HPD 上升沿后需数毫秒才能响应 DDC。
- EDID 与 SCDC 分离:EDID 对源端只读;不能通过
0x50改写 SCDC 寄存器。 - 可配合本站 EDID 解析工具 与 linuxhw EDID 数据 对照字段含义。
三、HDCP 交互与关键寄存器
HDCP 端口固定为 0x3A(8 位 0x74/0x75)。HDCP 1.4 与 HDCP 2.2/2.3 共用物理地址,HDCP 2.2 接收端通过 HDCP2Version(偏移 0x50)bit2 声明支持能力;认证版本还需结合 Source、Sink 与内容保护策略选择。
3.1 HDCP 1.4(DDC 寄存器映射)
认证由 Transmitter(源) 发起,典型三阶段:交换 KSV → 计算 Ri/Ri' → 启用加密。
| 偏移 | 名称 | 方向 | 长度 | 说明 |
|---|---|---|---|---|
0x00 | Bksv | R | 5 B | 接收端 Key Selection Vector |
0x08 | Ri' | R | 2 B | 链路完整性校验值 |
0x0A | Pj' | R | 1 B | 增强链路校验值 |
0x10 | Aksv | W | 5 B | 发送端 KSV |
0x18 | An | W | 8 B | 会话随机数 |
0x20 | V' | R | 20 B | Repeater 拓扑验证值 |
0x40 | Bcaps | R | 1 B | 接收端能力与 Repeater 标志 |
0x41 | Bstatus | R | 2 B | Repeater 拓扑状态 |
0x43 | KSV FIFO | R | 可变 | Repeater 下游 KSV 列表 |
交互要点:
- 源端写 Aksv、An 后,读 Bksv,双方本地计算 Km,再派生 Ks 用于视频加密。
- 链路运行期间按规范时序比较 Ri/Ri'。
- Bcaps.REPEATER 与 Bstatus 用于处理 Repeater 拓扑;中继设计还需正确读取 KSV FIFO 和验证 V'。
3.2 HDCP 2.2 / 2.3(消息型协议)
HDCP 2.x 不再使用 1.4 的 KSV/Ri 寄存器布局,改为 Write_Message / Read_Message 收发 AKE、LC、SKE 等结构化消息(RSA/AES 会话)。DDC 侧关键寄存器如下:
| 偏移 | 名称 | 方向 | 说明 |
|---|---|---|---|
0x50 | HDCP2Version | R | bit2=1 表示支持 HDMI 上的 HDCP 2.2 |
0x60 | Write_Message | W | 向接收端 burst 写消息 |
0x70 | RxStatus | R | 2 B,状态与待读消息长度 |
0x80 | Read_Message | R | 从接收端 burst 读消息 |
RxStatus 常用位(概念级):
| 位域 | 含义 |
|---|---|
| READY | 接收端有待读消息,可读 Read_Message |
| REAUTH_REQ | 请求重新认证 |
| Message_Size | 当前消息字节数(需按规范位域解析) |
典型流程(源端视角):
- 读
HDCP2Version并检查支持位。 - 经
Write_Message发送 AKE_Init 等消息;轮询RxStatus直至 READY。 - 经
Read_Message读取 AKE_Send_Cert 等响应,消息中携带RxCaps。 - 完成 LC_Init / LC_Send_L1、SKE_Send_Eks 后进入加密态。
- 运行中按规范处理
RxStatus.REAUTH_REQ、热插拔与 Repeater 拓扑变化。
与 HDCP 1.4 的差异小结:
| 项目 | HDCP 1.4 | HDCP 2.2/2.3 |
|---|---|---|
| 认证模型 | KSV + An + Ri | 证书 + 密钥交换消息 |
| DDC 用法 | 固定偏移读写 | 消息长度 + burst 读写 |
| 4K 内容 | 部分场景受限 | 4K 商用内容普遍要求 2.2+ |
| 兼容性 | 老设备广泛支持 | 需 TX/RX 均支持 2.x |
四、SCDC 交互与关键寄存器
SCDC(Status and Control Data Channel)自 HDMI 2.0 引入,I2C 地址 0x54(0xA8/0xA9)。与 EDID 不同,SCDC 包含双向状态与控制信息;各寄存器和位域分别由 Source 或 Sink 更新,用于 TMDS 加扰、时钟比、链路状态以及 HDMI 2.1 FRL 训练。
访问前提: Sink EDID 的 HF-VSDB 中 SCDC_Present = 1;否则源端不得访问 SCDC。
4.1 通用寄存器(TMDS / HDMI 2.0)
| 偏移 | 名称 | 读写 | 说明 |
|---|---|---|---|
0x01 | Sink Version | R | Sink 支持的 SCDC 版本 |
0x02 | Source Version | W | Source 使用的 SCDC 版本 |
0x10 | Update_0 | R/W | 更新标志低字节 |
0x11 | Update_1 | R/W | 更新标志高字节 |
0x20 | TMDS Configuration | R/W | Scrambling_Enable、TMDS_Bit_Clock_Ratio |
0x21 | Scrambler Status | R | 加扰状态 |
0x30 | Config_0 | W | RR_Enable 等 Source 配置 |
0x31 | Config_1 | W | FRL_Rate 与 FFE_Levels(HDMI 2.1) |
0x35 | Source Test Configuration | R | Sink 请求的 Source 测试配置 |
0x40 | Status Flags_0 | R | Clock/Lane lock 与 FLT_Ready |
0x41–0x42 | Status Flags_1/2 | R | FRL Link Training Pattern 请求 |
0x50–0x57 | CED / RS counters | R | 字符或 Reed-Solomon 错误统计 |
TMDS Configuration(0x20)要点:
- TMDS_Bit_Clock_Ratio = 0:TMDS 时钟/数据比 1:10,适用于不超过 340 Mcsc 的 TMDS 字符率。
- TMDS_Bit_Clock_Ratio = 1:比 1:40,适用于高于 340 Mcsc 的 TMDS 字符率。
- Scrambling 与时钟比必须按当前 TMDS 字符率和 Sink 能力配套配置;切换顺序与时限应遵循目标 HDMI 规范版本。
Update Flags: Update_0/1 主要由 Sink 置位,用于通知 Source 状态、CED 或 FRL 训练信息发生变化;Source 处理后写 1 清除相应标志。
4.2 FRL 相关寄存器(HDMI 2.1)
FRL(Fixed Rate Link)模式下,链路训练通过 SCDC 与 EDID 中的 Max_FRL_Rate 协同完成。主要扩展寄存器(同一 0x54 地址空间):
| 偏移 | 关键字段 | 作用 |
|---|---|---|
0x10 | FLT_Update、FRL_Start | Sink 通知 Source 读取训练状态,或通知 FRL 已启动 |
0x31 | FRL_Rate、FFE_Levels | Source 选择 FRL 速率并设置当前 FFE 等级 |
0x35 | FLT_no_timeout 等 | Sink 请求的 Source 测试配置;正常产品流程不应随意使用 |
0x40 | FLT_Ready、Lane Locked | Sink 就绪与各 lane 锁定状态 |
0x41–0x42 | LTP request | Sink 为各 lane 请求下一训练模式 |
FRL 建立概要:
- 读 EDID:HF-VSDB 中
SCDC_Present=1,记录Max_FRL_Rate。 - Source 写入 Source Version,并在
Config_1中选择不超过 EDID 声明的 FRL_Rate。 - 进入 Link Training 状态机(LTS1~LTS4),根据
FLT_Update、FLT_Ready和各 lane 的 LTP 请求推进训练。 - 训练失败或超时则回退 TMDS 模式。
- 正式输出前确认 FRL_Rate 与 lane 数(3 lane / 4 lane)一致。
FRL 与 TMDS 互斥:进入 FRL 后 TMDS Configuration 的 Scrambling 路径不再适用;调试时应在抓包中区分当前链路模式。
五、DDC/CI 交互
DDC/CI(Display Data Channel Command Interface)是 VESA 定义的 双向命令通道,I2C 从机地址 0x37(0x6E/0x6F)。主机通过 MCCS(Monitor Control Command Set)中的 VCP(Virtual Control Panel)码读写亮度、对比度、输入源等参数。HDMI 线缆上 DDC/CI 与 EDID 共用 SCL/SDA,但逻辑地址独立。
5.1 报文格式
DDC/CI 在 I2C 上传输 帧结构,而非 EDID 式的纯线性 ROM 读:
| 字段 | 说明 |
|---|---|
| 源地址 | 主机发送请求时通常使用 0x51 |
| 长度 | 高 bit 置 1 的 Length 字节 |
| 载荷 | VCP 码 + 参数 |
| 校验 | 整帧 XOR 校验 |
时序: 主机发送请求后,需等待 Sink 处理(规范建议 ≥40 ms)再读响应;连续命令间隔过短会导致返回异常。
5.2 常用 VCP 示例
| VCP 码 | 功能 | 说明 |
|---|---|---|
0x10 | Luminance | 亮度(0~100 或设备定义范围) |
0x12 | Contrast | 对比度 |
0x60 | Input Select | 输入源切换(枚举因厂商而异) |
0xD6 | Power Mode | 电源 / 待机状态 |
0xC0 | Display Usage Time | 累计使用时间(只读) |
读 VCP:GET VCP Feature;写 VCP:SET VCP Feature。Linux 下可用 ddcutil 在 /dev/i2c-* 上调试(需 0x37 响应 且显示器 OSD 开启 DDC/CI)。
5.3 实现注意
- 与 EDID 共用总线:固件应串行化 DDC 事务,避免长时间占用总线而阻塞 EDID 或 HDCP。
- 可选性:无 DDC/CI 的 Sink 在
0x37无 ACK,属正常现象。 - Repeater / 矩阵:部分中继设备不透传 DDC/CI,仅透传 EDID 与 HDCP。
相关工具
小结
HDMI DDC 总线上常见的从机地址包括:EDID(0x50)、段指针(0x30)、HDCP(0x3A)、SCDC(0x54)、DDC/CI(0x37)。Bring-up 顺序通常为:HPD → 读 EDID → 配置链路并输出视频 → 对受保护内容执行 HDCP 认证;FRL 场景在 SCDC 中完成 Link Training;显示器管理类功能则走 DDC/CI。抓包或移植驱动时,先确认 7 位地址与当前 HDCP 版本,可少走大量弯路。
