drivers: net: fsl_enetc: add support for SGMII 2500
authorAlex Marginean <alexm.osslist@gmail.com>
Mon, 15 Jul 2019 08:48:47 +0000 (11:48 +0300)
committerJoe Hershberger <joe.hershberger@ni.com>
Thu, 25 Jul 2019 18:13:30 +0000 (13:13 -0500)
SGMII 2500 as supported on NXP SoCs requires AN to be disabled, handle
this case in the enetc sgmii init code.

Signed-off-by: Alex Marginean <alexm.osslist@gmail.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
drivers/net/fsl_enetc.c
drivers/net/fsl_enetc.h

index da533a1e5dbbf0269282cfeaa4d68c11d2088df8..e7c5062c39ac7998d4cd4a9814e243bdad648ea9 100644 (file)
@@ -69,13 +69,25 @@ static bool enetc_has_imdio(struct udevice *dev)
 static int enetc_init_sgmii(struct udevice *dev)
 {
        struct enetc_priv *priv = dev_get_priv(dev);
+       bool is2500 = false;
+       u16 reg;
 
        if (!enetc_has_imdio(dev))
                return 0;
 
-       /* Set to SGMII mode, use AN */
+       if (priv->if_type == PHY_INTERFACE_MODE_SGMII_2500)
+               is2500 = true;
+
+       /*
+        * Set to SGMII mode, for 1Gbps enable AN, for 2.5Gbps set fixed speed.
+        * Although fixed speed is 1Gbps, we could be running at 2.5Gbps based
+        * on PLL configuration.  Setting 1G for 2.5G here is counter intuitive
+        * but intentional.
+        */
+       reg = ENETC_PCS_IF_MODE_SGMII;
+       reg |= is2500 ? ENETC_PCS_IF_MODE_SPEED_1G : ENETC_PCS_IF_MODE_SGMII_AN;
        enetc_mdio_write(&priv->imdio, ENETC_PCS_PHY_ADDR, MDIO_DEVAD_NONE,
-                        ENETC_PCS_IF_MODE, ENETC_PCS_IF_MODE_SGMII_AN);
+                        ENETC_PCS_IF_MODE, reg);
 
        /* Dev ability - SGMII */
        enetc_mdio_write(&priv->imdio, ENETC_PCS_PHY_ADDR, MDIO_DEVAD_NONE,
@@ -87,10 +99,11 @@ static int enetc_init_sgmii(struct udevice *dev)
        enetc_mdio_write(&priv->imdio, ENETC_PCS_PHY_ADDR, MDIO_DEVAD_NONE,
                         ENETC_PCS_LINK_TIMER2, ENETC_PCS_LINK_TIMER2_VAL);
 
+       reg = ENETC_PCS_CR_DEF_VAL;
+       reg |= is2500 ? ENETC_PCS_CR_RST : ENETC_PCS_CR_RESET_AN;
        /* restart PCS AN */
        enetc_mdio_write(&priv->imdio, ENETC_PCS_PHY_ADDR, MDIO_DEVAD_NONE,
-                        ENETC_PCS_CR,
-                        ENETC_PCS_CR_RESET_AN | ENETC_PCS_CR_DEF_VAL);
+                        ENETC_PCS_CR, reg);
 
        return 0;
 }
@@ -130,7 +143,7 @@ static int enetc_init_sxgmii(struct udevice *dev)
        /* Restart PCS AN */
        enetc_mdio_write(&priv->imdio, ENETC_PCS_PHY_ADDR, ENETC_PCS_DEVAD_REPL,
                         ENETC_PCS_CR,
-                        ENETC_PCS_CR_LANE_RESET | ENETC_PCS_CR_RESET_AN);
+                        ENETC_PCS_CR_RST | ENETC_PCS_CR_RESET_AN);
 
        return 0;
 }
@@ -174,6 +187,7 @@ static void enetc_start_pcs(struct udevice *dev)
 
        switch (priv->if_type) {
        case PHY_INTERFACE_MODE_SGMII:
+       case PHY_INTERFACE_MODE_SGMII_2500:
                enetc_init_sgmii(dev);
                break;
        case PHY_INTERFACE_MODE_RGMII:
index 7ac7c1fefeadc8cab43a8d0d1327274d56aa4ac1..0bb4cdff4794a99e7f20b11a666794d17b475baf 100644 (file)
@@ -183,7 +183,7 @@ struct enetc_priv {
 #define ENETC_PCS_CR                   0x00
 #define  ENETC_PCS_CR_RESET_AN         0x1200
 #define  ENETC_PCS_CR_DEF_VAL          0x0140
-#define  ENETC_PCS_CR_LANE_RESET       0x8000
+#define  ENETC_PCS_CR_RST              BIT(15)
 #define ENETC_PCS_DEV_ABILITY          0x04
 #define  ENETC_PCS_DEV_ABILITY_SGMII   0x4001
 #define  ENETC_PCS_DEV_ABILITY_SXGMII  0x5001
@@ -192,7 +192,9 @@ struct enetc_priv {
 #define ENETC_PCS_LINK_TIMER2          0x13
 #define  ENETC_PCS_LINK_TIMER2_VAL     0x0003
 #define ENETC_PCS_IF_MODE              0x14
-#define  ENETC_PCS_IF_MODE_SGMII_AN    0x0003
+#define  ENETC_PCS_IF_MODE_SGMII       BIT(0)
+#define  ENETC_PCS_IF_MODE_SGMII_AN    BIT(1)
+#define  ENETC_PCS_IF_MODE_SPEED_1G    BIT(3)
 
 /* PCS replicator block for USXGMII */
 #define ENETC_PCS_DEVAD_REPL           0x1f