Commit 4c7ee010 authored by Vladimir Oltean's avatar Vladimir Oltean Committed by Jakub Kicinski

net: dsa: sja1105: the 0x1F0000 SGMII "base address" is actually MDIO_MMD_VEND2

Looking at the SGMII PCS from SJA1110, which is accessed indirectly
through a different base address as can be seen in the next patch, it
appears odd that the address accessed through indirection still
references the base address from the SJA1105S register map (first MDIO
register is at 0x1f0000), when it could index the SGMII registers
starting from zero.

Except that the 0x1f0000 is not a base address at all, it seems. It is
0x1f << 16 | 0x0000, and 0x1f is coding for the vendor-specific MMD2.
So, it turns out, the Synopsys PCS implements all its registers inside
the vendor-specific MMDs 1 and 2 (0x1e and 0x1f). This explains why the
PCS has no overlaps (for the other MMDs) with other register regions of
the switch (because no other MMDs are implemented).

Change the code to remove the SGMII "base address" and explicitly encode
the MMD for reads/writes. This will become necessary for SJA1110 support.

Cc: Russell King <linux@armlinux.org.uk>
Cc: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 84db00f2
...@@ -48,7 +48,6 @@ struct sja1105_regs { ...@@ -48,7 +48,6 @@ struct sja1105_regs {
u64 rgu; u64 rgu;
u64 vl_status; u64 vl_status;
u64 config; u64 config;
u64 sgmii;
u64 rmii_pll1; u64 rmii_pll1;
u64 ptppinst; u64 ptppinst;
u64 ptppindur; u64 ptppindur;
......
...@@ -898,36 +898,34 @@ static int sja1105_parse_dt(struct sja1105_private *priv, ...@@ -898,36 +898,34 @@ static int sja1105_parse_dt(struct sja1105_private *priv,
return rc; return rc;
} }
static int sja1105_sgmii_read(struct sja1105_private *priv, int port, static int sja1105_sgmii_read(struct sja1105_private *priv, int port, int mmd,
int pcs_reg) int pcs_reg)
{ {
const struct sja1105_regs *regs = priv->info->regs; u64 addr = (mmd << 16) | pcs_reg;
u32 val; u32 val;
int rc; int rc;
if (port != SJA1105_SGMII_PORT) if (port != SJA1105_SGMII_PORT)
return -ENODEV; return -ENODEV;
rc = sja1105_xfer_u32(priv, SPI_READ, regs->sgmii + pcs_reg, rc = sja1105_xfer_u32(priv, SPI_READ, addr, &val, NULL);
&val, NULL);
if (rc < 0) if (rc < 0)
return rc; return rc;
return val; return val;
} }
static int sja1105_sgmii_write(struct sja1105_private *priv, int port, static int sja1105_sgmii_write(struct sja1105_private *priv, int port, int mmd,
int pcs_reg, u16 pcs_val) int pcs_reg, u16 pcs_val)
{ {
const struct sja1105_regs *regs = priv->info->regs; u64 addr = (mmd << 16) | pcs_reg;
u32 val = pcs_val; u32 val = pcs_val;
int rc; int rc;
if (port != SJA1105_SGMII_PORT) if (port != SJA1105_SGMII_PORT)
return -ENODEV; return -ENODEV;
rc = sja1105_xfer_u32(priv, SPI_WRITE, regs->sgmii + pcs_reg, rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &val, NULL);
&val, NULL);
if (rc < 0) if (rc < 0)
return rc; return rc;
...@@ -943,24 +941,24 @@ static void sja1105_sgmii_pcs_config(struct sja1105_private *priv, int port, ...@@ -943,24 +941,24 @@ static void sja1105_sgmii_pcs_config(struct sja1105_private *priv, int port,
* stop the clock during LPI mode, make the MAC reconfigure * stop the clock during LPI mode, make the MAC reconfigure
* autonomously after PCS autoneg is done, flush the internal FIFOs. * autonomously after PCS autoneg is done, flush the internal FIFOs.
*/ */
sja1105_sgmii_write(priv, port, SJA1105_DC1, sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, SJA1105_DC1,
SJA1105_DC1_EN_VSMMD1 | SJA1105_DC1_EN_VSMMD1 |
SJA1105_DC1_CLOCK_STOP_EN | SJA1105_DC1_CLOCK_STOP_EN |
SJA1105_DC1_MAC_AUTO_SW | SJA1105_DC1_MAC_AUTO_SW |
SJA1105_DC1_INIT); SJA1105_DC1_INIT);
/* DIGITAL_CONTROL_2: No polarity inversion for TX and RX lanes */ /* DIGITAL_CONTROL_2: No polarity inversion for TX and RX lanes */
sja1105_sgmii_write(priv, port, SJA1105_DC2, sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, SJA1105_DC2,
SJA1105_DC2_TX_POL_INV_DISABLE); SJA1105_DC2_TX_POL_INV_DISABLE);
/* AUTONEG_CONTROL: Use SGMII autoneg */ /* AUTONEG_CONTROL: Use SGMII autoneg */
if (an_master) if (an_master)
ac |= SJA1105_AC_PHY_MODE | SJA1105_AC_SGMII_LINK; ac |= SJA1105_AC_PHY_MODE | SJA1105_AC_SGMII_LINK;
sja1105_sgmii_write(priv, port, SJA1105_AC, ac); sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, SJA1105_AC, ac);
/* BASIC_CONTROL: enable in-band AN now, if requested. Otherwise, /* BASIC_CONTROL: enable in-band AN now, if requested. Otherwise,
* sja1105_sgmii_pcs_force_speed must be called later for the link * sja1105_sgmii_pcs_force_speed must be called later for the link
* to become operational. * to become operational.
*/ */
if (an_enabled) if (an_enabled)
sja1105_sgmii_write(priv, port, MII_BMCR, sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1,
BMCR_ANENABLE | BMCR_ANRESTART); BMCR_ANENABLE | BMCR_ANRESTART);
} }
...@@ -983,7 +981,8 @@ static void sja1105_sgmii_pcs_force_speed(struct sja1105_private *priv, ...@@ -983,7 +981,8 @@ static void sja1105_sgmii_pcs_force_speed(struct sja1105_private *priv,
dev_err(priv->ds->dev, "Invalid speed %d\n", speed); dev_err(priv->ds->dev, "Invalid speed %d\n", speed);
return; return;
} }
sja1105_sgmii_write(priv, port, MII_BMCR, pcs_speed | BMCR_FULLDPLX); sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1,
pcs_speed | BMCR_FULLDPLX);
} }
/* Convert link speed from SJA1105 to ethtool encoding */ /* Convert link speed from SJA1105 to ethtool encoding */
...@@ -1201,7 +1200,7 @@ static int sja1105_mac_pcs_get_state(struct dsa_switch *ds, int port, ...@@ -1201,7 +1200,7 @@ static int sja1105_mac_pcs_get_state(struct dsa_switch *ds, int port,
int ais; int ais;
/* Read the vendor-specific AUTONEG_INTR_STATUS register */ /* Read the vendor-specific AUTONEG_INTR_STATUS register */
ais = sja1105_sgmii_read(priv, port, SJA1105_AIS); ais = sja1105_sgmii_read(priv, port, MDIO_MMD_VEND2, SJA1105_AIS);
if (ais < 0) if (ais < 0)
return ais; return ais;
...@@ -1905,7 +1904,9 @@ int sja1105_static_config_reload(struct sja1105_private *priv, ...@@ -1905,7 +1904,9 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
mac[i].speed = SJA1105_SPEED_AUTO; mac[i].speed = SJA1105_SPEED_AUTO;
if (sja1105_supports_sgmii(priv, i)) if (sja1105_supports_sgmii(priv, i))
bmcr[i] = sja1105_sgmii_read(priv, i, MII_BMCR); bmcr[i] = sja1105_sgmii_read(priv, i,
MDIO_MMD_VEND2,
MDIO_CTRL1);
} }
/* No PTP operations can run right now */ /* No PTP operations can run right now */
......
...@@ -440,7 +440,6 @@ static struct sja1105_regs sja1105pqrs_regs = { ...@@ -440,7 +440,6 @@ static struct sja1105_regs sja1105pqrs_regs = {
.pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808}, .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
.pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809}, .pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809},
.pad_mii_id = {0x100810, 0x100811, 0x100812, 0x100813, 0x100814}, .pad_mii_id = {0x100810, 0x100811, 0x100812, 0x100813, 0x100814},
.sgmii = 0x1F0000,
.rmii_pll1 = 0x10000A, .rmii_pll1 = 0x10000A,
.cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F}, .cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F},
.stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208}, .stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment