RK3566适配YT8512C百兆以太网:RMII时钟方向与DTS配置实战排查
发布时间:2026/9/21 3:12:56 锦皓数字建站

讲真调了这么多年网口这次RK3566配YT8512C还是让我折腾了整整一个周末。板子是自己画的底板核心板用的RK3566PHY选了裕太微的YT8512C想着百兆嘛RMII一接DTS一配半小时就能搞定。结果通电那一刻ifconfig -a 里只有 lodmesg 里连PHY的影子都看不到。这种“看起来简单、实际上到处是坑”的事情放在嵌入式Linux开发里真是再常见不过了。这篇文章就把这个完整过程记录下来从硬件连接到RMII接口设计从DTS配置到时钟方向选择从PHY ID读取到驱动匹配最后到网络性能验证。每讲一个关键点我都会说明“我当时是怎么排查的”“为什么这一步这么设计”“哪些坑是数据手册里不会明写但实际一定会踩的”。不管你是刚接触RK3566的新手还是被国产PHY芯片折腾到头大的老工程师这篇文章应该都能给你一些参考。1. 选型与硬件设计为什么是YT8512CRMII接口有哪些容易忽略的信号约束1.1 在一堆PHY里挑中YT8512C的理由说实话做产品的选型和做开发板的选型逻辑差别挺大的。如果是学习或者快速验证很多人会直接上RTL8211F、AR8035这类资料多、用的人多的芯片。但我这块板子是要走量、有成本压力的方案所以当时对PHY的要求比较明确只要百兆、价格要低、供货要稳、最好国产。YT8512C就是在这个背景下被选中的。它是裕太微电子的一款10/100M自适应以太网PHY芯片支持RMII接口内部集成LDO外围电路简单功耗也不高在成本敏感的物联网网关、工业控制板、边缘计算盒子上用得非常多。和千兆PHY相比它在百兆场景下性价比确实高而且国内货源稳定。不过选型归选型真正让项目卡壳的是后面的调试。YT8512C的资料开放程度、参考设计的完善程度和Broadcom、Realtek这些老牌厂商比还是有差距的。很多细节藏在datasheet的字里行间不亲自踩一遍很难发现。1.2 RMII接口的信号构成比RGMII少一半线但坑并没有少RMIIReduced Media Independent Interface是专为10/100M以太网设计的简化接口它把数据线从RGMII的12根缩减到了7根。我先把RK3566 GMAC和YT8512C之间的RMII信号列一下方便后面讲问题信号方向MAC视角功能说明TXD[1:0]输出发送数据TX_EN输出发送使能RXD[1:0]输入接收数据CRS_DV输入载波侦听/数据有效REF_CLK输入/输出50MHz参考时钟MDC输出管理接口时钟MDIO双向管理接口数据数据线从RGMII的8根减到4根但时钟方案反而更讲究。RGMII的125MHz TX_CLK/RX_CLK是由PHY提供的方向很明确而RMII的REF_CLK必须由某一方主动提供50MHz——要么MAC给PHY要么PHY给MAC两边都觉得自己应该是输出方的时候板子就彻底沉默了。这个时钟方向问题就是后面最大的坑。1.3 原理图阶段必须确定的三个点晶振、复位、LED原理图设计阶段有几个点如果没提前确认后面调试就是给自己挖坑。第一是晶振或者时钟输入。YT8512C可以用25MHz晶振也可以由外部直接输入50MHz参考时钟。RMII规范要求MAC和PHY共用同一个50MHz参考源最省事的做法是给PHY配一个25MHz晶振让PHY内部PLL倍频到50MHz再把50MHz时钟输出给MAC的REF_CLK。这样整个系统只有一个晶振源相位一致性好也不容易出EMI问题。第二是复位电路。PHY的复位脚建议用GPIO控制不要直接接RC上电复位。原因有两个一是MAC和PHY的上电时序未必一致如果MAC已经初始化完了PHY才刚复位完MDIO通信就会失败二是调试期间你会发现需要软复位PHY的场景非常多用GPIO控制复位脚一条命令就能搞定不用反复断电。我在DTS里配置的就是RK3566的一个普通GPIO来做复位控制。第三是LED指示灯。YT8512C的LED引脚能反映link状态和活动状态画板时一定要预留出来哪怕不接灯也要引测试点。很多时候网口“没通”其实只是链路没协商上看一眼PHY的LED状态就能判断是硬件问题还是软件问题能省下大量抓日志的时间。2. 上电即失败日志、波形与MDIO的第一轮排查2.1 第一现场dmesg里根本看不到PHY板子第一次上电我用串口调试助手打开内核日志启动完成后执行 ifconfig -a结果是只有 lo连 eth0 都没有。再查 dmesg关于 GMAC 的日志只有一条rockchip-gmac fe010000.ethernet: no phy found当时我就知道问题不简单。这个日志的意思是MDIO总线上没读到PHY。但到底是PHY没上电、MDIO通信有问题、PHY地址不对、还是PHY本身就没有正常复位日志里完全看不出来。皮层之下还有很多可能性必须一层一层剥开。2.2 先量时钟50MHz到底有没有排查网络问题我习惯遵循信号链路顺序先电源再时钟再复位再MDIO最后才看数据线。这个习惯救了我很多次因为很多“软件问题”最后都证明是硬件信号没到位。示波器先测YT8512C的XI引脚能看到25MHz晶振波形说明PHY的时钟源工作正常。接着测PHY输出的50MHz REF_CLK这里出了问题——完全没有波形。也就是说PHY要么没有完成初始化要么复位一直被拉低要么PHY芯片根本没正常工作。顺着这个思路又测了复位脚的电压发现复位脚确实是高电平不是被拉低的状态。电源方面1.1V数字核心电压、2.5V模拟电压、3.3V IO电压都在规格书范围内。那问题就变得奇怪了有电源、时钟正常、复位正常为什么PHY没有输出50MHz2.3 换一块板子试出来的重大发现我在实验室又拿了两块一样的底板测试结果第一块能正常出50MHz时钟第二块不行。这就排除了芯片本身的问题指向了焊接或者物料问题。用放大镜检查YT8512C的引脚发现其中一个引脚有轻微的空焊——典型的手工回流焊温度曲线没控制好导致的虚焊。补焊之后50MHz时钟立即出来了。所以第一个教训是国产PHY芯片引脚间距通常比较密手工焊接后最好用万用表蜂鸣档把每个电源、地、时钟引脚都通断量一遍。很多所谓“PHY怎么调都不通”的情况最后查出来都是焊接问题。2.4 MDIO总线手动探测读不到ID就先别谈DTS时钟正常之后再次上电dmesg里依然报 no phy found。但这次我心里的预期变了问题可能出在DTS配置或者MDIO总线的地址匹配上。在继续改DTS之前先用mdio-tools这个工具手动扫描总线上到底有没有PHY响应。在RK3566上如果系统里没有现成的mdio-netlink工具可以交叉编译一个mdio-tools扔到板子里跑。mdio scan如果扫描结果为空说明内核MDIO总线上根本没发现设备。这时候再用示波器抓MDC和MDIO两个引脚的波形看内核有没有发MDIO读命令、PHY有没有回应。我当时抓到的现象是MDC波形正常MDIO在写地址阶段正常但读数据阶段整条线一直为高——PHY没有应答。这时候才把目光回到DTS上。因为RK3566的MDIO是复用引脚如果引脚的复用功能没有配置对GPIO被其他外设占用了MDIO命令就发不出去或者PHY收到但回应回不来。改到这一步才真正进入DTS配置的核心战场。3. DTS从零改到通RMII模式、时钟方向与引脚复用的完整配置3.1 能直接用的完整DTS配置先放出来后面经过反复修改这个配置在我这块板子上是稳定工作的。不同SDK版本的字段名可能略有差异但整体逻辑一致可以直接参考gmac { status okay; phy-mode rmii; clock_in_out output; snps,reset-gpio gpio3 RK_PB5 GPIO_ACTIVE_LOW; snps,reset-active-low; snps,reset-delays-us 0 10000 80000; assigned-clocks cru CLK_MAC_2PHY, cru CLK_MAC_PHY_2MAC; assigned-clock-parents cru CLK_MAC_2PHY_SEL, cru CLK_MAC_PHY_2MAC_SEL; assigned-clock-rates 50000000, 50000000; pinctrl-names default; pinctrl-0 rmiim0_pins; phy-handle phy0; }; mdio { status okay; phy0: ethernet-phy0 { reg 0; clocks cru CLK_REF_MAC_PHY; reset-gpios gpio3 RK_PB5 GPIO_ACTIVE_LOW; reset-assert-us 10000; reset-deassert-us 80000; }; };先别急着照抄这里每一个字段背后都有说道尤其是 clock_in_out、pinctrl-0 和 reset-gpios 这三个地方。下面的内容才是这篇文章真正值钱的部分。3.2 phy-mode rmii为什么不能写成rgmiiRK3566的GMAC控制器本身同时支持RGMII和RMII模式默认的设备树模板里通常写的是 rgmii。如果你只改了phy-mode忘了改其他依赖字段后面会遇到速率上不去、协商失败这类问题。百兆网卡在RMII模式下TXD/RXD各只有2根线2bit在一个时钟周期内传输50MHz时钟刚好能跑到100Mbps50M x 2bit 100Mbps。而RGMII是4bit DDR传输频率是125MHz跑千兆的。如果DTS里phy-mode还是rgmii而PHY实际工作在RMII模式时钟和数据宽度的匹配就全乱了。所以第一步确认PHY硬件接法按硬件原理图决定phy-mode。YT8512C是百兆PHY硬件上只支持RMII或者MII不可能支持RGMII。这里必须写rgmii还是rmii完全取决于你的原理图我这块板子接的是RMII所以配置为 rmii。3.3 clock_in_out 与 assigned-clock-rates方向错了时钟就没了这是我这次调试踩得最深的一个坑单独拿出来讲。RK3566的GMAC有一组时钟树关键节点有两个CLK_MAC_2PHY 和 CLK_MAC_PHY_2MAC。字面意思很好理解一个是MAC发给PHY的时钟一个是PHY发给MAC的时钟。RMII模式下只有一方会真正使用这50MHz。clock_in_out 这个字段决定了GMAC控制器的工作方向clock_in_out inputMAC作为从模式REF_CLK由外部PHY提供PHY方向为主。clock_in_out outputMAC作为主模式REF_CLK由MAC内部产生并输出给PHYPHY方向为从。我原理图上设计的是YT8512C用25MHz晶振内部PLL倍频出50MHz然后通过REF_CLK引脚输出给RK3566的GMAC。也就是说PHY是时钟主、MAC是时钟从DTS里应该配 clock_in_out input。结果我最初配的是 output等于让MAC也输出时钟PHY也输出时钟两个输出源互相怼REF_CLK线上根本不是稳定的50MHz方波PHY自然起不来。正确配置下的时钟关系是这样的25MHz晶振 --- YT8512C PLL --- 50MHz REF_CLK --- RK3566 GMAC反过来如果你的硬件设计是用RK3566的REF_CLK_OUT引脚输出50MHz给PHY那就要配 output。这个方向必须和原理图严格对应没有任何“两头都行”的余地。为了保证时钟频率准确assigned-clock-rates 里两个值我都写了 5000000050MHzassigned-clock-parents 选了对应的时钟源。某些SDK里如果你用了组播时钟源甚至需要查一下当前PLL的输出频率是不是刚好能被50MHz整除不然会出现时钟频率漂移网络时通时不通。3.4 pinctrl-0 rmiim0_pins引脚复用选哪个mux要看原理图RK3566的GMAC引脚有多组复用选项比如 rmiim0_pins、rmiim1_pins区别在于TXD、RXD、TX_EN、CRS_DV这些信号被分配到哪一组物理引脚上。这块最忌讳的就是想当然。我在第一版DTS里用的是 rmiim1_pins因为芯片参考设计里好像用的是m1组但实际我原理图里把RMII信号接到了m0组对应的引脚结果MDIO能通、数据线完全不对link根本建不起来。正确做法是在拿到原理图后对照RK3566的datasheet里的引脚复用表把你实际用到的TXD0、TXD1、RXD0、RXD1、TX_EN、CRS_DV、MDC、MDIO、REF_CLK这些信号对应的mux组找出来再去SDK的dtsi里确认这个组对应的 pinctrl 节点是怎么命名的。改完之后强烈建议查看一下实际生效的引脚复用cat /sys/kernel/debug/pinctrl/pinctrl-handles或者读一下pinmux寄存器确认你配置的引脚组和原理图是匹配的。这一步如果错了前面配置再对也没用。3.5 reset-gpios 和 reset-assert-us/release-us时序是解决问题的关键RESET引脚如果只在PHY上电时靠RC电路复位可能存在一种情况MAC驱动初始化先于PHY复位完成导致MDIO扫描时PHY还没准备好后续驱动重试机制不强的话就永远处于 no phy found 状态。RK3566的GMAC驱动支持 DTS 里的 reset-gpios 和对应的延时参数reset-assert-us复位信号拉低持续时间reset-deassert-us复位释放后等待PHY ready的时间我配置的复位低电平保持10msreset-assert-us 10000释放后等待80msreset-deassert-us 80000。这个80ms是给YT8512C完成内部校准、锁相环稳定的时间。第一次调试的时候我给的值太小只有10ms结果PHY的PLL还没锁住MDIO扫描照样失败。后来加长到80ms就稳定了。这里有个小经验PHY的复位释放等待时间宁长勿短。很多PHY芯片的上电初始化时间都在50ms以上尤其是带内部PLL的RMII芯片。如果系统启动时PHY还没ready有些驱动会反复重试但有的不会。自己加一个长延时是成本最低的解法。3.6 mdio子节点里的PHY地址reg为什么要从0开始YT8512C的PHY地址由硬件引脚决定常见的是把PHYAD[2:0]或者PHYAD[4:0]拉高或拉低来配置。我板子上把所有PHY地址引脚都接地了地址就是0。所以在mdio子节点里写的是 reg 0。如果这里写的地址和硬件不匹配MDIO总线自然找不到PHY。判断方法很简单用mdio-tools扫描总线看看哪个地址有回应mdio scan扫描结果会列出所有能通信的PHY地址。把扫描到的地址填进reg再把对应的PHY节点加上去驱动就能识别到了。3.7 compatible字段要不要写怎么写在PHY子节点里经常能看到类似这样的写法compatible ethernet-phy-id0044.1792, ethernet-phy-ieee802.15-c22;这个写法是把读取到的PHY ID直接用compatible指定给驱动。但YT8512C大多数情况下不需要特意指定compatibleLinux的phylib会通过MDIO读取PHY ID然后自动匹配通用的Generic PHY驱动。那什么时候需要指定呢当你需要调用芯片专用驱动的特定功能时比如某些厂商PHY的省电模式、EEE、特定寄存器初始化Generic驱动不会做这些事。如果你只是要一个能跑通的百兆网口通用驱动就够了。我实际调试中先用mdio read命令把PHY ID读出来mdio read 0 2 mdio read 0 3能读到非全F、非全0的ID值说明MDIO通信正常剩下的交给phylib自动匹配。如果读出来是0xffffffff说明PHY地址不对或者PHY根本没起来如果读出来是0x00000000说明PHY处于复位状态或者电源没到位。这一步能非常快速地区分硬件问题和配置问题。4. 驱动匹配、自协商与网络性能验证4.1 从no phy found到eth0出现哪些日志说明驱动已经正常工作DTS改对之后再次开机dmesg里不再是 no phy found而是类似这样的日志rk_gmac-dwmac fe010000.ethernet: 100Mbps, full duplex, link up同时 ifconfig -a 里也出现了 eth0。这说明从PHY硬件、MDIO管理通道到GMAC控制器已经全部打通了。这个时候先别急着高兴网口能link上只是第一步。我还遇到过link正常、但是ping不通的情况那问题就出在数据通路或者DMA配置上。先测一下驱动有没有报错dmesg | grep -i gmac\|eth0\|phy重点看有没有DMA相关的错误、描述符错误。RK3566的GMAC在DTS里还涉及dma-coherent、tx-fifo-depth这些参数一般SDK默认配置是没问题的但如果自己改过内存或DMA配置就要小心。4.2 自协商过程百兆全双工到底协商上没YT8512C上电后默认开启自协商与对端交换机/router协商速率和双工模式。确认当前协商结果ethtool eth0输出里会包含 Speed: 100Mb/s 和 Duplex: Full。如果显示 10Mb/s 或者 Half即使link是up的实际网络性能也会非常差。当时我遇到过一次协商成10M Half的情况原因是网线用了劣质线RMII信号质量差导致协商降级。换了一根好的网线立即恢复到100M Full。所以如果遇到协商速率不对先换线、换对端设备不要急着怀疑DTS。如果对端设备固定了速率和双工也可以在PHY节点里配置fixed-link { speed 100; full-duplex; };但一般情况下不建议用fixed-link因为会失去自协商的灵活性。只有在对端设备不支持自协商或者做工业设备互联时才会用到。4.3 用iperf3验证真实吞吐量百兆跑满该是多少很多人在这一步喜欢用ping大包来判断“网口通没通”但我的建议是ping通了之后再用iperf3测一下实际吞吐因为ping小包只是确认通路存在吞吐率才是性能真实指标。在RK3566板子上跑iperf3服务端PC上跑客户端iperf3 -s # 板子侧 iperf3 -c 192.168.1.100 -t 30 # PC侧百兆网口的理论极限大约是94-95Mbps因为以太网报头、帧间隙这些协议开销最多只能到线速的94%左右。如果实测能达到85Mbps以上基本可以认为性能正常。如果只有几十Mbps就要查是不是中断处理、DMA缓冲、CPU负载的问题。我这个板子最终测下来的结果是92Mbps左右接近线速说明RMII数据通路的DMA搬移和中断处理没有明显瓶颈。另外多线程模式可以再加一层验证iperf3 -c 192.168.1.100 -t 30 -P 4多线程打流能够暴露单线程TCP处理能力的上限如果多线程时吞吐明显高于单线程说明瓶颈在协议栈或者CPU单核处理能力而不是物理链路。4.4 UDP方向容易忽视的问题丢包率和实时性TCP有重传机制即使链路质量一般TCP吞吐看起来也还凑合。但很多实际项目比如用UDP做实时控制、Modbus TCP转UDP透传、视频流传输对UDP丢包率非常敏感。验证UDP丢包可以用iperf3iperf3 -c 192.168.1.100 -u -b 80M -t 30-U方向测的是发送如果想测接收要在服务端加 -u 参数。如果板子是作为UDP服务端接收数据就在板子上跑 iperf3 -s -uPC端跑 iperf3 -c 板子IP -u -b 80M -t 30。实测下来如果丢包率在0.1%以内对大多数应用都是可以接受的。如果丢包率很高优先检查RMII信号完整性、时钟抖动和PHY的接收电平配置。RMII模式对布线要求虽然比RGMII低但也不是完全无所谓。REF_CLK的走线尽量短别靠近电源和高速开关信号不然EMI会直接影响PHY的接收灵敏度。5. 复盘这张板子上最深的几个坑与实用工具链5.1 我踩过的坑整理成一张表为了让你少走弯路我把这次调试中遇到的所有问题和最终原因整理成了一张表按“症状-根因-解决方案”列出来症状根因解决方案dmesg报no phy foundYT8512C虚焊无法正常初始化补焊检查电源、时钟、复位引脚MDIO扫描无回应PHY芯片没有输出50MHz时钟确认晶振、PLL、时钟方向配置MDIO扫描无回应DTS中clock_in_out方向错误根据硬件原理图配置input或outputlink up但ping不通pinctrl选错mux组数据线复用错误对照原理图选择正确的rmiim0/rmiim1link时通时不通reset-deassert-us太短PHY未就绪加长复位释放等待时间到80msPHY地址不匹配PHYAD引脚配置与DTS reg不一致用mdio scan扫描实际地址并在DTS中修正协商速率降到10M网线质量差或信号完整性差更换网线检查REF_CLK走线、地平面这张表看起来像是事后总结但每一项都是我实际花费时间验证过的。尤其是 clock_in_out 方向和 pinctrl mux组选择这两个问题占了整个调试周期的一大半。如果从一开始就能确认这两个配置可能当天就能跑通。5.2 调试工具链串口、MDIO、ethtool、iperf3的组合拳嵌入式网络调试不是碰运气而是有一套工具链配合使用。我在这次项目里最常用的组合是串口调试助手 dmesg看内核日志确认驱动执行到了哪一步。RK3566开发板上一般要用USB转串口模块连接调试串口波特率通常是1500000具体以你的SDK配置为准。mdio/mdio-tools直接读写PHY寄存器判断PHY地址、PHY ID、link状态寄存器。比如读寄存器1MII status看link状态读寄存器0看速率和双工配置。ethtool查看和配置MAC侧的网络状态确认协商结果、环回测试是否正常。iperf3测试实际吞吐和UDP丢包率判断性能瓶颈。网络调试助手验证UDP/TCP应用层通信是否正常。调试以太网透传或者Modbus TCP这类应用时直接用现成的网络调试工具发报文比写脚本要直观得多。另外一个非常实用的命令是 ethtool -S eth0可以查看PHY层面的错误计数比如rx_crc_errors、rx_error_packets。如果CRC错误很多基本可以断定信号完整性有问题优先查时钟和布线而不是继续调软件。5.3 给后来人的几个建议量产板验证与复位时序最后再说几个这次项目结束后我对量产板验证和后续维护的经验。第一批量打板回来不要直接上系统先写一个简单的GPIO测试固件把所有PHY引脚的复用都释放掉然后逐一遍历PHY地址读取ID。这个步骤能快速过滤掉一部分焊接问题比直接刷系统、看dmesg要快得多。当时我第二块板子出问题就是靠着这个流程才定位到虚焊的。第二注意复位时序。RC复位电路在量产板上的表现和工程样板可能不一样因为不同批次电容的容差会导致复位时间不同。强烈建议量产方案里用GPIO复位并且在DTS里把reset-assert-us和reset-deassert-us设置得充足一些宁可多等几十毫秒不要赌那几毫秒。第三如果你的产品要做宽温测试YT8512C这类PHY芯片在低温下的PLL锁定时间可能会变长。我建议在低温环境下做一次启动测试确认50MHz时钟在低温下能正常起振。如果发现低温启动偶尔失败把reset-deassert-us再加大或者在系统启动脚本里延时后再让网络服务自动拉起。5.4 一个提高效率的小技巧把调试命令写成脚本调试到后期我发现自己反复在敲同一组命令于是把它们写成了一个一键脚本扔到板子上直接跑#!/bin/bash echo PHY ID mdio read 0 2 mdio read 0 3 echo Link State ethtool eth0 echo MAC Statistics ethtool -S eth0 echo Interrupt Status cat /proc/interrupts | grep -i eth这个脚本虽然简单但每次改完DTS后重启板子执行一次基本上能第一时间判断出问题出在哪一层。网络调试很多时候就是在和时间赛跑能少敲一条命令就少一分烦躁。回过头来看RK3566 YT8512C这套组合本身并不复杂真正的复杂度来自“你以为它是标准配置实际上每个芯片都有自己的脾气”。RMII时钟方向、引脚复用、复位时序这三个地方只要有一个没整对整个网口就起不来。希望这篇记录能帮你把那一个周末省下来用到更有价值的事情上。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。