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