xref: /openbmc/u-boot/board/compulab/cm_fx6/spl.c (revision edf0093732225c2fd0791c3864e9a3eef1f92f19)
1e32028a7SNikita Kiryanov /*
2e32028a7SNikita Kiryanov  * SPL specific code for Compulab CM-FX6 board
3e32028a7SNikita Kiryanov  *
4e32028a7SNikita Kiryanov  * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
5e32028a7SNikita Kiryanov  *
6e32028a7SNikita Kiryanov  * Author: Nikita Kiryanov <nikita@compulab.co.il>
7e32028a7SNikita Kiryanov  *
8e32028a7SNikita Kiryanov  * SPDX-License-Identifier:	GPL-2.0+
9e32028a7SNikita Kiryanov  */
10e32028a7SNikita Kiryanov 
11e32028a7SNikita Kiryanov #include <common.h>
12e32028a7SNikita Kiryanov #include <spl.h>
13e32028a7SNikita Kiryanov #include <asm/io.h>
14e32028a7SNikita Kiryanov #include <asm/gpio.h>
15e32028a7SNikita Kiryanov #include <asm/arch/mx6-ddr.h>
16e32028a7SNikita Kiryanov #include <asm/arch/clock.h>
17e32028a7SNikita Kiryanov #include <asm/arch/sys_proto.h>
18a6b0652bSNikita Kiryanov #include <asm/arch/crm_regs.h>
19e32028a7SNikita Kiryanov #include <asm/imx-common/iomux-v3.h>
20e32028a7SNikita Kiryanov #include <fsl_esdhc.h>
21e32028a7SNikita Kiryanov #include "common.h"
22e32028a7SNikita Kiryanov 
23e32028a7SNikita Kiryanov DECLARE_GLOBAL_DATA_PTR;
24e32028a7SNikita Kiryanov 
25e32028a7SNikita Kiryanov enum ddr_config {
26e32028a7SNikita Kiryanov 	DDR_16BIT_256MB,
27e32028a7SNikita Kiryanov 	DDR_32BIT_512MB,
28e32028a7SNikita Kiryanov 	DDR_32BIT_1GB,
29e32028a7SNikita Kiryanov 	DDR_64BIT_1GB,
30e32028a7SNikita Kiryanov 	DDR_64BIT_2GB,
31e32028a7SNikita Kiryanov 	DDR_64BIT_4GB,
32e32028a7SNikita Kiryanov 	DDR_UNKNOWN,
33e32028a7SNikita Kiryanov };
34e32028a7SNikita Kiryanov 
35e32028a7SNikita Kiryanov /*
36e32028a7SNikita Kiryanov  * Below DRAM_RESET[DDR_SEL] = 0 which is incorrect according to
37e32028a7SNikita Kiryanov  * Freescale QRM, but this is exactly the value used by the automatic
38e32028a7SNikita Kiryanov  * calibration script and it works also in all our tests, so we leave
39e32028a7SNikita Kiryanov  * it as is at this point.
40e32028a7SNikita Kiryanov  */
41e32028a7SNikita Kiryanov #define CM_FX6_DDR_IOMUX_CFG \
42e32028a7SNikita Kiryanov 	.dram_sdqs0	= 0x00000038, \
43e32028a7SNikita Kiryanov 	.dram_sdqs1	= 0x00000038, \
44e32028a7SNikita Kiryanov 	.dram_sdqs2	= 0x00000038, \
45e32028a7SNikita Kiryanov 	.dram_sdqs3	= 0x00000038, \
46e32028a7SNikita Kiryanov 	.dram_sdqs4	= 0x00000038, \
47e32028a7SNikita Kiryanov 	.dram_sdqs5	= 0x00000038, \
48e32028a7SNikita Kiryanov 	.dram_sdqs6	= 0x00000038, \
49e32028a7SNikita Kiryanov 	.dram_sdqs7	= 0x00000038, \
50e32028a7SNikita Kiryanov 	.dram_dqm0	= 0x00000038, \
51e32028a7SNikita Kiryanov 	.dram_dqm1	= 0x00000038, \
52e32028a7SNikita Kiryanov 	.dram_dqm2	= 0x00000038, \
53e32028a7SNikita Kiryanov 	.dram_dqm3	= 0x00000038, \
54e32028a7SNikita Kiryanov 	.dram_dqm4	= 0x00000038, \
55e32028a7SNikita Kiryanov 	.dram_dqm5	= 0x00000038, \
56e32028a7SNikita Kiryanov 	.dram_dqm6	= 0x00000038, \
57e32028a7SNikita Kiryanov 	.dram_dqm7	= 0x00000038, \
58e32028a7SNikita Kiryanov 	.dram_cas	= 0x00000038, \
59e32028a7SNikita Kiryanov 	.dram_ras	= 0x00000038, \
60e32028a7SNikita Kiryanov 	.dram_sdclk_0	= 0x00000038, \
61e32028a7SNikita Kiryanov 	.dram_sdclk_1	= 0x00000038, \
62e32028a7SNikita Kiryanov 	.dram_sdcke0	= 0x00003000, \
63e32028a7SNikita Kiryanov 	.dram_sdcke1	= 0x00003000, \
64e32028a7SNikita Kiryanov 	.dram_reset	= 0x00000038, \
65e32028a7SNikita Kiryanov 	.dram_sdba2	= 0x00000000, \
66e32028a7SNikita Kiryanov 	.dram_sdodt0	= 0x00000038, \
67e32028a7SNikita Kiryanov 	.dram_sdodt1	= 0x00000038,
68e32028a7SNikita Kiryanov 
69e32028a7SNikita Kiryanov #define CM_FX6_GPR_IOMUX_CFG \
70e32028a7SNikita Kiryanov 	.grp_b0ds	= 0x00000038, \
71e32028a7SNikita Kiryanov 	.grp_b1ds	= 0x00000038, \
72e32028a7SNikita Kiryanov 	.grp_b2ds	= 0x00000038, \
73e32028a7SNikita Kiryanov 	.grp_b3ds	= 0x00000038, \
74e32028a7SNikita Kiryanov 	.grp_b4ds	= 0x00000038, \
75e32028a7SNikita Kiryanov 	.grp_b5ds	= 0x00000038, \
76e32028a7SNikita Kiryanov 	.grp_b6ds	= 0x00000038, \
77e32028a7SNikita Kiryanov 	.grp_b7ds	= 0x00000038, \
78e32028a7SNikita Kiryanov 	.grp_addds	= 0x00000038, \
79e32028a7SNikita Kiryanov 	.grp_ddrmode_ctl = 0x00020000, \
80e32028a7SNikita Kiryanov 	.grp_ddrpke	= 0x00000000, \
81e32028a7SNikita Kiryanov 	.grp_ddrmode	= 0x00020000, \
82e32028a7SNikita Kiryanov 	.grp_ctlds	= 0x00000038, \
83e32028a7SNikita Kiryanov 	.grp_ddr_type	= 0x000C0000,
84e32028a7SNikita Kiryanov 
85e32028a7SNikita Kiryanov static struct mx6sdl_iomux_ddr_regs ddr_iomux_s = { CM_FX6_DDR_IOMUX_CFG };
86e32028a7SNikita Kiryanov static struct mx6sdl_iomux_grp_regs grp_iomux_s = { CM_FX6_GPR_IOMUX_CFG };
87e32028a7SNikita Kiryanov static struct mx6dq_iomux_ddr_regs ddr_iomux_q = { CM_FX6_DDR_IOMUX_CFG };
88e32028a7SNikita Kiryanov static struct mx6dq_iomux_grp_regs grp_iomux_q = { CM_FX6_GPR_IOMUX_CFG };
89e32028a7SNikita Kiryanov 
90e32028a7SNikita Kiryanov static struct mx6_mmdc_calibration cm_fx6_calib_s = {
91e32028a7SNikita Kiryanov 	.p0_mpwldectrl0	= 0x005B0061,
92e32028a7SNikita Kiryanov 	.p0_mpwldectrl1	= 0x004F0055,
93e32028a7SNikita Kiryanov 	.p0_mpdgctrl0	= 0x0314030C,
94e32028a7SNikita Kiryanov 	.p0_mpdgctrl1	= 0x025C0268,
95e32028a7SNikita Kiryanov 	.p0_mprddlctl	= 0x42464646,
96e32028a7SNikita Kiryanov 	.p0_mpwrdlctl	= 0x36322C34,
97e32028a7SNikita Kiryanov };
98e32028a7SNikita Kiryanov 
99e32028a7SNikita Kiryanov static struct mx6_ddr_sysinfo cm_fx6_sysinfo_s = {
100e32028a7SNikita Kiryanov 	.cs1_mirror	= 1,
101e32028a7SNikita Kiryanov 	.cs_density	= 16,
102e32028a7SNikita Kiryanov 	.bi_on		= 1,
103e32028a7SNikita Kiryanov 	.rtt_nom	= 1,
104e32028a7SNikita Kiryanov 	.rtt_wr		= 0,
105e32028a7SNikita Kiryanov 	.ralat		= 5,
106e32028a7SNikita Kiryanov 	.walat		= 1,
107e32028a7SNikita Kiryanov 	.mif3_mode	= 3,
108e32028a7SNikita Kiryanov 	.rst_to_cke	= 0x23,
109e32028a7SNikita Kiryanov 	.sde_to_rst	= 0x10,
110*edf00937SFabio Estevam 	.refsel = 1,		/* Refresh cycles at 32KHz */
111*edf00937SFabio Estevam 	.refr = 7,		/* 8 refresh commands per refresh cycle */
112e32028a7SNikita Kiryanov };
113e32028a7SNikita Kiryanov 
114e32028a7SNikita Kiryanov static struct mx6_ddr3_cfg cm_fx6_ddr3_cfg_s = {
115e32028a7SNikita Kiryanov 	.mem_speed	= 800,
116e32028a7SNikita Kiryanov 	.density	= 4,
117e32028a7SNikita Kiryanov 	.rowaddr	= 14,
118e32028a7SNikita Kiryanov 	.coladdr	= 10,
119e32028a7SNikita Kiryanov 	.pagesz		= 2,
120e32028a7SNikita Kiryanov 	.trcd		= 1800,
121e32028a7SNikita Kiryanov 	.trcmin		= 5200,
122e32028a7SNikita Kiryanov 	.trasmin	= 3600,
123e32028a7SNikita Kiryanov 	.SRT		= 0,
124e32028a7SNikita Kiryanov };
125e32028a7SNikita Kiryanov 
126e32028a7SNikita Kiryanov static void spl_mx6s_dram_init(enum ddr_config dram_config, bool reset)
127e32028a7SNikita Kiryanov {
128e32028a7SNikita Kiryanov 	if (reset)
129e32028a7SNikita Kiryanov 		((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2;
130e32028a7SNikita Kiryanov 
131e32028a7SNikita Kiryanov 	switch (dram_config) {
132e32028a7SNikita Kiryanov 	case DDR_16BIT_256MB:
133e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_s.dsize = 0;
134e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_s.ncs = 1;
135e32028a7SNikita Kiryanov 		break;
136e32028a7SNikita Kiryanov 	case DDR_32BIT_512MB:
137e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_s.dsize = 1;
138e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_s.ncs = 1;
139e32028a7SNikita Kiryanov 		break;
140e32028a7SNikita Kiryanov 	case DDR_32BIT_1GB:
141e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_s.dsize = 1;
142e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_s.ncs = 2;
143e32028a7SNikita Kiryanov 		break;
144e32028a7SNikita Kiryanov 	default:
145e32028a7SNikita Kiryanov 		puts("Tried to setup invalid DDR configuration\n");
146e32028a7SNikita Kiryanov 		hang();
147e32028a7SNikita Kiryanov 	}
148e32028a7SNikita Kiryanov 
149e32028a7SNikita Kiryanov 	mx6_dram_cfg(&cm_fx6_sysinfo_s, &cm_fx6_calib_s, &cm_fx6_ddr3_cfg_s);
150e32028a7SNikita Kiryanov 	udelay(100);
151e32028a7SNikita Kiryanov }
152e32028a7SNikita Kiryanov 
153e32028a7SNikita Kiryanov static struct mx6_mmdc_calibration cm_fx6_calib_q = {
154e32028a7SNikita Kiryanov 	.p0_mpwldectrl0	= 0x00630068,
155e32028a7SNikita Kiryanov 	.p0_mpwldectrl1	= 0x0068005D,
156e32028a7SNikita Kiryanov 	.p0_mpdgctrl0	= 0x04140428,
157e32028a7SNikita Kiryanov 	.p0_mpdgctrl1	= 0x037C037C,
158e32028a7SNikita Kiryanov 	.p0_mprddlctl	= 0x3C30303A,
159e32028a7SNikita Kiryanov 	.p0_mpwrdlctl	= 0x3A344038,
160e32028a7SNikita Kiryanov 	.p1_mpwldectrl0	= 0x0035004C,
161e32028a7SNikita Kiryanov 	.p1_mpwldectrl1	= 0x00170026,
162e32028a7SNikita Kiryanov 	.p1_mpdgctrl0	= 0x0374037C,
163e32028a7SNikita Kiryanov 	.p1_mpdgctrl1	= 0x0350032C,
164e32028a7SNikita Kiryanov 	.p1_mprddlctl	= 0x30322A3C,
165e32028a7SNikita Kiryanov 	.p1_mpwrdlctl	= 0x48304A3E,
166e32028a7SNikita Kiryanov };
167e32028a7SNikita Kiryanov 
168e32028a7SNikita Kiryanov static struct mx6_ddr_sysinfo cm_fx6_sysinfo_q = {
169e32028a7SNikita Kiryanov 	.cs_density	= 16,
170e32028a7SNikita Kiryanov 	.cs1_mirror	= 1,
171e32028a7SNikita Kiryanov 	.bi_on		= 1,
172e32028a7SNikita Kiryanov 	.rtt_nom	= 1,
173e32028a7SNikita Kiryanov 	.rtt_wr		= 0,
174e32028a7SNikita Kiryanov 	.ralat		= 5,
175e32028a7SNikita Kiryanov 	.walat		= 1,
176e32028a7SNikita Kiryanov 	.mif3_mode	= 3,
177e32028a7SNikita Kiryanov 	.rst_to_cke	= 0x23,
178e32028a7SNikita Kiryanov 	.sde_to_rst	= 0x10,
179*edf00937SFabio Estevam 	.refsel = 1,		/* Refresh cycles at 32KHz */
180*edf00937SFabio Estevam 	.refr = 7,		/* 8 refresh commands per refresh cycle */
181e32028a7SNikita Kiryanov };
182e32028a7SNikita Kiryanov 
183e32028a7SNikita Kiryanov static struct mx6_ddr3_cfg cm_fx6_ddr3_cfg_q = {
184e32028a7SNikita Kiryanov 	.mem_speed	= 1066,
185e32028a7SNikita Kiryanov 	.density	= 4,
186e32028a7SNikita Kiryanov 	.rowaddr	= 14,
187e32028a7SNikita Kiryanov 	.coladdr	= 10,
188e32028a7SNikita Kiryanov 	.pagesz		= 2,
189e32028a7SNikita Kiryanov 	.trcd		= 1324,
190e32028a7SNikita Kiryanov 	.trcmin		= 59500,
191e32028a7SNikita Kiryanov 	.trasmin	= 9750,
192e32028a7SNikita Kiryanov 	.SRT		= 0,
193e32028a7SNikita Kiryanov };
194e32028a7SNikita Kiryanov 
195e32028a7SNikita Kiryanov static void spl_mx6q_dram_init(enum ddr_config dram_config, bool reset)
196e32028a7SNikita Kiryanov {
197e32028a7SNikita Kiryanov 	if (reset)
198e32028a7SNikita Kiryanov 		((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2;
199e32028a7SNikita Kiryanov 
200e32028a7SNikita Kiryanov 	cm_fx6_ddr3_cfg_q.rowaddr = 14;
201e32028a7SNikita Kiryanov 	switch (dram_config) {
202e32028a7SNikita Kiryanov 	case DDR_16BIT_256MB:
203e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.dsize = 0;
204e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.ncs = 1;
205e32028a7SNikita Kiryanov 		break;
206e32028a7SNikita Kiryanov 	case DDR_32BIT_512MB:
207e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.dsize = 1;
208e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.ncs = 1;
209e32028a7SNikita Kiryanov 		break;
210e32028a7SNikita Kiryanov 	case DDR_64BIT_1GB:
211e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.dsize = 2;
212e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.ncs = 1;
213e32028a7SNikita Kiryanov 		break;
214e32028a7SNikita Kiryanov 	case DDR_64BIT_2GB:
215e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.dsize = 2;
216e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.ncs = 2;
217e32028a7SNikita Kiryanov 		break;
218e32028a7SNikita Kiryanov 	case DDR_64BIT_4GB:
219e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.dsize = 2;
220e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.ncs = 2;
221e32028a7SNikita Kiryanov 		cm_fx6_ddr3_cfg_q.rowaddr = 15;
222e32028a7SNikita Kiryanov 		break;
223e32028a7SNikita Kiryanov 	default:
224e32028a7SNikita Kiryanov 		puts("Tried to setup invalid DDR configuration\n");
225e32028a7SNikita Kiryanov 		hang();
226e32028a7SNikita Kiryanov 	}
227e32028a7SNikita Kiryanov 
228e32028a7SNikita Kiryanov 	mx6_dram_cfg(&cm_fx6_sysinfo_q, &cm_fx6_calib_q, &cm_fx6_ddr3_cfg_q);
229e32028a7SNikita Kiryanov 	udelay(100);
230e32028a7SNikita Kiryanov }
231e32028a7SNikita Kiryanov 
232e32028a7SNikita Kiryanov static int cm_fx6_spl_dram_init(void)
233e32028a7SNikita Kiryanov {
234e32028a7SNikita Kiryanov 	unsigned long bank1_size, bank2_size;
235e32028a7SNikita Kiryanov 
236e32028a7SNikita Kiryanov 	switch (get_cpu_type()) {
237e32028a7SNikita Kiryanov 	case MXC_CPU_MX6SOLO:
238e32028a7SNikita Kiryanov 		mx6sdl_dram_iocfg(64, &ddr_iomux_s, &grp_iomux_s);
239e32028a7SNikita Kiryanov 
240e32028a7SNikita Kiryanov 		spl_mx6s_dram_init(DDR_32BIT_1GB, false);
241e32028a7SNikita Kiryanov 		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
2420b23780fSNikita Kiryanov 		bank2_size = get_ram_size((long int *)PHYS_SDRAM_2, 0x80000000);
2430b23780fSNikita Kiryanov 		if (bank1_size == 0x20000000) {
2440b23780fSNikita Kiryanov 			if (bank2_size == 0x20000000)
245e32028a7SNikita Kiryanov 				return 0;
246e32028a7SNikita Kiryanov 
247e32028a7SNikita Kiryanov 			spl_mx6s_dram_init(DDR_32BIT_512MB, true);
248e32028a7SNikita Kiryanov 			return 0;
249e32028a7SNikita Kiryanov 		}
250e32028a7SNikita Kiryanov 
251e32028a7SNikita Kiryanov 		spl_mx6s_dram_init(DDR_16BIT_256MB, true);
252e32028a7SNikita Kiryanov 		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
253e32028a7SNikita Kiryanov 		if (bank1_size == 0x10000000)
254e32028a7SNikita Kiryanov 			return 0;
255e32028a7SNikita Kiryanov 
256e32028a7SNikita Kiryanov 		break;
257e32028a7SNikita Kiryanov 	case MXC_CPU_MX6D:
258e32028a7SNikita Kiryanov 	case MXC_CPU_MX6Q:
259e32028a7SNikita Kiryanov 		mx6dq_dram_iocfg(64, &ddr_iomux_q, &grp_iomux_q);
260e32028a7SNikita Kiryanov 
261e32028a7SNikita Kiryanov 		spl_mx6q_dram_init(DDR_64BIT_4GB, false);
262e32028a7SNikita Kiryanov 		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
263e32028a7SNikita Kiryanov 		if (bank1_size == 0x80000000)
264e32028a7SNikita Kiryanov 			return 0;
265e32028a7SNikita Kiryanov 
266e32028a7SNikita Kiryanov 		if (bank1_size == 0x40000000) {
267e32028a7SNikita Kiryanov 			bank2_size = get_ram_size((long int *)PHYS_SDRAM_2,
268e32028a7SNikita Kiryanov 								0x80000000);
269e32028a7SNikita Kiryanov 			if (bank2_size == 0x40000000) {
270e32028a7SNikita Kiryanov 				/* Don't do a full reset here */
271e32028a7SNikita Kiryanov 				spl_mx6q_dram_init(DDR_64BIT_2GB, false);
272e32028a7SNikita Kiryanov 			} else {
273e32028a7SNikita Kiryanov 				spl_mx6q_dram_init(DDR_64BIT_1GB, true);
274e32028a7SNikita Kiryanov 			}
275e32028a7SNikita Kiryanov 
276e32028a7SNikita Kiryanov 			return 0;
277e32028a7SNikita Kiryanov 		}
278e32028a7SNikita Kiryanov 
279e32028a7SNikita Kiryanov 		spl_mx6q_dram_init(DDR_32BIT_512MB, true);
280e32028a7SNikita Kiryanov 		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
281e32028a7SNikita Kiryanov 		if (bank1_size == 0x20000000)
282e32028a7SNikita Kiryanov 			return 0;
283e32028a7SNikita Kiryanov 
284e32028a7SNikita Kiryanov 		spl_mx6q_dram_init(DDR_16BIT_256MB, true);
285e32028a7SNikita Kiryanov 		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
286e32028a7SNikita Kiryanov 		if (bank1_size == 0x10000000)
287e32028a7SNikita Kiryanov 			return 0;
288e32028a7SNikita Kiryanov 
289e32028a7SNikita Kiryanov 		break;
290e32028a7SNikita Kiryanov 	}
291e32028a7SNikita Kiryanov 
292e32028a7SNikita Kiryanov 	return -1;
293e32028a7SNikita Kiryanov }
294e32028a7SNikita Kiryanov 
295e32028a7SNikita Kiryanov static iomux_v3_cfg_t const uart4_pads[] = {
296e32028a7SNikita Kiryanov 	IOMUX_PADS(PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
297e32028a7SNikita Kiryanov 	IOMUX_PADS(PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
298e32028a7SNikita Kiryanov };
299e32028a7SNikita Kiryanov 
300e32028a7SNikita Kiryanov static void cm_fx6_setup_uart(void)
301e32028a7SNikita Kiryanov {
302e32028a7SNikita Kiryanov 	SETUP_IOMUX_PADS(uart4_pads);
303e32028a7SNikita Kiryanov 	enable_uart_clk(1);
304e32028a7SNikita Kiryanov }
305e32028a7SNikita Kiryanov 
306e32028a7SNikita Kiryanov #ifdef CONFIG_SPL_SPI_SUPPORT
307e32028a7SNikita Kiryanov static void cm_fx6_setup_ecspi(void)
308e32028a7SNikita Kiryanov {
309e32028a7SNikita Kiryanov 	cm_fx6_set_ecspi_iomux();
3102d59acc7SPeng Fan 	enable_spi_clk(1, 0);
311e32028a7SNikita Kiryanov }
312e32028a7SNikita Kiryanov #else
313e32028a7SNikita Kiryanov static void cm_fx6_setup_ecspi(void) { }
314e32028a7SNikita Kiryanov #endif
315e32028a7SNikita Kiryanov 
316e32028a7SNikita Kiryanov void board_init_f(ulong dummy)
317e32028a7SNikita Kiryanov {
318a6b0652bSNikita Kiryanov 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
319a6b0652bSNikita Kiryanov 
320a6b0652bSNikita Kiryanov 	/*
321a6b0652bSNikita Kiryanov 	 * We don't use DMA in SPL, but we do need it in U-Boot. U-Boot
322a6b0652bSNikita Kiryanov 	 * initializes DMA very early (before all board code), so the only
323a6b0652bSNikita Kiryanov 	 * opportunity we have to initialize APBHDMA clocks is in SPL.
324a6b0652bSNikita Kiryanov 	 */
325a6b0652bSNikita Kiryanov 	setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
326a6b0652bSNikita Kiryanov 	enable_usdhc_clk(1, 2);
327a6b0652bSNikita Kiryanov 
328e32028a7SNikita Kiryanov 	arch_cpu_init();
329e32028a7SNikita Kiryanov 	timer_init();
330e32028a7SNikita Kiryanov 	cm_fx6_setup_ecspi();
331e32028a7SNikita Kiryanov 	cm_fx6_setup_uart();
332e32028a7SNikita Kiryanov 	get_clocks();
333e32028a7SNikita Kiryanov 	preloader_console_init();
334e32028a7SNikita Kiryanov 	gpio_direction_output(CM_FX6_GREEN_LED, 1);
335e32028a7SNikita Kiryanov 	if (cm_fx6_spl_dram_init()) {
336e32028a7SNikita Kiryanov 		puts("!!!ERROR!!! DRAM detection failed!!!\n");
337e32028a7SNikita Kiryanov 		hang();
338e32028a7SNikita Kiryanov 	}
339e32028a7SNikita Kiryanov 
340e32028a7SNikita Kiryanov 	memset(__bss_start, 0, __bss_end - __bss_start);
341e32028a7SNikita Kiryanov 	board_init_r(NULL, 0);
342e32028a7SNikita Kiryanov }
343e32028a7SNikita Kiryanov 
3447b9e980eSNikita Kiryanov void board_boot_order(u32 *spl_boot_list)
345e32028a7SNikita Kiryanov {
3467b9e980eSNikita Kiryanov 	spl_boot_list[0] = spl_boot_device();
3477b9e980eSNikita Kiryanov 	switch (spl_boot_list[0]) {
3487b9e980eSNikita Kiryanov 	case BOOT_DEVICE_SPI:
3497b9e980eSNikita Kiryanov 		spl_boot_list[1] = BOOT_DEVICE_MMC1;
3507b9e980eSNikita Kiryanov 		break;
3517b9e980eSNikita Kiryanov 	case BOOT_DEVICE_MMC1:
3527b9e980eSNikita Kiryanov 		spl_boot_list[1] = BOOT_DEVICE_SPI;
3537b9e980eSNikita Kiryanov 		break;
3547b9e980eSNikita Kiryanov 	}
355e32028a7SNikita Kiryanov }
356e32028a7SNikita Kiryanov 
357e32028a7SNikita Kiryanov #ifdef CONFIG_SPL_MMC_SUPPORT
358e32028a7SNikita Kiryanov static struct fsl_esdhc_cfg usdhc_cfg = {
359e32028a7SNikita Kiryanov 	.esdhc_base = USDHC3_BASE_ADDR,
360e32028a7SNikita Kiryanov 	.max_bus_width = 4,
361e32028a7SNikita Kiryanov };
362e32028a7SNikita Kiryanov 
363e32028a7SNikita Kiryanov int board_mmc_init(bd_t *bis)
364e32028a7SNikita Kiryanov {
365e32028a7SNikita Kiryanov 	cm_fx6_set_usdhc_iomux();
366e32028a7SNikita Kiryanov 
367e32028a7SNikita Kiryanov 	usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
368e32028a7SNikita Kiryanov 
369e32028a7SNikita Kiryanov 	return fsl_esdhc_initialize(bis, &usdhc_cfg);
370e32028a7SNikita Kiryanov }
371e32028a7SNikita Kiryanov #endif
372