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/clock.h>
12 #include <asm/arch/fsl_serdes.h>
13 #include <mmc.h>
14 #include <fsl_esdhc.h>
15 #include <fsl_ifc.h>
16 #include <fsl_sec.h>
17 
18 #include "../common/qixis.h"
19 #include "ls1021aqds_qixis.h"
20 #ifdef CONFIG_U_QE
21 #include "../../../drivers/qe/qe.h"
22 #endif
23 
24 DECLARE_GLOBAL_DATA_PTR;
25 
26 enum {
27 	MUX_TYPE_SD_PCI4,
28 	MUX_TYPE_SD_PC_SA_SG_SG,
29 	MUX_TYPE_SD_PC_SA_PC_SG,
30 	MUX_TYPE_SD_PC_SG_SG,
31 };
32 
33 int checkboard(void)
34 {
35 	char buf[64];
36 	u8 sw;
37 
38 	puts("Board: LS1021AQDS\n");
39 
40 	sw = QIXIS_READ(brdcfg[0]);
41 	sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
42 
43 	if (sw < 0x8)
44 		printf("vBank: %d\n", sw);
45 	else if (sw == 0x8)
46 		puts("PromJet\n");
47 	else if (sw == 0x9)
48 		puts("NAND\n");
49 	else if (sw == 0x15)
50 		printf("IFCCard\n");
51 	else
52 		printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
53 
54 	printf("Sys ID:0x%02x, Sys Ver: 0x%02x\n",
55 	       QIXIS_READ(id), QIXIS_READ(arch));
56 
57 	printf("FPGA:  v%d (%s), build %d\n",
58 	       (int)QIXIS_READ(scver), qixis_read_tag(buf),
59 	       (int)qixis_read_minor());
60 
61 	return 0;
62 }
63 
64 unsigned long get_board_sys_clk(void)
65 {
66 	u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
67 
68 	switch (sysclk_conf & 0x0f) {
69 	case QIXIS_SYSCLK_64:
70 		return 64000000;
71 	case QIXIS_SYSCLK_83:
72 		return 83333333;
73 	case QIXIS_SYSCLK_100:
74 		return 100000000;
75 	case QIXIS_SYSCLK_125:
76 		return 125000000;
77 	case QIXIS_SYSCLK_133:
78 		return 133333333;
79 	case QIXIS_SYSCLK_150:
80 		return 150000000;
81 	case QIXIS_SYSCLK_160:
82 		return 160000000;
83 	case QIXIS_SYSCLK_166:
84 		return 166666666;
85 	}
86 	return 66666666;
87 }
88 
89 unsigned long get_board_ddr_clk(void)
90 {
91 	u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
92 
93 	switch ((ddrclk_conf & 0x30) >> 4) {
94 	case QIXIS_DDRCLK_100:
95 		return 100000000;
96 	case QIXIS_DDRCLK_125:
97 		return 125000000;
98 	case QIXIS_DDRCLK_133:
99 		return 133333333;
100 	}
101 	return 66666666;
102 }
103 
104 int dram_init(void)
105 {
106 	gd->ram_size = initdram(0);
107 
108 	return 0;
109 }
110 
111 #ifdef CONFIG_FSL_ESDHC
112 struct fsl_esdhc_cfg esdhc_cfg[1] = {
113 	{CONFIG_SYS_FSL_ESDHC_ADDR},
114 };
115 
116 int board_mmc_init(bd_t *bis)
117 {
118 	esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
119 
120 	return fsl_esdhc_initialize(bis, &esdhc_cfg[0]);
121 }
122 #endif
123 
124 int select_i2c_ch_pca9547(u8 ch)
125 {
126 	int ret;
127 
128 	ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1);
129 	if (ret) {
130 		puts("PCA: failed to select proper channel\n");
131 		return ret;
132 	}
133 
134 	return 0;
135 }
136 
137 int board_early_init_f(void)
138 {
139 	struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
140 	struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR;
141 
142 #ifdef CONFIG_TSEC_ENET
143 	out_be32(&scfg->scfgrevcr, SCFG_SCFGREVCR_REV);
144 	out_be32(&scfg->etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR);
145 	out_be32(&scfg->scfgrevcr, SCFG_SCFGREVCR_NOREV);
146 #endif
147 
148 #ifdef CONFIG_FSL_IFC
149 	init_early_memctl_regs();
150 #endif
151 
152 	/* Workaround for the issue that DDR could not respond to
153 	 * barrier transaction which is generated by executing DSB/ISB
154 	 * instruction. Set CCI-400 control override register to
155 	 * terminate the barrier transaction. After DDR is initialized,
156 	 * allow barrier transaction to DDR again */
157 	out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER);
158 
159 	return 0;
160 }
161 
162 int config_board_mux(int ctrl_type)
163 {
164 	u8 reg12;
165 
166 	reg12 = QIXIS_READ(brdcfg[12]);
167 
168 	switch (ctrl_type) {
169 	case MUX_TYPE_SD_PCI4:
170 		reg12 = 0x38;
171 		break;
172 	case MUX_TYPE_SD_PC_SA_SG_SG:
173 		reg12 = 0x01;
174 		break;
175 	case MUX_TYPE_SD_PC_SA_PC_SG:
176 		reg12 = 0x01;
177 		break;
178 	case MUX_TYPE_SD_PC_SG_SG:
179 		reg12 = 0x21;
180 		break;
181 	default:
182 		printf("Wrong mux interface type\n");
183 		return -1;
184 	}
185 
186 	QIXIS_WRITE(brdcfg[12], reg12);
187 
188 	return 0;
189 }
190 
191 int config_serdes_mux(void)
192 {
193 	struct ccsr_gur *gur = (struct ccsr_gur *)CONFIG_SYS_FSL_GUTS_ADDR;
194 	u32 cfg;
195 
196 	cfg = in_be32(&gur->rcwsr[4]) & RCWSR4_SRDS1_PRTCL_MASK;
197 	cfg >>= RCWSR4_SRDS1_PRTCL_SHIFT;
198 
199 	switch (cfg) {
200 	case 0x0:
201 		config_board_mux(MUX_TYPE_SD_PCI4);
202 		break;
203 	case 0x30:
204 		config_board_mux(MUX_TYPE_SD_PC_SA_SG_SG);
205 		break;
206 	case 0x60:
207 		config_board_mux(MUX_TYPE_SD_PC_SG_SG);
208 		break;
209 	case 0x70:
210 		config_board_mux(MUX_TYPE_SD_PC_SA_PC_SG);
211 		break;
212 	default:
213 		printf("SRDS1 prtcl:0x%x\n", cfg);
214 		break;
215 	}
216 
217 	return 0;
218 }
219 
220 #if defined(CONFIG_MISC_INIT_R)
221 int misc_init_r(void)
222 {
223 #ifdef CONFIG_FSL_CAAM
224 	return sec_init();
225 #endif
226 }
227 #endif
228 
229 int board_init(void)
230 {
231 	struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR;
232 
233 	/* Set CCI-400 control override register to
234 	 * enable barrier transaction */
235 	out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER);
236 
237 	select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
238 
239 #ifndef CONFIG_SYS_FSL_NO_SERDES
240 	fsl_serdes_init();
241 	config_serdes_mux();
242 #endif
243 
244 #ifdef CONFIG_U_QE
245 	u_qe_init();
246 #endif
247 
248 	return 0;
249 }
250 
251 void ft_board_setup(void *blob, bd_t *bd)
252 {
253 	ft_cpu_setup(blob, bd);
254 }
255 
256 u8 flash_read8(void *addr)
257 {
258 	return __raw_readb(addr + 1);
259 }
260 
261 void flash_write16(u16 val, void *addr)
262 {
263 	u16 shftval = (((val >> 8) & 0xff) | ((val << 8) & 0xff00));
264 
265 	__raw_writew(shftval, addr);
266 }
267 
268 u16 flash_read16(void *addr)
269 {
270 	u16 val = __raw_readw(addr);
271 
272 	return (((val) >> 8) & 0x00ff) | (((val) << 8) & 0xff00);
273 }
274