net: mvpp2: rework the XLG MAC reset handling
authorAntoine Tenart <antoine.tenart@bootlin.com>
Fri, 1 Mar 2019 10:52:14 +0000 (11:52 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sat, 2 Mar 2019 07:23:35 +0000 (23:23 -0800)
This patch reworks the way the XLG MAC is set in reset: the XLG MAC is
set in reset at probe time and taken out of this state only when used.
The idea is to move forward a situation where only the blocks used are
taken out of reset. This also has the effect to handle the GMAC and the
XLG MAC in a similar way (the GMAC already is set in reset at boot
time).

Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c

index ba40b06d3ca39f1d9859c9c01118e9c550d5d863..c64ddad6b2b3570967fbb437f16e590b30e882bd 100644 (file)
@@ -1188,8 +1188,7 @@ static void mvpp2_port_enable(struct mvpp2_port *port)
        /* Only GOP port 0 has an XLG MAC */
        if (port->gop_id == 0 && mvpp2_is_xlg(port->phy_interface)) {
                val = readl(port->base + MVPP22_XLG_CTRL0_REG);
-               val |= MVPP22_XLG_CTRL0_PORT_EN |
-                      MVPP22_XLG_CTRL0_MAC_RESET_DIS;
+               val |= MVPP22_XLG_CTRL0_PORT_EN;
                val &= ~MVPP22_XLG_CTRL0_MIB_CNT_DIS;
                writel(val, port->base + MVPP22_XLG_CTRL0_REG);
        } else {
@@ -1209,10 +1208,6 @@ static void mvpp2_port_disable(struct mvpp2_port *port)
                val = readl(port->base + MVPP22_XLG_CTRL0_REG);
                val &= ~MVPP22_XLG_CTRL0_PORT_EN;
                writel(val, port->base + MVPP22_XLG_CTRL0_REG);
-
-               /* Disable & reset should be done separately */
-               val &= ~MVPP22_XLG_CTRL0_MAC_RESET_DIS;
-               writel(val, port->base + MVPP22_XLG_CTRL0_REG);
        }
 
        val = readl(port->base + MVPP2_GMAC_CTRL_0_REG);
@@ -1369,10 +1364,10 @@ static int mvpp2_ethtool_get_sset_count(struct net_device *dev, int sset)
        return -EOPNOTSUPP;
 }
 
-static void mvpp2_port_reset(struct mvpp2_port *port)
+static void mvpp2_mac_reset_assert(struct mvpp2_port *port)
 {
-       u32 val;
        unsigned int i;
+       u32 val;
 
        /* Read the GOP statistics to reset the hardware counters */
        for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_regs); i++)
@@ -1381,6 +1376,12 @@ static void mvpp2_port_reset(struct mvpp2_port *port)
        val = readl(port->base + MVPP2_GMAC_CTRL_2_REG) |
              MVPP2_GMAC_PORT_RESET_MASK;
        writel(val, port->base + MVPP2_GMAC_CTRL_2_REG);
+
+       if (port->priv->hw_version == MVPP22 && port->gop_id == 0) {
+               val = readl(port->base + MVPP22_XLG_CTRL0_REG) &
+                     ~MVPP22_XLG_CTRL0_MAC_RESET_DIS;
+               writel(val, port->base + MVPP22_XLG_CTRL0_REG);
+       }
 }
 
 /* Change maximum receive size of the port */
@@ -4511,6 +4512,8 @@ static void mvpp2_xlg_config(struct mvpp2_port *port, unsigned int mode,
        old_ctrl0 = ctrl0 = readl(port->base + MVPP22_XLG_CTRL0_REG);
        old_ctrl4 = ctrl4 = readl(port->base + MVPP22_XLG_CTRL4_REG);
 
+       ctrl0 |= MVPP22_XLG_CTRL0_MAC_RESET_DIS;
+
        if (state->pause & MLO_PAUSE_TX)
                ctrl0 |= MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN;
        else
@@ -4529,6 +4532,12 @@ static void mvpp2_xlg_config(struct mvpp2_port *port, unsigned int mode,
                writel(ctrl0, port->base + MVPP22_XLG_CTRL0_REG);
        if (old_ctrl4 != ctrl4)
                writel(ctrl4, port->base + MVPP22_XLG_CTRL4_REG);
+
+       if (!(old_ctrl0 & MVPP22_XLG_CTRL0_MAC_RESET_DIS)) {
+               while (!(readl(port->base + MVPP22_XLG_CTRL0_REG) &
+                        MVPP22_XLG_CTRL0_MAC_RESET_DIS))
+                       continue;
+       }
 }
 
 static void mvpp2_gmac_config(struct mvpp2_port *port, unsigned int mode,
@@ -4946,7 +4955,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 
        mvpp2_port_periodic_xon_disable(port);
 
-       mvpp2_port_reset(port);
+       mvpp2_mac_reset_assert(port);
 
        port->pcpu = alloc_percpu(struct mvpp2_port_pcpu);
        if (!port->pcpu) {