4. HDMI 接口设备树配置:RK3399 HDMI 控制器节点、PHY 配置、DDC 通道、音频与视频参数

RK3399 的 HDMI 接口基于 Synopsys DesignWare HDMI 2.0 TX 控制器,集成在 SoC 内部。设备树配置需要正确描述控制器基地址、中断、时钟、PHY 初始化参数、DDC 通道映射以及音视频时序参数。本章将逐一拆解这些节点,并给出经过验证的参考配置。

4.1 HDMI 控制器节点结构

RK3399 的 HDMI 控制器在设备树中通常位于 i2c 或 display-subsystem 下,主节点定义如下:

hdmi: hdmi@ff940000 {
    compatible = "rockchip,rk3399-hdmi";
    reg = <0x0 0xff940000 0x0 0x20000>;
    interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH 0>;
    clocks = <&cru PCLK_HDMI_CTRL>,
             <&cru SCLK_HDMI_CEC>,
             <&cru SCLK_HDMI_PHY>;
    clock-names = "pclk", "cec", "phy";
    pinctrl-names = "default";
    pinctrl-0 = <&hdmi_i2c_xfer>,
                <&hdmi_cec>;
    power-domains = <&power RK3399_PD_HDCP>;
    status = "disabled";
};
关键点: 时钟名称必须与驱动匹配,pclk 是 APB 总线时钟,cec 是 CEC 功能时钟,phy 是 PHY 参考时钟。缺少任一时钟将导致控制器无法完成初始化。

4.2 PHY 配置节点

RK3399 HDMI PHY 是独立的 IP 模块,基地址为 0xff968000。PHY 节点负责配置 TMDS 时钟、预加重、摆幅等模拟参数。

hdmi_phy: hdmi-phy@ff968000 {
    compatible = "rockchip,rk3399-hdmi-phy";
    reg = <0x0 0xff968000 0x0 0x4000>;
    clocks = <&cru SCLK_HDMI_PHY>,
             <&cru PCLK_HDMI_PHY>;
    clock-names = "ref", "pclk";
    #phy-cells = <0>;
    status = "disabled";
};

PHY 与控制器通过 phys 和 phy-names 属性连接:

&hdmi {
    phys = <&hdmi_phy>;
    phy-names = "hdmi_phy";
};
PHY 参数调优: 在驱动内部,PHY 初始化序列会根据分辨率自动调整 TMDS 时钟分频和摆幅。若遇到信号完整性问题(如闪屏、雪花),可在 PHY 节点中添加 rockchip,phy-tuning 属性覆盖默认值。

4.3 DDC 通道配置

DDC(Display Data Channel)用于读取显示器的 EDID 信息。RK3399 的 HDMI 控制器内部集成 DDC 控制器,通过 I2C 总线与显示器通信。设备树中通过 ddc-i2c-bus 属性指定 I2C 总线:

&hdmi {
    ddc-i2c-bus = <&i2c5>;
};

I2C 节点本身需要配置正确的引脚复用:

&i2c5 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&i2c5_xfer>;
};
属性 值 说明
ddc-i2c-bus &i2c5 指定用于 DDC 通信的 I2C 控制器
pinctrl-0 &i2c5_xfer 确保 I2C 引脚复用为 GPIO3_C0/C1
I2C 速率 100 kHz DDC 规范要求标准模式 100 kHz
常见错误: 若 ddc-i2c-bus 指向的 I2C 节点未使能或引脚复用错误,内核将无法读取 EDID,导致 HDMI 输出无信号。调试时可检查 /sys/kernel/debug/dri/0/HDMI-A-1/edid 是否存在。

4.4 音频与视频参数配置

HDMI 支持音频和视频同步传输。设备树中通过 audio-ports 和 port 子节点配置音视频通道。

4.4.1 视频端口绑定

&hdmi {
    ports {
        #address-cells = <1>;
        #size-cells = <0>;

        port@0 {
            reg = <0>;
            hdmi_in_vopb: endpoint {
                remote-endpoint = <&vopb_out_hdmi>;
            };
        };

        port@1 {
            reg = <1>;
            hdmi_out: endpoint {
                remote-endpoint = <&hdmi_con>;
            };
        };
    };
};

