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网络节点设备树配置的核心要素和它们之间的关系:
4.6 实战检查清单
最后,我总结了一份设备树配置的检查清单。每次调试网络之前,先过一遍这个清单,能省下不少时间:
- PHY地址:确认
reg值与硬件引脚一致,用mdio list验证 - 时钟方向:
clock_in_out与PHY芯片的时钟模式匹配 - 复位时序:复位脉冲宽度≥10ms,复位后延时≥50ms
- 中断号:对照TRM确认中断号正确,触发类型选
LEVEL_HIGH - 引脚复用:
pinctrl配置与原理图一致,特别是RGMII的TX/RX时钟引脚 - PHY模式:
phy-mode与PHY芯片支持的接口模式一致(rgmii/rmii/rgmii-id)
我的习惯:每次改完设备树,我都会先编译、烧录,然后启动内核看dmesg | grep stmmac的输出。如果看到stmmac_open和PHY ID打印,说明配置基本没问题了。