Merge git://git.denx.de/u-boot-dm
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2985e6e..fd47e60 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -668,6 +668,7 @@
 	select SUPPORT_SPL
 	select SPL
 	select OF_CONTROL
+	select SPL_DISABLE_OF_CONTROL
 	select CPU_V7
 	select DM
 	select DM_SPI_FLASH
@@ -794,6 +795,7 @@
 	select DM
 	select DM_SERIAL
 	select DM_I2C
+	select SPL_DISABLE_OF_CONTROL
 	help
 	  Support for UniPhier SoC family developed by Socionext Inc.
 	  (formerly, System LSI Business Division of Panasonic Corporation)
diff --git a/arch/arm/cpu/armv7/cpu.c b/arch/arm/cpu/armv7/cpu.c
index c56417d..0b0e500 100644
--- a/arch/arm/cpu/armv7/cpu.c
+++ b/arch/arm/cpu/armv7/cpu.c
@@ -24,7 +24,7 @@
 
 void __weak cpu_cache_initialization(void){}
 
-int cleanup_before_linux(void)
+int cleanup_before_linux_select(int flags)
 {
 	/*
 	 * this function is called just before we call linux
@@ -42,24 +42,30 @@
 	icache_disable();
 	invalidate_icache_all();
 
-	/*
-	 * turn off D-cache
-	 * dcache_disable() in turn flushes the d-cache and disables MMU
-	 */
-	dcache_disable();
-	v7_outer_cache_disable();
+	if (flags & CBL_DISABLE_CACHES) {
+		/*
+		* turn off D-cache
+		* dcache_disable() in turn flushes the d-cache and disables MMU
+		*/
+		dcache_disable();
+		v7_outer_cache_disable();
 
-	/*
-	 * After D-cache is flushed and before it is disabled there may
-	 * be some new valid entries brought into the cache. We are sure
-	 * that these lines are not dirty and will not affect our execution.
-	 * (because unwinding the call-stack and setting a bit in CP15 SCTLR
-	 * is all we did during this. We have not pushed anything on to the
-	 * stack. Neither have we affected any static data)
-	 * So just invalidate the entire d-cache again to avoid coherency
-	 * problems for kernel
-	 */
-	invalidate_dcache_all();
+		/*
+		* After D-cache is flushed and before it is disabled there may
+		* be some new valid entries brought into the cache. We are
+		* sure that these lines are not dirty and will not affect our
+		* execution. (because unwinding the call-stack and setting a
+		* bit in CP15 SCTRL is all we did during this. We have not
+		* pushed anything on to the stack. Neither have we affected
+		* any static data) So just invalidate the entire d-cache again
+		* to avoid coherency problems for kernel
+		*/
+		invalidate_dcache_all();
+	} else {
+		flush_dcache_all();
+		invalidate_icache_all();
+		icache_enable();
+	}
 
 	/*
 	 * Some CPU need more cache attention before starting the kernel.
@@ -68,3 +74,8 @@
 
 	return 0;
 }
+
+int cleanup_before_linux(void)
+{
+	return cleanup_before_linux_select(CBL_ALL);
+}
diff --git a/arch/arm/cpu/armv7/exynos/Kconfig b/arch/arm/cpu/armv7/exynos/Kconfig
index c614425..3ca7128 100644
--- a/arch/arm/cpu/armv7/exynos/Kconfig
+++ b/arch/arm/cpu/armv7/exynos/Kconfig
@@ -8,6 +8,7 @@
 	select SUPPORT_SPL
 	bool "Exynos4210 SMDKV310 board"
 	select OF_CONTROL
+	select SPL_DISABLE_OF_CONTROL
 
 config TARGET_TRATS
 	bool "Exynos4210 Trats board"
@@ -28,6 +29,7 @@
 config TARGET_ODROID_XU3
 	bool "Exynos5422 Odroid board"
 	select OF_CONTROL
+	select SPL_DISABLE_OF_CONTROL
 
 config TARGET_ARNDALE
 	bool "Exynos5250 Arndale board"
@@ -35,31 +37,37 @@
 	select CPU_V7_HAS_VIRT
 	select SUPPORT_SPL
 	select OF_CONTROL
+	select SPL_DISABLE_OF_CONTROL
 
 config TARGET_SMDK5250
 	bool "SMDK5250 board"
 	select SUPPORT_SPL
 	select OF_CONTROL
+	select SPL_DISABLE_OF_CONTROL
 
 config TARGET_SNOW
 	bool "Snow board"
 	select SUPPORT_SPL
 	select OF_CONTROL
+	select SPL_DISABLE_OF_CONTROL
 
 config TARGET_SMDK5420
 	bool "SMDK5420 board"
 	select SUPPORT_SPL
 	select OF_CONTROL
+	select SPL_DISABLE_OF_CONTROL
 
 config TARGET_PEACH_PI
 	bool "Peach Pi board"
 	select SUPPORT_SPL
 	select OF_CONTROL
+	select SPL_DISABLE_OF_CONTROL
 
 config TARGET_PEACH_PIT
 	bool "Peach Pit board"
 	select SUPPORT_SPL
 	select OF_CONTROL
+	select SPL_DISABLE_OF_CONTROL
 
 endchoice
 
diff --git a/arch/arm/cpu/armv7/s5pc1xx/Kconfig b/arch/arm/cpu/armv7/s5pc1xx/Kconfig
index 04acdaa..792ef59 100644
--- a/arch/arm/cpu/armv7/s5pc1xx/Kconfig
+++ b/arch/arm/cpu/armv7/s5pc1xx/Kconfig
@@ -7,10 +7,12 @@
 config TARGET_S5P_GONI
 	bool "S5P Goni board"
 	select OF_CONTROL
+	select SPL_DISABLE_OF_CONTROL
 
 config TARGET_SMDKC100
 	bool "Support smdkc100 board"
 	select OF_CONTROL
+	select SPL_DISABLE_OF_CONTROL
 
 endchoice
 
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index bc1421e..9c735c6 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -138,7 +138,8 @@
 
 targets += $(dtb-y)
 
-DTC_FLAGS += -R 4 -p 0x1000
+# Add any required device tree compiler flags here
+DTC_FLAGS +=
 
 PHONY += dtbs
 dtbs: $(addprefix $(obj)/, $(dtb-y))
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 9b42871..f5b5ee9 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -24,9 +24,15 @@
 config USE_PRIVATE_LIBGCC
 	default y
 
+config DM_USB
+	default y
+
 config SPL_DM
 	default y
 
+config SPL_DISABLE_OF_CONTROL
+	default y
+
 source "arch/arm/mach-tegra/tegra20/Kconfig"
 source "arch/arm/mach-tegra/tegra30/Kconfig"
 source "arch/arm/mach-tegra/tegra114/Kconfig"
diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach-tegra/board2.c
index ebcee4e..ce9b695 100644
--- a/arch/arm/mach-tegra/board2.c
+++ b/arch/arm/mach-tegra/board2.c
@@ -161,7 +161,6 @@
 
 #ifdef CONFIG_USB_EHCI_TEGRA
 	pin_mux_usb();
-	usb_process_devicetree(gd->fdt_blob);
 #endif
 
 #ifdef CONFIG_LCD
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index 02c4cd3..e6ddb17 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -52,6 +52,11 @@
 	return 0;
 }
 
+int cleanup_before_linux_select(int flags)
+{
+	return 0;
+}
+
 void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
 {
 #ifdef CONFIG_PCI
diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c
index cc904c2..cb1f071 100644
--- a/common/cmd_bmp.c
+++ b/common/cmd_bmp.c
@@ -34,12 +34,12 @@
  * didn't contain a valid BMP signature.
  */
 #ifdef CONFIG_VIDEO_BMP_GZIP
-bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp,
-			void **alloc_addr)
+struct bmp_image *gunzip_bmp(unsigned long addr, unsigned long *lenp,
+			     void **alloc_addr)
 {
 	void *dst;
 	unsigned long len;
-	bmp_image_t *bmp;
+	struct bmp_image *bmp;
 
 	/*
 	 * Decompress bmp image
@@ -55,7 +55,7 @@
 	bmp = dst;
 
 	/* align to 32-bit-aligned-address + 2 */
-	bmp = (bmp_image_t *)((((unsigned int)dst + 1) & ~3) + 2);
+	bmp = (struct bmp_image *)((((unsigned int)dst + 1) & ~3) + 2);
 
 	if (gunzip(bmp, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE, (uchar *)addr, &len) != 0) {
 		free(dst);
@@ -80,8 +80,8 @@
 	return bmp;
 }
 #else
-bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp,
-			void **alloc_addr)
+struct bmp_image *gunzip_bmp(unsigned long addr, unsigned long *lenp,
+			     void **alloc_addr)
 {
 	return NULL;
 }
