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