Linux 5.10 HDMI驱动机制详解

1. 版本背景

  • 发布时间:2020年12月13日
  • HDMI支持状态:HDMI 2.0完全支持,CEC框架标准化,HDCP 2.2广泛实现
  • 关键里程碑
    • DRM桥接器框架完全整合
    • HDMI 2.0 FRL (Fixed Rate Link)支持
    • CEC框架标准化
    • HDCP 2.2开源实现
    • 设备树驱动全面采用

2. 子系统架构

现代化架构

  +---------------------+
  |     用户空间        |
  |  DRM API (libdrm)   |
  |  + HDMI音频控制    |
  +----------+----------+
             |
  +----------v----------+
  |     内核空间        |
  |  DRM核心子系统     |
  |  + 标准HDMI桥接器  |
  +----------+----------+
             |
  +----------v----------+
  |  统一HDMI控制器     |
  |  (drm_bridge)      |
  +----------+----------+
             |
  +----------v----------+
  |     HDMI物理层     |
  +---------------------+

架构演进

  • 统一桥接器框架include/drm/drm_bridge.h 定义标准接口
  • HDMI控制器抽象drivers/gpu/drm/bridge/ 下的通用实现
  • CEC框架drivers/media/cec/ 标准化CEC处理
  • HDCP实现drivers/gpu/drm/drm_hdcp.c 开源HDCP 2.2

3. 源码深度解析

HDMI桥接器注册

// drivers/gpu/drm/bridge/adv7511.c
static const struct drm_bridge_funcs adv7511_bridge_funcs = {
    .attach = adv7511_attach,
    .mode_set = adv7511_mode_set,
    .enable = adv7511_enable,
    .disable = adv7511_disable,
    .atomic_enable = adv7511_atomic_enable,
    .atomic_disable = adv7511_atomic_disable,
};

int adv7511_probe(struct i2c_client *client)
{
    struct drm_bridge *bridge;
    struct adv7511 *adv7511;

    bridge = &adv7511->bridge;
    drm_bridge_init(dev, bridge, &adv7511_bridge_funcs);
    drm_bridge_add(bridge);

    return 0;
}
  • 关键函数
    • drm_bridge_init():桥接器初始化
    • drm_bridge_add():添加桥接器到DRM
    • atomic_enable():原子操作支持
    • mode_set():配置显示模式

HDMI 2.0 FRL实现

// drivers/gpu/drm/bridge/lt9611uxc.c
static void lt9611uxc_set_frl_rate(struct drm_bridge *bridge, u8 frl_rate)
{
    struct lt9611uxc *lt9611uxc = bridge_to_lt9611uxc(bridge);
    u8 reg_value;

    /* 配置FRL速率 */
    reg_value = lt9611uxc_read(lt9611uxc, LT9611UXC_REG_FRL_CTRL);
    reg_value &= ~LT9611UXC_FRL_RATE_MASK;
    reg_value |= (frl_rate << LT9611UXC_FRL_RATE_SHIFT);
    lt9611uxc_write(lt9611uxc, LT9611UXC_REG_FRL_CTRL, reg_value);

    /* 等待链路训练完成 */
    if (wait_for_frl_training(lt9611uxc))
        DRM_ERROR("FRL training failed\n");
}
  • FRL速率
    • 3Gbps (HDMI 1.4)
    • 6Gbps (HDMI 2.0)
    • 8Gbps/10Gbps/12Gbps (HDMI 2.1)

4. 设备树配置详解

标准设备树配置

&hdmi {
    status = "okay";

    hdmi-connector {
        compatible = "hdmi-connector";
        #address-cells = <1>;
        #size-cells = <0>;

        port@0 {
            reg = <0>;
            hdmi_con_in: endpoint {
                remote-endpoint = <&hdmi_con_out>;
            };
        };
    };
};

&dwc_hdmi {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&hdmi_hpd_pin>;

    ddc-i2c-bus = <&i2c1>;
    cec-i2c-bus = <&i2c2>;

    port {
        hdmi_con_out: endpoint {
            remote-endpoint = <&hdmi_con_in>;
            ddr = <0>;
        };
    };
};
  • 关键属性
    • ddc-i2c-bus:EDID读取使用的I2C总线
    • cec-i2c-bus:CEC通信使用的I2C总线
    • ddr:DDR模式配置

5. EDID处理机制

增强EDID处理

// drivers/gpu/drm/drm_edid.c
int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
{
    int num_modes = 0;
    int i;

    /* 添加标准显示模式 */
    for (i = 0; i < 4 && edid->standard_timings[i].t; i++) {
        num_modes += drm_add_standard_modes(connector, edid);
    }

    /* 添加CEA扩展块 */
    if (drm_edid_is_cea(edid)) {
        num_modes += drm_add_cea_modes(connector, edid);
        drm_add_speaker_allocation(connector, edid);
        drm_add_modes_custom_cea(connector, edid);
    }

    return num_modes;
}
  • CEA扩展块
    • 音频能力支持
    • 喇叭配置信息
    • 定制显示模式

