All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM
@ 2013-08-28 11:23 Tapani
  2013-08-28 14:26 ` Eric Bénard
  2013-08-28 16:08 ` Stefano Babic
  0 siblings, 2 replies; 14+ messages in thread
From: Tapani @ 2013-08-28 11:23 UTC (permalink / raw)
  To: u-boot


    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@technexion.com>
    Signed-off-by: Tapani Utriainen <tapani@technexion.com>
    Signed-off-by: Edward Lin <edward.lin@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@boundarydevices.com>
 	nitrogen6s		i.MX6S		512MB
 	nitrogen6s1g		i.MX6S		1GB
 
+Tapani Utriainen <tapani@technexion.com>
+
+	edm_cf_imx6		i.MX6		several configurations
+
 Alison Wang <b18965@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@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

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM
  2013-08-28 11:23 [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM Tapani
@ 2013-08-28 14:26 ` Eric Bénard
  2013-08-30  5:16   ` Tapani Utriainen
  2013-08-28 16:08 ` Stefano Babic
  1 sibling, 1 reply; 14+ messages in thread
From: Eric Bénard @ 2013-08-28 14:26 UTC (permalink / raw)
  To: u-boot

Hi Tapani,

Le Wed, 28 Aug 2013 19:23:33 +0800,
Tapani <tapani@technexion.com> a ?crit :

> 
>     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.
> 
aren't these boards Wandboard without the MicroSD connector but with
either a eMMC or a NAND ?
If yes maybe you could extend wandboard support instead of adding a new
board ?

Best regards,
Eric

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM
  2013-08-28 11:23 [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM Tapani
  2013-08-28 14:26 ` Eric Bénard
@ 2013-08-28 16:08 ` Stefano Babic
  2013-08-30  5:07   ` Tapani Utriainen
  1 sibling, 1 reply; 14+ messages in thread
From: Stefano Babic @ 2013-08-28 16:08 UTC (permalink / raw)
  To: u-boot

Hi Tapani,

On 28/08/2013 13:23, Tapani wrote:
> 
>     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@technexion.com>
>     Signed-off-by: Tapani Utriainen <tapani@technexion.com>
>     Signed-off-by: Edward Lin <edward.lin@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
> 

The patch should be split into separate patches, and each of them fixes
a specific issue. From our previous discussion, we agree about:

- we need to clean up conflicts in pad definitions - see Eric's answer.
- we need a way to simply defines pins for the different SOC variations.
Eric and Troy have already proposed a schema adding tables *only* into
the board file, and the generation of the table is quite automatic.
Let's say, if I am a board maintainer and I want to add support for a
board having all iMX6 variations, I would like to define only once which
pins I need, without replicating for each SOC variant.
- the same should be done with DDR and clocks, if necessary.

After these preparation patches, there should be a patch preparing i.MX6
for SPL - changes in i.MX6 common code should go here.

Last, there will be a patch on top of the rest adding support to your board.

> 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.
> + */

Please change all license text according to the new rule with
SPDX-License-Identifier.

> +
> +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

Maybe you should add some comments explaining that this is your
decision, not due to the SOC. Only the first dd is mandatory by iMX
(offset is 0x400 in flash). For u-boot, you have decided to put it into
raw data exactly after SPL and not into a filesystem.

> +
> +Only raw mmc boot has been verified to work.

The phrase is misleading, and let me think the other ways do not work. I
assume that you tested only raw mmc, so please rephrase to explain this.

> 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.
> + *

Where have you taken the file ? If this comes as it seems from nitrogen,
you cannot drop their copyright.

> 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;
> +}
> +
> 

Let's say: boot device is not board dependent, and the required SPL
function should be moved into general code (imx_common or
arch/arm/cpu/armv7/mx6).

+
> +int dram_init(void)
> +{
> +	uint cpurev, imxtype;
> +	u32 sdram_size;
> +
> +	cpurev = get_cpu_rev();
> +	imxtype = (cpurev & 0xFF000) >> 12;

I am expecting to have a global function getting the cputype, with
macros of the type is_cpu_mx6q() (I see you use it later) to help us the
usage. Not here in board code.

> +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),
> +};

I do not like this solution: this is a bare duplication of the pads, and
it is prone to errors. The definitions of the table must be in some way
automatic. I want to define a pin: if SD1_CLK is used for MMC, this does
not depend from the SOC variant.

What about Troy's solution ?

> +
> +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);
> +}

Let's say : this does not scale well. For each peripheral we have
exactly the same code. The if..then..else should be hidden in some way,
using macros to select the right table.

> +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);
> +			}

As you see, we can have a lot of some code.

> +			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);
> +			}

Again here.

> +
> +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;
> +}

I have not seen CONFIG_VIDEO in your configuration file. Is this dead code ?

> +#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);
> +}

None of this stuff is board specific - we need to factorize this, making
available for all i.MX6 boards. I will say, for i.MX5, too.

> +
> +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);
> +}

Really I do not like this solution. First, you should accessor to set
the iomux, without using base address + offset. And of course, access to
the ram controller should be done in the same way using a C structure,
not offsets.

