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