Merge git://git.denx.de/u-boot-net
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index bbc4f47..e22b52c 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -211,7 +211,8 @@
 	fsl-ls1012a-rdb.dtb \
 	fsl-ls1012a-frdm.dtb
 
-dtb-$(CONFIG_ARCH_SNAPDRAGON) += dragonboard410c.dtb
+dtb-$(CONFIG_TARGET_DRAGONBOARD410C) += dragonboard410c.dtb
+dtb-$(CONFIG_TARGET_DRAGONBOARD820C) += dragonboard820c.dtb
 
 dtb-$(CONFIG_STM32F4) += stm32f429-disco.dtb \
 	stm32f469-disco.dtb
@@ -384,6 +385,7 @@
 	imx6q-icore-rqs.dtb \
 	imx6q-logicpd.dtb \
 	imx6sx-sabreauto.dtb \
+	imx6sx-sdb.dtb \
 	imx6ul-geam-kit.dtb \
 	imx6ul-isiot-emmc.dtb \
 	imx6ul-isiot-mmc.dtb \
diff --git a/arch/arm/dts/dragonboard410c.dts b/arch/arm/dts/dragonboard410c.dts
index 7746622..5ccfe7f 100644
--- a/arch/arm/dts/dragonboard410c.dts
+++ b/arch/arm/dts/dragonboard410c.dts
@@ -23,11 +23,16 @@
 		reg = <0 0x80000000 0 0x3da00000>;
 	};
 
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+	};
+
 	chosen {
 		stdout-path = "/soc/serial@78b0000";
 	};
 
-
 	soc {
 		#address-cells = <0x1>;
 		#size-cells = <0x1>;
@@ -48,11 +53,6 @@
 			clock = <&clkc 4>;
 		};
 
-		restart@4ab000 {
-			compatible = "qcom,pshold";
-			reg = <0x4ab000 0x4>;
-		};
-
 		soc_gpios: pinctrl@1000000 {
 			compatible = "qcom,apq8016-pinctrl";
 			reg = <0x1000000 0x300000>;
@@ -86,6 +86,16 @@
 			clock-frequency = <200000000>;
 		};
 
+		wcnss {
+			bt {
+				compatible="qcom,wcnss-bt";
+			};
+
+			wifi {
+				compatible="qcom,wcnss-wlan";
+			};
+		};
+
 		spmi@200f000 {
 			compatible = "qcom,spmi-pmic-arb";
 			reg = <0x200f800 0x200 0x2400000 0x400000 0x2c00000 0x400000>;
diff --git a/arch/arm/dts/dragonboard820c-uboot.dtsi b/arch/arm/dts/dragonboard820c-uboot.dtsi
new file mode 100644
index 0000000..167e72c
--- /dev/null
+++ b/arch/arm/dts/dragonboard820c-uboot.dtsi
@@ -0,0 +1,19 @@
+/*
+ * U-Boot addition to handle Dragonboard 820c pins
+ *
+ * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+&pm8994_pon {
+	key_vol_down {
+		gpios = <&pm8994_pon 1 0>;
+		label = "key_vol_down";
+	};
+
+	key_power {
+		gpios = <&pm8994_pon 0 0>;
+		label = "key_power";
+	};
+};
diff --git a/arch/arm/dts/dragonboard820c.dts b/arch/arm/dts/dragonboard820c.dts
new file mode 100644
index 0000000..6424944
--- /dev/null
+++ b/arch/arm/dts/dragonboard820c.dts
@@ -0,0 +1,108 @@
+/*
+ * Qualcomm APQ8096 based Dragonboard 820C board device tree source
+ *
+ * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include "skeleton64.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. DB820c";
+	compatible = "arrow,apq8096-db820c", "qcom,apq8096-sbc";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		serial0 = &blsp2_uart1;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0 0x80000000 0 0xc0000000>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	soc: soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0 0 0xffffffff>;
+		compatible = "simple-bus";
+
+		gcc: clock-controller@300000 {
+			compatible = "qcom,gcc-msm8996";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+			reg = <0x300000 0x90000>;
+		};
+
+		blsp2_uart1: serial@75b0000 {
+			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+			reg = <0x75b0000 0x1000>;
+		};
+
+		sdhc2: sdhci@74a4900 {
+			 compatible = "qcom,sdhci-msm-v4";
+			 reg = <0x74a4900 0x314>, <0x74a4000 0x800>;
+			 index = <0x0>;
+			 bus-width = <4>;
+			 clock = <&gcc 0>;
+			clock-frequency = <200000000>;
+		 };
+
+		spmi@400f000 {
+			compatible = "qcom,spmi-pmic-arb";
+			reg = <0x400f800 0x200>,
+			      <0x4400000 0x400000>,
+			      <0x4c00000 0x400000>;
+			#address-cells = <0x1>;
+			#size-cells = <0x1>;
+
+			pmic0: pm8994@0 {
+				compatible = "qcom,spmi-pmic";
+				reg = <0x0 0x1>;
+				#address-cells = <0x1>;
+				#size-cells = <0x1>;
+
+				pm8994_pon: pm8994_pon@800 {
+					compatible = "qcom,pm8994-pwrkey";
+					reg = <0x800 0x96>;
+					#gpio-cells = <2>;
+					gpio-controller;
+					gpio-bank-name="pm8994_key.";
+				};
+
+				pm8994_gpios: pm8994_gpios@c000 {
+					compatible = "qcom,pm8994-gpio";
+					reg = <0xc000 0x400>;
+					gpio-controller;
+					gpio-count = <24>;
+					#gpio-cells = <2>;
+					gpio-bank-name="pm8994.";
+				};
+			};
+
+			pmic1: pm8994@1 {
+				compatible = "qcom,spmi-pmic";
+				reg = <0x1 0x1>;
+				#address-cells = <0x1>;
+				#size-cells = <0x1>;
+			};
+		};
+	};
+
+};
+
+#include "dragonboard820c-uboot.dtsi"
diff --git a/arch/arm/dts/imx6sx-sdb.dts b/arch/arm/dts/imx6sx-sdb.dts
new file mode 100644
index 0000000..6dd9beb
--- /dev/null
+++ b/arch/arm/dts/imx6sx-sdb.dts
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ */
+
+#include "imx6sx-sdb.dtsi"
+
+/ {
+	model = "Freescale i.MX6 SoloX SDB RevB Board";
+};
+
+&i2c1 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	status = "okay";
+
+	pmic: pfuze100@8 {
+		compatible = "fsl,pfuze200";
+		reg = <0x08>;
+
+		regulators {
+			sw1a_reg: sw1ab {
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1875000>;
+				regulator-boot-on;
+				regulator-always-on;
+				regulator-ramp-delay = <6250>;
+			};
+
+			sw2_reg: sw2 {
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sw3a_reg: sw3a {
+				regulator-min-microvolt = <400000>;
+				regulator-max-microvolt = <1975000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sw3b_reg: sw3b {
+				regulator-min-microvolt = <400000>;
+				regulator-max-microvolt = <1975000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			swbst_reg: swbst {
+				regulator-min-microvolt = <5000000>;
+				regulator-max-microvolt = <5150000>;
+			};
+
+			snvs_reg: vsnvs {
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			vref_reg: vrefddr {
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			vgen1_reg: vgen1 {
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1550000>;
+				regulator-always-on;
+			};
+
+			vgen2_reg: vgen2 {
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1550000>;
+			};
+
+			vgen3_reg: vgen3 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			vgen4_reg: vgen4 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			vgen5_reg: vgen5 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			vgen6_reg: vgen6 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+&qspi2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_qspi2>;
+	status = "okay";
+
+	flash0: n25q256a@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "micron,n25q256a", "jedec,spi-nor";
+		spi-max-frequency = <29000000>;
+		reg = <0>;
+	};
+
+	flash1: n25q256a@1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "micron,n25q256a", "jedec,spi-nor";
+		spi-max-frequency = <29000000>;
+		reg = <1>;
+	};
+};
+
+&reg_arm {
+	vin-supply = <&sw1a_reg>;
+};
+
+&reg_soc {
+	vin-supply = <&sw1a_reg>;
+};
diff --git a/arch/arm/dts/imx6sx-sdb.dtsi b/arch/arm/dts/imx6sx-sdb.dtsi
new file mode 100644
index 0000000..da81552
--- /dev/null
+++ b/arch/arm/dts/imx6sx-sdb.dtsi
@@ -0,0 +1,612 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "imx6sx.dtsi"
+
+/ {
+	model = "Freescale i.MX6 SoloX SDB Board";
+	compatible = "fsl,imx6sx-sdb", "fsl,imx6sx";
+
+	chosen {
+		stdout-path = &uart1;
+	};
+
+	memory {
+		reg = <0x80000000 0x40000000>;
+	};
+
+	backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm3 0 5000000>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <6>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_keys>;
+
+		volume-up {
+			label = "Volume Up";
+			gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_VOLUMEUP>;
+		};
+
+		volume-down {
+			label = "Volume Down";
+			gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_VOLUMEDOWN>;
+		};
+	};
+
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		vcc_sd3: regulator@0 {
+			compatible = "regulator-fixed";
+			reg = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_vcc_sd3>;
+			regulator-name = "VCC_SD3";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+			gpio = <&gpio2 11 GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+		};
+
+		reg_usb_otg1_vbus: regulator@1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_usb_otg1>;
+			regulator-name = "usb_otg1_vbus";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+		};
+
+		reg_usb_otg2_vbus: regulator@2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_usb_otg2>;
+			regulator-name = "usb_otg2_vbus";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+		};
+
+		reg_psu_5v: regulator@3 {
+			compatible = "regulator-fixed";
+			reg = <3>;
+			regulator-name = "PSU-5V0";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+		};
+
+		reg_lcd_3v3: regulator@4 {
+			compatible = "regulator-fixed";
+			reg = <4>;
+			regulator-name = "lcd-3v3";
+			gpio = <&gpio3 27 0>;
+			enable-active-high;
+		};
+
+		reg_peri_3v3: regulator@5 {
+			compatible = "regulator-fixed";
+			reg = <5>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_peri_3v3>;
+			regulator-name = "peri_3v3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			gpio = <&gpio4 16 GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+			regulator-always-on;
+		};
+
+		reg_enet_3v3: regulator@6 {
+			compatible = "regulator-fixed";
+			reg = <6>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_enet_3v3>;
+			regulator-name = "enet_3v3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	sound {
+		compatible = "fsl,imx6sx-sdb-wm8962", "fsl,imx-audio-wm8962";
+		model = "wm8962-audio";
+		ssi-controller = <&ssi2>;
+		audio-codec = <&codec>;
+		audio-routing =
+			"Headphone Jack", "HPOUTL",
+			"Headphone Jack", "HPOUTR",
+			"Ext Spk", "SPKOUTL",
+			"Ext Spk", "SPKOUTR",
+			"AMIC", "MICBIAS",
+			"IN3R", "AMIC";
+		mux-int-port = <2>;
+		mux-ext-port = <6>;
+	};
+};
+
+&audmux {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_audmux>;
+	status = "okay";
+};
+
+&fec1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet1>;
+	phy-supply = <&reg_enet_3v3>;
+	phy-mode = "rgmii";
+	phy-handle = <&ethphy1>;
+	status = "okay";
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy1: ethernet-phy@1 {
+			reg = <1>;
+		};
+
+		ethphy2: ethernet-phy@2 {
+			reg = <2>;
+		};
+	};
+};
+
+&fec2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet2>;
+	phy-mode = "rgmii";
+	phy-handle = <&ethphy2>;
+	status = "okay";
+};
+
+&i2c3 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	status = "okay";
+};
+
+&i2c4 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c4>;
+	status = "okay";
+
+	codec: wm8962@1a {
+		compatible = "wlf,wm8962";
+		reg = <0x1a>;
+		clocks = <&clks IMX6SX_CLK_AUDIO>;
+		DCVDD-supply = <&vgen4_reg>;
+		DBVDD-supply = <&vgen4_reg>;
+		AVDD-supply = <&vgen4_reg>;
+		CPVDD-supply = <&vgen4_reg>;
+		MICVDD-supply = <&vgen3_reg>;
+		PLLVDD-supply = <&vgen4_reg>;
+		SPKVDD1-supply = <&reg_psu_5v>;
+		SPKVDD2-supply = <&reg_psu_5v>;
+	};
+};
+
+&lcdif1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_lcd>;
+	lcd-supply = <&reg_lcd_3v3>;
+	display = <&display0>;
+	status = "okay";
+
+	display0: display0 {
+		bits-per-pixel = <16>;
+		bus-width = <24>;
+
+		display-timings {
+			native-mode = <&timing0>;
+			timing0: timing0 {
+				clock-frequency = <33500000>;
+				hactive = <800>;
+				vactive = <480>;
+				hback-porch = <89>;
+				hfront-porch = <164>;
+				vback-porch = <23>;
+				vfront-porch = <10>;
+				hsync-len = <10>;
+				vsync-len = <10>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <1>;
+				pixelclk-active = <0>;
+			};
+		};
+	};
+};
+
+&pwm3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm3>;
+	status = "okay";
+};
+
+&snvs_poweroff {
+	status = "okay";
+};
+
+&sai1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sai1>;
+	status = "disabled";
+};
+
+&ssi2 {
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1>;
+	status = "okay";
+};
+
+&uart5 { /* for bluetooth */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart5>;
+	uart-has-rtscts;
+	status = "okay";
+};
+
+&usbotg1 {
+	vbus-supply = <&reg_usb_otg1_vbus>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usb_otg1_id>;
+	status = "okay";
+};
+
+&usbotg2 {
+	vbus-supply = <&reg_usb_otg2_vbus>;
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbphy1 {
+	fsl,tx-d-cal = <106>;
+};
+
+&usbphy2 {
+	fsl,tx-d-cal = <106>;
+};
+
+&usdhc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc2>;
+	non-removable;
+	no-1-8-v;
+	keep-power-in-suspend;
+	wakeup-source;
+	status = "okay";
+};
+
+&usdhc3 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc3>;
+	pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+	bus-width = <8>;
+	cd-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+	wp-gpios = <&gpio2 15 GPIO_ACTIVE_HIGH>;
+	keep-power-in-suspend;
+	wakeup-source;
+	vmmc-supply = <&vcc_sd3>;
+	status = "okay";
+};
+
+&usdhc4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc4>;
+	cd-gpios = <&gpio6 21 GPIO_ACTIVE_LOW>;
+	wp-gpios = <&gpio6 20 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&wdog1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_wdog>;
+	fsl,ext-reset-output;
+};
+
+&iomuxc {
+	imx6x-sdb {
+		pinctrl_audmux: audmuxgrp {
+			fsl,pins = <
+				MX6SX_PAD_CSI_DATA00__AUDMUX_AUD6_TXC	0x130b0
+				MX6SX_PAD_CSI_DATA01__AUDMUX_AUD6_TXFS	0x130b0
+				MX6SX_PAD_CSI_HSYNC__AUDMUX_AUD6_TXD	0x120b0
+				MX6SX_PAD_CSI_VSYNC__AUDMUX_AUD6_RXD	0x130b0
+				MX6SX_PAD_CSI_PIXCLK__AUDMUX_MCLK	0x130b0
+			>;
+		};
+
+		pinctrl_enet1: enet1grp {
+			fsl,pins = <
+				MX6SX_PAD_ENET1_MDIO__ENET1_MDIO	0xa0b1
+				MX6SX_PAD_ENET1_MDC__ENET1_MDC		0xa0b1
+				MX6SX_PAD_RGMII1_TXC__ENET1_RGMII_TXC	0xa0b1
+				MX6SX_PAD_RGMII1_TD0__ENET1_TX_DATA_0	0xa0b1
+				MX6SX_PAD_RGMII1_TD1__ENET1_TX_DATA_1	0xa0b1
+				MX6SX_PAD_RGMII1_TD2__ENET1_TX_DATA_2	0xa0b1
+				MX6SX_PAD_RGMII1_TD3__ENET1_TX_DATA_3	0xa0b1
+				MX6SX_PAD_RGMII1_TX_CTL__ENET1_TX_EN	0xa0b1
+				MX6SX_PAD_RGMII1_RXC__ENET1_RX_CLK	0x3081
+				MX6SX_PAD_RGMII1_RD0__ENET1_RX_DATA_0	0x3081
+				MX6SX_PAD_RGMII1_RD1__ENET1_RX_DATA_1	0x3081
+				MX6SX_PAD_RGMII1_RD2__ENET1_RX_DATA_2	0x3081
+				MX6SX_PAD_RGMII1_RD3__ENET1_RX_DATA_3	0x3081
+				MX6SX_PAD_RGMII1_RX_CTL__ENET1_RX_EN	0x3081
+				MX6SX_PAD_ENET2_RX_CLK__ENET2_REF_CLK_25M	0x91
+			>;
+		};
+
+		pinctrl_enet_3v3: enet3v3grp {
+			fsl,pins = <
+				MX6SX_PAD_ENET2_COL__GPIO2_IO_6		0x80000000
+			>;
+		};
+
+		pinctrl_enet2: enet2grp {
+			fsl,pins = <
+				MX6SX_PAD_RGMII2_TXC__ENET2_RGMII_TXC	0xa0b9
+				MX6SX_PAD_RGMII2_TD0__ENET2_TX_DATA_0	0xa0b1
+				MX6SX_PAD_RGMII2_TD1__ENET2_TX_DATA_1	0xa0b1
+				MX6SX_PAD_RGMII2_TD2__ENET2_TX_DATA_2	0xa0b1
+				MX6SX_PAD_RGMII2_TD3__ENET2_TX_DATA_3	0xa0b1
+				MX6SX_PAD_RGMII2_TX_CTL__ENET2_TX_EN	0xa0b1
+				MX6SX_PAD_RGMII2_RXC__ENET2_RX_CLK	0x3081
+				MX6SX_PAD_RGMII2_RD0__ENET2_RX_DATA_0	0x3081
+				MX6SX_PAD_RGMII2_RD1__ENET2_RX_DATA_1	0x3081
+				MX6SX_PAD_RGMII2_RD2__ENET2_RX_DATA_2	0x3081
+				MX6SX_PAD_RGMII2_RD3__ENET2_RX_DATA_3	0x3081
+				MX6SX_PAD_RGMII2_RX_CTL__ENET2_RX_EN	0x3081
+			>;
+		};
+
+		pinctrl_gpio_keys: gpio_keysgrp {
+			fsl,pins = <
+				MX6SX_PAD_CSI_DATA04__GPIO1_IO_18 0x17059
+				MX6SX_PAD_CSI_DATA05__GPIO1_IO_19 0x17059
+			>;
+		};
+
+		pinctrl_i2c1: i2c1grp {
+			fsl,pins = <
+				MX6SX_PAD_GPIO1_IO01__I2C1_SDA		0x4001b8b1
+				MX6SX_PAD_GPIO1_IO00__I2C1_SCL		0x4001b8b1
+			>;
+		};
+
+		pinctrl_i2c3: i2c3grp {
+			fsl,pins = <
+				MX6SX_PAD_KEY_ROW4__I2C3_SDA		0x4001b8b1
+				MX6SX_PAD_KEY_COL4__I2C3_SCL		0x4001b8b1
+			>;
+		};
+
+		pinctrl_i2c4: i2c4grp {
+			fsl,pins = <
+				MX6SX_PAD_CSI_DATA07__I2C4_SDA		0x4001b8b1
+				MX6SX_PAD_CSI_DATA06__I2C4_SCL		0x4001b8b1
+			>;
+		};
+
+		pinctrl_lcd: lcdgrp {
+			fsl,pins = <
+				MX6SX_PAD_LCD1_DATA00__LCDIF1_DATA_0 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA01__LCDIF1_DATA_1 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA02__LCDIF1_DATA_2 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA03__LCDIF1_DATA_3 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA04__LCDIF1_DATA_4 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA05__LCDIF1_DATA_5 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA06__LCDIF1_DATA_6 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA07__LCDIF1_DATA_7 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA08__LCDIF1_DATA_8 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA09__LCDIF1_DATA_9 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA10__LCDIF1_DATA_10 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA11__LCDIF1_DATA_11 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA12__LCDIF1_DATA_12 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA13__LCDIF1_DATA_13 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA14__LCDIF1_DATA_14 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA15__LCDIF1_DATA_15 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA16__LCDIF1_DATA_16 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA17__LCDIF1_DATA_17 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA18__LCDIF1_DATA_18 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA19__LCDIF1_DATA_19 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA20__LCDIF1_DATA_20 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA21__LCDIF1_DATA_21 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA22__LCDIF1_DATA_22 0x4001b0b0
+				MX6SX_PAD_LCD1_DATA23__LCDIF1_DATA_23 0x4001b0b0
+				MX6SX_PAD_LCD1_CLK__LCDIF1_CLK	0x4001b0b0
+				MX6SX_PAD_LCD1_ENABLE__LCDIF1_ENABLE 0x4001b0b0
+				MX6SX_PAD_LCD1_VSYNC__LCDIF1_VSYNC 0x4001b0b0
+				MX6SX_PAD_LCD1_HSYNC__LCDIF1_HSYNC 0x4001b0b0
+				MX6SX_PAD_LCD1_RESET__GPIO3_IO_27 0x4001b0b0
+			>;
+		};
+
+		pinctrl_peri_3v3: peri3v3grp {
+			fsl,pins = <
+				MX6SX_PAD_QSPI1A_DATA0__GPIO4_IO_16	0x80000000
+			>;
+		};
+
+		pinctrl_pwm3: pwm3grp-1 {
+			fsl,pins = <
+				MX6SX_PAD_SD1_DATA2__PWM3_OUT 0x110b0
+			>;
+		};
+
+		pinctrl_qspi2: qspi2grp {
+			fsl,pins = <
+				MX6SX_PAD_NAND_WP_B__QSPI2_A_DATA_0     0x70f1
+				MX6SX_PAD_NAND_READY_B__QSPI2_A_DATA_1  0x70f1
+				MX6SX_PAD_NAND_CE0_B__QSPI2_A_DATA_2    0x70f1
+				MX6SX_PAD_NAND_CE1_B__QSPI2_A_DATA_3    0x70f1
+				MX6SX_PAD_NAND_CLE__QSPI2_A_SCLK        0x70f1
+				MX6SX_PAD_NAND_ALE__QSPI2_A_SS0_B       0x70f1
+				MX6SX_PAD_NAND_DATA01__QSPI2_B_DATA_0   0x70f1
+				MX6SX_PAD_NAND_DATA00__QSPI2_B_DATA_1   0x70f1
+				MX6SX_PAD_NAND_WE_B__QSPI2_B_DATA_2     0x70f1
+				MX6SX_PAD_NAND_RE_B__QSPI2_B_DATA_3     0x70f1
+				MX6SX_PAD_NAND_DATA02__QSPI2_B_SCLK     0x70f1
+				MX6SX_PAD_NAND_DATA03__QSPI2_B_SS0_B    0x70f1
+			>;
+		};
+
+		pinctrl_vcc_sd3: vccsd3grp {
+			fsl,pins = <
+				MX6SX_PAD_KEY_COL1__GPIO2_IO_11		0x17059
+			>;
+		};
+
+		pinctrl_sai1: sai1grp {
+			fsl,pins = <
+				MX6SX_PAD_CSI_DATA00__SAI1_TX_BCLK	0x130b0
+				MX6SX_PAD_CSI_DATA01__SAI1_TX_SYNC	0x130b0
+				MX6SX_PAD_CSI_HSYNC__SAI1_TX_DATA_0	0x120b0
+				MX6SX_PAD_CSI_VSYNC__SAI1_RX_DATA_0	0x130b0
+				MX6SX_PAD_CSI_PIXCLK__AUDMUX_MCLK	0x130b0
+			>;
+		};
+
+		pinctrl_uart1: uart1grp {
+			fsl,pins = <
+				MX6SX_PAD_GPIO1_IO04__UART1_TX		0x1b0b1
+				MX6SX_PAD_GPIO1_IO05__UART1_RX		0x1b0b1
+			>;
+		};
+
+		pinctrl_uart5: uart5grp {
+			fsl,pins = <
+				MX6SX_PAD_KEY_ROW3__UART5_RX		0x1b0b1
+				MX6SX_PAD_KEY_COL3__UART5_TX		0x1b0b1
+				MX6SX_PAD_KEY_ROW2__UART5_CTS_B		0x1b0b1
+				MX6SX_PAD_KEY_COL2__UART5_RTS_B		0x1b0b1
+			>;
+		};
+
+		pinctrl_usb_otg1: usbotg1grp {
+			fsl,pins = <
+				MX6SX_PAD_GPIO1_IO09__GPIO1_IO_9	0x10b0
+			>;
+		};
+
+		pinctrl_usb_otg1_id: usbotg1idgrp {
+			fsl,pins = <
+				MX6SX_PAD_GPIO1_IO10__ANATOP_OTG1_ID	0x17059
+			>;
+		};
+
+		pinctrl_usb_otg2: usbot2ggrp {
+			fsl,pins = <
+				MX6SX_PAD_GPIO1_IO12__GPIO1_IO_12	0x10b0
+			>;
+		};
+
+		pinctrl_usdhc2: usdhc2grp {
+			fsl,pins = <
+				MX6SX_PAD_SD2_CMD__USDHC2_CMD		0x17059
+				MX6SX_PAD_SD2_CLK__USDHC2_CLK		0x10059
+				MX6SX_PAD_SD2_DATA0__USDHC2_DATA0	0x17059
+				MX6SX_PAD_SD2_DATA1__USDHC2_DATA1	0x17059
+				MX6SX_PAD_SD2_DATA2__USDHC2_DATA2	0x17059
+				MX6SX_PAD_SD2_DATA3__USDHC2_DATA3	0x17059
+			>;
+		};
+
+		pinctrl_usdhc3: usdhc3grp {
+			fsl,pins = <
+				MX6SX_PAD_SD3_CMD__USDHC3_CMD		0x17059
+				MX6SX_PAD_SD3_CLK__USDHC3_CLK		0x10059
+				MX6SX_PAD_SD3_DATA0__USDHC3_DATA0	0x17059
+				MX6SX_PAD_SD3_DATA1__USDHC3_DATA1	0x17059
+				MX6SX_PAD_SD3_DATA2__USDHC3_DATA2	0x17059
+				MX6SX_PAD_SD3_DATA3__USDHC3_DATA3	0x17059
+				MX6SX_PAD_SD3_DATA4__USDHC3_DATA4	0x17059
+				MX6SX_PAD_SD3_DATA5__USDHC3_DATA5	0x17059
+				MX6SX_PAD_SD3_DATA6__USDHC3_DATA6	0x17059
+				MX6SX_PAD_SD3_DATA7__USDHC3_DATA7	0x17059
+				MX6SX_PAD_KEY_COL0__GPIO2_IO_10		0x17059 /* CD */
+				MX6SX_PAD_KEY_ROW0__GPIO2_IO_15		0x17059 /* WP */
+			>;
+		};
+
+		pinctrl_usdhc3_100mhz: usdhc3grp-100mhz {
+			fsl,pins = <
+				MX6SX_PAD_SD3_CMD__USDHC3_CMD		0x170b9
+				MX6SX_PAD_SD3_CLK__USDHC3_CLK		0x100b9
+				MX6SX_PAD_SD3_DATA0__USDHC3_DATA0	0x170b9
+				MX6SX_PAD_SD3_DATA1__USDHC3_DATA1	0x170b9
+				MX6SX_PAD_SD3_DATA2__USDHC3_DATA2	0x170b9
+				MX6SX_PAD_SD3_DATA3__USDHC3_DATA3	0x170b9
+				MX6SX_PAD_SD3_DATA4__USDHC3_DATA4	0x170b9
+				MX6SX_PAD_SD3_DATA5__USDHC3_DATA5	0x170b9
+				MX6SX_PAD_SD3_DATA6__USDHC3_DATA6	0x170b9
+				MX6SX_PAD_SD3_DATA7__USDHC3_DATA7	0x170b9
+			>;
+		};
+
+		pinctrl_usdhc3_200mhz: usdhc3grp-200mhz {
+			fsl,pins = <
+				MX6SX_PAD_SD3_CMD__USDHC3_CMD		0x170f9
+				MX6SX_PAD_SD3_CLK__USDHC3_CLK		0x100f9
+				MX6SX_PAD_SD3_DATA0__USDHC3_DATA0	0x170f9
+				MX6SX_PAD_SD3_DATA1__USDHC3_DATA1	0x170f9
+				MX6SX_PAD_SD3_DATA2__USDHC3_DATA2	0x170f9
+				MX6SX_PAD_SD3_DATA3__USDHC3_DATA3	0x170f9
+				MX6SX_PAD_SD3_DATA4__USDHC3_DATA4	0x170f9
+				MX6SX_PAD_SD3_DATA5__USDHC3_DATA5	0x170f9
+				MX6SX_PAD_SD3_DATA6__USDHC3_DATA6	0x170f9
+				MX6SX_PAD_SD3_DATA7__USDHC3_DATA7	0x170f9
+			>;
+		};
+
+		pinctrl_usdhc4: usdhc4grp {
+			fsl,pins = <
+				MX6SX_PAD_SD4_CMD__USDHC4_CMD		0x17059
+				MX6SX_PAD_SD4_CLK__USDHC4_CLK		0x10059
+				MX6SX_PAD_SD4_DATA0__USDHC4_DATA0	0x17059
+				MX6SX_PAD_SD4_DATA1__USDHC4_DATA1	0x17059
+				MX6SX_PAD_SD4_DATA2__USDHC4_DATA2	0x17059
+				MX6SX_PAD_SD4_DATA3__USDHC4_DATA3	0x17059
+				MX6SX_PAD_SD4_DATA7__GPIO6_IO_21	0x17059 /* CD */
+				MX6SX_PAD_SD4_DATA6__GPIO6_IO_20	0x17059 /* WP */
+			>;
+		};
+
+		pinctrl_wdog: wdoggrp {
+			fsl,pins = <
+				MX6SX_PAD_GPIO1_IO13__WDOG1_WDOG_ANY 0x30b0
+			>;
+		};
+	};
+};
diff --git a/arch/arm/dts/imx6ull-14x14-evk.dts b/arch/arm/dts/imx6ull-14x14-evk.dts
index 375bd4e..2a941bf 100644
--- a/arch/arm/dts/imx6ull-14x14-evk.dts
+++ b/arch/arm/dts/imx6ull-14x14-evk.dts
@@ -67,7 +67,7 @@
 		};
 	};
 
-	spi4 {
+	spi5 {
 		compatible = "spi-gpio";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_spi4>;
@@ -455,7 +455,8 @@
 	flash0: n25q256a@0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "micron,n25q256a";
+		/* compatible = "micron,n25q256a"; */
+		compatible = "spi-flash";
 		spi-max-frequency = <29000000>;
 		spi-nor,ddr-quad-read-dummy = <6>;
 		reg = <0>;
diff --git a/arch/arm/dts/imx6ull.dtsi b/arch/arm/dts/imx6ull.dtsi
index 65950e8..ea882a7 100644
--- a/arch/arm/dts/imx6ull.dtsi
+++ b/arch/arm/dts/imx6ull.dtsi
@@ -38,10 +38,11 @@
 		serial5 = &uart6;
 		serial6 = &uart7;
 		serial7 = &uart8;
-		spi0 = &ecspi1;
-		spi1 = &ecspi2;
-		spi2 = &ecspi3;
-		spi3 = &ecspi4;
+		spi0 = &qspi;
+		spi1 = &ecspi1;
+		spi2 = &ecspi2;
+		spi3 = &ecspi3;
+		spi4 = &ecspi4;
 		usbphy0 = &usbphy1;
 		usbphy1 = &usbphy2;
 	};
diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h
index e0ff459..a0cb19d 100644
--- a/arch/arm/include/asm/mach-imx/hab.h
+++ b/arch/arm/include/asm/mach-imx/hab.h
@@ -10,6 +10,34 @@
 
 #include <linux/types.h>
 
+/*
+ * IVT header definitions
+ * Security Reference Manual for i.MX 7Dual and 7Solo Applications Processors,
+ * Rev. 0, 03/2017
+ * Section : 6.7.1.1
+ */
+#define IVT_HEADER_MAGIC	0xD1
+#define IVT_TOTAL_LENGTH	0x20
+#define IVT_HEADER_V1		0x40
+#define IVT_HEADER_V2		0x41
+
+struct ivt_header {
+	uint8_t		magic;
+	uint16_t	length;
+	uint8_t		version;
+} __attribute__((packed));
+
+struct ivt {
+	struct ivt_header hdr;	/* IVT header above */
+	uint32_t entry;		/* Absolute address of first instruction */
+	uint32_t reserved1;	/* Reserved should be zero */
+	uint32_t dcd;		/* Absolute address of the image DCD */
+	uint32_t boot;		/* Absolute address of the boot data */
+	uint32_t self;		/* Absolute address of the IVT */
+	uint32_t csf;		/* Absolute address of the CSF */
+	uint32_t reserved2;	/* Reserved should be zero */
+};
+
 /* -------- start of HAB API updates ------------*/
 /* The following are taken from HAB4 SIS */
 
@@ -85,6 +113,12 @@
 	HAB_CTX_MAX
 };
 
+enum hab_target {
+	HAB_TGT_MEMORY		= 0x0f,
+	HAB_TGT_PERIPHERAL	= 0xf0,
+	HAB_TGT_ANY		= 0x55,
+};
+
 struct imx_sec_config_fuse_t {
 	int bank;
 	int word;
@@ -104,6 +138,9 @@
 typedef enum hab_status hab_rvt_exit_t(void);
 typedef void *hab_rvt_authenticate_image_t(uint8_t, ptrdiff_t,
 		void **, size_t *, hab_loader_callback_f_t);
+typedef enum hab_status hab_rvt_check_target_t(enum hab_target, const void *,
+					       size_t);
+typedef void hab_rvt_failsafe_t(void);
 typedef void hapi_clock_init_t(void);
 
 #define HAB_ENG_ANY		0x00   /* Select first compatible engine */
@@ -130,9 +167,11 @@
 
 #define HAB_RVT_ENTRY			(*(uint32_t *)(HAB_RVT_BASE + 0x04))
 #define HAB_RVT_EXIT			(*(uint32_t *)(HAB_RVT_BASE + 0x08))
+#define HAB_RVT_CHECK_TARGET		(*(uint32_t *)(HAB_RVT_BASE + 0x0C))
 #define HAB_RVT_AUTHENTICATE_IMAGE	(*(uint32_t *)(HAB_RVT_BASE + 0x10))
 #define HAB_RVT_REPORT_EVENT		(*(uint32_t *)(HAB_RVT_BASE + 0x20))
 #define HAB_RVT_REPORT_STATUS		(*(uint32_t *)(HAB_RVT_BASE + 0x24))
+#define HAB_RVT_FAILSAFE		(*(uint32_t *)(HAB_RVT_BASE + 0x28))
 
 #define HAB_RVT_REPORT_EVENT_NEW               (*(uint32_t *)0x000000B8)
 #define HAB_RVT_REPORT_STATUS_NEW              (*(uint32_t *)0x000000BC)
@@ -143,8 +182,13 @@
 #define HAB_CID_ROM 0 /**< ROM Caller ID */
 #define HAB_CID_UBOOT 1 /**< UBOOT Caller ID*/
 
+#define IVT_SIZE			0x20
+#define CSF_PAD_SIZE			0x2000
+
 /* ----------- end of HAB API updates ------------*/
 
-uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size);
+int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
+			       uint32_t ivt_offset);
+bool imx_hab_is_enabled(void);
 
 #endif
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index d7966cf..cf39d08 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -28,7 +28,9 @@
 obj-$(CONFIG_SATA) += sata.o
 obj-$(CONFIG_IMX_VIDEO_SKIP) += video.o
 obj-$(CONFIG_IMX_RDC) += rdc-sema.o
+ifneq ($(CONFIG_SPL_BUILD),y)
 obj-$(CONFIG_IMX_BOOTAUX) += imx_bootaux.o
+endif
 obj-$(CONFIG_SECURE_BOOT)    += hab.o
 obj-$(CONFIG_SYSCOUNTER_TIMER) += syscounter.o
 endif
diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c
index 02c7ae4..5f19777 100644
--- a/arch/arm/mach-imx/hab.c
+++ b/arch/arm/mach-imx/hab.c
@@ -70,9 +70,40 @@
 	((hab_rvt_exit_t *)HAB_RVT_EXIT)			\
 )
 
-#define IVT_SIZE		0x20
+static inline void hab_rvt_failsafe_new(void)
+{
+}
+
+#define hab_rvt_failsafe_p				\
+(							\
+	(is_mx6dqp()) ?					\
+	((hab_rvt_failsafe_t *)hab_rvt_failsafe_new) :	\
+	(is_mx6dq() && (soc_rev() >= CHIP_REV_1_5)) ?	\
+	((hab_rvt_failsafe_t *)hab_rvt_failsafe_new) :	\
+	(is_mx6sdl() && (soc_rev() >= CHIP_REV_1_2)) ?	\
+	((hab_rvt_failsafe_t *)hab_rvt_failsafe_new) :	\
+	((hab_rvt_failsafe_t *)HAB_RVT_FAILSAFE)	\
+)
+
+static inline enum hab_status hab_rvt_check_target_new(enum hab_target target,
+						       const void *start,
+						       size_t bytes)
+{
+	return HAB_SUCCESS;
+}
+
+#define hab_rvt_check_target_p					\
+(								\
+	(is_mx6dqp()) ?						\
+	((hab_rvt_check_target_t *)hab_rvt_check_target_new) :	\
+	(is_mx6dq() && (soc_rev() >= CHIP_REV_1_5)) ?		\
+	((hab_rvt_check_target_t *)hab_rvt_check_target_new) :	\
+	(is_mx6sdl() &&	(soc_rev() >= CHIP_REV_1_2)) ?		\
+	((hab_rvt_check_target_t *)hab_rvt_check_target_new) :	\
+	((hab_rvt_check_target_t *)HAB_RVT_CHECK_TARGET)	\
+)
+
 #define ALIGN_SIZE		0x1000
-#define CSF_PAD_SIZE		0x2000
 #define MX6DQ_PU_IROM_MMU_EN_VAR	0x009024a8
 #define MX6DLS_PU_IROM_MMU_EN_VAR	0x00901dd0
 #define MX6SL_PU_IROM_MMU_EN_VAR	0x00900a18
@@ -80,38 +111,30 @@
 	(is_soc_type(MXC_SOC_MX7ULP) ? 0x80000000 :	\
 	 (is_soc_type(MXC_SOC_MX7) ? 0x2000000 : 0x2))
 
+static int ivt_header_error(const char *err_str, struct ivt_header *ivt_hdr)
+{
+	printf("%s magic=0x%x length=0x%02x version=0x%x\n", err_str,
+	       ivt_hdr->magic, ivt_hdr->length, ivt_hdr->version);
+
+	return 1;
+}
+
+static int verify_ivt_header(struct ivt_header *ivt_hdr)
+{
+	int result = 0;
+
+	if (ivt_hdr->magic != IVT_HEADER_MAGIC)
+		result = ivt_header_error("bad magic", ivt_hdr);
+
-/*
- * +------------+  0x0 (DDR_UIMAGE_START) -
- * |   Header   |                          |
- * +------------+  0x40                    |
- * |            |                          |
- * |            |                          |
- * |            |                          |
- * |            |                          |
- * | Image Data |                          |
- * .            |                          |
- * .            |                           > Stuff to be authenticated ----+
- * .            |                          |                                |
- * |            |                          |                                |
- * |            |                          |                                |
- * +------------+                          |                                |
- * |            |                          |                                |
- * | Fill Data  |                          |                                |
- * |            |                          |                                |
- * +------------+ Align to ALIGN_SIZE      |                                |
- * |    IVT     |                          |                                |
- * +------------+ + IVT_SIZE              -                                 |
- * |            |                                                           |
- * |  CSF DATA  | <---------------------------------------------------------+
- * |            |
- * +------------+
- * |            |
- * | Fill Data  |
- * |            |
- * +------------+ + CSF_PAD_SIZE
- */
+	if (be16_to_cpu(ivt_hdr->length) != IVT_TOTAL_LENGTH)
+		result = ivt_header_error("bad length", ivt_hdr);
 
-static bool is_hab_enabled(void);
+	if (ivt_hdr->version != IVT_HEADER_V1 &&
+	    ivt_hdr->version != IVT_HEADER_V2)
+		result = ivt_header_error("bad version", ivt_hdr);
+
+	return result;
+}
 
 #if !defined(CONFIG_SPL_BUILD)
 
@@ -125,73 +148,81 @@
 	bool	 any_rec_flag;
 };
 
-char *rsn_str[] = {"RSN = HAB_RSN_ANY (0x00)\n",
-				   "RSN = HAB_ENG_FAIL (0x30)\n",
-				   "RSN = HAB_INV_ADDRESS (0x22)\n",
-				   "RSN = HAB_INV_ASSERTION (0x0C)\n",
-				   "RSN = HAB_INV_CALL (0x28)\n",
-				   "RSN = HAB_INV_CERTIFICATE (0x21)\n",
-				   "RSN = HAB_INV_COMMAND (0x06)\n",
-				   "RSN = HAB_INV_CSF (0x11)\n",
-				   "RSN = HAB_INV_DCD (0x27)\n",
-				   "RSN = HAB_INV_INDEX (0x0F)\n",
-				   "RSN = HAB_INV_IVT (0x05)\n",
-				   "RSN = HAB_INV_KEY (0x1D)\n",
-				   "RSN = HAB_INV_RETURN (0x1E)\n",
-				   "RSN = HAB_INV_SIGNATURE (0x18)\n",
-				   "RSN = HAB_INV_SIZE (0x17)\n",
-				   "RSN = HAB_MEM_FAIL (0x2E)\n",
-				   "RSN = HAB_OVR_COUNT (0x2B)\n",
-				   "RSN = HAB_OVR_STORAGE (0x2D)\n",
-				   "RSN = HAB_UNS_ALGORITHM (0x12)\n",
-				   "RSN = HAB_UNS_COMMAND (0x03)\n",
-				   "RSN = HAB_UNS_ENGINE (0x0A)\n",
-				   "RSN = HAB_UNS_ITEM (0x24)\n",
-				   "RSN = HAB_UNS_KEY (0x1B)\n",
-				   "RSN = HAB_UNS_PROTOCOL (0x14)\n",
-				   "RSN = HAB_UNS_STATE (0x09)\n",
-				   "RSN = INVALID\n",
-				   NULL};
+static char *rsn_str[] = {
+			  "RSN = HAB_RSN_ANY (0x00)\n",
+			  "RSN = HAB_ENG_FAIL (0x30)\n",
+			  "RSN = HAB_INV_ADDRESS (0x22)\n",
+			  "RSN = HAB_INV_ASSERTION (0x0C)\n",
+			  "RSN = HAB_INV_CALL (0x28)\n",
+			  "RSN = HAB_INV_CERTIFICATE (0x21)\n",
+			  "RSN = HAB_INV_COMMAND (0x06)\n",
+			  "RSN = HAB_INV_CSF (0x11)\n",
+			  "RSN = HAB_INV_DCD (0x27)\n",
+			  "RSN = HAB_INV_INDEX (0x0F)\n",
+			  "RSN = HAB_INV_IVT (0x05)\n",
+			  "RSN = HAB_INV_KEY (0x1D)\n",
+			  "RSN = HAB_INV_RETURN (0x1E)\n",
+			  "RSN = HAB_INV_SIGNATURE (0x18)\n",
+			  "RSN = HAB_INV_SIZE (0x17)\n",
+			  "RSN = HAB_MEM_FAIL (0x2E)\n",
+			  "RSN = HAB_OVR_COUNT (0x2B)\n",
+			  "RSN = HAB_OVR_STORAGE (0x2D)\n",
+			  "RSN = HAB_UNS_ALGORITHM (0x12)\n",
+			  "RSN = HAB_UNS_COMMAND (0x03)\n",
+			  "RSN = HAB_UNS_ENGINE (0x0A)\n",
+			  "RSN = HAB_UNS_ITEM (0x24)\n",
+			  "RSN = HAB_UNS_KEY (0x1B)\n",
+			  "RSN = HAB_UNS_PROTOCOL (0x14)\n",
+			  "RSN = HAB_UNS_STATE (0x09)\n",
+			  "RSN = INVALID\n",
+			  NULL
+};
 
-char *sts_str[] = {"STS = HAB_SUCCESS (0xF0)\n",
-				   "STS = HAB_FAILURE (0x33)\n",
-				   "STS = HAB_WARNING (0x69)\n",
-				   "STS = INVALID\n",
-				   NULL};
+static char *sts_str[] = {
+			  "STS = HAB_SUCCESS (0xF0)\n",
+			  "STS = HAB_FAILURE (0x33)\n",
+			  "STS = HAB_WARNING (0x69)\n",
+			  "STS = INVALID\n",
+			  NULL
+};
 
-char *eng_str[] = {"ENG = HAB_ENG_ANY (0x00)\n",
-				   "ENG = HAB_ENG_SCC (0x03)\n",
-				   "ENG = HAB_ENG_RTIC (0x05)\n",
-				   "ENG = HAB_ENG_SAHARA (0x06)\n",
-				   "ENG = HAB_ENG_CSU (0x0A)\n",
-				   "ENG = HAB_ENG_SRTC (0x0C)\n",
-				   "ENG = HAB_ENG_DCP (0x1B)\n",
-				   "ENG = HAB_ENG_CAAM (0x1D)\n",
-				   "ENG = HAB_ENG_SNVS (0x1E)\n",
-				   "ENG = HAB_ENG_OCOTP (0x21)\n",
-				   "ENG = HAB_ENG_DTCP (0x22)\n",
-				   "ENG = HAB_ENG_ROM (0x36)\n",
-				   "ENG = HAB_ENG_HDCP (0x24)\n",
-				   "ENG = HAB_ENG_RTL (0x77)\n",
-				   "ENG = HAB_ENG_SW (0xFF)\n",
-				   "ENG = INVALID\n",
-				   NULL};
+static char *eng_str[] = {
+			  "ENG = HAB_ENG_ANY (0x00)\n",
+			  "ENG = HAB_ENG_SCC (0x03)\n",
+			  "ENG = HAB_ENG_RTIC (0x05)\n",
+			  "ENG = HAB_ENG_SAHARA (0x06)\n",
+			  "ENG = HAB_ENG_CSU (0x0A)\n",
+			  "ENG = HAB_ENG_SRTC (0x0C)\n",
+			  "ENG = HAB_ENG_DCP (0x1B)\n",
+			  "ENG = HAB_ENG_CAAM (0x1D)\n",
+			  "ENG = HAB_ENG_SNVS (0x1E)\n",
+			  "ENG = HAB_ENG_OCOTP (0x21)\n",
+			  "ENG = HAB_ENG_DTCP (0x22)\n",
+			  "ENG = HAB_ENG_ROM (0x36)\n",
+			  "ENG = HAB_ENG_HDCP (0x24)\n",
+			  "ENG = HAB_ENG_RTL (0x77)\n",
+			  "ENG = HAB_ENG_SW (0xFF)\n",
+			  "ENG = INVALID\n",
+			  NULL
+};
 
-char *ctx_str[] = {"CTX = HAB_CTX_ANY(0x00)\n",
-				   "CTX = HAB_CTX_FAB (0xFF)\n",
-				   "CTX = HAB_CTX_ENTRY (0xE1)\n",
-				   "CTX = HAB_CTX_TARGET (0x33)\n",
-				   "CTX = HAB_CTX_AUTHENTICATE (0x0A)\n",
-				   "CTX = HAB_CTX_DCD (0xDD)\n",
-				   "CTX = HAB_CTX_CSF (0xCF)\n",
-				   "CTX = HAB_CTX_COMMAND (0xC0)\n",
-				   "CTX = HAB_CTX_AUT_DAT (0xDB)\n",
-				   "CTX = HAB_CTX_ASSERT (0xA0)\n",
-				   "CTX = HAB_CTX_EXIT (0xEE)\n",
-				   "CTX = INVALID\n",
-				   NULL};
+static char *ctx_str[] = {
+			  "CTX = HAB_CTX_ANY(0x00)\n",
+			  "CTX = HAB_CTX_FAB (0xFF)\n",
+			  "CTX = HAB_CTX_ENTRY (0xE1)\n",
+			  "CTX = HAB_CTX_TARGET (0x33)\n",
+			  "CTX = HAB_CTX_AUTHENTICATE (0x0A)\n",
+			  "CTX = HAB_CTX_DCD (0xDD)\n",
+			  "CTX = HAB_CTX_CSF (0xCF)\n",
+			  "CTX = HAB_CTX_COMMAND (0xC0)\n",
+			  "CTX = HAB_CTX_AUT_DAT (0xDB)\n",
+			  "CTX = HAB_CTX_ASSERT (0xA0)\n",
+			  "CTX = HAB_CTX_EXIT (0xEE)\n",
+			  "CTX = INVALID\n",
+			  NULL
+};
 