HDMI 2.0 EDID增强

  • 支持4K@60Hz:通过CTA-861-G标准
  • YCbCr 4:2:0支持:用于4K视频
  • HDR元数据:初步支持静态HDR

6. CEC/HDCP实现

标准化CEC框架

// drivers/media/cec/core/cec-core.c
int cec_transmit(struct cec_adapter *adap, u8 attempts,
                u8 signal_free_time, struct cec_msg *msg)
{
    struct cec_devnode *devnode = adap->devnode;
    int ret;

    mutex_lock(&devnode->lock);
    ret = __cec_transmit(adap, attempts, signal_free_time, msg);
    mutex_unlock(&devnode->lock);

    return ret;
}

static int __cec_transmit(...)
{
    if (adap->ops->adap_transmit) {
        ret = adap->ops->adap_transmit(adap, attempts,
                                     signal_free_time, msg);
        if (ret == 0)
            cec_msg_mark_as_replied(msg);
    }

    return ret;
}
  • 关键特性
    • 设备发现与物理地址分配
    • 标准CEC命令处理
    • 互操作性框架

HDCP 2.2实现

// drivers/gpu/drm/drm_hdcp.c
int drm_hdcp2_authenticate(struct drm_connector *connector)
{
    struct drm_device *dev = connector->dev;
    struct hdcp_port_data *data;
    int ret;

    /* 启动认证流程 */
    ret = drm_hdcp2_msg_send(dev, connector, HDCP_2_2_AKE_INIT);
    if (ret)
        return ret;

    /* 处理认证响应 */
    ret = drm_hdcp2_wait_for_msg(dev, connector, HDCP_2_2_AKE_SEND_CERT);
    if (ret)
        return ret;

    /* 完成认证 */
    return drm_hdcp2_complete_authentication(dev, connector);
}
  • 认证流程
    • AKE (Authenticated Key Exchange)
    • LC_INIT (Locality Check)
    • SKE (Session Key Exchange)

7. 性能调优指南

HDMI 2.0性能优化

  • 启用FRL

    # 设置HDMI 2.0模式
    echo "force" > /sys/class/drm/card0-HDMI-A-1/force_hdmi_20
    
  • 调整EDID读取

    # 增加EDID读取超时
    echo 500 > /sys/module/drm/parameters/edid_read_timeout_ms
    

音频调优

# 启用HDMI 8声道输出
echo "plug:hdmi:CARD=PCH,DEV=0 channels=8" > ~/.asoundrc

# 查看HDMI音频能力
cat /sys/class/drm/card0-HDMI-A-1/eld#

8. 版本差异对比

特性 Linux 4.19 Linux 5.10
HDMI版本 1.4/2.0基础 HDMI 2.0完全
CEC框架 实验性 标准化
HDCP支持 1.x为主 HDCP 2.2
设备树支持 部分 完整
HDR支持 静态HDR

9. 实际硬件适配案例

Rockchip RK3399 HDMI 2.0适配

硬件平台:Rockchip RK3399 EVB

关键代码

// drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = {
    .mode_valid = dw_hdmi_rockchip_mode_valid,
    .get_eld = dw_hdmi_rockchip_get_eld,
    .get_hpd = dw_hdmi_rockchip_get_hpd,
    .phy_data = &rk3399_phy_data,
};

static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
                               void *data)
{
    struct drm_device *drm = data;
    struct dw_hdmi_plat_data *plat_data;

    plat_data = devm_kzalloc(dev, sizeof(*plat_data), GFP_KERNEL);
    *plat_data = rk3399_hdmi_drv_data;

    return dw_hdmi_bind(dev, drm, plat_data);
}

设备树配置

&dwc_hdmi {
    status = "okay";
    ddc-i2c-bus = <&i2c3>;
    cec-i2c-bus = <&i2c4>;
    rockchip,grf = <&grf>;

    port {
        hdmi_in: endpoint {
            remote-endpoint = <&vopb_out_hdmi>;
        };
    };
};

10. 常见问题与解决方案

1. HDMI 2.0模式无法激活

  • 现象:无法输出4K@60Hz

  • 原因

    • 线缆不支持HDMI 2.0
    • EDID未正确报告能力
    • FRL训练失败
  • 解决方案

    # 强制HDMI 2.0模式
    echo "force" > /sys/class/drm/card0-HDMI-A-1/force_hdmi_20
    
    # 检查FRL状态
    cat /sys/kernel/debug/dri/0/bridge/hdmi/frl_status
    

2. CEC设备无法发现

  • 现象:电视遥控器无法控制设备

  • 原因

    • CEC总线配置错误
    • 物理地址冲突
  • 解决方案

    # 设置CEC物理地址
    echo 1.0.0.0 > /sys/class/cec/cec0/phys_addr
    
    # 启用CEC监听
    echo 1 > /sys/class/cec/cec0/monitor_all
    

11. 参考资料

posted @ 2026-07-09 15:51  Jaosn_chen  阅读(7)  评论(0)    收藏  举报