diff --git a/README b/README
index fb331f910d0cf73c7a6f33212a33febb589d14b2..b1ddf89fc588290a85311c713260df3718e1c86e 100644
--- a/README
+++ b/README
@@ -2625,6 +2625,10 @@ FIT uImage format:
 		CONFIG_SPL_NAND_DRIVERS
 		SPL uses normal NAND drivers, not minimal drivers.
 
+		CONFIG_SPL_NAND_IDENT
+		SPL uses the chip ID list to identify the NAND flash.
+		Requires CONFIG_SPL_NAND_BASE.
+
 		CONFIG_SPL_NAND_ECC
 		Include standard software ECC in the SPL
 
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
index 8fef4019af167cfb1302272dae072f6adfc16992..7818d729086bccd13a5eff93aeb7d83dfa36d953 100644
--- a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
+++ b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
@@ -15,7 +15,7 @@
 
 #include "mxs_init.h"
 
-static uint32_t dram_vals[] = {
+__weak uint32_t mxs_dram_vals[] = {
 /*
  * i.MX28 DDR2 at 200MHz
  */
@@ -100,11 +100,11 @@ static void initialize_dram_values(void)
 	int i;
 
 	debug("SPL: Setting mx28 board specific SDRAM parameters\n");
-	mxs_adjust_memory_params(dram_vals);
+	mxs_adjust_memory_params(mxs_dram_vals);
 
 	debug("SPL: Applying SDRAM parameters\n");
-	for (i = 0; i < ARRAY_SIZE(dram_vals); i++)
-		writel(dram_vals[i], MXS_DRAM_BASE + (4 * i));
+	for (i = 0; i < ARRAY_SIZE(mxs_dram_vals); i++)
+		writel(mxs_dram_vals[i], MXS_DRAM_BASE + (4 * i));
 }
 #else
 static void initialize_dram_values(void)
@@ -112,7 +112,7 @@ static void initialize_dram_values(void)
 	int i;
 
 	debug("SPL: Setting mx23 board specific SDRAM parameters\n");
-	mxs_adjust_memory_params(dram_vals);
+	mxs_adjust_memory_params(mxs_dram_vals);
 
 	/*
 	 * HW_DRAM_CTL27, HW_DRAM_CTL28 and HW_DRAM_CTL35 are not initialized as
@@ -124,10 +124,10 @@ static void initialize_dram_values(void)
 	 * So skip the initialization of these HW_DRAM_CTL registers.
 	 */
 	debug("SPL: Applying SDRAM parameters\n");
-	for (i = 0; i < ARRAY_SIZE(dram_vals); i++) {
+	for (i = 0; i < ARRAY_SIZE(mxs_dram_vals); i++) {
 		if (i == 8 || i == 27 || i == 28 || i == 35)
 			continue;
-		writel(dram_vals[i], MXS_DRAM_BASE + (4 * i));
+		writel(mxs_dram_vals[i], MXS_DRAM_BASE + (4 * i));
 	}
 
 	/*
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 493652ea8c43256071b05ab92fb155ff60266188..baad87d4d725d1bd54175fcc950e62fa74ae0ba1 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -425,7 +425,7 @@ dtb-$(CONFIG_MX6SX) += \
 	imx6sx-sdb.dtb
 
 dtb-$(CONFIG_MX6UL) += \
-	imx6ul-geam-kit.dtb \
+	imx6ul-geam.dtb \
 	imx6ul-isiot-emmc.dtb \
 	imx6ul-isiot-nand.dtb \
 	imx6ul-opos6uldev.dtb
diff --git a/arch/arm/dts/imx53-kp.dts b/arch/arm/dts/imx53-kp.dts
index fd64a9f2f6dd00147e2bab13c65ba19bdf3c5412..ca98fb59c61c450888dce9dcc2c6eae281873122 100644
--- a/arch/arm/dts/imx53-kp.dts
+++ b/arch/arm/dts/imx53-kp.dts
@@ -86,6 +86,10 @@
 				MX53_PAD_PATA_DA_2__GPIO7_8 0x1e4
 				/* BOOSTER_OFF */
 				MX53_PAD_EIM_CS0__GPIO2_23 0x1e4
+				/* LCD BACKLIGHT */
+				MX53_PAD_GPIO_1__GPIO1_1 0x1e4
+				/* KEY1 GPIO */
+				MX53_PAD_EIM_RW__GPIO2_26 0x1e4
 			>;
 		};
 
diff --git a/arch/arm/dts/imx6ul-geam-kit-u-boot.dtsi b/arch/arm/dts/imx6ul-geam-u-boot.dtsi
similarity index 100%
rename from arch/arm/dts/imx6ul-geam-kit-u-boot.dtsi
rename to arch/arm/dts/imx6ul-geam-u-boot.dtsi
diff --git a/arch/arm/dts/imx6ul-geam-kit.dts b/arch/arm/dts/imx6ul-geam.dts
similarity index 100%
rename from arch/arm/dts/imx6ul-geam-kit.dts
rename to arch/arm/dts/imx6ul-geam.dts
diff --git a/arch/arm/dts/imx7-colibri.dts b/arch/arm/dts/imx7-colibri.dts
index a2cade762a1ea20ac40950688ff67b33920a401a..dca501be25ccd7518416d1d19bf0ea01a739feae 100644
--- a/arch/arm/dts/imx7-colibri.dts
+++ b/arch/arm/dts/imx7-colibri.dts
@@ -16,6 +16,15 @@
 	};
 };
 
