uboot-mediatek: add build for BPi-R4
[openwrt/openwrt.git] / package / boot / uboot-mediatek / patches / 101-26-net-mediatek-add-support-for-MediaTek-MT7988-SoC.patch
1 From 59dba9d87c9caf04a5d797af46699055a53870f4 Mon Sep 17 00:00:00 2001
2 From: Weijie Gao <weijie.gao@mediatek.com>
3 Date: Wed, 19 Jul 2023 17:17:41 +0800
4 Subject: [PATCH 26/29] net: mediatek: add support for MediaTek MT7988 SoC
5
6 This patch adds support for MediaTek MT7988.
7
8 MT7988 features MediaTek NETSYS v3, including three GMACs, and two
9 of them supports 10Gbps USXGMII.
10
11 MT7988 embeds a MT7531 switch (not MCM) which supports accessing
12 internal registers through MMIO instead of MDIO.
13
14 Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
15 ---
16 drivers/net/mtk_eth.c | 158 +++++++++++++++++++++++++++++++++++++++++-
17 drivers/net/mtk_eth.h | 20 ++++++
18 2 files changed, 177 insertions(+), 1 deletion(-)
19
20 --- a/drivers/net/mtk_eth.c
21 +++ b/drivers/net/mtk_eth.c
22 @@ -54,6 +54,16 @@
23 (DP_PDMA << MC_DP_S) | \
24 (DP_PDMA << UN_DP_S))
25
26 +#define GDMA_BRIDGE_TO_CPU \
27 + (0xC0000000 | \
28 + GDM_ICS_EN | \
29 + GDM_TCS_EN | \
30 + GDM_UCS_EN | \
31 + (DP_PDMA << MYMAC_DP_S) | \
32 + (DP_PDMA << BC_DP_S) | \
33 + (DP_PDMA << MC_DP_S) | \
34 + (DP_PDMA << UN_DP_S))
35 +
36 #define GDMA_FWD_DISCARD \
37 (0x20000000 | \
38 GDM_ICS_EN | \
39 @@ -68,7 +78,8 @@
40 enum mtk_switch {
41 SW_NONE,
42 SW_MT7530,
43 - SW_MT7531
44 + SW_MT7531,
45 + SW_MT7988,
46 };
47
48 /* struct mtk_soc_data - This is the structure holding all differences
49 @@ -102,6 +113,7 @@ struct mtk_eth_priv {
50 void __iomem *fe_base;
51 void __iomem *gmac_base;
52 void __iomem *sgmii_base;
53 + void __iomem *gsw_base;
54
55 struct regmap *ethsys_regmap;
56
57 @@ -171,6 +183,11 @@ static void mtk_gdma_write(struct mtk_et
58 writel(val, priv->fe_base + gdma_base + reg);
59 }
60
61 +static void mtk_fe_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set)
62 +{
63 + clrsetbits_le32(priv->fe_base + reg, clr, set);
64 +}
65 +
66 static u32 mtk_gmac_read(struct mtk_eth_priv *priv, u32 reg)
67 {
68 return readl(priv->gmac_base + reg);
69 @@ -208,6 +225,16 @@ static void mtk_infra_rmw(struct mtk_eth
70 regmap_write(priv->infra_regmap, reg, val);
71 }
72
73 +static u32 mtk_gsw_read(struct mtk_eth_priv *priv, u32 reg)
74 +{
75 + return readl(priv->gsw_base + reg);
76 +}
77 +
78 +static void mtk_gsw_write(struct mtk_eth_priv *priv, u32 reg, u32 val)
79 +{
80 + writel(val, priv->gsw_base + reg);
81 +}
82 +
83 /* Direct MDIO clause 22/45 access via SoC */
84 static int mtk_mii_rw(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 data,
85 u32 cmd, u32 st)
86 @@ -342,6 +369,11 @@ static int mt753x_reg_read(struct mtk_et
87 {
88 int ret, low_word, high_word;
89
90 + if (priv->sw == SW_MT7988) {
91 + *data = mtk_gsw_read(priv, reg);
92 + return 0;
93 + }
94 +
95 /* Write page address */
96 ret = mtk_mii_write(priv, priv->mt753x_smi_addr, 0x1f, reg >> 6);
97 if (ret)
98 @@ -367,6 +399,11 @@ static int mt753x_reg_write(struct mtk_e
99 {
100 int ret;
101
102 + if (priv->sw == SW_MT7988) {
103 + mtk_gsw_write(priv, reg, data);
104 + return 0;
105 + }
106 +
107 /* Write page address */
108 ret = mtk_mii_write(priv, priv->mt753x_smi_addr, 0x1f, reg >> 6);
109 if (ret)
110 @@ -537,6 +574,7 @@ static int mtk_mdio_register(struct udev
111 priv->mmd_write = mtk_mmd_ind_write;
112 break;
113 case SW_MT7531:
114 + case SW_MT7988:
115 priv->mii_read = mt7531_mii_ind_read;
116 priv->mii_write = mt7531_mii_ind_write;
117 priv->mmd_read = mt7531_mmd_ind_read;
118 @@ -957,6 +995,103 @@ static int mt7531_setup(struct mtk_eth_p
119 return 0;
120 }
121
122 +static void mt7988_phy_setting(struct mtk_eth_priv *priv)
123 +{
124 + u16 val;
125 + u32 i;
126 +
127 + for (i = 0; i < MT753X_NUM_PHYS; i++) {
128 + /* Enable HW auto downshift */
129 + priv->mii_write(priv, i, 0x1f, 0x1);
130 + val = priv->mii_read(priv, i, PHY_EXT_REG_14);
131 + val |= PHY_EN_DOWN_SHFIT;
132 + priv->mii_write(priv, i, PHY_EXT_REG_14, val);
133 +
134 + /* PHY link down power saving enable */
135 + val = priv->mii_read(priv, i, PHY_EXT_REG_17);
136 + val |= PHY_LINKDOWN_POWER_SAVING_EN;
137 + priv->mii_write(priv, i, PHY_EXT_REG_17, val);
138 + }
139 +}
140 +
141 +static void mt7988_mac_control(struct mtk_eth_priv *priv, bool enable)
142 +{
143 + u32 pmcr = FORCE_MODE_LNK;
144 +
145 + if (enable)
146 + pmcr = priv->mt753x_pmcr;
147 +
148 + mt753x_reg_write(priv, PMCR_REG(6), pmcr);
149 +}
150 +
151 +static int mt7988_setup(struct mtk_eth_priv *priv)
152 +{
153 + u16 phy_addr, phy_val;
154 + u32 pmcr;
155 + int i;
156 +
157 + priv->gsw_base = regmap_get_range(priv->ethsys_regmap, 0) + GSW_BASE;
158 +
159 + priv->mt753x_phy_base = (priv->mt753x_smi_addr + 1) &
160 + MT753X_SMI_ADDR_MASK;
161 +
162 + /* Turn off PHYs */
163 + for (i = 0; i < MT753X_NUM_PHYS; i++) {
164 + phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i);
165 + phy_val = priv->mii_read(priv, phy_addr, MII_BMCR);
166 + phy_val |= BMCR_PDOWN;
167 + priv->mii_write(priv, phy_addr, MII_BMCR, phy_val);
168 + }
169 +
170 + switch (priv->phy_interface) {
171 + case PHY_INTERFACE_MODE_USXGMII:
172 + /* Use CPU bridge instead of actual USXGMII path */
173 +
174 + /* Set GDM1 no drop */
175 + mtk_fe_rmw(priv, PSE_NO_DROP_CFG_REG, 0, PSE_NO_DROP_GDM1);
176 +
177 + /* Enable GDM1 to GSW CPU bridge */
178 + mtk_gmac_rmw(priv, GMAC_MAC_MISC_REG, 0, BIT(0));
179 +
180 + /* XGMAC force link up */
181 + mtk_gmac_rmw(priv, GMAC_XGMAC_STS_REG, 0, P1_XGMAC_FORCE_LINK);
182 +
183 + /* Setup GSW CPU bridge IPG */
184 + mtk_gmac_rmw(priv, GMAC_GSW_CFG_REG, GSWTX_IPG_M | GSWRX_IPG_M,
185 + (0xB << GSWTX_IPG_S) | (0xB << GSWRX_IPG_S));
186 + break;
187 + default:
188 + printf("Error: MT7988 GSW does not support %s interface\n",
189 + phy_string_for_interface(priv->phy_interface));
190 + break;
191 + }
192 +
193 + pmcr = MT7988_FORCE_MODE |
194 + (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
195 + MAC_MODE | MAC_TX_EN | MAC_RX_EN |
196 + BKOFF_EN | BACKPR_EN |
197 + FORCE_RX_FC | FORCE_TX_FC |
198 + (SPEED_1000M << FORCE_SPD_S) | FORCE_DPX |
199 + FORCE_LINK;
200 +
201 + priv->mt753x_pmcr = pmcr;
202 +
203 + /* Keep MAC link down before starting eth */
204 + mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE_LNK);
205 +
206 + /* Turn on PHYs */
207 + for (i = 0; i < MT753X_NUM_PHYS; i++) {
208 + phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i);
209 + phy_val = priv->mii_read(priv, phy_addr, MII_BMCR);
210 + phy_val &= ~BMCR_PDOWN;
211 + priv->mii_write(priv, phy_addr, MII_BMCR, phy_val);
212 + }
213 +
214 + mt7988_phy_setting(priv);
215 +
216 + return 0;
217 +}
218 +
219 static int mt753x_switch_init(struct mtk_eth_priv *priv)
220 {
221 int ret;
222 @@ -1497,6 +1632,11 @@ static int mtk_eth_start(struct udevice
223 }
224
225 if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3)) {
226 + if (priv->sw == SW_MT7988 && priv->gmac_id == 0) {
227 + mtk_gdma_write(priv, priv->gmac_id, GDMA_IG_CTRL_REG,
228 + GDMA_BRIDGE_TO_CPU);
229 + }
230 +
231 mtk_gdma_write(priv, priv->gmac_id, GDMA_EG_CTRL_REG,
232 GDMA_CPU_BRIDGE_EN);
233 }
234 @@ -1845,6 +1985,12 @@ static int mtk_eth_of_to_plat(struct ude
235 priv->switch_mac_control = mt7531_mac_control;
236 priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR;
237 priv->mt753x_reset_wait_time = 200;
238 + } else if (!strcmp(str, "mt7988")) {
239 + priv->sw = SW_MT7988;
240 + priv->switch_init = mt7988_setup;
241 + priv->switch_mac_control = mt7988_mac_control;
242 + priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR;
243 + priv->mt753x_reset_wait_time = 50;
244 } else {
245 printf("error: unsupported switch\n");
246 return -EINVAL;
247 @@ -1879,6 +2025,15 @@ static int mtk_eth_of_to_plat(struct ude
248 return 0;
249 }
250
251 +static const struct mtk_soc_data mt7988_data = {
252 + .caps = MT7988_CAPS,
253 + .ana_rgc3 = 0x128,
254 + .gdma_count = 3,
255 + .pdma_base = PDMA_V3_BASE,
256 + .txd_size = sizeof(struct mtk_tx_dma_v2),
257 + .rxd_size = sizeof(struct mtk_rx_dma_v2),
258 +};
259 +
260 static const struct mtk_soc_data mt7986_data = {
261 .caps = MT7986_CAPS,
262 .ana_rgc3 = 0x128,
263 @@ -1930,6 +2085,7 @@ static const struct mtk_soc_data mt7621_
264 };
265
266 static const struct udevice_id mtk_eth_ids[] = {
267 + { .compatible = "mediatek,mt7988-eth", .data = (ulong)&mt7988_data },
268 { .compatible = "mediatek,mt7986-eth", .data = (ulong)&mt7986_data },
269 { .compatible = "mediatek,mt7981-eth", .data = (ulong)&mt7981_data },
270 { .compatible = "mediatek,mt7629-eth", .data = (ulong)&mt7629_data },
271 --- a/drivers/net/mtk_eth.h
272 +++ b/drivers/net/mtk_eth.h
273 @@ -51,6 +51,8 @@ enum mkt_eth_capabilities {
274
275 #define MT7986_CAPS (MTK_NETSYS_V2)
276
277 +#define MT7988_CAPS (MTK_NETSYS_V3 | MTK_INFRA)
278 +
279 /* Frame Engine Register Bases */
280 #define PDMA_V1_BASE 0x0800
281 #define PDMA_V2_BASE 0x6000
282 @@ -59,6 +61,7 @@ enum mkt_eth_capabilities {
283 #define GDMA2_BASE 0x1500
284 #define GDMA3_BASE 0x0540
285 #define GMAC_BASE 0x10000
286 +#define GSW_BASE 0x20000
287
288 /* Ethernet subsystem registers */
289
290 @@ -117,6 +120,9 @@ enum mkt_eth_capabilities {
291 #define RG_XFI_PLL_ANA_SWWA 0x02283248
292
293 /* Frame Engine Registers */
294 +#define PSE_NO_DROP_CFG_REG 0x108
295 +#define PSE_NO_DROP_GDM1 BIT(1)
296 +
297 #define FE_GLO_MISC_REG 0x124
298 #define PDMA_VER_V2 BIT(4)
299
300 @@ -187,6 +193,17 @@ enum mkt_eth_capabilities {
301 #define MDIO_RW_DATA_S 0
302 #define MDIO_RW_DATA_M 0xffff
303
304 +#define GMAC_XGMAC_STS_REG 0x000c
305 +#define P1_XGMAC_FORCE_LINK BIT(15)
306 +
307 +#define GMAC_MAC_MISC_REG 0x0010
308 +
309 +#define GMAC_GSW_CFG_REG 0x0080
310 +#define GSWTX_IPG_M 0xF0000
311 +#define GSWTX_IPG_S 16
312 +#define GSWRX_IPG_M 0xF
313 +#define GSWRX_IPG_S 0
314 +
315 /* MDIO_CMD: MDIO commands */
316 #define MDIO_CMD_ADDR 0
317 #define MDIO_CMD_WRITE 1
318 @@ -285,6 +302,9 @@ enum mkt_eth_capabilities {
319 FORCE_MODE_TX_FC | FORCE_MODE_RX_FC | \
320 FORCE_MODE_DPX | FORCE_MODE_SPD | \
321 FORCE_MODE_LNK
322 +#define MT7988_FORCE_MODE FORCE_MODE_TX_FC | FORCE_MODE_RX_FC | \
323 + FORCE_MODE_DPX | FORCE_MODE_SPD | \
324 + FORCE_MODE_LNK
325
326 /* MT7531 SGMII Registers */
327 #define MT7531_SGMII_REG_BASE 0x5000