Then the problem is similar to the pads. I will propose we have a
general function, and the values of board specific parameters (32
against 64 bit size, calibration registers, and so on), and start the
ddr procedure. The functions here do the same on different registers.

> +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;
> +	}
> +}

This is also common code.

> +
> +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)
> +{
> +
> +}

reset_cpu for imx should activate the watchdog, see
drivers/watchdog/imx_watchdog.c

> 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

Why CONFIG_SPL is not set into the configuration file ? Is there a
version without SPL ?

Please maintain the list sorted.

> +++ 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

if MACH_TYPE_EDM_CF_IMX6 is used only here, better:

#define CONFIG_MACH_TYPE		4257

> +
> +#define CONFIG_CMDLINE_TAG
> +#define CONFIG_SETUP_MEMORY_TAGS
> +#define CONFIG_REVISION_TAG
> +
> +/* SPL magic */

Why magic ?

> +#ifdef CONFIG_SPL
> +#define CONFIG_SPL_FRAMEWORK
> +#define CONFIG_SPL_TEXT_BASE          0x00908400

Ok - SPL goes into IRAM, that is good. Can you explain me the value of
the 0x8400 offset ?

> +#define CONFIG_SPL_PAD_TO 0x400
> +#define CONFIG_SPL_START_S_PATH     "arch/arm/cpu/armv7"
> +#define CONFIG_SPL_STACK	0x0091FFB8

Maybe better set it with some size - where is coming this value ?

Best regards,
Stefano Babic

-- 
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM
  2013-08-28 16:08 ` Stefano Babic
@ 2013-08-30  5:07   ` Tapani Utriainen
  2013-08-30 13:52     ` Eric Nelson
  2013-08-30 14:43     ` Stefano Babic
  0 siblings, 2 replies; 14+ messages in thread
From: Tapani Utriainen @ 2013-08-30  5:07 UTC (permalink / raw)
  To: u-boot


Stefano,

Thank you for reviewing this patch, and for the constructive comments. 
Most of your comments are taken on board, and we will re-submit updated patches 
in the near future.

On some things we probably need some clarification, see inlined responses
to some of your questions.

> > ---
> >  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
> > 
> 
> The patch should be split into separate patches, and each of them fixes
> a specific issue. From our previous discussion, we agree about:
> 
> - we need to clean up conflicts in pad definitions - see Eric's answer.
> - we need a way to simply defines pins for the different SOC variations.
> Eric and Troy have already proposed a schema adding tables *only* into
> the board file, and the generation of the table is quite automatic.
> Let's say, if I am a board maintainer and I want to add support for a
> board having all iMX6 variations, I would like to define only once which
> pins I need, without replicating for each SOC variant.
> - the same should be done with DDR and clocks, if necessary.
> 
> After these preparation patches, there should be a patch preparing i.MX6
> for SPL - changes in i.MX6 common code should go here.
> 
> Last, there will be a patch on top of the rest adding support to your board.
>

Understand. However, as far as I can tell Troy's suggestion is still
creating the pad setup compile time for one cpu. 
Is there something obvious we are missing?
 
> 
> Please change all license text according to the new rule with
> SPDX-License-Identifier.
>
Will do.
 
> 
> Maybe you should add some comments explaining that this is your
> decision, not due to the SOC. Only the first dd is mandatory by iMX
> (offset is 0x400 in flash). For u-boot, you have decided to put it into
> raw data exactly after SPL and not into a filesystem.
> 
> > +
> > +Only raw mmc boot has been verified to work.
> 
> The phrase is misleading, and let me think the other ways do not work. I
> assume that you tested only raw mmc, so please rephrase to explain this.
>
Not using a filesystem is by choice. We'll clarify on that 
(or maybe better, enable FAT)

...

> > +
> > +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;
> > +	}
> > +}
> > 
> 
> Let's say: boot device is not board dependent, and the required SPL
> function should be moved into general code (imx_common or
> arch/arm/cpu/armv7/mx6).
> 

Will do. In the first patch attempt we deliberately tried not to touch
common imx6 code.

> +
> > +int dram_init(void)
> > +{
> > +	uint cpurev, imxtype;
> > +	u32 sdram_size;
> > +
> > +	cpurev = get_cpu_rev();
> > +	imxtype = (cpurev & 0xFF000) >> 12;
> 
> I am expecting to have a global function getting the cputype, with
> macros of the type is_cpu_mx6q() (I see you use it later) to help us the
> usage. Not here in board code.
> 

Added.

> > +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),
> > +};
> 
> I do not like this solution: this is a bare duplication of the pads, and
> it is prone to errors. The definitions of the table must be in some way
> automatic. I want to define a pin: if SD1_CLK is used for MMC, this does
> not depend from the SOC variant.
>

TBH, I hate this solution as well. But guess we heard Eric's cries for mercy, 
and did it the way Boundary (and several kernel board files) do it -- rather 
than the way we did it in the Wandboard kernel.

> What about Troy's solution ?
> 
Did not apply? And still had a mess of arrays in the board file. Or what we
have *is* the multi-cpu variant of Troy's approach...?
(With both CPU type macros expanded, manually)

