4. 设备树配置:RK网络节点详解、PHY地址配置、时钟与复位属性、中断配置

设备树,说白了就是告诉内核“我这块板子上接了哪些外设、它们怎么连的”。对于RK平台的GMAC(千兆以太网MAC)来说,设备树配错了,内核根本认不出你的网口。我见过不少工程师,硬件原理图画得没问题,PCB走线也漂亮,结果卡在设备树配置上,一调就是好几天。

这一节,我们就来把RK网络节点的设备树配置彻底讲透。我会结合RK3568和RK3588两个主流平台,把PHY地址、时钟复位、中断这些关键属性一个个拆开讲。

4.1 RK网络节点整体结构

先看一个完整的GMAC设备树节点长什么样。以RK3568为例,它的gmac节点通常在rk3568.dtsi里定义,板级文件(比如rk3568-evb.dts)里做具体配置。

&gmac1 {
    status = "okay";
    phy-mode = "rgmii";
    clock_in_out = "input";

    snps,reset-gpio = &gpio4 RK_PB0 GPIO_ACTIVE_LOW;
    snps,reset-active-low;
    snps,reset-delays-us = <0 10000 50000>;

    assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
    assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;

    pinctrl-names = "default";
    pinctrl-0 = <&gmac1_miim
                 &gmac1_tx_bus2
                 &gmac1_rx_bus2
                 &gmac1_rgmii_clk
                 &gmac1_rgmii_bus>;

    phy-handle = <&phy0>;

    mdio {
        compatible = "snps,dwmac-mdio";
        #address-cells = <1>;
        #size-cells = <0>;

        phy0: ethernet-phy@1 {
            reg = <1>;
            compatible = "ethernet-phy-ieee802.3-c22";
            clocks = <&cru CLK_MAC1_2TOP>;
            reset-gpios = <&gpio4 RK_PB0 GPIO_ACTIVE_LOW>;
            reset-assert-us = <10000>;
            reset-deassert-us = <50000>;
        };
    };
};

嗯,这里要注意,RK3588的节点结构基本一致,但时钟域和引脚复用有差异。我建议你直接拿SDK里的dtsi文件做模板,别自己从头写,容易漏属性。

4.2 PHY地址配置——最容易踩的坑

PHY地址配置,说白了就是告诉内核“你的PHY芯片挂在MDIO总线的哪个地址上”。这个地址由PHY芯片的硬件引脚决定,通常是ADDR0~ADDR3的组合。

我曾经遇到过一块板子,PHY地址配成0x0,结果内核死活检测不到PHY。查了半天才发现,PHY芯片的地址引脚默认拉高,实际地址是0x1。所以,一定要先看PHY芯片的数据手册,确认硬件地址。

在设备树里,PHY地址通过reg属性指定:

phy0: ethernet-phy@1 {
    reg = <1>;
    compatible = "ethernet-phy-ieee802.3-c22";
};

这里@1和reg = <1>必须一致,都表示PHY地址为1。常见的PHY地址范围是0~31,但实际项目中多用1~4。

小技巧:如果你不确定PHY地址,可以在uboot里用mdio list命令扫描,或者在内核启动时加phy_mask=0参数让内核扫描所有地址。

4.3 时钟与复位属性

时钟配置是RK网络节点里最绕的部分。GMAC需要多个时钟:TX时钟、RX时钟、MAC主时钟、PHY参考时钟。RK平台通过assigned-clocks和assigned-clock-parents来指定时钟源。

时钟属性 说明 常见取值
assigned-clocks 需要配置的时钟列表 SCLK_GMAC1_RX_TX, SCLK_GMAC1
assigned-clock-parents 时钟的父时钟源 SCLK_GMAC1_RGMII_SPEED, CLK_MAC1_2TOP
clock_in_out 时钟方向:input或output "input", "output"
phy-mode PHY接口模式 "rgmii", "rmii", "rgmii-id"

我个人习惯把clock_in_out设为"input",让PHY芯片提供时钟给MAC。这样时钟抖动更小,稳定性更好。当然,如果你的PHY不支持时钟输出,那就得设成"output"。

复位属性也很关键。RK平台用snps,reset-gpio和snps,reset-delays-us来控制PHY复位时序:

snps,reset-gpio = &gpio4 RK_PB0 GPIO_ACTIVE_LOW;
snps,reset-active-low;
snps,reset-delays-us = <0 10000 50000>;

这三个延时参数分别表示:复位前延时、复位脉冲宽度、复位后延时。单位是微秒。我建议复位脉冲宽度至少10ms,复位后延时至少50ms,给PHY芯片足够的初始化时间。

避坑指南:有些PHY芯片(比如RTL8211F)对复位时序很敏感。我曾经把复位脉冲宽度设成1ms,结果PHY偶尔能识别、偶尔不能。后来改成10ms,问题就解决了。

4.4 中断配置

GMAC的中断配置相对简单,但容易忽略。RK平台通常使用SPI中断,在设备树里通过interrupts属性指定:

interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;

这里GIC_SPI表示共享外设中断,38是中断号,IRQ_TYPE_LEVEL_HIGH是触发类型。不同RK芯片的中断号不一样:

芯片型号 GMAC0中断号 GMAC1中断号
RK3568 34 38
RK3588 38 42
RK3399 30 34

你想想看,如果中断号配错了,内核根本收不到PHY的中断,网络性能会大打折扣。我建议你直接从芯片的TRM(技术参考手册)里查中断号,别靠猜。

4.5 知识结构图

下面这张图总结了RK网络节点设备树配置的核心要素和它们之间的关系:

RK网络节点设备树配置核心要素 GMAC 节点 PHY地址配置 reg = <1>; 时钟配置 assigned-clocks 复位配置 reset-gpios 中断配置 interrupts MDIO子节点 ethernet-phy@1 compatible = "snps,dwmac-mdio" 时钟源选择 SCLK_GMAC1_RGMII_SPEED CLK_MAC1_2TOP 复位时序 reset-assert-us = <10000> reset-deassert-us = <50000> 中断号 GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 配置验证:dmesg | grep stmmac 确认 PHY 识别、时钟锁定、中断注册

4.6 实战检查清单

最后,我总结了一份设备树配置的检查清单。每次调试网络之前,先过一遍这个清单,能省下不少时间:

  1. PHY地址:确认reg值与硬件引脚一致,用mdio list验证
  2. 时钟方向:clock_in_out与PHY芯片的时钟模式匹配
  3. 复位时序:复位脉冲宽度≥10ms,复位后延时≥50ms
  4. 中断号:对照TRM确认中断号正确,触发类型选LEVEL_HIGH
  5. 引脚复用:pinctrl配置与原理图一致,特别是RGMII的TX/RX时钟引脚
  6. PHY模式:phy-mode与PHY芯片支持的接口模式一致(rgmii/rmii/rgmii-id)

我的习惯:每次改完设备树,我都会先编译、烧录,然后启动内核看dmesg | grep stmmac的输出。如果看到stmmac_open和PHY ID打印,说明配置基本没问题了。