]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/freescale/ls1021atwr/ls1021atwr.c
ARM: ls102xa: allow all the peripheral access permission as R/W.
[karo-tx-uboot.git] / board / freescale / ls1021atwr / ls1021atwr.c
1 /*
2  * Copyright 2014 Freescale Semiconductor, Inc.
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <i2c.h>
9 #include <asm/io.h>
10 #include <asm/arch/immap_ls102xa.h>
11 #include <asm/arch/ns_access.h>
12 #include <asm/arch/clock.h>
13 #include <asm/arch/fsl_serdes.h>
14 #include <asm/pcie_layerscape.h>
15 #include <mmc.h>
16 #include <fsl_esdhc.h>
17 #include <fsl_ifc.h>
18 #include <netdev.h>
19 #include <fsl_mdio.h>
20 #include <tsec.h>
21 #include <fsl_sec.h>
22 #include <spl.h>
23 #ifdef CONFIG_U_QE
24 #include "../../../drivers/qe/qe.h"
25 #endif
26
27
28 DECLARE_GLOBAL_DATA_PTR;
29
30 #define VERSION_MASK            0x00FF
31 #define BANK_MASK               0x0001
32 #define CONFIG_RESET            0x1
33 #define INIT_RESET              0x1
34
35 #define CPLD_SET_MUX_SERDES     0x20
36 #define CPLD_SET_BOOT_BANK      0x40
37
38 #define BOOT_FROM_UPPER_BANK    0x0
39 #define BOOT_FROM_LOWER_BANK    0x1
40
41 #define LANEB_SATA              (0x01)
42 #define LANEB_SGMII1            (0x02)
43 #define LANEC_SGMII1            (0x04)
44 #define LANEC_PCIEX1            (0x08)
45 #define LANED_PCIEX2            (0x10)
46 #define LANED_SGMII2            (0x20)
47
48 #define MASK_LANE_B             0x1
49 #define MASK_LANE_C             0x2
50 #define MASK_LANE_D             0x4
51 #define MASK_SGMII              0x8
52
53 #define KEEP_STATUS             0x0
54 #define NEED_RESET              0x1
55
56 struct cpld_data {
57         u8 cpld_ver;            /* cpld revision */
58         u8 cpld_ver_sub;        /* cpld sub revision */
59         u8 pcba_ver;            /* pcb revision number */
60         u8 system_rst;          /* reset system by cpld */
61         u8 soft_mux_on;         /* CPLD override physical switches Enable */
62         u8 cfg_rcw_src1;        /* Reset config word 1 */
63         u8 cfg_rcw_src2;        /* Reset config word 2 */
64         u8 vbank;               /* Flash bank selection Control */
65         u8 gpio;                /* GPIO for TWR-ELEV */
66         u8 i2c3_ifc_mux;
67         u8 mux_spi2;
68         u8 can3_usb2_mux;       /* CAN3 and USB2 Selection */
69         u8 qe_lcd_mux;          /* QE and LCD Selection */
70         u8 serdes_mux;          /* Multiplexed pins for SerDes Lanes */
71         u8 global_rst;          /* reset with init CPLD reg to default */
72         u8 rev1;                /* Reserved */
73         u8 rev2;                /* Reserved */
74 };
75
76 #ifndef CONFIG_QSPI_BOOT
77 static void convert_serdes_mux(int type, int need_reset);
78
79 void cpld_show(void)
80 {
81         struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
82
83         printf("CPLD:  V%x.%x\nPCBA:  V%x.0\nVBank: %d\n",
84                in_8(&cpld_data->cpld_ver) & VERSION_MASK,
85                in_8(&cpld_data->cpld_ver_sub) & VERSION_MASK,
86                in_8(&cpld_data->pcba_ver) & VERSION_MASK,
87                in_8(&cpld_data->vbank) & BANK_MASK);
88
89 #ifdef CONFIG_DEBUG
90         printf("soft_mux_on =%x\n",
91                in_8(&cpld_data->soft_mux_on));
92         printf("cfg_rcw_src1 =%x\n",
93                in_8(&cpld_data->cfg_rcw_src1));
94         printf("cfg_rcw_src2 =%x\n",
95                in_8(&cpld_data->cfg_rcw_src2));
96         printf("vbank =%x\n",
97                in_8(&cpld_data->vbank));
98         printf("gpio =%x\n",
99                in_8(&cpld_data->gpio));
100         printf("i2c3_ifc_mux =%x\n",
101                in_8(&cpld_data->i2c3_ifc_mux));
102         printf("mux_spi2 =%x\n",
103                in_8(&cpld_data->mux_spi2));
104         printf("can3_usb2_mux =%x\n",
105                in_8(&cpld_data->can3_usb2_mux));
106         printf("qe_lcd_mux =%x\n",
107                in_8(&cpld_data->qe_lcd_mux));
108         printf("serdes_mux =%x\n",
109                in_8(&cpld_data->serdes_mux));
110 #endif
111 }
112 #endif
113
114 int checkboard(void)
115 {
116         puts("Board: LS1021ATWR\n");
117 #ifndef CONFIG_QSPI_BOOT
118         cpld_show();
119 #endif
120
121         return 0;
122 }
123
124 void ddrmc_init(void)
125 {
126         struct ccsr_ddr *ddr = (struct ccsr_ddr *)CONFIG_SYS_FSL_DDR_ADDR;
127
128         out_be32(&ddr->sdram_cfg, DDR_SDRAM_CFG);
129
130         out_be32(&ddr->cs0_bnds, DDR_CS0_BNDS);
131         out_be32(&ddr->cs0_config, DDR_CS0_CONFIG);
132
133         out_be32(&ddr->timing_cfg_0, DDR_TIMING_CFG_0);
134         out_be32(&ddr->timing_cfg_1, DDR_TIMING_CFG_1);
135         out_be32(&ddr->timing_cfg_2, DDR_TIMING_CFG_2);
136         out_be32(&ddr->timing_cfg_3, DDR_TIMING_CFG_3);
137         out_be32(&ddr->timing_cfg_4, DDR_TIMING_CFG_4);
138         out_be32(&ddr->timing_cfg_5, DDR_TIMING_CFG_5);
139
140         out_be32(&ddr->sdram_cfg_2,  DDR_SDRAM_CFG_2);
141
142         out_be32(&ddr->sdram_mode, DDR_SDRAM_MODE);
143         out_be32(&ddr->sdram_mode_2, DDR_SDRAM_MODE_2);
144
145         out_be32(&ddr->sdram_interval, DDR_SDRAM_INTERVAL);
146
147         out_be32(&ddr->ddr_wrlvl_cntl, DDR_DDR_WRLVL_CNTL);
148
149         out_be32(&ddr->ddr_wrlvl_cntl_2, DDR_DDR_WRLVL_CNTL_2);
150         out_be32(&ddr->ddr_wrlvl_cntl_3, DDR_DDR_WRLVL_CNTL_3);
151
152         out_be32(&ddr->ddr_cdr1, DDR_DDR_CDR1);
153         out_be32(&ddr->ddr_cdr2, DDR_DDR_CDR2);
154
155         out_be32(&ddr->sdram_clk_cntl, DDR_SDRAM_CLK_CNTL);
156         out_be32(&ddr->ddr_zq_cntl, DDR_DDR_ZQ_CNTL);
157
158         out_be32(&ddr->cs0_config_2, DDR_CS0_CONFIG_2);
159         udelay(1);
160         out_be32(&ddr->sdram_cfg, DDR_SDRAM_CFG | DDR_SDRAM_CFG_MEM_EN);
161 }
162
163 int dram_init(void)
164 {
165 #if (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
166         ddrmc_init();
167 #endif
168
169         gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
170         return 0;
171 }
172
173 #ifdef CONFIG_FSL_ESDHC
174 struct fsl_esdhc_cfg esdhc_cfg[1] = {
175         {CONFIG_SYS_FSL_ESDHC_ADDR},
176 };
177
178 int board_mmc_init(bd_t *bis)
179 {
180         esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
181
182         return fsl_esdhc_initialize(bis, &esdhc_cfg[0]);
183 }
184 #endif
185
186 #ifdef CONFIG_TSEC_ENET
187 int board_eth_init(bd_t *bis)
188 {
189         struct fsl_pq_mdio_info mdio_info;
190         struct tsec_info_struct tsec_info[4];
191         int num = 0;
192
193 #ifdef CONFIG_TSEC1
194         SET_STD_TSEC_INFO(tsec_info[num], 1);
195         if (is_serdes_configured(SGMII_TSEC1)) {
196                 puts("eTSEC1 is in sgmii mode.\n");
197                 tsec_info[num].flags |= TSEC_SGMII;
198         }
199         num++;
200 #endif
201 #ifdef CONFIG_TSEC2
202         SET_STD_TSEC_INFO(tsec_info[num], 2);
203         if (is_serdes_configured(SGMII_TSEC2)) {
204                 puts("eTSEC2 is in sgmii mode.\n");
205                 tsec_info[num].flags |= TSEC_SGMII;
206         }
207         num++;
208 #endif
209 #ifdef CONFIG_TSEC3
210         SET_STD_TSEC_INFO(tsec_info[num], 3);
211         num++;
212 #endif
213         if (!num) {
214                 printf("No TSECs initialized\n");
215                 return 0;
216         }
217
218         mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR;
219         mdio_info.name = DEFAULT_MII_NAME;
220         fsl_pq_mdio_init(bis, &mdio_info);
221
222         tsec_eth_init(bis, tsec_info, num);
223
224         return pci_eth_init(bis);
225 }
226 #endif
227
228 #ifndef CONFIG_QSPI_BOOT
229 int config_serdes_mux(void)
230 {
231         struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
232         u32 protocol = in_be32(&gur->rcwsr[4]) & RCWSR4_SRDS1_PRTCL_MASK;
233
234         protocol >>= RCWSR4_SRDS1_PRTCL_SHIFT;
235         switch (protocol) {
236         case 0x10:
237                 convert_serdes_mux(LANEB_SATA, KEEP_STATUS);
238                 convert_serdes_mux(LANED_PCIEX2 |
239                                 LANEC_PCIEX1, KEEP_STATUS);
240                 break;
241         case 0x20:
242                 convert_serdes_mux(LANEB_SGMII1, KEEP_STATUS);
243                 convert_serdes_mux(LANEC_PCIEX1, KEEP_STATUS);
244                 convert_serdes_mux(LANED_SGMII2, KEEP_STATUS);
245                 break;
246         case 0x30:
247                 convert_serdes_mux(LANEB_SATA, KEEP_STATUS);
248                 convert_serdes_mux(LANEC_SGMII1, KEEP_STATUS);
249                 convert_serdes_mux(LANED_SGMII2, KEEP_STATUS);
250                 break;
251         case 0x70:
252                 convert_serdes_mux(LANEB_SATA, KEEP_STATUS);
253                 convert_serdes_mux(LANEC_PCIEX1, KEEP_STATUS);
254                 convert_serdes_mux(LANED_SGMII2, KEEP_STATUS);
255                 break;
256         }
257
258         return 0;
259 }
260 #endif
261
262 int board_early_init_f(void)
263 {
264         struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
265
266 #ifdef CONFIG_TSEC_ENET
267         out_be32(&scfg->etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR);
268         out_be32(&scfg->etsecmcr, SCFG_ETSECCMCR_GE2_CLK125);
269 #endif
270
271 #ifdef CONFIG_FSL_IFC
272         init_early_memctl_regs();
273 #endif
274
275 #ifdef CONFIG_FSL_DCU_FB
276         out_be32(&scfg->pixclkcr, SCFG_PIXCLKCR_PXCKEN);
277 #endif
278
279 #ifdef CONFIG_FSL_QSPI
280         out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL);
281 #endif
282
283         return 0;
284 }
285
286 #ifdef CONFIG_SPL_BUILD
287 void board_init_f(ulong dummy)
288 {
289         /* Set global data pointer */
290         gd = &gdata;
291
292         /* Clear the BSS */
293         memset(__bss_start, 0, __bss_end - __bss_start);
294
295         get_clocks();
296
297         preloader_console_init();
298
299         dram_init();
300
301         board_init_r(NULL, 0);
302 }
303 #endif
304
305 #ifdef CONFIG_LS102XA_NS_ACCESS
306 static struct csu_ns_dev ns_dev[] = {
307         { CSU_CSLX_PCIE2_IO, CSU_ALL_RW },
308         { CSU_CSLX_PCIE1_IO, CSU_ALL_RW },
309         { CSU_CSLX_MG2TPR_IP, CSU_ALL_RW },
310         { CSU_CSLX_IFC_MEM, CSU_ALL_RW },
311         { CSU_CSLX_OCRAM, CSU_ALL_RW },
312         { CSU_CSLX_GIC, CSU_ALL_RW },
313         { CSU_CSLX_PCIE1, CSU_ALL_RW },
314         { CSU_CSLX_OCRAM2, CSU_ALL_RW },
315         { CSU_CSLX_QSPI_MEM, CSU_ALL_RW },
316         { CSU_CSLX_PCIE2, CSU_ALL_RW },
317         { CSU_CSLX_SATA, CSU_ALL_RW },
318         { CSU_CSLX_USB3, CSU_ALL_RW },
319         { CSU_CSLX_SERDES, CSU_ALL_RW },
320         { CSU_CSLX_QDMA, CSU_ALL_RW },
321         { CSU_CSLX_LPUART2, CSU_ALL_RW },
322         { CSU_CSLX_LPUART1, CSU_ALL_RW },
323         { CSU_CSLX_LPUART4, CSU_ALL_RW },
324         { CSU_CSLX_LPUART3, CSU_ALL_RW },
325         { CSU_CSLX_LPUART6, CSU_ALL_RW },
326         { CSU_CSLX_LPUART5, CSU_ALL_RW },
327         { CSU_CSLX_DSPI2, CSU_ALL_RW },
328         { CSU_CSLX_DSPI1, CSU_ALL_RW },
329         { CSU_CSLX_QSPI, CSU_ALL_RW },
330         { CSU_CSLX_ESDHC, CSU_ALL_RW },
331         { CSU_CSLX_2D_ACE, CSU_ALL_RW },
332         { CSU_CSLX_IFC, CSU_ALL_RW },
333         { CSU_CSLX_I2C1, CSU_ALL_RW },
334         { CSU_CSLX_USB2, CSU_ALL_RW },
335         { CSU_CSLX_I2C3, CSU_ALL_RW },
336         { CSU_CSLX_I2C2, CSU_ALL_RW },
337         { CSU_CSLX_DUART2, CSU_ALL_RW },
338         { CSU_CSLX_DUART1, CSU_ALL_RW },
339         { CSU_CSLX_WDT2, CSU_ALL_RW },
340         { CSU_CSLX_WDT1, CSU_ALL_RW },
341         { CSU_CSLX_EDMA, CSU_ALL_RW },
342         { CSU_CSLX_SYS_CNT, CSU_ALL_RW },
343         { CSU_CSLX_DMA_MUX2, CSU_ALL_RW },
344         { CSU_CSLX_DMA_MUX1, CSU_ALL_RW },
345         { CSU_CSLX_DDR, CSU_ALL_RW },
346         { CSU_CSLX_QUICC, CSU_ALL_RW },
347         { CSU_CSLX_DCFG_CCU_RCPM, CSU_ALL_RW },
348         { CSU_CSLX_SECURE_BOOTROM, CSU_ALL_RW },
349         { CSU_CSLX_SFP, CSU_ALL_RW },
350         { CSU_CSLX_TMU, CSU_ALL_RW },
351         { CSU_CSLX_SECURE_MONITOR, CSU_ALL_RW },
352         { CSU_CSLX_RESERVED0, CSU_ALL_RW },
353         { CSU_CSLX_ETSEC1, CSU_ALL_RW },
354         { CSU_CSLX_SEC5_5, CSU_ALL_RW },
355         { CSU_CSLX_ETSEC3, CSU_ALL_RW },
356         { CSU_CSLX_ETSEC2, CSU_ALL_RW },
357         { CSU_CSLX_GPIO2, CSU_ALL_RW },
358         { CSU_CSLX_GPIO1, CSU_ALL_RW },
359         { CSU_CSLX_GPIO4, CSU_ALL_RW },
360         { CSU_CSLX_GPIO3, CSU_ALL_RW },
361         { CSU_CSLX_PLATFORM_CONT, CSU_ALL_RW },
362         { CSU_CSLX_CSU, CSU_ALL_RW },
363         { CSU_CSLX_ASRC, CSU_ALL_RW },
364         { CSU_CSLX_SPDIF, CSU_ALL_RW },
365         { CSU_CSLX_FLEXCAN2, CSU_ALL_RW },
366         { CSU_CSLX_FLEXCAN1, CSU_ALL_RW },
367         { CSU_CSLX_FLEXCAN4, CSU_ALL_RW },
368         { CSU_CSLX_FLEXCAN3, CSU_ALL_RW },
369         { CSU_CSLX_SAI2, CSU_ALL_RW },
370         { CSU_CSLX_SAI1, CSU_ALL_RW },
371         { CSU_CSLX_SAI4, CSU_ALL_RW },
372         { CSU_CSLX_SAI3, CSU_ALL_RW },
373         { CSU_CSLX_FTM2, CSU_ALL_RW },
374         { CSU_CSLX_FTM1, CSU_ALL_RW },
375         { CSU_CSLX_FTM4, CSU_ALL_RW },
376         { CSU_CSLX_FTM3, CSU_ALL_RW },
377         { CSU_CSLX_FTM6, CSU_ALL_RW },
378         { CSU_CSLX_FTM5, CSU_ALL_RW },
379         { CSU_CSLX_FTM8, CSU_ALL_RW },
380         { CSU_CSLX_FTM7, CSU_ALL_RW },
381         { CSU_CSLX_COP_DCSR, CSU_ALL_RW },
382         { CSU_CSLX_EPU, CSU_ALL_RW },
383         { CSU_CSLX_GDI, CSU_ALL_RW },
384         { CSU_CSLX_DDI, CSU_ALL_RW },
385         { CSU_CSLX_RESERVED1, CSU_ALL_RW },
386         { CSU_CSLX_USB3_PHY, CSU_ALL_RW },
387         { CSU_CSLX_RESERVED2, CSU_ALL_RW },
388 };
389 #endif
390
391 int board_init(void)
392 {
393         struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR;
394
395         /*
396          * Set CCI-400 Slave interface S0, S1, S2 Shareable Override Register
397          * All transactions are treated as non-shareable
398          */
399         out_le32(&cci->slave[0].sha_ord, CCI400_SHAORD_NON_SHAREABLE);
400         out_le32(&cci->slave[1].sha_ord, CCI400_SHAORD_NON_SHAREABLE);
401         out_le32(&cci->slave[2].sha_ord, CCI400_SHAORD_NON_SHAREABLE);
402
403 #ifndef CONFIG_SYS_FSL_NO_SERDES
404         fsl_serdes_init();
405 #ifndef CONFIG_QSPI_BOOT
406         config_serdes_mux();
407 #endif
408 #endif
409
410 #ifdef CONFIG_LS102XA_NS_ACCESS
411         enable_devices_ns_access(ns_dev, ARRAY_SIZE(ns_dev));
412 #endif
413
414 #ifdef CONFIG_U_QE
415         u_qe_init();
416 #endif
417
418         return 0;
419 }
420
421 #if defined(CONFIG_MISC_INIT_R)
422 int misc_init_r(void)
423 {
424 #ifdef CONFIG_FSL_CAAM
425         return sec_init();
426 #endif
427 }
428 #endif
429
430 int ft_board_setup(void *blob, bd_t *bd)
431 {
432         ft_cpu_setup(blob, bd);
433
434 #ifdef CONFIG_PCIE_LAYERSCAPE
435         ft_pcie_setup(blob, bd);
436 #endif
437
438         return 0;
439 }
440
441 u8 flash_read8(void *addr)
442 {
443         return __raw_readb(addr + 1);
444 }
445
446 void flash_write16(u16 val, void *addr)
447 {
448         u16 shftval = (((val >> 8) & 0xff) | ((val << 8) & 0xff00));
449
450         __raw_writew(shftval, addr);
451 }
452
453 u16 flash_read16(void *addr)
454 {
455         u16 val = __raw_readw(addr);
456
457         return (((val) >> 8) & 0x00ff) | (((val) << 8) & 0xff00);
458 }
459
460 #ifndef CONFIG_QSPI_BOOT
461 static void convert_flash_bank(char bank)
462 {
463         struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
464
465         printf("Now switch to boot from flash bank %d.\n", bank);
466         cpld_data->soft_mux_on = CPLD_SET_BOOT_BANK;
467         cpld_data->vbank = bank;
468
469         printf("Reset board to enable configuration.\n");
470         cpld_data->system_rst = CONFIG_RESET;
471 }
472
473 static int flash_bank_cmd(cmd_tbl_t *cmdtp, int flag, int argc,
474                           char * const argv[])
475 {
476         if (argc != 2)
477                 return CMD_RET_USAGE;
478         if (strcmp(argv[1], "0") == 0)
479                 convert_flash_bank(BOOT_FROM_UPPER_BANK);
480         else if (strcmp(argv[1], "1") == 0)
481                 convert_flash_bank(BOOT_FROM_LOWER_BANK);
482         else
483                 return CMD_RET_USAGE;
484
485         return 0;
486 }
487
488 U_BOOT_CMD(
489         boot_bank, 2, 0, flash_bank_cmd,
490         "Flash bank Selection Control",
491         "bank[0-upper bank/1-lower bank] (e.g. boot_bank 0)"
492 );
493
494 static int cpld_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc,
495                           char * const argv[])
496 {
497         struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
498
499         if (argc > 2)
500                 return CMD_RET_USAGE;
501         if ((argc == 1) || (strcmp(argv[1], "conf") == 0))
502                 cpld_data->system_rst = CONFIG_RESET;
503         else if (strcmp(argv[1], "init") == 0)
504                 cpld_data->global_rst = INIT_RESET;
505         else
506                 return CMD_RET_USAGE;
507
508         return 0;
509 }
510
511 U_BOOT_CMD(
512         cpld_reset, 2, 0, cpld_reset_cmd,
513         "Reset via CPLD",
514         "conf\n"
515         "       -reset with current CPLD configuration\n"
516         "init\n"
517         "       -reset and initial CPLD configuration with default value"
518
519 );
520
521 static void convert_serdes_mux(int type, int need_reset)
522 {
523         char current_serdes;
524         struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
525
526         current_serdes = cpld_data->serdes_mux;
527
528         switch (type) {
529         case LANEB_SATA:
530                 current_serdes &= ~MASK_LANE_B;
531                 break;
532         case LANEB_SGMII1:
533                 current_serdes |= (MASK_LANE_B | MASK_SGMII | MASK_LANE_C);
534                 break;
535         case LANEC_SGMII1:
536                 current_serdes &= ~(MASK_LANE_B | MASK_SGMII | MASK_LANE_C);
537                 break;
538         case LANED_SGMII2:
539                 current_serdes |= MASK_LANE_D;
540                 break;
541         case LANEC_PCIEX1:
542                 current_serdes |= MASK_LANE_C;
543                 break;
544         case (LANED_PCIEX2 | LANEC_PCIEX1):
545                 current_serdes |= MASK_LANE_C;
546                 current_serdes &= ~MASK_LANE_D;
547                 break;
548         default:
549                 printf("CPLD serdes MUX: unsupported MUX type 0x%x\n", type);
550                 return;
551         }
552
553         cpld_data->soft_mux_on |= CPLD_SET_MUX_SERDES;
554         cpld_data->serdes_mux = current_serdes;
555
556         if (need_reset == 1) {
557                 printf("Reset board to enable configuration\n");
558                 cpld_data->system_rst = CONFIG_RESET;
559         }
560 }
561
562 void print_serdes_mux(void)
563 {
564         char current_serdes;
565         struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
566
567         current_serdes = cpld_data->serdes_mux;
568
569         printf("Serdes Lane B: ");
570         if ((current_serdes & MASK_LANE_B) == 0)
571                 printf("SATA,\n");
572         else
573                 printf("SGMII 1,\n");
574
575         printf("Serdes Lane C: ");
576         if ((current_serdes & MASK_LANE_C) == 0)
577                 printf("SGMII 1,\n");
578         else
579                 printf("PCIe,\n");
580
581         printf("Serdes Lane D: ");
582         if ((current_serdes & MASK_LANE_D) == 0)
583                 printf("PCIe,\n");
584         else
585                 printf("SGMII 2,\n");
586
587         printf("SGMII 1 is on lane ");
588         if ((current_serdes & MASK_SGMII) == 0)
589                 printf("C.\n");
590         else
591                 printf("B.\n");
592 }
593
594 static int serdes_mux_cmd(cmd_tbl_t *cmdtp, int flag, int argc,
595                           char * const argv[])
596 {
597         if (argc != 2)
598                 return CMD_RET_USAGE;
599         if (strcmp(argv[1], "sata") == 0) {
600                 printf("Set serdes lane B to SATA.\n");
601                 convert_serdes_mux(LANEB_SATA, NEED_RESET);
602         } else if (strcmp(argv[1], "sgmii1b") == 0) {
603                 printf("Set serdes lane B to SGMII 1.\n");
604                 convert_serdes_mux(LANEB_SGMII1, NEED_RESET);
605         } else if (strcmp(argv[1], "sgmii1c") == 0) {
606                 printf("Set serdes lane C to SGMII 1.\n");
607                 convert_serdes_mux(LANEC_SGMII1, NEED_RESET);
608         } else if (strcmp(argv[1], "sgmii2") == 0) {
609                 printf("Set serdes lane D to SGMII 2.\n");
610                 convert_serdes_mux(LANED_SGMII2, NEED_RESET);
611         } else if (strcmp(argv[1], "pciex1") == 0) {
612                 printf("Set serdes lane C to PCIe X1.\n");
613                 convert_serdes_mux(LANEC_PCIEX1, NEED_RESET);
614         } else if (strcmp(argv[1], "pciex2") == 0) {
615                 printf("Set serdes lane C & lane D to PCIe X2.\n");
616                 convert_serdes_mux((LANED_PCIEX2 | LANEC_PCIEX1), NEED_RESET);
617         } else if (strcmp(argv[1], "show") == 0) {
618                 print_serdes_mux();
619         } else {
620                 return CMD_RET_USAGE;
621         }
622
623         return 0;
624 }
625
626 U_BOOT_CMD(
627         lane_bank, 2, 0, serdes_mux_cmd,
628         "Multiplexed function setting for SerDes Lanes",
629         "sata\n"
630         "       -change lane B to sata\n"
631         "lane_bank sgmii1b\n"
632         "       -change lane B to SGMII1\n"
633         "lane_bank sgmii1c\n"
634         "       -change lane C to SGMII1\n"
635         "lane_bank sgmii2\n"
636         "       -change lane D to SGMII2\n"
637         "lane_bank pciex1\n"
638         "       -change lane C to PCIeX1\n"
639         "lane_bank pciex2\n"
640         "       -change lane C & lane D to PCIeX2\n"
641         "\nWARNING: If you aren't familiar with the setting of serdes, don't try to change anything!\n"
642 );
643 #endif