ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

RGMII接口ETH Clock Output配置与调试:从原理到示波器验证

RGMII接口ETH Clock Output配置与调试:从原理到示波器验证 做硬件和嵌入式Linux调试的兄弟肯定遇到过这种情况板子画好了PHY芯片也焊上去了上电之后死活协商不上网速查了一圈发现PHY的参考时钟压根没起振或者波形乱得一塌糊涂。这个问题十有八九跟RGMII接口的ETH Clock Output配置有关。今天就把我在这块踩过的坑和总结出来的配置思路完整梳理一遍重点讲清楚RGMII时钟输出的原理、设备树配置步骤、寄存器要点以及怎么用示波器把RGMII信号抓出来验证给正要调RGMII接口的同行一个能直接上手的参考。1. 先搞清RGMII的时钟关系再动手配置很多人一上来就改设备树、翻寄存器结果越改越乱根本原因是没有把RGMII接口的时钟拓扑理解透。RGMII不是简单的“发一根时钟线”就完事它的时钟架构决定了你到底是该从MAC侧输出时钟还是从PHY侧取时钟这一步错了后面全是白做。1.1 RGMII接口的信号组成与时序RGMII全称是Reduced Gigabit Media Independent Interface相比老的GMII把数据线从8根砍到了4根但数据吞吐不能降所以采用DDR双沿采样在时钟的上升沿和下降沿各采样一次。也就是说时钟频率在千兆模式下是125MHz但数据线上的有效传输速率是250Mbps每根线4根线合起来就是1000Mbps。整个接口信号分成两簇TX方向MAC到PHYTX_CLK发送时钟千兆125MHz百兆25MHz十兆2.5MHzTXD[3:0]发送数据DDR双沿采样TX_CTL发送控制信号DDR双沿分别表示TX_EN和TX_ERRRX方向PHY到MACRX_CLK接收时钟RXD[3:0]接收数据RX_CTL接收控制信号关键问题是TX_CLK到底由谁产生。这里存在两种主流方案一种是MAC提供125MHz/25MHz/2.5MHz时钟给PHY另一种是PHY自己从参考时钟分频后回送给MAC。不同SoC和PHY的组合选的模式不一样设备树里的phy-mode配置也完全不一样。1.2 什么是ETH Clock OutputETH Clock Output指的是SoC处理器主动输出一个时钟信号给外接的以太网PHY芯片作为参考时钟源。这个时钟输出引脚在不同芯片上的叫法不一样有些叫REF_CLK有些叫ETH_CLK有些直接复用TX_CLK引脚还有些平台叫CLKO_OUT。为什么要做这种设计因为很多PHY芯片内部虽然有PLL但需要一个干净的参考时钟才能锁定频率。传统做法是给PHY配一颗25MHz晶振但这样既占PCB面积又多一颗物料。SoC提供参考时钟的优势在于可以省掉外部晶振由SoC内部的PLL分频出精确的25MHz或50MHz同时还能通过软件动态开关和调频。这里要特别注意ETH Clock Output输出的不是RGMII的TX_CLK而是给PHY内部PLL用的参考时钟。举个例子很多PHY芯片的XI引脚需要输入25MHz内部PLL把25MHz倍频到125MHz然后从TX_CLK引脚输出给MAC做发送时钟。如果SoC输出的ETH Clock不是PHY需要的频率哪怕有波形PHY也锁不住链路就是起不来。2. 配置ETH Clock Output的三个层级启用ETH Clock Output不是一个单一操作它跨了硬件原理图、芯片引脚复用、设备树描述、内核时钟框架和PHY驱动好几层。我习惯把它拆成三个层面来看排查的时候也按这个顺序逐层验证。2.1 芯片手册层面引脚复用和时钟树第一步不是写代码而是翻芯片的Reference Manual。你需要确认三件事目标引脚是否支持以太网时钟输出功能还是只有普通GPIO功能该引脚在时钟树中挂在哪个PLL下面寄存器里的分频系数怎么设置输出时钟的电平标准和驱动能力是多少例如是1.8V还是2.5V电平能不能直接接PHY的时钟输入引脚很多平台会把ETH_CLK功能复用在一个多功能引脚上比如某款Cortex-A7处理器的引脚默认上电是GPIO模式必须设置IOMUX寄存器切换成ETH_CLK功能时钟才会真正输出。这一步经常被忽略因为设备树里写了pinctrl但实际pinctrl节点里漏掉了时钟功能复用。2.2 设备树层面phy-mode与时钟节点描述在Linux系统下RGMII的配置核心在设备树里。这里有几个关键属性必须理解清楚phy-mode以太网MAC与PHY之间的接口模式。常见取值有rgmii标准RGMII时钟没有内部延迟rgmii-idTX和RX都有内部延迟通常用于PCB走线等长不好控制的情况rgmii-txid只加TX延迟rgmii-rxid只加RX延迟clocks/clock-names给MAC控制器提供的时钟通常会有一个可以配置频率的时钟源assigned-clocks/assigned-clock-rates强制指定某个时钟的输出频率例如assign 50MHz给ETH_CLK引脚设备树里的时钟描述决定了内核在启动时会不会去操作对应的CCMClock Controller Module寄存器。如果时钟节点没配内核就根本不会去使能那个输出引脚自然没有信号。2.3 驱动层面内核时钟框架与PHY驱动硬件层面通过寄存器把时钟开出来了接下来由Linux内核的时钟框架Common Clock Framework管理它的开关和频率。驱动代码里通常会做这几件事通过devm_clk_get()获取设备树里描述的时钟句柄通过clk_set_rate()设置期望频率通过clk_prepare_enable()真正使能时钟输出很多情况下问题出在频率设置有偏差。比如PHY要求的是25MHz输入但内核默认可能输出50MHzPHY的PLL锁不住表现出来就是链路起不来或者协商到10Mbps就不动了。排查时可以用clk_summary接口debugfs查看时钟当前的父源、频率和开关状态这是最快的内核侧验证手段。3. 实操以常见SoC场景为例启用时钟输出理论讲完来点实际的。我以一套常见的方案为例处理器外接千兆PHY比如瑞昱或者Microchip的芯片RGMII接法PHY的参考时钟由SoC的ETH_CLK引脚提供。这套流程在i.MX、全志、瑞芯微等平台上大同小异区别只是寄存器和设备树节点名不同思路可以通用。3.1 确认PHY需要的时钟频率与引脚电平动手之前先查PHY数据手册找到时钟输入引脚。不同厂商命名不一样XI / CLKIN通常要求25MHz或50MHz晶振/参考时钟输入REF_CLK有些PHY支持从该引脚输入参考时钟125CLK部分PHY需要125MHz参考以常见的千兆PHY为例数据手册里会给出类似“25MHz crystal or clock source connected to XI pin”的描述。同时留意输入时钟的电平范围是3.3V容忍还是2.5V。有些SoC的ETH_CLK输出是1.8V电平直接接3.3V供电的PHY XI引脚虽然大多数情况下能工作但时序余量会差恶劣温度下可能出问题。最好加个电平转换或者选支持宽电平输入的PHY。3.2 修改设备树使能时钟输出下面是一段典型的设备树配置示意以简化后的平台为例mac1 { pinctrl-names default; pinctrl-0 pinctrl_rgmii; phy-mode rgmii-id; phy-handle phy0; phy-addr 0; status okay; mdio { #address-cells 1; #size-cells 0; phy0: ethernet-phy0 { reg 0; /* 如果PHY需要SoC提供参考时钟此处可配置 */ clocks clks ETH_CLK_GATE; clock-names phy-ref-clk; }; }; }; clks { assigned-clocks clks ETH_CLK_SEL, clks ETH_CLK_GATE; assigned-clock-parents clks PLL_DIV_SRC; assigned-clock-rates 0, 50000000; };关键点在于在clks节点里通过assigned-clock-rates指定ETH_CLK输出50MHz在MAC节点里把phy-mode选对如果PCB走线不规则建议直接用rgmii-id让MAC对TX和RX都做内部延迟省去外部延迟芯片如果PHY挂在MDIO总线上可以在PHY节点里引用这个时钟让PHY驱动在初始化时先使能参考时钟这段设备树并不保证直接复制就能用因为不同SoC的时钟框架定义差异非常大。但套路是固定的先确认时钟输出的父源和分频再确认门控开关有没有打开最后核对引脚的IOMUX是不是切到了ETH_CLK功能。3.3 验证时钟输出是否正确设备树改完重新编译内核或设备树文件启动后用以下命令验证# 查看SoC时钟树中以太网相关时钟的频率与状态 cat /sys/kernel/debug/clk/clk_summary | grep -i eth # 如果PHY节点挂了clocks属性可以通过下面目录查看 find /sys/kernel/debug/clk -name *eth* -o -name *phy* | head如果显示时钟频率是50000000且状态为enabled说明软件层面已经打开。但这只代表寄存器配置对了不代表物理引脚真的有波形这时候必须用示波器实测。我见过不止一次内核打印时钟开着但示波器测引脚啥都没有原因是引脚复用根本没切过去电平还是GPIO状态。4. 抓取RGMII信号验证时钟和数据质量软件配置完成之后最关键的一步就是用示波器实际测量验证ETH Clock Output和相关RGMII信号是否达标。这个环节叫“RGMII信号抓取”也是很多连板子都没见过的工程师最容易忽略的。不要看软件里都使能了就以为一定没问题高速信号的物理质量才是决定系统稳不稳定的关键。4.1 抓取前的准备工作工欲善其事必先利其器抓RGMII信号对示波器有硬性要求带宽至少要500MHz以上最好1GHz。RGMII千兆时钟125MHz但是上升沿非常快通常1ns左右低带宽示波器测出来的波形全是平滑过的假象探头建议用10x档带宽要足够高探头地线越短越好最好用接地弹簧不要用那根长长的鳄鱼夹地线否则测出来的噪声会大得离谱采样率至少2.5GSa/s这样才能看清细节触发方式上抓时钟信号用上升沿触发就可以抓数据和时钟的相对关系时用时钟上升沿触发然后再观察数据线的建立时间和保持时间。4.2 实测波形关键点抓到的波形重点看几个指标频率时钟信号应该是125MHz、25MHz或2.5MHz对应千兆/百兆/十兆模式。频率偏差通常要在±50ppm以内实际测量用示波器的频率测量功能直接读数占空比理想情况是50%允许范围一般在45%~55%。占空比偏差太大会导致DDR采样时某一沿的建立时间不足上升沿/下降沿对于125MHz时钟上升时间一般要求在1ns左右太慢会导致数据采样点不稳定过冲/振铃过冲超过10%就需要注意PCB阻抗匹配问题数据线与时钟的skewRGMII规定数据和时钟之间最大偏移不能超过1.5ns左右如果用了rgmii-id模式内部延迟时钟会让数据采样点落在数据窗口的正中间这里分享一个经验测试RGMII的数据信号时不要只看某一根线最好把TX_CLK和TXD[0]或者TX_CTL放在一起观察打开示波器的延迟测量功能看时钟边沿和数据跳变沿之间的时间差。如果这个差值接近数据有效窗口的边缘那系统在高温或电压波动下大概率会出现随机丢包。4.3 常见波形异常及其含义异常现象可能原因处理方向时钟频率偏低PHY分频配置错误或SoC PLL参数不对检查assigned-clock-rates和PHY的strap引脚波形有大量振铃PCB走线阻抗不连续或者串联匹配电阻没加调整终端匹配例如串联33R电阻上升沿很缓驱动能力不足或探头地线过长检查SoC IOMUX的驱动强度配置时钟电压摆幅不对SoC输出电平和PHY输入电平不匹配需要电平转换或更换PHY数据采样位置偏移时钟与数据skew过大切换phy-mode启用内部延迟或加外部延迟芯片5. 常见问题与排查技巧实录这部分是我最想分享的全是实际调试中踩过的坑整理成问题排查形式方便遇到类似场景的兄弟快速定位。5.1 时钟完全没有输出拿着示波器探头点ETH_CLK引脚啥波形都没有。按照下面的顺序排查用万用表量引脚电压确认是固定高电平还是低电平。如果是固定电平多半引脚复用没切到时钟功能回到IOMUX寄存器检查看内核clk_summary确认对应时钟有没有被enable。如果显示disabled看驱动代码哪里调用了clk_prepare_enable可能PHY比较晚才初始化日志里没显示错误不代表没有失败翻原理图确认ETH_CLK引脚是不是绕了一圈走了个0欧电阻或者磁珠到PHY可能电阻焊盘虚焊有一种隐蔽情况SoC有两个同功能引脚一个用于普通GPIO、一个用于ETH_CLKPCB上走线接到了ETH_CLK引脚但代码配置的是另一个引脚。这种只能靠仔细对照原理图和芯片封装图来找5.2 时钟频率不对或者不稳定波形有但频率是60MHz或者30MHz这种奇怪数值说明分频关系不对。查这两点SoC内部ETH_CLK的父源PLL应该输出多少频率经过几分频得到目标频率。很多平台PLL默认输出频率很离谱需要先通过assigned-clock-parents指到正确的PLLPHY芯片自己有没有把输入的25MHz倍频到125MHz。有些PHY的倍频系数是通过strap引脚配置的如果strap电阻焊错PHY内部PLL会按错误的倍频系数工作还有一种情况是频率有但一直在跳没什么规律。这种情况查一下SoC的PLL供电是不是有噪声或者PCB上ETH_CLK走线离开关电源太近被干扰了。时钟不稳直接导致PHY的PLL锁定不住所以表现为PHY的link状态灯闪来闪去。5.3 PHY能link但ping不通或协商速率不对这个现象比完全没信号更折磨人因为PHY的link状态是好的千兆也协商上了但就是ping不通或者吞吐量很低。这种问题大多不是时钟有没有的问题而是时序余量不够。第一步看phy-mode配置。如果PCB走线没做等长RGMII的TX/RX时钟和数据线延迟不匹配就需要用内部延迟。但在不同平台rgmii-id模式的延迟量不一定合适。可以尝试切换配置观察现象从rgmii-id改成rgmii-txid或者rgmii-rxid如果PHY或MAC支持寄存器级延迟微调可以逐级调整RX延时和TX延时例如从0.5ns开始以0.25ns步进第二步检查MDIO配置。有时候PHY实际地址和代码里的phy-address不一致导致内核读到的是错误的PHY寄存器从而错误配置了PHY的时钟极性或延迟模式。用mdio工具直接读写PHY寄存器确认芯片ID不陌生# 通过mdio工具读取PHY的芯片ID寄存器地址2和3 mdio eth0 phy_read 2 mdio eth0 phy_read 3第三步用iperf或ping大包验证。先ping 1472字节的大包如果丢包严重再ping小包通过丢包率跟包长的关系判断是时序问题还是电源问题。5.4 排查顺序建议把前面这些经验总结成一套固定的排查流程遇到问题按顺序走能省很多时间硬件侧确认原理图上PHY参考时钟来自哪里频率多少电平是否匹配时钟输出确认示波器实测ETH_CLK频率、占空比、上升沿软件配置确认clk_summary里的时钟状态、设备树phy-mode和assigned-clocksPHY寄存器确认读取PHY控制寄存器确定PHY工作模式和延迟配置信号质量确认抓TXD与TX_CLK的相对时序评估余量这套流程走下来绝大多数RGMII时钟问题都能定位。核心思想是先确认最底层时钟有没有再看频率对不对然后看时序好不好。最后再分享一个实用技巧我调试RGMII接口时习惯把示波器的测量结果保存为CSV然后用Python脚本自动计算上升沿、过冲和skew。特别是调内部延迟的时候肉眼估不准脚本算出来的数值靠谱得多。另外调试阶段建议在PCB上预留ETH_CLK和TX_CLK的测试点不要等打完板才发现没有可以下探针的地方那才叫真正的麻烦。
返回列表