33cd4b496489d14cc47393a2be1a525934f30fc0
[oweals/u-boot.git] / board / freescale / b4860qds / b4860qds.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2011-2012 Freescale Semiconductor, Inc.
4  */
5
6 #include <common.h>
7 #include <command.h>
8 #include <env.h>
9 #include <i2c.h>
10 #include <netdev.h>
11 #include <linux/compiler.h>
12 #include <asm/mmu.h>
13 #include <asm/processor.h>
14 #include <linux/errno.h>
15 #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_liodn.h>
20 #include <fm_eth.h>
21 #include <hwconfig.h>
22
23 #include "../common/qixis.h"
24 #include "../common/vsc3316_3308.h"
25 #include "../common/idt8t49n222a_serdes_clk.h"
26 #include "../common/zm7300.h"
27 #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
34 DECLARE_GLOBAL_DATA_PTR;
35
36 int checkboard(void)
37 {
38         char buf[64];
39         u8 sw;
40         struct cpu_type *cpu = gd->arch.cpu;
41         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
65         /*
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
84 int 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
98 /*
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
105 static 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
132 static 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 = env_get("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 */
304 out:    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
324 exit:
325         if (re_enable)
326                 enable_interrupts();
327         return ret;
328 }
329
330 int 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         char buffer[HWCONFIG_BUFFER_SIZE];
337         char *buf = NULL;
338
339         serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
340                         FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
341         if (!serdes1_prtcl) {
342                 printf("SERDES1 is not enabled\n");
343                 return 0;
344         }
345         serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
346         debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
347
348         serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
349                         FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
350         if (!serdes2_prtcl) {
351                 printf("SERDES2 is not enabled\n");
352                 return 0;
353         }
354         serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
355         debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
356
357         switch (serdes1_prtcl) {
358         case 0x29:
359         case 0x2a:
360         case 0x2C:
361         case 0x2D:
362         case 0x2E:
363                         /*
364                          * Configuration:
365                          * SERDES: 1
366                          * Lanes: A,B: SGMII
367                          * Lanes: C,D,E,F,G,H: CPRI
368                          */
369                 debug("Configuring crossbar to use onboard SGMII PHYs:"
370                                 "srds_prctl:%x\n", serdes1_prtcl);
371                 num_vsc16_con = NUM_CON_VSC3316;
372                 /* Configure VSC3316 crossbar switch */
373                 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
374                 if (!ret) {
375                         ret = vsc3316_config(VSC3316_TX_ADDRESS,
376                                         vsc16_tx_4sfp_sgmii_12_56,
377                                         num_vsc16_con);
378                         if (ret)
379                                 return ret;
380                         ret = vsc3316_config(VSC3316_RX_ADDRESS,
381                                         vsc16_rx_4sfp_sgmii_12_56,
382                                         num_vsc16_con);
383                         if (ret)
384                                 return ret;
385                 } else {
386                         return ret;
387                 }
388                 break;
389
390         case 0x01:
391         case 0x02:
392         case 0x04:
393         case 0x05:
394         case 0x06:
395         case 0x07:
396         case 0x08:
397         case 0x09:
398         case 0x0A:
399         case 0x0B:
400         case 0x0C:
401         case 0x2F:
402         case 0x30:
403         case 0x32:
404         case 0x33:
405         case 0x34:
406         case 0x39:
407         case 0x3A:
408         case 0x3C:
409         case 0x3D:
410         case 0x5C:
411         case 0x5D:
412                         /*
413                          * Configuration:
414                          * SERDES: 1
415                          * Lanes: A,B: AURORA
416                          * Lanes: C,d: SGMII
417                          * Lanes: E,F,G,H: CPRI
418                          */
419                 debug("Configuring crossbar for Aurora, SGMII 3 and 4,"
420                                 " and CPRI. srds_prctl:%x\n", serdes1_prtcl);
421                 num_vsc16_con = NUM_CON_VSC3316;
422                 /* Configure VSC3316 crossbar switch */
423                 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
424                 if (!ret) {
425                         ret = vsc3316_config(VSC3316_TX_ADDRESS,
426                                         vsc16_tx_sfp_sgmii_aurora,
427                                         num_vsc16_con);
428                         if (ret)
429                                 return ret;
430                         ret = vsc3316_config(VSC3316_RX_ADDRESS,
431                                         vsc16_rx_sfp_sgmii_aurora,
432                                         num_vsc16_con);
433                         if (ret)
434                                 return ret;
435                 } else {
436                         return ret;
437                 }
438                 break;
439
440 #ifdef CONFIG_ARCH_B4420
441         case 0x17:
442         case 0x18:
443                         /*
444                          * Configuration:
445                          * SERDES: 1
446                          * Lanes: A,B,C,D: SGMII
447                          * Lanes: E,F,G,H: CPRI
448                          */
449                 debug("Configuring crossbar to use onboard SGMII PHYs:"
450                                 "srds_prctl:%x\n", serdes1_prtcl);
451                 num_vsc16_con = NUM_CON_VSC3316;
452                 /* Configure VSC3316 crossbar switch */
453                 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
454                 if (!ret) {
455                         ret = vsc3316_config(VSC3316_TX_ADDRESS,
456                                         vsc16_tx_sgmii_lane_cd, num_vsc16_con);
457                         if (ret)
458                                 return ret;
459                         ret = vsc3316_config(VSC3316_RX_ADDRESS,
460                                         vsc16_rx_sgmii_lane_cd, num_vsc16_con);
461                         if (ret)
462                                 return ret;
463                 } else {
464                         return ret;
465                 }
466                 break;
467 #endif
468
469         case 0x3E:
470         case 0x0D:
471         case 0x0E:
472         case 0x12:
473                 num_vsc16_con = NUM_CON_VSC3316;
474                 /* Configure VSC3316 crossbar switch */
475                 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
476                 if (!ret) {
477                         ret = vsc3316_config(VSC3316_TX_ADDRESS,
478                                         vsc16_tx_sfp, num_vsc16_con);
479                         if (ret)
480                                 return ret;
481                         ret = vsc3316_config(VSC3316_RX_ADDRESS,
482                                         vsc16_rx_sfp, num_vsc16_con);
483                         if (ret)
484                                 return ret;
485                 } else {
486                         return ret;
487                 }
488                 break;
489         default:
490                 printf("WARNING:VSC crossbars programming not supported for:%x"
491                                         " SerDes1 Protocol.\n", serdes1_prtcl);
492                 return -1;
493         }
494
495         num_vsc08_con = NUM_CON_VSC3308;
496         /* Configure VSC3308 crossbar switch */
497         ret = select_i2c_ch_pca(I2C_CH_VSC3308);
498         switch (serdes2_prtcl) {
499 #ifdef CONFIG_ARCH_B4420
500         case 0x9d:
501 #endif
502         case 0x9E:
503         case 0x9A:
504         case 0x98:
505         case 0x48:
506         case 0x49:
507         case 0x4E:
508         case 0x79:
509         case 0x7A:
510                 if (!ret) {
511                         ret = vsc3308_config(VSC3308_TX_ADDRESS,
512                                         vsc08_tx_amc, num_vsc08_con);
513                         if (ret)
514                                 return ret;
515                         ret = vsc3308_config(VSC3308_RX_ADDRESS,
516                                         vsc08_rx_amc, num_vsc08_con);
517                         if (ret)
518                                 return ret;
519                 } else {
520                         return ret;
521                 }
522                 break;
523         case 0x80:
524         case 0x81:
525         case 0x82:
526         case 0x83:
527         case 0x84:
528         case 0x85:
529         case 0x86:
530         case 0x87:
531         case 0x88:
532         case 0x89:
533         case 0x8a:
534         case 0x8b:
535         case 0x8c:
536         case 0x8d:
537         case 0x8e:
538         case 0xb1:
539         case 0xb2:
540                 if (!ret) {
541                         /*
542                          * Extract hwconfig from environment since environment
543                          * is not setup properly yet
544                          */
545                         env_get_f("hwconfig", buffer, sizeof(buffer));
546                         buf = buffer;
547
548                         if (hwconfig_subarg_cmp_f("fsl_b4860_serdes2",
549                                                   "sfp_amc", "sfp", buf)) {
550 #ifdef CONFIG_SYS_FSL_B4860QDS_XFI_ERR
551                                 /* change default VSC3308 for XFI erratum */
552                                 ret = vsc3308_config_adjust(VSC3308_TX_ADDRESS,
553                                                 vsc08_tx_sfp, num_vsc08_con);
554                                 if (ret)
555                                         return ret;
556
557                                 ret = vsc3308_config_adjust(VSC3308_RX_ADDRESS,
558                                                 vsc08_rx_sfp, num_vsc08_con);
559                                 if (ret)
560                                         return ret;
561 #else
562                                 ret = vsc3308_config(VSC3308_TX_ADDRESS,
563                                                 vsc08_tx_sfp, num_vsc08_con);
564                                 if (ret)
565                                         return ret;
566
567                                 ret = vsc3308_config(VSC3308_RX_ADDRESS,
568                                                 vsc08_rx_sfp, num_vsc08_con);
569                                 if (ret)
570                                         return ret;
571 #endif
572                         } else {
573                                 ret = vsc3308_config(VSC3308_TX_ADDRESS,
574                                                 vsc08_tx_amc, num_vsc08_con);
575                                 if (ret)
576                                         return ret;
577
578                                 ret = vsc3308_config(VSC3308_RX_ADDRESS,
579                                                 vsc08_rx_amc, num_vsc08_con);
580                                 if (ret)
581                                         return ret;
582                         }
583
584                 } else {
585                         return ret;
586                 }
587                 break;
588         default:
589                 printf("WARNING:VSC crossbars programming not supported for: %x"
590                                         " SerDes2 Protocol.\n", serdes2_prtcl);
591                 return -1;
592         }
593
594         return 0;
595 }
596
597 static int calibrate_pll(serdes_corenet_t *srds_regs, int pll_num)
598 {
599         u32 rst_err;
600
601         /* Steps For SerDes PLLs reset and reconfiguration
602          * or PLL power-up procedure
603          */
604         debug("CALIBRATE PLL:%d\n", pll_num);
605         clrbits_be32(&srds_regs->bank[pll_num].rstctl,
606                         SRDS_RSTCTL_SDRST_B);
607         udelay(10);
608         clrbits_be32(&srds_regs->bank[pll_num].rstctl,
609                 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
610         udelay(10);
611         setbits_be32(&srds_regs->bank[pll_num].rstctl,
612                         SRDS_RSTCTL_RST);
613         setbits_be32(&srds_regs->bank[pll_num].rstctl,
614                 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
615                 | SRDS_RSTCTL_SDRST_B));
616
617         udelay(20);
618
619         /* Check whether PLL has been locked or not */
620         rst_err = in_be32(&srds_regs->bank[pll_num].rstctl) &
621                                 SRDS_RSTCTL_RSTERR;
622         rst_err >>= SRDS_RSTCTL_RSTERR_SHIFT;
623         debug("RST_ERR value for PLL %d is: 0x%x:\n", pll_num, rst_err);
624         if (rst_err)
625                 return rst_err;
626
627         return rst_err;
628 }
629
630 static int check_pll_locks(serdes_corenet_t *srds_regs, int pll_num)
631 {
632         int ret = 0;
633         u32 fcap, dcbias, bcap, pllcr1, pllcr0;
634
635         if (calibrate_pll(srds_regs, pll_num)) {
636                 /* STEP 1 */
637                 /* Read fcap, dcbias and bcap value */
638                 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
639                                 SRDS_PLLCR0_DCBIAS_OUT_EN);
640                 fcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
641                                         SRDS_PLLSR2_FCAP;
642                 fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
643                 bcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
644                                         SRDS_PLLSR2_BCAP_EN;
645                 bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
646                 setbits_be32(&srds_regs->bank[pll_num].pllcr0,
647                                 SRDS_PLLCR0_DCBIAS_OUT_EN);
648                 dcbias = in_be32(&srds_regs->bank[pll_num].pllsr2) &
649                                         SRDS_PLLSR2_DCBIAS;
650                 dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
651                 debug("values of bcap:%x, fcap:%x and dcbias:%x\n",
652                                         bcap, fcap, dcbias);
653                 if (fcap == 0 && bcap == 1) {
654                         /* Step 3 */
655                         clrbits_be32(&srds_regs->bank[pll_num].rstctl,
656                                 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
657                                  | SRDS_RSTCTL_SDRST_B));
658                         clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
659                                         SRDS_PLLCR1_BCAP_EN);
660                         setbits_be32(&srds_regs->bank[pll_num].pllcr1,
661                                         SRDS_PLLCR1_BCAP_OVD);
662                         if (calibrate_pll(srds_regs, pll_num)) {
663                                 /*save the fcap, dcbias and bcap values*/
664                                 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
665                                                 SRDS_PLLCR0_DCBIAS_OUT_EN);
666                                 fcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
667                                         & SRDS_PLLSR2_FCAP;
668                                 fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
669                                 bcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
670                                         & SRDS_PLLSR2_BCAP_EN;
671                                 bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
672                                 setbits_be32(&srds_regs->bank[pll_num].pllcr0,
673                                                 SRDS_PLLCR0_DCBIAS_OUT_EN);
674                                 dcbias = in_be32
675                                         (&srds_regs->bank[pll_num].pllsr2) &
676                                                         SRDS_PLLSR2_DCBIAS;
677                                 dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
678
679                                 /* Step 4*/
680                                 clrbits_be32(&srds_regs->bank[pll_num].rstctl,
681                                 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
682                                  | SRDS_RSTCTL_SDRST_B));
683                                 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
684                                                 SRDS_PLLCR1_BYP_CAL);
685                                 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
686                                                 SRDS_PLLCR1_BCAP_EN);
687                                 setbits_be32(&srds_regs->bank[pll_num].pllcr1,
688                                                 SRDS_PLLCR1_BCAP_OVD);
689                                 /* change the fcap and dcbias to the saved
690                                  * values from Step 3 */
691                                 clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
692                                                         SRDS_PLLCR1_PLL_FCAP);
693                                 pllcr1 = (in_be32
694                                         (&srds_regs->bank[pll_num].pllcr1)|
695                                         (fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
696                                 out_be32(&srds_regs->bank[pll_num].pllcr1,
697                                                         pllcr1);
698                                 clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
699                                                 SRDS_PLLCR0_DCBIAS_OVRD);
700                                 pllcr0 = (in_be32
701                                 (&srds_regs->bank[pll_num].pllcr0)|
702                                 (dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
703                                 out_be32(&srds_regs->bank[pll_num].pllcr0,
704                                                         pllcr0);
705                                 ret = calibrate_pll(srds_regs, pll_num);
706                                 if (ret)
707                                         return ret;
708                         } else {
709                                 goto out;
710                         }
711                 } else { /* Step 5 */
712                         clrbits_be32(&srds_regs->bank[pll_num].rstctl,
713                                 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
714                                  | SRDS_RSTCTL_SDRST_B));
715                         udelay(10);
716                         /* Change the fcap, dcbias, and bcap to the
717                          * values from Step 1 */
718                         setbits_be32(&srds_regs->bank[pll_num].pllcr1,
719                                         SRDS_PLLCR1_BYP_CAL);
720                         clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
721                                                 SRDS_PLLCR1_PLL_FCAP);
722                         pllcr1 = (in_be32(&srds_regs->bank[pll_num].pllcr1)|
723                                 (fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
724                         out_be32(&srds_regs->bank[pll_num].pllcr1,
725                                                 pllcr1);
726                         clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
727                                                 SRDS_PLLCR0_DCBIAS_OVRD);
728                         pllcr0 = (in_be32(&srds_regs->bank[pll_num].pllcr0)|
729                                 (dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
730                         out_be32(&srds_regs->bank[pll_num].pllcr0,
731                                                 pllcr0);
732                         clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
733                                         SRDS_PLLCR1_BCAP_EN);
734                         setbits_be32(&srds_regs->bank[pll_num].pllcr1,
735                                         SRDS_PLLCR1_BCAP_OVD);
736                         ret = calibrate_pll(srds_regs, pll_num);
737                         if (ret)
738                                 return ret;
739                 }
740         }
741 out:
742         return 0;
743 }
744
745 static int check_serdes_pll_locks(void)
746 {
747         serdes_corenet_t *srds1_regs =
748                 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
749         serdes_corenet_t *srds2_regs =
750                 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
751         int i, ret1, ret2;
752
753         debug("\nSerDes1 Lock check\n");
754         for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
755                 ret1 = check_pll_locks(srds1_regs, i);
756                 if (ret1) {
757                         printf("SerDes1, PLL:%d didnt lock\n", i);
758                         return ret1;
759                 }
760         }
761         debug("\nSerDes2 Lock check\n");
762         for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
763                 ret2 = check_pll_locks(srds2_regs, i);
764                 if (ret2) {
765                         printf("SerDes2, PLL:%d didnt lock\n", i);
766                         return ret2;
767                 }
768         }
769
770         return 0;
771 }
772
773 int config_serdes1_refclks(void)
774 {
775         ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
776         serdes_corenet_t *srds_regs =
777                 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
778         u32 serdes1_prtcl, lane;
779         unsigned int flag_sgmii_aurora_prtcl = 0;
780         int i;
781         int ret = 0;
782
783         serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
784                         FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
785         if (!serdes1_prtcl) {
786                 printf("SERDES1 is not enabled\n");
787                 return -1;
788         }
789         serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
790         debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
791
792         /* To prevent generation of reset request from SerDes
793          * while changing the refclks, By setting SRDS_RST_MSK bit,
794          * SerDes reset event cannot cause a reset request
795          */
796         setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
797
798         /* Reconfigure IDT idt8t49n222a device for CPRI to work
799          * For this SerDes1's Refclk1 and refclk2 need to be set
800          * to 122.88MHz
801          */
802         switch (serdes1_prtcl) {
803         case 0x29:
804         case 0x2A:
805         case 0x2C:
806         case 0x2D:
807         case 0x2E:
808         case 0x01:
809         case 0x02:
810         case 0x04:
811         case 0x05:
812         case 0x06:
813         case 0x07:
814         case 0x08:
815         case 0x09:
816         case 0x0A:
817         case 0x0B:
818         case 0x0C:
819         case 0x2F:
820         case 0x30:
821         case 0x32:
822         case 0x33:
823         case 0x34:
824         case 0x39:
825         case 0x3A:
826         case 0x3C:
827         case 0x3D:
828         case 0x5C:
829         case 0x5D:
830                 debug("Configuring idt8t49n222a for CPRI SerDes clks:"
831                         " for srds_prctl:%x\n", serdes1_prtcl);
832                 ret = select_i2c_ch_pca(I2C_CH_IDT);
833                 if (!ret) {
834                         ret = set_serdes_refclk(IDT_SERDES1_ADDRESS, 1,
835                                         SERDES_REFCLK_122_88,
836                                         SERDES_REFCLK_122_88, 0);
837                         if (ret) {
838                                 printf("IDT8T49N222A configuration failed.\n");
839                                 goto out;
840                         } else
841                                 debug("IDT8T49N222A configured.\n");
842                 } else {
843                         goto out;
844                 }
845                 select_i2c_ch_pca(I2C_CH_DEFAULT);
846
847                 /* Change SerDes1's Refclk1 to 125MHz for on board
848                  * SGMIIs or Aurora to work
849                  */
850                 for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
851                         enum srds_prtcl lane_prtcl = serdes_get_prtcl
852                                                 (0, serdes1_prtcl, lane);
853                         switch (lane_prtcl) {
854                         case SGMII_FM1_DTSEC1:
855                         case SGMII_FM1_DTSEC2:
856                         case SGMII_FM1_DTSEC3:
857                         case SGMII_FM1_DTSEC4:
858                         case SGMII_FM1_DTSEC5:
859                         case SGMII_FM1_DTSEC6:
860                         case AURORA:
861                                 flag_sgmii_aurora_prtcl++;
862                                 break;
863                         default:
864                                 break;
865                         }
866                 }
867
868                 if (flag_sgmii_aurora_prtcl)
869                         QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
870
871                 /* Steps For SerDes PLLs reset and reconfiguration after
872                  * changing SerDes's refclks
873                  */
874                 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
875                         debug("For PLL%d reset and reconfiguration after"
876                                " changing refclks\n", i+1);
877                         clrbits_be32(&srds_regs->bank[i].rstctl,
878                                         SRDS_RSTCTL_SDRST_B);
879                         udelay(10);
880                         clrbits_be32(&srds_regs->bank[i].rstctl,
881                                 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
882                         udelay(10);
883                         setbits_be32(&srds_regs->bank[i].rstctl,
884                                         SRDS_RSTCTL_RST);
885                         setbits_be32(&srds_regs->bank[i].rstctl,
886                                 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
887                                 | SRDS_RSTCTL_SDRST_B));
888                 }
889                 break;
890         default:
891                 printf("WARNING:IDT8T49N222A configuration not"
892                         " supported for:%x SerDes1 Protocol.\n",
893                         serdes1_prtcl);
894         }
895
896 out:
897         /* Clearing SRDS_RST_MSK bit as now
898          * SerDes reset event can cause a reset request
899          */
900         clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
901         return ret;
902 }
903
904 int config_serdes2_refclks(void)
905 {
906         ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
907         serdes_corenet_t *srds2_regs =
908                 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
909         u32 serdes2_prtcl;
910         int ret = 0;
911         int i;
912
913         serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
914                         FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
915         if (!serdes2_prtcl) {
916                 debug("SERDES2 is not enabled\n");
917                 return -ENODEV;
918         }
919         serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
920         debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
921
922         /* To prevent generation of reset request from SerDes
923          * while changing the refclks, By setting SRDS_RST_MSK bit,
924          * SerDes reset event cannot cause a reset request
925          */
926         setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
927
928         /* Reconfigure IDT idt8t49n222a device for PCIe SATA to work
929          * For this SerDes2's Refclk1 need to be set to 100MHz
930          */
931         switch (serdes2_prtcl) {
932 #ifdef CONFIG_ARCH_B4420
933         case 0x9d:
934 #endif
935         case 0x9E:
936         case 0x9A:
937                 /* fallthrough */
938         case 0xb1:
939         case 0xb2:
940                 debug("Configuring IDT for PCIe SATA for srds_prctl:%x\n",
941                         serdes2_prtcl);
942                 ret = select_i2c_ch_pca(I2C_CH_IDT);
943                 if (!ret) {
944                         ret = set_serdes_refclk(IDT_SERDES2_ADDRESS, 2,
945                                         SERDES_REFCLK_100,
946                                         SERDES_REFCLK_156_25, 0);
947                         if (ret) {
948                                 printf("IDT8T49N222A configuration failed.\n");
949                                 goto out;
950                         } else
951                                 debug("IDT8T49N222A configured.\n");
952                 } else {
953                         goto out;
954                 }
955                 select_i2c_ch_pca(I2C_CH_DEFAULT);
956
957                 /* Steps For SerDes PLLs reset and reconfiguration after
958                  * changing SerDes's refclks
959                  */
960                 for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
961                         clrbits_be32(&srds2_regs->bank[i].rstctl,
962                                         SRDS_RSTCTL_SDRST_B);
963                         udelay(10);
964                         clrbits_be32(&srds2_regs->bank[i].rstctl,
965                                 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
966                         udelay(10);
967                         setbits_be32(&srds2_regs->bank[i].rstctl,
968                                         SRDS_RSTCTL_RST);
969                         setbits_be32(&srds2_regs->bank[i].rstctl,
970                                 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
971                                 | SRDS_RSTCTL_SDRST_B));
972
973                         udelay(10);
974                 }
975                 break;
976         default:
977                 printf("IDT configuration not supported for:%x S2 Protocol.\n",
978                         serdes2_prtcl);
979         }
980
981 out:
982         /* Clearing SRDS_RST_MSK bit as now
983          * SerDes reset event can cause a reset request
984          */
985         clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
986         return ret;
987 }
988
989 int board_early_init_r(void)
990 {
991         const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
992         int flash_esel = find_tlb_idx((void *)flashbase, 1);
993         int ret;
994         u32 svr = SVR_SOC_VER(get_svr());
995
996         /* Create law for MAPLE only for personalities having MAPLE */
997         if ((svr == SVR_B4860) || (svr == SVR_B4440) ||
998             (svr == SVR_B4420) || (svr == SVR_B4220)) {
999                 set_next_law(CONFIG_SYS_MAPLE_MEM_PHYS, LAW_SIZE_16M,
1000                              LAW_TRGT_IF_MAPLE);
1001         }
1002
1003         /*
1004          * Remap Boot flash + PROMJET region to caching-inhibited
1005          * so that flash can be erased properly.
1006          */
1007
1008         /* Flush d-cache and invalidate i-cache of any FLASH data */
1009         flush_dcache();
1010         invalidate_icache();
1011
1012         if (flash_esel == -1) {
1013                 /* very unlikely unless something is messed up */
1014                 puts("Error: Could not find TLB for FLASH BASE\n");
1015                 flash_esel = 2; /* give our best effort to continue */
1016         } else {
1017                 /* invalidate existing TLB entry for flash + promjet */
1018                 disable_tlb(flash_esel);
1019         }
1020
1021         set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
1022                         MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
1023                         0, flash_esel, BOOKE_PAGESZ_256M, 1);
1024
1025         /*
1026          * Adjust core voltage according to voltage ID
1027          * This function changes I2C mux to channel 2.
1028          */
1029         if (adjust_vdd(0) < 0)
1030                 printf("Warning: Adjusting core voltage failed\n");
1031
1032         /* SerDes1 refclks need to be set again, as default clks
1033          * are not suitable for CPRI and onboard SGMIIs to work
1034          * simultaneously.
1035          * This function will set SerDes1's Refclk1 and refclk2
1036          * as per SerDes1 protocols
1037          */
1038         if (config_serdes1_refclks())
1039                 printf("SerDes1 Refclks couldn't set properly.\n");
1040         else
1041                 printf("SerDes1 Refclks have been set.\n");
1042
1043         /* SerDes2 refclks need to be set again, as default clks
1044          * are not suitable for PCIe SATA to work
1045          * This function will set SerDes2's Refclk1 and refclk2
1046          * for SerDes2 protocols having PCIe in them
1047          * for PCIe SATA to work
1048          */
1049         ret = config_serdes2_refclks();
1050         if (!ret)
1051                 printf("SerDes2 Refclks have been set.\n");
1052         else if (ret == -ENODEV)
1053                 printf("SerDes disable, Refclks couldn't change.\n");
1054         else
1055                 printf("SerDes2 Refclk reconfiguring failed.\n");
1056
1057 #if defined(CONFIG_SYS_FSL_ERRATUM_A006384) || \
1058                         defined(CONFIG_SYS_FSL_ERRATUM_A006475)
1059         /* Rechecking the SerDes locks after all SerDes configurations
1060          * are done, As SerDes PLLs may not lock reliably at 5 G VCO
1061          * and at cold temperatures.
1062          * Following sequence ensure the proper locking of SerDes PLLs.
1063          */
1064         if (SVR_MAJ(get_svr()) == 1) {
1065                 if (check_serdes_pll_locks())
1066                         printf("SerDes plls still not locked properly.\n");
1067                 else
1068                         printf("SerDes plls have been locked well.\n");
1069         }
1070 #endif
1071
1072         /* Configure VSC3316 and VSC3308 crossbar switches */
1073         if (configure_vsc3316_3308())
1074                 printf("VSC:failed to configure VSC3316/3308.\n");
1075         else
1076                 printf("VSC:VSC3316/3308 successfully configured.\n");
1077
1078         select_i2c_ch_pca(I2C_CH_DEFAULT);
1079
1080         return 0;
1081 }
1082
1083 unsigned long get_board_sys_clk(void)
1084 {
1085         u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
1086
1087         switch ((sysclk_conf & 0x0C) >> 2) {
1088         case QIXIS_CLK_100:
1089                 return 100000000;
1090         case QIXIS_CLK_125:
1091                 return 125000000;
1092         case QIXIS_CLK_133:
1093                 return 133333333;
1094         }
1095         return 66666666;
1096 }
1097
1098 unsigned long get_board_ddr_clk(void)
1099 {
1100         u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
1101
1102         switch (ddrclk_conf & 0x03) {
1103         case QIXIS_CLK_100:
1104                 return 100000000;
1105         case QIXIS_CLK_125:
1106                 return 125000000;
1107         case QIXIS_CLK_133:
1108                 return 133333333;
1109         }
1110         return 66666666;
1111 }
1112
1113 static int serdes_refclock(u8 sw, u8 sdclk)
1114 {
1115         unsigned int clock;
1116         int ret = -1;
1117         u8 brdcfg4;
1118
1119         if (sdclk == 1) {
1120                 brdcfg4 = QIXIS_READ(brdcfg[4]);
1121                 if ((brdcfg4 & CLK_MUX_SEL_MASK) == ETH_PHY_CLK_OUT)
1122                         return SRDS_PLLCR0_RFCK_SEL_125;
1123                 else
1124                         clock = (sw >> 5) & 7;
1125         } else
1126                 clock = (sw >> 6) & 3;
1127
1128         switch (clock) {
1129         case 0:
1130                 ret = SRDS_PLLCR0_RFCK_SEL_100;
1131                 break;
1132         case 1:
1133                 ret = SRDS_PLLCR0_RFCK_SEL_125;
1134                 break;
1135         case 2:
1136                 ret = SRDS_PLLCR0_RFCK_SEL_156_25;
1137                 break;
1138         case 3:
1139                 ret = SRDS_PLLCR0_RFCK_SEL_161_13;
1140                 break;
1141         case 4:
1142         case 5:
1143         case 6:
1144                 ret = SRDS_PLLCR0_RFCK_SEL_122_88;
1145                 break;
1146         default:
1147                 ret = -1;
1148                 break;
1149         }
1150
1151         return ret;
1152 }
1153
1154 #define NUM_SRDS_BANKS  2
1155
1156 int misc_init_r(void)
1157 {
1158         u8 sw;
1159         serdes_corenet_t *srds_regs =
1160                 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
1161         u32 actual[NUM_SRDS_BANKS];
1162         unsigned int i;
1163         int clock;
1164
1165         sw = QIXIS_READ(brdcfg[2]);
1166         clock = serdes_refclock(sw, 1);
1167         if (clock >= 0)
1168                 actual[0] = clock;
1169         else
1170                 printf("Warning: SDREFCLK1 switch setting is unsupported\n");
1171
1172         sw = QIXIS_READ(brdcfg[4]);
1173         clock = serdes_refclock(sw, 2);
1174         if (clock >= 0)
1175                 actual[1] = clock;
1176         else
1177                 printf("Warning: SDREFCLK2 switch setting unsupported\n");
1178
1179         for (i = 0; i < NUM_SRDS_BANKS; i++) {
1180                 u32 pllcr0 = srds_regs->bank[i].pllcr0;
1181                 u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK;
1182                 if (expected != actual[i]) {
1183                         printf("Warning: SERDES bank %u expects reference clock"
1184                                " %sMHz, but actual is %sMHz\n", i + 1,
1185                                serdes_clock_to_string(expected),
1186                                serdes_clock_to_string(actual[i]));
1187                 }
1188         }
1189
1190         return 0;
1191 }
1192
1193 int ft_board_setup(void *blob, bd_t *bd)
1194 {
1195         phys_addr_t base;
1196         phys_size_t size;
1197
1198         ft_cpu_setup(blob, bd);
1199
1200         base = env_get_bootm_low();
1201         size = env_get_bootm_size();
1202
1203         fdt_fixup_memory(blob, (u64)base, (u64)size);
1204
1205 #ifdef CONFIG_PCI
1206         pci_of_setup(blob, bd);
1207 #endif
1208
1209         fdt_fixup_liodn(blob);
1210
1211 #ifdef CONFIG_HAS_FSL_DR_USB
1212         fsl_fdt_fixup_dr_usb(blob, bd);
1213 #endif
1214
1215 #ifdef CONFIG_SYS_DPAA_FMAN
1216         fdt_fixup_fman_ethernet(blob);
1217         fdt_fixup_board_enet(blob);
1218 #endif
1219
1220         return 0;
1221 }
1222
1223 /*
1224  * Dump board switch settings.
1225  * The bits that cannot be read/sampled via some FPGA or some
1226  * registers, they will be displayed as
1227  * underscore in binary format. mask[] has those bits.
1228  * Some bits are calculated differently than the actual switches
1229  * if booting with overriding by FPGA.
1230  */
1231 void qixis_dump_switch(void)
1232 {
1233         int i;
1234         u8 sw[5];
1235
1236         /*
1237          * Any bit with 1 means that bit cannot be reverse engineered.
1238          * It will be displayed as _ in binary format.
1239          */
1240         static const u8 mask[] = {0x07, 0, 0, 0xff, 0};
1241         char buf[10];
1242         u8 brdcfg[16], dutcfg[16];
1243
1244         for (i = 0; i < 16; i++) {
1245                 brdcfg[i] = qixis_read(offsetof(struct qixis, brdcfg[0]) + i);
1246                 dutcfg[i] = qixis_read(offsetof(struct qixis, dutcfg[0]) + i);
1247         }
1248
1249         sw[0] = ((brdcfg[0] & 0x0f) << 4)       | \
1250                 (brdcfg[9] & 0x08);
1251         sw[1] = ((dutcfg[1] & 0x01) << 7)       | \
1252                 ((dutcfg[2] & 0x07) << 4)       | \
1253                 ((dutcfg[6] & 0x10) >> 1)       | \
1254                 ((dutcfg[6] & 0x80) >> 5)       | \
1255                 ((dutcfg[1] & 0x40) >> 5)       | \
1256                 (dutcfg[6] & 0x01);
1257         sw[2] = dutcfg[0];
1258         sw[3] = 0;
1259         sw[4] = ((brdcfg[1] & 0x30) << 2)       | \
1260                 ((brdcfg[1] & 0xc0) >> 2)       | \
1261                 (brdcfg[1] & 0x0f);
1262
1263         puts("DIP switch settings:\n");
1264         for (i = 0; i < 5; i++) {
1265                 printf("SW%d         = 0b%s (0x%02x)\n",
1266                         i + 1, byte_to_binary_mask(sw[i], mask[i], buf), sw[i]);
1267         }
1268 }