> 
> Let's say : this does not scale well. For each peripheral we have
> exactly the same code. The if..then..else should be hidden in some way,
> using macros to select the right table.
> 
...
> 
> As you see, we can have a lot of some code.
> 
...
> 
> Again here.
>
Beating a dead horse. I happily killed that mess in the WB kernel once already.

> > +
> > +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;
> > +}
> 
> I have not seen CONFIG_VIDEO in your configuration file. Is this dead code ?
>
Yes, we cut away the splash screen support from the submitted patch.
(Our original patch was against another u-boot version, and we tried to cut out 
everything non-essential or thoroughly tested).

Will cut even more :-)
 
> > +#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);
> > +}
> 
> None of this stuff is board specific - we need to factorize this, making
> available for all i.MX6 boards. I will say, for i.MX5, too.
>
Will try.
 
> > +
> > +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 */

[ .... long list of writels ... ]

> > +	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);
> > +}
> 
> Really I do not like this solution. First, you should accessor to set
> the iomux, without using base address + offset. And of course, access to
> the ram controller should be done in the same way using a C structure,
> not offsets.
> 
> Then the problem is similar to the pads. I will propose we have a
> general function, and the values of board specific parameters (32
> against 64 bit size, calibration registers, and so on), and start the
> ddr procedure. The functions here do the same on different registers.
> 

We agree that the does does not look pretty. But there needs to be some 
clarification. 

However, using this has some benefits:
* It is easier to convert from (and compare to) DCD tables 
* Easier to look things up in the TRM (base + offset are easier to find
in a long list of registers sorted by offset, than a name)
* It is a lot of effort to do struct accessors for huge tables. Both
of IOMUX and MMDC are large (offsets of 0x800+). Having struct
accessors would take quite long to enter manually (two tables of 500+ entries 
each, and different between cpu types). This would be hours, if not a day of
braindead work without any tangible benefit.

I could make those tables of { offset, value } and do the writels using
a for-loop, but that would just mariginally improve on the ugliness.

> > +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;
> > +	}
> > +}
> 
> This is also common code.
> 
Yes.

> > +
> > +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)
> > +{
> > +
> > +}
> 
> reset_cpu for imx should activate the watchdog, see
> drivers/watchdog/imx_watchdog.c
>
Ok.
 
> > 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
> 
> Why CONFIG_SPL is not set into the configuration file ? Is there a
> version without SPL ?
> 
There used to be... yes, we'll fix that.

> Please maintain the list sorted.
>
No problem.

... 
> > +
> > +#define MACH_TYPE_EDM_CF_IMX6		4257
> > +#define CONFIG_MACH_TYPE		MACH_TYPE_EDM_CF_IMX6
> 
> if MACH_TYPE_EDM_CF_IMX6 is used only here, better:
> 
> #define CONFIG_MACH_TYPE		4257
>
Yes, guess we tried to mimic wandboard.
 
> > +
> > +#define CONFIG_CMDLINE_TAG
> > +#define CONFIG_SETUP_MEMORY_TAGS
> > +#define CONFIG_REVISION_TAG
> > +

> 
> > +#ifdef CONFIG_SPL
> > +#define CONFIG_SPL_FRAMEWORK
> > +#define CONFIG_SPL_TEXT_BASE          0x00908400
> 
> Ok - SPL goes into IRAM, that is good. Can you explain me the value of
> the 0x8400 offset ?
> 
The available IRAM starts at 907000 and we need space for the IVT tables.

> > +#define CONFIG_SPL_PAD_TO 0x400
> > +#define CONFIG_SPL_START_S_PATH     "arch/arm/cpu/armv7"
> > +#define CONFIG_SPL_STACK	0x0091FFB8
> 
> Maybe better set it with some size - where is coming this value ?
> 

From page 393 in the imx6solo TRM. That is Freescale's recommended initial 
stack top.

regards,

//Tapani

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM
  2013-08-28 14:26 ` Eric Bénard
@ 2013-08-30  5:16   ` Tapani Utriainen
  0 siblings, 0 replies; 14+ messages in thread
From: Tapani Utriainen @ 2013-08-30  5:16 UTC (permalink / raw)
  To: u-boot

Eric,


On Wed, 28 Aug 2013 16:26:44 +0200
Eric B?nard <eric@eukrea.com> wrote:

> Le Wed, 28 Aug 2013 19:23:33 +0800,
> Tapani <tapani@technexion.com> a ?crit :
> 
> > 
> >     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.
> > 
> aren't these boards Wandboard without the MicroSD connector but with
> either a eMMC or a NAND ?

No.

While u-boot level edm-cf-imx6 is compatible with Wandboard, there are differences 
(some different pin definitions, different wifi chips, different board ids, 
different maintainers, ... ). Also there is going to be a edm2-cf-imx6 module, 
which we are hoping to be able to share code with instead.

However if someone wants to play with the SPL boot, a edm-cf-imx6 u-boot should 
work on a Wandboard (after changing machine id).