@@ -187,7 +187,7 @@
  */
 static int bmp_info(ulong addr)
 {
-	bmp_image_t *bmp=(bmp_image_t *)addr;
+	struct bmp_image *bmp = (struct bmp_image *)addr;
 	void *bmp_alloc_addr = NULL;
 	unsigned long len;
 
@@ -224,7 +224,7 @@
 int bmp_display(ulong addr, int x, int y)
 {
 	int ret;
-	bmp_image_t *bmp = (bmp_image_t *)addr;
+	struct bmp_image *bmp = (struct bmp_image *)addr;
 	void *bmp_alloc_addr = NULL;
 	unsigned long len;
 
diff --git a/common/lcd.c b/common/lcd.c
index 055c366..5a52fe4 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -448,8 +448,8 @@
 /*
  * Do not call this function directly, must be called from lcd_display_bitmap.
  */
-static void lcd_display_rle8_bitmap(bmp_image_t *bmp, ushort *cmap, uchar *fb,
-				    int x_off, int y_off)
+static void lcd_display_rle8_bitmap(struct bmp_image *bmp, ushort *cmap,
+				    uchar *fb, int x_off, int y_off)
 {
 	uchar *bmap;
 	ulong width, height;
@@ -548,10 +548,10 @@
 }
 #endif /* CONFIG_BMP_16BPP */
 
-__weak void lcd_set_cmap(bmp_image_t *bmp, unsigned colors)
+__weak void lcd_set_cmap(struct bmp_image *bmp, unsigned colors)
 {
 	int i;
-	bmp_color_table_entry_t cte;
+	struct bmp_color_table_entry cte;
 	ushort *cmap = configuration_get_cmap();
 
 	for (i = 0; i < colors; ++i) {
@@ -572,12 +572,14 @@
 	ushort *cmap_base = NULL;
 	ushort i, j;
 	uchar *fb;
-	bmp_image_t *bmp = (bmp_image_t *)map_sysmem(bmp_image, 0);
+	struct bmp_image *bmp = (struct bmp_image *)map_sysmem(bmp_image, 0);
 	uchar *bmap;
 	ushort padded_width;
 	unsigned long width, height, byte_width;
 	unsigned long pwidth = panel_info.vl_col;
 	unsigned colors, bpix, bmp_bpix;
+	int hdr_size;
+	struct bmp_color_table_entry *palette = bmp->color_table;
 
 	if (!bmp || !(bmp->header.signature[0] == 'B' &&
 		bmp->header.signature[1] == 'M')) {
@@ -589,6 +591,8 @@
 	width = get_unaligned_le32(&bmp->header.width);
 	height = get_unaligned_le32(&bmp->header.height);
 	bmp_bpix = get_unaligned_le16(&bmp->header.bit_count);
+	hdr_size = get_unaligned_le16(&bmp->header.size);
+	debug("hdr_size=%d, bmp_bpix=%d\n", hdr_size, bmp_bpix);
 
 	colors = 1 << bmp_bpix;
 
@@ -613,8 +617,8 @@
 		return 1;
 	}
 
-	debug("Display-bmp: %d x %d  with %d colors\n",
-		(int)width, (int)height, (int)colors);
+	debug("Display-bmp: %d x %d  with %d colors, display %d\n",
+	      (int)width, (int)height, (int)colors, 1 << bpix);
 
 	if (bmp_bpix == 8)
 		lcd_set_cmap(bmp, colors);
@@ -641,6 +645,7 @@
 		cmap_base = configuration_get_cmap();
 #ifdef CONFIG_LCD_BMP_RLE8
 		u32 compression = get_unaligned_le32(&bmp->header.compression);
+		debug("compressed %d %d\n", compression, BMP_BI_RLE8);
 		if (compression == BMP_BI_RLE8) {
 			if (bpix != 16) {
 				/* TODO implement render code for bpix != 16 */
@@ -663,7 +668,19 @@
 				if (bpix != 16) {
 					fb_put_byte(&fb, &bmap);
 				} else {
-					*(uint16_t *)fb = cmap_base[*(bmap++)];
+					struct bmp_color_table_entry *entry;
+					uint val;
+
+					if (cmap_base) {
+						val = cmap_base[*bmap];
+					} else {
+						entry = &palette[*bmap];
+						val = entry->blue >> 3 |
+							entry->green >> 2 << 5 |
+							entry->red >> 3 << 11;
+					}
+					*(uint16_t *)fb = val;
+					bmap++;
 					fb += sizeof(uint16_t) / sizeof(*fb);
 				}
 			}
diff --git a/common/malloc_simple.c b/common/malloc_simple.c
index d445199..9811ab6 100644
--- a/common/malloc_simple.c
+++ b/common/malloc_simple.c
@@ -26,6 +26,20 @@
 	return ptr;
 }
 
+void *memalign_simple(size_t align, size_t bytes)
+{
+	ulong addr, new_ptr;
+	void *ptr;
+
+	addr = ALIGN(gd->malloc_base + gd->malloc_ptr, bytes);
+	new_ptr = addr + bytes;
+	if (new_ptr > gd->malloc_limit)
+		return NULL;
+	ptr = map_sysmem(addr, bytes);
+	gd->malloc_ptr = ALIGN(new_ptr, sizeof(new_ptr));
+	return ptr;
+}
+
 #ifdef CONFIG_SYS_MALLOC_SIMPLE
 void *calloc(size_t nmemb, size_t elem_size)
 {
diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig
index a8584e9..67ad959 100644
--- a/configs/am335x_boneblack_vboot_defconfig
+++ b/configs/am335x_boneblack_vboot_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_TARGET_AM335X_EVM=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-boneblack"
 CONFIG_SPL=y
 CONFIG_SPL_STACK_R=y
diff --git a/configs/arches_defconfig b/configs/arches_defconfig
index 469dace..c55357b 100644
--- a/configs/arches_defconfig
+++ b/configs/arches_defconfig
@@ -6,3 +6,4 @@
 CONFIG_CMD_SETEXPR=y
 CONFIG_CMD_NET=y
 CONFIG_OF_CONTROL=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
diff --git a/configs/canyonlands_defconfig b/configs/canyonlands_defconfig
index 12d3352..e838a6c 100644
--- a/configs/canyonlands_defconfig
+++ b/configs/canyonlands_defconfig
@@ -6,4 +6,5 @@
 CONFIG_CMD_SETEXPR=y
 CONFIG_CMD_NET=y
 CONFIG_OF_CONTROL=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 CONFIG_OF_EMBED=y
diff --git a/configs/galileo_defconfig b/configs/galileo_defconfig
index a3b564e..5045510 100644
--- a/configs/galileo_defconfig
+++ b/configs/galileo_defconfig
@@ -5,5 +5,6 @@
 CONFIG_TARGET_GALILEO=y
 CONFIG_CMD_NET=y
 CONFIG_OF_CONTROL=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_GENERATE_PIRQ_TABLE=y
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig
index 5740359..1e4cf7b 100644
--- a/configs/microblaze-generic_defconfig
+++ b/configs/microblaze-generic_defconfig
@@ -4,4 +4,5 @@
 CONFIG_SPL=y
 CONFIG_CMD_NET=y
 CONFIG_OF_CONTROL=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 CONFIG_OF_EMBED=y
diff --git a/configs/odroid_defconfig b/configs/odroid_defconfig
index 5efcdf5..41005c7 100644
--- a/configs/odroid_defconfig
+++ b/configs/odroid_defconfig
@@ -2,6 +2,7 @@
 CONFIG_ARCH_EXYNOS=y
 CONFIG_TARGET_ODROID=y
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos4412-odroid"
 CONFIG_CMD_SETEXPR=y
 CONFIG_CMD_NET=y
diff --git a/configs/origen_defconfig b/configs/origen_defconfig
index 3c59b9b..657ef7e 100644
--- a/configs/origen_defconfig
+++ b/configs/origen_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
 CONFIG_TARGET_ORIGEN=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos4210-origen"
 CONFIG_SPL=y
 CONFIG_CMD_SETEXPR=y
diff --git a/configs/s5pc210_universal_defconfig b/configs/s5pc210_universal_defconfig
index 633698e..32ac86a 100644
--- a/configs/s5pc210_universal_defconfig
+++ b/configs/s5pc210_universal_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
 CONFIG_TARGET_S5PC210_UNIVERSAL=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos4210-universal_c210"
 CONFIG_CMD_SETEXPR=y
 CONFIG_OF_CONTROL=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 345b701..31fe2f9 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -41,3 +41,4 @@
 CONFIG_UT_TIME=y
 CONFIG_UT_DM=y
 CONFIG_UT_ENV=y
+CONFIG_SANDBOX_SERIAL=y
diff --git a/configs/socfpga_socrates_defconfig b/configs/socfpga_socrates_defconfig
index bbe4e80..c9fcb74 100644
--- a/configs/socfpga_socrates_defconfig
+++ b/configs/socfpga_socrates_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_ARCH_SOCFPGA=y
 CONFIG_TARGET_SOCFPGA_CYCLONE5=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 CONFIG_NETDEVICES=y
 CONFIG_DEFAULT_DEVICE_TREE="socfpga_cyclone5_socrates"
 CONFIG_SPL=y
diff --git a/configs/trats2_defconfig b/configs/trats2_defconfig
index 75a8aec..52e87a1 100644
--- a/configs/trats2_defconfig
+++ b/configs/trats2_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
 CONFIG_TARGET_TRATS2=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_DEFAULT_DEVICE_TREE="exynos4412-trats2"
 CONFIG_CMD_SETEXPR=y
diff --git a/configs/trats_defconfig b/configs/trats_defconfig
index a1aa892..25315b3 100644
--- a/configs/trats_defconfig
+++ b/configs/trats_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
 CONFIG_TARGET_TRATS=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos4210-trats"
 CONFIG_CMD_SETEXPR=y
 CONFIG_OF_CONTROL=y
diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig
index 9215ac5..03f4bf7 100644
--- a/configs/zynq_microzed_defconfig
+++ b/configs/zynq_microzed_defconfig
@@ -4,6 +4,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="zynq-microzed"
 # CONFIG_SYS_MALLOC_F is not set
 CONFIG_SPL=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
diff --git a/configs/zynq_zc70x_defconfig b/configs/zynq_zc70x_defconfig
index a018b6e..7377619 100644
--- a/configs/zynq_zc70x_defconfig
+++ b/configs/zynq_zc70x_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ZYNQ=y
 CONFIG_TARGET_ZYNQ_ZC70X=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702"
 # CONFIG_SYS_MALLOC_F is not set
 CONFIG_SPL=y
diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig
index 7c83e8b..c948ad7 100644
--- a/configs/zynq_zc770_xm010_defconfig
+++ b/configs/zynq_zc770_xm010_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ZYNQ=y
 CONFIG_TARGET_ZYNQ_ZC770=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010"
 # CONFIG_SYS_MALLOC_F is not set
 CONFIG_SPL=y
diff --git a/configs/zynq_zc770_xm012_defconfig b/configs/zynq_zc770_xm012_defconfig
index 2659d0a..3429bf9 100644
--- a/configs/zynq_zc770_xm012_defconfig
+++ b/configs/zynq_zc770_xm012_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ZYNQ=y
 CONFIG_TARGET_ZYNQ_ZC770=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012"
 # CONFIG_SYS_MALLOC_F is not set
 CONFIG_SPL=y
diff --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig
index 64624ea..a435229 100644
--- a/configs/zynq_zc770_xm013_defconfig
+++ b/configs/zynq_zc770_xm013_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ZYNQ=y
 CONFIG_TARGET_ZYNQ_ZC770=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013"
 # CONFIG_SYS_MALLOC_F is not set
 CONFIG_SPL=y
diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig
index 55d58a7..8f94d21 100644
--- a/configs/zynq_zed_defconfig
+++ b/configs/zynq_zed_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ZYNQ=y
 CONFIG_TARGET_ZYNQ_ZED=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zed"
 # CONFIG_SYS_MALLOC_F is not set
 CONFIG_SPL=y
diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig
index f119532..1849c74 100644
--- a/configs/zynq_zybo_defconfig
+++ b/configs/zynq_zybo_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ZYNQ=y
 CONFIG_TARGET_ZYNQ_ZYBO=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo"
 # CONFIG_SYS_MALLOC_F is not set
 CONFIG_SPL=y
diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index f14695b..a3fec38 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -5,5 +5,7 @@
 #
 
 obj-$(CONFIG_DM)	+= device.o lists.o root.o uclass.o util.o
+ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_OF_CONTROL) += simple-bus.o
+endif
 obj-$(CONFIG_DM_DEVICE_REMOVE)	+= device-remove.o
diff --git a/drivers/i2c/i2c-uclass-compat.c b/drivers/i2c/i2c-uclass-compat.c
index 223f238..5606d1f 100644
--- a/drivers/i2c/i2c-uclass-compat.c
+++ b/drivers/i2c/i2c-uclass-compat.c
@@ -106,3 +106,24 @@
 {
 	/* Nothing to do here - the init happens through driver model */
 }
+
+uint8_t i2c_reg_read(uint8_t chip_addr, uint8_t offset)
+{
+	struct udevice *dev;
+	int ret;
+
+	ret = i2c_compat_get_device(chip_addr, 1, &dev);
+	if (ret)
+		return 0xff;
+	return dm_i2c_reg_read(dev, offset);
+}
+
+void i2c_reg_write(uint8_t chip_addr, uint8_t offset, uint8_t val)
+{
+	struct udevice *dev;
+	int ret;
+
+	ret = i2c_compat_get_device(chip_addr, 1, &dev);
+	if (!ret)
+		dm_i2c_reg_write(dev, offset, val);
+}
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 5611fac..4829284 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -76,6 +76,26 @@
 	  value. Use this value to specify the shift to use, where 0=byte
 	  registers, 2=32-bit word registers, etc.
 
+config SANDBOX_SERIAL
+	bool "Sandbox UART support"
+	depends on SANDBOX && DM
+	help
+	  Select this to enable a seral UART for sandbox. This is required to
+	  operate correctly, otherwise you will see no serial output from
+	  sandbox. The emulated UART will display to the console and console
+	  input will be fed into the UART. This allows you to interact with
+	  U-Boot.
+
+	  The operation of the console is controlled by the -t command-line
+	  flag. In raw mode, U-Boot sees all characters from the terminal
+	  before they are processed, including Ctrl-C. In cooked mode, Ctrl-C
+	  is processed by the terminal, and terminates U-Boot. Valid options
+	  are:
+
+	     -t raw-with-sigs	Raw mode, Ctrl-C will terminate U-Boot
+	     -t raw		Raw mode, Ctrl-C is processed by U-Boot
+	     -t cooked		Cooked mode, Ctrl-C terminates
+
 config UNIPHIER_SERIAL
 	bool "Support for UniPhier on-chip UART"
 	depends on ARCH_UNIPHIER && DM_SERIAL
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 3d376d7..9b044a3 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -65,6 +65,8 @@
 	out_le32(addr, value);
 #elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN)
 	out_be32(addr, value);
+#elif defined(CONFIG_SYS_NS16550_MEM32)
+	writel(value, addr);
 #elif defined(CONFIG_SYS_BIG_ENDIAN)
 	writeb(value, addr + (1 << shift) - 1);
 #else
@@ -80,6 +82,8 @@
 	return in_le32(addr);
 #elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN)
 	return in_be32(addr);
+#elif defined(CONFIG_SYS_NS16550_MEM32)
+	return readl(addr);
 #elif defined(CONFIG_SYS_BIG_ENDIAN)
 	return readb(addr + (1 << shift) - 1);
 #else
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index b8c2f48..815fec3 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -30,49 +30,55 @@
 static void serial_find_console_or_panic(void)
 {
 	struct udevice *dev;
-
-#ifdef CONFIG_OF_CONTROL
 	int node;
 
-	/* Check for a chosen console */
-	node = fdtdec_get_chosen_node(gd->fdt_blob, "stdout-path");
-	if (node < 0)
-		node = fdt_path_offset(gd->fdt_blob, "console");
-	if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, &dev)) {
-		gd->cur_serial_dev = dev;
-		return;
-	}
-
-	/*
-	 * If the console is not marked to be bound before relocation, bind
-	 * it anyway.
-	 */
-	if (node > 0 &&
-	    !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &dev)) {
-		if (!device_probe(dev)) {
+	if (OF_CONTROL && gd->fdt_blob) {
+		/* Check for a chosen console */
+		node = fdtdec_get_chosen_node(gd->fdt_blob, "stdout-path");
+		if (node < 0)
+			node = fdt_path_offset(gd->fdt_blob, "console");
+		if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node,
+						    &dev)) {
 			gd->cur_serial_dev = dev;
 			return;
 		}
+
+		/*
+		* If the console is not marked to be bound before relocation,
+		* bind it anyway.
+		*/
+		if (node > 0 &&
+		    !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &dev)) {
+			if (!device_probe(dev)) {
+				gd->cur_serial_dev = dev;
+				return;
+			}
+		}
 	}
-#endif
-	/*
-	 * Try to use CONFIG_CONS_INDEX if available (it is numbered from 1!).
-	 *
-	 * Failing that, get the device with sequence number 0, or in extremis
-	 * just the first serial device we can find. But we insist on having
-	 * a console (even if it is silent).
-	 */
+	if (!SPL_BUILD || !OF_CONTROL || !gd->fdt_blob) {
+		/*
+		* Try to use CONFIG_CONS_INDEX if available (it is numbered
+		* from 1!).
+		*
+		* Failing that, get the device with sequence number 0, or in
+		* extremis just the first serial device we can find. But we
+		* insist on having a console (even if it is silent).
+		*/
 #ifdef CONFIG_CONS_INDEX
 #define INDEX (CONFIG_CONS_INDEX - 1)
 #else
 #define INDEX 0
 #endif
-	if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) &&
-	    uclass_get_device(UCLASS_SERIAL, INDEX, &dev) &&
-	    (uclass_first_device(UCLASS_SERIAL, &dev) || !dev))
-		panic_str("No serial driver found");
+		if (!uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) ||
+		    !uclass_get_device(UCLASS_SERIAL, INDEX, &dev) ||
+		    (!uclass_first_device(UCLASS_SERIAL, &dev) || dev)) {
+			gd->cur_serial_dev = dev;
+			return;
+		}
 #undef INDEX
