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