//Tapani

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM
  2013-08-30  5:07   ` Tapani Utriainen
@ 2013-08-30 13:52     ` Eric Nelson
  2013-08-30 14:43     ` Stefano Babic
  1 sibling, 0 replies; 14+ messages in thread
From: Eric Nelson @ 2013-08-30 13:52 UTC (permalink / raw)
  To: u-boot

Hi Tapani,

On 08/29/2013 10:07 PM, Tapani Utriainen wrote:
>
> Stefano,
>
> Thank you for reviewing this patch, and for the constructive comments.
> Most of your comments are taken on board, and we will re-submit updated patches
> in the near future.
>
> On some things we probably need some clarification, see inlined responses
> to some of your questions.
>
>>  <snip>
>>
>> After these preparation patches, there should be a patch preparing i.MX6
>> for SPL - changes in i.MX6 common code should go here.
>>
>> Last, there will be a patch on top of the rest adding support to your board.
>>
>
> Understand. However, as far as I can tell Troy's suggestion is still
> creating the pad setup compile time for one cpu.
> Is there something obvious we are missing?
>
Troy's patch-set defines some macros, then includes "pads.h" either
once (for single architecture) or twice (for multi-arch images):

	#ifdef CONFIG_MX6Q
	#include "pads.h"
	#endif
	#if defined(CONFIG_MX6DL) || defined(CONFIG_MX6S)
	#define FOR_DL_SOLO
	#include "pads.h"
	#endif

This allows pads.h to define the set of pads once, and build
either one or two sets of tables.

This allows you to define the pads in one place, easing maintenance
but requires the use of formalized naming of tables using
MX6NAME() macro when defining and referencing per-architecture
data.

<snip>

>>> +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),
>>> +};
>>
>> I do not like this solution: this is a bare duplication of the pads, and
>> it is prone to errors. The definitions of the table must be in some way
>> automatic. I want to define a pin: if SD1_CLK is used for MMC, this does
>> not depend from the SOC variant.
>>
>
> TBH, I hate this solution as well. But guess we heard Eric's cries for mercy,
> and did it the way Boundary (and several kernel board files) do it -- rather
> than the way we did it in the Wandboard kernel.
>
>> What about Troy's solution ?
>>
> Did not apply? And still had a mess of arrays in the board file. Or what we
> have *is* the multi-cpu variant of Troy's approach...?
> (With both CPU type macros expanded, manually)
>
Right.

There is no way around having multiple tables. The "Troy" approach
just makes it easier to create and maintain.

>>> +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 */
>
> [ .... long list of writels ... ]
>
>>> +	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);
>>> +}
>>
>> Really I do not like this solution. First, you should accessor to set
>> the iomux, without using base address + offset. And of course, access to
>> the ram controller should be done in the same way using a C structure,
>> not offsets.
>>
>> Then the problem is similar to the pads. I will propose we have a
>> general function, and the values of board specific parameters (32
>> against 64 bit size, calibration registers, and so on), and start the
>> ddr procedure. The functions here do the same on different registers.
>>
>
> We agree that the does does not look pretty. But there needs to be some
> clarification.
>
> However, using this has some benefits:
> * It is easier to convert from (and compare to) DCD tables
> * Easier to look things up in the TRM (base + offset are easier to find
> in a long list of registers sorted by offset, than a name)
> * It is a lot of effort to do struct accessors for huge tables. Both
> of IOMUX and MMDC are large (offsets of 0x800+). Having struct
> accessors would take quite long to enter manually (two tables of 500+ entries
> each, and different between cpu types). This would be hours, if not a day of
> braindead work without any tangible benefit.
>
> I could make those tables of { offset, value } and do the writels using
> a for-loop, but that would just mariginally improve on the ugliness.
>

It seems to me that there should be a way to define the memory
configuration data once and use it both in the imximage file
to produce a DCD for a single-architecture binary or to produce
a table for the multi-arch approach.

If you look at the structure of boundary/nitrogen6q.cfg and
variants, you'll see that we pulled out the common parts (ddr-setup.cfg
and clocks.cfg) and that the memory timings for each configuration
and processor variant are separated into the files

	1066mhz_4x128mx16.cfg
	...
	800mhz_2x256mx16.cfg

With some slight additional macro-fu, we should be able to do
both with the same structure.

Regards,


Eric

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM
  2013-08-30  5:07   ` Tapani Utriainen
  2013-08-30 13:52     ` Eric Nelson
@ 2013-08-30 14:43     ` Stefano Babic
  2013-09-04 11:21       ` Tapani
  1 sibling, 1 reply; 14+ messages in thread
From: Stefano Babic @ 2013-08-30 14:43 UTC (permalink / raw)
  To: u-boot

Hi Tapani,


On 30/08/2013 07:07, Tapani Utriainen wrote:
> 
> Stefano,
> 
> Thank you for reviewing this patch, and for the constructive comments. 
> Most of your comments are taken on board, and we will re-submit updated patches 
> in the near future.
> 
> On some things we probably need some clarification, see inlined responses
> to some of your questions.
> 

I hope I can help you.

>> The patch should be split into separate patches, and each of them fixes
>> a specific issue. From our previous discussion, we agree about:
>>
>> - we need to clean up conflicts in pad definitions - see Eric's answer.
>> - we need a way to simply defines pins for the different SOC variations.
>> Eric and Troy have already proposed a schema adding tables *only* into
>> the board file, and the generation of the table is quite automatic.
>> Let's say, if I am a board maintainer and I want to add support for a
>> board having all iMX6 variations, I would like to define only once which
>> pins I need, without replicating for each SOC variant.
>> - the same should be done with DDR and clocks, if necessary.
>>
>> After these preparation patches, there should be a patch preparing i.MX6
>> for SPL - changes in i.MX6 common code should go here.
>>
>> Last, there will be a patch on top of the rest adding support to your board.
>>
> 
> Understand. However, as far as I can tell Troy's suggestion is still
> creating the pad setup compile time for one cpu. 
> Is there something obvious we are missing?
>  

Ma main concern iy your patchset is that the tables must be maintained
and duplicated in the source code. However, on the board if a pin is
dedicated to a specific function, it will be dedicated for the same
function even with the other variants of the processor.

To beclearer, I take an example from your patch:

+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),
+};


CSI0_DAT10 is the pad and its function is UART, Does it make sense to
set the pin for dual as MX6_PAD_CSI0_DAT10__UART1_TXD  and for dual as
MX6Q_PAD_CSI0_DAT10__GPIO_5_28 ? Surely not, but your approach makes the
tables hard to maintain. What I am complaining is not the creation of
tables, but the cut&paste work in the code that can generate errors. You
can choose of course another solution for the problem, but what I like
to see is some macro(s) that let this job to the compiler and not to the
board maintainer.

>> +
>>> +int dram_init(void)
>>> +{
>>> +	uint cpurev, imxtype;
>>> +	u32 sdram_size;
>>> +
>>> +	cpurev = get_cpu_rev();
>>> +	imxtype = (cpurev & 0xFF000) >> 12;
>>
>> I am expecting to have a global function getting the cputype, with
>> macros of the type is_cpu_mx6q() (I see you use it later) to help us the
>> usage. Not here in board code.
>>
> 
> Added.

Eric sends already a patch:
	http://patchwork.ozlabs.org/patch/270889/

I will apply it, so feel free to use the macros.

> 
>> What about Troy's solution ?
>>
> Did not apply? And still had a mess of arrays in the board file. Or what we
> have *is* the multi-cpu variant of Troy's approach...?
> (With both CPU type macros expanded, manually)

As I said, my concern is not relating to the final result (multiple
array in the board file), but how easy is to maintain the code. I would
like to set a pad only once independently from the choosen SOC.

>> Really I do not like this solution. First, you should accessor to set
>> the iomux, without using base address + offset. And of course, access to
>> the ram controller should be done in the same way using a C structure,
>> not offsets.
>>
>> Then the problem is similar to the pads. I will propose we have a
>> general function, and the values of board specific parameters (32
>> against 64 bit size, calibration registers, and so on), and start the
>> ddr procedure. The functions here do the same on different registers.
>>
> 
> We agree that the does does not look pretty. But there needs to be some 
> clarification. 
> 
> However, using this has some benefits:
> * It is easier to convert from (and compare to) DCD tables 

With the usage of the precompiler, DCD tables in configuration files are
easy to read as your code. Anyway, if a board uses SPL for setup, there
is no need to let the SOC doing that via DCD tables. And if there would
be a need to move to or from DCD, this can be done by some scripts. We
are not constrained to use imximage syntax in a C file.

> * Easier to look things up in the TRM (base + offset are easier to find
> in a long list of registers sorted by offset, than a name)

Really not - which register is written with "writel(0x001F001F,
MMDC_P1_BASE_ADDR + 0x80c)" ? Only the memory map of all SOCs can
answer. It is easy to read in the imximage.cfg file, because this can be
written as "DATA 4, MX6_MMDC_P1_MPWLDECTRL0, 0x001F001F".

Using C structure in u-boot is a strict rule - if you see, all code is
done in this way. No new code is accepted with base + offset syntax.

> * It is a lot of effort to do struct accessors for huge tables. Both
> of IOMUX and MMDC are large (offsets of 0x800+).

You forget that for iomuxc the job was already done - there is structure
and functions to setup the pinmux.

This is really another reason to use structures: if I write something
into pointer->p1_mpwldectrl0, it is clear for everybody which register
is written. This is not true with writel(0x001F001F, MMDC_P1_BASE_ADDR +
0x80c).

> Having struct
> accessors would take quite long to enter manually (two tables of 500+ entries 
> each, and different between cpu types). This would be hours, if not a day of
> braindead work without any tangible benefit.
> 

Sorry, I see benefits in terms of readability and maintenability of the
source code and it makes easier to add new boards. This is the reason
why there are accessors for iomuxc(), as well as for most SOC's internal
controller.

> I could make those tables of { offset, value } and do the writels using
> a for-loop, but that would just mariginally improve on the ugliness.

It is not what I meant - if we see the code, we can recognize the
sequence how the DDR3 must be programmed. We can have a function
realizing the logic (that is, wehich registers in which sequence) must
be written, and taking as arguments the parameters (calibration, and so
on) that for each chip are different. In other words, I would like that
some kind of function will be moved into common code, and not here in
board code.

>>
>> Ok - SPL goes into IRAM, that is good. Can you explain me the value of
>> the 0x8400 offset ?
>>
> The available IRAM starts at 907000 and we need space for the IVT tables.

ok - then please add this explanation as comment.

> 
>>> +#define CONFIG_SPL_PAD_TO 0x400
>>> +#define CONFIG_SPL_START_S_PATH     "arch/arm/cpu/armv7"
>>> +#define CONFIG_SPL_STACK	0x0091FFB8
>>
>> Maybe better set it with some size - where is coming this value ?
>>
> 
> From page 393 in the imx6solo TRM. That is Freescale's recommended initial 
> stack top.

Ditto


Best regards,
Stefano Babic

-- 
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM
  2013-08-30 14:43     ` Stefano Babic
