blob: 25b3be8663690806e18aff4923278b0afef5dc76 [file] [log] [blame]
York Sunb5b06fb2012-12-23 19:25:27 +00001/*
2 * Copyright 2011-2012 Freescale Semiconductor, Inc.
3 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02004 * SPDX-License-Identifier: GPL-2.0+
York Sunb5b06fb2012-12-23 19:25:27 +00005 */
6
7#include <common.h>
8#include <command.h>
9#include <i2c.h>
10#include <netdev.h>
11#include <linux/compiler.h>
12#include <asm/mmu.h>
13#include <asm/processor.h>
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +053014#include <asm/errno.h>
York Sunb5b06fb2012-12-23 19:25:27 +000015#include <asm/cache.h>
16#include <asm/immap_85xx.h>
17#include <asm/fsl_law.h>
18#include <asm/fsl_serdes.h>
19#include <asm/fsl_portals.h>
20#include <asm/fsl_liodn.h>
21#include <fm_eth.h>
22
23#include "../common/qixis.h"
24#include "../common/vsc3316_3308.h"
Shaveta Leekhacb033742013-07-02 14:43:53 +053025#include "../common/idt8t49n222a_serdes_clk.h"
York Sunb5b06fb2012-12-23 19:25:27 +000026#include "b4860qds.h"
27#include "b4860qds_qixis.h"
28#include "b4860qds_crossbar_con.h"
29
30#define CLK_MUX_SEL_MASK 0x4
31#define ETH_PHY_CLK_OUT 0x4
Shaveta Leekhacb033742013-07-02 14:43:53 +053032#define PLL_NUM 2
York Sunb5b06fb2012-12-23 19:25:27 +000033
34DECLARE_GLOBAL_DATA_PTR;
35
36int checkboard(void)
37{
38 char buf[64];
39 u8 sw;
Simon Glass67ac13b2012-12-13 20:48:48 +000040 struct cpu_type *cpu = gd->arch.cpu;
York Sunb5b06fb2012-12-23 19:25:27 +000041 static const char *const freq[] = {"100", "125", "156.25", "161.13",
42 "122.88", "122.88", "122.88"};
43 int clock;
44
45 printf("Board: %sQDS, ", cpu->name);
46 printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, ",
47 QIXIS_READ(id), QIXIS_READ(arch));
48
49 sw = QIXIS_READ(brdcfg[0]);
50 sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
51
52 if (sw < 0x8)
53 printf("vBank: %d\n", sw);
54 else if (sw >= 0x8 && sw <= 0xE)
55 puts("NAND\n");
56 else
57 printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
58
59 printf("FPGA: v%d (%s), build %d",
60 (int)QIXIS_READ(scver), qixis_read_tag(buf),
61 (int)qixis_read_minor());
62 /* the timestamp string contains "\n" at the end */
63 printf(" on %s", qixis_read_time(buf));
64
York Sunb5b06fb2012-12-23 19:25:27 +000065 /*
66 * Display the actual SERDES reference clocks as configured by the
67 * dip switches on the board. Note that the SWx registers could
68 * technically be set to force the reference clocks to match the
69 * values that the SERDES expects (or vice versa). For now, however,
70 * we just display both values and hope the user notices when they
71 * don't match.
72 */
73 puts("SERDES Reference Clocks: ");
74 sw = QIXIS_READ(brdcfg[2]);
75 clock = (sw >> 5) & 7;
76 printf("Bank1=%sMHz ", freq[clock]);
77 sw = QIXIS_READ(brdcfg[4]);
78 clock = (sw >> 6) & 3;
79 printf("Bank2=%sMHz\n", freq[clock]);
80
81 return 0;
82}
83
84int select_i2c_ch_pca(u8 ch)
85{
86 int ret;
87
88 /* Selecting proper channel via PCA*/
89 ret = i2c_write(I2C_MUX_PCA_ADDR, 0x0, 1, &ch, 1);
90 if (ret) {
91 printf("PCA: failed to select proper channel.\n");
92 return ret;
93 }
94
95 return 0;
96}
97
98int configure_vsc3316_3308(void)
99{
100 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
101 unsigned int num_vsc16_con, num_vsc08_con;
102 u32 serdes1_prtcl, serdes2_prtcl;
103 int ret;
104
105 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
106 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
107 if (!serdes1_prtcl) {
108 printf("SERDES1 is not enabled\n");
109 return 0;
110 }
111 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
112 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
113
114 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
115 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
116 if (!serdes2_prtcl) {
117 printf("SERDES2 is not enabled\n");
118 return 0;
119 }
120 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
121 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
122
123 switch (serdes1_prtcl) {
poonam aggrwalc7d506d2014-02-17 08:38:58 +0530124 case 0x29:
York Sunb5b06fb2012-12-23 19:25:27 +0000125 case 0x2a:
126 case 0x2C:
127 case 0x2D:
128 case 0x2E:
129 /*
130 * Configuration:
131 * SERDES: 1
132 * Lanes: A,B: SGMII
133 * Lanes: C,D,E,F,G,H: CPRI
134 */
135 debug("Configuring crossbar to use onboard SGMII PHYs:"
136 "srds_prctl:%x\n", serdes1_prtcl);
137 num_vsc16_con = NUM_CON_VSC3316;
138 /* Configure VSC3316 crossbar switch */
139 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
140 if (!ret) {
141 ret = vsc3316_config(VSC3316_TX_ADDRESS,
Shaveta Leekha0fecbba2013-03-25 07:40:17 +0000142 vsc16_tx_4sfp_sgmii_12_56,
143 num_vsc16_con);
York Sunb5b06fb2012-12-23 19:25:27 +0000144 if (ret)
145 return ret;
146 ret = vsc3316_config(VSC3316_RX_ADDRESS,
Shaveta Leekha0fecbba2013-03-25 07:40:17 +0000147 vsc16_rx_4sfp_sgmii_12_56,
148 num_vsc16_con);
York Sunb5b06fb2012-12-23 19:25:27 +0000149 if (ret)
150 return ret;
151 } else {
152 return ret;
153 }
154 break;
155
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530156 case 0x02:
157 case 0x04:
158 case 0x05:
159 case 0x06:
160 case 0x08:
161 case 0x09:
162 case 0x0A:
163 case 0x0B:
164 case 0x0C:
165 case 0x30:
166 case 0x32:
167 case 0x33:
168 case 0x34:
169 case 0x39:
170 case 0x3A:
171 case 0x3C:
172 case 0x3D:
173 case 0x5C:
174 case 0x5D:
175 /*
176 * Configuration:
177 * SERDES: 1
178 * Lanes: A,B: AURORA
179 * Lanes: C,d: SGMII
180 * Lanes: E,F,G,H: CPRI
181 */
182 debug("Configuring crossbar for Aurora, SGMII 3 and 4,"
183 " and CPRI. srds_prctl:%x\n", serdes1_prtcl);
184 num_vsc16_con = NUM_CON_VSC3316;
185 /* Configure VSC3316 crossbar switch */
186 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
187 if (!ret) {
188 ret = vsc3316_config(VSC3316_TX_ADDRESS,
189 vsc16_tx_sfp_sgmii_aurora,
190 num_vsc16_con);
191 if (ret)
192 return ret;
193 ret = vsc3316_config(VSC3316_RX_ADDRESS,
194 vsc16_rx_sfp_sgmii_aurora,
195 num_vsc16_con);
196 if (ret)
197 return ret;
198 } else {
199 return ret;
200 }
201 break;
202
York Sunb5b06fb2012-12-23 19:25:27 +0000203#ifdef CONFIG_PPC_B4420
poonam aggrwalc7d506d2014-02-17 08:38:58 +0530204 case 0x17:
York Sunb5b06fb2012-12-23 19:25:27 +0000205 case 0x18:
206 /*
207 * Configuration:
208 * SERDES: 1
209 * Lanes: A,B,C,D: SGMII
210 * Lanes: E,F,G,H: CPRI
211 */
212 debug("Configuring crossbar to use onboard SGMII PHYs:"
213 "srds_prctl:%x\n", serdes1_prtcl);
214 num_vsc16_con = NUM_CON_VSC3316;
215 /* Configure VSC3316 crossbar switch */
216 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
217 if (!ret) {
218 ret = vsc3316_config(VSC3316_TX_ADDRESS,
219 vsc16_tx_sgmii_lane_cd, num_vsc16_con);
220 if (ret)
221 return ret;
222 ret = vsc3316_config(VSC3316_RX_ADDRESS,
223 vsc16_rx_sgmii_lane_cd, num_vsc16_con);
224 if (ret)
225 return ret;
226 } else {
227 return ret;
228 }
229 break;
230#endif
231
232 case 0x3E:
233 case 0x0D:
234 case 0x0E:
235 case 0x12:
236 num_vsc16_con = NUM_CON_VSC3316;
237 /* Configure VSC3316 crossbar switch */
238 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
239 if (!ret) {
240 ret = vsc3316_config(VSC3316_TX_ADDRESS,
241 vsc16_tx_sfp, num_vsc16_con);
242 if (ret)
243 return ret;
244 ret = vsc3316_config(VSC3316_RX_ADDRESS,
245 vsc16_rx_sfp, num_vsc16_con);
246 if (ret)
247 return ret;
248 } else {
249 return ret;
250 }
251 break;
252 default:
253 printf("WARNING:VSC crossbars programming not supported for:%x"
254 " SerDes1 Protocol.\n", serdes1_prtcl);
255 return -1;
256 }
257
258 switch (serdes2_prtcl) {
259 case 0x9E:
260 case 0x9A:
261 case 0x98:
262 case 0xb2:
263 case 0x49:
264 case 0x4E:
265 case 0x8D:
266 case 0x7A:
267 num_vsc08_con = NUM_CON_VSC3308;
268 /* Configure VSC3308 crossbar switch */
269 ret = select_i2c_ch_pca(I2C_CH_VSC3308);
270 if (!ret) {
271 ret = vsc3308_config(VSC3308_TX_ADDRESS,
272 vsc08_tx_amc, num_vsc08_con);
273 if (ret)
274 return ret;
275 ret = vsc3308_config(VSC3308_RX_ADDRESS,
276 vsc08_rx_amc, num_vsc08_con);
277 if (ret)
278 return ret;
279 } else {
280 return ret;
281 }
282 break;
283 default:
284 printf("WARNING:VSC crossbars programming not supported for: %x"
285 " SerDes2 Protocol.\n", serdes2_prtcl);
286 return -1;
287 }
288
289 return 0;
290}
291
Shaveta Leekhacb033742013-07-02 14:43:53 +0530292int config_serdes1_refclks(void)
293{
294 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
295 serdes_corenet_t *srds_regs =
296 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
297 u32 serdes1_prtcl, lane;
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530298 unsigned int flag_sgmii_aurora_prtcl = 0;
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530299 int i;
300 int ret = 0;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530301
302 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
303 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
304 if (!serdes1_prtcl) {
305 printf("SERDES1 is not enabled\n");
306 return -1;
307 }
308 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
309 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
310
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530311 /* To prevent generation of reset request from SerDes
312 * while changing the refclks, By setting SRDS_RST_MSK bit,
313 * SerDes reset event cannot cause a reset request
Shaveta Leekhacb033742013-07-02 14:43:53 +0530314 */
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530315 setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
316
Shaveta Leekhacb033742013-07-02 14:43:53 +0530317 /* Reconfigure IDT idt8t49n222a device for CPRI to work
318 * For this SerDes1's Refclk1 and refclk2 need to be set
319 * to 122.88MHz
320 */
321 switch (serdes1_prtcl) {
322 case 0x2A:
323 case 0x2C:
324 case 0x2D:
325 case 0x2E:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530326 case 0x02:
327 case 0x04:
328 case 0x05:
329 case 0x06:
330 case 0x08:
331 case 0x09:
332 case 0x0A:
333 case 0x0B:
334 case 0x0C:
335 case 0x30:
336 case 0x32:
337 case 0x33:
338 case 0x34:
339 case 0x39:
340 case 0x3A:
341 case 0x3C:
342 case 0x3D:
343 case 0x5C:
344 case 0x5D:
Shaveta Leekhacb033742013-07-02 14:43:53 +0530345 debug("Configuring idt8t49n222a for CPRI SerDes clks:"
346 " for srds_prctl:%x\n", serdes1_prtcl);
347 ret = select_i2c_ch_pca(I2C_CH_IDT);
348 if (!ret) {
349 ret = set_serdes_refclk(IDT_SERDES1_ADDRESS, 1,
350 SERDES_REFCLK_122_88,
351 SERDES_REFCLK_122_88, 0);
352 if (ret) {
353 printf("IDT8T49N222A configuration failed.\n");
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530354 goto out;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530355 } else
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530356 debug("IDT8T49N222A configured.\n");
Shaveta Leekhacb033742013-07-02 14:43:53 +0530357 } else {
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530358 goto out;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530359 }
360 select_i2c_ch_pca(I2C_CH_DEFAULT);
361
362 /* Change SerDes1's Refclk1 to 125MHz for on board
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530363 * SGMIIs or Aurora to work
Shaveta Leekhacb033742013-07-02 14:43:53 +0530364 */
365 for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
366 enum srds_prtcl lane_prtcl = serdes_get_prtcl
367 (0, serdes1_prtcl, lane);
368 switch (lane_prtcl) {
369 case SGMII_FM1_DTSEC1:
370 case SGMII_FM1_DTSEC2:
371 case SGMII_FM1_DTSEC3:
372 case SGMII_FM1_DTSEC4:
373 case SGMII_FM1_DTSEC5:
374 case SGMII_FM1_DTSEC6:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530375 case AURORA:
376 flag_sgmii_aurora_prtcl++;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530377 break;
378 default:
379 break;
380 }
381 }
382
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530383 if (flag_sgmii_aurora_prtcl)
Shaveta Leekhacb033742013-07-02 14:43:53 +0530384 QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
385
386 /* Steps For SerDes PLLs reset and reconfiguration after
387 * changing SerDes's refclks
388 */
389 for (i = 0; i < PLL_NUM; i++) {
390 debug("For PLL%d reset and reconfiguration after"
391 " changing refclks\n", i+1);
392 clrbits_be32(&srds_regs->bank[i].rstctl,
393 SRDS_RSTCTL_SDRST_B);
394 udelay(10);
395 clrbits_be32(&srds_regs->bank[i].rstctl,
396 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
397 udelay(10);
398 setbits_be32(&srds_regs->bank[i].rstctl,
399 SRDS_RSTCTL_RST);
400 setbits_be32(&srds_regs->bank[i].rstctl,
401 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
402 | SRDS_RSTCTL_SDRST_B));
403 }
404 break;
405 default:
406 printf("WARNING:IDT8T49N222A configuration not"
407 " supported for:%x SerDes1 Protocol.\n",
408 serdes1_prtcl);
Shaveta Leekhacb033742013-07-02 14:43:53 +0530409 }
410
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530411out:
412 /* Clearing SRDS_RST_MSK bit as now
413 * SerDes reset event can cause a reset request
414 */
415 clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
416 return ret;
417}
418
419int config_serdes2_refclks(void)
420{
421 ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
422 serdes_corenet_t *srds2_regs =
423 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
424 u32 serdes2_prtcl;
425 int ret = 0;
426 int i;
427
428 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
429 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
430 if (!serdes2_prtcl) {
431 debug("SERDES2 is not enabled\n");
432 return -ENODEV;
433 }
434 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
435 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
436
437 /* To prevent generation of reset request from SerDes
438 * while changing the refclks, By setting SRDS_RST_MSK bit,
439 * SerDes reset event cannot cause a reset request
440 */
441 setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
442
443 /* Reconfigure IDT idt8t49n222a device for PCIe SATA to work
444 * For this SerDes2's Refclk1 need to be set to 100MHz
445 */
446 switch (serdes2_prtcl) {
447 case 0x9E:
448 case 0x9A:
449 case 0xb2:
450 debug("Configuring IDT for PCIe SATA for srds_prctl:%x\n",
451 serdes2_prtcl);
452 ret = select_i2c_ch_pca(I2C_CH_IDT);
453 if (!ret) {
454 ret = set_serdes_refclk(IDT_SERDES2_ADDRESS, 2,
455 SERDES_REFCLK_100,
456 SERDES_REFCLK_100, 0);
457 if (ret) {
458 printf("IDT8T49N222A configuration failed.\n");
459 goto out;
460 } else
461 debug("IDT8T49N222A configured.\n");
462 } else {
463 goto out;
464 }
465 select_i2c_ch_pca(I2C_CH_DEFAULT);
466
467 /* Steps For SerDes PLLs reset and reconfiguration after
468 * changing SerDes's refclks
469 */
470 for (i = 0; i < PLL_NUM; i++) {
471 clrbits_be32(&srds2_regs->bank[i].rstctl,
472 SRDS_RSTCTL_SDRST_B);
473 udelay(10);
474 clrbits_be32(&srds2_regs->bank[i].rstctl,
475 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
476 udelay(10);
477 setbits_be32(&srds2_regs->bank[i].rstctl,
478 SRDS_RSTCTL_RST);
479 setbits_be32(&srds2_regs->bank[i].rstctl,
480 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
481 | SRDS_RSTCTL_SDRST_B));
482 }
483 break;
484 default:
485 printf("IDT configuration not supported for:%x S2 Protocol.\n",
486 serdes2_prtcl);
487 }
488
489out:
490 /* Clearing SRDS_RST_MSK bit as now
491 * SerDes reset event can cause a reset request
492 */
493 clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
494 return ret;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530495}
496
York Sunb5b06fb2012-12-23 19:25:27 +0000497int board_early_init_r(void)
498{
499 const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
500 const u8 flash_esel = find_tlb_idx((void *)flashbase, 1);
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530501 int ret;
York Sunb5b06fb2012-12-23 19:25:27 +0000502
503 /*
504 * Remap Boot flash + PROMJET region to caching-inhibited
505 * so that flash can be erased properly.
506 */
507
508 /* Flush d-cache and invalidate i-cache of any FLASH data */
509 flush_dcache();
510 invalidate_icache();
511
512 /* invalidate existing TLB entry for flash + promjet */
513 disable_tlb(flash_esel);
514
515 set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
516 MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
517 0, flash_esel, BOOKE_PAGESZ_256M, 1);
518
519 set_liodns();
520#ifdef CONFIG_SYS_DPAA_QBMAN
521 setup_portals();
522#endif
Shaveta Leekhacb033742013-07-02 14:43:53 +0530523 /* SerDes1 refclks need to be set again, as default clks
524 * are not suitable for CPRI and onboard SGMIIs to work
525 * simultaneously.
526 * This function will set SerDes1's Refclk1 and refclk2
527 * as per SerDes1 protocols
528 */
529 if (config_serdes1_refclks())
530 printf("SerDes1 Refclks couldn't set properly.\n");
531 else
532 printf("SerDes1 Refclks have been set.\n");
York Sunb5b06fb2012-12-23 19:25:27 +0000533
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530534 /* SerDes2 refclks need to be set again, as default clks
535 * are not suitable for PCIe SATA to work
536 * This function will set SerDes2's Refclk1 and refclk2
537 * for SerDes2 protocols having PCIe in them
538 * for PCIe SATA to work
539 */
540 ret = config_serdes2_refclks();
541 if (!ret)
542 printf("SerDes2 Refclks have been set.\n");
543 else if (ret == -ENODEV)
544 printf("SerDes disable, Refclks couldn't change.\n");
545 else
546 printf("SerDes2 Refclk reconfiguring failed.\n");
547
York Sunb5b06fb2012-12-23 19:25:27 +0000548 /* Configure VSC3316 and VSC3308 crossbar switches */
549 if (configure_vsc3316_3308())
550 printf("VSC:failed to configure VSC3316/3308.\n");
551 else
552 printf("VSC:VSC3316/3308 successfully configured.\n");
553
554 select_i2c_ch_pca(I2C_CH_DEFAULT);
555
556 return 0;
557}
558
559unsigned long get_board_sys_clk(void)
560{
561 u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
562
563 switch ((sysclk_conf & 0x0C) >> 2) {
564 case QIXIS_CLK_100:
565 return 100000000;
566 case QIXIS_CLK_125:
567 return 125000000;
568 case QIXIS_CLK_133:
569 return 133333333;
570 }
571 return 66666666;
572}
573
574unsigned long get_board_ddr_clk(void)
575{
576 u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
577
578 switch (ddrclk_conf & 0x03) {
579 case QIXIS_CLK_100:
580 return 100000000;
581 case QIXIS_CLK_125:
582 return 125000000;
583 case QIXIS_CLK_133:
584 return 133333333;
585 }
586 return 66666666;
587}
588
589static int serdes_refclock(u8 sw, u8 sdclk)
590{
591 unsigned int clock;
592 int ret = -1;
593 u8 brdcfg4;
594
595 if (sdclk == 1) {
596 brdcfg4 = QIXIS_READ(brdcfg[4]);
597 if ((brdcfg4 & CLK_MUX_SEL_MASK) == ETH_PHY_CLK_OUT)
598 return SRDS_PLLCR0_RFCK_SEL_125;
599 else
600 clock = (sw >> 5) & 7;
601 } else
602 clock = (sw >> 6) & 3;
603
604 switch (clock) {
605 case 0:
606 ret = SRDS_PLLCR0_RFCK_SEL_100;
607 break;
608 case 1:
609 ret = SRDS_PLLCR0_RFCK_SEL_125;
610 break;
611 case 2:
612 ret = SRDS_PLLCR0_RFCK_SEL_156_25;
613 break;
614 case 3:
615 ret = SRDS_PLLCR0_RFCK_SEL_161_13;
616 break;
617 case 4:
618 case 5:
619 case 6:
620 ret = SRDS_PLLCR0_RFCK_SEL_122_88;
621 break;
622 default:
623 ret = -1;
624 break;
625 }
626
627 return ret;
628}
629
York Sunb5b06fb2012-12-23 19:25:27 +0000630#define NUM_SRDS_BANKS 2
631
632int misc_init_r(void)
633{
634 u8 sw;
635 serdes_corenet_t *srds_regs =
636 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
637 u32 actual[NUM_SRDS_BANKS];
638 unsigned int i;
639 int clock;
640
641 sw = QIXIS_READ(brdcfg[2]);
642 clock = serdes_refclock(sw, 1);
643 if (clock >= 0)
644 actual[0] = clock;
645 else
646 printf("Warning: SDREFCLK1 switch setting is unsupported\n");
647
648 sw = QIXIS_READ(brdcfg[4]);
649 clock = serdes_refclock(sw, 2);
650 if (clock >= 0)
651 actual[1] = clock;
652 else
653 printf("Warning: SDREFCLK2 switch setting unsupported\n");
654
655 for (i = 0; i < NUM_SRDS_BANKS; i++) {
656 u32 pllcr0 = srds_regs->bank[i].pllcr0;
657 u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK;
658 if (expected != actual[i]) {
659 printf("Warning: SERDES bank %u expects reference clock"
660 " %sMHz, but actual is %sMHz\n", i + 1,
661 serdes_clock_to_string(expected),
662 serdes_clock_to_string(actual[i]));
663 }
664 }
665
666 return 0;
667}
668
669void ft_board_setup(void *blob, bd_t *bd)
670{
671 phys_addr_t base;
672 phys_size_t size;
673
674 ft_cpu_setup(blob, bd);
675
676 base = getenv_bootm_low();
677 size = getenv_bootm_size();
678
679 fdt_fixup_memory(blob, (u64)base, (u64)size);
680
681#ifdef CONFIG_PCI
682 pci_of_setup(blob, bd);
683#endif
684
685 fdt_fixup_liodn(blob);
686
687#ifdef CONFIG_HAS_FSL_DR_USB
688 fdt_fixup_dr_usb(blob, bd);
689#endif
690
691#ifdef CONFIG_SYS_DPAA_FMAN
692 fdt_fixup_fman_ethernet(blob);
693 fdt_fixup_board_enet(blob);
694#endif
695}
Shaveta Leekha43548892012-12-23 19:25:42 +0000696
697/*
698 * Dump board switch settings.
699 * The bits that cannot be read/sampled via some FPGA or some
700 * registers, they will be displayed as
701 * underscore in binary format. mask[] has those bits.
702 * Some bits are calculated differently than the actual switches
703 * if booting with overriding by FPGA.
704 */
705void qixis_dump_switch(void)
706{
707 int i;
708 u8 sw[5];
709
710 /*
711 * Any bit with 1 means that bit cannot be reverse engineered.
712 * It will be displayed as _ in binary format.
713 */
714 static const u8 mask[] = {0x07, 0, 0, 0xff, 0};
715 char buf[10];
716 u8 brdcfg[16], dutcfg[16];
717
718 for (i = 0; i < 16; i++) {
719 brdcfg[i] = qixis_read(offsetof(struct qixis, brdcfg[0]) + i);
720 dutcfg[i] = qixis_read(offsetof(struct qixis, dutcfg[0]) + i);
721 }
722
723 sw[0] = ((brdcfg[0] & 0x0f) << 4) | \
724 (brdcfg[9] & 0x08);
725 sw[1] = ((dutcfg[1] & 0x01) << 7) | \
726 ((dutcfg[2] & 0x07) << 4) | \
727 ((dutcfg[6] & 0x10) >> 1) | \
728 ((dutcfg[6] & 0x80) >> 5) | \
729 ((dutcfg[1] & 0x40) >> 5) | \
730 (dutcfg[6] & 0x01);
731 sw[2] = dutcfg[0];
732 sw[3] = 0;
733 sw[4] = ((brdcfg[1] & 0x30) << 2) | \
734 ((brdcfg[1] & 0xc0) >> 2) | \
735 (brdcfg[1] & 0x0f);
736
737 puts("DIP switch settings:\n");
738 for (i = 0; i < 5; i++) {
739 printf("SW%d = 0b%s (0x%02x)\n",
740 i + 1, byte_to_binary_mask(sw[i], mask[i], buf), sw[i]);
741 }
742}