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