diff mbox series

[net-next,14/15] net: mvpp2: set the XPCS and MPCS in reset when not used

Message ID 20190228132128.30154-15-antoine.tenart@bootlin.com
State Changes Requested
Delegated to: David Miller
Headers show
Series net: mvpp2: fixes and improvements | expand

Commit Message

Antoine Tenart Feb. 28, 2019, 1:21 p.m. UTC
This patch sets both the XPCS and MPCS blocks in reset when they aren't
used. This is done both at boot time and when reconfiguring a port mode.
The advantage now is that only the PCS used is set out of reset when the
port is configured (10GKR uses the MCPS while RXAUI uses the XPCS).

Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
---
 drivers/net/ethernet/marvell/mvpp2/mvpp2.h    |  1 +
 .../net/ethernet/marvell/mvpp2/mvpp2_main.c   | 62 ++++++++++++++++---
 2 files changed, 55 insertions(+), 8 deletions(-)

Comments

David Miller Feb. 28, 2019, 6:40 p.m. UTC | #1
From: Antoine Tenart <antoine.tenart@bootlin.com>
Date: Thu, 28 Feb 2019 14:21:27 +0100

> +static void mvpp22_pcs_reset(struct mvpp2_port *port)
> +{
> +	struct mvpp2 *priv = port->priv;
> +	void __iomem *mpcs = priv->iface_base + MVPP22_MPCS_BASE(port->gop_id);
> +	void __iomem *xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);
> +	u32 val;

Reverse christmas tree please.

 ...
> +static void mvpp22_pcs_unreset(struct mvpp2_port *port)
> +{
> +	struct mvpp2 *priv = port->priv;
> +	void __iomem *mpcs = priv->iface_base + MVPP22_MPCS_BASE(port->gop_id);
> +	void __iomem *xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);
> +	u32 val;

Likewise.
Antoine Tenart Feb. 28, 2019, 9:23 p.m. UTC | #2
Hi David,

On Thu, Feb 28, 2019 at 10:40:51AM -0800, David Miller wrote:
> From: Antoine Tenart <antoine.tenart@bootlin.com>
> Date: Thu, 28 Feb 2019 14:21:27 +0100
> 
> > +static void mvpp22_pcs_reset(struct mvpp2_port *port)
> > +{
> > +	struct mvpp2 *priv = port->priv;
> > +	void __iomem *mpcs = priv->iface_base + MVPP22_MPCS_BASE(port->gop_id);
> > +	void __iomem *xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);
> > +	u32 val;
> 
> Reverse christmas tree please.
> 
>  ...
> > +static void mvpp22_pcs_unreset(struct mvpp2_port *port)
> > +{
> > +	struct mvpp2 *priv = port->priv;
> > +	void __iomem *mpcs = priv->iface_base + MVPP22_MPCS_BASE(port->gop_id);
> > +	void __iomem *xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);
> > +	u32 val;
> 
> Likewise.

Right. But here we do need priv to be assigned first in order to assign
mpcs and xpcs. Do you want the pointer definition and assignment to be
in two steps to respect the christmas tree rule or is it acceptable in
such situations?

Thanks!
Antoine
David Miller Feb. 28, 2019, 9:45 p.m. UTC | #3
From: Antoine Tenart <antoine.tenart@bootlin.com>
Date: Thu, 28 Feb 2019 22:23:12 +0100

> Right. But here we do need priv to be assigned first in order to assign
> mpcs and xpcs.

Then put the latter assignments into the body of the function.
diff mbox series

Patch

diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
index c9edeac9ec01..ff0f4c503f53 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
@@ -483,6 +483,7 @@ 
 /* XPCS registers. PPv2.2 only */
 #define MVPP22_XPCS_BASE(port)			(0x7400 + (port) * 0x1000)
 #define MVPP22_XPCS_CFG0			0x0
+#define     MVPP22_XPCS_CFG0_RESET_DIS		BIT(0)
 #define     MVPP22_XPCS_CFG0_PCS_MODE(n)	((n) << 3)
 #define     MVPP22_XPCS_CFG0_ACTIVE_LANE(n)	((n) << 5)
 
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 36e709a4e7d9..29d32cb3d52b 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -1016,27 +1016,20 @@  static void mvpp22_gop_init_10gkr(struct mvpp2_port *port)
 	void __iomem *xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);
 	u32 val;
 
-	/* XPCS */
 	val = readl(xpcs + MVPP22_XPCS_CFG0);
 	val &= ~(MVPP22_XPCS_CFG0_PCS_MODE(0x3) |
 		 MVPP22_XPCS_CFG0_ACTIVE_LANE(0x3));
 	val |= MVPP22_XPCS_CFG0_ACTIVE_LANE(2);
 	writel(val, xpcs + MVPP22_XPCS_CFG0);
 
