[][kernel][mt7987][eth][Add XGMACv2 support for the NETSYS v3.1]

[Description]
Add XGMACv2 support for the NETSYS v3.1.

[Release-log]
N/A


Change-Id: I05a7f02f8626a05448497816f91af330778dcf77
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/9743740
diff --git a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
index 045fc2b..0f95a0a 100644
--- a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
+++ b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
@@ -1157,12 +1157,20 @@
 int xfi_cnt_read(struct seq_file *seq, void *v)
 {
 	struct mtk_eth *eth = g_eth;
+	bool has_xgmac[MTK_MAX_DEVS] = {0,
+					MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC2_2P5GPHY) ||
+					MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC2_2P5GPHY_V2) ||
+					MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC2_USXGMII),
+					MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC3_USXGMII)};
 	int i;
 
 	seq_puts(seq, "+------------------------------------+\n");
 	seq_puts(seq, "|             <<XFI MAC>>            |\n");
 
 	for (i = MTK_GMAC2_ID; i < MTK_GMAC_ID_MAX; i++) {
+		if (!has_xgmac[i])
+			continue;
+
 		xfi_mib_dump(seq, i);
 		mtk_m32(eth, 0x1, 0x1, MTK_XFI_MIB_BASE(i) + MTK_XFI_CNT_CTRL);
 		seq_puts(seq, "|                                    |\n");
@@ -1496,12 +1504,16 @@
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
 		seq_printf(seq, "| XMAC_P1_MCR	: %08x |\n",
 			   mtk_r32(eth, MTK_XMAC_MCR(1)));
-		seq_printf(seq, "| XMAC_P2_MCR	: %08x |\n",
-			   mtk_r32(eth, MTK_XMAC_MCR(2)));
 		seq_printf(seq, "| XMAC_P1_STS	: %08x |\n",
-			   mtk_r32(eth, MTK_XGMAC_STS(1)));
-		seq_printf(seq, "| XMAC_P2_STS	: %08x |\n",
-			   mtk_r32(eth, MTK_XGMAC_STS(2)));
+			   mtk_r32(eth, MTK_HAS_CAPS(eth->soc->caps, MTK_XGMAC_V2) ?
+						     MTK_XMAC_STS(1) : MTK_XGMAC_STS(1)));
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC3_USXGMII)) {
+			seq_printf(seq, "| XMAC_P2_MCR	: %08x |\n",
+				   mtk_r32(eth, MTK_XMAC_MCR(2)));
+			seq_printf(seq, "| XMAC_P2_STS	: %08x |\n",
+				   mtk_r32(eth, MTK_HAS_CAPS(eth->soc->caps, MTK_XGMAC_V2) ?
+							     MTK_XMAC_STS(2) : MTK_XGMAC_STS(2)));
+		}
 	}
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
 	    MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
diff --git a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c
index 5ebeb97..3cae2d1 100644
--- a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c
+++ b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c
@@ -272,11 +272,15 @@
 			"SGMII1", 0, 0x1a0);
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
 		mtk_dump_reg(eth, "XGMAC0", 0x12000, 0x300);
-		mtk_dump_reg(eth, "XGMAC1", 0x13000, 0x300);
-		mtk_dump_regmap(eth->usxgmii->pcs[0].regmap,
-				"USXGMII0", 0x800, 0x500);
-		mtk_dump_regmap(eth->usxgmii->pcs[1].regmap,
-				"USXGMII1", 0x800, 0x500);
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC2_USXGMII)) {
+			mtk_dump_regmap(eth->usxgmii->pcs[1].regmap,
+					"USXGMII1", 0x800, 0x500);
+		}
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC3_USXGMII)) {
+			mtk_dump_reg(eth, "XGMAC1", 0x13000, 0x300);
+			mtk_dump_regmap(eth->usxgmii->pcs[0].regmap,
+					"USXGMII0", 0x800, 0x500);
+		}
 	}
 }
 
@@ -882,9 +886,15 @@
 			mcr |= XMAC_MCR_TRX_DISABLE;
 			mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
 