@ 2013-09-04 11:21       ` Tapani
  2013-09-10 14:47         ` Stefano Babic
  0 siblings, 1 reply; 14+ messages in thread
From: Tapani @ 2013-09-04 11:21 UTC (permalink / raw)
  To: u-boot


Stefano,

On Fri, 30 Aug 2013 16:43:28 +0200 Stefano Babic <sbabic@denx.de> wrote:

> Hi Tapani,
> > 
> > On some things we probably need some clarification, see inlined responses
> > to some of your questions.
> > 
> 
> I hope I can help you.
> 

Well, we start to get it. Correct us if we are wrong.

> 
> Ma main concern iy your patchset is that the tables must be maintained
> and duplicated in the source code. However, on the board if a pin is
> dedicated to a specific function, it will be dedicated for the same
> function even with the other variants of the processor.
> 

We agree fully. Again, no need to beat a dead horse. :-)

The reason our patch used duplicate tables was because of the way our original
idea was received on the u-boot mailing list. It had the definitions just once.

> Using C structure in u-boot is a strict rule - if you see, all code is
> done in this way. No new code is accepted with base + offset syntax.
> 

Are the strict rules written down somewhere, so people less involved in
u-boot development can read them before submitting?

We both know it is not valid C to use structs the way you want us to. 
It is a quirk of the compiler that it works at all. The coding standard 
for u-boot sounds to be very picky to adhere to the C standard.

