global: Migrate CONFIG_SYS_FSL* symbols to the CFG_SYS namespace
[platform/kernel/u-boot.git] / board / freescale / ls1043aqds / eth.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2015 Freescale Semiconductor, Inc.
4  * Copyright 2019 NXP
5  */
6
7 #include <common.h>
8 #include <log.h>
9 #include <net.h>
10 #include <asm/io.h>
11 #include <netdev.h>
12 #include <fdt_support.h>
13 #include <fm_eth.h>
14 #include <fsl_mdio.h>
15 #include <fsl_dtsec.h>
16 #include <linux/libfdt.h>
17 #include <malloc.h>
18 #include <asm/arch/fsl_serdes.h>
19
20 #include "../common/qixis.h"
21 #include "../common/fman.h"
22 #include "ls1043aqds_qixis.h"
23
24 #define EMI_NONE        0xFF
25 #define EMI1_RGMII1     0
26 #define EMI1_RGMII2     1
27 #define EMI1_SLOT1      2
28 #define EMI1_SLOT2      3
29 #define EMI1_SLOT3      4
30 #define EMI1_SLOT4      5
31 #define EMI2            6
32
33 static const char * const mdio_names[] = {
34         "LS1043AQDS_MDIO_RGMII1",
35         "LS1043AQDS_MDIO_RGMII2",
36         "LS1043AQDS_MDIO_SLOT1",
37         "LS1043AQDS_MDIO_SLOT2",
38         "LS1043AQDS_MDIO_SLOT3",
39         "LS1043AQDS_MDIO_SLOT4",
40         "NULL",
41 };
42
43 /* Map SerDes1 4 lanes to default slot, will be initialized dynamically */
44 #ifdef CONFIG_FMAN_ENET
45 static int mdio_mux[NUM_FM_PORTS];
46
47 static u8 lane_to_slot[] = {1, 2, 3, 4};
48 #endif
49
50 static const char *ls1043aqds_mdio_name_for_muxval(u8 muxval)
51 {
52         return mdio_names[muxval];
53 }
54
55 struct mii_dev *mii_dev_for_muxval(u8 muxval)
56 {
57         struct mii_dev *bus;
58         const char *name;
59
60         if (muxval > EMI2)
61                 return NULL;
62
63         name = ls1043aqds_mdio_name_for_muxval(muxval);
64
65         if (!name) {
66                 printf("No bus for muxval %x\n", muxval);
67                 return NULL;
68         }
69
70         bus = miiphy_get_dev_by_name(name);
71
72         if (!bus) {
73                 printf("No bus by name %s\n", name);
74                 return NULL;
75         }
76
77         return bus;
78 }
79
80 #ifdef CONFIG_FMAN_ENET
81 struct ls1043aqds_mdio {
82         u8 muxval;
83         struct mii_dev *realbus;
84 };
85
86 static void ls1043aqds_mux_mdio(u8 muxval)
87 {
88         u8 brdcfg4;
89
90         if (muxval < 7) {
91                 brdcfg4 = QIXIS_READ(brdcfg[4]);
92                 brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
93                 brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
94                 QIXIS_WRITE(brdcfg[4], brdcfg4);
95         }
96 }
97
98 static int ls1043aqds_mdio_read(struct mii_dev *bus, int addr, int devad,
99                               int regnum)
100 {
101         struct ls1043aqds_mdio *priv = bus->priv;
102
103         ls1043aqds_mux_mdio(priv->muxval);
104
105         return priv->realbus->read(priv->realbus, addr, devad, regnum);
106 }
107
108 static int ls1043aqds_mdio_write(struct mii_dev *bus, int addr, int devad,
109                                int regnum, u16 value)
110 {
111         struct ls1043aqds_mdio *priv = bus->priv;
112
113         ls1043aqds_mux_mdio(priv->muxval);
114
115         return priv->realbus->write(priv->realbus, addr, devad,
116                                     regnum, value);
117 }
118
119 static int ls1043aqds_mdio_reset(struct mii_dev *bus)
120 {
121         struct ls1043aqds_mdio *priv = bus->priv;
122
123         return priv->realbus->reset(priv->realbus);
124 }
125
126 static int ls1043aqds_mdio_init(char *realbusname, u8 muxval)
127 {
128         struct ls1043aqds_mdio *pmdio;
129         struct mii_dev *bus = mdio_alloc();
130
131         if (!bus) {
132                 printf("Failed to allocate ls1043aqds MDIO bus\n");
133                 return -1;
134         }
135
136         pmdio = malloc(sizeof(*pmdio));
137         if (!pmdio) {
138                 printf("Failed to allocate ls1043aqds private data\n");
139                 free(bus);
140                 return -1;
141         }
142
143         bus->read = ls1043aqds_mdio_read;
144         bus->write = ls1043aqds_mdio_write;
145         bus->reset = ls1043aqds_mdio_reset;
146         strcpy(bus->name, ls1043aqds_mdio_name_for_muxval(muxval));
147
148         pmdio->realbus = miiphy_get_dev_by_name(realbusname);
149
150         if (!pmdio->realbus) {
151                 printf("No bus with name %s\n", realbusname);
152                 free(bus);
153                 free(pmdio);
154                 return -1;
155         }
156
157         pmdio->muxval = muxval;
158         bus->priv = pmdio;
159         return mdio_register(bus);
160 }
161
162 void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
163                               enum fm_port port, int offset)
164 {
165         struct fixed_link f_link;
166
167         if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) {
168                 if (port == FM1_DTSEC9) {
169                         fdt_set_phy_handle(fdt, compat, addr,
170                                            "sgmii-riser-s1-p1");
171                 } else if (port == FM1_DTSEC2) {
172                         fdt_set_phy_handle(fdt, compat, addr,
173                                            "sgmii-riser-s2-p1");
174                 } else if (port == FM1_DTSEC5) {
175                         fdt_set_phy_handle(fdt, compat, addr,
176                                            "sgmii-riser-s3-p1");
177                 } else if (port == FM1_DTSEC6) {
178                         fdt_set_phy_handle(fdt, compat, addr,
179                                            "sgmii-riser-s4-p1");
180                 }
181         } else if (fm_info_get_enet_if(port) ==
182                    PHY_INTERFACE_MODE_2500BASEX) {
183                 /* 2.5G SGMII interface */
184                 f_link.phy_id = cpu_to_fdt32(port);
185                 f_link.duplex = cpu_to_fdt32(1);
186                 f_link.link_speed = cpu_to_fdt32(1000);
187                 f_link.pause = 0;
188                 f_link.asym_pause = 0;
189                 /* no PHY for 2.5G SGMII */
190                 fdt_delprop(fdt, offset, "phy-handle");
191                 fdt_setprop(fdt, offset, "fixed-link", &f_link, sizeof(f_link));
192                 fdt_setprop_string(fdt, offset, "phy-connection-type",
193                                    "2500base-x");
194         } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_QSGMII) {
195                 switch (mdio_mux[port]) {
196                 case EMI1_SLOT1:
197                         switch (port) {
198                         case FM1_DTSEC1:
199                                 fdt_set_phy_handle(fdt, compat, addr,
200                                                    "qsgmii-s1-p1");
201                                 break;
202                         case FM1_DTSEC2:
203                                 fdt_set_phy_handle(fdt, compat, addr,
204                                                    "qsgmii-s1-p2");
205                                 break;
206                         case FM1_DTSEC5:
207                                 fdt_set_phy_handle(fdt, compat, addr,
208                                                    "qsgmii-s1-p3");
209                                 break;
210                         case FM1_DTSEC6:
211                                 fdt_set_phy_handle(fdt, compat, addr,
212                                                    "qsgmii-s1-p4");
213                                 break;
214                         default:
215                                 break;
216                         }
217                         break;
218                 case EMI1_SLOT2:
219                         switch (port) {
220                         case FM1_DTSEC1:
221                                 fdt_set_phy_handle(fdt, compat, addr,
222                                                    "qsgmii-s2-p1");
223                                 break;
224                         case FM1_DTSEC2:
225                                 fdt_set_phy_handle(fdt, compat, addr,
226                                                    "qsgmii-s2-p2");
227                                 break;
228                         case FM1_DTSEC5:
229                                 fdt_set_phy_handle(fdt, compat, addr,
230                                                    "qsgmii-s2-p3");
231                                 break;
232                         case FM1_DTSEC6:
233                                 fdt_set_phy_handle(fdt, compat, addr,
234                                                    "qsgmii-s2-p4");
235                                 break;
236                         default:
237                                 break;
238                         }
239                         break;
240                 default:
241                         break;
242                 }
243                 fdt_delprop(fdt, offset, "phy-connection-type");
244                 fdt_setprop_string(fdt, offset, "phy-connection-type",
245                                    "qsgmii");
246         } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_XGMII &&
247                    port == FM1_10GEC1) {
248                 /* 10GBase-R interface */
249                 f_link.phy_id = cpu_to_fdt32(port);
250                 f_link.duplex = cpu_to_fdt32(1);
251                 f_link.link_speed = cpu_to_fdt32(10000);
252                 f_link.pause = 0;
253                 f_link.asym_pause = 0;
254                 /* no PHY for 10GBase-R */
255                 fdt_delprop(fdt, offset, "phy-handle");
256                 fdt_setprop(fdt, offset, "fixed-link", &f_link, sizeof(f_link));
257                 fdt_setprop_string(fdt, offset, "phy-connection-type", "xgmii");
258         }
259 }
260
261 void fdt_fixup_board_enet(void *fdt)
262 {
263         int i;
264         struct ccsr_gur *gur = (void *)(CFG_SYS_FSL_GUTS_ADDR);
265         u32 srds_s1;
266
267         srds_s1 = in_be32(&gur->rcwsr[4]) &
268                         FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
269         srds_s1 >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
270
271         for (i = FM1_DTSEC1; i < NUM_FM_PORTS; i++) {
272                 switch (fm_info_get_enet_if(i)) {
273                 case PHY_INTERFACE_MODE_SGMII:
274                 case PHY_INTERFACE_MODE_QSGMII:
275                         switch (mdio_mux[i]) {
276                         case EMI1_SLOT1:
277                                 fdt_status_okay_by_alias(fdt, "emi1-slot1");
278                                 break;
279                         case EMI1_SLOT2:
280                                 fdt_status_okay_by_alias(fdt, "emi1-slot2");
281                                 break;
282                         case EMI1_SLOT3:
283                                 fdt_status_okay_by_alias(fdt, "emi1-slot3");
284                                 break;
285                         case EMI1_SLOT4:
286                                 fdt_status_okay_by_alias(fdt, "emi1-slot4");
287                                 break;
288                         default:
289                                 break;
290                         }
291                         break;
292                 case PHY_INTERFACE_MODE_XGMII:
293                         break;
294                 default:
295                         break;
296                 }
297         }
298 }
299
300 int board_eth_init(struct bd_info *bis)
301 {
302         int i, idx, lane, slot, interface;
303         struct memac_mdio_info dtsec_mdio_info;
304         struct memac_mdio_info tgec_mdio_info;
305         struct ccsr_gur *gur = (void *)(CFG_SYS_FSL_GUTS_ADDR);
306         u32 srds_s1;
307
308         srds_s1 = in_be32(&gur->rcwsr[4]) &
309                         FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
310         srds_s1 >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
311
312         /* Initialize the mdio_mux array so we can recognize empty elements */
313         for (i = 0; i < NUM_FM_PORTS; i++)
314                 mdio_mux[i] = EMI_NONE;
315
316         dtsec_mdio_info.regs =
317                 (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR;
318
319         dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;
320
321         /* Register the 1G MDIO bus */
322         fm_memac_mdio_init(bis, &dtsec_mdio_info);
323
324         tgec_mdio_info.regs =
325                 (struct memac_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR;
326         tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;
327
328         /* Register the 10G MDIO bus */
329         fm_memac_mdio_init(bis, &tgec_mdio_info);
330
331         /* Register the muxing front-ends to the MDIO buses */
332         ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1);
333         ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII2);
334         ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1);
335         ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT2);
336         ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3);
337         ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4);
338         ls1043aqds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2);
339
340         /* Set the two on-board RGMII PHY address */
341         fm_info_set_phy_address(FM1_DTSEC3, RGMII_PHY1_ADDR);
342         fm_info_set_phy_address(FM1_DTSEC4, RGMII_PHY2_ADDR);
343
344         switch (srds_s1) {
345         case 0x2555:
346                 /* 2.5G SGMII on lane A, MAC 9 */
347                 fm_info_set_phy_address(FM1_DTSEC9, 9);
348                 break;
349         case 0x4555:
350         case 0x4558:
351                 /* QSGMII on lane A, MAC 1/2/5/6 */
352                 fm_info_set_phy_address(FM1_DTSEC1,
353                                         QSGMII_CARD_PORT1_PHY_ADDR_S1);
354                 fm_info_set_phy_address(FM1_DTSEC2,
355                                         QSGMII_CARD_PORT2_PHY_ADDR_S1);
356                 fm_info_set_phy_address(FM1_DTSEC5,
357                                         QSGMII_CARD_PORT3_PHY_ADDR_S1);
358                 fm_info_set_phy_address(FM1_DTSEC6,
359                                         QSGMII_CARD_PORT4_PHY_ADDR_S1);
360                 break;
361         case 0x1355:
362                 /* SGMII on lane B, MAC 2*/
363                 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
364                 break;
365         case 0x2355:
366                 /* 2.5G SGMII on lane A, MAC 9 */
367                 fm_info_set_phy_address(FM1_DTSEC9, 9);
368                 /* SGMII on lane B, MAC 2*/
369                 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
370                 break;
371         case 0x3335:
372                 /* SGMII on lane C, MAC 5 */
373                 fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT1_PHY_ADDR);
374         case 0x3355:
375         case 0x3358:
376                 /* SGMII on lane B, MAC 2 */
377                 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
378         case 0x3555:
379         case 0x3558:
380                 /* SGMII on lane A, MAC 9 */
381                 fm_info_set_phy_address(FM1_DTSEC9, SGMII_CARD_PORT1_PHY_ADDR);
382                 break;
383         case 0x1455:
384                 /* QSGMII on lane B, MAC 1/2/5/6 */
385                 fm_info_set_phy_address(FM1_DTSEC1,
386                                         QSGMII_CARD_PORT1_PHY_ADDR_S2);
387                 fm_info_set_phy_address(FM1_DTSEC2,
388                                         QSGMII_CARD_PORT2_PHY_ADDR_S2);
389                 fm_info_set_phy_address(FM1_DTSEC5,
390                                         QSGMII_CARD_PORT3_PHY_ADDR_S2);
391                 fm_info_set_phy_address(FM1_DTSEC6,
392                                         QSGMII_CARD_PORT4_PHY_ADDR_S2);
393                 break;
394         case 0x2455:
395                 /* 2.5G SGMII on lane A, MAC 9 */
396                 fm_info_set_phy_address(FM1_DTSEC9, 9);
397                 /* QSGMII on lane B, MAC 1/2/5/6 */
398                 fm_info_set_phy_address(FM1_DTSEC1,
399                                         QSGMII_CARD_PORT1_PHY_ADDR_S2);
400                 fm_info_set_phy_address(FM1_DTSEC2,
401                                         QSGMII_CARD_PORT2_PHY_ADDR_S2);
402                 fm_info_set_phy_address(FM1_DTSEC5,
403                                         QSGMII_CARD_PORT3_PHY_ADDR_S2);
404                 fm_info_set_phy_address(FM1_DTSEC6,
405                                         QSGMII_CARD_PORT4_PHY_ADDR_S2);
406                 break;
407         case 0x2255:
408                 /* 2.5G SGMII on lane A, MAC 9 */
409                 fm_info_set_phy_address(FM1_DTSEC9, 9);
410                 /* 2.5G SGMII on lane B, MAC 2 */
411                 fm_info_set_phy_address(FM1_DTSEC2, 2);
412                 break;
413         case 0x3333:
414                 /* SGMII on lane A/B/C/D, MAC 9/2/5/6 */
415                 fm_info_set_phy_address(FM1_DTSEC9,
416                                         SGMII_CARD_PORT1_PHY_ADDR);
417                 fm_info_set_phy_address(FM1_DTSEC2,
418                                         SGMII_CARD_PORT1_PHY_ADDR);
419                 fm_info_set_phy_address(FM1_DTSEC5,
420                                         SGMII_CARD_PORT1_PHY_ADDR);
421                 fm_info_set_phy_address(FM1_DTSEC6,
422                                         SGMII_CARD_PORT1_PHY_ADDR);
423                 break;
424         default:
425                 printf("Invalid SerDes protocol 0x%x for LS1043AQDS\n",
426                        srds_s1);
427                 break;
428         }
429
430         for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
431                 idx = i - FM1_DTSEC1;
432                 interface = fm_info_get_enet_if(i);
433                 switch (interface) {
434                 case PHY_INTERFACE_MODE_SGMII:
435                 case PHY_INTERFACE_MODE_2500BASEX:
436                 case PHY_INTERFACE_MODE_QSGMII:
437                         if (interface == PHY_INTERFACE_MODE_SGMII) {
438                                 lane = serdes_get_first_lane(FSL_SRDS_1,
439                                                 SGMII_FM1_DTSEC1 + idx);
440                         } else if (interface == PHY_INTERFACE_MODE_2500BASEX) {
441                                 lane = serdes_get_first_lane(FSL_SRDS_1,
442                                                 SGMII_2500_FM1_DTSEC1 + idx);
443                         } else {
444                                 lane = serdes_get_first_lane(FSL_SRDS_1,
445                                                 QSGMII_FM1_A);
446                         }
447
448                         if (lane < 0)
449                                 break;
450
451                         slot = lane_to_slot[lane];
452                         debug("FM1@DTSEC%u expects SGMII in slot %u\n",
453                               idx + 1, slot);
454                         if (QIXIS_READ(present2) & (1 << (slot - 1)))
455                                 fm_disable_port(i);
456
457                         switch (slot) {
458                         case 1:
459                                 mdio_mux[i] = EMI1_SLOT1;
460                                 fm_info_set_mdio(i, mii_dev_for_muxval(
461                                                  mdio_mux[i]));
462                                 break;
463                         case 2:
464                                 mdio_mux[i] = EMI1_SLOT2;
465                                 fm_info_set_mdio(i, mii_dev_for_muxval(
466                                                  mdio_mux[i]));
467                                 break;
468                         case 3:
469                                 mdio_mux[i] = EMI1_SLOT3;
470                                 fm_info_set_mdio(i, mii_dev_for_muxval(
471                                                  mdio_mux[i]));
472                                 break;
473                         case 4:
474                                 mdio_mux[i] = EMI1_SLOT4;
475                                 fm_info_set_mdio(i, mii_dev_for_muxval(
476                                                  mdio_mux[i]));
477                                 break;
478                         default:
479                                 break;
480                         }
481                         break;
482                 case PHY_INTERFACE_MODE_RGMII:
483                 case PHY_INTERFACE_MODE_RGMII_TXID:
484                 case PHY_INTERFACE_MODE_RGMII_RXID:
485                 case PHY_INTERFACE_MODE_RGMII_ID:
486                         if (i == FM1_DTSEC3)
487                                 mdio_mux[i] = EMI1_RGMII1;
488                         else if (i == FM1_DTSEC4)
489                                 mdio_mux[i] = EMI1_RGMII2;
490                         fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
491                         break;
492                 default:
493                         break;
494                 }
495         }
496
497         cpu_eth_init(bis);
498
499         return pci_eth_init(bis);
500 }
501 #endif /* CONFIG_FMAN_ENET */