-uint8_t hab_statuses[5] = {
+static uint8_t hab_statuses[5] = {
 	HAB_STS_ANY,
 	HAB_FAILURE,
 	HAB_WARNING,
@@ -199,7 +230,7 @@
 	-1
 };
 
-uint8_t hab_reasons[26] = {
+static uint8_t hab_reasons[26] = {
 	HAB_RSN_ANY,
 	HAB_ENG_FAIL,
 	HAB_INV_ADDRESS,
@@ -228,7 +259,7 @@
 	-1
 };
 
-uint8_t hab_contexts[12] = {
+static uint8_t hab_contexts[12] = {
 	HAB_CTX_ANY,
 	HAB_CTX_FAB,
 	HAB_CTX_ENTRY,
@@ -243,7 +274,7 @@
 	-1
 };
 
-uint8_t hab_engines[16] = {
+static uint8_t hab_engines[16] = {
 	HAB_ENG_ANY,
 	HAB_ENG_SCC,
 	HAB_ENG_RTIC,
@@ -274,7 +305,7 @@
 	return -1;
 }
 
-void process_event_record(uint8_t *event_data, size_t bytes)
+static void process_event_record(uint8_t *event_data, size_t bytes)
 {
 	struct record *rec = (struct record *)event_data;
 
@@ -284,7 +315,7 @@
 	printf("%s", eng_str[get_idx(hab_engines, rec->contents[3])]);
 }
 
-void display_event(uint8_t *event_data, size_t bytes)
+static void display_event(uint8_t *event_data, size_t bytes)
 {
 	uint32_t i;
 
@@ -303,7 +334,7 @@
 	process_event_record(event_data, bytes);
 }
 
-int get_hab_status(void)
+static int get_hab_status(void)
 {
 	uint32_t index = 0; /* Loop index */
 	uint8_t event_data[128]; /* Event data buffer */
@@ -316,7 +347,7 @@
 	hab_rvt_report_event = hab_rvt_report_event_p;
 	hab_rvt_report_status = hab_rvt_report_status_p;
 
-	if (is_hab_enabled())
+	if (imx_hab_is_enabled())
 		puts("\nSecure boot enabled\n");
 	else
 		puts("\nSecure boot disabled\n");
@@ -348,7 +379,8 @@
 	return 0;
 }
 
-int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc,
+			 char * const argv[])
 {
 	if ((argc != 1)) {
 		cmd_usage(cmdtp);
@@ -361,22 +393,43 @@
 }
 
 static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc,
-				char * const argv[])
+				 char * const argv[])
 {
-	ulong	addr, ivt_offset;
+	ulong	addr, length, ivt_offset;
 	int	rcode = 0;
 
-	if (argc < 3)
+	if (argc < 4)
 		return CMD_RET_USAGE;
 
 	addr = simple_strtoul(argv[1], NULL, 16);
-	ivt_offset = simple_strtoul(argv[2], NULL, 16);
+	length = simple_strtoul(argv[2], NULL, 16);
+	ivt_offset = simple_strtoul(argv[3], NULL, 16);
 
-	rcode = authenticate_image(addr, ivt_offset);
+	rcode = imx_hab_authenticate_image(addr, length, ivt_offset);
+	if (rcode == 0)
+		rcode = CMD_RET_SUCCESS;
+	else
+		rcode = CMD_RET_FAILURE;
 
 	return rcode;
 }
 
+static int do_hab_failsafe(cmd_tbl_t *cmdtp, int flag, int argc,
+			   char * const argv[])
+{
+	hab_rvt_failsafe_t *hab_rvt_failsafe;
+
+	if (argc != 1) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	hab_rvt_failsafe = hab_rvt_failsafe_p;
+	hab_rvt_failsafe();
+
+	return 0;
+}
+
 U_BOOT_CMD(
 		hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
 		"display HAB status",
@@ -384,17 +437,23 @@
 	  );
 
 U_BOOT_CMD(
-		hab_auth_img, 3, 0, do_authenticate_image,
+		hab_auth_img, 4, 0, do_authenticate_image,
 		"authenticate image via HAB",
-		"addr ivt_offset\n"
+		"addr length ivt_offset\n"
 		"addr - image hex address\n"
+		"length - image hex length\n"
 		"ivt_offset - hex offset of IVT in the image"
 	  );
 
+U_BOOT_CMD(
+		hab_failsafe, CONFIG_SYS_MAXARGS, 1, do_hab_failsafe,
+		"run BootROM failsafe routine",
+		""
+	  );
 
 #endif /* !defined(CONFIG_SPL_BUILD) */
 
-static bool is_hab_enabled(void)
+bool imx_hab_is_enabled(void)
 {
 	struct imx_sec_config_fuse_t *fuse =
 		(struct imx_sec_config_fuse_t *)&imx_sec_config_fuse;
@@ -410,107 +469,133 @@
 	return (reg & IS_HAB_ENABLED_BIT) == IS_HAB_ENABLED_BIT;
 }
 
-uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size)
+int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
+			       uint32_t ivt_offset)
 {
 	uint32_t load_addr = 0;
 	size_t bytes;
-	ptrdiff_t ivt_offset = 0;
-	int result = 0;
+	uint32_t ivt_addr = 0;
+	int result = 1;
 	ulong start;
 	hab_rvt_authenticate_image_t *hab_rvt_authenticate_image;
 	hab_rvt_entry_t *hab_rvt_entry;
 	hab_rvt_exit_t *hab_rvt_exit;
+	hab_rvt_check_target_t *hab_rvt_check_target;
+	struct ivt *ivt;
+	struct ivt_header *ivt_hdr;
+	enum hab_status status;
 
 	hab_rvt_authenticate_image = hab_rvt_authenticate_image_p;
 	hab_rvt_entry = hab_rvt_entry_p;
 	hab_rvt_exit = hab_rvt_exit_p;
+	hab_rvt_check_target = hab_rvt_check_target_p;
 
-	if (is_hab_enabled()) {
-		printf("\nAuthenticate image from DDR location 0x%x...\n",
-		       ddr_start);
+	if (!imx_hab_is_enabled()) {
+		puts("hab fuse not enabled\n");
+		return 0;
+	}
 
-		hab_caam_clock_enable(1);
+	printf("\nAuthenticate image from DDR location 0x%x...\n",
+	       ddr_start);
 
-		if (hab_rvt_entry() == HAB_SUCCESS) {
-			/* If not already aligned, Align to ALIGN_SIZE */
-			ivt_offset = (image_size + ALIGN_SIZE - 1) &
-					~(ALIGN_SIZE - 1);
+	hab_caam_clock_enable(1);
 
-			start = ddr_start;
-			bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE;
+	/* Calculate IVT address header */
+	ivt_addr = ddr_start + ivt_offset;
+	ivt = (struct ivt *)ivt_addr;
+	ivt_hdr = &ivt->hdr;
+
+	/* Verify IVT header bugging out on error */
+	if (verify_ivt_header(ivt_hdr))
+		goto hab_caam_clock_disable;
+
+	/* Verify IVT body */
+	if (ivt->self != ivt_addr) {
+		printf("ivt->self 0x%08x pointer is 0x%08x\n",
+		       ivt->self, ivt_addr);
+		goto hab_caam_clock_disable;
+	}
+
+	start = ddr_start;
+	bytes = image_size;
+
+	if (hab_rvt_entry() != HAB_SUCCESS) {
+		puts("hab entry function fail\n");
+		goto hab_exit_failure_print_status;
+	}
+
+	status = hab_rvt_check_target(HAB_TGT_MEMORY, (void *)ddr_start, bytes);
+	if (status != HAB_SUCCESS) {
+		printf("HAB check target 0x%08x-0x%08x fail\n",
+		       ddr_start, ddr_start + bytes);
+		goto hab_exit_failure_print_status;
+	}
 #ifdef DEBUG
-			printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n",
-			       ivt_offset, ddr_start + ivt_offset);
-			puts("Dumping IVT\n");
-			print_buffer(ddr_start + ivt_offset,
-				     (void *)(ddr_start + ivt_offset),
-				     4, 0x8, 0);
+	printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", ivt_offset, ivt_addr);
+	printf("ivt entry = 0x%08x, dcd = 0x%08x, csf = 0x%08x\n", ivt->entry,
+	       ivt->dcd, ivt->csf);
+	puts("Dumping IVT\n");
+	print_buffer(ivt_addr, (void *)(ivt_addr), 4, 0x8, 0);
 
-			puts("Dumping CSF Header\n");
-			print_buffer(ddr_start + ivt_offset+IVT_SIZE,
-				     (void *)(ddr_start + ivt_offset+IVT_SIZE),
-				     4, 0x10, 0);
+	puts("Dumping CSF Header\n");
+	print_buffer(ivt->csf, (void *)(ivt->csf), 4, 0x10, 0);
 
 #if  !defined(CONFIG_SPL_BUILD)
-			get_hab_status();
+	get_hab_status();
 #endif
 
-			puts("\nCalling authenticate_image in ROM\n");
-			printf("\tivt_offset = 0x%x\n", ivt_offset);
-			printf("\tstart = 0x%08lx\n", start);
-			printf("\tbytes = 0x%x\n", bytes);
+	puts("\nCalling authenticate_image in ROM\n");
+	printf("\tivt_offset = 0x%x\n", ivt_offset);
+	printf("\tstart = 0x%08lx\n", start);
+	printf("\tbytes = 0x%x\n", bytes);
 #endif
+	/*
+	 * If the MMU is enabled, we have to notify the ROM
+	 * code, or it won't flush the caches when needed.
+	 * This is done, by setting the "pu_irom_mmu_enabled"
+	 * word to 1. You can find its address by looking in
+	 * the ROM map. This is critical for
+	 * authenticate_image(). If MMU is enabled, without
+	 * setting this bit, authentication will fail and may
+	 * crash.
+	 */
+	/* Check MMU enabled */
+	if (is_soc_type(MXC_SOC_MX6) && get_cr() & CR_M) {
+		if (is_mx6dq()) {
 			/*
-			 * If the MMU is enabled, we have to notify the ROM
-			 * code, or it won't flush the caches when needed.
-			 * This is done, by setting the "pu_irom_mmu_enabled"
-			 * word to 1. You can find its address by looking in
-			 * the ROM map. This is critical for
-			 * authenticate_image(). If MMU is enabled, without
-			 * setting this bit, authentication will fail and may
-			 * crash.
+			 * This won't work on Rev 1.0.0 of
+			 * i.MX6Q/D, since their ROM doesn't
+			 * do cache flushes. don't think any
+			 * exist, so we ignore them.
 			 */
-			/* Check MMU enabled */
-			if (is_soc_type(MXC_SOC_MX6) && get_cr() & CR_M) {
-				if (is_mx6dq()) {
-					/*
-					 * This won't work on Rev 1.0.0 of
-					 * i.MX6Q/D, since their ROM doesn't
-					 * do cache flushes. don't think any
-					 * exist, so we ignore them.
-					 */
-					if (!is_mx6dqp())
-						writel(1, MX6DQ_PU_IROM_MMU_EN_VAR);
-				} else if (is_mx6sdl()) {
-					writel(1, MX6DLS_PU_IROM_MMU_EN_VAR);
-				} else if (is_mx6sl()) {
-					writel(1, MX6SL_PU_IROM_MMU_EN_VAR);
-				}
-			}
-
-			load_addr = (uint32_t)hab_rvt_authenticate_image(
-					HAB_CID_UBOOT,
-					ivt_offset, (void **)&start,
-					(size_t *)&bytes, NULL);
-			if (hab_rvt_exit() != HAB_SUCCESS) {
-				puts("hab exit function fail\n");
-				load_addr = 0;
-			}
-		} else {
-			puts("hab entry function fail\n");
+			if (!is_mx6dqp())
+				writel(1, MX6DQ_PU_IROM_MMU_EN_VAR);
+		} else if (is_mx6sdl()) {
+			writel(1, MX6DLS_PU_IROM_MMU_EN_VAR);
+		} else if (is_mx6sl()) {
+			writel(1, MX6SL_PU_IROM_MMU_EN_VAR);
 		}
+	}
 
-		hab_caam_clock_enable(0);
+	load_addr = (uint32_t)hab_rvt_authenticate_image(
+			HAB_CID_UBOOT,
+			ivt_offset, (void **)&start,
+			(size_t *)&bytes, NULL);
+	if (hab_rvt_exit() != HAB_SUCCESS) {
+		puts("hab exit function fail\n");
+		load_addr = 0;
+	}
 
+hab_exit_failure_print_status:
 #if !defined(CONFIG_SPL_BUILD)
-		get_hab_status();
+	get_hab_status();
 #endif
-	} else {
-		puts("hab fuse not enabled\n");
-	}
+
+hab_caam_clock_disable:
+	hab_caam_clock_enable(0);
 
-	if ((!is_hab_enabled()) || (load_addr != 0))
-		result = 1;
+	if (load_addr != 0)
+		result = 0;
 
 	return result;
 }
diff --git a/arch/arm/mach-imx/imx_bootaux.c b/arch/arm/mach-imx/imx_bootaux.c
index 69026df..b62dfbf 100644
--- a/arch/arm/mach-imx/imx_bootaux.c
+++ b/arch/arm/mach-imx/imx_bootaux.c
@@ -6,27 +6,22 @@
 
 #include <common.h>
 #include <command.h>
+#include <linux/compiler.h>
 
 /* Allow for arch specific config before we boot */
-static int __arch_auxiliary_core_up(u32 core_id, u32 boot_private_data)
+int __weak arch_auxiliary_core_up(u32 core_id, u32 boot_private_data)
 {
 	/* please define platform specific arch_auxiliary_core_up() */
 	return CMD_RET_FAILURE;
 }
 
-int arch_auxiliary_core_up(u32 core_id, u32 boot_private_data)
-	__attribute__((weak, alias("__arch_auxiliary_core_up")));
-
 /* Allow for arch specific config before we boot */
-static int __arch_auxiliary_core_check_up(u32 core_id)
+int __weak arch_auxiliary_core_check_up(u32 core_id)
 {
 	/* please define platform specific arch_auxiliary_core_check_up() */
 	return 0;
 }
 
-int arch_auxiliary_core_check_up(u32 core_id)
-	__attribute__((weak, alias("__arch_auxiliary_core_check_up")));
-
 /*
  * To i.MX6SX and i.MX7D, the image supported by bootaux needs
  * the reset vector at the head for the image, with SP and PC
@@ -40,7 +35,7 @@
  * The TCMUL is mapped to (M4_BOOTROM_BASE_ADDR) at A core side for
  * accessing the M4 TCMUL.
  */
-int do_bootaux(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int do_bootaux(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	ulong addr;
 	int ret, up;
diff --git a/arch/arm/mach-imx/mx5/clock.c b/arch/arm/mach-imx/mx5/clock.c
index 610098c..284f6d4 100644
--- a/arch/arm/mach-imx/mx5/clock.c
+++ b/arch/arm/mach-imx/mx5/clock.c
@@ -911,10 +911,11 @@
 }
 #endif
 
+#ifndef CONFIG_SPL_BUILD
 /*
  * Dump some core clockes.
  */
-int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	u32 freq;
 
@@ -947,3 +948,4 @@
 	"display clocks",
 	""
 );
+#endif
diff --git a/arch/arm/mach-imx/mx6/Kconfig b/arch/arm/mach-imx/mx6/Kconfig
index 567a6a6..2f3e52d 100644
--- a/arch/arm/mach-imx/mx6/Kconfig
+++ b/arch/arm/mach-imx/mx6/Kconfig
@@ -130,6 +130,7 @@
 	bool "CM-FX6"
 	select SUPPORT_SPL
 	select MX6QDL
+	select BOARD_LATE_INIT
 	select DM
 	select DM_SERIAL
 	select DM_GPIO
@@ -377,6 +378,10 @@
 config TARGET_SECOMX6
 	bool "secomx6 boards"
 
+config TARGET_SKSIMX6
+	bool "sks-imx6"
+	select SUPPORT_SPL
+
 config TARGET_TBS2910
 	bool "TBS2910 Matrix ARM mini PC"
 
@@ -482,6 +487,7 @@
 source "board/liebherr/mccmon6/Kconfig"
 source "board/logicpd/imx6/Kconfig"
 source "board/seco/Kconfig"
+source "board/sks-kinkel/sksimx6/Kconfig"
 source "board/solidrun/mx6cuboxi/Kconfig"
 source "board/technexion/pico-imx6ul/Kconfig"
 source "board/tbs/tbs2910/Kconfig"
diff --git a/arch/arm/mach-imx/mx6/ddr.c b/arch/arm/mach-imx/mx6/ddr.c
index 52a9a25..39dbd2f 100644
--- a/arch/arm/mach-imx/mx6/ddr.c
+++ b/arch/arm/mach-imx/mx6/ddr.c
@@ -908,7 +908,7 @@
 #define MR(val, ba, cmd, cs1) \
 	((val << 16) | (1 << 15) | (cmd << 4) | (cs1 << 3) | ba)
 #define MMDC1(entry, value) do {					  \
-	if (!is_mx6sx() && !is_mx6ul() && !is_mx6sl())			  \
+	if (!is_mx6sx() && !is_mx6ul() && !is_mx6ull() && !is_mx6sl())	  \
 		mmdc1->entry = value;					  \
 	} while (0)
 
@@ -1215,7 +1215,7 @@
 	u16 mem_speed = ddr3_cfg->mem_speed;
 
 	mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
-	if (!is_mx6sx() && !is_mx6ul() && !is_mx6sl())
+	if (!is_mx6sx() && !is_mx6ul() && !is_mx6ull() && !is_mx6sl())
 		mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR;
 
 	/* Limit mem_speed for MX6D/MX6Q */
diff --git a/arch/arm/mach-imx/mx7/clock.c b/arch/arm/mach-imx/mx7/clock.c
index 8150faa..c11042d 100644
--- a/arch/arm/mach-imx/mx7/clock.c
+++ b/arch/arm/mach-imx/mx7/clock.c
@@ -1096,6 +1096,7 @@
 }
 #endif
 
+#ifndef CONFIG_SPL_BUILD
 /*
  * Dump some core clockes.
  */
@@ -1131,3 +1132,4 @@
 	"display clocks",
 	""
 );
+#endif
diff --git a/arch/arm/mach-imx/mx7ulp/clock.c b/arch/arm/mach-imx/mx7ulp/clock.c
index 77b282a..553d621 100644
--- a/arch/arm/mach-imx/mx7ulp/clock.c
+++ b/arch/arm/mach-imx/mx7ulp/clock.c
@@ -323,6 +323,7 @@
 }
 #endif
 
+#ifndef CONFIG_SPL_BUILD
 /*
  * Dump some core clockes.
  */
@@ -363,3 +364,4 @@
 	"display clocks",
 	""
 );
+#endif
diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c
index 723f51f..6c16872 100644
--- a/arch/arm/mach-imx/spl.c
+++ b/arch/arm/mach-imx/spl.c
@@ -106,10 +106,13 @@
 	switch (boot_device_spl) {
 	case SD1_BOOT:
 	case MMC1_BOOT:
-		return BOOT_DEVICE_MMC1;
 	case SD2_BOOT:
 	case MMC2_BOOT:
-		return BOOT_DEVICE_MMC2;
+	case SD3_BOOT:
+	case MMC3_BOOT:
+		return BOOT_DEVICE_MMC1;
+	case NAND_BOOT:
+		return BOOT_DEVICE_NAND;
 	case SPI_NOR_BOOT:
 		return BOOT_DEVICE_SPI;
 	default:
@@ -152,9 +155,41 @@
 
 #if defined(CONFIG_SECURE_BOOT)
 
+/*
+ * +------------+  0x0 (DDR_UIMAGE_START) -
+ * |   Header   |                          |
+ * +------------+  0x40                    |
+ * |            |                          |
+ * |            |                          |
+ * |            |                          |
+ * |            |                          |
+ * | Image Data |                          |
+ * .            |                          |
+ * .            |                           > Stuff to be authenticated ----+
+ * .            |                          |                                |
+ * |            |                          |                                |
+ * |            |                          |                                |
+ * +------------+                          |                                |
+ * |            |                          |                                |
+ * | Fill Data  |                          |                                |
+ * |            |                          |                                |
+ * +------------+ Align to ALIGN_SIZE      |                                |
+ * |    IVT     |                          |                                |
+ * +------------+ + IVT_SIZE              -                                 |
+ * |            |                                                           |
+ * |  CSF DATA  | <---------------------------------------------------------+
+ * |            |
+ * +------------+
+ * |            |
+ * | Fill Data  |
+ * |            |
+ * +------------+ + CSF_PAD_SIZE
+ */
+
 __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
 {
 	typedef void __noreturn (*image_entry_noargs_t)(void);
+	uint32_t offset;
 
 	image_entry_noargs_t image_entry =
 		(image_entry_noargs_t)(unsigned long)spl_image->entry_point;
@@ -163,8 +198,10 @@
 
 	/* HAB looks for the CSF at the end of the authenticated data therefore,
 	 * we need to subtract the size of the CSF from the actual filesize */
-	if (authenticate_image(spl_image->load_addr,
-			       spl_image->size - CONFIG_CSF_SIZE)) {
+	offset = spl_image->size - CONFIG_CSF_SIZE;
+	if (!imx_hab_authenticate_image(spl_image->load_addr,
+					offset + IVT_SIZE + CSF_PAD_SIZE,
+					offset)) {
 		image_entry();
 	} else {
 		puts("spl: ERROR:  image authentication unsuccessful\n");
diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig
index dc7ba21..d55dc1a 100644
--- a/arch/arm/mach-snapdragon/Kconfig
+++ b/arch/arm/mach-snapdragon/Kconfig
@@ -19,8 +19,18 @@
 	  - HDMI
 	  - 20-pin low speed and 40-pin high speed expanders, 4 LED, 3 buttons
 
+config TARGET_DRAGONBOARD820C
+	bool "96Boards Dragonboard 820C"
+	help
+	  Support for 96Boards Dragonboard 820C. This board complies with
+	  96Board Open Platform Specifications. Features:
+	  - Qualcomm Snapdragon 820C SoC - APQ8096 (4xKyro CPU)
+	  - 3GiB RAM
+	  - 32GiB UFS drive
+
 endchoice
 
 source "board/qualcomm/dragonboard410c/Kconfig"
+source "board/qualcomm/dragonboard820c/Kconfig"
 
 endif
diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile
index d82a04d..090c355 100644
--- a/arch/arm/mach-snapdragon/Makefile
+++ b/arch/arm/mach-snapdragon/Makefile
@@ -4,5 +4,8 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-y += clock-apq8016.o
-obj-y += sysmap-apq8016.o
+obj-$(CONFIG_TARGET_DRAGONBOARD820C) += clock-apq8096.o
+obj-$(CONFIG_TARGET_DRAGONBOARD820C) += sysmap-apq8096.o
+obj-$(CONFIG_TARGET_DRAGONBOARD410C) += clock-apq8016.o
+obj-$(CONFIG_TARGET_DRAGONBOARD410C) += sysmap-apq8016.o
+obj-y += clock-snapdragon.o
diff --git a/arch/arm/mach-snapdragon/clock-apq8016.c b/arch/arm/mach-snapdragon/clock-apq8016.c
index da05015..a242417 100644
--- a/arch/arm/mach-snapdragon/clock-apq8016.c
+++ b/arch/arm/mach-snapdragon/clock-apq8016.c
@@ -14,146 +14,12 @@
 #include <errno.h>
 #include <asm/io.h>
 #include <linux/bitops.h>
+#include "clock-snapdragon.h"
 
 /* GPLL0 clock control registers */
-#define GPLL0_STATUS        0x2101C
 #define GPLL0_STATUS_ACTIVE BIT(17)
-
-#define APCS_GPLL_ENA_VOTE  0x45000
 #define APCS_GPLL_ENA_VOTE_GPLL0 BIT(0)
 
-/* vote reg for blsp1 clock */
-#define APCS_CLOCK_BRANCH_ENA_VOTE  0x45004
-#define APCS_CLOCK_BRANCH_ENA_VOTE_BLSP1 BIT(10)
-
-/* SDC(n) clock control registers; n=1,2 */
-
-/* block control register */
-#define SDCC_BCR(n)                 ((n * 0x1000) + 0x41000)
-/* cmd */
-#define SDCC_CMD_RCGR(n)            ((n * 0x1000) + 0x41004)
-/* cfg */
-#define SDCC_CFG_RCGR(n)            ((n * 0x1000) + 0x41008)
-/* m */
-#define SDCC_M(n)                   ((n * 0x1000) + 0x4100C)
-/* n */
-#define SDCC_N(n)                   ((n * 0x1000) + 0x41010)
-/* d */
-#define SDCC_D(n)                   ((n * 0x1000) + 0x41014)
-/* branch control */
-#define SDCC_APPS_CBCR(n)           ((n * 0x1000) + 0x41018)
-#define SDCC_AHB_CBCR(n)            ((n * 0x1000) + 0x4101C)
-
-/* BLSP1 AHB clock (root clock for BLSP) */
-#define BLSP1_AHB_CBCR              0x1008
-
-/* Uart clock control registers */
-#define BLSP1_UART2_BCR             0x3028
-#define BLSP1_UART2_APPS_CBCR       0x302C
-#define BLSP1_UART2_APPS_CMD_RCGR   0x3034
-#define BLSP1_UART2_APPS_CFG_RCGR   0x3038
-#define BLSP1_UART2_APPS_M          0x303C
-#define BLSP1_UART2_APPS_N          0x3040
-#define BLSP1_UART2_APPS_D          0x3044
-
-/* CBCR register fields */
-#define CBCR_BRANCH_ENABLE_BIT  BIT(0)
-#define CBCR_BRANCH_OFF_BIT     BIT(31)
-
-struct msm_clk_priv {
-	phys_addr_t base;
-};
-
-/* Enable clock controlled by CBC soft macro */
-static void clk_enable_cbc(phys_addr_t cbcr)
-{
-	setbits_le32(cbcr, CBCR_BRANCH_ENABLE_BIT);
-
-	while (readl(cbcr) & CBCR_BRANCH_OFF_BIT)
-		;
-}
-
-/* clock has 800MHz */
-static void clk_enable_gpll0(phys_addr_t base)
-{
-	if (readl(base + GPLL0_STATUS) & GPLL0_STATUS_ACTIVE)
-		return; /* clock already enabled */
-
-	setbits_le32(base + APCS_GPLL_ENA_VOTE, APCS_GPLL_ENA_VOTE_GPLL0);
-
-	while ((readl(base + GPLL0_STATUS) & GPLL0_STATUS_ACTIVE) == 0)
-		;
-}
-
-#define APPS_CMD_RGCR_UPDATE BIT(0)
-
-/* Update clock command via CMD_RGCR */
-static void clk_bcr_update(phys_addr_t apps_cmd_rgcr)
-{
-	setbits_le32(apps_cmd_rgcr, APPS_CMD_RGCR_UPDATE);
-
-	/* Wait for frequency to be updated. */
-	while (readl(apps_cmd_rgcr) & APPS_CMD_RGCR_UPDATE)
-		;
-}
-
-struct bcr_regs {
-	uintptr_t cfg_rcgr;
-	uintptr_t cmd_rcgr;
-	uintptr_t M;
-	uintptr_t N;
-	uintptr_t D;
-};
-
-/* RCGR_CFG register fields */
-#define CFG_MODE_DUAL_EDGE (0x2 << 12) /* Counter mode */
-
-/* sources */
-#define CFG_CLK_SRC_CXO   (0 << 8)
-#define CFG_CLK_SRC_GPLL0 (1 << 8)
-#define CFG_CLK_SRC_MASK  (7 << 8)
-
-/* Mask for supported fields */
-#define CFG_MASK 0x3FFF
-
-#define CFG_DIVIDER_MASK 0x1F
-
-/* root set rate for clocks with half integer and MND divider */
-static void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
-				 int div, int m, int n, int source)
-{
-	uint32_t cfg;
-	/* M value for MND divider. */
-	uint32_t m_val = m;
-	/* NOT(N-M) value for MND divider. */
-	uint32_t n_val = ~((n)-(m)) * !!(n);
-	/* NOT 2D value for MND divider. */
-	uint32_t d_val = ~(n);
-
-	/* Program MND values */
-	writel(m_val, base + regs->M);
-	writel(n_val, base + regs->N);
-	writel(d_val, base + regs->D);
-
-	/* setup src select and divider */
-	cfg  = readl(base + regs->cfg_rcgr);
-	cfg &= ~CFG_MASK;
-	cfg |= source & CFG_CLK_SRC_MASK; /* Select clock source */
-
-	/* Set the divider; HW permits fraction dividers (+0.5), but
-	   for simplicity, we will support integers only */
-	if (div)
-		cfg |= (2 * div - 1) & CFG_DIVIDER_MASK;
-
-	if (n_val)
-		cfg |= CFG_MODE_DUAL_EDGE;
-
-	writel(cfg, base + regs->cfg_rcgr); /* Write new clock configuration */
-
-	/* Inform h/w to start using the new config. */
-	clk_bcr_update(base + regs->cmd_rcgr);
-}
-
 static const struct bcr_regs sdc_regs[] = {
 	{
 	.cfg_rcgr = SDCC_CFG_RCGR(1),
@@ -171,7 +37,14 @@
 	}
 };
 
+static struct gpll0_ctrl gpll0_ctrl = {
+	.status = GPLL0_STATUS,
+	.status_bit = GPLL0_STATUS_ACTIVE,
+	.ena_vote = APCS_GPLL_ENA_VOTE,
+	.vote_bit = APCS_GPLL_ENA_VOTE_GPLL0,
+};
+
-/* Init clock for SDHCI controller */
+/* SDHCI */
 static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate)
 {
 	int div = 8; /* 100MHz default */
@@ -183,7 +56,7 @@
 	/* 800Mhz/div, gpll0 */
 	clk_rcg_set_rate_mnd(priv->base, &sdc_regs[slot], div, 0, 0,
 			     CFG_CLK_SRC_GPLL0);
-	clk_enable_gpll0(priv->base);
+	clk_enable_gpll0(priv->base, &gpll0_ctrl);
 	clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot));
 
 	return rate;
@@ -197,7 +70,7 @@
 	.D = BLSP1_UART2_APPS_D,
 };
 
-/* Init UART clock, 115200 */
+/* UART: 115200 */
 static int clk_init_uart(struct msm_clk_priv *priv)
 {
 	/* Enable iface clk */
@@ -205,7 +78,7 @@
 	/* 7372800 uart block clock @ GPLL0 */
 	clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 144, 15625,
 			     CFG_CLK_SRC_GPLL0);
-	clk_enable_gpll0(priv->base);
+	clk_enable_gpll0(priv->base, &gpll0_ctrl);
 	/* Enable core clk */
 	clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
 
@@ -230,33 +103,3 @@
 		return 0;
 	}
 }