-	/* MPCS */
 	val = readl(mpcs + MVPP22_MPCS_CTRL);
 	val &= ~MVPP22_MPCS_CTRL_FWD_ERR_CONN;
 	writel(val, mpcs + MVPP22_MPCS_CTRL);
 
 	val = readl(mpcs + MVPP22_MPCS_CLK_RESET);
-	val &= ~(MVPP22_MPCS_CLK_RESET_DIV_RATIO(0x7) | MAC_CLK_RESET_MAC |
-		 MAC_CLK_RESET_SD_RX | MAC_CLK_RESET_SD_TX);
+	val &= ~MVPP22_MPCS_CLK_RESET_DIV_RATIO(0x7);
 	val |= MVPP22_MPCS_CLK_RESET_DIV_RATIO(1);
 	writel(val, mpcs + MVPP22_MPCS_CLK_RESET);
-
-	val &= ~MVPP22_MPCS_CLK_RESET_DIV_SET;
-	val |= MAC_CLK_RESET_MAC | MAC_CLK_RESET_SD_RX | MAC_CLK_RESET_SD_TX;
-	writel(val, mpcs + MVPP22_MPCS_CLK_RESET);
 }
 
 static int mvpp22_gop_init(struct mvpp2_port *port)
@@ -1385,6 +1378,53 @@  static void mvpp2_mac_reset(struct mvpp2_port *port)
 	}
 }
 
+static void mvpp22_pcs_reset(struct mvpp2_port *port)
+{
+	struct mvpp2 *priv = port->priv;
+	void __iomem *mpcs = priv->iface_base + MVPP22_MPCS_BASE(port->gop_id);
+	void __iomem *xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);
+	u32 val;
+
+	if (port->priv->hw_version != MVPP22 || port->gop_id != 0)
+		return;
+
+	val = readl(mpcs + MVPP22_MPCS_CLK_RESET);
+	val &= ~(MAC_CLK_RESET_MAC | MAC_CLK_RESET_SD_RX | MAC_CLK_RESET_SD_TX);
+	val |= MVPP22_MPCS_CLK_RESET_DIV_SET;
+	writel(val, mpcs + MVPP22_MPCS_CLK_RESET);
+
+	val = readl(xpcs + MVPP22_XPCS_CFG0);
+	writel(val & ~MVPP22_XPCS_CFG0_RESET_DIS, xpcs + MVPP22_XPCS_CFG0);
+}
+
+static void mvpp22_pcs_unreset(struct mvpp2_port *port)
+{
+	struct mvpp2 *priv = port->priv;
+	void __iomem *mpcs = priv->iface_base + MVPP22_MPCS_BASE(port->gop_id);
+	void __iomem *xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);
+	u32 val;
+
+	if (port->priv->hw_version != MVPP22 || port->gop_id != 0)
+		return;
+
+	switch (port->phy_interface) {
+	case PHY_INTERFACE_MODE_10GKR:
+		val = readl(mpcs + MVPP22_MPCS_CLK_RESET);
+		val |= MAC_CLK_RESET_MAC | MAC_CLK_RESET_SD_RX |
+		       MAC_CLK_RESET_SD_TX;
+		val &= ~MVPP22_MPCS_CLK_RESET_DIV_SET;
+		writel(val, mpcs + MVPP22_MPCS_CLK_RESET);
+		break;
+	case PHY_INTERFACE_MODE_XAUI:
+	case PHY_INTERFACE_MODE_RXAUI:
+		val = readl(xpcs + MVPP22_XPCS_CFG0);
+		writel(val | MVPP22_XPCS_CFG0_RESET_DIS, xpcs + MVPP22_XPCS_CFG0);
+		break;
+	default:
+		break;
+	}
+}
+
 /* Change maximum receive size of the port */
 static inline void mvpp2_gmac_max_rx_size_set(struct mvpp2_port *port)
 {
@@ -3140,12 +3180,17 @@  static void mvpp22_mode_reconfigure(struct mvpp2_port *port)
 	/* Set the GMAC & XLG MAC in reset */
 	mvpp2_mac_reset(port);
 
+	/* Set the MPCS and XPCS in reset */
+	mvpp22_pcs_reset(port);
+
 	/* comphy reconfiguration */
 	mvpp22_comphy_init(port);
 
 	/* gop reconfiguration */
 	mvpp22_gop_init(port);
 
+	mvpp22_pcs_unreset(port);
+
 	/* Only GOP port 0 has an XLG MAC */
 	if (port->gop_id == 0) {
 		ctrl3 = readl(port->base + MVPP22_XLG_CTRL3_REG);
@@ -4960,6 +5005,7 @@  static int mvpp2_port_probe(struct platform_device *pdev,
 	mvpp2_port_periodic_xon_disable(port);
 
 	mvpp2_mac_reset(port);
+	mvpp22_pcs_reset(port);
 
 	port->pcpu = alloc_percpu(struct mvpp2_port_pcpu);
 	if (!port->pcpu) {