+&gpmi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpmi_nand>;
+	fsl,use-minimum-ecc;
+	nand-on-flash-bbt;
+	nand-ecc-mode = "hw";
+	status = "okay";
+};
+
 &i2c1 {
 	pinctrl-names = "default", "gpio";
 	pinctrl-0 = <&pinctrl_i2c1>;
@@ -48,6 +57,25 @@
 };
 
 &iomuxc {
+	pinctrl_gpmi_nand: gpmi-nand-grp {
+		fsl,pins = <
+			MX7D_PAD_SD3_CLK__NAND_CLE		0x71
+			MX7D_PAD_SD3_CMD__NAND_ALE		0x71
+			MX7D_PAD_SAI1_TX_BCLK__NAND_CE0_B	0x71
+			MX7D_PAD_SAI1_TX_DATA__NAND_READY_B	0x74
+			MX7D_PAD_SD3_STROBE__NAND_RE_B		0x71
+			MX7D_PAD_SD3_RESET_B__NAND_WE_B		0x71
+			MX7D_PAD_SD3_DATA0__NAND_DATA00		0x71
+			MX7D_PAD_SD3_DATA1__NAND_DATA01		0x71
+			MX7D_PAD_SD3_DATA2__NAND_DATA02		0x71
+			MX7D_PAD_SD3_DATA3__NAND_DATA03		0x71
+			MX7D_PAD_SD3_DATA4__NAND_DATA04		0x71
+			MX7D_PAD_SD3_DATA5__NAND_DATA05		0x71
+			MX7D_PAD_SD3_DATA6__NAND_DATA06		0x71
+			MX7D_PAD_SD3_DATA7__NAND_DATA07		0x71
+		>;
+	};
+
 	pinctrl_i2c4: i2c4-grp {
 		fsl,pins = <
 			MX7D_PAD_ENET1_RGMII_TD3__I2C4_SDA	0x4000007f
diff --git a/arch/arm/dts/imx7s.dtsi b/arch/arm/dts/imx7s.dtsi
index a7d48e785d34113d3796fb6858194351010b6705..4d42335c0dee991aa18ff8c40526865eb89cd97c 100644
--- a/arch/arm/dts/imx7s.dtsi
+++ b/arch/arm/dts/imx7s.dtsi
@@ -42,6 +42,7 @@
  */
 
 #include <dt-bindings/clock/imx7d-clock.h>
+#include <dt-bindings/power/imx7-power.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -57,7 +58,7 @@
 	 * Also for U-Boot there must be a pre-existing /memory node.
 	 */
 	chosen {};
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory { device_type = "memory"; };
 
 	aliases {
 		gpio0 = &gpio1;
@@ -115,11 +116,77 @@
 		clock-output-names = "osc";
 	};
 
+	usbphynop1: usbphynop1 {
+		compatible = "usb-nop-xceiv";
+		clocks = <&clks IMX7D_USB_PHY1_CLK>;
+		clock-names = "main_clk";
+		#phy-cells = <0>;
+	};
+
+	usbphynop3: usbphynop3 {
+		compatible = "usb-nop-xceiv";
+		clocks = <&clks IMX7D_USB_HSIC_ROOT_CLK>;
+		clock-names = "main_clk";
+		#phy-cells = <0>;
+	};
+
+	pmu {
+		compatible = "arm,cortex-a7-pmu";
+		interrupt-parent = <&gpc>;
+		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>;
+	};
+
+	replicator {
+		/*
+		 * non-configurable replicators don't show up on the
+		 * AMBA bus.  As such no need to add "arm,primecell"
+		 */
+		compatible = "arm,coresight-replicator";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+				/* replicator output ports */
+			port@0 {
+				reg = <0>;
+				replicator_out_port0: endpoint {
+					remote-endpoint = <&tpiu_in_port>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				replicator_out_port1: endpoint {
+					remote-endpoint = <&etr_in_port>;
+				};
+			};
+
+			/* replicator input port */
+			port@2 {
+				reg = <0>;
+				replicator_in_port0: endpoint {
+					slave-mode;
+					remote-endpoint = <&etf_out_port>;
+				};
+			};
+		};
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupt-parent = <&intc>;
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
 	soc {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "simple-bus";
-		interrupt-parent = <&intc>;
+		interrupt-parent = <&gpc>;
 		ranges;
 
 		funnel@30041000 {
@@ -259,62 +326,18 @@
 			};
 		};
 
-		replicator {
-			/*
-			 * non-configurable replicators don't show up on the
-			 * AMBA bus.  As such no need to add "arm,primecell"
-			 */
-			compatible = "arm,coresight-replicator";
-
-			ports {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				/* replicator output ports */
-				port@0 {
-					reg = <0>;
-					replicator_out_port0: endpoint {
-						remote-endpoint = <&tpiu_in_port>;
-					};
-				};
-
-				port@1 {
-					reg = <1>;
-					replicator_out_port1: endpoint {
-						remote-endpoint = <&etr_in_port>;
-					};
-				};
-
-				/* replicator input port */
-				port@2 {
-					reg = <0>;
-					replicator_in_port0: endpoint {
-						slave-mode;
-						remote-endpoint = <&etf_out_port>;
-					};
-				};
-			};
-		};
-
 		intc: interrupt-controller@31001000 {
 			compatible = "arm,cortex-a7-gic";
 			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			interrupt-parent = <&intc>;
 			reg = <0x31001000 0x1000>,
 			      <0x31002000 0x2000>,
 			      <0x31004000 0x2000>,
 			      <0x31006000 0x2000>;
 		};
 
-		timer {
-			compatible = "arm,armv7-timer";
-			interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-				     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-				     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-				     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
-		};
-
 		aips1: aips-bus@30000000 {
 			compatible = "fsl,aips-bus", "simple-bus";
 			#address-cells = <1>;
@@ -482,20 +505,49 @@
 				status = "disabled";
 			};
 
+			kpp: kpp@30320000 {
+				compatible = "fsl,imx7d-kpp", "fsl,imx21-kpp";
+				reg = <0x30320000 0x10000>;
+				interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX7D_KPP_ROOT_CLK>;
+				status = "disabled";
+			};
+
 			iomuxc: iomuxc@30330000 {
 				compatible = "fsl,imx7d-iomuxc";
 				reg = <0x30330000 0x10000>;
 			};
 
 			gpr: iomuxc-gpr@30340000 {
-				compatible = "fsl,imx7d-iomuxc-gpr", "syscon";
+				compatible = "fsl,imx7d-iomuxc-gpr",
+					"fsl,imx6q-iomuxc-gpr", "syscon";
 				reg = <0x30340000 0x10000>;
 			};
 
 			ocotp: ocotp-ctrl@30350000 {
+				#address-cells = <1>;
+				#size-cells = <1>;
 				compatible = "fsl,imx7d-ocotp", "syscon";
 				reg = <0x30350000 0x10000>;
 				clocks = <&clks IMX7D_OCOTP_CLK>;
+
+				tempmon_calib: calib@3c {
+					reg = <0x3c 0x4>;
+				};
+
+				tempmon_temp_grade: temp-grade@10 {
+					reg = <0x10 0x4>;
+				};
+			};
+
+			tempmon: tempmon {
+				compatible = "fsl,imx7d-tempmon";
+				interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+				fsl,tempmon =<&anatop>;
+				nvmem-cells = <&tempmon_calib>,
+					<&tempmon_temp_grade>;
+				nvmem-cell-names = "calib", "temp_grade";
+				clocks = <&clks IMX7D_PLL_SYS_MAIN_CLK>;
 			};
 
 			anatop: anatop@30360000 {
@@ -504,8 +556,11 @@
 				reg = <0x30360000 0x10000>;
 				interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
 					<GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
 
-				reg_1p0d: regulator-vdd1p0d {
+				reg_1p0d: regulator-vdd1p0d@30360210 {
+					reg = <0x30360210>;
 					compatible = "fsl,anatop-regulator";
 					regulator-name = "vdd1p0d";
 					regulator-min-microvolt = <800000>;
@@ -516,6 +571,7 @@
 					anatop-min-bit-val = <8>;
 					anatop-min-voltage = <800000>;
 					anatop-max-voltage = <1200000>;
+					anatop-enable-bit = <0>;
 				};
 			};
 
@@ -529,12 +585,15 @@
 					offset = <0x34>;
 					interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
 						     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_SNVS_CLK>;
+					clock-names = "snvs-rtc";
 				};
 
 				snvs_poweroff: snvs-poweroff {
 					compatible = "syscon-poweroff";
 					regmap = <&snvs>;
 					offset = <0x38>;
+					value = <0x60>;
 					mask = <0x60>;
 				};
 
@@ -558,11 +617,32 @@
 			};
 
 			src: src@30390000 {
-				compatible = "fsl,imx7d-src", "fsl,imx51-src", "syscon";
+				compatible = "fsl,imx7d-src", "syscon";
 				reg = <0x30390000 0x10000>;
 				interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
 				#reset-cells = <1>;
 			};
+
+			gpc: gpc@303a0000 {
+				compatible = "fsl,imx7d-gpc";
+				reg = <0x303a0000 0x10000>;
+				interrupt-controller;
+				interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+				#interrupt-cells = <3>;
+				interrupt-parent = <&intc>;
+				#power-domain-cells = <1>;
+
+				pgc {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					pgc_pcie_phy: pgc-power-domain@1 {
+						#power-domain-cells = <0>;
+						reg = <1>;
+						power-supply = <&reg_1p0d>;
+					};
+				};
+			};
 		};
 
 		aips2: aips-bus@30400000 {
@@ -609,7 +689,7 @@
 				clocks = <&clks IMX7D_PWM1_ROOT_CLK>,
 					 <&clks IMX7D_PWM1_ROOT_CLK>;
 				clock-names = "ipg", "per";
-				#pwm-cells = <2>;
+				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
@@ -620,7 +700,7 @@
 				clocks = <&clks IMX7D_PWM2_ROOT_CLK>,
 					 <&clks IMX7D_PWM2_ROOT_CLK>;
 				clock-names = "ipg", "per";
-				#pwm-cells = <2>;
+				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
@@ -631,7 +711,7 @@
 				clocks = <&clks IMX7D_PWM3_ROOT_CLK>,
 					 <&clks IMX7D_PWM3_ROOT_CLK>;
 				clock-names = "ipg", "per";
-				#pwm-cells = <2>;
+				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
@@ -642,7 +722,7 @@
 				clocks = <&clks IMX7D_PWM4_ROOT_CLK>,
 					 <&clks IMX7D_PWM4_ROOT_CLK>;
 				clock-names = "ipg", "per";
-				#pwm-cells = <2>;
+				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
@@ -664,118 +744,156 @@
 			reg = <0x30800000 0x400000>;
 			ranges;
 
-			ecspi1: ecspi@30820000 {
+			spba-bus@30800000 {
+				compatible = "fsl,spba-bus", "simple-bus";
 				#address-cells = <1>;
-				#size-cells = <0>;
-				compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi";
-				reg = <0x30820000 0x10000>;
-				interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_ECSPI1_ROOT_CLK>,
-					<&clks IMX7D_ECSPI1_ROOT_CLK>;
-				clock-names = "ipg", "per";
-				status = "disabled";
-			};
+				#size-cells = <1>;
+				reg = <0x30800000 0x100000>;
+				ranges;
+
+				ecspi1: ecspi@30820000 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi";
+					reg = <0x30820000 0x10000>;
+					interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_ECSPI1_ROOT_CLK>,
+						<&clks IMX7D_ECSPI1_ROOT_CLK>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
 
-			ecspi2: ecspi@30830000 {
-				#address-cells = <1>;
-				#size-cells = <0>;
-				compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi";
-				reg = <0x30830000 0x10000>;
-				interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_ECSPI2_ROOT_CLK>,
-					<&clks IMX7D_ECSPI2_ROOT_CLK>;
-				clock-names = "ipg", "per";
-				status = "disabled";
-			};
+				ecspi2: ecspi@30830000 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi";
+					reg = <0x30830000 0x10000>;
+					interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_ECSPI2_ROOT_CLK>,
+						<&clks IMX7D_ECSPI2_ROOT_CLK>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
 
-			ecspi3: ecspi@30840000 {
-				#address-cells = <1>;
-				#size-cells = <0>;
-				compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi";
-				reg = <0x30840000 0x10000>;
-				interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_ECSPI3_ROOT_CLK>,
-					<&clks IMX7D_ECSPI3_ROOT_CLK>;
-				clock-names = "ipg", "per";
-				status = "disabled";
-			};
+				ecspi3: ecspi@30840000 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi";
+					reg = <0x30840000 0x10000>;
+					interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_ECSPI3_ROOT_CLK>,
+						<&clks IMX7D_ECSPI3_ROOT_CLK>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
 
-			uart1: serial@30860000 {
-				compatible = "fsl,imx7d-uart",
-					     "fsl,imx6q-uart";
-				reg = <0x30860000 0x10000>;
-				interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_UART1_ROOT_CLK>,
-					<&clks IMX7D_UART1_ROOT_CLK>;
-				clock-names = "ipg", "per";
-				status = "disabled";
-			};
+				uart1: serial@30860000 {
+					compatible = "fsl,imx7d-uart",
+						     "fsl,imx6q-uart";
+					reg = <0x30860000 0x10000>;
+					interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_UART1_ROOT_CLK>,
+						<&clks IMX7D_UART1_ROOT_CLK>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
 
-			uart2: serial@30890000 {
-				compatible = "fsl,imx7d-uart",
-					     "fsl,imx6q-uart";
-				reg = <0x30890000 0x10000>;
-				interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_UART2_ROOT_CLK>,
-					<&clks IMX7D_UART2_ROOT_CLK>;
-				clock-names = "ipg", "per";
-				status = "disabled";
-			};
+				uart2: serial@30890000 {
+					compatible = "fsl,imx7d-uart",
+						     "fsl,imx6q-uart";
+					reg = <0x30890000 0x10000>;
+					interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_UART2_ROOT_CLK>,
+						<&clks IMX7D_UART2_ROOT_CLK>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
 
-			uart3: serial@30880000 {
-				compatible = "fsl,imx7d-uart",
-					     "fsl,imx6q-uart";
-				reg = <0x30880000 0x10000>;
-				interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_UART3_ROOT_CLK>,
-					<&clks IMX7D_UART3_ROOT_CLK>;
-				clock-names = "ipg", "per";
-				status = "disabled";
-			};
+				uart3: serial@30880000 {
+					compatible = "fsl,imx7d-uart",
+						     "fsl,imx6q-uart";
+					reg = <0x30880000 0x10000>;
+					interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_UART3_ROOT_CLK>,
+						<&clks IMX7D_UART3_ROOT_CLK>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
 
-			sai1: sai@308a0000 {
-				#sound-dai-cells = <0>;
-				compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai";
-				reg = <0x308a0000 0x10000>;
-				interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_SAI1_IPG_CLK>,
-					 <&clks IMX7D_SAI1_ROOT_CLK>,
-					 <&clks IMX7D_CLK_DUMMY>,
-					 <&clks IMX7D_CLK_DUMMY>;
-				clock-names = "bus", "mclk1", "mclk2", "mclk3";
-				dma-names = "rx", "tx";
-				dmas = <&sdma 8 24 0>, <&sdma 9 24 0>;
-				status = "disabled";
-			};
+				sai1: sai@308a0000 {
+					#sound-dai-cells = <0>;
+					compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai";
+					reg = <0x308a0000 0x10000>;
+					interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_SAI1_IPG_CLK>,
+						 <&clks IMX7D_SAI1_ROOT_CLK>,
+						 <&clks IMX7D_CLK_DUMMY>,
+						 <&clks IMX7D_CLK_DUMMY>;
+					clock-names = "bus", "mclk1", "mclk2", "mclk3";
+					dma-names = "rx", "tx";
+					dmas = <&sdma 8 24 0>, <&sdma 9 24 0>;
+					status = "disabled";
+				};
 
-			sai2: sai@308b0000 {
-				#sound-dai-cells = <0>;
-				compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai";
-				reg = <0x308b0000 0x10000>;
-				interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_SAI2_IPG_CLK>,
-					 <&clks IMX7D_SAI2_ROOT_CLK>,
-					 <&clks IMX7D_CLK_DUMMY>,
-					 <&clks IMX7D_CLK_DUMMY>;
-				clock-names = "bus", "mclk1", "mclk2", "mclk3";
-				dma-names = "rx", "tx";
-				dmas = <&sdma 10 24 0>, <&sdma 11 24 0>;
-				status = "disabled";
+				sai2: sai@308b0000 {
+					#sound-dai-cells = <0>;
+					compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai";
+					reg = <0x308b0000 0x10000>;
+					interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_SAI2_IPG_CLK>,
+						 <&clks IMX7D_SAI2_ROOT_CLK>,
+						 <&clks IMX7D_CLK_DUMMY>,
+						 <&clks IMX7D_CLK_DUMMY>;
+					clock-names = "bus", "mclk1", "mclk2", "mclk3";
+					dma-names = "rx", "tx";
+					dmas = <&sdma 10 24 0>, <&sdma 11 24 0>;
+					status = "disabled";
+				};
+
+				sai3: sai@308c0000 {
+					#sound-dai-cells = <0>;
+					compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai";
+					reg = <0x308c0000 0x10000>;
+					interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_SAI3_IPG_CLK>,
+						 <&clks IMX7D_SAI3_ROOT_CLK>,
+						 <&clks IMX7D_CLK_DUMMY>,
+						 <&clks IMX7D_CLK_DUMMY>;
+					clock-names = "bus", "mclk1", "mclk2", "mclk3";
+					dma-names = "rx", "tx";
+					dmas = <&sdma 12 24 0>, <&sdma 13 24 0>;
+					status = "disabled";
+				};
 			};
 
-			sai3: sai@308c0000 {
-				#sound-dai-cells = <0>;
-				compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai";
-				reg = <0x308c0000 0x10000>;
-				interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_SAI3_IPG_CLK>,
-					 <&clks IMX7D_SAI3_ROOT_CLK>,
-					 <&clks IMX7D_CLK_DUMMY>,
-					 <&clks IMX7D_CLK_DUMMY>;
-				clock-names = "bus", "mclk1", "mclk2", "mclk3";
-				dma-names = "rx", "tx";
-				dmas = <&sdma 12 24 0>, <&sdma 13 24 0>;
-				status = "disabled";
+			crypto: caam@30900000 {
+				compatible = "fsl,sec-v4.0";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				reg = <0x30900000 0x40000>;
+				ranges = <0 0x30900000 0x40000>;
+				interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX7D_CAAM_CLK>,
+					 <&clks IMX7D_AHB_CHANNEL_ROOT_CLK>;
+				clock-names = "ipg", "aclk";
+
+				sec_jr0: jr0@1000 {
+					compatible = "fsl,sec-v4.0-job-ring";
+					reg = <0x1000 0x1000>;
+					interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+				};
+
+				sec_jr1: jr1@2000 {
+					compatible = "fsl,sec-v4.0-job-ring";
+					reg = <0x2000 0x1000>;
+					interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+				};
+
+				sec_jr2: jr1@3000 {
+					compatible = "fsl,sec-v4.0-job-ring";
+					reg = <0x3000 0x1000>;
+					interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+				};
 			};
 
 			flexcan1: can@30a00000 {
@@ -918,24 +1036,12 @@
 				reg = <0x30b30200 0x200>;
 			};
 
-			usbphynop1: usbphynop1 {
-				compatible = "usb-nop-xceiv";
-				clocks = <&clks IMX7D_USB_PHY1_CLK>;
-				clock-names = "main_clk";
-			};
-
-			usbphynop3: usbphynop3 {
-				compatible = "usb-nop-xceiv";
-				clocks = <&clks IMX7D_USB_HSIC_ROOT_CLK>;
-				clock-names = "main_clk";
-			};
-
 			usdhc1: usdhc@30b40000 {
 				compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc";
 				reg = <0x30b40000 0x10000>;
 				interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_CLK_DUMMY>,
-					<&clks IMX7D_CLK_DUMMY>,
+				clocks = <&clks IMX7D_IPG_ROOT_CLK>,
+					<&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>,
 					<&clks IMX7D_USDHC1_ROOT_CLK>;
 				clock-names = "ipg", "ahb", "per";
 				bus-width = <4>;
@@ -946,8 +1052,8 @@
 				compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc";
 				reg = <0x30b50000 0x10000>;
 				interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_CLK_DUMMY>,
-					<&clks IMX7D_CLK_DUMMY>,
+				clocks = <&clks IMX7D_IPG_ROOT_CLK>,
+					<&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>,
 					<&clks IMX7D_USDHC2_ROOT_CLK>;
 				clock-names = "ipg", "ahb", "per";
 				bus-width = <4>;
@@ -958,8 +1064,8 @@
 				compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc";
 				reg = <0x30b60000 0x10000>;
 				interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_CLK_DUMMY>,
-					<&clks IMX7D_CLK_DUMMY>,
+				clocks = <&clks IMX7D_IPG_ROOT_CLK>,
+					<&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>,
 					<&clks IMX7D_USDHC3_ROOT_CLK>;
 				clock-names = "ipg", "ahb", "per";
 				bus-width = <4>;
@@ -980,9 +1086,11 @@
 			fec1: ethernet@30be0000 {
 				compatible = "fsl,imx7d-fec", "fsl,imx6sx-fec";
 				reg = <0x30be0000 0x10000>;
-				interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+				interrupt-names = "int0", "int1", "int2", "pps";
+				interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
 					<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
-					<GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+					<GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>,
 					<&clks IMX7D_ENET_AXI_ROOT_CLK>,
 					<&clks IMX7D_ENET1_TIME_ROOT_CLK>,
@@ -995,5 +1103,36 @@
 				status = "disabled";
 			};
 		};
+
+		dma_apbh: dma-apbh@33000000 {
+			compatible = "fsl,imx7d-dma-apbh", "fsl,imx28-dma-apbh";
+			reg = <0x33000000 0x2000>;
+			interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
+			#dma-cells = <1>;
+			dma-channels = <4>;
+			clocks = <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>;
+		};
+
+		gpmi: gpmi-nand@33002000{
+			compatible = "fsl,imx7d-gpmi-nand";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x33002000 0x2000>, <0x33004000 0x4000>;
+			reg-names = "gpmi-nand", "bch";
+			interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "bch";
+			clocks = <&clks IMX7D_NAND_RAWNAND_CLK>,
+				<&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>;
+			clock-names = "gpmi_io", "gpmi_bch_apb";
+			dmas = <&dma_apbh 0>;
+			dma-names = "rx-tx";
+			status = "disabled";
+			assigned-clocks = <&clks IMX7D_NAND_ROOT_SRC>;
+			assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_500M_CLK>;
+		};
 	};
 };
diff --git a/arch/arm/mach-imx/cache.c b/arch/arm/mach-imx/cache.c
index 11f90ed8a21ca41094b6edb61ab9fb3db23e5a5d..82257f3280f2c9a46c71168ac939bd68960ce515 100644
--- a/arch/arm/mach-imx/cache.c
+++ b/arch/arm/mach-imx/cache.c
@@ -9,6 +9,34 @@
 #include <asm/io.h>
 #include <asm/mach-imx/sys_proto.h>
 
+static void enable_ca7_smp(void)
+{
+	u32 val;
+
+	/* Read MIDR */
+	asm volatile ("mrc p15, 0, %0, c0, c0, 0\n\t" : "=r"(val));
+	val = (val >> 4);
+	val &= 0xf;
+
+	/* Only set the SMP for Cortex A7 */
+	if (val == 0x7) {
+		/* Read auxiliary control register */
+		asm volatile ("mrc p15, 0, %0, c1, c0, 1\n\t" : "=r"(val));
+
+		if (val & (1 << 6))
+			return;
+
+		/* Enable SMP */
+		val |= (1 << 6);
+
+		/* Write auxiliary control register */
+		asm volatile ("mcr p15, 0, %0, c1, c0, 1\n\t" : : "r"(val));
+
+		DSB;
+		ISB;
+	}
+}
+
 #ifndef CONFIG_SYS_DCACHE_OFF
 void enable_caches(void)
 {
@@ -20,6 +48,9 @@ void enable_caches(void)
 	/* Avoid random hang when download by usb */
 	invalidate_dcache_all();
 
+	/* Set ACTLR.SMP bit for Cortex-A7 */
+	enable_ca7_smp();
+
 	/* Enable D-cache. I-cache is already enabled in start.S */
 	dcache_enable();
 
@@ -31,6 +62,17 @@ void enable_caches(void)
 					IRAM_SIZE,
 					option);
 }
+#else
+void enable_caches(void)
+{
+	/*
+	 * Set ACTLR.SMP bit for Cortex-A7, even if the caches are
+	 * disabled by u-boot
+	 */
+	enable_ca7_smp();
+
+	puts("WARNING: Caches not enabled\n");
+}
 #endif
 
 #ifndef CONFIG_SYS_L2CACHE_OFF
diff --git a/arch/arm/mach-imx/mx7/soc.c b/arch/arm/mach-imx/mx7/soc.c
index f1dea66d60dd5a14d7299d294810a61cf714595f..2aca24bbb0f8869c8a86cd00dcfbf033b025dcee 100644
--- a/arch/arm/mach-imx/mx7/soc.c
+++ b/arch/arm/mach-imx/mx7/soc.c
@@ -280,13 +280,6 @@ const struct boot_mode soc_boot_modes[] = {
 
 void s_init(void)
 {
-#if !defined CONFIG_SPL_BUILD
-	/* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */
-	asm volatile(
-			"mrc p15, 0, r0, c1, c0, 1\n"
-			"orr r0, r0, #1 << 6\n"
-			"mcr p15, 0, r0, c1, c0, 1\n");
-#endif
 	/* clock configuration. */
 	clock_init();
 
diff --git a/board/engicam/common/board.c b/board/engicam/common/board.c
index fb37403aa1289c1b448722f92d75c7fc5745c26a..5dccb17cb27114396b116c5071c5293ccd2c2cf1 100644
--- a/board/engicam/common/board.c
+++ b/board/engicam/common/board.c
@@ -50,8 +50,8 @@ static void setenv_fdt_file(void)
 			env_set("fdt_file", "imx6q-icore-rqs.dtb");
 		else if (is_mx6dl() || is_mx6solo())
 			env_set("fdt_file", "imx6dl-icore-rqs.dtb");
-	} else if (!strcmp(cmp_dtb, "imx6ul-geam-kit"))
-		env_set("fdt_file", "imx6ul-geam-kit.dtb");
+	} else if (!strcmp(cmp_dtb, "imx6ul-geam"))
+		env_set("fdt_file", "imx6ul-geam.dtb");
 	else if (!strcmp(cmp_dtb, "imx6ul-isiot-mmc"))
 		env_set("fdt_file", "imx6ul-isiot-emmc.dtb");
 	else if (!strcmp(cmp_dtb, "imx6ul-isiot-emmc"))
diff --git a/board/engicam/common/spl.c b/board/engicam/common/spl.c
index 470d96aaedba01e364a910c9d13503578d69f2e5..1a1fe6c66a45d1b277af567f044a05b465163222 100644
--- a/board/engicam/common/spl.c
+++ b/board/engicam/common/spl.c
@@ -43,10 +43,14 @@ int board_fit_config_name_match(const char *name)
                 return 0;
         else if (is_mx6dq() && !strcmp(name, "imx6q-icore-rqs"))
                 return 0;
+        else if (is_mx6dq() && !strcmp(name, "imx6q-icore-mipi"))
+                return 0;
         else if ((is_mx6dl() || is_mx6solo()) && !strcmp(name, "imx6dl-icore"))
                 return 0;
         else if ((is_mx6dl() || is_mx6solo()) && !strcmp(name, "imx6dl-icore-rqs"))
                 return 0;
+        else if ((is_mx6dl() || is_mx6solo()) && !strcmp(name, "imx6dl-icore-mipi"))
+                return 0;
         else
                 return -1;
 }
diff --git a/board/ge/bx50v3/MAINTAINERS b/board/ge/bx50v3/MAINTAINERS
index 8e6079197f2b9a9713e15c340a621332bd7724b1..a44edd4c8933384e6a9665e5ed6e8e820916c06c 100644
--- a/board/ge/bx50v3/MAINTAINERS
+++ b/board/ge/bx50v3/MAINTAINERS
@@ -3,6 +3,7 @@ M:	Martin Donnelly <martin.donnelly@ge.com>
 S:	Maintained
 F:	board/ge/bx50v3/
 F:	include/configs/ge_bx50v3.h
+F:	configs/ge_bx50v3_defconfig
 F:	configs/ge_b450v3_defconfig
 F:	configs/ge_b650v3_defconfig
 F:	configs/ge_b850v3_defconfig
diff --git a/board/k+p/bootscripts/tpcboot.cmd b/board/k+p/bootscripts/tpcboot.cmd
index eac79dc890fcb7c9ee401821ccb355e12a429f8e..16b93ebe3f778acad9142370cb1163e2e561aa86 100644
--- a/board/k+p/bootscripts/tpcboot.cmd
+++ b/board/k+p/bootscripts/tpcboot.cmd
@@ -23,6 +23,10 @@ setenv mmcroot "/dev/mmcblk${devnum}p2 rootwait rw"
 setenv displayargs ""
 setenv mmcargs "setenv bootargs console=${console} ${smp} root=${mmcroot} \
 	${displayargs}"
+setenv miscadj "
+if test '${boardsoc}' = 'imx53'; then
+       setenv bootargs '${bootargs} di=${dig_in} key1=${key1}';
+fi;"
 setenv boot_fitImage "
 	setenv fdt_conf 'conf@${boardsoc}-${boardname}.dtb';
 	setenv itbcfg "\"#\${fdt_conf}\"";
@@ -39,6 +43,7 @@ if test -e ${devtype} ${devnum}:${distro_bootpart} ${kernel_file}; then
 	if load ${devtype} ${devnum}:${distro_bootpart} ${loadaddr} \
 	   ${kernel_file}; then
 		run mmcargs;
+		run miscadj;
 		run boot_fitImage;
 	fi;
 fi;"
@@ -52,6 +57,7 @@ setenv download_kernel "tftpboot ${loadaddr} ${kernel_file}"
 setenv boot_tftp_kernel "
 if run download_kernel; then
 	run mmcargs;
+	run miscadj;
 	run boot_fitImage;
 fi"
 
diff --git a/board/k+p/kp_imx53/kp_imx53.c b/board/k+p/kp_imx53/kp_imx53.c
index c80eed36c62304ed904c108435f019178c9370e1..becb6a63faaaa3eb96f3a2cd6c31023059c41bf6 100644
--- a/board/k+p/kp_imx53/kp_imx53.c
+++ b/board/k+p/kp_imx53/kp_imx53.c
@@ -22,6 +22,8 @@
 #define VBUS_PWR_EN IMX_GPIO_NR(7, 8)
 #define PHY_nRST IMX_GPIO_NR(7, 6)
 #define BOOSTER_OFF IMX_GPIO_NR(2, 23)
+#define LCD_BACKLIGHT IMX_GPIO_NR(1, 1)
+#define KEY1 IMX_GPIO_NR(2, 26)
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -43,18 +45,6 @@ int dram_init_banksize(void)
 	return 0;
 }
 
-u32 get_board_rev(void)
-{
-	struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
-	struct fuse_bank *bank = &iim->bank[0];
-	struct fuse_bank0_regs *fuse =
-		(struct fuse_bank0_regs *)bank->fuse_regs;
-
-	int rev = readl(&fuse->gp[6]);
-
-	return (get_cpu_rev() & ~(0xF << 8)) | (rev & 0xF) << 8;
-}
-
 #ifdef CONFIG_USB_EHCI_MX5
 int board_ehci_hcd_init(int port)
 {
@@ -189,10 +179,28 @@ void eth_phy_reset(void)
 	udelay(50);
 }
 
+void board_disable_display(void)
+{
+	gpio_request(LCD_BACKLIGHT, "LCD_BACKLIGHT");
+	gpio_direction_output(LCD_BACKLIGHT, 0);
+}
+
+void board_misc_setup(void)
+{
+	gpio_request(KEY1, "KEY1_GPIO");
+	gpio_direction_input(KEY1);
+
+	if (gpio_get_value(KEY1))
+		env_set("key1", "off");
+	else
+		env_set("key1", "on");
+}
+
 int board_late_init(void)
 {
 	int ret = 0;
 
+	board_disable_display();
 	setup_ups();
 
 	if (!power_init())
@@ -207,5 +215,7 @@ int board_late_init(void)
 	show_eeprom();
 	read_board_id();
 
+	board_misc_setup();
+
 	return ret;
 }
diff --git a/board/liebherr/display5/common.c b/board/liebherr/display5/common.c
index 26575f73bdcb2a504cbb61174e1dc27f6bf2fe39..4eb86d8c5d7faddf700d40780c7b95d9a7801a09 100644
--- a/board/liebherr/display5/common.c
+++ b/board/liebherr/display5/common.c
@@ -34,6 +34,16 @@ void displ5_set_iomux_uart(void)
 	SETUP_IOMUX_PADS(uart_pads);
 }
 
+iomux_v3_cfg_t const misc_pads_spl[] = {
+	/* Emergency recovery pin */
+	MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+void displ5_set_iomux_misc_spl(void)
+{
+	SETUP_IOMUX_PADS(misc_pads_spl);
+}
+
 #ifdef CONFIG_MXC_SPI
 iomux_v3_cfg_t const ecspi_pads[] = {
 	/* SPI3 */
diff --git a/board/liebherr/display5/common.h b/board/liebherr/display5/common.h
index a507ef9ce83e61cd033555ef54a1b54b50cd71fc..78c64b02e280a8d7e2c6707b7a67a99ee72e7dc4 100644
--- a/board/liebherr/display5/common.h
+++ b/board/liebherr/display5/common.h
@@ -37,5 +37,6 @@ void displ5_set_iomux_ecspi_spl(void);
 void displ5_set_iomux_ecspi(void);
 void displ5_set_iomux_usdhc_spl(void);
 void displ5_set_iomux_usdhc(void);
+void displ5_set_iomux_misc_spl(void);
 
 #endif /* __DISPL5_COMMON_H_ */
diff --git a/board/liebherr/display5/display5.c b/board/liebherr/display5/display5.c
index ebc643e7e3f1a5c8358f080b491e16c64e05abd9..d8383170d2fadab375d1eba2cc5064dd8a6f6e12 100644
--- a/board/liebherr/display5/display5.c
+++ b/board/liebherr/display5/display5.c
@@ -25,6 +25,7 @@
 #include <miiphy.h>
 #include <netdev.h>
 #include <i2c.h>
+#include <environment.h>
 
 #include <dm.h>
 #include <dm/platform_data/serial_mxc.h>
@@ -44,6 +45,7 @@ static bool sw_ids_valid;
 static u32 cpu_id;
 static u32 unit_id;
 
+#define EM_PAD IMX_GPIO_NR(3, 29)
 #define SW0	IMX_GPIO_NR(2, 4)
 #define SW1	IMX_GPIO_NR(2, 5)
 #define SW2	IMX_GPIO_NR(2, 6)
@@ -179,6 +181,9 @@ iomux_v3_cfg_t const misc_pads[] = {
 
 	/* XTALOSC */
 	MX6_PAD_GPIO_3__XTALOSC_REF_CLK_24M | MUX_PAD_CTRL(NO_PAD_CTRL),
+
+	/* Emergency recovery pin */
+	MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
 };
 
 #ifdef CONFIG_FSL_ESDHC
@@ -250,6 +255,25 @@ static void setup_iomux_enet(void)
 	gpio_direction_input(IMX_GPIO_NR(1, 28)); /*INT#_GBE*/
 }
 
+static int setup_mac_from_fuse(void)
+{
+	unsigned char enetaddr[6];
+	int ret;
+
+	ret = eth_env_get_enetaddr("ethaddr", enetaddr);
+	if (ret)	/* ethaddr is already set */
+		return 0;
+
+	imx_get_mac_from_fuse(0, enetaddr);
+
+	if (is_valid_ethaddr(enetaddr)) {
+		eth_env_set_enetaddr("ethaddr", enetaddr);
+		return 0;
+	}
+
+	return 0;
+}
+
 int board_eth_init(bd_t *bd)
 {
 	struct phy_device *phydev;
@@ -264,6 +288,8 @@ int board_eth_init(bd_t *bd)
 	if (ret)
 		return ret;
 
+	setup_mac_from_fuse();
+
 	bus = fec_get_miibus(IMX_FEC_BASE, -1);
 	if (!bus)
 		return -ENODEV;
@@ -369,7 +395,22 @@ static inline void setup_boot_modes(void) {}
 
 int misc_init_r(void)
 {
+	int ret;
+
 	setup_boot_modes();
+
+	ret = gpio_request(EM_PAD, "Emergency_PAD");
+	if (ret) {
+		printf("Can't request emergency PAD gpio\n");
+		return ret;
+	}
+
+	ret = gpio_direction_input(EM_PAD);
+	if (ret) {
+		printf("Can't set emergency PAD direction\n");
+		return ret;
+	}
+
 	return 0;
 }
 
diff --git a/board/liebherr/display5/spl.c b/board/liebherr/display5/spl.c
index 6508e0ffa7dfa3c0e1e75145769175dfc9cf6631..0c0172e201091714ab89db78cf2c712d61e19469 100644
--- a/board/liebherr/display5/spl.c
+++ b/board/liebherr/display5/spl.c
@@ -16,10 +16,12 @@
 #include <asm/arch/imx-regs.h>
 #include "asm/arch/iomux.h"
 #include <asm/mach-imx/iomux-v3.h>
+#include <asm/gpio.h>
 #include <environment.h>
 #include <fsl_esdhc.h>
 #include <netdev.h>
 #include <bootcount.h>
+#include <watchdog.h>
 #include "common.h"
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -115,6 +117,49 @@ static void ccgr_init(void)
 	writel(0x000003FF, &ccm->CCGR6);
 }
 
+#ifdef CONFIG_MX6_DDRCAL
+static void spl_dram_print_cal(struct mx6_ddr_sysinfo const *sysinfo)
+{
+	struct mx6_mmdc_calibration calibration = {0};
+
+	mmdc_read_calibration(sysinfo, &calibration);
+
+	debug(".p0_mpdgctrl0\t= 0x%08X\n", calibration.p0_mpdgctrl0);
+	debug(".p0_mpdgctrl1\t= 0x%08X\n", calibration.p0_mpdgctrl1);
+	debug(".p0_mprddlctl\t= 0x%08X\n", calibration.p0_mprddlctl);
+	debug(".p0_mpwrdlctl\t= 0x%08X\n", calibration.p0_mpwrdlctl);
+	debug(".p0_mpwldectrl0\t= 0x%08X\n", calibration.p0_mpwldectrl0);
+	debug(".p0_mpwldectrl1\t= 0x%08X\n", calibration.p0_mpwldectrl1);
+	debug(".p1_mpdgctrl0\t= 0x%08X\n", calibration.p1_mpdgctrl0);
+	debug(".p1_mpdgctrl1\t= 0x%08X\n", calibration.p1_mpdgctrl1);
+	debug(".p1_mprddlctl\t= 0x%08X\n", calibration.p1_mprddlctl);
+	debug(".p1_mpwrdlctl\t= 0x%08X\n", calibration.p1_mpwrdlctl);
+	debug(".p1_mpwldectrl0\t= 0x%08X\n", calibration.p1_mpwldectrl0);
+	debug(".p1_mpwldectrl1\t= 0x%08X\n", calibration.p1_mpwldectrl1);
+}
+
+static void spl_dram_perform_cal(struct mx6_ddr_sysinfo const *sysinfo)
+{
+	int ret;
+
+	/* Perform DDR DRAM calibration */
+	udelay(100);
+	ret = mmdc_do_write_level_calibration(sysinfo);
+	if (ret) {
+		printf("DDR: Write level calibration error [%d]\n", ret);
+		return;
+	}
+
+	ret = mmdc_do_dqs_calibration(sysinfo);
+	if (ret) {
+		printf("DDR: DQS calibration error [%d]\n", ret);
+		return;
+	}
+
+	spl_dram_print_cal(sysinfo);
+}
+#endif /* CONFIG_MX6_DDRCAL */
+
 static void spl_dram_init(void)
 {
 	struct mx6_ddr_sysinfo sysinfo = {
@@ -141,6 +186,10 @@ static void spl_dram_init(void)
 
 	mx6dq_dram_iocfg(64, &mx6_ddr_ioregs, &mx6_grp_ioregs);
 	mx6_dram_cfg(&sysinfo, &mx6_4x256mx16_mmdc_calib, &mt41k128m16jt_125);
+
+#ifdef CONFIG_MX6_DDRCAL
+	spl_dram_perform_cal(&sysinfo);
+#endif
 }
 
 #ifdef CONFIG_SPL_SPI_SUPPORT
@@ -194,10 +243,28 @@ void board_init_f(ulong dummy)
 	/* Clear the BSS. */
 	memset(__bss_start, 0, __bss_end - __bss_start);
 
+	displ5_set_iomux_misc_spl();
+
+	/* Initialize and reset WDT in SPL */
+	hw_watchdog_init();
+	WATCHDOG_RESET();
+
 	/* load/boot image from boot device */
 	board_init_r(NULL, 0);
 }
 
+#define EM_PAD IMX_GPIO_NR(3, 29)
+int board_check_emergency_pad(void)
+{
+	int ret;
+
+	ret = gpio_direction_input(EM_PAD);
+	if (ret)
+		return ret;
+
+	return !gpio_get_value(EM_PAD);
+}
+
 void board_boot_order(u32 *spl_boot_list)
 {
 	/* Default boot sequence SPI -> MMC */
@@ -206,12 +273,19 @@ void board_boot_order(u32 *spl_boot_list)
 	spl_boot_list[2] = BOOT_DEVICE_UART;
 	spl_boot_list[3] = BOOT_DEVICE_NONE;
 
+	/*
+	 * In case of emergency PAD pressed, we always boot
+	 * to proper u-boot and perform recovery tasks there.
+	 */
+	if (board_check_emergency_pad())
+		return;
+
 #ifdef CONFIG_SPL_ENV_SUPPORT
 	/* 'fastboot' */
 	const char *s;
 
-	env_init();
-	env_load();
+	if (env_init() || env_load())
+		return;
 
 	s = env_get("BOOT_FROM");
 	if (s && !bootcount_error() && strcmp(s, "ACTIVE") == 0) {
diff --git a/board/solidrun/mx6cuboxi/mx6cuboxi.c b/board/solidrun/mx6cuboxi/mx6cuboxi.c
index 1fb3c69edeb529c12c61355095b7a8074ac07ea1..38d89f0130bb9f4d6283821ea620f72b76803838 100644
--- a/board/solidrun/mx6cuboxi/mx6cuboxi.c
+++ b/board/solidrun/mx6cuboxi/mx6cuboxi.c
@@ -57,9 +57,58 @@ DECLARE_GLOBAL_DATA_PTR;
 #define ETH_PHY_RESET	IMX_GPIO_NR(4, 15)
 #define USB_H1_VBUS	IMX_GPIO_NR(1, 0)
 
+enum board_type {
+	CUBOXI          = 0x00,
+	HUMMINGBOARD    = 0x01,
+	HUMMINGBOARD2   = 0x02,
+	UNKNOWN         = 0x03,
+};
+
+#define MEM_STRIDE 0x4000000
+static u32 get_ram_size_stride_test(u32 *base, u32 maxsize)
+{
+        volatile u32 *addr;
+        u32          save[64];
+        u32          cnt;
+        u32          size;
+        int          i = 0;
+
+        /* First save the data */
+        for (cnt = 0; cnt < maxsize; cnt += MEM_STRIDE) {
+                addr = (volatile u32 *)((u32)base + cnt);       /* pointer arith! */
+                sync ();
+                save[i++] = *addr;
+                sync ();
+        }
+
+        /* First write a signature */
+        * (volatile u32 *)base = 0x12345678;
+        for (size = MEM_STRIDE; size < maxsize; size += MEM_STRIDE) {
+                * (volatile u32 *)((u32)base + size) = size;
+                sync ();
+                if (* (volatile u32 *)((u32)base) == size) {	/* We reached the overlapping address */
+                        break;
+                }
+        }
+
+        /* Restore the data */
+        for (cnt = (maxsize - MEM_STRIDE); i > 0; cnt -= MEM_STRIDE) {
+                addr = (volatile u32 *)((u32)base + cnt);       /* pointer arith! */
+                sync ();
+                *addr = save[i--];
+                sync ();
+        }
+
+        return (size);
+}
+
 int dram_init(void)
 {
-	gd->ram_size = imx_ddr_size();
+	u32 max_size = imx_ddr_size();
+
+	gd->ram_size = get_ram_size_stride_test((u32 *) CONFIG_SYS_SDRAM_BASE,
+						(u32)max_size);
+
 	return 0;
 }
 
@@ -77,10 +126,17 @@ static iomux_v3_cfg_t const usdhc2_pads[] = {
 	IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
 };
 
-static iomux_v3_cfg_t const hb_cbi_sense[] = {
+static iomux_v3_cfg_t const board_detect[] = {
 	/* These pins are for sensing if it is a CuBox-i or a HummingBoard */
 	IOMUX_PADS(PAD_KEY_ROW1__GPIO4_IO09  | MUX_PAD_CTRL(UART_PAD_CTRL)),
 	IOMUX_PADS(PAD_EIM_DA4__GPIO3_IO04   | MUX_PAD_CTRL(UART_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08  | MUX_PAD_CTRL(UART_PAD_CTRL)),
+};
+
+static iomux_v3_cfg_t const som_rev_detect[] = {
+	/* These pins are for sensing if it is a CuBox-i or a HummingBoard */
+	IOMUX_PADS(PAD_CSI0_DAT14__GPIO6_IO00  | MUX_PAD_CTRL(UART_PAD_CTRL)),
+	IOMUX_PADS(PAD_CSI0_DAT18__GPIO6_IO04  | MUX_PAD_CTRL(UART_PAD_CTRL)),
 };
 
 static iomux_v3_cfg_t const usb_pads[] = {
@@ -333,88 +389,110 @@ int board_init(void)
 	return ret;
 }
 
-static bool is_hummingboard(void)
+static enum board_type board_type(void)
 {
-	int val1, val2;
+	int val1, val2, val3;
 
-	SETUP_IOMUX_PADS(hb_cbi_sense);
-
-	gpio_direction_input(IMX_GPIO_NR(4, 9));
-	gpio_direction_input(IMX_GPIO_NR(3, 4));
-
-	val1 = gpio_get_value(IMX_GPIO_NR(4, 9));
-	val2 = gpio_get_value(IMX_GPIO_NR(3, 4));
+	SETUP_IOMUX_PADS(board_detect);
 
 	/*
 	 * Machine selection -
-	 * Machine        val1, val2
-	 * -------------------------
-	 * HB2            x     x
-	 * HB rev 3.x     x     0
-	 * CBi            0     1
-	 * HB             1     1
+	 * Machine      val1, val2, val3
+	 * ----------------------------
+	 * HB2            x     x    0
+	 * HB rev 3.x     x     0    x
+	 * CBi            0     1    x
+	 * HB             1     1    x
 	 */
 
-	if (val2 == 0)
-		return true;
-	else if (val1 == 0)
-		return false;
-	else
-		return true;
-}
+	gpio_direction_input(IMX_GPIO_NR(2, 8));
+	val3 = gpio_get_value(IMX_GPIO_NR(2, 8));
 
-static bool is_hummingboard2(void)
-{
-	int val1;
+	if (val3 == 0)
+		return HUMMINGBOARD2;
 
-	SETUP_IOMUX_PADS(hb_cbi_sense);
+	gpio_direction_input(IMX_GPIO_NR(3, 4));
+	val2 = gpio_get_value(IMX_GPIO_NR(3, 4));
 
-	gpio_direction_input(IMX_GPIO_NR(2, 8));
+	if (val2 == 0)
+		return HUMMINGBOARD;
 
-        val1 = gpio_get_value(IMX_GPIO_NR(2, 8));
+	gpio_direction_input(IMX_GPIO_NR(4, 9));
+	val1 = gpio_get_value(IMX_GPIO_NR(4, 9));
 
-	/*
-	 * Machine selection -
-	 * Machine        val1
-	 * -------------------
-	 * HB2            0
-	 * HB rev 3.x     x
-	 * CBi            x
-	 * HB             x
-	 */
+	if (val1 == 0) {
+		return CUBOXI;
+	} else {
+		return HUMMINGBOARD;
+	}
+}
+
+static bool is_rev_15_som(void)
+{
+	int val1, val2;
+	SETUP_IOMUX_PADS(som_rev_detect);
+
+	val1 = gpio_get_value(IMX_GPIO_NR(6, 0));
+	val2 = gpio_get_value(IMX_GPIO_NR(6, 4));
 
-	if (val1 == 0)
+	if (val1 == 1 && val2 == 0)
 		return true;
-	else
-		return false;
+
+	return false;
 }
 
 int checkboard(void)
 {
-	if (is_hummingboard2())
-		puts("Board: MX6 Hummingboard2\n");
-	else if (is_hummingboard())
-		puts("Board: MX6 Hummingboard\n");
+	switch (board_type()) {
+	case CUBOXI:
+		puts("Board: MX6 Cubox-i");
+		break;
+	case HUMMINGBOARD:
+		puts("Board: MX6 HummingBoard");
+		break;
+	case HUMMINGBOARD2:
+		puts("Board: MX6 HummingBoard2");
+		break;
+	case UNKNOWN:
+	default:
+		puts("Board: Unknown\n");
+		goto out;
+	}
+
+	if (is_rev_15_som())
+		puts(" (som rev 1.5)\n");
 	else
-		puts("Board: MX6 Cubox-i\n");
+		puts("\n");
 
+out:
 	return 0;
 }
 
 int board_late_init(void)
 {
 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-	if (is_hummingboard2())
-		env_set("board_name", "HUMMINGBOARD2");
-	else if (is_hummingboard())
+	switch (board_type()) {
+	case CUBOXI:
+		env_set("board_name", "CUBOXI");
+		break;
+	case HUMMINGBOARD:
 		env_set("board_name", "HUMMINGBOARD");
-	else
+		break;
+	case HUMMINGBOARD2:
+		env_set("board_name", "HUMMINGBOARD2");
+		break;
+	case UNKNOWN:
+	default:
 		env_set("board_name", "CUBOXI");
+	}
 
 	if (is_mx6dq())
 		env_set("board_rev", "MX6Q");
 	else
 		env_set("board_rev", "MX6DL");
+
+	if (is_rev_15_som())
+		env_set("som_rev", "V15");
 #endif
 
 	return 0;
@@ -590,7 +668,7 @@ static struct mx6_ddr3_cfg mem_ddr_4g = {
 	.density = 4,
 	.width = 16,
 	.banks = 8,
-	.rowaddr = 15,
+	.rowaddr = 16,
 	.coladdr = 10,
 	.pagesz = 2,
 	.trcd = 1375,
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 1f1479718e9dc77527fd00b0b6db13ff7ffa0e2c..0bbf8d5b0231d3dbae8227382b5a5cecc384d225 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -152,7 +152,8 @@ config SPL_DISPLAY_PRINT
 
 config SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
 	bool "MMC raw mode: by sector"
-	default y if ARCH_SUNXI || ARCH_DAVINCI || ARCH_UNIPHIER ||ARCH_MX6 || \
+	default y if ARCH_SUNXI || ARCH_DAVINCI || ARCH_UNIPHIER || \
+		     ARCH_MX6 || ARCH_MX7 || \
 		     ARCH_ROCKCHIP || ARCH_MVEBU ||  ARCH_SOCFPGA || \
 		     ARCH_AT91 || ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || \
 		     OMAP44XX || OMAP54XX || AM33XX || AM43XX
@@ -165,7 +166,7 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
 	depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
 	default 0x50 if ARCH_SUNXI
 	default 0x75 if ARCH_DAVINCI
-	default 0x8a if ARCH_MX6
+	default 0x8a if ARCH_MX6 || ARCH_MX7
 	default 0x100 if ARCH_UNIPHIER
 	default 0x140 if ARCH_MVEBU
 	default 0x200 if ARCH_SOCFPGA || ARCH_AT91
diff --git a/configs/cl-som-imx7_defconfig b/configs/cl-som-imx7_defconfig
index 6d403eed7ade1b91e5ad9330e80ea6c733e84c65..38be7dbe7e5ffb59ae08bf9c136dc4ff5f120e3e 100644
--- a/configs/cl-som-imx7_defconfig
+++ b/configs/cl-som-imx7_defconfig
@@ -17,7 +17,6 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
 CONFIG_SPI_BOOT=y
 CONFIG_BOOTDELAY=3
 CONFIG_SPL_BOARD_INIT=y
-CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x80
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_SPI_LOAD=y
diff --git a/configs/display5_defconfig b/configs/display5_defconfig
index 4db8a2bfb95ab4e387eed8123abe5e8303e9abfd..f51fbd4aa525bcc524bfb8a86fbc6d891a70ad4d 100644
--- a/configs/display5_defconfig
+++ b/configs/display5_defconfig
@@ -4,12 +4,14 @@ CONFIG_SYS_TEXT_BASE=0x17800000
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_MX6_DDRCAL=y
 CONFIG_TARGET_DISPLAY5=y
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
 CONFIG_DEFAULT_DEVICE_TREE="imx6q-display5"
 CONFIG_FIT=y
 CONFIG_SPL_LOAD_FIT=y
@@ -32,6 +34,7 @@ CONFIG_CMD_ASKENV=y
 CONFIG_CRC32_VERIFY=y
 CONFIG_CMD_EEPROM=y
 CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_PART=y
@@ -48,8 +51,7 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nor0=02008000.spi.1"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),8m(lin-recovery),4m(swu-kernel),8m(swu-initramfs),-(reserved)"
-CONFIG_EFI_PARTITION=y
+CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),4m(swu-kernel),16m(swu-initramfs),1m(factory),-(reserved)"
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
diff --git a/configs/display5_factory_defconfig b/configs/display5_factory_defconfig
index 10b025ce04e78f63801310a5a5d4d85484897652..14df849fb7d87bc240b7345fc3c0739e9aa2eb84 100644
--- a/configs/display5_factory_defconfig
+++ b/configs/display5_factory_defconfig
@@ -9,6 +9,7 @@ CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
 CONFIG_FIT=y
 CONFIG_OF_BOARD_SETUP=y
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,MX6Q"
@@ -53,7 +54,7 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nor0=02008000.spi.1"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),8m(lin-recovery),4m(swu-kernel),8m(swu-initramfs),-(reserved)"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),4m(swu-kernel),16m(swu-initramfs),1m(factory),-(reserved)"
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_PARTITION_TYPE_GUID=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
diff --git a/configs/imx6ul_geam_mmc_defconfig b/configs/imx6ul_geam_mmc_defconfig
index 4ae09fff1161a4c5f7cd9faf08e15de37665e118..6cd1bfd15e94567deb3591ddbfd8463cb89b9303 100644
--- a/configs/imx6ul_geam_mmc_defconfig
+++ b/configs/imx6ul_geam_mmc_defconfig
@@ -10,7 +10,7 @@ CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL=y
 CONFIG_SPL_LIBDISK_SUPPORT=y
 # CONFIG_CMD_BMODE is not set
-CONFIG_DEFAULT_DEVICE_TREE="imx6ul-geam-kit"
+CONFIG_DEFAULT_DEVICE_TREE="imx6ul-geam"
 CONFIG_FIT=y
 CONFIG_FIT_SIGNATURE=y
 CONFIG_FIT_VERBOSE=y
diff --git a/configs/imx6ul_geam_nand_defconfig b/configs/imx6ul_geam_nand_defconfig
index e8f9cb44785feb190bcbe97a8260b5ac06742717..d3364a790fffa7c10232a2163627cec05954f076 100644
--- a/configs/imx6ul_geam_nand_defconfig
+++ b/configs/imx6ul_geam_nand_defconfig
@@ -8,7 +8,7 @@ CONFIG_TARGET_MX6UL_ENGICAM=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL=y
 # CONFIG_CMD_BMODE is not set
-CONFIG_DEFAULT_DEVICE_TREE="imx6ul-geam-kit"
+CONFIG_DEFAULT_DEVICE_TREE="imx6ul-geam"
 CONFIG_FIT=y
 CONFIG_FIT_SIGNATURE=y
 CONFIG_FIT_VERBOSE=y
diff --git a/configs/kp_imx53_defconfig b/configs/kp_imx53_defconfig
index 451b48d3c406cc1765f00bbb418f25bd502e390b..d1b533141ab792b617f5b6a9befdd50fa6f1ffa5 100644
--- a/configs/kp_imx53_defconfig
+++ b/configs/kp_imx53_defconfig
@@ -6,10 +6,14 @@ CONFIG_TARGET_KP_IMX53=y
 CONFIG_DEFAULT_DEVICE_TREE="imx53-kp"
 CONFIG_FIT=y
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx53loco/imximage.cfg"
+CONFIG_SILENT_CONSOLE=y
+# CONFIG_SILENT_CONSOLE_UPDATE_ON_SET is not set
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
 CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y
 CONFIG_SUPPORT_RAW_INITRD=y
 CONFIG_HUSH_PARSER=y
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_AUTOBOOT_STOP_STR="."
 CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
@@ -18,6 +22,7 @@ CONFIG_CMD_USB=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_CMD_PMIC=y
 CONFIG_CMD_EXT2=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
@@ -26,6 +31,7 @@ CONFIG_ENV_IS_IN_MMC=y
 CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 CONFIG_I2C_DEFAULT_BUS_NUMBER=0x1
 CONFIG_PHYLIB=y
+CONFIG_PHY_ADDR=1
 CONFIG_PHY_SMSC=y
 CONFIG_FEC_MXC=y
 CONFIG_PINCTRL=y
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b7e4ffb09d691c93934e7b5a3a01cfc9116e712e..29af22ecc70c76fcce2863063098e7e6df051ea7 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -109,7 +109,7 @@ config MSM_GPIO
 	  - MSM8916
 
 config MXC_GPIO
-	bool "Freescale/NXP MXC UART driver"
+	bool "Freescale/NXP MXC GPIO driver"
 	help
 	  Support GPIO controllers on various i.MX platforms
 
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 94fbf89e4b8cae01ae3e00c975f71bd3dfba614e..bdc272142e5f714618b9c24890b0f13bbb3ca849 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -143,6 +143,7 @@ config NAND_MXC
 config NAND_MXS
 	bool "MXS NAND support"
 	depends on MX23 || MX28 || MX6 || MX7
+	select SYS_NAND_SELF_INIT
 	imply CMD_NAND
 	select APBH_DMA
 	select APBH_DMA_BURST if ARCH_MX6 || ARCH_MX7
@@ -151,6 +152,21 @@ config NAND_MXS
 	  This enables NAND driver for the NAND flash controller on the
 	  MXS processors.
 
+if NAND_MXS
+
+config NAND_MXS_DT
+	bool "Support MXS NAND controller as a DT device"
+	depends on OF_CONTROL && MTD
+	help
+	  Enable the driver for MXS NAND flash on platforms using
+	  device tree.
+
+config NAND_MXS_USE_MINIMUM_ECC
+	bool "Use minimum ECC strength supported by the controller"
+	default false
+
+endif
+
 config NAND_ZYNQ
 	bool "Support for Zynq Nand controller"
 	select SYS_NAND_SELF_INIT
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index e20ef0777380c1a37002bd08fd091a3a9fb4ef6f..c61e3f38391aeb9027fd1599805d91e88c7eb2a9 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
 obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o
 obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o
 obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o
+obj-$(CONFIG_SPL_NAND_IDENT) += nand_ids.o nand_timings.o
 obj-$(CONFIG_SPL_NAND_INIT) += nand.o
 ifeq ($(CONFIG_SPL_ENV_SUPPORT),y)
 obj-$(CONFIG_ENV_IS_IN_NAND) += nand_util.o
@@ -55,6 +56,7 @@ obj-$(CONFIG_NAND_LPC32XX_SLC) += lpc32xx_nand_slc.o
 obj-$(CONFIG_NAND_VF610_NFC) += vf610_nfc.o
 obj-$(CONFIG_NAND_MXC) += mxc_nand.o
 obj-$(CONFIG_NAND_MXS) += mxs_nand.o
+obj-$(CONFIG_NAND_MXS_DT) += mxs_nand_dt.o
 obj-$(CONFIG_NAND_PXA3XX) += pxa3xx_nand.o
 obj-$(CONFIG_NAND_SPEAR) += spr_nand.o
 obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o
diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c
index b9ffa7cbae0f2c72b8732315a2e10fd387c2eed1..e3341812a203a3984fdbdbebea6207eab20c0709 100644
--- a/drivers/mtd/nand/mxs_nand.c
+++ b/drivers/mtd/nand/mxs_nand.c
@@ -13,8 +13,9 @@
  */
 
 #include <common.h>
-#include <linux/mtd/mtd.h>
+#include <dm.h>
 #include <linux/mtd/rawnand.h>
+#include <linux/sizes.h>
 #include <linux/types.h>
 #include <malloc.h>
 #include <linux/errno.h>
@@ -24,11 +25,10 @@
 #include <asm/mach-imx/regs-bch.h>
 #include <asm/mach-imx/regs-gpmi.h>
 #include <asm/arch/sys_proto.h>
-#include <asm/mach-imx/dma.h>
+#include "mxs_nand.h"
 
 #define	MXS_NAND_DMA_DESCRIPTOR_COUNT		4
 
-#define	MXS_NAND_CHUNK_DATA_CHUNK_SIZE		512
 #if (defined(CONFIG_MX6) || defined(CONFIG_MX7))
 #define	MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT	2
 #else
@@ -45,35 +45,7 @@
 
 #define	MXS_NAND_BCH_TIMEOUT			10000
 
-struct mxs_nand_info {
-	int		cur_chip;
-
-	uint32_t	cmd_queue_len;
-	uint32_t	data_buf_size;
-
-	uint8_t		*cmd_buf;
-	uint8_t		*data_buf;
-	uint8_t		*oob_buf;
-
-	uint8_t		marking_block_bad;
-	uint8_t		raw_oob_mode;
-
-	/* Functions with altered behaviour */
-	int		(*hooked_read_oob)(struct mtd_info *mtd,
-				loff_t from, struct mtd_oob_ops *ops);
-	int		(*hooked_write_oob)(struct mtd_info *mtd,
-				loff_t to, struct mtd_oob_ops *ops);
-	int		(*hooked_block_markbad)(struct mtd_info *mtd,
-				loff_t ofs);
-
-	/* DMA descriptors */
-	struct mxs_dma_desc	**desc;
-	uint32_t		desc_index;
-};
-
 struct nand_ecclayout fake_ecc_layout;
-static int chunk_data_size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
-static int galois_field = 13;
 
 /*
  * Cache management functions
@@ -134,61 +106,21 @@ static void mxs_nand_return_dma_descs(struct mxs_nand_info *info)
 	info->desc_index = 0;
 }
 
-static uint32_t mxs_nand_ecc_chunk_cnt(uint32_t page_data_size)
-{
-	return page_data_size / chunk_data_size;
-}
-
-static uint32_t mxs_nand_ecc_size_in_bits(uint32_t ecc_strength)
-{
-	return ecc_strength * galois_field;
-}
-
 static uint32_t mxs_nand_aux_status_offset(void)
 {
 	return (MXS_NAND_METADATA_SIZE + 0x3) & ~0x3;
 }
 
-static inline uint32_t mxs_nand_get_ecc_strength(uint32_t page_data_size,
-						uint32_t page_oob_size)
-{
-	int ecc_strength;
-	int max_ecc_strength_supported;
-
-	/* Refer to Chapter 17 for i.MX6DQ, Chapter 18 for i.MX6SX */
-	if (is_mx6sx() || is_mx7())
-		max_ecc_strength_supported = 62;
-	else
-		max_ecc_strength_supported = 40;
-
-	/*
-	 * Determine the ECC layout with the formula:
-	 *	ECC bits per chunk = (total page spare data bits) /
-	 *		(bits per ECC level) / (chunks per page)
-	 * where:
-	 *	total page spare data bits =
-	 *		(page oob size - meta data size) * (bits per byte)
-	 */
-	ecc_strength = ((page_oob_size - MXS_NAND_METADATA_SIZE) * 8)
-			/ (galois_field *
-			   mxs_nand_ecc_chunk_cnt(page_data_size));
-
-	return min(round_down(ecc_strength, 2), max_ecc_strength_supported);
-}
-
-static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size,
-						uint32_t ecc_strength)
+static inline int mxs_nand_calc_mark_offset(struct bch_geometry *geo,
+					    uint32_t page_data_size)
 {
-	uint32_t chunk_data_size_in_bits;
-	uint32_t chunk_ecc_size_in_bits;
+	uint32_t chunk_data_size_in_bits = geo->ecc_chunk_size * 8;
+	uint32_t chunk_ecc_size_in_bits = geo->ecc_strength * geo->gf_len;
 	uint32_t chunk_total_size_in_bits;
 	uint32_t block_mark_chunk_number;
 	uint32_t block_mark_chunk_bit_offset;
 	uint32_t block_mark_bit_offset;
 
-	chunk_data_size_in_bits = chunk_data_size * 8;
-	chunk_ecc_size_in_bits  = mxs_nand_ecc_size_in_bits(ecc_strength);
-
 	chunk_total_size_in_bits =
 			chunk_data_size_in_bits + chunk_ecc_size_in_bits;
 
@@ -213,7 +145,7 @@ static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size,
 			(block_mark_chunk_number * chunk_total_size_in_bits);
 
 	if (block_mark_chunk_bit_offset > chunk_data_size_in_bits)
-		return 1;
+		return -EINVAL;
 
 	/*
 	 * Now that we know the chunk number in which the block mark appears,
@@ -222,36 +154,100 @@ static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size,
 	block_mark_bit_offset -=
 		block_mark_chunk_number * chunk_ecc_size_in_bits;
 
-	return block_mark_bit_offset;
+	geo->block_mark_byte_offset = block_mark_bit_offset >> 3;
+	geo->block_mark_bit_offset = block_mark_bit_offset & 0x7;
+
+	return 0;
 }
 
-static uint32_t mxs_nand_mark_byte_offset(struct mtd_info *mtd)
+static inline int mxs_nand_calc_ecc_layout_by_info(struct bch_geometry *geo,
+						   struct mtd_info *mtd,
+						   unsigned int ecc_strength,
+						   unsigned int ecc_step)
 {
-	uint32_t ecc_strength;
-	ecc_strength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize);
-	return mxs_nand_get_mark_offset(mtd->writesize, ecc_strength) >> 3;
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	struct mxs_nand_info *nand_info = nand_get_controller_data(chip);
+
+	switch (ecc_step) {
+	case SZ_512:
+		geo->gf_len = 13;
+		break;
+	case SZ_1K:
+		geo->gf_len = 14;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	geo->ecc_chunk_size = ecc_step;
+	geo->ecc_strength = round_up(ecc_strength, 2);
+
+	/* Keep the C >= O */
+	if (geo->ecc_chunk_size < mtd->oobsize)
+		return -EINVAL;
+
+	if (geo->ecc_strength > nand_info->max_ecc_strength_supported)
+		return -EINVAL;
+
+	geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size;
+
+	return 0;
 }
 
-static uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd)
+static inline int mxs_nand_calc_ecc_layout(struct bch_geometry *geo,
+					   struct mtd_info *mtd)
 {
-	uint32_t ecc_strength;
-	ecc_strength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize);
-	return mxs_nand_get_mark_offset(mtd->writesize, ecc_strength) & 0x7;
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	struct mxs_nand_info *nand_info = nand_get_controller_data(chip);
+
+	/* The default for the length of Galois Field. */
+	geo->gf_len = 13;
+
+	/* The default for chunk size. */
+	geo->ecc_chunk_size = 512;
+
+	if (geo->ecc_chunk_size < mtd->oobsize) {
+		geo->gf_len = 14;
+		geo->ecc_chunk_size *= 2;
+	}
+
+	if (mtd->oobsize > geo->ecc_chunk_size) {
+		printf("Not support the NAND chips whose oob size is larger then %d bytes!\n",
+		       geo->ecc_chunk_size);
+		return -EINVAL;
+	}
+
+	geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size;
+
+	/*
+	 * Determine the ECC layout with the formula:
+	 *	ECC bits per chunk = (total page spare data bits) /
+	 *		(bits per ECC level) / (chunks per page)
+	 * where:
+	 *	total page spare data bits =
+	 *		(page oob size - meta data size) * (bits per byte)
+	 */
+	geo->ecc_strength = ((mtd->oobsize - MXS_NAND_METADATA_SIZE) * 8)
+			/ (geo->gf_len * geo->ecc_chunk_count);
+
+	geo->ecc_strength = min(round_down(geo->ecc_strength, 2),
+				nand_info->max_ecc_strength_supported);
+
+	return 0;
 }
 
 /*
  * Wait for BCH complete IRQ and clear the IRQ
  */
-static int mxs_nand_wait_for_bch_complete(void)
+static int mxs_nand_wait_for_bch_complete(struct mxs_nand_info *nand_info)
 {
-	struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE;
 	int timeout = MXS_NAND_BCH_TIMEOUT;
 	int ret;
 
-	ret = mxs_wait_mask_set(&bch_regs->hw_bch_ctrl_reg,
+	ret = mxs_wait_mask_set(&nand_info->bch_regs->hw_bch_ctrl_reg,
 		BCH_CTRL_COMPLETE_IRQ, timeout);
 
-	writel(BCH_CTRL_COMPLETE_IRQ, &bch_regs->hw_bch_ctrl_clr);
+	writel(BCH_CTRL_COMPLETE_IRQ, &nand_info->bch_regs->hw_bch_ctrl_clr);
 
 	return ret;
 }
@@ -349,11 +345,9 @@ static int mxs_nand_device_ready(struct mtd_info *mtd)
 {
 	struct nand_chip *chip = mtd_to_nand(mtd);
 	struct mxs_nand_info *nand_info = nand_get_controller_data(chip);
-	struct mxs_gpmi_regs *gpmi_regs =
-		(struct mxs_gpmi_regs *)MXS_GPMI_BASE;
 	uint32_t tmp;
 
-	tmp = readl(&gpmi_regs->hw_gpmi_stat);
+	tmp = readl(&nand_info->gpmi_regs->hw_gpmi_stat);
 	tmp >>= (GPMI_STAT_READY_BUSY_OFFSET + nand_info->cur_chip);
 
 	return tmp & 1;
@@ -377,18 +371,15 @@ static void mxs_nand_select_chip(struct mtd_info *mtd, int chip)
  * swapping the block mark, or swapping it *back* -- but it doesn't matter
  * because the the operation is the same.
  */
-static void mxs_nand_swap_block_mark(struct mtd_info *mtd,
-					uint8_t *data_buf, uint8_t *oob_buf)
+static void mxs_nand_swap_block_mark(struct bch_geometry *geo,
+				     uint8_t *data_buf, uint8_t *oob_buf)
 {
-	uint32_t bit_offset;
-	uint32_t buf_offset;
+	uint32_t bit_offset = geo->block_mark_bit_offset;
+	uint32_t buf_offset = geo->block_mark_byte_offset;
 
 	uint32_t src;
 	uint32_t dst;
 
-	bit_offset = mxs_nand_mark_bit_offset(mtd);
-	buf_offset = mxs_nand_mark_byte_offset(mtd);
-
 	/*
 	 * Get the byte from the data area that overlays the block mark. Since
 	 * the ECC engine applies its own view to the bits in the page, the
@@ -564,6 +555,7 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
 					int page)
 {
 	struct mxs_nand_info *nand_info = nand_get_controller_data(nand);
+	struct bch_geometry *geo = &nand_info->bch_geometry;
 	struct mxs_dma_desc *d;
 	uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip;
 	uint32_t corrected = 0, failed = 0;
@@ -652,7 +644,7 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
 		goto rtn;
 	}
 
-	ret = mxs_nand_wait_for_bch_complete();
+	ret = mxs_nand_wait_for_bch_complete(nand_info);
 	if (ret) {
 		printf("MXS NAND: BCH read timeout\n");
 		goto rtn;
@@ -662,11 +654,11 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
 	mxs_nand_inval_data_buf(nand_info);
 
 	/* Read DMA completed, now do the mark swapping. */
-	mxs_nand_swap_block_mark(mtd, nand_info->data_buf, nand_info->oob_buf);
+	mxs_nand_swap_block_mark(geo, nand_info->data_buf, nand_info->oob_buf);
 
 	/* Loop over status bytes, accumulating ECC status. */
 	status = nand_info->oob_buf + mxs_nand_aux_status_offset();
-	for (i = 0; i < mxs_nand_ecc_chunk_cnt(mtd->writesize); i++) {
+	for (i = 0; i < geo->ecc_chunk_count; i++) {
 		if (status[i] == 0x00)
 			continue;
 
@@ -714,6 +706,7 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd,
 				int oob_required, int page)
 {
 	struct mxs_nand_info *nand_info = nand_get_controller_data(nand);
+	struct bch_geometry *geo = &nand_info->bch_geometry;
 	struct mxs_dma_desc *d;
 	uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip;
 	int ret;
@@ -722,7 +715,7 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd,
 	memcpy(nand_info->oob_buf, nand->oob_poi, mtd->oobsize);
 
 	/* Handle block mark swapping. */
-	mxs_nand_swap_block_mark(mtd, nand_info->data_buf, nand_info->oob_buf);
+	mxs_nand_swap_block_mark(geo, nand_info->data_buf, nand_info->oob_buf);
 
 	/* Compile the DMA descriptor - write data. */
 	d = mxs_nand_get_dma_desc(nand_info);
@@ -759,7 +752,7 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd,
 		goto rtn;
 	}
 
-	ret = mxs_nand_wait_for_bch_complete();
+	ret = mxs_nand_wait_for_bch_complete(nand_info);
 	if (ret) {
 		printf("MXS NAND: BCH write timeout\n");
 		goto rtn;
@@ -970,57 +963,69 @@ static int mxs_nand_block_bad(struct mtd_info *mtd, loff_t ofs)
 	return 0;
 }
 
+static int mxs_nand_set_geometry(struct mtd_info *mtd, struct bch_geometry *geo)
+{
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	struct nand_chip *nand = mtd_to_nand(mtd);
+	struct mxs_nand_info *nand_info = nand_get_controller_data(nand);
+
+	if (chip->ecc.strength > 0 && chip->ecc.size > 0)
+		return mxs_nand_calc_ecc_layout_by_info(geo, mtd,
+				chip->ecc.strength, chip->ecc.size);
+
+	if (nand_info->use_minimum_ecc ||
+		mxs_nand_calc_ecc_layout(geo, mtd)) {
+		if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0))
+			return -EINVAL;
+
+		return mxs_nand_calc_ecc_layout_by_info(geo, mtd,
+				chip->ecc_strength_ds, chip->ecc_step_ds);
+	}
+
+	return 0;
+}
+
 /*
- * Nominally, the purpose of this function is to look for or create the bad
- * block table. In fact, since the we call this function at the very end of
- * the initialization process started by nand_scan(), and we doesn't have a
- * more formal mechanism, we "hook" this function to continue init process.
- *
  * At this point, the physical NAND Flash chips have been identified and
  * counted, so we know the physical geometry. This enables us to make some
  * important configuration decisions.
  *
  * The return value of this function propagates directly back to this driver's
- * call to nand_scan(). Anything other than zero will cause this driver to
+ * board_nand_init(). Anything other than zero will cause this driver to
  * tear everything down and declare failure.
  */
-static int mxs_nand_scan_bbt(struct mtd_info *mtd)
+int mxs_nand_setup_ecc(struct mtd_info *mtd)
 {
 	struct nand_chip *nand = mtd_to_nand(mtd);
 	struct mxs_nand_info *nand_info = nand_get_controller_data(nand);
-	struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE;
+	struct bch_geometry *geo = &nand_info->bch_geometry;
+	struct mxs_bch_regs *bch_regs = nand_info->bch_regs;
 	uint32_t tmp;
+	int ret;
 
-	if (mtd->oobsize > MXS_NAND_CHUNK_DATA_CHUNK_SIZE) {
-		galois_field = 14;
-		chunk_data_size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE * 2;
-	}
+	ret = mxs_nand_set_geometry(mtd, geo);
+	if (ret)
+		return ret;
 
-	if (mtd->oobsize > chunk_data_size) {
-		printf("Not support the NAND chips whose oob size is larger then %d bytes!\n", chunk_data_size);
-		return -EINVAL;
-	}
+	mxs_nand_calc_mark_offset(geo, mtd->writesize);
 
 	/* Configure BCH and set NFC geometry */
 	mxs_reset_block(&bch_regs->hw_bch_ctrl_reg);
 
 	/* Configure layout 0 */
-	tmp = (mxs_nand_ecc_chunk_cnt(mtd->writesize) - 1)
-		<< BCH_FLASHLAYOUT0_NBLOCKS_OFFSET;
+	tmp = (geo->ecc_chunk_count - 1) << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET;
 	tmp |= MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET;
-	tmp |= (mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1)
-		<< BCH_FLASHLAYOUT0_ECC0_OFFSET;
-	tmp |= chunk_data_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT;
-	tmp |= (14 == galois_field ? 1 : 0) <<
+	tmp |= (geo->ecc_strength >> 1) << BCH_FLASHLAYOUT0_ECC0_OFFSET;
+	tmp |= geo->ecc_chunk_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT;
+	tmp |= (geo->gf_len == 14 ? 1 : 0) <<
 		BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET;
 	writel(tmp, &bch_regs->hw_bch_flash0layout0);
 
 	tmp = (mtd->writesize + mtd->oobsize)
 		<< BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET;
-	tmp |= (mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1)
-		<< BCH_FLASHLAYOUT1_ECCN_OFFSET;
-	tmp |= chunk_data_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT;
-	tmp |= (14 == galois_field ? 1 : 0) <<
+	tmp |= (geo->ecc_strength >> 1) << BCH_FLASHLAYOUT1_ECCN_OFFSET;
+	tmp |= geo->ecc_chunk_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT;
+	tmp |= (geo->gf_len == 14 ? 1 : 0) <<
 		BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET;
 	writel(tmp, &bch_regs->hw_bch_flash0layout1);
 
@@ -1046,8 +1051,7 @@ static int mxs_nand_scan_bbt(struct mtd_info *mtd)
 		mtd->_block_markbad = mxs_nand_hook_block_markbad;
 	}
 
-	/* We use the reference implementation for bad block management. */
-	return nand_default_bbt(mtd);
+	return 0;
 }
 
 /*
@@ -1088,12 +1092,8 @@ int mxs_nand_alloc_buffers(struct mxs_nand_info *nand_info)
 /*
  * Initializes the NFC hardware.
  */
-int mxs_nand_init(struct mxs_nand_info *info)
+int mxs_nand_init_dma(struct mxs_nand_info *info)
 {
-	struct mxs_gpmi_regs *gpmi_regs =
-		(struct mxs_gpmi_regs *)MXS_GPMI_BASE;
-	struct mxs_bch_regs *bch_regs =
-		(struct mxs_bch_regs *)MXS_BCH_BASE;
 	int i = 0, j, ret = 0;
 
 	info->desc = malloc(sizeof(struct mxs_dma_desc *) *
@@ -1122,14 +1122,14 @@ int mxs_nand_init(struct mxs_nand_info *info)
 	}
 
 	/* Reset the GPMI block. */
-	mxs_reset_block(&gpmi_regs->hw_gpmi_ctrl0_reg);
-	mxs_reset_block(&bch_regs->hw_bch_ctrl_reg);
+	mxs_reset_block(&info->gpmi_regs->hw_gpmi_ctrl0_reg);
+	mxs_reset_block(&info->bch_regs->hw_bch_ctrl_reg);
 
 	/*
 	 * Choose NAND mode, set IRQ polarity, disable write protection and
 	 * select BCH ECC.
 	 */
-	clrsetbits_le32(&gpmi_regs->hw_gpmi_ctrl1,
+	clrsetbits_le32(&info->gpmi_regs->hw_gpmi_ctrl1,
 			GPMI_CTRL1_GPMI_MODE,
 			GPMI_CTRL1_ATA_IRQRDY_POLARITY | GPMI_CTRL1_DEV_RESET |
 			GPMI_CTRL1_BCH_MODE);
@@ -1149,16 +1149,7 @@ err1:
 	return ret;
 }
 
-/*!
- * This function is called during the driver binding process.
- *
- * @param   pdev  the device structure used to store device specific
- *                information that is used by the suspend, resume and
- *                remove functions
- *
- * @return  The function always returns 0.
- */
-int board_nand_init(struct nand_chip *nand)
+int mxs_nand_init_spl(struct nand_chip *nand)
 {
 	struct mxs_nand_info *nand_info;
 	int err;
@@ -1170,31 +1161,83 @@ int board_nand_init(struct nand_chip *nand)
 	}
 	memset(nand_info, 0, sizeof(struct mxs_nand_info));
 
+	nand_info->gpmi_regs = (struct mxs_gpmi_regs *)MXS_GPMI_BASE;
+	nand_info->bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE;
 	err = mxs_nand_alloc_buffers(nand_info);
 	if (err)
-		goto err1;
+		return err;
+
+	err = mxs_nand_init_dma(nand_info);
+	if (err)
+		return err;
+
+	nand_set_controller_data(nand, nand_info);
+
+	nand->options |= NAND_NO_SUBPAGE_WRITE;
+
+	nand->cmd_ctrl		= mxs_nand_cmd_ctrl;
+	nand->dev_ready		= mxs_nand_device_ready;
+	nand->select_chip	= mxs_nand_select_chip;
+
+	nand->read_byte		= mxs_nand_read_byte;
+	nand->read_buf		= mxs_nand_read_buf;
+
+	nand->ecc.read_page	= mxs_nand_ecc_read_page;
+
+	nand->ecc.mode		= NAND_ECC_HW;
+	nand->ecc.bytes		= 9;
+	nand->ecc.size		= 512;
+	nand->ecc.strength	= 8;
+
+	return 0;
+}
+
+int mxs_nand_init_ctrl(struct mxs_nand_info *nand_info)
+{
+	struct mtd_info *mtd;
+	struct nand_chip *nand;
+	int err;
+
+	nand = &nand_info->chip;
+	mtd = nand_to_mtd(nand);
+	err = mxs_nand_alloc_buffers(nand_info);
+	if (err)
+		return err;
 
-	err = mxs_nand_init(nand_info);
+	err = mxs_nand_init_dma(nand_info);
 	if (err)
-		goto err2;
+		goto err_free_buffers;
 
 	memset(&fake_ecc_layout, 0, sizeof(fake_ecc_layout));
 
+#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
+	nand->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
+#endif
+
 	nand_set_controller_data(nand, nand_info);
 	nand->options |= NAND_NO_SUBPAGE_WRITE;
 
+	if (nand_info->dev)
+		nand->flash_node = dev_of_offset(nand_info->dev);
+
 	nand->cmd_ctrl		= mxs_nand_cmd_ctrl;
 
 	nand->dev_ready		= mxs_nand_device_ready;
 	nand->select_chip	= mxs_nand_select_chip;
 	nand->block_bad		= mxs_nand_block_bad;
-	nand->scan_bbt		= mxs_nand_scan_bbt;
 
 	nand->read_byte		= mxs_nand_read_byte;
 
 	nand->read_buf		= mxs_nand_read_buf;
 	nand->write_buf		= mxs_nand_write_buf;
 
+	/* first scan to find the device and get the page size */
+	if (nand_scan_ident(mtd, CONFIG_SYS_MAX_NAND_DEVICE, NULL))
+		goto err_free_buffers;
+
+	if (mxs_nand_setup_ecc(mtd))
+		goto err_free_buffers;
+
 	nand->ecc.read_page	= mxs_nand_ecc_read_page;
 	nand->ecc.write_page	= mxs_nand_ecc_write_page;
 	nand->ecc.read_oob	= mxs_nand_ecc_read_oob;
@@ -1202,16 +1245,58 @@ int board_nand_init(struct nand_chip *nand)
 
 	nand->ecc.layout	= &fake_ecc_layout;
 	nand->ecc.mode		= NAND_ECC_HW;
-	nand->ecc.bytes		= 9;
-	nand->ecc.size		= 512;
-	nand->ecc.strength	= 8;
+	nand->ecc.size		= nand_info->bch_geometry.ecc_chunk_size;
+	nand->ecc.strength	= nand_info->bch_geometry.ecc_strength;
+
+	/* second phase scan */
+	err = nand_scan_tail(mtd);
+	if (err)
+		goto err_free_buffers;
+
+	err = nand_register(0, mtd);
+	if (err)
+		goto err_free_buffers;
 
 	return 0;
 
-err2:
+err_free_buffers:
 	free(nand_info->data_buf);
 	free(nand_info->cmd_buf);
-err1:
-	free(nand_info);
+
 	return err;
 }
+
+#ifndef CONFIG_NAND_MXS_DT
+void board_nand_init(void)
+{
+	struct mxs_nand_info *nand_info;
+
+	nand_info = malloc(sizeof(struct mxs_nand_info));
+	if (!nand_info) {
+		printf("MXS NAND: Failed to allocate private data\n");
+			return;
+	}
+	memset(nand_info, 0, sizeof(struct mxs_nand_info));
+
+	nand_info->gpmi_regs = (struct mxs_gpmi_regs *)MXS_GPMI_BASE;
+	nand_info->bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE;
+
+	/* Refer to Chapter 17 for i.MX6DQ, Chapter 18 for i.MX6SX */
+	if (is_mx6sx() || is_mx7())
+		nand_info->max_ecc_strength_supported = 62;
+	else
+		nand_info->max_ecc_strength_supported = 40;
+
+#ifdef CONFIG_NAND_MXS_USE_MINIMUM_ECC
+	nand_info->use_minimum_ecc = true;
+#endif
+
+	if (mxs_nand_init_ctrl(nand_info) < 0)
+		goto err;
+
+	return;
+
+err:
+	free(nand_info);
+}
+#endif
diff --git a/drivers/mtd/nand/mxs_nand.h b/drivers/mtd/nand/mxs_nand.h
new file mode 100644
index 0000000000000000000000000000000000000000..4bd65cded94a6cc44d293fabe54ad9c1ce147ca5
--- /dev/null
+++ b/drivers/mtd/nand/mxs_nand.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * NXP GPMI NAND flash driver
+ *
+ * Copyright (C) 2018 Toradex
+ * Authors:
+ * Stefan Agner <stefan.agner@toradex.com>
+ */
+
+#include <linux/mtd/mtd.h>
+#include <asm/cache.h>
+#include <nand.h>
+#include <asm/mach-imx/dma.h>
+
+/**
+ * @gf_len:                   The length of Galois Field. (e.g., 13 or 14)
+ * @ecc_strength:             A number that describes the strength of the ECC
+ *                            algorithm.
+ * @ecc_chunk_size:           The size, in bytes, of a single ECC chunk. Note
+ *                            the first chunk in the page includes both data and
+ *                            metadata, so it's a bit larger than this value.
+ * @ecc_chunk_count:          The number of ECC chunks in the page,
+ * @block_mark_byte_offset:   The byte offset in the ECC-based page view at
+ *                            which the underlying physical block mark appears.
+ * @block_mark_bit_offset:    The bit offset into the ECC-based page view at
+ *                            which the underlying physical block mark appears.
+ */
+struct bch_geometry {
+	unsigned int  gf_len;
+	unsigned int  ecc_strength;
+	unsigned int  ecc_chunk_size;
+	unsigned int  ecc_chunk_count;
+	unsigned int  block_mark_byte_offset;
+	unsigned int  block_mark_bit_offset;
+};
+
+struct mxs_nand_info {
+	struct nand_chip chip;
+	struct udevice *dev;
+	unsigned int	max_ecc_strength_supported;
+	bool		use_minimum_ecc;
+	int		cur_chip;
+
+	uint32_t	cmd_queue_len;
+	uint32_t	data_buf_size;
+	struct bch_geometry bch_geometry;
+
+	uint8_t		*cmd_buf;
+	uint8_t		*data_buf;
+	uint8_t		*oob_buf;
+
+	uint8_t		marking_block_bad;
+	uint8_t		raw_oob_mode;
+
+	struct mxs_gpmi_regs *gpmi_regs;
+	struct mxs_bch_regs *bch_regs;
+
+	/* Functions with altered behaviour */
+	int		(*hooked_read_oob)(struct mtd_info *mtd,
+				loff_t from, struct mtd_oob_ops *ops);
+	int		(*hooked_write_oob)(struct mtd_info *mtd,
+				loff_t to, struct mtd_oob_ops *ops);
+	int		(*hooked_block_markbad)(struct mtd_info *mtd,
+				loff_t ofs);
+
+	/* DMA descriptors */
+	struct mxs_dma_desc	**desc;
+	uint32_t		desc_index;
+};
+
+int mxs_nand_init_ctrl(struct mxs_nand_info *nand_info);
+int mxs_nand_init_spl(struct nand_chip *nand);
+int mxs_nand_setup_ecc(struct mtd_info *mtd);
diff --git a/drivers/mtd/nand/mxs_nand_dt.c b/drivers/mtd/nand/mxs_nand_dt.c
new file mode 100644
index 0000000000000000000000000000000000000000..f89eb091a992acae29c6d25ac981e79466087e89
--- /dev/null
+++ b/drivers/mtd/nand/mxs_nand_dt.c
@@ -0,0 +1,86 @@
+/*
+ * NXP GPMI NAND flash driver (DT initialization)
+ *
+ * Copyright (C) 2018 Toradex
+ * Authors:
+ * Stefan Agner <stefan.agner@toradex.com>
+ *
+ * Based on denali_dt.c
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <dm.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/printk.h>
+
+#include "mxs_nand.h"
+
+struct mxs_nand_dt_data {
+	unsigned int max_ecc_strength_supported;
+};
+
+static const struct mxs_nand_dt_data mxs_nand_imx7d_data = {
+	.max_ecc_strength_supported = 62,
+};
+
+static const struct udevice_id mxs_nand_dt_ids[] = {
+	{
+		.compatible = "fsl,imx7d-gpmi-nand",
+		.data = (unsigned long)&mxs_nand_imx7d_data,
+	},
+	{ /* sentinel */ }
+};
+
+static int mxs_nand_dt_probe(struct udevice *dev)
+{
+	struct mxs_nand_info *info = dev_get_priv(dev);
+	const struct mxs_nand_dt_data *data;
+	struct resource res;
+	int ret;
+
+	data = (void *)dev_get_driver_data(dev);
+	if (data)
+		info->max_ecc_strength_supported = data->max_ecc_strength_supported;
+
+	info->dev = dev;
+
+	ret = dev_read_resource_byname(dev, "gpmi-nand", &res);
+	if (ret)
+		return ret;
+
+	info->gpmi_regs = devm_ioremap(dev, res.start, resource_size(&res));
+
+
+	ret = dev_read_resource_byname(dev, "bch", &res);
+	if (ret)
+		return ret;
+
+	info->bch_regs = devm_ioremap(dev, res.start, resource_size(&res));
+
+	info->use_minimum_ecc = dev_read_bool(dev, "fsl,use-minimum-ecc");
+
+	return mxs_nand_init_ctrl(info);
+}
+
+U_BOOT_DRIVER(mxs_nand_dt) = {
+	.name = "mxs-nand-dt",
+	.id = UCLASS_MTD,
+	.of_match = mxs_nand_dt_ids,
+	.probe = mxs_nand_dt_probe,
+	.priv_auto_alloc_size = sizeof(struct mxs_nand_info),
+};
+
+void board_nand_init(void)
+{
+	struct udevice *dev;
+	int ret;
+
+	ret = uclass_get_device_by_driver(UCLASS_MTD,
+					  DM_GET_DRIVER(mxs_nand_dt),
+					  &dev);
+	if (ret && ret != -ENODEV)
+		pr_err("Failed to initialize MXS NAND controller. (error %d)\n",
+		       ret);
+}
diff --git a/drivers/mtd/nand/mxs_nand_spl.c b/drivers/mtd/nand/mxs_nand_spl.c
index 3e8b35f04adc81e5ea017ebfed0759fbbff2d7e9..2d7bbe83cce5419ad7030736a4ebd19708d5523f 100644
--- a/drivers/mtd/nand/mxs_nand_spl.c
+++ b/drivers/mtd/nand/mxs_nand_spl.c
@@ -6,6 +6,7 @@
 #include <common.h>
 #include <nand.h>
 #include <malloc.h>
+#include "mxs_nand.h"
 
 static struct mtd_info *mtd;
 static struct nand_chip nand_chip;
@@ -48,7 +49,29 @@ static void mxs_nand_command(struct mtd_info *mtd, unsigned int command,
 	}
 }
 
