net: mvpp2: set the XPCS and MPCS in reset when not used

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>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Antoine Tenart 2019-03-01 11:52:16 +01:00 committed by David S. Miller
parent 5434e8faf0
commit 7409e66e9e
2 changed files with 59 additions and 8 deletions

View File

@ -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)

View File

@ -1015,27 +1015,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)
@ -1384,6 +1377,57 @@ static void mvpp2_mac_reset_assert(struct mvpp2_port *port)
}
}
static void mvpp22_pcs_reset_assert(struct mvpp2_port *port)
{
struct mvpp2 *priv = port->priv;
void __iomem *mpcs, *xpcs;
u32 val;
if (port->priv->hw_version != MVPP22 || port->gop_id != 0)
return;
mpcs = priv->iface_base + MVPP22_MPCS_BASE(port->gop_id);
xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);
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_reset_deassert(struct mvpp2_port *port)
{
struct mvpp2 *priv = port->priv;
void __iomem *mpcs, *xpcs;
u32 val;
if (port->priv->hw_version != MVPP22 || port->gop_id != 0)
return;
mpcs = priv->iface_base + MVPP22_MPCS_BASE(port->gop_id);
xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);
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)
{
@ -3139,12 +3183,17 @@ static void mvpp22_mode_reconfigure(struct mvpp2_port *port)
/* Set the GMAC & XLG MAC in reset */
mvpp2_mac_reset_assert(port);
/* Set the MPCS and XPCS in reset */
mvpp22_pcs_reset_assert(port);
/* comphy reconfiguration */
mvpp22_comphy_init(port);
/* gop reconfiguration */
mvpp22_gop_init(port);
mvpp22_pcs_reset_deassert(port);
/* Only GOP port 0 has an XLG MAC */
if (port->gop_id == 0) {
ctrl3 = readl(port->base + MVPP22_XLG_CTRL3_REG);
@ -4959,6 +5008,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
mvpp2_port_periodic_xon_disable(port);
mvpp2_mac_reset_assert(port);
mvpp22_pcs_reset_assert(port);
port->pcpu = alloc_percpu(struct mvpp2_port_pcpu);
if (!port->pcpu) {