Merge branch 'master' of git://git.denx.de/u-boot
diff --git a/Makefile b/Makefile
index 8c0ca1b..775755e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2015
 PATCHLEVEL = 10
 SUBLEVEL =
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc5
 NAME =
 
 # *DOCUMENTATION*
diff --git a/README b/README
index c22b60b..0dc657d 100644
--- a/README
+++ b/README
@@ -681,8 +681,10 @@
 		CONFIG_ARM_ERRATA_742230
 		CONFIG_ARM_ERRATA_743622
 		CONFIG_ARM_ERRATA_751472
-		CONFIG_ARM_ERRATA_794072
 		CONFIG_ARM_ERRATA_761320
+		CONFIG_ARM_ERRATA_773022
+		CONFIG_ARM_ERRATA_774769
+		CONFIG_ARM_ERRATA_794072
 
 		If set, the workarounds for these ARM errata are applied early
 		during U-Boot startup. Note that these options force the
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3a336e6..7981355 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -567,6 +567,15 @@
 	select ARM64
 	select SEMIHOSTING
 
+config TARGET_VEXPRESS64_BASE_FVP_DRAM
+	bool "Support Versatile Express ARMv8a FVP BASE model booting from DRAM"
+	select ARM64
+	help
+	  This target is derived from TARGET_VEXPRESS64_BASE_FVP and over-rides
+	  the default config to allow the user to load the images directly into
+	  DRAM using model parameters rather than by using semi-hosting to load
+	  the files from the host filesystem.
+
 config TARGET_VEXPRESS64_JUNO
 	bool "Support Versatile Express Juno Development Platform"
 	select ARM64
diff --git a/arch/arm/cpu/arm926ejs/lpc32xx/clk.c b/arch/arm/cpu/arm926ejs/lpc32xx/clk.c
index 1ef8a36..f5e2103 100644
--- a/arch/arm/cpu/arm926ejs/lpc32xx/clk.c
+++ b/arch/arm/cpu/arm926ejs/lpc32xx/clk.c
@@ -54,12 +54,12 @@
 	if (fref > 27000000ULL || fref < 1000000ULL)
 		return 0;
 
-	fout = fref * m_div;
-	if (val & CLK_HCLK_PLL_FEEDBACK) {
-		fcco = fout;
+	fcco = fref * m_div;
+	fout = fcco;
+	if (val & CLK_HCLK_PLL_FEEDBACK)
+		fcco *= p_div;
+	else
 		do_div(fout, p_div);
-	} else
-		fcco = fout * p_div;
 
 	if (fcco > 320000000ULL || fcco < 156000000ULL)
 		return 0;
diff --git a/arch/arm/cpu/armv7/ls102xa/cpu.c b/arch/arm/cpu/armv7/ls102xa/cpu.c
index 8dd95d9..e2eb5f3 100644
--- a/arch/arm/cpu/armv7/ls102xa/cpu.c
+++ b/arch/arm/cpu/armv7/ls102xa/cpu.c
@@ -13,6 +13,8 @@
 #include <tsec.h>
 #include <netdev.h>
 #include <fsl_esdhc.h>
+#include <config.h>
+#include <fsl_wdog.h>
 
 #include "fsl_epu.h"
 
@@ -354,3 +356,16 @@
 	asm volatile("sev");
 }
 #endif
+
+void reset_cpu(ulong addr)
+{
+	struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
+
+	clrbits_be16(&wdog->wcr, WCR_SRS);
+
+	while (1) {
+		/*
+		 * Let the watchdog trigger
+		 */
+	}
+}
diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S
index 30d81db..31d1c9e 100644
--- a/arch/arm/cpu/armv7/nonsec_virt.S
+++ b/arch/arm/cpu/armv7/nonsec_virt.S
@@ -53,6 +53,20 @@
 	bl	psci_arch_init
 #endif
 
+#ifdef CONFIG_ARM_ERRATA_773022
+	mrc	p15, 0, r5, c1, c0, 1
+	orr	r5, r5, #(1 << 1)
+	mcr	p15, 0, r5, c1, c0, 1
+	isb
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_774769
+	mrc	p15, 0, r5, c1, c0, 1
+	orr	r5, r5, #(1 << 25)
+	mcr	p15, 0, r5, c1, c0, 1
+	isb
+#endif
+
 	mrc	p15, 0, r5, c1, c1, 0		@ read SCR
 	bic	r5, r5, #0x4a			@ clear IRQ, EA, nET bits
 	orr	r5, r5, #0x31			@ enable NS, AW, FW bits
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
index b40198b..d11365b 100644
--- a/arch/arm/cpu/armv7/sunxi/board.c
+++ b/arch/arm/cpu/armv7/sunxi/board.c
@@ -21,6 +21,7 @@
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/gpio.h>
+#include <asm/arch/spl.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/timer.h>
 #include <asm/arch/tzpc.h>
@@ -152,7 +153,7 @@
 	 * binary over USB. If it is found, it determines where SPL was
 	 * read from.
 	 */
-	if (readl(4) != 0x4E4F4765 || readl(8) != 0x3054422E) /* eGON.BT0 */
+	if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */
 		return BOOT_DEVICE_BOARD;
 
 	/* The BROM will try to boot from mmc0 first, so try that first. */
@@ -198,11 +199,6 @@
 	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
 #endif
 	sunxi_board_init();
-
-	/* Clear the BSS. */
-	memset(__bss_start, 0, __bss_end - __bss_start);
-
-	board_init_r(NULL, 0);
 }
 #endif
 
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 5f10243..65b4230 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -153,11 +153,13 @@
 	sun8i-a23-evb.dtb \
 	sun8i-a23-gt90h-v4.dtb \
 	sun8i-a23-ippo-q8h-v5.dtb \
-	sun8i-a23-ippo-q8h-v1.2.dtb
+	sun8i-a23-ippo-q8h-v1.2.dtb \
+	sun8i-a23-q8-tablet.dtb
 dtb-$(CONFIG_MACH_SUN8I_A33) += \
 	sun8i-a33-et-q8-v1.6.dtb \
 	sun8i-a33-ga10h-v1.1.dtb \
 	sun8i-a33-ippo-q8h-v1.2.dtb \
+	sun8i-a33-q8-tablet.dtb \
 	sun8i-a33-sinlinx-sina33.dtb
 dtb-$(CONFIG_MACH_SUN9I) += \
 	sun9i-a80-optimus.dtb \
diff --git a/arch/arm/dts/exynos4210-trats.dts b/arch/arm/dts/exynos4210-trats.dts
index 36d02df..f3fac80 100644
--- a/arch/arm/dts/exynos4210-trats.dts
+++ b/arch/arm/dts/exynos4210-trats.dts
@@ -117,4 +117,8 @@
 	sdhci@12540000 {
 		status = "disabled";
 	};
+
+	dwmmc@12550000 {
+		status = "disabled";
+	};
 };
diff --git a/arch/arm/dts/ls1021a-twr.dts b/arch/arm/dts/ls1021a-twr.dts
index 0e61c07..6ccd332 100644
--- a/arch/arm/dts/ls1021a-twr.dts
+++ b/arch/arm/dts/ls1021a-twr.dts
@@ -17,6 +17,7 @@
 		enet0_sgmii_phy = &sgmii_phy2;
 		enet1_sgmii_phy = &sgmii_phy0;
 		spi0 = &qspi;
+		spi1 = &dspi1;
 	};
 };
 
@@ -33,6 +34,21 @@
 	};
 };
 
+&dspi1 {
+	bus-num = <0>;
+	status = "okay";
+
+	dspiflash: at26df081a@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "spi-flash";
+		spi-max-frequency = <16000000>;
+		spi-cpol;
+		spi-cpha;
+		reg = <0>;
+	};
+};
+
 &i2c0 {
 	status = "okay";
 };
diff --git a/arch/arm/dts/sun8i-a23-q8-tablet.dts b/arch/arm/dts/sun8i-a23-q8-tablet.dts
new file mode 100644
index 0000000..6062ea7
--- /dev/null
+++ b/arch/arm/dts/sun8i-a23-q8-tablet.dts
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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 file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun8i-a23.dtsi"
+#include "sun8i-q8-common.dtsi"
+
+/ {
+	model = "Q8 A23 Tablet";
+	compatible = "allwinner,q8-a23", "allwinner,sun8i-a23";
+};
+
+/*
+ * FIXME for now we only support host mode and rely on u-boot to have
+ * turned on Vbus which is controlled by the axp223 pmic on the board.
+ *
+ * Once we have axp223 support we should switch to fully supporting otg.
+ */
+&usb_otg {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbphy {
+	status = "okay";
+};
diff --git a/arch/arm/dts/sun8i-a33-q8-tablet.dts b/arch/arm/dts/sun8i-a33-q8-tablet.dts
new file mode 100644
index 0000000..44b3229
--- /dev/null
+++ b/arch/arm/dts/sun8i-a33-q8-tablet.dts
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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 file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun8i-a33.dtsi"
+#include "sun8i-q8-common.dtsi"
+
+/ {
+	model = "Q8 A33 Tablet";
+	compatible = "allwinner,q8-a33", "allwinner,sun8i-a33";
+};
+
+/*
+ * FIXME for now we only support host mode and rely on u-boot to have
+ * turned on Vbus which is controlled by the axp223 pmic on the board.
+ *
+ * Once we have axp223 support we should switch to fully supporting otg.
+ */
+&usb_otg {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbphy {
+	status = "okay";
+};
diff --git a/arch/arm/dts/sun8i-q8-common.dtsi b/arch/arm/dts/sun8i-q8-common.dtsi
new file mode 100644
index 0000000..07cd268
--- /dev/null
+++ b/arch/arm/dts/sun8i-q8-common.dtsi
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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 file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "sunxi-q8-common.dtsi"
+
+/ {
+	aliases {
+		serial0 = &r_uart;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_q8>;
+	vmmc-supply = <&reg_vcc3v0>;
+	bus-width = <4>;
+	cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */
+	cd-inverted;
+	status = "okay";
+};
+
+&pio {
+	bl_en_pin_q8: bl_en_pin@0 {
+		allwinner,pins = "PH6";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
+	mmc0_cd_pin_q8: mmc0_cd_pin@0 {
+		allwinner,pins = "PB4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+};
+
+&r_uart {
+	pinctrl-names = "default";
+	pinctrl-0 = <&r_uart_pins_a>;
+	status = "okay";
+};
diff --git a/arch/arm/include/asm/arch-lpc32xx/emc.h b/arch/arm/include/asm/arch-lpc32xx/emc.h
index 1a2bab2..f70faf8 100644
--- a/arch/arm/include/asm/arch-lpc32xx/emc.h
+++ b/arch/arm/include/asm/arch-lpc32xx/emc.h
@@ -70,7 +70,7 @@
 
 /* Static Memory Delay Registers */
 #define EMC_STAT_WAITWEN(n)		(((n) - 1) & 0x0F)
-#define EMC_STAT_WAITOEN(n)		(((n) - 1) & 0x0F)
+#define EMC_STAT_WAITOEN(n)		((n) & 0x0F)
 #define EMC_STAT_WAITRD(n)		(((n) - 1) & 0x1F)
 #define EMC_STAT_WAITPAGE(n)		(((n) - 1) & 0x1F)
 #define EMC_STAT_WAITWR(n)		(((n) - 2) & 0x1F)
diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
index acbec46..a129dd4 100644
--- a/arch/arm/include/asm/arch-sunxi/spl.h
+++ b/arch/arm/include/asm/arch-sunxi/spl.h
@@ -1,20 +1,50 @@
 /*
- * This is a copy of omap3/spl.h:
- *
- * (C) Copyright 2012
- * Texas Instruments, <www.ti.com>
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
 #ifndef	_ASM_ARCH_SPL_H_
 #define	_ASM_ARCH_SPL_H_
 
-#define BOOT_DEVICE_NONE	0
-#define BOOT_DEVICE_XIP		1
-#define BOOT_DEVICE_NAND	2
-#define BOOT_DEVICE_ONE_NAND	3
-#define BOOT_DEVICE_MMC2	5 /*emmc*/
-#define BOOT_DEVICE_MMC1	6
-#define BOOT_DEVICE_XIPWAIT	7
-#define BOOT_DEVICE_MMC2_2      0xff
+#define BOOT0_MAGIC		"eGON.BT0"
+#define SPL_SIGNATURE		"SPL" /* marks "sunxi" SPL header */
+#define SPL_HEADER_VERSION	1
+
+/* Note: A80 will require special handling here: SPL_ADDR 0x10000 */
+#define SPL_ADDR		0x0
+
+/* boot head definition from sun4i boot code */
+struct boot_file_head {
+	uint32_t b_instruction;	/* one intruction jumping to real code */
+	uint8_t magic[8];	/* ="eGON.BT0" or "eGON.BT1", not C-style str */
+	uint32_t check_sum;	/* generated by PC */
+	uint32_t length;	/* generated by PC */
+	/*
+	 * We use a simplified header, only filling in what is needed
+	 * by the boot ROM. To be compatible with Allwinner tools we
+	 * would need to implement the proper fields here instead of
+	 * padding.
+	 *
+	 * Actually we want the ability to recognize our "sunxi" variant
+	 * of the SPL. To do so, let's place a special signature into the
+	 * "pub_head_size" field. We can reasonably expect Allwinner's
+	 * boot0 to always have the upper 16 bits of this set to 0 (after
+	 * all the value shouldn't be larger than the limit imposed by
+	 * SRAM size).
+	 * If the signature is present (at 0x14), then we know it's safe
+	 * to use the remaining 8 bytes (at 0x18) for our own purposes.
+	 * (E.g. sunxi-tools "fel" utility can pass information there.)
+	 */
+	union {
+		uint32_t pub_head_size;
+		uint8_t spl_signature[4];
+	};
+	uint32_t fel_script_address;
+	uint32_t reserved;		/* padding, align to 32 bytes */
+};
+
+#define is_boot0_magic(addr)	(memcmp((void *)addr, BOOT0_MAGIC, 8) == 0)
+
 #endif
diff --git a/arch/arm/mach-exynos/clock.c b/arch/arm/mach-exynos/clock.c
index 1c6baa1..18eadf5 100644
--- a/arch/arm/mach-exynos/clock.c
+++ b/arch/arm/mach-exynos/clock.c
@@ -1661,6 +1661,9 @@
 {
 	enum periph_id id;
 
+	if (cpu_is_exynos4())
+		return exynos4_get_mmc_clk(dev_index);
+
 	switch (dev_index) {
 	case 0:
 		id = PERIPH_ID_SDMMC0;
@@ -1679,12 +1682,7 @@
 		return -1;
 	}
 
-	if (cpu_is_exynos5())
-		return clock_get_periph_rate(id);
-	else if (cpu_is_exynos4())
-		return exynos4_get_mmc_clk(dev_index);
-
-	return 0;
+	return clock_get_periph_rate(id);
 }
 
 void set_mmc_clk(int dev_index, unsigned int div)
diff --git a/arch/arm/mach-mvebu/cpu.c b/arch/arm/mach-mvebu/cpu.c
index ea83e21..efd4d04 100644
--- a/arch/arm/mach-mvebu/cpu.c
+++ b/arch/arm/mach-mvebu/cpu.c
@@ -214,32 +214,40 @@
 
 int arch_cpu_init(void)
 {
-#ifndef CONFIG_SPL_BUILD
-	if (mvebu_soc_family() == MVEBU_SOC_A38X) {
-		struct pl310_regs *const pl310 =
-			(struct pl310_regs *)CONFIG_SYS_PL310_BASE;
-
-		/*
-		 * Only with disabled MMU its possible to switch the base
-		 * register address on Armada 38x. Without this the SDRAM
-		 * located at >= 0x4000.0000 is also not accessible, as its
-		 * still locked to cache.
-		 *
-		 * So to fully release / unlock this area from cache, we need
-		 * to first flush all caches, then disable the MMU and
-		 * disable the L2 cache.
-		 */
-		icache_disable();
-		dcache_disable();
-		mmu_disable();
-		clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
-	}
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_ARMADA_38X)
+	/*
+	 * Only with disabled MMU its possible to switch the base
+	 * register address on Armada 38x. Without this the SDRAM
+	 * located at >= 0x4000.0000 is also not accessible, as its
+	 * still locked to cache.
+	 */
+	mmu_disable();
 #endif
 
 	/* Linux expects the internal registers to be at 0xf1000000 */
 	writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG);
 	set_cbar(SOC_REGS_PHY_BASE + 0xC000);
 
+#if !defined(CONFIG_SPL_BUILD)
+	/*
+	 * From this stage on, the SoC detection is working. As we have
+	 * configured the internal register base to the value used
+	 * in the macros / defines in the U-Boot header (soc.h).
+	 */
+	if (mvebu_soc_family() == MVEBU_SOC_A38X) {
+		struct pl310_regs *const pl310 =
+			(struct pl310_regs *)CONFIG_SYS_PL310_BASE;
+
+		/*
+		 * To fully release / unlock this area from cache, we need
+		 * to flush all caches and disable the L2 cache.
+		 */
+		icache_disable();
+		dcache_disable();
+		clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
+	}
+#endif
+
 	/*
 	 * We need to call mvebu_mbus_probe() before calling
 	 * update_sdram_window_sizes() as it disables all previously
diff --git a/arch/arm/mach-mvebu/timer.c b/arch/arm/mach-mvebu/timer.c
index c516c41..5449a89 100644
--- a/arch/arm/mach-mvebu/timer.c
+++ b/arch/arm/mach-mvebu/timer.c
@@ -41,7 +41,7 @@
 #define timestamp			gd->arch.tbl
 #define lastdec				gd->arch.lastinc
 
-static int init_done;
+static int init_done __attribute__((section(".data"))) = 0;
 
 /* Timer reload and current value registers */
 struct kwtmr_val {
diff --git a/arch/arm/mach-rockchip/board-spl.c b/arch/arm/mach-rockchip/board-spl.c
index a241d96..28c3949 100644
--- a/arch/arm/mach-rockchip/board-spl.c
+++ b/arch/arm/mach-rockchip/board-spl.c
@@ -217,6 +217,13 @@
 		debug("DRAM init failed: %d\n", ret);
 		return;
 	}
+
+	/*
+	 * Now that DRAM is initialized setup base pointer for simple malloc
+	 * into RAM.
+	 */
+	gd->malloc_base = CONFIG_SPL_STACK_R_ADDR;
+	gd->malloc_ptr = 0;
 }
 
 static int setup_led(void)
diff --git a/arch/powerpc/cpu/ppc4xx/Kconfig b/arch/powerpc/cpu/ppc4xx/Kconfig
index 23ecc89..ce58d86 100644
--- a/arch/powerpc/cpu/ppc4xx/Kconfig
+++ b/arch/powerpc/cpu/ppc4xx/Kconfig
@@ -8,6 +8,9 @@
 	prompt "Target select"
 	optional
 
+config TARGET_LWMON5
+	bool "Support lwmon5"
+
 config TARGET_T3CORP
 	bool "Support t3corp"
 
@@ -165,6 +168,7 @@
 source "board/gdsys/dlvision/Kconfig"
 source "board/gdsys/gdppc440etx/Kconfig"
 source "board/gdsys/intip/Kconfig"
+source "board/lwmon5/Kconfig"
 source "board/mosaixtech/icon/Kconfig"
 source "board/mpl/mip405/Kconfig"
 source "board/mpl/pip405/Kconfig"
diff --git a/arch/powerpc/include/asm/global_data.h b/arch/powerpc/include/asm/global_data.h
index 2527ef8..4090975 100644
--- a/arch/powerpc/include/asm/global_data.h
+++ b/arch/powerpc/include/asm/global_data.h
@@ -106,6 +106,12 @@
 #ifdef CONFIG_SYS_FPGA_COUNT
 	unsigned fpga_state[CONFIG_SYS_FPGA_COUNT];
 #endif
+#if defined(CONFIG_WD_MAX_RATE)
+	unsigned long long wdt_last;	/* trace watch-dog triggering rate */
+#endif
+#if defined(CONFIG_LWMON5)
+	unsigned long kbd_status;
+#endif
 };
 
 #include <asm-generic/global_data.h>
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index 65b9125..08f72ac 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -153,6 +153,10 @@
 		};
 	};
 
+	reset@1 {
+		compatible = "sandbox,reset";
+	};
+
 	spi@0 {
 		#address-cells = <1>;
 		#size-cells = <0>;
diff --git a/arch/x86/lib/fsp/fsp_dram.c b/arch/x86/lib/fsp/fsp_dram.c
index 28552fa..e51ca96 100644
--- a/arch/x86/lib/fsp/fsp_dram.c
+++ b/arch/x86/lib/fsp/fsp_dram.c
@@ -72,9 +72,10 @@
 				entries[num_entries].type = E820_RAM;
 			else if (res_desc->type == RES_MEM_RESERVED)
 				entries[num_entries].type = E820_RESERVED;
+
+			num_entries++;
 		}
 		hdr = get_next_hob(hdr);
-		num_entries++;
 	}
 
 	/* Mark PCIe ECAM address range as reserved */
diff --git a/board/armltd/vexpress64/Kconfig b/board/armltd/vexpress64/Kconfig
index f5693ae..e05f353 100644
--- a/board/armltd/vexpress64/Kconfig
+++ b/board/armltd/vexpress64/Kconfig
@@ -1,17 +1,4 @@
-if TARGET_VEXPRESS64_BASE_FVP
-
-config SYS_BOARD
-	default "vexpress64"
-
-config SYS_VENDOR
-	default "armltd"
-
-config SYS_CONFIG_NAME
-	default "vexpress_aemv8a"
-
-endif
-
-if TARGET_VEXPRESS64_JUNO
+if TARGET_VEXPRESS64_BASE_FVP || TARGET_VEXPRESS64_JUNO || TARGET_VEXPRESS64_BASE_FVP_DRAM
 
 config SYS_BOARD
 	default "vexpress64"
diff --git a/board/armltd/vexpress64/MAINTAINERS b/board/armltd/vexpress64/MAINTAINERS
index 0ba044d..15b0a08 100644
--- a/board/armltd/vexpress64/MAINTAINERS
+++ b/board/armltd/vexpress64/MAINTAINERS
@@ -10,6 +10,11 @@
 S:	Maintained
 F:	configs/vexpress_aemv8a_semi_defconfig
 
+VEXPRESS_AEMV8A_DRAM BOARD
+M:	Ryan Harkin <ryan.harkin@linaro.org>
+S:	Maintained
+F:	configs/vexpress_aemv8a_dram_defconfig
+
 JUNO DEVELOPMENT PLATFORM BOARD
 M:	Linus Walleij <linus.walleij@linaro.org>
 S:	Maintained
