25b3be8663690806e18aff4923278b0afef5dc76
[karo-tx-uboot.git] / board / freescale / b4860qds / b4860qds.c
1 /*
2  * Copyright 2011-2012 Freescale Semiconductor, Inc.
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <command.h>
9 #include <i2c.h>
10 #include <netdev.h>
11 #include <linux/compiler.h>
12 #include <asm/mmu.h>
13 #include <asm/processor.h>
14 #include <asm/errno.h>
15 #include <asm/cache.h>
16 #include <asm/immap_85xx.h>
17 #include <asm/fsl_law.h>
18 #include <asm/fsl_serdes.h>
19 #include <asm/fsl_portals.h>
20 #include <asm/fsl_liodn.h>
21 #include <fm_eth.h>
22
23 #include "../common/qixis.h"
24 #include "../common/vsc3316_3308.h"
25 #include "../common/idt8t49n222a_serdes_clk.h"
26 #include "b4860qds.h"
27 #include "b4860qds_qixis.h"
28 #include "b4860qds_crossbar_con.h"
29
30 #define CLK_MUX_SEL_MASK        0x4
31 #define ETH_PHY_CLK_OUT         0x4
32 #define PLL_NUM                 2
33
34 DECLARE_GLOBAL_DATA_PTR;
35
36 int checkboard(void)
37 {
38         char buf[64];
39         u8 sw;
40         struct cpu_type *cpu = gd->arch.cpu;
41         static const char *const freq[] = {"100", "125", "156.25", "161.13",
42                                                 "122.88", "122.88", "122.88"};
43         int clock;
44
45         printf("Board: %sQDS, ", cpu->name);
46         printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, ",
47                 QIXIS_READ(id), QIXIS_READ(arch));
48
49         sw = QIXIS_READ(brdcfg[0]);
50         sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
51
52         if (sw < 0x8)
53                 printf("vBank: %d\n", sw);
54         else if (sw >= 0x8 && sw <= 0xE)
55                 puts("NAND\n");
56         else
57                 printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
58
59         printf("FPGA: v%d (%s), build %d",
60                 (int)QIXIS_READ(scver), qixis_read_tag(buf),
61                 (int)qixis_read_minor());
62         /* the timestamp string contains "\n" at the end */
63         printf(" on %s", qixis_read_time(buf));
64
65         /*
66          * Display the actual SERDES reference clocks as configured by the
67          * dip switches on the board.  Note that the SWx registers could
68          * technically be set to force the reference clocks to match the
69          * values that the SERDES expects (or vice versa).  For now, however,
70          * we just display both values and hope the user notices when they
71          * don't match.
72          */
73         puts("SERDES Reference Clocks: ");
74         sw = QIXIS_READ(brdcfg[2]);
75         clock = (sw >> 5) & 7;
76         printf("Bank1=%sMHz ", freq[clock]);
77         sw = QIXIS_READ(brdcfg[4]);
78         clock = (sw >> 6) & 3;
79         printf("Bank2=%sMHz\n", freq[clock]);
80
81         return 0;
82 }
83
84 int select_i2c_ch_pca(u8 ch)
85 {
86         int ret;
87
88         /* Selecting proper channel via PCA*/
89         ret = i2c_write(I2C_MUX_PCA_ADDR, 0x0, 1, &ch, 1);
90         if (ret) {
91                 printf("PCA: failed to select proper channel.\n");
92                 return ret;
93         }
94
95         return 0;
96 }
97
98 int configure_vsc3316_3308(void)
99 {
100         ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
101         unsigned int num_vsc16_con, num_vsc08_con;
102         u32 serdes1_prtcl, serdes2_prtcl;
103         int ret;
104
105         serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
106                         FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
107         if (!serdes1_prtcl) {
108                 printf("SERDES1 is not enabled\n");
109                 return 0;
110         }
111         serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
112         debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
113
114         serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
115                         FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
116         if (!serdes2_prtcl) {
117                 printf("SERDES2 is not enabled\n");
118                 return 0;
119         }
120         serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
121         debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
122
123         switch (serdes1_prtcl) {
124         case 0x29:
125         case 0x2a:
126         case 0x2C:
127         case 0x2D:
128         case 0x2E:
129                         /*
130                          * Configuration:
131                          * SERDES: 1
132                          * Lanes: A,B: SGMII
133                          * Lanes: C,D,E,F,G,H: CPRI
134                          */
135                 debug("Configuring crossbar to use onboard SGMII PHYs:"
136                                 "srds_prctl:%x\n", serdes1_prtcl);
137                 num_vsc16_con = NUM_CON_VSC3316;
138                 /* Configure VSC3316 crossbar switch */
139                 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
140                 if (!ret) {
141                         ret = vsc3316_config(VSC3316_TX_ADDRESS,
142                                         vsc16_tx_4sfp_sgmii_12_56,
143                                         num_vsc16_con);
144                         if (ret)
145                                 return ret;
146                         ret = vsc3316_config(VSC3316_RX_ADDRESS,
147                                         vsc16_rx_4sfp_sgmii_12_56,
148                                         num_vsc16_con);
149                         if (ret)
150                                 return ret;
151                 } else {
152                         return ret;
153                 }
154                 break;
155
156         case 0x02:
157         case 0x04:
158         case 0x05:
159         case 0x06:
160         case 0x08:
161         case 0x09:
162         case 0x0A:
163         case 0x0B:
164         case 0x0C:
165         case 0x30:
166         case 0x32:
167         case 0x33:
168         case 0x34:
169         case 0x39:
170         case 0x3A:
171         case 0x3C:
172         case 0x3D:
173         case 0x5C:
174         case 0x5D:
175                         /*
176                          * Configuration:
177                          * SERDES: 1
178                          * Lanes: A,B: AURORA
179                          * Lanes: C,d: SGMII
180                          * Lanes: E,F,G,H: CPRI
181                          */
182                 debug("Configuring crossbar for Aurora, SGMII 3 and 4,"
183                                 " and CPRI. srds_prctl:%x\n", serdes1_prtcl);
184                 num_vsc16_con = NUM_CON_VSC3316;
185                 /* Configure VSC3316 crossbar switch */
186                 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
187                 if (!ret) {
188                         ret = vsc3316_config(VSC3316_TX_ADDRESS,
189                                         vsc16_tx_sfp_sgmii_aurora,
190                                         num_vsc16_con);
191                         if (ret)
192                                 return ret;
193                         ret = vsc3316_config(VSC3316_RX_ADDRESS,
194                                         vsc16_rx_sfp_sgmii_aurora,
195                                         num_vsc16_con);
196                         if (ret)
197                                 return ret;
198                 } else {
199                         return ret;
200                 }
201                 break;
202
203 #ifdef CONFIG_PPC_B4420
204         case 0x17:
205         case 0x18:
206                         /*
207                          * Configuration:
208                          * SERDES: 1
209                          * Lanes: A,B,C,D: SGMII
210                          * Lanes: E,F,G,H: CPRI
211                          */
212                 debug("Configuring crossbar to use onboard SGMII PHYs:"
213                                 "srds_prctl:%x\n", serdes1_prtcl);
214                 num_vsc16_con = NUM_CON_VSC3316;
215                 /* Configure VSC3316 crossbar switch */
216                 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
217                 if (!ret) {
218                         ret = vsc3316_config(VSC3316_TX_ADDRESS,
219                                         vsc16_tx_sgmii_lane_cd, num_vsc16_con);
220                         if (ret)
221                                 return ret;
222                         ret = vsc3316_config(VSC3316_RX_ADDRESS,
223                                         vsc16_rx_sgmii_lane_cd, num_vsc16_con);
224                         if (ret)
225                                 return ret;
226                 } else {
227                         return ret;
228                 }
229                 break;
230 #endif
231
232         case 0x3E:
233         case 0x0D:
234         case 0x0E:
235         case 0x12:
236                 num_vsc16_con = NUM_CON_VSC3316;
237                 /* Configure VSC3316 crossbar switch */
238                 ret = select_i2c_ch_pca(I2C_CH_VSC3316);
239                 if (!ret) {
240                         ret = vsc3316_config(VSC3316_TX_ADDRESS,
241                                         vsc16_tx_sfp, num_vsc16_con);
242                         if (ret)
243                                 return ret;
244                         ret = vsc3316_config(VSC3316_RX_ADDRESS,
245                                         vsc16_rx_sfp, num_vsc16_con);
246                         if (ret)
247                                 return ret;
248                 } else {
249                         return ret;
250                 }
251                 break;
252         default:
253                 printf("WARNING:VSC crossbars programming not supported for:%x"
254                                         " SerDes1 Protocol.\n", serdes1_prtcl);
255                 return -1;
256         }
257
258         switch (serdes2_prtcl) {
259         case 0x9E:
260         case 0x9A:
261         case 0x98:
262         case 0xb2:
263         case 0x49:
264         case 0x4E:
265         case 0x8D:
266         case 0x7A:
267                 num_vsc08_con = NUM_CON_VSC3308;
268                 /* Configure VSC3308 crossbar switch */
269                 ret = select_i2c_ch_pca(I2C_CH_VSC3308);
270                 if (!ret) {
271                         ret = vsc3308_config(VSC3308_TX_ADDRESS,
272                                         vsc08_tx_amc, num_vsc08_con);
273                         if (ret)
274                                 return ret;
275                         ret = vsc3308_config(VSC3308_RX_ADDRESS,
276                                         vsc08_rx_amc, num_vsc08_con);
277                         if (ret)
278                                 return ret;
279                 } else {
280                         return ret;
281                 }
282                 break;
283         default:
284                 printf("WARNING:VSC crossbars programming not supported for: %x"
285                                         " SerDes2 Protocol.\n", serdes2_prtcl);
286                 return -1;
287         }
288
289         return 0;
290 }
291
292 int config_serdes1_refclks(void)
293 {
294         ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
295         serdes_corenet_t *srds_regs =
296                 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
297         u32 serdes1_prtcl, lane;
298         unsigned int flag_sgmii_aurora_prtcl = 0;
299         int i;
300         int ret = 0;
301
302         serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
303                         FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
304         if (!serdes1_prtcl) {
305                 printf("SERDES1 is not enabled\n");
306                 return -1;
307         }
308         serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
309         debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
310
311         /* To prevent generation of reset request from SerDes
312          * while changing the refclks, By setting SRDS_RST_MSK bit,
313          * SerDes reset event cannot cause a reset request
314          */
315         setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
316
317         /* Reconfigure IDT idt8t49n222a device for CPRI to work
318          * For this SerDes1's Refclk1 and refclk2 need to be set
319          * to 122.88MHz
320          */
321         switch (serdes1_prtcl) {
322         case 0x2A:
323         case 0x2C:
324         case 0x2D:
325         case 0x2E:
326         case 0x02:
327         case 0x04:
328         case 0x05:
329         case 0x06:
330         case 0x08:
331         case 0x09:
332         case 0x0A:
333         case 0x0B:
334         case 0x0C:
335         case 0x30:
336         case 0x32:
337         case 0x33:
338         case 0x34:
339         case 0x39:
340         case 0x3A:
341         case 0x3C:
342         case 0x3D:
343         case 0x5C:
344         case 0x5D:
345                 debug("Configuring idt8t49n222a for CPRI SerDes clks:"
346                         " for srds_prctl:%x\n", serdes1_prtcl);
347                 ret = select_i2c_ch_pca(I2C_CH_IDT);
348                 if (!ret) {
349                         ret = set_serdes_refclk(IDT_SERDES1_ADDRESS, 1,
350                                         SERDES_REFCLK_122_88,
351                                         SERDES_REFCLK_122_88, 0);
352                         if (ret) {
353                                 printf("IDT8T49N222A configuration failed.\n");
354                                 goto out;
355                         } else
356                                 debug("IDT8T49N222A configured.\n");
357                 } else {
358                         goto out;
359                 }
360                 select_i2c_ch_pca(I2C_CH_DEFAULT);
361
362                 /* Change SerDes1's Refclk1 to 125MHz for on board
363                  * SGMIIs or Aurora to work
364                  */
365                 for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
366                         enum srds_prtcl lane_prtcl = serdes_get_prtcl
367                                                 (0, serdes1_prtcl, lane);
368                         switch (lane_prtcl) {
369                         case SGMII_FM1_DTSEC1:
370                         case SGMII_FM1_DTSEC2:
371                         case SGMII_FM1_DTSEC3:
372                         case SGMII_FM1_DTSEC4:
373                         case SGMII_FM1_DTSEC5:
374                         case SGMII_FM1_DTSEC6:
375                         case AURORA:
376                                 flag_sgmii_aurora_prtcl++;
377                                 break;
378                         default:
379                                 break;
380                         }
381                 }
382
383                 if (flag_sgmii_aurora_prtcl)
384                         QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
385
386                 /* Steps For SerDes PLLs reset and reconfiguration after
387                  * changing SerDes's refclks
388                  */
389                 for (i = 0; i < PLL_NUM; i++) {
390                         debug("For PLL%d reset and reconfiguration after"
391                                " changing refclks\n", i+1);
392                         clrbits_be32(&srds_regs->bank[i].rstctl,
393                                         SRDS_RSTCTL_SDRST_B);
394                         udelay(10);
395                         clrbits_be32(&srds_regs->bank[i].rstctl,
396                                 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
397                         udelay(10);
398                         setbits_be32(&srds_regs->bank[i].rstctl,
399                                         SRDS_RSTCTL_RST);
400                         setbits_be32(&srds_regs->bank[i].rstctl,
401                                 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
402                                 | SRDS_RSTCTL_SDRST_B));
403                 }
404                 break;
405         default:
406                 printf("WARNING:IDT8T49N222A configuration not"
407                         " supported for:%x SerDes1 Protocol.\n",
408                         serdes1_prtcl);
409         }
410
411 out:
412         /* Clearing SRDS_RST_MSK bit as now
413          * SerDes reset event can cause a reset request
414          */
415         clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
416         return ret;
417 }
418
419 int config_serdes2_refclks(void)
420 {
421         ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
422         serdes_corenet_t *srds2_regs =
423                 (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
424         u32 serdes2_prtcl;
425         int ret = 0;
426         int i;
427
428         serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
429                         FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
430         if (!serdes2_prtcl) {
431                 debug("SERDES2 is not enabled\n");
432                 return -ENODEV;
433         }
434         serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
435         debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
436
437         /* To prevent generation of reset request from SerDes
438          * while changing the refclks, By setting SRDS_RST_MSK bit,
439          * SerDes reset event cannot cause a reset request
440          */
441         setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
442
443         /* Reconfigure IDT idt8t49n222a device for PCIe SATA to work
444          * For this SerDes2's Refclk1 need to be set to 100MHz
445          */
446         switch (serdes2_prtcl) {
447         case 0x9E:
448         case 0x9A:
449         case 0xb2:
450                 debug("Configuring IDT for PCIe SATA for srds_prctl:%x\n",
451                         serdes2_prtcl);
452                 ret = select_i2c_ch_pca(I2C_CH_IDT);
453                 if (!ret) {
454                         ret = set_serdes_refclk(IDT_SERDES2_ADDRESS, 2,
455                                         SERDES_REFCLK_100,
456                                         SERDES_REFCLK_100, 0);
457                         if (ret) {
458                                 printf("IDT8T49N222A configuration failed.\n");
459                                 goto out;
460                         } else
461                                 debug("IDT8T49N222A configured.\n");
462                 } else {
463                         goto out;
464                 }
465                 select_i2c_ch_pca(I2C_CH_DEFAULT);
466
467                 /* Steps For SerDes PLLs reset and reconfiguration after
468                  * changing SerDes's refclks
469                  */
470                 for (i = 0; i < PLL_NUM; i++) {
471                         clrbits_be32(&srds2_regs->bank[i].rstctl,
472                                         SRDS_RSTCTL_SDRST_B);
473                         udelay(10);
474                         clrbits_be32(&srds2_regs->bank[i].rstctl,
475                                 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
476                         udelay(10);
477                         setbits_be32(&srds2_regs->bank[i].rstctl,
478                                         SRDS_RSTCTL_RST);
479                         setbits_be32(&srds2_regs->bank[i].rstctl,
480                                 (SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
481                                 | SRDS_RSTCTL_SDRST_B));
482                 }
483                 break;
484         default:
485                 printf("IDT configuration not supported for:%x S2 Protocol.\n",
486                         serdes2_prtcl);
487         }
488
489 out:
490         /* Clearing SRDS_RST_MSK bit as now
491          * SerDes reset event can cause a reset request
492          */
493         clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
494         return ret;
495 }
496
497 int board_early_init_r(void)
498 {
499         const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
500         const u8 flash_esel = find_tlb_idx((void *)flashbase, 1);
501         int ret;
502
503         /*
504          * Remap Boot flash + PROMJET region to caching-inhibited
505          * so that flash can be erased properly.
506          */
507
508         /* Flush d-cache and invalidate i-cache of any FLASH data */
509         flush_dcache();
510         invalidate_icache();
511
512         /* invalidate existing TLB entry for flash + promjet */
513         disable_tlb(flash_esel);
514
515         set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
516                         MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
517                         0, flash_esel, BOOKE_PAGESZ_256M, 1);
518
519         set_liodns();
520 #ifdef CONFIG_SYS_DPAA_QBMAN
521         setup_portals();
522 #endif
523         /* SerDes1 refclks need to be set again, as default clks
524          * are not suitable for CPRI and onboard SGMIIs to work
525          * simultaneously.
526          * This function will set SerDes1's Refclk1 and refclk2
527          * as per SerDes1 protocols
528          */
529         if (config_serdes1_refclks())
530                 printf("SerDes1 Refclks couldn't set properly.\n");
531         else
532                 printf("SerDes1 Refclks have been set.\n");
533
534         /* SerDes2 refclks need to be set again, as default clks
535          * are not suitable for PCIe SATA to work
536          * This function will set SerDes2's Refclk1 and refclk2
537          * for SerDes2 protocols having PCIe in them
538          * for PCIe SATA to work
539          */
540         ret = config_serdes2_refclks();
541         if (!ret)
542                 printf("SerDes2 Refclks have been set.\n");
543         else if (ret == -ENODEV)
544                 printf("SerDes disable, Refclks couldn't change.\n");
545         else
546                 printf("SerDes2 Refclk reconfiguring failed.\n");
547
548         /* Configure VSC3316 and VSC3308 crossbar switches */
549         if (configure_vsc3316_3308())
550                 printf("VSC:failed to configure VSC3316/3308.\n");
551         else
552                 printf("VSC:VSC3316/3308 successfully configured.\n");
553
554         select_i2c_ch_pca(I2C_CH_DEFAULT);
555
556         return 0;
557 }
558
559 unsigned long get_board_sys_clk(void)
560 {
561         u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
562
563         switch ((sysclk_conf & 0x0C) >> 2) {
564         case QIXIS_CLK_100:
565                 return 100000000;
566         case QIXIS_CLK_125:
567                 return 125000000;
568         case QIXIS_CLK_133:
569                 return 133333333;
570         }
571         return 66666666;
572 }
573
574 unsigned long get_board_ddr_clk(void)
575 {
576         u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
577
578         switch (ddrclk_conf & 0x03) {
579         case QIXIS_CLK_100:
580                 return 100000000;
581         case QIXIS_CLK_125:
582                 return 125000000;
583         case QIXIS_CLK_133:
584                 return 133333333;
585         }
586         return 66666666;
587 }
588
589 static int serdes_refclock(u8 sw, u8 sdclk)
590 {
591         unsigned int clock;
592         int ret = -1;
593         u8 brdcfg4;
594
595         if (sdclk == 1) {
596                 brdcfg4 = QIXIS_READ(brdcfg[4]);
597                 if ((brdcfg4 & CLK_MUX_SEL_MASK) == ETH_PHY_CLK_OUT)
598                         return SRDS_PLLCR0_RFCK_SEL_125;
599                 else
600                         clock = (sw >> 5) & 7;
601         } else
602                 clock = (sw >> 6) & 3;
603
604         switch (clock) {
605         case 0:
606                 ret = SRDS_PLLCR0_RFCK_SEL_100;
607                 break;
608         case 1:
609                 ret = SRDS_PLLCR0_RFCK_SEL_125;
610                 break;
611         case 2:
612                 ret = SRDS_PLLCR0_RFCK_SEL_156_25;
613                 break;
614         case 3:
615                 ret = SRDS_PLLCR0_RFCK_SEL_161_13;
616                 break;
617         case 4:
618         case 5:
619         case 6:
620                 ret = SRDS_PLLCR0_RFCK_SEL_122_88;
621                 break;
622         default:
623                 ret = -1;
624                 break;
625         }
626
627         return ret;
628 }
629
630 #define NUM_SRDS_BANKS  2
631
632 int misc_init_r(void)
633 {
634         u8 sw;
635         serdes_corenet_t *srds_regs =
636                 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
637         u32 actual[NUM_SRDS_BANKS];
638         unsigned int i;
639         int clock;
640
641         sw = QIXIS_READ(brdcfg[2]);
642         clock = serdes_refclock(sw, 1);
643         if (clock >= 0)
644                 actual[0] = clock;
645         else
646                 printf("Warning: SDREFCLK1 switch setting is unsupported\n");
647
648         sw = QIXIS_READ(brdcfg[4]);
649         clock = serdes_refclock(sw, 2);
650         if (clock >= 0)
651                 actual[1] = clock;
652         else
653                 printf("Warning: SDREFCLK2 switch setting unsupported\n");
654
655         for (i = 0; i < NUM_SRDS_BANKS; i++) {
656                 u32 pllcr0 = srds_regs->bank[i].pllcr0;
657                 u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK;
658                 if (expected != actual[i]) {
659                         printf("Warning: SERDES bank %u expects reference clock"
660                                " %sMHz, but actual is %sMHz\n", i + 1,
661                                serdes_clock_to_string(expected),
662                                serdes_clock_to_string(actual[i]));
663                 }
664         }
665
666         return 0;
667 }
668
669 void ft_board_setup(void *blob, bd_t *bd)
670 {
671         phys_addr_t base;
672         phys_size_t size;
673
674         ft_cpu_setup(blob, bd);
675
676         base = getenv_bootm_low();
677         size = getenv_bootm_size();
678
679         fdt_fixup_memory(blob, (u64)base, (u64)size);
680
681 #ifdef CONFIG_PCI
682         pci_of_setup(blob, bd);
683 #endif
684
685         fdt_fixup_liodn(blob);
686
687 #ifdef CONFIG_HAS_FSL_DR_USB
688         fdt_fixup_dr_usb(blob, bd);
689 #endif
690
691 #ifdef CONFIG_SYS_DPAA_FMAN
692         fdt_fixup_fman_ethernet(blob);
693         fdt_fixup_board_enet(blob);
694 #endif
695 }
696
697 /*
698  * Dump board switch settings.
699  * The bits that cannot be read/sampled via some FPGA or some
700  * registers, they will be displayed as
701  * underscore in binary format. mask[] has those bits.
702  * Some bits are calculated differently than the actual switches
703  * if booting with overriding by FPGA.
704  */
705 void qixis_dump_switch(void)
706 {
707         int i;
708         u8 sw[5];
709
710         /*
711          * Any bit with 1 means that bit cannot be reverse engineered.
712          * It will be displayed as _ in binary format.
713          */
714         static const u8 mask[] = {0x07, 0, 0, 0xff, 0};
715         char buf[10];
716         u8 brdcfg[16], dutcfg[16];
717
718         for (i = 0; i < 16; i++) {
719                 brdcfg[i] = qixis_read(offsetof(struct qixis, brdcfg[0]) + i);
720                 dutcfg[i] = qixis_read(offsetof(struct qixis, dutcfg[0]) + i);
721         }
722
723         sw[0] = ((brdcfg[0] & 0x0f) << 4)       | \
724                 (brdcfg[9] & 0x08);
725         sw[1] = ((dutcfg[1] & 0x01) << 7)       | \
726                 ((dutcfg[2] & 0x07) << 4)       | \
727                 ((dutcfg[6] & 0x10) >> 1)       | \
728                 ((dutcfg[6] & 0x80) >> 5)       | \
729                 ((dutcfg[1] & 0x40) >> 5)       | \
730                 (dutcfg[6] & 0x01);
731         sw[2] = dutcfg[0];
732         sw[3] = 0;
733         sw[4] = ((brdcfg[1] & 0x30) << 2)       | \
734                 ((brdcfg[1] & 0xc0) >> 2)       | \
735                 (brdcfg[1] & 0x0f);
736
737         puts("DIP switch settings:\n");
738         for (i = 0; i < 5; i++) {
739                 printf("SW%d         = 0b%s (0x%02x)\n",
740                         i + 1, byte_to_binary_mask(sw[i], mask[i], buf), sw[i]);
741         }
742 }