1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67#include <common.h>
68#include <netdev.h>
69#include <asm/fsl_serdes.h>
70#include <fm_eth.h>
71#include <fsl_mdio.h>
72#include <malloc.h>
73#include <fdt_support.h>
74#include <asm/fsl_dtsec.h>
75
76#include "../common/ngpixis.h"
77#include "../common/fman.h"
78
79#ifdef CONFIG_FMAN_ENET
80
81#define BRDCFG1_EMI1_SEL_MASK 0x70
82#define BRDCFG1_EMI1_SEL_SLOT1 0x10
83#define BRDCFG1_EMI1_SEL_SLOT2 0x20
84#define BRDCFG1_EMI1_SEL_SLOT5 0x30
85#define BRDCFG1_EMI1_SEL_SLOT6 0x40
86#define BRDCFG1_EMI1_SEL_SLOT7 0x50
87#define BRDCFG1_EMI1_SEL_SLOT3 0x60
88#define BRDCFG1_EMI1_SEL_RGMII 0x00
89#define BRDCFG1_EMI1_EN 0x08
90#define BRDCFG1_EMI2_SEL_MASK 0x06
91#define BRDCFG1_EMI2_SEL_SLOT1 0x00
92#define BRDCFG1_EMI2_SEL_SLOT2 0x02
93
94#define BRDCFG2_REG_GPIO_SEL 0x20
95
96
97
98
99
100
101
102static struct {
103 u8 mask;
104 u8 val;
105} mdio_mux[NUM_FM_PORTS];
106
107
108
109
110
111
112static u8 lane_to_slot[] = {
113 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0
114};
115
116
117
118
119
120
121void super_hydra_mux_mdio(u8 mask, u8 val)
122{
123 clrsetbits_8(&pixis->brdcfg1, mask, val);
124}
125
126struct super_hydra_mdio {
127 u8 mask;
128 u8 val;
129 struct mii_dev *realbus;
130};
131
132static int super_hydra_mdio_read(struct mii_dev *bus, int addr, int devad,
133 int regnum)
134{
135 struct super_hydra_mdio *priv = bus->priv;
136
137 super_hydra_mux_mdio(priv->mask, priv->val);
138
139 return priv->realbus->read(priv->realbus, addr, devad, regnum);
140}
141
142static int super_hydra_mdio_write(struct mii_dev *bus, int addr, int devad,
143 int regnum, u16 value)
144{
145 struct super_hydra_mdio *priv = bus->priv;
146
147 super_hydra_mux_mdio(priv->mask, priv->val);
148
149 return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
150}
151
152static int super_hydra_mdio_reset(struct mii_dev *bus)
153{
154 struct super_hydra_mdio *priv = bus->priv;
155
156 return priv->realbus->reset(priv->realbus);
157}
158
159static void super_hydra_mdio_set_mux(char *name, u8 mask, u8 val)
160{
161 struct mii_dev *bus = miiphy_get_dev_by_name(name);
162 struct super_hydra_mdio *priv = bus->priv;
163
164 priv->mask = mask;
165 priv->val = val;
166}
167
168static int super_hydra_mdio_init(char *realbusname, char *fakebusname)
169{
170 struct super_hydra_mdio *hmdio;
171 struct mii_dev *bus = mdio_alloc();
172
173 if (!bus) {
174 printf("Failed to allocate Hydra MDIO bus\n");
175 return -1;
176 }
177
178 hmdio = malloc(sizeof(*hmdio));
179 if (!hmdio) {
180 printf("Failed to allocate Hydra private data\n");
181 free(bus);
182 return -1;
183 }
184
185 bus->read = super_hydra_mdio_read;
186 bus->write = super_hydra_mdio_write;
187 bus->reset = super_hydra_mdio_reset;
188 sprintf(bus->name, fakebusname);
189
190 hmdio->realbus = miiphy_get_dev_by_name(realbusname);
191
192 if (!hmdio->realbus) {
193 printf("No bus with name %s\n", realbusname);
194 free(bus);
195 free(hmdio);
196 return -1;
197 }
198
199 bus->priv = hmdio;
200
201 return mdio_register(bus);
202}
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
225 enum fm_port port, int offset)
226{
227 enum srds_prtcl device;
228 int lane, slot, phy;
229 char alias[32];
230
231
232
233 if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) {
234 device = serdes_device_from_fm_port(port);
235 lane = serdes_get_first_lane(device);
236 slot = lane_to_slot[lane];
237 phy = fm_info_get_phy_address(port);
238
239 sprintf(alias, "phy_sgmii_slot%u_%x", slot, phy);
240 fdt_set_phy_handle(fdt, compat, addr, alias);
241 }
242}
243
244#define PIXIS_SW2_LANE_23_SEL 0x80
245#define PIXIS_SW2_LANE_45_SEL 0x40
246#define PIXIS_SW2_LANE_67_SEL_MASK 0x30
247#define PIXIS_SW2_LANE_67_SEL_5 0x00
248#define PIXIS_SW2_LANE_67_SEL_6 0x20
249#define PIXIS_SW2_LANE_67_SEL_7 0x10
250#define PIXIS_SW2_LANE_8_SEL 0x08
251#define PIXIS_SW2_LANE_1617_SEL 0x04
252#define PIXIS_SW11_LANE_9_SEL 0x04
253
254
255
256
257
258
259
260
261static void initialize_lane_to_slot(void)
262{
263 u8 sw2 = in_8(&PIXIS_SW(2));
264
265 u8 sw11 = in_8(&PIXIS_SW(9));
266
267 lane_to_slot[2] = (sw2 & PIXIS_SW2_LANE_23_SEL) ? 7 : 4;
268 lane_to_slot[3] = lane_to_slot[2];
269
270 lane_to_slot[4] = (sw2 & PIXIS_SW2_LANE_45_SEL) ? 7 : 6;
271 lane_to_slot[5] = lane_to_slot[4];
272
273 switch (sw2 & PIXIS_SW2_LANE_67_SEL_MASK) {
274 case PIXIS_SW2_LANE_67_SEL_5:
275 lane_to_slot[6] = 5;
276 break;
277 case PIXIS_SW2_LANE_67_SEL_6:
278 lane_to_slot[6] = 6;
279 break;
280 case PIXIS_SW2_LANE_67_SEL_7:
281 lane_to_slot[6] = 7;
282 break;
283 }
284 lane_to_slot[7] = lane_to_slot[6];
285
286 lane_to_slot[8] = (sw2 & PIXIS_SW2_LANE_8_SEL) ? 3 : 0;
287 lane_to_slot[9] = (sw11 & PIXIS_SW11_LANE_9_SEL) ? 0 : 3;
288
289 lane_to_slot[16] = (sw2 & PIXIS_SW2_LANE_1617_SEL) ? 1 : 0;
290 lane_to_slot[17] = lane_to_slot[16];
291}
292
293#endif
294
295
296
297
298
299
300
301
302
303
304
305
306void fdt_fixup_board_enet(void *fdt)
307{
308#ifdef CONFIG_FMAN_ENET
309 enum fm_port i;
310 int lane, slot;
311
312 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
313 int idx = i - FM1_DTSEC1;
314
315 switch (fm_info_get_enet_if(i)) {
316 case PHY_INTERFACE_MODE_SGMII:
317 lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx);
318 if (lane >= 0) {
319 char alias[32];
320
321 slot = lane_to_slot[lane];
322 sprintf(alias, "hydra_sg_slot%u", slot);
323 fdt_status_okay_by_alias(fdt, alias);
324 debug("Enabled MDIO node %s (slot %i)\n",
325 alias, slot);
326 }
327 break;
328 case PHY_INTERFACE_MODE_RGMII:
329 fdt_status_okay_by_alias(fdt, "hydra_rg");
330 debug("Enabled MDIO node hydra_rg\n");
331 break;
332 default:
333 break;
334 }
335 }
336
337 lane = serdes_get_first_lane(XAUI_FM1);
338 if (lane >= 0) {
339 char alias[32];
340
341 slot = lane_to_slot[lane];
342 sprintf(alias, "hydra_xg_slot%u", slot);
343 fdt_status_okay_by_alias(fdt, alias);
344 debug("Enabled MDIO node %s (slot %i)\n", alias, slot);
345 }
346
347#if CONFIG_SYS_NUM_FMAN == 2
348 for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) {
349 int idx = i - FM2_DTSEC1;
350
351 switch (fm_info_get_enet_if(i)) {
352 case PHY_INTERFACE_MODE_SGMII:
353 lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx);
354 if (lane >= 0) {
355 char alias[32];
356
357 slot = lane_to_slot[lane];
358 sprintf(alias, "hydra_sg_slot%u", slot);
359 fdt_status_okay_by_alias(fdt, alias);
360 debug("Enabled MDIO node %s (slot %i)\n",
361 alias, slot);
362 }
363 break;
364 case PHY_INTERFACE_MODE_RGMII:
365 fdt_status_okay_by_alias(fdt, "hydra_rg");
366 debug("Enabled MDIO node hydra_rg\n");
367 break;
368 default:
369 break;
370 }
371 }
372
373 lane = serdes_get_first_lane(XAUI_FM2);
374 if (lane >= 0) {
375 char alias[32];
376
377 slot = lane_to_slot[lane];
378 sprintf(alias, "hydra_xg_slot%u", slot);
379 fdt_status_okay_by_alias(fdt, alias);
380 debug("Enabled MDIO node %s (slot %i)\n", alias, slot);
381 }
382#endif
383#endif
384}
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427int board_eth_init(bd_t *bis)
428{
429#ifdef CONFIG_FMAN_ENET
430 struct fsl_pq_mdio_info dtsec_mdio_info;
431 struct tgec_mdio_info tgec_mdio_info;
432 unsigned int i, slot;
433 int lane;
434 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
435 int srds_prtcl = (in_be32(&gur->rcwsr[4]) &
436 FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26;
437
438 printf("Initializing Fman\n");
439
440 initialize_lane_to_slot();
441
442
443 setbits_8(&pixis->brdcfg2, BRDCFG2_REG_GPIO_SEL);
444
445 memset(mdio_mux, 0, sizeof(mdio_mux));
446
447 dtsec_mdio_info.regs =
448 (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR;
449 dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;
450
451
452 fsl_pq_mdio_init(bis, &dtsec_mdio_info);
453
454 tgec_mdio_info.regs =
455 (struct tgec_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR;
456 tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;
457
458
459 fm_tgec_mdio_init(bis, &tgec_mdio_info);
460
461
462 super_hydra_mdio_init(DEFAULT_FM_MDIO_NAME,
463 "SUPER_HYDRA_RGMII_MDIO");
464 super_hydra_mdio_init(DEFAULT_FM_MDIO_NAME,
465 "SUPER_HYDRA_FM1_SGMII_MDIO");
466 super_hydra_mdio_init(DEFAULT_FM_MDIO_NAME,
467 "SUPER_HYDRA_FM2_SGMII_MDIO");
468 super_hydra_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME,
469 "SUPER_HYDRA_FM1_TGEC_MDIO");
470 super_hydra_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME,
471 "SUPER_HYDRA_FM2_TGEC_MDIO");
472
473
474
475
476
477
478 fm_info_set_phy_address(FM1_DTSEC1, CONFIG_SYS_FM1_DTSEC1_PHY_ADDR);
479 fm_info_set_phy_address(FM1_DTSEC2, CONFIG_SYS_FM1_DTSEC2_PHY_ADDR);
480 fm_info_set_phy_address(FM1_10GEC1, CONFIG_SYS_FM2_10GEC1_PHY_ADDR);
481
482#if (CONFIG_SYS_NUM_FMAN == 2)
483 fm_info_set_phy_address(FM2_DTSEC1, CONFIG_SYS_FM2_DTSEC1_PHY_ADDR);
484 fm_info_set_phy_address(FM2_DTSEC2, CONFIG_SYS_FM2_DTSEC2_PHY_ADDR);
485 fm_info_set_phy_address(FM2_DTSEC3, CONFIG_SYS_FM2_DTSEC1_PHY_ADDR);
486 fm_info_set_phy_address(FM2_DTSEC4, CONFIG_SYS_FM2_DTSEC2_PHY_ADDR);
487 fm_info_set_phy_address(FM2_10GEC1, CONFIG_SYS_FM1_10GEC1_PHY_ADDR);
488#endif
489
490 switch (srds_prtcl) {
491 case 0:
492 case 3:
493 case 4:
494 case 6:
495 case 0x11:
496 case 0x2a:
497 case 0x34:
498 case 0x36:
499 fm_info_set_phy_address(FM1_DTSEC3,
500 CONFIG_SYS_FM1_DTSEC3_PHY_ADDR);
501 fm_info_set_phy_address(FM1_DTSEC4,
502 CONFIG_SYS_FM1_DTSEC4_PHY_ADDR);
503 break;
504 case 1:
505 case 2:
506 case 5:
507 case 7:
508 case 0x35:
509 fm_info_set_phy_address(FM1_DTSEC3,
510 CONFIG_SYS_FM1_DTSEC1_PHY_ADDR);
511 fm_info_set_phy_address(FM1_DTSEC4,
512 CONFIG_SYS_FM1_DTSEC2_PHY_ADDR);
513 break;
514 default:
515 printf("Fman: Unsupport SerDes Protocol 0x%02x\n", srds_prtcl);
516 break;
517 }
518
519 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
520 int idx = i - FM1_DTSEC1;
521
522 switch (fm_info_get_enet_if(i)) {
523 case PHY_INTERFACE_MODE_SGMII:
524 lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx);
525 if (lane < 0)
526 break;
527 slot = lane_to_slot[lane];
528 mdio_mux[i].mask = BRDCFG1_EMI1_SEL_MASK;
529 debug("FM1@DTSEC%u expects SGMII in slot %u\n",
530 idx + 1, slot);
531 switch (slot) {
532 case 1:
533 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT1 |
534 BRDCFG1_EMI1_EN;
535 break;
536 case 2:
537 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT2 |
538 BRDCFG1_EMI1_EN;
539 break;
540 case 3:
541 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT3 |
542 BRDCFG1_EMI1_EN;
543 break;
544 case 5:
545 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT5 |
546 BRDCFG1_EMI1_EN;
547 break;
548 case 6:
549 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT6 |
550 BRDCFG1_EMI1_EN;
551 break;
552 case 7:
553 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT7 |
554 BRDCFG1_EMI1_EN;
555 break;
556 };
557
558 super_hydra_mdio_set_mux("SUPER_HYDRA_FM1_SGMII_MDIO",
559 mdio_mux[i].mask, mdio_mux[i].val);
560 fm_info_set_mdio(i,
561 miiphy_get_dev_by_name("SUPER_HYDRA_FM1_SGMII_MDIO"));
562 break;
563 case PHY_INTERFACE_MODE_RGMII:
564
565
566
567
568
569
570 debug("FM1@DTSEC%u is RGMII at address %u\n",
571 idx + 1, 0);
572 fm_info_set_phy_address(i, 0);
573 mdio_mux[i].mask = BRDCFG1_EMI1_SEL_MASK;
574 mdio_mux[i].val = BRDCFG1_EMI1_SEL_RGMII |
575 BRDCFG1_EMI1_EN;
576 super_hydra_mdio_set_mux("SUPER_HYDRA_RGMII_MDIO",
577 mdio_mux[i].mask, mdio_mux[i].val);
578 fm_info_set_mdio(i,
579 miiphy_get_dev_by_name("SUPER_HYDRA_RGMII_MDIO"));
580 break;
581 case PHY_INTERFACE_MODE_NONE:
582 fm_info_set_phy_address(i, 0);
583 break;
584 default:
585 printf("Fman1: DTSEC%u set to unknown interface %i\n",
586 idx + 1, fm_info_get_enet_if(i));
587 fm_info_set_phy_address(i, 0);
588 break;
589 }
590 }
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605 lane = serdes_get_first_lane(XAUI_FM1);
606 if (lane >= 0) {
607 debug("FM1@TGEC1 expects XAUI in slot %u\n", lane_to_slot[lane]);
608 mdio_mux[FM1_10GEC1].mask = BRDCFG1_EMI2_SEL_MASK;
609 mdio_mux[FM1_10GEC1].val = BRDCFG1_EMI2_SEL_SLOT2;
610 super_hydra_mdio_set_mux("SUPER_HYDRA_FM1_TGEC_MDIO",
611 mdio_mux[i].mask, mdio_mux[i].val);
612 }
613
614 fm_info_set_mdio(FM1_10GEC1,
615 miiphy_get_dev_by_name("SUPER_HYDRA_FM1_TGEC_MDIO"));
616
617#if (CONFIG_SYS_NUM_FMAN == 2)
618 for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) {
619 int idx = i - FM2_DTSEC1;
620
621 switch (fm_info_get_enet_if(i)) {
622 case PHY_INTERFACE_MODE_SGMII:
623 lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx);
624 if (lane < 0)
625 break;
626 slot = lane_to_slot[lane];
627 mdio_mux[i].mask = BRDCFG1_EMI1_SEL_MASK;
628 debug("FM2@DTSEC%u expects SGMII in slot %u\n",
629 idx + 1, slot);
630 switch (slot) {
631 case 1:
632 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT1 |
633 BRDCFG1_EMI1_EN;
634 break;
635 case 2:
636 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT2 |
637 BRDCFG1_EMI1_EN;
638 break;
639 case 3:
640 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT3 |
641 BRDCFG1_EMI1_EN;
642 break;
643 case 5:
644 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT5 |
645 BRDCFG1_EMI1_EN;
646 break;
647 case 6:
648 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT6 |
649 BRDCFG1_EMI1_EN;
650 break;
651 case 7:
652 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT7 |
653 BRDCFG1_EMI1_EN;
654 break;
655 };
656
657 super_hydra_mdio_set_mux("SUPER_HYDRA_FM2_SGMII_MDIO",
658 mdio_mux[i].mask, mdio_mux[i].val);
659 fm_info_set_mdio(i,
660 miiphy_get_dev_by_name("SUPER_HYDRA_FM2_SGMII_MDIO"));
661 break;
662 case PHY_INTERFACE_MODE_RGMII:
663
664
665
666
667
668
669 debug("FM2@DTSEC%u is RGMII at address %u\n",
670 idx + 1, 1);
671 fm_info_set_phy_address(i, 1);
672 mdio_mux[i].mask = BRDCFG1_EMI1_SEL_MASK;
673 mdio_mux[i].val = BRDCFG1_EMI1_SEL_RGMII |
674 BRDCFG1_EMI1_EN;
675 super_hydra_mdio_set_mux("SUPER_HYDRA_RGMII_MDIO",
676 mdio_mux[i].mask, mdio_mux[i].val);
677 fm_info_set_mdio(i,
678 miiphy_get_dev_by_name("SUPER_HYDRA_RGMII_MDIO"));
679 break;
680 case PHY_INTERFACE_MODE_NONE:
681 fm_info_set_phy_address(i, 0);
682 break;
683 default:
684 printf("Fman2: DTSEC%u set to unknown interface %i\n",
685 idx + 1, fm_info_get_enet_if(i));
686 fm_info_set_phy_address(i, 0);
687 break;
688 }
689 }
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704 lane = serdes_get_first_lane(XAUI_FM2);
705 if (lane >= 0) {
706 debug("FM2@TGEC1 expects XAUI in slot %u\n", lane_to_slot[lane]);
707 mdio_mux[FM2_10GEC1].mask = BRDCFG1_EMI2_SEL_MASK;
708 mdio_mux[FM2_10GEC1].val = BRDCFG1_EMI2_SEL_SLOT1;
709 super_hydra_mdio_set_mux("SUPER_HYDRA_FM2_TGEC_MDIO",
710 mdio_mux[i].mask, mdio_mux[i].val);
711 }
712
713 fm_info_set_mdio(FM2_10GEC1,
714 miiphy_get_dev_by_name("SUPER_HYDRA_FM2_TGEC_MDIO"));
715
716#endif
717
718 cpu_eth_init(bis);
719#endif
720
721 return pci_eth_init(bis);
722}
723