[PATCH v1 03/10] net: mvpp2: add 1000BaseX and 2500BaseX ppv2 support

Stefan Roese sr at denx.de
Tue Apr 27 15:27:10 CEST 2021


From: Stefan Chulski <stefanc at marvell.com>

Signed-off-by: Stefan Chulski <stefanc at marvell.com>
Signed-off-by: Stefan Roese <sr at denx.de>
---

 drivers/net/mvpp2.c | 117 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 112 insertions(+), 5 deletions(-)

diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c
index 015f5329de74..847007d5b487 100644
--- a/drivers/net/mvpp2.c
+++ b/drivers/net/mvpp2.c
@@ -2880,6 +2880,10 @@ static void mvpp2_port_mii_set(struct mvpp2_port *port)
 	case PHY_INTERFACE_MODE_SGMII:
 		val |= MVPP2_GMAC_INBAND_AN_MASK;
 		break;
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
+		val &= ~MVPP2_GMAC_INBAND_AN_MASK;
+		break;
 	case PHY_INTERFACE_MODE_RGMII:
 	case PHY_INTERFACE_MODE_RGMII_ID:
 		val |= MVPP2_GMAC_PORT_RGMII_MASK;
@@ -2940,7 +2944,9 @@ 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 ||
+	    port->phy_interface == PHY_INTERFACE_MODE_2500BASEX)
 		val |= MVPP2_GMAC_PCS_LB_EN_MASK;
 	else
 		val &= ~MVPP2_GMAC_PCS_LB_EN_MASK;
@@ -3051,10 +3057,10 @@ static void gop_gmac_sgmii2_5_cfg(struct mvpp2_port *port)
 
 	val = readl(port->base + MVPP2_GMAC_CTRL_0_REG);
 	/*
-	 * Configure GIG MAC to 1000Base-X mode connected to a fiber
+	 * Configure GIG MAC to SGMII mode connected to a fiber
 	 * transceiver
 	 */
-	val |= MVPP2_GMAC_PORT_TYPE_MASK;
+	val &= ~MVPP2_GMAC_PORT_TYPE_MASK;
 	writel(val, port->base + MVPP2_GMAC_CTRL_0_REG);
 
 	/* configure AN 0x9268 */
@@ -3106,6 +3112,89 @@ static void gop_gmac_sgmii_cfg(struct mvpp2_port *port)
 	writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
 }
 
