blob: c99c26680e323df4a9e797b2060666fb587019e6 [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>
Suresh Guptacd79e5f2014-11-13 11:27:32 +080022#include <hwconfig.h>
York Sunb5b06fb2012-12-23 19:25:27 +000023
24#include "../common/qixis.h"
25#include "../common/vsc3316_3308.h"
Shaveta Leekhacb033742013-07-02 14:43:53 +053026#include "../common/idt8t49n222a_serdes_clk.h"
Shaveta Leekha652e29b2014-04-11 14:12:40 +053027#include "../common/zm7300.h"
York Sunb5b06fb2012-12-23 19:25:27 +000028#include "b4860qds.h"
29#include "b4860qds_qixis.h"
30#include "b4860qds_crossbar_con.h"
31
32#define CLK_MUX_SEL_MASK 0x4
33#define ETH_PHY_CLK_OUT 0x4
34
35DECLARE_GLOBAL_DATA_PTR;
36
37int checkboard(void)
38{
39 char buf[64];
40 u8 sw;
Simon Glass67ac13b2012-12-13 20:48:48 +000041 struct cpu_type *cpu = gd->arch.cpu;
York Sunb5b06fb2012-12-23 19:25:27 +000042 static const char *const freq[] = {"100", "125", "156.25", "161.13",
43 "122.88", "122.88", "122.88"};
44 int clock;
45
46 printf("Board: %sQDS, ", cpu->name);
47 printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, ",
48 QIXIS_READ(id), QIXIS_READ(arch));
49
50 sw = QIXIS_READ(brdcfg[0]);
51 sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
52
53 if (sw < 0x8)
54 printf("vBank: %d\n", sw);
55 else if (sw >= 0x8 && sw <= 0xE)
56 puts("NAND\n");
57 else
58 printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
59
60 printf("FPGA: v%d (%s), build %d",
61 (int)QIXIS_READ(scver), qixis_read_tag(buf),
62 (int)qixis_read_minor());
63 /* the timestamp string contains "\n" at the end */
64 printf(" on %s", qixis_read_time(buf));
65
York Sunb5b06fb2012-12-23 19:25:27 +000066 /*
67 * Display the actual SERDES reference clocks as configured by the
68 * dip switches on the board. Note that the SWx registers could
69 * technically be set to force the reference clocks to match the
70 * values that the SERDES expects (or vice versa). For now, however,
71 * we just display both values and hope the user notices when they
72 * don't match.
73 */
74 puts("SERDES Reference Clocks: ");
75 sw = QIXIS_READ(brdcfg[2]);
76 clock = (sw >> 5) & 7;
77 printf("Bank1=%sMHz ", freq[clock]);
78 sw = QIXIS_READ(brdcfg[4]);
79 clock = (sw >> 6) & 3;
80 printf("Bank2=%sMHz\n", freq[clock]);
81
82 return 0;
83}
84
85int select_i2c_ch_pca(u8 ch)
86{
87 int ret;
88
89 /* Selecting proper channel via PCA*/
90 ret = i2c_write(I2C_MUX_PCA_ADDR, 0x0, 1, &ch, 1);
91 if (ret) {
92 printf("PCA: failed to select proper channel.\n");
93 return ret;
94 }
95
96 return 0;
97}
98
Shaveta Leekha652e29b2014-04-11 14:12:40 +053099/*
100 * read_voltage from sensor on I2C bus
101 * We use average of 4 readings, waiting for 532us befor another reading
102 */
103#define WAIT_FOR_ADC 532 /* wait for 532 microseconds for ADC */
104#define NUM_READINGS 4 /* prefer to be power of 2 for efficiency */
105
106static inline int read_voltage(void)
107{
108 int i, ret, voltage_read = 0;
109 u16 vol_mon;
110
111 for (i = 0; i < NUM_READINGS; i++) {
112 ret = i2c_read(I2C_VOL_MONITOR_ADDR,
113 I2C_VOL_MONITOR_BUS_V_OFFSET, 1, (void *)&vol_mon, 2);
114 if (ret) {
115 printf("VID: failed to read core voltage\n");
116 return ret;
117 }
118 if (vol_mon & I2C_VOL_MONITOR_BUS_V_OVF) {
119 printf("VID: Core voltage sensor error\n");
120 return -1;
121 }
122 debug("VID: bus voltage reads 0x%04x\n", vol_mon);
123 /* LSB = 4mv */
124 voltage_read += (vol_mon >> I2C_VOL_MONITOR_BUS_V_SHIFT) * 4;
125 udelay(WAIT_FOR_ADC);
126 }
127 /* calculate the average */
128 voltage_read /= NUM_READINGS;
129
130 return voltage_read;
131}
132
133static int adjust_vdd(ulong vdd_override)
134{
135 int re_enable = disable_interrupts();
136 ccsr_gur_t __iomem *gur =
137 (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
138 u32 fusesr;
139 u8 vid;
140 int vdd_target, vdd_last;
141 int existing_voltage, temp_voltage, voltage; /* all in 1/10 mV */
142 int ret;
143 unsigned int orig_i2c_speed;
144 unsigned long vdd_string_override;
145 char *vdd_string;
146 static const uint16_t vdd[32] = {
147 0, /* unused */
148 9875, /* 0.9875V */
149 9750,
150 9625,
151 9500,
152 9375,
153 9250,
154 9125,
155 9000,
156 8875,
157 8750,
158 8625,
159 8500,
160 8375,
161 8250,
162 8125,
163 10000, /* 1.0000V */
164 10125,
165 10250,
166 10375,
167 10500,
168 10625,
169 10750,
170 10875,
171 11000,
172 0, /* reserved */
173 };
174 struct vdd_drive {
175 u8 vid;
176 unsigned voltage;
177 };
178
179 ret = select_i2c_ch_pca(I2C_MUX_CH_VOL_MONITOR);
180 if (ret) {
181 printf("VID: I2c failed to switch channel\n");
182 ret = -1;
183 goto exit;
184 }
185
186 /* get the voltage ID from fuse status register */
187 fusesr = in_be32(&gur->dcfg_fusesr);
188 vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_VID_SHIFT) &
189 FSL_CORENET_DCFG_FUSESR_VID_MASK;
190 if (vid == FSL_CORENET_DCFG_FUSESR_VID_MASK) {
191 vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_ALTVID_SHIFT) &
192 FSL_CORENET_DCFG_FUSESR_ALTVID_MASK;
193 }
194 vdd_target = vdd[vid];
195 debug("VID:Reading from from fuse,vid=%x vdd is %dmV\n",
196 vid, vdd_target/10);
197
198 /* check override variable for overriding VDD */
199 vdd_string = getenv("b4qds_vdd_mv");
200 if (vdd_override == 0 && vdd_string &&
201 !strict_strtoul(vdd_string, 10, &vdd_string_override))
202 vdd_override = vdd_string_override;
203 if (vdd_override >= 819 && vdd_override <= 1212) {
204 vdd_target = vdd_override * 10; /* convert to 1/10 mV */
205 debug("VDD override is %lu\n", vdd_override);
206 } else if (vdd_override != 0) {
207 printf("Invalid value.\n");
208 }
209
210 if (vdd_target == 0) {
211 printf("VID: VID not used\n");
212 ret = 0;
213 goto exit;
214 }
215
216 /*
217 * Read voltage monitor to check real voltage.
218 * Voltage monitor LSB is 4mv.
219 */
220 vdd_last = read_voltage();
221 if (vdd_last < 0) {
222 printf("VID: abort VID adjustment\n");
223 ret = -1;
224 goto exit;
225 }
226
227 debug("VID: Core voltage is at %d mV\n", vdd_last);
228 ret = select_i2c_ch_pca(I2C_MUX_CH_DPM);
229 if (ret) {
230 printf("VID: I2c failed to switch channel to DPM\n");
231 ret = -1;
232 goto exit;
233 }
234
235 /* Round up to the value of step of Voltage regulator */
236 voltage = roundup(vdd_target, ZM_STEP);
237 debug("VID: rounded up voltage = %d\n", voltage);
238
239 /* lower the speed to 100kHz to access ZM7300 device */
240 debug("VID: Setting bus speed to 100KHz if not already set\n");
241 orig_i2c_speed = i2c_get_bus_speed();
242 if (orig_i2c_speed != 100000)
243 i2c_set_bus_speed(100000);
244
245 /* Read the existing level on board, if equal to requsted one,
246 no need to re-set */
247 existing_voltage = zm_read_voltage();
248
249 /* allowing the voltage difference of one step 0.0125V acceptable */
250 if ((existing_voltage >= voltage) &&
251 (existing_voltage < (voltage + ZM_STEP))) {
252 debug("VID: voltage already set as requested,returning\n");
253 ret = existing_voltage;
254 goto out;
255 }
256 debug("VID: Changing voltage for board from %dmV to %dmV\n",
257 existing_voltage/10, voltage/10);
258
259 if (zm_disable_wp() < 0) {
260 ret = -1;
261 goto out;
262 }
263 /* Change Voltage: the change is done through all the steps in the
264 way, to avoid reset to the board due to power good signal fail
265 in big voltage change gap jump.
266 */
267 if (existing_voltage > voltage) {
268 temp_voltage = existing_voltage - ZM_STEP;
269 while (temp_voltage >= voltage) {
270 ret = zm_write_voltage(temp_voltage);
271 if (ret == temp_voltage) {
272 temp_voltage -= ZM_STEP;
273 } else {
274 /* ZM7300 device failed to set
275 * the voltage */
276 printf
277 ("VID:Stepping down vol failed:%dmV\n",
278 temp_voltage/10);
279 ret = -1;
280 goto out;
281 }
282 }
283 } else {
284 temp_voltage = existing_voltage + ZM_STEP;
285 while (temp_voltage < (voltage + ZM_STEP)) {
286 ret = zm_write_voltage(temp_voltage);
287 if (ret == temp_voltage) {
288 temp_voltage += ZM_STEP;
289 } else {
290 /* ZM7300 device failed to set
291 * the voltage */
292 printf
293 ("VID:Stepping up vol failed:%dmV\n",
294 temp_voltage/10);
295 ret = -1;
296 goto out;
297 }
298 }
299 }
300
301 if (zm_enable_wp() < 0)
302 ret = -1;
303
304 /* restore the speed to 400kHz */
305out: debug("VID: Restore the I2C bus speed to %dKHz\n",
306 orig_i2c_speed/1000);
307 i2c_set_bus_speed(orig_i2c_speed);
308 if (ret < 0)
309 goto exit;
310
311 ret = select_i2c_ch_pca(I2C_MUX_CH_VOL_MONITOR);
312 if (ret) {
313 printf("VID: I2c failed to switch channel\n");
314 ret = -1;
315 goto exit;
316 }
317 vdd_last = read_voltage();
318 select_i2c_ch_pca(I2C_CH_DEFAULT);
319
320 if (vdd_last > 0)
321 printf("VID: Core voltage %d mV\n", vdd_last);
322 else
323 ret = -1;
324
325exit:
326 if (re_enable)
327 enable_interrupts();
328 return ret;
329}
330
York Sunb5b06fb2012-12-23 19:25:27 +0000331int configure_vsc3316_3308(void)
332{
333 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
334 unsigned int num_vsc16_con, num_vsc08_con;
335 u32 serdes1_prtcl, serdes2_prtcl;
336 int ret;
Suresh Guptacd79e5f2014-11-13 11:27:32 +0800337 char buffer[HWCONFIG_BUFFER_SIZE];
338 char *buf = NULL;
York Sunb5b06fb2012-12-23 19:25:27 +0000339
340 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
341 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
342 if (!serdes1_prtcl) {
343 printf("SERDES1 is not enabled\n");
344 return 0;
345 }
346 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
347 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
348
349 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
350 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
351 if (!serdes2_prtcl) {
352 printf("SERDES2 is not enabled\n");
353 return 0;
354 }
355 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
356 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
357
358 switch (serdes1_prtcl) {
poonam aggrwalc7d506d2014-02-17 08:38:58 +0530359 case 0x29:
York Sunb5b06fb2012-12-23 19:25:27 +0000360 case 0x2a:
361 case 0x2C:
362 case 0x2D:
363 case 0x2E:
364 /*
365 * Configuration:
366 * SERDES: 1
367 * Lanes: A,B: SGMII
368 * Lanes: C,D,E,F,G,H: CPRI
369 */
370 debug("Configuring crossbar to use onboard SGMII PHYs:"
371 "srds_prctl:%x\n", serdes1_prtcl);
372 num_vsc16_con = NUM_CON_VSC3316;
373 /* Configure VSC3316 crossbar switch */
374 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
375 if (!ret) {
376 ret = vsc3316_config(VSC3316_TX_ADDRESS,
Shaveta Leekha0fecbba2013-03-25 07:40:17 +0000377 vsc16_tx_4sfp_sgmii_12_56,
378 num_vsc16_con);
York Sunb5b06fb2012-12-23 19:25:27 +0000379 if (ret)
380 return ret;
381 ret = vsc3316_config(VSC3316_RX_ADDRESS,
Shaveta Leekha0fecbba2013-03-25 07:40:17 +0000382 vsc16_rx_4sfp_sgmii_12_56,
383 num_vsc16_con);
York Sunb5b06fb2012-12-23 19:25:27 +0000384 if (ret)
385 return ret;
386 } else {
387 return ret;
388 }
389 break;
390
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530391 case 0x01:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530392 case 0x02:
393 case 0x04:
394 case 0x05:
395 case 0x06:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530396 case 0x07:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530397 case 0x08:
398 case 0x09:
399 case 0x0A:
400 case 0x0B:
401 case 0x0C:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530402 case 0x2F:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530403 case 0x30:
404 case 0x32:
405 case 0x33:
406 case 0x34:
407 case 0x39:
408 case 0x3A:
409 case 0x3C:
410 case 0x3D:
411 case 0x5C:
412 case 0x5D:
413 /*
414 * Configuration:
415 * SERDES: 1
416 * Lanes: A,B: AURORA
417 * Lanes: C,d: SGMII
418 * Lanes: E,F,G,H: CPRI
419 */
420 debug("Configuring crossbar for Aurora, SGMII 3 and 4,"
421 " and CPRI. srds_prctl:%x\n", serdes1_prtcl);
422 num_vsc16_con = NUM_CON_VSC3316;
423 /* Configure VSC3316 crossbar switch */
424 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
425 if (!ret) {
426 ret = vsc3316_config(VSC3316_TX_ADDRESS,
427 vsc16_tx_sfp_sgmii_aurora,
428 num_vsc16_con);
429 if (ret)
430 return ret;
431 ret = vsc3316_config(VSC3316_RX_ADDRESS,
432 vsc16_rx_sfp_sgmii_aurora,
433 num_vsc16_con);
434 if (ret)
435 return ret;
436 } else {
437 return ret;
438 }
439 break;
440
York Sunb5b06fb2012-12-23 19:25:27 +0000441#ifdef CONFIG_PPC_B4420
poonam aggrwalc7d506d2014-02-17 08:38:58 +0530442 case 0x17:
York Sunb5b06fb2012-12-23 19:25:27 +0000443 case 0x18:
444 /*
445 * Configuration:
446 * SERDES: 1
447 * Lanes: A,B,C,D: SGMII
448 * Lanes: E,F,G,H: CPRI
449 */
450 debug("Configuring crossbar to use onboard SGMII PHYs:"
451 "srds_prctl:%x\n", serdes1_prtcl);
452 num_vsc16_con = NUM_CON_VSC3316;
453 /* Configure VSC3316 crossbar switch */
454 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
455 if (!ret) {
456 ret = vsc3316_config(VSC3316_TX_ADDRESS,
457 vsc16_tx_sgmii_lane_cd, num_vsc16_con);
458 if (ret)
459 return ret;
460 ret = vsc3316_config(VSC3316_RX_ADDRESS,
461 vsc16_rx_sgmii_lane_cd, num_vsc16_con);
462 if (ret)
463 return ret;
464 } else {
465 return ret;
466 }
467 break;
468#endif
469
470 case 0x3E:
471 case 0x0D:
472 case 0x0E:
473 case 0x12:
474 num_vsc16_con = NUM_CON_VSC3316;
475 /* Configure VSC3316 crossbar switch */
476 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
477 if (!ret) {
478 ret = vsc3316_config(VSC3316_TX_ADDRESS,
479 vsc16_tx_sfp, num_vsc16_con);
480 if (ret)
481 return ret;
482 ret = vsc3316_config(VSC3316_RX_ADDRESS,
483 vsc16_rx_sfp, num_vsc16_con);
484 if (ret)
485 return ret;
486 } else {
487 return ret;
488 }
489 break;
490 default:
491 printf("WARNING:VSC crossbars programming not supported for:%x"
492 " SerDes1 Protocol.\n", serdes1_prtcl);
493 return -1;
494 }
495
Shaohui Xie89b94d82014-11-13 11:26:19 +0800496 num_vsc08_con = NUM_CON_VSC3308;
497 /* Configure VSC3308 crossbar switch */
498 ret = select_i2c_ch_pca(I2C_CH_VSC3308);
York Sunb5b06fb2012-12-23 19:25:27 +0000499 switch (serdes2_prtcl) {
poonam aggrwalfa6e7422014-05-31 00:08:18 +0530500#ifdef CONFIG_PPC_B4420
501 case 0x9d:
502#endif
York Sunb5b06fb2012-12-23 19:25:27 +0000503 case 0x9E:
504 case 0x9A:
505 case 0x98:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530506 case 0x48:
York Sunb5b06fb2012-12-23 19:25:27 +0000507 case 0x49:
508 case 0x4E:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530509 case 0x79:
York Sunb5b06fb2012-12-23 19:25:27 +0000510 case 0x7A:
York Sunb5b06fb2012-12-23 19:25:27 +0000511 if (!ret) {
512 ret = vsc3308_config(VSC3308_TX_ADDRESS,
513 vsc08_tx_amc, num_vsc08_con);
514 if (ret)
515 return ret;
516 ret = vsc3308_config(VSC3308_RX_ADDRESS,
517 vsc08_rx_amc, num_vsc08_con);
518 if (ret)
519 return ret;
520 } else {
521 return ret;
522 }
523 break;
Shaohui Xie89b94d82014-11-13 11:26:19 +0800524 case 0x80:
525 case 0x81:
526 case 0x82:
527 case 0x83:
528 case 0x84:
529 case 0x85:
530 case 0x86:
531 case 0x87:
532 case 0x88:
533 case 0x89:
534 case 0x8a:
535 case 0x8b:
536 case 0x8c:
537 case 0x8d:
538 case 0x8e:
539 case 0xb1:
540 case 0xb2:
541 if (!ret) {
Suresh Guptacd79e5f2014-11-13 11:27:32 +0800542 /*
543 * Extract hwconfig from environment since environment
544 * is not setup properly yet
545 */
546 getenv_f("hwconfig", buffer, sizeof(buffer));
547 buf = buffer;
548
549 if (hwconfig_subarg_cmp_f("fsl_b4860_serdes2",
550 "sfp_amc", "sfp", buf)) {
551 ret = vsc3308_config(VSC3308_TX_ADDRESS,
552 vsc08_tx_sfp, num_vsc08_con);
553 if (ret)
554 return ret;
555
556 ret = vsc3308_config(VSC3308_RX_ADDRESS,
557 vsc08_rx_sfp, num_vsc08_con);
558 if (ret)
559 return ret;
560 } else {
561 ret = vsc3308_config(VSC3308_TX_ADDRESS,
562 vsc08_tx_amc, num_vsc08_con);
563 if (ret)
564 return ret;
565
566 ret = vsc3308_config(VSC3308_RX_ADDRESS,
567 vsc08_rx_amc, num_vsc08_con);
568 if (ret)
569 return ret;
570 }
571
Shaohui Xie89b94d82014-11-13 11:26:19 +0800572 } else {
573 return ret;
574 }
575 break;
York Sunb5b06fb2012-12-23 19:25:27 +0000576 default:
577 printf("WARNING:VSC crossbars programming not supported for: %x"
578 " SerDes2 Protocol.\n", serdes2_prtcl);
579 return -1;
580 }
581
582 return 0;
583}
584
Shaveta Leekha7af9a072014-02-26 16:08:22 +0530585static int calibrate_pll(serdes_corenet_t *srds_regs, int pll_num)
586{
587 u32 rst_err;
588
589 /* Steps For SerDes PLLs reset and reconfiguration
590 * or PLL power-up procedure
591 */
592 debug("CALIBRATE PLL:%d\n", pll_num);
593 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
594 SRDS_RSTCTL_SDRST_B);
595 udelay(10);
596 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
597 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
598 udelay(10);
599 setbits_be32(&srds_regs->bank[pll_num].rstctl,
600 SRDS_RSTCTL_RST);
601 setbits_be32(&srds_regs->bank[pll_num].rstctl,
602 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
603 | SRDS_RSTCTL_SDRST_B));
604
605 udelay(20);
606
607 /* Check whether PLL has been locked or not */
608 rst_err = in_be32(&srds_regs->bank[pll_num].rstctl) &
609 SRDS_RSTCTL_RSTERR;
610 rst_err >>= SRDS_RSTCTL_RSTERR_SHIFT;
611 debug("RST_ERR value for PLL %d is: 0x%x:\n", pll_num, rst_err);
612 if (rst_err)
613 return rst_err;
614
615 return rst_err;
616}
617
618static int check_pll_locks(serdes_corenet_t *srds_regs, int pll_num)
619{
620 int ret = 0;
621 u32 fcap, dcbias, bcap, pllcr1, pllcr0;
622
623 if (calibrate_pll(srds_regs, pll_num)) {
624 /* STEP 1 */
625 /* Read fcap, dcbias and bcap value */
626 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
627 SRDS_PLLCR0_DCBIAS_OUT_EN);
628 fcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
629 SRDS_PLLSR2_FCAP;
630 fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
631 bcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
632 SRDS_PLLSR2_BCAP_EN;
633 bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
634 setbits_be32(&srds_regs->bank[pll_num].pllcr0,
635 SRDS_PLLCR0_DCBIAS_OUT_EN);
636 dcbias = in_be32(&srds_regs->bank[pll_num].pllsr2) &
637 SRDS_PLLSR2_DCBIAS;
638 dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
639 debug("values of bcap:%x, fcap:%x and dcbias:%x\n",
640 bcap, fcap, dcbias);
641 if (fcap == 0 && bcap == 1) {
642 /* Step 3 */
643 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
644 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
645 | SRDS_RSTCTL_SDRST_B));
646 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
647 SRDS_PLLCR1_BCAP_EN);
648 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
649 SRDS_PLLCR1_BCAP_OVD);
650 if (calibrate_pll(srds_regs, pll_num)) {
651 /*save the fcap, dcbias and bcap values*/
652 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
653 SRDS_PLLCR0_DCBIAS_OUT_EN);
654 fcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
655 & SRDS_PLLSR2_FCAP;
656 fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
657 bcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
658 & SRDS_PLLSR2_BCAP_EN;
659 bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
660 setbits_be32(&srds_regs->bank[pll_num].pllcr0,
661 SRDS_PLLCR0_DCBIAS_OUT_EN);
662 dcbias = in_be32
663 (&srds_regs->bank[pll_num].pllsr2) &
664 SRDS_PLLSR2_DCBIAS;
665 dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
666
667 /* Step 4*/
668 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
669 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
670 | SRDS_RSTCTL_SDRST_B));
671 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
672 SRDS_PLLCR1_BYP_CAL);
673 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
674 SRDS_PLLCR1_BCAP_EN);
675 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
676 SRDS_PLLCR1_BCAP_OVD);
677 /* change the fcap and dcbias to the saved
678 * values from Step 3 */
679 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
680 SRDS_PLLCR1_PLL_FCAP);
681 pllcr1 = (in_be32
682 (&srds_regs->bank[pll_num].pllcr1)|
683 (fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
684 out_be32(&srds_regs->bank[pll_num].pllcr1,
685 pllcr1);
686 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
687 SRDS_PLLCR0_DCBIAS_OVRD);
688 pllcr0 = (in_be32
689 (&srds_regs->bank[pll_num].pllcr0)|
690 (dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
691 out_be32(&srds_regs->bank[pll_num].pllcr0,
692 pllcr0);
693 ret = calibrate_pll(srds_regs, pll_num);
694 if (ret)
695 return ret;
696 } else {
697 goto out;
698 }
699 } else { /* Step 5 */
700 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
701 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
702 | SRDS_RSTCTL_SDRST_B));
703 udelay(10);
704 /* Change the fcap, dcbias, and bcap to the
705 * values from Step 1 */
706 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
707 SRDS_PLLCR1_BYP_CAL);
708 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
709 SRDS_PLLCR1_PLL_FCAP);
710 pllcr1 = (in_be32(&srds_regs->bank[pll_num].pllcr1)|
711 (fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
712 out_be32(&srds_regs->bank[pll_num].pllcr1,
713 pllcr1);
714 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
715 SRDS_PLLCR0_DCBIAS_OVRD);
716 pllcr0 = (in_be32(&srds_regs->bank[pll_num].pllcr0)|
717 (dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
718 out_be32(&srds_regs->bank[pll_num].pllcr0,
719 pllcr0);
720 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
721 SRDS_PLLCR1_BCAP_EN);
722 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
723 SRDS_PLLCR1_BCAP_OVD);
724 ret = calibrate_pll(srds_regs, pll_num);
725 if (ret)
726 return ret;
727 }
728 }
729out:
730 return 0;
731}
732
733static int check_serdes_pll_locks(void)
734{
735 serdes_corenet_t *srds1_regs =
736 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
737 serdes_corenet_t *srds2_regs =
738 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
739 int i, ret1, ret2;
740
741 debug("\nSerDes1 Lock check\n");
742 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
743 ret1 = check_pll_locks(srds1_regs, i);
744 if (ret1) {
745 printf("SerDes1, PLL:%d didnt lock\n", i);
746 return ret1;
747 }
748 }
749 debug("\nSerDes2 Lock check\n");
750 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
751 ret2 = check_pll_locks(srds2_regs, i);
752 if (ret2) {
753 printf("SerDes2, PLL:%d didnt lock\n", i);
754 return ret2;
755 }
756 }
757
758 return 0;
759}
760
Shaveta Leekhacb033742013-07-02 14:43:53 +0530761int config_serdes1_refclks(void)
762{
763 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
764 serdes_corenet_t *srds_regs =
765 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
766 u32 serdes1_prtcl, lane;
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530767 unsigned int flag_sgmii_aurora_prtcl = 0;
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530768 int i;
769 int ret = 0;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530770
771 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
772 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
773 if (!serdes1_prtcl) {
774 printf("SERDES1 is not enabled\n");
775 return -1;
776 }
777 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
778 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
779
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530780 /* To prevent generation of reset request from SerDes
781 * while changing the refclks, By setting SRDS_RST_MSK bit,
782 * SerDes reset event cannot cause a reset request
Shaveta Leekhacb033742013-07-02 14:43:53 +0530783 */
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530784 setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
785
Shaveta Leekhacb033742013-07-02 14:43:53 +0530786 /* Reconfigure IDT idt8t49n222a device for CPRI to work
787 * For this SerDes1's Refclk1 and refclk2 need to be set
788 * to 122.88MHz
789 */
790 switch (serdes1_prtcl) {
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530791 case 0x29:
Shaveta Leekhacb033742013-07-02 14:43:53 +0530792 case 0x2A:
793 case 0x2C:
794 case 0x2D:
795 case 0x2E:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530796 case 0x01:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530797 case 0x02:
798 case 0x04:
799 case 0x05:
800 case 0x06:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530801 case 0x07:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530802 case 0x08:
803 case 0x09:
804 case 0x0A:
805 case 0x0B:
806 case 0x0C:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530807 case 0x2F:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530808 case 0x30:
809 case 0x32:
810 case 0x33:
811 case 0x34:
812 case 0x39:
813 case 0x3A:
814 case 0x3C:
815 case 0x3D:
816 case 0x5C:
817 case 0x5D:
Shaveta Leekhacb033742013-07-02 14:43:53 +0530818 debug("Configuring idt8t49n222a for CPRI SerDes clks:"
819 " for srds_prctl:%x\n", serdes1_prtcl);
820 ret = select_i2c_ch_pca(I2C_CH_IDT);
821 if (!ret) {
822 ret = set_serdes_refclk(IDT_SERDES1_ADDRESS, 1,
823 SERDES_REFCLK_122_88,
824 SERDES_REFCLK_122_88, 0);
825 if (ret) {
826 printf("IDT8T49N222A configuration failed.\n");
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530827 goto out;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530828 } else
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530829 debug("IDT8T49N222A configured.\n");
Shaveta Leekhacb033742013-07-02 14:43:53 +0530830 } else {
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530831 goto out;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530832 }
833 select_i2c_ch_pca(I2C_CH_DEFAULT);
834
835 /* Change SerDes1's Refclk1 to 125MHz for on board
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530836 * SGMIIs or Aurora to work
Shaveta Leekhacb033742013-07-02 14:43:53 +0530837 */
838 for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
839 enum srds_prtcl lane_prtcl = serdes_get_prtcl
840 (0, serdes1_prtcl, lane);
841 switch (lane_prtcl) {
842 case SGMII_FM1_DTSEC1:
843 case SGMII_FM1_DTSEC2:
844 case SGMII_FM1_DTSEC3:
845 case SGMII_FM1_DTSEC4:
846 case SGMII_FM1_DTSEC5:
847 case SGMII_FM1_DTSEC6:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530848 case AURORA:
849 flag_sgmii_aurora_prtcl++;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530850 break;
851 default:
852 break;
853 }
854 }
855
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530856 if (flag_sgmii_aurora_prtcl)
Shaveta Leekhacb033742013-07-02 14:43:53 +0530857 QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
858
859 /* Steps For SerDes PLLs reset and reconfiguration after
860 * changing SerDes's refclks
861 */
Shaveta Leekhac4930b12014-02-26 16:07:51 +0530862 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
Shaveta Leekhacb033742013-07-02 14:43:53 +0530863 debug("For PLL%d reset and reconfiguration after"
864 " changing refclks\n", i+1);
865 clrbits_be32(&srds_regs->bank[i].rstctl,
866 SRDS_RSTCTL_SDRST_B);
867 udelay(10);
868 clrbits_be32(&srds_regs->bank[i].rstctl,
869 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
870 udelay(10);
871 setbits_be32(&srds_regs->bank[i].rstctl,
872 SRDS_RSTCTL_RST);
873 setbits_be32(&srds_regs->bank[i].rstctl,
874 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
875 | SRDS_RSTCTL_SDRST_B));
876 }
877 break;
878 default:
879 printf("WARNING:IDT8T49N222A configuration not"
880 " supported for:%x SerDes1 Protocol.\n",
881 serdes1_prtcl);
Shaveta Leekhacb033742013-07-02 14:43:53 +0530882 }
883
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530884out:
885 /* Clearing SRDS_RST_MSK bit as now
886 * SerDes reset event can cause a reset request
887 */
888 clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
889 return ret;
890}
891
892int config_serdes2_refclks(void)
893{
894 ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
895 serdes_corenet_t *srds2_regs =
896 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
897 u32 serdes2_prtcl;
898 int ret = 0;
899 int i;
900
901 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
902 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
903 if (!serdes2_prtcl) {
904 debug("SERDES2 is not enabled\n");
905 return -ENODEV;
906 }
907 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
908 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
909
910 /* To prevent generation of reset request from SerDes
911 * while changing the refclks, By setting SRDS_RST_MSK bit,
912 * SerDes reset event cannot cause a reset request
913 */
914 setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
915
916 /* Reconfigure IDT idt8t49n222a device for PCIe SATA to work
917 * For this SerDes2's Refclk1 need to be set to 100MHz
918 */
919 switch (serdes2_prtcl) {
poonam aggrwalfa6e7422014-05-31 00:08:18 +0530920#ifdef CONFIG_PPC_B4420
921 case 0x9d:
922#endif
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530923 case 0x9E:
924 case 0x9A:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530925 /* fallthrough */
926 case 0xb1:
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530927 case 0xb2:
928 debug("Configuring IDT for PCIe SATA for srds_prctl:%x\n",
929 serdes2_prtcl);
930 ret = select_i2c_ch_pca(I2C_CH_IDT);
931 if (!ret) {
932 ret = set_serdes_refclk(IDT_SERDES2_ADDRESS, 2,
933 SERDES_REFCLK_100,
Shaveta Leekhac4930b12014-02-26 16:07:51 +0530934 SERDES_REFCLK_156_25, 0);
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530935 if (ret) {
936 printf("IDT8T49N222A configuration failed.\n");
937 goto out;
938 } else
939 debug("IDT8T49N222A configured.\n");
940 } else {
941 goto out;
942 }
943 select_i2c_ch_pca(I2C_CH_DEFAULT);
944
945 /* Steps For SerDes PLLs reset and reconfiguration after
946 * changing SerDes's refclks
947 */
Shaveta Leekhac4930b12014-02-26 16:07:51 +0530948 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530949 clrbits_be32(&srds2_regs->bank[i].rstctl,
950 SRDS_RSTCTL_SDRST_B);
951 udelay(10);
952 clrbits_be32(&srds2_regs->bank[i].rstctl,
953 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
954 udelay(10);
955 setbits_be32(&srds2_regs->bank[i].rstctl,
956 SRDS_RSTCTL_RST);
957 setbits_be32(&srds2_regs->bank[i].rstctl,
958 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
959 | SRDS_RSTCTL_SDRST_B));
Shaveta Leekha7af9a072014-02-26 16:08:22 +0530960
961 udelay(10);
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530962 }
963 break;
964 default:
965 printf("IDT configuration not supported for:%x S2 Protocol.\n",
966 serdes2_prtcl);
967 }
968
969out:
970 /* Clearing SRDS_RST_MSK bit as now
971 * SerDes reset event can cause a reset request
972 */
973 clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
974 return ret;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530975}
976
York Sunb5b06fb2012-12-23 19:25:27 +0000977int board_early_init_r(void)
978{
979 const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
York Sun9d045682014-06-24 21:16:20 -0700980 int flash_esel = find_tlb_idx((void *)flashbase, 1);
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530981 int ret;
Shaveta Leekhaf7c28aa2014-11-12 14:23:26 +0530982 u32 svr = SVR_SOC_VER(get_svr());
983
984 /* Create law for MAPLE only for personalities having MAPLE */
985 if ((svr == SVR_B4860) || (svr == SVR_B4440) ||
986 (svr == SVR_B4420) || (svr == SVR_B4220)) {
987 set_next_law(CONFIG_SYS_MAPLE_MEM_PHYS, LAW_SIZE_16M,
988 LAW_TRGT_IF_MAPLE);
989 }
York Sunb5b06fb2012-12-23 19:25:27 +0000990
991 /*
992 * Remap Boot flash + PROMJET region to caching-inhibited
993 * so that flash can be erased properly.
994 */
995
996 /* Flush d-cache and invalidate i-cache of any FLASH data */
997 flush_dcache();
998 invalidate_icache();
999
York Sun9d045682014-06-24 21:16:20 -07001000 if (flash_esel == -1) {
1001 /* very unlikely unless something is messed up */
1002 puts("Error: Could not find TLB for FLASH BASE\n");
1003 flash_esel = 2; /* give our best effort to continue */
1004 } else {
1005 /* invalidate existing TLB entry for flash + promjet */
1006 disable_tlb(flash_esel);
1007 }
York Sunb5b06fb2012-12-23 19:25:27 +00001008
1009 set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
1010 MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
1011 0, flash_esel, BOOKE_PAGESZ_256M, 1);
1012
1013 set_liodns();
1014#ifdef CONFIG_SYS_DPAA_QBMAN
1015 setup_portals();
1016#endif
Shaveta Leekha652e29b2014-04-11 14:12:40 +05301017 /*
1018 * Adjust core voltage according to voltage ID
1019 * This function changes I2C mux to channel 2.
1020 */
1021 if (adjust_vdd(0) < 0)
1022 printf("Warning: Adjusting core voltage failed\n");
1023
Shaveta Leekhacb033742013-07-02 14:43:53 +05301024 /* SerDes1 refclks need to be set again, as default clks
1025 * are not suitable for CPRI and onboard SGMIIs to work
1026 * simultaneously.
1027 * This function will set SerDes1's Refclk1 and refclk2
1028 * as per SerDes1 protocols
1029 */
1030 if (config_serdes1_refclks())
1031 printf("SerDes1 Refclks couldn't set properly.\n");
1032 else
1033 printf("SerDes1 Refclks have been set.\n");
York Sunb5b06fb2012-12-23 19:25:27 +00001034
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +05301035 /* SerDes2 refclks need to be set again, as default clks
1036 * are not suitable for PCIe SATA to work
1037 * This function will set SerDes2's Refclk1 and refclk2
1038 * for SerDes2 protocols having PCIe in them
1039 * for PCIe SATA to work
1040 */
1041 ret = config_serdes2_refclks();
1042 if (!ret)
1043 printf("SerDes2 Refclks have been set.\n");
1044 else if (ret == -ENODEV)
1045 printf("SerDes disable, Refclks couldn't change.\n");
1046 else
1047 printf("SerDes2 Refclk reconfiguring failed.\n");
1048
Shaveta Leekha7af9a072014-02-26 16:08:22 +05301049#if defined(CONFIG_SYS_FSL_ERRATUM_A006384) || \
1050 defined(CONFIG_SYS_FSL_ERRATUM_A006475)
1051 /* Rechecking the SerDes locks after all SerDes configurations
1052 * are done, As SerDes PLLs may not lock reliably at 5 G VCO
1053 * and at cold temperatures.
1054 * Following sequence ensure the proper locking of SerDes PLLs.
1055 */
1056 if (SVR_MAJ(get_svr()) == 1) {
1057 if (check_serdes_pll_locks())
1058 printf("SerDes plls still not locked properly.\n");
1059 else
1060 printf("SerDes plls have been locked well.\n");
1061 }
1062#endif
1063
York Sunb5b06fb2012-12-23 19:25:27 +00001064 /* Configure VSC3316 and VSC3308 crossbar switches */
1065 if (configure_vsc3316_3308())
1066 printf("VSC:failed to configure VSC3316/3308.\n");
1067 else
1068 printf("VSC:VSC3316/3308 successfully configured.\n");
1069
1070 select_i2c_ch_pca(I2C_CH_DEFAULT);
1071
1072 return 0;
1073}
1074
1075unsigned long get_board_sys_clk(void)
1076{
1077 u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
1078
1079 switch ((sysclk_conf & 0x0C) >> 2) {
1080 case QIXIS_CLK_100:
1081 return 100000000;
1082 case QIXIS_CLK_125:
1083 return 125000000;
1084 case QIXIS_CLK_133:
1085 return 133333333;
1086 }
1087 return 66666666;
1088}
1089
1090unsigned long get_board_ddr_clk(void)
1091{
1092 u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
1093
1094 switch (ddrclk_conf & 0x03) {
1095 case QIXIS_CLK_100:
1096 return 100000000;
1097 case QIXIS_CLK_125:
1098 return 125000000;
1099 case QIXIS_CLK_133:
1100 return 133333333;
1101 }
1102 return 66666666;
1103}
1104
1105static int serdes_refclock(u8 sw, u8 sdclk)
1106{
1107 unsigned int clock;
1108 int ret = -1;
1109 u8 brdcfg4;
1110
1111 if (sdclk == 1) {
1112 brdcfg4 = QIXIS_READ(brdcfg[4]);
1113 if ((brdcfg4 & CLK_MUX_SEL_MASK) == ETH_PHY_CLK_OUT)
1114 return SRDS_PLLCR0_RFCK_SEL_125;
1115 else
1116 clock = (sw >> 5) & 7;
1117 } else
1118 clock = (sw >> 6) & 3;
1119
1120 switch (clock) {
1121 case 0:
1122 ret = SRDS_PLLCR0_RFCK_SEL_100;
1123 break;
1124 case 1:
1125 ret = SRDS_PLLCR0_RFCK_SEL_125;
1126 break;
1127 case 2:
1128 ret = SRDS_PLLCR0_RFCK_SEL_156_25;
1129 break;
1130 case 3:
1131 ret = SRDS_PLLCR0_RFCK_SEL_161_13;
1132 break;
1133 case 4:
1134 case 5:
1135 case 6:
1136 ret = SRDS_PLLCR0_RFCK_SEL_122_88;
1137 break;
1138 default:
1139 ret = -1;
1140 break;
1141 }
1142
1143 return ret;
1144}
1145
York Sunb5b06fb2012-12-23 19:25:27 +00001146#define NUM_SRDS_BANKS 2
1147
1148int misc_init_r(void)
1149{
1150 u8 sw;
1151 serdes_corenet_t *srds_regs =
1152 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
1153 u32 actual[NUM_SRDS_BANKS];
1154 unsigned int i;
1155 int clock;
1156
1157 sw = QIXIS_READ(brdcfg[2]);
1158 clock = serdes_refclock(sw, 1);
1159 if (clock >= 0)
1160 actual[0] = clock;
1161 else
1162 printf("Warning: SDREFCLK1 switch setting is unsupported\n");
1163
1164 sw = QIXIS_READ(brdcfg[4]);
1165 clock = serdes_refclock(sw, 2);
1166 if (clock >= 0)
1167 actual[1] = clock;
1168 else
1169 printf("Warning: SDREFCLK2 switch setting unsupported\n");
1170
1171 for (i = 0; i < NUM_SRDS_BANKS; i++) {
1172 u32 pllcr0 = srds_regs->bank[i].pllcr0;
1173 u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK;
1174 if (expected != actual[i]) {
1175 printf("Warning: SERDES bank %u expects reference clock"
1176 " %sMHz, but actual is %sMHz\n", i + 1,
1177 serdes_clock_to_string(expected),
1178 serdes_clock_to_string(actual[i]));
1179 }
1180 }
1181
1182 return 0;
1183}
1184
Simon Glasse895a4b2014-10-23 18:58:47 -06001185int ft_board_setup(void *blob, bd_t *bd)
York Sunb5b06fb2012-12-23 19:25:27 +00001186{
1187 phys_addr_t base;
1188 phys_size_t size;
1189
1190 ft_cpu_setup(blob, bd);
1191
1192 base = getenv_bootm_low();
1193 size = getenv_bootm_size();
1194
1195 fdt_fixup_memory(blob, (u64)base, (u64)size);
1196
1197#ifdef CONFIG_PCI
1198 pci_of_setup(blob, bd);
1199#endif
1200
1201 fdt_fixup_liodn(blob);
1202
1203#ifdef CONFIG_HAS_FSL_DR_USB
1204 fdt_fixup_dr_usb(blob, bd);
1205#endif
1206
1207#ifdef CONFIG_SYS_DPAA_FMAN
1208 fdt_fixup_fman_ethernet(blob);
1209 fdt_fixup_board_enet(blob);
1210#endif
Simon Glasse895a4b2014-10-23 18:58:47 -06001211
1212 return 0;
York Sunb5b06fb2012-12-23 19:25:27 +00001213}
Shaveta Leekha43548892012-12-23 19:25:42 +00001214
1215/*
1216 * Dump board switch settings.
1217 * The bits that cannot be read/sampled via some FPGA or some
1218 * registers, they will be displayed as
1219 * underscore in binary format. mask[] has those bits.
1220 * Some bits are calculated differently than the actual switches
1221 * if booting with overriding by FPGA.
1222 */
1223void qixis_dump_switch(void)
1224{
1225 int i;
1226 u8 sw[5];
1227
1228 /*
1229 * Any bit with 1 means that bit cannot be reverse engineered.
1230 * It will be displayed as _ in binary format.
1231 */
1232 static const u8 mask[] = {0x07, 0, 0, 0xff, 0};
1233 char buf[10];
1234 u8 brdcfg[16], dutcfg[16];
1235
1236 for (i = 0; i < 16; i++) {
1237 brdcfg[i] = qixis_read(offsetof(struct qixis, brdcfg[0]) + i);
1238 dutcfg[i] = qixis_read(offsetof(struct qixis, dutcfg[0]) + i);
1239 }
1240
1241 sw[0] = ((brdcfg[0] & 0x0f) << 4) | \
1242 (brdcfg[9] & 0x08);
1243 sw[1] = ((dutcfg[1] & 0x01) << 7) | \
1244 ((dutcfg[2] & 0x07) << 4) | \
1245 ((dutcfg[6] & 0x10) >> 1) | \
1246 ((dutcfg[6] & 0x80) >> 5) | \
1247 ((dutcfg[1] & 0x40) >> 5) | \
1248 (dutcfg[6] & 0x01);
1249 sw[2] = dutcfg[0];
1250 sw[3] = 0;
1251 sw[4] = ((brdcfg[1] & 0x30) << 2) | \
1252 ((brdcfg[1] & 0xc0) >> 2) | \
1253 (brdcfg[1] & 0x0f);
1254
1255 puts("DIP switch settings:\n");
1256 for (i = 0; i < 5; i++) {
1257 printf("SW%d = 0b%s (0x%02x)\n",
1258 i + 1, byte_to_binary_mask(sw[i], mask[i], buf), sw[i]);
1259 }
1260}