-	gd->cur_serial_dev = dev;
+	}
+
+	panic_str("No serial driver found");
 }
 
 /* Called prior to relocation */
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 27705d6..e2574d7 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -35,12 +35,6 @@
 	#endif
 #endif
 
-#ifndef CONFIG_DM_USB
-enum {
-	USB_PORTS_MAX	= 3,		/* Maximum ports we allow */
-};
-#endif
-
 /* Parameters we need for USB */
 enum {
 	PARAM_DIVN,                     /* PLL FEEDBACK DIVIDer */
@@ -82,9 +76,6 @@
 	unsigned ulpi:1;	/* 1 if port has external ULPI transceiver */
 	unsigned enabled:1;	/* 1 to enable, 0 to disable */
 	unsigned has_legacy_mode:1; /* 1 if this port has legacy mode */
-#ifndef CONFIG_DM_USB
-	unsigned initialized:1; /* has this port already been initialized? */
-#endif
 	enum usb_ctlr_type type;
 	enum usb_init_type init_type;
 	enum dr_mode dr_mode;	/* dual role mode */
@@ -93,11 +84,6 @@
 	struct gpio_desc phy_reset_gpio; /* GPIO to reset ULPI phy */
 };
 
-#ifndef CONFIG_DM_USB
-static struct fdt_usb port[USB_PORTS_MAX];	/* List of valid USB ports */
-static unsigned port_count;			/* Number of available ports */
-#endif
-
 /*
  * This table has USB timing parameters for each Oscillator frequency we
  * support. There are four sets of values:
@@ -173,8 +159,6 @@
 static const u8 utmip_hs_sync_start_delay = 9;
 
 struct fdt_usb_controller {
-	/* TODO(sjg@chromium.org): Remove when we only use driver model */
-	int compat;
 	/* flag to determine whether controller supports hostpc register */
 	u32 has_hostpc:1;
 	const unsigned *pll_parameter;
