blob: 0e61abaa760e4a06466b5af8ba99bfbeb35d44eb [file] [log] [blame]
Wang Huanc8a7d9d2014-09-05 13:52:45 +08001/*
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>
Xiubo Lie87f3b32014-11-21 17:40:58 +080011#include <asm/arch/ns_access.h>
Wang Huanc8a7d9d2014-09-05 13:52:45 +080012#include <asm/arch/clock.h>
13#include <asm/arch/fsl_serdes.h>
Minghuan Lianda419022014-10-31 13:43:44 +080014#include <asm/pcie_layerscape.h>
Wang Huanc8a7d9d2014-09-05 13:52:45 +080015#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>
Ruchika Gupta4ba4a092014-10-15 11:39:06 +053021#include <fsl_sec.h>
Alison Wang8415bb62014-12-03 15:00:48 +080022#include <spl.h>
Zhao Qiangeaa859e2014-09-26 16:25:33 +080023#ifdef CONFIG_U_QE
24#include "../../../drivers/qe/qe.h"
25#endif
26
Wang Huanc8a7d9d2014-09-05 13:52:45 +080027
28DECLARE_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
56struct 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
Alison Wangd612f0a2014-12-09 17:38:02 +080076#ifndef CONFIG_QSPI_BOOT
Wang Huanc8a7d9d2014-09-05 13:52:45 +080077static void convert_serdes_mux(int type, int need_reset);
78
79void 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}
Alison Wangd612f0a2014-12-09 17:38:02 +0800112#endif
Wang Huanc8a7d9d2014-09-05 13:52:45 +0800113
114int checkboard(void)
115{
116 puts("Board: LS1021ATWR\n");
Alison Wangd612f0a2014-12-09 17:38:02 +0800117#ifndef CONFIG_QSPI_BOOT
Wang Huanc8a7d9d2014-09-05 13:52:45 +0800118 cpld_show();
Alison Wangd612f0a2014-12-09 17:38:02 +0800119#endif
Wang Huanc8a7d9d2014-09-05 13:52:45 +0800120
121 return 0;
122}
123
124void 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
163int 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
174struct fsl_esdhc_cfg esdhc_cfg[1] = {
175 {CONFIG_SYS_FSL_ESDHC_ADDR},
176};
177
178int 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
187int 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
Alison Wangd612f0a2014-12-09 17:38:02 +0800228#ifndef CONFIG_QSPI_BOOT
Wang Huanc8a7d9d2014-09-05 13:52:45 +0800229int 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}
Alison Wangd612f0a2014-12-09 17:38:02 +0800260#endif
Wang Huanc8a7d9d2014-09-05 13:52:45 +0800261
262int 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
Wang Huanc8a7d9d2014-09-05 13:52:45 +0800267 out_be32(&scfg->etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR);
268 out_be32(&scfg->etsecmcr, SCFG_ETSECCMCR_GE2_CLK125);
Wang Huanc8a7d9d2014-09-05 13:52:45 +0800269#endif
270
271#ifdef CONFIG_FSL_IFC
272 init_early_memctl_regs();
273#endif
274
Wang Huanb4ecc8c2014-09-05 13:52:50 +0800275#ifdef CONFIG_FSL_DCU_FB
Wang Huanb4ecc8c2014-09-05 13:52:50 +0800276 out_be32(&scfg->pixclkcr, SCFG_PIXCLKCR_PXCKEN);
Wang Huanb4ecc8c2014-09-05 13:52:50 +0800277#endif
278
Alison Wangd612f0a2014-12-09 17:38:02 +0800279#ifdef CONFIG_FSL_QSPI
280 out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL);
281#endif
282
Wang Huanc8a7d9d2014-09-05 13:52:45 +0800283 return 0;
284}
285
Alison Wang8415bb62014-12-03 15:00:48 +0800286#ifdef CONFIG_SPL_BUILD
287void 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
Xiubo Lie87f3b32014-11-21 17:40:58 +0800305#ifdef CONFIG_LS102XA_NS_ACCESS
306static 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
Wang Huanc8a7d9d2014-09-05 13:52:45 +0800391int board_init(void)
392{
Jason Jin644bc7e2014-10-17 15:26:32 +0800393 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
Wang Huanc8a7d9d2014-09-05 13:52:45 +0800403#ifndef CONFIG_SYS_FSL_NO_SERDES
404 fsl_serdes_init();
Alison Wangd612f0a2014-12-09 17:38:02 +0800405#ifndef CONFIG_QSPI_BOOT
Wang Huanc8a7d9d2014-09-05 13:52:45 +0800406 config_serdes_mux();
407#endif
Alison Wangd612f0a2014-12-09 17:38:02 +0800408#endif
Wang Huanc8a7d9d2014-09-05 13:52:45 +0800409
Xiubo Lie87f3b32014-11-21 17:40:58 +0800410#ifdef CONFIG_LS102XA_NS_ACCESS
411 enable_devices_ns_access(ns_dev, ARRAY_SIZE(ns_dev));
412#endif
413
Zhao Qiangeaa859e2014-09-26 16:25:33 +0800414#ifdef CONFIG_U_QE
415 u_qe_init();
416#endif
417
Wang Huanc8a7d9d2014-09-05 13:52:45 +0800418 return 0;
419}
420
Ruchika Gupta4ba4a092014-10-15 11:39:06 +0530421#if defined(CONFIG_MISC_INIT_R)
422int misc_init_r(void)
423{
424#ifdef CONFIG_FSL_CAAM
425 return sec_init();
426#endif
427}
428#endif
429
Simon Glasse895a4b2014-10-23 18:58:47 -0600430int ft_board_setup(void *blob, bd_t *bd)
Wang Huanc8a7d9d2014-09-05 13:52:45 +0800431{
432 ft_cpu_setup(blob, bd);
Simon Glasse895a4b2014-10-23 18:58:47 -0600433
Minghuan Lianda419022014-10-31 13:43:44 +0800434#ifdef CONFIG_PCIE_LAYERSCAPE
435 ft_pcie_setup(blob, bd);
436#endif
437
Simon Glasse895a4b2014-10-23 18:58:47 -0600438 return 0;
Wang Huanc8a7d9d2014-09-05 13:52:45 +0800439}
440
441u8 flash_read8(void *addr)
442{
443 return __raw_readb(addr + 1);
444}
445
446void flash_write16(u16 val, void *addr)
447{
448 u16 shftval = (((val >> 8) & 0xff) | ((val << 8) & 0xff00));
449
450 __raw_writew(shftval, addr);
451}
452
453u16 flash_read16(void *addr)
454{
455 u16 val = __raw_readw(addr);
456
457 return (((val) >> 8) & 0x00ff) | (((val) << 8) & 0xff00);
458}
459
Alison Wangd612f0a2014-12-09 17:38:02 +0800460#ifndef CONFIG_QSPI_BOOT
Wang Huanc8a7d9d2014-09-05 13:52:45 +0800461static 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
473static 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
488U_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
494static 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
511U_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
521static 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
562void 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
594static 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
626U_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);
Alison Wangd612f0a2014-12-09 17:38:02 +0800643#endif