-			sts = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
-			sts &= ~MTK_XGMAC_FORCE_LINK(mac->id);
-			mtk_w32(mac->hw, sts, MTK_XGMAC_STS(mac->id));
+			if (MTK_HAS_CAPS(eth->soc->caps, MTK_XGMAC_V2)) {
+				sts = mtk_r32(mac->hw, MTK_XMAC_STS_FRC(mac->id));
+				sts &= ~XMAC_FORCE_LINK;
+				mtk_w32(mac->hw, sts, MTK_XMAC_STS_FRC(mac->id));
+			} else {
+				sts = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
+				sts &= ~MTK_XGMAC_FORCE_LINK(mac->id);
+				mtk_w32(mac->hw, sts, MTK_XGMAC_STS(mac->id));
+			}
 		}
 	}
 }
diff --git a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index e7c7cd6..8196f2b 100644
--- a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -671,19 +671,32 @@
 	struct mtk_mac *mac = container_of(config, struct mtk_mac,
 					   phylink_config);
 	struct mtk_eth *eth = mac->hw;
+	bool has_xgmac[MTK_MAX_DEVS] = {0,
+					MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC2_2P5GPHY) ||
+					MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC2_2P5GPHY_V2) ||
+					MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC2_USXGMII),
+					MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC3_USXGMII)};
 	u32 val;
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
-	    mac->id != MTK_GMAC1_ID) {
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) && has_xgmac[mac->id]) {
 		val = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
 		val &= 0xfffffff0;
 		val |= XMAC_MCR_TRX_DISABLE;
 		mtk_w32(mac->hw, val, MTK_XMAC_MCR(mac->id));
 
-		val = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
-		val |= MTK_XGMAC_FORCE_MODE(mac->id);
-		val &= ~MTK_XGMAC_FORCE_LINK(mac->id);
-		mtk_w32(mac->hw, val, MTK_XGMAC_STS(mac->id));
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_XGMAC_V2)) {
+			val = mtk_r32(mac->hw, MTK_XMAC_STS_FRC(mac->id));
+			val |= XMAC_FORCE_RX_FC_MODE;
+			val |= XMAC_FORCE_TX_FC_MODE;
+			val |= XMAC_FORCE_LINK_MODE;
+			val &= ~XMAC_FORCE_LINK;
+			mtk_w32(mac->hw, val, MTK_XMAC_STS_FRC(mac->id));
+		} else {
+			val = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
+			val |= MTK_XGMAC_FORCE_MODE(mac->id);
+			val &= ~MTK_XGMAC_FORCE_LINK(mac->id);
+			mtk_w32(mac->hw, val, MTK_XGMAC_STS(mac->id));
+		}
 	}
 
 	return 0;
@@ -1029,7 +1042,8 @@
 	struct mtk_eth *eth = mac->hw;
 	u32 port = 0;
 
-	if (!up && mac->id == MTK_GMAC2_ID &&
+	if (eth->soc->caps == MT7988_CAPS &&
+	    !up && mac->id == MTK_GMAC2_ID &&
 	    interface == PHY_INTERFACE_MODE_INTERNAL &&
 	    MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) {
 		void __iomem *base;
@@ -1071,6 +1085,7 @@
 {
 	struct mtk_mac *mac = container_of(config, struct mtk_mac,
 					   phylink_config);
+	struct mtk_eth *eth = mac->hw;
 	u32 mcr, sts;
 
 	mtk_pse_set_mac_port_link(mac, false, interface);
@@ -1084,9 +1099,15 @@
 		mcr |= XMAC_MCR_TRX_DISABLE;
 		mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
 
-		sts = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
-		sts &= ~MTK_XGMAC_FORCE_LINK(mac->id);
-		mtk_w32(mac->hw, sts, MTK_XGMAC_STS(mac->id));
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_XGMAC_V2)) {
+			sts = mtk_r32(mac->hw, MTK_XMAC_STS_FRC(mac->id));
+			sts &= ~XMAC_FORCE_LINK;
+			mtk_w32(mac->hw, sts, MTK_XMAC_STS_FRC(mac->id));
+		} else {
+			sts = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
+			sts &= ~MTK_XGMAC_FORCE_LINK(mac->id);
+			mtk_w32(mac->hw, sts, MTK_XGMAC_STS(mac->id));
+		}
 	}
 }
 
