Merge branch 'next' of git://git.denx.de/u-boot-spi
diff --git a/Makefile b/Makefile
index b8816ad..600a4d6 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@
 VERSION = 2017
 PATCHLEVEL = 05
 SUBLEVEL =
-EXTRAVERSION = -rc3
+EXTRAVERSION =
 NAME =
 
 # *DOCUMENTATION*
diff --git a/README b/README
index 0ac0136..78173e2 100644
--- a/README
+++ b/README
@@ -828,7 +828,6 @@
 		CONFIG_CMD_CACHE	* icache, dcache
 		CONFIG_CMD_CONSOLE	  coninfo
 		CONFIG_CMD_CRC32	* crc32
-		CONFIG_CMD_DATE		* support for RTC, date/time...
 		CONFIG_CMD_DHCP		* DHCP support
 		CONFIG_CMD_DIAG		* Diagnostics
 		CONFIG_CMD_DS4510	* ds4510 I2C gpio commands
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 513a35f..b2d6e80 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -88,6 +88,12 @@
 config ARM_ERRATA_833471
 	bool
 
+config ARM_ERRATA_852421
+	bool
+
+config ARM_ERRATA_852423
+	bool
+
 config CPU_ARM720T
 	bool
 	select SYS_CACHE_SHIFT_5
@@ -643,6 +649,14 @@
 	select USB_STORAGE if DISTRO_DEFAULTS
 	select USB_KEYBOARD if DISTRO_DEFAULTS
 	select USE_TINY_PRINTF
+	imply PRE_CONSOLE_BUFFER
+	imply SPL_GPIO_SUPPORT
+	imply SPL_LIBCOMMON_SUPPORT
+	imply SPL_LIBDISK_SUPPORT
+	imply SPL_LIBGENERIC_SUPPORT
+	imply SPL_MMC_SUPPORT if GENERIC_MMC
+	imply SPL_POWER_SUPPORT
+	imply SPL_SERIAL_SUPPORT
 
 config TARGET_TS4600
 	bool "Support TS4600"
@@ -1043,6 +1057,8 @@
 
 source "arch/arm/mach-stm32/Kconfig"
 
+source "arch/arm/mach-sunxi/Kconfig"
+
 source "arch/arm/mach-tegra/Kconfig"
 
 source "arch/arm/mach-uniphier/Kconfig"
@@ -1102,7 +1118,7 @@
 source "board/h2200/Kconfig"
 source "board/hisilicon/hikey/Kconfig"
 source "board/imx31_phycore/Kconfig"
-source "board/isee/igep0033/Kconfig"
+source "board/isee/igep003x/Kconfig"
 source "board/olimex/mx23_olinuxino/Kconfig"
 source "board/phytec/pcm051/Kconfig"
 source "board/ppcag/bg0900/Kconfig"
@@ -1115,7 +1131,6 @@
 source "board/spear/spear600/Kconfig"
 source "board/spear/x600/Kconfig"
 source "board/st/stv0991/Kconfig"
-source "board/sunxi/Kconfig"
 source "board/syteco/zmx25/Kconfig"
 source "board/tcl/sl50/Kconfig"
 source "board/birdland/bav335x/Kconfig"
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index 1a6aee9..f06fd28 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -283,6 +283,18 @@
 skip_errata_725233:
 #endif
 
+#ifdef CONFIG_ARM_ERRATA_852421
+	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
+	orr	r0, r0, #1 << 24	@ set bit #24
+	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_852423
+	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
+	orr	r0, r0, #1 << 12	@ set bit #12
+	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
+#endif
+
 	mov	pc, r5			@ back to my caller
 ENDPROC(cpu_init_cp15)
 
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index f3f53f3..4d656ce 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -185,7 +185,8 @@
 
 dtb-$(CONFIG_ARCH_SNAPDRAGON) += dragonboard410c.dtb
 
-dtb-$(CONFIG_STM32F7) += stm32f746-disco.dtb
+dtb-$(CONFIG_STM32F7) += stm32f746-disco.dtb \
+	stm32f769-disco.dtb
 
 dtb-$(CONFIG_MACH_SUN4I) += \
 	sun4i-a10-a1000.dtb \
diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
index dc13952..723941a 100644
--- a/arch/arm/dts/ast2500-evb.dts
+++ b/arch/arm/dts/ast2500-evb.dts
@@ -21,3 +21,18 @@
 &sdrammc {
 	clock-frequency = <400000000>;
 };
+
+&wdt1 {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
+
+&wdt2 {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
+
+&wdt3 {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
diff --git a/arch/arm/dts/ast2500-u-boot.dtsi b/arch/arm/dts/ast2500-u-boot.dtsi
index c95a7ba..7f80bad 100644
--- a/arch/arm/dts/ast2500-u-boot.dtsi
+++ b/arch/arm/dts/ast2500-u-boot.dtsi
@@ -1,4 +1,5 @@
 #include <dt-bindings/clock/ast2500-scu.h>
+#include <dt-bindings/reset/ast2500-reset.h>
 
 #include "ast2500.dtsi"
 
@@ -11,12 +12,21 @@
 		#reset-cells = <1>;
 	};
 
+	rst: reset-controller {
+		u-boot,dm-pre-reloc;
+		compatible = "aspeed,ast2500-reset";
+		aspeed,wdt = <&wdt1>;
+		#reset-cells = <1>;
+	};
+
 	sdrammc: sdrammc@1e6e0000 {
 		u-boot,dm-pre-reloc;
 		compatible = "aspeed,ast2500-sdrammc";
 		reg = <0x1e6e0000 0x174
 			0x1e6e0200 0x1d4 >;
+		#reset-cells = <1>;
 		clocks = <&scu PLL_MPLL>;
+		resets = <&rst AST_RESET_SDRAM>;
 	};
 
 	ahb {
@@ -24,30 +34,39 @@
 
 		apb {
 			u-boot,dm-pre-reloc;
+		};
 
-			timer: timer@1e782000 {
-				u-boot,dm-pre-reloc;
-			};
+	};
+};
 
-			uart1: serial@1e783000 {
-				clocks = <&scu PCLK_UART1>;
-			};
+&uart1 {
+	clocks = <&scu PCLK_UART1>;
+};
 
-			uart2: serial@1e78d000 {
-				clocks = <&scu PCLK_UART2>;
-			};
+&uart2 {
+	clocks = <&scu PCLK_UART2>;
+};
 
-			uart3: serial@1e78e000 {
-				clocks = <&scu PCLK_UART3>;
-			};
+&uart3 {
+	clocks = <&scu PCLK_UART3>;
+};
 
-			uart4: serial@1e78f000 {
-				clocks = <&scu PCLK_UART4>;
-			};
+&uart4 {
+	clocks = <&scu PCLK_UART4>;
+};
 
-			uart5: serial@1e784000 {
-				clocks = <&scu PCLK_UART5>;
-			};
-		};
-	};
+&uart5 {
+	clocks = <&scu PCLK_UART5>;
+};
+
+&timer {
+	u-boot,dm-pre-reloc;
+};
+
+&mac0 {
+	clocks = <&scu PCLK_MAC1>, <&scu PLL_D2PLL>;
+};
+
+&mac1 {
+	clocks = <&scu PCLK_MAC2>, <&scu PLL_D2PLL>;
 };
diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
index 97fac69..7e0ad3a 100644
--- a/arch/arm/dts/ast2500.dtsi
+++ b/arch/arm/dts/ast2500.dtsi
@@ -1,6 +1,6 @@
 /*
  * This device tree is copied from
- * https://raw.githubusercontent.com/torvalds/linux/02440622/arch/arm/boot/dts/
+ * https://raw.githubusercontent.com/torvalds/linux/34ea5c9d/arch/arm/boot/dts/aspeed-g5.dtsi
  */
 #include "skeleton.dtsi"
 
@@ -36,6 +36,22 @@
 			reg = <0x1e6c0080 0x80>;
 		};
 
+		mac0: ethernet@1e660000 {
+			compatible = "faraday,ftgmac100";
+			reg = <0x1e660000 0x180>;
+			interrupts = <2>;
+			no-hw-checksum;
+			status = "disabled";
+		};
+
+		mac1: ethernet@1e680000 {
+			compatible = "faraday,ftgmac100";
+			reg = <0x1e680000 0x180>;
+			interrupts = <3>;
+			no-hw-checksum;
+			status = "disabled";
+		};
+
 		apb {
 			compatible = "simple-bus";
 			#address-cells = <1>;
@@ -48,6 +64,822 @@
 				reg = <0x1e6e2070 0x04>;
 			};
 
+			syscon: syscon@1e6e2000 {
+				compatible = "aspeed,g5-scu", "syscon", "simple-mfd";
+				reg = <0x1e6e2000 0x1a8>;
+
+				pinctrl: pinctrl {
+					compatible = "aspeed,g5-pinctrl";
+					aspeed,external-nodes = <&gfx &lhc>;
+
+					pinctrl_acpi_default: acpi_default {
+						function = "ACPI";
+						groups = "ACPI";
+					};
+
+					pinctrl_adc0_default: adc0_default {
+						function = "ADC0";
+						groups = "ADC0";
+					};
+
+					pinctrl_adc1_default: adc1_default {
+						function = "ADC1";
+						groups = "ADC1";
+					};
+
+					pinctrl_adc10_default: adc10_default {
+						function = "ADC10";
+						groups = "ADC10";
+					};
+
+					pinctrl_adc11_default: adc11_default {
+						function = "ADC11";
+						groups = "ADC11";
+					};
+
+					pinctrl_adc12_default: adc12_default {
+						function = "ADC12";
+						groups = "ADC12";
+					};
+
+					pinctrl_adc13_default: adc13_default {
+						function = "ADC13";
+						groups = "ADC13";
+					};
+
+					pinctrl_adc14_default: adc14_default {
+						function = "ADC14";
+						groups = "ADC14";
+					};
+
+					pinctrl_adc15_default: adc15_default {
+						function = "ADC15";
+						groups = "ADC15";
+					};
+
+					pinctrl_adc2_default: adc2_default {
+						function = "ADC2";
+						groups = "ADC2";
+					};
+
+					pinctrl_adc3_default: adc3_default {
+						function = "ADC3";
+						groups = "ADC3";
+					};
+
+					pinctrl_adc4_default: adc4_default {
+						function = "ADC4";
+						groups = "ADC4";
+					};
+
+					pinctrl_adc5_default: adc5_default {
+						function = "ADC5";
+						groups = "ADC5";
+					};
+
+					pinctrl_adc6_default: adc6_default {
+						function = "ADC6";
+						groups = "ADC6";
+					};
+
+					pinctrl_adc7_default: adc7_default {
+						function = "ADC7";
+						groups = "ADC7";
+					};
+
+					pinctrl_adc8_default: adc8_default {
+						function = "ADC8";
+						groups = "ADC8";
+					};
+
+					pinctrl_adc9_default: adc9_default {
+						function = "ADC9";
+						groups = "ADC9";
+					};
+
+					pinctrl_bmcint_default: bmcint_default {
+						function = "BMCINT";
+						groups = "BMCINT";
+					};
+
+					pinctrl_ddcclk_default: ddcclk_default {
+						function = "DDCCLK";
+						groups = "DDCCLK";
+					};
+
+					pinctrl_ddcdat_default: ddcdat_default {
+						function = "DDCDAT";
+						groups = "DDCDAT";
+					};
+
+					pinctrl_espi_default: espi_default {
+						function = "ESPI";
+						groups = "ESPI";
+					};
+
+					pinctrl_fwspics1_default: fwspics1_default {
+						function = "FWSPICS1";
+						groups = "FWSPICS1";
+					};
+
+					pinctrl_fwspics2_default: fwspics2_default {
+						function = "FWSPICS2";
+						groups = "FWSPICS2";
+					};
+
+					pinctrl_gpid0_default: gpid0_default {
+						function = "GPID0";
+						groups = "GPID0";
+					};
+
+					pinctrl_gpid2_default: gpid2_default {
+						function = "GPID2";
+						groups = "GPID2";
+					};
+
+					pinctrl_gpid4_default: gpid4_default {
+						function = "GPID4";
+						groups = "GPID4";
+					};
+
+					pinctrl_gpid6_default: gpid6_default {
+						function = "GPID6";
+						groups = "GPID6";
+					};
+
+					pinctrl_gpie0_default: gpie0_default {
+						function = "GPIE0";
+						groups = "GPIE0";
+					};
+
+					pinctrl_gpie2_default: gpie2_default {
+						function = "GPIE2";
+						groups = "GPIE2";
+					};
+
+					pinctrl_gpie4_default: gpie4_default {
+						function = "GPIE4";
+						groups = "GPIE4";
+					};
+
+					pinctrl_gpie6_default: gpie6_default {
+						function = "GPIE6";
+						groups = "GPIE6";
+					};
+
+					pinctrl_i2c10_default: i2c10_default {
+						function = "I2C10";
+						groups = "I2C10";
+					};
+
+					pinctrl_i2c11_default: i2c11_default {
+						function = "I2C11";
+						groups = "I2C11";
+					};
+
+					pinctrl_i2c12_default: i2c12_default {
+						function = "I2C12";
+						groups = "I2C12";
+					};
+
+					pinctrl_i2c13_default: i2c13_default {
+						function = "I2C13";
+						groups = "I2C13";
+					};
+
+					pinctrl_i2c14_default: i2c14_default {
+						function = "I2C14";
+						groups = "I2C14";
+					};
+
+					pinctrl_i2c3_default: i2c3_default {
+						function = "I2C3";
+						groups = "I2C3";
+					};
+
+					pinctrl_i2c4_default: i2c4_default {
+						function = "I2C4";
+						groups = "I2C4";
+					};
+
+					pinctrl_i2c5_default: i2c5_default {
+						function = "I2C5";
+						groups = "I2C5";
+					};
+
+					pinctrl_i2c6_default: i2c6_default {
+						function = "I2C6";
+						groups = "I2C6";
+					};
+
+					pinctrl_i2c7_default: i2c7_default {
+						function = "I2C7";
+						groups = "I2C7";
+					};
+
+					pinctrl_i2c8_default: i2c8_default {
+						function = "I2C8";
+						groups = "I2C8";
+					};
+
+					pinctrl_i2c9_default: i2c9_default {
+						function = "I2C9";
+						groups = "I2C9";
+					};
+
+					pinctrl_lad0_default: lad0_default {
+						function = "LAD0";
+						groups = "LAD0";
+					};
+
+					pinctrl_lad1_default: lad1_default {
+						function = "LAD1";
+						groups = "LAD1";
+					};
+
+					pinctrl_lad2_default: lad2_default {
+						function = "LAD2";
+						groups = "LAD2";
+					};
+
+					pinctrl_lad3_default: lad3_default {
+						function = "LAD3";
+						groups = "LAD3";
+					};
+
+					pinctrl_lclk_default: lclk_default {
+						function = "LCLK";
+						groups = "LCLK";
+					};
+
+					pinctrl_lframe_default: lframe_default {
+						function = "LFRAME";
+						groups = "LFRAME";
+					};
+
+					pinctrl_lpchc_default: lpchc_default {
+						function = "LPCHC";
+						groups = "LPCHC";
+					};
+
+					pinctrl_lpcpd_default: lpcpd_default {
+						function = "LPCPD";
+						groups = "LPCPD";
+					};
+
+					pinctrl_lpcplus_default: lpcplus_default {
+						function = "LPCPLUS";
+						groups = "LPCPLUS";
+					};
+
+					pinctrl_lpcpme_default: lpcpme_default {
+						function = "LPCPME";
+						groups = "LPCPME";
+					};
+
+					pinctrl_lpcrst_default: lpcrst_default {
+						function = "LPCRST";
+						groups = "LPCRST";
+					};
+
+					pinctrl_lpcsmi_default: lpcsmi_default {
+						function = "LPCSMI";
+						groups = "LPCSMI";
+					};
+
+					pinctrl_lsirq_default: lsirq_default {
+						function = "LSIRQ";
+						groups = "LSIRQ";
+					};
+
+					pinctrl_mac1link_default: mac1link_default {
+						function = "MAC1LINK";
+						groups = "MAC1LINK";
+					};
+
+					pinctrl_mac2link_default: mac2link_default {
+						function = "MAC2LINK";
+						groups = "MAC2LINK";
+					};
+
+					pinctrl_mdio1_default: mdio1_default {
+						function = "MDIO1";
+						groups = "MDIO1";
+					};
+
+					pinctrl_mdio2_default: mdio2_default {
+						function = "MDIO2";
+						groups = "MDIO2";
+					};
+
+					pinctrl_ncts1_default: ncts1_default {
+						function = "NCTS1";
+						groups = "NCTS1";
+					};
+
+					pinctrl_ncts2_default: ncts2_default {
+						function = "NCTS2";
+						groups = "NCTS2";
+					};
+
+					pinctrl_ncts3_default: ncts3_default {
+						function = "NCTS3";
+						groups = "NCTS3";
+					};
+
+					pinctrl_ncts4_default: ncts4_default {
+						function = "NCTS4";
+						groups = "NCTS4";
+					};
+
+					pinctrl_ndcd1_default: ndcd1_default {
+						function = "NDCD1";
+						groups = "NDCD1";
+					};
+
+					pinctrl_ndcd2_default: ndcd2_default {
+						function = "NDCD2";
+						groups = "NDCD2";
+					};
+
+					pinctrl_ndcd3_default: ndcd3_default {
+						function = "NDCD3";
+						groups = "NDCD3";
+					};
+
+					pinctrl_ndcd4_default: ndcd4_default {
+						function = "NDCD4";
+						groups = "NDCD4";
+					};
+
+					pinctrl_ndsr1_default: ndsr1_default {
+						function = "NDSR1";
+						groups = "NDSR1";
+					};
+
+					pinctrl_ndsr2_default: ndsr2_default {
+						function = "NDSR2";
+						groups = "NDSR2";
+					};
+
+					pinctrl_ndsr3_default: ndsr3_default {
+						function = "NDSR3";
+						groups = "NDSR3";
+					};
+
+					pinctrl_ndsr4_default: ndsr4_default {
+						function = "NDSR4";
+						groups = "NDSR4";
+					};
+
+					pinctrl_ndtr1_default: ndtr1_default {
+						function = "NDTR1";
+						groups = "NDTR1";
+					};
+
+					pinctrl_ndtr2_default: ndtr2_default {
+						function = "NDTR2";
+						groups = "NDTR2";
+					};
+
+					pinctrl_ndtr3_default: ndtr3_default {
+						function = "NDTR3";
+						groups = "NDTR3";
+					};
+
+					pinctrl_ndtr4_default: ndtr4_default {
+						function = "NDTR4";
+						groups = "NDTR4";
+					};
+
+					pinctrl_nri1_default: nri1_default {
+						function = "NRI1";
+						groups = "NRI1";
+					};
+
+					pinctrl_nri2_default: nri2_default {
+						function = "NRI2";
+						groups = "NRI2";
+					};
+
+					pinctrl_nri3_default: nri3_default {
+						function = "NRI3";
+						groups = "NRI3";
+					};
+
+					pinctrl_nri4_default: nri4_default {
+						function = "NRI4";
+						groups = "NRI4";
+					};
+
+					pinctrl_nrts1_default: nrts1_default {
+						function = "NRTS1";
+						groups = "NRTS1";
+					};
+
+					pinctrl_nrts2_default: nrts2_default {
+						function = "NRTS2";
+						groups = "NRTS2";
+					};
+
+					pinctrl_nrts3_default: nrts3_default {
+						function = "NRTS3";
+						groups = "NRTS3";
+					};
+
+					pinctrl_nrts4_default: nrts4_default {
+						function = "NRTS4";
+						groups = "NRTS4";
+					};
+
+					pinctrl_oscclk_default: oscclk_default {
+						function = "OSCCLK";
+						groups = "OSCCLK";
+					};
+
+					pinctrl_pewake_default: pewake_default {
+						function = "PEWAKE";
+						groups = "PEWAKE";
+					};
+
+					pinctrl_pnor_default: pnor_default {
+						function = "PNOR";
+						groups = "PNOR";
+					};
+
+					pinctrl_pwm0_default: pwm0_default {
+						function = "PWM0";
+						groups = "PWM0";
+					};
+
+					pinctrl_pwm1_default: pwm1_default {
+						function = "PWM1";
+						groups = "PWM1";
+					};
+
+					pinctrl_pwm2_default: pwm2_default {
+						function = "PWM2";
+						groups = "PWM2";
+					};
+
+					pinctrl_pwm3_default: pwm3_default {
+						function = "PWM3";
+						groups = "PWM3";
+					};
+
+					pinctrl_pwm4_default: pwm4_default {
+						function = "PWM4";
+						groups = "PWM4";
+					};
+
+					pinctrl_pwm5_default: pwm5_default {
+						function = "PWM5";
+						groups = "PWM5";
+					};
+
+					pinctrl_pwm6_default: pwm6_default {
+						function = "PWM6";
+						groups = "PWM6";
+					};
+
+					pinctrl_pwm7_default: pwm7_default {
+						function = "PWM7";
+						groups = "PWM7";
+					};
+
+					pinctrl_rgmii1_default: rgmii1_default {
+						function = "RGMII1";
+						groups = "RGMII1";
+					};
+
+					pinctrl_rgmii2_default: rgmii2_default {
+						function = "RGMII2";
+						groups = "RGMII2";
+					};
+
+					pinctrl_rmii1_default: rmii1_default {
+						function = "RMII1";
+						groups = "RMII1";
+					};
+
+					pinctrl_rmii2_default: rmii2_default {
+						function = "RMII2";
+						groups = "RMII2";
+					};
+
+					pinctrl_rxd1_default: rxd1_default {
+						function = "RXD1";
+						groups = "RXD1";
+					};
+
+					pinctrl_rxd2_default: rxd2_default {
+						function = "RXD2";
+						groups = "RXD2";
+					};
+
+					pinctrl_rxd3_default: rxd3_default {
+						function = "RXD3";
+						groups = "RXD3";
+					};
+
+					pinctrl_rxd4_default: rxd4_default {
+						function = "RXD4";
+						groups = "RXD4";
+					};
+
+					pinctrl_salt1_default: salt1_default {
+						function = "SALT1";
+						groups = "SALT1";
+					};
+
+					pinctrl_salt10_default: salt10_default {
+						function = "SALT10";
+						groups = "SALT10";
+					};
+
+					pinctrl_salt11_default: salt11_default {
+						function = "SALT11";
+						groups = "SALT11";
+					};
+
+					pinctrl_salt12_default: salt12_default {
+						function = "SALT12";
+						groups = "SALT12";
+					};
+
+					pinctrl_salt13_default: salt13_default {
+						function = "SALT13";
+						groups = "SALT13";
+					};
+
+					pinctrl_salt14_default: salt14_default {
+						function = "SALT14";
+						groups = "SALT14";
+					};
+
+					pinctrl_salt2_default: salt2_default {
+						function = "SALT2";
+						groups = "SALT2";
+					};
+
+					pinctrl_salt3_default: salt3_default {
+						function = "SALT3";
+						groups = "SALT3";
+					};
+
+					pinctrl_salt4_default: salt4_default {
+						function = "SALT4";
+						groups = "SALT4";
+					};
+
+					pinctrl_salt5_default: salt5_default {
+						function = "SALT5";
+						groups = "SALT5";
+					};
+
+					pinctrl_salt6_default: salt6_default {
+						function = "SALT6";
+						groups = "SALT6";
+					};
+
+					pinctrl_salt7_default: salt7_default {
+						function = "SALT7";
+						groups = "SALT7";
+					};
+
+					pinctrl_salt8_default: salt8_default {
+						function = "SALT8";
+						groups = "SALT8";
+					};
+
+					pinctrl_salt9_default: salt9_default {
+						function = "SALT9";
+						groups = "SALT9";
+					};
+
+					pinctrl_scl1_default: scl1_default {
+						function = "SCL1";
+						groups = "SCL1";
+					};
+
+					pinctrl_scl2_default: scl2_default {
+						function = "SCL2";
+						groups = "SCL2";
+					};
+
+					pinctrl_sd1_default: sd1_default {
+						function = "SD1";
+						groups = "SD1";
+					};
+
+					pinctrl_sd2_default: sd2_default {
+						function = "SD2";
+						groups = "SD2";
+					};
+
+					pinctrl_sda1_default: sda1_default {
+						function = "SDA1";
+						groups = "SDA1";
+					};
+
+					pinctrl_sda2_default: sda2_default {
+						function = "SDA2";
+						groups = "SDA2";
+					};
+
+					pinctrl_sgps1_default: sgps1_default {
+						function = "SGPS1";
+						groups = "SGPS1";
+					};
+
+					pinctrl_sgps2_default: sgps2_default {
+						function = "SGPS2";
+						groups = "SGPS2";
+					};
+
+					pinctrl_sioonctrl_default: sioonctrl_default {
+						function = "SIOONCTRL";
+						groups = "SIOONCTRL";
+					};
+
+					pinctrl_siopbi_default: siopbi_default {
+						function = "SIOPBI";
+						groups = "SIOPBI";
+					};
+
+					pinctrl_siopbo_default: siopbo_default {
+						function = "SIOPBO";
+						groups = "SIOPBO";
+					};
+
+					pinctrl_siopwreq_default: siopwreq_default {
+						function = "SIOPWREQ";
+						groups = "SIOPWREQ";
+					};
+
+					pinctrl_siopwrgd_default: siopwrgd_default {
+						function = "SIOPWRGD";
+						groups = "SIOPWRGD";
+					};
+
+					pinctrl_sios3_default: sios3_default {
+						function = "SIOS3";
+						groups = "SIOS3";
+					};
+
+					pinctrl_sios5_default: sios5_default {
+						function = "SIOS5";
+						groups = "SIOS5";
+					};
+
+					pinctrl_siosci_default: siosci_default {
+						function = "SIOSCI";
+						groups = "SIOSCI";
+					};
+
+					pinctrl_spi1_default: spi1_default {
+						function = "SPI1";
+						groups = "SPI1";
+					};
+
+					pinctrl_spi1cs1_default: spi1cs1_default {
+						function = "SPI1CS1";
+						groups = "SPI1CS1";
+					};
+
+					pinctrl_spi1debug_default: spi1debug_default {
+						function = "SPI1DEBUG";
+						groups = "SPI1DEBUG";
+					};
+
+					pinctrl_spi1passthru_default: spi1passthru_default {
+						function = "SPI1PASSTHRU";
+						groups = "SPI1PASSTHRU";
+					};
+
+					pinctrl_spi2ck_default: spi2ck_default {
+						function = "SPI2CK";
+						groups = "SPI2CK";
+					};
+
+					pinctrl_spi2cs0_default: spi2cs0_default {
+						function = "SPI2CS0";
+						groups = "SPI2CS0";
+					};
+
+					pinctrl_spi2cs1_default: spi2cs1_default {
+						function = "SPI2CS1";
+						groups = "SPI2CS1";
+					};
+
+					pinctrl_spi2miso_default: spi2miso_default {
+						function = "SPI2MISO";
+						groups = "SPI2MISO";
+					};
+
+					pinctrl_spi2mosi_default: spi2mosi_default {
+						function = "SPI2MOSI";
+						groups = "SPI2MOSI";
+					};
+
+					pinctrl_timer3_default: timer3_default {
+						function = "TIMER3";
+						groups = "TIMER3";
+					};
+
+					pinctrl_timer4_default: timer4_default {
+						function = "TIMER4";
+						groups = "TIMER4";
+					};
+
+					pinctrl_timer5_default: timer5_default {
+						function = "TIMER5";
+						groups = "TIMER5";
+					};
+
+					pinctrl_timer6_default: timer6_default {
+						function = "TIMER6";
+						groups = "TIMER6";
+					};
+
+					pinctrl_timer7_default: timer7_default {
+						function = "TIMER7";
+						groups = "TIMER7";
+					};
+
+					pinctrl_timer8_default: timer8_default {
+						function = "TIMER8";
+						groups = "TIMER8";
+					};
+
+					pinctrl_txd1_default: txd1_default {
+						function = "TXD1";
+						groups = "TXD1";
+					};
+
+					pinctrl_txd2_default: txd2_default {
+						function = "TXD2";
+						groups = "TXD2";
+					};
+
+					pinctrl_txd3_default: txd3_default {
+						function = "TXD3";
+						groups = "TXD3";
+					};
+
+					pinctrl_txd4_default: txd4_default {
+						function = "TXD4";
+						groups = "TXD4";
+					};
+
+					pinctrl_uart6_default: uart6_default {
+						function = "UART6";
+						groups = "UART6";
+					};
+
+					pinctrl_usbcki_default: usbcki_default {
+						function = "USBCKI";
+						groups = "USBCKI";
+					};
+
+					pinctrl_vgabiosrom_default: vgabiosrom_default {
+						function = "VGABIOSROM";
+						groups = "VGABIOSROM";
+					};
+
+					pinctrl_vgahs_default: vgahs_default {
+						function = "VGAHS";
+						groups = "VGAHS";
+					};
+
+					pinctrl_vgavs_default: vgavs_default {
+						function = "VGAVS";
+						groups = "VGAVS";
+					};
+
+					pinctrl_vpi24_default: vpi24_default {
+						function = "VPI24";
+						groups = "VPI24";
+					};
+
+					pinctrl_vpo_default: vpo_default {
+						function = "VPO";
+						groups = "VPO";
+					};
+
+					pinctrl_wdtrst1_default: wdtrst1_default {
+						function = "WDTRST1";
+						groups = "WDTRST1";
+					};
+
+					pinctrl_wdtrst2_default: wdtrst2_default {
+						function = "WDTRST2";
+						groups = "WDTRST2";
+					};
+
+				};
+			};
+
 			clk_hpll: clk_hpll@1e6e2024 {
 				#clock-cells = <0>;
 				compatible = "aspeed,g5-hpll-clock";
@@ -75,11 +907,27 @@
 				reg = <0x1e6e202c 0x4>;
 			};
 
+			gfx: display@1e6e6000 {
+				compatible = "aspeed,ast2500-gfx", "syscon";
+				reg = <0x1e6e6000 0x1000>;
+				reg-io-width = <4>;
+			};
+
 			sram@1e720000 {
 				compatible = "mmio-sram";
 				reg = <0x1e720000 0x9000>;	// 36K
 			};
 
+			gpio: gpio@1e780000 {
+				#gpio-cells = <2>;
+				gpio-controller;
+				compatible = "aspeed,ast2500-gpio";
+				reg = <0x1e780000 0x1000>;
+				interrupts = <20>;
+				gpio-ranges = <&pinctrl 0 0 220>;
+				interrupt-controller;
+			};
+
 			timer: timer@1e782000 {
 				compatible = "aspeed,ast2400-timer";
 				reg = <0x1e782000 0x90>;
@@ -90,6 +938,7 @@
 				clocks = <&clk_apb>;
 			};
 
+
 			wdt1: wdt@1e785000 {
 				compatible = "aspeed,wdt";
 				reg = <0x1e785000 0x1c>;
@@ -119,6 +968,36 @@
 				status = "disabled";
 			};
 
+			lpc: lpc@1e789000 {
+				compatible = "aspeed,ast2500-lpc", "simple-mfd";
+				reg = <0x1e789000 0x1000>;
+
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x1e789000 0x1000>;
+
+				lpc_bmc: lpc-bmc@0 {
+					compatible = "aspeed,ast2500-lpc-bmc";
+					reg = <0x0 0x80>;
+				};
+
+				lpc_host: lpc-host@80 {
+					compatible = "aspeed,ast2500-lpc-host", "simple-mfd", "syscon";
+					reg = <0x80 0x1e0>;
+
+					#address-cells = <1>;
+					#size-cells = <1>;
+					ranges = <0 0x80 0x1e0>;
+
+					reg-io-width = <4>;
+
+					lhc: lhc@20 {
+						compatible = "aspeed,ast2500-lhc";
+						reg = <0x20 0x24 0x48 0x8>;
+					};
+				};
+			};
+
 			uart2: serial@1e78d000 {
 				compatible = "ns16550a";
 				reg = <0x1e78d000 0x1000>;
diff --git a/arch/arm/dts/stm32f7-u-boot.dtsi b/arch/arm/dts/stm32f7-u-boot.dtsi
new file mode 100644
index 0000000..5f77f57
--- /dev/null
+++ b/arch/arm/dts/stm32f7-u-boot.dtsi
@@ -0,0 +1,24 @@
+&pinctrl {
+	usart1_pins_a: usart1@0	{
+		u-boot,dm-pre-reloc;
+		pins1 {
+			u-boot,dm-pre-reloc;
+		};
+		pins2 {
+			u-boot,dm-pre-reloc;
+		};
+	};
+	fmc_pins: fmc@0 {
+		u-boot,dm-pre-reloc;
+		pins
+		{
+		 u-boot,dm-pre-reloc;
+		};
+	};
+};
+
+&fmc {
+	bank1: bank@0 {
+		 u-boot,dm-pre-reloc;
+	};
+};
diff --git a/arch/arm/dts/stm32f746-disco.dts b/arch/arm/dts/stm32f746-disco.dts
index 07e0ca7..2c7fa79 100644
--- a/arch/arm/dts/stm32f746-disco.dts
+++ b/arch/arm/dts/stm32f746-disco.dts
@@ -1,5 +1,6 @@
 /*
  * Copyright 2016 - Michael Kurz <michi.kurz@gmail.com>
+ * Copyright 2016 - Vikas MANOCHA <vikas.manocha@st.com>
  *
  * Based on:
  * stm32f469-disco.dts from Linux
@@ -46,6 +47,7 @@
 
 /dts-v1/;
 #include "stm32f746.dtsi"
+#include <dt-bindings/memory/stm32-sdram.h>
 
 / {
 	model = "STMicroelectronics STM32F746-DISCO board";
@@ -63,6 +65,28 @@
 	aliases {
 		serial0 = &usart1;
 		spi0 = &qspi;
+		/* Aliases for gpios so as to use sequence */
+		gpio0 = &gpioa;
+		gpio1 = &gpiob;
+		gpio2 = &gpioc;
+		gpio3 = &gpiod;
+		gpio4 = &gpioe;
+		gpio5 = &gpiof;
+		gpio6 = &gpiog;
+		gpio7 = &gpioh;
+		gpio8 = &gpioi;
+		gpio9 = &gpioj;
+		gpio10 = &gpiok;
+	};
+
+	led1 {
+		compatible = "st,led1";
+		led-gpio = <&gpioi 1 0>;
+	};
+
+	button1 {
+		compatible = "st,button1";
+		button-gpio = <&gpioi 11 0>;
 	};
 };
 
@@ -70,12 +94,120 @@
 	clock-frequency = <25000000>;
 };
 
+&pinctrl {
+	usart1_pins_a: usart1@0	{
+		pins1 {
+		       pinmux = <STM32F746_PA9_FUNC_USART1_TX>;
+				bias-disable;
+				drive-push-pull;
+				slew-rate = <2>;
+		};
+		pins2 {
+			pinmux = <STM32F746_PB7_FUNC_USART1_RX>;
+			bias-disable;
+		};
+	};
+
+	ethernet_mii: mii@0 {
+	      pins {
+		      pinmux = <STM32F746_PG13_FUNC_ETH_MII_TXD0_ETH_RMII_TXD0>,
+			     <STM32F746_PG14_FUNC_ETH_MII_TXD1_ETH_RMII_TXD1>,
+			     <STM32F746_PG11_FUNC_ETH_MII_TX_EN_ETH_RMII_TX_EN>,
+			     <STM32F746_PA2_FUNC_ETH_MDIO>,
+			     <STM32F746_PC1_FUNC_ETH_MDC>,
+			     <STM32F746_PA1_FUNC_ETH_MII_RX_CLK_ETH_RMII_REF_CLK>,
+			     <STM32F746_PA7_FUNC_ETH_MII_RX_DV_ETH_RMII_CRS_DV>,
+			     <STM32F746_PC4_FUNC_ETH_MII_RXD0_ETH_RMII_RXD0>,
+			     <STM32F746_PC5_FUNC_ETH_MII_RXD1_ETH_RMII_RXD1>;
+		      slew-rate = <2>;
+	      };
+	};
+
+	qspi_pins: qspi@0 {
+		pins {
+			pinmux = <STM32F746_PB2_FUNC_QUADSPI_CLK>,
+			       <STM32F746_PB6_FUNC_QUADSPI_BK1_NCS>,
+			       <STM32F746_PD11_FUNC_QUADSPI_BK1_IO0>,
+			       <STM32F746_PD12_FUNC_QUADSPI_BK1_IO1>,
+			       <STM32F746_PD13_FUNC_QUADSPI_BK1_IO3>,
+			       <STM32F746_PE2_FUNC_QUADSPI_BK1_IO2>;
+			slew-rate = <2>;
+		};
+	};
+
+	fmc_pins: fmc@0 {
+		pins {
+			pinmux = <STM32F746_PD10_FUNC_FMC_D15>,
+				 <STM32F746_PD9_FUNC_FMC_D14>,
+				 <STM32F746_PD8_FUNC_FMC_D13>,
+				 <STM32F746_PE15_FUNC_FMC_D12>,
+				 <STM32F746_PE14_FUNC_FMC_D11>,
+				 <STM32F746_PE13_FUNC_FMC_D10>,
+				 <STM32F746_PE12_FUNC_FMC_D9>,
+				 <STM32F746_PE11_FUNC_FMC_D8>,
+				 <STM32F746_PE10_FUNC_FMC_D7>,
+				 <STM32F746_PE9_FUNC_FMC_D6>,
+				 <STM32F746_PE8_FUNC_FMC_D5>,
+				 <STM32F746_PE7_FUNC_FMC_D4>,
+				 <STM32F746_PD1_FUNC_FMC_D3>,
+				 <STM32F746_PD0_FUNC_FMC_D2>,
+				 <STM32F746_PD15_FUNC_FMC_D1>,
+				 <STM32F746_PD14_FUNC_FMC_D0>,
+
+				 <STM32F746_PE1_FUNC_FMC_NBL1>,
+				 <STM32F746_PE0_FUNC_FMC_NBL0>,
+
+				 <STM32F746_PG5_FUNC_FMC_A15_FMC_BA1>,
+				 <STM32F746_PG4_FUNC_FMC_A14_FMC_BA0>,
+
+				 <STM32F746_PG1_FUNC_FMC_A11>,
+				 <STM32F746_PG0_FUNC_FMC_A10>,
+				 <STM32F746_PF15_FUNC_FMC_A9>,
+				 <STM32F746_PF14_FUNC_FMC_A8>,
+				 <STM32F746_PF13_FUNC_FMC_A7>,
+				 <STM32F746_PF12_FUNC_FMC_A6>,
+				 <STM32F746_PF5_FUNC_FMC_A5>,
+				 <STM32F746_PF4_FUNC_FMC_A4>,
+				 <STM32F746_PF3_FUNC_FMC_A3>,
+				 <STM32F746_PF2_FUNC_FMC_A2>,
+				 <STM32F746_PF1_FUNC_FMC_A1>,
+				 <STM32F746_PF0_FUNC_FMC_A0>,
+
+				 <STM32F746_PH3_FUNC_FMC_SDNE0>,
+				 <STM32F746_PH5_FUNC_FMC_SDNWE>,
+				 <STM32F746_PF11_FUNC_FMC_SDNRAS>,
+				 <STM32F746_PG15_FUNC_FMC_SDNCAS>,
+				 <STM32F746_PC3_FUNC_FMC_SDCKE0>,
+				 <STM32F746_PG8_FUNC_FMC_SDCLK>;
+			  slew-rate = <2>;
+		};
+	};
+};
+
 &usart1 {
 	pinctrl-0 = <&usart1_pins_a>;
 	pinctrl-names = "default";
 	status = "okay";
 };
 
+&fmc {
+	pinctrl-0 = <&fmc_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	mr-nbanks = <1>;
+	/* Memory configuration from sdram datasheet MT48LC_4M32_B2B5-6A */
+	bank1: bank@0 {
+	       st,sdram-control = /bits/ 8 <NO_COL_8 NO_ROW_12 MWIDTH_16 BANKS_4
+	       				    CAS_3 SDCLK_2 RD_BURST_EN
+					    RD_PIPE_DL_0>;
+	       st,sdram-timing = /bits/ 8 <TMRD_2 TXSR_6 TRAS_4 TRC_6 TWR_2
+	       				   TRP_2 TRCD_2>;
+		/* refcount = (64msec/total_row_sdram)*freq - 20 */
+	       st,sdram-refcount = < 1542 >;
+       };
+};
+
 &mac {
 	status = "okay";
 	pinctrl-0 = <&ethernet_mii>;
diff --git a/arch/arm/dts/stm32f746.dtsi b/arch/arm/dts/stm32f746.dtsi
index b2b0b5f..ac24d98 100644
--- a/arch/arm/dts/stm32f746.dtsi
+++ b/arch/arm/dts/stm32f746.dtsi
@@ -1,5 +1,6 @@
 /*
  * Copyright 2016 - Michael Kurz <michi.kurz@gmail.com>
+ * Copyright 2016 - Vikas MANOCHA <vikas.manocha@st.com>
  *
  * Based on:
  * stm32f429.dtsi from Linux
@@ -70,6 +71,13 @@
 			status = "disabled";
 		};
 
+		fmc: fmc@A0000000 {
+			compatible = "st,stm32-fmc";
+			reg = <0xA0000000 0x1000>;
+			clocks = <&rcc 0 64>;
+			u-boot,dm-pre-reloc;
+		};
+
 		qspi: quadspi@A0001000 {
 			compatible = "st,stm32-qspi";
 			#address-cells = <1>;
@@ -78,6 +86,7 @@
 			reg-names = "QuadSPI", "QuadSPI-memory";
 			interrupts = <92>;
 			spi-max-frequency = <108000000>;
+			clocks = <&rcc 0 65>;
 			status = "disabled";
 		};
 		usart1: serial@40011000 {
@@ -105,43 +114,117 @@
 			u-boot,dm-pre-reloc;
 			pins-are-numbered;
 
+			gpioa: gpio@40020000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				compatible = "st,stm32-gpio";
+				reg = <0x0 0x400>;
+				clocks = <&rcc 0 0>;
+				st,bank-name = "GPIOA";
+				u-boot,dm-pre-reloc;
+			};
+
+			gpiob: gpio@40020400 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				compatible = "st,stm32-gpio";
+				reg = <0x400 0x400>;
+				clocks = <&rcc 0 1>;
+				st,bank-name = "GPIOB";
+				u-boot,dm-pre-reloc;
+			};
+
+
+			gpioc: gpio@40020800 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				compatible = "st,stm32-gpio";
+				reg = <0x800 0x400>;
+				clocks = <&rcc 0 2>;
+				st,bank-name = "GPIOC";
+				u-boot,dm-pre-reloc;
+			};
+
-			usart1_pins_a: usart1@0 {
-				pins1 {
-					pinmux = <STM32F746_PA9_FUNC_USART1_TX>;
-					bias-disable;
-					drive-push-pull;
-					slew-rate = <2>;
-				};
-				pins2 {
-					pinmux = <STM32F746_PB7_FUNC_USART1_RX>;
-					bias-disable;
-				};
+			gpiod: gpio@40020c00 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				compatible = "st,stm32-gpio";
+				reg = <0xc00 0x400>;
+				clocks = <&rcc 0 3>;
+				st,bank-name = "GPIOD";
+				u-boot,dm-pre-reloc;
 			};
-			ethernet_mii: mii@0 {
-				pins {
-					pinmux = <STM32F746_PG13_FUNC_ETH_MII_TXD0_ETH_RMII_TXD0>,
-						 <STM32F746_PG14_FUNC_ETH_MII_TXD1_ETH_RMII_TXD1>,
-						 <STM32F746_PG11_FUNC_ETH_MII_TX_EN_ETH_RMII_TX_EN>,
-						 <STM32F746_PA2_FUNC_ETH_MDIO>,
-						 <STM32F746_PC1_FUNC_ETH_MDC>,
-						 <STM32F746_PA1_FUNC_ETH_MII_RX_CLK_ETH_RMII_REF_CLK>,
-						 <STM32F746_PA7_FUNC_ETH_MII_RX_DV_ETH_RMII_CRS_DV>,
-						 <STM32F746_PC4_FUNC_ETH_MII_RXD0_ETH_RMII_RXD0>,
-						 <STM32F746_PC5_FUNC_ETH_MII_RXD1_ETH_RMII_RXD1>;
-					slew-rate = <2>;
-				};
+
+			gpioe: gpio@40021000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				compatible = "st,stm32-gpio";
+				reg = <0x1000 0x400>;
+				clocks = <&rcc 0 4>;
+				st,bank-name = "GPIOE";
+				u-boot,dm-pre-reloc;
 			};
-			qspi_pins: qspi@0{
-				pins {
-					pinmux = <STM32F746_PB2_FUNC_QUADSPI_CLK>,
-						 <STM32F746_PB6_FUNC_QUADSPI_BK1_NCS>,
-						 <STM32F746_PD11_FUNC_QUADSPI_BK1_IO0>,
-						 <STM32F746_PD12_FUNC_QUADSPI_BK1_IO1>,
-						 <STM32F746_PD13_FUNC_QUADSPI_BK1_IO3>,
-						 <STM32F746_PE2_FUNC_QUADSPI_BK1_IO2>;
-					slew-rate = <2>;
-				};
+
+			gpiof: gpio@40021400 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				compatible = "st,stm32-gpio";
+				reg = <0x1400 0x400>;
+				clocks = <&rcc 0 5>;
+				st,bank-name = "GPIOF";
+				u-boot,dm-pre-reloc;
 			};
+
+			gpiog: gpio@40021800 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				compatible = "st,stm32-gpio";
+				reg = <0x1800 0x400>;
+				clocks = <&rcc 0 6>;
+				st,bank-name = "GPIOG";
+				u-boot,dm-pre-reloc;
+			};
+
+			gpioh: gpio@40021c00 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				compatible = "st,stm32-gpio";
+				reg = <0x1c00 0x400>;
+				clocks = <&rcc 0 7>;
+				st,bank-name = "GPIOH";
+				u-boot,dm-pre-reloc;
+			};
+
+			gpioi: gpio@40022000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				compatible = "st,stm32-gpio";
+				reg = <0x2000 0x400>;
+				clocks = <&rcc 0 8>;
+				st,bank-name = "GPIOI";
+				u-boot,dm-pre-reloc;
+			};
+
+			gpioj: gpio@40022400 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				compatible = "st,stm32-gpio";
+				reg = <0x2400 0x400>;
+				clocks = <&rcc 0 9>;
+				st,bank-name = "GPIOJ";
+				u-boot,dm-pre-reloc;
+			};
+
+			gpiok: gpio@40022800 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				compatible = "st,stm32-gpio";
+				reg = <0x2800 0x400>;
+				clocks = <&rcc 0 10>;
+				st,bank-name = "GPIOK";
+				u-boot,dm-pre-reloc;
+			};
+
 		};
 	};
 };
diff --git a/arch/arm/dts/stm32f769-disco.dts b/arch/arm/dts/stm32f769-disco.dts
new file mode 100644
index 0000000..6591cc8
--- /dev/null
+++ b/arch/arm/dts/stm32f769-disco.dts
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2016 - Vikas Manocha <vikas.manocha@st.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "stm32f746.dtsi"
+#include <dt-bindings/memory/stm32-sdram.h>
+
+/ {
+	model = "STMicroelectronics STM32F769-DISCO board";
+	compatible = "st,stm32f769-disco", "st,stm32f7";
+
+	chosen {
+		bootargs = "root=/dev/ram rdinit=/linuxrc";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory {
+		reg = <0xC0000000 0x1000000>;
+	};
+
+	aliases {
+		serial0 = &usart1;
+		spi0 = &qspi;
+		/* Aliases for gpios so as to use sequence */
+		gpio0 = &gpioa;
+		gpio1 = &gpiob;
+		gpio2 = &gpioc;
+		gpio3 = &gpiod;
+		gpio4 = &gpioe;
+		gpio5 = &gpiof;
+		gpio6 = &gpiog;
+		gpio7 = &gpioh;
+		gpio8 = &gpioi;
+		gpio9 = &gpioj;
+		gpio10 = &gpiok;
+	};
+
+	led1 {
+		compatible = "st,led1";
+		led-gpio = <&gpioj 5 0>;
+	};
+
+	button1 {
+		compatible = "st,button1";
+		button-gpio = <&gpioa 0 0>;
+	};
+};
+
+&clk_hse {
+	clock-frequency = <25000000>;
+};
+
+&pinctrl {
+	usart1_pins_a: usart1@0	{
+		pins1 {
+		       pinmux = <STM32F746_PA9_FUNC_USART1_TX>;
+				bias-disable;
+				drive-push-pull;
+				slew-rate = <2>;
+		};
+		pins2 {
+			pinmux = <STM32F746_PA10_FUNC_USART1_RX>;
+			bias-disable;
+		};
+	};
+
+	ethernet_mii: mii@0 {
+	      pins {
+		      pinmux = <STM32F746_PG13_FUNC_ETH_MII_TXD0_ETH_RMII_TXD0>,
+			     <STM32F746_PG14_FUNC_ETH_MII_TXD1_ETH_RMII_TXD1>,
+			     <STM32F746_PG11_FUNC_ETH_MII_TX_EN_ETH_RMII_TX_EN>,
+			     <STM32F746_PA2_FUNC_ETH_MDIO>,
+			     <STM32F746_PC1_FUNC_ETH_MDC>,
+			     <STM32F746_PA1_FUNC_ETH_MII_RX_CLK_ETH_RMII_REF_CLK>,
+			     <STM32F746_PA7_FUNC_ETH_MII_RX_DV_ETH_RMII_CRS_DV>,
+			     <STM32F746_PC4_FUNC_ETH_MII_RXD0_ETH_RMII_RXD0>,
+			     <STM32F746_PC5_FUNC_ETH_MII_RXD1_ETH_RMII_RXD1>;
+		      slew-rate = <2>;
+	      };
+	};
+
+	qspi_pins: qspi@0 {
+		pins {
+			pinmux = <STM32F746_PB2_FUNC_QUADSPI_CLK>,
+			       <STM32F746_PB6_FUNC_QUADSPI_BK1_NCS>,
+			       <STM32F746_PC9_FUNC_QUADSPI_BK1_IO0>,
+			       <STM32F746_PC10_FUNC_QUADSPI_BK1_IO1>,
+			       <STM32F746_PD13_FUNC_QUADSPI_BK1_IO3>,
+			       <STM32F746_PE2_FUNC_QUADSPI_BK1_IO2>;
+			slew-rate = <2>;
+		};
+	};
+
+	fmc_pins: fmc@0 {
+		  pins {
+			  pinmux = <STM32F746_PI10_FUNC_FMC_D31>,
+				 <STM32F746_PI9_FUNC_FMC_D30>,
+				 <STM32F746_PI7_FUNC_FMC_D29>,
+				 <STM32F746_PI6_FUNC_FMC_D28>,
+				 <STM32F746_PI3_FUNC_FMC_D27>,
+				 <STM32F746_PI2_FUNC_FMC_D26>,
+				 <STM32F746_PI1_FUNC_FMC_D25>,
+				 <STM32F746_PI0_FUNC_FMC_D24>,
+				 <STM32F746_PH15_FUNC_FMC_D23>,
+				 <STM32F746_PH14_FUNC_FMC_D22>,
+				 <STM32F746_PH13_FUNC_FMC_D21>,
+				 <STM32F746_PH12_FUNC_FMC_D20>,
+				 <STM32F746_PH11_FUNC_FMC_D19>,
+				 <STM32F746_PH10_FUNC_FMC_D18>,
+				 <STM32F746_PH9_FUNC_FMC_D17>,
+				 <STM32F746_PH8_FUNC_FMC_D16>,
+
+				 <STM32F746_PD10_FUNC_FMC_D15>,
+				 <STM32F746_PD9_FUNC_FMC_D14>,
+				 <STM32F746_PD8_FUNC_FMC_D13>,
+				 <STM32F746_PE15_FUNC_FMC_D12>,
+				 <STM32F746_PE14_FUNC_FMC_D11>,
+				 <STM32F746_PE13_FUNC_FMC_D10>,
+				 <STM32F746_PE12_FUNC_FMC_D9>,
+				 <STM32F746_PE11_FUNC_FMC_D8>,
+				 <STM32F746_PE10_FUNC_FMC_D7>,
+				 <STM32F746_PE9_FUNC_FMC_D6>,
+				 <STM32F746_PE8_FUNC_FMC_D5>,
+				 <STM32F746_PE7_FUNC_FMC_D4>,
+				 <STM32F746_PD1_FUNC_FMC_D3>,
+				 <STM32F746_PD0_FUNC_FMC_D2>,
+				 <STM32F746_PD15_FUNC_FMC_D1>,
+				 <STM32F746_PD14_FUNC_FMC_D0>,
+
+				 <STM32F746_PI5_FUNC_FMC_NBL3>,
+				 <STM32F746_PI4_FUNC_FMC_NBL2>,
+				 <STM32F746_PE1_FUNC_FMC_NBL1>,
+				 <STM32F746_PE0_FUNC_FMC_NBL0>,
+
+				 <STM32F746_PG5_FUNC_FMC_A15_FMC_BA1>,
+				 <STM32F746_PG4_FUNC_FMC_A14_FMC_BA0>,
+
+				 <STM32F746_PG1_FUNC_FMC_A11>,
+				 <STM32F746_PG0_FUNC_FMC_A10>,
+				 <STM32F746_PF15_FUNC_FMC_A9>,
+				 <STM32F746_PF14_FUNC_FMC_A8>,
+				 <STM32F746_PF13_FUNC_FMC_A7>,
+				 <STM32F746_PF12_FUNC_FMC_A6>,
+				 <STM32F746_PF5_FUNC_FMC_A5>,
+				 <STM32F746_PF4_FUNC_FMC_A4>,
+				 <STM32F746_PF3_FUNC_FMC_A3>,
+				 <STM32F746_PF2_FUNC_FMC_A2>,
+				 <STM32F746_PF1_FUNC_FMC_A1>,
+				 <STM32F746_PF0_FUNC_FMC_A0>,
+
+				 <STM32F746_PH3_FUNC_FMC_SDNE0>,
+				 <STM32F746_PH5_FUNC_FMC_SDNWE>,
+				 <STM32F746_PF11_FUNC_FMC_SDNRAS>,
+				 <STM32F746_PG15_FUNC_FMC_SDNCAS>,
+				 <STM32F746_PH2_FUNC_FMC_SDCKE0>,
+				 <STM32F746_PG8_FUNC_FMC_SDCLK>;
+			  slew-rate = <2>;
+		  };
+	  };
+};
+
+&usart1 {
+	pinctrl-0 = <&usart1_pins_a>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&fmc {
+	pinctrl-0 = <&fmc_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	mr-nbanks = <1>;
+	/* Memory configuration from sdram datasheet MT48LC_4M32_B2B5-6A */
+	bank1: bank@0 {
+	       st,sdram-control = /bits/ 8 <NO_COL_8 NO_ROW_12 MWIDTH_32 BANKS_4
+	       				    CAS_3 SDCLK_2 RD_BURST_EN
+					    RD_PIPE_DL_0>;
+	       st,sdram-timing = /bits/ 8 <TMRD_2 TXSR_6 TRAS_4 TRC_6 TWR_2
+	       				   TRP_2 TRCD_2>;
+		/* refcount = (64msec/total_row_sdram)*freq - 20 */
+	       st,sdram-refcount = < 1542 >;
+       };
+};
+
+&mac {
+	status = "okay";
+	pinctrl-0 = <&ethernet_mii>;
+	phy-mode = "rmii";
+	phy-handle = <&phy0>;
+
+	mdio0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "snps,dwmac-mdio";
+		phy0: ethernet-phy@0 {
+			reg = <0>;
+		};
+	};
+};
+
+&qspi {
+	pinctrl-0 = <&qspi_pins>;
+	status = "okay";
+
+	qflash0: n25q128a {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "micron,n25q128a13", "spi-flash";
+			spi-max-frequency = <108000000>;
+			spi-tx-bus-width = <1>;
+			spi-rx-bus-width = <1>;
+			memory-map = <0x90000000 0x1000000>;
+			reg = <0>;
+	};
+};
diff --git a/arch/arm/include/asm/arch-am33xx/spl.h b/arch/arm/include/asm/arch-am33xx/spl.h
index f744ab0..4b5a48e 100644
--- a/arch/arm/include/asm/arch-am33xx/spl.h
+++ b/arch/arm/include/asm/arch-am33xx/spl.h
@@ -28,7 +28,7 @@
 #define BOOT_DEVICE_XIP		0x01
 #define BOOT_DEVICE_XIPWAIT	0x02
 #define BOOT_DEVICE_NAND	0x03
-#define BOOT_DEVICE_ONENAD	0x04
+#define BOOT_DEVICE_ONENAND	0x04
 #define BOOT_DEVICE_MMC2	0x05 /* ROM only supports 2nd instance. */
 #define BOOT_DEVICE_MMC1	0x06
 #define BOOT_DEVICE_UART	0x43
@@ -47,6 +47,7 @@
 #define BOOT_DEVICE_UART	0x41
 #define BOOT_DEVICE_USBETH	0x44
 #define BOOT_DEVICE_CPGMAC	0x46
+#define BOOT_DEVICE_ONENAND	0xFF /* ROM does not support OneNAND. */
 
 #define MMC_BOOT_DEVICES_START	BOOT_DEVICE_MMC1
 #define MMC_BOOT_DEVICES_END	BOOT_DEVICE_MMC2
diff --git a/arch/arm/include/asm/arch-aspeed/pinctrl.h b/arch/arm/include/asm/arch-aspeed/pinctrl.h
new file mode 100644
index 0000000..365dc21
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/pinctrl.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _ASM_ARCH_PERIPH_H
+#define _ASM_ARCH_PERIPH_H
+
+/*
+ * Peripherals supported by the hardware.
+ * These are used to specify pinctrl settings.
+ */
+
+enum periph_id {
+	PERIPH_ID_UART1,
+	PERIPH_ID_UART2,
+	PERIPH_ID_UART3,
+	PERIPH_ID_UART4,
+	PERIPH_ID_LPC,
+	PERIPH_ID_PWM0,
+	PERIPH_ID_PWM1,
+	PERIPH_ID_PWM2,
+	PERIPH_ID_PWM3,
+	PERIPH_ID_PWM4,
+	PERIPH_ID_PWM5,
+	PERIPH_ID_PWM6,
+	PERIPH_ID_PWM7,
+	PERIPH_ID_PWM8,
+	PERIPH_ID_MAC1,
+	PERIPH_ID_MAC2,
+	PERIPH_ID_VIDEO,
+	PERIPH_ID_SPI1,
+	PERIPH_ID_SPI2,
+	PERIPH_ID_I2C1,
+	PERIPH_ID_I2C2,
+	PERIPH_ID_I2C3,
+	PERIPH_ID_I2C4,
+	PERIPH_ID_I2C5,
+	PERIPH_ID_I2C6,
+	PERIPH_ID_I2C7,
+	PERIPH_ID_I2C8,
+	PERIPH_ID_I2C9,
+	PERIPH_ID_I2C10,
+	PERIPH_ID_I2C11,
+	PERIPH_ID_I2C12,
+	PERIPH_ID_I2C13,
+	PERIPH_ID_I2C14,
+	PERIPH_ID_SD1,
+	PERIPH_ID_SD2,
+};
+
+#endif  /* _ASM_ARCH_SCU_AST2500_H */
diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
index fc0c01a..590aed2 100644
--- a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
+++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
@@ -8,28 +8,134 @@
 
 #define SCU_UNLOCK_VALUE		0x1688a8a8
 
-#define SCU_HWSTRAP_VGAMEM_MASK		3
 #define SCU_HWSTRAP_VGAMEM_SHIFT	2
+#define SCU_HWSTRAP_VGAMEM_MASK		(3 << SCU_HWSTRAP_VGAMEM_SHIFT)
+#define SCU_HWSTRAP_MAC1_RGMII		(1 << 6)
+#define SCU_HWSTRAP_MAC2_RGMII		(1 << 7)
 #define SCU_HWSTRAP_DDR4		(1 << 24)
 #define SCU_HWSTRAP_CLKIN_25MHZ		(1 << 23)
 
 #define SCU_MPLL_DENUM_SHIFT		0
 #define SCU_MPLL_DENUM_MASK		0x1f
 #define SCU_MPLL_NUM_SHIFT		5
-#define SCU_MPLL_NUM_MASK		0xff
+#define SCU_MPLL_NUM_MASK		(0xff << SCU_MPLL_NUM_SHIFT)
 #define SCU_MPLL_POST_SHIFT		13
-#define SCU_MPLL_POST_MASK		0x3f
-
+#define SCU_MPLL_POST_MASK		(0x3f << SCU_MPLL_POST_SHIFT)
+#define SCU_PCLK_DIV_SHIFT		23
+#define SCU_PCLK_DIV_MASK		(7 << SCU_PCLK_DIV_SHIFT)
 #define SCU_HPLL_DENUM_SHIFT		0
 #define SCU_HPLL_DENUM_MASK		0x1f
 #define SCU_HPLL_NUM_SHIFT		5
-#define SCU_HPLL_NUM_MASK		0xff
+#define SCU_HPLL_NUM_MASK		(0xff << SCU_HPLL_NUM_SHIFT)
 #define SCU_HPLL_POST_SHIFT		13
-#define SCU_HPLL_POST_MASK		0x3f
+#define SCU_HPLL_POST_MASK		(0x3f << SCU_HPLL_POST_SHIFT)
 
+#define SCU_MACCLK_SHIFT		16
+#define SCU_MACCLK_MASK			(7 << SCU_MACCLK_SHIFT)
+
+#define SCU_MISC2_RGMII_HPLL		(1 << 23)
+#define SCU_MISC2_RGMII_CLKDIV_SHIFT	20
+#define SCU_MISC2_RGMII_CLKDIV_MASK	(3 << SCU_MISC2_RGMII_CLKDIV_SHIFT)
+#define SCU_MISC2_RMII_MPLL		(1 << 19)
+#define SCU_MISC2_RMII_CLKDIV_SHIFT	16
+#define SCU_MISC2_RMII_CLKDIV_MASK	(3 << SCU_MISC2_RMII_CLKDIV_SHIFT)
 #define SCU_MISC2_UARTCLK_SHIFT		24
 
+#define SCU_MISC_D2PLL_OFF		(1 << 4)
 #define SCU_MISC_UARTCLK_DIV13		(1 << 12)
+#define SCU_MISC_GCRT_USB20CLK		(1 << 21)
+
+#define SCU_MICDS_MAC1RGMII_TXDLY_SHIFT	0
+#define SCU_MICDS_MAC1RGMII_TXDLY_MASK	(0x3f\
+					 << SCU_MICDS_MAC1RGMII_TXDLY_SHIFT)
+#define SCU_MICDS_MAC2RGMII_TXDLY_SHIFT	6
+#define SCU_MICDS_MAC2RGMII_TXDLY_MASK	(0x3f\
+					 << SCU_MICDS_MAC2RGMII_TXDLY_SHIFT)
+#define SCU_MICDS_MAC1RMII_RDLY_SHIFT	12
+#define SCU_MICDS_MAC1RMII_RDLY_MASK	(0x3f << SCU_MICDS_MAC1RMII_RDLY_SHIFT)
+#define SCU_MICDS_MAC2RMII_RDLY_SHIFT	18
+#define SCU_MICDS_MAC2RMII_RDLY_MASK	(0x3f << SCU_MICDS_MAC2RMII_RDLY_SHIFT)
+#define SCU_MICDS_MAC1RMII_TXFALL	(1 << 24)
+#define SCU_MICDS_MAC2RMII_TXFALL	(1 << 25)
+#define SCU_MICDS_RMII1_RCLKEN		(1 << 29)
+#define SCU_MICDS_RMII2_RCLKEN		(1 << 30)
+#define SCU_MICDS_RGMIIPLL		(1 << 31)
+
+/*
+ * SYSRESET is actually more like a Power register,
+ * except that corresponding bit set to 1 means that
+ * the peripheral is off.
+ */
+#define SCU_SYSRESET_XDMA		(1 << 25)
+#define SCU_SYSRESET_MCTP		(1 << 24)
+#define SCU_SYSRESET_ADC		(1 << 23)
+#define SCU_SYSRESET_JTAG		(1 << 22)
+#define SCU_SYSRESET_MIC		(1 << 18)
+#define SCU_SYSRESET_SDIO		(1 << 16)
+#define SCU_SYSRESET_USB11HOST		(1 << 15)
+#define SCU_SYSRESET_USBHUB		(1 << 14)
+#define SCU_SYSRESET_CRT		(1 << 13)
+#define SCU_SYSRESET_MAC2		(1 << 12)
+#define SCU_SYSRESET_MAC1		(1 << 11)
+#define SCU_SYSRESET_PECI		(1 << 10)
+#define SCU_SYSRESET_PWM		(1 << 9)
+#define SCU_SYSRESET_PCI_VGA		(1 << 8)
+#define SCU_SYSRESET_2D			(1 << 7)
+#define SCU_SYSRESET_VIDEO		(1 << 6)
+#define SCU_SYSRESET_LPC		(1 << 5)
+#define SCU_SYSRESET_HAC		(1 << 4)
+#define SCU_SYSRESET_USBHID		(1 << 3)
+#define SCU_SYSRESET_I2C		(1 << 2)
+#define SCU_SYSRESET_AHB		(1 << 1)
+#define SCU_SYSRESET_SDRAM_WDT		(1 << 0)
+
+/* Bits 16-27 in the register control pin functions for I2C devices 3-14 */
+#define SCU_PINMUX_CTRL5_I2C		(1 << 16)
+
+/*
+ * The values are grouped by function, not by register.
+ * They are actually scattered across multiple loosely related registers.
+ */
+#define SCU_PIN_FUN_MAC1_MDC		(1 << 30)
+#define SCU_PIN_FUN_MAC1_MDIO		(1 << 31)
+#define SCU_PIN_FUN_MAC1_PHY_LINK	(1 << 0)
+#define SCU_PIN_FUN_MAC2_MDIO		(1 << 2)
+#define SCU_PIN_FUN_MAC2_PHY_LINK	(1 << 1)
+#define SCU_PIN_FUN_SCL1		(1 << 12)
+#define SCU_PIN_FUN_SCL2		(1 << 14)
+#define SCU_PIN_FUN_SDA1		(1 << 13)
+#define SCU_PIN_FUN_SDA2		(1 << 15)
+
+#define SCU_CLKSTOP_MAC1		(1 << 20)
+#define SCU_CLKSTOP_MAC2		(1 << 21)
+
+#define SCU_D2PLL_EXT1_OFF		(1 << 0)
+#define SCU_D2PLL_EXT1_BYPASS		(1 << 1)
+#define SCU_D2PLL_EXT1_RESET		(1 << 2)
+#define SCU_D2PLL_EXT1_MODE_SHIFT	3
+#define SCU_D2PLL_EXT1_MODE_MASK	(3 << SCU_D2PLL_EXT1_MODE_SHIFT)
+#define SCU_D2PLL_EXT1_PARAM_SHIFT	5
+#define SCU_D2PLL_EXT1_PARAM_MASK	(0x1ff << SCU_D2PLL_EXT1_PARAM_SHIFT)
+
+#define SCU_D2PLL_NUM_SHIFT		0
+#define SCU_D2PLL_NUM_MASK		(0xff << SCU_D2PLL_NUM_SHIFT)
+#define SCU_D2PLL_DENUM_SHIFT		8
+#define SCU_D2PLL_DENUM_MASK		(0x1f << SCU_D2PLL_DENUM_SHIFT)
+#define SCU_D2PLL_POST_SHIFT		13
+#define SCU_D2PLL_POST_MASK		(0x3f << SCU_D2PLL_POST_SHIFT)
+#define SCU_D2PLL_ODIV_SHIFT		19
+#define SCU_D2PLL_ODIV_MASK		(7 << SCU_D2PLL_ODIV_SHIFT)
+#define SCU_D2PLL_SIC_SHIFT		22
+#define SCU_D2PLL_SIC_MASK		(0x1f << SCU_D2PLL_SIC_SHIFT)
+#define SCU_D2PLL_SIP_SHIFT		27
+#define SCU_D2PLL_SIP_MASK		(0x1f << SCU_D2PLL_SIP_SHIFT)
+
+#define SCU_CLKDUTY_DCLK_SHIFT		0
+#define SCU_CLKDUTY_DCLK_MASK		(0x3f << SCU_CLKDUTY_DCLK_SHIFT)
+#define SCU_CLKDUTY_RGMII1TXCK_SHIFT	8
+#define SCU_CLKDUTY_RGMII1TXCK_MASK	(0x7f << SCU_CLKDUTY_RGMII1TXCK_SHIFT)
+#define SCU_CLKDUTY_RGMII2TXCK_SHIFT	16
+#define SCU_CLKDUTY_RGMII2TXCK_MASK	(0x7f << SCU_CLKDUTY_RGMII2TXCK_SHIFT)
 
 #ifndef __ASSEMBLY__
 
@@ -120,6 +226,20 @@
  */
 void *ast_get_scu(void);
 
+/**
+ * ast_scu_unlock() - unlock protected registers
+ *
+ * @scu, pointer to ast2500_scu
+ */
+void ast_scu_unlock(struct ast2500_scu *scu);
+
+/**
+ * ast_scu_lock() - lock protected registers
+ *
+ * @scu, pointer to ast2500_scu
+ */
+void ast_scu_lock(struct ast2500_scu *scu);
+
 #endif  /* __ASSEMBLY__ */
 
 #endif  /* _ASM_ARCH_SCU_AST2500_H */
diff --git a/arch/arm/include/asm/arch-aspeed/wdt.h b/arch/arm/include/asm/arch-aspeed/wdt.h
index b292a0e..db8ecbc 100644
--- a/arch/arm/include/asm/arch-aspeed/wdt.h
+++ b/arch/arm/include/asm/arch-aspeed/wdt.h
@@ -67,33 +67,39 @@
 	u32 timeout_status;
 	u32 clr_timeout_status;
 	u32 reset_width;
-#ifdef CONFIG_ASPEED_AST2500
+	/* On pre-ast2500 SoCs this register is reserved. */
 	u32 reset_mask;
-#else
-	u32 reserved0;
-#endif
 };
 
-void wdt_stop(struct ast_wdt *wdt);
-void wdt_start(struct ast_wdt *wdt, u32 timeout);
-
 /**
- * Reset peripherals specified by mask
+ * Given flags parameter passed to wdt_reset or wdt_start uclass functions,
+ * gets Reset Mode value from it.
  *
- * Note, that this is only supported by ast2500 SoC
+ * @flags: flags parameter passed into wdt_reset or wdt_start
+ * @return Reset Mode value
+ */
+u32 ast_reset_mode_from_flags(ulong flags);
+
+/**
+ * Given flags parameter passed to wdt_reset or wdt_start uclass functions,
+ * gets Reset Mask value from it. Reset Mask is only supported on ast2500
  *
- * @wdt: watchdog to use for this reset
- * @mask: reset mask.
+ * @flags: flags parameter passed into wdt_reset or wdt_start
+ * @return Reset Mask value
  */
-int ast_wdt_reset_masked(struct ast_wdt *wdt, u32 mask);
+u32 ast_reset_mask_from_flags(ulong flags);
 
 /**
- * ast_get_wdt() - get a pointer to watchdog registers
+ * Given Reset Mask and Reset Mode values, converts them to flags,
+ * suitable for passing into wdt_start or wdt_reset uclass functions.
  *
- * @wdt_number: 0-based WDT peripheral number
- * @return pointer to registers or -ve error on error
+ * On ast2500 Reset Mask is 25 bits wide and Reset Mode is 2 bits wide, so they
+ * can both be packed into single 32 bits wide value.
+ *
+ * @reset_mode: Reset Mode
+ * @reset_mask: Reset Mask
  */
-struct ast_wdt *ast_get_wdt(u8 wdt_number);
+ulong ast_flags_from_reset_mode_mask(u32 reset_mode, u32 reset_mask);
 #endif  /* __ASSEMBLY__ */
 
 #endif /* _ASM_ARCH_WDT_H */
diff --git a/arch/arm/include/asm/arch-stm32f7/gpio.h b/arch/arm/include/asm/arch-stm32f7/gpio.h
index 2942cd9..56e469e 100644
--- a/arch/arm/include/asm/arch-stm32f7/gpio.h
+++ b/arch/arm/include/asm/arch-stm32f7/gpio.h
@@ -7,6 +7,7 @@
 
 #ifndef _STM32_GPIO_H_
 #define _STM32_GPIO_H_
+#include <asm/gpio.h>
 
 enum stm32_gpio_port {
 	STM32_GPIO_PORT_A = 0,
@@ -96,6 +97,22 @@
 	enum stm32_gpio_af	af;
 };
 
+struct stm32_gpio_regs {
+	u32 moder;	/* GPIO port mode */
+	u32 otyper;	/* GPIO port output type */
+	u32 ospeedr;	/* GPIO port output speed */
+	u32 pupdr;	/* GPIO port pull-up/pull-down */
+	u32 idr;	/* GPIO port input data */
+	u32 odr;	/* GPIO port output data */
+	u32 bsrr;	/* GPIO port bit set/reset */
+	u32 lckr;	/* GPIO port configuration lock */
+	u32 afr[2];	/* GPIO alternate function */
+};
+
+struct stm32_gpio_priv {
+	struct stm32_gpio_regs *regs;
+};
+
 static inline unsigned stm32_gpio_to_port(unsigned gpio)
 {
 	return gpio / 16;
@@ -106,8 +123,4 @@
 	return gpio % 16;
 }
 
-int stm32_gpio_config(const struct stm32_gpio_dsc *gpio_dsc,
-		const struct stm32_gpio_ctl *gpio_ctl);
-int stm32_gpout_set(const struct stm32_gpio_dsc *gpio_dsc, int state);
-
 #endif /* _STM32_GPIO_H_ */
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
index a44ea77..faa1479 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
@@ -25,7 +25,7 @@
 	u32 pll6_cfg;		/* 0x28 pll6 control */
 	u32 reserved5;
 	u32 pll7_cfg;		/* 0x30 pll7 control */
-	u32 reserved6;
+	u32 sata_pll_cfg;	/* 0x34 SATA pll control (R40 only) */
 	u32 pll8_cfg;		/* 0x38 pll8 control */
 	u32 reserved7;
 	u32 mipi_pll_cfg;	/* 0x40 MIPI pll control */
@@ -58,7 +58,8 @@
 	u32 i2s1_clk_cfg;	/* 0xb4 I2S1 clock control */
 	u32 reserved10[2];
 	u32 spdif_clk_cfg;	/* 0xc0 SPDIF clock control */
-	u32 reserved11[2];
+	u32 reserved11;
+	u32 sata_clk_cfg;	/* 0xc8 SATA clock control (R40 only) */
 	u32 usb_clk_cfg;	/* 0xcc USB clock control */
 	u32 gmac_clk_cfg;	/* 0xd0 GMAC clock control */
 	u32 reserved12[7];
@@ -224,6 +225,8 @@
 #define CCM_PLL6_CTRL_K_MASK		(0x3 << CCM_PLL6_CTRL_K_SHIFT)
 #define CCM_PLL6_CTRL_LOCK		(1 << 28)
 
+#define CCM_SATA_PLL_DEFAULT		0x90005811 /* 100 MHz */
+
 #define CCM_MIPI_PLL_CTRL_M_SHIFT	0
 #define CCM_MIPI_PLL_CTRL_M_MASK	(0xf << CCM_MIPI_PLL_CTRL_M_SHIFT)
 #define CCM_MIPI_PLL_CTRL_M(n)		((((n) - 1) & 0xf) << 0)
@@ -280,7 +283,12 @@
 #define AHB_GATE_OFFSET_USB_EHCI1	27
 #define AHB_GATE_OFFSET_USB_EHCI0	26
 #endif
+#ifndef CONFIG_MACH_SUN8I_R40
 #define AHB_GATE_OFFSET_USB0		24
+#else
+#define AHB_GATE_OFFSET_USB0		25
+#define AHB_GATE_OFFSET_SATA		24
+#endif
 #define AHB_GATE_OFFSET_MCTL		14
 #define AHB_GATE_OFFSET_GMAC		17
 #define AHB_GATE_OFFSET_NAND0		13
@@ -315,6 +323,9 @@
 #define CCM_MMC_CTRL_PLL6		(0x1 << 24)
 #define CCM_MMC_CTRL_ENABLE		(0x1 << 31)
 
+#define CCM_SATA_CTRL_ENABLE		(0x1 << 31)
+#define CCM_SATA_CTRL_USE_EXTCLK	(0x1 << 24)
+
 #define CCM_USB_CTRL_PHY0_RST (0x1 << 0)
 #define CCM_USB_CTRL_PHY1_RST (0x1 << 1)
 #define CCM_USB_CTRL_PHY2_RST (0x1 << 2)
@@ -417,6 +428,9 @@
 #define CCM_PLL11_PATTERN		0xf5860000
 
 /* ahb_reset0 offsets */
+#ifdef CONFIG_MACH_SUN8I_R40
+#define AHB_RESET_OFFSET_SATA		24
+#endif
 #define AHB_RESET_OFFSET_GMAC		17
 #define AHB_RESET_OFFSET_MCTL		14
 #define AHB_RESET_OFFSET_MMC3		11
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
index 88c3f13..6aa5e91 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
@@ -18,6 +18,8 @@
 #define SUNXI_SRAM_D_BASE		0x00010000	/* 4 kiB */
 #define SUNXI_SRAM_B_BASE		0x00020000	/* 64 kiB (secure) */
 
+#define SUNXI_DE2_BASE			0x01000000
+
 #ifdef CONFIG_MACH_SUN8I_A83T
 #define SUNXI_CPUCFG_BASE		0x01700000
 #endif
@@ -46,7 +48,9 @@
 #define SUNXI_USB1_BASE			0x01c14000
 #endif
 #define SUNXI_SS_BASE			0x01c15000
+#if !defined(CONFIG_MACH_SUNXI_H3_H5) && !defined(CONFIG_MACH_SUN50I)
 #define SUNXI_HDMI_BASE			0x01c16000
+#endif
 #define SUNXI_SPI2_BASE			0x01c17000
 #define SUNXI_SATA_BASE			0x01c18000
 #ifdef CONFIG_SUNXI_GEN_SUN4I
@@ -164,6 +168,10 @@
 #define SUNXI_MP_BASE			0x01e80000
 #define SUNXI_AVG_BASE			0x01ea0000
 
+#if defined(CONFIG_MACH_SUNXI_H3_H5) || defined(CONFIG_MACH_SUN50I)
+#define SUNXI_HDMI_BASE			0x01ee0000
+#endif
+
 #define SUNXI_RTC_BASE			0x01f00000
 #define SUNXI_PRCM_BASE			0x01f01400
 
diff --git a/arch/arm/include/asm/arch-sunxi/display2.h b/arch/arm/include/asm/arch-sunxi/display2.h
new file mode 100644
index 0000000..b5875f9
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/display2.h
@@ -0,0 +1,124 @@
+/*
+ * Sunxi platform display controller register and constant defines
+ *
+ * (C) Copyright 2017 Jernej Skrabec <jernej.skrabec@siol.net>
+ *
+ * Based on out of tree Linux DRM driver defines:
+ * Copyright (C) 2016 Jean-Francois Moine <moinejf@free.fr>
+ * Copyright (c) 2016 Allwinnertech Co., Ltd.
+*
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _SUNXI_DISPLAY2_H
+#define _SUNXI_DISPLAY2_H
+
+/* internal clock settings */
+struct de_clk {
+	u32 gate_cfg;
+	u32 bus_cfg;
+	u32 rst_cfg;
+	u32 div_cfg;
+	u32 sel_cfg;
+};
+
+/* global control */
+struct de_glb {
+	u32 ctl;
+	u32 status;
+	u32 dbuff;
+	u32 size;
+};
+
+/* alpha blending */
+struct de_bld {
+	u32 fcolor_ctl;
+	struct {
+		u32 fcolor;
+		u32 insize;
+		u32 offset;
+		u32 dum;
+	} attr[4];
+	u32 dum0[15];
+	u32 route;
+	u32 premultiply;
+	u32 bkcolor;
+	u32 output_size;
+	u32 bld_mode[4];
+	u32 dum1[4];
+	u32 ck_ctl;
+	u32 ck_cfg;
+	u32 dum2[2];
+	u32 ck_max[4];
+	u32 dum3[4];
+	u32 ck_min[4];
+	u32 dum4[3];
+	u32 out_ctl;
+};
+
+/* VI channel */
+struct de_vi {
+	struct {
+		u32 attr;
+		u32 size;
+		u32 coord;
+		u32 pitch[3];
+		u32 top_laddr[3];
+		u32 bot_laddr[3];
+	} cfg[4];
+	u32 fcolor[4];
+	u32 top_haddr[3];
+	u32 bot_haddr[3];
+	u32 ovl_size[2];
+	u32 hori[2];
+	u32 vert[2];
+};
+
+struct de_ui {
+	struct {
+		u32 attr;
+		u32 size;
+		u32 coord;
+		u32 pitch;
+		u32 top_laddr;
+		u32 bot_laddr;
+		u32 fcolor;
+		u32 dum;
+	} cfg[4];
+	u32 top_haddr;
+	u32 bot_haddr;
+	u32 ovl_size;
+};
+
+/*
+ * DE register constants.
+ */
+#define SUNXI_DE2_MUX0_BASE			(SUNXI_DE2_BASE + 0x100000)
+#define SUNXI_DE2_MUX1_BASE			(SUNXI_DE2_BASE + 0x200000)
+
+#define SUNXI_DE2_MUX_GLB_REGS			0x00000
+#define SUNXI_DE2_MUX_BLD_REGS			0x01000
+#define SUNXI_DE2_MUX_CHAN_REGS			0x02000
+#define SUNXI_DE2_MUX_CHAN_SZ			0x1000
+#define SUNXI_DE2_MUX_VSU_REGS			0x20000
+#define SUNXI_DE2_MUX_GSU1_REGS			0x30000
+#define SUNXI_DE2_MUX_GSU2_REGS			0x40000
+#define SUNXI_DE2_MUX_GSU3_REGS			0x50000
+#define SUNXI_DE2_MUX_FCE_REGS			0xa0000
+#define SUNXI_DE2_MUX_BWS_REGS			0xa2000
+#define SUNXI_DE2_MUX_LTI_REGS			0xa4000
+#define SUNXI_DE2_MUX_PEAK_REGS			0xa6000
+#define SUNXI_DE2_MUX_ASE_REGS			0xa8000
+#define SUNXI_DE2_MUX_FCC_REGS			0xaa000
+#define SUNXI_DE2_MUX_DCSC_REGS			0xb0000
+
+#define SUNXI_DE2_FORMAT_XRGB_8888		4
+#define SUNXI_DE2_FORMAT_RGB_565		10
+
+#define SUNXI_DE2_MUX_GLB_CTL_EN		(1 << 0)
+#define SUNXI_DE2_UI_CFG_ATTR_EN		(1 << 0)
+#define SUNXI_DE2_UI_CFG_ATTR_FMT(f)		((f & 0xf) << 8)
+
+#define SUNXI_DE2_WH(w, h)			(((h - 1) << 16) | (w - 1))
+
+#endif /* _SUNXI_DISPLAY2_H */
diff --git a/arch/arm/lib/spl.c b/arch/arm/lib/spl.c
index e606d47..8ff2c50 100644
--- a/arch/arm/lib/spl.c
+++ b/arch/arm/lib/spl.c
@@ -44,22 +44,21 @@
 /*
  * This function jumps to an image with argument. Normally an FDT or ATAGS
  * image.
- * arg: Pointer to paramter image in RAM
  */
 #ifdef CONFIG_SPL_OS_BOOT
-void __noreturn jump_to_image_linux(struct spl_image_info *spl_image, void *arg)
+void __noreturn jump_to_image_linux(struct spl_image_info *spl_image)
 {
 	unsigned long machid = 0xffffffff;
 #ifdef CONFIG_MACH_TYPE
 	machid = CONFIG_MACH_TYPE;
 #endif
 
-	debug("Entering kernel arg pointer: 0x%p\n", arg);
+	debug("Entering kernel arg pointer: 0x%p\n", spl_image->arg);
 	typedef void (*image_entry_arg_t)(int, int, void *)
 		__attribute__ ((noreturn));
 	image_entry_arg_t image_entry =
 		(image_entry_arg_t)(uintptr_t) spl_image->entry_point;
 	cleanup_before_linux();
-	image_entry(0, machid, arg);
+	image_entry(0, machid, spl_image->arg);
 }
 #endif
diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
index c5b90bd..4f021ba 100644
--- a/arch/arm/mach-aspeed/Kconfig
+++ b/arch/arm/mach-aspeed/Kconfig
@@ -11,19 +11,13 @@
 
 config ASPEED_AST2500
 	bool "Support Aspeed AST2500 SoC"
+	depends on DM_RESET
 	select CPU_ARM1176
 	help
 	  The Aspeed AST2500 is a ARM-based SoC with arm1176 CPU.
 	  It is used as Board Management Controller on many server boards,
 	  which is enabled by support of LPC and eSPI peripherals.
 
-config WDT_NUM
-	int "Number of Watchdog Timers"
-	default 3 if ASPEED_AST2500
-	help
-	  The number of Watchdot Timers on a SoC.
-	  AST2500 has three WDTsk earlier versions have two or fewer.
-
 source "arch/arm/mach-aspeed/ast2500/Kconfig"
 
 endif
diff --git a/arch/arm/mach-aspeed/ast2500/clk_ast2500.c b/arch/arm/mach-aspeed/ast2500/clk_ast2500.c
index 079909f..30cfac1 100644
--- a/arch/arm/mach-aspeed/ast2500/clk_ast2500.c
+++ b/arch/arm/mach-aspeed/ast2500/clk_ast2500.c
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <asm/io.h>
 #include <asm/arch/scu_ast2500.h>
 
 int ast_get_clk(struct udevice **devp)
@@ -28,3 +29,17 @@
 
 	return priv->scu;
 }
+
+void ast_scu_unlock(struct ast2500_scu *scu)
+{
+	writel(SCU_UNLOCK_VALUE, &scu->protection_key);
+	while (!readl(&scu->protection_key))
+		;
+}
+
+void ast_scu_lock(struct ast2500_scu *scu)
+{
+	writel(~SCU_UNLOCK_VALUE, &scu->protection_key);
+	while (readl(&scu->protection_key))
+		;
+}
diff --git a/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
index cb6e03f..6383f72 100644
--- a/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
+++ b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
@@ -12,6 +12,7 @@
 #include <errno.h>
 #include <ram.h>
 #include <regmap.h>
+#include <reset.h>
 #include <asm/io.h>
 #include <asm/arch/scu_ast2500.h>
 #include <asm/arch/sdram_ast2500.h>
@@ -182,9 +183,8 @@
 static size_t ast2500_sdrammc_get_vga_mem_size(struct dram_info *info)
 {
 	size_t vga_mem_size_base = 8 * 1024 * 1024;
-	u32 vga_hwconf = (readl(&info->scu->hwstrap)
-			  >> SCU_HWSTRAP_VGAMEM_SHIFT)
-			& SCU_HWSTRAP_VGAMEM_MASK;
+	u32 vga_hwconf = (readl(&info->scu->hwstrap) & SCU_HWSTRAP_VGAMEM_MASK)
+	    >> SCU_HWSTRAP_VGAMEM_SHIFT;
 
 	return vga_mem_size_base << vga_hwconf;
 }
@@ -328,6 +328,7 @@
 
 static int ast2500_sdrammc_probe(struct udevice *dev)
 {
+	struct reset_ctl reset_ctl;
 	struct dram_info *priv = (struct dram_info *)dev_get_priv(dev);
 	struct ast2500_sdrammc_regs *regs = priv->regs;
 	int i;
@@ -345,9 +346,15 @@
 	}
 
 	clk_set_rate(&priv->ddr_clk, priv->clock_rate);
-	ret = ast_wdt_reset_masked(ast_get_wdt(0), WDT_RESET_SDRAM);
+	ret = reset_get_by_index(dev, 0, &reset_ctl);
+	if (ret) {
+		debug("%s(): Failed to get reset signal\n", __func__);
+		return ret;
+	}
+
+	ret = reset_assert(&reset_ctl);
 	if (ret) {
-		debug("%s(): SDRAM reset failed\n", __func__);
+		debug("%s(): SDRAM reset failed: %u\n", __func__, ret);
 		return ret;
 	}
 
diff --git a/arch/arm/mach-aspeed/ast_wdt.c b/arch/arm/mach-aspeed/ast_wdt.c
index 22481ab..1a858b1 100644
--- a/arch/arm/mach-aspeed/ast_wdt.c
+++ b/arch/arm/mach-aspeed/ast_wdt.c
@@ -9,51 +9,22 @@
 #include <asm/arch/wdt.h>
 #include <linux/err.h>
 
-void wdt_stop(struct ast_wdt *wdt)
+u32 ast_reset_mode_from_flags(ulong flags)
 {
-	clrbits_le32(&wdt->ctrl, WDT_CTRL_EN);
+	return flags & WDT_CTRL_RESET_MASK;
 }
 
-void wdt_start(struct ast_wdt *wdt, u32 timeout)
+u32 ast_reset_mask_from_flags(ulong flags)
 {
-	writel(timeout, &wdt->counter_reload_val);
-	writel(WDT_COUNTER_RESTART_VAL, &wdt->counter_restart);
-	/*
-	 * Setting CLK1MHZ bit is just for compatibility with ast2400 part.
-	 * On ast2500 watchdog timer clock is fixed at 1MHz and the bit is
-	 * read-only
-	 */
-	setbits_le32(&wdt->ctrl,
-		     WDT_CTRL_EN | WDT_CTRL_RESET | WDT_CTRL_CLK1MHZ);
+	return flags >> 2;
 }
 
-struct ast_wdt *ast_get_wdt(u8 wdt_number)
+ulong ast_flags_from_reset_mode_mask(u32 reset_mode, u32 reset_mask)
 {
-	if (wdt_number > CONFIG_WDT_NUM - 1)
-		return ERR_PTR(-EINVAL);
+	ulong ret = reset_mode & WDT_CTRL_RESET_MASK;
 
-	return (struct ast_wdt *)(WDT_BASE +
-				  sizeof(struct ast_wdt) * wdt_number);
-}
-
-int ast_wdt_reset_masked(struct ast_wdt *wdt, u32 mask)
-{
-#ifdef CONFIG_ASPEED_AST2500
-	if (!mask)
-		return -EINVAL;
-
-	writel(mask, &wdt->reset_mask);
-	clrbits_le32(&wdt->ctrl,
-		     WDT_CTRL_RESET_MASK << WDT_CTRL_RESET_MODE_SHIFT);
-	wdt_start(wdt, 1);
-
-	/* Wait for WDT to reset */
-	while (readl(&wdt->ctrl) & WDT_CTRL_EN)
-		;
-	wdt_stop(wdt);
+	if (ret == WDT_CTRL_RESET_SOC)
+		ret |= (reset_mask << 2);
 
-	return 0;
-#else
-	return -EINVAL;
-#endif
+	return ret;
 }
diff --git a/arch/arm/mach-keystone/clock.c b/arch/arm/mach-keystone/clock.c
index 68f8980..645bd96 100644
--- a/arch/arm/mach-keystone/clock.c
+++ b/arch/arm/mach-keystone/clock.c
@@ -284,7 +284,7 @@
 	u32 tmp, reg;
 
 	if (pll == MAIN_PLL) {
-		ret = external_clk[sys_clk];
+		ret = get_external_clk(sys_clk);
 		if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN_MASK) {
 			/* PLL mode */
 			tmp = __raw_readl(KS2_MAINPLLCTL0);
@@ -302,23 +302,23 @@
 	} else {
 		switch (pll) {
 		case PASS_PLL:
-			ret = external_clk[pa_clk];
+			ret = get_external_clk(pa_clk);
 			reg = KS2_PASSPLLCTL0;
 			break;
 		case TETRIS_PLL:
-			ret = external_clk[tetris_clk];
+			ret = get_external_clk(tetris_clk);
 			reg = KS2_ARMPLLCTL0;
 			break;
 		case DDR3A_PLL:
-			ret = external_clk[ddr3a_clk];
+			ret = get_external_clk(ddr3a_clk);
 			reg = KS2_DDR3APLLCTL0;
 			break;
 		case DDR3B_PLL:
-			ret = external_clk[ddr3b_clk];
+			ret = get_external_clk(ddr3b_clk);
 			reg = KS2_DDR3BPLLCTL0;
 			break;
 		case UART_PLL:
-			ret = external_clk[uart_clk];
+			ret = get_external_clk(uart_clk);
 			reg = KS2_UARTPLLCTL0;
 			break;
 		default:
diff --git a/arch/arm/mach-keystone/include/mach/clock-k2g.h b/arch/arm/mach-keystone/include/mach/clock-k2g.h
index 74de620..374f0d9 100644
--- a/arch/arm/mach-keystone/include/mach/clock-k2g.h
+++ b/arch/arm/mach-keystone/include/mach/clock-k2g.h
@@ -12,8 +12,8 @@
 
 #define PLLSET_CMD_LIST		"<pa|arm|ddr3>"
 
-#define DEV_SUPPORTED_SPEEDS	0x1ff
-#define ARM_SUPPORTED_SPEEDS	0xff
+#define DEV_SUPPORTED_SPEEDS	0xff
+#define ARM_SUPPORTED_SPEEDS	0x3ff
 
 #define KS2_CLK1_6 sys_clk0_6_clk
 
diff --git a/arch/arm/mach-keystone/include/mach/clock.h b/arch/arm/mach-keystone/include/mach/clock.h
index 0d8a944..006d074 100644
--- a/arch/arm/mach-keystone/include/mach/clock.h
+++ b/arch/arm/mach-keystone/include/mach/clock.h
@@ -117,7 +117,6 @@
 	int pll_od;		/* PLL output divider */
 };
 
-extern unsigned int external_clk[ext_clk_count];
 extern const struct keystone_pll_regs keystone_pll_regs[];
 extern s16 divn_val[];
 extern int speeds[];
@@ -129,6 +128,7 @@
 int get_max_dev_speed(int *spds);
 int get_max_arm_speed(int *spds);
 void pll_pa_clk_sel(void);
+unsigned int get_external_clk(u32 clk);
 
 #endif
 #endif
diff --git a/arch/arm/mach-keystone/include/mach/hardware-k2g.h b/arch/arm/mach-keystone/include/mach/hardware-k2g.h
index 0f6bf61..90ca120 100644
--- a/arch/arm/mach-keystone/include/mach/hardware-k2g.h
+++ b/arch/arm/mach-keystone/include/mach/hardware-k2g.h
@@ -86,4 +86,25 @@
 #define RSTMUX_OMODE8_INT		0x3
 #define RSTMUX_OMODE8_INT_AND_DEV_RESET	0x4
 
+/* DEVSTAT register definition */
+#define KS2_DEVSTAT_REFCLK_SHIFT	 7
+#define KS2_DEVSTAT_REFCLK_MASK		(0x7 << 7)
+
+/* GPMC */
+#define KS2_GPMC_BASE			0x21818000
+
+/* SYSCLK indexes */
+#define SYSCLK_19MHz	0
+#define SYSCLK_24MHz	1
+#define SYSCLK_25MHz	2
+#define SYSCLK_26MHz	3
+#define MAX_SYSCLK	4
+
+#ifndef __ASSEMBLY__
+static inline u8 get_sysclk_index(void)
+{
+	u32 dev_stat = __raw_readl(KS2_DEVSTAT);
+	return (dev_stat & KS2_DEVSTAT_REFCLK_MASK) >> KS2_DEVSTAT_REFCLK_SHIFT;
+}
+#endif
 #endif /* __ASM_ARCH_HARDWARE_K2G_H */
diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c
index 1c0477a..2ef5726 100644
--- a/arch/arm/mach-mvebu/arm64-common.c
+++ b/arch/arm/mach-mvebu/arm64-common.c
@@ -94,7 +94,7 @@
 
 	ac = fdt_address_cells(fdt, 0);
 	sc = fdt_size_cells(fdt, 0);
-	if (ac < 1 || sc > 2 || sc < 1 || sc > 2) {
+	if (ac < 1 || ac > 2 || sc < 1 || sc > 2) {
 		printf("invalid address/size cells\n");
 		return -ENXIO;
 	}
diff --git a/arch/arm/mach-omap2/am33xx/Kconfig b/arch/arm/mach-omap2/am33xx/Kconfig
index cf5d95a..db3c70f 100644
--- a/arch/arm/mach-omap2/am33xx/Kconfig
+++ b/arch/arm/mach-omap2/am33xx/Kconfig
@@ -44,8 +44,9 @@
 	select DM_SERIAL
 	select DM_GPIO
 
-config TARGET_AM335X_IGEP0033
-	bool "Support am335x_igep0033"
+config TARGET_AM335X_IGEP003X
+	bool "Support am335x_igep003x"
+	select BOARD_LATE_INIT
 	select DM
 	select DM_SERIAL
 	select DM_GPIO
diff --git a/arch/arm/mach-omap2/omap5/Kconfig b/arch/arm/mach-omap2/omap5/Kconfig
index 4041adc..c89c438 100644
--- a/arch/arm/mach-omap2/omap5/Kconfig
+++ b/arch/arm/mach-omap2/omap5/Kconfig
@@ -1,11 +1,17 @@
 if OMAP54XX
 
+config DRA7XX
+	bool
+	help
+	  DRA7xx is an OMAP based SOC with Dual Core A-15s.
+
 choice
 	prompt "OMAP5 board select"
 	optional
 
 config TARGET_CL_SOM_AM57X
 	bool "CompuLab CL-SOM-AM57x"
+	select DRA7XX
 
 config TARGET_CM_T54
 	bool "CompuLab CM-T54"
@@ -16,12 +22,14 @@
 config TARGET_DRA7XX_EVM
 	bool "TI DRA7XX"
 	select BOARD_LATE_INIT
+	select DRA7XX
 	select TI_I2C_BOARD_DETECT
 	select PHYS_64BIT
 
 config TARGET_AM57XX_EVM
 	bool "AM57XX"
 	select BOARD_LATE_INIT
+	select DRA7XX
 	select TI_I2C_BOARD_DETECT
 
 endchoice
diff --git a/board/sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
similarity index 97%
rename from board/sunxi/Kconfig
rename to arch/arm/mach-sunxi/Kconfig
index b47034f..8d9900e 100644
--- a/board/sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -3,32 +3,6 @@
 config IDENT_STRING
 	default " Allwinner Technology"
 
-# FIXME: Should not redefine these Kconfig symbols
-config PRE_CONSOLE_BUFFER
-	default y
-
-config SPL_GPIO_SUPPORT
-	default y
-
-config SPL_LIBCOMMON_SUPPORT
-	default y
-
-config SPL_LIBDISK_SUPPORT
-	default y
-
-config SPL_LIBGENERIC_SUPPORT
-	default y
-
-config SPL_MMC_SUPPORT
-	depends on SPL && GENERIC_MMC
-	default y
-
-config SPL_POWER_SUPPORT
-	default y
-
-config SPL_SERIAL_SUPPORT
-	default y
-
 config SUNXI_HIGH_SRAM
 	bool
 	default n
@@ -58,6 +32,7 @@
 
 config MACH_SUNXI_H3_H5
 	bool
+	select DM_I2C
 	select SUNXI_DE2
 	select SUNXI_GEN_SUN6I
 	select SUPPORT_SPL
@@ -163,6 +138,7 @@
 config MACH_SUN50I
 	bool "sun50i (Allwinner A64)"
 	select ARM64
+	select DM_I2C
 	select SUNXI_DE2
 	select SUNXI_GEN_SUN6I
 	select SUNXI_HIGH_SRAM
@@ -706,6 +682,16 @@
 	bool
 	default n
 
+config VIDEO_DE2
+	bool "Display Engine 2 video driver"
+	depends on SUNXI_DE2
+	select DM_VIDEO
+	select DISPLAY
+	default y
+	---help---
+	Say y here if you want to build DE2 video driver which is present on
+	newer SoCs. Currently only HDMI output is supported.
+
 
 choice
 	prompt "LCD panel support"
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 4507279..65b1ebd 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -204,7 +204,9 @@
 	clock_init();
 	timer_init();
 	gpio_init();
+#ifndef CONFIG_DM_I2C
 	i2c_init_board();
+#endif
 	eth_init_board();
 }
 
diff --git a/arch/arm/mach-sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c
index 631bc6e..ec5b026 100644
--- a/arch/arm/mach-sunxi/clock_sun6i.c
+++ b/arch/arm/mach-sunxi/clock_sun6i.c
@@ -51,6 +51,13 @@
 	writel(MBUS_CLK_DEFAULT, &ccm->mbus0_clk_cfg);
 	if (IS_ENABLED(CONFIG_MACH_SUN6I))
 		writel(MBUS_CLK_DEFAULT, &ccm->mbus1_clk_cfg);
+
+#if defined(CONFIG_MACH_SUN8I_R40) && defined(CONFIG_SUNXI_AHCI)
+	setbits_le32(&ccm->sata_pll_cfg, CCM_SATA_PLL_DEFAULT);
+	setbits_le32(&ccm->ahb_reset0_cfg, 0x1 << AHB_GATE_OFFSET_SATA);
+	setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_SATA);
+	setbits_le32(&ccm->sata_clk_cfg, CCM_SATA_CTRL_ENABLE);
+#endif
 }
 #endif
 
diff --git a/arch/microblaze/cpu/spl.c b/arch/microblaze/cpu/spl.c
index 8e6d926..3d57a5a 100644
--- a/arch/microblaze/cpu/spl.c
+++ b/arch/microblaze/cpu/spl.c
@@ -29,15 +29,15 @@
 }
 
 #ifdef CONFIG_SPL_OS_BOOT
-void __noreturn jump_to_image_linux(struct spl_image_info *spl_image, void *arg)
+void __noreturn jump_to_image_linux(struct spl_image_info *spl_image)
 {
-	debug("Entering kernel arg pointer: 0x%p\n", arg);
+	debug("Entering kernel arg pointer: 0x%p\n", spl_image->arg);
 	typedef void (*image_entry_arg_t)(char *, ulong, ulong)
 		__attribute__ ((noreturn));
 	image_entry_arg_t image_entry =
 		(image_entry_arg_t)spl_image->entry_point;
 
-	image_entry(NULL, 0, (ulong)arg);
+	image_entry(NULL, 0, (ulong)spl_image->arg);
 }
 #endif /* CONFIG_SPL_OS_BOOT */
 
diff --git a/arch/powerpc/lib/spl.c b/arch/powerpc/lib/spl.c
index 080b978..b931970 100644
--- a/arch/powerpc/lib/spl.c
+++ b/arch/powerpc/lib/spl.c
@@ -14,18 +14,18 @@
 /*
  * This function jumps to an image with argument. Normally an FDT or ATAGS
  * image.
- * arg: Pointer to paramter image in RAM
  */
 #ifdef CONFIG_SPL_OS_BOOT
-void __noreturn jump_to_image_linux(struct spl_image_info *spl_image, void *arg)
+void __noreturn jump_to_image_linux(struct spl_image_info *spl_image)
 {
-	debug("Entering kernel arg pointer: 0x%p\n", arg);
+	debug("Entering kernel arg pointer: 0x%p\n", spl_image->arg);
 	typedef void (*image_entry_arg_t)(void *, ulong r4, ulong r5, ulong r6,
 					  ulong r7, ulong r8, ulong r9)
 		__attribute__ ((noreturn));
 	image_entry_arg_t image_entry =
 		(image_entry_arg_t)spl_image->entry_point;
 
-	image_entry(arg, 0, 0, EPAPR_MAGIC, CONFIG_SYS_BOOTMAPSZ, 0, 0);
+	image_entry(spl_image->arg, 0, 0, EPAPR_MAGIC, CONFIG_SYS_BOOTMAPSZ,
+		    0, 0);
 }
 #endif /* CONFIG_SPL_OS_BOOT */
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 50bcdeb..094c5aa 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -426,6 +426,10 @@
 			};
 		};
 	};
+
+	wdt0: wdt@0 {
+		compatible = "sandbox,wdt";
+	};
 };
 
 #include "sandbox_pmic.dtsi"
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index 149f28d..987cc7b 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -39,6 +39,12 @@
 	struct udevice *emul;
 };
 
+struct sandbox_wdt_info {
+	unsigned long long counter;
+	uint reset_count;
+	bool running;
+};
+
 /* The complete state of the test system */
 struct sandbox_state {
 	const char *cmd;		/* Command to execute */
@@ -69,6 +75,9 @@
 	/* Pointer to information for each SPI bus/cs */
 	struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS]
 					[CONFIG_SANDBOX_SPI_MAX_CS];
+
+	/* Information about Watchdog */
+	struct sandbox_wdt_info wdt;
 };
 
 /* Minimum space we guarantee in the state FDT when calling read/write*/
diff --git a/board/BuR/common/common.c b/board/BuR/common/common.c
index 8761504..5cc82c9 100644
--- a/board/BuR/common/common.c
+++ b/board/BuR/common/common.c
@@ -264,13 +264,13 @@
 #else
 	char *dtbname = getenv("dtb");
 	char *dtbdev = getenv("dtbdev");
-	char *dtppart = getenv("dtbpart");
-	if (!dtbdev || !dtbdev || !dtbname) {
+	char *dtbpart = getenv("dtbpart");
+	if (!dtbdev || !dtbpart || !dtbname) {
 		printf("%s: <dtbdev>/<dtbpart>/<dtb> missing.\n", __func__);
 		return -1;
 	}
 
-	if (fs_set_blk_dev(dtbdev, dtppart, FS_TYPE_EXT)) {
+	if (fs_set_blk_dev(dtbdev, dtbpart, FS_TYPE_EXT)) {
 		puts("load_devicetree: set_blk_dev failed.\n");
 		return -1;
 	}
diff --git a/board/compulab/cl-som-am57x/cl-som-am57x.c b/board/compulab/cl-som-am57x/cl-som-am57x.c
index bdd0a2b..4701b71 100644
--- a/board/compulab/cl-som-am57x/cl-som-am57x.c
+++ b/board/compulab/cl-som-am57x/cl-som-am57x.c
@@ -53,16 +53,6 @@
 }
 #endif /* CONFIG_GENERIC_MMC */
 
-#ifdef CONFIG_USB_XHCI_OMAP
-int board_usb_init(int index, enum usb_init_type init)
-{
-	setbits_le32((*prcm)->cm_l3init_usb_otg_ss1_clkctrl,
-		     OTG_SS_CLKCTRL_MODULEMODE_HW | OPTFCLKEN_REFCLK960M);
-
-	return 0;
-}
-#endif /* CONFIG_USB_XHCI_OMAP */
-
 int misc_init_r(void)
 {
 	cl_print_pcb_info();
diff --git a/board/isee/igep0033/MAINTAINERS b/board/isee/igep0033/MAINTAINERS
deleted file mode 100644
index bd8a1f2..0000000
--- a/board/isee/igep0033/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-IGEP0033 BOARD
-M:	Enric Balletbo i Serra <eballetbo@gmail.com>
-S:	Maintained
-F:	board/isee/igep0033/
-F:	include/configs/am335x_igep0033.h
-F:	configs/am335x_igep0033_defconfig
diff --git a/board/isee/igep0033/board.c b/board/isee/igep0033/board.c
deleted file mode 100644
index 5fea7ff..0000000
--- a/board/isee/igep0033/board.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Board functions for IGEP COM AQUILA based boards
- *
- * Copyright (C) 2013, ISEE 2007 SL - http://www.isee.biz/
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <errno.h>
-#include <spl.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/omap.h>
-#include <asm/arch/ddr_defs.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/gpio.h>
-#include <asm/arch/mmc_host_def.h>
-#include <asm/arch/sys_proto.h>
-#include <asm/io.h>
-#include <asm/emif.h>
-#include <asm/gpio.h>
-#include <i2c.h>
-#include <miiphy.h>
-#include <cpsw.h>
-#include "board.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
-
-#ifdef CONFIG_SPL_BUILD
-static const struct ddr_data ddr3_data = {
-	.datardsratio0 = K4B2G1646EBIH9_RD_DQS,
-	.datawdsratio0 = K4B2G1646EBIH9_WR_DQS,
-	.datafwsratio0 = K4B2G1646EBIH9_PHY_FIFO_WE,
-	.datawrsratio0 = K4B2G1646EBIH9_PHY_WR_DATA,
-};
-
-static const struct cmd_control ddr3_cmd_ctrl_data = {
-	.cmd0csratio = K4B2G1646EBIH9_RATIO,
-	.cmd0iclkout = K4B2G1646EBIH9_INVERT_CLKOUT,
-
-	.cmd1csratio = K4B2G1646EBIH9_RATIO,
-	.cmd1iclkout = K4B2G1646EBIH9_INVERT_CLKOUT,
-
-	.cmd2csratio = K4B2G1646EBIH9_RATIO,
-	.cmd2iclkout = K4B2G1646EBIH9_INVERT_CLKOUT,
-};
-
-static struct emif_regs ddr3_emif_reg_data = {
-	.sdram_config = K4B2G1646EBIH9_EMIF_SDCFG,
-	.ref_ctrl = K4B2G1646EBIH9_EMIF_SDREF,
-	.sdram_tim1 = K4B2G1646EBIH9_EMIF_TIM1,
-	.sdram_tim2 = K4B2G1646EBIH9_EMIF_TIM2,
-	.sdram_tim3 = K4B2G1646EBIH9_EMIF_TIM3,
-	.zq_config = K4B2G1646EBIH9_ZQ_CFG,
-	.emif_ddr_phy_ctlr_1 = K4B2G1646EBIH9_EMIF_READ_LATENCY,
-};
-
-#define OSC    (V_OSCK/1000000)
-const struct dpll_params dpll_ddr = {
-		400, OSC-1, 1, -1, -1, -1, -1};
-
-const struct dpll_params *get_dpll_ddr_params(void)
-{
-	return &dpll_ddr;
-}
-
-void set_uart_mux_conf(void)
-{
-	enable_uart0_pin_mux();
-}
-
-void set_mux_conf_regs(void)
-{
-	enable_board_pin_mux();
-}
-
-const struct ctrl_ioregs ioregs = {
-	.cm0ioctl		= K4B2G1646EBIH9_IOCTRL_VALUE,
-	.cm1ioctl		= K4B2G1646EBIH9_IOCTRL_VALUE,
-	.cm2ioctl		= K4B2G1646EBIH9_IOCTRL_VALUE,
-	.dt0ioctl		= K4B2G1646EBIH9_IOCTRL_VALUE,
-	.dt1ioctl		= K4B2G1646EBIH9_IOCTRL_VALUE,
-};
-
-void sdram_init(void)
-{
-	config_ddr(400, &ioregs, &ddr3_data,
-		   &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);
-}
-#endif
-
-/*
- * Basic board specific setup.  Pinmux has been handled already.
- */
-int board_init(void)
-{
-	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
-
-	gpmc_init();
-
-	return 0;
-}
-
-#if defined(CONFIG_DRIVER_TI_CPSW)
-static void cpsw_control(int enabled)
-{
-	/* VTP can be added here */
-
-	return;
-}
-
-static struct cpsw_slave_data cpsw_slaves[] = {
-	{
-		.slave_reg_ofs	= 0x208,
-		.sliver_reg_ofs	= 0xd80,
-		.phy_addr	= 0,
-		.phy_if		= PHY_INTERFACE_MODE_RMII,
-	},
-};
-
-static struct cpsw_platform_data cpsw_data = {
-	.mdio_base		= CPSW_MDIO_BASE,
-	.cpsw_base		= CPSW_BASE,
-	.mdio_div		= 0xff,
-	.channels		= 8,
-	.cpdma_reg_ofs		= 0x800,
-	.slaves			= 1,
-	.slave_data		= cpsw_slaves,
-	.ale_reg_ofs		= 0xd00,
-	.ale_entries		= 1024,
-	.host_port_reg_ofs	= 0x108,
-	.hw_stats_reg_ofs	= 0x900,
-	.bd_ram_ofs		= 0x2000,
-	.mac_control		= (1 << 5),
-	.control		= cpsw_control,
-	.host_port_num		= 0,
-	.version		= CPSW_CTRL_VERSION_2,
-};
-
-int board_eth_init(bd_t *bis)
-{
-	int rv, ret = 0;
-	uint8_t mac_addr[6];
-	uint32_t mac_hi, mac_lo;
-
-	if (!eth_getenv_enetaddr("ethaddr", mac_addr)) {
-		/* try reading mac address from efuse */
-		mac_lo = readl(&cdev->macid0l);
-		mac_hi = readl(&cdev->macid0h);
-		mac_addr[0] = mac_hi & 0xFF;
-		mac_addr[1] = (mac_hi & 0xFF00) >> 8;
-		mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
-		mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
-		mac_addr[4] = mac_lo & 0xFF;
-		mac_addr[5] = (mac_lo & 0xFF00) >> 8;
-		if (is_valid_ethaddr(mac_addr))
-			eth_setenv_enetaddr("ethaddr", mac_addr);
-	}
-
-	writel((GMII1_SEL_RMII | RMII1_IO_CLK_EN),
-	       &cdev->miisel);
-
-	rv = cpsw_register(&cpsw_data);
-	if (rv < 0)
-		printf("Error %d registering CPSW switch\n", rv);
-	else
-		ret += rv;
-
-	return ret;
-}
-#endif
diff --git a/board/isee/igep0033/Kconfig b/board/isee/igep003x/Kconfig
similarity index 61%
rename from board/isee/igep0033/Kconfig
rename to board/isee/igep003x/Kconfig
index e989e4b..68a68fc 100644
--- a/board/isee/igep0033/Kconfig
+++ b/board/isee/igep003x/Kconfig
@@ -1,7 +1,7 @@
-if TARGET_AM335X_IGEP0033
+if TARGET_AM335X_IGEP003X
 
 config SYS_BOARD
-	default "igep0033"
+	default "igep003x"
 
 config SYS_VENDOR
 	default "isee"
@@ -10,6 +10,6 @@
 	default "am33xx"
 
 config SYS_CONFIG_NAME
-	default "am335x_igep0033"
+	default "am335x_igep003x"
 
 endif
diff --git a/board/isee/igep003x/MAINTAINERS b/board/isee/igep003x/MAINTAINERS
new file mode 100644
index 0000000..748b189
--- /dev/null
+++ b/board/isee/igep003x/MAINTAINERS
@@ -0,0 +1,6 @@
+IGEP003X BOARD
+M:	Enric Balletbo i Serra <eballetbo@gmail.com>
+S:	Maintained
+F:	board/isee/igep003x/
+F:	include/configs/am335x_igep003x.h
+F:	configs/am335x_igep0033_defconfig
diff --git a/board/isee/igep0033/Makefile b/board/isee/igep003x/Makefile
similarity index 100%
rename from board/isee/igep0033/Makefile
rename to board/isee/igep003x/Makefile
diff --git a/board/isee/igep003x/board.c b/board/isee/igep003x/board.c
new file mode 100644
index 0000000..2d0ebbf
--- /dev/null
+++ b/board/isee/igep003x/board.c
@@ -0,0 +1,287 @@
+/*
+ * Board functions for IGEP COM AQUILA and SMARC AM335x based boards
+ *
+ * Copyright (C) 2013-2017, ISEE 2007 SL - http://www.isee.biz/
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <spl.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/omap.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/mmc_host_def.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+#include <asm/emif.h>
+#include <asm/gpio.h>
+#include <i2c.h>
+#include <miiphy.h>
+#include <cpsw.h>
+#include <fdt_support.h>
+#include <mtd_node.h>
+#include <jffs2/load_kernel.h>
+#include <environment.h>
+#include "board.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* GPIO0_27 and GPIO0_26 are used to read board revision from IGEP003x boards
+ * and control IGEP0034 green and red LEDs.
+ * U-boot configures these pins as input pullup to detect board revision:
+ * IGEP0034-LITE = 0b00
+ * IGEP0034 (FULL) = 0b01
+ * IGEP0033 = 0b1X
+ */
+#define GPIO_GREEN_REVISION	27
+#define GPIO_RED_REVISION	26
+
+static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
+
+/*
+ * Routine: get_board_revision
+ * Description: Returns the board revision
+ */
+static int get_board_revision(void)
+{
+	int revision;
+
+	gpio_request(GPIO_GREEN_REVISION, "green_revision");
+	gpio_direction_input(GPIO_GREEN_REVISION);
+	revision = 2 * gpio_get_value(GPIO_GREEN_REVISION);
+	gpio_free(GPIO_GREEN_REVISION);
+
+	gpio_request(GPIO_RED_REVISION, "red_revision");
+	gpio_direction_input(GPIO_RED_REVISION);
+	revision = revision + gpio_get_value(GPIO_RED_REVISION);
+	gpio_free(GPIO_RED_REVISION);
+
+	return revision;
+}
+
+#ifdef CONFIG_SPL_BUILD
+/* PN H5TQ4G63AFR is equivalent to MT41K256M16HA125*/
+static const struct ddr_data ddr3_igep0034_data = {
+	.datardsratio0 = MT41K256M16HA125E_RD_DQS,
+	.datawdsratio0 = MT41K256M16HA125E_WR_DQS,
+	.datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE,
+	.datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA,
+};
+
+static const struct ddr_data ddr3_igep0034_lite_data = {
+	.datardsratio0 = K4B2G1646EBIH9_RD_DQS,
+	.datawdsratio0 = K4B2G1646EBIH9_WR_DQS,
+	.datafwsratio0 = K4B2G1646EBIH9_PHY_FIFO_WE,
+	.datawrsratio0 = K4B2G1646EBIH9_PHY_WR_DATA,
+};
+
+static const struct cmd_control ddr3_igep0034_cmd_ctrl_data = {
+	.cmd0csratio = MT41K256M16HA125E_RATIO,
+	.cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
+
+	.cmd1csratio = MT41K256M16HA125E_RATIO,
+	.cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
+
+	.cmd2csratio = MT41K256M16HA125E_RATIO,
+	.cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
+};
+
+static const struct cmd_control ddr3_igep0034_lite_cmd_ctrl_data = {
+	.cmd0csratio = K4B2G1646EBIH9_RATIO,
+	.cmd0iclkout = K4B2G1646EBIH9_INVERT_CLKOUT,
+
+	.cmd1csratio = K4B2G1646EBIH9_RATIO,
+	.cmd1iclkout = K4B2G1646EBIH9_INVERT_CLKOUT,
+
+	.cmd2csratio = K4B2G1646EBIH9_RATIO,
+	.cmd2iclkout = K4B2G1646EBIH9_INVERT_CLKOUT,
+};
+
+static struct emif_regs ddr3_igep0034_emif_reg_data = {
+	.sdram_config = MT41K256M16HA125E_EMIF_SDCFG,
+	.ref_ctrl = MT41K256M16HA125E_EMIF_SDREF,
+	.sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1,
+	.sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2,
+	.sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3,
+	.zq_config = MT41K256M16HA125E_ZQ_CFG,
+	.emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY,
+};
+
+static struct emif_regs ddr3_igep0034_lite_emif_reg_data = {
+	.sdram_config = K4B2G1646EBIH9_EMIF_SDCFG,
+	.ref_ctrl = K4B2G1646EBIH9_EMIF_SDREF,
+	.sdram_tim1 = K4B2G1646EBIH9_EMIF_TIM1,
+	.sdram_tim2 = K4B2G1646EBIH9_EMIF_TIM2,
+	.sdram_tim3 = K4B2G1646EBIH9_EMIF_TIM3,
+	.zq_config = K4B2G1646EBIH9_ZQ_CFG,
+	.emif_ddr_phy_ctlr_1 = K4B2G1646EBIH9_EMIF_READ_LATENCY,
+};
+
+const struct ctrl_ioregs ioregs_igep0034 = {
+	.cm0ioctl		= MT41K256M16HA125E_IOCTRL_VALUE,
+	.cm1ioctl		= MT41K256M16HA125E_IOCTRL_VALUE,
+	.cm2ioctl		= MT41K256M16HA125E_IOCTRL_VALUE,
+	.dt0ioctl		= MT41K256M16HA125E_IOCTRL_VALUE,
+	.dt1ioctl		= MT41K256M16HA125E_IOCTRL_VALUE,
+};
+
+const struct ctrl_ioregs ioregs_igep0034_lite = {
+	.cm0ioctl		= K4B2G1646EBIH9_IOCTRL_VALUE,
+	.cm1ioctl		= K4B2G1646EBIH9_IOCTRL_VALUE,
+	.cm2ioctl		= K4B2G1646EBIH9_IOCTRL_VALUE,
+	.dt0ioctl		= K4B2G1646EBIH9_IOCTRL_VALUE,
+	.dt1ioctl		= K4B2G1646EBIH9_IOCTRL_VALUE,
+};
+
+#define OSC    (V_OSCK/1000000)
+const struct dpll_params dpll_ddr = {
+		400, OSC-1, 1, -1, -1, -1, -1};
+
+const struct dpll_params *get_dpll_ddr_params(void)
+{
+	return &dpll_ddr;
+}
+
+void set_uart_mux_conf(void)
+{
+	enable_uart0_pin_mux();
+}
+
+void set_mux_conf_regs(void)
+{
+	enable_board_pin_mux();
+}
+
+void sdram_init(void)
+{
+	if (get_board_revision() == 1)
+		config_ddr(400, &ioregs_igep0034, &ddr3_igep0034_data,
+			&ddr3_igep0034_cmd_ctrl_data, &ddr3_igep0034_emif_reg_data, 0);
+	else
+		config_ddr(400, &ioregs_igep0034_lite, &ddr3_igep0034_lite_data,
+			&ddr3_igep0034_lite_cmd_ctrl_data, &ddr3_igep0034_lite_emif_reg_data, 0);
+}
+#endif
+
+/*
+ * Basic board specific setup.  Pinmux has been handled already.
+ */
+int board_init(void)
+{
+	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+
+	gpmc_init();
+
+	return 0;
+}
+
+#ifdef CONFIG_BOARD_LATE_INIT
+int board_late_init(void)
+{
+#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+	switch (get_board_revision()) {
+		case 0:
+			setenv("board_name", "igep0034-lite");
+			break;
+		case 1:
+			setenv("board_name", "igep0034");
+			break;
+		default:
+			setenv("board_name", "igep0033");
+			break;
+	}
+#endif
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_OF_BOARD_SETUP
+int ft_board_setup(void *blob, bd_t *bd)
+{
+#ifdef CONFIG_FDT_FIXUP_PARTITIONS
+	static struct node_info nodes[] = {
+		{ "ti,omap2-nand", MTD_DEV_TYPE_NAND, },
+	};
+
+	fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
+#endif
+	return 0;
+}
+#endif
+
+#if defined(CONFIG_DRIVER_TI_CPSW)
+static void cpsw_control(int enabled)
+{
+	/* VTP can be added here */
+
+	return;
+}
+
+static struct cpsw_slave_data cpsw_slaves[] = {
+	{
+		.slave_reg_ofs	= 0x208,
+		.sliver_reg_ofs	= 0xd80,
+		.phy_addr	= 0,
+		.phy_if		= PHY_INTERFACE_MODE_RMII,
+	},
+};
+
+static struct cpsw_platform_data cpsw_data = {
+	.mdio_base		= CPSW_MDIO_BASE,
+	.cpsw_base		= CPSW_BASE,
+	.mdio_div		= 0xff,
+	.channels		= 8,
+	.cpdma_reg_ofs		= 0x800,
+	.slaves			= 1,
+	.slave_data		= cpsw_slaves,
+	.ale_reg_ofs		= 0xd00,
+	.ale_entries		= 1024,
+	.host_port_reg_ofs	= 0x108,
+	.hw_stats_reg_ofs	= 0x900,
+	.bd_ram_ofs		= 0x2000,
+	.mac_control		= (1 << 5),
+	.control		= cpsw_control,
+	.host_port_num		= 0,
+	.version		= CPSW_CTRL_VERSION_2,
+};
+
+int board_eth_init(bd_t *bis)
+{
+	int rv, ret = 0;
+	uint8_t mac_addr[6];
+	uint32_t mac_hi, mac_lo;
+
+	if (!eth_getenv_enetaddr("ethaddr", mac_addr)) {
+		/* try reading mac address from efuse */
+		mac_lo = readl(&cdev->macid0l);
+		mac_hi = readl(&cdev->macid0h);
+		mac_addr[0] = mac_hi & 0xFF;
+		mac_addr[1] = (mac_hi & 0xFF00) >> 8;
+		mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
+		mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
+		mac_addr[4] = mac_lo & 0xFF;
+		mac_addr[5] = (mac_lo & 0xFF00) >> 8;
+		if (is_valid_ethaddr(mac_addr))
+			eth_setenv_enetaddr("ethaddr", mac_addr);
+	}
+
+	writel((GMII1_SEL_RMII | RMII1_IO_CLK_EN),
+	       &cdev->miisel);
+
+	if (get_board_revision() == 1)
+		cpsw_slaves[0].phy_addr = 1;
+
+	rv = cpsw_register(&cpsw_data);
+	if (rv < 0)
+		printf("Error %d registering CPSW switch\n", rv);
+	else
+		ret += rv;
+
+	return ret;
+}
+#endif
diff --git a/board/isee/igep0033/board.h b/board/isee/igep003x/board.h
similarity index 100%
rename from board/isee/igep0033/board.h
rename to board/isee/igep003x/board.h
diff --git a/board/isee/igep0033/mux.c b/board/isee/igep003x/mux.c
similarity index 90%
rename from board/isee/igep0033/mux.c
rename to board/isee/igep003x/mux.c
index e8627766..550e3b3 100644
--- a/board/isee/igep0033/mux.c
+++ b/board/isee/igep003x/mux.c
@@ -32,7 +32,7 @@
 	{OFFSET(mmc0_dat0), (MODE(0) | RXACTIVE | PULLUP_EN)},	/* MMC0_DAT0 */
 	{OFFSET(mmc0_clk), (MODE(0) | RXACTIVE | PULLUP_EN)},	/* MMC0_CLK */
 	{OFFSET(mmc0_cmd), (MODE(0) | RXACTIVE | PULLUP_EN)},	/* MMC0_CMD */
-	{OFFSET(mcasp0_aclkx), (MODE(4) | RXACTIVE)},		/* MMC0_CD */
+	{OFFSET(spi0_cs1), (MODE(5) | RXACTIVE | PULLUP_EN)},	/* MMC0_CD */
 	{-1},
 };
 
@@ -69,6 +69,12 @@
 	{-1},
 };
 
+static struct module_pin_mux gpio_pin_mux[] = {
+	{OFFSET(gpmc_ad10), (MODE(7) | RXACTIVE | PULLUP_EN)},	/* GPIO0_26 */
+	{OFFSET(gpmc_ad11), (MODE(7) | RXACTIVE | PULLUP_EN)},	/* GPIO0_27 */
+	{-1},
+};
+
 void enable_uart0_pin_mux(void)
 {
 	configure_module_pin_mux(uart0_pin_mux);
@@ -85,4 +91,6 @@
 	configure_module_pin_mux(mmc0_pin_mux);
 	/* Ethernet pinmux. */
 	configure_module_pin_mux(rmii1_pin_mux);
+	/* GPIO pinmux. */
+	configure_module_pin_mux(gpio_pin_mux);
 }
diff --git a/board/st/stm32f746-disco/stm32f746-disco.c b/board/st/stm32f746-disco/stm32f746-disco.c
index fdad8d1..dc3a9dc 100644
--- a/board/st/stm32f746-disco/stm32f746-disco.c
+++ b/board/st/stm32f746-disco/stm32f746-disco.c
@@ -6,268 +6,83 @@
  */
 
 #include <common.h>
+#include <dm.h>
+#include <ram.h>
 #include <asm/io.h>
 #include <asm/armv7m.h>
 #include <asm/arch/stm32.h>
 #include <asm/arch/gpio.h>
-#include <asm/arch/fmc.h>
 #include <dm/platdata.h>
 #include <dm/platform_data/serial_stm32x7.h>
 #include <asm/arch/stm32_periph.h>
 #include <asm/arch/stm32_defs.h>
 #include <asm/arch/syscfg.h>
+#include <asm/gpio.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-const struct stm32_gpio_ctl gpio_ctl_gpout = {
-	.mode = STM32_GPIO_MODE_OUT,
-	.otype = STM32_GPIO_OTYPE_PP,
-	.speed = STM32_GPIO_SPEED_50M,
-	.pupd = STM32_GPIO_PUPD_NO,
-	.af = STM32_GPIO_AF0
-};
-
-const struct stm32_gpio_ctl gpio_ctl_fmc = {
-	.mode = STM32_GPIO_MODE_AF,
-	.otype = STM32_GPIO_OTYPE_PP,
-	.speed = STM32_GPIO_SPEED_100M,
-	.pupd = STM32_GPIO_PUPD_NO,
-	.af = STM32_GPIO_AF12
-};
-
-static const struct stm32_gpio_dsc ext_ram_fmc_gpio[] = {
-	/* Chip is LQFP144, see DM00077036.pdf for details */
-	{STM32_GPIO_PORT_D, STM32_GPIO_PIN_10},	/* 79, FMC_D15 */
-	{STM32_GPIO_PORT_D, STM32_GPIO_PIN_9},	/* 78, FMC_D14 */
-	{STM32_GPIO_PORT_D, STM32_GPIO_PIN_8},	/* 77, FMC_D13 */
-	{STM32_GPIO_PORT_E, STM32_GPIO_PIN_15},	/* 68, FMC_D12 */
-	{STM32_GPIO_PORT_E, STM32_GPIO_PIN_14},	/* 67, FMC_D11 */
-	{STM32_GPIO_PORT_E, STM32_GPIO_PIN_13},	/* 66, FMC_D10 */
-	{STM32_GPIO_PORT_E, STM32_GPIO_PIN_12},	/* 65, FMC_D9 */
-	{STM32_GPIO_PORT_E, STM32_GPIO_PIN_11},	/* 64, FMC_D8 */
-	{STM32_GPIO_PORT_E, STM32_GPIO_PIN_10},	/* 63, FMC_D7 */
-	{STM32_GPIO_PORT_E, STM32_GPIO_PIN_9},	/* 60, FMC_D6 */
-	{STM32_GPIO_PORT_E, STM32_GPIO_PIN_8},	/* 59, FMC_D5 */
-	{STM32_GPIO_PORT_E, STM32_GPIO_PIN_7},	/* 58, FMC_D4 */
-	{STM32_GPIO_PORT_D, STM32_GPIO_PIN_1},	/* 115, FMC_D3 */
-	{STM32_GPIO_PORT_D, STM32_GPIO_PIN_0},	/* 114, FMC_D2 */
-	{STM32_GPIO_PORT_D, STM32_GPIO_PIN_15},	/* 86, FMC_D1 */
-	{STM32_GPIO_PORT_D, STM32_GPIO_PIN_14},	/* 85, FMC_D0 */
-
-	{STM32_GPIO_PORT_E, STM32_GPIO_PIN_1},	/* 142, FMC_NBL1 */
-	{STM32_GPIO_PORT_E, STM32_GPIO_PIN_0},	/* 141, FMC_NBL0 */
-
-	{STM32_GPIO_PORT_G, STM32_GPIO_PIN_5},	/* 90, FMC_A15, BA1 */
-	{STM32_GPIO_PORT_G, STM32_GPIO_PIN_4},	/* 89, FMC_A14, BA0 */
-
-	{STM32_GPIO_PORT_G, STM32_GPIO_PIN_1},	/* 57, FMC_A11 */
-	{STM32_GPIO_PORT_G, STM32_GPIO_PIN_0},	/* 56, FMC_A10 */
-	{STM32_GPIO_PORT_F, STM32_GPIO_PIN_15},	/* 55, FMC_A9 */
-	{STM32_GPIO_PORT_F, STM32_GPIO_PIN_14},	/* 54, FMC_A8 */
-	{STM32_GPIO_PORT_F, STM32_GPIO_PIN_13},	/* 53, FMC_A7 */
-	{STM32_GPIO_PORT_F, STM32_GPIO_PIN_12},	/* 50, FMC_A6 */
-	{STM32_GPIO_PORT_F, STM32_GPIO_PIN_5},	/* 15, FMC_A5 */
-	{STM32_GPIO_PORT_F, STM32_GPIO_PIN_4},	/* 14, FMC_A4 */
-	{STM32_GPIO_PORT_F, STM32_GPIO_PIN_3},	/* 13, FMC_A3 */
-	{STM32_GPIO_PORT_F, STM32_GPIO_PIN_2},	/* 12, FMC_A2 */
-	{STM32_GPIO_PORT_F, STM32_GPIO_PIN_1},	/* 11, FMC_A1 */
-	{STM32_GPIO_PORT_F, STM32_GPIO_PIN_0},	/* 10, FMC_A0 */
-
-	{STM32_GPIO_PORT_H, STM32_GPIO_PIN_3},	/* 136, SDRAM_NE */
-	{STM32_GPIO_PORT_F, STM32_GPIO_PIN_11},	/* 49, SDRAM_NRAS */
-	{STM32_GPIO_PORT_G, STM32_GPIO_PIN_15},	/* 132, SDRAM_NCAS */
-	{STM32_GPIO_PORT_H, STM32_GPIO_PIN_5},	/* 26, SDRAM_NWE */
-	{STM32_GPIO_PORT_C, STM32_GPIO_PIN_3},	/* 135, SDRAM_CKE */
-
-	{STM32_GPIO_PORT_G, STM32_GPIO_PIN_8},	/* 93, SDRAM_CLK */
-};
-
-static int fmc_setup_gpio(void)
+int get_memory_base_size(fdt_addr_t *mr_base, fdt_addr_t *mr_size)
 {
-	int rv = 0;
-	int i;
-
-	clock_setup(GPIO_B_CLOCK_CFG);
-	clock_setup(GPIO_C_CLOCK_CFG);
-	clock_setup(GPIO_D_CLOCK_CFG);
-	clock_setup(GPIO_E_CLOCK_CFG);
-	clock_setup(GPIO_F_CLOCK_CFG);
-	clock_setup(GPIO_G_CLOCK_CFG);
-	clock_setup(GPIO_H_CLOCK_CFG);
+	int mr_node;
 
-	for (i = 0; i < ARRAY_SIZE(ext_ram_fmc_gpio); i++) {
-		rv = stm32_gpio_config(&ext_ram_fmc_gpio[i],
-				&gpio_ctl_fmc);
-		if (rv)
-			goto out;
-	}
+	mr_node = fdt_path_offset(gd->fdt_blob, "/memory");
+	if (mr_node < 0)
+		return mr_node;
+	*mr_base = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, mr_node,
+						      "reg", 0, mr_size, false);
+	debug("mr_base = %lx, mr_size= %lx\n", *mr_base, *mr_size);
 
-out:
-	return rv;
-}
-
-static inline u32 _ns2clk(u32 ns, u32 freq)
-{
-	u32 tmp = freq/1000000;
-	return (tmp * ns) / 1000;
+	return 0;
 }
-
-#define NS2CLK(ns) (_ns2clk(ns, freq))
-
-/*
- * Following are timings for IS42S16400J, from corresponding datasheet
- */
-#define SDRAM_CAS	3	/* 3 cycles */
-#define SDRAM_NB	1	/* Number of banks */
-#define SDRAM_MWID	1	/* 16 bit memory */
-
-#define SDRAM_NR	0x1	/* 12-bit row */
-#define SDRAM_NC	0x0	/* 8-bit col */
-#define SDRAM_RBURST	0x1	/* Single read requests always as bursts */
-#define SDRAM_RPIPE	0x0	/* No HCLK clock cycle delay */
-
-#define SDRAM_TRRD	NS2CLK(12)
-#define SDRAM_TRCD	NS2CLK(18)
-#define SDRAM_TRP	NS2CLK(18)
-#define SDRAM_TRAS	NS2CLK(42)
-#define SDRAM_TRC	NS2CLK(60)
-#define SDRAM_TRFC	NS2CLK(60)
-#define SDRAM_TCDL	(1 - 1)
-#define SDRAM_TRDL	NS2CLK(12)
-#define SDRAM_TBDL	(1 - 1)
-#define SDRAM_TREF	(NS2CLK(64000000 / 8192) - 20)
-#define SDRAM_TCCD	(1 - 1)
-
-#define SDRAM_TXSR	SDRAM_TRFC	/* Row cycle time after precharge */
-#define SDRAM_TMRD	1		/* Page 10, Mode Register Set */
-
-
-/* Last data in to row precharge, need also comply ineq on page 1648 */
-#define SDRAM_TWR	max(\
-	(int)max((int)SDRAM_TRDL, (int)(SDRAM_TRAS - SDRAM_TRCD)), \
-	(int)(SDRAM_TRC - SDRAM_TRCD - SDRAM_TRP)\
-)
-
-
-#define SDRAM_MODE_BL_SHIFT	0
-#define SDRAM_MODE_CAS_SHIFT	4
-#define SDRAM_MODE_BL		0
-#define SDRAM_MODE_CAS		SDRAM_CAS
-
 int dram_init(void)
 {
-	u32 freq;
+	struct udevice *dev;
 	int rv;
+	fdt_addr_t mr_base, mr_size;
 
-	rv = fmc_setup_gpio();
-	if (rv)
+	rv = uclass_get_device(UCLASS_RAM, 0, &dev);
+	if (rv) {
+		debug("DRAM init failed: %d\n", rv);
 		return rv;
-
-	clock_setup(FMC_CLOCK_CFG);
-
-	/*
-	 * Get frequency for NS2CLK calculation.
-	 */
-	freq = clock_get(CLOCK_AHB) / CONFIG_SYS_RAM_FREQ_DIV;
-
-	writel(
-		CONFIG_SYS_RAM_FREQ_DIV << FMC_SDCR_SDCLK_SHIFT
-		| SDRAM_CAS << FMC_SDCR_CAS_SHIFT
-		| SDRAM_NB << FMC_SDCR_NB_SHIFT
-		| SDRAM_MWID << FMC_SDCR_MWID_SHIFT
-		| SDRAM_NR << FMC_SDCR_NR_SHIFT
-		| SDRAM_NC << FMC_SDCR_NC_SHIFT
-		| SDRAM_RPIPE << FMC_SDCR_RPIPE_SHIFT
-		| SDRAM_RBURST << FMC_SDCR_RBURST_SHIFT,
-		&STM32_SDRAM_FMC->sdcr1);
-
-	writel(
-		SDRAM_TRCD << FMC_SDTR_TRCD_SHIFT
-		| SDRAM_TRP << FMC_SDTR_TRP_SHIFT
-		| SDRAM_TWR << FMC_SDTR_TWR_SHIFT
-		| SDRAM_TRC << FMC_SDTR_TRC_SHIFT
-		| SDRAM_TRAS << FMC_SDTR_TRAS_SHIFT
-		| SDRAM_TXSR << FMC_SDTR_TXSR_SHIFT
-		| SDRAM_TMRD << FMC_SDTR_TMRD_SHIFT,
-		&STM32_SDRAM_FMC->sdtr1);
-
-	writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_START_CLOCK,
-	       &STM32_SDRAM_FMC->sdcmr);
-
-	udelay(200);	/* 200 us delay, page 10, "Power-Up" */
-	FMC_BUSY_WAIT();
-
-	writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_PRECHARGE,
-	       &STM32_SDRAM_FMC->sdcmr);
-
-	udelay(100);
-	FMC_BUSY_WAIT();
-
-	writel((FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_AUTOREFRESH
-		| 7 << FMC_SDCMR_NRFS_SHIFT), &STM32_SDRAM_FMC->sdcmr);
-
-	udelay(100);
-	FMC_BUSY_WAIT();
-
-	writel(FMC_SDCMR_BANK_1 | (SDRAM_MODE_BL << SDRAM_MODE_BL_SHIFT
-		| SDRAM_MODE_CAS << SDRAM_MODE_CAS_SHIFT)
-		<< FMC_SDCMR_MODE_REGISTER_SHIFT | FMC_SDCMR_MODE_WRITE_MODE,
-		&STM32_SDRAM_FMC->sdcmr);
-
-	udelay(100);
-
-	FMC_BUSY_WAIT();
-
-	writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_NORMAL,
-	       &STM32_SDRAM_FMC->sdcmr);
+	}
 
-	FMC_BUSY_WAIT();
+	rv = get_memory_base_size(&mr_base, &mr_size);
+	if (rv)
+		return rv;
+	gd->ram_size = mr_size;
+	gd->ram_top = mr_base;
 
-	/* Refresh timer */
-	writel(SDRAM_TREF, &STM32_SDRAM_FMC->sdrtr);
+	return rv;
+}
 
+int dram_init_banksize(void)
+{
+	fdt_addr_t mr_base, mr_size;
+	get_memory_base_size(&mr_base, &mr_size);
 	/*
 	 * Fill in global info with description of SRAM configuration
 	 */
-	gd->bd->bi_dram[0].start = CONFIG_SYS_RAM_BASE;
-	gd->bd->bi_dram[0].size  = CONFIG_SYS_RAM_SIZE;
-
-	gd->ram_size = CONFIG_SYS_RAM_SIZE;
-
-	return rv;
-}
+	gd->bd->bi_dram[0].start = mr_base;
+	gd->bd->bi_dram[0].size  = mr_size;
 
-int uart_setup_gpio(void)
-{
-	clock_setup(GPIO_A_CLOCK_CFG);
-	clock_setup(GPIO_B_CLOCK_CFG);
 	return 0;
 }
 
 #ifdef CONFIG_ETH_DESIGNWARE
-
 static int stmmac_setup(void)
 {
 	clock_setup(SYSCFG_CLOCK_CFG);
 	/* Set >RMII mode */
 	STM32_SYSCFG->pmc |= SYSCFG_PMC_MII_RMII_SEL;
-
-	clock_setup(GPIO_A_CLOCK_CFG);
-	clock_setup(GPIO_C_CLOCK_CFG);
-	clock_setup(GPIO_G_CLOCK_CFG);
 	clock_setup(STMMAC_CLOCK_CFG);
 
 	return 0;
 }
-#endif
-
-#ifdef CONFIG_STM32_QSPI
 
-static int qspi_setup(void)
+int board_early_init_f(void)
 {
-	clock_setup(GPIO_B_CLOCK_CFG);
-	clock_setup(GPIO_D_CLOCK_CFG);
-	clock_setup(GPIO_E_CLOCK_CFG);
+	stmmac_setup();
+
 	return 0;
 }
 #endif
@@ -277,32 +92,44 @@
 	return 0;
 }
 
-int board_early_init_f(void)
+int board_late_init(void)
 {
-	int res;
+	struct gpio_desc gpio = {};
+	int node;
 
-	res = uart_setup_gpio();
-	if (res)
-		return res;
+	node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "st,led1");
+	if (node < 0)
+		return -1;
 
-#ifdef CONFIG_ETH_DESIGNWARE
-	res = stmmac_setup();
-	if (res)
-		return res;
-#endif
+	gpio_request_by_name_nodev(gd->fdt_blob, node, "led-gpio", 0, &gpio,
+				   GPIOD_IS_OUT);
 
-#ifdef CONFIG_STM32_QSPI
-	res = qspi_setup();
-	if (res)
-		return res;
-#endif
+	if (dm_gpio_is_valid(&gpio)) {
+		dm_gpio_set_value(&gpio, 0);
+		mdelay(10);
+		dm_gpio_set_value(&gpio, 1);
+	}
+
+	/* read button 1*/
+	node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "st,button1");
+	if (node < 0)
+		return -1;
+
+	gpio_request_by_name_nodev(gd->fdt_blob, node, "button-gpio", 0, &gpio,
+				   GPIOD_IS_IN);
+
+	if (dm_gpio_is_valid(&gpio)) {
+		if (dm_gpio_get_value(&gpio))
+			puts("usr button is at HIGH LEVEL\n");
+		else
+			puts("usr button is at LOW LEVEL\n");
+	}
 
 	return 0;
 }
 
 int board_init(void)
 {
-	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
-
+	gd->bd->bi_boot_params = gd->bd->bi_dram[0].start + 0x100;
 	return 0;
 }
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index f39402b..1c88173 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -280,6 +280,11 @@
 F:	configs/Sinlinx_SinA33_defconfig
 W:	http://linux-sunxi.org/Sinlinx_SinA33
 
+SINOVOIP BPI M2 PLUS H3 BOARD
+M:	Icenowy Zheng <icenowy@aosc.io>
+S:	Maintained
+F:	configs/Sinovoip_BPI_M2_Plus_defconfig
+
 SINOVOIP BPI M3 A83T BOARD
 M:	VishnuPatekar <vishnupatekar0510@gmail.com>
 S:	Maintained
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 04a6291..01de42d 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -77,6 +77,100 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+void i2c_init_board(void)
+{
+#ifdef CONFIG_I2C0_ENABLE
+#if defined(CONFIG_MACH_SUN4I) || \
+    defined(CONFIG_MACH_SUN5I) || \
+    defined(CONFIG_MACH_SUN7I) || \
+    defined(CONFIG_MACH_SUN8I_R40)
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN4I_GPB_TWI0);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN4I_GPB_TWI0);
+	clock_twi_onoff(0, 1);
+#elif defined(CONFIG_MACH_SUN6I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(14), SUN6I_GPH_TWI0);
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(15), SUN6I_GPH_TWI0);
+	clock_twi_onoff(0, 1);
+#elif defined(CONFIG_MACH_SUN8I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN8I_GPH_TWI0);
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN8I_GPH_TWI0);
+	clock_twi_onoff(0, 1);
+#endif
+#endif
+
+#ifdef CONFIG_I2C1_ENABLE
+#if defined(CONFIG_MACH_SUN4I) || \
+    defined(CONFIG_MACH_SUN7I) || \
+    defined(CONFIG_MACH_SUN8I_R40)
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN4I_GPB_TWI1);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN4I_GPB_TWI1);
+	clock_twi_onoff(1, 1);
+#elif defined(CONFIG_MACH_SUN5I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(15), SUN5I_GPB_TWI1);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(16), SUN5I_GPB_TWI1);
+	clock_twi_onoff(1, 1);
+#elif defined(CONFIG_MACH_SUN6I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(16), SUN6I_GPH_TWI1);
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(17), SUN6I_GPH_TWI1);
+	clock_twi_onoff(1, 1);
+#elif defined(CONFIG_MACH_SUN8I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(4), SUN8I_GPH_TWI1);
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(5), SUN8I_GPH_TWI1);
+	clock_twi_onoff(1, 1);
+#endif
+#endif
+
+#ifdef CONFIG_I2C2_ENABLE
+#if defined(CONFIG_MACH_SUN4I) || \
+    defined(CONFIG_MACH_SUN7I) || \
+    defined(CONFIG_MACH_SUN8I_R40)
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN4I_GPB_TWI2);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(21), SUN4I_GPB_TWI2);
+	clock_twi_onoff(2, 1);
+#elif defined(CONFIG_MACH_SUN5I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(17), SUN5I_GPB_TWI2);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN5I_GPB_TWI2);
+	clock_twi_onoff(2, 1);
+#elif defined(CONFIG_MACH_SUN6I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(18), SUN6I_GPH_TWI2);
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(19), SUN6I_GPH_TWI2);
+	clock_twi_onoff(2, 1);
+#elif defined(CONFIG_MACH_SUN8I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPE(12), SUN8I_GPE_TWI2);
+	sunxi_gpio_set_cfgpin(SUNXI_GPE(13), SUN8I_GPE_TWI2);
+	clock_twi_onoff(2, 1);
+#endif
+#endif
+
+#ifdef CONFIG_I2C3_ENABLE
+#if defined(CONFIG_MACH_SUN6I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPG(10), SUN6I_GPG_TWI3);
+	sunxi_gpio_set_cfgpin(SUNXI_GPG(11), SUN6I_GPG_TWI3);
+	clock_twi_onoff(3, 1);
+#elif defined(CONFIG_MACH_SUN7I) || \
+      defined(CONFIG_MACH_SUN8I_R40)
+	sunxi_gpio_set_cfgpin(SUNXI_GPI(0), SUN7I_GPI_TWI3);
+	sunxi_gpio_set_cfgpin(SUNXI_GPI(1), SUN7I_GPI_TWI3);
+	clock_twi_onoff(3, 1);
+#endif
+#endif
+
+#ifdef CONFIG_I2C4_ENABLE
+#if defined(CONFIG_MACH_SUN7I) || \
+    defined(CONFIG_MACH_SUN8I_R40)
+	sunxi_gpio_set_cfgpin(SUNXI_GPI(2), SUN7I_GPI_TWI4);
+	sunxi_gpio_set_cfgpin(SUNXI_GPI(3), SUN7I_GPI_TWI4);
+	clock_twi_onoff(4, 1);
+#endif
+#endif
+
+#ifdef CONFIG_R_I2C_ENABLE
+	clock_twi_onoff(5, 1);
+	sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_H3_GPL_R_TWI);
+	sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_H3_GPL_R_TWI);
+#endif
+}
+
 /* add board specific code here */
 int board_init(void)
 {
@@ -128,6 +222,14 @@
 	gpio_direction_output(macpwr_pin, 1);
 #endif
 
+#ifdef CONFIG_DM_I2C
+	/*
+	 * Temporary workaround for enabling I2C clocks until proper sunxi DM
+	 * clk, reset and pinctrl drivers land.
+	 */
+	i2c_init_board();
+#endif
+
 	/* Uses dm gpio code so do this here and not in i2c_init_board() */
 	return soft_i2c_board_init();
 }
@@ -405,100 +507,6 @@
 	return 0;
 }
 #endif
-
-void i2c_init_board(void)
-{
-#ifdef CONFIG_I2C0_ENABLE
-#if defined(CONFIG_MACH_SUN4I) || \
-    defined(CONFIG_MACH_SUN5I) || \
-    defined(CONFIG_MACH_SUN7I) || \
-    defined(CONFIG_MACH_SUN8I_R40)
-	sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN4I_GPB_TWI0);
-	sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN4I_GPB_TWI0);
-	clock_twi_onoff(0, 1);
-#elif defined(CONFIG_MACH_SUN6I)
-	sunxi_gpio_set_cfgpin(SUNXI_GPH(14), SUN6I_GPH_TWI0);
-	sunxi_gpio_set_cfgpin(SUNXI_GPH(15), SUN6I_GPH_TWI0);
-	clock_twi_onoff(0, 1);
-#elif defined(CONFIG_MACH_SUN8I)
-	sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN8I_GPH_TWI0);
-	sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN8I_GPH_TWI0);
-	clock_twi_onoff(0, 1);
-#endif
-#endif
-
-#ifdef CONFIG_I2C1_ENABLE
-#if defined(CONFIG_MACH_SUN4I) || \
-    defined(CONFIG_MACH_SUN7I) || \
-    defined(CONFIG_MACH_SUN8I_R40)
-	sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN4I_GPB_TWI1);
-	sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN4I_GPB_TWI1);
-	clock_twi_onoff(1, 1);
-#elif defined(CONFIG_MACH_SUN5I)
-	sunxi_gpio_set_cfgpin(SUNXI_GPB(15), SUN5I_GPB_TWI1);
-	sunxi_gpio_set_cfgpin(SUNXI_GPB(16), SUN5I_GPB_TWI1);
-	clock_twi_onoff(1, 1);
-#elif defined(CONFIG_MACH_SUN6I)
-	sunxi_gpio_set_cfgpin(SUNXI_GPH(16), SUN6I_GPH_TWI1);
-	sunxi_gpio_set_cfgpin(SUNXI_GPH(17), SUN6I_GPH_TWI1);
-	clock_twi_onoff(1, 1);
-#elif defined(CONFIG_MACH_SUN8I)
-	sunxi_gpio_set_cfgpin(SUNXI_GPH(4), SUN8I_GPH_TWI1);
-	sunxi_gpio_set_cfgpin(SUNXI_GPH(5), SUN8I_GPH_TWI1);
-	clock_twi_onoff(1, 1);
-#endif
-#endif
-
-#ifdef CONFIG_I2C2_ENABLE
-#if defined(CONFIG_MACH_SUN4I) || \
-    defined(CONFIG_MACH_SUN7I) || \
-    defined(CONFIG_MACH_SUN8I_R40)
-	sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN4I_GPB_TWI2);
-	sunxi_gpio_set_cfgpin(SUNXI_GPB(21), SUN4I_GPB_TWI2);
-	clock_twi_onoff(2, 1);
-#elif defined(CONFIG_MACH_SUN5I)
-	sunxi_gpio_set_cfgpin(SUNXI_GPB(17), SUN5I_GPB_TWI2);
-	sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN5I_GPB_TWI2);
-	clock_twi_onoff(2, 1);
-#elif defined(CONFIG_MACH_SUN6I)
-	sunxi_gpio_set_cfgpin(SUNXI_GPH(18), SUN6I_GPH_TWI2);
-	sunxi_gpio_set_cfgpin(SUNXI_GPH(19), SUN6I_GPH_TWI2);
-	clock_twi_onoff(2, 1);
-#elif defined(CONFIG_MACH_SUN8I)
-	sunxi_gpio_set_cfgpin(SUNXI_GPE(12), SUN8I_GPE_TWI2);
-	sunxi_gpio_set_cfgpin(SUNXI_GPE(13), SUN8I_GPE_TWI2);
-	clock_twi_onoff(2, 1);
-#endif
-#endif
-
-#ifdef CONFIG_I2C3_ENABLE
-#if defined(CONFIG_MACH_SUN6I)
-	sunxi_gpio_set_cfgpin(SUNXI_GPG(10), SUN6I_GPG_TWI3);
-	sunxi_gpio_set_cfgpin(SUNXI_GPG(11), SUN6I_GPG_TWI3);
-	clock_twi_onoff(3, 1);
-#elif defined(CONFIG_MACH_SUN7I) || \
-      defined(CONFIG_MACH_SUN8I_R40)
-	sunxi_gpio_set_cfgpin(SUNXI_GPI(0), SUN7I_GPI_TWI3);
-	sunxi_gpio_set_cfgpin(SUNXI_GPI(1), SUN7I_GPI_TWI3);
-	clock_twi_onoff(3, 1);
-#endif
-#endif
-
-#ifdef CONFIG_I2C4_ENABLE
-#if defined(CONFIG_MACH_SUN7I) || \
-    defined(CONFIG_MACH_SUN8I_R40)
-	sunxi_gpio_set_cfgpin(SUNXI_GPI(2), SUN7I_GPI_TWI4);
-	sunxi_gpio_set_cfgpin(SUNXI_GPI(3), SUN7I_GPI_TWI4);
-	clock_twi_onoff(4, 1);
-#endif
-#endif
-
-#ifdef CONFIG_R_I2C_ENABLE
-	clock_twi_onoff(5, 1);
-	sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_H3_GPL_R_TWI);
-	sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_H3_GPL_R_TWI);
-#endif
-}
 
 #ifdef CONFIG_SPL_BUILD
 void sunxi_board_init(void)
diff --git a/board/ti/am43xx/board.c b/board/ti/am43xx/board.c
index 390cc16..2572029 100644
--- a/board/ti/am43xx/board.c
+++ b/board/ti/am43xx/board.c
@@ -694,7 +694,7 @@
 #endif /* CONFIG_USB_DWC3 */
 
 #if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP)
-int board_usb_init(int index, enum usb_init_type init)
+int omap_xhci_board_usb_init(int index, enum usb_init_type init)
 {
 	enable_usb_clocks(index);
 #ifdef CONFIG_USB_DWC3
@@ -725,7 +725,7 @@
 	return 0;
 }
 
-int board_usb_cleanup(int index, enum usb_init_type init)
+int omap_xhci_board_usb_cleanup(int index, enum usb_init_type init)
 {
 #ifdef CONFIG_USB_DWC3
 	switch (index) {
diff --git a/board/ti/am57xx/board.c b/board/ti/am57xx/board.c
index 1cfc08b..6d444e0 100644
--- a/board/ti/am57xx/board.c
+++ b/board/ti/am57xx/board.c
@@ -720,7 +720,7 @@
 #endif /* CONFIG_USB_DWC3 */
 
 #if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP)
-int board_usb_init(int index, enum usb_init_type init)
+int omap_xhci_board_usb_init(int index, enum usb_init_type init)
 {
 	enable_usb_clocks(index);
 	switch (index) {
@@ -754,7 +754,7 @@
 	return 0;
 }
 
-int board_usb_cleanup(int index, enum usb_init_type init)
+int omap_xhci_board_usb_cleanup(int index, enum usb_init_type init)
 {
 #ifdef CONFIG_USB_DWC3
 	switch (index) {
diff --git a/board/ti/common/Kconfig b/board/ti/common/Kconfig
index 15b5ccf..08c39d9 100644
--- a/board/ti/common/Kconfig
+++ b/board/ti/common/Kconfig
@@ -13,3 +13,29 @@
 	hex "Board EEPROM's I2C chip address"
 	range 0 0xff
 	default 0x50
+
+config TI_COMMON_CMD_OPTIONS
+	bool "Enable cmd options on TI platforms"
+	imply CMD_ASKENV
+	imply CMD_BOOTZ
+	imply CMD_DFU if USB_GADGET_DOWNLOAD
+	imply CMD_DHCP
+	imply CMD_EXT2
+	imply CMD_EXT4
+	imply CMD_EXT4_WRITE
+	imply CMD_FASTBOOT if FASTBOOT
+	imply CMD_FAT
+	imply CMD_FS_GENERIC
+	imply CMD_GPIO
+	imply CMD_GPT
+	imply CMD_I2C
+	imply CMD_MII
+	imply CMD_MMC
+	imply CMD_PART
+	imply CMD_PING
+	imply CMD_PMIC if DM_PMIC
+	imply CMD_REGULATOR if DM_REGULATOR
+	imply CMD_SF if SPI_FLASH
+	imply CMD_SPI
+	imply CMD_TIME
+	imply CMD_USB if USB
diff --git a/board/ti/dra7xx/evm.c b/board/ti/dra7xx/evm.c
index ed0bc18..d8e48dd 100644
--- a/board/ti/dra7xx/evm.c
+++ b/board/ti/dra7xx/evm.c
@@ -750,7 +750,7 @@
 	.index = 1,
 };
 
-int board_usb_init(int index, enum usb_init_type init)
+int omap_xhci_board_usb_init(int index, enum usb_init_type init)
 {
 	enable_usb_clocks(index);
 	switch (index) {
@@ -787,7 +787,7 @@
 	return 0;
 }
 
-int board_usb_cleanup(int index, enum usb_init_type init)
+int omap_xhci_board_usb_cleanup(int index, enum usb_init_type init)
 {
 	switch (index) {
 	case 0:
diff --git a/board/ti/ks2_evm/board_k2e.c b/board/ti/ks2_evm/board_k2e.c
index cbb3077..64f0c9c 100644
--- a/board/ti/ks2_evm/board_k2e.c
+++ b/board/ti/ks2_evm/board_k2e.c
@@ -14,12 +14,30 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-unsigned int external_clk[ext_clk_count] = {
-	[sys_clk]	= 100000000,
-	[alt_core_clk]	= 100000000,
-	[pa_clk]	= 100000000,
-	[ddr3a_clk]	= 100000000,
-};
+unsigned int get_external_clk(u32 clk)
+{
+	unsigned int clk_freq;
+
+	switch (clk) {
+	case sys_clk:
+		clk_freq = 100000000;
+		break;
+	case alt_core_clk:
+		clk_freq = 100000000;
+		break;
+	case pa_clk:
+		clk_freq = 100000000;
+		break;
+	case ddr3a_clk:
+		clk_freq = 100000000;
+		break;
+	default:
+		clk_freq = 0;
+		break;
+	}
+
+	return clk_freq;
+}
 
 static struct pll_init_data core_pll_config[NUM_SPDS] = {
 	[SPD800]	= CORE_PLL_800,
diff --git a/board/ti/ks2_evm/board_k2g.c b/board/ti/ks2_evm/board_k2g.c
index 79e110e..6e03f6b 100644
--- a/board/ti/ks2_evm/board_k2g.c
+++ b/board/ti/ks2_evm/board_k2g.c
@@ -14,16 +14,42 @@
 #include "mux-k2g.h"
 #include "../common/board_detect.h"
 
-#define SYS_CLK		24000000
-
-unsigned int external_clk[ext_clk_count] = {
-	[sys_clk]	=	SYS_CLK,
-	[pa_clk]	=	SYS_CLK,
-	[tetris_clk]	=	SYS_CLK,
-	[ddr3a_clk]	=	SYS_CLK,
-	[uart_clk]	=	SYS_CLK,
+const unsigned int sysclk_array[MAX_SYSCLK] = {
+	19200000,
+	24000000,
+	25000000,
+	26000000,
 };
 
+unsigned int get_external_clk(u32 clk)
+{
+	unsigned int clk_freq;
+	u8 sysclk_index = get_sysclk_index();
+
+	switch (clk) {
+	case sys_clk:
+		clk_freq = sysclk_array[sysclk_index];
+		break;
+	case pa_clk:
+		clk_freq = sysclk_array[sysclk_index];
+		break;
+	case tetris_clk:
+		clk_freq = sysclk_array[sysclk_index];
+		break;
+	case ddr3a_clk:
+		clk_freq = sysclk_array[sysclk_index];
+		break;
+	case uart_clk:
+		clk_freq = sysclk_array[sysclk_index];
+		break;
+	default:
+		clk_freq = 0;
+		break;
+	}
+
+	return clk_freq;
+}
+
 static int arm_speeds[DEVSPEED_NUMSPDS] = {
 	SPD400,
 	SPD600,
@@ -48,49 +74,116 @@
 	SPD400,
 };
 
+static struct pll_init_data main_pll_config[MAX_SYSCLK][NUM_SPDS] = {
+	[SYSCLK_19MHz] = {
+		[SPD400]	= {MAIN_PLL, 125, 3, 2},
+		[SPD600]	= {MAIN_PLL, 125, 2, 2},
+		[SPD800]	= {MAIN_PLL, 250, 3, 2},
+		[SPD900]	= {TETRIS_PLL, 187, 2, 2},
+		[SPD1000]	= {TETRIS_PLL, 104, 1, 2},
+	},
+	[SYSCLK_24MHz] = {
+		[SPD400]	= {MAIN_PLL, 100, 3, 2},
+		[SPD600]	= {MAIN_PLL, 300, 6, 2},
+		[SPD800]	= {MAIN_PLL, 200, 3, 2},
+		[SPD900]	= {TETRIS_PLL, 75, 1, 2},
+		[SPD1000]	= {TETRIS_PLL, 250, 3, 2},
+	},
+	[SYSCLK_25MHz] = {
+		[SPD400]	= {MAIN_PLL, 32, 1, 2},
+		[SPD600]	= {MAIN_PLL, 48, 1, 2},
+		[SPD800]	= {MAIN_PLL, 64, 1, 2},
+		[SPD900]	= {TETRIS_PLL, 72, 1, 2},
+		[SPD1000]	= {TETRIS_PLL, 80, 1, 2},
+	},
+	[SYSCLK_26MHz] = {
+		[SPD400]	= {MAIN_PLL, 400, 13, 2},
+		[SPD600]	= {MAIN_PLL, 230, 5, 2},
+		[SPD800]	= {MAIN_PLL, 123, 2, 2},
+		[SPD900]	= {TETRIS_PLL, 69, 1, 2},
+		[SPD1000]	= {TETRIS_PLL, 384, 5, 2},
+	},
+};
+
+static struct pll_init_data tetris_pll_config[MAX_SYSCLK][NUM_SPDS] = {
+	[SYSCLK_19MHz] = {
+		[SPD200]	= {TETRIS_PLL, 625, 6, 10},
+		[SPD400]	= {TETRIS_PLL, 125, 1, 6},
+		[SPD600]	= {TETRIS_PLL, 125, 1, 4},
+		[SPD800]	= {TETRIS_PLL, 333, 2, 4},
+		[SPD900]	= {TETRIS_PLL, 187, 2, 2},
+		[SPD1000]	= {TETRIS_PLL, 104, 1, 2},
+	},
+	[SYSCLK_24MHz] = {
+		[SPD200]	= {TETRIS_PLL, 250, 3, 10},
+		[SPD400]	= {TETRIS_PLL, 100, 1, 6},
+		[SPD600]	= {TETRIS_PLL, 100, 1, 4},
+		[SPD800]	= {TETRIS_PLL, 400, 3, 4},
+		[SPD900]	= {TETRIS_PLL, 75, 1, 2},
+		[SPD1000]	= {TETRIS_PLL, 250, 3, 2},
+	},
+	[SYSCLK_25MHz] = {
+		[SPD200]	= {TETRIS_PLL, 80, 1, 10},
+		[SPD400]	= {TETRIS_PLL, 96, 1, 6},
+		[SPD600]	= {TETRIS_PLL, 96, 1, 4},
+		[SPD800]	= {TETRIS_PLL, 128, 1, 4},
+		[SPD900]	= {TETRIS_PLL, 72, 1, 2},
+		[SPD1000]	= {TETRIS_PLL, 80, 1, 2},
+	},
+	[SYSCLK_26MHz] = {
+		[SPD200]	= {TETRIS_PLL, 307, 4, 10},
+		[SPD400]	= {TETRIS_PLL, 369, 4, 6},
+		[SPD600]	= {TETRIS_PLL, 369, 4, 4},
+		[SPD800]	= {TETRIS_PLL, 123, 1, 4},
+		[SPD900]	= {TETRIS_PLL, 69, 1, 2},
+		[SPD1000]	= {TETRIS_PLL, 384, 5, 2},
+	},
+};
+
-static struct pll_init_data main_pll_config[NUM_SPDS] = {
-	[SPD400]	= {MAIN_PLL, 100, 3, 2},
-	[SPD600]	= {MAIN_PLL, 300, 6, 2},
-	[SPD800]	= {MAIN_PLL, 200, 3, 2},
-	[SPD900] =	{TETRIS_PLL, 75, 1, 2},
-	[SPD1000] =	{TETRIS_PLL, 250, 3, 2},
+static struct pll_init_data uart_pll_config[MAX_SYSCLK] = {
+	[SYSCLK_19MHz] = {UART_PLL, 160, 1, 8},
+	[SYSCLK_24MHz] = {UART_PLL, 128, 1, 8},
+	[SYSCLK_25MHz] = {UART_PLL, 768, 5, 10},
+	[SYSCLK_26MHz] = {UART_PLL, 384, 13, 2},
 };
 
-static struct pll_init_data tetris_pll_config[NUM_SPDS] = {
-	[SPD200] =	{TETRIS_PLL, 250, 3, 10},
-	[SPD400] =	{TETRIS_PLL, 100, 1, 6},
-	[SPD600] =	{TETRIS_PLL, 100, 1, 4},
-	[SPD800] =	{TETRIS_PLL, 400, 3, 4},
-	[SPD900] =	{TETRIS_PLL, 75, 1, 2},
-	[SPD1000] =	{TETRIS_PLL, 250, 3, 2},
+static struct pll_init_data nss_pll_config[MAX_SYSCLK] = {
+	[SYSCLK_19MHz] = {NSS_PLL, 625, 6, 2},
+	[SYSCLK_24MHz] = {NSS_PLL, 250, 3, 2},
+	[SYSCLK_25MHz] = {NSS_PLL, 80, 1, 2},
+	[SYSCLK_26MHz] = {NSS_PLL, 1000, 13, 2},
 };
 
-static struct pll_init_data uart_pll_config = {UART_PLL, 64, 1, 4};
-static struct pll_init_data nss_pll_config = {NSS_PLL, 250, 3, 2};
-static struct pll_init_data ddr3_pll_config = {DDR3A_PLL, 133, 1, 16};
+static struct pll_init_data ddr3_pll_config[MAX_SYSCLK] = {
+	[SYSCLK_19MHz] = {DDR3A_PLL, 167, 1, 16},
+	[SYSCLK_24MHz] = {DDR3A_PLL, 133, 1, 16},
+	[SYSCLK_25MHz] = {DDR3A_PLL, 128, 1, 16},
+	[SYSCLK_26MHz] = {DDR3A_PLL, 123, 1, 16},
+};
 
 struct pll_init_data *get_pll_init_data(int pll)
 {
 	int speed;
 	struct pll_init_data *data = NULL;
+	u8 sysclk_index = get_sysclk_index();
 
 	switch (pll) {
 	case MAIN_PLL:
 		speed = get_max_dev_speed(dev_speeds);
-		data = &main_pll_config[speed];
+		data = &main_pll_config[sysclk_index][speed];
 		break;
 	case TETRIS_PLL:
 		speed = get_max_arm_speed(arm_speeds);
-		data = &tetris_pll_config[speed];
+		data = &tetris_pll_config[sysclk_index][speed];
 		break;
 	case NSS_PLL:
-		data = &nss_pll_config;
+		data = &nss_pll_config[sysclk_index];
 		break;
 	case UART_PLL:
-		data = &uart_pll_config;
+		data = &uart_pll_config[sysclk_index];
 		break;
 	case DDR3_PLL:
-		data = &ddr3_pll_config;
+		data = &ddr3_pll_config[sysclk_index];
 		break;
 	default:
 		data = NULL;
diff --git a/board/ti/ks2_evm/board_k2hk.c b/board/ti/ks2_evm/board_k2hk.c
index e217bea..b35f24d 100644
--- a/board/ti/ks2_evm/board_k2hk.c
+++ b/board/ti/ks2_evm/board_k2hk.c
@@ -23,6 +23,37 @@
 	[ddr3b_clk]	=	100000000,
 };
 
+unsigned int get_external_clk(u32 clk)
+{
+	unsigned int clk_freq;
+
+	switch (clk) {
+	case sys_clk:
+		clk_freq = 122880000;
+		break;
+	case alt_core_clk:
+		clk_freq = 125000000;
+		break;
+	case pa_clk:
+		clk_freq = 122880000;
+		break;
+	case tetris_clk:
+		clk_freq = 125000000;
+		break;
+	case ddr3a_clk:
+		clk_freq = 100000000;
+		break;
+	case ddr3b_clk:
+		clk_freq = 100000000;
+		break;
+	default:
+		clk_freq = 0;
+		break;
+	}
+
+	return clk_freq;
+}
+
 static struct pll_init_data core_pll_config[NUM_SPDS] = {
 	[SPD800]	= CORE_PLL_799,
 	[SPD1000]	= CORE_PLL_999,
diff --git a/board/ti/ks2_evm/board_k2l.c b/board/ti/ks2_evm/board_k2l.c
index 2a2e005..f3eea42 100644
--- a/board/ti/ks2_evm/board_k2l.c
+++ b/board/ti/ks2_evm/board_k2l.c
@@ -14,13 +14,33 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-unsigned int external_clk[ext_clk_count] = {
-	[sys_clk]	= 122880000,
-	[alt_core_clk]	= 100000000,
-	[pa_clk]	= 122880000,
-	[tetris_clk]	= 122880000,
-	[ddr3a_clk]	= 100000000,
-};
+unsigned int get_external_clk(u32 clk)
+{
+	unsigned int clk_freq;
+
+	switch (clk) {
+	case sys_clk:
+		clk_freq = 122880000;
+		break;
+	case alt_core_clk:
+		clk_freq = 100000000;
+		break;
+	case pa_clk:
+		clk_freq = 122880000;
+		break;
+	case tetris_clk:
+		clk_freq = 122880000;
+		break;
+	case ddr3a_clk:
+		clk_freq = 100000000;
+		break;
+	default:
+		clk_freq = 0;
+		break;
+	}
+
+	return clk_freq;
+}
 
 static struct pll_init_data core_pll_config[NUM_SPDS] = {
 	[SPD800]	= CORE_PLL_799,
diff --git a/common/spl/spl.c b/common/spl/spl.c
index a3e73b8..50828e6 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -345,6 +345,9 @@
 #endif
 
 	memset(&spl_image, '\0', sizeof(spl_image));
+#ifdef CONFIG_SYS_SPL_ARGS_ADDR
+	spl_image.arg = (void *)CONFIG_SYS_SPL_ARGS_ADDR;
+#endif
 	board_boot_order(spl_boot_list);
 
 	if (boot_from_devices(&spl_image, spl_boot_list,
@@ -361,8 +364,7 @@
 	case IH_OS_LINUX:
 		debug("Jumping to Linux\n");
 		spl_board_prepare_for_linux();
-		jump_to_image_linux(&spl_image,
-				    (void *)CONFIG_SYS_SPL_ARGS_ADDR);
+		jump_to_image_linux(&spl_image);
 #endif
 	default:
 		debug("Unsupported OS image.. Jumping nevertheless..\n");
diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c
index d07ca84..1ef8ac8 100644
--- a/common/spl/spl_nor.c
+++ b/common/spl/spl_nor.c
@@ -39,13 +39,7 @@
 					sizeof(struct image_header)),
 			       spl_image->size);
 
-			/*
-			 * Copy DT blob (fdt) to SDRAM. Passing pointer to
-			 * flash doesn't work
-			 */
-			memcpy((void *)CONFIG_SYS_SPL_ARGS_ADDR,
-			       (void *)(CONFIG_SYS_FDT_BASE),
-			       CONFIG_SYS_FDT_SIZE);
+			spl_image->arg = (void *)CONFIG_SYS_FDT_BASE;
 
 			return 0;
 		} else {
diff --git a/configs/Bananapi_M2_Ultra_defconfig b/configs/Bananapi_M2_Ultra_defconfig
index c6da727..4332eca 100644
--- a/configs/Bananapi_M2_Ultra_defconfig
+++ b/configs/Bananapi_M2_Ultra_defconfig
@@ -7,9 +7,12 @@
 CONFIG_MMC0_CD_PIN="PH13"
 CONFIG_MMC_SUNXI_SLOT_EXTRA=2
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-r40-bananapi-m2-ultra"
+CONFIG_AHCI=y
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL=y
 CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_FPGA is not set
+CONFIG_AXP_DLDO4_VOLT=2500
+CONFIG_AXP_ELDO3_VOLT=1200
diff --git a/configs/Sinovoip_BPI_M2_Plus_defconfig b/configs/Sinovoip_BPI_M2_Plus_defconfig
new file mode 100644
index 0000000..e8cd4fb
--- /dev/null
+++ b/configs/Sinovoip_BPI_M2_Plus_defconfig
@@ -0,0 +1,20 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN8I_H3=y
+CONFIG_DRAM_CLK=672
+CONFIG_DRAM_ZQ=3881979
+CONFIG_DRAM_ODT_EN=y
+CONFIG_MACPWR="PD6"
+CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-bananapi-m2-plus"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_CONSOLE_MUX=y
+CONFIG_SPL=y
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_ISO_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SUN8I_EMAC=y
+CONFIG_USB_EHCI_HCD=y
diff --git a/configs/am335x_boneblack_defconfig b/configs/am335x_boneblack_defconfig
index d3cb828..487ece4 100644
--- a/configs/am335x_boneblack_defconfig
+++ b/configs/am335x_boneblack_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_OMAP2PLUS=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_AM33XX=y
 CONFIG_TARGET_AM335X_EVM=y
 # CONFIG_SPL_NAND_SUPPORT is not set
@@ -18,18 +19,8 @@
 CONFIG_AUTOBOOT_DELAY_STR="d"
 CONFIG_AUTOBOOT_STOP_STR=" "
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
-CONFIG_CMD_GPT=y
-CONFIG_CMD_MMC=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
-CONFIG_CMD_DFU=y
-CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_EXT4_WRITE=y
 CONFIG_DFU_TFTP=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig
index 109e2a2..198efb4 100644
--- a/configs/am335x_boneblack_vboot_defconfig
+++ b/configs/am335x_boneblack_vboot_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_OMAP2PLUS=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_AM33XX=y
 CONFIG_TARGET_AM335X_EVM=y
 # CONFIG_SPL_NAND_SUPPORT is not set
@@ -21,18 +22,8 @@
 CONFIG_AUTOBOOT_DELAY_STR="d"
 CONFIG_AUTOBOOT_STOP_STR=" "
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
-CONFIG_CMD_GPT=y
-CONFIG_CMD_MMC=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
-CONFIG_CMD_DFU=y
-CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_EXT4_WRITE=y
 CONFIG_OF_CONTROL=y
 # CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
diff --git a/configs/am335x_evm_defconfig b/configs/am335x_evm_defconfig
index 0e5afba..c3237f5 100644
--- a/configs/am335x_evm_defconfig
+++ b/configs/am335x_evm_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_OMAP2PLUS=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_AM33XX=y
 CONFIG_TARGET_AM335X_EVM=y
 CONFIG_SPL_STACK_R_ADDR=0x82000000
@@ -16,18 +17,8 @@
 CONFIG_SPL_MUSB_NEW_SUPPORT=y
 CONFIG_SPL_OS_BOOT=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
-CONFIG_CMD_GPT=y
-CONFIG_CMD_MMC=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
-CONFIG_CMD_DFU=y
-CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_EXT4_WRITE=y
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="am335x-evm am335x-bone am335x-boneblack am335x-evmsk am335x-bonegreen am335x-icev2"
 # CONFIG_BLK is not set
diff --git a/configs/am335x_evm_norboot_defconfig b/configs/am335x_evm_norboot_defconfig
index 023cea4..ef8cb0b 100644
--- a/configs/am335x_evm_norboot_defconfig
+++ b/configs/am335x_evm_norboot_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 # CONFIG_SYS_THUMB_BUILD is not set
 CONFIG_ARCH_OMAP2PLUS=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_AM33XX=y
 CONFIG_TARGET_AM335X_EVM=y
 CONFIG_NOR=y
@@ -11,17 +12,7 @@
 CONFIG_ARCH_MISC_INIT=y
 CONFIG_BOARD_EARLY_INIT_F=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
-CONFIG_CMD_GPT=y
-CONFIG_CMD_MMC=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
-CONFIG_CMD_DFU=y
-CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_EXT4_WRITE=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_MMC_OMAP_HS=y
diff --git a/configs/am335x_evm_spiboot_defconfig b/configs/am335x_evm_spiboot_defconfig
index c9373f9..ece79c2 100644
--- a/configs/am335x_evm_spiboot_defconfig
+++ b/configs/am335x_evm_spiboot_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_OMAP2PLUS=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_AM33XX=y
 CONFIG_TARGET_AM335X_EVM=y
 # CONFIG_SPL_NAND_SUPPORT is not set
@@ -16,18 +17,8 @@
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_MUSB_NEW_SUPPORT=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
-CONFIG_CMD_GPT=y
-CONFIG_CMD_MMC=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
-CONFIG_CMD_DFU=y
-CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_EXT4_WRITE=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_MMC_OMAP_HS=y
diff --git a/configs/am335x_evm_usbspl_defconfig b/configs/am335x_evm_usbspl_defconfig
index 04005f0..ee3405c 100644
--- a/configs/am335x_evm_usbspl_defconfig
+++ b/configs/am335x_evm_usbspl_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_OMAP2PLUS=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_AM33XX=y
 CONFIG_TARGET_AM335X_EVM=y
 CONFIG_SPL_STACK_R_ADDR=0x82000000
@@ -15,18 +16,8 @@
 CONFIG_SPL_NET_SUPPORT=y
 CONFIG_SPL_OS_BOOT=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
-CONFIG_CMD_GPT=y
-CONFIG_CMD_MMC=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
-CONFIG_CMD_DFU=y
-CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_EXT4_WRITE=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_NAND=y
 CONFIG_DFU_RAM=y
diff --git a/configs/am335x_hs_evm_defconfig b/configs/am335x_hs_evm_defconfig
index 62e763d..73c9d01 100644
--- a/configs/am335x_hs_evm_defconfig
+++ b/configs/am335x_hs_evm_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_OMAP2PLUS=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_AM33XX=y
 CONFIG_TI_SECURE_DEVICE=y
 CONFIG_TARGET_AM335X_EVM=y
@@ -22,17 +23,8 @@
 CONFIG_SPL_MTD_SUPPORT=y
 # CONFIG_SPL_YMODEM_SUPPORT is not set
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
-CONFIG_CMD_MMC=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
-CONFIG_CMD_DFU=y
-CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_EXT4_WRITE=y
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="am335x-evm am335x-bone am335x-boneblack am335x-evmsk am335x-bonegreen am335x-icev2"
diff --git a/configs/am335x_igep0033_defconfig b/configs/am335x_igep003x_defconfig
similarity index 80%
rename from configs/am335x_igep0033_defconfig
rename to configs/am335x_igep003x_defconfig
index 27bd3f1..fa468f0 100644
--- a/configs/am335x_igep0033_defconfig
+++ b/configs/am335x_igep003x_defconfig
@@ -4,7 +4,8 @@
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_AM33XX=y
-CONFIG_TARGET_AM335X_IGEP0033=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_TARGET_AM335X_IGEP003X=y
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_LIBDISK_SUPPORT=y
@@ -13,6 +14,8 @@
 CONFIG_SPL_FAT_SUPPORT=y
 CONFIG_SPL_POWER_SUPPORT=y
 CONFIG_SPL_STACK_R_ADDR=0x82000000
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_SYS_EXTRA_OPTIONS="MACH_TYPE=MACH_TYPE_IGEP0033"
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
 CONFIG_SPL=y
@@ -40,8 +43,12 @@
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_UBI=y
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
 CONFIG_MMC_OMAP_HS=y
+CONFIG_MTD_UBI_FASTMAP=y
 CONFIG_SYS_NS16550=y
 CONFIG_OF_LIBFDT=y
+CONFIG_FDT_FIXUP_PARTITIONS=y
+# CONFIG_GENERATE_SMBIOS_TABLE is not set
diff --git a/configs/am43xx_evm_defconfig b/configs/am43xx_evm_defconfig
index 89a37fb..4d9ec88 100644
--- a/configs/am43xx_evm_defconfig
+++ b/configs/am43xx_evm_defconfig
@@ -2,6 +2,7 @@
 CONFIG_ARCH_OMAP2PLUS=y
 CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_AM43XX=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_TARGET_AM43XX_EVM=y
 CONFIG_SPL_STACK_R_ADDR=0x82000000
 CONFIG_DEFAULT_DEVICE_TREE="am437x-gp-evm"
@@ -14,28 +15,9 @@
 CONFIG_SPL_MTD_SUPPORT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_HUSH_PARSER=y
-CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
-CONFIG_CMD_GPT=y
-CONFIG_CMD_MMC=y
-CONFIG_CMD_PART=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
-CONFIG_CMD_DFU=y
-CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_EXT4_WRITE=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
 CONFIG_ISO_PARTITION=y
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="am437x-gp-evm am437x-sk-evm am43x-epos-evm am437x-idk-evm"
diff --git a/configs/am43xx_hs_evm_defconfig b/configs/am43xx_hs_evm_defconfig
index 886d54c..6f3cb51 100644
--- a/configs/am43xx_hs_evm_defconfig
+++ b/configs/am43xx_hs_evm_defconfig
@@ -2,6 +2,7 @@
 CONFIG_ARCH_OMAP2PLUS=y
 CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_AM43XX=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_TI_SECURE_DEVICE=y
 CONFIG_TARGET_AM43XX_EVM=y
 CONFIG_ISW_ENTRY_ADDR=0x403018e0
@@ -24,28 +25,9 @@
 CONFIG_SPL_USB_GADGET_SUPPORT=y
 CONFIG_SPL_USBETH_SUPPORT=y
 CONFIG_HUSH_PARSER=y
-CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
-CONFIG_CMD_GPT=y
-CONFIG_CMD_MMC=y
-CONFIG_CMD_PART=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
-CONFIG_CMD_DFU=y
-CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_EXT4_WRITE=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
 CONFIG_ISO_PARTITION=y
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="am437x-gp-evm am437x-sk-evm am43x-epos-evm am437x-idk-evm"
diff --git a/configs/am57xx_evm_defconfig b/configs/am57xx_evm_defconfig
index f64b583..5dc9f4f 100644
--- a/configs/am57xx_evm_defconfig
+++ b/configs/am57xx_evm_defconfig
@@ -2,6 +2,7 @@
 CONFIG_ARCH_OMAP2PLUS=y
 CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_OMAP54XX=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_TARGET_AM57XX_EVM=y
 # CONFIG_SPL_NAND_SUPPORT is not set
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
@@ -23,36 +24,16 @@
 CONFIG_HUSH_PARSER=y
 CONFIG_FASTBOOT=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
-CONFIG_CMD_FASTBOOT=y
 CONFIG_ANDROID_BOOT_IMAGE=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_FASTBOOT_BUF_SIZE=0x2f000000
 CONFIG_FASTBOOT_USB_DEV=1
 CONFIG_FASTBOOT_FLASH=y
 CONFIG_FASTBOOT_FLASH_MMC_DEV=1
-CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
-CONFIG_CMD_GPT=y
-CONFIG_CMD_MMC=y
-CONFIG_CMD_PART=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
-CONFIG_CMD_DFU=y
-CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_REGULATOR=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_EXT4_WRITE=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
+# CONFIG_CMD_PMIC is not set
 CONFIG_ISO_PARTITION=y
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
diff --git a/configs/am57xx_hs_evm_defconfig b/configs/am57xx_hs_evm_defconfig
index 743f82c..517f750 100644
--- a/configs/am57xx_hs_evm_defconfig
+++ b/configs/am57xx_hs_evm_defconfig
@@ -2,6 +2,7 @@
 CONFIG_ARCH_OMAP2PLUS=y
 CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_OMAP54XX=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_TI_SECURE_DEVICE=y
 CONFIG_TARGET_AM57XX_EVM=y
 CONFIG_TI_SECURE_EMIF_REGION_START=0xbdb00000
@@ -28,36 +29,15 @@
 CONFIG_HUSH_PARSER=y
 CONFIG_FASTBOOT=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
-CONFIG_CMD_FASTBOOT=y
 CONFIG_ANDROID_BOOT_IMAGE=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_FASTBOOT_BUF_SIZE=0x2f000000
 CONFIG_FASTBOOT_USB_DEV=1
 CONFIG_FASTBOOT_FLASH=y
 CONFIG_FASTBOOT_FLASH_MMC_DEV=1
-CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
-CONFIG_CMD_GPT=y
-CONFIG_CMD_MMC=y
-CONFIG_CMD_PART=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
-CONFIG_CMD_DFU=y
-CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_REGULATOR=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_EXT4_WRITE=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
 CONFIG_ISO_PARTITION=y
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
diff --git a/configs/cl-som-am57x_defconfig b/configs/cl-som-am57x_defconfig
index 356266f..ed419a3 100644
--- a/configs/cl-som-am57x_defconfig
+++ b/configs/cl-som-am57x_defconfig
@@ -16,6 +16,7 @@
 CONFIG_CMD_SF=y
 CONFIG_CMD_SPI=y
 CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
 CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_DHCP=y
@@ -48,4 +49,5 @@
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_STORAGE=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/dra7xx_evm_defconfig b/configs/dra7xx_evm_defconfig
index 462e6ff..b50a762 100644
--- a/configs/dra7xx_evm_defconfig
+++ b/configs/dra7xx_evm_defconfig
@@ -2,6 +2,7 @@
 CONFIG_ARCH_OMAP2PLUS=y
 CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_OMAP54XX=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_TARGET_DRA7XX_EVM=y
 # CONFIG_SPL_NAND_SUPPORT is not set
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
@@ -23,36 +24,14 @@
 CONFIG_HUSH_PARSER=y
 CONFIG_FASTBOOT=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
-CONFIG_CMD_FASTBOOT=y
 CONFIG_ANDROID_BOOT_IMAGE=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_FASTBOOT_BUF_SIZE=0x2f000000
 CONFIG_FASTBOOT_FLASH=y
 CONFIG_FASTBOOT_FLASH_MMC_DEV=1
-CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
-CONFIG_CMD_GPT=y
-CONFIG_CMD_MMC=y
-CONFIG_CMD_PART=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
-CONFIG_CMD_DFU=y
-CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_PMIC=y
-CONFIG_CMD_REGULATOR=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_EXT4_WRITE=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
 CONFIG_ISO_PARTITION=y
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
@@ -91,6 +70,7 @@
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_XHCI_DRA7XX_INDEX=1
 CONFIG_USB_DWC3=y
 CONFIG_USB_DWC3_GADGET=y
 CONFIG_USB_DWC3_OMAP=y
diff --git a/configs/dra7xx_hs_evm_defconfig b/configs/dra7xx_hs_evm_defconfig
index a348878..568c3f6 100644
--- a/configs/dra7xx_hs_evm_defconfig
+++ b/configs/dra7xx_hs_evm_defconfig
@@ -2,6 +2,7 @@
 CONFIG_ARCH_OMAP2PLUS=y
 CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_OMAP54XX=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_TI_SECURE_DEVICE=y
 CONFIG_TARGET_DRA7XX_EVM=y
 CONFIG_TI_SECURE_EMIF_REGION_START=0xbdb00000
@@ -28,36 +29,14 @@
 CONFIG_HUSH_PARSER=y
 CONFIG_FASTBOOT=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
-CONFIG_CMD_FASTBOOT=y
 CONFIG_ANDROID_BOOT_IMAGE=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_FASTBOOT_BUF_SIZE=0x2f000000
 CONFIG_FASTBOOT_FLASH=y
 CONFIG_FASTBOOT_FLASH_MMC_DEV=1
-CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
-CONFIG_CMD_GPT=y
-CONFIG_CMD_MMC=y
-CONFIG_CMD_PART=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
-CONFIG_CMD_DFU=y
-CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_PMIC=y
-CONFIG_CMD_REGULATOR=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_EXT4_WRITE=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
 CONFIG_ISO_PARTITION=y
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
@@ -96,6 +75,7 @@
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_XHCI_DRA7XX_INDEX=1
 CONFIG_USB_DWC3=y
 CONFIG_USB_DWC3_GADGET=y
 CONFIG_USB_DWC3_OMAP=y
diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index cc5fea9..08b5f85 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -15,3 +15,9 @@
 CONFIG_SYS_NS16550=y
 CONFIG_SYSRESET=y
 CONFIG_TIMER=y
+CONFIG_WDT=y
+CONFIG_DM_RESET=y
+CONFIG_PINCTRL=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_ASPEED=y
+CONFIG_CMD_I2C=y
diff --git a/configs/k2e_evm_defconfig b/configs/k2e_evm_defconfig
index e862046..83e2138 100644
--- a/configs/k2e_evm_defconfig
+++ b/configs/k2e_evm_defconfig
@@ -4,6 +4,7 @@
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_TARGET_K2E_EVM=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
@@ -18,23 +19,12 @@
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_GPT is not set
+# CONFIG_CMD_MMC is not set
 CONFIG_CMD_NAND=y
-CONFIG_CMD_PART=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
+# CONFIG_CMD_GPIO is not set
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_EXT4_WRITE=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_UBI=y
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
diff --git a/configs/k2e_hs_evm_defconfig b/configs/k2e_hs_evm_defconfig
index 268b56e..d4ec83e 100644
--- a/configs/k2e_hs_evm_defconfig
+++ b/configs/k2e_hs_evm_defconfig
@@ -2,30 +2,20 @@
 CONFIG_ARCH_KEYSTONE=y
 CONFIG_SYS_TEXT_BASE=0x0c000060
 CONFIG_TARGET_K2E_EVM=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
+CONFIG_TI_SECURE_DEVICE=y
 CONFIG_DEFAULT_DEVICE_TREE="keystone-k2e-evm"
 CONFIG_OF_BOARD_SETUP=y
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
 CONFIG_HUSH_PARSER=y
-CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_GPT is not set
+# CONFIG_CMD_MMC is not set
 CONFIG_CMD_NAND=y
-CONFIG_CMD_PART=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
+# CONFIG_CMD_GPIO is not set
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_EXT4_WRITE=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_UBI=y
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
diff --git a/configs/k2g_evm_defconfig b/configs/k2g_evm_defconfig
index 40fc7f0..674ddcc 100644
--- a/configs/k2g_evm_defconfig
+++ b/configs/k2g_evm_defconfig
@@ -4,6 +4,7 @@
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_TARGET_K2G_EVM=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
@@ -16,26 +17,12 @@
 CONFIG_SPL=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_HUSH_PARSER=y
-CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
-CONFIG_CMD_MMC=y
-CONFIG_CMD_PART=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
+# CONFIG_CMD_GPT is not set
 CONFIG_CMD_REMOTEPROC=y
+# CONFIG_CMD_GPIO is not set
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_EXT4_WRITE=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_UBI=y
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
diff --git a/configs/k2g_hs_evm_defconfig b/configs/k2g_hs_evm_defconfig
index d6266df..2e06c8c 100644
--- a/configs/k2g_hs_evm_defconfig
+++ b/configs/k2g_hs_evm_defconfig
@@ -2,31 +2,21 @@
 CONFIG_ARCH_KEYSTONE=y
 CONFIG_SYS_TEXT_BASE=0x0c000060
 CONFIG_TARGET_K2G_EVM=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
+CONFIG_TI_SECURE_DEVICE=y
 CONFIG_DEFAULT_DEVICE_TREE="keystone-k2g-evm"
+CONFIG_FIT=y
+CONFIG_FIT_IMAGE_POST_PROCESS=y
 CONFIG_OF_BOARD_SETUP=y
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
 CONFIG_HUSH_PARSER=y
-CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
-CONFIG_CMD_MMC=y
-CONFIG_CMD_PART=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
+# CONFIG_CMD_GPT is not set
 CONFIG_CMD_REMOTEPROC=y
+# CONFIG_CMD_GPIO is not set
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_EXT4_WRITE=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_UBI=y
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
diff --git a/configs/k2hk_evm_defconfig b/configs/k2hk_evm_defconfig
index 4ec6b6f..7dc5cf5 100644
--- a/configs/k2hk_evm_defconfig
+++ b/configs/k2hk_evm_defconfig
@@ -4,6 +4,7 @@
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_TARGET_K2HK_EVM=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
@@ -16,25 +17,13 @@
 CONFIG_SPL=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_HUSH_PARSER=y
-CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_GPT is not set
+# CONFIG_CMD_MMC is not set
 CONFIG_CMD_NAND=y
-CONFIG_CMD_PART=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
+# CONFIG_CMD_GPIO is not set
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_EXT4_WRITE=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_UBI=y
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
diff --git a/configs/k2hk_hs_evm_defconfig b/configs/k2hk_hs_evm_defconfig
index 500707f..67807e4 100644
--- a/configs/k2hk_hs_evm_defconfig
+++ b/configs/k2hk_hs_evm_defconfig
@@ -2,30 +2,20 @@
 CONFIG_ARCH_KEYSTONE=y
 CONFIG_SYS_TEXT_BASE=0x0c000060
 CONFIG_TARGET_K2HK_EVM=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
+CONFIG_TI_SECURE_DEVICE=y
 CONFIG_DEFAULT_DEVICE_TREE="keystone-k2hk-evm"
 CONFIG_OF_BOARD_SETUP=y
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
 CONFIG_HUSH_PARSER=y
-CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_GPT is not set
+# CONFIG_CMD_MMC is not set
 CONFIG_CMD_NAND=y
-CONFIG_CMD_PART=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
+# CONFIG_CMD_GPIO is not set
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_EXT4_WRITE=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_UBI=y
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
diff --git a/configs/k2l_evm_defconfig b/configs/k2l_evm_defconfig
index 564a179..6be4941 100644
--- a/configs/k2l_evm_defconfig
+++ b/configs/k2l_evm_defconfig
@@ -4,6 +4,7 @@
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_TARGET_K2L_EVM=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
@@ -16,25 +17,13 @@
 CONFIG_SPL=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_HUSH_PARSER=y
-CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_GPT is not set
+# CONFIG_CMD_MMC is not set
 CONFIG_CMD_NAND=y
-CONFIG_CMD_PART=y
-CONFIG_CMD_SF=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_USB=y
+# CONFIG_CMD_GPIO is not set
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_EXT4_WRITE=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_UBI=y
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
diff --git a/configs/nanopi_neo_air_defconfig b/configs/nanopi_neo_air_defconfig
index 9598bd5..5400d37 100644
--- a/configs/nanopi_neo_air_defconfig
+++ b/configs/nanopi_neo_air_defconfig
@@ -15,3 +15,4 @@
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_USB_EHCI_HCD=y
+# CONFIG_VIDEO_DE2 is not set
diff --git a/configs/nanopi_neo_defconfig b/configs/nanopi_neo_defconfig
index 89f5687..5afd5d5 100644
--- a/configs/nanopi_neo_defconfig
+++ b/configs/nanopi_neo_defconfig
@@ -16,3 +16,4 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_SUN8I_EMAC=y
 CONFIG_USB_EHCI_HCD=y
+# CONFIG_VIDEO_DE2 is not set
diff --git a/configs/orangepi_zero_defconfig b/configs/orangepi_zero_defconfig
index ac44937..97ef089 100644
--- a/configs/orangepi_zero_defconfig
+++ b/configs/orangepi_zero_defconfig
@@ -15,3 +15,4 @@
 CONFIG_SPL_SPI_SUNXI=y
 CONFIG_SUN8I_EMAC=y
 CONFIG_USB_EHCI_HCD=y
+# CONFIG_VIDEO_DE2 is not set
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index d3fee89..64bb923 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -180,3 +180,5 @@
 CONFIG_UT_TIME=y
 CONFIG_UT_DM=y
 CONFIG_UT_ENV=y
+CONFIG_WDT=y
+CONFIG_WDT_SANDBOX=y
diff --git a/configs/stm32f746-disco_defconfig b/configs/stm32f746-disco_defconfig
index ea98391..4322aad 100644
--- a/configs/stm32f746-disco_defconfig
+++ b/configs/stm32f746-disco_defconfig
@@ -24,6 +24,7 @@
 CONFIG_CMD_LINK_LOCAL=y
 CONFIG_CMD_TIMER=y
 CONFIG_OF_CONTROL=y
+CONFIG_DM_SEQ_ALIAS=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_NETCONSOLE=y
 CONFIG_CLK=y
@@ -43,3 +44,12 @@
 CONFIG_STM32_QSPI=y
 CONFIG_OF_LIBFDT_OVERLAY=y
 # CONFIG_EFI_LOADER is not set
+CONFIG_CLK=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_FULL is not set
+CONFIG_PINCTRL_STM32=y
+CONFIG_RAM=y
+CONFIG_STM32_SDRAM=y
+CONFIG_DM_GPIO=y
+CONFIG_STM32F7_GPIO=y
+CONFIG_SYS_MALLOC_F_LEN=0xC00
diff --git a/doc/device-tree-bindings/ram/st,stm32-fmc.txt b/doc/device-tree-bindings/ram/st,stm32-fmc.txt
new file mode 100644
index 0000000..3d1392c
--- /dev/null
+++ b/doc/device-tree-bindings/ram/st,stm32-fmc.txt
@@ -0,0 +1,51 @@
+ST, stm32 flexible memory controller Drive
+Required properties:
+- compatible	: "st,stm32-fmc"
+- reg		: fmc controller base address
+- clocks	: fmc controller clock
+u-boot,dm-pre-reloc: flag to initialize memory before relocation.
+
+on-board sdram memory attributes:
+- st,sdram-control : parameters for sdram configuration, in this order:
+  number of columns
+  number of rows
+  memory width
+  number of intenal banks in memory
+  cas latency
+  read burst enable or disable
+  read pipe delay
+
+- st,sdram-timing: timings for sdram, in this order:
+  tmrd
+  txsr
+  tras
+  trc
+  trp
+  trcd
+
+There is device tree include file at :
+include/dt-bindings/memory/stm32-sdram.h to define sdram control and timing
+parameters as MACROS.
+
+Example:
+	fmc: fmc@A0000000 {
+	     compatible = "st,stm32-fmc";
+	     reg = <0xA0000000 0x1000>;
+	     clocks = <&rcc 0 64>;
+	     u-boot,dm-pre-reloc;
+	};
+
+	&fmc {
+		pinctrl-0 = <&fmc_pins>;
+		pinctrl-names = "default";
+		status = "okay";
+
+		mr-nbanks = <1>;
+		/* sdram memory configuration from sdram datasheet */
+	bank1: bank@0 {
+	       st,sdram-control = /bits/ 8 <NO_COL_8 NO_ROW_12 MWIDTH_16 BANKS_2
+						CAS_3 RD_BURST_EN RD_PIPE_DL_0>;
+	       st,sdram-timing = /bits/ 8 <TMRD_1 TXSR_60 TRAS_42 TRC_60 TRP_18
+						TRCD_18>;
+       };
+}
diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
index 26a5e58..ccf47a1 100644
--- a/drivers/clk/aspeed/clk_ast2500.c
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -12,16 +12,39 @@
 #include <dm/lists.h>
 #include <dt-bindings/clock/ast2500-scu.h>
 
+/*
+ * MAC Clock Delay settings, taken from Aspeed SDK
+ */
+#define RGMII_TXCLK_ODLY		8
+#define RMII_RXCLK_IDLY		2
+
+/*
+ * TGMII Clock Duty constants, taken from Aspeed SDK
+ */
+#define RGMII2_TXCK_DUTY	0x66
+#define RGMII1_TXCK_DUTY	0x64
+
+#define D2PLL_DEFAULT_RATE	(250 * 1000 * 1000)
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
+ * Clock divider/multiplier configuration struct.
  * For H-PLL and M-PLL the formula is
  * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1)
  * M - Numerator
  * N - Denumerator
  * P - Post Divider
  * They have the same layout in their control register.
+ *
+ * D-PLL and D2-PLL have extra divider (OD + 1), which is not
+ * yet needed and ignored by clock configurations.
  */
+struct ast2500_div_config {
+	unsigned int num;
+	unsigned int denum;
+	unsigned int post_div;
+};
 
 /*
  * Get the rate of the M-PLL clock from input clock frequency and
@@ -29,11 +52,11 @@
  */
 static ulong ast2500_get_mpll_rate(ulong clkin, u32 mpll_reg)
 {
-	const ulong num = (mpll_reg >> SCU_MPLL_NUM_SHIFT) & SCU_MPLL_NUM_MASK;
-	const ulong denum = (mpll_reg >> SCU_MPLL_DENUM_SHIFT)
-			& SCU_MPLL_DENUM_MASK;
-	const ulong post_div = (mpll_reg >> SCU_MPLL_POST_SHIFT)
-			& SCU_MPLL_POST_MASK;
+	const ulong num = (mpll_reg & SCU_MPLL_NUM_MASK) >> SCU_MPLL_NUM_SHIFT;
+	const ulong denum = (mpll_reg & SCU_MPLL_DENUM_MASK)
+			>> SCU_MPLL_DENUM_SHIFT;
+	const ulong post_div = (mpll_reg & SCU_MPLL_POST_MASK)
+			>> SCU_MPLL_POST_SHIFT;
 
 	return (clkin * ((num + 1) / (denum + 1))) / (post_div + 1);
 }
@@ -44,11 +67,11 @@
  */
 static ulong ast2500_get_hpll_rate(ulong clkin, u32 hpll_reg)
 {
-	const ulong num = (hpll_reg >> SCU_HPLL_NUM_SHIFT) & SCU_HPLL_NUM_MASK;
-	const ulong denum = (hpll_reg >> SCU_HPLL_DENUM_SHIFT)
-			& SCU_HPLL_DENUM_MASK;
-	const ulong post_div = (hpll_reg >> SCU_HPLL_POST_SHIFT)
-			& SCU_HPLL_POST_MASK;
+	const ulong num = (hpll_reg & SCU_HPLL_NUM_MASK) >> SCU_HPLL_NUM_SHIFT;
+	const ulong denum = (hpll_reg & SCU_HPLL_DENUM_MASK)
+			>> SCU_HPLL_DENUM_SHIFT;
+	const ulong post_div = (hpll_reg & SCU_HPLL_POST_MASK)
+			>> SCU_HPLL_POST_SHIFT;
 
 	return (clkin * ((num + 1) / (denum + 1))) / (post_div + 1);
 }
@@ -110,6 +133,17 @@
 		rate = ast2500_get_mpll_rate(clkin,
 					     readl(&priv->scu->m_pll_param));
 		break;
+	case BCLK_PCLK:
+		{
+			ulong apb_div = 4 + 4 * ((readl(&priv->scu->clk_sel1)
+						  & SCU_PCLK_DIV_MASK)
+						 >> SCU_PCLK_DIV_SHIFT);
+			rate = ast2500_get_hpll_rate(clkin,
+						     readl(&priv->
+							   scu->h_pll_param));
+			rate = rate / apb_div;
+		}
+		break;
 	case PCLK_UART1:
 		rate = ast2500_get_uart_clk_rate(priv->scu, 1);
 		break;
@@ -132,44 +166,41 @@
 	return rate;
 }
 
-static void ast2500_scu_unlock(struct ast2500_scu *scu)
-{
-	writel(SCU_UNLOCK_VALUE, &scu->protection_key);
-	while (!readl(&scu->protection_key))
-		;
-}
-
-static void ast2500_scu_lock(struct ast2500_scu *scu)
-{
-	writel(~SCU_UNLOCK_VALUE, &scu->protection_key);
-	while (readl(&scu->protection_key))
-		;
-}
-
-static ulong ast2500_configure_ddr(struct ast2500_scu *scu, ulong rate)
+/*
+ * @input_rate - the rate of input clock in Hz
+ * @requested_rate - desired output rate in Hz
+ * @div - this is an IN/OUT parameter, at input all fields of the config
+ * need to be set to their maximum allowed values.
+ * The result (the best config we could find), would also be returned
+ * in this structure.
+ *
+ * @return The clock rate, when the resulting div_config is used.
+ */
+static ulong ast2500_calc_clock_config(ulong input_rate, ulong requested_rate,
+				       struct ast2500_div_config *cfg)
 {
-	ulong clkin = ast2500_get_clkin(scu);
-	u32 mpll_reg;
-
 	/*
-	 * There are not that many combinations of numerator, denumerator
-	 * and post divider, so just brute force the best combination.
-	 * However, to avoid overflow when multiplying, use kHz.
+	 * The assumption is that kHz precision is good enough and
+	 * also enough to avoid overflow when multiplying.
 	 */
-	const ulong clkin_khz = clkin / 1000;
-	const ulong rate_khz = rate / 1000;
-	ulong best_num = 0;
-	ulong best_denum = 0;
-	ulong best_post = 0;
-	ulong delta = rate;
-	ulong num, denum, post;
+	const ulong input_rate_khz = input_rate / 1000;
+	const ulong rate_khz = requested_rate / 1000;
+	const struct ast2500_div_config max_vals = *cfg;
+	struct ast2500_div_config it = { 0, 0, 0 };
+	ulong delta = rate_khz;
+	ulong new_rate_khz = 0;
 
-	for (denum = 0; denum <= SCU_MPLL_DENUM_MASK; ++denum) {
-		for (post = 0; post <= SCU_MPLL_POST_MASK; ++post) {
-			num = (rate_khz * (post + 1) / clkin_khz) * (denum + 1);
-			ulong new_rate_khz = (clkin_khz
-					      * ((num + 1) / (denum + 1)))
-					     / (post + 1);
+	for (; it.denum <= max_vals.denum; ++it.denum) {
+		for (it.post_div = 0; it.post_div <= max_vals.post_div;
+		     ++it.post_div) {
+			it.num = (rate_khz * (it.post_div + 1) / input_rate_khz)
+			    * (it.denum + 1);
+			if (it.num > max_vals.num)
+				continue;
+
+			new_rate_khz = (input_rate_khz
+					* ((it.num + 1) / (it.denum + 1)))
+			    / (it.post_div + 1);
 
 			/* Keep the rate below requested one. */
 			if (new_rate_khz > rate_khz)
@@ -177,33 +208,172 @@
 
 			if (new_rate_khz - rate_khz < delta) {
 				delta = new_rate_khz - rate_khz;
-
-				best_num = num;
-				best_denum = denum;
-				best_post = post;
-
+				*cfg = it;
 				if (delta == 0)
-					goto rate_calc_done;
+					return new_rate_khz * 1000;
 			}
 		}
 	}
 
+	return new_rate_khz * 1000;
+}
+
- rate_calc_done:
+static ulong ast2500_configure_ddr(struct ast2500_scu *scu, ulong rate)
+{
+	ulong clkin = ast2500_get_clkin(scu);
+	u32 mpll_reg;
+	struct ast2500_div_config div_cfg = {
+		.num = (SCU_MPLL_NUM_MASK >> SCU_MPLL_NUM_SHIFT),
+		.denum = (SCU_MPLL_DENUM_MASK >> SCU_MPLL_DENUM_SHIFT),
+		.post_div = (SCU_MPLL_POST_MASK >> SCU_MPLL_POST_SHIFT),
+	};
+
+	ast2500_calc_clock_config(clkin, rate, &div_cfg);
+
 	mpll_reg = readl(&scu->m_pll_param);
-	mpll_reg &= ~((SCU_MPLL_POST_MASK << SCU_MPLL_POST_SHIFT)
-		      | (SCU_MPLL_NUM_MASK << SCU_MPLL_NUM_SHIFT)
-		      | (SCU_MPLL_DENUM_MASK << SCU_MPLL_DENUM_SHIFT));
-	mpll_reg |= (best_post << SCU_MPLL_POST_SHIFT)
-	    | (best_num << SCU_MPLL_NUM_SHIFT)
-	    | (best_denum << SCU_MPLL_DENUM_SHIFT);
+	mpll_reg &= ~(SCU_MPLL_POST_MASK | SCU_MPLL_NUM_MASK
+		      | SCU_MPLL_DENUM_MASK);
+	mpll_reg |= (div_cfg.post_div << SCU_MPLL_POST_SHIFT)
+	    | (div_cfg.num << SCU_MPLL_NUM_SHIFT)
+	    | (div_cfg.denum << SCU_MPLL_DENUM_SHIFT);
 
-	ast2500_scu_unlock(scu);
+	ast_scu_unlock(scu);
 	writel(mpll_reg, &scu->m_pll_param);
-	ast2500_scu_lock(scu);
+	ast_scu_lock(scu);
 
 	return ast2500_get_mpll_rate(clkin, mpll_reg);
 }
 
+static ulong ast2500_configure_mac(struct ast2500_scu *scu, int index)
+{
+	ulong clkin = ast2500_get_clkin(scu);
+	ulong hpll_rate = ast2500_get_hpll_rate(clkin,
+						readl(&scu->h_pll_param));
+	ulong required_rate;
+	u32 hwstrap;
+	u32 divisor;
+	u32 reset_bit;
+	u32 clkstop_bit;
+
+	/*
+	 * According to data sheet, for 10/100 mode the MAC clock frequency
+	 * should be at least 25MHz and for 1000 mode at least 100MHz
+	 */
+	hwstrap = readl(&scu->hwstrap);
+	if (hwstrap & (SCU_HWSTRAP_MAC1_RGMII | SCU_HWSTRAP_MAC2_RGMII))
+		required_rate = 100 * 1000 * 1000;
+	else
+		required_rate = 25 * 1000 * 1000;
+
+	divisor = hpll_rate / required_rate;
+
+	if (divisor < 4) {
+		/* Clock can't run fast enough, but let's try anyway */
+		debug("MAC clock too slow\n");
+		divisor = 4;
+	} else if (divisor > 16) {
+		/* Can't slow down the clock enough, but let's try anyway */
+		debug("MAC clock too fast\n");
+		divisor = 16;
+	}
+
+	switch (index) {
+	case 1:
+		reset_bit = SCU_SYSRESET_MAC1;
+		clkstop_bit = SCU_CLKSTOP_MAC1;
+		break;
+	case 2:
+		reset_bit = SCU_SYSRESET_MAC2;
+		clkstop_bit = SCU_CLKSTOP_MAC2;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ast_scu_unlock(scu);
+	clrsetbits_le32(&scu->clk_sel1, SCU_MACCLK_MASK,
+			((divisor - 2) / 2) << SCU_MACCLK_SHIFT);
+
+	/*
+	 * Disable MAC, start its clock and re-enable it.
+	 * The procedure and the delays (100us & 10ms) are
+	 * specified in the datasheet.
+	 */
+	setbits_le32(&scu->sysreset_ctrl1, reset_bit);
+	udelay(100);
+	clrbits_le32(&scu->clk_stop_ctrl1, clkstop_bit);
+	mdelay(10);
+	clrbits_le32(&scu->sysreset_ctrl1, reset_bit);
+
+	writel((RGMII2_TXCK_DUTY << SCU_CLKDUTY_RGMII2TXCK_SHIFT)
+	       | (RGMII1_TXCK_DUTY << SCU_CLKDUTY_RGMII1TXCK_SHIFT),
+	       &scu->clk_duty_sel);
+
+	ast_scu_lock(scu);
+
+	return required_rate;
+}
+
+static ulong ast2500_configure_d2pll(struct ast2500_scu *scu, ulong rate)
+{
+	/*
+	 * The values and the meaning of the next three
+	 * parameters are undocumented. Taken from Aspeed SDK.
+	 */
+	const u32 d2_pll_ext_param = 0x2c;
+	const u32 d2_pll_sip = 0x11;
+	const u32 d2_pll_sic = 0x18;
+	u32 clk_delay_settings =
+	    (RMII_RXCLK_IDLY << SCU_MICDS_MAC1RMII_RDLY_SHIFT)
+	    | (RMII_RXCLK_IDLY << SCU_MICDS_MAC2RMII_RDLY_SHIFT)
+	    | (RGMII_TXCLK_ODLY << SCU_MICDS_MAC1RGMII_TXDLY_SHIFT)
+	    | (RGMII_TXCLK_ODLY << SCU_MICDS_MAC2RGMII_TXDLY_SHIFT);
+	struct ast2500_div_config div_cfg = {
+		.num = SCU_D2PLL_NUM_MASK >> SCU_D2PLL_NUM_SHIFT,
+		.denum = SCU_D2PLL_DENUM_MASK >> SCU_D2PLL_DENUM_SHIFT,
+		.post_div = SCU_D2PLL_POST_MASK >> SCU_D2PLL_POST_SHIFT,
+	};
+	ulong clkin = ast2500_get_clkin(scu);
+	ulong new_rate;
+
+	ast_scu_unlock(scu);
+	writel((d2_pll_ext_param << SCU_D2PLL_EXT1_PARAM_SHIFT)
+	       | SCU_D2PLL_EXT1_OFF
+	       | SCU_D2PLL_EXT1_RESET, &scu->d2_pll_ext_param[0]);
+
+	/*
+	 * Select USB2.0 port1 PHY clock as a clock source for GCRT.
+	 * This would disconnect it from D2-PLL.
+	 */
+	clrsetbits_le32(&scu->misc_ctrl1, SCU_MISC_D2PLL_OFF,
+			SCU_MISC_GCRT_USB20CLK);
+
+	new_rate = ast2500_calc_clock_config(clkin, rate, &div_cfg);
+	writel((d2_pll_sip << SCU_D2PLL_SIP_SHIFT)
+	       | (d2_pll_sic << SCU_D2PLL_SIC_SHIFT)
+	       | (div_cfg.num << SCU_D2PLL_NUM_SHIFT)
+	       | (div_cfg.denum << SCU_D2PLL_DENUM_SHIFT)
+	       | (div_cfg.post_div << SCU_D2PLL_POST_SHIFT),
+	       &scu->d2_pll_param);
+
+	clrbits_le32(&scu->d2_pll_ext_param[0],
+		     SCU_D2PLL_EXT1_OFF | SCU_D2PLL_EXT1_RESET);
+
+	clrsetbits_le32(&scu->misc_ctrl2,
+			SCU_MISC2_RGMII_HPLL | SCU_MISC2_RMII_MPLL
+			| SCU_MISC2_RGMII_CLKDIV_MASK |
+			SCU_MISC2_RMII_CLKDIV_MASK,
+			(4 << SCU_MISC2_RMII_CLKDIV_SHIFT));
+
+	writel(clk_delay_settings | SCU_MICDS_RGMIIPLL, &scu->mac_clk_delay);
+	writel(clk_delay_settings, &scu->mac_clk_delay_100M);
+	writel(clk_delay_settings, &scu->mac_clk_delay_10M);
+
+	ast_scu_lock(scu);
+
+	return new_rate;
+}
+
 static ulong ast2500_clk_set_rate(struct clk *clk, ulong rate)
 {
 	struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
@@ -214,6 +384,9 @@
 	case MCLK_DDR:
 		new_rate = ast2500_configure_ddr(priv->scu, rate);
 		break;
+	case PLL_D2PLL:
+		new_rate = ast2500_configure_d2pll(priv->scu, rate);
+		break;
 	default:
 		return -ENOENT;
 	}
@@ -221,9 +394,35 @@
 	return new_rate;
 }
 
+static int ast2500_clk_enable(struct clk *clk)
+{
+	struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
+
+	switch (clk->id) {
+	/*
+	 * For MAC clocks the clock rate is
+	 * configured based on whether RGMII or RMII mode has been selected
+	 * through hardware strapping.
+	 */
+	case PCLK_MAC1:
+		ast2500_configure_mac(priv->scu, 1);
+		break;
+	case PCLK_MAC2:
+		ast2500_configure_mac(priv->scu, 2);
+		break;
+	case PLL_D2PLL:
+		ast2500_configure_d2pll(priv->scu, D2PLL_DEFAULT_RATE);
+	default:
+		return -ENOENT;
+	}
+
+	return 0;
+}
+
 struct clk_ops ast2500_clk_ops = {
 	.get_rate = ast2500_clk_get_rate,
 	.set_rate = ast2500_clk_set_rate,
+	.enable = ast2500_clk_enable,
 };
 
 static int ast2500_clk_probe(struct udevice *dev)
diff --git a/drivers/clk/clk_stm32f7.c b/drivers/clk/clk_stm32f7.c
index 0d86395..da3c204 100644
--- a/drivers/clk/clk_stm32f7.c
+++ b/drivers/clk/clk_stm32f7.c
@@ -228,56 +228,17 @@
 void clock_setup(int peripheral)
 {
 	switch (peripheral) {
-	case GPIO_A_CLOCK_CFG:
-		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_A_EN);
-		break;
-	case GPIO_B_CLOCK_CFG:
-		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_B_EN);
-		break;
-	case GPIO_C_CLOCK_CFG:
-		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_C_EN);
-		break;
-	case GPIO_D_CLOCK_CFG:
-		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_D_EN);
-		break;
-	case GPIO_E_CLOCK_CFG:
-		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_E_EN);
-		break;
-	case GPIO_F_CLOCK_CFG:
-		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_F_EN);
-		break;
-	case GPIO_G_CLOCK_CFG:
-		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_G_EN);
-		break;
-	case GPIO_H_CLOCK_CFG:
-		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_H_EN);
-		break;
-	case GPIO_I_CLOCK_CFG:
-		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_I_EN);
-		break;
-	case GPIO_J_CLOCK_CFG:
-		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_J_EN);
-		break;
-	case GPIO_K_CLOCK_CFG:
-		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_K_EN);
-		break;
 	case SYSCFG_CLOCK_CFG:
 		setbits_le32(&STM32_RCC->apb2enr, RCC_APB2ENR_SYSCFGEN);
 		break;
 	case TIMER2_CLOCK_CFG:
 		setbits_le32(&STM32_RCC->apb1enr, RCC_APB1ENR_TIM2EN);
 		break;
-	case FMC_CLOCK_CFG:
-		setbits_le32(&STM32_RCC->ahb3enr, RCC_AHB3ENR_FMC_EN);
-		break;
 	case STMMAC_CLOCK_CFG:
 		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_ETHMAC_EN);
 		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_ETHMAC_RX_EN);
 		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_ETHMAC_TX_EN);
 		break;
-	case QSPI_CLOCK_CFG:
-		setbits_le32(&STM32_RCC->ahb3enr, RCC_AHB3ENR_QSPI_EN);
-		break;
 	default:
 		break;
 	}
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index c95e9ac..9951611 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -171,6 +171,15 @@
 	help
 	  Say yes here to support Microchip PIC32 GPIOs.
 
+config STM32F7_GPIO
+	bool "ST STM32 GPIO driver"
+	depends on DM_GPIO && STM32
+	default y
+	help
+	  Device model driver support for STM32 GPIO controller. It should be
+	  usable on many stm32 families like stm32f4 & stm32H7.
+	  Tested on STM32F7.
+
 config MVEBU_GPIO
 	bool "Marvell MVEBU GPIO driver"
 	depends on DM_GPIO && ARCH_MVEBU
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 27f8068..0ca845f 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -49,6 +49,7 @@
 obj-$(CONFIG_SUNXI_GPIO)	+= sunxi_gpio.o
 obj-$(CONFIG_LPC32XX_GPIO)	+= lpc32xx_gpio.o
 obj-$(CONFIG_STM32_GPIO)	+= stm32_gpio.o
+obj-$(CONFIG_STM32F7_GPIO)	+= stm32f7_gpio.o
 obj-$(CONFIG_GPIO_UNIPHIER)	+= gpio-uniphier.o
 obj-$(CONFIG_ZYNQ_GPIO)		+= zynq_gpio.o
 obj-$(CONFIG_VYBRID_GPIO)	+= vybrid_gpio.o
diff --git a/drivers/gpio/stm32f7_gpio.c b/drivers/gpio/stm32f7_gpio.c
new file mode 100644
index 0000000..5e05463
--- /dev/null
+++ b/drivers/gpio/stm32f7_gpio.c
@@ -0,0 +1,135 @@
+/*
+ * (C) Copyright 2017
+ * Vikas Manocha, <vikas.manocha@st.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/stm32.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+
+#define MAX_SIZE_BANK_NAME		5
+#define STM32_GPIOS_PER_BANK		16
+#define MODE_BITS(gpio_pin)		(gpio_pin * 2)
+#define MODE_BITS_MASK			3
+#define IN_OUT_BIT_INDEX(gpio_pin)	(1UL << (gpio_pin))
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int stm32_gpio_direction_input(struct udevice *dev, unsigned offset)
+{
+	struct stm32_gpio_priv *priv = dev_get_priv(dev);
+	struct stm32_gpio_regs *regs = priv->regs;
+	int bits_index = MODE_BITS(offset);
+	int mask = MODE_BITS_MASK << bits_index;
+
+	clrsetbits_le32(&regs->moder, mask, STM32_GPIO_MODE_IN << bits_index);
+
+	return 0;
+}
+
+static int stm32_gpio_direction_output(struct udevice *dev, unsigned offset,
+				       int value)
+{
+	struct stm32_gpio_priv *priv = dev_get_priv(dev);
+	struct stm32_gpio_regs *regs = priv->regs;
+	int bits_index = MODE_BITS(offset);
+	int mask = MODE_BITS_MASK << bits_index;
+
+	clrsetbits_le32(&regs->moder, mask, STM32_GPIO_MODE_OUT << bits_index);
+	mask = IN_OUT_BIT_INDEX(offset);
+	clrsetbits_le32(&regs->odr, mask, value ? mask : 0);
+
+	return 0;
+}
+
+static int stm32_gpio_get_value(struct udevice *dev, unsigned offset)
+{
+	struct stm32_gpio_priv *priv = dev_get_priv(dev);
+	struct stm32_gpio_regs *regs = priv->regs;
+
+	return readl(&regs->idr) & IN_OUT_BIT_INDEX(offset) ? 1 : 0;
+}
+
+static int stm32_gpio_set_value(struct udevice *dev, unsigned offset, int value)
+{
+	struct stm32_gpio_priv *priv = dev_get_priv(dev);
+	struct stm32_gpio_regs *regs = priv->regs;
+	int mask = IN_OUT_BIT_INDEX(offset);
+
+	clrsetbits_le32(&regs->odr, mask, value ? mask : 0);
+
+	return 0;
+}
+
+static const struct dm_gpio_ops gpio_stm32_ops = {
+	.direction_input	= stm32_gpio_direction_input,
+	.direction_output	= stm32_gpio_direction_output,
+	.get_value		= stm32_gpio_get_value,
+	.set_value		= stm32_gpio_set_value,
+};
+
+static int gpio_stm32_probe(struct udevice *dev)
+{
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct stm32_gpio_priv *priv = dev_get_priv(dev);
+	fdt_addr_t addr;
+	char *name;
+
+	addr = dev_get_addr(dev);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->regs = (struct stm32_gpio_regs *)addr;
+	name = (char *)fdtdec_locate_byte_array(gd->fdt_blob,
+						dev_of_offset(dev),
+						"st,bank-name",
+						MAX_SIZE_BANK_NAME);
+	if (!name)
+		return -EINVAL;
+	uc_priv->bank_name = name;
+	uc_priv->gpio_count = STM32_GPIOS_PER_BANK;
+	debug("%s, addr = 0x%p, bank_name = %s\n", __func__, (u32 *)priv->regs,
+	      uc_priv->bank_name);
+
+#ifdef CONFIG_CLK
+	struct clk clk;
+	int ret;
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_enable(&clk);
+
+	if (ret) {
+		dev_err(dev, "failed to enable clock\n");
+		return ret;
+	}
+	debug("clock enabled for device %s\n", dev->name);
+#endif
+
+	return 0;
+}
+
+static const struct udevice_id stm32_gpio_ids[] = {
+	{ .compatible = "st,stm32-gpio" },
+	{ }
+};
+
+U_BOOT_DRIVER(gpio_stm32) = {
+	.name	= "gpio_stm32",
+	.id	= UCLASS_GPIO,
+	.of_match = stm32_gpio_ids,
+	.probe	= gpio_stm32_probe,
+	.ops	= &gpio_stm32_ops,
+	.flags	= DM_FLAG_PRE_RELOC | DM_UC_FLAG_SEQ_ALIAS,
+	.priv_auto_alloc_size	= sizeof(struct stm32_gpio_priv),
+};
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 4e9afc1..c58bc1e 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -114,6 +114,15 @@
 	  enable status register. This config option can be enabled in such
 	  cases.
 
+config SYS_I2C_ASPEED
+	bool "Aspeed I2C Controller"
+	depends on DM_I2C && ARCH_ASPEED
+	help
+	  Say yes here to select Aspeed I2C Host Controller. The driver
+	  supports AST2500 and AST2400 controllers, but is very limited.
+	  Only single master mode is supported and only byte-by-byte
+	  synchronous reads and writes are supported, no Pool Buffers or DMA.
+
 config SYS_I2C_INTEL
 	bool "Intel I2C/SMBUS driver"
 	depends on DM_I2C
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 4872c1d..d20fe7b 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -15,6 +15,7 @@
 obj-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
 obj-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o
 obj-$(CONFIG_SYS_I2C) += i2c_core.o
+obj-$(CONFIG_SYS_I2C_ASPEED) += ast_i2c.o
 obj-$(CONFIG_SYS_I2C_AT91) += at91_i2c.o
 obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o
 obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o
diff --git a/drivers/i2c/ast_i2c.c b/drivers/i2c/ast_i2c.c
new file mode 100644
index 0000000..16dfb57
--- /dev/null
+++ b/drivers/i2c/ast_i2c.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ * Copyright 2016 IBM Corporation
+ * Copyright 2017 Google, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <i2c.h>
+#include <asm/io.h>
+#include <asm/arch/scu_ast2500.h>
+
+#include "ast_i2c.h"
+
+#define I2C_TIMEOUT_US 100000
+#define I2C_SLEEP_STEP_US 20
+
+#define HIGHSPEED_TTIMEOUT		3
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Device private data
+ */
+struct ast_i2c_priv {
+	/* This device's clock */
+	struct clk clk;
+	/* Device registers */
+	struct ast_i2c_regs *regs;
+	/* I2C speed in Hz */
+	int speed;
+};
+
+/*
+ * Given desired divider ratio, return the value that needs to be set
+ * in Clock and AC Timing Control register
+ */
+static u32 get_clk_reg_val(ulong divider_ratio)
+{
+	ulong inc = 0, div;
+	ulong scl_low, scl_high, data;
+
+	for (div = 0; divider_ratio >= 16; div++) {
+		inc |= (divider_ratio & 1);
+		divider_ratio >>= 1;
+	}
+	divider_ratio += inc;
+	scl_low = (divider_ratio >> 1) - 1;
+	scl_high = divider_ratio - scl_low - 2;
+	data = I2CD_CACTC_BASE
+			| (scl_high << I2CD_TCKHIGH_SHIFT)
+			| (scl_low << I2CD_TCKLOW_SHIFT)
+			| (div << I2CD_BASE_DIV_SHIFT);
+
+	return data;
+}
+
+static void ast_i2c_clear_interrupts(struct udevice *dev)
+{
+	struct ast_i2c_priv *priv = dev_get_priv(dev);
+
+	writel(~0, &priv->regs->isr);
+}
+
+static void ast_i2c_init_bus(struct udevice *dev)
+{
+	struct ast_i2c_priv *priv = dev_get_priv(dev);
+
+	/* Reset device */
+	writel(0, &priv->regs->fcr);
+	/* Enable Master Mode. Assuming single-master */
+	writel(I2CD_MASTER_EN
+	       | I2CD_M_SDA_LOCK_EN
+	       | I2CD_MULTI_MASTER_DIS | I2CD_M_SCL_DRIVE_EN,
+	       &priv->regs->fcr);
+	/* Enable Interrupts */
+	writel(I2CD_INTR_TX_ACK
+	       | I2CD_INTR_TX_NAK
+	       | I2CD_INTR_RX_DONE
+	       | I2CD_INTR_BUS_RECOVER_DONE
+	       | I2CD_INTR_NORMAL_STOP
+	       | I2CD_INTR_ABNORMAL, &priv->regs->icr);
+}
+
+static int ast_i2c_ofdata_to_platdata(struct udevice *dev)
+{
+	struct ast_i2c_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	priv->regs = dev_get_addr_ptr(dev);
+	if (IS_ERR(priv->regs))
+		return PTR_ERR(priv->regs);
+
+	ret = clk_get_by_index(dev, 0, &priv->clk);
+	if (ret < 0) {
+		debug("%s: Can't get clock for %s: %d\n", __func__, dev->name,
+		      ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ast_i2c_probe(struct udevice *dev)
+{
+	struct ast2500_scu *scu;
+
+	debug("Enabling I2C%u\n", dev->seq);
+
+	/*
+	 * Get all I2C devices out of Reset.
+	 * Only needs to be done once, but doing it for every
+	 * device does not hurt.
+	 */
+	scu = ast_get_scu();
+	ast_scu_unlock(scu);
+	clrbits_le32(&scu->sysreset_ctrl1, SCU_SYSRESET_I2C);
+	ast_scu_lock(scu);
+
+	ast_i2c_init_bus(dev);
+
+	return 0;
+}
+
+static int ast_i2c_wait_isr(struct udevice *dev, u32 flag)
+{
+	struct ast_i2c_priv *priv = dev_get_priv(dev);
+	int timeout = I2C_TIMEOUT_US;
+
+	while (!(readl(&priv->regs->isr) & flag) && timeout > 0) {
+		udelay(I2C_SLEEP_STEP_US);
+		timeout -= I2C_SLEEP_STEP_US;
+	}
+
+	ast_i2c_clear_interrupts(dev);
+	if (timeout <= 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static int ast_i2c_send_stop(struct udevice *dev)
+{
+	struct ast_i2c_priv *priv = dev_get_priv(dev);
+
+	writel(I2CD_M_STOP_CMD, &priv->regs->csr);
+
+	return ast_i2c_wait_isr(dev, I2CD_INTR_NORMAL_STOP);
+}
+
+static int ast_i2c_wait_tx(struct udevice *dev)
+{
+	struct ast_i2c_priv *priv = dev_get_priv(dev);
+	int timeout = I2C_TIMEOUT_US;
+	u32 flag = I2CD_INTR_TX_ACK | I2CD_INTR_TX_NAK;
+	u32 status = readl(&priv->regs->isr) & flag;
+	int ret = 0;
+
+	while (!status && timeout > 0) {
+		status = readl(&priv->regs->isr) & flag;
+		udelay(I2C_SLEEP_STEP_US);
+		timeout -= I2C_SLEEP_STEP_US;
+	}
+
+	if (status == I2CD_INTR_TX_NAK)
+		ret = -EREMOTEIO;
+
+	if (timeout <= 0)
+		ret = -ETIMEDOUT;
+
+	ast_i2c_clear_interrupts(dev);
+
+	return ret;
+}
+
+static int ast_i2c_start_txn(struct udevice *dev, uint devaddr)
+{
+	struct ast_i2c_priv *priv = dev_get_priv(dev);
+
+	/* Start and Send Device Address */
+	writel(devaddr, &priv->regs->trbbr);
+	writel(I2CD_M_START_CMD | I2CD_M_TX_CMD, &priv->regs->csr);
+
+	return ast_i2c_wait_tx(dev);
+}
+
+static int ast_i2c_read_data(struct udevice *dev, u8 chip_addr, u8 *buffer,
+			     size_t len, bool send_stop)
+{
+	struct ast_i2c_priv *priv = dev_get_priv(dev);
+	u32 i2c_cmd = I2CD_M_RX_CMD;
+	int ret;
+
+	ret = ast_i2c_start_txn(dev, (chip_addr << 1) | I2C_M_RD);
+	if (ret < 0)
+		return ret;
+
+	for (; len > 0; len--, buffer++) {
+		if (len == 1)
+			i2c_cmd |= I2CD_M_S_RX_CMD_LAST;
+		writel(i2c_cmd, &priv->regs->csr);
+		ret = ast_i2c_wait_isr(dev, I2CD_INTR_RX_DONE);
+		if (ret < 0)
+			return ret;
+		*buffer = (readl(&priv->regs->trbbr) & I2CD_RX_DATA_MASK)
+				>> I2CD_RX_DATA_SHIFT;
+	}
+	ast_i2c_clear_interrupts(dev);
+
+	if (send_stop)
+		return ast_i2c_send_stop(dev);
+
+	return 0;
+}
+
+static int ast_i2c_write_data(struct udevice *dev, u8 chip_addr, u8
+			      *buffer, size_t len, bool send_stop)
+{
+	struct ast_i2c_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = ast_i2c_start_txn(dev, (chip_addr << 1));
+	if (ret < 0)
+		return ret;
+
+	for (; len > 0; len--, buffer++) {
+		writel(*buffer, &priv->regs->trbbr);
+		writel(I2CD_M_TX_CMD, &priv->regs->csr);
+		ret = ast_i2c_wait_tx(dev);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (send_stop)
+		return ast_i2c_send_stop(dev);
+
+	return 0;
+}
+
+static int ast_i2c_deblock(struct udevice *dev)
+{
+	struct ast_i2c_priv *priv = dev_get_priv(dev);
+	struct ast_i2c_regs *regs = priv->regs;
+	u32 csr = readl(&regs->csr);
+	bool sda_high = csr & I2CD_SDA_LINE_STS;
+	bool scl_high = csr & I2CD_SCL_LINE_STS;
+	int ret = 0;
+
+	if (sda_high && scl_high) {
+		/* Bus is idle, no deblocking needed. */
+		return 0;
+	} else if (sda_high) {
+		/* Send stop command */
+		debug("Unterminated TXN in (%x), sending stop\n", csr);
+		ret = ast_i2c_send_stop(dev);
+	} else if (scl_high) {
+		/* Possibly stuck slave */
+		debug("Bus stuck (%x), attempting recovery\n", csr);
+		writel(I2CD_BUS_RECOVER_CMD, &regs->csr);
+		ret = ast_i2c_wait_isr(dev, I2CD_INTR_BUS_RECOVER_DONE);
+	} else {
+		/* Just try to reinit the device. */
+		ast_i2c_init_bus(dev);
+	}
+
+	return ret;
+}
+
+static int ast_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs)
+{
+	int ret;
+
+	ret = ast_i2c_deblock(dev);
+	if (ret < 0)
+		return ret;
+
+	debug("i2c_xfer: %d messages\n", nmsgs);
+	for (; nmsgs > 0; nmsgs--, msg++) {
+		if (msg->flags & I2C_M_RD) {
+			debug("i2c_read: chip=0x%x, len=0x%x, flags=0x%x\n",
+			      msg->addr, msg->len, msg->flags);
+			ret = ast_i2c_read_data(dev, msg->addr, msg->buf,
+						msg->len, (nmsgs == 1));
+		} else {
+			debug("i2c_write: chip=0x%x, len=0x%x, flags=0x%x\n",
+			      msg->addr, msg->len, msg->flags);
+			ret = ast_i2c_write_data(dev, msg->addr, msg->buf,
+						 msg->len, (nmsgs == 1));
+		}
+		if (ret) {
+			debug("%s: error (%d)\n", __func__, ret);
+			return -EREMOTEIO;
+		}
+	}
+
+	return 0;
+}
+
+static int ast_i2c_set_speed(struct udevice *dev, unsigned int speed)
+{
+	struct ast_i2c_priv *priv = dev_get_priv(dev);
+	struct ast_i2c_regs *regs = priv->regs;
+	ulong i2c_rate, divider;
+
+	debug("Setting speed for I2C%d to <%u>\n", dev->seq, speed);
+	if (!speed) {
+		debug("No valid speed specified\n");
+		return -EINVAL;
+	}
+
+	i2c_rate = clk_get_rate(&priv->clk);
+	divider = i2c_rate / speed;
+
+	priv->speed = speed;
+	if (speed > I2C_HIGHSPEED_RATE) {
+		debug("Enable High Speed\n");
+		setbits_le32(&regs->fcr, I2CD_M_HIGH_SPEED_EN
+			     | I2CD_M_SDA_DRIVE_1T_EN
+			     | I2CD_SDA_DRIVE_1T_EN);
+		writel(HIGHSPEED_TTIMEOUT, &regs->cactcr2);
+	} else {
+		debug("Enabling Normal Speed\n");
+		writel(I2CD_NO_TIMEOUT_CTRL, &regs->cactcr2);
+	}
+
+	writel(get_clk_reg_val(divider), &regs->cactcr1);
+	ast_i2c_clear_interrupts(dev);
+
+	return 0;
+}
+
+static const struct dm_i2c_ops ast_i2c_ops = {
+	.xfer = ast_i2c_xfer,
+	.set_bus_speed = ast_i2c_set_speed,
+	.deblock = ast_i2c_deblock,
+};
+
+static const struct udevice_id ast_i2c_ids[] = {
+	{ .compatible = "aspeed,ast2400-i2c-bus" },
+	{ .compatible = "aspeed,ast2500-i2c-bus" },
+	{ },
+};
+
+U_BOOT_DRIVER(ast_i2c) = {
+	.name = "ast_i2c",
+	.id = UCLASS_I2C,
+	.of_match = ast_i2c_ids,
+	.probe = ast_i2c_probe,
+	.ofdata_to_platdata = ast_i2c_ofdata_to_platdata,
+	.priv_auto_alloc_size = sizeof(struct ast_i2c_priv),
+	.ops = &ast_i2c_ops,
+};
diff --git a/drivers/i2c/ast_i2c.h b/drivers/i2c/ast_i2c.h
new file mode 100644
index 0000000..e5dec7a
--- /dev/null
+++ b/drivers/i2c/ast_i2c.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ * Copyright 2016 IBM Corporation
+ * Copyright 2017 Google, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef __AST_I2C_H_
+#define __AST_I2C_H_
+
+struct ast_i2c_regs {
+	u32 fcr;
+	u32 cactcr1;
+	u32 cactcr2;
+	u32 icr;
+	u32 isr;
+	u32 csr;
+	u32 sdar;
+	u32 pbcr;
+	u32 trbbr;
+#ifdef CONFIG_ASPEED_AST2500
+	u32 dma_mbar;
+	u32 dma_tlr;
+#endif
+};
+
+/* Device Register Definition */
+/* 0x00 : I2CD Function Control Register  */
+#define I2CD_BUFF_SEL_MASK				(0x7 << 20)
+#define I2CD_BUFF_SEL(x)				(x << 20)
+#define I2CD_M_SDA_LOCK_EN			(0x1 << 16)
+#define I2CD_MULTI_MASTER_DIS			(0x1 << 15)
+#define I2CD_M_SCL_DRIVE_EN		(0x1 << 14)
+#define I2CD_MSB_STS					(0x1 << 9)
+#define I2CD_SDA_DRIVE_1T_EN			(0x1 << 8)
+#define I2CD_M_SDA_DRIVE_1T_EN		(0x1 << 7)
+#define I2CD_M_HIGH_SPEED_EN		(0x1 << 6)
+#define I2CD_DEF_ADDR_EN				(0x1 << 5)
+#define I2CD_DEF_ALERT_EN				(0x1 << 4)
+#define I2CD_DEF_ARP_EN					(0x1 << 3)
+#define I2CD_DEF_GCALL_EN				(0x1 << 2)
+#define I2CD_SLAVE_EN					(0x1 << 1)
+#define I2CD_MASTER_EN					(0x1)
+
+/* 0x04 : I2CD Clock and AC Timing Control Register #1 */
+/* Base register value. These bits are always set by the driver. */
+#define I2CD_CACTC_BASE			0xfff00300
+#define I2CD_TCKHIGH_SHIFT			16
+#define I2CD_TCKLOW_SHIFT			12
+#define I2CD_THDDAT_SHIFT			10
+#define I2CD_TO_DIV_SHIFT			8
+#define I2CD_BASE_DIV_SHIFT			0
+
+/* 0x08 : I2CD Clock and AC Timing Control Register #2 */
+#define I2CD_tTIMEOUT					1
+#define I2CD_NO_TIMEOUT_CTRL			0
+
+/* 0x0c : I2CD Interrupt Control Register &
+ * 0x10 : I2CD Interrupt Status Register
+ *
+ * These share bit definitions, so use the same values for the enable &
+ * status bits.
+ */
+#define I2CD_INTR_SDA_DL_TIMEOUT			(0x1 << 14)
+#define I2CD_INTR_BUS_RECOVER_DONE			(0x1 << 13)
+#define I2CD_INTR_SMBUS_ALERT			(0x1 << 12)
+#define I2CD_INTR_SMBUS_ARP_ADDR			(0x1 << 11)
+#define I2CD_INTR_SMBUS_DEV_ALERT_ADDR		(0x1 << 10)
+#define I2CD_INTR_SMBUS_DEF_ADDR			(0x1 << 9)
+#define I2CD_INTR_GCALL_ADDR			(0x1 << 8)
+#define I2CD_INTR_SLAVE_MATCH			(0x1 << 7)
+#define I2CD_INTR_SCL_TIMEOUT			(0x1 << 6)
+#define I2CD_INTR_ABNORMAL				(0x1 << 5)
+#define I2CD_INTR_NORMAL_STOP			(0x1 << 4)
+#define I2CD_INTR_ARBIT_LOSS			(0x1 << 3)
+#define I2CD_INTR_RX_DONE				(0x1 << 2)
+#define I2CD_INTR_TX_NAK				(0x1 << 1)
+#define I2CD_INTR_TX_ACK				(0x1 << 0)
+
+/* 0x14 : I2CD Command/Status Register   */
+#define I2CD_SDA_OE					(0x1 << 28)
+#define I2CD_SDA_O					(0x1 << 27)
+#define I2CD_SCL_OE					(0x1 << 26)
+#define I2CD_SCL_O					(0x1 << 25)
+#define I2CD_TX_TIMING				(0x1 << 24)
+#define I2CD_TX_STATUS				(0x1 << 23)
+
+/* Tx State Machine */
+#define I2CD_IDLE					0x0
+#define I2CD_MACTIVE				0x8
+#define I2CD_MSTART					0x9
+#define I2CD_MSTARTR				0xa
+#define I2CD_MSTOP					0xb
+#define I2CD_MTXD					0xc
+#define I2CD_MRXACK					0xd
+#define I2CD_MRXD					0xe
+#define I2CD_MTXACK				0xf
+#define I2CD_SWAIT					0x1
+#define I2CD_SRXD					0x4
+#define I2CD_STXACK				0x5
+#define I2CD_STXD					0x6
+#define I2CD_SRXACK				0x7
+#define I2CD_RECOVER				0x3
+
+#define I2CD_SCL_LINE_STS				(0x1 << 18)
+#define I2CD_SDA_LINE_STS				(0x1 << 17)
+#define I2CD_BUS_BUSY_STS				(0x1 << 16)
+#define I2CD_SDA_OE_OUT_DIR				(0x1 << 15)
+#define I2CD_SDA_O_OUT_DIR				(0x1 << 14)
+#define I2CD_SCL_OE_OUT_DIR				(0x1 << 13)
+#define I2CD_SCL_O_OUT_DIR				(0x1 << 12)
+#define I2CD_BUS_RECOVER_CMD			(0x1 << 11)
+#define I2CD_S_ALT_EN				(0x1 << 10)
+#define I2CD_RX_DMA_ENABLE				(0x1 << 9)
+#define I2CD_TX_DMA_ENABLE				(0x1 << 8)
+
+/* Command Bit */
+#define I2CD_RX_BUFF_ENABLE				(0x1 << 7)
+#define I2CD_TX_BUFF_ENABLE				(0x1 << 6)
+#define I2CD_M_STOP_CMD					(0x1 << 5)
+#define I2CD_M_S_RX_CMD_LAST			(0x1 << 4)
+#define I2CD_M_RX_CMD					(0x1 << 3)
+#define I2CD_S_TX_CMD					(0x1 << 2)
+#define I2CD_M_TX_CMD					(0x1 << 1)
+#define I2CD_M_START_CMD				0x1
+
+#define I2CD_RX_DATA_SHIFT			8
+#define I2CD_RX_DATA_MASK			(0xff << I2CD_RX_DATA_SHIFT)
+
+#define I2C_HIGHSPEED_RATE    400000
+
+#endif				/* __AST_I2C_H_ */
diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
index 648a96e..3703519 100644
--- a/drivers/i2c/mvtwsi.c
+++ b/drivers/i2c/mvtwsi.c
@@ -37,6 +37,14 @@
 #endif /* CONFIG_DM_I2C */
 
 /*
+ * On SUNXI, we get CONFIG_SYS_TCLK from this include, so we want to
+ * always have it.
+ */
+#if defined(CONFIG_DM_I2C) && defined(CONFIG_ARCH_SUNXI)
+#include <asm/arch/i2c.h>
+#endif
+
+/*
  * TWSI register structure
  */
 
@@ -831,6 +839,7 @@
 static const struct udevice_id mvtwsi_i2c_ids[] = {
 	{ .compatible = "marvell,mv64xxx-i2c", },
 	{ .compatible = "marvell,mv78230-i2c", },
+	{ .compatible = "allwinner,sun6i-a31-i2c", },
 	{ /* sentinel */ }
 };
 
diff --git a/drivers/mtd/nand/am335x_spl_bch.c b/drivers/mtd/nand/am335x_spl_bch.c
index 5b189a1..e68b4a5 100644
--- a/drivers/mtd/nand/am335x_spl_bch.c
+++ b/drivers/mtd/nand/am335x_spl_bch.c
@@ -198,53 +198,6 @@
 	return 0;
 }
 
-int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
-{
-	unsigned int block, lastblock;
-	unsigned int page, page_offset;
-
-	/*
-	 * offs has to be aligned to a page address!
-	 */
-	block = offs / CONFIG_SYS_NAND_BLOCK_SIZE;
-	lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE;
-	page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE;
-	page_offset = offs % CONFIG_SYS_NAND_PAGE_SIZE;
-
-	while (block <= lastblock) {
-		if (!nand_is_bad_block(block)) {
-			/*
-			 * Skip bad blocks
-			 */
-			while (page < CONFIG_SYS_NAND_PAGE_COUNT) {
-				nand_read_page(block, page, dst);
-				/*
-				 * When offs is not aligned to page address the
-				 * extra offset is copied to dst as well. Copy
-				 * the image such that its first byte will be
-				 * at the dst.
-				 */
-				if (unlikely(page_offset)) {
-					memmove(dst, dst + page_offset,
-						CONFIG_SYS_NAND_PAGE_SIZE);
-					dst = (void *)((int)dst - page_offset);
-					page_offset = 0;
-				}
-				dst += CONFIG_SYS_NAND_PAGE_SIZE;
-				page++;
-			}
-
-			page = 0;
-		} else {
-			lastblock++;
-		}
-
-		block++;
-	}
-
-	return 0;
-}
-
 /* nand_init() - initialize data to make nand usable by SPL */
 void nand_init(void)
 {
@@ -269,3 +222,5 @@
 	if (nand_chip.select_chip)
 		nand_chip.select_chip(mtd, -1);
 }
+
+#include "nand_spl_loaders.c"
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 21d5d0e..7c10bfed 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -1380,34 +1380,6 @@
 }
 #endif /* CONFIG_SPL_NAND_ECC */
 
-int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
-{
-	unsigned int block, lastblock;
-	unsigned int page;
-
-	block = offs / CONFIG_SYS_NAND_BLOCK_SIZE;
-	lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE;
-	page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE;
-
-	while (block <= lastblock) {
-		if (!nand_is_bad_block(block)) {
-			while (page < CONFIG_SYS_NAND_PAGE_COUNT) {
-				nand_read_page(block, page, dst);
-				dst += CONFIG_SYS_NAND_PAGE_SIZE;
-				page++;
-			}
-
-			page = 0;
-		} else {
-			lastblock++;
-		}
-
-		block++;
-	}
-
-	return 0;
-}
-
 int at91_nand_wait_ready(struct mtd_info *mtd)
 {
 	struct nand_chip *this = mtd_to_nand(mtd);
@@ -1474,6 +1446,8 @@
 		nand_chip.select_chip(mtd, -1);
 }
 
+#include "nand_spl_loaders.c"
+
 #else
 
 #ifndef CONFIG_SYS_NAND_BASE_LIST
diff --git a/drivers/mtd/nand/nand_spl_loaders.c b/drivers/mtd/nand/nand_spl_loaders.c
new file mode 100644
index 0000000..177c12b
--- /dev/null
+++ b/drivers/mtd/nand/nand_spl_loaders.c
@@ -0,0 +1,104 @@
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
+{
+	unsigned int block, lastblock;
+	unsigned int page, page_offset;
+
+	/* offs has to be aligned to a page address! */
+	block = offs / CONFIG_SYS_NAND_BLOCK_SIZE;
+	lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE;
+	page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE;
+	page_offset = offs % CONFIG_SYS_NAND_PAGE_SIZE;
+
+	while (block <= lastblock) {
+		if (!nand_is_bad_block(block)) {
+			/* Skip bad blocks */
+			while (page < CONFIG_SYS_NAND_PAGE_COUNT) {
+				nand_read_page(block, page, dst);
+				/*
+				 * When offs is not aligned to page address the
+				 * extra offset is copied to dst as well. Copy
+				 * the image such that its first byte will be
+				 * at the dst.
+				 */
+				if (unlikely(page_offset)) {
+					memmove(dst, dst + page_offset,
+						CONFIG_SYS_NAND_PAGE_SIZE);
+					dst = (void *)((int)dst - page_offset);
+					page_offset = 0;
+				}
+				dst += CONFIG_SYS_NAND_PAGE_SIZE;
+				page++;
+			}
+
+			page = 0;
+		} else {
+			lastblock++;
+		}
+
+		block++;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_SPL_UBI
+/*
+ * Temporary storage for non NAND page aligned and non NAND page sized
+ * reads. Note: This does not support runtime detected FLASH yet, but
+ * that should be reasonably easy to fix by making the buffer large
+ * enough :)
+ */
+static u8 scratch_buf[CONFIG_SYS_NAND_PAGE_SIZE];
+
+/**
+ * nand_spl_read_block - Read data from physical eraseblock into a buffer
+ * @block:	Number of the physical eraseblock
+ * @offset:	Data offset from the start of @peb
+ * @len:	Data size to read
+ * @dst:	Address of the destination buffer
+ *
+ * This could be further optimized if we'd have a subpage read
+ * function in the simple code. On NAND which allows subpage reads
+ * this would spare quite some time to readout e.g. the VID header of
+ * UBI.
+ *
+ * Notes:
+ *	@offset + @len are not allowed to be larger than a physical
+ *	erase block. No sanity check done for simplicity reasons.
+ *
+ * To support runtime detected flash this needs to be extended by
+ * information about the actual flash geometry, but thats beyond the
+ * scope of this effort and for most applications where fast boot is
+ * required it is not an issue anyway.
+ */
+int nand_spl_read_block(int block, int offset, int len, void *dst)
+{
+	int page, read;
+
+	/* Calculate the page number */
+	page = offset / CONFIG_SYS_NAND_PAGE_SIZE;
+
+	/* Offset to the start of a flash page */
+	offset = offset % CONFIG_SYS_NAND_PAGE_SIZE;
+
+	while (len) {
+		/*
+		 * Non page aligned reads go to the scratch buffer.
+		 * Page aligned reads go directly to the destination.
+		 */
+		if (offset || len < CONFIG_SYS_NAND_PAGE_SIZE) {
+			nand_read_page(block, page, scratch_buf);
+			read = min(len, CONFIG_SYS_NAND_PAGE_SIZE - offset);
+			memcpy(dst, scratch_buf + offset, read);
+			offset = 0;
+		} else {
+			nand_read_page(block, page, dst);
+			read = CONFIG_SYS_NAND_PAGE_SIZE;
+		}
+		page++;
+		len -= read;
+		dst += read;
+	}
+	return 0;
+}
+#endif
diff --git a/drivers/mtd/nand/nand_spl_simple.c b/drivers/mtd/nand/nand_spl_simple.c
index 55f48d3..56e86d1 100644
--- a/drivers/mtd/nand/nand_spl_simple.c
+++ b/drivers/mtd/nand/nand_spl_simple.c
@@ -209,102 +209,6 @@
 }
 #endif
 
-#ifdef CONFIG_SPL_UBI
-/*
- * Temporary storage for non NAND page aligned and non NAND page sized
- * reads. Note: This does not support runtime detected FLASH yet, but
- * that should be reasonably easy to fix by making the buffer large
- * enough :)
- */
-static u8 scratch_buf[CONFIG_SYS_NAND_PAGE_SIZE];
-
-/**
- * nand_spl_read_block - Read data from physical eraseblock into a buffer
- * @block:	Number of the physical eraseblock
- * @offset:	Data offset from the start of @peb
- * @len:	Data size to read
- * @dst:	Address of the destination buffer
- *
- * This could be further optimized if we'd have a subpage read
- * function in the simple code. On NAND which allows subpage reads
- * this would spare quite some time to readout e.g. the VID header of
- * UBI.
- *
- * Notes:
- *	@offset + @len are not allowed to be larger than a physical
- *	erase block. No sanity check done for simplicity reasons.
- *
- * To support runtime detected flash this needs to be extended by
- * information about the actual flash geometry, but thats beyond the
- * scope of this effort and for most applications where fast boot is
- * required it is not an issue anyway.
- */
-int nand_spl_read_block(int block, int offset, int len, void *dst)
-{
-	int page, read;
-
-	/* Calculate the page number */
-	page = offset / CONFIG_SYS_NAND_PAGE_SIZE;
-
-	/* Offset to the start of a flash page */
-	offset = offset % CONFIG_SYS_NAND_PAGE_SIZE;
-
-	while (len) {
-		/*
-		 * Non page aligned reads go to the scratch buffer.
-		 * Page aligned reads go directly to the destination.
-		 */
-		if (offset || len < CONFIG_SYS_NAND_PAGE_SIZE) {
-			nand_read_page(block, page, scratch_buf);
-			read = min(len, CONFIG_SYS_NAND_PAGE_SIZE - offset);
-			memcpy(dst, scratch_buf + offset, read);
-			offset = 0;
-		} else {
-			nand_read_page(block, page, dst);
-			read = CONFIG_SYS_NAND_PAGE_SIZE;
-		}
-		page++;
-		len -= read;
-		dst += read;
-	}
-	return 0;
-}
-#endif
-
-int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
-{
-	unsigned int block, lastblock;
-	unsigned int page;
-
-	/*
-	 * offs has to be aligned to a page address!
-	 */
-	block = offs / CONFIG_SYS_NAND_BLOCK_SIZE;
-	lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE;
-	page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE;
-
-	while (block <= lastblock) {
-		if (!nand_is_bad_block(block)) {
-			/*
-			 * Skip bad blocks
-			 */
-			while (page < CONFIG_SYS_NAND_PAGE_COUNT) {
-				nand_read_page(block, page, dst);
-				dst += CONFIG_SYS_NAND_PAGE_SIZE;
-				page++;
-			}
-
-			page = 0;
-		} else {
-			lastblock++;
-		}
-
-		block++;
-	}
-
-	return 0;
-}
-
 /* nand_init() - initialize data to make nand usable by SPL */
 void nand_init(void)
 {
@@ -333,3 +237,5 @@
 	if (nand_chip.select_chip)
 		nand_chip.select_chip(mtd, -1);
 }
+
+#include "nand_spl_loaders.c"
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 9cea6f2..f6616c5 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -248,6 +248,15 @@
 	  the GPIO definitions and pin control functions for each available
 	  multiplex function.
 
+config ASPEED_AST2500_PINCTRL
+  bool "Aspeed AST2500 pin control driver"
+  depends on DM && PINCTRL_GENERIC && ASPEED_AST2500
+  default y
+  help
+    Support pin multiplexing control on Aspeed ast2500 SoC. The driver uses
+	Generic Pinctrl framework and is compatible with the Linux driver,
+	i.e. it uses the same device tree configuration.
+
 endif
 
 source "drivers/pinctrl/meson/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 17a7173..1e5c425 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -8,6 +8,7 @@
 obj-$(CONFIG_PINCTRL_AT91)		+= pinctrl-at91.o
 obj-$(CONFIG_PINCTRL_AT91PIO4)		+= pinctrl-at91-pio4.o
 obj-y					+= nxp/
+obj-$(CONFIG_ARCH_ASPEED) += aspeed/
 obj-$(CONFIG_ARCH_ATH79) += ath79/
 obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
 obj-$(CONFIG_PINCTRL_SANDBOX)	+= pinctrl-sandbox.o
diff --git a/drivers/pinctrl/aspeed/Makefile b/drivers/pinctrl/aspeed/Makefile
new file mode 100644
index 0000000..2e6ed60
--- /dev/null
+++ b/drivers/pinctrl/aspeed/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ASPEED_AST2500_PINCTRL) += pinctrl_ast2500.o
diff --git a/drivers/pinctrl/aspeed/pinctrl_ast2500.c b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
new file mode 100644
index 0000000..01f97c1
--- /dev/null
+++ b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/arch/pinctrl.h>
+#include <asm/arch/scu_ast2500.h>
+#include <dm/pinctrl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * This driver works with very simple configuration that has the same name
+ * for group and function. This way it is compatible with the Linux Kernel
+ * driver.
+ */
+
+struct ast2500_pinctrl_priv {
+	struct ast2500_scu *scu;
+};
+
+static int ast2500_pinctrl_probe(struct udevice *dev)
+{
+	struct ast2500_pinctrl_priv *priv = dev_get_priv(dev);
+
+	priv->scu = ast_get_scu();
+
+	return 0;
+}
+
+struct ast2500_group_config {
+	char *group_name;
+	/* Control register number (1-10) */
+	unsigned reg_num;
+	/* The mask of control bits in the register */
+	u32 ctrl_bit_mask;
+};
+
+static const struct ast2500_group_config ast2500_groups[] = {
+	{ "I2C1", 8, (1 << 13) | (1 << 12) },
+	{ "I2C2", 8, (1 << 15) | (1 << 14) },
+	{ "I2C3", 8, (1 << 16) },
+	{ "I2C4", 5, (1 << 17) },
+	{ "I2C4", 5, (1 << 17) },
+	{ "I2C5", 5, (1 << 18) },
+	{ "I2C6", 5, (1 << 19) },
+	{ "I2C7", 5, (1 << 20) },
+	{ "I2C8", 5, (1 << 21) },
+	{ "I2C9", 5, (1 << 22) },
+	{ "I2C10", 5, (1 << 23) },
+	{ "I2C11", 5, (1 << 24) },
+	{ "I2C12", 5, (1 << 25) },
+	{ "I2C13", 5, (1 << 26) },
+	{ "I2C14", 5, (1 << 27) },
+	{ "MAC1LINK", 1, (1 << 0) },
+	{ "MDIO1", 3, (1 << 31) | (1 << 30) },
+	{ "MAC2LINK", 1, (1 << 1) },
+	{ "MDIO2", 5, (1 << 2) },
+};
+
+static int ast2500_pinctrl_get_groups_count(struct udevice *dev)
+{
+	debug("PINCTRL: get_(functions/groups)_count\n");
+
+	return ARRAY_SIZE(ast2500_groups);
+}
+
+static const char *ast2500_pinctrl_get_group_name(struct udevice *dev,
+						  unsigned selector)
+{
+	debug("PINCTRL: get_(function/group)_name %u\n", selector);
+
+	return ast2500_groups[selector].group_name;
+}
+
+static int ast2500_pinctrl_group_set(struct udevice *dev, unsigned selector,
+				     unsigned func_selector)
+{
+	struct ast2500_pinctrl_priv *priv = dev_get_priv(dev);
+	const struct ast2500_group_config *config;
+	u32 *ctrl_reg;
+
+	debug("PINCTRL: group_set <%u, %u>\n", selector, func_selector);
+	if (selector >= ARRAY_SIZE(ast2500_groups))
+		return -EINVAL;
+
+	config = &ast2500_groups[selector];
+	if (config->reg_num > 6)
+		ctrl_reg = &priv->scu->pinmux_ctrl1[config->reg_num - 7];
+	else
+		ctrl_reg = &priv->scu->pinmux_ctrl[config->reg_num - 1];
+
+	ast_scu_unlock(priv->scu);
+	setbits_le32(ctrl_reg, config->ctrl_bit_mask);
+	ast_scu_lock(priv->scu);
+
+	return 0;
+}
+
+static struct pinctrl_ops ast2500_pinctrl_ops = {
+	.set_state = pinctrl_generic_set_state,
+	.get_groups_count = ast2500_pinctrl_get_groups_count,
+	.get_group_name = ast2500_pinctrl_get_group_name,
+	.get_functions_count = ast2500_pinctrl_get_groups_count,
+	.get_function_name = ast2500_pinctrl_get_group_name,
+	.pinmux_group_set = ast2500_pinctrl_group_set,
+};
+
+static const struct udevice_id ast2500_pinctrl_ids[] = {
+	{ .compatible = "aspeed,ast2500-pinctrl" },
+	{ .compatible = "aspeed,g5-pinctrl" },
+	{ }
+};
+
+U_BOOT_DRIVER(pinctrl_ast2500) = {
+	.name = "aspeed_ast2500_pinctrl",
+	.id = UCLASS_PINCTRL,
+	.of_match = ast2500_pinctrl_ids,
+	.priv_auto_alloc_size = sizeof(struct ast2500_pinctrl_priv),
+	.ops = &ast2500_pinctrl_ops,
+	.probe = ast2500_pinctrl_probe,
+};
diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c
index aa2c440..d7b5ea3 100644
--- a/drivers/pinctrl/pinctrl_stm32.c
+++ b/drivers/pinctrl/pinctrl_stm32.c
@@ -1,10 +1,46 @@
 #include <common.h>
-#include <asm/arch/gpio.h>
 #include <dm.h>
 #include <dm/pinctrl.h>
+#include <asm/arch/gpio.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#define MAX_PINS_ONE_IP			70
+#define MODE_BITS_MASK			3
+#define OSPEED_MASK			3
+#define PUPD_MASK			3
+#define OTYPE_MSK			1
+#define AFR_MASK			0xF
+
+static int stm32_gpio_config(struct gpio_desc *desc,
+			     const struct stm32_gpio_ctl *ctl)
+{
+	struct stm32_gpio_priv *priv = dev_get_priv(desc->dev);
+	struct stm32_gpio_regs *regs = priv->regs;
+	u32 index;
+
+	if (!ctl || ctl->af > 15 || ctl->mode > 3 || ctl->otype > 1 ||
+	    ctl->pupd > 2 || ctl->speed > 3)
+		return -EINVAL;
+
+	index = (desc->offset & 0x07) * 4;
+	clrsetbits_le32(&regs->afr[desc->offset >> 3], AFR_MASK << index,
+			ctl->af << index);
+
+	index = desc->offset * 2;
+	clrsetbits_le32(&regs->moder, MODE_BITS_MASK << index,
+			ctl->mode << index);
+	clrsetbits_le32(&regs->ospeedr, OSPEED_MASK << index,
+			ctl->speed << index);
+	clrsetbits_le32(&regs->pupdr, PUPD_MASK << index, ctl->pupd << index);
+
+	index = desc->offset;
+	clrsetbits_le32(&regs->otyper, OTYPE_MSK << index, ctl->otype << index);
+
+	return 0;
+}
 static int prep_gpio_dsc(struct stm32_gpio_dsc *gpio_dsc, u32 port_pin)
 {
 	gpio_dsc->port = (port_pin & 0xF000) >> 12;
@@ -18,6 +54,7 @@
 static int prep_gpio_ctl(struct stm32_gpio_ctl *gpio_ctl, u32 gpio_fn, int node)
 {
 	gpio_fn &= 0x00FF;
+	gpio_ctl->af = 0;
 
 	switch (gpio_fn) {
 	case 0:
@@ -59,7 +96,7 @@
 static int stm32_pinctrl_set_state_simple(struct udevice *dev,
 					  struct udevice *periph)
 {
-	u32 pin_mux[50];
+	u32 pin_mux[MAX_PINS_ONE_IP];
 	struct fdtdec_phandle_args args;
 	int rv, len;
 
@@ -85,11 +122,16 @@
 		if (len < 0)
 			return -EINVAL;
 		for (i = 0; i < len; i++) {
+			struct gpio_desc desc;
 			debug("%s: pinmux = %x\n", __func__, *(pin_mux + i));
 			prep_gpio_dsc(&gpio_dsc, *(pin_mux + i));
 			prep_gpio_ctl(&gpio_ctl, *(pin_mux + i), args.node);
-
-			rv = stm32_gpio_config(&gpio_dsc, &gpio_ctl);
+			rv = uclass_get_device_by_seq(UCLASS_GPIO,
+						      gpio_dsc.port, &desc.dev);
+			if (rv)
+				return rv;
+			desc.offset = gpio_dsc.pin;
+			rv = stm32_gpio_config(&desc, &gpio_ctl);
 			debug("%s: rv = %d\n\n", __func__, rv);
 			if (rv)
 				return rv;
diff --git a/drivers/power/sy8106a.c b/drivers/power/sy8106a.c
index bbf116f..f9db396 100644
--- a/drivers/power/sy8106a.c
+++ b/drivers/power/sy8106a.c
@@ -12,6 +12,7 @@
 #define SY8106A_VOUT1_SEL 1
 #define SY8106A_VOUT1_SEL_ENABLE (1 << 7)
 
+#ifdef CONFIG_SPL_BUILD
 static u8 sy8106a_mvolt_to_cfg(int mvolt, int min, int max, int div)
 {
 	if (mvolt < min)
@@ -27,3 +28,4 @@
 	u8 data = sy8106a_mvolt_to_cfg(mvolt, 680, 1950, 10) | SY8106A_VOUT1_SEL_ENABLE;
 	return i2c_write(SY8106A_I2C_ADDR, SY8106A_VOUT1_SEL, 1, &data, 1);
 }
+#endif
diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig
index ff09f22..61afd7a 100644
--- a/drivers/ram/Kconfig
+++ b/drivers/ram/Kconfig
@@ -16,3 +16,11 @@
 	  If this is acceptable and you have a need to use RAM drivers in
 	  SPL, enable this option. It might provide a cleaner interface to
 	  setting up RAM (e.g. SDRAM / DDR) within SPL.
+
+config STM32_SDRAM
+	bool "Enable STM32 SDRAM support"
+	depends on RAM
+	help
+	  STM32F7 family devices support flexible memory controller(FMC) to
+	  support external memories like sdram, psram & nand.
+	  This driver is for the sdram memory interface with the FMC.
diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
index 0e10249..ecb036d 100644
--- a/drivers/ram/Makefile
+++ b/drivers/ram/Makefile
@@ -6,3 +6,4 @@
 #
 obj-$(CONFIG_RAM) += ram-uclass.o
 obj-$(CONFIG_SANDBOX) += sandbox_ram.o
+obj-$(CONFIG_STM32_SDRAM) += stm32_sdram.o
diff --git a/drivers/ram/stm32_sdram.c b/drivers/ram/stm32_sdram.c
new file mode 100644
index 0000000..48b4979
--- /dev/null
+++ b/drivers/ram/stm32_sdram.c
@@ -0,0 +1,179 @@
+/*
+ * (C) Copyright 2017
+ * Vikas Manocha, <vikas.manocha@st.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <ram.h>
+#include <asm/io.h>
+#include <asm/arch/fmc.h>
+#include <asm/arch/stm32.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct stm32_sdram_control {
+	u8 no_columns;
+	u8 no_rows;
+	u8 memory_width;
+	u8 no_banks;
+	u8 cas_latency;
+	u8 sdclk;
+	u8 rd_burst;
+	u8 rd_pipe_delay;
+};
+
+struct stm32_sdram_timing {
+	u8 tmrd;
+	u8 txsr;
+	u8 tras;
+	u8 trc;
+	u8 trp;
+	u8 twr;
+	u8 trcd;
+};
+struct stm32_sdram_params {
+	u8 no_sdram_banks;
+	struct stm32_sdram_control sdram_control;
+	struct stm32_sdram_timing sdram_timing;
+	u32 sdram_ref_count;
+};
+
+#define SDRAM_MODE_BL_SHIFT	0
+#define SDRAM_MODE_CAS_SHIFT	4
+#define SDRAM_MODE_BL		0
+
+int stm32_sdram_init(struct udevice *dev)
+{
+	struct stm32_sdram_params *params = dev_get_platdata(dev);
+
+	writel(params->sdram_control.sdclk << FMC_SDCR_SDCLK_SHIFT
+		| params->sdram_control.cas_latency << FMC_SDCR_CAS_SHIFT
+		| params->sdram_control.no_banks << FMC_SDCR_NB_SHIFT
+		| params->sdram_control.memory_width << FMC_SDCR_MWID_SHIFT
+		| params->sdram_control.no_rows << FMC_SDCR_NR_SHIFT
+		| params->sdram_control.no_columns << FMC_SDCR_NC_SHIFT
+		| params->sdram_control.rd_pipe_delay << FMC_SDCR_RPIPE_SHIFT
+		| params->sdram_control.rd_burst << FMC_SDCR_RBURST_SHIFT,
+		&STM32_SDRAM_FMC->sdcr1);
+
+	writel(params->sdram_timing.trcd << FMC_SDTR_TRCD_SHIFT
+		| params->sdram_timing.trp << FMC_SDTR_TRP_SHIFT
+		| params->sdram_timing.twr << FMC_SDTR_TWR_SHIFT
+		| params->sdram_timing.trc << FMC_SDTR_TRC_SHIFT
+		| params->sdram_timing.tras << FMC_SDTR_TRAS_SHIFT
+		| params->sdram_timing.txsr << FMC_SDTR_TXSR_SHIFT
+		| params->sdram_timing.tmrd << FMC_SDTR_TMRD_SHIFT,
+		&STM32_SDRAM_FMC->sdtr1);
+
+	writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_START_CLOCK,
+	       &STM32_SDRAM_FMC->sdcmr);
+	udelay(200);	/* 200 us delay, page 10, "Power-Up" */
+	FMC_BUSY_WAIT();
+
+	writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_PRECHARGE,
+	       &STM32_SDRAM_FMC->sdcmr);
+	udelay(100);
+	FMC_BUSY_WAIT();
+
+	writel((FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_AUTOREFRESH
+		| 7 << FMC_SDCMR_NRFS_SHIFT), &STM32_SDRAM_FMC->sdcmr);
+	udelay(100);
+	FMC_BUSY_WAIT();
+
+	writel(FMC_SDCMR_BANK_1 | (SDRAM_MODE_BL << SDRAM_MODE_BL_SHIFT
+	       | params->sdram_control.cas_latency << SDRAM_MODE_CAS_SHIFT)
+	       << FMC_SDCMR_MODE_REGISTER_SHIFT | FMC_SDCMR_MODE_WRITE_MODE,
+	       &STM32_SDRAM_FMC->sdcmr);
+	udelay(100);
+	FMC_BUSY_WAIT();
+
+	writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_NORMAL,
+	       &STM32_SDRAM_FMC->sdcmr);
+	FMC_BUSY_WAIT();
+
+	/* Refresh timer */
+	writel((params->sdram_ref_count) << 1, &STM32_SDRAM_FMC->sdrtr);
+
+	return 0;
+}
+
+static int stm32_fmc_ofdata_to_platdata(struct udevice *dev)
+{
+	int ret;
+	int node = dev->of_offset;
+	const void *blob = gd->fdt_blob;
+	struct stm32_sdram_params *params = dev_get_platdata(dev);
+
+	params->no_sdram_banks = fdtdec_get_uint(blob, node, "mr-nbanks", 1);
+	debug("%s, no of banks = %d\n", __func__, params->no_sdram_banks);
+
+	fdt_for_each_subnode(node, blob, node) {
+		ret = fdtdec_get_byte_array(blob, node, "st,sdram-control",
+					    (u8 *)&params->sdram_control,
+					    sizeof(params->sdram_control));
+		if (ret)
+			return ret;
+		ret = fdtdec_get_byte_array(blob, node, "st,sdram-timing",
+					    (u8 *)&params->sdram_timing,
+					    sizeof(params->sdram_timing));
+		if (ret)
+			return ret;
+
+		params->sdram_ref_count = fdtdec_get_int(blob, node,
+						"st,sdram-refcount", 8196);
+	}
+
+	return 0;
+}
+
+static int stm32_fmc_probe(struct udevice *dev)
+{
+#ifdef CONFIG_CLK
+	int ret;
+	struct clk clk;
+
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_enable(&clk);
+
+	if (ret) {
+		dev_err(dev, "failed to enable clock\n");
+		return ret;
+	}
+#endif
+	ret = stm32_sdram_init(dev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int stm32_fmc_get_info(struct udevice *dev, struct ram_info *info)
+{
+	return 0;
+}
+
+static struct ram_ops stm32_fmc_ops = {
+	.get_info = stm32_fmc_get_info,
+};
+
+static const struct udevice_id stm32_fmc_ids[] = {
+	{ .compatible = "st,stm32-fmc" },
+	{ }
+};
+
+U_BOOT_DRIVER(stm32_fmc) = {
+	.name = "stm32_fmc",
+	.id = UCLASS_RAM,
+	.of_match = stm32_fmc_ids,
+	.ops = &stm32_fmc_ops,
+	.ofdata_to_platdata = stm32_fmc_ofdata_to_platdata,
+	.probe = stm32_fmc_probe,
+	.platdata_auto_alloc_size = sizeof(struct stm32_sdram_params),
+};
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index fa77ee4..80f4646 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -51,4 +51,14 @@
 	  Say Y if you want to control reset signals provided by System Control
 	  block, Media I/O block, Peripheral Block.
 
+config AST2500_RESET
+	bool "Reset controller driver for AST2500 SoCs"
+	depends on DM_RESET && WDT_ASPEED
+	default y if ASPEED_AST2500
+	help
+	  Support for reset controller on AST2500 SoC. This controller uses
+	  watchdog to reset different peripherals and thus only supports
+	  resets that are supported by watchdog. The main limitation though
+	  is that some reset signals, like I2C or MISC reset multiple devices.
+
 endmenu
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 2b96396..630b4b4 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -9,3 +9,4 @@
 obj-$(CONFIG_TEGRA_CAR_RESET) += tegra-car-reset.o
 obj-$(CONFIG_TEGRA186_RESET) += tegra186-reset.o
 obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
+obj-$(CONFIG_AST2500_RESET) += ast2500-reset.o
diff --git a/drivers/reset/ast2500-reset.c b/drivers/reset/ast2500-reset.c
new file mode 100644
index 0000000..b2c89e1
--- /dev/null
+++ b/drivers/reset/ast2500-reset.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <misc.h>
+#include <reset.h>
+#include <reset-uclass.h>
+#include <wdt.h>
+#include <asm/io.h>
+#include <asm/arch/scu_ast2500.h>
+#include <asm/arch/wdt.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct ast2500_reset_priv {
+	/* WDT used to perform resets. */
+	struct udevice *wdt;
+	struct ast2500_scu *scu;
+};
+
+static int ast2500_ofdata_to_platdata(struct udevice *dev)
+{
+	struct ast2500_reset_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = uclass_get_device_by_phandle(UCLASS_WDT, dev, "aspeed,wdt",
+					   &priv->wdt);
+	if (ret) {
+		debug("%s: can't find WDT for reset controller", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ast2500_reset_assert(struct reset_ctl *reset_ctl)
+{
+	struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+	u32 reset_mode, reset_mask;
+	bool reset_sdram;
+	int ret;
+
+	/*
+	 * To reset SDRAM, a specifal flag in SYSRESET register
+	 * needs to be enabled first
+	 */
+	reset_mode = ast_reset_mode_from_flags(reset_ctl->id);
+	reset_mask = ast_reset_mask_from_flags(reset_ctl->id);
+	reset_sdram = reset_mode == WDT_CTRL_RESET_SOC &&
+		(reset_mask & WDT_RESET_SDRAM);
+
+	if (reset_sdram) {
+		ast_scu_unlock(priv->scu);
+		setbits_le32(&priv->scu->sysreset_ctrl1,
+			     SCU_SYSRESET_SDRAM_WDT);
+		ret = wdt_expire_now(priv->wdt, reset_ctl->id);
+		clrbits_le32(&priv->scu->sysreset_ctrl1,
+			     SCU_SYSRESET_SDRAM_WDT);
+		ast_scu_lock(priv->scu);
+	} else {
+		ret = wdt_expire_now(priv->wdt, reset_ctl->id);
+	}
+
+	return ret;
+}
+
+static int ast2500_reset_request(struct reset_ctl *reset_ctl)
+{
+	debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl,
+	      reset_ctl->dev, reset_ctl->id);
+
+	return 0;
+}
+
+static int ast2500_reset_probe(struct udevice *dev)
+{
+	struct ast2500_reset_priv *priv = dev_get_priv(dev);
+
+	priv->scu = ast_get_scu();
+
+	return 0;
+}
+
+static const struct udevice_id ast2500_reset_ids[] = {
+	{ .compatible = "aspeed,ast2500-reset" },
+	{ }
+};
+
+struct reset_ops ast2500_reset_ops = {
+	.rst_assert = ast2500_reset_assert,
+	.request = ast2500_reset_request,
+};
+
+U_BOOT_DRIVER(ast2500_reset) = {
+	.name		= "ast2500_reset",
+	.id		= UCLASS_RESET,
+	.of_match = ast2500_reset_ids,
+	.probe = ast2500_reset_probe,
+	.ops = &ast2500_reset_ops,
+	.ofdata_to_platdata = ast2500_ofdata_to_platdata,
+	.priv_auto_alloc_size = sizeof(struct ast2500_reset_priv),
+};
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index cb79a01..d06130c7 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -23,4 +23,11 @@
 	  has a selectable I2C-bus or SPI-bus, a backup battery switch-over circuit, a
 	  programmable watchdog function, a timestamp function, and many other features.
 
+config RTC_DS1307
+	bool "Enable DS1307 driver"
+	depends on DM_RTC
+	help
+	  Support for Dallas Semiconductor (now Maxim) DS1307 and DS1338/9 and
+	  compatible Real Time Clock devices.
+
 endmenu
diff --git a/drivers/rtc/ds1307.c b/drivers/rtc/ds1307.c
index 3be1da6..5df15c7 100644
--- a/drivers/rtc/ds1307.c
+++ b/drivers/rtc/ds1307.c
@@ -16,28 +16,16 @@
 
 #include <common.h>
 #include <command.h>
+#include <dm.h>
 #include <rtc.h>
 #include <i2c.h>
 
-#if defined(CONFIG_CMD_DATE)
-
-/*---------------------------------------------------------------------*/
-#undef DEBUG_RTC
-
-#ifdef DEBUG_RTC
-#define DEBUGR(fmt,args...) printf(fmt ,##args)
-#else
-#define DEBUGR(fmt,args...)
-#endif
-/*---------------------------------------------------------------------*/
-
-#ifndef CONFIG_SYS_I2C_RTC_ADDR
-# define CONFIG_SYS_I2C_RTC_ADDR	0x68
-#endif
-
-#if defined(CONFIG_RTC_DS1307) && (CONFIG_SYS_I2C_SPEED > 100000)
-# error The DS1307 is specified only up to 100kHz!
-#endif
+enum ds_type {
+	ds_1307,
+	ds_1337,
+	ds_1340,
+	mcp794xx,
+};
 
 /*
  * RTC register addresses
@@ -62,6 +50,28 @@
 #define MCP7941X_BIT_ST		0x80
 #define MCP7941X_BIT_VBATEN	0x08
 
+#ifndef CONFIG_DM_RTC
+
+#if defined(CONFIG_CMD_DATE)
+
+/*---------------------------------------------------------------------*/
+#undef DEBUG_RTC
+
+#ifdef DEBUG_RTC
+#define DEBUGR(fmt, args...) printf(fmt, ##args)
+#else
+#define DEBUGR(fmt, args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+#ifndef CONFIG_SYS_I2C_RTC_ADDR
+# define CONFIG_SYS_I2C_RTC_ADDR	0x68
+#endif
+
+#if defined(CONFIG_RTC_DS1307) && (CONFIG_SYS_I2C_SPEED > 100000)
+# error The DS1307 is specified only up to 100kHz!
+#endif
+
 static uchar rtc_read (uchar reg);
 static void rtc_write (uchar reg, uchar val);
 
@@ -211,4 +221,163 @@
 {
 	i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
 }
-#endif
+
+#endif /* CONFIG_CMD_DATE*/
+
+#endif /* !CONFIG_DM_RTC */
+
+#ifdef CONFIG_DM_RTC
+static int ds1307_rtc_set(struct udevice *dev, const struct rtc_time *tm)
+{
+	int ret;
+	uchar buf[7];
+	enum ds_type type = dev_get_driver_data(dev);
+
+	debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	      tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
+	      tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	if (tm->tm_year < 1970 || tm->tm_year > 2069)
+		printf("WARNING: year should be between 1970 and 2069!\n");
+
+	buf[RTC_YR_REG_ADDR] = bin2bcd(tm->tm_year % 100);
+	buf[RTC_MON_REG_ADDR] = bin2bcd(tm->tm_mon);
+	buf[RTC_DAY_REG_ADDR] = bin2bcd(tm->tm_wday + 1);
+	buf[RTC_DATE_REG_ADDR] = bin2bcd(tm->tm_mday);
+	buf[RTC_HR_REG_ADDR] = bin2bcd(tm->tm_hour);
+	buf[RTC_MIN_REG_ADDR] = bin2bcd(tm->tm_min);
+	buf[RTC_SEC_REG_ADDR] = bin2bcd(tm->tm_sec);
+
+	if (type == mcp794xx) {
+		buf[RTC_DAY_REG_ADDR] |= MCP7941X_BIT_VBATEN;
+		buf[RTC_SEC_REG_ADDR] |= MCP7941X_BIT_ST;
+	}
+
+	ret = dm_i2c_write(dev, 0, buf, sizeof(buf));
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int ds1307_rtc_get(struct udevice *dev, struct rtc_time *tm)
+{
+	int ret;
+	uchar buf[7];
+	enum ds_type type = dev_get_driver_data(dev);
+
+read_rtc:
+	ret = dm_i2c_read(dev, 0, buf, sizeof(buf));
+	if (ret < 0)
+		return ret;
+
+	if (type == ds_1307) {
+		if (buf[RTC_SEC_REG_ADDR] & RTC_SEC_BIT_CH) {
+			printf("### Warning: RTC oscillator has stopped\n");
+			/* clear the CH flag */
+			buf[RTC_SEC_REG_ADDR] &= ~RTC_SEC_BIT_CH;
+			dm_i2c_reg_write(dev, RTC_SEC_REG_ADDR,
+					 buf[RTC_SEC_REG_ADDR]);
+			return -1;
+		}
+	}
+
+	if (type == mcp794xx) {
+		/* make sure that the backup battery is enabled */
+		if (!(buf[RTC_DAY_REG_ADDR] & MCP7941X_BIT_VBATEN)) {
+			dm_i2c_reg_write(dev, RTC_DAY_REG_ADDR,
+					 buf[RTC_DAY_REG_ADDR] |
+					 MCP7941X_BIT_VBATEN);
+		}
+
+		/* clock halted?  turn it on, so clock can tick. */
+		if (!(buf[RTC_SEC_REG_ADDR] & MCP7941X_BIT_ST)) {
+			dm_i2c_reg_write(dev, RTC_SEC_REG_ADDR,
+					 MCP7941X_BIT_ST);
+			printf("Started RTC\n");
+			goto read_rtc;
+		}
+	}
+
+	tm->tm_sec  = bcd2bin(buf[RTC_SEC_REG_ADDR] & 0x7F);
+	tm->tm_min  = bcd2bin(buf[RTC_MIN_REG_ADDR] & 0x7F);
+	tm->tm_hour = bcd2bin(buf[RTC_HR_REG_ADDR] & 0x3F);
+	tm->tm_mday = bcd2bin(buf[RTC_DATE_REG_ADDR] & 0x3F);
+	tm->tm_mon  = bcd2bin(buf[RTC_MON_REG_ADDR] & 0x1F);
+	tm->tm_year = bcd2bin(buf[RTC_YR_REG_ADDR]) +
+			      (bcd2bin(buf[RTC_YR_REG_ADDR]) >= 70 ?
+			       1900 : 2000);
+	tm->tm_wday = bcd2bin((buf[RTC_DAY_REG_ADDR] - 1) & 0x07);
+	tm->tm_yday = 0;
+	tm->tm_isdst = 0;
+
+	debug("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	      tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
+	      tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	return 0;
+}
+
+static int ds1307_rtc_reset(struct udevice *dev)
+{
+	int ret;
+	struct rtc_time tmp = {
+		.tm_year = 1970,
+		.tm_mon = 1,
+		.tm_mday = 1,
+		.tm_hour = 0,
+		.tm_min = 0,
+		.tm_sec = 0,
+	};
+
+	/* clear Clock Halt */
+	ret = dm_i2c_reg_write(dev, RTC_SEC_REG_ADDR, 0x00);
+	if (ret < 0)
+		return ret;
+	ret = dm_i2c_reg_write(dev, RTC_CTL_REG_ADDR,
+			       RTC_CTL_BIT_SQWE | RTC_CTL_BIT_RS1 |
+			       RTC_CTL_BIT_RS0);
+	if (ret < 0)
+		return ret;
+
+	ret = ds1307_rtc_set(dev, &tmp);
+	if (ret < 0)
+		return ret;
+
+	debug("RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
+	      tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
+	      tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
+
+	return 0;
+}
+
+static int ds1307_probe(struct udevice *dev)
+{
+	i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS |
+			   DM_I2C_CHIP_WR_ADDRESS);
+
+	return 0;
+}
+
+static const struct rtc_ops ds1307_rtc_ops = {
+	.get = ds1307_rtc_get,
+	.set = ds1307_rtc_set,
+	.reset = ds1307_rtc_reset,
+};
+
+static const struct udevice_id ds1307_rtc_ids[] = {
+	{ .compatible = "dallas,ds1307", .data = ds_1307 },
+	{ .compatible = "dallas,ds1337", .data = ds_1337 },
+	{ .compatible = "dallas,ds1340", .data = ds_1340 },
+	{ .compatible = "microchip,mcp7941x", .data = mcp794xx },
+	{ }
+};
+
+U_BOOT_DRIVER(rtc_ds1307) = {
+	.name	= "rtc-ds1307",
+	.id	= UCLASS_RTC,
+	.probe	= ds1307_probe,
+	.of_match = ds1307_rtc_ids,
+	.ops	= &ds1307_rtc_ops,
+};
+#endif /* CONFIG_DM_RTC */
diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
index 8a89450..76d376a 100644
--- a/drivers/spi/omap3_spi.c
+++ b/drivers/spi/omap3_spi.c
@@ -692,6 +692,5 @@
 	.probe = omap3_spi_probe,
 	.ops    = &omap3_spi_ops,
 	.priv_auto_alloc_size = sizeof(struct omap3_spi_priv),
-	.probe = omap3_spi_probe,
 };
 #endif
diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c
index 05358eb..f0434a4 100644
--- a/drivers/spi/stm32_qspi.c
+++ b/drivers/spi/stm32_qspi.c
@@ -17,6 +17,7 @@
 #include <errno.h>
 #include <asm/arch/stm32.h>
 #include <asm/arch/stm32_defs.h>
+#include <clk.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -457,7 +458,20 @@
 
 	priv->max_hz = plat->max_hz;
 
-	clock_setup(QSPI_CLOCK_CFG);
+#ifdef CONFIG_CLK
+	int ret;
+	struct clk clk;
+	ret = clk_get_by_index(bus, 0, &clk);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_enable(&clk);
+
+	if (ret) {
+		dev_err(bus, "failed to enable clock\n");
+		return ret;
+	}
+#endif
 
 	setbits_le32(&priv->regs->cr, STM32_QSPI_CR_SSHIFT);
 
diff --git a/drivers/sysreset/sysreset_ast.c b/drivers/sysreset/sysreset_ast.c
index a0ab128..3c3f552 100644
--- a/drivers/sysreset/sysreset_ast.c
+++ b/drivers/sysreset/sysreset_ast.c
@@ -8,21 +8,19 @@
 #include <dm.h>
 #include <errno.h>
 #include <sysreset.h>
+#include <wdt.h>
 #include <asm/io.h>
 #include <asm/arch/wdt.h>
 #include <linux/err.h>
 
-/* Number of Watchdog Timer ticks before reset */
-#define AST_WDT_RESET_TIMEOUT	10
-#define AST_WDT_FOR_RESET	0
-
 static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type)
 {
-	struct ast_wdt *wdt = ast_get_wdt(AST_WDT_FOR_RESET);
-	u32 reset_mode = 0;
+	struct udevice *wdt;
+	u32 reset_mode;
+	int ret = uclass_first_device(UCLASS_WDT, &wdt);
 
-	if (IS_ERR(wdt))
-		return PTR_ERR(wdt);
+	if (ret)
+		return ret;
 
 	switch (type) {
 	case SYSRESET_WARM:
@@ -35,11 +33,11 @@
 		return -EPROTONOSUPPORT;
 	}
 
-	/* Clear reset mode bits */
-	clrsetbits_le32(&wdt->ctrl,
-			(WDT_CTRL_RESET_MODE_MASK << WDT_CTRL_RESET_MODE_SHIFT),
-			(reset_mode << WDT_CTRL_RESET_MODE_SHIFT));
-	wdt_start(wdt, AST_WDT_RESET_TIMEOUT);
+	ret = wdt_expire_now(wdt, reset_mode);
+	if (ret) {
+		debug("Sysreset failed: %d", ret);
+		return ret;
+	}
 
 	return -EINPROGRESS;
 }
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 0bf8274..fb5aa6f 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -44,6 +44,15 @@
 	help
 	  Enables support for the on-chip xHCI controller on Xilinx ZynqMP SoCs.
 
+config USB_XHCI_DRA7XX_INDEX
+	int "DRA7XX xHCI USB index"
+	range 0 1
+	default 0
+	depends on DRA7XX
+	help
+	  Select the DRA7XX xHCI USB index.
+	  Current supported values: 0, 1.
+
 endif # USB_XHCI_HCD
 
 config USB_EHCI_HCD
diff --git a/drivers/usb/host/xhci-omap.c b/drivers/usb/host/xhci-omap.c
index b881b19..d6c5744 100644
--- a/drivers/usb/host/xhci-omap.c
+++ b/drivers/usb/host/xhci-omap.c
@@ -27,12 +27,27 @@
 
 static struct omap_xhci omap;
 
-__weak int __board_usb_init(int index, enum usb_init_type init)
+__weak int omap_xhci_board_usb_init(int index, enum usb_init_type init)
 {
+	enable_usb_clocks(index);
 	return 0;
 }
+
 int board_usb_init(int index, enum usb_init_type init)
-	__attribute__((weak, alias("__board_usb_init")));
+{
+	return omap_xhci_board_usb_init(index, init);
+}
+
+__weak int omap_xhci_board_usb_cleanup(int index, enum usb_init_type init)
+{
+	disable_usb_clocks(index);
+	return 0;
+}
+
+int board_usb_cleanup(int index, enum usb_init_type init)
+{
+	return omap_xhci_board_usb_cleanup(index, init);
+}
 
 static int omap_xhci_core_init(struct omap_xhci *omap)
 {
diff --git a/drivers/video/sunxi/Makefile b/drivers/video/sunxi/Makefile
index dfc9b47..b8afd89 100644
--- a/drivers/video/sunxi/Makefile
+++ b/drivers/video/sunxi/Makefile
@@ -6,3 +6,4 @@
 #
 
 obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o lcdc.o ../videomodes.o
+obj-$(CONFIG_VIDEO_DE2) += sunxi_de2.o sunxi_dw_hdmi.o lcdc.o ../dw_hdmi.o
diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c
new file mode 100644
index 0000000..9a32c3a
--- /dev/null
+++ b/drivers/video/sunxi/sunxi_de2.c
@@ -0,0 +1,258 @@
+/*
+ * Allwinner DE2 display driver
+ *
+ * (C) Copyright 2017 Jernej Skrabec <jernej.skrabec@siol.net>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <display.h>
+#include <dm.h>
+#include <edid.h>
+#include <video.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/display2.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+	/* Maximum LCD size we support */
+	LCD_MAX_WIDTH		= 3840,
+	LCD_MAX_HEIGHT		= 2160,
+	LCD_MAX_LOG2_BPP	= VIDEO_BPP32,
+};
+
+static void sunxi_de2_composer_init(void)
+{
+	struct sunxi_ccm_reg * const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+#ifdef CONFIG_MACH_SUN50I
+	u32 reg_value;
+
+	/* set SRAM for video use (A64 only) */
+	reg_value = readl(SUNXI_SRAMC_BASE + 0x04);
+	reg_value &= ~(0x01 << 24);
+	writel(reg_value, SUNXI_SRAMC_BASE + 0x04);
+#endif
+
+	clock_set_pll10(432000000);
+
+	/* Set DE parent to pll10 */
+	clrsetbits_le32(&ccm->de_clk_cfg, CCM_DE2_CTRL_PLL_MASK,
+			CCM_DE2_CTRL_PLL10);
+
+	/* Set ahb gating to pass */
+	setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE);
+	setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_DE);
+
+	/* Clock on */
+	setbits_le32(&ccm->de_clk_cfg, CCM_DE2_CTRL_GATE);
+}
+
+static void sunxi_de2_mode_set(int mux, const struct display_timing *mode,
+			       int bpp, ulong address)
+{
+	ulong de_mux_base = (mux == 0) ?
+			    SUNXI_DE2_MUX0_BASE : SUNXI_DE2_MUX1_BASE;
+	struct de_clk * const de_clk_regs =
+		(struct de_clk *)(SUNXI_DE2_BASE);
+	struct de_glb * const de_glb_regs =
+		(struct de_glb *)(de_mux_base +
+				  SUNXI_DE2_MUX_GLB_REGS);
+	struct de_bld * const de_bld_regs =
+		(struct de_bld *)(de_mux_base +
+				  SUNXI_DE2_MUX_BLD_REGS);
+	struct de_ui * const de_ui_regs =
+		(struct de_ui *)(de_mux_base +
+				 SUNXI_DE2_MUX_CHAN_REGS +
+				 SUNXI_DE2_MUX_CHAN_SZ * 1);
+	u32 size = SUNXI_DE2_WH(mode->hactive.typ, mode->vactive.typ);
+	int channel;
+	u32 format;
+
+	/* enable clock */
+#ifdef CONFIG_MACH_SUN8I_H3
+	setbits_le32(&de_clk_regs->rst_cfg, (mux == 0) ? 1 : 4);
+#else
+	setbits_le32(&de_clk_regs->rst_cfg, BIT(mux));
+#endif
+	setbits_le32(&de_clk_regs->gate_cfg, BIT(mux));
+	setbits_le32(&de_clk_regs->bus_cfg, BIT(mux));
+
+	clrbits_le32(&de_clk_regs->sel_cfg, 1);
+
+	writel(SUNXI_DE2_MUX_GLB_CTL_EN, &de_glb_regs->ctl);
+	writel(0, &de_glb_regs->status);
+	writel(1, &de_glb_regs->dbuff);
+	writel(size, &de_glb_regs->size);
+
+	for (channel = 0; channel < 4; channel++) {
+		void *ch = (void *)(de_mux_base + SUNXI_DE2_MUX_CHAN_REGS +
+				    SUNXI_DE2_MUX_CHAN_SZ * channel);
+		memset(ch, 0, (channel == 0) ?
+			sizeof(struct de_vi) : sizeof(struct de_ui));
+	}
+	memset(de_bld_regs, 0, sizeof(struct de_bld));
+
+	writel(0x00000101, &de_bld_regs->fcolor_ctl);
+
+	writel(1, &de_bld_regs->route);
+
+	writel(0, &de_bld_regs->premultiply);
+	writel(0xff000000, &de_bld_regs->bkcolor);
+
+	writel(0x03010301, &de_bld_regs->bld_mode[0]);
+
+	writel(size, &de_bld_regs->output_size);
+	writel(mode->flags & DISPLAY_FLAGS_INTERLACED ? 2 : 0,
+	       &de_bld_regs->out_ctl);
+	writel(0, &de_bld_regs->ck_ctl);
+
+	writel(0xff000000, &de_bld_regs->attr[0].fcolor);
+	writel(size, &de_bld_regs->attr[0].insize);
+
+	/* Disable all other units */
+	writel(0, de_mux_base + SUNXI_DE2_MUX_VSU_REGS);
+	writel(0, de_mux_base + SUNXI_DE2_MUX_GSU1_REGS);
+	writel(0, de_mux_base + SUNXI_DE2_MUX_GSU2_REGS);
+	writel(0, de_mux_base + SUNXI_DE2_MUX_GSU3_REGS);
+	writel(0, de_mux_base + SUNXI_DE2_MUX_FCE_REGS);
+	writel(0, de_mux_base + SUNXI_DE2_MUX_BWS_REGS);
+	writel(0, de_mux_base + SUNXI_DE2_MUX_LTI_REGS);
+	writel(0, de_mux_base + SUNXI_DE2_MUX_PEAK_REGS);
+	writel(0, de_mux_base + SUNXI_DE2_MUX_ASE_REGS);
+	writel(0, de_mux_base + SUNXI_DE2_MUX_FCC_REGS);
+	writel(0, de_mux_base + SUNXI_DE2_MUX_DCSC_REGS);
+
+	switch (bpp) {
+	case 16:
+		format = SUNXI_DE2_UI_CFG_ATTR_FMT(SUNXI_DE2_FORMAT_RGB_565);
+		break;
+	case 32:
+	default:
+		format = SUNXI_DE2_UI_CFG_ATTR_FMT(SUNXI_DE2_FORMAT_XRGB_8888);
+		break;
+	}
+
+	writel(SUNXI_DE2_UI_CFG_ATTR_EN | format, &de_ui_regs->cfg[0].attr);
+	writel(size, &de_ui_regs->cfg[0].size);
+	writel(0, &de_ui_regs->cfg[0].coord);
+	writel((bpp / 8) * mode->hactive.typ, &de_ui_regs->cfg[0].pitch);
+	writel(address, &de_ui_regs->cfg[0].top_laddr);
+	writel(size, &de_ui_regs->ovl_size);
+
+	/* apply settings */
+	writel(1, &de_glb_regs->dbuff);
+}
+
+static int sunxi_de2_init(struct udevice *dev, ulong fbbase,
+			  enum video_log2_bpp l2bpp,
+			  struct udevice *disp, int mux)
+{
+	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct display_timing timing;
+	struct display_plat *disp_uc_plat;
+	int ret;
+
+	disp_uc_plat = dev_get_uclass_platdata(disp);
+	debug("Using device '%s', disp_uc_priv=%p\n", disp->name, disp_uc_plat);
+	if (display_in_use(disp)) {
+		debug("   - device in use\n");
+		return -EBUSY;
+	}
+
+	disp_uc_plat->source_id = mux;
+
+	ret = device_probe(disp);
+	if (ret) {
+		debug("%s: device '%s' display won't probe (ret=%d)\n",
+		      __func__, dev->name, ret);
+		return ret;
+	}
+
+	ret = display_read_timing(disp, &timing);
+	if (ret) {
+		debug("%s: Failed to read timings\n", __func__);
+		return ret;
+	}
+
+	sunxi_de2_composer_init();
+	sunxi_de2_mode_set(mux, &timing, 1 << l2bpp, fbbase);
+
+	ret = display_enable(disp, 1 << l2bpp, &timing);
+	if (ret) {
+		debug("%s: Failed to enable display\n", __func__);
+		return ret;
+	}
+
+	uc_priv->xsize = timing.hactive.typ;
+	uc_priv->ysize = timing.vactive.typ;
+	uc_priv->bpix = l2bpp;
+	debug("fb=%lx, size=%d %d\n", fbbase, uc_priv->xsize, uc_priv->ysize);
+
+	return 0;
+}
+
+static int sunxi_de2_probe(struct udevice *dev)
+{
+	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+	struct udevice *disp;
+	int ret;
+	int mux;
+
+	/* Before relocation we don't need to do anything */
+	if (!(gd->flags & GD_FLG_RELOC))
+		return 0;
+
+	ret = uclass_find_device_by_name(UCLASS_DISPLAY,
+					 "sunxi_dw_hdmi", &disp);
+	if (ret) {
+		debug("%s: hdmi display not found (ret=%d)\n", __func__, ret);
+		return ret;
+	}
+
+	if (IS_ENABLED(CONFIG_MACH_SUNXI_H3_H5))
+		mux = 0;
+	else
+		mux = 1;
+
+	ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, mux);
+	if (ret)
+		return ret;
+
+	video_set_flush_dcache(dev, 1);
+
+	return 0;
+}
+
+static int sunxi_de2_bind(struct udevice *dev)
+{
+	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+
+	plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
+		(1 << LCD_MAX_LOG2_BPP) / 8;
+
+	return 0;
+}
+
+static const struct video_ops sunxi_de2_ops = {
+};
+
+U_BOOT_DRIVER(sunxi_de2) = {
+	.name	= "sunxi_de2",
+	.id	= UCLASS_VIDEO,
+	.ops	= &sunxi_de2_ops,
+	.bind	= sunxi_de2_bind,
+	.probe	= sunxi_de2_probe,
+	.flags	= DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DEVICE(sunxi_de2) = {
+	.name = "sunxi_de2"
+};
diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c
new file mode 100644
index 0000000..33920a2
--- /dev/null
+++ b/drivers/video/sunxi/sunxi_dw_hdmi.c
@@ -0,0 +1,389 @@
+/*
+ * Allwinner DW HDMI bridge
+ *
+ * (C) Copyright 2017 Jernej Skrabec <jernej.skrabec@siol.net>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <display.h>
+#include <dm.h>
+#include <dw_hdmi.h>
+#include <edid.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/lcdc.h>
+
+struct sunxi_dw_hdmi_priv {
+	struct dw_hdmi hdmi;
+	int mux;
+};
+
+struct sunxi_hdmi_phy {
+	u32 pol;
+	u32 res1[3];
+	u32 read_en;
+	u32 unscramble;
+	u32 res2[2];
+	u32 ctrl;
+	u32 unk1;
+	u32 unk2;
+	u32 pll;
+	u32 clk;
+	u32 unk3;
+	u32 status;
+};
+
+#define HDMI_PHY_OFFS 0x10000
+
+static int sunxi_dw_hdmi_get_divider(uint clock)
+{
+	/*
+	 * Due to missing documentaion of HDMI PHY, we know correct
+	 * settings only for following four PHY dividers. Select one
+	 * based on clock speed.
+	 */
+	if (clock <= 27000000)
+		return 11;
+	else if (clock <= 74250000)
+		return 4;
+	else if (clock <= 148500000)
+		return 2;
+	else
+		return 1;
+}
+
+static void sunxi_dw_hdmi_phy_init(void)
+{
+	struct sunxi_hdmi_phy * const phy =
+		(struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS);
+	unsigned long tmo;
+	u32 tmp;
+
+	/*
+	 * HDMI PHY settings are taken as-is from Allwinner BSP code.
+	 * There is no documentation.
+	 */
+	writel(0, &phy->ctrl);
+	setbits_le32(&phy->ctrl, BIT(0));
+	udelay(5);
+	setbits_le32(&phy->ctrl, BIT(16));
+	setbits_le32(&phy->ctrl, BIT(1));
+	udelay(10);
+	setbits_le32(&phy->ctrl, BIT(2));
+	udelay(5);
+	setbits_le32(&phy->ctrl, BIT(3));
+	udelay(40);
+	setbits_le32(&phy->ctrl, BIT(19));
+	udelay(100);
+	setbits_le32(&phy->ctrl, BIT(18));
+	setbits_le32(&phy->ctrl, 7 << 4);
+
+	/* Note that Allwinner code doesn't fail in case of timeout */
+	tmo = timer_get_us() + 2000;
+	while ((readl(&phy->status) & 0x80) == 0) {
+		if (timer_get_us() > tmo) {
+			printf("Warning: HDMI PHY init timeout!\n");
+			break;
+		}
+	}
+
+	setbits_le32(&phy->ctrl, 0xf << 8);
+	setbits_le32(&phy->ctrl, BIT(7));
+
+	writel(0x39dc5040, &phy->pll);
+	writel(0x80084343, &phy->clk);
+	udelay(10000);
+	writel(1, &phy->unk3);
+	setbits_le32(&phy->pll, BIT(25));
+	udelay(100000);
+	tmp = (readl(&phy->status) & 0x1f800) >> 11;
+	setbits_le32(&phy->pll, BIT(31) | BIT(30));
+	setbits_le32(&phy->pll, tmp);
+	writel(0x01FF0F7F, &phy->ctrl);
+	writel(0x80639000, &phy->unk1);
+	writel(0x0F81C405, &phy->unk2);
+
+	/* enable read access to HDMI controller */
+	writel(0x54524545, &phy->read_en);
+	/* descramble register offsets */
+	writel(0x42494E47, &phy->unscramble);
+}
+
+static int sunxi_dw_hdmi_get_plug_in_status(void)
+{
+	struct sunxi_hdmi_phy * const phy =
+		(struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS);
+
+	return !!(readl(&phy->status) & (1 << 19));
+}
+
+static int sunxi_dw_hdmi_wait_for_hpd(void)
+{
+	ulong start;
+
+	start = get_timer(0);
+	do {
+		if (sunxi_dw_hdmi_get_plug_in_status())
+			return 0;
+		udelay(100);
+	} while (get_timer(start) < 300);
+
+	return -1;
+}
+
+static void sunxi_dw_hdmi_phy_set(uint clock)
+{
+	struct sunxi_hdmi_phy * const phy =
+		(struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS);
+	int div = sunxi_dw_hdmi_get_divider(clock);
+	u32 tmp;
+
+	/*
+	 * Unfortunately, we don't know much about those magic
+	 * numbers. They are taken from Allwinner BSP driver.
+	 */
+	switch (div) {
+	case 1:
+		writel(0x30dc5fc0, &phy->pll);
+		writel(0x800863C0, &phy->clk);
+		mdelay(10);
+		writel(0x00000001, &phy->unk3);
+		setbits_le32(&phy->pll, BIT(25));
+		mdelay(200);
+		tmp = (readl(&phy->status) & 0x1f800) >> 11;
+		setbits_le32(&phy->pll, BIT(31) | BIT(30));
+		if (tmp < 0x3d)
+			setbits_le32(&phy->pll, tmp + 2);
+		else
+			setbits_le32(&phy->pll, 0x3f);
+		mdelay(100);
+		writel(0x01FFFF7F, &phy->ctrl);
+		writel(0x8063b000, &phy->unk1);
+		writel(0x0F8246B5, &phy->unk2);
+		break;
+	case 2:
+		writel(0x39dc5040, &phy->pll);
+		writel(0x80084381, &phy->clk);
+		mdelay(10);
+		writel(0x00000001, &phy->unk3);
+		setbits_le32(&phy->pll, BIT(25));
+		mdelay(100);
+		tmp = (readl(&phy->status) & 0x1f800) >> 11;
+		setbits_le32(&phy->pll, BIT(31) | BIT(30));
+		setbits_le32(&phy->pll, tmp);
+		writel(0x01FFFF7F, &phy->ctrl);
+		writel(0x8063a800, &phy->unk1);
+		writel(0x0F81C485, &phy->unk2);
+		break;
+	case 4:
+		writel(0x39dc5040, &phy->pll);
+		writel(0x80084343, &phy->clk);
+		mdelay(10);
+		writel(0x00000001, &phy->unk3);
+		setbits_le32(&phy->pll, BIT(25));
+		mdelay(100);
+		tmp = (readl(&phy->status) & 0x1f800) >> 11;
+		setbits_le32(&phy->pll, BIT(31) | BIT(30));
+		setbits_le32(&phy->pll, tmp);
+		writel(0x01FFFF7F, &phy->ctrl);
+		writel(0x8063b000, &phy->unk1);
+		writel(0x0F81C405, &phy->unk2);
+		break;
+	case 11:
+		writel(0x39dc5040, &phy->pll);
+		writel(0x8008430a, &phy->clk);
+		mdelay(10);
+		writel(0x00000001, &phy->unk3);
+		setbits_le32(&phy->pll, BIT(25));
+		mdelay(100);
+		tmp = (readl(&phy->status) & 0x1f800) >> 11;
+		setbits_le32(&phy->pll, BIT(31) | BIT(30));
+		setbits_le32(&phy->pll, tmp);
+		writel(0x01FFFF7F, &phy->ctrl);
+		writel(0x8063b000, &phy->unk1);
+		writel(0x0F81C405, &phy->unk2);
+		break;
+	}
+}
+
+static void sunxi_dw_hdmi_pll_set(uint clk_khz)
+{
+	int value, n, m, div = 0, diff;
+	int best_n = 0, best_m = 0, best_diff = 0x0FFFFFFF;
+
+	div = sunxi_dw_hdmi_get_divider(clk_khz * 1000);
+
+	/*
+	 * Find the lowest divider resulting in a matching clock. If there
+	 * is no match, pick the closest lower clock, as monitors tend to
+	 * not sync to higher frequencies.
+	 */
+	for (m = 1; m <= 16; m++) {
+		n = (m * div * clk_khz) / 24000;
+
+		if ((n >= 1) && (n <= 128)) {
+			value = (24000 * n) / m / div;
+			diff = clk_khz - value;
+			if (diff < best_diff) {
+				best_diff = diff;
+				best_m = m;
+				best_n = n;
+			}
+		}
+	}
+
+	clock_set_pll3_factors(best_m, best_n);
+	debug("dotclock: %dkHz = %dkHz: (24MHz * %d) / %d / %d\n",
+	      clk_khz, (clock_get_pll3() / 1000) / div,
+	      best_n, best_m, div);
+}
+
+static void sunxi_dw_hdmi_lcdc_init(int mux, const struct display_timing *edid,
+				    int bpp)
+{
+	struct sunxi_ccm_reg * const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	int div = sunxi_dw_hdmi_get_divider(edid->pixelclock.typ);
+	struct sunxi_lcdc_reg *lcdc;
+
+	if (mux == 0) {
+		lcdc = (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
+
+		/* Reset off */
+		setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_LCD0);
+
+		/* Clock on */
+		setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_LCD0);
+		writel(CCM_LCD0_CTRL_GATE | CCM_LCD0_CTRL_M(div),
+		       &ccm->lcd0_clk_cfg);
+	} else {
+		lcdc = (struct sunxi_lcdc_reg *)SUNXI_LCD1_BASE;
+
+		/* Reset off */
+		setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_LCD1);
+
+		/* Clock on */
+		setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_LCD1);
+		writel(CCM_LCD1_CTRL_GATE | CCM_LCD1_CTRL_M(div),
+		       &ccm->lcd1_clk_cfg);
+	}
+
+	lcdc_init(lcdc);
+	lcdc_tcon1_mode_set(lcdc, edid, false, false);
+	lcdc_enable(lcdc, bpp);
+}
+
+static int sunxi_dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint mpixelclock)
+{
+	sunxi_dw_hdmi_pll_set(mpixelclock/1000);
+	sunxi_dw_hdmi_phy_set(mpixelclock);
+
+	return 0;
+}
+
+static int sunxi_dw_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size)
+{
+	struct sunxi_dw_hdmi_priv *priv = dev_get_priv(dev);
+
+	return dw_hdmi_read_edid(&priv->hdmi, buf, buf_size);
+}
+
+static int sunxi_dw_hdmi_enable(struct udevice *dev, int panel_bpp,
+				const struct display_timing *edid)
+{
+	struct sunxi_hdmi_phy * const phy =
+		(struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS);
+	struct sunxi_dw_hdmi_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = dw_hdmi_enable(&priv->hdmi, edid);
+	if (ret)
+		return ret;
+
+	sunxi_dw_hdmi_lcdc_init(priv->mux, edid, panel_bpp);
+
+	/*
+	 * Condition in original code is a bit weird. This is attempt
+	 * to make it more reasonable and it works. It could be that
+	 * bits and conditions are related and should be separated.
+	 */
+	if (!((edid->flags & DISPLAY_FLAGS_HSYNC_HIGH) &&
+	      (edid->flags & DISPLAY_FLAGS_VSYNC_HIGH))) {
+		setbits_le32(&phy->pol, 0x300);
+	}
+
+	setbits_le32(&phy->ctrl, 0xf << 12);
+
+	/*
+	 * This is last hdmi access before boot, so scramble addresses
+	 * again or othwerwise BSP driver won't work. Dummy read is
+	 * needed or otherwise last write doesn't get written correctly.
+	 */
+	(void)readb(SUNXI_HDMI_BASE);
+	writel(0, &phy->unscramble);
+
+	return 0;
+}
+
+static int sunxi_dw_hdmi_probe(struct udevice *dev)
+{
+	struct display_plat *uc_plat = dev_get_uclass_platdata(dev);
+	struct sunxi_dw_hdmi_priv *priv = dev_get_priv(dev);
+	struct sunxi_ccm_reg * const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	int ret;
+
+	/* Set pll3 to 297 MHz */
+	clock_set_pll3(297000000);
+
+	/* Set hdmi parent to pll3 */
+	clrsetbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_PLL_MASK,
+			CCM_HDMI_CTRL_PLL3);
+
+	/* Set ahb gating to pass */
+	setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI);
+	setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI2);
+	setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI);
+	setbits_le32(&ccm->hdmi_slow_clk_cfg, CCM_HDMI_SLOW_CTRL_DDC_GATE);
+
+	/* Clock on */
+	setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE);
+
+	sunxi_dw_hdmi_phy_init();
+
+	ret = sunxi_dw_hdmi_wait_for_hpd();
+	if (ret < 0) {
+		debug("hdmi can not get hpd signal\n");
+		return -1;
+	}
+
+	priv->hdmi.ioaddr = SUNXI_HDMI_BASE;
+	priv->hdmi.i2c_clk_high = 0xd8;
+	priv->hdmi.i2c_clk_low = 0xfe;
+	priv->hdmi.reg_io_width = 1;
+	priv->hdmi.phy_set = sunxi_dw_hdmi_phy_cfg;
+	priv->mux = uc_plat->source_id;
+
+	dw_hdmi_init(&priv->hdmi);
+
+	return 0;
+}
+
+static const struct dm_display_ops sunxi_dw_hdmi_ops = {
+	.read_edid = sunxi_dw_hdmi_read_edid,
+	.enable = sunxi_dw_hdmi_enable,
+};
+
+U_BOOT_DRIVER(sunxi_dw_hdmi) = {
+	.name	= "sunxi_dw_hdmi",
+	.id	= UCLASS_DISPLAY,
+	.ops	= &sunxi_dw_hdmi_ops,
+	.probe	= sunxi_dw_hdmi_probe,
+	.priv_auto_alloc_size = sizeof(struct sunxi_dw_hdmi_priv),
+};
+
+U_BOOT_DEVICE(sunxi_dw_hdmi) = {
+	.name = "sunxi_dw_hdmi"
+};
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index dbdaafc..2034e3c 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1,8 +1,37 @@
-menu "WATCHDOG support"
+menu "Watchdog Timer Support"
 
 config ULP_WATCHDOG
 	bool "i.MX7ULP watchdog"
 	help
 	  Say Y here to enable i.MX7ULP watchdog driver.
 
+config WDT
+	bool "Enable driver model for watchdog timer drivers"
+	depends on DM
+	help
+	  Enable driver model for watchdog timer. At the moment the API
+	  is very simple and only supports four operations:
+	  start, restart, stop and reset (expire immediately).
+	  What exactly happens when the timer expires is up to a particular
+	  device/driver.
+
+config WDT_SANDBOX
+	bool "Enable Watchdog Timer support for Sandbox"
+	depends on SANDBOX && WDT
+	help
+		Enable Watchdog Timer support in Sandbox. This is a dummy device that
+		can be probed and supports all of the methods of WDT, but does not
+		really do anything.
+
+config WDT_ASPEED
+	bool "Aspeed ast2400/ast2500 watchdog timer support"
+	depends on WDT
+	default y if ARCH_ASPEED
+	help
+	  Select this to enable watchdog timer for Aspeed ast2500/ast2400 devices.
+	  The watchdog timer is stopped when initialized. It performs reset, either
+	  full SoC reset or CPU or just some peripherals, based on the flags.
+	  It currently does not support Boot Flash Addressing Mode Detection or
+	  Second Boot.
+
 endmenu
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 36745ca..dfc7fbd 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -15,3 +15,6 @@
 obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
 obj-$(CONFIG_DESIGNWARE_WATCHDOG) += designware_wdt.o
 obj-$(CONFIG_ULP_WATCHDOG) += ulp_wdog.o
+obj-$(CONFIG_WDT) += wdt-uclass.o
+obj-$(CONFIG_WDT_SANDBOX) += sandbox_wdt.o
+obj-$(CONFIG_WDT_ASPEED) += ast_wdt.o
diff --git a/drivers/watchdog/ast_wdt.c b/drivers/watchdog/ast_wdt.c
new file mode 100644
index 0000000..b2bd912
--- /dev/null
+++ b/drivers/watchdog/ast_wdt.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <wdt.h>
+#include <asm/io.h>
+#include <asm/arch/wdt.h>
+
+#define WDT_AST2500	2500
+#define WDT_AST2400	2400
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct ast_wdt_priv {
+	struct ast_wdt *regs;
+};
+
+static int ast_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+	struct ast_wdt_priv *priv = dev_get_priv(dev);
+	ulong driver_data = dev_get_driver_data(dev);
+	u32 reset_mode = ast_reset_mode_from_flags(flags);
+
+	clrsetbits_le32(&priv->regs->ctrl,
+			WDT_CTRL_RESET_MASK << WDT_CTRL_RESET_MODE_SHIFT,
+			reset_mode << WDT_CTRL_RESET_MODE_SHIFT);
+
+	if (driver_data >= WDT_AST2500 && reset_mode == WDT_CTRL_RESET_SOC)
+		writel(ast_reset_mask_from_flags(flags),
+		       &priv->regs->reset_mask);
+
+	writel((u32) timeout, &priv->regs->counter_reload_val);
+	writel(WDT_COUNTER_RESTART_VAL, &priv->regs->counter_restart);
+	/*
+	 * Setting CLK1MHZ bit is just for compatibility with ast2400 part.
+	 * On ast2500 watchdog timer clock is fixed at 1MHz and the bit is
+	 * read-only
+	 */
+	setbits_le32(&priv->regs->ctrl,
+		     WDT_CTRL_EN | WDT_CTRL_RESET | WDT_CTRL_CLK1MHZ);
+
+	return 0;
+}
+
+static int ast_wdt_stop(struct udevice *dev)
+{
+	struct ast_wdt_priv *priv = dev_get_priv(dev);
+
+	clrbits_le32(&priv->regs->ctrl, WDT_CTRL_EN);
+
+	return 0;
+}
+
+static int ast_wdt_reset(struct udevice *dev)
+{
+	struct ast_wdt_priv *priv = dev_get_priv(dev);
+
+	writel(WDT_COUNTER_RESTART_VAL, &priv->regs->counter_restart);
+
+	return 0;
+}
+
+static int ast_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+	struct ast_wdt_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = ast_wdt_start(dev, 1, flags);
+	if (ret)
+		return ret;
+
+	while (readl(&priv->regs->ctrl) & WDT_CTRL_EN)
+		;
+
+	return ast_wdt_stop(dev);
+}
+
+static int ast_wdt_ofdata_to_platdata(struct udevice *dev)
+{
+	struct ast_wdt_priv *priv = dev_get_priv(dev);
+
+	priv->regs = dev_get_addr_ptr(dev);
+	if (IS_ERR(priv->regs))
+		return PTR_ERR(priv->regs);
+
+	return 0;
+}
+
+static const struct wdt_ops ast_wdt_ops = {
+	.start = ast_wdt_start,
+	.reset = ast_wdt_reset,
+	.stop = ast_wdt_stop,
+	.expire_now = ast_wdt_expire_now,
+};
+
+static const struct udevice_id ast_wdt_ids[] = {
+	{ .compatible = "aspeed,wdt", .data = WDT_AST2500 },
+	{ .compatible = "aspeed,ast2500-wdt", .data = WDT_AST2500 },
+	{ .compatible = "aspeed,ast2400-wdt", .data = WDT_AST2400 },
+	{}
+};
+
+static int ast_wdt_probe(struct udevice *dev)
+{
+	debug("%s() wdt%u\n", __func__, dev->seq);
+	ast_wdt_stop(dev);
+
+	return 0;
+}
+
+U_BOOT_DRIVER(ast_wdt) = {
+	.name = "ast_wdt",
+	.id = UCLASS_WDT,
+	.of_match = ast_wdt_ids,
+	.probe = ast_wdt_probe,
+	.priv_auto_alloc_size = sizeof(struct ast_wdt_priv),
+	.ofdata_to_platdata = ast_wdt_ofdata_to_platdata,
+	.ops = &ast_wdt_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/watchdog/sandbox_wdt.c b/drivers/watchdog/sandbox_wdt.c
new file mode 100644
index 0000000..34d90be
--- /dev/null
+++ b/drivers/watchdog/sandbox_wdt.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/state.h>
+#include <wdt.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int sandbox_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+	struct sandbox_state *state = state_get_current();
+
+	state->wdt.counter = timeout;
+	state->wdt.running = true;
+
+	return 0;
+}
+
+static int sandbox_wdt_stop(struct udevice *dev)
+{
+	struct sandbox_state *state = state_get_current();
+
+	state->wdt.running = false;
+
+	return 0;
+}
+
+static int sandbox_wdt_reset(struct udevice *dev)
+{
+	struct sandbox_state *state = state_get_current();
+
+	state->wdt.reset_count++;
+
+	return 0;
+}
+
+static int sandbox_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+	sandbox_wdt_start(dev, 1, flags);
+
+	return 0;
+}
+
+static int sandbox_wdt_probe(struct udevice *dev)
+{
+	struct sandbox_state *state = state_get_current();
+
+	memset(&state->wdt, 0, sizeof(state->wdt));
+
+	return 0;
+}
+
+static const struct wdt_ops sandbox_wdt_ops = {
+	.start = sandbox_wdt_start,
+	.reset = sandbox_wdt_reset,
+	.stop = sandbox_wdt_stop,
+	.expire_now = sandbox_wdt_expire_now,
+};
+
+static const struct udevice_id sandbox_wdt_ids[] = {
+	{ .compatible = "sandbox,wdt" },
+	{}
+};
+
+U_BOOT_DRIVER(wdt_sandbox) = {
+	.name = "wdt_sandbox",
+	.id = UCLASS_WDT,
+	.of_match = sandbox_wdt_ids,
+	.ops = &sandbox_wdt_ops,
+	.probe = sandbox_wdt_probe,
+};
diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c
new file mode 100644
index 0000000..ab8a64c
--- /dev/null
+++ b/drivers/watchdog/wdt-uclass.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <wdt.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+	const struct wdt_ops *ops = device_get_ops(dev);
+
+	if (!ops->start)
+		return -ENOSYS;
+
+	return ops->start(dev, timeout, flags);
+}
+
+int wdt_stop(struct udevice *dev)
+{
+	const struct wdt_ops *ops = device_get_ops(dev);
+
+	if (!ops->stop)
+		return -ENOSYS;
+
+	return ops->stop(dev);
+}
+
+int wdt_reset(struct udevice *dev)
+{
+	const struct wdt_ops *ops = device_get_ops(dev);
+
+	if (!ops->reset)
+		return -ENOSYS;
+
+	return ops->reset(dev);
+}
+
+int wdt_expire_now(struct udevice *dev, ulong flags)
+{
+	int ret = 0;
+	const struct wdt_ops *ops;
+
+	debug("WDT Resettting: %lu\n", flags);
+	ops = device_get_ops(dev);
+	if (ops->expire_now) {
+		return ops->expire_now(dev, flags);
+	} else {
+		if (!ops->start)
+			return -ENOSYS;
+
+		ret = ops->start(dev, 1, flags);
+		if (ret < 0)
+			return ret;
+
+		hang();
+	}
+
+	return ret;
+}
+
+UCLASS_DRIVER(wdt) = {
+	.id		= UCLASS_WDT,
+	.name		= "wdt",
+};
diff --git a/include/configs/am335x_igep0033.h b/include/configs/am335x_igep003x.h
similarity index 64%
rename from include/configs/am335x_igep0033.h
rename to include/configs/am335x_igep003x.h
index 7ee8ea7..55b511c 100644
--- a/include/configs/am335x_igep0033.h
+++ b/include/configs/am335x_igep003x.h
@@ -11,20 +11,17 @@
  * GNU General Public License for more details.
  */
 
-#ifndef __CONFIG_IGEP0033_H
-#define __CONFIG_IGEP0033_H
+#ifndef __CONFIG_IGEP003X_H
+#define __CONFIG_IGEP003X_H
 
 #define CONFIG_NAND
 #include <configs/ti_am335x_common.h>
 
-/* Mach type */
-#define CONFIG_MACH_TYPE		MACH_TYPE_IGEP0033
-
 /* Clock defines */
 #define V_OSCK				24000000  /* Clock output from T2 */
 #define V_SCLK				(V_OSCK)
 
-#define CONFIG_ENV_SIZE			(128 << 10)	/* 128 KiB */
+#define CONFIG_ENV_SIZE			(96 << 10)	/*  96 KiB */
 
 /* Make the verbose messages from UBI stop printing */
 #define CONFIG_UBI_SILENCE_MSG
@@ -37,7 +34,6 @@
 	DEFAULT_LINUX_BOOT_ENV \
 	"bootdir=/boot\0" \
 	"bootfile=zImage\0" \
-	"dtbfile=am335x-base0033.dtb\0" \
 	"console=ttyO0,115200n8\0" \
 	"mmcdev=0\0" \
 	"mmcroot=/dev/mmcblk0p2 rw\0" \
@@ -51,7 +47,7 @@
 	"importbootenv=echo Importing environment from mmc ...; " \
 		"env import -t ${loadaddr} ${filesize}\0" \
 	"mmcload=load mmc ${mmcdev}:2 ${loadaddr} ${bootdir}/${bootfile}; " \
-		"load mmc ${mmcdev}:2 ${fdtaddr} ${bootdir}/${dtbfile}\0" \
+		"load mmc ${mmcdev}:2 ${fdtaddr} ${bootdir}/${fdtfile}\0" \
 	"mmcboot=mmc dev ${mmcdev}; " \
 		"if mmc rescan; then " \
 			"echo SD/MMC found on device ${mmcdev};" \
@@ -70,11 +66,11 @@
 		"fi;\0" \
 	"mtdids=" MTDIDS_DEFAULT "\0" \
 	"mtdparts=" MTDPARTS_DEFAULT "\0" \
-	"nandroot=ubi0:filesystem rw ubi.mtd=3,2048\0" \
+	"nandroot=ubi0:rootfs rw ubi.mtd=1\0" \
 	"nandrootfstype=ubifs rootwait\0" \
-	"nandload=ubi part filesystem 2048; ubifsmount ubi0; " \
-		"ubifsload ${loadaddr} ${bootdir}/${bootfile}; " \
-		"ubifsload ${fdtaddr} ${bootdir}/${dtbfile} \0" \
+	"nandload=ubi part UBI; " \
+		"ubi read ${loadaddr} kernel; " \
+		"ubi read ${fdtaddr} dtb \0" \
 	"nandargs=setenv bootargs console=${console} " \
 		"${optargs} " \
 		"root=${nandroot} " \
@@ -82,12 +78,33 @@
 	"nandboot=echo Booting from nand ...; " \
 		"run nandargs; " \
 		"run nandload; " \
-		"bootz ${loadaddr} - ${fdtaddr} \0"
+		"bootz ${loadaddr} - ${fdtaddr} \0" \
+	"netload=tftpboot ${loadaddr} ${bootfile}; " \
+		"tftpboot ${fdtaddr} ${fdtfile} \0" \
+	"netargs=setenv bootargs console=${console} " \
+		"${optargs} " \
+		"root=/dev/nfs " \
+		"ip=${ipaddr} nfsroot=${serverip}:${rootnfs},v3,tcp \0" \
+	"netboot=echo Booting from net ...; " \
+		"run netargs; " \
+		"run netload; " \
+		"bootz ${loadaddr} - ${fdtaddr} \0" \
+	"findfdt="\
+		"if test ${board_name} = igep0033; then " \
+			"setenv fdtfile am335x-igep-base0033.dtb; fi; " \
+		"if test ${board_name} = igep0034; then " \
+			"setenv fdtfile am335x-igep-base0040.dtb; fi; " \
+		"if test ${board_name} = igep0034-lite; then " \
+			"setenv fdtfile am335x-igep-base0040-lite.dtb; fi; " \
+		"if test ${fdtfile} = ''; then " \
+			"echo WARNING: Could not determine device tree to use; fi; \0"
 #endif
 
 #define CONFIG_BOOTCOMMAND \
+	"run findfdt;" \
 	"run mmcboot;" \
-	"run nandboot;"
+	"run nandboot;" \
+	"run netboot;"
 
 /* NS16550 Configuration */
 #define CONFIG_SYS_NS16550_COM1		0x44e09000	/* UART0 */
@@ -100,12 +117,6 @@
 /* NAND support */
 #define CONFIG_NAND_OMAP_ELM
 #define CONFIG_SYS_NAND_ONFI_DETECTION	1
-#define CONFIG_SYS_ENV_SECT_SIZE	(128 << 10)	/* 128 KiB */
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
-#define CONFIG_ENV_IS_IN_NAND
-#define CONFIG_ENV_OFFSET		0x180000 /* environment starts here */
-#define CONFIG_ENV_ADDR_REDUND		(CONFIG_ENV_OFFSET + CONFIG_SYS_ENV_SECT_SIZE)
-#define CONFIG_ENV_SIZE_REDUND		(CONFIG_ENV_SIZE)
 
 #define CONFIG_MTD_PARTITIONS
 #define CONFIG_MTD_DEVICE
@@ -113,13 +124,32 @@
 #define CONFIG_LZO
 
 #define MTDIDS_DEFAULT			"nand0=omap2-nand.0"
-#define MTDPARTS_DEFAULT		"mtdparts=omap2-nand.0:512k(spl),"\
-					"1m(uboot),256k(environment),"\
-					"-(filesystem)"
+#define MTDPARTS_DEFAULT		"mtdparts=omap2-nand.0:512k(SPL),-(UBI)"
 
 /* SPL */
 #define CONFIG_SPL_LDSCRIPT		"arch/arm/mach-omap2/am33xx/u-boot-spl.lds"
 
+/* UBI configuration */
+#define CONFIG_SPL_UBI			1
+#define CONFIG_SPL_UBI_MAX_VOL_LEBS	256
+#define CONFIG_SPL_UBI_MAX_PEB_SIZE	(256*1024)
+#define CONFIG_SPL_UBI_MAX_PEBS		4096
+#define CONFIG_SPL_UBI_VOL_IDS		8
+#define CONFIG_SPL_UBI_LOAD_MONITOR_ID	0
+#define CONFIG_SPL_UBI_LOAD_KERNEL_ID	3
+#define CONFIG_SPL_UBI_LOAD_ARGS_ID	4
+#define CONFIG_SPL_UBI_PEB_OFFSET	4
+#define CONFIG_SPL_UBI_VID_OFFSET	512
+#define CONFIG_SPL_UBI_LEB_START	2048
+#define CONFIG_SPL_UBI_INFO_ADDR	0x88080000
+
+/* environment organization */
+#define CONFIG_ENV_IS_IN_UBI		1
+#define CONFIG_ENV_UBI_PART		"UBI"
+#define CONFIG_ENV_UBI_VOLUME		"config"
+#define CONFIG_ENV_UBI_VOLUME_REDUND	"config_r"
+
+/* NAND config */
 #define CONFIG_SYS_NAND_5_ADDR_CYCLE
 #define CONFIG_SYS_NAND_PAGE_COUNT	(CONFIG_SYS_NAND_BLOCK_SIZE / \
 					 CONFIG_SYS_NAND_PAGE_SIZE)
@@ -139,8 +169,4 @@
 #define CONFIG_SYS_NAND_ECCBYTES	14
 #define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_BCH8_CODE_HW
 
-#define	CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_TEXT_BASE
-
-#define CONFIG_SYS_NAND_U_BOOT_OFFS	0x80000
-
-#endif	/* ! __CONFIG_IGEP0033_H */
+#endif	/* ! __CONFIG_IGEP003X_H */
diff --git a/include/configs/am57xx_evm.h b/include/configs/am57xx_evm.h
index dc7a370..6962039 100644
--- a/include/configs/am57xx_evm.h
+++ b/include/configs/am57xx_evm.h
@@ -14,8 +14,6 @@
 
 #include <environment/ti/dfu.h>
 
-#define CONFIG_DRA7XX
-
 #ifdef CONFIG_SPL_BUILD
 #define CONFIG_IODELAY_RECALIBRATION
 #endif
diff --git a/include/configs/cl-som-am57x.h b/include/configs/cl-som-am57x.h
index a4950f3..3000453 100644
--- a/include/configs/cl-som-am57x.h
+++ b/include/configs/cl-som-am57x.h
@@ -11,8 +11,6 @@
 #ifndef __CONFIG_CL_SOM_AM57X_H
 #define __CONFIG_CL_SOM_AM57X_H
 
-#define CONFIG_DRA7XX
-
 #define CONFIG_NR_DRAM_BANKS		2
 
 #define CONSOLEDEV			"ttyO2"
@@ -84,6 +82,8 @@
 #define CONFIG_SYS_I2C_PCA953X_ADDR     0x20
 #define CONFIG_SYS_I2C_PCA953X_WIDTH    { {0x20, 16} }
 
+#endif /* !CONFIG_SPL_BUILD */
+
 /* USB xHCI HOST */
 #define CONFIG_USB_XHCI_OMAP
 #define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
@@ -98,8 +98,6 @@
 #define CONFIG_USB_ETHER_ASIX
 #define CONFIG_USB_ETHER_MCS7830
 
-#endif /* !CONFIG_SPL_BUILD */
-
 /* CPSW Ethernet */
 #define CONFIG_DRIVER_TI_CPSW
 #define CONFIG_MII
diff --git a/include/configs/dra7xx_evm.h b/include/configs/dra7xx_evm.h
index 7d6f7ff..a9ca023 100644
--- a/include/configs/dra7xx_evm.h
+++ b/include/configs/dra7xx_evm.h
@@ -14,8 +14,6 @@
 
 #include <environment/ti/dfu.h>
 
-#define CONFIG_DRA7XX
-
 #ifdef CONFIG_SPL_BUILD
 #define CONFIG_IODELAY_RECALIBRATION
 #endif
diff --git a/include/configs/meson-gxbb-common.h b/include/configs/meson-gxbb-common.h
index fab2e67..f1734c0 100644
--- a/include/configs/meson-gxbb-common.h
+++ b/include/configs/meson-gxbb-common.h
@@ -55,4 +55,6 @@
 	MESON_FDTFILE_SETTING \
 	BOOTENV
 
+#define CONFIG_SYS_BOOTM_LEN    (64 << 20)      /* 64 MiB */
+
 #endif /* __MESON_GXBB_COMMON_CONFIG_H */
diff --git a/include/configs/stm32f746-disco.h b/include/configs/stm32f746-disco.h
index de3d661..1ee5815 100644
--- a/include/configs/stm32f746-disco.h
+++ b/include/configs/stm32f746-disco.h
@@ -16,11 +16,6 @@
  * Configuration of the external SDRAM memory
  */
 #define CONFIG_NR_DRAM_BANKS		1
-#define CONFIG_SYS_RAM_SIZE		(8 * 1024 * 1024)
-#define CONFIG_SYS_RAM_CS		1
-#define CONFIG_SYS_RAM_FREQ_DIV		2
-#define CONFIG_SYS_RAM_BASE		0xC0000000
-#define CONFIG_SYS_SDRAM_BASE		CONFIG_SYS_RAM_BASE
 #define CONFIG_SYS_LOAD_ADDR		0xC0400000
 #define CONFIG_LOADADDR			0xC0400000
 
@@ -30,11 +25,9 @@
 #define CONFIG_ENV_IS_NOWHERE
 #define CONFIG_ENV_SIZE			(8 << 10)
 
-#define CONFIG_STM32_GPIO
 #define CONFIG_STM32_FLASH
 #define CONFIG_STM32X7_SERIAL
 
-#define CONFIG_DESIGNWARE_ETH
 #define CONFIG_DW_GMAC_DEFAULT_DMA_PBL	(8)
 #define CONFIG_DW_ALTDESCRIPTOR
 #define CONFIG_MII
@@ -73,7 +66,7 @@
 #define CONFIG_SYS_LONGHELP
 #define CONFIG_AUTO_COMPLETE
 #define CONFIG_CMDLINE_EDITING
-
-#define CONFIG_CMD_MEM
 #define CONFIG_CMD_CACHE
+#define CONFIG_BOARD_LATE_INIT
+#define CONFIG_DISPLAY_BOARDINFO
 #endif /* __CONFIG_H */
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 64a1900..997a92c 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -211,11 +211,13 @@
 #if defined CONFIG_I2C0_ENABLE || defined CONFIG_I2C1_ENABLE || \
     defined CONFIG_I2C2_ENABLE || defined CONFIG_I2C3_ENABLE || \
     defined CONFIG_I2C4_ENABLE || defined CONFIG_R_I2C_ENABLE
-#define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_MVTWSI
+#ifndef CONFIG_DM_I2C
+#define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_SPEED		400000
 #define CONFIG_SYS_I2C_SLAVE		0x7f
 #endif
+#endif
 
 #if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD)
 #define CONFIG_SYS_I2C_SOFT
@@ -473,6 +475,11 @@
 #define CONSOLE_STDOUT_SETTINGS \
 	"stdout=serial,vga\0" \
 	"stderr=serial,vga\0"
+#elif CONFIG_DM_VIDEO
+#define CONFIG_SYS_WHITE_ON_BLACK
+#define CONSOLE_STDOUT_SETTINGS \
+	"stdout=serial,vidconsole\0" \
+	"stderr=serial,vidconsole\0"
 #else
 #define CONSOLE_STDOUT_SETTINGS \
 	"stdout=serial\0" \
diff --git a/include/configs/ti_armv7_keystone2.h b/include/configs/ti_armv7_keystone2.h
index 5d2a7ab..868464c 100644
--- a/include/configs/ti_armv7_keystone2.h
+++ b/include/configs/ti_armv7_keystone2.h
@@ -318,7 +318,7 @@
 #ifndef CONFIG_SOC_K2G
 #define CONFIG_SYS_HZ_CLOCK		ks_clk_get_rate(KS2_CLK1_6)
 #else
-#define CONFIG_SYS_HZ_CLOCK		external_clk[sys_clk]
+#define CONFIG_SYS_HZ_CLOCK		get_external_clk(sys_clk)
 #endif
 
 #endif /* __CONFIG_KS2_EVM_H */
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 1b635e4..4e7cc93 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -84,6 +84,7 @@
 	UCLASS_VIDEO,		/* Video or LCD device */
 	UCLASS_VIDEO_BRIDGE,	/* Video bridge, e.g. DisplayPort to LVDS */
 	UCLASS_VIDEO_CONSOLE,	/* Text console driver for video device */
+	UCLASS_WDT,		/* Watchdot Timer driver */
 
 	UCLASS_COUNT,
 	UCLASS_INVALID = -1,
diff --git a/include/dt-bindings/clock/ast2500-scu.h b/include/dt-bindings/clock/ast2500-scu.h
index ca58b12..e2d7aaf 100644
--- a/include/dt-bindings/clock/ast2500-scu.h
+++ b/include/dt-bindings/clock/ast2500-scu.h
@@ -27,3 +27,5 @@
 #define PCLK_UART3	503
 #define PCLK_UART4	504
 #define PCLK_UART5	505
+#define PCLK_MAC1	506
+#define PCLK_MAC2	507
diff --git a/include/dt-bindings/memory/stm32-sdram.h b/include/dt-bindings/memory/stm32-sdram.h
new file mode 100644
index 0000000..89b719a
--- /dev/null
+++ b/include/dt-bindings/memory/stm32-sdram.h
@@ -0,0 +1,37 @@
+#ifndef DT_BINDINGS_STM32_SDRAM_H
+#define DT_BINDINGS_STM32_SDRAM_H
+
+#define NO_COL_8	0x0
+#define NO_COL_9	0x1
+#define NO_COL_10	0x2
+#define NO_COL_11	0x3
+
+#define NO_ROW_11	0x0
+#define NO_ROW_12	0x1
+#define NO_ROW_13	0x2
+
+#define MWIDTH_8	0x0
+#define MWIDTH_16	0x1
+#define MWIDTH_32	0x2
+#define BANKS_2		0x0
+#define BANKS_4		0x1
+#define CAS_1		0x1
+#define CAS_2		0x2
+#define CAS_3		0x3
+#define SDCLK_2		0x2
+#define RD_BURST_EN	0x1
+#define RD_BURST_DIS	0x0
+#define RD_PIPE_DL_0	0x0
+#define RD_PIPE_DL_1	0x1
+#define RD_PIPE_DL_2	0x2
+
+/* Timing = value +1 cycles */
+#define TMRD_2		(2 - 1)
+#define TXSR_6		(6 - 1)
+#define TRAS_4		(4 - 1)
+#define TRC_6		(6 - 1)
+#define TWR_2		(2 - 1)
+#define TRP_2		(2 - 1)
+#define TRCD_2		(2 - 1)
+
+#endif
diff --git a/include/dt-bindings/reset/ast2500-reset.h b/include/dt-bindings/reset/ast2500-reset.h
new file mode 100644
index 0000000..eb5e1db
--- /dev/null
+++ b/include/dt-bindings/reset/ast2500-reset.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ABI_MACH_ASPEED_AST2500_RESET_H_
+#define _ABI_MACH_ASPEED_AST2500_RESET_H_
+
+/*
+ * The values are intentionally layed out as flags in
+ * WDT reset parameter.
+ */
+
+#define AST_RESET_SOC			0
+#define AST_RESET_CHIP			1
+#define AST_RESET_CPU			(1 << 1)
+#define AST_RESET_ARM			(1 << 2)
+#define AST_RESET_COPROC		(1 << 3)
+#define AST_RESET_SDRAM			(1 << 4)
+#define AST_RESET_AHB			(1 << 5)
+#define AST_RESET_I2C			(1 << 6)
+#define AST_RESET_MAC1			(1 << 7)
+#define AST_RESET_MAC2			(1 << 8)
+#define AST_RESET_GCRT			(1 << 9)
+#define AST_RESET_USB20			(1 << 10)
+#define AST_RESET_USB11_HOST		(1 << 11)
+#define AST_RESET_USB11_HID		(1 << 12)
+#define AST_RESET_VIDEO			(1 << 13)
+#define AST_RESET_HAC			(1 << 14)
+#define AST_RESET_LPC			(1 << 15)
+#define AST_RESET_SDIO			(1 << 16)
+#define AST_RESET_MIC			(1 << 17)
+#define AST_RESET_CRT2D			(1 << 18)
+#define AST_RESET_PWM			(1 << 19)
+#define AST_RESET_PECI			(1 << 20)
+#define AST_RESET_JTAG			(1 << 21)
+#define AST_RESET_ADC			(1 << 22)
+#define AST_RESET_GPIO			(1 << 23)
+#define AST_RESET_MCTP			(1 << 24)
+#define AST_RESET_XDMA			(1 << 25)
+#define AST_RESET_SPI			(1 << 26)
+#define AST_RESET_MISC			(1 << 27)
+
+#endif  /* _ABI_MACH_ASPEED_AST2500_RESET_H_ */
diff --git a/include/linux/usb/xhci-omap.h b/include/linux/usb/xhci-omap.h
index 9de80d7..f038ddb 100644
--- a/include/linux/usb/xhci-omap.h
+++ b/include/linux/usb/xhci-omap.h
@@ -10,14 +10,16 @@
 #ifndef _ASM_ARCH_XHCI_OMAP_H_
 #define _ASM_ARCH_XHCI_OMAP_H_
 
-#ifdef CONFIG_TARGET_DRA7XX_EVM
+#ifdef CONFIG_DRA7XX
+#if CONFIG_USB_XHCI_DRA7XX_INDEX == 1
 #define OMAP_XHCI_BASE 0x488d0000
 #define OMAP_OCP1_SCP_BASE 0x4A081000
 #define OMAP_OTG_WRAPPER_BASE 0x488c0000
-#elif defined CONFIG_TARGET_AM57XX_EVM
+#elif CONFIG_USB_XHCI_DRA7XX_INDEX == 0
 #define OMAP_XHCI_BASE 0x48890000
 #define OMAP_OCP1_SCP_BASE 0x4A084c00
 #define OMAP_OTG_WRAPPER_BASE 0x48880000
+#endif /* CONFIG_USB_XHCI_DRA7XX_INDEX == 1 */
 #elif defined CONFIG_AM43XX
 #define OMAP_XHCI_BASE 0x483d0000
 #define OMAP_OCP1_SCP_BASE 0x483E8000
diff --git a/include/spl.h b/include/spl.h
index 2e5b885..d1638e9 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -27,6 +27,7 @@
 	ulong entry_point;
 	u32 size;
 	u32 flags;
+	void *arg;
 };
 
 /*
@@ -106,10 +107,8 @@
  * This jumps into a Linux kernel using the information in @spl_image.
  *
  * @spl_image: Image description to set up
- * @arg: Argument to pass to Linux (typically a device tree pointer)
  */
-void __noreturn jump_to_image_linux(struct spl_image_info *spl_image,
-				    void *arg);
+void __noreturn jump_to_image_linux(struct spl_image_info *spl_image);
 
 /**
  * spl_start_uboot() - Check if SPL should start the kernel or U-Boot
diff --git a/include/wdt.h b/include/wdt.h
new file mode 100644
index 0000000..0b5f058
--- /dev/null
+++ b/include/wdt.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _WDT_H_
+#define _WDT_H_
+
+/*
+ * Implement a simple watchdog uclass. Watchdog is basically a timer that
+ * is used to detect or recover from malfunction. During normal operation
+ * the watchdog would be regularly reset to prevent it from timing out.
+ * If, due to a hardware fault or program error, the computer fails to reset
+ * the watchdog, the timer will elapse and generate a timeout signal.
+ * The timeout signal is used to initiate corrective action or actions,
+ * which typically include placing the system in a safe, known state.
+ */
+
+/*
+ * Start the timer
+ *
+ * @dev: WDT Device
+ * @timeout: Number of ticks before timer expires
+ * @flags: Driver specific flags. This might be used to specify
+ * which action needs to be executed when the timer expires
+ * @return: 0 if OK, -ve on error
+ */
+int wdt_start(struct udevice *dev, u64 timeout, ulong flags);
+
+/*
+ * Stop the timer, thus disabling the Watchdog. Use wdt_start to start it again.
+ *
+ * @dev: WDT Device
+ * @return: 0 if OK, -ve on error
+ */
+int wdt_stop(struct udevice *dev);
+
+/*
+ * Reset the timer, typically restoring the counter to
+ * the value configured by start()
+ *
+ * @dev: WDT Device
+ * @return: 0 if OK, -ve on error
+ */
+int wdt_reset(struct udevice *dev);
+
+/*
+ * Expire the timer, thus executing its action immediately.
+ * This is typically used to reset the board or peripherals.
+ *
+ * @dev: WDT Device
+ * @flags: Driver specific flags
+ * @return 0 if OK -ve on error. If wdt action is system reset,
+ * this function may never return.
+ */
+int wdt_expire_now(struct udevice *dev, ulong flags);
+
+/*
+ * struct wdt_ops - Driver model wdt operations
+ *
+ * The uclass interface is implemented by all wdt devices which use
+ * driver model.
+ */
+struct wdt_ops {
+	/*
+	 * Start the timer
+	 *
+	 * @dev: WDT Device
+	 * @timeout: Number of ticks before the timer expires
+	 * @flags: Driver specific flags. This might be used to specify
+	 * which action needs to be executed when the timer expires
+	 * @return: 0 if OK, -ve on error
+	 */
+	int (*start)(struct udevice *dev, u64 timeout, ulong flags);
+	/*
+	 * Stop the timer
+	 *
+	 * @dev: WDT Device
+	 * @return: 0 if OK, -ve on error
+	 */
+	int (*stop)(struct udevice *dev);
+	/*
+	 * Reset the timer, typically restoring the counter to
+	 * the value configured by start()
+	 *
+	 * @dev: WDT Device
+	 * @return: 0 if OK, -ve on error
+	 */
+	int (*reset)(struct udevice *dev);
+	/*
+	 * Expire the timer, thus executing the action immediately (optional)
+	 *
+	 * If this function is not provided, a default implementation
+	 * will be used, which sets the counter to 1
+	 * and waits forever. This is good enough for system level
+	 * reset, where the function is not expected to return, but might not be
+	 * good enough for other use cases.
+	 *
+	 * @dev: WDT Device
+	 * @flags: Driver specific flags
+	 * @return 0 if OK -ve on error. May not return.
+	 */
+	int (*expire_now)(struct udevice *dev, ulong flags);
+};
+
+#endif  /* _WDT_H_ */
diff --git a/lib/circbuf.c b/lib/circbuf.c
index 9848da3..6ed0516 100644
--- a/lib/circbuf.c
+++ b/lib/circbuf.c
@@ -41,11 +41,13 @@
 int buf_pop (circbuf_t * buf, char *dest, unsigned int len)
 {
 	unsigned int i;
-	char *p = buf->top;
+	char *p;
 
 	assert (buf != NULL);
 	assert (dest != NULL);
 
+	p = buf->top;
+
 	/* Cap to number of bytes in buffer */
 	if (len > buf->size)
 		len = buf->size;
@@ -69,11 +71,13 @@
 {
 	/* NOTE:  this function allows push to overwrite old data. */
 	unsigned int i;
-	char *p = buf->tail;
+	char *p;
 
 	assert (buf != NULL);
 	assert (src != NULL);
 
+	p = buf->tail;
+
 	for (i = 0; i < len; i++) {
 		*p++ = src[i];
 		if (p == buf->end) {
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index ed349b9..1704f9c 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -664,7 +664,6 @@
 CONFIG_DP_DDR_CTRL
 CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR
 CONFIG_DP_DDR_NUM_CTRLS
-CONFIG_DRA7XX
 CONFIG_DRAM_2G
 CONFIG_DRAM_TIMINGS_
 CONFIG_DRIVER_AT91EMAC
diff --git a/test/dm/Makefile b/test/dm/Makefile
index e956915..b15f1d0 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -42,4 +42,5 @@
 obj-$(CONFIG_DM_VIDEO) += video.o
 obj-$(CONFIG_ADC) += adc.o
 obj-$(CONFIG_SPMI) += spmi.o
+obj-$(CONFIG_WDT) += wdt.o
 endif
diff --git a/test/dm/wdt.c b/test/dm/wdt.c
new file mode 100644
index 0000000..2ecfcea
--- /dev/null
+++ b/test/dm/wdt.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <wdt.h>
+#include <asm/state.h>
+#include <asm/test.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+/* Test that watchdog driver functions are called */
+static int dm_test_wdt_base(struct unit_test_state *uts)
+{
+	struct sandbox_state *state = state_get_current();
+	struct udevice *dev;
+	const u64 timeout = 42;
+
+	ut_assertok(uclass_get_device(UCLASS_WDT, 0, &dev));
+	ut_asserteq(0, state->wdt.counter);
+	ut_asserteq(false, state->wdt.running);
+
+	ut_assertok(wdt_start(dev, timeout, 0));
+	ut_asserteq(timeout, state->wdt.counter);
+	ut_asserteq(true, state->wdt.running);
+
+	uint reset_count = state->wdt.reset_count;
+	ut_assertok(wdt_reset(dev));
+	ut_asserteq(reset_count + 1, state->wdt.reset_count);
+	ut_asserteq(true, state->wdt.running);
+
+	ut_assertok(wdt_stop(dev));
+	ut_asserteq(false, state->wdt.running);
+
+	return 0;
+}
+DM_TEST(dm_test_wdt_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/tools/moveconfig.py b/tools/moveconfig.py
index dcca0ec..95ef352 100755
--- a/tools/moveconfig.py
+++ b/tools/moveconfig.py
@@ -435,6 +435,20 @@
     matched += extended_matched
     matched.sort()
 
+def confirm(options, prompt):
+    if not options.yes:
+        while True:
+            choice = raw_input('{} [y/n]: '.format(prompt))
+            choice = choice.lower()
+            print choice
+            if choice == 'y' or choice == 'n':
+                break
+
+        if choice == 'n':
+            return False
+
+    return True
+
 def cleanup_one_header(header_path, patterns, options):
     """Clean regex-matched lines away from a file.
 
@@ -502,15 +516,8 @@
       configs: A list of CONFIGs to remove.
       options: option flags.
     """
-    if not options.yes:
-        while True:
-            choice = raw_input('Clean up headers? [y/n]: ').lower()
-            print choice
-            if choice == 'y' or choice == 'n':
-                break
-
-        if choice == 'n':
-            return
+    if not confirm(options, 'Clean up headers?'):
+        return
 
     patterns = []
     for config in configs:
@@ -582,16 +589,8 @@
       configs: A list of CONFIGs to remove.
       options: option flags.
     """
-    if not options.yes:
-        while True:
-            choice = (raw_input('Clean up CONFIG_SYS_EXTRA_OPTIONS? [y/n]: ').
-                      lower())
-            print choice
-            if choice == 'y' or choice == 'n':
-                break
-
-        if choice == 'n':
-            return
+    if not confirm(options, 'Clean up CONFIG_SYS_EXTRA_OPTIONS?'):
+        return
 
     configs = [ config[len('CONFIG_'):] for config in configs ]
 
@@ -601,6 +600,65 @@
         cleanup_one_extra_option(os.path.join('configs', defconfig), configs,
                                  options)
 
+def cleanup_whitelist(configs, options):
+    """Delete config whitelist entries
+
+    Arguments:
+      configs: A list of CONFIGs to remove.
+      options: option flags.
+    """
+    if not confirm(options, 'Clean up whitelist entries?'):
+        return
+
+    with open(os.path.join('scripts', 'config_whitelist.txt')) as f:
+        lines = f.readlines()
+
+    lines = [x for x in lines if x.strip() not in configs]
+
+    with open(os.path.join('scripts', 'config_whitelist.txt'), 'w') as f:
+        f.write(''.join(lines))
+
+def find_matching(patterns, line):
+    for pat in patterns:
+        if pat.search(line):
+            return True
+    return False
+
+def cleanup_readme(configs, options):
+    """Delete config description in README
+
+    Arguments:
+      configs: A list of CONFIGs to remove.
+      options: option flags.
+    """
+    if not confirm(options, 'Clean up README?'):
+        return
+
+    patterns = []
+    for config in configs:
+        patterns.append(re.compile(r'^\s+%s' % config))
+
+    with open('README') as f:
+        lines = f.readlines()
+
+    found = False
+    newlines = []
+    for line in lines:
+        if not found:
+            found = find_matching(patterns, line)
+            if found:
+                continue
+
+        if found and re.search(r'^\s+CONFIG', line):
+            found = False
+
+        if not found:
+            newlines.append(line)
+
+    with open('README', 'w') as f:
+        f.write(''.join(newlines))
+
+
 ### classes ###
 class Progress:
 
@@ -1297,6 +1355,8 @@
     if configs:
         cleanup_headers(configs, options)
         cleanup_extra_options(configs, options)
+        cleanup_whitelist(configs, options)
+        cleanup_readme(configs, options)
 
     if options.commit:
         subprocess.call(['git', 'add', '-u'])
diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c
index 3c9d134..df968eb 100644
--- a/tools/relocate-rela.c
+++ b/tools/relocate-rela.c
@@ -27,9 +27,11 @@
 {
 	va_list args;
 
-	va_start(args, fmt);
-	if (debug_en)
+	if (debug_en) {
+		va_start(args, fmt);
 		vprintf(fmt, args);
+		va_end(args);
+	}
 }
 
 static bool supported_rela(Elf64_Rela *rela)
diff --git a/tools/sunxi-spl-image-builder.c b/tools/sunxi-spl-image-builder.c
index d538a38..a367f11 100644
--- a/tools/sunxi-spl-image-builder.c
+++ b/tools/sunxi-spl-image-builder.c
@@ -433,7 +433,7 @@
 			break;
 		case 'c':
 			info.ecc_strength = strtol(optarg, &endptr, 0);
-			if (endptr || *endptr == '/')
+			if (*endptr == '/')
 				info.ecc_step_size = strtol(endptr + 1, NULL, 0);
 			break;
 		case 'p':