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