3、设备树配置:SA8155显示相关设备树节点解析、DPU/HDMI/DSI接口的DTS配置实战

在高通SA8155平台上,显示与GPU驱动的初始化、时钟管理、中断绑定以及接口配置,全部依赖于设备树(Device Tree Source, DTS)的描述。本章将深入解析SA8155显示子系统相关的设备树节点结构,并手把手完成DPU(Display Processing Unit)、HDMI和DSI接口的DTS配置实战。

学习目标:掌握SA8155显示DTS的层级结构;理解DPU、MDSS、HDMI、DSI节点的关键属性;能够独立编写和调试显示接口的设备树片段。

3.1 SA8155显示子系统设备树层级总览

SA8155的显示子系统在设备树中通常挂载在 soc 总线节点下,以 mdss(Mobile Display Subsystem)为顶层容器。其层级关系如下:

核心层级结构:
soc -> mdss -> mdss_mdp (DPU) -> mdss_dsi0/1 (DSI控制器) -> mdss_hdmi_tx (HDMI发送器)

下面的SVG图展示了SA8155显示子系统在设备树中的主要节点及其依赖关系:

SA8155显示子系统设备树节点结构 SA8155 显示子系统设备树节点层级 soc mdss (显示子系统) mdss_mdp (DPU核心) mdss_dsi0 (DSI控制器) mdss_dsi1 (DSI控制器) mdss_hdmi_tx (HDMI) 说明: • DPU通过内部接口(如DPU_INTF)连接DSI和HDMI控制器。 • 每个显示接口节点都包含时钟、中断、电源域和PHY的phandle引用。

3.2 DPU(mdss_mdp)节点关键属性解析

DPU节点是显示处理的核心,负责图层混合、色彩管理、显示时序生成。以下是一个典型的SA8155 DPU节点配置片段:

mdss_mdp: qcom,mdss_mdp@ae00000 {
    compatible = "qcom,sdm845-mdss-mdp";
    reg = <0 0x0ae00000 0 0x900000>,
          <0 0x0ac90000 0 0x300>;
    reg-names = "mdp_phys", "vbif_phys";
    interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
    interrupt-controller;
    #interrupt-cells = <1>;

    clocks = <&gcc GCC_DISP_AHB_CLK>,
             <&gcc GCC_DISP_AXI_CLK>,
             <&gcc GCC_DISP_MDP_CLK>;
    clock-names = "iface", "bus", "core";

    power-domains = <&disp_domain>;

    /* DPU 内部接口端口定义 */
    ports {
        #address-cells = <1>;
        #size-cells = <0>;
        port@0 {
            reg = <0>;
            dpu_intf0_out: endpoint {
                remote-endpoint = <&dsi0_in>;
            };
        };
        port@1 {
            reg = <1>;
            dpu_intf1_out: endpoint {
                remote-endpoint = <&dsi1_in>;
            };
        };
        port@2 {
            reg = <2>;
            dpu_intf2_out: endpoint {
                remote-endpoint = <&hdmi_in>;
            };
        };
    };
};
DPU节点关键属性说明
属性值示例说明
compatibleqcom,sdm845-mdss-mdp驱动匹配字符串,用于绑定对应的DPU驱动
reg0x0ae00000, 0x900000DPU寄存器基地址和大小,包含MDP和VBIF两个区域
interruptsGIC_SPI 83DPU全局中断,用于VSYNC、错误处理等
clocksiface, bus, core三路核心时钟:AHB接口时钟、AXI总线时钟、MDP核心时钟
power-domainsdisp_domain显示电源域,控制DPU的电源状态
portsport@0/1/2输出端口,分别连接到DSI0、DSI1和HDMI
避坑提示:DPU的 reg 地址必须与芯片手册的物理地址严格一致。如果 vbif_phys 地址配置错误,会导致DPU无法访问VBIF(Virtual Bus Interface FIFO),出现图层无法提交的故障。

3.3 DSI接口DTS配置实战

DSI(Display Serial Interface)控制器负责将DPU输出的并行数据转换为串行MIPI DSI协议数据。SA8155通常包含两个DSI控制器,支持双通道或级联模式。以下是 mdss_dsi0 的完整配置示例:

mdss_dsi0: qcom,mdss_dsi@ae94000 {
    compatible = "qcom,sdm845-dsi-ctrl";
    reg = <0 0x0ae94000 0 0x400>;
    reg-names = "dsi_ctrl";

    interrupt-parent = <&mdss_mdp>;
    interrupts = <4 0>;

    clocks = <&gcc GCC_DISP_AHB_CLK>,
             <&gcc GCC_DISP_AXI_CLK>,
             <&gcc GCC_DISP_MDP_CLK>,
             <&gcc GCC_DISP_DSI0_CLK>;
    clock-names = "iface", "bus", "core", "core_mmss";

    assigned-clocks = <&gcc GCC_DISP_DSI0_CLK>;
    assigned-clock-rates = <192000000>;

    phys = <&dsi0_phy>;
    phy-names = "dsi";

    ports {
        #address-cells = <1>;
        #size-cells = <0>;
        port@0 {
            reg = <0>;
            dsi0_in: endpoint {
                remote-endpoint = <&dpu_intf0_out>;
            };
        };
        port@1 {
            reg = <1>;
            dsi0_out: endpoint {
                remote-endpoint = <&panel0_in>;
                data-lanes = <0 1 2 3>;
            };
        };
    };
};

3.3.1 DSI PHY配置

