net: ethernet: ti: am65-cpsw: fixup PHY mode for fixed RGMII TX delay

All am65-cpsw controllers have a fixed TX delay, so the PHY interface
mode must be fixed up to account for this.

Modes that claim to a delay on the PCB can't actually work. Warn people
to update their Device Trees if one of the unsupported modes is specified.

Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Siddharth Vadapalli <s-vadapalli@ti.com>
Link: https://patch.msgid.link/9b3fb1fbf719bef30702192155c6413cd5de5dcf.1750756583.git.matthias.schiffer@ew.tq-group.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Matthias Schiffer 2025-06-24 12:53:33 +02:00 committed by Paolo Abeni
parent 9b357ea525
commit ca13b249f2
1 changed files with 25 additions and 2 deletions

View File

@ -2602,6 +2602,7 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
return -ENOENT; return -ENOENT;
for_each_child_of_node(node, port_np) { for_each_child_of_node(node, port_np) {
phy_interface_t phy_if;
struct am65_cpsw_port *port; struct am65_cpsw_port *port;
u32 port_id; u32 port_id;
@ -2667,14 +2668,36 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
/* get phy/link info */ /* get phy/link info */
port->slave.port_np = of_node_get(port_np); port->slave.port_np = of_node_get(port_np);
ret = of_get_phy_mode(port_np, &port->slave.phy_if); ret = of_get_phy_mode(port_np, &phy_if);
if (ret) { if (ret) {
dev_err(dev, "%pOF read phy-mode err %d\n", dev_err(dev, "%pOF read phy-mode err %d\n",
port_np, ret); port_np, ret);
goto of_node_put; goto of_node_put;
} }
ret = phy_set_mode_ext(port->slave.ifphy, PHY_MODE_ETHERNET, port->slave.phy_if); /* 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 (phy_if) {
case PHY_INTERFACE_MODE_RGMII_ID:
phy_if = PHY_INTERFACE_MODE_RGMII_RXID;
break;
case PHY_INTERFACE_MODE_RGMII_TXID:
phy_if = 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;
default:
break;
}
port->slave.phy_if = phy_if;
ret = phy_set_mode_ext(port->slave.ifphy, PHY_MODE_ETHERNET, phy_if);
if (ret) if (ret)
goto of_node_put; goto of_node_put;