blob: eed379a9eb5f4acb3b724fb2a4411201f51fb924 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
York Sunb5b06fb2012-12-23 19:25:27 +00002/*
3 * Copyright 2011-2012 Freescale Semiconductor, Inc.
York Sunb5b06fb2012-12-23 19:25:27 +00004 */
5
6#include <common.h>
7#include <command.h>
Simon Glass3a7d5572019-08-01 09:46:42 -06008#include <env.h>
Simon Glass807765b2019-12-28 10:44:54 -07009#include <fdt_support.h>
York Sunb5b06fb2012-12-23 19:25:27 +000010#include <i2c.h>
Simon Glass4d72caa2020-05-10 11:40:01 -060011#include <image.h>
Simon Glass52559322019-11-14 12:57:46 -070012#include <init.h>
Simon Glass36bf4462019-11-14 12:57:42 -070013#include <irq_func.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060014#include <log.h>
York Sunb5b06fb2012-12-23 19:25:27 +000015#include <netdev.h>
16#include <linux/compiler.h>
17#include <asm/mmu.h>
18#include <asm/processor.h>
Masahiro Yamada1221ce42016-09-21 11:28:55 +090019#include <linux/errno.h>
York Sunb5b06fb2012-12-23 19:25:27 +000020#include <asm/cache.h>
21#include <asm/immap_85xx.h>
22#include <asm/fsl_law.h>
23#include <asm/fsl_serdes.h>
York Sunb5b06fb2012-12-23 19:25:27 +000024#include <asm/fsl_liodn.h>
25#include <fm_eth.h>
Suresh Guptacd79e5f2014-11-13 11:27:32 +080026#include <hwconfig.h>
York Sunb5b06fb2012-12-23 19:25:27 +000027
28#include "../common/qixis.h"
29#include "../common/vsc3316_3308.h"
Shaveta Leekhacb033742013-07-02 14:43:53 +053030#include "../common/idt8t49n222a_serdes_clk.h"
Shaveta Leekha652e29b2014-04-11 14:12:40 +053031#include "../common/zm7300.h"
York Sunb5b06fb2012-12-23 19:25:27 +000032#include "b4860qds.h"
33#include "b4860qds_qixis.h"
34#include "b4860qds_crossbar_con.h"
35
36#define CLK_MUX_SEL_MASK 0x4
37#define ETH_PHY_CLK_OUT 0x4
38
39DECLARE_GLOBAL_DATA_PTR;
40
41int checkboard(void)
42{
43 char buf[64];
44 u8 sw;
Simon Glass67ac13b2012-12-13 20:48:48 +000045 struct cpu_type *cpu = gd->arch.cpu;
York Sunb5b06fb2012-12-23 19:25:27 +000046 static const char *const freq[] = {"100", "125", "156.25", "161.13",
47 "122.88", "122.88", "122.88"};
48 int clock;
49
50 printf("Board: %sQDS, ", cpu->name);
51 printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, ",
52 QIXIS_READ(id), QIXIS_READ(arch));
53
54 sw = QIXIS_READ(brdcfg[0]);
55 sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
56
57 if (sw < 0x8)
58 printf("vBank: %d\n", sw);
59 else if (sw >= 0x8 && sw <= 0xE)
60 puts("NAND\n");
61 else
62 printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
63
64 printf("FPGA: v%d (%s), build %d",
65 (int)QIXIS_READ(scver), qixis_read_tag(buf),
66 (int)qixis_read_minor());
67 /* the timestamp string contains "\n" at the end */
68 printf(" on %s", qixis_read_time(buf));
69
York Sunb5b06fb2012-12-23 19:25:27 +000070 /*
71 * Display the actual SERDES reference clocks as configured by the
72 * dip switches on the board. Note that the SWx registers could
73 * technically be set to force the reference clocks to match the
74 * values that the SERDES expects (or vice versa). For now, however,
75 * we just display both values and hope the user notices when they
76 * don't match.
77 */
78 puts("SERDES Reference Clocks: ");
79 sw = QIXIS_READ(brdcfg[2]);
80 clock = (sw >> 5) & 7;
81 printf("Bank1=%sMHz ", freq[clock]);
82 sw = QIXIS_READ(brdcfg[4]);
83 clock = (sw >> 6) & 3;
84 printf("Bank2=%sMHz\n", freq[clock]);
85
86 return 0;
87}
88
89int select_i2c_ch_pca(u8 ch)
90{
91 int ret;
92
93 /* Selecting proper channel via PCA*/
94 ret = i2c_write(I2C_MUX_PCA_ADDR, 0x0, 1, &ch, 1);
95 if (ret) {
96 printf("PCA: failed to select proper channel.\n");
97 return ret;
98 }
99
100 return 0;
101}
102
Shaveta Leekha652e29b2014-04-11 14:12:40 +0530103/*
104 * read_voltage from sensor on I2C bus
105 * We use average of 4 readings, waiting for 532us befor another reading
106 */
107#define WAIT_FOR_ADC 532 /* wait for 532 microseconds for ADC */
108#define NUM_READINGS 4 /* prefer to be power of 2 for efficiency */
109
110static inline int read_voltage(void)
111{
112 int i, ret, voltage_read = 0;
113 u16 vol_mon;
114
115 for (i = 0; i < NUM_READINGS; i++) {
116 ret = i2c_read(I2C_VOL_MONITOR_ADDR,
117 I2C_VOL_MONITOR_BUS_V_OFFSET, 1, (void *)&vol_mon, 2);
118 if (ret) {
119 printf("VID: failed to read core voltage\n");
120 return ret;
121 }
122 if (vol_mon & I2C_VOL_MONITOR_BUS_V_OVF) {
123 printf("VID: Core voltage sensor error\n");
124 return -1;
125 }
126 debug("VID: bus voltage reads 0x%04x\n", vol_mon);
127 /* LSB = 4mv */
128 voltage_read += (vol_mon >> I2C_VOL_MONITOR_BUS_V_SHIFT) * 4;
129 udelay(WAIT_FOR_ADC);
130 }
131 /* calculate the average */
132 voltage_read /= NUM_READINGS;
133
134 return voltage_read;
135}
136
137static int adjust_vdd(ulong vdd_override)
138{
139 int re_enable = disable_interrupts();
140 ccsr_gur_t __iomem *gur =
141 (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
142 u32 fusesr;
143 u8 vid;
144 int vdd_target, vdd_last;
145 int existing_voltage, temp_voltage, voltage; /* all in 1/10 mV */
146 int ret;
147 unsigned int orig_i2c_speed;
148 unsigned long vdd_string_override;
149 char *vdd_string;
150 static const uint16_t vdd[32] = {
151 0, /* unused */
152 9875, /* 0.9875V */
153 9750,
154 9625,
155 9500,
156 9375,
157 9250,
158 9125,
159 9000,
160 8875,
161 8750,
162 8625,
163 8500,
164 8375,
165 8250,
166 8125,
167 10000, /* 1.0000V */
168 10125,
169 10250,
170 10375,
171 10500,
172 10625,
173 10750,
174 10875,
175 11000,
176 0, /* reserved */
177 };
178 struct vdd_drive {
179 u8 vid;
180 unsigned voltage;
181 };
182
183 ret = select_i2c_ch_pca(I2C_MUX_CH_VOL_MONITOR);
184 if (ret) {
185 printf("VID: I2c failed to switch channel\n");
186 ret = -1;
187 goto exit;
188 }
189
190 /* get the voltage ID from fuse status register */
191 fusesr = in_be32(&gur->dcfg_fusesr);
192 vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_VID_SHIFT) &
193 FSL_CORENET_DCFG_FUSESR_VID_MASK;
194 if (vid == FSL_CORENET_DCFG_FUSESR_VID_MASK) {
195 vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_ALTVID_SHIFT) &
196 FSL_CORENET_DCFG_FUSESR_ALTVID_MASK;
197 }
198 vdd_target = vdd[vid];
199 debug("VID:Reading from from fuse,vid=%x vdd is %dmV\n",
200 vid, vdd_target/10);
201
202 /* check override variable for overriding VDD */
Simon Glass00caae62017-08-03 12:22:12 -0600203 vdd_string = env_get("b4qds_vdd_mv");
Shaveta Leekha652e29b2014-04-11 14:12:40 +0530204 if (vdd_override == 0 && vdd_string &&
205 !strict_strtoul(vdd_string, 10, &vdd_string_override))
206 vdd_override = vdd_string_override;
207 if (vdd_override >= 819 && vdd_override <= 1212) {
208 vdd_target = vdd_override * 10; /* convert to 1/10 mV */
209 debug("VDD override is %lu\n", vdd_override);
210 } else if (vdd_override != 0) {
211 printf("Invalid value.\n");
212 }
213
214 if (vdd_target == 0) {
215 printf("VID: VID not used\n");
216 ret = 0;
217 goto exit;
218 }
219
220 /*
221 * Read voltage monitor to check real voltage.
222 * Voltage monitor LSB is 4mv.
223 */
224 vdd_last = read_voltage();
225 if (vdd_last < 0) {
226 printf("VID: abort VID adjustment\n");
227 ret = -1;
228 goto exit;
229 }
230
231 debug("VID: Core voltage is at %d mV\n", vdd_last);
232 ret = select_i2c_ch_pca(I2C_MUX_CH_DPM);
233 if (ret) {
234 printf("VID: I2c failed to switch channel to DPM\n");
235 ret = -1;
236 goto exit;
237 }
238
239 /* Round up to the value of step of Voltage regulator */
240 voltage = roundup(vdd_target, ZM_STEP);
241 debug("VID: rounded up voltage = %d\n", voltage);
242
243 /* lower the speed to 100kHz to access ZM7300 device */
244 debug("VID: Setting bus speed to 100KHz if not already set\n");
245 orig_i2c_speed = i2c_get_bus_speed();
246 if (orig_i2c_speed != 100000)
247 i2c_set_bus_speed(100000);
248
249 /* Read the existing level on board, if equal to requsted one,
250 no need to re-set */
251 existing_voltage = zm_read_voltage();
252
253 /* allowing the voltage difference of one step 0.0125V acceptable */
254 if ((existing_voltage >= voltage) &&
255 (existing_voltage < (voltage + ZM_STEP))) {
256 debug("VID: voltage already set as requested,returning\n");
257 ret = existing_voltage;
258 goto out;
259 }
260 debug("VID: Changing voltage for board from %dmV to %dmV\n",
261 existing_voltage/10, voltage/10);
262
263 if (zm_disable_wp() < 0) {
264 ret = -1;
265 goto out;
266 }
267 /* Change Voltage: the change is done through all the steps in the
268 way, to avoid reset to the board due to power good signal fail
269 in big voltage change gap jump.
270 */
271 if (existing_voltage > voltage) {
272 temp_voltage = existing_voltage - ZM_STEP;
273 while (temp_voltage >= voltage) {
274 ret = zm_write_voltage(temp_voltage);
275 if (ret == temp_voltage) {
276 temp_voltage -= ZM_STEP;
277 } else {
278 /* ZM7300 device failed to set
279 * the voltage */
280 printf
281 ("VID:Stepping down vol failed:%dmV\n",
282 temp_voltage/10);
283 ret = -1;
284 goto out;
285 }
286 }
287 } else {
288 temp_voltage = existing_voltage + ZM_STEP;
289 while (temp_voltage < (voltage + ZM_STEP)) {
290 ret = zm_write_voltage(temp_voltage);
291 if (ret == temp_voltage) {
292 temp_voltage += ZM_STEP;
293 } else {
294 /* ZM7300 device failed to set
295 * the voltage */
296 printf
297 ("VID:Stepping up vol failed:%dmV\n",
298 temp_voltage/10);
299 ret = -1;
300 goto out;
301 }
302 }
303 }
304
305 if (zm_enable_wp() < 0)
306 ret = -1;
307
308 /* restore the speed to 400kHz */
309out: debug("VID: Restore the I2C bus speed to %dKHz\n",
310 orig_i2c_speed/1000);
311 i2c_set_bus_speed(orig_i2c_speed);
312 if (ret < 0)
313 goto exit;
314
315 ret = select_i2c_ch_pca(I2C_MUX_CH_VOL_MONITOR);
316 if (ret) {
317 printf("VID: I2c failed to switch channel\n");
318 ret = -1;
319 goto exit;
320 }
321 vdd_last = read_voltage();
322 select_i2c_ch_pca(I2C_CH_DEFAULT);
323
324 if (vdd_last > 0)
325 printf("VID: Core voltage %d mV\n", vdd_last);
326 else
327 ret = -1;
328
329exit:
330 if (re_enable)
331 enable_interrupts();
332 return ret;
333}
334
York Sunb5b06fb2012-12-23 19:25:27 +0000335int configure_vsc3316_3308(void)
336{
337 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
338 unsigned int num_vsc16_con, num_vsc08_con;
339 u32 serdes1_prtcl, serdes2_prtcl;
340 int ret;
Suresh Guptacd79e5f2014-11-13 11:27:32 +0800341 char buffer[HWCONFIG_BUFFER_SIZE];
342 char *buf = NULL;
York Sunb5b06fb2012-12-23 19:25:27 +0000343
344 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
345 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
346 if (!serdes1_prtcl) {
347 printf("SERDES1 is not enabled\n");
348 return 0;
349 }
350 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
351 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
352
353 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
354 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
355 if (!serdes2_prtcl) {
356 printf("SERDES2 is not enabled\n");
357 return 0;
358 }
359 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
360 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
361
362 switch (serdes1_prtcl) {
poonam aggrwalc7d506d2014-02-17 08:38:58 +0530363 case 0x29:
York Sunb5b06fb2012-12-23 19:25:27 +0000364 case 0x2a:
365 case 0x2C:
366 case 0x2D:
367 case 0x2E:
368 /*
369 * Configuration:
370 * SERDES: 1
371 * Lanes: A,B: SGMII
372 * Lanes: C,D,E,F,G,H: CPRI
373 */
374 debug("Configuring crossbar to use onboard SGMII PHYs:"
375 "srds_prctl:%x\n", serdes1_prtcl);
376 num_vsc16_con = NUM_CON_VSC3316;
377 /* Configure VSC3316 crossbar switch */
378 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
379 if (!ret) {
380 ret = vsc3316_config(VSC3316_TX_ADDRESS,
Shaveta Leekha0fecbba2013-03-25 07:40:17 +0000381 vsc16_tx_4sfp_sgmii_12_56,
382 num_vsc16_con);
York Sunb5b06fb2012-12-23 19:25:27 +0000383 if (ret)
384 return ret;
385 ret = vsc3316_config(VSC3316_RX_ADDRESS,
Shaveta Leekha0fecbba2013-03-25 07:40:17 +0000386 vsc16_rx_4sfp_sgmii_12_56,
387 num_vsc16_con);
York Sunb5b06fb2012-12-23 19:25:27 +0000388 if (ret)
389 return ret;
390 } else {
391 return ret;
392 }
393 break;
394
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530395 case 0x01:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530396 case 0x02:
397 case 0x04:
398 case 0x05:
399 case 0x06:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530400 case 0x07:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530401 case 0x08:
402 case 0x09:
403 case 0x0A:
404 case 0x0B:
405 case 0x0C:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530406 case 0x2F:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530407 case 0x30:
408 case 0x32:
409 case 0x33:
410 case 0x34:
411 case 0x39:
412 case 0x3A:
413 case 0x3C:
414 case 0x3D:
415 case 0x5C:
416 case 0x5D:
417 /*
418 * Configuration:
419 * SERDES: 1
420 * Lanes: A,B: AURORA
421 * Lanes: C,d: SGMII
422 * Lanes: E,F,G,H: CPRI
423 */
424 debug("Configuring crossbar for Aurora, SGMII 3 and 4,"
425 " and CPRI. srds_prctl:%x\n", serdes1_prtcl);
426 num_vsc16_con = NUM_CON_VSC3316;
427 /* Configure VSC3316 crossbar switch */
428 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
429 if (!ret) {
430 ret = vsc3316_config(VSC3316_TX_ADDRESS,
431 vsc16_tx_sfp_sgmii_aurora,
432 num_vsc16_con);
433 if (ret)
434 return ret;
435 ret = vsc3316_config(VSC3316_RX_ADDRESS,
436 vsc16_rx_sfp_sgmii_aurora,
437 num_vsc16_con);
438 if (ret)
439 return ret;
440 } else {
441 return ret;
442 }
443 break;
444
York Sunb41f1922016-11-18 11:56:57 -0800445#ifdef CONFIG_ARCH_B4420
poonam aggrwalc7d506d2014-02-17 08:38:58 +0530446 case 0x17:
York Sunb5b06fb2012-12-23 19:25:27 +0000447 case 0x18:
448 /*
449 * Configuration:
450 * SERDES: 1
451 * Lanes: A,B,C,D: SGMII
452 * Lanes: E,F,G,H: CPRI
453 */
454 debug("Configuring crossbar to use onboard SGMII PHYs:"
455 "srds_prctl:%x\n", serdes1_prtcl);
456 num_vsc16_con = NUM_CON_VSC3316;
457 /* Configure VSC3316 crossbar switch */
458 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
459 if (!ret) {
460 ret = vsc3316_config(VSC3316_TX_ADDRESS,
461 vsc16_tx_sgmii_lane_cd, num_vsc16_con);
462 if (ret)
463 return ret;
464 ret = vsc3316_config(VSC3316_RX_ADDRESS,
465 vsc16_rx_sgmii_lane_cd, num_vsc16_con);
466 if (ret)
467 return ret;
468 } else {
469 return ret;
470 }
471 break;
472#endif
473
474 case 0x3E:
475 case 0x0D:
476 case 0x0E:
477 case 0x12:
478 num_vsc16_con = NUM_CON_VSC3316;
479 /* Configure VSC3316 crossbar switch */
480 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
481 if (!ret) {
482 ret = vsc3316_config(VSC3316_TX_ADDRESS,
483 vsc16_tx_sfp, num_vsc16_con);
484 if (ret)
485 return ret;
486 ret = vsc3316_config(VSC3316_RX_ADDRESS,
487 vsc16_rx_sfp, num_vsc16_con);
488 if (ret)
489 return ret;
490 } else {
491 return ret;
492 }
493 break;
494 default:
495 printf("WARNING:VSC crossbars programming not supported for:%x"
496 " SerDes1 Protocol.\n", serdes1_prtcl);
497 return -1;
498 }
499
Shaohui Xie89b94d82014-11-13 11:26:19 +0800500 num_vsc08_con = NUM_CON_VSC3308;
501 /* Configure VSC3308 crossbar switch */
502 ret = select_i2c_ch_pca(I2C_CH_VSC3308);
York Sunb5b06fb2012-12-23 19:25:27 +0000503 switch (serdes2_prtcl) {
York Sunb41f1922016-11-18 11:56:57 -0800504#ifdef CONFIG_ARCH_B4420
poonam aggrwalfa6e7422014-05-31 00:08:18 +0530505 case 0x9d:
506#endif
York Sunb5b06fb2012-12-23 19:25:27 +0000507 case 0x9E:
508 case 0x9A:
509 case 0x98:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530510 case 0x48:
York Sunb5b06fb2012-12-23 19:25:27 +0000511 case 0x49:
512 case 0x4E:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530513 case 0x79:
York Sunb5b06fb2012-12-23 19:25:27 +0000514 case 0x7A:
York Sunb5b06fb2012-12-23 19:25:27 +0000515 if (!ret) {
516 ret = vsc3308_config(VSC3308_TX_ADDRESS,
517 vsc08_tx_amc, num_vsc08_con);
518 if (ret)
519 return ret;
520 ret = vsc3308_config(VSC3308_RX_ADDRESS,
521 vsc08_rx_amc, num_vsc08_con);
522 if (ret)
523 return ret;
524 } else {
525 return ret;
526 }
527 break;
Shaohui Xie89b94d82014-11-13 11:26:19 +0800528 case 0x80:
529 case 0x81:
530 case 0x82:
531 case 0x83:
532 case 0x84:
533 case 0x85:
534 case 0x86:
535 case 0x87:
536 case 0x88:
537 case 0x89:
538 case 0x8a:
539 case 0x8b:
540 case 0x8c:
541 case 0x8d:
542 case 0x8e:
543 case 0xb1:
544 case 0xb2:
545 if (!ret) {
Suresh Guptacd79e5f2014-11-13 11:27:32 +0800546 /*
547 * Extract hwconfig from environment since environment
548 * is not setup properly yet
549 */
Simon Glass00caae62017-08-03 12:22:12 -0600550 env_get_f("hwconfig", buffer, sizeof(buffer));
Suresh Guptacd79e5f2014-11-13 11:27:32 +0800551 buf = buffer;
552
553 if (hwconfig_subarg_cmp_f("fsl_b4860_serdes2",
554 "sfp_amc", "sfp", buf)) {
Shaohui Xieb24f6d42014-11-13 11:27:49 +0800555#ifdef CONFIG_SYS_FSL_B4860QDS_XFI_ERR
556 /* change default VSC3308 for XFI erratum */
557 ret = vsc3308_config_adjust(VSC3308_TX_ADDRESS,
558 vsc08_tx_sfp, num_vsc08_con);
559 if (ret)
560 return ret;
561
562 ret = vsc3308_config_adjust(VSC3308_RX_ADDRESS,
563 vsc08_rx_sfp, num_vsc08_con);
564 if (ret)
565 return ret;
566#else
Suresh Guptacd79e5f2014-11-13 11:27:32 +0800567 ret = vsc3308_config(VSC3308_TX_ADDRESS,
568 vsc08_tx_sfp, num_vsc08_con);
569 if (ret)
570 return ret;
571
572 ret = vsc3308_config(VSC3308_RX_ADDRESS,
573 vsc08_rx_sfp, num_vsc08_con);
574 if (ret)
575 return ret;
Shaohui Xieb24f6d42014-11-13 11:27:49 +0800576#endif
Suresh Guptacd79e5f2014-11-13 11:27:32 +0800577 } else {
578 ret = vsc3308_config(VSC3308_TX_ADDRESS,
579 vsc08_tx_amc, num_vsc08_con);
580 if (ret)
581 return ret;
582
583 ret = vsc3308_config(VSC3308_RX_ADDRESS,
584 vsc08_rx_amc, num_vsc08_con);
585 if (ret)
586 return ret;
587 }
588
Shaohui Xie89b94d82014-11-13 11:26:19 +0800589 } else {
590 return ret;
591 }
592 break;
York Sunb5b06fb2012-12-23 19:25:27 +0000593 default:
594 printf("WARNING:VSC crossbars programming not supported for: %x"
595 " SerDes2 Protocol.\n", serdes2_prtcl);
596 return -1;
597 }
598
599 return 0;
600}
601
Shaveta Leekha7af9a072014-02-26 16:08:22 +0530602static int calibrate_pll(serdes_corenet_t *srds_regs, int pll_num)
603{
604 u32 rst_err;
605
606 /* Steps For SerDes PLLs reset and reconfiguration
607 * or PLL power-up procedure
608 */
609 debug("CALIBRATE PLL:%d\n", pll_num);
610 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
611 SRDS_RSTCTL_SDRST_B);
612 udelay(10);
613 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
614 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
615 udelay(10);
616 setbits_be32(&srds_regs->bank[pll_num].rstctl,
617 SRDS_RSTCTL_RST);
618 setbits_be32(&srds_regs->bank[pll_num].rstctl,
619 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
620 | SRDS_RSTCTL_SDRST_B));
621
622 udelay(20);
623
624 /* Check whether PLL has been locked or not */
625 rst_err = in_be32(&srds_regs->bank[pll_num].rstctl) &
626 SRDS_RSTCTL_RSTERR;
627 rst_err >>= SRDS_RSTCTL_RSTERR_SHIFT;
628 debug("RST_ERR value for PLL %d is: 0x%x:\n", pll_num, rst_err);
629 if (rst_err)
630 return rst_err;
631
632 return rst_err;
633}
634
635static int check_pll_locks(serdes_corenet_t *srds_regs, int pll_num)
636{
637 int ret = 0;
638 u32 fcap, dcbias, bcap, pllcr1, pllcr0;
639
640 if (calibrate_pll(srds_regs, pll_num)) {
641 /* STEP 1 */
642 /* Read fcap, dcbias and bcap value */
643 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
644 SRDS_PLLCR0_DCBIAS_OUT_EN);
645 fcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
646 SRDS_PLLSR2_FCAP;
647 fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
648 bcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
649 SRDS_PLLSR2_BCAP_EN;
650 bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
651 setbits_be32(&srds_regs->bank[pll_num].pllcr0,
652 SRDS_PLLCR0_DCBIAS_OUT_EN);
653 dcbias = in_be32(&srds_regs->bank[pll_num].pllsr2) &
654 SRDS_PLLSR2_DCBIAS;
655 dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
656 debug("values of bcap:%x, fcap:%x and dcbias:%x\n",
657 bcap, fcap, dcbias);
658 if (fcap == 0 && bcap == 1) {
659 /* Step 3 */
660 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
661 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
662 | SRDS_RSTCTL_SDRST_B));
663 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
664 SRDS_PLLCR1_BCAP_EN);
665 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
666 SRDS_PLLCR1_BCAP_OVD);
667 if (calibrate_pll(srds_regs, pll_num)) {
668 /*save the fcap, dcbias and bcap values*/
669 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
670 SRDS_PLLCR0_DCBIAS_OUT_EN);
671 fcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
672 & SRDS_PLLSR2_FCAP;
673 fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
674 bcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
675 & SRDS_PLLSR2_BCAP_EN;
676 bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
677 setbits_be32(&srds_regs->bank[pll_num].pllcr0,
678 SRDS_PLLCR0_DCBIAS_OUT_EN);
679 dcbias = in_be32
680 (&srds_regs->bank[pll_num].pllsr2) &
681 SRDS_PLLSR2_DCBIAS;
682 dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
683
684 /* Step 4*/
685 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
686 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
687 | SRDS_RSTCTL_SDRST_B));
688 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
689 SRDS_PLLCR1_BYP_CAL);
690 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
691 SRDS_PLLCR1_BCAP_EN);
692 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
693 SRDS_PLLCR1_BCAP_OVD);
694 /* change the fcap and dcbias to the saved
695 * values from Step 3 */
696 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
697 SRDS_PLLCR1_PLL_FCAP);
698 pllcr1 = (in_be32
699 (&srds_regs->bank[pll_num].pllcr1)|
700 (fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
701 out_be32(&srds_regs->bank[pll_num].pllcr1,
702 pllcr1);
703 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
704 SRDS_PLLCR0_DCBIAS_OVRD);
705 pllcr0 = (in_be32
706 (&srds_regs->bank[pll_num].pllcr0)|
707 (dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
708 out_be32(&srds_regs->bank[pll_num].pllcr0,
709 pllcr0);
710 ret = calibrate_pll(srds_regs, pll_num);
711 if (ret)
712 return ret;
713 } else {
714 goto out;
715 }
716 } else { /* Step 5 */
717 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
718 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
719 | SRDS_RSTCTL_SDRST_B));
720 udelay(10);
721 /* Change the fcap, dcbias, and bcap to the
722 * values from Step 1 */
723 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
724 SRDS_PLLCR1_BYP_CAL);
725 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
726 SRDS_PLLCR1_PLL_FCAP);
727 pllcr1 = (in_be32(&srds_regs->bank[pll_num].pllcr1)|
728 (fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
729 out_be32(&srds_regs->bank[pll_num].pllcr1,
730 pllcr1);
731 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
732 SRDS_PLLCR0_DCBIAS_OVRD);
733 pllcr0 = (in_be32(&srds_regs->bank[pll_num].pllcr0)|
734 (dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
735 out_be32(&srds_regs->bank[pll_num].pllcr0,
736 pllcr0);
737 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
738 SRDS_PLLCR1_BCAP_EN);
739 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
740 SRDS_PLLCR1_BCAP_OVD);
741 ret = calibrate_pll(srds_regs, pll_num);
742 if (ret)
743 return ret;
744 }
745 }
746out:
747 return 0;
748}
749
750static int check_serdes_pll_locks(void)
751{
752 serdes_corenet_t *srds1_regs =
753 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
754 serdes_corenet_t *srds2_regs =
755 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
756 int i, ret1, ret2;
757
758 debug("\nSerDes1 Lock check\n");
759 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
760 ret1 = check_pll_locks(srds1_regs, i);
761 if (ret1) {
762 printf("SerDes1, PLL:%d didnt lock\n", i);
763 return ret1;
764 }
765 }
766 debug("\nSerDes2 Lock check\n");
767 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
768 ret2 = check_pll_locks(srds2_regs, i);
769 if (ret2) {
770 printf("SerDes2, PLL:%d didnt lock\n", i);
771 return ret2;
772 }
773 }
774
775 return 0;
776}
777
Shaveta Leekhacb033742013-07-02 14:43:53 +0530778int config_serdes1_refclks(void)
779{
780 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
781 serdes_corenet_t *srds_regs =
782 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
783 u32 serdes1_prtcl, lane;
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530784 unsigned int flag_sgmii_aurora_prtcl = 0;
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530785 int i;
786 int ret = 0;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530787
788 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
789 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
790 if (!serdes1_prtcl) {
791 printf("SERDES1 is not enabled\n");
792 return -1;
793 }
794 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
795 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
796
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530797 /* To prevent generation of reset request from SerDes
798 * while changing the refclks, By setting SRDS_RST_MSK bit,
799 * SerDes reset event cannot cause a reset request
Shaveta Leekhacb033742013-07-02 14:43:53 +0530800 */
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530801 setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
802
Shaveta Leekhacb033742013-07-02 14:43:53 +0530803 /* Reconfigure IDT idt8t49n222a device for CPRI to work
804 * For this SerDes1's Refclk1 and refclk2 need to be set
805 * to 122.88MHz
806 */
807 switch (serdes1_prtcl) {
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530808 case 0x29:
Shaveta Leekhacb033742013-07-02 14:43:53 +0530809 case 0x2A:
810 case 0x2C:
811 case 0x2D:
812 case 0x2E:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530813 case 0x01:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530814 case 0x02:
815 case 0x04:
816 case 0x05:
817 case 0x06:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530818 case 0x07:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530819 case 0x08:
820 case 0x09:
821 case 0x0A:
822 case 0x0B:
823 case 0x0C:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530824 case 0x2F:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530825 case 0x30:
826 case 0x32:
827 case 0x33:
828 case 0x34:
829 case 0x39:
830 case 0x3A:
831 case 0x3C:
832 case 0x3D:
833 case 0x5C:
834 case 0x5D:
Shaveta Leekhacb033742013-07-02 14:43:53 +0530835 debug("Configuring idt8t49n222a for CPRI SerDes clks:"
836 " for srds_prctl:%x\n", serdes1_prtcl);
837 ret = select_i2c_ch_pca(I2C_CH_IDT);
838 if (!ret) {
839 ret = set_serdes_refclk(IDT_SERDES1_ADDRESS, 1,
840 SERDES_REFCLK_122_88,
841 SERDES_REFCLK_122_88, 0);
842 if (ret) {
843 printf("IDT8T49N222A configuration failed.\n");
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530844 goto out;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530845 } else
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530846 debug("IDT8T49N222A configured.\n");
Shaveta Leekhacb033742013-07-02 14:43:53 +0530847 } else {
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530848 goto out;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530849 }
850 select_i2c_ch_pca(I2C_CH_DEFAULT);
851
852 /* Change SerDes1's Refclk1 to 125MHz for on board
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530853 * SGMIIs or Aurora to work
Shaveta Leekhacb033742013-07-02 14:43:53 +0530854 */
855 for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
856 enum srds_prtcl lane_prtcl = serdes_get_prtcl
857 (0, serdes1_prtcl, lane);
858 switch (lane_prtcl) {
859 case SGMII_FM1_DTSEC1:
860 case SGMII_FM1_DTSEC2:
861 case SGMII_FM1_DTSEC3:
862 case SGMII_FM1_DTSEC4:
863 case SGMII_FM1_DTSEC5:
864 case SGMII_FM1_DTSEC6:
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530865 case AURORA:
866 flag_sgmii_aurora_prtcl++;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530867 break;
868 default:
869 break;
870 }
871 }
872
Shaveta Leekha5e5097c2014-02-26 16:06:30 +0530873 if (flag_sgmii_aurora_prtcl)
Shaveta Leekhacb033742013-07-02 14:43:53 +0530874 QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
875
876 /* Steps For SerDes PLLs reset and reconfiguration after
877 * changing SerDes's refclks
878 */
Shaveta Leekhac4930b12014-02-26 16:07:51 +0530879 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
Shaveta Leekhacb033742013-07-02 14:43:53 +0530880 debug("For PLL%d reset and reconfiguration after"
881 " changing refclks\n", i+1);
882 clrbits_be32(&srds_regs->bank[i].rstctl,
883 SRDS_RSTCTL_SDRST_B);
884 udelay(10);
885 clrbits_be32(&srds_regs->bank[i].rstctl,
886 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
887 udelay(10);
888 setbits_be32(&srds_regs->bank[i].rstctl,
889 SRDS_RSTCTL_RST);
890 setbits_be32(&srds_regs->bank[i].rstctl,
891 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
892 | SRDS_RSTCTL_SDRST_B));
893 }
894 break;
895 default:
896 printf("WARNING:IDT8T49N222A configuration not"
897 " supported for:%x SerDes1 Protocol.\n",
898 serdes1_prtcl);
Shaveta Leekhacb033742013-07-02 14:43:53 +0530899 }
900
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530901out:
902 /* Clearing SRDS_RST_MSK bit as now
903 * SerDes reset event can cause a reset request
904 */
905 clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
906 return ret;
907}
908
909int config_serdes2_refclks(void)
910{
911 ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
912 serdes_corenet_t *srds2_regs =
913 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
914 u32 serdes2_prtcl;
915 int ret = 0;
916 int i;
917
918 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
919 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
920 if (!serdes2_prtcl) {
921 debug("SERDES2 is not enabled\n");
922 return -ENODEV;
923 }
924 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
925 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
926
927 /* To prevent generation of reset request from SerDes
928 * while changing the refclks, By setting SRDS_RST_MSK bit,
929 * SerDes reset event cannot cause a reset request
930 */
931 setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
932
933 /* Reconfigure IDT idt8t49n222a device for PCIe SATA to work
934 * For this SerDes2's Refclk1 need to be set to 100MHz
935 */
936 switch (serdes2_prtcl) {
York Sunb41f1922016-11-18 11:56:57 -0800937#ifdef CONFIG_ARCH_B4420
poonam aggrwalfa6e7422014-05-31 00:08:18 +0530938 case 0x9d:
939#endif
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530940 case 0x9E:
941 case 0x9A:
Shaveta Leekha8c328c22014-11-12 16:00:44 +0530942 /* fallthrough */
943 case 0xb1:
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530944 case 0xb2:
945 debug("Configuring IDT for PCIe SATA for srds_prctl:%x\n",
946 serdes2_prtcl);
947 ret = select_i2c_ch_pca(I2C_CH_IDT);
948 if (!ret) {
949 ret = set_serdes_refclk(IDT_SERDES2_ADDRESS, 2,
950 SERDES_REFCLK_100,
Shaveta Leekhac4930b12014-02-26 16:07:51 +0530951 SERDES_REFCLK_156_25, 0);
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530952 if (ret) {
953 printf("IDT8T49N222A configuration failed.\n");
954 goto out;
955 } else
956 debug("IDT8T49N222A configured.\n");
957 } else {
958 goto out;
959 }
960 select_i2c_ch_pca(I2C_CH_DEFAULT);
961
962 /* Steps For SerDes PLLs reset and reconfiguration after
963 * changing SerDes's refclks
964 */
Shaveta Leekhac4930b12014-02-26 16:07:51 +0530965 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530966 clrbits_be32(&srds2_regs->bank[i].rstctl,
967 SRDS_RSTCTL_SDRST_B);
968 udelay(10);
969 clrbits_be32(&srds2_regs->bank[i].rstctl,
970 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
971 udelay(10);
972 setbits_be32(&srds2_regs->bank[i].rstctl,
973 SRDS_RSTCTL_RST);
974 setbits_be32(&srds2_regs->bank[i].rstctl,
975 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
976 | SRDS_RSTCTL_SDRST_B));
Shaveta Leekha7af9a072014-02-26 16:08:22 +0530977
978 udelay(10);
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530979 }
980 break;
981 default:
982 printf("IDT configuration not supported for:%x S2 Protocol.\n",
983 serdes2_prtcl);
984 }
985
986out:
987 /* Clearing SRDS_RST_MSK bit as now
988 * SerDes reset event can cause a reset request
989 */
990 clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
991 return ret;
Shaveta Leekhacb033742013-07-02 14:43:53 +0530992}
993
York Sunb5b06fb2012-12-23 19:25:27 +0000994int board_early_init_r(void)
995{
996 const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
York Sun9d045682014-06-24 21:16:20 -0700997 int flash_esel = find_tlb_idx((void *)flashbase, 1);
Shaveta Leekhafb07c0a2014-02-26 16:06:56 +0530998 int ret;
Shaveta Leekhaf7c28aa2014-11-12 14:23:26 +0530999 u32 svr = SVR_SOC_VER(get_svr());
1000
1001 /* Create law for MAPLE only for personalities having MAPLE */
1002 if ((svr == SVR_B4860) || (svr == SVR_B4440) ||
1003 (svr == SVR_B4420) || (svr == SVR_B4220)) {
1004 set_next_law(CONFIG_SYS_MAPLE_MEM_PHYS, LAW_SIZE_16M,
1005 LAW_TRGT_IF_MAPLE);
1006 }
York Sunb5b06fb2012-12-23 19:25:27 +00001007
1008 /*
1009 * Remap Boot flash + PROMJET region to caching-inhibited
1010 * so that flash can be erased properly.
1011 */
1012
1013 /* Flush d-cache and invalidate i-cache of any FLASH data */
1014 flush_dcache();
1015 invalidate_icache();
1016
York Sun9d045682014-06-24 21:16:20 -07001017 if (flash_esel == -1) {
1018 /* very unlikely unless something is messed up */
1019 puts("Error: Could not find TLB for FLASH BASE\n");
1020 flash_esel = 2; /* give our best effort to continue */
1021 } else {
1022 /* invalidate existing TLB entry for flash + promjet */
1023 disable_tlb(flash_esel);
1024 }
York Sunb5b06fb2012-12-23 19:25:27 +00001025
1026 set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
1027 MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
1028 0, flash_esel, BOOKE_PAGESZ_256M, 1);
1029
Shaveta Leekha652e29b2014-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 Leekhacb033742013-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 Sunb5b06fb2012-12-23 19:25:27 +00001047
Shaveta Leekhafb07c0a2014-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 Leekha7af9a072014-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 Sunb5b06fb2012-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 Sunb5b06fb2012-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 Glasse895a4b2014-10-23 18:58:47 -06001198int ft_board_setup(void *blob, bd_t *bd)
York Sunb5b06fb2012-12-23 19:25:27 +00001199{
1200 phys_addr_t base;
1201 phys_size_t size;
1202
1203 ft_cpu_setup(blob, bd);
1204
Simon Glass723806c2017-08-03 12:22:15 -06001205 base = env_get_bootm_low();
1206 size = env_get_bootm_size();
York Sunb5b06fb2012-12-23 19:25:27 +00001207
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
Sriram Dasha5c289b2016-09-16 17:12:15 +05301217 fsl_fdt_fixup_dr_usb(blob, bd);
York Sunb5b06fb2012-12-23 19:25:27 +00001218#endif
1219
1220#ifdef CONFIG_SYS_DPAA_FMAN
1221 fdt_fixup_fman_ethernet(blob);
1222 fdt_fixup_board_enet(blob);
1223#endif
Simon Glasse895a4b2014-10-23 18:58:47 -06001224
1225 return 0;
York Sunb5b06fb2012-12-23 19:25:27 +00001226}
Shaveta Leekha43548892012-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}