blob: 6a8fca61a0d451b6c407c87a3397bde2f1557eaa [file] [log] [blame]
York Sun0789dc92012-12-23 19:25:27 +00001/*
2 * Copyright 2011-2012 Freescale Semiconductor, Inc.
3 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02004 * SPDX-License-Identifier: GPL-2.0+
York Sun0789dc92012-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 Leekha2145a3e2014-02-26 16:06:56 +053014#include <asm/errno.h>
York Sun0789dc92012-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 Guptaf43bb232014-11-13 11:27:32 +080022#include <hwconfig.h>
York Sun0789dc92012-12-23 19:25:27 +000023
24#include "../common/qixis.h"
25#include "../common/vsc3316_3308.h"
Shaveta Leekhad1cb7742013-07-02 14:43:53 +053026#include "../common/idt8t49n222a_serdes_clk.h"
Shaveta Leekhae1b6f4c2014-04-11 14:12:40 +053027#include "../common/zm7300.h"
York Sun0789dc92012-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 Glassa8b57392012-12-13 20:48:48 +000041 struct cpu_type *cpu = gd->arch.cpu;
York Sun0789dc92012-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 Sun0789dc92012-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 Leekhae1b6f4c2014-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 Sun0789dc92012-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 Guptaf43bb232014-11-13 11:27:32 +0800337 char buffer[HWCONFIG_BUFFER_SIZE];
338 char *buf = NULL;
York Sun0789dc92012-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 aggrwal331dd1d2014-02-17 08:38:58 +0530359 case 0x29:
York Sun0789dc92012-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 Leekha93201602013-03-25 07:40:17 +0000377 vsc16_tx_4sfp_sgmii_12_56,
378 num_vsc16_con);
York Sun0789dc92012-12-23 19:25:27 +0000379 if (ret)
380 return ret;
381 ret = vsc3316_config(VSC3316_RX_ADDRESS,
Shaveta Leekha93201602013-03-25 07:40:17 +0000382 vsc16_rx_4sfp_sgmii_12_56,
383 num_vsc16_con);
York Sun0789dc92012-12-23 19:25:27 +0000384 if (ret)
385 return ret;
386 } else {
387 return ret;
388 }
389 break;
390
Shaveta Leekhab900a612014-11-12 16:00:44 +0530391 case 0x01:
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530392 case 0x02:
393 case 0x04:
394 case 0x05:
395 case 0x06:
Shaveta Leekhab900a612014-11-12 16:00:44 +0530396 case 0x07:
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530397 case 0x08:
398 case 0x09:
399 case 0x0A:
400 case 0x0B:
401 case 0x0C:
Shaveta Leekhab900a612014-11-12 16:00:44 +0530402 case 0x2F:
Shaveta Leekha8d2ba982014-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 Sun0789dc92012-12-23 19:25:27 +0000441#ifdef CONFIG_PPC_B4420
poonam aggrwal331dd1d2014-02-17 08:38:58 +0530442 case 0x17:
York Sun0789dc92012-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 Xie37c82b52014-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 Sun0789dc92012-12-23 19:25:27 +0000499 switch (serdes2_prtcl) {
poonam aggrwal1e9956b2014-05-31 00:08:18 +0530500#ifdef CONFIG_PPC_B4420
501 case 0x9d:
502#endif
York Sun0789dc92012-12-23 19:25:27 +0000503 case 0x9E:
504 case 0x9A:
505 case 0x98:
Shaveta Leekhab900a612014-11-12 16:00:44 +0530506 case 0x48:
York Sun0789dc92012-12-23 19:25:27 +0000507 case 0x49:
508 case 0x4E:
Shaveta Leekhab900a612014-11-12 16:00:44 +0530509 case 0x79:
York Sun0789dc92012-12-23 19:25:27 +0000510 case 0x7A:
York Sun0789dc92012-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 Xie37c82b52014-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 Guptaf43bb232014-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)) {
Shaohui Xie60c3b092014-11-13 11:27:49 +0800551#ifdef CONFIG_SYS_FSL_B4860QDS_XFI_ERR
552 /* change default VSC3308 for XFI erratum */
553 ret = vsc3308_config_adjust(VSC3308_TX_ADDRESS,
554 vsc08_tx_sfp, num_vsc08_con);
555 if (ret)
556 return ret;
557
558 ret = vsc3308_config_adjust(VSC3308_RX_ADDRESS,
559 vsc08_rx_sfp, num_vsc08_con);
560 if (ret)
561 return ret;
562#else
Suresh Guptaf43bb232014-11-13 11:27:32 +0800563 ret = vsc3308_config(VSC3308_TX_ADDRESS,
564 vsc08_tx_sfp, num_vsc08_con);
565 if (ret)
566 return ret;
567
568 ret = vsc3308_config(VSC3308_RX_ADDRESS,
569 vsc08_rx_sfp, num_vsc08_con);
570 if (ret)
571 return ret;
Shaohui Xie60c3b092014-11-13 11:27:49 +0800572#endif
Suresh Guptaf43bb232014-11-13 11:27:32 +0800573 } else {
574 ret = vsc3308_config(VSC3308_TX_ADDRESS,
575 vsc08_tx_amc, num_vsc08_con);
576 if (ret)
577 return ret;
578
579 ret = vsc3308_config(VSC3308_RX_ADDRESS,
580 vsc08_rx_amc, num_vsc08_con);
581 if (ret)
582 return ret;
583 }
584
Shaohui Xie37c82b52014-11-13 11:26:19 +0800585 } else {
586 return ret;
587 }
588 break;
York Sun0789dc92012-12-23 19:25:27 +0000589 default:
590 printf("WARNING:VSC crossbars programming not supported for: %x"
591 " SerDes2 Protocol.\n", serdes2_prtcl);
592 return -1;
593 }
594
595 return 0;
596}
597
Shaveta Leekhad11523b2014-02-26 16:08:22 +0530598static int calibrate_pll(serdes_corenet_t *srds_regs, int pll_num)
599{
600 u32 rst_err;
601
602 /* Steps For SerDes PLLs reset and reconfiguration
603 * or PLL power-up procedure
604 */
605 debug("CALIBRATE PLL:%d\n", pll_num);
606 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
607 SRDS_RSTCTL_SDRST_B);
608 udelay(10);
609 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
610 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
611 udelay(10);
612 setbits_be32(&srds_regs->bank[pll_num].rstctl,
613 SRDS_RSTCTL_RST);
614 setbits_be32(&srds_regs->bank[pll_num].rstctl,
615 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
616 | SRDS_RSTCTL_SDRST_B));
617
618 udelay(20);
619
620 /* Check whether PLL has been locked or not */
621 rst_err = in_be32(&srds_regs->bank[pll_num].rstctl) &
622 SRDS_RSTCTL_RSTERR;
623 rst_err >>= SRDS_RSTCTL_RSTERR_SHIFT;
624 debug("RST_ERR value for PLL %d is: 0x%x:\n", pll_num, rst_err);
625 if (rst_err)
626 return rst_err;
627
628 return rst_err;
629}
630
631static int check_pll_locks(serdes_corenet_t *srds_regs, int pll_num)
632{
633 int ret = 0;
634 u32 fcap, dcbias, bcap, pllcr1, pllcr0;
635
636 if (calibrate_pll(srds_regs, pll_num)) {
637 /* STEP 1 */
638 /* Read fcap, dcbias and bcap value */
639 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
640 SRDS_PLLCR0_DCBIAS_OUT_EN);
641 fcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
642 SRDS_PLLSR2_FCAP;
643 fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
644 bcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
645 SRDS_PLLSR2_BCAP_EN;
646 bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
647 setbits_be32(&srds_regs->bank[pll_num].pllcr0,
648 SRDS_PLLCR0_DCBIAS_OUT_EN);
649 dcbias = in_be32(&srds_regs->bank[pll_num].pllsr2) &
650 SRDS_PLLSR2_DCBIAS;
651 dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
652 debug("values of bcap:%x, fcap:%x and dcbias:%x\n",
653 bcap, fcap, dcbias);
654 if (fcap == 0 && bcap == 1) {
655 /* Step 3 */
656 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
657 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
658 | SRDS_RSTCTL_SDRST_B));
659 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
660 SRDS_PLLCR1_BCAP_EN);
661 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
662 SRDS_PLLCR1_BCAP_OVD);
663 if (calibrate_pll(srds_regs, pll_num)) {
664 /*save the fcap, dcbias and bcap values*/
665 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
666 SRDS_PLLCR0_DCBIAS_OUT_EN);
667 fcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
668 & SRDS_PLLSR2_FCAP;
669 fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
670 bcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
671 & SRDS_PLLSR2_BCAP_EN;
672 bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
673 setbits_be32(&srds_regs->bank[pll_num].pllcr0,
674 SRDS_PLLCR0_DCBIAS_OUT_EN);
675 dcbias = in_be32
676 (&srds_regs->bank[pll_num].pllsr2) &
677 SRDS_PLLSR2_DCBIAS;
678 dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
679
680 /* Step 4*/
681 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
682 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
683 | SRDS_RSTCTL_SDRST_B));
684 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
685 SRDS_PLLCR1_BYP_CAL);
686 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
687 SRDS_PLLCR1_BCAP_EN);
688 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
689 SRDS_PLLCR1_BCAP_OVD);
690 /* change the fcap and dcbias to the saved
691 * values from Step 3 */
692 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
693 SRDS_PLLCR1_PLL_FCAP);
694 pllcr1 = (in_be32
695 (&srds_regs->bank[pll_num].pllcr1)|
696 (fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
697 out_be32(&srds_regs->bank[pll_num].pllcr1,
698 pllcr1);
699 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
700 SRDS_PLLCR0_DCBIAS_OVRD);
701 pllcr0 = (in_be32
702 (&srds_regs->bank[pll_num].pllcr0)|
703 (dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
704 out_be32(&srds_regs->bank[pll_num].pllcr0,
705 pllcr0);
706 ret = calibrate_pll(srds_regs, pll_num);
707 if (ret)
708 return ret;
709 } else {
710 goto out;
711 }
712 } else { /* Step 5 */
713 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
714 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
715 | SRDS_RSTCTL_SDRST_B));
716 udelay(10);
717 /* Change the fcap, dcbias, and bcap to the
718 * values from Step 1 */
719 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
720 SRDS_PLLCR1_BYP_CAL);
721 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
722 SRDS_PLLCR1_PLL_FCAP);
723 pllcr1 = (in_be32(&srds_regs->bank[pll_num].pllcr1)|
724 (fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
725 out_be32(&srds_regs->bank[pll_num].pllcr1,
726 pllcr1);
727 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
728 SRDS_PLLCR0_DCBIAS_OVRD);
729 pllcr0 = (in_be32(&srds_regs->bank[pll_num].pllcr0)|
730 (dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
731 out_be32(&srds_regs->bank[pll_num].pllcr0,
732 pllcr0);
733 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
734 SRDS_PLLCR1_BCAP_EN);
735 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
736 SRDS_PLLCR1_BCAP_OVD);
737 ret = calibrate_pll(srds_regs, pll_num);
738 if (ret)
739 return ret;
740 }
741 }
742out:
743 return 0;
744}
745
746static int check_serdes_pll_locks(void)
747{
748 serdes_corenet_t *srds1_regs =
749 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
750 serdes_corenet_t *srds2_regs =
751 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
752 int i, ret1, ret2;
753
754 debug("\nSerDes1 Lock check\n");
755 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
756 ret1 = check_pll_locks(srds1_regs, i);
757 if (ret1) {
758 printf("SerDes1, PLL:%d didnt lock\n", i);
759 return ret1;
760 }
761 }
762 debug("\nSerDes2 Lock check\n");
763 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
764 ret2 = check_pll_locks(srds2_regs, i);
765 if (ret2) {
766 printf("SerDes2, PLL:%d didnt lock\n", i);
767 return ret2;
768 }
769 }
770
771 return 0;
772}
773
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530774int config_serdes1_refclks(void)
775{
776 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
777 serdes_corenet_t *srds_regs =
778 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
779 u32 serdes1_prtcl, lane;
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530780 unsigned int flag_sgmii_aurora_prtcl = 0;
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530781 int i;
782 int ret = 0;
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530783
784 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
785 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
786 if (!serdes1_prtcl) {
787 printf("SERDES1 is not enabled\n");
788 return -1;
789 }
790 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
791 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
792
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530793 /* To prevent generation of reset request from SerDes
794 * while changing the refclks, By setting SRDS_RST_MSK bit,
795 * SerDes reset event cannot cause a reset request
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530796 */
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530797 setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
798
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530799 /* Reconfigure IDT idt8t49n222a device for CPRI to work
800 * For this SerDes1's Refclk1 and refclk2 need to be set
801 * to 122.88MHz
802 */
803 switch (serdes1_prtcl) {
Shaveta Leekhab900a612014-11-12 16:00:44 +0530804 case 0x29:
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530805 case 0x2A:
806 case 0x2C:
807 case 0x2D:
808 case 0x2E:
Shaveta Leekhab900a612014-11-12 16:00:44 +0530809 case 0x01:
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530810 case 0x02:
811 case 0x04:
812 case 0x05:
813 case 0x06:
Shaveta Leekhab900a612014-11-12 16:00:44 +0530814 case 0x07:
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530815 case 0x08:
816 case 0x09:
817 case 0x0A:
818 case 0x0B:
819 case 0x0C:
Shaveta Leekhab900a612014-11-12 16:00:44 +0530820 case 0x2F:
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530821 case 0x30:
822 case 0x32:
823 case 0x33:
824 case 0x34:
825 case 0x39:
826 case 0x3A:
827 case 0x3C:
828 case 0x3D:
829 case 0x5C:
830 case 0x5D:
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530831 debug("Configuring idt8t49n222a for CPRI SerDes clks:"
832 " for srds_prctl:%x\n", serdes1_prtcl);
833 ret = select_i2c_ch_pca(I2C_CH_IDT);
834 if (!ret) {
835 ret = set_serdes_refclk(IDT_SERDES1_ADDRESS, 1,
836 SERDES_REFCLK_122_88,
837 SERDES_REFCLK_122_88, 0);
838 if (ret) {
839 printf("IDT8T49N222A configuration failed.\n");
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530840 goto out;
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530841 } else
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530842 debug("IDT8T49N222A configured.\n");
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530843 } else {
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530844 goto out;
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530845 }
846 select_i2c_ch_pca(I2C_CH_DEFAULT);
847
848 /* Change SerDes1's Refclk1 to 125MHz for on board
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530849 * SGMIIs or Aurora to work
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530850 */
851 for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
852 enum srds_prtcl lane_prtcl = serdes_get_prtcl
853 (0, serdes1_prtcl, lane);
854 switch (lane_prtcl) {
855 case SGMII_FM1_DTSEC1:
856 case SGMII_FM1_DTSEC2:
857 case SGMII_FM1_DTSEC3:
858 case SGMII_FM1_DTSEC4:
859 case SGMII_FM1_DTSEC5:
860 case SGMII_FM1_DTSEC6:
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530861 case AURORA:
862 flag_sgmii_aurora_prtcl++;
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530863 break;
864 default:
865 break;
866 }
867 }
868
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530869 if (flag_sgmii_aurora_prtcl)
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530870 QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
871
872 /* Steps For SerDes PLLs reset and reconfiguration after
873 * changing SerDes's refclks
874 */
Shaveta Leekha7e1ee692014-02-26 16:07:51 +0530875 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530876 debug("For PLL%d reset and reconfiguration after"
877 " changing refclks\n", i+1);
878 clrbits_be32(&srds_regs->bank[i].rstctl,
879 SRDS_RSTCTL_SDRST_B);
880 udelay(10);
881 clrbits_be32(&srds_regs->bank[i].rstctl,
882 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
883 udelay(10);
884 setbits_be32(&srds_regs->bank[i].rstctl,
885 SRDS_RSTCTL_RST);
886 setbits_be32(&srds_regs->bank[i].rstctl,
887 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
888 | SRDS_RSTCTL_SDRST_B));
889 }
890 break;
891 default:
892 printf("WARNING:IDT8T49N222A configuration not"
893 " supported for:%x SerDes1 Protocol.\n",
894 serdes1_prtcl);
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530895 }
896
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530897out:
898 /* Clearing SRDS_RST_MSK bit as now
899 * SerDes reset event can cause a reset request
900 */
901 clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
902 return ret;
903}
904
905int config_serdes2_refclks(void)
906{
907 ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
908 serdes_corenet_t *srds2_regs =
909 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
910 u32 serdes2_prtcl;
911 int ret = 0;
912 int i;
913
914 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
915 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
916 if (!serdes2_prtcl) {
917 debug("SERDES2 is not enabled\n");
918 return -ENODEV;
919 }
920 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
921 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
922
923 /* To prevent generation of reset request from SerDes
924 * while changing the refclks, By setting SRDS_RST_MSK bit,
925 * SerDes reset event cannot cause a reset request
926 */
927 setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
928
929 /* Reconfigure IDT idt8t49n222a device for PCIe SATA to work
930 * For this SerDes2's Refclk1 need to be set to 100MHz
931 */
932 switch (serdes2_prtcl) {
poonam aggrwal1e9956b2014-05-31 00:08:18 +0530933#ifdef CONFIG_PPC_B4420
934 case 0x9d:
935#endif
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530936 case 0x9E:
937 case 0x9A:
Shaveta Leekhab900a612014-11-12 16:00:44 +0530938 /* fallthrough */
939 case 0xb1:
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530940 case 0xb2:
941 debug("Configuring IDT for PCIe SATA for srds_prctl:%x\n",
942 serdes2_prtcl);
943 ret = select_i2c_ch_pca(I2C_CH_IDT);
944 if (!ret) {
945 ret = set_serdes_refclk(IDT_SERDES2_ADDRESS, 2,
946 SERDES_REFCLK_100,
Shaveta Leekha7e1ee692014-02-26 16:07:51 +0530947 SERDES_REFCLK_156_25, 0);
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530948 if (ret) {
949 printf("IDT8T49N222A configuration failed.\n");
950 goto out;
951 } else
952 debug("IDT8T49N222A configured.\n");
953 } else {
954 goto out;
955 }
956 select_i2c_ch_pca(I2C_CH_DEFAULT);
957
958 /* Steps For SerDes PLLs reset and reconfiguration after
959 * changing SerDes's refclks
960 */
Shaveta Leekha7e1ee692014-02-26 16:07:51 +0530961 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530962 clrbits_be32(&srds2_regs->bank[i].rstctl,
963 SRDS_RSTCTL_SDRST_B);
964 udelay(10);
965 clrbits_be32(&srds2_regs->bank[i].rstctl,
966 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
967 udelay(10);
968 setbits_be32(&srds2_regs->bank[i].rstctl,
969 SRDS_RSTCTL_RST);
970 setbits_be32(&srds2_regs->bank[i].rstctl,
971 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
972 | SRDS_RSTCTL_SDRST_B));
Shaveta Leekhad11523b2014-02-26 16:08:22 +0530973
974 udelay(10);
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530975 }
976 break;
977 default:
978 printf("IDT configuration not supported for:%x S2 Protocol.\n",
979 serdes2_prtcl);
980 }
981
982out:
983 /* Clearing SRDS_RST_MSK bit as now
984 * SerDes reset event can cause a reset request
985 */
986 clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
987 return ret;
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530988}
989
York Sun0789dc92012-12-23 19:25:27 +0000990int board_early_init_r(void)
991{
992 const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
York Sun220c3462014-06-24 21:16:20 -0700993 int flash_esel = find_tlb_idx((void *)flashbase, 1);
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530994 int ret;
Shaveta Leekha1b636352014-11-12 14:23:26 +0530995 u32 svr = SVR_SOC_VER(get_svr());
996
997 /* Create law for MAPLE only for personalities having MAPLE */
998 if ((svr == SVR_B4860) || (svr == SVR_B4440) ||
999 (svr == SVR_B4420) || (svr == SVR_B4220)) {
1000 set_next_law(CONFIG_SYS_MAPLE_MEM_PHYS, LAW_SIZE_16M,
1001 LAW_TRGT_IF_MAPLE);
1002 }
York Sun0789dc92012-12-23 19:25:27 +00001003
1004 /*
1005 * Remap Boot flash + PROMJET region to caching-inhibited
1006 * so that flash can be erased properly.
1007 */
1008
1009 /* Flush d-cache and invalidate i-cache of any FLASH data */
1010 flush_dcache();
1011 invalidate_icache();
1012
York Sun220c3462014-06-24 21:16:20 -07001013 if (flash_esel == -1) {
1014 /* very unlikely unless something is messed up */
1015 puts("Error: Could not find TLB for FLASH BASE\n");
1016 flash_esel = 2; /* give our best effort to continue */
1017 } else {
1018 /* invalidate existing TLB entry for flash + promjet */
1019 disable_tlb(flash_esel);
1020 }
York Sun0789dc92012-12-23 19:25:27 +00001021
1022 set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
1023 MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
1024 0, flash_esel, BOOKE_PAGESZ_256M, 1);
1025
1026 set_liodns();
1027#ifdef CONFIG_SYS_DPAA_QBMAN
1028 setup_portals();
1029#endif
Shaveta Leekhae1b6f4c2014-04-11 14:12:40 +05301030 /*
1031 * Adjust core voltage according to voltage ID
1032 * This function changes I2C mux to channel 2.
1033 */
1034 if (adjust_vdd(0) < 0)
1035 printf("Warning: Adjusting core voltage failed\n");
1036
Shaveta Leekhad1cb7742013-07-02 14:43:53 +05301037 /* SerDes1 refclks need to be set again, as default clks
1038 * are not suitable for CPRI and onboard SGMIIs to work
1039 * simultaneously.
1040 * This function will set SerDes1's Refclk1 and refclk2
1041 * as per SerDes1 protocols
1042 */
1043 if (config_serdes1_refclks())
1044 printf("SerDes1 Refclks couldn't set properly.\n");
1045 else
1046 printf("SerDes1 Refclks have been set.\n");
York Sun0789dc92012-12-23 19:25:27 +00001047
Shaveta Leekha2145a3e2014-02-26 16:06:56 +05301048 /* SerDes2 refclks need to be set again, as default clks
1049 * are not suitable for PCIe SATA to work
1050 * This function will set SerDes2's Refclk1 and refclk2
1051 * for SerDes2 protocols having PCIe in them
1052 * for PCIe SATA to work
1053 */
1054 ret = config_serdes2_refclks();
1055 if (!ret)
1056 printf("SerDes2 Refclks have been set.\n");
1057 else if (ret == -ENODEV)
1058 printf("SerDes disable, Refclks couldn't change.\n");
1059 else
1060 printf("SerDes2 Refclk reconfiguring failed.\n");
1061
Shaveta Leekhad11523b2014-02-26 16:08:22 +05301062#if defined(CONFIG_SYS_FSL_ERRATUM_A006384) || \
1063 defined(CONFIG_SYS_FSL_ERRATUM_A006475)
1064 /* Rechecking the SerDes locks after all SerDes configurations
1065 * are done, As SerDes PLLs may not lock reliably at 5 G VCO
1066 * and at cold temperatures.
1067 * Following sequence ensure the proper locking of SerDes PLLs.
1068 */
1069 if (SVR_MAJ(get_svr()) == 1) {
1070 if (check_serdes_pll_locks())
1071 printf("SerDes plls still not locked properly.\n");
1072 else
1073 printf("SerDes plls have been locked well.\n");
1074 }
1075#endif
1076
York Sun0789dc92012-12-23 19:25:27 +00001077 /* Configure VSC3316 and VSC3308 crossbar switches */
1078 if (configure_vsc3316_3308())
1079 printf("VSC:failed to configure VSC3316/3308.\n");
1080 else
1081 printf("VSC:VSC3316/3308 successfully configured.\n");
1082
1083 select_i2c_ch_pca(I2C_CH_DEFAULT);
1084
1085 return 0;
1086}
1087
1088unsigned long get_board_sys_clk(void)
1089{
1090 u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
1091
1092 switch ((sysclk_conf & 0x0C) >> 2) {
1093 case QIXIS_CLK_100:
1094 return 100000000;
1095 case QIXIS_CLK_125:
1096 return 125000000;
1097 case QIXIS_CLK_133:
1098 return 133333333;
1099 }
1100 return 66666666;
1101}
1102
1103unsigned long get_board_ddr_clk(void)
1104{
1105 u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
1106
1107 switch (ddrclk_conf & 0x03) {
1108 case QIXIS_CLK_100:
1109 return 100000000;
1110 case QIXIS_CLK_125:
1111 return 125000000;
1112 case QIXIS_CLK_133:
1113 return 133333333;
1114 }
1115 return 66666666;
1116}
1117
1118static int serdes_refclock(u8 sw, u8 sdclk)
1119{
1120 unsigned int clock;
1121 int ret = -1;
1122 u8 brdcfg4;
1123
1124 if (sdclk == 1) {
1125 brdcfg4 = QIXIS_READ(brdcfg[4]);
1126 if ((brdcfg4 & CLK_MUX_SEL_MASK) == ETH_PHY_CLK_OUT)
1127 return SRDS_PLLCR0_RFCK_SEL_125;
1128 else
1129 clock = (sw >> 5) & 7;
1130 } else
1131 clock = (sw >> 6) & 3;
1132
1133 switch (clock) {
1134 case 0:
1135 ret = SRDS_PLLCR0_RFCK_SEL_100;
1136 break;
1137 case 1:
1138 ret = SRDS_PLLCR0_RFCK_SEL_125;
1139 break;
1140 case 2:
1141 ret = SRDS_PLLCR0_RFCK_SEL_156_25;
1142 break;
1143 case 3:
1144 ret = SRDS_PLLCR0_RFCK_SEL_161_13;
1145 break;
1146 case 4:
1147 case 5:
1148 case 6:
1149 ret = SRDS_PLLCR0_RFCK_SEL_122_88;
1150 break;
1151 default:
1152 ret = -1;
1153 break;
1154 }
1155
1156 return ret;
1157}
1158
York Sun0789dc92012-12-23 19:25:27 +00001159#define NUM_SRDS_BANKS 2
1160
1161int misc_init_r(void)
1162{
1163 u8 sw;
1164 serdes_corenet_t *srds_regs =
1165 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
1166 u32 actual[NUM_SRDS_BANKS];
1167 unsigned int i;
1168 int clock;
1169
1170 sw = QIXIS_READ(brdcfg[2]);
1171 clock = serdes_refclock(sw, 1);
1172 if (clock >= 0)
1173 actual[0] = clock;
1174 else
1175 printf("Warning: SDREFCLK1 switch setting is unsupported\n");
1176
1177 sw = QIXIS_READ(brdcfg[4]);
1178 clock = serdes_refclock(sw, 2);
1179 if (clock >= 0)
1180 actual[1] = clock;
1181 else
1182 printf("Warning: SDREFCLK2 switch setting unsupported\n");
1183
1184 for (i = 0; i < NUM_SRDS_BANKS; i++) {
1185 u32 pllcr0 = srds_regs->bank[i].pllcr0;
1186 u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK;
1187 if (expected != actual[i]) {
1188 printf("Warning: SERDES bank %u expects reference clock"
1189 " %sMHz, but actual is %sMHz\n", i + 1,
1190 serdes_clock_to_string(expected),
1191 serdes_clock_to_string(actual[i]));
1192 }
1193 }
1194
1195 return 0;
1196}
1197
Simon Glass2aec3cc2014-10-23 18:58:47 -06001198int ft_board_setup(void *blob, bd_t *bd)
York Sun0789dc92012-12-23 19:25:27 +00001199{
1200 phys_addr_t base;
1201 phys_size_t size;
1202
1203 ft_cpu_setup(blob, bd);
1204
1205 base = getenv_bootm_low();
1206 size = getenv_bootm_size();
1207
1208 fdt_fixup_memory(blob, (u64)base, (u64)size);
1209
1210#ifdef CONFIG_PCI
1211 pci_of_setup(blob, bd);
1212#endif
1213
1214 fdt_fixup_liodn(blob);
1215
1216#ifdef CONFIG_HAS_FSL_DR_USB
1217 fdt_fixup_dr_usb(blob, bd);
1218#endif
1219
1220#ifdef CONFIG_SYS_DPAA_FMAN
1221 fdt_fixup_fman_ethernet(blob);
1222 fdt_fixup_board_enet(blob);
1223#endif
Simon Glass2aec3cc2014-10-23 18:58:47 -06001224
1225 return 0;
York Sun0789dc92012-12-23 19:25:27 +00001226}
Shaveta Leekha6942b482012-12-23 19:25:42 +00001227
1228/*
1229 * Dump board switch settings.
1230 * The bits that cannot be read/sampled via some FPGA or some
1231 * registers, they will be displayed as
1232 * underscore in binary format. mask[] has those bits.
1233 * Some bits are calculated differently than the actual switches
1234 * if booting with overriding by FPGA.
1235 */
1236void qixis_dump_switch(void)
1237{
1238 int i;
1239 u8 sw[5];
1240
1241 /*
1242 * Any bit with 1 means that bit cannot be reverse engineered.
1243 * It will be displayed as _ in binary format.
1244 */
1245 static const u8 mask[] = {0x07, 0, 0, 0xff, 0};
1246 char buf[10];
1247 u8 brdcfg[16], dutcfg[16];
1248
1249 for (i = 0; i < 16; i++) {
1250 brdcfg[i] = qixis_read(offsetof(struct qixis, brdcfg[0]) + i);
1251 dutcfg[i] = qixis_read(offsetof(struct qixis, dutcfg[0]) + i);
1252 }
1253
1254 sw[0] = ((brdcfg[0] & 0x0f) << 4) | \
1255 (brdcfg[9] & 0x08);
1256 sw[1] = ((dutcfg[1] & 0x01) << 7) | \
1257 ((dutcfg[2] & 0x07) << 4) | \
1258 ((dutcfg[6] & 0x10) >> 1) | \
1259 ((dutcfg[6] & 0x80) >> 5) | \
1260 ((dutcfg[1] & 0x40) >> 5) | \
1261 (dutcfg[6] & 0x01);
1262 sw[2] = dutcfg[0];
1263 sw[3] = 0;
1264 sw[4] = ((brdcfg[1] & 0x30) << 2) | \
1265 ((brdcfg[1] & 0xc0) >> 2) | \
1266 (brdcfg[1] & 0x0f);
1267
1268 puts("DIP switch settings:\n");
1269 for (i = 0; i < 5; i++) {
1270 printf("SW%d = 0b%s (0x%02x)\n",
1271 i + 1, byte_to_binary_mask(sw[i], mask[i], buf), sw[i]);
1272 }
1273}