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