-
-static int msm_clk_probe(struct udevice *dev)
-{
-	struct msm_clk_priv *priv = dev_get_priv(dev);
-
-	priv->base = devfdt_get_addr(dev);
-	if (priv->base == FDT_ADDR_T_NONE)
-		return -EINVAL;
-
-	return 0;
-}
-
-static struct clk_ops msm_clk_ops = {
-	.set_rate = msm_set_rate,
-};
-
-static const struct udevice_id msm_clk_ids[] = {
-	{ .compatible = "qcom,gcc-msm8916" },
-	{ .compatible = "qcom,gcc-apq8016" },
-	{ }
-};
-
-U_BOOT_DRIVER(clk_msm) = {
-	.name		= "clk_msm",
-	.id		= UCLASS_CLK,
-	.of_match	= msm_clk_ids,
-	.ops		= &msm_clk_ops,
-	.priv_auto_alloc_size = sizeof(struct msm_clk_priv),
-	.probe		= msm_clk_probe,
-};
diff --git a/arch/arm/mach-snapdragon/clock-apq8096.c b/arch/arm/mach-snapdragon/clock-apq8096.c
new file mode 100644
index 0000000..3d363d4
--- /dev/null
+++ b/arch/arm/mach-snapdragon/clock-apq8096.c
@@ -0,0 +1,62 @@
+/*
+ * Clock drivers for Qualcomm APQ8096
+ *
+ * (C) Copyright 2017 Jorge Ramirez Ortiz <jorge.ramirez-ortiz@linaro.org>
+ *
+ * Based on Little Kernel driver, simplified
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include "clock-snapdragon.h"
+
+/* GPLL0 clock control registers */
+#define GPLL0_STATUS_ACTIVE		BIT(30)
+#define APCS_GPLL_ENA_VOTE_GPLL0	BIT(0)
+
+static const struct bcr_regs sdc_regs = {
+	.cfg_rcgr = SDCC2_CFG_RCGR,
+	.cmd_rcgr = SDCC2_CMD_RCGR,
+	.M = SDCC2_M,
+	.N = SDCC2_N,
+	.D = SDCC2_D,
+};
+
+static const struct gpll0_ctrl gpll0_ctrl = {
+	.status = GPLL0_STATUS,
+	.status_bit = GPLL0_STATUS_ACTIVE,
+	.ena_vote = APCS_GPLL_ENA_VOTE,
+	.vote_bit = APCS_GPLL_ENA_VOTE_GPLL0,
+};
+
+static int clk_init_sdc(struct msm_clk_priv *priv, uint rate)
+{
+	int div = 3;
+
+	clk_enable_cbc(priv->base + SDCC2_AHB_CBCR);
+	clk_rcg_set_rate_mnd(priv->base, &sdc_regs, div, 0, 0,
+			     CFG_CLK_SRC_GPLL0);
+	clk_enable_gpll0(priv->base, &gpll0_ctrl);
+	clk_enable_cbc(priv->base + SDCC2_APPS_CBCR);
+
+	return rate;
+}
+
+ulong msm_set_rate(struct clk *clk, ulong rate)
+{
+	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+	switch (clk->id) {
+	case 0: /* SDC1 */
+		return clk_init_sdc(priv, rate);
+		break;
+	default:
+		return 0;
+	}
+}
diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.c b/arch/arm/mach-snapdragon/clock-snapdragon.c
new file mode 100644
index 0000000..899b5ba
--- /dev/null
+++ b/arch/arm/mach-snapdragon/clock-snapdragon.c
@@ -0,0 +1,134 @@
+/*
+ * Clock drivers for Qualcomm APQ8016, APQ8096
+ *
+ * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
+ *
+ * Based on Little Kernel driver, simplified
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include "clock-snapdragon.h"
+
+/* CBCR register fields */
+#define CBCR_BRANCH_ENABLE_BIT  BIT(0)
+#define CBCR_BRANCH_OFF_BIT     BIT(31)
+
+extern ulong msm_set_rate(struct clk *clk, ulong rate);
+
+/* Enable clock controlled by CBC soft macro */
+void clk_enable_cbc(phys_addr_t cbcr)
+{
+	setbits_le32(cbcr, CBCR_BRANCH_ENABLE_BIT);
+
+	while (readl(cbcr) & CBCR_BRANCH_OFF_BIT)
+		;
+}
+
+void clk_enable_gpll0(phys_addr_t base, const struct gpll0_ctrl *gpll0)
+{
+	if (readl(base + gpll0->status) & gpll0->status_bit)
+		return; /* clock already enabled */
+
+	setbits_le32(base + gpll0->ena_vote, gpll0->vote_bit);
+
+	while ((readl(base + gpll0->status) & gpll0->status_bit) == 0)
+		;
+}
+
+#define APPS_CMD_RGCR_UPDATE BIT(0)
+
+/* Update clock command via CMD_RGCR */
+void clk_bcr_update(phys_addr_t apps_cmd_rgcr)
+{
+	setbits_le32(apps_cmd_rgcr, APPS_CMD_RGCR_UPDATE);
+
+	/* Wait for frequency to be updated. */
+	while (readl(apps_cmd_rgcr) & APPS_CMD_RGCR_UPDATE)
+		;
+}
+
+#define CFG_MODE_DUAL_EDGE (0x2 << 12) /* Counter mode */
+
+#define CFG_MASK 0x3FFF
+
+#define CFG_DIVIDER_MASK 0x1F
+
+/* root set rate for clocks with half integer and MND divider */
+void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
+			  int div, int m, int n, int source)
+{
+	u32 cfg;
+	/* M value for MND divider. */
+	u32 m_val = m;
+	/* NOT(N-M) value for MND divider. */
+	u32 n_val = ~((n) - (m)) * !!(n);
+	/* NOT 2D value for MND divider. */
+	u32 d_val = ~(n);
+
+	/* Program MND values */
+	writel(m_val, base + regs->M);
+	writel(n_val, base + regs->N);
+	writel(d_val, base + regs->D);
+
+	/* setup src select and divider */
+	cfg  = readl(base + regs->cfg_rcgr);
+	cfg &= ~CFG_MASK;
+	cfg |= source & CFG_CLK_SRC_MASK; /* Select clock source */
+
+	/* Set the divider; HW permits fraction dividers (+0.5), but
+	   for simplicity, we will support integers only */
+	if (div)
+		cfg |= (2 * div - 1) & CFG_DIVIDER_MASK;
+
+	if (n_val)
+		cfg |= CFG_MODE_DUAL_EDGE;
+
+	writel(cfg, base + regs->cfg_rcgr); /* Write new clock configuration */
+
+	/* Inform h/w to start using the new config. */
+	clk_bcr_update(base + regs->cmd_rcgr);
+}
+
+static int msm_clk_probe(struct udevice *dev)
+{
+	struct msm_clk_priv *priv = dev_get_priv(dev);
+
+	priv->base = devfdt_get_addr(dev);
+	if (priv->base == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	return 0;
+}
+
+static ulong msm_clk_set_rate(struct clk *clk, ulong rate)
+{
+	return msm_set_rate(clk, rate);
+}
+
+static struct clk_ops msm_clk_ops = {
+	.set_rate = msm_clk_set_rate,
+};
+
+static const struct udevice_id msm_clk_ids[] = {
+	{ .compatible = "qcom,gcc-msm8916" },
+	{ .compatible = "qcom,gcc-apq8016" },
+	{ .compatible = "qcom,gcc-msm8996" },
+	{ .compatible = "qcom,gcc-apq8096" },
+	{ }
+};
+
+U_BOOT_DRIVER(clk_msm) = {
+	.name		= "clk_msm",
+	.id		= UCLASS_CLK,
+	.of_match	= msm_clk_ids,
+	.ops		= &msm_clk_ops,
+	.priv_auto_alloc_size = sizeof(struct msm_clk_priv),
+	.probe		= msm_clk_probe,
+};
diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.h b/arch/arm/mach-snapdragon/clock-snapdragon.h
new file mode 100644
index 0000000..d7026aa
--- /dev/null
+++ b/arch/arm/mach-snapdragon/clock-snapdragon.h
@@ -0,0 +1,40 @@
+/*
+ * Qualcomm APQ8016, APQ8096
+ *
+ * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _CLOCK_SNAPDRAGON_H
+#define _CLOCK_SNAPDRAGON_H
+
+#define CFG_CLK_SRC_CXO   (0 << 8)
+#define CFG_CLK_SRC_GPLL0 (1 << 8)
+#define CFG_CLK_SRC_MASK  (7 << 8)
+
+struct gpll0_ctrl {
+	uintptr_t status;
+	int status_bit;
+	uintptr_t ena_vote;
+	int vote_bit;
+};
+
+struct bcr_regs {
+	uintptr_t cfg_rcgr;
+	uintptr_t cmd_rcgr;
+	uintptr_t M;
+	uintptr_t N;
+	uintptr_t D;
+};
+
+struct msm_clk_priv {
+	phys_addr_t base;
+};
+
+void clk_enable_gpll0(phys_addr_t base, const struct gpll0_ctrl *pll0);
+void clk_bcr_update(phys_addr_t apps_cmd_rgcr);
+void clk_enable_cbc(phys_addr_t cbcr);
+void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
+			  int div, int m, int n, int source);
+
+#endif
diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h b/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h
index cdbfad0..1094b14 100644
--- a/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h
+++ b/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h
@@ -8,7 +8,32 @@
 #ifndef _MACH_SYSMAP_APQ8016_H
 #define _MACH_SYSMAP_APQ8016_H
 
-#define GICD_BASE 0x0b000000
-#define GICC_BASE 0x0a20c000
+#define GICD_BASE			(0x0b000000)
+#define GICC_BASE			(0x0a20c000)
+
+/* Clocks: (from CLK_CTL_BASE)  */
+#define GPLL0_STATUS			(0x2101C)
+#define APCS_GPLL_ENA_VOTE		(0x45000)
+
+#define SDCC_BCR(n)			((n * 0x1000) + 0x41000)
+#define SDCC_CMD_RCGR(n)		((n * 0x1000) + 0x41004)
+#define SDCC_CFG_RCGR(n)		((n * 0x1000) + 0x41008)
+#define SDCC_M(n)			((n * 0x1000) + 0x4100C)
+#define SDCC_N(n)			((n * 0x1000) + 0x41010)
+#define SDCC_D(n)			((n * 0x1000) + 0x41014)
+#define SDCC_APPS_CBCR(n)		((n * 0x1000) + 0x41018)
+#define SDCC_AHB_CBCR(n)		((n * 0x1000) + 0x4101C)
+
+/* BLSP1 AHB clock (root clock for BLSP) */
+#define BLSP1_AHB_CBCR			0x1008
+
+/* Uart clock control registers */
+#define BLSP1_UART2_BCR			(0x3028)
+#define BLSP1_UART2_APPS_CBCR		(0x302C)
+#define BLSP1_UART2_APPS_CMD_RCGR	(0x3034)
+#define BLSP1_UART2_APPS_CFG_RCGR	(0x3038)
+#define BLSP1_UART2_APPS_M		(0x303C)
+#define BLSP1_UART2_APPS_N		(0x3040)
+#define BLSP1_UART2_APPS_D		(0x3044)
 
 #endif
diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-apq8096.h b/arch/arm/mach-snapdragon/include/mach/sysmap-apq8096.h
new file mode 100644
index 0000000..fb89de2
--- /dev/null
+++ b/arch/arm/mach-snapdragon/include/mach/sysmap-apq8096.h
@@ -0,0 +1,29 @@
+/*
+ * Qualcomm APQ8096 sysmap
+ *
+ * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _MACH_SYSMAP_APQ8096_H
+#define _MACH_SYSMAP_APQ8096_H
+
+#define TLMM_BASE_ADDR			(0x1010000)
+
+/* Strength (sdc1) */
+#define SDC1_HDRV_PULL_CTL_REG		(TLMM_BASE_ADDR + 0x0012D000)
+
+/* Clocks: (from CLK_CTL_BASE)  */
+#define GPLL0_STATUS			(0x0000)
+#define APCS_GPLL_ENA_VOTE		(0x52000)
+
+#define SDCC2_BCR			(0x14000) /* block reset */
+#define SDCC2_APPS_CBCR			(0x14004) /* branch control */
+#define SDCC2_AHB_CBCR			(0x14008)
+#define SDCC2_CMD_RCGR			(0x14010)
+#define SDCC2_CFG_RCGR			(0x14014)
+#define SDCC2_M				(0x14018)
+#define SDCC2_N				(0x1401C)
+#define SDCC2_D				(0x14020)
+
+#endif
diff --git a/arch/arm/mach-snapdragon/sysmap-apq8096.c b/arch/arm/mach-snapdragon/sysmap-apq8096.c
new file mode 100644
index 0000000..cb6d1e4
--- /dev/null
+++ b/arch/arm/mach-snapdragon/sysmap-apq8096.c
@@ -0,0 +1,32 @@
+/*
+ * Qualcomm APQ8096 memory map
+ *
+ * (C) Copyright 2017 Jorge Ramirez Ortiz <jorge.ramirez-ortiz@linaro.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/armv8/mmu.h>
+
+static struct mm_region apq8096_mem_map[] = {
+	{
+		.virt = 0x0UL, /* Peripheral block */
+		.phys = 0x0UL, /* Peripheral block */
+		.size = 0x10000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		.virt = 0x80000000UL, /* DDR */
+		.phys = 0x80000000UL, /* DDR */
+		.size = 0xC0000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
+		/* List terminator */
+		0,
+	}
+};
+
+struct mm_region *mem_map = apq8096_mem_map;
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index e67d428..3f9e788 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -478,6 +478,13 @@
 	wdt0: wdt@0 {
 		compatible = "sandbox,wdt";
 	};
+
+	chosen {
+		chosen-test {
+			compatible = "denx,u-boot-fdt-test";
+			reg = <9 1>;
+		};
+	};
 };
 
 #include "sandbox_pmic.dtsi"
diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c
index 620c3f2..673de03 100644
--- a/board/compulab/cm_fx6/cm_fx6.c
+++ b/board/compulab/cm_fx6/cm_fx6.c
@@ -621,6 +621,27 @@
 	return 0;
 }
 
+int board_late_init(void)
+{
+#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+	char baseboard_name[16];
+	int err;
+
+	if (is_mx6dq())
+		env_set("board_rev", "MX6Q");
+	else if (is_mx6dl())
+		env_set("board_rev", "MX6DL");
+
+	err = cl_eeprom_get_product_name((uchar *)baseboard_name, 0);
+	if (err)
+		return 0;
+
+	if (!strncmp("SB-FX6m", baseboard_name, 7))
+		env_set("board_name", "Utilite");
+#endif
+	return 0;
+}
+
 int checkboard(void)
 {
 	puts("Board: CM-FX6\n");
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile
index 1c53fb6..e13cb20 100644
--- a/board/freescale/common/Makefile
+++ b/board/freescale/common/Makefile
@@ -61,6 +61,7 @@
 obj-$(CONFIG_IDT8T49N222A)	+= idt8t49n222a_serdes_clk.o
 obj-$(CONFIG_ZM7300)		+= zm7300.o
 obj-$(CONFIG_POWER_PFUZE100)	+= pfuze.o
+obj-$(CONFIG_DM_PMIC_PFUZE100)	+= pfuze.o
 obj-$(CONFIG_POWER_MC34VR500)	+= mc34vr500.o
 
 obj-$(CONFIG_LS102XA_STREAM_ID)	+= ls102xa_stream_id.o
diff --git a/board/freescale/common/pfuze.c b/board/freescale/common/pfuze.c
index 69afa83..f194d0b 100644
--- a/board/freescale/common/pfuze.c
+++ b/board/freescale/common/pfuze.c
@@ -92,4 +92,83 @@
 
 	return p;
 }
+#else
+int pfuze_mode_init(struct udevice *dev, u32 mode)
+{
+	unsigned char offset, i, switch_num;
+	u32 id;
+	int ret;
+
+	id = pmic_reg_read(dev, PFUZE100_DEVICEID);
+	id = id & 0xf;
+
+	if (id == 0) {
+		switch_num = 6;
+		offset = PFUZE100_SW1CMODE;
+	} else if (id == 1) {
+		switch_num = 4;
+		offset = PFUZE100_SW2MODE;
+	} else {
+		printf("Not supported, id=%d\n", id);
+		return -EINVAL;
+	}
+
+	ret = pmic_reg_write(dev, PFUZE100_SW1ABMODE, mode);
+	if (ret < 0) {
+		printf("Set SW1AB mode error!\n");
+		return ret;
+	}
+
+	for (i = 0; i < switch_num - 1; i++) {
+		ret = pmic_reg_write(dev, offset + i * SWITCH_SIZE, mode);
+		if (ret < 0) {
+			printf("Set switch 0x%x mode error!\n",
+			       offset + i * SWITCH_SIZE);
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
+struct udevice *pfuze_common_init(void)
+{
+	struct udevice *dev;
+	int ret;
+	unsigned int reg, dev_id, rev_id;
+
+	ret = pmic_get("pfuze100", &dev);
+	if (ret == -ENODEV)
+		return NULL;
+
+	dev_id = pmic_reg_read(dev, PFUZE100_DEVICEID);
+	rev_id = pmic_reg_read(dev, PFUZE100_REVID);
+	printf("PMIC: PFUZE100! DEV_ID=0x%x REV_ID=0x%x\n", dev_id, rev_id);
+
+	/* Set SW1AB stanby volage to 0.975V */
+	reg = pmic_reg_read(dev, PFUZE100_SW1ABSTBY);
+	reg &= ~SW1x_STBY_MASK;
+	reg |= SW1x_0_975V;
+	pmic_reg_write(dev, PFUZE100_SW1ABSTBY, reg);
+
+	/* Set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */
+	reg = pmic_reg_read(dev, PFUZE100_SW1ABCONF);
+	reg &= ~SW1xCONF_DVSSPEED_MASK;
+	reg |= SW1xCONF_DVSSPEED_4US;
+	pmic_reg_write(dev, PFUZE100_SW1ABCONF, reg);
+
+	/* Set SW1C standby voltage to 0.975V */
+	reg = pmic_reg_read(dev, PFUZE100_SW1CSTBY);
+	reg &= ~SW1x_STBY_MASK;
+	reg |= SW1x_0_975V;
+	pmic_reg_write(dev, PFUZE100_SW1CSTBY, reg);
+
+	/* Set SW1C/VDDSOC step ramp up time from 16us to 4us/25mV */
+	reg = pmic_reg_read(dev, PFUZE100_SW1CCONF);
+	reg &= ~SW1xCONF_DVSSPEED_MASK;
+	reg |= SW1xCONF_DVSSPEED_4US;
+	pmic_reg_write(dev, PFUZE100_SW1CCONF, reg);
+
+	return dev;
+}
 #endif
diff --git a/board/freescale/common/pfuze.h b/board/freescale/common/pfuze.h
index 53cfc99..3f8c107 100644
--- a/board/freescale/common/pfuze.h
+++ b/board/freescale/common/pfuze.h
@@ -7,7 +7,12 @@
 #ifndef __PFUZE_BOARD_HELPER__
 #define __PFUZE_BOARD_HELPER__
 
+#ifdef CONFIG_DM_PMIC_PFUZE100
+struct udevice *pfuze_common_init(void);
+int pfuze_mode_init(struct udevice *dev, u32 mode);
+#else
 struct pmic *pfuze_common_init(unsigned char i2cbus);
 int pfuze_mode_init(struct pmic *p, u32 mode);
+#endif
 
 #endif
diff --git a/board/freescale/mx6memcal/Kconfig b/board/freescale/mx6memcal/Kconfig
index 443804d..9987cba 100644
--- a/board/freescale/mx6memcal/Kconfig
+++ b/board/freescale/mx6memcal/Kconfig
@@ -45,20 +45,12 @@
 		  NXP SABRELite.
 
 	config UART1_CSI0_DAT10_11
-		bool "UART1 on CSI0_DAT10/11 (Wand)"
+		bool "UART1 on CSI0_DAT10/11 (Wand, SabreSD)"
 		depends on SERIAL_CONSOLE_UART1
 		help
 		  Choose this configuration if you're using pads
 		  CSI0_DAT10 and DAT11 for a console on UART1 as
-		  is done on the i.MX6 Wand board.
-
-	config UART1_SD3_DAT6_7
-		bool "UART1 on SD3_DAT6/7 (SabreSD, SabreAuto)"
-		depends on SERIAL_CONSOLE_UART1
-		help
-		  Choose this configuration if you're using pads
-		  SD3_DAT6 and DAT7 for a console on UART1 as is
-		  done on the NXP SABRESD or SABREAUTO designs.
+		  is done on the i.MX6 Wand board and i.MX6 SabreSD.
 
 	config UART1_UART1
 		bool "UART1 on UART1 (i.MX6SL EVK, WaRP)"
diff --git a/board/freescale/mx6memcal/spl.c b/board/freescale/mx6memcal/spl.c
index 8ee89ff..027da4f 100644
--- a/board/freescale/mx6memcal/spl.c
+++ b/board/freescale/mx6memcal/spl.c
@@ -419,6 +419,7 @@
 	if (sysinfo.dsize != 1) {
 		if (is_cpu_type(MXC_CPU_MX6SX) ||
 		    is_cpu_type(MXC_CPU_MX6UL) ||
+		    is_cpu_type(MXC_CPU_MX6ULL) ||
 		    is_cpu_type(MXC_CPU_MX6SL)) {
 			printf("cpu type 0x%x doesn't support 64-bit bus\n",
 			       get_cpu_type());
@@ -445,7 +446,7 @@
 	} else {
 		errs = mmdc_do_dqs_calibration(&sysinfo);
 		if (errs) {
-			printf("error %d from write level calibration\n", errs);
+			printf("error %d from dqs calibration\n", errs);
 		} else {
 			printf("completed successfully\n");
 			mmdc_read_calibration(&sysinfo, &calibration);
diff --git a/board/freescale/mx6sxsabresd/mx6sxsabresd.c b/board/freescale/mx6sxsabresd/mx6sxsabresd.c
index 3ad2140..34371ad 100644
--- a/board/freescale/mx6sxsabresd/mx6sxsabresd.c
+++ b/board/freescale/mx6sxsabresd/mx6sxsabresd.c
@@ -26,8 +26,6 @@
 #include <power/pmic.h>
 #include <power/pfuze100_pmic.h>
 #include "../common/pfuze.h"
-#include <usb.h>
-#include <usb/ehci-ci.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -39,11 +37,6 @@
 	PAD_CTL_PUS_22K_UP  | PAD_CTL_SPEED_LOW |		\
 	PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
 
-#define I2C_PAD_CTRL    (PAD_CTL_PKE | PAD_CTL_PUE |            \
-	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |               \
-	PAD_CTL_DSE_40ohm | PAD_CTL_HYS |			\
-	PAD_CTL_ODE)
-
 #define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE |     \
 	PAD_CTL_SPEED_HIGH   |                                   \
 	PAD_CTL_DSE_48ohm   | PAD_CTL_SRE_FAST)
@@ -54,14 +47,12 @@
 #define ENET_RX_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |          \
 	PAD_CTL_SPEED_HIGH   | PAD_CTL_SRE_FAST)
 
-#define I2C_PAD_CTRL    (PAD_CTL_PKE | PAD_CTL_PUE |            \
-	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |               \
-	PAD_CTL_DSE_40ohm | PAD_CTL_HYS |			\
-	PAD_CTL_ODE)
-
 #define LCD_PAD_CTRL    (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \
 	PAD_CTL_PKE | PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm)
 
+#define WDOG_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_PKE | PAD_CTL_SPEED_MED |	\
+	PAD_CTL_DSE_40ohm)
+
 int dram_init(void)
 {
 	gd->ram_size = imx_ddr_size();
@@ -74,44 +65,9 @@
 	MX6_PAD_GPIO1_IO05__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
 };
 
-static iomux_v3_cfg_t const usdhc2_pads[] = {
-	MX6_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-};
-
-static iomux_v3_cfg_t const usdhc3_pads[] = {
-	MX6_PAD_SD3_CLK__USDHC3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD3_CMD__USDHC3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD3_DATA0__USDHC3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD3_DATA1__USDHC3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD3_DATA2__USDHC3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD3_DATA3__USDHC3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD3_DATA4__USDHC3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD3_DATA5__USDHC3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD3_DATA6__USDHC3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD3_DATA7__USDHC3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-
-	/* CD pin */
-	MX6_PAD_KEY_COL0__GPIO2_IO_10 | MUX_PAD_CTRL(NO_PAD_CTRL),
-
-	/* RST_B, used for power reset cycle */
-	MX6_PAD_KEY_COL1__GPIO2_IO_11 | MUX_PAD_CTRL(NO_PAD_CTRL),
-};
-
-static iomux_v3_cfg_t const usdhc4_pads[] = {
-	MX6_PAD_SD4_CLK__USDHC4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD4_CMD__USDHC4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD4_DATA0__USDHC4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD4_DATA1__USDHC4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD4_DATA2__USDHC4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD4_DATA3__USDHC4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-	MX6_PAD_SD4_DATA7__GPIO6_IO_21 | MUX_PAD_CTRL(NO_PAD_CTRL),
+static iomux_v3_cfg_t const wdog_b_pad = {
+	MX6_PAD_GPIO1_IO13__GPIO1_IO_13 | MUX_PAD_CTRL(WDOG_PAD_CTRL),
 };
-
 static iomux_v3_cfg_t const fec1_pads[] = {
 	MX6_PAD_ENET1_MDC__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
 	MX6_PAD_ENET1_MDIO__ENET1_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
@@ -166,9 +122,11 @@
 					 ARRAY_SIZE(phy_control_pads));
 
 	/* Enable the ENET power, active low */
+	gpio_request(IMX_GPIO_NR(2, 6), "enet_rst");
 	gpio_direction_output(IMX_GPIO_NR(2, 6) , 0);
 
 	/* Reset AR8031 PHY */
+	gpio_request(IMX_GPIO_NR(2, 7), "phy_rst");
 	gpio_direction_output(IMX_GPIO_NR(2, 7) , 0);
 	mdelay(10);
 	gpio_set_value(IMX_GPIO_NR(2, 7), 1);
@@ -188,87 +146,29 @@
 	return cpu_eth_init(bis);
 }
 
-#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
-/* I2C1 for PMIC */
-static struct i2c_pads_info i2c_pad_info1 = {
-	.scl = {
-		.i2c_mode = MX6_PAD_GPIO1_IO00__I2C1_SCL | PC,
-		.gpio_mode = MX6_PAD_GPIO1_IO00__GPIO1_IO_0 | PC,
-		.gp = IMX_GPIO_NR(1, 0),
-	},
-	.sda = {
-		.i2c_mode = MX6_PAD_GPIO1_IO01__I2C1_SDA | PC,
-		.gpio_mode = MX6_PAD_GPIO1_IO01__GPIO1_IO_1 | PC,
-		.gp = IMX_GPIO_NR(1, 1),
-	},
-};
-
 int power_init_board(void)
 {
-	struct pmic *p;
+	struct udevice *dev;
 	unsigned int reg;
 	int ret;
 
-	p = pfuze_common_init(I2C_PMIC);
-	if (!p)
+	dev = pfuze_common_init();
+	if (!dev)
 		return -ENODEV;
 
-	ret = pfuze_mode_init(p, APS_PFM);
+	ret = pfuze_mode_init(dev, APS_PFM);
 	if (ret < 0)
 		return ret;
 
 	/* Enable power of VGEN5 3V3, needed for SD3 */
-	pmic_reg_read(p, PFUZE100_VGEN5VOL, &reg);
+	reg = pmic_reg_read(dev, PFUZE100_VGEN5VOL);
 	reg &= ~LDO_VOL_MASK;
 	reg |= (LDOB_3_30V | (1 << LDO_EN));
-	pmic_reg_write(p, PFUZE100_VGEN5VOL, reg);
+	pmic_reg_write(dev, PFUZE100_VGEN5VOL, reg);
 
 	return 0;
 }
 
