[U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM

Tapani tapani at technexion.com
Wed Aug 28 13:23:33 CEST 2013


    Add support for TechNexion edm-cf-imx6 SoM

    The edm1-cf-imx6 SoM comes in three variants, one with imx6 solo cpu,
    one with an imx6 dual lite cpu and one with an imx6 quad cpu.

    This patch adds basic support for the module that utilizes SPL boot 
    mechanism for detecting imx6 CPU runtime and sets the system accordingly.

    Signed-off-by: Richard Hu <richard.hu at technexion.com>
    Signed-off-by: Tapani Utriainen <tapani at technexion.com>
    Signed-off-by: Edward Lin <edward.lin at technexion.com>
---
 MAINTAINERS                                     |   4 +
 arch/arm/include/asm/arch-mx6/spl.h             |  19 +
 board/technexion/edm_cf_imx6/Makefile           |  26 +
 board/technexion/edm_cf_imx6/README             |  30 +
 board/technexion/edm_cf_imx6/clocks.cfg         |  44 ++
 board/technexion/edm_cf_imx6/edm_cf_imx6.c      | 801 ++++++++++++++++++++++++
 board/technexion/edm_cf_imx6/edm_cf_imx6_pins.h |  44 ++
 board/technexion/edm_cf_imx6/imximage.cfg       |  17 +
 boards.cfg                                      |   1 +
 include/configs/edm_cf_imx6.h                   | 140 +++++
 10 files changed, 1126 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-mx6/spl.h
 create mode 100644 board/technexion/edm_cf_imx6/Makefile
 create mode 100644 board/technexion/edm_cf_imx6/README
 create mode 100644 board/technexion/edm_cf_imx6/clocks.cfg
 create mode 100644 board/technexion/edm_cf_imx6/edm_cf_imx6.c
 create mode 100644 board/technexion/edm_cf_imx6/edm_cf_imx6_pins.h
 create mode 100644 board/technexion/edm_cf_imx6/imximage.cfg
 create mode 100644 include/configs/edm_cf_imx6.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 0a900dc..2c0f8b1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1074,6 +1074,10 @@ Eric Nelson <eric.nelson at boundarydevices.com>
 	nitrogen6s		i.MX6S		512MB
 	nitrogen6s1g		i.MX6S		1GB
 
+Tapani Utriainen <tapani at technexion.com>
+
+	edm_cf_imx6		i.MX6		several configurations
+
 Alison Wang <b18965 at freescale.com>
 
 	vf610twr	VF610
diff --git a/arch/arm/include/asm/arch-mx6/spl.h b/arch/arm/include/asm/arch-mx6/spl.h
new file mode 100644
index 0000000..dd04088
--- /dev/null
+++ b/arch/arm/include/asm/arch-mx6/spl.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2013 TechNexion Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#ifndef __ASM_ARCH_IMX6_SPL_H__
+#define __ASM_ARCH_IMX6_SPL_H__
+
+#define BOOT_DEVICE_MMC1	0
+#define BOOT_DEVICE_MMC2	1
+#define BOOT_DEVICE_MMC2_2	2
+#define BOOT_DEVICE_NAND	3
+#define BOOT_DEVICE_NONE	4
+
+#endif	/* __ASM_ARCH_IMX6_SPL_H__ */
diff --git a/board/technexion/edm_cf_imx6/Makefile b/board/technexion/edm_cf_imx6/Makefile
new file mode 100644
index 0000000..2e764cb
--- /dev/null
+++ b/board/technexion/edm_cf_imx6/Makefile
@@ -0,0 +1,26 @@
+#
+# (C) Copyright 2013 TechNexion Ltd.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    = $(obj)lib$(BOARD).o
+
+COBJS  := edm_cf_imx6.o
+
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/technexion/edm_cf_imx6/README b/board/technexion/edm_cf_imx6/README
new file mode 100644
index 0000000..aaca361
--- /dev/null
+++ b/board/technexion/edm_cf_imx6/README
@@ -0,0 +1,30 @@
+U-Boot for edm_cf_imx6
+--------------------
+
+The edm_cf_imx6 uses SPL boot for auto configuration of CPU type and memory.
+Supported cpus are imx6 duallite, quad and solo.
+
+For more details of the SoM, please refer to:
+http://www.technexion.com
+
+Building U-boot for edm_cf_imx6
+-----------------------------
+
+To build U-Boot for i.mx6 solo, dual lite, quad:
+
+$ make distclean
+$ make edm_cf_imx6_config
+$ make
+$ make u-boot.img
+
+Flashing U-boot into the SD card
+--------------------------------
+
+- After the 'make u-boot.img' command completes, the generated 'SPL' and
+'u-boot.img' binary must be flashed into the SD card:
+
+# dd if=SPL of=/dev/$dev bs=1k seek=1
+
+# dd if=u-boot.img of=/dev/$dev bs=64k seek=1; sync
+
+Only raw mmc boot has been verified to work.
diff --git a/board/technexion/edm_cf_imx6/clocks.cfg b/board/technexion/edm_cf_imx6/clocks.cfg
new file mode 100644
index 0000000..9a182c8
--- /dev/null
+++ b/board/technexion/edm_cf_imx6/clocks.cfg
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2013 TechNexion Ltd.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Device Configuration Data (DCD) for both imx6sdl and imx6q
+ *
+ * Each entry must be well-defined on all applicable cpu variants
+ *
+ * Also, each entry must have the format
+ * Addr-type           Address        Value
+ *
+ * where:
+ *      Addr-type register length (1,2 or 4 bytes)
+ *      Address   absolute address of the register
+ *      value     value to be stored in the register
+ *
+ */
+
+/* set the default clock gate to save power */
+DATA 4, CCM_CCGR0, 0x00C03F3F
+DATA 4, CCM_CCGR1, 0x0030FC03
+DATA 4, CCM_CCGR2, 0x0FFFC000
+DATA 4, CCM_CCGR3, 0x3FF00000
+
+/* Note: this turns off NAND clock */
+DATA 4, CCM_CCGR4, 0x00FFF300
+DATA 4, CCM_CCGR5, 0x0F0000C3
+DATA 4, CCM_CCGR6, 0x000003FF
+
+/* enable AXI cache for VDOA/VPU/IPU and set Qos=0xf (bypass) */
+DATA 4, MX6_IOMUXC_GPR4, 0xF00000CF
+DATA 4, MX6_IOMUXC_GPR6, 0x007F007F
+
+/*
+ * Setup CCM_CCOSR register as follows:
+ *
+ * cko1_en  = 1	   --> CKO1 enabled
+ * cko1_div = 111  --> divide by 8
+ * cko1_sel = 1011 --> ahb_clk_root
+ *
+ * This sets CKO1 at ahb_clk_root/8 = 132/8 = 16.5 MHz
+ */
+DATA 4, CCM_CCOSR, 0x000000fb
diff --git a/board/technexion/edm_cf_imx6/edm_cf_imx6.c b/board/technexion/edm_cf_imx6/edm_cf_imx6.c
new file mode 100644
index 0000000..1a98168
--- /dev/null
+++ b/board/technexion/edm_cf_imx6/edm_cf_imx6.c
@@ -0,0 +1,801 @@
+/*
+ * Copyright (C) 2013 TechNexion Ltd.
+ *
+ * Author: Richard Hu (richard.hu at technexion.com)
+ *         Tapani Utriainen (tapani at technexion.com)
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/arch/clock.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/iomux.h>
+#include <asm/arch/imx-regs.h>
+#ifdef CONFIG_SPL
+#include <spl.h>
+#endif
+#include <asm/arch/sys_proto.h>
+#include <asm/gpio.h>
+#include <asm/imx-common/iomux-v3.h>
+#include <asm/imx-common/boot_mode.h>
+#include <asm/io.h>
+#include <asm/sizes.h>
+#include <common.h>
+#include <fsl_esdhc.h>
+#include <mmc.h>
+
+#include "edm_cf_imx6_pins.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
+	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |			\
+	PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP |			\
+	PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |			\
+	PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+
+#define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
+	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define USDHC1_CD_GPIO		IMX_GPIO_NR(1, 2)
+#define USDHC3_CD_GPIO		IMX_GPIO_NR(3, 9)
+
+enum boot_device {
+	SD0_BOOT,
+	SD1_BOOT,
+	MMC_BOOT,
+	NAND_BOOT,
+	WEIM_NOR_BOOT,
+	ONE_NAND_BOOT,
+	PATA_BOOT,
+	SATA_BOOT,
+	I2C_BOOT,
+	SPI_NOR_BOOT,
+	UNKNOWN_BOOT,
+	BOOT_DEV_NUM = UNKNOWN_BOOT,
+};
+
+
+static enum boot_device boot_dev;
+enum boot_device get_boot_device(void);
+
+static inline void setup_boot_device(void)
+{
+	uint soc_sbmr = readl(SRC_BASE_ADDR + 0x4);
+	uint bt_mem_ctl = (soc_sbmr & 0x000000FF) >> 4 ;
+	uint bt_mem_type = (soc_sbmr & 0x00000008) >> 3;
+	uint bt_mem_mmc = (soc_sbmr & 0x00001000) >> 12;
+
+	switch (bt_mem_ctl) {
+	case 0x0:
+		if (bt_mem_type)
+			boot_dev = ONE_NAND_BOOT;
+		else
+			boot_dev = WEIM_NOR_BOOT;
+		break;
+	case 0x2:
+			boot_dev = SATA_BOOT;
+		break;
+	case 0x3:
+		if (bt_mem_type)
+			boot_dev = I2C_BOOT;
+		else
+			boot_dev = SPI_NOR_BOOT;
+		break;
+	case 0x4:
+	case 0x5:
+		if (bt_mem_mmc)
+			boot_dev = SD0_BOOT;
+		else
+			boot_dev = SD1_BOOT;
+		break;
+	case 0x6:
+	case 0x7:
+		boot_dev = MMC_BOOT;
+		break;
+	case 0x8 ... 0xf:
+		boot_dev = NAND_BOOT;
+		break;
+	default:
+		boot_dev = UNKNOWN_BOOT;
+		break;
+	}
+}
+
+enum boot_device get_boot_device(void) {
+	return boot_dev;
+}
+
+
+int dram_init(void)
+{
+	uint cpurev, imxtype;
+	u32 sdram_size;
+
+	cpurev = get_cpu_rev();
+	imxtype = (cpurev & 0xFF000) >> 12;
+
+	switch (imxtype){
+	case MXC_CPU_MX6SOLO:
+		sdram_size = 512 * 1024 * 1024;
+		break;
+	case MXC_CPU_MX6Q:
+		sdram_size = 2u * 1024 * 1024 * 1024;
+		break;
+	case MXC_CPU_MX6DL:
+	default:
+		sdram_size = 1u * 1024 * 1024 * 1024;;
+		break;
+	}
+	gd->ram_size = get_ram_size((void *)PHYS_SDRAM, sdram_size);
+
+	return 0;
+}
+
+static iomux_v3_cfg_t const edmdl_uart1_pads[] = {
+	MX6DL_PAD_CSI0_DAT10__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+	MX6DL_PAD_CSI0_DAT11__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const edmq_uart1_pads[] = {
+	MX6Q_PAD_CSI0_DAT10__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+	MX6Q_PAD_CSI0_DAT11__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const edmdl_usdhc1_pads[] = {
+	MX6DL_PAD_SD1_CLK__USDHC1_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6DL_PAD_SD1_CMD__USDHC1_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6DL_PAD_SD1_DAT0__USDHC1_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6DL_PAD_SD1_DAT1__USDHC1_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6DL_PAD_SD1_DAT2__USDHC1_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6DL_PAD_SD1_DAT3__USDHC1_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	/* Card detect */
+	MX6DL_PAD_GPIO_2__GPIO_1_2      | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const edmq_usdhc1_pads[] = {
+	MX6Q_PAD_SD1_CLK__USDHC1_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6Q_PAD_SD1_CMD__USDHC1_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6Q_PAD_SD1_DAT0__USDHC1_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6Q_PAD_SD1_DAT1__USDHC1_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6Q_PAD_SD1_DAT2__USDHC1_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6Q_PAD_SD1_DAT3__USDHC1_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	/* Card detect */
+	MX6Q_PAD_GPIO_2__GPIO_1_2      | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const edmdl_usdhc3_pads[] = {
+	MX6DL_PAD_SD3_CLK__USDHC3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6DL_PAD_SD3_CMD__USDHC3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6DL_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6DL_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6DL_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6DL_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	/* Card detect */
+	MX6DL_PAD_EIM_DA9__GPIO_3_9     | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const edmq_usdhc3_pads[] = {
+	MX6Q_PAD_SD3_CLK__USDHC3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6Q_PAD_SD3_CMD__USDHC3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	/* Card detect */
+	MX6Q_PAD_EIM_DA9__GPIO_3_9     | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+static bool cpu_is_mx6q(void)
+{
+	u32 cpurev, imxtype;
+
+	cpurev = get_cpu_rev();
+	imxtype = (cpurev & 0xFF000) >> 12;
+
+        return (imxtype == MXC_CPU_MX6Q);
+}
+
+static void setup_iomux_uart(void)
+{
+	const iomux_v3_cfg_t *uart1_pads = NULL;
+	u32 uart1_pads_cnt;
+
+	if (cpu_is_mx6q())
+	{
+		uart1_pads = edmq_uart1_pads;
+		uart1_pads_cnt = ARRAY_SIZE(edmq_uart1_pads);
+	}
+	else
+	{
+		uart1_pads = edmdl_uart1_pads;
+		uart1_pads_cnt = ARRAY_SIZE(edmdl_uart1_pads);
+	}
+	imx_iomux_v3_setup_multiple_pads(uart1_pads, uart1_pads_cnt);
+}
+
+static struct fsl_esdhc_cfg usdhc_cfg[2] = {
+	{ USDHC3_BASE_ADDR },
+	{ USDHC1_BASE_ADDR },
+};
+
+int board_mmc_getcd(struct mmc *mmc)
+{
+	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+	int ret = 0;
+
+	switch (cfg->esdhc_base) {
+	case USDHC1_BASE_ADDR:
+		ret = !gpio_get_value(USDHC1_CD_GPIO);
+		break;
+	case USDHC3_BASE_ADDR:
+		ret = !gpio_get_value(USDHC3_CD_GPIO);
+		break;
+	}
+
+	return ret;
+}
+
+int board_mmc_init(bd_t *bis)
+{
+	s32 status = 0;
+	u32 index = 0;
+	const iomux_v3_cfg_t *usdhc3_pads = NULL;
+	u32 usdhc3_pads_cnt;
+	const iomux_v3_cfg_t *usdhc1_pads = NULL;
+	u32 usdhc1_pads_cnt;
+	/*
+	 * Following map is done:
+	 * (U-boot device node)    (Physical Port)
+	 * mmc0                    SOM MicroSD
+	 * mmc1                    Carrier board MicroSD
+	 */
+	switch (get_boot_device()) {
+		case SD1_BOOT:
+			usdhc_cfg[0].esdhc_base = USDHC1_BASE_ADDR;
+			usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+			usdhc_cfg[0].max_bus_width = 4;
+			usdhc_cfg[1].esdhc_base = USDHC3_BASE_ADDR;
+			usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+			usdhc_cfg[1].max_bus_width = 4;
+		break;
+		case SD0_BOOT:
+		default:
+			usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
+			usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+			usdhc_cfg[0].max_bus_width = 4;
+			usdhc_cfg[1].esdhc_base = USDHC1_BASE_ADDR;
+			usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+			usdhc_cfg[1].max_bus_width = 4;
+		break;
+	}
+
+	for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) {
+		switch (index) {
+		case 0:
+
+			if (cpu_is_mx6q())
+			{
+				usdhc3_pads = edmq_usdhc3_pads;
+				usdhc3_pads_cnt = ARRAY_SIZE(edmq_usdhc3_pads);
+			}
+			else
+			{
+				usdhc3_pads = edmdl_usdhc3_pads;
+				usdhc3_pads_cnt = ARRAY_SIZE(edmdl_usdhc3_pads);
+			}
+			imx_iomux_v3_setup_multiple_pads(
+				usdhc3_pads, usdhc3_pads_cnt);
+
+			gpio_direction_input(USDHC3_CD_GPIO);
+			break;
+		case 1:
+			if (cpu_is_mx6q())
+			{
+				usdhc1_pads = edmq_usdhc1_pads;
+				usdhc1_pads_cnt = ARRAY_SIZE(edmq_usdhc1_pads);
+			}
+			else
+			{
+				usdhc1_pads = edmdl_usdhc1_pads;
+				usdhc1_pads_cnt = ARRAY_SIZE(edmdl_usdhc1_pads);
+			}
+			imx_iomux_v3_setup_multiple_pads(
+				usdhc1_pads, usdhc1_pads_cnt);
+			gpio_direction_input(USDHC1_CD_GPIO);
+			break;
+		default:
+			printf("Warning: you configured more USDHC controllers"
+			       "(%d) then supported by the board (%d)\n",
+			       index + 1, CONFIG_SYS_FSL_USDHC_NUM);
+			return status;
+		}
+		status |= fsl_esdhc_initialize(bis, &usdhc_cfg[index]);
+	}
+	return status;
+}
+
+int board_early_init_f(void)
+{
+	setup_iomux_uart();
+	return 0;
+}
+
+/*
+ * Do not overwrite the console
+ * Use always serial for U-Boot console
+ */
+int overwrite_console(void)
+{
+	return 1;
+}
+
+#ifdef CONFIG_CMD_BMODE
+static const struct boot_mode board_boot_modes[] = {
+	/* 4 bit bus width */
+	{"mmc0",	  MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
+	{"mmc1",	  MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)},
+	{NULL,	 0},
+};
+#endif
+
+int board_late_init(void)
+{
+#ifdef CONFIG_CMD_BMODE
+	add_board_boot_modes(board_boot_modes);
+#endif
+
+	return 0;
+}
+
+int board_init(void)
+{
+	setup_boot_device();
+	/* address of boot parameters */
+	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
+
+	return 0;
+}
+
+int checkboard(void)
+{
+	puts("Board: edm_cf_imx6\n");
+
+	return 0;
+}
+
+#if defined(CONFIG_SPL_BUILD)
+void board_init_f(ulong dummy)
+{
+	/* Set the stack pointer. */
+	asm volatile("mov sp, %0\n" : : "r"(CONFIG_SPL_STACK));
+
+	/* Clear the BSS. */
+	memset(__bss_start, 0, __bss_end - __bss_start);
+
+	/* Set global data pointer. */
+	gd = &gdata;
+
+	arch_cpu_init();
+	board_early_init_f();
+	timer_init();
+	preloader_console_init();
+
+	board_init_r(NULL, 0);
+}
+
+static void spl_dram_init_mx6solo_512mb(void)
+{
+	/* DDR3 initialization based on the MX6Solo Auto Reference Design (ARD) */
+	/* DDR IO TYPE */
+	writel(0x000c0000, IOMUXC_BASE_ADDR + 0x774);
+	writel(0x00000000, IOMUXC_BASE_ADDR + 0x754);
+	/* Clock */
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x4ac);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x4b0);
+	/* Address */
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x464);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x490);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x74c);
+	/* Control */
+	writel(0x000c0030, IOMUXC_BASE_ADDR + 0x494);
+	writel(0x00003000, IOMUXC_BASE_ADDR + 0x4a4);
+	writel(0x00003000, IOMUXC_BASE_ADDR + 0x4a8);
+	writel(0x00000000, IOMUXC_BASE_ADDR + 0x4a0);
+	writel(0x00003030, IOMUXC_BASE_ADDR + 0x4b4);
+	writel(0x00003030, IOMUXC_BASE_ADDR + 0x4b8);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x76c);
+	/* Strobe */
+	writel(0x00020000, IOMUXC_BASE_ADDR + 0x750);
+	writel(0x00000038, IOMUXC_BASE_ADDR + 0x4bc);
+	writel(0x00000038, IOMUXC_BASE_ADDR + 0x4c0);
+	writel(0x00000038, IOMUXC_BASE_ADDR + 0x4c4);
+	writel(0x00000038, IOMUXC_BASE_ADDR + 0x4c8);
+	writel(0x00000038, IOMUXC_BASE_ADDR + 0x4cc);
+	writel(0x00000038, IOMUXC_BASE_ADDR + 0x4d0);
+	writel(0x00000038, IOMUXC_BASE_ADDR + 0x4d4);
+	writel(0x00000038, IOMUXC_BASE_ADDR + 0x4d8);
+	/* Data */
+	writel(0x00020000, IOMUXC_BASE_ADDR + 0x760);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x764);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x770);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x778);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x77c);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x780);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x784);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x78c);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x748);
+
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x470);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x474);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x478);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x47c);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x480);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x484);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x488);
+	writel(0x000C0030, IOMUXC_BASE_ADDR + 0x48c);
+	/* ZQ */
+	writel(0xa1390003, MMDC_P0_BASE_ADDR + 0x800);
+	writel(0xa1390003, MMDC_P1_BASE_ADDR + 0x800);
+	/* Write leveling */
+	writel(0x0040003c, MMDC_P0_BASE_ADDR + 0x80c);
+	writel(0x0032003e, MMDC_P0_BASE_ADDR + 0x810);
+
+	writel(0x42350231, MMDC_P0_BASE_ADDR + 0x83c);
+	writel(0x021a0218, MMDC_P0_BASE_ADDR + 0x840);
+	writel(0x4b4b4e49, MMDC_P0_BASE_ADDR + 0x848);
+	writel(0x3f3f3035, MMDC_P0_BASE_ADDR + 0x850);
+	/* Read data bit delay */
+	writel(0x33333333, MMDC_P0_BASE_ADDR + 0x81c);
+	writel(0x33333333, MMDC_P0_BASE_ADDR + 0x820);
+	writel(0x33333333, MMDC_P0_BASE_ADDR + 0x824);
+	writel(0x33333333, MMDC_P0_BASE_ADDR + 0x828);
+	writel(0x33333333, MMDC_P1_BASE_ADDR + 0x81c);
+	writel(0x33333333, MMDC_P1_BASE_ADDR + 0x820);
+	writel(0x33333333, MMDC_P1_BASE_ADDR + 0x824);
+	writel(0x33333333, MMDC_P1_BASE_ADDR + 0x828);
+	/* Complete calibration by forced measurement */
+	writel(0x00000800, MMDC_P0_BASE_ADDR + 0x8b8);
+
+        writel(0x0002002d, MMDC_P0_BASE_ADDR + 0x004);
+	writel(0x00333030, MMDC_P0_BASE_ADDR + 0x008);
+	writel(0x696d5323, MMDC_P0_BASE_ADDR + 0x00c);
+	writel(0xb66e8c63, MMDC_P0_BASE_ADDR + 0x010);
+	writel(0x01ff00db, MMDC_P0_BASE_ADDR + 0x014);
+	writel(0x00001740, MMDC_P0_BASE_ADDR + 0x018);
+	writel(0x00008000, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x000026d2, MMDC_P0_BASE_ADDR + 0x02c);
+	writel(0x006d0e21, MMDC_P0_BASE_ADDR + 0x030);
+	writel(0x00000027, MMDC_P0_BASE_ADDR + 0x040);
+	writel(0x84190000, MMDC_P0_BASE_ADDR + 0x000);
+	writel(0x04008032, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x00008033, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x00048031, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x07208030, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x04008040, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x00005800, MMDC_P0_BASE_ADDR + 0x020);
+	writel(0x00011117, MMDC_P0_BASE_ADDR + 0x818);
+	writel(0x00011117, MMDC_P1_BASE_ADDR + 0x818);
+	writel(0x0002556d, MMDC_P0_BASE_ADDR + 0x004);
+	writel(0x00011006, MMDC_P1_BASE_ADDR + 0x004);
+	writel(0x00000000, MMDC_P0_BASE_ADDR + 0x01c);
+}
+
+static void spl_dram_init_mx6dl_1g(void)
+{
+	/* DDR3 initialization based on the MX6Solo Auto Reference Design (ARD) */
+	/* DDR IO TYPE */
+	writel(0x000c0000, IOMUXC_BASE_ADDR + 0x774);
+	writel(0x00000000, IOMUXC_BASE_ADDR + 0x754);
+	/* Clock */
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x4ac);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x4b0);
+	/* Address */
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x464);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x490);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x74c);
+	/* Control */
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x494);
+	writel(0x00003000, IOMUXC_BASE_ADDR + 0x4a4);
+	writel(0x00003000, IOMUXC_BASE_ADDR + 0x4a8);
+	writel(0x00000000, IOMUXC_BASE_ADDR + 0x4a0);
+	writel(0x00003030, IOMUXC_BASE_ADDR + 0x4b4);
+	writel(0x00003030, IOMUXC_BASE_ADDR + 0x4b8);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x76c);
+	/* Data Strobe */
+	writel(0x00020000, IOMUXC_BASE_ADDR + 0x750);
+	
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x4bc);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x4c0);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x4c4);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x4c8);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x4cc);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x4d0);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x4d4);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x4d8);
+	/* Data */
+	writel(0x00020000, IOMUXC_BASE_ADDR + 0x760);
+	
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x764);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x770);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x778);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x77c);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x780);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x784);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x78c);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x748);
+
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x470);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x474);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x478);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x47c);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x480);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x484);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x488);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x48c);
+	
+	/* Calibrations */
+	/* ZQ */
+	writel(0xa1390003, MMDC_P0_BASE_ADDR + 0x800);
+	writel(0xa1390003, MMDC_P1_BASE_ADDR + 0x800);
+	/* write leveling */
+	writel(0x001F001F, MMDC_P0_BASE_ADDR + 0x80c);
+	writel(0x001F001F, MMDC_P0_BASE_ADDR + 0x810);
+	writel(0x001F001F, MMDC_P1_BASE_ADDR + 0x80c);
+	writel(0x001F001F, MMDC_P1_BASE_ADDR + 0x810);
+	/* DQS gating, read delay, write delay calibration values */
+	/* based on calibration compare of 0x00ffff00 */
+	writel(0x420E020E, MMDC_P0_BASE_ADDR + 0x83c);
+	writel(0x02000200, MMDC_P0_BASE_ADDR + 0x840);
+	writel(0x42020202, MMDC_P1_BASE_ADDR + 0x83C);
+	writel(0x01720172, MMDC_P1_BASE_ADDR + 0x840);
+	writel(0x494C4F4C, MMDC_P0_BASE_ADDR + 0x848);
+	writel(0x4A4C4C49, MMDC_P1_BASE_ADDR + 0x848);
+	writel(0x3F3F3133, MMDC_P0_BASE_ADDR + 0x850);
+	writel(0x39373F2E, MMDC_P1_BASE_ADDR + 0x850);
+	/* read data bit delay */
+	writel(0x33333333, MMDC_P0_BASE_ADDR + 0x81c);
+	writel(0x33333333, MMDC_P0_BASE_ADDR + 0x820);
+	writel(0x33333333, MMDC_P0_BASE_ADDR + 0x824);
+	writel(0x33333333, MMDC_P0_BASE_ADDR + 0x828);
+	writel(0x33333333, MMDC_P1_BASE_ADDR + 0x81c);
+	writel(0x33333333, MMDC_P1_BASE_ADDR + 0x820);
+	writel(0x33333333, MMDC_P1_BASE_ADDR + 0x824);
+	writel(0x33333333, MMDC_P1_BASE_ADDR + 0x828);
+	/* Complete calibration by forced measurment */
+	writel(0x00000800, MMDC_P0_BASE_ADDR + 0x8b8);
+	writel(0x00000800, MMDC_P1_BASE_ADDR + 0x8b8);
+
+	writel(0x0002002d, MMDC_P0_BASE_ADDR + 0x004);
+	writel(0x00333030, MMDC_P0_BASE_ADDR + 0x008);
+	
+	writel(0x40445323, MMDC_P0_BASE_ADDR + 0x00c);
+	writel(0xb66e8c63, MMDC_P0_BASE_ADDR + 0x010);
+
+	writel(0x01ff00db, MMDC_P0_BASE_ADDR + 0x014);
+	writel(0x00081740, MMDC_P0_BASE_ADDR + 0x018);
+	writel(0x00008000, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x000026d2, MMDC_P0_BASE_ADDR + 0x02c);
+	writel(0x00440e21, MMDC_P0_BASE_ADDR + 0x030);
+	writel(0x00000027, MMDC_P0_BASE_ADDR + 0x040);
+	writel(0xc31a0000, MMDC_P0_BASE_ADDR + 0x000);
+	/* MR2 */
+	writel(0x04008032, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x0400803a, MMDC_P0_BASE_ADDR + 0x01c);
+	/* MR3 */
+	writel(0x00008033, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x0000803b, MMDC_P0_BASE_ADDR + 0x01c);
+	/* MR1 */
+	writel(0x00428031, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x00428039, MMDC_P0_BASE_ADDR + 0x01c);
+	/* MR0 */
+	writel(0x07208030, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x07208038, MMDC_P0_BASE_ADDR + 0x01c);
+	/* ZQ calibration */
+	writel(0x04008040, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x04008040, MMDC_P0_BASE_ADDR + 0x01c);
+	/* final DDR setup */
+	writel(0x00005800, MMDC_P0_BASE_ADDR + 0x020);
+	writel(0x00000007, MMDC_P0_BASE_ADDR + 0x818);
+	writel(0x00000007, MMDC_P1_BASE_ADDR + 0x818);
+	writel(0x0002556d, MMDC_P0_BASE_ADDR + 0x004);
+	writel(0x00011006, MMDC_P1_BASE_ADDR + 0x404);
+	writel(0x00000000, MMDC_P0_BASE_ADDR + 0x01c);
+}
+
+static void spl_dram_init_mx6q_2g(void)
+{
+	/* i.MX6Q */
+	/* DDR IO TYPE */
+	writel(0x000C0000, IOMUXC_BASE_ADDR + 0x798);
+	writel(0x00000000, IOMUXC_BASE_ADDR + 0x758);
+	/* Clock */
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x588);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x594);
+	/* Address */
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x56c);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x578);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x74c);
+	/* Control */
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x57c);
+
+	writel(0x00000000, IOMUXC_BASE_ADDR + 0x58c);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x59c);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x5a0);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x78c);
+	/* Data Strobe */
+	writel(0x00020000, IOMUXC_BASE_ADDR + 0x750);
+
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x5a8);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x5b0);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x524);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x51c);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x518);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x50c);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x5b8);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x5c0);
+	/* Data */
+	writel(0x00020000, IOMUXC_BASE_ADDR + 0x774);
+
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x784);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x788);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x794);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x79c);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x7a0);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x7a4);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x7a8);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x748);
+
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x5ac);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x5b4);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x528);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x520);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x514);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x510);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x5bc);
+	writel(0x00000030, IOMUXC_BASE_ADDR + 0x5c4);
+
+	/* Calibrations */
+	/* ZQ */
+	writel(0xa1390003, MMDC_P0_BASE_ADDR + 0x800);
+	/* write leveling */
+	writel(0x001F001F, MMDC_P0_BASE_ADDR + 0x80c);
+	writel(0x001F001F, MMDC_P0_BASE_ADDR + 0x810);
+	writel(0x001F001F, MMDC_P1_BASE_ADDR + 0x80c);
+	writel(0x001F001F, MMDC_P1_BASE_ADDR + 0x810);
+	/* DQS gating, read delay, write delay calibration values */
+	/* based on calibration compare of 0x00ffff00 */
+	writel(0x4301030D, MMDC_P0_BASE_ADDR + 0x83c);
+	writel(0x03020277, MMDC_P0_BASE_ADDR + 0x840);
+	writel(0x4300030A, MMDC_P1_BASE_ADDR + 0x83c);
+	writel(0x02780248, MMDC_P1_BASE_ADDR + 0x840);
+
+	writel(0x4536393B, MMDC_P0_BASE_ADDR + 0x848);
+	writel(0x36353441, MMDC_P1_BASE_ADDR + 0x848);
+
+	writel(0x41414743, MMDC_P0_BASE_ADDR + 0x850);
+	writel(0x462F453F, MMDC_P1_BASE_ADDR + 0x850);
+
+	writel(0x33333333, MMDC_P0_BASE_ADDR + 0x81c);
+	writel(0x33333333, MMDC_P0_BASE_ADDR + 0x820);
+	writel(0x33333333, MMDC_P0_BASE_ADDR + 0x824);
+	writel(0x33333333, MMDC_P0_BASE_ADDR + 0x828);
+	writel(0x33333333, MMDC_P1_BASE_ADDR + 0x81c);
+	writel(0x33333333, MMDC_P1_BASE_ADDR + 0x820);
+	writel(0x33333333, MMDC_P1_BASE_ADDR + 0x824);
+	writel(0x33333333, MMDC_P1_BASE_ADDR + 0x828);
+
+	writel(0x00000800, MMDC_P0_BASE_ADDR + 0x8b8);
+	writel(0x00000800, MMDC_P1_BASE_ADDR + 0x8b8);
+	/* MMDC init: in DDR3, 64-bit mode, only MMDC0 is initiated: */
+	writel(0x00020036, MMDC_P0_BASE_ADDR + 0x004);
+	writel(0x09444040, MMDC_P0_BASE_ADDR + 0x008);
+	writel(0x555A7975, MMDC_P0_BASE_ADDR + 0x00c);
+	writel(0xFF538F64, MMDC_P0_BASE_ADDR + 0x010);
+	writel(0x01FF00DB, MMDC_P0_BASE_ADDR + 0x014);
+	writel(0x00001740, MMDC_P0_BASE_ADDR + 0x018);
+
+	writel(0x00008000, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x000026D2, MMDC_P0_BASE_ADDR + 0x02c);
+	writel(0x005A1023, MMDC_P0_BASE_ADDR + 0x030);
+
+	/* 2G */
+	writel(0x00000047, MMDC_P0_BASE_ADDR + 0x040);
+	writel(0x841A0000, MMDC_P0_BASE_ADDR + 0x000);
+
+	writel(0x04088032, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x00008033, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x00048031, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x09408030, MMDC_P0_BASE_ADDR + 0x01c);
+	writel(0x04008040, MMDC_P0_BASE_ADDR + 0x01c);
+
+	writel(0x00005800, MMDC_P0_BASE_ADDR + 0x020);
+
+	writel(0x00011117, MMDC_P0_BASE_ADDR + 0x818);
+	writel(0x00011117, MMDC_P1_BASE_ADDR + 0x818);
+
+	writel(0x00025576, MMDC_P0_BASE_ADDR + 0x004);
+	writel(0x00011006, MMDC_P0_BASE_ADDR + 0x404);
+	writel(0x00000000, MMDC_P0_BASE_ADDR + 0x01c);
+}
+
+static void spl_dram_init(void)
+{
+	u32 cpurev, imxtype;
+
+	cpurev = get_cpu_rev();
+	imxtype = (cpurev & 0xFF000) >> 12;
+
+	puts("CPU:   Freescale i.MX");
+	puts(get_imx_type(imxtype));
+	puts("\n");
+
+	switch (imxtype){
+	case MXC_CPU_MX6SOLO:
+		spl_dram_init_mx6solo_512mb();
+		break;
+	case MXC_CPU_MX6Q:
+		spl_dram_init_mx6q_2g();
+		break;
+	case MXC_CPU_MX6DL:
+	default:
+		spl_dram_init_mx6dl_1g();
+		break;
+	}
+}
+
+void spl_board_init(void)
+{
+	spl_dram_init();
+	setup_boot_device();
+}
+
+u32 spl_boot_device(void)
+{
+	puts("Boot Device: ");
+	switch (get_boot_device()) {
+	case SD0_BOOT:
+		printf("SD0\n");
+		return BOOT_DEVICE_MMC1;
+	case SD1_BOOT:
+		printf("SD1\n");
+		return BOOT_DEVICE_MMC2;
+	case MMC_BOOT:
+		printf("MMC\n");
+		return BOOT_DEVICE_MMC2;
+	case NAND_BOOT:
+		printf("NAND\n");
+		return BOOT_DEVICE_NAND;
+	case UNKNOWN_BOOT:
+	default:
+		printf("UNKNOWN\n");
+		return BOOT_DEVICE_NONE;
+	}
+}
+
+u32 spl_boot_mode(void)
+{
+	switch (spl_boot_device()) {
+	case BOOT_DEVICE_MMC1:
+	case BOOT_DEVICE_MMC2:
+	case BOOT_DEVICE_MMC2_2:
+#ifdef CONFIG_SPL_FAT_SUPPORT
+		return MMCSD_MODE_FAT;
+#else
+		return MMCSD_MODE_RAW;
+#endif
+		break;
+        case BOOT_DEVICE_NAND:
+	default:
+		puts("spl: ERROR:  unsupported device\n");
+		hang();
+	}
+}
+
+void reset_cpu(ulong addr)
+{
+
+}
+#endif
diff --git a/board/technexion/edm_cf_imx6/edm_cf_imx6_pins.h b/board/technexion/edm_cf_imx6/edm_cf_imx6_pins.h
new file mode 100644
index 0000000..cba5d1c
--- /dev/null
+++ b/board/technexion/edm_cf_imx6/edm_cf_imx6_pins.h
@@ -0,0 +1,44 @@
+#ifndef _EDM_CF_IMX6_PINS_H
+#define _EDM_CF_IMX6_PINS_H
+
+enum {
+	MX6DL_PAD_CSI0_DAT10__UART1_TXD		= IOMUX_PAD(0x0360, 0x004C, 3, 0x0000, 0, 0),
+	MX6DL_PAD_CSI0_DAT11__UART1_RXD		= IOMUX_PAD(0x0364, 0x0050, 3, 0x08FC, 1, 0),
+
+	MX6Q_PAD_CSI0_DAT10__UART1_TXD		= IOMUX_PAD(0x0650, 0x0280, 3, 0x0000, 0, 0),
+	MX6Q_PAD_CSI0_DAT11__UART1_RXD		= IOMUX_PAD(0x0654, 0x0284, 3, 0x0920, 1, 0),
+
+        MX6DL_PAD_SD1_CLK__USDHC1_CLK		= IOMUX_PAD(0x06C4, 0x02DC, 0, 0x0928, 1, 0),
+	MX6DL_PAD_SD1_CMD__USDHC1_CMD		= IOMUX_PAD(0x06C8, 0x02E0, 0 | IOMUX_CONFIG_SION, 0x0000, 0, 0),
+	MX6DL_PAD_SD1_DAT0__USDHC1_DAT0		= IOMUX_PAD(0x06CC, 0x02E4, 0, 0x0000, 0, 0),
+	MX6DL_PAD_SD1_DAT1__USDHC1_DAT1		= IOMUX_PAD(0x06D0, 0x02E8, 0, 0x0000, 0, 0),
+	MX6DL_PAD_SD1_DAT2__USDHC1_DAT2		= IOMUX_PAD(0x06D4, 0x02EC, 0, 0x0000, 0, 0),
+	MX6DL_PAD_SD1_DAT3__USDHC1_DAT3		= IOMUX_PAD(0x06D8, 0x02F0, 0, 0x0000, 0, 0),
+	MX6DL_PAD_GPIO_2__GPIO_1_2		= IOMUX_PAD(0x05F4, 0x0224, 5, 0x0000, 0, 0),
+
+        MX6Q_PAD_SD1_CLK__USDHC1_CLK		= IOMUX_PAD(0x0738, 0x0350, 0, 0x0000, 0, 0),
+	MX6Q_PAD_SD1_CMD__USDHC1_CMD		= IOMUX_PAD(0x0730, 0x0348, 16, 0x0000, 0, 0),
+	MX6Q_PAD_SD1_DAT0__USDHC1_DAT0		= IOMUX_PAD(0x0728, 0x0340, 0, 0x0000, 0, 0),
+	MX6Q_PAD_SD1_DAT1__USDHC1_DAT1		= IOMUX_PAD(0x0724, 0x033C, 0, 0x0000, 0, 0),
+	MX6Q_PAD_SD1_DAT2__USDHC1_DAT2		= IOMUX_PAD(0x0734, 0x034C, 0, 0x0000, 0, 0),
+	MX6Q_PAD_SD1_DAT3__USDHC1_DAT3		= IOMUX_PAD(0x072C, 0x0344, 0, 0x0000, 0, 0),
+	MX6Q_PAD_GPIO_2__GPIO_1_2		= IOMUX_PAD(0x0604, 0x0234, 5, 0x0000, 0, 0),
+
+        MX6DL_PAD_SD3_CLK__USDHC3_CLK		= IOMUX_PAD(0x06F4, 0x030C, 0, 0x0934, 1, 0),
+	MX6DL_PAD_SD3_CMD__USDHC3_CMD		= IOMUX_PAD(0x06F8, 0x0310, 0 | IOMUX_CONFIG_SION, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_DAT0__USDHC3_DAT0		= IOMUX_PAD(0x06FC, 0x0314, 0, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_DAT1__USDHC3_DAT1		= IOMUX_PAD(0x0700, 0x0318, 0, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_DAT2__USDHC3_DAT2		= IOMUX_PAD(0x0704, 0x031C, 0, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_DAT3__USDHC3_DAT3		= IOMUX_PAD(0x0708, 0x0320, 0, 0x0000, 0, 0),
+	MX6DL_PAD_EIM_DA9__GPIO_3_9		= IOMUX_PAD(0x0590, 0x01C0, 5, 0x0000, 0, 0),
+
+        MX6Q_PAD_SD3_CLK__USDHC3_CLK		= IOMUX_PAD(0x06A4, 0x02BC, 0, 0x0000, 0, 0),
+	MX6Q_PAD_SD3_CMD__USDHC3_CMD		= IOMUX_PAD(0x06A0, 0x02B8, 16, 0x0000, 0, 0),
+	MX6Q_PAD_SD3_DAT0__USDHC3_DAT0		= IOMUX_PAD(0x06A8, 0x02C0, 0, 0x0000, 0, 0),
+	MX6Q_PAD_SD3_DAT1__USDHC3_DAT1		= IOMUX_PAD(0x06AC, 0x02C4, 0, 0x0000, 0, 0),
+	MX6Q_PAD_SD3_DAT2__USDHC3_DAT2		= IOMUX_PAD(0x06B0, 0x02C8, 0, 0x0000, 0, 0),
+	MX6Q_PAD_SD3_DAT3__USDHC3_DAT3		= IOMUX_PAD(0x06B4, 0x02CC, 0, 0x0000, 0, 0),
+	MX6Q_PAD_EIM_DA9__GPIO_3_9		= IOMUX_PAD(0x044C, 0x0138, 5, 0x0000, 0, 0),
+};
+
+#endif /* _EDM_CF_IMX6_PINS_H */
diff --git a/board/technexion/edm_cf_imx6/imximage.cfg b/board/technexion/edm_cf_imx6/imximage.cfg
new file mode 100644
index 0000000..4019d68
--- /dev/null
+++ b/board/technexion/edm_cf_imx6/imximage.cfg
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2013 TechNexion Ltd.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ */
+
+IMAGE_VERSION 2
+
+BOOT_FROM      sd
+
+#define __ASSEMBLY__
+#include <config.h>
+#include "asm/arch/iomux.h"
+#include "asm/arch/crm_regs.h"
+
+#include "clocks.cfg"
diff --git a/boards.cfg b/boards.cfg
index 79d6cd8..b7d66ff 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -288,6 +288,7 @@ nitrogen6s1g                 arm         armv7       nitrogen6x          boundar
 wandboard_dl		     arm	 armv7	     wandboard		 -		mx6 wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL,DDR_MB=1024
 wandboard_quad		     arm	 armv7	     wandboard		 -		mx6 wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6q2g.cfg,MX6Q,DDR_MB=2048
 wandboard_solo		     arm	 armv7	     wandboard		 -		mx6 wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6s.cfg,MX6S,DDR_MB=512
+edm_cf_imx6                  arm         armv7       edm_cf_imx6         technexion     mx6 edm_cf_imx6:IMX_CONFIG=board/technexion/edm_cf_imx6/imximage.cfg,SPL
 omap3_overo                  arm         armv7       overo               -              omap3
 omap3_pandora                arm         armv7       pandora             -              omap3
 dig297                       arm         armv7       dig297              comelit        omap3
diff --git a/include/configs/edm_cf_imx6.h b/include/configs/edm_cf_imx6.h
new file mode 100644
index 0000000..7bfe8e2
--- /dev/null
+++ b/include/configs/edm_cf_imx6.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * Configuration settings for the Wandboard.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <asm/arch/imx-regs.h>
+#include <asm/imx-common/gpio.h>
+#include <asm/sizes.h>
+
+#define CONFIG_MX6
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DISPLAY_BOARDINFO
+
+#define MACH_TYPE_EDM_CF_IMX6		4257
+#define CONFIG_MACH_TYPE		MACH_TYPE_EDM_CF_IMX6
+
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_REVISION_TAG
+
+/* SPL magic */
+#ifdef CONFIG_SPL
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_TEXT_BASE          0x00908400
+#define CONFIG_SPL_PAD_TO 0x400
+#define CONFIG_SPL_START_S_PATH     "arch/arm/cpu/armv7"
+#define CONFIG_SPL_STACK	0x0091FFB8
+
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+
+#define CONFIG_SPL_GPIO_SUPPORT
+#define CONFIG_SPL_MMC_SUPPORT
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR	128 /* offset 64KB */
+#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS	700 /* 350 KB */
+#define CONFIG_SYS_MONITOR_LEN	(CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS*512)
+
+#define CONFIG_SPL_BOARD_INIT
+#define CONFIG_SYS_SPL_MALLOC_START     0x00916000
+#define CONFIG_SYS_SPL_MALLOC_SIZE     0x2000
+#define CONFIG_SYS_TEXT_BASE          0x17800000
+#endif
+
+/* Memory map */
+#define CONFIG_NR_DRAM_BANKS		1
+#define PHYS_SDRAM			MMDC0_ARB_BASE_ADDR
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM
+#define CONFIG_SYS_INIT_RAM_ADDR	IRAM_BASE_ADDR
+/* Set to 64k since we should be able to run on both imx6dl and imx6q */
+#define CONFIG_SYS_INIT_RAM_SIZE	0x10000
+
+#define CONFIG_SYS_INIT_SP_OFFSET \
+	(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR \
+	(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
+
+#define CONFIG_SYS_MEMTEST_START	0x10000000
+#define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_MEMTEST_START + 500 * SZ_1M)
+#define CONFIG_LOADADDR			0x12000000
+#define CONFIG_SYS_TEXT_BASE		0x17800000
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN		(10 * SZ_1M)
+
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_BOARD_LATE_INIT
+
+#define CONFIG_MXC_GPIO
+
+/* debug console */
+#define CONFIG_MXC_UART
+#define CONFIG_MXC_UART_BASE		UART1_BASE
+#define CONFIG_CONS_INDEX		1
+#define CONFIG_BAUDRATE			115200
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+#define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
+
+/* Standard command definition */
+#include <config_cmd_default.h>
+/* ... exclude what's not yet supported */
+#undef CONFIG_CMD_IMLS
+#undef CONFIG_CMD_NFS
+#undef CONFIG_CMD_NET
+
+/* MMC Configuration */
+#define CONFIG_MMC
+#define CONFIG_CMD_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_BOUNCE_BUFFER
+
+#define CONFIG_FSL_ESDHC
+#define CONFIG_FSL_USDHC
+#define CONFIG_SYS_FSL_USDHC_NUM	2
+#define CONFIG_SYS_FSL_ESDHC_ADDR	0
+/* Environment settings */
+#define CONFIG_ENV_SIZE			(8 << 10)
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_ENV_OFFSET		(8 * 64 * 1024)
+#define CONFIG_SYS_NO_FLASH
+/* SPL boot reorders mmc devices so that boot device is 0 -- env is in boot dev */
+#define CONFIG_SYS_MMC_ENV_DEV		0
+
+#define CONFIG_BOOTDELAY		1
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"console=ttymxc0\0" \
+        "bootargs=console=ttymxc0,115200 root=/dev/mmcblk0p1 rootfstype=ext4 rootwait rw video=mxcfb0:dev=hdmi,1920x1080 at 60,if=BGR32\0"
+
+#define CONFIG_BOOTCOMMAND \
+        "mmc dev 0; mmc read $loadaddr 0x800 0x1000; bootm"
+
+/* Miscellaneous configurable options */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT	       "=> "
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_SYS_CBSIZE		384
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS	       32
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+
+#define CONFIG_SYS_LOAD_ADDR		CONFIG_LOADADDR
+#define CONFIG_SYS_HZ			1000
+
+#define CONFIG_CMD_BOOTZ
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+#define CONFIG_CMD_CACHE
+#endif
+
+#endif			       /* __CONFIG_H * */
-- 
1.8.0.3



More information about the U-Boot mailing list