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