-#ifdef CONFIG_USB_EHCI_MX6
-#define USB_OTHERREGS_OFFSET	0x800
-#define UCTRL_PWR_POL		(1 << 9)
-
-static iomux_v3_cfg_t const usb_otg_pads[] = {
-	/* OGT1 */
-	MX6_PAD_GPIO1_IO09__USB_OTG1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
-	MX6_PAD_GPIO1_IO10__ANATOP_OTG1_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
-	/* OTG2 */
-	MX6_PAD_GPIO1_IO12__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL)
-};
-
-static void setup_usb(void)
-{
-	imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
-					 ARRAY_SIZE(usb_otg_pads));
-}
-
-int board_usb_phy_mode(int port)
-{
-	if (port == 1)
-		return USB_INIT_HOST;
-	else
-		return usb_phy_mode(port);
-}
-
-int board_ehci_hcd_init(int port)
-{
-	u32 *usbnc_usb_ctrl;
-
-	if (port > 1)
-		return -EINVAL;
-
-	usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET +
-				 port * 4);
-
-	/* Set Power polarity */
-	setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL);
-
-	return 0;
-}
-#endif
-
 int board_phy_config(struct phy_device *phydev)
 {
 	/*
@@ -296,138 +196,12 @@
 	imx_iomux_v3_setup_multiple_pads(peri_3v3_pads,
 					 ARRAY_SIZE(peri_3v3_pads));
 
-	/* Active high for ncp692 */
-	gpio_direction_output(IMX_GPIO_NR(4, 16) , 1);
-
-#ifdef CONFIG_USB_EHCI_MX6
-	setup_usb();
-#endif
-
 	return 0;
 }
 
