手把手教你为AM5728开发板调试Marvell 88E1512 PHY驱动(RGMII模式实战)
手把手教你为AM5728开发板调试Marvell 88E1512 PHY驱动(RGMII模式实战)
在嵌入式Linux开发中,网络驱动的调试往往是让开发者头疼的环节之一。特别是当硬件平台采用复杂的PHY芯片时,从设备树配置到驱动修改,再到实际验证,整个过程需要开发者对硬件原理、内核驱动框架和调试工具都有深入理解。本文将围绕TI AM5728平台与Marvell 88E1512 PHY芯片,详细讲解RGMII模式下的完整驱动调试流程。
1. 硬件环境与基础概念
1.1 开发板与PHY芯片介绍
创龙AM5728开发板(型号tl5728-easy-evm)采用双核ARM Cortex-A15处理器,集成了丰富的外设接口。在网络部分,开发板通过RGMII接口连接了两颗Marvell 88E1512 PHY芯片:
- PHY0:工作模式为RGMII to Copper(电口)
- PHY1:工作模式为RGMII to SGMII(与交换芯片连接)
RGMII(Reduced Gigabit Media Independent Interface)是千兆以太网常用的接口标准,相比GMII接口,它通过双沿采样技术将数据线数量从24根减少到12根,但时序要求更为严格。
1.2 PHY工作模式关键寄存器
88E1512通过Page 18的Register 20配置工作模式,主要模式包括:
| MODE[2:0] | 工作模式 | 描述 |
|---|---|---|
| 0x0 | RGMII to Copper | 直接连接RJ45电口 |
| 0x4 | RGMII to 1000BASE-X | 通过SGMII连接交换芯片 |
提示:修改工作模式后必须执行PHY复位操作,新配置才能生效。
2. 设备树配置详解
2.1 phy-mode属性解析
在AM5728的设备树文件(am57xx-beagle-x15-common.dtsi)中,phy-mode属性的正确配置至关重要。常见的RGMII相关模式包括:
rgmii:MAC和PHY都不进行时序补偿rgmii-id:MAC和PHY都进行时序补偿rgmii-rxid:仅RX方向进行补偿rgmii-txid:仅TX方向进行补偿
对于88E1512 PHY,推荐使用rgmii-id模式,由PHY侧补偿时序:
phy0: ethernet-phy@0 { compatible = "ethernet-phy-id0141.0dd1"; reg = <0>; ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>; ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>; ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>; phy-mode = "rgmii-id"; };2.2 operating-mode自定义属性
为灵活配置PHY工作模式,可以在设备树中添加自定义属性:
phy1: ethernet-phy@1 { compatible = "ethernet-phy-id0141.0dd1"; reg = <1>; phy-mode = "rgmii-id"; operating-mode = <2>; /* RGMII to SGMII */ };3. 驱动修改实战
3.1 marvell.c驱动修改要点
在drivers/net/phy/marvell.c中,我们需要扩展88E1512的初始化函数:
static int m88e1510_config_init(struct phy_device *phydev) { int err, temp; u32 mode_num; struct device_node *np = phydev->mdio.dev.of_node; /* 读取设备树中的operating-mode属性 */ if (!of_property_read_u32(np, "operating-mode", &mode_num)) { if (mode_num == 0) { /* RGMII to Copper模式 */ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 18); if (err < 0) return err; temp = phy_read(phydev, MII_88E1510_GEN_CTRL_REG_1); temp &= ~MII_88E1510_GEN_CTRL_REG_1_MODE_MASK; temp |= MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_TO_COPPER; err = phy_write(phydev, MII_88E1510_GEN_CTRL_REG_1, temp); if (err < 0) return err; /* 必须复位PHY使配置生效 */ temp |= MII_88E1510_GEN_CTRL_REG_1_RESET; err = phy_write(phydev, MII_88E1510_GEN_CTRL_REG_1, temp); if (err < 0) return err; } /* 其他模式处理... */ } return m88e1121_config_init(phydev); }3.2 LED配置与特殊功能处理
88E1512的LED引脚可能复用为其他功能(如PPS信号输入),需要通过寄存器配置:
# 使用mdio工具配置PHY1的LED1为高阻状态 mdio eth1 22 3 # 选择Page 3 mdio eth1 16 0xa0 # 配置LED1为Hi-Z模式4. 调试技巧与验证方法
4.1 链路层测试工具
- Wireshark抓包:开发板与PC直连,观察是否能抓到PHY发出的测试包(固定模式如5AA55AA5...)
- tcpdump命令:在开发板上执行
tcpdump -i eth0 arp -XX -v检查ARP包收发 - 链路统计信息:通过
ethtool -S eth0查看收发包计数和错误统计
4.2 常见问题排查
链路无法UP:
- 检查
phy-mode和设备树配置是否匹配硬件设计 - 使用
mdio工具读取PHY寄存器,确认工作模式设置正确 - 测量RGMII信号质量,特别是时钟与数据线的时序关系
- 检查
性能不稳定:
- 确认MAC和PHY的时序补偿配置一致
- 检查PCB布线长度是否符合RGMII规范(时钟与数据线长度匹配)
PHY寄存器读写失败:
- 确认MDC/MDIO引脚配置正确
- 检查PHY地址是否与设备树中
reg属性一致
5. 进阶调试:硬件信号测量
当软件调试无法解决问题时,需要借助示波器或逻辑分析仪测量实际信号:
RGMII时序参数:
- TX/RX时钟与数据建立/保持时间
- 时钟频率是否稳定在125MHz(千兆模式)
电源质量检查:
- PHY芯片的3.3V和1.2V电源纹波
- 参考时钟的抖动特性
在实际项目中遇到过一个典型问题:PHY偶尔会丢失链路,最终发现是电源滤波电容值不足导致。通过增加10μF的MLCC电容后问题解决。