+static void gop_gmac_2500basex_cfg(struct mvpp2_port *port)
+{
+	u32 val, thresh;
+
+	/*
+	 * Configure minimal level of the Tx FIFO before the lower part
+	 * starts to read a packet
+	 */
+	thresh = MVPP2_SGMII2_5_TX_FIFO_MIN_TH;
+	val = readl(port->base + MVPP2_GMAC_PORT_FIFO_CFG_1_REG);
+	val &= ~MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK;
+	val |= MVPP2_GMAC_TX_FIFO_MIN_TH_MASK(thresh);
+	writel(val, port->base + MVPP2_GMAC_PORT_FIFO_CFG_1_REG);
+
+	/* Disable bypass of sync module */
+	val = readl(port->base + MVPP2_GMAC_CTRL_4_REG);
+	val |= MVPP2_GMAC_CTRL4_SYNC_BYPASS_MASK;
+	/* configure DP clock select according to mode */
+	val |= MVPP2_GMAC_CTRL4_DP_CLK_SEL_MASK;
+	/* configure QSGMII bypass according to mode */
+	val |= MVPP2_GMAC_CTRL4_QSGMII_BYPASS_ACTIVE_MASK;
+	writel(val, port->base + MVPP2_GMAC_CTRL_4_REG);
+
+	val = readl(port->base + MVPP2_GMAC_CTRL_0_REG);
+	/*
+	 * Configure GIG MAC to 2500Base-X mode connected to a fiber
+	 * transceiver
+	 */
+	val |= MVPP2_GMAC_PORT_TYPE_MASK;
+	writel(val, port->base + MVPP2_GMAC_CTRL_0_REG);
+
+	/* In 2500BaseX mode, we can't negotiate speed
+	 * and we do not want InBand autoneg
+	 * bypass enabled (link interrupt storm risk
+	 * otherwise).
+	 */
+	val = MVPP2_GMAC_EN_PCS_AN |
+		MVPP2_GMAC_CONFIG_GMII_SPEED  |
+		MVPP2_GMAC_CONFIG_FULL_DUPLEX |
+		MVPP2_GMAC_CHOOSE_SAMPLE_TX_CONFIG;
+	writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
+}
+
+static void gop_gmac_1000basex_cfg(struct mvpp2_port *port)
+{
+	u32 val, thresh;
+
+	/*
+	 * Configure minimal level of the Tx FIFO before the lower part
+	 * starts to read a packet
+	 */
+	thresh = MVPP2_SGMII_TX_FIFO_MIN_TH;
+	val = readl(port->base + MVPP2_GMAC_PORT_FIFO_CFG_1_REG);
+	val &= ~MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK;
+	val |= MVPP2_GMAC_TX_FIFO_MIN_TH_MASK(thresh);
+	writel(val, port->base + MVPP2_GMAC_PORT_FIFO_CFG_1_REG);
+
+	/* Disable bypass of sync module */
+	val = readl(port->base + MVPP2_GMAC_CTRL_4_REG);
+	val |= MVPP2_GMAC_CTRL4_SYNC_BYPASS_MASK;
+	/* configure DP clock select according to mode */
+	val &= ~MVPP2_GMAC_CTRL4_DP_CLK_SEL_MASK;
+	/* configure QSGMII bypass according to mode */
+	val |= MVPP2_GMAC_CTRL4_QSGMII_BYPASS_ACTIVE_MASK;
+	writel(val, port->base + MVPP2_GMAC_CTRL_4_REG);
+
+	val = readl(port->base + MVPP2_GMAC_CTRL_0_REG);
+	/* configure GIG MAC to 1000BASEX mode */
+	val |= MVPP2_GMAC_PORT_TYPE_MASK;
+	writel(val, port->base + MVPP2_GMAC_CTRL_0_REG);
+
+	/* In 1000BaseX mode, we can't negotiate speed (it's
+	 * only 1000), and we do not want InBand autoneg
+	 * bypass enabled (link interrupt storm risk
+	 * otherwise).
+	 */
+	val = MVPP2_GMAC_EN_PCS_AN |
+		MVPP2_GMAC_CONFIG_GMII_SPEED  |
+		MVPP2_GMAC_CONFIG_FULL_DUPLEX |
+		MVPP2_GMAC_CHOOSE_SAMPLE_TX_CONFIG;
+	writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
+}
+
 static void gop_gmac_rgmii_cfg(struct mvpp2_port *port)
 {
 	u32 val, thresh;
@@ -3157,6 +3246,12 @@ static int gop_gmac_mode_cfg(struct mvpp2_port *port)
 			gop_gmac_sgmii_cfg(port);
 		break;
 
+	case PHY_INTERFACE_MODE_1000BASEX:
+		gop_gmac_1000basex_cfg(port);
+
+	case PHY_INTERFACE_MODE_2500BASEX:
+		gop_gmac_2500basex_cfg(port);
+
 	case PHY_INTERFACE_MODE_RGMII:
 	case PHY_INTERFACE_MODE_RGMII_ID:
 		gop_gmac_rgmii_cfg(port);
@@ -3329,6 +3424,8 @@ static int gop_port_init(struct mvpp2_port *port)
 		break;
 
 	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
 		/* configure PCS */
 		gop_gpcs_mode_cfg(port, 1);
 
@@ -3386,6 +3483,8 @@ static void gop_port_enable(struct mvpp2_port *port, int enable)
 	case PHY_INTERFACE_MODE_RGMII:
 	case PHY_INTERFACE_MODE_RGMII_ID:
 	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
 		if (enable)
 			mvpp2_port_enable(port);
 		else
@@ -3419,7 +3518,9 @@ static u32 mvpp2_netc_cfg_create(int gop_id, phy_interface_t phy_type)
 	u32 val = 0;
 
 	if (gop_id == 2) {
-		if (phy_type == PHY_INTERFACE_MODE_SGMII)
+		if (phy_type == PHY_INTERFACE_MODE_SGMII ||
+		    phy_type == PHY_INTERFACE_MODE_1000BASEX ||
+		    phy_type == PHY_INTERFACE_MODE_2500BASEX)
 			val |= MV_NETC_GE_MAC2_SGMII;
 		else if (phy_type == PHY_INTERFACE_MODE_RGMII ||
 			 phy_type == PHY_INTERFACE_MODE_RGMII_ID)
@@ -3427,7 +3528,9 @@ static u32 mvpp2_netc_cfg_create(int gop_id, phy_interface_t phy_type)
 	}
 
 	if (gop_id == 3) {
-		if (phy_type == PHY_INTERFACE_MODE_SGMII)
+		if (phy_type == PHY_INTERFACE_MODE_SGMII ||
+		    phy_type == PHY_INTERFACE_MODE_1000BASEX ||
+		    phy_type == PHY_INTERFACE_MODE_2500BASEX)
 			val |= MV_NETC_GE_MAC3_SGMII;
 		else if (phy_type == PHY_INTERFACE_MODE_RGMII ||
 			 phy_type == PHY_INTERFACE_MODE_RGMII_ID)
@@ -4423,6 +4526,8 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
 	case PHY_INTERFACE_MODE_RGMII:
 	case PHY_INTERFACE_MODE_RGMII_ID:
 	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
 		mvpp2_gmac_max_rx_size_set(port);
 	default:
 		break;
@@ -5159,6 +5264,8 @@ static int mvpp2_start(struct udevice *dev)
 	case PHY_INTERFACE_MODE_RGMII:
 	case PHY_INTERFACE_MODE_RGMII_ID:
 	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
 		mvpp2_port_power_up(port);
 	default:
 		break;
-- 
2.31.1



More information about the U-Boot mailing list