port@0 连接 VOP(Video Output Processor)的 vopb 或 vopl,port@1 连接外部 HDMI 连接器。

4.4.2 音频参数

RK3399 HDMI 音频通过 I2S 接口传输。设备树中需使能 I2S 节点并关联 HDMI:

&i2s2 {
    status = "okay";
    rockchip,i2s-broken-bclk = <1>;
};

&hdmi {
    #sound-dai-cells = <0>;
    hdmi_audio: hdmi-audio {
        compatible = "rockchip,hdmi-audio";
        status = "okay";
    };
};
音频调试: 若 HDMI 无声音,首先检查 aplay -l 是否列出 HDMI 声卡。若未列出,检查 I2S 时钟和 DMA 通道配置。常见问题:rockchip,i2s-broken-bclk 未设置导致 BCLK 频率错误。

4.5 HDMI 设备树完整配置流程

下图展示了 RK3399 HDMI 设备树各节点之间的依赖关系:

RK3399 HDMI 设备树节点依赖关系 RK3399 HDMI 设备树节点依赖关系 display-subsystem hdmi@ff940000 hdmi-phy@ff968000 i2c5 (DDC) hdmi-audio SCLK_HDMI_PHY pinctrl (i2c5_xfer) i2s2 说明: • 控制器通过 phys 属性引用 PHY 节点,通过 ddc-i2c-bus 引用 I2C 节点。 • 音频节点挂载在 HDMI 控制器下,通过 I2S 接口传输音频数据。 • 所有时钟节点由 CRU(Clock Reset Unit)提供,需确保时钟使能。

4.6 视频时序参数配置

HDMI 输出分辨率通过 VOP 的 display-timings 子节点配置。以下为 1080p@60Hz 的典型时序:

display-timings {
    native-mode = <&timing0>;
    timing0: timing0 {
        clock-frequency = <148500000>;
        hactive = <1920>;
        vactive = <1080>;
        hfront-porch = <88>;
        hsync-len = <44>;
        hback-porch = <148>;
        vfront-porch = <4>;
        vsync-len = <5>;
        vback-porch = <36>;
        hsync-active = <0>;
        vsync-active = <0>;
        de-active = <0>;
        pixelclk-active = <0>;
    };
};
参数 1080p@60Hz 4K@30Hz 说明
clock-frequency 148.5 MHz 297 MHz 像素时钟频率
hactive 1920 3840 水平有效像素
vactive 1080 2160 垂直有效像素
hfront-porch 88 176 水平前肩
hsync-len 44 88 水平同步宽度
vfront-porch 4 8 垂直前肩
时序验证: 配置完成后,可通过 modetest -M rockchip 查看当前时序。若显示器无显示,检查 clock-frequency 是否在显示器支持的范围内,以及 hsync-active 和 vsync-active 极性是否正确。

4.7 完整 HDMI 设备树示例

以下为 RK3399 EVB 开发板的 HDMI 完整配置片段:

&hdmi {
    status = "okay";
    ddc-i2c-bus = <&i2c5>;
    phys = <&hdmi_phy>;
    phy-names = "hdmi_phy";
    #sound-dai-cells = <0>;
    pinctrl-names = "default";
    pinctrl-0 = <&hdmi_i2c_xfer>,
                <&hdmi_cec>;
};

&hdmi_phy {
    status = "okay";
};

&i2c5 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&i2c5_xfer>;
};

&i2s2 {
    status = "okay";
    rockchip,i2s-broken-bclk = <1>;
};

&vopb {
    status = "okay";
};

&vopb_mmu {
    status = "okay";
};
调试建议: 若 HDMI 无输出,按以下顺序排查:
1. 检查 dmesg | grep hdmi 是否有错误信息。
2. 确认 /sys/class/drm/card0-HDMI-A-1/status 为 connected。
3. 使用 cat /sys/kernel/debug/clk/clk_summary | grep hdmi 检查时钟是否使能。
4. 测量 HDMI 引脚电压,确保 PHY 供电正常。