[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