-static struct fsl_esdhc_cfg usdhc_cfg[3] = {
-	{USDHC2_BASE_ADDR, 0, 4},
-	{USDHC3_BASE_ADDR},
-	{USDHC4_BASE_ADDR},
-};
-
-#define USDHC3_CD_GPIO	IMX_GPIO_NR(2, 10)
-#define USDHC3_PWR_GPIO	IMX_GPIO_NR(2, 11)
-#define USDHC4_CD_GPIO	IMX_GPIO_NR(6, 21)
-
 int board_mmc_get_env_dev(int devno)
 {
-	return devno - 1;
-}
-
-int board_mmc_getcd(struct mmc *mmc)
-{
-	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
-	int ret = 0;
-
-	switch (cfg->esdhc_base) {
-	case USDHC2_BASE_ADDR:
-		ret = 1; /* Assume uSDHC2 is always present */
-		break;
-	case USDHC3_BASE_ADDR:
-		ret = !gpio_get_value(USDHC3_CD_GPIO);
-		break;
-	case USDHC4_BASE_ADDR:
-		ret = !gpio_get_value(USDHC4_CD_GPIO);
-		break;
-	}
-
-	return ret;
-}
-
-int board_mmc_init(bd_t *bis)
-{
-#ifndef CONFIG_SPL_BUILD
-	int i, ret;
-
-	/*
-	 * According to the board_mmc_init() the following map is done:
-	 * (U-Boot device node)    (Physical Port)
-	 * mmc0                    USDHC2
-	 * mmc1                    USDHC3
-	 * mmc2                    USDHC4
-	 */
-	for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
-		switch (i) {
-		case 0:
-			imx_iomux_v3_setup_multiple_pads(
-				usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
-			usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
-			break;
-		case 1:
-			imx_iomux_v3_setup_multiple_pads(
-				usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
-			gpio_direction_input(USDHC3_CD_GPIO);
-			gpio_direction_output(USDHC3_PWR_GPIO, 1);
-			usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
-			break;
-		case 2:
-			imx_iomux_v3_setup_multiple_pads(
-				usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
-			gpio_direction_input(USDHC4_CD_GPIO);
-			usdhc_cfg[2].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
-			break;
-		default:
-			printf("Warning: you configured more USDHC controllers"
-				"(%d) than supported by the board\n", i + 1);
-			return -EINVAL;
-			}
-
-			ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
-			if (ret) {
-				printf("Warning: failed to initialize mmc dev %d\n", i);
-				return ret;
-			}
-	}
-
-	return 0;
-#else
-	struct src *src_regs = (struct src *)SRC_BASE_ADDR;
-	u32 val;
-	u32 port;
-
-	val = readl(&src_regs->sbmr1);
-
-	if ((val & 0xc0) != 0x40) {
-		printf("Not boot from USDHC!\n");
-		return -EINVAL;
-	}
-
-	port = (val >> 11) & 0x3;
-	printf("port %d\n", port);
-	switch (port) {
-	case 1:
-		imx_iomux_v3_setup_multiple_pads(
-			usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
-		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
-		usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
-		break;
-	case 2:
-		imx_iomux_v3_setup_multiple_pads(
-			usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
-		gpio_direction_input(USDHC3_CD_GPIO);
-		gpio_direction_output(USDHC3_PWR_GPIO, 1);
-		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
-		usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
-		break;
-	case 3:
-		imx_iomux_v3_setup_multiple_pads(
-			usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
-		gpio_direction_input(USDHC4_CD_GPIO);
-		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
-		usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR;
-		break;
-	}
-
-	gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
-	return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
-#endif
+	return devno;
 }
 
 #ifdef CONFIG_FSL_QSPI
@@ -509,11 +283,13 @@
 	imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads));
 
 	/* Reset the LCD */
+	gpio_request(IMX_GPIO_NR(3, 27), "lcd_rst");
 	gpio_direction_output(IMX_GPIO_NR(3, 27) , 0);
 	udelay(500);
 	gpio_direction_output(IMX_GPIO_NR(3, 27) , 1);
 
 	/* Set Brightness to high */
+	gpio_request(IMX_GPIO_NR(6, 4), "lcd_bright");
 	gpio_direction_output(IMX_GPIO_NR(6, 4) , 1);
 
 	return 0;
@@ -525,9 +301,18 @@
 	/* Address of boot parameters */
 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 
-#ifdef CONFIG_SYS_I2C_MXC
-	setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
-#endif
+	/*
+	 * Because kernel set WDOG_B mux before pad with the common pinctrl
+	 * framwork now and wdog reset will be triggered once set WDOG_B mux
+	 * with default pad setting, we set pad setting here to workaround this.
+	 * Since imx_iomux_v3_setup_pad also set mux before pad setting, we set
+	 * as GPIO mux firstly here to workaround it.
+	 */
+	imx_iomux_v3_setup_pad(wdog_b_pad);
+
+	/* Active high for ncp692 */
+	gpio_request(IMX_GPIO_NR(4, 16), "ncp692_en");
+	gpio_direction_output(IMX_GPIO_NR(4, 16), 1);
 
 #ifdef CONFIG_FSL_QSPI
 	board_qspi_init();
@@ -566,6 +351,117 @@
 #include <spl.h>
 #include <asm/arch/mx6-ddr.h>
 
+static struct fsl_esdhc_cfg usdhc_cfg[3] = {
+	{USDHC2_BASE_ADDR, 0, 4},
+	{USDHC3_BASE_ADDR},
+	{USDHC4_BASE_ADDR},
+};
+
+#define USDHC3_CD_GPIO	IMX_GPIO_NR(2, 10)
+#define USDHC3_PWR_GPIO	IMX_GPIO_NR(2, 11)
+#define USDHC4_CD_GPIO	IMX_GPIO_NR(6, 21)
+
+static iomux_v3_cfg_t const usdhc2_pads[] = {
+	MX6_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const usdhc3_pads[] = {
+	MX6_PAD_SD3_CLK__USDHC3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD3_CMD__USDHC3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD3_DATA0__USDHC3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD3_DATA1__USDHC3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD3_DATA2__USDHC3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD3_DATA3__USDHC3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD3_DATA4__USDHC3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD3_DATA5__USDHC3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD3_DATA6__USDHC3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD3_DATA7__USDHC3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+
+	/* CD pin */
+	MX6_PAD_KEY_COL0__GPIO2_IO_10 | MUX_PAD_CTRL(NO_PAD_CTRL),
+
+	/* RST_B, used for power reset cycle */
+	MX6_PAD_KEY_COL1__GPIO2_IO_11 | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const usdhc4_pads[] = {
+	MX6_PAD_SD4_CLK__USDHC4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD4_CMD__USDHC4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD4_DATA0__USDHC4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD4_DATA1__USDHC4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD4_DATA2__USDHC4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD4_DATA3__USDHC4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD4_DATA7__GPIO6_IO_21 | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+int board_mmc_init(bd_t *bis)
+{
+	struct src *src_regs = (struct src *)SRC_BASE_ADDR;
+	u32 val;
+	u32 port;
+
+	val = readl(&src_regs->sbmr1);
+
+	if ((val & 0xc0) != 0x40) {
+		printf("Not boot from USDHC!\n");
+		return -EINVAL;
+	}
+
+	port = (val >> 11) & 0x3;
+	printf("port %d\n", port);
+	switch (port) {
+	case 1:
+		imx_iomux_v3_setup_multiple_pads(
+			usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
+		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+		usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
+		break;
+	case 2:
+		imx_iomux_v3_setup_multiple_pads(
+			usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
+		gpio_direction_input(USDHC3_CD_GPIO);
+		gpio_direction_output(USDHC3_PWR_GPIO, 1);
+		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+		usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
+		break;
+	case 3:
+		imx_iomux_v3_setup_multiple_pads(
+			usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
+		gpio_direction_input(USDHC4_CD_GPIO);
+		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
+		usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR;
+		break;
+	}
+
+	gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
+	return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
+}
+
+int board_mmc_getcd(struct mmc *mmc)
+{
+	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+	int ret = 0;
+
+	switch (cfg->esdhc_base) {
+	case USDHC2_BASE_ADDR:
+		ret = 1; /* Assume uSDHC2 is always present */
+		break;
+	case USDHC3_BASE_ADDR:
+		ret = !gpio_get_value(USDHC3_CD_GPIO);
+		break;
+	case USDHC4_BASE_ADDR:
+		ret = !gpio_get_value(USDHC4_CD_GPIO);
+		break;
+	}
+
+	return ret;
+}
+
 const struct mx6sx_iomux_ddr_regs mx6_ddr_ioregs = {
 	.dram_dqm0 = 0x00000028,
 	.dram_dqm1 = 0x00000028,
diff --git a/board/gateworks/gw_ventana/eeprom.c b/board/gateworks/gw_ventana/eeprom.c
index 2c07a84..a435dd9 100644
--- a/board/gateworks/gw_ventana/eeprom.c
+++ b/board/gateworks/gw_ventana/eeprom.c
@@ -119,7 +119,7 @@
 	{ /* Sentinel */ }
 };
 
-#ifdef CONFIG_CMD_EECONFIG
+#if defined(CONFIG_CMD_EECONFIG) && !defined(CONFIG_SPL_BUILD)
 static struct ventana_eeprom_config *get_config(const char *name)
 {
 	struct ventana_eeprom_config *cfg = econfig;
@@ -135,7 +135,7 @@
 static u8 econfig_bytes[sizeof(ventana_info.config)];
 static int econfig_init = -1;
 
-int do_econfig(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int do_econfig(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	struct ventana_eeprom_config *cfg;
 	struct ventana_board_info *info = &ventana_info;
diff --git a/board/gateworks/gw_ventana/gsc.c b/board/gateworks/gw_ventana/gsc.c
index 68b1ddb..f2a01b8 100644
--- a/board/gateworks/gw_ventana/gsc.c
+++ b/board/gateworks/gw_ventana/gsc.c
@@ -172,7 +172,7 @@
 	return 1;
 }
 
-#ifdef CONFIG_CMD_GSC
+#if defined(CONFIG_CMD_GSC) && !defined(CONFIG_SPL_BUILD)
 static int do_gsc_sleep(cmd_tbl_t *cmdtp, int flag, int argc,
 			char * const argv[])
 {
diff --git a/board/qualcomm/dragonboard410c/Makefile b/board/qualcomm/dragonboard410c/Makefile
index cd67808..5082383 100644
--- a/board/qualcomm/dragonboard410c/Makefile
+++ b/board/qualcomm/dragonboard410c/Makefile
@@ -5,4 +5,5 @@
 #
 
 obj-y	:= dragonboard410c.o
+obj-y	+= lowlevel_init.o
 extra-y += head.o
diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c
index 848e278..9a60095 100644
--- a/board/qualcomm/dragonboard410c/dragonboard410c.c
+++ b/board/qualcomm/dragonboard410c/dragonboard410c.c
@@ -10,12 +10,27 @@
 #include <dm.h>
 #include <usb.h>
 #include <asm/gpio.h>
+#include <fdt_support.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/* pointer to the device tree ammended by the firmware */
+extern void *fw_dtb;
+
+void *board_fdt_blob_setup(void)
+{
+	if (fdt_magic(fw_dtb) != FDT_MAGIC) {
+		printf("Firmware provided invalid dtb!\n");
+		return NULL;
+	}
+
+	return fw_dtb;
+}
+
 int dram_init(void)
 {
 	gd->ram_size = PHYS_SDRAM_1_SIZE;
+
 	return 0;
 }
 
@@ -27,7 +42,6 @@
 	return 0;
 }
 
-
 int board_prepare_usb(enum usb_init_type type)
 {
 	static struct udevice *pmic_gpio;
@@ -96,11 +110,6 @@
 	return 0;
 }
 
-int board_init(void)
-{
-	return 0;
-}
-
 /* Check for vol- button - if pressed - stop autoboot */
 int misc_init_r(void)
 {
@@ -134,3 +143,48 @@
 
 	return 0;
 }
+
+int board_init(void)
+{
+	return 0;
+}
+
+int ft_board_setup(void *blob, bd_t *bd)
+{
+	int offset, len, i;
+	const char *mac;
+	struct {
+		const char *compatible;
+		const char *property;
+	} fix[] = {
+		[0] = {
+			/* update the kernel's dtb with wlan mac */
+			.compatible = "qcom,wcnss-wlan",
+			.property = "local-mac-address",
+		},
+		[1] = {
+			/* update the kernel's dtb with bt mac */
+			.compatible = "qcom,wcnss-bt",
+			.property = "local-bd-address",
+		},
+	};
+
+	for (i = 0; i < sizeof(fix) / sizeof(fix[0]); i++) {
+		offset = fdt_node_offset_by_compatible(gd->fdt_blob, -1,
+						       fix[i].compatible);
+		if (offset < 0)
+			continue;
+
+		mac = fdt_getprop(gd->fdt_blob, offset, fix[i].property, &len);
+		if (mac)
+			do_fixup_by_compat(blob, fix[i].compatible,
+					   fix[i].property, mac, ARP_HLEN, 1);
+	}
+
+	return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+	psci_system_reset();
+}
diff --git a/board/qualcomm/dragonboard410c/lowlevel_init.S b/board/qualcomm/dragonboard410c/lowlevel_init.S
new file mode 100644
index 0000000..15b2d0c
--- /dev/null
+++ b/board/qualcomm/dragonboard410c/lowlevel_init.S
@@ -0,0 +1,28 @@
+/*
+ * (C) Copyright 2016
+ * Cédric Schieli <cschieli@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+
+.align 8
+.global fw_dtb
+fw_dtb:
+	.dword 0x0
+
+/*
+ * Routine: save_boot_params (called after reset from start.S)
+ * Description: save ATAG/FDT address provided by the firmware at boot time
+ */
+
+.global save_boot_params
+save_boot_params:
+
+	/* The firmware provided ATAG/FDT address can be found in r2/x0 */
+	adr	x8, fw_dtb
+	str	x0, [x8]
+
+	/* Returns */
+	b	save_boot_params_ret
diff --git a/board/qualcomm/dragonboard820c/Kconfig b/board/qualcomm/dragonboard820c/Kconfig
new file mode 100644
index 0000000..aff9af5
--- /dev/null
+++ b/board/qualcomm/dragonboard820c/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_DRAGONBOARD820C
+
+config SYS_BOARD
+	default "dragonboard820c"
+
+config SYS_VENDOR
+	default "qualcomm"
+
+config SYS_SOC
+	default "apq8096"
+
+config SYS_CONFIG_NAME
+	default "dragonboard820c"
+
+endif
diff --git a/board/qualcomm/dragonboard820c/MAINTAINERS b/board/qualcomm/dragonboard820c/MAINTAINERS
new file mode 100644
index 0000000..a157033
--- /dev/null
+++ b/board/qualcomm/dragonboard820c/MAINTAINERS
@@ -0,0 +1,6 @@
+DRAGONBOARD820C BOARD
+M:	Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
+S:	Maintained
+F:	board/qualcomm/dragonboard820c/
+F:	include/configs/dragonboard820c.h
+F:	configs/dragonboard820c_defconfig
diff --git a/board/qualcomm/dragonboard820c/Makefile b/board/qualcomm/dragonboard820c/Makefile
new file mode 100644
index 0000000..a1ce4b2
--- /dev/null
+++ b/board/qualcomm/dragonboard820c/Makefile
@@ -0,0 +1,8 @@
+#
+# (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@gmail.com>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	:= dragonboard820c.o
+extra-y += head.o
diff --git a/board/qualcomm/dragonboard820c/dragonboard820c.c b/board/qualcomm/dragonboard820c/dragonboard820c.c
new file mode 100644
index 0000000..6040787
--- /dev/null
+++ b/board/qualcomm/dragonboard820c/dragonboard820c.c
@@ -0,0 +1,163 @@
+/*
+ * Board init file for Dragonboard 820C
+ *
+ * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/arch/sysmap-apq8096.h>
+#include <linux/arm-smccc.h>
+#include <linux/psci.h>
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <asm/psci.h>
+#include <asm/gpio.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+	gd->ram_size = PHYS_SDRAM_SIZE;
+
+	return 0;
+}
+
+int dram_init_banksize(void)
+{
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+	gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+	gd->bd->bi_dram[1].size  = PHYS_SDRAM_2_SIZE;
+
+	return 0;
+}
+
+static void sdhci_power_init(void)
+{
+	const u32 TLMM_PULL_MASK = 0x3;
+	const u32 TLMM_HDRV_MASK = 0x7;
+
+	struct tlmm_cfg {
+		u32 bit;  /* bit in the register      */
+		u8 mask;  /* mask clk/dat/cmd control */
+		u8 val;
+	};
+
+	/* bit offsets in the sdc tlmm register */
+	enum {  SDC1_DATA_HDRV = 0,
+		SDC1_CMD_HDRV  = 3,
+		SDC1_CLK_HDRV  = 6,
+		SDC1_DATA_PULL = 9,
+		SDC1_CMD_PULL  = 11,
+		SDC1_CLK_PULL  = 13,
+		SDC1_RCLK_PULL = 15,
+	};
+
+	enum {  TLMM_PULL_DOWN	 = 0x1,
+		TLMM_PULL_UP   = 0x3,
+		TLMM_NO_PULL   = 0x0,
+	};
+
+	enum {  TLMM_CUR_VAL_10MA = 0x04,
+		TLMM_CUR_VAL_16MA = 0x07,
+	};
+	int i;
+
+	/* drive strength configs for sdhc pins */
+	const struct tlmm_cfg hdrv[] = {
+	
+		{ SDC1_CLK_HDRV,  TLMM_CUR_VAL_16MA, TLMM_HDRV_MASK, },
+		{ SDC1_CMD_HDRV,  TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK, },
+		{ SDC1_DATA_HDRV, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK, },
+	};
+
+	/* pull configs for sdhc pins */
+	const struct tlmm_cfg pull[] = {
+	
+		{ SDC1_CLK_PULL,  TLMM_NO_PULL, TLMM_PULL_MASK, },
+		{ SDC1_CMD_PULL,  TLMM_PULL_UP, TLMM_PULL_MASK, },
+		{ SDC1_DATA_PULL, TLMM_PULL_UP, TLMM_PULL_MASK, },
+	};
+
+	const struct tlmm_cfg rclk[] = {
+	
+		{ SDC1_RCLK_PULL, TLMM_PULL_DOWN, TLMM_PULL_MASK,},
+	};
+
+	for (i = 0; i < ARRAY_SIZE(hdrv); i++)
+		clrsetbits_le32(SDC1_HDRV_PULL_CTL_REG,
+				hdrv[i].mask << hdrv[i].bit,
+			hdrv[i].val  << hdrv[i].bit);
+
+	for (i = 0; i < ARRAY_SIZE(pull); i++)
+		clrsetbits_le32(SDC1_HDRV_PULL_CTL_REG,
+				pull[i].mask << pull[i].bit,
+			pull[i].val  << pull[i].bit);
+
+	for (i = 0; i < ARRAY_SIZE(rclk); i++)
+		clrsetbits_le32(SDC1_HDRV_PULL_CTL_REG,
+				rclk[i].mask << rclk[i].bit,
+			rclk[i].val  << rclk[i].bit);
+}
+
+static void show_psci_version(void)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(ARM_PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0, 0, 0, 0, 0, &res);
+
+	printf("PSCI:  v%ld.%ld\n",
+	       PSCI_VERSION_MAJOR(res.a0),
+		PSCI_VERSION_MINOR(res.a0));
+}
+
+int board_init(void)
+{
+	sdhci_power_init();
+	show_psci_version();
+
+	return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+	psci_system_reset();
+}
+
+/* Check for vol- button - if pressed - stop autoboot */
+int misc_init_r(void)
+{
+	struct udevice *pon;
+	struct gpio_desc resin;
+	int node, ret;
+
+	ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8994_pon@800", &pon);
+	if (ret < 0) {
+		printf("Failed to find PMIC pon node. Check device tree\n");
+		return 0;
+	}
+
+	node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
+				  "key_vol_down");
+	if (node < 0) {
+		printf("Failed to find key_vol_down node. Check device tree\n");
+		return 0;
+	}
+
+	if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
+				       &resin, 0)) {
+		printf("Failed to request key_vol_down button.\n");
+		return 0;
+	}
+
+	if (dm_gpio_get_value(&resin)) {
+		env_set("bootdelay", "-1");
+		printf("Power button pressed - dropping to console.\n");
+	}
+
+	return 0;
+}
diff --git a/board/qualcomm/dragonboard820c/head.S b/board/qualcomm/dragonboard820c/head.S
new file mode 100644
index 0000000..06d82d5
--- /dev/null
+++ b/board/qualcomm/dragonboard820c/head.S
@@ -0,0 +1,34 @@
+/*
+ * ARM64 header for proper chain-loading with Little Kernel.
+ *
+ * Little Kernel shipped with Dragonboard820C boots standard Linux images for
+ * ARM64. This file adds header that is required to boot U-Boot properly.
+ *
+ * For details see:
+ * https://www.kernel.org/doc/Documentation/arm64/booting.txt
+ *
+ * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+
+/*
+ *   per document in linux/Doc/arm64/booting.text
+ */
+.global _arm64_header
+_arm64_header:
+	b _start
+	.word 0
+	.quad   CONFIG_SYS_TEXT_BASE-PHYS_SDRAM_1 /* Image load offset, LE */
+	.quad   0    /* Effective size of kernel image, little-endian */
+	.quad   0    /* kernel flags, little-endian */
+	.quad   0    /* reserved */
+	.quad   0    /* reserved */
+	.quad   0    /* reserved */
+	.byte   0x41 /* Magic number, "ARM\x64" */
+	.byte   0x52
+	.byte   0x4d
+	.byte   0x64
+	.word   0    /* reserved (used for PE COFF offset) */
diff --git a/board/qualcomm/dragonboard820c/readme.txt b/board/qualcomm/dragonboard820c/readme.txt
new file mode 100644
index 0000000..1f310b3
--- /dev/null
+++ b/board/qualcomm/dragonboard820c/readme.txt
@@ -0,0 +1,459 @@
+#
+# (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+================================================================================
+             What is working (enough to boot a distro from SD card)
+================================================================================
+   - UART
+   - SD card
+   - PSCI reset
+   - Environment in EXT4 partition 1 in SD card (check defconfig for details)
+         dont forget to insert the card in the SD slot before booting if you
+         are going to make mods to the environment
+
+================================================================================
+                     Build & Run instructions
+================================================================================
+
+1) Install mkbootimg and dtbTool from Codeaurora:
+
+   git://codeaurora.org/quic/kernel/skales
+   commit 8492547e404e969262d9070dee9bdd15668bb70f worked for me.
+
+2) Setup CROSS_COMPILE to aarch64 compiler or if you use ccache just do
+   CROSS_COMPILE="ccache aarch64-linux-gnu-"
+
+3) cd to the u-boot tree
+
+  $ make dragonboard820c_config
+  $ make -j `nproc`
+
+4) generate fake, empty ramdisk (can have 0 bytes)
+
+   $ touch rd
+
+5) Generate qualcomm device tree table with dtbTool
+
+   $ dtbTool -o dt.img arch/arm/dts
+
+6) Generate Android boot image with mkbootimg:
+
+   $ mkbootimg --kernel=u-boot-dtb.bin             \
+               --output=u-boot.img                 \
+               --dt=dt.img                         \
+               --pagesize 4096                     \
+               --base 0x80000000                   \
+               --ramdisk=rd                        \
+               --cmdline=""
+
+7) Reboot the board into fastboot mode
+   - plug the board micro-usb to your laptop usb host.
+   - reboot the board with vol- button pressed
+
+8) Boot the uboot image using fastboot
+
+   $ fastboot boot u-boot.img
+
+   or flash it to the UFS drive boot partition:
+
+   $ fastboot flash boot u-boot.img
+   $ fastboot reboot
+
+
+================================================================================
+      To boot a linux kernel from SDHCI with the ROOTFS on an NFS share:
+================================================================================
+
+1) create an EXT4 partition on the SD card (must be partition #1)
+
+2) build the kernel image and dtb  (documented extensively somewhere else)
+
+3) copy the drivers to the NFS partition (ie: 192.168.1.2 /exports/db820c-rootfs)
+
+4) add the u-boot headers to the image:
+
+    $ mkimage -A arm64                                     \
+              -O linux                                     \
+              -C none                                      \
+              -T kernel                                    \
+              -a 0x80080000                                \
+              -e 0x80080000                                \
+              -n Dragonboard820c                           \
+              -d $kernel/arch/arm64/boot/Image             \
+              uImage
+
+5) copy the generated uImage and the device tree binary to the SD card EXT4
+   partition
+
+    $ cp uImage /mnt/boot/
+    $ cp apq8096-db820c.dtb /mnt/boot/
+
+6) on the SD card create /extlinux/extlinux.conf  as follows:
+
+   default nfs
+   prompt 1
+   timeout 10
+
+   LABEL nfs
+      MENU NFS entry
+      LINUX /uImage
+      FDT /apq8096-db820c.dtb
+      APPEND root=/dev/nfs rw                                         \
+             nfsroot=192.168.1.2:/exports/db829c-rootfs,v3,tcp        \
+             rootwait                                                 \
+             ip=dhcp consoleblank=0                                   \
+             console=tty0                                             \
+             console=ttyMSM0,115200n8                                 \
+             earlyprintk earlycon=msm_serial_dm,0x75b0000             \
+             androidboot.bootdevice=624000.ufshc                      \
+             androidboot.verifiedbootstate=orange                     \
+             androidboot.ver0
+
+7) remove the SD card from the laptop and insert it back to the db820 board.
+   the SD card EXT4 partition#1 should contain:
+      /uImage
+      /apq8096-db820c.dtb
+      /extlinux/extlinux.conf
+
+8) reboot the db820 board
+
+================================================================================
+                    Successful boot sequence
+================================================================================
+
+Format: Log Type - Time(microsec) - Message - Optional Info
+Log Type: B - Since Boot(Power On Reset),  D - Delta,  S - Statistic
+S - QC_IMAGE_VERSION_STRING=BOOT.XF.1.0-00301
+S - IMAGE_VARIANT_STRING=M8996LAB
+S - OEM_IMAGE_VERSION_STRING=crm-ubuntu68
+S - Boot Interface: UFS
+S - Secure Boot: Off
+S - Boot Config @ 0x00076044 = 0x000001c9
+S - JTAG ID @ 0x000760f4 = 0x4003e0e1
+S - OEM ID @ 0x000760f8 = 0x00000000
+S - Serial Number @ 0x00074138 = 0x2e8844ce
+S - OEM Config Row 0 @ 0x00074188 = 0x0000000000000000
+S - OEM Config Row 1 @ 0x00074190 = 0x0000000000000000
+S - Feature Config Row 0 @ 0x000741a0 = 0x0050000010000100
+S - Feature Config Row 1 @ 0x000741a8 = 0x00fff00001ffffff
+S - Core 0 Frequency, 1228 MHz
+B -         0 - PBL, Start
+B -     10412 - bootable_media_detect_entry, Start
+B -     47480 - bootable_media_detect_success, Start
+B -     47481 - elf_loader_entry, Start
+B -     49027 - auth_hash_seg_entry, Start
+B -     49129 - auth_hash_seg_exit, Start
+B -     82403 - elf_segs_hash_verify_entry, Start
+B -     84905 - PBL, End
+B -     86955 - SBL1, Start
+B -    182969 - usb: hs_phy_nondrive_start
+B -    183305 - usb: PLL lock success - 0x3
+B -    186294 - usb: hs_phy_nondrive_finish
+B -    190442 - boot_flash_init, Start
+D -        30 - boot_flash_init, Delta
+B -    197548 - sbl1_ddr_set_default_params, Start
+D -        30 - sbl1_ddr_set_default_params, Delta
+B -    205509 - boot_config_data_table_init, Start
+D -    200659 - boot_config_data_table_init, Delta - (60 Bytes)
+B -    410713 - CDT Version:3,Platform ID:24,Major ID:1,Minor ID:0,Subtype:0
+B -    415410 - Image Load, Start
+D -     22570 - PMIC Image Loaded, Delta - (37272 Bytes)
+B -    437980 - pm_device_init, Start
+B -    443744 - PON REASON:PM0:0x200000061 PM1:0x200000021
+B -    480161 - PM_SET_VAL:Skip
+D -     40016 - pm_device_init, Delta
+B -    482083 - pm_driver_init, Start
+D -      2928 - pm_driver_init, Delta
+B -    488671 - pm_sbl_chg_init, Start
+D -        91 - pm_sbl_chg_init, Delta
+B -    495442 - vsense_init, Start
+D -         0 - vsense_init, Delta
+B -    505171 - Pre_DDR_clock_init, Start
+D -       396 - Pre_DDR_clock_init, Delta
+B -    509045 - ddr_initialize_device, Start
+B -    512766 - 8996 v3.x detected, Max frequency = 1.8 GHz
+B -    522373 - ddr_initialize_device, Delta
+B -    522404 - DDR ID, Rank 0, Rank 1, 0x6, 0x300, 0x300
+B -    526247 - Basic DDR tests done
+B -    594994 - clock_init, Start
+D -       274 - clock_init, Delta
+B -    598349 - Image Load, Start
+D -      4331 - QSEE Dev Config Image Loaded, Delta - (46008 Bytes)
+B -    603808 - Image Load, Start
+D -      5338 - APDP Image Loaded, Delta - (0 Bytes)
+B -    612409 - usb: UFS Serial - 2f490ecf
+B -    616801 - usb: fedl, vbus_low
+B -    620431 - Image Load, Start
+D -     55418 - QSEE Image Loaded, Delta - (1640572 Bytes)
+B -    675849 - Image Load, Start
+D -      2013 - SEC Image Loaded, Delta - (4096 Bytes)
+B -    683413 - sbl1_efs_handle_cookies, Start
+D -       457 - sbl1_efs_handle_cookies, Delta
+B -    691892 - Image Load, Start
+D -     14396 - QHEE Image Loaded, Delta - (254184 Bytes)
+B -    706319 - Image Load, Start
+D -     14061 - RPM Image Loaded, Delta - (223900 Bytes)
+B -    721111 - Image Load, Start
+D -      3233 - STI Image Loaded, Delta - (0 Bytes)
+B -    727913 - Image Load, Start
+D -     34709 - APPSBL Image Loaded, Delta - (748716 Bytes)
+B -    762713 - SBL1, End
+D -    680028 - SBL1, Delta
+S - Flash Throughput, 94000 KB/s  (2959024 Bytes,  31250 us)
+S - DDR Frequency, 1017 MHz
+Android Bootloader - UART_DM Initialized!!!
+
+[0] BUILD_VERSION=
+[0] BUILD_DATE=16:07:51 - Nov 17 2017
+[0] welcome to lk
+[10] platform_init()
+[10] target_init()
+[10] RPM GLink Init
+[10] Opening RPM Glink Port success
+[10] Opening SSR Glink Port success
+[20] Glink Connection between APPS and RPM established
+[20] Glink Connection between APPS and RPM established
+[40] UFS init success
+[80] Qseecom Init Done in Appsbl
+[80] secure app region addr=0x86600000 size=0x2200000[90] TZ App region notif returned with status:0 addr:86600000 size:35651584
+[100] TZ App log region register returned with status:0 addr:916d4000 size:4096
+[100] Qseecom TZ Init Done in Appsbl
+[120] Loading cmnlib done
+[120] qseecom_start_app: Loading app keymaster for the first time
+[150] <8>keymaster: "\"KEYMASTER Init \""
+[160] Selected panel: none
+Skip panel configuration
+[160] pm8x41_get_is_cold_boot: cold boot
+[170] boot_verifier: Device is in ORANGE boot state.
+[180] Device is unlocked! Skipping verification...
+[180] Loading (boot) image (348160): start
+[190] Loading (boot) image (348160): done
+[190] use_signed_kernel=1, is_unlocked=1, is_tampered=0.
+[200] Your device has been unlocked and cant be trusted.
+Wait for 5 seconds before proceeding
+
+[5200] mdtp: mdtp_img loaded
+[5210] mdtp: is_test_mode: test mode is set to 1
+[5210] mdtp: read_metadata: SUCCESS
+[5230] LK SEC APP Handle: 0x1
+[5230] Return value from recv_data: 14
+[5240] Return value from recv_data: 14
+[5250] Return value from recv_data: 14
+[5260] DTB Total entry: 1, DTB version: 3
+[5260] Using DTB entry 0x00000123/00000000/0x00000018/0 for device 0x00000123/00030001/0x00010018/0
+[5270] cmdline:  androidboot.bootdevice=624000.ufshc androidboot.verifiedbootstate=orange androidboot.veritymode=enforcing androidboot.serialno=2f490ecf androidboot.baseband=apq mdss_mdp.panel=0
+[5290] Updating device tree: start
+[5290] Updating device tree: done
+[5290] Return value from recv_data: 14
+[5300] RPM GLINK UnInit
+[5300] Qseecom De-Init Done in Appsbl
+[5300] booting linux @ 0x80080000, ramdisk @ 0x82200000 (0), tags/device tree @ 0x82000000
+[5310] Jumping to kernel via monitor
+
+U-Boot 2017.11-00145-ge895117 (Nov 29 2017 - 10:04:06 +0100)
+Qualcomm-DragonBoard 820C
+
+DRAM:  3 GiB
+PSCI:  v1.0
+MMC:   sdhci@74a4900: 0
+In:    serial@75b0000
+Out:   serial@75b0000
+Err:   serial@75b0000
+Net:   Net Initialization Skipped
+No ethernet found.
+Hit any key to stop autoboot:  0
+switch to partitions #0, OK
+mmc0 is current device
+Scanning mmc 0:1...
+Found /extlinux/extlinux.conf
+Retrieving file: /extlinux/extlinux.conf
+433 bytes read in 71 ms (5.9 KiB/s)
+1:      nfs root
+
+Retrieving file: /uImage
+19397184 bytes read in 2024 ms (9.1 MiB/s)
+append: root=/dev/nfs rw nfsroot=192.168.1.2:/db820c/rootfs,v3,tcp rootwait ip=dhcp consoleblank=0 console=tty0 console=ttyMSM0,115200n8 earlyprintk earlycon=msm_serial_dm,0x75b0000 androidboot.bootdevice=624000.ufshc androidboot.verifiedbootstate=orange androidboot.ver0
+
+Retrieving file: /apq8096-db820c.dtb
+38134 bytes read in 37 ms (1005.9 KiB/s)
+
+## Booting kernel from Legacy Image at 95000000 ...
+   Image Name:   Dragonboard820c
+   Image Type:   AArch64 Linux Kernel Image (uncompressed)
+   Data Size:    19397120 Bytes = 18.5 MiB
+   Load Address: 80080000
+   Entry Point:  80080000
+   Verifying Checksum ... OK
+## Flattened Device Tree blob at 93000000
+   Booting using the fdt blob at 0x93000000
+   Loading Kernel Image ... OK
+   Using Device Tree in place at 0000000093000000, end 000000009300c4f5
+
+Starting kernel ...
+
+[    0.000000] Booting Linux on physical CPU 0x0
+[    0.000000] Linux version 4.11.3-30039-g5a922a1 (jramirez@igloo) (gcc version 6.3.1 20170404 (Linaro GCC 6.3-2017.05) ) #1 SMP PREEMPT Wed Oct 18 10:21:11 CEST 2017
+[    0.000000] Boot CPU: AArch64 Processor [511f2112]
+[    0.000000] earlycon: msm_serial_dm0 at MMIO 0x00000000075b0000 (options '')
+[    0.000000] bootconsole [msm_serial_dm0] enabled
+[    0.000000] efi: Getting EFI parameters from FDT:
+[    0.000000] efi: UEFI not found.
+[    0.000000] OF: reserved mem: OVERLAP DETECTED!
+[    0.000000] adsp@8ea00000 (0x000000008ea00000--0x0000000090400000) overlaps with gpu@8f200000 (0x000000008f200000--0x000000008f300000)
+[    0.000000] Reserved memory: created DMA memory pool at 0x000000008f200000, size 1 MiB
+[    0.000000] OF: reserved mem: initialized node gpu@8f200000, compatible id shared-dma-pool
+[    0.000000] Reserved memory: created DMA memory pool at 0x0000000090400000, size 8 MiB
+[    0.000000] OF: reserved mem: initialized node venus@90400000, compatible id shared-dma-pool
+[    0.000000] cma: Reserved 128 MiB at 0x00000000b8000000
+[    0.000000] NUMA: No NUMA configuration found
+[    0.000000] NUMA: Faking a node at [mem 0x0000000000000000-0x00000000bfffffff]
+[    0.000000] NUMA: Adding memblock [0x80000000 - 0x857fffff] on node 0
+[    0.000000] NUMA: Adding memblock [0x91800000 - 0xbfffffff] on node 0
+[    0.000000] NUMA: Initmem setup node 0 [mem 0x80000000-0xbfffffff]
+[    0.000000] NUMA: NODE_DATA [mem 0xb7fb6680-0xb7fb817f]
+[    0.000000] Zone ranges:
+[    0.000000]   DMA      [mem 0x0000000080000000-0x00000000bfffffff]
+[    0.000000]   Normal   empty
+[    0.000000] Movable zone start for each node
+[    0.000000] Early memory node ranges
+[    0.000000]   node   0: [mem 0x0000000080000000-0x00000000857fffff]
+[    0.000000]   node   0: [mem 0x0000000091800000-0x00000000bfffffff]
+[    0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x00000000bfffffff]
+[    0.000000] psci: probing for conduit method from DT.
+[    0.000000] psci: PSCIv1.0 detected in firmware.
+[    0.000000] psci: Using standard PSCI v0.2 function IDs
+[    0.000000] psci: MIGRATE_INFO_TYPE not supported.
+[    0.000000] percpu: Embedded 23 pages/cpu @ffff8000de9a3000 s57240 r8192 d28776 u94208
+[    0.000000] pcpu-alloc: s57240 r8192 d28776 u94208 alloc=23*4096
+[    0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3
+[    0.000000] Detected PIPT I-cache on CPU0
+[    0.000000] Built 1 zonelists in Node order, mobility grouping on.  Total pages: 720293
+[    0.000000] Policy zone: Normal
+[    0.000000] Kernel command line: root=/dev/nfs rw nfsroot=192.168.1.2:/db820c/rootfs,v3,tcp rootwait ip=dhcp consoleblank=0
+console=tty0 console=ttyMSM0,115200n8 earlyprintk earlycon=msm_serial_dm,0x75b0000 androidboot.bootdevice=624000.ufshc androidboot.verifiedbootstate=orange a
+ndroidboot.ver0
+[    0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
+[    0.000000] software IO TLB [mem 0xd3fff000-0xd7fff000] (64MB) mapped at [ffff800053fff000-ffff800057ffefff]
+[    0.000000] Memory: 2644172K/2926908K available (11196K kernel code, 1470K rwdata, 5132K rodata, 1088K init, 449K bss, 151664K reserved, 131072K cma-reser
+ved)
+[    0.000000] Virtual kernel memory layout:
+[    0.000000]     modules : 0xffff000000000000 - 0xffff000008000000   (   128 MB)
+[    0.000000]     vmalloc : 0xffff000008000000 - 0xffff7dffbfff0000   (129022 GB)
+[    0.000000]       .text : 0xffff000008080000 - 0xffff000008b70000   ( 11200 KB)
+[    0.000000]     .rodata : 0xffff000008b70000 - 0xffff000009080000   (  5184 KB)
+[    0.000000]       .init : 0xffff000009080000 - 0xffff000009190000   (  1088 KB)
+[    0.000000]       .data : 0xffff000009190000 - 0xffff0000092ffa00   (  1471 KB)
+[    0.000000]        .bss : 0xffff0000092ffa00 - 0xffff00000937014c   (   450 KB)
+[    0.000000]     fixed   : 0xffff7dfffe7fd000 - 0xffff7dfffec00000   (  4108 KB)
+[    0.000000]     PCI I/O : 0xffff7dfffee00000 - 0xffff7dffffe00000   (    16 MB)
+[    0.000000]     vmemmap : 0xffff7e0000000000 - 0xffff800000000000   (  2048 GB maximum)
+[    0.000000]               0xffff7e0000000000 - 0xffff7e00037a93c0   (    55 MB actual)
+[    0.000000]     memory  : 0xffff800000000000 - 0xffff8000dea4f000   (  3562 MB)
+[    0.000000] SLUB: HWalign=128, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
+[    0.000000] Preemptible hierarchical RCU implementation.
+[    0.000000]  Build-time adjustment of leaf fanout to 64.
+[    0.000000]  RCU restricting CPUs from NR_CPUS=64 to nr_cpu_ids=4.
+[    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=64, nr_cpu_ids=4
+[    0.000000] NR_IRQS:64 nr_irqs:64 0
+[    0.000000] GICv3: CPU0: found redistributor 0 region 0:0x0000000009c00000
+[    0.000000] GICv2m: range[mem 0x09bd0000-0x09bd0fff], SPI[544:639]
+[    0.000000] arm_arch_timer: Architected cp15 and mmio timer(s) running at 19.20MHz (virt/virt).
+[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x46d987e47, max_idle_ns: 440795202767 ns
+[    0.000002] sched_clock: 56 bits at 19MHz, resolution 52ns, wraps every 4398046511078ns
+
+[....]
+
+
+Some kernel information:
+
+root@linaro-developer:~# cat /proc/cpuinfo
+processor       : 0
+BogoMIPS        : 38.40
+Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
+CPU implementer : 0x51
+CPU architecture: 8
+CPU variant     : 0x1
+CPU part        : 0x211
+CPU revision    : 2
+
+processor       : 1
+BogoMIPS        : 38.40
+Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
+CPU implementer : 0x51
+CPU architecture: 8
+CPU variant     : 0x1
+CPU part        : 0x211
+CPU revision    : 2
+
+processor       : 2
+BogoMIPS        : 38.40
+Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
+CPU implementer : 0x51
+CPU architecture: 8
+CPU variant     : 0x1
+CPU part        : 0x205
+CPU revision    : 2
+
+processor       : 3
+BogoMIPS        : 38.40
+Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
+CPU implementer : 0x51
+CPU architecture: 8
+CPU variant     : 0x1
+CPU part        : 0x205
+CPU revision    : 2
+
+root@linaro-developer:~# uname -a
+Linux linaro-developer 4.11.3-30039-g5a922a1 #1 SMP PREEMPT Wed Oct 18 10:21:11 CEST 2017 aarch64 GNU/Linux
+
+root@linaro-developer:~# cat /proc/cmdline
+root=/dev/nfs rw nfsroot=192.168.1.2:/db820c/rootfs,v3,tcp rootwait ip=dhcp consoleblank=0 console=tty0 console=ttyMSM0,115200n8 earlyprintk earlycon=msm_serial_dm,0x75b0000 androidboot.bootdevice=624000.ufshc androidboot.verifiedbootstate=orange androidboot.ver0
+
+root@linaro-developer:~# cat /proc/meminfo
+MemTotal:        2776332 kB
+MemFree:         2593696 kB
+MemAvailable:    2561432 kB
+Buffers:               0 kB
+Cached:            94744 kB
+SwapCached:            0 kB
+Active:            43888 kB
+Inactive:          72972 kB
+Active(anon):      22968 kB
+Inactive(anon):    24616 kB
+Active(file):      20920 kB
+Inactive(file):    48356 kB
+Unevictable:           0 kB
+Mlocked:               0 kB
+SwapTotal:             0 kB
+SwapFree:              0 kB
+Dirty:                 0 kB
+Writeback:             0 kB
+AnonPages:         22120 kB
+Mapped:            29284 kB
+Shmem:             25468 kB
+Slab:              32876 kB
+SReclaimable:      12924 kB
+SUnreclaim:        19952 kB
+KernelStack:        2144 kB
+PageTables:          928 kB
+NFS_Unstable:          0 kB
+Bounce:                0 kB
+WritebackTmp:          0 kB
+CommitLimit:     1388164 kB
+Committed_AS:     204192 kB
+VmallocTotal:   135290290112 kB
+VmallocUsed:           0 kB
+VmallocChunk:          0 kB
+AnonHugePages:      2048 kB
+ShmemHugePages:        0 kB
+ShmemPmdMapped:        0 kB
+CmaTotal:         131072 kB
+CmaFree:          130356 kB
+HugePages_Total:       0
+HugePages_Free:        0
+HugePages_Rsvd:        0
+HugePages_Surp:        0
+Hugepagesize:       2048 kB
diff --git a/board/qualcomm/dragonboard820c/u-boot.lds b/board/qualcomm/dragonboard820c/u-boot.lds
new file mode 100644
index 0000000..b84b4ac
--- /dev/null
+++ b/board/qualcomm/dragonboard820c/u-boot.lds
@@ -0,0 +1,106 @@
+/*
+ * Override linker script for fastboot-readable images
+ *
+ * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
+ *
+ * Based on arch/arm/cpu/armv8/u-boot.lds (Just add header)
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+ENTRY(_arm64_header)
+SECTIONS
+{
+	. = 0x00000000;
+
+	. = ALIGN(8);
+	.text :
+	{
+		*(.__image_copy_start)
+		board/qualcomm/dragonboard820c/head.o (.text*)
+		CPUDIR/start.o (.text*)
+		*(.text*)
+	}
+
+	. = ALIGN(8);
+	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+	. = ALIGN(8);
+	.data : {
+		*(.data*)
+	}
+
+	. = ALIGN(8);
+
+	. = .;
+
+	. = ALIGN(8);
+	.u_boot_list : {
+		KEEP(*(SORT(.u_boot_list*)));
+	}
+
+	. = ALIGN(8);
+
+	.efi_runtime : {
+                __efi_runtime_start = .;
+		*(efi_runtime_text)
+		*(efi_runtime_data)
+                __efi_runtime_stop = .;
+	}
+
+	.efi_runtime_rel : {
+                __efi_runtime_rel_start = .;
+		*(.relaefi_runtime_text)
+		*(.relaefi_runtime_data)
+                __efi_runtime_rel_stop = .;
+	}
+
+	. = ALIGN(8);
+
+	.image_copy_end :
+	{
+		*(.__image_copy_end)
+	}
+
+	. = ALIGN(8);
+
+	.rel_dyn_start :
+	{
+		*(.__rel_dyn_start)
+	}
+
+	.rela.dyn : {
+		*(.rela*)
+	}
+
+	.rel_dyn_end :
+	{
+		*(.__rel_dyn_end)
+	}
+
+	_end = .;
+
+	. = ALIGN(8);
+
+	.bss_start : {
+		KEEP(*(.__bss_start));
+	}
+
+	.bss : {
+		*(.bss*)
+		 . = ALIGN(8);
+	}
+
+	.bss_end : {
+		KEEP(*(.__bss_end));
+	}
+
+	/DISCARD/ : { *(.dynsym) }
+	/DISCARD/ : { *(.dynstr*) }
+	/DISCARD/ : { *(.dynamic*) }
+	/DISCARD/ : { *(.plt*) }
+	/DISCARD/ : { *(.interp*) }
+	/DISCARD/ : { *(.gnu*) }
+}
diff --git a/board/sks-kinkel/sksimx6/Kconfig b/board/sks-kinkel/sksimx6/Kconfig
new file mode 100644
index 0000000..3efdf9d
--- /dev/null
+++ b/board/sks-kinkel/sksimx6/Kconfig
@@ -0,0 +1,11 @@
+if TARGET_SKSIMX6
+
+config SYS_BOARD
+	default "sksimx6"
+
+config SYS_VENDOR
+	default "sks-kinkel"
+
+config SYS_CONFIG_NAME
+	default "sksimx6"
+endif
diff --git a/board/sks-kinkel/sksimx6/MAINTAINERS b/board/sks-kinkel/sksimx6/MAINTAINERS
new file mode 100644
index 0000000..c1527bf
--- /dev/null
+++ b/board/sks-kinkel/sksimx6/MAINTAINERS
@@ -0,0 +1,6 @@
+SKS-Kinkel sksimx6
+M:	Stefano Babic <sbabic@denx.de>
+S:	Maintained
+F:	board/sks-kinkel/sksimx6/
+F:	include/configs/sksimx6.h
+F:	configs/sksimx6_defconfig
diff --git a/board/sks-kinkel/sksimx6/Makefile b/board/sks-kinkel/sksimx6/Makefile
new file mode 100644
index 0000000..676a007
--- /dev/null
+++ b/board/sks-kinkel/sksimx6/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier:	GPL-2.0+
+#
+obj-y  := sksimx6.o
diff --git a/board/sks-kinkel/sksimx6/sksimx6.c b/board/sks-kinkel/sksimx6/sksimx6.c
new file mode 100644
index 0000000..d50d408
--- /dev/null
+++ b/board/sks-kinkel/sksimx6/sksimx6.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2016 Stefano Babic <sbabic@denx.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/iomux.h>
+#include <asm/arch/mx6-pins.h>
+#include <linux/errno.h>
+#include <asm/gpio.h>
+#include <asm/mach-imx/iomux-v3.h>
+#include <asm/mach-imx/video.h>
+#include <mmc.h>
+#include <fsl_esdhc.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+#include <spl.h>
+#include <netdev.h>
+#include <miiphy.h>
+#include <micrel.h>
+
+#include <common.h>
+#include <malloc.h>
+#include <fuse.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
+	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |			\
+	PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |             \
+	PAD_CTL_PUS_22K_UP  | PAD_CTL_SPEED_LOW |               \
+	PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+
+#define I2C_PAD_CTRL	(PAD_CTL_PUS_100K_UP |			\
+	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |	\
+	PAD_CTL_ODE | PAD_CTL_SRE_FAST)
+
+#define ENET_PAD_CTRL		(PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+				 PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+static iomux_v3_cfg_t const uart1_pads[] = {
+	IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
+	IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
+};
+
+static iomux_v3_cfg_t const gpios_pads[] = {
+	IOMUX_PADS(PAD_EIM_A24__GPIO5_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL)),
+};
+
+static iomux_v3_cfg_t const usdhc2_pads[] = {
+	IOMUX_PADS(PAD_SD2_CLK__SD2_CLK	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD2_CMD__SD2_CMD	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_NANDF_D0__GPIO2_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL)),/* CD */
+};
+
+static iomux_v3_cfg_t const enet_pads[] = {
+	IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_ENET_MDC__ENET_MDC   | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK  |
+						MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL |
+						MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL |
+						MUX_PAD_CTRL(ENET_PAD_CTRL)),
+	IOMUX_PADS(PAD_ENET_CRS_DV__GPIO1_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL)),
+};
+
+iomux_v3_cfg_t const enet_pads1[] = {
+	/* pin 35 - 1 (PHY_AD2) on reset */
+	IOMUX_PADS(PAD_RGMII_RXC__GPIO6_IO30	| MUX_PAD_CTRL(NO_PAD_CTRL)),
+	/* pin 32 - 1 - (MODE0) all */
+	IOMUX_PADS(PAD_RGMII_RD0__GPIO6_IO25	| MUX_PAD_CTRL(NO_PAD_CTRL)),
+	/* pin 31 - 1 - (MODE1) all */
+	IOMUX_PADS(PAD_RGMII_RD1__GPIO6_IO27	| MUX_PAD_CTRL(NO_PAD_CTRL)),
+	/* pin 28 - 1 - (MODE2) all */
+	IOMUX_PADS(PAD_RGMII_RD2__GPIO6_IO28	| MUX_PAD_CTRL(NO_PAD_CTRL)),
+	/* pin 27 - 1 - (MODE3) all */
+	IOMUX_PADS(PAD_RGMII_RD3__GPIO6_IO29	| MUX_PAD_CTRL(NO_PAD_CTRL)),
+	/* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
+	IOMUX_PADS(PAD_RGMII_RX_CTL__GPIO6_IO24	| MUX_PAD_CTRL(NO_PAD_CTRL)),
+	/* pin 42 PHY nRST */
+	IOMUX_PADS(PAD_ENET_CRS_DV__GPIO1_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL)),
+};
+
+static int mx6_rgmii_rework(struct phy_device *phydev)
+{
+
+	/* min rx data delay */
+	ksz9021_phy_extended_write(phydev, MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW,
+				   0x0);
+	/* min tx data delay */
+	ksz9021_phy_extended_write(phydev, MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW,
+				   0x0);
+	/* max rx/tx clock delay, min rx/tx control */
+	ksz9021_phy_extended_write(phydev, MII_KSZ9021_EXT_RGMII_CLOCK_SKEW,
+				   0xf0f0);
+
+	return 0;
+}
+
+int board_phy_config(struct phy_device *phydev)
+{
+	mx6_rgmii_rework(phydev);
+
+	if (phydev->drv->config)
+		return phydev->drv->config(phydev);
+
+	return 0;
+}
+
+#define ENET_NRST IMX_GPIO_NR(1, 25)
+
+void setup_iomux_enet(void)
+{
+	SETUP_IOMUX_PADS(enet_pads);
+
+}
+
+int board_eth_init(bd_t *bis)
+{
+	uint32_t base = IMX_FEC_BASE;
+	struct mii_dev *bus = NULL;
+	struct phy_device *phydev = NULL;
+	int ret;
+
+	setup_iomux_enet();
+
+	bus = fec_get_miibus(base, -1);
+	if (!bus)
+		return -EINVAL;
+	/* scan phy */
+	phydev = phy_find_by_mask(bus, (0xf << CONFIG_FEC_MXC_PHYADDR),
+					PHY_INTERFACE_MODE_RGMII);
+
+	if (!phydev) {
+		ret = -EINVAL;
+		goto free_bus;
+	}
+	ret  = fec_probe(bis, -1, base, bus, phydev);
+	if (ret)
+		goto free_phydev;
+
+	return 0;
+
+free_phydev:
+	free(phydev);
+free_bus:
+	free(bus);
+	return ret;
+}
+
+int board_early_init_f(void)
+{
+	SETUP_IOMUX_PADS(uart1_pads);
+
+	return 0;
+}
+
+int board_init(void)
+{
+	/* Address of boot parameters */
+	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
+
+	/* Take in reset the ATMega processor */
+	SETUP_IOMUX_PADS(gpios_pads);
+	gpio_direction_output(IMX_GPIO_NR(5, 4), 0);
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = imx_ddr_size();
+
+	return 0;
+}
+
+struct fsl_esdhc_cfg usdhc_cfg[1] = {
+	{USDHC2_BASE_ADDR, 0},
+};
+
+#define USDHC2_CD_GPIO	IMX_GPIO_NR(2, 0)
+int board_mmc_getcd(struct mmc *mmc)
+{
+	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+	int ret = 0;
+
+	if (cfg->esdhc_base == USDHC2_BASE_ADDR)
+		ret = 1;
+
+	return ret;
+}
+
+int board_mmc_init(bd_t *bis)
+{
+	int ret;
+
+	SETUP_IOMUX_PADS(usdhc2_pads);
+	gpio_direction_input(USDHC2_CD_GPIO);
+	usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+	usdhc_cfg[0].max_bus_width = 4;
+
+	ret = fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
+	if (ret) {
+		printf("Warning: failed to initialize mmc dev \n");
+		return ret;
+	}
+
+	return 0;
+}
+
+#if defined(CONFIG_SPL_BUILD)
+#include <asm/arch/mx6-ddr.h>
+
+/*
+ * Driving strength:
+ *   0x30 == 40 Ohm
+ *   0x28 == 48 Ohm
+ */
+#define IMX6SDL_DRIVE_STRENGTH	0x230
+
+
+/* configure MX6SOLO/DUALLITE mmdc DDR io registers */
+struct mx6sdl_iomux_ddr_regs mx6sdl_ddr_ioregs = {
+	.dram_sdclk_0 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_sdclk_1 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_cas = IMX6SDL_DRIVE_STRENGTH,
+	.dram_ras = IMX6SDL_DRIVE_STRENGTH,
+	.dram_reset = IMX6SDL_DRIVE_STRENGTH,
+	.dram_sdcke0 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_sdcke1 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_sdba2 = 0x00000000,
+	.dram_sdodt0 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_sdodt1 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_sdqs0 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_sdqs1 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_sdqs2 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_sdqs3 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_sdqs4 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_sdqs5 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_sdqs6 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_sdqs7 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_dqm0 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_dqm1 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_dqm2 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_dqm3 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_dqm4 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_dqm5 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_dqm6 = IMX6SDL_DRIVE_STRENGTH,
+	.dram_dqm7 = IMX6SDL_DRIVE_STRENGTH,
+};
+
+/* configure MX6SOLO/DUALLITE mmdc GRP io registers */
+struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = {
+	.grp_ddr_type = 0x000c0000,
+	.grp_ddrmode_ctl = 0x00020000,
+	.grp_ddrpke = 0x00000000,
+	.grp_addds = IMX6SDL_DRIVE_STRENGTH,
+	.grp_ctlds = IMX6SDL_DRIVE_STRENGTH,
+	.grp_ddrmode = 0x00020000,
+	.grp_b0ds = IMX6SDL_DRIVE_STRENGTH,
+	.grp_b1ds = IMX6SDL_DRIVE_STRENGTH,
+	.grp_b2ds = IMX6SDL_DRIVE_STRENGTH,
+	.grp_b3ds = IMX6SDL_DRIVE_STRENGTH,
+	.grp_b4ds = IMX6SDL_DRIVE_STRENGTH,
+	.grp_b5ds = IMX6SDL_DRIVE_STRENGTH,
+	.grp_b6ds = IMX6SDL_DRIVE_STRENGTH,
+	.grp_b7ds = IMX6SDL_DRIVE_STRENGTH,
+};
+
+/* MT41K128M16JT-125 */
+static struct mx6_ddr3_cfg mt41k128m16jt_125 = {
+	/* quad = 1066, duallite = 800 */
+	.mem_speed = 1066,
+	.density = 2,
+	.width = 16,
+	.banks = 8,
+	.rowaddr = 14,
+	.coladdr = 10,
+	.pagesz = 2,
+	.trcd = 1375,
+	.trcmin = 4875,
+	.trasmin = 3500,
+	.SRT = 0,
+};
+
+static struct mx6_mmdc_calibration mx6dl_1g_mmdc_calib = {
+	.p0_mpwldectrl0 = 0x0043004E,
+	.p0_mpwldectrl1 = 0x003D003F,
+	.p1_mpwldectrl0 = 0x00230021,
+	.p1_mpwldectrl1 = 0x0028003E,
+	.p0_mpdgctrl0 = 0x42580250,
+	.p0_mpdgctrl1 = 0x0238023C,
+	.p1_mpdgctrl0 = 0x422C0238,
+	.p1_mpdgctrl1 = 0x02180228,
+	.p0_mprddlctl = 0x44464A46,
+	.p1_mprddlctl = 0x44464A42,
+	.p0_mpwrdlctl = 0x36343236,
+	.p1_mpwrdlctl = 0x36343230,
+};
+
+/* DDR 64bit 1GB */
+static struct mx6_ddr_sysinfo mem_qdl = {
+	.dsize = 2,
+	.cs1_mirror = 0,
+	/* config for full 4GB range so that get_mem_size() works */
+	.cs_density = 32,
+	.ncs = 1,
+	.bi_on = 1,
+	.rtt_nom = 1,
+	.rtt_wr = 1,
+	.ralat = 5,
+	.walat = 0,
+	.mif3_mode = 3,
+	.rst_to_cke = 0x23,
+	.sde_to_rst = 0x10,
+	.refsel = 1,	/* Refresh cycles at 32KHz */
+	.refr = 7,	/* 8 refresh commands per refresh cycle */
+};
+
+static void ccgr_init(void)
+{
+	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+
+	/* set the default clock gate to save power */
+	writel(0x00C03F3F, &ccm->CCGR0);
+	writel(0x0030FC03, &ccm->CCGR1);
+	writel(0x0FFFC000, &ccm->CCGR2);
+	writel(0x3FF00000, &ccm->CCGR3);
+	writel(0x00FFF300, &ccm->CCGR4);
+	writel(0xFFFFFFFF, &ccm->CCGR5);
+	writel(0x000003FF, &ccm->CCGR6);
+}
+
+static void spl_dram_init(void)
+{
+	if (is_cpu_type(MXC_CPU_MX6DL)) {
+		mt41k128m16jt_125.mem_speed = 800;
+		mem_qdl.rtt_nom = 1;
+		mem_qdl.rtt_wr = 1;
+
+		mx6sdl_dram_iocfg(64, &mx6sdl_ddr_ioregs, &mx6sdl_grp_ioregs);
+		mx6_dram_cfg(&mem_qdl, &mx6dl_1g_mmdc_calib, &mt41k128m16jt_125);
+	} else {
+		printf("Wrong CPU for this board\n");
+		return;
+	}
+
+	udelay(100);
+
+#ifdef CONFIG_MX6_DDRCAL
+
+	/* Perform DDR DRAM calibration */
+	mmdc_do_write_level_calibration(&mem_qdl);
+	mmdc_do_dqs_calibration(&mem_qdl);
+#endif
+}
+
+static void check_bootcfg(void)
+{
+	u32 val5, val6;
+
+	fuse_sense(0, 5, &val5);
+	fuse_sense(0, 6, &val6);
+	/* Check if boot from MMC */
+	if (val6 & 0x10) {
+		puts("BT_FUSE_SEL already fused, will do nothing\n");
+		return;
+	}
+	fuse_prog(0, 5, 0x00000840);
+	/* BT_FUSE_SEL */
+	fuse_prog(0, 6, 0x00000010);
+
+	do_reset(NULL, 0, 0, NULL);
+}
+
+void board_init_f(ulong dummy)
+{
+	ccgr_init();
+
+	/* setup AIPS and disable watchdog */
+	arch_cpu_init();
+
+	gpr_init();
+
+	/* iomux */
+	board_early_init_f();
+
+	/* setup GP timer */
+	timer_init();
+
+	/* UART clocks enabled and gd valid - init serial console */
+	preloader_console_init();
+
+	/* DDR initialization */
+	spl_dram_init();
+
+	/* Set fuses for new boards and reboot if not set */
+	check_bootcfg();
+
+	/* Clear the BSS. */
+	memset(__bss_start, 0, __bss_end - __bss_start);
+
+	/* load/boot image from boot device */
+	board_init_r(NULL, 0);
+}
+#endif
diff --git a/board/toradex/apalis_imx6/pf0100.c b/board/toradex/apalis_imx6/pf0100.c
index 5eaf9c0..013801e 100644
--- a/board/toradex/apalis_imx6/pf0100.c
+++ b/board/toradex/apalis_imx6/pf0100.c
@@ -10,6 +10,7 @@
 
 #include <common.h>
 #include <i2c.h>
