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