[meta-freescale] [meta-fsl-arm-extra][PATCH 2/3] u-boot-armadeus: add Armadeus u-boot for APF6 boards

Vincent Dehors vincent.dehors at gmail.com
Fri May 22 09:39:52 PDT 2015


This commit allow to build u-boot compatible with APF6 boards. This u-boot
is based on the legacy u-boot version 2014.07. All the patches come from
the Armadeus BSP.
---
 ...-restore-command-env-param-compatitbility.patch |   15 +
 .../040-i2c-mxc-fix-mx51-i2c-declaration.patch     |   41 +
 .../u-boot/u-boot-armadeus/102-mx1-i2c.patch       |   46 +
 .../u-boot/u-boot-armadeus/103-apf9328.patch       | 1153 +++++++++++++++++++
 .../u-boot-armadeus/104-apf9328-makefile.patch     |   22 +
 .../u-boot/u-boot-armadeus/106-mx1-pllclk.patch    |   63 ++
 .../u-boot-armadeus/107-mx1-pllclk-debug.patch     |   26 +
 .../u-boot/u-boot-armadeus/108-DM9000.patch        |   48 +
 .../u-boot/u-boot-armadeus/111-mx1-timer.patch     |   25 +
 .../300-imx27-fix_dcache_boot_issue.patch          |   22 +
 .../302-apf27-support-boot-from-RAM.patch          |   48 +
 .../u-boot-armadeus/311-imx-nand-lock-unlock.patch |   98 ++
 .../u-boot/u-boot-armadeus/320-spartan.patch       |   71 ++
 .../u-boot-armadeus/340-apf27-misc-commands.patch  |  376 +++++++
 .../350-nand_large_file_download.patch             |  265 +++++
 ...60-arm-support-continuous-mmu-mem-mapping.patch |   94 ++
 recipes-bsp/u-boot/u-boot-armadeus/400-imx51.patch |  522 +++++++++
 recipes-bsp/u-boot/u-boot-armadeus/401-apf51.patch | 1001 +++++++++++++++++
 .../u-boot/u-boot-armadeus/410-imx-iim.patch       |  502 +++++++++
 .../u-boot-armadeus/420-apf51-nand-spl-NG.patch    |  361 ++++++
 .../u-boot-armadeus/501-imx28-update-and-fix.patch |   60 +
 .../u-boot/u-boot-armadeus/502-add-apf28.patch     | 1186 ++++++++++++++++++++
 .../u-boot/u-boot-armadeus/503-add-apf6.patch      |  945 ++++++++++++++++
 ...4-apf6-seek_uboot_image_in_boot_partition.patch |   18 +
 ..._bootstrap_get_uboot_image_on_serial_port.patch |   16 +
 .../506-apf6-in_bootstrap_dont_use_env_vars.patch  |   30 +
 recipes-bsp/u-boot/u-boot-armadeus/apf6-config.h   |  318 ++++++
 recipes-bsp/u-boot/u-boot-armadeus_2014.07.bb      |   52 +
 28 files changed, 7424 insertions(+)
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/001-restore-command-env-param-compatitbility.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/040-i2c-mxc-fix-mx51-i2c-declaration.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/102-mx1-i2c.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/103-apf9328.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/104-apf9328-makefile.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/106-mx1-pllclk.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/107-mx1-pllclk-debug.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/108-DM9000.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/111-mx1-timer.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/300-imx27-fix_dcache_boot_issue.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/302-apf27-support-boot-from-RAM.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/311-imx-nand-lock-unlock.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/320-spartan.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/340-apf27-misc-commands.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/350-nand_large_file_download.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/360-arm-support-continuous-mmu-mem-mapping.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/400-imx51.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/401-apf51.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/410-imx-iim.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/420-apf51-nand-spl-NG.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/501-imx28-update-and-fix.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/502-add-apf28.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/503-add-apf6.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/504-apf6-seek_uboot_image_in_boot_partition.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/505-apf6-in_bootstrap_get_uboot_image_on_serial_port.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/506-apf6-in_bootstrap_dont_use_env_vars.patch
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus/apf6-config.h
 create mode 100644 recipes-bsp/u-boot/u-boot-armadeus_2014.07.bb

