4、HDMI接口原理:HDMI信号特性、TMDS编码、EDID与DDC、HDCP协议
HDMI(High-Definition Multimedia Interface)是现代嵌入式显示系统中应用最广泛的数字音视频接口。作为DRM/KMS驱动开发者,理解HDMI的底层信号特性、编码机制、设备发现与内容保护协议,是正确实现drm_encoder与drm_connector驱动的必要条件。本章从物理层到协议层,系统讲解HDMI的核心原理。
4.1 HDMI信号特性
HDMI采用全数字传输,基于TMDS(Transition Minimized Differential Signaling)差分信号架构。其物理层具有以下关键特性:
| 参数 | 规格 | 说明 |
|---|---|---|
| 信号类型 | 差分对(Differential Pair) | 每路数据由D+和D-两根线组成,抗共模干扰 |
| 数据通道数 | 3个TMDS数据通道 + 1个TMDS时钟通道 | 分别传输R/G/B或数据岛包 |
| 单通道速率 | 最高6 Gbps(HDMI 2.1) | 取决于TMDS时钟频率 |
| 传输距离 | 典型5~15米(无中继) | 受线缆质量和信号衰减影响 |
| 阻抗要求 | 100Ω ±15% 差分阻抗 | PCB布线必须严格控制 |
| 电压摆幅 | 400~600 mV(峰峰值) | TMDS电平标准 |
drm_display_info结构体中的max_tmds_clock字段用于限制源端输出的TMDS时钟频率,避免超出接收端能力。HDMI 1.4最大支持340 MHz,HDMI 2.0支持600 MHz。
4.1.1 HDMI信号链路架构
下图展示了HDMI源端(Source)到接收端(Sink)的完整信号链路,包括TMDS数据通道、时钟通道、DDC通道和CEC通道。
4.2 TMDS编码
TMDS(Transition Minimized Differential Signaling)是HDMI物理层的核心编码技术。其目标是在传输过程中最小化信号跳变次数,从而降低电磁干扰(EMI)并提高信号完整性。
4.2.1 TMDS编码流程
TMDS编码器将8位像素数据转换为10位传输字符,包含两个阶段:
- 第一阶段:最小化跳变——将8位数据转换为9位,使得输出序列中0→1或1→0的跳变次数最少。
- 第二阶段:直流平衡——根据当前数据流的直流偏移,选择是否反转第9位,最终输出10位字符,保证长时间传输中1和0的数量大致相等。
4.2.2 TMDS编码示例
下表展示了一个8位像素值经过TMDS编码后的变化过程:
| 阶段 | 数据 | 说明 |
|---|---|---|
| 原始像素 | 0xA5 (10100101) |
8位红色分量 |
| 最小化跳变 | 1 01101001 |
9位,跳变次数从5次降为3次 |
| 直流平衡 | 01 01101001 或 10 10010110 |
10位,根据当前偏移选择反转 |
4.2.3 TMDS编码状态机
下图展示了TMDS编码器的内部状态转换逻辑:
4.3 EDID与DDC
EDID(Extended Display Identification Data)和DDC(Display Data Channel)是HDMI系统中源端发现接收端能力的关键机制。
4.3.1 EDID数据结构
EDID是一段128字节的二进制数据块,存储在接收端的EEPROM中。源端通过DDC通道读取EDID,获取显示器的分辨率、时序、色彩空间、音频能力等信息。
| 字节偏移 | 字段 | 长度 | 说明 |
|---|---|---|---|
| 0x00~0x07 | Header | 8字节 | 固定标识 00 FF FF FF FF FF FF 00 |
| 0x08~0x11 | Manufacturer ID | 10字节 | 厂商代码和产品代码 |
| 0x12~0x13 | Serial Number | 2字节 | 序列号 |
| 0x14~0x17 | Week/Year | 4字节 | 生产周和年份 |
| 0x18~0x1B | EDID Version | 4字节 | 版本号(通常为1.4) |
| 0x36~0x47 | Established Timings | 18字节 | 标准时序支持位图 |
| 0x48~0x7F | Detailed Timings | 56字节 | 4个18字节的详细时序描述块 |
4.3.2 DDC通信协议
DDC基于I²C总线,使用固定的从设备地址:
- DDC地址:
0x50(7位地址)或0xA0(8位地址) - SCL时钟:标准模式100 kHz,快速模式400 kHz
- 读取流程:源端先发送EDID块地址(0x00~0xFF),然后重新启动I²C读取操作,接收128字节数据
- 扩展EDID:HDMI 1.4+支持CEA-861扩展块,位于EDID的0x80~0xFF区域
drm_edid_read()函数封装了DDC读取流程。如果读取失败,驱动应回退到默认时序或报告连接器状态为connector_status_disconnected。部分廉价的HDMI转接器可能存在DDC信号质量问题,导致EDID读取不稳定。
4.3.3 EDID解析流程
4.4 HDCP协议
HDCP(High-bandwidth Digital Content Protection)是HDMI系统中的内容保护机制,用于防止未经授权的复制和窃听。HDCP由Intel开发,目前有HDCP 1.4和HDCP 2.2/2.3两个主要版本。
4.4.1 HDCP认证流程
HDCP认证分为三个阶段:
- 第一阶段:初始认证——源端向接收端发送AKE(Authentication and Key Exchange)请求,接收端回复自己的公钥证书和密钥。
- 第二阶段:会话密钥协商——双方基于Diffie-Hellman密钥交换算法生成共享会话密钥。
- 第三阶段:周期性检查——在传输过程中,源端每隔2秒发送一次Repeater认证请求,确保接收端仍然合法。
| 版本 | 加密算法 | 密钥长度 | 应用场景 |
|---|---|---|---|
| HDCP 1.4 | 40-bit XOR + AES-128 | 40位设备密钥 | HDMI 1.x、DVI |
| HDCP 2.2 | AES-128 + ECC-256 | 256位椭圆曲线密钥 | HDMI 2.0、4K内容保护 |
| HDCP 2.3 | AES-128 + ECC-256 | 256位椭圆曲线密钥 | HDMI 2.1、增强安全性 |
4.4.2 HDCP在DRM驱动中的实现
在Linux DRM子系统中,HDCP支持通过drm_hdcp接口实现。驱动需要实现以下回调:
struct drm_connector_hdcp_funcs {
int (*hdcp_read_bksv)(struct drm_connector *connector, u8 *bksv);
int (*hdcp_read_ksv_ready)(struct drm_connector *connector, bool *ready);
int (*hdcp_read_an)(struct drm_connector *connector, u8 *an);
int (*hdcp_read_aksv)(struct drm_connector *connector, u8 *aksv);
int (*hdcp_read_v_prime)(struct drm_connector *connector, u8 *v_prime);
int (*hdcp_write_an)(struct drm_connector *connector, u8 *an);
int (*hdcp_write_aksv)(struct drm_connector *connector, u8 *aksv);
int (*hdcp_enable)(struct drm_connector *connector, u8 content_type);
int (*hdcp_disable)(struct drm_connector *connector);
};
4.4.3 HDCP状态机
4.5 HDMI接口驱动开发要点
在DRM/KMS驱动中实现HDMI接口时,需要关注以下关键点:
- TMDS时钟配置:根据分辨率计算TMDS时钟频率,配置PLL和时钟树。公式:
TMDS Clock = H_total × V_total × refresh_rate - DDC通道初始化:注册I²C适配器,设置
connector->ddc指针,确保EDID读取正常 - HDCP状态管理:在
connector->hdcp中维护认证状态,处理重认证和超时 - 音频支持:HDMI支持内嵌音频,需要配置音频数据岛包(Audio InfoFrame)
- 热插拔检测:通过HPD(Hot Plug Detect)引脚检测显示器连接状态,触发
drm_kms_helper_hotplug_event()
cat /sys/kernel/debug/dri/0/HDMI-A-1/edid可以查看原始EDID数据。使用drm_info工具可以查看HDCP认证状态和TMDS时钟配置。