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