xref: /OK3568_Linux_fs/u-boot/board/freescale/ls1021atwr/ls1021atwr.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2014 Freescale Semiconductor, Inc.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <i2c.h>
9*4882a593Smuzhiyun #include <asm/io.h>
10*4882a593Smuzhiyun #include <asm/arch/immap_ls102xa.h>
11*4882a593Smuzhiyun #include <asm/arch/clock.h>
12*4882a593Smuzhiyun #include <asm/arch/fsl_serdes.h>
13*4882a593Smuzhiyun #include <asm/arch/ls102xa_devdis.h>
14*4882a593Smuzhiyun #include <asm/arch/ls102xa_soc.h>
15*4882a593Smuzhiyun #include <asm/arch/ls102xa_sata.h>
16*4882a593Smuzhiyun #include <hwconfig.h>
17*4882a593Smuzhiyun #include <mmc.h>
18*4882a593Smuzhiyun #include <fsl_csu.h>
19*4882a593Smuzhiyun #include <fsl_esdhc.h>
20*4882a593Smuzhiyun #include <fsl_ifc.h>
21*4882a593Smuzhiyun #include <fsl_immap.h>
22*4882a593Smuzhiyun #include <netdev.h>
23*4882a593Smuzhiyun #include <fsl_mdio.h>
24*4882a593Smuzhiyun #include <tsec.h>
25*4882a593Smuzhiyun #include <fsl_sec.h>
26*4882a593Smuzhiyun #include <fsl_devdis.h>
27*4882a593Smuzhiyun #include <spl.h>
28*4882a593Smuzhiyun #include "../common/sleep.h"
29*4882a593Smuzhiyun #ifdef CONFIG_U_QE
30*4882a593Smuzhiyun #include <fsl_qe.h>
31*4882a593Smuzhiyun #endif
32*4882a593Smuzhiyun #include <fsl_validate.h>
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun #define VERSION_MASK		0x00FF
38*4882a593Smuzhiyun #define BANK_MASK		0x0001
39*4882a593Smuzhiyun #define CONFIG_RESET		0x1
40*4882a593Smuzhiyun #define INIT_RESET		0x1
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun #define CPLD_SET_MUX_SERDES	0x20
43*4882a593Smuzhiyun #define CPLD_SET_BOOT_BANK	0x40
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun #define BOOT_FROM_UPPER_BANK	0x0
46*4882a593Smuzhiyun #define BOOT_FROM_LOWER_BANK	0x1
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun #define LANEB_SATA		(0x01)
49*4882a593Smuzhiyun #define LANEB_SGMII1		(0x02)
50*4882a593Smuzhiyun #define LANEC_SGMII1		(0x04)
51*4882a593Smuzhiyun #define LANEC_PCIEX1		(0x08)
52*4882a593Smuzhiyun #define LANED_PCIEX2		(0x10)
53*4882a593Smuzhiyun #define LANED_SGMII2		(0x20)
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun #define MASK_LANE_B		0x1
56*4882a593Smuzhiyun #define MASK_LANE_C		0x2
57*4882a593Smuzhiyun #define MASK_LANE_D		0x4
58*4882a593Smuzhiyun #define MASK_SGMII		0x8
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun #define KEEP_STATUS		0x0
61*4882a593Smuzhiyun #define NEED_RESET		0x1
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun #define SOFT_MUX_ON_I2C3_IFC	0x2
64*4882a593Smuzhiyun #define SOFT_MUX_ON_CAN3_USB2	0x8
65*4882a593Smuzhiyun #define SOFT_MUX_ON_QE_LCD	0x10
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun #define PIN_I2C3_IFC_MUX_I2C3	0x0
68*4882a593Smuzhiyun #define PIN_I2C3_IFC_MUX_IFC	0x1
69*4882a593Smuzhiyun #define PIN_CAN3_USB2_MUX_USB2	0x0
70*4882a593Smuzhiyun #define PIN_CAN3_USB2_MUX_CAN3	0x1
71*4882a593Smuzhiyun #define PIN_QE_LCD_MUX_LCD	0x0
72*4882a593Smuzhiyun #define PIN_QE_LCD_MUX_QE	0x1
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun struct cpld_data {
75*4882a593Smuzhiyun 	u8 cpld_ver;		/* cpld revision */
76*4882a593Smuzhiyun 	u8 cpld_ver_sub;	/* cpld sub revision */
77*4882a593Smuzhiyun 	u8 pcba_ver;		/* pcb revision number */
78*4882a593Smuzhiyun 	u8 system_rst;		/* reset system by cpld */
79*4882a593Smuzhiyun 	u8 soft_mux_on;		/* CPLD override physical switches Enable */
80*4882a593Smuzhiyun 	u8 cfg_rcw_src1;	/* Reset config word 1 */
81*4882a593Smuzhiyun 	u8 cfg_rcw_src2;	/* Reset config word 2 */
82*4882a593Smuzhiyun 	u8 vbank;		/* Flash bank selection Control */
83*4882a593Smuzhiyun 	u8 gpio;		/* GPIO for TWR-ELEV */
84*4882a593Smuzhiyun 	u8 i2c3_ifc_mux;
85*4882a593Smuzhiyun 	u8 mux_spi2;
86*4882a593Smuzhiyun 	u8 can3_usb2_mux;	/* CAN3 and USB2 Selection */
87*4882a593Smuzhiyun 	u8 qe_lcd_mux;		/* QE and LCD Selection */
88*4882a593Smuzhiyun 	u8 serdes_mux;		/* Multiplexed pins for SerDes Lanes */
89*4882a593Smuzhiyun 	u8 global_rst;		/* reset with init CPLD reg to default */
90*4882a593Smuzhiyun 	u8 rev1;		/* Reserved */
91*4882a593Smuzhiyun 	u8 rev2;		/* Reserved */
92*4882a593Smuzhiyun };
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun #if !defined(CONFIG_QSPI_BOOT) && !defined(CONFIG_SD_BOOT_QSPI)
95*4882a593Smuzhiyun static void convert_serdes_mux(int type, int need_reset);
96*4882a593Smuzhiyun 
cpld_show(void)97*4882a593Smuzhiyun void cpld_show(void)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun 	struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	printf("CPLD:  V%x.%x\nPCBA:  V%x.0\nVBank: %d\n",
102*4882a593Smuzhiyun 	       in_8(&cpld_data->cpld_ver) & VERSION_MASK,
103*4882a593Smuzhiyun 	       in_8(&cpld_data->cpld_ver_sub) & VERSION_MASK,
104*4882a593Smuzhiyun 	       in_8(&cpld_data->pcba_ver) & VERSION_MASK,
105*4882a593Smuzhiyun 	       in_8(&cpld_data->vbank) & BANK_MASK);
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun #ifdef CONFIG_DEBUG
108*4882a593Smuzhiyun 	printf("soft_mux_on =%x\n",
109*4882a593Smuzhiyun 	       in_8(&cpld_data->soft_mux_on));
110*4882a593Smuzhiyun 	printf("cfg_rcw_src1 =%x\n",
111*4882a593Smuzhiyun 	       in_8(&cpld_data->cfg_rcw_src1));
112*4882a593Smuzhiyun 	printf("cfg_rcw_src2 =%x\n",
113*4882a593Smuzhiyun 	       in_8(&cpld_data->cfg_rcw_src2));
114*4882a593Smuzhiyun 	printf("vbank =%x\n",
115*4882a593Smuzhiyun 	       in_8(&cpld_data->vbank));
116*4882a593Smuzhiyun 	printf("gpio =%x\n",
117*4882a593Smuzhiyun 	       in_8(&cpld_data->gpio));
118*4882a593Smuzhiyun 	printf("i2c3_ifc_mux =%x\n",
119*4882a593Smuzhiyun 	       in_8(&cpld_data->i2c3_ifc_mux));
120*4882a593Smuzhiyun 	printf("mux_spi2 =%x\n",
121*4882a593Smuzhiyun 	       in_8(&cpld_data->mux_spi2));
122*4882a593Smuzhiyun 	printf("can3_usb2_mux =%x\n",
123*4882a593Smuzhiyun 	       in_8(&cpld_data->can3_usb2_mux));
124*4882a593Smuzhiyun 	printf("qe_lcd_mux =%x\n",
125*4882a593Smuzhiyun 	       in_8(&cpld_data->qe_lcd_mux));
126*4882a593Smuzhiyun 	printf("serdes_mux =%x\n",
127*4882a593Smuzhiyun 	       in_8(&cpld_data->serdes_mux));
128*4882a593Smuzhiyun #endif
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun #endif
131*4882a593Smuzhiyun 
checkboard(void)132*4882a593Smuzhiyun int checkboard(void)
133*4882a593Smuzhiyun {
134*4882a593Smuzhiyun 	puts("Board: LS1021ATWR\n");
135*4882a593Smuzhiyun #if !defined(CONFIG_QSPI_BOOT) && !defined(CONFIG_SD_BOOT_QSPI)
136*4882a593Smuzhiyun 	cpld_show();
137*4882a593Smuzhiyun #endif
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	return 0;
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun 
ddrmc_init(void)142*4882a593Smuzhiyun void ddrmc_init(void)
143*4882a593Smuzhiyun {
144*4882a593Smuzhiyun 	struct ccsr_ddr *ddr = (struct ccsr_ddr *)CONFIG_SYS_FSL_DDR_ADDR;
145*4882a593Smuzhiyun 	u32 temp_sdram_cfg, tmp;
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	out_be32(&ddr->sdram_cfg, DDR_SDRAM_CFG);
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	out_be32(&ddr->cs0_bnds, DDR_CS0_BNDS);
150*4882a593Smuzhiyun 	out_be32(&ddr->cs0_config, DDR_CS0_CONFIG);
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	out_be32(&ddr->timing_cfg_0, DDR_TIMING_CFG_0);
153*4882a593Smuzhiyun 	out_be32(&ddr->timing_cfg_1, DDR_TIMING_CFG_1);
154*4882a593Smuzhiyun 	out_be32(&ddr->timing_cfg_2, DDR_TIMING_CFG_2);
155*4882a593Smuzhiyun 	out_be32(&ddr->timing_cfg_3, DDR_TIMING_CFG_3);
156*4882a593Smuzhiyun 	out_be32(&ddr->timing_cfg_4, DDR_TIMING_CFG_4);
157*4882a593Smuzhiyun 	out_be32(&ddr->timing_cfg_5, DDR_TIMING_CFG_5);
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun #ifdef CONFIG_DEEP_SLEEP
160*4882a593Smuzhiyun 	if (is_warm_boot()) {
161*4882a593Smuzhiyun 		out_be32(&ddr->sdram_cfg_2,
162*4882a593Smuzhiyun 			 DDR_SDRAM_CFG_2 & ~SDRAM_CFG2_D_INIT);
163*4882a593Smuzhiyun 		out_be32(&ddr->init_addr, CONFIG_SYS_SDRAM_BASE);
164*4882a593Smuzhiyun 		out_be32(&ddr->init_ext_addr, (1 << 31));
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun 		/* DRAM VRef will not be trained */
167*4882a593Smuzhiyun 		out_be32(&ddr->ddr_cdr2,
168*4882a593Smuzhiyun 			 DDR_DDR_CDR2 & ~DDR_CDR2_VREF_TRAIN_EN);
169*4882a593Smuzhiyun 	} else
170*4882a593Smuzhiyun #endif
171*4882a593Smuzhiyun 	{
172*4882a593Smuzhiyun 		out_be32(&ddr->sdram_cfg_2, DDR_SDRAM_CFG_2);
173*4882a593Smuzhiyun 		out_be32(&ddr->ddr_cdr2, DDR_DDR_CDR2);
174*4882a593Smuzhiyun 	}
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	out_be32(&ddr->sdram_mode, DDR_SDRAM_MODE);
177*4882a593Smuzhiyun 	out_be32(&ddr->sdram_mode_2, DDR_SDRAM_MODE_2);
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	out_be32(&ddr->sdram_interval, DDR_SDRAM_INTERVAL);
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	out_be32(&ddr->ddr_wrlvl_cntl, DDR_DDR_WRLVL_CNTL);
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 	out_be32(&ddr->ddr_wrlvl_cntl_2, DDR_DDR_WRLVL_CNTL_2);
184*4882a593Smuzhiyun 	out_be32(&ddr->ddr_wrlvl_cntl_3, DDR_DDR_WRLVL_CNTL_3);
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	out_be32(&ddr->ddr_cdr1, DDR_DDR_CDR1);
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	out_be32(&ddr->sdram_clk_cntl, DDR_SDRAM_CLK_CNTL);
189*4882a593Smuzhiyun 	out_be32(&ddr->ddr_zq_cntl, DDR_DDR_ZQ_CNTL);
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	out_be32(&ddr->cs0_config_2, DDR_CS0_CONFIG_2);
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	/* DDR erratum A-009942 */
194*4882a593Smuzhiyun 	tmp = in_be32(&ddr->debug[28]);
195*4882a593Smuzhiyun 	out_be32(&ddr->debug[28], tmp | 0x0070006f);
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	udelay(1);
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun #ifdef CONFIG_DEEP_SLEEP
200*4882a593Smuzhiyun 	if (is_warm_boot()) {
201*4882a593Smuzhiyun 		/* enter self-refresh */
202*4882a593Smuzhiyun 		temp_sdram_cfg = in_be32(&ddr->sdram_cfg_2);
203*4882a593Smuzhiyun 		temp_sdram_cfg |= SDRAM_CFG2_FRC_SR;
204*4882a593Smuzhiyun 		out_be32(&ddr->sdram_cfg_2, temp_sdram_cfg);
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 		temp_sdram_cfg = (DDR_SDRAM_CFG_MEM_EN | SDRAM_CFG_BI);
207*4882a593Smuzhiyun 	} else
208*4882a593Smuzhiyun #endif
209*4882a593Smuzhiyun 		temp_sdram_cfg = (DDR_SDRAM_CFG_MEM_EN & ~SDRAM_CFG_BI);
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	out_be32(&ddr->sdram_cfg, DDR_SDRAM_CFG | temp_sdram_cfg);
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun #ifdef CONFIG_DEEP_SLEEP
214*4882a593Smuzhiyun 	if (is_warm_boot()) {
215*4882a593Smuzhiyun 		/* exit self-refresh */
216*4882a593Smuzhiyun 		temp_sdram_cfg = in_be32(&ddr->sdram_cfg_2);
217*4882a593Smuzhiyun 		temp_sdram_cfg &= ~SDRAM_CFG2_FRC_SR;
218*4882a593Smuzhiyun 		out_be32(&ddr->sdram_cfg_2, temp_sdram_cfg);
219*4882a593Smuzhiyun 	}
220*4882a593Smuzhiyun #endif
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun 
dram_init(void)223*4882a593Smuzhiyun int dram_init(void)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun #if (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
226*4882a593Smuzhiyun 	ddrmc_init();
227*4882a593Smuzhiyun #endif
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun #if defined(CONFIG_DEEP_SLEEP) && !defined(CONFIG_SPL_BUILD)
232*4882a593Smuzhiyun 	fsl_dp_resume();
233*4882a593Smuzhiyun #endif
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	return 0;
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun #ifdef CONFIG_FSL_ESDHC
239*4882a593Smuzhiyun struct fsl_esdhc_cfg esdhc_cfg[1] = {
240*4882a593Smuzhiyun 	{CONFIG_SYS_FSL_ESDHC_ADDR},
241*4882a593Smuzhiyun };
242*4882a593Smuzhiyun 
board_mmc_init(bd_t * bis)243*4882a593Smuzhiyun int board_mmc_init(bd_t *bis)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun 	esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	return fsl_esdhc_initialize(bis, &esdhc_cfg[0]);
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun #endif
250*4882a593Smuzhiyun 
board_eth_init(bd_t * bis)251*4882a593Smuzhiyun int board_eth_init(bd_t *bis)
252*4882a593Smuzhiyun {
253*4882a593Smuzhiyun #ifdef CONFIG_TSEC_ENET
254*4882a593Smuzhiyun 	struct fsl_pq_mdio_info mdio_info;
255*4882a593Smuzhiyun 	struct tsec_info_struct tsec_info[4];
256*4882a593Smuzhiyun 	int num = 0;
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun #ifdef CONFIG_TSEC1
259*4882a593Smuzhiyun 	SET_STD_TSEC_INFO(tsec_info[num], 1);
260*4882a593Smuzhiyun 	if (is_serdes_configured(SGMII_TSEC1)) {
261*4882a593Smuzhiyun 		puts("eTSEC1 is in sgmii mode.\n");
262*4882a593Smuzhiyun 		tsec_info[num].flags |= TSEC_SGMII;
263*4882a593Smuzhiyun 	}
264*4882a593Smuzhiyun 	num++;
265*4882a593Smuzhiyun #endif
266*4882a593Smuzhiyun #ifdef CONFIG_TSEC2
267*4882a593Smuzhiyun 	SET_STD_TSEC_INFO(tsec_info[num], 2);
268*4882a593Smuzhiyun 	if (is_serdes_configured(SGMII_TSEC2)) {
269*4882a593Smuzhiyun 		puts("eTSEC2 is in sgmii mode.\n");
270*4882a593Smuzhiyun 		tsec_info[num].flags |= TSEC_SGMII;
271*4882a593Smuzhiyun 	}
272*4882a593Smuzhiyun 	num++;
273*4882a593Smuzhiyun #endif
274*4882a593Smuzhiyun #ifdef CONFIG_TSEC3
275*4882a593Smuzhiyun 	SET_STD_TSEC_INFO(tsec_info[num], 3);
276*4882a593Smuzhiyun 	tsec_info[num].interface = PHY_INTERFACE_MODE_RGMII_ID;
277*4882a593Smuzhiyun 	num++;
278*4882a593Smuzhiyun #endif
279*4882a593Smuzhiyun 	if (!num) {
280*4882a593Smuzhiyun 		printf("No TSECs initialized\n");
281*4882a593Smuzhiyun 		return 0;
282*4882a593Smuzhiyun 	}
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR;
285*4882a593Smuzhiyun 	mdio_info.name = DEFAULT_MII_NAME;
286*4882a593Smuzhiyun 	fsl_pq_mdio_init(bis, &mdio_info);
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	tsec_eth_init(bis, tsec_info, num);
289*4882a593Smuzhiyun #endif
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun 	return pci_eth_init(bis);
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun #if !defined(CONFIG_QSPI_BOOT) && !defined(CONFIG_SD_BOOT_QSPI)
config_serdes_mux(void)295*4882a593Smuzhiyun int config_serdes_mux(void)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
298*4882a593Smuzhiyun 	u32 protocol = in_be32(&gur->rcwsr[4]) & RCWSR4_SRDS1_PRTCL_MASK;
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	protocol >>= RCWSR4_SRDS1_PRTCL_SHIFT;
301*4882a593Smuzhiyun 	switch (protocol) {
302*4882a593Smuzhiyun 	case 0x10:
303*4882a593Smuzhiyun 		convert_serdes_mux(LANEB_SATA, KEEP_STATUS);
304*4882a593Smuzhiyun 		convert_serdes_mux(LANED_PCIEX2 |
305*4882a593Smuzhiyun 				LANEC_PCIEX1, KEEP_STATUS);
306*4882a593Smuzhiyun 		break;
307*4882a593Smuzhiyun 	case 0x20:
308*4882a593Smuzhiyun 		convert_serdes_mux(LANEB_SGMII1, KEEP_STATUS);
309*4882a593Smuzhiyun 		convert_serdes_mux(LANEC_PCIEX1, KEEP_STATUS);
310*4882a593Smuzhiyun 		convert_serdes_mux(LANED_SGMII2, KEEP_STATUS);
311*4882a593Smuzhiyun 		break;
312*4882a593Smuzhiyun 	case 0x30:
313*4882a593Smuzhiyun 		convert_serdes_mux(LANEB_SATA, KEEP_STATUS);
314*4882a593Smuzhiyun 		convert_serdes_mux(LANEC_SGMII1, KEEP_STATUS);
315*4882a593Smuzhiyun 		convert_serdes_mux(LANED_SGMII2, KEEP_STATUS);
316*4882a593Smuzhiyun 		break;
317*4882a593Smuzhiyun 	case 0x70:
318*4882a593Smuzhiyun 		convert_serdes_mux(LANEB_SATA, KEEP_STATUS);
319*4882a593Smuzhiyun 		convert_serdes_mux(LANEC_PCIEX1, KEEP_STATUS);
320*4882a593Smuzhiyun 		convert_serdes_mux(LANED_SGMII2, KEEP_STATUS);
321*4882a593Smuzhiyun 		break;
322*4882a593Smuzhiyun 	}
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	return 0;
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyun #endif
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun #if !defined(CONFIG_QSPI_BOOT) && !defined(CONFIG_SD_BOOT_QSPI)
config_board_mux(void)329*4882a593Smuzhiyun int config_board_mux(void)
330*4882a593Smuzhiyun {
331*4882a593Smuzhiyun 	struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
332*4882a593Smuzhiyun 	int conflict_flag;
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 	conflict_flag = 0;
335*4882a593Smuzhiyun 	if (hwconfig("i2c3")) {
336*4882a593Smuzhiyun 		conflict_flag++;
337*4882a593Smuzhiyun 		cpld_data->soft_mux_on |= SOFT_MUX_ON_I2C3_IFC;
338*4882a593Smuzhiyun 		cpld_data->i2c3_ifc_mux = PIN_I2C3_IFC_MUX_I2C3;
339*4882a593Smuzhiyun 	}
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	if (hwconfig("ifc")) {
342*4882a593Smuzhiyun 		conflict_flag++;
343*4882a593Smuzhiyun 		/* some signals can not enable simultaneous*/
344*4882a593Smuzhiyun 		if (conflict_flag > 1)
345*4882a593Smuzhiyun 			goto conflict;
346*4882a593Smuzhiyun 		cpld_data->soft_mux_on |= SOFT_MUX_ON_I2C3_IFC;
347*4882a593Smuzhiyun 		cpld_data->i2c3_ifc_mux = PIN_I2C3_IFC_MUX_IFC;
348*4882a593Smuzhiyun 	}
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	conflict_flag = 0;
351*4882a593Smuzhiyun 	if (hwconfig("usb2")) {
352*4882a593Smuzhiyun 		conflict_flag++;
353*4882a593Smuzhiyun 		cpld_data->soft_mux_on |= SOFT_MUX_ON_CAN3_USB2;
354*4882a593Smuzhiyun 		cpld_data->can3_usb2_mux = PIN_CAN3_USB2_MUX_USB2;
355*4882a593Smuzhiyun 	}
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 	if (hwconfig("can3")) {
358*4882a593Smuzhiyun 		conflict_flag++;
359*4882a593Smuzhiyun 		/* some signals can not enable simultaneous*/
360*4882a593Smuzhiyun 		if (conflict_flag > 1)
361*4882a593Smuzhiyun 			goto conflict;
362*4882a593Smuzhiyun 		cpld_data->soft_mux_on |= SOFT_MUX_ON_CAN3_USB2;
363*4882a593Smuzhiyun 		cpld_data->can3_usb2_mux = PIN_CAN3_USB2_MUX_CAN3;
364*4882a593Smuzhiyun 	}
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun 	conflict_flag = 0;
367*4882a593Smuzhiyun 	if (hwconfig("lcd")) {
368*4882a593Smuzhiyun 		conflict_flag++;
369*4882a593Smuzhiyun 		cpld_data->soft_mux_on |= SOFT_MUX_ON_QE_LCD;
370*4882a593Smuzhiyun 		cpld_data->qe_lcd_mux = PIN_QE_LCD_MUX_LCD;
371*4882a593Smuzhiyun 	}
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	if (hwconfig("qe")) {
374*4882a593Smuzhiyun 		conflict_flag++;
375*4882a593Smuzhiyun 		/* some signals can not enable simultaneous*/
376*4882a593Smuzhiyun 		if (conflict_flag > 1)
377*4882a593Smuzhiyun 			goto conflict;
378*4882a593Smuzhiyun 		cpld_data->soft_mux_on |= SOFT_MUX_ON_QE_LCD;
379*4882a593Smuzhiyun 		cpld_data->qe_lcd_mux = PIN_QE_LCD_MUX_QE;
380*4882a593Smuzhiyun 	}
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 	return 0;
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun conflict:
385*4882a593Smuzhiyun 	printf("WARNING: pin conflict! MUX setting may failed!\n");
386*4882a593Smuzhiyun 	return 0;
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun #endif
389*4882a593Smuzhiyun 
board_early_init_f(void)390*4882a593Smuzhiyun int board_early_init_f(void)
391*4882a593Smuzhiyun {
392*4882a593Smuzhiyun 	struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun #ifdef CONFIG_TSEC_ENET
395*4882a593Smuzhiyun 	/* clear BD & FR bits for BE BD's and frame data */
396*4882a593Smuzhiyun 	clrbits_be32(&scfg->etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR);
397*4882a593Smuzhiyun 	out_be32(&scfg->etsecmcr, SCFG_ETSECCMCR_GE2_CLK125);
398*4882a593Smuzhiyun #endif
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun #ifdef CONFIG_FSL_IFC
401*4882a593Smuzhiyun 	init_early_memctl_regs();
402*4882a593Smuzhiyun #endif
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	arch_soc_init();
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun #if defined(CONFIG_DEEP_SLEEP)
407*4882a593Smuzhiyun 	if (is_warm_boot()) {
408*4882a593Smuzhiyun 		timer_init();
409*4882a593Smuzhiyun 		dram_init();
410*4882a593Smuzhiyun 	}
411*4882a593Smuzhiyun #endif
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	return 0;
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun #ifdef CONFIG_SPL_BUILD
board_init_f(ulong dummy)417*4882a593Smuzhiyun void board_init_f(ulong dummy)
418*4882a593Smuzhiyun {
419*4882a593Smuzhiyun 	void (*second_uboot)(void);
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	/* Clear the BSS */
422*4882a593Smuzhiyun 	memset(__bss_start, 0, __bss_end - __bss_start);
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	get_clocks();
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun #if defined(CONFIG_DEEP_SLEEP)
427*4882a593Smuzhiyun 	if (is_warm_boot())
428*4882a593Smuzhiyun 		fsl_dp_disable_console();
429*4882a593Smuzhiyun #endif
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun 	preloader_console_init();
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 	dram_init();
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	/* Allow OCRAM access permission as R/W */
436*4882a593Smuzhiyun #ifdef CONFIG_LAYERSCAPE_NS_ACCESS
437*4882a593Smuzhiyun 	enable_layerscape_ns_access();
438*4882a593Smuzhiyun #endif
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 	/*
441*4882a593Smuzhiyun 	 * if it is woken up from deep sleep, then jump to second
442*4882a593Smuzhiyun 	 * stage uboot and continue executing without recopying
443*4882a593Smuzhiyun 	 * it from SD since it has already been reserved in memeory
444*4882a593Smuzhiyun 	 * in last boot.
445*4882a593Smuzhiyun 	 */
446*4882a593Smuzhiyun 	if (is_warm_boot()) {
447*4882a593Smuzhiyun 		second_uboot = (void (*)(void))CONFIG_SYS_TEXT_BASE;
448*4882a593Smuzhiyun 		second_uboot();
449*4882a593Smuzhiyun 	}
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	board_init_r(NULL, 0);
452*4882a593Smuzhiyun }
453*4882a593Smuzhiyun #endif
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun #ifdef CONFIG_DEEP_SLEEP
456*4882a593Smuzhiyun /* program the regulator (MC34VR500) to support deep sleep */
ls1twr_program_regulator(void)457*4882a593Smuzhiyun void ls1twr_program_regulator(void)
458*4882a593Smuzhiyun {
459*4882a593Smuzhiyun 	unsigned int i2c_bus;
460*4882a593Smuzhiyun 	u8 i2c_device_id;
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun #define LS1TWR_I2C_BUS_MC34VR500	1
463*4882a593Smuzhiyun #define MC34VR500_ADDR			0x8
464*4882a593Smuzhiyun #define MC34VR500_DEVICEID		0x4
465*4882a593Smuzhiyun #define MC34VR500_DEVICEID_MASK		0x0f
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun 	i2c_bus = i2c_get_bus_num();
468*4882a593Smuzhiyun 	i2c_set_bus_num(LS1TWR_I2C_BUS_MC34VR500);
469*4882a593Smuzhiyun 	i2c_device_id = i2c_reg_read(MC34VR500_ADDR, 0x0) &
470*4882a593Smuzhiyun 					MC34VR500_DEVICEID_MASK;
471*4882a593Smuzhiyun 	if (i2c_device_id != MC34VR500_DEVICEID) {
472*4882a593Smuzhiyun 		printf("The regulator (MC34VR500) does not exist. The device does not support deep sleep.\n");
473*4882a593Smuzhiyun 		return;
474*4882a593Smuzhiyun 	}
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun 	i2c_reg_write(MC34VR500_ADDR, 0x31, 0x4);
477*4882a593Smuzhiyun 	i2c_reg_write(MC34VR500_ADDR, 0x4d, 0x4);
478*4882a593Smuzhiyun 	i2c_reg_write(MC34VR500_ADDR, 0x6d, 0x38);
479*4882a593Smuzhiyun 	i2c_reg_write(MC34VR500_ADDR, 0x6f, 0x37);
480*4882a593Smuzhiyun 	i2c_reg_write(MC34VR500_ADDR, 0x71, 0x30);
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 	i2c_set_bus_num(i2c_bus);
483*4882a593Smuzhiyun }
484*4882a593Smuzhiyun #endif
485*4882a593Smuzhiyun 
board_init(void)486*4882a593Smuzhiyun int board_init(void)
487*4882a593Smuzhiyun {
488*4882a593Smuzhiyun #ifdef CONFIG_SYS_FSL_ERRATUM_A010315
489*4882a593Smuzhiyun 	erratum_a010315();
490*4882a593Smuzhiyun #endif
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun #ifndef CONFIG_SYS_FSL_NO_SERDES
493*4882a593Smuzhiyun 	fsl_serdes_init();
494*4882a593Smuzhiyun #if !defined(CONFIG_QSPI_BOOT) && !defined(CONFIG_SD_BOOT_QSPI)
495*4882a593Smuzhiyun 	config_serdes_mux();
496*4882a593Smuzhiyun #endif
497*4882a593Smuzhiyun #endif
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun 	ls102xa_smmu_stream_id_init();
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun #ifdef CONFIG_U_QE
502*4882a593Smuzhiyun 	u_qe_init();
503*4882a593Smuzhiyun #endif
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun #ifdef CONFIG_DEEP_SLEEP
506*4882a593Smuzhiyun 	ls1twr_program_regulator();
507*4882a593Smuzhiyun #endif
508*4882a593Smuzhiyun 	return 0;
509*4882a593Smuzhiyun }
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun #if defined(CONFIG_SPL_BUILD)
spl_board_init(void)512*4882a593Smuzhiyun void spl_board_init(void)
513*4882a593Smuzhiyun {
514*4882a593Smuzhiyun 	ls102xa_smmu_stream_id_init();
515*4882a593Smuzhiyun }
516*4882a593Smuzhiyun #endif
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun #ifdef CONFIG_BOARD_LATE_INIT
board_late_init(void)519*4882a593Smuzhiyun int board_late_init(void)
520*4882a593Smuzhiyun {
521*4882a593Smuzhiyun #ifdef CONFIG_SCSI_AHCI_PLAT
522*4882a593Smuzhiyun 	ls1021a_sata_init();
523*4882a593Smuzhiyun #endif
524*4882a593Smuzhiyun #ifdef CONFIG_CHAIN_OF_TRUST
525*4882a593Smuzhiyun 	fsl_setenv_chain_of_trust();
526*4882a593Smuzhiyun #endif
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun 	return 0;
529*4882a593Smuzhiyun }
530*4882a593Smuzhiyun #endif
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun #if defined(CONFIG_MISC_INIT_R)
misc_init_r(void)533*4882a593Smuzhiyun int misc_init_r(void)
534*4882a593Smuzhiyun {
535*4882a593Smuzhiyun #ifdef CONFIG_FSL_DEVICE_DISABLE
536*4882a593Smuzhiyun 	device_disable(devdis_tbl, ARRAY_SIZE(devdis_tbl));
537*4882a593Smuzhiyun #endif
538*4882a593Smuzhiyun #if !defined(CONFIG_QSPI_BOOT) && !defined(CONFIG_SD_BOOT_QSPI)
539*4882a593Smuzhiyun 	config_board_mux();
540*4882a593Smuzhiyun #endif
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun #ifdef CONFIG_FSL_CAAM
543*4882a593Smuzhiyun 	return sec_init();
544*4882a593Smuzhiyun #endif
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun #endif
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun #if defined(CONFIG_DEEP_SLEEP)
board_sleep_prepare(void)549*4882a593Smuzhiyun void board_sleep_prepare(void)
550*4882a593Smuzhiyun {
551*4882a593Smuzhiyun #ifdef CONFIG_LAYERSCAPE_NS_ACCESS
552*4882a593Smuzhiyun 	enable_layerscape_ns_access();
553*4882a593Smuzhiyun #endif
554*4882a593Smuzhiyun }
555*4882a593Smuzhiyun #endif
556*4882a593Smuzhiyun 
ft_board_setup(void * blob,bd_t * bd)557*4882a593Smuzhiyun int ft_board_setup(void *blob, bd_t *bd)
558*4882a593Smuzhiyun {
559*4882a593Smuzhiyun 	ft_cpu_setup(blob, bd);
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun #ifdef CONFIG_PCI
562*4882a593Smuzhiyun 	ft_pci_setup(blob, bd);
563*4882a593Smuzhiyun #endif
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun 	return 0;
566*4882a593Smuzhiyun }
567*4882a593Smuzhiyun 
flash_read8(void * addr)568*4882a593Smuzhiyun u8 flash_read8(void *addr)
569*4882a593Smuzhiyun {
570*4882a593Smuzhiyun 	return __raw_readb(addr + 1);
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun 
flash_write16(u16 val,void * addr)573*4882a593Smuzhiyun void flash_write16(u16 val, void *addr)
574*4882a593Smuzhiyun {
575*4882a593Smuzhiyun 	u16 shftval = (((val >> 8) & 0xff) | ((val << 8) & 0xff00));
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 	__raw_writew(shftval, addr);
578*4882a593Smuzhiyun }
579*4882a593Smuzhiyun 
flash_read16(void * addr)580*4882a593Smuzhiyun u16 flash_read16(void *addr)
581*4882a593Smuzhiyun {
582*4882a593Smuzhiyun 	u16 val = __raw_readw(addr);
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun 	return (((val) >> 8) & 0x00ff) | (((val) << 8) & 0xff00);
585*4882a593Smuzhiyun }
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun #if !defined(CONFIG_QSPI_BOOT) && !defined(CONFIG_SD_BOOT_QSPI)
convert_flash_bank(char bank)588*4882a593Smuzhiyun static void convert_flash_bank(char bank)
589*4882a593Smuzhiyun {
590*4882a593Smuzhiyun 	struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun 	printf("Now switch to boot from flash bank %d.\n", bank);
593*4882a593Smuzhiyun 	cpld_data->soft_mux_on = CPLD_SET_BOOT_BANK;
594*4882a593Smuzhiyun 	cpld_data->vbank = bank;
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun 	printf("Reset board to enable configuration.\n");
597*4882a593Smuzhiyun 	cpld_data->system_rst = CONFIG_RESET;
598*4882a593Smuzhiyun }
599*4882a593Smuzhiyun 
flash_bank_cmd(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])600*4882a593Smuzhiyun static int flash_bank_cmd(cmd_tbl_t *cmdtp, int flag, int argc,
601*4882a593Smuzhiyun 			  char * const argv[])
602*4882a593Smuzhiyun {
603*4882a593Smuzhiyun 	if (argc != 2)
604*4882a593Smuzhiyun 		return CMD_RET_USAGE;
605*4882a593Smuzhiyun 	if (strcmp(argv[1], "0") == 0)
606*4882a593Smuzhiyun 		convert_flash_bank(BOOT_FROM_UPPER_BANK);
607*4882a593Smuzhiyun 	else if (strcmp(argv[1], "1") == 0)
608*4882a593Smuzhiyun 		convert_flash_bank(BOOT_FROM_LOWER_BANK);
609*4882a593Smuzhiyun 	else
610*4882a593Smuzhiyun 		return CMD_RET_USAGE;
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun 	return 0;
613*4882a593Smuzhiyun }
614*4882a593Smuzhiyun 
615*4882a593Smuzhiyun U_BOOT_CMD(
616*4882a593Smuzhiyun 	boot_bank, 2, 0, flash_bank_cmd,
617*4882a593Smuzhiyun 	"Flash bank Selection Control",
618*4882a593Smuzhiyun 	"bank[0-upper bank/1-lower bank] (e.g. boot_bank 0)"
619*4882a593Smuzhiyun );
620*4882a593Smuzhiyun 
cpld_reset_cmd(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])621*4882a593Smuzhiyun static int cpld_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc,
622*4882a593Smuzhiyun 			  char * const argv[])
623*4882a593Smuzhiyun {
624*4882a593Smuzhiyun 	struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun 	if (argc > 2)
627*4882a593Smuzhiyun 		return CMD_RET_USAGE;
628*4882a593Smuzhiyun 	if ((argc == 1) || (strcmp(argv[1], "conf") == 0))
629*4882a593Smuzhiyun 		cpld_data->system_rst = CONFIG_RESET;
630*4882a593Smuzhiyun 	else if (strcmp(argv[1], "init") == 0)
631*4882a593Smuzhiyun 		cpld_data->global_rst = INIT_RESET;
632*4882a593Smuzhiyun 	else
633*4882a593Smuzhiyun 		return CMD_RET_USAGE;
634*4882a593Smuzhiyun 
635*4882a593Smuzhiyun 	return 0;
636*4882a593Smuzhiyun }
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun U_BOOT_CMD(
639*4882a593Smuzhiyun 	cpld_reset, 2, 0, cpld_reset_cmd,
640*4882a593Smuzhiyun 	"Reset via CPLD",
641*4882a593Smuzhiyun 	"conf\n"
642*4882a593Smuzhiyun 	"	-reset with current CPLD configuration\n"
643*4882a593Smuzhiyun 	"init\n"
644*4882a593Smuzhiyun 	"	-reset and initial CPLD configuration with default value"
645*4882a593Smuzhiyun 
646*4882a593Smuzhiyun );
647*4882a593Smuzhiyun 
convert_serdes_mux(int type,int need_reset)648*4882a593Smuzhiyun static void convert_serdes_mux(int type, int need_reset)
649*4882a593Smuzhiyun {
650*4882a593Smuzhiyun 	char current_serdes;
651*4882a593Smuzhiyun 	struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun 	current_serdes = cpld_data->serdes_mux;
654*4882a593Smuzhiyun 
655*4882a593Smuzhiyun 	switch (type) {
656*4882a593Smuzhiyun 	case LANEB_SATA:
657*4882a593Smuzhiyun 		current_serdes &= ~MASK_LANE_B;
658*4882a593Smuzhiyun 		break;
659*4882a593Smuzhiyun 	case LANEB_SGMII1:
660*4882a593Smuzhiyun 		current_serdes |= (MASK_LANE_B | MASK_SGMII | MASK_LANE_C);
661*4882a593Smuzhiyun 		break;
662*4882a593Smuzhiyun 	case LANEC_SGMII1:
663*4882a593Smuzhiyun 		current_serdes &= ~(MASK_LANE_B | MASK_SGMII | MASK_LANE_C);
664*4882a593Smuzhiyun 		break;
665*4882a593Smuzhiyun 	case LANED_SGMII2:
666*4882a593Smuzhiyun 		current_serdes |= MASK_LANE_D;
667*4882a593Smuzhiyun 		break;
668*4882a593Smuzhiyun 	case LANEC_PCIEX1:
669*4882a593Smuzhiyun 		current_serdes |= MASK_LANE_C;
670*4882a593Smuzhiyun 		break;
671*4882a593Smuzhiyun 	case (LANED_PCIEX2 | LANEC_PCIEX1):
672*4882a593Smuzhiyun 		current_serdes |= MASK_LANE_C;
673*4882a593Smuzhiyun 		current_serdes &= ~MASK_LANE_D;
674*4882a593Smuzhiyun 		break;
675*4882a593Smuzhiyun 	default:
676*4882a593Smuzhiyun 		printf("CPLD serdes MUX: unsupported MUX type 0x%x\n", type);
677*4882a593Smuzhiyun 		return;
678*4882a593Smuzhiyun 	}
679*4882a593Smuzhiyun 
680*4882a593Smuzhiyun 	cpld_data->soft_mux_on |= CPLD_SET_MUX_SERDES;
681*4882a593Smuzhiyun 	cpld_data->serdes_mux = current_serdes;
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun 	if (need_reset == 1) {
684*4882a593Smuzhiyun 		printf("Reset board to enable configuration\n");
685*4882a593Smuzhiyun 		cpld_data->system_rst = CONFIG_RESET;
686*4882a593Smuzhiyun 	}
687*4882a593Smuzhiyun }
688*4882a593Smuzhiyun 
print_serdes_mux(void)689*4882a593Smuzhiyun void print_serdes_mux(void)
690*4882a593Smuzhiyun {
691*4882a593Smuzhiyun 	char current_serdes;
692*4882a593Smuzhiyun 	struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
693*4882a593Smuzhiyun 
694*4882a593Smuzhiyun 	current_serdes = cpld_data->serdes_mux;
695*4882a593Smuzhiyun 
696*4882a593Smuzhiyun 	printf("Serdes Lane B: ");
697*4882a593Smuzhiyun 	if ((current_serdes & MASK_LANE_B) == 0)
698*4882a593Smuzhiyun 		printf("SATA,\n");
699*4882a593Smuzhiyun 	else
700*4882a593Smuzhiyun 		printf("SGMII 1,\n");
701*4882a593Smuzhiyun 
702*4882a593Smuzhiyun 	printf("Serdes Lane C: ");
703*4882a593Smuzhiyun 	if ((current_serdes & MASK_LANE_C) == 0)
704*4882a593Smuzhiyun 		printf("SGMII 1,\n");
705*4882a593Smuzhiyun 	else
706*4882a593Smuzhiyun 		printf("PCIe,\n");
707*4882a593Smuzhiyun 
708*4882a593Smuzhiyun 	printf("Serdes Lane D: ");
709*4882a593Smuzhiyun 	if ((current_serdes & MASK_LANE_D) == 0)
710*4882a593Smuzhiyun 		printf("PCIe,\n");
711*4882a593Smuzhiyun 	else
712*4882a593Smuzhiyun 		printf("SGMII 2,\n");
713*4882a593Smuzhiyun 
714*4882a593Smuzhiyun 	printf("SGMII 1 is on lane ");
715*4882a593Smuzhiyun 	if ((current_serdes & MASK_SGMII) == 0)
716*4882a593Smuzhiyun 		printf("C.\n");
717*4882a593Smuzhiyun 	else
718*4882a593Smuzhiyun 		printf("B.\n");
719*4882a593Smuzhiyun }
720*4882a593Smuzhiyun 
serdes_mux_cmd(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])721*4882a593Smuzhiyun static int serdes_mux_cmd(cmd_tbl_t *cmdtp, int flag, int argc,
722*4882a593Smuzhiyun 			  char * const argv[])
723*4882a593Smuzhiyun {
724*4882a593Smuzhiyun 	if (argc != 2)
725*4882a593Smuzhiyun 		return CMD_RET_USAGE;
726*4882a593Smuzhiyun 	if (strcmp(argv[1], "sata") == 0) {
727*4882a593Smuzhiyun 		printf("Set serdes lane B to SATA.\n");
728*4882a593Smuzhiyun 		convert_serdes_mux(LANEB_SATA, NEED_RESET);
729*4882a593Smuzhiyun 	} else if (strcmp(argv[1], "sgmii1b") == 0) {
730*4882a593Smuzhiyun 		printf("Set serdes lane B to SGMII 1.\n");
731*4882a593Smuzhiyun 		convert_serdes_mux(LANEB_SGMII1, NEED_RESET);
732*4882a593Smuzhiyun 	} else if (strcmp(argv[1], "sgmii1c") == 0) {
733*4882a593Smuzhiyun 		printf("Set serdes lane C to SGMII 1.\n");
734*4882a593Smuzhiyun 		convert_serdes_mux(LANEC_SGMII1, NEED_RESET);
735*4882a593Smuzhiyun 	} else if (strcmp(argv[1], "sgmii2") == 0) {
736*4882a593Smuzhiyun 		printf("Set serdes lane D to SGMII 2.\n");
737*4882a593Smuzhiyun 		convert_serdes_mux(LANED_SGMII2, NEED_RESET);
738*4882a593Smuzhiyun 	} else if (strcmp(argv[1], "pciex1") == 0) {
739*4882a593Smuzhiyun 		printf("Set serdes lane C to PCIe X1.\n");
740*4882a593Smuzhiyun 		convert_serdes_mux(LANEC_PCIEX1, NEED_RESET);
741*4882a593Smuzhiyun 	} else if (strcmp(argv[1], "pciex2") == 0) {
742*4882a593Smuzhiyun 		printf("Set serdes lane C & lane D to PCIe X2.\n");
743*4882a593Smuzhiyun 		convert_serdes_mux((LANED_PCIEX2 | LANEC_PCIEX1), NEED_RESET);
744*4882a593Smuzhiyun 	} else if (strcmp(argv[1], "show") == 0) {
745*4882a593Smuzhiyun 		print_serdes_mux();
746*4882a593Smuzhiyun 	} else {
747*4882a593Smuzhiyun 		return CMD_RET_USAGE;
748*4882a593Smuzhiyun 	}
749*4882a593Smuzhiyun 
750*4882a593Smuzhiyun 	return 0;
751*4882a593Smuzhiyun }
752*4882a593Smuzhiyun 
753*4882a593Smuzhiyun U_BOOT_CMD(
754*4882a593Smuzhiyun 	lane_bank, 2, 0, serdes_mux_cmd,
755*4882a593Smuzhiyun 	"Multiplexed function setting for SerDes Lanes",
756*4882a593Smuzhiyun 	"sata\n"
757*4882a593Smuzhiyun 	"	-change lane B to sata\n"
758*4882a593Smuzhiyun 	"lane_bank sgmii1b\n"
759*4882a593Smuzhiyun 	"	-change lane B to SGMII1\n"
760*4882a593Smuzhiyun 	"lane_bank sgmii1c\n"
761*4882a593Smuzhiyun 	"	-change lane C to SGMII1\n"
762*4882a593Smuzhiyun 	"lane_bank sgmii2\n"
763*4882a593Smuzhiyun 	"	-change lane D to SGMII2\n"
764*4882a593Smuzhiyun 	"lane_bank pciex1\n"
765*4882a593Smuzhiyun 	"	-change lane C to PCIeX1\n"
766*4882a593Smuzhiyun 	"lane_bank pciex2\n"
767*4882a593Smuzhiyun 	"	-change lane C & lane D to PCIeX2\n"
768*4882a593Smuzhiyun 	"\nWARNING: If you aren't familiar with the setting of serdes, don't try to change anything!\n"
769*4882a593Smuzhiyun );
770*4882a593Smuzhiyun #endif
771