1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (C) 2017 DENX Software Engineering
3*4882a593Smuzhiyun * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <common.h>
9*4882a593Smuzhiyun #include <spl.h>
10*4882a593Smuzhiyun #include <linux/libfdt.h>
11*4882a593Smuzhiyun #include <asm/io.h>
12*4882a593Smuzhiyun #include <asm/arch/clock.h>
13*4882a593Smuzhiyun #include <asm/arch/mx6-ddr.h>
14*4882a593Smuzhiyun #include <asm/arch/mx6-pins.h>
15*4882a593Smuzhiyun #include "asm/arch/crm_regs.h"
16*4882a593Smuzhiyun #include <asm/arch/sys_proto.h>
17*4882a593Smuzhiyun #include <asm/arch/imx-regs.h>
18*4882a593Smuzhiyun #include "asm/arch/iomux.h"
19*4882a593Smuzhiyun #include <asm/mach-imx/iomux-v3.h>
20*4882a593Smuzhiyun #include <environment.h>
21*4882a593Smuzhiyun #include <fsl_esdhc.h>
22*4882a593Smuzhiyun #include <netdev.h>
23*4882a593Smuzhiyun #include "common.h"
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun static const struct mx6dq_iomux_ddr_regs mx6_ddr_ioregs = {
28*4882a593Smuzhiyun .dram_sdclk_0 = 0x00000030,
29*4882a593Smuzhiyun .dram_sdclk_1 = 0x00000030,
30*4882a593Smuzhiyun .dram_cas = 0x00000030,
31*4882a593Smuzhiyun .dram_ras = 0x00000030,
32*4882a593Smuzhiyun .dram_reset = 0x00000030,
33*4882a593Smuzhiyun .dram_sdcke0 = 0x00003000,
34*4882a593Smuzhiyun .dram_sdcke1 = 0x00003000,
35*4882a593Smuzhiyun .dram_sdba2 = 0x00000000,
36*4882a593Smuzhiyun .dram_sdodt0 = 0x00000030,
37*4882a593Smuzhiyun .dram_sdodt1 = 0x00000030,
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun .dram_sdqs0 = 0x00000030,
40*4882a593Smuzhiyun .dram_sdqs1 = 0x00000030,
41*4882a593Smuzhiyun .dram_sdqs2 = 0x00000030,
42*4882a593Smuzhiyun .dram_sdqs3 = 0x00000030,
43*4882a593Smuzhiyun .dram_sdqs4 = 0x00000030,
44*4882a593Smuzhiyun .dram_sdqs5 = 0x00000030,
45*4882a593Smuzhiyun .dram_sdqs6 = 0x00000030,
46*4882a593Smuzhiyun .dram_sdqs7 = 0x00000030,
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun .dram_dqm0 = 0x00000030,
49*4882a593Smuzhiyun .dram_dqm1 = 0x00000030,
50*4882a593Smuzhiyun .dram_dqm2 = 0x00000030,
51*4882a593Smuzhiyun .dram_dqm3 = 0x00000030,
52*4882a593Smuzhiyun .dram_dqm4 = 0x00000030,
53*4882a593Smuzhiyun .dram_dqm5 = 0x00000030,
54*4882a593Smuzhiyun .dram_dqm6 = 0x00000030,
55*4882a593Smuzhiyun .dram_dqm7 = 0x00000030,
56*4882a593Smuzhiyun };
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun static const struct mx6dq_iomux_grp_regs mx6_grp_ioregs = {
59*4882a593Smuzhiyun .grp_ddr_type = 0x000c0000,
60*4882a593Smuzhiyun .grp_ddrmode_ctl = 0x00020000,
61*4882a593Smuzhiyun .grp_ddrpke = 0x00000000,
62*4882a593Smuzhiyun .grp_addds = 0x00000030,
63*4882a593Smuzhiyun .grp_ctlds = 0x00000030,
64*4882a593Smuzhiyun .grp_ddrmode = 0x00020000,
65*4882a593Smuzhiyun .grp_b0ds = 0x00000030,
66*4882a593Smuzhiyun .grp_b1ds = 0x00000030,
67*4882a593Smuzhiyun .grp_b2ds = 0x00000030,
68*4882a593Smuzhiyun .grp_b3ds = 0x00000030,
69*4882a593Smuzhiyun .grp_b4ds = 0x00000030,
70*4882a593Smuzhiyun .grp_b5ds = 0x00000030,
71*4882a593Smuzhiyun .grp_b6ds = 0x00000030,
72*4882a593Smuzhiyun .grp_b7ds = 0x00000030,
73*4882a593Smuzhiyun };
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun /* 4x128Mx16.cfg */
76*4882a593Smuzhiyun static const struct mx6_mmdc_calibration mx6_4x256mx16_mmdc_calib = {
77*4882a593Smuzhiyun .p0_mpwldectrl0 = 0x002D0028,
78*4882a593Smuzhiyun .p0_mpwldectrl1 = 0x0032002D,
79*4882a593Smuzhiyun .p1_mpwldectrl0 = 0x00210036,
80*4882a593Smuzhiyun .p1_mpwldectrl1 = 0x0019002E,
81*4882a593Smuzhiyun .p0_mpdgctrl0 = 0x4349035C,
82*4882a593Smuzhiyun .p0_mpdgctrl1 = 0x0348033D,
83*4882a593Smuzhiyun .p1_mpdgctrl0 = 0x43550362,
84*4882a593Smuzhiyun .p1_mpdgctrl1 = 0x03520316,
85*4882a593Smuzhiyun .p0_mprddlctl = 0x41393940,
86*4882a593Smuzhiyun .p1_mprddlctl = 0x3F3A3C47,
87*4882a593Smuzhiyun .p0_mpwrdlctl = 0x413A423A,
88*4882a593Smuzhiyun .p1_mpwrdlctl = 0x4042483E,
89*4882a593Smuzhiyun };
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /* MT41K128M16JT-125 (2Gb density) */
92*4882a593Smuzhiyun static const struct mx6_ddr3_cfg mt41k128m16jt_125 = {
93*4882a593Smuzhiyun .mem_speed = 1600,
94*4882a593Smuzhiyun .density = 2,
95*4882a593Smuzhiyun .width = 16,
96*4882a593Smuzhiyun .banks = 8,
97*4882a593Smuzhiyun .rowaddr = 14,
98*4882a593Smuzhiyun .coladdr = 10,
99*4882a593Smuzhiyun .pagesz = 2,
100*4882a593Smuzhiyun .trcd = 1375,
101*4882a593Smuzhiyun .trcmin = 4875,
102*4882a593Smuzhiyun .trasmin = 3500,
103*4882a593Smuzhiyun };
104*4882a593Smuzhiyun
ccgr_init(void)105*4882a593Smuzhiyun static void ccgr_init(void)
106*4882a593Smuzhiyun {
107*4882a593Smuzhiyun struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun writel(0x00C03F3F, &ccm->CCGR0);
110*4882a593Smuzhiyun writel(0x0030FC3F, &ccm->CCGR1);
111*4882a593Smuzhiyun writel(0x0FFFCFC0, &ccm->CCGR2);
112*4882a593Smuzhiyun writel(0x3FF00000, &ccm->CCGR3);
113*4882a593Smuzhiyun writel(0x00FFF300, &ccm->CCGR4);
114*4882a593Smuzhiyun writel(0x0F0000C3, &ccm->CCGR5);
115*4882a593Smuzhiyun writel(0x000003FF, &ccm->CCGR6);
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun
spl_dram_init(void)118*4882a593Smuzhiyun static void spl_dram_init(void)
119*4882a593Smuzhiyun {
120*4882a593Smuzhiyun struct mx6_ddr_sysinfo sysinfo = {
121*4882a593Smuzhiyun /* width of data bus:0=16,1=32,2=64 */
122*4882a593Smuzhiyun .dsize = 2,
123*4882a593Smuzhiyun /* config for full 4GB range so that get_mem_size() works */
124*4882a593Smuzhiyun .cs_density = 32, /* 32Gb per CS */
125*4882a593Smuzhiyun /* single chip select */
126*4882a593Smuzhiyun .ncs = 1,
127*4882a593Smuzhiyun .cs1_mirror = 0,
128*4882a593Smuzhiyun .rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */
129*4882a593Smuzhiyun .rtt_nom = 2 /*DDR3_RTT_120_OHM*/, /* RTT_Nom = RZQ/2 */
130*4882a593Smuzhiyun .walat = 1, /* Write additional latency */
131*4882a593Smuzhiyun .ralat = 5, /* Read additional latency */
132*4882a593Smuzhiyun .mif3_mode = 3, /* Command prediction working mode */
133*4882a593Smuzhiyun .bi_on = 1, /* Bank interleaving enabled */
134*4882a593Smuzhiyun .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */
135*4882a593Smuzhiyun .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */
136*4882a593Smuzhiyun .pd_fast_exit = 1, /* enable precharge power-down fast exit */
137*4882a593Smuzhiyun .ddr_type = DDR_TYPE_DDR3,
138*4882a593Smuzhiyun .refsel = 1, /* Refresh cycles at 32KHz */
139*4882a593Smuzhiyun .refr = 7, /* 8 refresh commands per refresh cycle */
140*4882a593Smuzhiyun };
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun mx6dq_dram_iocfg(64, &mx6_ddr_ioregs, &mx6_grp_ioregs);
143*4882a593Smuzhiyun mx6_dram_cfg(&sysinfo, &mx6_4x256mx16_mmdc_calib, &mt41k128m16jt_125);
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun #ifdef CONFIG_SPL_SPI_SUPPORT
displ5_init_ecspi(void)147*4882a593Smuzhiyun static void displ5_init_ecspi(void)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun displ5_set_iomux_ecspi_spl();
150*4882a593Smuzhiyun enable_spi_clk(1, 1);
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun #else
displ5_init_ecspi(void)153*4882a593Smuzhiyun static inline void displ5_init_ecspi(void) { }
154*4882a593Smuzhiyun #endif
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun #ifdef CONFIG_SPL_MMC_SUPPORT
157*4882a593Smuzhiyun static struct fsl_esdhc_cfg usdhc_cfg = {
158*4882a593Smuzhiyun .esdhc_base = USDHC4_BASE_ADDR,
159*4882a593Smuzhiyun .max_bus_width = 8,
160*4882a593Smuzhiyun };
161*4882a593Smuzhiyun
board_mmc_init(bd_t * bd)162*4882a593Smuzhiyun int board_mmc_init(bd_t *bd)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun displ5_set_iomux_usdhc_spl();
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
167*4882a593Smuzhiyun gd->arch.sdhc_clk = usdhc_cfg.sdhc_clk;
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun return fsl_esdhc_initialize(bd, &usdhc_cfg);
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun #endif
172*4882a593Smuzhiyun
board_init_f(ulong dummy)173*4882a593Smuzhiyun void board_init_f(ulong dummy)
174*4882a593Smuzhiyun {
175*4882a593Smuzhiyun ccgr_init();
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun arch_cpu_init();
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun gpr_init();
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun /* setup GP timer */
182*4882a593Smuzhiyun timer_init();
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun displ5_set_iomux_uart_spl();
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun /* UART clocks enabled and gd valid - init serial console */
187*4882a593Smuzhiyun preloader_console_init();
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun displ5_init_ecspi();
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun /* DDR initialization */
192*4882a593Smuzhiyun spl_dram_init();
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun /* Clear the BSS. */
195*4882a593Smuzhiyun memset(__bss_start, 0, __bss_end - __bss_start);
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun /* load/boot image from boot device */
198*4882a593Smuzhiyun board_init_r(NULL, 0);
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun
board_boot_order(u32 * spl_boot_list)201*4882a593Smuzhiyun void board_boot_order(u32 *spl_boot_list)
202*4882a593Smuzhiyun {
203*4882a593Smuzhiyun /* Default boot sequence SPI -> MMC */
204*4882a593Smuzhiyun spl_boot_list[0] = spl_boot_device();
205*4882a593Smuzhiyun spl_boot_list[1] = BOOT_DEVICE_MMC1;
206*4882a593Smuzhiyun spl_boot_list[2] = BOOT_DEVICE_UART;
207*4882a593Smuzhiyun spl_boot_list[3] = BOOT_DEVICE_NONE;
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun #ifdef CONFIG_SPL_ENV_SUPPORT
210*4882a593Smuzhiyun /* 'fastboot' */
211*4882a593Smuzhiyun const char *s;
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun env_init();
214*4882a593Smuzhiyun env_load();
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun s = env_get("BOOT_FROM");
217*4882a593Smuzhiyun if (s && strcmp(s, "ACTIVE") == 0) {
218*4882a593Smuzhiyun spl_boot_list[0] = BOOT_DEVICE_MMC1;
219*4882a593Smuzhiyun spl_boot_list[1] = spl_boot_device();
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun #endif
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun
reset_cpu(ulong addr)224*4882a593Smuzhiyun void reset_cpu(ulong addr) {}
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun #ifdef CONFIG_SPL_LOAD_FIT
board_fit_config_name_match(const char * name)227*4882a593Smuzhiyun int board_fit_config_name_match(const char *name)
228*4882a593Smuzhiyun {
229*4882a593Smuzhiyun return 0;
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun #endif
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun #ifdef CONFIG_SPL_OS_BOOT
234*4882a593Smuzhiyun /* Return: 1 - boot to U-Boot. 0 - boot OS (falcon mode) */
spl_start_uboot(void)235*4882a593Smuzhiyun int spl_start_uboot(void)
236*4882a593Smuzhiyun {
237*4882a593Smuzhiyun /* break into full u-boot on 'c' */
238*4882a593Smuzhiyun if (serial_tstc() && serial_getc() == 'c')
239*4882a593Smuzhiyun return 1;
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun #ifdef CONFIG_SPL_ENV_SUPPORT
242*4882a593Smuzhiyun if (env_get_yesno("boot_os") != 1)
243*4882a593Smuzhiyun return 1;
244*4882a593Smuzhiyun #endif
245*4882a593Smuzhiyun return 0;
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun #endif
248