[PATCH 2/2] net: ethernet: ti: am65-cpsw: fix up PHY mode for fixed RGMII TX delay

Matthias Schiffer matthias.schiffer at ew.tq-group.com
Tue Sep 30 10:05:11 CEST 2025


The am65-cpsw driver currently sets the SEL_RGMII_IDMODE flag in a MAC's
mode register to enable or disable the TX delay. While this was supported
for earlier generations of the CPSW controller, the datasheets of all
modern TI SoCs using the am65-cpsw MAC state that the TX delay is fixed,
and the SEL_RGMII_IDMODE bit is documented as reserved in most of them.
Furthermore, while it was found that this bit does in fact disable the TX
delay, [1] states that this setting is truly unsupported by TI and not
just undocumented.

Following the clarification of the rgmii* phy-mode values in the Linux
DT bindings in [2], the Linux am65-cpsw driver was changed in [3] to
account for the fixed TX delay by fixing up the mode passed to the PHY
driver; a similar fixup already existed in the TI icssg-prueth driver.
[4] followed up on this by explicitly clearing the SEL_RGMII_IDMODE flag
to handle the case where it is set by the bootloader or other firmware
before Linux.

With the above changes, Device Trees that set the recommended "rgmii-id"
mode are now appearing in Linux 6.17+. Avoid setting the unsupported
SEL_RGMII_IDMODE flag for such Device Trees, and instead fix up the PHY
interface mode, thus aligning the U-Boot driver with the Linux kernel.

[1] https://www.spinics.net/lists/netdev/msg1112647.html
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c360eb0c3ccb95306704fd221442283ee82f1f58
[3] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ca13b249f291f4920466638d1adbfb3f9c8db6e9
[4] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a22d3b0d49d411e64ed07e30c2095035ecb30ed2

Signed-off-by: Matthias Schiffer <matthias.schiffer at ew.tq-group.com>
---
 drivers/net/ti/am65-cpsw-nuss.c | 35 ++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c
index 9b69f36d04d..ce1b38e9687 100644
--- a/drivers/net/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ti/am65-cpsw-nuss.c
@@ -234,14 +234,11 @@ out:
 #define AM65_GMII_SEL_MODE_RGMII	2
 #define AM65_GMII_SEL_MODE_SGMII	3
 
-#define AM65_GMII_SEL_RGMII_IDMODE	BIT(4)
-
 static int am65_cpsw_gmii_sel_k3(struct am65_cpsw_priv *priv,
 				 phy_interface_t phy_mode)
 {
 	struct udevice *dev = priv->dev;
 	u32 offset, reg, phandle;
-	bool rgmii_id = false;
 	fdt_addr_t gmii_sel;
 	u32 mode = 0;
 	ofnode node;
@@ -278,12 +275,6 @@ static int am65_cpsw_gmii_sel_k3(struct am65_cpsw_priv *priv,
 		mode = AM65_GMII_SEL_MODE_RGMII;
 		break;
 
-	case PHY_INTERFACE_MODE_RGMII_ID:
-	case PHY_INTERFACE_MODE_RGMII_TXID:
-		mode = AM65_GMII_SEL_MODE_RGMII;
-		rgmii_id = true;
-		break;
-
 	case PHY_INTERFACE_MODE_SGMII:
 		mode = AM65_GMII_SEL_MODE_SGMII;
 		break;
@@ -298,9 +289,6 @@ static int am65_cpsw_gmii_sel_k3(struct am65_cpsw_priv *priv,
 		break;
 	};
 
-	if (rgmii_id)
-		mode |= AM65_GMII_SEL_RGMII_IDMODE;
-
 	reg = mode;
 	dev_dbg(dev, "gmii_sel PHY mode: %u, new gmii_sel: %08x\n",
 		phy_mode, reg);
@@ -630,7 +618,7 @@ static int am65_cpsw_phy_init(struct udevice *dev)
 	u32 supported = PHY_GBIT_FEATURES;
 	int ret;
 
-	phydev = dm_eth_phy_connect(dev);
+	phydev = dm_eth_phy_connect_interface(dev, pdata->phy_interface);
 	if (!phydev) {
 		dev_err(dev, "phy_connect() failed\n");
 		return -ENODEV;
@@ -657,9 +645,28 @@ static int am65_cpsw_ofdata_parse_phy(struct udevice *dev)
 	dev_read_u32(dev, "reg", &priv->port_id);
 
 	pdata->phy_interface = dev_read_phy_mode(dev);
-	if (pdata->phy_interface == PHY_INTERFACE_MODE_NA) {
+
+	/* CPSW controllers supported by this driver have a fixed internal TX
+	 * delay in RGMII mode. Fix up PHY mode to account for this and warn
+	 * about Device Trees that claim to have a TX delay on the PCB.
+	 */
+	switch (pdata->phy_interface) {
+	case PHY_INTERFACE_MODE_RGMII_ID:
+		pdata->phy_interface = PHY_INTERFACE_MODE_RGMII_RXID;
+		break;
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		pdata->phy_interface = PHY_INTERFACE_MODE_RGMII;
+		break;
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+		dev_warn(dev,
+			 "RGMII mode without internal TX delay unsupported; please fix your Device Tree\n");
+		break;
+	case PHY_INTERFACE_MODE_NA:
 		dev_err(dev, "Invalid PHY mode, port %u\n", priv->port_id);
 		return -EINVAL;
+	default:
+		break;
 	}
 
 	dev_read_u32(dev, "max-speed", (u32 *)&pdata->max_speed);
-- 
TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht München, HRB 105018
Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
https://www.tq-group.com/



More information about the U-Boot mailing list