Afair, Microsoft shot themselves in the foot badly assuming structs could be 
used this way in early versions of MS Office. (Wrote structs to files, but 
new versions could not load since the memory layout was different).

Sure, we might do it for the mmdc. But long term maintainable, it is not.

> > * It is a lot of effort to do struct accessors for huge tables. Both
> > of IOMUX and MMDC are large (offsets of 0x800+).
> 
> You forget that for iomuxc the job was already done - there is structure
> and functions to setup the pinmux.
> 

You would not accept code using the current iomux structure...

> > Having struct
> > accessors would take quite long to enter manually (two tables of 500+ entries 
> > each, and different between cpu types). This would be hours, if not a day of
> > braindead work without any tangible benefit.
> > 
> 
> Sorry, I see benefits in terms of readability and maintenability of the
> source code and it makes easier to add new boards. This is the reason
> why there are accessors for iomuxc(), as well as for most SOC's internal
> controller.
> 

If making the addition of new boards easier is a goal, there are other parts 
of the process that are currently a greater hurdle than writing the code. :-)

> > I could make those tables of { offset, value } and do the writels using
> > a for-loop, but that would just mariginally improve on the ugliness.
> 
> It is not what I meant - if we see the code, we can recognize the
> sequence how the DDR3 must be programmed. We can have a function
> realizing the logic (that is, wehich registers in which sequence) must
> be written, and taking as arguments the parameters (calibration, and so
> on) that for each chip are different. In other words, I would like that
> some kind of function will be moved into common code, and not here in
> board code.
>

To summarize, we are expected to:
(i) Create a more general DDR3 API for IMX6, to setup memory chips on any board?
(ii) Use the above API to redo our already working DDR setup for our board.
(iii) Rewrite the iomux struct(s) to more accurately reflect the iomux memory space. 
There is more than plain pinmuxing there. 
(iv) Rewrite any code that gets broken from changing the iomux struct(s)
(v) Use the new struct(s) in setting up memory for our board

Some of the above might need to be done differently for different cpu variants.

We are worried that we might not familiar enough with u-boot development to get 
such changes accepted in reasonable time.

Did we understand this correctly? 

regards,

