blob: b2d53781438d35a296990068e90085bf27ef8ce2 [file] [log] [blame]
York Sun0789dc92012-12-23 19:25:27 +00001/*
2 * Copyright 2011-2012 Freescale Semiconductor, Inc.
3 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02004 * SPDX-License-Identifier: GPL-2.0+
York Sun0789dc92012-12-23 19:25:27 +00005 */
6
7#include <common.h>
8#include <command.h>
9#include <i2c.h>
10#include <netdev.h>
11#include <linux/compiler.h>
12#include <asm/mmu.h>
13#include <asm/processor.h>
Shaveta Leekha2145a3e2014-02-26 16:06:56 +053014#include <asm/errno.h>
York Sun0789dc92012-12-23 19:25:27 +000015#include <asm/cache.h>
16#include <asm/immap_85xx.h>
17#include <asm/fsl_law.h>
18#include <asm/fsl_serdes.h>
19#include <asm/fsl_portals.h>
20#include <asm/fsl_liodn.h>
21#include <fm_eth.h>
22
23#include "../common/qixis.h"
24#include "../common/vsc3316_3308.h"
Shaveta Leekhad1cb7742013-07-02 14:43:53 +053025#include "../common/idt8t49n222a_serdes_clk.h"
Shaveta Leekhae1b6f4c2014-04-11 14:12:40 +053026#include "../common/zm7300.h"
York Sun0789dc92012-12-23 19:25:27 +000027#include "b4860qds.h"
28#include "b4860qds_qixis.h"
29#include "b4860qds_crossbar_con.h"
30
31#define CLK_MUX_SEL_MASK 0x4
32#define ETH_PHY_CLK_OUT 0x4
33
34DECLARE_GLOBAL_DATA_PTR;
35
36int checkboard(void)
37{
38 char buf[64];
39 u8 sw;
Simon Glassa8b57392012-12-13 20:48:48 +000040 struct cpu_type *cpu = gd->arch.cpu;
York Sun0789dc92012-12-23 19:25:27 +000041 static const char *const freq[] = {"100", "125", "156.25", "161.13",
42 "122.88", "122.88", "122.88"};
43 int clock;
44
45 printf("Board: %sQDS, ", cpu->name);
46 printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, ",
47 QIXIS_READ(id), QIXIS_READ(arch));
48
49 sw = QIXIS_READ(brdcfg[0]);
50 sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
51
52 if (sw < 0x8)
53 printf("vBank: %d\n", sw);
54 else if (sw >= 0x8 && sw <= 0xE)
55 puts("NAND\n");
56 else
57 printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
58
59 printf("FPGA: v%d (%s), build %d",
60 (int)QIXIS_READ(scver), qixis_read_tag(buf),
61 (int)qixis_read_minor());
62 /* the timestamp string contains "\n" at the end */
63 printf(" on %s", qixis_read_time(buf));
64
York Sun0789dc92012-12-23 19:25:27 +000065 /*
66 * Display the actual SERDES reference clocks as configured by the
67 * dip switches on the board. Note that the SWx registers could
68 * technically be set to force the reference clocks to match the
69 * values that the SERDES expects (or vice versa). For now, however,
70 * we just display both values and hope the user notices when they
71 * don't match.
72 */
73 puts("SERDES Reference Clocks: ");
74 sw = QIXIS_READ(brdcfg[2]);
75 clock = (sw >> 5) & 7;
76 printf("Bank1=%sMHz ", freq[clock]);
77 sw = QIXIS_READ(brdcfg[4]);
78 clock = (sw >> 6) & 3;
79 printf("Bank2=%sMHz\n", freq[clock]);
80
81 return 0;
82}
83
84int select_i2c_ch_pca(u8 ch)
85{
86 int ret;
87
88 /* Selecting proper channel via PCA*/
89 ret = i2c_write(I2C_MUX_PCA_ADDR, 0x0, 1, &ch, 1);
90 if (ret) {
91 printf("PCA: failed to select proper channel.\n");
92 return ret;
93 }
94
95 return 0;
96}
97
Shaveta Leekhae1b6f4c2014-04-11 14:12:40 +053098/*
99 * read_voltage from sensor on I2C bus
100 * We use average of 4 readings, waiting for 532us befor another reading
101 */
102#define WAIT_FOR_ADC 532 /* wait for 532 microseconds for ADC */
103#define NUM_READINGS 4 /* prefer to be power of 2 for efficiency */
104
105static inline int read_voltage(void)
106{
107 int i, ret, voltage_read = 0;
108 u16 vol_mon;
109
110 for (i = 0; i < NUM_READINGS; i++) {
111 ret = i2c_read(I2C_VOL_MONITOR_ADDR,
112 I2C_VOL_MONITOR_BUS_V_OFFSET, 1, (void *)&vol_mon, 2);
113 if (ret) {
114 printf("VID: failed to read core voltage\n");
115 return ret;
116 }
117 if (vol_mon & I2C_VOL_MONITOR_BUS_V_OVF) {
118 printf("VID: Core voltage sensor error\n");
119 return -1;
120 }
121 debug("VID: bus voltage reads 0x%04x\n", vol_mon);
122 /* LSB = 4mv */
123 voltage_read += (vol_mon >> I2C_VOL_MONITOR_BUS_V_SHIFT) * 4;
124 udelay(WAIT_FOR_ADC);
125 }
126 /* calculate the average */
127 voltage_read /= NUM_READINGS;
128
129 return voltage_read;
130}
131
132static int adjust_vdd(ulong vdd_override)
133{
134 int re_enable = disable_interrupts();
135 ccsr_gur_t __iomem *gur =
136 (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
137 u32 fusesr;
138 u8 vid;
139 int vdd_target, vdd_last;
140 int existing_voltage, temp_voltage, voltage; /* all in 1/10 mV */
141 int ret;
142 unsigned int orig_i2c_speed;
143 unsigned long vdd_string_override;
144 char *vdd_string;
145 static const uint16_t vdd[32] = {
146 0, /* unused */
147 9875, /* 0.9875V */
148 9750,
149 9625,
150 9500,
151 9375,
152 9250,
153 9125,
154 9000,
155 8875,
156 8750,
157 8625,
158 8500,
159 8375,
160 8250,
161 8125,
162 10000, /* 1.0000V */
163 10125,
164 10250,
165 10375,
166 10500,
167 10625,
168 10750,
169 10875,
170 11000,
171 0, /* reserved */
172 };
173 struct vdd_drive {
174 u8 vid;
175 unsigned voltage;
176 };
177
178 ret = select_i2c_ch_pca(I2C_MUX_CH_VOL_MONITOR);
179 if (ret) {
180 printf("VID: I2c failed to switch channel\n");
181 ret = -1;
182 goto exit;
183 }
184
185 /* get the voltage ID from fuse status register */
186 fusesr = in_be32(&gur->dcfg_fusesr);
187 vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_VID_SHIFT) &
188 FSL_CORENET_DCFG_FUSESR_VID_MASK;
189 if (vid == FSL_CORENET_DCFG_FUSESR_VID_MASK) {
190 vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_ALTVID_SHIFT) &
191 FSL_CORENET_DCFG_FUSESR_ALTVID_MASK;
192 }
193 vdd_target = vdd[vid];
194 debug("VID:Reading from from fuse,vid=%x vdd is %dmV\n",
195 vid, vdd_target/10);
196
197 /* check override variable for overriding VDD */
198 vdd_string = getenv("b4qds_vdd_mv");
199 if (vdd_override == 0 && vdd_string &&
200 !strict_strtoul(vdd_string, 10, &vdd_string_override))
201 vdd_override = vdd_string_override;
202 if (vdd_override >= 819 && vdd_override <= 1212) {
203 vdd_target = vdd_override * 10; /* convert to 1/10 mV */
204 debug("VDD override is %lu\n", vdd_override);
205 } else if (vdd_override != 0) {
206 printf("Invalid value.\n");
207 }
208
209 if (vdd_target == 0) {
210 printf("VID: VID not used\n");
211 ret = 0;
212 goto exit;
213 }
214
215 /*
216 * Read voltage monitor to check real voltage.
217 * Voltage monitor LSB is 4mv.
218 */
219 vdd_last = read_voltage();
220 if (vdd_last < 0) {
221 printf("VID: abort VID adjustment\n");
222 ret = -1;
223 goto exit;
224 }
225
226 debug("VID: Core voltage is at %d mV\n", vdd_last);
227 ret = select_i2c_ch_pca(I2C_MUX_CH_DPM);
228 if (ret) {
229 printf("VID: I2c failed to switch channel to DPM\n");
230 ret = -1;
231 goto exit;
232 }
233
234 /* Round up to the value of step of Voltage regulator */
235 voltage = roundup(vdd_target, ZM_STEP);
236 debug("VID: rounded up voltage = %d\n", voltage);
237
238 /* lower the speed to 100kHz to access ZM7300 device */
239 debug("VID: Setting bus speed to 100KHz if not already set\n");
240 orig_i2c_speed = i2c_get_bus_speed();
241 if (orig_i2c_speed != 100000)
242 i2c_set_bus_speed(100000);
243
244 /* Read the existing level on board, if equal to requsted one,
245 no need to re-set */
246 existing_voltage = zm_read_voltage();
247
248 /* allowing the voltage difference of one step 0.0125V acceptable */
249 if ((existing_voltage >= voltage) &&
250 (existing_voltage < (voltage + ZM_STEP))) {
251 debug("VID: voltage already set as requested,returning\n");
252 ret = existing_voltage;
253 goto out;
254 }
255 debug("VID: Changing voltage for board from %dmV to %dmV\n",
256 existing_voltage/10, voltage/10);
257
258 if (zm_disable_wp() < 0) {
259 ret = -1;
260 goto out;
261 }
262 /* Change Voltage: the change is done through all the steps in the
263 way, to avoid reset to the board due to power good signal fail
264 in big voltage change gap jump.
265 */
266 if (existing_voltage > voltage) {
267 temp_voltage = existing_voltage - ZM_STEP;
268 while (temp_voltage >= voltage) {
269 ret = zm_write_voltage(temp_voltage);
270 if (ret == temp_voltage) {
271 temp_voltage -= ZM_STEP;
272 } else {
273 /* ZM7300 device failed to set
274 * the voltage */
275 printf
276 ("VID:Stepping down vol failed:%dmV\n",
277 temp_voltage/10);
278 ret = -1;
279 goto out;
280 }
281 }
282 } else {
283 temp_voltage = existing_voltage + ZM_STEP;
284 while (temp_voltage < (voltage + ZM_STEP)) {
285 ret = zm_write_voltage(temp_voltage);
286 if (ret == temp_voltage) {
287 temp_voltage += ZM_STEP;
288 } else {
289 /* ZM7300 device failed to set
290 * the voltage */
291 printf
292 ("VID:Stepping up vol failed:%dmV\n",
293 temp_voltage/10);
294 ret = -1;
295 goto out;
296 }
297 }
298 }
299
300 if (zm_enable_wp() < 0)
301 ret = -1;
302
303 /* restore the speed to 400kHz */
304out: debug("VID: Restore the I2C bus speed to %dKHz\n",
305 orig_i2c_speed/1000);
306 i2c_set_bus_speed(orig_i2c_speed);
307 if (ret < 0)
308 goto exit;
309
310 ret = select_i2c_ch_pca(I2C_MUX_CH_VOL_MONITOR);
311 if (ret) {
312 printf("VID: I2c failed to switch channel\n");
313 ret = -1;
314 goto exit;
315 }
316 vdd_last = read_voltage();
317 select_i2c_ch_pca(I2C_CH_DEFAULT);
318
319 if (vdd_last > 0)
320 printf("VID: Core voltage %d mV\n", vdd_last);
321 else
322 ret = -1;
323
324exit:
325 if (re_enable)
326 enable_interrupts();
327 return ret;
328}
329
York Sun0789dc92012-12-23 19:25:27 +0000330int configure_vsc3316_3308(void)
331{
332 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
333 unsigned int num_vsc16_con, num_vsc08_con;
334 u32 serdes1_prtcl, serdes2_prtcl;
335 int ret;
336
337 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
338 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
339 if (!serdes1_prtcl) {
340 printf("SERDES1 is not enabled\n");
341 return 0;
342 }
343 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
344 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
345
346 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
347 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
348 if (!serdes2_prtcl) {
349 printf("SERDES2 is not enabled\n");
350 return 0;
351 }
352 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
353 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
354
355 switch (serdes1_prtcl) {
poonam aggrwal331dd1d2014-02-17 08:38:58 +0530356 case 0x29:
York Sun0789dc92012-12-23 19:25:27 +0000357 case 0x2a:
358 case 0x2C:
359 case 0x2D:
360 case 0x2E:
361 /*
362 * Configuration:
363 * SERDES: 1
364 * Lanes: A,B: SGMII
365 * Lanes: C,D,E,F,G,H: CPRI
366 */
367 debug("Configuring crossbar to use onboard SGMII PHYs:"
368 "srds_prctl:%x\n", serdes1_prtcl);
369 num_vsc16_con = NUM_CON_VSC3316;
370 /* Configure VSC3316 crossbar switch */
371 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
372 if (!ret) {
373 ret = vsc3316_config(VSC3316_TX_ADDRESS,
Shaveta Leekha93201602013-03-25 07:40:17 +0000374 vsc16_tx_4sfp_sgmii_12_56,
375 num_vsc16_con);
York Sun0789dc92012-12-23 19:25:27 +0000376 if (ret)
377 return ret;
378 ret = vsc3316_config(VSC3316_RX_ADDRESS,
Shaveta Leekha93201602013-03-25 07:40:17 +0000379 vsc16_rx_4sfp_sgmii_12_56,
380 num_vsc16_con);
York Sun0789dc92012-12-23 19:25:27 +0000381 if (ret)
382 return ret;
383 } else {
384 return ret;
385 }
386 break;
387
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530388 case 0x02:
389 case 0x04:
390 case 0x05:
391 case 0x06:
392 case 0x08:
393 case 0x09:
394 case 0x0A:
395 case 0x0B:
396 case 0x0C:
397 case 0x30:
398 case 0x32:
399 case 0x33:
400 case 0x34:
401 case 0x39:
402 case 0x3A:
403 case 0x3C:
404 case 0x3D:
405 case 0x5C:
406 case 0x5D:
407 /*
408 * Configuration:
409 * SERDES: 1
410 * Lanes: A,B: AURORA
411 * Lanes: C,d: SGMII
412 * Lanes: E,F,G,H: CPRI
413 */
414 debug("Configuring crossbar for Aurora, SGMII 3 and 4,"
415 " and CPRI. srds_prctl:%x\n", serdes1_prtcl);
416 num_vsc16_con = NUM_CON_VSC3316;
417 /* Configure VSC3316 crossbar switch */
418 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
419 if (!ret) {
420 ret = vsc3316_config(VSC3316_TX_ADDRESS,
421 vsc16_tx_sfp_sgmii_aurora,
422 num_vsc16_con);
423 if (ret)
424 return ret;
425 ret = vsc3316_config(VSC3316_RX_ADDRESS,
426 vsc16_rx_sfp_sgmii_aurora,
427 num_vsc16_con);
428 if (ret)
429 return ret;
430 } else {
431 return ret;
432 }
433 break;
434
York Sun0789dc92012-12-23 19:25:27 +0000435#ifdef CONFIG_PPC_B4420
poonam aggrwal331dd1d2014-02-17 08:38:58 +0530436 case 0x17:
York Sun0789dc92012-12-23 19:25:27 +0000437 case 0x18:
438 /*
439 * Configuration:
440 * SERDES: 1
441 * Lanes: A,B,C,D: SGMII
442 * Lanes: E,F,G,H: CPRI
443 */
444 debug("Configuring crossbar to use onboard SGMII PHYs:"
445 "srds_prctl:%x\n", serdes1_prtcl);
446 num_vsc16_con = NUM_CON_VSC3316;
447 /* Configure VSC3316 crossbar switch */
448 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
449 if (!ret) {
450 ret = vsc3316_config(VSC3316_TX_ADDRESS,
451 vsc16_tx_sgmii_lane_cd, num_vsc16_con);
452 if (ret)
453 return ret;
454 ret = vsc3316_config(VSC3316_RX_ADDRESS,
455 vsc16_rx_sgmii_lane_cd, num_vsc16_con);
456 if (ret)
457 return ret;
458 } else {
459 return ret;
460 }
461 break;
462#endif
463
464 case 0x3E:
465 case 0x0D:
466 case 0x0E:
467 case 0x12:
468 num_vsc16_con = NUM_CON_VSC3316;
469 /* Configure VSC3316 crossbar switch */
470 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
471 if (!ret) {
472 ret = vsc3316_config(VSC3316_TX_ADDRESS,
473 vsc16_tx_sfp, num_vsc16_con);
474 if (ret)
475 return ret;
476 ret = vsc3316_config(VSC3316_RX_ADDRESS,
477 vsc16_rx_sfp, num_vsc16_con);
478 if (ret)
479 return ret;
480 } else {
481 return ret;
482 }
483 break;
484 default:
485 printf("WARNING:VSC crossbars programming not supported for:%x"
486 " SerDes1 Protocol.\n", serdes1_prtcl);
487 return -1;
488 }
489
490 switch (serdes2_prtcl) {
491 case 0x9E:
492 case 0x9A:
493 case 0x98:
494 case 0xb2:
495 case 0x49:
496 case 0x4E:
497 case 0x8D:
498 case 0x7A:
499 num_vsc08_con = NUM_CON_VSC3308;
500 /* Configure VSC3308 crossbar switch */
501 ret = select_i2c_ch_pca(I2C_CH_VSC3308);
502 if (!ret) {
503 ret = vsc3308_config(VSC3308_TX_ADDRESS,
504 vsc08_tx_amc, num_vsc08_con);
505 if (ret)
506 return ret;
507 ret = vsc3308_config(VSC3308_RX_ADDRESS,
508 vsc08_rx_amc, num_vsc08_con);
509 if (ret)
510 return ret;
511 } else {
512 return ret;
513 }
514 break;
515 default:
516 printf("WARNING:VSC crossbars programming not supported for: %x"
517 " SerDes2 Protocol.\n", serdes2_prtcl);
518 return -1;
519 }
520
521 return 0;
522}
523
Shaveta Leekhad11523b2014-02-26 16:08:22 +0530524static int calibrate_pll(serdes_corenet_t *srds_regs, int pll_num)
525{
526 u32 rst_err;
527
528 /* Steps For SerDes PLLs reset and reconfiguration
529 * or PLL power-up procedure
530 */
531 debug("CALIBRATE PLL:%d\n", pll_num);
532 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
533 SRDS_RSTCTL_SDRST_B);
534 udelay(10);
535 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
536 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
537 udelay(10);
538 setbits_be32(&srds_regs->bank[pll_num].rstctl,
539 SRDS_RSTCTL_RST);
540 setbits_be32(&srds_regs->bank[pll_num].rstctl,
541 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
542 | SRDS_RSTCTL_SDRST_B));
543
544 udelay(20);
545
546 /* Check whether PLL has been locked or not */
547 rst_err = in_be32(&srds_regs->bank[pll_num].rstctl) &
548 SRDS_RSTCTL_RSTERR;
549 rst_err >>= SRDS_RSTCTL_RSTERR_SHIFT;
550 debug("RST_ERR value for PLL %d is: 0x%x:\n", pll_num, rst_err);
551 if (rst_err)
552 return rst_err;
553
554 return rst_err;
555}
556
557static int check_pll_locks(serdes_corenet_t *srds_regs, int pll_num)
558{
559 int ret = 0;
560 u32 fcap, dcbias, bcap, pllcr1, pllcr0;
561
562 if (calibrate_pll(srds_regs, pll_num)) {
563 /* STEP 1 */
564 /* Read fcap, dcbias and bcap value */
565 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
566 SRDS_PLLCR0_DCBIAS_OUT_EN);
567 fcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
568 SRDS_PLLSR2_FCAP;
569 fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
570 bcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
571 SRDS_PLLSR2_BCAP_EN;
572 bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
573 setbits_be32(&srds_regs->bank[pll_num].pllcr0,
574 SRDS_PLLCR0_DCBIAS_OUT_EN);
575 dcbias = in_be32(&srds_regs->bank[pll_num].pllsr2) &
576 SRDS_PLLSR2_DCBIAS;
577 dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
578 debug("values of bcap:%x, fcap:%x and dcbias:%x\n",
579 bcap, fcap, dcbias);
580 if (fcap == 0 && bcap == 1) {
581 /* Step 3 */
582 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
583 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
584 | SRDS_RSTCTL_SDRST_B));
585 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
586 SRDS_PLLCR1_BCAP_EN);
587 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
588 SRDS_PLLCR1_BCAP_OVD);
589 if (calibrate_pll(srds_regs, pll_num)) {
590 /*save the fcap, dcbias and bcap values*/
591 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
592 SRDS_PLLCR0_DCBIAS_OUT_EN);
593 fcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
594 & SRDS_PLLSR2_FCAP;
595 fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
596 bcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
597 & SRDS_PLLSR2_BCAP_EN;
598 bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
599 setbits_be32(&srds_regs->bank[pll_num].pllcr0,
600 SRDS_PLLCR0_DCBIAS_OUT_EN);
601 dcbias = in_be32
602 (&srds_regs->bank[pll_num].pllsr2) &
603 SRDS_PLLSR2_DCBIAS;
604 dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
605
606 /* Step 4*/
607 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
608 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
609 | SRDS_RSTCTL_SDRST_B));
610 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
611 SRDS_PLLCR1_BYP_CAL);
612 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
613 SRDS_PLLCR1_BCAP_EN);
614 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
615 SRDS_PLLCR1_BCAP_OVD);
616 /* change the fcap and dcbias to the saved
617 * values from Step 3 */
618 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
619 SRDS_PLLCR1_PLL_FCAP);
620 pllcr1 = (in_be32
621 (&srds_regs->bank[pll_num].pllcr1)|
622 (fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
623 out_be32(&srds_regs->bank[pll_num].pllcr1,
624 pllcr1);
625 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
626 SRDS_PLLCR0_DCBIAS_OVRD);
627 pllcr0 = (in_be32
628 (&srds_regs->bank[pll_num].pllcr0)|
629 (dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
630 out_be32(&srds_regs->bank[pll_num].pllcr0,
631 pllcr0);
632 ret = calibrate_pll(srds_regs, pll_num);
633 if (ret)
634 return ret;
635 } else {
636 goto out;
637 }
638 } else { /* Step 5 */
639 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
640 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
641 | SRDS_RSTCTL_SDRST_B));
642 udelay(10);
643 /* Change the fcap, dcbias, and bcap to the
644 * values from Step 1 */
645 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
646 SRDS_PLLCR1_BYP_CAL);
647 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
648 SRDS_PLLCR1_PLL_FCAP);
649 pllcr1 = (in_be32(&srds_regs->bank[pll_num].pllcr1)|
650 (fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
651 out_be32(&srds_regs->bank[pll_num].pllcr1,
652 pllcr1);
653 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
654 SRDS_PLLCR0_DCBIAS_OVRD);
655 pllcr0 = (in_be32(&srds_regs->bank[pll_num].pllcr0)|
656 (dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
657 out_be32(&srds_regs->bank[pll_num].pllcr0,
658 pllcr0);
659 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
660 SRDS_PLLCR1_BCAP_EN);
661 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
662 SRDS_PLLCR1_BCAP_OVD);
663 ret = calibrate_pll(srds_regs, pll_num);
664 if (ret)
665 return ret;
666 }
667 }
668out:
669 return 0;
670}
671
672static int check_serdes_pll_locks(void)
673{
674 serdes_corenet_t *srds1_regs =
675 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
676 serdes_corenet_t *srds2_regs =
677 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
678 int i, ret1, ret2;
679
680 debug("\nSerDes1 Lock check\n");
681 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
682 ret1 = check_pll_locks(srds1_regs, i);
683 if (ret1) {
684 printf("SerDes1, PLL:%d didnt lock\n", i);
685 return ret1;
686 }
687 }
688 debug("\nSerDes2 Lock check\n");
689 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
690 ret2 = check_pll_locks(srds2_regs, i);
691 if (ret2) {
692 printf("SerDes2, PLL:%d didnt lock\n", i);
693 return ret2;
694 }
695 }
696
697 return 0;
698}
699
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530700int config_serdes1_refclks(void)
701{
702 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
703 serdes_corenet_t *srds_regs =
704 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
705 u32 serdes1_prtcl, lane;
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530706 unsigned int flag_sgmii_aurora_prtcl = 0;
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530707 int i;
708 int ret = 0;
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530709
710 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
711 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
712 if (!serdes1_prtcl) {
713 printf("SERDES1 is not enabled\n");
714 return -1;
715 }
716 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
717 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
718
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530719 /* To prevent generation of reset request from SerDes
720 * while changing the refclks, By setting SRDS_RST_MSK bit,
721 * SerDes reset event cannot cause a reset request
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530722 */
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530723 setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
724
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530725 /* Reconfigure IDT idt8t49n222a device for CPRI to work
726 * For this SerDes1's Refclk1 and refclk2 need to be set
727 * to 122.88MHz
728 */
729 switch (serdes1_prtcl) {
730 case 0x2A:
731 case 0x2C:
732 case 0x2D:
733 case 0x2E:
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530734 case 0x02:
735 case 0x04:
736 case 0x05:
737 case 0x06:
738 case 0x08:
739 case 0x09:
740 case 0x0A:
741 case 0x0B:
742 case 0x0C:
743 case 0x30:
744 case 0x32:
745 case 0x33:
746 case 0x34:
747 case 0x39:
748 case 0x3A:
749 case 0x3C:
750 case 0x3D:
751 case 0x5C:
752 case 0x5D:
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530753 debug("Configuring idt8t49n222a for CPRI SerDes clks:"
754 " for srds_prctl:%x\n", serdes1_prtcl);
755 ret = select_i2c_ch_pca(I2C_CH_IDT);
756 if (!ret) {
757 ret = set_serdes_refclk(IDT_SERDES1_ADDRESS, 1,
758 SERDES_REFCLK_122_88,
759 SERDES_REFCLK_122_88, 0);
760 if (ret) {
761 printf("IDT8T49N222A configuration failed.\n");
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530762 goto out;
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530763 } else
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530764 debug("IDT8T49N222A configured.\n");
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530765 } else {
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530766 goto out;
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530767 }
768 select_i2c_ch_pca(I2C_CH_DEFAULT);
769
770 /* Change SerDes1's Refclk1 to 125MHz for on board
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530771 * SGMIIs or Aurora to work
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530772 */
773 for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
774 enum srds_prtcl lane_prtcl = serdes_get_prtcl
775 (0, serdes1_prtcl, lane);
776 switch (lane_prtcl) {
777 case SGMII_FM1_DTSEC1:
778 case SGMII_FM1_DTSEC2:
779 case SGMII_FM1_DTSEC3:
780 case SGMII_FM1_DTSEC4:
781 case SGMII_FM1_DTSEC5:
782 case SGMII_FM1_DTSEC6:
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530783 case AURORA:
784 flag_sgmii_aurora_prtcl++;
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530785 break;
786 default:
787 break;
788 }
789 }
790
Shaveta Leekha8d2ba982014-02-26 16:06:30 +0530791 if (flag_sgmii_aurora_prtcl)
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530792 QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
793
794 /* Steps For SerDes PLLs reset and reconfiguration after
795 * changing SerDes's refclks
796 */
Shaveta Leekha7e1ee692014-02-26 16:07:51 +0530797 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530798 debug("For PLL%d reset and reconfiguration after"
799 " changing refclks\n", i+1);
800 clrbits_be32(&srds_regs->bank[i].rstctl,
801 SRDS_RSTCTL_SDRST_B);
802 udelay(10);
803 clrbits_be32(&srds_regs->bank[i].rstctl,
804 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
805 udelay(10);
806 setbits_be32(&srds_regs->bank[i].rstctl,
807 SRDS_RSTCTL_RST);
808 setbits_be32(&srds_regs->bank[i].rstctl,
809 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
810 | SRDS_RSTCTL_SDRST_B));
811 }
812 break;
813 default:
814 printf("WARNING:IDT8T49N222A configuration not"
815 " supported for:%x SerDes1 Protocol.\n",
816 serdes1_prtcl);
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530817 }
818
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530819out:
820 /* Clearing SRDS_RST_MSK bit as now
821 * SerDes reset event can cause a reset request
822 */
823 clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
824 return ret;
825}
826
827int config_serdes2_refclks(void)
828{
829 ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
830 serdes_corenet_t *srds2_regs =
831 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
832 u32 serdes2_prtcl;
833 int ret = 0;
834 int i;
835
836 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
837 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
838 if (!serdes2_prtcl) {
839 debug("SERDES2 is not enabled\n");
840 return -ENODEV;
841 }
842 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
843 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
844
845 /* To prevent generation of reset request from SerDes
846 * while changing the refclks, By setting SRDS_RST_MSK bit,
847 * SerDes reset event cannot cause a reset request
848 */
849 setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
850
851 /* Reconfigure IDT idt8t49n222a device for PCIe SATA to work
852 * For this SerDes2's Refclk1 need to be set to 100MHz
853 */
854 switch (serdes2_prtcl) {
855 case 0x9E:
856 case 0x9A:
857 case 0xb2:
858 debug("Configuring IDT for PCIe SATA for srds_prctl:%x\n",
859 serdes2_prtcl);
860 ret = select_i2c_ch_pca(I2C_CH_IDT);
861 if (!ret) {
862 ret = set_serdes_refclk(IDT_SERDES2_ADDRESS, 2,
863 SERDES_REFCLK_100,
Shaveta Leekha7e1ee692014-02-26 16:07:51 +0530864 SERDES_REFCLK_156_25, 0);
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530865 if (ret) {
866 printf("IDT8T49N222A configuration failed.\n");
867 goto out;
868 } else
869 debug("IDT8T49N222A configured.\n");
870 } else {
871 goto out;
872 }
873 select_i2c_ch_pca(I2C_CH_DEFAULT);
874
875 /* Steps For SerDes PLLs reset and reconfiguration after
876 * changing SerDes's refclks
877 */
Shaveta Leekha7e1ee692014-02-26 16:07:51 +0530878 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530879 clrbits_be32(&srds2_regs->bank[i].rstctl,
880 SRDS_RSTCTL_SDRST_B);
881 udelay(10);
882 clrbits_be32(&srds2_regs->bank[i].rstctl,
883 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
884 udelay(10);
885 setbits_be32(&srds2_regs->bank[i].rstctl,
886 SRDS_RSTCTL_RST);
887 setbits_be32(&srds2_regs->bank[i].rstctl,
888 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
889 | SRDS_RSTCTL_SDRST_B));
Shaveta Leekhad11523b2014-02-26 16:08:22 +0530890
891 udelay(10);
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530892 }
893 break;
894 default:
895 printf("IDT configuration not supported for:%x S2 Protocol.\n",
896 serdes2_prtcl);
897 }
898
899out:
900 /* Clearing SRDS_RST_MSK bit as now
901 * SerDes reset event can cause a reset request
902 */
903 clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
904 return ret;
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530905}
906
York Sun0789dc92012-12-23 19:25:27 +0000907int board_early_init_r(void)
908{
909 const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
910 const u8 flash_esel = find_tlb_idx((void *)flashbase, 1);
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530911 int ret;
York Sun0789dc92012-12-23 19:25:27 +0000912
913 /*
914 * Remap Boot flash + PROMJET region to caching-inhibited
915 * so that flash can be erased properly.
916 */
917
918 /* Flush d-cache and invalidate i-cache of any FLASH data */
919 flush_dcache();
920 invalidate_icache();
921
922 /* invalidate existing TLB entry for flash + promjet */
923 disable_tlb(flash_esel);
924
925 set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
926 MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
927 0, flash_esel, BOOKE_PAGESZ_256M, 1);
928
929 set_liodns();
930#ifdef CONFIG_SYS_DPAA_QBMAN
931 setup_portals();
932#endif
Shaveta Leekhae1b6f4c2014-04-11 14:12:40 +0530933 /*
934 * Adjust core voltage according to voltage ID
935 * This function changes I2C mux to channel 2.
936 */
937 if (adjust_vdd(0) < 0)
938 printf("Warning: Adjusting core voltage failed\n");
939
Shaveta Leekhad1cb7742013-07-02 14:43:53 +0530940 /* SerDes1 refclks need to be set again, as default clks
941 * are not suitable for CPRI and onboard SGMIIs to work
942 * simultaneously.
943 * This function will set SerDes1's Refclk1 and refclk2
944 * as per SerDes1 protocols
945 */
946 if (config_serdes1_refclks())
947 printf("SerDes1 Refclks couldn't set properly.\n");
948 else
949 printf("SerDes1 Refclks have been set.\n");
York Sun0789dc92012-12-23 19:25:27 +0000950
Shaveta Leekha2145a3e2014-02-26 16:06:56 +0530951 /* SerDes2 refclks need to be set again, as default clks
952 * are not suitable for PCIe SATA to work
953 * This function will set SerDes2's Refclk1 and refclk2
954 * for SerDes2 protocols having PCIe in them
955 * for PCIe SATA to work
956 */
957 ret = config_serdes2_refclks();
958 if (!ret)
959 printf("SerDes2 Refclks have been set.\n");
960 else if (ret == -ENODEV)
961 printf("SerDes disable, Refclks couldn't change.\n");
962 else
963 printf("SerDes2 Refclk reconfiguring failed.\n");
964
Shaveta Leekhad11523b2014-02-26 16:08:22 +0530965#if defined(CONFIG_SYS_FSL_ERRATUM_A006384) || \
966 defined(CONFIG_SYS_FSL_ERRATUM_A006475)
967 /* Rechecking the SerDes locks after all SerDes configurations
968 * are done, As SerDes PLLs may not lock reliably at 5 G VCO
969 * and at cold temperatures.
970 * Following sequence ensure the proper locking of SerDes PLLs.
971 */
972 if (SVR_MAJ(get_svr()) == 1) {
973 if (check_serdes_pll_locks())
974 printf("SerDes plls still not locked properly.\n");
975 else
976 printf("SerDes plls have been locked well.\n");
977 }
978#endif
979
York Sun0789dc92012-12-23 19:25:27 +0000980 /* Configure VSC3316 and VSC3308 crossbar switches */
981 if (configure_vsc3316_3308())
982 printf("VSC:failed to configure VSC3316/3308.\n");
983 else
984 printf("VSC:VSC3316/3308 successfully configured.\n");
985
986 select_i2c_ch_pca(I2C_CH_DEFAULT);
987
988 return 0;
989}
990
991unsigned long get_board_sys_clk(void)
992{
993 u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
994
995 switch ((sysclk_conf & 0x0C) >> 2) {
996 case QIXIS_CLK_100:
997 return 100000000;
998 case QIXIS_CLK_125:
999 return 125000000;
1000 case QIXIS_CLK_133:
1001 return 133333333;
1002 }
1003 return 66666666;
1004}
1005
1006unsigned long get_board_ddr_clk(void)
1007{
1008 u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
1009
1010 switch (ddrclk_conf & 0x03) {
1011 case QIXIS_CLK_100:
1012 return 100000000;
1013 case QIXIS_CLK_125:
1014 return 125000000;
1015 case QIXIS_CLK_133:
1016 return 133333333;
1017 }
1018 return 66666666;
1019}
1020
1021static int serdes_refclock(u8 sw, u8 sdclk)
1022{
1023 unsigned int clock;
1024 int ret = -1;
1025 u8 brdcfg4;
1026
1027 if (sdclk == 1) {
1028 brdcfg4 = QIXIS_READ(brdcfg[4]);
1029 if ((brdcfg4 & CLK_MUX_SEL_MASK) == ETH_PHY_CLK_OUT)
1030 return SRDS_PLLCR0_RFCK_SEL_125;
1031 else
1032 clock = (sw >> 5) & 7;
1033 } else
1034 clock = (sw >> 6) & 3;
1035
1036 switch (clock) {
1037 case 0:
1038 ret = SRDS_PLLCR0_RFCK_SEL_100;
1039 break;
1040 case 1:
1041 ret = SRDS_PLLCR0_RFCK_SEL_125;
1042 break;
1043 case 2:
1044 ret = SRDS_PLLCR0_RFCK_SEL_156_25;
1045 break;
1046 case 3:
1047 ret = SRDS_PLLCR0_RFCK_SEL_161_13;
1048 break;
1049 case 4:
1050 case 5:
1051 case 6:
1052 ret = SRDS_PLLCR0_RFCK_SEL_122_88;
1053 break;
1054 default:
1055 ret = -1;
1056 break;
1057 }
1058
1059 return ret;
1060}
1061
York Sun0789dc92012-12-23 19:25:27 +00001062#define NUM_SRDS_BANKS 2
1063
1064int misc_init_r(void)
1065{
1066 u8 sw;
1067 serdes_corenet_t *srds_regs =
1068 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
1069 u32 actual[NUM_SRDS_BANKS];
1070 unsigned int i;
1071 int clock;
1072
1073 sw = QIXIS_READ(brdcfg[2]);
1074 clock = serdes_refclock(sw, 1);
1075 if (clock >= 0)
1076 actual[0] = clock;
1077 else
1078 printf("Warning: SDREFCLK1 switch setting is unsupported\n");
1079
1080 sw = QIXIS_READ(brdcfg[4]);
1081 clock = serdes_refclock(sw, 2);
1082 if (clock >= 0)
1083 actual[1] = clock;
1084 else
1085 printf("Warning: SDREFCLK2 switch setting unsupported\n");
1086
1087 for (i = 0; i < NUM_SRDS_BANKS; i++) {
1088 u32 pllcr0 = srds_regs->bank[i].pllcr0;
1089 u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK;
1090 if (expected != actual[i]) {
1091 printf("Warning: SERDES bank %u expects reference clock"
1092 " %sMHz, but actual is %sMHz\n", i + 1,
1093 serdes_clock_to_string(expected),
1094 serdes_clock_to_string(actual[i]));
1095 }
1096 }
1097
1098 return 0;
1099}
1100
1101void ft_board_setup(void *blob, bd_t *bd)
1102{
1103 phys_addr_t base;
1104 phys_size_t size;
1105
1106 ft_cpu_setup(blob, bd);
1107
1108 base = getenv_bootm_low();
1109 size = getenv_bootm_size();
1110
1111 fdt_fixup_memory(blob, (u64)base, (u64)size);
1112
1113#ifdef CONFIG_PCI
1114 pci_of_setup(blob, bd);
1115#endif
1116
1117 fdt_fixup_liodn(blob);
1118
1119#ifdef CONFIG_HAS_FSL_DR_USB
1120 fdt_fixup_dr_usb(blob, bd);
1121#endif
1122
1123#ifdef CONFIG_SYS_DPAA_FMAN
1124 fdt_fixup_fman_ethernet(blob);
1125 fdt_fixup_board_enet(blob);
1126#endif
1127}
Shaveta Leekha6942b482012-12-23 19:25:42 +00001128
1129/*
1130 * Dump board switch settings.
1131 * The bits that cannot be read/sampled via some FPGA or some
1132 * registers, they will be displayed as
1133 * underscore in binary format. mask[] has those bits.
1134 * Some bits are calculated differently than the actual switches
1135 * if booting with overriding by FPGA.
1136 */
1137void qixis_dump_switch(void)
1138{
1139 int i;
1140 u8 sw[5];
1141
1142 /*
1143 * Any bit with 1 means that bit cannot be reverse engineered.
1144 * It will be displayed as _ in binary format.
1145 */
1146 static const u8 mask[] = {0x07, 0, 0, 0xff, 0};
1147 char buf[10];
1148 u8 brdcfg[16], dutcfg[16];
1149
1150 for (i = 0; i < 16; i++) {
1151 brdcfg[i] = qixis_read(offsetof(struct qixis, brdcfg[0]) + i);
1152 dutcfg[i] = qixis_read(offsetof(struct qixis, dutcfg[0]) + i);
1153 }
1154
1155 sw[0] = ((brdcfg[0] & 0x0f) << 4) | \
1156 (brdcfg[9] & 0x08);
1157 sw[1] = ((dutcfg[1] & 0x01) << 7) | \
1158 ((dutcfg[2] & 0x07) << 4) | \
1159 ((dutcfg[6] & 0x10) >> 1) | \
1160 ((dutcfg[6] & 0x80) >> 5) | \
1161 ((dutcfg[1] & 0x40) >> 5) | \
1162 (dutcfg[6] & 0x01);
1163 sw[2] = dutcfg[0];
1164 sw[3] = 0;
1165 sw[4] = ((brdcfg[1] & 0x30) << 2) | \
1166 ((brdcfg[1] & 0xc0) >> 2) | \
1167 (brdcfg[1] & 0x0f);
1168
1169 puts("DIP switch settings:\n");
1170 for (i = 0; i < 5; i++) {
1171 printf("SW%d = 0b%s (0x%02x)\n",
1172 i + 1, byte_to_binary_mask(sw[i], mask[i], buf), sw[i]);
1173 }
1174}