Hi all,
This series adds 1000BaseX and 2500BaseX support to the Marvell PPv2
driver. In order to use it, the 2.5 SGMII mode is added in the Marvell
common PHY driver (cp110-comphy).
This was tested on a mcbin.
All patches should probably go through net-next as patch 4/4 depends on
patch 1/4 to build and work.
Please note the two mvpp2 patches do not conflict with the ACPI series
v2 Marcin sent a few days ago, and the two series can be processed in
parallel. (Marcin is aware of me sending this series).
Thanks!
Antoine
Since v4:
- Fixed a compilation warning which was a real error in the code.
Since v3:
- Stopped setting the MII_SPEED bit in the GMAC AN register, as the
GMII_SPEED bit takes over anyway.
- Added Andrew's Reviewed-by on patch 4/4.
Since v2:
- Added a comment before mvpp22_comphy_init() about the different PHY modes
used and why they differ between the PPv2 driver and the COMPHY one.
Since v1:
- s/PHY_MODE_SGMII_2_5G/PHY_MODE_2500SGMII/
- Fixed a build error in 'net: mvpp2: 1000baseX support' (which was solved in
the 2500baseX support one, but the bisection was broken).
- Removed the dt patches, as the fourth network interface on the mcbin also
needs PHYLINK support in the PPv2 driver to be correctly supported.
Antoine Tenart (4):
phy: add 2.5G SGMII mode to the phy_mode enum
phy: cp110-comphy: 2.5G SGMII mode
net: mvpp2: 1000baseX support
net: mvpp2: 2500baseX support
drivers/net/ethernet/marvell/mvpp2.c | 74 ++++++++++++++++++++++++----
drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 17 +++++--
include/linux/phy/phy.h | 1 +
3 files changed, 79 insertions(+), 13 deletions(-)
--
2.14.3
This patch allow the CP100 comphy to configure some lanes in the
2.5G SGMII mode. This mode is quite close to SGMII and uses nearly the
same code path.
Signed-off-by: Antoine Tenart <[email protected]>
---
drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
index a0d522154cdf..4ef429250d7b 100644
--- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
+++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
@@ -135,19 +135,25 @@ struct mvebu_comhy_conf {
static const struct mvebu_comhy_conf mvebu_comphy_cp110_modes[] = {
/* lane 0 */
MVEBU_COMPHY_CONF(0, 1, PHY_MODE_SGMII, 0x1),
+ MVEBU_COMPHY_CONF(0, 1, PHY_MODE_2500SGMII, 0x1),
/* lane 1 */
MVEBU_COMPHY_CONF(1, 2, PHY_MODE_SGMII, 0x1),
+ MVEBU_COMPHY_CONF(1, 2, PHY_MODE_2500SGMII, 0x1),
/* lane 2 */
MVEBU_COMPHY_CONF(2, 0, PHY_MODE_SGMII, 0x1),
+ MVEBU_COMPHY_CONF(2, 0, PHY_MODE_2500SGMII, 0x1),
MVEBU_COMPHY_CONF(2, 0, PHY_MODE_10GKR, 0x1),
/* lane 3 */
MVEBU_COMPHY_CONF(3, 1, PHY_MODE_SGMII, 0x2),
+ MVEBU_COMPHY_CONF(3, 1, PHY_MODE_2500SGMII, 0x2),
/* lane 4 */
MVEBU_COMPHY_CONF(4, 0, PHY_MODE_SGMII, 0x2),
+ MVEBU_COMPHY_CONF(4, 0, PHY_MODE_2500SGMII, 0x2),
MVEBU_COMPHY_CONF(4, 0, PHY_MODE_10GKR, 0x2),
MVEBU_COMPHY_CONF(4, 1, PHY_MODE_SGMII, 0x1),
/* lane 5 */
MVEBU_COMPHY_CONF(5, 2, PHY_MODE_SGMII, 0x1),
+ MVEBU_COMPHY_CONF(5, 2, PHY_MODE_2500SGMII, 0x1),
};
struct mvebu_comphy_priv {
@@ -206,6 +212,10 @@ static void mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane,
if (mode == PHY_MODE_10GKR)
val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xe) |
MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xe);
+ else if (mode == PHY_MODE_2500SGMII)
+ val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x8) |
+ MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x8) |
+ MVEBU_COMPHY_SERDES_CFG0_HALF_BUS;
else if (mode == PHY_MODE_SGMII)
val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x6) |
MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x6) |
@@ -296,13 +306,13 @@ static int mvebu_comphy_init_plls(struct mvebu_comphy_lane *lane,
return 0;
}
-static int mvebu_comphy_set_mode_sgmii(struct phy *phy)
+static int mvebu_comphy_set_mode_sgmii(struct phy *phy, enum phy_mode mode)
{
struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
struct mvebu_comphy_priv *priv = lane->priv;
u32 val;
- mvebu_comphy_ethernet_init_reset(lane, PHY_MODE_SGMII);
+ mvebu_comphy_ethernet_init_reset(lane, mode);
val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
val &= ~MVEBU_COMPHY_RX_CTRL1_CLK8T_EN;
@@ -487,7 +497,8 @@ static int mvebu_comphy_power_on(struct phy *phy)
switch (lane->mode) {
case PHY_MODE_SGMII:
- ret = mvebu_comphy_set_mode_sgmii(phy);
+ case PHY_MODE_2500SGMII:
+ ret = mvebu_comphy_set_mode_sgmii(phy, lane->mode);
break;
case PHY_MODE_10GKR:
ret = mvebu_comphy_set_mode_10gkr(phy);
--
2.14.3
This patch adds the 2500Base-X PHY mode support in the Marvell PPv2
driver. 2500Base-X is quite close to 1000Base-X and SGMII modes and uses
nearly the same code path.
Signed-off-by: Antoine Tenart <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
---
drivers/net/ethernet/marvell/mvpp2.c | 49 ++++++++++++++++++++++++++++--------
1 file changed, 39 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index 257a6b99b4ca..38f9a79481c6 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -4502,6 +4502,7 @@ static int mvpp22_gop_init(struct mvpp2_port *port)
break;
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_1000BASEX:
+ case PHY_INTERFACE_MODE_2500BASEX:
mvpp22_gop_init_sgmii(port);
break;
case PHY_INTERFACE_MODE_10GKR:
@@ -4540,7 +4541,8 @@ static void mvpp22_gop_unmask_irq(struct mvpp2_port *port)
if (phy_interface_mode_is_rgmii(port->phy_interface) ||
port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
- port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
+ port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+ port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) {
/* Enable the GMAC link status irq for this port */
val = readl(port->base + MVPP22_GMAC_INT_SUM_MASK);
val |= MVPP22_GMAC_INT_SUM_MASK_LINK_STAT;
@@ -4571,7 +4573,8 @@ static void mvpp22_gop_mask_irq(struct mvpp2_port *port)
if (phy_interface_mode_is_rgmii(port->phy_interface) ||
port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
- port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
+ port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+ port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) {
val = readl(port->base + MVPP22_GMAC_INT_SUM_MASK);
val &= ~MVPP22_GMAC_INT_SUM_MASK_LINK_STAT;
writel(val, port->base + MVPP22_GMAC_INT_SUM_MASK);
@@ -4584,7 +4587,8 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port)
if (phy_interface_mode_is_rgmii(port->phy_interface) ||
port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
- port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
+ port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+ port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) {
val = readl(port->base + MVPP22_GMAC_INT_MASK);
val |= MVPP22_GMAC_INT_MASK_LINK_STAT;
writel(val, port->base + MVPP22_GMAC_INT_MASK);
@@ -4599,6 +4603,16 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port)
mvpp22_gop_unmask_irq(port);
}
+/* Sets the PHY mode of the COMPHY (which configures the serdes lanes).
+ *
+ * The PHY mode used by the PPv2 driver comes from the network subsystem, while
+ * the one given to the COMPHY comes from the generic PHY subsystem. Hence they
+ * differ.
+ *
+ * The COMPHY configures the serdes lanes regardless of the actual use of the
+ * lanes by the physical layer. This is why configurations like
+ * "PPv2 (2500BaseX) - COMPHY (2500SGMII)" are valid.
+ */
static int mvpp22_comphy_init(struct mvpp2_port *port)
{
enum phy_mode mode;
@@ -4612,6 +4626,9 @@ static int mvpp22_comphy_init(struct mvpp2_port *port)
case PHY_INTERFACE_MODE_1000BASEX:
mode = PHY_MODE_SGMII;
break;
+ case PHY_INTERFACE_MODE_2500BASEX:
+ mode = PHY_MODE_2500SGMII;
+ break;
case PHY_INTERFACE_MODE_10GKR:
mode = PHY_MODE_10GKR;
break;
@@ -4631,7 +4648,8 @@ static void mvpp2_port_mii_gmac_configure_mode(struct mvpp2_port *port)
u32 val;
if (port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
- port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
+ port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+ port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) {
val = readl(port->base + MVPP22_GMAC_CTRL_4_REG);
val |= MVPP22_CTRL4_SYNC_BYPASS_DIS | MVPP22_CTRL4_DP_CLK_SEL |
MVPP22_CTRL4_QSGMII_BYPASS_ACTIVE;
@@ -4647,7 +4665,8 @@ static void mvpp2_port_mii_gmac_configure_mode(struct mvpp2_port *port)
}
val = readl(port->base + MVPP2_GMAC_CTRL_0_REG);
- if (port->phy_interface == PHY_INTERFACE_MODE_1000BASEX)
+ if (port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+ port->phy_interface == PHY_INTERFACE_MODE_2500BASEX)
val |= MVPP2_GMAC_PORT_TYPE_MASK;
else
val &= ~MVPP2_GMAC_PORT_TYPE_MASK;
@@ -4660,7 +4679,13 @@ static void mvpp2_port_mii_gmac_configure_mode(struct mvpp2_port *port)
if (port->phy_interface == PHY_INTERFACE_MODE_SGMII)
val |= MVPP2_GMAC_IN_BAND_AUTONEG;
- if (port->phy_interface == PHY_INTERFACE_MODE_1000BASEX)
+ /* Clear all fields we may want to explicitly set below */
+ val &= ~(MVPP2_GMAC_CONFIG_FULL_DUPLEX | MVPP2_GMAC_CONFIG_GMII_SPEED |
+ MVPP2_GMAC_CONFIG_MII_SPEED | MVPP2_GMAC_AN_SPEED_EN |
+ MVPP2_GMAC_AN_DUPLEX_EN);
+
+ if (port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+ port->phy_interface == PHY_INTERFACE_MODE_2500BASEX)
/* 1000BaseX port cannot negotiate speed nor can it
* negotiate duplex: they are always operating with a
* fixed speed of 1000Mbps in full duplex, so force
@@ -4693,7 +4718,8 @@ static void mvpp2_port_mii_gmac_configure(struct mvpp2_port *port)
/* Configure the PCS and in-band AN */
val = readl(port->base + MVPP2_GMAC_CTRL_2_REG);
if (port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
- port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
+ port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+ port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) {
val |= MVPP2_GMAC_INBAND_AN_MASK | MVPP2_GMAC_PCS_ENABLE_MASK;
} else if (phy_interface_mode_is_rgmii(port->phy_interface)) {
val &= ~MVPP2_GMAC_PCS_ENABLE_MASK;
@@ -4756,7 +4782,8 @@ static void mvpp2_port_mii_set(struct mvpp2_port *port)
if (phy_interface_mode_is_rgmii(port->phy_interface) ||
port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
- port->phy_interface == PHY_INTERFACE_MODE_1000BASEX)
+ port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+ port->phy_interface == PHY_INTERFACE_MODE_2500BASEX)
mvpp2_port_mii_gmac_configure(port);
else if (port->phy_interface == PHY_INTERFACE_MODE_10GKR)
mvpp2_port_mii_xlg_configure(port);
@@ -4834,7 +4861,8 @@ static void mvpp2_port_loopback_set(struct mvpp2_port *port)
val &= ~MVPP2_GMAC_GMII_LB_EN_MASK;
if (port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
- port->phy_interface == PHY_INTERFACE_MODE_1000BASEX)
+ port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+ port->phy_interface == PHY_INTERFACE_MODE_2500BASEX)
val |= MVPP2_GMAC_PCS_LB_EN_MASK;
else
val &= ~MVPP2_GMAC_PCS_LB_EN_MASK;
@@ -6048,7 +6076,8 @@ static irqreturn_t mvpp2_link_status_isr(int irq, void *dev_id)
}
} else if (phy_interface_mode_is_rgmii(port->phy_interface) ||
port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
- port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
+ port->phy_interface == PHY_INTERFACE_MODE_1000BASEX ||
+ port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) {
val = readl(port->base + MVPP22_GMAC_INT_STAT);
if (val & MVPP22_GMAC_INT_STAT_LINK) {
event = true;
--
2.14.3
This patch adds the 1000Base-X PHY mode support in the Marvell PPv2
driver. 1000Base-X is quite close the SGMII and uses nearly the same
code path.
Signed-off-by: Antoine Tenart <[email protected]>
---
drivers/net/ethernet/marvell/mvpp2.c | 45 ++++++++++++++++++++++++++++--------
1 file changed, 35 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index a19760736b71..257a6b99b4ca 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -4501,6 +4501,7 @@ static int mvpp22_gop_init(struct mvpp2_port *port)
mvpp22_gop_init_rgmii(port);
break;
case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_1000BASEX:
mvpp22_gop_init_sgmii(port);
break;
case PHY_INTERFACE_MODE_10GKR:
@@ -4538,7 +4539,8 @@ static void mvpp22_gop_unmask_irq(struct mvpp2_port *port)
u32 val;
if (phy_interface_mode_is_rgmii(port->phy_interface) ||
- port->phy_interface == PHY_INTERFACE_MODE_SGMII) {
+ port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
+ port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
/* Enable the GMAC link status irq for this port */
val = readl(port->base + MVPP22_GMAC_INT_SUM_MASK);
val |= MVPP22_GMAC_INT_SUM_MASK_LINK_STAT;
@@ -4568,7 +4570,8 @@ static void mvpp22_gop_mask_irq(struct mvpp2_port *port)
}
if (phy_interface_mode_is_rgmii(port->phy_interface) ||
- port->phy_interface == PHY_INTERFACE_MODE_SGMII) {
+ port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
+ port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
val = readl(port->base + MVPP22_GMAC_INT_SUM_MASK);
val &= ~MVPP22_GMAC_INT_SUM_MASK_LINK_STAT;
writel(val, port->base + MVPP22_GMAC_INT_SUM_MASK);
@@ -4580,7 +4583,8 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port)
u32 val;
if (phy_interface_mode_is_rgmii(port->phy_interface) ||
- port->phy_interface == PHY_INTERFACE_MODE_SGMII) {
+ port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
+ port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
val = readl(port->base + MVPP22_GMAC_INT_MASK);
val |= MVPP22_GMAC_INT_MASK_LINK_STAT;
writel(val, port->base + MVPP22_GMAC_INT_MASK);
@@ -4605,6 +4609,7 @@ static int mvpp22_comphy_init(struct mvpp2_port *port)
switch (port->phy_interface) {
case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_1000BASEX:
mode = PHY_MODE_SGMII;
break;
case PHY_INTERFACE_MODE_10GKR:
@@ -4625,7 +4630,8 @@ static void mvpp2_port_mii_gmac_configure_mode(struct mvpp2_port *port)
{
u32 val;
- if (port->phy_interface == PHY_INTERFACE_MODE_SGMII) {
+ if (port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
+ port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
val = readl(port->base + MVPP22_GMAC_CTRL_4_REG);
val |= MVPP22_CTRL4_SYNC_BYPASS_DIS | MVPP22_CTRL4_DP_CLK_SEL |
MVPP22_CTRL4_QSGMII_BYPASS_ACTIVE;
@@ -4640,9 +4646,11 @@ static void mvpp2_port_mii_gmac_configure_mode(struct mvpp2_port *port)
writel(val, port->base + MVPP22_GMAC_CTRL_4_REG);
}
- /* The port is connected to a copper PHY */
val = readl(port->base + MVPP2_GMAC_CTRL_0_REG);
- val &= ~MVPP2_GMAC_PORT_TYPE_MASK;
+ if (port->phy_interface == PHY_INTERFACE_MODE_1000BASEX)
+ val |= MVPP2_GMAC_PORT_TYPE_MASK;
+ else
+ val &= ~MVPP2_GMAC_PORT_TYPE_MASK;
writel(val, port->base + MVPP2_GMAC_CTRL_0_REG);
val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG);
@@ -4651,6 +4659,19 @@ static void mvpp2_port_mii_gmac_configure_mode(struct mvpp2_port *port)
MVPP2_GMAC_AN_DUPLEX_EN;
if (port->phy_interface == PHY_INTERFACE_MODE_SGMII)
val |= MVPP2_GMAC_IN_BAND_AUTONEG;
+
+ if (port->phy_interface == PHY_INTERFACE_MODE_1000BASEX)
+ /* 1000BaseX port cannot negotiate speed nor can it
+ * negotiate duplex: they are always operating with a
+ * fixed speed of 1000Mbps in full duplex, so force
+ * 1000 speed and full duplex here.
+ */
+ val |= MVPP2_GMAC_CONFIG_GMII_SPEED |
+ MVPP2_GMAC_CONFIG_FULL_DUPLEX;
+ else
+ val |= MVPP2_GMAC_AN_SPEED_EN |
+ MVPP2_GMAC_AN_DUPLEX_EN;
+
writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
}
@@ -4671,7 +4692,8 @@ static void mvpp2_port_mii_gmac_configure(struct mvpp2_port *port)
/* Configure the PCS and in-band AN */
val = readl(port->base + MVPP2_GMAC_CTRL_2_REG);
- if (port->phy_interface == PHY_INTERFACE_MODE_SGMII) {
+ if (port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
+ port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
val |= MVPP2_GMAC_INBAND_AN_MASK | MVPP2_GMAC_PCS_ENABLE_MASK;
} else if (phy_interface_mode_is_rgmii(port->phy_interface)) {
val &= ~MVPP2_GMAC_PCS_ENABLE_MASK;
@@ -4733,7 +4755,8 @@ static void mvpp2_port_mii_set(struct mvpp2_port *port)
mvpp22_port_mii_set(port);
if (phy_interface_mode_is_rgmii(port->phy_interface) ||
- port->phy_interface == PHY_INTERFACE_MODE_SGMII)
+ port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
+ port->phy_interface == PHY_INTERFACE_MODE_1000BASEX)
mvpp2_port_mii_gmac_configure(port);
else if (port->phy_interface == PHY_INTERFACE_MODE_10GKR)
mvpp2_port_mii_xlg_configure(port);
@@ -4810,7 +4833,8 @@ static void mvpp2_port_loopback_set(struct mvpp2_port *port)
else
val &= ~MVPP2_GMAC_GMII_LB_EN_MASK;
- if (port->phy_interface == PHY_INTERFACE_MODE_SGMII)
+ if (port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
+ port->phy_interface == PHY_INTERFACE_MODE_1000BASEX)
val |= MVPP2_GMAC_PCS_LB_EN_MASK;
else
val &= ~MVPP2_GMAC_PCS_LB_EN_MASK;
@@ -6023,7 +6047,8 @@ static irqreturn_t mvpp2_link_status_isr(int irq, void *dev_id)
link = true;
}
} else if (phy_interface_mode_is_rgmii(port->phy_interface) ||
- port->phy_interface == PHY_INTERFACE_MODE_SGMII) {
+ port->phy_interface == PHY_INTERFACE_MODE_SGMII ||
+ port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
val = readl(port->base + MVPP22_GMAC_INT_STAT);
if (val & MVPP22_GMAC_INT_STAT_LINK) {
event = true;
--
2.14.3
This patch adds one more generic PHY mode to the phy_mode enum, to allow
configuring generic PHYs to the 2.5G SGMII mode by using the set_mode
callback.
Signed-off-by: Antoine Tenart <[email protected]>
---
include/linux/phy/phy.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 4f8423a948d5..5a80e9de3686 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -28,6 +28,7 @@ enum phy_mode {
PHY_MODE_USB_DEVICE,
PHY_MODE_USB_OTG,
PHY_MODE_SGMII,
+ PHY_MODE_2500SGMII,
PHY_MODE_10GKR,
PHY_MODE_UFS_HS_A,
PHY_MODE_UFS_HS_B,
--
2.14.3
From: Antoine Tenart <[email protected]>
Date: Fri, 12 Jan 2018 08:51:27 +0100
> This patch adds one more generic PHY mode to the phy_mode enum, to allow
> configuring generic PHYs to the 2.5G SGMII mode by using the set_mode
> callback.
>
> Signed-off-by: Antoine Tenart <[email protected]>
PHY layer folks, and reviews please?
> ---
> include/linux/phy/phy.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
> index 4f8423a948d5..5a80e9de3686 100644
> --- a/include/linux/phy/phy.h
> +++ b/include/linux/phy/phy.h
> @@ -28,6 +28,7 @@ enum phy_mode {
> PHY_MODE_USB_DEVICE,
> PHY_MODE_USB_OTG,
> PHY_MODE_SGMII,
> + PHY_MODE_2500SGMII,
> PHY_MODE_10GKR,
> PHY_MODE_UFS_HS_A,
> PHY_MODE_UFS_HS_B,
> --
> 2.14.3
>
On Tuesday 16 January 2018 12:51 AM, David Miller wrote:
> From: Antoine Tenart <[email protected]>
> Date: Fri, 12 Jan 2018 08:51:27 +0100
>
>> This patch adds one more generic PHY mode to the phy_mode enum, to allow
>> configuring generic PHYs to the 2.5G SGMII mode by using the set_mode
>> callback.
>>
>> Signed-off-by: Antoine Tenart <[email protected]>
Acked-by: Kishon Vijay Abraham I <[email protected]>
>
> PHY layer folks, and reviews please?
>
>> ---
>> include/linux/phy/phy.h | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
>> index 4f8423a948d5..5a80e9de3686 100644
>> --- a/include/linux/phy/phy.h
>> +++ b/include/linux/phy/phy.h
>> @@ -28,6 +28,7 @@ enum phy_mode {
>> PHY_MODE_USB_DEVICE,
>> PHY_MODE_USB_OTG,
>> PHY_MODE_SGMII,
>> + PHY_MODE_2500SGMII,
>> PHY_MODE_10GKR,
>> PHY_MODE_UFS_HS_A,
>> PHY_MODE_UFS_HS_B,
>> --
>> 2.14.3
>>
On Friday 12 January 2018 01:21 PM, Antoine Tenart wrote:
> This patch allow the CP100 comphy to configure some lanes in the
> 2.5G SGMII mode. This mode is quite close to SGMII and uses nearly the
> same code path.
>
> Signed-off-by: Antoine Tenart <[email protected]>
Acked-by: Kishon Vijay Abraham I <[email protected]>
> ---
> drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 17 ++++++++++++++---
> 1 file changed, 14 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
> index a0d522154cdf..4ef429250d7b 100644
> --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
> +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
> @@ -135,19 +135,25 @@ struct mvebu_comhy_conf {
> static const struct mvebu_comhy_conf mvebu_comphy_cp110_modes[] = {
> /* lane 0 */
> MVEBU_COMPHY_CONF(0, 1, PHY_MODE_SGMII, 0x1),
> + MVEBU_COMPHY_CONF(0, 1, PHY_MODE_2500SGMII, 0x1),
> /* lane 1 */
> MVEBU_COMPHY_CONF(1, 2, PHY_MODE_SGMII, 0x1),
> + MVEBU_COMPHY_CONF(1, 2, PHY_MODE_2500SGMII, 0x1),
> /* lane 2 */
> MVEBU_COMPHY_CONF(2, 0, PHY_MODE_SGMII, 0x1),
> + MVEBU_COMPHY_CONF(2, 0, PHY_MODE_2500SGMII, 0x1),
> MVEBU_COMPHY_CONF(2, 0, PHY_MODE_10GKR, 0x1),
> /* lane 3 */
> MVEBU_COMPHY_CONF(3, 1, PHY_MODE_SGMII, 0x2),
> + MVEBU_COMPHY_CONF(3, 1, PHY_MODE_2500SGMII, 0x2),
> /* lane 4 */
> MVEBU_COMPHY_CONF(4, 0, PHY_MODE_SGMII, 0x2),
> + MVEBU_COMPHY_CONF(4, 0, PHY_MODE_2500SGMII, 0x2),
> MVEBU_COMPHY_CONF(4, 0, PHY_MODE_10GKR, 0x2),
> MVEBU_COMPHY_CONF(4, 1, PHY_MODE_SGMII, 0x1),
> /* lane 5 */
> MVEBU_COMPHY_CONF(5, 2, PHY_MODE_SGMII, 0x1),
> + MVEBU_COMPHY_CONF(5, 2, PHY_MODE_2500SGMII, 0x1),
> };
>
> struct mvebu_comphy_priv {
> @@ -206,6 +212,10 @@ static void mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane,
> if (mode == PHY_MODE_10GKR)
> val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xe) |
> MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xe);
> + else if (mode == PHY_MODE_2500SGMII)
> + val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x8) |
> + MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x8) |
> + MVEBU_COMPHY_SERDES_CFG0_HALF_BUS;
> else if (mode == PHY_MODE_SGMII)
> val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x6) |
> MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x6) |
> @@ -296,13 +306,13 @@ static int mvebu_comphy_init_plls(struct mvebu_comphy_lane *lane,
> return 0;
> }
>
> -static int mvebu_comphy_set_mode_sgmii(struct phy *phy)
> +static int mvebu_comphy_set_mode_sgmii(struct phy *phy, enum phy_mode mode)
> {
> struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
> struct mvebu_comphy_priv *priv = lane->priv;
> u32 val;
>
> - mvebu_comphy_ethernet_init_reset(lane, PHY_MODE_SGMII);
> + mvebu_comphy_ethernet_init_reset(lane, mode);
>
> val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
> val &= ~MVEBU_COMPHY_RX_CTRL1_CLK8T_EN;
> @@ -487,7 +497,8 @@ static int mvebu_comphy_power_on(struct phy *phy)
>
> switch (lane->mode) {
> case PHY_MODE_SGMII:
> - ret = mvebu_comphy_set_mode_sgmii(phy);
> + case PHY_MODE_2500SGMII:
> + ret = mvebu_comphy_set_mode_sgmii(phy, lane->mode);
> break;
> case PHY_MODE_10GKR:
> ret = mvebu_comphy_set_mode_10gkr(phy);
>
On Fri, Jan 12, 2018 at 08:51:26AM +0100, Antoine Tenart wrote:
> Hi all,
>
> This series adds 1000BaseX and 2500BaseX support to the Marvell PPv2
> driver. In order to use it, the 2.5 SGMII mode is added in the Marvell
> common PHY driver (cp110-comphy).
>
> This was tested on a mcbin.
>
> All patches should probably go through net-next as patch 4/4 depends on
> patch 1/4 to build and work.
>
> Please note the two mvpp2 patches do not conflict with the ACPI series
> v2 Marcin sent a few days ago, and the two series can be processed in
> parallel. (Marcin is aware of me sending this series).
As I've already said, we need to make sure things are done in a similar
way for all netdev DT drivers that are hoping to switch to phylink.
The mvneta patches are now in net-next for this.
What I can see is that there's a stark difference between mvpp2 and
mvneta and their handling of the "link irq" aka inband autonegotiation
status.
mvneta requires 'managed = "in-band-status";' to use the results of
the gmac negotiation otherwise inband AN is disabled. As phylink was
developed against mvneta, phylink requires that for Base-X modes.
So, in order to be compatible with mvneta and to do what phylink expects,
specifying 'managed = "in-band-status";' is a requirement for Base-X
modes, and having that in place _now_ will make the transition to
phylink easier without creating the need to update DT when that change
happens.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up
Hi Russell,
On Tue, Jan 16, 2018 at 03:12:45PM +0000, Russell King - ARM Linux wrote:
>
> As I've already said, we need to make sure things are done in a similar
> way for all netdev DT drivers that are hoping to switch to phylink.
> The mvneta patches are now in net-next for this.
>
> What I can see is that there's a stark difference between mvpp2 and
> mvneta and their handling of the "link irq" aka inband autonegotiation
> status.
>
> mvneta requires 'managed = "in-band-status";' to use the results of
> the gmac negotiation otherwise inband AN is disabled. As phylink was
> developed against mvneta, phylink requires that for Base-X modes.
>
> So, in order to be compatible with mvneta and to do what phylink expects,
> specifying 'managed = "in-band-status";' is a requirement for Base-X
> modes, and having that in place _now_ will make the transition to
> phylink easier without creating the need to update DT when that change
> happens.
Yes, we should aim for similar bindings and not having all drivers doing
their own way. Part of the PPv2 move to phylink will be to rework the
"link irq" to match what phylink expect, and I think we all agree on
this. Part of this will be to update the dt of the 7k-db and 8k-db, as
they're the two boards currently using the "link irq" in mainline.
I don't mind too much keeping these base-X patches out-of-tree for now,
and to send them as part of the phylink series during the next cycle.
I don't quite get the reason not to take them now, as they do not
modify any DT-related part. Or do you fear this would allow others to
send DT patches before the PPv2 move to phylink lands in?
Thanks,
Antoine
--
Antoine T?nart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com