gpio-nct5104d: fix compilation with kernel 6.6
[openwrt/openwrt.git] / target / linux / generic / pending-5.15 / 737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch
1 From 1e25ca1147579bda8b941be1b9851f5911d44eb0 Mon Sep 17 00:00:00 2001
2 From: Daniel Golle <daniel@makrotopia.org>
3 Date: Tue, 22 Aug 2023 19:04:42 +0100
4 Subject: [PATCH 098/125] net: ethernet: mtk_eth_soc: add paths and SerDes
5 modes for MT7988
6
7 MT7988 comes with a built-in 2.5G PHY as well as SerDes lanes to
8 connect external PHYs or transceivers in USXGMII, 10GBase-R, 5GBase-R,
9 2500Base-X, 1000Base-X and Cisco SGMII interface modes.
10
11 Implement support for configuring for the new paths to SerDes interfaces
12 and the internal 2.5G PHY.
13
14 Add USXGMII PCS driver for 10GBase-R, 5GBase-R and USXGMII mode, and
15 setup the new PHYA on MT7988 to access the also still existing old
16 LynxI PCS for 1000Base-X, 2500Base-X and Cisco SGMII PCS interface
17 modes.
18
19 Signed-off-by: Daniel Golle <daniel@makrotopia.org>
20 ---
21 drivers/net/ethernet/mediatek/Kconfig | 16 +
22 drivers/net/ethernet/mediatek/Makefile | 1 +
23 drivers/net/ethernet/mediatek/mtk_eth_path.c | 123 +++-
24 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 182 ++++-
25 drivers/net/ethernet/mediatek/mtk_eth_soc.h | 232 ++++++-
26 drivers/net/ethernet/mediatek/mtk_usxgmii.c | 692 +++++++++++++++++++
27 6 files changed, 1215 insertions(+), 31 deletions(-)
28 create mode 100644 drivers/net/ethernet/mediatek/mtk_usxgmii.c
29
30 --- a/drivers/net/ethernet/mediatek/Kconfig
31 +++ b/drivers/net/ethernet/mediatek/Kconfig
32 @@ -24,6 +24,22 @@ config NET_MEDIATEK_SOC
33 This driver supports the gigabit ethernet MACs in the
34 MediaTek SoC family.
35
36 +config NET_MEDIATEK_SOC_USXGMII
37 + bool "Support USXGMII SerDes on MT7988"
38 + depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
39 + def_bool NET_MEDIATEK_SOC != n
40 + help
41 + Include support for 10GE SerDes which can be found on MT7988.
42 + If this kernel should run on SoCs with 10 GBit/s Ethernet you
43 + will need to select this option to use GMAC2 and GMAC3 with
44 + external PHYs, SFP(+) cages in 10GBase-R, 5GBase-R or USXGMII
45 + interface modes.
46 +
47 + Note that as the 2500Base-X/1000Base-X/Cisco SGMII SerDes PCS
48 + unit (MediaTek LynxI) in MT7988 is connected via the new 10GE
49 + SerDes, you will also need to select this option in case you
50 + want to use any of those SerDes modes.
51 +
52 config NET_MEDIATEK_STAR_EMAC
53 tristate "MediaTek STAR Ethernet MAC support"
54 select PHYLIB
55 --- a/drivers/net/ethernet/mediatek/Makefile
56 +++ b/drivers/net/ethernet/mediatek/Makefile
57 @@ -5,6 +5,7 @@
58
59 obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o
60 mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o
61 +mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_USXGMII) += mtk_usxgmii.o
62 mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o
63 ifdef CONFIG_DEBUG_FS
64 mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o
65 --- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
66 +++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
67 @@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64
68 return "gmac2_rgmii";
69 case MTK_ETH_PATH_GMAC2_SGMII:
70 return "gmac2_sgmii";
71 + case MTK_ETH_PATH_GMAC2_2P5GPHY:
72 + return "gmac2_2p5gphy";
73 case MTK_ETH_PATH_GMAC2_GEPHY:
74 return "gmac2_gephy";
75 + case MTK_ETH_PATH_GMAC3_SGMII:
76 + return "gmac3_sgmii";
77 case MTK_ETH_PATH_GDM1_ESW:
78 return "gdm1_esw";
79 + case MTK_ETH_PATH_GMAC1_USXGMII:
80 + return "gmac1_usxgmii";
81 + case MTK_ETH_PATH_GMAC2_USXGMII:
82 + return "gmac2_usxgmii";
83 + case MTK_ETH_PATH_GMAC3_USXGMII:
84 + return "gmac3_usxgmii";
85 default:
86 return "unknown path";
87 }
88 @@ -127,6 +137,27 @@ static int set_mux_u3_gmac2_to_qphy(stru
89 return 0;
90 }
91
92 +static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path)
93 +{
94 + int ret;
95 +
96 + if (path == MTK_ETH_PATH_GMAC2_2P5GPHY) {
97 + ret = regmap_clear_bits(eth->ethsys, ETHSYS_SYSCFG0, SYSCFG0_SGMII_GMAC2_V2);
98 + if (ret)
99 + return ret;
100 +
101 + /* Setup mux to 2p5g PHY */
102 + ret = regmap_clear_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, MUX_G2_USXGMII_SEL);
103 + if (ret)
104 + return ret;
105 +
106 + dev_dbg(eth->dev, "path %s in %s updated\n",
107 + mtk_eth_path_name(path), __func__);
108 + }
109 +
110 + return 0;
111 +}
112 +
113 static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
114 {
115 unsigned int val = 0;
116 @@ -165,7 +196,48 @@ static int set_mux_gmac1_gmac2_to_sgmii_
117 return 0;
118 }
119
120 -static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
121 +static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path)
122 +{
123 + unsigned int val = 0;
124 + bool updated = true;
125 + int mac_id = 0;
126 +
127 + /* Disable SYSCFG1 SGMII */
128 + regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
129 +
130 + switch (path) {
131 + case MTK_ETH_PATH_GMAC1_USXGMII:
132 + val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2;
133 + mac_id = MTK_GMAC1_ID;
134 + break;
135 + case MTK_ETH_PATH_GMAC2_USXGMII:
136 + val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2;
137 + mac_id = MTK_GMAC2_ID;
138 + break;
139 + case MTK_ETH_PATH_GMAC3_USXGMII:
140 + val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2;
141 + mac_id = MTK_GMAC3_ID;
142 + break;
143 + default:
144 + updated = false;
145 + };
146 +
147 + if (updated) {
148 + regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
149 + SYSCFG0_SGMII_MASK, val);
150 +
151 + if (mac_id == MTK_GMAC2_ID)
152 + regmap_set_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX,
153 + MUX_G2_USXGMII_SEL);
154 + }
155 +
156 + dev_dbg(eth->dev, "path %s in %s updated = %d\n",
157 + mtk_eth_path_name(path), __func__, updated);
158 +
159 + return 0;
160 +}
161 +
162 +static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
163 {
164 unsigned int val = 0;
165 bool updated = true;
166 @@ -182,6 +254,9 @@ static int set_mux_gmac12_to_gephy_sgmii
167 case MTK_ETH_PATH_GMAC2_SGMII:
168 val |= SYSCFG0_SGMII_GMAC2_V2;
169 break;
170 + case MTK_ETH_PATH_GMAC3_SGMII:
171 + val |= SYSCFG0_SGMII_GMAC3_V2;
172 + break;
173 default:
174 updated = false;
175 }
176 @@ -210,13 +285,25 @@ static const struct mtk_eth_muxc mtk_eth
177 .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY,
178 .set_path = set_mux_u3_gmac2_to_qphy,
179 }, {
180 + .name = "mux_gmac2_to_2p5gphy",
181 + .cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY,
182 + .set_path = set_mux_gmac2_to_2p5gphy,
183 + }, {
184 .name = "mux_gmac1_gmac2_to_sgmii_rgmii",
185 .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII,
186 .set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii,
187 }, {
188 .name = "mux_gmac12_to_gephy_sgmii",
189 .cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII,
190 - .set_path = set_mux_gmac12_to_gephy_sgmii,
191 + .set_path = set_mux_gmac123_to_gephy_sgmii,
192 + }, {
193 + .name = "mux_gmac123_to_gephy_sgmii",
194 + .cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII,
195 + .set_path = set_mux_gmac123_to_gephy_sgmii,
196 + }, {
197 + .name = "mux_gmac123_to_usxgmii",
198 + .cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII,
199 + .set_path = set_mux_gmac123_to_usxgmii,
200 },
201 };
202
203 @@ -249,12 +336,39 @@ out:
204 return err;
205 }
206
207 +int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id)
208 +{
209 + u64 path;
210 +
211 + path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_USXGMII :
212 + (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_USXGMII :
213 + MTK_ETH_PATH_GMAC3_USXGMII;
214 +
215 + /* Setup proper MUXes along the path */
216 + return mtk_eth_mux_setup(eth, path);
217 +}
218 +
219 int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
220 {
221 u64 path;
222
223 - path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII :
224 - MTK_ETH_PATH_GMAC2_SGMII;
225 + path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII :
226 + (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII :
227 + MTK_ETH_PATH_GMAC3_SGMII;
228 +
229 + /* Setup proper MUXes along the path */
230 + return mtk_eth_mux_setup(eth, path);
231 +}
232 +
233 +int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id)
234 +{
235 + u64 path = 0;
236 +
237 + if (mac_id == MTK_GMAC2_ID)
238 + path = MTK_ETH_PATH_GMAC2_2P5GPHY;
239 +
240 + if (!path)
241 + return -EINVAL;
242
243 /* Setup proper MUXes along the path */
244 return mtk_eth_mux_setup(eth, path);
245 @@ -284,4 +398,3 @@ int mtk_gmac_rgmii_path_setup(struct mtk
246 /* Setup proper MUXes along the path */
247 return mtk_eth_mux_setup(eth, path);
248 }
249 -
250 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
251 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
252 @@ -432,6 +432,30 @@ static void mtk_setup_bridge_switch(stru
253 MTK_GSW_CFG);
254 }
255
256 +static bool mtk_check_gmac23_idle(struct mtk_mac *mac)
257 +{
258 + u32 mac_fsm, gdm_fsm;
259 +
260 + mac_fsm = mtk_r32(mac->hw, MTK_MAC_FSM(mac->id));
261 +
262 + switch (mac->id) {
263 + case MTK_GMAC2_ID:
264 + gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM2_FSM);
265 + break;
266 + case MTK_GMAC3_ID:
267 + gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM3_FSM);
268 + break;
269 + default:
270 + return true;
271 + };
272 +
273 + if ((mac_fsm & 0xFFFF0000) == 0x01010000 &&
274 + (gdm_fsm & 0xFFFF0000) == 0x00000000)
275 + return true;
276 +
277 + return false;
278 +}
279 +
280 static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
281 phy_interface_t interface)
282 {
283 @@ -440,12 +464,20 @@ static struct phylink_pcs *mtk_mac_selec
284 struct mtk_eth *eth = mac->hw;
285 unsigned int sid;
286
287 - if (interface == PHY_INTERFACE_MODE_SGMII ||
288 - phy_interface_mode_is_8023z(interface)) {
289 - sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
290 - 0 : mac->id;
291 -
292 - return eth->sgmii_pcs[sid];
293 + if ((interface == PHY_INTERFACE_MODE_SGMII ||
294 + phy_interface_mode_is_8023z(interface)) &&
295 + MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
296 + sid = mtk_mac2xgmii_id(eth, mac->id);
297 + if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII))
298 + return mtk_sgmii_wrapper_select_pcs(eth, mac->id);
299 + else
300 + return eth->sgmii_pcs[sid];
301 + } else if ((interface == PHY_INTERFACE_MODE_USXGMII ||
302 + interface == PHY_INTERFACE_MODE_10GBASER ||
303 + interface == PHY_INTERFACE_MODE_5GBASER) &&
304 + MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII) &&
305 + mac->id != MTK_GMAC1_ID) {
306 + return mtk_usxgmii_select_pcs(eth, mac->id);
307 }
308
309 return NULL;
310 @@ -501,7 +533,22 @@ static void mtk_mac_config(struct phylin
311 goto init_err;
312 }
313 break;
314 + case PHY_INTERFACE_MODE_USXGMII:
315 + case PHY_INTERFACE_MODE_10GBASER:
316 + case PHY_INTERFACE_MODE_5GBASER:
317 + if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) {
318 + err = mtk_gmac_usxgmii_path_setup(eth, mac->id);
319 + if (err)
320 + goto init_err;
321 + }
322 + break;
323 case PHY_INTERFACE_MODE_INTERNAL:
324 + if (mac->id == MTK_GMAC2_ID &&
325 + MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) {
326 + err = mtk_gmac_2p5gphy_path_setup(eth, mac->id);
327 + if (err)
328 + goto init_err;
329 + }
330 break;
331 default:
332 goto err_phy;
333 @@ -556,8 +603,6 @@ static void mtk_mac_config(struct phylin
334 val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id);
335 val |= SYSCFG0_GE_MODE(ge_mode, mac->id);
336 regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
337 -
338 - mac->interface = state->interface;
339 }
340
341 /* SGMII */
342 @@ -574,21 +619,40 @@ static void mtk_mac_config(struct phylin
343
344 /* Save the syscfg0 value for mac_finish */
345 mac->syscfg0 = val;
346 - } else if (phylink_autoneg_inband(mode)) {
347 + } else if (state->interface != PHY_INTERFACE_MODE_USXGMII &&
348 + state->interface != PHY_INTERFACE_MODE_10GBASER &&
349 + state->interface != PHY_INTERFACE_MODE_5GBASER &&
350 + phylink_autoneg_inband(mode)) {
351 dev_err(eth->dev,
352 - "In-band mode not supported in non SGMII mode!\n");
353 + "In-band mode not supported in non-SerDes modes!\n");
354 return;
355 }
356
357 /* Setup gmac */
358 - if (mtk_is_netsys_v3_or_greater(eth) &&
359 - mac->interface == PHY_INTERFACE_MODE_INTERNAL) {
360 - mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
361 - mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
362 + if (mtk_is_netsys_v3_or_greater(eth)) {
363 + if (mtk_interface_mode_is_xgmii(state->interface)) {
364 + mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
365 + mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
366 +
367 + if (mac->id == MTK_GMAC1_ID)
368 + mtk_setup_bridge_switch(eth);
369 + } else {
370 + mtk_w32(eth, 0, MTK_GDMA_EG_CTRL(mac->id));
371
372 - mtk_setup_bridge_switch(eth);
373 + /* FIXME: In current hardware design, we have to reset FE
374 + * when swtiching XGDM to GDM. Therefore, here trigger an SER
375 + * to let GDM go back to the initial state.
376 + */
377 + if ((mtk_interface_mode_is_xgmii(mac->interface) ||
378 + mac->interface == PHY_INTERFACE_MODE_NA) &&
379 + !mtk_check_gmac23_idle(mac) &&
380 + !test_bit(MTK_RESETTING, &eth->state))
381 + schedule_work(&eth->pending_work);
382 + }
383 }
384
385 + mac->interface = state->interface;
386 +
387 return;
388
389 err_phy:
390 @@ -633,10 +697,14 @@ static void mtk_mac_link_down(struct phy
391 {
392 struct mtk_mac *mac = container_of(config, struct mtk_mac,
393 phylink_config);
394 - u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
395
396 - mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK);
397 - mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
398 + if (!mtk_interface_mode_is_xgmii(interface)) {
399 + mtk_m32(mac->hw, MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK, 0, MTK_MAC_MCR(mac->id));
400 + if (mtk_is_netsys_v3_or_greater(eth))
401 + mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), 0, MTK_XGMAC_STS(mac->id));
402 + } else if (mac->id != MTK_GMAC1_ID) {
403 + mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE, MTK_XMAC_MCR(mac->id));
404 + }
405 }
406
407 static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
408 @@ -708,13 +776,11 @@ static void mtk_set_queue_speed(struct m
409 mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
410 }
411
412 -static void mtk_mac_link_up(struct phylink_config *config,
413 - struct phy_device *phy,
414 - unsigned int mode, phy_interface_t interface,
415 - int speed, int duplex, bool tx_pause, bool rx_pause)
416 +static void mtk_gdm_mac_link_up(struct mtk_mac *mac,
417 + struct phy_device *phy,
418 + unsigned int mode, phy_interface_t interface,
419 + int speed, int duplex, bool tx_pause, bool rx_pause)
420 {
421 - struct mtk_mac *mac = container_of(config, struct mtk_mac,
422 - phylink_config);
423 u32 mcr;
424
425 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
426 @@ -748,6 +814,55 @@ static void mtk_mac_link_up(struct phyli
427 mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
428 }
429
430 +static void mtk_xgdm_mac_link_up(struct mtk_mac *mac,
431 + struct phy_device *phy,
432 + unsigned int mode, phy_interface_t interface,
433 + int speed, int duplex, bool tx_pause, bool rx_pause)
434 +{
435 + u32 mcr, force_link = 0;
436 +
437 + if (mac->id == MTK_GMAC1_ID)
438 + return;
439 +
440 + /* Eliminate the interference(before link-up) caused by PHY noise */
441 + mtk_m32(mac->hw, XMAC_LOGIC_RST, 0, MTK_XMAC_LOGIC_RST(mac->id));
442 + mdelay(20);
443 + mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR, MTK_XMAC_CNT_CTRL(mac->id));
444 +
445 + if (mac->interface == PHY_INTERFACE_MODE_INTERNAL || mac->id == MTK_GMAC3_ID)
446 + force_link = MTK_XGMAC_FORCE_LINK(mac->id);
447 +
448 + mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), force_link, MTK_XGMAC_STS(mac->id));
449 +
450 + mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
451 + mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC | XMAC_MCR_TRX_DISABLE);
452 + /* Configure pause modes -
453 + * phylink will avoid these for half duplex
454 + */
455 + if (tx_pause)
456 + mcr |= XMAC_MCR_FORCE_TX_FC;
457 + if (rx_pause)
458 + mcr |= XMAC_MCR_FORCE_RX_FC;
459 +
460 + mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
461 +}
462 +
463 +static void mtk_mac_link_up(struct phylink_config *config,
464 + struct phy_device *phy,
465 + unsigned int mode, phy_interface_t interface,
466 + int speed, int duplex, bool tx_pause, bool rx_pause)
467 +{
468 + struct mtk_mac *mac = container_of(config, struct mtk_mac,
469 + phylink_config);
470 +
471 + if (mtk_interface_mode_is_xgmii(interface))
472 + mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
473 + tx_pause, rx_pause);
474 + else
475 + mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
476 + tx_pause, rx_pause);
477 +}
478 +
479 static const struct phylink_mac_ops mtk_phylink_ops = {
480 .validate = phylink_generic_validate,
481 .mac_select_pcs = mtk_mac_select_pcs,
482 @@ -4562,8 +4677,21 @@ static int mtk_add_mac(struct mtk_eth *e
483 phy_interface_zero(mac->phylink_config.supported_interfaces);
484 __set_bit(PHY_INTERFACE_MODE_INTERNAL,
485 mac->phylink_config.supported_interfaces);
486 + } else if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) {
487 + mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD;
488 + __set_bit(PHY_INTERFACE_MODE_5GBASER,
489 + mac->phylink_config.supported_interfaces);
490 + __set_bit(PHY_INTERFACE_MODE_10GBASER,
491 + mac->phylink_config.supported_interfaces);
492 + __set_bit(PHY_INTERFACE_MODE_USXGMII,
493 + mac->phylink_config.supported_interfaces);
494 }
495
496 + if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) &&
497 + id == MTK_GMAC2_ID)
498 + __set_bit(PHY_INTERFACE_MODE_INTERNAL,
499 + mac->phylink_config.supported_interfaces);
500 +
501 phylink = phylink_create(&mac->phylink_config,
502 of_fwnode_handle(mac->of_node),
503 phy_mode, &mtk_phylink_ops);
504 @@ -4756,6 +4884,13 @@ static int mtk_probe(struct platform_dev
505
506 if (err)
507 return err;
508 + }
509 +
510 + if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) {
511 + err = mtk_usxgmii_init(eth);
512 +
513 + if (err)
514 + return err;
515 }
516
517 if (eth->soc->required_pctl) {
518 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
519 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
520 @@ -499,6 +499,21 @@
521 #define INTF_MODE_RGMII_1000 (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED)
522 #define INTF_MODE_RGMII_10_100 0
523
524 +/* XFI Mac control registers */
525 +#define MTK_XMAC_BASE(x) (0x12000 + (((x) - 1) * 0x1000))
526 +#define MTK_XMAC_MCR(x) (MTK_XMAC_BASE(x))
527 +#define XMAC_MCR_TRX_DISABLE 0xf
528 +#define XMAC_MCR_FORCE_TX_FC BIT(5)
529 +#define XMAC_MCR_FORCE_RX_FC BIT(4)
530 +
531 +/* XFI Mac logic reset registers */
532 +#define MTK_XMAC_LOGIC_RST(x) (MTK_XMAC_BASE(x) + 0x10)
533 +#define XMAC_LOGIC_RST BIT(0)
534 +
535 +/* XFI Mac count global control */
536 +#define MTK_XMAC_CNT_CTRL(x) (MTK_XMAC_BASE(x) + 0x100)
537 +#define XMAC_GLB_CNTCLR BIT(0)
538 +
539 /* GPIO port control registers for GMAC 2*/
540 #define GPIO_OD33_CTRL8 0x4c0
541 #define GPIO_BIAS_CTRL 0xed0
542 @@ -524,6 +539,7 @@
543 #define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK)
544 #define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
545 #define SYSCFG0_SGMII_GMAC2_V2 BIT(8)
546 +#define SYSCFG0_SGMII_GMAC3_V2 BIT(7)
547
548
549 /* ethernet subsystem clock register */
550 @@ -556,12 +572,74 @@
551 #define ETHSYS_DMA_AG_MAP_QDMA BIT(1)
552 #define ETHSYS_DMA_AG_MAP_PPE BIT(2)
553
554 +/* USXGMII subsystem config registers */
555 +/* Register to control speed */
556 +#define RG_PHY_TOP_SPEED_CTRL1 0x80C
557 +#define USXGMII_RATE_UPDATE_MODE BIT(31)
558 +#define USXGMII_MAC_CK_GATED BIT(29)
559 +#define USXGMII_IF_FORCE_EN BIT(28)
560 +#define USXGMII_RATE_ADAPT_MODE GENMASK(10, 8)
561 +#define USXGMII_RATE_ADAPT_MODE_X1 0
562 +#define USXGMII_RATE_ADAPT_MODE_X2 1
563 +#define USXGMII_RATE_ADAPT_MODE_X4 2
564 +#define USXGMII_RATE_ADAPT_MODE_X10 3
565 +#define USXGMII_RATE_ADAPT_MODE_X100 4
566 +#define USXGMII_RATE_ADAPT_MODE_X5 5
567 +#define USXGMII_RATE_ADAPT_MODE_X50 6
568 +#define USXGMII_XFI_RX_MODE GENMASK(6, 4)
569 +#define USXGMII_XFI_RX_MODE_10G 0
570 +#define USXGMII_XFI_RX_MODE_5G 1
571 +#define USXGMII_XFI_TX_MODE GENMASK(2, 0)
572 +#define USXGMII_XFI_TX_MODE_10G 0
573 +#define USXGMII_XFI_TX_MODE_5G 1
574 +
575 +/* Register to control PCS AN */
576 +#define RG_PCS_AN_CTRL0 0x810
577 +#define USXGMII_AN_RESTART BIT(31)
578 +#define USXGMII_AN_SYNC_CNT GENMASK(30, 11)
579 +#define USXGMII_AN_ENABLE BIT(0)
580 +
581 +#define RG_PCS_AN_CTRL2 0x818
582 +#define USXGMII_LINK_TIMER_IDLE_DETECT GENMASK(29, 20)
583 +#define USXGMII_LINK_TIMER_COMP_ACK_DETECT GENMASK(19, 10)
584 +#define USXGMII_LINK_TIMER_AN_RESTART GENMASK(9, 0)
585 +
586 +/* Register to read PCS AN status */
587 +#define RG_PCS_AN_STS0 0x81c
588 +#define USXGMII_PCS_AN_WORD GENMASK(15, 0)
589 +#define USXGMII_LPA_LATCH BIT(31)
590 +
591 +/* Register to control USXGMII XFI PLL digital */
592 +#define XFI_PLL_DIG_GLB8 0x08
593 +#define RG_XFI_PLL_EN BIT(31)
594 +
595 +/* Register to control USXGMII XFI PLL analog */
596 +#define XFI_PLL_ANA_GLB8 0x108
597 +#define RG_XFI_PLL_ANA_SWWA 0x02283248
598 +
599 /* Infrasys subsystem config registers */
600 #define INFRA_MISC2 0x70c
601 #define CO_QPHY_SEL BIT(0)
602 #define GEPHY_MAC_SEL BIT(1)
603
604 +/* Toprgu subsystem config registers */
605 +#define TOPRGU_SWSYSRST 0x18
606 +#define SWSYSRST_UNLOCK_KEY GENMASK(31, 24)
607 +#define SWSYSRST_XFI_PLL_GRST BIT(16)
608 +#define SWSYSRST_XFI_PEXPT1_GRST BIT(15)
609 +#define SWSYSRST_XFI_PEXPT0_GRST BIT(14)
610 +#define SWSYSRST_XFI1_GRST BIT(13)
611 +#define SWSYSRST_XFI0_GRST BIT(12)
612 +#define SWSYSRST_SGMII1_GRST BIT(2)
613 +#define SWSYSRST_SGMII0_GRST BIT(1)
614 +#define TOPRGU_SWSYSRST_EN 0xFC
615 +
616 /* Top misc registers */
617 +#define TOP_MISC_NETSYS_PCS_MUX 0x84
618 +#define NETSYS_PCS_MUX_MASK GENMASK(1, 0)
619 +#define MUX_G2_USXGMII_SEL BIT(1)
620 +#define MUX_HSGMII1_G1_SEL BIT(0)
621 +
622 #define USB_PHY_SWITCH_REG 0x218
623 #define QPHY_SEL_MASK GENMASK(1, 0)
624 #define SGMII_QPHY_SEL 0x2
625 @@ -586,6 +664,8 @@
626 #define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c)
627 #define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110)
628
629 +/* Debug Purpose Register */
630 +#define MTK_PSE_FQFC_CFG 0x100
631 #define MTK_FE_CDM1_FSM 0x220
632 #define MTK_FE_CDM2_FSM 0x224
633 #define MTK_FE_CDM3_FSM 0x238
634 @@ -594,6 +674,11 @@
635 #define MTK_FE_CDM6_FSM 0x328
636 #define MTK_FE_GDM1_FSM 0x228
637 #define MTK_FE_GDM2_FSM 0x22C
638 +#define MTK_FE_GDM3_FSM 0x23C
639 +#define MTK_FE_PSE_FREE 0x240
640 +#define MTK_FE_DROP_FQ 0x244
641 +#define MTK_FE_DROP_FC 0x248
642 +#define MTK_FE_DROP_PPE 0x24C
643
644 #define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100))
645
646 @@ -940,6 +1025,8 @@ enum mkt_eth_capabilities {
647 MTK_RGMII_BIT = 0,
648 MTK_TRGMII_BIT,
649 MTK_SGMII_BIT,
650 + MTK_USXGMII_BIT,
651 + MTK_2P5GPHY_BIT,
652 MTK_ESW_BIT,
653 MTK_GEPHY_BIT,
654 MTK_MUX_BIT,
655 @@ -960,8 +1047,11 @@ enum mkt_eth_capabilities {
656 MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
657 MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT,
658 MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
659 + MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT,
660 MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT,
661 MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT,
662 + MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT,
663 + MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT,
664
665 /* PATH BITS */
666 MTK_ETH_PATH_GMAC1_RGMII_BIT,
667 @@ -969,14 +1059,21 @@ enum mkt_eth_capabilities {
668 MTK_ETH_PATH_GMAC1_SGMII_BIT,
669 MTK_ETH_PATH_GMAC2_RGMII_BIT,
670 MTK_ETH_PATH_GMAC2_SGMII_BIT,
671 + MTK_ETH_PATH_GMAC2_2P5GPHY_BIT,
672 MTK_ETH_PATH_GMAC2_GEPHY_BIT,
673 + MTK_ETH_PATH_GMAC3_SGMII_BIT,
674 MTK_ETH_PATH_GDM1_ESW_BIT,
675 + MTK_ETH_PATH_GMAC1_USXGMII_BIT,
676 + MTK_ETH_PATH_GMAC2_USXGMII_BIT,
677 + MTK_ETH_PATH_GMAC3_USXGMII_BIT,
678 };
679
680 /* Supported hardware group on SoCs */
681 #define MTK_RGMII BIT_ULL(MTK_RGMII_BIT)
682 #define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT)
683 #define MTK_SGMII BIT_ULL(MTK_SGMII_BIT)
684 +#define MTK_USXGMII BIT_ULL(MTK_USXGMII_BIT)
685 +#define MTK_2P5GPHY BIT_ULL(MTK_2P5GPHY_BIT)
686 #define MTK_ESW BIT_ULL(MTK_ESW_BIT)
687 #define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT)
688 #define MTK_MUX BIT_ULL(MTK_MUX_BIT)
689 @@ -999,10 +1096,16 @@ enum mkt_eth_capabilities {
690 BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
691 #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \
692 BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
693 +#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY \
694 + BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT)
695 #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \
696 BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
697 #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \
698 BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
699 +#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII \
700 + BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT)
701 +#define MTK_ETH_MUX_GMAC123_TO_USXGMII \
702 + BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT)
703
704 /* Supported path present on SoCs */
705 #define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
706 @@ -1010,8 +1113,13 @@ enum mkt_eth_capabilities {
707 #define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
708 #define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
709 #define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
710 +#define MTK_ETH_PATH_GMAC2_2P5GPHY BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT)
711 #define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
712 +#define MTK_ETH_PATH_GMAC3_SGMII BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT)
713 #define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
714 +#define MTK_ETH_PATH_GMAC1_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT)
715 +#define MTK_ETH_PATH_GMAC2_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT)
716 +#define MTK_ETH_PATH_GMAC3_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT)
717
718 #define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
719 #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
720 @@ -1019,7 +1127,12 @@ enum mkt_eth_capabilities {
721 #define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
722 #define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
723 #define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
724 +#define MTK_GMAC2_2P5GPHY (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY)
725 +#define MTK_GMAC3_SGMII (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
726 #define MTK_GDM1_ESW (MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
727 +#define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
728 +#define MTK_GMAC2_USXGMII (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII)
729 +#define MTK_GMAC3_USXGMII (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII)
730
731 /* MUXes present on SoCs */
732 /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */
733 @@ -1038,10 +1151,20 @@ enum mkt_eth_capabilities {
734 (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \
735 MTK_SHARED_SGMII)
736
737 +/* 2: GMAC2 -> XGMII */
738 +#define MTK_MUX_GMAC2_TO_2P5GPHY \
739 + (MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA)
740 +
741 /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */
742 #define MTK_MUX_GMAC12_TO_GEPHY_SGMII \
743 (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
744
745 +#define MTK_MUX_GMAC123_TO_GEPHY_SGMII \
746 + (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX)
747 +
748 +#define MTK_MUX_GMAC123_TO_USXGMII \
749 + (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA)
750 +
751 #define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x))
752
753 #define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
754 @@ -1073,8 +1196,12 @@ enum mkt_eth_capabilities {
755 MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
756 MTK_RSTCTRL_PPE1 | MTK_SRAM)
757
758 -#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \
759 - MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
760 +#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \
761 + MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \
762 + MTK_GMAC3_SGMII | MTK_GMAC3_USXGMII | \
763 + MTK_MUX_GMAC123_TO_GEPHY_SGMII | \
764 + MTK_MUX_GMAC123_TO_USXGMII | MTK_MUX_GMAC2_TO_2P5GPHY | \
765 + MTK_QDMA | MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
766
767 struct mtk_tx_dma_desc_info {
768 dma_addr_t addr;
769 @@ -1184,6 +1311,24 @@ struct mtk_soc_data {
770 /* currently no SoC has more than 3 macs */
771 #define MTK_MAX_DEVS 3
772
773 +/* struct mtk_usxgmii_pcs - This structure holds each usxgmii regmap and
774 + * associated data
775 + * @regmap: The register map pointing at the range used to setup
776 + * USXGMII modes
777 + * @interface: Currently selected interface mode
778 + * @id: The element is used to record the index of PCS
779 + * @pcs: Phylink PCS structure
780 + */
781 +struct mtk_usxgmii_pcs {
782 + struct mtk_eth *eth;
783 + struct regmap *regmap;
784 + struct phylink_pcs *wrapped_sgmii_pcs;
785 + phy_interface_t interface;
786 + u8 id;
787 + unsigned int mode;
788 + struct phylink_pcs pcs;
789 +};
790 +
791 /* struct mtk_eth - This is the main datasructure for holding the state
792 * of the driver
793 * @dev: The device pointer
794 @@ -1204,6 +1349,12 @@ struct mtk_soc_data {
795 * @infra: The register map pointing at the range used to setup
796 * SGMII and GePHY path
797 * @sgmii_pcs: Pointers to mtk-pcs-lynxi phylink_pcs instances
798 + * @sgmii_wrapped_pcs: Pointers to NETSYSv3 wrapper PCS instances
799 + * @usxgmii_pll: The register map pointing at the range used to control
800 + * the USXGMII SerDes PLL
801 + * @regmap_pextp: The register map pointing at the range used to setup
802 + * PHYA
803 + * @usxgmii_pcs: Pointer to array of pointers to struct for USXGMII PCS
804 * @pctl: The register map pointing at the range used to setup
805 * GMAC port drive/slew values
806 * @dma_refcnt: track how many netdevs are using the DMA engine
807 @@ -1247,6 +1398,10 @@ struct mtk_eth {
808 struct regmap *ethsys;
809 struct regmap *infra;
810 struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS];
811 + struct regmap *toprgu;
812 + struct regmap *usxgmii_pll;
813 + struct regmap *regmap_pextp[MTK_MAX_DEVS];
814 + struct mtk_usxgmii_pcs *usxgmii_pcs[MTK_MAX_DEVS];
815 struct regmap *pctl;
816 bool hwlro;
817 refcount_t dma_refcnt;
818 @@ -1434,6 +1589,19 @@ static inline u32 mtk_get_ib2_multicast_
819 return MTK_FOE_IB2_MULTICAST;
820 }
821
822 +static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface)
823 +{
824 + switch (interface) {
825 + case PHY_INTERFACE_MODE_INTERNAL:
826 + case PHY_INTERFACE_MODE_USXGMII:
827 + case PHY_INTERFACE_MODE_10GBASER:
828 + case PHY_INTERFACE_MODE_5GBASER:
829 + return true;
830 + default:
831 + return false;
832 + }
833 +}
834 +
835 /* read the hardware status register */
836 void mtk_stats_update_mac(struct mtk_mac *mac);
837
838 @@ -1442,8 +1610,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
839 u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg);
840
841 int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
842 +int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id);
843 int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
844 int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id);
845 +int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id);
846
847 int mtk_eth_offload_init(struct mtk_eth *eth);
848 int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
849 @@ -1453,5 +1623,63 @@ int mtk_flow_offload_cmd(struct mtk_eth
850 void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list);
851 void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
852
853 +static inline int mtk_mac2xgmii_id(struct mtk_eth *eth, int mac_id)
854 +{
855 + int xgmii_id = mac_id;
856 +
857 + if (mtk_is_netsys_v3_or_greater(eth)) {
858 + switch (mac_id) {
859 + case MTK_GMAC1_ID:
860 + case MTK_GMAC2_ID:
861 + xgmii_id = 1;
862 + break;
863 + case MTK_GMAC3_ID:
864 + xgmii_id = 0;
865 + break;
866 + default:
867 + xgmii_id = -1;
868 + }
869 + }
870 +
871 + return MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII) ? 0 : xgmii_id;
872 +}
873 +
874 +static inline int mtk_xgmii2mac_id(struct mtk_eth *eth, int xgmii_id)
875 +{
876 + int mac_id = xgmii_id;
877 +
878 + if (mtk_is_netsys_v3_or_greater(eth)) {
879 + switch (xgmii_id) {
880 + case 0:
881 + mac_id = 2;
882 + break;
883 + case 1:
884 + mac_id = 1;
885 + break;
886 + default:
887 + mac_id = -1;
888 + }
889 + }
890 +
891 + return mac_id;
892 +}
893 +
894 +#ifdef CONFIG_NET_MEDIATEK_SOC_USXGMII
895 +struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int id);
896 +struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id);
897 +int mtk_usxgmii_init(struct mtk_eth *eth);
898 +#else
899 +static inline struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int id)
900 +{
901 + return NULL;
902 +}
903 +
904 +static inline struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id)
905 +{
906 + return NULL;
907 +}
908 +
909 +static inline int mtk_usxgmii_init(struct mtk_eth *eth) { return 0; }
910 +#endif /* NET_MEDIATEK_SOC_USXGMII */
911
912 #endif /* MTK_ETH_H */
913 --- /dev/null
914 +++ b/drivers/net/ethernet/mediatek/mtk_usxgmii.c
915 @@ -0,0 +1,690 @@
916 +// SPDX-License-Identifier: GPL-2.0
917 +/*
918 + * Copyright (c) 2023 MediaTek Inc.
919 + * Author: Henry Yen <henry.yen@mediatek.com>
920 + * Daniel Golle <daniel@makrotopia.org>
921 + */
922 +
923 +#include <linux/mfd/syscon.h>
924 +#include <linux/of.h>
925 +#include <linux/regmap.h>
926 +#include "mtk_eth_soc.h"
927 +
928 +static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs)
929 +{
930 + return container_of(pcs, struct mtk_usxgmii_pcs, pcs);
931 +}
932 +
933 +static int mtk_xfi_pextp_init(struct mtk_eth *eth)
934 +{
935 + struct device *dev = eth->dev;
936 + struct device_node *r = dev->of_node;
937 + struct device_node *np;
938 + int i;
939 +
940 + for (i = 0; i < MTK_MAX_DEVS; i++) {
941 + np = of_parse_phandle(r, "mediatek,xfi-pextp", i);
942 + if (!np)
943 + break;
944 +
945 + eth->regmap_pextp[i] = syscon_node_to_regmap(np);
946 + if (IS_ERR(eth->regmap_pextp[i]))
947 + return PTR_ERR(eth->regmap_pextp[i]);
948 + }
949 +
950 + return 0;
951 +}
952 +
953 +static int mtk_xfi_pll_init(struct mtk_eth *eth)
954 +{
955 + struct device_node *r = eth->dev->of_node;
956 + struct device_node *np;
957 +
958 + np = of_parse_phandle(r, "mediatek,xfi-pll", 0);
959 + if (!np)
960 + return -1;
961 +
962 + eth->usxgmii_pll = syscon_node_to_regmap(np);
963 + if (IS_ERR(eth->usxgmii_pll))
964 + return PTR_ERR(eth->usxgmii_pll);
965 +
966 + return 0;
967 +}
968 +
969 +static int mtk_toprgu_init(struct mtk_eth *eth)
970 +{
971 + struct device_node *r = eth->dev->of_node;
972 + struct device_node *np;
973 +
974 + np = of_parse_phandle(r, "mediatek,toprgu", 0);
975 + if (!np)
976 + return -1;
977 +
978 + eth->toprgu = syscon_node_to_regmap(np);
979 + if (IS_ERR(eth->toprgu))
980 + return PTR_ERR(eth->toprgu);
981 +
982 + return 0;
983 +}
984 +
985 +static int mtk_xfi_pll_enable(struct mtk_eth *eth)
986 +{
987 + u32 val = 0;
988 +
989 + if (!eth->usxgmii_pll)
990 + return -EINVAL;
991 +
992 + /* Add software workaround for USXGMII PLL TCL issue */
993 + regmap_write(eth->usxgmii_pll, XFI_PLL_ANA_GLB8, RG_XFI_PLL_ANA_SWWA);
994 +
995 + regmap_read(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, &val);
996 + val |= RG_XFI_PLL_EN;
997 + regmap_write(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, val);
998 +
999 + return 0;
1000 +}
1001 +
1002 +static void mtk_usxgmii_setup_phya(struct regmap *pextp, phy_interface_t interface, int id)
1003 +{
1004 + bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
1005 + interface == PHY_INTERFACE_MODE_USXGMII);
1006 + bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
1007 + bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
1008 +
1009 + /* Setup operation mode */
1010 + if (is_10g)
1011 + regmap_write(pextp, 0x9024, 0x00C9071C);
1012 + else
1013 + regmap_write(pextp, 0x9024, 0x00D9071C);
1014 +
1015 + if (is_5g)
1016 + regmap_write(pextp, 0x2020, 0xAAA5A5AA);
1017 + else
1018 + regmap_write(pextp, 0x2020, 0xAA8585AA);
1019 +
1020 + if (is_2p5g || is_5g || is_10g) {
1021 + regmap_write(pextp, 0x2030, 0x0C020707);
1022 + regmap_write(pextp, 0x2034, 0x0E050F0F);
1023 + regmap_write(pextp, 0x2040, 0x00140032);
1024 + } else {
1025 + regmap_write(pextp, 0x2030, 0x0C020207);
1026 + regmap_write(pextp, 0x2034, 0x0E05050F);
1027 + regmap_write(pextp, 0x2040, 0x00200032);
1028 + }
1029 +
1030 + if (is_2p5g || is_10g)
1031 + regmap_write(pextp, 0x50F0, 0x00C014AA);
1032 + else if (is_5g)
1033 + regmap_write(pextp, 0x50F0, 0x00C018AA);
1034 + else
1035 + regmap_write(pextp, 0x50F0, 0x00C014BA);
1036 +
1037 + if (is_5g) {
1038 + regmap_write(pextp, 0x50E0, 0x3777812B);
1039 + regmap_write(pextp, 0x506C, 0x005C9CFF);
1040 + regmap_write(pextp, 0x5070, 0x9DFAFAFA);
1041 + regmap_write(pextp, 0x5074, 0x273F3F3F);
1042 + regmap_write(pextp, 0x5078, 0xA8883868);
1043 + regmap_write(pextp, 0x507C, 0x14661466);
1044 + } else {
1045 + regmap_write(pextp, 0x50E0, 0x3777C12B);
1046 + regmap_write(pextp, 0x506C, 0x005F9CFF);
1047 + regmap_write(pextp, 0x5070, 0x9D9DFAFA);
1048 + regmap_write(pextp, 0x5074, 0x27273F3F);
1049 + regmap_write(pextp, 0x5078, 0xA7883C68);
1050 + regmap_write(pextp, 0x507C, 0x11661166);
1051 + }
1052 +
1053 + if (is_2p5g || is_10g) {
1054 + regmap_write(pextp, 0x5080, 0x0E000AAF);
1055 + regmap_write(pextp, 0x5084, 0x08080D0D);
1056 + regmap_write(pextp, 0x5088, 0x02030909);
1057 + } else if (is_5g) {
1058 + regmap_write(pextp, 0x5080, 0x0E001ABF);
1059 + regmap_write(pextp, 0x5084, 0x080B0D0D);
1060 + regmap_write(pextp, 0x5088, 0x02050909);
1061 + } else {
1062 + regmap_write(pextp, 0x5080, 0x0E000EAF);
1063 + regmap_write(pextp, 0x5084, 0x08080E0D);
1064 + regmap_write(pextp, 0x5088, 0x02030B09);
1065 + }
1066 +
1067 + if (is_5g) {
1068 + regmap_write(pextp, 0x50E4, 0x0C000000);
1069 + regmap_write(pextp, 0x50E8, 0x04000000);
1070 + } else {
1071 + regmap_write(pextp, 0x50E4, 0x0C0C0000);
1072 + regmap_write(pextp, 0x50E8, 0x04040000);
1073 + }
1074 +
1075 + if (is_2p5g || mtk_interface_mode_is_xgmii(interface))
1076 + regmap_write(pextp, 0x50EC, 0x0F0F0C06);
1077 + else
1078 + regmap_write(pextp, 0x50EC, 0x0F0F0606);
1079 +
1080 + if (is_5g) {
1081 + regmap_write(pextp, 0x50A8, 0x50808C8C);
1082 + regmap_write(pextp, 0x6004, 0x18000000);
1083 + } else {
1084 + regmap_write(pextp, 0x50A8, 0x506E8C8C);
1085 + regmap_write(pextp, 0x6004, 0x18190000);
1086 + }
1087 +
1088 + if (is_10g)
1089 + regmap_write(pextp, 0x00F8, 0x01423342);
1090 + else if (is_5g)
1091 + regmap_write(pextp, 0x00F8, 0x00A132A1);
1092 + else if (is_2p5g)
1093 + regmap_write(pextp, 0x00F8, 0x009C329C);
1094 + else
1095 + regmap_write(pextp, 0x00F8, 0x00FA32FA);
1096 +
1097 + /* Force SGDT_OUT off and select PCS */
1098 + if (mtk_interface_mode_is_xgmii(interface))
1099 + regmap_write(pextp, 0x00F4, 0x80201F20);
1100 + else
1101 + regmap_write(pextp, 0x00F4, 0x80201F21);
1102 +
1103 + /* Force GLB_CKDET_OUT */
1104 + regmap_write(pextp, 0x0030, 0x00050C00);
1105 +
1106 + /* Force AEQ on */
1107 + regmap_write(pextp, 0x0070, 0x02002800);
1108 + ndelay(1020);
1109 +
1110 + /* Setup DA default value */
1111 + regmap_write(pextp, 0x30B0, 0x00000020);
1112 + regmap_write(pextp, 0x3028, 0x00008A01);
1113 + regmap_write(pextp, 0x302C, 0x0000A884);
1114 + regmap_write(pextp, 0x3024, 0x00083002);
1115 + if (mtk_interface_mode_is_xgmii(interface)) {
1116 + regmap_write(pextp, 0x3010, 0x00022220);
1117 + regmap_write(pextp, 0x5064, 0x0F020A01);
1118 + regmap_write(pextp, 0x50B4, 0x06100600);
1119 + if (interface == PHY_INTERFACE_MODE_USXGMII)
1120 + regmap_write(pextp, 0x3048, 0x40704000);
1121 + else
1122 + regmap_write(pextp, 0x3048, 0x47684100);
1123 + } else {
1124 + regmap_write(pextp, 0x3010, 0x00011110);
1125 + regmap_write(pextp, 0x3048, 0x40704000);
1126 + }
1127 +
1128 + if (!mtk_interface_mode_is_xgmii(interface) && !is_2p5g)
1129 + regmap_write(pextp, 0x3064, 0x0000C000);
1130 +
1131 + if (interface == PHY_INTERFACE_MODE_USXGMII) {
1132 + regmap_write(pextp, 0x3050, 0xA8000000);
1133 + regmap_write(pextp, 0x3054, 0x000000AA);
1134 + } else if (mtk_interface_mode_is_xgmii(interface)) {
1135 + regmap_write(pextp, 0x3050, 0x00000000);
1136 + regmap_write(pextp, 0x3054, 0x00000000);
1137 + } else {
1138 + regmap_write(pextp, 0x3050, 0xA8000000);
1139 + regmap_write(pextp, 0x3054, 0x000000AA);
1140 + }
1141 +
1142 + if (mtk_interface_mode_is_xgmii(interface))
1143 + regmap_write(pextp, 0x306C, 0x00000F00);
1144 + else if (is_2p5g)
1145 + regmap_write(pextp, 0x306C, 0x22000F00);
1146 + else
1147 + regmap_write(pextp, 0x306C, 0x20200F00);
1148 +
1149 + if (interface == PHY_INTERFACE_MODE_10GBASER && id == 0)
1150 + regmap_write(pextp, 0xA008, 0x0007B400);
1151 +
1152 + if (mtk_interface_mode_is_xgmii(interface))
1153 + regmap_write(pextp, 0xA060, 0x00040000);
1154 + else
1155 + regmap_write(pextp, 0xA060, 0x00050000);
1156 +
1157 + if (is_10g)
1158 + regmap_write(pextp, 0x90D0, 0x00000001);
1159 + else if (is_5g)
1160 + regmap_write(pextp, 0x90D0, 0x00000003);
1161 + else if (is_2p5g)
1162 + regmap_write(pextp, 0x90D0, 0x00000005);
1163 + else
1164 + regmap_write(pextp, 0x90D0, 0x00000007);
1165 +
1166 + /* Release reset */
1167 + regmap_write(pextp, 0x0070, 0x0200E800);
1168 + usleep_range(150, 500);
1169 +
1170 + /* Switch to P0 */
1171 + regmap_write(pextp, 0x0070, 0x0200C111);
1172 + ndelay(1020);
1173 + regmap_write(pextp, 0x0070, 0x0200C101);
1174 + usleep_range(15, 50);
1175 +
1176 + if (mtk_interface_mode_is_xgmii(interface)) {
1177 + /* Switch to Gen3 */
1178 + regmap_write(pextp, 0x0070, 0x0202C111);
1179 + } else {
1180 + /* Switch to Gen2 */
1181 + regmap_write(pextp, 0x0070, 0x0201C111);
1182 + }
1183 + ndelay(1020);
1184 + if (mtk_interface_mode_is_xgmii(interface))
1185 + regmap_write(pextp, 0x0070, 0x0202C101);
1186 + else
1187 + regmap_write(pextp, 0x0070, 0x0201C101);
1188 + usleep_range(100, 500);
1189 + regmap_write(pextp, 0x30B0, 0x00000030);
1190 + if (mtk_interface_mode_is_xgmii(interface))
1191 + regmap_write(pextp, 0x00F4, 0x80201F00);
1192 + else
1193 + regmap_write(pextp, 0x00F4, 0x80201F01);
1194 +
1195 + regmap_write(pextp, 0x3040, 0x30000000);
1196 + usleep_range(400, 1000);
1197 +}
1198 +
1199 +static void mtk_usxgmii_reset(struct mtk_eth *eth, int id)
1200 +{
1201 + u32 toggle, val;
1202 +
1203 + if (id >= MTK_MAX_DEVS || !eth->toprgu)
1204 + return;
1205 +
1206 + switch (id) {
1207 + case 0:
1208 + toggle = SWSYSRST_XFI_PEXPT0_GRST | SWSYSRST_XFI0_GRST |
1209 + SWSYSRST_SGMII0_GRST;
1210 + break;
1211 + case 1:
1212 + toggle = SWSYSRST_XFI_PEXPT1_GRST | SWSYSRST_XFI1_GRST |
1213 + SWSYSRST_SGMII1_GRST;
1214 + break;
1215 + default:
1216 + return;
1217 + }
1218 +
1219 + /* Enable software reset */
1220 + regmap_set_bits(eth->toprgu, TOPRGU_SWSYSRST_EN, toggle);
1221 +
1222 + /* Assert USXGMII reset */
1223 + regmap_set_bits(eth->toprgu, TOPRGU_SWSYSRST,
1224 + FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) | toggle);
1225 +
1226 + usleep_range(100, 500);
1227 +
1228 + /* De-assert USXGMII reset */
1229 + regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
1230 + val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88);
1231 + val &= ~toggle;
1232 + regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
1233 +
1234 + /* Disable software reset */
1235 + regmap_clear_bits(eth->toprgu, TOPRGU_SWSYSRST_EN, toggle);
1236 +
1237 + mdelay(10);
1238 +}
1239 +
1240 +/* As the USXGMII PHYA is shared with the 1000Base-X/2500Base-X/Cisco SGMII unit
1241 + * the psc-mtk-lynxi instance needs to be wrapped, so that calls to .pcs_config
1242 + * also trigger an initial reset and subsequent configuration of the PHYA.
1243 + */
1244 +struct mtk_sgmii_wrapper_pcs {
1245 + struct mtk_eth *eth;
1246 + struct phylink_pcs *wrapped_pcs;
1247 + u8 id;
1248 + struct phylink_pcs pcs;
1249 +};
1250 +
1251 +static int mtk_sgmii_wrapped_pcs_config(struct phylink_pcs *pcs,
1252 + unsigned int mode,
1253 + phy_interface_t interface,
1254 + const unsigned long *advertising,
1255 + bool permit_pause_to_mac)
1256 +{
1257 + struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
1258 + bool full_reconf;
1259 + int ret;
1260 +
1261 + full_reconf = interface != wp->eth->usxgmii_pcs[wp->id]->interface;
1262 + if (full_reconf) {
1263 + mtk_xfi_pll_enable(wp->eth);
1264 + mtk_usxgmii_reset(wp->eth, wp->id);
1265 + }
1266 +
1267 + ret = wp->wrapped_pcs->ops->pcs_config(wp->wrapped_pcs, mode, interface,
1268 + advertising, permit_pause_to_mac);
1269 +
1270 + if (full_reconf)
1271 + mtk_usxgmii_setup_phya(wp->eth->regmap_pextp[wp->id], interface, wp->id);
1272 +
1273 + wp->eth->usxgmii_pcs[wp->id]->interface = interface;
1274 +
1275 + return ret;
1276 +}
1277 +
1278 +static void mtk_sgmii_wrapped_pcs_get_state(struct phylink_pcs *pcs,
1279 + struct phylink_link_state *state)
1280 +{
1281 + struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
1282 +
1283 + return wp->wrapped_pcs->ops->pcs_get_state(wp->wrapped_pcs, state);
1284 +}
1285 +
1286 +static void mtk_sgmii_wrapped_pcs_an_restart(struct phylink_pcs *pcs)
1287 +{
1288 + struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
1289 +
1290 + wp->wrapped_pcs->ops->pcs_an_restart(wp->wrapped_pcs);
1291 +}
1292 +
1293 +static void mtk_sgmii_wrapped_pcs_link_up(struct phylink_pcs *pcs,
1294 + unsigned int mode,
1295 + phy_interface_t interface, int speed,
1296 + int duplex)
1297 +{
1298 + struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
1299 +
1300 + wp->wrapped_pcs->ops->pcs_link_up(wp->wrapped_pcs, mode, interface, speed, duplex);
1301 +}
1302 +
1303 +static void mtk_sgmii_wrapped_pcs_disable(struct phylink_pcs *pcs)
1304 +{
1305 + struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
1306 +
1307 + wp->wrapped_pcs->ops->pcs_disable(wp->wrapped_pcs);
1308 +
1309 + wp->eth->usxgmii_pcs[wp->id]->interface = PHY_INTERFACE_MODE_NA;
1310 +}
1311 +
1312 +static const struct phylink_pcs_ops mtk_sgmii_wrapped_pcs_ops = {
1313 + .pcs_get_state = mtk_sgmii_wrapped_pcs_get_state,
1314 + .pcs_config = mtk_sgmii_wrapped_pcs_config,
1315 + .pcs_an_restart = mtk_sgmii_wrapped_pcs_an_restart,
1316 + .pcs_link_up = mtk_sgmii_wrapped_pcs_link_up,
1317 + .pcs_disable = mtk_sgmii_wrapped_pcs_disable,
1318 +};
1319 +
1320 +static int mtk_sgmii_wrapper_init(struct mtk_eth *eth)
1321 +{
1322 + struct mtk_sgmii_wrapper_pcs *wp;
1323 + int i;
1324 +
1325 + for (i = 0; i < MTK_MAX_DEVS; i++) {
1326 + if (!eth->sgmii_pcs[i])
1327 + continue;
1328 +
1329 + if (!eth->usxgmii_pcs[i])
1330 + continue;
1331 +
1332 + /* Make sure all PCS ops are supported by wrapped PCS */
1333 + if (!eth->sgmii_pcs[i]->ops->pcs_get_state ||
1334 + !eth->sgmii_pcs[i]->ops->pcs_config ||
1335 + !eth->sgmii_pcs[i]->ops->pcs_an_restart ||
1336 + !eth->sgmii_pcs[i]->ops->pcs_link_up ||
1337 + !eth->sgmii_pcs[i]->ops->pcs_disable)
1338 + return -EOPNOTSUPP;
1339 +
1340 + wp = devm_kzalloc(eth->dev, sizeof(*wp), GFP_KERNEL);
1341 + if (!wp)
1342 + return -ENOMEM;
1343 +
1344 + wp->wrapped_pcs = eth->sgmii_pcs[i];
1345 + wp->id = i;
1346 + wp->pcs.poll = true;
1347 + wp->pcs.ops = &mtk_sgmii_wrapped_pcs_ops;
1348 + wp->eth = eth;
1349 +
1350 + eth->usxgmii_pcs[i]->wrapped_sgmii_pcs = &wp->pcs;
1351 + }
1352 +
1353 + return 0;
1354 +}
1355 +
1356 +struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int mac_id)
1357 +{
1358 + u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id);
1359 +
1360 + if (!eth->usxgmii_pcs[xgmii_id])
1361 + return NULL;
1362 +
1363 + return eth->usxgmii_pcs[xgmii_id]->wrapped_sgmii_pcs;
1364 +}
1365 +
1366 +static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
1367 + phy_interface_t interface,
1368 + const unsigned long *advertising,
1369 + bool permit_pause_to_mac)
1370 +{
1371 + struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
1372 + struct mtk_eth *eth = mpcs->eth;
1373 + struct regmap *pextp = eth->regmap_pextp[mpcs->id];
1374 + unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0;
1375 + bool mode_changed = false;
1376 +
1377 + if (!pextp)
1378 + return -ENODEV;
1379 +
1380 + if (interface == PHY_INTERFACE_MODE_USXGMII) {
1381 + an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | USXGMII_AN_ENABLE;
1382 + link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
1383 + FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
1384 + FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
1385 + xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) |
1386 + FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G);
1387 + } else if (interface == PHY_INTERFACE_MODE_10GBASER) {
1388 + an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF);
1389 + link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
1390 + FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
1391 + FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
1392 + xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) |
1393 + FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G);
1394 + adapt_mode = USXGMII_RATE_UPDATE_MODE;
1395 + } else if (interface == PHY_INTERFACE_MODE_5GBASER) {
1396 + an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF);
1397 + link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) |
1398 + FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) |
1399 + FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D);
1400 + xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_5G) |
1401 + FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_5G);
1402 + adapt_mode = USXGMII_RATE_UPDATE_MODE;
1403 + } else {
1404 + return -EINVAL;
1405 + }
1406 +
1407 + adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1);
1408 +
1409 + if (mpcs->interface != interface) {
1410 + mpcs->interface = interface;
1411 + mode_changed = true;
1412 + }
1413 +
1414 + mtk_xfi_pll_enable(eth);
1415 + mtk_usxgmii_reset(eth, mpcs->id);
1416 +
1417 + /* Setup USXGMII AN ctrl */
1418 + regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL0,
1419 + USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE,
1420 + an_ctrl);
1421 +
1422 + regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL2,
1423 + USXGMII_LINK_TIMER_IDLE_DETECT |
1424 + USXGMII_LINK_TIMER_COMP_ACK_DETECT |
1425 + USXGMII_LINK_TIMER_AN_RESTART,
1426 + link_timer);
1427 +
1428 + mpcs->mode = mode;
1429 +
1430 + /* Gated MAC CK */
1431 + regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
1432 + USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED);
1433 +
1434 + /* Enable interface force mode */
1435 + regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
1436 + USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN);
1437 +
1438 + /* Setup USXGMII adapt mode */
1439 + regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
1440 + USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE,
1441 + adapt_mode);
1442 +
1443 + /* Setup USXGMII speed */
1444 + regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
1445 + USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE,
1446 + xfi_mode);
1447 +
1448 + usleep_range(1, 10);
1449 +
1450 + /* Un-gated MAC CK */
1451 + regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
1452 + USXGMII_MAC_CK_GATED, 0);
1453 +
1454 + usleep_range(1, 10);
1455 +
1456 + /* Disable interface force mode for the AN mode */
1457 + if (an_ctrl & USXGMII_AN_ENABLE)
1458 + regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
1459 + USXGMII_IF_FORCE_EN, 0);
1460 +
1461 + /* Setup USXGMIISYS with the determined property */
1462 + mtk_usxgmii_setup_phya(pextp, interface, mpcs->id);
1463 +
1464 + return mode_changed;
1465 +}
1466 +
1467 +static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs,
1468 + struct phylink_link_state *state)
1469 +{
1470 + struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
1471 + struct mtk_eth *eth = mpcs->eth;
1472 + struct mtk_mac *mac = eth->mac[mtk_xgmii2mac_id(eth, mpcs->id)];
1473 + u32 val = 0;
1474 +
1475 + regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val);
1476 + if (FIELD_GET(USXGMII_AN_ENABLE, val)) {
1477 + /* Refresh LPA by inverting LPA_LATCH */
1478 + regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val);
1479 + regmap_update_bits(mpcs->regmap, RG_PCS_AN_STS0,
1480 + USXGMII_LPA_LATCH,
1481 + !(val & USXGMII_LPA_LATCH));
1482 +
1483 + regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val);
1484 +
1485 + phylink_decode_usxgmii_word(state, FIELD_GET(USXGMII_PCS_AN_WORD,
1486 + val));
1487 +
1488 + state->interface = mpcs->interface;
1489 + } else {
1490 + val = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
1491 +
1492 + if (mac->id == MTK_GMAC2_ID)
1493 + val >>= 16;
1494 +
1495 + switch (FIELD_GET(MTK_USXGMII_PCS_MODE, val)) {
1496 + case 0:
1497 + state->speed = SPEED_10000;
1498 + break;
1499 + case 1:
1500 + state->speed = SPEED_5000;
1501 + break;
1502 + case 2:
1503 + state->speed = SPEED_2500;
1504 + break;
1505 + case 3:
1506 + state->speed = SPEED_1000;
1507 + break;
1508 + }
1509 +
1510 + state->interface = mpcs->interface;
1511 + state->link = FIELD_GET(MTK_USXGMII_PCS_LINK, val);
1512 + state->duplex = DUPLEX_FULL;
1513 + }
1514 +
1515 + /* Continuously repeat re-configuration sequence until link comes up */
1516 + if (state->link == 0)
1517 + mtk_usxgmii_pcs_config(pcs, mpcs->mode,
1518 + state->interface, NULL, false);
1519 +}
1520 +
1521 +static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs)
1522 +{
1523 + struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
1524 + unsigned int val = 0;
1525 +
1526 + if (!mpcs->regmap)
1527 + return;
1528 +
1529 + regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val);
1530 + val |= USXGMII_AN_RESTART;
1531 + regmap_write(mpcs->regmap, RG_PCS_AN_CTRL0, val);
1532 +}
1533 +
1534 +static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
1535 + phy_interface_t interface,
1536 + int speed, int duplex)
1537 +{
1538 + /* Reconfiguring USXGMII to ensure the quality of the RX signal
1539 + * after the line side link up.
1540 + */
1541 + mtk_usxgmii_pcs_config(pcs, mode,
1542 + interface, NULL, false);
1543 +}
1544 +
1545 +static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = {
1546 + .pcs_config = mtk_usxgmii_pcs_config,
1547 + .pcs_get_state = mtk_usxgmii_pcs_get_state,
1548 + .pcs_an_restart = mtk_usxgmii_pcs_restart_an,
1549 + .pcs_link_up = mtk_usxgmii_pcs_link_up,
1550 +};
1551 +
1552 +int mtk_usxgmii_init(struct mtk_eth *eth)
1553 +{
1554 + struct device_node *r = eth->dev->of_node;
1555 + struct device *dev = eth->dev;
1556 + struct device_node *np;
1557 + int i, ret;
1558 +
1559 + for (i = 0; i < MTK_MAX_DEVS; i++) {
1560 + np = of_parse_phandle(r, "mediatek,usxgmiisys", i);
1561 + if (!np)
1562 + break;
1563 +
1564 + eth->usxgmii_pcs[i] = devm_kzalloc(dev, sizeof(*eth->usxgmii_pcs[i]), GFP_KERNEL);
1565 + if (!eth->usxgmii_pcs[i])
1566 + return -ENOMEM;
1567 +
1568 + eth->usxgmii_pcs[i]->id = i;
1569 + eth->usxgmii_pcs[i]->eth = eth;
1570 + eth->usxgmii_pcs[i]->regmap = syscon_node_to_regmap(np);
1571 + if (IS_ERR(eth->usxgmii_pcs[i]->regmap))
1572 + return PTR_ERR(eth->usxgmii_pcs[i]->regmap);
1573 +
1574 + eth->usxgmii_pcs[i]->pcs.ops = &mtk_usxgmii_pcs_ops;
1575 + eth->usxgmii_pcs[i]->pcs.poll = true;
1576 + eth->usxgmii_pcs[i]->interface = PHY_INTERFACE_MODE_NA;
1577 + eth->usxgmii_pcs[i]->mode = -1;
1578 +
1579 + of_node_put(np);
1580 + }
1581 +
1582 + ret = mtk_xfi_pextp_init(eth);
1583 + if (ret)
1584 + return ret;
1585 +
1586 + ret = mtk_xfi_pll_init(eth);
1587 + if (ret)
1588 + return ret;
1589 +
1590 + ret = mtk_toprgu_init(eth);
1591 + if (ret)
1592 + return ret;
1593 +
1594 + return mtk_sgmii_wrapper_init(eth);
1595 +}
1596 +
1597 +struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int mac_id)
1598 +{
1599 + u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id);
1600 +
1601 + if (!eth->usxgmii_pcs[xgmii_id]->regmap)
1602 + return NULL;
1603 +
1604 + return &eth->usxgmii_pcs[xgmii_id]->pcs;
1605 +}