diff --git a/recipes-bsp/u-boot/u-boot-armadeus/001-restore-command-env-param-compatitbility.patch b/recipes-bsp/u-boot/u-boot-armadeus/001-restore-command-env-param-compatitbility.patch
new file mode 100644
index 0000000..d1700d0
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/001-restore-command-env-param-compatitbility.patch
@@ -0,0 +1,15 @@
+restore command env param compatitbility with legacy U-Boot versions
+
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+---
+--- uboot-custom/common/cmd_nvedit.c
++++ uboot-custom/common/cmd_nvedit.c
+@@ -749,7 +749,7 @@ static int do_env_default(cmd_tbl_t *cmd
+ 		}
+ 	}
+ 	debug("Final value for argc=%d\n", argc);
+-	if (all && (argc == 0)) {
++	if ((all || (flag & H_FORCE)) && (argc == 0)) {
+ 		/* Reset the whole environment */
+ 		set_default_env("## Resetting to default environment\n");
+ 		return 0;
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/040-i2c-mxc-fix-mx51-i2c-declaration.patch b/recipes-bsp/u-boot/u-boot-armadeus/040-i2c-mxc-fix-mx51-i2c-declaration.patch
new file mode 100644
index 0000000..50fcc7a
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/040-i2c-mxc-fix-mx51-i2c-declaration.patch
@@ -0,0 +1,41 @@
+From 8cc45b2a0332154b9ef2deaa3085da90f4397da7 Mon Sep 17 00:00:00 2001
+From: Eric Jarrige <eric.jarrige at armadeus.org>
+Date: Tue, 13 May 2014 14:22:51 +0200
+Subject: [PATCH 1/1] i2c: mxc: fix mx51 i2c declaration
+
+
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+---
+ drivers/i2c/mxc_i2c.c |    8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
+index 595019b..a4280b4 100644
+--- a/drivers/i2c/mxc_i2c.c
++++ b/drivers/i2c/mxc_i2c.c
+@@ -421,8 +421,11 @@ static void * const i2c_bases[] = {
+ #elif defined(CONFIG_MX27)
+ 	(void *)IMX_I2C1_BASE,
+ 	(void *)IMX_I2C2_BASE
++#elif defined(CONFIG_MX51)
++	(void *)I2C1_BASE_ADDR,
++	(void *)I2C2_BASE_ADDR,
+ #elif defined(CONFIG_MX31) || defined(CONFIG_MX35) || \
+-	defined(CONFIG_MX51) || defined(CONFIG_MX53) ||	\
++	defined(CONFIG_MX53) ||	\
+ 	defined(CONFIG_MX6)
+ 	(void *)I2C1_BASE_ADDR,
+ 	(void *)I2C2_BASE_ADDR,
+@@ -544,8 +547,7 @@ U_BOOT_I2C_ADAP_COMPLETE(mxc1, mxc_i2c_init, mxc_i2c_probe,
+ 			 CONFIG_SYS_MXC_I2C2_SPEED,
+ 			 CONFIG_SYS_MXC_I2C2_SLAVE, 1)
+ #if defined(CONFIG_MX31) || defined(CONFIG_MX35) ||\
+-	defined(CONFIG_MX51) || defined(CONFIG_MX53) ||\
+-	defined(CONFIG_MX6)
++	defined(CONFIG_MX53) || defined(CONFIG_MX6)
+ U_BOOT_I2C_ADAP_COMPLETE(mxc2, mxc_i2c_init, mxc_i2c_probe,
+ 			 mxc_i2c_read, mxc_i2c_write,
+ 			 mxc_i2c_set_bus_speed,
+-- 
+1.7.9.5
+
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/102-mx1-i2c.patch b/recipes-bsp/u-boot/u-boot-armadeus/102-mx1-i2c.patch
new file mode 100644
index 0000000..ff78658
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/102-mx1-i2c.patch
@@ -0,0 +1,46 @@
+mx1: add i2c registers
+
+Add i2c registers for Freescale imx1/L/S
+
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+Signed-off-by: Philippe Reynes <tremyfr at yahoo.fr>
+Cc: Stefano Babic <sbabic at denx.de>
+---
+ arch/arm/include/asm/arch-imx/imx-regs.h |   23 +++++++++++++++++++++++
+ 1 files changed, 23 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/include/asm/arch-imx/imx-regs.h b/arch/arm/include/asm/arch-imx/imx-regs.h
+index 4de0779..1fd3e17 100644
+--- a/arch/arm/include/asm/arch-imx/imx-regs.h
++++ b/arch/arm/include/asm/arch-imx/imx-regs.h
+@@ -634,4 +634,27 @@
+ #define TSTAT_CAPT     (1<<1)  /* Capture event */
+ #define TSTAT_COMP     (1)     /* Compare event */
+ 
++/*
++ * I2C module
++ */
++#define IADR   __REG(IMX_I2C_BASE + 0x000) /* I2C Address Register */
++#define IFDR   __REG(IMX_I2C_BASE + 0x004) /* I2C Frequency Divider Register*/
++#define I2CR   __REG(IMX_I2C_BASE + 0x008) /* I2C Control Register */
++#define I2SR   __REG(IMX_I2C_BASE + 0x00C) /* I2C Status Register */
++#define I2DR   __REG(IMX_I2C_BASE + 0x010) /* I2C Data I/O Register */
++/* I2C Control Register Bit Fields */
++#define I2CR_IEN	(1<<7)		/* I2C Enable */
++#define I2CR_IIEN	(1<<6)		/* I2C Interrupt Enable */
++#define I2CR_MSTA	(1<<5)		/* I2C Master/Slave Mode Select */
++#define I2CR_MTX	(1<<4)		/* I2C Transmit/Receive Mode Select */
++#define I2CR_TXAK	(1<<3)		/* I2C Transmit Acknowledge Enable */
++#define I2CR_RSTA	(1<<2)		/* I2C Repeated START */
++#define I2SR_ICF	(1<<7)		/* I2C Data Transfer */
++#define I2SR_IAAS	(1<<6)		/* I2C Addressed As a Slave */
++#define I2SR_IBB	(1<<5)		/* I2C Bus Busy */
++#define I2SR_IAL	(1<<4)		/* I2C Arbitration Lost */
++#define I2SR_SRW	(1<<2)		/* I2C Slave Read/Write	*/
++#define I2SR_IIF	(1<<1)		/* I2C interrupt */
++#define I2SR_RXAK	(1<<0)		/* I2C Received Acknowledge */
++
+ #endif				/* _IMX_REGS_H */
+-- 
+1.7.2.5
+
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/103-apf9328.patch b/recipes-bsp/u-boot/u-boot-armadeus/103-apf9328.patch
new file mode 100644
index 0000000..4e7e1bb
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/103-apf9328.patch
@@ -0,0 +1,1153 @@
+apf9328: Add Armadeus Project board APF9328
+
+Add Armadeus Project board APF9328
+
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+Signed-off-by: Nicolas Colombain <nicolas.colombain at armadeus.com>
+Signed-off-by: Philippe Reynes <tremyfr at yahoo.fr>
+Cc: Nicolas Colombain <nicolas.colombain at armadeus.com>
+---
+ board/armadeus/apf9328/Makefile        |   51 ++++
+ board/armadeus/apf9328/apf9328.c       |  106 +++++++
+ board/armadeus/apf9328/apf9328fpga.c   |  100 +++++++
+ board/armadeus/apf9328/apf9328fpga.h   |   31 ++
+ board/armadeus/apf9328/eeprom.c        |   88 ++++++
+ board/armadeus/apf9328/fpga.c          |  121 ++++++++
+ board/armadeus/apf9328/fpga.h          |   30 ++
+ board/armadeus/apf9328/i2c.c           |  276 +++++++++++++++++++
+ board/armadeus/apf9328/lowlevel_init.S |  469 ++++++++++++++++++++++++++++++++
+ 9 files changed, 1272 insertions(+), 0 deletions(-)
+ create mode 100644 board/armadeus/apf9328/Makefile
+ create mode 100644 board/armadeus/apf9328/apf9328.c
+ create mode 100644 board/armadeus/apf9328/apf9328fpga.c
+ create mode 100644 board/armadeus/apf9328/apf9328fpga.h
+ create mode 100644 board/armadeus/apf9328/eeprom.c
+ create mode 100644 board/armadeus/apf9328/fpga.c
+ create mode 100644 board/armadeus/apf9328/fpga.h
+ create mode 100644 board/armadeus/apf9328/i2c.c
+ create mode 100644 board/armadeus/apf9328/lowlevel_init.S
+
+diff --git a/board/armadeus/apf9328/Makefile b/board/armadeus/apf9328/Makefile
+new file mode 100644
+index 0000000..0f097cd
+--- /dev/null
++++ b/board/armadeus/apf9328/Makefile
+@@ -0,0 +1,10 @@
++#
++# (C) Copyright 2000-2004
++# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
++#
++# SPDX-License-Identifier:    GPL-2.0+
++#
++
++obj-y	:= apf9328.o i2c.o eeprom.o
++obj-y	+= lowlevel_init.o
++obj-$(CONFIG_FPGA)	+= apf9328fpga.o fpga.o
+diff --git a/board/armadeus/apf9328/apf9328.c b/board/armadeus/apf9328/apf9328.c
+new file mode 100644
+index 0000000..280f749
+--- /dev/null
++++ b/board/armadeus/apf9328/apf9328.c
+@@ -0,0 +1,61 @@
++/*
++ * Copyright (C) 2005-2014
++ * Nicolas Colombain <nicolas.colombain at armadeus.com>
++ * Eric Jarrige <eric.jarrige at armadeus.org>
++ *
++ * SPDX-License-Identifier:    GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/arch/imx-regs.h>
++#include <flash.h>
++#include <netdev.h>
++#include "apf9328fpga.h"
++
++extern void imx_gpio_mode(int gpio_mode);
++
++DECLARE_GLOBAL_DATA_PTR;
++
++int board_init(void)
++{
++
++	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
++
++#ifdef CONFIG_DRIVER_DM9000
++	imx_gpio_mode(GPIO_PORTB | GPIO_DR | GPIO_IN | 14);
++#endif
++
++#ifdef CONFIG_FPGA
++	apf9328_init_fpga();
++#endif
++
++	return 0;
++}
++
++int dram_init(void)
++{
++	/* dram_init must store complete ramsize in gd->ram_size */
++	gd->ram_size = get_ram_size((void *)PHYS_SDRAM_1,
++				    PHYS_SDRAM_1_SIZE);
++	return 0;
++}
++
++void enable_caches(void)
++{
++#ifndef CONFIG_SYS_DCACHE_OFF
++	/* Enable D-cache. I-cache is already enabled in start.S */
++	dcache_enable();
++#endif
++}
++
++void show_boot_progress(int status)
++{
++	return;
++}
++
++#ifdef CONFIG_DRIVER_DM9000
++int board_eth_init(bd_t *bis)
++{
++	return dm9000_initialize(bis);
++}
++#endif
+diff --git a/board/armadeus/apf9328/apf9328fpga.c b/board/armadeus/apf9328/apf9328fpga.c
+new file mode 100644
+index 0000000..9782115
+--- /dev/null
++++ b/board/armadeus/apf9328/apf9328fpga.c
+@@ -0,0 +1,65 @@
++/*
++ * Copyright (C) 2005-2014
++ * Nicolas Colombain <nicolas.colombain at armadeus.com>
++ * Eric Jarrige <eric.jarrige at armadeus.org>
++ *
++ * SPDX-License-Identifier:    GPL-2.0+
++ */
++
++/*
++ * Spartan 3 FPGA configuration support for the APF9328 daughter board
++ */
++
++#include <common.h>
++#include <spartan3.h>
++#include <command.h>
++#include <jffs2/jffs2.h>
++#include <asm/arch/imx-regs.h>
++#include <asm/io.h>
++#include "apf9328fpga.h"
++
++#ifdef CONFIG_FPGA
++DECLARE_GLOBAL_DATA_PTR;
++/* Note that these are pointers to code that is in Flash.  They will be
++ * relocated at runtime.
++ * Spartan3 code is used to download our Spartan 3 :) code is compatible.
++ * Just take care about the file size
++*/
++xilinx_spartan3_slave_serial_fns fpga_fns = {
++	fpga_pre_fn,
++	fpga_pgm_fn,
++	fpga_clk_fn,
++	fpga_init_fn,
++	fpga_done_fn,
++	fpga_wr_fn,
++	fpga_post_fn,
++	NULL,
++	fpga_abort_fn,
++};
++
++xilinx_desc fpga[CONFIG_FPGA_COUNT] = {
++	{xilinx_spartan3,
++	 slave_serial,
++	 XILINX_XC3S400_SIZE,
++	 (void *)&fpga_fns,
++	 0,
++	 &spartan3_op }
++};
++
++/*
++ * Initialize the fpga.  Return 1 on success, 0 on failure.
++ */
++int apf9328_init_fpga(void)
++{
++	int i;
++
++	fpga_init();
++
++	for (i = 0; i < CONFIG_FPGA_COUNT; i++) {
++		fpga_add(fpga_xilinx, &fpga[i]);
++	}
++
++	return 0;
++}
++
++#endif /* CONFIG_FPGA */
+diff --git a/board/armadeus/apf9328/apf9328fpga.h b/board/armadeus/apf9328/apf9328fpga.h
+new file mode 100644
+index 0000000..2a15443
+--- /dev/null
++++ b/board/armadeus/apf9328/apf9328fpga.h
+@@ -0,0 +1,10 @@
++/*
++ * SPDX-License-Identifier:    GPL-2.0+
++ */
++
++/*
++ * Spartan 3 FPGA configuration support for the APF9328 daughter board
++ */
++
++#include "fpga.h"
++extern int apf9328_init_fpga(void);
+diff --git a/board/armadeus/apf9328/eeprom.c b/board/armadeus/apf9328/eeprom.c
+new file mode 100644
+index 0000000..c8165ea
+--- /dev/null
++++ b/board/armadeus/apf9328/eeprom.c
+@@ -0,0 +1,72 @@
++/*
++ * Copyright (C) 2008-2014 Armadeus Project
++ * Copyright (C) 2007
++ * Stefano Babic, DENX Software Engineering, sbabic at denx.de.
++ *
++ * SPDX-License-Identifier:    GPL-2.0+
++ */
++
++#include <common.h>
++#include <command.h>
++#include <dm9000.h>
++
++static int do_read_dm9000_eeprom(cmd_tbl_t *cmdtp, int flag, int argc,
++				 char * const argv[])
++{
++	unsigned int i;
++	u8 data[2];
++
++	for (i = 0; i < 0x40; i++) {
++		if (!(i % 0x10))
++			printf("\n%08x:", i);
++		dm9000_read_srom_word(i, data);
++		printf(" %02x%02x", data[1], data[0]);
++	}
++	printf("\n");
++	return 0;
++}
++
++static int do_write_dm9000_eeprom(cmd_tbl_t *cmdtp, int flag, int argc,
++				  char * const argv[])
++{
++	unsigned long offset, value;
++
++	if (argc < 4) {
++		cmd_usage(cmdtp);
++		return 1;
++	}
++
++	strict_strtoul(argv[2], 16, &offset);
++	strict_strtoul(argv[3], 16, &value);
++	if (offset > 0x40) {
++		printf("Wrong offset : 0x%lx\n", offset);
++		cmd_usage(cmdtp);
++		return 1;
++	}
++	dm9000_write_srom_word(offset, value);
++	return 0;
++}
++
++int do_dm9000_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
++{
++	if (argc < 2) {
++		cmd_usage(cmdtp);
++		return 1;
++	}
++
++	if (strcmp(argv[1], "read") == 0) {
++		return do_read_dm9000_eeprom(cmdtp, flag, argc, argv);
++	} else if (strcmp(argv[1], "write") == 0) {
++		return do_write_dm9000_eeprom(cmdtp, flag, argc, argv);
++	} else {
++		cmd_usage(cmdtp);
++		return 1;
++	}
++}
++
++U_BOOT_CMD(dm9000ee, 4, 1, do_dm9000_eeprom,
++	"Read/Write eeprom connected to Ethernet Controller",
++	"\ndm9000ee write <word offset> <value>\n"
++	"\tdm9000ee read\n"
++	"\tword:\t\t00-02 : MAC Address\n"
++	"\t\t\t03-07 : DM9000 Configuration\n" "\t\t\t08-63 : User data");
+diff --git a/board/armadeus/apf9328/fpga.c b/board/armadeus/apf9328/fpga.c
+new file mode 100644
+index 0000000..f3d4f03
+--- /dev/null
++++ b/board/armadeus/apf9328/fpga.c
+@@ -0,0 +1,116 @@
++/*
++ * Copyright (C) 2007
++ * Rich Ireland, Enterasys Networks, rireland at enterasys.com.
++ * Keith Outwater, keith_outwater at mvis.com.
++ *
++ * SPDX-License-Identifier:    GPL-2.0+
++ */
++#include <common.h>
++
++#ifdef CONFIG_FPGA
++
++#include <asm/arch/imx-regs.h>
++#include <asm/io.h>
++#include <config.h>
++
++extern void imx_gpio_mode(int gpio_mode);
++
++#define GPIO_PORT(x)  ((x >> 5) & 3)
++#define GPIO_SET(x)   (DR(GPIO_PORT(x)) |= (1<<(x & GPIO_PIN_MASK)))
++#define GPIO_CLEAR(x) (DR(GPIO_PORT(x)) &= ~(1<<(x & GPIO_PIN_MASK)))
++#define GPIO_WRITE(x, y) (y ? GPIO_SET(x) : GPIO_CLEAR(x))
++#define GPIO_READ(x)  ((SSR(GPIO_PORT(x)) & (1<<(x & GPIO_PIN_MASK))))
++
++/*
++ * Port bit numbers for the serial slave controls
++ */
++#define FPGA_INIT	CONFIG_SYS_FPGA_INIT
++#define FPGA_DONE	CONFIG_SYS_FPGA_DONE
++#define FPGA_DIN	CONFIG_SYS_FPGA_DATA
++#define FPGA_PROGRAM	CONFIG_SYS_FPGA_PRG
++#define FPGA_CLOCK	CONFIG_SYS_FPGA_CLK
++
++/* Note that these are pointers to code that is in Flash.  They will be
++ * relocated at runtime.
++ * Spartan2 code is used to download our Spartan 3 :) code is compatible.
++ * Just take care about the file size
++*/
++
++/*
++ * nitialize GPIO port B before download
++ */
++int fpga_pre_fn(int cookie)
++{
++	debug("%s:%d: FPGA PRE ", __func__, __LINE__);
++
++	/* Initialize GPIO pins */
++	imx_gpio_mode(FPGA_INIT | GPIO_DR | GPIO_IN);
++	imx_gpio_mode(FPGA_DONE | GPIO_DR | GPIO_IN);
++	imx_gpio_mode(FPGA_DIN | GPIO_DR | GPIO_OUT);
++	imx_gpio_mode(FPGA_PROGRAM | GPIO_DR | GPIO_OUT);
++	imx_gpio_mode(FPGA_CLOCK | GPIO_DR | GPIO_OUT);
++	return cookie;
++}
++
++/*
++ * Set the FPGA's active-low program line to the specified level
++ */
++int fpga_pgm_fn(int assert, int flush, int cookie)
++{
++	debug("%s:%d: FPGA PROGRAM %s", __func__, __LINE__,
++	       assert ? "high" : "low");
++	GPIO_WRITE(FPGA_PROGRAM, !assert);
++	return assert;
++}
++
++/*
++ * Set the FPGA's active-high clock line to the specified level
++ */
++int fpga_clk_fn(int assert_clk, int flush, int cookie)
++{
++	debug("%s:%d: FPGA CLOCK %s", __func__, __LINE__,
++	       assert_clk ? "high" : "low");
++	GPIO_WRITE(FPGA_CLOCK, assert_clk);
++	return assert_clk;
++}
++
++/*
++ * Test the state of the active-low FPGA INIT line.  Return 1 on INIT
++ * asserted (low).
++ */
++int fpga_init_fn(int cookie)
++{
++	debug("%s:%d: INIT check... ", __func__, __LINE__);
++	return !GPIO_READ(FPGA_INIT);
++}
++
++/*
++ * Test the state of the active-high FPGA DONE pin
++ */
++int fpga_done_fn(int cookie)
++{
++	debug("%s:%d: DONE check... ", __func__, __LINE__);
++	return GPIO_READ(FPGA_DONE);
++}
++
++/*
++ * Set the FPGA's data line to the specified level
++ */
++int fpga_wr_fn(int assert_write, int flush, int cookie)
++{
++	debug("%s:%d: DATA write... ", __func__, __LINE__);
++	GPIO_WRITE(FPGA_DIN, assert_write);
++	return assert_write;
++}
++
++int fpga_post_fn(int cookie)
++{
++	return cookie;
++}
++
++int fpga_abort_fn(int cookie)
++{
++	return fpga_post_fn(cookie);
++}
++
++#endif /* CONFIG_FPGA */
+diff --git a/board/armadeus/apf9328/fpga.h b/board/armadeus/apf9328/fpga.h
+new file mode 100644
+index 0000000..3b226d7
+--- /dev/null
++++ b/board/armadeus/apf9328/fpga.h
+@@ -0,0 +1,15 @@
++/*
++ * Copyright (C) 2002
++ * Rich Ireland, Enterasys Networks, rireland at enterasys.com.
++ * Keith Outwater, keith_outwater at mvis.com.
++ *
++ * SPDX-License-Identifier:    GPL-2.0+
++ */
++extern int fpga_pre_fn(int cookie);
++extern int fpga_pgm_fn(int assert_pgm, int flush, int cookie);
++extern int fpga_init_fn(int cookie);
++extern int fpga_done_fn(int cookie);
++extern int fpga_clk_fn(int assert_clk, int flush, int cookie);
++extern int fpga_wr_fn(int assert_write, int flush, int cookie);
++extern int fpga_post_fn(int cookie);
++extern int fpga_abort_fn(int cookie);
+diff --git a/board/armadeus/apf9328/i2c.c b/board/armadeus/apf9328/i2c.c
+new file mode 100644
+index 0000000..0ba0a8d
+--- /dev/null
++++ b/board/armadeus/apf9328/i2c.c
+@@ -0,0 +1,260 @@
++/*
++ * Copyright (C) 2005-2014 Eric Jarrige <eric.jarrige at armadeus.org>
++ *
++ * SPDX-License-Identifier:    GPL-2.0+
++ */
++
++#include <common.h>
++
++#ifdef CONFIG_HARD_I2C
++
++#include <asm/io.h>
++#include <asm/arch/imx-regs.h>
++#include <i2c.h>
++
++extern void imx_gpio_mode(int gpio_mode);
++
++/*-----------------------------------------------------------------------
++ * Definitions
++ */
++
++#define I2C_ACK		0	/* level to ack a byte */
++#define I2C_NOACK	1	/* level to noack a byte */
++
++/*-----------------------------------------------------------------------
++ * Local functions
++ */
++
++/*-----------------------------------------------------------------------
++ * START: High -> Low on SDA while SCL is High
++ * after check for a bus free
++ */
++static void imxi2c_send_start(void)
++{
++	while (I2SR & I2SR_IBB)
++		udelay(1);
++
++	I2CR |= I2CR_MSTA;
++	I2SR &= ~I2SR_IIF;
++}
++
++/*-----------------------------------------------------------------------
++ * STOP: Low -> High on SDA while SCL is High
++ * after the end of previous transfer
++ */
++static void imxi2c_send_stop(void)
++{
++	while (!(I2SR & I2SR_ICF))
++		udelay(1);
++
++	I2CR &= ~I2CR_MSTA;
++}
++
++/*-----------------------------------------------------------------------
++ * Send 8 bits and look for an acknowledgement.
++ */
++static int imxi2c_write_byte(uchar data)
++{
++	while (!(I2SR & I2SR_ICF))	/* Wait end of transfer */
++		udelay(1);
++
++	I2CR |= I2CR_MTX;
++	I2SR &= ~I2SR_IIF;
++	I2DR = data;
++
++	while (!(I2SR & I2SR_IIF))	/* checking IIF before ICF: FIXME */
++		udelay(1);
++
++	I2SR &= ~I2SR_IIF;
++
++	while (!(I2SR & I2SR_ICF))	/* Wait end of transfer */
++		udelay(1);
++
++	return I2SR & I2SR_RXAK;	/* not a nack is an ack */
++}
++
++/*-----------------------------------------------------------------------
++ * if ack == I2C_ACK, ACK the byte so can continue reading, else
++ * send I2C_NOACK to end the read.
++ */
++static uchar imxi2c_read_byte(int ack)
++{
++	int data;
++
++	while (!(I2SR & I2SR_ICF))
++		udelay(1);
++
++	I2CR &= ~I2CR_MTX;
++
++	if (ack)
++		I2CR |= I2CR_TXAK;
++	else
++		I2CR &= ~I2CR_TXAK;
++
++	data = I2DR;
++	return data;
++}
++
++/* ------------------------------------------------------------------------
++ * API Functions
++ * ------------------------------------------------------------------------
++ */
++
++/*-----------------------------------------------------------------------
++ * i2c_init compute the i2c divider to reach the requested speed
++ * see mxl reference manual
++ */
++void i2c_init(int speed, int slaveaddr)
++{
++	int hclk_dividers[] = {
++		30, 32, 36, 42, 48, 52, 60, 72,
++		80, 88, 104, 128, 144, 160, 192, 240,
++		288, 320, 384, 480, 576, 640, 768, 960,
++		1152, 1280, 1536, 1920, 2304, 2560, 3072, 3840,
++		22, 24, 26, 26, 32, 36, 40, 44,
++		48, 56, 64, 72, 80, 96, 112, 128,
++		160, 192, 224, 256, 320, 384, 448, 512,
++		640, 768, 896, 1024, 1280, 1536, 1792, 2048
++	};
++	int refDiv = get_HCLK() / speed;
++	int i, tmpIC;
++
++	imx_gpio_mode(PA15_PF_I2C_SDA);
++	imx_gpio_mode(PA16_PF_I2C_SCL);
++
++	tmpIC = (sizeof(hclk_dividers) / sizeof(int)) - 1;
++	for (i = tmpIC; i >= 0; i--) {
++		if ((hclk_dividers[i] >= refDiv)
++		    && (hclk_dividers[i] < hclk_dividers[tmpIC])) {
++			tmpIC = i;
++		}
++	}
++
++	IFDR = tmpIC;
++	IADR = slaveaddr << 1;
++
++	if (I2SR & I2SR_IBB)
++		imxi2c_send_stop();
++
++	I2CR |= I2CR_IEN;
++}
++
++/*-----------------------------------------------------------------------
++ * Probe to see if a chip is present. Also good for checking for the
++ * completion of EEPROM writes since the chip stops responding until
++ * the write completes (typically 10mSec).
++ * probe sends a read command to probe a an address
++ */
++int i2c_probe(uchar addr)
++{
++	int rc;
++
++	imxi2c_send_start();
++	rc = imxi2c_write_byte((addr << 1) | 0);
++	imxi2c_send_stop();
++
++	return rc ? 1 : 0;
++}
++
++/*-----------------------------------------------------------------------
++ * Read bytes
++ */
++int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
++{
++	int shift;
++	debug("i2c_read: chip %02X addr %02X alen %d buffer %p len %d\n",
++	       chip, addr, alen, buffer, len);
++
++#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
++	/*
++	 * EEPROM chips that implement "address overflow" are ones
++	 * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
++	 * address and the extra bits end up in the "chip address"
++	 * bit slots. This makes a 24WC08 (1Kbyte) chip look like
++	 * four 256 byte chips.
++	 *
++	 * Note that we consider the length of the address field to
++	 * still be one byte because the extra address bits are
++	 * hidden in the chip address.
++	 */
++	chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
++
++	debug("i2c_read: fix addr_overflow: chip %02X addr %02X\n",
++	       chip, addr);
++#endif
++
++	/*
++	 * Do the addressing portion of a write cycle to set the
++	 * chip's address pointer. If the address length is zero,
++	 * don't do the normal write cycle to set the address pointer,
++	 * there is no address pointer in this chip.
++	 */
++	imxi2c_send_start();
++	if (alen > 0) {
++		if (imxi2c_write_byte(chip << 1)) {	/* write cycle */
++			imxi2c_send_stop();
++			debug("i2c_read, no chip responded %02X\n", chip);
++			return 1;
++		}
++		shift = (alen - 1) * 8;
++		while (alen-- > 0) {
++			if (imxi2c_write_byte(addr >> shift)) {
++				debug("i2c_read, address not <ACK>ed\n");
++				return 1;
++			}
++			shift -= 8;
++		}
++
++		/* reportedly some chips need a full stop */
++		imxi2c_send_stop();
++		imxi2c_send_start();
++	}
++	/*
++	 * Send the chip address again, this time for a read cycle.
++	 * Then read the data. On the last byte, we do a NACK instead
++	 * of an ACK(len == 0) to terminate the read.
++	 */
++	imxi2c_write_byte((chip << 1) | 1);	/* read cycle */
++	imxi2c_read_byte(len <= 2);
++	while (len-- > 1)
++		*buffer++ = imxi2c_read_byte(len == 1);
++
++	imxi2c_send_stop();
++	*buffer++ = imxi2c_read_byte(0);
++	return 0;
++}
++
++/*-----------------------------------------------------------------------
++ * Write bytes
++ */
++int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
++{
++	int shift, failures = 0;
++
++	debug("i2c_write: chip %02X addr %02X alen %d buffer %p len %d\n",
++	       chip, addr, alen, buffer, len);
++
++	imxi2c_send_start();
++	if (imxi2c_write_byte(chip << 1)) {	/* write cycle */
++		imxi2c_send_stop();
++		debug("i2c_write, no chip responded %02X\n", chip);
++		return 1;
++	}
++	shift = (alen - 1) * 8;
++	while (alen-- > 0) {
++		if (imxi2c_write_byte(addr >> shift)) {
++			debug("i2c_write, address not <ACK>ed\n");
++			return 1;
++		}
++		shift -= 8;
++	}
++
++	while (len-- > 0) {
++		if (imxi2c_write_byte(*buffer++))
++			failures++;
++	}
++	imxi2c_send_stop();
++	return failures;
++}
++
++#endif /* CONFIG_HARD_I2C */
+diff --git a/board/armadeus/apf9328/lowlevel_init.S b/board/armadeus/apf9328/lowlevel_init.S
+new file mode 100644
+index 0000000..f080423
+--- /dev/null
++++ b/board/armadeus/apf9328/lowlevel_init.S
+@@ -0,0 +1,458 @@
++/*
++ * Copyright (C) 2005-2014 Eric Jarrige <eric.jarrige at armadeus.org>
++ * Copyright (C) 2004 Sascha Hauer, Synertronixx GmbH
++ *
++ * SPDX-License-Identifier:    GPL-2.0+
++ */
++
++#include <config.h>
++#include <version.h>
++#include <asm/arch/imx-regs.h>
++
++.globl lowlevel_init
++lowlevel_init:
++/* Change PERCLK1DIV to 14 ie 14+1 */
++	ldr		r0,	=PCDR
++	ldr		r1,	=CONFIG_SYS_PCDR_VAL
++	str		r1,	[r0]
++
++/* set MCU PLL Control Register 0 */
++
++	ldr		r0,	=MPCTL0
++	ldr		r1,	=CONFIG_SYS_MPCTL0_VAL
++	str		r1,	[r0]
++
++/* set MCU PLL Control Register 1 */
++
++	ldr		r0,	=MPCTL1
++	ldr		r1,	=CONFIG_SYS_MPCTL1_VAL
++	str		r1,	[r0]
++
++/* set mpll restart bit */
++	ldr		r0, =CSCR
++	ldr		r1, [r0]
++	orr		r1,r1,#(1<<21)
++	str		r1, [r0]
++
++	mov		r2,#0x10
++1:
++	mov		r3,#0x2000
++2:
++	subs	r3,r3,#1
++	bne		2b
++
++	subs	r2,r2,#1
++	bne		1b
++
++/* set System PLL Control Register 0 */
++
++	ldr		r0,	=SPCTL0
++	ldr		r1,	=CONFIG_SYS_SPCTL0_VAL
++	str		r1,	[r0]
++
++/* set System PLL Control Register 1 */
++
++	ldr		r0,	=SPCTL1
++	ldr		r1,	=CONFIG_SYS_SPCTL1_VAL
++	str		r1,	[r0]
++
++/* set spll restart bit */
++	ldr		r0, =CSCR
++	ldr		r1, [r0]
++	orr		r1,r1,#(1<<22)
++	str		r1, [r0]
++
++	mov		r2,#0x10
++1:
++	mov		r3,#0x2000
++2:
++	subs	r3,r3,#1
++	bne		2b
++
++	subs	r2,r2,#1
++	bne		1b
++
++	ldr		r0,	=CSCR
++	ldr		r1,	=CONFIG_SYS_CSCR_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=GPCR
++	ldr		r1,	=CONFIG_SYS_GPCR_VAL
++	str		r1,	[r0]
++
++/* I have now read the ARM920 DataSheet back-to-Back, and have stumbled upon
++ *this.....
++ *
++ * It would appear that from a Cold-Boot the ARM920T enters "FastBus" mode CP15
++ * register 1, this stops it using the output of the PLL and thus runs at the
++ * slow rate. Unless you place the Core into "Asynch" mode, the CPU will never
++ * use the value set in the CM_OSC registers...regardless of what you set it
++ * too!  Thus, although i thought i was running at 140MHz, i'm actually running
++ * at 40!..
++
++ * Slapping this into my bootloader does the trick...
++
++ * MRC p15,0,r0,c1,c0,0	 ; read core configuration register
++ * ORR r0,r0,#0xC0000000	; set asynchronous clocks and not fastbus mode
++ * MCR p15,0,r0,c1,c0,0	 ; write modified value to core configuration
++ * register
++ */
++	MRC p15,0,r0,c1,c0,0
++	ORR r0,r0,#0xC0000000
++	MCR p15,0,r0,c1,c0,0
++
++/*	ldr		r0,	=GPR(0)
++	ldr		r1,	=CONFIG_SYS_GPR_A_VAL
++	str		r1,	[r0]
++*/
++
++	ldr		r0,	=DR(0)
++	ldr		r1,	=CONFIG_SYS_DR_A_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=OCR1(0)
++	ldr		r1,	=CONFIG_SYS_OCR1_A_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=OCR2(0)
++	ldr		r1,	=CONFIG_SYS_OCR2_A_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICONFA1(0)
++	ldr		r1,	=CONFIG_SYS_ICFA1_A_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICONFA2(0)
++	ldr		r1,	=CONFIG_SYS_ICFA2_A_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICONFB1(0)
++	ldr		r1,	=CONFIG_SYS_ICFB1_A_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICONFB2(0)
++	ldr		r1,	=CONFIG_SYS_ICFB2_A_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICR1(0)
++	ldr		r1,	=CONFIG_SYS_ICR1_A_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICR2(0)
++	ldr		r1,	=CONFIG_SYS_ICR2_A_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=IMR(0)
++	ldr		r1,	=CONFIG_SYS_IMR_A_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=DDIR(0)
++	ldr		r1,	=CONFIG_SYS_DDIR_A_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=GPR(0)
++	ldr		r1,	=CONFIG_SYS_GPR_A_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=PUEN(0)
++	ldr		r1,	=CONFIG_SYS_PUEN_A_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=GIUS(0)
++	ldr		r1,	=CONFIG_SYS_GIUS_A_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=DR(1)
++	ldr		r1,	=CONFIG_SYS_DR_B_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=OCR1(1)
++	ldr		r1,	=CONFIG_SYS_OCR1_B_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=OCR2(1)
++	ldr		r1,	=CONFIG_SYS_OCR2_B_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICONFA1(1)
++	ldr		r1,	=CONFIG_SYS_ICFA1_B_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICONFA2(1)
++	ldr		r1,	=CONFIG_SYS_ICFA2_B_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICONFB1(1)
++	ldr		r1,	=CONFIG_SYS_ICFB1_B_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICONFB2(1)
++	ldr		r1,	=CONFIG_SYS_ICFB2_B_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICR1(1)
++	ldr		r1,	=CONFIG_SYS_ICR1_B_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICR2(1)
++	ldr		r1,	=CONFIG_SYS_ICR2_B_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=IMR(1)
++	ldr		r1,	=CONFIG_SYS_IMR_B_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=DDIR(1)
++	ldr		r1,	=CONFIG_SYS_DDIR_B_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=GPR(1)
++	ldr		r1,	=CONFIG_SYS_GPR_B_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=PUEN(1)
++	ldr		r1,	=CONFIG_SYS_PUEN_B_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=GIUS(1)
++	ldr		r1,	=CONFIG_SYS_GIUS_B_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=DR(2)
++	ldr		r1,	=CONFIG_SYS_DR_C_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=OCR1(2)
++	ldr		r1,	=CONFIG_SYS_OCR1_C_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=OCR2(2)
++	ldr		r1,	=CONFIG_SYS_OCR2_C_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICONFA1(2)
++	ldr		r1,	=CONFIG_SYS_ICFA1_C_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICONFA2(2)
++	ldr		r1,	=CONFIG_SYS_ICFA2_C_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICONFB1(2)
++	ldr		r1,	=CONFIG_SYS_ICFB1_C_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICONFB2(2)
++	ldr		r1,	=CONFIG_SYS_ICFB2_C_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICR1(2)
++	ldr		r1,	=CONFIG_SYS_ICR1_C_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICR2(2)
++	ldr		r1,	=CONFIG_SYS_ICR2_C_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=IMR(2)
++	ldr		r1,	=CONFIG_SYS_IMR_C_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=DDIR(2)
++	ldr		r1,	=CONFIG_SYS_DDIR_C_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=GPR(2)
++	ldr		r1,	=CONFIG_SYS_GPR_C_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=PUEN(2)
++	ldr		r1,	=CONFIG_SYS_PUEN_C_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=GIUS(2)
++	ldr		r1,	=CONFIG_SYS_GIUS_C_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=DR(3)
++	ldr		r1,	=CONFIG_SYS_DR_D_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=OCR1(3)
++	ldr		r1,	=CONFIG_SYS_OCR1_D_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=OCR2(3)
++	ldr		r1,	=CONFIG_SYS_OCR2_D_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICONFA1(3)
++	ldr		r1,	=CONFIG_SYS_ICFA1_D_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICONFA2(3)
++	ldr		r1,	=CONFIG_SYS_ICFA2_D_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICONFB1(3)
++	ldr		r1,	=CONFIG_SYS_ICFB1_D_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICONFB2(3)
++	ldr		r1,	=CONFIG_SYS_ICFB2_D_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICR1(3)
++	ldr		r1,	=CONFIG_SYS_ICR1_D_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=ICR2(3)
++	ldr		r1,	=CONFIG_SYS_ICR2_D_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=IMR(3)
++	ldr		r1,	=CONFIG_SYS_IMR_D_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=DDIR(3)
++	ldr		r1,	=CONFIG_SYS_DDIR_D_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=GPR(3)
++	ldr		r1,	=CONFIG_SYS_GPR_D_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=PUEN(3)
++	ldr		r1,	=CONFIG_SYS_PUEN_D_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=GIUS(3)
++	ldr		r1,	=CONFIG_SYS_GIUS_D_VAL
++	str		r1,	[r0]
++
++/* CS3 becomes CS3 by clearing reset default bit 1 in FMCR */
++
++	ldr		r0,	=FMCR
++	ldr		r1,	=CONFIG_SYS_FMCR_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=CS0U
++	ldr		r1,	=CONFIG_SYS_CS0U_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=CS0L
++	ldr		r1,	=CONFIG_SYS_CS0L_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=CS1U
++	ldr		r1,	=CONFIG_SYS_CS1U_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=CS1L
++	ldr		r1,	=CONFIG_SYS_CS1L_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=CS2U
++	ldr		r1,	=CONFIG_SYS_CS2U_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=CS2L
++	ldr		r1,	=CONFIG_SYS_CS2L_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=CS3U
++	ldr		r1,	=CONFIG_SYS_CS3U_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=CS3L
++	ldr		r1,	=CONFIG_SYS_CS3L_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=CS4U
++	ldr		r1,	=CONFIG_SYS_CS4U_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=CS4L
++	ldr		r1,	=CONFIG_SYS_CS4L_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=CS5U
++	ldr		r1,	=CONFIG_SYS_CS5U_VAL
++	str		r1,	[r0]
++
++	ldr		r0,	=CS5L
++	ldr		r1,	=CONFIG_SYS_CS5L_VAL
++	str		r1,	[r0]
++
++	adr	r0, sdramsetup	/* r0 <- current position of code */
++	/* test if we run from flash or RAM */
++	ldr	r1, =PHYS_SDRAM_1
++	cmp	r1, r0		/* don't reloc during debug*/
++	bhi		sdramsetup
++	/* test if we run from flash or RAM */
++	ldr	r1, =CONFIG_SYS_FLASH_BASE
++	cmp	r0, r1		/* don't reloc during debug */
++	bmi		copy2ram
++
++/* SDRAM Setup */
++sdramsetup:
++	ldr		r0, =SDCTL0
++	ldr		r1, =CONFIG_SYS_PRECHARGE_CMD
++	str		r1,	[r0]
++
++	ldr		r1, =PHYS_SDRAM_1			\
++				+CONFIG_SYS_SDRAM_PRECHARGE_ALL_VAL
++	ldr		r2,	[r1]
++
++	ldr		r1, =CONFIG_SYS_AUTOREFRESH_CMD
++	str		r1,	[r0]
++
++	ldr		r1, =PHYS_SDRAM_1
++	ldr		r2,	[r1] /* Issue AutoRefresh Command */
++	ldr		r2,	[r1]
++	ldr		r2,	[r1]
++	ldr		r2,	[r1]
++	ldr		r2,	[r1]
++	ldr		r2,	[r1]
++	ldr		r2,	[r1]
++	ldr		r2,	[r1]
++
++	ldr		r1, =CONFIG_SYS_SET_MODE_REG_CMD
++	str		r1,	[r0]
++
++	ldr		r1, =PHYS_SDRAM_1			\
++				+CONFIG_SYS_SDRAM_MODE_REGISTER_VAL
++	str		r2,	[r1]
++
++	ldr		r1, =CONFIG_SYS_NORMAL_RW_CMD
++	str		r1,	[r0]
++/* make U-Boot runnable form "almost" anywhere */
++/* but SYS_TEXT_BASE should be in RAM */
++copy2ram:		/* populate _TEXT_BASE with U-Boot from load addr */
++	ldr	r0, _start_adr
++	ldr	r1, _copy2ram
++	sub	r1, r1, r0
++	adr	r0, copy2ram
++	sub	r0, r0, r1
++	ldr	r1, =CONFIG_SYS_TEXT_BASE
++	cmp	r0, r1
++	beq	end_of_copy2ram		/* skip U-Boot copy */
++	ldr	r2, =CONFIG_SYS_MONITOR_LEN
++	add	r2, r2, r0		/* r2 <- source end address	    */
++
++copy_loop:
++	ldmia	r0!, {r9-r10}		/* copy from source address [r0]    */
++	stmia	r1!, {r9-r10}		/* copy to   target address [r1]    */
++	cmp	r0, r2			/* until source end address [r2]    */
++	blo	copy_loop
++	ldr	pc, =CONFIG_SYS_TEXT_BASE /* reboot from RAM */
++	nop
++	nop
++
++end_of_copy2ram:
++	mov	pc,lr
++
++_copy2ram:
++	.word copy2ram
++_start_adr:
++	.word _start
+-- 
+1.7.2.5
+
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/104-apf9328-makefile.patch b/recipes-bsp/u-boot/u-boot-armadeus/104-apf9328-makefile.patch
new file mode 100644
index 0000000..895c4a7
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/104-apf9328-makefile.patch
@@ -0,0 +1,22 @@
+apf9328: add apf9328 board in Makefile
+
+add apf9328 board definition in makefile, MAKEALL and MAINTAINERS list
+
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+Signed-off-by: Philippe Reynes <tremyfr at yahoo.fr>
+---
+ boards.cfg  |    1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/boards.cfg b/boards.cfg
+index 7c1fc74..8a40643 100644
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -75,6 +75,7 @@ Active  arm         arm920t        at91
+ Active  arm         arm920t        at91        eukrea          cpuat91             cpuat91_ram                           cpuat91:RAMBOOT                                                                                                                   Eric Benard <eric at eukrea.com>
+ Active  arm         arm920t        ep93xx      cirrus          edb93xx             edb9315a                              edb93xx:MK_edb9315a                                                                                                               Sergey Kostanbaev <sergey.kostanbaev at fairwaves.ru>
+ Active  arm         arm920t        imx         -               scb9328             scb9328                               -                                                                                                                                 Torsten Koschorrek <koschorrek at synertronixx.de>
++Active  arm         arm920t        imx         armadeus        apf9328             apf9328                              -                                                                                                                                 Eric Jarrige <eric.jarrige at armadeus.org>
+ Active  arm         arm920t        ks8695      -               cm4008              cm4008                                -                                                                                                                                 Greg Ungerer <greg.ungerer at opengear.com>
+ Active  arm         arm920t        ks8695      -               cm41xx              cm41xx                                -                                                                                                                                 -
+ Active  arm         arm920t        s3c24x0     mpl             vcma9               VCMA9                                 -                                                                                                                                 David Müller <d.mueller at elsoft.ch>
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/106-mx1-pllclk.patch b/recipes-bsp/u-boot/u-boot-armadeus/106-mx1-pllclk.patch
new file mode 100644
index 0000000..acf1894
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/106-mx1-pllclk.patch
@@ -0,0 +1,63 @@
+mx1: improve PLL freq computation
+
+Improve PLL freq computation by using the full resolution of the PLL registers
+
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+Signed-off-by: Philippe Reynes <tremyfr at yahoo.fr>
+Cc: Stefano Babic <sbabic at denx.de>
+---
+ arch/arm/cpu/arm920t/imx/speed.c |   29 +++++++++++------------------
+ 1 files changed, 11 insertions(+), 18 deletions(-)
+
+diff --git a/arch/arm/cpu/arm920t/imx/speed.c b/arch/arm/cpu/arm920t/imx/speed.c
+index 1e29698..b1c2bd6 100644
+--- a/arch/arm/cpu/arm920t/imx/speed.c
++++ b/arch/arm/cpu/arm920t/imx/speed.c
+@@ -20,33 +20,26 @@
+  * the specified bus in HZ.
+  */
+ /* ------------------------------------------------------------------------- */
+-
+-ulong get_systemPLLCLK(void)
++static ulong get_PLLCLK(u32 sys_clk_freq, u32 pllctl0)
+ {
+ 	/* FIXME: We assume System_SEL = 0 here */
+-	u32 spctl0 = SPCTL0;
+-	u32 mfi = (spctl0 >> 10) & 0xf;
+-	u32 mfn = spctl0 & 0x3f;
+-	u32 mfd = (spctl0 >> 16) & 0x3f;
+-	u32 pd =  (spctl0 >> 26) & 0xf;
++	u32 mfi = (pllctl0 >> 10) & 0xf;
++	u32 mfn = pllctl0 & 0x3ff;
++	u32 mfd = (pllctl0 >> 16) & 0x3ff;
++	u32 pd =  (pllctl0 >> 26) & 0xf;
+ 
+ 	mfi = mfi<=5 ? 5 : mfi;
++	return (2*(u64)sys_clk_freq * (mfi*(mfd+1) + mfn))/((mfd+1)*(pd+1));
++}
+ 
+-	return (2*(CONFIG_SYSPLL_CLK_FREQ>>10)*( (mfi<<10) + (mfn<<10)/(mfd+1)))/(pd+1);
++ulong get_systemPLLCLK(void)
++{
++	return get_PLLCLK(CONFIG_SYSPLL_CLK_FREQ, SPCTL0);
+ }
+ 
+ ulong get_mcuPLLCLK(void)
+ {
+-	/* FIXME: We assume System_SEL = 0 here */
+-	u32 mpctl0 = MPCTL0;
+-	u32 mfi = (mpctl0 >> 10) & 0xf;
+-	u32 mfn = mpctl0 & 0x3f;
+-	u32 mfd = (mpctl0 >> 16) & 0x3f;
+-	u32 pd =  (mpctl0 >> 26) & 0xf;
+-
+-	mfi = mfi<=5 ? 5 : mfi;
+-
+-	return (2*(CONFIG_SYS_CLK_FREQ>>10)*( (mfi<<10) + (mfn<<10)/(mfd+1)))/(pd+1);
++	return get_PLLCLK(CONFIG_SYS_CLK_FREQ, MPCTL0);
+ }
+ 
+ ulong get_FCLK(void)
+-- 
+1.7.2.5
+
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/107-mx1-pllclk-debug.patch b/recipes-bsp/u-boot/u-boot-armadeus/107-mx1-pllclk-debug.patch
new file mode 100644
index 0000000..26a73dd
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/107-mx1-pllclk-debug.patch
@@ -0,0 +1,26 @@
+mx1: change a printf in speed.c to use debug instead
+
+
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+Signed-off-by: Philippe Reynes <tremyfr at yahoo.fr>
+Cc: Stefano Babic <sbabic at denx.de>
+---
+ arch/arm/cpu/arm920t/imx/speed.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/cpu/arm920t/imx/speed.c b/arch/arm/cpu/arm920t/imx/speed.c
+index b1c2bd6..b8e42bf 100644
+--- a/arch/arm/cpu/arm920t/imx/speed.c
++++ b/arch/arm/cpu/arm920t/imx/speed.c
+@@ -51,7 +51,7 @@ ulong get_FCLK(void)
+ ulong get_HCLK(void)
+ {
+ 	u32 bclkdiv = (( CSCR >> 10 ) & 0xf) + 1;
+-	printf("bclkdiv: %d\n", bclkdiv);
++	debug("bclkdiv: %d\n", bclkdiv);
+ 	return get_systemPLLCLK() / bclkdiv;
+ }
+ 
+-- 
+1.7.2.5
+
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/108-DM9000.patch b/recipes-bsp/u-boot/u-boot-armadeus/108-DM9000.patch
new file mode 100644
index 0000000..f302512
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/108-DM9000.patch
@@ -0,0 +1,48 @@
+DM9000: change some printf to use debug instead
+
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+Signed-off-by: Philippe Reynes <tremyfr at yahoo.fr>
+Cc: Ben Warren <biggerbadderben at gmail.com>
+---
+ drivers/net/dm9000x.c |    8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c
+index f0c4499..738e6ef 100644
+--- a/drivers/net/dm9000x.c
++++ b/drivers/net/dm9000x.c
+@@ -232,7 +232,7 @@ dm9000_probe(void)
+ 	id_val |= DM9000_ior(DM9000_PIDL) << 16;
+ 	id_val |= DM9000_ior(DM9000_PIDH) << 24;
+ 	if (id_val == DM9000_ID) {
+-		printf("dm9000 i/o: 0x%x, id: 0x%x \n", CONFIG_DM9000_BASE,
++		DM9000_DBG("dm9000 i/o: 0x%x, id: 0x%x\n", CONFIG_DM9000_BASE,
+ 		       id_val);
+ 		return 0;
+ 	} else {
+@@ -298,19 +298,19 @@ static int dm9000_init(struct eth_device *dev, bd_t *bd)
+ 
+ 	switch (io_mode) {
+ 	case 0x0:  /* 16-bit mode */
+-		printf("DM9000: running in 16 bit mode\n");
++		DM9000_DBG("DM9000: running in 16 bit mode\n");
+ 		db->outblk    = dm9000_outblk_16bit;
+ 		db->inblk     = dm9000_inblk_16bit;
+ 		db->rx_status = dm9000_rx_status_16bit;
+ 		break;
+ 	case 0x01:  /* 32-bit mode */
+-		printf("DM9000: running in 32 bit mode\n");
++		DM9000_DBG("DM9000: running in 32 bit mode\n");
+ 		db->outblk    = dm9000_outblk_32bit;
+ 		db->inblk     = dm9000_inblk_32bit;
+ 		db->rx_status = dm9000_rx_status_32bit;
+ 		break;
+ 	case 0x02: /* 8 bit mode */
+-		printf("DM9000: running in 8 bit mode\n");
++		DM9000_DBG("DM9000: running in 8 bit mode\n");
+ 		db->outblk    = dm9000_outblk_8bit;
+ 		db->inblk     = dm9000_inblk_8bit;
+ 		db->rx_status = dm9000_rx_status_8bit;
+-- 
+1.7.2.5
+
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/111-mx1-timer.patch b/recipes-bsp/u-boot/u-boot-armadeus/111-mx1-timer.patch
new file mode 100644
index 0000000..a6dd375
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/111-mx1-timer.patch
@@ -0,0 +1,25 @@
+mx1: Fix function get_timer() to adjust frequency according to CONFIG_SYS_HZ
+
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+Signed-off-by: Philippe Reynes <tremyfr at yahoo.fr>
+Cc: Stefano Babic <sbabic at denx.de>
+---
+ arch/arm/cpu/arm920t/imx/timer.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/cpu/arm920t/imx/timer.c b/arch/arm/cpu/arm920t/imx/timer.c
+index 6141bd4..d6d1968 100644
+--- a/arch/arm/cpu/arm920t/imx/timer.c
++++ b/arch/arm/cpu/arm920t/imx/timer.c
+@@ -39,7 +39,7 @@ int timer_init (void)
+  */
+ ulong get_timer (ulong base)
+ {
+-	return get_timer_masked() - base;
++	return get_timer_masked() / (1000000 / CONFIG_SYS_HZ) - base;
+ }
+ 
+ ulong get_timer_masked (void)
+-- 
+1.7.2.5
+
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/300-imx27-fix_dcache_boot_issue.patch b/recipes-bsp/u-boot/u-boot-armadeus/300-imx27-fix_dcache_boot_issue.patch
new file mode 100644
index 0000000..058b2b3
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/300-imx27-fix_dcache_boot_issue.patch
@@ -0,0 +1,22 @@
+imx27: Dcache is not correctly flushed during the boot process
+This patch fix it and make it possible to run U-Boot from RAM.
+tested method: start U-Boot from RAM with a go a0000800
+
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+---
+--- uboot-custom/arch/arm/cpu/arm926ejs/start.S
++++ uboot-custom/arch/arm/cpu/arm926ejs/start.S
+@@ -78,11 +78,12 @@ cpu_init_crit:
+ 	 */
+ 	mov	r0, #0
+ flush_dcache:
+-	mrc	p15, 0, r15, c7, c10, 3
++	mrc	p15, 0, r15, c7, c14, 3
+ 	bne	flush_dcache
+ 
+ 	mcr	p15, 0, r0, c8, c7, 0	/* invalidate TLB */
+ 	mcr	p15, 0, r0, c7, c5, 0	/* invalidate I Cache */
++	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+ 
+ 	/*
+ 	 * disable MMU and D cache
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/302-apf27-support-boot-from-RAM.patch b/recipes-bsp/u-boot/u-boot-armadeus/302-apf27-support-boot-from-RAM.patch
new file mode 100644
index 0000000..7f1402e
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/302-apf27-support-boot-from-RAM.patch
@@ -0,0 +1,48 @@
+apf27: Support boot from RAM
+This patch adds capabilites to start U-Boot directly from RAM
+to test a new version of U-Boot before being programmed in FLASH.
+here is a typical use case: run download_uboot ; go a0000000
+
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+---
+--- a/board/armadeus/apf27/apf27.c
++++ b/board/armadeus/apf27/apf27.c
+@@ -241,10 +241,22 @@ void board_init_f(ulong bootflag)
+ 	 * are 4-byte-aligned.
+ 	 */
+ 	ulong *start_ptr, *end_ptr, *link_ptr, *run_ptr, *dst;
++	register ulong reg0;
+ 	asm volatile ("ldr %0, =_start" : "=r"(start_ptr));
+ 	asm volatile ("ldr %0, =_end" : "=r"(end_ptr));
+ 	asm volatile ("ldr %0, =board_init_f" : "=r"(link_ptr));
+ 	asm volatile ("adr %0, board_init_f" : "=r"(run_ptr));
++	asm volatile ("mov %0, pc" : "=r"(reg0));
++	if ((reg0 > (ulong)PHYS_SDRAM_1) &&
++		(reg0 < (ulong)(PHYS_SDRAM_2+PHYS_SDRAM_2_SIZE))) {
++		/*
++		 * in the case we are already running from RAM we do not need
++		 * to load U-Boot from flash - so let's go to U-Boot in RAM.
++		 */
++		asm volatile ("ldr %0, =0xfffff800" : "=r"(reg0));
++		asm volatile ("and %0, %0, pc" : "=r"(reg0));
++		asm volatile ("add pc, %0, %1" : : "r" (reg0), "i" (CONFIG_SYS_NAND_U_BOOT_OFFS));
++	}
+ 	for (dst = start_ptr; dst < end_ptr; dst++)
+ 		*dst = *(dst+(run_ptr-link_ptr));
+ 
+--- a/board/armadeus/apf27/lowlevel_init.S
++++ b/board/armadeus/apf27/lowlevel_init.S
+@@ -162,6 +162,13 @@ lowlevel_init:
+ 	init_aipi
+ 	init_clock
+ #ifdef CONFIG_SPL_BUILD
++	/* skip sdram initialization if we run from RAM */
++	cmp	pc, #PHYS_SDRAM_1
++	bls	1f
++	cmp	pc, #(PHYS_SDRAM_2+PHYS_SDRAM_2_SIZE)
++	bhi	1f
++	mov	pc, lr
++1:
+ 	init_ddr
+ #endif
+ 
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/311-imx-nand-lock-unlock.patch b/recipes-bsp/u-boot/u-boot-armadeus/311-imx-nand-lock-unlock.patch
new file mode 100644
index 0000000..ef92d80
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/311-imx-nand-lock-unlock.patch
@@ -0,0 +1,98 @@
+mxc_nand.c: Support nand lock/unlock
+
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+Signed-off-by: Philippe Reynes <tremyfr at yahoo.fr>
+--
+ drivers/mtd/nand/mxc_nand.c |   66 +++++++++++++++++++++++++++++++++++++++++++
+ 1 files changed, 66 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
+index d0ded48..2bbc1fd 100644
+--- a/drivers/mtd/nand/mxc_nand.c
++++ b/drivers/mtd/nand/mxc_nand.c
+@@ -47,6 +47,28 @@ static struct mxc_nand_host *host = &mxc_host;
+ #define MAIN_SINGLEBIT_ERROR 0x4
+ #define SPARE_SINGLEBIT_ERROR 0x1
+ 
++#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
++/******************************************************************************
++ * Support for locking / unlocking feature of imx NFC controller
++ *****************************************************************************/
++
++#define NAND_CMD_LOCK		0x2a
++#define NAND_CMD_LOCK_TIGHT	0x2c
++#define NAND_CMD_UNLOCK1	0x23
++#define NAND_CMD_UNLOCK2	0x24
++#define NAND_CMD_LOCK_STATUS	0x7a
++
++/* NFC_WRPROT Control Register Bit Fields */
++#define NFC_WRPROT_UNLOCKBLK	(4<<0)		/* unlock block according to given address range */
++#define NFC_WRPROT_LOCKALL	(2<<0)		/* lock all */
++#define NFC_WRPROT_LOCKTIGHT	(1<<0)		/* lock-tight locked blocks */
++/* NFC_WRPR_STAT Status Register Bit Fields */
++#define NFC_WRPR_US 	        (1<<2)		/* Unlocked status	*/
++#define NFC_WRPR_LS 	        (1<<1)		/* Locked status */
++#define NFC_WRPR_LTS 	        (1<<0)		/* Lock-tight Status */
++
++#endif
++
+ /* OOB placement block for use with hardware ecc generation */
+ #if defined(MXC_NFC_V1)
+ #ifndef CONFIG_SYS_NAND_LARGEPAGE
+@@ -1079,6 +1091,53 @@ void mxc_nand_command(struct mtd_info *mtd, unsigned command,
+ 		}
+ 
+ 		break;
++#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
++   	case NAND_CMD_LOCK:
++		/* Blocks to be unlocked */
++		writew(-1, &host->regs->unlockstart_blkaddr);
++		writew(-1, &host->regs->unlockend_blkaddr);
++
++		/* Lock Block Command for given address range */
++		writew(NFC_WRPROT_LOCKALL, &host->regs->wrprot);
++		return;
++   	case NAND_CMD_LOCK_TIGHT:
++		/* Blocks to be unlocked */
++		writew(-1, &host->regs->unlockstart_blkaddr);
++		writew(-1, &host->regs->unlockend_blkaddr);
++
++		/* Lock Block Command for given address range */
++		writew(NFC_WRPROT_LOCKTIGHT, &host->regs->wrprot);
++		return;
++   	case NAND_CMD_UNLOCK1:
++		writew(page_addr>>6, &host->regs->unlockstart_blkaddr);
++		return;
++   	case NAND_CMD_UNLOCK2:
++		writew(page_addr>>6, &host->regs->unlockend_blkaddr);
++
++		/* Lock Block Command for given address range */
++		writew(NFC_WRPROT_UNLOCKBLK, &host->regs->wrprot);
++		return;
++   	case NAND_CMD_LOCK_STATUS:
++		host->col_addr = 0;
++		host->spare_only = false;
++
++    		MTDDEBUG(MTD_DEBUG_LEVEL3,"get_lock_status %x\n", readw(&host->regs->nf_wrprst));
++
++		if ((readw(&host->regs->nf_wrprst) & NFC_WRPR_US)
++			&& !(readw(&host->regs->nf_wrprst) & NFC_WRPR_LTS)
++			&& ((readw(&host->regs->unlockend_blkaddr) >= page_addr>>6)
++			&& (readw(&host->regs->unlockstart_blkaddr) <= page_addr>>6))) {
++			void __iomem *main_buf = host->regs->main_area[0];
++			writew(NFC_WRPR_US, main_buf);
++		} else if (readw(&host->regs->nf_wrprst) & NFC_WRPR_LTS) {
++			void __iomem *main_buf = host->regs->main_area[0];
++			writew(readw(&host->regs->nf_wrprst), main_buf);
++		} else {
++			void __iomem *main_buf = host->regs->main_area[0];
++			writew(readw(&host->regs->nf_wrprst) & ~NFC_WRPR_US, main_buf);
++		}
++		return;
++#endif
+ 	}
+ 
+ 	/* Write out the command to the device. */
+-- 
+1.7.2.5
+
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/320-spartan.patch b/recipes-bsp/u-boot/u-boot-armadeus/320-spartan.patch
new file mode 100644
index 0000000..50909a2
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/320-spartan.patch
@@ -0,0 +1,71 @@
+spartan3: Fix minor issue.
+
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+Signed-off-by: Philippe Reynes <tremyfr at yahoo.fr>
+Signed-off-by: Nicolas Colombain <nicolas.colombain at armadeus.com>
+---
+ drivers/fpga/spartan3.c |    9 +++++++--
+ 1 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/fpga/spartan3.c b/drivers/fpga/spartan3.c
+index 1633a70..9ca0522 100644
+--- a/drivers/fpga/spartan3.c
++++ b/drivers/fpga/spartan3.c
+@@ -172,8 +172,14 @@ static int Spartan3_sp_load(Xilinx_desc
+ 		(*fn->clk) (true, true, cookie);	/* Assert the clock pin */
+ 
+ 		/* Load the data */
+-		while (bytecount < bsize) {
+-			/* XXX - do we check for an Ctrl-C press in here ??? */
++		while ( ((*fn->done) (cookie) != FPGA_SUCCESS)
++			&& (bytecount < bsize)) {
++#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
++			if (ctrlc ()) {
++				(*fn->abort) (cookie);
++				return FPGA_FAIL;
++			}
++#endif
+ 			/* XXX - Check the error bit? */
+ 
+ 			(*fn->wdata) (data[bytecount++], true, cookie); /* write the data */
+@@ -272,7 +278,12 @@ static int Spartan3_sp_dump(Xilinx_desc
+ 
+ 		/* dump the data */
+ 		while (bytecount < bsize) {
+-			/* XXX - do we check for an Ctrl-C press in here ??? */
++#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
++			if (ctrlc ()) {
++				(*fn->abort) (cookie);
++				return FPGA_FAIL;
++			}
++#endif
+ 
+ 			(*fn->clk) (false, true, cookie);	/* Deassert the clock pin */
+ 			(*fn->clk) (true, true, cookie);	/* Assert the clock pin */
+@@ -376,6 +387,12 @@ static int Spartan3_ss_load(Xilinx_desc
+ 			(*fn->bwr) (data, bsize, true, cookie);
+ 		else {
+ 			while (bytecount < bsize) {
++#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
++				if (ctrlc ()) {
++					(*fn->abort) (cookie);
++					return FPGA_FAIL;
++				}
++#endif
+ 
+ 				/* Xilinx detects an error if INIT goes low (active)
+ 				   while DONE is low (inactive) */
+--- uboot-custom/include/fpga.h
++++ uboot-custom/include/fpga.h
+@@ -16,7 +16,7 @@
+ 
+ /* fpga_xxxx function return value definitions */
+ #define FPGA_SUCCESS		0
+-#define FPGA_FAIL		-1
++#define FPGA_FAIL		1
+ 
+ /* device numbers must be non-negative */
+ #define FPGA_INVALID_DEVICE	-1
+-- 
+1.7.2.5
+
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/340-apf27-misc-commands.patch b/recipes-bsp/u-boot/u-boot-armadeus/340-apf27-misc-commands.patch
new file mode 100644
index 0000000..7af55df
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/340-apf27-misc-commands.patch
@@ -0,0 +1,376 @@
+Add apf27 imxfuse command
+
+Signed-off-by: Philippe Reynes <tremyfr at yahoo.fr>
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+---
+ arch/arm/include/asm/arch-mx27/imx-regs.h |    4 +
+ board/armadeus/apf27/Makefile             |    1 +-
+ board/armadeus/apf27/cmd_imxfuse.c        |  331 +++++++++++++++++++++++++++++
+ 3 files changed, 335 insertions(+), 1 deletions(-)
+ create mode 100644 board/armadeus/apf27/cmd_imxfuse.c
+
+diff --git a/arch/arm/include/asm/arch-mx27/imx-regs.h b/arch/arm/include/asm/arch-mx27/imx-regs.h
+index d3a14e1..c100b72 100644
+--- a/arch/arm/include/asm/arch-mx27/imx-regs.h
++++ b/arch/arm/include/asm/arch-mx27/imx-regs.h
+@@ -138,6 +138,10 @@ struct fuse_bank0_regs {
+ 	u32 gpt_tstat;
+ };
+ 
++/* IIM Control Registers */
++#define IIM_BANK_AREA	IMX_IIM_BASE + 0x800
++#define IIM_BANK_REG(x,y) (IIM_BANK_AREA + 0x400 * x + (y<<2))
++
+ /*
+  *  GPIO Module and I/O Multiplexer
+  */
+diff --git a/board/armadeus/apf27/Makefile b/board/armadeus/apf27/Makefile
+index 7a39426..484268e 100644
+--- a/board/armadeus/apf27/Makefile
++++ b/board/armadeus/apf27/Makefile
+@@ -9,4 +9,5 @@
+ 
+ obj-y	:= apf27.o
+ obj-y	+= lowlevel_init.o
++obj-y	+= cmd_imxfuse.o
+ obj-$(CONFIG_FPGA)	+= fpga.o
+diff --git a/board/armadeus/apf27/cmd_imxfuse.c b/board/armadeus/apf27/cmd_imxfuse.c
+new file mode 100644
+index 0000000..cd2078a
+--- /dev/null
++++ b/board/armadeus/apf27/cmd_imxfuse.c
+@@ -0,0 +1,331 @@
++/*
++ * cmd_imxfuse-c Interface to iMX IC Identification Module
++ * 	Based on Freescale iMX27 Board Support Package
++ *
++ * (C) Copyright 2008,2009 Eric Jarrige <eric.jarrige at armadeus.org>
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <config.h>
++#include <common.h>
++#include <command.h>
++
++#ifdef CONFIG_CMD_IMX_FUSE
++
++#include <asm/arch/imx-regs.h>
++#include <asm/io.h>
++
++#define IIM_ERR_SHIFT	   8
++#define POLL_FUSE_PRGD	  (IIM_STAT_PRGD | (IIM_ERR_PRGE << IIM_ERR_SHIFT))
++#define POLL_FUSE_SNSD	  (IIM_STAT_SNSD | (IIM_ERR_SNSE << IIM_ERR_SHIFT))
++
++static void imx_fuse_op_start(void)
++{
++	struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
++	/* Do not generate interrupt */
++	writel(0x00, &iim->iim_statm);
++	// clear the status bits and error bits
++	writel(0x03, &iim->iim_stat);
++	writel(0xFE, &iim->iim_err);
++}
++
++/*
++ * The action should be either:
++ *		  POLL_FUSE_PRGD
++ * or:
++ *		  POLL_FUSE_SNSD
++ */
++static int imx_poll_fuse_op_done(int action)
++{
++	u32 status, error;
++	struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
++
++	if (action != POLL_FUSE_PRGD && action != POLL_FUSE_SNSD) {
++		printf("%s(%d) invalid operation\n", __FUNCTION__, action);
++		return -1;
++	}
++
++	/* Poll busy bit till it is NOT set */
++	while ((readl(&iim->iim_stat) & IIM_STAT_BUSY) != 0 ) {
++	}
++
++	/* Test for successful write */
++	status = readl(&iim->iim_stat);
++	error = readl(&iim->iim_err);
++
++	if ((status & action) != 0 && (error & (action >> IIM_ERR_SHIFT)) == 0) {
++		if (error) {
++			printf("Even though the operation seems successful...\n");
++			printf("There are some error(s) at addr=0x%x: 0x%x\n",
++						readl(&iim->iim_err), error);
++		}
++		return 0;
++	}
++	printf("%s(0x%x) failed\n", __FUNCTION__, action);
++	printf("status address=0x%x, value=0x%x\n",
++				readl(&iim->iim_stat), status);
++	printf("There are some error(s) at addr=0x%x: 0x%x\n",
++				readl(&iim->iim_err), error);
++	return -1;
++}
++
++static int imx_read_shadow_fuse(int bank, int row, int bit)
++{
++	printf("Shadow fuses at (bank:%d, row:%d) = 0x%x\n",
++		bank, row, readl((long*)IIM_BANK_REG(bank,row)));
++	return 0;
++}
++
++static int imx_sense_fuse(int bank, int row, int bit)
++{
++	int addr, addr_l, addr_h;
++	struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
++
++	imx_fuse_op_start();
++
++	/* Enable IIM Program Protect */
++	writel(0x0,&iim->iim_prg_p);
++
++	addr = ((bank << 11) | (row << 3) | (bit & 0x7));
++	/* Set IIM Program Upper Address */
++	addr_h = (addr >> 8) & 0x000000FF;
++	/* Set IIM Program Lower Address */
++	addr_l = (addr & 0x000000FF);
++
++#ifdef IIM_FUSE_DEBUG
++	printf("%s: addr_h=0x%x, addr_l=0x%x\n",
++		__FUNCTION__, addr_h, addr_l);
++#endif
++	writel(addr_h, &iim->iim_ua);
++	writel(addr_l, &iim->iim_la);
++
++	/* Start sensing */
++	writel(0x08, &iim->iim_fctl);
++	if (imx_poll_fuse_op_done(POLL_FUSE_SNSD) != 0) {
++		printf("%s(bank: %d, row: %d, bit: %d failed\n",
++			__FUNCTION__, bank, row, bit);
++	}
++
++	printf("fuses at (bank:%d, row:%d) = 0x%x\n",
++		bank, row, readl(&iim->iim_sdat));
++	return 0;
++}
++
++/* Blow fuses based on the bank, row and bit positions (all 0-based)
++*/
++static int imx_fuse_blow(int bank,int row,int bit)
++{
++	int addr, addr_l, addr_h, ret = 1;
++	struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
++
++	imx_fuse_op_start();
++
++	/* Disable IIM Program Protect */
++	writel(0xAA, &iim->iim_prg_p);
++
++	addr = ((bank << 11) | (row << 3) | (bit & 0x7));
++	/* Set IIM Program Upper Address */
++	addr_h = (addr >> 8) & 0x000000FF;
++	/* Set IIM Program Lower Address */
++	addr_l = (addr & 0x000000FF);
++
++#ifdef IIM_FUSE_DEBUG
++	printf("blowing addr_h=0x%x, addr_l=0x%x\n", addr_h, addr_l);
++#endif
++
++	writel(addr_h, &iim->iim_ua);
++	writel(addr_l, &iim->iim_la);
++	/* Start Programming */
++	writel(0x31, &iim->iim_fctl);
++	if (imx_poll_fuse_op_done(POLL_FUSE_PRGD) == 0) {
++		ret = 0;
++	}
++
++	/* Enable IIM Program Protect */
++	writel(0x0, &iim->iim_prg_p);
++	return ret;
++}
++
++/* Blow byte fuses based on the bank and row positions (all 0-based)
++*/
++static int imx_fuse_blow_byte(int bank,int row,unsigned char value)
++{
++	int i, ret = 0;
++
++		for (i = 0; i < 8; i++) {
++			if (((value >> i) & 0x1) == 0) {
++				continue;
++			}
++			ret |= imx_fuse_blow(bank, row, i);
++		}
++
++	return ret;
++}
++
++static int imx_mac_read(unsigned char pmac[6])
++{
++	int i;
++	int uninitialized = 0;
++	struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
++	struct fuse_bank *bank = &iim->bank[0];
++	struct fuse_bank0_regs *fuse =
++			(struct fuse_bank0_regs *)bank->fuse_regs;
++
++	for (i = 0; i < 6; i++) {
++		pmac[6 - 1 - i] = readl(&fuse->mac_addr[i]) & 0xff;
++	}
++
++	/* uninitialized if all 00 */
++        if ((pmac[0] == 0) && (pmac[1] == 0) && (pmac[2] == 0) &&
++	    (pmac[3] == 0) && (pmac[4] == 0) && (pmac[5] == 0))
++	        uninitialized = 1;
++
++	return uninitialized;
++}
++
++static int imx_mac_blow(unsigned char pmac[6])
++{
++	int i, ret = 1;
++	unsigned char mac[6];
++	int uninitialized = 0;
++
++	uninitialized = imx_mac_read(mac);
++
++	if (uninitialized) {
++		ret = 0;
++		for(i=0;i<6;i++) {
++			ret |= imx_fuse_blow_byte(IIM_MAC_BANK,
++				(IIM_MAC_ROW+i), pmac[6 - 1 -i]);
++		}
++	}
++
++	return ret;
++}
++
++
++int do_imx_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
++{
++	uint32_t bank, row, value, i;
++	int ret = 1;
++
++	if (argc < 2) {
++		printf("It is too dangeous for you to use this command.\n");
++		printf("Usage:\n%s\n", cmdtp->usage);
++		return ret;
++	}
++
++	if ((!strcmp(argv[1], "sense"))&&((argc == 4))) {
++		bank = simple_strtoul(argv[2], NULL, 16);
++		row = simple_strtoul(argv[3], NULL, 16);
++
++		printf("Sense read fuse at bank:%d row:%d\n", bank, row);
++		ret = imx_sense_fuse(bank, row, 0);
++	}else if ((!strcmp(argv[1], "read"))&&((argc == 4))) {
++		bank = simple_strtoul(argv[2], NULL, 16);
++		row = simple_strtoul(argv[3], NULL, 16);
++
++		printf("Shadow read fuse at bank:%d row:%d\n", bank, row);
++		ret = imx_read_shadow_fuse(bank, row, 0);
++	}else if ((!strcmp(argv[1], "blow"))&&(argc == 5)) {
++		bank = simple_strtoul(argv[2], NULL, 16);
++		row = simple_strtoul(argv[3], NULL, 16);
++		value = simple_strtoul(argv[4], NULL, 16);
++
++		printf("Blowing fuse at bank:%d row:%d value:%d\n",
++				bank, row, value);
++		for (i = 0; i < 8; i++) {
++			if (((value >> i) & 0x1) == 0) {
++				continue;
++			}
++			if (imx_fuse_blow(bank, row, i) != 0) {
++				printf("fuse_blow(bank: %d, row: %d, bit:"
++					" %d failed\n",	bank, row, i);
++			} else {
++				printf("fuse_blow(bank: %d, row: %d, bit:"
++					" %d successful\n", bank, row, i);
++				ret = 0;
++			}
++		}
++
++		/* read back fuse by shadow register if applicable */
++		ret |= imx_read_shadow_fuse(bank, row, 0);
++
++	}else if ((!strcmp(argv[1], "mac"))&&(argc == 2)) {
++		unsigned char mac[6];
++		ret = imx_mac_read(mac);
++
++		printf("%siMX mac_addr in fuse: %02X:%02X:%02X:%02X:%02X:%02X\n",
++		ret?"No ":"",
++		mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
++	}else if ((!strcmp(argv[1], "mac"))&&(argc == 3)) {
++		unsigned char mac[6];
++		char *tmp, *end;
++
++		tmp = argv[2];
++		/* convert MAC from string to int */
++		for (i=0; i<6; i++) {
++		mac[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
++		if (tmp)
++			tmp = (*end) ? end+1 : end;
++		}
++
++		ret = imx_mac_blow(mac);
++		if (ret) {
++			printf("Failed to blow mac_addr in fuse: "
++				"%02X:%02X:%02X:%02X:%02X:%02X\n",
++				mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
++		} else {
++			imx_mac_read(mac);
++			printf("Mac_addr blowed in fuse: "
++				"%02X:%02X:%02X:%02X:%02X:%02X\n",
++				mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
++		}
++	}else if ((!strcmp(argv[1], "suid"))&&(argc == 2)) {
++
++		printf("iMX SUID: ");
++		for (i=0;i<6;i++) {
++			printf("%02x", readl((long*)IIM_BANK_REG(1,(IIM1_SUID+i))));
++		}
++		printf("\n");
++		ret = 0;
++	}else if ((!strcmp(argv[1], "scc_key"))&&(argc == 2)) {
++
++		printf("iMX SCC_KEY: ");
++		for (i=0;i<21;i++) {
++			printf("%02x", readl((long*)IIM_BANK_REG(0,(IIM0_SCC_KEY+i))));
++		}
++		printf("\n");
++		ret = 0;
++	} else { printf("arc:%d\n", argc);
++		printf("Usage:\n%s\n", cmdtp->usage);
++		return 1;
++	}
++
++	return ret;
++}
++
++U_BOOT_CMD(imxfuse, 5, 0, do_imx_fuse,
++	"imxfuse - Read/Blow some iMX fuses\n",\
++	"sense <bank> <row> - sense read iMX fuses at <bank>/<row>\n" \
++	"imxfuse read <bank> <row> - shadow read iMX fuses at <bank>/<row>\n" \
++	"imxfuse blow <bank> <row> <value> - blow <value> at <bank>/<row>\n"\
++	"	- Read/Blow 8 bits <Value> for some iMX fuses at <bank>/<row>\n"\
++	"imxfuse mac [<mac_addr>]  - read/blow <mac_addr> in iMX fuses\n"\
++	"imxfuse suid - read iMX SUID\n"\
++	"imxfuse scc_key - read iMX SCC_KEY\n");
++
++#endif /* CONFIG_CMD_IMX_FUSE */
+-- 
+1.7.2.5
+
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/350-nand_large_file_download.patch b/recipes-bsp/u-boot/u-boot-armadeus/350-nand_large_file_download.patch
new file mode 100644
index 0000000..25c80f1
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/350-nand_large_file_download.patch
@@ -0,0 +1,265 @@
+tftp: support tftp direct download to NAND flash.
+
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+Signed-off-by: Philippe Reynes <tremyfr at yahoo.fr>
+Signed-off-by: Nicolas Colombain <nicolas.colombain at armadeus.com>
+---
+ common/cmd_net.c |   26 ++++++++++++-
+ net/tftp.c       |  112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 137 insertions(+), 1 deletions(-)
+
+diff --git a/common/cmd_net.c b/common/cmd_net.c
+index a9ade8b..fc1ce05 100644
+--- a/common/cmd_net.c
++++ b/common/cmd_net.c
+@@ -12,6 +12,10 @@
+ #include <command.h>
+ #include <net.h>
+ 
++#if defined(CONFIG_CMD_NAND) && defined(CONFIG_SYS_DIRECT_FLASH_TFTP)
++int tftpboot2nand=0;	/* set to 1 for tftp to nand direct */
++#endif
++
+ static int netboot_common(enum proto_t, cmd_tbl_t *, int, char * const []);
+ 
+ static int do_bootp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+@@ -35,11 +39,19 @@ int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+ 	return ret;
+ }
+ 
++#if defined(CONFIG_CMD_NAND) && defined(CONFIG_SYS_DIRECT_FLASH_TFTP)
++U_BOOT_CMD(
++	tftpboot,	4,	1,	do_tftpb,
++	"boot image via network using TFTP protocol",
++	"[loadAddress] [[hostIPaddr:]bootfilename] [nand]"
++);
++#else
+ U_BOOT_CMD(
+ 	tftpboot,	3,	1,	do_tftpb,
+ 	"boot image via network using TFTP protocol",
+ 	"[loadAddress] [[hostIPaddr:]bootfilename]"
+ );
++#endif
+ 
+ #ifdef CONFIG_CMD_TFTPPUT
+ int do_tftpput(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+@@ -185,6 +197,10 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
+ 	int   size;
+ 	ulong addr;
+ 
++#if defined(CONFIG_CMD_NAND) && defined(CONFIG_SYS_DIRECT_FLASH_TFTP)
++	tftpboot2nand = 0;
++#endif
++
+ 	/* pre-set load_addr */
+ 	if ((s = getenv("loadaddr")) != NULL) {
+ 		load_addr = simple_strtoul(s, NULL, 16);
+@@ -212,8 +228,16 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
+ 
+ 		break;
+ 
+-#ifdef CONFIG_CMD_TFTPPUT
+ 	case 4:
++#if defined(CONFIG_CMD_NAND) && defined(CONFIG_SYS_DIRECT_FLASH_TFTP)
++		if( strcmp(argv[3],"nand") == 0 ) {
++			tftpboot2nand = 1;
++			load_addr = simple_strtoul(argv[1], NULL, 16);
++			copy_filename (BootFile, argv[2], sizeof(BootFile));
++			break;
++		}
++#endif
++#ifdef CONFIG_CMD_TFTPPUT
+ 		if (strict_strtoul(argv[1], 16, &save_addr) < 0 ||
+ 			strict_strtoul(argv[2], 16, &save_size) < 0) {
+ 			printf("Invalid address/size\n");
+diff --git a/net/tftp.c b/net/tftp.c
+index 59a8ebb..727e746 100644
+--- a/net/tftp.c
++++ b/net/tftp.c
+@@ -15,6 +15,11 @@
+ #include <flash.h>
+ #endif
+ 
++#if defined(CONFIG_CMD_NAND) && defined(CONFIG_SYS_DIRECT_FLASH_TFTP)
++#include <nand.h>
++extern int tftpboot2nand;
++#endif 
++
+ /* Well known TFTP port # */
+ #define WELL_KNOWN_PORT	69
+ /* Millisecs to timeout for lost pkt */
+@@ -28,6 +33,11 @@
+ /* Number of "loading" hashes per line (for checking the image size) */
+ #define HASHES_PER_LINE	65
+ 
++#if defined(CONFIG_CMD_NAND) && defined(CONFIG_SYS_DIRECT_FLASH_TFTP)
++static int temp_buf_offset = 0;
++unsigned long nand_offset = 0;
++#endif
++
+ /*
+  *	TFTP operations.
+  */
+@@ -156,12 +166,120 @@ mcast_cleanup(void)
+ 
+ #endif	/* CONFIG_MCAST_TFTP */
+ 
++#if defined(CONFIG_CMD_NAND) && defined(CONFIG_SYS_DIRECT_FLASH_TFTP)
++static size_t drop_ffs(const nand_info_t *nand, const u_char *buf,
++			const size_t *len)
++{
++	size_t l = *len;
++	ssize_t i;
++
++	for (i = l - 1; i >= 0; i--)
++		if (buf[i] != 0xFF)
++			break;
++
++	/* The resulting length must be aligned to the minimum flash I/O size */
++	l = i + 1;
++	l = (l + nand->writesize - 1) / nand->writesize;
++	l *=  nand->writesize;
++
++	/*
++	 * since the input length may be unaligned, prevent access past the end
++	 * of the buffer
++	 */
++	return min(l, *len);
++}
++
++static int tftp_nand_write(nand_info_t *meminfo, uchar *src, unsigned long *offset, size_t *length   )
++{
++/*	size_t written ;*/
++	int ret = 0;
++	loff_t offs;
++	int blockstart = -1;
++	size_t truncated_write_size;
++	/* find first non bad block */
++	do {
++		blockstart = (*offset) & (~meminfo->erasesize+1);
++		offs = blockstart;
++		ret = meminfo->_block_isbad(meminfo, offs);
++
++		if (ret < 0) {
++			printf("Bad block check failed\n");
++			return -1;
++		}
++		if (ret == 1) {
++			(*offset) = blockstart + meminfo->erasesize;
++/*			printf("\rBad block at 0x%lx "
++			       "in erase block from "
++			       "0x%x will be skipped. new offset %x\n",
++			       (long) offs,
++			       blockstart, *offset);*/
++		}
++	} while ((ret!=0) && (*offset < meminfo->size) );
++
++	if (*offset < meminfo->size) {
++		/* write out the page data */
++		truncated_write_size = drop_ffs(meminfo, src, length);
++		ret = nand_write(meminfo, *offset, &truncated_write_size, src);
++/*		ret = meminfo->write(meminfo,
++				*offset,
++				meminfo->oobblock,
++				&written,
++				src);*/
++	}
++	if (ret != 0) {
++		printf("writing NAND page at offset 0x%lx failed\n",
++		       *offset);
++		return -1;
++	}
++	return ret;
++}
++
++static void tftp_2_nand(uchar * src, unsigned len)
++{
++	#define TFTP2NAND_BUFFER_SIZE 4096
++	static u_char temp_buf[TFTP2NAND_BUFFER_SIZE];
++	size_t nand_page_size;
++	/* retrieve current nand infos */
++	nand_info_t *nand;
++	nand = &nand_info[nand_curr_device];
++
++	nand_page_size = nand->writesize;
++	if ((nand_page_size<<1) > TFTP2NAND_BUFFER_SIZE) {
++		printf("error: NAND page size too big\n");
++		net_set_state(NETLOOP_FAIL);
++		return;
++	}
++
++	if ((TftpBlkSize<<1) > TFTP2NAND_BUFFER_SIZE) {
++		printf("error: tftp block size too big\n");
++		net_set_state(NETLOOP_FAIL);
++		return;
++	}
++
++	if (len)
++		(void)memcpy((void *)(temp_buf + temp_buf_offset), src, len);
++	temp_buf_offset += len;
++	if ((temp_buf_offset >= nand_page_size) || (!len) ){
++		if( tftp_nand_write(nand, temp_buf, &nand_offset, &nand_page_size) ){
++			net_set_state(NETLOOP_FAIL);
++			return;		
++		}		
++		nand_offset += nand_page_size;
++		if (len){
++			temp_buf_offset -= nand_page_size;
++			(void)memcpy((void *)(temp_buf), (void *)(temp_buf+nand_page_size), temp_buf_offset);
++		}
++	}
++}
++#endif
++
+ static inline void
+ store_block(int block, uchar *src, unsigned len)
+ {
+ 	ulong offset = block * TftpBlkSize + TftpBlockWrapOffset;
+ 	ulong newsize = offset + len;
+ #ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
++#ifndef CONFIG_SYS_NO_FLASH	
+ 	int i, rc = 0;
+ 
+ 	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
+@@ -182,6 +276,13 @@ store_block(int block, uchar *src, unsigned len)
+ 			return;
+ 		}
+ 	} else
++#endif /* CONFIG_SYS_NO_FLASH */
++#ifdef CONFIG_CMD_NAND
++	if (tftpboot2nand) {
++		tftp_2_nand(src, len);
++	}
++	else
++#endif /* CONFIG_CMD_NAND */
+ #endif /* CONFIG_SYS_DIRECT_FLASH_TFTP */
+ 	{
+ 		(void)memcpy((void *)(load_addr + offset), src, len);
+@@ -204,6 +305,10 @@ static void new_transfer(void)
+ #ifdef CONFIG_CMD_TFTPPUT
+ 	TftpFinalBlock = 0;
+ #endif
++#if defined(CONFIG_CMD_NAND) && defined(CONFIG_SYS_DIRECT_FLASH_TFTP)
++	temp_buf_offset = 0;
++	nand_offset = load_addr;
++#endif
+ }
+ 
+ #ifdef CONFIG_CMD_TFTPPUT
+@@ -293,6 +398,13 @@ static void update_block_number(void)
+ /* The TFTP get or put is complete */
+ static void tftp_complete(void)
+ {
++#if defined(CONFIG_CMD_NAND) && defined(CONFIG_SYS_DIRECT_FLASH_TFTP)
++		/* complete write to nand with last buffer */
++		if (tftpboot2nand)
++			tftp_2_nand(NULL, 0);
++
++#endif /* defined(CONFIG_CMD_NAND) && defined(CONFIG_SYS_DIRECT_FLASH_TFTP) */
++
+ #ifdef CONFIG_TFTP_TSIZE
+ 	/* Print hash marks for the last packet received */
+ 	while (TftpTsize && TftpNumchars < 49) {
+-- 
+1.7.2.5
+
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/360-arm-support-continuous-mmu-mem-mapping.patch b/recipes-bsp/u-boot/u-boot-armadeus/360-arm-support-continuous-mmu-mem-mapping.patch
new file mode 100644
index 0000000..f06e82e
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/360-arm-support-continuous-mmu-mem-mapping.patch
@@ -0,0 +1,94 @@
+ARM: support continuous MMU memory mapping beside the regular identity mapping.
+
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+---
+diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
+index 939de10..25f0ff1 100644
+--- a/arch/arm/lib/cache-cp15.c
++++ b/arch/arm/lib/cache-cp15.c
+@@ -32,14 +32,14 @@ static void cp_delay (void)
+ 	asm volatile("" : : : "memory");
+ }
+ 
+-void set_section_dcache(int section, enum dcache_option option)
++void set_section_dcache(int section, int section_index, enum dcache_option option)
+ {
+ 	u32 *page_table = (u32 *)gd->arch.tlb_addr;
+ 	u32 value;
+ 
+ 	value = (section << MMU_SECTION_SHIFT) | (3 << 10);
+ 	value |= option;
+-	page_table[section] = value;
++	page_table[section_index] = value;
+ }
+ 
+ __weak void mmu_page_table_flush(unsigned long start, unsigned long stop)
+@@ -58,11 +58,11 @@ void mmu_set_region_dcache_behaviour(u32
+ 	debug("%s: start=%x, size=%x, option=%d\n", __func__, start, size,
+ 	      option);
+ 	for (upto = start; upto < end; upto++)
+-		set_section_dcache(upto, option);
++		set_section_dcache(upto, upto, option);
+ 	mmu_page_table_flush((u32)&page_table[start], (u32)&page_table[end]);
+ }
+ 
+-__weak void dram_bank_mmu_setup(int bank)
++__weak void dram_bank_mmu_setup(int bank, int page_offset)
+ {
+ 	bd_t *bd = gd->bd;
+ 	int	i;
+@@ -72,9 +72,9 @@ __weak void dram_bank_mmu_setup(int bank
+ 	     i < (bd->bi_dram[bank].start + bd->bi_dram[bank].size) >> 20;
+ 	     i++) {
+ #if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
+-		set_section_dcache(i, DCACHE_WRITETHROUGH);
++		set_section_dcache(i, page_offset++, DCACHE_WRITETHROUGH);
+ #else
+-		set_section_dcache(i, DCACHE_WRITEBACK);
++		set_section_dcache(i, page_offset++, DCACHE_WRITEBACK);
+ #endif
+ 	}
+ }
+@@ -84,14 +84,22 @@ static inline void mmu_setup(void)
+ {
+ 	int i;
+ 	u32 reg;
++	bd_t *bd = gd->bd;
++	int page_offset, continuity_offset;
+ 
+ 	arm_init_before_mmu();
+ 	/* Set up an identity-mapping for all 4GB, rw for everyone */
+ 	for (i = 0; i < 4096; i++)
+-		set_section_dcache(i, DCACHE_OFF);
++		set_section_dcache(i, i, DCACHE_OFF);
+ 
++	continuity_offset = bd->bi_dram[0].start >> 20;
+ 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+-		dram_bank_mmu_setup(i);
++		page_offset = (bd->bi_dram[i].start) >> 20;
++		/* direct identity mapping */
++		dram_bank_mmu_setup(i, page_offset);
++		/* secondary mapping to build a continous memory space */
++		dram_bank_mmu_setup(i, continuity_offset);
++		continuity_offset = (bd->bi_dram[i].start + bd->bi_dram[i].size) >> 20;
+ 	}
+ 
+ 	/* Copy the page table address to cp15 */
+diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
+--- a/arch/arm/include/asm/cache.h
++++ b/arch/arm/include/asm/cache.h
+@@ -27,12 +27,12 @@ static inline void invalidate_l2_cache(v
+ 
+ void l2_cache_enable(void);
+ void l2_cache_disable(void);
+-void set_section_dcache(int section, enum dcache_option option);
++void set_section_dcache(int section, int section_index, enum dcache_option option);
+ 
+ void arm_init_before_mmu(void);
+ void arm_init_domains(void);
+ void cpu_cache_initialization(void);
+-void dram_bank_mmu_setup(int bank);
++void dram_bank_mmu_setup(int bank, int page_offset);
+ 
+ #endif
+ 
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/400-imx51.patch b/recipes-bsp/u-boot/u-boot-armadeus/400-imx51.patch
new file mode 100644
index 0000000..66cebe9
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/400-imx51.patch
@@ -0,0 +1,522 @@
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+Signed-off-by: Philippe Reynes <tremyfr at yahoo.fr>
+---
+ arch/arm/cpu/armv7/cpu.c
+ arch/arm/cpu/armv7/mx5/lowlevel_init.S
+ arch/arm/include/asm/arch-mx5/imx-regs.h
+ arch/arm/include/asm/arch-mx5/iomux-mx51.h
+ arch/arm/include/asm/arch-mx5/regs_esdctl.h
+
+diff --git a/arch/arm/cpu/armv7/cpu.c b/arch/arm/cpu/armv7/cpu.c
+index 39a8023..c8c2293 100644
+--- a/arch/arm/cpu/armv7/cpu.c
++++ b/arch/arm/cpu/armv7/cpu.c
+@@ -66,5 +66,9 @@ int cleanup_before_linux(void)
+ 	 */
+ 	cpu_cache_initialization();
+ 
++#ifndef CONFIG_L2_OFF
++/*	v7_outer_cache_enable();*/
++#endif
++
+ 	return 0;
+ }
+diff --git a/arch/arm/cpu/armv7/mx5/lowlevel_init.S b/arch/arm/cpu/armv7/mx5/lowlevel_init.S
+index a40b84f..1ca9b22 100644
+--- a/arch/arm/cpu/armv7/mx5/lowlevel_init.S
++++ b/arch/arm/cpu/armv7/mx5/lowlevel_init.S
+@@ -11,6 +11,34 @@
+ #include <generated/asm-offsets.h>
+ #include <linux/linkage.h>
+ 
++#ifndef CONFIG_SYS_PLL_DP_CTL
++/* use internal oscillator */
++#define CONFIG_SYS_PLL_DP_CTL	0x00001232
++#endif
++
++#ifndef CONFIG_SYS_CLKCTL_CCSR
++/* use internal oscillator */
++#define CONFIG_SYS_CLKCTL_CCSR	0x00000000
++#endif
++
++#ifndef CONFIG_SYS_CLKTL_CBCDR
++#define CONFIG_SYS_CLKTL_CBCDR	0x59E35100
++#endif
++
++#ifndef CONFIG_SYS_CLKTL_CBCMR
++/* Use lp_apm (24MHz) source for perclk */
++#define CONFIG_SYS_CLKTL_CBCMR	0x000020C2
++#endif
++
++#ifndef CONFIG_SYS_CLKTL_CSCDR1
++#define CONFIG_SYS_CLKTL_CSCDR1 0x00C30321
++#endif
++
++#ifndef CONFIG_SYS_CLKTL_CBCMR1
++/* Use PLL 2 for UART's, get 66.5MHz from it */
++#define CONFIG_SYS_CLKTL_CBCMR1 0xA5A2A020
++#endif
++
+ .section ".text.init", "x"
+ 
+ .macro init_arm_erratum
+@@ -107,7 +135,7 @@
+ #define W_DP_MFN	8
+ 
+ setup_pll_func:
+-	ldr r1, =0x00001232
++	ldr r1, =CONFIG_SYS_PLL_DP_CTL
+ 	str r1, [r0, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */
+ 	mov r1, #0x2
+ 	str r1, [r0, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */
+@@ -124,7 +152,7 @@
+ 	str r1, [r0, #PLL_DP_MFN]
+ 	str r1, [r0, #PLL_DP_HFS_MFN]
+ 
+-	ldr r1, =0x00001232
++	ldr r1, =CONFIG_SYS_PLL_DP_CTL
+ 	str r1, [r0, #PLL_DP_CTL]
+ 1:	ldr r1, [r0, #PLL_DP_CTL]
+ 	ands r1, r1, #0x1
+@@ -136,7 +164,7 @@
+ .macro setup_pll_errata pll, freq
+ 	ldr r2, =\pll
+ 	str r4, [r2, #PLL_DP_CONFIG] /* Disable auto-restart AREN bit */
+-	ldr r1, =0x00001236
++	ldr r1, =CONFIG_SYS_PLL_DP_CTL  | 0x04
+ 	str r1, [r2, #PLL_DP_CTL]    /* Restart PLL with PLM=1 */
+ 1:	ldr r1, [r2, #PLL_DP_CTL]    /* Wait for lock */
+ 	ands r1, r1, #0x1
+@@ -165,6 +193,16 @@
+ #if defined (CONFIG_MX51)
+ 	ldr r0, =CCM_BASE_ADDR
+ 
++#ifdef CONFIG_SYS_CLKCTL_CCMR
++	ldr r1, =CONFIG_SYS_CLKCTL_CCMR
++	str r1, [r0, #CLKCTL_CCMR]
++
++	/* make sure clocks are ready */
++1:	ldr r1, [r0, #CLKCTL_CSR]
++	cmp r1, #CONFIG_SYS_CLKCTL_CSR
++	bne 1b
++#endif
++
+ 	/* Gate of clocks to the peripherals first */
+ 	ldr r1, =0x3FFFFFFF
+ 	str r1, [r0, #CLKCTL_CCGR0]
+@@ -192,7 +230,7 @@
+ 	bne 1b
+ 
+ 	/* Switch ARM to step clock */
+-	mov r1, #0x4
++	mov r1, #CONFIG_SYS_CLKCTL_CCSR | 0x04
+ 	str r1, [r0, #CLKCTL_CCSR]
+ 
+ #if defined(CONFIG_MX51_PLL_ERRATA)
+@@ -237,13 +275,14 @@
+ 	str r1, [r0, #CLKCTL_CACRR]
+ 
+ 	/* Switch ARM back to PLL 1 */
++	mov r1, #CONFIG_SYS_CLKCTL_CCSR
+-	str r4, [r0, #CLKCTL_CCSR]
++	str r1, [r0, #CLKCTL_CCSR]
+ 
+ 	/* setup the rest */
+-	/* Use lp_apm (24MHz) source for perclk */
+-	ldr r1, =0x000020C2 | CONFIG_SYS_DDR_CLKSEL
++	/* select source for perclk */
++	ldr r1, =CONFIG_SYS_CLKTL_CBCMR | CONFIG_SYS_DDR_CLKSEL
+ 	str r1, [r0, #CLKCTL_CBCMR]
+-	/* ddr clock from PLL 1, all perclk dividers are 1 since using 24MHz */
++	/* ddr clock from PLL 1 */
+ 	ldr r1, =CONFIG_SYS_CLKTL_CBCDR
+ 	str r1, [r0, #CLKCTL_CBCDR]
+ 
+@@ -258,9 +297,9 @@
+ 	str r1, [r0, #CLKCTL_CCGR6]
+ 
+ 	/* Use PLL 2 for UART's, get 66.5MHz from it */
+-	ldr r1, =0xA5A2A020
++	ldr r1, =CONFIG_SYS_CLKTL_CBCMR1
+ 	str r1, [r0, #CLKCTL_CSCMR1]
+-	ldr r1, =0x00C30321
++	ldr r1, =CONFIG_SYS_CLKTL_CSCDR1
+ 	str r1, [r0, #CLKCTL_CSCDR1]
+ 	/* make sure divider effective */
+ 1:	ldr r1, [r0, #CLKCTL_CDHIPR]
+diff --git a/arch/arm/include/asm/arch-mx5/imx-regs.h b/arch/arm/include/asm/arch-mx5/imx-regs.h
+index 46017f4..520bf98 100644
+--- a/arch/arm/include/asm/arch-mx5/imx-regs.h
++++ b/arch/arm/include/asm/arch-mx5/imx-regs.h
+@@ -255,6 +255,7 @@
+ #define M4IF_GENP_WEIM_MM_MASK		0x00000001
+ #define WEIM_GCR2_MUX16_BYP_GRANT_MASK	0x00001000
+ 
++#ifndef DP_OP_800
+ /* Assuming 24MHz input clock with doubler ON */
+ /*                            MFI         PDF */
+ #define DP_OP_864	((8 << 4) + ((1 - 1)  << 0))
+@@ -293,6 +294,7 @@
+ #define DP_OP_216	((6 << 4) + ((3 - 1)  << 0))
+ #define DP_MFD_216	(4 - 1)
+ #define DP_MFN_216	3
++#endif /* DP_OP_800 */
+ 
+ #define CHIP_REV_1_0            0x10
+ #define CHIP_REV_1_1            0x11
+diff --git a/arch/arm/include/asm/arch-mx5/iomux-mx51.h b/arch/arm/include/asm/arch-mx5/iomux-mx51.h
+--- a/arch/arm/include/asm/arch-mx5/iomux-mx51.h
++++ b/arch/arm/include/asm/arch-mx5/iomux-mx51.h
+@@ -60,9 +60,17 @@ enum {
+ 	MX51_PAD_EIM_D21__USBH2_DATA5		= IOMUX_PAD(0x404, 0x070, 2, __NA_, 0, MX51_USBH_PAD_CTRL),
+ 	MX51_PAD_EIM_D22__USBH2_DATA6		= IOMUX_PAD(0x408, 0x074, 2, __NA_, 0, MX51_USBH_PAD_CTRL),
+ 	MX51_PAD_EIM_D23__USBH2_DATA7		= IOMUX_PAD(0x40c, 0x078, 2, __NA_, 0, MX51_USBH_PAD_CTRL),
++	MX51_PAD_EIM_D24__I2C2_SDA		= IOMUX_PAD(0x410, 0x07c, 0x14, 0x9bc, 0, MX51_I2C_PAD_CTRL),
+ 	MX51_PAD_EIM_D25__UART3_RXD		= IOMUX_PAD(0x414, 0x080, 3, 0x9f4, 0, MX51_UART_PAD_CTRL),
++	MX51_PAD_EIM_D25__UART2_CTS		= IOMUX_PAD(0x414, 0x080, 4, __NA_, 0, MX51_UART_PAD_CTRL),
+ 	MX51_PAD_EIM_D26__UART3_TXD		= IOMUX_PAD(0x418, 0x084, 3, __NA_, 0, MX51_UART_PAD_CTRL),
++	MX51_PAD_EIM_D26__UART2_RTS		= IOMUX_PAD(0x418, 0x084, 4, 0x9e8, 3, MX51_UART_PAD_CTRL),
++	MX51_PAD_EIM_D27__I2C2_SCL		= IOMUX_PAD(0x41c, 0x088, 0x14, 0x9b8, 0, MX51_I2C_PAD_CTRL),
+ 	MX51_PAD_EIM_D27__GPIO2_9		= IOMUX_PAD(0x41c, 0x088, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
++	MX51_PAD_EIM_D28__AUD6_TXD		= IOMUX_PAD(0x420, 0x08c, 5, 0x8f0, 0, NO_PAD_CTRL),
++	MX51_PAD_EIM_D29__AUD6_RXD		= IOMUX_PAD(0x424, 0x090, 5, 0x8ec, 0, NO_PAD_CTRL),
++	MX51_PAD_EIM_D30__AUD6_TXC		= IOMUX_PAD(0x428, 0x094, 5, 0x8fc, 0, NO_PAD_CTRL),
++	MX51_PAD_EIM_D31__AUD6_TXFS		= IOMUX_PAD(0x42c, 0x098, 5, 0x900, 0, NO_PAD_CTRL),
+ 	MX51_PAD_EIM_A16__GPIO2_10		= IOMUX_PAD(0x430, 0x09c, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_EIM_A17__GPIO2_11		= IOMUX_PAD(0x434, 0x0a0, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_EIM_A20__GPIO2_14		= IOMUX_PAD(0x440, 0x0ac, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
+@@ -73,16 +81,22 @@ enum {
+ 	MX51_PAD_EIM_A26__USBH2_STP		= IOMUX_PAD(0x458, 0x0c4, 2, __NA_, 0, MX51_USBH_PAD_CTRL),
+ 	MX51_PAD_EIM_A27__USBH2_NXT		= IOMUX_PAD(0x45c, 0x0c8, 2, __NA_, 0, MX51_USBH_PAD_CTRL),
+ 	MX51_PAD_EIM_EB2__FEC_MDIO		= IOMUX_PAD(0x468, 0x0d4, 3, 0x954, 0, PAD_CTL_PUS_22K_UP | PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | PAD_CTL_HYS),
+-	MX51_PAD_EIM_EB3__FEC_RDATA1		= IOMUX_PAD(0x46c, 0x0d8, 3, 0x95c, 0, NO_PAD_CTRL),
++	MX51_PAD_EIM_EB2__AUD5_RXFS		= IOMUX_PAD(0x468, 0x0d4, 6, 0x8e0, 0, NO_PAD_CTRL),
+ 	MX51_PAD_EIM_EB3__GPIO2_23		= IOMUX_PAD(0x46c, 0x0d8, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
++	MX51_PAD_EIM_EB3__FEC_RDATA1		= IOMUX_PAD(0x46c, 0x0d8, 3, 0x95c, 0, NO_PAD_CTRL),
++	MX51_PAD_EIM_EB3__AUD5_RXC		= IOMUX_PAD(0x46c, 0x0d8, 6, 0x8dc, 0, NO_PAD_CTRL),
+ 	MX51_PAD_EIM_CS0__GPIO2_25		= IOMUX_PAD(0x474, 0x0e0, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
+-	MX51_PAD_EIM_CS2__FEC_RDATA2		= IOMUX_PAD(0x47c, 0x0e8, 3, 0x960, 0, NO_PAD_CTRL),
+ 	MX51_PAD_EIM_CS2__GPIO2_27		= IOMUX_PAD(0x47c, 0x0e8, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
+-	MX51_PAD_EIM_CS3__FEC_RDATA3		= IOMUX_PAD(0x480, 0x0ec, 3, 0x964, 0, NO_PAD_CTRL),
++	MX51_PAD_EIM_CS2__FEC_RDATA2		= IOMUX_PAD(0x47c, 0x0e8, 3, 0x960, 0, NO_PAD_CTRL),
++	MX51_PAD_EIM_CS2__AUD5_TXD		= IOMUX_PAD(0x47c, 0x0e8, 6, 0x8d8, 1, NO_PAD_CTRL),
+ 	MX51_PAD_EIM_CS3__GPIO2_28		= IOMUX_PAD(0x480, 0x0ec, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
+-	MX51_PAD_EIM_CS4__FEC_RX_ER		= IOMUX_PAD(0x484, 0x0f0, 3, 0x970, 0, MX51_PAD_CTRL_2),
++	MX51_PAD_EIM_CS3__FEC_RDATA3		= IOMUX_PAD(0x480, 0x0ec, 3, 0x964, 0, NO_PAD_CTRL),
++	MX51_PAD_EIM_CS3__AUD5_RXD		= IOMUX_PAD(0x480, 0x0ec, 6, 0x8d4, 1, NO_PAD_CTRL),
+ 	MX51_PAD_EIM_CS4__GPIO2_29		= IOMUX_PAD(0x484, 0x0f0, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
++	MX51_PAD_EIM_CS4__FEC_RX_ER		= IOMUX_PAD(0x484, 0x0f0, 3, 0x970, 0, MX51_PAD_CTRL_2),
++	MX51_PAD_EIM_CS4__AUD5_TXC		= IOMUX_PAD(0x484, 0x0f0, 6, 0x8e4, 1, NO_PAD_CTRL),
+ 	MX51_PAD_EIM_CS5__FEC_CRS		= IOMUX_PAD(0x488, 0x0f4, 3, 0x950, 0, MX51_PAD_CTRL_2),
++	MX51_PAD_EIM_CS5__AUD5_TXFS		= IOMUX_PAD(0x488, 0x0f4, 6, 0x8e8, 1, NO_PAD_CTRL),
+ 	MX51_PAD_DRAM_RAS__DRAM_RAS		= IOMUX_PAD(0x4a4, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_DRAM_CAS__DRAM_CAS		= IOMUX_PAD(0x4a8, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_DRAM_SDWE__DRAM_SDWE		= IOMUX_PAD(0x4ac, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+@@ -99,18 +113,31 @@ enum {
+ 	MX51_PAD_DRAM_DQM1__DRAM_DQM1		= IOMUX_PAD(0x4d8, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_DRAM_DQM2__DRAM_DQM2		= IOMUX_PAD(0x4dc, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_DRAM_DQM3__DRAM_DQM3		= IOMUX_PAD(0x4e0, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_WE_B__NANDF_WE_B		= IOMUX_PAD(0x4e4, 0x108, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_WE_B__PATA_DIOW		= IOMUX_PAD(0x4e4, 0x108, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_RE_B__NANDF_RE_B		= IOMUX_PAD(0x4e8, 0x10c, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_RE_B__PATA_DIOR		= IOMUX_PAD(0x4e8, 0x10c, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_ALE__NANDF_ALE		= IOMUX_PAD(0x4ec, 0x110, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_ALE__PATA_BUFFER_EN	= IOMUX_PAD(0x4ec, 0x110, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_CLE__NANDF_CLE		= IOMUX_PAD(0x4f0, 0x114, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_CLE__PATA_RESET_B	= IOMUX_PAD(0x4f0, 0x114, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_WP_B__NANDF_WP_B		= IOMUX_PAD(0x4f4, 0x118, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_WP_B__PATA_DMACK		= IOMUX_PAD(0x4f4, 0x118, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_RB0__NANDF_RB0		= IOMUX_PAD(0x4f8, 0x11c, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_RB0__PATA_DMARQ		= IOMUX_PAD(0x4f8, 0x11c, 1, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_RB1__PATA_IORDY		= IOMUX_PAD(0x4fc, 0x120, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_RB1__ECSPI2_RDY		= IOMUX_PAD(0x4fc, 0x120, 2, __NA_, 0, MX51_ECSPI_PAD_CTRL),
+ 	MX51_PAD_NANDF_RB2__FEC_COL		= IOMUX_PAD(0x500, 0x124, 1, 0x94c, 0, MX51_PAD_CTRL_2),
++	MX51_PAD_NANDF_RB2__ECSPI2_SCLK		= IOMUX_PAD(0x500, 0x124, 2, __NA_, 0, MX51_ECSPI_PAD_CTRL),
+ 	MX51_PAD_NANDF_RB2__GPIO3_10		= IOMUX_PAD(0x500, 0x124, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_NANDF_RB3__FEC_RX_CLK		= IOMUX_PAD(0x504, 0x128, 1, 0x968, 0, MX51_PAD_CTRL_2),
++	MX51_PAD_NANDF_RB3__ECSPI2_MISO		= IOMUX_PAD(0x504, 0x128, 2, __NA_, 0, MX51_ECSPI_PAD_CTRL),
+ 	MX51_PAD_NANDF_RB3__GPIO3_11		= IOMUX_PAD(0x504, 0x128, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
++	MX51_PAD_EIM_SDBA2__EIM_SDBA2		= IOMUX_PAD(0x508, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_EIM_SDODT1__EIM_SDODT1		= IOMUX_PAD(0x50C, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_EIM_SDODT0__EIM_SDODT0		= IOMUX_PAD(0x510, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_GPIO_NAND__PATA_INTRQ		= IOMUX_PAD(0x514, 0x12c, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_CS0__NANDF_CS0		= IOMUX_PAD(0x518, 0x130, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_CS2__FEC_TX_ER		= IOMUX_PAD(0x520, 0x138, 2, __NA_, 0, MX51_PAD_CTRL_5),
+ 	MX51_PAD_NANDF_CS2__PATA_CS_0		= IOMUX_PAD(0x520, 0x138, 1, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_CS3__FEC_MDC		= IOMUX_PAD(0x524, 0x13c, 2, __NA_, 0, MX51_PAD_CTRL_5),
+@@ -123,13 +150,17 @@ enum {
+ 	MX51_PAD_NANDF_CS6__PATA_DA_2		= IOMUX_PAD(0x530, 0x148, 1, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_CS7__FEC_TX_EN		= IOMUX_PAD(0x534, 0x14c, 1, __NA_, 0, MX51_PAD_CTRL_5),
+ 	MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK	= IOMUX_PAD(0x538, 0x150, 1, 0x974, 0, MX51_PAD_CTRL_4),
+-	MX51_PAD_NANDF_D15__GPIO3_25		= IOMUX_PAD(0x53c, 0x154, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_NANDF_D15__PATA_DATA15		= IOMUX_PAD(0x53c, 0x154, 1, __NA_, 0, NO_PAD_CTRL),
+-	MX51_PAD_NANDF_D14__GPIO3_26		= IOMUX_PAD(0x540, 0x158, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
++	MX51_PAD_NANDF_D15__ECSPI2_MOSI		= IOMUX_PAD(0x53c, 0x154, 2, __NA_, 0, MX51_ECSPI_PAD_CTRL),
++	MX51_PAD_NANDF_D15__GPIO3_25		= IOMUX_PAD(0x53c, 0x154, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_NANDF_D14__PATA_DATA14		= IOMUX_PAD(0x540, 0x158, 1, __NA_, 0, NO_PAD_CTRL),
+-	MX51_PAD_NANDF_D13__GPIO3_27		= IOMUX_PAD(0x544, 0x15c, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
++	MX51_PAD_NANDF_D14__ECSPI2_SS3		= IOMUX_PAD(0x540, 0x158, 2, 0x934, 0, MX51_ECSPI_PAD_CTRL),
++	MX51_PAD_NANDF_D14__GPIO3_26		= IOMUX_PAD(0x540, 0x158, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_NANDF_D13__PATA_DATA13		= IOMUX_PAD(0x544, 0x15c, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_D13__ECSPI2_SS2		= IOMUX_PAD(0x544, 0x15c, 2, __NA_, 0, MX51_ECSPI_PAD_CTRL),
++	MX51_PAD_NANDF_D13__GPIO3_27		= IOMUX_PAD(0x544, 0x15c, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_NANDF_D12__PATA_DATA12		= IOMUX_PAD(0x548, 0x160, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_D12__ECSPI2_SS1		= IOMUX_PAD(0x548, 0x160, 2, 0x930, 1, MX51_ECSPI_PAD_CTRL),
+ 	MX51_PAD_NANDF_D11__FEC_RX_DV		= IOMUX_PAD(0x54c, 0x164, 2, 0x96c, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_D11__PATA_DATA11		= IOMUX_PAD(0x54c, 0x164, 1, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_D10__GPIO3_30		= IOMUX_PAD(0x550, 0x168, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
+@@ -139,16 +170,47 @@ enum {
+ 	MX51_PAD_NANDF_D9__PATA_DATA9		= IOMUX_PAD(0x554, 0x16c, 1, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_D8__FEC_TDATA0		= IOMUX_PAD(0x558, 0x170, 2, __NA_, 0, MX51_PAD_CTRL_5),
+ 	MX51_PAD_NANDF_D8__PATA_DATA8		= IOMUX_PAD(0x558, 0x170, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_D7__NANDF_D7		= IOMUX_PAD(0x55c, 0x174, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_D7__PATA_DATA7		= IOMUX_PAD(0x55c, 0x174, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_D6__NANDF_D6		= IOMUX_PAD(0x560, 0x178, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_D6__PATA_DATA6		= IOMUX_PAD(0x560, 0x178, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_D5__NANDF_D5		= IOMUX_PAD(0x564, 0x17c, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_D5__PATA_DATA5		= IOMUX_PAD(0x564, 0x17c, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_D4__NANDF_D4		= IOMUX_PAD(0x568, 0x180, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_D4__PATA_DATA4		= IOMUX_PAD(0x568, 0x180, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_D3__NANDF_D3		= IOMUX_PAD(0x56c, 0x184, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_D3__PATA_DATA3		= IOMUX_PAD(0x56c, 0x184, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_D2__NANDF_D2		= IOMUX_PAD(0x570, 0x188, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_D2__PATA_DATA2		= IOMUX_PAD(0x570, 0x188, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_D1__NANDF_D1		= IOMUX_PAD(0x574, 0x18c, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_D1__PATA_DATA1		= IOMUX_PAD(0x574, 0x18c, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_NANDF_D0__NANDF_D0		= IOMUX_PAD(0x578, 0x190, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_NANDF_D0__PATA_DATA0		= IOMUX_PAD(0x578, 0x190, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_CSI1_D8__CSI1_D8		= IOMUX_PAD(0x57c, 0x194, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_CSI1_D9__CSI1_D9		= IOMUX_PAD(0x580, 0x198, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_CSI1_D10__CSI1_D10		= IOMUX_PAD(0x584, 0x19c, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_CSI1_D11__CSI1_D11		= IOMUX_PAD(0x588, 0x1a0, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_CSI1_D12__CSI1_D12		= IOMUX_PAD(0x58c, 0x1a4, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_CSI1_D13__CSI1_D13		= IOMUX_PAD(0x590, 0x1a8, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_CSI1_D14__CSI1_D14		= IOMUX_PAD(0x594, 0x1ac, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_CSI1_D15__CSI1_D15		= IOMUX_PAD(0x598, 0x1b0, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_CSI1_D16__CSI1_D16		= IOMUX_PAD(0x59c, 0x1b4, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_CSI1_D17__CSI1_D17		= IOMUX_PAD(0x5a0, 0x1b8, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_CSI1_D18__CSI1_D18		= IOMUX_PAD(0x5a4, 0x1bc, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_CSI1_D19__CSI1_D19		= IOMUX_PAD(0x5a8, 0x1c0, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_CSI1_VSYNC__CSI1_VSYNC		= IOMUX_PAD(0x5ac, 0x1c4, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_CSI1_HSYNC__CSI1_HSYNC		= IOMUX_PAD(0x5b0, 0x1c8, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK	= IOMUX_PAD(0x5b4, __NA_, 0, 0x000, 0, NO_PAD_CTRL),
++	MX51_PAD_CSI1_MCLK__CSI1_MCLK		= IOMUX_PAD(0x5b8, __NA_, 0, 0x000, 0, NO_PAD_CTRL),
+ 	MX51_PAD_CSI2_D12__GPIO4_9		= IOMUX_PAD(0x5bc, 0x1cc, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_CSI2_D13__GPIO4_10		= IOMUX_PAD(0x5c0, 0x1d0, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
++	MX51_PAD_CSI2_D18__GPIO4_11		= IOMUX_PAD(0x5d4, 0x1e4, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
++	MX51_PAD_I2C1_CLK__I2C1_CLK		= IOMUX_PAD(0x5e8, 0x1f8, 0x10, __NA_, 0, MX51_I2C_PAD_CTRL),
++	MX51_PAD_I2C1_DAT__I2C1_DAT		= IOMUX_PAD(0x5ec, 0x1fc, 0x10, __NA_, 0, MX51_I2C_PAD_CTRL),
++	MX51_PAD_AUD3_BB_TXD__AUD3_TXD		= IOMUX_PAD(0x5f0, 0x200, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_AUD3_BB_RXD__AUD3_RXD		= IOMUX_PAD(0x5f4, 0x204, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_AUD3_BB_CK__AUD3_TXC		= IOMUX_PAD(0x5f8, 0x208, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_AUD3_BB_FS__AUD3_TXFS		= IOMUX_PAD(0x5fc, 0x20c, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI	= IOMUX_PAD(0x600, 0x210, 0, __NA_, 0, MX51_ECSPI_PAD_CTRL),
+ 	MX51_PAD_CSPI1_MISO__ECSPI1_MISO	= IOMUX_PAD(0x604, 0x214, 0, __NA_, 0, MX51_ECSPI_PAD_CTRL),
+ 	MX51_PAD_CSPI1_SS0__ECSPI1_SS0		= IOMUX_PAD(0x608, 0x218, 0, __NA_, 0, MX51_ECSPI_PAD_CTRL),
+@@ -162,6 +224,10 @@ enum {
+ 	MX51_PAD_UART1_TXD__UART1_TXD		= IOMUX_PAD(0x61c, 0x22c, 0, __NA_, 0, MX51_UART_PAD_CTRL),
+ 	MX51_PAD_UART1_RTS__UART1_RTS		= IOMUX_PAD(0x620, 0x230, 0, 0x9e0, 0, MX51_UART_PAD_CTRL),
+ 	MX51_PAD_UART1_CTS__UART1_CTS		= IOMUX_PAD(0x624, 0x234, 0, __NA_, 0, MX51_UART_PAD_CTRL),
++	MX51_PAD_UART2_RXD__UART2_RXD		= IOMUX_PAD(0x628, 0x238, 0, 0x9ec, 2, MX51_UART_PAD_CTRL),
++	MX51_PAD_UART2_TXD__UART2_TXD		= IOMUX_PAD(0x62c, 0x23c, 0, __NA_, 0, MX51_UART_PAD_CTRL),
++	MX51_PAD_UART3_RXD__UART3_RXD		= IOMUX_PAD(0x630, 0x240, 1, 0x9f4, 4, MX51_UART_PAD_CTRL),
++	MX51_PAD_UART3_TXD__UART3_TXD		= IOMUX_PAD(0x634, 0x244, 1, __NA_, 0, MX51_UART_PAD_CTRL),
+ 	MX51_PAD_USBH1_CLK__USBH1_CLK		= IOMUX_PAD(0x678, 0x278, 0, __NA_, 0, MX51_USBH_PAD_CTRL),
+ 	MX51_PAD_USBH1_DIR__USBH1_DIR		= IOMUX_PAD(0x67c, 0x27c, 0, __NA_, 0, MX51_USBH_PAD_CTRL),
+ 	MX51_PAD_USBH1_STP__GPIO1_27		= IOMUX_PAD(0x680, 0x280, 2, __NA_, 0, MX51_GPIO_PAD_CTRL),
+@@ -175,6 +241,7 @@ enum {
+ 	MX51_PAD_USBH1_DATA5__USBH1_DATA5	= IOMUX_PAD(0x69c, 0x29c, 0, __NA_, 0, MX51_USBH_PAD_CTRL),
+ 	MX51_PAD_USBH1_DATA6__USBH1_DATA6	= IOMUX_PAD(0x6a0, 0x2a0, 0, __NA_, 0, MX51_USBH_PAD_CTRL),
+ 	MX51_PAD_USBH1_DATA7__USBH1_DATA7	= IOMUX_PAD(0x6a4, 0x2a4, 0, __NA_, 0, MX51_USBH_PAD_CTRL),
++	MX51_PAD_DI1_PIN11__GPIO3_0		= IOMUX_PAD(0x6a8, 0x2a8, 4, __NA_, 0, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_DI1_PIN11__ECSPI1_SS2		= IOMUX_PAD(0x6a8, 0x2a8, 7, __NA_, 0, MX51_ECSPI_PAD_CTRL),
+ 	MX51_PAD_DI1_PIN12__GPIO3_1		= IOMUX_PAD(0x6ac, 0x2ac, 4, 0x978, 1, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_DI1_PIN13__GPIO3_2		= IOMUX_PAD(0x6b0, 0x2b0, 4, 0x97c, 1, MX51_GPIO_PAD_CTRL),
+@@ -182,10 +249,30 @@ enum {
+ 	MX51_PAD_DI1_D1_CS__GPIO3_4		= IOMUX_PAD(0x6b8, 0x2b8, 4, 0x984, 1, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_DISPB2_SER_DIN__GPIO3_5	= IOMUX_PAD(0x6bc, 0x2bc, 4, 0x988, 1, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_DISPB2_SER_DIO__GPIO3_6	= IOMUX_PAD(0x6c0, 0x2c0, 4, 0x98c, 1, MX51_GPIO_PAD_CTRL),
++	MX51_PAD_DISPB2_SER_CLK__GPIO3_7	= IOMUX_PAD(0x6c4, 0x2c4, 4, 0x990, 1, MX51_GPIO_PAD_CTRL),
++	MX51_PAD_DISPB2_SER_RS__GPIO3_8		= IOMUX_PAD(0x6c8, 0x2c8, 4, 0x994, 1, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_DI1_PIN3__DI1_PIN3		= IOMUX_PAD(0x72c, 0x32c, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_DI1_PIN2__DI1_PIN2		= IOMUX_PAD(0x734, 0x330, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_DI_GP3__FEC_TX_ER		= IOMUX_PAD(0x744, 0x33c, 2, __NA_, 0, MX51_PAD_CTRL_5),
++	MX51_PAD_DI2_PIN4__FEC_CRS		= IOMUX_PAD(0x748, 0x340, 2, 0x950, 1, NO_PAD_CTRL),
++	MX51_PAD_DI2_PIN2__FEC_MDC		= IOMUX_PAD(0x74c, 0x344, 2, __NA_, 0, MX51_PAD_CTRL_5),
++	MX51_PAD_DI2_PIN3__FEC_MDIO		= IOMUX_PAD(0x750, 0x348, 2, 0x954, 1, NO_PAD_CTRL),
+ 	MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK	= IOMUX_PAD(0x754, 0x34c, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_DI2_DISP_CLK__FEC_RDATA1	= IOMUX_PAD(0x754, 0x34c, 2, 0x95c, 1, NO_PAD_CTRL),
++	MX51_PAD_DI_GP4__FEC_RDATA2		= IOMUX_PAD(0x758, 0x350, 2, 0x960, 1, NO_PAD_CTRL),
+ 	MX51_PAD_DI_GP4__DI2_PIN15		= IOMUX_PAD(0x758, 0x350, 4, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_DISP2_DAT0__FEC_RDATA3		= IOMUX_PAD(0x75c, 0x354, 2, 0x964, 1, NO_PAD_CTRL),
++	MX51_PAD_DISP2_DAT1__FEC_RX_ER		= IOMUX_PAD(0x760, 0x358, 2, 0x970, 1, NO_PAD_CTRL),
++	MX51_PAD_DISP2_DAT6__FEC_TDATA1		= IOMUX_PAD(0x774, 0x36c, 2, __NA_, 0, MX51_PAD_CTRL_5),
++	MX51_PAD_DISP2_DAT7__FEC_TDATA2		= IOMUX_PAD(0x778, 0x370, 2, __NA_, 0, MX51_PAD_CTRL_5),
++	MX51_PAD_DISP2_DAT8__FEC_TDATA3		= IOMUX_PAD(0x77c, 0x374, 2, __NA_, 0, MX51_PAD_CTRL_5),
++	MX51_PAD_DISP2_DAT9__FEC_TX_EN		= IOMUX_PAD(0x780, 0x378, 2, __NA_, 0, MX51_PAD_CTRL_5),
++	MX51_PAD_DISP2_DAT10__FEC_COL		= IOMUX_PAD(0x784, 0x37c, 2, 0x94c, 1, NO_PAD_CTRL),
++	MX51_PAD_DISP2_DAT11__FEC_RX_CLK	= IOMUX_PAD(0x788, 0x380, 2, 0x968, 1, NO_PAD_CTRL),
++	MX51_PAD_DISP2_DAT12__FEC_RX_DV		= IOMUX_PAD(0x78c, 0x384, 2, 0x96c, 1, NO_PAD_CTRL),
++	MX51_PAD_DISP2_DAT13__FEC_TX_CLK	= IOMUX_PAD(0x790, 0x388, 2, 0x974, 1, MX51_PAD_CTRL_4),
++	MX51_PAD_DISP2_DAT14__FEC_RDATA0	= IOMUX_PAD(0x794, 0x38c, 2, 0x958, 1, MX51_PAD_CTRL_4),
++	MX51_PAD_DISP2_DAT15__FEC_TDATA0	= IOMUX_PAD(0x798, 0x390, 2, __NA_, 0, MX51_PAD_CTRL_5),
+ 	MX51_PAD_SD1_CMD__SD1_CMD		= IOMUX_PAD(0x79c, 0x394, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL),
+ 	MX51_PAD_SD1_CLK__SD1_CLK		= IOMUX_PAD(0x7a0, 0x398, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS),
+ 	MX51_PAD_SD1_DATA0__SD1_DATA0		= IOMUX_PAD(0x7a4, 0x39c, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL),
+@@ -204,13 +291,17 @@ enum {
+ 	MX51_PAD_GPIO1_2__GPIO1_2		= IOMUX_PAD(0x7d4, 0x3cc, 0, __NA_, 0, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_GPIO1_2__PWM1_PWMO		= IOMUX_PAD(0x7d4, 0x3cc, 1, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_GPIO1_3__GPIO1_3		= IOMUX_PAD(0x7d8, 0x3d0, 0, __NA_, 0, MX51_GPIO_PAD_CTRL),
++	MX51_PAD_GPIO1_3__PWM2_PWMO		= IOMUX_PAD(0x7d8, 0x3d0, 1, __NA_, 0, NO_PAD_CTRL),
++	MX51_PAD_GPIO1_4__GPIO1_4		= IOMUX_PAD(0x804, 0x3d8, 0, __NA_, 0, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_GPIO1_5__GPIO1_5		= IOMUX_PAD(0x808, 0x3dc, 0, __NA_, 0, MX51_GPIO_PAD_CTRL),
++	MX51_PAD_GPIO1_5__CCM_CLKO		= IOMUX_PAD(0x808, 0x3dc, 5, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_PAD_GPIO1_6__GPIO1_6		= IOMUX_PAD(0x80c, 0x3e0, 0, __NA_, 0, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_GPIO1_7__GPIO1_7		= IOMUX_PAD(0x810, 0x3e4, 0, __NA_, 0, MX51_GPIO_PAD_CTRL),
+ 	MX51_PAD_GPIO1_7__SD2_WP		= IOMUX_PAD(0x810, 0x3e4, 6, __NA_, 0, MX51_ESDHC_PAD_CTRL),
+ 	MX51_PAD_GPIO1_8__SD2_CD		= IOMUX_PAD(0x814, 0x3e8, 6, __NA_, 0, MX51_ESDHC_PAD_CTRL),
+ 	MX51_GRP_DDRPKS				= IOMUX_PAD(0x820, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_GRP_DRAM_B4			= IOMUX_PAD(0x82c, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_GRP_INDDR				= IOMUX_PAD(0x830, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_GRP_PKEDDR				= IOMUX_PAD(0x838, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_GRP_DDR_A0				= IOMUX_PAD(0x83c, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_GRP_DDR_A1				= IOMUX_PAD(0x848, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+@@ -218,6 +309,7 @@ enum {
+ 	MX51_GRP_HYSDDR0			= IOMUX_PAD(0x85c, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_GRP_HYSDDR1			= IOMUX_PAD(0x864, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_GRP_HYSDDR2			= IOMUX_PAD(0x86c, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_GRP_HVDDR				= IOMUX_PAD(0x870, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_GRP_HYSDDR3			= IOMUX_PAD(0x874, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_GRP_DRAM_SR_B0			= IOMUX_PAD(0x878, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_GRP_DDRAPKS			= IOMUX_PAD(0x87c, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+@@ -229,6 +321,7 @@ enum {
+ 	MX51_GRP_INMODE1			= IOMUX_PAD(0x8a0, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_GRP_DRAM_B0			= IOMUX_PAD(0x8a4, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_GRP_DRAM_B1			= IOMUX_PAD(0x8ac, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
++	MX51_GRP_DDR_SR_A0			= IOMUX_PAD(0x8b0, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_GRP_DRAM_B2			= IOMUX_PAD(0x8b8, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ 	MX51_GRP_DDR_SR_A1			= IOMUX_PAD(0x8bc, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
+ };
+diff --git a/arch/arm/include/asm/arch-mx5/regs_esdctl.h b/arch/arm/include/asm/arch-mx5/regs_esdctl.h
+new file mode 100644
+index 0000000..1c0bf8e
+--- /dev/null
++++ b/arch/arm/include/asm/arch-mx5/regs_esdctl.h
+@@ -0,0 +1,114 @@
++/*
++ * Copyright (C) 2012 Eric Jarrige <eric.jarrige at armadeus.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++
++#ifndef __REGS_ESDCTL_H__
++#define __REGS_ESDCTL_H__
++
++
++#ifndef	__ASSEMBLY__
++/* ESDCTL registers */
++#if defined(CONFIG_MX51)
++struct esdctl_regs {
++	u32	esdctl0;
++	u32	esdcfg0;
++	u32	esdctl1;
++	u32	esdcfg1;
++	u32	esdmisc;
++	u32	esdscr;
++	u32	reserved[2];
++	u32	esdcdly1;
++	u32	esdcdly2;
++	u32	esdcdly3;
++	u32	esdcdly4;
++	u32	esdcdly5;
++	u32	esdgpr;
++	u32	esdprct0;
++	u32	esdprct1;
++};
++#elif defined(CONFIG_MX53)
++struct esdctl_regs {
++	u32	esdctl;
++	u32	esdpdc;
++	u32	esdotc;
++	u32	esdcfg0;
++	u32	esdcfg1;
++	u32	esdcfg2;
++	u32	esdmisc;
++	u32	esdscr;
++	u32	esdref;
++	u32	esdwcc;
++	u32	esdrcc;
++	u32	esdrwd;
++	u32	esdor;
++	u32	esdmrr;
++	u32	esdcfg3_lp;
++	u32	esdmr4;
++	u32	zqhwctrl;
++	u32	zqswctrl;
++	u32	wlgcr;
++	u32	wldectrl0;
++	u32	wldectrl1;
++	u32	wldlst;
++	u32	odtctrl;
++	u32	rddqby0dl;
++	u32	rddqby1dl;
++	u32	rddqby2dl;
++	u32	rddqby3dl;
++	u32	wrdqby0dl;
++	u32	wrdqby1dl;
++	u32	wrdqby2dl;
++	u32	wrdqby3dl;
++	u32	dgctrl0;
++	u32	dgctrl1;
++	u32	dgdlst;
++	u32	rddlctl;
++	u32	rddlst;
++	u32	wrlctl;
++	u32	wrlst;
++	u32	sdctrl;
++	u32	zqlp2ctl;
++	u32	rddlhwctl;
++	u32	wrdlhwctl;
++	u32	rddlhwst0;
++	u32	rddlhwst1;
++	u32	wrdlhwst0;
++	u32	wrdlhwst1;
++	u32	wlhwerr;
++	u32	dghwst0;
++	u32	dghwst1;
++	u32	dghwst2;
++	u32	dghwst3;
++	u32	pdcmpr1;
++	u32	pdcmpr2;
++	u32	swdar;
++	u32	swdrdr0;
++	u32	swdrdr1;
++	u32	swdrdr2;
++	u32	swdrdr3;
++	u32	swdrdr4;
++	u32	swdrdr5;
++	u32	swdrdr6;
++	u32	swdrdr7;
++	u32	mur;
++	u32	wrcadl;
++};
++#endif
++
++#endif /* __ASSEMBLY__ */
++
++/* DDR commands */
++/* cs ChipSelect in range of 0..1 */
++/* ba Bank Address in range of 0..3 */
++/* addr Pseudo Address as expected by the DDR */
++
++#define DDR_NOP_CMD(cs)		(0x00008000 + (cs << 2))
++#define DRR_PRECHARGE_CMD(cs, ba)	(0x04008008 + (cs << 2) + ba)
++#define DRR_AUTOREFRESH_CMD(cs)	(0x00008010 + (cs << 2))
++#define DRR_LMR_CMD(cs, ba, addr)	(0x00008018 + (addr << 16)\
++						+ (cs << 2) + ba)
++
++#endif /* __REGS_ESDCTL_H__ */
+-- 
+1.7.2.5
+
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/401-apf51.patch b/recipes-bsp/u-boot/u-boot-armadeus/401-apf51.patch
new file mode 100644
index 0000000..b6201ea
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/401-apf51.patch
@@ -0,0 +1,1001 @@
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+Signed-off-by: Nicolas Colombain <nicolas.colombain at armadeus.com>
+Signed-off-by: Philippe Reynes <tremyfr at yahoo.fr>
+---
+ board/armadeus/apf51/Makefile |   43 ++
+ board/armadeus/apf51/apf51.c  | 1222 +++++++++++++++++++++++++++++++++++++++++
+ board/armadeus/apf51/fpga.c   |  266 +++++++++
+ board/armadeus/apf51/fpga.h   |   39 ++
+ boards.cfg                    |    1 +
+ 5 files changed, 1571 insertions(+), 0 deletions(-)
+ create mode 100644 board/armadeus/apf51/Makefile
+ create mode 100644 board/armadeus/apf51/apf51.c
+ create mode 100644 board/armadeus/apf51/fpga.c
+ create mode 100644 board/armadeus/apf51/fpga.h
+
+diff --git a/board/armadeus/apf51/Makefile b/board/armadeus/apf51/Makefile
+new file mode 100644
+index 0000000..9d94f74
+--- /dev/null
++++ b/board/armadeus/apf51/Makefile
+@@ -0,0 +1,9 @@
++#
++# (C) Copyright 2000-2006
++# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++obj-y	:= apf51.o fpga.o
++
+diff --git a/board/armadeus/apf51/apf51.c b/board/armadeus/apf51/apf51.c
+new file mode 100644
+index 0000000..8ff1381
+--- /dev/null
++++ b/board/armadeus/apf51/apf51.c
+@@ -0,0 +1,677 @@
++/*
++ * Armadeus APF51 baseboard
++ *
++ * (C) Copyright 2010-2014 Eric Jarrige, Armadeus Project
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <command.h>
++#include <environment.h>
++#include <asm/armv7.h>
++#include <asm/arch/clock.h>
++#include <asm/arch/crm_regs.h>
++#include <asm/arch/imx-regs.h>
++#include <asm/arch/iomux-mx51.h>
++#include <asm/arch/regs_esdctl.h>
++#include <asm/arch/sys_proto.h>
++#include <asm/gpio.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <i2c.h>
++#include <jffs2/jffs2.h>
++#include <fsl_esdhc.h>
++#include "fpga.h"
++#include <nand.h>
++#include <mmc.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++unsigned long boot_verb;
++
++u32 get_board_rev(void)
++{
++
++	struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
++
++	return readl(&iim->bank[1].fuse_regs[0x0f]) & 0x1f;
++}
++
++int get_num_ram_bank(void)
++{
++	struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
++	int nr_dram_banks = 1;
++
++	if ((get_board_rev() > 0) && (CONFIG_NR_DRAM_BANKS > 1))
++		nr_dram_banks += readl(&iim->bank[1].fuse_regs[0x10]) & 0x01;
++	else
++		nr_dram_banks = CONFIG_NR_DRAM_POPULATED;
++
++	return nr_dram_banks;
++}
++
++int dram_init(void)
++{
++
++	gd->ram_size = get_ram_size((void *)CSD0_BASE_ADDR, PHYS_SDRAM_1_SIZE);
++	if (get_num_ram_bank() > 1) {
++		gd->ram_size +=
++			get_ram_size((void *)CSD1_BASE_ADDR, PHYS_SDRAM_2_SIZE);
++	}
++
++	return 0;
++}
++
++void dram_init_banksize(void)
++{
++	gd->bd->bi_dram[0].start = CSD0_BASE_ADDR;
++	gd->bd->bi_dram[0].size = gd->ram_size / get_num_ram_bank();
++	if (CONFIG_NR_DRAM_BANKS > 1) {
++		gd->bd->bi_dram[1].start = CSD1_BASE_ADDR;
++		gd->bd->bi_dram[1].size = gd->ram_size
++					- gd->bd->bi_dram[0].size;
++	}
++
++}
++
++void setup_usb(void)
++{
++	/*
++	 * Configure iomux for USB interfaces
++	 */
++#define USB_PAD_CFG		(PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH | \
++				PAD_CTL_SRE_FAST)
++
++	/*
++	 * usboh1
++	 */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_USBH1_CLK__USBH1_CLK,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_USBH1_DIR__USBH1_DIR,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_USBH1_STP__USBH1_STP,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_USBH1_NXT__USBH1_NXT,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_USBH1_DATA0__USBH1_DATA0,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_USBH1_DATA1__USBH1_DATA1,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_USBH1_DATA2__USBH1_DATA2,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_USBH1_DATA3__USBH1_DATA3,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_USBH1_DATA4__USBH1_DATA4,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_USBH1_DATA5__USBH1_DATA5,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_USBH1_DATA6__USBH1_DATA6,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_USBH1_DATA7__USBH1_DATA7,
++				USB_PAD_CFG));
++	/*
++	 * usboh2
++	 */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_D16__USBH2_DATA0,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_D17__USBH2_DATA1,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_D18__USBH2_DATA2,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_D19__USBH2_DATA3,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_D20__USBH2_DATA4,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_D21__USBH2_DATA5,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_D22__USBH2_DATA6,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_D23__USBH2_DATA7,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_A24__USBH2_CLK,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_A25__USBH2_DIR,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_A26__USBH2_STP,
++				USB_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_A27__USBH2_NXT,
++				USB_PAD_CFG));
++}
++
++void setup_uart(void)
++{
++	/*
++	 * Configure iomux for UART interfaces
++	 */
++
++#define UART_PAD_CFG		(PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH | \
++				PAD_CTL_SRE_FAST)
++	/*
++	 * uart1
++	 */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_UART1_RXD__UART1_RXD,
++				UART_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_UART1_TXD__UART1_TXD,
++				UART_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_UART1_RTS__UART1_RTS,
++				UART_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_UART1_CTS__UART1_CTS,
++				UART_PAD_CFG));
++	/*
++	 * uart2
++	 */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_D25__UART2_CTS,
++				UART_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_D26__UART2_RTS,
++				UART_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_UART2_RXD__UART2_RXD,
++				UART_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_UART2_TXD__UART2_TXD,
++				UART_PAD_CFG));
++	/*
++	 * uart3
++	 */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_UART3_RXD__UART3_RXD,
++				UART_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_UART3_TXD__UART3_TXD,
++				UART_PAD_CFG));
++
++}
++
++void setup_audio(void)
++{
++	/*
++	 * Configure iomux for audio interfaces
++	 */
++
++#define AUD_PAD_CFG		(PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH | \
++				PAD_CTL_SRE_FAST)
++	/*
++	 * audmux3
++	 */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_AUD3_BB_TXD__AUD3_TXD,
++				AUD_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_AUD3_BB_RXD__AUD3_RXD,
++				AUD_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_AUD3_BB_CK__AUD3_TXC,
++				AUD_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_AUD3_BB_FS__AUD3_TXFS,
++				AUD_PAD_CFG));
++	/*
++	 * audmux5
++	 */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_EB2__AUD5_RXFS,
++				AUD_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_EB3__AUD5_RXC,
++				AUD_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_CS2__AUD5_TXD,
++				AUD_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_CS3__AUD5_RXD,
++				AUD_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_CS4__AUD5_TXC,
++				AUD_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_CS5__AUD5_TXFS,
++				AUD_PAD_CFG));
++	/*
++	 * audmux6
++	 */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_D28__AUD6_TXD,
++				UART_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_D29__AUD6_RXD,
++				UART_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_D30__AUD6_TXC,
++				UART_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_D31__AUD6_TXFS,
++				UART_PAD_CFG));
++}
++
++void setup_csi(void)
++{
++	/*
++	 * Configure iomux for CSI interfaces
++	 */
++
++#define CSI_PAD_CFG		(PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH | \
++				PAD_CTL_SRE_FAST)
++	/*
++	 * csi1
++	 */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI1_D8__CSI1_D8,
++				CSI_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI1_D9__CSI1_D9,
++				CSI_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI1_D10__CSI1_D10,
++				CSI_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI1_D11__CSI1_D11,
++				CSI_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI1_D12__CSI1_D12,
++				CSI_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI1_D13__CSI1_D13,
++				CSI_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI1_D14__CSI1_D14,
++				CSI_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI1_D15__CSI1_D15,
++				CSI_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI1_D16__CSI1_D16,
++				CSI_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI1_D17__CSI1_D17,
++				CSI_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI1_D18__CSI1_D18,
++				CSI_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI1_D19__CSI1_D19,
++				CSI_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI1_VSYNC__CSI1_VSYNC,
++				CSI_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI1_HSYNC__CSI1_HSYNC,
++				CSI_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK,
++				CSI_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI1_MCLK__CSI1_MCLK,
++				CSI_PAD_CFG));
++}
++
++void setup_eim(void)
++{
++struct weim *weim = (struct weim *)WEIM_BASE_ADDR;
++
++	writel(ACFG_WCR_VALUE, &weim->wcr);
++	writel(ACFG_WIAR_VALUE, &weim->wiar);
++
++	writel(ACFG_CS1GCR1_VALUE, &weim->cs1gcr1);
++	writel(ACFG_CS2GCR1_VALUE, &weim->cs2gcr1);
++	writel(ACFG_CS3GCR1_VALUE, &weim->cs3gcr1);
++	writel(ACFG_CS4GCR1_VALUE, &weim->cs4gcr1);
++	writel(ACFG_CS5GCR1_VALUE, &weim->cs5gcr1);
++
++	writel(ACFG_CS1GCR2_VALUE, &weim->cs1gcr2);
++	writel(ACFG_CS2GCR2_VALUE, &weim->cs2gcr2);
++	writel(ACFG_CS3GCR2_VALUE, &weim->cs3gcr2);
++	writel(ACFG_CS4GCR2_VALUE, &weim->cs4gcr2);
++	writel(ACFG_CS5GCR2_VALUE, &weim->cs5gcr2);
++
++	writel(ACFG_CS1RCR1_VALUE, &weim->cs1rcr1);
++	writel(ACFG_CS2RCR1_VALUE, &weim->cs2rcr1);
++	writel(ACFG_CS3RCR1_VALUE, &weim->cs3rcr1);
++	writel(ACFG_CS4RCR1_VALUE, &weim->cs4rcr1);
++	writel(ACFG_CS5RCR1_VALUE, &weim->cs5rcr1);
++
++	writel(ACFG_CS1RCR2_VALUE, &weim->cs1rcr2);
++	writel(ACFG_CS2RCR2_VALUE, &weim->cs2rcr2);
++	writel(ACFG_CS3RCR2_VALUE, &weim->cs3rcr2);
++	writel(ACFG_CS4RCR2_VALUE, &weim->cs4rcr2);
++	writel(ACFG_CS5RCR2_VALUE, &weim->cs5rcr2);
++
++	writel(ACFG_CS1WCR1_VALUE, &weim->cs1wcr1);
++	writel(ACFG_CS2WCR1_VALUE, &weim->cs2wcr1);
++	writel(ACFG_CS3WCR1_VALUE, &weim->cs3wcr1);
++	writel(ACFG_CS4WCR1_VALUE, &weim->cs4wcr1);
++	writel(ACFG_CS5WCR1_VALUE, &weim->cs5wcr1);
++
++	writel(ACFG_CS1WCR2_VALUE, &weim->cs1wcr2);
++	writel(ACFG_CS2WCR2_VALUE, &weim->cs2wcr2);
++	writel(ACFG_CS3WCR2_VALUE, &weim->cs3wcr2);
++	writel(ACFG_CS4WCR2_VALUE, &weim->cs4wcr2);
++	writel(ACFG_CS5WCR2_VALUE, &weim->cs5wcr2);
++
++}
++
++void setup_misc(void)
++{
++	/*
++	 * Configure iomux for misc interfaces
++	 */
++
++#define GPIO_PAD_CFG		(PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH | \
++				PAD_CTL_SRE_FAST)
++
++	/* pwm 1 & 2 */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_GPIO1_2__PWM1_PWMO,
++				GPIO_PAD_CFG));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_GPIO1_3__PWM2_PWMO,
++				GPIO_PAD_CFG));
++
++	/* touch detect# */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_GPIO1_4__GPIO1_4,
++				GPIO_PAD_CFG));
++
++	/* clko */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_GPIO1_5__CCM_CLKO,
++				GPIO_PAD_CFG));
++
++	/* touch eoc# */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_GPIO1_6__GPIO1_6,
++				GPIO_PAD_CFG));
++
++	/* PMIC IRQ */
++	imx_iomux_v3_setup_pad(MX51_PAD_GPIO1_7__GPIO1_7);
++
++	/* FEC PHY RST# */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DI1_PIN11__GPIO3_0,
++				GPIO_PAD_CFG));
++
++	/* USBHOST RST# */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DI1_PIN12__GPIO3_1,
++				GPIO_PAD_CFG));
++
++	/* PMIC SLEEP# */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DISPB2_SER_CLK__GPIO3_7,
++				GPIO_PAD_CFG));
++
++	/* PMIC OFF# */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DISPB2_SER_RS__GPIO3_8,
++				GPIO_PAD_CFG));
++}
++
++void setup_fpga(void)
++{
++#define FPGA_PAD_CFG		(PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH | \
++				PAD_CTL_SRE_FAST)
++	/* FPGA PWR */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DI1_D0_CS__GPIO3_3,
++				FPGA_PAD_CFG));
++
++	/* FPGA SUSPEND */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DISPB2_SER_DIO__GPIO3_6,
++				FPGA_PAD_CFG));
++
++	/* FPGA PROG */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI2_D12__GPIO4_9,
++				FPGA_PAD_CFG));
++
++	/* FPGA DONE */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI2_D13__GPIO4_10,
++				FPGA_PAD_CFG));
++
++	/* FPGA INIT# */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_CSI2_D18__GPIO4_11,
++				FPGA_PAD_CFG));
++}
++
++void setup_display(void)
++{
++	/*
++	 * Configure iomux for display 1 interface
++	 */
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DI1_D1_CS__GPIO3_4,
++				(PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH |
++				PAD_CTL_SRE_FAST)));
++}
++
++void setup_nfc(void)
++{
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_WE_B__NANDF_WE_B,
++				PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_RE_B__NANDF_RE_B,
++				PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_CLE__NANDF_CLE,
++				PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_ALE__NANDF_ALE,
++				PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_WP_B__NANDF_WP_B,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_RB0__NANDF_RB0,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_D0__NANDF_D0,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_D1__NANDF_D1,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_D2__NANDF_D2,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_D3__NANDF_D3,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_D4__NANDF_D4,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_D5__NANDF_D5,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_D6__NANDF_D6,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_D7__NANDF_D7,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++}
++
++void setup_spi_io(void)
++{
++	/*
++	 * Configure iomux for SPI interface
++	 */
++
++#define CSPI_PAD_CFG		(PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH | \
++				PAD_CTL_SRE_FAST)
++
++	static const iomux_v3_cfg_t spi_pads[] = {
++		NEW_PAD_CTRL(MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI, CSPI_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_CSPI1_MISO__ECSPI1_MISO, CSPI_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_CSPI1_SS0__ECSPI1_SS0, CSPI_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_CSPI1_SS1__ECSPI1_SS1, CSPI_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_CSPI1_RDY__ECSPI1_RDY, CSPI_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK, CSPI_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_NANDF_RB1__ECSPI2_RDY, CSPI_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_NANDF_RB2__ECSPI2_SCLK, CSPI_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_NANDF_RB3__ECSPI2_MISO, CSPI_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_NANDF_D15__ECSPI2_MOSI, CSPI_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_NANDF_D14__ECSPI2_SS3, CSPI_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_NANDF_D13__ECSPI2_SS2, CSPI_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_NANDF_D12__ECSPI2_SS1, CSPI_PAD_CFG),
++	};
++
++	imx_iomux_v3_setup_multiple_pads(spi_pads, ARRAY_SIZE(spi_pads));
++}
++
++#ifdef CONFIG_SYS_I2C_MXC
++static void setup_i2c(unsigned int i2c_bus)
++{
++	static const iomux_v3_cfg_t i2c1_pads[] = {
++		MX51_PAD_I2C1_CLK__I2C1_CLK,
++		MX51_PAD_I2C1_DAT__I2C1_DAT,
++	};
++
++	static const iomux_v3_cfg_t i2c2_pads[] = {
++		MX51_PAD_EIM_D24__I2C2_SDA,
++		MX51_PAD_EIM_D27__I2C2_SCL,
++	};
++
++	/*
++	 * Configure iomux for I2C interfaces
++	 */
++	switch (i2c_bus) {
++	case 0:
++		imx_iomux_v3_setup_multiple_pads(i2c1_pads, ARRAY_SIZE(i2c1_pads));
++		break;
++
++	case 1:
++		imx_iomux_v3_setup_multiple_pads(i2c2_pads, ARRAY_SIZE(i2c2_pads));
++		break;
++
++	default:
++		printf("Invalid I2C bus: 0x%x\n", i2c_bus);
++		break;
++	}
++}
++#endif
++
++static void setup_fec(void)
++{
++#ifdef CONFIG_FEC_MXC
++#define FEC_PAD_CFG		(PAD_CTL_DSE_MED | PAD_CTL_HYS )
++
++	static const iomux_v3_cfg_t fec_pads[] = {
++		NEW_PAD_CTRL(MX51_PAD_DI_GP3__FEC_TX_ER, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DI2_PIN4__FEC_CRS, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DI2_PIN2__FEC_MDC, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DI2_PIN3__FEC_MDIO, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DI2_DISP_CLK__FEC_RDATA1, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DI_GP4__FEC_RDATA2, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DISP2_DAT0__FEC_RDATA3, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DISP2_DAT1__FEC_RX_ER, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DISP2_DAT6__FEC_TDATA1, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DISP2_DAT7__FEC_TDATA2, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DISP2_DAT8__FEC_TDATA3, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DISP2_DAT9__FEC_TX_EN, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DISP2_DAT10__FEC_COL, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DISP2_DAT11__FEC_RX_CLK, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DISP2_DAT12__FEC_RX_DV, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DISP2_DAT13__FEC_TX_CLK, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DISP2_DAT14__FEC_RDATA0, FEC_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_DISP2_DAT15__FEC_TDATA0, FEC_PAD_CFG),
++	};
++
++	gpio_set_value(CONFIG_SYS_PHY_RESET_GPIO, 0);
++	gpio_direction_output(CONFIG_SYS_PHY_RESET_GPIO, 0);
++
++	imx_iomux_v3_setup_multiple_pads(fec_pads, ARRAY_SIZE(fec_pads));
++
++	/* Ethernet PHY leave Reset state (POR only) */
++	gpio_set_value(CONFIG_SYS_PHY_RESET_GPIO, 1);
++	gpio_direction_output(CONFIG_SYS_PHY_RESET_GPIO, 1);
++
++#endif
++}
++
++#ifdef CONFIG_FSL_ESDHC
++
++struct fsl_esdhc_cfg esdhc_cfg[2] = {
++	{MMC_SDHC1_BASE_ADDR},
++	{MMC_SDHC2_BASE_ADDR},
++};
++
++int board_mmc_getcd(struct mmc *mmc)
++{
++	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
++	int ret = 0;
++
++	if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
++		ret = !gpio_get_value(IMX_GPIO_NR(2, 29));
++
++	return ret;
++}
++
++#define SD_PAD_CFG		(PAD_CTL_DSE_MAX | PAD_CTL_PKE | \
++				PAD_CTL_PUE | PAD_CTL_PUS_47K_UP | \
++				PAD_CTL_HYS  | PAD_CTL_SRE_FAST)
++int board_mmc_init(bd_t *bis)
++{
++	static const iomux_v3_cfg_t sd1_pads[] = {
++		MX51_PAD_EIM_CS4__GPIO2_29,
++		NEW_PAD_CTRL(MX51_PAD_SD1_CMD__SD1_CMD, SD_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_SD1_CLK__SD1_CLK, PAD_CTL_DSE_MAX | \
++				PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST),
++		NEW_PAD_CTRL(MX51_PAD_SD1_DATA0__SD1_DATA0, SD_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_SD1_DATA1__SD1_DATA1, SD_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_SD1_DATA2__SD1_DATA2, SD_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_SD1_DATA3__SD1_DATA3, SD_PAD_CFG),
++	};
++
++	static const iomux_v3_cfg_t sd2_pads[] = {
++		NEW_PAD_CTRL(MX51_PAD_SD2_CMD__SD2_CMD, SD_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_SD2_CLK__SD2_CLK, PAD_CTL_DSE_MAX | \
++				PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST),
++		NEW_PAD_CTRL(MX51_PAD_SD2_DATA0__SD2_DATA0, SD_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_SD2_DATA1__SD2_DATA1, SD_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_SD2_DATA2__SD2_DATA2, SD_PAD_CFG),
++		NEW_PAD_CTRL(MX51_PAD_SD2_DATA3__SD2_DATA3, SD_PAD_CFG),
++	};
++
++	s32 status = 0;
++	int esdh_addr = CONFIG_SYS_FSL_ESDHC_ADDR;
++
++	switch (esdh_addr) {
++	case MMC_SDHC1_BASE_ADDR:
++
++		esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
++
++		imx_iomux_v3_setup_multiple_pads(sd1_pads, ARRAY_SIZE(sd1_pads));
++
++		gpio_direction_input(IMX_GPIO_NR(2, 29));
++
++		status = fsl_esdhc_initialize(bis, &esdhc_cfg[0]);
++		break;
++	case MMC_SDHC2_BASE_ADDR:
++		esdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
++
++		imx_iomux_v3_setup_multiple_pads(sd2_pads, ARRAY_SIZE(sd2_pads));
++
++		status = fsl_esdhc_initialize(bis, &esdhc_cfg[1]);
++		break;
++	default:
++		printf("*** ERROR: SD/MMC interface %d not supported\n",
++		       esdh_addr);
++		status = 1;
++		break;
++	}
++
++	return status;
++}
++#endif
++
++int board_early_init_f(void)
++{
++	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
++	struct src *src = (struct src *)SRC_BASE_ADDR;
++
++	/* Increase freq to APF_ARM_CLK (800MHz) */
++	writel((ACFG_PLL1_CLK / APF_ARM_CLK) - 1, &mxc_ccm->cacrr);
++
++	/* Disable warm reset */
++	writel(0x560, &src->scr);
++
++	setup_misc();
++	setup_uart();
++	setup_spi_io();
++	setup_nfc();
++	setup_fec();
++#ifdef CONFIG_SYS_I2C_MXC
++	setup_i2c(1);
++#endif
++	setup_display();
++	setup_usb();
++	setup_audio();
++	setup_eim();
++	setup_csi();
++#ifdef CONFIG_FPGA
++	setup_fpga();
++#endif
++
++	return 0;
++}
++
++int board_init(void)
++{
++	/* address of boot parameters */
++	gd->bd->bi_boot_params = CSD0_BASE_ADDR + 0x100;
++
++#if defined(CONFIG_FPGA)
++	APF51_init_fpga();
++#endif
++	return 0;
++}
++
++int checkboard(void)
++{
++	printf("Board: Armadeus APF51 revision %d\n", get_board_rev());
++	return 0;
++}
++
++/*void enable_caches(void)
++{
++#ifndef CONFIG_SYS_DCACHE_OFF
++
++	dcache_enable();
++#endif
++}*/
++
++#ifndef CONFIG_L2_OFF
++void v7_outer_cache_enable(void)
++{
++	asm("mrc 15, 0, r0, c1, c0, 1");
++	asm("orr r0, r0, #0x2");
++	asm("mcr 15, 0, r0, c1, c0, 1");
++}
++
++void v7_outer_cache_disable(void)
++{
++	asm("mrc 15, 0, r0, c1, c0, 1");
++	asm("bic r0, r0, #0x2");
++	asm("mcr 15, 0, r0, c1, c0, 1");
++}
++#endif
+diff --git a/board/armadeus/apf51/fpga.c b/board/armadeus/apf51/fpga.c
+new file mode 100644
+index 0000000..665928e
+--- /dev/null
++++ b/board/armadeus/apf51/fpga.c
+@@ -0,0 +1,240 @@
++/*
++ * Copyright (C) 2002-2010
++ * Nicolas Colombain <nicolas.colombain at armadeus.com>
++ * Rich Ireland, Enterasys Networks, rireland at enterasys.com.
++ * Keith Outwater, keith_outwater at mvis.com.
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++#include <common.h>
++
++#if defined(CONFIG_FPGA)
++
++#include <asm/arch/crm_regs.h>
++#include <asm/arch/imx-regs.h>
++#include <asm/gpio.h>
++#include <generated/asm-offsets.h>
++#include <asm/io.h>
++#include <command.h>
++#include <config.h>
++#include <asm/arch/iomux-mx51.h>
++#include "fpga.h"
++#include <spartan3.h>
++
++#ifdef FPGA_DEBUG
++#define		PRINTF(fmt, args...)	printf(fmt , ##args)
++#else
++#define		PRINTF(fmt, args...)
++#endif
++
++static u32 temp_clk;		/* use to restore the emi_clk_sel after donwload */
++static u32 temp_rcr1;
++static u32 temp_wcr1;
++static u32 temp_data;
++static u32 temp_index;
++
++/* Note that these are pointers to code that is in Flash.  They will be
++ * relocated at runtime.
++ * Spartan2 code is used to download our Spartan 6 :) code is compatible.
++ * Just take care about the file size
++*/
++xilinx_spartan3_slave_parallel_fns fpga_fns = {
++	fpga_pre_fn,
++	fpga_pgm_fn,
++	fpga_init_fn,
++	NULL,
++	fpga_done_fn,
++	fpga_clk_fn,
++	fpga_cs_fn,
++	fpga_wr_fn,
++	fpga_rdata_fn,
++	fpga_wdata_fn,
++	fpga_busy_fn,
++	fpga_abort_fn,
++	fpga_post_fn,
++};
++
++xilinx_desc fpga[CONFIG_FPGA_COUNT] = {
++	{xilinx_spartan3,
++	 slave_parallel,
++	 3713568l / 8,
++	 (void *)&fpga_fns,
++	 0}
++};
++
++/*
++ *
++ */
++int fpga_pre_fn(int cookie)
++{
++#define EMI_CLK_SEL		1<<26
++	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
++	struct weim *weim = (struct weim *)WEIM_BASE_ADDR;
++
++	temp_index = 0;
++	temp_rcr1 = readl(&weim->cs1rcr1);
++	writel(0x01000010, &weim->cs1rcr1);
++	temp_wcr1 = readl(&weim->cs1wcr1);
++	writel(0x01000008, &weim->cs1wcr1);
++
++	/* change emi_clk_sel to ensure blck smaller than 50MHz */
++	temp_clk = readl(&mxc_ccm->cbcdr);
++	writel(temp_clk | EMI_CLK_SEL, &mxc_ccm->cbcdr);
++
++	/* FPGA PROG */
++	gpio_set_value(ACFG_FPGA_PRG, 1);
++	gpio_direction_output(ACFG_FPGA_PRG, 1);
++
++	/* FPGA SUSPEND */
++	gpio_set_value(ACFG_FPGA_SUSPEND, 1);
++	gpio_direction_output(ACFG_FPGA_SUSPEND, 1);
++
++	/* FPGA DONE */
++	gpio_direction_input(ACFG_FPGA_DONE);
++
++	/* FPGA INIT# */
++	gpio_direction_input(ACFG_FPGA_INIT);
++
++	/* FPGA PWR */
++	gpio_set_value(ACFG_FPGA_PWR, 1);
++	gpio_direction_output(ACFG_FPGA_PWR, 1);
++
++	PRINTF("FPGA power enabled\n");
++
++	return cookie;
++}
++
++/*
++ * Set the FPGA's active-low program line to the specified level
++ */
++int fpga_pgm_fn(int assert, int flush, int cookie)
++{
++	PRINTF("%s:%d: FPGA PROGRAM %s\n", __func__, __LINE__,
++		assert ? "high" : "low");
++	gpio_set_value(ACFG_FPGA_PRG, !assert);
++	return assert;
++}
++
++/*
++ * Set the FPGA's active-high clock line to the specified level
++ */
++int fpga_clk_fn(int assert_clk, int flush, int cookie)
++{
++	return assert_clk;
++}
++
++/*
++ * Test the state of the active-low FPGA INIT line.  Return 1 on INIT
++ * asserted (low).
++ */
++int fpga_init_fn(int cookie)
++{
++	int value;
++	PRINTF("%s:%d: INIT check...\n", __func__, __LINE__);
++	value = gpio_get_value(ACFG_FPGA_INIT);
++	PRINTF("init value read %x\n", value);
++	if (value)
++		return 0;
++	return 1;
++}
++
++/*
++ * Test the state of the active-high FPGA DONE pin
++ */
++int fpga_done_fn(int cookie)
++{
++	int value;
++	value = gpio_get_value(ACFG_FPGA_DONE);
++	PRINTF("%s:%d: DONE check... %s", __func__, __LINE__,
++	       value ? "high" : "low");
++	return value ? FPGA_SUCCESS : FPGA_FAIL;
++}
++
++/*
++ * Set the FPGA's wr line to the specified level
++ */
++int fpga_wr_fn(int assert_write, int flush, int cookie)
++{
++	return assert_write;
++}
++
++int fpga_cs_fn(int assert_cs, int flush, int cookie)
++{
++	return assert_cs;
++}
++
++int fpga_rdata_fn(unsigned char *data, int cookie)
++{
++	PRINTF("%s:%d: FPGA READ DATA %02X\n", __func__, __LINE__,
++	       *((char *)ACFG_FPGA_RDATA));
++	*data =
++	    (unsigned char)((*((unsigned short *)ACFG_FPGA_RDATA)) &
++			    0x00FF);
++	return *data;
++}
++
++int fpga_wdata_fn(unsigned char data, int flush, int cookie)
++{
++	PRINTF("%s:%d: FPGA WRITE DATA %02X\n", __func__, __LINE__, data);
++
++	switch (temp_index++) {
++	case 0:
++		temp_data = data << 8;
++		break;
++	case 1:
++		temp_data = temp_data + data;
++		break;
++	case 2:
++		temp_data = temp_data + (data << 24);
++		break;
++	default:
++		*((unsigned long *)ACFG_FPGA_WDATA) = temp_data + (data << 16);
++		temp_index = 0;
++		break;
++	}
++
++	return data;
++}
++
++int fpga_abort_fn(int cookie)
++{
++	return fpga_post_fn(cookie);
++}
++
++int fpga_busy_fn(int cookie)
++{
++	return 1;
++}
++
++int fpga_post_fn(int cookie)
++{
++	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
++	struct weim *weim = (struct weim *)WEIM_BASE_ADDR;
++	PRINTF("%s:%d: FPGA POST\n", __func__, __LINE__);
++	/* restore emi_clk_sel */
++	writel(temp_clk, &mxc_ccm->cbcdr);
++	udelay(10);		/* wait a few us after emi_clk_sel change */
++	writel(temp_rcr1, &weim->cs1rcr1);
++	writel(temp_wcr1, &weim->cs1wcr1);
++
++	return cookie;
++}
++
++/*
++ * Initialize the fpga.  Return 1 on success, 0 on failure.
++ */
++int APF51_init_fpga(void)
++{
++	int i;
++
++	fpga_init();
++
++	for (i = 0; i < CONFIG_FPGA_COUNT; i++) {
++		PRINTF("%s:%d: Adding fpga %d\n", __func__, __LINE__, i);
++		fpga_add(fpga_xilinx, &fpga[i]);
++	}
++
++	return 0;
++}
++
++#endif /* CONFIG_FPGA */
+diff --git a/board/armadeus/apf51/fpga.h b/board/armadeus/apf51/fpga.h
+new file mode 100644
+index 0000000..f22f4d8
+--- /dev/null
++++ b/board/armadeus/apf51/fpga.h
+@@ -0,0 +1,22 @@
++/*
++ * Copyright (C) 2002-2010
++ * Eric Jarrige <eric.jarrige at armadeus.org>
++ * Rich Ireland, Enterasys Networks, rireland at enterasys.com.
++ * Keith Outwater, keith_outwater at mvis.com.
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++extern int APF51_init_fpga(void);
++
++extern int fpga_pre_fn(int cookie);
++extern int fpga_pgm_fn(int assert_pgm, int flush, int cookie);
++extern int fpga_cs_fn(int assert_cs, int flush, int cookie);
++extern int fpga_init_fn(int cookie);
++extern int fpga_done_fn(int cookie);
++extern int fpga_clk_fn(int assert_clk, int flush, int cookie);
++extern int fpga_wr_fn(int assert_write, int flush, int cookie);
++extern int fpga_rdata_fn(unsigned char *data, int cookie);
++extern int fpga_wdata_fn(unsigned char data, int flush, int cookie);
++extern int fpga_abort_fn(int cookie);
++extern int fpga_post_fn(int cookie);
++extern int fpga_busy_fn(int cookie);
+diff --git a/boards.cfg b/boards.cfg
+index 9df6212..1aa7e95 100644
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -302,6 +302,7 @@ Active  arm         armv7          exyno
+ Active  arm         armv7          exynos      samsung         universal_c210      s5pc210_universal                     -                                                                                                                                 Przemyslaw Marczak <p.marczak at samsung.com>
+ Active  arm         armv7          highbank    -               highbank            highbank                              -                                                                                                                                 Rob Herring <robh at kernel.org>
+ Active  arm         armv7          keystone    ti              k2hk_evm            k2hk_evm                              -                                                                                                                                 Vitaly Andrianov <vitalya at ti.com>
++Active  arm         armv7          mx5         armadeus        apf51               apf51                              apf51:IMX_CONFIG=board/armadeus/apf51/imximage.cfg                                                                                Eric Jarrige <eric.jarrige at armadeus.org>
+ Active  arm         armv7          mx5         denx            m53evk              m53evk                                m53evk:IMX_CONFIG=board/denx/m53evk/imximage.cfg                                                                                  Marek Vasut <marek.vasut at gmail.com>
+ Active  arm         armv7          mx5         esg             ima3-mx53           ima3-mx53                             ima3-mx53:IMX_CONFIG=board/esg/ima3-mx53/imximage.cfg                                                                             -
+ Active  arm         armv7          mx5         freescale       mx51evk             mx51evk                               mx51evk:IMX_CONFIG=board/freescale/mx51evk/imximage.cfg                                                                           Stefano Babic <sbabic at denx.de>
+1.7.2.5
+
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/410-imx-iim.patch b/recipes-bsp/u-boot/u-boot-armadeus/410-imx-iim.patch
new file mode 100644
index 0000000..13b5c1e
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/410-imx-iim.patch
@@ -0,0 +1,502 @@
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+Signed-off-by: Philippe Reynes <tremyfr at yahoo.fr>
+---
+ arch/arm/include/asm/arch-mx5/imx_iim.h |   61 ++++++
+ common/Makefile                         |    1 +
+ common/cmd_iim.c                        |   95 +++++++++
+ drivers/misc/Makefile                   |    1 +
+ drivers/misc/imx_iim.c                  |  333 +++++++++++++++++++++++++++++++
+ 5 files changed, 491 insertions(+), 0 deletions(-)
+ create mode 100644 arch/arm/include/asm/arch-mx5/imx_iim.h
+ create mode 100644 common/cmd_iim.c
+ create mode 100644 drivers/misc/imx_iim.c
+
+diff --git a/arch/arm/include/asm/arch-mx5/imx_iim.h b/arch/arm/include/asm/arch-mx5/imx_iim.h
+new file mode 100644
+index 0000000..c5203a0
+--- /dev/null
++++ b/arch/arm/include/asm/arch-mx5/imx_iim.h
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc.
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __IMX_IIM_H__
++#define __IMX_IIM_H__
++
++
++#define IIM_PROD_REV_SH         3
++#define IIM_PROD_REV_LEN        5
++#define IIM_SREV_REV_SH         4
++#define IIM_SREV_REV_LEN        4
++#define PROD_SIGNATURE_MX51     0x1
++
++/*
++ * IIM STAT
++ */
++#define IIM_STAT_BUSY	(1 << 7)
++#define IIM_STAT_PRGD	(1 << 1)
++#define IIM_STAT_SNSD	(1 << 0)
++
++#define IIM_ERR_SHIFT       8
++#define POLL_FUSE_PRGD      (IIM_STAT_PRGD | (IIM_ERR_PRGE << IIM_ERR_SHIFT))
++#define POLL_FUSE_SNSD      (IIM_STAT_SNSD | (IIM_ERR_SNSE << IIM_ERR_SHIFT))
++
++/*
++ * IIM ERR
++ */
++#define IIM_ERR_PRGE	(1 << 7)
++#define IIM_ERR_WPE	(1 << 6)
++#define IIM_ERR_OPE	(1 << 5)
++#define IIM_ERR_RPE	(1 << 4)
++#define IIM_ERR_WLRE	(1 << 3)
++#define IIM_ERR_SNSE	(1 << 2)
++#define IIM_ERR_PARITYE	(1 << 1)
++
++#define IIM_BANK_AREA_0_OFFSET	0x800
++#define IIM_BANK_AREA_1_OFFSET	0xc00
++#define IIM_BANK_AREA_2_OFFSET	0x1000
++#define IIM_BANK_AREA_3_OFFSET	0x1400
++
++int iim_read(int bank, char row);
++int iim_blow(int bank, int row, int val);
++int iim_blow_func(char *func_name, char *func_val);
++
++#endif
+diff --git a/common/Makefile b/common/Makefile
+index 973f05a..f368b24 100644
+--- a/common/Makefile
++++ b/common/Makefile
+@@ -113,6 +113,7 @@ ifdef CONFIG_FPGA
+ obj-$(CONFIG_CMD_FUSE) += cmd_fuse.o
+ obj-$(CONFIG_CMD_GETTIME) += cmd_gettime.o
+ obj-$(CONFIG_CMD_GPIO) += cmd_gpio.o
++obj-$(CONFIG_CMD_IIM) += cmd_iim.o
+ obj-$(CONFIG_CMD_I2C) += cmd_i2c.o
+ obj-$(CONFIG_CMD_IOTRACE) += cmd_iotrace.o
+ obj-$(CONFIG_CMD_HASH) += cmd_hash.o
+diff --git a/common/cmd_iim.c b/common/cmd_iim.c
+new file mode 100644
+index 0000000..d47ccf5
+--- /dev/null
++++ b/common/cmd_iim.c
+@@ -0,0 +1,79 @@
++/*
++ * Copyright (C) 2008-2010 Freescale Semiconductor, Inc.
++ *
++ * Copyright (C) 2007, Freescale Semiconductor, Inc
++ * Andy Fleming
++ *
++ * Based vaguely on the pxa mmc code:
++ * Copyright (C) 2003
++ * Kyle Harris, Nexus Technologies, Inc. kharris at nexus-tech.net
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <linux/types.h>
++#include <asm/io.h>
++#include <command.h>
++#include <common.h>
++#include <asm/arch/imx_iim.h>
++
++int do_iimops(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
++{
++	int bank = 0,
++		row = 0,
++		val = 0;
++
++	if (argc < 3 || argc > 5)
++		goto err_rtn;
++
++	if (strcmp(argv[1], "read") == 0) {
++		if (strcmp(argv[2], "fecmac") == 0) {
++			if (3 == argc)
++				iim_blow_func(argv[2], NULL);
++			else
++				goto err_rtn;
++		} else {
++			if (4 == argc) {
++				bank = simple_strtoul(argv[2], NULL, 16);
++				row = simple_strtoul(argv[3], NULL, 16);
++
++				iim_read(bank, row);
++			} else
++				goto err_rtn;
++		}
++	} else if (strcmp(argv[1], "blow") == 0) {
++		if (strcmp(argv[2], "fecmac") == 0) {
++			if (4 == argc)
++				iim_blow_func(argv[2], argv[3]);
++			else
++				goto err_rtn;
++		} else {
++			if (5 == argc) {
++				bank = simple_strtoul(argv[2], NULL, 16);
++				row = simple_strtoul(argv[3], NULL, 16);
++				val = simple_strtoul(argv[4], NULL, 16);
++
++				iim_blow(bank, row, val);
++			} else
++				goto err_rtn;
++		}
++	} else
++		goto err_rtn;
++
++	return 0;
++err_rtn:
++	printf("Invalid parameters!\n");
++	printf("It is too dangeous for you to use iim command.\n");
++	return 1;
++}
++
++U_BOOT_CMD(
++	iim, 5, 1, do_iimops,
++	"IIM sub system",
++	"Warning: all numbers in parameter are in hex format!\n"
++	"iim read <bank> <row>	- Read some fuses\n"
++	"iim read fecmac	- Read FEC Mac address\n"
++	"iim blow <bank> <row> <value>	- Blow some fuses\n"
++	"iim blow fecmac <0x##:0x##:0x##:0x##:0x##:0x##>"
++	"- Blow FEC Mac address");
++
+diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
+index 271463c..9a444bc 100644
+--- a/drivers/misc/Makefile
++++ b/drivers/misc/Makefile
+@@ -15,6 +15,7 @@ COBJS-$(CONFIG_ALI152X) += ali512x.o
+ obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o
+ obj-$(CONFIG_FSL_IIM) += fsl_iim.o
+ obj-$(CONFIG_GPIO_LED) += gpio_led.o
++obj-$(CONFIG_IMX_IIM) += imx_iim.o
+ obj-$(CONFIG_FSL_MC9SDZ60) += mc9sdz60.o
+ obj-$(CONFIG_MXC_OCOTP) += mxc_ocotp.o
+ obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o
+diff --git a/drivers/misc/imx_iim.c b/drivers/misc/imx_iim.c
+new file mode 100644
+index 0000000..32da5fc
+--- /dev/null
++++ b/drivers/misc/imx_iim.c
+@@ -0,0 +1,317 @@
++/*
++ * Copyright (C) 2008-2010 Freescale Semiconductor, Inc.
++ * Terry Lv
++ *
++ * Copyright (C) 2007, Freescale Semiconductor, Inc
++ * Andy Fleming
++ *
++ * Based vaguely on the pxa mmc code:
++ * Copyright (C) 2003
++ * Kyle Harris, Nexus Technologies, Inc. kharris at nexus-tech.net
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <linux/types.h>
++#include <asm/io.h>
++#include <asm/arch/imx_iim.h>
++#include <asm/arch/imx-regs.h>
++#include <net.h>
++
++static const struct iim_regs *imx_iim =
++		(struct iim_regs *)IMX_IIM_BASE;
++
++/* slen - streng length, e.g.: 23 -> slen=2; abcd -> slen=4 */
++/* only convert hex value as string input. so "12" is 0x12. */
++static u32 quick_atoi(char *a, u32 slen)
++{
++	u32 i, num = 0, digit;
++
++	for (i = 0; i < slen; i++) {
++		if (a[i] >= '0' && a[i] <= '9') {
++			digit = a[i] - '0';
++		} else if (a[i] >= 'a' && a[i] <= 'f') {
++			digit = a[i] - 'a' + 10;
++		} else if (a[i] >= 'A' && a[i] <= 'F') {
++			digit = a[i] - 'A' + 10;
++		} else {
++			printf("ERROR: %c\n", a[i]);
++			return -1;
++		}
++		num = (num * 16) + digit;
++	}
++
++    return num;
++}
++
++static void fuse_op_start(void)
++{
++	/* Do not generate interrupt */
++	writel(0, &(imx_iim->statm));
++	/* clear the status bits and error bits */
++	writel(0x3, &(imx_iim->stat));
++	writel(0xfe, &(imx_iim->err));
++}
++
++/*
++ * The action should be either:
++ *          POLL_FUSE_PRGD
++ * or:
++ *          POLL_FUSE_SNSD
++ */
++static s32 poll_fuse_op_done(s32 action)
++{
++	u32 status, error;
++
++	if (action != POLL_FUSE_PRGD && action != POLL_FUSE_SNSD) {
++		printf("%s(%d) invalid operation\n", __func__, action);
++		return -1;
++	}
++
++	/* Poll busy bit till it is NOT set */
++	while ((readl(&(imx_iim->stat)) & IIM_STAT_BUSY) != 0)
++		;
++
++	/* Test for successful write */
++	status = readl(&(imx_iim->stat));
++	error = readl(&(imx_iim->err));
++
++	if ((status & action) != 0 && \
++			(error & (action >> IIM_ERR_SHIFT)) == 0) {
++		if (error) {
++			printf("Even though the operation"
++				"seems successful...\n");
++			printf("There are some error(s) "
++				"at addr=0x%x: 0x%x\n",
++				(u32)&(imx_iim->err), error);
++		}
++		return 0;
++	}
++	printf("%s(%d) failed\n", __func__, action);
++	printf("status address=0x%x, value=0x%x\n",
++		(u32)&(imx_iim->stat), status);
++	printf("There are some error(s) at addr=0x%x: 0x%x\n",
++		(u32)&(imx_iim->err), error);
++	return -1;
++}
++
++static u32 sense_fuse(s32 bank, s32 row, s32 bit)
++{
++	s32 addr, addr_l, addr_h;
++
++	fuse_op_start();
++
++	addr = ((bank << 11) | (row << 3) | (bit & 0x7));
++	/* Set IIM Program Upper Address */
++	addr_h = (addr >> 8) & 0x000000FF;
++	/* Set IIM Program Lower Address */
++	addr_l = (addr & 0x000000FF);
++
++#ifdef IIM_FUSE_DEBUG
++	printf("%s: addr_h=0x%x, addr_l=0x%x\n",
++			__func__, addr_h, addr_l);
++#endif
++	writel(addr_h, &(imx_iim->ua));
++	writel(addr_l, &(imx_iim->la));
++
++	/* Start sensing */
++	writel(0x8, &(imx_iim->fctl));
++	if (poll_fuse_op_done(POLL_FUSE_SNSD) != 0) {
++		printf("%s(bank: %d, row: %d, bit: %d failed\n",
++			__func__, bank, row, bit);
++	}
++
++	return readl(&imx_iim->sdat);
++}
++
++int iim_read(int bank, char row)
++{
++	u32 fuse_val;
++	s32 err = 0;
++
++	printf("Read fuse at bank:%d row:%d\n", bank, row);
++	fuse_val = sense_fuse(bank, row, 0);
++	printf("fuses at (bank:%d, row:%d) = 0x%x\n", bank, row, fuse_val);
++
++	return err;
++}
++
++/* Blow fuses based on the bank, row and bit positions (all 0-based)
++*/
++static s32 fuse_blow_bit(s32 bank, s32 row, s32 bit)
++{
++	int addr, addr_l, addr_h, ret = -1;
++
++	fuse_op_start();
++
++	/* Disable IIM Program Protect */
++	writel(0xaa, &(imx_iim->prg_p));
++
++	addr = ((bank << 11) | (row << 3) | (bit & 0x7));
++	/* Set IIM Program Upper Address */
++	addr_h = (addr >> 8) & 0x000000FF;
++	/* Set IIM Program Lower Address */
++	addr_l = (addr & 0x000000FF);
++
++#ifdef IIM_FUSE_DEBUG
++	printf("blowing addr_h=0x%x, addr_l=0x%x\n", addr_h, addr_l);
++#endif
++
++	writel(addr_h, &(imx_iim->ua));
++	writel(addr_l, &(imx_iim->la));
++
++	/* Start Programming */
++	writel(0x31, &(imx_iim->fctl));
++	if (poll_fuse_op_done(POLL_FUSE_PRGD) == 0)
++		ret = 0;
++
++	/* Enable IIM Program Protect */
++	writel(0x0, &(imx_iim->prg_p));
++
++	return ret;
++}
++
++static void fuse_blow_row(s32 bank, s32 row, s32 value)
++{
++	u32 reg, i;
++
++	/* enable fuse blown */
++	reg = readl(CCM_BASE_ADDR + 0x64);
++	reg |= 0x10;
++	writel(reg, CCM_BASE_ADDR + 0x64);
++
++	for (i = 0; i < 8; i++) {
++		if (((value >> i) & 0x1) == 0)
++			continue;
++	if (fuse_blow_bit(bank, row, i) != 0) {
++			printf("fuse_blow_bit(bank: %d, row: %d, "
++				"bit: %d failed\n",
++				bank, row, i);
++		}
++    }
++    reg &= ~0x10;
++    writel(reg, CCM_BASE_ADDR + 0x64);
++}
++
++int iim_blow(int bank, int row, int val)
++{
++	u32 fuse_val, err = 0;
++
++	printf("Blowing fuse at bank:%d row:%d value:%d\n",
++			bank, row, val);
++	fuse_blow_row(bank, row, val);
++	fuse_val = sense_fuse(bank, row, 0);
++	printf("fuses at (bank:%d, row:%d) = 0x%x\n", bank, row, fuse_val);
++
++	return err;
++}
++
++static int iim_read_mac_addr(u8 *data)
++{
++	s32 bank = CONFIG_IIM_MAC_BANK;
++	s32 row  = CONFIG_IIM_MAC_ROW;
++
++	data[0] = sense_fuse(bank, row, 0) ;
++	data[1] = sense_fuse(bank, row + 1, 0) ;
++	data[2] = sense_fuse(bank, row + 2, 0) ;
++	data[3] = sense_fuse(bank, row + 3, 0) ;
++	data[4] = sense_fuse(bank, row + 4, 0) ;
++	data[5] = sense_fuse(bank, row + 5, 0) ;
++
++	if (!memcmp(data, "\0\0\0\0\0\0", 6))
++		return 0;
++	else
++		return 1;
++}
++
++int iim_blow_func(char *func_name, char *func_val)
++{
++	u32 value, i;
++	char *s;
++	char val[3];
++	s32 err = 0;
++
++	if (0 == strcmp(func_name, "scc")) {
++		/* fuse_blow scc
++	C3D153EDFD2EA9982226EF5047D3B9A0B9C7138EA87C028401D28C2C2C0B9AA2 */
++		printf("Ready to burn SCC fuses\n");
++		s = func_val;
++		for (i = 0; ; ++i) {
++			memcpy(val, s, 2);
++			val[2] = '\0';
++			value = quick_atoi(val, 2);
++			/* printf("fuse_blow_row(2, %d, value=0x%x)\n",
++					i, value); */
++			fuse_blow_row(2, i, value);
++
++			if ((++s)[0] == '\0') {
++				printf("ERROR: Odd string input\n");
++				err = -1;
++				break;
++			}
++			if ((++s)[0] == '\0') {
++				printf("Successful\n");
++				break;
++			}
++		}
++	} else if (0 == strcmp(func_name, "srk")) {
++		/* fuse_blow srk
++	418bccd09b53bee1ab59e2662b3c7877bc0094caee201052add49be8780dff95 */
++		printf("Ready to burn SRK key fuses\n");
++		s = func_val;
++		for (i = 0; ; ++i) {
++			memcpy(val, s, 2);
++			val[2] = '\0';
++			value = quick_atoi(val, 2);
++			if (i == 0) {
++				/* 0x41 goes to SRK_HASH[255:248],
++				 * bank 1, row 1 */
++				fuse_blow_row(1, 1, value);
++			} else {
++				/* 0x8b in SRK_HASH[247:240] bank 3, row 1 */
++				/* 0xcc in SRK_HASH[239:232] bank 3, row 2 */
++				/* ... */
++				fuse_blow_row(3, i, value);
++
++				if ((++s)[0] == '\0') {
++					printf("ERROR: Odd string input\n");
++					err = -1;
++					break;
++				}
++				if ((++s)[0] == '\0') {
++					printf("Successful\n");
++					break;
++				}
++			}
++		}
++	} else if (0 == strcmp(func_name, "fecmac")) {
++		u8 ea[6] = { 0 };
++
++		if (NULL == func_val) {
++			/* Read the Mac address and print it */
++			iim_read_mac_addr(ea);
++
++			printf("FEC MAC address: ");
++			printf("0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n\n",
++				ea[0], ea[1], ea[2], ea[3], ea[4], ea[5]);
++
++			return 0;
++		}
++
++		eth_parse_enetaddr(func_val, ea);
++		if (!is_valid_ether_addr(ea)) {
++			printf("Error: invalid mac address parameter!\n");
++			err = -1;
++		} else {
++			for (i = 0; i < 6; ++i)
++				fuse_blow_row(1, i + 9, ea[i]);
++		}
++	} else {
++		printf("This command is not supported\n");
++	}
++
++	return err;
++}
++
++
+-- 
+1.7.2.5
+
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/420-apf51-nand-spl-NG.patch b/recipes-bsp/u-boot/u-boot-armadeus/420-apf51-nand-spl-NG.patch
new file mode 100644
index 0000000..a9c4aa2
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/420-apf51-nand-spl-NG.patch
@@ -0,0 +1,361 @@
+Add APF51 new NAND SPL:
+- compliant with U-Boot regular SPL archictecture
+- Remove 256KiB limitation of the CPU internal SPL/IPL
+- run SPL from IRAM
+- intialize SDRAM from SPL instead of DCD: cf imx51 chip errata
+- use regular U-Boot mxc_nand driver
+- add nand loch/unlock feature
+- final binary may be launch from NAND, IRAM or SDRAM
+- use make u-boot-with-nand-spl.imx to build U-Boot with NAND SPL
+
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+
+--- a/arch/arm/imx-common/Makefile
++++ b/arch/arm/imx-common/Makefile
+@@ -73,7 +73,7 @@ u-boot-with-nand-spl.imx: spl/u-boot-nan
+ 	$(call if_changed,pad_cat)
+ 
+ quiet_cmd_u-boot-nand-spl_imx = GEN     $@
+-cmd_u-boot-nand-spl_imx = (echo -ne '\x00\x00\x00\x00\x46\x43\x42\x20\x01' && \
++cmd_u-boot-nand-spl_imx = (echo -ne '\xFE\x04\x00\xEA\xFD\x0F\x00\xEA\x01' && \
+ 	dd bs=1015 count=1 if=/dev/zero 2>/dev/null) | cat - $< > $@
+ 
+ spl/u-boot-nand-spl.imx: SPL FORCE
+--- a/board/armadeus/apf51/apf51_spl.c
++++ b/board/armadeus/apf51/apf51_spl.c
+@@ -0,0 +1,201 @@
++/*
++ * Copyright (C) 2013-2014 Eric Jarrige <eric.jarrige at armadeus.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <config.h>
++#include <spl.h>
++#include <nand.h>
++#include <asm/arch/imx-regs.h>
++#include <asm/arch/iomux-mx51.h>
++#include <asm/arch/regs_esdctl.h>
++#include <asm/io.h>
++
++/* Pointer to as well as the global data structure for SPL */
++DECLARE_GLOBAL_DATA_PTR;
++
++static inline void init_dram(void)
++{
++	struct esdctl_regs *esdctl = (struct esdctl_regs *)ESDCTL_BASE_ADDR;
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DRAM_RAS__DRAM_RAS,
++				ACFG_IOMUX_PAD_DRAM_RAS));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DRAM_CAS__DRAM_CAS,
++				ACFG_IOMUX_PAD_DRAM_CAS));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DRAM_SDWE__DRAM_SDWE,
++				ACFG_IOMUX_PAD_DRAM_SDWE));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DRAM_SDCKE0__DRAM_SDCKE0,
++				ACFG_IOMUX_PAD_DRAM_SDCKE0));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DRAM_SDCKE1__DRAM_SDCKE1,
++				ACFG_IOMUX_PAD_DRAM_SDCKE1));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DRAM_SDCLK__DRAM_SDCLK,
++				ACFG_IOMUX_PAD_DRAM_SDCLK));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DRAM_SDQS0__DRAM_SDQS0,
++				ACFG_IOMUX_PAD_DRAM_SDQS0));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DRAM_SDQS1__DRAM_SDQS1,
++				ACFG_IOMUX_PAD_DRAM_SDQS1));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DRAM_SDQS2__DRAM_SDQS2,
++				ACFG_IOMUX_PAD_DRAM_SDQS2));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DRAM_SDQS3__DRAM_SDQS3,
++				ACFG_IOMUX_PAD_DRAM_SDQS3));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DRAM_CS0__DRAM_CS0,
++				ACFG_IOMUX_PAD_DRAM_CS0));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DRAM_CS1__DRAM_CS1,
++				ACFG_IOMUX_PAD_DRAM_CS1));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DRAM_DQM0__DRAM_DQM0,
++				ACFG_IOMUX_PAD_DRAM_DQM0));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DRAM_DQM1__DRAM_DQM1,
++				ACFG_IOMUX_PAD_DRAM_DQM1));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DRAM_DQM2__DRAM_DQM2,
++				ACFG_IOMUX_PAD_DRAM_DQM2));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_DRAM_DQM3__DRAM_DQM3,
++				ACFG_IOMUX_PAD_DRAM_DQM3));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_SDBA2__EIM_SDBA2,
++				ACFG_IOMUX_PAD_EIM_SDBA2));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_SDODT1__EIM_SDODT1,
++				ACFG_IOMUX_PAD_EIM_SDODT1));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_EIM_SDODT0__EIM_SDODT0,
++				ACFG_IOMUX_PAD_EIM_SDODT0));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_DDRPKS,
++				ACFG_IOMUX_GRP_DDRPKS));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_DRAM_B4,
++				ACFG_IOMUX_GRP_DRAM_B4));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_INDDR,
++				ACFG_IOMUX_GRP_INDDR));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_PKEDDR,
++				ACFG_IOMUX_GRP_PKEDDR));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_DDR_A0,
++				ACFG_IOMUX_GRP_DDR_A0));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_DDR_A1,
++				ACFG_IOMUX_GRP_DDR_A1));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_DDRAPUS,
++				ACFG_IOMUX_GRP_DDRAPUS));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_HYSDDR0,
++				ACFG_IOMUX_GRP_HYSDDR0));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_HYSDDR1,
++				ACFG_IOMUX_GRP_HYSDDR1));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_HYSDDR2,
++				ACFG_IOMUX_GRP_HYSDDR2));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_HVDDR,
++				ACFG_IOMUX_GRP_HVDDR));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_HYSDDR3,
++				ACFG_IOMUX_GRP_HYSDDR3));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_DRAM_SR_B0,
++				ACFG_IOMUX_GRP_DDR_SR_B0));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_DDRAPKS,
++				ACFG_IOMUX_GRP_DDRAPKS));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_DRAM_SR_B1,
++				ACFG_IOMUX_GRP_DDR_SR_B1));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_DDRPUS,
++				ACFG_IOMUX_GRP_DDRPUS));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_DRAM_SR_B2,
++				ACFG_IOMUX_GRP_DDR_SR_B2));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_PKEADDR,
++				ACFG_IOMUX_GRP_PKEADDR));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_DRAM_SR_B4,
++				ACFG_IOMUX_GRP_DDR_SR_B4));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_INMODE1,
++				ACFG_IOMUX_GRP_INMODE1));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_DRAM_B0,
++				ACFG_IOMUX_GRP_DRAM_B0));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_DRAM_B1,
++				ACFG_IOMUX_GRP_DRAM_B1));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_DDR_SR_A0,
++				ACFG_IOMUX_GRP_DDR_SR_A0));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_DRAM_B2,
++				ACFG_IOMUX_GRP_DRAM_B2));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_GRP_DDR_SR_A1,
++				ACFG_IOMUX_GRP_DDR_SR_A1));
++
++/* DDR2/mDDR Configs */
++
++/* Init DDR on CS0 */
++	writel((ACFG_SDRAM_ESDCTL_REGISTER_VAL&0x8FFFFFFF), &esdctl->esdctl0);
++	writel(DRR_PRECHARGE_CMD(0, 0), &esdctl->esdscr);
++	writel(DRR_AUTOREFRESH_CMD(0), &esdctl->esdscr);
++	writel(DRR_AUTOREFRESH_CMD(0), &esdctl->esdscr);
++	writel(DRR_LMR_CMD(0, 0, ACFG_DRR_MR_VAL), &esdctl->esdscr);
++	writel(DRR_LMR_CMD(0, 2, ACFG_DRR_EMR_VAL), &esdctl->esdscr);
++	writel(DDR_NOP_CMD(0), &esdctl->esdscr);
++	writel(ACFG_SDRAM_ESDCTL_REGISTER_VAL, &esdctl->esdctl0);
++	writel(ACFG_SDRAM_ESDCFG_REGISTER_VAL, &esdctl->esdcfg0);
++/* Init DDR on CS1 */
++	writel((ACFG_SDRAM_ESDCTL_REGISTER_VAL&0x8FFFFFFF), &esdctl->esdctl1);
++	writel(DRR_PRECHARGE_CMD(1, 0), &esdctl->esdscr);
++	writel(DRR_AUTOREFRESH_CMD(1), &esdctl->esdscr);
++	writel(DRR_AUTOREFRESH_CMD(1), &esdctl->esdscr);
++	writel(DRR_LMR_CMD(1, 0, ACFG_DRR_MR_VAL), &esdctl->esdscr);
++	writel(DRR_LMR_CMD(1, 2, ACFG_DRR_EMR_VAL), &esdctl->esdscr);
++	writel(DDR_NOP_CMD(1), &esdctl->esdscr);
++	writel(ACFG_SDRAM_ESDCTL_REGISTER_VAL, &esdctl->esdctl1);
++	writel(ACFG_SDRAM_ESDCFG_REGISTER_VAL, &esdctl->esdcfg1);
++
++	writel(ACFG_SDRAM_ESDMISC_REGISTER_VAL, &esdctl->esdmisc);
++	writel(0x00000000, &esdctl->esdscr);
++
++	writel(ACFG_SDRAM_ESDGPR_REGISTER_VAL, &esdctl->esdgpr);
++	writel(ACFG_SDRAM_ESDCDLY1_REGISTER_VAL, &esdctl->esdcdly1);
++	writel(ACFG_SDRAM_ESDCDLY2_REGISTER_VAL, &esdctl->esdcdly2);
++	writel(ACFG_SDRAM_ESDCDLY3_REGISTER_VAL, &esdctl->esdcdly3);
++	writel(ACFG_SDRAM_ESDCDLY4_REGISTER_VAL, &esdctl->esdcdly4);
++	writel(ACFG_SDRAM_ESDCDLY5_REGISTER_VAL, &esdctl->esdcdly5);
++}
++
++void setup_nfc(void)
++{
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_WE_B__NANDF_WE_B,
++				PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_RE_B__NANDF_RE_B,
++				PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_CLE__NANDF_CLE,
++				PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_ALE__NANDF_ALE,
++				PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_WP_B__NANDF_WP_B,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_RB0__NANDF_RB0,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_D0__NANDF_D0,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_D1__NANDF_D1,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_D2__NANDF_D2,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_D3__NANDF_D3,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_D4__NANDF_D4,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_D5__NANDF_D5,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_D6__NANDF_D6,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_NANDF_D7__NANDF_D7,
++				PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH));
++}
++
++void spl_board_init(void)
++{
++	register ulong reg0;
++
++	asm volatile ("mov %0, pc" : "=r"(reg0));
++
++	if ((reg0 < (ulong)CSD0_BASE_ADDR) ||
++		(reg0 > (ulong)(CSD1_BASE_ADDR+PHYS_SDRAM_2_SIZE))) init_dram();
++
++	setup_nfc();
++}
++
++u32 spl_boot_device(void)
++{
++	register ulong reg0;
++	u32 boot_device = BOOT_DEVICE_NAND;
++
++	asm volatile ("mov %0, pc" : "=r"(reg0));
++
++	if ((reg0 < (ulong)CONFIG_SYS_INIT_RAM_ADDR) ||
++		(reg0 > (ulong)(CONFIG_SYS_INIT_RAM_ADDR+CONFIG_SYS_INIT_RAM_SIZE)))
++		boot_device = BOOT_DEVICE_RAM;
++
++	return boot_device;
++}
+--- a/board/armadeus/apf51/imximage.cfg
++++ b/board/armadeus/apf51/imximage.cfg
+@@ -0,0 +1,27 @@
++/*
++ * i.MX image header offset values
++ * Copyright (C) 2013 Marek Vasut <marex at denx.de>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++#include <asm/imx-common/imximage.cfg>
++
++/* image version */
++IMAGE_VERSION 1
++
++ /* Boot Offset 0x400, valid for both SD and NAND boot. */
++BOOT_OFFSET	FLASH_OFFSET_STANDARD
++
++/*
++ * Device Configuration Data (DCD)
++ *
++ * 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
++ */
++
++
+--- a/board/armadeus/apf51/Makefile
++++ b/board/armadeus/apf51/Makefile
+@@ -5,5 +5,9 @@
+ # SPDX-License-Identifier:	GPL-2.0+
+ #
+ 
++ifndef	CONFIG_SPL_BUILD
+ obj-y	:= apf51.o fpga.o
++else
++obj-y	:= apf51_spl.o
++endif
+ 
+--- a/drivers/mtd/nand/mxc_nand.c
++++ b/drivers/mtd/nand/mxc_nand.c
+@@ -1102,7 +1102,65 @@ void mxc_nand_command(struct mtd_info *m
+ 
+ 		break;
+ #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
+-   	case NAND_CMD_LOCK:
++#if defined(MXC_NFC_V3_2)
++	case NAND_CMD_LOCK:
++		/* Lock Block whole NAND only supported */
++		writenfc(NFC_V3_IPC_CREQ, &host->ip_regs->ipc);
++		while (!(readnfc(&host->ip_regs->ipc) & NFC_V3_IPC_CACK));
++		writenfc(NFC_V3_WRPROT_BLS_UNLOCK | NFC_V3_WRPROT_LOCK,
++			&host->ip_regs->wrprot);
++		writenfc(0, &host->ip_regs->ipc);
++		return;
++	case NAND_CMD_LOCK_TIGHT:
++		/* Lock Tight whole NAND only supported */
++		writenfc(NFC_V3_IPC_CREQ, &host->ip_regs->ipc);
++		while (!(readnfc(&host->ip_regs->ipc) & NFC_V3_IPC_CACK));
++		writenfc(NFC_V3_WRPROT_BLS_UNLOCK | NFC_V3_WRPROT_LOCKTIGHT,
++			&host->ip_regs->wrprot);
++		writenfc(0, &host->ip_regs->ipc);
++		return;
++	case NAND_CMD_UNLOCK1:
++		/*  64 pages per block only */
++		writenfc(NFC_V3_IPC_CREQ, &host->ip_regs->ipc);
++		while (!(readnfc(&host->ip_regs->ipc) & NFC_V3_IPC_CACK));
++		writenfc(page_addr>>7,
++				&host->ip_regs->wrprot_unlock_blkaddr);
++		writenfc(0, &host->ip_regs->ipc);
++		return;
++	case NAND_CMD_UNLOCK2:{
++		int temp;
++		writenfc(NFC_V3_IPC_CREQ, &host->ip_regs->ipc);
++		while (!(readnfc(&host->ip_regs->ipc) & NFC_V3_IPC_CACK));
++		temp = readnfc(&host->ip_regs->wrprot_unlock_blkaddr)
++			& 0x0000FFFF;
++		writenfc(((page_addr>>7)<<16) | temp ,
++				&host->ip_regs->wrprot_unlock_blkaddr);
++		/* Unlock Block Command for given address range */
++		writenfc(NFC_V3_WRPROT_BLS_UNLOCK | NFC_V3_WRPROT_UNLOCK,
++			&host->ip_regs->wrprot);
++		writenfc(0, &host->ip_regs->ipc);
++		}
++		return;
++	case NAND_CMD_LOCK_STATUS:{
++		void __iomem *main_buf = host->regs->main_area[0];
++		host->col_addr = 0;
++		host->spare_only = false;
++
++		if (((readnfc(&host->ip_regs->wrprot)>>8) & NFC_WRPR_US)
++			&& !((readnfc(&host->ip_regs->wrprot)>>8) & NFC_WRPR_LTS)
++			&& (((readnfc(&host->ip_regs->wrprot_unlock_blkaddr)>>16) >= page_addr>>7)
++			&& ((readnfc(&host->ip_regs->wrprot_unlock_blkaddr)& 0x0000FFFF) <= page_addr>>7))) {
++			writew(NFC_WRPR_US, main_buf);
++		} else if ((readnfc(&host->ip_regs->wrprot)>>8) & NFC_WRPR_LTS) {
++			writew((readnfc(&host->ip_regs->wrprot)>>8), main_buf);
++		} else {
++			writew((readnfc(&host->ip_regs->wrprot)>>8) & ~NFC_WRPR_US, main_buf);
++		}
++	}
++		return;
++
++#else /* not defined(MXC_NFC_V3_2) */
++	case NAND_CMD_LOCK:
+ 		/* Blocks to be unlocked */
+ 		writew(-1, &host->regs->unlockstart_blkaddr);
+ 		writew(-1, &host->regs->unlockend_blkaddr);
+@@ -1147,6 +1205,7 @@ void mxc_nand_command(struct mtd_info *m
+ 			writew(readw(&host->regs->nf_wrprst) & ~NFC_WRPR_US, main_buf);
+ 		}
+ 		return;
++#endif /* not defined(MXC_NFC_V3_2) */
+ #endif
+ 	}
+ 
+--- a/drivers/mtd/nand/mxc_nand.h
++++ b/drivers/mtd/nand/mxc_nand.h
+@@ -191,9 +191,12 @@ struct mxc_nand_ip_regs {
+ #define NFC_V3_CONFIG3_NO_SDMA		(1 << 20)
+ 
+ #define NFC_V3_WRPROT_UNLOCK		(1 << 2)
++#define NFC_V3_WRPROT_LOCK		(1 << 1)
++#define NFC_V3_WRPROT_LOCKTIGHT		(1 << 0)
+ #define NFC_V3_WRPROT_BLS_UNLOCK	(2 << 6)
+ 
+ #define NFC_V3_IPC_CREQ			(1 << 0)
++#define NFC_V3_IPC_CACK			(1 << 1)
+ #define NFC_V3_IPC_INT			(1 << 31)
+ 
+ #if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/501-imx28-update-and-fix.patch b/recipes-bsp/u-boot/u-boot-armadeus/501-imx28-update-and-fix.patch
new file mode 100644
index 0000000..4cd72c8
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/501-imx28-update-and-fix.patch
@@ -0,0 +1,60 @@
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+Signed-off-by: Philippe Reynes <tremyfr at yahoo.fr>
+---
+ arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd |    4 ++--
+ common/memsize.c                           |    2 ++
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd b/arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd
+index c60615a..f533ad0 100644
+--- a/arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd
++++ b/arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd
+@@ -8,7 +8,7 @@ section (0) {
+ 	load ivt (entry = 0x0014) > 0x8000;
+ 	hab call 0x8000;
+ 
+-	load u_boot > 0x40000100;
+-	load ivt (entry = 0x40000100) > 0x8000;
++	load u_boot > 0x40000000;
++	load ivt (entry = 0x40000000) > 0x8000;
+ 	hab call 0x8000;
+ }
+--- a/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg
++++ b/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg
+@@ -3,6 +3,6 @@ SECTION 0x0 BOOTABLE
+  LOAD     0x1000     spl/u-boot-spl.bin
+  LOAD IVT 0x8000     0x1000
+  CALL HAB 0x8000     0x0
+- LOAD     0x40002000 u-boot.bin
+- LOAD IVT 0x8000     0x40002000
++ LOAD     0x40000000 u-boot.bin
++ LOAD IVT 0x8000     0x40000000
+  CALL HAB 0x8000     0x0
+--- a/include/configs/mxs.h
++++ b/include/configs/mxs.h
+@@ -89,7 +89,9 @@
+  * As for the SPL, we must avoid the first 4 KiB as well, but we load the
+  * IVT and CST to 0x8000, so we don't need to waste the subsequent 4 KiB.
+  */
++#ifndef CONFIG_SYS_TEXT_BASE
+ #define CONFIG_SYS_TEXT_BASE		0x40002000
++#endif
+ #define CONFIG_SPL_TEXT_BASE		0x00001000
+ 
+ /* U-Boot general configuration */
+diff --git a/common/memsize.c b/common/memsize.c
+index 963e4f3..a9f76bc 100644
+--- a/common/memsize.c
++++ b/common/memsize.c
+@@ -61,6 +61,8 @@ long get_ram_size(long *base, long maxsize)
+ 		return (0);
+ 	}
+ 
++	sync();
++	*addr = save[i];
+ 	for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) {
+ 		addr = base + cnt;	/* pointer arith! */
+ 		val = *addr;
+-- 
+1.7.2.5
+
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/502-add-apf28.patch b/recipes-bsp/u-boot/u-boot-armadeus/502-add-apf28.patch
new file mode 100644
index 0000000..74da664
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/502-add-apf28.patch
@@ -0,0 +1,1186 @@
+Signed-off-by: Eric Jarrige <eric.jarrige at armadeus.org>
+Signed-off-by: Philippe Reynes <tremyfr at yahoo.fr>
+---
+ board/armadeus/apf28/Makefile    |   50 ++++
+ board/armadeus/apf28/apf28.c     |  191 +++++++++++++
+ board/armadeus/apf28/cmd_ocotp.c |  269 ++++++++++++++++++
+ board/armadeus/apf28/mx28_bcb.c  |  559 ++++++++++++++++++++++++++++++++++++++
+ board/armadeus/apf28/spl_boot.c  |  206 ++++++++++++++
+ boards.cfg                       |    1 +
+ 6 files changed, 1276 insertions(+), 0 deletions(-)
+ create mode 100644 board/armadeus/apf28/Makefile
+ create mode 100644 board/armadeus/apf28/apf28.c
+ create mode 100644 board/armadeus/apf28/cmd_ocotp.c
+ create mode 100644 board/armadeus/apf28/mx28_bcb.c
+ create mode 100644 board/armadeus/apf28/spl_boot.c
+
+diff --git a/board/armadeus/apf28/Makefile b/board/armadeus/apf28/Makefile
+new file mode 100644
+index 0000000..029e58d
+--- /dev/null
++++ b/board/armadeus/apf28/Makefile
+@@ -0,0 +1,13 @@
++#
++# (C) Copyright 2000-2006
++# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++ifndef	CONFIG_SPL_BUILD
++obj-y	:= mx28_bcb.o apf28.o
++obj-$(CONFIG_IMX_OCOTP) += cmd_ocotp.o
++else
++obj-y	:= spl_boot.o
++endif
+diff --git a/board/armadeus/apf28/apf28.c b/board/armadeus/apf28/apf28.c
+new file mode 100644
+index 0000000..7f75494
+--- /dev/null
++++ b/board/armadeus/apf28/apf28.c
+@@ -0,0 +1,130 @@
++/*
++ * APF28 motherboard based on DENX M28 module
++ *
++ * Copyright (C) 2012-2014 Eric Jarrige <eric.jarrige at armadeus.org>
++ * Copyright (C) 2011 Marek Vasut <marek.vasut at gmail.com>
++ * on behalf of DENX Software Engineering GmbH
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <environment.h>
++#include <asm/gpio.h>
++#include <asm/io.h>
++#include <asm/arch/imx-regs.h>
++#include <asm/arch/iomux-mx28.h>
++#include <asm/arch/clock.h>
++#include <asm/arch/sys_proto.h>
++#include <linux/mii.h>
++#include <miiphy.h>
++#include <netdev.h>
++#include <errno.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++/*
++ * Functions
++ */
++int board_early_init_f(void)
++{
++	/* IO0 clock at 480MHz */
++	mxs_set_ioclk(MXC_IOCLK0, 480000);
++	/* IO1 clock at 480MHz */
++	mxs_set_ioclk(MXC_IOCLK1, 480000);
++
++	/* SSP0 clock at 96MHz */
++	mxs_set_sspclk(MXC_SSPCLK0, 96000, 0);
++	/* SSP2 clock at 160MHz */
++	mxs_set_sspclk(MXC_SSPCLK2, 160000, 0);
++
++#ifdef	CONFIG_CMD_USB
++	mxs_iomux_setup_pad(MX28_PAD_LCD_D23__GPIO_1_23 |
++			MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL);
++	gpio_direction_output(MX28_PAD_LCD_D23__GPIO_1_23, 0);
++#endif
++
++	return 0;
++}
++
++int board_init(void)
++{
++	/* Adress of boot parameters */
++	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
++
++	return 0;
++}
++
++int dram_init(void)
++{
++	return mxs_dram_init();
++}
++
++#ifdef	CONFIG_CMD_MMC
++static int m28_mmc_wp(int id)
++{
++	if (id != 0) {
++		printf("MXS MMC: Invalid card selected (card id = %d)\n", id);
++		return 1;
++	}
++
++	return 0;
++}
++
++int board_mmc_init(bd_t *bis)
++{
++	return mxsmmc_initialize(bis, 0, m28_mmc_wp, NULL);
++}
++#endif
++
++#ifdef	CONFIG_CMD_NET
++int board_eth_init(bd_t *bis)
++{
++	struct mxs_clkctrl_regs *clkctrl_regs =
++		(struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
++	struct eth_device *dev;
++	int ret;
++
++	ret = cpu_eth_init(bis);
++	if (ret)
++		return ret;
++
++	/* uses ENET_CLK PAD to drive FEC clock */
++	writel(CLKCTRL_ENET_TIME_SEL_RMII_CLK | CLKCTRL_ENET_CLK_OUT_EN,
++					&clkctrl_regs->hw_clkctrl_enet);
++
++	gpio_direction_output(MX28_PAD_ENET0_RX_CLK__GPIO_4_13, 0);
++	udelay(200);
++	gpio_set_value(MX28_PAD_ENET0_RX_CLK__GPIO_4_13, 1);
++
++	ret = fecmxc_initialize_multi(bis, 0, 0, MXS_ENET0_BASE);
++	if (ret) {
++		printf("FEC MXS: Unable to init FEC0\n");
++		return ret;
++	}
++
++	dev = eth_get_dev_by_name("FEC0");
++	if (!dev) {
++		printf("FEC MXS: Unable to get FEC0 device entry\n");
++		return -EINVAL;
++	}
++
++	return ret;
++}
++
++#ifdef	CONFIG_MX28_FEC_MAC_IN_OCOTP
++void mx28_adjust_mac(int dev_id, unsigned char *mac)
++{
++	struct mxs_ocotp_regs *ocotp_regs =
++		(struct mxs_ocotp_regs *)MXS_OCOTP_BASE;
++
++	writel(OCOTP_CTRL_RD_BANK_OPEN, &ocotp_regs->hw_ocotp_ctrl_clr);
++
++	mac[0] = (ACFG_OUI >> 16) & 0xff;
++	mac[1] = (ACFG_OUI >> 8) & 0xff;
++
++	if (dev_id == 1) /* Let MAC1 be MAC0 + 1 by default */
++		mac[5] += 1;
++}
++#endif
++#endif
+diff --git a/board/armadeus/apf28/cmd_ocotp.c b/board/armadeus/apf28/cmd_ocotp.c
+new file mode 100644
+index 0000000..2efae8d
+--- /dev/null
++++ b/board/armadeus/apf28/cmd_ocotp.c
+@@ -0,0 +1,253 @@
++/*
++ * Copyright (C) 2012-2014 Eric Jarrige <eric.jarrige at armadeus.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <linux/types.h>
++#include <asm/io.h>
++#include <command.h>
++#include <common.h>
++#include <asm/arch/imx-regs.h>
++#include <asm/arch/sys_proto.h>
++
++#define	MXS_OCOTP_MAX_TIMEOUT	1000000
++
++static struct mxs_ocotp_regs *ocotp_regs =
++		(struct mxs_ocotp_regs *)MXS_OCOTP_BASE;
++
++int otp_error(void)
++{
++	u32 otpctrl;
++
++	if (mxs_wait_mask_clr(&ocotp_regs->hw_ocotp_ctrl_reg, OCOTP_CTRL_BUSY,
++				MXS_OCOTP_MAX_TIMEOUT)) {
++		printf("OCOTP still busy after timeout\n");
++		return -1;
++	}
++
++	otpctrl = readl(&ocotp_regs->hw_ocotp_ctrl_reg);
++
++	if (otpctrl & OCOTP_CTRL_ERROR) {
++		printf("OCOTP error: CTRL register value: 0x%x\n", otpctrl);
++		return -1;
++	}
++
++	return 0;
++}
++
++int otp_read(int addr)
++{
++	u32 val = 0, otpctrl;
++
++	if ((addr < 0) || (addr > 0x27)) {
++		printf("Invalid address! (should be between 0 and 0x27)\n");
++		return val;
++	}
++
++	if (otp_error())
++		return val;
++
++	otpctrl = readl(&ocotp_regs->hw_ocotp_ctrl_reg);
++
++	if (otpctrl & OCOTP_CTRL_ERROR) {
++		printf("OCOTP in error: CTRL register value: 0x%x\n", otpctrl);
++		return val;
++	}
++
++	writel(OCOTP_CTRL_RD_BANK_OPEN, &ocotp_regs->hw_ocotp_ctrl_set);
++
++	if (mxs_wait_mask_clr(&ocotp_regs->hw_ocotp_ctrl_reg, OCOTP_CTRL_BUSY,
++				MXS_OCOTP_MAX_TIMEOUT)) {
++		printf("OCOTP Busy: Can't open OCOTP bank\n");
++		return val;
++	}
++
++	val = readl(&ocotp_regs->hw_ocotp_cust0 + (addr * 4));
++
++	writel(OCOTP_CTRL_RD_BANK_OPEN, &ocotp_regs->hw_ocotp_ctrl_clr);
++
++	return val;
++}
++
++int otp_blow(unsigned int addr, unsigned int data)
++{
++	u32 hbus, clkseq, vddio;
++	int err = 0;
++	struct mxs_clkctrl_regs *clkctrl_regs =
++		(struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
++	struct mxs_power_regs *power_regs =
++		(struct mxs_power_regs *)MXS_POWER_BASE;
++
++	if ((addr < 0) || (addr > 0x27)) {
++		printf("Invalid address! (should be between 0 and 0x27)\n");
++		return -1;
++	}
++
++	/* Save HBUS, CLKSEQ and VDDIO */
++	hbus = readl(&clkctrl_regs->hw_clkctrl_hbus_reg);
++	clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq_reg);
++	vddio = readl(&power_regs->hw_power_vddioctrl);
++
++	/* Force HBUS and CPU down to 24 MHz */
++	writel(CLKCTRL_CLKSEQ_BYPASS_CPU, &clkctrl_regs->hw_clkctrl_clkseq_set);
++	writel(1 << CLKCTRL_HBUS_DIV_OFFSET,
++		&clkctrl_regs->hw_clkctrl_hbus_set);
++	writel(CLKCTRL_HBUS_DIV_MASK - 1, &clkctrl_regs->hw_clkctrl_hbus_clr);
++
++	/* Change VDDIO to 2.8V while burning the fuses */
++	writel(POWER_VDDIOCTRL_TRG_MASK, &clkctrl_regs->hw_clkctrl_hbus_clr);
++
++	/* Disable read bank */
++	writel(OCOTP_CTRL_RD_BANK_OPEN, &ocotp_regs->hw_ocotp_ctrl_clr);
++
++	/* Check ocotp status busy and error */
++	if (!otp_error()) {
++		/* initiate fuse blow at addr.. */
++		writel(OCOTP_CTRL_WR_UNLOCK_KEY | (addr & OCOTP_CTRL_ADDR_MASK),
++		&ocotp_regs->hw_ocotp_ctrl);
++
++		/* Start writing data */
++		writel(data, &ocotp_regs->hw_ocotp_data);
++
++		/* wait end of blowing process + 2us wrtie postamble*/
++		if (otp_error()) {
++			printf("OCOTP blow failed!\n");
++			err = -1;
++		}
++		udelay(2);
++
++	} else
++		err = -1;
++
++
++	/* restore HBUS, CLKSEQ and VDDIO */
++	writel(vddio, &power_regs->hw_power_vddioctrl);
++	writel(hbus, &clkctrl_regs->hw_clkctrl_hbus);
++	writel(clkseq, &clkctrl_regs->hw_clkctrl_clkseq);
++
++	return err;
++}
++
++int otp_read_func(char *func_name)
++{
++	s32 err = 0;
++
++	if (0 == strncmp(func_name, "fecmac", 6)) {
++		s32 addr = func_name[6] - '0';
++
++		if ((addr >= 0) && (addr < 2)) {
++			/* Read the Mac address and print it */
++			u32 val = otp_read(addr);
++
++			printf("%s address: ", func_name);
++			printf("0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n\n",
++				(ACFG_OUI >> 16) & 0xff, (ACFG_OUI >> 8) & 0xff,
++				(val >> 24) & 0xff, (val >> 16) & 0xff,
++				(val >> 8) & 0xff, val & 0xff);
++		} else {
++			printf("%s is not supported\n", func_name);
++			err = -1;
++		}
++	} else {
++		printf("%s is not supported\n", func_name);
++		err = -1;
++	}
++
++	return err;
++}
++
++int otp_blow_func(char *func_name, char *func_val)
++{
++	s32 err = 0;
++
++	if (0 == strncmp(func_name, "fecmac", 6)) {
++		s32 addr  = func_name[6] - '0';
++
++		if ((addr >= 0) && (addr < 2)) {
++			u8 ea[6] = { 0 };
++			u32 macaddr;
++
++			eth_parse_enetaddr(func_val, ea);
++			if (!is_valid_ether_addr(ea)) {
++				printf("Error: invalid mac address!\n");
++				return -1;
++			}
++
++			macaddr = (ea[2] << 24) | (ea[3] << 16) |
++				(ea[4] << 8) | ea[5];
++
++			err = otp_blow(addr, macaddr);
++
++		} else {
++			printf("%s is not supported\n", func_name);
++			err = -1;
++		}
++	} else {
++		printf("%s is not supported\n", func_name);
++		err = -1;
++	}
++
++	return err;
++}
++
++
++int do_otpops(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
++{
++	int addr = 0, val = 0;
++
++	if (argc < 2 || argc > 4)
++		goto err_rtn;
++
++	if (strcmp(argv[1], "read") == 0) {
++		if (strncmp(argv[2], "fecmac", 6) == 0) {
++			if (3 == argc)
++				otp_read_func(argv[2]);
++			else
++				goto err_rtn;
++		} else {
++			if (3 == argc) {
++				addr = simple_strtoul(argv[2], NULL, 16);
++
++				printf("Read fuse at add: 0x%02x\n", addr);
++				val = otp_read(addr);
++				printf("fuses at (addr:0x%02x) = 0x%08x\n",
++					addr, val);
++			} else
++				goto err_rtn;
++		}
++	} else if (strcmp(argv[1], "blow") == 0) {
++		if (strncmp(argv[2], "fecmac", 6) == 0) {
++			if (4 == argc)
++				otp_blow_func(argv[2], argv[3]);
++			else
++				goto err_rtn;
++		} else {
++			if (4 == argc) {
++				addr = simple_strtoul(argv[2], NULL, 16);
++				val = simple_strtoul(argv[3], NULL, 16);
++
++				otp_blow(addr, val);
++			} else
++				goto err_rtn;
++		}
++	} else
++		goto err_rtn;
++
++	return 0;
++err_rtn:
++	printf("Invalid parameters!\n");
++	printf("It is too dangeous for you to use ocotp command.\n");
++	return 1;
++}
++
++U_BOOT_CMD(
++	ocotp, 4, 1, do_otpops,
++	"OCOTP sub system",
++	"Warning: all numbers in parameter are in hex format!\n"
++	"ocotp read <addr>		- Read some fuses\n"
++	"ocotp read fecmac<n>		- Read fecmac<n> MAC address\n"
++	"ocotp blow <addr> <value>	- Blow some fuses\n"
++	"ocotp blow fecmac<n> <0x##:0x##:0x##:0x##:0x##:0x##> "
++	"- Blow fecmac<n> MAC address");
++
+diff --git a/board/armadeus/apf28/mx28_bcb.c b/board/armadeus/apf28/mx28_bcb.c
+new file mode 100644
+index 0000000..2be032c
+--- /dev/null
++++ b/board/armadeus/apf28/mx28_bcb.c
+@@ -0,0 +1,540 @@
++/*
++ * i.MX28 NAND Boot Control Blocks generator
++ *
++ * Copyright (C) 2012-2014 Eric Jarrige <eric.jarrige at armadeus.org>
++ *
++ * Based on code from mxsboot:
++ * Freescale i.MX28 image generator
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <asm/io.h>
++#include <common.h>
++#include <malloc.h>
++#include <nand.h>
++#include <asm/arch/imx-regs.h>
++
++/*
++ * BCB layout Read from OCOTP fuses.
++ */
++static uint32_t stride_pages;
++static uint32_t stride_count;
++
++/*
++ * Sector on which the SigmaTel boot partition (0x53) starts.
++ */
++uint32_t sd_sector = 2048;
++
++/* i.MX28 NAND controller-specific constants. DO NOT TWEAK! */
++#define	MXS_NAND_DMA_DESCRIPTOR_COUNT		4
++#define	MXS_NAND_CHUNK_DATA_CHUNK_SIZE		512
++#define	MXS_NAND_METADATA_SIZE			10
++#define	MXS_NAND_COMMAND_BUFFER_SIZE		32
++
++struct mx28_nand_fcb {
++	uint32_t		checksum;
++	uint32_t		fingerprint;
++	uint32_t		version;
++	struct {
++		uint8_t			data_setup;
++		uint8_t			data_hold;
++		uint8_t			address_setup;
++		uint8_t			dsample_time;
++		uint8_t			nand_timing_state;
++		uint8_t			rea;
++		uint8_t			rloh;
++		uint8_t			rhoh;
++	}			timing;
++	uint32_t		page_data_size;
++	uint32_t		total_page_size;
++	uint32_t		sectors_per_block;
++	uint32_t		number_of_nands;		/* Ignored */
++	uint32_t		total_internal_die;		/* Ignored */
++	uint32_t		cell_type;			/* Ignored */
++	uint32_t		ecc_block_n_ecc_type;
++	uint32_t		ecc_block_0_size;
++	uint32_t		ecc_block_n_size;
++	uint32_t		ecc_block_0_ecc_type;
++	uint32_t		metadata_bytes;
++	uint32_t		num_ecc_blocks_per_page;
++	uint32_t		ecc_block_n_ecc_level_sdk;	/* Ignored */
++	uint32_t		ecc_block_0_size_sdk;		/* Ignored */
++	uint32_t		ecc_block_n_size_sdk;		/* Ignored */
++	uint32_t		ecc_block_0_ecc_level_sdk;	/* Ignored */
++	uint32_t		num_ecc_blocks_per_page_sdk;	/* Ignored */
++	uint32_t		metadata_bytes_sdk;		/* Ignored */
++	uint32_t		erase_threshold;
++	uint32_t		boot_patch;
++	uint32_t		patch_sectors;
++	uint32_t		firmware1_starting_sector;
++	uint32_t		firmware2_starting_sector;
++	uint32_t		sectors_in_firmware1;
++	uint32_t		sectors_in_firmware2;
++	uint32_t		dbbt_search_area_start_address;
++	uint32_t		badblock_marker_byte;
++	uint32_t		badblock_marker_start_bit;
++	uint32_t		bb_marker_physical_offset;
++};
++
++struct mx28_nand_dbbt {
++	uint32_t		checksum;
++	uint32_t		fingerprint;
++	uint32_t		version;
++	uint32_t		number_bb;
++	uint32_t		number_2k_pages_bb;
++};
++
++struct mx28_nand_bbt {
++	uint32_t		nand;
++	uint32_t		number_bb;
++	uint32_t		badblock[510];
++};
++
++struct mx28_sd_drive_info {
++	uint32_t		chip_num;
++	uint32_t		drive_type;
++	uint32_t		tag;
++	uint32_t		first_sector_number;
++	uint32_t		sector_count;
++};
++
++struct mx28_sd_config_block {
++	uint32_t			signature;
++	uint32_t			primary_boot_tag;
++	uint32_t			secondary_boot_tag;
++	uint32_t			num_copies;
++	struct mx28_sd_drive_info	drv_info[1];
++};
++
++static inline uint32_t mx28_nand_ecc_size_in_bits(uint32_t ecc_strength)
++{
++	return ecc_strength * 13;
++}
++
++static inline uint32_t mx28_nand_get_ecc_strength(uint32_t page_data_size,
++						uint32_t page_oob_size)
++{
++	if (page_data_size == 2048)
++		return 8;
++
++	if (page_data_size == 4096) {
++		if (page_oob_size == 128)
++			return 8;
++
++		if (page_oob_size == 218)
++			return 16;
++	}
++
++	return 0;
++}
++
++static inline uint32_t mx28_nand_get_mark_offset(uint32_t page_data_size,
++						uint32_t ecc_strength)
++{
++	uint32_t chunk_data_size_in_bits;
++	uint32_t chunk_ecc_size_in_bits;
++	uint32_t chunk_total_size_in_bits;
++	uint32_t block_mark_chunk_number;
++	uint32_t block_mark_chunk_bit_offset;
++	uint32_t block_mark_bit_offset;
++
++	chunk_data_size_in_bits = MXS_NAND_CHUNK_DATA_CHUNK_SIZE * 8;
++	chunk_ecc_size_in_bits  = mx28_nand_ecc_size_in_bits(ecc_strength);
++
++	chunk_total_size_in_bits =
++			chunk_data_size_in_bits + chunk_ecc_size_in_bits;
++
++	/* Compute the bit offset of the block mark within the physical page. */
++	block_mark_bit_offset = page_data_size * 8;
++
++	/* Subtract the metadata bits. */
++	block_mark_bit_offset -= MXS_NAND_METADATA_SIZE * 8;
++
++	/*
++	 * Compute the chunk number (starting at zero) in which the block mark
++	 * appears.
++	 */
++	block_mark_chunk_number =
++			block_mark_bit_offset / chunk_total_size_in_bits;
++
++	/*
++	 * Compute the bit offset of the block mark within its chunk, and
++	 * validate it.
++	 */
++	block_mark_chunk_bit_offset = block_mark_bit_offset -
++			(block_mark_chunk_number * chunk_total_size_in_bits);
++
++	if (block_mark_chunk_bit_offset > chunk_data_size_in_bits)
++		return 1;
++
++	/*
++	 * Now that we know the chunk number in which the block mark appears,
++	 * we can subtract all the ECC bits that appear before it.
++	 */
++	block_mark_bit_offset -=
++		block_mark_chunk_number * chunk_ecc_size_in_bits;
++
++	return block_mark_bit_offset;
++}
++
++static inline uint32_t mx28_nand_mark_byte_offset(nand_info_t *nand)
++{
++	uint32_t ecc_strength;
++	ecc_strength =
++		mx28_nand_get_ecc_strength(nand->writesize, nand->oobsize);
++	return mx28_nand_get_mark_offset(nand->writesize, ecc_strength) >> 3;
++}
++
++static inline uint32_t mx28_nand_mark_bit_offset(nand_info_t *nand)
++{
++	uint32_t ecc_strength;
++	ecc_strength =
++		mx28_nand_get_ecc_strength(nand->writesize, nand->oobsize);
++	return mx28_nand_get_mark_offset(nand->writesize, ecc_strength) & 0x7;
++}
++
++static uint32_t mx28_nand_block_csum(uint8_t *block, uint32_t size)
++{
++	uint32_t csum = 0;
++	int i;
++
++	for (i = 0; i < size; i++)
++		csum += block[i];
++
++	return csum ^ 0xffffffff;
++}
++
++static struct mx28_nand_fcb *mx28_nand_get_fcb(nand_info_t *nand, uint32_t size)
++{
++	struct mx28_nand_fcb *fcb;
++	uint32_t bcb_size_bytes;
++	uint32_t stride_size_bytes;
++	uint32_t bootstream_size_pages;
++	uint32_t fw1_start_page;
++	uint32_t fw2_start_page;
++
++	fcb = malloc(nand->writesize);
++	if (!fcb) {
++		printf("MX28 NAND: Unable to allocate FCB\n");
++		return NULL;
++	}
++
++	memset(fcb, 0, nand->writesize);
++
++	fcb->fingerprint =			0x20424346;
++	fcb->version =				0x01000000;
++
++	/*
++	 * FIXME: These here are default values as found in kobs-ng. We should
++	 * probably retrieve the data from NAND or something.
++	 */
++	fcb->timing.data_setup =		80;
++	fcb->timing.data_hold =			60;
++	fcb->timing.address_setup =		25;
++	fcb->timing.dsample_time =		6;
++
++	fcb->page_data_size =		nand->writesize;
++	fcb->total_page_size =		nand->writesize + nand->oobsize;
++	fcb->sectors_per_block =	nand->erasesize / nand->writesize;
++
++	fcb->num_ecc_blocks_per_page =	(nand->writesize / 512) - 1;
++	fcb->ecc_block_0_size =		512;
++	fcb->ecc_block_n_size =		512;
++	fcb->metadata_bytes =		10;
++
++	if (nand->writesize == 2048) {
++		fcb->ecc_block_n_ecc_type =		4;
++		fcb->ecc_block_0_ecc_type =		4;
++	} else if (nand->writesize == 4096) {
++		if (nand->oobsize == 128) {
++			fcb->ecc_block_n_ecc_type =	4;
++			fcb->ecc_block_0_ecc_type =	4;
++		} else if (nand->oobsize == 218) {
++			fcb->ecc_block_n_ecc_type =	8;
++			fcb->ecc_block_0_ecc_type =	8;
++		}
++	}
++
++	if (fcb->ecc_block_n_ecc_type == 0) {
++		printf("MX28 NAND: Unsupported NAND geometry\n");
++		goto err;
++	}
++
++	fcb->boot_patch =			0;
++	fcb->patch_sectors =			0;
++
++	fcb->badblock_marker_byte =	mx28_nand_mark_byte_offset(nand);
++	fcb->badblock_marker_start_bit = mx28_nand_mark_bit_offset(nand);
++	fcb->bb_marker_physical_offset = nand->writesize;
++
++	stride_size_bytes = stride_pages * nand->writesize;
++	bcb_size_bytes = stride_size_bytes * stride_count;
++
++	bootstream_size_pages = (size + (nand->writesize - 1)) /
++					nand->writesize;
++
++	fw1_start_page = 2 * bcb_size_bytes / nand->writesize;
++	fw2_start_page = (2 * bcb_size_bytes + size) /
++				nand->writesize;
++
++	fcb->firmware1_starting_sector =	fw1_start_page;
++	fcb->firmware2_starting_sector =	fw2_start_page;
++	fcb->sectors_in_firmware1 =		bootstream_size_pages;
++	fcb->sectors_in_firmware2 =		bootstream_size_pages;
++
++	fcb->dbbt_search_area_start_address =	stride_pages * stride_count;
++
++	return fcb;
++
++err:
++	free(fcb);
++	return NULL;
++}
++
++static struct mx28_nand_dbbt *mx28_nand_get_dbbt(nand_info_t *nand)
++{
++	struct mx28_nand_dbbt *dbbt;
++
++	dbbt = malloc(nand->writesize);
++	if (!dbbt) {
++		printf("MX28 NAND: Unable to allocate DBBT\n");
++		return NULL;
++	}
++
++	memset(dbbt, 0, nand->writesize);
++
++	dbbt->fingerprint	= 0x54424244;
++	dbbt->version		= 0x1;
++
++	return dbbt;
++}
++
++static inline uint8_t mx28_nand_parity_13_8(const uint8_t b)
++{
++	uint32_t parity = 0, tmp;
++
++	tmp = ((b >> 6) ^ (b >> 5) ^ (b >> 3) ^ (b >> 2)) & 1;
++	parity |= tmp << 0;
++
++	tmp = ((b >> 7) ^ (b >> 5) ^ (b >> 4) ^ (b >> 2) ^ (b >> 1)) & 1;
++	parity |= tmp << 1;
++
++	tmp = ((b >> 7) ^ (b >> 6) ^ (b >> 5) ^ (b >> 1) ^ (b >> 0)) & 1;
++	parity |= tmp << 2;
++
++	tmp = ((b >> 7) ^ (b >> 4) ^ (b >> 3) ^ (b >> 0)) & 1;
++	parity |= tmp << 3;
++
++	tmp = ((b >> 6) ^ (b >> 4) ^ (b >> 3) ^
++		(b >> 2) ^ (b >> 1) ^ (b >> 0)) & 1;
++	parity |= tmp << 4;
++
++	return parity;
++}
++
++static uint8_t *mx28_nand_fcb_block
++		(nand_info_t *nand, struct mx28_nand_fcb *fcb)
++{
++	uint8_t *block;
++	uint8_t *ecc;
++	int i;
++
++	block = malloc(nand->writesize + nand->oobsize);
++	if (!block) {
++		printf("MX28 NAND: Unable to allocate FCB block\n");
++		return NULL;
++	}
++
++	memset(block, 0, nand->writesize + nand->oobsize);
++
++	/* Update the FCB checksum */
++	fcb->checksum = mx28_nand_block_csum(((uint8_t *)fcb) + 4, 508);
++
++	/* Figure 12-11. in iMX28RM, rev. 1, says FCB is at offset 12 */
++	memcpy(block + 12, fcb, sizeof(struct mx28_nand_fcb));
++
++	/* ECC is at offset 12 + 512 */
++	ecc = block + 12 + 512;
++
++	/* Compute the ECC parity */
++	for (i = 0; i < sizeof(struct mx28_nand_fcb); i++)
++		ecc[i] = mx28_nand_parity_13_8(block[i + 12]);
++
++	return block;
++}
++
++
++static int mx28_nand_write_fcb(nand_info_t *nand, struct mx28_nand_fcb *fcb)
++{
++	uint32_t offset;
++	uint8_t *fcbblock;
++	int ret = 0;
++	int i;
++	nand_erase_options_t opts;
++
++	fcbblock = mx28_nand_fcb_block(nand, fcb);
++	if (!fcbblock)
++		return -1;
++
++	memset(&opts, 0, sizeof(opts));
++	opts.offset = 0;
++	opts.length = stride_pages * stride_count * nand->writesize;
++	opts.jffs2  = 0;
++	opts.quiet  = 1;
++	opts.spread = 0;
++	opts.scrub = 1;
++
++	printf("Erasing FCB...\n");
++	if (!nand_erase_opts(nand, &opts)) {
++		mtd_oob_ops_t ops = {
++			.datbuf = (u8 *)fcbblock,
++			.oobbuf = (u8 *)fcbblock + nand->writesize,
++			.len = nand->writesize,
++			.ooblen = nand->oobsize,
++			.mode = MTD_OPS_RAW
++		};
++
++		printf("Writing FCB...\n");
++
++		for (i = 0; i < stride_pages * stride_count;
++				i += stride_pages) {
++			offset = i * nand->writesize;
++			ret = nand->_write_oob(nand, offset, &ops);
++		}
++	}
++	free(fcbblock);
++	return ret;
++}
++
++static int mx28_nand_write_dbbt(nand_info_t *nand, struct mx28_nand_dbbt *dbbt)
++{
++	uint32_t offset;
++	int i = stride_pages * stride_count, ret = 0;
++
++	nand_erase_options_t opts;
++
++	memset(&opts, 0, sizeof(opts));
++	opts.offset = stride_pages * stride_count * nand->writesize;
++	opts.length = stride_pages * stride_count * nand->writesize;
++	opts.jffs2  = 0;
++	opts.quiet  = 1;
++	opts.spread = 0;
++	opts.scrub = 1;
++
++	printf("Erasing DBBT...\n");
++	if (!nand_erase_opts(nand, &opts)) {
++		mtd_oob_ops_t ops = {
++			.datbuf = (u8 *)dbbt,
++			.oobbuf = (u8 *)dbbt + nand->writesize,
++			.len = nand->writesize,
++			.ooblen = nand->oobsize,
++			.mode = MTD_OPS_RAW
++		};
++
++		printf("Writing DBBT...\n");
++
++		for (; i < 2 * stride_pages * stride_count; i += stride_pages) {
++			offset = i * nand->writesize;
++			ret = nand->_write_oob(nand, offset, &ops);
++		}
++
++	}
++
++	return ret;
++}
++
++
++static int mx28_update_nand_bcb(int firmware_max_size)
++{
++	struct mx28_nand_fcb *fcb;
++	struct mx28_nand_dbbt *dbbt;
++	int ret = -1;
++	nand_info_t *nand = &nand_info[0];
++	struct mxs_ocotp_regs *ocotp_regs =
++		(struct mxs_ocotp_regs *)MXS_OCOTP_BASE;
++	char buf[12];
++
++	stride_pages = ((readl(&ocotp_regs->hw_ocotp_rom1) >> 4) & 0x0f) * 64;
++	if (stride_pages < 64)
++		stride_pages = 64;
++
++	stride_count = 1 << ((readl(&ocotp_regs->hw_ocotp_rom1) >> 8) & 0x0f);
++	if (stride_count < 2)
++		stride_count = 4;
++
++	if (firmware_max_size <= nand->erasesize)
++		firmware_max_size = 1 * 1024 * 1024;
++
++	debug("stride_pages= %d\n", stride_pages);
++	debug("stride_count= %d\n", stride_count);
++	debug("firmware_max_size= %x\n", firmware_max_size);
++
++	fcb = mx28_nand_get_fcb(nand, firmware_max_size);
++	if (!fcb) {
++		printf("Unable to build FCB\n");
++		goto err0;
++	}
++
++	dbbt = mx28_nand_get_dbbt(nand);
++	if (!dbbt) {
++		printf("Unable to build DBBT\n");
++		goto err1;
++	}
++
++	ret = mx28_nand_write_fcb(nand, fcb);
++	if (ret) {
++		printf("Unable to write FCB to NAND\n");
++		goto err2;
++	}
++
++
++	ret = mx28_nand_write_dbbt(nand, dbbt);
++	if (ret) {
++		printf("Unable to write DBBT to NAND\n");
++		goto err2;
++	}
++
++	sprintf(buf, "0x%08x",
++		fcb->firmware1_starting_sector * nand->writesize);
++	setenv("u-boot_addr", buf);
++	sprintf(buf, "0x%08x",
++		fcb->firmware2_starting_sector * nand->writesize);
++	setenv("u-boot2_addr", buf);
++
++	printf("NAND BCB tables updated\n");
++	ret = 0;
++
++err2:
++	free(dbbt);
++err1:
++	free(fcb);
++err0:
++	return ret;
++}
++
++int do_bcb(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
++{
++	int err = 0;
++	int arg = (1 * 1024 * 1024);
++
++	if (argc < 2 || argc > 3)
++		goto usage;
++
++	if (strcmp(argv[1], "nand.write") == 0) {
++		if (argc == 3)
++			arg = simple_strtoul(argv[2], NULL, 16);
++		err = mx28_update_nand_bcb(arg);
++	} else
++		goto usage;
++
++	return err;
++usage:
++	return cmd_usage(cmdtp);
++}
++
++U_BOOT_CMD(
++	bcb, 2, 1, do_bcb,
++	"mx28 Boot Control Block sub system",
++	"nand.write [Firmware max size]	- Update NAND BCB tables\n"
++	"	default firmware max size is 1MiB");
+diff --git a/board/armadeus/apf28/spl_boot.c b/board/armadeus/apf28/spl_boot.c
+new file mode 100644
+index 0000000..9854cda
+--- /dev/null
++++ b/board/armadeus/apf28/spl_boot.c
+@@ -0,0 +1,190 @@
++/*
++ * Freescale i.MX28 Boot setup for the APF28 board
++ *
++ * Copyright (C) 2012-2014 Eric Jarrige <eric.jarrige at armadeus.org>
++ * Copyright (C) 2011 Marek Vasut <marek.vasut at gmail.com>
++ * on behalf of DENX Software Engineering GmbH
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <config.h>
++#include <asm/io.h>
++#include <asm/arch/iomux-mx28.h>
++#include <asm/arch/imx-regs.h>
++#include <asm/arch/sys_proto.h>
++
++#define	MUX_CONFIG_LED	(MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
++#define	MUX_CONFIG_SSP0	(MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_PULLUP)
++#define	MUX_CONFIG_GPMI	(MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
++#define	MUX_CONFIG_ENET	(MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_PULLUP)
++#define	MUX_CONFIG_EMI	(MXS_PAD_1V8 | MXS_PAD_8MA | MXS_PAD_NOPULL)
++
++const iomux_cfg_t iomux_setup[] = {
++	/* LED */
++	MX28_PAD_GPMI_RDY1__GPIO_0_21 | MUX_CONFIG_LED,
++
++	/* DEBUG UART (console) */
++	MX28_PAD_PWM0__DUART_RX | (MXS_PAD_3V3 | MXS_PAD_4MA),
++	MX28_PAD_PWM1__DUART_TX | (MXS_PAD_3V3 | MXS_PAD_4MA),
++
++	/* MMC0 */
++	MX28_PAD_SSP0_DATA0__SSP0_D0 | MUX_CONFIG_SSP0,
++	MX28_PAD_SSP0_DATA1__SSP0_D1 | MUX_CONFIG_SSP0,
++	MX28_PAD_SSP0_DATA2__SSP0_D2 | MUX_CONFIG_SSP0,
++	MX28_PAD_SSP0_DATA3__SSP0_D3 | MUX_CONFIG_SSP0,
++	MX28_PAD_SSP0_CMD__SSP0_CMD | MUX_CONFIG_SSP0,
++	MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT |
++		(MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_NOPULL),
++	MX28_PAD_SSP0_SCK__SSP0_SCK |
++		(MXS_PAD_3V3 | MXS_PAD_12MA | MXS_PAD_NOPULL),
++
++	/* GPMI NAND */
++	MX28_PAD_GPMI_D00__GPMI_D0 | MUX_CONFIG_GPMI,
++	MX28_PAD_GPMI_D01__GPMI_D1 | MUX_CONFIG_GPMI,
++	MX28_PAD_GPMI_D02__GPMI_D2 | MUX_CONFIG_GPMI,
++	MX28_PAD_GPMI_D03__GPMI_D3 | MUX_CONFIG_GPMI,
++	MX28_PAD_GPMI_D04__GPMI_D4 | MUX_CONFIG_GPMI,
++	MX28_PAD_GPMI_D05__GPMI_D5 | MUX_CONFIG_GPMI,
++	MX28_PAD_GPMI_D06__GPMI_D6 | MUX_CONFIG_GPMI,
++	MX28_PAD_GPMI_D07__GPMI_D7 | MUX_CONFIG_GPMI,
++	MX28_PAD_GPMI_CE0N__GPMI_CE0N | MUX_CONFIG_GPMI,
++	MX28_PAD_GPMI_RDY0__GPMI_READY0 | MUX_CONFIG_GPMI,
++	/* see mx28 reference manual 9.2.2.1 notes for RD/WR 8mA reason */
++	MX28_PAD_GPMI_RDN__GPMI_RDN |
++		(MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_NOPULL),
++	/* see mx28 reference manual 9.4.36 pullup bit description */
++	MX28_PAD_GPMI_WRN__GPMI_WRN |
++		(MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_PULLUP),
++	MX28_PAD_GPMI_ALE__GPMI_ALE | MUX_CONFIG_GPMI,
++	MX28_PAD_GPMI_CLE__GPMI_CLE | MUX_CONFIG_GPMI,
++	MX28_PAD_GPMI_RESETN__GPMI_RESETN | MUX_CONFIG_GPMI,
++
++	/* FEC Ethernet */
++	MX28_PAD_ENET0_MDC__ENET0_MDC | MUX_CONFIG_ENET,
++	MX28_PAD_ENET0_MDIO__ENET0_MDIO | MUX_CONFIG_ENET,
++	MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | MUX_CONFIG_ENET,
++	MX28_PAD_ENET0_TX_EN__ENET0_TX_EN | MUX_CONFIG_ENET,
++	MX28_PAD_ENET0_RXD0__ENET0_RXD0 | MUX_CONFIG_ENET,
++	MX28_PAD_ENET0_RXD1__ENET0_RXD1 | MUX_CONFIG_ENET,
++	MX28_PAD_ENET0_TXD0__ENET0_TXD0 | MUX_CONFIG_ENET,
++	MX28_PAD_ENET0_TXD1__ENET0_TXD1 | MUX_CONFIG_ENET,
++	MX28_PAD_ENET_CLK__CLKCTRL_ENET | MUX_CONFIG_ENET,
++	MX28_PAD_ENET0_TX_CLK__GPIO_4_5
++		| MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL,
++	MX28_PAD_ENET0_RX_CLK__GPIO_4_13
++		| MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL,
++
++	/* EMI */
++	MX28_PAD_EMI_D00__EMI_DATA0 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_D01__EMI_DATA1 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_D02__EMI_DATA2 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_D03__EMI_DATA3 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_D04__EMI_DATA4 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_D05__EMI_DATA5 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_D06__EMI_DATA6 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_D07__EMI_DATA7 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_D08__EMI_DATA8 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_D09__EMI_DATA9 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_D10__EMI_DATA10 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_D11__EMI_DATA11 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_D12__EMI_DATA12 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_D13__EMI_DATA13 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_D14__EMI_DATA14 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_D15__EMI_DATA15 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_ODT0__EMI_ODT0 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_DQM0__EMI_DQM0 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_CLK__EMI_CLK | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_DQS0__EMI_DQS0 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_DQS1__EMI_DQS1 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN | MUX_CONFIG_EMI,
++
++	MX28_PAD_EMI_A00__EMI_ADDR0 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_A01__EMI_ADDR1 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_A02__EMI_ADDR2 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_A03__EMI_ADDR3 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_A04__EMI_ADDR4 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_A05__EMI_ADDR5 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_A06__EMI_ADDR6 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_A07__EMI_ADDR7 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_A08__EMI_ADDR8 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_A09__EMI_ADDR9 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_A10__EMI_ADDR10 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_A11__EMI_ADDR11 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_A12__EMI_ADDR12 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_A13__EMI_ADDR13 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_A14__EMI_ADDR14 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_BA0__EMI_BA0 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_BA1__EMI_BA1 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_BA2__EMI_BA2 | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_CASN__EMI_CASN | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_RASN__EMI_RASN | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_WEN__EMI_WEN | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_CE0N__EMI_CE0N | MUX_CONFIG_EMI,
++	MX28_PAD_EMI_CKE__EMI_CKE | MUX_CONFIG_EMI,
++};
++
++uint32_t apf28_dram_vals[] = {
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000100, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00010101, 0x01010101, 0x000f0f01, 0x0f02020a,
++	0x00000000, 0x00010101, 0x00000100, 0x00000100, 0x00000000,
++	0x00000002, 0x01010000, 0x07080403, 0x06005003, 0x0a0000c8,
++	0x02009c40, 0x0002030c, 0x0036a609, 0x031a0612, 0x02030202,
++	0x00c8001c, 0x00000000, 0x00000000, 0x00012100, 0xffff0303,
++	0x00012100, 0xffff0303, 0x00012100, 0xffff0303, 0x00012100,
++	0xffff0303, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000612, 0x01000f02, 0x06120612, 0x00000200,
++	0x00020007, 0xf4004a27, 0xf4004a27, 0xf4004a27, 0xf4004a27,
++	0x07000300, 0x07000300, 0x07400300, 0x07400300, 0x00000005,
++	0x00000000, 0x00000000, 0x01000000, 0x01020408, 0x08040201,
++	0x000f1133, 0x00000000, 0x00001f04, 0x00001f04, 0x00001f04,
++	0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x00000000, 0x00010000, 0x00030404, 0x00000003,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
++	0x00000000, 0x01010000, 0x01000000, 0x03030000, 0x00010303,
++	0x01020202, 0x00000000, 0x02040303, 0x21002103, 0x00061200,
++	0x06120612, 0x04420442, 0x04420442, 0x00040004, 0x00040004,
++	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff
++};
++
++void mxs_adjust_memory_params(uint32_t *dram_vals)
++{
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(apf28_dram_vals); i++)
++		*dram_vals++ = apf28_dram_vals[i];
++}
++
++void board_init_ll(const uint32_t arg, const uint32_t *resptr)
++{
++	struct mxs_clkctrl_regs *clkctrl_regs =
++		(struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
++
++	/* Avoid watchdog to perform a complete POR...
++	A logic reset is more appropriate */
++	setbits_le32(&clkctrl_regs->hw_clkctrl_reset,
++			CLKCTRL_RESET_WDOG_POR_DISABLE);
++
++	mxs_common_spl_init(arg, resptr, iomux_setup, ARRAY_SIZE(iomux_setup));
++}
++
+diff --git a/boards.cfg b/boards.cfg
+index 1aa7e95..f3c8b40 100644
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -210,6 +210,7 @@ Active  arm         arm926ejs      mx27
+ Active  arm         arm926ejs      mx27        logicpd         imx27lite           magnesium                             -                                                                                                                                 Heiko Schocher <hs at denx.de>
+ Active  arm         arm926ejs      mxs         bluegiga        apx4devkit          apx4devkit                            -                                                                                                                                 Lauri Hintsala <lauri.hintsala at bluegiga.com>
+ Active  arm         arm926ejs      mxs         creative        xfi3                xfi3                                  -                                                                                                                                 Marek Vasut <marek.vasut at gmail.com>
++Active  arm         arm926ejs      mxs         armadeus        apf28               apf28                               -                                                                                                                                 Eric Jarrige <eric.jarrige at armadeus.org>
+ Active  arm         arm926ejs      mxs         denx            m28evk              m28evk                                -                                                                                                                                 Marek Vasut <marek.vasut at gmail.com>
+ Active  arm         arm926ejs      mxs         freescale       mx23evk             mx23evk                               -                                                                                                                                 Otavio Salvador <otavio at ossystems.com.br>
+ Active  arm         arm926ejs      mxs         freescale       mx28evk             mx28evk                               mx28evk:ENV_IS_IN_MMC                                                                                                             Fabio Estevam <fabio.estevam at freescale.com>
+1.7.2.5
+
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/503-add-apf6.patch b/recipes-bsp/u-boot/u-boot-armadeus/503-add-apf6.patch
new file mode 100644
index 0000000..06a069d
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/503-add-apf6.patch
@@ -0,0 +1,945 @@
+Index: uboot-2014.07/boards.cfg
+===================================================================
+--- uboot-2014.07.orig/boards.cfg
++++ uboot-2014.07/boards.cfg
+@@ -318,6 +318,7 @@ Active  arm         armv7          mx6
+ Active  arm         armv7          mx6         -               wandboard           wandboard_dl                          wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL,DDR_MB=1024                                                  Fabio Estevam <fabio.estevam at freescale.com>
+ Active  arm         armv7          mx6         -               wandboard           wandboard_quad                        wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6q2g.cfg,MX6Q,DDR_MB=2048                                                  Fabio Estevam <fabio.estevam at freescale.com>
+ Active  arm         armv7          mx6         -               wandboard           wandboard_solo                        wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6s.cfg,MX6S,DDR_MB=512                                                     Fabio Estevam <fabio.estevam at freescale.com>
++Active  arm         armv7          mx6         armadeus        apf6                apf6                                  apf6:IMX_CONFIG=board/armadeus/apf6/apf6.cfg,MX6QDL,SPL                                                                           Armadeus Systems <contact at armadeus.com>
+ Active  arm         armv7          mx6         barco           titanium            titanium                              titanium:IMX_CONFIG=board/barco/titanium/imximage.cfg                                                                             Stefan Roese <sr at denx.de>
+ Active  arm         armv7          mx6         boundary        nitrogen6x          mx6qsabrelite                         nitrogen6x:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6q.cfg,MX6Q,DDR_MB=1024,SABRELITE                                         Eric Nelson <eric.nelson at boundarydevices.com>
+ Active  arm         armv7          mx6         boundary        nitrogen6x          nitrogen6dl                           nitrogen6x:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL,DDR_MB=1024                                                 Eric Nelson <eric.nelson at boundarydevices.com>
+Index: uboot-2014.07/board/armadeus/apf6/Makefile
+===================================================================
+--- /dev/null
++++ uboot-2014.07/board/armadeus/apf6/Makefile
+@@ -0,0 +1,8 @@
++#
++# Copyright (C) 2014, ARMadeus Systems <support at armadeus.com>
++#
++# SPDX-License-Identifier:  GPL-2.0+
++#
++
++obj-y  := apf6.o fpga.o
++obj-$(CONFIG_SPL_BUILD) += apf6_spl.o
+Index: uboot-2014.07/board/armadeus/apf6/apf6.c
+===================================================================
+--- /dev/null
++++ uboot-2014.07/board/armadeus/apf6/apf6.c
+@@ -0,0 +1,386 @@
++/*
++ * Copyright (C) 2013 Armadeus systems.
++ *
++ * Author: Nicolas Colombain <nicolas.colombain at armadeus.com>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#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/gpio.h>
++#include <asm/imx-common/boot_mode.h>
++#include <asm/imx-common/video.h>
++#include <asm/io.h>
++#include <common.h>
++#include <fsl_esdhc.h>
++#include <linux/ctype.h>
++#include <miiphy.h>
++#include <mmc.h>
++#include <netdev.h>
++#include "fpga.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 ENET_PAD_CTRL2  (PAD_CTL_PUS_22K_UP |			\
++	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
++
++#define FPGA_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
++	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
++
++#define USB_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_47K_UP |	\
++	PAD_CTL_PUE)
++
++#define USDHC2_CD_GPIO		IMX_GPIO_NR(1, 2)
++#define ETH_PHY_RESET		IMX_GPIO_NR(1, 24)
++
++static iomux_v3_cfg_t const uart4_pads[] = {
++	IOMUX_PADS(PAD_CSI0_DAT12__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
++	IOMUX_PADS(PAD_CSI0_DAT13__UART4_RX_DATA | MUX_PAD_CTRL(UART_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)),
++	IOMUX_PADS(PAD_GPIO_2__GPIO1_IO02   | 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)),
++	IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
++	IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
++	IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
++	IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
++};
++
++static iomux_v3_cfg_t const enet_pads[] = {
++	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)),
++	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_CTRL2)),
++	IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3		| MUX_PAD_CTRL(ENET_PAD_CTRL2)),
++	IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL)),
++	/* AR8035 PHY Reset */
++	IOMUX_PADS(PAD_ENET_RX_ER__GPIO1_IO24		| MUX_PAD_CTRL(NO_PAD_CTRL)),
++	/* AR8035 INT */
++	IOMUX_PADS(PAD_ENET_TX_EN__GPIO1_IO28		| MUX_PAD_CTRL(NO_PAD_CTRL)),
++};
++
++static iomux_v3_cfg_t const fpga_pads[] = {
++	/* FPGA AS_DATA enet_txd1*/
++	IOMUX_PADS(PAD_ENET_TXD1__GPIO1_IO29		| MUX_PAD_CTRL(FPGA_PAD_CTRL)),
++	/* FPGA DCLK enet_rxd0*/
++	IOMUX_PADS(PAD_ENET_RXD0__GPIO1_IO27		| MUX_PAD_CTRL(FPGA_PAD_CTRL)),
++	/* FPGA CONF_DONE enet_rxd1*/
++	IOMUX_PADS(PAD_ENET_RXD1__GPIO1_IO26		| MUX_PAD_CTRL(FPGA_PAD_CTRL)),
++	/* FPGA NCONFIG EIM_D26*/
++	IOMUX_PADS(PAD_EIM_D26__GPIO3_IO26		| MUX_PAD_CTRL(FPGA_PAD_CTRL)),
++	/* FPGA NSTATUS EIM_D27*/
++	IOMUX_PADS(PAD_EIM_D27__GPIO3_IO27		| MUX_PAD_CTRL(FPGA_PAD_CTRL)),
++	/* FPGA CVP_CONFDONE EIM_D22*/
++	IOMUX_PADS(PAD_EIM_D22__GPIO3_IO22		| MUX_PAD_CTRL(FPGA_PAD_CTRL)),
++	/* FPGA PERSTL0# EIM_D18*/
++	IOMUX_PADS(PAD_EIM_D18__GPIO3_IO18		| MUX_PAD_CTRL(FPGA_PAD_CTRL)),
++};
++
++static iomux_v3_cfg_t const usb_pads[] = {
++	IOMUX_PADS(PAD_GPIO_1__USB_OTG_ID | MUX_PAD_CTRL(USB_PAD_CTRL)),
++};
++
++static void setup_iomux_uart(void)
++{
++	SETUP_IOMUX_PADS(uart4_pads);
++}
++
++static void setup_iomux_enet(void)
++{
++	SETUP_IOMUX_PADS(enet_pads);
++
++	/* Reset AR8035 PHY */
++	gpio_direction_output(ETH_PHY_RESET, 0);
++	udelay(10000);
++	gpio_set_value(ETH_PHY_RESET, 1);
++}
++
++static void setup_fpga(void)
++{
++	SETUP_IOMUX_PADS(fpga_pads);
++}
++
++static struct fsl_esdhc_cfg usdhc_cfg[2] = {
++	{USDHC3_BASE_ADDR},
++	{USDHC2_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 USDHC2_BASE_ADDR:
++		ret = !gpio_get_value(USDHC2_CD_GPIO);
++		break;
++	case USDHC3_BASE_ADDR:
++		ret = 1;
++		break;
++	}
++
++	return ret;
++}
++
++int board_mmc_init(bd_t *bis)
++{
++	s32 status = 0;
++	u32 index = 0;
++
++	for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) {
++		switch (index) {
++		case 0:
++			SETUP_IOMUX_PADS(usdhc3_pads);
++			usdhc_cfg[index].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
++			usdhc_cfg[index].max_bus_width = 8;
++			break;
++		case 1:
++			SETUP_IOMUX_PADS(usdhc2_pads);
++			usdhc_cfg[index].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
++			usdhc_cfg[index].max_bus_width = 4;
++			gpio_direction_input(USDHC2_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;
++}
++
++static int mx6_rgmii_rework(struct phy_device *phydev)
++{
++	unsigned short val;
++
++	/*
++	 * Ar803x phy SmartEEE feature cause link status generates glitch,
++	 * which cause ethernet link down/up issue, so disable SmartEEE
++	 *
++	 */
++	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
++	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x805d);
++	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4003);
++
++	/* To enable AR8035 ouput a 125MHz clk from CLK_25M */
++	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
++	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
++	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
++
++	val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
++	val &= 0xffe3;
++	val |= 0x18;
++	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
++
++	/* introduce tx clock delay */
++	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
++	val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
++	val |= 0x0100;
++	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
++
++	return 0;
++}
++
++int board_phy_config(struct phy_device *phydev)
++{
++	mx6_rgmii_rework(phydev);
++
++	if (phydev->drv->config)
++		phydev->drv->config(phydev);
++
++	return 0;
++}
++
++#if defined(CONFIG_VIDEO_IPUV3)
++static struct fb_videomode const hdmi = {
++	.name           = "HDMI",
++	.refresh        = 60,
++	.xres           = 1024,
++	.yres           = 768,
++	.pixclock       = 15385,
++	.left_margin    = 220,
++	.right_margin   = 40,
++	.upper_margin   = 21,
++	.lower_margin   = 7,
++	.hsync_len      = 60,
++	.vsync_len      = 10,
++	.sync           = FB_SYNC_EXT,
++	.vmode          = FB_VMODE_NONINTERLACED
++};
++
++static void do_enable_hdmi(struct display_info_t const *dev)
++{
++	imx_enable_hdmi_phy();
++}
++
++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,
++		.xres           = 1024,
++		.yres           = 768,
++		.pixclock       = 15385,
++		.left_margin    = 220,
++		.right_margin   = 40,
++		.upper_margin   = 21,
++		.lower_margin   = 7,
++		.hsync_len      = 60,
++		.vsync_len      = 10,
++		.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;
++	int reg;
++
++	enable_ipu_clock();
++	imx_setup_hdmi();
++
++	reg = readl(&mxc_ccm->chsccdr);
++	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
++		<< MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
++	writel(reg, &mxc_ccm->chsccdr);
++}
++#endif /* CONFIG_VIDEO_IPUV3 */
++
++int board_eth_init(bd_t *bis)
++{
++	int ret;
++
++	setup_iomux_enet();
++
++	ret = cpu_eth_init(bis);
++	if (ret)
++		printf("FEC MXC: %s:failed\n", __func__);
++
++	return 0;
++}
++
++int board_early_init_f(void)
++{
++	setup_iomux_uart();
++#if defined(CONFIG_VIDEO_IPUV3)
++	setup_display();
++#endif
++#ifdef CONFIG_FPGA
++	setup_fpga();
++#endif
++
++	return 0;
++}
++
++int board_late_init(void)
++{
++	u_char *firmware_buffer =
++	    (u_char *) (CONFIG_SYS_LOAD_ADDR + CONFIG_SYS_MONITOR_LEN);
++	size_t size = 0;
++
++	SETUP_IOMUX_PADS(usb_pads);
++
++	if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D))
++		setenv("fdt_file", "imx6q-apf6dev.dtb");
++	else if (is_cpu_type(MXC_CPU_MX6DL) || is_cpu_type(MXC_CPU_MX6SOLO))
++		setenv("fdt_file", "imx6dl-apf6dev.dtb");
++
++#if defined(CONFIG_FPGA)
++	/* init and download fpga */
++/*	if ((autoload) && (0 == strcmp(autoload, "1"))) {
++		if ((mtdparts_init() == 0) && (find_dev_and_part("firmware",
++			&dev, &pnum, &part) == 0)) {
++			size = part->size;
++			if (nand_read_skip_bad(&nand_info[0], part->offset,
++				&size, firmware_buffer))
++				size = 0;
++		}
++		if (ctrlc()) {
++			printf("Firmware download stopped!\n");
++			size = 0;
++		}
++	}*/
++	APF6_init_fpga(firmware_buffer, size);
++#endif
++
++	return 0;
++}
++
++int dram_init(void)
++{
++	gd->ram_size = imx_ddr_size();
++
++	return 0;
++}
++
++int board_init(void)
++{
++	struct iomuxc_base_regs *const iomuxc_regs
++		= (struct iomuxc_base_regs *)IOMUXC_BASE_ADDR;
++
++	clrsetbits_le32(&iomuxc_regs->gpr[1],
++			IOMUXC_GPR1_OTG_ID_MASK,
++			IOMUXC_GPR1_OTG_ID_GPIO1);
++
++	/* address of boot parameters */
++	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
++
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: APF6\n");
++
++	return 0;
++}
+Index: uboot-2014.07/board/armadeus/apf6/apf6.cfg
+===================================================================
+--- /dev/null
++++ uboot-2014.07/board/armadeus/apf6/apf6.cfg
+@@ -0,0 +1,21 @@
++/*
++ * Copyright (C) 2014 ARMadeus Systems <support at armadeus.com>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ *
++ */
++
++/* image version */
++IMAGE_VERSION 2
++
++/*
++ * Boot Device : one of
++ * spi, sd (the board has no nand neither onenand)
++ */
++BOOT_FROM      sd
++
++#define __ASSEMBLY__
++#include <config.h>
++#include "asm/arch/iomux.h"
++#include "asm/arch/crm_regs.h"
++#include "clocks.cfg"
+Index: uboot-2014.07/board/armadeus/apf6/apf6_spl.c
+===================================================================
+--- /dev/null
++++ uboot-2014.07/board/armadeus/apf6/apf6_spl.c
+@@ -0,0 +1,251 @@
++/*
++ * Copyright (C) 2014 ARMadeus systems <support at armadeus.com>
++ *
++ * SPDX-License-Identifier:     GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/io.h>
++#include <asm/arch/iomux.h>
++#include <asm/arch/mx6-ddr.h>
++#include <asm/arch/mx6-pins.h>
++#include <asm/arch/sys_proto.h>
++#include <asm/imx-common/boot_mode.h>
++#include <asm/imx-common/iomux-v3.h>
++#include <spl.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++/* configure MX6Q/DUAL mmdc DDR io registers */
++struct mx6dq_iomux_ddr_regs mx6dq_ddr_ioregs = {
++	/* SDCLK[0:1], CAS, RAS, Reset: Differential input, 40ohm */
++	.dram_sdclk_0 = 0x00020030,
++	.dram_sdclk_1 = 0x00020030,
++	.dram_cas = 0x00020030,
++	.dram_ras = 0x00020030,
++	.dram_reset = 0x00020030,
++	/* SDCKE[0:1]: 100k pull-up */
++	.dram_sdcke0 = 0x00003000,
++	.dram_sdcke1 = 0x00003000,
++	/* SDBA2: pull-up disabled */
++	.dram_sdba2 = 0x00000000,
++	/* SDODT[0:1]: 100k pull-up, 40 ohm */
++	.dram_sdodt0 = 0x00003030,
++	.dram_sdodt1 = 0x00003030,
++	/* SDQS[0:7]: Differential input, 40 ohm */
++	.dram_sdqs0 = 0x00000030,
++	.dram_sdqs1 = 0x00000030,
++	.dram_sdqs2 = 0x00000030,
++	.dram_sdqs3 = 0x00000030,
++	.dram_sdqs4 = 0x00000030,
++	.dram_sdqs5 = 0x00000030,
++	.dram_sdqs6 = 0x00000030,
++	.dram_sdqs7 = 0x00000030,
++
++	/* DQM[0:7]: Differential input, 40 ohm */
++	.dram_dqm0 = 0x00020030,
++	.dram_dqm1 = 0x00020030,
++	.dram_dqm2 = 0x00020030,
++	.dram_dqm3 = 0x00020030,
++	.dram_dqm4 = 0x00020030,
++	.dram_dqm5 = 0x00020030,
++	.dram_dqm6 = 0x00020030,
++	.dram_dqm7 = 0x00020030,
++};
++
++/* configure MX6Q/DUAL mmdc GRP io registers */
++struct mx6dq_iomux_grp_regs mx6dq_grp_ioregs = {
++	/* DDR3 */
++	.grp_ddr_type = 0x000c0000,
++	.grp_ddrmode_ctl = 0x00020000,
++	/* disable DDR pullups */
++	.grp_ddrpke = 0x00000000,
++	/* ADDR[00:16], SDBA[0:1]: 40 ohm */
++	.grp_addds = 0x00000030,
++	/* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm */
++	.grp_ctlds = 0x00000030,
++	/* DATA[00:63]: Differential input, 40 ohm */
++	.grp_ddrmode = 0x00020000,
++	.grp_b0ds = 0x00000030,
++	.grp_b1ds = 0x00000030,
++	.grp_b2ds = 0x00000030,
++	.grp_b3ds = 0x00000030,
++	.grp_b4ds = 0x00000030,
++	.grp_b5ds = 0x00000030,
++	.grp_b6ds = 0x00000030,
++	.grp_b7ds = 0x00000030,
++};
++
++/* configure MX6SOLO/DUALLITE mmdc DDR io registers */
++struct mx6sdl_iomux_ddr_regs mx6sdl_ddr_ioregs = {
++	/* SDCLK[0:1], CAS, RAS, Reset: Differential input, 40ohm */
++	.dram_sdclk_0 = 0x00020030,
++	.dram_sdclk_1 = 0x00020030,
++	.dram_cas = 0x00020030,
++	.dram_ras = 0x00020030,
++	.dram_reset = 0x00020030,
++	/* SDCKE[0:1]: 100k pull-up */
++	.dram_sdcke0 = 0x00003000,
++	.dram_sdcke1 = 0x00003000,
++	/* SDBA2: pull-up disabled */
++	.dram_sdba2 = 0x00000000,
++	/* SDODT[0:1]: 100k pull-up, 40 ohm */
++	.dram_sdodt0 = 0x00003030,
++	.dram_sdodt1 = 0x00003030,
++	/* SDQS[0:7]: Differential input, 40 ohm */
++	.dram_sdqs0 = 0x00000030,
++	.dram_sdqs1 = 0x00000030,
++	.dram_sdqs2 = 0x00000030,
++	.dram_sdqs3 = 0x00000030,
++	.dram_sdqs4 = 0x00000030,
++	.dram_sdqs5 = 0x00000030,
++	.dram_sdqs6 = 0x00000030,
++	.dram_sdqs7 = 0x00000030,
++
++	/* DQM[0:7]: Differential input, 40 ohm */
++	.dram_dqm0 = 0x00020030,
++	.dram_dqm1 = 0x00020030,
++	.dram_dqm2 = 0x00020030,
++	.dram_dqm3 = 0x00020030,
++	.dram_dqm4 = 0x00020030,
++	.dram_dqm5 = 0x00020030,
++	.dram_dqm6 = 0x00020030,
++	.dram_dqm7 = 0x00020030,
++};
++
++/* configure MX6SOLO/DUALLITE mmdc GRP io registers */
++struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = {
++	/* DDR3 */
++	.grp_ddr_type = 0x000c0000,
++	/* SDQS[0:7]: Differential input, 40 ohm */
++	.grp_ddrmode_ctl = 0x00020000,
++	/* disable DDR pullups */
++	.grp_ddrpke = 0x00000000,
++	/* ADDR[00:16], SDBA[0:1]: 40 ohm */
++	.grp_addds = 0x00000030,
++	/* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm */
++	.grp_ctlds = 0x00000030,
++	/* DATA[00:63]: Differential input, 40 ohm */
++	.grp_ddrmode = 0x00020000,
++	.grp_b0ds = 0x00000030,
++	.grp_b1ds = 0x00000030,
++	.grp_b2ds = 0x00000030,
++	.grp_b3ds = 0x00000030,
++	.grp_b4ds = 0x00000030,
++	.grp_b5ds = 0x00000030,
++	.grp_b6ds = 0x00000030,
++	.grp_b7ds = 0x00000030,
++};
++
++/* MT41K128M16JT-125 */
++static struct mx6_ddr3_cfg mt41k128m16jt_125 = {
++	.mem_speed = 1600,
++	.density = 2,
++	.width = 16,
++	.banks = 8,
++	.rowaddr = 14,
++	.coladdr = 10,
++	.pagesz = 2,
++	.trcd = 1375,
++	.trcmin = 4875,
++	.trasmin = 3500,
++};
++
++/* APF6Dev specific calibration */
++static struct mx6_mmdc_calibration apf6dev_mmdc_calib = {
++	/* write leveling calibration determine */
++	.p0_mpwldectrl0 = 0x001C0018,
++	.p0_mpwldectrl1 = 0x001F001C,
++	.p1_mpwldectrl0 = 0x00110022,
++	.p1_mpwldectrl1 = 0x00080018,
++	/* Read DQS Gating calibration */
++	.p0_mpdgctrl0 = 0x42580264,
++	.p0_mpdgctrl1 = 0x02590250,
++	.p1_mpdgctrl0 = 0x425C0260,
++	.p1_mpdgctrl1 = 0x02540240,
++	/* Read Calibration: DQS delay relative to DQ read access */
++	.p0_mprddlctl = 0x3632343A,
++	.p1_mprddlctl = 0x3436303E,
++	/* Write Calibration: DQ/DM delay relative to DQS write access */
++	.p0_mpwrdlctl = 0x38363E3A,
++	.p1_mpwrdlctl = 0x3C303C36,
++};
++
++static void spl_dram_init(int width)
++{
++	struct mx6_ddr3_cfg *mem = &mt41k128m16jt_125;
++	struct mx6_ddr_sysinfo sysinfo = {
++		/* width of data bus:0=16,1=32,2=64 */
++		.dsize = width/32,
++		/* config for full 4GB range so that get_mem_size() works */
++		.cs_density = 32, /* 32Gb per CS */
++		/* single chip select */
++		.ncs = 1,
++		.cs1_mirror = 1,
++		.rtt_wr = 1 /*DDR3_RTT_60_OHM*/,	/* RTT_Wr = RZQ/4 */
++#ifdef RTT_NOM_120OHM
++		.rtt_nom = 2 /*DDR3_RTT_120_OHM*/,	/* RTT_Nom = RZQ/2 */
++#else
++		.rtt_nom = 1 /*DDR3_RTT_60_OHM*/,	/* RTT_Nom = RZQ/4 */
++#endif
++		.walat = 0,	/* Write additional latency */
++		.ralat = 5,	/* Read additional latency */
++		.mif3_mode = 3,	/* Command prediction working mode */
++		.bi_on = 1,	/* Bank interleaving enabled */
++		.sde_to_rst = 0x10,	/* 14 cycles, 200us (JEDEC default) */
++		.rst_to_cke = 0x23,	/* 33 cycles, 500us (JEDEC default) */
++	};
++
++	if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D))
++		mx6dq_dram_iocfg(width, &mx6dq_ddr_ioregs,
++				 &mx6dq_grp_ioregs);
++	else
++		mx6sdl_dram_iocfg(width, &mx6sdl_ddr_ioregs,
++				  &mx6sdl_grp_ioregs);
++	mx6_dram_cfg(&sysinfo, &apf6dev_mmdc_calib, mem);
++}
++
++/*
++ * called from C runtime startup code (arch/arm/lib/crt0.S:_main)
++ * - we have a stack and a place to store GD, both in SRAM
++ * - no variable global data is available
++ */
++void board_init_f(ulong dummy)
++{
++	/*
++	 * Zero out global data:
++	 *  - this shoudl be done by crt0.S
++	 *  - failure to zero it will cause i2c_setup to fail
++	 */
++	memset((void *)gd, 0, sizeof(struct global_data));
++
++	/* setup AIPS and disable watchdog */
++	arch_cpu_init();
++
++	/* iomux */
++	board_early_init_f();
++
++	/* setup GP timer */
++	timer_init();
++
++	/* UART clocks enabled and gd valid - init serial console */
++	preloader_console_init();
++
++	/* configure MMDC for SDRAM width/size and per-model calibration */
++	if (is_cpu_type(MXC_CPU_MX6SOLO))
++		spl_dram_init(32);
++	else
++		spl_dram_init(64);
++
++	/* Clear the BSS. */
++	memset(__bss_start, 0, __bss_end - __bss_start);
++
++	get_clocks();
++
++	/* load/boot image from boot device */
++	board_init_r(NULL, 0);
++}
++
++void reset_cpu(ulong addr)
++{
++}
+Index: uboot-2014.07/board/armadeus/apf6/clocks.cfg
+===================================================================
+--- /dev/null
++++ uboot-2014.07/board/armadeus/apf6/clocks.cfg
+@@ -0,0 +1,25 @@
++/* 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
++DATA 4, CCM_CCGR4, 0x00FFF300
++DATA 4, CCM_CCGR5, 0x0F0000C3
++DATA 4, CCM_CCGR6, 0x000003FF
++
++/* enable AXI cache for VDOA/VPU/IPU */
++DATA 4, MX6_IOMUXC_GPR4, 0xF00000CF
++/* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
++DATA 4, MX6_IOMUXC_GPR6, 0x007F007F
++DATA 4, MX6_IOMUXC_GPR7, 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
+Index: uboot-2014.07/board/armadeus/apf6/fpga.c
+===================================================================
+--- /dev/null
++++ uboot-2014.07/board/armadeus/apf6/fpga.c
+@@ -0,0 +1,173 @@
++/*
++ * (C) Copyright 2002-2014
++ * Nicolas Colombain <nicolas.colombain at armadeus.com>
++ * Rich Ireland, Enterasys Networks, rireland at enterasys.com.
++ * Keith Outwater, keith_outwater at mvis.com.
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ *
++ */
++#include <common.h>
++
++#if defined(CONFIG_FPGA)
++
++#include <asm/gpio.h>
++#include <asm/io.h>
++#include <command.h>
++#include <asm/arch/iomux.h>
++#include "fpga.h"
++#include <fpga.h>
++#include <ACEX1K.h>
++
++#ifdef FPGA_DEBUG
++#define		PRINTF(fmt, args...)	printf(fmt , ##args)
++#else
++#define		PRINTF(fmt, args...)
++#endif
++
++#define FPGA_AS_DATA		IMX_GPIO_NR(1, 29)
++#define FPGA_DCLK		IMX_GPIO_NR(1, 27)
++#define FPGA_CONF_DONE		IMX_GPIO_NR(1, 26)
++#define FPGA_NCONFIG		IMX_GPIO_NR(3, 26)
++#define FPGA_NSTATUS		IMX_GPIO_NR(3, 27)
++#define FPGA_CVP_CONFDONE	IMX_GPIO_NR(3, 22)
++#define FPGA_PERSTL0		IMX_GPIO_NR(3, 18)
++
++
++Altera_CYC2_Passive_Serial_fns altera_fns = {
++	fpga_null_fn,
++	fpga_config_fn,
++	fpga_status_fn,
++	fpga_done_fn,
++	fpga_wr_fn,
++	fpga_null_fn,
++	fpga_null_fn,
++};
++
++Altera_desc fpga = {
++	Altera_CYC2,
++	 passive_serial,
++	 320280l / 8, /* C3 IOSCR*/
++	 (void *) &altera_fns,
++	 NULL,
++	 0
++};
++
++
++int fpga_null_fn(int cookie)
++{
++	return 0;
++}
++
++int fpga_config_fn(int assert, int flush, int cookie)
++{
++	gpio_set_value(FPGA_NCONFIG, assert);
++	return assert;
++}
++
++int fpga_done_fn(int cookie)
++{
++	int result = 0;
++	udelay(10);
++	PRINTF("CONF_DONE check ... ");
++	if (gpio_get_value(FPGA_CONF_DONE) & 1) {
++		PRINTF("high\n");
++		result = 1;
++	} else
++		PRINTF("low\n");
++
++	return result;
++}
++
++int fpga_status_fn(int cookie)
++{
++	int result = 0;
++	PRINTF("STATUS check ... ");
++	if (gpio_get_value(FPGA_NSTATUS) & 1) {
++		PRINTF("high\n");
++		result = 1;
++	} else
++		PRINTF("low\n");
++
++	return result;
++}
++
++int fpga_clk_fn(int assert_clk, int flush, int cookie)
++{
++	PRINTF("CLOCK %s\n", assert_clk ? "high" : "low");
++	gpio_set_value(FPGA_DCLK, assert_clk);
++
++	return assert_clk;
++}
++
++static inline int _write_fpga(u8 val, int dump)
++{
++	int i=0;
++	if (dump)
++		PRINTF("  %02x -> ", val);
++	for (i = 0; i < 8; i++) {
++		gpio_set_value(FPGA_DCLK,0);
++		gpio_set_value(FPGA_AS_DATA,val & 1);
++		gpio_set_value(FPGA_DCLK,1);
++		val >>= 1;
++	}
++	if (dump)
++		PRINTF("\n");
++
++	return 0;
++}
++
++int fpga_wr_fn(const void *buf, size_t len, int flush, int cookie)
++{
++	unsigned char *data = (unsigned char *) buf;
++	int i;
++
++	PRINTF("fpga_wr: buf %p / size %d\n", buf, len);
++	for (i = 0; i < len; i++)
++		_write_fpga(data[i], 0);
++	PRINTF("\n");
++
++	return FPGA_SUCCESS;
++}
++
++int APF6_init_fpga(u_char *buffer, size_t size)
++{
++	PRINTF("Initialize FPGA interface\n");
++
++	gpio_direction_output(FPGA_AS_DATA, 0);
++	gpio_direction_output(FPGA_DCLK, 0);
++	gpio_direction_output(FPGA_NCONFIG, 0);
++
++	fpga_init();
++	fpga_add(fpga_altera, &fpga);
++
++	if ((size >= fpga.size)) {
++		printf("Loading FPGA...");
++		if (FPGA_SUCCESS != fpga_load(0, (void *)buffer, size, BIT_FULL)) {
++			printf("firmware download failed!\n");
++		} else {
++			printf("firmware successfully programmed\n");
++		}
++	}
++
++	return 1;
++}
++
++
++#endif /* CONFIG_FPGA */
+Index: uboot-2014.07/board/armadeus/apf6/fpga.h
+===================================================================
+--- /dev/null
++++ uboot-2014.07/board/armadeus/apf6/fpga.h
+@@ -0,0 +1,34 @@
++/*
++ * (C) Copyright 2002-2010
++ * Eric Jarrige <eric.jarrige at armadeus.org>
++ * Rich Ireland, Enterasys Networks, rireland at enterasys.com.
++ * Keith Outwater, keith_outwater at mvis.com.
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ *
++ */
++extern int APF6_init_fpga(u_char *buffer, size_t size);
++
++extern int fpga_pgm_fn(int assert_pgm, int flush, int cookie);
++extern int fpga_status_fn(int cookie);
++extern int fpga_config_fn(int assert, int flush, int cookie);
++extern int fpga_done_fn(int cookie);
++extern int fpga_clk_fn(int assert_clk, int flush, int cookie);
++extern int fpga_wr_fn(const void *buf, size_t len, int flush, int cookie);
++extern int fpga_null_fn(int cookie);
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/504-apf6-seek_uboot_image_in_boot_partition.patch b/recipes-bsp/u-boot/u-boot-armadeus/504-apf6-seek_uboot_image_in_boot_partition.patch
new file mode 100644
index 0000000..d1e52c7
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/504-apf6-seek_uboot_image_in_boot_partition.patch
@@ -0,0 +1,18 @@
+Index: uboot-2014.07/arch/arm/imx-common/spl.c
+===================================================================
+--- uboot-2014.07.orig/arch/arm/imx-common/spl.c
++++ uboot-2014.07/arch/arm/imx-common/spl.c
+@@ -64,9 +64,12 @@ u32 spl_boot_device(void)
+ u32 spl_boot_mode(void)
+ {
+	switch (spl_boot_device()) {
+-	/* for MMC return either RAW or FAT mode */
+	case BOOT_DEVICE_MMC1:
+	case BOOT_DEVICE_MMC2:
++#ifdef CONFIG_SUPPORT_EMMC_BOOT
++		return MMCSD_MODE_EMMCBOOT;
++#endif
++
+ #ifdef CONFIG_SPL_FAT_SUPPORT
+		return MMCSD_MODE_FAT;
+ #else
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/505-apf6-in_bootstrap_get_uboot_image_on_serial_port.patch b/recipes-bsp/u-boot/u-boot-armadeus/505-apf6-in_bootstrap_get_uboot_image_on_serial_port.patch
new file mode 100644
index 0000000..ca4e6ce
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/505-apf6-in_bootstrap_get_uboot_image_on_serial_port.patch
@@ -0,0 +1,16 @@
+Index: uboot-2014.07/arch/arm/imx-common/spl.c
+===================================================================
+--- uboot-2014.07.orig/arch/arm/imx-common/spl.c
++++ uboot-2014.07/arch/arm/imx-common/spl.c
+@@ -19,6 +19,11 @@ u32 spl_boot_device(void)
+ {
+	struct src *psrc = (struct src *)SRC_BASE_ADDR;
+	unsigned reg = readl(&psrc->sbmr1);
++	unsigned reg2 = readl(&psrc->sbmr2);
++
++	/* In bootstrap get U-Boot on the serial port */
++	if (((reg2 & 0x3000000) >> 24) == 0x1)
++		return BOOT_DEVICE_UART;
+
+	/* BOOT_CFG1[7:4] - see IMX6DQRM Table 8-8 */
+	switch ((reg & 0x000000FF) >> 4) {
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/506-apf6-in_bootstrap_dont_use_env_vars.patch b/recipes-bsp/u-boot/u-boot-armadeus/506-apf6-in_bootstrap_dont_use_env_vars.patch
new file mode 100644
index 0000000..6268851
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/506-apf6-in_bootstrap_dont_use_env_vars.patch
@@ -0,0 +1,30 @@
+Index: uboot-2014.07/board/armadeus/apf6/apf6.c
+===================================================================
+--- uboot-2014.07.orig/board/armadeus/apf6/apf6.c
++++ uboot-2014.07/board/armadeus/apf6/apf6.c
+@@ -18,6 +18,7 @@
+ #include <asm/imx-common/video.h>
+ #include <asm/io.h>
+ #include <common.h>
++#include <environment.h>
+ #include <fsl_esdhc.h>
+ #include <linux/ctype.h>
+ #include <miiphy.h>
+@@ -327,9 +328,17 @@ int board_late_init(void)
+ 	u_char *firmware_buffer =
+ 	    (u_char *) (CONFIG_SYS_LOAD_ADDR + CONFIG_SYS_MONITOR_LEN);
+ 	size_t size = 0;
++	struct src *psrc = (struct src *)SRC_BASE_ADDR;
++	unsigned reg = readl(&psrc->sbmr2);
+ 
+ 	SETUP_IOMUX_PADS(usb_pads);
+ 
++	/* In bootstrap don't use the the env vars */
++	if (((reg & 0x3000000) >> 24) == 0x1) {
++		set_default_env(NULL);
++		setenv("preboot", "");
++	}
++
+ 	if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D))
+ 		setenv("fdt_file", "imx6q-apf6dev.dtb");
+ 	else if (is_cpu_type(MXC_CPU_MX6DL) || is_cpu_type(MXC_CPU_MX6SOLO))
diff --git a/recipes-bsp/u-boot/u-boot-armadeus/apf6-config.h b/recipes-bsp/u-boot/u-boot-armadeus/apf6-config.h
new file mode 100644
index 0000000..4d0aabc
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus/apf6-config.h
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2013-2015 Armadeus Systems
+ *
+ * Configuration settings for the APF6.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+#define DEBUG
+*/
+
+#define CONFIG_SYS_GENERIC_BOARD
+
+#define CONFIG_VERSION_VARIABLE
+#define CONFIG_ENV_VERSION	5
+#define CONFIG_BOARD_NAME	apf6
+
+/* SPL */
+#define CONFIG_SPL_MMC_SUPPORT
+#define CONFIG_SPL_YMODEM_SUPPORT
+
+#include "imx6_spl.h"
+#include "mx6_common.h"
+
+#define CONFIG_MX6
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DISPLAY_BOARDINFO
+
+#define CONFIG_MACH_TYPE		4412 /* has to be changed !! */
+
+#include <asm/arch/imx-regs.h>
+#include <asm/imx-common/gpio.h>
+#include <linux/sizes.h>
+
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+#define CONFIG_REVISION_TAG
+
+/* 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
+
+#define CONFIG_MXC_UART
+#define CONFIG_MXC_UART_BASE		UART4_BASE
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_CONS_INDEX		1
+#define CONFIG_BAUDRATE			115200
+
+/* U-boot commands */
+#include <config_cmd_default.h>
+#undef CONFIG_CMD_IMLS
+#define CONFIG_CMD_BMODE
+#define CONFIG_CMD_BOOTZ
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_DNS
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_EXT4
+#define CONFIG_CMD_EXT4_WRITE
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_FS_GENERIC
+#define CONFIG_CMD_HDMIDETECT
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_PCI
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SETEXPR
+#define CONFIG_CMD_USB
+#define CONFIG_CMD_USB_MASS_STORAGE
+
+#define CONFIG_BOOTDELAY		5
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+
+#define CONFIG_SYS_MEMTEST_START	0x10000000
+#define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_MEMTEST_START + 500 * SZ_1M)
+#define CONFIG_LOADADDR			0x12000000
+
+/* MMC Configuration */
+#define CONFIG_SUPPORT_EMMC_BOOT
+#define CONFIG_FSL_ESDHC
+#define CONFIG_FSL_USDHC
+#define CONFIG_SYS_FSL_USDHC_NUM	2
+#define CONFIG_SYS_FSL_ESDHC_ADDR	USDHC2_BASE_ADDR
+
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_BOUNCE_BUFFER
+#define CONFIG_DOS_PARTITION
+
+/* Ethernet Configuration */
+#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		1
+#define CONFIG_NETCONSOLE
+#define CONFIG_PHYLIB
+#define CONFIG_PHY_ATHEROS
+
+/* Framebuffer */
+#define CONFIG_BMP_16BPP
+#define CONFIG_CFB_CONSOLE
+#define CONFIG_IMX_HDMI
+#define CONFIG_IMX_VIDEO_SKIP
+#define CONFIG_IPUV3_CLK 260000000
+#define CONFIG_SPLASH_SCREEN
+#define CONFIG_SPLASH_SCREEN_ALIGN
+#define CONFIG_VGA_AS_SINGLE_DEVICE
+#define CONFIG_VIDEO
+#define CONFIG_VIDEO_BMP_RLE8
+#define CONFIG_VIDEO_IPUV3
+#define CONFIG_VIDEO_LOGO
+
+/* USB Configs */
+#define CONFIG_USB_DEVICE
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_MX6
+#define CONFIG_USB_STORAGE
+#define CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP
+#define CONFIG_USB_HOST_ETHER
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
+#define CONFIG_MXC_USB_PORTSC		(PORT_PTS_UTMI | PORT_PTS_PTW)
+#define CONFIG_MXC_USB_FLAGS		0
+#define CONFIG_EHCI_HCD_INIT_AFTER_RESET
+/* Gadget part */
+#define CONFIG_CI_UDC
+#define CONFIG_USB_GADGET
+#define CONFIG_USB_GADGET_DUALSPEED
+#define CONFIG_USB_GADGET_MASS_STORAGE
+#define CONFIG_USB_GADGET_VBUS_DRAW	2
+#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_G_DNL_VENDOR_NUM		0x0525
+#define CONFIG_G_DNL_PRODUCT_NUM	0xa4a5
+#define CONFIG_G_DNL_MANUFACTURER	"Armadeus Systems"
+
+/* PCIE */
+#define CONFIG_PCI
+#define CONFIG_PCI_PNP
+#define CONFIG_PCIE_IMX
+
+/* FPGA */
+#define CONFIG_FPGA_COUNT	1
+#define CONFIG_FPGA
+#define CONFIG_FPGA_ALTERA
+#define CONFIG_FPGA_CYCLON2
+
+/*
+ *  BOOTP options
+ */
+#define CONFIG_BOOTP_SUBNETMASK
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_BOOTFILESIZE
+#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_DNS2
+
+#define CONFIG_HOSTNAME         CONFIG_BOARD_NAME
+#define CONFIG_ROOTPATH         "/tftpboot/" __stringify(CONFIG_BOARD_NAME) "-root"
+
+#define CONFIG_PREBOOT		"run check_env;"
+
+#define ACFG_CONSOLE_DEV        ttymxc3
+#define CONFIG_SYS_AUTOLOAD	"no"
+#define CONFIG_BOOTARGS		"console=" __stringify(ACFG_CONSOLE_DEV) "," __stringify(CONFIG_BAUDRATE)
+#define CONFIG_BOOTCOMMAND 	"run emmcboot"
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"env_version="          __stringify(CONFIG_ENV_VERSION)         "\0"			\
+	"consoledev="           __stringify(ACFG_CONSOLE_DEV)           "\0" 			\
+	"board_name="           __stringify(CONFIG_BOARD_NAME)          "\0" 			\
+	"fdt_high=0xffffffff\0" 								\
+	"initrd_high=0xffffffff\0" 								\
+	"fdt_addr=0x18000000\0" 								\
+	"ip_dyn=yes\0" 										\
+	"stdin=serial\0"									\
+	"stout=serial\0"									\
+	"sterr=serial\0"									\
+	"mmcdev=0\0" 										\
+	"mmcpart=1\0" 										\
+	"mmcroot=/dev/mmcblk2p2 ro\0" 								\
+	"mmcrootfstype=ext4 rootwait\0" 							\
+	"check_env=if test -n ${flash_env_version}; "						\
+		"then env default env_version; "						\
+		"else env set flash_env_version ${env_version}; env save; "			\
+		"fi; "										\
+		"if itest ${flash_env_version} != ${env_version}; then "			\
+			"echo \"*** Warning - Environment version"				\
+			" change suggests: run flash_reset_env; reset\"; "			\
+			"env default flash_reset_env; "						\
+		"else exit; fi; \0"								\
+	"flash_reset_env=env default -f -a && saveenv && "					\
+		"echo Flash environment variables erased!\0"					\
+	"download_uboot_spl=tftpboot ${loadaddr} ${board_name}-u-boot.spl\0" 			\
+	"flash_uboot_spl=" 									\
+		"if mmc dev 0 1; then "								\
+			"setexpr sz ${filesize} / 0x200; " 					\
+			"setexpr sz ${sz} + 1; " 						\
+			"if mmc write ${loadaddr} 0x2 ${sz}; then " 				\
+				"echo Flashing of U-boot SPL succeed; " 			\
+			"else echo Flashing of U-boot SPL failed; "				\
+			"fi; "									\
+		"fi;\0" 									\
+	"download_uboot_img=tftpboot ${loadaddr} ${board_name}-u-boot.img\0" 			\
+	"flash_uboot_img=" 									\
+		"if mmc dev 0 1; then "								\
+			"setexpr sz ${filesize} / 0x200; " 					\
+			"setexpr sz ${sz} + 1; " 						\
+			"if mmc write ${loadaddr} 0x8a ${sz}; then " 				\
+				"echo Flashing of U-boot image succeed; " 			\
+			"else echo Flashing of U-boot image failed; " 				\
+			"fi; "									\
+		"fi;\0" 									\
+	"update_uboot=run download_uboot_spl flash_uboot_spl " 					\
+		"download_uboot_img flash_uboot_img\0" 						\
+	"download_kernel=tftpboot ${loadaddr} ${board_name}-linux.bin\0" 			\
+	"flash_kernel=" 									\
+		"if ext4write mmc ${mmcdev}:${mmcpart} ${loadaddr} /${board_name}-linux.bin ${filesize}; then "	\
+		      "echo Flashing of kernel succeed; "                      			\
+		      "else echo Flashing of kernel failed; "                  			\
+		"fi;\0"						               			\
+	"update_kernel=run download_kernel flash_kernel\0" 					\
+	"download_dtb=tftpboot ${loadaddr} ${fdt_file}\0" 					\
+	"flash_dtb=" 										\
+		"if ext4write mmc ${mmcdev}:${mmcpart} ${loadaddr} /dtbs/${fdt_file} ${filesize}; then " 	\
+		      "echo Flashing of dtb succeed; "                      			\
+		      "else echo Flashing of dtb failed; "                  			\
+		"fi;\0" 									\
+	"update_dtb=run download_dtb flash_dtb\0" 						\
+	"download_rootfs=tftpboot ${loadaddr} ${board_name}-rootfs.ext4\0" 			\
+	"flash_rootfs=" 									\
+		"if mmc dev 0 0; then "								\
+			"setexpr nbblocks ${filesize} / 0x200; " 				\
+			"setexpr nbblocks ${nbblocks} + 1; " 					\
+			"if mmc write ${loadaddr} 0x18800 ${nbblocks}; then " 			\
+				"echo Flashing of rootfs image succeed; " 			\
+			"else echo Flashing of rootfs image failed; " 				\
+			"fi; "									\
+		"fi;\0" 									\
+	"update_rootfs=run download_rootfs flash_rootfs\0" 					\
+	"update_all=run update_kernel update_rootfs update_dtb update_uboot\0"				\
+	"loadzimage=load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${board_name}-linux.bin\0" 	\
+	"loadfdt=load mmc ${mmcdev}:${mmcpart} ${fdt_addr} /dtbs/${fdt_file}\0" 		\
+	"addipargs=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:"			\
+		"${gatewayip}:${netmask}:${hostname}:eth0:off\0"				\
+	"addmmcargs=setenv bootargs ${bootargs} root=${mmcroot} " 				\
+		"rootfstype=${mmcrootfstype}\0" 						\
+	"emmcboot=setenv bootargs console=${consoledev},${baudrate} ${extrabootargs}; "		\
+		"run addmmcargs; "								\
+		"run loadzimage && run loadfdt && bootz ${loadaddr} - ${fdt_addr};\0"		\
+	"addnfsargs=setenv bootargs ${bootargs} root=/dev/nfs rw "				\
+		"nfsroot=${serverip}:${rootpath}\0"						\
+	"nfsboot=setenv bootargs console=${consoledev},${baudrate} ${extrabootargs}; "		\
+		"run addnfsargs addipargs; "							\
+		"nfs ${loadaddr} ${serverip}:${rootpath}/boot/${board_name}-linux.bin && "	\
+		"nfs ${fdt_addr} ${serverip}:${rootpath}/boot/dtbs/${fdt_file} && "		\
+		"bootz ${loadaddr} - ${fdt_addr};\0"
+
+/* Miscellaneous configurable options */
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_CONSOLE_MUX
+#define CONFIG_SYS_CBSIZE		256
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_PROMPT		"BIOS> "
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS	       16
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+
+#define CONFIG_SYS_LOAD_ADDR		CONFIG_LOADADDR
+#define CONFIG_SYS_HZ			1000
+
+/* 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_SYS_NO_FLASH
+
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV		0
+#define CONFIG_SYS_MMC_ENV_PART		1
+#define CONFIG_ENV_SIZE			(10 * 1024)
+#define CONFIG_ENV_OFFSET		(1024 * 1024) /* 1 MB */
+#define CONFIG_ENV_OFFSET_REDUND	(1536 * 1024) /* 512KB from CONFIG_ENV_OFFSET */
+
+#define CONFIG_OF_LIBFDT
+#define CONFIG_SUPPORT_RAW_INITRD
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+#define CONFIG_CMD_CACHE
+#endif
+
+#endif			       /* __CONFIG_H * */
diff --git a/recipes-bsp/u-boot/u-boot-armadeus_2014.07.bb b/recipes-bsp/u-boot/u-boot-armadeus_2014.07.bb
new file mode 100644
index 0000000..3efae48
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-armadeus_2014.07.bb
@@ -0,0 +1,52 @@
+# Armadeus u-boot
+
+require recipes-bsp/u-boot/u-boot.inc
+
+DESCRIPTION = "u-boot which includes support for Armadeus Boards."
+
+LICENSE = "GPLv2+"
+LIC_FILES_CHKSUM = "file://Licenses/gpl-2.0.txt;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
+                    file://README;beginline=1;endline=22;md5=2687c5ebfd9cb284491c3204b726ea29 "
+
+PROVIDES += "u-boot"
+
+PV = "2014.07"
+
+SRCREV = "524123a70761110c5cf3ccc5f52f6d4da071b959"
+
+SRC_URI += "file://001-restore-command-env-param-compatitbility.patch \
+            file://040-i2c-mxc-fix-mx51-i2c-declaration.patch \
+            file://102-mx1-i2c.patch \
+            file://103-apf9328.patch \
+            file://104-apf9328-makefile.patch \
+            file://106-mx1-pllclk.patch \
+            file://107-mx1-pllclk-debug.patch \
+            file://108-DM9000.patch \
+            file://111-mx1-timer.patch \
+            file://300-imx27-fix_dcache_boot_issue.patch \
+            file://302-apf27-support-boot-from-RAM.patch \
+            file://311-imx-nand-lock-unlock.patch \
+            file://320-spartan.patch \
+            file://340-apf27-misc-commands.patch \
+            file://350-nand_large_file_download.patch \
+            file://360-arm-support-continuous-mmu-mem-mapping.patch \
+            file://400-imx51.patch \
+            file://401-apf51.patch \
+            file://410-imx-iim.patch \
+            file://420-apf51-nand-spl-NG.patch \
+            file://501-imx28-update-and-fix.patch \
+            file://502-add-apf28.patch \
+            file://503-add-apf6.patch \
+            file://504-apf6-seek_uboot_image_in_boot_partition.patch \
+            file://505-apf6-in_bootstrap_get_uboot_image_on_serial_port.patch \
+            file://506-apf6-in_bootstrap_dont_use_env_vars.patch \
+            file://apf6-config.h"
+
+COMPATIBLE_MACHINE = "(apf6dl|apf6q)"
+
+do_configure_prepend_apf6() {
+    cp "${WORKDIR}/apf6-config.h" "${S}/include/configs/apf6.h"
+}
+
+SPL_BINARY="SPL"
+
-- 
2.1.4



More information about the meta-freescale mailing list