xref: /openbmc/u-boot/board/compulab/cm_fx6/spl.c (revision 2d59acc70f76e6d52cc9a226c55539c9353a23cb)
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,
110e32028a7SNikita Kiryanov };
111e32028a7SNikita Kiryanov 
112e32028a7SNikita Kiryanov static struct mx6_ddr3_cfg cm_fx6_ddr3_cfg_s = {
113e32028a7SNikita Kiryanov 	.mem_speed	= 800,
114e32028a7SNikita Kiryanov 	.density	= 4,
115e32028a7SNikita Kiryanov 	.rowaddr	= 14,
116e32028a7SNikita Kiryanov 	.coladdr	= 10,
117e32028a7SNikita Kiryanov 	.pagesz		= 2,
118e32028a7SNikita Kiryanov 	.trcd		= 1800,
119e32028a7SNikita Kiryanov 	.trcmin		= 5200,
120e32028a7SNikita Kiryanov 	.trasmin	= 3600,
121e32028a7SNikita Kiryanov 	.SRT		= 0,
122e32028a7SNikita Kiryanov };
123e32028a7SNikita Kiryanov 
124e32028a7SNikita Kiryanov static void spl_mx6s_dram_init(enum ddr_config dram_config, bool reset)
125e32028a7SNikita Kiryanov {
126e32028a7SNikita Kiryanov 	if (reset)
127e32028a7SNikita Kiryanov 		((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2;
128e32028a7SNikita Kiryanov 
129e32028a7SNikita Kiryanov 	switch (dram_config) {
130e32028a7SNikita Kiryanov 	case DDR_16BIT_256MB:
131e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_s.dsize = 0;
132e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_s.ncs = 1;
133e32028a7SNikita Kiryanov 		break;
134e32028a7SNikita Kiryanov 	case DDR_32BIT_512MB:
135e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_s.dsize = 1;
136e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_s.ncs = 1;
137e32028a7SNikita Kiryanov 		break;
138e32028a7SNikita Kiryanov 	case DDR_32BIT_1GB:
139e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_s.dsize = 1;
140e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_s.ncs = 2;
141e32028a7SNikita Kiryanov 		break;
142e32028a7SNikita Kiryanov 	default:
143e32028a7SNikita Kiryanov 		puts("Tried to setup invalid DDR configuration\n");
144e32028a7SNikita Kiryanov 		hang();
145e32028a7SNikita Kiryanov 	}
146e32028a7SNikita Kiryanov 
147e32028a7SNikita Kiryanov 	mx6_dram_cfg(&cm_fx6_sysinfo_s, &cm_fx6_calib_s, &cm_fx6_ddr3_cfg_s);
148e32028a7SNikita Kiryanov 	udelay(100);
149e32028a7SNikita Kiryanov }
150e32028a7SNikita Kiryanov 
151e32028a7SNikita Kiryanov static struct mx6_mmdc_calibration cm_fx6_calib_q = {
152e32028a7SNikita Kiryanov 	.p0_mpwldectrl0	= 0x00630068,
153e32028a7SNikita Kiryanov 	.p0_mpwldectrl1	= 0x0068005D,
154e32028a7SNikita Kiryanov 	.p0_mpdgctrl0	= 0x04140428,
155e32028a7SNikita Kiryanov 	.p0_mpdgctrl1	= 0x037C037C,
156e32028a7SNikita Kiryanov 	.p0_mprddlctl	= 0x3C30303A,
157e32028a7SNikita Kiryanov 	.p0_mpwrdlctl	= 0x3A344038,
158e32028a7SNikita Kiryanov 	.p1_mpwldectrl0	= 0x0035004C,
159e32028a7SNikita Kiryanov 	.p1_mpwldectrl1	= 0x00170026,
160e32028a7SNikita Kiryanov 	.p1_mpdgctrl0	= 0x0374037C,
161e32028a7SNikita Kiryanov 	.p1_mpdgctrl1	= 0x0350032C,
162e32028a7SNikita Kiryanov 	.p1_mprddlctl	= 0x30322A3C,
163e32028a7SNikita Kiryanov 	.p1_mpwrdlctl	= 0x48304A3E,
164e32028a7SNikita Kiryanov };
165e32028a7SNikita Kiryanov 
166e32028a7SNikita Kiryanov static struct mx6_ddr_sysinfo cm_fx6_sysinfo_q = {
167e32028a7SNikita Kiryanov 	.cs_density	= 16,
168e32028a7SNikita Kiryanov 	.cs1_mirror	= 1,
169e32028a7SNikita Kiryanov 	.bi_on		= 1,
170e32028a7SNikita Kiryanov 	.rtt_nom	= 1,
171e32028a7SNikita Kiryanov 	.rtt_wr		= 0,
172e32028a7SNikita Kiryanov 	.ralat		= 5,
173e32028a7SNikita Kiryanov 	.walat		= 1,
174e32028a7SNikita Kiryanov 	.mif3_mode	= 3,
175e32028a7SNikita Kiryanov 	.rst_to_cke	= 0x23,
176e32028a7SNikita Kiryanov 	.sde_to_rst	= 0x10,
177e32028a7SNikita Kiryanov };
178e32028a7SNikita Kiryanov 
179e32028a7SNikita Kiryanov static struct mx6_ddr3_cfg cm_fx6_ddr3_cfg_q = {
180e32028a7SNikita Kiryanov 	.mem_speed	= 1066,
181e32028a7SNikita Kiryanov 	.density	= 4,
182e32028a7SNikita Kiryanov 	.rowaddr	= 14,
183e32028a7SNikita Kiryanov 	.coladdr	= 10,
184e32028a7SNikita Kiryanov 	.pagesz		= 2,
185e32028a7SNikita Kiryanov 	.trcd		= 1324,
186e32028a7SNikita Kiryanov 	.trcmin		= 59500,
187e32028a7SNikita Kiryanov 	.trasmin	= 9750,
188e32028a7SNikita Kiryanov 	.SRT		= 0,
189e32028a7SNikita Kiryanov };
190e32028a7SNikita Kiryanov 
191e32028a7SNikita Kiryanov static void spl_mx6q_dram_init(enum ddr_config dram_config, bool reset)
192e32028a7SNikita Kiryanov {
193e32028a7SNikita Kiryanov 	if (reset)
194e32028a7SNikita Kiryanov 		((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2;
195e32028a7SNikita Kiryanov 
196e32028a7SNikita Kiryanov 	cm_fx6_ddr3_cfg_q.rowaddr = 14;
197e32028a7SNikita Kiryanov 	switch (dram_config) {
198e32028a7SNikita Kiryanov 	case DDR_16BIT_256MB:
199e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.dsize = 0;
200e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.ncs = 1;
201e32028a7SNikita Kiryanov 		break;
202e32028a7SNikita Kiryanov 	case DDR_32BIT_512MB:
203e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.dsize = 1;
204e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.ncs = 1;
205e32028a7SNikita Kiryanov 		break;
206e32028a7SNikita Kiryanov 	case DDR_64BIT_1GB:
207e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.dsize = 2;
208e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.ncs = 1;
209e32028a7SNikita Kiryanov 		break;
210e32028a7SNikita Kiryanov 	case DDR_64BIT_2GB:
211e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.dsize = 2;
212e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.ncs = 2;
213e32028a7SNikita Kiryanov 		break;
214e32028a7SNikita Kiryanov 	case DDR_64BIT_4GB:
215e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.dsize = 2;
216e32028a7SNikita Kiryanov 		cm_fx6_sysinfo_q.ncs = 2;
217e32028a7SNikita Kiryanov 		cm_fx6_ddr3_cfg_q.rowaddr = 15;
218e32028a7SNikita Kiryanov 		break;
219e32028a7SNikita Kiryanov 	default:
220e32028a7SNikita Kiryanov 		puts("Tried to setup invalid DDR configuration\n");
221e32028a7SNikita Kiryanov 		hang();
222e32028a7SNikita Kiryanov 	}
223e32028a7SNikita Kiryanov 
224e32028a7SNikita Kiryanov 	mx6_dram_cfg(&cm_fx6_sysinfo_q, &cm_fx6_calib_q, &cm_fx6_ddr3_cfg_q);
225e32028a7SNikita Kiryanov 	udelay(100);
226e32028a7SNikita Kiryanov }
227e32028a7SNikita Kiryanov 
228e32028a7SNikita Kiryanov static int cm_fx6_spl_dram_init(void)
229e32028a7SNikita Kiryanov {
230e32028a7SNikita Kiryanov 	unsigned long bank1_size, bank2_size;
231e32028a7SNikita Kiryanov 
232e32028a7SNikita Kiryanov 	switch (get_cpu_type()) {
233e32028a7SNikita Kiryanov 	case MXC_CPU_MX6SOLO:
234e32028a7SNikita Kiryanov 		mx6sdl_dram_iocfg(64, &ddr_iomux_s, &grp_iomux_s);
235e32028a7SNikita Kiryanov 
236e32028a7SNikita Kiryanov 		spl_mx6s_dram_init(DDR_32BIT_1GB, false);
237e32028a7SNikita Kiryanov 		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
2380b23780fSNikita Kiryanov 		bank2_size = get_ram_size((long int *)PHYS_SDRAM_2, 0x80000000);
2390b23780fSNikita Kiryanov 		if (bank1_size == 0x20000000) {
2400b23780fSNikita Kiryanov 			if (bank2_size == 0x20000000)
241e32028a7SNikita Kiryanov 				return 0;
242e32028a7SNikita Kiryanov 
243e32028a7SNikita Kiryanov 			spl_mx6s_dram_init(DDR_32BIT_512MB, true);
244e32028a7SNikita Kiryanov 			return 0;
245e32028a7SNikita Kiryanov 		}
246e32028a7SNikita Kiryanov 
247e32028a7SNikita Kiryanov 		spl_mx6s_dram_init(DDR_16BIT_256MB, true);
248e32028a7SNikita Kiryanov 		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
249e32028a7SNikita Kiryanov 		if (bank1_size == 0x10000000)
250e32028a7SNikita Kiryanov 			return 0;
251e32028a7SNikita Kiryanov 
252e32028a7SNikita Kiryanov 		break;
253e32028a7SNikita Kiryanov 	case MXC_CPU_MX6D:
254e32028a7SNikita Kiryanov 	case MXC_CPU_MX6Q:
255e32028a7SNikita Kiryanov 		mx6dq_dram_iocfg(64, &ddr_iomux_q, &grp_iomux_q);
256e32028a7SNikita Kiryanov 
257e32028a7SNikita Kiryanov 		spl_mx6q_dram_init(DDR_64BIT_4GB, false);
258e32028a7SNikita Kiryanov 		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
259e32028a7SNikita Kiryanov 		if (bank1_size == 0x80000000)
260e32028a7SNikita Kiryanov 			return 0;
261e32028a7SNikita Kiryanov 
262e32028a7SNikita Kiryanov 		if (bank1_size == 0x40000000) {
263e32028a7SNikita Kiryanov 			bank2_size = get_ram_size((long int *)PHYS_SDRAM_2,
264e32028a7SNikita Kiryanov 								0x80000000);
265e32028a7SNikita Kiryanov 			if (bank2_size == 0x40000000) {
266e32028a7SNikita Kiryanov 				/* Don't do a full reset here */
267e32028a7SNikita Kiryanov 				spl_mx6q_dram_init(DDR_64BIT_2GB, false);
268e32028a7SNikita Kiryanov 			} else {
269e32028a7SNikita Kiryanov 				spl_mx6q_dram_init(DDR_64BIT_1GB, true);
270e32028a7SNikita Kiryanov 			}
271e32028a7SNikita Kiryanov 
272e32028a7SNikita Kiryanov 			return 0;
273e32028a7SNikita Kiryanov 		}
274e32028a7SNikita Kiryanov 
275e32028a7SNikita Kiryanov 		spl_mx6q_dram_init(DDR_32BIT_512MB, true);
276e32028a7SNikita Kiryanov 		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
277e32028a7SNikita Kiryanov 		if (bank1_size == 0x20000000)
278e32028a7SNikita Kiryanov 			return 0;
279e32028a7SNikita Kiryanov 
280e32028a7SNikita Kiryanov 		spl_mx6q_dram_init(DDR_16BIT_256MB, true);
281e32028a7SNikita Kiryanov 		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
282e32028a7SNikita Kiryanov 		if (bank1_size == 0x10000000)
283e32028a7SNikita Kiryanov 			return 0;
284e32028a7SNikita Kiryanov 
285e32028a7SNikita Kiryanov 		break;
286e32028a7SNikita Kiryanov 	}
287e32028a7SNikita Kiryanov 
288e32028a7SNikita Kiryanov 	return -1;
289e32028a7SNikita Kiryanov }
290e32028a7SNikita Kiryanov 
291e32028a7SNikita Kiryanov static iomux_v3_cfg_t const uart4_pads[] = {
292e32028a7SNikita Kiryanov 	IOMUX_PADS(PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
293e32028a7SNikita Kiryanov 	IOMUX_PADS(PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
294e32028a7SNikita Kiryanov };
295e32028a7SNikita Kiryanov 
296e32028a7SNikita Kiryanov static void cm_fx6_setup_uart(void)
297e32028a7SNikita Kiryanov {
298e32028a7SNikita Kiryanov 	SETUP_IOMUX_PADS(uart4_pads);
299e32028a7SNikita Kiryanov 	enable_uart_clk(1);
300e32028a7SNikita Kiryanov }
301e32028a7SNikita Kiryanov 
302e32028a7SNikita Kiryanov #ifdef CONFIG_SPL_SPI_SUPPORT
303e32028a7SNikita Kiryanov static void cm_fx6_setup_ecspi(void)
304e32028a7SNikita Kiryanov {
305e32028a7SNikita Kiryanov 	cm_fx6_set_ecspi_iomux();
306*2d59acc7SPeng Fan 	enable_spi_clk(1, 0);
307e32028a7SNikita Kiryanov }
308e32028a7SNikita Kiryanov #else
309e32028a7SNikita Kiryanov static void cm_fx6_setup_ecspi(void) { }
310e32028a7SNikita Kiryanov #endif
311e32028a7SNikita Kiryanov 
312e32028a7SNikita Kiryanov void board_init_f(ulong dummy)
313e32028a7SNikita Kiryanov {
314a6b0652bSNikita Kiryanov 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
315a6b0652bSNikita Kiryanov 
316a6b0652bSNikita Kiryanov 	/*
317a6b0652bSNikita Kiryanov 	 * We don't use DMA in SPL, but we do need it in U-Boot. U-Boot
318a6b0652bSNikita Kiryanov 	 * initializes DMA very early (before all board code), so the only
319a6b0652bSNikita Kiryanov 	 * opportunity we have to initialize APBHDMA clocks is in SPL.
320a6b0652bSNikita Kiryanov 	 */
321a6b0652bSNikita Kiryanov 	setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
322a6b0652bSNikita Kiryanov 	enable_usdhc_clk(1, 2);
323a6b0652bSNikita Kiryanov 
324e32028a7SNikita Kiryanov 	arch_cpu_init();
325e32028a7SNikita Kiryanov 	timer_init();
326e32028a7SNikita Kiryanov 	cm_fx6_setup_ecspi();
327e32028a7SNikita Kiryanov 	cm_fx6_setup_uart();
328e32028a7SNikita Kiryanov 	get_clocks();
329e32028a7SNikita Kiryanov 	preloader_console_init();
330e32028a7SNikita Kiryanov 	gpio_direction_output(CM_FX6_GREEN_LED, 1);
331e32028a7SNikita Kiryanov 	if (cm_fx6_spl_dram_init()) {
332e32028a7SNikita Kiryanov 		puts("!!!ERROR!!! DRAM detection failed!!!\n");
333e32028a7SNikita Kiryanov 		hang();
334e32028a7SNikita Kiryanov 	}
335e32028a7SNikita Kiryanov 
336e32028a7SNikita Kiryanov 	memset(__bss_start, 0, __bss_end - __bss_start);
337e32028a7SNikita Kiryanov 	board_init_r(NULL, 0);
338e32028a7SNikita Kiryanov }
339e32028a7SNikita Kiryanov 
340e32028a7SNikita Kiryanov void spl_board_init(void)
341e32028a7SNikita Kiryanov {
342e32028a7SNikita Kiryanov 	u32 boot_device = spl_boot_device();
343e32028a7SNikita Kiryanov 
344e32028a7SNikita Kiryanov 	if (boot_device == BOOT_DEVICE_SPI)
345e32028a7SNikita Kiryanov 		puts("Booting from SPI flash\n");
346e32028a7SNikita Kiryanov 	else if (boot_device == BOOT_DEVICE_MMC1)
347e32028a7SNikita Kiryanov 		puts("Booting from MMC\n");
348e32028a7SNikita Kiryanov 	else
349e32028a7SNikita Kiryanov 		puts("Unknown boot device\n");
350e32028a7SNikita Kiryanov }
351e32028a7SNikita Kiryanov 
352e32028a7SNikita Kiryanov #ifdef CONFIG_SPL_MMC_SUPPORT
353e32028a7SNikita Kiryanov static struct fsl_esdhc_cfg usdhc_cfg = {
354e32028a7SNikita Kiryanov 	.esdhc_base = USDHC3_BASE_ADDR,
355e32028a7SNikita Kiryanov 	.max_bus_width = 4,
356e32028a7SNikita Kiryanov };
357e32028a7SNikita Kiryanov 
358e32028a7SNikita Kiryanov int board_mmc_init(bd_t *bis)
359e32028a7SNikita Kiryanov {
360e32028a7SNikita Kiryanov 	cm_fx6_set_usdhc_iomux();
361e32028a7SNikita Kiryanov 
362e32028a7SNikita Kiryanov 	usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
363e32028a7SNikita Kiryanov 
364e32028a7SNikita Kiryanov 	return fsl_esdhc_initialize(bis, &usdhc_cfg);
365e32028a7SNikita Kiryanov }
366e32028a7SNikita Kiryanov #endif
367