
Add support for configuring the CPSW Ethernet Switch in SGMII mode.
Signed-off-by: Siddharth Vadapalli s-vadapalli@ti.com --- drivers/net/ti/am65-cpsw-nuss.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c index 523a4c9f91..403de3ea25 100644 --- a/drivers/net/ti/am65-cpsw-nuss.c +++ b/drivers/net/ti/am65-cpsw-nuss.c @@ -54,6 +54,12 @@ #define AM65_CPSW_PN_REG_SA_L 0x308 #define AM65_CPSW_PN_REG_SA_H 0x30c
+#define AM65_CPSW_SGMII_CONTROL_REG 0x010 +#define AM65_CPSW_SGMII_MR_ADV_ABILITY_REG 0x018 +#define AM65_CPSW_SGMII_CONTROL_MR_AN_ENABLE BIT(0) + +#define ADVERTISE_SGMII 0x1 + #define AM65_CPSW_ALE_CTL_REG 0x8 #define AM65_CPSW_ALE_CTL_REG_ENABLE BIT(31) #define AM65_CPSW_ALE_CTL_REG_RESET_TBL BIT(30) @@ -89,6 +95,7 @@
struct am65_cpsw_port { fdt_addr_t port_base; + fdt_addr_t port_sgmii_base; fdt_addr_t macsl_base; bool disabled; u32 mac_control; @@ -203,6 +210,8 @@ static int am65_cpsw_update_link(struct am65_cpsw_priv *priv) mac_control |= AM65_CPSW_MACSL_CTL_REG_FULL_DUPLEX; if (phy->speed == 100) mac_control |= AM65_CPSW_MACSL_CTL_REG_IFCTL_A; + if (phy->interface == PHY_INTERFACE_MODE_SGMII) + mac_control |= AM65_CPSW_MACSL_CTL_EXT_EN; }
if (mac_control == port->mac_control) @@ -228,6 +237,7 @@ out: #define AM65_GMII_SEL_MODE_MII 0 #define AM65_GMII_SEL_MODE_RMII 1 #define AM65_GMII_SEL_MODE_RGMII 2 +#define AM65_GMII_SEL_MODE_SGMII 3
#define AM65_GMII_SEL_RGMII_IDMODE BIT(4)
@@ -260,6 +270,10 @@ static void am65_cpsw_gmii_sel_k3(struct am65_cpsw_priv *priv, rgmii_id = true; break;
+ case PHY_INTERFACE_MODE_SGMII: + mode = AM65_GMII_SEL_MODE_SGMII; + break; + default: dev_warn(common->dev, "Unsupported PHY mode: %u. Defaulting to MII.\n", @@ -396,6 +410,13 @@ static int am65_cpsw_start(struct udevice *dev) goto err_dis_rx; }
+ if (priv->phydev->interface == PHY_INTERFACE_MODE_SGMII) { + writel(ADVERTISE_SGMII, + port->port_sgmii_base + AM65_CPSW_SGMII_MR_ADV_ABILITY_REG); + writel(AM65_CPSW_SGMII_CONTROL_MR_AN_ENABLE, + port->port_sgmii_base + AM65_CPSW_SGMII_CONTROL_REG); + } + ret = phy_startup(priv->phydev); if (ret) { dev_err(dev, "phy_startup failed\n"); @@ -779,6 +800,8 @@ static int am65_cpsw_probe_nuss(struct udevice *dev) port->port_base = cpsw_common->cpsw_base + AM65_CPSW_CPSW_NU_PORTS_OFFSET + (i * AM65_CPSW_CPSW_NU_PORTS_OFFSET); + port->port_sgmii_base = cpsw_common->ss_base + + AM65_CPSW_SGMII_BASE * (i); port->macsl_base = port->port_base + AM65_CPSW_CPSW_NU_PORT_MACSL_OFFSET; }