@@ -182,17 +166,14 @@
 
 static struct fdt_usb_controller fdt_usb_controllers[USB_CTRL_COUNT] = {
 	{
-		.compat		= COMPAT_NVIDIA_TEGRA20_USB,
 		.has_hostpc	= 0,
 		.pll_parameter	= (const unsigned *)T20_usb_pll,
 	},
 	{
-		.compat		= COMPAT_NVIDIA_TEGRA30_USB,
 		.has_hostpc	= 1,
 		.pll_parameter	= (const unsigned *)T30_usb_pll,
 	},
 	{
-		.compat		= COMPAT_NVIDIA_TEGRA114_USB,
 		.has_hostpc	= 1,
 		.pll_parameter	= (const unsigned *)T114_usb_pll,
 	},
@@ -754,12 +735,6 @@
 		return -1;
 	}
 
-#ifndef CONFIG_DM_USB
-	/* skip init, if the port is already initialized */
-	if (config->initialized && config->init_type == init)
-		return 0;
-#endif
-
 	debug("%d, %d\n", config->utmi, config->ulpi);
 	if (config->utmi)
 		ret = init_utmi_usb_controller(config, init);
@@ -796,130 +771,6 @@
 	.powerup_fixup		= tegra_ehci_powerup_fixup,
 };
 
