blob: 87dcc10f1a0182b571f01f00f6240c3399af12e6 [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"
Shaveta Leekha652e29b2014-04-11 14:12:40 +053026#include "../common/zm7300.h"
York Sunb5b06fb2012-12-23 19:25:27 +000027#include "b4860qds.h"
28#include "b4860qds_qixis.h"
29#include "b4860qds_crossbar_con.h"
30
31#define CLK_MUX_SEL_MASK 0x4
32#define ETH_PHY_CLK_OUT 0x4
33
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
Shaveta Leekha652e29b2014-04-11 14:12:40 +053098/*
99 * read_voltage from sensor on I2C bus
100 * We use average of 4 readings, waiting for 532us befor another reading
101 */
102#define WAIT_FOR_ADC 532 /* wait for 532 microseconds for ADC */
103#define NUM_READINGS 4 /* prefer to be power of 2 for efficiency */
104
105static inline int read_voltage(void)
106{
107 int i, ret, voltage_read = 0;
108 u16 vol_mon;
109
110 for (i = 0; i < NUM_READINGS; i++) {
111 ret = i2c_read(I2C_VOL_MONITOR_ADDR,
112 I2C_VOL_MONITOR_BUS_V_OFFSET, 1, (void *)&vol_mon, 2);
113 if (ret) {
114 printf("VID: failed to read core voltage\n");
115 return ret;
116 }
117 if (vol_mon & I2C_VOL_MONITOR_BUS_V_OVF) {
118 printf("VID: Core voltage sensor error\n");
119 return -1;
120 }
121 debug("VID: bus voltage reads 0x%04x\n", vol_mon);
122 /* LSB = 4mv */
123 voltage_read += (vol_mon >> I2C_VOL_MONITOR_BUS_V_SHIFT) * 4;
124 udelay(WAIT_FOR_ADC);
125 }
126 /* calculate the average */
127 voltage_read /= NUM_READINGS;
128
129 return voltage_read;
130}
131
132static int adjust_vdd(ulong vdd_override)
133{
134 int re_enable = disable_interrupts();
135 ccsr_gur_t __iomem *gur =
136 (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
137 u32 fusesr;
138 u8 vid;
139 int vdd_target, vdd_last;
140 int existing_voltage, temp_voltage, voltage; /* all in 1/10 mV */
141 int ret;
142 unsigned int orig_i2c_speed;
143 unsigned long vdd_string_override;
144 char *vdd_string;
145 static const uint16_t vdd[32] = {
146 0, /* unused */
147 9875, /* 0.9875V */
148 9750,
149 9625,
150 9500,
151 9375,
152 9250,
153 9125,
154 9000,
155 8875,
156 8750,
157 8625,
158 8500,
159 8375,
160 8250,
161 8125,
162 10000, /* 1.0000V */
163 10125,
164 10250,
165 10375,
166 10500,
167 10625,
168 10750,
169 10875,
170 11000,
171 0, /* reserved */
172 };
173 struct vdd_drive {
174 u8 vid;
175 unsigned voltage;
176 };
177
178 ret = select_i2c_ch_pca(I2C_MUX_CH_VOL_MONITOR);
179 if (ret) {
180 printf("VID: I2c failed to switch channel\n");
181 ret = -1;
182 goto exit;
183 }
184
185 /* get the voltage ID from fuse status register */
186 fusesr = in_be32(&gur->dcfg_fusesr);
187 vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_VID_SHIFT) &
188 FSL_CORENET_DCFG_FUSESR_VID_MASK;
189 if (vid == FSL_CORENET_DCFG_FUSESR_VID_MASK) {
190 vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_ALTVID_SHIFT) &
191 FSL_CORENET_DCFG_FUSESR_ALTVID_MASK;
192 }
193 vdd_target = vdd[vid];
194 debug("VID:Reading from from fuse,vid=%x vdd is %dmV\n",
195 vid, vdd_target/10);
196
197 /* check override variable for overriding VDD */
198 vdd_string = getenv("b4qds_vdd_mv");
199 if (vdd_override == 0 && vdd_string &&
200 !strict_strtoul(vdd_string, 10, &vdd_string_override))
201 vdd_override = vdd_string_override;
202 if (vdd_override >= 819 && vdd_override <= 1212) {
203 vdd_target = vdd_override * 10; /* convert to 1/10 mV */
204 debug("VDD override is %lu\n", vdd_override);
205 } else if (vdd_override != 0) {
206 printf("Invalid value.\n");
207 }
208
209 if (vdd_target == 0) {
210 printf("VID: VID not used\n");
211 ret = 0;
212 goto exit;
213 }
214
215 /*
216 * Read voltage monitor to check real voltage.
217 * Voltage monitor LSB is 4mv.
218 */
219 vdd_last = read_voltage();
220 if (vdd_last < 0) {
221 printf("VID: abort VID adjustment\n");
222 ret = -1;
223 goto exit;
224 }
225
226 debug("VID: Core voltage is at %d mV\n", vdd_last);
227 ret = select_i2c_ch_pca(I2C_MUX_CH_DPM);
228 if (ret) {
229 printf("VID: I2c failed to switch channel to DPM\n");
230 ret = -1;
231 goto exit;
232 }
233
234 /* Round up to the value of step of Voltage regulator */
235 voltage = roundup(vdd_target, ZM_STEP);
236 debug("VID: rounded up voltage = %d\n", voltage);
237
238 /* lower the speed to 100kHz to access ZM7300 device */
239 debug("VID: Setting bus speed to 100KHz if not already set\n");
240 orig_i2c_speed = i2c_get_bus_speed();
241 if (orig_i2c_speed != 100000)
242 i2c_set_bus_speed(100000);
243
244 /* Read the existing level on board, if equal to requsted one,
245 no need to re-set */
246 existing_voltage = zm_read_voltage();
247
248 /* allowing the voltage difference of one step 0.0125V acceptable */
249 if ((existing_voltage >= voltage) &&
250 (existing_voltage < (voltage + ZM_STEP))) {
251 debug("VID: voltage already set as requested,returning\n");
252 ret = existing_voltage;
253 goto out;
254 }
255 debug("VID: Changing voltage for board from %dmV to %dmV\n",
256 existing_voltage/10, voltage/10);
257
258 if (zm_disable_wp() < 0) {
259 ret = -1;
260 goto out;
261 }
262 /* Change Voltage: the change is done through all the steps in the
263 way, to avoid reset to the board due to power good signal fail
264 in big voltage change gap jump.
265 */
266 if (existing_voltage > voltage) {
267 temp_voltage = existing_voltage - ZM_STEP;
268 while (temp_voltage >= voltage) {
269 ret = zm_write_voltage(temp_voltage);
270 if (ret == temp_voltage) {
271 temp_voltage -= ZM_STEP;
272 } else {
273 /* ZM7300 device failed to set
274 * the voltage */
275 printf
276 ("VID:Stepping down vol failed:%dmV\n",
277 temp_voltage/10);
278 ret = -1;
279 goto out;
280 }
281 }
282 } else {
283 temp_voltage = existing_voltage + ZM_STEP;
284 while (temp_voltage < (voltage + ZM_STEP)) {
285 ret = zm_write_voltage(temp_voltage);
286 if (ret == temp_voltage) {
287 temp_voltage += ZM_STEP;
288 } else {
289 /* ZM7300 device failed to set
290 * the voltage */
291 printf
292 ("VID:Stepping up vol failed:%dmV\n",
293 temp_voltage/10);
294 ret = -1;
295 goto out;
296 }
297 }
298 }
299
300 if (zm_enable_wp() < 0)
301 ret = -1;
302
303 /* restore the speed to 400kHz */
304out: debug("VID: Restore the I2C bus speed to %dKHz\n",
305 orig_i2c_speed/1000);
306 i2c_set_bus_speed(orig_i2c_speed);
307 if (ret < 0)
308 goto exit;
309
310 ret = select_i2c_ch_pca(I2C_MUX_CH_VOL_MONITOR);
311 if (ret) {
312 printf("VID: I2c failed to switch channel\n");
313 ret = -1;
314 goto exit;
315 }
316 vdd_last = read_voltage();
317 select_i2c_ch_pca(I2C_CH_DEFAULT);
318
319 if (vdd_last > 0)
320 printf("VID: Core voltage %d mV\n", vdd_last);
321 else
322 ret = -1;
323
324exit:
325 if (re_enable)
326 enable_interrupts();
327 return ret;
328}
329
York Sunb5b06fb2012-12-23 19:25:27 +0000330int configure_vsc3316_3308(void)
331{
332 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
333 unsigned int num_vsc16_con, num_vsc08_con;
334 u32 serdes1_prtcl, serdes2_prtcl;
335 int ret;
336
337 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
338 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
339 if (!serdes1_prtcl) {
340 printf("SERDES1 is not enabled\n");
341 return 0;
342 }
343 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
344 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
345
346 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
347 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
348 if (!serdes2_prtcl) {
349 printf("SERDES2 is not enabled\n");
350 return 0;
351 }
352 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
353 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
354
355 switch (serdes1_prtcl) {
poonam aggrwalc7d506d2014-02-17 08:38:58 +0530356 case 0x29:
York Sunb5b06fb2012-12-23 19:25:27 +0000357 case 0x2a:
358 case 0x2C:
359 case 0x2D:
360 case 0x2E:
361 /*
362 * Configuration:
363 * SERDES: 1
364 * Lanes: A,B: SGMII
365 * Lanes: C,D,E,F,G,H: CPRI
366 */
367 debug("Configuring crossbar to use onboard SGMII PHYs:"
368 "srds_prctl:%x\n", serdes1_prtcl);
369 num_vsc16_con = NUM_CON_VSC3316;
370 /* Configure VSC3316 crossbar switch */
371 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
372 if (!ret) {
373 ret = vsc3316_config(VSC3316_TX_ADDRESS,
Shaveta Leekha0fecbba2013-03-25 07:40:17 +0000374 vsc16_tx_4sfp_sgmii_12_56,
375 num_vsc16_con);
York Sunb5b06fb2012-12-23 19:25:27 +0000376 if (ret)
377 return ret;
378 ret = vsc3316_config(VSC3316_RX_ADDRESS,
Shaveta Leekha0fecbba2013-03-25 07:40:17 +0000379 vsc16_rx_4sfp_sgmii_12_56,
380 num_vsc16_con);
York Sunb5b06fb2012-12-23 19:25:27 +0000381 if (ret)
382 return ret;
383 } else {
384 return ret;
385 }
386 break;
387
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530388 case 0x01:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530389 case 0x02:
390 case 0x04:
391 case 0x05:
392 case 0x06:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530393 case 0x07:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530394 case 0x08:
395 case 0x09:
396 case 0x0A:
397 case 0x0B:
398 case 0x0C:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530399 case 0x2F:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530400 case 0x30:
401 case 0x32:
402 case 0x33:
403 case 0x34:
404 case 0x39:
405 case 0x3A:
406 case 0x3C:
407 case 0x3D:
408 case 0x5C:
409 case 0x5D:
410 /*
411 * Configuration:
412 * SERDES: 1
413 * Lanes: A,B: AURORA
414 * Lanes: C,d: SGMII
415 * Lanes: E,F,G,H: CPRI
416 */
417 debug("Configuring crossbar for Aurora, SGMII 3 and 4,"
418 " and CPRI. srds_prctl:%x\n", serdes1_prtcl);
419 num_vsc16_con = NUM_CON_VSC3316;
420 /* Configure VSC3316 crossbar switch */
421 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
422 if (!ret) {
423 ret = vsc3316_config(VSC3316_TX_ADDRESS,
424 vsc16_tx_sfp_sgmii_aurora,
425 num_vsc16_con);
426 if (ret)
427 return ret;
428 ret = vsc3316_config(VSC3316_RX_ADDRESS,
429 vsc16_rx_sfp_sgmii_aurora,
430 num_vsc16_con);
431 if (ret)
432 return ret;
433 } else {
434 return ret;
435 }
436 break;
437
York Sunb5b06fb2012-12-23 19:25:27 +0000438#ifdef CONFIG_PPC_B4420
poonam aggrwalc7d506d2014-02-17 08:38:58 +0530439 case 0x17:
York Sunb5b06fb2012-12-23 19:25:27 +0000440 case 0x18:
441 /*
442 * Configuration:
443 * SERDES: 1
444 * Lanes: A,B,C,D: SGMII
445 * Lanes: E,F,G,H: CPRI
446 */
447 debug("Configuring crossbar to use onboard SGMII PHYs:"
448 "srds_prctl:%x\n", serdes1_prtcl);
449 num_vsc16_con = NUM_CON_VSC3316;
450 /* Configure VSC3316 crossbar switch */
451 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
452 if (!ret) {
453 ret = vsc3316_config(VSC3316_TX_ADDRESS,
454 vsc16_tx_sgmii_lane_cd, num_vsc16_con);
455 if (ret)
456 return ret;
457 ret = vsc3316_config(VSC3316_RX_ADDRESS,
458 vsc16_rx_sgmii_lane_cd, num_vsc16_con);
459 if (ret)
460 return ret;
461 } else {
462 return ret;
463 }
464 break;
465#endif
466
467 case 0x3E:
468 case 0x0D:
469 case 0x0E:
470 case 0x12:
471 num_vsc16_con = NUM_CON_VSC3316;
472 /* Configure VSC3316 crossbar switch */
473 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
474 if (!ret) {
475 ret = vsc3316_config(VSC3316_TX_ADDRESS,
476 vsc16_tx_sfp, num_vsc16_con);
477 if (ret)
478 return ret;
479 ret = vsc3316_config(VSC3316_RX_ADDRESS,
480 vsc16_rx_sfp, num_vsc16_con);
481 if (ret)
482 return ret;
483 } else {
484 return ret;
485 }
486 break;
487 default:
488 printf("WARNING:VSC crossbars programming not supported for:%x"
489 " SerDes1 Protocol.\n", serdes1_prtcl);
490 return -1;
491 }
492
Shaohui Xie89b94d82014-11-13 11:26:19 +0800493 num_vsc08_con = NUM_CON_VSC3308;
494 /* Configure VSC3308 crossbar switch */
495 ret = select_i2c_ch_pca(I2C_CH_VSC3308);
York Sunb5b06fb2012-12-23 19:25:27 +0000496 switch (serdes2_prtcl) {
poonam aggrwalfa6e7422014-05-31 00:08:18 +0530497#ifdef CONFIG_PPC_B4420
498 case 0x9d:
499#endif
York Sunb5b06fb2012-12-23 19:25:27 +0000500 case 0x9E:
501 case 0x9A:
502 case 0x98:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530503 case 0x48:
York Sunb5b06fb2012-12-23 19:25:27 +0000504 case 0x49:
505 case 0x4E:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530506 case 0x79:
York Sunb5b06fb2012-12-23 19:25:27 +0000507 case 0x7A:
York Sunb5b06fb2012-12-23 19:25:27 +0000508 if (!ret) {
509 ret = vsc3308_config(VSC3308_TX_ADDRESS,
510 vsc08_tx_amc, num_vsc08_con);
511 if (ret)
512 return ret;
513 ret = vsc3308_config(VSC3308_RX_ADDRESS,
514 vsc08_rx_amc, num_vsc08_con);
515 if (ret)
516 return ret;
517 } else {
518 return ret;
519 }
520 break;
Shaohui Xie89b94d82014-11-13 11:26:19 +0800521 case 0x80:
522 case 0x81:
523 case 0x82:
524 case 0x83:
525 case 0x84:
526 case 0x85:
527 case 0x86:
528 case 0x87:
529 case 0x88:
530 case 0x89:
531 case 0x8a:
532 case 0x8b:
533 case 0x8c:
534 case 0x8d:
535 case 0x8e:
536 case 0xb1:
537 case 0xb2:
538 if (!ret) {
539 ret = vsc3308_config(VSC3308_TX_ADDRESS,
540 vsc08_tx_sfp, num_vsc08_con);
541 if (ret)
542 return ret;
543 ret = vsc3308_config(VSC3308_RX_ADDRESS,
544 vsc08_rx_sfp, num_vsc08_con);
545 if (ret)
546 return ret;
547 } else {
548 return ret;
549 }
550 break;
York Sunb5b06fb2012-12-23 19:25:27 +0000551 default:
552 printf("WARNING:VSC crossbars programming not supported for: %x"
553 " SerDes2 Protocol.\n", serdes2_prtcl);
554 return -1;
555 }
556
557 return 0;
558}
559
Shaveta Leekha7af9a072014-02-26 16:08:22 +0530560static int calibrate_pll(serdes_corenet_t *srds_regs, int pll_num)
561{
562 u32 rst_err;
563
564 /* Steps For SerDes PLLs reset and reconfiguration
565 * or PLL power-up procedure
566 */
567 debug("CALIBRATE PLL:%d\n", pll_num);
568 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
569 SRDS_RSTCTL_SDRST_B);
570 udelay(10);
571 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
572 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
573 udelay(10);
574 setbits_be32(&srds_regs->bank[pll_num].rstctl,
575 SRDS_RSTCTL_RST);
576 setbits_be32(&srds_regs->bank[pll_num].rstctl,
577 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
578 | SRDS_RSTCTL_SDRST_B));
579
580 udelay(20);
581
582 /* Check whether PLL has been locked or not */
583 rst_err = in_be32(&srds_regs->bank[pll_num].rstctl) &
584 SRDS_RSTCTL_RSTERR;
585 rst_err >>= SRDS_RSTCTL_RSTERR_SHIFT;
586 debug("RST_ERR value for PLL %d is: 0x%x:\n", pll_num, rst_err);
587 if (rst_err)
588 return rst_err;
589
590 return rst_err;
591}
592
593static int check_pll_locks(serdes_corenet_t *srds_regs, int pll_num)
594{
595 int ret = 0;
596 u32 fcap, dcbias, bcap, pllcr1, pllcr0;
597
598 if (calibrate_pll(srds_regs, pll_num)) {
599 /* STEP 1 */
600 /* Read fcap, dcbias and bcap value */
601 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
602 SRDS_PLLCR0_DCBIAS_OUT_EN);
603 fcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
604 SRDS_PLLSR2_FCAP;
605 fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
606 bcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
607 SRDS_PLLSR2_BCAP_EN;
608 bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
609 setbits_be32(&srds_regs->bank[pll_num].pllcr0,
610 SRDS_PLLCR0_DCBIAS_OUT_EN);
611 dcbias = in_be32(&srds_regs->bank[pll_num].pllsr2) &
612 SRDS_PLLSR2_DCBIAS;
613 dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
614 debug("values of bcap:%x, fcap:%x and dcbias:%x\n",
615 bcap, fcap, dcbias);
616 if (fcap == 0 && bcap == 1) {
617 /* Step 3 */
618 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
619 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
620 | SRDS_RSTCTL_SDRST_B));
621 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
622 SRDS_PLLCR1_BCAP_EN);
623 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
624 SRDS_PLLCR1_BCAP_OVD);
625 if (calibrate_pll(srds_regs, pll_num)) {
626 /*save the fcap, dcbias and bcap values*/
627 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
628 SRDS_PLLCR0_DCBIAS_OUT_EN);
629 fcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
630 & SRDS_PLLSR2_FCAP;
631 fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
632 bcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
633 & SRDS_PLLSR2_BCAP_EN;
634 bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
635 setbits_be32(&srds_regs->bank[pll_num].pllcr0,
636 SRDS_PLLCR0_DCBIAS_OUT_EN);
637 dcbias = in_be32
638 (&srds_regs->bank[pll_num].pllsr2) &
639 SRDS_PLLSR2_DCBIAS;
640 dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
641
642 /* Step 4*/
643 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
644 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
645 | SRDS_RSTCTL_SDRST_B));
646 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
647 SRDS_PLLCR1_BYP_CAL);
648 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
649 SRDS_PLLCR1_BCAP_EN);
650 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
651 SRDS_PLLCR1_BCAP_OVD);
652 /* change the fcap and dcbias to the saved
653 * values from Step 3 */
654 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
655 SRDS_PLLCR1_PLL_FCAP);
656 pllcr1 = (in_be32
657 (&srds_regs->bank[pll_num].pllcr1)|
658 (fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
659 out_be32(&srds_regs->bank[pll_num].pllcr1,
660 pllcr1);
661 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
662 SRDS_PLLCR0_DCBIAS_OVRD);
663 pllcr0 = (in_be32
664 (&srds_regs->bank[pll_num].pllcr0)|
665 (dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
666 out_be32(&srds_regs->bank[pll_num].pllcr0,
667 pllcr0);
668 ret = calibrate_pll(srds_regs, pll_num);
669 if (ret)
670 return ret;
671 } else {
672 goto out;
673 }
674 } else { /* Step 5 */
675 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
676 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
677 | SRDS_RSTCTL_SDRST_B));
678 udelay(10);
679 /* Change the fcap, dcbias, and bcap to the
680 * values from Step 1 */
681 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
682 SRDS_PLLCR1_BYP_CAL);
683 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
684 SRDS_PLLCR1_PLL_FCAP);
685 pllcr1 = (in_be32(&srds_regs->bank[pll_num].pllcr1)|
686 (fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
687 out_be32(&srds_regs->bank[pll_num].pllcr1,
688 pllcr1);
689 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
690 SRDS_PLLCR0_DCBIAS_OVRD);
691 pllcr0 = (in_be32(&srds_regs->bank[pll_num].pllcr0)|
692 (dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
693 out_be32(&srds_regs->bank[pll_num].pllcr0,
694 pllcr0);
695 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
696 SRDS_PLLCR1_BCAP_EN);
697 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
698 SRDS_PLLCR1_BCAP_OVD);
699 ret = calibrate_pll(srds_regs, pll_num);
700 if (ret)
701 return ret;
702 }
703 }
704out:
705 return 0;
706}
707
708static int check_serdes_pll_locks(void)
709{
710 serdes_corenet_t *srds1_regs =
711 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
712 serdes_corenet_t *srds2_regs =
713 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
714 int i, ret1, ret2;
715
716 debug("\nSerDes1 Lock check\n");
717 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
718 ret1 = check_pll_locks(srds1_regs, i);
719 if (ret1) {
720 printf("SerDes1, PLL:%d didnt lock\n", i);
721 return ret1;
722 }
723 }
724 debug("\nSerDes2 Lock check\n");
725 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
726 ret2 = check_pll_locks(srds2_regs, i);
727 if (ret2) {
728 printf("SerDes2, PLL:%d didnt lock\n", i);
729 return ret2;
730 }
731 }
732
733 return 0;
734}
735
Shaveta Leekhacb033742013-07-02 14:43:53 +0530736int config_serdes1_refclks(void)
737{
738 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
739 serdes_corenet_t *srds_regs =
740 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
741 u32 serdes1_prtcl, lane;
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530742 unsigned int flag_sgmii_aurora_prtcl = 0;
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530743 int i;
744 int ret = 0;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530745
746 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
747 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
748 if (!serdes1_prtcl) {
749 printf("SERDES1 is not enabled\n");
750 return -1;
751 }
752 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
753 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
754
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530755 /* To prevent generation of reset request from SerDes
756 * while changing the refclks, By setting SRDS_RST_MSK bit,
757 * SerDes reset event cannot cause a reset request
Shaveta Leekhacb033742013-07-02 14:43:53 +0530758 */
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530759 setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
760
Shaveta Leekhacb033742013-07-02 14:43:53 +0530761 /* Reconfigure IDT idt8t49n222a device for CPRI to work
762 * For this SerDes1's Refclk1 and refclk2 need to be set
763 * to 122.88MHz
764 */
765 switch (serdes1_prtcl) {
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530766 case 0x29:
Shaveta Leekhacb033742013-07-02 14:43:53 +0530767 case 0x2A:
768 case 0x2C:
769 case 0x2D:
770 case 0x2E:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530771 case 0x01:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530772 case 0x02:
773 case 0x04:
774 case 0x05:
775 case 0x06:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530776 case 0x07:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530777 case 0x08:
778 case 0x09:
779 case 0x0A:
780 case 0x0B:
781 case 0x0C:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530782 case 0x2F:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530783 case 0x30:
784 case 0x32:
785 case 0x33:
786 case 0x34:
787 case 0x39:
788 case 0x3A:
789 case 0x3C:
790 case 0x3D:
791 case 0x5C:
792 case 0x5D:
Shaveta Leekhacb033742013-07-02 14:43:53 +0530793 debug("Configuring idt8t49n222a for CPRI SerDes clks:"
794 " for srds_prctl:%x\n", serdes1_prtcl);
795 ret = select_i2c_ch_pca(I2C_CH_IDT);
796 if (!ret) {
797 ret = set_serdes_refclk(IDT_SERDES1_ADDRESS, 1,
798 SERDES_REFCLK_122_88,
799 SERDES_REFCLK_122_88, 0);
800 if (ret) {
801 printf("IDT8T49N222A configuration failed.\n");
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530802 goto out;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530803 } else
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530804 debug("IDT8T49N222A configured.\n");
Shaveta Leekhacb033742013-07-02 14:43:53 +0530805 } else {
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530806 goto out;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530807 }
808 select_i2c_ch_pca(I2C_CH_DEFAULT);
809
810 /* Change SerDes1's Refclk1 to 125MHz for on board
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530811 * SGMIIs or Aurora to work
Shaveta Leekhacb033742013-07-02 14:43:53 +0530812 */
813 for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
814 enum srds_prtcl lane_prtcl = serdes_get_prtcl
815 (0, serdes1_prtcl, lane);
816 switch (lane_prtcl) {
817 case SGMII_FM1_DTSEC1:
818 case SGMII_FM1_DTSEC2:
819 case SGMII_FM1_DTSEC3:
820 case SGMII_FM1_DTSEC4:
821 case SGMII_FM1_DTSEC5:
822 case SGMII_FM1_DTSEC6:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530823 case AURORA:
824 flag_sgmii_aurora_prtcl++;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530825 break;
826 default:
827 break;
828 }
829 }
830
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530831 if (flag_sgmii_aurora_prtcl)
Shaveta Leekhacb033742013-07-02 14:43:53 +0530832 QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
833
834 /* Steps For SerDes PLLs reset and reconfiguration after
835 * changing SerDes's refclks
836 */
Shaveta Leekhac4930b12014-02-26 16:07:51 +0530837 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
Shaveta Leekhacb033742013-07-02 14:43:53 +0530838 debug("For PLL%d reset and reconfiguration after"
839 " changing refclks\n", i+1);
840 clrbits_be32(&srds_regs->bank[i].rstctl,
841 SRDS_RSTCTL_SDRST_B);
842 udelay(10);
843 clrbits_be32(&srds_regs->bank[i].rstctl,
844 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
845 udelay(10);
846 setbits_be32(&srds_regs->bank[i].rstctl,
847 SRDS_RSTCTL_RST);
848 setbits_be32(&srds_regs->bank[i].rstctl,
849 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
850 | SRDS_RSTCTL_SDRST_B));
851 }
852 break;
853 default:
854 printf("WARNING:IDT8T49N222A configuration not"
855 " supported for:%x SerDes1 Protocol.\n",
856 serdes1_prtcl);
Shaveta Leekhacb033742013-07-02 14:43:53 +0530857 }
858
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530859out:
860 /* Clearing SRDS_RST_MSK bit as now
861 * SerDes reset event can cause a reset request
862 */
863 clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
864 return ret;
865}
866
867int config_serdes2_refclks(void)
868{
869 ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
870 serdes_corenet_t *srds2_regs =
871 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
872 u32 serdes2_prtcl;
873 int ret = 0;
874 int i;
875
876 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
877 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
878 if (!serdes2_prtcl) {
879 debug("SERDES2 is not enabled\n");
880 return -ENODEV;
881 }
882 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
883 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
884
885 /* To prevent generation of reset request from SerDes
886 * while changing the refclks, By setting SRDS_RST_MSK bit,
887 * SerDes reset event cannot cause a reset request
888 */
889 setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
890
891 /* Reconfigure IDT idt8t49n222a device for PCIe SATA to work
892 * For this SerDes2's Refclk1 need to be set to 100MHz
893 */
894 switch (serdes2_prtcl) {
poonam aggrwalfa6e7422014-05-31 00:08:18 +0530895#ifdef CONFIG_PPC_B4420
896 case 0x9d:
897#endif
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530898 case 0x9E:
899 case 0x9A:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530900 /* fallthrough */
901 case 0xb1:
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530902 case 0xb2:
903 debug("Configuring IDT for PCIe SATA for srds_prctl:%x\n",
904 serdes2_prtcl);
905 ret = select_i2c_ch_pca(I2C_CH_IDT);
906 if (!ret) {
907 ret = set_serdes_refclk(IDT_SERDES2_ADDRESS, 2,
908 SERDES_REFCLK_100,
Shaveta Leekhac4930b12014-02-26 16:07:51 +0530909 SERDES_REFCLK_156_25, 0);
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530910 if (ret) {
911 printf("IDT8T49N222A configuration failed.\n");
912 goto out;
913 } else
914 debug("IDT8T49N222A configured.\n");
915 } else {
916 goto out;
917 }
918 select_i2c_ch_pca(I2C_CH_DEFAULT);
919
920 /* Steps For SerDes PLLs reset and reconfiguration after
921 * changing SerDes's refclks
922 */
Shaveta Leekhac4930b12014-02-26 16:07:51 +0530923 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530924 clrbits_be32(&srds2_regs->bank[i].rstctl,
925 SRDS_RSTCTL_SDRST_B);
926 udelay(10);
927 clrbits_be32(&srds2_regs->bank[i].rstctl,
928 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
929 udelay(10);
930 setbits_be32(&srds2_regs->bank[i].rstctl,
931 SRDS_RSTCTL_RST);
932 setbits_be32(&srds2_regs->bank[i].rstctl,
933 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
934 | SRDS_RSTCTL_SDRST_B));
Shaveta Leekha7af9a072014-02-26 16:08:22 +0530935
936 udelay(10);
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530937 }
938 break;
939 default:
940 printf("IDT configuration not supported for:%x S2 Protocol.\n",
941 serdes2_prtcl);
942 }
943
944out:
945 /* Clearing SRDS_RST_MSK bit as now
946 * SerDes reset event can cause a reset request
947 */
948 clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
949 return ret;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530950}
951
York Sunb5b06fb2012-12-23 19:25:27 +0000952int board_early_init_r(void)
953{
954 const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
York Sun9d045682014-06-24 21:16:20 -0700955 int flash_esel = find_tlb_idx((void *)flashbase, 1);
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530956 int ret;
Shaveta Leekhaf7c28aa2014-11-12 14:23:26 +0530957 u32 svr = SVR_SOC_VER(get_svr());
958
959 /* Create law for MAPLE only for personalities having MAPLE */
960 if ((svr == SVR_B4860) || (svr == SVR_B4440) ||
961 (svr == SVR_B4420) || (svr == SVR_B4220)) {
962 set_next_law(CONFIG_SYS_MAPLE_MEM_PHYS, LAW_SIZE_16M,
963 LAW_TRGT_IF_MAPLE);
964 }
York Sunb5b06fb2012-12-23 19:25:27 +0000965
966 /*
967 * Remap Boot flash + PROMJET region to caching-inhibited
968 * so that flash can be erased properly.
969 */
970
971 /* Flush d-cache and invalidate i-cache of any FLASH data */
972 flush_dcache();
973 invalidate_icache();
974
York Sun9d045682014-06-24 21:16:20 -0700975 if (flash_esel == -1) {
976 /* very unlikely unless something is messed up */
977 puts("Error: Could not find TLB for FLASH BASE\n");
978 flash_esel = 2; /* give our best effort to continue */
979 } else {
980 /* invalidate existing TLB entry for flash + promjet */
981 disable_tlb(flash_esel);
982 }
York Sunb5b06fb2012-12-23 19:25:27 +0000983
984 set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
985 MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
986 0, flash_esel, BOOKE_PAGESZ_256M, 1);
987
988 set_liodns();
989#ifdef CONFIG_SYS_DPAA_QBMAN
990 setup_portals();
991#endif
Shaveta Leekha652e29b2014-04-11 14:12:40 +0530992 /*
993 * Adjust core voltage according to voltage ID
994 * This function changes I2C mux to channel 2.
995 */
996 if (adjust_vdd(0) < 0)
997 printf("Warning: Adjusting core voltage failed\n");
998
Shaveta Leekhacb033742013-07-02 14:43:53 +0530999 /* SerDes1 refclks need to be set again, as default clks
1000 * are not suitable for CPRI and onboard SGMIIs to work
1001 * simultaneously.
1002 * This function will set SerDes1's Refclk1 and refclk2
1003 * as per SerDes1 protocols
1004 */
1005 if (config_serdes1_refclks())
1006 printf("SerDes1 Refclks couldn't set properly.\n");
1007 else
1008 printf("SerDes1 Refclks have been set.\n");
York Sunb5b06fb2012-12-23 19:25:27 +00001009
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +05301010 /* SerDes2 refclks need to be set again, as default clks
1011 * are not suitable for PCIe SATA to work
1012 * This function will set SerDes2's Refclk1 and refclk2
1013 * for SerDes2 protocols having PCIe in them
1014 * for PCIe SATA to work
1015 */
1016 ret = config_serdes2_refclks();
1017 if (!ret)
1018 printf("SerDes2 Refclks have been set.\n");
1019 else if (ret == -ENODEV)
1020 printf("SerDes disable, Refclks couldn't change.\n");
1021 else
1022 printf("SerDes2 Refclk reconfiguring failed.\n");
1023
Shaveta Leekha7af9a072014-02-26 16:08:22 +05301024#if defined(CONFIG_SYS_FSL_ERRATUM_A006384) || \
1025 defined(CONFIG_SYS_FSL_ERRATUM_A006475)
1026 /* Rechecking the SerDes locks after all SerDes configurations
1027 * are done, As SerDes PLLs may not lock reliably at 5 G VCO
1028 * and at cold temperatures.
1029 * Following sequence ensure the proper locking of SerDes PLLs.
1030 */
1031 if (SVR_MAJ(get_svr()) == 1) {
1032 if (check_serdes_pll_locks())
1033 printf("SerDes plls still not locked properly.\n");
1034 else
1035 printf("SerDes plls have been locked well.\n");
1036 }
1037#endif
1038
York Sunb5b06fb2012-12-23 19:25:27 +00001039 /* Configure VSC3316 and VSC3308 crossbar switches */
1040 if (configure_vsc3316_3308())
1041 printf("VSC:failed to configure VSC3316/3308.\n");
1042 else
1043 printf("VSC:VSC3316/3308 successfully configured.\n");
1044
1045 select_i2c_ch_pca(I2C_CH_DEFAULT);
1046
1047 return 0;
1048}
1049
1050unsigned long get_board_sys_clk(void)
1051{
1052 u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
1053
1054 switch ((sysclk_conf & 0x0C) >> 2) {
1055 case QIXIS_CLK_100:
1056 return 100000000;
1057 case QIXIS_CLK_125:
1058 return 125000000;
1059 case QIXIS_CLK_133:
1060 return 133333333;
1061 }
1062 return 66666666;
1063}
1064
1065unsigned long get_board_ddr_clk(void)
1066{
1067 u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
1068
1069 switch (ddrclk_conf & 0x03) {
1070 case QIXIS_CLK_100:
1071 return 100000000;
1072 case QIXIS_CLK_125:
1073 return 125000000;
1074 case QIXIS_CLK_133:
1075 return 133333333;
1076 }
1077 return 66666666;
1078}
1079
1080static int serdes_refclock(u8 sw, u8 sdclk)
1081{
1082 unsigned int clock;
1083 int ret = -1;
1084 u8 brdcfg4;
1085
1086 if (sdclk == 1) {
1087 brdcfg4 = QIXIS_READ(brdcfg[4]);
1088 if ((brdcfg4 & CLK_MUX_SEL_MASK) == ETH_PHY_CLK_OUT)
1089 return SRDS_PLLCR0_RFCK_SEL_125;
1090 else
1091 clock = (sw >> 5) & 7;
1092 } else
1093 clock = (sw >> 6) & 3;
1094
1095 switch (clock) {
1096 case 0:
1097 ret = SRDS_PLLCR0_RFCK_SEL_100;
1098 break;
1099 case 1:
1100 ret = SRDS_PLLCR0_RFCK_SEL_125;
1101 break;
1102 case 2:
1103 ret = SRDS_PLLCR0_RFCK_SEL_156_25;
1104 break;
1105 case 3:
1106 ret = SRDS_PLLCR0_RFCK_SEL_161_13;
1107 break;
1108 case 4:
1109 case 5:
1110 case 6:
1111 ret = SRDS_PLLCR0_RFCK_SEL_122_88;
1112 break;
1113 default:
1114 ret = -1;
1115 break;
1116 }
1117
1118 return ret;
1119}
1120
York Sunb5b06fb2012-12-23 19:25:27 +00001121#define NUM_SRDS_BANKS 2
1122
1123int misc_init_r(void)
1124{
1125 u8 sw;
1126 serdes_corenet_t *srds_regs =
1127 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
1128 u32 actual[NUM_SRDS_BANKS];
1129 unsigned int i;
1130 int clock;
1131
1132 sw = QIXIS_READ(brdcfg[2]);
1133 clock = serdes_refclock(sw, 1);
1134 if (clock >= 0)
1135 actual[0] = clock;
1136 else
1137 printf("Warning: SDREFCLK1 switch setting is unsupported\n");
1138
1139 sw = QIXIS_READ(brdcfg[4]);
1140 clock = serdes_refclock(sw, 2);
1141 if (clock >= 0)
1142 actual[1] = clock;
1143 else
1144 printf("Warning: SDREFCLK2 switch setting unsupported\n");
1145
1146 for (i = 0; i < NUM_SRDS_BANKS; i++) {
1147 u32 pllcr0 = srds_regs->bank[i].pllcr0;
1148 u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK;
1149 if (expected != actual[i]) {
1150 printf("Warning: SERDES bank %u expects reference clock"
1151 " %sMHz, but actual is %sMHz\n", i + 1,
1152 serdes_clock_to_string(expected),
1153 serdes_clock_to_string(actual[i]));
1154 }
1155 }
1156
1157 return 0;
1158}
1159
Simon Glasse895a4b2014-10-23 18:58:47 -06001160int ft_board_setup(void *blob, bd_t *bd)
York Sunb5b06fb2012-12-23 19:25:27 +00001161{
1162 phys_addr_t base;
1163 phys_size_t size;
1164
1165 ft_cpu_setup(blob, bd);
1166
1167 base = getenv_bootm_low();
1168 size = getenv_bootm_size();
1169
1170 fdt_fixup_memory(blob, (u64)base, (u64)size);
1171
1172#ifdef CONFIG_PCI
1173 pci_of_setup(blob, bd);
1174#endif
1175
1176 fdt_fixup_liodn(blob);
1177
1178#ifdef CONFIG_HAS_FSL_DR_USB
1179 fdt_fixup_dr_usb(blob, bd);
1180#endif
1181
1182#ifdef CONFIG_SYS_DPAA_FMAN
1183 fdt_fixup_fman_ethernet(blob);
1184 fdt_fixup_board_enet(blob);
1185#endif
Simon Glasse895a4b2014-10-23 18:58:47 -06001186
1187 return 0;
York Sunb5b06fb2012-12-23 19:25:27 +00001188}
Shaveta Leekha43548892012-12-23 19:25:42 +00001189
1190/*
1191 * Dump board switch settings.
1192 * The bits that cannot be read/sampled via some FPGA or some
1193 * registers, they will be displayed as
1194 * underscore in binary format. mask[] has those bits.
1195 * Some bits are calculated differently than the actual switches
1196 * if booting with overriding by FPGA.
1197 */
1198void qixis_dump_switch(void)
1199{
1200 int i;
1201 u8 sw[5];
1202
1203 /*
1204 * Any bit with 1 means that bit cannot be reverse engineered.
1205 * It will be displayed as _ in binary format.
1206 */
1207 static const u8 mask[] = {0x07, 0, 0, 0xff, 0};
1208 char buf[10];
1209 u8 brdcfg[16], dutcfg[16];
1210
1211 for (i = 0; i < 16; i++) {
1212 brdcfg[i] = qixis_read(offsetof(struct qixis, brdcfg[0]) + i);
1213 dutcfg[i] = qixis_read(offsetof(struct qixis, dutcfg[0]) + i);
1214 }
1215
1216 sw[0] = ((brdcfg[0] & 0x0f) << 4) | \
1217 (brdcfg[9] & 0x08);
1218 sw[1] = ((dutcfg[1] & 0x01) << 7) | \
1219 ((dutcfg[2] & 0x07) << 4) | \
1220 ((dutcfg[6] & 0x10) >> 1) | \
1221 ((dutcfg[6] & 0x80) >> 5) | \
1222 ((dutcfg[1] & 0x40) >> 5) | \
1223 (dutcfg[6] & 0x01);
1224 sw[2] = dutcfg[0];
1225 sw[3] = 0;
1226 sw[4] = ((brdcfg[1] & 0x30) << 2) | \
1227 ((brdcfg[1] & 0xc0) >> 2) | \
1228 (brdcfg[1] & 0x0f);
1229
1230 puts("DIP switch settings:\n");
1231 for (i = 0; i < 5; i++) {
1232 printf("SW%d = 0b%s (0x%02x)\n",
1233 i + 1, byte_to_binary_mask(sw[i], mask[i], buf), sw[i]);
1234 }
1235}