diff --git a/board/lwmon5/Kconfig b/board/lwmon5/Kconfig
new file mode 100644
index 0000000..7b8c605
--- /dev/null
+++ b/board/lwmon5/Kconfig
@@ -0,0 +1,13 @@
+if TARGET_LWMON5
+
+config SYS_BOARD
+	default "lwmon5"
+
+config SYS_CONFIG_NAME
+	default "lwmon5"
+
+config DISPLAY_BOARDINFO
+	bool
+	default y
+
+endif
diff --git a/board/lwmon5/MAINTAINERS b/board/lwmon5/MAINTAINERS
new file mode 100644
index 0000000..3ea1888
--- /dev/null
+++ b/board/lwmon5/MAINTAINERS
@@ -0,0 +1,6 @@
+LWMON5 BOARD
+M:	Stefan Roese <sr@denx.de>
+S:	Maintained
+F:	board/lwmon5/
+F:	include/configs/lwmon5.h
+F:	configs/lwmon5_defconfig
diff --git a/board/lwmon5/Makefile b/board/lwmon5/Makefile
new file mode 100644
index 0000000..02478ca
--- /dev/null
+++ b/board/lwmon5/Makefile
@@ -0,0 +1,9 @@
+#
+# (C) Copyright 2002-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	= lwmon5.o kbd.o sdram.o
+extra-y	+= init.o
diff --git a/board/lwmon5/config.mk b/board/lwmon5/config.mk
new file mode 100644
index 0000000..d0348e8
--- /dev/null
+++ b/board/lwmon5/config.mk
@@ -0,0 +1,18 @@
+#
+# (C) Copyright 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+# lwmon5 (440EPx)
+#
+
+PLATFORM_CPPFLAGS += -DCONFIG_440=1
+
+ifeq ($(debug),1)
+PLATFORM_CPPFLAGS += -DDEBUG
+endif
+
+ifeq ($(dbcr),1)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_INIT_DBCR=0x8cff0000
+endif
diff --git a/board/lwmon5/init.S b/board/lwmon5/init.S
new file mode 100644
index 0000000..e5207c2
--- /dev/null
+++ b/board/lwmon5/init.S
@@ -0,0 +1,75 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ *  Copyright (C) 2002 Scott McNutt <smcnutt@artesyncp.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <ppc_asm.tmpl>
+#include <config.h>
+#include <asm/mmu.h>
+
+/**************************************************************************
+ * TLB TABLE
+ *
+ * This table is used by the cpu boot code to setup the initial tlb
+ * entries. Rather than make broad assumptions in the cpu source tree,
+ * this table lets each board set things up however they like.
+ *
+ *  Pointer to the table is returned in r1
+ *
+ *************************************************************************/
+	.section .bootpg,"ax"
+	.globl tlbtab
+
+tlbtab:
+	tlbtab_start
+
+	/*
+	 * BOOT_CS (FLASH) must be first. Before relocation SA_I can be off to use the
+	 * speed up boot process. It is patched after relocation to enable SA_I
+	 */
+	tlbentry(CONFIG_SYS_BOOT_BASE_ADDR, SZ_256M, CONFIG_SYS_BOOT_BASE_ADDR, 1, AC_RWX | SA_G)
+
+	/*
+	 * TLB entries for SDRAM are not needed on this platform.
+	 * They are dynamically generated in the SPD DDR(2) detection
+	 * routine.
+	 */
+
+#ifdef CONFIG_SYS_INIT_RAM_DCACHE
+	/* TLB-entry for init-ram in dcache (SA_I must be turned off!) */
+	tlbentry(CONFIG_SYS_INIT_RAM_ADDR, SZ_4K, CONFIG_SYS_INIT_RAM_ADDR, 0, AC_RWX | SA_G)
+#endif
+
+	/* TLB-entry for PCI Memory */
+	tlbentry(CONFIG_SYS_PCI_MEMBASE, SZ_256M, CONFIG_SYS_PCI_MEMBASE, 1, AC_RW | SA_IG)
+	tlbentry(CONFIG_SYS_PCI_MEMBASE1, SZ_256M, CONFIG_SYS_PCI_MEMBASE1, 1, AC_RW | SA_IG)
+	tlbentry(CONFIG_SYS_PCI_MEMBASE2, SZ_256M, CONFIG_SYS_PCI_MEMBASE2, 1, AC_RW | SA_IG)
+	tlbentry(CONFIG_SYS_PCI_MEMBASE3, SZ_256M, CONFIG_SYS_PCI_MEMBASE3, 1, AC_RW | SA_IG)
+
+	/* TLB-entry for the FPGA Chip select 2 */
+	tlbentry(CONFIG_SYS_FPGA_BASE_0, SZ_1M, CONFIG_SYS_FPGA_BASE_0, 1, AC_RWX | SA_I|SA_G)
+
+	/* TLB-entry for the FPGA Chip select 3 */
+	tlbentry(CONFIG_SYS_FPGA_BASE_1, SZ_1M, CONFIG_SYS_FPGA_BASE_1, 1,AC_RWX | SA_I|SA_G)
+
+	/* TLB-entry for the LIME Controller */
+	tlbentry(CONFIG_SYS_LIME_BASE_0, SZ_16M, CONFIG_SYS_LIME_BASE_0, 1, AC_RWX | SA_I|SA_G)
+	tlbentry(CONFIG_SYS_LIME_BASE_1, SZ_16M, CONFIG_SYS_LIME_BASE_1, 1, AC_RWX | SA_I|SA_G)
+	tlbentry(CONFIG_SYS_LIME_BASE_2, SZ_16M, CONFIG_SYS_LIME_BASE_2, 1, AC_RWX | SA_I|SA_G)
+	tlbentry(CONFIG_SYS_LIME_BASE_3, SZ_16M, CONFIG_SYS_LIME_BASE_3, 1, AC_RWX | SA_I|SA_G)
+
+	/* TLB-entry for Internal Registers & OCM */
+	tlbentry(0xe0000000, SZ_16M, 0xe0000000, 0,  AC_RWX | SA_I)
+
+	/*TLB-entry PCI registers*/
+	tlbentry(0xEEC00000, SZ_1K, 0xEEC00000, 1,  AC_RWX | SA_IG)
+
+	/* TLB-entry for peripherals */
+	tlbentry(0xEF000000, SZ_16M, 0xEF000000, 1, AC_RWX | SA_IG)
+
+	tlbtab_end
diff --git a/board/lwmon5/kbd.c b/board/lwmon5/kbd.c
new file mode 100644
index 0000000..97962da
--- /dev/null
+++ b/board/lwmon5/kbd.c
@@ -0,0 +1,490 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * (C) Copyright 2001, 2002
+ * DENX Software Engineering
+ * Wolfgang Denk, wd@denx.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/* define DEBUG for debugging output (obviously ;-)) */
+#if 0
+#define DEBUG
+#endif
+
+#include <common.h>
+#include <i2c.h>
+#include <command.h>
+#include <post.h>
+#include <serial.h>
+#include <malloc.h>
+
+#include <linux/types.h>
+#include <linux/string.h>	/* for strdup */
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void kbd_init (void);
+static int compare_magic (uchar *kbd_data, uchar *str);
+
+/*--------------------- Local macros and constants --------------------*/
+#define	_NOT_USED_	0xFFFFFFFF
+
+/*------------------------- dspic io expander -----------------------*/
+#define DSPIC_PON_STATUS_REG	0x80A
+#define DSPIC_PON_INV_STATUS_REG 0x80C
+#define DSPIC_PON_KEY_REG	0x810
+/*------------------------- Keyboard controller -----------------------*/
+/* command codes */
+#define	KEYBD_CMD_READ_KEYS	0x01
+#define KEYBD_CMD_READ_VERSION	0x02
+#define KEYBD_CMD_READ_STATUS	0x03
+#define KEYBD_CMD_RESET_ERRORS	0x10
+
+/* status codes */
+#define KEYBD_STATUS_MASK	0x3F
+#define	KEYBD_STATUS_H_RESET	0x20
+#define KEYBD_STATUS_BROWNOUT	0x10
+#define KEYBD_STATUS_WD_RESET	0x08
+#define KEYBD_STATUS_OVERLOAD	0x04
+#define KEYBD_STATUS_ILLEGAL_WR	0x02
+#define KEYBD_STATUS_ILLEGAL_RD	0x01
+
+/* Number of bytes returned from Keyboard Controller */
+#define KEYBD_VERSIONLEN	2	/* version information */
+
+/*
+ * This is different from the "old" lwmon dsPIC kbd controller
+ * implementation. Now the controller still answers with 9 bytes,
+ * but the last 3 bytes are always "0x06 0x07 0x08". So we just
+ * set the length to compare to 6 instead of 9.
+ */
+#define	KEYBD_DATALEN		6	/* normal key scan data */
+
+/* maximum number of "magic" key codes that can be assigned */
+
+static uchar kbd_addr = CONFIG_SYS_I2C_KEYBD_ADDR;
+static uchar dspic_addr = CONFIG_SYS_I2C_DSPIC_IO_ADDR;
+
+static uchar *key_match (uchar *);
+
+#define	KEYBD_SET_DEBUGMODE	'#'	/* Magic key to enable debug output */
+
+/***********************************************************************
+F* Function:     int board_postclk_init (void) P*A*Z*
+ *
+P* Parameters:   none
+P*
+P* Returnvalue:  int
+P*                - 0 is always returned.
+ *
+Z* Intention:    This function is the board_postclk_init() method implementation
+Z*               for the lwmon board.
+ *
+ ***********************************************************************/
+int board_postclk_init (void)
+{
+	kbd_init();
+
+	return (0);
+}
+
+static void kbd_init (void)
+{
+	uchar kbd_data[KEYBD_DATALEN];
+	uchar tmp_data[KEYBD_DATALEN];
+	uchar val, errcd;
+	int i;
+
+	i2c_set_bus_num(0);
+
+	gd->arch.kbd_status = 0;
+
+	/* Forced by PIC. Delays <= 175us loose */
+	udelay(1000);
+
+	/* Read initial keyboard error code */
+	val = KEYBD_CMD_READ_STATUS;
+	i2c_write (kbd_addr, 0, 0, &val, 1);
+	i2c_read (kbd_addr, 0, 0, &errcd, 1);
+	/* clear unused bits */
+	errcd &= KEYBD_STATUS_MASK;
+	/* clear "irrelevant" bits. Recommended by Martin Rajek, LWN */
+	errcd &= ~(KEYBD_STATUS_H_RESET|KEYBD_STATUS_BROWNOUT);
+	if (errcd) {
+		gd->arch.kbd_status |= errcd << 8;
+	}
+	/* Reset error code and verify */
+	val = KEYBD_CMD_RESET_ERRORS;
+	i2c_write (kbd_addr, 0, 0, &val, 1);
+	udelay(1000);	/* delay NEEDED by keyboard PIC !!! */
+
+	val = KEYBD_CMD_READ_STATUS;
+	i2c_write (kbd_addr, 0, 0, &val, 1);
+	i2c_read (kbd_addr, 0, 0, &val, 1);
+
+	val &= KEYBD_STATUS_MASK;	/* clear unused bits */
+	if (val) {			/* permanent error, report it */
+		gd->arch.kbd_status |= val;
+		return;
+	}
+
+	/*
+	 * Read current keyboard state.
+	 *
+	 * After the error reset it may take some time before the
+	 * keyboard PIC picks up a valid keyboard scan - the total
+	 * scan time is approx. 1.6 ms (information by Martin Rajek,
+	 * 28 Sep 2002). We read a couple of times for the keyboard
+	 * to stabilize, using a big enough delay.
+	 * 10 times should be enough. If the data is still changing,
+	 * we use what we get :-(
+	 */
+
+	memset (tmp_data, 0xFF, KEYBD_DATALEN);	/* impossible value */
+	for (i=0; i<10; ++i) {
+		val = KEYBD_CMD_READ_KEYS;
+		i2c_write (kbd_addr, 0, 0, &val, 1);
+		i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
+
+		if (memcmp(kbd_data, tmp_data, KEYBD_DATALEN) == 0) {
+			/* consistent state, done */
+			break;
+		}
+		/* remeber last state, delay, and retry */
+		memcpy (tmp_data, kbd_data, KEYBD_DATALEN);
+		udelay (5000);
+	}
+}
+
+
+/* Read a register from the dsPIC. */
+int _dspic_read(ushort reg, ushort *data)
+{
+	uchar buf[sizeof(*data)];
+	int rval;
+
+	if (i2c_read(dspic_addr, reg, 2, buf, 2))
+		return -1;
+
+	rval = i2c_read(dspic_addr, reg, sizeof(reg), buf, sizeof(*data));
+	*data = (buf[0] << 8) | buf[1];
+
+	return rval;
+}
+
+
+/***********************************************************************
+F* Function:     int misc_init_r (void) P*A*Z*
+ *
+P* Parameters:   none
+P*
+P* Returnvalue:  int
+P*                - 0 is always returned, even in the case of a keyboard
+P*                    error.
+ *
+Z* Intention:    This function is the misc_init_r() method implementation
+Z*               for the lwmon board.
+Z*               The keyboard controller is initialized and the result
+Z*               of a read copied to the environment variable "keybd".
+Z*               If KEYBD_SET_DEBUGMODE is defined, a check is made for
+Z*               this key, and if found display to the LCD will be enabled.
+Z*               The keys in "keybd" are checked against the magic
+Z*               keycommands defined in the environment.
+Z*               See also key_match().
+ *
+D* Design:       wd@denx.de
+C* Coding:       wd@denx.de
+V* Verification: dzu@denx.de
+ ***********************************************************************/
+int misc_init_r_kbd (void)
+{
+	uchar kbd_data[KEYBD_DATALEN];
+	char keybd_env[2 * KEYBD_DATALEN + 1];
+	uchar kbd_init_status = gd->arch.kbd_status >> 8;
+	uchar kbd_status = gd->arch.kbd_status;
+	uchar val;
+	ushort data, inv_data;
+	char *str;
+	int i;
+
+	if (kbd_init_status) {
+		printf ("KEYBD: Error %02X\n", kbd_init_status);
+	}
+	if (kbd_status) {		/* permanent error, report it */
+		printf ("*** Keyboard error code %02X ***\n", kbd_status);
+		sprintf (keybd_env, "%02X", kbd_status);
+		setenv ("keybd", keybd_env);
+		return 0;
+	}
+
+	/*
+	 * Now we know that we have a working  keyboard,  so  disable
+	 * all output to the LCD except when a key press is detected.
+	 */
+
+	if ((console_assign (stdout, "serial") < 0) ||
+		(console_assign (stderr, "serial") < 0)) {
+		printf ("Can't assign serial port as output device\n");
+	}
+
+	/* Read Version */
+	val = KEYBD_CMD_READ_VERSION;
+	i2c_write (kbd_addr, 0, 0, &val, 1);
+	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_VERSIONLEN);
+	printf ("KEYBD: Version %d.%d\n", kbd_data[0], kbd_data[1]);
+
+	/* Read current keyboard state */
+	val = KEYBD_CMD_READ_KEYS;
+	i2c_write (kbd_addr, 0, 0, &val, 1);
+	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
+
+	/* read out start key from bse01 received via can */
+	_dspic_read(DSPIC_PON_STATUS_REG, &data);
+	/* check highbyte from status register */
+	if (data > 0xFF) {
+		_dspic_read(DSPIC_PON_INV_STATUS_REG, &inv_data);
+
+		/* check inverse data */
+		if ((data+inv_data) == 0xFFFF) {
+			/* don't overwrite local key */
+			if (kbd_data[1] == 0) {
+				/* read key value */
+				_dspic_read(DSPIC_PON_KEY_REG, &data);
+				str = (char *)&data;
+				/* swap bytes */
+				kbd_data[1] = str[1];
+				kbd_data[2] = str[0];
+				printf("CAN received startkey: 0x%X\n", data);
+			}
+		}
+	}
+
+	for (i = 0; i < KEYBD_DATALEN; ++i) {
+		sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
+	}
+
+	setenv ("keybd", keybd_env);
+
+	str = strdup ((char *)key_match (kbd_data));	/* decode keys */
+#ifdef KEYBD_SET_DEBUGMODE
+	if (kbd_data[0] == KEYBD_SET_DEBUGMODE) {	/* set debug mode */
+		if ((console_assign (stdout, "lcd") < 0) ||
+			(console_assign (stderr, "lcd") < 0)) {
+			printf ("Can't assign LCD display as output device\n");
+		}
+	}
+#endif /* KEYBD_SET_DEBUGMODE */
+#ifdef CONFIG_PREBOOT	/* automatically configure "preboot" command on key match */
+	setenv ("preboot", str);	/* set or delete definition */
+#endif /* CONFIG_PREBOOT */
+	if (str != NULL) {
+		free (str);
+	}
+	return (0);
+}
+
+#ifdef CONFIG_PREBOOT
+
+static uchar kbd_magic_prefix[] = "key_magic";
+static uchar kbd_command_prefix[] = "key_cmd";
+
+static int compare_magic (uchar *kbd_data, uchar *str)
+{
+	uchar compare[KEYBD_DATALEN-1];
+	char *nxt;
+	int i;
+
+	/* Don't include modifier byte */
+	memcpy (compare, kbd_data+1, KEYBD_DATALEN-1);
+
+	for (; str != NULL; str = (*nxt) ? (uchar *)(nxt+1) : (uchar *)nxt) {
+		uchar c;
+		int k;
+
+		c = (uchar) simple_strtoul ((char *)str, (char **) (&nxt), 16);
+
+		if (str == (uchar *)nxt) {	/* invalid character */
+			break;
+		}
+
+		/*
+		 * Check if this key matches the input.
+		 * Set matches to zero, so they match only once
+		 * and we can find duplicates or extra keys
+		 */
+		for (k = 0; k < sizeof(compare); ++k) {
+			if (compare[k] == '\0')	/* only non-zero entries */
+				continue;
+			if (c == compare[k]) {	/* found matching key */
+				compare[k] = '\0';
+				break;
+			}
+		}
+		if (k == sizeof(compare)) {
+			return -1;		/* unmatched key */
+		}
+	}
+
+	/*
+	 * A full match leaves no keys in the `compare' array,
+	 */
+	for (i = 0; i < sizeof(compare); ++i) {
+		if (compare[i])
+		{
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/***********************************************************************
+F* Function:     static uchar *key_match (uchar *kbd_data) P*A*Z*
+ *
+P* Parameters:   uchar *kbd_data
+P*                - The keys to match against our magic definitions
+P*
+P* Returnvalue:  uchar *
+P*                - != NULL: Pointer to the corresponding command(s)
+P*                     NULL: No magic is about to happen
+ *
+Z* Intention:    Check if pressed key(s) match magic sequence,
+Z*               and return the command string associated with that key(s).
+Z*
+Z*               If no key press was decoded, NULL is returned.
+Z*
+Z*               Note: the first character of the argument will be
+Z*                     overwritten with the "magic charcter code" of the
+Z*                     decoded key(s), or '\0'.
+Z*
+Z*               Note: the string points to static environment data
+Z*                     and must be saved before you call any function that
+Z*                     modifies the environment.
+ *
+D* Design:       wd@denx.de
+C* Coding:       wd@denx.de
+V* Verification: dzu@denx.de
+ ***********************************************************************/
+static uchar *key_match (uchar *kbd_data)
+{
+	char magic[sizeof (kbd_magic_prefix) + 1];
+	uchar *suffix;
+	char *kbd_magic_keys;
+
+	/*
+	 * The following string defines the characters that can pe appended
+	 * to "key_magic" to form the names of environment variables that
+	 * hold "magic" key codes, i. e. such key codes that can cause
+	 * pre-boot actions. If the string is empty (""), then only
+	 * "key_magic" is checked (old behaviour); the string "125" causes
+	 * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
+	 */
+	if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
+		kbd_magic_keys = "";
+
+	/* loop over all magic keys;
+	 * use '\0' suffix in case of empty string
+	 */
+	for (suffix=(uchar *)kbd_magic_keys; *suffix || suffix==(uchar *)kbd_magic_keys; ++suffix) {
+		sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
+		debug ("### Check magic \"%s\"\n", magic);
+		if (compare_magic(kbd_data, (uchar *)getenv(magic)) == 0) {
+			char cmd_name[sizeof (kbd_command_prefix) + 1];
+			char *cmd;
+
+			sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
+
+			cmd = getenv (cmd_name);
+			debug ("### Set PREBOOT to $(%s): \"%s\"\n",
+					cmd_name, cmd ? cmd : "<<NULL>>");
+			*kbd_data = *suffix;
+			return ((uchar *)cmd);
+		}
+	}
+	debug ("### Delete PREBOOT\n");
+	*kbd_data = '\0';
+	return (NULL);
+}
+#endif /* CONFIG_PREBOOT */
+
+/***********************************************************************
+F* Function:     int do_kbd (cmd_tbl_t *cmdtp, int flag,
+F*                           int argc, char * const argv[]) P*A*Z*
+ *
+P* Parameters:   cmd_tbl_t *cmdtp
+P*                - Pointer to our command table entry
+P*               int flag
+P*                - If the CMD_FLAG_REPEAT bit is set, then this call is
+P*                  a repetition
+P*               int argc
+P*                - Argument count
+P*               char * const argv[]
+P*                - Array of the actual arguments
+P*
+P* Returnvalue:  int
+P*                - 0 is always returned.
+ *
+Z* Intention:    Implement the "kbd" command.
+Z*               The keyboard status is read.  The result is printed on
+Z*               the console and written into the "keybd" environment
+Z*               variable.
+ *
+D* Design:       wd@denx.de
+C* Coding:       wd@denx.de
+V* Verification: dzu@denx.de
+ ***********************************************************************/
+int do_kbd (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	uchar kbd_data[KEYBD_DATALEN];
+	char keybd_env[2 * KEYBD_DATALEN + 1];
+	uchar val;
+	int i;
+
+#if 0 /* Done in kbd_init */
+	i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
+
+	/* Read keys */
+	val = KEYBD_CMD_READ_KEYS;
+	i2c_write (kbd_addr, 0, 0, &val, 1);
+	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
+
+	puts ("Keys:");
+	for (i = 0; i < KEYBD_DATALEN; ++i) {
+		sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
+		printf (" %02x", kbd_data[i]);
+	}
+	putc ('\n');
+	setenv ("keybd", keybd_env);
+	return 0;
+}
+
+U_BOOT_CMD(
+	kbd,	1,	1,	do_kbd,
+	"read keyboard status",
+	""
+);
+
+/*----------------------------- Utilities -----------------------------*/
+
+#ifdef CONFIG_POST
+/*
+ * Returns 1 if keys pressed to start the power-on long-running tests
+ * Called from board_init_f().
+ */
+int post_hotkeys_pressed(void)
+{
+	uchar kbd_data[KEYBD_DATALEN];
+	uchar val;
+
+	/* Read keys */
+	val = KEYBD_CMD_READ_KEYS;
+	i2c_write (kbd_addr, 0, 0, &val, 1);
+	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
+
+	return (compare_magic(kbd_data, (uchar *)CONFIG_POST_KEY_MAGIC) == 0);
+}
+#endif
diff --git a/board/lwmon5/lwmon5.c b/board/lwmon5/lwmon5.c
new file mode 100644
index 0000000..8ad6712
--- /dev/null
+++ b/board/lwmon5/lwmon5.c
@@ -0,0 +1,550 @@
+/*
+ * (C) Copyright 2007-2013
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/ppc440.h>
+#include <asm/processor.h>
+#include <asm/ppc4xx-gpio.h>
+#include <asm/io.h>
+#include <post.h>
+#include <flash.h>
+#include <mtd/cfi_flash.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static phys_addr_t lwmon5_cfi_flash_bank_addr[2] = CONFIG_SYS_FLASH_BANKS_LIST;
+
+ulong flash_get_size(ulong base, int banknum);
+int misc_init_r_kbd(void);
+
+int board_early_init_f(void)
+{
+	u32 sdr0_pfc1, sdr0_pfc2;
+	u32 reg;
+
+	/* PLB Write pipelining disabled. Denali Core workaround */
+	mtdcr(PLB4A0_ACR, 0xDE000000);
+	mtdcr(PLB4A1_ACR, 0xDE000000);
+
+	/*--------------------------------------------------------------------
+	 * Setup the interrupt controller polarities, triggers, etc.
+	 *-------------------------------------------------------------------*/
+	mtdcr(UIC0SR, 0xffffffff);  /* clear all. if write with 1 then the status is cleared  */
+	mtdcr(UIC0ER, 0x00000000);  /* disable all */
+	mtdcr(UIC0CR, 0x00000000);  /* we have not critical interrupts at the moment */
+	mtdcr(UIC0PR, 0xFFBFF1EF);  /* Adjustment of the polarity */
+	mtdcr(UIC0TR, 0x00000900);  /* per ref-board manual */
+	mtdcr(UIC0VR, 0x00000000);  /* int31 highest, base=0x000 is within DDRAM */
+	mtdcr(UIC0SR, 0xffffffff);  /* clear all */
+
+	mtdcr(UIC1SR, 0xffffffff);  /* clear all */
+	mtdcr(UIC1ER, 0x00000000);  /* disable all */
+	mtdcr(UIC1CR, 0x00000000);  /* all non-critical */
+	mtdcr(UIC1PR, 0xFFFFC6A5);  /* Adjustment of the polarity */
+	mtdcr(UIC1TR, 0x60000040);  /* per ref-board manual */
+	mtdcr(UIC1VR, 0x00000000);  /* int31 highest, base=0x000 is within DDRAM */
+	mtdcr(UIC1SR, 0xffffffff);  /* clear all */
+
+	mtdcr(UIC2SR, 0xffffffff);  /* clear all */
+	mtdcr(UIC2ER, 0x00000000);  /* disable all */
+	mtdcr(UIC2CR, 0x00000000);  /* all non-critical */
+	mtdcr(UIC2PR, 0x27C00000);  /* Adjustment of the polarity */
+	mtdcr(UIC2TR, 0x3C000000);  /* per ref-board manual */
+	mtdcr(UIC2VR, 0x00000000);  /* int31 highest, base=0x000 is within DDRAM */
+	mtdcr(UIC2SR, 0xffffffff);  /* clear all */
+
+	/* Trace Pins are disabled. SDR0_PFC0 Register */
+	mtsdr(SDR0_PFC0, 0x0);
+
+	/* select Ethernet pins */
+	mfsdr(SDR0_PFC1, sdr0_pfc1);
+	/* SMII via ZMII */
+	sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_SELECT_MASK) |
+		SDR0_PFC1_SELECT_CONFIG_6;
+	mfsdr(SDR0_PFC2, sdr0_pfc2);
+	sdr0_pfc2 = (sdr0_pfc2 & ~SDR0_PFC2_SELECT_MASK) |
+		SDR0_PFC2_SELECT_CONFIG_6;
+
+	/* enable SPI (SCP) */
+	sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_SIS_MASK) | SDR0_PFC1_SIS_SCP_SEL;
+
+	mtsdr(SDR0_PFC2, sdr0_pfc2);
+	mtsdr(SDR0_PFC1, sdr0_pfc1);
+
+	mtsdr(SDR0_PFC4, 0x80000000);
+
+	/* PCI arbiter disabled */
+	/* PCI Host Configuration disbaled */
+	mfsdr(SDR0_PCI0, reg);
+	reg = 0;
+	mtsdr(SDR0_PCI0, 0x00000000 | reg);
+
+	gpio_write_bit(CONFIG_SYS_GPIO_FLASH_WP, 1);
+
+#if CONFIG_POST & CONFIG_SYS_POST_BSPEC1
+	/* enable the LSB transmitter */
+	gpio_write_bit(CONFIG_SYS_GPIO_LSB_ENABLE, 1);
+	/* enable the CAN transmitter */
+	gpio_write_bit(CONFIG_SYS_GPIO_CAN_ENABLE, 1);
+
+	reg = 0; /* reuse as counter */
+	out_be32((void *)CONFIG_SYS_DSPIC_TEST_ADDR,
+		in_be32((void *)CONFIG_SYS_DSPIC_TEST_ADDR)
+			& ~CONFIG_SYS_DSPIC_TEST_MASK);
+	while (gpio_read_in_bit(CONFIG_SYS_GPIO_DSPIC_READY) && reg++ < 1000) {
+		udelay(1000);
+	}
+	if (gpio_read_in_bit(CONFIG_SYS_GPIO_DSPIC_READY)) {
+		/* set "boot error" flag */
+		out_be32((void *)CONFIG_SYS_DSPIC_TEST_ADDR,
+			in_be32((void *)CONFIG_SYS_DSPIC_TEST_ADDR) |
+			CONFIG_SYS_DSPIC_TEST_MASK);
+	}
+#endif
+
+	/*
+	 * Reset PHY's:
+	 * The PHY's need a 2nd reset pulse, since the MDIO address is latched
+	 * upon reset, and with the first reset upon powerup, the addresses are
+	 * not latched reliable, since the IRQ line is multiplexed with an
+	 * MDIO address. A 2nd reset at this time will make sure, that the
+	 * correct address is latched.
+	 */
+	gpio_write_bit(CONFIG_SYS_GPIO_PHY0_RST, 1);
+	gpio_write_bit(CONFIG_SYS_GPIO_PHY1_RST, 1);
+	udelay(1000);
+	gpio_write_bit(CONFIG_SYS_GPIO_PHY0_RST, 0);
+	gpio_write_bit(CONFIG_SYS_GPIO_PHY1_RST, 0);
+	udelay(1000);
+	gpio_write_bit(CONFIG_SYS_GPIO_PHY0_RST, 1);
+	gpio_write_bit(CONFIG_SYS_GPIO_PHY1_RST, 1);
+
+	return 0;
+}
+
+/*
+ * Override weak default with board specific version
+ */
+phys_addr_t cfi_flash_bank_addr(int bank)
+{
+	return lwmon5_cfi_flash_bank_addr[bank];
+}
+
+/*
+ * Override the weak default mapping function with a board specific one
+ */
+u32 flash_get_bank_size(int cs, int idx)
+{
+	return flash_info[idx].size;
+}
+
+int board_early_init_r(void)
+{
+	u32 val0, val1;
+
+	/*
+	 * lwmon5 is manufactured in 2 different board versions:
+	 * The lwmon5a board has 64MiB NOR flash instead of the
+	 * 128MiB of the original lwmon5. Unfortunately the CFI driver
+	 * will report 2 banks of 64MiB even for the smaller flash
+	 * chip, since the bank is mirrored. To fix this, we bring
+	 * one bank into CFI query mode and read its response. This
+	 * enables us to detect the real number of flash devices/
+	 * banks which will be used later on by the common CFI driver.
+	 */
+
+	/* Put bank 0 into CFI command mode and read */
+	out_be32((void *)CONFIG_SYS_FLASH0, 0x00980098);
+	val0 = in_be32((void *)CONFIG_SYS_FLASH0 + FLASH_OFFSET_CFI_RESP);
+	val1 = in_be32((void *)CONFIG_SYS_FLASH1 + FLASH_OFFSET_CFI_RESP);
+
+	/* Reset flash again out of query mode */
+	out_be32((void *)CONFIG_SYS_FLASH0, 0x00f000f0);
+
+	/* When not identical, we have 2 different flash devices/banks */
+	if (val0 != val1)
+		return 0;
+
+	/*
+	 * Now we're sure that we're running on a LWMON5a board with
+	 * only 64MiB NOR flash in one bank:
+	 *
+	 * Set flash base address and bank count for CFI driver probing.
+	 */
+	cfi_flash_num_flash_banks = 1;
+	lwmon5_cfi_flash_bank_addr[0] = CONFIG_SYS_FLASH0;
+
+	return 0;
+}
+
+int misc_init_r(void)
+{
+	u32 pbcr;
+	int size_val = 0;
+	u32 reg;
+	unsigned long usb2d0cr = 0;
+	unsigned long usb2phy0cr, usb2h0cr = 0;
+	unsigned long sdr0_pfc1, sdr0_srst;
+
+	/*
+	 * FLASH stuff...
+	 */
+
+	/* Re-do sizing to get full correct info */
+
+	/* adjust flash start and offset */
+	gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize;
+	gd->bd->bi_flashoffset = 0;
+
+	mfebc(PB0CR, pbcr);
+	size_val = ffs(gd->bd->bi_flashsize) - 21;
+	pbcr = (pbcr & 0x0001ffff) | gd->bd->bi_flashstart | (size_val << 17);
+	mtebc(PB0CR, pbcr);
+
+	/*
+	 * Re-check to get correct base address
+	 */
+	flash_get_size(gd->bd->bi_flashstart, 0);
+
+	/* Monitor protection ON by default */
+	flash_protect(FLAG_PROTECT_SET, -CONFIG_SYS_MONITOR_LEN, 0xffffffff,
+		      &flash_info[cfi_flash_num_flash_banks - 1]);
+
+	/* Env protection ON by default */
+	flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR_REDUND,
+		      CONFIG_ENV_ADDR_REDUND + 2 * CONFIG_ENV_SECT_SIZE - 1,
+		      &flash_info[cfi_flash_num_flash_banks - 1]);
+
+	/*
+	 * USB suff...
+	 */
+
+	/* Reset USB */
+	/* Reset of USB2PHY0 must be active at least 10 us  */
+	mtsdr(SDR0_SRST0, SDR0_SRST0_USB2H | SDR0_SRST0_USB2D);
+	udelay(2000);
+
+	mtsdr(SDR0_SRST1, SDR0_SRST1_USB20PHY | SDR0_SRST1_USB2HUTMI |
+	      SDR0_SRST1_USB2HPHY | SDR0_SRST1_OPBA2 |
+	      SDR0_SRST1_PLB42OPB1 | SDR0_SRST1_OPB2PLB40);
+	udelay(2000);
+
+	/* Errata CHIP_6 */
+
+	/* 1. Set internal PHY configuration */
+	/* SDR Setting */
+	mfsdr(SDR0_PFC1, sdr0_pfc1);
+	mfsdr(SDR0_USB0, usb2d0cr);
+	mfsdr(SDR0_USB2PHY0CR, usb2phy0cr);
+	mfsdr(SDR0_USB2H0CR, usb2h0cr);
+
+	usb2phy0cr = usb2phy0cr & ~SDR0_USB2PHY0CR_XOCLK_MASK;
+	usb2phy0cr = usb2phy0cr |  SDR0_USB2PHY0CR_XOCLK_EXTERNAL;	/*0*/
+	usb2phy0cr = usb2phy0cr & ~SDR0_USB2PHY0CR_WDINT_MASK;
+	usb2phy0cr = usb2phy0cr |  SDR0_USB2PHY0CR_WDINT_16BIT_30MHZ;	/*1*/
+	usb2phy0cr = usb2phy0cr & ~SDR0_USB2PHY0CR_DVBUS_MASK;
+	usb2phy0cr = usb2phy0cr |  SDR0_USB2PHY0CR_DVBUS_PUREN;		/*1*/
+	usb2phy0cr = usb2phy0cr & ~SDR0_USB2PHY0CR_DWNSTR_MASK;
+	usb2phy0cr = usb2phy0cr |  SDR0_USB2PHY0CR_DWNSTR_HOST;		/*1*/
+	usb2phy0cr = usb2phy0cr & ~SDR0_USB2PHY0CR_UTMICN_MASK;
+	usb2phy0cr = usb2phy0cr |  SDR0_USB2PHY0CR_UTMICN_HOST;		/*1*/
+
+	/*
+	 * An 8-bit/60MHz interface is the only possible alternative
+	 * when connecting the Device to the PHY
+	 */
+	usb2h0cr   = usb2h0cr & ~SDR0_USB2H0CR_WDINT_MASK;
+	usb2h0cr   = usb2h0cr |  SDR0_USB2H0CR_WDINT_16BIT_30MHZ;	/*1*/
+
+	mtsdr(SDR0_PFC1, sdr0_pfc1);
+	mtsdr(SDR0_USB0, usb2d0cr);
+	mtsdr(SDR0_USB2PHY0CR, usb2phy0cr);
+	mtsdr(SDR0_USB2H0CR, usb2h0cr);
+
+	/* 2. De-assert internal PHY reset */
+	mfsdr(SDR0_SRST1, sdr0_srst);
+	sdr0_srst = sdr0_srst & ~SDR0_SRST1_USB20PHY;
+	mtsdr(SDR0_SRST1, sdr0_srst);
+
+	/* 3. Wait for more than 1 ms */
+	udelay(2000);
+
+	/* 4. De-assert USB 2.0 Host main reset */
+	mfsdr(SDR0_SRST0, sdr0_srst);
+	sdr0_srst = sdr0_srst &~ SDR0_SRST0_USB2H;
+	mtsdr(SDR0_SRST0, sdr0_srst);
+	udelay(1000);
+
+	/* 5. De-assert reset of OPB2 cores */
+	mfsdr(SDR0_SRST1, sdr0_srst);
+	sdr0_srst = sdr0_srst &~ SDR0_SRST1_PLB42OPB1;
+	sdr0_srst = sdr0_srst &~ SDR0_SRST1_OPB2PLB40;
+	sdr0_srst = sdr0_srst &~ SDR0_SRST1_OPBA2;
+	mtsdr(SDR0_SRST1, sdr0_srst);
+	udelay(1000);
+
+	/* 6. Set EHCI Configure FLAG */
+
+	/* 7. Reassert internal PHY reset: */
+	mtsdr(SDR0_SRST1, SDR0_SRST1_USB20PHY);
+	udelay(1000);
+
+	/*
+	 * Clear resets
+	 */
+	mtsdr(SDR0_SRST1, 0x00000000);
+	mtsdr(SDR0_SRST0, 0x00000000);
+
+	printf("USB:   Host(int phy) Device(ext phy)\n");
+
+	/*
+	 * Clear PLB4A0_ACR[WRP]
+	 * This fix will make the MAL burst disabling patch for the Linux
+	 * EMAC driver obsolete.
+	 */
+	reg = mfdcr(PLB4A0_ACR) & ~PLB4Ax_ACR_WRP_MASK;
+	mtdcr(PLB4A0_ACR, reg);
+
+	/*
+	 * Init matrix keyboard
+	 */
+	misc_init_r_kbd();
+
+	return 0;
+}
+
+int checkboard(void)
+{
+	char buf[64];
+	int i = getenv_f("serial#", buf, sizeof(buf));
+
+	printf("Board: %s", __stringify(CONFIG_HOSTNAME));
+
+	if (i > 0) {
+		puts(", serial# ");
+		puts(buf);
+	}
+	putc('\n');
+
+	return (0);
+}
+
+void hw_watchdog_reset(void)
+{
+	int val;
+#if defined(CONFIG_WD_MAX_RATE)
+	unsigned long long ct = get_ticks();
+
+	/*
+	 * Don't allow watch-dog triggering more frequently than
+	 * the predefined value CONFIG_WD_MAX_RATE [ticks].
+	 */
+	if (ct >= gd->arch.wdt_last) {
+		if ((ct - gd->arch.wdt_last) < CONFIG_WD_MAX_RATE)
+			return;
+	} else {
+		/* Time base counter had been reset */
+		if (((unsigned long long)(-1) - gd->arch.wdt_last + ct) <
+		    CONFIG_WD_MAX_RATE)
+			return;
+	}
+	gd->arch.wdt_last = get_ticks();
+#endif
+
+	/*
+	 * Toggle watchdog output
+	 */
+	val = gpio_read_out_bit(CONFIG_SYS_GPIO_WATCHDOG) == 0 ? 1 : 0;
+	gpio_write_bit(CONFIG_SYS_GPIO_WATCHDOG, val);
+}
+
+int do_eeprom_wp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	if (argc < 2)
+		return cmd_usage(cmdtp);
+
+	if ((strcmp(argv[1], "on") == 0))
+		gpio_write_bit(CONFIG_SYS_GPIO_EEPROM_EXT_WP, 1);
+	else if ((strcmp(argv[1], "off") == 0))
+		gpio_write_bit(CONFIG_SYS_GPIO_EEPROM_EXT_WP, 0);
+	else
+		return cmd_usage(cmdtp);
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	eepromwp,	2,	0,	do_eeprom_wp,
+	"eeprom write protect off/on",
+	"<on|off> - enable (on) or disable (off) I2C EEPROM write protect"
+);
+
+#if defined(CONFIG_VIDEO)
+#include <video_fb.h>
+#include <mb862xx.h>
+
+extern GraphicDevice mb862xx;
+
+static const gdc_regs init_regs [] = {
+	{ 0x0100, 0x00000f00 },
+	{ 0x0020, 0x801401df },
+	{ 0x0024, 0x00000000 },
+	{ 0x0028, 0x00000000 },
+	{ 0x002c, 0x00000000 },
+	{ 0x0110, 0x00000000 },
+	{ 0x0114, 0x00000000 },
+	{ 0x0118, 0x01df0280 },
+	{ 0x0004, 0x031f0000 },
+	{ 0x0008, 0x027f027f },
+	{ 0x000c, 0x015f028f },
+	{ 0x0010, 0x020c0000 },
+	{ 0x0014, 0x01df01ea },
+	{ 0x0018, 0x00000000 },
+	{ 0x001c, 0x01e00280 },
+	{ 0x0100, 0x80010f00 },
+	{ 0x0, 0x0 }
+};
+
+const gdc_regs *board_get_regs(void)
+{
+	return init_regs;
+}
+
+/* Returns Lime base address */
+unsigned int board_video_init(void)
+{
+	/*
+	 * Reset Lime controller
+	 */
+	gpio_write_bit(CONFIG_SYS_GPIO_LIME_S, 1);
+	udelay(500);
+	gpio_write_bit(CONFIG_SYS_GPIO_LIME_RST, 1);
+
+	mb862xx.winSizeX = 640;
+	mb862xx.winSizeY = 480;
+	mb862xx.gdfBytesPP = 2;
+	mb862xx.gdfIndex = GDF_15BIT_555RGB;
+
+	return CONFIG_SYS_LIME_BASE_0;
+}
+
+#define DEFAULT_BRIGHTNESS	0x64
+
+static void board_backlight_brightness(int brightness)
+{
+	if (brightness > 0) {
+		/* pwm duty, lamp on */
+		out_be32((void *)(CONFIG_SYS_FPGA_BASE_0 + 0x00000024), brightness);
+		out_be32((void *)(CONFIG_SYS_FPGA_BASE_0 + 0x00000020), 0x701);
+	} else {
+		/* lamp off */
+		out_be32((void *)(CONFIG_SYS_FPGA_BASE_0 + 0x00000024), 0x00);
+		out_be32((void *)(CONFIG_SYS_FPGA_BASE_0 + 0x00000020), 0x00);
+	}
+}
+
+void board_backlight_switch(int flag)
+{
+	char * param;
+	int rc;
+
+	if (flag) {
+		param = getenv("brightness");
+		rc = param ? simple_strtol(param, NULL, 10) : -1;
+		if (rc < 0)
+			rc = DEFAULT_BRIGHTNESS;
+	} else {
+		rc = 0;
+	}
+	board_backlight_brightness(rc);
+}
+
+#if defined(CONFIG_CONSOLE_EXTRA_INFO)
+/*
+ * Return text to be printed besides the logo.
+ */
+void video_get_info_str(int line_number, char *info)
+{
+	if (line_number == 1)
+		strcpy(info, " Board: Lwmon5 (Liebherr Elektronik GmbH)");
+	else
+		info [0] = '\0';
+}
+#endif /* CONFIG_CONSOLE_EXTRA_INFO */
+#endif /* CONFIG_VIDEO */
+
+void board_reset(void)
+{
+	gpio_write_bit(CONFIG_SYS_GPIO_BOARD_RESET, 1);
+}
+
+#ifdef CONFIG_SPL_OS_BOOT
+/*
+ * lwmon5 specific implementation of spl_start_uboot()
+ *
+ * RETURN
+ * 0 if booting into OS is selected (default)
+ * 1 if booting into U-Boot is selected
+ */
+int spl_start_uboot(void)
+{
+	char s[8];
+
+	env_init();
+	getenv_f("boot_os", s, sizeof(s));
+	if ((s != NULL) && (strcmp(s, "yes") == 0))
+		return 0;
+
+	return 1;
+}
+
+/*
+ * This function is called from the SPL U-Boot version for
+ * early init stuff, that needs to be done for OS (e.g. Linux)
+ * booting. Doing it later in the real U-Boot would not work
+ * in case that the SPL U-Boot boots Linux directly.
+ */
+void spl_board_init(void)
+{
+	const gdc_regs *regs = board_get_regs();
+
+	/*
+	 * Setup PFC registers, mainly for ethernet support
+	 * later on in Linux
+	 */
+	board_early_init_f();
+
+	/* enable the LSB transmitter */
+	gpio_write_bit(CONFIG_SYS_GPIO_LSB_ENABLE, 1);
+
+	/*
+	 * Clear resets
+	 */
+	mtsdr(SDR0_SRST1, 0x00000000);
+	mtsdr(SDR0_SRST0, 0x00000000);
+
+	/*
+	 * Reset Lime controller
+	 */
+	gpio_write_bit(CONFIG_SYS_GPIO_LIME_S, 1);
+	udelay(500);
+	gpio_write_bit(CONFIG_SYS_GPIO_LIME_RST, 1);
+
+	out_be32((void *)CONFIG_SYS_LIME_SDRAM_CLOCK, CONFIG_SYS_MB862xx_CCF);
+	udelay(300);
+	out_be32((void *)CONFIG_SYS_LIME_MMR, CONFIG_SYS_MB862xx_MMR);
+
+	while (regs->index) {
+		out_be32((void *)(CONFIG_SYS_LIME_BASE_0 + GC_DISP_BASE) +
+			 regs->index, regs->value);
+		regs++;
+	}
+
+	board_backlight_brightness(DEFAULT_BRIGHTNESS);
+}
+#endif
diff --git a/board/lwmon5/sdram.c b/board/lwmon5/sdram.c
new file mode 100644
index 0000000..bcb3449
--- /dev/null
+++ b/board/lwmon5/sdram.c
@@ -0,0 +1,245 @@
+/*
+ * (C) Copyright 2006
+ * Sylvie Gohl,		    AMCC/IBM, gohl.sylvie@fr.ibm.com
+ * Jacqueline Pira-Ferriol, AMCC/IBM, jpira-ferriol@fr.ibm.com
+ * Thierry Roman,	    AMCC/IBM, thierry_roman@fr.ibm.com
+ * Alain Saurel,	    AMCC/IBM, alain.saurel@fr.ibm.com
+ * Robert Snyder,	    AMCC/IBM, rob.snyder@fr.ibm.com
+ *
+ * (C) Copyright 2007-2013
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/* define DEBUG for debugging output (obviously ;-)) */
+#if 0
+#define DEBUG
+#endif
+
+#include <common.h>
+#include <asm/processor.h>
+#include <asm/mmu.h>
+#include <asm/io.h>
+#include <asm/cache.h>
+#include <asm/ppc440.h>
+#include <watchdog.h>
+
+/*
+ * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 memory
+ * region. Right now the cache should still be disabled in U-Boot because of the
+ * EMAC driver, that need it's buffer descriptor to be located in non cached
+ * memory.
+ *
+ * If at some time this restriction doesn't apply anymore, just define
+ * CONFIG_4xx_DCACHE in the board config file and this code should setup
+ * everything correctly.
+ */
+#ifdef CONFIG_4xx_DCACHE
+#define MY_TLB_WORD2_I_ENABLE	0			/* enable caching on SDRAM */
+#else
+#define MY_TLB_WORD2_I_ENABLE	TLB_WORD2_I_ENABLE	/* disable caching on SDRAM */
+#endif
+
+/*-----------------------------------------------------------------------------+
+ * Prototypes
+ *-----------------------------------------------------------------------------*/
+extern int denali_wait_for_dlllock(void);
+extern void denali_core_search_data_eye(void);
+extern void dcbz_area(u32 start_address, u32 num_bytes);
+
+static u32 is_ecc_enabled(void)
+{
+	u32 val;
+
+	mfsdram(DDR0_22, val);
+	val &= DDR0_22_CTRL_RAW_MASK;
+	if (val)
+		return 1;
+	else
+		return 0;
+}
+
+void board_add_ram_info(int use_default)
+{
+	PPC4xx_SYS_INFO board_cfg;
+	u32 val;
+
+	if (is_ecc_enabled())
+		puts(" (ECC");
+	else
+		puts(" (ECC not");
+
+	get_sys_info(&board_cfg);
+	printf(" enabled, %ld MHz", (board_cfg.freqPLB * 2) / 1000000);
+
+	mfsdram(DDR0_03, val);
+	val = DDR0_03_CASLAT_DECODE(val);
+	printf(", CL%d)", val);
+}
+
+#ifdef CONFIG_DDR_ECC
+static void wait_ddr_idle(void)
+{
+	/*
+	 * Controller idle status cannot be determined for Denali
+	 * DDR2 code. Just return here.
+	 */
+}
+
+static void program_ecc(u32 start_address,
+			u32 num_bytes,
+			u32 tlb_word2_i_value)
+{
+	u32 val;
+	u32 current_addr = start_address;
+	u32 size;
+	int bytes_remaining;
+
+	sync();
+	wait_ddr_idle();
+
+	/*
+	 * Because of 440EPx errata CHIP 11, we don't touch the last 256
+	 * bytes of SDRAM.
+	 */
+	bytes_remaining = num_bytes - CONFIG_SYS_MEM_TOP_HIDE;
+
+	/*
+	 * We have to write the ECC bytes by zeroing and flushing in smaller
+	 * steps, since the whole 256MByte takes too long for the external
+	 * watchdog.
+	 */
+	while (bytes_remaining > 0) {
+		size = min((64 << 20), bytes_remaining);
+
+		/* Write zero's to SDRAM */
+		dcbz_area(current_addr, size);
+
+		/* Write modified dcache lines back to memory */
+		clean_dcache_range(current_addr, current_addr + size);
+
+		current_addr += 64 << 20;
+		bytes_remaining -= 64 << 20;
+		WATCHDOG_RESET();
+	}
+
+	sync();
+	wait_ddr_idle();
+
+	/* Clear error status */
+	mfsdram(DDR0_00, val);
+	mtsdram(DDR0_00, val | DDR0_00_INT_ACK_ALL);
+
+	/* Set 'int_mask' parameter to functionnal value */
+	mfsdram(DDR0_01, val);
+	mtsdram(DDR0_01, ((val &~ DDR0_01_INT_MASK_MASK) | DDR0_01_INT_MASK_ALL_OFF));
+
+	sync();
+	wait_ddr_idle();
+}
+#endif
+
+/*************************************************************************
+ *
+ * initdram -- 440EPx's DDR controller is a DENALI Core
+ *
+ ************************************************************************/
+phys_size_t initdram (int board_type)
+{
+	/* CL=4 */
+	mtsdram(DDR0_02, 0x00000000);
+
+	mtsdram(DDR0_00, 0x0000190A);
+	mtsdram(DDR0_01, 0x01000000);
+	mtsdram(DDR0_03, 0x02040803); /* A suitable burst length was taken. CAS is right for our board */
+
+	mtsdram(DDR0_04, 0x0B030300);
+	mtsdram(DDR0_05, 0x02020308);
+	mtsdram(DDR0_06, 0x0003C812);
+	mtsdram(DDR0_07, 0x00090100);
+	mtsdram(DDR0_08, 0x03c80001);
+	mtsdram(DDR0_09, 0x00011D5F);
+	mtsdram(DDR0_10, 0x00000100);
+	mtsdram(DDR0_11, 0x000CC800);
+	mtsdram(DDR0_12, 0x00000003);
+	mtsdram(DDR0_14, 0x00000000);
+	mtsdram(DDR0_17, 0x1e000000);
+	mtsdram(DDR0_18, 0x1e1e1e1e);
+	mtsdram(DDR0_19, 0x1e1e1e1e);
+	mtsdram(DDR0_20, 0x0B0B0B0B);
+	mtsdram(DDR0_21, 0x0B0B0B0B);
+#ifdef CONFIG_DDR_ECC
+	mtsdram(DDR0_22, 0x00267F0B | DDR0_22_CTRL_RAW_ECC_ENABLE); /* enable ECC       */
+#else
+	mtsdram(DDR0_22, 0x00267F0B);
+#endif
+
+	mtsdram(DDR0_23, 0x01000000);
+	mtsdram(DDR0_24, 0x01010001);
+
+	mtsdram(DDR0_26, 0x2D93028A);
+	mtsdram(DDR0_27, 0x0784682B);
+
+	mtsdram(DDR0_28, 0x00000080);
+	mtsdram(DDR0_31, 0x00000000);
+	mtsdram(DDR0_42, 0x01000008);
+
+	mtsdram(DDR0_43, 0x050A0200);
+	mtsdram(DDR0_44, 0x00000005);
+	mtsdram(DDR0_02, 0x00000001); /* Activate the denali core */
+
+	denali_wait_for_dlllock();
+
+#if defined(CONFIG_DDR_DATA_EYE)
+	/* -----------------------------------------------------------+
+	 * Perform data eye search if requested.
+	 * ----------------------------------------------------------*/
+	program_tlb(0, CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MBYTES_SDRAM << 20,
+		    TLB_WORD2_I_ENABLE);
+	denali_core_search_data_eye();
+	remove_tlb(CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MBYTES_SDRAM << 20);
+#endif
+
+	/*
+	 * Program tlb entries for this size (dynamic)
+	 */
+	program_tlb(0, CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MBYTES_SDRAM << 20,
+		    MY_TLB_WORD2_I_ENABLE);
+
+#if defined(CONFIG_DDR_ECC)
+#if defined(CONFIG_4xx_DCACHE)
+	/*
+	 * If ECC is enabled, initialize the parity bits.
+	 */
+	program_ecc(0, CONFIG_SYS_MBYTES_SDRAM << 20, 0);
+#else /* CONFIG_4xx_DCACHE */
+	/*
+	 * Setup 2nd TLB with same physical address but different virtual address
+	 * with cache enabled. This is done for fast ECC generation.
+	 */
+	program_tlb(0, CONFIG_SYS_DDR_CACHED_ADDR, CONFIG_SYS_MBYTES_SDRAM << 20, 0);
+
+	/*
+	 * If ECC is enabled, initialize the parity bits.
+	 */
+	program_ecc(CONFIG_SYS_DDR_CACHED_ADDR, CONFIG_SYS_MBYTES_SDRAM << 20, 0);
+
+	/*
+	 * Now after initialization (auto-calibration and ECC generation)
+	 * remove the TLB entries with caches enabled and program again with
+	 * desired cache functionality
+	 */
+	remove_tlb(CONFIG_SYS_DDR_CACHED_ADDR, CONFIG_SYS_MBYTES_SDRAM << 20);
+#endif /* CONFIG_4xx_DCACHE */
+#endif /* CONFIG_DDR_ECC */
+
+	/*
+	 * Clear possible errors resulting from data-eye-search.
+	 * If not done, then we could get an interrupt later on when
+	 * exceptions are enabled.
+	 */
+	set_mcsr(get_mcsr());
+
+	return (CONFIG_SYS_MBYTES_SDRAM << 20);
+}
diff --git a/board/nvidia/p2371-2180/pinmux-config-p2371-2180.h b/board/nvidia/p2371-2180/pinmux-config-p2371-2180.h
index ff89b9e..d5be6ec 100644
--- a/board/nvidia/p2371-2180/pinmux-config-p2371-2180.h
+++ b/board/nvidia/p2371-2180/pinmux-config-p2371-2180.h
@@ -24,6 +24,17 @@
 static const struct tegra_gpio_config p2371_2180_gpio_inits[] = {
 	/*        gpio, init_val */
 	GPIO_INIT(A5,   IN),
+	GPIO_INIT(B0,   IN),
+	GPIO_INIT(B1,   IN),
+	GPIO_INIT(B2,   IN),
+	GPIO_INIT(B3,   IN),
+	GPIO_INIT(C0,   IN),
+	GPIO_INIT(C1,   IN),
+	GPIO_INIT(C2,   IN),
+	GPIO_INIT(C3,   IN),
+	GPIO_INIT(C4,   IN),
+	GPIO_INIT(E4,   IN),
+	GPIO_INIT(E5,   IN),
 	GPIO_INIT(E6,   IN),
 	GPIO_INIT(H0,   OUT0),
 	GPIO_INIT(H1,   OUT0),
@@ -32,7 +43,7 @@
 	GPIO_INIT(H4,   OUT0),
 	GPIO_INIT(H5,   IN),
 	GPIO_INIT(H6,   IN),
-	GPIO_INIT(H7,   OUT0),
+	GPIO_INIT(H7,   IN),
 	GPIO_INIT(I0,   OUT0),
 	GPIO_INIT(I1,   IN),
 	GPIO_INIT(I2,   OUT0),
@@ -47,6 +58,8 @@
 	GPIO_INIT(S7,   OUT0),
 	GPIO_INIT(T0,   OUT0),
 	GPIO_INIT(T1,   OUT0),
+	GPIO_INIT(U2,   IN),
+	GPIO_INIT(U3,   IN),
 	GPIO_INIT(V1,   OUT0),
 	GPIO_INIT(V2,   OUT0),
 	GPIO_INIT(V3,   IN),
@@ -65,8 +78,9 @@
 	GPIO_INIT(Z0,   IN),
 	GPIO_INIT(Z2,   IN),
 	GPIO_INIT(Z3,   OUT0),
+	GPIO_INIT(BB0,  IN),
 	GPIO_INIT(BB2,  OUT0),
-	GPIO_INIT(BB3,  OUT0),
+	GPIO_INIT(BB3,  IN),
 	GPIO_INIT(CC1,  IN),
 };
 