DSI PHY负责MIPI D-PHY物理层信号转换,必须与DSI控制器配对配置:

dsi0_phy: qcom,dsi-phy@ae94400 {
    compatible = "qcom,sdm845-dsi-phy-10nm";
    reg = <0 0x0ae94400 0 0x200>,
          <0 0x0ae94600 0 0x280>,
          <0 0x0ae94900 0 0x180>;
    reg-names = "dsi_phy", "dsi_phy_lane", "dsi_pll";

    #clock-cells = <1>;
    #phy-cells = <0>;

    clocks = <&gcc GCC_DISP_AHB_CLK>;
    clock-names = "iface";

    vdda-supply = <&pm8150_l5>;
    vddio-supply = <&pm8150_l12>;
};
实战要点:DSI的 data-lanes 属性必须与硬件走线顺序一致。如果硬件使用了4条数据通道,但配置为 <0 1 2>(3条),则屏幕无法点亮。建议在硬件原理图中确认lane映射关系。

3.4 HDMI接口DTS配置实战

SA8155的HDMI发送器通过 mdss_hdmi_tx 节点配置,支持HDMI 2.0输出。核心配置包括时钟、PHY、HDCP和音频接口:

mdss_hdmi_tx: qcom,hdmi-tx@ae90000 {
    compatible = "qcom,sdm845-hdmi-tx";
    reg = <0 0x0ae90000 0 0x10000>,
          <0 0x0ae00000 0 0x1000>;
    reg-names = "core_physical", "mdp_physical";

    interrupt-parent = <&mdss_mdp>;
    interrupts = <8 0>, <9 0>;
    interrupt-names = "hpd", "irq";

    clocks = <&gcc GCC_DISP_AHB_CLK>,
             <&gcc GCC_DISP_AXI_CLK>,
             <&gcc GCC_DISP_MDP_CLK>,
             <&gcc GCC_DISP_HDMI_CLK>;
    clock-names = "iface", "bus", "core", "core_mmss";

    assigned-clocks = <&gcc GCC_DISP_HDMI_CLK>;
    assigned-clock-rates = <297000000>;

    phys = <&hdmi_phy>;
    phy-names = "hdmi_phy";

    hdcp {
        compatible = "qcom,sdm845-hdcp";
        qcom,hdmi-tx-hdcp = <&mdss_hdmi_tx>;
    };

    ports {
        #address-cells = <1>;
        #size-cells = <0>;
        port@0 {
            reg = <0>;
            hdmi_in: endpoint {
                remote-endpoint = <&dpu_intf2_out>;
            };
        };
        port@1 {
            reg = <1>;
            hdmi_out: endpoint {
                remote-endpoint = <&hdmi_connector_in>;
            };
        };
    };
};
HDMI节点关键属性对比
属性DSIHDMI
时钟频率192 MHz(典型)297 MHz(HDMI 2.0 4K@60)
中断数量1个(DSI控制器中断)2个(HPD热插拔 + IRQ)
PHY类型MIPI D-PHYHDMI TMDS PHY
特殊功能data-lanes配置HDCP加密模块
电源域通常与DPU共享独立HDMI电源域

3.5 显示接口与DPU的端口连接实战

设备树中,显示接口与DPU的连接通过 remote-endpoint 属性实现。以下是一个完整的端口连接示意图:

DPU与显示接口的端口连接关系 DPU 与 DSI/HDMI 端口连接关系 mdss_mdp (DPU) port@0 / port@1 / port@2 dpu_intf0_out dpu_intf1_out dpu_intf2_out mdss_dsi0 dsi0_in <- dpu_intf0_out mdss_dsi1 dsi1_in <- dpu_intf1_out mdss_hdmi_tx hdmi_in <- dpu_intf2_out 连接规则: 每个显示接口的 port@0 作为输入端口,通过 remote-endpoint 引用DPU对应输出端口的 phandle。

3.6 常见配置错误与调试方法

  • 时钟未使能:如果 assigned-clock-rates 设置的值超出硬件范围,DSI或HDMI将无法输出时钟,导致无显示。检查 clk_summary 确认时钟频率。
  • PHY电源缺失:DSI PHY和HDMI PHY需要独立的LDO供电。如果 vdda-supply 或 vddio-supply 未正确配置,PHY初始化会失败。
  • 端口连接断裂:如果 remote-endpoint 的phandle引用错误(例如拼写错误或节点不存在),内核会在 dmesg 中输出 EPROBE_DEFER 或 of_graph_get_remote_endpoint 错误。
  • 中断号冲突:DPU和HDMI的中断号必须在 interrupts 属性中正确指定。使用 cat /proc/interrupts 验证中断是否注册成功。
调试命令速查:
# 查看设备树节点是否被正确解析
ls /sys/firmware/devicetree/base/soc/mdss/
# 查看DPU时钟状态
cat /sys/kernel/debug/clk/gcc_disp_mdp_clk/clk_rate
# 查看DSI控制器状态
cat /sys/kernel/debug/dsi0/status

3.7 本章小结

本章详细解析了SA8155显示子系统的设备树配置,从顶层 mdss 节点到底层 DSI 和 HDMI 接口,涵盖了DPU的端口连接、时钟分配、PHY配置以及中断绑定。掌握这些DTS配置技巧,是后续驱动开发和显示调试的基础。在实际项目中,建议始终对照芯片参考手册和原理图进行设备树编写,避免因地址或属性错误导致显示异常。