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