[PATCH 2/2] net: phy: micrel_ksz90x1: support forced GIGE master for KSZ9031
Max Merchel
Max.Merchel at ew.tq-group.com
Fri Nov 21 09:18:07 CET 2025
From: Markus Niebel <Markus.Niebel at ew.tq-group.com>
The micrel KSZ9031 phy has a optional clock pin (CLK125_NDO) which can be
used as reference clock for the MAC unit. The clock signal must meet the
RGMII requirements to ensure the correct data transmission between the
MAC and the PHY. The KSZ9031 phy does not fulfill the duty cycle
requirement if the phy is configured as slave. For a complete
describtion look at the errata sheets: DS80000691D or DS80000692D.
The errata sheet recommends to force the phy into master mode whenever
there is a 1000Base-T link-up as work around. Only set the
"micrel,force-master" property if you use the phy reference clock provided
by CLK125_NDO pin as MAC reference clock in your application.
Attention: this workaround is only usable if the link partner can
be configured to slave mode for 1000Base-T.
This follows linux implementation in commit
e1b505a60366 ("net: phy: micrel: add 125MHz reference clock workaround")
Signed-off-by: Markus Niebel <Markus.Niebel at ew.tq-group.com>
Signed-off-by: Max Merchel <Max.Merchel at ew.tq-group.com>
---
drivers/net/phy/micrel_ksz90x1.c | 37 +++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/micrel_ksz90x1.c b/drivers/net/phy/micrel_ksz90x1.c
index bc42506c65e..1c0a58e25de 100644
--- a/drivers/net/phy/micrel_ksz90x1.c
+++ b/drivers/net/phy/micrel_ksz90x1.c
@@ -189,6 +189,9 @@ static int ksz9031_of_config(struct phy_device *phydev)
{ MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW, 2, ksz90x1_txd_grp, 4 },
{ MII_KSZ9031_EXT_RGMII_CLOCK_SKEW, 2, ksz9031_clk_grp, 2 },
};
+ const unsigned int master = CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG;
+ struct udevice *dev = phydev->dev;
+ ofnode node;
int i, ret = 0;
for (i = 0; i < ARRAY_SIZE(ofcfg); i++) {
@@ -198,7 +201,39 @@ static int ksz9031_of_config(struct phy_device *phydev)
return ret;
}
- return 0;
+ node = phydev->node;
+
+ /* Look for a PHY node under the Ethernet node */
+ if (!ofnode_valid(node))
+ node = dev_read_subnode(dev, "ethernet-phy");
+
+ /* No node found, look in the Ethernet node */
+ if (!ofnode_valid(node))
+ node = dev_ofnode(dev);
+
+ /* Silicon Errata Sheet (DS80000691D or DS80000692D):
+ * When the device links in the 1000BASE-T slave mode only,
+ * the optional 125MHz reference output clock (CLK125_NDO)
+ * has wide duty cycle variation.
+ *
+ * The optional CLK125_NDO clock does not meet the RGMII
+ * 45/55 percent (min/max) duty cycle requirement and therefore
+ * cannot be used directly by the MAC side for clocking
+ * applications that have setup/hold time requirements on
+ * rising and falling clock edges.
+ *
+ * Workaround:
+ * Force the phy to be the master to receive a stable clock
+ * which meets the duty cycle requirement.
+ */
+ if (ofnode_read_bool(node, "micrel,force-master")) {
+ ret = phy_modify(phydev, MDIO_DEVAD_NONE, MII_CTRL1000,
+ master | CTRL1000_PREFER_MASTER, master);
+ if (ret < 0)
+ pr_err("KSZ9031: error applying 'micrel,force-master'\n");
+ }
+
+ return ret;
}
static int ksz9031_center_flp_timing(struct phy_device *phydev)
--
2.43.0
More information about the U-Boot
mailing list