+#include <linux/compiler.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/iomux.h>
 #include <asm/arch/mx6-pins.h>
@@ -23,7 +24,7 @@
 /*#define DEBUG */
 
 /* use Apalis GPIO1 to switch on VPGM, ON: 1 */
-static iomux_v3_cfg_t const pmic_prog_pads[] = {
+static __maybe_unused iomux_v3_cfg_t const pmic_prog_pads[] = {
 	MX6_PAD_NANDF_D4__GPIO2_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL),
 #	define PMIC_PROG_VOLTAGE IMX_GPIO_NR(2, 4)
 };
@@ -161,7 +162,8 @@
 	return programmed;
 }
 
-int pf0100_prog(void)
+#ifndef CONFIG_SPL_BUILD
+static int pf0100_prog(void)
 {
 	unsigned char bus = 1;
 	unsigned char val;
@@ -208,7 +210,7 @@
 	return CMD_RET_SUCCESS;
 }
 
-int do_pf0100_prog(cmd_tbl_t *cmdtp, int flag, int argc,
+static int do_pf0100_prog(cmd_tbl_t *cmdtp, int flag, int argc,
 		char * const argv[])
 {
 	int ret;
@@ -226,3 +228,4 @@
 	"Program the OTP fuses on the PMIC PF0100",
 	""
 );
+#endif
diff --git a/board/toradex/apalis_imx6/pf0100.h b/board/toradex/apalis_imx6/pf0100.h
index c84cab8..af1e88f 100644
--- a/board/toradex/apalis_imx6/pf0100.h
+++ b/board/toradex/apalis_imx6/pf0100.h
@@ -50,7 +50,4 @@
 /* i.e. 0: unprogrammed, 3: programmed, other: undefined prog. state */
 unsigned pmic_init(void);
 
-/* programmes OTP fuses to values required on a Toradex Apalis iMX6 */
-int pf0100_prog(void);
-
 #endif /* PF0100_H_ */
diff --git a/board/toradex/colibri_imx6/pf0100.c b/board/toradex/colibri_imx6/pf0100.c
index 6889287..62e64ab 100644
--- a/board/toradex/colibri_imx6/pf0100.c
+++ b/board/toradex/colibri_imx6/pf0100.c
@@ -23,7 +23,7 @@
 /*#define DEBUG */
 
 /* use GPIO: EXT_IO1 to switch on VPGM, ON: 1 */
-static iomux_v3_cfg_t const pmic_prog_pads[] = {
+static __maybe_unused iomux_v3_cfg_t const pmic_prog_pads[] = {
 	MX6_PAD_NANDF_D3__GPIO2_IO03 | MUX_PAD_CTRL(NO_PAD_CTRL),
 #	define PMIC_PROG_VOLTAGE IMX_GPIO_NR(2, 3)
 };
@@ -144,7 +144,8 @@
 	return programmed;
 }
 
-int pf0100_prog(void)
+#ifndef CONFIG_SPL_BUILD
+static int pf0100_prog(void)
 {
 	unsigned char bus = 1;
 	unsigned char val;
@@ -191,7 +192,7 @@
 	return CMD_RET_SUCCESS;
 }
 
-int do_pf0100_prog(cmd_tbl_t *cmdtp, int flag, int argc,
+static int do_pf0100_prog(cmd_tbl_t *cmdtp, int flag, int argc,
 		char * const argv[])
 {
 	int ret;
@@ -209,3 +210,4 @@
 	"Program the OTP fuses on the PMIC PF0100",
 	""
 );
+#endif
diff --git a/board/toradex/colibri_imx6/pf0100.h b/board/toradex/colibri_imx6/pf0100.h
index c84cab8..af1e88f 100644
--- a/board/toradex/colibri_imx6/pf0100.h
+++ b/board/toradex/colibri_imx6/pf0100.h
@@ -50,7 +50,4 @@
 /* i.e. 0: unprogrammed, 3: programmed, other: undefined prog. state */
 unsigned pmic_init(void);
 
-/* programmes OTP fuses to values required on a Toradex Apalis iMX6 */
-int pf0100_prog(void);
-
 #endif /* PF0100_H_ */
diff --git a/configs/cm_fx6_defconfig b/configs/cm_fx6_defconfig
index 33e610c..6b1c0a8 100644
--- a/configs/cm_fx6_defconfig
+++ b/configs/cm_fx6_defconfig
@@ -16,7 +16,7 @@
 CONFIG_OF_BOARD_SETUP=y
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
 CONFIG_BOOTDELAY=3
-CONFIG_BOOTCOMMAND="run distro_bootcmd; run legacy_bootcmd"
+CONFIG_BOOTCOMMAND="run findfdt; run distro_bootcmd; run legacy_bootcmd"
 CONFIG_SPL=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x80
 CONFIG_SPL_I2C_SUPPORT=y
diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig
index b71bff7..4389f52 100644
--- a/configs/dragonboard410c_defconfig
+++ b/configs/dragonboard410c_defconfig
@@ -30,7 +30,6 @@
 CONFIG_PMIC_PM8916=y
 CONFIG_MSM_SERIAL=y
 CONFIG_SPMI_MSM=y
-CONFIG_SYSRESET=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_EHCI_HCD=y
@@ -44,3 +43,8 @@
 CONFIG_USB_ETHER_MCS7830=y
 CONFIG_USB_ETHER_SMSC95XX=y
 CONFIG_OF_LIBFDT_OVERLAY=y
+CONFIG_OF_CONTROL=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_PSCI_RESET=y
+CONFIG_OF_SEPARATE=y
diff --git a/configs/dragonboard820c_defconfig b/configs/dragonboard820c_defconfig
new file mode 100644
index 0000000..8af54aa
--- /dev/null
+++ b/configs/dragonboard820c_defconfig
@@ -0,0 +1,43 @@
+CONFIG_ARM=y
+CONFIG_ARM_SMCCC=y
+CONFIG_ARCH_SNAPDRAGON=y
+CONFIG_TARGET_DRAGONBOARD820C=y
+CONFIG_IDENT_STRING="\nQualcomm-DragonBoard 820C"
+CONFIG_DEFAULT_DEVICE_TREE="dragonboard820c"
+CONFIG_USE_BOOTARGS=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_BOOTARGS="console=ttyMSM0,115200n8"
+CONFIG_SYS_PROMPT="dragonboard820c => "
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_BOOTEFI=y
+CONFIG_EFI_LOADER=y
+CONFIG_CMD_BOOTEFI_HELLO=y
+CONFIG_CMD_PXE=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_TIMER=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_PMIC=y
+CONFIG_OF_CONTROL=y
+CONFIG_MSM_SERIAL=y
+CONFIG_SPMI_MSM=y
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_MMC_SDHCI=y
+CONFIG_DM_MMC=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_PM8916=y
+CONFIG_PM8916_GPIO=y
+CONFIG_CLK=y
+CONFIG_PSCI_RESET=y
+CONFIG_ENV_IS_IN_EXT4=y
+CONFIG_ENV_EXT4_INTERFACE="mmc"
+CONFIG_ENV_EXT4_DEVICE_AND_PART="0:1"
+CONFIG_ENV_EXT4_FILE="/uboot.env"
diff --git a/configs/mx6sxsabresd_defconfig b/configs/mx6sxsabresd_defconfig
index b707322..9a27710 100644
--- a/configs/mx6sxsabresd_defconfig
+++ b/configs/mx6sxsabresd_defconfig
@@ -3,6 +3,7 @@
 CONFIG_TARGET_MX6SXSABRESD=y
 # CONFIG_CMD_BMODE is not set
 CONFIG_NXP_BOARD_REVISION=y
+CONFIG_DEFAULT_DEVICE_TREE="imx6sx-sdb"
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6sxsabresd/imximage.cfg"
 # CONFIG_CONSOLE_MUX is not set
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
@@ -27,13 +28,25 @@
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_CONTROL=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_DM_MMC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_PHYLIB=y
 CONFIG_PCI=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_IMX6=y
+CONFIG_DM_PMIC=y
+CONFIG_DM_PMIC_PFUZE100=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_PFUZE100=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
 CONFIG_USB=y
+CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
 CONFIG_VIDEO=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/mx6sxsabresd_spl_defconfig b/configs/mx6sxsabresd_spl_defconfig
index 9ab4b2f..033fc6c 100644
--- a/configs/mx6sxsabresd_spl_defconfig
+++ b/configs/mx6sxsabresd_spl_defconfig
@@ -10,6 +10,7 @@
 CONFIG_SPL_WATCHDOG_SUPPORT=y
 # CONFIG_CMD_BMODE is not set
 CONFIG_NXP_BOARD_REVISION=y
+CONFIG_DEFAULT_DEVICE_TREE="imx6sx-sdb"
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
 # CONFIG_CONSOLE_MUX is not set
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
@@ -36,12 +37,24 @@
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_CONTROL=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_DM_MMC=y
 CONFIG_SPI_FLASH=y
 CONFIG_PHYLIB=y
 CONFIG_PCI=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_IMX6=y
+CONFIG_DM_PMIC=y
+CONFIG_DM_PMIC_PFUZE100=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_PFUZE100=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
 CONFIG_USB=y
+CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
 CONFIG_VIDEO=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/mx6ull_14x14_evk_defconfig b/configs/mx6ull_14x14_evk_defconfig
index 4960056..5305c12 100644
--- a/configs/mx6ull_14x14_evk_defconfig
+++ b/configs/mx6ull_14x14_evk_defconfig
@@ -10,6 +10,7 @@
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_CACHE=y
@@ -24,7 +25,12 @@
 CONFIG_DM_74X164=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_IMX6=y
 CONFIG_DM_REGULATOR=y
 CONFIG_DM_SPI=y
+CONFIG_FSL_QSPI=y
diff --git a/configs/mx6ull_14x14_evk_plugin_defconfig b/configs/mx6ull_14x14_evk_plugin_defconfig
index d07be22..f1023b2 100644
--- a/configs/mx6ull_14x14_evk_plugin_defconfig
+++ b/configs/mx6ull_14x14_evk_plugin_defconfig
@@ -11,6 +11,7 @@
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_CACHE=y
@@ -25,7 +26,12 @@
 CONFIG_DM_74X164=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_IMX6=y
 CONFIG_DM_REGULATOR=y
 CONFIG_DM_SPI=y
+CONFIG_FSL_QSPI=y
diff --git a/configs/sksimx6_defconfig b/configs/sksimx6_defconfig
new file mode 100644
index 0000000..4543996
--- /dev/null
+++ b/configs/sksimx6_defconfig
@@ -0,0 +1,47 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MX6=y
+CONFIG_SPL_GPIO_SUPPORT=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_MX6_DDRCAL=y
+CONFIG_TARGET_SKSIMX6=y
+CONFIG_SPL_MMC_SUPPORT=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_SPL_LIBDISK_SUPPORT=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,MX6QDL"
+CONFIG_BOOTDELAY=1
+CONFIG_SILENT_CONSOLE=y
+CONFIG_SILENT_U_BOOT_ONLY=y
+CONFIG_VERSION_VARIABLE=y
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_SPL=y
+CONFIG_SPL_EXT_SUPPORT=y
+CONFIG_SPL_I2C_SUPPORT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_DM=y
+CONFIG_PHYLIB=y
+CONFIG_PHY_MICREL=y
+CONFIG_PHY_MICREL_KSZ90X1=y
+CONFIG_PHY_MICREL_KSZ8XXX=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_DM_THERMAL=y
+CONFIG_OF_LIBFDT=y
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 976e2c4..36336b6 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -266,6 +266,17 @@
 	for (offset = fdt_first_subnode(blob, offset);
 	     offset > 0;
 	     offset = fdt_next_subnode(blob, offset)) {
+		/* "chosen" node isn't a device itself but may contain some: */
+		if (!strcmp(fdt_get_name(blob, offset, NULL), "chosen")) {
+			pr_debug("parsing subnodes of \"chosen\"\n");
+
+			err = dm_scan_fdt_node(parent, blob, offset,
+					       pre_reloc_only);
+			if (err && !ret)
+				ret = err;
+			continue;
+		}
+
 		if (pre_reloc_only &&
 		    !dm_fdt_pre_reloc(blob, offset))
 			continue;
diff --git a/drivers/gpio/pm8916_gpio.c b/drivers/gpio/pm8916_gpio.c
index 9ec2a24..42f068e 100644
--- a/drivers/gpio/pm8916_gpio.c
+++ b/drivers/gpio/pm8916_gpio.c
@@ -29,7 +29,7 @@
 #define REG_STATUS_VAL_MASK    0x1
 
 /* MODE_CTL */
-#define REG_CTL           0x40
+#define REG_CTL		0x40
 #define REG_CTL_MODE_MASK       0x70
 #define REG_CTL_MODE_INPUT      0x00
 #define REG_CTL_MODE_INOUT      0x20
@@ -183,7 +183,7 @@
 		return -ENODEV;
 
 	reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE);
-	if (reg != 0x5)
+	if (reg != 0x5 && reg != 0x1)
 		return -ENODEV;
 
 	return 0;
@@ -203,6 +203,7 @@
 
 static const struct udevice_id pm8916_gpio_ids[] = {
 	{ .compatible = "qcom,pm8916-gpio" },
+	{ .compatible = "qcom,pm8994-gpio" },	/* 22 GPIO's */
 	{ }
 };
 
@@ -278,6 +279,7 @@
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 
 	uc_priv->gpio_count = 2;
+	uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
 	if (uc_priv->bank_name == NULL)
 		uc_priv->bank_name = "pm8916_key";
 
@@ -286,6 +288,7 @@
 
 static const struct udevice_id pm8941_pwrkey_ids[] = {
 	{ .compatible = "qcom,pm8916-pwrkey" },
+	{ .compatible = "qcom,pm8994-pwrkey" },
 	{ }
 };
 
diff --git a/drivers/misc/mxc_ocotp.c b/drivers/misc/mxc_ocotp.c
index 8986bb4..18a2730 100644
--- a/drivers/misc/mxc_ocotp.c
+++ b/drivers/misc/mxc_ocotp.c
@@ -342,6 +342,23 @@
 static int prepare_write(struct ocotp_regs **regs, u32 bank, u32 word,
 				const char *caller)
 {
+#ifdef CONFIG_MX7ULP
+	u32 val;
+	int ret;
+
+	/* Only bank 0 and 1 are redundancy mode, others are ECC mode */
+	if (bank != 0 && bank != 1) {
+		ret = fuse_sense(bank, word, &val);
+		if (ret)
+			return ret;
+
+		if (val != 0) {
+			printf("mxc_ocotp: The word has been programmed, no more write\n");
+			return -EPERM;
+		}
+	}
+#endif
+
 	return prepare_access(regs, bank, word, true, caller);
 }
 
diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c
index 2900c8d..ef66a1d 100644
--- a/drivers/pci/pcie_imx.c
+++ b/drivers/pci/pcie_imx.c
@@ -517,10 +517,12 @@
 __weak int imx6_pcie_toggle_power(void)
 {
 #ifdef CONFIG_PCIE_IMX_POWER_GPIO
+	gpio_request(CONFIG_PCIE_IMX_POWER_GPIO, "pcie_power");
 	gpio_direction_output(CONFIG_PCIE_IMX_POWER_GPIO, 0);
 	mdelay(20);
 	gpio_set_value(CONFIG_PCIE_IMX_POWER_GPIO, 1);
 	mdelay(20);
+	gpio_free(CONFIG_PCIE_IMX_POWER_GPIO);
 #endif
 	return 0;
 }
@@ -556,10 +558,12 @@
 	 * state due to being previously used in U-Boot.
 	 */
 #ifdef CONFIG_PCIE_IMX_PERST_GPIO
+	gpio_request(CONFIG_PCIE_IMX_PERST_GPIO, "pcie_reset");
 	gpio_direction_output(CONFIG_PCIE_IMX_PERST_GPIO, 0);
 	mdelay(20);
 	gpio_set_value(CONFIG_PCIE_IMX_PERST_GPIO, 1);
 	mdelay(20);
+	gpio_free(CONFIG_PCIE_IMX_PERST_GPIO);
 #else
 	puts("WARNING: Make sure the PCIe #PERST line is connected!\n");
 #endif
@@ -612,6 +616,17 @@
 	imx_pcie_regions_setup();
 
 	/*
+	 * By default, the subordinate is set equally to the secondary
+	 * bus (0x01) when the RC boots.
+	 * This means that theoretically, only bus 1 is reachable from the RC.
+	 * Force the PCIe RC subordinate to 0xff, otherwise no downstream
+	 * devices will be detected if the enumeration is applied strictly.
+	 */
+	tmp = readl(MX6_DBI_ADDR + 0x18);
+	tmp |= (0xff << 16);
+	writel(tmp, MX6_DBI_ADDR + 0x18);
+
+	/*
 	 * FIXME: Force the PCIe RC to Gen1 operation
 	 * The RC must be forced into Gen1 mode before bringing the link
 	 * up, otherwise no downstream devices are detected. After the
diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
index 0f3f7d9..2f5345f 100644
--- a/drivers/spi/fsl_qspi.c
+++ b/drivers/spi/fsl_qspi.c
@@ -20,7 +20,8 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 #define RX_BUFFER_SIZE		0x80
-#ifdef CONFIG_MX6SX
+#if defined(CONFIG_MX6SX) || defined(CONFIG_MX6UL) || \
+	defined(CONFIG_MX6ULL) || defined(CONFIG_MX7D)
 #define TX_BUFFER_SIZE		0x200
 #else
 #define TX_BUFFER_SIZE		0x40
@@ -268,7 +269,8 @@
 			     INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |
 			     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
 #endif
-#ifdef CONFIG_MX6SX
+#if defined(CONFIG_MX6SX) || defined(CONFIG_MX6UL) || \
+	defined(CONFIG_MX6ULL) || defined(CONFIG_MX7D)
 	/*
 	 * To MX6SX, OPRND0(TX_BUFFER_SIZE) can not work correctly.
 	 * So, Use IDATSZ in IPCR to determine the size and here set 0.
@@ -905,6 +907,11 @@
 	qspi->slave.max_write_size = TX_BUFFER_SIZE;
 
 	mcr_val = qspi_read32(qspi->priv.flags, &regs->mcr);
+
+	/* Set endianness to LE for i.mx */
+	if (IS_ENABLED(CONFIG_MX6) || IS_ENABLED(CONFIG_MX7))
+		mcr_val = QSPI_MCR_END_CFD_LE;
+
 	qspi_write32(qspi->priv.flags, &regs->mcr,
 		     QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK |
 		     (mcr_val & QSPI_MCR_END_CFD_MASK));
@@ -1023,6 +1030,11 @@
 	}
 
 	mcr_val = qspi_read32(priv->flags, &priv->regs->mcr);
+
+	/* Set endianness to LE for i.mx */
+	if (IS_ENABLED(CONFIG_MX6) || IS_ENABLED(CONFIG_MX7))
+		mcr_val = QSPI_MCR_END_CFD_LE;
+
 	qspi_write32(priv->flags, &priv->regs->mcr,
 		     QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK |
 		     (mcr_val & QSPI_MCR_END_CFD_MASK));
@@ -1227,6 +1239,8 @@
 static const struct udevice_id fsl_qspi_ids[] = {
 	{ .compatible = "fsl,vf610-qspi" },
 	{ .compatible = "fsl,imx6sx-qspi" },
+	{ .compatible = "fsl,imx6ul-qspi" },
+	{ .compatible = "fsl,imx7d-qspi" },
 	{ }
 };
 
diff --git a/drivers/spmi/spmi-msm.c b/drivers/spmi/spmi-msm.c
index c226913..dd7a1ea 100644
--- a/drivers/spmi/spmi-msm.c
+++ b/drivers/spmi/spmi-msm.c
@@ -17,6 +17,10 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/* PMIC Arbiter configuration registers */
+#define PMIC_ARB_VERSION		0x0000
+#define PMIC_ARB_VERSION_V2_MIN		0x20010000
+
 #define ARB_CHANNEL_OFFSET(n)		(0x4 * (n))
 #define SPMI_CH_OFFSET(chnl)		((chnl) * 0x8000)
 
@@ -148,6 +152,8 @@
 	struct udevice *parent = dev->parent;
 	struct msm_spmi_priv *priv = dev_get_priv(dev);
 	int node = dev_of_offset(dev);
+	u32 hw_ver;
+	bool is_v1;
 	int i;
 
 	priv->arb_chnl = devfdt_get_addr(dev);
@@ -155,6 +161,12 @@
 			dev_of_offset(parent), node, "reg", 1, NULL, false);
 	priv->spmi_obs = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
 			dev_of_offset(parent), node, "reg", 2, NULL, false);
