blob: 3f812dbd3c9b7bc20dad1d56afe7741e7c09da0f [file] [log] [blame]
Shengzhou Liuae6b03f2011-11-22 16:51:13 +08001/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 *
4 * See file CREDITS for list of people who contributed to this
5 * project.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23#include <common.h>
24#include <command.h>
25#include <netdev.h>
26#include <asm/mmu.h>
27#include <asm/processor.h>
28#include <asm/cache.h>
29#include <asm/immap_85xx.h>
30#include <asm/fsl_law.h>
31#include <asm/fsl_ddr_sdram.h>
32#include <asm/fsl_serdes.h>
33#include <asm/fsl_portals.h>
34#include <asm/fsl_liodn.h>
35#include <malloc.h>
36#include <fm_eth.h>
37#include <fsl_mdio.h>
38#include <miiphy.h>
39#include <phy.h>
40#include <asm/fsl_dtsec.h>
41
42#include "../common/qixis.h"
43#include "../common/fman.h"
44
45#include "p3060qds_qixis.h"
46
47#define EMI_NONE 0xffffffff
48#define EMI1_RGMII1 0
49#define EMI1_SLOT1 1
50#define EMI1_SLOT2 2
51#define EMI1_SLOT3 3
52#define EMI1_RGMII2 4
53
54static int mdio_mux[NUM_FM_PORTS];
55
56static char *mdio_names[5] = {
57 "P3060QDS_MDIO0",
58 "P3060QDS_MDIO1",
59 "P3060QDS_MDIO2",
60 "P3060QDS_MDIO3",
61 "P3060QDS_MDIO4",
62};
63
64/*
65 * Mapping of all 18 SERDES lanes to board slots.
66 * A value of '0' here means that the mapping must be determined
67 * dynamically, Lane 8/9/16/17 map to Slot1 or Aurora debug
68 */
69static u8 lane_to_slot[] = {
70 4, 4, 4, 4, 3, 3, 3, 3, 0, 0, 2, 2, 2, 2, 1, 1, 0, 0
71};
72
73static char *p3060qds_mdio_name_for_muxval(u32 muxval)
74{
75 return mdio_names[muxval];
76}
77
78struct mii_dev *mii_dev_for_muxval(u32 muxval)
79{
80 struct mii_dev *bus;
81 char *name = p3060qds_mdio_name_for_muxval(muxval);
82
83 if (!name) {
84 printf("No bus for muxval %x\n", muxval);
85 return NULL;
86 }
87
88 bus = miiphy_get_dev_by_name(name);
89
90 if (!bus) {
91 printf("No bus by name %s\n", name);
92 return NULL;
93 }
94
95 return bus;
96}
97
98struct p3060qds_mdio {
99 u32 muxval;
100 struct mii_dev *realbus;
101};
102
103static void p3060qds_mux_mdio(u32 muxval)
104{
105 u8 brdcfg4;
106
107 brdcfg4 = QIXIS_READ(brdcfg[4]);
108 brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
109 brdcfg4 |= (muxval << 4);
110 QIXIS_WRITE(brdcfg[4], brdcfg4);
111}
112
113static int p3060qds_mdio_read(struct mii_dev *bus, int addr, int devad,
114 int regnum)
115{
116 struct p3060qds_mdio *priv = bus->priv;
117
118 p3060qds_mux_mdio(priv->muxval);
119
120 return priv->realbus->read(priv->realbus, addr, devad, regnum);
121}
122
123static int p3060qds_mdio_write(struct mii_dev *bus, int addr, int devad,
124 int regnum, u16 value)
125{
126 struct p3060qds_mdio *priv = bus->priv;
127
128 p3060qds_mux_mdio(priv->muxval);
129
130 return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
131}
132
133static int p3060qds_mdio_reset(struct mii_dev *bus)
134{
135 struct p3060qds_mdio *priv = bus->priv;
136
137 return priv->realbus->reset(priv->realbus);
138}
139
140static int p3060qds_mdio_init(char *realbusname, u32 muxval)
141{
142 struct p3060qds_mdio *pmdio;
143 struct mii_dev *bus = mdio_alloc();
144
145 if (!bus) {
146 printf("Failed to allocate P3060QDS MDIO bus\n");
147 return -1;
148 }
149
150 pmdio = malloc(sizeof(*pmdio));
151 if (!pmdio) {
152 printf("Failed to allocate P3060QDS private data\n");
153 free(bus);
154 return -1;
155 }
156
157 bus->read = p3060qds_mdio_read;
158 bus->write = p3060qds_mdio_write;
159 bus->reset = p3060qds_mdio_reset;
160 sprintf(bus->name, p3060qds_mdio_name_for_muxval(muxval));
161
162 pmdio->realbus = miiphy_get_dev_by_name(realbusname);
163
164 if (!pmdio->realbus) {
165 printf("No bus with name %s\n", realbusname);
166 free(bus);
167 free(pmdio);
168 return -1;
169 }
170
171 pmdio->muxval = muxval;
172 bus->priv = pmdio;
173
174 return mdio_register(bus);
175}
176
177void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa,
178 enum fm_port port, int offset)
179{
180 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
181 int srds_prtcl = (in_be32(&gur->rcwsr[4]) &
182 FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26;
183
184 if (mdio_mux[port] == EMI1_RGMII1)
185 fdt_set_phy_handle(blob, prop, pa, "phy_rgmii1");
186
187 if (mdio_mux[port] == EMI1_RGMII2)
188 fdt_set_phy_handle(blob, prop, pa, "phy_rgmii2");
189
190 if ((mdio_mux[port] == EMI1_SLOT1) && ((srds_prtcl == 0x3)
191 || (srds_prtcl == 0x6))) {
192 switch (port) {
193 case FM2_DTSEC4:
194 fdt_set_phy_handle(blob, prop, pa, "phy2_slot1");
195 break;
196 case FM1_DTSEC4:
197 fdt_set_phy_handle(blob, prop, pa, "phy3_slot1");
198 break;
199 default:
200 break;
201 }
202 }
203
204 if (mdio_mux[port] == EMI1_SLOT3) {
205 switch (port) {
206 case FM2_DTSEC3:
207 fdt_set_phy_handle(blob, prop, pa, "phy0_slot3");
208 break;
209 case FM1_DTSEC3:
210 fdt_set_phy_handle(blob, prop, pa, "phy1_slot3");
211 break;
212 default:
213 break;
214 }
215 }
216}
217
218void fdt_fixup_board_enet(void *fdt)
219{
220 int i, lane, idx;
221
222 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
223 idx = i - FM1_DTSEC1;
224 switch (fm_info_get_enet_if(i)) {
225 case PHY_INTERFACE_MODE_SGMII:
226 lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx);
227 if (lane < 0)
228 break;
229
230 switch (mdio_mux[i]) {
231 case EMI1_SLOT1:
232 if (lane >= 14) {
233 fdt_status_okay_by_alias(fdt,
234 "emi1_slot1");
235 fdt_status_disabled_by_alias(fdt,
236 "emi1_slot1_bk1");
237 } else {
238 fdt_status_disabled_by_alias(fdt,
239 "emi1_slot1");
240 fdt_status_okay_by_alias(fdt,
241 "emi1_slot1_bk1");
242 }
243 break;
244 case EMI1_SLOT2:
245 fdt_status_okay_by_alias(fdt, "emi1_slot2");
246 break;
247 case EMI1_SLOT3:
248 fdt_status_okay_by_alias(fdt, "emi1_slot3");
249 break;
250 }
251 break;
252 case PHY_INTERFACE_MODE_RGMII:
253 if (i == FM1_DTSEC1)
254 fdt_status_okay_by_alias(fdt, "emi1_rgmii1");
255
256 if (i == FM1_DTSEC2)
257 fdt_status_okay_by_alias(fdt, "emi1_rgmii2");
258 break;
259 default:
260 break;
261 }
262 }
263#if (CONFIG_SYS_NUM_FMAN == 2)
264 for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) {
265 idx = i - FM2_DTSEC1;
266 switch (fm_info_get_enet_if(i)) {
267 case PHY_INTERFACE_MODE_SGMII:
268 lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx);
269 if (lane >= 0) {
270 switch (mdio_mux[i]) {
271 case EMI1_SLOT1:
272 if (lane >= 14)
273 fdt_status_okay_by_alias(fdt,
274 "emi1_slot1");
275 else
276 fdt_status_okay_by_alias(fdt,
277 "emi1_slot1_bk1");
278 break;
279 case EMI1_SLOT2:
280 fdt_status_okay_by_alias(fdt,
281 "emi1_slot2");
282 break;
283 case EMI1_SLOT3:
284 fdt_status_okay_by_alias(fdt,
285 "emi1_slot3");
286 break;
287 }
288 }
289 break;
290 default:
291 break;
292 }
293 }
294#endif
295}
296
297static void initialize_lane_to_slot(void)
298{
299 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
300 int sdprtl = (in_be32(&gur->rcwsr[4]) &
301 FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26;
302
303 switch (sdprtl) {
304 case 0x03:
305 case 0x06:
306 lane_to_slot[8] = 1;
307 lane_to_slot[9] = lane_to_slot[8];
308 lane_to_slot[16] = 5;
309 lane_to_slot[17] = lane_to_slot[16];
310 break;
311 case 0x16:
312 case 0x19:
313 case 0x1C:
314 lane_to_slot[8] = 5;
315 lane_to_slot[9] = lane_to_slot[8];
316 lane_to_slot[16] = 1;
317 lane_to_slot[17] = lane_to_slot[16];
318 break;
319 default:
320 puts("Invalid SerDes protocol for P3060QDS\n");
321 break;
322 }
323}
324
325int board_eth_init(bd_t *bis)
326{
327#ifdef CONFIG_FMAN_ENET
328 struct dtsec *tsec = (void *)CONFIG_SYS_FSL_FM1_DTSEC1_ADDR;
329 int i;
330 struct fsl_pq_mdio_info dtsec_mdio_info;
331 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
332 int srds_cfg = (in_be32(&gur->rcwsr[4]) &
333 FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26;
334
335 initialize_lane_to_slot();
336
337 /*
338 * Set TBIPA on FM1@DTSEC1. This is needed for configurations
339 * where FM1@DTSEC1 isn't used directly, since it provides
340 * MDIO for other ports.
341 */
342 out_be32(&tsec->tbipa, CONFIG_SYS_TBIPA_VALUE);
343
344 /* Initialize the mdio_mux array so we can recognize empty elements */
345 for (i = 0; i < NUM_FM_PORTS; i++)
346 mdio_mux[i] = EMI_NONE;
347
348 dtsec_mdio_info.regs =
349 (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR;
350 dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;
351
352 /* Register the 1G MDIO bus */
353 fsl_pq_mdio_init(bis, &dtsec_mdio_info);
354
355 /* Register the 5 muxing front-ends to the MDIO buses */
356 if (fm_info_get_enet_if(FM1_DTSEC1) == PHY_INTERFACE_MODE_RGMII)
357 p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1);
358
359 if (fm_info_get_enet_if(FM1_DTSEC2) == PHY_INTERFACE_MODE_RGMII)
360 p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII2);
361 p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1);
362 p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT2);
363 p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3);
364
365 if (fm_info_get_enet_if(FM1_DTSEC1) == PHY_INTERFACE_MODE_RGMII)
366 fm_info_set_phy_address(FM1_DTSEC1, 1); /* RGMII1 */
367 else if (fm_info_get_enet_if(FM1_DTSEC1) == PHY_INTERFACE_MODE_SGMII)
368 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT2_PHY_ADDR);
369
370 if (fm_info_get_enet_if(FM1_DTSEC2) == PHY_INTERFACE_MODE_RGMII)
371 fm_info_set_phy_address(FM1_DTSEC2, 2); /* RGMII2 */
372 else if (fm_info_get_enet_if(FM1_DTSEC2) == PHY_INTERFACE_MODE_SGMII)
373 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
374
375 fm_info_set_phy_address(FM2_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR);
376 fm_info_set_phy_address(FM2_DTSEC2, SGMII_CARD_PORT3_PHY_ADDR);
377
378 switch (srds_cfg) {
379 case 0x03:
380 case 0x06:
381 fm_info_set_phy_address(FM2_DTSEC3, SGMII_CARD_PORT3_PHY_ADDR);
382 fm_info_set_phy_address(FM1_DTSEC3, SGMII_CARD_PORT4_PHY_ADDR);
383 fm_info_set_phy_address(FM2_DTSEC4, SGMII_CARD_PORT1_PHY_ADDR);
384 fm_info_set_phy_address(FM1_DTSEC4, SGMII_CARD_PORT2_PHY_ADDR);
385 break;
386 case 0x16:
387 case 0x19:
388 case 0x1C:
389 fm_info_set_phy_address(FM2_DTSEC3, SGMII_CARD_PORT1_PHY_ADDR);
390 fm_info_set_phy_address(FM1_DTSEC3, SGMII_CARD_PORT2_PHY_ADDR);
391 fm_info_set_phy_address(FM2_DTSEC4, SGMII_CARD_PORT3_PHY_ADDR);
392 fm_info_set_phy_address(FM1_DTSEC4, SGMII_CARD_PORT4_PHY_ADDR);
393 break;
394 default:
395 puts("Invalid SerDes protocol for P3060QDS\n");
396 break;
397 }
398
399 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
400 int idx = i - FM1_DTSEC1, lane, slot;
401 switch (fm_info_get_enet_if(i)) {
402 case PHY_INTERFACE_MODE_SGMII:
403 lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx);
404 if (lane < 0)
405 break;
406 slot = lane_to_slot[lane];
407 if (QIXIS_READ(present) & (1 << (slot - 1)))
408 fm_disable_port(i);
409 switch (slot) {
410 case 1:
411 mdio_mux[i] = EMI1_SLOT1;
412 fm_info_set_mdio(i,
413 mii_dev_for_muxval(mdio_mux[i]));
414 break;
415 case 2:
416 mdio_mux[i] = EMI1_SLOT2;
417 fm_info_set_mdio(i,
418 mii_dev_for_muxval(mdio_mux[i]));
419 break;
420 case 3:
421 mdio_mux[i] = EMI1_SLOT3;
422 fm_info_set_mdio(i,
423 mii_dev_for_muxval(mdio_mux[i]));
424 break;
425 };
426 break;
427 case PHY_INTERFACE_MODE_RGMII:
428 if (i == FM1_DTSEC1) {
429 mdio_mux[i] = EMI1_RGMII1;
430 fm_info_set_mdio(i,
431 mii_dev_for_muxval(mdio_mux[i]));
432 } else if (i == FM1_DTSEC2) {
433 mdio_mux[i] = EMI1_RGMII2;
434 fm_info_set_mdio(i,
435 mii_dev_for_muxval(mdio_mux[i]));
436 }
437 break;
438 default:
439 break;
440 }
441 }
442
443#if (CONFIG_SYS_NUM_FMAN == 2)
444 for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) {
445 int idx = i - FM2_DTSEC1, lane, slot;
446 switch (fm_info_get_enet_if(i)) {
447 case PHY_INTERFACE_MODE_SGMII:
448 lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx);
449 if (lane < 0)
450 break;
451 slot = lane_to_slot[lane];
452 if (QIXIS_READ(present) & (1 << (slot - 1)))
453 fm_disable_port(i);
454 switch (slot) {
455 case 1:
456 mdio_mux[i] = EMI1_SLOT1;
457 fm_info_set_mdio(i,
458 mii_dev_for_muxval(mdio_mux[i]));
459 break;
460 case 2:
461 mdio_mux[i] = EMI1_SLOT2;
462 fm_info_set_mdio(i,
463 mii_dev_for_muxval(mdio_mux[i]));
464 break;
465 case 3:
466 mdio_mux[i] = EMI1_SLOT3;
467 fm_info_set_mdio(i,
468 mii_dev_for_muxval(mdio_mux[i]));
469 break;
470 };
471 break;
472 default:
473 break;
474 }
475 }
476#endif /* CONFIG_SYS_NUM_FMAN */
477
478 cpu_eth_init(bis);
479#endif /* CONFIG_FMAN_ENET */
480
481 return pci_eth_init(bis);
482}