-#ifndef CONFIG_DM_USB
-/*
- * process_usb_nodes() - Process a list of USB nodes, adding them to our list
- *			of USB ports.
- * @blob:	fdt blob
- * @node_list:	list of nodes to process (any <=0 are ignored)
- * @count:	number of nodes to process
- * @id:		controller type (enum usb_ctlr_type)
- *
- * Return:	0 - ok, -1 - error
- */
-static int process_usb_nodes(const void *blob, int node_list[], int count,
-			     enum usb_ctlr_type id)
-{
-	struct fdt_usb config;
-	int node, i;
-	int clk_done = 0;
-
-	port_count = 0;
-	for (i = 0; i < count; i++) {
-		if (port_count == USB_PORTS_MAX) {
-			printf("tegrausb: Cannot register more than %d ports\n",
-				USB_PORTS_MAX);
-			return -1;
-		}
-
-		debug("USB %d: ", i);
-		node = node_list[i];
-		if (!node)
-			continue;
-		if (fdt_decode_usb(blob, node, &config)) {
-			debug("Cannot decode USB node %s\n",
-			      fdt_get_name(blob, node, NULL));
-			return -1;
-		}
-		if (!clk_done) {
-			config_clock(get_pll_timing(
-					&fdt_usb_controllers[id]));
-			clk_done = 1;
-		}
-		config.type = id;
-		config.initialized = 0;
-
-		/* add new USB port to the list of available ports */
-		port[port_count++] = config;
-	}
-
-	return 0;
-}
-
-int usb_process_devicetree(const void *blob)
-{
-	int node_list[USB_PORTS_MAX];
-	int count, err = 0;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(fdt_usb_controllers); i++) {
-		count = fdtdec_find_aliases_for_id(blob, "usb",
-			fdt_usb_controllers[i].compat, node_list,
-			USB_PORTS_MAX);
-		if (count) {
-			err = process_usb_nodes(blob, node_list, count, i);
-			if (err)
-				printf("%s: Error processing USB node!\n",
-				       __func__);
-			return err;
-		}
-	}
-
-	return err;
-}
-
-/**
- * Start up the given port number (ports are numbered from 0 on each board).
- * This returns values for the appropriate hccr and hcor addresses to use for
- * USB EHCI operations.
- *
- * @param index	port number to start
- * @param hccr		returns start address of EHCI HCCR registers
- * @param hcor		returns start address of EHCI HCOR registers
- * @return 0 if ok, -1 on error (generally invalid port number)
- */
-int ehci_hcd_init(int index, enum usb_init_type init,
-		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
-{
-	struct fdt_usb *config;
-	struct usb_ctlr *usbctlr;
-	int ret;
-
-	if (index >= port_count)
-		return -1;
-
-	config = &port[index];
-	ehci_set_controller_priv(index, config, &tegra_ehci_ops);
-
-	ret = usb_common_init(config, init);
-	if (ret) {
-		printf("tegrausb: Cannot init port %d\n", index);
-		return ret;
-	}
-
-	config->initialized = 1;
-
-	usbctlr = config->reg;
-	*hccr = (struct ehci_hccr *)&usbctlr->cap_length;
-	*hcor = (struct ehci_hcor *)&usbctlr->usb_cmd;
-
-	return 0;
-}
-
-/*
- * Bring down the specified USB controller
- */
-int ehci_hcd_stop(int index)
-{
-	usb_common_uninit(&port[index]);
-
-	port[index].initialized = 0;
-
-	return 0;
-}
-#endif /* !CONFIG_DM_USB */
-
-#ifdef CONFIG_DM_USB
 static int ehci_usb_ofdata_to_platdata(struct udevice *dev)
 {
 	struct fdt_usb *priv = dev_get_priv(dev);
@@ -987,4 +838,3 @@
 	.priv_auto_alloc_size = sizeof(struct fdt_usb),
 	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
 };
-#endif
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 963464c..6e86f4a 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -628,6 +628,49 @@
 	return 0;
 }
 