-static int mxs_flash_ident(struct mtd_info *mtd)
+#if defined (CONFIG_SPL_NAND_IDENT)
+
+/* Trying to detect the NAND flash using ONFi, JEDEC, and (extended) IDs */
+static int mxs_flash_full_ident(struct mtd_info *mtd)
+{
+	int nand_maf_id, nand_dev_id;
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	struct nand_flash_dev *type;
+
+	type = nand_get_flash_type(mtd, chip, &nand_maf_id, &nand_dev_id, NULL);
+
+	if (IS_ERR(type)) {
+		chip->select_chip(mtd, -1);
+		return PTR_ERR(type);
+	}
+
+	return 0;
+}
+
+#else
+
+/* Trying to detect the NAND flash using ONFi only */
+static int mxs_flash_onfi_ident(struct mtd_info *mtd)
 {
 	register struct nand_chip *chip = mtd_to_nand(mtd);
 	int i;
@@ -108,6 +131,19 @@ static int mxs_flash_ident(struct mtd_info *mtd)
 	return 0;
 }
 
+#endif /* CONFIG_SPL_NAND_IDENT */
+
+static int mxs_flash_ident(struct mtd_info *mtd)
+{
+	int ret;
+#if defined (CONFIG_SPL_NAND_IDENT)
+	ret = mxs_flash_full_ident(mtd);
+#else
+	ret = mxs_flash_onfi_ident(mtd);
+#endif
+	return ret;
+}
+
 static int mxs_read_page_ecc(struct mtd_info *mtd, void *buf, unsigned int page)
 {
 	register struct nand_chip *chip = mtd_to_nand(mtd);
@@ -145,7 +181,7 @@ static int mxs_nand_init(void)
 		return 0;
 
 	/* init mxs nand driver */
-	board_nand_init(&nand_chip);
+	mxs_nand_init_spl(&nand_chip);
 	mtd = nand_to_mtd(&nand_chip);
 	/* set mtd functions */
 	nand_chip.cmdfunc = mxs_nand_command;
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index eb9f121f810a270616e41c514fd44b8d69a9d8e1..64e4621aaaf1324667763fb6fa67001959a63125 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3755,7 +3755,7 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip,
 /*
  * Get the flash and manufacturer id and lookup if the type is supported.
  */
-static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
+struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 						  struct nand_chip *chip,
 						  int *maf_id, int *dev_id,
 						  struct nand_flash_dev *type)
