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