+/*
+ * Detect if a USB device has been plugged or unplugged.
+ */
+int usb_detect_change(void)
+{
+	struct udevice *hub;
+	struct uclass *uc;
+	int change = 0;
+	int ret;
+
+	ret = uclass_get(UCLASS_USB_HUB, &uc);
+	if (ret)
+		return ret;
+
+	uclass_foreach_dev(hub, uc) {
+		struct usb_device *udev;
+		struct udevice *dev;
+
+		if (!device_active(hub))
+			continue;
+		for (device_find_first_child(hub, &dev);
+		     dev;
+		     device_find_next_child(&dev)) {
+			struct usb_port_status status;
+
+			if (!device_active(dev))
+				continue;
+
+			udev = dev_get_parentdata(dev);
+			if (usb_get_port_status(udev, udev->portnr, &status)
+					< 0)
+				/* USB request failed */
+				continue;
+
+			if (le16_to_cpu(status.wPortChange) &
+			    USB_PORT_STAT_C_CONNECTION)
+				change++;
+		}
+	}
+
+	return change;
+}
+
 int usb_child_post_bind(struct udevice *dev)
 {
 	struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 4ed3a49..d43d8a5 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -81,12 +81,12 @@
 #endif
 }
 
-void lcd_set_cmap(bmp_image_t *bmp, unsigned colors)
+void lcd_set_cmap(struct bmp_image *bmp, unsigned colors)
 {
 	int i;
 
 	for (i = 0; i < colors; ++i) {
-		bmp_color_table_entry_t cte = bmp->color_table[i];
+		struct bmp_color_table_entry cte = bmp->color_table[i];
 		lcd_setcolreg(i, cte.red, cte.green, cte.blue);
 	}
 }