@@ -3927,6 +3927,7 @@ ident_done:
 		mtd->erasesize >> 10, mtd->writesize, mtd->oobsize);
 	return type;
 }
+EXPORT_SYMBOL(nand_get_flash_type);
 
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 DECLARE_GLOBAL_DATA_PTR;
diff --git a/drivers/power/pmic/pfuze100.c b/drivers/power/pmic/pfuze100.c
index 4670a84560ebab526b4c4689f87f172021b5226b..8a5a8996b432879fcf3acb58611706bd2c693ed4 100644
--- a/drivers/power/pmic/pfuze100.c
+++ b/drivers/power/pmic/pfuze100.c
@@ -12,6 +12,7 @@
 #include <power/pmic.h>
 #include <power/regulator.h>
 #include <power/pfuze100_pmic.h>
+#include <power/pfuze3000_pmic.h>
 
 static const struct pmic_child_info pmic_children_info[] = {
 	/* sw[x], swbst */
@@ -23,7 +24,7 @@ static const struct pmic_child_info pmic_children_info[] = {
 
 static int pfuze100_reg_count(struct udevice *dev)
 {
-	return PFUZE100_NUM_OF_REGS;
+	return dev->driver_data == PFUZE3000 ? PFUZE3000_NUM_OF_REGS : PFUZE100_NUM_OF_REGS;
 }
 
 static int pfuze100_write(struct udevice *dev, uint reg, const uint8_t *buff,
diff --git a/drivers/power/pmic/pmic_pfuze3000.c b/drivers/power/pmic/pmic_pfuze3000.c
index f2a51fe4a49a9b567d835cb41a25d154768faacd..1077fa5e9d9869bcefd90311037a1a8d7c5a96b2 100644
--- a/drivers/power/pmic/pmic_pfuze3000.c
+++ b/drivers/power/pmic/pmic_pfuze3000.c
@@ -22,7 +22,7 @@ int power_pfuze3000_init(unsigned char bus)
 
 	p->name = name;
 	p->interface = PMIC_I2C;
-	p->number_of_regs = PMIC_NUM_OF_REGS;
+	p->number_of_regs = PFUZE3000_NUM_OF_REGS;
 	p->hw.i2c.addr = CONFIG_POWER_PFUZE3000_I2C_ADDR;
 	p->hw.i2c.tx_num = 1;
 	p->bus = bus;
diff --git a/include/configs/display5.h b/include/configs/display5.h
index cff689420e75855f5c7bfa45ac60ab6ae6bdb285..f3c875738563556ab87ff144da22bb2ea28c34f6 100644
--- a/include/configs/display5.h
+++ b/include/configs/display5.h
@@ -30,9 +30,9 @@
  * 0x020000 - 0x120000 : SPI.u-boot (1MiB)
  * 0x120000 - 0x130000 : SPI.u-boot-env1 (64KiB)
  * 0x130000 - 0x140000 : SPI.u-boot-env2 (64KiB)
- * 0x140000 - 0x940000 : SPI.fitImage-recovery (8MiB)
- * 0x940000 - 0xD40000 : SPI.swupdate-kernel-FIT (4MiB)
- * 0xD40000 - 0x1540000 : SPI.swupdate-initramfs  (8MiB)
+ * 0x140000 - 0x540000 : SPI.swupdate-kernel-FIT (4MiB)
+ * 0x540000 - 0x1540000 : SPI.swupdate-initramfs  (16MiB)
+ * 0x1540000 - 0x1640000 : SPI.factory  (1MiB)
  */
 
 #ifndef CONFIG_SPL_BUILD
@@ -100,7 +100,13 @@
 #define CONFIG_BAUDRATE			115200
 
 #ifndef CONFIG_BOOTCOMMAND
-#define CONFIG_BOOTCOMMAND "run boot_mmc"
+#define CONFIG_BOOTCOMMAND "if run check_em_pad; then " \
+	     "run recovery;" \
+	"else if test ${BOOT_FROM} = FACTORY; then " \
+	     "run factory_nfs;" \
+	"else " \
+	     "run boot_mmc;" \
+	"fi;fi"
 #endif
 
 #define PARTS_DEFAULT \
@@ -110,7 +116,7 @@
 	"name=kernel_raw1,start=128K,size=8M,uuid=${uuid_gpt_kernel_raw1};" \
 	"name=rootfs1,size=1528M,uuid=${uuid_gpt_rootfs1};" \
 	"name=kernel_raw2,size=8M,uuid=${uuid_gpt_kernel_raw2};" \
-	"name=rootfs2,size=1528M,uuid=${uuid_gpt_rootfs2};" \
+	"name=rootfs2,size=512M,uuid=${uuid_gpt_rootfs2};" \
 	"name=data,size=-,uuid=${uuid_gpt_data}\0"
 
 #define FACTORY_PROCEDURE \
@@ -123,7 +129,6 @@
 	"run tftp_sf_SPL;" \
 	"run tftp_sf_uboot;" \
 	TFTP_UPDATE_KERNEL \
-	"run tftp_sf_fitImg_recovery;" \
 	"run tftp_sf_fitImg_SWU;" \
 	"run tftp_sf_initramfs_SWU;" \
 	TFTP_UPDATE_ROOTFS \
@@ -139,6 +144,16 @@
 	"echo '#######################';" \
 	"echo '# RECOVERY SWUupdate  #';" \
 	"echo '#######################';" \
+	"echo '#######################';" \
+	"echo '# GPT verify          #';" \
+	"if gpt verify mmc ${mmcdev} ${partitions}; then " \
+		"echo '# OK !                #';" \
+	"else " \
+		"echo '# FAILED !            #';" \
+		"echo '# GPT RESTORATION     #';" \
+		"gpt write mmc ${mmcdev} ${partitions};" \
+	"fi;" \
+	"echo '#######################';" \
 	"setenv loadaddr_swu_initramfs 0x14000000;" \
 	"setenv bootargs console=${console} " \
 		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}" \
@@ -146,15 +161,7 @@
 	"sf probe;" \
 	"sf read ${loadaddr} swu-kernel;" \
 	"sf read ${loadaddr_swu_initramfs} swu-initramfs;" \
-	"bootm ${loadaddr} ${loadaddr_swu_initramfs};"
-
-#define KERNEL_RECOVERY_PROCEDURE \
-	"echo '#######################';" \
-	"echo '# RECOVERY KERNEL IMG #';" \
-	"echo '#######################';" \
-	"sf probe;" \
-	"sf read ${loadaddr} lin-recovery;" \
-	"bootm;"
+	"bootm ${loadaddr} ${loadaddr_swu_initramfs};reset;"
 
 #define SETUP_BOOTARGS \
 	"run set_rootfs_part;" \
@@ -197,13 +204,11 @@
 	       "mmc write ${loadaddr} ${lba_start} ${fw_sz}; " \
 	   "; fi\0" \
 
-/* To save some considerable time, we only once download the rootfs image */
-/* and store it on 'active' and 'backup' rootfs partitions */
 #define TFTP_UPDATE_ROOTFS \
 	"setenv rootfs_part ${rootfs_part_active};" \
 	"run tftp_mmc_rootfs;" \
-	"part start mmc ${mmcdev} ${rootfs_part_backup} lba_start;" \
-	"mmc write ${loadaddr} ${lba_start} ${fw_sz};" \
+	"run tftp_mmc_rootfs_bkp;" \
+
 
 #define TFTP_UPDATE_RECOVERY_SWU_KERNEL \
 	"tftp_sf_fitImg_SWU=" \
@@ -214,7 +219,7 @@
 	"; fi\0"	  \
 
 #define TFTP_UPDATE_RECOVERY_SWU_INITRAMFS \
-	"swu_initramfs_file=swupdate-image-display5.ext3.gz.u-boot\0" \
+	"swu_initramfs_file=swupdate-image-display5.ext4.gz.u-boot\0" \
 	"tftp_sf_initramfs_SWU=" \
 	    "if tftp ${loadaddr} ${swu_initramfs_file}; then " \
 		"sf probe;" \
@@ -222,15 +227,6 @@
 		"sf write ${loadaddr} swu-initramfs ${filesize};" \
 	"; fi\0"	  \
 
-#define TFTP_UPDATE_RECOVERY_KERNEL_INITRAMFS \
-	"kernel_recovery_file=fitImage-initramfs\0" \
-	"tftp_sf_fitImg_recovery=" \
-	    "if tftp ${loadaddr} ${kernel_recovery_file}; then " \
-		"sf probe;" \
-		"sf erase lin-recovery +${filesize};" \
-		"sf write ${loadaddr} lin-recovery ${filesize};" \
-	"; fi\0"	  \
-
 #define TFTP_UPDATE_BOOTLOADER \
 	"ubootfile=u-boot.img\0" \
 	"ubootfileSPL=SPL\0" \
@@ -248,8 +244,20 @@
 		"sf write ${loadaddr} 0x400 ${filesize};" \
 	"fi\0" \
 
+#define TFTP_UPDATE_SPINOR \
+	"spinorfile=core-image-lwn-display5.spinor\0" \
+	"spinorsize=0x2000000\0" \
+	"tftp_sf_img=" \
+	    "if tftp ${loadaddr} ${spinorfile}; then " \
+		"sf probe;" \
+		"sf erase 0x0 ${spinorsize};" \
+		"sf write ${loadaddr} 0x0 ${filesize};" \
+	"fi\0" \
+
 #define CONFIG_EXTRA_ENV_SETTINGS	  \
 	PARTS_DEFAULT \
+	"gpio_recovery=93\0" \
+	"check_em_pad=gpio input ${gpio_recovery};test $? -eq 0;\0" \
 	"display=tianma-tm070-800x480\0" \
 	"board=display5\0" \
 	"mmcdev=0\0" \
@@ -265,7 +273,7 @@
 	"hostname=display5\0" \
 	"loadaddr=0x12000000\0" \
 	"fdtaddr=0x12800000\0" \
-	"console=ttymxc4,115200 quiet\0" \
+	"console=ttymxc4,115200 quiet cma=256M\0" \
 	"fdtfile=imx6q-display5.dtb\0" \
 	"fdt_high=0xffffffff\0" \
 	"initrd_high=0xffffffff\0" \
@@ -273,21 +281,22 @@
 	"up=run tftp_sf_SPL; run tftp_sf_uboot\0" \
 	"download_kernel=" \
 		"tftpboot ${loadaddr} ${kernel_file};\0" \
-	"boot_kernel_recovery=" KERNEL_RECOVERY_PROCEDURE "\0" \
+	"factory_nfs=" \
+	     "setenv ipaddr 192.168.1.102;" \
+	     "setenv gatewayip 192.168.1.1;" \
+	     "setenv netmask 255.255.255.0;" \
+	     "setenv serverip 192.168.1.2;" \
+	     "echo BOOT: FACTORY (LEG);" \
+	     "run boot_nfs\0" \
 	"boot_swu_recovery=" SWUPDATE_RECOVERY_PROCEDURE "\0" \
 	"recovery=" \
-	"if test ${BOOT_FROM_RECOVERY} = SWU; then " \
 	     "echo BOOT: RECOVERY: SWU;" \
-	     "run boot_swu_recovery;" \
-	"else " \
-	     "echo BOOT: RECOVERY: Linux;" \
-	     "run boot_kernel_recovery;" \
-	"fi\0" \
+	     "run boot_swu_recovery\0" \
 	"boot_tftp=" \
 	"if run download_kernel; then "	  \
 	     "setenv bootargs console=${console} " \
 	     "root=/dev/mmcblk0p2 rootwait;" \
-	     "bootm ${loadaddr} - ${fdtaddr};" \
+	     "bootm ${loadaddr} - ${fdtaddr};reset;" \
 	"fi\0" \
 	"addip=setenv bootargs ${bootargs} " \
 	"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:" \
@@ -304,7 +313,7 @@
 	     "run addip;"	  \
 	     "setenv bootargs ${bootargs} console=${console};"	  \
 	     "setenv fdt_conf imx6q-${board}-${display}.dtb; " \
-	     "bootm ${loadaddr}#conf@${fdt_conf};" \
+	     "bootm ${loadaddr}#conf@${fdt_conf};reset;" \
 	"fi\0" \
 	"falcon_setup=" \
 	"if mmc dev ${mmcdev}; then "	  \
@@ -318,7 +327,7 @@
 	"boot_mmc=" \
 	"if mmc dev ${mmcdev}; then "	  \
 	     SETUP_BOOTARGS \
-	     "bootm ${loadaddr}#conf@${fdt_conf};" \
+	     "bootm ${loadaddr}#conf@${fdt_conf};reset;" \
 	"fi\0" \
 	"set_kernel_part=" \
 	"if test ${BOOT_FROM} = ACTIVE; then " \
@@ -339,16 +348,20 @@
 	     "run recovery;" \
 	"fi;fi\0" \
 	"BOOT_FROM=ACTIVE\0" \
-	"BOOT_FROM_RECOVERY=Linux\0" \
 	TFTP_UPDATE_BOOTLOADER \
+	TFTP_UPDATE_SPINOR \
 	"kernel_part_active=1\0" \
 	"kernel_part_backup=3\0" \
 	__TFTP_UPDATE_KERNEL \
 	"rootfs_part_active=2\0" \
 	"rootfs_part_backup=4\0" \
 	"rootfs_file=core-image-lwn-display5.ext4\0" \
+	"rootfs_file_backup=core-image-lwn-backup-display5.ext4\0" \
 	__TFTP_UPDATE_ROOTFS \
-	TFTP_UPDATE_RECOVERY_KERNEL_INITRAMFS \
+	"tftp_mmc_rootfs_bkp=" \
+	   "setenv rootfs_part ${rootfs_part_backup};" \
+	   "setenv rootfs_file ${rootfs_file_backup};" \
+	   "run tftp_mmc_rootfs\0" \
 	TFTP_UPDATE_RECOVERY_SWU_KERNEL \
 	TFTP_UPDATE_RECOVERY_SWU_INITRAMFS \
 	"\0" \
@@ -383,6 +396,11 @@
 #define CONFIG_MTD_PARTITIONS
 #define CONFIG_MTD_DEVICE
 
+/* Watchdog */
+#define CONFIG_HW_WATCHDOG
+#define CONFIG_IMX_WATCHDOG
+#define CONFIG_WATCHDOG_TIMEOUT_MSECS   15000
+
 /* ENV config */
 #ifdef CONFIG_ENV_IS_IN_SPI_FLASH
 #define CONFIG_ENV_SIZE		(SZ_64K)
diff --git a/include/configs/kp_imx53.h b/include/configs/kp_imx53.h
index 530c3557d03ed1c2145e487ae0d6438174cbedd5..0dc708e480ac801166fbaa5a06030dc82915ea23 100644
--- a/include/configs/kp_imx53.h
+++ b/include/configs/kp_imx53.h
@@ -46,6 +46,7 @@
 	"fdt_high=0xffffffff\0"		\
 	"scriptaddr=0x74000000\0"	\
 	"kernel_file=fitImage\0"\
+	"silent=1\0"\
 	"rdinit=/sbin/init\0" \
 	"addinitrd=setenv bootargs ${bootargs} rdinit=${rdinit} ${debug} \0" \
 	"upd_image=st.4k\0" \
diff --git a/include/configs/mx6cuboxi.h b/include/configs/mx6cuboxi.h
index 6e2137769822799335fa14f3527920673382c186..803661cfa843390970a7bacfa204ae25fd391187 100644
--- a/include/configs/mx6cuboxi.h
+++ b/include/configs/mx6cuboxi.h
@@ -101,18 +101,18 @@
 			"fi; "	\
 		"fi\0" \
 	"findfdt="\
-		"if test $board_name = HUMMINGBOARD2 && test $board_rev = MX6Q ; then " \
-			"setenv fdtfile imx6q-hummingboard2.dtb; fi; " \
-		"if test $board_name = HUMMINGBOARD2 && test $board_rev = MX6DL ; then " \
-			"setenv fdtfile imx6dl-hummingboard2.dtb; fi; " \
-		"if test $board_name = HUMMINGBOARD && test $board_rev = MX6Q ; then " \
-			"setenv fdtfile imx6q-hummingboard.dtb; fi; " \
-		"if test $board_name = HUMMINGBOARD && test $board_rev = MX6DL ; then " \
-			"setenv fdtfile imx6dl-hummingboard.dtb; fi; " \
-		"if test $board_name = CUBOXI && test $board_rev = MX6Q ; then " \
-			"setenv fdtfile imx6q-cubox-i.dtb; fi; " \
-		"if test $board_name = CUBOXI && test $board_rev = MX6DL ; then " \
-			"setenv fdtfile imx6dl-cubox-i.dtb; fi; " \
+		"if test $board_rev = MX6Q ; then " \
+			"setenv fdtprefix imx6q; fi; " \
+		"if test $board_rev = MX6DL ; then " \
+			"setenv fdtprefix imx6dl; fi; " \
+		"if test $som_rev = V15 ; then " \
+			"setenv fdtsuffix -som-v15; fi; " \
+		"if test $board_name = HUMMINGBOARD2 ; then " \
+			"setenv fdtfile ${fdtprefix}-hummingboard2${fdtsuffix}.dtb; fi; " \
+		"if test $board_name = HUMMINGBOARD ; then " \
+			"setenv fdtfile ${fdtprefix}-hummingboard${fdtsuffix}.dtb; fi; " \
+		"if test $board_name = CUBOXI ; then " \
+			"setenv fdtfile ${fdtprefix}-cubox-i${fdtsuffix}.dtb; fi; " \
 		"if test $fdtfile = undefined; then " \
 			"echo WARNING: Could not determine dtb to use; fi; \0" \
 	BOOTENV
diff --git a/include/configs/pico-imx7d.h b/include/configs/pico-imx7d.h
index b208d7f4d969379c5fcd9a6592860837acacc8b8..d2ffa70fc556100a5152666fe7b2c5b878dd0c1d 100644
--- a/include/configs/pico-imx7d.h
+++ b/include/configs/pico-imx7d.h
@@ -41,7 +41,7 @@
 	"console=ttymxc4\0" \
 	"fdt_high=0xffffffff\0" \
 	"initrd_high=0xffffffff\0" \
-	"fdt_file=imx7d-pico.dtb\0" \
+	"fdt_file=imx7d-pico-pi.dtb\0" \
 	"fdt_addr=0x83000000\0" \
 	"ip_dyn=yes\0" \
 	"mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \
diff --git a/include/configs/wandboard.h b/include/configs/wandboard.h
index 1edd7a88270fb45e8acb7e79d9e040283d6e0c03..cb32cd11f945c6c7480016468cf70789f2c3d113 100644
--- a/include/configs/wandboard.h
+++ b/include/configs/wandboard.h
@@ -78,7 +78,7 @@
 #endif
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
-	"console=ttymxc0,115200\0" \
+	"console=ttymxc0\0" \
 	"splashpos=m,m\0" \
 	"fdtfile=undefined\0" \
 	"fdt_high=0xffffffff\0" \
diff --git a/include/dt-bindings/clock/imx7d-clock.h b/include/dt-bindings/clock/imx7d-clock.h
index a7a1a50f33efe98b00f6f818d2cca609019673bc..b2325d3e236a72ad36f6e29412aa57f6c397e08c 100644
--- a/include/dt-bindings/clock/imx7d-clock.h
+++ b/include/dt-bindings/clock/imx7d-clock.h
@@ -80,10 +80,10 @@
 #define IMX7D_ARM_M4_ROOT_SRC		67
 #define IMX7D_ARM_M4_ROOT_CG		68
 #define IMX7D_ARM_M4_ROOT_DIV		69
-#define IMX7D_ARM_M0_ROOT_CLK		70
-#define IMX7D_ARM_M0_ROOT_SRC		71
-#define IMX7D_ARM_M0_ROOT_CG		72
-#define IMX7D_ARM_M0_ROOT_DIV		73
+#define IMX7D_ARM_M0_ROOT_CLK		70	/* unused */
+#define IMX7D_ARM_M0_ROOT_SRC		71	/* unused */
+#define IMX7D_ARM_M0_ROOT_CG		72	/* unused */
+#define IMX7D_ARM_M0_ROOT_DIV		73	/* unused */
 #define IMX7D_MAIN_AXI_ROOT_CLK		74
 #define IMX7D_MAIN_AXI_ROOT_SRC		75
 #define IMX7D_MAIN_AXI_ROOT_CG		76
@@ -450,5 +450,10 @@
 #define IMX7D_CLK_ARM			437
 #define IMX7D_CKIL			438
 #define IMX7D_OCOTP_CLK			439
-#define IMX7D_CLK_END			440
+#define IMX7D_NAND_RAWNAND_CLK		440
+#define IMX7D_NAND_USDHC_BUS_RAWNAND_CLK 441
+#define IMX7D_SNVS_CLK			442
+#define IMX7D_CAAM_CLK			443
+#define IMX7D_KPP_ROOT_CLK		444
+#define IMX7D_CLK_END			445
 #endif /* __DT_BINDINGS_CLOCK_IMX7D_H */
diff --git a/include/dt-bindings/power/imx7-power.h b/include/dt-bindings/power/imx7-power.h
new file mode 100644
index 0000000000000000000000000000000000000000..3a181e4105171d5a039cee8ce27862254fd7444d
--- /dev/null
+++ b/include/dt-bindings/power/imx7-power.h
@@ -0,0 +1,16 @@
+/*
+ *  Copyright (C) 2017 Impinj
+ *
+ * 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.
+ */
+
+#ifndef __DT_BINDINGS_IMX7_POWER_H__
+#define __DT_BINDINGS_IMX7_POWER_H__
+
+#define IMX7_POWER_DOMAIN_MIPI_PHY		0
+#define IMX7_POWER_DOMAIN_PCIE_PHY		1
+#define IMX7_POWER_DOMAIN_USB_HSIC_PHY		2
+
+#endif
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 7fe553fc51c2488de556bb9effd902987b88576f..cdad7b85fa6dfc7e0bc3a63b7202e139b82ac53e 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -22,9 +22,16 @@
 #include <asm/cache.h>
 
 struct mtd_info;
+struct nand_chip;
 struct nand_flash_dev;
 struct device_node;
 
+/* Get the flash and manufacturer id and lookup if the type is supported. */
+struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
+					   struct nand_chip *chip,
+					   int *maf_id, int *dev_id,
+					   struct nand_flash_dev *type);
+
 /* Scan and identify a NAND device */
 int nand_scan(struct mtd_info *mtd, int max_chips);
 /*
@@ -247,9 +254,6 @@ typedef enum {
 #define NAND_CI_CELLTYPE_MSK	0x0C
 #define NAND_CI_CELLTYPE_SHIFT	2
 
-/* Keep gcc happy */
-struct nand_chip;
-
 /* ONFI features */
 #define ONFI_FEATURE_16_BIT_BUS		(1 << 0)
 #define ONFI_FEATURE_EXT_PARAM_PAGE	(1 << 7)
diff --git a/include/power/pfuze3000_pmic.h b/include/power/pfuze3000_pmic.h
index 87ea7cad466f0b865a9dc2b1d5f61bde5accd28c..b836d67fb62ecf66dcf04d60d60321140f24ec2a 100644
--- a/include/power/pfuze3000_pmic.h
+++ b/include/power/pfuze3000_pmic.h
@@ -69,7 +69,7 @@ enum {
 	PFUZE3000_VLDO3CTL	= 0x70,
 	PFUZE3000_VLD4CTL	= 0x71,
 
-	PMIC_NUM_OF_REGS	= 0x7F,
+	PFUZE3000_NUM_OF_REGS	= 0x100,
 };
 
 int power_pfuze3000_init(unsigned char bus);
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 1a5433759409c1f9ce7c759a7bea3fe40a46a257..1219dcc3befdbde525ea4174691039a589f4858f 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -1937,6 +1937,7 @@ CONFIG_SPL_NAND_BASE
 CONFIG_SPL_NAND_BOOT
 CONFIG_SPL_NAND_DRIVERS
 CONFIG_SPL_NAND_ECC
+CONFIG_SPL_NAND_IDENT
 CONFIG_SPL_NAND_INIT
 CONFIG_SPL_NAND_LOAD
 CONFIG_SPL_NAND_MINIMAL