@@ -91,19 +105,19 @@
 	PINCFG(PEX_L1_CLKREQ_N_PA4,  PE1,        NORMAL, NORMAL,   INPUT,   DISABLE, HIGH),
 	PINCFG(SATA_LED_ACTIVE_PA5,  DEFAULT,    UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(PA6,                  SATA,       NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(DAP1_FS_PB0,          I2S1,       NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
-	PINCFG(DAP1_DIN_PB1,         I2S1,       NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
-	PINCFG(DAP1_DOUT_PB2,        I2S1,       NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
-	PINCFG(DAP1_SCLK_PB3,        I2S1,       NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(DAP1_FS_PB0,          DEFAULT,    DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(DAP1_DIN_PB1,         DEFAULT,    DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(DAP1_DOUT_PB2,        DEFAULT,    DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(DAP1_SCLK_PB3,        DEFAULT,    DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(SPI2_MOSI_PB4,        SPI2,       NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(SPI2_MISO_PB5,        SPI2,       NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(SPI2_SCK_PB6,         SPI2,       NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(SPI2_CS0_PB7,         SPI2,       UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
-	PINCFG(SPI1_MOSI_PC0,        SPI1,       DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
-	PINCFG(SPI1_MISO_PC1,        SPI1,       DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
-	PINCFG(SPI1_SCK_PC2,         SPI1,       DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
-	PINCFG(SPI1_CS0_PC3,         SPI1,       UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
-	PINCFG(SPI1_CS1_PC4,         SPI1,       UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(SPI1_MOSI_PC0,        DEFAULT,    DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(SPI1_MISO_PC1,        DEFAULT,    DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(SPI1_SCK_PC2,         DEFAULT,    DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(SPI1_CS0_PC3,         DEFAULT,    UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(SPI1_CS1_PC4,         DEFAULT,    UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(SPI4_SCK_PC5,         SPI4,       DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(SPI4_CS0_PC6,         SPI4,       UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(SPI4_MOSI_PC7,        SPI4,       DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
@@ -116,9 +130,9 @@
 	PINCFG(DMIC1_DAT_PE1,        I2S3,       NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(DMIC2_CLK_PE2,        I2S3,       NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(DMIC2_DAT_PE3,        I2S3,       NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
-	PINCFG(DMIC3_CLK_PE4,        DMIC3,      NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(DMIC3_DAT_PE5,        DMIC3,      UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
-	PINCFG(PE6,                  DEFAULT,    UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(DMIC3_CLK_PE4,        DEFAULT,    DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(DMIC3_DAT_PE5,        DEFAULT,    DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(PE6,                  DEFAULT,    DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(PE7,                  PWM3,       NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(GEN3_I2C_SCL_PF0,     I2C3,       NORMAL, NORMAL,   INPUT,   DISABLE, NORMAL),
 	PINCFG(GEN3_I2C_SDA_PF1,     I2C3,       NORMAL, NORMAL,   INPUT,   DISABLE, NORMAL),
@@ -133,7 +147,7 @@
 	PINCFG(BT_RST_PH4,           DEFAULT,    NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(BT_WAKE_AP_PH5,       DEFAULT,    UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(PH6,                  DEFAULT,    UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
-	PINCFG(AP_WAKE_NFC_PH7,      DEFAULT,    NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
+	PINCFG(AP_WAKE_NFC_PH7,      DEFAULT,    DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(NFC_EN_PI0,           DEFAULT,    NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(NFC_INT_PI1,          DEFAULT,    UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(GPS_EN_PI2,           DEFAULT,    NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
@@ -184,8 +198,8 @@
 	PINCFG(CAM1_STROBE_PT1,      DEFAULT,    NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(UART1_TX_PU0,         UARTA,      NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(UART1_RX_PU1,         UARTA,      UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
-	PINCFG(UART1_RTS_PU2,        UARTA,      NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(UART1_CTS_PU3,        UARTA,      UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(UART1_RTS_PU2,        DEFAULT,    DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(UART1_CTS_PU3,        DEFAULT,    DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(LCD_BL_PWM_PV0,       PWM0,       NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(LCD_BL_EN_PV1,        DEFAULT,    NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(LCD_RST_PV2,          DEFAULT,    NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
@@ -194,10 +208,10 @@
 	PINCFG(AP_READY_PV5,         DEFAULT,    NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(TOUCH_RST_PV6,        DEFAULT,    NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(TOUCH_CLK_PV7,        TOUCH,      NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(MODEM_WAKE_AP_PX0,    DEFAULT,    UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(MODEM_WAKE_AP_PX0,    DEFAULT,    DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(TOUCH_INT_PX1,        DEFAULT,    UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(MOTION_INT_PX2,       DEFAULT,    UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
-	PINCFG(ALS_PROX_INT_PX3,     DEFAULT,    UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(ALS_PROX_INT_PX3,     DEFAULT,    DOWN,   NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(TEMP_ALERT_PX4,       DEFAULT,    UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(BUTTON_POWER_ON_PX5,  DEFAULT,    UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(BUTTON_VOL_UP_PX6,    DEFAULT,    UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
@@ -218,10 +232,10 @@
 	PINCFG(DAP2_SCLK_PAA1,       I2S2,       NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(DAP2_DIN_PAA2,        I2S2,       NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(DAP2_DOUT_PAA3,       I2S2,       NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
-	PINCFG(AUD_MCLK_PBB0,        AUD,        NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
+	PINCFG(AUD_MCLK_PBB0,        DEFAULT,    UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(DVFS_PWM_PBB1,        CLDVFS,     NORMAL, TRISTATE, OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(DVFS_CLK_PBB2,        DEFAULT,    NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(GPIO_X1_AUD_PBB3,     DEFAULT,    NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
+	PINCFG(GPIO_X1_AUD_PBB3,     DEFAULT,    UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
 	PINCFG(GPIO_X3_AUD_PBB4,     RSVD0,      DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(HDMI_CEC_PCC0,        CEC,        NORMAL, NORMAL,   INPUT,   DISABLE, HIGH),
 	PINCFG(HDMI_INT_DP_HPD_PCC1, DEFAULT,    DOWN,   NORMAL,   INPUT,   DISABLE, NORMAL),
diff --git a/board/siemens/smartweb/smartweb.c b/board/siemens/smartweb/smartweb.c
index 2d42488..d82f1b7 100644
--- a/board/siemens/smartweb/smartweb.c
+++ b/board/siemens/smartweb/smartweb.c
@@ -90,7 +90,8 @@
 		pin_to_mask(AT91_PIN_PA17) |
 		pin_to_mask(AT91_PIN_PA25) |
 		pin_to_mask(AT91_PIN_PA26) |
-		pin_to_mask(AT91_PIN_PA28),
+		pin_to_mask(AT91_PIN_PA28) |
+		pin_to_mask(AT91_PIN_PA29),
 		&pioa->pudr);
 
 	at91_phy_reset();
@@ -101,7 +102,8 @@
 		pin_to_mask(AT91_PIN_PA17) |
 		pin_to_mask(AT91_PIN_PA25) |
 		pin_to_mask(AT91_PIN_PA26) |
-		pin_to_mask(AT91_PIN_PA28),
+		pin_to_mask(AT91_PIN_PA28) |
+		pin_to_mask(AT91_PIN_PA29),
 		&pioa->puer);
 
 	/* Initialize EMAC=MACB hardware */
@@ -141,13 +143,6 @@
 
 int board_init(void)
 {
-	/* Adress of boot parameters */
-	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
-
-	smartweb_nand_hw_init();
-#ifdef CONFIG_MACB
-	smartweb_macb_hw_init();
-#endif
 	/* power LED red */
 	at91_set_gpio_output(AT91_PIN_PC6, 0);
 	at91_set_gpio_output(AT91_PIN_PC7, 1);
@@ -163,6 +158,13 @@
 	at91_udc_probe(&board_udc_data);
 #endif
 
+	/* Adress of boot parameters */
+	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+
+	smartweb_nand_hw_init();
+#ifdef CONFIG_MACB
+	smartweb_macb_hw_init();
+#endif
 	return 0;
 }
 
@@ -197,6 +199,7 @@
 
 void spl_board_init(void)
 {
+	/* power LED orange */
 	at91_set_gpio_output(AT91_PIN_PC6, 1);
 	at91_set_gpio_output(AT91_PIN_PC7, 1);
 	/* alarm LED orange */
@@ -212,8 +215,8 @@
 
 	/* check if both  button are pressed */
 	if (at91_get_gpio_value(AT91_PIN_PA28) == 0 &&
-	    at91_get_gpio_value(AT91_PIN_PA29) == 0) {
-		debug("Recovery button pressed\n");
+		at91_get_gpio_value(AT91_PIN_PA29) == 0) {
+		smartweb_nand_hw_init();
 		nand_init();
 		spl_nand_erase_one(0, 0);
 	}
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index 8f95867..67a9d29 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -20,8 +20,6 @@
 F:	configs/pov_protab2_ips9_defconfig
 F:	include/configs/sun5i.h
 F:	configs/A10s-OLinuXino-M_defconfig
-F:	configs/A10s-OLinuXino-M_defconfig
-F:	configs/A10s-Wobo-i5_defconfig
 F:	configs/A13-OLinuXino_defconfig
 F:	configs/A13-OLinuXinoM_defconfig
 F:	configs/Auxtek-T003_defconfig
@@ -35,6 +33,7 @@
 F:	configs/CSQ_CS908_defconfig
 F:	configs/Mele_A1000G_quad_defconfig
 F:	configs/Mele_M9_defconfig
+F:	configs/Wobo_i5_defconfig
 F:	include/configs/sun7i.h
 F:	configs/A20-OLinuXino_MICRO_defconfig
 F:	configs/Bananapi_defconfig
@@ -51,6 +50,9 @@
 F:	configs/gt90h_v4_defconfig
 F:	configs/Ippo_q8h_v1_2_defconfig
 F:	configs/Ippo_q8h_v1_2_a33_1024x600_defconfig
+F:	configs/q8_a23_tablet_800x480_defconfig
+F:	configs/q8_a33_tablet_800x480_defconfig
+F:	configs/q8_a33_tablet_1024x600_defconfig
 F:	include/configs/sun9i.h
 F:	configs/Merrii_A80_Optimus_defconfig
 
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 9c855f6..096d127 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -516,6 +516,31 @@
 }
 #endif
 
+#if !defined(CONFIG_SPL_BUILD)
+#include <asm/arch/spl.h>
+
+/*
+ * Check the SPL header for the "sunxi" variant. If found: parse values
+ * that might have been passed by the loader ("fel" utility), and update
+ * the environment accordingly.
+ */
+static void parse_spl_header(const uint32_t spl_addr)
+{
+	struct boot_file_head *spl = (void *)spl_addr;
+	if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) == 0) {
+		uint8_t spl_header_version = spl->spl_signature[3];
+		if (spl_header_version == SPL_HEADER_VERSION) {
+			if (spl->fel_script_address)
+				setenv_hex("fel_scriptaddr",
+					   spl->fel_script_address);
+			return;
+		}
+		printf("sunxi SPL version mismatch: expected %u, got %u\n",
+		       SPL_HEADER_VERSION, spl_header_version);
+	}
+}
+#endif
+
 #ifdef CONFIG_MISC_INIT_R
 int misc_init_r(void)
 {
@@ -524,6 +549,16 @@
 	uint8_t mac_addr[6];
 	int ret;
 
+#if !defined(CONFIG_SPL_BUILD)
+	setenv("fel_booted", NULL);
+	setenv("fel_scriptaddr", NULL);
+	/* determine if we are running in FEL mode */
+	if (!is_boot0_magic(SPL_ADDR + 4)) { /* eGON.BT0 */
+		setenv("fel_booted", "1");
+		parse_spl_header(SPL_ADDR);
+	}
+#endif
+
 	ret = sunxi_get_sid(sid);
 	if (ret == 0 && sid[0] != 0 && sid[3] != 0) {
 		if (!getenv("ethaddr")) {
diff --git a/board/synopsys/axs101/axs101.c b/board/synopsys/axs101/axs101.c
index d4280f7..aa446b9 100644
--- a/board/synopsys/axs101/axs101.c
+++ b/board/synopsys/axs101/axs101.c
@@ -30,7 +30,7 @@
 	host->dev_index = 0;
 	host->bus_hz = 50000000;
 
-	add_dwmci(host, host->bus_hz, 400000);
+	add_dwmci(host, host->bus_hz / 2, 400000);
 
 	return 0;
 }
diff --git a/board/timll/devkit3250/devkit3250.c b/board/timll/devkit3250/devkit3250.c
index 4b3c94e..386d0cd 100644
--- a/board/timll/devkit3250/devkit3250.c
+++ b/board/timll/devkit3250/devkit3250.c
@@ -62,7 +62,7 @@
 
 	/* Change the NOR timings to optimum value to get maximum bandwidth */
 	emc->stat[0].waitwen	= EMC_STAT_WAITWEN(1);
-	emc->stat[0].waitoen	= EMC_STAT_WAITOEN(1);
+	emc->stat[0].waitoen	= EMC_STAT_WAITOEN(0);
 	emc->stat[0].waitrd	= EMC_STAT_WAITRD(12);
 	emc->stat[0].waitpage	= EMC_STAT_WAITPAGE(12);
 	emc->stat[0].waitwr	= EMC_STAT_WAITWR(5);
diff --git a/common/bootm.c b/common/bootm.c
index 667c934..58936ca 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -389,6 +389,15 @@
 		break;
 	}
 #endif /* CONFIG_LZO */
+#ifdef CONFIG_LZ4
+	case IH_COMP_LZ4: {
+		size_t size = unc_len;
+
+		ret = ulz4fn(image_buf, image_len, load_buf, &size);
+		image_len = size;
+		break;
+	}
+#endif /* CONFIG_LZ4 */
 	default:
 		printf("Unimplemented compression type %d\n", comp);
 		return BOOTM_ERR_UNIMPLEMENTED;
@@ -474,7 +483,9 @@
 #ifdef CONFIG_NETCONSOLE
 	/* Stop the ethernet stack if NetConsole could have left it up */
 	eth_halt();
+# ifndef CONFIG_DM_ETH
 	eth_unregister(eth_get_dev());
+# endif
 #endif
 
 #if defined(CONFIG_CMD_USB)
diff --git a/common/cmd_armflash.c b/common/cmd_armflash.c
index 1db92b0..af453f7 100644
--- a/common/cmd_armflash.c
+++ b/common/cmd_armflash.c
@@ -175,7 +175,7 @@
 		parse_bank(bank);
 }
 
-static void load_image(const char * const name, const ulong address)
+static int load_image(const char * const name, const ulong address)
 {
 	struct afs_image *afi = NULL;
 	int i;
@@ -191,7 +191,7 @@
 	}
 	if (!afi) {
 		printf("image \"%s\" not found in flash\n", name);
-		return;
+		return CMD_RET_FAILURE;
 	}
 
 	for (i = 0; i < afi->region_count; i++) {
@@ -204,7 +204,7 @@
 			to = afi->regions[i].load_address;
 		} else {
 			printf("no valid load address\n");
-			return;
+			return CMD_RET_FAILURE;
 		}
 
 		memcpy((void *)to, (void *)from, afi->regions[i].size);
@@ -215,6 +215,7 @@
 		       to,
 		       afi->regions[i].size);
 	}
+	return CMD_RET_SUCCESS;
 }
 
 static void print_images(void)
@@ -251,27 +252,47 @@
 	}
 }
 
+static int exists(const char * const name)
+{
+	int i;
+
+	parse_flash();
+	for (i = 0; i < num_afs_images; i++) {
+		struct afs_image *afi = &afs_images[i];
+
+		if (strcmp(afi->name, name) == 0)
+			return CMD_RET_SUCCESS;
+	}
+	return CMD_RET_FAILURE;
+}
+
 static int do_afs(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
+	int ret = CMD_RET_SUCCESS;
+
 	if (argc == 1) {
 		print_images();
+	} else if (argc == 3 && !strcmp(argv[1], "exists")) {
+		ret = exists(argv[2]);
 	} else if (argc == 3 && !strcmp(argv[1], "load")) {
-		load_image(argv[2], 0x0);
+		ret = load_image(argv[2], 0x0);
 	} else if (argc == 4 && !strcmp(argv[1], "load")) {
 		ulong load_addr;
 
 		load_addr = simple_strtoul(argv[3], NULL, 16);
-		load_image(argv[2], load_addr);
+		ret = load_image(argv[2], load_addr);
 	} else {
 		return CMD_RET_USAGE;
 	}
 
-	return 0;
+	return ret;
 }
 
 U_BOOT_CMD(afs, 4, 0, do_afs, "show AFS partitions",
 	   "no arguments\n"
 	   "    - list images in flash\n"
+	   "exists <image>\n"
+	   "    - returns 1 if an image exists, else 0\n"
 	   "load <image>\n"
 	   "    - load an image to the location indicated in the header\n"
 	   "load <image> 0x<address>\n"
diff --git a/common/env_eeprom.c b/common/env_eeprom.c
index 905d39a..eea169d 100644
--- a/common/env_eeprom.c
+++ b/common/env_eeprom.c
@@ -82,17 +82,117 @@
 
 void env_relocate_spec(void)
 {
-	char buf[CONFIG_ENV_SIZE];
+	char buf_env[CONFIG_ENV_SIZE];
 	unsigned int off = CONFIG_ENV_OFFSET;
 
 #ifdef CONFIG_ENV_OFFSET_REDUND
+	ulong len, crc[2], crc_tmp;
+	unsigned int off_env[2];
+	uchar rdbuf[64], flags[2];
+	int i, crc_ok[2] = {0, 0};
+
+	eeprom_init();	/* prepare for EEPROM read/write */
+
+	off_env[0] = CONFIG_ENV_OFFSET;
+	off_env[1] = CONFIG_ENV_OFFSET_REDUND;
+
+	for (i = 0; i < 2; i++) {
+		/* read CRC */
+		eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
+				off_env[i] + offsetof(env_t, crc),
+				(uchar *)&crc[i], sizeof(ulong));
+		/* read FLAGS */
+		eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
+				off_env[i] + offsetof(env_t, flags),
+				(uchar *)&flags[i], sizeof(uchar));
+
+		crc_tmp = 0;
+		len = ENV_SIZE;
+		off = off_env[i] + offsetof(env_t, data);
+		while (len > 0) {
+			int n = (len > sizeof(rdbuf)) ? sizeof(rdbuf) : len;
+
+			eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR, off,
+					rdbuf, n);
+
+			crc_tmp = crc32(crc_tmp, rdbuf, n);
+			len -= n;
+			off += n;
+		}
+
+		if (crc_tmp == crc[i])
+			crc_ok[i] = 1;
+	}
+
+	if (!crc_ok[0] && !crc_ok[1]) {
+		gd->env_addr	= 0;
+		gd->env_valid	= 0;
+	} else if (crc_ok[0] && !crc_ok[1]) {
+		gd->env_valid = 1;
+	} else if (!crc_ok[0] && crc_ok[1]) {
+		gd->env_valid = 2;
+	} else {
+		/* both ok - check serial */
+		if (flags[0] == ACTIVE_FLAG && flags[1] == OBSOLETE_FLAG)
+			gd->env_valid = 1;
+		else if (flags[0] == OBSOLETE_FLAG && flags[1] == ACTIVE_FLAG)
+			gd->env_valid = 2;
+		else if (flags[0] == 0xFF && flags[1] == 0)
+			gd->env_valid = 2;
+		else if (flags[1] == 0xFF && flags[0] == 0)
+			gd->env_valid = 1;
+		else /* flags are equal - almost impossible */
+			gd->env_valid = 1;
+	}
+
+	if (gd->env_valid == 2)
+		gd->env_addr = off_env[1] + offsetof(env_t, data);
+	else if (gd->env_valid == 1)
+		gd->env_addr = off_env[0] + offsetof(env_t, data);
+
+#else /* CONFIG_ENV_OFFSET_REDUND */
+	ulong crc, len, new;
+	uchar rdbuf[64];
+
+	eeprom_init();	/* prepare for EEPROM read/write */
+
+	/* read old CRC */
+	eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
+			CONFIG_ENV_OFFSET + offsetof(env_t, crc),
+			(uchar *)&crc, sizeof(ulong));
+
+	new = 0;
+	len = ENV_SIZE;
+	off = offsetof(env_t, data);
+	while (len > 0) {
+		int n = (len > sizeof(rdbuf)) ? sizeof(rdbuf) : len;
+
+		eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
+				CONFIG_ENV_OFFSET + off, rdbuf, n);
+		new = crc32(new, rdbuf, n);
+		len -= n;
+		off += n;
+	}
+
+	if (crc == new) {
+		gd->env_addr	= offsetof(env_t, data);
+		gd->env_valid	= 1;
+	} else {
+		gd->env_addr	= 0;
+		gd->env_valid	= 0;
+	}
+#endif /* CONFIG_ENV_OFFSET_REDUND */
+
+	off = CONFIG_ENV_OFFSET;
+#ifdef CONFIG_ENV_OFFSET_REDUND
 	if (gd->env_valid == 2)
 		off = CONFIG_ENV_OFFSET_REDUND;
 #endif
-	eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
-			off, (uchar *)buf, CONFIG_ENV_SIZE);
 
-	env_import(buf, 1);
+	eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
+		off, (uchar *)buf_env, CONFIG_ENV_SIZE);
+
+	env_import(buf_env, 1);
 }
 
 int saveenv(void)
@@ -144,121 +244,9 @@
  * We are still running from ROM, so data use is limited.
  * Use a (moderately small) buffer on the stack
  */
-#ifdef CONFIG_ENV_OFFSET_REDUND
 int env_init(void)
 {
-#ifdef ENV_IS_EMBEDDED
-	ulong len, crc[2], crc_tmp;
-	unsigned int off, off_env[2];
-	uchar buf[64], flags[2];
-	int i, crc_ok[2] = {0, 0};
-
-	eeprom_init();	/* prepare for EEPROM read/write */
-
-	off_env[0] = CONFIG_ENV_OFFSET;
-	off_env[1] = CONFIG_ENV_OFFSET_REDUND;
-
-	for (i = 0; i < 2; i++) {
-		/* read CRC */
-		eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
-				off_env[i] + offsetof(env_t, crc),
-				(uchar *)&crc[i], sizeof(ulong));
-		/* read FLAGS */
-		eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
-				off_env[i] + offsetof(env_t, flags),
-				(uchar *)&flags[i], sizeof(uchar));
-
-		crc_tmp = 0;
-		len = ENV_SIZE;
-		off = off_env[i] + offsetof(env_t, data);
-		while (len > 0) {
-			int n = (len > sizeof(buf)) ? sizeof(buf) : len;
-
-			eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR, off,
-					buf, n);
-
-			crc_tmp = crc32(crc_tmp, buf, n);
-			len -= n;
-			off += n;
-		}
-
-		if (crc_tmp == crc[i])
-			crc_ok[i] = 1;
-	}
-
-	if (!crc_ok[0] && !crc_ok[1]) {
-		gd->env_addr	= 0;
-		gd->env_valid	= 0;
-
-		return 0;
-	} else if (crc_ok[0] && !crc_ok[1]) {
-		gd->env_valid = 1;
-	} else if (!crc_ok[0] && crc_ok[1]) {
-		gd->env_valid = 2;
-	} else {
-		/* both ok - check serial */
-		if (flags[0] == ACTIVE_FLAG && flags[1] == OBSOLETE_FLAG)
-			gd->env_valid = 1;
-		else if (flags[0] == OBSOLETE_FLAG && flags[1] == ACTIVE_FLAG)
-			gd->env_valid = 2;
-		else if (flags[0] == 0xFF && flags[1] == 0)
-			gd->env_valid = 2;
-		else if (flags[1] == 0xFF && flags[0] == 0)
-			gd->env_valid = 1;
-		else /* flags are equal - almost impossible */
-			gd->env_valid = 1;
-	}
-
-	if (gd->env_valid == 2)
-		gd->env_addr = off_env[1] + offsetof(env_t, data);
-	else if (gd->env_valid == 1)
-		gd->env_addr = off_env[0] + offsetof(env_t, data);
-#else
 	gd->env_addr = (ulong)&default_environment[0];
 	gd->env_valid = 1;
-#endif
 	return 0;
 }
-#else
-int env_init(void)
-{
-#ifdef ENV_IS_EMBEDDED
-	ulong crc, len, new;
-	unsigned off;
-	uchar buf[64];
-
-	eeprom_init();	/* prepare for EEPROM read/write */
-
-	/* read old CRC */
-	eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
-			CONFIG_ENV_OFFSET + offsetof(env_t, crc),
-			(uchar *)&crc, sizeof(ulong));
-
-	new = 0;
-	len = ENV_SIZE;
-	off = offsetof(env_t, data);
-
-	while (len > 0) {
-		int n = (len > sizeof(buf)) ? sizeof(buf) : len;
-
-		eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
-				CONFIG_ENV_OFFSET + off, buf, n);
-		new = crc32(new, buf, n);
-		len -= n;
-		off += n;
-	}
-
-	if (crc == new) {
-		gd->env_addr	= offsetof(env_t, data);
-		gd->env_valid	= 1;
-	} else {
-		gd->env_addr	= 0;
-		gd->env_valid	= 0;
-	}
-#else
-	gd->env_addr = (ulong)&default_environment[0];
-	gd->env_valid = 1;
-#endif
-	return 0;
-}
-#endif
diff --git a/common/image-android.c b/common/image-android.c
index d946c2f..b6a94b3 100644
--- a/common/image-android.c
+++ b/common/image-android.c
@@ -130,8 +130,10 @@
 int android_image_get_ramdisk(const struct andr_img_hdr *hdr,
 			      ulong *rd_data, ulong *rd_len)
 {
-	if (!hdr->ramdisk_size)
+	if (!hdr->ramdisk_size) {
+		*rd_data = *rd_len = 0;
 		return -1;
+	}
 
 	printf("RAM disk load addr 0x%08x size %u KiB\n",
 	       hdr->ramdisk_addr, DIV_ROUND_UP(hdr->ramdisk_size, 1024));
diff --git a/common/image.c b/common/image.c
index 1325e07..e607109 100644
--- a/common/image.c
+++ b/common/image.c
@@ -167,6 +167,7 @@
 	{	IH_COMP_GZIP,	"gzip",		"gzip compressed",	},
 	{	IH_COMP_LZMA,	"lzma",		"lzma compressed",	},
 	{	IH_COMP_LZO,	"lzo",		"lzo compressed",	},
+	{	IH_COMP_LZ4,	"lz4",		"lz4 compressed",	},
 	{	-1,		"",		"",			},
 };
 
@@ -907,6 +908,15 @@
 	*rd_start = 0;
 	*rd_end = 0;
 
+#ifdef CONFIG_ANDROID_BOOT_IMAGE
+	/*
+	 * Look for an Android boot image.
+	 */
+	buf = map_sysmem(images->os.start, 0);
+	if (genimg_get_format(buf) == IMAGE_FORMAT_ANDROID)
+		select = argv[0];
+#endif
+
 	if (argc >= 2)
 		select = argv[1];
 
diff --git a/configs/Bananapi_defconfig b/configs/Bananapi_defconfig
index 794b727..898631d 100644
--- a/configs/Bananapi_defconfig
+++ b/configs/Bananapi_defconfig
@@ -11,5 +11,6 @@
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_FPGA is not set
+CONFIG_NETCONSOLE=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_USB_EHCI_HCD=y
diff --git a/configs/Bananapro_defconfig b/configs/Bananapro_defconfig
index e56ca71..e9909d9 100644
--- a/configs/Bananapro_defconfig
+++ b/configs/Bananapro_defconfig
@@ -13,5 +13,6 @@
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_FPGA is not set
+CONFIG_NETCONSOLE=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_USB_EHCI_HCD=y
diff --git a/configs/Linksprite_pcDuino_defconfig b/configs/Linksprite_pcDuino_defconfig
index de44890..13b7ed3 100644
--- a/configs/Linksprite_pcDuino_defconfig
+++ b/configs/Linksprite_pcDuino_defconfig
@@ -1,7 +1,8 @@
 CONFIG_ARM=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_MACH_SUN4I=y
-CONFIG_DRAM_CLK=408
+CONFIG_USB1_VBUS_PIN=""
+CONFIG_USB2_VBUS_PIN=""
 CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-pcduino"
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL=y
diff --git a/configs/A10s-Wobo-i5_defconfig b/configs/Wobo_i5_defconfig
similarity index 100%
rename from configs/A10s-Wobo-i5_defconfig
rename to configs/Wobo_i5_defconfig
diff --git a/configs/chromebook_link_defconfig b/configs/chromebook_link_defconfig
index 1c10124..21e85f3 100644
--- a/configs/chromebook_link_defconfig
+++ b/configs/chromebook_link_defconfig
@@ -1,4 +1,5 @@
 CONFIG_X86=y
+CONFIG_SYS_MALLOC_F_LEN=0x1800
 CONFIG_VENDOR_GOOGLE=y
 CONFIG_DEFAULT_DEVICE_TREE="chromebook_link"
 CONFIG_TARGET_CHROMEBOOK_LINK=y
diff --git a/configs/lwmon5_defconfig b/configs/lwmon5_defconfig
new file mode 100644
index 0000000..0a6da68
--- /dev/null
+++ b/configs/lwmon5_defconfig
@@ -0,0 +1,4 @@
+CONFIG_PPC=y
+CONFIG_4xx=y
+CONFIG_TARGET_LWMON5=y
+# CONFIG_CMD_SETEXPR is not set
diff --git a/configs/q8_a23_tablet_800x480_defconfig b/configs/q8_a23_tablet_800x480_defconfig
new file mode 100644
index 0000000..3a3afa5
--- /dev/null
+++ b/configs/q8_a23_tablet_800x480_defconfig
@@ -0,0 +1,25 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN8I_A23=y
+CONFIG_DRAM_CLK=432
+CONFIG_DRAM_ZQ=63306
+CONFIG_MMC0_CD_PIN="PB4"
+CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE"
+CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_USB0_ID_DET="PH8"
+CONFIG_AXP_GPIO=y
+CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:36,ri:210,up:18,lo:22,hs:10,vs:5,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_DCLK_PHASE=0
+CONFIG_VIDEO_LCD_POWER="PH7"
+CONFIG_VIDEO_LCD_BL_EN="PH6"
+CONFIG_VIDEO_LCD_BL_PWM="PH0"
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-a23-q8-tablet"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5"
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+CONFIG_AXP221_DLDO1_VOLT=3300
+CONFIG_AXP221_ALDO1_VOLT=3000
+CONFIG_USB_MUSB_HOST=y
diff --git a/configs/q8_a33_tablet_1024x600_defconfig b/configs/q8_a33_tablet_1024x600_defconfig
new file mode 100644
index 0000000..fbbf128
--- /dev/null
+++ b/configs/q8_a33_tablet_1024x600_defconfig
@@ -0,0 +1,25 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN8I_A33=y
+CONFIG_DRAM_CLK=456
+CONFIG_DRAM_ZQ=15291
+CONFIG_MMC0_CD_PIN="PB4"
+CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE"
+CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_USB0_ID_DET="PH8"
+CONFIG_AXP_GPIO=y
+CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:18,pclk_khz:51000,le:159,ri:160,up:22,lo:12,hs:1,vs:1,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_DCLK_PHASE=0
+CONFIG_VIDEO_LCD_POWER="PH7"
+CONFIG_VIDEO_LCD_BL_EN="PH6"
+CONFIG_VIDEO_LCD_BL_PWM="PH0"
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-a33-q8-tablet"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5"
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+CONFIG_AXP221_DLDO1_VOLT=3300
+CONFIG_AXP221_ALDO1_VOLT=3000
+CONFIG_USB_MUSB_HOST=y
diff --git a/configs/q8_a33_tablet_800x480_defconfig b/configs/q8_a33_tablet_800x480_defconfig
new file mode 100644
index 0000000..8e8aa92
--- /dev/null
+++ b/configs/q8_a33_tablet_800x480_defconfig
@@ -0,0 +1,25 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN8I_A33=y
+CONFIG_DRAM_CLK=456
+CONFIG_DRAM_ZQ=15291
+CONFIG_MMC0_CD_PIN="PB4"
+CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE"
+CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_USB0_ID_DET="PH8"
+CONFIG_AXP_GPIO=y
+CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:167,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_DCLK_PHASE=0
+CONFIG_VIDEO_LCD_POWER="PH7"
+CONFIG_VIDEO_LCD_BL_EN="PH6"
+CONFIG_VIDEO_LCD_BL_PWM="PH0"
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-a33-q8-tablet"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5"
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+CONFIG_AXP221_DLDO1_VOLT=3300
+CONFIG_AXP221_ALDO1_VOLT=3000
+CONFIG_USB_MUSB_HOST=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index ae96b63..b2675c7 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -56,6 +56,7 @@
 CONFIG_SYS_VSNPRINTF=y
 CONFIG_CMD_DHRYSTONE=y
 CONFIG_TPM=y
+CONFIG_LZ4=y
 CONFIG_ERRNO_STR=y
 CONFIG_UNIT_TEST=y
 CONFIG_UT_TIME=y
diff --git a/configs/vexpress_aemv8a_dram_defconfig b/configs/vexpress_aemv8a_dram_defconfig
new file mode 100644
index 0000000..e9fc870
--- /dev/null
+++ b/configs/vexpress_aemv8a_dram_defconfig
@@ -0,0 +1,19 @@
+CONFIG_ARM=y
+CONFIG_TARGET_VEXPRESS64_BASE_FVP_DRAM=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_DEFAULT_DEVICE_TREE="vexpress64"
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_ITEST is not set
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_NFS is not set
+# CONFIG_CMD_MISC is not set
+CONFIG_DM=y
+CONFIG_DM_SERIAL=y
+CONFIG_SYS_PROMPT="VExpress64# "
diff --git a/doc/README.scrapyard b/doc/README.scrapyard
index 9cda0bd..c7b4fa3 100644
--- a/doc/README.scrapyard
+++ b/doc/README.scrapyard
@@ -19,7 +19,6 @@
 sbc405           powerpc     ppc4xx         -           -
 pcs440ep         powerpc     ppc4xx         -           -           Stefan Roese <sr@denx.de>
 p3p440           powerpc     ppc4xx         -           -           Stefan Roese <sr@denx.de>
-lwmon5           powerpc     ppc4xx         -           -           Stefan Roese <sr@denx.de>
 csb272/csb472    powerpc     ppc4xx         -           -           Tolunay Orkun <torkun@nextio.com>
 alpr             powerpc     ppc4xx         -           -           Stefan Roese <sr@denx.de>
 cam_enc_4xx      arm         arm926ejs      8d775763    2015-08-20  Heiko Schocher <hs@denx.de>
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 0bc04d4..833a803 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -289,8 +289,12 @@
 
 	dev->flags |= DM_FLAG_ACTIVATED;
 
-	/* continue regardless of the result of pinctrl */
-	pinctrl_select_state(dev, "default");
+	/*
+	 * Process pinctrl for everything except the root device, and
+	 * continue regardless of the result of pinctrl.
+	 */
+	if (dev->parent)
+		pinctrl_select_state(dev, "default");
 
 	ret = uclass_pre_probe_device(dev);
 	if (ret)
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index 17fcfbf..0f22b23 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -341,18 +341,22 @@
 		plat = calloc(1, sizeof(*plat));
 		if (!plat)
 			return -ENOMEM;
-		reg = fdtdec_get_addr(blob, node, "reg");
-		if (reg != FDT_ADDR_T_NONE)
-			bank = (struct s5p_gpio_bank *)((ulong)base + reg);
-		plat->bank = bank;
-		plat->bank_name = fdt_get_name(blob, node, NULL);
-		debug("dev at %p: %s\n", bank, plat->bank_name);
 
+		plat->bank_name = fdt_get_name(blob, node, NULL);
 		ret = device_bind(parent, parent->driver,
-					plat->bank_name, plat, -1, &dev);
+				  plat->bank_name, plat, -1, &dev);
 		if (ret)
 			return ret;
+
 		dev->of_offset = node;
+
+		reg = dev_get_addr(dev);
+		if (reg != FDT_ADDR_T_NONE)
+			bank = (struct s5p_gpio_bank *)((ulong)base + reg);
+
+		plat->bank = bank;
+
+		debug("dev at %p: %s\n", bank, plat->bank_name);
 	}
 
 	return 0;
diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c
index 4921f0f..8e880e2 100644
--- a/drivers/gpio/tegra_gpio.c
+++ b/drivers/gpio/tegra_gpio.c
@@ -1,6 +1,6 @@
 /*
  * NVIDIA Tegra20 GPIO handling.
- *  (C) Copyright 2010-2012
+ *  (C) Copyright 2010-2012,2015
  *  NVIDIA Corporation <www.nvidia.com>
  *
  * SPDX-License-Identifier:	GPL-2.0+
@@ -25,12 +25,10 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-enum {
-	TEGRA_CMD_INFO,
-	TEGRA_CMD_PORT,
-	TEGRA_CMD_OUTPUT,
-	TEGRA_CMD_INPUT,
-};
+static const int CONFIG_SFIO = 0;
+static const int CONFIG_GPIO = 1;
+static const int DIRECTION_INPUT = 0;
+static const int DIRECTION_OUTPUT = 1;
 
 struct tegra_gpio_platdata {
 	struct gpio_ctlr_bank *bank;
@@ -44,7 +42,7 @@
 	int base_gpio;		/* Port number for this port (0, 1,.., n-1) */
 };
 
-/* Return config of pin 'gpio' as GPIO (1) or SFPIO (0) */
+/* Return config of pin 'gpio' as GPIO (1) or SFIO (0) */
 static int get_config(unsigned gpio)
 {
 	struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
@@ -53,15 +51,15 @@
 	int type;
 
 	u = readl(&bank->gpio_config[GPIO_PORT(gpio)]);
-	type =  (u >> GPIO_BIT(gpio)) & 1;
+	type = (u >> GPIO_BIT(gpio)) & 1;
 
 	debug("get_config: port = %d, bit = %d is %s\n",
 		GPIO_FULLPORT(gpio), GPIO_BIT(gpio), type ? "GPIO" : "SFPIO");
 
-	return type;
+	return type ? CONFIG_GPIO : CONFIG_SFIO;
 }
 
-/* Config pin 'gpio' as GPIO or SFPIO, based on 'type' */
+/* Config pin 'gpio' as GPIO or SFIO, based on 'type' */
 static void set_config(unsigned gpio, int type)
 {
 	struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
@@ -72,7 +70,7 @@
 		GPIO_FULLPORT(gpio), GPIO_BIT(gpio), type ? "GPIO" : "SFPIO");
 
 	u = readl(&bank->gpio_config[GPIO_PORT(gpio)]);
-	if (type)				/* GPIO */
+	if (type != CONFIG_SFIO)
 		u |= 1 << GPIO_BIT(gpio);
 	else
 		u &= ~(1 << GPIO_BIT(gpio));
@@ -93,7 +91,7 @@
 	debug("get_direction: port = %d, bit = %d, %s\n",
 		GPIO_FULLPORT(gpio), GPIO_BIT(gpio), dir ? "OUT" : "IN");
 
-	return dir;
+	return dir ? DIRECTION_OUTPUT : DIRECTION_INPUT;
 }
 
 /* Config GPIO pin 'gpio' as input or output (OE) as per 'output' */
@@ -107,7 +105,7 @@
 		GPIO_FULLPORT(gpio), GPIO_BIT(gpio), output ? "OUT" : "IN");
 
 	u = readl(&bank->gpio_dir_out[GPIO_PORT(gpio)]);
-	if (output)
+	if (output != DIRECTION_INPUT)
 		u |= 1 << GPIO_BIT(gpio);
 	else
 		u &= ~(1 << GPIO_BIT(gpio));
@@ -136,24 +134,16 @@
  * Generic_GPIO primitives.
  */
 
-static int tegra_gpio_request(struct udevice *dev, unsigned offset,
-			      const char *label)
-{
-	struct tegra_port_info *state = dev_get_priv(dev);
-
-	/* Configure as a GPIO */
-	set_config(state->base_gpio + offset, 1);
-
-	return 0;
-}
-
 /* set GPIO pin 'gpio' as an input */
 static int tegra_gpio_direction_input(struct udevice *dev, unsigned offset)
 {
 	struct tegra_port_info *state = dev_get_priv(dev);
 
 	/* Configure GPIO direction as input. */
-	set_direction(state->base_gpio + offset, 0);
+	set_direction(state->base_gpio + offset, DIRECTION_INPUT);
+
+	/* Enable the pin as a GPIO */
+	set_config(state->base_gpio + offset, 1);
 
 	return 0;
 }
@@ -169,7 +159,10 @@
 	set_level(gpio, value);
 
 	/* Configure GPIO direction as output. */
-	set_direction(gpio, 1);
+	set_direction(gpio, DIRECTION_OUTPUT);
+
+	/* Enable the pin as a GPIO */
+	set_config(state->base_gpio + offset, 1);
 
 	return 0;
 }
@@ -211,16 +204,18 @@
 	for (i = 0; i < len; i++) {
 		switch (config[i].init) {
 		case TEGRA_GPIO_INIT_IN:
-			gpio_direction_input(config[i].gpio);
+			set_direction(config[i].gpio, DIRECTION_INPUT);
 			break;
 		case TEGRA_GPIO_INIT_OUT0:
-			gpio_direction_output(config[i].gpio, 0);
+			set_level(config[i].gpio, 0);
+			set_direction(config[i].gpio, DIRECTION_OUTPUT);
 			break;
 		case TEGRA_GPIO_INIT_OUT1:
-			gpio_direction_output(config[i].gpio, 1);
+			set_level(config[i].gpio, 1);
+			set_direction(config[i].gpio, DIRECTION_OUTPUT);
 			break;
 		}
-		set_config(config[i].gpio, 1);
+		set_config(config[i].gpio, CONFIG_GPIO);
 	}
 }
 
@@ -254,7 +249,6 @@
 }
 
 static const struct dm_gpio_ops gpio_tegra_ops = {
-	.request		= tegra_gpio_request,
 	.direction_input	= tegra_gpio_direction_input,
 	.direction_output	= tegra_gpio_direction_output,
 	.get_value		= tegra_gpio_get_value,
diff --git a/drivers/misc/reset_sandbox.c b/drivers/misc/reset_sandbox.c
index 917121b..2691bb0 100644
--- a/drivers/misc/reset_sandbox.c
+++ b/drivers/misc/reset_sandbox.c
@@ -40,7 +40,7 @@
 	 * (see the U_BOOT_DEVICE() declaration below) should not do anything.
 	 * If we are that device, return an error.
 	 */
-	if (gd->fdt_blob && dev->of_offset == -1)
+	if (state->fdt_fname && dev->of_offset == -1)
 		return -ENODEV;
 
 	switch (type) {
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 25f18ad..e717c44 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -120,17 +120,27 @@
 	/* determine delays */
 	if (hz <= 400000) {
 		oclk_dly = 0;
-		sclk_dly = 7;
+		sclk_dly = 0;
 	} else if (hz <= 25000000) {
 		oclk_dly = 0;
 		sclk_dly = 5;
+#ifdef CONFIG_MACH_SUN9I
 	} else if (hz <= 50000000) {
-		oclk_dly = 3;
-		sclk_dly = 5;
+		oclk_dly = 5;
+		sclk_dly = 4;
 	} else {
 		/* hz > 50000000 */
 		oclk_dly = 2;
 		sclk_dly = 4;
+#else
+	} else if (hz <= 50000000) {
+		oclk_dly = 3;
+		sclk_dly = 4;
+	} else {
+		/* hz > 50000000 */
+		oclk_dly = 1;
+		sclk_dly = 4;
+#endif
 	}
 
 	writel(CCM_MMC_CTRL_ENABLE | pll | CCM_MMC_CTRL_SCLK_DLY(sclk_dly) |
diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index 4372988..4814fa2 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -558,10 +558,10 @@
 		bit_pos  = error_loc[count] % 8;
 		if (byte_pos < SECTOR_BYTES) {
 			dat[byte_pos] ^= 1 << bit_pos;
-			printf("nand: bit-flip corrected @data=%d\n", byte_pos);
+			debug("nand: bit-flip corrected @data=%d\n", byte_pos);
 		} else if (byte_pos < error_max) {
 			read_ecc[byte_pos - SECTOR_BYTES] ^= 1 << bit_pos;
-			printf("nand: bit-flip corrected @oob=%d\n", byte_pos -
+			debug("nand: bit-flip corrected @oob=%d\n", byte_pos -
 								SECTOR_BYTES);
 		} else {
 			err = -EBADMSG;
@@ -663,7 +663,7 @@
 			/* correct data only, not ecc bytes */
 			if (errloc[i] < 8*512)
 				data[errloc[i]/8] ^= 1 << (errloc[i] & 7);
-			printf("corrected bitflip %u\n", errloc[i]);
+			debug("corrected bitflip %u\n", errloc[i]);
 #ifdef DEBUG
 			puts("read_ecc: ");
 			/*
diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c
index 5985534..b0e07aa 100644
--- a/drivers/mtd/nand/sunxi_nand_spl.c
+++ b/drivers/mtd/nand/sunxi_nand_spl.c
@@ -356,18 +356,32 @@
 
 int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
 {
+#if CONFIG_SYS_NAND_U_BOOT_OFFS == CONFIG_SPL_PAD_TO
+	/*
+	 * u-boot-dtb.bin appended to SPL, use syndrome (like the BROM does)
+	 * and try different erase block sizes to find the backup.
+	 */
 	const uint32_t boot_offsets[] = {
 		0 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS,
 		1 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS,
 		2 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS,
 		4 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS,
 	};
-	int i, syndrome;
-
-	if (CONFIG_SYS_NAND_U_BOOT_OFFS == CONFIG_SPL_PAD_TO)
-		syndrome = 1; /* u-boot-dtb.bin appended to SPL */
-	else
-		syndrome = 0; /* u-boot-dtb.bin on its own partition */
+	const int syndrome = 1;
+#else
+	/*
+	 * u-boot-dtb.bin on its own partition, do not use syndrome, u-boot
+	 * partition sits after 2 eraseblocks (spl, spl-backup), look for
+	 * backup u-boot 1 erase block further.
+	 */
+	const uint32_t eraseblock_size = CONFIG_SYS_NAND_U_BOOT_OFFS / 2;
+	const uint32_t boot_offsets[] = {
+		CONFIG_SYS_NAND_U_BOOT_OFFS,
+		CONFIG_SYS_NAND_U_BOOT_OFFS + eraseblock_size,
+	};
+	const int syndrome = 0;
+#endif
+	int i;
 
 	if (offs == CONFIG_SYS_NAND_U_BOOT_OFFS) {
 		for (i = 0; i < ARRAY_SIZE(boot_offsets); i++) {
diff --git a/drivers/mtd/spi/sf_params.c b/drivers/mtd/spi/sf_params.c
index 4a4a3af..8f5bdda 100644
--- a/drivers/mtd/spi/sf_params.c
+++ b/drivers/mtd/spi/sf_params.c
@@ -23,6 +23,7 @@
 	{"AT45DB321D",	   0x1f2700, 0x0,	64 * 1024,    64, RD_NORM,		    SECT_4K},
 	{"AT45DB641D",	   0x1f2800, 0x0,	64 * 1024,   128, RD_NORM,		    SECT_4K},
 	{"AT25DF321",      0x1f4701, 0x0,	64 * 1024,    64, RD_NORM,		    SECT_4K},
+	{"AT26DF081A",     0x1f4501, 0x0,	64 * 1024,    16, RD_NORM,		    SECT_4K},
 #endif
 #ifdef CONFIG_SPI_FLASH_EON		/* EON */
 	{"EN25Q32B",	   0x1c3016, 0x0,	64 * 1024,    64, RD_NORM,			  0},
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 31042a6..bf972dc 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -170,7 +170,11 @@
 
 static void nc_send_packet(const char *buf, int len)
 {
+#ifdef CONFIG_DM_ETH
+	struct udevice *eth;
+#else
 	struct eth_device *eth;
+#endif
 	int inited = 0;
 	uchar *pkt;
 	uchar *ether;
@@ -183,7 +187,7 @@
 		return;
 
 	if (!memcmp(nc_ether, net_null_ethaddr, 6)) {
-		if (eth->state == ETH_STATE_ACTIVE)
+		if (eth_is_active(eth))
 			return;	/* inside net loop */
 		output_packet = buf;
 		output_packet_len = len;
@@ -194,7 +198,7 @@
 		return;
 	}
 
-	if (eth->state != ETH_STATE_ACTIVE) {
+	if (!eth_is_active(eth)) {
 		if (eth_is_on_demand_init()) {
 			if (eth_init() < 0)
 				return;
@@ -292,7 +296,11 @@
 
 static int nc_stdio_tstc(struct stdio_dev *dev)
 {
+#ifdef CONFIG_DM_ETH
+	struct udevice *eth;
+#else
 	struct eth_device *eth;
+#endif
 
 	if (input_recursion)
 		return 0;
@@ -301,7 +309,7 @@
 		return 1;
 
 	eth = eth_get_dev();
-	if (eth && eth->state == ETH_STATE_ACTIVE)
+	if (eth_is_active(eth))
 		return 0;	/* inside net loop */
 
 	input_recursion = 1;
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 65c731a..a6023f1 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -571,7 +571,7 @@
 	memset(dev, 0, sizeof(*dev));
 
 	dev->duplex = -1;
-	dev->link = 1;
+	dev->link = 0;
 	dev->interface = interface;
 
 	dev->autoneg = AUTONEG_ENABLE;
diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c
index 41d5447..79f27c7 100644
--- a/drivers/pci/pci_auto.c
+++ b/drivers/pci/pci_auto.c
@@ -185,6 +185,7 @@
 #ifndef CONFIG_PCI_ENUM_ONLY
 	/* Configure the expansion ROM address */
 	pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);
+	header_type &= 0x7f;
 	if (header_type != PCI_HEADER_TYPE_CARDBUS) {
 		rom_addr = (header_type == PCI_HEADER_TYPE_NORMAL) ?
 			   PCI_ROM_ADDRESS : PCI_ROM_ADDRESS1;
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index ccb80d2..ddb725d 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -111,7 +111,7 @@
 
 config ROCKCHIP_SERIAL
 	bool "Rockchip on-chip UART support"
-	depends on ARCH_UNIPHIER && DM_SERIAL
+	depends on ARCH_ROCKCHIP && DM_SERIAL
 	help
 	  Select this to enable a debug UART for Rockchip devices. This uses
 	  the ns16550 driver. You will need to #define CONFIG_SYS_NS16550 in
diff --git a/drivers/spi/tegra20_slink.c b/drivers/spi/tegra20_slink.c
index fbb665b..144716f 100644
--- a/drivers/spi/tegra20_slink.c
+++ b/drivers/spi/tegra20_slink.c
@@ -36,6 +36,11 @@
 #define SLINK_CMD_ENB			(1 << 31)
 #define SLINK_CMD_GO			(1 << 30)
 #define SLINK_CMD_M_S			(1 << 28)
+#define SLINK_CMD_IDLE_SCLK_DRIVE_LOW	(0 << 24)
+#define SLINK_CMD_IDLE_SCLK_DRIVE_HIGH	(1 << 24)
+#define SLINK_CMD_IDLE_SCLK_PULL_LOW	(2 << 24)
+#define SLINK_CMD_IDLE_SCLK_PULL_HIGH	(3 << 24)
+#define SLINK_CMD_IDLE_SCLK_MASK	(3 << 24)
 #define SLINK_CMD_CK_SDA		(1 << 21)
 #define SLINK_CMD_CS_POL		(1 << 13)
 #define SLINK_CMD_CS_VAL		(1 << 12)
@@ -331,6 +336,22 @@
 static int tegra30_spi_set_mode(struct udevice *bus, uint mode)
 {
 	struct tegra30_spi_priv *priv = dev_get_priv(bus);
+	struct spi_regs *regs = priv->regs;
+	u32 reg;
+
+	reg = readl(&regs->command);
+
+	/* Set CPOL and CPHA */
+	reg &= ~(SLINK_CMD_IDLE_SCLK_MASK | SLINK_CMD_CK_SDA);
+	if (mode & SPI_CPHA)
+		reg |= SLINK_CMD_CK_SDA;
+
+	if (mode & SPI_CPOL)
+		reg |= SLINK_CMD_IDLE_SCLK_DRIVE_HIGH;
+	else
+		reg |= SLINK_CMD_IDLE_SCLK_DRIVE_LOW;
+
+	writel(reg, &regs->command);
 
 	priv->mode = mode;
 	debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode);
diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c
index 6c21acd..8ccc578 100644
--- a/drivers/spi/xilinx_spi.c
+++ b/drivers/spi/xilinx_spi.c
@@ -247,7 +247,7 @@
 
 	priv->freq = speed;
 
-	debug("xilinx_spi_set_speed: regs=%p, mode=%d\n", priv->regs,
+	debug("xilinx_spi_set_speed: regs=%p, speed=%d\n", priv->regs,
 	      priv->freq);
 
 	return 0;
@@ -260,13 +260,13 @@
 	uint32_t spicr;
 
 	spicr = readl(&regs->spicr);
-	if (priv->mode & SPI_LSB_FIRST)
+	if (mode & SPI_LSB_FIRST)
 		spicr |= SPICR_LSB_FIRST;
-	if (priv->mode & SPI_CPHA)
+	if (mode & SPI_CPHA)
 		spicr |= SPICR_CPHA;
-	if (priv->mode & SPI_CPOL)
+	if (mode & SPI_CPOL)
 		spicr |= SPICR_CPOL;
-	if (priv->mode & SPI_LOOP)
+	if (mode & SPI_LOOP)
 		spicr |= SPICR_LOOP;
 
 	writel(spicr, &regs->spicr);
diff --git a/drivers/spi/zynq_spi.c b/drivers/spi/zynq_spi.c
index 310fb69..d370e49 100644
--- a/drivers/spi/zynq_spi.c
+++ b/drivers/spi/zynq_spi.c
@@ -272,7 +272,8 @@
 	writel(confr, &regs->cr);
 	priv->freq = speed;
 
-	debug("zynq_spi_set_speed: regs=%p, mode=%d\n", priv->regs, priv->freq);
+	debug("zynq_spi_set_speed: regs=%p, speed=%d\n",
+	      priv->regs, priv->freq);
 
 	return 0;
 }
@@ -287,9 +288,9 @@
 	confr = readl(&regs->cr);
 	confr &= ~(ZYNQ_SPI_CR_CPHA_MASK | ZYNQ_SPI_CR_CPOL_MASK);
 
-	if (priv->mode & SPI_CPHA)
+	if (mode & SPI_CPHA)
 		confr |= ZYNQ_SPI_CR_CPHA_MASK;
-	if (priv->mode & SPI_CPOL)
+	if (mode & SPI_CPOL)
 		confr |= ZYNQ_SPI_CR_CPOL_MASK;
 
 	writel(confr, &regs->cr);
diff --git a/drivers/video/mb862xx.c b/drivers/video/mb862xx.c
index 868c512..1c74e97 100644
--- a/drivers/video/mb862xx.c
+++ b/drivers/video/mb862xx.c
@@ -419,7 +419,8 @@
 	board_disp_init ();
 #endif
 
-#if defined(CONFIG_SOCRATES) && !(CONFIG_POST & CONFIG_SYS_POST_SYSMON)
+#if (defined(CONFIG_LWMON5) || \
+     defined(CONFIG_SOCRATES)) && !(CONFIG_POST & CONFIG_SYS_POST_SYSMON)
 	/* Lamp on */
 	board_backlight_switch (1);
 #endif
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 9e9cb55..a007ae8 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -7,7 +7,7 @@
 
 obj-$(CONFIG_AT91SAM9_WATCHDOG) += at91sam9_wdt.o
 obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o
-ifneq (,$(filter $(SOC), mx31 mx35 mx5 mx6 mx7 vf610 ls102xa))
+ifneq (,$(filter $(SOC), mx31 mx35 mx5 mx6 mx7 vf610))
 obj-y += imx_watchdog.o
 endif
 obj-$(CONFIG_S5P)               += s5p_wdt.o
diff --git a/drivers/watchdog/imx_watchdog.c b/drivers/watchdog/imx_watchdog.c
index 9a77a54..0d77595 100644
--- a/drivers/watchdog/imx_watchdog.c
+++ b/drivers/watchdog/imx_watchdog.c
@@ -8,19 +8,7 @@
 #include <asm/io.h>
 #include <watchdog.h>
 #include <asm/arch/imx-regs.h>
-
-struct watchdog_regs {
-	u16	wcr;	/* Control */
-	u16	wsr;	/* Service */
-	u16	wrsr;	/* Reset Status */
-};
-
-#define WCR_WDZST	0x01
-#define WCR_WDBG	0x02
-#define WCR_WDE		0x04	/* WDOG enable */
-#define WCR_WDT		0x08
-#define WCR_SRS		0x10
-#define SET_WCR_WT(x)	(x << 8)
+#include <fsl_wdog.h>
 
 #ifdef CONFIG_IMX_WATCHDOG
 void hw_watchdog_reset(void)
diff --git a/dts/Kconfig b/dts/Kconfig
index 0f4d755..fb2d79e 100644
--- a/dts/Kconfig
+++ b/dts/Kconfig
@@ -37,7 +37,9 @@
 	bool "Embedded DTB for DT control"
 	help
 	  If this option is enabled, the device tree will be picked up and
-	  built into the U-Boot image.
+	  built into the U-Boot image. This is suitable for local debugging
+	  and development only and is not recommended for production devices.
+	  Boards in the mainline U-Boot tree should not use it.
 
 config OF_HOSTFILE
 	bool "Host filed DTB for DT control"
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index adb6940..af828d0 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -555,8 +555,9 @@
 set_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer,
 	     unsigned long size)
 {
-	int idx = 0;
+	__u32 idx = 0;
 	__u32 startsect;
+	int ret;
 
 	if (clustnum > 0)
 		startsect = mydata->data_begin +
@@ -566,26 +567,45 @@
 
 	debug("clustnum: %d, startsect: %d\n", clustnum, startsect);
 
-	if ((size / mydata->sect_size) > 0) {
-		if (disk_write(startsect, size / mydata->sect_size, buffer) < 0) {
-			debug("Error writing data\n");
+	if ((unsigned long)buffer & (ARCH_DMA_MINALIGN - 1)) {
+		ALLOC_CACHE_ALIGN_BUFFER(__u8, tmpbuf, mydata->sect_size);
+
+		printf("FAT: Misaligned buffer address (%p)\n", buffer);
+
+		while (size >= mydata->sect_size) {
+			memcpy(tmpbuf, buffer, mydata->sect_size);
+			ret = disk_write(startsect++, 1, tmpbuf);
+			if (ret != 1) {
+				debug("Error writing data (got %d)\n", ret);
+				return -1;
+			}
+
+			buffer += mydata->sect_size;
+			size -= mydata->sect_size;
+		}
+	} else if (size >= mydata->sect_size) {
+		idx = size / mydata->sect_size;
+		ret = disk_write(startsect, idx, buffer);
+		if (ret != idx) {
+			debug("Error writing data (got %d)\n", ret);
 			return -1;
 		}
+
+		startsect += idx;
+		idx *= mydata->sect_size;
+		buffer += idx;
+		size -= idx;
 	}
 
-	if (size % mydata->sect_size) {
-		__u8 tmpbuf[mydata->sect_size];
+	if (size) {
+		ALLOC_CACHE_ALIGN_BUFFER(__u8, tmpbuf, mydata->sect_size);
 
-		idx = size / mydata->sect_size;
-		buffer += idx * mydata->sect_size;
-		memcpy(tmpbuf, buffer, size % mydata->sect_size);
-
-		if (disk_write(startsect + idx, 1, tmpbuf) < 0) {
-			debug("Error writing data\n");
+		memcpy(tmpbuf, buffer, size);
+		ret = disk_write(startsect, 1, tmpbuf);
+		if (ret != 1) {
+			debug("Error writing data (got %d)\n", ret);
 			return -1;
 		}
-
-		return 0;
 	}
 
 	return 0;
@@ -690,6 +710,14 @@
 
 	debug("%llu bytes\n", filesize);
 
+	if (!curclust) {
+		if (filesize) {
+			debug("error: nonempty clusterless file!\n");
+			return -1;
+		}
+		return 0;
+	}
+
 	actsize = bytesperclust;
 	endclust = curclust;
 	do {
@@ -701,28 +729,17 @@
 				goto getit;
 
 			if (CHECK_CLUST(newclust, mydata->fatsize)) {
-				debug("curclust: 0x%x\n", newclust);
+				debug("newclust: 0x%x\n", newclust);
 				debug("Invalid FAT entry\n");
 				return 0;
 			}
 			endclust = newclust;
 			actsize += bytesperclust;
 		}
-		/* actsize >= file size */
-		actsize -= bytesperclust;
-		/* set remaining clusters */
-		if (set_cluster(mydata, curclust, buffer, (int)actsize) != 0) {
-			debug("error: writing cluster\n");
-			return -1;
-		}
 
 		/* set remaining bytes */
-		*gotsize += actsize;
-		filesize -= actsize;
-		buffer += actsize;
 		actsize = filesize;
-
-		if (set_cluster(mydata, endclust, buffer, (int)actsize) != 0) {
+		if (set_cluster(mydata, curclust, buffer, (int)actsize) != 0) {
 			debug("error: writing cluster\n");
 			return -1;
 		}
@@ -745,8 +762,8 @@
 		filesize -= actsize;
 		buffer += actsize;
 
-		if (CHECK_CLUST(curclust, mydata->fatsize)) {
-			debug("curclust: 0x%x\n", curclust);
+		if (CHECK_CLUST(newclust, mydata->fatsize)) {
+			debug("newclust: 0x%x\n", newclust);
 			debug("Invalid FAT entry\n");
 			return 0;
 		}
@@ -756,15 +773,24 @@
 }
 
 /*
- * Fill dir_entry
+ * Set start cluster in directory entry
  */
-static void fill_dentry(fsdata *mydata, dir_entry *dentptr,
-	const char *filename, __u32 start_cluster, __u32 size, __u8 attr)
+static void set_start_cluster(const fsdata *mydata, dir_entry *dentptr,
+				__u32 start_cluster)
 {
 	if (mydata->fatsize == 32)
 		dentptr->starthi =
 			cpu_to_le16((start_cluster & 0xffff0000) >> 16);
 	dentptr->start = cpu_to_le16(start_cluster & 0xffff);
+}
+
+/*
+ * Fill dir_entry
+ */
+static void fill_dentry(fsdata *mydata, dir_entry *dentptr,
+	const char *filename, __u32 start_cluster, __u32 size, __u8 attr)
+{
+	set_start_cluster(mydata, dentptr, start_cluster);
 	dentptr->size = cpu_to_le32(size);
 
 	dentptr->attr = attr;
@@ -1019,91 +1045,89 @@
 	if (retdent) {
 		/* Update file size and start_cluster in a directory entry */
 		retdent->size = cpu_to_le32(size);
-		start_cluster = FAT2CPU16(retdent->start);
-		if (mydata->fatsize == 32)
-			start_cluster |=
-				(FAT2CPU16(retdent->starthi) << 16);
+		start_cluster = START(retdent);
 
-		ret = check_overflow(mydata, start_cluster, size);
-		if (ret) {
-			printf("Error: %llu overflow\n", size);
-			goto exit;
-		}
+		if (start_cluster) {
+			if (size) {
+				ret = check_overflow(mydata, start_cluster,
+							size);
+				if (ret) {
+					printf("Error: %llu overflow\n", size);
+					goto exit;
+				}
+			}
 
-		ret = clear_fatent(mydata, start_cluster);
-		if (ret) {
-			printf("Error: clearing FAT entries\n");
-			goto exit;
-		}
+			ret = clear_fatent(mydata, start_cluster);
+			if (ret) {
+				printf("Error: clearing FAT entries\n");
+				goto exit;
+			}
 
-		ret = set_contents(mydata, retdent, buffer, size, actwrite);
-		if (ret < 0) {
-			printf("Error: writing contents\n");
-			goto exit;
-		}
-		debug("attempt to write 0x%llx bytes\n", *actwrite);
+			if (!size)
+				set_start_cluster(mydata, retdent, 0);
+		} else if (size) {
+			ret = start_cluster = find_empty_cluster(mydata);
+			if (ret < 0) {
+				printf("Error: finding empty cluster\n");
+				goto exit;
+			}
 
-		/* Flush fat buffer */
-		ret = flush_fat_buffer(mydata);
-		if (ret) {
-			printf("Error: flush fat buffer\n");
-			goto exit;
-		}
+			ret = check_overflow(mydata, start_cluster, size);
+			if (ret) {
+				printf("Error: %llu overflow\n", size);
+				goto exit;
+			}
 
-		/* Write directory table to device */
-		ret = set_cluster(mydata, dir_curclust,
-			    get_dentfromdir_block,
-			    mydata->clust_size * mydata->sect_size);
-		if (ret) {
-			printf("Error: writing directory entry\n");
-			goto exit;
+			set_start_cluster(mydata, retdent, start_cluster);
 		}
 	} else {
 		/* Set short name to set alias checksum field in dir_slot */
 		set_name(empty_dentptr, filename);
 		fill_dir_slot(mydata, &empty_dentptr, filename);
 
-		ret = start_cluster = find_empty_cluster(mydata);
-		if (ret < 0) {
-			printf("Error: finding empty cluster\n");
-			goto exit;
-		}
+		if (size) {
+			ret = start_cluster = find_empty_cluster(mydata);
+			if (ret < 0) {
+				printf("Error: finding empty cluster\n");
+				goto exit;
+			}
 
-		ret = check_overflow(mydata, start_cluster, size);
-		if (ret) {
-			printf("Error: %llu overflow\n", size);
-			goto exit;
+			ret = check_overflow(mydata, start_cluster, size);
+			if (ret) {
+				printf("Error: %llu overflow\n", size);
+				goto exit;
+			}
+		} else {
+			start_cluster = 0;
 		}
 
 		/* Set attribute as archieve for regular file */
 		fill_dentry(mydata, empty_dentptr, filename,
 			start_cluster, size, 0x20);
 
-		ret = set_contents(mydata, empty_dentptr, buffer, size,
-				   actwrite);
-		if (ret < 0) {
-			printf("Error: writing contents\n");
-			goto exit;
-		}
-		debug("attempt to write 0x%llx bytes\n", *actwrite);
-
-		/* Flush fat buffer */
-		ret = flush_fat_buffer(mydata);
-		if (ret) {
-			printf("Error: flush fat buffer\n");
-			goto exit;
-		}
-
-		/* Write directory table to device */
-		ret = set_cluster(mydata, dir_curclust,
-			    get_dentfromdir_block,
-			    mydata->clust_size * mydata->sect_size);
-		if (ret) {
-			printf("Error: writing directory entry\n");
-			goto exit;
-		}
+		retdent = empty_dentptr;
 	}
 
+	ret = set_contents(mydata, retdent, buffer, size, actwrite);
+	if (ret < 0) {
+		printf("Error: writing contents\n");
+		goto exit;
+	}
+	debug("attempt to write 0x%llx bytes\n", *actwrite);
+
+	/* Flush fat buffer */
+	ret = flush_fat_buffer(mydata);
+	if (ret) {
+		printf("Error: flush fat buffer\n");
+		goto exit;
+	}
+
+	/* Write directory table to device */
+	ret = set_cluster(mydata, dir_curclust, get_dentfromdir_block,
+			mydata->clust_size * mydata->sect_size);
+	if (ret)
+		printf("Error: writing directory entry\n");
+
 exit:
 	free(mydata->fatbuf);
 	return ret;
diff --git a/include/common.h b/include/common.h
index 68b24d0..ecb1f06 100644
--- a/include/common.h
+++ b/include/common.h
@@ -826,6 +826,9 @@
 	    u64 startoffs,
 	    u64 szexpected);
 
+/* lib/lz4_wrapper.c */
+int ulz4fn(const void *src, size_t srcn, void *dst, size_t *dstn);
+
 /* lib/qsort.c */
 void qsort(void *base, size_t nmemb, size_t size,
 	   int(*compar)(const void *, const void *));
diff --git a/include/configs/arndale.h b/include/configs/arndale.h
index 437a745..b08f341 100644
--- a/include/configs/arndale.h
+++ b/include/configs/arndale.h
@@ -49,6 +49,10 @@
 /* The PERIPHBASE in the CBAR register is wrong on the Arndale, so override it */
 #define CONFIG_ARM_GIC_BASE_ADDRESS	0x10480000
 
+/* CPU Errata */
+#define CONFIG_ARM_ERRATA_773022
+#define CONFIG_ARM_ERRATA_774769
+
 /* Power */
 #define CONFIG_POWER
 #define CONFIG_POWER_I2C
diff --git a/include/configs/at91-sama5_common.h b/include/configs/at91-sama5_common.h
index 3d6b0ae..a5990cec 100644
--- a/include/configs/at91-sama5_common.h
+++ b/include/configs/at91-sama5_common.h
@@ -53,6 +53,13 @@
 #define CONFIG_CMD_DHCP
 
 #ifdef CONFIG_SYS_USE_MMC
+
+#ifdef CONFIG_ENV_IS_IN_MMC
+/* Use raw reserved sectors to save environment */
+#define CONFIG_ENV_OFFSET		0x2000
+#define CONFIG_ENV_SIZE			0x1000
+#define CONFIG_SYS_MMC_ENV_DEV		0
+#else
 /* u-boot env in sd/mmc card */
 #define CONFIG_ENV_IS_IN_FAT
 #define CONFIG_FAT_WRITE
@@ -60,6 +67,7 @@
 #define FAT_ENV_DEVICE_AND_PART	"0"
 #define FAT_ENV_FILE		"uboot.env"
 #define CONFIG_ENV_SIZE		0x4000
+#endif
 
 #define CONFIG_BOOTCOMMAND	"if test ! -n ${dtb_name}; then "	\
 				    "setenv dtb_name at91-${board_name}.dtb; " \
diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h
index f6bd5fc..02cc09c 100644
--- a/include/configs/ls1021atwr.h
+++ b/include/configs/ls1021atwr.h
@@ -310,12 +310,16 @@
 #define FSL_QSPI_FLASH_NUM		2
 #define CONFIG_SPI_FLASH_STMICRO
 
+/* DSPI */
+#define CONFIG_FSL_DSPI
+#define CONFIG_SPI_FLASH_ATMEL
+#endif
+
 /* DM SPI */
 #if defined(CONFIG_FSL_DSPI) || defined(CONFIG_FSL_QSPI)
 #define CONFIG_CMD_SF
 #define CONFIG_DM_SPI_FLASH
 #endif
-#endif
 
 /*
  * Video
diff --git a/include/configs/lwmon5.h b/include/configs/lwmon5.h
new file mode 100644
index 0000000..26136a5
--- /dev/null
+++ b/include/configs/lwmon5.h
@@ -0,0 +1,633 @@
+/*
+ * (C) Copyright 2007-2013
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * lwmon5.h - configuration for lwmon5 board
+ */
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * Liebherr extra version info
+ */
+#define CONFIG_IDENT_STRING	" - v2.0"
+
+/*
+ * High Level Configuration Options
+ */
+#define CONFIG_LWMON5		1		/* Board is lwmon5	*/
+#define CONFIG_440EPX		1		/* Specific PPC440EPx	*/
+#define CONFIG_440		1		/* ... PPC440 family	*/
+
+#define CONFIG_SYS_GENERIC_BOARD
+
+#define CONFIG_SYS_TEXT_BASE	0xFFF80000
+#define CONFIG_HOSTNAME		lwmon5
+
+#define CONFIG_SYS_CLK_FREQ	33300000	/* external freq to pll	*/
+
+#define CONFIG_4xx_DCACHE		/* enable cache in SDRAM	*/
+
+#define CONFIG_BOARD_EARLY_INIT_F	/* Call board_early_init_f	*/
+#define CONFIG_BOARD_EARLY_INIT_R	/* Call board_early_init_r	*/
+#define CONFIG_BOARD_POSTCLK_INIT	/* Call board_postclk_init	*/
+#define CONFIG_MISC_INIT_R		/* Call misc_init_r		*/
+#define CONFIG_BOARD_RESET		/* Call board_reset		*/
+
+/*
+ * Base addresses -- Note these are effective addresses where the
+ * actual resources get mapped (not physical addresses)
+ */
+#define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE	/* Start of U-Boot	*/
+#define CONFIG_SYS_MONITOR_LEN		0x80000
+#define CONFIG_SYS_MALLOC_LEN		(1 << 20)	/* Reserved for malloc	*/
+
+#define CONFIG_SYS_BOOT_BASE_ADDR	0xf0000000
+#define CONFIG_SYS_SDRAM_BASE		0x00000000	/* _must_ be 0		*/
+#define CONFIG_SYS_FLASH_BASE		0xf8000000	/* start of FLASH	*/
+#define CONFIG_SYS_LIME_BASE_0		0xc0000000
+#define CONFIG_SYS_LIME_BASE_1		0xc1000000
+#define CONFIG_SYS_LIME_BASE_2		0xc2000000
+#define CONFIG_SYS_LIME_BASE_3		0xc3000000
+#define CONFIG_SYS_FPGA_BASE_0		0xc4000000
+#define CONFIG_SYS_FPGA_BASE_1		0xc4200000
+#define CONFIG_SYS_OCM_BASE		0xe0010000      /* ocm			*/
+#define CONFIG_SYS_PCI_BASE		0xe0000000      /* Internal PCI regs	*/
+#define CONFIG_SYS_PCI_MEMBASE		0x80000000	/* mapped pci memory	*/
+#define CONFIG_SYS_PCI_MEMBASE1		(CONFIG_SYS_PCI_MEMBASE  + 0x10000000)
+#define CONFIG_SYS_PCI_MEMBASE2		(CONFIG_SYS_PCI_MEMBASE1 + 0x10000000)
+#define CONFIG_SYS_PCI_MEMBASE3		(CONFIG_SYS_PCI_MEMBASE2 + 0x10000000)
+
+#define CONFIG_SYS_USB2D0_BASE		0xe0000100
+#define CONFIG_SYS_USB_DEVICE		0xe0000000
+#define CONFIG_SYS_USB_HOST		0xe0000400
+
+/*
+ * Initial RAM & stack pointer
+ *
+ * On LWMON5 we use D-cache as init-ram and stack pointer. We also move
+ * the POST_WORD from OCM to a 440EPx register that preserves it's
+ * content during reset (GPT0_COMP6). This way we reserve the OCM (16k)
+ * for logbuffer only. (GPT0_COMP1-COMP5 are reserved for logbuffer header.)
+ */
+#define CONFIG_SYS_INIT_RAM_DCACHE	1		/* d-cache as init ram	*/
+#define CONFIG_SYS_INIT_RAM_ADDR	0x70000000		/* DCache       */
+#define CONFIG_SYS_INIT_RAM_SIZE		(4 << 10)
+#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_INIT_RAM_SIZE - \
+					 GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_OFFSET	CONFIG_SYS_GBL_DATA_OFFSET
+
+/* unused GPT0 COMP reg	*/
+#define CONFIG_SYS_POST_WORD_ADDR	(CONFIG_SYS_PERIPHERAL_BASE + GPT0_COMP6)
+#define CONFIG_SYS_OCM_SIZE		(16 << 10)
+/* 440EPx errata CHIP 11: don't use last 4kbytes */
+#define CONFIG_SYS_MEM_TOP_HIDE		(4 << 10)
+
+/* Additional registers for watchdog timer post test */
+#define CONFIG_SYS_WATCHDOG_TIME_ADDR	(CONFIG_SYS_PERIPHERAL_BASE + GPT0_MASK2)
+#define CONFIG_SYS_WATCHDOG_FLAGS_ADDR	(CONFIG_SYS_PERIPHERAL_BASE + GPT0_MASK1)
+#define CONFIG_SYS_DSPIC_TEST_ADDR	CONFIG_SYS_WATCHDOG_FLAGS_ADDR
+#define CONFIG_SYS_OCM_STATUS_ADDR	CONFIG_SYS_WATCHDOG_FLAGS_ADDR
+#define CONFIG_SYS_WATCHDOG_MAGIC	0x12480000
+#define CONFIG_SYS_WATCHDOG_MAGIC_MASK	0xFFFF0000
+#define CONFIG_SYS_DSPIC_TEST_MASK	0x00000001
+#define CONFIG_SYS_OCM_STATUS_OK	0x00009A00
+#define CONFIG_SYS_OCM_STATUS_FAIL	0x0000A300
+#define CONFIG_SYS_OCM_STATUS_MASK	0x0000FF00
+
+/*
+ * Serial Port
+ */
+#define CONFIG_CONS_INDEX	2	/* Use UART1			*/
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_REG_SIZE	1
+#define CONFIG_SYS_NS16550_CLK		get_serial_clock()
+#undef CONFIG_SYS_EXT_SERIAL_CLOCK		/* no external clock provided	*/
+#define CONFIG_BAUDRATE		115200
+
+#define CONFIG_SYS_BAUDRATE_TABLE						\
+	{300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200}
+
+/*
+ * Environment
+ */
+#define CONFIG_ENV_IS_IN_FLASH		/* use FLASH for environment vars	*/
+
+/*
+ * FLASH related
+ */
+#define CONFIG_SYS_FLASH_CFI			/* The flash is CFI compatible	*/
+#define CONFIG_FLASH_CFI_DRIVER			/* Use common CFI driver	*/
+
+#define CONFIG_SYS_FLASH0		0xFC000000
+#define CONFIG_SYS_FLASH1		0xF8000000
+#define CONFIG_SYS_FLASH_BANKS_LIST	{ CONFIG_SYS_FLASH1, CONFIG_SYS_FLASH0 }
+
+#define CONFIG_SYS_MAX_FLASH_BANKS_DETECT 2	/* max number of memory banks		*/
+#define CONFIG_SYS_MAX_FLASH_SECT	512	/* max number of sectors on one chip	*/
+
+#define CONFIG_SYS_FLASH_ERASE_TOUT	120000	/* Timeout for Flash Erase (in ms)	*/
+#define CONFIG_SYS_FLASH_WRITE_TOUT	500	/* Timeout for Flash Write (in ms)	*/
+
+#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE 	/* use buffered writes (20x faster)	*/
+#define CONFIG_SYS_FLASH_PROTECTION		/* use hardware flash protection	*/
+
+#define CONFIG_SYS_FLASH_EMPTY_INFO		/* print 'E' for empty sector on flinfo */
+#define CONFIG_SYS_FLASH_QUIET_TEST		/* don't warn upon unknown flash	*/
+
+#define CONFIG_ENV_SECT_SIZE	0x40000	/* size of one complete sector		*/
+#define CONFIG_ENV_ADDR		((-CONFIG_SYS_MONITOR_LEN) - CONFIG_ENV_SECT_SIZE)
+#define	CONFIG_ENV_SIZE		0x2000	/* Total Size of Environment Sector	*/
+
+/* Address and size of Redundant Environment Sector	*/
+#define CONFIG_ENV_ADDR_REDUND	(CONFIG_ENV_ADDR - CONFIG_ENV_SECT_SIZE)
+#define CONFIG_ENV_SIZE_REDUND	(CONFIG_ENV_SIZE)
+
+/*
+ * DDR SDRAM
+ */
+#define CONFIG_SYS_MBYTES_SDRAM		256
+#define CONFIG_SYS_DDR_CACHED_ADDR	0x40000000	/* setup 2nd TLB cached here	*/
+#define CONFIG_DDR_DATA_EYE			/* use DDR2 optimization	*/
+#define CONFIG_DDR_ECC				/* enable ECC			*/
+
+/* POST support */
+#define CONFIG_POST		(CONFIG_SYS_POST_CACHE		| \
+				 CONFIG_SYS_POST_CPU		| \
+				 CONFIG_SYS_POST_ECC		| \
+				 CONFIG_SYS_POST_ETHER		| \
+				 CONFIG_SYS_POST_FPU		| \
+				 CONFIG_SYS_POST_I2C		| \
+				 CONFIG_SYS_POST_MEMORY		| \
+				 CONFIG_SYS_POST_OCM		| \
+				 CONFIG_SYS_POST_RTC		| \
+				 CONFIG_SYS_POST_SPR		| \
+				 CONFIG_SYS_POST_UART		| \
+				 CONFIG_SYS_POST_SYSMON		| \
+				 CONFIG_SYS_POST_WATCHDOG	| \
+				 CONFIG_SYS_POST_DSP		| \
+				 CONFIG_SYS_POST_BSPEC1		| \
+				 CONFIG_SYS_POST_BSPEC2		| \
+				 CONFIG_SYS_POST_BSPEC3		| \
+				 CONFIG_SYS_POST_BSPEC4		| \
+				 CONFIG_SYS_POST_BSPEC5)
+
+/* Define here the base-addresses of the UARTs to test in POST */
+#define CONFIG_SYS_POST_UART_TABLE	{ CONFIG_SYS_NS16550_COM1, \
+			CONFIG_SYS_NS16550_COM2 }
+
+#define CONFIG_POST_UART  {				\
+	"UART test",					\
+	"uart",						\
+	"This test verifies the UART operation.",	\
+	POST_RAM | POST_SLOWTEST | POST_ALWAYS | POST_MANUAL,	\
+	&uart_post_test,				\
+	NULL,						\
+	NULL,						\
+	CONFIG_SYS_POST_UART				\
+	}
+
+#define CONFIG_POST_WATCHDOG  {				\
+	"Watchdog timer test",				\
+	"watchdog",					\
+	"This test checks the watchdog timer.",		\
+	POST_RAM | POST_POWERON | POST_SLOWTEST | POST_MANUAL | POST_REBOOT, \
+	&lwmon5_watchdog_post_test,			\
+	NULL,						\
+	NULL,						\
+	CONFIG_SYS_POST_WATCHDOG			\
+	}
+
+#define CONFIG_POST_BSPEC1    {				\
+	"dsPIC init test",				\
+	"dspic_init",					\
+	"This test returns result of dsPIC READY test run earlier.",	\
+	POST_RAM | POST_ALWAYS,				\
+	&dspic_init_post_test,				\
+	NULL,						\
+	NULL,						\
+	CONFIG_SYS_POST_BSPEC1				\
+	}
+
+#define CONFIG_POST_BSPEC2    {				\
+	"dsPIC test",					\
+	"dspic",					\
+	"This test gets result of dsPIC POST and dsPIC version.",	\
+	POST_RAM | POST_ALWAYS,				\
+	&dspic_post_test,				\
+	NULL,						\
+	NULL,						\
+	CONFIG_SYS_POST_BSPEC2				\
+	}
+
+#define CONFIG_POST_BSPEC3    {				\
+	"FPGA test",					\
+	"fpga",						\
+	"This test checks FPGA registers and memory.",	\
+	POST_RAM | POST_ALWAYS | POST_MANUAL,		\
+	&fpga_post_test,				\
+	NULL,						\
+	NULL,						\
+	CONFIG_SYS_POST_BSPEC3				\
+	}
+
+#define CONFIG_POST_BSPEC4    {				\
+	"GDC test",					\
+	"gdc",						\
+	"This test checks GDC registers and memory.",	\
+	POST_RAM | POST_ALWAYS | POST_MANUAL,\
+	&gdc_post_test,					\
+	NULL,						\
+	NULL,						\
+	CONFIG_SYS_POST_BSPEC4				\
+	}
+
+#define CONFIG_POST_BSPEC5    {				\
+	"SYSMON1 test",					\
+	"sysmon1",					\
+	"This test checks GPIO_62_EPX pin indicating power failure.",	\
+	POST_RAM | POST_MANUAL | POST_NORMAL | POST_SLOWTEST,	\
+	&sysmon1_post_test,				\
+	NULL,						\
+	NULL,						\
+	CONFIG_SYS_POST_BSPEC5				\
+	}
+
+#define CONFIG_SYS_POST_CACHE_ADDR	0x7fff0000 /* free virtual address	*/
+#define CONFIG_LOGBUFFER
+/* Reserve GPT0_COMP1-COMP5 for logbuffer header */
+#define CONFIG_ALT_LH_ADDR	(CONFIG_SYS_PERIPHERAL_BASE + GPT0_COMP1)
+#define CONFIG_ALT_LB_ADDR	(CONFIG_SYS_OCM_BASE)
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV /* Otherwise it catches logbuffer as output */
+
+/*
+ * I2C
+ */
+#define CONFIG_SYS_I2C
+#define CONFIG_SYS_I2C_PPC4XX
+#define CONFIG_SYS_I2C_PPC4XX_CH0
+#define CONFIG_SYS_I2C_PPC4XX_SPEED_0		100000
+#define CONFIG_SYS_I2C_PPC4XX_SLAVE_0		0x7F
+
+#define CONFIG_SYS_I2C_RTC_ADDR	0x51	/* RTC				*/
+#define CONFIG_SYS_I2C_EEPROM_CPU_ADDR	0x52	/* EEPROM          (CPU Modul)	*/
+#define CONFIG_SYS_I2C_EEPROM_MB_ADDR	0x53	/* EEPROM AT24C128 (MainBoard)	*/
+#define CONFIG_SYS_I2C_DSPIC_ADDR	0x54	/* dsPIC   			*/
+#define CONFIG_SYS_I2C_DSPIC_2_ADDR	0x55	/* dsPIC			*/
+#define CONFIG_SYS_I2C_DSPIC_KEYB_ADDR	0x56	/* dsPIC			*/
+#define CONFIG_SYS_I2C_DSPIC_IO_ADDR	0x57	/* dsPIC			*/
+
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2	/* Bytes of address		*/
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 6	/* The Atmel AT24C128 has	*/
+					/* 64 byte page write mode using*/
+					/* last 6 bits of the address	*/
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS	10   /* and takes up to 10 msec */
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_ENABLE
+
+#define CONFIG_RTC_PCF8563			/* enable Philips PCF8563 RTC	*/
+#define CONFIG_SYS_I2C_RTC_ADDR		0x51	/* Philips PCF8563 RTC address	*/
+#define CONFIG_SYS_I2C_KEYBD_ADDR	0x56	/* PIC LWE keyboard		*/
+#define CONFIG_SYS_I2C_DSPIC_IO_ADDR	0x57	/* PIC I/O addr               */
+
+#define CONFIG_SYS_POST_I2C_ADDRS	{CONFIG_SYS_I2C_RTC_ADDR,	\
+					 CONFIG_SYS_I2C_EEPROM_CPU_ADDR,\
+					 CONFIG_SYS_I2C_EEPROM_MB_ADDR,	\
+					 CONFIG_SYS_I2C_DSPIC_ADDR,	\
+					 CONFIG_SYS_I2C_DSPIC_2_ADDR,	\
+					 CONFIG_SYS_I2C_DSPIC_KEYB_ADDR,\
+					 CONFIG_SYS_I2C_DSPIC_IO_ADDR }
+
+/*
+ * Pass open firmware flat tree
+ */
+#define CONFIG_OF_LIBFDT
+#define CONFIG_OF_BOARD_SETUP
+/* Update size in "reg" property of NOR FLASH device tree nodes */
+#define CONFIG_FDT_FIXUP_NOR_FLASH_SIZE
+
+#define CONFIG_FIT			/* enable FIT image support	*/
+
+#define	CONFIG_POST_KEY_MAGIC	"3C+3E"	/* press F3 + F5 keys to force POST */
+
+#define	CONFIG_PREBOOT		"setenv bootdelay 15"
+
+#undef	CONFIG_BOOTARGS
+
+#define	CONFIG_EXTRA_ENV_SETTINGS					\
+	"hostname=lwmon5\0"						\
+	"netdev=eth0\0"							\
+	"unlock=yes\0"							\
+	"logversion=2\0"						\
+	"nfsargs=setenv bootargs root=/dev/nfs rw "			\
+		"nfsroot=${serverip}:${rootpath}\0"			\
+	"ramargs=setenv bootargs root=/dev/ram rw\0"			\
+	"addip=setenv bootargs ${bootargs} "				\
+		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"	\
+		":${hostname}:${netdev}:off panic=1\0"			\
+	"addtty=setenv bootargs ${bootargs} console=ttyS1,${baudrate}\0"\
+	"addmisc=setenv bootargs ${bootargs} rtc-pcf8563.probe=0,0x51\0"\
+	"flash_nfs=run nfsargs addip addtty addmisc;"			\
+		"bootm ${kernel_addr}\0"				\
+	"flash_self=run ramargs addip addtty addmisc;"			\
+		"bootm ${kernel_addr} ${ramdisk_addr}\0"		\
+	"net_nfs=tftp 200000 ${bootfile};"				\
+		"run nfsargs addip addtty addmisc;bootm\0"		\
+	"rootpath=/opt/eldk/ppc_4xxFP\0"				\
+	"bootfile=/tftpboot/lwmon5/uImage\0"				\
+	"kernel_addr=FC000000\0"					\
+	"ramdisk_addr=FC180000\0"					\
+	"load=tftp 200000 /tftpboot/${hostname}/u-boot.bin\0"		\
+	"update=protect off FFF80000 FFFFFFFF;era FFF80000 FFFFFFFF;"	\
+		"cp.b 200000 FFF80000 80000\0"			        \
+	"upd=run load update\0"						\
+	"lwe_env=tftp 200000 /tftpboot.dev/lwmon5/env_uboot.bin;"	\
+		"autoscr 200000\0"					\
+	""
+#define CONFIG_BOOTCOMMAND	"run flash_self"
+
+#define CONFIG_BOOTDELAY	5	/* autoboot after 5 seconds	*/
+
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download	*/
+#define CONFIG_SYS_LOADS_BAUD_CHANGE	1	/* allow baudrate change	*/
+
+#define CONFIG_PPC4xx_EMAC
+#define	CONFIG_IBM_EMAC4_V4	1
+#define CONFIG_MII		1	/* MII PHY management		*/
+#define CONFIG_PHY_ADDR		3	/* PHY address, See schematics	*/
+
+#define CONFIG_PHY_RESET        1	/* reset phy upon startup         */
+#define CONFIG_PHY_RESET_DELAY	300
+
+#define CONFIG_HAS_ETH0
+#define CONFIG_SYS_RX_ETH_BUFFER	32	/* Number of ethernet rx buffers & descriptors */
+
+#define CONFIG_HAS_ETH1		1	/* add support for "eth1addr"	*/
+#define CONFIG_PHY1_ADDR	1
+
+/* Video console */
+#define CONFIG_VIDEO
+#define CONFIG_VIDEO_MB862xx
+#define CONFIG_VIDEO_MB862xx_ACCEL
+#define CONFIG_CFB_CONSOLE
+#define CONFIG_VIDEO_LOGO
+#define CONFIG_CONSOLE_EXTRA_INFO
+#define VIDEO_FB_16BPP_PIXEL_SWAP
+#define VIDEO_FB_16BPP_WORD_SWAP
+
+#define CONFIG_VGA_AS_SINGLE_DEVICE
+#define CONFIG_VIDEO_SW_CURSOR
+#define CONFIG_SPLASH_SCREEN
+
+/*
+ * USB/EHCI
+ */
+#define CONFIG_USB_EHCI			/* Enable EHCI USB support	*/
+#define CONFIG_USB_EHCI_PPC4XX		/* on PPC4xx platform		*/
+#define CONFIG_SYS_PPC4XX_USB_ADDR	0xe0000300
+#define CONFIG_EHCI_MMIO_BIG_ENDIAN
+#define CONFIG_EHCI_DESC_BIG_ENDIAN
+#define CONFIG_EHCI_HCD_INIT_AFTER_RESET /* re-init HCD after CMD_RESET */
+#define CONFIG_USB_STORAGE
+
+/* Partitions */
+#define CONFIG_MAC_PARTITION
+#define CONFIG_DOS_PARTITION
+#define CONFIG_ISO_PARTITION
+
+/*
+ * BOOTP options
+ */
+#define CONFIG_BOOTP_BOOTFILESIZE
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+
+/*
+ * Command line configuration.
+ */
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_DATE
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_EEPROM
+#define CONFIG_CMD_ELF
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_IRQ
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_SDRAM
+
+#ifdef CONFIG_VIDEO
+#define CONFIG_CMD_BMP
+#endif
+
+#ifdef CONFIG_440EPX
+#define CONFIG_CMD_USB
+#endif
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SUPPORT_VFAT
+
+#define CONFIG_SYS_LONGHELP			/* undef to save memory		*/
+
+#define CONFIG_SYS_HUSH_PARSER		1	/* Use the HUSH parser		*/
+
+#if defined(CONFIG_CMD_KGDB)
+#define CONFIG_SYS_CBSIZE	        1024	/* Console I/O Buffer Size	*/
+#else
+#define CONFIG_SYS_CBSIZE	        256	/* Console I/O Buffer Size	*/
+#endif
+#define CONFIG_SYS_PBSIZE              (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
+#define CONFIG_SYS_MAXARGS	        16	/* max number of command args	*/
+#define CONFIG_SYS_BARGSIZE	        CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size	*/
+
+#define CONFIG_SYS_MEMTEST_START	0x0400000 /* memtest works on		*/
+#define CONFIG_SYS_MEMTEST_END		0x0C00000 /* 4 ... 12 MB in DRAM	*/
+
+#define CONFIG_SYS_LOAD_ADDR		0x100000  /* default load address	*/
+#define CONFIG_SYS_EXTBDINFO		1	/* To use extended board_into (bd_t) */
+
+#define CONFIG_CMDLINE_EDITING	1	/* add command line history	*/
+#define CONFIG_LOOPW            1       /* enable loopw command         */
+#define CONFIG_MX_CYCLIC        1       /* enable mdc/mwc commands      */
+#define CONFIG_VERSION_VARIABLE 1	/* include version env variable */
+
+#define CONFIG_SYS_CONSOLE_INFO_QUIET	/* don't print console @ startup*/
+
+#ifndef DEBUG
+#define CONFIG_HW_WATCHDOG	1	/* Use external HW-Watchdog	*/
+#endif
+#define CONFIG_WD_PERIOD	40000	/* in usec */
+#define CONFIG_WD_MAX_RATE	66600	/* in ticks */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 16 MB of memory, since this is
+ * the maximum mapped by the 40x Linux kernel during initialization.
+ */
+#define CONFIG_SYS_BOOTMAPSZ		(16 << 20) /* Initial Memory map for Linux */
+#define CONFIG_SYS_BOOTM_LEN		(16 << 20) /* Increase max gunzip size */
+
+/*
+ * External Bus Controller (EBC) Setup
+ */
+#define CONFIG_SYS_FLASH		CONFIG_SYS_FLASH_BASE
+
+/* Memory Bank 0 (NOR-FLASH) initialization					*/
+#define CONFIG_SYS_EBC_PB0AP		0x03000280
+#define CONFIG_SYS_EBC_PB0CR		(CONFIG_SYS_FLASH | 0xfc000)
+
+/* Memory Bank 1 (Lime) initialization						*/
+#define CONFIG_SYS_EBC_PB1AP		0x01004380
+#define CONFIG_SYS_EBC_PB1CR		(CONFIG_SYS_LIME_BASE_0 | 0xbc000)
+
+/* Memory Bank 2 (FPGA) initialization						*/
+#define CONFIG_SYS_EBC_PB2AP		0x01004400
+#define CONFIG_SYS_EBC_PB2CR		(CONFIG_SYS_FPGA_BASE_0 | 0x1c000)
+
+/* Memory Bank 3 (FPGA2) initialization						*/
+#define CONFIG_SYS_EBC_PB3AP		0x01004400
+#define CONFIG_SYS_EBC_PB3CR		(CONFIG_SYS_FPGA_BASE_1 | 0x1c000)
+
+#define CONFIG_SYS_EBC_CFG		0xb8400000
+
+/*
+ * Graphics (Fujitsu Lime)
+ */
+/* SDRAM Clock frequency adjustment register */
+#define CONFIG_SYS_LIME_SDRAM_CLOCK	0xC1FC0038
+#if 1 /* 133MHz is not tested enough, use 100MHz for now */
+/* Lime Clock frequency is to set 100MHz */
+#define CONFIG_SYS_LIME_CLOCK_100MHZ	0x00000
+#else
+/* Lime Clock frequency for 133MHz */
+#define CONFIG_SYS_LIME_CLOCK_133MHZ	0x10000
+#endif
+
+/* SDRAM Parameter register */
+#define CONFIG_SYS_LIME_MMR		0xC1FCFFFC
+/*
+ * SDRAM parameter value; was 0x414FB7F2, caused several vertical bars
+ * and pixel flare on display when 133MHz was configured. According to
+ * SDRAM chip datasheet CAS Latency is 3 for 133MHz and -75 Speed
+ * Grade
+ */
+#ifdef CONFIG_SYS_LIME_CLOCK_133MHZ
+#define CONFIG_SYS_MB862xx_MMR	0x414FB7F3
+#define CONFIG_SYS_MB862xx_CCF	CONFIG_SYS_LIME_CLOCK_133MHZ
+#else
+#define CONFIG_SYS_MB862xx_MMR	0x414FB7F2
+#define CONFIG_SYS_MB862xx_CCF	CONFIG_SYS_LIME_CLOCK_100MHZ
+#endif
+
+/*
+ * GPIO Setup
+ */
+#define CONFIG_SYS_GPIO_PHY1_RST	12
+#define CONFIG_SYS_GPIO_FLASH_WP	14
+#define CONFIG_SYS_GPIO_PHY0_RST	22
+#define CONFIG_SYS_GPIO_PERM_VOLT_FEED	49
+#define CONFIG_SYS_GPIO_DSPIC_READY	51
+#define CONFIG_SYS_GPIO_CAN_ENABLE	53
+#define CONFIG_SYS_GPIO_LSB_ENABLE	54
+#define CONFIG_SYS_GPIO_EEPROM_EXT_WP	55
+#define CONFIG_SYS_GPIO_HIGHSIDE	56
+#define CONFIG_SYS_GPIO_EEPROM_INT_WP	57
+#define CONFIG_SYS_GPIO_BOARD_RESET	58
+#define CONFIG_SYS_GPIO_LIME_S		59
+#define CONFIG_SYS_GPIO_LIME_RST	60
+#define CONFIG_SYS_GPIO_SYSMON_STATUS	62
+#define CONFIG_SYS_GPIO_WATCHDOG	63
+
+#define GPIO49_VAL	1
+
+/*
+ * PPC440 GPIO Configuration
+ */
+#define CONFIG_SYS_4xx_GPIO_TABLE { /*	  Out		  GPIO	Alternate1	Alternate2	Alternate3 */ \
+{											\
+/* GPIO Core 0 */									\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO0	EBC_ADDR(7)	DMA_REQ(2)	*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO1	EBC_ADDR(6)	DMA_ACK(2)	*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO2	EBC_ADDR(5)	DMA_EOT/TC(2)	*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO3	EBC_ADDR(4)	DMA_REQ(3)	*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO4	EBC_ADDR(3)	DMA_ACK(3)	*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO5	EBC_ADDR(2)	DMA_EOT/TC(3)	*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO6	EBC_CS_N(1)			*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO7	EBC_CS_N(2)			*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO8	EBC_CS_N(3)			*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO9	EBC_CS_N(4)			*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO10 EBC_CS_N(5)			*/	\
+{GPIO0_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO11 EBC_BUS_ERR			*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_0}, /* GPIO12				*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_0}, /* GPIO13				*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_1}, /* GPIO14				*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_1}, /* GPIO15				*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO16 GMCTxD(4)			*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO17 GMCTxD(5)			*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO18 GMCTxD(6)			*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO19 GMCTxD(7)			*/	\
+{GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO20 RejectPkt0			*/	\
+{GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO21 RejectPkt1			*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_0}, /* GPIO22				*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO23 SCPD0				*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO24 GMCTxD(2)			*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO25 GMCTxD(3)			*/	\
+{GPIO0_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO26				*/	\
+{GPIO0_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO27 EXT_EBC_REQ	USB2D_RXERROR	*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_0}, /* GPIO28		USB2D_TXVALID	*/	\
+{GPIO0_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_0}, /* GPIO29 EBC_EXT_HDLA	USB2D_PAD_SUSPNDM */	\
+{GPIO0_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO30 EBC_EXT_ACK	USB2D_XCVRSELECT*/	\
+{GPIO0_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO31 EBC_EXR_BUSREQ	USB2D_TERMSELECT*/	\
+},											\
+{											\
+/* GPIO Core 1 */									\
+{GPIO1_BASE, GPIO_IN , GPIO_ALT2, GPIO_OUT_0}, /* GPIO32 USB2D_OPMODE0	EBC_DATA(2)	*/	\
+{GPIO1_BASE, GPIO_IN , GPIO_ALT2, GPIO_OUT_0}, /* GPIO33 USB2D_OPMODE1	EBC_DATA(3)	*/	\
+{GPIO1_BASE, GPIO_OUT, GPIO_ALT3, GPIO_OUT_0}, /* GPIO34 UART0_DCD_N	UART1_DSR_CTS_N	UART2_SOUT*/ \
+{GPIO1_BASE, GPIO_IN , GPIO_ALT3, GPIO_OUT_0}, /* GPIO35 UART0_8PIN_DSR_N UART1_RTS_DTR_N UART2_SIN*/ \
+{GPIO1_BASE, GPIO_IN , GPIO_ALT2, GPIO_OUT_0}, /* GPIO36 UART0_8PIN_CTS_N EBC_DATA(0)	UART3_SIN*/ \
+{GPIO1_BASE, GPIO_OUT, GPIO_ALT2, GPIO_OUT_0}, /* GPIO37 UART0_RTS_N	EBC_DATA(1)	UART3_SOUT*/ \
+{GPIO1_BASE, GPIO_OUT, GPIO_ALT2, GPIO_OUT_0}, /* GPIO38 UART0_DTR_N	UART1_SOUT	*/	\
+{GPIO1_BASE, GPIO_IN , GPIO_ALT2, GPIO_OUT_0}, /* GPIO39 UART0_RI_N	UART1_SIN	*/	\
+{GPIO1_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO40 UIC_IRQ(0)			*/	\
+{GPIO1_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO41 UIC_IRQ(1)			*/	\
+{GPIO1_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO42 UIC_IRQ(2)			*/	\
+{GPIO1_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO43 UIC_IRQ(3)			*/	\
+{GPIO1_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO44 UIC_IRQ(4)	DMA_ACK(1)	*/	\
+{GPIO1_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO45 UIC_IRQ(6)	DMA_EOT/TC(1)	*/	\
+{GPIO1_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO46 UIC_IRQ(7)	DMA_REQ(0)	*/	\
+{GPIO1_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO47 UIC_IRQ(8)	DMA_ACK(0)	*/	\
+{GPIO1_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO48 UIC_IRQ(9)	DMA_EOT/TC(0)	*/	\
+{GPIO1_BASE, GPIO_OUT, GPIO_SEL , GPIO49_VAL}, /* GPIO49  Unselect via TraceSelect Bit	*/	\
+{GPIO1_BASE, GPIO_IN,  GPIO_SEL , GPIO_OUT_0}, /* GPIO50  Unselect via TraceSelect Bit	*/	\
+{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO51  Unselect via TraceSelect Bit	*/	\
+{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO52  Unselect via TraceSelect Bit	*/	\
+{GPIO1_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_0}, /* GPIO53  Unselect via TraceSelect Bit	*/	\
+{GPIO1_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_0}, /* GPIO54  Unselect via TraceSelect Bit	*/	\
+{GPIO1_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_1}, /* GPIO55  Unselect via TraceSelect Bit	*/	\
+{GPIO1_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_0}, /* GPIO56  Unselect via TraceSelect Bit	*/	\
+{GPIO1_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_1}, /* GPIO57  Unselect via TraceSelect Bit	*/	\
+{GPIO1_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_0}, /* GPIO58  Unselect via TraceSelect Bit	*/	\
+{GPIO1_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_0}, /* GPIO59  Unselect via TraceSelect Bit	*/	\
+{GPIO1_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_0}, /* GPIO60  Unselect via TraceSelect Bit	*/	\
+{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO61  Unselect via TraceSelect Bit	*/	\
+{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO62  Unselect via TraceSelect Bit	*/	\
+{GPIO1_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_0}, /* GPIO63  Unselect via TraceSelect Bit	*/	\
+}											\
+}
+
+#if defined(CONFIG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE	230400	/* speed to run kgdb serial port */
+#endif
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/pcm052.h b/include/configs/pcm052.h
index 903f94c..150698e 100644
--- a/include/configs/pcm052.h
+++ b/include/configs/pcm052.h
@@ -60,14 +60,15 @@
 #define CONFIG_CMD_MTDPARTS
 #define CONFIG_MTD_PARTITIONS
 #define CONFIG_MTD_DEVICE
-#define MTDIDS_DEFAULT			"nand0=NAND,nor0=qspi0-a,nor1=qspi0-b"
+#define MTDIDS_DEFAULT			"nand0=NAND"
 #define MTDPARTS_DEFAULT		"mtdparts=NAND:256k(spare)"\
 					",384k(bootloader)"\
 					",128k(env1)"\
 					",128k(env2)"\
-					",3840k(kernel)"\
-					",-(rootfs)"\
-					",qspi0-a:-(jffs2),qspio0-b:-(jffs2)"
+					",128k(dtb)"\
+					",6144k(kernel)"\
+					",65536k(ramdisk)"\
+					",450944k(root)"
 #endif
 
 #define CONFIG_MMC
@@ -135,36 +136,85 @@
 #define CONFIG_BOARD_SIZE_LIMIT		524288
 
 #define CONFIG_BOOTCOMMAND              "run bootcmd_sd"
-#define CONFIG_EXTRA_ENV_SETTINGS                                       \
-	"bootfile=uImage\0"                             \
-	"bootargs_base=setenv bootargs rw mem=256M "                    \
-		"console=ttymxc1,115200n8\0"            \
-	"bootargs_sd=setenv bootargs ${bootargs} "                      \
-		"root=/dev/mmcblk0p2 rootwait\0"        \
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"fdt_high=0xffffffff\0" \
+	"initrd_high=0xffffffff\0" \
+	"blimg_file=u-boot.imx\0" \
+	"blsec_addr=0x81000000\0" \
+	"blimg_addr=0x81000400\0" \
+	"kernel_file=zImage\0" \
+	"kernel_addr=0x82000000\0" \
+	"fdt_file=vf610-pcm052.dtb\0" \
+	"fdt_addr=0x81000000\0" \
+	"ram_file=uRamdisk\0" \
+	"ram_addr=0x83000000\0" \
+	"filesys=rootfs.ubifs\0" \
+	"sys_addr=0x81000000\0" \
+	"tftploc=/path/to/tftp/directory/\0" \
+	"nfs_root=/path/to/nfs/root\0" \
+	"tftptimeout=1000\0" \
+	"tftptimeoutcountmax=1000000\0" \
+	"mtdparts=" MTDPARTS_DEFAULT "\0" \
+	"bootargs_base=setenv bootargs rw mem=256M " \
+		"console=ttyLP1,115200n8\0" \
+	"bootargs_sd=setenv bootargs ${bootargs} " \
+		"root=/dev/mmcblk0p2 rootwait\0" \
 	"bootargs_net=setenv bootargs ${bootargs} root=/dev/nfs ip=dhcp " \
-		"nfsroot=${serverip}:${nfs_root},v3,tcp\0"              \
-	"bootargs_nand=setenv bootargs ${bootargs} "                    \
-		"root=/dev/mtdblock2 rootfstype=jffs2\0"                \
-	"bootargs_mtd=setenv bootargs ${bootargs} ${mtdparts}\0"        \
-	"bootcmd_sd=run bootargs_base bootargs_sd bootargs_mtd; mmc rescan; " \
-		"fatload mmc 0:1 ${loadaddr} ${bootfile}; bootm ${loadaddr}\0" \
-	"bootcmd_net=run bootargs_base bootargs_net bootargs_mtd; "     \
-		"tftpboot ${loadaddr} ${tftploc}${bootfile}; bootm\0"   \
-	"bootcmd_nand='run bootargs_base bootargs_nand bootargs_mtd; "  \
-		"nand read ${loadaddr} 0x000E0000 0x3C0000; "           \
-		"bootm ${loadaddr}\0"                                   \
-	"tftploc=/path/to/tftp/directory/\0"                            \
-	"nfs_root=/path/to/nfs/root\0"                                  \
-	"mtdparts=" MTDPARTS_DEFAULT "\0"                               \
-	"update_kernel_from_sd=mw.b $(loadaddr) 0xff 0x3C0000; "        \
-		"mmc rescan; fatload mmc 0:2 ${loadaddr} ${bootfile}; " \
-		"nand erase 0xE0000 0x3C0000; "                         \
-		"nand write.i ${loadaddr} 0xE0000 0x3C0000\0"           \
-	"update_rootfs_from_tftp=mw.b ${loadaddr} 0xff 0x8F20000; "     \
-		"tftp ${loadaddr} ${tftp}${filesys}; "                  \
-		"nand erase 0x4A0000 0x8F20000; "                       \
-		"nand write.i ${loadaddr} 0x4A0000 0x8F20000\0"         \
-	"filesys=rootfs.jffs2\0"
+		"nfsroot=${serverip}:${nfs_root},v3,tcp\0" \
+	"bootargs_nand=setenv bootargs ${bootargs} " \
+		"ubi.mtd=6 rootfstype=ubifs root=ubi0:rootfs\0" \
+	"bootargs_ram=setenv bootargs ${bootargs} " \
+		"root=/dev/ram rw initrd=${ram_addr}\0" \
+	"bootargs_mtd=setenv bootargs ${bootargs} ${mtdparts}\0" \
+	"bootcmd_sd=run bootargs_base bootargs_sd bootargs_mtd; " \
+		"fatload mmc 0:1 ${kernel_addr} ${kernel_file}; " \
+		"fatload mmc 0:1 ${fdt_addr} ${fdt_file}; " \
+		"bootz ${kernel_addr} - ${fdt_addr}\0" \
+	"bootcmd_net=run bootargs_base bootargs_net bootargs_mtd; " \
+		"tftpboot ${kernel_addr} ${tftpdir}${kernel_file}; " \
+		"tftpboot ${fdt_addr} ${tftpdir}${fdt_file}; " \
+		"bootz ${kernel_addr} - ${fdt_addr}\0" \
+	"bootcmd_nand=run bootargs_base bootargs_nand bootargs_mtd; " \
+		"nand read ${fdt_addr} dtb; " \
+		"nand read ${kernel_addr} kernel; " \
+		"bootz ${kernel_addr} - ${fdt_addr}\0" \
+	"bootcmd_ram=run bootargs_base bootargs_ram bootargs_mtd; " \
+		"nand read ${fdt_addr} dtb; " \
+		"nand read ${kernel_addr} kernel; " \
+		"nand read ${ram_addr} ramdisk; " \
+		"bootz ${kernel_addr} ${ram_addr} ${fdt_addr}\0" \
+	"update_bootloader_from_tftp=mtdparts default; " \
+		"nand read ${blsec_addr} bootloader; " \
+		"mw.b ${blimg_addr} 0xff 0x5FC00; " \
+		"if tftp ${blimg_addr} ${tftpdir}${blimg_file}; then " \
+		"nand erase.part bootloader; " \
+		"nand write ${blsec_addr} bootloader ${filesize}; fi\0" \
+	"update_kernel_from_sd=if fatload mmc 0:2 ${kernel_addr} " \
+		"${kernel_file}; " \
+		"then mtdparts default; " \
+		"nand erase.part kernel; " \
+		"nand write ${kernel_addr} kernel ${filesize}; " \
+		"if fatload mmc 0:2 ${fdt_addr} ${fdt_file}; then " \
+		"nand erase.part dtb; " \
+		"nand write ${fdt_addr} dtb ${filesize}; fi\0" \
+	"update_kernel_from_tftp=if tftp ${fdt_addr} ${tftpdir}${fdt_file}; " \
+		"then setenv fdtsize ${filesize}; " \
+		"if tftp ${kernel_addr} ${tftpdir}${kernel_file}; then " \
+		"mtdparts default; " \
+		"nand erase.part dtb; " \
+		"nand write ${fdt_addr} dtb ${fdtsize}; " \
+		"nand erase.part kernel; " \
+		"nand write ${kernel_addr} kernel ${filesize}; fi; fi\0" \
+	"update_rootfs_from_tftp=if tftp ${sys_addr} ${tftpdir}${filesys}; " \
+		"then mtdparts default; " \
+		"nand erase.part root; " \
+		"ubi part root; " \
+		"ubi create rootfs; " \
+		"ubi write ${sys_addr} rootfs ${filesize}; fi\0" \
+	"update_ramdisk_from_tftp=if tftp ${ram_addr} ${tftpdir}${ram_file}; " \
+		"then mtdparts default; " \
+		"nand erase.part ramdisk; " \
+		"nand write ${ram_addr} ramdisk ${filesize}; fi\0"
 
 /* miscellaneous commands */
 #define CONFIG_CMD_ELF
@@ -220,9 +270,9 @@
 #ifdef CONFIG_ENV_IS_IN_NAND
 #define CONFIG_ENV_SECT_SIZE		(128 * 1024)
 #define CONFIG_ENV_SIZE			(8 * 1024)
-#define CONFIG_ENV_OFFSET		0x80000
+#define CONFIG_ENV_OFFSET		0xA0000
 #define CONFIG_ENV_SIZE_REDUND		(8 * 1024)
-#define CONFIG_ENV_OFFSET_REDUND	0xA0000
+#define CONFIG_ENV_OFFSET_REDUND	0xC0000
 #endif
 
 #define CONFIG_OF_LIBFDT
diff --git a/include/configs/smartweb.h b/include/configs/smartweb.h
index d189c3f..e11c016 100644
--- a/include/configs/smartweb.h
+++ b/include/configs/smartweb.h
@@ -117,6 +117,9 @@
  *
  */
 #define CONFIG_MACB
+#define CONFIG_USB_HOST_ETHER
+#define CONFIG_USB_ETHER_ASIX
+#define CONFIG_USB_ETHER_MCS7830
 #define CONFIG_RMII			/* use reduced MII inteface */
 #define CONFIG_NET_RETRY_COUNT	20      /* # of DHCP/BOOTP retries */
 #define CONFIG_AT91_WANTS_COMMON_PHY
@@ -182,6 +185,7 @@
 /* General Boot Parameter */
 #define CONFIG_BOOTDELAY		3
 #define CONFIG_BOOTCOMMAND		"run flashboot"
+#define CONFIG_BOOT_RETRY_TIME          30
 #define CONFIG_SYS_CBSIZE		512
 #define CONFIG_SYS_MAXARGS		16
 #define CONFIG_SYS_PBSIZE \
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 48cc4ed..e1ba791 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -13,6 +13,7 @@
 #ifndef _SUNXI_COMMON_CONFIG_H
 #define _SUNXI_COMMON_CONFIG_H
 
+#include <asm/arch/cpu.h>
 #include <linux/stringify.h>
 
 #ifdef CONFIG_OLD_SUNXI_KERNEL_COMPAT
@@ -39,23 +40,14 @@
 #define CONFIG_SYS_THUMB_BUILD	/* Thumbs mode to save space in SPL */
 #endif
 
-#include <asm/arch/cpu.h>	/* get chip and board defs */
-
-#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_DM_SERIAL)
-# define CONFIG_DW_SERIAL
-#endif
-
-/*
- * Display CPU information
- */
-#define CONFIG_DISPLAY_CPUINFO
-
 /* Serial & console */
 #define CONFIG_SYS_NS16550
 #define CONFIG_SYS_NS16550_SERIAL
 /* ns16550 reg in the low bits of cpu reg */
 #define CONFIG_SYS_NS16550_CLK		24000000
-#ifndef CONFIG_DM_SERIAL
+#ifdef CONFIG_DM_SERIAL
+# define CONFIG_DW_SERIAL
+#else
 # define CONFIG_SYS_NS16550_REG_SIZE	-4
 # define CONFIG_SYS_NS16550_COM1		SUNXI_UART0_BASE
 # define CONFIG_SYS_NS16550_COM2		SUNXI_UART1_BASE
@@ -65,6 +57,7 @@
 #endif
 
 /* CPU */
+#define CONFIG_DISPLAY_CPUINFO
 #define CONFIG_SYS_CACHELINE_SIZE	64
 
 /*
@@ -152,8 +145,8 @@
 #define CONFIG_SYS_MMC_ENV_DEV		0	/* first detected MMC controller */
 #endif
 
-/* 4MB of malloc() pool */
-#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + (4 << 20))
+/* 64MB of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + (64 << 20))
 
 /*
  * Miscellaneous configurable options
@@ -282,11 +275,7 @@
  * The amount of RAM to keep free at the top of RAM when relocating u-boot,
  * to use as framebuffer. This must be a multiple of 4096.
  */
-#ifdef CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804
-#define CONFIG_SUNXI_MAX_FB_SIZE (12 << 20)
-#else
-#define CONFIG_SUNXI_MAX_FB_SIZE (9 << 20)
-#endif
+#define CONFIG_SUNXI_MAX_FB_SIZE (16 << 20)
 
 /* Do we want to initialize a simple FB? */
 #define CONFIG_VIDEO_DT_SIMPLEFB
@@ -393,12 +382,12 @@
 #define CONFIG_PRE_CON_BUF_SZ		4096 /* Aprox 2 80*25 screens */
 
 /*
- * 240M RAM (256M minimum minus space for the framebuffer),
+ * 160M RAM (256M minimum minus 64MB heap + 32MB for u-boot, stack, fb, etc.
  * 32M uncompressed kernel, 16M compressed kernel, 1M fdt,
  * 1M script, 1M pxe and the ramdisk at the end.
  */
 #define MEM_LAYOUT_ENV_SETTINGS \
-	"bootm_size=0xf000000\0" \
+	"bootm_size=0xa000000\0" \
 	"kernel_addr_r=" __stringify(SDRAM_OFFSET(2000000)) "\0" \
 	"fdt_addr_r=" __stringify(SDRAM_OFFSET(3000000)) "\0" \
 	"scriptaddr=" __stringify(SDRAM_OFFSET(3100000)) "\0" \
@@ -423,7 +412,18 @@
 #define BOOT_TARGET_DEVICES_USB(func)
 #endif
 
+/* FEL boot support, auto-execute boot.scr if a script address was provided */
+#define BOOTENV_DEV_FEL(devtypeu, devtypel, instance) \
+	"bootcmd_fel=" \
+		"if test -n ${fel_booted} && test -n ${fel_scriptaddr}; then " \
+			"echo '(FEL boot)'; " \
+			"source ${fel_scriptaddr}; " \
+		"fi\0"
+#define BOOTENV_DEV_NAME_FEL(devtypeu, devtypel, instance) \
+	"fel "
+
 #define BOOT_TARGET_DEVICES(func) \
+	func(FEL, fel, na) \
 	BOOT_TARGET_DEVICES_MMC(func) \
 	BOOT_TARGET_DEVICES_SCSI(func) \
 	BOOT_TARGET_DEVICES_USB(func) \
diff --git a/include/configs/tegra114-common.h b/include/configs/tegra114-common.h
index 252e607..671071b 100644
--- a/include/configs/tegra114-common.h
+++ b/include/configs/tegra114-common.h
@@ -34,7 +34,7 @@
 /*-----------------------------------------------------------------------
  * Physical Memory Map
  */
-#define CONFIG_SYS_TEXT_BASE	0x8010E000
+#define CONFIG_SYS_TEXT_BASE	0x80110000
 
 /*
  * Memory layout for where various images get loaded by boot scripts:
diff --git a/include/configs/tegra20-common.h b/include/configs/tegra20-common.h
index 0841f33..00e85c4 100644
--- a/include/configs/tegra20-common.h
+++ b/include/configs/tegra20-common.h
@@ -32,7 +32,7 @@
 /*-----------------------------------------------------------------------
  * Physical Memory Map
  */
-#define CONFIG_SYS_TEXT_BASE	0x0010E000
+#define CONFIG_SYS_TEXT_BASE	0x00110000
 
 /*
  * Memory layout for where various images get loaded by boot scripts:
diff --git a/include/configs/tegra210-common.h b/include/configs/tegra210-common.h
index e6c8152..8f35a7b 100644
--- a/include/configs/tegra210-common.h
+++ b/include/configs/tegra210-common.h
@@ -26,7 +26,7 @@
 /*-----------------------------------------------------------------------
  * Physical Memory Map
  */
-#define CONFIG_SYS_TEXT_BASE	0x8010E000
+#define CONFIG_SYS_TEXT_BASE	0x80110000
 
 /* Generic Interrupt Controller */
 #define CONFIG_GICV2
diff --git a/include/configs/tegra30-common.h b/include/configs/tegra30-common.h
index 3e8e3c1..9afd864 100644
--- a/include/configs/tegra30-common.h
+++ b/include/configs/tegra30-common.h
@@ -31,7 +31,7 @@
 /*-----------------------------------------------------------------------
  * Physical Memory Map
  */
-#define CONFIG_SYS_TEXT_BASE	0x8010E000
+#define CONFIG_SYS_TEXT_BASE	0x80110000
 
 /*
  * Memory layout for where various images get loaded by boot scripts:
diff --git a/include/configs/ti_omap3_common.h b/include/configs/ti_omap3_common.h
index be231a5..e399a87 100644
--- a/include/configs/ti_omap3_common.h
+++ b/include/configs/ti_omap3_common.h
@@ -66,7 +66,7 @@
 #define CONFIG_SYS_MONITOR_LEN		(256 << 10)
 
 /* TWL4030 */
-#define CONFIG_TWL4030_POWER		1
+#define CONFIG_TWL4030_POWER
 
 /* SPL */
 #define CONFIG_SPL_TEXT_BASE		0x40200800
diff --git a/include/configs/vexpress_aemv8a.h b/include/configs/vexpress_aemv8a.h
index 6107c64..ef3014d 100644
--- a/include/configs/vexpress_aemv8a.h
+++ b/include/configs/vexpress_aemv8a.h
@@ -30,7 +30,8 @@
 #define CONFIG_BOOTP_VCI_STRING		"U-boot.armv8.vexpress_aemv8a"
 
 /* Link Definitions */
-#ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP
+#if defined(CONFIG_TARGET_VEXPRESS64_BASE_FVP) || \
+	defined(CONFIG_TARGET_VEXPRESS64_BASE_FVP_DRAM)
 /* ATF loads u-boot here for BASE_FVP model */
 #define CONFIG_SYS_TEXT_BASE		0x88000000
 #define CONFIG_SYS_INIT_SP_ADDR         (CONFIG_SYS_SDRAM_BASE + 0x03f00000)
@@ -41,6 +42,8 @@
 #error "Unknown board variant"
 #endif
 
+#define CONFIG_SYS_BOOTM_LEN (64 << 20)      /* Increase max gunzip size */
+
 /* Flat Device Tree Definitions */
 #define CONFIG_OF_LIBFDT
 
@@ -101,7 +104,8 @@
 #define GICR_BASE			(0x2f100000)
 #else
 
-#ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP
+#if defined(CONFIG_TARGET_VEXPRESS64_BASE_FVP) || \
+	defined(CONFIG_TARGET_VEXPRESS64_BASE_FVP_DRAM)
 #define GICD_BASE			(0x2f000000)
 #define GICC_BASE			(0x2c000000)
 #elif CONFIG_TARGET_VEXPRESS64_JUNO
@@ -183,25 +187,46 @@
  * be copied into DRAM
  */
 #define CONFIG_EXTRA_ENV_SETTINGS	\
-				"kernel_name=Image\0"	\
+				"kernel_name=norkern\0"	\
+				"kernel_alt_name=Image\0"	\
 				"kernel_addr=0x80000000\0" \
-				"fdt_name=juno\0" \
+				"initrd_name=ramdisk.img\0"	\
+				"initrd_addr=0x84000000\0"	\
+				"fdt_name=board.dtb\0" \
+				"fdt_alt_name=juno\0" \
 				"fdt_addr=0x83000000\0" \
 				"fdt_high=0xffffffffffffffff\0" \
 				"initrd_high=0xffffffffffffffff\0" \
 
 /* Assume we boot with root on the first partition of a USB stick */
 #define CONFIG_BOOTARGS		"console=ttyAMA0,115200n8 " \
-				"root=/dev/sda1 rw " \
+				"root=/dev/sda2 rw " \
 				"rootwait "\
-				"earlyprintk=pl011,0x7ff80000 debug user_debug=31 "\
+				"earlyprintk=pl011,0x7ff80000 debug "\
+				"user_debug=31 "\
+				"androidboot.hardware=juno "\
 				"loglevel=9"
 
 /* Copy the kernel and FDT to DRAM memory and boot */
 #define CONFIG_BOOTCOMMAND	"afs load ${kernel_name} ${kernel_addr} ; " \
+				"if test $? -eq 1; then "\
+				"  echo Loading ${kernel_alt_name} instead of "\
+				"${kernel_name}; "\
+				"  afs load ${kernel_alt_name} ${kernel_addr};"\
+				"fi ; "\
 				"afs load  ${fdt_name} ${fdt_addr} ; " \
+				"if test $? -eq 1; then "\
+				"  echo Loading ${fdt_alt_name} instead of "\
+				"${fdt_name}; "\
+				"  afs load ${fdt_alt_name} ${fdt_addr}; "\
+				"fi ; "\
 				"fdt addr ${fdt_addr}; fdt resize; " \
-				"booti ${kernel_addr} - ${fdt_addr}"
+				"if afs load  ${initrd_name} ${initrd_addr} ; "\
+				"then "\
+				"  setenv initrd_param ${initrd_addr}; "\
+				"  else setenv initrd_param -; "\
+				"fi ; " \
+				"booti ${kernel_addr} ${initrd_param} ${fdt_addr}"
 
 #define CONFIG_BOOTDELAY		1
 
@@ -222,13 +247,33 @@
 
 #define CONFIG_BOOTCOMMAND	"smhload ${kernel_name} ${kernel_addr}; " \
 				"smhload ${fdt_name} ${fdt_addr}; " \
-				"smhload ${initrd_name} ${initrd_addr} initrd_end; " \
+				"smhload ${initrd_name} ${initrd_addr} "\
+				"initrd_end; " \
 				"fdt addr ${fdt_addr}; fdt resize; " \
 				"fdt chosen ${initrd_addr} ${initrd_end}; " \
 				"booti $kernel_addr - $fdt_addr"
 
 #define CONFIG_BOOTDELAY		1
 
+#elif CONFIG_TARGET_VEXPRESS64_BASE_FVP_DRAM
+#define CONFIG_EXTRA_ENV_SETTINGS	\
+				"kernel_addr=0x80080000\0"	\
+				"initrd_addr=0x84000000\0"	\
+				"fdt_addr=0x83000000\0"		\
+				"fdt_high=0xffffffffffffffff\0"	\
+				"initrd_high=0xffffffffffffffff\0"
+
+#define CONFIG_BOOTARGS		"console=ttyAMA0 earlyprintk=pl011,"\
+				"0x1c090000 debug user_debug=31 "\
+				"androidboot.hardware=fvpbase "\
+				"root=/dev/vda2 rw "\
+				"rootwait "\
+				"loglevel=9"
+
+#define CONFIG_BOOTCOMMAND	"booti $kernel_addr $initrd_addr $fdt_addr"
+
+#define CONFIG_BOOTDELAY		1
+
 #else
 #error "Unknown board variant"
 #endif
diff --git a/include/fsl_wdog.h b/include/fsl_wdog.h
new file mode 100644
index 0000000..d15a70c
--- /dev/null
+++ b/include/fsl_wdog.h
@@ -0,0 +1,18 @@
+/*
+ * (C) Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+struct watchdog_regs {
+	u16	wcr;	/* Control */
+	u16	wsr;	/* Service */
+	u16	wrsr;	/* Reset Status */
+};
+
+#define WCR_WDZST	0x01
+#define WCR_WDBG	0x02
+#define WCR_WDE		0x04
+#define WCR_WDT		0x08
+#define WCR_SRS		0x10
+#define SET_WCR_WT(x)	(x << 8)
diff --git a/include/image.h b/include/image.h
index 8a864ae..08ae24a 100644
--- a/include/image.h
+++ b/include/image.h
@@ -259,6 +259,7 @@
 #define IH_COMP_BZIP2		2	/* bzip2 Compression Used	*/
 #define IH_COMP_LZMA		3	/* lzma  Compression Used	*/
 #define IH_COMP_LZO		4	/* lzo   Compression Used	*/
+#define IH_COMP_LZ4		5	/* lz4   Compression Used	*/
 
 #define IH_MAGIC	0x27051956	/* Image Magic Number		*/
 #define IH_NMLEN		32	/* Image Name Length		*/
diff --git a/include/net.h b/include/net.h
index f1671e3..3a787cc 100644
--- a/include/net.h
+++ b/include/net.h
@@ -149,7 +149,9 @@
  */
 struct udevice *eth_get_dev_by_name(const char *devname);
 unsigned char *eth_get_ethaddr(void); /* get the current device MAC */
+
 /* Used only when NetConsole is enabled */
+int eth_is_active(struct udevice *dev); /* Test device for active state */
 int eth_init_state_only(void); /* Set active state */
 void eth_halt_state_only(void); /* Set passive state */
 #endif
@@ -195,6 +197,8 @@
 	return NULL;
 }
 
+/* Used only when NetConsole is enabled */
+int eth_is_active(struct eth_device *dev); /* Test device for active state */
 /* Set active state */
 static inline __attribute__((always_inline)) int eth_init_state_only(void)
 {
diff --git a/lib/Kconfig b/lib/Kconfig
index 0673072..a8f8460 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -100,6 +100,24 @@
 	  is performed in hardware.
 endmenu
 
+menu "Compression Support"
+
+config LZ4
+	bool "Enable LZ4 decompression support"
+	help
+	  If this option is set, support for LZ4 compressed images
+	  is included. The LZ4 algorithm can run in-place as long as the
+	  compressed image is loaded to the end of the output buffer, and
+	  trades lower compression ratios for much faster decompression.
+	  
+	  NOTE: This implements the release version of the LZ4 frame
+	  format as generated by default by the 'lz4' command line tool.
+	  This is not the same as the outdated, less efficient legacy
+	  frame format currently (2015) implemented in the Linux kernel
+	  (generated by 'lz4 -l'). The two formats are incompatible.
+
+endmenu
+
 config ERRNO_STR
 	bool "Enable function for getting errno-related string message"
 	help
diff --git a/lib/Makefile b/lib/Makefile
index 96f832e..3eecefa 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -34,6 +34,7 @@
 obj-y += initcall.o
 obj-$(CONFIG_LMB) += lmb.o
 obj-y += ldiv.o
+obj-$(CONFIG_LZ4) += lz4_wrapper.o
 obj-$(CONFIG_MD5) += md5.o
 obj-y += net_utils.o
 obj-$(CONFIG_PHYSMEM) += physmem.o
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 9f0b65d..1a86369 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -149,7 +149,7 @@
 	}
 
 	ns = fdt_size_cells(blob, parent);
-	if (ns < 1) {
+	if (ns < 0) {
 		debug("(bad #size-cells)\n");
 		return FDT_ADDR_T_NONE;
 	}
@@ -180,10 +180,11 @@
 fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
 		const char *prop_name, fdt_size_t *sizep)
 {
+	int ns = sizep ? (sizeof(fdt_size_t) / sizeof(fdt32_t)) : 0;
+
 	return fdtdec_get_addr_size_fixed(blob, node, prop_name, 0,
 					  sizeof(fdt_addr_t) / sizeof(fdt32_t),
-					  sizeof(fdt_size_t) / sizeof(fdt32_t),
-					  sizep);
+					  ns, sizep);
 }
 
 fdt_addr_t fdtdec_get_addr(const void *blob, int node,
diff --git a/lib/lz4.c b/lib/lz4.c
new file mode 100644
index 0000000..f518341
--- /dev/null
+++ b/lib/lz4.c
@@ -0,0 +1,243 @@
+/*
+   LZ4 - Fast LZ compression algorithm
+   Copyright (C) 2011-2015, Yann Collet.
+
+   SPDX-License-Identifier: BSD-2-Clause
+
+   You can contact the author at :
+   - LZ4 source repository : https://github.com/Cyan4973/lz4
+   - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
+*/
+
+
+/**************************************
+*  Reading and writing into memory
+**************************************/
+
+/* customized version of memcpy, which may overwrite up to 7 bytes beyond dstEnd */
+static void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd)
+{
+    BYTE* d = (BYTE*)dstPtr;
+    const BYTE* s = (const BYTE*)srcPtr;
+    BYTE* e = (BYTE*)dstEnd;
+    do { LZ4_copy8(d,s); d+=8; s+=8; } while (d<e);
+}
+
+
+/**************************************
+*  Common Constants
+**************************************/
+#define MINMATCH 4
+
+#define COPYLENGTH 8
+#define LASTLITERALS 5
+#define MFLIMIT (COPYLENGTH+MINMATCH)
+static const int LZ4_minLength = (MFLIMIT+1);
+
+#define KB *(1 <<10)
+#define MB *(1 <<20)
+#define GB *(1U<<30)
+
+#define MAXD_LOG 16
+#define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
+
+#define ML_BITS  4
+#define ML_MASK  ((1U<<ML_BITS)-1)
+#define RUN_BITS (8-ML_BITS)
+#define RUN_MASK ((1U<<RUN_BITS)-1)
+
+
+/**************************************
+*  Local Structures and types
+**************************************/
+typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive;
+typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
+typedef enum { full = 0, partial = 1 } earlyEnd_directive;
+
+
+
+/*******************************
+*  Decompression functions
+*******************************/
+/*
+ * This generic decompression function cover all use cases.
+ * It shall be instantiated several times, using different sets of directives
+ * Note that it is essential this generic function is really inlined,
+ * in order to remove useless branches during compilation optimization.
+ */
+FORCE_INLINE int LZ4_decompress_generic(
+                 const char* const source,
+                 char* const dest,
+                 int inputSize,
+                 int outputSize,         /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */
+
+                 int endOnInput,         /* endOnOutputSize, endOnInputSize */
+                 int partialDecoding,    /* full, partial */
+                 int targetOutputSize,   /* only used if partialDecoding==partial */
+                 int dict,               /* noDict, withPrefix64k, usingExtDict */
+                 const BYTE* const lowPrefix,  /* == dest if dict == noDict */
+                 const BYTE* const dictStart,  /* only if dict==usingExtDict */
+                 const size_t dictSize         /* note : = 0 if noDict */
+                 )
+{
+    /* Local Variables */
+    const BYTE* ip = (const BYTE*) source;
+    const BYTE* const iend = ip + inputSize;
+
+    BYTE* op = (BYTE*) dest;
+    BYTE* const oend = op + outputSize;
+    BYTE* cpy;
+    BYTE* oexit = op + targetOutputSize;
+    const BYTE* const lowLimit = lowPrefix - dictSize;
+
+    const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize;
+    const size_t dec32table[] = {4, 1, 2, 1, 4, 4, 4, 4};
+    const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3};
+
+    const int safeDecode = (endOnInput==endOnInputSize);
+    const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB)));
+
+
+    /* Special cases */
+    if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT;                         /* targetOutputSize too high => decode everything */
+    if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1;  /* Empty output buffer */
+    if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1);
+
+
+    /* Main Loop */
+    while (1)
+    {
+        unsigned token;
+        size_t length;
+        const BYTE* match;
+
+        /* get literal length */
+        token = *ip++;
+        if ((length=(token>>ML_BITS)) == RUN_MASK)
+        {
+            unsigned s;
+            do
+            {
+                s = *ip++;
+                length += s;
+            }
+            while (likely((endOnInput)?ip<iend-RUN_MASK:1) && (s==255));
+            if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)(op))) goto _output_error;   /* overflow detection */
+            if ((safeDecode) && unlikely((size_t)(ip+length)<(size_t)(ip))) goto _output_error;   /* overflow detection */
+        }
+
+        /* copy literals */
+        cpy = op+length;
+        if (((endOnInput) && ((cpy>(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) )
+            || ((!endOnInput) && (cpy>oend-COPYLENGTH)))
+        {
+            if (partialDecoding)
+            {
+                if (cpy > oend) goto _output_error;                           /* Error : write attempt beyond end of output buffer */
+                if ((endOnInput) && (ip+length > iend)) goto _output_error;   /* Error : read attempt beyond end of input buffer */
+            }
+            else
+            {
+                if ((!endOnInput) && (cpy != oend)) goto _output_error;       /* Error : block decoding must stop exactly there */
+                if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error;   /* Error : input must be consumed */
+            }
+            memcpy(op, ip, length);
+            ip += length;
+            op += length;
+            break;     /* Necessarily EOF, due to parsing restrictions */
+        }
+        LZ4_wildCopy(op, ip, cpy);
+        ip += length; op = cpy;
+
+        /* get offset */
+        match = cpy - LZ4_readLE16(ip); ip+=2;
+        if ((checkOffset) && (unlikely(match < lowLimit))) goto _output_error;   /* Error : offset outside destination buffer */
+
+        /* get matchlength */
+        length = token & ML_MASK;
+        if (length == ML_MASK)
+        {
+            unsigned s;
+            do
+            {
+                if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error;
+                s = *ip++;
+                length += s;
+            } while (s==255);
+            if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)op)) goto _output_error;   /* overflow detection */
+        }
+        length += MINMATCH;
+
+        /* check external dictionary */
+        if ((dict==usingExtDict) && (match < lowPrefix))
+        {
+            if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error;   /* doesn't respect parsing restriction */
+
+            if (length <= (size_t)(lowPrefix-match))
+            {
+                /* match can be copied as a single segment from external dictionary */
+                match = dictEnd - (lowPrefix-match);
+                memmove(op, match, length); op += length;
+            }
+            else
+            {
+                /* match encompass external dictionary and current segment */
+                size_t copySize = (size_t)(lowPrefix-match);
+                memcpy(op, dictEnd - copySize, copySize);
+                op += copySize;
+                copySize = length - copySize;
+                if (copySize > (size_t)(op-lowPrefix))   /* overlap within current segment */
+                {
+                    BYTE* const endOfMatch = op + copySize;
+                    const BYTE* copyFrom = lowPrefix;
+                    while (op < endOfMatch) *op++ = *copyFrom++;
+                }
+                else
+                {
+                    memcpy(op, lowPrefix, copySize);
+                    op += copySize;
+                }
+            }
+            continue;
+        }
+
+        /* copy repeated sequence */
+        cpy = op + length;
+        if (unlikely((op-match)<8))
+        {
+            const size_t dec64 = dec64table[op-match];
+            op[0] = match[0];
+            op[1] = match[1];
+            op[2] = match[2];
+            op[3] = match[3];
+            match += dec32table[op-match];
+            LZ4_copy4(op+4, match);
+            op += 8; match -= dec64;
+        } else { LZ4_copy8(op, match); op+=8; match+=8; }
+
+        if (unlikely(cpy>oend-12))
+        {
+            if (cpy > oend-LASTLITERALS) goto _output_error;    /* Error : last LASTLITERALS bytes must be literals */
+            if (op < oend-8)
+            {
+                LZ4_wildCopy(op, match, oend-8);
+                match += (oend-8) - op;
+                op = oend-8;
+            }
+            while (op<cpy) *op++ = *match++;
+        }
+        else
+            LZ4_wildCopy(op, match, cpy);
+        op=cpy;   /* correction */
+    }
+
+    /* end of decoding */
+    if (endOnInput)
+       return (int) (((char*)op)-dest);     /* Nb of output bytes decoded */
+    else
+       return (int) (((const char*)ip)-source);   /* Nb of input bytes read */
+
+    /* Overflow error detected */
+_output_error:
+    return (int) (-(((const char*)ip)-source))-1;
+}
diff --git a/lib/lz4_wrapper.c b/lib/lz4_wrapper.c
new file mode 100644
index 0000000..0739663
--- /dev/null
+++ b/lib/lz4_wrapper.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * SPDX-License-Identifier: GPL 2.0+ BSD-3-Clause
+ */
+
+#include <common.h>
+#include <compiler.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+static u16 LZ4_readLE16(const void *src) { return le16_to_cpu(*(u16 *)src); }
+static void LZ4_copy4(void *dst, const void *src) { *(u32 *)dst = *(u32 *)src; }
+static void LZ4_copy8(void *dst, const void *src) { *(u64 *)dst = *(u64 *)src; }
+
+typedef  uint8_t BYTE;
+typedef uint16_t U16;
+typedef uint32_t U32;
+typedef  int32_t S32;
+typedef uint64_t U64;
+
+#define FORCE_INLINE static inline __attribute__((always_inline))
+
+/* Unaltered (except removing unrelated code) from github.com/Cyan4973/lz4. */
+#include "lz4.c"	/* #include for inlining, do not link! */
+
+#define LZ4F_MAGIC 0x184D2204
+
+struct lz4_frame_header {
+	u32 magic;
+	union {
+		u8 flags;
+		struct {
+			u8 reserved0:2;
+			u8 has_content_checksum:1;
+			u8 has_content_size:1;
+			u8 has_block_checksum:1;
+			u8 independent_blocks:1;
+			u8 version:2;
+		};
+	};
+	union {
+		u8 block_descriptor;
+		struct {
+			u8 reserved1:4;
+			u8 max_block_size:3;
+			u8 reserved2:1;
+		};
+	};
+	/* + u64 content_size iff has_content_size is set */
+	/* + u8 header_checksum */
+} __packed;
+
+struct lz4_block_header {
+	union {
+		u32 raw;
+		struct {
+			u32 size:31;
+			u32 not_compressed:1;
+		};
+	};
+	/* + size bytes of data */
+	/* + u32 block_checksum iff has_block_checksum is set */
+} __packed;
+
+int ulz4fn(const void *src, size_t srcn, void *dst, size_t *dstn)
+{
+	const void *end = dst + *dstn;
+	const void *in = src;
+	void *out = dst;
+	int has_block_checksum;
+	int ret;
+	*dstn = 0;
+
+	{ /* With in-place decompression the header may become invalid later. */
+		const struct lz4_frame_header *h = in;
+
+		if (srcn < sizeof(*h) + sizeof(u64) + sizeof(u8))
+			return -EINVAL;	/* input overrun */
+
+		/* We assume there's always only a single, standard frame. */
+		if (le32_to_cpu(h->magic) != LZ4F_MAGIC || h->version != 1)
+			return -EPROTONOSUPPORT;	/* unknown format */
+		if (h->reserved0 || h->reserved1 || h->reserved2)
+			return -EINVAL;	/* reserved must be zero */
+		if (!h->independent_blocks)
+			return -EPROTONOSUPPORT; /* we can't support this yet */
+		has_block_checksum = h->has_block_checksum;
+
+		in += sizeof(*h);
+		if (h->has_content_size)
+			in += sizeof(u64);
+		in += sizeof(u8);
+	}
+
+	while (1) {
+		struct lz4_block_header b = { .raw = le32_to_cpu(*(u32 *)in) };
+		in += sizeof(struct lz4_block_header);
+
+		if (in - src + b.size > srcn) {
+			ret = -EINVAL;		/* input overrun */
+			break;
+		}
+
+		if (!b.size) {
+			ret = 0;	/* decompression successful */
+			break;
+		}
+
+		if (b.not_compressed) {
+			size_t size = min((ptrdiff_t)b.size, end - out);
+			memcpy(out, in, size);
+			out += size;
+			if (size < b.size) {
+				ret = -ENOBUFS;	/* output overrun */
+				break;
+			}
+		} else {
+			/* constant folding essential, do not touch params! */
+			ret = LZ4_decompress_generic(in, out, b.size,
+					end - out, endOnInputSize,
+					full, 0, noDict, out, NULL, 0);
+			if (ret < 0) {
+				ret = -EPROTO;	/* decompression error */
+				break;
+			}
+			out += ret;
+		}
+
+		in += b.size;
+		if (has_block_checksum)
+			in += sizeof(u32);
+	}
+
+	*dstn = out - dst;
+	return ret;
+}
diff --git a/net/Kconfig b/net/Kconfig
index 915371d..77a2f7e 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -16,4 +16,10 @@
 	  A new MAC address will be generated on every boot and it will
 	  not be added to the environment.
 
+config NETCONSOLE
+	bool "NetConsole support"
+	help
+	  Support the 'nc' input/output device for networked console.
+	  See README.NetConsole for details.
+
 endif   # if NET
diff --git a/net/eth.c b/net/eth.c
index 26520d3..2e24b55 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -389,6 +389,17 @@
 	priv->state = ETH_STATE_PASSIVE;
 }
 
+int eth_is_active(struct udevice *dev)
+{
+	struct eth_device_priv *priv;
+
+	if (!dev || !device_active(dev))
+		return 0;
+
+	priv = dev_get_uclass_priv(dev);
+	return priv->state == ETH_STATE_ACTIVE;
+}
+
 int eth_send(void *packet, int length)
 {
 	struct udevice *current;
@@ -580,7 +591,7 @@
 	.per_device_auto_alloc_size = sizeof(struct eth_device_priv),
 	.flags		= DM_UC_FLAG_SEQ_ALIAS,
 };
-#endif
+#endif /* #ifdef CONFIG_DM_ETH */
 
 #ifndef CONFIG_DM_ETH
 
@@ -918,6 +929,11 @@
 	eth_current->state = ETH_STATE_PASSIVE;
 }
 
+int eth_is_active(struct eth_device *dev)
+{
+	return dev && dev->state == ETH_STATE_ACTIVE;
+}
+
 int eth_send(void *packet, int length)
 {
 	if (!eth_current)
diff --git a/test/compression.c b/test/compression.c
index 7ef3a8c..be4e04e 100644
--- a/test/compression.c
+++ b/test/compression.c
@@ -95,6 +95,28 @@
 	"\x73\x61\x67\x65\x73\x2e\x0a\x11\x00\x00\x00\x00\x00\x00";
 static const unsigned long lzo_compressed_size = 334;
 
+/* lz4 -z /tmp/plain.txt > /tmp/plain.lz4 */
+static const char lz4_compressed[] =
+	"\x04\x22\x4d\x18\x64\x70\xb9\x01\x01\x00\x00\xff\x19\x49\x20\x61"
+	"\x6d\x20\x61\x20\x68\x69\x67\x68\x6c\x79\x20\x63\x6f\x6d\x70\x72"
+	"\x65\x73\x73\x61\x62\x6c\x65\x20\x62\x69\x74\x20\x6f\x66\x20\x74"
+	"\x65\x78\x74\x2e\x0a\x28\x00\x3d\xf1\x25\x54\x68\x65\x72\x65\x20"
+	"\x61\x72\x65\x20\x6d\x61\x6e\x79\x20\x6c\x69\x6b\x65\x20\x6d\x65"
+	"\x2c\x20\x62\x75\x74\x20\x74\x68\x69\x73\x20\x6f\x6e\x65\x20\x69"
+	"\x73\x20\x6d\x69\x6e\x65\x2e\x0a\x49\x66\x20\x49\x20\x77\x32\x00"
+	"\xd1\x6e\x79\x20\x73\x68\x6f\x72\x74\x65\x72\x2c\x20\x74\x45\x00"
+	"\xf4\x0b\x77\x6f\x75\x6c\x64\x6e\x27\x74\x20\x62\x65\x20\x6d\x75"
+	"\x63\x68\x20\x73\x65\x6e\x73\x65\x20\x69\x6e\x0a\xcf\x00\x50\x69"
+	"\x6e\x67\x20\x6d\x12\x00\x00\x32\x00\xf0\x11\x20\x66\x69\x72\x73"
+	"\x74\x20\x70\x6c\x61\x63\x65\x2e\x20\x41\x74\x20\x6c\x65\x61\x73"
+	"\x74\x20\x77\x69\x74\x68\x20\x6c\x7a\x6f\x2c\x63\x00\xf5\x14\x77"
+	"\x61\x79\x2c\x0a\x77\x68\x69\x63\x68\x20\x61\x70\x70\x65\x61\x72"
+	"\x73\x20\x74\x6f\x20\x62\x65\x68\x61\x76\x65\x20\x70\x6f\x6f\x72"
+	"\x6c\x79\x4e\x00\x30\x61\x63\x65\x27\x01\x01\x95\x00\x01\x2d\x01"
+	"\xb0\x0a\x6d\x65\x73\x73\x61\x67\x65\x73\x2e\x0a\x00\x00\x00\x00"
+	"\x9d\x12\x8c\x9d";
+static const unsigned long lz4_compressed_size = 276;
+
 
 #define TEST_BUFFER_SIZE	512
 
@@ -227,6 +249,39 @@
 	return (ret != LZO_E_OK);
 }
 
+static int compress_using_lz4(void *in, unsigned long in_size,
+			      void *out, unsigned long out_max,
+			      unsigned long *out_size)
+{
+	/* There is no lz4 compression in u-boot, so fake it. */
+	assert(in_size == strlen(plain));
+	assert(memcmp(plain, in, in_size) == 0);
+
+	if (lz4_compressed_size > out_max)
+		return -1;
+
+	memcpy(out, lz4_compressed, lz4_compressed_size);
+	if (out_size)
+		*out_size = lz4_compressed_size;
+
+	return 0;
+}
+
+static int uncompress_using_lz4(void *in, unsigned long in_size,
+				void *out, unsigned long out_max,
+				unsigned long *out_size)
+{
+	int ret;
+	size_t input_size = in_size;
+	size_t output_size = out_max;
+
+	ret = ulz4fn(in, input_size, out, &output_size);
+	if (out_size)
+		*out_size = output_size;
+
+	return (ret != 0);
+}
+
 #define errcheck(statement) if (!(statement)) { \
 	fprintf(stderr, "\tFailed: %s\n", #statement); \
 	ret = 1; \
@@ -325,6 +380,7 @@
 	err += run_test("bzip2", compress_using_bzip2, uncompress_using_bzip2);
 	err += run_test("lzma", compress_using_lzma, uncompress_using_lzma);
 	err += run_test("lzo", compress_using_lzo, uncompress_using_lzo);
+	err += run_test("lz4", compress_using_lz4, uncompress_using_lz4);
 
 	printf("ut_compression %s\n", err == 0 ? "ok" : "FAILED");
 
@@ -401,6 +457,7 @@
 	err |= run_bootm_test(IH_COMP_BZIP2, compress_using_bzip2);
 	err |= run_bootm_test(IH_COMP_LZMA, compress_using_lzma);
 	err |= run_bootm_test(IH_COMP_LZO, compress_using_lzo);
+	err |= run_bootm_test(IH_COMP_LZ4, compress_using_lz4);
 	err |= run_bootm_test(IH_COMP_NONE, compress_using_none);
 
 	printf("ut_image_decomp %s\n", err == 0 ? "ok" : "FAILED");
diff --git a/test/dm/core.c b/test/dm/core.c
index 976a706..9fbc70d 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -77,7 +77,7 @@
 int dm_leak_check_end(struct unit_test_state *uts)
 {
 	struct mallinfo end;
-	int id;
+	int id, diff;
 
 	/* Don't delete the root class, since we started with that */
 	for (id = UCLASS_ROOT + 1; id < UCLASS_COUNT; id++) {
@@ -90,6 +90,11 @@
 	}
 
 	end = mallinfo();
+	diff = end.uordblks - uts->start.uordblks;
+	if (diff > 0)
+		printf("Leak: lost %#xd bytes\n", diff);
+	else if (diff < 0)
+		printf("Leak: gained %#xd bytes\n", -diff);
 	ut_asserteq(uts->start.uordblks, end.uordblks);
 
 	return 0;
diff --git a/test/fs/fs-test.sh b/test/fs/fs-test.sh
index b88a67c..6f0a345 100755
--- a/test/fs/fs-test.sh
+++ b/test/fs/fs-test.sh
@@ -10,13 +10,13 @@
 # Expected results are as follows:
 # EXT4 tests:
 # fs-test.sb.ext4.out: Summary: PASS: 17 FAIL: 2
-# fs-test.ext4.out: Summary: PASS: 11 FAIL: 8
-# fs-test.fs.ext4.out: Summary: PASS: 11 FAIL: 8
+# fs-test.ext4.out: Summary: PASS: 10 FAIL: 9
+# fs-test.fs.ext4.out: Summary: PASS: 10 FAIL: 9
 # FAT tests:
 # fs-test.sb.fat.out: Summary: PASS: 17 FAIL: 2
 # fs-test.fat.out: Summary: PASS: 19 FAIL: 0
 # fs-test.fs.fat.out: Summary: PASS: 19 FAIL: 0
-# Total Summary: TOTAL PASS: 94 TOTAL FAIL: 20
+# Total Summary: TOTAL PASS: 92 TOTAL FAIL: 22
 
 # pre-requisite binaries list.
 PREREQ_BINS="md5sum mkfs mount umount dd fallocate mkdir"
@@ -465,9 +465,9 @@
 	check_md5 "Test Case 9b " "$1" "$2" 6 \
 		"TC9: load 1MB chunk crossing 2GB boundary from $4"
 
-	# Check 2mb chunk from the last 1MB of 2.5GB file - generic failure case
-	grep -A6 "Test Case 10 " "$1" | grep -q 'Error: "filesize" not defined'
-	pass_fail "TC10: load 2MB from the last 1MB of $4 - generic fail case"
+	# Check 2mb chunk from the last 1MB of 2.5GB file loads 1MB
+	grep -A6 "Test Case 10 " "$1" | grep -q "filesize=100000"
+	pass_fail "TC10: load 2MB from the last 1MB of $4 loads 1MB"
 
 	# Check 1mb chunk write
 	grep -A3 "Test Case 11a " "$1" | \
diff --git a/tools/default_image.c b/tools/default_image.c
index 18940af..3ed7014 100644
--- a/tools/default_image.c
+++ b/tools/default_image.c
@@ -89,7 +89,6 @@
 {
 	uint32_t checksum;
 	char *source_date_epoch;
-	struct tm *time_universal;
 	time_t time;
 
 	image_header_t * hdr = (image_header_t *)ptr;
@@ -103,13 +102,10 @@
 	if (source_date_epoch != NULL) {
 		time = (time_t) strtol(source_date_epoch, NULL, 10);
 
-		time_universal = gmtime(&time);
-		if (time_universal == NULL) {
+		if (gmtime(&time) == NULL) {
 			fprintf(stderr, "%s: SOURCE_DATE_EPOCH is not valid\n",
 				__func__);
 			time = 0;
-		} else {
-			time = mktime(time_universal);
 		}
 	} else {
 		time = sbuf->st_mtime;
diff --git a/tools/kwbimage.c b/tools/kwbimage.c
index 3fa90d3..5e62d08 100644
--- a/tools/kwbimage.c
+++ b/tools/kwbimage.c
@@ -17,89 +17,6 @@
 #include <stdint.h>
 #include "kwbimage.h"
 
-#define ALIGN_SUP(x, a) (((x) + (a - 1)) & ~(a - 1))
-
-/* Structure of the main header, version 0 (Kirkwood, Dove) */
-struct main_hdr_v0 {
-	uint8_t  blockid;		/*0     */
-	uint8_t  nandeccmode;		/*1     */
-	uint16_t nandpagesize;		/*2-3   */
-	uint32_t blocksize;		/*4-7   */
-	uint32_t rsvd1;			/*8-11  */
-	uint32_t srcaddr;		/*12-15 */
-	uint32_t destaddr;		/*16-19 */
-	uint32_t execaddr;		/*20-23 */
-	uint8_t  satapiomode;		/*24    */
-	uint8_t  rsvd3;			/*25    */
-	uint16_t ddrinitdelay;		/*26-27 */
-	uint16_t rsvd2;			/*28-29 */
-	uint8_t  ext;			/*30    */
-	uint8_t  checksum;		/*31    */
-};
-
-struct ext_hdr_v0_reg {
-	uint32_t raddr;
-	uint32_t rdata;
-};
-
-#define EXT_HDR_V0_REG_COUNT ((0x1dc - 0x20) / sizeof(struct ext_hdr_v0_reg))
-
-struct ext_hdr_v0 {
-	uint32_t              offset;
-	uint8_t               reserved[0x20 - sizeof(uint32_t)];
-	struct ext_hdr_v0_reg rcfg[EXT_HDR_V0_REG_COUNT];
-	uint8_t               reserved2[7];
-	uint8_t               checksum;
-};
-
-/* Structure of the main header, version 1 (Armada 370, Armada XP) */
-struct main_hdr_v1 {
-	uint8_t  blockid;               /* 0 */
-	uint8_t  reserved1;             /* 1 */
-	uint16_t reserved2;             /* 2-3 */
-	uint32_t blocksize;             /* 4-7 */
-	uint8_t  version;               /* 8 */
-	uint8_t  headersz_msb;          /* 9 */
-	uint16_t headersz_lsb;          /* A-B */
-	uint32_t srcaddr;               /* C-F */
-	uint32_t destaddr;              /* 10-13 */
-	uint32_t execaddr;              /* 14-17 */
-	uint8_t  reserved3;             /* 18 */
-	uint8_t  nandblocksize;         /* 19 */
-	uint8_t  nandbadblklocation;    /* 1A */
-	uint8_t  reserved4;             /* 1B */
-	uint16_t reserved5;             /* 1C-1D */
-	uint8_t  ext;                   /* 1E */
-	uint8_t  checksum;              /* 1F */
-};
-
-/*
- * Header for the optional headers, version 1 (Armada 370, Armada XP)
- */
-struct opt_hdr_v1 {
-	uint8_t  headertype;
-	uint8_t  headersz_msb;
-	uint16_t headersz_lsb;
-	char     data[0];
-};
-
-/*
- * Various values for the opt_hdr_v1->headertype field, describing the
- * different types of optional headers. The "secure" header contains
- * informations related to secure boot (encryption keys, etc.). The
- * "binary" header contains ARM binary code to be executed prior to
- * executing the main payload (usually the bootloader). This is
- * typically used to execute DDR3 training code. The "register" header
- * allows to describe a set of (address, value) tuples that are
- * generally used to configure the DRAM controller.
- */
-#define OPT_HDR_V1_SECURE_TYPE   0x1
-#define OPT_HDR_V1_BINARY_TYPE   0x2
-#define OPT_HDR_V1_REGISTER_TYPE 0x3
-
-#define KWBHEADER_V1_SIZE(hdr) \
-	(((hdr)->headersz_msb << 16) | (hdr)->headersz_lsb)
-
 static struct image_cfg_element *image_cfg;
 static int cfgn;
 
@@ -174,17 +91,6 @@
 #define IMAGE_CFG_ELEMENT_MAX 256
 
 /*
- * Byte 8 of the image header contains the version number. In the v0
- * header, byte 8 was reserved, and always set to 0. In the v1 header,
- * byte 8 has been changed to a proper field, set to 1.
- */
-static unsigned int image_version(void *header)
-{
-	unsigned char *ptr = header;
-	return ptr[8];
-}
-
-/*
  * Utility functions to manipulate boot mode and ecc modes (convert
  * them back and forth between description strings and the
  * corresponding numerical identifiers).
diff --git a/tools/kwbimage.h b/tools/kwbimage.h
index 8e4a4e2..9d2585c 100644
--- a/tools/kwbimage.h
+++ b/tools/kwbimage.h
@@ -29,6 +29,94 @@
 #define IBR_HDR_UART_ID			0x69
 #define IBR_DEF_ATTRIB	 		0x00
 
+#define ALIGN_SUP(x, a) (((x) + (a - 1)) & ~(a - 1))
+
+/* Structure of the main header, version 0 (Kirkwood, Dove) */
+struct main_hdr_v0 {
+	uint8_t  blockid;		/*0     */
+	uint8_t  nandeccmode;		/*1     */
+	uint16_t nandpagesize;		/*2-3   */
+	uint32_t blocksize;		/*4-7   */
+	uint32_t rsvd1;			/*8-11  */
+	uint32_t srcaddr;		/*12-15 */
+	uint32_t destaddr;		/*16-19 */
+	uint32_t execaddr;		/*20-23 */
+	uint8_t  satapiomode;		/*24    */
+	uint8_t  rsvd3;			/*25    */
+	uint16_t ddrinitdelay;		/*26-27 */
+	uint16_t rsvd2;			/*28-29 */
+	uint8_t  ext;			/*30    */
+	uint8_t  checksum;		/*31    */
+};
+
+struct ext_hdr_v0_reg {
+	uint32_t raddr;
+	uint32_t rdata;
+};
+
+#define EXT_HDR_V0_REG_COUNT ((0x1dc - 0x20) / sizeof(struct ext_hdr_v0_reg))
+
+struct ext_hdr_v0 {
+	uint32_t              offset;
+	uint8_t               reserved[0x20 - sizeof(uint32_t)];
+	struct ext_hdr_v0_reg rcfg[EXT_HDR_V0_REG_COUNT];
+	uint8_t               reserved2[7];
+	uint8_t               checksum;
+};
+
+struct kwb_header {
+	struct main_hdr_v0	kwb_hdr;
+	struct ext_hdr_v0	kwb_exthdr;
+};
+
+/* Structure of the main header, version 1 (Armada 370, Armada XP) */
+struct main_hdr_v1 {
+	uint8_t  blockid;               /* 0 */
+	uint8_t  reserved1;             /* 1 */
+	uint16_t reserved2;             /* 2-3 */
+	uint32_t blocksize;             /* 4-7 */
+	uint8_t  version;               /* 8 */
+	uint8_t  headersz_msb;          /* 9 */
+	uint16_t headersz_lsb;          /* A-B */
+	uint32_t srcaddr;               /* C-F */
+	uint32_t destaddr;              /* 10-13 */
+	uint32_t execaddr;              /* 14-17 */
+	uint8_t  reserved3;             /* 18 */
+	uint8_t  nandblocksize;         /* 19 */
+	uint8_t  nandbadblklocation;    /* 1A */
+	uint8_t  reserved4;             /* 1B */
+	uint16_t reserved5;             /* 1C-1D */
+	uint8_t  ext;                   /* 1E */
+	uint8_t  checksum;              /* 1F */
+};
+
+/*
+ * Header for the optional headers, version 1 (Armada 370, Armada XP)
+ */
+struct opt_hdr_v1 {
+	uint8_t  headertype;
+	uint8_t  headersz_msb;
+	uint16_t headersz_lsb;
+	char     data[0];
+};
+
+/*
+ * Various values for the opt_hdr_v1->headertype field, describing the
+ * different types of optional headers. The "secure" header contains
+ * informations related to secure boot (encryption keys, etc.). The
+ * "binary" header contains ARM binary code to be executed prior to
+ * executing the main payload (usually the bootloader). This is
+ * typically used to execute DDR3 training code. The "register" header
+ * allows to describe a set of (address, value) tuples that are
+ * generally used to configure the DRAM controller.
+ */
+#define OPT_HDR_V1_SECURE_TYPE   0x1
+#define OPT_HDR_V1_BINARY_TYPE   0x2
+#define OPT_HDR_V1_REGISTER_TYPE 0x3
+
+#define KWBHEADER_V1_SIZE(hdr) \
+	(((hdr)->headersz_msb << 16) | (hdr)->headersz_lsb)
+
 enum kwbimage_cmd {
 	CMD_INVALID,
 	CMD_BOOT_FROM,
@@ -46,45 +134,20 @@
 	CFG_DATA1
 };
 
-/* typedefs */
-typedef struct bhr_t {
-	uint8_t blockid;		/*0     */
-	uint8_t nandeccmode;		/*1     */
-	uint16_t nandpagesize;		/*2-3   */
-	uint32_t blocksize;		/*4-7   */
-	uint32_t rsvd1;			/*8-11  */
-	uint32_t srcaddr;		/*12-15 */
-	uint32_t destaddr;		/*16-19 */
-	uint32_t execaddr;		/*20-23 */
-	uint8_t satapiomode;		/*24    */
-	uint8_t rsvd3;			/*25    */
-	uint16_t ddrinitdelay;		/*26-27 */
-	uint16_t rsvd2;			/*28-29 */
-	uint8_t ext;			/*30    */
-	uint8_t checkSum;		/*31    */
-} bhr_t, *pbhr_t;
-
-struct reg_config {
-	uint32_t raddr;
-	uint32_t rdata;
-};
-
-typedef struct extbhr_t {
-	uint32_t dramregsoffs;
-	uint8_t rsrvd1[0x20 - sizeof(uint32_t)];
-	struct reg_config rcfg[KWBIMAGE_MAX_CONFIG];
-	uint8_t rsrvd2[7];
-	uint8_t checkSum;
-} extbhr_t, *pextbhr_t;
-
-struct kwb_header {
-	bhr_t kwb_hdr;
-	extbhr_t kwb_exthdr;
-};
-
 /*
  * functions
  */
 void init_kwb_image_type (void);
 
+/*
+ * Byte 8 of the image header contains the version number. In the v0
+ * header, byte 8 was reserved, and always set to 0. In the v1 header,
+ * byte 8 has been changed to a proper field, set to 1.
+ */
+static inline unsigned int image_version(void *header)
+{
+	unsigned char *ptr = header;
+	return ptr[8];
+}
+
 #endif /* _KWBIMAGE_H_ */
diff --git a/tools/kwboot.c b/tools/kwboot.c
index af7a6ee..c5f4492 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -614,9 +614,10 @@
 kwboot_img_patch_hdr(void *img, size_t size)
 {
 	int rc;
-	bhr_t *hdr;
+	struct main_hdr_v1 *hdr;
 	uint8_t csum;
-	const size_t hdrsz = sizeof(*hdr);
+	size_t hdrsz = sizeof(*hdr);
+	int image_ver;
 
 	rc = -1;
 	hdr = img;
@@ -626,8 +627,20 @@
 		goto out;
 	}
 
-	csum = kwboot_img_csum8(hdr, hdrsz) - hdr->checkSum;
-	if (csum != hdr->checkSum) {
+	image_ver = image_version(img);
+	if (image_ver < 0) {
+		fprintf(stderr, "Invalid image header version\n");
+		errno = EINVAL;
+		goto out;
+	}
+
+	if (image_ver == 0)
+		hdrsz = sizeof(*hdr);
+	else
+		hdrsz = KWBHEADER_V1_SIZE(hdr);
+
+	csum = kwboot_img_csum8(hdr, hdrsz) - hdr->checksum;
+	if (csum != hdr->checksum) {
 		errno = EINVAL;
 		goto out;
 	}
@@ -639,14 +652,18 @@
 
 	hdr->blockid = IBR_HDR_UART_ID;
 
-	hdr->nandeccmode = IBR_HDR_ECC_DISABLED;
-	hdr->nandpagesize = 0;
+	if (image_ver == 0) {
+		struct main_hdr_v0 *hdr_v0 = img;
 
-	hdr->srcaddr = hdr->ext
-		? sizeof(struct kwb_header)
-		: sizeof(*hdr);
+		hdr_v0->nandeccmode = IBR_HDR_ECC_DISABLED;
+		hdr_v0->nandpagesize = 0;
 
-	hdr->checkSum = kwboot_img_csum8(hdr, hdrsz) - csum;
+		hdr_v0->srcaddr = hdr_v0->ext
+			? sizeof(struct kwb_header)
+			: sizeof(*hdr_v0);
+	}
+
+	hdr->checksum = kwboot_img_csum8(hdr, hdrsz) - csum;
 
 	rc = 0;
 out:
diff --git a/tools/mkimage.c b/tools/mkimage.c
index c50af05..8af9d50 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -595,7 +595,7 @@
 		params.cmdname);
 	fprintf(stderr, "       %s [-D dtc_options] [-f fit-image.its|-F] fit-image\n",
 		params.cmdname);
-	fprintf(stderr, "          -D => set options for device tree compiler\n"
+	fprintf(stderr, "          -D => set all options for device tree compiler\n"
 			"          -f => input filename for FIT source\n");
 #ifdef CONFIG_FIT_SIGNATURE
 	fprintf(stderr, "Signing / verified boot options: [-k keydir] [-K dtb] [ -c <comment>] [-r]\n"
diff --git a/tools/mksunxiboot.c b/tools/mksunxiboot.c
index 676d392..9c1c5b7 100644
--- a/tools/mksunxiboot.c
+++ b/tools/mksunxiboot.c
@@ -15,23 +15,8 @@
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include "asm/arch/spl.h"
 
-/* boot head definition from sun4i boot code */
-struct boot_file_head {
-	uint32_t b_instruction;	/* one intruction jumping to real code */
-	uint8_t magic[8];	/* ="eGON.BT0" or "eGON.BT1", not C-style str */
-	uint32_t check_sum;	/* generated by PC */
-	uint32_t length;	/* generated by PC */
-	/*
-	 * We use a simplified header, only filling in what is needed
-	 * by the boot ROM. To be compatible with Allwinner tools we
-	 * would need to implement the proper fields here instead of
-	 * padding.
-	 */
-	uint8_t pad[12];		/* align to 32 bytes */
-};
-
-#define BOOT0_MAGIC                     "eGON.BT0"
 #define STAMP_VALUE                     0x5F0A6C39
 
 /* check sum functon from sun4i boot code */
@@ -133,6 +118,10 @@
 		ALIGN(file_size + sizeof(struct boot_file_head), BLOCK_SIZE);
 	img.header.b_instruction = cpu_to_le32(img.header.b_instruction);
 	img.header.length = cpu_to_le32(img.header.length);
+
+	memcpy(img.header.spl_signature, SPL_SIGNATURE, 3); /* "sunxi" marker */
+	img.header.spl_signature[3] = SPL_HEADER_VERSION;
+
 	gen_check_sum(&img.header);
 
 	count = write(fd_out, &img, le32_to_cpu(img.header.length));