diff --git a/drivers/video/bus_vcxk.c b/drivers/video/bus_vcxk.c
index 60a5cc5..2f54d3d 100644
--- a/drivers/video/bus_vcxk.c
+++ b/drivers/video/bus_vcxk.c
@@ -358,7 +358,7 @@
 
 int vcxk_display_bitmap(ulong addr, int x, int y)
 {
-	bmp_image_t *bmp;
+	struct bmp_image *bmp;
 	unsigned long width;
 	unsigned long height;
 	unsigned long bpp;
@@ -369,7 +369,7 @@
 	unsigned long c_height;
 	unsigned char *dataptr;
 
-	bmp = (bmp_image_t *) addr;
+	bmp = (struct bmp_image *)addr;
 	if ((bmp->header.signature[0] == 'B') &&
 	    (bmp->header.signature[1] == 'M')) {
 		width        = le32_to_cpu(bmp->header.width);
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index f4231b8..7f2ddc1 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -1295,7 +1295,7 @@
 	*fb = (uchar *) addr;	/* return modified address */
 }
 
-static int display_rle8_bitmap(bmp_image_t *img, int xoff, int yoff,
+static int display_rle8_bitmap(struct bmp_image *img, int xoff, int yoff,
 			       int width, int height)
 {
 	unsigned char *bm;
@@ -1304,7 +1304,7 @@
 	int decode = 1;
 	int x, y, bpp, i, ncolors;
 	struct palette p[256];
-	bmp_color_table_entry_t cte;
+	struct bmp_color_table_entry cte;
 	int green_shift, red_off;
 	int limit = VIDEO_COLS * VIDEO_ROWS;
 	int pixels = 0;
@@ -1447,13 +1447,13 @@
 {
 	ushort xcount, ycount;
 	uchar *fb;
-	bmp_image_t *bmp = (bmp_image_t *) bmp_image;
+	struct bmp_image *bmp = (struct bmp_image *)bmp_image;
 	uchar *bmap;
 	ushort padded_line;
 	unsigned long width, height, bpp;
 	unsigned colors;
 	unsigned long compression;
-	bmp_color_table_entry_t cte;
+	struct bmp_color_table_entry cte;
 
 #ifdef CONFIG_VIDEO_BMP_GZIP
 	unsigned char *dst = NULL;
@@ -1495,7 +1495,7 @@
 		/*
 		 * Set addr to decompressed image
 		 */
-		bmp = (bmp_image_t *)(dst+2);
+		bmp = (struct bmp_image *)(dst+2);
 
 		if (!((bmp->header.signature[0] == 'B') &&
 		      (bmp->header.signature[1] == 'M'))) {
diff --git a/include/bmp_layout.h b/include/bmp_layout.h
index 22b1fbc..55db8b8 100644
--- a/include/bmp_layout.h
+++ b/include/bmp_layout.h
@@ -11,17 +11,17 @@
 #ifndef _BMP_H_
 #define _BMP_H_
 
-typedef struct bmp_color_table_entry {
+struct __packed bmp_color_table_entry {
 	__u8	blue;
 	__u8	green;
 	__u8	red;
 	__u8	reserved;
-} __attribute__ ((packed)) bmp_color_table_entry_t;
+};
 
 /* When accessing these fields, remember that they are stored in little
    endian format, so use linux macros, e.g. le32_to_cpu(width)          */
 
-typedef struct bmp_header {
+struct __packed bmp_header {
 	/* Header */
 	char signature[2];
 	__u32	file_size;
@@ -40,15 +40,14 @@
 	__u32	colors_used;
 	__u32	colors_important;
 	/* ColorTable */
+};
 
-} __attribute__ ((packed)) bmp_header_t;
-
-typedef struct bmp_image {
-	bmp_header_t header;
+struct bmp_image {
+	struct bmp_header header;
 	/* We use a zero sized array just as a placeholder for variable
 	   sized array */
-	bmp_color_table_entry_t color_table[0];
-} bmp_image_t;
+	struct bmp_color_table_entry color_table[0];
+};
 
 /* Data in the bmp_image is aligned to this length */
 #define BMP_DATA_ALIGN	4
diff --git a/include/common.h b/include/common.h
index ea5aeb0..8f4b2ec 100644
--- a/include/common.h
+++ b/include/common.h
@@ -714,6 +714,21 @@
 void	invalidate_dcache_all(void);
 void	invalidate_icache_all(void);
 
+enum {
+	/* Disable caches (else flush caches but leave them active) */
+	CBL_DISABLE_CACHES		= 1 << 0,
+	CBL_SHOW_BOOTSTAGE_REPORT	= 1 << 1,
+
+	CBL_ALL				= 3,
+};
+
+/**
+ * Clean up ready for linux
+ *
+ * @param flags		Flags to control what is done
+ */
+int cleanup_before_linux_select(int flags);
+
 /* arch/$(ARCH)/lib/ticks.S */
 uint64_t get_ticks(void);
 void	wait_ticks    (unsigned long);
diff --git a/include/config_uncmd_spl.h b/include/config_uncmd_spl.h
index 38cb0e8..c191f56 100644
--- a/include/config_uncmd_spl.h
+++ b/include/config_uncmd_spl.h
@@ -20,7 +20,9 @@
 #undef CONFIG_CMD_SNTP
 #undef CONFIG_CMD_TFTPPUT
 #undef CONFIG_CMD_TFTPSRV
+#ifdef CONFIG_SPL_DISABLE_OF_CONTROL
 #undef CONFIG_OF_CONTROL
+#endif
 
 #ifndef CONFIG_SPL_DM
 #undef CONFIG_DM_SERIAL
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 3a857e2..3caa83c 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -113,7 +113,6 @@
 #define CONFIG_BAUDRATE			115200
 #define CONFIG_SYS_BAUDRATE_TABLE	{4800, 9600, 19200, 38400, 57600,\
 					115200}
-#define CONFIG_SANDBOX_SERIAL
 
 #define CONFIG_SYS_NO_FLASH
 
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 4fb8a2a..2323603 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -41,6 +41,12 @@
 	fdt_addr_t end;
 };
 
+#ifdef CONFIG_SPL_BUILD
+#define SPL_BUILD	1
+#else
+#define SPL_BUILD	0
+#endif
+
 #ifdef CONFIG_OF_CONTROL
 # if defined(CONFIG_SPL_BUILD) && defined(SPL_DISABLE_OF_CONTROL)
 #  define OF_CONTROL 0
@@ -122,9 +128,6 @@
  */
 enum fdt_compat_id {
 	COMPAT_UNKNOWN,
-	COMPAT_NVIDIA_TEGRA20_USB,	/* Tegra20 USB port */
-	COMPAT_NVIDIA_TEGRA30_USB,	/* Tegra30 USB port */
-	COMPAT_NVIDIA_TEGRA114_USB,	/* Tegra114 USB port */
 	COMPAT_NVIDIA_TEGRA20_EMC,	/* Tegra20 memory controller */
 	COMPAT_NVIDIA_TEGRA20_EMC_TABLE, /* Tegra20 memory timing table */
 	COMPAT_NVIDIA_TEGRA20_KBC,	/* Tegra20 Keyboard */
diff --git a/include/i2c.h b/include/i2c.h
index ddfebc4..9300d97 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -284,6 +284,12 @@
  */
 void board_i2c_init(const void *blob);
 
+/*
+ * Compatibility functions for driver model.
+ */
+uint8_t i2c_reg_read(uint8_t addr, uint8_t reg);
+void i2c_reg_write(uint8_t addr, uint8_t reg, uint8_t val);
+
 #endif
 
 /*
diff --git a/include/ns16550.h b/include/ns16550.h
index 0607379..4e62067 100644
--- a/include/ns16550.h
+++ b/include/ns16550.h
@@ -33,7 +33,7 @@
 
 #if !defined(CONFIG_SYS_NS16550_REG_SIZE) || (CONFIG_SYS_NS16550_REG_SIZE == 0)
 #error "Please define NS16550 registers size."
-#elif defined(CONFIG_SYS_NS16550_MEM32)
+#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_DM_SERIAL)
 #define UART_REG(x) u32 x
 #elif (CONFIG_SYS_NS16550_REG_SIZE > 0)
 #define UART_REG(x)						   \
diff --git a/include/spl.h b/include/spl.h
index b2e5bf7..d19940f 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -11,6 +11,8 @@
 #include <linux/compiler.h>
 #include <asm/spl.h>
 
+/* Value in r0 indicates we booted from U-Boot */
+#define UBOOT_NOT_LOADED_FROM_SPL	0x13578642
 
 /* Boot type */
 #define MMCSD_MODE_UNDEFINED	0
@@ -82,4 +84,15 @@
 #ifdef CONFIG_SPL_BOARD_INIT
 void spl_board_init(void);
 #endif
+
+/**
+ * spl_was_boot_source() - check if U-Boot booted from SPL
+ *
+ * This will normally be true, but if U-Boot jumps to second U-Boot, it will
+ * be false. This should be implemented by board-specific code.
+ *
+ * @return true if U-Boot booted from SPL, else false
+ */
+bool spl_was_boot_source(void);
+
 #endif
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 46dfcb6..9877849 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -22,9 +22,6 @@
 #define COMPAT(id, name) name
 static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(UNKNOWN, "<none>"),
-	COMPAT(NVIDIA_TEGRA20_USB, "nvidia,tegra20-ehci"),
-	COMPAT(NVIDIA_TEGRA30_USB, "nvidia,tegra30-ehci"),
-	COMPAT(NVIDIA_TEGRA114_USB, "nvidia,tegra114-ehci"),
 	COMPAT(NVIDIA_TEGRA20_EMC, "nvidia,tegra20-emc"),
 	COMPAT(NVIDIA_TEGRA20_EMC_TABLE, "nvidia,tegra20-emc-table"),
 	COMPAT(NVIDIA_TEGRA20_KBC, "nvidia,tegra20-kbc"),
diff --git a/scripts/Makefile.uncmd_spl b/scripts/Makefile.uncmd_spl
index 343c3fc..4f05652 100644
--- a/scripts/Makefile.uncmd_spl
+++ b/scripts/Makefile.uncmd_spl
@@ -3,7 +3,9 @@
 # TODO: Invent a better way
 
 ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_DISABLE_OF_CONTROL
 CONFIG_OF_CONTROL=
+endif
 
 ifndef CONFIG_SPL_DM
 CONFIG_DM_SERIAL=