Tapani

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM
  2013-09-04 11:21       ` Tapani
@ 2013-09-10 14:47         ` Stefano Babic
  2013-11-04 17:28           ` Fabio Estevam
  0 siblings, 1 reply; 14+ messages in thread
From: Stefano Babic @ 2013-09-10 14:47 UTC (permalink / raw)
  To: u-boot

Hi Tapani,

On 04/09/2013 13:21, Tapani wrote:

> 
> Are the strict rules written down somewhere, so people less involved in
> u-boot development can read them before submitting?
> 

As far as I know, there is not such documentation ;-(

> 
> Sure, we might do it for the mmdc. But long term maintainable, it is not.
> 
>>> * It is a lot of effort to do struct accessors for huge tables. Both
>>> of IOMUX and MMDC are large (offsets of 0x800+).
>>
>> You forget that for iomuxc the job was already done - there is structure
>> and functions to setup the pinmux.
>>
> 
> You would not accept code using the current iomux structure...

I do not get what you are meaning. Supported boards are using iomux
structures and utility functions to set up the pinmux.

> 
>>> Having struct
>>> accessors would take quite long to enter manually (two tables of 500+ entries 
>>> each, and different between cpu types). This would be hours, if not a day of
>>> braindead work without any tangible benefit.
>>>
>>
>> Sorry, I see benefits in terms of readability and maintenability of the
>> source code and it makes easier to add new boards. This is the reason
>> why there are accessors for iomuxc(), as well as for most SOC's internal
>> controller.
>>
> 
> If making the addition of new boards easier is a goal, there are other parts 
> of the process that are currently a greater hurdle than writing the code. :-)

Well, of course it is an iterative process. We are trying to make
everything better ;-)

> 
> To summarize, we are expected to:
> (i) Create a more general DDR3 API for IMX6, to setup memory chips on any board?

Yes - as the setup of the DDR controller is moving from DCD to code, I
am expecting to reuse that code.

> (ii) Use the above API to redo our already working DDR setup for our board.

Agree.

> (iii) Rewrite the iomux struct(s) to more accurately reflect the iomux memory space. 

Not sure what you are meaning here. If mean what we have discuss before,
that is a way to declare a set of pins independently from the processor
generating then the required setup / tables, yes.

> There is more than plain pinmuxing there. 
> (iv) Rewrite any code that gets broken from changing the iomux struct(s)

Right. If something is changed that breaks boads, we should adapt the
broken boards.

> (v) Use the new struct(s) in setting up memory for our board
> 
> Some of the above might need to be done differently for different cpu variants.

Let's see - we will have to check the single detail.

> 
> We are worried that we might not familiar enough with u-boot development to get 
> such changes accepted in reasonable time.

I do not know what you mean for a reasonable time. Merge window is
closed, that is patchsets adding new features will not be merged in the
next release 2013.10. The next release should be 2013.01, and there are
chances to get them merged.

Best regards,
Stefano

-- 
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM
  2013-09-10 14:47         ` Stefano Babic
@ 2013-11-04 17:28           ` Fabio Estevam
  2013-11-04 17:37             ` Eric Nelson
  2013-11-05 15:12             ` Tapani
  0 siblings, 2 replies; 14+ messages in thread
From: Fabio Estevam @ 2013-11-04 17:28 UTC (permalink / raw)
  To: u-boot

Hi Tapani,

On Tue, Sep 10, 2013 at 11:47 AM, Stefano Babic <sbabic@denx.de> wrote:
>> We are worried that we might not familiar enough with u-boot development to get
>> such changes accepted in reasonable time.
>
> I do not know what you mean for a reasonable time. Merge window is
> closed, that is patchsets adding new features will not be merged in the
> next release 2013.10. The next release should be 2013.01, and there are
> chances to get them merged.

Do you plan to send a new version of the patch that adds support for
booting a single binary on the mx6q/dl/solo?

Regards,

Fabio Estevam

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM
  2013-11-04 17:28           ` Fabio Estevam
@ 2013-11-04 17:37             ` Eric Nelson
  2013-11-04 17:39               ` Otavio Salvador
  2013-11-04 17:50               ` Stefano Babic
  2013-11-05 15:12             ` Tapani
  1 sibling, 2 replies; 14+ messages in thread
From: Eric Nelson @ 2013-11-04 17:37 UTC (permalink / raw)
  To: u-boot

On 11/04/2013 10:28 AM, Fabio Estevam wrote:
> Hi Tapani,
>
> On Tue, Sep 10, 2013 at 11:47 AM, Stefano Babic <sbabic@denx.de> wrote:
>>> We are worried that we might not familiar enough with u-boot development to get
>>> such changes accepted in reasonable time.
>>
>> I do not know what you mean for a reasonable time. Merge window is
>> closed, that is patchsets adding new features will not be merged in the
>> next release 2013.10. The next release should be 2013.01, and there are
>> chances to get them merged.
>
> Do you plan to send a new version of the patch that adds support for
> booting a single binary on the mx6q/dl/solo?
>

BTW, I have updated patches to consolidate the IOMUX registers, and
they include updates to board/freescale/titanium.

Should I re-base them on top of the patches which move titanium into
board/barco?

It seems that this change is likely to be applied once Stefano waits
the requisite 48 hours...

Please advise,


