blob: e7f684bfb3a4da03887a386689ce68d60c892f0a [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
York Sun0789dc92012-12-23 19:25:27 +00002/*
3 * Copyright 2011-2012 Freescale Semiconductor, Inc.
York Sun0789dc92012-12-23 19:25:27 +00004 */
5
6#include <common.h>
7#include <command.h>
Simon Glassdb229612019-08-01 09:46:42 -06008#include <env.h>
Simon Glass3bbe70c2019-12-28 10:44:54 -07009#include <fdt_support.h>
York Sun0789dc92012-12-23 19:25:27 +000010#include <i2c.h>
Simon Glassa7b51302019-11-14 12:57:46 -070011#include <init.h>
Simon Glass8f3f7612019-11-14 12:57:42 -070012#include <irq_func.h>
York Sun0789dc92012-12-23 19:25:27 +000013#include <netdev.h>
14#include <linux/compiler.h>
15#include <asm/mmu.h>
16#include <asm/processor.h>
Masahiro Yamada56a931c2016-09-21 11:28:55 +090017#include <linux/errno.h>
York Sun0789dc92012-12-23 19:25:27 +000018#include <asm/cache.h>
19#include <asm/immap_85xx.h>
20#include <asm/fsl_law.h>
21#include <asm/fsl_serdes.h>
York Sun0789dc92012-12-23 19:25:27 +000022#include <asm/fsl_liodn.h>
23#include <fm_eth.h>
Suresh Guptaf43bb232014-11-13 11:27:32 +080024#include <hwconfig.h>
York Sun0789dc92012-12-23 19:25:27 +000025
26#include "../common/qixis.h"
27#include "../common/vsc3316_3308.h"
Shaveta Leekhad1cb7742013-07-02 14:43:53 +053028#include "../common/idt8t49n222a_serdes_clk.h"
Shaveta Leekhae1b6f4c2014-04-11 14:12:40 +053029#include "../common/zm7300.h"
York Sun0789dc92012-12-23 19:25:27 +000030#include "b4860qds.h"
31#include "b4860qds_qixis.h"
32#include "b4860qds_crossbar_con.h"
33
34#define CLK_MUX_SEL_MASK 0x4
35#define ETH_PHY_CLK_OUT 0x4
36
37DECLARE_GLOBAL_DATA_PTR;
38
39int checkboard(void)
40{
41 char buf[64];
42 u8 sw;
Simon Glassa8b57392012-12-13 20:48:48 +000043 struct cpu_type *cpu = gd->arch.cpu;
York Sun0789dc92012-12-23 19:25:27 +000044 static const char *const freq[] = {"100", "125", "156.25", "161.13",
45 "122.88", "122.88", "122.88"};
46 int clock;
47
48 printf("Board: %sQDS, ", cpu->name);
49 printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, ",
50 QIXIS_READ(id), QIXIS_READ(arch));
51
52 sw = QIXIS_READ(brdcfg[0]);
53 sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
54
55 if (sw < 0x8)
56 printf("vBank: %d\n", sw);
57 else if (sw >= 0x8 && sw <= 0xE)
58 puts("NAND\n");
59 else
60 printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
61
62 printf("FPGA: v%d (%s), build %d",
63 (int)QIXIS_READ(scver), qixis_read_tag(buf),
64 (int)qixis_read_minor());
65 /* the timestamp string contains "\n" at the end */
66 printf(" on %s", qixis_read_time(buf));
67
York Sun0789dc92012-12-23 19:25:27 +000068 /*
69 * Display the actual SERDES reference clocks as configured by the
70 * dip switches on the board. Note that the SWx registers could
71 * technically be set to force the reference clocks to match the
72 * values that the SERDES expects (or vice versa). For now, however,
73 * we just display both values and hope the user notices when they
74 * don't match.
75 */
76 puts("SERDES Reference Clocks: ");
77 sw = QIXIS_READ(brdcfg[2]);
78 clock = (sw >> 5) & 7;
79 printf("Bank1=%sMHz ", freq[clock]);
80 sw = QIXIS_READ(brdcfg[4]);
81 clock = (sw >> 6) & 3;
82 printf("Bank2=%sMHz\n", freq[clock]);
83
84 return 0;
85}
86
87int select_i2c_ch_pca(u8 ch)
88{
89 int ret;
90
91 /* Selecting proper channel via PCA*/
92 ret = i2c_write(I2C_MUX_PCA_ADDR, 0x0, 1, &ch, 1);
93 if (ret) {
94 printf("PCA: failed to select proper channel.\n");
95 return ret;
96 }
97
98 return 0;
99}
100
Shaveta Leekhae1b6f4c2014-04-11 14:12:40 +0530101/*
102 * read_voltage from sensor on I2C bus
103 * We use average of 4 readings, waiting for 532us befor another reading
104 */
105#define WAIT_FOR_ADC 532 /* wait for 532 microseconds for ADC */
106#define NUM_READINGS 4 /* prefer to be power of 2 for efficiency */
107
108static inline int read_voltage(void)
109{
110 int i, ret, voltage_read = 0;
111 u16 vol_mon;
112
113 for (i = 0; i < NUM_READINGS; i++) {
114 ret = i2c_read(I2C_VOL_MONITOR_ADDR,
115 I2C_VOL_MONITOR_BUS_V_OFFSET, 1, (void *)&vol_mon, 2);
116 if (ret) {
117 printf("VID: failed to read core voltage\n");
118 return ret;
119 }
120 if (vol_mon & I2C_VOL_MONITOR_BUS_V_OVF) {
121 printf("VID: Core voltage sensor error\n");
122 return -1;
123 }
124 debug("VID: bus voltage reads 0x%04x\n", vol_mon);
125 /* LSB = 4mv */
126 voltage_read += (vol_mon >> I2C_VOL_MONITOR_BUS_V_SHIFT) * 4;
127 udelay(WAIT_FOR_ADC);
128 }
129 /* calculate the average */
130 voltage_read /= NUM_READINGS;
131
132 return voltage_read;
133}
134
135static int adjust_vdd(ulong vdd_override)
136{
137 int re_enable = disable_interrupts();
138 ccsr_gur_t __iomem *gur =
139 (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
140 u32 fusesr;
141 u8 vid;
142 int vdd_target, vdd_last;
143 int existing_voltage, temp_voltage, voltage; /* all in 1/10 mV */
144 int ret;
145 unsigned int orig_i2c_speed;
146 unsigned long vdd_string_override;
147 char *vdd_string;
148 static const uint16_t vdd[32] = {
149 0, /* unused */
150 9875, /* 0.9875V */
151 9750,
152 9625,
153 9500,
154 9375,
155 9250,
156 9125,
157 9000,
158 8875,
159 8750,
160 8625,
161 8500,
162 8375,
163 8250,
164 8125,
165 10000, /* 1.0000V */
166 10125,
167 10250,
168 10375,
169 10500,
170 10625,
171 10750,
172 10875,
173 11000,
174 0, /* reserved */
175 };
176 struct vdd_drive {
177 u8 vid;
178 unsigned voltage;
179 };
180
181 ret = select_i2c_ch_pca(I2C_MUX_CH_VOL_MONITOR);
182 if (ret) {
183 printf("VID: I2c failed to switch channel\n");
184 ret = -1;
185 goto exit;
186 }
187
188 /* get the voltage ID from fuse status register */
189 fusesr = in_be32(&gur->dcfg_fusesr);
190 vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_VID_SHIFT) &
191 FSL_CORENET_DCFG_FUSESR_VID_MASK;
192 if (vid == FSL_CORENET_DCFG_FUSESR_VID_MASK) {
193 vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_ALTVID_SHIFT) &
194 FSL_CORENET_DCFG_FUSESR_ALTVID_MASK;
195 }
196 vdd_target = vdd[vid];
197 debug("VID:Reading from from fuse,vid=%x vdd is %dmV\n",
198 vid, vdd_target/10);
199
200 /* check override variable for overriding VDD */
Simon Glass64b723f2017-08-03 12:22:12 -0600201 vdd_string = env_get("b4qds_vdd_mv");
Shaveta Leekhae1b6f4c2014-04-11 14:12:40 +0530202 if (vdd_override == 0 && vdd_string &&
203 !strict_strtoul(vdd_string, 10, &vdd_string_override))
204 vdd_override = vdd_string_override;
205 if (vdd_override >= 819 && vdd_override <= 1212) {
206 vdd_target = vdd_override * 10; /* convert to 1/10 mV */
207 debug("VDD override is %lu\n", vdd_override);
208 } else if (vdd_override != 0) {
209 printf("Invalid value.\n");
210 }
211
212 if (vdd_target == 0) {
213 printf("VID: VID not used\n");
214 ret = 0;
215 goto exit;
216 }
217
218 /*
219 * Read voltage monitor to check real voltage.
220 * Voltage monitor LSB is 4mv.
221 */
222 vdd_last = read_voltage();
223 if (vdd_last < 0) {
224 printf("VID: abort VID adjustment\n");
225 ret = -1;
226 goto exit;
227 }
228
229 debug("VID: Core voltage is at %d mV\n", vdd_last);
230 ret = select_i2c_ch_pca(I2C_MUX_CH_DPM);
231 if (ret) {
232 printf("VID: I2c failed to switch channel to DPM\n");
233 ret = -1;
234 goto exit;
235 }
236
237 /* Round up to the value of step of Voltage regulator */
238 voltage = roundup(vdd_target, ZM_STEP);
239 debug("VID: rounded up voltage = %d\n", voltage);
240
241 /* lower the speed to 100kHz to access ZM7300 device */
242 debug("VID: Setting bus speed to 100KHz if not already set\n");
243 orig_i2c_speed = i2c_get_bus_speed();
244 if (orig_i2c_speed != 100000)
245 i2c_set_bus_speed(100000);
246
247 /* Read the existing level on board, if equal to requsted one,
248 no need to re-set */
249 existing_voltage = zm_read_voltage();
250
251 /* allowing the voltage difference of one step 0.0125V acceptable */
252 if ((existing_voltage >= voltage) &&
253 (existing_voltage < (voltage + ZM_STEP))) {
254 debug("VID: voltage already set as requested,returning\n");
255 ret = existing_voltage;
256 goto out;
257 }
258 debug("VID: Changing voltage for board from %dmV to %dmV\n",
259 existing_voltage/10, voltage/10);
260
261 if (zm_disable_wp() < 0) {
262 ret = -1;
263 goto out;
264 }
265 /* Change Voltage: the change is done through all the steps in the
266 way, to avoid reset to the board due to power good signal fail
267 in big voltage change gap jump.
268 */
269 if (existing_voltage > voltage) {
270 temp_voltage = existing_voltage - ZM_STEP;
271 while (temp_voltage >= voltage) {
272 ret = zm_write_voltage(temp_voltage);
273 if (ret == temp_voltage) {
274 temp_voltage -= ZM_STEP;
275 } else {
276 /* ZM7300 device failed to set
277 * the voltage */
278 printf
279 ("VID:Stepping down vol failed:%dmV\n",
280 temp_voltage/10);
281 ret = -1;
282 goto out;
283 }
284 }
285 } else {
286 temp_voltage = existing_voltage + ZM_STEP;
287 while (temp_voltage < (voltage + ZM_STEP)) {
288 ret = zm_write_voltage(temp_voltage);
289 if (ret == temp_voltage) {
290 temp_voltage += ZM_STEP;
291 } else {
292 /* ZM7300 device failed to set
293 * the voltage */
294 printf
295 ("VID:Stepping up vol failed:%dmV\n",
296 temp_voltage/10);
297 ret = -1;
298 goto out;
299 }
300 }
301 }
302
303 if (zm_enable_wp() < 0)
304 ret = -1;
305
306 /* restore the speed to 400kHz */
307out: debug("VID: Restore the I2C bus speed to %dKHz\n",
308 orig_i2c_speed/1000);
309 i2c_set_bus_speed(orig_i2c_speed);
310 if (ret < 0)
311 goto exit;
312
313 ret = select_i2c_ch_pca(I2C_MUX_CH_VOL_MONITOR);
314 if (ret) {
315 printf("VID: I2c failed to switch channel\n");
316 ret = -1;
317 goto exit;
318 }
319 vdd_last = read_voltage();
320 select_i2c_ch_pca(I2C_CH_DEFAULT);
321
322 if (vdd_last > 0)
323 printf("VID: Core voltage %d mV\n", vdd_last);
324 else
325 ret = -1;
326
327exit:
328 if (re_enable)
329 enable_interrupts();
330 return ret;
331}
332
York Sun0789dc92012-12-23 19:25:27 +0000333int configure_vsc3316_3308(void)
334{
335 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
336 unsigned int num_vsc16_con, num_vsc08_con;
337 u32 serdes1_prtcl, serdes2_prtcl;
338 int ret;
Suresh Guptaf43bb232014-11-13 11:27:32 +0800339 char buffer[HWCONFIG_BUFFER_SIZE];
340 char *buf = NULL;
York Sun0789dc92012-12-23 19:25:27 +0000341
342 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
343 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
344 if (!serdes1_prtcl) {
345 printf("SERDES1 is not enabled\n");
346 return 0;
347 }
348 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
349 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
350
351 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
352 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
353 if (!serdes2_prtcl) {
354 printf("SERDES2 is not enabled\n");
355 return 0;
356 }
357 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
358 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
359
360 switch (serdes1_prtcl) {
poonam aggrwal331dd1d2014-02-17 08:38:58 +0530361 case 0x29:
York Sun0789dc92012-12-23 19:25:27 +0000362 case 0x2a:
363 case 0x2C:
364 case 0x2D:
365 case 0x2E:
366 /*
367 * Configuration:
368 * SERDES: 1
369 * Lanes: A,B: SGMII
370 * Lanes: C,D,E,F,G,H: CPRI
371 */
372 debug("Configuring crossbar to use onboard SGMII PHYs:"
373 "srds_prctl:%x\n", serdes1_prtcl);
374 num_vsc16_con = NUM_CON_VSC3316;
375 /* Configure VSC3316 crossbar switch */
376 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
377 if (!ret) {
378 ret = vsc3316_config(VSC3316_TX_ADDRESS,
Shaveta Leekha93201602013-03-25 07:40:17 +0000379 vsc16_tx_4sfp_sgmii_12_56,
380 num_vsc16_con);
York Sun0789dc92012-12-23 19:25:27 +0000381 if (ret)
382 return ret;
383 ret = vsc3316_config(VSC3316_RX_ADDRESS,
Shaveta Leekha93201602013-03-25 07:40:17 +0000384 vsc16_rx_4sfp_sgmii_12_56,
385 num_vsc16_con);
York Sun0789dc92012-12-23 19:25:27 +0000386 if (ret)
387 return ret;
388 } else {
389 return ret;
390 }
391 break;
392
Shaveta Leekhab900a612014-11-12 16:00:44 +0530393 case 0x01:
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530394 case 0x02:
395 case 0x04:
396 case 0x05:
397 case 0x06:
Shaveta Leekhab900a612014-11-12 16:00:44 +0530398 case 0x07:
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530399 case 0x08:
400 case 0x09:
401 case 0x0A:
402 case 0x0B:
403 case 0x0C:
Shaveta Leekhab900a612014-11-12 16:00:44 +0530404 case 0x2F:
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530405 case 0x30:
406 case 0x32:
407 case 0x33:
408 case 0x34:
409 case 0x39:
410 case 0x3A:
411 case 0x3C:
412 case 0x3D:
413 case 0x5C:
414 case 0x5D:
415 /*
416 * Configuration:
417 * SERDES: 1
418 * Lanes: A,B: AURORA
419 * Lanes: C,d: SGMII
420 * Lanes: E,F,G,H: CPRI
421 */
422 debug("Configuring crossbar for Aurora, SGMII 3 and 4,"
423 " and CPRI. srds_prctl:%x\n", serdes1_prtcl);
424 num_vsc16_con = NUM_CON_VSC3316;
425 /* Configure VSC3316 crossbar switch */
426 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
427 if (!ret) {
428 ret = vsc3316_config(VSC3316_TX_ADDRESS,
429 vsc16_tx_sfp_sgmii_aurora,
430 num_vsc16_con);
431 if (ret)
432 return ret;
433 ret = vsc3316_config(VSC3316_RX_ADDRESS,
434 vsc16_rx_sfp_sgmii_aurora,
435 num_vsc16_con);
436 if (ret)
437 return ret;
438 } else {
439 return ret;
440 }
441 break;
442
York Sunfda566d2016-11-18 11:56:57 -0800443#ifdef CONFIG_ARCH_B4420
poonam aggrwal331dd1d2014-02-17 08:38:58 +0530444 case 0x17:
York Sun0789dc92012-12-23 19:25:27 +0000445 case 0x18:
446 /*
447 * Configuration:
448 * SERDES: 1
449 * Lanes: A,B,C,D: SGMII
450 * Lanes: E,F,G,H: CPRI
451 */
452 debug("Configuring crossbar to use onboard SGMII PHYs:"
453 "srds_prctl:%x\n", serdes1_prtcl);
454 num_vsc16_con = NUM_CON_VSC3316;
455 /* Configure VSC3316 crossbar switch */
456 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
457 if (!ret) {
458 ret = vsc3316_config(VSC3316_TX_ADDRESS,
459 vsc16_tx_sgmii_lane_cd, num_vsc16_con);
460 if (ret)
461 return ret;
462 ret = vsc3316_config(VSC3316_RX_ADDRESS,
463 vsc16_rx_sgmii_lane_cd, num_vsc16_con);
464 if (ret)
465 return ret;
466 } else {
467 return ret;
468 }
469 break;
470#endif
471
472 case 0x3E:
473 case 0x0D:
474 case 0x0E:
475 case 0x12:
476 num_vsc16_con = NUM_CON_VSC3316;
477 /* Configure VSC3316 crossbar switch */
478 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
479 if (!ret) {
480 ret = vsc3316_config(VSC3316_TX_ADDRESS,
481 vsc16_tx_sfp, num_vsc16_con);
482 if (ret)
483 return ret;
484 ret = vsc3316_config(VSC3316_RX_ADDRESS,
485 vsc16_rx_sfp, num_vsc16_con);
486 if (ret)
487 return ret;
488 } else {
489 return ret;
490 }
491 break;
492 default:
493 printf("WARNING:VSC crossbars programming not supported for:%x"
494 " SerDes1 Protocol.\n", serdes1_prtcl);
495 return -1;
496 }
497
Shaohui Xie37c82b52014-11-13 11:26:19 +0800498 num_vsc08_con = NUM_CON_VSC3308;
499 /* Configure VSC3308 crossbar switch */
500 ret = select_i2c_ch_pca(I2C_CH_VSC3308);
York Sun0789dc92012-12-23 19:25:27 +0000501 switch (serdes2_prtcl) {
York Sunfda566d2016-11-18 11:56:57 -0800502#ifdef CONFIG_ARCH_B4420
poonam aggrwal1e9956b2014-05-31 00:08:18 +0530503 case 0x9d:
504#endif
York Sun0789dc92012-12-23 19:25:27 +0000505 case 0x9E:
506 case 0x9A:
507 case 0x98:
Shaveta Leekhab900a612014-11-12 16:00:44 +0530508 case 0x48:
York Sun0789dc92012-12-23 19:25:27 +0000509 case 0x49:
510 case 0x4E:
Shaveta Leekhab900a612014-11-12 16:00:44 +0530511 case 0x79:
York Sun0789dc92012-12-23 19:25:27 +0000512 case 0x7A:
York Sun0789dc92012-12-23 19:25:27 +0000513 if (!ret) {
514 ret = vsc3308_config(VSC3308_TX_ADDRESS,
515 vsc08_tx_amc, num_vsc08_con);
516 if (ret)
517 return ret;
518 ret = vsc3308_config(VSC3308_RX_ADDRESS,
519 vsc08_rx_amc, num_vsc08_con);
520 if (ret)
521 return ret;
522 } else {
523 return ret;
524 }
525 break;
Shaohui Xie37c82b52014-11-13 11:26:19 +0800526 case 0x80:
527 case 0x81:
528 case 0x82:
529 case 0x83:
530 case 0x84:
531 case 0x85:
532 case 0x86:
533 case 0x87:
534 case 0x88:
535 case 0x89:
536 case 0x8a:
537 case 0x8b:
538 case 0x8c:
539 case 0x8d:
540 case 0x8e:
541 case 0xb1:
542 case 0xb2:
543 if (!ret) {
Suresh Guptaf43bb232014-11-13 11:27:32 +0800544 /*
545 * Extract hwconfig from environment since environment
546 * is not setup properly yet
547 */
Simon Glass64b723f2017-08-03 12:22:12 -0600548 env_get_f("hwconfig", buffer, sizeof(buffer));
Suresh Guptaf43bb232014-11-13 11:27:32 +0800549 buf = buffer;
550
551 if (hwconfig_subarg_cmp_f("fsl_b4860_serdes2",
552 "sfp_amc", "sfp", buf)) {
Shaohui Xie60c3b092014-11-13 11:27:49 +0800553#ifdef CONFIG_SYS_FSL_B4860QDS_XFI_ERR
554 /* change default VSC3308 for XFI erratum */
555 ret = vsc3308_config_adjust(VSC3308_TX_ADDRESS,
556 vsc08_tx_sfp, num_vsc08_con);
557 if (ret)
558 return ret;
559
560 ret = vsc3308_config_adjust(VSC3308_RX_ADDRESS,
561 vsc08_rx_sfp, num_vsc08_con);
562 if (ret)
563 return ret;
564#else
Suresh Guptaf43bb232014-11-13 11:27:32 +0800565 ret = vsc3308_config(VSC3308_TX_ADDRESS,
566 vsc08_tx_sfp, num_vsc08_con);
567 if (ret)
568 return ret;
569
570 ret = vsc3308_config(VSC3308_RX_ADDRESS,
571 vsc08_rx_sfp, num_vsc08_con);
572 if (ret)
573 return ret;
Shaohui Xie60c3b092014-11-13 11:27:49 +0800574#endif
Suresh Guptaf43bb232014-11-13 11:27:32 +0800575 } else {
576 ret = vsc3308_config(VSC3308_TX_ADDRESS,
577 vsc08_tx_amc, num_vsc08_con);
578 if (ret)
579 return ret;
580
581 ret = vsc3308_config(VSC3308_RX_ADDRESS,
582 vsc08_rx_amc, num_vsc08_con);
583 if (ret)
584 return ret;
585 }
586
Shaohui Xie37c82b52014-11-13 11:26:19 +0800587 } else {
588 return ret;
589 }
590 break;
York Sun0789dc92012-12-23 19:25:27 +0000591 default:
592 printf("WARNING:VSC crossbars programming not supported for: %x"
593 " SerDes2 Protocol.\n", serdes2_prtcl);
594 return -1;
595 }
596
597 return 0;
598}
599
Shaveta Leekhad11523b2014-02-26 16:08:22 +0530600static int calibrate_pll(serdes_corenet_t *srds_regs, int pll_num)
601{
602 u32 rst_err;
603
604 /* Steps For SerDes PLLs reset and reconfiguration
605 * or PLL power-up procedure
606 */
607 debug("CALIBRATE PLL:%d\n", pll_num);
608 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
609 SRDS_RSTCTL_SDRST_B);
610 udelay(10);
611 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
612 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
613 udelay(10);
614 setbits_be32(&srds_regs->bank[pll_num].rstctl,
615 SRDS_RSTCTL_RST);
616 setbits_be32(&srds_regs->bank[pll_num].rstctl,
617 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
618 | SRDS_RSTCTL_SDRST_B));
619
620 udelay(20);
621
622 /* Check whether PLL has been locked or not */
623 rst_err = in_be32(&srds_regs->bank[pll_num].rstctl) &
624 SRDS_RSTCTL_RSTERR;
625 rst_err >>= SRDS_RSTCTL_RSTERR_SHIFT;
626 debug("RST_ERR value for PLL %d is: 0x%x:\n", pll_num, rst_err);
627 if (rst_err)
628 return rst_err;
629
630 return rst_err;
631}
632
633static int check_pll_locks(serdes_corenet_t *srds_regs, int pll_num)
634{
635 int ret = 0;
636 u32 fcap, dcbias, bcap, pllcr1, pllcr0;
637
638 if (calibrate_pll(srds_regs, pll_num)) {
639 /* STEP 1 */
640 /* Read fcap, dcbias and bcap value */
641 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
642 SRDS_PLLCR0_DCBIAS_OUT_EN);
643 fcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
644 SRDS_PLLSR2_FCAP;
645 fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
646 bcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
647 SRDS_PLLSR2_BCAP_EN;
648 bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
649 setbits_be32(&srds_regs->bank[pll_num].pllcr0,
650 SRDS_PLLCR0_DCBIAS_OUT_EN);
651 dcbias = in_be32(&srds_regs->bank[pll_num].pllsr2) &
652 SRDS_PLLSR2_DCBIAS;
653 dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
654 debug("values of bcap:%x, fcap:%x and dcbias:%x\n",
655 bcap, fcap, dcbias);
656 if (fcap == 0 && bcap == 1) {
657 /* Step 3 */
658 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
659 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
660 | SRDS_RSTCTL_SDRST_B));
661 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
662 SRDS_PLLCR1_BCAP_EN);
663 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
664 SRDS_PLLCR1_BCAP_OVD);
665 if (calibrate_pll(srds_regs, pll_num)) {
666 /*save the fcap, dcbias and bcap values*/
667 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
668 SRDS_PLLCR0_DCBIAS_OUT_EN);
669 fcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
670 & SRDS_PLLSR2_FCAP;
671 fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
672 bcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
673 & SRDS_PLLSR2_BCAP_EN;
674 bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
675 setbits_be32(&srds_regs->bank[pll_num].pllcr0,
676 SRDS_PLLCR0_DCBIAS_OUT_EN);
677 dcbias = in_be32
678 (&srds_regs->bank[pll_num].pllsr2) &
679 SRDS_PLLSR2_DCBIAS;
680 dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
681
682 /* Step 4*/
683 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
684 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
685 | SRDS_RSTCTL_SDRST_B));
686 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
687 SRDS_PLLCR1_BYP_CAL);
688 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
689 SRDS_PLLCR1_BCAP_EN);
690 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
691 SRDS_PLLCR1_BCAP_OVD);
692 /* change the fcap and dcbias to the saved
693 * values from Step 3 */
694 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
695 SRDS_PLLCR1_PLL_FCAP);
696 pllcr1 = (in_be32
697 (&srds_regs->bank[pll_num].pllcr1)|
698 (fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
699 out_be32(&srds_regs->bank[pll_num].pllcr1,
700 pllcr1);
701 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
702 SRDS_PLLCR0_DCBIAS_OVRD);
703 pllcr0 = (in_be32
704 (&srds_regs->bank[pll_num].pllcr0)|
705 (dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
706 out_be32(&srds_regs->bank[pll_num].pllcr0,
707 pllcr0);
708 ret = calibrate_pll(srds_regs, pll_num);
709 if (ret)
710 return ret;
711 } else {
712 goto out;
713 }
714 } else { /* Step 5 */
715 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
716 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
717 | SRDS_RSTCTL_SDRST_B));
718 udelay(10);
719 /* Change the fcap, dcbias, and bcap to the
720 * values from Step 1 */
721 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
722 SRDS_PLLCR1_BYP_CAL);
723 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
724 SRDS_PLLCR1_PLL_FCAP);
725 pllcr1 = (in_be32(&srds_regs->bank[pll_num].pllcr1)|
726 (fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
727 out_be32(&srds_regs->bank[pll_num].pllcr1,
728 pllcr1);
729 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
730 SRDS_PLLCR0_DCBIAS_OVRD);
731 pllcr0 = (in_be32(&srds_regs->bank[pll_num].pllcr0)|
732 (dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
733 out_be32(&srds_regs->bank[pll_num].pllcr0,
734 pllcr0);
735 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
736 SRDS_PLLCR1_BCAP_EN);
737 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
738 SRDS_PLLCR1_BCAP_OVD);
739 ret = calibrate_pll(srds_regs, pll_num);
740 if (ret)
741 return ret;
742 }
743 }
744out:
745 return 0;
746}
747
748static int check_serdes_pll_locks(void)
749{
750 serdes_corenet_t *srds1_regs =
751 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
752 serdes_corenet_t *srds2_regs =
753 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
754 int i, ret1, ret2;
755
756 debug("\nSerDes1 Lock check\n");
757 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
758 ret1 = check_pll_locks(srds1_regs, i);
759 if (ret1) {
760 printf("SerDes1, PLL:%d didnt lock\n", i);
761 return ret1;
762 }
763 }
764 debug("\nSerDes2 Lock check\n");
765 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
766 ret2 = check_pll_locks(srds2_regs, i);
767 if (ret2) {
768 printf("SerDes2, PLL:%d didnt lock\n", i);
769 return ret2;
770 }
771 }
772
773 return 0;
774}
775
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530776int config_serdes1_refclks(void)
777{
778 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
779 serdes_corenet_t *srds_regs =
780 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
781 u32 serdes1_prtcl, lane;
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530782 unsigned int flag_sgmii_aurora_prtcl = 0;
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530783 int i;
784 int ret = 0;
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530785
786 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
787 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
788 if (!serdes1_prtcl) {
789 printf("SERDES1 is not enabled\n");
790 return -1;
791 }
792 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
793 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
794
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530795 /* To prevent generation of reset request from SerDes
796 * while changing the refclks, By setting SRDS_RST_MSK bit,
797 * SerDes reset event cannot cause a reset request
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530798 */
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530799 setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
800
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530801 /* Reconfigure IDT idt8t49n222a device for CPRI to work
802 * For this SerDes1's Refclk1 and refclk2 need to be set
803 * to 122.88MHz
804 */
805 switch (serdes1_prtcl) {
Shaveta Leekhab900a612014-11-12 16:00:44 +0530806 case 0x29:
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530807 case 0x2A:
808 case 0x2C:
809 case 0x2D:
810 case 0x2E:
Shaveta Leekhab900a612014-11-12 16:00:44 +0530811 case 0x01:
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530812 case 0x02:
813 case 0x04:
814 case 0x05:
815 case 0x06:
Shaveta Leekhab900a612014-11-12 16:00:44 +0530816 case 0x07:
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530817 case 0x08:
818 case 0x09:
819 case 0x0A:
820 case 0x0B:
821 case 0x0C:
Shaveta Leekhab900a612014-11-12 16:00:44 +0530822 case 0x2F:
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530823 case 0x30:
824 case 0x32:
825 case 0x33:
826 case 0x34:
827 case 0x39:
828 case 0x3A:
829 case 0x3C:
830 case 0x3D:
831 case 0x5C:
832 case 0x5D:
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530833 debug("Configuring idt8t49n222a for CPRI SerDes clks:"
834 " for srds_prctl:%x\n", serdes1_prtcl);
835 ret = select_i2c_ch_pca(I2C_CH_IDT);
836 if (!ret) {
837 ret = set_serdes_refclk(IDT_SERDES1_ADDRESS, 1,
838 SERDES_REFCLK_122_88,
839 SERDES_REFCLK_122_88, 0);
840 if (ret) {
841 printf("IDT8T49N222A configuration failed.\n");
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530842 goto out;
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530843 } else
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530844 debug("IDT8T49N222A configured.\n");
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530845 } else {
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530846 goto out;
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530847 }
848 select_i2c_ch_pca(I2C_CH_DEFAULT);
849
850 /* Change SerDes1's Refclk1 to 125MHz for on board
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530851 * SGMIIs or Aurora to work
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530852 */
853 for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
854 enum srds_prtcl lane_prtcl = serdes_get_prtcl
855 (0, serdes1_prtcl, lane);
856 switch (lane_prtcl) {
857 case SGMII_FM1_DTSEC1:
858 case SGMII_FM1_DTSEC2:
859 case SGMII_FM1_DTSEC3:
860 case SGMII_FM1_DTSEC4:
861 case SGMII_FM1_DTSEC5:
862 case SGMII_FM1_DTSEC6:
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530863 case AURORA:
864 flag_sgmii_aurora_prtcl++;
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530865 break;
866 default:
867 break;
868 }
869 }
870
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530871 if (flag_sgmii_aurora_prtcl)
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530872 QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
873
874 /* Steps For SerDes PLLs reset and reconfiguration after
875 * changing SerDes's refclks
876 */
Shaveta Leekha7e1ee692014-02-26 16:07:51 +0530877 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530878 debug("For PLL%d reset and reconfiguration after"
879 " changing refclks\n", i+1);
880 clrbits_be32(&srds_regs->bank[i].rstctl,
881 SRDS_RSTCTL_SDRST_B);
882 udelay(10);
883 clrbits_be32(&srds_regs->bank[i].rstctl,
884 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
885 udelay(10);
886 setbits_be32(&srds_regs->bank[i].rstctl,
887 SRDS_RSTCTL_RST);
888 setbits_be32(&srds_regs->bank[i].rstctl,
889 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
890 | SRDS_RSTCTL_SDRST_B));
891 }
892 break;
893 default:
894 printf("WARNING:IDT8T49N222A configuration not"
895 " supported for:%x SerDes1 Protocol.\n",
896 serdes1_prtcl);
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530897 }
898
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530899out:
900 /* Clearing SRDS_RST_MSK bit as now
901 * SerDes reset event can cause a reset request
902 */
903 clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
904 return ret;
905}
906
907int config_serdes2_refclks(void)
908{
909 ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
910 serdes_corenet_t *srds2_regs =
911 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
912 u32 serdes2_prtcl;
913 int ret = 0;
914 int i;
915
916 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
917 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
918 if (!serdes2_prtcl) {
919 debug("SERDES2 is not enabled\n");
920 return -ENODEV;
921 }
922 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
923 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
924
925 /* To prevent generation of reset request from SerDes
926 * while changing the refclks, By setting SRDS_RST_MSK bit,
927 * SerDes reset event cannot cause a reset request
928 */
929 setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
930
931 /* Reconfigure IDT idt8t49n222a device for PCIe SATA to work
932 * For this SerDes2's Refclk1 need to be set to 100MHz
933 */
934 switch (serdes2_prtcl) {
York Sunfda566d2016-11-18 11:56:57 -0800935#ifdef CONFIG_ARCH_B4420
poonam aggrwal1e9956b2014-05-31 00:08:18 +0530936 case 0x9d:
937#endif
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530938 case 0x9E:
939 case 0x9A:
Shaveta Leekhab900a612014-11-12 16:00:44 +0530940 /* fallthrough */
941 case 0xb1:
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530942 case 0xb2:
943 debug("Configuring IDT for PCIe SATA for srds_prctl:%x\n",
944 serdes2_prtcl);
945 ret = select_i2c_ch_pca(I2C_CH_IDT);
946 if (!ret) {
947 ret = set_serdes_refclk(IDT_SERDES2_ADDRESS, 2,
948 SERDES_REFCLK_100,
Shaveta Leekha7e1ee692014-02-26 16:07:51 +0530949 SERDES_REFCLK_156_25, 0);
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530950 if (ret) {
951 printf("IDT8T49N222A configuration failed.\n");
952 goto out;
953 } else
954 debug("IDT8T49N222A configured.\n");
955 } else {
956 goto out;
957 }
958 select_i2c_ch_pca(I2C_CH_DEFAULT);
959
960 /* Steps For SerDes PLLs reset and reconfiguration after
961 * changing SerDes's refclks
962 */
Shaveta Leekha7e1ee692014-02-26 16:07:51 +0530963 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530964 clrbits_be32(&srds2_regs->bank[i].rstctl,
965 SRDS_RSTCTL_SDRST_B);
966 udelay(10);
967 clrbits_be32(&srds2_regs->bank[i].rstctl,
968 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
969 udelay(10);
970 setbits_be32(&srds2_regs->bank[i].rstctl,
971 SRDS_RSTCTL_RST);
972 setbits_be32(&srds2_regs->bank[i].rstctl,
973 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
974 | SRDS_RSTCTL_SDRST_B));
Shaveta Leekhad11523b2014-02-26 16:08:22 +0530975
976 udelay(10);
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530977 }
978 break;
979 default:
980 printf("IDT configuration not supported for:%x S2 Protocol.\n",
981 serdes2_prtcl);
982 }
983
984out:
985 /* Clearing SRDS_RST_MSK bit as now
986 * SerDes reset event can cause a reset request
987 */
988 clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
989 return ret;
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530990}
991
York Sun0789dc92012-12-23 19:25:27 +0000992int board_early_init_r(void)
993{
994 const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
York Sun220c3462014-06-24 21:16:20 -0700995 int flash_esel = find_tlb_idx((void *)flashbase, 1);
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530996 int ret;
Shaveta Leekha1b636352014-11-12 14:23:26 +0530997 u32 svr = SVR_SOC_VER(get_svr());
998
999 /* Create law for MAPLE only for personalities having MAPLE */
1000 if ((svr == SVR_B4860) || (svr == SVR_B4440) ||
1001 (svr == SVR_B4420) || (svr == SVR_B4220)) {
1002 set_next_law(CONFIG_SYS_MAPLE_MEM_PHYS, LAW_SIZE_16M,
1003 LAW_TRGT_IF_MAPLE);
1004 }
York Sun0789dc92012-12-23 19:25:27 +00001005
1006 /*
1007 * Remap Boot flash + PROMJET region to caching-inhibited
1008 * so that flash can be erased properly.
1009 */
1010
1011 /* Flush d-cache and invalidate i-cache of any FLASH data */
1012 flush_dcache();
1013 invalidate_icache();
1014
York Sun220c3462014-06-24 21:16:20 -07001015 if (flash_esel == -1) {
1016 /* very unlikely unless something is messed up */
1017 puts("Error: Could not find TLB for FLASH BASE\n");
1018 flash_esel = 2; /* give our best effort to continue */
1019 } else {
1020 /* invalidate existing TLB entry for flash + promjet */
1021 disable_tlb(flash_esel);
1022 }
York Sun0789dc92012-12-23 19:25:27 +00001023
1024 set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
1025 MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
1026 0, flash_esel, BOOKE_PAGESZ_256M, 1);
1027
Shaveta Leekhae1b6f4c2014-04-11 14:12:40 +05301028 /*
1029 * Adjust core voltage according to voltage ID
1030 * This function changes I2C mux to channel 2.
1031 */
1032 if (adjust_vdd(0) < 0)
1033 printf("Warning: Adjusting core voltage failed\n");
1034
Shaveta Leekhad1cb7742013-07-02 14:43:53 +05301035 /* SerDes1 refclks need to be set again, as default clks
1036 * are not suitable for CPRI and onboard SGMIIs to work
1037 * simultaneously.
1038 * This function will set SerDes1's Refclk1 and refclk2
1039 * as per SerDes1 protocols
1040 */
1041 if (config_serdes1_refclks())
1042 printf("SerDes1 Refclks couldn't set properly.\n");
1043 else
1044 printf("SerDes1 Refclks have been set.\n");
York Sun0789dc92012-12-23 19:25:27 +00001045
Shaveta Leekha2145a3e2014-02-26 16:06:56 +05301046 /* SerDes2 refclks need to be set again, as default clks
1047 * are not suitable for PCIe SATA to work
1048 * This function will set SerDes2's Refclk1 and refclk2
1049 * for SerDes2 protocols having PCIe in them
1050 * for PCIe SATA to work
1051 */
1052 ret = config_serdes2_refclks();
1053 if (!ret)
1054 printf("SerDes2 Refclks have been set.\n");
1055 else if (ret == -ENODEV)
1056 printf("SerDes disable, Refclks couldn't change.\n");
1057 else
1058 printf("SerDes2 Refclk reconfiguring failed.\n");
1059
Shaveta Leekhad11523b2014-02-26 16:08:22 +05301060#if defined(CONFIG_SYS_FSL_ERRATUM_A006384) || \
1061 defined(CONFIG_SYS_FSL_ERRATUM_A006475)
1062 /* Rechecking the SerDes locks after all SerDes configurations
1063 * are done, As SerDes PLLs may not lock reliably at 5 G VCO
1064 * and at cold temperatures.
1065 * Following sequence ensure the proper locking of SerDes PLLs.
1066 */
1067 if (SVR_MAJ(get_svr()) == 1) {
1068 if (check_serdes_pll_locks())
1069 printf("SerDes plls still not locked properly.\n");
1070 else
1071 printf("SerDes plls have been locked well.\n");
1072 }
1073#endif
1074
York Sun0789dc92012-12-23 19:25:27 +00001075 /* Configure VSC3316 and VSC3308 crossbar switches */
1076 if (configure_vsc3316_3308())
1077 printf("VSC:failed to configure VSC3316/3308.\n");
1078 else
1079 printf("VSC:VSC3316/3308 successfully configured.\n");
1080
1081 select_i2c_ch_pca(I2C_CH_DEFAULT);
1082
1083 return 0;
1084}
1085
1086unsigned long get_board_sys_clk(void)
1087{
1088 u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
1089
1090 switch ((sysclk_conf & 0x0C) >> 2) {
1091 case QIXIS_CLK_100:
1092 return 100000000;
1093 case QIXIS_CLK_125:
1094 return 125000000;
1095 case QIXIS_CLK_133:
1096 return 133333333;
1097 }
1098 return 66666666;
1099}
1100
1101unsigned long get_board_ddr_clk(void)
1102{
1103 u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
1104
1105 switch (ddrclk_conf & 0x03) {
1106 case QIXIS_CLK_100:
1107 return 100000000;
1108 case QIXIS_CLK_125:
1109 return 125000000;
1110 case QIXIS_CLK_133:
1111 return 133333333;
1112 }
1113 return 66666666;
1114}
1115
1116static int serdes_refclock(u8 sw, u8 sdclk)
1117{
1118 unsigned int clock;
1119 int ret = -1;
1120 u8 brdcfg4;
1121
1122 if (sdclk == 1) {
1123 brdcfg4 = QIXIS_READ(brdcfg[4]);
1124 if ((brdcfg4 & CLK_MUX_SEL_MASK) == ETH_PHY_CLK_OUT)
1125 return SRDS_PLLCR0_RFCK_SEL_125;
1126 else
1127 clock = (sw >> 5) & 7;
1128 } else
1129 clock = (sw >> 6) & 3;
1130
1131 switch (clock) {
1132 case 0:
1133 ret = SRDS_PLLCR0_RFCK_SEL_100;
1134 break;
1135 case 1:
1136 ret = SRDS_PLLCR0_RFCK_SEL_125;
1137 break;
1138 case 2:
1139 ret = SRDS_PLLCR0_RFCK_SEL_156_25;
1140 break;
1141 case 3:
1142 ret = SRDS_PLLCR0_RFCK_SEL_161_13;
1143 break;
1144 case 4:
1145 case 5:
1146 case 6:
1147 ret = SRDS_PLLCR0_RFCK_SEL_122_88;
1148 break;
1149 default:
1150 ret = -1;
1151 break;
1152 }
1153
1154 return ret;
1155}
1156
York Sun0789dc92012-12-23 19:25:27 +00001157#define NUM_SRDS_BANKS 2
1158
1159int misc_init_r(void)
1160{
1161 u8 sw;
1162 serdes_corenet_t *srds_regs =
1163 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
1164 u32 actual[NUM_SRDS_BANKS];
1165 unsigned int i;
1166 int clock;
1167
1168 sw = QIXIS_READ(brdcfg[2]);
1169 clock = serdes_refclock(sw, 1);
1170 if (clock >= 0)
1171 actual[0] = clock;
1172 else
1173 printf("Warning: SDREFCLK1 switch setting is unsupported\n");
1174
1175 sw = QIXIS_READ(brdcfg[4]);
1176 clock = serdes_refclock(sw, 2);
1177 if (clock >= 0)
1178 actual[1] = clock;
1179 else
1180 printf("Warning: SDREFCLK2 switch setting unsupported\n");
1181
1182 for (i = 0; i < NUM_SRDS_BANKS; i++) {
1183 u32 pllcr0 = srds_regs->bank[i].pllcr0;
1184 u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK;
1185 if (expected != actual[i]) {
1186 printf("Warning: SERDES bank %u expects reference clock"
1187 " %sMHz, but actual is %sMHz\n", i + 1,
1188 serdes_clock_to_string(expected),
1189 serdes_clock_to_string(actual[i]));
1190 }
1191 }
1192
1193 return 0;
1194}
1195
Simon Glass2aec3cc2014-10-23 18:58:47 -06001196int ft_board_setup(void *blob, bd_t *bd)
York Sun0789dc92012-12-23 19:25:27 +00001197{
1198 phys_addr_t base;
1199 phys_size_t size;
1200
1201 ft_cpu_setup(blob, bd);
1202
Simon Glassda1a1342017-08-03 12:22:15 -06001203 base = env_get_bootm_low();
1204 size = env_get_bootm_size();
York Sun0789dc92012-12-23 19:25:27 +00001205
1206 fdt_fixup_memory(blob, (u64)base, (u64)size);
1207
1208#ifdef CONFIG_PCI
1209 pci_of_setup(blob, bd);
1210#endif
1211
1212 fdt_fixup_liodn(blob);
1213
1214#ifdef CONFIG_HAS_FSL_DR_USB
Sriram Dash9fd465c2016-09-16 17:12:15 +05301215 fsl_fdt_fixup_dr_usb(blob, bd);
York Sun0789dc92012-12-23 19:25:27 +00001216#endif
1217
1218#ifdef CONFIG_SYS_DPAA_FMAN
1219 fdt_fixup_fman_ethernet(blob);
1220 fdt_fixup_board_enet(blob);
1221#endif
Simon Glass2aec3cc2014-10-23 18:58:47 -06001222
1223 return 0;
York Sun0789dc92012-12-23 19:25:27 +00001224}
Shaveta Leekha6942b482012-12-23 19:25:42 +00001225
1226/*
1227 * Dump board switch settings.
1228 * The bits that cannot be read/sampled via some FPGA or some
1229 * registers, they will be displayed as
1230 * underscore in binary format. mask[] has those bits.
1231 * Some bits are calculated differently than the actual switches
1232 * if booting with overriding by FPGA.
1233 */
1234void qixis_dump_switch(void)
1235{
1236 int i;
1237 u8 sw[5];
1238
1239 /*
1240 * Any bit with 1 means that bit cannot be reverse engineered.
1241 * It will be displayed as _ in binary format.
1242 */
1243 static const u8 mask[] = {0x07, 0, 0, 0xff, 0};
1244 char buf[10];
1245 u8 brdcfg[16], dutcfg[16];
1246
1247 for (i = 0; i < 16; i++) {
1248 brdcfg[i] = qixis_read(offsetof(struct qixis, brdcfg[0]) + i);
1249 dutcfg[i] = qixis_read(offsetof(struct qixis, dutcfg[0]) + i);
1250 }
1251
1252 sw[0] = ((brdcfg[0] & 0x0f) << 4) | \
1253 (brdcfg[9] & 0x08);
1254 sw[1] = ((dutcfg[1] & 0x01) << 7) | \
1255 ((dutcfg[2] & 0x07) << 4) | \
1256 ((dutcfg[6] & 0x10) >> 1) | \
1257 ((dutcfg[6] & 0x80) >> 5) | \
1258 ((dutcfg[1] & 0x40) >> 5) | \
1259 (dutcfg[6] & 0x01);
1260 sw[2] = dutcfg[0];
1261 sw[3] = 0;
1262 sw[4] = ((brdcfg[1] & 0x30) << 2) | \
1263 ((brdcfg[1] & 0xc0) >> 2) | \
1264 (brdcfg[1] & 0x0f);
1265
1266 puts("DIP switch settings:\n");
1267 for (i = 0; i < 5; i++) {
1268 printf("SW%d = 0b%s (0x%02x)\n",
1269 i + 1, byte_to_binary_mask(sw[i], mask[i], buf), sw[i]);
1270 }
1271}