乐橙sn1采用hi3798cv200方案,该Soc内置两个完全一样的gmac,都可引出RGMII接口外挂千兆phy,其中RGMII0与SDIO复用,所以该板子实际使用的是RGMII1。海思与Linaro推出的poplar开发板同样是引出RGMII1,但是poplar开发板外接RTL8211E,这与乐橙sn1的RTL8211F不一样。
在调乐橙sn1的固件的时候,首先刷好poplar的bootloader(ATF+u-boot),可以正常进入u-boot控制台。并且在u-boot控制台中使用mii命令测试与phy芯片进行通信是一切正常的。可以看到乐橙sn1的RTL8211F配置的MDIO总线地址为0x3,这与poplar开发板上的配置刚好一致。
但是后来加载Linux内核后进入系统的时候,gmac驱动报MDIO读取异常,反复重启多次依旧无法读取。于是祭出逻辑分析仪+示波器,根据RTL8211F的手册,在板子上找到MDIO总线接入逻辑分析仪。MDIO仅需一根时钟线+一根双向开漏数据线即可通信,有点类似于IIC。考虑到有可能跟复位信号有关,顺便把RESET也接了上去。
为了方便排查,我在u-boot的bootcmd中加入了一句mii操作指令,让u-boot在加载内核之前进行有效的mdio操作以便对比。
上电启动后的波形如下,其中通道0为MDIO时钟,频率为2.5MHz,通道1为MDIO数据线,通道2为RESET引脚,RESET是低电平有效:
具体分析如下:
- u-boot拉低RESET约30ms后释放
- u-boot在加载内核前进行mii操作,此时phy芯片可以正常应答(0x38)
- 进入Linux后,gmac驱动拉低RESET约10ms后释放
- 接着gmac驱动尝试通过MDIO读取phy寄存器,此时phy芯片没有应答,MDIO数据线保持上拉的高电平状态,表现为0xFFFF
检查内核相关初始化代码,没有发现什么问题。接着猜测是不是因为复位操作,导致phy状态出现异常,那么就先将gmac有关的复位操作禁用试试看。
修改arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
里面的gmac1
节点,去除reset
和reset-names
属性,重新编译dtb并加载。此时,Linux内核启动后可以通过mdio与phy进行正常通信。也就是说去掉了上面所说的第3步操作后可以正常工作。
接着发现在dts中有这么一个属性:
hisilicon,phy-reset-delays-us = <10000 10000 30000>;
这个属性我是直接复制poplar的,三个数值的含义分别是phy复位前,复位时,复位后的持续时间,单位是微秒。
考虑到u-boot中复位拉低的时间长达30ms,而默认设置的复位时长仅为10ms,所以调整该节点的值为:
hisilicon,phy-reset-delays-us = <30000 30000 50000>;
重新编译dtb,再次启动系统,波形如下:
- Linux中的gmac驱动拉低RESET的时间长达40ms
- 复位后操作MDIO总线,可以正常读取(0x38)
总结
参考RTL8211F的手册,手册中提到复位信号至少需要持续10ms,但是通过这次调试可以看到,为了保证phy芯片复位后能正常工作,最好将复位信号的持续时间延长到手册要求的最小值的两倍以上才比较稳妥。