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_RGMII 0x00
88#define BRDCFG1_EMI1_EN 0x08
89#define BRDCFG1_EMI2_SEL_MASK 0x06
90#define BRDCFG1_EMI2_SEL_SLOT1 0x00
91#define BRDCFG1_EMI2_SEL_SLOT2 0x02
92
93#define BRDCFG2_REG_GPIO_SEL 0x20
94
95
96
97
98
99
100
101struct {
102 u8 mask;
103 u8 val;
104} mdio_mux[NUM_FM_PORTS];
105
106
107
108
109
110
111static u8 lane_to_slot[] = {
112 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 0, 0
113};
114
115
116
117
118
119
120void hydra_mux_mdio(u8 mask, u8 val)
121{
122 clrsetbits_8(&pixis->brdcfg1, mask, val);
123}
124
125struct hydra_mdio {
126 u8 mask;
127 u8 val;
128 struct mii_dev *realbus;
129};
130
131static int hydra_mdio_read(struct mii_dev *bus, int addr, int devad,
132 int regnum)
133{
134 struct hydra_mdio *priv = bus->priv;
135
136 hydra_mux_mdio(priv->mask, priv->val);
137
138 return priv->realbus->read(priv->realbus, addr, devad, regnum);
139}
140
141static int hydra_mdio_write(struct mii_dev *bus, int addr, int devad,
142 int regnum, u16 value)
143{
144 struct hydra_mdio *priv = bus->priv;
145
146 hydra_mux_mdio(priv->mask, priv->val);
147
148 return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
149}
150
151static int hydra_mdio_reset(struct mii_dev *bus)
152{
153 struct hydra_mdio *priv = bus->priv;
154
155 return priv->realbus->reset(priv->realbus);
156}
157
158static void hydra_mdio_set_mux(char *name, u8 mask, u8 val)
159{
160 struct mii_dev *bus = miiphy_get_dev_by_name(name);
161 struct hydra_mdio *priv = bus->priv;
162
163 priv->mask = mask;
164 priv->val = val;
165}
166
167static int hydra_mdio_init(char *realbusname, char *fakebusname)
168{
169 struct hydra_mdio *hmdio;
170 struct mii_dev *bus = mdio_alloc();
171
172 if (!bus) {
173 printf("Failed to allocate Hydra MDIO bus\n");
174 return -1;
175 }
176
177 hmdio = malloc(sizeof(*hmdio));
178 if (!hmdio) {
179 printf("Failed to allocate Hydra private data\n");
180 free(bus);
181 return -1;
182 }
183
184 bus->read = hydra_mdio_read;
185 bus->write = hydra_mdio_write;
186 bus->reset = hydra_mdio_reset;
187 sprintf(bus->name, fakebusname);
188
189 hmdio->realbus = miiphy_get_dev_by_name(realbusname);
190
191 if (!hmdio->realbus) {
192 printf("No bus with name %s\n", realbusname);
193 free(bus);
194 free(hmdio);
195 return -1;
196 }
197
198 bus->priv = hmdio;
199
200 return mdio_register(bus);
201}
202
203
204
205
206
207
208
209
210
211
212static void fdt_set_mdio_mux(void *fdt, const char *alias, u32 mux)
213{
214 const char *path = fdt_get_alias(fdt, alias);
215
216 if (!path)
217 path = alias;
218
219 do_fixup_by_path(fdt, path, "fsl,hydra-mdio-muxval",
220 &mux, sizeof(mux), 1);
221}
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
251 enum fm_port port, int offset)
252{
253 unsigned int mux = mdio_mux[port].val & mdio_mux[port].mask;
254 char phy[16];
255
256 if (port == FM1_10GEC1) {
257
258 int lane = serdes_get_first_lane(XAUI_FM1);
259 if (lane >= 0) {
260
261 sprintf(phy, "phy_xgmii_%u", lane_to_slot[lane]);
262 fdt_set_phy_handle(fdt, compat, addr, phy);
263 }
264 return;
265 }
266
267 if (mux == BRDCFG1_EMI1_SEL_RGMII) {
268
269
270 sprintf(phy, "phy_rgmii_%u", port == FM1_DTSEC4 ? 0 : 1);
271 fdt_set_phy_handle(fdt, compat, addr, phy);
272 }
273
274
275 if (mux) {
276
277 sprintf(phy, "phy_sgmii_%x",
278 CONFIG_SYS_FM1_DTSEC1_PHY_ADDR + (port - FM1_DTSEC1));
279 fdt_set_phy_handle(fdt, compat, addr, phy);
280 }
281}
282
283#define PIXIS_SW2_LANE_23_SEL 0x80
284#define PIXIS_SW2_LANE_45_SEL 0x40
285#define PIXIS_SW2_LANE_67_SEL_MASK 0x30
286#define PIXIS_SW2_LANE_67_SEL_5 0x00
287#define PIXIS_SW2_LANE_67_SEL_6 0x20
288#define PIXIS_SW2_LANE_67_SEL_7 0x10
289#define PIXIS_SW2_LANE_8_SEL 0x08
290#define PIXIS_SW2_LANE_1617_SEL 0x04
291
292
293
294
295
296
297
298
299
300static void initialize_lane_to_slot(void)
301{
302 u8 sw2 = in_8(&PIXIS_SW(2));
303
304 lane_to_slot[2] = (sw2 & PIXIS_SW2_LANE_23_SEL) ? 7 : 4;
305 lane_to_slot[3] = lane_to_slot[2];
306
307 lane_to_slot[4] = (sw2 & PIXIS_SW2_LANE_45_SEL) ? 7 : 6;
308 lane_to_slot[5] = lane_to_slot[4];
309
310 switch (sw2 & PIXIS_SW2_LANE_67_SEL_MASK) {
311 case PIXIS_SW2_LANE_67_SEL_5:
312 lane_to_slot[6] = 5;
313 break;
314 case PIXIS_SW2_LANE_67_SEL_6:
315 lane_to_slot[6] = 6;
316 break;
317 case PIXIS_SW2_LANE_67_SEL_7:
318 lane_to_slot[6] = 7;
319 break;
320 }
321 lane_to_slot[7] = lane_to_slot[6];
322
323 lane_to_slot[8] = (sw2 & PIXIS_SW2_LANE_8_SEL) ? 3 : 0;
324
325 lane_to_slot[16] = (sw2 & PIXIS_SW2_LANE_1617_SEL) ? 1 : 0;
326 lane_to_slot[17] = lane_to_slot[16];
327}
328
329#endif
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344void fdt_fixup_board_enet(void *fdt)
345{
346#ifdef CONFIG_FMAN_ENET
347 unsigned int i;
348 int lane;
349
350 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
351 int idx = i - FM1_DTSEC1;
352
353 switch (fm_info_get_enet_if(i)) {
354 case PHY_INTERFACE_MODE_SGMII:
355 lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx);
356 if (lane >= 0) {
357 fdt_status_okay_by_alias(fdt, "emi1_sgmii");
358
359 fdt_set_mdio_mux(fdt, "emi1_sgmii",
360 mdio_mux[i].val);
361 }
362 break;
363 case PHY_INTERFACE_MODE_RGMII:
364 fdt_status_okay_by_alias(fdt, "emi1_rgmii");
365 break;
366 default:
367 break;
368 }
369 }
370
371 lane = serdes_get_first_lane(XAUI_FM1);
372 if (lane >= 0)
373 fdt_status_okay_by_alias(fdt, "emi2_xgmii");
374#endif
375}
376
377int board_eth_init(bd_t *bis)
378{
379#ifdef CONFIG_FMAN_ENET
380 struct fsl_pq_mdio_info dtsec_mdio_info;
381 struct tgec_mdio_info tgec_mdio_info;
382 unsigned int i, slot;
383 int lane;
384
385 printf("Initializing Fman\n");
386
387 initialize_lane_to_slot();
388
389
390 setbits_8(&pixis->brdcfg2, BRDCFG2_REG_GPIO_SEL);
391
392 memset(mdio_mux, 0, sizeof(mdio_mux));
393
394 dtsec_mdio_info.regs =
395 (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR;
396 dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;
397
398
399 fsl_pq_mdio_init(bis, &dtsec_mdio_info);
400
401 tgec_mdio_info.regs =
402 (struct tgec_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR;
403 tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;
404
405
406 fm_tgec_mdio_init(bis, &tgec_mdio_info);
407
408
409 hydra_mdio_init(DEFAULT_FM_MDIO_NAME, "HYDRA_RGMII_MDIO");
410 hydra_mdio_init(DEFAULT_FM_MDIO_NAME, "HYDRA_SGMII_MDIO");
411
412
413
414
415
416
417 fm_info_set_phy_address(FM1_DTSEC1, CONFIG_SYS_FM1_DTSEC1_PHY_ADDR);
418 fm_info_set_phy_address(FM1_DTSEC2, CONFIG_SYS_FM1_DTSEC2_PHY_ADDR);
419 fm_info_set_phy_address(FM1_DTSEC3, CONFIG_SYS_FM1_DTSEC3_PHY_ADDR);
420 fm_info_set_phy_address(FM1_DTSEC4, CONFIG_SYS_FM1_DTSEC4_PHY_ADDR);
421
422 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
423 int idx = i - FM1_DTSEC1;
424
425 switch (fm_info_get_enet_if(i)) {
426 case PHY_INTERFACE_MODE_SGMII:
427 lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx);
428 if (lane < 0)
429 break;
430 slot = lane_to_slot[lane];
431 mdio_mux[i].mask = BRDCFG1_EMI1_SEL_MASK;
432 switch (slot) {
433 case 1:
434
435 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT1 |
436 BRDCFG1_EMI1_EN;
437 break;
438 case 2:
439 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT2 |
440 BRDCFG1_EMI1_EN;
441 break;
442 case 5:
443 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT5 |
444 BRDCFG1_EMI1_EN;
445 break;
446 case 6:
447 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT6 |
448 BRDCFG1_EMI1_EN;
449 break;
450 case 7:
451 mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT7 |
452 BRDCFG1_EMI1_EN;
453 break;
454 };
455
456 hydra_mdio_set_mux("HYDRA_SGMII_MDIO",
457 mdio_mux[i].mask, mdio_mux[i].val);
458 fm_info_set_mdio(i,
459 miiphy_get_dev_by_name("HYDRA_SGMII_MDIO"));
460 break;
461 case PHY_INTERFACE_MODE_RGMII:
462
463
464
465
466
467
468
469 fm_info_set_phy_address(i, i == FM1_DTSEC4 ? 0 : 1);
470 mdio_mux[i].mask = BRDCFG1_EMI1_SEL_MASK;
471 mdio_mux[i].val = BRDCFG1_EMI1_SEL_RGMII |
472 BRDCFG1_EMI1_EN;
473 hydra_mdio_set_mux("HYDRA_RGMII_MDIO",
474 mdio_mux[i].mask, mdio_mux[i].val);
475 fm_info_set_mdio(i,
476 miiphy_get_dev_by_name("HYDRA_RGMII_MDIO"));
477 break;
478 case PHY_INTERFACE_MODE_NONE:
479 fm_info_set_phy_address(i, 0);
480 break;
481 default:
482 printf("Fman1: DTSEC%u set to unknown interface %i\n",
483 idx + 1, fm_info_get_enet_if(i));
484 fm_info_set_phy_address(i, 0);
485 break;
486 }
487 }
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502 lane = serdes_get_first_lane(XAUI_FM1);
503 if (lane >= 0) {
504 slot = lane_to_slot[lane];
505 if (slot == 1) {
506
507 clrsetbits_8(&pixis->brdcfg1, BRDCFG1_EMI2_SEL_MASK,
508 BRDCFG1_EMI2_SEL_SLOT1);
509 fm_info_set_phy_address(FM1_10GEC1,
510 CONFIG_SYS_FM1_10GEC1_PHY_ADDR);
511 } else {
512
513 clrsetbits_8(&pixis->brdcfg1, BRDCFG1_EMI2_SEL_MASK,
514 BRDCFG1_EMI2_SEL_SLOT2);
515 fm_info_set_phy_address(FM1_10GEC1,
516 CONFIG_SYS_FM2_10GEC1_PHY_ADDR);
517 }
518 }
519
520 fm_info_set_mdio(FM1_10GEC1,
521 miiphy_get_dev_by_name(DEFAULT_FM_TGEC_MDIO_NAME));
522
523 cpu_eth_init(bis);
524#endif
525
526 return pci_eth_init(bis);
527}
528