+
+	hw_ver = readl(priv->arb_chnl + PMIC_ARB_VERSION - 0x800);
+	is_v1  = (hw_ver < PMIC_ARB_VERSION_V2_MIN);
+
+	dev_dbg(dev, "PMIC Arb Version-%d (0x%x)\n", (is_v1 ? 1 : 2), hw_ver);
+
 	if (priv->arb_chnl == FDT_ADDR_T_NONE ||
 	    priv->spmi_core == FDT_ADDR_T_NONE ||
 	    priv->spmi_obs == FDT_ADDR_T_NONE)
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index 2e9598e..000c288 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -8,10 +8,8 @@
 obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
 obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o
 obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o
-
 obj-$(CONFIG_ARCH_ROCKCHIP) += sysreset_rockchip.o
 obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
-obj-$(CONFIG_ARCH_SNAPDRAGON) += sysreset_snapdragon.o
 obj-$(CONFIG_ARCH_STI) += sysreset_sti.o
 obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o
 obj-$(CONFIG_ARCH_ASPEED) += sysreset_ast.o
diff --git a/drivers/sysreset/sysreset_snapdragon.c b/drivers/sysreset/sysreset_snapdragon.c
deleted file mode 100644
index 9869813..0000000
--- a/drivers/sysreset/sysreset_snapdragon.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Qualcomm APQ8016 reset controller driver
- *
- * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <dm.h>
-#include <errno.h>
-#include <sysreset.h>
-#include <asm/io.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-static int msm_sysreset_request(struct udevice *dev, enum sysreset_t type)
-{
-	phys_addr_t addr = devfdt_get_addr(dev);
-	if (!addr)
-		return -EINVAL;
-	writel(0, addr);
-	return -EINPROGRESS;
-}
-
-static struct sysreset_ops msm_sysreset_ops = {
-	.request	= msm_sysreset_request,
-};
-
-static const struct udevice_id msm_sysreset_ids[] = {
-	{ .compatible = "qcom,pshold" },
-	{ }
-};
-
-U_BOOT_DRIVER(msm_reset) = {
-	.name		= "msm_sysreset",
-	.id		= UCLASS_SYSRESET,
-	.of_match	= msm_sysreset_ids,
-	.ops		= &msm_sysreset_ops,
-};
diff --git a/env/Kconfig b/env/Kconfig
index bef6e89..692f863 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -81,6 +81,13 @@
 	  - CONFIG_FAT_WRITE:
 	  This must be enabled. Otherwise it cannot save the environment file.
 
+config ENV_IS_IN_EXT4
+	bool "Environment is in a EXT4 filesystem"
+	depends on !CHAIN_OF_TRUST
+	select EXT4_WRITE
+	help
+	  Define this if you want to use the EXT4 file system for the environment.
+
 config ENV_IS_IN_FLASH
 	bool "Environment in flash memory"
 	depends on !CHAIN_OF_TRUST
@@ -396,6 +403,38 @@
 	  It's a string of the FAT file name. This file use to store the
 	  environment.
 
+config ENV_EXT4_INTERFACE
+	string "Name of the block device for the environment"
+	depends on ENV_IS_IN_EXT4
+	help
+	  Define this to a string that is the name of the block device.
+
+config ENV_EXT4_DEVICE_AND_PART
+	string "Device and partition for where to store the environemt in EXT4"
+	depends on ENV_IS_IN_EXT4
+	help
+	  Define this to a string to specify the partition of the device. It can
+	  be as following:
+
+	    "D:P", "D:0", "D", "D:" or "D:auto" (D, P are integers. And P >= 1)
+	       - "D:P": device D partition P. Error occurs if device D has no
+	                partition table.
+	       - "D:0": device D.
+	       - "D" or "D:": device D partition 1 if device D has partition
+	                      table, or the whole device D if has no partition
+	                      table.
+	       - "D:auto": first partition in device D with bootable flag set.
+	                   If none, first valid partition in device D. If no
+	                   partition table then means device D.
+
+config ENV_EXT4_FILE
+	string "Name of the EXT4 file to use for the environemnt"
+	depends on ENV_IS_IN_EXT4
+	default "uboot.env"
+	help
+	  It's a string of the EXT4 file name. This file use to store the
+	  environment (explicit path to the file)
+
 if ARCH_SUNXI
 
 config ENV_OFFSET
diff --git a/env/env.c b/env/env.c
index 76a5608..7455632 100644
--- a/env/env.c
+++ b/env/env.c
@@ -32,6 +32,8 @@
 		return ENVL_EEPROM;
 	else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT)
 		return ENVL_FAT;
+	else if IS_ENABLED(CONFIG_ENV_IS_IN_EXT4)
+		return ENVL_EXT4;
 	else if IS_ENABLED(CONFIG_ENV_IS_IN_FLASH)
 		return ENVL_FLASH;
 	else if IS_ENABLED(CONFIG_ENV_IS_IN_MMC)
diff --git a/env/ext4.c b/env/ext4.c
index 6520221..9cdf28e 100644
--- a/env/ext4.c
+++ b/env/ext4.c
@@ -46,9 +46,9 @@
 	if (err)
 		return err;
 
-	part = blk_get_device_part_str(EXT4_ENV_INTERFACE,
-					EXT4_ENV_DEVICE_AND_PART,
-					&dev_desc, &info, 1);
+	part = blk_get_device_part_str(CONFIG_ENV_EXT4_INTERFACE,
+				       CONFIG_ENV_EXT4_DEVICE_AND_PART,
+				       &dev_desc, &info, 1);
 	if (part < 0)
 		return 1;
 
@@ -57,16 +57,19 @@
 
 	if (!ext4fs_mount(info.size)) {
 		printf("\n** Unable to use %s %s for saveenv **\n",
-		       EXT4_ENV_INTERFACE, EXT4_ENV_DEVICE_AND_PART);
+		       CONFIG_ENV_EXT4_INTERFACE,
+		       CONFIG_ENV_EXT4_DEVICE_AND_PART);
 		return 1;
 	}
 
-	err = ext4fs_write(EXT4_ENV_FILE, (void *)&env_new, sizeof(env_t));
+	err = ext4fs_write(CONFIG_ENV_EXT4_FILE, (void *)&env_new,
+			   sizeof(env_t));
 	ext4fs_close();
 
 	if (err == -1) {
 		printf("\n** Unable to write \"%s\" from %s%d:%d **\n",
-			EXT4_ENV_FILE, EXT4_ENV_INTERFACE, dev, part);
+			CONFIG_ENV_EXT4_FILE, CONFIG_ENV_EXT4_INTERFACE, dev,
+			part);
 		return 1;
 	}
 
@@ -84,9 +87,9 @@
 	int err;
 	loff_t off;
 
-	part = blk_get_device_part_str(EXT4_ENV_INTERFACE,
-					EXT4_ENV_DEVICE_AND_PART,
-					&dev_desc, &info, 1);
+	part = blk_get_device_part_str(CONFIG_ENV_EXT4_INTERFACE,
+				       CONFIG_ENV_EXT4_DEVICE_AND_PART,
+				       &dev_desc, &info, 1);
 	if (part < 0)
 		goto err_env_relocate;
 
@@ -95,16 +98,19 @@
 
 	if (!ext4fs_mount(info.size)) {
 		printf("\n** Unable to use %s %s for loading the env **\n",
-		       EXT4_ENV_INTERFACE, EXT4_ENV_DEVICE_AND_PART);
+		       CONFIG_ENV_EXT4_INTERFACE,
+		       CONFIG_ENV_EXT4_DEVICE_AND_PART);
 		goto err_env_relocate;
 	}
 
-	err = ext4_read_file(EXT4_ENV_FILE, buf, 0, CONFIG_ENV_SIZE, &off);
+	err = ext4_read_file(CONFIG_ENV_EXT4_FILE, buf, 0, CONFIG_ENV_SIZE,
+			     &off);
 	ext4fs_close();
 
 	if (err == -1) {
 		printf("\n** Unable to read \"%s\" from %s%d:%d **\n",
-			EXT4_ENV_FILE, EXT4_ENV_INTERFACE, dev, part);
+			CONFIG_ENV_EXT4_FILE, CONFIG_ENV_EXT4_INTERFACE, dev,
+			part);
 		goto err_env_relocate;
 	}
 
diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h
index ec3e6e6..da870b9 100644
--- a/include/configs/cm_fx6.h
+++ b/include/configs/cm_fx6.h
@@ -67,6 +67,7 @@
 #define CONFIG_ENV_OFFSET		(768 * 1024)
 
 #ifndef CONFIG_SPL_BUILD
+#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"fdt_high=0xffffffff\0" \
 	"initrd_high=0xffffffff\0" \
@@ -75,6 +76,7 @@
 	"kernel_addr_r=" __stringify(CONFIG_LOADADDR) "\0" \
 	"pxefile_addr_r=" __stringify(CONFIG_LOADADDR) "\0" \
 	"scriptaddr=" __stringify(CONFIG_LOADADDR) "\0" \
+	"fdtfile=undefined\0" \
 	"stdin=serial,usbkbd\0" \
 	"stdout=serial,vga\0" \
 	"stderr=serial,vga\0" \
@@ -152,6 +154,11 @@
 		"fi;" \
 		"run setupnandboot;" \
 		"run nandboot;\0" \
+	"findfdt="\
+		"if test $board_name = Utilite && test $board_rev = MX6Q ; then " \
+			"setenv fdtfile imx6q-utilite-pro.dtb; fi; " \
+		"if test $fdtfile = undefined; then " \
+			"echo WARNING: Could not determine dtb to use; fi; \0" \
 	BOOTENV
 
 #define CONFIG_PREBOOT		"usb start;sf probe"
diff --git a/include/configs/dragonboard410c.h b/include/configs/dragonboard410c.h
index d2447b2..530d667 100644
--- a/include/configs/dragonboard410c.h
+++ b/include/configs/dragonboard410c.h
@@ -23,7 +23,7 @@
 #define CONFIG_SYS_TEXT_BASE		0x80080000
 #define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x7fff0)
 #define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x80000)
-#define CONFIG_SYS_BOOTM_LEN		0x1000000 /* 16MB max kernel size */
+#define CONFIG_SYS_BOOTM_LEN		SZ_64M
 
 /* UART */
 
@@ -92,7 +92,7 @@
 	"initrd_high=0xffffffffffffffff\0" \
 	"linux_image=Image\0" \
 	"kernel_addr_r=0x81000000\0"\
-	"fdtfile=apq8016-sbc.dtb\0" \
+	"fdtfile=qcom/apq8016-sbc.dtb\0" \
 	"fdt_addr_r=0x83000000\0"\
 	"ramdisk_addr_r=0x84000000\0"\
 	"scriptaddr=0x90000000\0"\
diff --git a/include/configs/dragonboard820c.h b/include/configs/dragonboard820c.h
new file mode 100644
index 0000000..010bc44
--- /dev/null
+++ b/include/configs/dragonboard820c.h
@@ -0,0 +1,74 @@
+/*
+ * Board configuration file for Dragonboard 410C
+ *
+ * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIGS_DRAGONBOARD820C_H
+#define __CONFIGS_DRAGONBOARD820C_H
+
+#include <linux/sizes.h>
+#include <asm/arch/sysmap-apq8096.h>
+
+#define CONFIG_MISC_INIT_R /* To stop autoboot */
+
+/* Physical Memory Map */
+#define CONFIG_NR_DRAM_BANKS		2
+
+#define PHYS_SDRAM_SIZE			0xC0000000
+#define PHYS_SDRAM_1			0x80000000
+#define PHYS_SDRAM_1_SIZE		0x60000000
+#define PHYS_SDRAM_2			0x100000000
+#define PHYS_SDRAM_2_SIZE		0x5ea4ffff
+
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+#define CONFIG_SYS_TEXT_BASE		0x80080000
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x7fff0)
+#define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x80000)
+#define CONFIG_SYS_BOOTM_LEN		SZ_64M
+#define CONFIG_SYS_LDSCRIPT	"board/qualcomm/dragonboard820c/u-boot.lds"
+
+/* Generic Timer Definitions */
+#define COUNTER_FREQUENCY		19000000
+
+/* Partition table support */
+#define HAVE_BLOCK_DEVICE
+
+/* BOOTP options */
+#define CONFIG_BOOTP_BOOTFILESIZE
+
+#ifndef CONFIG_SPL_BUILD
+#include <config_distro_defaults.h>
+#include <config_distro_bootcmd.h>
+#endif
+
+#define BOOT_TARGET_DEVICES(func) \
+	func(MMC, mmc, 0)
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"loadaddr=0x95000000\0" \
+	"fdt_high=0xffffffffffffffff\0" \
+	"initrd_high=0xffffffffffffffff\0" \
+	"linux_image=uImage\0" \
+	"kernel_addr_r=0x95000000\0"\
+	"fdtfile=qcom/apq8096-db820c.dtb\0" \
+	"fdt_addr_r=0x93000000\0"\
+	"ramdisk_addr_r=0x91000000\0"\
+	"scriptaddr=0x90000000\0"\
+	"pxefile_addr_r=0x90100000\0"\
+	BOOTENV
+
+#define CONFIG_EXT4_WRITE
+#define CONFIG_ENV_SIZE			0x4000
+#define CONFIG_ENV_VARS_UBOOT_CONFIG
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + SZ_8M)
+
+/* Monitor Command Prompt */
+#define CONFIG_SYS_CBSIZE		512
+#define CONFIG_SYS_MAXARGS		64
+
+#endif
diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h
index 906e677..1eaaf01 100644
--- a/include/configs/mx6sxsabresd.h
+++ b/include/configs/mx6sxsabresd.h
@@ -145,19 +145,12 @@
 #define CONFIG_SYS_FSL_ESDHC_ADDR	USDHC4_BASE_ADDR
 
 /* I2C Configs */
-#define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_MXC
 #define CONFIG_SYS_I2C_MXC_I2C1		/* enable I2C bus 1 */
 #define CONFIG_SYS_I2C_MXC_I2C2		/* enable I2C bus 2 */
 #define CONFIG_SYS_I2C_MXC_I2C3		/* enable I2C bus 3 */
 #define CONFIG_SYS_I2C_SPEED		  100000
 
-/* PMIC */
-#define CONFIG_POWER
-#define CONFIG_POWER_I2C
-#define CONFIG_POWER_PFUZE100
-#define CONFIG_POWER_PFUZE100_I2C_ADDR	0x08
-
 /* Network */
 #define CONFIG_FEC_MXC
 #define CONFIG_MII
@@ -210,7 +203,7 @@
 #endif
 #endif
 
-#define CONFIG_ENV_OFFSET		(8 * SZ_64K)
+#define CONFIG_ENV_OFFSET		(14 * SZ_64K)
 #define CONFIG_ENV_SIZE			SZ_8K
 
 #define CONFIG_SYS_FSL_USDHC_NUM	3
diff --git a/include/configs/mx6ullevk.h b/include/configs/mx6ullevk.h
index 8787df4..6a48742 100644
--- a/include/configs/mx6ullevk.h
+++ b/include/configs/mx6ullevk.h
@@ -164,4 +164,14 @@
 
 #define CONFIG_SOFT_SPI
 
+#ifdef CONFIG_FSL_QSPI
+#define CONFIG_SYS_FSL_QSPI_AHB
+#define CONFIG_SF_DEFAULT_BUS		0
+#define CONFIG_SF_DEFAULT_CS		0
+#define CONFIG_SF_DEFAULT_SPEED	40000000
+#define CONFIG_SF_DEFAULT_MODE		SPI_MODE_0
+#define FSL_QSPI_FLASH_NUM		1
+#define FSL_QSPI_FLASH_SIZE		SZ_32M
+#endif
+
 #endif
diff --git a/include/configs/poplar.h b/include/configs/poplar.h
index 1c39ed1..8a12b52 100644
--- a/include/configs/poplar.h
+++ b/include/configs/poplar.h
@@ -18,7 +18,7 @@
 #define CONFIG_NR_DRAM_BANKS			2
 
 /* SYS */
-#define CONFIG_SYS_BOOTM_LEN			0x1400000
+#define CONFIG_SYS_BOOTM_LEN			SZ_64M
 #define CONFIG_SYS_INIT_SP_ADDR			0x200000
 #define CONFIG_SYS_LOAD_ADDR			0x800000
 #define CONFIG_SYS_MALLOC_LEN			SZ_32M
diff --git a/include/configs/sksimx6.h b/include/configs/sksimx6.h
new file mode 100644
index 0000000..c635e9f
--- /dev/null
+++ b/include/configs/sksimx6.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) Stefano Babic <sbabic@denx.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+
+#ifndef __SKSIMX6_CONFIG_H
+#define __SKSIMX6_CONFIG_H
+
+#include <config_distro_defaults.h>
+
+#include "mx6_common.h"
+#include "imx6_spl.h"
+
+/* Thermal */
+#define CONFIG_IMX_THERMAL
+
+/* Serial */
+#define CONFIG_MXC_UART
+#define CONFIG_MXC_UART_BASE	       UART1_BASE
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN		(8 * SZ_1M)
+
+/* Ethernet */
+#define IMX_FEC_BASE			ENET_BASE_ADDR
+#define CONFIG_FEC_XCV_TYPE		RGMII
+#define CONFIG_ETHPRIME			"FEC"
+#define CONFIG_FEC_MXC_PHYADDR		0x01
+
+#define CONFIG_MII
+#define CONFIG_PHY_MICREL_KSZ9021
+
+/* I2C Configs */
+#define CONFIG_SYS_I2C
+#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C2
+#define CONFIG_SYS_I2C_SPEED		  100000
+
+/* Filesystem support */
+
+/* Physical Memory Map */
+#define CONFIG_NR_DRAM_BANKS           1
+#define PHYS_SDRAM                     MMDC0_ARB_BASE_ADDR
+
+#define CONFIG_SYS_SDRAM_BASE          PHYS_SDRAM
+#define CONFIG_SYS_INIT_RAM_ADDR       IRAM_BASE_ADDR
+#define CONFIG_SYS_INIT_RAM_SIZE       IRAM_SIZE
+
+#define CONFIG_SYS_INIT_SP_OFFSET \
+	(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR \
+	(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
+
+/* MMC Configs */
+#define CONFIG_SYS_FSL_ESDHC_ADDR	0
+#define CONFIG_SYS_FSL_USDHC_NUM	1
+
+/* Environment organization */
+#define CONFIG_ENV_SIZE                (16 * 1024)
+#define CONFIG_ENV_OFFSET		(6 * 64 * 1024)
+#define CONFIG_SYS_MMC_ENV_DEV		0
+#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
+#define CONFIG_ENV_OFFSET_REDUND       (CONFIG_ENV_OFFSET + \
+						CONFIG_ENV_SIZE)
+#define CONFIG_ENV_SIZE_REDUND         CONFIG_ENV_SIZE
+
+/* Default environment */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"addcons=setenv bootargs ${bootargs} "				\
+		"console=${console},${baudrate}\0"			\
+	"addip=setenv bootargs ${bootargs} "				\
+		"ip=${ipaddr}:${serverip}:${gatewayip}:"		\
+		"${netmask}:${hostname}:${netdev}:off\0"		\
+	"addmisc=setenv bootargs ${bootargs} ${miscargs}\0" 		\
+	"bootcmd=run mmcboot\0"						\
+	"bootfile=uImage\0"						\
+	"bootimage=uImage\0"						\
+	"console=ttymxc0\0"						\
+	"fdt_addr_r=0x18000000\0" 					\
+	"fdt_file=imx6dl-sks-cts.dtb\0"					\
+	"fdt_high=0xffffffff\0" 					\
+	"kernel_addr_r=" __stringify(CONFIG_LOADADDR) "\0" 		\
+	"miscargs=quiet\0"						\
+	"mmcargs=setenv bootargs root=${mmcroot} rw rootwait\0"		\
+	"mmcboot=if run mmcload;then " 					\
+		"run mmcargs addcons addmisc;"				\
+			"bootm;fi\0" 					\
+	"mmcload=mmc rescan;"						\
+		"load mmc 0:${mmcpart} ${kernel_addr_r} boot/fitImage\0"\
+	"mmcpart=1\0"							\
+	"mmcroot=/dev/mmcblk0p1\0"					\
+	"net_nfs=tftp ${kernel_addr_r} ${board_name}/${bootfile};"	\
+		"tftp ${fdt_addr_r} ${board_name}/${fdt_file};"		\
+		"run nfsargs addip addcons addmisc;"			\
+		"bootm ${kernel_addr_r} - ${fdt_addr_r}\0"		\
+	"nfsargs=setenv bootargs root=/dev/nfs "			\
+		"nfsroot=${serverip}:${nfsroot},v3 panic=1\0"
+
+#endif
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 0fb3e07..4afb9ac 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -990,7 +990,8 @@
 
 /**
  * Board-specific FDT initialization. Returns the address to a device tree blob.
- * Called when CONFIG_OF_BOARD is defined.
+ * Called when CONFIG_OF_BOARD is defined, or if CONFIG_OF_SEPARATE is defined
+ * and the board implements it.
  */
 void *board_fdt_blob_setup(void);
 
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 30ec6b9..6b138fa 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -1272,6 +1272,28 @@
 # endif
 #endif
 
+#if defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE)
+/*
+ * For CONFIG_OF_SEPARATE, the board may optionally implement this to
+ * provide and/or fixup the fdt.
+ */
+__weak void *board_fdt_blob_setup(void)
+{
+	void *fdt_blob = NULL;
+#ifdef CONFIG_SPL_BUILD
+	/* FDT is at end of BSS unless it is in a different memory region */
+	if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS))
+		fdt_blob = (ulong *)&_image_binary_end;
+	else
+		fdt_blob = (ulong *)&__bss_end;
+#else
+	/* FDT is at end of image */
+	fdt_blob = (ulong *)&_end;
+#endif
+	return fdt_blob;
+}
+#endif
+
 int fdtdec_setup(void)
 {
 #if CONFIG_IS_ENABLED(OF_CONTROL)
@@ -1285,18 +1307,7 @@
 #  else
 	gd->fdt_blob = __dtb_dt_begin;
 #  endif
-# elif defined CONFIG_OF_SEPARATE
-#  ifdef CONFIG_SPL_BUILD
-	/* FDT is at end of BSS unless it is in a different memory region */
-	if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS))
-		gd->fdt_blob = (ulong *)&_image_binary_end;
-	else
-		gd->fdt_blob = (ulong *)&__bss_end;
-#  else
-	/* FDT is at end of image */
-	gd->fdt_blob = (ulong *)&_end;
-#  endif
-# elif defined(CONFIG_OF_BOARD)
+# elif defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE)
 	/* Allow the board to override the fdt address. */
 	gd->fdt_blob = board_fdt_blob_setup();
 # elif defined(CONFIG_OF_HOSTFILE)
diff --git a/test/dm/bus.c b/test/dm/bus.c
index 7006d41..1da398a 100644
--- a/test/dm/bus.c
+++ b/test/dm/bus.c
@@ -105,7 +105,7 @@
 /* Test that we can probe for children */
 static int dm_test_bus_children(struct unit_test_state *uts)
 {
-	int num_devices = 6;
+	int num_devices = 7;
 	struct udevice *bus;
 	struct uclass *uc;
 
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index dcc2ef8..920ccbf 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -167,7 +167,7 @@
 /* Test that FDT-based binding works correctly */
 static int dm_test_fdt(struct unit_test_state *uts)
 {
-	const int num_devices = 6;
+	const int num_devices = 7;
 	struct udevice *dev;
 	struct uclass *uc;
 	int ret;