Eric

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM
  2013-11-04 17:37             ` Eric Nelson
@ 2013-11-04 17:39               ` Otavio Salvador
  2013-11-04 17:50               ` Stefano Babic
  1 sibling, 0 replies; 14+ messages in thread
From: Otavio Salvador @ 2013-11-04 17:39 UTC (permalink / raw)
  To: u-boot

On Mon, Nov 4, 2013 at 3:37 PM, Eric Nelson
<eric.nelson@boundarydevices.com> wrote:
> On 11/04/2013 10:28 AM, Fabio Estevam wrote:
>>
>> Hi Tapani,
>>
>> On Tue, Sep 10, 2013 at 11:47 AM, Stefano Babic <sbabic@denx.de> wrote:
>>>>
>>>> We are worried that we might not familiar enough with u-boot development
>>>> to get
>>>> such changes accepted in reasonable time.
>>>
>>>
>>> I do not know what you mean for a reasonable time. Merge window is
>>> closed, that is patchsets adding new features will not be merged in the
>>> next release 2013.10. The next release should be 2013.01, and there are
>>> chances to get them merged.
>>
>>
>> Do you plan to send a new version of the patch that adds support for
>> booting a single binary on the mx6q/dl/solo?
>>
>
> BTW, I have updated patches to consolidate the IOMUX registers, and
> they include updates to board/freescale/titanium.
>
> Should I re-base them on top of the patches which move titanium into
> board/barco?

It makes sense to base on this patch, for sure.

-- 
Otavio Salvador                             O.S. Systems
http://www.ossystems.com.br        http://code.ossystems.com.br
Mobile: +55 (53) 9981-7854            Mobile: +1 (347) 903-9750

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM
  2013-11-04 17:37             ` Eric Nelson
  2013-11-04 17:39               ` Otavio Salvador
@ 2013-11-04 17:50               ` Stefano Babic
  1 sibling, 0 replies; 14+ messages in thread
From: Stefano Babic @ 2013-11-04 17:50 UTC (permalink / raw)
  To: u-boot

Hi Eric,

On 04/11/2013 18:37, Eric Nelson wrote:
> On 11/04/2013 10:28 AM, Fabio Estevam wrote:
>> Hi Tapani,
>>
>> On Tue, Sep 10, 2013 at 11:47 AM, Stefano Babic <sbabic@denx.de> wrote:
>>>> We are worried that we might not familiar enough with u-boot
>>>> development to get
>>>> such changes accepted in reasonable time.
>>>
>>> I do not know what you mean for a reasonable time. Merge window is
>>> closed, that is patchsets adding new features will not be merged in the
>>> next release 2013.10. The next release should be 2013.01, and there are
>>> chances to get them merged.
>>
>> Do you plan to send a new version of the patch that adds support for
>> booting a single binary on the mx6q/dl/solo?
>>
> 
> BTW, I have updated patches to consolidate the IOMUX registers, and
> they include updates to board/freescale/titanium.
> 
> Should I re-base them on top of the patches which move titanium into
> board/barco?
> 

Yes, please do it ! I think your patches will be the base for the other
ones, and I would like we can merge your efforts soon..

> It seems that this change is likely to be applied once Stefano waits
> the requisite 48 hours...

;-D

Regards,
Stefano

-- 
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM
  2013-11-04 17:28           ` Fabio Estevam
  2013-11-04 17:37             ` Eric Nelson
@ 2013-11-05 15:12             ` Tapani
  1 sibling, 0 replies; 14+ messages in thread
From: Tapani @ 2013-11-05 15:12 UTC (permalink / raw)
  To: u-boot

On Mon, 4 Nov 2013 15:28:39 -0200
Fabio Estevam <festevam@gmail.com> wrote:

> Hi Tapani,
> 
> On Tue, Sep 10, 2013 at 11:47 AM, Stefano Babic <sbabic@denx.de> wrote:
> >> We are worried that we might not familiar enough with u-boot development to get
> >> such changes accepted in reasonable time.
> >
> > I do not know what you mean for a reasonable time. Merge window is
> > closed, that is patchsets adding new features will not be merged in the
> > next release 2013.10. The next release should be 2013.01, and there are
> > chances to get them merged.
> 
> Do you plan to send a new version of the patch that adds support for
> booting a single binary on the mx6q/dl/solo?
> 
> Regards,
> 
> Fabio Estevam

Fabio (and others),

mainlining SPL boot for edm-cf-imx6 is on hold until more of the required
framework in u-boot is in place.

//Tapani

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2013-11-05 15:12 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-28 11:23 [U-Boot] [PATCH] Add support for TechNexion edm1-cf-imx6 SoM Tapani
2013-08-28 14:26 ` Eric Bénard
2013-08-30  5:16   ` Tapani Utriainen
2013-08-28 16:08 ` Stefano Babic
2013-08-30  5:07   ` Tapani Utriainen
2013-08-30 13:52     ` Eric Nelson
2013-08-30 14:43     ` Stefano Babic
2013-09-04 11:21       ` Tapani
2013-09-10 14:47         ` Stefano Babic
2013-11-04 17:28           ` Fabio Estevam
2013-11-04 17:37             ` Eric Nelson
2013-11-04 17:39               ` Otavio Salvador
2013-11-04 17:50               ` Stefano Babic
2013-11-05 15:12             ` Tapani

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.