@@ -1178,6 +1199,7 @@
 {
 	struct mtk_mac *mac = container_of(config, struct mtk_mac,
 					   phylink_config);
+	struct mtk_eth *eth = mac->hw;
 	u32 mcr, mcr_cur, sts;
 
 	mac->speed = speed;
@@ -1235,23 +1257,41 @@
 		mdelay(20);
 		mtk_m32(mac->hw, XMAC_GLB_CNTCLR, 0x1, MTK_XMAC_CNT_CTRL(mac->id));
 
-		sts = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
-		sts |= MTK_XGMAC_FORCE_LINK(mac->id);
-		mtk_w32(mac->hw, sts, MTK_XGMAC_STS(mac->id));
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_XGMAC_V2)) {
+			sts = mtk_r32(mac->hw, MTK_XMAC_STS_FRC(mac->id));
+			sts &= ~(XMAC_FORCE_TX_FC | XMAC_FORCE_RX_FC);
+			/* Configure pause modes -
+			 * phylink will avoid these for half duplex
+			 */
+			if (tx_pause)
+				sts |= XMAC_FORCE_TX_FC;
+			if (rx_pause)
+				sts |= XMAC_FORCE_RX_FC;
+			sts |= XMAC_FORCE_LINK;
+			mtk_w32(mac->hw, sts, MTK_XMAC_STS_FRC(mac->id));
 
-		mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
+			mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
+			mcr &= ~(XMAC_MCR_TRX_DISABLE);
+			mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
+		} else {
+			sts = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
+			sts |= MTK_XGMAC_FORCE_LINK(mac->id);
+			mtk_w32(mac->hw, sts, MTK_XGMAC_STS(mac->id));
 
-		mcr &= ~(XMAC_MCR_FORCE_TX_FC |	XMAC_MCR_FORCE_RX_FC);
-		/* Configure pause modes -
-		 * phylink will avoid these for half duplex
-		 */
-		if (tx_pause)
-			mcr |= XMAC_MCR_FORCE_TX_FC;
-		if (rx_pause)
-			mcr |= XMAC_MCR_FORCE_RX_FC;
+			mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
 
-		mcr &= ~(XMAC_MCR_TRX_DISABLE);
-		mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
+			mcr &= ~(XMAC_MCR_FORCE_TX_FC |	XMAC_MCR_FORCE_RX_FC);
+			/* Configure pause modes -
+			 * phylink will avoid these for half duplex
+			 */
+			if (tx_pause)
+				mcr |= XMAC_MCR_FORCE_TX_FC;
+			if (rx_pause)
+				mcr |= XMAC_MCR_FORCE_RX_FC;
+
+			mcr &= ~(XMAC_MCR_TRX_DISABLE);
+			mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
+		}
 	}
 	mtk_pse_set_mac_port_link(mac, true, interface);
 }
@@ -5301,10 +5341,17 @@
 		pause->rx_pause = !!(val & MAC_MCR_FORCE_RX_FC);
 		pause->tx_pause = !!(val & MAC_MCR_FORCE_TX_FC);
 	} else if (mac->type == MTK_XGDM_TYPE) {
-		val = mtk_r32(eth, MTK_XMAC_MCR(mac->id));
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_XGMAC_V2)) {
+			val = mtk_r32(mac->hw, MTK_XMAC_STS_FRC(mac->id));
 
-		pause->rx_pause = !!(val & XMAC_MCR_FORCE_RX_FC);
-		pause->tx_pause = !!(val & XMAC_MCR_FORCE_TX_FC);
+			pause->rx_pause = !!(val & XMAC_FORCE_RX_FC);
+			pause->tx_pause = !!(val & XMAC_FORCE_TX_FC);
+		} else {
+			val = mtk_r32(eth, MTK_XMAC_MCR(mac->id));
+
+			pause->rx_pause = !!(val & XMAC_MCR_FORCE_RX_FC);
+			pause->tx_pause = !!(val & XMAC_MCR_FORCE_TX_FC);
+		}
 	}
 }
 
diff --git a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index d9d6012..05c113d 100644
--- a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -793,12 +793,34 @@
 #define XMAC_MCR_FORCE_TX_FC	BIT(5)
 #define XMAC_MCR_FORCE_RX_FC	BIT(4)
 
