aboutsummaryrefslogtreecommitdiffstats
path: root/package/boot/uboot-mediatek/patches/101-20-net-mediatek-add-support-for-SGMII-1Gbps-auto-negoti.patch
blob: 45acbc36ac1bac982c6e16f0786d60ab8487401d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
From 8e59c3cc700a6efb8db574f3c8e18b6181b4a07d Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Wed, 19 Jul 2023 17:17:13 +0800
Subject: [PATCH 20/29] net: mediatek: add support for SGMII 1Gbps
 auto-negotiation mode

Existing SGMII support of mtk-eth is actually a MediaTek-specific
2.5Gbps high-speed SGMII (HSGMII) which does not support
auto-negotiation mode.

This patch adds SGMII 1Gbps auto-negotiation mode and rename the
existing HSGMII to 2500basex.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/net/mtk_eth.c | 46 +++++++++++++++++++++++++++++++++++++------
 drivers/net/mtk_eth.h |  2 ++
 2 files changed, 42 insertions(+), 6 deletions(-)

--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -893,7 +893,7 @@ static int mt7531_setup(struct mtk_eth_p
 		if (!port5_sgmii)
 			mt7531_port_rgmii_init(priv, 5);
 		break;
-	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_2500BASEX:
 		mt7531_port_sgmii_init(priv, 6);
 		if (port5_sgmii)
 			mt7531_port_sgmii_init(priv, 5);
@@ -986,6 +986,7 @@ static void mtk_phy_link_adjust(struct m
 	      (MAC_RX_PKT_LEN_1536 << MAC_RX_PKT_LEN_S) |
 	      MAC_MODE | FORCE_MODE |
 	      MAC_TX_EN | MAC_RX_EN |
+	      DEL_RXFIFO_CLR |
 	      BKOFF_EN | BACKPR_EN;
 
 	switch (priv->phydev->speed) {
@@ -996,6 +997,7 @@ static void mtk_phy_link_adjust(struct m
 		mcr |= (SPEED_100M << FORCE_SPD_S);
 		break;
 	case SPEED_1000:
+	case SPEED_2500:
 		mcr |= (SPEED_1000M << FORCE_SPD_S);
 		break;
 	};
@@ -1048,7 +1050,8 @@ static int mtk_phy_start(struct mtk_eth_
 		return 0;
 	}
 
-	mtk_phy_link_adjust(priv);
+	if (!priv->force_mode)
+		mtk_phy_link_adjust(priv);
 
 	debug("Speed: %d, %s duplex%s\n", phydev->speed,
 	      (phydev->duplex) ? "full" : "half",
@@ -1076,7 +1079,31 @@ static int mtk_phy_probe(struct udevice
 	return 0;
 }
 
-static void mtk_sgmii_init(struct mtk_eth_priv *priv)
+static void mtk_sgmii_an_init(struct mtk_eth_priv *priv)
+{
+	/* Set SGMII GEN1 speed(1G) */
+	clrsetbits_le32(priv->sgmii_base + priv->soc->ana_rgc3,
+			SGMSYS_SPEED_2500, 0);
+
+	/* Enable SGMII AN */
+	setbits_le32(priv->sgmii_base + SGMSYS_PCS_CONTROL_1,
+		     SGMII_AN_ENABLE);
+
+	/* SGMII AN mode setting */
+	writel(SGMII_AN_MODE, priv->sgmii_base + SGMSYS_SGMII_MODE);
+
+	/* SGMII PN SWAP setting */
+	if (priv->pn_swap) {
+		setbits_le32(priv->sgmii_base + SGMSYS_QPHY_WRAP_CTRL,
+			     SGMII_PN_SWAP_TX_RX);
+	}
+
+	/* Release PHYA power down state */
+	clrsetbits_le32(priv->sgmii_base + SGMSYS_QPHY_PWR_STATE_CTRL,
+			SGMII_PHYA_PWD, 0);
+}
+
+static void mtk_sgmii_force_init(struct mtk_eth_priv *priv)
 {
 	/* Set SGMII GEN2 speed(2.5G) */
 	setbits_le32(priv->sgmii_base + priv->soc->ana_rgc3,
@@ -1111,10 +1138,14 @@ static void mtk_mac_init(struct mtk_eth_
 		ge_mode = GE_MODE_RGMII;
 		break;
 	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_2500BASEX:
 		ge_mode = GE_MODE_RGMII;
 		mtk_ethsys_rmw(priv, ETHSYS_SYSCFG0_REG, SYSCFG0_SGMII_SEL_M,
 			       SYSCFG0_SGMII_SEL(priv->gmac_id));
-		mtk_sgmii_init(priv);
+		if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII)
+			mtk_sgmii_an_init(priv);
+		else
+			mtk_sgmii_force_init(priv);
 		break;
 	case PHY_INTERFACE_MODE_MII:
 	case PHY_INTERFACE_MODE_GMII:
@@ -1148,6 +1179,7 @@ static void mtk_mac_init(struct mtk_eth_
 			mcr |= SPEED_100M << FORCE_SPD_S;
 			break;
 		case SPEED_1000:
+		case SPEED_2500:
 			mcr |= SPEED_1000M << FORCE_SPD_S;
 			break;
 		}
@@ -1490,13 +1522,15 @@ static int mtk_eth_of_to_plat(struct ude
 		priv->duplex = ofnode_read_bool(subnode, "full-duplex");
 
 		if (priv->speed != SPEED_10 && priv->speed != SPEED_100 &&
-		    priv->speed != SPEED_1000) {
+		    priv->speed != SPEED_1000 && priv->speed != SPEED_2500 &&
+		    priv->speed != SPEED_10000) {
 			printf("error: no valid speed set in fixed-link\n");
 			return -EINVAL;
 		}
 	}
 
-	if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII) {
+	if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII ||
+	    priv->phy_interface == PHY_INTERFACE_MODE_2500BASEX) {
 		/* get corresponding sgmii phandle */
 		ret = dev_read_phandle_with_args(dev, "mediatek,sgmiisys",
 						 NULL, 0, 0, &args);
--- a/drivers/net/mtk_eth.h
+++ b/drivers/net/mtk_eth.h
@@ -69,6 +69,7 @@ enum mkt_eth_capabilities {
 #define SGMII_AN_RESTART		BIT(9)
 
 #define SGMSYS_SGMII_MODE		0x20
+#define SGMII_AN_MODE			0x31120103
 #define SGMII_FORCE_MODE		0x31120019
 
 #define SGMSYS_QPHY_PWR_STATE_CTRL	0xe8
@@ -168,6 +169,7 @@ enum mkt_eth_capabilities {
 #define FORCE_MODE			BIT(15)
 #define MAC_TX_EN			BIT(14)
 #define MAC_RX_EN			BIT(13)
+#define DEL_RXFIFO_CLR			BIT(12)
 #define BKOFF_EN			BIT(9)
 #define BACKPR_EN			BIT(8)
 #define FORCE_RX_FC			BIT(5)