blob: c2ceb8014eff18addaa60a67e86199e6c1b44528 [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>
Masahiro Yamada1221ce42016-09-21 11:28:55 +090014#include <linux/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>
York Sunb5b06fb2012-12-23 19:25:27 +000019#include <asm/fsl_liodn.h>
20#include <fm_eth.h>
Suresh Guptacd79e5f2014-11-13 11:27:32 +080021#include <hwconfig.h>
York Sunb5b06fb2012-12-23 19:25:27 +000022
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;
Suresh Guptacd79e5f2014-11-13 11:27:32 +0800336 char buffer[HWCONFIG_BUFFER_SIZE];
337 char *buf = NULL;
York Sunb5b06fb2012-12-23 19:25:27 +0000338
339 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
340 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
341 if (!serdes1_prtcl) {
342 printf("SERDES1 is not enabled\n");
343 return 0;
344 }
345 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
346 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
347
348 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
349 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
350 if (!serdes2_prtcl) {
351 printf("SERDES2 is not enabled\n");
352 return 0;
353 }
354 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
355 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
356
357 switch (serdes1_prtcl) {
poonam aggrwalc7d506d2014-02-17 08:38:58 +0530358 case 0x29:
York Sunb5b06fb2012-12-23 19:25:27 +0000359 case 0x2a:
360 case 0x2C:
361 case 0x2D:
362 case 0x2E:
363 /*
364 * Configuration:
365 * SERDES: 1
366 * Lanes: A,B: SGMII
367 * Lanes: C,D,E,F,G,H: CPRI
368 */
369 debug("Configuring crossbar to use onboard SGMII PHYs:"
370 "srds_prctl:%x\n", serdes1_prtcl);
371 num_vsc16_con = NUM_CON_VSC3316;
372 /* Configure VSC3316 crossbar switch */
373 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
374 if (!ret) {
375 ret = vsc3316_config(VSC3316_TX_ADDRESS,
Shaveta Leekha0fecbba2013-03-25 07:40:17 +0000376 vsc16_tx_4sfp_sgmii_12_56,
377 num_vsc16_con);
York Sunb5b06fb2012-12-23 19:25:27 +0000378 if (ret)
379 return ret;
380 ret = vsc3316_config(VSC3316_RX_ADDRESS,
Shaveta Leekha0fecbba2013-03-25 07:40:17 +0000381 vsc16_rx_4sfp_sgmii_12_56,
382 num_vsc16_con);
York Sunb5b06fb2012-12-23 19:25:27 +0000383 if (ret)
384 return ret;
385 } else {
386 return ret;
387 }
388 break;
389
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530390 case 0x01:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530391 case 0x02:
392 case 0x04:
393 case 0x05:
394 case 0x06:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530395 case 0x07:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530396 case 0x08:
397 case 0x09:
398 case 0x0A:
399 case 0x0B:
400 case 0x0C:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530401 case 0x2F:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530402 case 0x30:
403 case 0x32:
404 case 0x33:
405 case 0x34:
406 case 0x39:
407 case 0x3A:
408 case 0x3C:
409 case 0x3D:
410 case 0x5C:
411 case 0x5D:
412 /*
413 * Configuration:
414 * SERDES: 1
415 * Lanes: A,B: AURORA
416 * Lanes: C,d: SGMII
417 * Lanes: E,F,G,H: CPRI
418 */
419 debug("Configuring crossbar for Aurora, SGMII 3 and 4,"
420 " and CPRI. srds_prctl:%x\n", serdes1_prtcl);
421 num_vsc16_con = NUM_CON_VSC3316;
422 /* Configure VSC3316 crossbar switch */
423 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
424 if (!ret) {
425 ret = vsc3316_config(VSC3316_TX_ADDRESS,
426 vsc16_tx_sfp_sgmii_aurora,
427 num_vsc16_con);
428 if (ret)
429 return ret;
430 ret = vsc3316_config(VSC3316_RX_ADDRESS,
431 vsc16_rx_sfp_sgmii_aurora,
432 num_vsc16_con);
433 if (ret)
434 return ret;
435 } else {
436 return ret;
437 }
438 break;
439
York Sunb5b06fb2012-12-23 19:25:27 +0000440#ifdef CONFIG_PPC_B4420
poonam aggrwalc7d506d2014-02-17 08:38:58 +0530441 case 0x17:
York Sunb5b06fb2012-12-23 19:25:27 +0000442 case 0x18:
443 /*
444 * Configuration:
445 * SERDES: 1
446 * Lanes: A,B,C,D: SGMII
447 * Lanes: E,F,G,H: CPRI
448 */
449 debug("Configuring crossbar to use onboard SGMII PHYs:"
450 "srds_prctl:%x\n", serdes1_prtcl);
451 num_vsc16_con = NUM_CON_VSC3316;
452 /* Configure VSC3316 crossbar switch */
453 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
454 if (!ret) {
455 ret = vsc3316_config(VSC3316_TX_ADDRESS,
456 vsc16_tx_sgmii_lane_cd, num_vsc16_con);
457 if (ret)
458 return ret;
459 ret = vsc3316_config(VSC3316_RX_ADDRESS,
460 vsc16_rx_sgmii_lane_cd, num_vsc16_con);
461 if (ret)
462 return ret;
463 } else {
464 return ret;
465 }
466 break;
467#endif
468
469 case 0x3E:
470 case 0x0D:
471 case 0x0E:
472 case 0x12:
473 num_vsc16_con = NUM_CON_VSC3316;
474 /* Configure VSC3316 crossbar switch */
475 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
476 if (!ret) {
477 ret = vsc3316_config(VSC3316_TX_ADDRESS,
478 vsc16_tx_sfp, num_vsc16_con);
479 if (ret)
480 return ret;
481 ret = vsc3316_config(VSC3316_RX_ADDRESS,
482 vsc16_rx_sfp, num_vsc16_con);
483 if (ret)
484 return ret;
485 } else {
486 return ret;
487 }
488 break;
489 default:
490 printf("WARNING:VSC crossbars programming not supported for:%x"
491 " SerDes1 Protocol.\n", serdes1_prtcl);
492 return -1;
493 }
494
Shaohui Xie89b94d82014-11-13 11:26:19 +0800495 num_vsc08_con = NUM_CON_VSC3308;
496 /* Configure VSC3308 crossbar switch */
497 ret = select_i2c_ch_pca(I2C_CH_VSC3308);
York Sunb5b06fb2012-12-23 19:25:27 +0000498 switch (serdes2_prtcl) {
poonam aggrwalfa6e7422014-05-31 00:08:18 +0530499#ifdef CONFIG_PPC_B4420
500 case 0x9d:
501#endif
York Sunb5b06fb2012-12-23 19:25:27 +0000502 case 0x9E:
503 case 0x9A:
504 case 0x98:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530505 case 0x48:
York Sunb5b06fb2012-12-23 19:25:27 +0000506 case 0x49:
507 case 0x4E:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530508 case 0x79:
York Sunb5b06fb2012-12-23 19:25:27 +0000509 case 0x7A:
York Sunb5b06fb2012-12-23 19:25:27 +0000510 if (!ret) {
511 ret = vsc3308_config(VSC3308_TX_ADDRESS,
512 vsc08_tx_amc, num_vsc08_con);
513 if (ret)
514 return ret;
515 ret = vsc3308_config(VSC3308_RX_ADDRESS,
516 vsc08_rx_amc, num_vsc08_con);
517 if (ret)
518 return ret;
519 } else {
520 return ret;
521 }
522 break;
Shaohui Xie89b94d82014-11-13 11:26:19 +0800523 case 0x80:
524 case 0x81:
525 case 0x82:
526 case 0x83:
527 case 0x84:
528 case 0x85:
529 case 0x86:
530 case 0x87:
531 case 0x88:
532 case 0x89:
533 case 0x8a:
534 case 0x8b:
535 case 0x8c:
536 case 0x8d:
537 case 0x8e:
538 case 0xb1:
539 case 0xb2:
540 if (!ret) {
Suresh Guptacd79e5f2014-11-13 11:27:32 +0800541 /*
542 * Extract hwconfig from environment since environment
543 * is not setup properly yet
544 */
545 getenv_f("hwconfig", buffer, sizeof(buffer));
546 buf = buffer;
547
548 if (hwconfig_subarg_cmp_f("fsl_b4860_serdes2",
549 "sfp_amc", "sfp", buf)) {
Shaohui Xieb24f6d42014-11-13 11:27:49 +0800550#ifdef CONFIG_SYS_FSL_B4860QDS_XFI_ERR
551 /* change default VSC3308 for XFI erratum */
552 ret = vsc3308_config_adjust(VSC3308_TX_ADDRESS,
553 vsc08_tx_sfp, num_vsc08_con);
554 if (ret)
555 return ret;
556
557 ret = vsc3308_config_adjust(VSC3308_RX_ADDRESS,
558 vsc08_rx_sfp, num_vsc08_con);
559 if (ret)
560 return ret;
561#else
Suresh Guptacd79e5f2014-11-13 11:27:32 +0800562 ret = vsc3308_config(VSC3308_TX_ADDRESS,
563 vsc08_tx_sfp, num_vsc08_con);
564 if (ret)
565 return ret;
566
567 ret = vsc3308_config(VSC3308_RX_ADDRESS,
568 vsc08_rx_sfp, num_vsc08_con);
569 if (ret)
570 return ret;
Shaohui Xieb24f6d42014-11-13 11:27:49 +0800571#endif
Suresh Guptacd79e5f2014-11-13 11:27:32 +0800572 } else {
573 ret = vsc3308_config(VSC3308_TX_ADDRESS,
574 vsc08_tx_amc, num_vsc08_con);
575 if (ret)
576 return ret;
577
578 ret = vsc3308_config(VSC3308_RX_ADDRESS,
579 vsc08_rx_amc, num_vsc08_con);
580 if (ret)
581 return ret;
582 }
583
Shaohui Xie89b94d82014-11-13 11:26:19 +0800584 } else {
585 return ret;
586 }
587 break;
York Sunb5b06fb2012-12-23 19:25:27 +0000588 default:
589 printf("WARNING:VSC crossbars programming not supported for: %x"
590 " SerDes2 Protocol.\n", serdes2_prtcl);
591 return -1;
592 }
593
594 return 0;
595}
596
Shaveta Leekha7af9a072014-02-26 16:08:22 +0530597static int calibrate_pll(serdes_corenet_t *srds_regs, int pll_num)
598{
599 u32 rst_err;
600
601 /* Steps For SerDes PLLs reset and reconfiguration
602 * or PLL power-up procedure
603 */
604 debug("CALIBRATE PLL:%d\n", pll_num);
605 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
606 SRDS_RSTCTL_SDRST_B);
607 udelay(10);
608 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
609 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
610 udelay(10);
611 setbits_be32(&srds_regs->bank[pll_num].rstctl,
612 SRDS_RSTCTL_RST);
613 setbits_be32(&srds_regs->bank[pll_num].rstctl,
614 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
615 | SRDS_RSTCTL_SDRST_B));
616
617 udelay(20);
618
619 /* Check whether PLL has been locked or not */
620 rst_err = in_be32(&srds_regs->bank[pll_num].rstctl) &
621 SRDS_RSTCTL_RSTERR;
622 rst_err >>= SRDS_RSTCTL_RSTERR_SHIFT;
623 debug("RST_ERR value for PLL %d is: 0x%x:\n", pll_num, rst_err);
624 if (rst_err)
625 return rst_err;
626
627 return rst_err;
628}
629
630static int check_pll_locks(serdes_corenet_t *srds_regs, int pll_num)
631{
632 int ret = 0;
633 u32 fcap, dcbias, bcap, pllcr1, pllcr0;
634
635 if (calibrate_pll(srds_regs, pll_num)) {
636 /* STEP 1 */
637 /* Read fcap, dcbias and bcap value */
638 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
639 SRDS_PLLCR0_DCBIAS_OUT_EN);
640 fcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
641 SRDS_PLLSR2_FCAP;
642 fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
643 bcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
644 SRDS_PLLSR2_BCAP_EN;
645 bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
646 setbits_be32(&srds_regs->bank[pll_num].pllcr0,
647 SRDS_PLLCR0_DCBIAS_OUT_EN);
648 dcbias = in_be32(&srds_regs->bank[pll_num].pllsr2) &
649 SRDS_PLLSR2_DCBIAS;
650 dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
651 debug("values of bcap:%x, fcap:%x and dcbias:%x\n",
652 bcap, fcap, dcbias);
653 if (fcap == 0 && bcap == 1) {
654 /* Step 3 */
655 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
656 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
657 | SRDS_RSTCTL_SDRST_B));
658 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
659 SRDS_PLLCR1_BCAP_EN);
660 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
661 SRDS_PLLCR1_BCAP_OVD);
662 if (calibrate_pll(srds_regs, pll_num)) {
663 /*save the fcap, dcbias and bcap values*/
664 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
665 SRDS_PLLCR0_DCBIAS_OUT_EN);
666 fcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
667 & SRDS_PLLSR2_FCAP;
668 fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
669 bcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
670 & SRDS_PLLSR2_BCAP_EN;
671 bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
672 setbits_be32(&srds_regs->bank[pll_num].pllcr0,
673 SRDS_PLLCR0_DCBIAS_OUT_EN);
674 dcbias = in_be32
675 (&srds_regs->bank[pll_num].pllsr2) &
676 SRDS_PLLSR2_DCBIAS;
677 dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
678
679 /* Step 4*/
680 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
681 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
682 | SRDS_RSTCTL_SDRST_B));
683 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
684 SRDS_PLLCR1_BYP_CAL);
685 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
686 SRDS_PLLCR1_BCAP_EN);
687 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
688 SRDS_PLLCR1_BCAP_OVD);
689 /* change the fcap and dcbias to the saved
690 * values from Step 3 */
691 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
692 SRDS_PLLCR1_PLL_FCAP);
693 pllcr1 = (in_be32
694 (&srds_regs->bank[pll_num].pllcr1)|
695 (fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
696 out_be32(&srds_regs->bank[pll_num].pllcr1,
697 pllcr1);
698 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
699 SRDS_PLLCR0_DCBIAS_OVRD);
700 pllcr0 = (in_be32
701 (&srds_regs->bank[pll_num].pllcr0)|
702 (dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
703 out_be32(&srds_regs->bank[pll_num].pllcr0,
704 pllcr0);
705 ret = calibrate_pll(srds_regs, pll_num);
706 if (ret)
707 return ret;
708 } else {
709 goto out;
710 }
711 } else { /* Step 5 */
712 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
713 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
714 | SRDS_RSTCTL_SDRST_B));
715 udelay(10);
716 /* Change the fcap, dcbias, and bcap to the
717 * values from Step 1 */
718 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
719 SRDS_PLLCR1_BYP_CAL);
720 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
721 SRDS_PLLCR1_PLL_FCAP);
722 pllcr1 = (in_be32(&srds_regs->bank[pll_num].pllcr1)|
723 (fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
724 out_be32(&srds_regs->bank[pll_num].pllcr1,
725 pllcr1);
726 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
727 SRDS_PLLCR0_DCBIAS_OVRD);
728 pllcr0 = (in_be32(&srds_regs->bank[pll_num].pllcr0)|
729 (dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
730 out_be32(&srds_regs->bank[pll_num].pllcr0,
731 pllcr0);
732 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
733 SRDS_PLLCR1_BCAP_EN);
734 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
735 SRDS_PLLCR1_BCAP_OVD);
736 ret = calibrate_pll(srds_regs, pll_num);
737 if (ret)
738 return ret;
739 }
740 }
741out:
742 return 0;
743}
744
745static int check_serdes_pll_locks(void)
746{
747 serdes_corenet_t *srds1_regs =
748 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
749 serdes_corenet_t *srds2_regs =
750 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
751 int i, ret1, ret2;
752
753 debug("\nSerDes1 Lock check\n");
754 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
755 ret1 = check_pll_locks(srds1_regs, i);
756 if (ret1) {
757 printf("SerDes1, PLL:%d didnt lock\n", i);
758 return ret1;
759 }
760 }
761 debug("\nSerDes2 Lock check\n");
762 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
763 ret2 = check_pll_locks(srds2_regs, i);
764 if (ret2) {
765 printf("SerDes2, PLL:%d didnt lock\n", i);
766 return ret2;
767 }
768 }
769
770 return 0;
771}
772
Shaveta Leekhacb033742013-07-02 14:43:53 +0530773int config_serdes1_refclks(void)
774{
775 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
776 serdes_corenet_t *srds_regs =
777 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
778 u32 serdes1_prtcl, lane;
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530779 unsigned int flag_sgmii_aurora_prtcl = 0;
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530780 int i;
781 int ret = 0;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530782
783 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
784 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
785 if (!serdes1_prtcl) {
786 printf("SERDES1 is not enabled\n");
787 return -1;
788 }
789 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
790 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
791
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530792 /* To prevent generation of reset request from SerDes
793 * while changing the refclks, By setting SRDS_RST_MSK bit,
794 * SerDes reset event cannot cause a reset request
Shaveta Leekhacb033742013-07-02 14:43:53 +0530795 */
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530796 setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
797
Shaveta Leekhacb033742013-07-02 14:43:53 +0530798 /* Reconfigure IDT idt8t49n222a device for CPRI to work
799 * For this SerDes1's Refclk1 and refclk2 need to be set
800 * to 122.88MHz
801 */
802 switch (serdes1_prtcl) {
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530803 case 0x29:
Shaveta Leekhacb033742013-07-02 14:43:53 +0530804 case 0x2A:
805 case 0x2C:
806 case 0x2D:
807 case 0x2E:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530808 case 0x01:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530809 case 0x02:
810 case 0x04:
811 case 0x05:
812 case 0x06:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530813 case 0x07:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530814 case 0x08:
815 case 0x09:
816 case 0x0A:
817 case 0x0B:
818 case 0x0C:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530819 case 0x2F:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530820 case 0x30:
821 case 0x32:
822 case 0x33:
823 case 0x34:
824 case 0x39:
825 case 0x3A:
826 case 0x3C:
827 case 0x3D:
828 case 0x5C:
829 case 0x5D:
Shaveta Leekhacb033742013-07-02 14:43:53 +0530830 debug("Configuring idt8t49n222a for CPRI SerDes clks:"
831 " for srds_prctl:%x\n", serdes1_prtcl);
832 ret = select_i2c_ch_pca(I2C_CH_IDT);
833 if (!ret) {
834 ret = set_serdes_refclk(IDT_SERDES1_ADDRESS, 1,
835 SERDES_REFCLK_122_88,
836 SERDES_REFCLK_122_88, 0);
837 if (ret) {
838 printf("IDT8T49N222A configuration failed.\n");
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530839 goto out;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530840 } else
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530841 debug("IDT8T49N222A configured.\n");
Shaveta Leekhacb033742013-07-02 14:43:53 +0530842 } else {
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530843 goto out;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530844 }
845 select_i2c_ch_pca(I2C_CH_DEFAULT);
846
847 /* Change SerDes1's Refclk1 to 125MHz for on board
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530848 * SGMIIs or Aurora to work
Shaveta Leekhacb033742013-07-02 14:43:53 +0530849 */
850 for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
851 enum srds_prtcl lane_prtcl = serdes_get_prtcl
852 (0, serdes1_prtcl, lane);
853 switch (lane_prtcl) {
854 case SGMII_FM1_DTSEC1:
855 case SGMII_FM1_DTSEC2:
856 case SGMII_FM1_DTSEC3:
857 case SGMII_FM1_DTSEC4:
858 case SGMII_FM1_DTSEC5:
859 case SGMII_FM1_DTSEC6:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530860 case AURORA:
861 flag_sgmii_aurora_prtcl++;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530862 break;
863 default:
864 break;
865 }
866 }
867
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530868 if (flag_sgmii_aurora_prtcl)
Shaveta Leekhacb033742013-07-02 14:43:53 +0530869 QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
870
871 /* Steps For SerDes PLLs reset and reconfiguration after
872 * changing SerDes's refclks
873 */
Shaveta Leekhac4930b12014-02-26 16:07:51 +0530874 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
Shaveta Leekhacb033742013-07-02 14:43:53 +0530875 debug("For PLL%d reset and reconfiguration after"
876 " changing refclks\n", i+1);
877 clrbits_be32(&srds_regs->bank[i].rstctl,
878 SRDS_RSTCTL_SDRST_B);
879 udelay(10);
880 clrbits_be32(&srds_regs->bank[i].rstctl,
881 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
882 udelay(10);
883 setbits_be32(&srds_regs->bank[i].rstctl,
884 SRDS_RSTCTL_RST);
885 setbits_be32(&srds_regs->bank[i].rstctl,
886 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
887 | SRDS_RSTCTL_SDRST_B));
888 }
889 break;
890 default:
891 printf("WARNING:IDT8T49N222A configuration not"
892 " supported for:%x SerDes1 Protocol.\n",
893 serdes1_prtcl);
Shaveta Leekhacb033742013-07-02 14:43:53 +0530894 }
895
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530896out:
897 /* Clearing SRDS_RST_MSK bit as now
898 * SerDes reset event can cause a reset request
899 */
900 clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
901 return ret;
902}
903
904int config_serdes2_refclks(void)
905{
906 ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
907 serdes_corenet_t *srds2_regs =
908 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
909 u32 serdes2_prtcl;
910 int ret = 0;
911 int i;
912
913 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
914 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
915 if (!serdes2_prtcl) {
916 debug("SERDES2 is not enabled\n");
917 return -ENODEV;
918 }
919 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
920 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
921
922 /* To prevent generation of reset request from SerDes
923 * while changing the refclks, By setting SRDS_RST_MSK bit,
924 * SerDes reset event cannot cause a reset request
925 */
926 setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
927
928 /* Reconfigure IDT idt8t49n222a device for PCIe SATA to work
929 * For this SerDes2's Refclk1 need to be set to 100MHz
930 */
931 switch (serdes2_prtcl) {
poonam aggrwalfa6e7422014-05-31 00:08:18 +0530932#ifdef CONFIG_PPC_B4420
933 case 0x9d:
934#endif
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530935 case 0x9E:
936 case 0x9A:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530937 /* fallthrough */
938 case 0xb1:
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530939 case 0xb2:
940 debug("Configuring IDT for PCIe SATA for srds_prctl:%x\n",
941 serdes2_prtcl);
942 ret = select_i2c_ch_pca(I2C_CH_IDT);
943 if (!ret) {
944 ret = set_serdes_refclk(IDT_SERDES2_ADDRESS, 2,
945 SERDES_REFCLK_100,
Shaveta Leekhac4930b12014-02-26 16:07:51 +0530946 SERDES_REFCLK_156_25, 0);
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530947 if (ret) {
948 printf("IDT8T49N222A configuration failed.\n");
949 goto out;
950 } else
951 debug("IDT8T49N222A configured.\n");
952 } else {
953 goto out;
954 }
955 select_i2c_ch_pca(I2C_CH_DEFAULT);
956
957 /* Steps For SerDes PLLs reset and reconfiguration after
958 * changing SerDes's refclks
959 */
Shaveta Leekhac4930b12014-02-26 16:07:51 +0530960 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530961 clrbits_be32(&srds2_regs->bank[i].rstctl,
962 SRDS_RSTCTL_SDRST_B);
963 udelay(10);
964 clrbits_be32(&srds2_regs->bank[i].rstctl,
965 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
966 udelay(10);
967 setbits_be32(&srds2_regs->bank[i].rstctl,
968 SRDS_RSTCTL_RST);
969 setbits_be32(&srds2_regs->bank[i].rstctl,
970 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
971 | SRDS_RSTCTL_SDRST_B));
Shaveta Leekha7af9a072014-02-26 16:08:22 +0530972
973 udelay(10);
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530974 }
975 break;
976 default:
977 printf("IDT configuration not supported for:%x S2 Protocol.\n",
978 serdes2_prtcl);
979 }
980
981out:
982 /* Clearing SRDS_RST_MSK bit as now
983 * SerDes reset event can cause a reset request
984 */
985 clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
986 return ret;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530987}
988
York Sunb5b06fb2012-12-23 19:25:27 +0000989int board_early_init_r(void)
990{
991 const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
York Sun9d045682014-06-24 21:16:20 -0700992 int flash_esel = find_tlb_idx((void *)flashbase, 1);
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530993 int ret;
Shaveta Leekhaf7c28aa2014-11-12 14:23:26 +0530994 u32 svr = SVR_SOC_VER(get_svr());
995
996 /* Create law for MAPLE only for personalities having MAPLE */
997 if ((svr == SVR_B4860) || (svr == SVR_B4440) ||
998 (svr == SVR_B4420) || (svr == SVR_B4220)) {
999 set_next_law(CONFIG_SYS_MAPLE_MEM_PHYS, LAW_SIZE_16M,
1000 LAW_TRGT_IF_MAPLE);
1001 }
York Sunb5b06fb2012-12-23 19:25:27 +00001002
1003 /*
1004 * Remap Boot flash + PROMJET region to caching-inhibited
1005 * so that flash can be erased properly.
1006 */
1007
1008 /* Flush d-cache and invalidate i-cache of any FLASH data */
1009 flush_dcache();
1010 invalidate_icache();
1011
York Sun9d045682014-06-24 21:16:20 -07001012 if (flash_esel == -1) {
1013 /* very unlikely unless something is messed up */
1014 puts("Error: Could not find TLB for FLASH BASE\n");
1015 flash_esel = 2; /* give our best effort to continue */
1016 } else {
1017 /* invalidate existing TLB entry for flash + promjet */
1018 disable_tlb(flash_esel);
1019 }
York Sunb5b06fb2012-12-23 19:25:27 +00001020
1021 set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
1022 MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
1023 0, flash_esel, BOOKE_PAGESZ_256M, 1);
1024
Shaveta Leekha652e29b2014-04-11 14:12:40 +05301025 /*
1026 * Adjust core voltage according to voltage ID
1027 * This function changes I2C mux to channel 2.
1028 */
1029 if (adjust_vdd(0) < 0)
1030 printf("Warning: Adjusting core voltage failed\n");
1031
Shaveta Leekhacb033742013-07-02 14:43:53 +05301032 /* SerDes1 refclks need to be set again, as default clks
1033 * are not suitable for CPRI and onboard SGMIIs to work
1034 * simultaneously.
1035 * This function will set SerDes1's Refclk1 and refclk2
1036 * as per SerDes1 protocols
1037 */
1038 if (config_serdes1_refclks())
1039 printf("SerDes1 Refclks couldn't set properly.\n");
1040 else
1041 printf("SerDes1 Refclks have been set.\n");
York Sunb5b06fb2012-12-23 19:25:27 +00001042
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +05301043 /* SerDes2 refclks need to be set again, as default clks
1044 * are not suitable for PCIe SATA to work
1045 * This function will set SerDes2's Refclk1 and refclk2
1046 * for SerDes2 protocols having PCIe in them
1047 * for PCIe SATA to work
1048 */
1049 ret = config_serdes2_refclks();
1050 if (!ret)
1051 printf("SerDes2 Refclks have been set.\n");
1052 else if (ret == -ENODEV)
1053 printf("SerDes disable, Refclks couldn't change.\n");
1054 else
1055 printf("SerDes2 Refclk reconfiguring failed.\n");
1056
Shaveta Leekha7af9a072014-02-26 16:08:22 +05301057#if defined(CONFIG_SYS_FSL_ERRATUM_A006384) || \
1058 defined(CONFIG_SYS_FSL_ERRATUM_A006475)
1059 /* Rechecking the SerDes locks after all SerDes configurations
1060 * are done, As SerDes PLLs may not lock reliably at 5 G VCO
1061 * and at cold temperatures.
1062 * Following sequence ensure the proper locking of SerDes PLLs.
1063 */
1064 if (SVR_MAJ(get_svr()) == 1) {
1065 if (check_serdes_pll_locks())
1066 printf("SerDes plls still not locked properly.\n");
1067 else
1068 printf("SerDes plls have been locked well.\n");
1069 }
1070#endif
1071
York Sunb5b06fb2012-12-23 19:25:27 +00001072 /* Configure VSC3316 and VSC3308 crossbar switches */
1073 if (configure_vsc3316_3308())
1074 printf("VSC:failed to configure VSC3316/3308.\n");
1075 else
1076 printf("VSC:VSC3316/3308 successfully configured.\n");
1077
1078 select_i2c_ch_pca(I2C_CH_DEFAULT);
1079
1080 return 0;
1081}
1082
1083unsigned long get_board_sys_clk(void)
1084{
1085 u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
1086
1087 switch ((sysclk_conf & 0x0C) >> 2) {
1088 case QIXIS_CLK_100:
1089 return 100000000;
1090 case QIXIS_CLK_125:
1091 return 125000000;
1092 case QIXIS_CLK_133:
1093 return 133333333;
1094 }
1095 return 66666666;
1096}
1097
1098unsigned long get_board_ddr_clk(void)
1099{
1100 u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
1101
1102 switch (ddrclk_conf & 0x03) {
1103 case QIXIS_CLK_100:
1104 return 100000000;
1105 case QIXIS_CLK_125:
1106 return 125000000;
1107 case QIXIS_CLK_133:
1108 return 133333333;
1109 }
1110 return 66666666;
1111}
1112
1113static int serdes_refclock(u8 sw, u8 sdclk)
1114{
1115 unsigned int clock;
1116 int ret = -1;
1117 u8 brdcfg4;
1118
1119 if (sdclk == 1) {
1120 brdcfg4 = QIXIS_READ(brdcfg[4]);
1121 if ((brdcfg4 & CLK_MUX_SEL_MASK) == ETH_PHY_CLK_OUT)
1122 return SRDS_PLLCR0_RFCK_SEL_125;
1123 else
1124 clock = (sw >> 5) & 7;
1125 } else
1126 clock = (sw >> 6) & 3;
1127
1128 switch (clock) {
1129 case 0:
1130 ret = SRDS_PLLCR0_RFCK_SEL_100;
1131 break;
1132 case 1:
1133 ret = SRDS_PLLCR0_RFCK_SEL_125;
1134 break;
1135 case 2:
1136 ret = SRDS_PLLCR0_RFCK_SEL_156_25;
1137 break;
1138 case 3:
1139 ret = SRDS_PLLCR0_RFCK_SEL_161_13;
1140 break;
1141 case 4:
1142 case 5:
1143 case 6:
1144 ret = SRDS_PLLCR0_RFCK_SEL_122_88;
1145 break;
1146 default:
1147 ret = -1;
1148 break;
1149 }
1150
1151 return ret;
1152}
1153
York Sunb5b06fb2012-12-23 19:25:27 +00001154#define NUM_SRDS_BANKS 2
1155
1156int misc_init_r(void)
1157{
1158 u8 sw;
1159 serdes_corenet_t *srds_regs =
1160 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
1161 u32 actual[NUM_SRDS_BANKS];
1162 unsigned int i;
1163 int clock;
1164
1165 sw = QIXIS_READ(brdcfg[2]);
1166 clock = serdes_refclock(sw, 1);
1167 if (clock >= 0)
1168 actual[0] = clock;
1169 else
1170 printf("Warning: SDREFCLK1 switch setting is unsupported\n");
1171
1172 sw = QIXIS_READ(brdcfg[4]);
1173 clock = serdes_refclock(sw, 2);
1174 if (clock >= 0)
1175 actual[1] = clock;
1176 else
1177 printf("Warning: SDREFCLK2 switch setting unsupported\n");
1178
1179 for (i = 0; i < NUM_SRDS_BANKS; i++) {
1180 u32 pllcr0 = srds_regs->bank[i].pllcr0;
1181 u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK;
1182 if (expected != actual[i]) {
1183 printf("Warning: SERDES bank %u expects reference clock"
1184 " %sMHz, but actual is %sMHz\n", i + 1,
1185 serdes_clock_to_string(expected),
1186 serdes_clock_to_string(actual[i]));
1187 }
1188 }
1189
1190 return 0;
1191}
1192
Simon Glasse895a4b2014-10-23 18:58:47 -06001193int ft_board_setup(void *blob, bd_t *bd)
York Sunb5b06fb2012-12-23 19:25:27 +00001194{
1195 phys_addr_t base;
1196 phys_size_t size;
1197
1198 ft_cpu_setup(blob, bd);
1199
1200 base = getenv_bootm_low();
1201 size = getenv_bootm_size();
1202
1203 fdt_fixup_memory(blob, (u64)base, (u64)size);
1204
1205#ifdef CONFIG_PCI
1206 pci_of_setup(blob, bd);
1207#endif
1208
1209 fdt_fixup_liodn(blob);
1210
1211#ifdef CONFIG_HAS_FSL_DR_USB
Sriram Dasha5c289b2016-09-16 17:12:15 +05301212 fsl_fdt_fixup_dr_usb(blob, bd);
York Sunb5b06fb2012-12-23 19:25:27 +00001213#endif
1214
1215#ifdef CONFIG_SYS_DPAA_FMAN
1216 fdt_fixup_fman_ethernet(blob);
1217 fdt_fixup_board_enet(blob);
1218#endif
Simon Glasse895a4b2014-10-23 18:58:47 -06001219
1220 return 0;
York Sunb5b06fb2012-12-23 19:25:27 +00001221}
Shaveta Leekha43548892012-12-23 19:25:42 +00001222
1223/*
1224 * Dump board switch settings.
1225 * The bits that cannot be read/sampled via some FPGA or some
1226 * registers, they will be displayed as
1227 * underscore in binary format. mask[] has those bits.
1228 * Some bits are calculated differently than the actual switches
1229 * if booting with overriding by FPGA.
1230 */
1231void qixis_dump_switch(void)
1232{
1233 int i;
1234 u8 sw[5];
1235
1236 /*
1237 * Any bit with 1 means that bit cannot be reverse engineered.
1238 * It will be displayed as _ in binary format.
1239 */
1240 static const u8 mask[] = {0x07, 0, 0, 0xff, 0};
1241 char buf[10];
1242 u8 brdcfg[16], dutcfg[16];
1243
1244 for (i = 0; i < 16; i++) {
1245 brdcfg[i] = qixis_read(offsetof(struct qixis, brdcfg[0]) + i);
1246 dutcfg[i] = qixis_read(offsetof(struct qixis, dutcfg[0]) + i);
1247 }
1248
1249 sw[0] = ((brdcfg[0] & 0x0f) << 4) | \
1250 (brdcfg[9] & 0x08);
1251 sw[1] = ((dutcfg[1] & 0x01) << 7) | \
1252 ((dutcfg[2] & 0x07) << 4) | \
1253 ((dutcfg[6] & 0x10) >> 1) | \
1254 ((dutcfg[6] & 0x80) >> 5) | \
1255 ((dutcfg[1] & 0x40) >> 5) | \
1256 (dutcfg[6] & 0x01);
1257 sw[2] = dutcfg[0];
1258 sw[3] = 0;
1259 sw[4] = ((brdcfg[1] & 0x30) << 2) | \
1260 ((brdcfg[1] & 0xc0) >> 2) | \
1261 (brdcfg[1] & 0x0f);
1262
1263 puts("DIP switch settings:\n");
1264 for (i = 0; i < 5; i++) {
1265 printf("SW%d = 0b%s (0x%02x)\n",
1266 i + 1, byte_to_binary_mask(sw[i], mask[i], buf), sw[i]);
1267 }
1268}