Add support for configuring the CPSW Ethernet Switch in SGMII mode.

Signed-off-by: Siddharth Vadapalli <s-vadapa...@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;
        }
-- 
2.34.1

Reply via email to