Merge git://git.denx.de/u-boot-dm
diff --git a/Kconfig b/Kconfig
index e57fad4..9b8a807 100644
--- a/Kconfig
+++ b/Kconfig
@@ -66,6 +66,7 @@
 	default y if ARCH_MESON
 	default y if ARCH_ROCKCHIP
 	default n
+	imply USE_BOOTCOMMAND
 	select CMD_BOOTZ if ARM && !ARM64
 	select CMD_BOOTI if ARM64
 	select CMD_DHCP
diff --git a/Makefile b/Makefile
index 67f01ad..b5f81e3 100644
--- a/Makefile
+++ b/Makefile
@@ -1135,7 +1135,7 @@
 
 u-boot.rom: u-boot-x86-16bit.bin u-boot.bin \
 		$(if $(CONFIG_SPL_X86_16BIT_INIT),spl/u-boot-spl.bin) \
-		$(if $(CONFIG_HAVE_REFCODE),refcode.bin) checkbinman FORCE
+		$(if $(CONFIG_HAVE_REFCODE),refcode.bin) FORCE
 	$(call if_changed,binman)
 
 OBJCOPYFLAGS_u-boot-x86-16bit.bin := -O binary -j .start16 -j .resetvec
@@ -1144,8 +1144,7 @@
 endif
 
 ifneq ($(CONFIG_ARCH_SUNXI),)
-u-boot-sunxi-with-spl.bin: spl/sunxi-spl.bin u-boot.img u-boot.dtb \
-		checkbinman FORCE
+u-boot-sunxi-with-spl.bin: spl/sunxi-spl.bin u-boot.img u-boot.dtb FORCE
 	$(call if_changed,binman)
 endif
 
@@ -1379,18 +1378,6 @@
 $(timestamp_h): $(srctree)/Makefile FORCE
 	$(call filechk,timestamp.h)
 
-checkbinman: tools
-	@if ! ( echo 'import libfdt' | ( PYTHONPATH=tools $(PYTHON) )); then \
-		echo >&2; \
-		echo >&2 '*** binman needs the Python libfdt library.'; \
-		echo >&2 '*** Either install it on your system, or try:'; \
-		echo >&2 '***'; \
-		echo >&2 '*** sudo apt-get install swig libpython-dev'; \
-		echo >&2 '***'; \
-		echo >&2 '*** to have U-Boot build its own version.'; \
-		false; \
-	fi
-
 # ---------------------------------------------------------------------------
 quiet_cmd_cpp_lds = LDS     $@
 cmd_cpp_lds = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) \
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 30e71b2..94ad805 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -9,6 +9,22 @@
 	select PHYS_64BIT
 	select SYS_CACHE_SHIFT_6
 
+if ARM64
+config POSITION_INDEPENDENT
+	bool "Generate position-independent pre-relocation code"
+	help
+	  U-Boot expects to be linked to a specific hard-coded address, and to
+	  be loaded to and run from that address. This option lifts that
+	  restriction, thus allowing the code to be loaded to and executed
+	  from almost any address. This logic relies on the relocation
+	  information that is embedded into the binary to support U-Boot
+	  relocating itself to the top-of-RAM later during execution.
+endif
+
+config STATIC_RELA
+	bool
+	default y if ARM64 && !POSITION_INDEPENDENT
+
 config DMA_ADDR_T_64BIT
 	bool
 	default y if ARM64
@@ -675,6 +691,7 @@
 
 config ARCH_SUNXI
 	bool "Support sunxi (Allwinner) SoCs"
+	select BINMAN
 	select CMD_GPIO
 	select CMD_MMC if MMC
 	select CMD_USB if DISTRO_DEFAULTS
@@ -817,6 +834,7 @@
 	select ARMV8_MULTIENTRY
 	select ARCH_MISC_INIT
 	select BOARD_LATE_INIT
+	select SUPPORT_SPL
 	help
 	  Support for NXP LS1088AQDS platform
 	  The LS1088A Development System (QDS) is a high-performance
@@ -931,6 +949,7 @@
 	select ARMV8_MULTIENTRY
 	select ARCH_MISC_INIT
 	select BOARD_LATE_INIT
+	select SUPPORT_SPL
 	help
 	  Support for NXP LS1088ARDB platform.
 	  The LS1088A Reference design board (RDB) is a high-performance
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
index 8bbc981..5daf79e 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
+++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
@@ -84,6 +84,7 @@
 	select FSL_TZASC_1
 	select ARCH_EARLY_INIT_R
 	select BOARD_EARLY_INIT_F
+	imply SCSI
 
 config ARCH_LS2080A
 	bool
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3 b/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3
index 7867c37..025a1b7 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3
+++ b/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3
@@ -118,7 +118,7 @@
 mcboottimeout:	MC boot timeout in milliseconds. If this variable is not defined
 		the value CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS will be assumed.
 
-mcmemsize:	MC DRAM block size. If this variable is not defined, the value
+mcmemsize:	MC DRAM block size in hex. If this variable is not defined, the value
 		CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE will be assumed.
 
 mcinitcmd:	This environment variable is defined to initiate MC and DPL deployment
@@ -201,6 +201,50 @@
 Notice the difference from QDS is SRC, SRC_ADDR and the offset of u-boot image
 to match board NAND device with 4KB/page, block size 512KB.
 
+Booting from SD/eMMC
+-------------------
+Booting from SD/eMMC requires two images, RCW and u-boot-with-spl.bin.
+The difference between SD boot RCW image and QSPI-NOR boot image is the
+PBI command sequence. Below is one example for PBI commands for RDB
+and QDS which uses SD device with block size 512. Block location can be
+calculated by dividing offset with block size.
+
+1) Block Copy: SRC=0x0040, SRC_ADDR=0x00100000, DEST_ADDR=0x1800a000,
+BLOCK_SIZE=0x00016000
+
+This command copies u-boot image from SD device into OCRAM. The values
+need to adjust accordingly for SD/eMMC
+
+SRC		should match the cfg_rcw_src, the reset config pins.
+		The value for source(SRC) can be 0x0040 or 0x0041
+		depending upon SD or eMMC.
+SRC_ADDR	is the offset of u-boot-with-spl.bin image in SD device.
+		In the example above, 1MB. This is same as QSPI-NOR.
+DEST_ADDR	is configured at 0x1800a000, matching bootloc set above.
+BLOCK_SIZE	is the size to be copied by PBI.
+
+2) CCSR 4-byte write to 0x01e00404, data=0x00000000
+3) CCSR 4-byte write to 0x01e00400, data=0x1800a000
+The above two commands set bootloc register to 0x00000000_1800a000 where
+the u-boot code will be running in OCRAM.
+
+
+RCW image should be written at 8th block of device(SD/eMMC). Example of
+using u-boot command
+
+mmc erase 0x8 0x10
+mmc write <rcw image in memory> 0x8 <size of rcw in block count typical value=10>
+
+To form the SD-Boot image, build u-boot with SD config, for example,
+ls1088ardb_sdcard_qspi_defconfig. The image needed is u-boot-with-spl.bin.
+The u-boot image should be written to match SRC_ADDR, in above example
+offset 0x100000 in other work it means block location 0x800
+
+mmc erase 0x800 0x1800
+mmc write <u-boot image in memory> 0x800 <size of u-boot image in block count>
+
+With these two images in SD/eMMC device, the board can boot from SD/eMMC.
+
 MMU Translation Tables
 ======================
 
diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S
index 5c500be..03e744e 100644
--- a/arch/arm/cpu/armv8/start.S
+++ b/arch/arm/cpu/armv8/start.S
@@ -57,6 +57,32 @@
 .globl	save_boot_params_ret
 save_boot_params_ret:
 
+#if CONFIG_POSITION_INDEPENDENT
+	/*
+	 * Fix .rela.dyn relocations. This allows U-Boot to be loaded to and
+	 * executed at a different address than it was linked at.
+	 */
+pie_fixup:
+	adr	x0, _start		/* x0 <- Runtime value of _start */
+	ldr	x1, _TEXT_BASE		/* x1 <- Linked value of _start */
+	sub	x9, x0, x1		/* x9 <- Run-vs-link offset */
+	adr	x2, __rel_dyn_start	/* x2 <- Runtime &__rel_dyn_start */
+	adr	x3, __rel_dyn_end	/* x3 <- Runtime &__rel_dyn_end */
+pie_fix_loop:
+	ldp	x0, x1, [x2], #16	/* (x0, x1) <- (Link location, fixup) */
+	ldr	x4, [x2], #8		/* x4 <- addend */
+	cmp	w1, #1027		/* relative fixup? */
+	bne	pie_skip_reloc
+	/* relative fix: store addend plus offset at dest location */
+	add	x0, x0, x9
+	add	x4, x4, x9
+	str	x4, [x0]
+pie_skip_reloc:
+	cmp	x2, x3
+	b.lo	pie_fix_loop
+pie_fixup_done:
+#endif
+
 #ifdef CONFIG_SYS_RESET_SCTRL
 	bl reset_sctrl
 #endif
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 6db64f91..cd540e9 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -54,7 +54,8 @@
 	rk3399-puma-ddr1866.dtb \
 	rv1108-evb.dtb
 dtb-$(CONFIG_ARCH_MESON) += \
-	meson-gxbb-odroidc2.dtb
+	meson-gxbb-odroidc2.dtb \
+	meson-gxl-s905x-p212.dtb
 dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
 	tegra20-medcom-wide.dtb \
 	tegra20-paz00.dtb \
diff --git a/arch/arm/dts/armada-388-clearfog.dts b/arch/arm/dts/armada-388-clearfog.dts
index b2dfd56..bc52bc0 100644
--- a/arch/arm/dts/armada-388-clearfog.dts
+++ b/arch/arm/dts/armada-388-clearfog.dts
@@ -61,6 +61,7 @@
 		ethernet1 = &eth0;
 		ethernet2 = &eth1;
 		ethernet3 = &eth2;
+		spi1 = &spi1;
 	};
 
 	chosen {
@@ -330,11 +331,9 @@
 				status = "okay";
 			};
 
-			spi@10680 {
+			spi1: spi@10680 {
 				/*
-				 * We don't seem to have the W25Q32 on the
-				 * A1 Rev 2.0 boards, so disable SPI.
-				 * CS0: W25Q32 (doesn't appear to be present)
+				 * CS0: W25Q32
 				 * CS1:
 				 * CS2: mikrobus
 				 */
@@ -345,10 +344,9 @@
 				spi-flash@0 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "w25q32", "jedec,spi-nor";
+					compatible = "w25q32", "jedec,spi-nor", "spi-flash";
 					reg = <0>; /* Chip select 0 */
 					spi-max-frequency = <3000000>;
-					status = "disabled";
 				};
 			};
 
diff --git a/arch/arm/dts/dragonboard410c-uboot.dtsi b/arch/arm/dts/dragonboard410c-uboot.dtsi
index cc2c175..c3475c4 100644
--- a/arch/arm/dts/dragonboard410c-uboot.dtsi
+++ b/arch/arm/dts/dragonboard410c-uboot.dtsi
@@ -6,6 +6,13 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+/ {
+	config {
+		u-boot,mmc-env-partition = "boot";
+	};
+};
+
+
 &pm8916_gpios {
 	usb_hub_reset_pm {
 		gpios = <&pm8916_gpios 2 0>;
diff --git a/arch/arm/dts/meson-gx.dtsi b/arch/arm/dts/meson-gx.dtsi
index 436b875..738ed68 100644
--- a/arch/arm/dts/meson-gx.dtsi
+++ b/arch/arm/dts/meson-gx.dtsi
@@ -200,7 +200,7 @@
 		};
 
 		scpi_sensors: sensors {
-			compatible = "arm,scpi-sensors";
+			compatible = "amlogic,meson-gxbb-scpi-sensors", "arm,scpi-sensors";
 			#thermal-sensor-cells = <1>;
 		};
 	};
@@ -304,6 +304,15 @@
 				status = "disabled";
 			};
 
+			spicc: spi@8d80 {
+				compatible = "amlogic,meson-gx-spicc";
+				reg = <0x0 0x08d80 0x0 0x80>;
+				interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
 			spifc: spi@8c80 {
 				compatible = "amlogic,meson-gx-spifc", "amlogic,meson-gxbb-spifc";
 				reg = <0x0 0x08c80 0x0 0x80>;
@@ -391,7 +400,7 @@
 			};
 
 			pwm_AO_ab: pwm@550 {
-				compatible = "amlogic,meson-gx-pwm", "amlogic,meson-gxbb-pwm";
+				compatible = "amlogic,meson-gx-ao-pwm", "amlogic,meson-gxbb-ao-pwm";
 				reg = <0x0 0x00550 0x0 0x10>;
 				#pwm-cells = <3>;
 				status = "disabled";
diff --git a/arch/arm/dts/meson-gxbb-odroidc2.dts b/arch/arm/dts/meson-gxbb-odroidc2.dts
index 54a9c6a..d147c85 100644
--- a/arch/arm/dts/meson-gxbb-odroidc2.dts
+++ b/arch/arm/dts/meson-gxbb-odroidc2.dts
@@ -137,16 +137,6 @@
 	};
 };
 
-&scpi_clocks {
-	status = "disabled";
-};
-
-&uart_AO {
-	status = "okay";
-	pinctrl-0 = <&uart_ao_a_pins>;
-	pinctrl-names = "default";
-};
-
 &ethmac {
 	status = "okay";
 	pinctrl-0 = <&eth_rgmii_pins>;
@@ -172,6 +162,33 @@
 	};
 };
 
+&gpio_ao {
+	/*
+	 * WARNING: The USB Hub on the Odroid-C2 needs a reset signal
+	 * to be turned high in order to be detected by the USB Controller
+	 * This signal should be handled by a USB specific power sequence
+	 * in order to reset the Hub when USB bus is powered down.
+	 */
+	usb-hub {
+		gpio-hog;
+		gpios = <GPIOAO_4 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "usb-hub-reset";
+	};
+};
+
+&i2c_A {
+	status = "okay";
+	pinctrl-0 = <&i2c_a_pins>;
+	pinctrl-names = "default";
+};
+
+&ir {
+	status = "okay";
+	pinctrl-0 = <&remote_input_ao_pins>;
+	pinctrl-names = "default";
+};
+
 &pinctrl_aobus {
 	gpio-line-names = "UART TX", "UART RX", "VCCK En", "TF 3V3/1V8 En",
 			  "USB HUB nRESET", "USB OTG Power En",
@@ -223,55 +240,15 @@
 			  "";
 };
 
-&ir {
-	status = "okay";
-	pinctrl-0 = <&remote_input_ao_pins>;
-	pinctrl-names = "default";
-};
-
-&i2c_A {
-	status = "okay";
-	pinctrl-0 = <&i2c_a_pins>;
-	pinctrl-names = "default";
-};
-
-&gpio_ao {
-	/*
-	 * WARNING: The USB Hub on the Odroid-C2 needs a reset signal
-	 * to be turned high in order to be detected by the USB Controller
-	 * This signal should be handled by a USB specific power sequence
-	 * in order to reset the Hub when USB bus is powered down.
-	 */
-	usb-hub {
-		gpio-hog;
-		gpios = <GPIOAO_4 GPIO_ACTIVE_HIGH>;
-		output-high;
-		line-name = "usb-hub-reset";
-	};
-};
-
-&usb0_phy {
-	status = "okay";
-	phy-supply = <&usb_otg_pwr>;
-};
-
-&usb1_phy {
-	status = "okay";
-};
-
-&usb0 {
-	status = "okay";
-};
-
-&usb1 {
-	status = "okay";
-};
-
 &saradc {
 	status = "okay";
 	vref-supply = <&vcc1v8>;
 };
 
+&scpi_clocks {
+	status = "disabled";
+};
+
 /* SD */
 &sd_emmc_b {
 	status = "okay";
@@ -309,3 +286,26 @@
 	vmmc-supply = <&vcc3v3>;
 	vqmmc-supply = <&vcc1v8>;
 };
+
+&uart_AO {
+	status = "okay";
+	pinctrl-0 = <&uart_ao_a_pins>;
+	pinctrl-names = "default";
+};
+
+&usb0_phy {
+	status = "okay";
+	phy-supply = <&usb_otg_pwr>;
+};
+
+&usb1_phy {
+	status = "okay";
+};
+
+&usb0 {
+	status = "okay";
+};
+
+&usb1 {
+	status = "okay";
+};
diff --git a/arch/arm/dts/meson-gxbb.dtsi b/arch/arm/dts/meson-gxbb.dtsi
index 86105a6..17d3efd 100644
--- a/arch/arm/dts/meson-gxbb.dtsi
+++ b/arch/arm/dts/meson-gxbb.dtsi
@@ -97,13 +97,6 @@
 	};
 };
 
-&ethmac {
-	clocks = <&clkc CLKID_ETH>,
-		 <&clkc CLKID_FCLK_DIV2>,
-		 <&clkc CLKID_MPLL2>;
-	clock-names = "stmmaceth", "clkin0", "clkin1";
-};
-
 &aobus {
 	pinctrl_aobus: pinctrl@14 {
 		compatible = "amlogic,meson-gxbb-aobus-pinctrl";
@@ -249,9 +242,119 @@
 				function = "spdif_out_ao";
 			};
 		};
+
+		ao_cec_pins: ao_cec {
+			mux {
+				groups = "ao_cec";
+				function = "cec_ao";
+			};
+		};
+
+		ee_cec_pins: ee_cec {
+			mux {
+				groups = "ee_cec";
+				function = "cec_ao";
+			};
+		};
 	};
 };
 
+&apb {
+	mali: gpu@c0000 {
+		compatible = "amlogic,meson-gxbb-mali", "arm,mali-450";
+		reg = <0x0 0xc0000 0x0 0x40000>;
+		interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "gp", "gpmmu", "pp", "pmu",
+			"pp0", "ppmmu0", "pp1", "ppmmu1",
+			"pp2", "ppmmu2";
+		clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>;
+		clock-names = "bus", "core";
+
+		/*
+		 * Mali clocking is provided by two identical clock paths
+		 * MALI_0 and MALI_1 muxed to a single clock by a glitch
+		 * free mux to safely change frequency while running.
+		 */
+		assigned-clocks = <&clkc CLKID_MALI_0_SEL>,
+				  <&clkc CLKID_MALI_0>,
+				  <&clkc CLKID_MALI>; /* Glitch free mux */
+		assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>,
+					 <0>, /* Do Nothing */
+					 <&clkc CLKID_MALI_0>;
+		assigned-clock-rates = <0>, /* Do Nothing */
+				       <666666666>,
+				       <0>; /* Do Nothing */
+	};
+};
+
+&cbus {
+	spifc: spi@8c80 {
+		compatible = "amlogic,meson-gxbb-spifc";
+		reg = <0x0 0x08c80 0x0 0x80>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clocks = <&clkc CLKID_SPI>;
+		status = "disabled";
+	};
+};
+
+&ethmac {
+	clocks = <&clkc CLKID_ETH>,
+		 <&clkc CLKID_FCLK_DIV2>,
+		 <&clkc CLKID_MPLL2>;
+	clock-names = "stmmaceth", "clkin0", "clkin1";
+};
+
+&hdmi_tx {
+	compatible = "amlogic,meson-gxbb-dw-hdmi", "amlogic,meson-gx-dw-hdmi";
+	resets = <&reset RESET_HDMITX_CAPB3>,
+		 <&reset RESET_HDMI_SYSTEM_RESET>,
+		 <&reset RESET_HDMI_TX>;
+	reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy";
+	clocks = <&clkc CLKID_HDMI_PCLK>,
+		 <&clkc CLKID_CLK81>,
+		 <&clkc CLKID_GCLK_VENCI_INT0>;
+	clock-names = "isfr", "iahb", "venci";
+};
+
+&hiubus {
+	clkc: clock-controller@0 {
+		compatible = "amlogic,gxbb-clkc";
+		#clock-cells = <1>;
+		reg = <0x0 0x0 0x0 0x3db>;
+	};
+};
+
+&hwrng {
+	clocks = <&clkc CLKID_RNG0>;
+	clock-names = "core";
+};
+
+&i2c_A {
+	clocks = <&clkc CLKID_I2C>;
+};
+
+&i2c_AO {
+	clocks = <&clkc CLKID_AO_I2C>;
+};
+
+&i2c_B {
+	clocks = <&clkc CLKID_I2C>;
+};
+
+&i2c_C {
+	clocks = <&clkc CLKID_I2C>;
+};
+
 &periphs {
 	pinctrl_periphs: pinctrl@4b0 {
 		compatible = "amlogic,meson-gxbb-periphs-pinctrl";
@@ -262,7 +365,7 @@
 		gpio: bank@4b0 {
 			reg = <0x0 0x004b0 0x0 0x28>,
 			      <0x0 0x004e8 0x0 0x14>,
-			      <0x0 0x00120 0x0 0x14>,
+			      <0x0 0x00520 0x0 0x14>,
 			      <0x0 0x00430 0x0 0x40>;
 			reg-names = "mux", "pull", "pull-enable", "gpio";
 			gpio-controller;
@@ -290,6 +393,22 @@
 			};
 		};
 
+		spi_pins: spi {
+			mux {
+				groups = "spi_miso",
+					"spi_mosi",
+					"spi_sclk";
+				function = "spi";
+			};
+		};
+
+		spi_ss0_pins: spi-ss0 {
+			mux {
+				groups = "spi_ss0";
+				function = "spi";
+			};
+		};
+
 		sdcard_pins: sdcard {
 			mux {
 				groups = "sdcard_d0",
@@ -521,67 +640,6 @@
 	};
 };
 
-&hiubus {
-	clkc: clock-controller@0 {
-		compatible = "amlogic,gxbb-clkc";
-		#clock-cells = <1>;
-		reg = <0x0 0x0 0x0 0x3db>;
-	};
-};
-
-&apb {
-	mali: gpu@c0000 {
-		compatible = "amlogic,meson-gxbb-mali", "arm,mali-450";
-		reg = <0x0 0xc0000 0x0 0x40000>;
-		interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "gp", "gpmmu", "pp", "pmu",
-			"pp0", "ppmmu0", "pp1", "ppmmu1",
-			"pp2", "ppmmu2";
-		clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>;
-		clock-names = "bus", "core";
-
-		/*
-		 * Mali clocking is provided by two identical clock paths
-		 * MALI_0 and MALI_1 muxed to a single clock by a glitch
-		 * free mux to safely change frequency while running.
-		 */
-		assigned-clocks = <&clkc CLKID_MALI_0_SEL>,
-				  <&clkc CLKID_MALI_0>,
-				  <&clkc CLKID_MALI>; /* Glitch free mux */
-		assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>,
-					 <0>, /* Do Nothing */
-					 <&clkc CLKID_MALI_0>;
-		assigned-clock-rates = <0>, /* Do Nothing */
-				       <666666666>,
-				       <0>; /* Do Nothing */
-	};
-};
-
-&i2c_A {
-	clocks = <&clkc CLKID_I2C>;
-};
-
-&i2c_AO {
-	clocks = <&clkc CLKID_AO_I2C>;
-};
-
-&i2c_B {
-	clocks = <&clkc CLKID_I2C>;
-};
-
-&i2c_C {
-	clocks = <&clkc CLKID_I2C>;
-};
-
 &saradc {
 	compatible = "amlogic,meson-gxbb-saradc", "amlogic,meson-saradc";
 	clocks = <&xtal>,
@@ -613,6 +671,13 @@
 	clock-names = "core", "clkin0", "clkin1";
 };
 
+&spicc {
+	clocks = <&clkc CLKID_SPICC>;
+	clock-names = "core";
+	resets = <&reset RESET_PERIPHS_SPICC>;
+	num-cs = <1>;
+};
+
 &spifc {
 	clocks = <&clkc CLKID_SPI>;
 };
@@ -620,20 +685,3 @@
 &vpu {
 	compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu";
 };
-
-&hwrng {
-	clocks = <&clkc CLKID_RNG0>;
-	clock-names = "core";
-};
-
-&hdmi_tx {
-	compatible = "amlogic,meson-gxbb-dw-hdmi", "amlogic,meson-gx-dw-hdmi";
-	resets = <&reset RESET_HDMITX_CAPB3>,
-		 <&reset RESET_HDMI_SYSTEM_RESET>,
-		 <&reset RESET_HDMI_TX>;
-	reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy";
-	clocks = <&clkc CLKID_HDMI_PCLK>,
-		 <&clkc CLKID_CLK81>,
-		 <&clkc CLKID_GCLK_VENCI_INT0>;
-	clock-names = "isfr", "iahb", "venci";
-};
diff --git a/arch/arm/dts/meson-gxl-mali.dtsi b/arch/arm/dts/meson-gxl-mali.dtsi
new file mode 100644
index 0000000..f06cc23
--- /dev/null
+++ b/arch/arm/dts/meson-gxl-mali.dtsi
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017 BayLibre SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+&apb {
+	mali: gpu@c0000 {
+		compatible = "amlogic,meson-gxbb-mali", "arm,mali-450";
+		reg = <0x0 0xc0000 0x0 0x40000>;
+		interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "gp", "gpmmu", "pp", "pmu",
+			"pp0", "ppmmu0", "pp1", "ppmmu1",
+			"pp2", "ppmmu2";
+		clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>;
+		clock-names = "bus", "core";
+
+		/*
+		 * Mali clocking is provided by two identical clock paths
+		 * MALI_0 and MALI_1 muxed to a single clock by a glitch
+		 * free mux to safely change frequency while running.
+		 */
+		assigned-clocks = <&clkc CLKID_MALI_0_SEL>,
+				  <&clkc CLKID_MALI_0>,
+				  <&clkc CLKID_MALI>; /* Glitch free mux */
+		assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>,
+					 <0>, /* Do Nothing */
+					 <&clkc CLKID_MALI_0>;
+		assigned-clock-rates = <0>, /* Do Nothing */
+				       <666666666>,
+				       <0>; /* Do Nothing */
+	};
+};
diff --git a/arch/arm/dts/meson-gxl-s905x-p212.dts b/arch/arm/dts/meson-gxl-s905x-p212.dts
new file mode 100644
index 0000000..6ab17c1
--- /dev/null
+++ b/arch/arm/dts/meson-gxl-s905x-p212.dts
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 library 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 library 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 "meson-gxl-s905x-p212.dtsi"
+
+/ {
+	compatible = "amlogic,p212", "amlogic,s905x", "amlogic,meson-gxl";
+	model = "Amlogic Meson GXL (S905X) P212 Development Board";
+
+	cvbs-connector {
+		compatible = "composite-video-connector";
+
+		port {
+			cvbs_connector_in: endpoint {
+				remote-endpoint = <&cvbs_vdac_out>;
+			};
+		};
+	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&hdmi_tx_tmds_out>;
+			};
+		};
+	};
+};
+
+&cvbs_vdac_port {
+	cvbs_vdac_out: endpoint {
+		remote-endpoint = <&cvbs_connector_in>;
+	};
+};
+
+&hdmi_tx {
+	status = "okay";
+	pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
+	pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+	hdmi_tx_tmds_out: endpoint {
+		remote-endpoint = <&hdmi_connector_in>;
+	};
+};
+
+/* This UART is brought out to the DB9 connector */
+&uart_AO {
+	status = "okay";
+};
diff --git a/arch/arm/dts/meson-gxl-s905x-p212.dtsi b/arch/arm/dts/meson-gxl-s905x-p212.dtsi
new file mode 100644
index 0000000..f3eea8e
--- /dev/null
+++ b/arch/arm/dts/meson-gxl-s905x-p212.dtsi
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>.
+ * Based on meson-gx-p23x-q20x.dtsi:
+ * - Copyright (c) 2016 Endless Computers, Inc.
+ *   Author: Carlo Caione <carlo@endlessm.com>
+ * - Copyright (c) 2016 BayLibre, SAS.
+ *   Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+/* Common DTSI for devices which are based on the P212 reference board. */
+
+#include "meson-gxl-s905x.dtsi"
+
+/ {
+	aliases {
+		serial0 = &uart_AO;
+		serial1 = &uart_A;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>;
+	};
+
+	vddio_boot: regulator-vddio_boot {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDIO_BOOT";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	vddao_3v3: regulator-vddao_3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDAO_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vddio_ao18: regulator-vddio_ao18 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDIO_AO18";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	vcc_3v3: regulator-vcc_3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	emmc_pwrseq: emmc-pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+	};
+
+	wifi32k: wifi32k {
+		compatible = "pwm-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+		clocks = <&wifi32k>;
+		clock-names = "ext_clock";
+	};
+};
+
+&ethmac {
+	status = "okay";
+};
+
+&ir {
+	status = "okay";
+	pinctrl-0 = <&remote_input_ao_pins>;
+	pinctrl-names = "default";
+};
+
+&saradc {
+	status = "okay";
+	vref-supply = <&vddio_ao18>;
+};
+
+/* Wireless SDIO Module */
+&sd_emmc_a {
+	status = "okay";
+	pinctrl-0 = <&sdio_pins>;
+	pinctrl-names = "default";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	max-frequency = <100000000>;
+
+	non-removable;
+	disable-wp;
+
+	mmc-pwrseq = <&sdio_pwrseq>;
+
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddio_boot>;
+};
+
+/* SD card */
+&sd_emmc_b {
+	status = "okay";
+	pinctrl-0 = <&sdcard_pins>;
+	pinctrl-names = "default";
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	max-frequency = <100000000>;
+	disable-wp;
+
+	cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
+	cd-inverted;
+
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddio_boot>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+	status = "okay";
+	pinctrl-0 = <&emmc_pins>;
+	pinctrl-names = "default";
+
+	bus-width = <8>;
+	cap-sd-highspeed;
+	cap-mmc-highspeed;
+	max-frequency = <200000000>;
+	non-removable;
+	disable-wp;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+
+	mmc-pwrseq = <&emmc_pwrseq>;
+	vmmc-supply = <&vcc_3v3>;
+	vqmmc-supply = <&vddio_boot>;
+};
+
+&pwm_ef {
+	status = "okay";
+	pinctrl-0 = <&pwm_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&clkc CLKID_FCLK_DIV4>;
+	clock-names = "clkin0";
+};
+
+/* This is connected to the Bluetooth module: */
+&uart_A {
+	status = "okay";
+	pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+	pinctrl-names = "default";
+	uart-has-rtscts;
+};
+
+&uart_AO {
+	status = "okay";
+	pinctrl-0 = <&uart_ao_a_pins>;
+	pinctrl-names = "default";
+};
diff --git a/arch/arm/dts/meson-gxl-s905x.dtsi b/arch/arm/dts/meson-gxl-s905x.dtsi
new file mode 100644
index 0000000..3314a0b
--- /dev/null
+++ b/arch/arm/dts/meson-gxl-s905x.dtsi
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 library 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 library 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 "meson-gxl.dtsi"
+#include "meson-gxl-mali.dtsi"
+
+/ {
+	compatible = "amlogic,s905x", "amlogic,meson-gxl";
+};
+
+/* S905X only has access to its internal PHY */
+&ethmac {
+	phy-mode = "rmii";
+	phy-handle = <&internal_phy>;
+};
diff --git a/arch/arm/dts/meson-gxl.dtsi b/arch/arm/dts/meson-gxl.dtsi
new file mode 100644
index 0000000..8d4f316
--- /dev/null
+++ b/arch/arm/dts/meson-gxl.dtsi
@@ -0,0 +1,628 @@
+/*
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 library 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 library 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 "meson-gx.dtsi"
+#include <dt-bindings/clock/gxbb-clkc.h>
+#include <dt-bindings/gpio/meson-gxl-gpio.h>
+#include <dt-bindings/reset/amlogic,meson-gxbb-reset.h>
+
+/ {
+	compatible = "amlogic,meson-gxl";
+};
+
+&ethmac {
+	reg = <0x0 0xc9410000 0x0 0x10000
+	       0x0 0xc8834540 0x0 0x4>;
+
+	clocks = <&clkc CLKID_ETH>,
+		 <&clkc CLKID_FCLK_DIV2>,
+		 <&clkc CLKID_MPLL2>;
+	clock-names = "stmmaceth", "clkin0", "clkin1";
+
+	mdio0: mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "snps,dwmac-mdio";
+	};
+};
+
+&aobus {
+	pinctrl_aobus: pinctrl@14 {
+		compatible = "amlogic,meson-gxl-aobus-pinctrl";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gpio_ao: bank@14 {
+			reg = <0x0 0x00014 0x0 0x8>,
+			      <0x0 0x0002c 0x0 0x4>,
+			      <0x0 0x00024 0x0 0x8>;
+			reg-names = "mux", "pull", "gpio";
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_aobus 0 0 14>;
+		};
+
+		uart_ao_a_pins: uart_ao_a {
+			mux {
+				groups = "uart_tx_ao_a", "uart_rx_ao_a";
+				function = "uart_ao";
+			};
+		};
+
+		uart_ao_a_cts_rts_pins: uart_ao_a_cts_rts {
+			mux {
+				groups = "uart_cts_ao_a",
+				       "uart_rts_ao_a";
+				function = "uart_ao";
+			};
+		};
+
+		uart_ao_b_pins: uart_ao_b {
+			mux {
+				groups = "uart_tx_ao_b", "uart_rx_ao_b";
+				function = "uart_ao_b";
+			};
+		};
+
+		uart_ao_b_0_1_pins: uart_ao_b_0_1 {
+			mux {
+				groups = "uart_tx_ao_b_0", "uart_rx_ao_b_1";
+				function = "uart_ao_b";
+			};
+		};
+
+		uart_ao_b_cts_rts_pins: uart_ao_b_cts_rts {
+			mux {
+				groups = "uart_cts_ao_b",
+				       "uart_rts_ao_b";
+				function = "uart_ao_b";
+			};
+		};
+
+		remote_input_ao_pins: remote_input_ao {
+			mux {
+				groups = "remote_input_ao";
+				function = "remote_input_ao";
+			};
+		};
+
+		i2c_ao_pins: i2c_ao {
+			mux {
+				groups = "i2c_sck_ao",
+				       "i2c_sda_ao";
+				function = "i2c_ao";
+			};
+		};
+
+		pwm_ao_a_3_pins: pwm_ao_a_3 {
+			mux {
+				groups = "pwm_ao_a_3";
+				function = "pwm_ao_a";
+			};
+		};
+
+		pwm_ao_a_8_pins: pwm_ao_a_8 {
+			mux {
+				groups = "pwm_ao_a_8";
+				function = "pwm_ao_a";
+			};
+		};
+
+		pwm_ao_b_pins: pwm_ao_b {
+			mux {
+				groups = "pwm_ao_b";
+				function = "pwm_ao_b";
+			};
+		};
+
+		pwm_ao_b_6_pins: pwm_ao_b_6 {
+			mux {
+				groups = "pwm_ao_b_6";
+				function = "pwm_ao_b";
+			};
+		};
+
+		i2s_out_ch23_ao_pins: i2s_out_ch23_ao {
+			mux {
+				groups = "i2s_out_ch23_ao";
+				function = "i2s_out_ao";
+			};
+		};
+
+		i2s_out_ch45_ao_pins: i2s_out_ch45_ao {
+			mux {
+				groups = "i2s_out_ch45_ao";
+				function = "i2s_out_ao";
+			};
+		};
+
+		spdif_out_ao_6_pins: spdif_out_ao_6 {
+			mux {
+				groups = "spdif_out_ao_6";
+				function = "spdif_out_ao";
+			};
+		};
+
+		spdif_out_ao_9_pins: spdif_out_ao_9 {
+			mux {
+				groups = "spdif_out_ao_9";
+				function = "spdif_out_ao";
+			};
+		};
+
+		ao_cec_pins: ao_cec {
+			mux {
+				groups = "ao_cec";
+				function = "cec_ao";
+			};
+		};
+
+		ee_cec_pins: ee_cec {
+			mux {
+				groups = "ee_cec";
+				function = "cec_ao";
+			};
+		};
+	};
+};
+
+&hdmi_tx {
+	compatible = "amlogic,meson-gxl-dw-hdmi", "amlogic,meson-gx-dw-hdmi";
+	resets = <&reset RESET_HDMITX_CAPB3>,
+		 <&reset RESET_HDMI_SYSTEM_RESET>,
+		 <&reset RESET_HDMI_TX>;
+	reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy";
+	clocks = <&clkc CLKID_HDMI_PCLK>,
+		 <&clkc CLKID_CLK81>,
+		 <&clkc CLKID_GCLK_VENCI_INT0>;
+	clock-names = "isfr", "iahb", "venci";
+};
+
+&hiubus {
+	clkc: clock-controller@0 {
+		compatible = "amlogic,gxl-clkc", "amlogic,gxbb-clkc";
+		#clock-cells = <1>;
+		reg = <0x0 0x0 0x0 0x3db>;
+	};
+};
+
+&i2c_A {
+	clocks = <&clkc CLKID_I2C>;
+};
+
+&i2c_AO {
+	clocks = <&clkc CLKID_AO_I2C>;
+};
+
+&i2c_B {
+	clocks = <&clkc CLKID_I2C>;
+};
+
+&i2c_C {
+	clocks = <&clkc CLKID_I2C>;
+};
+
+&periphs {
+	pinctrl_periphs: pinctrl@4b0 {
+		compatible = "amlogic,meson-gxl-periphs-pinctrl";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gpio: bank@4b0 {
+			reg = <0x0 0x004b0 0x0 0x28>,
+			      <0x0 0x004e8 0x0 0x14>,
+			      <0x0 0x00520 0x0 0x14>,
+			      <0x0 0x00430 0x0 0x40>;
+			reg-names = "mux", "pull", "pull-enable", "gpio";
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_periphs 0 10 101>;
+		};
+
+		emmc_pins: emmc {
+			mux {
+				groups = "emmc_nand_d07",
+				       "emmc_cmd",
+				       "emmc_clk",
+				       "emmc_ds";
+				function = "emmc";
+			};
+		};
+
+		nor_pins: nor {
+			mux {
+				groups = "nor_d",
+				       "nor_q",
+				       "nor_c",
+				       "nor_cs";
+				function = "nor";
+			};
+		};
+
+		spi_pins: spi {
+			mux {
+				groups = "spi_miso",
+					"spi_mosi",
+					"spi_sclk";
+				function = "spi";
+			};
+		};
+
+		spi_ss0_pins: spi-ss0 {
+			mux {
+				groups = "spi_ss0";
+				function = "spi";
+			};
+		};
+
+		sdcard_pins: sdcard {
+			mux {
+				groups = "sdcard_d0",
+				       "sdcard_d1",
+				       "sdcard_d2",
+				       "sdcard_d3",
+				       "sdcard_cmd",
+				       "sdcard_clk";
+				function = "sdcard";
+			};
+		};
+
+		sdio_pins: sdio {
+			mux {
+				groups = "sdio_d0",
+				       "sdio_d1",
+				       "sdio_d2",
+				       "sdio_d3",
+				       "sdio_cmd",
+				       "sdio_clk";
+				function = "sdio";
+			};
+		};
+
+		sdio_irq_pins: sdio_irq {
+			mux {
+				groups = "sdio_irq";
+				function = "sdio";
+			};
+		};
+
+		uart_a_pins: uart_a {
+			mux {
+				groups = "uart_tx_a",
+				       "uart_rx_a";
+				function = "uart_a";
+			};
+		};
+
+		uart_a_cts_rts_pins: uart_a_cts_rts {
+			mux {
+				groups = "uart_cts_a",
+				       "uart_rts_a";
+				function = "uart_a";
+			};
+		};
+
+		uart_b_pins: uart_b {
+			mux {
+				groups = "uart_tx_b",
+				       "uart_rx_b";
+				function = "uart_b";
+			};
+		};
+
+		uart_b_cts_rts_pins: uart_b_cts_rts {
+			mux {
+				groups = "uart_cts_b",
+				       "uart_rts_b";
+				function = "uart_b";
+			};
+		};
+
+		uart_c_pins: uart_c {
+			mux {
+				groups = "uart_tx_c",
+				       "uart_rx_c";
+				function = "uart_c";
+			};
+		};
+
+		uart_c_cts_rts_pins: uart_c_cts_rts {
+			mux {
+				groups = "uart_cts_c",
+				       "uart_rts_c";
+				function = "uart_c";
+			};
+		};
+
+		i2c_a_pins: i2c_a {
+			mux {
+				groups = "i2c_sck_a",
+				     "i2c_sda_a";
+				function = "i2c_a";
+			};
+		};
+
+		i2c_b_pins: i2c_b {
+			mux {
+				groups = "i2c_sck_b",
+				      "i2c_sda_b";
+				function = "i2c_b";
+			};
+		};
+
+		i2c_c_pins: i2c_c {
+			mux {
+				groups = "i2c_sck_c",
+				      "i2c_sda_c";
+				function = "i2c_c";
+			};
+		};
+
+		eth_pins: eth_c {
+			mux {
+				groups = "eth_mdio",
+				       "eth_mdc",
+				       "eth_clk_rx_clk",
+				       "eth_rx_dv",
+				       "eth_rxd0",
+				       "eth_rxd1",
+				       "eth_rxd2",
+				       "eth_rxd3",
+				       "eth_rgmii_tx_clk",
+				       "eth_tx_en",
+				       "eth_txd0",
+				       "eth_txd1",
+				       "eth_txd2",
+				       "eth_txd3";
+				function = "eth";
+			};
+		};
+
+		eth_link_led_pins: eth_link_led {
+			mux {
+				groups = "eth_link_led";
+				function = "eth_led";
+			};
+		};
+
+		eth_act_led_pins: eth_act_led {
+			mux {
+				groups = "eth_act_led";
+				function = "eth_led";
+			};
+		};
+		
+		pwm_a_pins: pwm_a {
+			mux {
+				groups = "pwm_a";
+				function = "pwm_a";
+			};
+		};
+
+		pwm_b_pins: pwm_b {
+			mux {
+				groups = "pwm_b";
+				function = "pwm_b";
+			};
+		};
+
+		pwm_c_pins: pwm_c {
+			mux {
+				groups = "pwm_c";
+				function = "pwm_c";
+			};
+		};
+
+		pwm_d_pins: pwm_d {
+			mux {
+				groups = "pwm_d";
+				function = "pwm_d";
+			};
+		};
+
+		pwm_e_pins: pwm_e {
+			mux {
+				groups = "pwm_e";
+				function = "pwm_e";
+			};
+		};
+
+		pwm_f_clk_pins: pwm_f_clk {
+			mux {
+				groups = "pwm_f_clk";
+				function = "pwm_f";
+			};
+		};
+
+		pwm_f_x_pins: pwm_f_x {
+			mux {
+				groups = "pwm_f_x";
+				function = "pwm_f";
+			};
+		};
+
+		hdmi_hpd_pins: hdmi_hpd {
+			mux {
+				groups = "hdmi_hpd";
+				function = "hdmi_hpd";
+			};
+		};
+
+		hdmi_i2c_pins: hdmi_i2c {
+			mux {
+				groups = "hdmi_sda", "hdmi_scl";
+				function = "hdmi_i2c";
+			};
+		};
+
+		i2s_am_clk_pins: i2s_am_clk {
+			mux {
+				groups = "i2s_am_clk";
+				function = "i2s_out";
+			};
+		};
+
+		i2s_out_ao_clk_pins: i2s_out_ao_clk {
+			mux {
+				groups = "i2s_out_ao_clk";
+				function = "i2s_out";
+			};
+		};
+
+		i2s_out_lr_clk_pins: i2s_out_lr_clk {
+			mux {
+				groups = "i2s_out_lr_clk";
+				function = "i2s_out";
+			};
+		};
+
+		i2s_out_ch01_pins: i2s_out_ch01 {
+			mux {
+				groups = "i2s_out_ch01";
+				function = "i2s_out";
+			};
+		};
+		i2sout_ch23_z_pins: i2sout_ch23_z {
+			mux {
+				groups = "i2sout_ch23_z";
+				function = "i2s_out";
+			};
+		};
+
+		i2sout_ch45_z_pins: i2sout_ch45_z {
+			mux {
+				groups = "i2sout_ch45_z";
+				function = "i2s_out";
+			};
+		};
+
+		i2sout_ch67_z_pins: i2sout_ch67_z {
+			mux {
+				groups = "i2sout_ch67_z";
+				function = "i2s_out";
+			};
+		};
+
+		spdif_out_h_pins: spdif_out_ao_h {
+			mux {
+				groups = "spdif_out_h";
+				function = "spdif_out";
+			};
+		};
+	};
+
+	eth-phy-mux {
+		compatible = "mdio-mux-mmioreg", "mdio-mux";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x0 0x55c 0x0 0x4>;
+		mux-mask = <0xffffffff>;
+		mdio-parent-bus = <&mdio0>;
+
+		internal_mdio: mdio@e40908ff {
+			reg = <0xe40908ff>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			internal_phy: ethernet-phy@8 {
+				compatible = "ethernet-phy-id0181.4400", "ethernet-phy-ieee802.3-c22";
+				reg = <8>;
+				max-speed = <100>;
+			};
+		};
+
+		external_mdio: mdio@2009087f {
+			reg = <0x2009087f>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+};
+
+&saradc {
+	compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc";
+	clocks = <&xtal>,
+		 <&clkc CLKID_SAR_ADC>,
+		 <&clkc CLKID_SANA>,
+		 <&clkc CLKID_SAR_ADC_CLK>,
+		 <&clkc CLKID_SAR_ADC_SEL>;
+	clock-names = "clkin", "core", "sana", "adc_clk", "adc_sel";
+};
+
+&sd_emmc_a {
+	clocks = <&clkc CLKID_SD_EMMC_A>,
+		 <&xtal>,
+		 <&clkc CLKID_FCLK_DIV2>;
+	clock-names = "core", "clkin0", "clkin1";
+};
+
+&sd_emmc_b {
+	clocks = <&clkc CLKID_SD_EMMC_B>,
+		 <&xtal>,
+		 <&clkc CLKID_FCLK_DIV2>;
+       clock-names = "core", "clkin0", "clkin1";
+};
+
+&sd_emmc_c {
+	clocks = <&clkc CLKID_SD_EMMC_C>,
+		 <&xtal>,
+		 <&clkc CLKID_FCLK_DIV2>;
+	clock-names = "core", "clkin0", "clkin1";
+};
+
+&spicc {
+	clocks = <&clkc CLKID_SPICC>;
+	clock-names = "core";
+	resets = <&reset RESET_PERIPHS_SPICC>;
+	num-cs = <1>;
+};
+
+&spifc {
+	clocks = <&clkc CLKID_SPI>;
+};
+
+&vpu {
+	compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu";
+};
diff --git a/arch/arm/include/asm/arch-am33xx/hardware.h b/arch/arm/include/asm/arch-am33xx/hardware.h
index 3437e61..c2cc849 100644
--- a/arch/arm/include/asm/arch-am33xx/hardware.h
+++ b/arch/arm/include/asm/arch-am33xx/hardware.h
@@ -53,7 +53,19 @@
 #define DDR_CONTROL_BASE_ADDR		0x44E11404
 
 /* UART */
-#define DEFAULT_UART_BASE		UART0_BASE
+#if CONFIG_CONS_INDEX == 1
+#	define DEFAULT_UART_BASE UART0_BASE
+#elif CONFIG_CONS_INDEX == 2
+#	define DEFAULT_UART_BASE UART1_BASE
+#elif CONFIG_CONS_INDEX == 3
+#	define DEFAULT_UART_BASE UART2_BASE
+#elif CONFIG_CONS_INDEX == 4
+#	define DEFAULT_UART_BASE UART3_BASE
+#elif CONFIG_CONS_INDEX == 5
+#	define DEFAULT_UART_BASE UART4_BASE
+#elif CONFIG_CONS_INDEX == 6
+#	define DEFAULT_UART_BASE UART5_BASE
+#endif
 
 /* GPMC Base address */
 #define GPMC_BASE			0x50000000
diff --git a/arch/arm/include/asm/arch-am33xx/hardware_am33xx.h b/arch/arm/include/asm/arch-am33xx/hardware_am33xx.h
index fa9b84f..3e46283 100644
--- a/arch/arm/include/asm/arch-am33xx/hardware_am33xx.h
+++ b/arch/arm/include/asm/arch-am33xx/hardware_am33xx.h
@@ -15,6 +15,11 @@
 
 /* UART Base Address */
 #define UART0_BASE			0x44E09000
+#define UART1_BASE			0x48022000
+#define UART2_BASE			0x48024000
+#define UART3_BASE			0x481A6000
+#define UART4_BASE			0x481A8000
+#define UART5_BASE			0x481AA000
 
 /* GPIO Base address */
 #define GPIO2_BASE			0x481AC000
diff --git a/arch/arm/include/asm/arch-am33xx/sys_proto.h b/arch/arm/include/asm/arch-am33xx/sys_proto.h
index 4e78aaf..57fbfa4 100644
--- a/arch/arm/include/asm/arch-am33xx/sys_proto.h
+++ b/arch/arm/include/asm/arch-am33xx/sys_proto.h
@@ -40,6 +40,7 @@
 #endif
 void am33xx_spl_board_init(void);
 int am335x_get_efuse_mpu_max_freq(struct ctrl_dev *cdev);
+int am335x_get_mpu_vdd(int sil_rev, int frequency);
 int am335x_get_tps65910_mpu_vdd(int sil_rev, int frequency);
 #endif
 
diff --git a/arch/arm/include/asm/arch-meson/gxbb.h b/arch/arm/include/asm/arch-meson/gxbb.h
index ce41349..74d5290 100644
--- a/arch/arm/include/asm/arch-meson/gxbb.h
+++ b/arch/arm/include/asm/arch-meson/gxbb.h
@@ -22,11 +22,14 @@
 
 #define GXBB_ETH_REG_0		GXBB_PERIPHS_ADDR(0x50)
 #define GXBB_ETH_REG_1		GXBB_PERIPHS_ADDR(0x51)
+#define GXBB_ETH_REG_2		GXBB_PERIPHS_ADDR(0x56)
+#define GXBB_ETH_REG_3		GXBB_PERIPHS_ADDR(0x57)
 
 #define GXBB_ETH_REG_0_PHY_INTF		BIT(0)
 #define GXBB_ETH_REG_0_TX_PHASE(x)	(((x) & 3) << 5)
 #define GXBB_ETH_REG_0_TX_RATIO(x)	(((x) & 7) << 7)
 #define GXBB_ETH_REG_0_PHY_CLK_EN	BIT(10)
+#define GXBB_ETH_REG_0_INVERT_RMII_CLK	BIT(11)
 #define GXBB_ETH_REG_0_CLK_EN		BIT(12)
 
 /* HIU registers */
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h
index 5674d37..9f17829 100644
--- a/arch/arm/include/asm/config.h
+++ b/arch/arm/include/asm/config.h
@@ -10,10 +10,6 @@
 #define CONFIG_LMB
 #define CONFIG_SYS_BOOT_RAMDISK_HIGH
 
-#ifdef CONFIG_ARM64
-#define CONFIG_STATIC_RELA
-#endif
-
 #if defined(CONFIG_ARCH_LS1021A) || \
 	defined(CONFIG_CPU_PXA27X) || \
 	defined(CONFIG_CPU_MONAHANS) || \
diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S
index 9c46c93..ccefce0 100644
--- a/arch/arm/lib/crt0_64.S
+++ b/arch/arm/lib/crt0_64.S
@@ -98,6 +98,14 @@
 	ldr	x18, [x18, #GD_NEW_GD]		/* x18 <- gd->new_gd */
 
 	adr	lr, relocation_return
+#if CONFIG_POSITION_INDEPENDENT
+	/* Add in link-vs-runtime offset */
+	adr	x0, _start		/* x0 <- Runtime value of _start */
+	ldr	x9, _TEXT_BASE		/* x9 <- Linked value of _start */
+	sub	x9, x9, x0		/* x9 <- Run-vs-link offset */
+	add	lr, lr, x9
+#endif
+	/* Add in link-vs-relocation offset */
 	ldr	x9, [x18, #GD_RELOC_OFF]	/* x9 <- gd->reloc_off */
 	add	lr, lr, x9	/* new return address after relocation */
 	ldr	x0, [x18, #GD_RELOCADDR]	/* x0 <- gd->relocaddr */
@@ -112,6 +120,8 @@
 #endif /* !CONFIG_SPL_BUILD */
 #if defined(CONFIG_SPL_BUILD)
 	bl	spl_relocate_stack_gd           /* may return NULL */
+	/* set up gd here, outside any C code */
+	mov	x18, x0
 	/*
 	 * Perform 'sp = (x0 != NULL) ? x0 : sp' while working
 	 * around the constraint that conditional moves can not
diff --git a/arch/arm/lib/relocate_64.S b/arch/arm/lib/relocate_64.S
index fdba004..0480452 100644
--- a/arch/arm/lib/relocate_64.S
+++ b/arch/arm/lib/relocate_64.S
@@ -27,11 +27,24 @@
 	/*
 	 * Copy u-boot from flash to RAM
 	 */
-	ldr	x1, =__image_copy_start	/* x1 <- SRC &__image_copy_start */
-	subs	x9, x0, x1		/* x9 <- relocation offset */
+	adr	x1, __image_copy_start	/* x1 <- Run &__image_copy_start */
+	subs	x9, x0, x1		/* x8 <- Run to copy offset */
 	b.eq	relocate_done		/* skip relocation */
-	ldr	x2, =__image_copy_end	/* x2 <- SRC &__image_copy_end */
+	/*
+	 * Don't ldr x1, __image_copy_start here, since if the code is already
+	 * running at an address other than it was linked to, that instruction
+	 * will load the relocated value of __image_copy_start. To
+	 * correctly apply relocations, we need to know the linked value.
+	 *
+	 * Linked &__image_copy_start, which we know was at
+	 * CONFIG_SYS_TEXT_BASE, which is stored in _TEXT_BASE, as a non-
+	 * relocated value, since it isn't a symbol reference.
+	 */
+	ldr	x1, _TEXT_BASE		/* x1 <- Linked &__image_copy_start */
+	subs	x9, x0, x1		/* x9 <- Link to copy offset */
 
+	adr	x1, __image_copy_start	/* x1 <- Run &__image_copy_start */
+	adr	x2, __image_copy_end	/* x2 <- Run &__image_copy_end */
 copy_loop:
 	ldp	x10, x11, [x1], #16	/* copy from source address [x1] */
 	stp	x10, x11, [x0], #16	/* copy to   target address [x0] */
@@ -42,8 +55,8 @@
 	/*
 	 * Fix .rela.dyn relocations
 	 */
-	ldr	x2, =__rel_dyn_start	/* x2 <- SRC &__rel_dyn_start */
-	ldr	x3, =__rel_dyn_end	/* x3 <- SRC &__rel_dyn_end */
+	adr	x2, __rel_dyn_start	/* x2 <- Run &__rel_dyn_start */
+	adr	x3, __rel_dyn_end	/* x3 <- Run &__rel_dyn_end */
 fixloop:
 	ldp	x0, x1, [x2], #16	/* (x0,x1) <- (SRC location, fixup) */
 	ldr	x4, [x2], #8		/* x4 <- addend */
diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig
index af3be59..d4bd230 100644
--- a/arch/arm/mach-meson/Kconfig
+++ b/arch/arm/mach-meson/Kconfig
@@ -9,6 +9,15 @@
 	  The Amlogic Meson GXBaby (S905) is an ARM SoC with a
 	  quad-core Cortex-A53 CPU and a Mali-450 GPU.
 
+config MESON_GXL
+	bool "Support Meson GXL"
+	select ARM64
+	select DM
+	select DM_SERIAL
+	help
+	  The Amlogic Meson GXL (S905X and S905X) is an ARM SoC with a
+	  quad-core Cortex-A53 CPU and a Mali-450 GPU.
+
 if MESON_GXBB
 
 config TARGET_ODROID_C2
@@ -20,6 +29,17 @@
 
 endif
 
+if MESON_GXL
+
+config TARGET_P212
+	bool "P212"
+	help
+	  P212 is a reference dessign board based on Meson GXL S905X SoC
+	  with 2 GiB of RAM, Ethernet, HDMI, 2 USB, micro-SD slot,
+	  eMMC, IR receiver, CVBS+Audio jack and a SDIO WiFi module.
+
+endif
+
 config SYS_SOC
 	default "meson"
 
@@ -28,4 +48,6 @@
 
 source "board/amlogic/odroid-c2/Kconfig"
 
+source "board/amlogic/p212/Kconfig"
+
 endif
diff --git a/arch/arm/mach-mvebu/cpu.c b/arch/arm/mach-mvebu/cpu.c
index 74a63dd..7c64a68 100644
--- a/arch/arm/mach-mvebu/cpu.c
+++ b/arch/arm/mach-mvebu/cpu.c
@@ -554,6 +554,47 @@
 }
 #endif
 
+#ifdef CONFIG_USB_XHCI_MVEBU
+#define USB3_MAX_WINDOWS        4
+#define USB3_WIN_CTRL(w)        (0x0 + ((w) * 8))
+#define USB3_WIN_BASE(w)        (0x4 + ((w) * 8))
+
+static void xhci_mvebu_mbus_config(void __iomem *base,
+			const struct mbus_dram_target_info *dram)
+{
+	int i;
+
+	for (i = 0; i < USB3_MAX_WINDOWS; i++) {
+		writel(0, base + USB3_WIN_CTRL(i));
+		writel(0, base + USB3_WIN_BASE(i));
+	}
+
+	for (i = 0; i < dram->num_cs; i++) {
+		const struct mbus_dram_window *cs = dram->cs + i;
+
+		/* Write size, attributes and target id to control register */
+		writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
+			(dram->mbus_dram_target_id << 4) | 1,
+			base + USB3_WIN_CTRL(i));
+
+		/* Write base address to base register */
+		writel((cs->base & 0xffff0000), base + USB3_WIN_BASE(i));
+	}
+}
+
+int board_xhci_enable(fdt_addr_t base)
+{
+	const struct mbus_dram_target_info *dram;
+
+	printf("MVEBU XHCI INIT controller @ 0x%lx\n", base);
+
+	dram = mvebu_mbus_dram_info();
+	xhci_mvebu_mbus_config((void __iomem *)base, dram);
+
+	return 0;
+}
+#endif
+
 void enable_caches(void)
 {
 	/* Avoid problem with e.g. neta ethernet driver */
diff --git a/arch/arm/mach-omap2/am33xx/sys_info.c b/arch/arm/mach-omap2/am33xx/sys_info.c
index ea434aa..0181a8c 100644
--- a/arch/arm/mach-omap2/am33xx/sys_info.c
+++ b/arch/arm/mach-omap2/am33xx/sys_info.c
@@ -175,6 +175,22 @@
 	return MPUPLL_M_720;
 }
 
+int am335x_get_mpu_vdd(int sil_rev, int frequency)
+{
+	int sel_mask = am335x_get_tps65910_mpu_vdd(sil_rev, frequency);
+
+	switch (sel_mask) {
+	case TPS65910_OP_REG_SEL_1_3_2_5:
+		return 1325000;
+	case TPS65910_OP_REG_SEL_1_2_0:
+		return 1200000;
+	case TPS65910_OP_REG_SEL_1_1_0:
+		return 1100000;
+	default:
+		return 1262500;
+	}
+}
+
 int am335x_get_tps65910_mpu_vdd(int sil_rev, int frequency)
 {
 	/* For PG2.0 and later, we have one set of values. */
diff --git a/arch/nios2/dts/10m50_devboard.dts b/arch/nios2/dts/10m50_devboard.dts
index 05eac30..461ae68 100644
--- a/arch/nios2/dts/10m50_devboard.dts
+++ b/arch/nios2/dts/10m50_devboard.dts
@@ -19,6 +19,7 @@
 		#size-cells = <0>;
 
 		cpu: cpu@0 {
+			u-boot,dm-pre-reloc;
 			device_type = "cpu";
 			compatible = "altr,nios2-1.1";
 			reg = <0x00000000>;
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 98c56ad..5c23b2c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -152,6 +152,7 @@
 config X86_RESET_VECTOR
 	bool
 	default n
+	select BINMAN
 
 # The following options control where the 16-bit and 32-bit init lies
 # If SPL is enabled then it normally holds this init code, and U-Boot proper
diff --git a/board/Marvell/mvebu_armada-37xx/board.c b/board/Marvell/mvebu_armada-37xx/board.c
index 8dc1f46..ac3e3a3 100644
--- a/board/Marvell/mvebu_armada-37xx/board.c
+++ b/board/Marvell/mvebu_armada-37xx/board.c
@@ -123,7 +123,7 @@
 }
 
 /* Board specific xHCI enable code */
-int board_xhci_enable(void)
+int board_xhci_enable(fdt_addr_t base)
 {
 	struct udevice *dev;
 	int ret;
diff --git a/board/Marvell/mvebu_armada-8k/board.c b/board/Marvell/mvebu_armada-8k/board.c
index 7d1b5d9..f4eabfb 100644
--- a/board/Marvell/mvebu_armada-8k/board.c
+++ b/board/Marvell/mvebu_armada-8k/board.c
@@ -95,7 +95,7 @@
 	return 0;
 }
 
-int board_xhci_enable(void)
+int board_xhci_enable(fdt_addr_t base)
 {
 	struct udevice *dev;
 	int ret;
diff --git a/board/amlogic/p212/Kconfig b/board/amlogic/p212/Kconfig
new file mode 100644
index 0000000..720c92b
--- /dev/null
+++ b/board/amlogic/p212/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_P212
+
+config SYS_BOARD
+	default "p212"
+
+config SYS_VENDOR
+	default "amlogic"
+
+config SYS_CONFIG_NAME
+	default "p212"
+
+endif
diff --git a/board/amlogic/p212/MAINTAINERS b/board/amlogic/p212/MAINTAINERS
new file mode 100644
index 0000000..6575f17
--- /dev/null
+++ b/board/amlogic/p212/MAINTAINERS
@@ -0,0 +1,6 @@
+P212
+M:	Neil Armstrong <narmstrong@baylibre.com>
+S:	Maintained
+F:	board/amlogic/p212/
+F:	include/configs/p212.h
+F:	configs/p212_defconfig
diff --git a/board/amlogic/p212/Makefile b/board/amlogic/p212/Makefile
new file mode 100644
index 0000000..960a661
--- /dev/null
+++ b/board/amlogic/p212/Makefile
@@ -0,0 +1,8 @@
+#
+# (C) Copyright 2016 BayLibre, SAS
+# Author: Neil Armstrong <narmstrong@baylibre.com>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	:= p212.o
diff --git a/board/amlogic/p212/README b/board/amlogic/p212/README
new file mode 100644
index 0000000..979502d
--- /dev/null
+++ b/board/amlogic/p212/README
@@ -0,0 +1,96 @@
+U-Boot for Amlogic P212
+=======================
+
+P212 is a reference board manufactured by Amlogic with the following
+specifications:
+
+ - Amlogic S905X ARM Cortex-A53 quad-core SoC @ 1.5GHz
+ - ARM Mali 450 GPU
+ - 2GB DDR3 SDRAM
+ - 10/100 Ethernet
+ - HDMI 2.0 4K/60Hz display
+ - 2 x USB 2.0 Host
+ - eMMC, microSD
+ - Infrared receiver
+ - SDIO WiFi Module
+ - CVBS+Stereo Audio Jack
+
+Schematics are available from Amlogic on demand.
+
+Currently the u-boot port supports the following devices:
+ - serial
+ - eMMC, microSD
+
+u-boot compilation
+==================
+
+ > export ARCH=arm
+ > export CROSS_COMPILE=aarch64-none-elf-
+ > make p212_defconfig
+ > make
+
+Image creation
+==============
+
+Amlogic doesn't provide sources for the firmware and for tools needed
+to create the bootloader image, so it is necessary to obtain them from
+the git tree published by the board vendor:
+
+ > wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ > wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+ > tar xvfJ gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ > tar xvfJ gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+ > export PATH=$PWD/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin:$PWD/gcc-linaro-arm-none-eabi-4.8-2013.11_linux/bin:$PATH
+ > git clone https://github.com/BayLibre/u-boot.git -b n-amlogic-openlinux-20170606 amlogic-u-boot
+ > cd amlogic-u-boot
+ > make gxl_p212_v1_defconfig
+ > make
+ > export FIPDIR=$PWD/fip
+
+Go back to mainline U-boot source tree then :
+ > mkdir fip
+
+ > cp $FIPDIR/gxl/bl2.bin fip/
+ > cp $FIPDIR/gxl/acs.bin fip/
+ > cp $FIPDIR/gxl/bl21.bin fip/
+ > cp $FIPDIR/gxl/bl30.bin fip/
+ > cp $FIPDIR/gxl/bl301.bin fip/
+ > cp $FIPDIR/gxl/bl31.img fip/
+ > cp u-boot.bin fip/bl33.bin
+
+ > $FIPDIR/blx_fix.sh \
+	fip/bl30.bin \
+	fip/zero_tmp \
+	fip/bl30_zero.bin \
+	fip/bl301.bin \
+	fip/bl301_zero.bin \
+	fip/bl30_new.bin \
+	bl30
+
+ > $FIPDIR/acs_tool.pyc fip/bl2.bin fip/bl2_acs.bin fip/acs.bin 0
+
+ > $FIPDIR/blx_fix.sh \
+	fip/bl2_acs.bin \
+	fip/zero_tmp \
+	fip/bl2_zero.bin \
+	fip/bl21.bin \
+	fip/bl21_zero.bin \
+	fip/bl2_new.bin \
+	bl2
+
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl30_new.bin
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl31.img
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl33.bin
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl2sig --input fip/bl2_new.bin --output fip/bl2.n.bin.sig
+ > $FIPDIR/gxl/aml_encrypt_gxl --bootmk \
+		--output fip/u-boot.bin \
+		--bl2 fip/bl2.n.bin.sig \
+		--bl30 fip/bl30_new.bin.enc \
+		--bl31 fip/bl31.img.enc \
+		--bl33 fip/bl33.bin.enc
+
+and then write the image to SD with:
+
+ > DEV=/dev/your_sd_device
+ > dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=512 skip=1 seek=1
+ > dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=1 count=444
diff --git a/board/amlogic/p212/p212.c b/board/amlogic/p212/p212.c
new file mode 100644
index 0000000..ece8096
--- /dev/null
+++ b/board/amlogic/p212/p212.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <asm/arch/gxbb.h>
+#include <asm/arch/sm.h>
+#include <phy.h>
+
+#define EFUSE_SN_OFFSET		20
+#define EFUSE_SN_SIZE		16
+#define EFUSE_MAC_OFFSET	52
+#define EFUSE_MAC_SIZE		6
+
+int board_init(void)
+{
+	return 0;
+}
+
+int misc_init_r(void)
+{
+	u8 mac_addr[EFUSE_MAC_SIZE];
+	char serial[EFUSE_SN_SIZE];
+	ssize_t len;
+
+	/* Set RMII mode */
+	out_le32(GXBB_ETH_REG_0, GXBB_ETH_REG_0_INVERT_RMII_CLK |
+				 GXBB_ETH_REG_0_CLK_EN);
+
+	/* Use Internal PHY */
+	out_le32(GXBB_ETH_REG_2, 0x10110181);
+	out_le32(GXBB_ETH_REG_3, 0xe40908ff);
+
+	/* Enable power and clock gate */
+	setbits_le32(GXBB_GCLK_MPEG_1, GXBB_GCLK_MPEG_1_ETH);
+	clrbits_le32(GXBB_MEM_PD_REG_0, GXBB_MEM_PD_REG_0_ETH_MASK);
+
+	if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
+		len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
+					  mac_addr, EFUSE_MAC_SIZE);
+		if (len == EFUSE_MAC_SIZE && is_valid_ethaddr(mac_addr))
+			eth_env_set_enetaddr("ethaddr", mac_addr);
+	}
+
+	if (!env_get("serial#")) {
+		len = meson_sm_read_efuse(EFUSE_SN_OFFSET, serial,
+			EFUSE_SN_SIZE);
+		if (len == EFUSE_SN_SIZE)
+			env_set("serial#", serial);
+	}
+
+	return 0;
+}
diff --git a/board/armltd/vexpress/vexpress_common.c b/board/armltd/vexpress/vexpress_common.c
index 89ab8f7..37b8d7f 100644
--- a/board/armltd/vexpress/vexpress_common.c
+++ b/board/armltd/vexpress/vexpress_common.c
@@ -76,6 +76,7 @@
 	(void) bis;
 #ifdef CONFIG_ARM_PL180_MMCI
 	struct pl180_mmc_host *host;
+	struct mmc *mmc;
 
 	host = malloc(sizeof(struct pl180_mmc_host));
 	if (!host)
@@ -91,7 +92,7 @@
 	host->clock_in = ARM_MCLK;
 	host->clock_min = ARM_MCLK / (2 * (SDI_CLKCR_CLKDIV_INIT_V1 + 1));
 	host->clock_max = CONFIG_ARM_PL180_MMCI_CLOCK_FREQ;
-	rc = arm_pl180_mmci_init(host);
+	rc = arm_pl180_mmci_init(host, &mmc);
 #endif
 	return rc;
 }
diff --git a/board/freescale/ls1088a/MAINTAINERS b/board/freescale/ls1088a/MAINTAINERS
index e1e6d4b..b3d5c38 100644
--- a/board/freescale/ls1088a/MAINTAINERS
+++ b/board/freescale/ls1088a/MAINTAINERS
@@ -5,6 +5,7 @@
 F:	board/freescale/ls1088a/
 F:	include/configs/ls1088ardb.h
 F:	configs/ls1088ardb_qspi_defconfig
+F:	configs/ls1088ardb_sdcard_qspi_defconfig
 
 LS1088AQDS BOARD
 M:	Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
@@ -13,3 +14,4 @@
 F:	board/freescale/ls1088a/
 F:	include/configs/ls1088aqds.h
 F:	configs/ls1088aqds_qspi_defconfig
+F:	configs/ls1088aqds_sdcard_qspi_defconfig
diff --git a/board/freescale/ls1088a/ddr.c b/board/freescale/ls1088a/ddr.c
index 0ecfd65..e24bfd5 100644
--- a/board/freescale/ls1088a/ddr.c
+++ b/board/freescale/ls1088a/ddr.c
@@ -96,7 +96,10 @@
 {
 	puts("Initializing DDR....using SPD\n");
 
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+	gd->ram_size = fsl_ddr_sdram_size();
+#else
 	gd->ram_size = fsl_ddr_sdram();
-
+#endif
 	return 0;
 }
diff --git a/board/logicpd/omap3som/omap3logic.c b/board/logicpd/omap3som/omap3logic.c
index 40783c8..1da9e38 100644
--- a/board/logicpd/omap3som/omap3logic.c
+++ b/board/logicpd/omap3som/omap3logic.c
@@ -294,336 +294,4 @@
 }
 #endif
 
-/*
- * IEN  - Input Enable
- * IDIS - Input Disable
- * PTD  - Pull type Down
- * PTU  - Pull type Up
- * DIS  - Pull type selection is inactive
- * EN   - Pull type selection is active
- * M0   - Mode 0
- * The commented string gives the final mux configuration for that pin
- */
-
-/*
- * Routine: set_muxconf_regs
- * Description: Setting up the configuration Mux registers specific to the
- *		hardware. Many pins need to be moved from protect to primary
- *		mode.
- */
-void set_muxconf_regs(void)
-{
-	MUX_VAL(CP(SDRC_D0), (IEN  | PTD | DIS | M0)); /*SDRC_D0*/
-	MUX_VAL(CP(SDRC_D1), (IEN  | PTD | DIS | M0)); /*SDRC_D1*/
-	MUX_VAL(CP(SDRC_D2), (IEN  | PTD | DIS | M0)); /*SDRC_D2*/
-	MUX_VAL(CP(SDRC_D3), (IEN  | PTD | DIS | M0)); /*SDRC_D3*/
-	MUX_VAL(CP(SDRC_D4), (IEN  | PTD | DIS | M0)); /*SDRC_D4*/
-	MUX_VAL(CP(SDRC_D5), (IEN  | PTD | DIS | M0)); /*SDRC_D5*/
-	MUX_VAL(CP(SDRC_D6), (IEN  | PTD | DIS | M0)); /*SDRC_D6*/
-	MUX_VAL(CP(SDRC_D7), (IEN  | PTD | DIS | M0)); /*SDRC_D7*/
-	MUX_VAL(CP(SDRC_D8), (IEN  | PTD | DIS | M0)); /*SDRC_D8*/
-	MUX_VAL(CP(SDRC_D9), (IEN  | PTD | DIS | M0)); /*SDRC_D9*/
-	MUX_VAL(CP(SDRC_D10), (IEN  | PTD | DIS | M0)); /*SDRC_D10*/
-	MUX_VAL(CP(SDRC_D11), (IEN  | PTD | DIS | M0)); /*SDRC_D11*/
-	MUX_VAL(CP(SDRC_D12), (IEN  | PTD | DIS | M0)); /*SDRC_D12*/
-	MUX_VAL(CP(SDRC_D13), (IEN  | PTD | DIS | M0)); /*SDRC_D13*/
-	MUX_VAL(CP(SDRC_D14), (IEN  | PTD | DIS | M0)); /*SDRC_D14*/
-	MUX_VAL(CP(SDRC_D15), (IEN  | PTD | DIS | M0)); /*SDRC_D15*/
-	MUX_VAL(CP(SDRC_D16), (IEN  | PTD | DIS | M0)); /*SDRC_D16*/
-	MUX_VAL(CP(SDRC_D17), (IEN  | PTD | DIS | M0)); /*SDRC_D17*/
-	MUX_VAL(CP(SDRC_D18), (IEN  | PTD | DIS | M0)); /*SDRC_D18*/
-	MUX_VAL(CP(SDRC_D19), (IEN  | PTD | DIS | M0)); /*SDRC_D19*/
-	MUX_VAL(CP(SDRC_D20), (IEN  | PTD | DIS | M0)); /*SDRC_D20*/
-	MUX_VAL(CP(SDRC_D21), (IEN  | PTD | DIS | M0)); /*SDRC_D21*/
-	MUX_VAL(CP(SDRC_D22), (IEN  | PTD | DIS | M0)); /*SDRC_D22*/
-	MUX_VAL(CP(SDRC_D23), (IEN  | PTD | DIS | M0)); /*SDRC_D23*/
-	MUX_VAL(CP(SDRC_D24), (IEN  | PTD | DIS | M0)); /*SDRC_D24*/
-	MUX_VAL(CP(SDRC_D25), (IEN  | PTD | DIS | M0)); /*SDRC_D25*/
-	MUX_VAL(CP(SDRC_D26), (IEN  | PTD | DIS | M0)); /*SDRC_D26*/
-	MUX_VAL(CP(SDRC_D27), (IEN  | PTD | DIS | M0)); /*SDRC_D27*/
-	MUX_VAL(CP(SDRC_D28), (IEN  | PTD | DIS | M0)); /*SDRC_D28*/
-	MUX_VAL(CP(SDRC_D29), (IEN  | PTD | DIS | M0)); /*SDRC_D29*/
-	MUX_VAL(CP(SDRC_D30), (IEN  | PTD | DIS | M0)); /*SDRC_D30*/
-	MUX_VAL(CP(SDRC_D31), (IEN  | PTD | DIS | M0)); /*SDRC_D31*/
-	MUX_VAL(CP(SDRC_CLK), (IEN  | PTD | DIS | M0)); /*SDRC_CLK*/
-	MUX_VAL(CP(SDRC_DQS0), (IEN  | PTD | DIS | M0)); /*SDRC_DQS0*/
-	MUX_VAL(CP(SDRC_DQS1), (IEN  | PTD | DIS | M0)); /*SDRC_DQS1*/
-	MUX_VAL(CP(SDRC_DQS2), (IEN  | PTD | DIS | M0)); /*SDRC_DQS2*/
-	MUX_VAL(CP(SDRC_DQS3), (IEN  | PTD | DIS | M0)); /*SDRC_DQS3*/
-	MUX_VAL(CP(SDRC_CKE0), (IDIS | PTU | EN  | M0)); /*SDRC_CKE0*/
-	MUX_VAL(CP(SDRC_CKE1), (IDIS | PTU | DIS | M0)); /*SDRC_CKE1*/
-
-	MUX_VAL(CP(GPMC_A1), (IDIS | PTU | EN  | M0)); /*GPMC_A1*/
-	MUX_VAL(CP(GPMC_A2), (IDIS | PTU | EN  | M0)); /*GPMC_A2*/
-	MUX_VAL(CP(GPMC_A3), (IDIS | PTU | EN  | M0)); /*GPMC_A3*/
-	MUX_VAL(CP(GPMC_A4), (IDIS | PTU | EN  | M0)); /*GPMC_A4*/
-	MUX_VAL(CP(GPMC_A5), (IDIS | PTU | EN  | M0)); /*GPMC_A5*/
-	MUX_VAL(CP(GPMC_A6), (IDIS | PTU | EN  | M0)); /*GPMC_A6*/
-	MUX_VAL(CP(GPMC_A7), (IDIS | PTU | EN  | M0)); /*GPMC_A7*/
-	MUX_VAL(CP(GPMC_A8), (IDIS | PTU | EN  | M0)); /*GPMC_A8*/
-	MUX_VAL(CP(GPMC_A9), (IDIS | PTU | EN  | M0)); /*GPMC_A9*/
-	MUX_VAL(CP(GPMC_A10), (IDIS | PTU | EN  | M0)); /*GPMC_A10*/
-	MUX_VAL(CP(GPMC_D0), (IEN  | PTU | EN  | M0)); /*GPMC_D0*/
-	MUX_VAL(CP(GPMC_D1), (IEN  | PTU | EN  | M0)); /*GPMC_D1*/
-	MUX_VAL(CP(GPMC_D2), (IEN  | PTU | EN  | M0)); /*GPMC_D2*/
-	MUX_VAL(CP(GPMC_D3), (IEN  | PTU | EN  | M0)); /*GPMC_D3*/
-	MUX_VAL(CP(GPMC_D4),  (IEN  | PTU | EN  | M0)); /*GPMC_D4*/
-	MUX_VAL(CP(GPMC_D5),  (IEN  | PTU | EN  | M0)); /*GPMC_D5*/
-	MUX_VAL(CP(GPMC_D6),  (IEN  | PTU | EN  | M0)); /*GPMC_D6*/
-	MUX_VAL(CP(GPMC_D7),   (IEN  | PTU | EN  | M0)); /*GPMC_D7*/
-	MUX_VAL(CP(GPMC_D8),  (IEN  | PTU | EN  | M0)); /*GPMC_D8*/
-	MUX_VAL(CP(GPMC_D9),  (IEN  | PTU | EN  | M0)); /*GPMC_D9*/
-	MUX_VAL(CP(GPMC_D10), (IEN  | PTU | EN  | M0)); /*GPMC_D10*/
-	MUX_VAL(CP(GPMC_D11), (IEN  | PTU | EN  | M0)); /*GPMC_D11*/
-	MUX_VAL(CP(GPMC_D12), (IEN  | PTU | EN  | M0)); /*GPMC_D12*/
-	MUX_VAL(CP(GPMC_D13), (IEN  | PTU | EN  | M0)); /*GPMC_D13*/
-	MUX_VAL(CP(GPMC_D14), (IEN  | PTU | EN  | M0)); /*GPMC_D14*/
-	MUX_VAL(CP(GPMC_D15), (IEN  | PTU | EN  | M0)); /*GPMC_D15*/
-	MUX_VAL(CP(GPMC_NCS0), (IDIS | PTU | EN  | M0)); /*GPMC_nCS0*/
-	MUX_VAL(CP(GPMC_NCS1), (IDIS | PTU | EN  | M0)); /*GPMC_nCS1*/
-	MUX_VAL(CP(GPMC_NCS2), (IDIS | PTU | EN  | M0)); /*GPMC_nCS2*/
-	MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | EN  | M0)); /*GPMC_nCS3*/
-	MUX_VAL(CP(GPMC_NCS4), (IEN  | PTU | EN  | M0)); /*GPMC_nCS4*/
-	MUX_VAL(CP(GPMC_NCS5), (IDIS | PTU | EN  | M0)); /*GPMC_nCS5*/
-	MUX_VAL(CP(GPMC_NCS6), (IEN  | PTU | EN | M0)); /*GPMC_nCS6*/
-	MUX_VAL(CP(GPMC_NCS7), (IEN  | PTU | EN  | M0)); /*GPMC_nCS7*/
-	MUX_VAL(CP(GPMC_CLK),  (IDIS | PTU | EN  | M0)); /*GPMC_CLK*/
-	MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0)); /*GPMC_nADV_ALE*/
-	MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0)); /*GPMC_nOE*/
-	MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0)); /*GPMC_nWE*/
-	MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTU | EN  | M0)); /*GPMC_nBE0_CLE*/
-	MUX_VAL(CP(GPMC_NBE1), (IEN  | PTU | EN  | M0)); /*GPMC_nBE1*/
-	MUX_VAL(CP(GPMC_NWP),  (IEN  | PTD | DIS | M0)); /*GPMC_nWP*/
-	MUX_VAL(CP(GPMC_WAIT0), (IEN  | PTU | EN  | M0)); /*GPMC_WAIT0*/
-	MUX_VAL(CP(GPMC_WAIT1), (IEN  | PTU | EN  | M0)); /*GPMC_WAIT1*/
-	MUX_VAL(CP(GPMC_WAIT2), (IEN  | PTU | EN  | M4)); /*GPIO_64*/
-	MUX_VAL(CP(GPMC_WAIT3), (IEN  | PTU | EN  | M0)); /*GPMC_WAIT3*/
-
-	MUX_VAL(CP(CAM_HS), (IEN  | PTU | EN  | M0)); /*CAM_HS */
-	MUX_VAL(CP(CAM_VS), (IEN  | PTU | EN  | M0)); /*CAM_VS */
-	MUX_VAL(CP(CAM_XCLKA), (IDIS | PTD | DIS | M0)); /*CAM_XCLKA*/
-	MUX_VAL(CP(CAM_PCLK), (IEN  | PTU | EN  | M0)); /*CAM_PCLK*/
-	MUX_VAL(CP(CAM_FLD), (IDIS | PTD | DIS | M4)); /*GPIO_98*/
-	MUX_VAL(CP(CAM_D0), (IEN  | PTD | DIS | M0)); /*CAM_D0*/
-	MUX_VAL(CP(CAM_D1), (IEN  | PTD | DIS | M0)); /*CAM_D1*/
-	MUX_VAL(CP(CAM_D2), (IEN  | PTD | DIS | M0)); /*CAM_D2*/
-	MUX_VAL(CP(CAM_D3), (IEN  | PTD | DIS | M0)); /*CAM_D3*/
-	MUX_VAL(CP(CAM_D4), (IEN  | PTD | DIS | M0)); /*CAM_D4*/
-	MUX_VAL(CP(CAM_D5), (IEN  | PTD | DIS | M0)); /*CAM_D5*/
-	MUX_VAL(CP(CAM_D6), (IEN  | PTD | DIS | M0)); /*CAM_D6*/
-	MUX_VAL(CP(CAM_D7), (IEN  | PTD | DIS | M0)); /*CAM_D7*/
-	MUX_VAL(CP(CAM_D8), (IEN  | PTD | DIS | M0)); /*CAM_D8*/
-	MUX_VAL(CP(CAM_D9), (IEN  | PTD | DIS | M0)); /*CAM_D9*/
-	MUX_VAL(CP(CAM_D10), (IEN  | PTD | DIS | M0)); /*CAM_D10*/
-	MUX_VAL(CP(CAM_D11), (IEN  | PTD | DIS | M0)); /*CAM_D11*/
-	MUX_VAL(CP(CAM_XCLKB), (IDIS | PTD | DIS | M0)); /*CAM_XCLKB*/
-	MUX_VAL(CP(CAM_WEN), (IEN  | PTD | DIS | M4)); /*GPIO_167*/
-	MUX_VAL(CP(CAM_STROBE), (IDIS | PTD | DIS | M0)); /*CAM_STROBE*/
-
-	MUX_VAL(CP(CSI2_DX0), (IEN  | PTD | DIS | M0)); /*CSI2_DX0*/
-	MUX_VAL(CP(CSI2_DY0), (IEN  | PTD | DIS | M0)); /*CSI2_DY0*/
-	MUX_VAL(CP(CSI2_DX1), (IEN  | PTD | DIS | M0)); /*CSI2_DX1*/
-	MUX_VAL(CP(CSI2_DY1), (IEN  | PTD | DIS | M0)); /*CSI2_DY1*/
-
-	MUX_VAL(CP(MCBSP2_FSX), (IEN  | PTD | DIS | M0)); /*McBSP2_FSX*/
-	MUX_VAL(CP(MCBSP2_CLKX), (IEN  | PTD | DIS | M0)); /*McBSP2_CLKX*/
-	MUX_VAL(CP(MCBSP2_DR), (IEN  | PTD | DIS | M0)); /*McBSP2_DR*/
-	MUX_VAL(CP(MCBSP2_DX), (IDIS | PTD | DIS | M0)); /*McBSP2_DX*/
-
-	MUX_VAL(CP(MMC1_CLK), (IDIS | PTU | EN  | M0)); /*MMC1_CLK*/
-	MUX_VAL(CP(MMC1_CMD), (IEN  | PTU | EN  | M0)); /*MMC1_CMD*/
-	MUX_VAL(CP(MMC1_DAT0), (IEN  | PTU | EN  | M0)); /*MMC1_DAT0*/
-	MUX_VAL(CP(MMC1_DAT1), (IEN  | PTU | EN  | M0)); /*MMC1_DAT1*/
-	MUX_VAL(CP(MMC1_DAT2), (IEN  | PTU | EN  | M0)); /*MMC1_DAT2*/
-	MUX_VAL(CP(MMC1_DAT3), (IEN  | PTU | EN  | M0)); /*MMC1_DAT3*/
-	MUX_VAL(CP(MMC1_DAT4), (IEN  | PTU | EN  | M0)); /*MMC1_DAT4*/
-	MUX_VAL(CP(MMC1_DAT5), (IEN  | PTU | EN  | M0)); /*MMC1_DAT5*/
-	MUX_VAL(CP(MMC1_DAT6), (IEN  | PTU | EN  | M0)); /*MMC1_DAT6*/
-	MUX_VAL(CP(MMC1_DAT7), (IEN  | PTU | EN  | M0)); /*MMC1_DAT7*/
-
-	MUX_VAL(CP(MMC2_CLK),  (IEN  | PTD | DIS | M0)); /*MMC2_CLK*/
-	MUX_VAL(CP(MMC2_CMD),  (IEN  | PTU | EN  | M0)); /*MMC2_CMD*/
-	MUX_VAL(CP(MMC2_DAT0), (IEN  | PTU | EN  | M0)); /*MMC2_DAT0*/
-	MUX_VAL(CP(MMC2_DAT1), (IEN  | PTU | EN  | M0)); /*MMC2_DAT1*/
-	MUX_VAL(CP(MMC2_DAT2), (IEN  | PTU | EN  | M0)); /*MMC2_DAT2*/
-	MUX_VAL(CP(MMC2_DAT3), (IEN  | PTU | EN  | M0)); /*MMC2_DAT3*/
-	MUX_VAL(CP(MMC2_DAT4), (IDIS | PTD | DIS | M0)); /*MMC2_DAT4*/
-	MUX_VAL(CP(MMC2_DAT5), (IDIS | PTD | DIS | M0)); /*MMC2_DAT5*/
-	MUX_VAL(CP(MMC2_DAT6), (IDIS | PTD | DIS | M0)); /*MMC2_DAT6 */
-	MUX_VAL(CP(MMC2_DAT7), (IEN  | PTU | EN  | M0)); /*MMC2_DAT7*/
-
-	MUX_VAL(CP(MCBSP3_DX), (IDIS | PTD | DIS | M0)); /*McBSP3_DX*/
-	MUX_VAL(CP(MCBSP3_DR), (IEN  | PTD | DIS | M0)); /*McBSP3_DR*/
-	MUX_VAL(CP(MCBSP3_CLKX), (IEN  | PTD | DIS | M0)); /*McBSP3_CLKX*/
-	MUX_VAL(CP(MCBSP3_FSX), (IEN  | PTD | DIS | M0)); /*McBSP3_FSX*/
-
-	MUX_VAL(CP(UART2_CTS), (IEN  | PTU | EN  | M0)); /*UART2_CTS*/
-	MUX_VAL(CP(UART2_RTS), (IDIS | PTD | DIS | M0)); /*UART2_RTS*/
-	MUX_VAL(CP(UART2_TX), (IDIS | PTD | DIS | M0)); /*UART2_TX*/
-	MUX_VAL(CP(UART2_RX), (IEN  | PTD | DIS | M0)); /*UART2_RX*/
-
-	MUX_VAL(CP(UART1_TX), (IDIS | PTD | DIS | M0)); /*UART1_TX*/
-	MUX_VAL(CP(UART1_RTS), (IDIS | PTD | DIS | M0)); /*UART1_RTS*/
-	MUX_VAL(CP(UART1_CTS), (IEN  | PTU | DIS | M0)); /*UART1_CTS*/
-	MUX_VAL(CP(UART1_RX), (IEN  | PTD | DIS | M0)); /*UART1_RX*/
-
-	MUX_VAL(CP(MCBSP4_CLKX), (IDIS | PTD | DIS | M4)); /*GPIO_152*/
-	MUX_VAL(CP(MCBSP4_DR), (IDIS | PTD | DIS | M4)); /*GPIO_153*/
-
-	MUX_VAL(CP(MCBSP1_CLKR), (IEN  | PTD | DIS | M0)); /*MCBSP1_CLKR*/
-	MUX_VAL(CP(MCBSP1_FSR), (IDIS | PTU | EN  | M0)); /*MCBSP1_FSR*/
-	MUX_VAL(CP(MCBSP1_DX), (IDIS | PTD | DIS | M0)); /*MCBSP1_DX*/
-	MUX_VAL(CP(MCBSP1_DR), (IEN  | PTD | DIS | M0)); /*MCBSP1_DR*/
-	MUX_VAL(CP(MCBSP_CLKS), (IEN  | PTU | DIS | M0)); /*MCBSP_CLKS*/
-	MUX_VAL(CP(MCBSP1_FSX), (IEN  | PTD | DIS | M0)); /*MCBSP1_FSX*/
-	MUX_VAL(CP(MCBSP1_CLKX), (IEN  | PTD | DIS | M0)); /*MCBSP1_CLKX*/
-
-	MUX_VAL(CP(UART3_CTS_RCTX), (IEN  | PTD | EN  | M0)); /*UART3_CTS_*/
-	MUX_VAL(CP(UART3_RTS_SD),  (IDIS | PTD | DIS | M0)); /*UART3_RTS_SD */
-	MUX_VAL(CP(UART3_RX_IRRX), (IEN  | PTD | DIS | M0)); /*UART3_RX_IRRX*/
-	MUX_VAL(CP(UART3_TX_IRTX), (IDIS | PTD | DIS | M0)); /*UART3_TX_IRTX*/
-
-	MUX_VAL(CP(HSUSB0_CLK), (IEN  | PTD | DIS | M0)); /*HSUSB0_CLK*/
-	MUX_VAL(CP(HSUSB0_STP), (IDIS | PTU | EN  | M0)); /*HSUSB0_STP*/
-	MUX_VAL(CP(HSUSB0_DIR), (IEN  | PTD | DIS | M0)); /*HSUSB0_DIR*/
-	MUX_VAL(CP(HSUSB0_NXT), (IEN  | PTD | DIS | M0)); /*HSUSB0_NXT*/
-	MUX_VAL(CP(HSUSB0_DATA0), (IEN  | PTD | DIS | M0)); /*HSUSB0_DATA0*/
-	MUX_VAL(CP(HSUSB0_DATA1), (IEN  | PTD | DIS | M0)); /*HSUSB0_DATA1*/
-	MUX_VAL(CP(HSUSB0_DATA2), (IEN  | PTD | DIS | M0)); /*HSUSB0_DATA2*/
-	MUX_VAL(CP(HSUSB0_DATA3), (IEN  | PTD | DIS | M0)); /*HSUSB0_DATA3*/
-	MUX_VAL(CP(HSUSB0_DATA4), (IEN  | PTD | DIS | M0)); /*HSUSB0_DATA4*/
-	MUX_VAL(CP(HSUSB0_DATA5), (IEN  | PTD | DIS | M0)); /*HSUSB0_DATA5*/
-	MUX_VAL(CP(HSUSB0_DATA6), (IEN  | PTD | DIS | M0)); /*HSUSB0_DATA6*/
-	MUX_VAL(CP(HSUSB0_DATA7), (IEN  | PTD | DIS | M0)); /*HSUSB0_DATA7*/
-
-	MUX_VAL(CP(I2C1_SCL), (IEN  | PTU | EN  | M0)); /*I2C1_SCL*/
-	MUX_VAL(CP(I2C1_SDA), (IEN  | PTU | EN  | M0)); /*I2C1_SDA*/
-
-	MUX_VAL(CP(I2C2_SCL), (IEN  | PTU | EN  | M0)); /*I2C2_SCL*/
-	MUX_VAL(CP(I2C2_SDA), (IEN  | PTU | EN  | M0)); /*I2C2_SDA*/
-
-	MUX_VAL(CP(I2C3_SCL), (IEN  | PTU | EN  | M0)); /*I2C3_SCL*/
-	MUX_VAL(CP(I2C3_SDA), (IEN  | PTU | EN  | M0)); /*I2C3_SDA*/
-
-	MUX_VAL(CP(I2C4_SCL), (IEN  | PTU | EN  | M0)); /*I2C4_SCL*/
-	MUX_VAL(CP(I2C4_SDA), (IEN  | PTU | EN  | M0)); /*I2C4_SDA*/
-
-	MUX_VAL(CP(HDQ_SIO), (IEN  | PTU | EN  | M0)); /*HDQ_SIO*/
-
-	MUX_VAL(CP(MCSPI1_CLK), (IEN  | PTD | DIS | M0)); /*McSPI1_CLK*/
-	MUX_VAL(CP(MCSPI1_SIMO), (IEN  | PTD | DIS | M0)); /*McSPI1_SIMO  */
-	MUX_VAL(CP(MCSPI1_SOMI), (IEN  | PTD | DIS | M0)); /*McSPI1_SOMI  */
-	MUX_VAL(CP(MCSPI1_CS0), (IEN  | PTD | EN  | M0)); /*McSPI1_CS0*/
-	MUX_VAL(CP(MCSPI1_CS1), (IEN  | PTD | EN  | M4)); /*GPIO_175*/
-	MUX_VAL(CP(MCSPI1_CS2), (IEN  | PTU | DIS | M4)); /*GPIO_176*/
-	MUX_VAL(CP(MCSPI1_CS3), (IEN  | PTD | EN  | M0)); /*McSPI1_CS3*/
-
-	MUX_VAL(CP(MCSPI2_CLK), (IEN  | PTD | DIS | M0)); /*McSPI2_CLK*/
-	MUX_VAL(CP(MCSPI2_SIMO), (IEN  | PTD | DIS | M0)); /*McSPI2_SIMO*/
-	MUX_VAL(CP(MCSPI2_SOMI), (IEN  | PTD | DIS | M0)); /*McSPI2_SOMI*/
-	MUX_VAL(CP(MCSPI2_CS0),  (IEN  | PTD | EN  | M0)); /*McSPI2_CS0*/
-	MUX_VAL(CP(MCSPI2_CS1),  (IEN  | PTD | EN  | M0)); /*McSPI2_CS1*/
-
-	MUX_VAL(CP(SYS_32K), (IEN  | PTD | DIS | M0)); /*SYS_32K*/
-	MUX_VAL(CP(SYS_CLKREQ), (IEN  | PTD | DIS | M0)); /*SYS_CLKREQ*/
-	MUX_VAL(CP(SYS_NIRQ), (IEN  | PTU | EN  | M0)); /*SYS_nIRQ*/
-	MUX_VAL(CP(SYS_BOOT0), (IEN  | PTD | DIS | M4)); /*GPIO_2*/
-	MUX_VAL(CP(SYS_BOOT1), (IEN  | PTD | DIS | M4)); /*GPIO_3 */
-	MUX_VAL(CP(SYS_BOOT2), (IEN  | PTD | DIS | M4)); /*GPIO_4*/
-	MUX_VAL(CP(SYS_BOOT3), (IEN  | PTD | DIS | M4)); /*GPIO_5*/
-	MUX_VAL(CP(SYS_BOOT4), (IEN  | PTD | DIS | M4)); /*GPIO_6*/
-	MUX_VAL(CP(SYS_BOOT5), (IEN  | PTD | DIS | M4)); /*GPIO_7*/
-
-	MUX_VAL(CP(SYS_OFF_MODE), (IEN  | PTD | DIS | M0)); /*SYS_OFF_MODE*/
-	MUX_VAL(CP(SYS_CLKOUT1), (IEN  | PTD | DIS | M0)); /*SYS_CLKOUT1*/
-	MUX_VAL(CP(SYS_CLKOUT2), (IEN  | PTU | EN  | M0)); /*SYS_CLKOUT2*/
-
-	MUX_VAL(CP(JTAG_TCK), (IEN  | PTD | DIS | M0)); /*JTAG_TCK*/
-	MUX_VAL(CP(JTAG_TMS), (IEN  | PTD | DIS | M0)); /*JTAG_TMS*/
-	MUX_VAL(CP(JTAG_TDI), (IEN  | PTD | DIS | M0)); /*JTAG_TDI*/
-	MUX_VAL(CP(JTAG_EMU0), (IEN  | PTD | DIS | M0)); /*JTAG_EMU0*/
-	MUX_VAL(CP(JTAG_EMU1), (IEN  | PTD | DIS | M0)); /*JTAG_EMU1*/
-
-	MUX_VAL(CP(ETK_CLK_ES2), (IDIS | PTU | EN  | M0)); /*ETK_CLK*/
-	MUX_VAL(CP(ETK_CTL_ES2), (IDIS | PTD | DIS | M0)); /*ETK_CTL*/
-	MUX_VAL(CP(ETK_D0_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D0*/
-	MUX_VAL(CP(ETK_D1_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D1*/
-	MUX_VAL(CP(ETK_D2_ES2), (IEN  | PTD | EN  | M0)); /*ETK_D2*/
-	MUX_VAL(CP(ETK_D3_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D3*/
-	MUX_VAL(CP(ETK_D4_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D4*/
-	MUX_VAL(CP(ETK_D5_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D5*/
-	MUX_VAL(CP(ETK_D6_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D6*/
-	MUX_VAL(CP(ETK_D7_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D7*/
-	MUX_VAL(CP(ETK_D8_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D8*/
-	MUX_VAL(CP(ETK_D9_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D9*/
-	MUX_VAL(CP(ETK_D10_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D10*/
-	MUX_VAL(CP(ETK_D11_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D11*/
-	MUX_VAL(CP(ETK_D12_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D12*/
-	MUX_VAL(CP(ETK_D13_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D13*/
-	MUX_VAL(CP(ETK_D14_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D14*/
-	MUX_VAL(CP(ETK_D15_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D15*/
 
-	MUX_VAL(CP(D2D_MCAD1), (IEN  | PTD | EN  | M0)); /*d2d_mcad1*/
-	MUX_VAL(CP(D2D_MCAD2), (IEN  | PTD | EN  | M0)); /*d2d_mcad2*/
-	MUX_VAL(CP(D2D_MCAD3), (IEN  | PTD | EN  | M0)); /*d2d_mcad3*/
-	MUX_VAL(CP(D2D_MCAD4), (IEN  | PTD | EN  | M0)); /*d2d_mcad4*/
-	MUX_VAL(CP(D2D_MCAD5), (IEN  | PTD | EN  | M0)); /*d2d_mcad5*/
-	MUX_VAL(CP(D2D_MCAD6), (IEN  | PTD | EN  | M0)); /*d2d_mcad6*/
-	MUX_VAL(CP(D2D_MCAD7), (IEN  | PTD | EN  | M0)); /*d2d_mcad7*/
-	MUX_VAL(CP(D2D_MCAD8), (IEN  | PTD | EN  | M0)); /*d2d_mcad8*/
-	MUX_VAL(CP(D2D_MCAD9), (IEN  | PTD | EN  | M0)); /*d2d_mcad9*/
-	MUX_VAL(CP(D2D_MCAD10), (IEN  | PTD | EN  | M0)); /*d2d_mcad10*/
-	MUX_VAL(CP(D2D_MCAD11), (IEN  | PTD | EN  | M0)); /*d2d_mcad11*/
-	MUX_VAL(CP(D2D_MCAD12), (IEN  | PTD | EN  | M0)); /*d2d_mcad12*/
-	MUX_VAL(CP(D2D_MCAD13), (IEN  | PTD | EN  | M0)); /*d2d_mcad13*/
-	MUX_VAL(CP(D2D_MCAD14), (IEN  | PTD | EN  | M0)); /*d2d_mcad14*/
-	MUX_VAL(CP(D2D_MCAD15), (IEN  | PTD | EN  | M0)); /*d2d_mcad15*/
-	MUX_VAL(CP(D2D_MCAD16), (IEN  | PTD | EN  | M0)); /*d2d_mcad16*/
-	MUX_VAL(CP(D2D_MCAD17), (IEN  | PTD | EN  | M0)); /*d2d_mcad17*/
-	MUX_VAL(CP(D2D_MCAD18), (IEN  | PTD | EN  | M0)); /*d2d_mcad18*/
-	MUX_VAL(CP(D2D_MCAD19), (IEN  | PTD | EN  | M0)); /*d2d_mcad19*/
-	MUX_VAL(CP(D2D_MCAD20), (IEN  | PTD | EN  | M0)); /*d2d_mcad20*/
-	MUX_VAL(CP(D2D_MCAD21), (IEN  | PTD | EN  | M0)); /*d2d_mcad21*/
-	MUX_VAL(CP(D2D_MCAD22), (IEN  | PTD | EN  | M0)); /*d2d_mcad22*/
-	MUX_VAL(CP(D2D_MCAD23), (IEN  | PTD | EN  | M0)); /*d2d_mcad23*/
-	MUX_VAL(CP(D2D_MCAD24), (IEN  | PTD | EN  | M0)); /*d2d_mcad24*/
-	MUX_VAL(CP(D2D_MCAD25), (IEN  | PTD | EN  | M0)); /*d2d_mcad25*/
-	MUX_VAL(CP(D2D_MCAD26), (IEN  | PTD | EN  | M0)); /*d2d_mcad26*/
-	MUX_VAL(CP(D2D_MCAD27), (IEN  | PTD | EN  | M0)); /*d2d_mcad27*/
-	MUX_VAL(CP(D2D_MCAD28), (IEN  | PTD | EN  | M0)); /*d2d_mcad28*/
-	MUX_VAL(CP(D2D_MCAD29), (IEN  | PTD | EN  | M0)); /*d2d_mcad29*/
-	MUX_VAL(CP(D2D_MCAD30), (IEN  | PTD | EN  | M0)); /*d2d_mcad30*/
-	MUX_VAL(CP(D2D_MCAD31), (IEN  | PTD | EN  | M0)); /*d2d_mcad31*/
-	MUX_VAL(CP(D2D_MCAD32), (IEN  | PTD | EN  | M0)); /*d2d_mcad32*/
-	MUX_VAL(CP(D2D_MCAD33), (IEN  | PTD | EN  | M0)); /*d2d_mcad33*/
-	MUX_VAL(CP(D2D_MCAD34), (IEN  | PTD | EN  | M0)); /*d2d_mcad34*/
-	MUX_VAL(CP(D2D_MCAD35), (IEN  | PTD | EN  | M0)); /*d2d_mcad35*/
-	MUX_VAL(CP(D2D_MCAD36), (IEN  | PTD | EN  | M0)); /*d2d_mcad36*/
-	MUX_VAL(CP(D2D_CLK26MI), (IEN  | PTD | DIS | M0)); /*d2d_clk26mi*/
-	MUX_VAL(CP(D2D_NRESPWRON), (IEN  | PTD | EN  | M0)); /*d2d_nrespwron*/
-	MUX_VAL(CP(D2D_NRESWARM), (IEN  | PTU | EN  | M0)); /*d2d_nreswarm */
-	MUX_VAL(CP(D2D_ARM9NIRQ), (IEN  | PTD | DIS | M0)); /*d2d_arm9nirq */
-	MUX_VAL(CP(D2D_UMA2P6FIQ), (IEN  | PTD | DIS | M0)); /*d2d_uma2p6fiq*/
-	MUX_VAL(CP(D2D_SPINT), (IEN  | PTD | EN  | M0)); /*d2d_spint*/
-	MUX_VAL(CP(D2D_FRINT), (IEN  | PTD | EN  | M0)); /*d2d_frint*/
-	MUX_VAL(CP(D2D_DMAREQ0), (IEN  | PTD | DIS | M0)); /*d2d_dmareq0*/
-	MUX_VAL(CP(D2D_DMAREQ1), (IEN  | PTD | DIS | M0)); /*d2d_dmareq1*/
-	MUX_VAL(CP(D2D_DMAREQ2), (IEN  | PTD | DIS | M0)); /*d2d_dmareq2*/
-	MUX_VAL(CP(D2D_DMAREQ3), (IEN  | PTD | DIS | M0)); /*d2d_dmareq3*/
-	MUX_VAL(CP(D2D_N3GTRST), (IEN  | PTD | DIS | M0)); /*d2d_n3gtrst*/
-	MUX_VAL(CP(D2D_N3GTDI),  (IEN  | PTD | DIS | M0)); /*d2d_n3gtdi*/
-	MUX_VAL(CP(D2D_N3GTDO),  (IEN  | PTD | DIS | M0)); /*d2d_n3gtdo*/
-	MUX_VAL(CP(D2D_N3GTMS),  (IEN  | PTD | DIS | M0)); /*d2d_n3gtms*/
-	MUX_VAL(CP(D2D_N3GTCK),  (IEN  | PTD | DIS | M0)); /*d2d_n3gtck*/
-	MUX_VAL(CP(D2D_N3GRTCK), (IEN  | PTD | DIS | M0)); /*d2d_n3grtck*/
-	MUX_VAL(CP(D2D_MSTDBY),  (IEN  | PTU | EN  | M0)); /*d2d_mstdby*/
-	MUX_VAL(CP(D2D_SWAKEUP), (IEN  | PTD | EN  | M0)); /*d2d_swakeup*/
-	MUX_VAL(CP(D2D_IDLEREQ), (IEN  | PTD | DIS | M0)); /*d2d_idlereq*/
-	MUX_VAL(CP(D2D_IDLEACK), (IEN  | PTU | EN  | M0)); /*d2d_idleack*/
-	MUX_VAL(CP(D2D_MWRITE),  (IEN  | PTD | DIS | M0)); /*d2d_mwrite*/
-	MUX_VAL(CP(D2D_SWRITE),  (IEN  | PTD | DIS | M0)); /*d2d_swrite*/
-	MUX_VAL(CP(D2D_MREAD),   (IEN  | PTD | DIS | M0)); /*d2d_mread*/
-	MUX_VAL(CP(D2D_SREAD),   (IEN  | PTD | DIS | M0)); /*d2d_sread*/
-	MUX_VAL(CP(D2D_MBUSFLAG), (IEN  | PTD | DIS | M0)); /*d2d_mbusflag*/
-	MUX_VAL(CP(D2D_SBUSFLAG), (IEN  | PTD | DIS | M0)); /*d2d_sbusflag*/
-}
diff --git a/board/logicpd/omap3som/omap3logic.h b/board/logicpd/omap3som/omap3logic.h
index 3a3ef6e..22d7760 100644
--- a/board/logicpd/omap3som/omap3logic.h
+++ b/board/logicpd/omap3som/omap3logic.h
@@ -27,5 +27,338 @@
 	"NAND",
 };
 
+/*
+ * IEN  - Input Enable
+ * IDIS - Input Disable
+ * PTD  - Pull type Down
+ * PTU  - Pull type Up
+ * DIS  - Pull type selection is inactive
+ * EN   - Pull type selection is active
+ * M0   - Mode 0
+ * The commented string gives the final mux configuration for that pin
+ */
+
+/*
+ * Routine: set_muxconf_regs
+ * Description: Setting up the configuration Mux registers specific to the
+ *		hardware. Many pins need to be moved from protect to primary
+ *		mode.
+ */
+void set_muxconf_regs(void)
+{
+	MUX_VAL(CP(SDRC_D0), (IEN  | PTD | DIS | M0)); /*SDRC_D0*/
+	MUX_VAL(CP(SDRC_D1), (IEN  | PTD | DIS | M0)); /*SDRC_D1*/
+	MUX_VAL(CP(SDRC_D2), (IEN  | PTD | DIS | M0)); /*SDRC_D2*/
+	MUX_VAL(CP(SDRC_D3), (IEN  | PTD | DIS | M0)); /*SDRC_D3*/
+	MUX_VAL(CP(SDRC_D4), (IEN  | PTD | DIS | M0)); /*SDRC_D4*/
+	MUX_VAL(CP(SDRC_D5), (IEN  | PTD | DIS | M0)); /*SDRC_D5*/
+	MUX_VAL(CP(SDRC_D6), (IEN  | PTD | DIS | M0)); /*SDRC_D6*/
+	MUX_VAL(CP(SDRC_D7), (IEN  | PTD | DIS | M0)); /*SDRC_D7*/
+	MUX_VAL(CP(SDRC_D8), (IEN  | PTD | DIS | M0)); /*SDRC_D8*/
+	MUX_VAL(CP(SDRC_D9), (IEN  | PTD | DIS | M0)); /*SDRC_D9*/
+	MUX_VAL(CP(SDRC_D10), (IEN  | PTD | DIS | M0)); /*SDRC_D10*/
+	MUX_VAL(CP(SDRC_D11), (IEN  | PTD | DIS | M0)); /*SDRC_D11*/
+	MUX_VAL(CP(SDRC_D12), (IEN  | PTD | DIS | M0)); /*SDRC_D12*/
+	MUX_VAL(CP(SDRC_D13), (IEN  | PTD | DIS | M0)); /*SDRC_D13*/
+	MUX_VAL(CP(SDRC_D14), (IEN  | PTD | DIS | M0)); /*SDRC_D14*/
+	MUX_VAL(CP(SDRC_D15), (IEN  | PTD | DIS | M0)); /*SDRC_D15*/
+	MUX_VAL(CP(SDRC_D16), (IEN  | PTD | DIS | M0)); /*SDRC_D16*/
+	MUX_VAL(CP(SDRC_D17), (IEN  | PTD | DIS | M0)); /*SDRC_D17*/
+	MUX_VAL(CP(SDRC_D18), (IEN  | PTD | DIS | M0)); /*SDRC_D18*/
+	MUX_VAL(CP(SDRC_D19), (IEN  | PTD | DIS | M0)); /*SDRC_D19*/
+	MUX_VAL(CP(SDRC_D20), (IEN  | PTD | DIS | M0)); /*SDRC_D20*/
+	MUX_VAL(CP(SDRC_D21), (IEN  | PTD | DIS | M0)); /*SDRC_D21*/
+	MUX_VAL(CP(SDRC_D22), (IEN  | PTD | DIS | M0)); /*SDRC_D22*/
+	MUX_VAL(CP(SDRC_D23), (IEN  | PTD | DIS | M0)); /*SDRC_D23*/
+	MUX_VAL(CP(SDRC_D24), (IEN  | PTD | DIS | M0)); /*SDRC_D24*/
+	MUX_VAL(CP(SDRC_D25), (IEN  | PTD | DIS | M0)); /*SDRC_D25*/
+	MUX_VAL(CP(SDRC_D26), (IEN  | PTD | DIS | M0)); /*SDRC_D26*/
+	MUX_VAL(CP(SDRC_D27), (IEN  | PTD | DIS | M0)); /*SDRC_D27*/
+	MUX_VAL(CP(SDRC_D28), (IEN  | PTD | DIS | M0)); /*SDRC_D28*/
+	MUX_VAL(CP(SDRC_D29), (IEN  | PTD | DIS | M0)); /*SDRC_D29*/
+	MUX_VAL(CP(SDRC_D30), (IEN  | PTD | DIS | M0)); /*SDRC_D30*/
+	MUX_VAL(CP(SDRC_D31), (IEN  | PTD | DIS | M0)); /*SDRC_D31*/
+	MUX_VAL(CP(SDRC_CLK), (IEN  | PTD | DIS | M0)); /*SDRC_CLK*/
+	MUX_VAL(CP(SDRC_DQS0), (IEN  | PTD | DIS | M0)); /*SDRC_DQS0*/
+	MUX_VAL(CP(SDRC_DQS1), (IEN  | PTD | DIS | M0)); /*SDRC_DQS1*/
+	MUX_VAL(CP(SDRC_DQS2), (IEN  | PTD | DIS | M0)); /*SDRC_DQS2*/
+	MUX_VAL(CP(SDRC_DQS3), (IEN  | PTD | DIS | M0)); /*SDRC_DQS3*/
+	MUX_VAL(CP(SDRC_CKE0), (IDIS | PTU | EN  | M0)); /*SDRC_CKE0*/
+	MUX_VAL(CP(SDRC_CKE1), (IDIS | PTU | DIS | M0)); /*SDRC_CKE1*/
+
+	MUX_VAL(CP(GPMC_A1), (IDIS | PTU | EN  | M0)); /*GPMC_A1*/
+	MUX_VAL(CP(GPMC_A2), (IDIS | PTU | EN  | M0)); /*GPMC_A2*/
+	MUX_VAL(CP(GPMC_A3), (IDIS | PTU | EN  | M0)); /*GPMC_A3*/
+	MUX_VAL(CP(GPMC_A4), (IDIS | PTU | EN  | M0)); /*GPMC_A4*/
+	MUX_VAL(CP(GPMC_A5), (IDIS | PTU | EN  | M0)); /*GPMC_A5*/
+	MUX_VAL(CP(GPMC_A6), (IDIS | PTU | EN  | M0)); /*GPMC_A6*/
+	MUX_VAL(CP(GPMC_A7), (IDIS | PTU | EN  | M0)); /*GPMC_A7*/
+	MUX_VAL(CP(GPMC_A8), (IDIS | PTU | EN  | M0)); /*GPMC_A8*/
+	MUX_VAL(CP(GPMC_A9), (IDIS | PTU | EN  | M0)); /*GPMC_A9*/
+	MUX_VAL(CP(GPMC_A10), (IDIS | PTU | EN  | M0)); /*GPMC_A10*/
+	MUX_VAL(CP(GPMC_D0), (IEN  | PTU | EN  | M0)); /*GPMC_D0*/
+	MUX_VAL(CP(GPMC_D1), (IEN  | PTU | EN  | M0)); /*GPMC_D1*/
+	MUX_VAL(CP(GPMC_D2), (IEN  | PTU | EN  | M0)); /*GPMC_D2*/
+	MUX_VAL(CP(GPMC_D3), (IEN  | PTU | EN  | M0)); /*GPMC_D3*/
+	MUX_VAL(CP(GPMC_D4),  (IEN  | PTU | EN  | M0)); /*GPMC_D4*/
+	MUX_VAL(CP(GPMC_D5),  (IEN  | PTU | EN  | M0)); /*GPMC_D5*/
+	MUX_VAL(CP(GPMC_D6),  (IEN  | PTU | EN  | M0)); /*GPMC_D6*/
+	MUX_VAL(CP(GPMC_D7),   (IEN  | PTU | EN  | M0)); /*GPMC_D7*/
+	MUX_VAL(CP(GPMC_D8),  (IEN  | PTU | EN  | M0)); /*GPMC_D8*/
+	MUX_VAL(CP(GPMC_D9),  (IEN  | PTU | EN  | M0)); /*GPMC_D9*/
+	MUX_VAL(CP(GPMC_D10), (IEN  | PTU | EN  | M0)); /*GPMC_D10*/
+	MUX_VAL(CP(GPMC_D11), (IEN  | PTU | EN  | M0)); /*GPMC_D11*/
+	MUX_VAL(CP(GPMC_D12), (IEN  | PTU | EN  | M0)); /*GPMC_D12*/
+	MUX_VAL(CP(GPMC_D13), (IEN  | PTU | EN  | M0)); /*GPMC_D13*/
+	MUX_VAL(CP(GPMC_D14), (IEN  | PTU | EN  | M0)); /*GPMC_D14*/
+	MUX_VAL(CP(GPMC_D15), (IEN  | PTU | EN  | M0)); /*GPMC_D15*/
+	MUX_VAL(CP(GPMC_NCS0), (IDIS | PTU | EN  | M0)); /*GPMC_nCS0*/
+	MUX_VAL(CP(GPMC_NCS1), (IDIS | PTU | EN  | M0)); /*GPMC_nCS1*/
+	MUX_VAL(CP(GPMC_NCS2), (IDIS | PTU | EN  | M0)); /*GPMC_nCS2*/
+	MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | EN  | M0)); /*GPMC_nCS3*/
+	MUX_VAL(CP(GPMC_NCS4), (IEN  | PTU | EN  | M0)); /*GPMC_nCS4*/
+	MUX_VAL(CP(GPMC_NCS5), (IDIS | PTU | EN  | M0)); /*GPMC_nCS5*/
+	MUX_VAL(CP(GPMC_NCS6), (IEN  | PTU | EN | M0)); /*GPMC_nCS6*/
+	MUX_VAL(CP(GPMC_NCS7), (IEN  | PTU | EN  | M0)); /*GPMC_nCS7*/
+	MUX_VAL(CP(GPMC_CLK),  (IDIS | PTU | EN  | M0)); /*GPMC_CLK*/
+	MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0)); /*GPMC_nADV_ALE*/
+	MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0)); /*GPMC_nOE*/
+	MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0)); /*GPMC_nWE*/
+	MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTU | EN  | M0)); /*GPMC_nBE0_CLE*/
+	MUX_VAL(CP(GPMC_NBE1), (IEN  | PTU | EN  | M0)); /*GPMC_nBE1*/
+	MUX_VAL(CP(GPMC_NWP),  (IEN  | PTD | DIS | M0)); /*GPMC_nWP*/
+	MUX_VAL(CP(GPMC_WAIT0), (IEN  | PTU | EN  | M0)); /*GPMC_WAIT0*/
+	MUX_VAL(CP(GPMC_WAIT1), (IEN  | PTU | EN  | M0)); /*GPMC_WAIT1*/
+	MUX_VAL(CP(GPMC_WAIT2), (IEN  | PTU | EN  | M4)); /*GPIO_64*/
+	MUX_VAL(CP(GPMC_WAIT3), (IEN  | PTU | EN  | M0)); /*GPMC_WAIT3*/
+
+	MUX_VAL(CP(CAM_HS), (IEN  | PTU | EN  | M0)); /*CAM_HS */
+	MUX_VAL(CP(CAM_VS), (IEN  | PTU | EN  | M0)); /*CAM_VS */
+	MUX_VAL(CP(CAM_XCLKA), (IDIS | PTD | DIS | M0)); /*CAM_XCLKA*/
+	MUX_VAL(CP(CAM_PCLK), (IEN  | PTU | EN  | M0)); /*CAM_PCLK*/
+	MUX_VAL(CP(CAM_FLD), (IDIS | PTD | DIS | M4)); /*GPIO_98*/
+	MUX_VAL(CP(CAM_D0), (IEN  | PTD | DIS | M0)); /*CAM_D0*/
+	MUX_VAL(CP(CAM_D1), (IEN  | PTD | DIS | M0)); /*CAM_D1*/
+	MUX_VAL(CP(CAM_D2), (IEN  | PTD | DIS | M0)); /*CAM_D2*/
+	MUX_VAL(CP(CAM_D3), (IEN  | PTD | DIS | M0)); /*CAM_D3*/
+	MUX_VAL(CP(CAM_D4), (IEN  | PTD | DIS | M0)); /*CAM_D4*/
+	MUX_VAL(CP(CAM_D5), (IEN  | PTD | DIS | M0)); /*CAM_D5*/
+	MUX_VAL(CP(CAM_D6), (IEN  | PTD | DIS | M0)); /*CAM_D6*/
+	MUX_VAL(CP(CAM_D7), (IEN  | PTD | DIS | M0)); /*CAM_D7*/
+	MUX_VAL(CP(CAM_D8), (IEN  | PTD | DIS | M0)); /*CAM_D8*/
+	MUX_VAL(CP(CAM_D9), (IEN  | PTD | DIS | M0)); /*CAM_D9*/
+	MUX_VAL(CP(CAM_D10), (IEN  | PTD | DIS | M0)); /*CAM_D10*/
+	MUX_VAL(CP(CAM_D11), (IEN  | PTD | DIS | M0)); /*CAM_D11*/
+	MUX_VAL(CP(CAM_XCLKB), (IDIS | PTD | DIS | M0)); /*CAM_XCLKB*/
+	MUX_VAL(CP(CAM_WEN), (IEN  | PTD | DIS | M4)); /*GPIO_167*/
+	MUX_VAL(CP(CAM_STROBE), (IDIS | PTD | DIS | M0)); /*CAM_STROBE*/
+
+	MUX_VAL(CP(CSI2_DX0), (IEN  | PTD | DIS | M0)); /*CSI2_DX0*/
+	MUX_VAL(CP(CSI2_DY0), (IEN  | PTD | DIS | M0)); /*CSI2_DY0*/
+	MUX_VAL(CP(CSI2_DX1), (IEN  | PTD | DIS | M0)); /*CSI2_DX1*/
+	MUX_VAL(CP(CSI2_DY1), (IEN  | PTD | DIS | M0)); /*CSI2_DY1*/
+
+	MUX_VAL(CP(MCBSP2_FSX), (IEN  | PTD | DIS | M0)); /*McBSP2_FSX*/
+	MUX_VAL(CP(MCBSP2_CLKX), (IEN  | PTD | DIS | M0)); /*McBSP2_CLKX*/
+	MUX_VAL(CP(MCBSP2_DR), (IEN  | PTD | DIS | M0)); /*McBSP2_DR*/
+	MUX_VAL(CP(MCBSP2_DX), (IDIS | PTD | DIS | M0)); /*McBSP2_DX*/
+
+	MUX_VAL(CP(MMC1_CLK), (IDIS | PTU | EN  | M0)); /*MMC1_CLK*/
+	MUX_VAL(CP(MMC1_CMD), (IEN  | PTU | EN  | M0)); /*MMC1_CMD*/
+	MUX_VAL(CP(MMC1_DAT0), (IEN  | PTU | EN  | M0)); /*MMC1_DAT0*/
+	MUX_VAL(CP(MMC1_DAT1), (IEN  | PTU | EN  | M0)); /*MMC1_DAT1*/
+	MUX_VAL(CP(MMC1_DAT2), (IEN  | PTU | EN  | M0)); /*MMC1_DAT2*/
+	MUX_VAL(CP(MMC1_DAT3), (IEN  | PTU | EN  | M0)); /*MMC1_DAT3*/
+	MUX_VAL(CP(MMC1_DAT4), (IEN  | PTU | EN  | M0)); /*MMC1_DAT4*/
+	MUX_VAL(CP(MMC1_DAT5), (IEN  | PTU | EN  | M0)); /*MMC1_DAT5*/
+	MUX_VAL(CP(MMC1_DAT6), (IEN  | PTU | EN  | M0)); /*MMC1_DAT6*/
+	MUX_VAL(CP(MMC1_DAT7), (IEN  | PTU | EN  | M0)); /*MMC1_DAT7*/
+
+	MUX_VAL(CP(MMC2_CLK),  (IEN  | PTD | DIS | M0)); /*MMC2_CLK*/
+	MUX_VAL(CP(MMC2_CMD),  (IEN  | PTU | EN  | M0)); /*MMC2_CMD*/
+	MUX_VAL(CP(MMC2_DAT0), (IEN  | PTU | EN  | M0)); /*MMC2_DAT0*/
+	MUX_VAL(CP(MMC2_DAT1), (IEN  | PTU | EN  | M0)); /*MMC2_DAT1*/
+	MUX_VAL(CP(MMC2_DAT2), (IEN  | PTU | EN  | M0)); /*MMC2_DAT2*/
+	MUX_VAL(CP(MMC2_DAT3), (IEN  | PTU | EN  | M0)); /*MMC2_DAT3*/
+	MUX_VAL(CP(MMC2_DAT4), (IDIS | PTD | DIS | M0)); /*MMC2_DAT4*/
+	MUX_VAL(CP(MMC2_DAT5), (IDIS | PTD | DIS | M0)); /*MMC2_DAT5*/
+	MUX_VAL(CP(MMC2_DAT6), (IDIS | PTD | DIS | M0)); /*MMC2_DAT6 */
+	MUX_VAL(CP(MMC2_DAT7), (IEN  | PTU | EN  | M0)); /*MMC2_DAT7*/
+
+	MUX_VAL(CP(MCBSP3_DX), (IDIS | PTD | DIS | M0)); /*McBSP3_DX*/
+	MUX_VAL(CP(MCBSP3_DR), (IEN  | PTD | DIS | M0)); /*McBSP3_DR*/
+	MUX_VAL(CP(MCBSP3_CLKX), (IEN  | PTD | DIS | M0)); /*McBSP3_CLKX*/
+	MUX_VAL(CP(MCBSP3_FSX), (IEN  | PTD | DIS | M0)); /*McBSP3_FSX*/
+
+	MUX_VAL(CP(UART2_CTS), (IEN  | PTU | EN  | M0)); /*UART2_CTS*/
+	MUX_VAL(CP(UART2_RTS), (IDIS | PTD | DIS | M0)); /*UART2_RTS*/
+	MUX_VAL(CP(UART2_TX), (IDIS | PTD | DIS | M0)); /*UART2_TX*/
+	MUX_VAL(CP(UART2_RX), (IEN  | PTD | DIS | M0)); /*UART2_RX*/
+
+	MUX_VAL(CP(UART1_TX), (IDIS | PTD | DIS | M0)); /*UART1_TX*/
+	MUX_VAL(CP(UART1_RTS), (IDIS | PTD | DIS | M0)); /*UART1_RTS*/
+	MUX_VAL(CP(UART1_CTS), (IEN  | PTU | DIS | M0)); /*UART1_CTS*/
+	MUX_VAL(CP(UART1_RX), (IEN  | PTD | DIS | M0)); /*UART1_RX*/
+
+	MUX_VAL(CP(MCBSP4_CLKX), (IDIS | PTD | DIS | M4)); /*GPIO_152*/
+	MUX_VAL(CP(MCBSP4_DR), (IDIS | PTD | DIS | M4)); /*GPIO_153*/
+
+	MUX_VAL(CP(MCBSP1_CLKR), (IEN  | PTD | DIS | M0)); /*MCBSP1_CLKR*/
+	MUX_VAL(CP(MCBSP1_FSR), (IDIS | PTU | EN  | M0)); /*MCBSP1_FSR*/
+	MUX_VAL(CP(MCBSP1_DX), (IDIS | PTD | DIS | M0)); /*MCBSP1_DX*/
+	MUX_VAL(CP(MCBSP1_DR), (IEN  | PTD | DIS | M0)); /*MCBSP1_DR*/
+	MUX_VAL(CP(MCBSP_CLKS), (IEN  | PTU | DIS | M0)); /*MCBSP_CLKS*/
+	MUX_VAL(CP(MCBSP1_FSX), (IEN  | PTD | DIS | M0)); /*MCBSP1_FSX*/
+	MUX_VAL(CP(MCBSP1_CLKX), (IEN  | PTD | DIS | M0)); /*MCBSP1_CLKX*/
+
+	MUX_VAL(CP(UART3_CTS_RCTX), (IEN  | PTD | EN  | M0)); /*UART3_CTS_*/
+	MUX_VAL(CP(UART3_RTS_SD),  (IDIS | PTD | DIS | M0)); /*UART3_RTS_SD */
+	MUX_VAL(CP(UART3_RX_IRRX), (IEN  | PTD | DIS | M0)); /*UART3_RX_IRRX*/
+	MUX_VAL(CP(UART3_TX_IRTX), (IDIS | PTD | DIS | M0)); /*UART3_TX_IRTX*/
+
+	MUX_VAL(CP(HSUSB0_CLK), (IEN  | PTD | DIS | M0)); /*HSUSB0_CLK*/
+	MUX_VAL(CP(HSUSB0_STP), (IDIS | PTU | EN  | M0)); /*HSUSB0_STP*/
+	MUX_VAL(CP(HSUSB0_DIR), (IEN  | PTD | DIS | M0)); /*HSUSB0_DIR*/
+	MUX_VAL(CP(HSUSB0_NXT), (IEN  | PTD | DIS | M0)); /*HSUSB0_NXT*/
+	MUX_VAL(CP(HSUSB0_DATA0), (IEN  | PTD | DIS | M0)); /*HSUSB0_DATA0*/
+	MUX_VAL(CP(HSUSB0_DATA1), (IEN  | PTD | DIS | M0)); /*HSUSB0_DATA1*/
+	MUX_VAL(CP(HSUSB0_DATA2), (IEN  | PTD | DIS | M0)); /*HSUSB0_DATA2*/
+	MUX_VAL(CP(HSUSB0_DATA3), (IEN  | PTD | DIS | M0)); /*HSUSB0_DATA3*/
+	MUX_VAL(CP(HSUSB0_DATA4), (IEN  | PTD | DIS | M0)); /*HSUSB0_DATA4*/
+	MUX_VAL(CP(HSUSB0_DATA5), (IEN  | PTD | DIS | M0)); /*HSUSB0_DATA5*/
+	MUX_VAL(CP(HSUSB0_DATA6), (IEN  | PTD | DIS | M0)); /*HSUSB0_DATA6*/
+	MUX_VAL(CP(HSUSB0_DATA7), (IEN  | PTD | DIS | M0)); /*HSUSB0_DATA7*/
+
+	MUX_VAL(CP(I2C1_SCL), (IEN  | PTU | EN  | M0)); /*I2C1_SCL*/
+	MUX_VAL(CP(I2C1_SDA), (IEN  | PTU | EN  | M0)); /*I2C1_SDA*/
+
+	MUX_VAL(CP(I2C2_SCL), (IEN  | PTU | EN  | M0)); /*I2C2_SCL*/
+	MUX_VAL(CP(I2C2_SDA), (IEN  | PTU | EN  | M0)); /*I2C2_SDA*/
+
+	MUX_VAL(CP(I2C3_SCL), (IEN  | PTU | EN  | M0)); /*I2C3_SCL*/
+	MUX_VAL(CP(I2C3_SDA), (IEN  | PTU | EN  | M0)); /*I2C3_SDA*/
+
+	MUX_VAL(CP(I2C4_SCL), (IEN  | PTU | EN  | M0)); /*I2C4_SCL*/
+	MUX_VAL(CP(I2C4_SDA), (IEN  | PTU | EN  | M0)); /*I2C4_SDA*/
+
+	MUX_VAL(CP(HDQ_SIO), (IEN  | PTU | EN  | M0)); /*HDQ_SIO*/
+
+	MUX_VAL(CP(MCSPI1_CLK), (IEN  | PTD | DIS | M0)); /*McSPI1_CLK*/
+	MUX_VAL(CP(MCSPI1_SIMO), (IEN  | PTD | DIS | M0)); /*McSPI1_SIMO  */
+	MUX_VAL(CP(MCSPI1_SOMI), (IEN  | PTD | DIS | M0)); /*McSPI1_SOMI  */
+	MUX_VAL(CP(MCSPI1_CS0), (IEN  | PTD | EN  | M0)); /*McSPI1_CS0*/
+	MUX_VAL(CP(MCSPI1_CS1), (IEN  | PTD | EN  | M4)); /*GPIO_175*/
+	MUX_VAL(CP(MCSPI1_CS2), (IEN  | PTU | DIS | M4)); /*GPIO_176*/
+	MUX_VAL(CP(MCSPI1_CS3), (IEN  | PTD | EN  | M0)); /*McSPI1_CS3*/
+
+	MUX_VAL(CP(MCSPI2_CLK), (IEN  | PTD | DIS | M0)); /*McSPI2_CLK*/
+	MUX_VAL(CP(MCSPI2_SIMO), (IEN  | PTD | DIS | M0)); /*McSPI2_SIMO*/
+	MUX_VAL(CP(MCSPI2_SOMI), (IEN  | PTD | DIS | M0)); /*McSPI2_SOMI*/
+	MUX_VAL(CP(MCSPI2_CS0),  (IEN  | PTD | EN  | M0)); /*McSPI2_CS0*/
+	MUX_VAL(CP(MCSPI2_CS1),  (IEN  | PTD | EN  | M0)); /*McSPI2_CS1*/
+
+	MUX_VAL(CP(SYS_32K), (IEN  | PTD | DIS | M0)); /*SYS_32K*/
+	MUX_VAL(CP(SYS_CLKREQ), (IEN  | PTD | DIS | M0)); /*SYS_CLKREQ*/
+	MUX_VAL(CP(SYS_NIRQ), (IEN  | PTU | EN  | M0)); /*SYS_nIRQ*/
+	MUX_VAL(CP(SYS_BOOT0), (IEN  | PTD | DIS | M4)); /*GPIO_2*/
+	MUX_VAL(CP(SYS_BOOT1), (IEN  | PTD | DIS | M4)); /*GPIO_3 */
+	MUX_VAL(CP(SYS_BOOT2), (IEN  | PTD | DIS | M4)); /*GPIO_4*/
+	MUX_VAL(CP(SYS_BOOT3), (IEN  | PTD | DIS | M4)); /*GPIO_5*/
+	MUX_VAL(CP(SYS_BOOT4), (IEN  | PTD | DIS | M4)); /*GPIO_6*/
+	MUX_VAL(CP(SYS_BOOT5), (IEN  | PTD | DIS | M4)); /*GPIO_7*/
+
+	MUX_VAL(CP(SYS_OFF_MODE), (IEN  | PTD | DIS | M0)); /*SYS_OFF_MODE*/
+	MUX_VAL(CP(SYS_CLKOUT1), (IEN  | PTD | DIS | M0)); /*SYS_CLKOUT1*/
+	MUX_VAL(CP(SYS_CLKOUT2), (IEN  | PTU | EN  | M0)); /*SYS_CLKOUT2*/
+
+	MUX_VAL(CP(JTAG_TCK), (IEN  | PTD | DIS | M0)); /*JTAG_TCK*/
+	MUX_VAL(CP(JTAG_TMS), (IEN  | PTD | DIS | M0)); /*JTAG_TMS*/
+	MUX_VAL(CP(JTAG_TDI), (IEN  | PTD | DIS | M0)); /*JTAG_TDI*/
+	MUX_VAL(CP(JTAG_EMU0), (IEN  | PTD | DIS | M0)); /*JTAG_EMU0*/
+	MUX_VAL(CP(JTAG_EMU1), (IEN  | PTD | DIS | M0)); /*JTAG_EMU1*/
+
+	MUX_VAL(CP(ETK_CLK_ES2), (IDIS | PTU | EN  | M0)); /*ETK_CLK*/
+	MUX_VAL(CP(ETK_CTL_ES2), (IDIS | PTD | DIS | M0)); /*ETK_CTL*/
+	MUX_VAL(CP(ETK_D0_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D0*/
+	MUX_VAL(CP(ETK_D1_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D1*/
+	MUX_VAL(CP(ETK_D2_ES2), (IEN  | PTD | EN  | M0)); /*ETK_D2*/
+	MUX_VAL(CP(ETK_D3_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D3*/
+	MUX_VAL(CP(ETK_D4_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D4*/
+	MUX_VAL(CP(ETK_D5_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D5*/
+	MUX_VAL(CP(ETK_D6_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D6*/
+	MUX_VAL(CP(ETK_D7_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D7*/
+	MUX_VAL(CP(ETK_D8_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D8*/
+	MUX_VAL(CP(ETK_D9_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D9*/
+	MUX_VAL(CP(ETK_D10_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D10*/
+	MUX_VAL(CP(ETK_D11_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D11*/
+	MUX_VAL(CP(ETK_D12_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D12*/
+	MUX_VAL(CP(ETK_D13_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D13*/
+	MUX_VAL(CP(ETK_D14_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D14*/
+	MUX_VAL(CP(ETK_D15_ES2), (IEN  | PTD | DIS | M0)); /*ETK_D15*/
+
+	MUX_VAL(CP(D2D_MCAD1), (IEN  | PTD | EN  | M0)); /*d2d_mcad1*/
+	MUX_VAL(CP(D2D_MCAD2), (IEN  | PTD | EN  | M0)); /*d2d_mcad2*/
+	MUX_VAL(CP(D2D_MCAD3), (IEN  | PTD | EN  | M0)); /*d2d_mcad3*/
+	MUX_VAL(CP(D2D_MCAD4), (IEN  | PTD | EN  | M0)); /*d2d_mcad4*/
+	MUX_VAL(CP(D2D_MCAD5), (IEN  | PTD | EN  | M0)); /*d2d_mcad5*/
+	MUX_VAL(CP(D2D_MCAD6), (IEN  | PTD | EN  | M0)); /*d2d_mcad6*/
+	MUX_VAL(CP(D2D_MCAD7), (IEN  | PTD | EN  | M0)); /*d2d_mcad7*/
+	MUX_VAL(CP(D2D_MCAD8), (IEN  | PTD | EN  | M0)); /*d2d_mcad8*/
+	MUX_VAL(CP(D2D_MCAD9), (IEN  | PTD | EN  | M0)); /*d2d_mcad9*/
+	MUX_VAL(CP(D2D_MCAD10), (IEN  | PTD | EN  | M0)); /*d2d_mcad10*/
+	MUX_VAL(CP(D2D_MCAD11), (IEN  | PTD | EN  | M0)); /*d2d_mcad11*/
+	MUX_VAL(CP(D2D_MCAD12), (IEN  | PTD | EN  | M0)); /*d2d_mcad12*/
+	MUX_VAL(CP(D2D_MCAD13), (IEN  | PTD | EN  | M0)); /*d2d_mcad13*/
+	MUX_VAL(CP(D2D_MCAD14), (IEN  | PTD | EN  | M0)); /*d2d_mcad14*/
+	MUX_VAL(CP(D2D_MCAD15), (IEN  | PTD | EN  | M0)); /*d2d_mcad15*/
+	MUX_VAL(CP(D2D_MCAD16), (IEN  | PTD | EN  | M0)); /*d2d_mcad16*/
+	MUX_VAL(CP(D2D_MCAD17), (IEN  | PTD | EN  | M0)); /*d2d_mcad17*/
+	MUX_VAL(CP(D2D_MCAD18), (IEN  | PTD | EN  | M0)); /*d2d_mcad18*/
+	MUX_VAL(CP(D2D_MCAD19), (IEN  | PTD | EN  | M0)); /*d2d_mcad19*/
+	MUX_VAL(CP(D2D_MCAD20), (IEN  | PTD | EN  | M0)); /*d2d_mcad20*/
+	MUX_VAL(CP(D2D_MCAD21), (IEN  | PTD | EN  | M0)); /*d2d_mcad21*/
+	MUX_VAL(CP(D2D_MCAD22), (IEN  | PTD | EN  | M0)); /*d2d_mcad22*/
+	MUX_VAL(CP(D2D_MCAD23), (IEN  | PTD | EN  | M0)); /*d2d_mcad23*/
+	MUX_VAL(CP(D2D_MCAD24), (IEN  | PTD | EN  | M0)); /*d2d_mcad24*/
+	MUX_VAL(CP(D2D_MCAD25), (IEN  | PTD | EN  | M0)); /*d2d_mcad25*/
+	MUX_VAL(CP(D2D_MCAD26), (IEN  | PTD | EN  | M0)); /*d2d_mcad26*/
+	MUX_VAL(CP(D2D_MCAD27), (IEN  | PTD | EN  | M0)); /*d2d_mcad27*/
+	MUX_VAL(CP(D2D_MCAD28), (IEN  | PTD | EN  | M0)); /*d2d_mcad28*/
+	MUX_VAL(CP(D2D_MCAD29), (IEN  | PTD | EN  | M0)); /*d2d_mcad29*/
+	MUX_VAL(CP(D2D_MCAD30), (IEN  | PTD | EN  | M0)); /*d2d_mcad30*/
+	MUX_VAL(CP(D2D_MCAD31), (IEN  | PTD | EN  | M0)); /*d2d_mcad31*/
+	MUX_VAL(CP(D2D_MCAD32), (IEN  | PTD | EN  | M0)); /*d2d_mcad32*/
+	MUX_VAL(CP(D2D_MCAD33), (IEN  | PTD | EN  | M0)); /*d2d_mcad33*/
+	MUX_VAL(CP(D2D_MCAD34), (IEN  | PTD | EN  | M0)); /*d2d_mcad34*/
+	MUX_VAL(CP(D2D_MCAD35), (IEN  | PTD | EN  | M0)); /*d2d_mcad35*/
+	MUX_VAL(CP(D2D_MCAD36), (IEN  | PTD | EN  | M0)); /*d2d_mcad36*/
+	MUX_VAL(CP(D2D_CLK26MI), (IEN  | PTD | DIS | M0)); /*d2d_clk26mi*/
+	MUX_VAL(CP(D2D_NRESPWRON), (IEN  | PTD | EN  | M0)); /*d2d_nrespwron*/
+	MUX_VAL(CP(D2D_NRESWARM), (IEN  | PTU | EN  | M0)); /*d2d_nreswarm */
+	MUX_VAL(CP(D2D_ARM9NIRQ), (IEN  | PTD | DIS | M0)); /*d2d_arm9nirq */
+	MUX_VAL(CP(D2D_UMA2P6FIQ), (IEN  | PTD | DIS | M0)); /*d2d_uma2p6fiq*/
+	MUX_VAL(CP(D2D_SPINT), (IEN  | PTD | EN  | M0)); /*d2d_spint*/
+	MUX_VAL(CP(D2D_FRINT), (IEN  | PTD | EN  | M0)); /*d2d_frint*/
+	MUX_VAL(CP(D2D_DMAREQ0), (IEN  | PTD | DIS | M0)); /*d2d_dmareq0*/
+	MUX_VAL(CP(D2D_DMAREQ1), (IEN  | PTD | DIS | M0)); /*d2d_dmareq1*/
+	MUX_VAL(CP(D2D_DMAREQ2), (IEN  | PTD | DIS | M0)); /*d2d_dmareq2*/
+	MUX_VAL(CP(D2D_DMAREQ3), (IEN  | PTD | DIS | M0)); /*d2d_dmareq3*/
+	MUX_VAL(CP(D2D_N3GTRST), (IEN  | PTD | DIS | M0)); /*d2d_n3gtrst*/
+	MUX_VAL(CP(D2D_N3GTDI),  (IEN  | PTD | DIS | M0)); /*d2d_n3gtdi*/
+	MUX_VAL(CP(D2D_N3GTDO),  (IEN  | PTD | DIS | M0)); /*d2d_n3gtdo*/
+	MUX_VAL(CP(D2D_N3GTMS),  (IEN  | PTD | DIS | M0)); /*d2d_n3gtms*/
+	MUX_VAL(CP(D2D_N3GTCK),  (IEN  | PTD | DIS | M0)); /*d2d_n3gtck*/
+	MUX_VAL(CP(D2D_N3GRTCK), (IEN  | PTD | DIS | M0)); /*d2d_n3grtck*/
+	MUX_VAL(CP(D2D_MSTDBY),  (IEN  | PTU | EN  | M0)); /*d2d_mstdby*/
+	MUX_VAL(CP(D2D_SWAKEUP), (IEN  | PTD | EN  | M0)); /*d2d_swakeup*/
+	MUX_VAL(CP(D2D_IDLEREQ), (IEN  | PTD | DIS | M0)); /*d2d_idlereq*/
+	MUX_VAL(CP(D2D_IDLEACK), (IEN  | PTU | EN  | M0)); /*d2d_idleack*/
+	MUX_VAL(CP(D2D_MWRITE),  (IEN  | PTD | DIS | M0)); /*d2d_mwrite*/
+	MUX_VAL(CP(D2D_SWRITE),  (IEN  | PTD | DIS | M0)); /*d2d_swrite*/
+	MUX_VAL(CP(D2D_MREAD),   (IEN  | PTD | DIS | M0)); /*d2d_mread*/
+	MUX_VAL(CP(D2D_SREAD),   (IEN  | PTD | DIS | M0)); /*d2d_sread*/
+	MUX_VAL(CP(D2D_MBUSFLAG), (IEN  | PTD | DIS | M0)); /*d2d_mbusflag*/
+	MUX_VAL(CP(D2D_SBUSFLAG), (IEN  | PTD | DIS | M0)); /*d2d_sbusflag*/
+}
 
 #endif
diff --git a/board/ti/dra7xx/evm.c b/board/ti/dra7xx/evm.c
index 97aae01..6bcfa48 100644
--- a/board/ti/dra7xx/evm.c
+++ b/board/ti/dra7xx/evm.c
@@ -672,6 +672,13 @@
 
 	omap_die_id_serial();
 	omap_set_fastboot_vars();
+
+	/*
+	 * Hook the LDO1 regulator to EN pin. This applies only to LP8733
+	 * Rest all regulators are hooked to EN Pin at reset.
+	 */
+	if (board_is_dra71x_evm())
+		palmas_i2c_write_u8(LP873X_I2C_SLAVE_ADDR, 0x9, 0x7);
 #endif
 	return 0;
 }
diff --git a/cmd/mac.c b/cmd/mac.c
index 52d3ba0..4d0dd2b 100644
--- a/cmd/mac.c
+++ b/cmd/mac.c
@@ -13,21 +13,21 @@
 U_BOOT_CMD(
 	mac, 3, 1,  do_mac,
 	"display and program the system ID and MAC addresses in EEPROM",
-	"[read|save|id|num|errata|date|ports|0|1|2|3|4|5|6|7]\n"
+	"[read|save|id|num|errata|date|ports|port_number]\n"
 	"mac read\n"
-	"    - read EEPROM content into memory\n"
+	"    - read EEPROM content into memory data structure\n"
 	"mac save\n"
-	"    - save to the EEPROM\n"
+	"    - save memory data structure to the EEPROM\n"
 	"mac id\n"
-	"    - program system id\n"
-	"mac num\n"
-	"    - program system serial number\n"
-	"mac errata\n"
-	"    - program errata data\n"
-	"mac date\n"
-	"    - program date\n"
-	"mac ports\n"
-	"    - program the number of ports\n"
-	"mac X\n"
-	"    - program the MAC address for port X [X=0...7]"
+	"    - program system id per hard coded value\n"
+	"mac num string\n"
+	"    - program system serial number to value string\n"
+	"mac errata string\n"
+	"    - program errata data to value string\n"
+	"mac date YYMMDDhhmmss\n"
+	"    - program date to string value YYMMDDhhmmss\n"
+	"mac ports N\n"
+	"    - program the number of network ports to integer N\n"
+	"mac X string\n"
+	"    - program MAC addr for port X [X=0,1..] to colon separated string"
 );
diff --git a/common/Kconfig b/common/Kconfig
index f96a25f..c50d6eb 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -200,6 +200,23 @@
 	  CONFIG_BOOTARGS goes into the environment value "bootargs". Note that
 	  this value will also override the "chosen" node in FDT blob.
 
+config USE_BOOTCOMMAND
+	bool "Enable a default value for bootcmd"
+	help
+	  Provide a default value for the bootcmd entry in the environment.  If
+	  autoboot is enabled this is what will be run automatically.  Enable
+	  this option to be able to specify CONFIG_BOOTCOMMAND as a string.  If
+	  this option is disabled, CONFIG_BOOTCOMMAND will be undefined and
+	  won't take any space in U-Boot image.
+
+config BOOTCOMMAND
+	string "bootcmd value"
+	depends on USE_BOOTCOMMAND
+	default "run distro_bootcmd" if DISTRO_DEFAULTS
+	help
+	  This is the string of commands that will be used as bootcmd and if
+	  AUTOBOOT is set, automatically run.
+
 menu "Console"
 
 config MENU
diff --git a/configs/am335x_evm_defconfig b/configs/am335x_evm_defconfig
index 79f47c3..c98a010 100644
--- a/configs/am335x_evm_defconfig
+++ b/configs/am335x_evm_defconfig
@@ -4,6 +4,7 @@
 CONFIG_AM33XX=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-evm"
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="if test ${boot_fit} -eq 1; then run update_to_fit; fi; run findfdt; run init_console; run envboot; run distro_bootcmd"
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
diff --git a/configs/am335x_evm_nor_defconfig b/configs/am335x_evm_nor_defconfig
index e9a876d..7fd3a6a 100644
--- a/configs/am335x_evm_nor_defconfig
+++ b/configs/am335x_evm_nor_defconfig
@@ -4,6 +4,7 @@
 CONFIG_AM33XX=y
 CONFIG_NOR=y
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="if test ${boot_fit} -eq 1; then run update_to_fit; fi; run findfdt; run init_console; run envboot; run distro_bootcmd"
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
 CONFIG_ARCH_MISC_INIT=y
diff --git a/configs/am335x_evm_norboot_defconfig b/configs/am335x_evm_norboot_defconfig
index 9d424e8..7d04d66 100644
--- a/configs/am335x_evm_norboot_defconfig
+++ b/configs/am335x_evm_norboot_defconfig
@@ -6,6 +6,7 @@
 CONFIG_AM33XX=y
 CONFIG_NOR=y
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="if test ${boot_fit} -eq 1; then run update_to_fit; fi; run findfdt; run init_console; run envboot; run distro_bootcmd"
 CONFIG_NOR_BOOT=y
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
diff --git a/configs/am335x_evm_spiboot_defconfig b/configs/am335x_evm_spiboot_defconfig
index ad79d6c..d1dfa89 100644
--- a/configs/am335x_evm_spiboot_defconfig
+++ b/configs/am335x_evm_spiboot_defconfig
@@ -6,6 +6,7 @@
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="if test ${boot_fit} -eq 1; then run update_to_fit; fi; run findfdt; run init_console; run envboot; run distro_bootcmd"
 CONFIG_SYS_EXTRA_OPTIONS="SPI_BOOT"
 CONFIG_SPI_BOOT=y
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
diff --git a/configs/am335x_evm_usbspl_defconfig b/configs/am335x_evm_usbspl_defconfig
index e3431db..c9041aa 100644
--- a/configs/am335x_evm_usbspl_defconfig
+++ b/configs/am335x_evm_usbspl_defconfig
@@ -4,6 +4,7 @@
 CONFIG_AM33XX=y
 # CONFIG_SPL_NAND_SUPPORT is not set
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="if test ${boot_fit} -eq 1; then run update_to_fit; fi; run findfdt; run init_console; run envboot; run distro_bootcmd"
 # CONFIG_ANDROID_BOOT_IMAGE is not set
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
diff --git a/configs/apalis-tk1_defconfig b/configs/apalis-tk1_defconfig
index a75a168..c1227a3 100644
--- a/configs/apalis-tk1_defconfig
+++ b/configs/apalis-tk1_defconfig
@@ -6,6 +6,7 @@
 CONFIG_FIT=y
 CONFIG_OF_SYSTEM_SETUP=y
 CONFIG_BOOTDELAY=1
+CONFIG_BOOTCOMMAND="run emmcboot; setenv fdtfile ${soc}-apalis-${fdt_board}.dtb && run distro_bootcmd"
 CONFIG_CONSOLE_MUX=y
 CONFIG_SYS_STDIO_DEREGISTER=y
 CONFIG_VERSION_VARIABLE=y
diff --git a/configs/clearfog_defconfig b/configs/clearfog_defconfig
index fa9f04a..5fa645a 100644
--- a/configs/clearfog_defconfig
+++ b/configs/clearfog_defconfig
@@ -43,5 +43,9 @@
 CONFIG_SYS_NS16550=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
-CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_MVEBU=y
 CONFIG_USB_STORAGE=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig
index a85aa74..4c04544 100644
--- a/configs/dragonboard410c_defconfig
+++ b/configs/dragonboard410c_defconfig
@@ -43,3 +43,5 @@
 CONFIG_USB_ETHER_MCS7830=y
 CONFIG_USB_ETHER_SMSC95XX=y
 CONFIG_OF_LIBFDT_OVERLAY=y
+CONFIG_OF_CONTROL=y
+CONFIG_ENV_IS_IN_MMC=y
diff --git a/configs/duovero_defconfig b/configs/duovero_defconfig
index b76da3e..f52cbe7 100644
--- a/configs/duovero_defconfig
+++ b/configs/duovero_defconfig
@@ -4,6 +4,7 @@
 CONFIG_TARGET_DUOVERO=y
 # CONFIG_SPL_NAND_SUPPORT is not set
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="if test ${boot_fit} -eq 1; then run update_to_fit; fi; run findfdt; run init_console; run envboot; run distro_bootcmd"
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
diff --git a/configs/evb-rv1108_defconfig b/configs/evb-rv1108_defconfig
index 239676b..a59d89e 100644
--- a/configs/evb-rv1108_defconfig
+++ b/configs/evb-rv1108_defconfig
@@ -4,6 +4,7 @@
 CONFIG_TARGET_EVB_RV1108=y
 CONFIG_DEFAULT_DEVICE_TREE="rv1108-evb"
 CONFIG_DEBUG_UART=y
+# CONFIG_USE_BOOTCOMMAND is not set
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_FASTBOOT_BUF_ADDR=0x62000000
 CONFIG_FASTBOOT_BUF_SIZE=0x08000000
diff --git a/configs/igep0032_defconfig b/configs/igep0032_defconfig
index 0521039..c295dea 100644
--- a/configs/igep0032_defconfig
+++ b/configs/igep0032_defconfig
@@ -2,6 +2,7 @@
 CONFIG_ARCH_OMAP2PLUS=y
 CONFIG_TARGET_OMAP3_IGEP00X0=y
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="run findfdt; run distro_bootcmd"
 CONFIG_OF_BOARD_SETUP=y
 CONFIG_BOOTDELAY=3
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
diff --git a/configs/igep00x0_defconfig b/configs/igep00x0_defconfig
index a2f29cc..479b183 100644
--- a/configs/igep00x0_defconfig
+++ b/configs/igep00x0_defconfig
@@ -2,6 +2,7 @@
 CONFIG_ARCH_OMAP2PLUS=y
 CONFIG_TARGET_OMAP3_IGEP00X0=y
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="run findfdt; run distro_bootcmd"
 CONFIG_OF_BOARD_SETUP=y
 CONFIG_BOOTDELAY=3
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
diff --git a/configs/ls1088aqds_qspi_defconfig b/configs/ls1088aqds_qspi_defconfig
index a870a06..850be3e 100644
--- a/configs/ls1088aqds_qspi_defconfig
+++ b/configs/ls1088aqds_qspi_defconfig
@@ -22,6 +22,7 @@
 CONFIG_DM=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_NETDEVICES=y
 CONFIG_E1000=y
 CONFIG_PCI=y
diff --git a/configs/ls1088aqds_sdcard_qspi_defconfig b/configs/ls1088aqds_sdcard_qspi_defconfig
new file mode 100644
index 0000000..214de54
--- /dev/null
+++ b/configs/ls1088aqds_sdcard_qspi_defconfig
@@ -0,0 +1,41 @@
+CONFIG_ARM=y
+CONFIG_TARGET_LS1088AQDS=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_FSL_LS_PPA=y
+CONFIG_SPL_MMC_SUPPORT=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_DEFAULT_DEVICE_TREE="fsl-ls1088a-qds"
+# CONFIG_SYS_MALLOC_F is not set
+CONFIG_FIT_VERBOSE=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_PARTITIONS=y
+CONFIG_SYS_EXTRA_OPTIONS="SD_BOOT_QSPI"
+CONFIG_SD_BOOT=y
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_SPL=y
+CONFIG_SPL_BUILD=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x8b0
+CONFIG_SPL_ENV_SUPPORT=y
+CONFIG_SPL_I2C_SUPPORT=y
+CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_OF_CONTROL=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_DM=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_NETDEVICES=y
+CONFIG_E1000=y
+CONFIG_SYS_NS16550=y
+CONFIG_DM_SPI=y
+CONFIG_FSL_DSPI=y
diff --git a/configs/ls1088ardb_qspi_defconfig b/configs/ls1088ardb_qspi_defconfig
index f2ab8e3..1f3d581 100644
--- a/configs/ls1088ardb_qspi_defconfig
+++ b/configs/ls1088ardb_qspi_defconfig
@@ -2,6 +2,7 @@
 CONFIG_TARGET_LS1088ARDB=y
 CONFIG_FSL_LS_PPA=y
 CONFIG_DEFAULT_DEVICE_TREE="fsl-ls1088a-rdb"
+CONFIG_DISTRO_DEFAULTS=y
 # CONFIG_SYS_MALLOC_F is not set
 CONFIG_FIT_VERBOSE=y
 CONFIG_OF_BOARD_SETUP=y
@@ -22,6 +23,7 @@
 CONFIG_DM=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_NETDEVICES=y
 CONFIG_E1000=y
 CONFIG_PCI=y
diff --git a/configs/ls1088ardb_sdcard_qspi_defconfig b/configs/ls1088ardb_sdcard_qspi_defconfig
new file mode 100644
index 0000000..8e5cf3b
--- /dev/null
+++ b/configs/ls1088ardb_sdcard_qspi_defconfig
@@ -0,0 +1,42 @@
+CONFIG_ARM=y
+CONFIG_TARGET_LS1088ARDB=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_FSL_LS_PPA=y
+CONFIG_SPL_MMC_SUPPORT=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_DEFAULT_DEVICE_TREE="fsl-ls1088a-rdb"
+CONFIG_DISTRO_DEFAULTS=y
+# CONFIG_SYS_MALLOC_F is not set
+CONFIG_FIT_VERBOSE=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_PARTITIONS=y
+CONFIG_SYS_EXTRA_OPTIONS="SD_BOOT_QSPI"
+CONFIG_SD_BOOT=y
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_SPL=y
+CONFIG_SPL_BUILD=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x8b0
+CONFIG_SPL_ENV_SUPPORT=y
+CONFIG_SPL_I2C_SUPPORT=y
+CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_OF_CONTROL=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_DM=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_NETDEVICES=y
+CONFIG_E1000=y
+CONFIG_SYS_NS16550=y
+CONFIG_DM_SPI=y
+CONFIG_FSL_DSPI=y
diff --git a/configs/ls2080a_emu_defconfig b/configs/ls2080a_emu_defconfig
index 516c8b9..80e3e89 100644
--- a/configs/ls2080a_emu_defconfig
+++ b/configs/ls2080a_emu_defconfig
@@ -9,6 +9,7 @@
 CONFIG_BOOTDELAY=10
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0 earlycon=uart8250,mmio,0x21c0500 ramdisk_size=0x2000000 default_hugepagesz=2m hugepagesz=2m hugepages=256"
+# CONFIG_USE_BOOTCOMMAND is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_XIMG is not set
diff --git a/configs/ls2080a_simu_defconfig b/configs/ls2080a_simu_defconfig
index 94ecdba..cdc80c2 100644
--- a/configs/ls2080a_simu_defconfig
+++ b/configs/ls2080a_simu_defconfig
@@ -9,6 +9,7 @@
 CONFIG_BOOTDELAY=10
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0 earlycon=uart8250,mmio,0x21c0500 ramdisk_size=0x2000000 default_hugepagesz=2m hugepagesz=2m hugepages=256"
+# CONFIG_USE_BOOTCOMMAND is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_XIMG is not set
diff --git a/configs/ls2080aqds_SECURE_BOOT_defconfig b/configs/ls2080aqds_SECURE_BOOT_defconfig
index 2937ba9..ee6043e 100644
--- a/configs/ls2080aqds_SECURE_BOOT_defconfig
+++ b/configs/ls2080aqds_SECURE_BOOT_defconfig
@@ -10,6 +10,7 @@
 CONFIG_BOOTDELAY=10
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0 earlycon=uart8250,mmio,0x21c0500 ramdisk_size=0x2000000 default_hugepagesz=2m hugepagesz=2m hugepages=256"
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_CMD_IMLS=y
 CONFIG_CMD_GREPENV=y
 CONFIG_CMD_EEPROM=y
diff --git a/configs/ls2080aqds_defconfig b/configs/ls2080aqds_defconfig
index 58eea7f..f8afa36 100644
--- a/configs/ls2080aqds_defconfig
+++ b/configs/ls2080aqds_defconfig
@@ -9,6 +9,7 @@
 CONFIG_BOOTDELAY=10
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0 earlycon=uart8250,mmio,0x21c0500 ramdisk_size=0x2000000 default_hugepagesz=2m hugepagesz=2m hugepages=256"
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_CMD_IMLS=y
 CONFIG_CMD_GREPENV=y
 CONFIG_CMD_EEPROM=y
diff --git a/configs/ls2080aqds_nand_defconfig b/configs/ls2080aqds_nand_defconfig
index e6f1e53..6d94671 100644
--- a/configs/ls2080aqds_nand_defconfig
+++ b/configs/ls2080aqds_nand_defconfig
@@ -14,6 +14,7 @@
 CONFIG_BOOTDELAY=10
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0 earlycon=uart8250,mmio,0x21c0500 ramdisk_size=0x2000000 default_hugepagesz=2m hugepagesz=2m hugepages=256"
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_SPL=y
 CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_I2C_SUPPORT=y
diff --git a/configs/ls2080aqds_qspi_defconfig b/configs/ls2080aqds_qspi_defconfig
index 79307f8..3fb47c5 100644
--- a/configs/ls2080aqds_qspi_defconfig
+++ b/configs/ls2080aqds_qspi_defconfig
@@ -10,6 +10,7 @@
 CONFIG_BOOTDELAY=10
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0 earlycon=uart8250,mmio,0x21c0500 ramdisk_size=0x2000000 default_hugepagesz=2m hugepagesz=2m hugepages=256"
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_CMD_GREPENV=y
 CONFIG_CMD_EEPROM=y
 CONFIG_CMD_GPT=y
diff --git a/configs/ls2080aqds_sdcard_defconfig b/configs/ls2080aqds_sdcard_defconfig
index 0e8b7d0..2ae7014 100644
--- a/configs/ls2080aqds_sdcard_defconfig
+++ b/configs/ls2080aqds_sdcard_defconfig
@@ -15,6 +15,7 @@
 CONFIG_BOOTDELAY=10
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0 earlycon=uart8250,mmio,0x21c0500 ramdisk_size=0x2000000 default_hugepagesz=2m hugepagesz=2m hugepages=256"
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_SPL=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x8b0
diff --git a/configs/ls2080ardb_SECURE_BOOT_defconfig b/configs/ls2080ardb_SECURE_BOOT_defconfig
index a8e4fdd..01fc9e6 100644
--- a/configs/ls2080ardb_SECURE_BOOT_defconfig
+++ b/configs/ls2080ardb_SECURE_BOOT_defconfig
@@ -10,6 +10,7 @@
 CONFIG_BOOTDELAY=10
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS1,115200 root=/dev/ram0 earlycon=uart8250,mmio,0x21c0600 ramdisk_size=0x2000000 default_hugepagesz=2m hugepagesz=2m hugepages=256"
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_CMD_IMLS=y
 CONFIG_CMD_GREPENV=y
 CONFIG_CMD_EEPROM=y
diff --git a/configs/ls2080ardb_defconfig b/configs/ls2080ardb_defconfig
index 0fd3fee..36d2313 100644
--- a/configs/ls2080ardb_defconfig
+++ b/configs/ls2080ardb_defconfig
@@ -9,6 +9,7 @@
 CONFIG_BOOTDELAY=10
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS1,115200 root=/dev/ram0 earlycon=uart8250,mmio,0x21c0600 ramdisk_size=0x2000000 default_hugepagesz=2m hugepagesz=2m hugepages=256"
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_CMD_IMLS=y
 CONFIG_CMD_GREPENV=y
 CONFIG_CMD_EEPROM=y
diff --git a/configs/ls2080ardb_nand_defconfig b/configs/ls2080ardb_nand_defconfig
index 0f248a7..0c24051 100644
--- a/configs/ls2080ardb_nand_defconfig
+++ b/configs/ls2080ardb_nand_defconfig
@@ -14,6 +14,7 @@
 CONFIG_BOOTDELAY=10
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS1,115200 root=/dev/ram0 earlycon=uart8250,mmio,0x21c0600 ramdisk_size=0x2000000 default_hugepagesz=2m hugepagesz=2m hugepages=256"
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_SPL=y
 CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_I2C_SUPPORT=y
diff --git a/configs/ls2081ardb_defconfig b/configs/ls2081ardb_defconfig
index 1848d3a..1ab8f18 100644
--- a/configs/ls2081ardb_defconfig
+++ b/configs/ls2081ardb_defconfig
@@ -11,6 +11,7 @@
 CONFIG_BOOTDELAY=10
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS1,115200 root=/dev/ram0 earlycon=uart8250,mmio,0x21c0600 ramdisk_size=0x2000000 default_hugepagesz=2m hugepagesz=2m hugepages=256"
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_CMD_GREPENV=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
diff --git a/configs/ls2088ardb_qspi_SECURE_BOOT_defconfig b/configs/ls2088ardb_qspi_SECURE_BOOT_defconfig
index eeb0d49..b53f575 100644
--- a/configs/ls2088ardb_qspi_SECURE_BOOT_defconfig
+++ b/configs/ls2088ardb_qspi_SECURE_BOOT_defconfig
@@ -10,6 +10,7 @@
 CONFIG_OF_STDOUT_VIA_ALIAS=y
 CONFIG_QSPI_BOOT=y
 CONFIG_BOOTDELAY=10
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_CMD_GREPENV=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
diff --git a/configs/ls2088ardb_qspi_defconfig b/configs/ls2088ardb_qspi_defconfig
index 115a793..277c7de 100644
--- a/configs/ls2088ardb_qspi_defconfig
+++ b/configs/ls2088ardb_qspi_defconfig
@@ -11,6 +11,7 @@
 CONFIG_BOOTDELAY=10
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS1,115200 root=/dev/ram0 earlycon=uart8250,mmio,0x21c0600 ramdisk_size=0x2000000 default_hugepagesz=2m hugepagesz=2m hugepages=256"
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_CMD_GREPENV=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
diff --git a/configs/lsxhl_defconfig b/configs/lsxhl_defconfig
index 5f2ac4f..d6ba4be 100644
--- a/configs/lsxhl_defconfig
+++ b/configs/lsxhl_defconfig
@@ -8,6 +8,7 @@
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/sda2"
+CONFIG_BOOTCOMMAND="run bootcmd_${bootsource}"
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 # CONFIG_DISPLAY_BOARDINFO is not set
diff --git a/configs/marsboard_defconfig b/configs/marsboard_defconfig
index e73d622..4037921 100644
--- a/configs/marsboard_defconfig
+++ b/configs/marsboard_defconfig
@@ -2,6 +2,7 @@
 CONFIG_ARCH_MX6=y
 CONFIG_TARGET_EMBESTMX6BOARDS=y
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="run finduuid; run distro_bootcmd"
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6q.cfg,MX6Q,DDR_MB=1024"
 # CONFIG_CONSOLE_MUX is not set
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
diff --git a/configs/mvebu_db_armada8k_defconfig b/configs/mvebu_db_armada8k_defconfig
index 9fa4d9f..cffb3d0 100644
--- a/configs/mvebu_db_armada8k_defconfig
+++ b/configs/mvebu_db_armada8k_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_TARGET_MVEBU_ARMADA_8K=y
 CONFIG_DEFAULT_DEVICE_TREE="armada-8040-db"
+CONFIG_DISTRO_DEFAULTS=y
 CONFIG_SMBIOS_PRODUCT_NAME=""
 CONFIG_DEBUG_UART=y
 CONFIG_AHCI=y
diff --git a/configs/mvebu_mcbin-88f8040_defconfig b/configs/mvebu_mcbin-88f8040_defconfig
index 9afe651..f779793 100644
--- a/configs/mvebu_mcbin-88f8040_defconfig
+++ b/configs/mvebu_mcbin-88f8040_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_TARGET_MVEBU_ARMADA_8K=y
 CONFIG_DEFAULT_DEVICE_TREE="armada-8040-mcbin"
+CONFIG_DISTRO_DEFAULTS=y
 CONFIG_SMBIOS_PRODUCT_NAME=""
 CONFIG_DEBUG_UART=y
 CONFIG_AHCI=y
diff --git a/configs/mx6cuboxi_defconfig b/configs/mx6cuboxi_defconfig
index 97a79e5..bd7917e 100644
--- a/configs/mx6cuboxi_defconfig
+++ b/configs/mx6cuboxi_defconfig
@@ -11,6 +11,7 @@
 # CONFIG_CMD_BMODE is not set
 CONFIG_CMD_HDMIDETECT=y
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="run findfdt; run finduuid; run distro_bootcmd"
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,MX6QDL"
 # CONFIG_SYS_STDIO_DEREGISTER is not set
 CONFIG_BOARD_EARLY_INIT_F=y
diff --git a/configs/novena_defconfig b/configs/novena_defconfig
index b6a03dc..3084fef 100644
--- a/configs/novena_defconfig
+++ b/configs/novena_defconfig
@@ -12,6 +12,7 @@
 CONFIG_SPL_FAT_SUPPORT=y
 CONFIG_CMD_HDMIDETECT=y
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="run distro_bootcmd ; run net_nfs"
 CONFIG_FIT=y
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,MX6Q"
 CONFIG_USE_BOOTARGS=y
diff --git a/configs/omap3_beagle_defconfig b/configs/omap3_beagle_defconfig
index 7dd623d..ad72079 100644
--- a/configs/omap3_beagle_defconfig
+++ b/configs/omap3_beagle_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x80100000
 CONFIG_TARGET_OMAP3_BEAGLE=y
 CONFIG_DISTRO_DEFAULTS=y
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
 CONFIG_SPL=y
diff --git a/configs/omap3_evm_defconfig b/configs/omap3_evm_defconfig
index 5103e9f..f67bcb1 100644
--- a/configs/omap3_evm_defconfig
+++ b/configs/omap3_evm_defconfig
@@ -6,6 +6,7 @@
 CONFIG_SYS_MPUCLK=720
 CONFIG_TARGET_OMAP3_EVM=y
 CONFIG_DISTRO_DEFAULTS=y
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_BOOTDELAY=3
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_DEFAULT_FDT_FILE="omap3-evm.dtb"
diff --git a/configs/omap3_pandora_defconfig b/configs/omap3_pandora_defconfig
index d937644..3e202b7 100644
--- a/configs/omap3_pandora_defconfig
+++ b/configs/omap3_pandora_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x80008000
 CONFIG_TARGET_OMAP3_PANDORA=y
 CONFIG_DISTRO_DEFAULTS=y
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
diff --git a/configs/omap4_panda_defconfig b/configs/omap4_panda_defconfig
index d208d0c..0faea77 100644
--- a/configs/omap4_panda_defconfig
+++ b/configs/omap4_panda_defconfig
@@ -4,6 +4,7 @@
 CONFIG_TARGET_OMAP4_PANDA=y
 # CONFIG_SPL_NAND_SUPPORT is not set
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="if test ${boot_fit} -eq 1; then run update_to_fit; fi; run findfdt; run init_console; run envboot; run distro_bootcmd"
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
diff --git a/configs/omap4_sdp4430_defconfig b/configs/omap4_sdp4430_defconfig
index c92b842..b7ba1f3 100644
--- a/configs/omap4_sdp4430_defconfig
+++ b/configs/omap4_sdp4430_defconfig
@@ -7,6 +7,7 @@
 CONFIG_CMD_BAT=y
 # CONFIG_SPL_NAND_SUPPORT is not set
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="if test ${boot_fit} -eq 1; then run update_to_fit; fi; run findfdt; run init_console; run envboot; run distro_bootcmd"
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
diff --git a/configs/p212_defconfig b/configs/p212_defconfig
new file mode 100644
index 0000000..d4b5349
--- /dev/null
+++ b/configs/p212_defconfig
@@ -0,0 +1,35 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MESON=y
+CONFIG_MESON_GXL=y
+CONFIG_TARGET_P212=y
+CONFIG_IDENT_STRING=" p212"
+CONFIG_DEFAULT_DEVICE_TREE="meson-gxl-s905x-p212"
+CONFIG_DEBUG_UART=y
+CONFIG_ENV_IS_NOWHERE=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_FPGA is not set
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_OF_CONTROL=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_MESON_GX=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_PHY_MESON_GXL=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_MESON_GXL=y
+CONFIG_DEBUG_UART_MESON=y
+CONFIG_DEBUG_UART_BASE=0xc81004c0
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_MESON_SERIAL=y
+CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/riotboard_defconfig b/configs/riotboard_defconfig
index 5855c60..da5e0fc 100644
--- a/configs/riotboard_defconfig
+++ b/configs/riotboard_defconfig
@@ -2,6 +2,7 @@
 CONFIG_ARCH_MX6=y
 CONFIG_TARGET_EMBESTMX6BOARDS=y
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="run finduuid; run distro_bootcmd"
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6s1g.cfg,MX6S,DDR_MB=1024"
 # CONFIG_CONSOLE_MUX is not set
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
diff --git a/configs/theadorable_debug_defconfig b/configs/theadorable_debug_defconfig
index 75d592e..863d6ce 100644
--- a/configs/theadorable_debug_defconfig
+++ b/configs/theadorable_debug_defconfig
@@ -26,7 +26,6 @@
 CONFIG_CMD_SF=y
 CONFIG_CMD_SPI=y
 CONFIG_CMD_USB=y
-# CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_TFTPPUT=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
diff --git a/configs/ti816x_evm_defconfig b/configs/ti816x_evm_defconfig
index be9c21f..b9bb57f 100644
--- a/configs/ti816x_evm_defconfig
+++ b/configs/ti816x_evm_defconfig
@@ -15,6 +15,7 @@
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyO2,115200n8 noinitrd earlyprintk"
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_BOARDINFO is not set
diff --git a/configs/udoo_neo_defconfig b/configs/udoo_neo_defconfig
index 2f75361..4134586 100644
--- a/configs/udoo_neo_defconfig
+++ b/configs/udoo_neo_defconfig
@@ -10,6 +10,7 @@
 CONFIG_SPL_WATCHDOG_SUPPORT=y
 # CONFIG_CMD_BMODE is not set
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="run findfdt; run distro_bootcmd"
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_SPL=y
diff --git a/configs/usbarmory_defconfig b/configs/usbarmory_defconfig
index cc276b7..99cfbd7 100644
--- a/configs/usbarmory_defconfig
+++ b/configs/usbarmory_defconfig
@@ -3,6 +3,7 @@
 CONFIG_TARGET_USBARMORY=y
 # CONFIG_CMD_BMODE is not set
 CONFIG_DISTRO_DEFAULTS=y
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_CMD_MEMTEST=y
 CONFIG_CMD_FUSE=y
 CONFIG_CMD_I2C=y
diff --git a/configs/vexpress_aemv8a_dram_defconfig b/configs/vexpress_aemv8a_dram_defconfig
index a767d99..115cb35 100644
--- a/configs/vexpress_aemv8a_dram_defconfig
+++ b/configs/vexpress_aemv8a_dram_defconfig
@@ -6,6 +6,7 @@
 CONFIG_BOOTDELAY=1
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyAMA0 earlyprintk=pl011,0x1c090000 debug user_debug=31 androidboot.hardware=fvpbase root=/dev/vda2 rw rootwait loglevel=9"
+# CONFIG_USE_BOOTCOMMAND is not set
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SYS_PROMPT="VExpress64# "
diff --git a/configs/vexpress_aemv8a_juno_defconfig b/configs/vexpress_aemv8a_juno_defconfig
index b48e749..06f7067 100644
--- a/configs/vexpress_aemv8a_juno_defconfig
+++ b/configs/vexpress_aemv8a_juno_defconfig
@@ -6,6 +6,7 @@
 CONFIG_BOOTDELAY=1
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyAMA0,115200n8 root=/dev/sda2 rw rootwait earlyprintk=pl011,0x7ff80000 debug user_debug=31 androidboot.hardware=juno loglevel=9"
+# CONFIG_USE_BOOTCOMMAND is not set
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SYS_PROMPT="VExpress64# "
diff --git a/configs/vexpress_aemv8a_semi_defconfig b/configs/vexpress_aemv8a_semi_defconfig
index 62602db..5bf0184 100644
--- a/configs/vexpress_aemv8a_semi_defconfig
+++ b/configs/vexpress_aemv8a_semi_defconfig
@@ -6,6 +6,7 @@
 CONFIG_BOOTDELAY=1
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyAMA0 earlyprintk=pl011,0x1c090000 debug user_debug=31 loglevel=9"
+# CONFIG_USE_BOOTCOMMAND is not set
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SYS_PROMPT="VExpress64# "
diff --git a/configs/vexpress_ca15_tc2_defconfig b/configs/vexpress_ca15_tc2_defconfig
index 9303f89..4a0fb5e 100644
--- a/configs/vexpress_ca15_tc2_defconfig
+++ b/configs/vexpress_ca15_tc2_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_TARGET_VEXPRESS_CA15_TC2=y
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="run distro_bootcmd; run bootflash"
 CONFIG_OF_BOARD_SETUP=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
diff --git a/configs/vexpress_ca5x2_defconfig b/configs/vexpress_ca5x2_defconfig
index 3f8bc9c..68d08a0 100644
--- a/configs/vexpress_ca5x2_defconfig
+++ b/configs/vexpress_ca5x2_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_TARGET_VEXPRESS_CA5X2=y
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="run distro_bootcmd; run bootflash"
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
 # CONFIG_CMD_CONSOLE is not set
diff --git a/configs/vexpress_ca9x4_defconfig b/configs/vexpress_ca9x4_defconfig
index 4cbc962..4f5eae3 100644
--- a/configs/vexpress_ca9x4_defconfig
+++ b/configs/vexpress_ca9x4_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_TARGET_VEXPRESS_CA9X4=y
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="run distro_bootcmd; run bootflash"
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
 # CONFIG_CMD_CONSOLE is not set
diff --git a/configs/wandboard_defconfig b/configs/wandboard_defconfig
index 23a6403..d053db7 100644
--- a/configs/wandboard_defconfig
+++ b/configs/wandboard_defconfig
@@ -10,6 +10,7 @@
 CONFIG_SPL_WATCHDOG_SUPPORT=y
 CONFIG_CMD_HDMIDETECT=y
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="run findfdt; run finduuid; run distro_bootcmd"
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,MX6QDL"
 # CONFIG_CONSOLE_MUX is not set
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
diff --git a/configs/zc5202_defconfig b/configs/zc5202_defconfig
index a0dc7fd..2cacf77 100644
--- a/configs/zc5202_defconfig
+++ b/configs/zc5202_defconfig
@@ -11,6 +11,7 @@
 CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_SPL_WATCHDOG_SUPPORT=y
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="run findfdt; run distro_bootcmd"
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,MX6Q"
 CONFIG_BOOTDELAY=3
 CONFIG_DEFAULT_FDT_FILE="imx6q-zc5202.dtb"
diff --git a/configs/zc5601_defconfig b/configs/zc5601_defconfig
index f8a5fde..17a7176 100644
--- a/configs/zc5601_defconfig
+++ b/configs/zc5601_defconfig
@@ -11,6 +11,7 @@
 CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_SPL_WATCHDOG_SUPPORT=y
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTCOMMAND="run findfdt; run distro_bootcmd"
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,MX6Q"
 CONFIG_BOOTDELAY=3
 CONFIG_DEFAULT_FDT_FILE="imx6q-zc5601.dtb"
diff --git a/doc/device-tree-bindings/config.txt b/doc/device-tree-bindings/config.txt
index fe0e04a..15e4349 100644
--- a/doc/device-tree-bindings/config.txt
+++ b/doc/device-tree-bindings/config.txt
@@ -21,6 +21,15 @@
 
 	This setting will override any values configured via Kconfig.
 
+u-boot,mmc-env-partition
+	if present, the environment shall be placed at the last
+	CONFIG_ENV_SIZE blocks of the partition on the
+	CONFIG_SYS_MMC_ENV_DEV.
+
+	if u-boot,mmc-env-offset* is present, this setting will take
+	precedence. In that case, only if the partition is not found,
+	mmc-env-offset* will be tried.
+
 u-boot,mmc-env-offset
 u-boot,mmc-env-offset-redundant
 	If present, the values of the 'u-boot,mmc-env-offset' and/or
diff --git a/drivers/clk/clk_stm32f7.c b/drivers/clk/clk_stm32f7.c
index a273f8f..f1a9e9c 100644
--- a/drivers/clk/clk_stm32f7.c
+++ b/drivers/clk/clk_stm32f7.c
@@ -136,13 +136,15 @@
 		| (sys_pll_psc.apb2_psc << RCC_CFGR_PPRE2_SHIFT)));
 
 	/* Configure the main PLL */
-	uint32_t pllcfgr = 0;
-	pllcfgr = RCC_PLLCFGR_PLLSRC; /* pll source HSE */
-	pllcfgr |= sys_pll_psc.pll_m << RCC_PLLCFGR_PLLM_SHIFT;
-	pllcfgr |= sys_pll_psc.pll_n << RCC_PLLCFGR_PLLN_SHIFT;
-	pllcfgr |= ((sys_pll_psc.pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT;
-	pllcfgr |= sys_pll_psc.pll_q << RCC_PLLCFGR_PLLQ_SHIFT;
-	writel(pllcfgr, &regs->pllcfgr);
+	setbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLSRC); /* pll source HSE */
+	clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLM_MASK,
+			sys_pll_psc.pll_m << RCC_PLLCFGR_PLLM_SHIFT);
+	clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLN_MASK,
+			sys_pll_psc.pll_n << RCC_PLLCFGR_PLLN_SHIFT);
+	clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLP_MASK,
+			((sys_pll_psc.pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT);
+	clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLQ_MASK,
+			sys_pll_psc.pll_q << RCC_PLLCFGR_PLLQ_SHIFT);
 
 	/* Enable the main PLL */
 	setbits_le32(&regs->cr, RCC_CR_PLLON);
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 94050836..62ce0af 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -33,6 +33,15 @@
 
 if MMC
 
+config ARM_PL180_MMCI
+	bool "ARM AMBA Multimedia Card Interface and compatible support"
+	depends on DM_MMC && OF_CONTROL
+	help
+	  This selects the ARM(R) AMBA(R) PrimeCell Multimedia Card
+	  Interface (PL180, PL181 and compatible) support.
+	  If you have an ARM(R) platform with a Multimedia Card slot,
+	  say Y or M here.
+
 config SPL_MMC_TINY
 	bool "Tiny MMC framework in SPL"
 	help
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c
index ddf8383..89a7c19 100644
--- a/drivers/mmc/arm_pl180_mmci.c
+++ b/drivers/mmc/arm_pl180_mmci.c
@@ -12,12 +12,29 @@
 
 /* #define DEBUG */
 
-#include <asm/io.h>
 #include "common.h"
+#include <clk.h>
 #include <errno.h>
+#include <malloc.h>
 #include <mmc.h>
+
+#include <asm/io.h>
+#include <asm-generic/gpio.h>
+
 #include "arm_pl180_mmci.h"
-#include <malloc.h>
+
+#ifdef CONFIG_DM_MMC
+#include <dm.h>
+DECLARE_GLOBAL_DATA_PTR;
+
+#define MMC_CLOCK_MAX	48000000
+#define MMC_CLOCK_MIN	400000
+
+struct arm_pl180_mmc_plat {
+	struct mmc_config cfg;
+	struct mmc mmc;
+};
+#endif
 
 static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd)
 {
@@ -265,16 +282,6 @@
 	return result;
 }
 
-/* MMC uses open drain drivers in the enumeration phase */
-static int mmc_host_reset(struct mmc *dev)
-{
-	struct pl180_mmc_host *host = dev->priv;
-
-	writel(host->pwr_init, &host->base->power);
-
-	return 0;
-}
-
 static int  host_set_ios(struct mmc *dev)
 {
 	struct pl180_mmc_host *host = dev->priv;
@@ -337,20 +344,31 @@
 	return 0;
 }
 
+#ifndef CONFIG_DM_MMC
+/* MMC uses open drain drivers in the enumeration phase */
+static int mmc_host_reset(struct mmc *dev)
+{
+	struct pl180_mmc_host *host = dev->priv;
+
+	writel(host->pwr_init, &host->base->power);
+
+	return 0;
+}
+
 static const struct mmc_ops arm_pl180_mmci_ops = {
 	.send_cmd = host_request,
 	.set_ios = host_set_ios,
 	.init = mmc_host_reset,
 };
+#endif
 
 /*
  * mmc_host_init - initialize the mmc controller.
  * Set initial clock and power for mmc slot.
  * Initialize mmc struct and register with mmc framework.
  */
-int arm_pl180_mmci_init(struct pl180_mmc_host *host)
+int arm_pl180_mmci_init(struct pl180_mmc_host *host, struct mmc **mmc)
 {
-	struct mmc *mmc;
 	u32 sdi_u32;
 
 	writel(host->pwr_init, &host->base->power);
@@ -362,7 +380,9 @@
 	writel(sdi_u32, &host->base->mask0);
 
 	host->cfg.name = host->name;
+#ifndef CONFIG_DM_MMC
 	host->cfg.ops = &arm_pl180_mmci_ops;
+#endif
 	/* TODO remove the duplicates */
 	host->cfg.host_caps = host->caps;
 	host->cfg.voltages = host->voltages;
@@ -373,11 +393,144 @@
 	else
 		host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
-	mmc = mmc_create(&host->cfg, host);
-	if (mmc == NULL)
+	*mmc = mmc_create(&host->cfg, host);
+	if (!*mmc)
 		return -1;
 
+	debug("registered mmc interface number is:%d\n",
+	      (*mmc)->block_dev.devnum);
+
+	return 0;
+}
+
+#ifdef CONFIG_DM_MMC
+static int arm_pl180_mmc_probe(struct udevice *dev)
+{
+	struct arm_pl180_mmc_plat *pdata = dev_get_platdata(dev);
+	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+	struct mmc *mmc = &pdata->mmc;
+	struct pl180_mmc_host *host = mmc->priv;
+	struct clk clk;
+	u32 bus_width;
+	int ret;
+
-	debug("registered mmc interface number is:%d\n", mmc->block_dev.devnum);
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_enable(&clk);
+	if (ret) {
+		dev_err(dev, "failed to enable clock\n");
+		return ret;
+	}
+
+	strcpy(host->name, "MMC");
+	host->pwr_init = INIT_PWR;
+	host->clkdiv_init = SDI_CLKCR_CLKDIV_INIT_V1 | SDI_CLKCR_CLKEN |
+			    SDI_CLKCR_HWFC_EN;
+	host->voltages = VOLTAGE_WINDOW_SD;
+	host->caps = 0;
+	host->clock_in = clk_get_rate(&clk);
+	host->clock_min = host->clock_in / (2 * (SDI_CLKCR_CLKDIV_INIT_V1 + 1));
+	host->clock_max = dev_read_u32_default(dev, "max-frequency",
+					       MMC_CLOCK_MAX);
+	host->version2 = dev_get_driver_data(dev);
+
+	gpio_request_by_name(dev, "cd-gpios", 0, &host->cd_gpio, GPIOD_IS_IN);
+
+	bus_width = dev_read_u32_default(dev, "bus-width", 1);
+	switch (bus_width) {
+	case 8:
+		host->caps |= MMC_MODE_8BIT;
+		/* Hosts capable of 8-bit transfers can also do 4 bits */
+	case 4:
+		host->caps |= MMC_MODE_4BIT;
+		break;
+	case 1:
+		break;
+	default:
+		dev_err(dev, "Invalid bus-width value %u\n", bus_width);
+	}
+
+	ret = arm_pl180_mmci_init(host, &mmc);
+	if (ret) {
+		dev_err(dev, "arm_pl180_mmci init failed\n");
+		return ret;
+	}
+
+	mmc->dev = dev;
+	dev->priv = host;
+	upriv->mmc = mmc;
+
+	return 0;
+}
+
+static int dm_host_request(struct udevice *dev, struct mmc_cmd *cmd,
+			   struct mmc_data *data)
+{
+	struct mmc *mmc = mmc_get_mmc_dev(dev);
+
+	return host_request(mmc, cmd, data);
+}
+
+static int dm_host_set_ios(struct udevice *dev)
+{
+	struct mmc *mmc = mmc_get_mmc_dev(dev);
+
+	return host_set_ios(mmc);
+}
+
+static int dm_mmc_getcd(struct udevice *dev)
+{
+	struct arm_pl180_mmc_plat *pdata = dev_get_platdata(dev);
+	struct mmc *mmc = &pdata->mmc;
+	struct pl180_mmc_host *host = mmc->priv;
+	int value = 1;
+
+	if (dm_gpio_is_valid(&host->cd_gpio)) {
+		value = dm_gpio_get_value(&host->cd_gpio);
+		if (host->cd_inverted)
+			return !value;
+	}
+
+	return value;
+}
+
+static const struct dm_mmc_ops arm_pl180_dm_mmc_ops = {
+	.send_cmd = dm_host_request,
+	.set_ios = dm_host_set_ios,
+	.get_cd = dm_mmc_getcd,
+};
+
+static int arm_pl180_mmc_ofdata_to_platdata(struct udevice *dev)
+{
+	struct arm_pl180_mmc_plat *pdata = dev_get_platdata(dev);
+	struct mmc *mmc = &pdata->mmc;
+	struct pl180_mmc_host *host = mmc->priv;
+	fdt_addr_t addr;
+
+	addr = devfdt_get_addr(dev);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	host->base = (void *)addr;
 
 	return 0;
 }
+
+static const struct udevice_id arm_pl180_mmc_match[] = {
+	{ .compatible = "st,stm32f4xx-sdio", .data = VERSION1 },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(arm_pl180_mmc) = {
+	.name = "arm_pl180_mmc",
+	.id = UCLASS_MMC,
+	.of_match = arm_pl180_mmc_match,
+	.ops = &arm_pl180_dm_mmc_ops,
+	.probe = arm_pl180_mmc_probe,
+	.ofdata_to_platdata = arm_pl180_mmc_ofdata_to_platdata,
+	.priv_auto_alloc_size = sizeof(struct pl180_mmc_host),
+	.platdata_auto_alloc_size = sizeof(struct arm_pl180_mmc_plat),
+};
+#endif
diff --git a/drivers/mmc/arm_pl180_mmci.h b/drivers/mmc/arm_pl180_mmci.h
index f23bd39..9df4b75 100644
--- a/drivers/mmc/arm_pl180_mmci.h
+++ b/drivers/mmc/arm_pl180_mmci.h
@@ -142,6 +142,9 @@
 
 #define SDI_FIFO_BURST_SIZE	8
 
+#define VERSION1	false
+#define VERSION2	true
+
 struct sdi_registers {
 	u32 power;		/* 0x00*/
 	u32 clock;		/* 0x04*/
@@ -188,8 +191,12 @@
 	unsigned int pwr_init;
 	int version2;
 	struct mmc_config cfg;
+#ifdef CONFIG_DM_MMC
+	struct gpio_desc cd_gpio;
+	bool cd_inverted;
+#endif
 };
 
-int arm_pl180_mmci_init(struct pl180_mmc_host *);
+int arm_pl180_mmci_init(struct pl180_mmc_host *host, struct mmc **mmc);
 
 #endif
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 794410a1..ca98193 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -55,6 +55,7 @@
 config NAND_OMAP_GPMC_PREFETCH
 	bool "Enable GPMC Prefetch"
 	depends on NAND_OMAP_GPMC
+	default y
 	help
 	  On OMAP platforms that use the GPMC controller
 	  (CONFIG_NAND_OMAP_GPMC_PREFETCH), this options enables the code that
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index bc6bdc9..a757a3b 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -48,7 +48,6 @@
 	/* device info */
 	struct fsl_ifc regs;
 	void __iomem *addr;      /* Address of assigned IFC buffer        */
-	unsigned int cs_nand;    /* On which chipsel NAND is connected	  */
 	unsigned int page;       /* Last page written to / read from      */
 	unsigned int read_bytes; /* Number of bytes read during command   */
 	unsigned int column;     /* Saved column from SEQIN               */
@@ -296,7 +295,7 @@
 	int i;
 
 	/* set the chip select for NAND Transaction */
-	ifc_out32(&ifc->ifc_nand.nand_csel, ifc_ctrl->cs_nand);
+	ifc_out32(&ifc->ifc_nand.nand_csel, priv->bank << IFC_NAND_CSEL_SHIFT);
 
 	/* start read/write seq */
 	ifc_out32(&ifc->ifc_nand.nandseq_strt,
@@ -798,7 +797,7 @@
 {
 }
 
-static int fsl_ifc_sram_init(uint32_t ver)
+static int fsl_ifc_sram_init(struct fsl_ifc_mtd *priv, uint32_t ver)
 {
 	struct fsl_ifc_runtime *ifc = ifc_ctrl->regs.rregs;
 	uint32_t cs = 0, csor = 0, csor_8k = 0, csor_ext = 0;
@@ -823,7 +822,7 @@
 		return 1;
 	}
 
-	cs = ifc_ctrl->cs_nand >> IFC_NAND_CSEL_SHIFT;
+	cs = priv->bank;
 
 	/* Save CSOR and CSOR_ext */
 	csor = ifc_in32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor);
@@ -850,7 +849,7 @@
 	ifc_out32(&ifc->ifc_nand.col0, 0x0);
 
 	/* set the chip select for NAND Transaction */
-	ifc_out32(&ifc->ifc_nand.nand_csel, ifc_ctrl->cs_nand);
+	ifc_out32(&ifc->ifc_nand.nand_csel, priv->bank << IFC_NAND_CSEL_SHIFT);
 
 	/* start read seq */
 	ifc_out32(&ifc->ifc_nand.nandseq_strt, IFC_NAND_SEQ_STRT_FIR_STRT);
@@ -911,10 +910,8 @@
 		csor = ifc_in32(&gregs->csor_cs[priv->bank].csor);
 
 		if ((cspr & CSPR_V) && (cspr & CSPR_MSEL) == CSPR_MSEL_NAND &&
-		    (cspr & CSPR_BA) == CSPR_PHYS_ADDR(phys_addr)) {
-			ifc_ctrl->cs_nand = priv->bank << IFC_NAND_CSEL_SHIFT;
+		    (cspr & CSPR_BA) == CSPR_PHYS_ADDR(phys_addr))
 			break;
-		}
 	}
 
 	if (priv->bank >= MAX_BANKS) {
@@ -1029,7 +1026,7 @@
 
 	ver = ifc_in32(&gregs->ifc_rev);
 	if (ver >= FSL_IFC_V1_1_0)
-		ret = fsl_ifc_sram_init(ver);
+		ret = fsl_ifc_sram_init(priv, ver);
 	if (ret)
 		return ret;
 
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index be2b611..c76f582 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -826,7 +826,7 @@
 
 	if (dram_block_size_env_var) {
 		dram_block_size = simple_strtoul(dram_block_size_env_var, NULL,
-						 10);
+						 16);
 
 		if (dram_block_size < CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE) {
 			printf("fsl-mc: WARNING: Invalid value for \'"
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c
index f235b62..21be79a 100644
--- a/drivers/net/ldpaa_eth/ldpaa_eth.c
+++ b/drivers/net/ldpaa_eth/ldpaa_eth.c
@@ -334,7 +334,7 @@
 					&buffer_start, 1);
 	} while (err == -EBUSY);
 
-	if (err < 0) {
+	if (err <= 0) {
 		printf("qbman_swp_acquire() failed\n");
 		return -ENOMEM;
 	}
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 4d02d8b..e32f1eb 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -55,6 +55,9 @@
 config PHY_MARVELL
 	bool "Marvell Ethernet PHYs support"
 
+config PHY_MESON_GXL
+	bool "Amlogic Meson GXL Internal PHY support"
+
 config PHY_MICREL
 	bool "Micrel Ethernet PHYs support"
 	help
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 54f32f6..1e264b2 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -21,6 +21,7 @@
 obj-$(CONFIG_PHY_MARVELL) += marvell.o
 obj-$(CONFIG_PHY_MICREL_KSZ8XXX) += micrel_ksz8xxx.o
 obj-$(CONFIG_PHY_MICREL_KSZ90X1) += micrel_ksz90x1.o
+obj-$(CONFIG_PHY_MESON_GXL) += meson-gxl.o
 obj-$(CONFIG_PHY_NATSEMI) += natsemi.o
 obj-$(CONFIG_PHY_REALTEK) += realtek.o
 obj-$(CONFIG_PHY_SMSC) += smsc.o
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
new file mode 100644
index 0000000..ccf70c9
--- /dev/null
+++ b/drivers/net/phy/meson-gxl.c
@@ -0,0 +1,57 @@
+/*
+ * Meson GXL Internal PHY Driver
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2016 BayLibre, SAS. All rights reserved.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <config.h>
+#include <common.h>
+#include <linux/bitops.h>
+#include <phy.h>
+
+static int meson_gxl_phy_config(struct phy_device *phydev)
+{
+	/* Enable Analog and DSP register Bank access by */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x14, 0x0000);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x14, 0x0400);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x14, 0x0000);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x14, 0x0400);
+
+	/* Write Analog register 23 */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x17, 0x8E0D);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x14, 0x4417);
+
+	/* Enable fractional PLL */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x17, 0x0005);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x14, 0x5C1B);
+
+	/* Program fraction FR_PLL_DIV1 */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x17, 0x029A);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x14, 0x5C1D);
+
+	/* Program fraction FR_PLL_DIV1 */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x17, 0xAAAA);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x14, 0x5C1C);
+
+	return genphy_config(phydev);
+}
+
+static struct phy_driver meson_gxl_phy_driver = {
+	.name = "Meson GXL Internal PHY",
+	.uid = 0x01814400,
+	.mask = 0xfffffff0,
+	.features = PHY_BASIC_FEATURES,
+	.config = &meson_gxl_phy_config,
+	.startup = &genphy_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+int phy_meson_gxl_init(void)
+{
+	phy_register(&meson_gxl_phy_driver);
+
+	return 0;
+}
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 5be51d7..fd3dd55 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -494,6 +494,9 @@
 #ifdef CONFIG_PHY_MICREL_KSZ90X1
 	phy_micrel_ksz90x1_init();
 #endif
+#ifdef CONFIG_PHY_MESON_GXL
+	phy_meson_gxl_init();
+#endif
 #ifdef CONFIG_PHY_NATSEMI
 	phy_natsemi_init();
 #endif
diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c
index ee9a854..c2bc326 100644
--- a/drivers/pci/pci_auto.c
+++ b/drivers/pci/pci_auto.c
@@ -181,8 +181,8 @@
 
 	/* Configure bus number registers */
 	dm_pci_write_config8(dev, PCI_PRIMARY_BUS,
-			     PCI_BUS(dm_pci_get_bdf(dev)));
-	dm_pci_write_config8(dev, PCI_SECONDARY_BUS, sub_bus);
+			     PCI_BUS(dm_pci_get_bdf(dev)) - ctlr->seq);
+	dm_pci_write_config8(dev, PCI_SECONDARY_BUS, sub_bus - ctlr->seq);
 	dm_pci_write_config8(dev, PCI_SUBORDINATE_BUS, 0xff);
 
 	if (pci_mem) {
@@ -257,7 +257,7 @@
 	pci_io = ctlr_hose->pci_io;
 
 	/* Configure bus number registers */
-	dm_pci_write_config8(dev, PCI_SUBORDINATE_BUS, sub_bus);
+	dm_pci_write_config8(dev, PCI_SUBORDINATE_BUS, sub_bus - ctlr->seq);
 
 	if (pci_mem) {
 		/* Round memory allocator to 1MB boundary */
diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c
index da0aa29..076a63f 100644
--- a/drivers/pci/pci_mvebu.c
+++ b/drivers/pci/pci_mvebu.c
@@ -82,11 +82,11 @@
 
 /*
  * MVEBU PCIe controller needs MEMORY and I/O BARs to be mapped
- * into SoCs address space. Each controller will map 32M of MEM
+ * into SoCs address space. Each controller will map 128M of MEM
  * and 64K of I/O space when registered.
  */
 static void __iomem *mvebu_pcie_membase = (void __iomem *)MBUS_PCI_MEM_BASE;
-#define PCIE_MEM_SIZE	(32 << 20)
+#define PCIE_MEM_SIZE	(128 << 20)
 
 #if defined(CONFIG_ARMADA_38X)
 #define PCIE_BASE(if)					\
diff --git a/drivers/pci/pcie_dw_mvebu.c b/drivers/pci/pcie_dw_mvebu.c
index 202cfe9..a198855 100644
--- a/drivers/pci/pcie_dw_mvebu.c
+++ b/drivers/pci/pcie_dw_mvebu.c
@@ -162,6 +162,7 @@
 		/* Accessing root port configuration space. */
 		va_address = (uintptr_t)pcie->ctrl_base;
 	} else {
+		d = PCI_MASK_BUS(d) | (PCI_BUS(d) - pcie->first_busno);
 		writel(d << 8, pcie->ctrl_base + PCIE_ATU_LOWER_TARGET);
 		va_address = (uintptr_t)pcie->cfg_base;
 	}
diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c
index 0cb7f6d..503fd5e 100644
--- a/drivers/pci/pcie_layerscape.c
+++ b/drivers/pci/pcie_layerscape.c
@@ -255,7 +255,7 @@
 		return 0;
 	}
 
-	busdev = PCIE_ATU_BUS(PCI_BUS(bdf)) |
+	busdev = PCIE_ATU_BUS(PCI_BUS(bdf) - bus->seq) |
 		 PCIE_ATU_DEV(PCI_DEV(bdf)) |
 		 PCIE_ATU_FUNC(PCI_FUNC(bdf));
 
diff --git a/drivers/pinctrl/meson/Kconfig b/drivers/pinctrl/meson/Kconfig
index c3e6901..27ba890 100644
--- a/drivers/pinctrl/meson/Kconfig
+++ b/drivers/pinctrl/meson/Kconfig
@@ -8,4 +8,8 @@
 	bool "Amlogic Meson GXBB SoC pinctrl driver"
 	select PINCTRL_MESON
 
+config PINCTRL_MESON_GXL
+	bool "Amlogic Meson GXL SoC pinctrl driver"
+	select PINCTRL_MESON
+
 endif
diff --git a/drivers/pinctrl/meson/Makefile b/drivers/pinctrl/meson/Makefile
index 6dde4bc..18921e3 100644
--- a/drivers/pinctrl/meson/Makefile
+++ b/drivers/pinctrl/meson/Makefile
@@ -4,3 +4,4 @@
 
 obj-y					+= pinctrl-meson.o
 obj-$(CONFIG_PINCTRL_MESON_GXBB)	+= pinctrl-meson-gxbb.o
+obj-$(CONFIG_PINCTRL_MESON_GXL)		+= pinctrl-meson-gxl.o
diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c
new file mode 100644
index 0000000..eebfaa9
--- /dev/null
+++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c
@@ -0,0 +1,736 @@
+/*
+ * (C) Copyright 2016 - Beniamino Galvani <b.galvani@gmail.com>
+ *
+ * Based on code from Linux kernel:
+ *   Copyright (C) 2016 Endless Mobile, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <dt-bindings/gpio/meson-gxl-gpio.h>
+
+#include "pinctrl-meson.h"
+
+#define EE_OFF	10
+
+static const unsigned int emmc_nand_d07_pins[] = {
+	PIN(BOOT_0, EE_OFF), PIN(BOOT_1, EE_OFF), PIN(BOOT_2, EE_OFF),
+	PIN(BOOT_3, EE_OFF), PIN(BOOT_4, EE_OFF), PIN(BOOT_5, EE_OFF),
+	PIN(BOOT_6, EE_OFF), PIN(BOOT_7, EE_OFF),
+};
+static const unsigned int emmc_clk_pins[] = { PIN(BOOT_8, EE_OFF) };
+static const unsigned int emmc_cmd_pins[] = { PIN(BOOT_10, EE_OFF) };
+static const unsigned int emmc_ds_pins[] = { PIN(BOOT_15, EE_OFF) };
+
+static const unsigned int nor_d_pins[]		= { PIN(BOOT_11, EE_OFF) };
+static const unsigned int nor_q_pins[]		= { PIN(BOOT_12, EE_OFF) };
+static const unsigned int nor_c_pins[]		= { PIN(BOOT_13, EE_OFF) };
+static const unsigned int nor_cs_pins[]		= { PIN(BOOT_15, EE_OFF) };
+
+static const unsigned int spi_mosi_pins[]	= { PIN(GPIOX_8, EE_OFF) };
+static const unsigned int spi_miso_pins[]	= { PIN(GPIOX_9, EE_OFF) };
+static const unsigned int spi_ss0_pins[]	= { PIN(GPIOX_10, EE_OFF) };
+static const unsigned int spi_sclk_pins[]	= { PIN(GPIOX_11, EE_OFF) };
+
+static const unsigned int sdcard_d0_pins[] = { PIN(CARD_1, EE_OFF) };
+static const unsigned int sdcard_d1_pins[] = { PIN(CARD_0, EE_OFF) };
+static const unsigned int sdcard_d2_pins[] = { PIN(CARD_5, EE_OFF) };
+static const unsigned int sdcard_d3_pins[] = { PIN(CARD_4, EE_OFF) };
+static const unsigned int sdcard_cmd_pins[] = { PIN(CARD_3, EE_OFF) };
+static const unsigned int sdcard_clk_pins[] = { PIN(CARD_2, EE_OFF) };
+
+static const unsigned int sdio_d0_pins[] = { PIN(GPIOX_0, EE_OFF) };
+static const unsigned int sdio_d1_pins[] = { PIN(GPIOX_1, EE_OFF) };
+static const unsigned int sdio_d2_pins[] = { PIN(GPIOX_2, EE_OFF) };
+static const unsigned int sdio_d3_pins[] = { PIN(GPIOX_3, EE_OFF) };
+static const unsigned int sdio_cmd_pins[] = { PIN(GPIOX_4, EE_OFF) };
+static const unsigned int sdio_clk_pins[] = { PIN(GPIOX_5, EE_OFF) };
+static const unsigned int sdio_irq_pins[] = { PIN(GPIOX_7, EE_OFF) };
+
+static const unsigned int nand_ce0_pins[]	= { PIN(BOOT_8, EE_OFF) };
+static const unsigned int nand_ce1_pins[]	= { PIN(BOOT_9, EE_OFF) };
+static const unsigned int nand_rb0_pins[]	= { PIN(BOOT_10, EE_OFF) };
+static const unsigned int nand_ale_pins[]	= { PIN(BOOT_11, EE_OFF) };
+static const unsigned int nand_cle_pins[]	= { PIN(BOOT_12, EE_OFF) };
+static const unsigned int nand_wen_clk_pins[]	= { PIN(BOOT_13, EE_OFF) };
+static const unsigned int nand_ren_wr_pins[]	= { PIN(BOOT_14, EE_OFF) };
+static const unsigned int nand_dqs_pins[]	= { PIN(BOOT_15, EE_OFF) };
+
+static const unsigned int uart_tx_a_pins[]	= { PIN(GPIOX_12, EE_OFF) };
+static const unsigned int uart_rx_a_pins[]	= { PIN(GPIOX_13, EE_OFF) };
+static const unsigned int uart_cts_a_pins[]	= { PIN(GPIOX_14, EE_OFF) };
+static const unsigned int uart_rts_a_pins[]	= { PIN(GPIOX_15, EE_OFF) };
+
+static const unsigned int uart_tx_b_pins[]	= { PIN(GPIODV_24, EE_OFF) };
+static const unsigned int uart_rx_b_pins[]	= { PIN(GPIODV_25, EE_OFF) };
+static const unsigned int uart_cts_b_pins[]	= { PIN(GPIODV_26, EE_OFF) };
+static const unsigned int uart_rts_b_pins[]	= { PIN(GPIODV_27, EE_OFF) };
+
+static const unsigned int uart_tx_c_pins[]	= { PIN(GPIOX_8, EE_OFF) };
+static const unsigned int uart_rx_c_pins[]	= { PIN(GPIOX_9, EE_OFF) };
+static const unsigned int uart_cts_c_pins[]	= { PIN(GPIOX_10, EE_OFF) };
+static const unsigned int uart_rts_c_pins[]	= { PIN(GPIOX_11, EE_OFF) };
+
+static const unsigned int i2c_sck_a_pins[]	= { PIN(GPIODV_25, EE_OFF) };
+static const unsigned int i2c_sda_a_pins[]	= { PIN(GPIODV_24, EE_OFF) };
+
+static const unsigned int i2c_sck_b_pins[]	= { PIN(GPIODV_27, EE_OFF) };
+static const unsigned int i2c_sda_b_pins[]	= { PIN(GPIODV_26, EE_OFF) };
+
+static const unsigned int i2c_sck_c_pins[]	= { PIN(GPIODV_29, EE_OFF) };
+static const unsigned int i2c_sda_c_pins[]	= { PIN(GPIODV_28, EE_OFF) };
+
+static const unsigned int i2c_sck_c_dv19_pins[]	= { PIN(GPIODV_19, EE_OFF) };
+static const unsigned int i2c_sda_c_dv18_pins[]	= { PIN(GPIODV_18, EE_OFF) };
+
+static const unsigned int eth_mdio_pins[]	= { PIN(GPIOZ_0, EE_OFF) };
+static const unsigned int eth_mdc_pins[]	= { PIN(GPIOZ_1, EE_OFF) };
+static const unsigned int eth_clk_rx_clk_pins[]	= { PIN(GPIOZ_2, EE_OFF) };
+static const unsigned int eth_rx_dv_pins[]	= { PIN(GPIOZ_3, EE_OFF) };
+static const unsigned int eth_rxd0_pins[]	= { PIN(GPIOZ_4, EE_OFF) };
+static const unsigned int eth_rxd1_pins[]	= { PIN(GPIOZ_5, EE_OFF) };
+static const unsigned int eth_rxd2_pins[]	= { PIN(GPIOZ_6, EE_OFF) };
+static const unsigned int eth_rxd3_pins[]	= { PIN(GPIOZ_7, EE_OFF) };
+static const unsigned int eth_rgmii_tx_clk_pins[] = { PIN(GPIOZ_8, EE_OFF) };
+static const unsigned int eth_tx_en_pins[]	= { PIN(GPIOZ_9, EE_OFF) };
+static const unsigned int eth_txd0_pins[]	= { PIN(GPIOZ_10, EE_OFF) };
+static const unsigned int eth_txd1_pins[]	= { PIN(GPIOZ_11, EE_OFF) };
+static const unsigned int eth_txd2_pins[]	= { PIN(GPIOZ_12, EE_OFF) };
+static const unsigned int eth_txd3_pins[]	= { PIN(GPIOZ_13, EE_OFF) };
+
+static const unsigned int pwm_a_pins[]		= { PIN(GPIOX_6, EE_OFF) };
+
+static const unsigned int pwm_b_pins[]		= { PIN(GPIODV_29, EE_OFF) };
+
+static const unsigned int pwm_c_pins[]		= { PIN(GPIOZ_15, EE_OFF) };
+
+static const unsigned int pwm_d_pins[]		= { PIN(GPIODV_28, EE_OFF) };
+
+static const unsigned int pwm_e_pins[]		= { PIN(GPIOX_16, EE_OFF) };
+
+static const unsigned int pwm_f_clk_pins[]	= { PIN(GPIOCLK_1, EE_OFF) };
+static const unsigned int pwm_f_x_pins[]	= { PIN(GPIOX_7, EE_OFF) };
+
+static const unsigned int hdmi_hpd_pins[]	= { PIN(GPIOH_0, EE_OFF) };
+static const unsigned int hdmi_sda_pins[]	= { PIN(GPIOH_1, EE_OFF) };
+static const unsigned int hdmi_scl_pins[]	= { PIN(GPIOH_2, EE_OFF) };
+
+static const unsigned int i2s_am_clk_pins[]	= { PIN(GPIOH_6, EE_OFF) };
+static const unsigned int i2s_out_ao_clk_pins[]	= { PIN(GPIOH_7, EE_OFF) };
+static const unsigned int i2s_out_lr_clk_pins[]	= { PIN(GPIOH_8, EE_OFF) };
+static const unsigned int i2s_out_ch01_pins[]	= { PIN(GPIOH_9, EE_OFF) };
+static const unsigned int i2s_out_ch23_z_pins[]	= { PIN(GPIOZ_5, EE_OFF) };
+static const unsigned int i2s_out_ch45_z_pins[]	= { PIN(GPIOZ_6, EE_OFF) };
+static const unsigned int i2s_out_ch67_z_pins[]	= { PIN(GPIOZ_7, EE_OFF) };
+
+static const unsigned int spdif_out_h_pins[]	= { PIN(GPIOH_4, EE_OFF) };
+
+static const unsigned int eth_link_led_pins[]	= { PIN(GPIOZ_14, EE_OFF) };
+static const unsigned int eth_act_led_pins[]	= { PIN(GPIOZ_15, EE_OFF) };
+
+static const unsigned int tsin_a_d0_pins[]	= { PIN(GPIODV_0, EE_OFF) };
+static const unsigned int tsin_a_d0_x_pins[]	= { PIN(GPIOX_10, EE_OFF) };
+static const unsigned int tsin_a_clk_pins[]	= { PIN(GPIODV_8, EE_OFF) };
+static const unsigned int tsin_a_clk_x_pins[]	= { PIN(GPIOX_11, EE_OFF) };
+static const unsigned int tsin_a_sop_pins[]	= { PIN(GPIODV_9, EE_OFF) };
+static const unsigned int tsin_a_sop_x_pins[]	= { PIN(GPIOX_8, EE_OFF) };
+static const unsigned int tsin_a_d_valid_pins[]	= { PIN(GPIODV_10, EE_OFF) };
+static const unsigned int tsin_a_d_valid_x_pins[] = { PIN(GPIOX_9, EE_OFF) };
+static const unsigned int tsin_a_fail_pins[]	= { PIN(GPIODV_11, EE_OFF) };
+static const unsigned int tsin_a_dp_pins[] = {
+	PIN(GPIODV_1, EE_OFF),
+	PIN(GPIODV_2, EE_OFF),
+	PIN(GPIODV_3, EE_OFF),
+	PIN(GPIODV_4, EE_OFF),
+	PIN(GPIODV_5, EE_OFF),
+	PIN(GPIODV_6, EE_OFF),
+	PIN(GPIODV_7, EE_OFF),
+};
+
+static const unsigned int uart_tx_ao_a_pins[]	= { PIN(GPIOAO_0, 0) };
+static const unsigned int uart_rx_ao_a_pins[]	= { PIN(GPIOAO_1, 0) };
+static const unsigned int uart_tx_ao_b_0_pins[]	= { PIN(GPIOAO_0, 0) };
+static const unsigned int uart_rx_ao_b_1_pins[]	= { PIN(GPIOAO_1, 0) };
+static const unsigned int uart_cts_ao_a_pins[]	= { PIN(GPIOAO_2, 0) };
+static const unsigned int uart_rts_ao_a_pins[]	= { PIN(GPIOAO_3, 0) };
+static const unsigned int uart_tx_ao_b_pins[]	= { PIN(GPIOAO_4, 0) };
+static const unsigned int uart_rx_ao_b_pins[]	= { PIN(GPIOAO_5, 0) };
+static const unsigned int uart_cts_ao_b_pins[]	= { PIN(GPIOAO_2, 0) };
+static const unsigned int uart_rts_ao_b_pins[]	= { PIN(GPIOAO_3, 0) };
+
+static const unsigned int i2c_sck_ao_pins[] = {PIN(GPIOAO_4, 0) };
+static const unsigned int i2c_sda_ao_pins[] = {PIN(GPIOAO_5, 0) };
+static const unsigned int i2c_slave_sck_ao_pins[] = {PIN(GPIOAO_4, 0) };
+static const unsigned int i2c_slave_sda_ao_pins[] = {PIN(GPIOAO_5, 0) };
+
+static const unsigned int remote_input_ao_pins[] = {PIN(GPIOAO_7, 0) };
+
+static const unsigned int pwm_ao_a_3_pins[]	= { PIN(GPIOAO_3, 0) };
+static const unsigned int pwm_ao_a_8_pins[]	= { PIN(GPIOAO_8, 0) };
+
+static const unsigned int pwm_ao_b_pins[]	= { PIN(GPIOAO_9, 0) };
+static const unsigned int pwm_ao_b_6_pins[]	= { PIN(GPIOAO_6, 0) };
+
+static const unsigned int i2s_out_ch23_ao_pins[] = { PIN(GPIOAO_8, 0) };
+static const unsigned int i2s_out_ch45_ao_pins[] = { PIN(GPIOAO_9, 0) };
+
+static const unsigned int spdif_out_ao_6_pins[]	= { PIN(GPIOAO_6, 0) };
+static const unsigned int spdif_out_ao_9_pins[]	= { PIN(GPIOAO_9, 0) };
+
+static const unsigned int ao_cec_pins[]		= { PIN(GPIOAO_8, 0) };
+static const unsigned int ee_cec_pins[]		= { PIN(GPIOAO_8, 0) };
+
+static struct meson_pmx_group meson_gxl_periphs_groups[] = {
+	GPIO_GROUP(GPIOZ_0, EE_OFF),
+	GPIO_GROUP(GPIOZ_1, EE_OFF),
+	GPIO_GROUP(GPIOZ_2, EE_OFF),
+	GPIO_GROUP(GPIOZ_3, EE_OFF),
+	GPIO_GROUP(GPIOZ_4, EE_OFF),
+	GPIO_GROUP(GPIOZ_5, EE_OFF),
+	GPIO_GROUP(GPIOZ_6, EE_OFF),
+	GPIO_GROUP(GPIOZ_7, EE_OFF),
+	GPIO_GROUP(GPIOZ_8, EE_OFF),
+	GPIO_GROUP(GPIOZ_9, EE_OFF),
+	GPIO_GROUP(GPIOZ_10, EE_OFF),
+	GPIO_GROUP(GPIOZ_11, EE_OFF),
+	GPIO_GROUP(GPIOZ_12, EE_OFF),
+	GPIO_GROUP(GPIOZ_13, EE_OFF),
+	GPIO_GROUP(GPIOZ_14, EE_OFF),
+	GPIO_GROUP(GPIOZ_15, EE_OFF),
+
+	GPIO_GROUP(GPIOH_0, EE_OFF),
+	GPIO_GROUP(GPIOH_1, EE_OFF),
+	GPIO_GROUP(GPIOH_2, EE_OFF),
+	GPIO_GROUP(GPIOH_3, EE_OFF),
+	GPIO_GROUP(GPIOH_4, EE_OFF),
+	GPIO_GROUP(GPIOH_5, EE_OFF),
+	GPIO_GROUP(GPIOH_6, EE_OFF),
+	GPIO_GROUP(GPIOH_7, EE_OFF),
+	GPIO_GROUP(GPIOH_8, EE_OFF),
+	GPIO_GROUP(GPIOH_9, EE_OFF),
+
+	GPIO_GROUP(BOOT_0, EE_OFF),
+	GPIO_GROUP(BOOT_1, EE_OFF),
+	GPIO_GROUP(BOOT_2, EE_OFF),
+	GPIO_GROUP(BOOT_3, EE_OFF),
+	GPIO_GROUP(BOOT_4, EE_OFF),
+	GPIO_GROUP(BOOT_5, EE_OFF),
+	GPIO_GROUP(BOOT_6, EE_OFF),
+	GPIO_GROUP(BOOT_7, EE_OFF),
+	GPIO_GROUP(BOOT_8, EE_OFF),
+	GPIO_GROUP(BOOT_9, EE_OFF),
+	GPIO_GROUP(BOOT_10, EE_OFF),
+	GPIO_GROUP(BOOT_11, EE_OFF),
+	GPIO_GROUP(BOOT_12, EE_OFF),
+	GPIO_GROUP(BOOT_13, EE_OFF),
+	GPIO_GROUP(BOOT_14, EE_OFF),
+	GPIO_GROUP(BOOT_15, EE_OFF),
+
+	GPIO_GROUP(CARD_0, EE_OFF),
+	GPIO_GROUP(CARD_1, EE_OFF),
+	GPIO_GROUP(CARD_2, EE_OFF),
+	GPIO_GROUP(CARD_3, EE_OFF),
+	GPIO_GROUP(CARD_4, EE_OFF),
+	GPIO_GROUP(CARD_5, EE_OFF),
+	GPIO_GROUP(CARD_6, EE_OFF),
+
+	GPIO_GROUP(GPIODV_0, EE_OFF),
+	GPIO_GROUP(GPIODV_1, EE_OFF),
+	GPIO_GROUP(GPIODV_2, EE_OFF),
+	GPIO_GROUP(GPIODV_3, EE_OFF),
+	GPIO_GROUP(GPIODV_4, EE_OFF),
+	GPIO_GROUP(GPIODV_5, EE_OFF),
+	GPIO_GROUP(GPIODV_6, EE_OFF),
+	GPIO_GROUP(GPIODV_7, EE_OFF),
+	GPIO_GROUP(GPIODV_8, EE_OFF),
+	GPIO_GROUP(GPIODV_9, EE_OFF),
+	GPIO_GROUP(GPIODV_10, EE_OFF),
+	GPIO_GROUP(GPIODV_11, EE_OFF),
+	GPIO_GROUP(GPIODV_12, EE_OFF),
+	GPIO_GROUP(GPIODV_13, EE_OFF),
+	GPIO_GROUP(GPIODV_14, EE_OFF),
+	GPIO_GROUP(GPIODV_15, EE_OFF),
+	GPIO_GROUP(GPIODV_16, EE_OFF),
+	GPIO_GROUP(GPIODV_17, EE_OFF),
+	GPIO_GROUP(GPIODV_19, EE_OFF),
+	GPIO_GROUP(GPIODV_20, EE_OFF),
+	GPIO_GROUP(GPIODV_21, EE_OFF),
+	GPIO_GROUP(GPIODV_22, EE_OFF),
+	GPIO_GROUP(GPIODV_23, EE_OFF),
+	GPIO_GROUP(GPIODV_24, EE_OFF),
+	GPIO_GROUP(GPIODV_25, EE_OFF),
+	GPIO_GROUP(GPIODV_26, EE_OFF),
+	GPIO_GROUP(GPIODV_27, EE_OFF),
+	GPIO_GROUP(GPIODV_28, EE_OFF),
+	GPIO_GROUP(GPIODV_29, EE_OFF),
+
+	GPIO_GROUP(GPIOX_0, EE_OFF),
+	GPIO_GROUP(GPIOX_1, EE_OFF),
+	GPIO_GROUP(GPIOX_2, EE_OFF),
+	GPIO_GROUP(GPIOX_3, EE_OFF),
+	GPIO_GROUP(GPIOX_4, EE_OFF),
+	GPIO_GROUP(GPIOX_5, EE_OFF),
+	GPIO_GROUP(GPIOX_6, EE_OFF),
+	GPIO_GROUP(GPIOX_7, EE_OFF),
+	GPIO_GROUP(GPIOX_8, EE_OFF),
+	GPIO_GROUP(GPIOX_9, EE_OFF),
+	GPIO_GROUP(GPIOX_10, EE_OFF),
+	GPIO_GROUP(GPIOX_11, EE_OFF),
+	GPIO_GROUP(GPIOX_12, EE_OFF),
+	GPIO_GROUP(GPIOX_13, EE_OFF),
+	GPIO_GROUP(GPIOX_14, EE_OFF),
+	GPIO_GROUP(GPIOX_15, EE_OFF),
+	GPIO_GROUP(GPIOX_16, EE_OFF),
+	GPIO_GROUP(GPIOX_17, EE_OFF),
+	GPIO_GROUP(GPIOX_18, EE_OFF),
+
+	GPIO_GROUP(GPIOCLK_0, EE_OFF),
+	GPIO_GROUP(GPIOCLK_1, EE_OFF),
+
+	GPIO_GROUP(GPIO_TEST_N, EE_OFF),
+
+	/* Bank X */
+	GROUP(sdio_d0,		5,	31),
+	GROUP(sdio_d1,		5,	30),
+	GROUP(sdio_d2,		5,	29),
+	GROUP(sdio_d3,		5,	28),
+	GROUP(sdio_clk,		5,	27),
+	GROUP(sdio_cmd,		5,	26),
+	GROUP(sdio_irq,		5,	24),
+	GROUP(uart_tx_a,	5,	19),
+	GROUP(uart_rx_a,	5,	18),
+	GROUP(uart_cts_a,	5,	17),
+	GROUP(uart_rts_a,	5,	16),
+	GROUP(uart_tx_c,	5,	13),
+	GROUP(uart_rx_c,	5,	12),
+	GROUP(uart_cts_c,	5,	11),
+	GROUP(uart_rts_c,	5,	10),
+	GROUP(pwm_a,		5,	25),
+	GROUP(pwm_e,		5,	15),
+	GROUP(pwm_f_x,		5,	14),
+	GROUP(spi_mosi,		5,	3),
+	GROUP(spi_miso,		5,	2),
+	GROUP(spi_ss0,		5,	1),
+	GROUP(spi_sclk,		5,	0),
+	GROUP(tsin_a_sop_x,	6,	3),
+	GROUP(tsin_a_d_valid_x,	6,	2),
+	GROUP(tsin_a_d0_x,	6,	1),
+	GROUP(tsin_a_clk_x,	6,	0),
+
+	/* Bank Z */
+	GROUP(eth_mdio,		4,	23),
+	GROUP(eth_mdc,		4,	22),
+	GROUP(eth_clk_rx_clk,	4,	21),
+	GROUP(eth_rx_dv,	4,	20),
+	GROUP(eth_rxd0,		4,	19),
+	GROUP(eth_rxd1,		4,	18),
+	GROUP(eth_rxd2,		4,	17),
+	GROUP(eth_rxd3,		4,	16),
+	GROUP(eth_rgmii_tx_clk,	4,	15),
+	GROUP(eth_tx_en,	4,	14),
+	GROUP(eth_txd0,		4,	13),
+	GROUP(eth_txd1,		4,	12),
+	GROUP(eth_txd2,		4,	11),
+	GROUP(eth_txd3,		4,	10),
+	GROUP(pwm_c,		3,	20),
+	GROUP(i2s_out_ch23_z,	3,	26),
+	GROUP(i2s_out_ch45_z,	3,	25),
+	GROUP(i2s_out_ch67_z,	3,	24),
+	GROUP(eth_link_led,	4,	25),
+	GROUP(eth_act_led,	4,	24),
+
+	/* Bank H */
+	GROUP(hdmi_hpd,		6,	31),
+	GROUP(hdmi_sda,		6,	30),
+	GROUP(hdmi_scl,		6,	29),
+	GROUP(i2s_am_clk,	6,	26),
+	GROUP(i2s_out_ao_clk,	6,	25),
+	GROUP(i2s_out_lr_clk,	6,	24),
+	GROUP(i2s_out_ch01,	6,	23),
+	GROUP(spdif_out_h,	6,	28),
+
+	/* Bank DV */
+	GROUP(uart_tx_b,	2,	16),
+	GROUP(uart_rx_b,	2,	15),
+	GROUP(uart_cts_b,	2,	14),
+	GROUP(uart_rts_b,	2,	13),
+	GROUP(i2c_sda_c_dv18,	1,	17),
+	GROUP(i2c_sck_c_dv19,	1,	16),
+	GROUP(i2c_sda_a,	1,	15),
+	GROUP(i2c_sck_a,	1,	14),
+	GROUP(i2c_sda_b,	1,	13),
+	GROUP(i2c_sck_b,	1,	12),
+	GROUP(i2c_sda_c,	1,	11),
+	GROUP(i2c_sck_c,	1,	10),
+	GROUP(pwm_b,		2,	11),
+	GROUP(pwm_d,		2,	12),
+	GROUP(tsin_a_d0,	2,	4),
+	GROUP(tsin_a_dp,	2,	3),
+	GROUP(tsin_a_clk,	2,	2),
+	GROUP(tsin_a_sop,	2,	1),
+	GROUP(tsin_a_d_valid,	2,	0),
+	GROUP(tsin_a_fail,	1,	31),
+
+	/* Bank BOOT */
+	GROUP(emmc_nand_d07,	7,	31),
+	GROUP(emmc_clk,		7,	30),
+	GROUP(emmc_cmd,		7,	29),
+	GROUP(emmc_ds,		7,	28),
+	GROUP(nor_d,		7,	13),
+	GROUP(nor_q,		7,	12),
+	GROUP(nor_c,		7,	11),
+	GROUP(nor_cs,		7,	10),
+	GROUP(nand_ce0,		7,	7),
+	GROUP(nand_ce1,		7,	6),
+	GROUP(nand_rb0,		7,	5),
+	GROUP(nand_ale,		7,	4),
+	GROUP(nand_cle,		7,	3),
+	GROUP(nand_wen_clk,	7,	2),
+	GROUP(nand_ren_wr,	7,	1),
+	GROUP(nand_dqs,		7,	0),
+
+	/* Bank CARD */
+	GROUP(sdcard_d1,	6,	5),
+	GROUP(sdcard_d0,	6,	4),
+	GROUP(sdcard_d3,	6,	1),
+	GROUP(sdcard_d2,	6,	0),
+	GROUP(sdcard_cmd,	6,	2),
+	GROUP(sdcard_clk,	6,	3),
+
+	/* Bank CLK */
+	GROUP(pwm_f_clk,	8,	30),
+};
+
+static struct meson_pmx_group meson_gxl_aobus_groups[] = {
+	GPIO_GROUP(GPIOAO_0, 0),
+	GPIO_GROUP(GPIOAO_1, 0),
+	GPIO_GROUP(GPIOAO_2, 0),
+	GPIO_GROUP(GPIOAO_3, 0),
+	GPIO_GROUP(GPIOAO_4, 0),
+	GPIO_GROUP(GPIOAO_5, 0),
+	GPIO_GROUP(GPIOAO_6, 0),
+	GPIO_GROUP(GPIOAO_7, 0),
+	GPIO_GROUP(GPIOAO_8, 0),
+	GPIO_GROUP(GPIOAO_9, 0),
+
+	/* bank AO */
+	GROUP(uart_tx_ao_b_0,	0,	26),
+	GROUP(uart_rx_ao_b_1,	0,	25),
+	GROUP(uart_tx_ao_b,	0,	24),
+	GROUP(uart_rx_ao_b,	0,	23),
+	GROUP(uart_tx_ao_a,	0,	12),
+	GROUP(uart_rx_ao_a,	0,	11),
+	GROUP(uart_cts_ao_a,	0,	10),
+	GROUP(uart_rts_ao_a,	0,	9),
+	GROUP(uart_cts_ao_b,	0,	8),
+	GROUP(uart_rts_ao_b,	0,	7),
+	GROUP(i2c_sck_ao,	0,	6),
+	GROUP(i2c_sda_ao,	0,	5),
+	GROUP(i2c_slave_sck_ao, 0,	2),
+	GROUP(i2c_slave_sda_ao, 0,	1),
+	GROUP(remote_input_ao,	0,	0),
+	GROUP(pwm_ao_a_3,	0,	22),
+	GROUP(pwm_ao_b_6,	0,	18),
+	GROUP(pwm_ao_a_8,	0,	17),
+	GROUP(pwm_ao_b,		0,	3),
+	GROUP(i2s_out_ch23_ao,	1,	0),
+	GROUP(i2s_out_ch45_ao,	1,	1),
+	GROUP(spdif_out_ao_6,	0,	16),
+	GROUP(spdif_out_ao_9,	0,	4),
+	GROUP(ao_cec,		0,	15),
+	GROUP(ee_cec,		0,	14),
+};
+
+static const char * const gpio_periphs_groups[] = {
+	"GPIOZ_0", "GPIOZ_1", "GPIOZ_2", "GPIOZ_3", "GPIOZ_4",
+	"GPIOZ_5", "GPIOZ_6", "GPIOZ_7", "GPIOZ_8", "GPIOZ_9",
+	"GPIOZ_10", "GPIOZ_11", "GPIOZ_12", "GPIOZ_13", "GPIOZ_14",
+	"GPIOZ_15",
+
+	"GPIOH_0", "GPIOH_1", "GPIOH_2", "GPIOH_3", "GPIOH_4",
+	"GPIOH_5", "GPIOH_6", "GPIOH_7", "GPIOH_8", "GPIOH_9",
+
+	"BOOT_0", "BOOT_1", "BOOT_2", "BOOT_3", "BOOT_4",
+	"BOOT_5", "BOOT_6", "BOOT_7", "BOOT_8", "BOOT_9",
+	"BOOT_10", "BOOT_11", "BOOT_12", "BOOT_13", "BOOT_14",
+	"BOOT_15",
+
+	"CARD_0", "CARD_1", "CARD_2", "CARD_3", "CARD_4",
+	"CARD_5", "CARD_6",
+
+	"GPIODV_0", "GPIODV_1", "GPIODV_2", "GPIODV_3", "GPIODV_4",
+	"GPIODV_5", "GPIODV_6", "GPIODV_7", "GPIODV_8", "GPIODV_9",
+	"GPIODV_10", "GPIODV_11", "GPIODV_12", "GPIODV_13", "GPIODV_14",
+	"GPIODV_15", "GPIODV_16", "GPIODV_17", "GPIODV_18", "GPIODV_19",
+	"GPIODV_20", "GPIODV_21", "GPIODV_22", "GPIODV_23", "GPIODV_24",
+	"GPIODV_25", "GPIODV_26", "GPIODV_27", "GPIODV_28", "GPIODV_29",
+
+	"GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", "GPIOX_4",
+	"GPIOX_5", "GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9",
+	"GPIOX_10", "GPIOX_11", "GPIOX_12", "GPIOX_13", "GPIOX_14",
+	"GPIOX_15", "GPIOX_16", "GPIOX_17", "GPIOX_18",
+
+	"GPIO_TEST_N",
+};
+
+static const char * const emmc_groups[] = {
+	"emmc_nand_d07", "emmc_clk", "emmc_cmd", "emmc_ds",
+};
+
+static const char * const nor_groups[] = {
+	"nor_d", "nor_q", "nor_c", "nor_cs",
+};
+
+static const char * const spi_groups[] = {
+	"spi_mosi", "spi_miso", "spi_ss0", "spi_sclk",
+};
+
+static const char * const sdcard_groups[] = {
+	"sdcard_d0", "sdcard_d1", "sdcard_d2", "sdcard_d3",
+	"sdcard_cmd", "sdcard_clk",
+};
+
+static const char * const sdio_groups[] = {
+	"sdio_d0", "sdio_d1", "sdio_d2", "sdio_d3",
+	"sdio_cmd", "sdio_clk", "sdio_irq",
+};
+
+static const char * const nand_groups[] = {
+	"nand_ce0", "nand_ce1", "nand_rb0", "nand_ale", "nand_cle",
+	"nand_wen_clk", "nand_ren_wr", "nand_dqs",
+};
+
+static const char * const uart_a_groups[] = {
+	"uart_tx_a", "uart_rx_a", "uart_cts_a", "uart_rts_a",
+};
+
+static const char * const uart_b_groups[] = {
+	"uart_tx_b", "uart_rx_b", "uart_cts_b", "uart_rts_b",
+};
+
+static const char * const uart_c_groups[] = {
+	"uart_tx_c", "uart_rx_c", "uart_cts_c", "uart_rts_c",
+};
+
+static const char * const i2c_a_groups[] = {
+	"i2c_sck_a", "i2c_sda_a",
+};
+
+static const char * const i2c_b_groups[] = {
+	"i2c_sck_b", "i2c_sda_b",
+};
+
+static const char * const i2c_c_groups[] = {
+	"i2c_sck_c", "i2c_sda_c", "i2c_sda_c_dv18", "i2c_sck_c_dv19",
+};
+
+static const char * const eth_groups[] = {
+	"eth_mdio", "eth_mdc", "eth_clk_rx_clk", "eth_rx_dv",
+	"eth_rxd0", "eth_rxd1", "eth_rxd2", "eth_rxd3",
+	"eth_rgmii_tx_clk", "eth_tx_en",
+	"eth_txd0", "eth_txd1", "eth_txd2", "eth_txd3",
+};
+
+static const char * const pwm_a_groups[] = {
+	"pwm_a",
+};
+
+static const char * const pwm_b_groups[] = {
+	"pwm_b",
+};
+
+static const char * const pwm_c_groups[] = {
+	"pwm_c",
+};
+
+static const char * const pwm_d_groups[] = {
+	"pwm_d",
+};
+
+static const char * const pwm_e_groups[] = {
+	"pwm_e",
+};
+
+static const char * const pwm_f_groups[] = {
+	"pwm_f_clk", "pwm_f_x",
+};
+
+static const char * const hdmi_hpd_groups[] = {
+	"hdmi_hpd",
+};
+
+static const char * const hdmi_i2c_groups[] = {
+	"hdmi_sda", "hdmi_scl",
+};
+
+static const char * const i2s_out_groups[] = {
+	"i2s_am_clk", "i2s_out_ao_clk", "i2s_out_lr_clk",
+	"i2s_out_ch01", "i2s_out_ch23_z", "i2s_out_ch45_z", "i2s_out_ch67_z",
+};
+
+static const char * const spdif_out_groups[] = {
+	"spdif_out_h",
+};
+
+static const char * const eth_led_groups[] = {
+	"eth_link_led", "eth_act_led",
+};
+
+static const char * const tsin_a_groups[] = {
+	"tsin_a_clk", "tsin_a_clk_x", "tsin_a_sop", "tsin_a_sop_x",
+	"tsin_a_d_valid", "tsin_a_d_valid_x", "tsin_a_d0", "tsin_a_d0_x",
+	"tsin_a_dp", "tsin_a_fail",
+};
+
+static const char * const gpio_aobus_groups[] = {
+	"GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
+	"GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
+};
+
+static const char * const uart_ao_groups[] = {
+	"uart_tx_ao_a", "uart_rx_ao_a", "uart_cts_ao_a", "uart_rts_ao_a",
+};
+
+static const char * const uart_ao_b_groups[] = {
+	"uart_tx_ao_b", "uart_rx_ao_b", "uart_cts_ao_b", "uart_rts_ao_b",
+	"uart_tx_ao_b_0", "uart_rx_ao_b_1",
+};
+
+static const char * const i2c_ao_groups[] = {
+	"i2c_sck_ao", "i2c_sda_ao",
+};
+
+static const char * const i2c_slave_ao_groups[] = {
+	"i2c_slave_sck_ao", "i2c_slave_sda_ao",
+};
+
+static const char * const remote_input_ao_groups[] = {
+	"remote_input_ao",
+};
+
+static const char * const pwm_ao_a_groups[] = {
+	"pwm_ao_a_3", "pwm_ao_a_8",
+};
+
+static const char * const pwm_ao_b_groups[] = {
+	"pwm_ao_b", "pwm_ao_b_6",
+};
+
+static const char * const i2s_out_ao_groups[] = {
+	"i2s_out_ch23_ao", "i2s_out_ch45_ao",
+};
+
+static const char * const spdif_out_ao_groups[] = {
+	"spdif_out_ao_6", "spdif_out_ao_9",
+};
+
+static const char * const cec_ao_groups[] = {
+	"ao_cec", "ee_cec",
+};
+
+static struct meson_pmx_func meson_gxl_periphs_functions[] = {
+	FUNCTION(gpio_periphs),
+	FUNCTION(emmc),
+	FUNCTION(nor),
+	FUNCTION(spi),
+	FUNCTION(sdcard),
+	FUNCTION(sdio),
+	FUNCTION(nand),
+	FUNCTION(uart_a),
+	FUNCTION(uart_b),
+	FUNCTION(uart_c),
+	FUNCTION(i2c_a),
+	FUNCTION(i2c_b),
+	FUNCTION(i2c_c),
+	FUNCTION(eth),
+	FUNCTION(pwm_a),
+	FUNCTION(pwm_b),
+	FUNCTION(pwm_c),
+	FUNCTION(pwm_d),
+	FUNCTION(pwm_e),
+	FUNCTION(pwm_f),
+	FUNCTION(hdmi_hpd),
+	FUNCTION(hdmi_i2c),
+	FUNCTION(i2s_out),
+	FUNCTION(spdif_out),
+	FUNCTION(eth_led),
+	FUNCTION(tsin_a),
+};
+
+static struct meson_pmx_func meson_gxl_aobus_functions[] = {
+	FUNCTION(gpio_aobus),
+	FUNCTION(uart_ao),
+	FUNCTION(uart_ao_b),
+	FUNCTION(i2c_ao),
+	FUNCTION(i2c_slave_ao),
+	FUNCTION(remote_input_ao),
+	FUNCTION(pwm_ao_a),
+	FUNCTION(pwm_ao_b),
+	FUNCTION(i2s_out_ao),
+	FUNCTION(spdif_out_ao),
+	FUNCTION(cec_ao),
+};
+
+static struct meson_bank meson_gxl_periphs_banks[] = {
+	/*   name    first                      last                    pullen  pull    dir     out     in  */
+	BANK("X",    PIN(GPIOX_0, EE_OFF),	PIN(GPIOX_18, EE_OFF),  4,  0,  4,  0,  12, 0,  13, 0,  14, 0),
+	BANK("DV",   PIN(GPIODV_0, EE_OFF),	PIN(GPIODV_29, EE_OFF), 0,  0,  0,  0,  0,  0,  1,  0,  2,  0),
+	BANK("H",    PIN(GPIOH_0, EE_OFF),	PIN(GPIOH_9, EE_OFF),   1, 20,  1, 20,  3, 20,  4, 20,  5, 20),
+	BANK("Z",    PIN(GPIOZ_0, EE_OFF),	PIN(GPIOZ_15, EE_OFF),  3,  0,  3,  0,  9,  0,  10, 0, 11,  0),
+	BANK("CARD", PIN(CARD_0, EE_OFF),	PIN(CARD_6, EE_OFF),    2, 20,  2, 20,  6, 20,  7, 20,  8, 20),
+	BANK("BOOT", PIN(BOOT_0, EE_OFF),	PIN(BOOT_15, EE_OFF),   2,  0,  2,  0,  6,  0,  7,  0,  8,  0),
+	BANK("CLK",  PIN(GPIOCLK_0, EE_OFF),	PIN(GPIOCLK_1, EE_OFF), 3, 28,  3, 28,  9, 28, 10, 28, 11, 28),
+};
+
+static struct meson_bank meson_gxl_aobus_banks[] = {
+	/*   name    first              last              pullen  pull    dir     out     in  */
+	BANK("AO",   PIN(GPIOAO_0, 0),  PIN(GPIOAO_9, 0), 0,  0,  0, 16,  0,  0,  0, 16,  1,  0),
+};
+
+struct meson_pinctrl_data meson_gxl_periphs_pinctrl_data = {
+	.name		= "periphs-banks",
+	.pin_base	= 10,
+	.groups		= meson_gxl_periphs_groups,
+	.funcs		= meson_gxl_periphs_functions,
+	.banks		= meson_gxl_periphs_banks,
+	.num_pins	= 101,
+	.num_groups	= ARRAY_SIZE(meson_gxl_periphs_groups),
+	.num_funcs	= ARRAY_SIZE(meson_gxl_periphs_functions),
+	.num_banks	= ARRAY_SIZE(meson_gxl_periphs_banks),
+};
+
+struct meson_pinctrl_data meson_gxl_aobus_pinctrl_data = {
+	.name		= "aobus-banks",
+	.pin_base	= 0,
+	.groups		= meson_gxl_aobus_groups,
+	.funcs		= meson_gxl_aobus_functions,
+	.banks		= meson_gxl_aobus_banks,
+	.num_pins	= 10,
+	.num_groups	= ARRAY_SIZE(meson_gxl_aobus_groups),
+	.num_funcs	= ARRAY_SIZE(meson_gxl_aobus_functions),
+	.num_banks	= ARRAY_SIZE(meson_gxl_aobus_banks),
+};
+
+static const struct udevice_id meson_gxl_pinctrl_match[] = {
+	{
+		.compatible = "amlogic,meson-gxl-periphs-pinctrl",
+		.data = (ulong)&meson_gxl_periphs_pinctrl_data,
+	},
+	{
+		.compatible = "amlogic,meson-gxl-aobus-pinctrl",
+		.data = (ulong)&meson_gxl_aobus_pinctrl_data,
+	},
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(meson_gxl_pinctrl) = {
+	.name = "meson-gxl-pinctrl",
+	.id = UCLASS_PINCTRL,
+	.of_match = of_match_ptr(meson_gxl_pinctrl_match),
+	.probe = meson_pinctrl_probe,
+	.priv_auto_alloc_size = sizeof(struct meson_pinctrl),
+	.ops = &meson_pinctrl_ops,
+};
diff --git a/drivers/serial/serial_nulldev.c b/drivers/serial/serial_nulldev.c
index 0768308..17b2310 100644
--- a/drivers/serial/serial_nulldev.c
+++ b/drivers/serial/serial_nulldev.c
@@ -18,6 +18,11 @@
 	return -EAGAIN;
 }
 
+static int nulldev_serial_pending(struct udevice *dev, bool input)
+{
+	return 0;
+}
+
 static int nulldev_serial_input(struct udevice *dev)
 {
 	return 0;
@@ -36,6 +41,7 @@
 
 const struct dm_serial_ops nulldev_serial_ops = {
 	.putc = nulldev_serial_putc,
+	.pending = nulldev_serial_pending,
 	.getc = nulldev_serial_getc,
 	.setbrg = nulldev_serial_setbrg,
 };
diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c
index b9201a5..dbdfce3 100644
--- a/drivers/usb/host/xhci-mvebu.c
+++ b/drivers/usb/host/xhci-mvebu.c
@@ -35,7 +35,7 @@
  * Dummy implementation that can be overwritten by a board
  * specific function
  */
-__weak int board_xhci_enable(void)
+__weak int board_xhci_enable(fdt_addr_t base)
 {
 	return 0;
 }
@@ -62,7 +62,7 @@
 	}
 
 	/* Enable USB xHCI (VBUS, reset etc) in board specific code */
-	board_xhci_enable();
+	board_xhci_enable(devfdt_get_addr_index(dev, 1));
 
 	return xhci_register(dev, ctx->hcd, hcor);
 }
@@ -85,6 +85,7 @@
 
 static const struct udevice_id xhci_usb_ids[] = {
 	{ .compatible = "marvell,armada3700-xhci" },
+	{ .compatible = "marvell,armada-380-xhci" },
 	{ .compatible = "marvell,armada-8k-xhci" },
 	{ }
 };
diff --git a/dts/Kconfig b/dts/Kconfig
index daa757d..0cef225 100644
--- a/dts/Kconfig
+++ b/dts/Kconfig
@@ -8,6 +8,17 @@
 config DTC
 	bool
 
+config PYLIBFDT
+	bool
+
+config DTOC
+	bool
+	select PYLIBFDT
+
+config BINMAN
+	bool
+	select DTOC
+
 menu "Device Tree Control"
 	depends on SUPPORT_OF_CONTROL
 
@@ -231,6 +242,7 @@
 config SPL_OF_PLATDATA
 	bool "Generate platform data for use in SPL"
 	depends on SPL_OF_CONTROL
+	select DTOC
 	help
 	  For very constrained SPL environments the overhead of decoding
 	  device tree nodes and converting their contents into platform data
@@ -252,6 +264,7 @@
 config TPL_OF_PLATDATA
 	bool "Generate platform data for use in TPL"
 	depends on TPL_OF_CONTROL
+	select DTOC
 	help
 	  For very constrained SPL environments the overhead of decoding
 	  device tree nodes and converting their contents into platform data
diff --git a/env/mmc.c b/env/mmc.c
index 3f3092d..3343f9e 100644
--- a/env/mmc.c
+++ b/env/mmc.c
@@ -15,9 +15,13 @@
 #include <malloc.h>
 #include <memalign.h>
 #include <mmc.h>
+#include <part.h>
 #include <search.h>
 #include <errno.h>
 
+#define __STR(X) #X
+#define STR(X) __STR(X)
+
 #if defined(CONFIG_ENV_SIZE_REDUND) &&  \
 	(CONFIG_ENV_SIZE_REDUND != CONFIG_ENV_SIZE)
 #error CONFIG_ENV_SIZE_REDUND should be the same as CONFIG_ENV_SIZE
@@ -30,18 +34,68 @@
 #endif
 
 #if CONFIG_IS_ENABLED(OF_CONTROL)
+static inline int mmc_offset_try_partition(const char *str, s64 *val)
+{
+	disk_partition_t info;
+	struct blk_desc *desc;
+	int len, i, ret;
+
+	ret = blk_get_device_by_str("mmc", STR(CONFIG_SYS_MMC_ENV_DEV), &desc);
+	if (ret < 0)
+		return (ret);
+
+	for (i = 1;;i++) {
+		ret = part_get_info(desc, i, &info);
+		if (ret < 0)
+			return ret;
+
+		if (!strncmp((const char *)info.name, str, sizeof(str)))
+			break;
+	}
+
+	/* round up to info.blksz */
+	len = (CONFIG_ENV_SIZE + info.blksz - 1) & ~(info.blksz - 1);
+
+	/* use the top of the partion for the environment */
+	*val = (info.start + info.size - 1) - len / info.blksz;
+
+	return 0;
+}
+
 static inline s64 mmc_offset(int copy)
 {
-	const char *propname = "u-boot,mmc-env-offset";
-	s64 defvalue = CONFIG_ENV_OFFSET;
+	const struct {
+		const char *offset_redund;
+		const char *partition;
+		const char *offset;
+	} dt_prop = {
+		.offset_redund = "u-boot,mmc-env-offset-redundant",
+		.partition = "u-boot,mmc-env-partition",
+		.offset = "u-boot,mmc-env-offset",
+	};
+	s64 val, defvalue;
+	const char *propname;
+	const char *str;
+	int err;
+
+	/* look for the partition in mmc CONFIG_SYS_MMC_ENV_DEV */
+	str = fdtdec_get_config_string(gd->fdt_blob, dt_prop.partition);
+	if (str) {
+		/* try to place the environment at end of the partition */
+		err = mmc_offset_try_partition(str, &val);
+		if (!err)
+			return val;
+	}
+
+	defvalue = CONFIG_ENV_OFFSET;
+	propname = dt_prop.offset;
 
 #if defined(CONFIG_ENV_OFFSET_REDUND)
 	if (copy) {
-		propname = "u-boot,mmc-env-offset-redundant";
 		defvalue = CONFIG_ENV_OFFSET_REDUND;
+		propname = dt_prop.offset_redund;
 	}
 #endif
-
 	return fdtdec_get_config_int(gd->fdt_blob, propname, defvalue);
 }
 #else
diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index 4823a7e..5ad0366 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -82,15 +82,6 @@
 	func(PXE, pxe, na) \
 	func(DHCP, dhcp, na)
 
-#define CONFIG_BOOTCOMMAND \
-	"if test ${boot_fit} -eq 1; then "	\
-		"run update_to_fit;"	\
-	"fi;"	\
-	"run findfdt; " \
-	"run init_console; " \
-	"run envboot; " \
-	"run distro_bootcmd"
-
 #include <config_distro_bootcmd.h>
 
 #ifndef CONFIG_SPL_BUILD
diff --git a/include/configs/apalis-tk1.h b/include/configs/apalis-tk1.h
index e6d119e..c13e446 100644
--- a/include/configs/apalis-tk1.h
+++ b/include/configs/apalis-tk1.h
@@ -54,10 +54,6 @@
 #undef CONFIG_SERVERIP
 #define CONFIG_SERVERIP		192.168.10.1
 
-#define CONFIG_BOOTCOMMAND \
-	"run emmcboot; setenv fdtfile ${soc}-apalis-${fdt_board}.dtb && " \
-		"run distro_bootcmd"
-
 #define DFU_ALT_EMMC_INFO	"apalis-tk1.img raw 0x0 0x500 mmcpart 1; " \
 				"boot part 0 1 mmcpart 0; " \
 				"rootfs part 0 2 mmcpart 0; " \
diff --git a/include/configs/clearfog.h b/include/configs/clearfog.h
index 5061f6c..bf87bac 100644
--- a/include/configs/clearfog.h
+++ b/include/configs/clearfog.h
@@ -33,9 +33,7 @@
 #define CONFIG_SYS_I2C_SPEED		100000
 
 /* SPI NOR flash default params, used by sf commands */
-#define CONFIG_SF_DEFAULT_SPEED		1000000
-#define CONFIG_SF_DEFAULT_MODE		SPI_MODE_3
-#define CONFIG_SPI_FLASH_STMICRO
+#define CONFIG_SF_DEFAULT_BUS		1
 
 /*
  * SDIO/MMC Card Configuration
diff --git a/include/configs/dragonboard410c.h b/include/configs/dragonboard410c.h
index 6b5d59d..d2447b2 100644
--- a/include/configs/dragonboard410c.h
+++ b/include/configs/dragonboard410c.h
@@ -100,6 +100,7 @@
 	BOOTENV
 
 #define CONFIG_ENV_SIZE			0x2000
+#define CONFIG_SYS_MMC_ENV_DEV		0	/* mmc0 = emmc, mmc1 = sd */
 #define CONFIG_ENV_VARS_UBOOT_CONFIG
 
 /* Size of malloc() pool */
diff --git a/include/configs/el6x_common.h b/include/configs/el6x_common.h
index 01d75d6..909981c 100644
--- a/include/configs/el6x_common.h
+++ b/include/configs/el6x_common.h
@@ -80,10 +80,6 @@
 	func(PXE, PXE, na) \
 	func(DHCP, dhcp, na)
 
-#define CONFIG_BOOTCOMMAND \
-	   "run findfdt; " \
-	   "run distro_bootcmd"
-
 #include <config_distro_bootcmd.h>
 
 #define CONFIG_ARP_TIMEOUT     200UL
diff --git a/include/configs/embestmx6boards.h b/include/configs/embestmx6boards.h
index 3f128e6..08a2922 100644
--- a/include/configs/embestmx6boards.h
+++ b/include/configs/embestmx6boards.h
@@ -132,10 +132,6 @@
 	func(PXE, pxe, na) \
 	func(DHCP, dhcp, na)
 
-#define CONFIG_BOOTCOMMAND \
-	"run finduuid; " \
-	"run distro_bootcmd"
-
 #include <config_distro_bootcmd.h>
 
 #define CONSOLE_STDIN_SETTINGS \
diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h
index 0f20e5e..5be61ad 100644
--- a/include/configs/ls1021atwr.h
+++ b/include/configs/ls1021atwr.h
@@ -375,6 +375,8 @@
 	"ramdisk_addr_r=0xa0000000\0"	\
 	"load_addr=0xa0000000\0"	\
 	"kernel_size=0x2800000\0"	\
+	"kernel_addr_sd=0x8000\0"	\
+	"kernel_size_sd=0x14000\0"	\
 	BOOTENV				\
 	"boot_scripts=ls1021atwr_boot.scr\0"	\
 	"boot_script_hdr=hdr_ls1021atwr_bs.out\0"	\
@@ -456,21 +458,25 @@
 			"${scripthdraddr} ${prefix}${boot_script_hdr} " \
 			"&& esbc_validate ${scripthdraddr};"    \
 		"source ${scriptaddr}\0"	  \
-	"installer=load mmc 0:2 $load_addr "	\
-		"/flex_installer_arm32.itb; "		\
-		"bootm $load_addr#ls1021atwr\0"	\
 	"qspi_bootcmd=echo Trying load from qspi..;"	\
 		"sf probe && sf read $load_addr "	\
 		"$kernel_addr $kernel_size && bootm $load_addr#$board\0"	\
 	"nor_bootcmd=echo Trying load from nor..;"	\
 		"cp.b $kernel_addr $load_addr "		\
-		"$kernel_size && bootm $load_addr#$board\0"
+		"$kernel_size && bootm $load_addr#$board\0" \
+	"sd_bootcmd=echo Trying load from SD ..;"       \
+		"mmcinfo && mmc read $load_addr "	\
+		"$kernel_addr_sd $kernel_size_sd && "	\
+		"bootm $load_addr#$board\0"
 #endif
 
 #undef CONFIG_BOOTCOMMAND
 #if defined(CONFIG_QSPI_BOOT) || defined(CONFIG_SD_BOOT_QSPI)
 #define CONFIG_BOOTCOMMAND "run distro_bootcmd; env exists secureboot"	\
 			   "&& esbc_halt; run qspi_bootcmd;"
+#elif defined(CONFIG_SD_BOOT)
+#define CONFIG_BOOTCOMMAND "run distro_bootcmd; env exists secureboot"  \
+			   "&& esbc_halt; run sd_bootcmd;"
 #else
 #define CONFIG_BOOTCOMMAND "run distro_bootcmd; env exists secureboot"	\
 			   "&& esbc_halt; run nor_bootcmd;"
diff --git a/include/configs/ls1043a_common.h b/include/configs/ls1043a_common.h
index 98fa711..a4cd09a 100644
--- a/include/configs/ls1043a_common.h
+++ b/include/configs/ls1043a_common.h
@@ -261,6 +261,8 @@
 	"fdt_addr_r=0x90000000\0"		\
 	"load_addr=0xa0000000\0"		\
 	"kernel_size=0x2800000\0"		\
+	"kernel_addr_sd=0x8000\0"		\
+	"kernel_size_sd=0x14000\0"		\
 	"console=ttyS0,115200\0"		\
 	"boot_os=y\0"				\
 	"mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0"	\
@@ -291,20 +293,25 @@
 			"${scripthdraddr} ${prefix}${boot_script_hdr} "	\
 			"&& esbc_validate ${scripthdraddr};"	\
 		"source ${scriptaddr}\0"			\
-	"installer=load mmc 0:2 $load_addr "	\
-		"/flex_installer_arm64.itb; "	\
-		"bootm $load_addr#ls1043ardb\0"	\
 	"qspi_bootcmd=echo Trying load from qspi..;"	\
 		"sf probe && sf read $load_addr "	\
 		"$kernel_addr $kernel_size && bootm $load_addr#$board\0" \
 	"nor_bootcmd=echo Trying load from nor..;"	\
 		"cp.b $kernel_addr $load_addr "	\
-		"$kernel_size && bootm $load_addr#$board\0"
+		"$kernel_size && bootm $load_addr#$board\0" \
+	"sd_bootcmd=echo Trying load from SD ..;"       \
+		"mmcinfo; mmc read $load_addr "         \
+		"$kernel_addr_sd $kernel_size_sd && "     \
+		"bootm $load_addr#$board\0"
+
 
 #undef CONFIG_BOOTCOMMAND
 #if defined(CONFIG_QSPI_BOOT) || defined(CONFIG_SD_BOOT_QSPI)
 #define CONFIG_BOOTCOMMAND "run distro_bootcmd; env exists secureboot"	\
 			   "&& esbc_halt; run qspi_bootcmd;"
+#elif defined(CONFIG_SD_BOOT)
+#define CONFIG_BOOTCOMMAND "run distro_bootcmd; env exists secureboot"  \
+			   "&& esbc_halt; run sd_bootcmd;"
 #else
 #define CONFIG_BOOTCOMMAND "run distro_bootcmd; env exists secureboot"	\
 			   "&& esbc_halt; run nor_bootcmd;"
diff --git a/include/configs/ls1046a_common.h b/include/configs/ls1046a_common.h
index eea54c7..11f2a28 100644
--- a/include/configs/ls1046a_common.h
+++ b/include/configs/ls1046a_common.h
@@ -227,6 +227,8 @@
 	"kernel_start=0x1000000\0"		\
 	"kernel_load=0xa0000000\0"		\
 	"kernel_size=0x2800000\0"		\
+	"kernel_addr_sd=0x8000\0"		\
+	"kernel_size_sd=0x14000\0"		\
 	"console=ttyS0,115200\0"                \
 	 CONFIG_MTDPARTS_DEFAULT "\0"		\
 	BOOTENV					\
@@ -257,12 +259,13 @@
 			"${scripthdraddr} ${prefix}${boot_script_hdr} " \
 			"&& esbc_validate ${scripthdraddr};"    \
 		"source ${scriptaddr}\0"	  \
-	"installer=load mmc 0:2 $load_addr "          \
-		"/flex_installer_arm64.itb; "          \
-		"bootm $load_addr#ls1046ardb\0"	 \
 	"qspi_bootcmd=echo Trying load from qspi..;"      \
 		"sf probe && sf read $load_addr "         \
-		"$kernel_start $kernel_size && bootm $load_addr#$board\0"
+		"$kernel_start $kernel_size && bootm $load_addr#$board\0" \
+	"sd_bootcmd=echo Trying load from SD ..;"	\
+		"mmcinfo; mmc read $load_addr "		\
+		"$kernel_addr_sd $kernel_size_sd && "	\
+		"bootm $load_addr#$board\0"
 
 #endif
 
diff --git a/include/configs/ls1046ardb.h b/include/configs/ls1046ardb.h
index 87d6c81..d001b80 100644
--- a/include/configs/ls1046ardb.h
+++ b/include/configs/ls1046ardb.h
@@ -225,8 +225,13 @@
 
 #ifndef SPL_NO_MISC
 #undef CONFIG_BOOTCOMMAND
+#if defined(CONFIG_QSPI_BOOT)
 #define CONFIG_BOOTCOMMAND "run distro_bootcmd; env exists secureboot"	\
 			   "&& esbc_halt; run qspi_bootcmd;"
+#elif defined(CONFIG_SD_BOOT)
+#define CONFIG_BOOTCOMMAND "run distro_bootcmd; env exists secureboot"	\
+			   "&& esbc_halt; run sd_bootcmd;"
+#endif
 #endif
 
 #include <asm/fsl_secure_boot.h>
diff --git a/include/configs/ls1088a_common.h b/include/configs/ls1088a_common.h
index fa058f7..6b71d47 100644
--- a/include/configs/ls1088a_common.h
+++ b/include/configs/ls1088a_common.h
@@ -20,18 +20,24 @@
 #define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_FSL_OCRAM_BASE + 0xfff0)
 
 /* Link Definitions */
+#ifdef CONFIG_SPL
+#define CONFIG_SYS_TEXT_BASE		0x80400000
+#else
 #ifdef CONFIG_QSPI_BOOT
 #define CONFIG_SYS_TEXT_BASE            0x20100000
 #else
 #define CONFIG_SYS_TEXT_BASE		0x30100000
 #endif
+#endif
 
 #define CONFIG_SUPPORT_RAW_INITRD
 
 
 #define CONFIG_SKIP_LOWLEVEL_INIT
 
+#if !defined(CONFIG_SD_BOOT)
 #define CONFIG_FSL_DDR_INTERACTIVE	/* Interactive debugging */
+#endif
 
 #define CONFIG_VERY_BIG_RAM
 #define CONFIG_SYS_DDR_SDRAM_BASE	0x80000000UL
@@ -148,6 +154,19 @@
 /* Miscellaneous configurable options */
 #define CONFIG_SYS_LOAD_ADDR	(CONFIG_SYS_DDR_SDRAM_BASE + 0x10000000)
 
+/* SATA */
+#ifdef CONFIG_SCSI
+#define CONFIG_LIBATA
+#define CONFIG_SCSI_AHCI
+#define CONFIG_SCSI_AHCI_PLAT
+#define CONFIG_SYS_SATA1		AHCI_BASE_ADDR1
+
+#define CONFIG_SYS_SCSI_MAX_SCSI_ID	1
+#define CONFIG_SYS_SCSI_MAX_LUN		1
+#define CONFIG_SYS_SCSI_MAX_DEVICE	(CONFIG_SYS_SCSI_MAX_SCSI_ID * \
+					CONFIG_SYS_SCSI_MAX_LUN)
+#endif
+
 /* Physical Memory Map */
 #define CONFIG_CHIP_SELECTS_PER_CTRL	4
 
@@ -187,6 +206,11 @@
 				" fsl_mc apply dpl 0x80200000 &&" \
 				" sf read $kernel_load $kernel_start" \
 				" $kernel_size && bootm $kernel_load"
+#elif defined(CONFIG_SD_BOOT)
+#define CONFIG_BOOTCOMMAND	"mmcinfo;mmc read 0x80200000 0x6800 0x800;"\
+				" fsl_mc apply dpl 0x80200000 &&" \
+				" mmc read $kernel_load $kernel_start" \
+				" $kernel_size && bootm $kernel_load"
 #else /* NOR BOOT*/
 #define CONFIG_BOOTCOMMAND	"fsl_mc apply dpl 0x580d00000 &&" \
 				" cp.b $kernel_start $kernel_load" \
@@ -206,6 +230,20 @@
 
 #define CONFIG_PANIC_HANG	/* do not reset board on panic */
 
+#ifdef CONFIG_SPL
+#define CONFIG_SPL_BSS_START_ADDR      0x80100000
+#define CONFIG_SPL_BSS_MAX_SIZE                0x00100000
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv8/u-boot-spl.lds"
+#define CONFIG_SPL_MAX_SIZE            0x16000
+#define CONFIG_SPL_STACK               (CONFIG_SYS_FSL_OCRAM_BASE + 0x9ff0)
+#define CONFIG_SPL_TARGET              "u-boot-with-spl.bin"
+#define CONFIG_SPL_TEXT_BASE           0x1800a000
+
+#define CONFIG_SYS_SPL_MALLOC_SIZE     0x00100000
+#define CONFIG_SYS_SPL_MALLOC_START    0x80200000
+#define CONFIG_SYS_MONITOR_LEN         (512 * 1024)
+#endif
 #define CONFIG_SYS_BOOTM_LEN   (64 << 20)      /* Increase max gunzip size */
 
 #endif /* __LS1088_COMMON_H */
diff --git a/include/configs/ls1088aqds.h b/include/configs/ls1088aqds.h
index c2e6fd2..310e8fd 100644
--- a/include/configs/ls1088aqds.h
+++ b/include/configs/ls1088aqds.h
@@ -23,6 +23,10 @@
 #define CONFIG_ENV_SIZE			0x2000          /* 8KB */
 #define CONFIG_ENV_OFFSET		0x300000        /* 3MB */
 #define CONFIG_ENV_SECT_SIZE		0x40000
+#elif defined(CONFIG_SD_BOOT)
+#define CONFIG_ENV_OFFSET		(3 * 1024 * 1024)
+#define CONFIG_SYS_MMC_ENV_DEV		0
+#define CONFIG_ENV_SIZE			0x2000
 #else
 #define CONFIG_ENV_IS_IN_FLASH
 #define CONFIG_ENV_ADDR			(CONFIG_SYS_FLASH_BASE + 0x300000)
@@ -30,10 +34,11 @@
 #define CONFIG_ENV_SIZE			0x20000
 #endif
 
-#if defined(CONFIG_QSPI_BOOT)
+#if defined(CONFIG_QSPI_BOOT) || defined(CONFIG_SD_BOOT_QSPI)
 #define CONFIG_QIXIS_I2C_ACCESS
 #define SYS_NO_FLASH
 
+#undef CONFIG_CMD_IMLS
 #define CONFIG_SYS_CLK_FREQ		100000000
 #define CONFIG_DDR_CLK_FREQ		100000000
 #else
@@ -190,7 +195,7 @@
 					| CSPR_V)
 
 #define CONFIG_SYS_FPGA_AMASK		IFC_AMASK(64*1024)
-#if defined(CONFIG_QSPI_BOOT)
+#if defined(CONFIG_QSPI_BOOT) || defined(CONFIG_SD_BOOT_QSPI)
 #define CONFIG_SYS_FPGA_CSOR		CSOR_GPCM_ADM_SHIFT(0)
 #else
 #define CONFIG_SYS_FPGA_CSOR		CSOR_GPCM_ADM_SHIFT(12)
@@ -293,9 +298,8 @@
 #define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS	5
 
 /* QSPI device */
-#if defined(CONFIG_QSPI_BOOT)
+#if defined(CONFIG_QSPI_BOOT) || defined(CONFIG_SD_BOOT_QSPI)
 #define CONFIG_FSL_QSPI
-#define CONFIG_SPI_FLASH_SPANSION
 #define FSL_QSPI_FLASH_SIZE		(1 << 26)
 #define FSL_QSPI_FLASH_NUM		2
 
@@ -316,7 +320,11 @@
 #define CONFIG_SYS_MEMTEST_START	0x80000000
 #define CONFIG_SYS_MEMTEST_END		0x9fffffff
 
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SYS_MONITOR_BASE CONFIG_SPL_TEXT_BASE
+#else
 #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
+#endif
 
 #define CONFIG_FSL_MEMAC
 
@@ -344,6 +352,23 @@
 	"sf read 0x80100000 0xE00000 0x100000;" \
 	"fsl_mc start mc 0x80000000 0x80100000\0"	\
 	"mcmemsize=0x70000000 \0"
+#elif defined(CONFIG_SD_BOOT)
+#undef CONFIG_EXTRA_ENV_SETTINGS
+#define CONFIG_EXTRA_ENV_SETTINGS               \
+	"hwconfig=fsl_ddr:bank_intlv=auto\0"    \
+	"loadaddr=0x90100000\0"                 \
+	"kernel_addr=0x800\0"                \
+	"ramdisk_addr=0x800000\0"               \
+	"ramdisk_size=0x2000000\0"              \
+	"fdt_high=0xa0000000\0"                 \
+	"initrd_high=0xffffffffffffffff\0"      \
+	"kernel_start=0x8000\0"              \
+	"kernel_load=0xa0000000\0"              \
+	"kernel_size=0x14000\0"               \
+	"mcinitcmd=mmcinfo;mmc read 0x80000000 0x5000 0x800;"  \
+	"mmc read 0x80100000 0x7000 0x800;" \
+	"fsl_mc start mc 0x80000000 0x80100000\0"       \
+	"mcmemsize=0x70000000 \0"
 #else	/* NOR BOOT */
 #undef CONFIG_EXTRA_ENV_SETTINGS
 #define CONFIG_EXTRA_ENV_SETTINGS		\
diff --git a/include/configs/ls1088ardb.h b/include/configs/ls1088ardb.h
index 478ddd0..e6bf2b8 100644
--- a/include/configs/ls1088ardb.h
+++ b/include/configs/ls1088ardb.h
@@ -15,6 +15,10 @@
 #define CONFIG_ENV_SIZE			0x2000          /* 8KB */
 #define CONFIG_ENV_OFFSET		0x300000        /* 3MB */
 #define CONFIG_ENV_SECT_SIZE		0x40000
+#elif defined(CONFIG_SD_BOOT)
+#define CONFIG_ENV_OFFSET		(3 * 1024 * 1024)
+#define CONFIG_SYS_MMC_ENV_DEV		0
+#define CONFIG_ENV_SIZE			0x2000
 #else
 #define CONFIG_ENV_IS_IN_FLASH
 #define CONFIG_ENV_ADDR			(CONFIG_SYS_FLASH_BASE + 0x300000)
@@ -22,9 +26,10 @@
 #define CONFIG_ENV_SIZE			0x20000
 #endif
 
-#if defined(CONFIG_QSPI_BOOT)
+#if defined(CONFIG_QSPI_BOOT) || defined(CONFIG_SD_BOOT_QSPI)
 #define CONFIG_QIXIS_I2C_ACCESS
 #define SYS_NO_FLASH
+#undef CONFIG_CMD_IMLS
 #endif
 
 #define CONFIG_SYS_CLK_FREQ		100000000
@@ -232,9 +237,8 @@
 #define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS	5
 
 /* QSPI device */
-#if defined(CONFIG_QSPI_BOOT)
+#if defined(CONFIG_QSPI_BOOT) || defined(CONFIG_SD_BOOT_QSPI)
 #define CONFIG_FSL_QSPI
-#define CONFIG_SPI_FLASH_SPANSION
 #define FSL_QSPI_FLASH_SIZE		(1 << 26)
 #define FSL_QSPI_FLASH_NUM		2
 #endif
@@ -244,29 +248,112 @@
 #define CONFIG_SYS_MEMTEST_START	0x80000000
 #define CONFIG_SYS_MEMTEST_END		0x9fffffff
 
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SYS_MONITOR_BASE CONFIG_SPL_TEXT_BASE
+#else
 #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
+#endif
 
 #define CONFIG_FSL_MEMAC
 
 /* Initial environment variables */
 #if defined(CONFIG_QSPI_BOOT)
+#define MC_INIT_CMD				\
+	"mcinitcmd=sf probe 0:0;sf read 0x80000000 0xA00000 0x100000;"	\
+	"sf read 0x80100000 0xE00000 0x100000;"				\
+	"fsl_mc start mc 0x80000000 0x80100000\0"			\
+	"mcmemsize=0x70000000\0"
+#elif defined(CONFIG_SD_BOOT)
+#define MC_INIT_CMD				\
+	"mcinitcmd=mmcinfo;mmc read 0x80000000 0x5000 0x800;"		\
+	"mmc read 0x80100000 0x7000 0x800;"				\
+	"fsl_mc start mc 0x80000000 0x80100000\0"			\
+	"mcmemsize=0x70000000\0"
+#endif
+
 #undef CONFIG_EXTRA_ENV_SETTINGS
 #define CONFIG_EXTRA_ENV_SETTINGS		\
+	"BOARD=ls1088ardb\0"			\
 	"hwconfig=fsl_ddr:bank_intlv=auto\0"	\
-	"loadaddr=0x90100000\0"			\
-	"kernel_addr=0x100000\0"		\
 	"ramdisk_addr=0x800000\0"		\
 	"ramdisk_size=0x2000000\0"		\
 	"fdt_high=0xa0000000\0"			\
 	"initrd_high=0xffffffffffffffff\0"	\
-	"kernel_start=0x1000000\0"		\
-	"kernel_load=0xa0000000\0"		\
+	"fdt_addr=0x64f00000\0"			\
+	"kernel_addr=0x1000000\0"		\
+	"kernel_addr_sd=0x8000\0"		\
+	"kernel_start=0x580100000\0"		\
+	"kernelheader_start=0x580800000\0"	\
+	"scriptaddr=0x80000000\0"		\
+	"scripthdraddr=0x80080000\0"		\
+	"fdtheader_addr_r=0x80100000\0"		\
+	"kernelheader_addr=0x800000\0"		\
+	"kernelheader_addr_r=0x80200000\0"	\
+	"kernel_addr_r=0x81000000\0"		\
+	"kernelheader_size=0x40000\0"		\
+	"fdt_addr_r=0x90000000\0"		\
+	"load_addr=0xa0000000\0"		\
 	"kernel_size=0x2800000\0"		\
-	"mcinitcmd=sf probe 0:0;sf read 0x80000000 0xA00000 0x100000;"	\
-	"sf read 0x80100000 0xE00000 0x100000;" \
-	"fsl_mc start mc 0x80000000 0x80100000\0"	\
-	"mcmemsize=0x70000000 \0"
+	"kernel_size_sd=0x14000\0"		\
+	MC_INIT_CMD				\
+	BOOTENV					\
+	"boot_scripts=ls1088ardb_boot.scr\0"	\
+	"boot_script_hdr=hdr_ls1088ardb_bs.out\0"	\
+	"scan_dev_for_boot_part="		\
+		"part list ${devtype} ${devnum} devplist; "	\
+		"env exists devplist || setenv devplist 1; "	\
+		"for distro_bootpart in ${devplist}; do "	\
+			"if fstype ${devtype} "			\
+				"${devnum}:${distro_bootpart} "	\
+				"bootfstype; then "		\
+				"run scan_dev_for_boot; "	\
+			"fi; "					\
+		"done\0"					\
+	"scan_dev_for_boot="					\
+		"echo Scanning ${devtype} "			\
+		"${devnum}:${distro_bootpart}...; "		\
+		"for prefix in ${boot_prefixes}; do "		\
+			"run scan_dev_for_scripts; "		\
+		"done;\0"					\
+	"boot_a_script="					\
+		"load ${devtype} ${devnum}:${distro_bootpart} " \
+		"${scriptaddr} ${prefix}${script}; "		\
+	"env exists secureboot && load ${devtype} "		\
+		"${devnum}:${distro_bootpart} "			\
+		"${scripthdraddr} ${prefix}${boot_script_hdr} " \
+		"&& esbc_validate ${scripthdraddr};"		\
+		"source ${scriptaddr}\0"			\
+	"installer=load mmc 0:2 $load_addr "			\
+		"/flex_installer_arm64.itb; "			\
+		"env exists mcinitcmd && run mcinitcmd && "	\
+		"mmc read 0x80200000 0x6800 0x800;"		\
+		"fsl_mc apply dpl 0x80200000;"			\
+		"bootm $load_addr#ls1088ardb\0"			\
+	"qspi_bootcmd=echo Trying load from qspi..;"		\
+		"sf probe && sf read $load_addr "		\
+		"$kernel_addr $kernel_size &&"			\
+		"bootm $load_addr#$BOARD\0"			\
+	"sd_bootcmd=echo Trying load from sd card..;"		\
+		"mmcinfo; mmc read $load_addr "			\
+		"$kernel_addr_sd $kernel_size_sd ;"		\
+		"bootm $load_addr#$BOARD\0"
 
+#undef CONFIG_BOOTCOMMAND
+#if defined(CONFIG_QSPI_BOOT)
+/* Try to boot an on-QSPI kernel first, then do normal distro boot */
+#define CONFIG_BOOTCOMMAND                                      \
+		"env exists mcinitcmd && run mcinitcmd && "	\
+		"sf read 0x80200000 0xd00000 0x100000;"	\
+		" fsl_mc apply dpl 0x80200000;"		\
+		"run distro_bootcmd;run qspi_bootcmd"
+/* Try to boot an on-SD kernel first, then do normal distro boot */
+#elif defined(CONFIG_SD_BOOT)
+#define CONFIG_BOOTCOMMAND                                      \
+		"env exists mcinitcmd && run mcinitcmd ;"	\
+		"&& env exists mcinitcmd && mmcinfo; "		\
+		"mmc read 0x88000000 0x6800 0x800; "		\
+		"&& fsl_mc apply dpl 0x88000000;"		\
+		"run distro_bootcmd;run sd_bootcmd"
 #endif
 
 /* MAC/PHY configuration */
@@ -304,7 +391,6 @@
 #include <config_distro_defaults.h>
 
 #define BOOT_TARGET_DEVICES(func) \
-	func(USB, usb, 0) \
 	func(MMC, mmc, 0) \
 	func(SCSI, scsi, 0) \
 	func(DHCP, dhcp, na)
diff --git a/include/configs/ls2080ardb.h b/include/configs/ls2080ardb.h
index 48c3a53..650db2f 100644
--- a/include/configs/ls2080ardb.h
+++ b/include/configs/ls2080ardb.h
@@ -349,6 +349,17 @@
 	"esbc_validate 0x20700000 && "		\
 	"esbc_validate 0x20740000;"		\
 	"fsl_mc start mc 0x20a00000 0x20e00000 \0"
+#elif defined(CONFIG_SD_BOOT)
+#define MC_INIT_CMD                             \
+	"mcinitcmd=mmcinfo;mmc read 0x80000000 0x5000 0x800;" \
+	"mmc read 0x80100000 0x7000 0x800;"	\
+	"env exists secureboot && "		\
+	"mmc read 0x80700000 0x3800 0x10 && "	\
+	"mmc read 0x80740000 0x3A00 0x10 && "	\
+	"esbc_validate 0x80700000 && "		\
+	"esbc_validate 0x80740000 ;"		\
+	"fsl_mc start mc 0x80000000 0x80100000\0" \
+	"mcmemsize=0x70000000\0"
 #else
 #define MC_INIT_CMD				\
 	"mcinitcmd=env exists secureboot && "	\
@@ -379,8 +390,14 @@
 	"fdt_addr_r=0x90000000\0"		\
 	"load_addr=0xa0000000\0"		\
 	"kernel_size=0x2800000\0"		\
+	"kernel_addr_sd=0x8000\0"		\
+	"kernel_size_sd=0x14000\0"              \
 	"console=ttyAMA0,38400n8\0"		\
 	"mcmemsize=0x70000000\0"		\
+	"sd_bootcmd=echo Trying load from SD ..;" \
+	"mmcinfo; mmc read $load_addr "		\
+	"$kernel_addr_sd $kernel_size_sd && "	\
+	"bootm $load_addr#$board\0"             \
 	MC_INIT_CMD				\
 	BOOTENV					\
 	"boot_scripts=ls2088ardb_boot.scr\0"	\
@@ -409,9 +426,6 @@
 			"${scripthdraddr} ${prefix}${boot_script_hdr} "	\
 			"&& esbc_validate ${scripthdraddr};"	\
 		"source ${scriptaddr}\0"			\
-	"installer=load mmc 0:2 $load_addr "			\
-		"/flex_installer_arm64.itb; "			\
-		"bootm $load_addr#ls2088ardb\0"			\
 	"qspi_bootcmd=echo Trying load from qspi..;"		\
 		"sf probe && sf read $load_addr "		\
 		"$kernel_start $kernel_size ; env exists secureboot &&"	\
@@ -433,16 +447,27 @@
 			"&& esbc_validate 0x20780000; "			\
 			"env exists mcinitcmd && "			\
 			"fsl_mc lazyapply dpl 0x20d00000; "		\
-			"run distro_bootcmd;run qspi_bootcmd; "		\
-			"env exists secureboot && esbc_halt; "
+			"run distro_bootcmd;env exists secureboot "	\
+			" && esbc_halt;run qspi_bootcmd; "
+#elif defined(CONFIG_SD_BOOT)
+/* Try to boot an on-SD kernel first, then do normal distro boot */
+#define CONFIG_BOOTCOMMAND						\
+			"env exists mcinitcmd && env exists secureboot "\
+			"&& mmcinfo && mmc read $load_addr 0x3c00 0x800 " \
+			"&& esbc_validate $load_addr; "			\
+			"env exists mcinitcmd && run mcinitcmd "	\
+			"&& mmc read 0x88000000 0x6800 0x800 "		\
+			"&& fsl_mc lazyapply dpl 0x88000000; "		\
+			"run distro_bootcmd;env exists secureboot "	\
+			"&& esbc_halt;run sd_bootcmd;"
 #else
 /* Try to boot an on-NOR kernel first, then do normal distro boot */
 #define CONFIG_BOOTCOMMAND						\
 			"env exists mcinitcmd && env exists secureboot "\
 			"&& esbc_validate 0x580780000; env exists mcinitcmd "\
 			"&& fsl_mc lazyapply dpl 0x580d00000;"		\
-			"run distro_bootcmd;run nor_bootcmd; "		\
-			"env exists secureboot && esbc_halt; "
+			"run distro_bootcmd; env exists secureboot "	\
+			"&& esbc_halt; run nor_bootcmd;"
 #endif
 
 /* MAC/PHY configuration */
diff --git a/include/configs/lsxl.h b/include/configs/lsxl.h
index 5d5851f..0793fcb 100644
--- a/include/configs/lsxl.h
+++ b/include/configs/lsxl.h
@@ -70,7 +70,6 @@
  * Default environment variables
  */
 #define CONFIG_LOADADDR		0x00800000
-#define CONFIG_BOOTCOMMAND	"run bootcmd_${bootsource}"
 
 #if defined(CONFIG_LSXHL)
 #define CONFIG_FDTFILE "kirkwood-lsxhl.dtb"
diff --git a/include/configs/mx6cuboxi.h b/include/configs/mx6cuboxi.h
index 7fefe8e..6b42b2b 100644
--- a/include/configs/mx6cuboxi.h
+++ b/include/configs/mx6cuboxi.h
@@ -122,11 +122,6 @@
 			"echo WARNING: Could not determine dtb to use; fi; \0" \
 	BOOTENV
 
-#define CONFIG_BOOTCOMMAND \
-	"run findfdt; " \
-	"run finduuid; " \
-	"run distro_bootcmd"
-
 #define BOOT_TARGET_DEVICES(func) \
 	func(MMC, mmc, 0) \
 	func(SATA, sata, 0) \
diff --git a/include/configs/novena.h b/include/configs/novena.h
index 3acc8c6..dd0e637 100644
--- a/include/configs/novena.h
+++ b/include/configs/novena.h
@@ -38,7 +38,6 @@
 
 /* Booting Linux */
 #define CONFIG_BOOTFILE			"fitImage"
-#define CONFIG_BOOTCOMMAND		"run distro_bootcmd ; run net_nfs"
 #define CONFIG_HOSTNAME			novena
 
 /* Physical Memory Map */
diff --git a/include/configs/odroid.h b/include/configs/odroid.h
index 22e9c82..60ed013 100644
--- a/include/configs/odroid.h
+++ b/include/configs/odroid.h
@@ -44,7 +44,7 @@
 /* Console configuration */
 
 #define CONFIG_BOOTCOMMAND		"run autoboot"
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC1,115200n8\0"
+#define CONFIG_DEFAULT_CONSOLE		"ttySAC1,115200n8"
 
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_LOAD_ADDR \
 					- GENERATED_GBL_DATA_SIZE)
@@ -158,7 +158,7 @@
 		"elif test -e mmc 0 uImage; then; " \
 			"run boot_uimg;" \
 		"fi;\0" \
-	"console=" CONFIG_DEFAULT_CONSOLE \
+	"console=" CONFIG_DEFAULT_CONSOLE "\0" \
 	"mmcbootdev=0\0" \
 	"mmcbootpart=1\0" \
 	"mmcrootdev=0\0" \
diff --git a/include/configs/odroid_xu3.h b/include/configs/odroid_xu3.h
index 13a4501..2969f18 100644
--- a/include/configs/odroid_xu3.h
+++ b/include/configs/odroid_xu3.h
@@ -34,7 +34,7 @@
 
 #define CONFIG_SYS_INIT_SP_ADDR        (CONFIG_SYS_LOAD_ADDR - 0x1000000)
 
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC2,115200n8\0"
+#define CONFIG_DEFAULT_CONSOLE		"ttySAC2,115200n8"
 
 /* USB */
 #define CONFIG_USB_EHCI_EXYNOS
@@ -108,7 +108,7 @@
 	BOOTENV \
 	"bootdelay=0\0" \
 	"rootfstype=ext4\0" \
-	"console=" CONFIG_DEFAULT_CONSOLE \
+	"console=" CONFIG_DEFAULT_CONSOLE "\0"\
 	"fdtfile=exynos5422-odroidxu3.dtb\0" \
 	"boardname=odroidxu3\0" \
 	"mmcbootdev=0\0" \
diff --git a/include/configs/omap3_igep00x0.h b/include/configs/omap3_igep00x0.h
index 1a90cb5..91b3a23 100644
--- a/include/configs/omap3_igep00x0.h
+++ b/include/configs/omap3_igep00x0.h
@@ -72,10 +72,6 @@
 #define BOOT_TARGET_DEVICES(func) \
 	func(MMC, mmc, 0)
 
-#define CONFIG_BOOTCOMMAND \
-	"run findfdt; " \
-	"run distro_bootcmd"
-
 #include <config_distro_bootcmd.h>
 
 #define ENV_FINDFDT \
diff --git a/include/configs/p212.h b/include/configs/p212.h
new file mode 100644
index 0000000..793b556
--- /dev/null
+++ b/include/configs/p212.h
@@ -0,0 +1,24 @@
+/*
+ * Configuration for Amlogic P212
+ *
+ * Copyright (C) 2017 Baylibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_MISC_INIT_R
+
+#define CONFIG_PHY_ADDR 		8
+
+/* Serial setup */
+#define CONFIG_CONS_INDEX		0
+
+#define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxl-s905x-p212.dtb\0"
+
+#include <configs/meson-gxbb-common.h>
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h
index d81a36e..86835e7 100644
--- a/include/configs/s5p_goni.h
+++ b/include/configs/s5p_goni.h
@@ -95,7 +95,7 @@
 
 #define CONFIG_BOOTCOMMAND	"run mmcboot"
 
-#define CONFIG_DEFAULT_CONSOLE	"console=ttySAC2,115200n8\0"
+#define CONFIG_DEFAULT_CONSOLE	"ttySAC2,115200n8"
 
 #define CONFIG_RAMDISK_BOOT	"root=/dev/ram0 rw rootfstype=ext4" \
 		" ${console} ${meminfo}"
@@ -145,7 +145,7 @@
 	"bootchart=set opts init=/sbin/bootchartd; run bootcmd\0" \
 	"verify=n\0" \
 	"rootfstype=ext4\0" \
-	"console=" CONFIG_DEFAULT_CONSOLE \
+	"console=" CONFIG_DEFAULT_CONSOLE "\0"\
 	"meminfo=mem=80M mem=256M@0x40000000 mem=128M@0x50000000\0" \
 	"loaduimage=ext4load mmc ${mmcdev}:${mmcbootpart} 0x30007FC0 uImage\0" \
 	"mmcdev=0\0" \
diff --git a/include/configs/s5pc210_universal.h b/include/configs/s5pc210_universal.h
index 2b71c5e..b0bcc56 100644
--- a/include/configs/s5pc210_universal.h
+++ b/include/configs/s5pc210_universal.h
@@ -30,7 +30,7 @@
 /* Console configuration */
 
 #define CONFIG_BOOTCOMMAND		"run mmcboot"
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC1,115200n8\0"
+#define CONFIG_DEFAULT_CONSOLE		"ttySAC1,115200n8"
 
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_LOAD_ADDR \
 					- GENERATED_GBL_DATA_SIZE)
@@ -119,7 +119,7 @@
 	"mmcoops=mmc read 0 0x40000000 0x40 8; md 0x40000000 0x400\0" \
 	"verify=n\0" \
 	"rootfstype=ext4\0" \
-	"console=" CONFIG_DEFAULT_CONSOLE \
+	"console=" CONFIG_DEFAULT_CONSOLE "\0" \
 	"mtdparts=" CONFIG_MTDPARTS_DEFAULT \
 	"mbrparts=" MBRPARTS_DEFAULT \
 	"meminfo=crashkernel=32M@0x50000000\0" \
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 71c2ae3..f042656 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -74,8 +74,6 @@
 	func(HOST, host, 1) \
 	func(HOST, host, 0)
 
-#define CONFIG_BOOTCOMMAND ""
-
 #include <config_distro_bootcmd.h>
 
 #define CONFIG_KEEP_SERVERADDR
diff --git a/include/configs/ti_omap4_common.h b/include/configs/ti_omap4_common.h
index 8994400..91b2132 100644
--- a/include/configs/ti_omap4_common.h
+++ b/include/configs/ti_omap4_common.h
@@ -91,14 +91,6 @@
 	func(PXE, pxe, na) \
 	func(DHCP, dhcp, na)
 
-#define CONFIG_BOOTCOMMAND \
-	"if test ${boot_fit} -eq 1; then "	\
-		"run update_to_fit;"	\
-	"fi;"	\
-	"run findfdt; " \
-	"run envboot; " \
-	"run distro_bootcmd"
-
 #include <config_distro_bootcmd.h>
 #include <environment/ti/mmc.h>
 
diff --git a/include/configs/trats.h b/include/configs/trats.h
index a34c349..b97efc2 100644
--- a/include/configs/trats.h
+++ b/include/configs/trats.h
@@ -42,7 +42,7 @@
 #define CONFIG_MACH_TYPE		MACH_TYPE_TRATS
 
 #define CONFIG_BOOTCOMMAND		"run autoboot"
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC2,115200n8\0"
+#define CONFIG_DEFAULT_CONSOLE		"ttySAC2,115200n8"
 
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_LOAD_ADDR \
 					- GENERATED_GBL_DATA_SIZE)
@@ -129,7 +129,7 @@
 	"mmcoops=mmc read 0 0x40000000 0x40 8; md 0x40000000 0x400\0" \
 	"verify=n\0" \
 	"rootfstype=ext4\0" \
-	"console=" CONFIG_DEFAULT_CONSOLE \
+	"console=" CONFIG_DEFAULT_CONSOLE "\0" \
 	"meminfo=crashkernel=32M@0x50000000\0" \
 	"nfsroot=/nfsroot/arm\0" \
 	"bootblock=" CONFIG_BOOTBLOCK "\0" \
diff --git a/include/configs/trats2.h b/include/configs/trats2.h
index 6b371f4..871accf 100644
--- a/include/configs/trats2.h
+++ b/include/configs/trats2.h
@@ -39,7 +39,7 @@
 /* Console configuration */
 
 #define CONFIG_BOOTCOMMAND		"run autoboot"
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC2,115200n8\0"
+#define CONFIG_DEFAULT_CONSOLE		"ttySAC2,115200n8"
 
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_LOAD_ADDR \
 					- GENERATED_GBL_DATA_SIZE)
@@ -111,7 +111,7 @@
 	"boottrace=setenv opts initcall_debug; run bootcmd\0" \
 	"verify=n\0" \
 	"rootfstype=ext4\0" \
-	"console=" CONFIG_DEFAULT_CONSOLE \
+	"console=" CONFIG_DEFAULT_CONSOLE "\0" \
 	"kernelname=uImage\0" \
 	"loaduimage=ext4load mmc ${mmcdev}:${mmcbootpart} 0x40007FC0 " \
 		"${kernelname}\0" \
diff --git a/include/configs/udoo_neo.h b/include/configs/udoo_neo.h
index 9b0a20d..3e46a42 100644
--- a/include/configs/udoo_neo.h
+++ b/include/configs/udoo_neo.h
@@ -60,10 +60,6 @@
 	func(MMC, mmc, 0) \
 	func(DHCP, dhcp, na)
 
-#define CONFIG_BOOTCOMMAND \
-	"run findfdt; " \
-	"run distro_bootcmd"
-
 #include <config_distro_bootcmd.h>
 
 /* Miscellaneous configurable options */
diff --git a/include/configs/vexpress_common.h b/include/configs/vexpress_common.h
index ade7ba4..294ca18 100644
--- a/include/configs/vexpress_common.h
+++ b/include/configs/vexpress_common.h
@@ -177,10 +177,6 @@
 #include <config_distro_defaults.h>
 
 /* Basic environment settings */
-#define CONFIG_BOOTCOMMAND \
-	"run distro_bootcmd; " \
-	"run bootflash; "
-
 #define BOOT_TARGET_DEVICES(func) \
         func(MMC, mmc, 1) \
         func(MMC, mmc, 0) \
diff --git a/include/configs/wandboard.h b/include/configs/wandboard.h
index 8fdfc02..97d193b 100644
--- a/include/configs/wandboard.h
+++ b/include/configs/wandboard.h
@@ -140,11 +140,6 @@
 	func(PXE, pxe, na) \
 	func(DHCP, dhcp, na)
 
-#define CONFIG_BOOTCOMMAND \
-	   "run findfdt; " \
-	   "run finduuid; " \
-	   "run distro_bootcmd"
-
 #include <config_distro_bootcmd.h>
 
 /* Physical Memory Map */
diff --git a/include/dt-bindings/gpio/meson-gxl-gpio.h b/include/dt-bindings/gpio/meson-gxl-gpio.h
new file mode 100644
index 0000000..684d0d7
--- /dev/null
+++ b/include/dt-bindings/gpio/meson-gxl-gpio.h
@@ -0,0 +1,131 @@
+/*
+ * GPIO definitions for Amlogic Meson GXL SoCs
+ *
+ * Copyright (C) 2016 Endless Mobile, Inc.
+ * Author: Carlo Caione <carlo@endlessm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _DT_BINDINGS_MESON_GXL_GPIO_H
+#define _DT_BINDINGS_MESON_GXL_GPIO_H
+
+#define	GPIOAO_0	0
+#define	GPIOAO_1	1
+#define	GPIOAO_2	2
+#define	GPIOAO_3	3
+#define	GPIOAO_4	4
+#define	GPIOAO_5	5
+#define	GPIOAO_6	6
+#define	GPIOAO_7	7
+#define	GPIOAO_8	8
+#define	GPIOAO_9	9
+
+#define	GPIOZ_0		0
+#define	GPIOZ_1		1
+#define	GPIOZ_2		2
+#define	GPIOZ_3		3
+#define	GPIOZ_4		4
+#define	GPIOZ_5		5
+#define	GPIOZ_6		6
+#define	GPIOZ_7		7
+#define	GPIOZ_8		8
+#define	GPIOZ_9		9
+#define	GPIOZ_10	10
+#define	GPIOZ_11	11
+#define	GPIOZ_12	12
+#define	GPIOZ_13	13
+#define	GPIOZ_14	14
+#define	GPIOZ_15	15
+#define	GPIOH_0		16
+#define	GPIOH_1		17
+#define	GPIOH_2		18
+#define	GPIOH_3		19
+#define	GPIOH_4		20
+#define	GPIOH_5		21
+#define	GPIOH_6		22
+#define	GPIOH_7		23
+#define	GPIOH_8		24
+#define	GPIOH_9		25
+#define	BOOT_0		26
+#define	BOOT_1		27
+#define	BOOT_2		28
+#define	BOOT_3		29
+#define	BOOT_4		30
+#define	BOOT_5		31
+#define	BOOT_6		32
+#define	BOOT_7		33
+#define	BOOT_8		34
+#define	BOOT_9		35
+#define	BOOT_10		36
+#define	BOOT_11		37
+#define	BOOT_12		38
+#define	BOOT_13		39
+#define	BOOT_14		40
+#define	BOOT_15		41
+#define	CARD_0		42
+#define	CARD_1		43
+#define	CARD_2		44
+#define	CARD_3		45
+#define	CARD_4		46
+#define	CARD_5		47
+#define	CARD_6		48
+#define	GPIODV_0	49
+#define	GPIODV_1	50
+#define	GPIODV_2	51
+#define	GPIODV_3	52
+#define	GPIODV_4	53
+#define	GPIODV_5	54
+#define	GPIODV_6	55
+#define	GPIODV_7	56
+#define	GPIODV_8	57
+#define	GPIODV_9	58
+#define	GPIODV_10	59
+#define	GPIODV_11	60
+#define	GPIODV_12	61
+#define	GPIODV_13	62
+#define	GPIODV_14	63
+#define	GPIODV_15	64
+#define	GPIODV_16	65
+#define	GPIODV_17	66
+#define	GPIODV_18	67
+#define	GPIODV_19	68
+#define	GPIODV_20	69
+#define	GPIODV_21	70
+#define	GPIODV_22	71
+#define	GPIODV_23	72
+#define	GPIODV_24	73
+#define	GPIODV_25	74
+#define	GPIODV_26	75
+#define	GPIODV_27	76
+#define	GPIODV_28	77
+#define	GPIODV_29	78
+#define	GPIOX_0		79
+#define	GPIOX_1		80
+#define	GPIOX_2		81
+#define	GPIOX_3		82
+#define	GPIOX_4		83
+#define	GPIOX_5		84
+#define	GPIOX_6		85
+#define	GPIOX_7		86
+#define	GPIOX_8		87
+#define	GPIOX_9		88
+#define	GPIOX_10	89
+#define	GPIOX_11	90
+#define	GPIOX_12	91
+#define	GPIOX_13	92
+#define	GPIOX_14	93
+#define	GPIOX_15	94
+#define	GPIOX_16	95
+#define	GPIOX_17	96
+#define	GPIOX_18	97
+#define	GPIOCLK_0	98
+#define	GPIOCLK_1	99
+#define	GPIO_TEST_N	100
+
+#endif
diff --git a/include/fdt.h b/include/fdt.h
index f40b56c..b97b3f2 100644
--- a/include/fdt.h
+++ b/include/fdt.h
@@ -1 +1 @@
-#include "../lib/libfdt/fdt.h"
+#include "../scripts/dtc/libfdt/fdt.h"
diff --git a/include/libfdt_env.h b/include/libfdt_env.h
index 6c6845f..273b5d3 100644
--- a/include/libfdt_env.h
+++ b/include/libfdt_env.h
@@ -23,12 +23,6 @@
 #define fdt64_to_cpu(x)		be64_to_cpu(x)
 #define cpu_to_fdt64(x)		cpu_to_be64(x)
 
-#ifdef __UBOOT__
-#include <vsprintf.h>
-
-#define strtoul(cp, endp, base)	simple_strtoul(cp, endp, base)
-#endif
-
 /* adding a ramdisk needs 0x44 bytes in version 2008.10 */
 #define FDT_RAMDISK_OVERHEAD	0x80
 
diff --git a/include/linux/libfdt.h b/include/linux/libfdt.h
new file mode 100644
index 0000000..2a663c6
--- /dev/null
+++ b/include/linux/libfdt.h
@@ -0,0 +1,17 @@
+#ifndef _LIBFDT_ENV_H
+#define _LIBFDT_ENV_H
+
+#include <linux/string.h>
+
+#include <asm/byteorder.h>
+
+typedef __be16 fdt16_t;
+typedef __be32 fdt32_t;
+typedef __be64 fdt64_t;
+
+#define fdt32_to_cpu(x) be32_to_cpu(x)
+#define cpu_to_fdt32(x) cpu_to_be32(x)
+#define fdt64_to_cpu(x) be64_to_cpu(x)
+#define cpu_to_fdt64(x) cpu_to_be64(x)
+
+#endif /* _LIBFDT_ENV_H */
diff --git a/include/linux/libfdt_env.h b/include/linux/libfdt_env.h
new file mode 100644
index 0000000..8178f91
--- /dev/null
+++ b/include/linux/libfdt_env.h
@@ -0,0 +1,22 @@
+#ifndef _LIBFDT_ENV_H
+#define _LIBFDT_ENV_H
+
+#include <linux/string.h>
+
+#include <asm/byteorder.h>
+
+typedef __be16 fdt16_t;
+typedef __be32 fdt32_t;
+typedef __be64 fdt64_t;
+
+#define fdt32_to_cpu(x) be32_to_cpu(x)
+#define cpu_to_fdt32(x) cpu_to_be32(x)
+#define fdt64_to_cpu(x) be64_to_cpu(x)
+#define cpu_to_fdt64(x) cpu_to_be64(x)
+
+/* U-Boot: for strtoul in fdt_overlay.c */
+#include <vsprintf.h>
+
+#define strtoul(cp, endp, base)	simple_strtoul(cp, endp, base)
+
+#endif /* _LIBFDT_ENV_H */
diff --git a/include/linux/types.h b/include/linux/types.h
index 416fa66..7c33e7a 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -24,6 +24,8 @@
 typedef __kernel_uid16_t        uid16_t;
 typedef __kernel_gid16_t        gid16_t;
 
+typedef unsigned long		uintptr_t;
+
 #ifdef CONFIG_UID16
 /* This is defined by include/asm-{arch}/posix_types.h */
 typedef __kernel_old_uid_t	old_uid_t;
diff --git a/include/phy.h b/include/phy.h
index a0b1f12..50f1e12 100644
--- a/include/phy.h
+++ b/include/phy.h
@@ -268,6 +268,7 @@
 int phy_marvell_init(void);
 int phy_micrel_ksz8xxx_init(void);
 int phy_micrel_ksz90x1_init(void);
+int phy_meson_gxl_init(void);
 int phy_natsemi_init(void);
 int phy_realtek_init(void);
 int phy_smsc_init(void);
diff --git a/lib/libfdt/Makefile b/lib/libfdt/Makefile
index 6ef8290..369bbf9 100644
--- a/lib/libfdt/Makefile
+++ b/lib/libfdt/Makefile
@@ -5,15 +5,22 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+# Use upstream code.
 obj-y += \
 	fdt.o \
-	fdt_ro.o \
-	fdt_rw.o \
 	fdt_strerror.o \
 	fdt_sw.o \
-	fdt_wip.o \
 	fdt_empty_tree.o \
-	fdt_addresses.o \
-	fdt_region.o
+	fdt_addresses.o
 
 obj-$(CONFIG_OF_LIBFDT_OVERLAY) += fdt_overlay.o
+
+# Locally modified for U-Boot.
+# TODO: split out the local modifiction.
+obj-y += \
+	fdt_ro.o \
+	fdt_rw.o \
+	fdt_wip.o \
+
+# U-Boot own file
+obj-y += fdt_region.o
diff --git a/lib/libfdt/fdt.c b/lib/libfdt/fdt.c
index 2055734..0958e6ba 100644
--- a/lib/libfdt/fdt.c
+++ b/lib/libfdt/fdt.c
@@ -1,210 +1,2 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- * SPDX-License-Identifier:	GPL-2.0+ BSD-2-Clause
- */
-#include <libfdt_env.h>
-
-#ifndef USE_HOSTCC
-#include <fdt.h>
-#include <libfdt.h>
-#else
-#include "fdt_host.h"
-#endif
-
-#include "libfdt_internal.h"
-
-int fdt_check_header(const void *fdt)
-{
-	if (fdt_magic(fdt) == FDT_MAGIC) {
-		/* Complete tree */
-		if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
-			return -FDT_ERR_BADVERSION;
-		if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
-			return -FDT_ERR_BADVERSION;
-	} else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
-		/* Unfinished sequential-write blob */
-		if (fdt_size_dt_struct(fdt) == 0)
-			return -FDT_ERR_BADSTATE;
-	} else {
-		return -FDT_ERR_BADMAGIC;
-	}
-
-	return 0;
-}
-
-const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
-{
-	unsigned absoffset = offset + fdt_off_dt_struct(fdt);
-
-	if ((absoffset < offset)
-	    || ((absoffset + len) < absoffset)
-	    || (absoffset + len) > fdt_totalsize(fdt))
-		return NULL;
-
-	if (fdt_version(fdt) >= 0x11)
-		if (((offset + len) < offset)
-		    || ((offset + len) > fdt_size_dt_struct(fdt)))
-			return NULL;
-
-	return _fdt_offset_ptr(fdt, offset);
-}
-
-uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
-{
-	const fdt32_t *tagp, *lenp;
-	uint32_t tag;
-	int offset = startoffset;
-	const char *p;
-
-	*nextoffset = -FDT_ERR_TRUNCATED;
-	tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
-	if (!tagp)
-		return FDT_END; /* premature end */
-	tag = fdt32_to_cpu(*tagp);
-	offset += FDT_TAGSIZE;
-
-	*nextoffset = -FDT_ERR_BADSTRUCTURE;
-	switch (tag) {
-	case FDT_BEGIN_NODE:
-		/* skip name */
-		do {
-			p = fdt_offset_ptr(fdt, offset++, 1);
-		} while (p && (*p != '\0'));
-		if (!p)
-			return FDT_END; /* premature end */
-		break;
-
-	case FDT_PROP:
-		lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
-		if (!lenp)
-			return FDT_END; /* premature end */
-		/* skip-name offset, length and value */
-		offset += sizeof(struct fdt_property) - FDT_TAGSIZE
-			+ fdt32_to_cpu(*lenp);
-		break;
-
-	case FDT_END:
-	case FDT_END_NODE:
-	case FDT_NOP:
-		break;
-
-	default:
-		return FDT_END;
-	}
-
-	if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
-		return FDT_END; /* premature end */
-
-	*nextoffset = FDT_TAGALIGN(offset);
-	return tag;
-}
-
-int _fdt_check_node_offset(const void *fdt, int offset)
-{
-	if ((offset < 0) || (offset % FDT_TAGSIZE)
-	    || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
-		return -FDT_ERR_BADOFFSET;
-
-	return offset;
-}
-
-int _fdt_check_prop_offset(const void *fdt, int offset)
-{
-	if ((offset < 0) || (offset % FDT_TAGSIZE)
-	    || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
-		return -FDT_ERR_BADOFFSET;
-
-	return offset;
-}
-
-int fdt_next_node(const void *fdt, int offset, int *depth)
-{
-	int nextoffset = 0;
-	uint32_t tag;
-
-	if (offset >= 0)
-		if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
-			return nextoffset;
-
-	do {
-		offset = nextoffset;
-		tag = fdt_next_tag(fdt, offset, &nextoffset);
-
-		switch (tag) {
-		case FDT_PROP:
-		case FDT_NOP:
-			break;
-
-		case FDT_BEGIN_NODE:
-			if (depth)
-				(*depth)++;
-			break;
-
-		case FDT_END_NODE:
-			if (depth && ((--(*depth)) < 0))
-				return nextoffset;
-			break;
-
-		case FDT_END:
-			if ((nextoffset >= 0)
-			    || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
-				return -FDT_ERR_NOTFOUND;
-			else
-				return nextoffset;
-		}
-	} while (tag != FDT_BEGIN_NODE);
-
-	return offset;
-}
-
-int fdt_first_subnode(const void *fdt, int offset)
-{
-	int depth = 0;
-
-	offset = fdt_next_node(fdt, offset, &depth);
-	if (offset < 0 || depth != 1)
-		return -FDT_ERR_NOTFOUND;
-
-	return offset;
-}
-
-int fdt_next_subnode(const void *fdt, int offset)
-{
-	int depth = 1;
-
-	/*
-	 * With respect to the parent, the depth of the next subnode will be
-	 * the same as the last.
-	 */
-	do {
-		offset = fdt_next_node(fdt, offset, &depth);
-		if (offset < 0 || depth < 1)
-			return -FDT_ERR_NOTFOUND;
-	} while (depth > 1);
-
-	return offset;
-}
-
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
-{
-	int len = strlen(s) + 1;
-	const char *last = strtab + tabsize - len;
-	const char *p;
-
-	for (p = strtab; p <= last; p++)
-		if (memcmp(p, s, len) == 0)
-			return p;
-	return NULL;
-}
-
-int fdt_move(const void *fdt, void *buf, int bufsize)
-{
-	FDT_CHECK_HEADER(fdt);
-
-	if (fdt_totalsize(fdt) > bufsize)
-		return -FDT_ERR_NOSPACE;
-
-	memmove(buf, fdt, fdt_totalsize(fdt));
-	return 0;
-}
+#include <linux/libfdt_env.h>
+#include "../../scripts/dtc/libfdt/fdt.c"
diff --git a/lib/libfdt/fdt.h b/lib/libfdt/fdt.h
deleted file mode 100644
index 3134d78..0000000
--- a/lib/libfdt/fdt.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef _FDT_H
-#define _FDT_H
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- * Copyright 2012 Kim Phillips, Freescale Semiconductor.
- *
- * SPDX-License-Identifier:     GPL-2.0+ BSD-2-Clause
- */
-
-#ifndef __ASSEMBLY__
-
-struct fdt_header {
-	fdt32_t magic;			 /* magic word FDT_MAGIC */
-	fdt32_t totalsize;		 /* total size of DT block */
-	fdt32_t off_dt_struct;		 /* offset to structure */
-	fdt32_t off_dt_strings;		 /* offset to strings */
-	fdt32_t off_mem_rsvmap;		 /* offset to memory reserve map */
-	fdt32_t version;		 /* format version */
-	fdt32_t last_comp_version;	 /* last compatible version */
-
-	/* version 2 fields below */
-	fdt32_t boot_cpuid_phys;	 /* Which physical CPU id we're
-					    booting on */
-	/* version 3 fields below */
-	fdt32_t size_dt_strings;	 /* size of the strings block */
-
-	/* version 17 fields below */
-	fdt32_t size_dt_struct;		 /* size of the structure block */
-};
-
-struct fdt_reserve_entry {
-	fdt64_t address;
-	fdt64_t size;
-};
-
-struct fdt_node_header {
-	fdt32_t tag;
-	char name[0];
-};
-
-struct fdt_property {
-	fdt32_t tag;
-	fdt32_t len;
-	fdt32_t nameoff;
-	char data[0];
-};
-
-#endif /* !__ASSEMBLY */
-
-#define FDT_MAGIC	0xd00dfeed	/* 4: version, 4: total size */
-#define FDT_TAGSIZE	sizeof(fdt32_t)
-
-#define FDT_BEGIN_NODE	0x1		/* Start node: full name */
-#define FDT_END_NODE	0x2		/* End node */
-#define FDT_PROP	0x3		/* Property: name off,
-					   size, content */
-#define FDT_NOP		0x4		/* nop */
-#define FDT_END		0x9
-
-#define FDT_V1_SIZE	(7*sizeof(fdt32_t))
-#define FDT_V2_SIZE	(FDT_V1_SIZE + sizeof(fdt32_t))
-#define FDT_V3_SIZE	(FDT_V2_SIZE + sizeof(fdt32_t))
-#define FDT_V16_SIZE	FDT_V3_SIZE
-#define FDT_V17_SIZE	(FDT_V16_SIZE + sizeof(fdt32_t))
-
-#endif /* _FDT_H */
diff --git a/lib/libfdt/fdt_addresses.c b/lib/libfdt/fdt_addresses.c
index b6bc66e..b82a029 100644
--- a/lib/libfdt/fdt_addresses.c
+++ b/lib/libfdt/fdt_addresses.c
@@ -1,55 +1,2 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
- * SPDX-License-Identifier:	GPL-2.0+ BSD-2-Clause
- */
-#include <libfdt_env.h>
-
-#ifndef USE_HOSTCC
-#include <fdt.h>
-#include <libfdt.h>
-#else
-#include "fdt_host.h"
-#endif
-
-#include "libfdt_internal.h"
-
-int fdt_address_cells(const void *fdt, int nodeoffset)
-{
-	const fdt32_t *ac;
-	int val;
-	int len;
-
-	ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len);
-	if (!ac)
-		return 2;
-
-	if (len != sizeof(*ac))
-		return -FDT_ERR_BADNCELLS;
-
-	val = fdt32_to_cpu(*ac);
-	if ((val <= 0) || (val > FDT_MAX_NCELLS))
-		return -FDT_ERR_BADNCELLS;
-
-	return val;
-}
-
-int fdt_size_cells(const void *fdt, int nodeoffset)
-{
-	const fdt32_t *sc;
-	int val;
-	int len;
-
-	sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len);
-	if (!sc)
-		return 2;
-
-	if (len != sizeof(*sc))
-		return -FDT_ERR_BADNCELLS;
-
-	val = fdt32_to_cpu(*sc);
-	if ((val < 0) || (val > FDT_MAX_NCELLS))
-		return -FDT_ERR_BADNCELLS;
-
-	return val;
-}
+#include <linux/libfdt_env.h>
+#include "../../scripts/dtc/libfdt/fdt_addresses.c"
diff --git a/lib/libfdt/fdt_empty_tree.c b/lib/libfdt/fdt_empty_tree.c
index 6fde1eb..2b4ae10 100644
--- a/lib/libfdt/fdt_empty_tree.c
+++ b/lib/libfdt/fdt_empty_tree.c
@@ -1,37 +1,2 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2012 David Gibson, IBM Corporation.
- * SPDX-License-Identifier:	GPL-2.0+ BSD-2-Clause
- */
-#include <libfdt_env.h>
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-int fdt_create_empty_tree(void *buf, int bufsize)
-{
-	int err;
-
-	err = fdt_create(buf, bufsize);
-	if (err)
-		return err;
-
-	err = fdt_finish_reservemap(buf);
-	if (err)
-		return err;
-
-	err = fdt_begin_node(buf, "");
-	if (err)
-		return err;
-
-	err =  fdt_end_node(buf);
-	if (err)
-		return err;
-
-	err = fdt_finish(buf);
-	if (err)
-		return err;
-
-	return fdt_open_into(buf, buf, bufsize);
-}
+#include <linux/libfdt_env.h>
+#include "../../scripts/dtc/libfdt/fdt_empty_tree.c"
diff --git a/lib/libfdt/fdt_overlay.c b/lib/libfdt/fdt_overlay.c
index bd81241..575c827 100644
--- a/lib/libfdt/fdt_overlay.c
+++ b/lib/libfdt/fdt_overlay.c
@@ -1,861 +1,2 @@
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-/**
- * overlay_get_target_phandle - retrieves the target phandle of a fragment
- * @fdto: pointer to the device tree overlay blob
- * @fragment: node offset of the fragment in the overlay
- *
- * overlay_get_target_phandle() retrieves the target phandle of an
- * overlay fragment when that fragment uses a phandle (target
- * property) instead of a path (target-path property).
- *
- * returns:
- *      the phandle pointed by the target property
- *      0, if the phandle was not found
- *	-1, if the phandle was malformed
- */
-static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
-{
-	const fdt32_t *val;
-	int len;
-
-	val = fdt_getprop(fdto, fragment, "target", &len);
-	if (!val)
-		return 0;
-
-	if ((len != sizeof(*val)) || (fdt32_to_cpu(*val) == (uint32_t)-1))
-		return (uint32_t)-1;
-
-	return fdt32_to_cpu(*val);
-}
-
-/**
- * overlay_get_target - retrieves the offset of a fragment's target
- * @fdt: Base device tree blob
- * @fdto: Device tree overlay blob
- * @fragment: node offset of the fragment in the overlay
- * @pathp: pointer which receives the path of the target (or NULL)
- *
- * overlay_get_target() retrieves the target offset in the base
- * device tree of a fragment, no matter how the actual targetting is
- * done (through a phandle or a path)
- *
- * returns:
- *      the targetted node offset in the base device tree
- *      Negative error code on error
- */
-static int overlay_get_target(const void *fdt, const void *fdto,
-			      int fragment, char const **pathp)
-{
-	uint32_t phandle;
-	const char *path = NULL;
-	int path_len = 0, ret;
-
-	/* Try first to do a phandle based lookup */
-	phandle = overlay_get_target_phandle(fdto, fragment);
-	if (phandle == (uint32_t)-1)
-		return -FDT_ERR_BADPHANDLE;
-
-	/* no phandle, try path */
-	if (!phandle) {
-		/* And then a path based lookup */
-		path = fdt_getprop(fdto, fragment, "target-path", &path_len);
-		if (path)
-			ret = fdt_path_offset(fdt, path);
-		else
-			ret = path_len;
-	} else
-		ret = fdt_node_offset_by_phandle(fdt, phandle);
-
-	/*
-	* If we haven't found either a target or a
-	* target-path property in a node that contains a
-	* __overlay__ subnode (we wouldn't be called
-	* otherwise), consider it a improperly written
-	* overlay
-	*/
-	if (ret < 0 && path_len == -FDT_ERR_NOTFOUND)
-		ret = -FDT_ERR_BADOVERLAY;
-
-	/* return on error */
-	if (ret < 0)
-		return ret;
-
-	/* return pointer to path (if available) */
-	if (pathp)
-		*pathp = path ? path : NULL;
-
-	return ret;
-}
-
-/**
- * overlay_phandle_add_offset - Increases a phandle by an offset
- * @fdt: Base device tree blob
- * @node: Device tree overlay blob
- * @name: Name of the property to modify (phandle or linux,phandle)
- * @delta: offset to apply
- *
- * overlay_phandle_add_offset() increments a node phandle by a given
- * offset.
- *
- * returns:
- *      0 on success.
- *      Negative error code on error
- */
-static int overlay_phandle_add_offset(void *fdt, int node,
-				      const char *name, uint32_t delta)
-{
-	const fdt32_t *val;
-	uint32_t adj_val;
-	int len;
-
-	val = fdt_getprop(fdt, node, name, &len);
-	if (!val)
-		return len;
-
-	if (len != sizeof(*val))
-		return -FDT_ERR_BADPHANDLE;
-
-	adj_val = fdt32_to_cpu(*val);
-	if ((adj_val + delta) < adj_val)
-		return -FDT_ERR_NOPHANDLES;
-
-	adj_val += delta;
-	if (adj_val == (uint32_t)-1)
-		return -FDT_ERR_NOPHANDLES;
-
-	return fdt_setprop_inplace_u32(fdt, node, name, adj_val);
-}
-
-/**
- * overlay_adjust_node_phandles - Offsets the phandles of a node
- * @fdto: Device tree overlay blob
- * @node: Offset of the node we want to adjust
- * @delta: Offset to shift the phandles of
- *
- * overlay_adjust_node_phandles() adds a constant to all the phandles
- * of a given node. This is mainly use as part of the overlay
- * application process, when we want to update all the overlay
- * phandles to not conflict with the overlays of the base device tree.
- *
- * returns:
- *      0 on success
- *      Negative error code on failure
- */
-static int overlay_adjust_node_phandles(void *fdto, int node,
-					uint32_t delta)
-{
-	int child;
-	int ret;
-
-	ret = overlay_phandle_add_offset(fdto, node, "phandle", delta);
-	if (ret && ret != -FDT_ERR_NOTFOUND)
-		return ret;
-
-	ret = overlay_phandle_add_offset(fdto, node, "linux,phandle", delta);
-	if (ret && ret != -FDT_ERR_NOTFOUND)
-		return ret;
-
-	fdt_for_each_subnode(child, fdto, node) {
-		ret = overlay_adjust_node_phandles(fdto, child, delta);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
-/**
- * overlay_adjust_local_phandles - Adjust the phandles of a whole overlay
- * @fdto: Device tree overlay blob
- * @delta: Offset to shift the phandles of
- *
- * overlay_adjust_local_phandles() adds a constant to all the
- * phandles of an overlay. This is mainly use as part of the overlay
- * application process, when we want to update all the overlay
- * phandles to not conflict with the overlays of the base device tree.
- *
- * returns:
- *      0 on success
- *      Negative error code on failure
- */
-static int overlay_adjust_local_phandles(void *fdto, uint32_t delta)
-{
-	/*
-	 * Start adjusting the phandles from the overlay root
-	 */
-	return overlay_adjust_node_phandles(fdto, 0, delta);
-}
-
-/**
- * overlay_update_local_node_references - Adjust the overlay references
- * @fdto: Device tree overlay blob
- * @tree_node: Node offset of the node to operate on
- * @fixup_node: Node offset of the matching local fixups node
- * @delta: Offset to shift the phandles of
- *
- * overlay_update_local_nodes_references() update the phandles
- * pointing to a node within the device tree overlay by adding a
- * constant delta.
- *
- * This is mainly used as part of a device tree application process,
- * where you want the device tree overlays phandles to not conflict
- * with the ones from the base device tree before merging them.
- *
- * returns:
- *      0 on success
- *      Negative error code on failure
- */
-static int overlay_update_local_node_references(void *fdto,
-						int tree_node,
-						int fixup_node,
-						uint32_t delta)
-{
-	int fixup_prop;
-	int fixup_child;
-	int ret;
-
-	fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) {
-		const fdt32_t *fixup_val;
-		const char *tree_val;
-		const char *name;
-		int fixup_len;
-		int tree_len;
-		int i;
-
-		fixup_val = fdt_getprop_by_offset(fdto, fixup_prop,
-						  &name, &fixup_len);
-		if (!fixup_val)
-			return fixup_len;
-
-		if (fixup_len % sizeof(uint32_t))
-			return -FDT_ERR_BADOVERLAY;
-
-		tree_val = fdt_getprop(fdto, tree_node, name, &tree_len);
-		if (!tree_val) {
-			if (tree_len == -FDT_ERR_NOTFOUND)
-				return -FDT_ERR_BADOVERLAY;
-
-			return tree_len;
-		}
-
-		for (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) {
-			fdt32_t adj_val;
-			uint32_t poffset;
-
-			poffset = fdt32_to_cpu(fixup_val[i]);
-
-			/*
-			 * phandles to fixup can be unaligned.
-			 *
-			 * Use a memcpy for the architectures that do
-			 * not support unaligned accesses.
-			 */
-			memcpy(&adj_val, tree_val + poffset, sizeof(adj_val));
-
-			adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta);
-
-			ret = fdt_setprop_inplace_namelen_partial(fdto,
-								  tree_node,
-								  name,
-								  strlen(name),
-								  poffset,
-								  &adj_val,
-								  sizeof(adj_val));
-			if (ret == -FDT_ERR_NOSPACE)
-				return -FDT_ERR_BADOVERLAY;
-
-			if (ret)
-				return ret;
-		}
-	}
-
-	fdt_for_each_subnode(fixup_child, fdto, fixup_node) {
-		const char *fixup_child_name = fdt_get_name(fdto, fixup_child,
-							    NULL);
-		int tree_child;
-
-		tree_child = fdt_subnode_offset(fdto, tree_node,
-						fixup_child_name);
-		if (tree_child == -FDT_ERR_NOTFOUND)
-			return -FDT_ERR_BADOVERLAY;
-		if (tree_child < 0)
-			return tree_child;
-
-		ret = overlay_update_local_node_references(fdto,
-							   tree_child,
-							   fixup_child,
-							   delta);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
-/**
- * overlay_update_local_references - Adjust the overlay references
- * @fdto: Device tree overlay blob
- * @delta: Offset to shift the phandles of
- *
- * overlay_update_local_references() update all the phandles pointing
- * to a node within the device tree overlay by adding a constant
- * delta to not conflict with the base overlay.
- *
- * This is mainly used as part of a device tree application process,
- * where you want the device tree overlays phandles to not conflict
- * with the ones from the base device tree before merging them.
- *
- * returns:
- *      0 on success
- *      Negative error code on failure
- */
-static int overlay_update_local_references(void *fdto, uint32_t delta)
-{
-	int fixups;
-
-	fixups = fdt_path_offset(fdto, "/__local_fixups__");
-	if (fixups < 0) {
-		/* There's no local phandles to adjust, bail out */
-		if (fixups == -FDT_ERR_NOTFOUND)
-			return 0;
-
-		return fixups;
-	}
-
-	/*
-	 * Update our local references from the root of the tree
-	 */
-	return overlay_update_local_node_references(fdto, 0, fixups,
-						    delta);
-}
-
-/**
- * overlay_fixup_one_phandle - Set an overlay phandle to the base one
- * @fdt: Base Device Tree blob
- * @fdto: Device tree overlay blob
- * @symbols_off: Node offset of the symbols node in the base device tree
- * @path: Path to a node holding a phandle in the overlay
- * @path_len: number of path characters to consider
- * @name: Name of the property holding the phandle reference in the overlay
- * @name_len: number of name characters to consider
- * @poffset: Offset within the overlay property where the phandle is stored
- * @label: Label of the node referenced by the phandle
- *
- * overlay_fixup_one_phandle() resolves an overlay phandle pointing to
- * a node in the base device tree.
- *
- * This is part of the device tree overlay application process, when
- * you want all the phandles in the overlay to point to the actual
- * base dt nodes.
- *
- * returns:
- *      0 on success
- *      Negative error code on failure
- */
-static int overlay_fixup_one_phandle(void *fdt, void *fdto,
-				     int symbols_off,
-				     const char *path, uint32_t path_len,
-				     const char *name, uint32_t name_len,
-				     int poffset, const char *label)
-{
-	const char *symbol_path;
-	uint32_t phandle;
-	fdt32_t phandle_prop;
-	int symbol_off, fixup_off;
-	int prop_len;
-
-	if (symbols_off < 0)
-		return symbols_off;
-
-	symbol_path = fdt_getprop(fdt, symbols_off, label,
-				  &prop_len);
-	if (!symbol_path)
-		return prop_len;
-
-	symbol_off = fdt_path_offset(fdt, symbol_path);
-	if (symbol_off < 0)
-		return symbol_off;
-
-	phandle = fdt_get_phandle(fdt, symbol_off);
-	if (!phandle)
-		return -FDT_ERR_NOTFOUND;
-
-	fixup_off = fdt_path_offset_namelen(fdto, path, path_len);
-	if (fixup_off == -FDT_ERR_NOTFOUND)
-		return -FDT_ERR_BADOVERLAY;
-	if (fixup_off < 0)
-		return fixup_off;
-
-	phandle_prop = cpu_to_fdt32(phandle);
-	return fdt_setprop_inplace_namelen_partial(fdto, fixup_off,
-						   name, name_len, poffset,
-						   &phandle_prop,
-						   sizeof(phandle_prop));
-};
-
-/**
- * overlay_fixup_phandle - Set an overlay phandle to the base one
- * @fdt: Base Device Tree blob
- * @fdto: Device tree overlay blob
- * @symbols_off: Node offset of the symbols node in the base device tree
- * @property: Property offset in the overlay holding the list of fixups
- *
- * overlay_fixup_phandle() resolves all the overlay phandles pointed
- * to in a __fixups__ property, and updates them to match the phandles
- * in use in the base device tree.
- *
- * This is part of the device tree overlay application process, when
- * you want all the phandles in the overlay to point to the actual
- * base dt nodes.
- *
- * returns:
- *      0 on success
- *      Negative error code on failure
- */
-static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
-				 int property)
-{
-	const char *value;
-	const char *label;
-	int len;
-
-	value = fdt_getprop_by_offset(fdto, property,
-				      &label, &len);
-	if (!value) {
-		if (len == -FDT_ERR_NOTFOUND)
-			return -FDT_ERR_INTERNAL;
-
-		return len;
-	}
-
-	do {
-		const char *path, *name, *fixup_end;
-		const char *fixup_str = value;
-		uint32_t path_len, name_len;
-		uint32_t fixup_len;
-		char *sep, *endptr;
-		int poffset, ret;
-
-		fixup_end = memchr(value, '\0', len);
-		if (!fixup_end)
-			return -FDT_ERR_BADOVERLAY;
-		fixup_len = fixup_end - fixup_str;
-
-		len -= fixup_len + 1;
-		value += fixup_len + 1;
-
-		path = fixup_str;
-		sep = memchr(fixup_str, ':', fixup_len);
-		if (!sep || *sep != ':')
-			return -FDT_ERR_BADOVERLAY;
-
-		path_len = sep - path;
-		if (path_len == (fixup_len - 1))
-			return -FDT_ERR_BADOVERLAY;
-
-		fixup_len -= path_len + 1;
-		name = sep + 1;
-		sep = memchr(name, ':', fixup_len);
-		if (!sep || *sep != ':')
-			return -FDT_ERR_BADOVERLAY;
-
-		name_len = sep - name;
-		if (!name_len)
-			return -FDT_ERR_BADOVERLAY;
-
-		poffset = strtoul(sep + 1, &endptr, 10);
-		if ((*endptr != '\0') || (endptr <= (sep + 1)))
-			return -FDT_ERR_BADOVERLAY;
-
-		ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off,
-						path, path_len, name, name_len,
-						poffset, label);
-		if (ret)
-			return ret;
-	} while (len > 0);
-
-	return 0;
-}
-
-/**
- * overlay_fixup_phandles - Resolve the overlay phandles to the base
- *                          device tree
- * @fdt: Base Device Tree blob
- * @fdto: Device tree overlay blob
- *
- * overlay_fixup_phandles() resolves all the overlay phandles pointing
- * to nodes in the base device tree.
- *
- * This is one of the steps of the device tree overlay application
- * process, when you want all the phandles in the overlay to point to
- * the actual base dt nodes.
- *
- * returns:
- *      0 on success
- *      Negative error code on failure
- */
-static int overlay_fixup_phandles(void *fdt, void *fdto)
-{
-	int fixups_off, symbols_off;
-	int property;
-
-	/* We can have overlays without any fixups */
-	fixups_off = fdt_path_offset(fdto, "/__fixups__");
-	if (fixups_off == -FDT_ERR_NOTFOUND)
-		return 0; /* nothing to do */
-	if (fixups_off < 0)
-		return fixups_off;
-
-	/* And base DTs without symbols */
-	symbols_off = fdt_path_offset(fdt, "/__symbols__");
-	if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND)))
-		return symbols_off;
-
-	fdt_for_each_property_offset(property, fdto, fixups_off) {
-		int ret;
-
-		ret = overlay_fixup_phandle(fdt, fdto, symbols_off, property);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
-/**
- * overlay_apply_node - Merges a node into the base device tree
- * @fdt: Base Device Tree blob
- * @target: Node offset in the base device tree to apply the fragment to
- * @fdto: Device tree overlay blob
- * @node: Node offset in the overlay holding the changes to merge
- *
- * overlay_apply_node() merges a node into a target base device tree
- * node pointed.
- *
- * This is part of the final step in the device tree overlay
- * application process, when all the phandles have been adjusted and
- * resolved and you just have to merge overlay into the base device
- * tree.
- *
- * returns:
- *      0 on success
- *      Negative error code on failure
- */
-static int overlay_apply_node(void *fdt, int target,
-			      void *fdto, int node)
-{
-	int property;
-	int subnode;
-
-	fdt_for_each_property_offset(property, fdto, node) {
-		const char *name;
-		const void *prop;
-		int prop_len;
-		int ret;
-
-		prop = fdt_getprop_by_offset(fdto, property, &name,
-					     &prop_len);
-		if (prop_len == -FDT_ERR_NOTFOUND)
-			return -FDT_ERR_INTERNAL;
-		if (prop_len < 0)
-			return prop_len;
-
-		ret = fdt_setprop(fdt, target, name, prop, prop_len);
-		if (ret)
-			return ret;
-	}
-
-	fdt_for_each_subnode(subnode, fdto, node) {
-		const char *name = fdt_get_name(fdto, subnode, NULL);
-		int nnode;
-		int ret;
-
-		nnode = fdt_add_subnode(fdt, target, name);
-		if (nnode == -FDT_ERR_EXISTS) {
-			nnode = fdt_subnode_offset(fdt, target, name);
-			if (nnode == -FDT_ERR_NOTFOUND)
-				return -FDT_ERR_INTERNAL;
-		}
-
-		if (nnode < 0)
-			return nnode;
-
-		ret = overlay_apply_node(fdt, nnode, fdto, subnode);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
-/**
- * overlay_merge - Merge an overlay into its base device tree
- * @fdt: Base Device Tree blob
- * @fdto: Device tree overlay blob
- *
- * overlay_merge() merges an overlay into its base device tree.
- *
- * This is the next to last step in the device tree overlay application
- * process, when all the phandles have been adjusted and resolved and
- * you just have to merge overlay into the base device tree.
- *
- * returns:
- *      0 on success
- *      Negative error code on failure
- */
-static int overlay_merge(void *fdt, void *fdto)
-{
-	int fragment;
-
-	fdt_for_each_subnode(fragment, fdto, 0) {
-		int overlay;
-		int target;
-		int ret;
-
-		/*
-		 * Each fragments will have an __overlay__ node. If
-		 * they don't, it's not supposed to be merged
-		 */
-		overlay = fdt_subnode_offset(fdto, fragment, "__overlay__");
-		if (overlay == -FDT_ERR_NOTFOUND)
-			continue;
-
-		if (overlay < 0)
-			return overlay;
-
-		target = overlay_get_target(fdt, fdto, fragment, NULL);
-		if (target < 0)
-			return target;
-
-		ret = overlay_apply_node(fdt, target, fdto, overlay);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
-static int get_path_len(const void *fdt, int nodeoffset)
-{
-	int len = 0, namelen;
-	const char *name;
-
-	FDT_CHECK_HEADER(fdt);
-
-	for (;;) {
-		name = fdt_get_name(fdt, nodeoffset, &namelen);
-		if (!name)
-			return namelen;
-
-		/* root? we're done */
-		if (namelen == 0)
-			break;
-
-		nodeoffset = fdt_parent_offset(fdt, nodeoffset);
-		if (nodeoffset < 0)
-			return nodeoffset;
-		len += namelen + 1;
-	}
-
-	/* in case of root pretend it's "/" */
-	if (len == 0)
-		len++;
-	return len;
-}
-
-/**
- * overlay_symbol_update - Update the symbols of base tree after a merge
- * @fdt: Base Device Tree blob
- * @fdto: Device tree overlay blob
- *
- * overlay_symbol_update() updates the symbols of the base tree with the
- * symbols of the applied overlay
- *
- * This is the last step in the device tree overlay application
- * process, allowing the reference of overlay symbols by subsequent
- * overlay operations.
- *
- * returns:
- *      0 on success
- *      Negative error code on failure
- */
-static int overlay_symbol_update(void *fdt, void *fdto)
-{
-	int root_sym, ov_sym, prop, path_len, fragment, target;
-	int len, frag_name_len, ret, rel_path_len;
-	const char *s, *e;
-	const char *path;
-	const char *name;
-	const char *frag_name;
-	const char *rel_path;
-	const char *target_path;
-	char *buf;
-	void *p;
-
-	ov_sym = fdt_subnode_offset(fdto, 0, "__symbols__");
-
-	/* if no overlay symbols exist no problem */
-	if (ov_sym < 0)
-		return 0;
-
-	root_sym = fdt_subnode_offset(fdt, 0, "__symbols__");
-
-	/* it no root symbols exist we should create them */
-	if (root_sym == -FDT_ERR_NOTFOUND)
-		root_sym = fdt_add_subnode(fdt, 0, "__symbols__");
-
-	/* any error is fatal now */
-	if (root_sym < 0)
-		return root_sym;
-
-	/* iterate over each overlay symbol */
-	fdt_for_each_property_offset(prop, fdto, ov_sym) {
-		path = fdt_getprop_by_offset(fdto, prop, &name, &path_len);
-		if (!path)
-			return path_len;
-
-		/* verify it's a string property (terminated by a single \0) */
-		if (path_len < 1 || memchr(path, '\0', path_len) != &path[path_len - 1])
-			return -FDT_ERR_BADVALUE;
-
-		/* keep end marker to avoid strlen() */
-		e = path + path_len;
-
-		/* format: /<fragment-name>/__overlay__/<relative-subnode-path> */
-
-		if (*path != '/')
-			return -FDT_ERR_BADVALUE;
-
-		/* get fragment name first */
-		s = strchr(path + 1, '/');
-		if (!s)
-			return -FDT_ERR_BADOVERLAY;
-
-		frag_name = path + 1;
-		frag_name_len = s - path - 1;
-
-		/* verify format; safe since "s" lies in \0 terminated prop */
-		len = sizeof("/__overlay__/") - 1;
-		if ((e - s) < len || memcmp(s, "/__overlay__/", len))
-			return -FDT_ERR_BADOVERLAY;
-
-		rel_path = s + len;
-		rel_path_len = e - rel_path;
-
-		/* find the fragment index in which the symbol lies */
-		ret = fdt_subnode_offset_namelen(fdto, 0, frag_name,
-					       frag_name_len);
-		/* not found? */
-		if (ret < 0)
-			return -FDT_ERR_BADOVERLAY;
-		fragment = ret;
-
-		/* an __overlay__ subnode must exist */
-		ret = fdt_subnode_offset(fdto, fragment, "__overlay__");
-		if (ret < 0)
-			return -FDT_ERR_BADOVERLAY;
-
-		/* get the target of the fragment */
-		ret = overlay_get_target(fdt, fdto, fragment, &target_path);
-		if (ret < 0)
-			return ret;
-		target = ret;
-
-		/* if we have a target path use */
-		if (!target_path) {
-			ret = get_path_len(fdt, target);
-			if (ret < 0)
-				return ret;
-			len = ret;
-		} else {
-			len = strlen(target_path);
-		}
-
-		ret = fdt_setprop_placeholder(fdt, root_sym, name,
-				len + (len > 1) + rel_path_len + 1, &p);
-		if (ret < 0)
-			return ret;
-
-		if (!target_path) {
-			/* again in case setprop_placeholder changed it */
-			ret = overlay_get_target(fdt, fdto, fragment, &target_path);
-			if (ret < 0)
-				return ret;
-			target = ret;
-		}
-
-		buf = p;
-		if (len > 1) { /* target is not root */
-			if (!target_path) {
-				ret = fdt_get_path(fdt, target, buf, len + 1);
-				if (ret < 0)
-					return ret;
-			} else
-				memcpy(buf, target_path, len + 1);
-
-		} else
-			len--;
-
-		buf[len] = '/';
-		memcpy(buf + len + 1, rel_path, rel_path_len);
-		buf[len + 1 + rel_path_len] = '\0';
-	}
-
-	return 0;
-}
-
-int fdt_overlay_apply(void *fdt, void *fdto)
-{
-	uint32_t delta = fdt_get_max_phandle(fdt);
-	int ret;
-
-	FDT_CHECK_HEADER(fdt);
-	FDT_CHECK_HEADER(fdto);
-
-	ret = overlay_adjust_local_phandles(fdto, delta);
-	if (ret)
-		goto err;
-
-	ret = overlay_update_local_references(fdto, delta);
-	if (ret)
-		goto err;
-
-	ret = overlay_fixup_phandles(fdt, fdto);
-	if (ret)
-		goto err;
-
-	ret = overlay_merge(fdt, fdto);
-	if (ret)
-		goto err;
-
-	ret = overlay_symbol_update(fdt, fdto);
-	if (ret)
-		goto err;
-
-	/*
-	 * The overlay has been damaged, erase its magic.
-	 */
-	fdt_set_magic(fdto, ~0);
-
-	return 0;
-
-err:
-	/*
-	 * The overlay might have been damaged, erase its magic.
-	 */
-	fdt_set_magic(fdto, ~0);
-
-	/*
-	 * The base device tree might have been damaged, erase its
-	 * magic.
-	 */
-	fdt_set_magic(fdt, ~0);
-
-	return ret;
-}
+#include <linux/libfdt_env.h>
+#include "../../scripts/dtc/libfdt/fdt_overlay.c"
diff --git a/lib/libfdt/fdt_strerror.c b/lib/libfdt/fdt_strerror.c
index f89004c..408a883 100644
--- a/lib/libfdt/fdt_strerror.c
+++ b/lib/libfdt/fdt_strerror.c
@@ -1,61 +1,2 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- * SPDX-License-Identifier:	GPL-2.0+ BSD-2-Clause
- */
-#include <libfdt_env.h>
-
-#ifndef USE_HOSTCC
-#include <fdt.h>
-#include <libfdt.h>
-#else
-#include "fdt_host.h"
-#endif
-
-#include "libfdt_internal.h"
-
-struct fdt_errtabent {
-	const char *str;
-};
-
-#define FDT_ERRTABENT(val) \
-	[(val)] = { .str = #val, }
-
-static struct fdt_errtabent fdt_errtable[] = {
-	FDT_ERRTABENT(FDT_ERR_NOTFOUND),
-	FDT_ERRTABENT(FDT_ERR_EXISTS),
-	FDT_ERRTABENT(FDT_ERR_NOSPACE),
-
-	FDT_ERRTABENT(FDT_ERR_BADOFFSET),
-	FDT_ERRTABENT(FDT_ERR_BADPATH),
-	FDT_ERRTABENT(FDT_ERR_BADPHANDLE),
-	FDT_ERRTABENT(FDT_ERR_BADSTATE),
-
-	FDT_ERRTABENT(FDT_ERR_TRUNCATED),
-	FDT_ERRTABENT(FDT_ERR_BADMAGIC),
-	FDT_ERRTABENT(FDT_ERR_BADVERSION),
-	FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),
-	FDT_ERRTABENT(FDT_ERR_BADLAYOUT),
-	FDT_ERRTABENT(FDT_ERR_INTERNAL),
-	FDT_ERRTABENT(FDT_ERR_BADNCELLS),
-	FDT_ERRTABENT(FDT_ERR_BADVALUE),
-	FDT_ERRTABENT(FDT_ERR_BADOVERLAY),
-	FDT_ERRTABENT(FDT_ERR_NOPHANDLES),
-};
-#define FDT_ERRTABSIZE	(sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
-
-const char *fdt_strerror(int errval)
-{
-	if (errval > 0)
-		return "<valid offset/length>";
-	else if (errval == 0)
-		return "<no error>";
-	else if (errval > -FDT_ERRTABSIZE) {
-		const char *s = fdt_errtable[-errval].str;
-
-		if (s)
-			return s;
-	}
-
-	return "<unknown error>";
-}
+#include <linux/libfdt_env.h>
+#include "../../scripts/dtc/libfdt/fdt_strerror.c"
diff --git a/lib/libfdt/fdt_sw.c b/lib/libfdt/fdt_sw.c
index 70fd026..0da3ed9 100644
--- a/lib/libfdt/fdt_sw.c
+++ b/lib/libfdt/fdt_sw.c
@@ -1,254 +1,2 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- * SPDX-License-Identifier:	GPL-2.0+ BSD-2-Clause
- */
-#include <libfdt_env.h>
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-static int _fdt_sw_check_header(void *fdt)
-{
-	if (fdt_magic(fdt) != FDT_SW_MAGIC)
-		return -FDT_ERR_BADMAGIC;
-	/* FIXME: should check more details about the header state */
-	return 0;
-}
-
-#define FDT_SW_CHECK_HEADER(fdt) \
-	{ \
-		int err; \
-		if ((err = _fdt_sw_check_header(fdt)) != 0) \
-			return err; \
-	}
-
-static void *_fdt_grab_space(void *fdt, size_t len)
-{
-	int offset = fdt_size_dt_struct(fdt);
-	int spaceleft;
-
-	spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
-		- fdt_size_dt_strings(fdt);
-
-	if ((offset + len < offset) || (offset + len > spaceleft))
-		return NULL;
-
-	fdt_set_size_dt_struct(fdt, offset + len);
-	return _fdt_offset_ptr_w(fdt, offset);
-}
-
-int fdt_create(void *buf, int bufsize)
-{
-	void *fdt = buf;
-
-	if (bufsize < sizeof(struct fdt_header))
-		return -FDT_ERR_NOSPACE;
-
-	memset(buf, 0, bufsize);
-
-	fdt_set_magic(fdt, FDT_SW_MAGIC);
-	fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
-	fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
-	fdt_set_totalsize(fdt,  bufsize);
-
-	fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header),
-					      sizeof(struct fdt_reserve_entry)));
-	fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
-	fdt_set_off_dt_strings(fdt, bufsize);
-
-	return 0;
-}
-
-int fdt_resize(void *fdt, void *buf, int bufsize)
-{
-	size_t headsize, tailsize;
-	char *oldtail, *newtail;
-
-	FDT_SW_CHECK_HEADER(fdt);
-
-	headsize = fdt_off_dt_struct(fdt);
-	tailsize = fdt_size_dt_strings(fdt);
-
-	if ((headsize + tailsize) > bufsize)
-		return -FDT_ERR_NOSPACE;
-
-	oldtail = (char *)fdt + fdt_totalsize(fdt) - tailsize;
-	newtail = (char *)buf + bufsize - tailsize;
-
-	/* Two cases to avoid clobbering data if the old and new
-	 * buffers partially overlap */
-	if (buf <= fdt) {
-		memmove(buf, fdt, headsize);
-		memmove(newtail, oldtail, tailsize);
-	} else {
-		memmove(newtail, oldtail, tailsize);
-		memmove(buf, fdt, headsize);
-	}
-
-	fdt_set_off_dt_strings(buf, bufsize);
-	fdt_set_totalsize(buf, bufsize);
-
-	return 0;
-}
-
-int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
-{
-	struct fdt_reserve_entry *re;
-	int offset;
-
-	FDT_SW_CHECK_HEADER(fdt);
-
-	if (fdt_size_dt_struct(fdt))
-		return -FDT_ERR_BADSTATE;
-
-	offset = fdt_off_dt_struct(fdt);
-	if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
-		return -FDT_ERR_NOSPACE;
-
-	re = (struct fdt_reserve_entry *)((char *)fdt + offset);
-	re->address = cpu_to_fdt64(addr);
-	re->size = cpu_to_fdt64(size);
-
-	fdt_set_off_dt_struct(fdt, offset + sizeof(*re));
-
-	return 0;
-}
-
-int fdt_finish_reservemap(void *fdt)
-{
-	return fdt_add_reservemap_entry(fdt, 0, 0);
-}
-
-int fdt_begin_node(void *fdt, const char *name)
-{
-	struct fdt_node_header *nh;
-	int namelen = strlen(name) + 1;
-
-	FDT_SW_CHECK_HEADER(fdt);
-
-	nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
-	if (! nh)
-		return -FDT_ERR_NOSPACE;
-
-	nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
-	memcpy(nh->name, name, namelen);
-	return 0;
-}
-
-int fdt_end_node(void *fdt)
-{
-	fdt32_t *en;
-
-	FDT_SW_CHECK_HEADER(fdt);
-
-	en = _fdt_grab_space(fdt, FDT_TAGSIZE);
-	if (! en)
-		return -FDT_ERR_NOSPACE;
-
-	*en = cpu_to_fdt32(FDT_END_NODE);
-	return 0;
-}
-
-static int _fdt_find_add_string(void *fdt, const char *s)
-{
-	char *strtab = (char *)fdt + fdt_totalsize(fdt);
-	const char *p;
-	int strtabsize = fdt_size_dt_strings(fdt);
-	int len = strlen(s) + 1;
-	int struct_top, offset;
-
-	p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
-	if (p)
-		return p - strtab;
-
-	/* Add it */
-	offset = -strtabsize - len;
-	struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
-	if (fdt_totalsize(fdt) + offset < struct_top)
-		return 0; /* no more room :( */
-
-	memcpy(strtab + offset, s, len);
-	fdt_set_size_dt_strings(fdt, strtabsize + len);
-	return offset;
-}
-
-int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp)
-{
-	struct fdt_property *prop;
-	int nameoff;
-
-	FDT_SW_CHECK_HEADER(fdt);
-
-	nameoff = _fdt_find_add_string(fdt, name);
-	if (nameoff == 0)
-		return -FDT_ERR_NOSPACE;
-
-	prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
-	if (! prop)
-		return -FDT_ERR_NOSPACE;
-
-	prop->tag = cpu_to_fdt32(FDT_PROP);
-	prop->nameoff = cpu_to_fdt32(nameoff);
-	prop->len = cpu_to_fdt32(len);
-	*valp = prop->data;
-	return 0;
-}
-
-int fdt_property(void *fdt, const char *name, const void *val, int len)
-{
-	void *ptr;
-	int ret;
-
-	ret = fdt_property_placeholder(fdt, name, len, &ptr);
-	if (ret)
-		return ret;
-	memcpy(ptr, val, len);
-	return 0;
-}
-
-int fdt_finish(void *fdt)
-{
-	char *p = (char *)fdt;
-	fdt32_t *end;
-	int oldstroffset, newstroffset;
-	uint32_t tag;
-	int offset, nextoffset;
-
-	FDT_SW_CHECK_HEADER(fdt);
-
-	/* Add terminator */
-	end = _fdt_grab_space(fdt, sizeof(*end));
-	if (! end)
-		return -FDT_ERR_NOSPACE;
-	*end = cpu_to_fdt32(FDT_END);
-
-	/* Relocate the string table */
-	oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
-	newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
-	memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
-	fdt_set_off_dt_strings(fdt, newstroffset);
-
-	/* Walk the structure, correcting string offsets */
-	offset = 0;
-	while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
-		if (tag == FDT_PROP) {
-			struct fdt_property *prop =
-				_fdt_offset_ptr_w(fdt, offset);
-			int nameoff;
-
-			nameoff = fdt32_to_cpu(prop->nameoff);
-			nameoff += fdt_size_dt_strings(fdt);
-			prop->nameoff = cpu_to_fdt32(nameoff);
-		}
-		offset = nextoffset;
-	}
-	if (nextoffset < 0)
-		return nextoffset;
-
-	/* Finally, adjust the header */
-	fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
-	fdt_set_magic(fdt, FDT_MAGIC);
-	return 0;
-}
+#include <linux/libfdt_env.h>
+#include "../../scripts/dtc/libfdt/fdt_sw.c"
diff --git a/lib/libfdt/libfdt_internal.h b/lib/libfdt/libfdt_internal.h
index 9a79fe8..5197c5d 100644
--- a/lib/libfdt/libfdt_internal.h
+++ b/lib/libfdt/libfdt_internal.h
@@ -1,50 +1 @@
-#ifndef _LIBFDT_INTERNAL_H
-#define _LIBFDT_INTERNAL_H
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- * SPDX-License-Identifier:	GPL-2.0+ BSD-2-Clause
- */
-#include <fdt.h>
-
-#define FDT_ALIGN(x, a)		(((x) + (a) - 1) & ~((a) - 1))
-#define FDT_TAGALIGN(x)		(FDT_ALIGN((x), FDT_TAGSIZE))
-
-#define FDT_CHECK_HEADER(fdt) \
-	{ \
-		int __err; \
-		if ((__err = fdt_check_header(fdt)) != 0) \
-			return __err; \
-	}
-
-int _fdt_check_node_offset(const void *fdt, int offset);
-int _fdt_check_prop_offset(const void *fdt, int offset);
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
-int _fdt_node_end_offset(void *fdt, int nodeoffset);
-
-static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
-{
-	return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
-}
-
-static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
-{
-	return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
-}
-
-static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
-{
-	const struct fdt_reserve_entry *rsv_table =
-		(const struct fdt_reserve_entry *)
-		((const char *)fdt + fdt_off_mem_rsvmap(fdt));
-
-	return rsv_table + n;
-}
-static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
-{
-	return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
-}
-
-#define FDT_SW_MAGIC		(~FDT_MAGIC)
-
-#endif /* _LIBFDT_INTERNAL_H */
+#include "../../scripts/dtc/libfdt/libfdt_internal.h"
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index 49b27ac..ca04476 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -257,7 +257,7 @@
 $(obj)/$(SPL_BIN).dtb: dts/dt.dtb $(objtree)/tools/fdtgrep FORCE
 	$(call if_changed,fdtgrep)
 
-pythonpath = PYTHONPATH=tools
+pythonpath = PYTHONPATH=scripts/dtc/pylibfdt
 
 quiet_cmd_dtocc = DTOC C  $@
 cmd_dtocc = $(pythonpath) $(srctree)/tools/dtoc/dtoc -d $(obj)/$(SPL_BIN).dtb -o $@ platdata
@@ -276,10 +276,10 @@
 dts_dir:
 	$(shell [ -d $(obj)/dts ] || mkdir -p $(obj)/dts)
 
-include/generated/dt-structs-gen.h: $(obj)/$(SPL_BIN).dtb dts_dir checkdtoc
+include/generated/dt-structs-gen.h: $(obj)/$(SPL_BIN).dtb dts_dir FORCE
 	$(call if_changed,dtoch)
 
-$(obj)/dts/dt-platdata.c: $(obj)/$(SPL_BIN).dtb dts_dir checkdtoc
+$(obj)/dts/dt-platdata.c: $(obj)/$(SPL_BIN).dtb dts_dir FORCE
 	$(call if_changed,dtocc)
 
 ifdef CONFIG_SAMSUNG
@@ -380,17 +380,6 @@
   include $(cmd_files)
 endif
 
-checkdtoc: tools
-	@if ! ( echo 'import libfdt' | ( PYTHONPATH=tools $(PYTHON) )); then \
-		echo '*** dtoc needs the Python libfdt library. Either '; \
-		echo '*** install it on your system, or try:'; \
-		echo '***'; \
-		echo '*** sudo apt-get install swig libpython-dev'; \
-		echo '***'; \
-		echo '*** to have U-Boot build its own version.'; \
-		false; \
-	fi
-
 PHONY += FORCE
 FORCE:
 
diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile
index 2a48022..90ef2db 100644
--- a/scripts/dtc/Makefile
+++ b/scripts/dtc/Makefile
@@ -29,3 +29,6 @@
 
 # generated files need to be cleaned explicitly
 clean-files	:= dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h
+
+# Added for U-Boot
+subdir-$(CONFIG_PYLIBFDT) += pylibfdt
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
index afabf64..08a3a29 100644
--- a/scripts/dtc/checks.c
+++ b/scripts/dtc/checks.c
@@ -956,6 +956,265 @@
 WARNING(obsolete_chosen_interrupt_controller,
 	check_obsolete_chosen_interrupt_controller, NULL);
 
+struct provider {
+	const char *prop_name;
+	const char *cell_name;
+	bool optional;
+};
+
+static void check_property_phandle_args(struct check *c,
+					  struct dt_info *dti,
+				          struct node *node,
+				          struct property *prop,
+				          const struct provider *provider)
+{
+	struct node *root = dti->dt;
+	int cell, cellsize = 0;
+
+	if (prop->val.len % sizeof(cell_t)) {
+		FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s",
+		     prop->name, prop->val.len, sizeof(cell_t), node->fullpath);
+		return;
+	}
+
+	for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) {
+		struct node *provider_node;
+		struct property *cellprop;
+		int phandle;
+
+		phandle = propval_cell_n(prop, cell);
+		/*
+		 * Some bindings use a cell value 0 or -1 to skip over optional
+		 * entries when each index position has a specific definition.
+		 */
+		if (phandle == 0 || phandle == -1) {
+			cellsize = 0;
+			continue;
+		}
+
+		/* If we have markers, verify the current cell is a phandle */
+		if (prop->val.markers) {
+			struct marker *m = prop->val.markers;
+			for_each_marker_of_type(m, REF_PHANDLE) {
+				if (m->offset == (cell * sizeof(cell_t)))
+					break;
+			}
+			if (!m)
+				FAIL(c, dti, "Property '%s', cell %d is not a phandle reference in %s",
+				     prop->name, cell, node->fullpath);
+		}
+
+		provider_node = get_node_by_phandle(root, phandle);
+		if (!provider_node) {
+			FAIL(c, dti, "Could not get phandle node for %s:%s(cell %d)",
+			     node->fullpath, prop->name, cell);
+			break;
+		}
+
+		cellprop = get_property(provider_node, provider->cell_name);
+		if (cellprop) {
+			cellsize = propval_cell(cellprop);
+		} else if (provider->optional) {
+			cellsize = 0;
+		} else {
+			FAIL(c, dti, "Missing property '%s' in node %s or bad phandle (referred from %s:%s[%d])",
+			     provider->cell_name,
+			     provider_node->fullpath,
+			     node->fullpath, prop->name, cell);
+			break;
+		}
+
+		if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) {
+			FAIL(c, dti, "%s property size (%d) too small for cell size %d in %s",
+			     prop->name, prop->val.len, cellsize, node->fullpath);
+		}
+	}
+}
+
+static void check_provider_cells_property(struct check *c,
+					  struct dt_info *dti,
+				          struct node *node)
+{
+	struct provider *provider = c->data;
+	struct property *prop;
+
+	prop = get_property(node, provider->prop_name);
+	if (!prop)
+		return;
+
+	check_property_phandle_args(c, dti, node, prop, provider);
+}
+#define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \
+	static struct provider nm##_provider = { (propname), (cells_name), __VA_ARGS__ }; \
+	WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &phandle_references);
+
+WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(dmas, "dmas", "#dma-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(hwlocks, "hwlocks", "#hwlock-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(interrupts_extended, "interrupts-extended", "#interrupt-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(io_channels, "io-channels", "#io-channel-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(iommus, "iommus", "#iommu-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(mboxes, "mboxes", "#mbox-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(msi_parent, "msi-parent", "#msi-cells", true);
+WARNING_PROPERTY_PHANDLE_CELLS(mux_controls, "mux-controls", "#mux-control-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(sound_dais, "sound-dais", "#sound-dai-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells");
+
+static bool prop_is_gpio(struct property *prop)
+{
+	char *str;
+
+	/*
+	 * *-gpios and *-gpio can appear in property names,
+	 * so skip over any false matches (only one known ATM)
+	 */
+	if (strstr(prop->name, "nr-gpio"))
+		return false;
+
+	str = strrchr(prop->name, '-');
+	if (str)
+		str++;
+	else
+		str = prop->name;
+	if (!(streq(str, "gpios") || streq(str, "gpio")))
+		return false;
+
+	return true;
+}
+
+static void check_gpios_property(struct check *c,
+					  struct dt_info *dti,
+				          struct node *node)
+{
+	struct property *prop;
+
+	/* Skip GPIO hog nodes which have 'gpios' property */
+	if (get_property(node, "gpio-hog"))
+		return;
+
+	for_each_property(node, prop) {
+		struct provider provider;
+
+		if (!prop_is_gpio(prop))
+			continue;
+
+		provider.prop_name = prop->name;
+		provider.cell_name = "#gpio-cells";
+		provider.optional = false;
+		check_property_phandle_args(c, dti, node, prop, &provider);
+	}
+
+}
+WARNING(gpios_property, check_gpios_property, NULL, &phandle_references);
+
+static void check_deprecated_gpio_property(struct check *c,
+					   struct dt_info *dti,
+				           struct node *node)
+{
+	struct property *prop;
+
+	for_each_property(node, prop) {
+		char *str;
+
+		if (!prop_is_gpio(prop))
+			continue;
+
+		str = strstr(prop->name, "gpio");
+		if (!streq(str, "gpio"))
+			continue;
+
+		FAIL(c, dti, "'[*-]gpio' is deprecated, use '[*-]gpios' instead for %s:%s",
+		     node->fullpath, prop->name);
+	}
+
+}
+CHECK(deprecated_gpio_property, check_deprecated_gpio_property, NULL);
+
+static bool node_is_interrupt_provider(struct node *node)
+{
+	struct property *prop;
+
+	prop = get_property(node, "interrupt-controller");
+	if (prop)
+		return true;
+
+	prop = get_property(node, "interrupt-map");
+	if (prop)
+		return true;
+
+	return false;
+}
+static void check_interrupts_property(struct check *c,
+				      struct dt_info *dti,
+				      struct node *node)
+{
+	struct node *root = dti->dt;
+	struct node *irq_node = NULL, *parent = node;
+	struct property *irq_prop, *prop = NULL;
+	int irq_cells, phandle;
+
+	irq_prop = get_property(node, "interrupts");
+	if (!irq_prop)
+		return;
+
+	if (irq_prop->val.len % sizeof(cell_t))
+		FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s",
+		     irq_prop->name, irq_prop->val.len, sizeof(cell_t),
+		     node->fullpath);
+
+	while (parent && !prop) {
+		if (parent != node && node_is_interrupt_provider(parent)) {
+			irq_node = parent;
+			break;
+		}
+
+		prop = get_property(parent, "interrupt-parent");
+		if (prop) {
+			phandle = propval_cell(prop);
+			irq_node = get_node_by_phandle(root, phandle);
+			if (!irq_node) {
+				FAIL(c, dti, "Bad interrupt-parent phandle for %s",
+				     node->fullpath);
+				return;
+			}
+			if (!node_is_interrupt_provider(irq_node))
+				FAIL(c, dti,
+				     "Missing interrupt-controller or interrupt-map property in %s",
+				     irq_node->fullpath);
+
+			break;
+		}
+
+		parent = parent->parent;
+	}
+
+	if (!irq_node) {
+		FAIL(c, dti, "Missing interrupt-parent for %s", node->fullpath);
+		return;
+	}
+
+	prop = get_property(irq_node, "#interrupt-cells");
+	if (!prop) {
+		FAIL(c, dti, "Missing #interrupt-cells in interrupt-parent %s",
+		     irq_node->fullpath);
+		return;
+	}
+
+	irq_cells = propval_cell(prop);
+	if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) {
+		FAIL(c, dti,
+		     "interrupts size is (%d), expected multiple of %d in %s",
+		     irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)),
+		     node->fullpath);
+	}
+}
+WARNING(interrupts_property, check_interrupts_property, &phandle_references);
+
 static struct check *check_table[] = {
 	&duplicate_node_names, &duplicate_property_names,
 	&node_name_chars, &node_name_format, &property_name_chars,
@@ -987,6 +1246,27 @@
 	&avoid_default_addr_size,
 	&obsolete_chosen_interrupt_controller,
 
+	&clocks_property,
+	&cooling_device_property,
+	&dmas_property,
+	&hwlocks_property,
+	&interrupts_extended_property,
+	&io_channels_property,
+	&iommus_property,
+	&mboxes_property,
+	&msi_parent_property,
+	&mux_controls_property,
+	&phys_property,
+	&power_domains_property,
+	&pwms_property,
+	&resets_property,
+	&sound_dais_property,
+	&thermal_sensors_property,
+
+	&deprecated_gpio_property,
+	&gpios_property,
+	&interrupts_property,
+
 	&always_fail,
 };
 
diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped
index 3934d86..011bb96 100644
--- a/scripts/dtc/dtc-lexer.lex.c_shipped
+++ b/scripts/dtc/dtc-lexer.lex.c_shipped
@@ -8,8 +8,8 @@
 
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 1
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
@@ -88,25 +88,13 @@
 
 #endif /* ! FLEXINT_H */
 
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else	/* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif	/* defined (__STDC__) */
-#endif	/* ! __cplusplus */
-
-#ifdef YY_USE_CONST
+/* TODO: this is always defined, so inline it */
 #define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
 #else
-#define yyconst
+#define yynoreturn
 #endif
 
 /* Returned upon end-of-file. */
@@ -162,6 +150,11 @@
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 #endif
 
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
 extern int yyleng;
 
 extern FILE *yyin, *yyout;
@@ -171,6 +164,7 @@
 #define EOB_ACT_LAST_MATCH 2
 
     #define YY_LESS_LINENO(n)
+    #define YY_LINENO_REWIND_TO(ptr)
     
 /* Return all but the first "n" matched characters back to the input stream. */
 #define yyless(n) \
@@ -188,11 +182,6 @@
 
 #define unput(c) yyunput( c, (yytext_ptr)  )
 
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
@@ -205,7 +194,7 @@
 	/* Size of input buffer in bytes, not including room for EOB
 	 * characters.
 	 */
-	yy_size_t yy_buf_size;
+	int yy_buf_size;
 
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
@@ -233,7 +222,7 @@
 
     int yy_bs_lineno; /**< The line count. */
     int yy_bs_column; /**< The column count. */
-    
+
 	/* Whether to try to fill the input buffer when we reach the
 	 * end of it.
 	 */
@@ -261,7 +250,7 @@
 /* Stack of input buffers. */
 static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
 static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
 
 /* We provide macros for accessing buffer states in case in the
  * future we want to put the buffer states in a more general
@@ -284,7 +273,7 @@
 int yyleng;
 
 /* Points to current character in buffer. */
-static char *yy_c_buf_p = (char *) 0;
+static char *yy_c_buf_p = NULL;
 static int yy_init = 0;		/* whether we need to initialize */
 static int yy_start = 0;	/* start state number */
 
@@ -341,12 +330,12 @@
 
 /* Begin user sect3 */
 
-#define yywrap(n) 1
+#define yywrap() (/*CONSTCOND*/1)
 #define YY_SKIP_YYWRAP
 
 typedef unsigned char YY_CHAR;
 
-FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+FILE *yyin = NULL, *yyout = NULL;
 
 typedef int yy_state_type;
 
@@ -355,19 +344,22 @@
 int yylineno = 1;
 
 extern char *yytext;
+#ifdef yytext_ptr
+#undef yytext_ptr
+#endif
 #define yytext_ptr yytext
 
 static yy_state_type yy_get_previous_state (void );
 static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
 static int yy_get_next_buffer (void );
-static void yy_fatal_error (yyconst char msg[]  );
+static void yynoreturn yy_fatal_error (yyconst char* msg  );
 
 /* Done after the current pattern has been matched and before the
  * corresponding action - sets up yytext.
  */
 #define YY_DO_BEFORE_ACTION \
 	(yytext_ptr) = yy_bp; \
-	yyleng = (size_t) (yy_cp - yy_bp); \
+	yyleng = (int) (yy_cp - yy_bp); \
 	(yy_hold_char) = *yy_cp; \
 	*yy_cp = '\0'; \
 	(yy_c_buf_p) = yy_cp;
@@ -403,7 +395,7 @@
         0,    0,    0,    8,    0
     } ;
 
-static yyconst flex_int32_t yy_ec[256] =
+static yyconst YY_CHAR yy_ec[256] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         4,    4,    4,    1,    1,    1,    1,    1,    1,    1,
@@ -435,7 +427,7 @@
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[48] =
+static yyconst YY_CHAR yy_meta[48] =
     {   0,
         1,    1,    1,    1,    1,    1,    2,    3,    1,    2,
         2,    2,    4,    5,    5,    5,    6,    1,    1,    1,
@@ -444,7 +436,7 @@
         8,    8,    8,    8,    3,    1,    4
     } ;
 
-static yyconst flex_int16_t yy_base[180] =
+static yyconst flex_uint16_t yy_base[180] =
     {   0,
         0,  393,   35,  392,   66,  391,   38,  107,  397,  401,
        55,  113,  377,  112,  111,  111,  114,   42,  376,  106,
@@ -490,7 +482,7 @@
       165,  165,  165,  165,  165,  165,  165,  165,  165
     } ;
 
-static yyconst flex_int16_t yy_nxt[449] =
+static yyconst flex_uint16_t yy_nxt[449] =
     {   0,
        10,   11,   12,   11,   13,   14,   10,   15,   16,   10,
        10,   10,   17,   10,   10,   10,   10,   18,   19,   20,
@@ -665,7 +657,7 @@
 static bool pop_input_file(void);
 static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
 
-#line 669 "dtc-lexer.lex.c"
+#line 661 "dtc-lexer.lex.c"
 
 #define INITIAL 0
 #define BYTESTRING 1
@@ -701,19 +693,19 @@
 
 FILE *yyget_in (void );
 
-void yyset_in  (FILE * in_str  );
+void yyset_in  (FILE * _in_str  );
 
 FILE *yyget_out (void );
 
-void yyset_out  (FILE * out_str  );
+void yyset_out  (FILE * _out_str  );
 
-int yyget_leng (void );
+			int yyget_leng (void );
 
 char *yyget_text (void );
 
 int yyget_lineno (void );
 
-void yyset_lineno (int line_number  );
+void yyset_lineno (int _line_number  );
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -727,6 +719,10 @@
 #endif
 #endif
 
+#ifndef YY_NO_UNPUT
+    
+#endif
+
 #ifndef yytext_ptr
 static void yy_flex_strncpy (char *,yyconst char *,int );
 #endif
@@ -760,7 +756,7 @@
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -784,7 +780,7 @@
 	else \
 		{ \
 		errno=0; \
-		while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+		while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
 			{ \
 			if( errno != EINTR) \
 				{ \
@@ -839,7 +835,7 @@
 
 /* Code executed at the end of each rule. */
 #ifndef YY_BREAK
-#define YY_BREAK break;
+#define YY_BREAK /*LINTED*/break;
 #endif
 
 #define YY_RULE_SETUP \
@@ -852,14 +848,10 @@
  */
 YY_DECL
 {
-	register yy_state_type yy_current_state;
-	register char *yy_cp, *yy_bp;
-	register int yy_act;
+	yy_state_type yy_current_state;
+	char *yy_cp, *yy_bp;
+	int yy_act;
     
-#line 69 "dtc-lexer.l"
-
-#line 862 "dtc-lexer.lex.c"
-
 	if ( !(yy_init) )
 		{
 		(yy_init) = 1;
@@ -886,7 +878,12 @@
 		yy_load_buffer_state( );
 		}
 
+	{
+#line 69 "dtc-lexer.l"
+
-	while ( 1 )		/* loops until end-of-file is reached */
+#line 885 "dtc-lexer.lex.c"
+
+	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
 		yy_cp = (yy_c_buf_p);
 
@@ -903,7 +900,7 @@
 yy_match:
 		do
 			{
-			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
 			if ( yy_accept[yy_current_state] )
 				{
 				(yy_last_accepting_state) = yy_current_state;
@@ -915,7 +912,7 @@
 				if ( yy_current_state >= 166 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
-			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
 			++yy_cp;
 			}
 		while ( yy_current_state != 165 );
@@ -1256,7 +1253,7 @@
 #line 272 "dtc-lexer.l"
 ECHO;
 	YY_BREAK
-#line 1260 "dtc-lexer.lex.c"
+#line 1257 "dtc-lexer.lex.c"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -1386,6 +1383,7 @@
 			"fatal flex scanner internal error--no action found" );
 	} /* end of action switch */
 		} /* end of scanning one token */
+	} /* end of user's declarations */
 } /* end of yylex */
 
 /* yy_get_next_buffer - try to read in a new buffer
@@ -1397,9 +1395,9 @@
  */
 static int yy_get_next_buffer (void)
 {
-    	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
-	register char *source = (yytext_ptr);
-	register int number_to_move, i;
+    	char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+	char *source = (yytext_ptr);
+	int number_to_move, i;
 	int ret_val;
 
 	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
@@ -1428,7 +1426,7 @@
 	/* Try to read more data. */
 
 	/* First move last chars to start of buffer. */
-	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
 
 	for ( i = 0; i < number_to_move; ++i )
 		*(dest++) = *(source++);
@@ -1448,7 +1446,7 @@
 			{ /* Not enough room in the buffer - grow it. */
 
 			/* just a shorter name for the current buffer */
-			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
 
 			int yy_c_buf_p_offset =
 				(int) ((yy_c_buf_p) - b->yy_ch_buf);
@@ -1468,7 +1466,7 @@
 				}
 			else
 				/* Can't grow it, we don't own it. */
-				b->yy_ch_buf = 0;
+				b->yy_ch_buf = NULL;
 
 			if ( ! b->yy_ch_buf )
 				YY_FATAL_ERROR(
@@ -1486,7 +1484,7 @@
 
 		/* Read in more data. */
 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			(yy_n_chars), (size_t) num_to_read );
+			(yy_n_chars), num_to_read );
 
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
 		}
@@ -1510,9 +1508,9 @@
 	else
 		ret_val = EOB_ACT_CONTINUE_SCAN;
 
-	if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+	if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
 		/* Extend the array by 50%, plus the number we really need. */
-		yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+		int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
 		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
 		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
 			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
@@ -1531,15 +1529,15 @@
 
     static yy_state_type yy_get_previous_state (void)
 {
-	register yy_state_type yy_current_state;
-	register char *yy_cp;
+	yy_state_type yy_current_state;
+	char *yy_cp;
     
 	yy_current_state = (yy_start);
 	yy_current_state += YY_AT_BOL();
 
 	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
 		{
-		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
 		if ( yy_accept[yy_current_state] )
 			{
 			(yy_last_accepting_state) = yy_current_state;
@@ -1551,7 +1549,7 @@
 			if ( yy_current_state >= 166 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
-		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
 		}
 
 	return yy_current_state;
@@ -1564,10 +1562,10 @@
  */
     static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
 {
-	register int yy_is_jam;
-    	register char *yy_cp = (yy_c_buf_p);
+	int yy_is_jam;
+    	char *yy_cp = (yy_c_buf_p);
 
-	register YY_CHAR yy_c = 1;
+	YY_CHAR yy_c = 1;
 	if ( yy_accept[yy_current_state] )
 		{
 		(yy_last_accepting_state) = yy_current_state;
@@ -1579,12 +1577,16 @@
 		if ( yy_current_state >= 166 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
-	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
 	yy_is_jam = (yy_current_state == 165);
 
-	return yy_is_jam ? 0 : yy_current_state;
+		return yy_is_jam ? 0 : yy_current_state;
 }
 
+#ifndef YY_NO_UNPUT
+
+#endif
+
 #ifndef YY_NO_INPUT
 #ifdef __cplusplus
     static int yyinput (void)
@@ -1633,7 +1635,7 @@
 				case EOB_ACT_END_OF_FILE:
 					{
 					if ( yywrap( ) )
-						return EOF;
+						return 0;
 
 					if ( ! (yy_did_buffer_switch_on_eof) )
 						YY_NEW_FILE;
@@ -1736,7 +1738,7 @@
 	if ( ! b )
 		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
-	b->yy_buf_size = size;
+	b->yy_buf_size = (yy_size_t)size;
 
 	/* yy_ch_buf has to be 2 characters longer than the size given because
 	 * we need to put in 2 end-of-buffer characters.
@@ -1891,15 +1893,15 @@
 		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
 		 * immediate realloc on the next call.
          */
-		num_to_alloc = 1;
+      num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
 		(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
 								(num_to_alloc * sizeof(struct yy_buffer_state*)
 								);
 		if ( ! (yy_buffer_stack) )
 			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-								  
+
 		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-				
+
 		(yy_buffer_stack_max) = num_to_alloc;
 		(yy_buffer_stack_top) = 0;
 		return;
@@ -1908,7 +1910,7 @@
 	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
 
 		/* Increase the buffer to prepare for a possible push. */
-		int grow_size = 8 /* arbitrary grow size */;
+		yy_size_t grow_size = 8 /* arbitrary grow size */;
 
 		num_to_alloc = (yy_buffer_stack_max) + grow_size;
 		(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
@@ -1928,7 +1930,7 @@
  * @param base the character buffer
  * @param size the size in bytes of the character buffer
  * 
- * @return the newly allocated buffer state object. 
+ * @return the newly allocated buffer state object.
  */
 YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
 {
@@ -1938,7 +1940,7 @@
 	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
 	     base[size-1] != YY_END_OF_BUFFER_CHAR )
 		/* They forgot to leave room for the EOB's. */
-		return 0;
+		return NULL;
 
 	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
 	if ( ! b )
@@ -1947,7 +1949,7 @@
 	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
 	b->yy_buf_pos = b->yy_ch_buf = base;
 	b->yy_is_our_buffer = 0;
-	b->yy_input_file = 0;
+	b->yy_input_file = NULL;
 	b->yy_n_chars = b->yy_buf_size;
 	b->yy_is_interactive = 0;
 	b->yy_at_bol = 1;
@@ -1970,7 +1972,7 @@
 YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
 {
     
-	return yy_scan_bytes(yystr,strlen(yystr) );
+	return yy_scan_bytes(yystr,(int) strlen(yystr) );
 }
 
 /** Setup the input buffer state to scan the given bytes. The next call to yylex() will
@@ -1988,7 +1990,7 @@
 	int i;
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
-	n = _yybytes_len + 2;
+	n = (yy_size_t) (_yybytes_len + 2);
 	buf = (char *) yyalloc(n  );
 	if ( ! buf )
 		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
@@ -2014,9 +2016,9 @@
 #define YY_EXIT_FAILURE 2
 #endif
 
-static void yy_fatal_error (yyconst char* msg )
+static void yynoreturn yy_fatal_error (yyconst char* msg )
 {
-    	(void) fprintf( stderr, "%s\n", msg );
+			(void) fprintf( stderr, "%s\n", msg );
 	exit( YY_EXIT_FAILURE );
 }
 
@@ -2044,7 +2046,7 @@
  */
 int yyget_lineno  (void)
 {
-        
+    
     return yylineno;
 }
 
@@ -2082,29 +2084,29 @@
 }
 
 /** Set the current line number.
- * @param line_number
+ * @param _line_number line number
  * 
  */
-void yyset_lineno (int  line_number )
+void yyset_lineno (int  _line_number )
 {
     
-    yylineno = line_number;
+    yylineno = _line_number;
 }
 
 /** Set the input stream. This does not discard the current
  * input buffer.
- * @param in_str A readable stream.
+ * @param _in_str A readable stream.
  * 
  * @see yy_switch_to_buffer
  */
-void yyset_in (FILE *  in_str )
+void yyset_in (FILE *  _in_str )
 {
-        yyin = in_str ;
+        yyin = _in_str ;
 }
 
-void yyset_out (FILE *  out_str )
+void yyset_out (FILE *  _out_str )
 {
-        yyout = out_str ;
+        yyout = _out_str ;
 }
 
 int yyget_debug  (void)
@@ -2112,9 +2114,9 @@
         return yy_flex_debug;
 }
 
-void yyset_debug (int  bdebug )
+void yyset_debug (int  _bdebug )
 {
-        yy_flex_debug = bdebug ;
+        yy_flex_debug = _bdebug ;
 }
 
 static int yy_init_globals (void)
@@ -2123,10 +2125,10 @@
      * This function is called from yylex_destroy(), so don't allocate here.
      */
 
-    (yy_buffer_stack) = 0;
+    (yy_buffer_stack) = NULL;
     (yy_buffer_stack_top) = 0;
     (yy_buffer_stack_max) = 0;
-    (yy_c_buf_p) = (char *) 0;
+    (yy_c_buf_p) = NULL;
     (yy_init) = 0;
     (yy_start) = 0;
 
@@ -2135,8 +2137,8 @@
     yyin = stdin;
     yyout = stdout;
 #else
-    yyin = (FILE *) 0;
-    yyout = (FILE *) 0;
+    yyin = NULL;
+    yyout = NULL;
 #endif
 
     /* For future reference: Set errno on error, since we are called by
@@ -2174,7 +2176,8 @@
 #ifndef yytext_ptr
 static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
 {
-	register int i;
+		
+	int i;
 	for ( i = 0; i < n; ++i )
 		s1[i] = s2[i];
 }
@@ -2183,7 +2186,7 @@
 #ifdef YY_NEED_STRLEN
 static int yy_flex_strlen (yyconst char * s )
 {
-	register int n;
+	int n;
 	for ( n = 0; s[n]; ++n )
 		;
 
@@ -2193,11 +2196,12 @@
 
 void *yyalloc (yy_size_t  size )
 {
-	return (void *) malloc( size );
+			return malloc(size);
 }
 
 void *yyrealloc  (void * ptr, yy_size_t  size )
 {
+		
 	/* The cast to (char *) in the following accommodates both
 	 * implementations that use char* generic pointers, and those
 	 * that use void* generic pointers.  It works with the latter
@@ -2205,12 +2209,12 @@
 	 * any pointer type to void*, and deal with argument conversions
 	 * as though doing an assignment.
 	 */
-	return (void *) realloc( (char *) ptr, size );
+	return realloc(ptr, size);
 }
 
 void yyfree (void * ptr )
 {
-	free( (char *) ptr );	/* see yyrealloc() for (char *) cast */
+			free( (char *) ptr );	/* see yyrealloc() for (char *) cast */
 }
 
 #define YYTABLES_NAME "yytables"
diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped
index 4d10814..aea514f 100644
--- a/scripts/dtc/dtc-parser.tab.c_shipped
+++ b/scripts/dtc/dtc-parser.tab.c_shipped
@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 3.0.2.  */
+/* A Bison parser, made by GNU Bison 3.0.4.  */
 
 /* Bison implementation for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -44,7 +44,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "3.0.2"
+#define YYBISON_VERSION "3.0.4"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -143,7 +143,7 @@
 
 /* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE YYSTYPE;
+
 union YYSTYPE
 {
 #line 39 "dtc-parser.y" /* yacc.c:355  */
@@ -168,6 +168,8 @@
 
 #line 170 "dtc-parser.tab.c" /* yacc.c:355  */
 };
+
+typedef union YYSTYPE YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define YYSTYPE_IS_DECLARED 1
 #endif
@@ -195,7 +197,7 @@
 
 /* Copy the second part of user declarations.  */
 
-#line 199 "dtc-parser.tab.c" /* yacc.c:358  */
+#line 201 "dtc-parser.tab.c" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -446,7 +448,7 @@
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  30
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  84
+#define YYNRULES  85
 /* YYNSTATES -- Number of states.  */
 #define YYNSTATES  149
 
@@ -497,14 +499,14 @@
 static const yytype_uint16 yyrline[] =
 {
        0,   109,   109,   117,   121,   128,   129,   139,   142,   149,
-     153,   161,   165,   170,   181,   191,   206,   214,   217,   224,
-     228,   232,   236,   244,   248,   252,   256,   260,   276,   286,
-     294,   297,   301,   308,   324,   329,   348,   362,   369,   370,
-     371,   378,   382,   383,   387,   388,   392,   393,   397,   398,
-     402,   403,   407,   408,   412,   413,   414,   418,   419,   420,
-     421,   422,   426,   427,   428,   432,   433,   434,   438,   439,
-     448,   457,   461,   462,   463,   464,   469,   472,   476,   484,
-     487,   491,   499,   503,   507
+     153,   161,   165,   170,   181,   200,   213,   220,   228,   231,
+     238,   242,   246,   250,   258,   262,   266,   270,   274,   290,
+     300,   308,   311,   315,   322,   338,   343,   362,   376,   383,
+     384,   385,   392,   396,   397,   401,   402,   406,   407,   411,
+     412,   416,   417,   421,   422,   426,   427,   428,   432,   433,
+     434,   435,   436,   440,   441,   442,   446,   447,   448,   452,
+     453,   462,   471,   475,   476,   477,   478,   483,   486,   490,
+     498,   501,   505,   513,   517,   521
 };
 #endif
 
@@ -580,20 +582,20 @@
 static const yytype_uint8 yydefact[] =
 {
        0,     0,     0,     5,     7,     3,     1,     6,     0,     0,
-       0,     7,     0,    38,    39,     0,     0,    10,     0,     2,
-       8,     4,     0,     0,     0,    72,     0,    41,    42,    44,
-      46,    48,    50,    52,    54,    57,    64,    67,    71,     0,
-      17,    11,     0,     0,     0,     0,    73,    74,    75,    40,
+      16,     7,     0,    39,    40,     0,     0,    10,     0,     2,
+       8,     4,     0,     0,     0,    73,     0,    42,    43,    45,
+      47,    49,    51,    53,    55,    58,    65,    68,    72,     0,
+      18,    11,     0,     0,     0,     0,    74,    75,    76,    41,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     9,
-      79,     0,     0,    14,    12,    45,     0,    47,    49,    51,
-      53,    55,    56,    60,    61,    59,    58,    62,    63,    65,
-      66,    69,    68,    70,     0,     0,     0,     0,    18,     0,
-      79,    15,    13,     0,     0,     0,    20,    30,    82,    22,
-      84,     0,    81,    80,    43,    21,    83,     0,     0,    16,
-      29,    19,    31,     0,    23,    32,    26,     0,    76,    34,
-       0,     0,     0,     0,    37,    36,    24,    35,    33,     0,
-      77,    78,    25,     0,    28,     0,     0,     0,    27
+      80,     0,     0,    14,    12,    46,     0,    48,    50,    52,
+      54,    56,    57,    61,    62,    60,    59,    63,    64,    66,
+      67,    70,    69,    71,     0,     0,     0,     0,    19,     0,
+      80,    15,    13,     0,     0,     0,    21,    31,    83,    23,
+      85,     0,    82,    81,    44,    22,    84,     0,     0,    17,
+      30,    20,    32,     0,    24,    33,    27,     0,    77,    35,
+       0,     0,     0,     0,    38,    37,    25,    36,    34,     0,
+      78,    79,    26,     0,    29,     0,     0,     0,    28
 };
 
   /* YYPGOTO[NTERM-NUM].  */
@@ -676,28 +678,28 @@
 static const yytype_uint8 yyr1[] =
 {
        0,    48,    49,    50,    50,    51,    51,    52,    52,    53,
-      53,    54,    54,    54,    54,    54,    55,    56,    56,    57,
-      57,    57,    57,    58,    58,    58,    58,    58,    58,    58,
-      59,    59,    59,    60,    60,    60,    60,    60,    61,    61,
-      61,    62,    63,    63,    64,    64,    65,    65,    66,    66,
-      67,    67,    68,    68,    69,    69,    69,    70,    70,    70,
-      70,    70,    71,    71,    71,    72,    72,    72,    73,    73,
-      73,    73,    74,    74,    74,    74,    75,    75,    75,    76,
-      76,    76,    77,    77,    77
+      53,    54,    54,    54,    54,    54,    54,    55,    56,    56,
+      57,    57,    57,    57,    58,    58,    58,    58,    58,    58,
+      58,    59,    59,    59,    60,    60,    60,    60,    60,    61,
+      61,    61,    62,    63,    63,    64,    64,    65,    65,    66,
+      66,    67,    67,    68,    68,    69,    69,    69,    70,    70,
+      70,    70,    70,    71,    71,    71,    72,    72,    72,    73,
+      73,    73,    73,    74,    74,    74,    74,    75,    75,    75,
+      76,    76,    76,    77,    77,    77
 };
 
   /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
        0,     2,     3,     2,     4,     1,     2,     0,     2,     4,
-       2,     2,     3,     4,     3,     4,     5,     0,     2,     4,
-       2,     3,     2,     2,     3,     4,     2,     9,     5,     2,
-       0,     2,     2,     3,     1,     2,     2,     2,     1,     1,
-       3,     1,     1,     5,     1,     3,     1,     3,     1,     3,
-       1,     3,     1,     3,     1,     3,     3,     1,     3,     3,
-       3,     3,     3,     3,     1,     3,     3,     1,     3,     3,
-       3,     1,     1,     2,     2,     2,     0,     2,     2,     0,
-       2,     2,     2,     3,     2
+       2,     2,     3,     4,     3,     4,     0,     5,     0,     2,
+       4,     2,     3,     2,     2,     3,     4,     2,     9,     5,
+       2,     0,     2,     2,     3,     1,     2,     2,     2,     1,
+       1,     3,     1,     1,     5,     1,     3,     1,     3,     1,
+       3,     1,     3,     1,     3,     1,     3,     3,     1,     3,
+       3,     3,     3,     3,     3,     1,     3,     3,     1,     3,
+       3,     3,     1,     1,     2,     2,     2,     0,     2,     2,
+       0,     2,     2,     2,     3,     2
 };
 
 
@@ -1472,7 +1474,7 @@
 			parser_output = build_dt_info((yyvsp[-2].flags), (yyvsp[-1].re), (yyvsp[0].node),
 			                              guess_boot_cpuid((yyvsp[0].node)));
 		}
-#line 1476 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1478 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 3:
@@ -1480,7 +1482,7 @@
     {
 			(yyval.flags) = DTSF_V1;
 		}
-#line 1484 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1486 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 4:
@@ -1488,7 +1490,7 @@
     {
 			(yyval.flags) = DTSF_V1 | DTSF_PLUGIN;
 		}
-#line 1492 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1494 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 6:
@@ -1498,7 +1500,7 @@
 				ERROR(&(yylsp[0]), "Header flags don't match earlier ones");
 			(yyval.flags) = (yyvsp[-1].flags);
 		}
-#line 1502 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1504 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 7:
@@ -1506,7 +1508,7 @@
     {
 			(yyval.re) = NULL;
 		}
-#line 1510 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1512 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 8:
@@ -1514,7 +1516,7 @@
     {
 			(yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re));
 		}
-#line 1518 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1520 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 9:
@@ -1522,7 +1524,7 @@
     {
 			(yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer));
 		}
-#line 1526 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1528 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 10:
@@ -1531,7 +1533,7 @@
 			add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref));
 			(yyval.re) = (yyvsp[0].re);
 		}
-#line 1535 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1537 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 11:
@@ -1539,7 +1541,7 @@
     {
 			(yyval.node) = name_node((yyvsp[0].node), "");
 		}
-#line 1543 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1545 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 12:
@@ -1547,7 +1549,7 @@
     {
 			(yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node));
 		}
-#line 1551 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1553 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 13:
@@ -1562,7 +1564,7 @@
 				ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
 			(yyval.node) = (yyvsp[-3].node);
 		}
-#line 1566 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1568 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 14:
@@ -1570,17 +1572,26 @@
     {
 			struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref));
 
-			if (target)
+			if (target) {
 				merge_nodes(target, (yyvsp[0].node));
-			else
-				ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
+			} else {
+				/*
+				 * We rely on the rule being always:
+				 *   versioninfo plugindecl memreserves devicetree
+				 * so $-1 is what we want (plugindecl)
+				 */
+				if ((yyvsp[(-1) - (3)].flags) & DTSF_PLUGIN)
+					add_orphan_node((yyvsp[-2].node), (yyvsp[0].node), (yyvsp[-1].labelref));
+				else
+					ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
+			}
 			(yyval.node) = (yyvsp[-2].node);
 		}
-#line 1580 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1591 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 15:
-#line 192 "dtc-parser.y" /* yacc.c:1646  */
+#line 201 "dtc-parser.y" /* yacc.c:1646  */
     {
 			struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
 
@@ -1592,100 +1603,109 @@
 
 			(yyval.node) = (yyvsp[-3].node);
 		}
-#line 1596 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1607 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 16:
-#line 207 "dtc-parser.y" /* yacc.c:1646  */
+#line 213 "dtc-parser.y" /* yacc.c:1646  */
     {
-			(yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
+			/* build empty node */
+			(yyval.node) = name_node(build_node(NULL, NULL), "");
 		}
-#line 1604 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1616 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 17:
-#line 214 "dtc-parser.y" /* yacc.c:1646  */
+#line 221 "dtc-parser.y" /* yacc.c:1646  */
     {
-			(yyval.proplist) = NULL;
+			(yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
 		}
-#line 1612 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1624 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 18:
-#line 218 "dtc-parser.y" /* yacc.c:1646  */
+#line 228 "dtc-parser.y" /* yacc.c:1646  */
     {
-			(yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
+			(yyval.proplist) = NULL;
 		}
-#line 1620 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1632 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 19:
-#line 225 "dtc-parser.y" /* yacc.c:1646  */
+#line 232 "dtc-parser.y" /* yacc.c:1646  */
     {
-			(yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
+			(yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
 		}
-#line 1628 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1640 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 20:
-#line 229 "dtc-parser.y" /* yacc.c:1646  */
+#line 239 "dtc-parser.y" /* yacc.c:1646  */
     {
-			(yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
+			(yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
 		}
-#line 1636 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1648 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 21:
-#line 233 "dtc-parser.y" /* yacc.c:1646  */
+#line 243 "dtc-parser.y" /* yacc.c:1646  */
     {
-			(yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
+			(yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
 		}
-#line 1644 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1656 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
   case 22:
-#line 237 "dtc-parser.y" /* yacc.c:1646  */
+#line 247 "dtc-parser.y" /* yacc.c:1646  */
+    {
+			(yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
+		}
+#line 1664 "dtc-parser.tab.c" /* yacc.c:1646  */
+    break;
+
+  case 23:
+#line 251 "dtc-parser.y" /* yacc.c:1646  */
     {
 			add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref));
 			(yyval.prop) = (yyvsp[0].prop);
 		}
-#line 1653 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1673 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 23:
-#line 245 "dtc-parser.y" /* yacc.c:1646  */
+  case 24:
+#line 259 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data));
 		}
-#line 1661 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1681 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 24:
-#line 249 "dtc-parser.y" /* yacc.c:1646  */
+  case 25:
+#line 263 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data);
 		}
-#line 1669 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1689 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 25:
-#line 253 "dtc-parser.y" /* yacc.c:1646  */
+  case 26:
+#line 267 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data));
 		}
-#line 1677 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1697 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 26:
-#line 257 "dtc-parser.y" /* yacc.c:1646  */
+  case 27:
+#line 271 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref));
 		}
-#line 1685 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1705 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 27:
-#line 261 "dtc-parser.y" /* yacc.c:1646  */
+  case 28:
+#line 275 "dtc-parser.y" /* yacc.c:1646  */
     {
 			FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL);
 			struct data d;
@@ -1701,11 +1721,11 @@
 			(yyval.data) = data_merge((yyvsp[-8].data), d);
 			fclose(f);
 		}
-#line 1705 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1725 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 28:
-#line 277 "dtc-parser.y" /* yacc.c:1646  */
+  case 29:
+#line 291 "dtc-parser.y" /* yacc.c:1646  */
     {
 			FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL);
 			struct data d = empty_data;
@@ -1715,43 +1735,43 @@
 			(yyval.data) = data_merge((yyvsp[-4].data), d);
 			fclose(f);
 		}
-#line 1719 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1739 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 29:
-#line 287 "dtc-parser.y" /* yacc.c:1646  */
+  case 30:
+#line 301 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
 		}
-#line 1727 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1747 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 30:
-#line 294 "dtc-parser.y" /* yacc.c:1646  */
+  case 31:
+#line 308 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.data) = empty_data;
 		}
-#line 1735 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1755 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 31:
-#line 298 "dtc-parser.y" /* yacc.c:1646  */
+  case 32:
+#line 312 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.data) = (yyvsp[-1].data);
 		}
-#line 1743 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1763 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 32:
-#line 302 "dtc-parser.y" /* yacc.c:1646  */
+  case 33:
+#line 316 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
 		}
-#line 1751 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1771 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 33:
-#line 309 "dtc-parser.y" /* yacc.c:1646  */
+  case 34:
+#line 323 "dtc-parser.y" /* yacc.c:1646  */
     {
 			unsigned long long bits;
 
@@ -1767,20 +1787,20 @@
 			(yyval.array).data = empty_data;
 			(yyval.array).bits = bits;
 		}
-#line 1771 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1791 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 34:
-#line 325 "dtc-parser.y" /* yacc.c:1646  */
+  case 35:
+#line 339 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.array).data = empty_data;
 			(yyval.array).bits = 32;
 		}
-#line 1780 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1800 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 35:
-#line 330 "dtc-parser.y" /* yacc.c:1646  */
+  case 36:
+#line 344 "dtc-parser.y" /* yacc.c:1646  */
     {
 			if ((yyvsp[-1].array).bits < 64) {
 				uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1;
@@ -1799,11 +1819,11 @@
 
 			(yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits);
 		}
-#line 1803 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1823 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 36:
-#line 349 "dtc-parser.y" /* yacc.c:1646  */
+  case 37:
+#line 363 "dtc-parser.y" /* yacc.c:1646  */
     {
 			uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits);
 
@@ -1817,129 +1837,129 @@
 
 			(yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits);
 		}
-#line 1821 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1841 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 37:
-#line 363 "dtc-parser.y" /* yacc.c:1646  */
+  case 38:
+#line 377 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref));
 		}
-#line 1829 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1849 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 40:
-#line 372 "dtc-parser.y" /* yacc.c:1646  */
+  case 41:
+#line 386 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.integer) = (yyvsp[-1].integer);
 		}
-#line 1837 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1857 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 43:
-#line 383 "dtc-parser.y" /* yacc.c:1646  */
+  case 44:
+#line 397 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); }
-#line 1843 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1863 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 45:
-#line 388 "dtc-parser.y" /* yacc.c:1646  */
+  case 46:
+#line 402 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); }
-#line 1849 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1869 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 47:
-#line 393 "dtc-parser.y" /* yacc.c:1646  */
+  case 48:
+#line 407 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); }
-#line 1855 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1875 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 49:
-#line 398 "dtc-parser.y" /* yacc.c:1646  */
+  case 50:
+#line 412 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); }
-#line 1861 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1881 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 51:
-#line 403 "dtc-parser.y" /* yacc.c:1646  */
+  case 52:
+#line 417 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); }
-#line 1867 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1887 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 53:
-#line 408 "dtc-parser.y" /* yacc.c:1646  */
+  case 54:
+#line 422 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); }
-#line 1873 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1893 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 55:
-#line 413 "dtc-parser.y" /* yacc.c:1646  */
+  case 56:
+#line 427 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); }
-#line 1879 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1899 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 56:
-#line 414 "dtc-parser.y" /* yacc.c:1646  */
+  case 57:
+#line 428 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); }
-#line 1885 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1905 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 58:
-#line 419 "dtc-parser.y" /* yacc.c:1646  */
+  case 59:
+#line 433 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); }
-#line 1891 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1911 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 59:
-#line 420 "dtc-parser.y" /* yacc.c:1646  */
+  case 60:
+#line 434 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); }
-#line 1897 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1917 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 60:
-#line 421 "dtc-parser.y" /* yacc.c:1646  */
+  case 61:
+#line 435 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); }
-#line 1903 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1923 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 61:
-#line 422 "dtc-parser.y" /* yacc.c:1646  */
+  case 62:
+#line 436 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); }
-#line 1909 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1929 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 62:
-#line 426 "dtc-parser.y" /* yacc.c:1646  */
+  case 63:
+#line 440 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); }
-#line 1915 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1935 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 63:
-#line 427 "dtc-parser.y" /* yacc.c:1646  */
+  case 64:
+#line 441 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); }
-#line 1921 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1941 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 65:
-#line 432 "dtc-parser.y" /* yacc.c:1646  */
+  case 66:
+#line 446 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); }
-#line 1927 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1947 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 66:
-#line 433 "dtc-parser.y" /* yacc.c:1646  */
+  case 67:
+#line 447 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); }
-#line 1933 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1953 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 68:
-#line 438 "dtc-parser.y" /* yacc.c:1646  */
+  case 69:
+#line 452 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); }
-#line 1939 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1959 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 69:
-#line 440 "dtc-parser.y" /* yacc.c:1646  */
+  case 70:
+#line 454 "dtc-parser.y" /* yacc.c:1646  */
     {
 			if ((yyvsp[0].integer) != 0) {
 				(yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer);
@@ -1948,11 +1968,11 @@
 				(yyval.integer) = 0;
 			}
 		}
-#line 1952 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1972 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 70:
-#line 449 "dtc-parser.y" /* yacc.c:1646  */
+  case 71:
+#line 463 "dtc-parser.y" /* yacc.c:1646  */
     {
 			if ((yyvsp[0].integer) != 0) {
 				(yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer);
@@ -1961,103 +1981,103 @@
 				(yyval.integer) = 0;
 			}
 		}
-#line 1965 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1985 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 73:
-#line 462 "dtc-parser.y" /* yacc.c:1646  */
+  case 74:
+#line 476 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = -(yyvsp[0].integer); }
-#line 1971 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1991 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 74:
-#line 463 "dtc-parser.y" /* yacc.c:1646  */
+  case 75:
+#line 477 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = ~(yyvsp[0].integer); }
-#line 1977 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1997 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 75:
-#line 464 "dtc-parser.y" /* yacc.c:1646  */
+  case 76:
+#line 478 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = !(yyvsp[0].integer); }
-#line 1983 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2003 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 76:
-#line 469 "dtc-parser.y" /* yacc.c:1646  */
+  case 77:
+#line 483 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.data) = empty_data;
 		}
-#line 1991 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2011 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 77:
-#line 473 "dtc-parser.y" /* yacc.c:1646  */
+  case 78:
+#line 487 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
 		}
-#line 1999 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2019 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 78:
-#line 477 "dtc-parser.y" /* yacc.c:1646  */
+  case 79:
+#line 491 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
 		}
-#line 2007 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2027 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 79:
-#line 484 "dtc-parser.y" /* yacc.c:1646  */
+  case 80:
+#line 498 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.nodelist) = NULL;
 		}
-#line 2015 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2035 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 80:
-#line 488 "dtc-parser.y" /* yacc.c:1646  */
+  case 81:
+#line 502 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
 		}
-#line 2023 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2043 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 81:
-#line 492 "dtc-parser.y" /* yacc.c:1646  */
+  case 82:
+#line 506 "dtc-parser.y" /* yacc.c:1646  */
     {
 			ERROR(&(yylsp[0]), "Properties must precede subnodes");
 			YYERROR;
 		}
-#line 2032 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2052 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 82:
-#line 500 "dtc-parser.y" /* yacc.c:1646  */
+  case 83:
+#line 514 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
 		}
-#line 2040 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2060 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 83:
-#line 504 "dtc-parser.y" /* yacc.c:1646  */
+  case 84:
+#line 518 "dtc-parser.y" /* yacc.c:1646  */
     {
 			(yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
 		}
-#line 2048 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2068 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
-  case 84:
-#line 508 "dtc-parser.y" /* yacc.c:1646  */
+  case 85:
+#line 522 "dtc-parser.y" /* yacc.c:1646  */
     {
 			add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
 			(yyval.node) = (yyvsp[0].node);
 		}
-#line 2057 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2077 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
 
 
-#line 2061 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2081 "dtc-parser.tab.c" /* yacc.c:1646  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -2292,7 +2312,7 @@
 #endif
   return yyresult;
 }
-#line 514 "dtc-parser.y" /* yacc.c:1906  */
+#line 528 "dtc-parser.y" /* yacc.c:1906  */
 
 
 void yyerror(char const *s)
diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped
index e7b04dd..6aa512c 100644
--- a/scripts/dtc/dtc-parser.tab.h_shipped
+++ b/scripts/dtc/dtc-parser.tab.h_shipped
@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 3.0.2.  */
+/* A Bison parser, made by GNU Bison 3.0.4.  */
 
 /* Bison interface for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -72,7 +72,7 @@
 
 /* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE YYSTYPE;
+
 union YYSTYPE
 {
 #line 39 "dtc-parser.y" /* yacc.c:1909  */
@@ -97,6 +97,8 @@
 
 #line 99 "dtc-parser.tab.h" /* yacc.c:1909  */
 };
+
+typedef union YYSTYPE YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define YYSTYPE_IS_DECLARED 1
 #endif
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
index ca3f500..affc81a 100644
--- a/scripts/dtc/dtc-parser.y
+++ b/scripts/dtc/dtc-parser.y
@@ -182,10 +182,19 @@
 		{
 			struct node *target = get_node_by_ref($1, $2);
 
-			if (target)
+			if (target) {
 				merge_nodes(target, $3);
-			else
-				ERROR(&@2, "Label or path %s not found", $2);
+			} else {
+				/*
+				 * We rely on the rule being always:
+				 *   versioninfo plugindecl memreserves devicetree
+				 * so $-1 is what we want (plugindecl)
+				 */
+				if ($<flags>-1 & DTSF_PLUGIN)
+					add_orphan_node($1, $3, $2);
+				else
+					ERROR(&@2, "Label or path %s not found", $2);
+			}
 			$$ = $1;
 		}
 	| devicetree DT_DEL_NODE DT_REF ';'
@@ -200,6 +209,11 @@
 
 			$$ = $1;
 		}
+	| /* empty */
+		{
+			/* build empty node */
+			$$ = name_node(build_node(NULL, NULL), "");
+		}
 	;
 
 nodedef:
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index 409db76..35cf926 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -203,6 +203,7 @@
 struct node *name_node(struct node *node, char *name);
 struct node *chain_node(struct node *first, struct node *list);
 struct node *merge_nodes(struct node *old_node, struct node *new_node);
+void add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
 
 void add_property(struct node *node, struct property *prop);
 void delete_property_by_name(struct node *node, char *name);
@@ -216,6 +217,7 @@
 const char *get_unitname(struct node *node);
 struct property *get_property(struct node *node, const char *propname);
 cell_t propval_cell(struct property *prop);
+cell_t propval_cell_n(struct property *prop, int n);
 struct property *get_property_by_label(struct node *tree, const char *label,
 				       struct node **node);
 struct marker *get_marker_label(struct node *tree, const char *label,
diff --git a/scripts/dtc/libfdt/fdt_addresses.c b/scripts/dtc/libfdt/fdt_addresses.c
new file mode 100644
index 0000000..eff4dbc
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt_addresses.c
@@ -0,0 +1,96 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ *  a) This library 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 library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ *  b) Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *     1. Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *     2. Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+int fdt_address_cells(const void *fdt, int nodeoffset)
+{
+	const fdt32_t *ac;
+	int val;
+	int len;
+
+	ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len);
+	if (!ac)
+		return 2;
+
+	if (len != sizeof(*ac))
+		return -FDT_ERR_BADNCELLS;
+
+	val = fdt32_to_cpu(*ac);
+	if ((val <= 0) || (val > FDT_MAX_NCELLS))
+		return -FDT_ERR_BADNCELLS;
+
+	return val;
+}
+
+int fdt_size_cells(const void *fdt, int nodeoffset)
+{
+	const fdt32_t *sc;
+	int val;
+	int len;
+
+	sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len);
+	if (!sc)
+		return 2;
+
+	if (len != sizeof(*sc))
+		return -FDT_ERR_BADNCELLS;
+
+	val = fdt32_to_cpu(*sc);
+	if ((val < 0) || (val > FDT_MAX_NCELLS))
+		return -FDT_ERR_BADNCELLS;
+
+	return val;
+}
diff --git a/scripts/dtc/libfdt/fdt_overlay.c b/scripts/dtc/libfdt/fdt_overlay.c
new file mode 100644
index 0000000..bd81241
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt_overlay.c
@@ -0,0 +1,861 @@
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+/**
+ * overlay_get_target_phandle - retrieves the target phandle of a fragment
+ * @fdto: pointer to the device tree overlay blob
+ * @fragment: node offset of the fragment in the overlay
+ *
+ * overlay_get_target_phandle() retrieves the target phandle of an
+ * overlay fragment when that fragment uses a phandle (target
+ * property) instead of a path (target-path property).
+ *
+ * returns:
+ *      the phandle pointed by the target property
+ *      0, if the phandle was not found
+ *	-1, if the phandle was malformed
+ */
+static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
+{
+	const fdt32_t *val;
+	int len;
+
+	val = fdt_getprop(fdto, fragment, "target", &len);
+	if (!val)
+		return 0;
+
+	if ((len != sizeof(*val)) || (fdt32_to_cpu(*val) == (uint32_t)-1))
+		return (uint32_t)-1;
+
+	return fdt32_to_cpu(*val);
+}
+
+/**
+ * overlay_get_target - retrieves the offset of a fragment's target
+ * @fdt: Base device tree blob
+ * @fdto: Device tree overlay blob
+ * @fragment: node offset of the fragment in the overlay
+ * @pathp: pointer which receives the path of the target (or NULL)
+ *
+ * overlay_get_target() retrieves the target offset in the base
+ * device tree of a fragment, no matter how the actual targetting is
+ * done (through a phandle or a path)
+ *
+ * returns:
+ *      the targetted node offset in the base device tree
+ *      Negative error code on error
+ */
+static int overlay_get_target(const void *fdt, const void *fdto,
+			      int fragment, char const **pathp)
+{
+	uint32_t phandle;
+	const char *path = NULL;
+	int path_len = 0, ret;
+
+	/* Try first to do a phandle based lookup */
+	phandle = overlay_get_target_phandle(fdto, fragment);
+	if (phandle == (uint32_t)-1)
+		return -FDT_ERR_BADPHANDLE;
+
+	/* no phandle, try path */
+	if (!phandle) {
+		/* And then a path based lookup */
+		path = fdt_getprop(fdto, fragment, "target-path", &path_len);
+		if (path)
+			ret = fdt_path_offset(fdt, path);
+		else
+			ret = path_len;
+	} else
+		ret = fdt_node_offset_by_phandle(fdt, phandle);
+
+	/*
+	* If we haven't found either a target or a
+	* target-path property in a node that contains a
+	* __overlay__ subnode (we wouldn't be called
+	* otherwise), consider it a improperly written
+	* overlay
+	*/
+	if (ret < 0 && path_len == -FDT_ERR_NOTFOUND)
+		ret = -FDT_ERR_BADOVERLAY;
+
+	/* return on error */
+	if (ret < 0)
+		return ret;
+
+	/* return pointer to path (if available) */
+	if (pathp)
+		*pathp = path ? path : NULL;
+
+	return ret;
+}
+
+/**
+ * overlay_phandle_add_offset - Increases a phandle by an offset
+ * @fdt: Base device tree blob
+ * @node: Device tree overlay blob
+ * @name: Name of the property to modify (phandle or linux,phandle)
+ * @delta: offset to apply
+ *
+ * overlay_phandle_add_offset() increments a node phandle by a given
+ * offset.
+ *
+ * returns:
+ *      0 on success.
+ *      Negative error code on error
+ */
+static int overlay_phandle_add_offset(void *fdt, int node,
+				      const char *name, uint32_t delta)
+{
+	const fdt32_t *val;
+	uint32_t adj_val;
+	int len;
+
+	val = fdt_getprop(fdt, node, name, &len);
+	if (!val)
+		return len;
+
+	if (len != sizeof(*val))
+		return -FDT_ERR_BADPHANDLE;
+
+	adj_val = fdt32_to_cpu(*val);
+	if ((adj_val + delta) < adj_val)
+		return -FDT_ERR_NOPHANDLES;
+
+	adj_val += delta;
+	if (adj_val == (uint32_t)-1)
+		return -FDT_ERR_NOPHANDLES;
+
+	return fdt_setprop_inplace_u32(fdt, node, name, adj_val);
+}
+
+/**
+ * overlay_adjust_node_phandles - Offsets the phandles of a node
+ * @fdto: Device tree overlay blob
+ * @node: Offset of the node we want to adjust
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_adjust_node_phandles() adds a constant to all the phandles
+ * of a given node. This is mainly use as part of the overlay
+ * application process, when we want to update all the overlay
+ * phandles to not conflict with the overlays of the base device tree.
+ *
+ * returns:
+ *      0 on success
+ *      Negative error code on failure
+ */
+static int overlay_adjust_node_phandles(void *fdto, int node,
+					uint32_t delta)
+{
+	int child;
+	int ret;
+
+	ret = overlay_phandle_add_offset(fdto, node, "phandle", delta);
+	if (ret && ret != -FDT_ERR_NOTFOUND)
+		return ret;
+
+	ret = overlay_phandle_add_offset(fdto, node, "linux,phandle", delta);
+	if (ret && ret != -FDT_ERR_NOTFOUND)
+		return ret;
+
+	fdt_for_each_subnode(child, fdto, node) {
+		ret = overlay_adjust_node_phandles(fdto, child, delta);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * overlay_adjust_local_phandles - Adjust the phandles of a whole overlay
+ * @fdto: Device tree overlay blob
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_adjust_local_phandles() adds a constant to all the
+ * phandles of an overlay. This is mainly use as part of the overlay
+ * application process, when we want to update all the overlay
+ * phandles to not conflict with the overlays of the base device tree.
+ *
+ * returns:
+ *      0 on success
+ *      Negative error code on failure
+ */
+static int overlay_adjust_local_phandles(void *fdto, uint32_t delta)
+{
+	/*
+	 * Start adjusting the phandles from the overlay root
+	 */
+	return overlay_adjust_node_phandles(fdto, 0, delta);
+}
+
+/**
+ * overlay_update_local_node_references - Adjust the overlay references
+ * @fdto: Device tree overlay blob
+ * @tree_node: Node offset of the node to operate on
+ * @fixup_node: Node offset of the matching local fixups node
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_update_local_nodes_references() update the phandles
+ * pointing to a node within the device tree overlay by adding a
+ * constant delta.
+ *
+ * This is mainly used as part of a device tree application process,
+ * where you want the device tree overlays phandles to not conflict
+ * with the ones from the base device tree before merging them.
+ *
+ * returns:
+ *      0 on success
+ *      Negative error code on failure
+ */
+static int overlay_update_local_node_references(void *fdto,
+						int tree_node,
+						int fixup_node,
+						uint32_t delta)
+{
+	int fixup_prop;
+	int fixup_child;
+	int ret;
+
+	fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) {
+		const fdt32_t *fixup_val;
+		const char *tree_val;
+		const char *name;
+		int fixup_len;
+		int tree_len;
+		int i;
+
+		fixup_val = fdt_getprop_by_offset(fdto, fixup_prop,
+						  &name, &fixup_len);
+		if (!fixup_val)
+			return fixup_len;
+
+		if (fixup_len % sizeof(uint32_t))
+			return -FDT_ERR_BADOVERLAY;
+
+		tree_val = fdt_getprop(fdto, tree_node, name, &tree_len);
+		if (!tree_val) {
+			if (tree_len == -FDT_ERR_NOTFOUND)
+				return -FDT_ERR_BADOVERLAY;
+
+			return tree_len;
+		}
+
+		for (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) {
+			fdt32_t adj_val;
+			uint32_t poffset;
+
+			poffset = fdt32_to_cpu(fixup_val[i]);
+
+			/*
+			 * phandles to fixup can be unaligned.
+			 *
+			 * Use a memcpy for the architectures that do
+			 * not support unaligned accesses.
+			 */
+			memcpy(&adj_val, tree_val + poffset, sizeof(adj_val));
+
+			adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta);
+
+			ret = fdt_setprop_inplace_namelen_partial(fdto,
+								  tree_node,
+								  name,
+								  strlen(name),
+								  poffset,
+								  &adj_val,
+								  sizeof(adj_val));
+			if (ret == -FDT_ERR_NOSPACE)
+				return -FDT_ERR_BADOVERLAY;
+
+			if (ret)
+				return ret;
+		}
+	}
+
+	fdt_for_each_subnode(fixup_child, fdto, fixup_node) {
+		const char *fixup_child_name = fdt_get_name(fdto, fixup_child,
+							    NULL);
+		int tree_child;
+
+		tree_child = fdt_subnode_offset(fdto, tree_node,
+						fixup_child_name);
+		if (tree_child == -FDT_ERR_NOTFOUND)
+			return -FDT_ERR_BADOVERLAY;
+		if (tree_child < 0)
+			return tree_child;
+
+		ret = overlay_update_local_node_references(fdto,
+							   tree_child,
+							   fixup_child,
+							   delta);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * overlay_update_local_references - Adjust the overlay references
+ * @fdto: Device tree overlay blob
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_update_local_references() update all the phandles pointing
+ * to a node within the device tree overlay by adding a constant
+ * delta to not conflict with the base overlay.
+ *
+ * This is mainly used as part of a device tree application process,
+ * where you want the device tree overlays phandles to not conflict
+ * with the ones from the base device tree before merging them.
+ *
+ * returns:
+ *      0 on success
+ *      Negative error code on failure
+ */
+static int overlay_update_local_references(void *fdto, uint32_t delta)
+{
+	int fixups;
+
+	fixups = fdt_path_offset(fdto, "/__local_fixups__");
+	if (fixups < 0) {
+		/* There's no local phandles to adjust, bail out */
+		if (fixups == -FDT_ERR_NOTFOUND)
+			return 0;
+
+		return fixups;
+	}
+
+	/*
+	 * Update our local references from the root of the tree
+	 */
+	return overlay_update_local_node_references(fdto, 0, fixups,
+						    delta);
+}
+
+/**
+ * overlay_fixup_one_phandle - Set an overlay phandle to the base one
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ * @symbols_off: Node offset of the symbols node in the base device tree
+ * @path: Path to a node holding a phandle in the overlay
+ * @path_len: number of path characters to consider
+ * @name: Name of the property holding the phandle reference in the overlay
+ * @name_len: number of name characters to consider
+ * @poffset: Offset within the overlay property where the phandle is stored
+ * @label: Label of the node referenced by the phandle
+ *
+ * overlay_fixup_one_phandle() resolves an overlay phandle pointing to
+ * a node in the base device tree.
+ *
+ * This is part of the device tree overlay application process, when
+ * you want all the phandles in the overlay to point to the actual
+ * base dt nodes.
+ *
+ * returns:
+ *      0 on success
+ *      Negative error code on failure
+ */
+static int overlay_fixup_one_phandle(void *fdt, void *fdto,
+				     int symbols_off,
+				     const char *path, uint32_t path_len,
+				     const char *name, uint32_t name_len,
+				     int poffset, const char *label)
+{
+	const char *symbol_path;
+	uint32_t phandle;
+	fdt32_t phandle_prop;
+	int symbol_off, fixup_off;
+	int prop_len;
+
+	if (symbols_off < 0)
+		return symbols_off;
+
+	symbol_path = fdt_getprop(fdt, symbols_off, label,
+				  &prop_len);
+	if (!symbol_path)
+		return prop_len;
+
+	symbol_off = fdt_path_offset(fdt, symbol_path);
+	if (symbol_off < 0)
+		return symbol_off;
+
+	phandle = fdt_get_phandle(fdt, symbol_off);
+	if (!phandle)
+		return -FDT_ERR_NOTFOUND;
+
+	fixup_off = fdt_path_offset_namelen(fdto, path, path_len);
+	if (fixup_off == -FDT_ERR_NOTFOUND)
+		return -FDT_ERR_BADOVERLAY;
+	if (fixup_off < 0)
+		return fixup_off;
+
+	phandle_prop = cpu_to_fdt32(phandle);
+	return fdt_setprop_inplace_namelen_partial(fdto, fixup_off,
+						   name, name_len, poffset,
+						   &phandle_prop,
+						   sizeof(phandle_prop));
+};
+
+/**
+ * overlay_fixup_phandle - Set an overlay phandle to the base one
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ * @symbols_off: Node offset of the symbols node in the base device tree
+ * @property: Property offset in the overlay holding the list of fixups
+ *
+ * overlay_fixup_phandle() resolves all the overlay phandles pointed
+ * to in a __fixups__ property, and updates them to match the phandles
+ * in use in the base device tree.
+ *
+ * This is part of the device tree overlay application process, when
+ * you want all the phandles in the overlay to point to the actual
+ * base dt nodes.
+ *
+ * returns:
+ *      0 on success
+ *      Negative error code on failure
+ */
+static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
+				 int property)
+{
+	const char *value;
+	const char *label;
+	int len;
+
+	value = fdt_getprop_by_offset(fdto, property,
+				      &label, &len);
+	if (!value) {
+		if (len == -FDT_ERR_NOTFOUND)
+			return -FDT_ERR_INTERNAL;
+
+		return len;
+	}
+
+	do {
+		const char *path, *name, *fixup_end;
+		const char *fixup_str = value;
+		uint32_t path_len, name_len;
+		uint32_t fixup_len;
+		char *sep, *endptr;
+		int poffset, ret;
+
+		fixup_end = memchr(value, '\0', len);
+		if (!fixup_end)
+			return -FDT_ERR_BADOVERLAY;
+		fixup_len = fixup_end - fixup_str;
+
+		len -= fixup_len + 1;
+		value += fixup_len + 1;
+
+		path = fixup_str;
+		sep = memchr(fixup_str, ':', fixup_len);
+		if (!sep || *sep != ':')
+			return -FDT_ERR_BADOVERLAY;
+
+		path_len = sep - path;
+		if (path_len == (fixup_len - 1))
+			return -FDT_ERR_BADOVERLAY;
+
+		fixup_len -= path_len + 1;
+		name = sep + 1;
+		sep = memchr(name, ':', fixup_len);
+		if (!sep || *sep != ':')
+			return -FDT_ERR_BADOVERLAY;
+
+		name_len = sep - name;
+		if (!name_len)
+			return -FDT_ERR_BADOVERLAY;
+
+		poffset = strtoul(sep + 1, &endptr, 10);
+		if ((*endptr != '\0') || (endptr <= (sep + 1)))
+			return -FDT_ERR_BADOVERLAY;
+
+		ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off,
+						path, path_len, name, name_len,
+						poffset, label);
+		if (ret)
+			return ret;
+	} while (len > 0);
+
+	return 0;
+}
+
+/**
+ * overlay_fixup_phandles - Resolve the overlay phandles to the base
+ *                          device tree
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ *
+ * overlay_fixup_phandles() resolves all the overlay phandles pointing
+ * to nodes in the base device tree.
+ *
+ * This is one of the steps of the device tree overlay application
+ * process, when you want all the phandles in the overlay to point to
+ * the actual base dt nodes.
+ *
+ * returns:
+ *      0 on success
+ *      Negative error code on failure
+ */
+static int overlay_fixup_phandles(void *fdt, void *fdto)
+{
+	int fixups_off, symbols_off;
+	int property;
+
+	/* We can have overlays without any fixups */
+	fixups_off = fdt_path_offset(fdto, "/__fixups__");
+	if (fixups_off == -FDT_ERR_NOTFOUND)
+		return 0; /* nothing to do */
+	if (fixups_off < 0)
+		return fixups_off;
+
+	/* And base DTs without symbols */
+	symbols_off = fdt_path_offset(fdt, "/__symbols__");
+	if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND)))
+		return symbols_off;
+
+	fdt_for_each_property_offset(property, fdto, fixups_off) {
+		int ret;
+
+		ret = overlay_fixup_phandle(fdt, fdto, symbols_off, property);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * overlay_apply_node - Merges a node into the base device tree
+ * @fdt: Base Device Tree blob
+ * @target: Node offset in the base device tree to apply the fragment to
+ * @fdto: Device tree overlay blob
+ * @node: Node offset in the overlay holding the changes to merge
+ *
+ * overlay_apply_node() merges a node into a target base device tree
+ * node pointed.
+ *
+ * This is part of the final step in the device tree overlay
+ * application process, when all the phandles have been adjusted and
+ * resolved and you just have to merge overlay into the base device
+ * tree.
+ *
+ * returns:
+ *      0 on success
+ *      Negative error code on failure
+ */
+static int overlay_apply_node(void *fdt, int target,
+			      void *fdto, int node)
+{
+	int property;
+	int subnode;
+
+	fdt_for_each_property_offset(property, fdto, node) {
+		const char *name;
+		const void *prop;
+		int prop_len;
+		int ret;
+
+		prop = fdt_getprop_by_offset(fdto, property, &name,
+					     &prop_len);
+		if (prop_len == -FDT_ERR_NOTFOUND)
+			return -FDT_ERR_INTERNAL;
+		if (prop_len < 0)
+			return prop_len;
+
+		ret = fdt_setprop(fdt, target, name, prop, prop_len);
+		if (ret)
+			return ret;
+	}
+
+	fdt_for_each_subnode(subnode, fdto, node) {
+		const char *name = fdt_get_name(fdto, subnode, NULL);
+		int nnode;
+		int ret;
+
+		nnode = fdt_add_subnode(fdt, target, name);
+		if (nnode == -FDT_ERR_EXISTS) {
+			nnode = fdt_subnode_offset(fdt, target, name);
+			if (nnode == -FDT_ERR_NOTFOUND)
+				return -FDT_ERR_INTERNAL;
+		}
+
+		if (nnode < 0)
+			return nnode;
+
+		ret = overlay_apply_node(fdt, nnode, fdto, subnode);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * overlay_merge - Merge an overlay into its base device tree
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ *
+ * overlay_merge() merges an overlay into its base device tree.
+ *
+ * This is the next to last step in the device tree overlay application
+ * process, when all the phandles have been adjusted and resolved and
+ * you just have to merge overlay into the base device tree.
+ *
+ * returns:
+ *      0 on success
+ *      Negative error code on failure
+ */
+static int overlay_merge(void *fdt, void *fdto)
+{
+	int fragment;
+
+	fdt_for_each_subnode(fragment, fdto, 0) {
+		int overlay;
+		int target;
+		int ret;
+
+		/*
+		 * Each fragments will have an __overlay__ node. If
+		 * they don't, it's not supposed to be merged
+		 */
+		overlay = fdt_subnode_offset(fdto, fragment, "__overlay__");
+		if (overlay == -FDT_ERR_NOTFOUND)
+			continue;
+
+		if (overlay < 0)
+			return overlay;
+
+		target = overlay_get_target(fdt, fdto, fragment, NULL);
+		if (target < 0)
+			return target;
+
+		ret = overlay_apply_node(fdt, target, fdto, overlay);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int get_path_len(const void *fdt, int nodeoffset)
+{
+	int len = 0, namelen;
+	const char *name;
+
+	FDT_CHECK_HEADER(fdt);
+
+	for (;;) {
+		name = fdt_get_name(fdt, nodeoffset, &namelen);
+		if (!name)
+			return namelen;
+
+		/* root? we're done */
+		if (namelen == 0)
+			break;
+
+		nodeoffset = fdt_parent_offset(fdt, nodeoffset);
+		if (nodeoffset < 0)
+			return nodeoffset;
+		len += namelen + 1;
+	}
+
+	/* in case of root pretend it's "/" */
+	if (len == 0)
+		len++;
+	return len;
+}
+
+/**
+ * overlay_symbol_update - Update the symbols of base tree after a merge
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ *
+ * overlay_symbol_update() updates the symbols of the base tree with the
+ * symbols of the applied overlay
+ *
+ * This is the last step in the device tree overlay application
+ * process, allowing the reference of overlay symbols by subsequent
+ * overlay operations.
+ *
+ * returns:
+ *      0 on success
+ *      Negative error code on failure
+ */
+static int overlay_symbol_update(void *fdt, void *fdto)
+{
+	int root_sym, ov_sym, prop, path_len, fragment, target;
+	int len, frag_name_len, ret, rel_path_len;
+	const char *s, *e;
+	const char *path;
+	const char *name;
+	const char *frag_name;
+	const char *rel_path;
+	const char *target_path;
+	char *buf;
+	void *p;
+
+	ov_sym = fdt_subnode_offset(fdto, 0, "__symbols__");
+
+	/* if no overlay symbols exist no problem */
+	if (ov_sym < 0)
+		return 0;
+
+	root_sym = fdt_subnode_offset(fdt, 0, "__symbols__");
+
+	/* it no root symbols exist we should create them */
+	if (root_sym == -FDT_ERR_NOTFOUND)
+		root_sym = fdt_add_subnode(fdt, 0, "__symbols__");
+
+	/* any error is fatal now */
+	if (root_sym < 0)
+		return root_sym;
+
+	/* iterate over each overlay symbol */
+	fdt_for_each_property_offset(prop, fdto, ov_sym) {
+		path = fdt_getprop_by_offset(fdto, prop, &name, &path_len);
+		if (!path)
+			return path_len;
+
+		/* verify it's a string property (terminated by a single \0) */
+		if (path_len < 1 || memchr(path, '\0', path_len) != &path[path_len - 1])
+			return -FDT_ERR_BADVALUE;
+
+		/* keep end marker to avoid strlen() */
+		e = path + path_len;
+
+		/* format: /<fragment-name>/__overlay__/<relative-subnode-path> */
+
+		if (*path != '/')
+			return -FDT_ERR_BADVALUE;
+
+		/* get fragment name first */
+		s = strchr(path + 1, '/');
+		if (!s)
+			return -FDT_ERR_BADOVERLAY;
+
+		frag_name = path + 1;
+		frag_name_len = s - path - 1;
+
+		/* verify format; safe since "s" lies in \0 terminated prop */
+		len = sizeof("/__overlay__/") - 1;
+		if ((e - s) < len || memcmp(s, "/__overlay__/", len))
+			return -FDT_ERR_BADOVERLAY;
+
+		rel_path = s + len;
+		rel_path_len = e - rel_path;
+
+		/* find the fragment index in which the symbol lies */
+		ret = fdt_subnode_offset_namelen(fdto, 0, frag_name,
+					       frag_name_len);
+		/* not found? */
+		if (ret < 0)
+			return -FDT_ERR_BADOVERLAY;
+		fragment = ret;
+
+		/* an __overlay__ subnode must exist */
+		ret = fdt_subnode_offset(fdto, fragment, "__overlay__");
+		if (ret < 0)
+			return -FDT_ERR_BADOVERLAY;
+
+		/* get the target of the fragment */
+		ret = overlay_get_target(fdt, fdto, fragment, &target_path);
+		if (ret < 0)
+			return ret;
+		target = ret;
+
+		/* if we have a target path use */
+		if (!target_path) {
+			ret = get_path_len(fdt, target);
+			if (ret < 0)
+				return ret;
+			len = ret;
+		} else {
+			len = strlen(target_path);
+		}
+
+		ret = fdt_setprop_placeholder(fdt, root_sym, name,
+				len + (len > 1) + rel_path_len + 1, &p);
+		if (ret < 0)
+			return ret;
+
+		if (!target_path) {
+			/* again in case setprop_placeholder changed it */
+			ret = overlay_get_target(fdt, fdto, fragment, &target_path);
+			if (ret < 0)
+				return ret;
+			target = ret;
+		}
+
+		buf = p;
+		if (len > 1) { /* target is not root */
+			if (!target_path) {
+				ret = fdt_get_path(fdt, target, buf, len + 1);
+				if (ret < 0)
+					return ret;
+			} else
+				memcpy(buf, target_path, len + 1);
+
+		} else
+			len--;
+
+		buf[len] = '/';
+		memcpy(buf + len + 1, rel_path, rel_path_len);
+		buf[len + 1 + rel_path_len] = '\0';
+	}
+
+	return 0;
+}
+
+int fdt_overlay_apply(void *fdt, void *fdto)
+{
+	uint32_t delta = fdt_get_max_phandle(fdt);
+	int ret;
+
+	FDT_CHECK_HEADER(fdt);
+	FDT_CHECK_HEADER(fdto);
+
+	ret = overlay_adjust_local_phandles(fdto, delta);
+	if (ret)
+		goto err;
+
+	ret = overlay_update_local_references(fdto, delta);
+	if (ret)
+		goto err;
+
+	ret = overlay_fixup_phandles(fdt, fdto);
+	if (ret)
+		goto err;
+
+	ret = overlay_merge(fdt, fdto);
+	if (ret)
+		goto err;
+
+	ret = overlay_symbol_update(fdt, fdto);
+	if (ret)
+		goto err;
+
+	/*
+	 * The overlay has been damaged, erase its magic.
+	 */
+	fdt_set_magic(fdto, ~0);
+
+	return 0;
+
+err:
+	/*
+	 * The overlay might have been damaged, erase its magic.
+	 */
+	fdt_set_magic(fdto, ~0);
+
+	/*
+	 * The base device tree might have been damaged, erase its
+	 * magic.
+	 */
+	fdt_set_magic(fdt, ~0);
+
+	return ret;
+}
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
index aecd278..6846ad2 100644
--- a/scripts/dtc/livetree.c
+++ b/scripts/dtc/livetree.c
@@ -216,6 +216,28 @@
 	return old_node;
 }
 
+void add_orphan_node(struct node *dt, struct node *new_node, char *ref)
+{
+	static unsigned int next_orphan_fragment = 0;
+	struct node *node;
+	struct property *p;
+	struct data d = empty_data;
+	char *name;
+
+	d = data_add_marker(d, REF_PHANDLE, ref);
+	d = data_append_integer(d, 0xffffffff, 32);
+
+	p = build_property("target", d);
+
+	xasprintf(&name, "fragment@%u",
+			next_orphan_fragment++);
+	name_node(new_node, "__overlay__");
+	node = build_node(p, new_node);
+	name_node(node, name);
+
+	add_child(dt, node);
+}
+
 struct node *chain_node(struct node *first, struct node *list)
 {
 	assert(first->next_sibling == NULL);
@@ -396,6 +418,12 @@
 	return fdt32_to_cpu(*((fdt32_t *)prop->val.val));
 }
 
+cell_t propval_cell_n(struct property *prop, int n)
+{
+	assert(prop->val.len / sizeof(cell_t) >= n);
+	return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n));
+}
+
 struct property *get_property_by_label(struct node *tree, const char *label,
 				       struct node **node)
 {
diff --git a/scripts/dtc/pylibfdt/.gitignore b/scripts/dtc/pylibfdt/.gitignore
new file mode 100644
index 0000000..033f23d
--- /dev/null
+++ b/scripts/dtc/pylibfdt/.gitignore
@@ -0,0 +1,4 @@
+/_libfdt.so
+/libfdt.py
+/libfdt.pyc
+/libfdt_wrap.c
diff --git a/scripts/dtc/pylibfdt/Makefile b/scripts/dtc/pylibfdt/Makefile
new file mode 100644
index 0000000..01d5e0f
--- /dev/null
+++ b/scripts/dtc/pylibfdt/Makefile
@@ -0,0 +1,30 @@
+# Unfortunately setup.py below cannot handle srctree being ".." which it often
+# is. It fails with an error like:
+# Fatal error: can't create build/temp.linux-x86_64-2.7/../lib/libfdt/fdt.o:
+#    No such file or directory
+# To fix this, use an absolute path.
+LIBFDT_srcdir = $(abspath $(srctree)/$(src)/../libfdt)
+
+include $(LIBFDT_srcdir)/Makefile.libfdt
+
+# Unfortunately setup.py (or actually the Python distutil implementation) puts
+# files into the same directory as the .i file. We cannot touch the source
+# directory, so we "ship" .i file into the objtree.
+PYLIBFDT_srcs = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_SRCS)) \
+		$(obj)/libfdt.i
+
+quiet_cmd_pymod = PYMOD   $@
+      cmd_pymod = unset CC; unset CROSS_COMPILE; unset CFLAGS;\
+		LDFLAGS="$(HOSTLDFLAGS)" \
+		VERSION="u-boot-$(UBOOTVERSION)" \
+		CPPFLAGS="$(HOSTCFLAGS) -I$(LIBFDT_srcdir)" OBJDIR=$(obj) \
+		SOURCES="$(PYLIBFDT_srcs)" \
+		SWIG_OPTS="-I$(LIBFDT_srcdir) -I$(LIBFDT_srcdir)/.." \
+		$(PYTHON) $< --quiet build_ext --inplace
+
+$(obj)/_libfdt.so: $(src)/setup.py $(PYLIBFDT_srcs) FORCE
+	$(call if_changed,pymod)
+
+always += _libfdt.so
+
+clean-files += libfdt.i _libfdt.so libfdt.py libfdt_wrap.c
diff --git a/lib/libfdt/pylibfdt/libfdt.i b/scripts/dtc/pylibfdt/libfdt.i_shipped
similarity index 100%
rename from lib/libfdt/pylibfdt/libfdt.i
rename to scripts/dtc/pylibfdt/libfdt.i_shipped
diff --git a/lib/libfdt/pylibfdt/setup.py b/scripts/dtc/pylibfdt/setup.py
similarity index 100%
rename from lib/libfdt/pylibfdt/setup.py
rename to scripts/dtc/pylibfdt/setup.py
diff --git a/scripts/dtc/update-dtc-source.sh b/scripts/dtc/update-dtc-source.sh
index b8ebcc6..f3e5c59 100755
--- a/scripts/dtc/update-dtc-source.sh
+++ b/scripts/dtc/update-dtc-source.sh
@@ -34,7 +34,9 @@
 		srcpos.h treesource.c util.c util.h version_gen.h Makefile.dtc \
 		dtc-lexer.l dtc-parser.y"
 DTC_GENERATED="dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h"
-LIBFDT_SOURCE="Makefile.libfdt fdt.c fdt.h fdt_empty_tree.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c fdt_wip.c libfdt.h libfdt_env.h libfdt_internal.h"
+LIBFDT_SOURCE="Makefile.libfdt fdt.c fdt.h fdt_addresses.c fdt_empty_tree.c \
+		fdt_overlay.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c \
+		fdt_wip.c libfdt.h libfdt_env.h libfdt_internal.h"
 
 get_last_dtc_version() {
 	git log --oneline scripts/dtc/ | grep 'upstream' | head -1 | sed -e 's/^.* \(.*\)/\1/'
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h
index b5ed715..d88393c 100644
--- a/scripts/dtc/version_gen.h
+++ b/scripts/dtc/version_gen.h
@@ -1 +1 @@
-#define DTC_VERSION "DTC 1.4.4-gfe50bd1e"
+#define DTC_VERSION "DTC 1.4.5-gb1a60033"
diff --git a/test/py/multiplexed_log.css b/test/py/multiplexed_log.css
index f135b10..9b7c44f 100644
--- a/test/py/multiplexed_log.css
+++ b/test/py/multiplexed_log.css
@@ -62,6 +62,10 @@
     color: #8080ff
 }
 
+.timestamp {
+    color: #8080ff
+}
+
 .status-pass {
     color: #00ff00
 }
diff --git a/test/py/multiplexed_log.py b/test/py/multiplexed_log.py
index 5bc1bc4..8ca5153 100644
--- a/test/py/multiplexed_log.py
+++ b/test/py/multiplexed_log.py
@@ -7,6 +7,7 @@
 # each represented in a well-delineated/-structured fashion.
 
 import cgi
+import datetime
 import os.path
 import shutil
 import subprocess
@@ -164,6 +165,7 @@
         self.logfile.write(self, output)
         if self.chained_file:
             self.chained_file.write(output)
+        self.logfile.timestamp()
 
         # Store the output so it can be accessed if we raise an exception.
         self.output = output
@@ -219,6 +221,9 @@
         self.blocks = []
         self.cur_evt = 1
         self.anchor = 0
+        self.timestamp_start = self._get_time()
+        self.timestamp_prev = self.timestamp_start
+        self.timestamp_blocks = []
 
         shutil.copy(mod_dir + '/multiplexed_log.css', os.path.dirname(fn))
         self.f.write('''\
@@ -388,6 +393,7 @@
 
         self._terminate_stream()
         self.blocks.append(marker)
+        self.timestamp_blocks.append(self._get_time())
         if not anchor:
             self.anchor += 1
             anchor = str(self.anchor)
@@ -396,6 +402,7 @@
         self.f.write('<div class="section-header block-header">Section: ' +
                      blk_path + '</div>\n')
         self.f.write('<div class="section-content block-content">\n')
+        self.timestamp()
 
         return anchor
 
@@ -416,6 +423,11 @@
             raise Exception('Block nesting mismatch: "%s" "%s"' %
                             (marker, '/'.join(self.blocks)))
         self._terminate_stream()
+        timestamp_now = self._get_time()
+        timestamp_section_start = self.timestamp_blocks.pop()
+        delta_section = timestamp_now - timestamp_section_start
+        self._note("timestamp",
+            "TIME: SINCE-SECTION: " + str(delta_section))
         blk_path = '/'.join(self.blocks)
         self.f.write('<div class="section-trailer block-trailer">' +
                      'End section: ' + blk_path + '</div>\n')
@@ -492,6 +504,31 @@
 
         self._note("action", msg)
 
+    def _get_time(self):
+        return datetime.datetime.now()
+
+    def timestamp(self):
+        """Write a timestamp to the log file.
+
+        Args:
+            None
+
+        Returns:
+            Nothing.
+        """
+
+        timestamp_now = self._get_time()
+        delta_prev = timestamp_now - self.timestamp_prev
+        delta_start = timestamp_now - self.timestamp_start
+        self.timestamp_prev = timestamp_now
+
+        self._note("timestamp",
+            "TIME: NOW: " + timestamp_now.strftime("%Y/%m/%d %H:%M:%S.%f"))
+        self._note("timestamp",
+            "TIME: SINCE-PREV: " + str(delta_prev))
+        self._note("timestamp",
+            "TIME: SINCE-START: " + str(delta_start))
+
     def status_pass(self, msg, anchor=None):
         """Write a note to the log file describing test(s) which passed.
 
diff --git a/test/py/u_boot_console_base.py b/test/py/u_boot_console_base.py
index eedf73f..4bccd72 100644
--- a/test/py/u_boot_console_base.py
+++ b/test/py/u_boot_console_base.py
@@ -215,6 +215,8 @@
             self.log.error(str(ex))
             self.cleanup_spawn()
             raise
+        finally:
+            self.log.timestamp()
 
     def run_command_list(self, cmds):
         """Run a list of commands.
@@ -370,6 +372,7 @@
             self.cleanup_spawn()
             raise
         finally:
+            self.log.timestamp()
             self.log.end_section('Starting U-Boot')
 
     def cleanup_spawn(self):
diff --git a/tools/.gitignore b/tools/.gitignore
index 5293d44..6a487d2 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -1,4 +1,3 @@
-/_libfdt.so
 /atmel_pmecc_params
 /bin2header
 /bmp_logo
@@ -17,9 +16,6 @@
 /img2srec
 /kwboot
 /lib/
-/libfdt.py
-/libfdt.pyc
-/libfdt_wrap.c
 /mips-relocs
 /mkenvimage
 /mkexynosspl
diff --git a/tools/Makefile b/tools/Makefile
index 5db2a54..acbcd87 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -58,21 +58,17 @@
 hostprogs-$(CONFIG_FIT_SIGNATURE) += fit_info fit_check_sign
 
 FIT_SIG_OBJS-$(CONFIG_FIT_SIGNATURE) := common/image-sig.o
-# Flattened device tree objects
-LIBFDT_CSRCS := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c  \
-			fdt_empty_tree.c fdt_addresses.c fdt_overlay.c \
-			fdt_region.c
 
-# Unfortunately setup.py below cannot handle srctree being ".." which it often
-# is. It fails with an error like:
-# Fatal error: can't create build/temp.linux-x86_64-2.7/../lib/libfdt/fdt.o:
-#    No such file or directory
-# To fix this, use an absolute path.
-libfdt_tree := $(shell readlink -f $(srctree)/lib/libfdt)
+# The following files are synced with upstream DTC.
+# Use synced versions from scripts/dtc/libfdt/.
+LIBFDT_SRCS_SYNCED := fdt.c fdt_sw.c fdt_strerror.c fdt_empty_tree.c \
+		      fdt_addresses.c fdt_overlay.c
+# The following files are locally modified for U-Boot (unfotunately).
+# Use U-Boot own versions from lib/libfdt/.
+LIBFDT_SRCS_UNSYNCED := fdt_ro.c fdt_wip.c fdt_rw.c fdt_region.c
 
-LIBFDT_SRCS := $(addprefix $(libfdt_tree)/, $(LIBFDT_CSRCS))
-LIBFDT_SWIG := $(addprefix $(libfdt_tree)/, pylibfdt/libfdt.i)
-LIBFDT_OBJS := $(addprefix lib/libfdt/, $(patsubst %.c, %.o, $(LIBFDT_CSRCS)))
+LIBFDT_OBJS := $(addprefix libfdt/, $(patsubst %.c, %.o, $(LIBFDT_SRCS_SYNCED))) \
+	       $(addprefix lib/libfdt/, $(patsubst %.c, %.o, $(LIBFDT_SRCS_UNSYNCED)))
 
 RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/rsa/, \
 					rsa-sign.o rsa-verify.o rsa-checksum.o \
@@ -123,23 +119,6 @@
 fit_info-objs   := $(dumpimage-mkimage-objs) fit_info.o
 fit_check_sign-objs   := $(dumpimage-mkimage-objs) fit_check_sign.o
 
-# Unfortunately setup.py (or actually the Python distutil implementation)
-# puts files into the same directory as the .i file. We cannot touch the source
-# directory, so we copy the .i file into the tools/ build subdirectory before
-# calling setup. This directory is safe to write to. This ensures that we get
-# all three files in $(obj)/tools: _libfdt.so, libfdt.py and libfdt_wrap.c
-# The latter is a temporary file which we could actually remove.
-tools/_libfdt.so: $(LIBFDT_SRCS) $(LIBFDT_SWIG)
-	$(Q)cp $(LIBFDT_SWIG) tools/.
-	$(Q)unset CC; \
-	unset CROSS_COMPILE; \
-	LDFLAGS="$(HOSTLDFLAGS)" CFLAGS= VERSION="u-boot-$(UBOOTVERSION)" \
-		CPPFLAGS="$(_hostc_flags)" OBJDIR=tools \
-		SOURCES="$(LIBFDT_SRCS) tools/libfdt.i" \
-		SWIG_OPTS="-I$(srctree)/lib/libfdt -I$(srctree)/lib" \
-		$(PYTHON) $(libfdt_tree)/pylibfdt/setup.py --quiet build_ext \
-			--build-lib tools
-
 ifneq ($(CONFIG_MX23)$(CONFIG_MX28),)
 # Add CONFIG_MXS into host CFLAGS, so we can check whether or not register
 # the mxsimage support within tools/mxsimage.c .
@@ -231,10 +210,6 @@
 
 always := $(hostprogs-y)
 
-# Build a libfdt Python module if swig is available
-# Use 'sudo apt-get install swig libpython-dev' to enable this
-always += $(if $(shell which swig 2> /dev/null),_libfdt.so)
-
 # Generated LCD/video logo
 LOGO_H = $(objtree)/include/bmp_logo.h
 LOGO_DATA_H = $(objtree)/include/bmp_logo_data.h
diff --git a/tools/binman/binman.py b/tools/binman/binman.py
index 09dc36a..e75a59d 100755
--- a/tools/binman/binman.py
+++ b/tools/binman/binman.py
@@ -21,7 +21,7 @@
     sys.path.insert(0, os.path.join(our_path, dirname))
 
 # Bring in the libfdt module
-sys.path.insert(0, 'tools')
+sys.path.insert(0, 'scripts/dtc/pylibfdt')
 
 # Also allow entry-type modules to be brought in from the etype directory.
 sys.path.insert(0, os.path.join(our_path, 'etype'))
diff --git a/tools/libfdt/fdt.c b/tools/libfdt/fdt.c
new file mode 100644
index 0000000..8ba8091
--- /dev/null
+++ b/tools/libfdt/fdt.c
@@ -0,0 +1,2 @@
+#include "fdt_host.h"
+#include "../scripts/dtc/libfdt/fdt.c"
diff --git a/tools/libfdt/fdt_addresses.c b/tools/libfdt/fdt_addresses.c
new file mode 100644
index 0000000..242a2c0
--- /dev/null
+++ b/tools/libfdt/fdt_addresses.c
@@ -0,0 +1,2 @@
+#include "fdt_host.h"
+#include "../scripts/dtc/libfdt/fdt_addresses.c"
diff --git a/tools/libfdt/fdt_empty_tree.c b/tools/libfdt/fdt_empty_tree.c
new file mode 100644
index 0000000..9ccbb1f
--- /dev/null
+++ b/tools/libfdt/fdt_empty_tree.c
@@ -0,0 +1,2 @@
+#include "fdt_host.h"
+#include "../scripts/dtc/libfdt/fdt_empty_tree.c"
diff --git a/tools/libfdt/fdt_overlay.c b/tools/libfdt/fdt_overlay.c
new file mode 100644
index 0000000..801ec37
--- /dev/null
+++ b/tools/libfdt/fdt_overlay.c
@@ -0,0 +1,2 @@
+#include "fdt_host.h"
+#include "../scripts/dtc/libfdt/fdt_overlay.c"
diff --git a/tools/libfdt/fdt_strerror.c b/tools/libfdt/fdt_strerror.c
new file mode 100644
index 0000000..d7ed70b
--- /dev/null
+++ b/tools/libfdt/fdt_strerror.c
@@ -0,0 +1,2 @@
+#include "fdt_host.h"
+#include "../scripts/dtc/libfdt/fdt_strerror.c"
diff --git a/tools/libfdt/fdt_sw.c b/tools/libfdt/fdt_sw.c
new file mode 100644
index 0000000..ed6b327
--- /dev/null
+++ b/tools/libfdt/fdt_sw.c
@@ -0,0 +1,2 @@
+#include "fdt_host.h"
+#include "../scripts/dtc/libfdt/fdt_sw.c"