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