+/* XFI Mac status force registers */
+#define MTK_XMAC_STS(x)		(MTK_XMAC_MCR(x) + 0x14)
+
+/* XFI Mac status force registers */
+#define MTK_XMAC_STS_FRC(x)	(MTK_XMAC_MCR(x) + 0x18)
+#define XMAC_FORCE_RX_FC_MODE	BIT(13)
+#define XMAC_FORCE_TX_FC_MODE	BIT(12)
+#define XMAC_FORCE_SPD_MODE	BIT(10)
+#define XMAC_FORCE_LINK_MODE	BIT(8)
+#define XMAC_FORCE_RX_FC	BIT(5)
+#define XMAC_FORCE_TX_FC	BIT(4)
+#define XMAC_FORCE_SPD_MASK	GENMASK(3, 1)
+#define XMAC_FORCE_SPD_10	FIELD_PREP(XMAC_FORCE_SPD_MASK, 0)
+#define XMAC_FORCE_SPD_100	FIELD_PREP(XMAC_FORCE_SPD_MASK, 1)
+#define XMAC_FORCE_SPD_1000	FIELD_PREP(XMAC_FORCE_SPD_MASK, 2)
+#define XMAC_FORCE_SPD_10000	FIELD_PREP(XMAC_FORCE_SPD_MASK, 3)
+#define XMAC_FORCE_SPD_2500	FIELD_PREP(XMAC_FORCE_SPD_MASK, 4)
+#define XMAC_FORCE_SPD_5000	FIELD_PREP(XMAC_FORCE_SPD_MASK, 5)
+#define XMAC_FORCE_LINK		BIT(0)
+
 /* XFI Mac Rx configuration registers */
 #define MTK_XMAC_RX_CFG2(x)	(MTK_XMAC_MCR(x) + 0xd0)
 #define MTK_XMAC_MAX_RX_MASK	GENMASK(13, 0)
 
 /* XFI Mac logic reset registers */
-#define MTK_XMAC_LOGIC_RST(x)	(MTK_XMAC_BASE(x) + 0x10)
+#define MTK_XMAC_LOGIC_RST(x)	(MTK_XMAC_BASE(x) +				\
+				 (MTK_HAS_CAPS(eth->soc->caps, MTK_XGMAC_V2) ?	\
+				  0x820 : 0x10))
 #define XMAC_LOGIC_RST		BIT(0)
 
 /* XFI Mac count global control */
@@ -1547,6 +1569,8 @@
 	MTK_SOC_MT7628_BIT,
 	MTK_RSTCTRL_PPE1_BIT,
 	MTK_RSTCTRL_PPE2_BIT,
+	MTK_XGMAC_BIT,
+	MTK_XGMAC_V2_BIT,
 	MTK_U3_COPHY_V2_BIT,
 	MTK_36BIT_DMA_BIT,
 
@@ -1599,6 +1623,8 @@
 #define MTK_SOC_MT7628		BIT_ULL(MTK_SOC_MT7628_BIT)
 #define MTK_RSTCTRL_PPE1	BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
 #define MTK_RSTCTRL_PPE2	BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
+#define MTK_XGMAC		BIT_ULL(MTK_XGMAC_BIT)
+#define MTK_XGMAC_V2		BIT_ULL(MTK_XGMAC_V2_BIT)
 #define MTK_U3_COPHY_V2		BIT_ULL(MTK_U3_COPHY_V2_BIT)
 #define MTK_36BIT_DMA		BIT_ULL(MTK_36BIT_DMA_BIT)
 
@@ -1638,13 +1664,14 @@
 #define MTK_GMAC1_SGMII		(MTK_ETH_PATH_GMAC1_SGMII | MTK_SGMII)
 #define MTK_GMAC2_RGMII		(MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
 #define MTK_GMAC2_SGMII		(MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
-#define MTK_GMAC2_2P5GPHY	(MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY)
+#define MTK_GMAC2_2P5GPHY	(MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY | MTK_XGMAC)
+#define MTK_GMAC2_2P5GPHY_V2	(MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY | MTK_XGMAC_V2)
 #define MTK_GMAC2_GEPHY		(MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
 #define MTK_GMAC3_SGMII		(MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
 #define MTK_GDM1_ESW		(MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
-#define MTK_GMAC1_USXGMII	(MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
-#define MTK_GMAC2_USXGMII	(MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII)
-#define MTK_GMAC3_USXGMII	(MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII)
+#define MTK_GMAC1_USXGMII	(MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII | MTK_XGMAC)
+#define MTK_GMAC2_USXGMII	(MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII | MTK_XGMAC)
+#define MTK_GMAC3_USXGMII	(MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII | MTK_XGMAC)
 
 /* MUXes present on SoCs */
 /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */