[U-Boot] [PATCH v2] imx: mx6var_som: Add support for Variscite mx6 boards

Eran Matityahu eran.m at variscite.com
Tue May 31 17:14:20 CEST 2016


Add support for Variscite VAR-SOM-MX6 / VAR-SOM-SOLO/DUAL / DART-MX6 boards with features:
PMIC, NAND flash, SD/MMC, USB, Ethernet, I2C, LVDS, HDMI.

Signed-off-by: Eran Matityahu <eran.m at variscite.com>
Cc: Stefano Babic <sbabic at denx.de>
---
Note:
This patch depends on two other patches I've submitted that were not yet reviewed:
  https://patchwork.ozlabs.org/patch/614924/  or 
  http://lists.denx.de/pipermail/u-boot/2016-April/252840.html

  https://patchwork.ozlabs.org/patch/627880/  or
  http://lists.denx.de/pipermail/u-boot/2016-May/256341.html

Changes for v2:
	- Many changes, code reorganization & cleanups and minor bug fixes
	- On DART board mmc0 is now always SD and mmc1 is eMMC,
	  regardless of the current boot device
	- Move all previous automatic env settings from the code to
	  env scripts, and also add some new ones, with options to
	  enable/disable each one individually from the env
	- Add audiocodec_reset to SPL to fix a bug in "L" SOM variants (Low power)
	- Change kernel device tree file names for Variscite's 4.1.15 kernel
	- Change mmcblk device numbers for Variscite's 4.1.15 kernel
	- Changed a lot of things following Stefano's comments:
	  Some things were fixed and some were made more clear.

Some explanations:
	- This single U-Boot supports 3 different carrier boards:
	  VAR-MX6CustomBoard, VAR-SOLOCustomBoard and VAR-DT6CustomBoard,
	  and 3 different SOM types: VAR-SOM-MX6, VAR-SOM-SOLO/DUAL and DART-MX6
	  (DART-MX6 goes with VAR-DT6CustomBoard, and the others can be mixed).
	  Each SOM type can come in various configurations (can be with
	  different CPU types and frequencies, can be with or without eMMC,
	  can be with different types and capacities of NAND, RAM, etc.)
	- About the EEPROM code:
	  Since each SOM can come with a different RAM type and capacity, we use
	  an EPPROM to keep the configuration of the specific RAM on the SOM.
	  This code is based on an old U-Boot Variscite was managing internally
	  before my time in the company.
	  I've changed and simplified a lot of the code, but I cannot change
	  the data on the EEPROM completely, since these SOMs are already in
	  the market for a few years now.

 arch/arm/cpu/armv7/mx6/Kconfig                |    7 +
 board/variscite/mx6var_som/Kconfig            |   12 +
 board/variscite/mx6var_som/MAINTAINERS        |    7 +
 board/variscite/mx6var_som/Makefile           |    9 +
 board/variscite/mx6var_som/addresses.inc      |   38 +
 board/variscite/mx6var_som/mx6var_eeprom.h    |   16 +
 board/variscite/mx6var_som/mx6var_eeprom_v1.c |  244 +++++
 board/variscite/mx6var_som/mx6var_eeprom_v1.h |   66 ++
 board/variscite/mx6var_som/mx6var_eeprom_v2.c |  238 ++++
 board/variscite/mx6var_som/mx6var_eeprom_v2.h |   57 +
 board/variscite/mx6var_som/mx6var_som.c       | 1444 +++++++++++++++++++++++++
 board/variscite/mx6var_som/values.inc         |   39 +
 configs/mx6var_som_nand_defconfig             |   31 +
 configs/mx6var_som_sd_defconfig               |   31 +
 include/configs/mx6var_som.h                  |  429 ++++++++
 tools/logos/variscite.bmp                     |  Bin 0 -> 15414 bytes
 16 files changed, 2668 insertions(+)
 create mode 100644 board/variscite/mx6var_som/Kconfig
 create mode 100644 board/variscite/mx6var_som/MAINTAINERS
 create mode 100644 board/variscite/mx6var_som/Makefile
 create mode 100644 board/variscite/mx6var_som/addresses.inc
 create mode 100644 board/variscite/mx6var_som/mx6var_eeprom.h
 create mode 100644 board/variscite/mx6var_som/mx6var_eeprom_v1.c
 create mode 100644 board/variscite/mx6var_som/mx6var_eeprom_v1.h
 create mode 100644 board/variscite/mx6var_som/mx6var_eeprom_v2.c
 create mode 100644 board/variscite/mx6var_som/mx6var_eeprom_v2.h
 create mode 100644 board/variscite/mx6var_som/mx6var_som.c
 create mode 100644 board/variscite/mx6var_som/values.inc
 create mode 100644 configs/mx6var_som_nand_defconfig
 create mode 100644 configs/mx6var_som_sd_defconfig
 create mode 100644 include/configs/mx6var_som.h
 create mode 100644 tools/logos/variscite.bmp

diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig
index 663f970..738c2ea 100644
--- a/arch/arm/cpu/armv7/mx6/Kconfig
+++ b/arch/arm/cpu/armv7/mx6/Kconfig
@@ -129,6 +129,12 @@ config TARGET_MX6UL_14X14_EVK
 	select DM_THERMAL
 	select SUPPORT_SPL
 
+config TARGET_MX6VAR_SOM
+	bool "mx6var_som"
+	select SUPPORT_SPL
+	select DM
+	select DM_THERMAL
+
 config TARGET_NITROGEN6X
 	bool "nitrogen6x"
 
@@ -208,6 +214,7 @@ source "board/technexion/pico-imx6ul/Kconfig"
 source "board/tbs/tbs2910/Kconfig"
 source "board/tqc/tqma6/Kconfig"
 source "board/udoo/Kconfig"
+source "board/variscite/mx6var_som/Kconfig"
 source "board/wandboard/Kconfig"
 source "board/warp/Kconfig"
 
diff --git a/board/variscite/mx6var_som/Kconfig b/board/variscite/mx6var_som/Kconfig
new file mode 100644
index 0000000..0b82df7
--- /dev/null
+++ b/board/variscite/mx6var_som/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_MX6VAR_SOM
+
+config SYS_BOARD
+	default "mx6var_som"
+
+config SYS_VENDOR
+	default "variscite"
+
+config SYS_CONFIG_NAME
+	default "mx6var_som"
+
+endif
diff --git a/board/variscite/mx6var_som/MAINTAINERS b/board/variscite/mx6var_som/MAINTAINERS
new file mode 100644
index 0000000..a9367f0
--- /dev/null
+++ b/board/variscite/mx6var_som/MAINTAINERS
@@ -0,0 +1,7 @@
+MX6VAR_SOM BOARD
+M:	Eran Matityahu <eran.m at variscite.com>
+S:	Maintained
+F:	board/variscite/mx6var_som/
+F:	include/configs/mx6var_som.h
+F:	configs/mx6var_som_nand_defconfig
+F:	configs/mx6var_som_sd_defconfig
diff --git a/board/variscite/mx6var_som/Makefile b/board/variscite/mx6var_som/Makefile
new file mode 100644
index 0000000..818d6c6
--- /dev/null
+++ b/board/variscite/mx6var_som/Makefile
@@ -0,0 +1,9 @@
+#
+# Copyright (C) 2007, Guennadi Liakhovetski <lg at denx.de>
+#
+# (C) Copyright 2011 Freescale Semiconductor, Inc.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y := mx6var_som.o mx6var_eeprom_v1.o mx6var_eeprom_v2.o
diff --git a/board/variscite/mx6var_som/addresses.inc b/board/variscite/mx6var_som/addresses.inc
new file mode 100644
index 0000000..3aaea54
--- /dev/null
+++ b/board/variscite/mx6var_som/addresses.inc
@@ -0,0 +1,38 @@
+0x00000000, 0x020C4068, 0x020C406C, 0x020C4070,
+0x020C4074, 0x020C4078, 0x020C407C, 0x020C4080,
+0x020C4084, 0x020E0464, 0x020E0470, 0x020E0474,
+0x020E0478, 0x020E047C, 0x020E0480, 0x020E0484,
+0x020E0488, 0x020E048C, 0x020E0490, 0x020E0494,
+0x020E04A0, 0x020E04AC, 0x020E04B0, 0x020E04B4,
+0x020E04B8, 0x020E04BC, 0x020E04C0, 0x020E04C4,
+0x020E04C8, 0x020E04CC, 0x020E04D0, 0x020E04D4,
+0x020E04D8, 0x020E050C, 0x020E0510, 0x020E0514,
+0x020E0518, 0x020E051C, 0x020E0520, 0x020E0524,
+0x020E0528, 0x020E056C, 0x020E0578, 0x020E057C,
+0x020E0588, 0x020E058C, 0x020E0594, 0x020E059C,
+0x020E05A0, 0x020E05A8, 0x020E05AC, 0x020E05B0,
+0x020E05B4, 0x020E05B8, 0x020E05BC, 0x020E05C0,
+0x020E05C4, 0x020E0748, 0x020E074C, 0x020E0750,
+0x020E0754, 0x020E0758, 0x020E0760, 0x020E0764,
+0x020E076C, 0x020E0770, 0x020E0774, 0x020E0778,
+0x020E077C, 0x020E0780, 0x020E0784, 0x020E0788,
+0x020E078C, 0x020E0794, 0x020E0798, 0x020E079C,
+0x020E07A0, 0x020E07A4, 0x020E07A8, 0x021B0000,
+0x021B0004, 0x021B0008, 0x021B000C, 0x021B0010,
+0x021B0014, 0x021B0018, 0x021B001C, 0x021B0020,
+0x021B002C, 0x021B0030, 0x021B0038, 0x021B0040,
+0x021B0400, 0x021B0404, 0x021B0800, 0x021B080C,
+0x021B0810, 0x021B0818, 0x021B081C, 0x021B0820,
+0x021B0824, 0x021B0828, 0x021B082C, 0x021B0830,
+0x021B0834, 0x021B0838, 0x021B083C, 0x021B0840,
+0x021B0848, 0x021B0850, 0x021B085C, 0x021B0890,
+0x021B08B8, 0x021B08C0, 0x021B4000, 0x021B4004,
+0x021B4008, 0x021B400C, 0x021B4010, 0x021B4014,
+0x021B4018, 0x021B401C, 0x021B4020, 0x021B402C,
+0x021B4030, 0x021B4038, 0x021B4040, 0x021B4400,
+0x021B4404, 0x021B4800, 0x021B480C, 0x021B4810,
+0x021B4818, 0x021B481C, 0x021B4820, 0x021B4824,
+0x021B4828, 0x021B482C, 0x021B4830, 0x021B4834,
+0x021B4838, 0x021B483C, 0x021B4840, 0x021B4848,
+0x021B4850, 0x021B485C, 0x021B4890, 0x021B48B8,
+0x021B48BC, 0x021B48C0
diff --git a/board/variscite/mx6var_som/mx6var_eeprom.h b/board/variscite/mx6var_som/mx6var_eeprom.h
new file mode 100644
index 0000000..ae67a78
--- /dev/null
+++ b/board/variscite/mx6var_som/mx6var_eeprom.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _MX6VAR_EEPROM_H_
+#define _MX6VAR_EEPROM_H_
+
+u32 var_eeprom_v1_get_ram_size(void);
+int var_eeprom_v1_dram_init(void);
+
+u32 var_eeprom_v2_get_ram_size(void);
+int var_eeprom_v2_dram_init(void);
+
+#endif /* _MX6VAR_EEPROM_H_ */
diff --git a/board/variscite/mx6var_som/mx6var_eeprom_v1.c b/board/variscite/mx6var_som/mx6var_eeprom_v1.c
new file mode 100644
index 0000000..fcf97e7
--- /dev/null
+++ b/board/variscite/mx6var_som/mx6var_eeprom_v1.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
+ *
+ * Setup DRAM parametes and calibration values
+ * for the specific DRAM on the board.
+ * The parameters were provided by
+ * i.MX6 DDR Stress Test Tool and saved on EEPROM.
+ *
+ * For non-DART boards
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include "mx6var_eeprom_v1.h"
+
+static inline bool var_eeprom_v1_is_valid(const struct var_eeprom_v1_cfg *p_var_eeprom_v1_cfg)
+{
+	return (VARISCITE_MAGIC == p_var_eeprom_v1_cfg->header.variscite_magic);
+}
+
+static int var_eeprom_v1_read_struct(struct var_eeprom_v1_cfg *p_var_eeprom_v1_cfg)
+{
+	i2c_set_bus_num(VAR_EEPROM_I2C_BUS);
+	if (i2c_probe(VAR_EEPROM_I2C_ADDR)) {
+		printf("\nError: couldn't find EEPROM device\n");
+		return -1;
+	}
+
+	if (i2c_read(VAR_EEPROM_I2C_ADDR, 0, 1,
+				(u8 *)p_var_eeprom_v1_cfg,
+				sizeof(struct var_eeprom_v1_cfg))) {
+		printf("\nError reading data from EEPROM\n");
+		return -1;
+	}
+
+	if (!var_eeprom_v1_is_valid(p_var_eeprom_v1_cfg)) {
+		printf("\nError: Data on EEPROM is invalid\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Returns DRAM size in MiB
+ */
+u32 var_eeprom_v1_get_ram_size(void)
+{
+	struct var_eeprom_v1_cfg var_eeprom_v1_cfg = {{0}};
+
+	if (var_eeprom_v1_read_struct(&var_eeprom_v1_cfg))
+		return -1;
+
+	return var_eeprom_v1_cfg.header.dram_size;
+}
+
+#ifdef CONFIG_SPL_BUILD
+#include <asm/arch/mx6-ddr.h>
+#include <asm/arch/sys_proto.h>
+
+static void var_eeprom_v1_mx6sdl_dram_setup_iomux(const struct var_pinmux_group_regs *pinmux_group)
+{
+	const struct mx6sdl_iomux_ddr_regs mx6_ddr_ioregs = {
+		.dram_sdclk_0	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_sdclk_1	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_cas	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_ras	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_reset	= pinmux_group->dram_reset,
+		.dram_sdcke0	= pinmux_group->dram_sdcke0,
+		.dram_sdcke1	= pinmux_group->dram_sdcke1,
+		.dram_sdba2	= pinmux_group->IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2,
+		.dram_sdodt0	= pinmux_group->dram_sdodt0,
+		.dram_sdodt1	= pinmux_group->dram_sdodt1,
+		.dram_sdqs0	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_sdqs1	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_sdqs2	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_sdqs3	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_sdqs4	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_sdqs5	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_sdqs6	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_sdqs7	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_dqm0	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_dqm1	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_dqm2	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_dqm3	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_dqm4	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_dqm5	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_dqm6	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_dqm7	= pinmux_group->pinmux_ctrlpad_all_value,
+	};
+
+	const struct mx6sdl_iomux_grp_regs mx6_grp_ioregs = {
+		.grp_ddr_type		= pinmux_group->IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE,
+		.grp_ddrpke		= pinmux_group->IOMUXC_SW_PAD_CTL_GRP_DDRPKE,
+		.grp_addds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_ctlds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_ddrmode_ctl	= pinmux_group->IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL,
+		.grp_ddrmode		= pinmux_group->IOMUXC_SW_PAD_CTL_GRP_DDRMODE,
+		.grp_b0ds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_b1ds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_b2ds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_b3ds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_b4ds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_b5ds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_b6ds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_b7ds		= pinmux_group->pinmux_ctrlpad_all_value,
+	};
+
+	mx6sdl_dram_iocfg(64, &mx6_ddr_ioregs, &mx6_grp_ioregs);
+}
+
+static void var_eeprom_v1_mx6dq_dram_setup_iomux(const struct var_pinmux_group_regs *pinmux_group)
+{
+	const struct mx6dq_iomux_ddr_regs mx6_ddr_ioregs = {
+		.dram_sdclk_0	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_sdclk_1	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_cas	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_ras	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_reset	= pinmux_group->dram_reset,
+		.dram_sdcke0	= pinmux_group->dram_sdcke0,
+		.dram_sdcke1	= pinmux_group->dram_sdcke1,
+		.dram_sdba2	= pinmux_group->IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2,
+		.dram_sdodt0	= pinmux_group->dram_sdodt0,
+		.dram_sdodt1	= pinmux_group->dram_sdodt1,
+		.dram_sdqs0	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_sdqs1	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_sdqs2	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_sdqs3	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_sdqs4	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_sdqs5	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_sdqs6	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_sdqs7	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_dqm0	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_dqm1	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_dqm2	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_dqm3	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_dqm4	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_dqm5	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_dqm6	= pinmux_group->pinmux_ctrlpad_all_value,
+		.dram_dqm7	= pinmux_group->pinmux_ctrlpad_all_value,
+	};
+
+	const struct mx6dq_iomux_grp_regs mx6_grp_ioregs = {
+		.grp_ddr_type		= pinmux_group->IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE,
+		.grp_ddrpke		= pinmux_group->IOMUXC_SW_PAD_CTL_GRP_DDRPKE,
+		.grp_addds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_ctlds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_ddrmode_ctl	= pinmux_group->IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL,
+		.grp_ddrmode		= pinmux_group->IOMUXC_SW_PAD_CTL_GRP_DDRMODE,
+		.grp_b0ds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_b1ds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_b2ds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_b3ds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_b4ds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_b5ds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_b6ds		= pinmux_group->pinmux_ctrlpad_all_value,
+		.grp_b7ds		= pinmux_group->pinmux_ctrlpad_all_value,
+	};
+
+	mx6dq_dram_iocfg(64, &mx6_ddr_ioregs, &mx6_grp_ioregs);
+}
+
+static void var_eeprom_v1_handle_write_opcodes(const struct reg_write_opcode write_opcodes[])
+{
+	volatile struct mmdc_p_regs *mmdc_p0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
+	u32 opcode, address, value, i = 0;
+	volatile u32 *reg_ptr;
+
+	/* Go through all register initializations and apply to correct registers */
+	while (i < VAR_EEPROM_MAX_NUM_OF_OPCODES) {
+		address = write_opcodes[i].address;
+		if (address == 0)
+			break;
+		reg_ptr = (u32 *)address;
+		value = write_opcodes[i].value;
+
+		opcode = address & 0xF0000000;
+		switch (opcode) {
+		case VAR_DDR_INIT_OPCODE_WRITE_VAL_TO_ADDRESS:
+			/* ZQ calibration? ==> Need to wait? */
+			if ((address == mmdc_p0->mpzqhwctrl) && (value & 0x3))
+				while (mmdc_p0->mpzqhwctrl & 0x00010000);
+			else
+				/* write value to reg */
+				*reg_ptr = value;
+			break;
+		case VAR_DDR_INIT_OPCODE_WAIT_MASK_RISING:
+			while ((value & (*reg_ptr)) != value);
+			break;
+		case VAR_DDR_INIT_OPCODE_WAIT_MASK_FALLING:
+			while ((value & ~(*reg_ptr)) != value);
+			break;
+		case VAR_DDR_INIT_OPCODE_DELAY_USEC:
+			udelay(value);
+			break;
+		default:
+			break;
+		}
+
+		i++;
+	}
+
+	udelay(500);
+}
+
+/*
+ * Null terminate the info strings, in case the info was never written to EEPROM and it contains garbage
+ */
+static void var_eeprom_v1_null_term_strings(struct var_eeprom_v1_cfg *p_var_eeprom_v1_cfg)
+{
+	p_var_eeprom_v1_cfg->header.part_number[sizeof(p_var_eeprom_v1_cfg->header.part_number) - 1] = (u8)0;
+	p_var_eeprom_v1_cfg->header.Assembly[sizeof(p_var_eeprom_v1_cfg->header.Assembly) - 1] = (u8)0;
+	p_var_eeprom_v1_cfg->header.date[sizeof(p_var_eeprom_v1_cfg->header.date) - 1] = (u8)0;
+}
+
+static void var_eeprom_v1_print_info(const struct var_eeprom_v1_cfg *p_var_eeprom_v1_cfg)
+{
+	printf("\nPart number: %s\n", (char *)p_var_eeprom_v1_cfg->header.part_number);
+	printf("Assembly: %s\n", (char *)p_var_eeprom_v1_cfg->header.Assembly);
+	printf("Date of production: %s\n", (char *)p_var_eeprom_v1_cfg->header.date);
+}
+
+int var_eeprom_v1_dram_init(void)
+{
+	struct var_eeprom_v1_cfg var_eeprom_v1_cfg = {{0}};
+
+	if (var_eeprom_v1_read_struct(&var_eeprom_v1_cfg))
+		return -1;
+
+	if (is_cpu_type(MXC_CPU_MX6DL) || is_cpu_type(MXC_CPU_MX6SOLO))
+		var_eeprom_v1_mx6sdl_dram_setup_iomux(&(var_eeprom_v1_cfg.pinmux_group));
+	else if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D))
+		var_eeprom_v1_mx6dq_dram_setup_iomux(&(var_eeprom_v1_cfg.pinmux_group));
+
+	var_eeprom_v1_handle_write_opcodes(var_eeprom_v1_cfg.write_opcodes);
+
+	var_eeprom_v1_null_term_strings(&var_eeprom_v1_cfg);
+	var_eeprom_v1_print_info(&var_eeprom_v1_cfg);
+
+	return 0;
+}
+#endif /* CONFIG_SPL_BUILD */
diff --git a/board/variscite/mx6var_som/mx6var_eeprom_v1.h b/board/variscite/mx6var_som/mx6var_eeprom_v1.h
new file mode 100644
index 0000000..9707d08
--- /dev/null
+++ b/board/variscite/mx6var_som/mx6var_eeprom_v1.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _MX6VAR_EEPROM_V1_H_
+#define _MX6VAR_EEPROM_V1_H_
+
+#define VARISCITE_MAGIC			0x49524157 /* == HEX("VARI")*/
+
+#define VAR_EEPROM_I2C_BUS		1
+#define VAR_EEPROM_I2C_ADDR		0x56
+#define VAR_EEPROM_SIZE_BYTES		512
+#define VAR_EEPROM_MAX_NUM_OF_OPCODES	((VAR_EEPROM_SIZE_BYTES \
+						- sizeof(struct var_eeprom_v1_cfg_header) \
+						- sizeof(struct var_pinmux_group_regs)) \
+						/ sizeof(struct reg_write_opcode))
+
+#define VAR_DDR_INIT_OPCODE_WRITE_VAL_TO_ADDRESS	0x00000000
+#define VAR_DDR_INIT_OPCODE_WAIT_MASK_RISING		0x10000000
+#define VAR_DDR_INIT_OPCODE_WAIT_MASK_FALLING		0x20000000
+#define VAR_DDR_INIT_OPCODE_DELAY_USEC			0x30000000
+
+struct var_eeprom_v1_cfg_header
+{
+	u32 variscite_magic; /* == HEX("VARI")?*/
+	u8 part_number[16];
+	u8 Assembly[16];
+	u8 date[16];
+	u8 version;
+	u8 reserved[7];
+	/* DRAM size in MiB */
+	u32 dram_size;
+};
+
+struct var_pinmux_group_regs
+{
+	u32 IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE;
+	u32 IOMUXC_SW_PAD_CTL_GRP_DDRPKE;
+	u32 IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL;
+	u32 IOMUXC_SW_PAD_CTL_GRP_DDRMODE;
+	u32 IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2;
+	u32 dram_reset;
+	u32 dram_sdcke0;
+	u32 dram_sdcke1;
+	u32 dram_sdodt0;
+	u32 dram_sdodt1;
+	u32 reserved;
+	u32 pinmux_ctrlpad_all_value;
+};
+
+struct reg_write_opcode
+{
+	u32 address; /* address encoded with opcode */
+	u32 value;
+};
+
+struct var_eeprom_v1_cfg
+{
+	struct var_eeprom_v1_cfg_header header;
+	struct var_pinmux_group_regs pinmux_group;
+	struct reg_write_opcode write_opcodes[VAR_EEPROM_MAX_NUM_OF_OPCODES];
+};
+
+#endif /* _MX6VAR_EEPROM_V1_H_ */
diff --git a/board/variscite/mx6var_som/mx6var_eeprom_v2.c b/board/variscite/mx6var_som/mx6var_eeprom_v2.c
new file mode 100644
index 0000000..b148b20
--- /dev/null
+++ b/board/variscite/mx6var_som/mx6var_eeprom_v2.c
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
+ *
+ * Setup DRAM parametes and calibration values
+ * for the specific DRAM on the board.
+ * The parameters were provided by
+ * i.MX6 DDR Stress Test Tool and saved on EEPROM.
+ *
+ * For DART board
+ * (Can hold more parameters than "VAR EEPROM V1")
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include "mx6var_eeprom_v2.h"
+
+static inline bool var_eeprom_v2_is_valid(const struct var_eeprom_v2_cfg *p_var_eeprom_v2_cfg)
+{
+	return (VARISCITE_MAGIC_V2 == p_var_eeprom_v2_cfg->variscite_magic);
+}
+
+static int var_eeprom_v2_read_struct(struct var_eeprom_v2_cfg *var_eeprom_v2_cfg)
+{
+	i2c_set_bus_num(VAR_DART_EEPROM_I2C_BUS);
+	if (i2c_probe(VAR_DART_EEPROM_I2C_ADDR)) {
+		printf("\nError: Couldn't find EEPROM device\n");
+		return -1;
+	}
+
+	if (i2c_read(VAR_DART_EEPROM_I2C_ADDR, 0, 1,
+				(u8 *) var_eeprom_v2_cfg,
+				sizeof(struct var_eeprom_v2_cfg))) {
+		printf("\nError reading data from EEPROM\n");
+		return -1;
+	}
+
+	if (!var_eeprom_v2_is_valid(var_eeprom_v2_cfg)) {
+		printf("\nError: Data on EEPROM is invalid\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Returns DRAM size in MiB
+ */
+u32 var_eeprom_v2_get_ram_size(void)
+{
+	struct var_eeprom_v2_cfg var_eeprom_v2_cfg = {0};
+
+	if (var_eeprom_v2_read_struct(&var_eeprom_v2_cfg))
+		return -1;
+
+	return var_eeprom_v2_cfg.dram_size * 128;
+}
+
+#ifdef CONFIG_SPL_BUILD
+/*
+ * Fills custom_addresses & custom_values, from custom_addresses_values
+ */
+static void load_custom_data(u32 *custom_addresses, u32 *custom_values, const u32 *custom_addresses_values)
+{
+	int i, j=0;
+
+	for (i = 0; i < MAX_CUSTOM_ADDRESSES; i++) {
+		if (custom_addresses_values[i] == 0)
+			break;
+		custom_addresses[i] = custom_addresses_values[i];
+	}
+
+	i++;
+	if (i > MAX_CUSTOM_ADDRESSES)
+		return;
+
+	j=0;
+	for (; i < MAX_CUSTOM_VALUES; i++) {
+		if (custom_addresses_values[i] == 0)
+			break;
+		custom_values[j] = custom_addresses_values[i];
+		j++;
+	}
+}
+
+static u32 get_address_by_index(u8 index, const u32 *common_addresses, const u32 *custom_addresses)
+{
+	if (index >= MAX_COMMON_ADDRS_INDEX)
+		return custom_addresses[index - MAX_COMMON_ADDRS_INDEX];
+
+	return common_addresses[index];
+}
+
+static u32 get_value_by_index(u8 index, const u32 *common_values, const u32 *custom_values)
+{
+	if (index >= MAX_COMMON_VALUES_INDEX)
+		return custom_values[index - MAX_COMMON_VALUES_INDEX];
+
+	return common_values[index];
+}
+
+static int handle_commands(const struct eeprom_command commands[],
+			const u32 *common_addresses,
+			const u32 *common_values,
+			const u32 *custom_addresses,
+			const u32 *custom_values)
+{
+	u32 address, value;
+	volatile u32 *reg_ptr;
+	u8 wait_idx = 0;
+	int i = 0;
+
+	while (i < MAX_NUM_OF_COMMANDS) {
+
+		eeprom_v2_debug("Executing command %03d: %03d,  %03d\n",
+				i,
+				commands[i].address_index,
+				commands[i].value_index);
+
+		if (commands[i].address_index == LAST_COMMAND_INDEX)
+			return 0;
+
+		if (commands[i].address_index == DELAY_10USEC_INDEX) {
+			/* Delay for Value * 10 uSeconds */
+			eeprom_v2_debug("Delaying for %d microseconds\n", commands[i].value_index * 10);
+			udelay((int)(commands[i].value_index * 10));
+			++i;
+			continue;
+		}
+
+		/*
+		 * Check for a wait index.
+		 * A wait index means "next command is a wait command".
+		 */
+		switch (commands[i].address_index) {
+		case WHILE_NOT_EQUAL_INDEX:
+		case WHILE_EQUAL_INDEX:
+		case WHILE_AND_INDEX:
+		case WHILE_NOT_AND_INDEX:
+			/* Save wait index and go to next command */
+			wait_idx = commands[i].address_index;
+			++i;
+			break;
+		}
+
+		/* Get address and value */
+		address = get_address_by_index(commands[i].address_index, common_addresses, custom_addresses);
+		value = get_value_by_index(commands[i].value_index, common_values, custom_values);
+		reg_ptr = (u32 *)address;
+
+		switch (wait_idx) {
+		case WHILE_NOT_EQUAL_INDEX:
+			eeprom_v2_debug("Waiting while data at address %08x is not equal %08x\n", address, value);
+			while(*reg_ptr != value);
+			break;
+		case WHILE_EQUAL_INDEX:
+			eeprom_v2_debug("Waiting while data at address %08x is equal %08x\n", address, value);
+			while(*reg_ptr == value);
+			break;
+		case WHILE_AND_INDEX:
+			eeprom_v2_debug("Waiting while data at address %08x and %08x is not zero\n", address, value);
+			while(*reg_ptr & value);
+			break;
+		case WHILE_NOT_AND_INDEX:
+			eeprom_v2_debug("Waiting while data at address %08x and %08x is zero\n", address, value);
+			while(!(*reg_ptr & value));
+			break;
+		default:
+			/* This is a regular set command (non-wait) */
+			eeprom_v2_debug("Setting data at address %08x to %08x\n", address, value);
+			*reg_ptr = value;
+			break;
+		}
+
+		++i;
+	}
+
+	return 0;
+}
+
+/*
+ * Null terminate the info strings, in case the info was never written to EEPROM and it contains garbage
+ */
+static void var_eeprom_v2_null_term_strings(struct var_eeprom_v2_cfg *p_var_eeprom_v2_cfg)
+{
+	p_var_eeprom_v2_cfg->part_number[sizeof(p_var_eeprom_v2_cfg->part_number)-1] = (u8)0;
+	p_var_eeprom_v2_cfg->Assembly[sizeof(p_var_eeprom_v2_cfg->Assembly)-1] = (u8)0;
+	p_var_eeprom_v2_cfg->date[sizeof(p_var_eeprom_v2_cfg->date)-1] = (u8)0;
+}
+
+static void var_eeprom_v2_print_info(const struct var_eeprom_v2_cfg *p_var_eeprom_v2_cfg)
+{
+	printf("\nPart number: %s\n", (char *)p_var_eeprom_v2_cfg->part_number);
+	printf("Assembly: %s\n", (char *)p_var_eeprom_v2_cfg->Assembly);
+	printf("Date of production: %s\n", (char *)p_var_eeprom_v2_cfg->date);
+}
+
+int var_eeprom_v2_dram_init(void)
+{
+	struct var_eeprom_v2_cfg var_eeprom_v2_cfg = {0};
+
+	/*
+	 * The eeprom contains commands with
+	 * 1 byte index to a common address in this array, and
+	 * 1 byte index to a common value in the next array - to write to the address.
+	 */
+	const u32 common_addresses[]=
+	{
+		#include "addresses.inc"
+	};
+
+	const u32 common_values[] =
+	{
+		#include "values.inc"
+	};
+
+	/*
+	 * Some commands in the eeprom contain higher indices,
+	 * to custom addresses and values which are not present in the common arrays,
+	 * and it also contains an array of the custom addresses and values themselves.
+	 */
+	u32 custom_addresses[MAX_CUSTOM_ADDRESSES]={0};
+	u32 custom_values[MAX_CUSTOM_VALUES]={0};
+
+	if (var_eeprom_v2_read_struct(&var_eeprom_v2_cfg))
+		return -1;
+
+	load_custom_data(custom_addresses, custom_values, var_eeprom_v2_cfg.custom_addresses_values);
+
+	handle_commands(var_eeprom_v2_cfg.commands, common_addresses, common_values, custom_addresses, custom_values);
+
+	var_eeprom_v2_null_term_strings(&var_eeprom_v2_cfg);
+	var_eeprom_v2_print_info(&var_eeprom_v2_cfg);
+
+	return 0;
+}
+#endif /* CONFIG_SPL_BUILD */
diff --git a/board/variscite/mx6var_som/mx6var_eeprom_v2.h b/board/variscite/mx6var_som/mx6var_eeprom_v2.h
new file mode 100644
index 0000000..c0c159a
--- /dev/null
+++ b/board/variscite/mx6var_som/mx6var_eeprom_v2.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _MX6VAR_EEPROM_V2_H_
+#define _MX6VAR_EEPROM_V2_H_
+
+#define VARISCITE_MAGIC_V2		0x32524156 /* == HEX("VAR2") */
+
+#define VAR_DART_EEPROM_I2C_BUS		1
+#define VAR_DART_EEPROM_I2C_ADDR	0x52
+
+#define WHILE_NOT_EQUAL_INDEX		241
+#define WHILE_EQUAL_INDEX		242
+#define WHILE_AND_INDEX			243
+#define WHILE_NOT_AND_INDEX		244
+#define DELAY_10USEC_INDEX		245
+#define LAST_COMMAND_INDEX		255
+
+#define MAX_CUSTOM_ADDRESSES		32
+#define MAX_CUSTOM_VALUES		32
+
+#define MAX_COMMON_ADDRS_INDEX		200
+#define MAX_COMMON_VALUES_INDEX		200
+
+#define MAX_NUM_OF_COMMANDS		150
+
+#ifdef EEPROM_V2_DEBUG
+#define eeprom_v2_debug(M, ...) printf("EEPROM_V2 DEBUG: " M, ##__VA_ARGS__)
+#else
+#define eeprom_v2_debug(M, ...)
+#endif
+
+struct __attribute__((packed)) eeprom_command
+{
+	u8 address_index;
+	u8 value_index;
+};
+
+struct __attribute__((packed)) var_eeprom_v2_cfg
+{
+	u32 variscite_magic; /* == HEX("VAR2")? */
+	u8 part_number[16];
+	u8 Assembly[16];
+	u8 date[12];
+	/* Contains addresses and values not present in .inc files */
+	u32 custom_addresses_values[32];
+	struct eeprom_command commands[MAX_NUM_OF_COMMANDS];
+	u8 reserved[34];
+	/* DRAM size in 8KiB unit */
+	u8 dram_size;
+	u8 crc;
+};
+
+#endif /* _MX6VAR_EEPROM_V2_H_ */
diff --git a/board/variscite/mx6var_som/mx6var_som.c b/board/variscite/mx6var_som/mx6var_som.c
new file mode 100644
index 0000000..4673525
--- /dev/null
+++ b/board/variscite/mx6var_som/mx6var_som.c
@@ -0,0 +1,1444 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ * Author: Fabio Estevam <fabio.estevam at freescale.com>
+ *
+ * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
+ *
+ * Author: Eran Matityahu <eran.m at variscite.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <fsl_esdhc.h>
+#include <i2c.h>
+#include <malloc.h>
+#include <micrel.h>
+#include <miiphy.h>
+#include <mmc.h>
+#include <netdev.h>
+#include <power/pmic.h>
+#include <power/pfuze100_pmic.h>
+#include <splash.h>
+#include <usb.h>
+#include <usb/ehci-ci.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/iomux.h>
+#include <asm/arch/mx6-pins.h>
+#include <asm/arch/mxc_hdmi.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/errno.h>
+#include <asm/gpio.h>
+#include <asm/imx-common/mxc_i2c.h>
+#include <asm/imx-common/iomux-v3.h>
+#include <asm/imx-common/boot_mode.h>
+#include <asm/imx-common/video.h>
+#include <asm/io.h>
+#include "mx6var_eeprom.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 GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
+#define GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \
+			PAD_CTL_SRE_FAST)
+#define GPMI_PAD_CTRL2 (GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1)
+
+#define PER_VCC_EN_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |	\
+	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |	\
+	PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
+
+#define I2C_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
+	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |	\
+	PAD_CTL_ODE | PAD_CTL_SRE_FAST)
+
+#define OTG_ID_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |		\
+	PAD_CTL_PUS_47K_UP  | PAD_CTL_SPEED_LOW |		\
+	PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+
+
+#define VAR_SOM_BACKLIGHT_EN	IMX_GPIO_NR(4, 30)
+
+bool lvds_enabled=false;
+
+/*
+ * Returns true iff the SOM is VAR-SOM-SOLO
+ */
+static bool is_som_solo(void)
+{
+	bool ret;
+	int oldbus = i2c_get_bus_num();
+
+	i2c_set_bus_num(PMIC_I2C_BUS);
+	/* Probing for PMIC which is preset on all SOM types but SOM-SOLO */
+	ret = (0 != i2c_probe(CONFIG_POWER_PFUZE100_I2C_ADDR));
+
+	i2c_set_bus_num(oldbus);
+	return ret;
+}
+
+/*
+ * Returns true iff the carrier board is VAR-SOLOCustomBoard
+ */
+static bool is_solo_custom_board(void)
+{
+	bool ret;
+	int oldbus = i2c_get_bus_num();
+
+	i2c_set_bus_num(1);
+	/* Probing for extra EEPROM present only on SOLOCustomBoard */
+	ret = (0 == i2c_probe(0x51));
+
+	i2c_set_bus_num(oldbus);
+	return ret;
+}
+
+static bool is_cpu_pop_packaged(void)
+{
+	struct src *src_regs = (struct src *)SRC_BASE_ADDR;
+	u32 soc_sbmr = readl(&src_regs->sbmr1);
+	u8  boot_cfg3 = (soc_sbmr >> 16) & 0xFF;
+
+	/* DDR Memory Map config == 4KB Interleaving Enabled */
+	return ((boot_cfg3 & 0x30) == 0x20);
+}
+
+/*
+ * Returns true iff the carrier board is VAR-DT6CustomBoard
+ *  (and the SOM is DART-MX6)
+ */
+static inline bool is_dart_board(void)
+{
+	return is_cpu_pop_packaged();
+}
+
+/*
+ * Returns true iff the carrier board is VAR-MX6CustomBoard
+ */
+static inline bool is_mx6_custom_board(void)
+{
+	return (!is_dart_board() && !is_solo_custom_board());
+}
+
+enum current_board {
+	DART_BOARD,
+	SOLO_CUSTOM_BOARD,
+	MX6_CUSTOM_BOARD,
+};
+
+static enum current_board get_board_indx(void)
+{
+	if (is_dart_board())
+		return DART_BOARD;
+	if (is_solo_custom_board())
+		return SOLO_CUSTOM_BOARD;
+	if (is_mx6_custom_board())
+		return MX6_CUSTOM_BOARD;
+
+	printf("Error identifing carrier board!\n");
+	hang();
+}
+
+static int check_env(char *var, char *val)
+{
+	char *read_val;
+	if (var==NULL || val==NULL)
+		return 0;
+
+	read_val = getenv(var);
+
+	if ((read_val != NULL) &&
+			(strcmp(read_val, val) == 0)) {
+		return 1;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_SPLASH_SCREEN
+static void set_splashsource_to_boot_rootfs(void)
+{
+	if (!check_env("splashsourceauto", "yes"))
+		return;
+
+#ifdef CONFIG_SYS_BOOT_NAND
+	setenv("splashsource", getenv("rootfs_device"));
+#else
+	if (mmc_get_env_dev() == 0)
+		setenv("splashsource", "sd");
+	else if (mmc_get_env_dev() == 1)
+		setenv("splashsource", "emmc");
+#endif
+}
+
+int splash_screen_prepare(void)
+{
+	int ret;
+
+	struct splash_location var_splash_locations[] = {
+		{
+			.name = "sd",
+			.storage = SPLASH_STORAGE_MMC,
+			.flags = SPLASH_STORAGE_FS,
+			.devpart = "0:2",
+		},
+		{
+			.name = "emmc",
+			.storage = SPLASH_STORAGE_MMC,
+			.flags = SPLASH_STORAGE_FS,
+			.devpart = (is_dart_board() ? "1:2" : "1:1"),
+		},
+		{
+			.name = "nand",
+			.storage = SPLASH_STORAGE_NAND,
+			.flags = SPLASH_STORAGE_FS,
+			.mtdpart = "rootfs",
+			.ubivol = "ubi0:rootfs",
+		},
+	};
+
+	set_splashsource_to_boot_rootfs();
+
+	ret = splash_source_load(var_splash_locations,
+			ARRAY_SIZE(var_splash_locations));
+
+	/* Turn on backlight */
+	if (lvds_enabled)
+		gpio_set_value(VAR_SOM_BACKLIGHT_EN, 1);
+
+	return ret;
+}
+#endif
+
+static void print_emmc_size(void)
+{
+	struct mmc *mmc;
+	int err;
+
+	mmc = find_mmc_device(1);
+	err = !mmc;
+	if (!err) {
+		/* Silence mmc_init since SOMs can be with or without eMMC */
+		gd->flags |= GD_FLG_SILENT;
+		err = mmc_init(mmc);
+		gd->flags &= ~GD_FLG_SILENT;
+	}
+
+	if (err) {
+		puts("No eMMC\n");
+		return;
+	}
+
+	puts("eMMC:  ");
+	print_size(mmc->capacity, "\n");
+}
+
+/*
+ * Returns DRAM size in MiB
+ */
+static u32 read_ram_size_from_eeprom(void)
+{
+	u32 ram_size = is_dart_board() ?
+		var_eeprom_v2_get_ram_size() :
+		var_eeprom_v1_get_ram_size();
+
+	if (ram_size < 0) {
+		printf("Error reading RAM size from EEPROM\n");
+		hang();
+	}
+
+	/* Just to be sure */
+	if (ram_size > 3840)
+		ram_size = 3840;
+
+	return ram_size;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = read_ram_size_from_eeprom() * 1024 * 1024;
+	return 0;
+}
+
+static iomux_v3_cfg_t const uart1_pads[] = {
+	IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
+	IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
+};
+
+static iomux_v3_cfg_t const enet_pads1[] = {
+	IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO	| MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_ENET_MDC__ENET_MDC	| MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC	| MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0	| MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1	| MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2	| MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3	| MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK	| MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	/* pin 35 - 1 (PHY_AD2) on reset */
+	IOMUX_PADS(PAD_RGMII_RXC__GPIO6_IO30		| MUX_PAD_CTRL(NO_PAD_CTRL)),
+	/* pin 32 - 1 - (MODE0) all */
+	IOMUX_PADS(PAD_RGMII_RD0__GPIO6_IO25		| MUX_PAD_CTRL(NO_PAD_CTRL)),
+	/* pin 31 - 1 - (MODE1) all */
+	IOMUX_PADS(PAD_RGMII_RD1__GPIO6_IO27		| MUX_PAD_CTRL(NO_PAD_CTRL)),
+	/* pin 28 - 1 - (MODE2) all */
+	IOMUX_PADS(PAD_RGMII_RD2__GPIO6_IO28		| MUX_PAD_CTRL(NO_PAD_CTRL)),
+	/* pin 27 - 1 - (MODE3) all */
+	IOMUX_PADS(PAD_RGMII_RD3__GPIO6_IO29		| MUX_PAD_CTRL(NO_PAD_CTRL)),
+	/* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
+	IOMUX_PADS(PAD_RGMII_RX_CTL__GPIO6_IO24		| MUX_PAD_CTRL(NO_PAD_CTRL)),
+	/* PHY Reset */
+	IOMUX_PADS(PAD_ENET_CRS_DV__GPIO1_IO25		| MUX_PAD_CTRL(NO_PAD_CTRL)),
+};
+
+static iomux_v3_cfg_t const enet_pads2[] = {
+	IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL)),
+};
+
+static void setup_iomux_enet(void)
+{
+	gpio_direction_output(IMX_GPIO_NR(1, 25), 0);
+	gpio_direction_output(IMX_GPIO_NR(6, 30), 1);
+	gpio_direction_output(IMX_GPIO_NR(6, 25), 1);
+	gpio_direction_output(IMX_GPIO_NR(6, 27), 1);
+	gpio_direction_output(IMX_GPIO_NR(6, 28), 1);
+	gpio_direction_output(IMX_GPIO_NR(6, 29), 1);
+
+	SETUP_IOMUX_PADS(enet_pads1);
+
+	gpio_direction_output(IMX_GPIO_NR(6, 24), 1);
+
+	mdelay(10);
+	/* Reset PHY */
+	gpio_set_value(IMX_GPIO_NR(1, 25), 1);
+
+	SETUP_IOMUX_PADS(enet_pads2);
+}
+
+static iomux_v3_cfg_t const usdhc1_pads[] = {
+	IOMUX_PADS(PAD_SD1_CLK__SD1_CLK		| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD1_CMD__SD1_CMD		| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD1_DAT0__SD1_DATA0	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD1_DAT1__SD1_DATA1	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD1_DAT2__SD1_DATA2	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD1_DAT3__SD1_DATA3	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+};
+
+
+static iomux_v3_cfg_t const usdhc2_pads[] = {
+	IOMUX_PADS(PAD_SD2_CLK__SD2_CLK		| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD2_CMD__SD2_CMD		| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+};
+
+static iomux_v3_cfg_t const usdhc2_cd_pad[][1*2] = {
+	{
+		/* DART */
+		IOMUX_PADS(PAD_GPIO_6__GPIO1_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
+	},
+	{
+		/* Non-DART */
+		IOMUX_PADS(PAD_KEY_COL4__GPIO4_IO14 | MUX_PAD_CTRL(NO_PAD_CTRL)),
+	}
+};
+
+static iomux_v3_cfg_t const usdhc3_pads[] = {
+	IOMUX_PADS(PAD_SD3_CLK__SD3_CLK		| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_CMD__SD3_CMD		| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+};
+
+#ifdef CONFIG_SYS_I2C_MXC
+I2C_PADS(i2c_pad_info1,
+	PAD_CSI0_DAT9__I2C1_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL),
+	PAD_CSI0_DAT9__GPIO5_IO27 | MUX_PAD_CTRL(I2C_PAD_CTRL),
+	IMX_GPIO_NR(5, 27),
+	PAD_CSI0_DAT8__I2C1_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL),
+	PAD_CSI0_DAT8__GPIO5_IO26 | MUX_PAD_CTRL(I2C_PAD_CTRL),
+	IMX_GPIO_NR(5, 26));
+
+I2C_PADS(i2c_pad_info2,
+	PAD_KEY_COL3__I2C2_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL),
+	PAD_KEY_COL3__GPIO4_IO12 | MUX_PAD_CTRL(I2C_PAD_CTRL),
+	IMX_GPIO_NR(4, 12),
+	PAD_KEY_ROW3__I2C2_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL),
+	PAD_KEY_ROW3__GPIO4_IO13 | MUX_PAD_CTRL(I2C_PAD_CTRL),
+	IMX_GPIO_NR(4, 13));
+
+I2C_PADS(i2c_pad_info3,
+	PAD_GPIO_5__I2C3_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL),
+	PAD_GPIO_5__GPIO1_IO05 | MUX_PAD_CTRL(I2C_PAD_CTRL),
+	IMX_GPIO_NR(1, 5),
+	PAD_GPIO_16__I2C3_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL),
+	PAD_GPIO_16__GPIO7_IO11 | MUX_PAD_CTRL(I2C_PAD_CTRL),
+	IMX_GPIO_NR(7, 11));
+#endif
+
+void setup_local_i2c(void) {
+	setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c_pad_info1));
+	setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c_pad_info2));
+	setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c_pad_info3));
+}
+
+static void setup_iomux_uart(void)
+{
+	SETUP_IOMUX_PADS(uart1_pads);
+}
+
+#ifdef CONFIG_FSL_ESDHC
+static struct fsl_esdhc_cfg usdhc_cfg[2];
+
+int board_mmc_get_env_dev(int devno)
+{
+	return devno - 1;
+}
+
+#ifdef CONFIG_ENV_IS_IN_MMC
+static int mmc_map_to_kernel_blk(int dev_no)
+{
+	return dev_no + 1;
+}
+#endif
+
+static int usdhc2_cd_gpio[] = {
+	/* DART */
+	IMX_GPIO_NR(1, 6),
+	/* Non-DART */
+	IMX_GPIO_NR(4, 14)
+};
+
+int board_mmc_getcd(struct mmc *mmc)
+{
+	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+	int board = is_dart_board() ? 0 : 1;
+
+	/* SD card */
+	if (cfg->esdhc_base == USDHC2_BASE_ADDR) {
+		return !gpio_get_value(usdhc2_cd_gpio[board]);
+	}
+
+	/*
+	 * On DART SOMs eMMC is always present.
+	 *
+	 * On non DART SOMs eMMC can be present or not,
+	 * but we can't know until we try to init it
+	 * so return 1 here anyway
+	 */
+	return 1;
+}
+
+#ifdef CONFIG_SPL_BUILD
+enum mmc_boot_device {
+	USDHC1,
+	USDHC2,
+	USDHC3,
+	USDHC4,
+};
+
+static enum mmc_boot_device get_mmc_boot_device(void)
+{
+	struct src *psrc = (struct src *)SRC_BASE_ADDR;
+	unsigned reg = readl(&psrc->sbmr1) >> 11;
+	/*
+	 * Upon reading BOOT_CFG register
+	 * Bit 11 and 12 of BOOT_CFG register can determine the current
+	 * mmc port
+	 */
+
+	return (reg & 0x3);
+}
+#endif
+
+int board_mmc_init(bd_t *bis)
+{
+#ifndef CONFIG_SPL_BUILD
+	int ret, i, board;
+
+	/*
+	 * According to the board_mmc_init() the following map is done:
+	 * (U-Boot device node)    (Physical Port)
+	 * On non DART boards:
+	 * mmc0                    SD2 (SD)
+	 * mmc1                    SD1 (eMMC)
+	 *
+	 * On DART board:
+	 * mmc0                    SD2 (SD)
+	 * mmc1                    SD3 (eMMC)
+	 */
+	for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
+		switch (i) {
+		case 0:
+			SETUP_IOMUX_PADS(usdhc2_pads);
+
+			board = is_dart_board() ? 0 : 1;
+			SETUP_IOMUX_PADS(usdhc2_cd_pad[board]);
+			gpio_direction_input(usdhc2_cd_gpio[board]);
+
+			usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
+			usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+			usdhc_cfg[0].max_bus_width = 4;
+			break;
+		case 1:
+			if (is_dart_board()) {
+				SETUP_IOMUX_PADS(usdhc3_pads);
+				usdhc_cfg[1].esdhc_base = USDHC3_BASE_ADDR;
+				usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+			} else {
+				SETUP_IOMUX_PADS(usdhc1_pads);
+				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;
+		default:
+			printf("Warning: you configured more USDHC controllers"
+			       "(%d) then supported by the board (%d)\n",
+			       i + 1, CONFIG_SYS_FSL_USDHC_NUM);
+			return -EINVAL;
+		}
+
+		ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
+		if (ret)
+			return ret;
+	}
+	return 0;
+#else
+	/*
+	 * Possible MMC boot devices:
+	 * SD2 (SD)
+	 * SD3 (DART eMMC)
+	 */
+	puts("MMC Boot Device: ");
+	switch (get_mmc_boot_device()) {
+	case USDHC2:
+		puts("mmc0 (SD)\n");
+		SETUP_IOMUX_PADS(usdhc2_pads);
+		usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
+		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+		gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
+		usdhc_cfg[0].max_bus_width = 4;
+		break;
+	case USDHC3:
+		puts("mmc1 (eMMC)\n");
+		SETUP_IOMUX_PADS(usdhc3_pads);
+		usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
+		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+		gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
+		usdhc_cfg[0].max_bus_width = 4;
+		break;
+	default:
+		break;
+	}
+
+	return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
+#endif
+}
+#endif
+
+#ifdef CONFIG_ENV_IS_IN_MMC
+static void mmc_late_init(void)
+{
+	char cmd[32];
+	char mmcblk[32];
+	u32 dev_no = mmc_get_env_dev();
+
+	if (!check_env("mmcautodetect", "yes"))
+		return;
+
+	setenv_ulong("mmcdev", dev_no);
+
+	/* Set mmcroot env */
+	sprintf(mmcblk, "/dev/mmcblk%dp2 rootwait rw",
+			mmc_map_to_kernel_blk(dev_no));
+	setenv("mmcroot", mmcblk);
+
+	sprintf(cmd, "mmc dev %d", dev_no);
+	run_command(cmd, 0);
+}
+#endif
+
+#ifdef CONFIG_SYS_USE_NAND
+static iomux_v3_cfg_t const gpmi_pads[] = {
+	IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
+	IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
+	IOMUX_PADS(PAD_NANDF_WP_B__NAND_WP_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
+	IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL0)),
+	IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
+	IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
+	IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
+	IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
+	IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
+	IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
+	IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
+	IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
+	IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
+	IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
+	IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
+	IOMUX_PADS(PAD_SD4_DAT0__NAND_DQS	| MUX_PAD_CTRL(GPMI_PAD_CTRL1)),
+};
+
+static void setup_gpmi_nand(void)
+{
+	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+
+	SETUP_IOMUX_PADS(gpmi_pads);
+
+	/* gate ENFC_CLK_ROOT clock first,before clk source switch */
+	clrbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
+
+	/* config gpmi and bch clock to 100 MHz */
+	clrsetbits_le32(&mxc_ccm->cs2cdr,
+			MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
+			MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
+			MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
+			MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
+			MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
+			MXC_CCM_CS2CDR_ENFC_CLK_SEL(3));
+
+	/* enable ENFC_CLK_ROOT clock */
+	setbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
+
+	/* enable gpmi and bch clock gating */
+	setbits_le32(&mxc_ccm->CCGR4,
+			MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
+			MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
+			MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
+			MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
+			MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET);
+
+	/* enable apbh clock gating */
+	setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
+}
+#endif
+
+int board_phy_config(struct phy_device *phydev)
+{
+	if (phydev->drv->config)
+		phydev->drv->config(phydev);
+
+	/* manually configure PHY as master during master-slave negotiation */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x9, 0x1c00);
+
+	/* control data pad skew */
+	ksz9031_phy_extended_write(phydev, 0x02,
+			MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW,
+			MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
+	/* rx data pad skew */
+	ksz9031_phy_extended_write(phydev, 0x02,
+			MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW,
+			MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
+	/* tx data pad skew */
+	ksz9031_phy_extended_write(phydev, 0x02,
+			MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW,
+			MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
+	/* gtx and rx clock pad skew */
+	ksz9031_phy_extended_write(phydev, 0x02,
+			MII_KSZ9031_EXT_RGMII_CLOCK_SKEW,
+			MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x03FF);
+
+	return 0;
+}
+
+#if defined(CONFIG_VIDEO_IPUV3)
+static void disable_lvds(struct display_info_t const *dev)
+{
+	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
+
+	int reg = readl(&iomux->gpr[2]);
+
+	reg &= ~(IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
+		 IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
+
+	writel(reg, &iomux->gpr[2]);
+}
+
+static void do_enable_hdmi(struct display_info_t const *dev)
+{
+	disable_lvds(dev);
+	/*
+	 * imx_enable_hdmi_phy(); should be called here.
+	 * It is ommitted to avoid a current known bug where
+	 * the boot sometimes hangs if an HDMI cable is attached
+	 * - at least on some SOMs.
+	 */
+}
+
+static void lvds_enable_disable(struct display_info_t const *dev)
+{
+	if (getenv("splashimage") != NULL)
+		lvds_enabled=true;
+	else
+		disable_lvds(dev);
+}
+
+static int detect_dart_vsc_display(struct display_info_t const *dev)
+{
+	return (!is_mx6_custom_board());
+}
+
+static int detect_mx6cb_cdisplay(struct display_info_t const *dev)
+{
+	if (!is_mx6_custom_board())
+		return 0;
+
+	i2c_set_bus_num(dev->bus);
+	return (0 == i2c_probe(dev->addr));
+}
+
+static int detect_mx6cb_rdisplay(struct display_info_t const *dev)
+{
+	if (!is_mx6_custom_board())
+		return 0;
+
+	/* i2c probe the *c*display */
+	i2c_set_bus_num(MX6CB_CDISPLAY_I2C_BUS);
+	return (0 != i2c_probe(MX6CB_CDISPLAY_I2C_ADDR));
+}
+
+#define MHZ2PS(f)	(1000000/(f))
+
+struct display_info_t const displays[] = {{
+	.bus	= -1,
+	.addr	= 0,
+	.pixfmt	= IPU_PIX_FMT_RGB24,
+	.detect	= detect_hdmi,
+	.enable	= do_enable_hdmi,
+	.mode	= {
+		.name           = "HDMI",
+		.refresh        = 60,  /* optional */
+		.xres           = 800,
+		.yres           = 480,
+		.pixclock       = 31777,
+		.left_margin    = 48,
+		.right_margin   = 16,
+		.upper_margin   = 33,
+		.lower_margin   = 10,
+		.hsync_len      = 96,
+		.vsync_len      = 2,
+		.sync           = 0,
+		.vmode          = FB_VMODE_NONINTERLACED
+} }, {
+	.bus	= -1,
+	.addr	= 0,
+	.pixfmt	= IPU_PIX_FMT_RGB666,
+	.detect	= detect_dart_vsc_display,
+	.enable	= lvds_enable_disable,
+	.mode	= {
+		.name           = "VAR-WVGA",
+		.refresh        = 60,  /* optional */
+		.xres           = 800,
+		.yres           = 480,
+		.pixclock       = MHZ2PS(50),
+		.left_margin    = 40,
+		.right_margin   = 40,
+		.upper_margin   = 29,
+		.lower_margin   = 13,
+		.hsync_len      = 48,
+		.vsync_len      = 3,
+		.sync           = FB_SYNC_EXT,
+		.vmode          = FB_VMODE_NONINTERLACED
+} }, {
+	.bus	= MX6CB_CDISPLAY_I2C_BUS,
+	.addr	= MX6CB_CDISPLAY_I2C_ADDR,
+	.pixfmt	= IPU_PIX_FMT_RGB24,
+	.detect	= detect_mx6cb_cdisplay,
+	.enable	= lvds_enable_disable,
+	.mode	= {
+		.name           = "VAR-WVGA MX6CB-C",
+		.refresh        = 60,  /* optional */
+		.xres           = 800,
+		.yres           = 480,
+		.pixclock       = MHZ2PS(50),
+		.left_margin    = 39,
+		.right_margin   = 39,
+		.upper_margin   = 29,
+		.lower_margin   = 13,
+		.hsync_len      = 128,
+		.vsync_len      = 2,
+		.sync           = FB_SYNC_EXT,
+		.vmode          = FB_VMODE_NONINTERLACED
+} }, {
+	.bus	= -1,
+	.addr	= 0,
+	.pixfmt	= IPU_PIX_FMT_RGB24,
+	.detect	= detect_mx6cb_rdisplay,
+	.enable	= lvds_enable_disable,
+	.mode	= {
+		.name           = "VAR-WVGA MX6CB-R",
+		.refresh        = 60,  /* optional */
+		.xres           = 800,
+		.yres           = 480,
+		.pixclock       = MHZ2PS(50),
+		.left_margin    = 0,
+		.right_margin   = 40,
+		.upper_margin   = 20,
+		.lower_margin   = 13,
+		.hsync_len      = 48,
+		.vsync_len      = 3,
+		.sync           = FB_SYNC_EXT,
+		.vmode          = FB_VMODE_NONINTERLACED
+} } };
+
+size_t display_count = ARRAY_SIZE(displays);
+
+static void setup_display(void)
+{
+	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
+	int reg;
+
+	/* Setup backlight */
+	SETUP_IOMUX_PAD(PAD_DISP0_DAT9__GPIO4_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL));
+
+	/* Turn off backlight until display is ready */
+	gpio_direction_output(VAR_SOM_BACKLIGHT_EN , 0);
+
+	enable_ipu_clock();
+	imx_setup_hdmi();
+
+	/* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */
+	reg = readl(&mxc_ccm->CCGR3);
+	reg |=  MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
+	writel(reg, &mxc_ccm->CCGR3);
+
+	/* set LDB0, LDB1 clk select to 011/011 */
+	reg = readl(&mxc_ccm->cs2cdr);
+	reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
+		 | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
+	/* 1 -> ~50MHz , 2 -> ~56MHz, 3 -> ~75MHz, 4 -> ~68MHz */
+	reg |= (1 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
+	      | (1 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
+	writel(reg, &mxc_ccm->cs2cdr);
+
+	reg = readl(&mxc_ccm->cscmr2);
+	reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
+	writel(reg, &mxc_ccm->cscmr2);
+
+	reg = readl(&mxc_ccm->chsccdr);
+	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
+		<< MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
+	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
+		<< MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
+	writel(reg, &mxc_ccm->chsccdr);
+
+	reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
+	     | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
+	     | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
+	     | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
+	     | IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
+	     | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
+	     | IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
+	     | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0
+	     | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
+	writel(reg, &iomux->gpr[2]);
+
+	reg = readl(&iomux->gpr[3]);
+	reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK | IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
+		| (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 << IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
+	writel(reg, &iomux->gpr[3]);
+}
+#endif /* CONFIG_VIDEO_IPUV3 */
+
+/*
+ * Do not overwrite the console
+ * Use always serial for U-Boot console
+ */
+int overwrite_console(void)
+{
+	return 1;
+}
+
+int board_eth_init(bd_t *bis)
+{
+	uint32_t base = IMX_FEC_BASE;
+	struct mii_dev *bus = NULL;
+	struct phy_device *phydev = NULL;
+	int ret;
+
+	setup_iomux_enet();
+
+#ifdef CONFIG_FEC_MXC
+	bus = fec_get_miibus(base, -1);
+	if (!bus) {
+		printf("FEC MXC bus: %s:failed\n", __func__);
+		return 0;
+	}
+
+	phydev = phy_find_by_mask(bus, (0x1 << CONFIG_FEC_MXC_PHYADDR), PHY_INTERFACE_MODE_RGMII);
+	if (!phydev) {
+		printf("FEC MXC phy find: %s:failed\n", __func__);
+		free(bus);
+		return 0;
+	}
+	printf("using phy at %d\n", phydev->addr);
+
+	ret  = fec_probe(bis, -1, base, bus, phydev);
+	if (ret) {
+		printf("FEC MXC probe: %s:failed\n", __func__);
+		free(phydev);
+		free(bus);
+	}
+#endif
+
+#if defined(CONFIG_CI_UDC) && defined(CONFIG_USB_ETHER)
+	/* USB Ethernet Gadget */
+	usb_eth_initialize(bis);
+#endif
+
+	return 0;
+}
+
+#ifdef CONFIG_USB_EHCI_MX6
+static int const usb_otg_pwr_en_gpio[] = {
+	/* DART */
+	IMX_GPIO_NR(4, 15),
+	/* SOLOCustomBoard */
+	IMX_GPIO_NR(3, 22),
+};
+
+static int const usb_h1_pwr_en_gpio[] = {
+	/* DART */
+	IMX_GPIO_NR(1, 28),
+	/* SOLOCustomBoard */
+	IMX_GPIO_NR(4, 15),
+};
+
+static iomux_v3_cfg_t const usb_pads[][3*2] = {
+	{
+		/* DART */
+		IOMUX_PADS(PAD_ENET_RX_ER__USB_OTG_ID	| MUX_PAD_CTRL(OTG_ID_PAD_CTRL)),
+		IOMUX_PADS(PAD_KEY_ROW4__GPIO4_IO15	| MUX_PAD_CTRL(NO_PAD_CTRL)),
+		IOMUX_PADS(PAD_ENET_TX_EN__GPIO1_IO28	| MUX_PAD_CTRL(NO_PAD_CTRL)),
+	},
+	{
+		/* SOLOCustomBoard */
+		IOMUX_PADS(PAD_GPIO_1__USB_OTG_ID	| MUX_PAD_CTRL(OTG_ID_PAD_CTRL)),
+		IOMUX_PADS(PAD_EIM_D22__GPIO3_IO22	| MUX_PAD_CTRL(NO_PAD_CTRL)),
+		IOMUX_PADS(PAD_KEY_ROW4__GPIO4_IO15	| MUX_PAD_CTRL(NO_PAD_CTRL)),
+	}
+};
+
+static void setup_usb(void)
+{
+	int board = get_board_indx();
+	if (board == MX6_CUSTOM_BOARD)
+		return;
+
+	SETUP_IOMUX_PADS(usb_pads[board]);
+	gpio_direction_output(usb_otg_pwr_en_gpio[board], 0);
+	gpio_direction_output(usb_h1_pwr_en_gpio[board], 0);
+
+	if (board == DART_BOARD)
+		imx_iomux_set_gpr_register(1, 13, 1, 0);
+	else if (board == SOLO_CUSTOM_BOARD)
+		imx_iomux_set_gpr_register(1, 13, 1, 1);
+}
+
+int board_usb_phy_mode(int port)
+{
+	if (is_mx6_custom_board() && port == 0) {
+		if (check_env("usbmode", "host"))
+			return USB_INIT_HOST;
+		else
+			return USB_INIT_DEVICE;
+	}
+	return usb_phy_mode(port);
+}
+
+int board_ehci_power(int port, int on)
+{
+	int board = get_board_indx();
+	if (board == MX6_CUSTOM_BOARD)
+		return 0; /* no power enable needed */
+
+	if (port > 1)
+		return -EINVAL;
+
+	if (port)
+		gpio_set_value(usb_h1_pwr_en_gpio[board], on);
+	else
+		gpio_set_value(usb_otg_pwr_en_gpio[board], on);
+
+	return 0;
+}
+#endif /* CONFIG_USB_EHCI_MX6 */
+
+int board_early_init_f(void)
+{
+	setup_iomux_uart();
+#if defined(CONFIG_VIDEO_IPUV3)
+	setup_display();
+#endif
+#ifdef CONFIG_SYS_I2C_MXC
+	setup_local_i2c();
+#endif
+#ifdef CONFIG_SYS_USE_NAND
+	setup_gpmi_nand();
+#endif
+
+	return 0;
+}
+
+int board_init(void)
+{
+	int ret = 0;
+
+	/* address of boot parameters */
+	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+	gd->bd->bi_arch_number = CONFIG_MACH_VAR_SOM_MX6;
+
+#ifdef CONFIG_USB_EHCI_MX6
+	setup_usb();
+#endif
+	return ret;
+}
+
+static struct pmic *pfuze;
+
+struct pmic_write_values {
+	u32 reg;
+	u32 mask;
+	u32 writeval;
+};
+
+static int pmic_write_val(struct pmic *p, struct pmic_write_values pmic_struct)
+{
+	unsigned int val = 0;
+	int retval = 0;
+
+	if (!p) {
+		printf("No PMIC found!\n");
+		return -1;
+	}
+
+	retval += pmic_reg_read(p, pmic_struct.reg, &val);
+	val &= ~(pmic_struct.mask);
+	val |= pmic_struct.writeval;
+	retval += pmic_reg_write(p, pmic_struct.reg, val);
+
+	if (retval)
+		printf("PMIC write voltages error!\n");
+
+	return retval;
+}
+
+static int pmic_write_vals(struct pmic *p, struct pmic_write_values *arr, int arr_size)
+{
+	int i, retval;
+
+	for (i = 0; i < arr_size; ++i) {
+		retval = pmic_write_val(p, arr[i]);
+		if (retval)
+			return retval;
+	}
+
+	return 0;
+}
+
+static void set_anatop_bypass(void)
+{
+	struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
+	u32 reg = readl(&anatop->reg_core);
+
+	/* bypass VDDARM/VDDSOC */
+	reg |= (0x1F << 18) | 0x1F;
+	writel(reg, &anatop->reg_core);
+}
+
+static void ldo_mode_set(void)
+{
+	if (!is_som_solo()) {
+		struct pmic *p = pfuze;
+
+		struct pmic_write_values ldo_mode_arr[] = {
+			/* Set SW1AB to 1.325V */
+			{PFUZE100_SW1ABVOL, SW1x_NORMAL_MASK, SW1x_1_325V},
+			/* Set SW1C to 1.325V */
+			{PFUZE100_SW1CVOL, SW1x_NORMAL_MASK, SW1x_1_325V}
+		};
+
+		if (pmic_write_vals(p, ldo_mode_arr, ARRAY_SIZE(ldo_mode_arr)))
+			return;
+
+		set_anatop_bypass();
+		printf("switch to ldo_bypass mode!\n");
+	}
+}
+
+int power_init_board(void)
+{
+	if (!is_som_solo()) {
+		unsigned int reg;
+		int retval;
+
+		retval = power_pfuze100_init(PMIC_I2C_BUS);
+		if (retval)
+			return -ENODEV;
+		pfuze = pmic_get("PFUZE100");
+		retval = pmic_probe(pfuze);
+		if (retval)
+			return -ENODEV;
+		pmic_reg_read(pfuze, PFUZE100_DEVICEID, &reg);
+		printf("PMIC:  PFUZE100 ID=0x%02x\n", reg);
+
+		if (is_dart_board()) {
+
+			struct pmic_write_values dart_pmic_arr[] = {
+				/* Set SW1AB standby volage to 0.9V */
+				{PFUZE100_SW1ABSTBY, SW1x_STBY_MASK, SW1x_0_900V},
+
+				/* Set SW1AB off volage to 0.9V */
+				{PFUZE100_SW1ABOFF, SW1x_OFF_MASK, SW1x_0_900V},
+
+				/* Set SW1C standby voltage to 0.9V */
+				{PFUZE100_SW1CSTBY, SW1x_STBY_MASK, SW1x_0_900V},
+
+				/* Set SW1C off volage to 0.9V */
+				{PFUZE100_SW1COFF, SW1x_OFF_MASK, SW1x_0_900V},
+
+				/* Set SW2 to 3.3V */
+				{PFUZE100_SW2VOL, SWx_NORMAL_MASK, SWx_HR_3_300V},
+
+				/* Set SW2 standby voltage to 3.2V */
+				{PFUZE100_SW2STBY, SWx_STBY_MASK, SWx_HR_3_200V},
+
+				/* Set SW2 off voltage to 3.2V */
+				{PFUZE100_SW2OFF, SWx_OFF_MASK, SWx_HR_3_200V},
+
+				/* Set SW1AB/VDDARM step ramp up time 2us */
+				{PFUZE100_SW1ABCONF, SW1xCONF_DVSSPEED_MASK, SW1xCONF_DVSSPEED_2US},
+
+				/* Set SW1AB, SW1C, SW2 normal mode to PWM, and standby mode to PFM */
+				{PFUZE100_SW1ABMODE, SW_MODE_MASK, PWM_PFM},
+				{PFUZE100_SW1CMODE, SW_MODE_MASK, PWM_PFM},
+				{PFUZE100_SW2MODE, SW_MODE_MASK, PWM_PFM},
+
+				/* Set VGEN6 to 3.3V */
+				{PFUZE100_VGEN6VOL, LDO_VOL_MASK, LDOB_3_30V}
+			};
+
+			retval = pmic_write_vals(pfuze, dart_pmic_arr, ARRAY_SIZE(dart_pmic_arr));
+
+		} else {
+
+			struct pmic_write_values pmic_arr[] = {
+				/* Set SW1AB standby volage to 0.975V */
+				{PFUZE100_SW1ABSTBY, SW1x_STBY_MASK, SW1x_0_975V},
+
+				/* Set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */
+				{PFUZE100_SW1ABCONF, SW1xCONF_DVSSPEED_MASK, SW1xCONF_DVSSPEED_4US},
+
+				/* Set SW1C standby voltage to 0.975V */
+				{PFUZE100_SW1CSTBY, SW1x_STBY_MASK, SW1x_0_975V},
+
+				/* Set Gigbit Ethernet voltage */
+				{PFUZE100_SW4VOL, SWx_NORMAL_MASK, SWx_LR_1_200V},
+
+				/* Increase VGEN5 from 2.8 to 3V */
+				{PFUZE100_VGEN5VOL, LDO_VOL_MASK, LDOB_3_00V},
+
+				/* Set VGEN3 to 2.5V */
+				{PFUZE100_VGEN3VOL, LDO_VOL_MASK, LDOB_2_50V},
+#ifdef LOW_POWER_MODE_ENABLE
+				/* Set low power mode voltages to disable */
+
+				/* Set SW2 to 3.2V */
+				{PFUZE100_SW2VOL, SWx_NORMAL_MASK, SWx_HR_3_200V},
+
+				/* Set SW3A standby voltage to 1.275V */
+				{PFUZE100_SW3ASTBY, SWx_STBY_MASK, SWx_LR_1_275V},
+
+				/* Set SW3A off voltage to 1.275V */
+				{PFUZE100_SW3AOFF, SWx_OFF_MASK, SWx_LR_1_275V},
+
+				/* SW4MODE = OFF in standby */
+				{PFUZE100_SW4MODE, SW_MODE_MASK, PWM_OFF},
+
+				/* Set VGEN3CTL = OFF in standby */
+				{PFUZE100_VGEN3VOL, (LDO_MODE_MASK | LDO_EXT_MODE_MASK), \
+					(LDO_EN | LDO_EXT_MODE_ON_OFF << LDO_EXT_MODE_SHIFT)}
+#else
+				/* Set VGEN3CTL = low power in standby */
+				{PFUZE100_VGEN3VOL, (LDO_MODE_MASK | LDO_EXT_MODE_MASK), \
+					(LDO_EN | LDO_EXT_MODE_ON_LPM << LDO_EXT_MODE_SHIFT)}
+#endif
+			};
+
+			retval = pmic_write_vals(pfuze, pmic_arr, ARRAY_SIZE(pmic_arr));
+		}
+
+		/* Set SW1C/VDDSOC step ramp up time from 16us to 4us/25mV */
+		retval += pmic_write_val(pfuze,
+				(struct pmic_write_values)
+				{PFUZE100_SW1CCONF, SW1xCONF_DVSSPEED_MASK, SW1xCONF_DVSSPEED_4US});
+
+		if (retval)
+			return retval;
+
+		ldo_mode_set();
+	}
+
+	return 0;
+}
+
+static void imx6_pcie_assert_core_reset(void)
+{
+	struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
+
+	if (is_mx6dqp())
+		setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_PCIE_SW_RST);
+
+	setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_TEST_POWERDOWN);
+	clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_REF_SSP_EN);
+}
+
+static void imx6_pcie_init_phy(void)
+{
+	struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
+
+	clrbits_le32(&iomuxc_regs->gpr[12], IOMUXC_GPR12_APPS_LTSSM_ENABLE);
+
+	clrsetbits_le32(&iomuxc_regs->gpr[12],
+			IOMUXC_GPR12_DEVICE_TYPE_MASK,
+			IOMUXC_GPR12_DEVICE_TYPE_RC);
+	clrsetbits_le32(&iomuxc_regs->gpr[12],
+			IOMUXC_GPR12_LOS_LEVEL_MASK,
+			IOMUXC_GPR12_LOS_LEVEL_9);
+
+	writel((0x0 << IOMUXC_GPR8_PCS_TX_DEEMPH_GEN1_OFFSET) |
+			(0x0 << IOMUXC_GPR8_PCS_TX_DEEMPH_GEN2_3P5DB_OFFSET) |
+			(20 << IOMUXC_GPR8_PCS_TX_DEEMPH_GEN2_6DB_OFFSET) |
+			(127 << IOMUXC_GPR8_PCS_TX_SWING_FULL_OFFSET) |
+			(127 << IOMUXC_GPR8_PCS_TX_SWING_LOW_OFFSET),
+			&iomuxc_regs->gpr[8]);
+}
+
+static void imx6_pcie_deassert_core_reset(void)
+{
+	struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
+
+	if (is_mx6dqp())
+		clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_PCIE_SW_RST);
+
+	/*
+	 * Wait for the clock to settle a bit, when the clock are sourced
+	 * from the CPU, we need about 30 ms to settle.
+	 */
+	mdelay(50);
+
+	/* Enable PCIe */
+	clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_TEST_POWERDOWN);
+	setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_REF_SSP_EN);
+}
+
+/*
+ * Init the PCIe phy in order to prevent a soft reboot hang
+ */
+static void imx_pcie_reset(void)
+{
+	imx6_pcie_assert_core_reset();
+	imx6_pcie_init_phy();
+	imx6_pcie_deassert_core_reset();
+}
+
+int board_late_init(void)
+{
+#ifdef CONFIG_ENV_IS_IN_MMC
+	mmc_late_init();
+#endif
+	print_emmc_size();
+
+#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+	if (is_dart_board())
+		setenv("board_name", "DT6CUSTOM");
+	else if (is_solo_custom_board())
+		setenv("board_name", "SOLOCUSTOM");
+	else
+		setenv("board_name", "MX6CUSTOM");
+
+	if (is_som_solo())
+		setenv("board_som", "SOM-SOLO");
+	else if (is_dart_board())
+		setenv("board_som", "DART-MX6");
+	else
+		setenv("board_som", "SOM-MX6");
+
+	if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D))
+		setenv("board_rev", "MX6Q");
+	else if (is_cpu_type(MXC_CPU_MX6DL) || is_cpu_type(MXC_CPU_MX6SOLO))
+		setenv("board_rev", "MX6DL");
+#endif
+
+	imx_pcie_reset();
+
+	return 0;
+}
+
+int checkboard(void)
+{
+	puts("Board: Variscite VAR-SOM-MX6 ");
+
+	switch (get_cpu_type()) {
+	case MXC_CPU_MX6Q:
+		puts("Quad");
+		if (is_cpu_pop_packaged())
+			puts("-PoP");
+		break;
+	case MXC_CPU_MX6D:
+		puts("Dual");
+		if (is_cpu_pop_packaged())
+			puts("-PoP");
+		break;
+	case MXC_CPU_MX6DL:
+		if (is_som_solo())
+			puts("SOM-Dual");
+		else
+			puts("Dual Lite");
+		break;
+	case MXC_CPU_MX6SOLO:
+		if (is_som_solo())
+			puts("SOM-Solo");
+		else
+			puts("Solo");
+		break;
+	default:
+		puts("????");
+		break;
+	}
+	puts("\n");
+
+	return 0;
+}
+
+#ifdef CONFIG_SPL_BUILD
+#include <spl.h>
+#include <libfdt.h>
+#include <asm/arch/mx6-ddr.h>
+
+static void ccgr_init(void)
+{
+	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+
+	writel(0x00C03F3F, &ccm->CCGR0);
+	writel(0x0030FC03, &ccm->CCGR1);
+	writel(0x0FFFC000, &ccm->CCGR2);
+	writel(0x3FF00000, &ccm->CCGR3);
+	writel(0x00FFF300, &ccm->CCGR4);
+	writel(0x0F0000C3, &ccm->CCGR5);
+	writel(0x000003FF, &ccm->CCGR6);
+}
+
+static void gpr_init(void)
+{
+	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
+
+	/* enable AXI cache for VDOA/VPU/IPU */
+	writel(0xF00000CF, &iomux->gpr[4]);
+	/* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
+	writel(0x007F007F, &iomux->gpr[6]);
+	writel(0x007F007F, &iomux->gpr[7]);
+}
+
+static void setup_iomux_var_per_vcc_en(void)
+{
+	SETUP_IOMUX_PAD(PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(PER_VCC_EN_PAD_CTRL));
+	gpio_direction_output(IMX_GPIO_NR(3, 31), 1);
+}
+
+static void setup_iomux_audiocodec(void)
+{
+	SETUP_IOMUX_PAD(PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL));
+	gpio_direction_output(IMX_GPIO_NR(4, 5), 1);
+}
+
+static void audiocodec_reset(int rst)
+{
+	gpio_set_value(IMX_GPIO_NR(4, 5), !rst);
+}
+
+/*
+ * Bugfix: Fix Freescale wrong processor documentation.
+ */
+static void spl_mx6qd_dram_setup_iomux_check_reset(void)
+{
+	if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) {
+		volatile struct mx6dq_iomux_ddr_regs *mx6dq_ddr_iomux;
+
+		mx6dq_ddr_iomux = (struct mx6dq_iomux_ddr_regs *) MX6DQ_IOM_DDR_BASE;
+
+		if (mx6dq_ddr_iomux->dram_reset == (u32)0x000C0030)
+			mx6dq_ddr_iomux->dram_reset = (u32)0x00000030;
+	}
+}
+
+static void spl_dram_init(void)
+{
+	int err = is_dart_board() ?
+		var_eeprom_v2_dram_init() :
+		var_eeprom_v1_dram_init();
+
+	if (err) {
+		printf("Error initializing RAM using EEPROM\n");
+		hang();
+	}
+	spl_mx6qd_dram_setup_iomux_check_reset();
+}
+
+void board_init_f(ulong dummy)
+{
+	/* setup AIPS and disable watchdog */
+	arch_cpu_init();
+
+	ccgr_init();
+	gpr_init();
+
+	setup_iomux_var_per_vcc_en();
+	setup_iomux_audiocodec();
+	audiocodec_reset(1);
+
+	/* iomux and setup of i2c */
+	board_early_init_f();
+
+	/* setup GP timer */
+	timer_init();
+
+	mdelay(330);
+
+	audiocodec_reset(0);
+
+	/* UART clocks enabled and gd valid - init serial console */
+	preloader_console_init();
+
+	/* DDR initialization */
+	spl_dram_init();
+
+	/* Clear the BSS. */
+	memset(__bss_start, 0, __bss_end - __bss_start);
+
+	/* load/boot image from boot device */
+	board_init_r(NULL, 0);
+}
+#endif
diff --git a/board/variscite/mx6var_som/values.inc b/board/variscite/mx6var_som/values.inc
new file mode 100644
index 0000000..aafc088
--- /dev/null
+++ b/board/variscite/mx6var_som/values.inc
@@ -0,0 +1,39 @@
+0x00000000,0x00000010,0x00000013,0x00000017,
+0x00000027,0x00000028,0x00000030,0x00000038,
+0x00000047,0x00000053,0x00000080,0x000000DD,
+0x0000020E,0x00000800,0x00001740,0x0000174C,
+0x00001800,0x000026D2,0x00003000,0x00003030,
+0x00005800,0x00007800,0x00008000,0x00008033,
+0x0000803B,0x00011006,0x00011117,0x00011740,
+0x00020000,0x00020025,0x0002002D,0x00020036,
+0x00022227,0x00025565,0x0002556D,0x00025576,
+0x00048031,0x00048039,0x00080000,0x00081740,
+0x000C0000,0x000C0030,0x00130029,0x00160E83,
+0x0019002E,0x001C0019,0x001D002C,0x001F0019,
+0x001F001F,0x001F002B,0x00220AAC,0x0024001F,
+0x00260026,0x00333030,0x00333040,0x003F1023,
+0x003F8030,0x003F8038,0x00400000,0x00431023,
+0x00450000,0x005A1023,0x006B1023,0x008E1023,
+0x008F1023,0x017B017A,0x01FF00DB,0x02008032,
+0x0200803A,0x02038030,0x02088032,0x0208803A,
+0x0214021C,0x021B08B8,0x02280228,0x02300238,
+0x02580258,0x03038038,0x03200314,0x032C0278,
+0x033C0350,0x04008032,0x0400803A,0x04008040,
+0x04008048,0x04088032,0x0408803A,0x05208030,
+0x05208038,0x052C0470,0x052C0520,0x06028030,
+0x06028038,0x07208030,0x09408030,0x09444040,
+0x0F9F26D2,0x11420000,0x15208030,0x15208038,
+0x19408030,0x19408038,0x1B5F01FF,0x20000000,
+0x24911492,0x24921492,0x2B35382B,0x3234342C,
+0x33333333,0x38362E32,0x38363236,0x38383E3A,
+0x3A363446,0x3A38443C,0x3A3F7975,0x3E363A40,
+0x3E373A3C,0x3E463E40,0x3F435313,0x4036363A,
+0x403C3246,0x40404040,0x421C0216,0x421C0228,
+0x423D3843,0x42440244,0x43240334,0x432C0340,
+0x4528053C,0x45300544,0x454A61A5,0x46344840,
+0x48364A3E,0x484A4C4A,0x4B2B4842,0x4B4A4E4C,
+0x555A7974,0x676B5313,0x821A0000,0x83110000,
+0x831A0000,0x84190000,0x841A0000,0x8A8F7955,
+0xA1390003,0xB66D8B63,0xB66E8B63,0xC2018030,
+0xC2018038,0xC41A0000,0xDB538F64,0xF3333333,
+0xFF0A8030,0xFF0A8038,0xFF328F64,0xFFFFFFFF
diff --git a/configs/mx6var_som_nand_defconfig b/configs/mx6var_som_nand_defconfig
new file mode 100644
index 0000000..1a38095
--- /dev/null
+++ b/configs/mx6var_som_nand_defconfig
@@ -0,0 +1,31 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MX6=y
+CONFIG_TARGET_MX6VAR_SOM=y
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,SPL,MX6QDL,SYS_BOOT_NAND"
+CONFIG_HUSH_PARSER=y
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_USB=y
+CONFIG_USB_GADGET=y
+CONFIG_CI_UDC=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_G_DNL_MANUFACTURER="Variscite"
+CONFIG_G_DNL_VENDOR_NUM=0x0525
+CONFIG_G_DNL_PRODUCT_NUM=0xa4a5
+CONFIG_OF_LIBFDT=y
diff --git a/configs/mx6var_som_sd_defconfig b/configs/mx6var_som_sd_defconfig
new file mode 100644
index 0000000..6ccac65
--- /dev/null
+++ b/configs/mx6var_som_sd_defconfig
@@ -0,0 +1,31 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MX6=y
+CONFIG_TARGET_MX6VAR_SOM=y
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,SPL,MX6QDL"
+CONFIG_HUSH_PARSER=y
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_USB=y
+CONFIG_USB_GADGET=y
+CONFIG_CI_UDC=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_G_DNL_MANUFACTURER="Variscite"
+CONFIG_G_DNL_VENDOR_NUM=0x0525
+CONFIG_G_DNL_PRODUCT_NUM=0xa4a5
+CONFIG_OF_LIBFDT=y
diff --git a/include/configs/mx6var_som.h b/include/configs/mx6var_som.h
new file mode 100644
index 0000000..1860502
--- /dev/null
+++ b/include/configs/mx6var_som.h
@@ -0,0 +1,429 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
+ *
+ * Author: Eran Matityahu <eran.m at variscite.com>
+ *
+ * Configuration settings for Variscite VAR-SOM-MX6 board family.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __MX6VAR_SOM_CONFIG_H
+#define __MX6VAR_SOM_CONFIG_H
+
+#ifdef CONFIG_SPL
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#ifdef CONFIG_SYS_BOOT_NAND
+#define CONFIG_SPL_NAND_SUPPORT
+#else
+#define CONFIG_SPL_MMC_SUPPORT
+#endif
+#include "imx6_spl.h"
+#endif
+#include "mx6_common.h"
+
+/* Address of reserved 4Bytes in OCRAM for sending RAM size from SPL to U-Boot */
+#define RAM_SIZE_ADDR	((CONFIG_SPL_TEXT_BASE) + (CONFIG_SPL_MAX_SIZE))
+
+#define CONFIG_MACH_VAR_SOM_MX6		4419
+#define CONFIG_MACH_TYPE		CONFIG_MACH_VAR_SOM_MX6
+
+#define CONFIG_MXC_UART_BASE		UART1_BASE
+#define CONFIG_CONSOLE_DEV		"ttymxc0"
+#define CONFIG_MMCROOT			"/dev/mmcblk0p2"
+
+#define CONFIG_IMX_THERMAL
+
+/* 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_SILENT_CONSOLE
+
+#define CONFIG_MXC_UART
+
+#define LOW_POWER_MODE_ENABLE
+
+/* MMC Configs */
+#define CONFIG_SYS_FSL_ESDHC_ADDR	0
+#define CONFIG_SYS_FSL_USDHC_NUM	2
+#define CONFIG_SYS_MMC_ENV_DEV		0
+#define CONFIG_SYS_MMC_ENV_PART		0
+#define CONFIG_SYS_MMC_IMG_LOAD_PART	1
+
+/* Ethernet Configs */
+#define CONFIG_FEC_MXC
+#define CONFIG_MII
+#define IMX_FEC_BASE			ENET_BASE_ADDR
+#define CONFIG_FEC_XCV_TYPE		RGMII
+#define CONFIG_ETHPRIME			"FEC"
+#define CONFIG_FEC_MXC_PHYADDR		7
+#define CONFIG_PHYLIB
+#define CONFIG_PHY_MICREL
+
+#ifdef CONFIG_BOOTDELAY
+#undef CONFIG_BOOTDELAY
+#endif
+#define CONFIG_BOOTDELAY		1
+
+#ifdef CONFIG_SYS_BOOT_NAND
+#define MFG_NAND_PARTITION "mtdparts=gpmi-nand:16m(boot),16m(kernel),16m(dtb),-(rootfs) "
+#else
+#define MFG_NAND_PARTITION ""
+#endif
+
+#ifdef CONFIG_SYS_BOOT_NAND
+#define MMC_DEV_SET " "
+#else
+#define MMC_DEV_SET "mmcdev=" __stringify(CONFIG_SYS_MMC_ENV_DEV)
+#endif
+
+#define MFG_ENV_SETTINGS \
+	"mfgtool_args=setenv bootargs console=${console},${baudrate} " \
+		"rdinit=/linuxrc " \
+		"g_mass_storage.stall=0 g_mass_storage.removable=1 " \
+		"g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF "\
+		"g_mass_storage.iSerialNumber=\"\" "\
+		"enable_wait_mode=off "\
+		MFG_NAND_PARTITION \
+		"\0" \
+	"initrd_addr=0x12C00000\0" \
+	"initrd_high=0xffffffff\0" \
+	"bootcmd_mfg=run mfgtool_args;bootm ${loadaddr} ${initrd_addr} ${fdt_addr};\0" \
+
+#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+
+#define MMC_BOOT_ENV_SETTINGS \
+	"uimage=uImage\0" \
+	"boot_fdt=try\0" \
+	"ip_dyn=yes\0" \
+	MMC_DEV_SET \
+	"\0" \
+	"mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \
+	"mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \
+	"mmcautodetect=yes\0" \
+	"mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}; " \
+		"run videoargs\0" \
+	"loadbootscript=" \
+		"fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
+	"bootscript=echo Running bootscript from mmc ...; " \
+		"source\0" \
+	"loaduimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${uimage}\0" \
+	"loadfdt=run findfdt; " \
+		"fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
+	"mmcboot=echo Booting from mmc ...; " \
+		"run mmcargs; " \
+		"if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
+			"if run loadfdt; then " \
+				"bootm ${loadaddr} - ${fdt_addr}; " \
+			"else " \
+				"if test ${boot_fdt} = try; then " \
+					"bootm; " \
+				"else " \
+					"echo WARN: Cannot load the DT; " \
+				"fi; " \
+			"fi; " \
+		"else " \
+			"bootm; " \
+		"fi;\0" \
+
+
+#define NAND_BOOT_ENV_SETTINGS \
+	"bootargs_nand=setenv bootargs console=${console},${baudrate} ubi.mtd=3 " \
+		"root=ubi0:rootfs rootfstype=ubifs; " \
+		"run videoargs\0" \
+	"bootargs_emmc=setenv bootargs console=${console},${baudrate} " \
+		"root=/dev/mmcblk0p1 rootwait rw; " \
+		"run videoargs\0" \
+	"rootfs_device=nand\0" \
+	"bootcmd=" \
+		"if test ${rootfs_device} != emmc; then " \
+			"run bootargs_nand; " \
+		"else " \
+			"run bootargs_emmc; " \
+		"fi; " \
+		"nand read ${loadaddr} 0x400000 0x600000;" \
+		"nand read ${fdt_addr} 0x3e0000 0x20000;" \
+		"bootm ${loadaddr} - ${fdt_addr}\0" \
+	"mtdids=" MTDIDS_DEFAULT "\0" \
+	"mtdparts=" MTDPARTS_DEFAULT "\0" \
+
+
+#ifdef CONFIG_SYS_BOOT_NAND
+#define BOOT_ENV_SETTINGS	NAND_BOOT_ENV_SETTINGS
+#else
+#define BOOT_ENV_SETTINGS	MMC_BOOT_ENV_SETTINGS
+#define CONFIG_BOOTCOMMAND \
+	"mmc dev ${mmcdev};" \
+	"if mmc rescan; then " \
+		"if run loadbootscript; then " \
+			"run bootscript; " \
+		"else " \
+			"if run loaduimage; then " \
+				"run mmcboot; " \
+			"else " \
+				"run netboot; " \
+			"fi; " \
+		"fi; " \
+	"else run netboot; fi"
+#endif
+
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	MFG_ENV_SETTINGS \
+	BOOT_ENV_SETTINGS \
+	"fdt_file=undefined\0" \
+	"fdt_addr=0x18000000\0" \
+	"fdt_high=0xffffffff\0" \
+	"splashsourceauto=yes\0" \
+	"splashfile=/boot/splash.bmp\0" \
+	"splashimage=0x18100000\0" \
+	"splashenable=setenv splashfile /boot/splash.bmp; " \
+		"setenv splashimage 0x18100000\0" \
+	"splashdisable=setenv splashfile; setenv splashimage\0" \
+	"console=" CONFIG_CONSOLE_DEV "\0" \
+	"netargs=setenv bootargs console=${console},${baudrate} " \
+		"root=/dev/nfs rw " \
+		"ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp; " \
+		"run videoargs\0" \
+	"netboot=echo Booting from net ...; " \
+		"run netargs; " \
+		"if test ${ip_dyn} = yes; then " \
+			"setenv get_cmd dhcp; " \
+		"else " \
+			"setenv get_cmd tftp; " \
+		"fi; " \
+		"${get_cmd} ${uimage}; " \
+		"if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
+			"run findfdt; " \
+			"if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \
+				"bootm ${loadaddr} - ${fdt_addr}; " \
+			"else " \
+				"if test ${boot_fdt} = try; then " \
+					"bootm; " \
+				"else " \
+					"echo WARN: Cannot load the DT; " \
+				"fi; " \
+			"fi; " \
+		"else " \
+			"bootm; " \
+		"fi;\0" \
+	"videoargs=" \
+		"if hdmidet; then " \
+			"setenv bootargs ${bootargs} " \
+				"video=mxcfb0:dev=hdmi,1920x1080M at 60,if=RGB24; " \
+		"fi; " \
+		"setenv bootargs ${bootargs} " \
+			"video=mxcfb1:off;\0" \
+	"findfdt="\
+		"if test $fdt_file = undefined; then " \
+			"if test $board_name = DT6CUSTOM && test $board_rev = MX6Q; then " \
+				"setenv fdt_file imx6q-var-dart.dtb; " \
+			"fi; " \
+			"if test $board_name = SOLOCUSTOM && test $board_rev = MX6Q; then " \
+				"setenv fdt_file imx6q-var-som-vsc.dtb; " \
+			"fi; " \
+			"if test $board_name = SOLOCUSTOM && test $board_rev = MX6DL && test $board_som = SOM-SOLO; then " \
+				"setenv fdt_file imx6dl-var-som-solo-vsc.dtb; " \
+			"fi; " \
+			"if test $board_name = SOLOCUSTOM && test $board_rev = MX6DL && test $board_som = SOM-MX6; then " \
+				"setenv fdt_file imx6dl-var-som-vsc.dtb; " \
+			"fi; " \
+			"if test $board_name = MX6CUSTOM && test $board_rev = MX6Q; then " \
+				"i2c dev 2; " \
+				"if i2c probe 0x38; then " \
+					"setenv fdt_file imx6q-var-som-cap.dtb; " \
+				"else " \
+					"setenv fdt_file imx6q-var-som-res.dtb; " \
+				"fi; " \
+			"fi; " \
+			"if test $board_name = MX6CUSTOM && test $board_rev = MX6DL && test $board_som = SOM-SOLO; then " \
+				"i2c dev 2; " \
+				"if i2c probe 0x38; then " \
+					"setenv fdt_file imx6dl-var-som-solo-cap.dtb; " \
+				"else " \
+					"setenv fdt_file imx6dl-var-som-solo-res.dtb; " \
+				"fi; " \
+			"fi; " \
+			"if test $board_name = MX6CUSTOM && test $board_rev = MX6DL && test $board_som = SOM-MX6; then " \
+				"i2c dev 2; " \
+				"if i2c probe 0x38; then " \
+					"setenv fdt_file imx6dl-var-som-cap.dtb; " \
+				"else " \
+					"setenv fdt_file imx6dl-var-som-res.dtb; " \
+				"fi; " \
+			"fi; " \
+			"if test $fdt_file = undefined; then " \
+				"echo WARNING: Could not determine dtb to use; " \
+			"fi; " \
+		"fi;\0"
+
+
+#define CONFIG_ARP_TIMEOUT		200UL
+
+#define CONFIG_SYS_MEMTEST_START	0x10000000
+#define CONFIG_SYS_MEMTEST_END		0x10010000
+#define CONFIG_SYS_MEMTEST_SCRATCH	0x10800000
+
+#define CONFIG_STACKSIZE		(128 * 1024)
+
+/* Physical 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
+#define CONFIG_SYS_INIT_RAM_SIZE	IRAM_SIZE
+
+#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)
+
+/* FLASH and environment organization */
+#define CONFIG_ENV_SIZE			(8 * 1024)
+
+#ifdef CONFIG_SYS_BOOT_NAND
+#define CONFIG_SYS_USE_NAND
+#define CONFIG_ENV_IS_IN_NAND
+/* NAND boot config */
+#define CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_NAND_U_BOOT_OFFS	0x200000
+#define CONFIG_SYS_NAND_PAGE_SIZE	2048
+#else
+#define CONFIG_ENV_IS_IN_MMC
+#endif
+
+#ifdef CONFIG_SYS_USE_NAND
+#define CONFIG_CMD_NAND
+#define CONFIG_CMD_NAND_TRIMFFS
+
+/* UBI/UBIFS support */
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS
+#define CONFIG_UBI_SILENCE_MSG
+#define CONFIG_UBIFS_SILENCE_MSG
+#define CONFIG_RBTREE
+#define CONFIG_MTD_DEVICE
+#define CONFIG_MTD_PARTITIONS
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_LZO
+
+#define MTDIDS_DEFAULT		"nand0=nandflash-0"
+
+/*
+ * Partions' layout for NAND is:
+ *     mtd0: 2M       (spl) First boot loader
+ *     mtd1: 2M       (u-boot, dtb)
+ *     mtd2: 6M       (kernel)
+ *     mtd4: left     (rootfs)
+ */
+/* Default mtd partition table */
+#define MTDPARTS_DEFAULT	"mtdparts=nandflash-0:"\
+					"2m(spl),"\
+					"2m(u-boot),"\
+					"6m(kernel),"\
+					"-(rootfs)"	/* ubifs */
+
+/* NAND stuff */
+#define CONFIG_NAND_MXS
+#define CONFIG_SYS_MAX_NAND_DEVICE	1
+#define CONFIG_SYS_NAND_BASE		0x40000000
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+
+/* DMA stuff, needed for GPMI/MXS NAND support */
+#define CONFIG_APBH_DMA
+#define CONFIG_APBH_DMA_BURST
+#define CONFIG_APBH_DMA_BURST8
+#endif
+
+#if defined(CONFIG_ENV_IS_IN_MMC)
+#define CONFIG_ENV_OFFSET		(0x3E0000)
+#elif defined(CONFIG_ENV_IS_IN_NAND)
+#undef CONFIG_ENV_SIZE
+#define CONFIG_ENV_OFFSET		(0x180000)
+#define CONFIG_ENV_SECT_SIZE		(128 << 10)
+#define CONFIG_ENV_SIZE			CONFIG_ENV_SECT_SIZE
+#endif
+
+/* Framebuffer */
+#define CONFIG_VIDEO
+#define CONFIG_VIDEO_IPUV3
+#define CONFIG_CFB_CONSOLE
+#define CONFIG_VGA_AS_SINGLE_DEVICE
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+#define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
+#define CONFIG_VIDEO_BMP_RLE8
+#define CONFIG_SPLASH_SCREEN
+#define CONFIG_SPLASH_SCREEN_ALIGN
+#define CONFIG_SPLASH_SOURCE
+#define CONFIG_BMP_16BPP
+#define CONFIG_VIDEO_LOGO
+#define CONFIG_VIDEO_BMP_LOGO
+#ifdef CONFIG_MX6DL
+#define CONFIG_IPUV3_CLK 198000000
+#else
+#define CONFIG_IPUV3_CLK 264000000
+#endif
+#define CONFIG_IMX_HDMI
+#define CONFIG_CMD_HDMIDETECT
+#define CONFIG_IMX_VIDEO_SKIP
+#define CONFIG_CMD_BMP
+
+#define PMIC_I2C_BUS		1
+#define MX6CB_CDISPLAY_I2C_BUS	2
+#define MX6CB_CDISPLAY_I2C_ADDR	0x38
+
+/* I2C Configs */
+#define CONFIG_SYS_I2C
+#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C1		/* enable I2C bus 1 */
+#define CONFIG_SYS_I2C_MXC_I2C2		/* enable I2C bus 2 */
+#define CONFIG_SYS_I2C_MXC_I2C3		/* enable I2C bus 3 */
+#define CONFIG_SYS_I2C_SPEED		100000
+
+/* PMIC */
+#define CONFIG_POWER
+#define CONFIG_POWER_I2C
+#define CONFIG_POWER_PFUZE100
+#define CONFIG_POWER_PFUZE100_I2C_ADDR	0x08
+
+/* USB Configs */
+#ifdef CONFIG_CMD_USB
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_MX6
+#define CONFIG_USB_STORAGE
+#define CONFIG_EHCI_HCD_INIT_AFTER_RESET
+#define CONFIG_USB_HOST_ETHER
+#define CONFIG_USB_ETHER_ASIX
+#define CONFIG_MXC_USB_PORTSC		(PORT_PTS_UTMI | PORT_PTS_PTW)
+#define CONFIG_MXC_USB_FLAGS		0
+#define CONFIG_USB_MAX_CONTROLLER_COUNT	2 /* Enabled USB controller number */
+#endif
+
+#define CONFIG_USBD_HS
+
+/* Uncomment for USB Ethernet Gadget support */
+/*
+ * #define CONFIG_USB_ETHER
+ * #define CONFIG_USB_ETH_CDC
+ */
+#define CONFIG_NETCONSOLE
+
+#define CONFIG_USB_FUNCTION_MASS_STORAGE
+
+/* USB Device Firmware Update support */
+#define CONFIG_CMD_DFU
+#define CONFIG_USB_FUNCTION_DFU
+#define CONFIG_DFU_MMC
+#define CONFIG_DFU_RAM
+#ifdef CONFIG_SYS_USE_NAND
+#define CONFIG_SYS_MAX_NAND_DEVICE	1
+#define CONFIG_DFU_NAND
+#endif
+
+#endif	/* __MX6VAR_SOM_CONFIG_H */
diff --git a/tools/logos/variscite.bmp b/tools/logos/variscite.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..f3ca27ceb169cd5d174fa919248968877cb0e3d3
GIT binary patch
literal 15414
zcmeHO34B!LwU2kgL_-?_NHAh*x%YW*oFT>rL2W at 1H!9Ey5zD at apnzf#MH;{mV~o*=
z6n&VdJdo9}8iv3iVKoq03NnF<0ok<4kPu*!FqZ;F&pYRQ_s(MTMEYxgCYA$t`Id9;
z`G05m&Nuw%+OuP)2&Rsa5fO>_b{wxRcwG~5E#3ufjfse$3p>RX5dj^4l?)wIQsAyT
z+QYB!>IlEN^DgLo_uX*cJ)NOzmwVy<d%M5`UAscJ2Oos)-5!SS4|ju}k30gse%BNF
z^zIFP`#c5%`}KpNg9pQtLx;fdAw%KGVZ&h5$dNGm>8IeCQKMnp*s<{9`0?<k2 at _yS
zS{lsxLnO at ZE5V${uY>uiHkkLg1Pkz*pV|aIO0{D<65ElGkA3-%H-ULLcR}B4 at EHjU
z at ye%n<jp7kzSqKne%ImkGnn5m78dny4)X>#hlPXiIiM9R=pP632DXMpgIYoUpcb&C
z|MjqVa2zZeasw<JoB&G(-vEn;;`p$eVezmVVZm at 27C+GzmJgF*=|~xtjc5z`Puv1a
zM%;q$x4??gDtt5|5ta;3gym1&3d=@2VdW?XEFY5sE1yY$g3))t%4hF at 6@Tmit`|DN
z$1ijN*MzRHYU2H{>ZM0uO<GSVO6vw|UhWNRCqD}7r}Tn#>3v}8lqs+_<M*&GBNf)Y
zIsn$aIS at 9!IRrMnJ`^_PJPliNhQa1(!=d=?r{L4vF|c*Uv#@=}bFgLRc-S^`99}O%
zao+Q=<AVwC*?VbF^8O^)H7gBv%}s}_%uLA1&W7AK-hk=Troo at zo(}KMm;re+XTq!x
z-iHro&xZMP=Ry9$MX-G7QYcul0#><Puy)NFSYK2GJ7-UY-E%VGFLSeC_kuTIPkt`!
z&3_d<OWp$g<F{e=lIhr<0sEIuhtd`Afxhw`yk^3F*DNS2oCEt-&xJ3F7D3tCxo~j(
zA~>>fF&y5s3^s4v2#2>Uh9jGo!;w!{!k1fJ at MZC8IQp3zj+U&4V>>>9uS!<K*E?3j
z at sf4;TnB&Mvk at wGZ-OnGHpAB9V%T0%0=stZguS1C4*U1*gR%n$;NTZ!aOmJ6DBrUM
zyrm^jrEdf8{#{UcU<Y2i;l#n+P<e0{RF&<9ibH$h#9<vy9^4D34te0zky3o>P<41e
zoIY{@jvqS))kn(U)NviEj~|3HUmpVB*N5SB#Zjm$KMEBU6;SE*!imZgP=!}@bv4v@
zzk;)sUqNkUIT$A^z<<gMwI?gVUtI}xr%!@$<|Ndd at quyr6r4YE8qU?62477L)Zk^*
z)`DReaN%q%T=3Vy`Ev$bI(H5(o<9edF8mG7|Lr`SyLb^UT(|(2 at cH*|F2W_ezWMtl
zxcJRC at a?zX0!H at _y+mU8sorrRf5H?I at e>Az(5~WZ-1fa{zpM6Z$SZKwKO3 at jF0b2v
zp#AEO?^^O+ZtlBtH<$S?zd#Lq#y{Ba%UL5H?4ZetBFoA5^q=;Z2Co0*)C<Sw|6<&I
zn&xb)%1BCEr`oQ=6YFX(C!-;chvD<hxLa}j;x;w!qoqh6z2DZU-K?o&ju`$h2)<RB
z>1i3+Zt`9q(rMww^y&-u=ws#O<;Ti{%)V7w8IvYuWVxz>ee`zLlbw+^<&_*g*zMDa
zHKfBZbhpdp4(ZWzUYR^8BYTI*6t1M%8N}!JmkmgCXtJz5Qq5ESXHzw&;=E0Hcx at PK
zPBTf8Y<R_H)wt|YNNq@%n_lg4p_+T_Hl%0^pgSQ7xtO97Jf;Hl$Z1L9knHh=R<~PX
z-oSe4X-#R8&F&U6d at JMZ%p=)iU#sE1v%WArxi5&%*xX%FHK(RHo-^%Lo2w~KS#c;G
z-meRCX7GpU<2ETSof^`sBx()!HxDR;U8RvU>$+q7C0{0^r5+?HDvNvZ=7|eRwAm+{
z0^HZov}jA5C&rv);`?g?4Vxsz?L#?rRii(%WCor=eCzMmn3B{L)@V_Rf`q;8^8zmF
zVwr3|d}9E%mBg@`2g2}qxGPH7FO!!7k(r7{W{c0bV|bQzliCPK-?86K)*1+W<=0#D
z`6)HmQJ6pP*Y8x)QwZjJ0N<W&m@^ecb|^hgS`(^zDNZN#sws0Uo*P(TWZcUcFUMKm
zSWOH9Ukhu&X})Pc##bm5X__!~>P^uMHCm at RdaRIQZyGILq;%>w!tCewMwx?>js5c`
zA<Z7$)Xu=gsvPa1^({ttbu58z7QV{9!g`uR85>-Hmk2WsIJNse6+GqaWKtHv at O@}{
z9DnjM_G`nK5_A&dX~~TYdY{bt*`|1OeRUhwx(SO5x8HsNFE%|rT}P%I=C at CA>&Nu$
zSR1tpNZ2 at 8>yS$(43LFyqN+Fvp{#131O|-_Ns2Rxfh&)nWY`{7C&si=mQYS74ijH!
ze$hqzk^Q{al7`LA(N)YBkNqBD7!i!V1nQS2lejSZ8J;G at 9;MR=E^ITJX6LX#4`@we
zaWt^@c3IO>i!A at c9uwd8WML>xbMy#t;S;?S4LLN-GynA#2{252=AJ05*+i!i(?8G9
zyGay(l8xh!`Gn>;SjhNdag{Jz;d at Jqfzk5nh1+i*L9jJ5r at 43;63iARs8+4w;wX!i
zb;5)%-=13)KxpC{K~csek7YK$(DQk8PwZBm4oBxBG*HE{BZ2^%w2(HNP9ydBC&iy+
zyN>MV^AK?)8a1UNaxqqG;)!3fa;dL1r5`)(9pUy9_^jk5vNn4peK|;#y<|mGWu@=7
zvt}pbt1C%H+!Sb9lDdpXb`|lX=vN$nj9eH{M0QMpm&aR>dZG5SRN&DN`*E9YK0W(J
zGg+Vkyg#QE2rQT3E+8V=_1Vu7&dX!hNt{XkTDI8P{+J;#C8~E!Gb2IRZ#-Lx at TtFL
zGa1vKXNHO%9F+uJ?#(PBU?f{i{NyZmIpYhpUs(POi9gokwCA;i=C~`<q97F-Mma;Z
zi^Z~(<>&X|6FW*=>kx`>{VK5yapHDODPQfok;O2+$_E(*;nT)&w{L(zW4xepFW%(j
z^*mJ2ROm-)#x^BAL+uw^&6C6}Z2vR7SuN~jEJ2cu(q}p44JkT=$9k>TKgFQW+(|4^
z^pvFGG&oYh9SuDZ|Mp{ZFuo#9QP~9%_hPo&flkT7LD%sXPlFC6SBNi7kBua7LDFeJ
z#GlyI#Kf at u&+xPe@?c>Vn?sX?{Q^~r$w!axvmdW&@blu0vTofVnbHMr1?`{znuRgG
zncA%m(@YN><?g&&Zk|Xl{;KYrKXFu1hFbfk*OQZ();d;ft>O0L+`uC67HU6Vb4wxV
z8e8n-0udixR#nn1j^HyKUnw(N at n@C<qWm<MS|WF-=_|5`ocf8mgE78Q>TTqPGVbFe
zd6%nsQqg+R48QRbAtUgL+B0nD#N^;ID at UEw681Bz59+|3DY*X`*}{5~y~Wf5ok!{B
z<5VF9QlZX7F7!SAY4A2_FXWVrx2fdyEaUhCnCdl0@{56hW_$xNs}i9R=h9dGU)?J^
zlS>%tdX+7Xc}ebim^5MyM4~su@`uKsEt-<MNul<eB+Qp#4%gsf)2t~Bn_~xC<+R_}
zqe}7h`|S5RGqHn{j24JbvXe@?+ba&u at o1ocHuv{bVIj at o>{y1g>Wszc!pfV(Yn=KW
zx-@~86FVKiHrgSwi7k!C3`01bPA$`Zwq}K<YoLFI*bmnn|A^Ysc)ev@%a*MODwd_F
ztaa!S#d{1Puh)KNfaqKo#+gPEl`R!RMxH}cwP%lV3Zb^ZSM!)Gb~#lUj9va(;~5o?
zN~vN`nJ8?F4%&&<bv3V at d8QK|3bP+78=sz)kx9aJwwX9Th&?%*KaF0ASfi-o at Z!-A
zXT`EvJtDBu*gwU0%(W8nM+FZPTU|<HFEW|P#j6K7v>prCFU*OeKI@|<Qv4yPJnpZ0
zh%hB at V`VnTW at Rd~{rp0Q>kG at h<?eVs?L_fH3j5*afqx{aC8-i>zYkg8*urBK<?aN^
z2~um;*2R^jEjleb3s102->t7d%*>oh15!*T66HnqW1B5zGBWXIA;tSJnznaHdG3&f
zOgzo_6EP;Y|AKqh@^)|T2Q|GEG_RtxbBf$rz&c1xn#MFWj}JF76XTQ8%+s8}$5Vy<
ze6a*jvLTy5WR=I}c^M(|3fQDqSX|IQ{anMbC|o&lx^RgSNO0g#4BEfWH>TGj%fbSk
z8GmE()J`F$3>4kZvAe3NqV*Q;jcnasoYT){n2LxmV%4kjJU6waDK2q<VtgWhn&;a>
zvnr!mG*!Sr)(mQygecR6iXr($9GhqcGMb_45_Pa(lYUl6slIspacc(?n&X}A_dkll
zryxbRXEnPgZU{Sh+D`R00`F`$!sNmqU`%!BldW~p&1V8UA-K4{X<3WCB7a)HzZ9|s
zO^u>nGlk)!ASh32MsY+Gw4V`={%*42X3O4-vTqD1A+_Ewc<Q+`zT#xw-jmuN<QYY(
zu%<FYF#LhwVaYSy;`ipXiJ>2NBBPq6xvWkd&z|Y&s9t$S4E{1hR?riO(yYzM_c5}e
zi`k>&vUH1$p5C1JXzY)SzA?v|Yj}utcp8bxPEViA_?prebmBnr6%LQVIw~@{O+W=P
z5O!yLRS!`~swn-%(2H1$5ha at Kw`FdoYzX1>>pR?T^Sl$%O|O1D42AxT7dq_I-EMbj
z07P)e>p^kf4W8hzI3ES_r#V2<Jg0-R>Um>)#sn_H<UDp?OehW!aCh!yj;$$VKP5G^
zbgoC#zq8A%&#wFvjL*OQmx+q3bfV4OFgE`Ze}us*9Lt$m)b>}UI`P*F<sEALNF*ZJ
zsz0wl31Ppwr!_~Sqd%L^pX<=tX>`g^<RQ2N`u)bAR6H_v5ta89$o>~j6_vt2i?7aq
zpaX7sd47x?qq>ixa{S4fe2=hbaSB=&M}Isr?RVu02>ThvbXmPifZ2Jw?9}j(@078a
zo6Wx^R;D_&{{MgQU-?(Bn4{EA6!zo550hcxs~)Tls3DfxcPW{eq>L0lmQK{}quTmM
zBrj5VJ$d(XDp~l9&wu;J%^NmsE?VDT>;}9gC=aaNRE)hJbk674yqvU#Hy*%eY<Z}i
znv|s7Do((b1vM;elC;hrG(63Jm_|W-#<t#6XR4xjG4VO^bSpc$%%feqQBnv#qwFcf
z$F(%0<3mKEoFqRMTDUYal%e>HQwtxJ#bJS>kD$t`+WrkXaWz&7#fRIU_rJR<?FgG7
zS-W%Gfv|sXYHT<|@v-hz%SQb^g?__V)ui7H``_b at 4bXS={RezFUcKj&`S1OC_VSX7
zMw(PYFxH2!(I(3fT-Iy-_^i>!|GbK?aog~!{jS=tA+Nwy|7^(Cxx8*y?RWV#YREHw
Ls{bo4fb0JN2LML%

literal 0
HcmV?d00001

-- 
1.9.1




More information about the U-Boot mailing list