Merge tag 'dm-9oct18' of git://git.denx.de/u-boot-dm

Test improvements to tidy up output and drop duplicate tests
Sandbox SPL/TPL support
Various dm-related improvements
diff --git a/arch/arm/cpu/arm920t/ep93xx/timer.c b/arch/arm/cpu/arm920t/ep93xx/timer.c
index 5f3609a..49bf49b 100644
--- a/arch/arm/cpu/arm920t/ep93xx/timer.c
+++ b/arch/arm/cpu/arm920t/ep93xx/timer.c
@@ -66,14 +66,9 @@
 	return sys_ticks;
 }
 
-unsigned long get_timer_masked(void)
-{
-	return get_ticks();
-}
-
 unsigned long get_timer(unsigned long base)
 {
-	return get_timer_masked() - base;
+	return get_ticks() - base;
 }
 
 void __udelay(unsigned long usec)
diff --git a/arch/arm/cpu/arm920t/imx/timer.c b/arch/arm/cpu/arm920t/imx/timer.c
index cd9b546..96fff3f 100644
--- a/arch/arm/cpu/arm920t/imx/timer.c
+++ b/arch/arm/cpu/arm920t/imx/timer.c
@@ -36,17 +36,17 @@
 /*
  * timer without interrupts
  */
-ulong get_timer (ulong base)
+static ulong get_timer_masked (void)
 {
-	return get_timer_masked() - base;
+	return TCN1;
 }
 
-ulong get_timer_masked (void)
+ulong get_timer (ulong base)
 {
-	return TCN1;
+	return get_timer_masked() - base;
 }
 
-void udelay_masked (unsigned long usec)
+void __udelay (unsigned long usec)
 {
 	ulong endtime = get_timer_masked() + usec;
 	signed long diff;
@@ -57,11 +57,6 @@
 	} while (diff >= 0);
 }
 
-void __udelay (unsigned long usec)
-{
-	udelay_masked(usec);
-}
-
 /*
  * This function is derived from PowerPC code (read timebase as long long).
  * On ARM it just returns the timer value.
diff --git a/arch/arm/cpu/arm926ejs/armada100/timer.c b/arch/arm/cpu/arm926ejs/armada100/timer.c
index f10f678..d2ecbd0 100644
--- a/arch/arm/cpu/arm926ejs/armada100/timer.c
+++ b/arch/arm/cpu/arm926ejs/armada100/timer.c
@@ -61,7 +61,7 @@
 	return(readl(&armd1timers->cvwr));
 }
 
-ulong get_timer_masked(void)
+static ulong get_timer_masked(void)
 {
 	ulong now = read_timer();
 
diff --git a/arch/arm/cpu/arm926ejs/mx27/timer.c b/arch/arm/cpu/arm926ejs/mx27/timer.c
index 9399320..94b5d45 100644
--- a/arch/arm/cpu/arm926ejs/mx27/timer.c
+++ b/arch/arm/cpu/arm926ejs/mx27/timer.c
@@ -126,7 +126,7 @@
 	return timestamp;
 }
 
-ulong get_timer_masked(void)
+static ulong get_timer_masked(void)
 {
 	/*
 	 * get_ticks() returns a long long (64 bit), it wraps in
diff --git a/arch/arm/cpu/arm926ejs/mxs/timer.c b/arch/arm/cpu/arm926ejs/mxs/timer.c
index 517cadb..7492ba4 100644
--- a/arch/arm/cpu/arm926ejs/mxs/timer.c
+++ b/arch/arm/cpu/arm926ejs/mxs/timer.c
@@ -110,14 +110,9 @@
 	return timestamp;
 }
 
-ulong get_timer_masked(void)
-{
-	return tick_to_time(get_ticks());
-}
-
 ulong get_timer(ulong base)
 {
-	return get_timer_masked() - base;
+	return tick_to_time(get_ticks()) - base;
 }
 
 /* We use the HW_DIGCTL_MICROSECONDS register for sub-millisecond timer. */
diff --git a/arch/arm/cpu/arm926ejs/spear/timer.c b/arch/arm/cpu/arm926ejs/spear/timer.c
index e9ba87a..e7b5bda 100644
--- a/arch/arm/cpu/arm926ejs/spear/timer.c
+++ b/arch/arm/cpu/arm926ejs/spear/timer.c
@@ -21,6 +21,8 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static ulong get_timer_masked(void);
+
 #define timestamp gd->arch.tbl
 #define lastdec gd->arch.lastinc
 
@@ -82,7 +84,7 @@
 		;
 }
 
-ulong get_timer_masked(void)
+static ulong get_timer_masked(void)
 {
 	ulong now = READ_TIMER();
 
@@ -98,11 +100,6 @@
 	return timestamp;
 }
 
-void udelay_masked(unsigned long usec)
-{
-	return udelay(usec);
-}
-
 /*
  * This function is derived from PowerPC code (read timebase as long long).
  * On ARM it just returns the timer value.
diff --git a/arch/arm/cpu/armv7/ls102xa/timer.c b/arch/arm/cpu/armv7/ls102xa/timer.c
index 35a557b..e79360a 100644
--- a/arch/arm/cpu/armv7/ls102xa/timer.c
+++ b/arch/arm/cpu/armv7/ls102xa/timer.c
@@ -90,14 +90,9 @@
 	return now;
 }
 
-unsigned long get_timer_masked(void)
-{
-	return tick_to_time(get_ticks());
-}
-
 unsigned long get_timer(ulong base)
 {
-	return get_timer_masked() - base;
+	return tick_to_time(get_ticks()) - base;
 }
 
 /* delay x useconds and preserve advance timstamp value */
diff --git a/arch/arm/cpu/armv7/s5p-common/timer.c b/arch/arm/cpu/armv7/s5p-common/timer.c
index b37892c..0048cd8 100644
--- a/arch/arm/cpu/armv7/s5p-common/timer.c
+++ b/arch/arm/cpu/armv7/s5p-common/timer.c
@@ -19,6 +19,7 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 unsigned long get_current_tick(void);
+static void reset_timer_masked(void);
 
 /* macro to read the 16 bit timer */
 static inline struct s5p_timer *s5p_get_base_timer(void)
@@ -106,7 +107,7 @@
 		;
 }
 
-void reset_timer_masked(void)
+static void reset_timer_masked(void)
 {
 	struct s5p_timer *const timer = s5p_get_base_timer();
 
diff --git a/arch/arm/cpu/armv7/stv0991/timer.c b/arch/arm/cpu/armv7/stv0991/timer.c
index 5784b06..d1b763d 100644
--- a/arch/arm/cpu/armv7/stv0991/timer.c
+++ b/arch/arm/cpu/armv7/stv0991/timer.c
@@ -21,6 +21,8 @@
 #define timestamp gd->arch.tbl
 #define lastdec gd->arch.lastinc
 
+static ulong get_timer_masked(void);
+
 int timer_init(void)
 {
 	/* Timer1 clock configuration */
@@ -73,7 +75,7 @@
 		;
 }
 
-ulong get_timer_masked(void)
+static ulong get_timer_masked(void)
 {
 	ulong now = READ_TIMER();
 
@@ -89,11 +91,6 @@
 	return timestamp;
 }
 
-void udelay_masked(unsigned long usec)
-{
-	return udelay(usec);
-}
-
 /*
  * This function is derived from PowerPC code (read timebase as long long).
  * On ARM it just returns the timer value.
diff --git a/arch/arm/cpu/armv7/sunxi/timer.c b/arch/arm/cpu/armv7/sunxi/timer.c
index 0f8ab0e..304c1ac 100644
--- a/arch/arm/cpu/armv7/sunxi/timer.c
+++ b/arch/arm/cpu/armv7/sunxi/timer.c
@@ -55,12 +55,7 @@
 }
 
 /* timer without interrupts */
-ulong get_timer(ulong base)
-{
-	return get_timer_masked() - base;
-}
-
-ulong get_timer_masked(void)
+static ulong get_timer_masked(void)
 {
 	/* current tick value */
 	ulong now = TICKS_TO_HZ(read_timer());
@@ -77,6 +72,11 @@
 	return gd->arch.tbl;
 }
 
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
 /* delay x useconds */
 void __udelay(unsigned long usec)
 {
diff --git a/arch/arm/cpu/armv7/vf610/timer.c b/arch/arm/cpu/armv7/vf610/timer.c
index 6e1308e..821a279 100644
--- a/arch/arm/cpu/armv7/vf610/timer.c
+++ b/arch/arm/cpu/armv7/vf610/timer.c
@@ -57,14 +57,9 @@
 	return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
 }
 
-ulong get_timer_masked(void)
-{
-	return tick_to_time(get_ticks());
-}
-
 ulong get_timer(ulong base)
 {
-	return get_timer_masked() - base;
+	return tick_to_time(get_ticks()) - base;
 }
 
 /* delay x useconds AND preserve advance timstamp value */
diff --git a/arch/arm/cpu/sa1100/timer.c b/arch/arm/cpu/sa1100/timer.c
index 12514e4..0fac5c1 100644
--- a/arch/arm/cpu/sa1100/timer.c
+++ b/arch/arm/cpu/sa1100/timer.c
@@ -12,22 +12,17 @@
 #include <common.h>
 #include <SA-1100.h>
 
-ulong get_timer (ulong base)
-{
-	return get_timer_masked ();
-}
-
-void __udelay (unsigned long usec)
+static ulong get_timer_masked (void)
 {
-	udelay_masked (usec);
+	return OSCR;
 }
 
-ulong get_timer_masked (void)
+ulong get_timer (ulong base)
 {
-	return OSCR;
+	return get_timer_masked ();
 }
 
-void udelay_masked (unsigned long usec)
+void __udelay (unsigned long usec)
 {
 	ulong tmo;
 	ulong endtime;
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 44ebc50..dfe9335 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -58,7 +58,8 @@
 	meson-gxbb-nanopi-k2.dtb \
 	meson-gxl-s905x-p212.dtb \
 	meson-gxl-s905x-libretech-cc.dtb \
-	meson-gxl-s905x-khadas-vim.dtb
+	meson-gxl-s905x-khadas-vim.dtb \
+	meson-gxm-khadas-vim2.dtb
 dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
 	tegra20-medcom-wide.dtb \
 	tegra20-paz00.dtb \
diff --git a/arch/arm/dts/meson-gxm-khadas-vim2.dts b/arch/arm/dts/meson-gxm-khadas-vim2.dts
new file mode 100644
index 0000000..0868da4
--- /dev/null
+++ b/arch/arm/dts/meson-gxm-khadas-vim2.dts
@@ -0,0 +1,412 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>.
+ * Copyright (c) 2017 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/thermal/thermal.h>
+
+#include "meson-gxm.dtsi"
+
+/ {
+	compatible = "khadas,vim2", "amlogic,s912", "amlogic,meson-gxm";
+	model = "Khadas VIM2";
+
+	aliases {
+		serial0 = &uart_AO;
+		serial1 = &uart_A;
+		serial2 = &uart_AO_B;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>;
+	};
+
+	adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 0>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1710000>;
+
+		button-function {
+			label = "Function";
+			linux,code = <KEY_FN>;
+			press-threshold-microvolt = <10000>;
+		};
+	};
+
+	emmc_pwrseq: emmc-pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+	};
+
+	gpio_fan: gpio-fan {
+		compatible = "gpio-fan";
+		gpios = <&gpio GPIODV_14 GPIO_ACTIVE_HIGH
+			 &gpio GPIODV_15 GPIO_ACTIVE_HIGH>;
+		/* Dummy RPM values since fan is optional */
+		gpio-fan,speed-map = <0 0
+				      1 1
+				      2 2
+				      3 3>;
+		#cooling-cells = <2>;
+	};
+
+	gpio-keys-polled {
+		compatible = "gpio-keys-polled";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		poll-interval = <100>;
+
+		button@0 {
+			label = "power";
+			linux,code = <KEY_POWER>;
+			gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&hdmi_tx_tmds_out>;
+			};
+		};
+	};
+
+	pwmleds {
+		compatible = "pwm-leds";
+
+		power {
+			label = "vim:red:power";
+			pwms = <&pwm_AO_ab 1 7812500 0>;
+			max-brightness = <255>;
+			linux,default-trigger = "default-on";
+		};
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+		clocks = <&wifi32k>;
+		clock-names = "ext_clock";
+	};
+
+	thermal-zones {
+		cpu-thermal {
+			polling-delay-passive = <250>; /* milliseconds */
+			polling-delay = <1000>; /* milliseconds */
+
+			thermal-sensors = <&scpi_sensors 0>;
+
+			trips {
+				cpu_alert0: cpu-alert0 {
+					temperature = <70000>; /* millicelsius */
+					hysteresis = <2000>; /* millicelsius */
+					type = "active";
+				};
+
+				cpu_alert1: cpu-alert1 {
+					temperature = <80000>; /* millicelsius */
+					hysteresis = <2000>; /* millicelsius */
+					type = "passive";
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert0>;
+					cooling-device = <&gpio_fan THERMAL_NO_LIMIT 1>;
+				};
+
+				map1 {
+					trip = <&cpu_alert1>;
+					cooling-device = <&gpio_fan 2 THERMAL_NO_LIMIT>;
+				};
+
+				map2 {
+					trip = <&cpu_alert1>;
+					cooling-device =
+						<&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+
+				map3 {
+					trip = <&cpu_alert1>;
+					cooling-device =
+						<&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+		};
+	};
+
+	hdmi_5v: regulator-hdmi-5v {
+		compatible = "regulator-fixed";
+
+		regulator-name = "HDMI_5V";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+
+		gpio = <&gpio GPIOH_3 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-always-on;
+	};
+
+	vcc_3v3: regulator-vcc_3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vddio_ao18: regulator-vddio_ao18 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDIO_AO18";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	vddio_boot: regulator-vddio_boot {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDIO_BOOT";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	vddao_3v3: regulator-vddao_3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDAO_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	wifi32k: wifi32k {
+		compatible = "pwm-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+	};
+};
+
+&cec_AO {
+	status = "okay";
+	pinctrl-0 = <&ao_cec_pins>;
+	pinctrl-names = "default";
+	hdmi-phandle = <&hdmi_tx>;
+};
+
+&cpu0 {
+	#cooling-cells = <2>;
+};
+
+&cpu4 {
+	#cooling-cells = <2>;
+};
+
+&ethmac {
+	pinctrl-0 = <&eth_pins>;
+	pinctrl-names = "default";
+
+	/* Select external PHY by default */
+	phy-handle = <&external_phy>;
+
+	amlogic,tx-delay-ns = <2>;
+
+	/* External PHY reset is shared with internal PHY Led signals */
+	snps,reset-gpio = <&gpio GPIOZ_14 0>;
+	snps,reset-delays-us = <0 10000 1000000>;
+	snps,reset-active-low;
+
+	/* External PHY is in RGMII */
+	phy-mode = "rgmii";
+
+	status = "okay";
+};
+
+&external_mdio {
+	external_phy: ethernet-phy@0 {
+		/* Realtek RTL8211F (0x001cc916) */
+		reg = <0>;
+		interrupt-parent = <&gpio_intc>;
+		/* MAC_INTR on GPIOZ_15 */
+		interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&hdmi_tx {
+	status = "okay";
+	pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
+	pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+	hdmi_tx_tmds_out: endpoint {
+		remote-endpoint = <&hdmi_connector_in>;
+	};
+};
+
+&i2c_A {
+	status = "okay";
+	pinctrl-0 = <&i2c_a_pins>;
+	pinctrl-names = "default";
+};
+
+&i2c_B {
+	status = "okay";
+	pinctrl-0 = <&i2c_b_pins>;
+	pinctrl-names = "default";
+
+	rtc: rtc@51 {
+		/* has to be enabled manually when a battery is connected: */
+		status = "disabled";
+		compatible = "haoyu,hym8563";
+		reg = <0x51>;
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		clock-output-names = "xin32k";
+	};
+};
+
+&ir {
+	status = "okay";
+	pinctrl-0 = <&remote_input_ao_pins>;
+	pinctrl-names = "default";
+	linux,rc-map-name = "rc-geekbox";
+};
+
+&pwm_AO_ab {
+	status = "okay";
+	pinctrl-0 = <&pwm_ao_a_3_pins>, <&pwm_ao_b_pins>;
+	pinctrl-names = "default";
+	clocks = <&clkc CLKID_FCLK_DIV4>;
+	clock-names = "clkin0";
+};
+
+&pwm_ef {
+	status = "okay";
+	pinctrl-0 = <&pwm_e_pins>, <&pwm_f_clk_pins>;
+	pinctrl-names = "default";
+	clocks = <&clkc CLKID_FCLK_DIV4>;
+	clock-names = "clkin0";
+};
+
+&sd_emmc_a {
+	status = "okay";
+	pinctrl-0 = <&sdio_pins>;
+	pinctrl-names = "default";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	bus-width = <4>;
+	max-frequency = <100000000>;
+
+	non-removable;
+	disable-wp;
+
+	mmc-pwrseq = <&sdio_pwrseq>;
+
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddio_boot>;
+
+	brcmf: wifi@1 {
+		reg = <1>;
+		compatible = "brcm,bcm4329-fmac";
+	};
+};
+
+/* SD card */
+&sd_emmc_b {
+	status = "okay";
+	pinctrl-0 = <&sdcard_pins>;
+	pinctrl-names = "default";
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	max-frequency = <100000000>;
+	disable-wp;
+
+	cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
+	cd-inverted;
+
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddio_boot>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+	status = "okay";
+	pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+	pinctrl-names = "default";
+
+	bus-width = <8>;
+	cap-sd-highspeed;
+	cap-mmc-highspeed;
+	max-frequency = <200000000>;
+	non-removable;
+	disable-wp;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+
+	mmc-pwrseq = <&emmc_pwrseq>;
+	vmmc-supply = <&vcc_3v3>;
+	vqmmc-supply = <&vddio_boot>;
+};
+
+/*
+ * EMMC_DS pin is shared between SPI NOR CS and eMMC Data Strobe
+ * Remove emmc_ds_pins from sd_emmc_c pinctrl-0 then spifc can be enabled
+ */
+&spifc {
+	status = "disabled";
+	pinctrl-0 = <&nor_pins>;
+	pinctrl-names = "default";
+
+	w25q32: spi-flash@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "winbond,w25q16", "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <3000000>;
+	};
+};
+
+/* This one is connected to the Bluetooth module */
+&uart_A {
+	status = "okay";
+	pinctrl-0 = <&uart_a_pins>;
+	pinctrl-names = "default";
+};
+
+/* This is brought out on the Linux_RX (18) and Linux_TX (19) pins: */
+&uart_AO {
+	status = "okay";
+	pinctrl-0 = <&uart_ao_a_pins>;
+	pinctrl-names = "default";
+};
+
+/* This is brought out on the UART_RX_AO_B (15) and UART_TX_AO_B (16) pins: */
+&uart_AO_B {
+	status = "okay";
+	pinctrl-0 = <&uart_ao_b_pins>;
+	pinctrl-names = "default";
+};
+
+&saradc {
+	status = "okay";
+	vref-supply = <&vddio_ao18>;
+};
+
+&usb0 {
+	status = "okay";
+};
diff --git a/arch/arm/dts/meson-gxm.dtsi b/arch/arm/dts/meson-gxm.dtsi
new file mode 100644
index 0000000..247888d
--- /dev/null
+++ b/arch/arm/dts/meson-gxm.dtsi
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.com>
+ */
+
+#include "meson-gxl.dtsi"
+
+/ {
+	compatible = "amlogic,meson-gxm";
+
+	cpus {
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+				core1 {
+					cpu = <&cpu1>;
+				};
+				core2 {
+					cpu = <&cpu2>;
+				};
+				core3 {
+					cpu = <&cpu3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpu4>;
+				};
+				core1 {
+					cpu = <&cpu5>;
+				};
+				core2 {
+					cpu = <&cpu6>;
+				};
+				core3 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+
+		cpu4: cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			next-level-cache = <&l2>;
+			clocks = <&scpi_dvfs 1>;
+		};
+
+		cpu5: cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x101>;
+			enable-method = "psci";
+			next-level-cache = <&l2>;
+			clocks = <&scpi_dvfs 1>;
+		};
+
+		cpu6: cpu@102 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x102>;
+			enable-method = "psci";
+			next-level-cache = <&l2>;
+			clocks = <&scpi_dvfs 1>;
+		};
+
+		cpu7: cpu@103 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x103>;
+			enable-method = "psci";
+			next-level-cache = <&l2>;
+			clocks = <&scpi_dvfs 1>;
+		};
+	};
+};
+
+&apb {
+	usb2_phy2: phy@78040 {
+		compatible = "amlogic,meson-gxl-usb2-phy";
+		#phy-cells = <0>;
+		reg = <0x0 0x78040 0x0 0x20>;
+		clocks = <&clkc CLKID_USB>;
+		clock-names = "phy";
+		resets = <&reset RESET_USB_OTG>;
+		reset-names = "phy";
+		status = "okay";
+	};
+};
+
+&clkc_AO {
+	compatible = "amlogic,meson-gxm-aoclkc", "amlogic,meson-gx-aoclkc";
+};
+
+&saradc {
+	compatible = "amlogic,meson-gxm-saradc", "amlogic,meson-saradc";
+};
+
+&scpi_dvfs {
+	clock-indices = <0 1>;
+	clock-output-names = "vbig", "vlittle";
+};
+
+&vpu {
+	compatible = "amlogic,meson-gxm-vpu", "amlogic,meson-gx-vpu";
+};
+
+&hdmi_tx {
+	compatible = "amlogic,meson-gxm-dw-hdmi", "amlogic,meson-gx-dw-hdmi";
+};
+
+&dwc3 {
+	phys = <&usb3_phy>, <&usb2_phy0>, <&usb2_phy1>, <&usb2_phy2>;
+};
diff --git a/arch/arm/dts/stm32mp157c-ed1.dts b/arch/arm/dts/stm32mp157c-ed1.dts
index 898deaf..f8b7701 100644
--- a/arch/arm/dts/stm32mp157c-ed1.dts
+++ b/arch/arm/dts/stm32mp157c-ed1.dts
@@ -361,6 +361,10 @@
 	status = "okay";
 };
 
+&usbotg_hs {
+	usb33d-supply = <&usb33>;
+};
+
 &usbphyc_port0 {
 	phy-supply = <&vdd_usb>;
 	vdda1v1-supply = <&reg11>;
diff --git a/arch/arm/dts/ulcb.dtsi b/arch/arm/dts/ulcb.dtsi
index f66727c..ab88665 100644
--- a/arch/arm/dts/ulcb.dtsi
+++ b/arch/arm/dts/ulcb.dtsi
@@ -24,6 +24,15 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	cpld {
+		compatible = "renesas,ulcb-cpld";
+		status = "okay";
+		gpio-sck = <&gpio6 8 0>;
+		gpio-mosi = <&gpio6 7 0>;
+		gpio-miso = <&gpio6 10 0>;
+		gpio-sstbz = <&gpio2 3 0>;
+	};
+
 	audio_clkout: audio-clkout {
 		/*
 		 * This is same as <&rcar_sound 0>
diff --git a/arch/arm/include/asm/u-boot-arm.h b/arch/arm/include/asm/u-boot-arm.h
index cc828c4..2e8c8e5 100644
--- a/arch/arm/include/asm/u-boot-arm.h
+++ b/arch/arm/include/asm/u-boot-arm.h
@@ -24,26 +24,17 @@
 extern ulong IRQ_STACK_START_IN;	/* 8 bytes in IRQ stack */
 
 /* cpu/.../cpu.c */
-int	cpu_init(void);
 int	cleanup_before_linux(void);
 
 /* Set up ARMv7 MMU, caches and TLBs */
 void	cpu_init_cp15(void);
 
 /* cpu/.../arch/cpu.c */
-int	arch_cpu_init(void);
 int	arch_misc_init(void);
-int	arch_early_init_r(void);
 
 /* board/.../... */
 int	board_init(void);
 
-/* cpu/.../interrupt.c */
-int	arch_interrupt_init	(void);
-void	reset_timer_masked	(void);
-ulong	get_timer_masked	(void);
-void	udelay_masked		(unsigned long usec);
-
 /* calls to c from vectors.S */
 struct pt_regs;
 
diff --git a/arch/arm/mach-at91/arm920t/timer.c b/arch/arm/mach-at91/arm920t/timer.c
index bbe90ae..6db541a 100644
--- a/arch/arm/mach-at91/arm920t/timer.c
+++ b/arch/arm/mach-at91/arm920t/timer.c
@@ -53,16 +53,6 @@
 /*
  * timer without interrupts
  */
-ulong get_timer(ulong base)
-{
-	return get_timer_masked() - base;
-}
-
-void __udelay(unsigned long usec)
-{
-	udelay_masked(usec);
-}
-
 ulong get_timer_raw(void)
 {
 	at91_tc_t *tc = (at91_tc_t *) ATMEL_BASE_TC;
@@ -82,12 +72,17 @@
 	return gd->arch.tbl;
 }
 
-ulong get_timer_masked(void)
+static ulong get_timer_masked(void)
 {
 	return get_timer_raw()/TIMER_LOAD_VAL;
 }
 
-void udelay_masked(unsigned long usec)
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+void __udelay(unsigned long usec)
 {
 	u32 tmo;
 	u32 endtime;
diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h
index d4b25c3..3981978 100644
--- a/arch/arm/mach-davinci/include/mach/gpio.h
+++ b/arch/arm/mach-davinci/include/mach/gpio.h
@@ -21,27 +21,6 @@
 #define DAVINCI_GPIO_BANK8	0x01E260B0
 #endif /* CONFIG_SOC_DA8XX */
 
-struct davinci_gpio {
-	unsigned int dir;
-	unsigned int out_data;
-	unsigned int set_data;
-	unsigned int clr_data;
-	unsigned int in_data;
-	unsigned int set_rising;
-	unsigned int clr_rising;
-	unsigned int set_falling;
-	unsigned int clr_falling;
-	unsigned int intstat;
-};
-
-struct davinci_gpio_bank {
-	int num_gpio;
-	unsigned int irq_num;
-	unsigned int irq_mask;
-	unsigned long *in_use;
-	struct davinci_gpio *base;
-};
-
 #define davinci_gpio_bank01 ((struct davinci_gpio *)DAVINCI_GPIO_BANK01)
 #define davinci_gpio_bank23 ((struct davinci_gpio *)DAVINCI_GPIO_BANK23)
 #define davinci_gpio_bank45 ((struct davinci_gpio *)DAVINCI_GPIO_BANK45)
@@ -61,18 +40,7 @@
 #define MAX_NUM_GPIOS		144
 #endif
 #define GPIO_BANK(gp)		(davinci_gpio_bank01 + ((gp) >> 5))
-#define GPIO_BIT(gp)		((gp) & 0x1F)
 
 void gpio_info(void);
 
-#ifdef CONFIG_DM_GPIO
-
-/* Information about a GPIO bank */
-struct davinci_gpio_platdata {
-	int bank_index;
-	ulong base;	/* address of registers in physical memory */
-	const char *port_name;
-};
-#endif
-
 #endif
diff --git a/arch/arm/mach-imx/syscounter.c b/arch/arm/mach-imx/syscounter.c
index 676bb3c..34bdb95 100644
--- a/arch/arm/mach-imx/syscounter.c
+++ b/arch/arm/mach-imx/syscounter.c
@@ -89,14 +89,9 @@
 	return now;
 }
 
-ulong get_timer_masked(void)
-{
-	return tick_to_time(get_ticks());
-}
-
 ulong get_timer(ulong base)
 {
-	return get_timer_masked() - base;
+	return tick_to_time(get_ticks()) - base;
 }
 
 void __udelay(unsigned long usec)
diff --git a/arch/arm/mach-k3/am6_init.c b/arch/arm/mach-k3/am6_init.c
index 8a3a99f..68f0b8c 100644
--- a/arch/arm/mach-k3/am6_init.c
+++ b/arch/arm/mach-k3/am6_init.c
@@ -72,6 +72,29 @@
 	preloader_console_init();
 }
 
+u32 spl_boot_mode(const u32 boot_device)
+{
+#if defined(CONFIG_SUPPORT_EMMC_BOOT)
+	u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT);
+	u32 bootindex = readl(K3_BOOT_PARAM_TABLE_INDEX_VAL);
+
+	u32 bootmode = (devstat & CTRLMMR_MAIN_DEVSTAT_BOOTMODE_MASK) >>
+			CTRLMMR_MAIN_DEVSTAT_BOOTMODE_SHIFT;
+
+	/* eMMC boot0 mode is only supported for primary boot */
+	if (bootindex == K3_PRIMARY_BOOTMODE &&
+	    bootmode == BOOT_DEVICE_MMC1)
+		return MMCSD_MODE_EMMCBOOT;
+#endif
+
+	/* Everything else use filesystem if available */
+#if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT)
+	return MMCSD_MODE_FS;
+#else
+	return MMCSD_MODE_RAW;
+#endif
+}
+
 static u32 __get_backup_bootmedia(u32 devstat)
 {
 	u32 bkup_boot = (devstat & CTRLMMR_MAIN_DEVSTAT_BKUP_BOOTMODE_MASK) >>
@@ -85,7 +108,13 @@
 	case BACKUP_BOOT_DEVICE_ETHERNET:
 		return BOOT_DEVICE_ETHERNET;
 	case BACKUP_BOOT_DEVICE_MMC2:
+	{
+		u32 port = (devstat & CTRLMMR_MAIN_DEVSTAT_BKUP_MMC_PORT_MASK) >>
+			    CTRLMMR_MAIN_DEVSTAT_BKUP_MMC_PORT_SHIFT;
+		if (port == 0x0)
+			return BOOT_DEVICE_MMC1;
 		return BOOT_DEVICE_MMC2;
+	}
 	case BACKUP_BOOT_DEVICE_SPI:
 		return BOOT_DEVICE_SPI;
 	case BACKUP_BOOT_DEVICE_HYPERFLASH:
@@ -99,11 +128,24 @@
 
 static u32 __get_primary_bootmedia(u32 devstat)
 {
-	u32 bootmode = devstat & CTRLMMR_MAIN_DEVSTAT_BOOTMODE_MASK;
+	u32 bootmode = (devstat & CTRLMMR_MAIN_DEVSTAT_BOOTMODE_MASK) >>
+			CTRLMMR_MAIN_DEVSTAT_BOOTMODE_SHIFT;
 
 	if (bootmode == BOOT_DEVICE_OSPI || bootmode ==	BOOT_DEVICE_QSPI)
 		bootmode = BOOT_DEVICE_SPI;
 
+	if (bootmode == BOOT_DEVICE_MMC2) {
+		u32 port = (devstat & CTRLMMR_MAIN_DEVSTAT_MMC_PORT_MASK) >>
+			    CTRLMMR_MAIN_DEVSTAT_MMC_PORT_SHIFT;
+		if (port == 0x0)
+			bootmode = BOOT_DEVICE_MMC1;
+	} else if (bootmode == BOOT_DEVICE_MMC1) {
+		u32 port = (devstat & CTRLMMR_MAIN_DEVSTAT_EMMC_PORT_MASK) >>
+			    CTRLMMR_MAIN_DEVSTAT_EMMC_PORT_SHIFT;
+		if (port == 0x1)
+			bootmode = BOOT_DEVICE_MMC2;
+	}
+
 	return bootmode;
 }
 
diff --git a/arch/arm/mach-k3/include/mach/am6_hardware.h b/arch/arm/mach-k3/include/mach/am6_hardware.h
index e4b78f8..b524460 100644
--- a/arch/arm/mach-k3/include/mach/am6_hardware.h
+++ b/arch/arm/mach-k3/include/mach/am6_hardware.h
@@ -16,6 +16,12 @@
 #define CTRLMMR_MAIN_DEVSTAT_BOOTMODE_SHIFT		0
 #define CTRLMMR_MAIN_DEVSTAT_BKUP_BOOTMODE_MASK		GENMASK(6, 4)
 #define CTRLMMR_MAIN_DEVSTAT_BKUP_BOOTMODE_SHIFT	4
+#define CTRLMMR_MAIN_DEVSTAT_MMC_PORT_MASK		GENMASK(12, 12)
+#define CTRLMMR_MAIN_DEVSTAT_MMC_PORT_SHIFT		12
+#define CTRLMMR_MAIN_DEVSTAT_EMMC_PORT_MASK		GENMASK(14, 14)
+#define CTRLMMR_MAIN_DEVSTAT_EMMC_PORT_SHIFT		14
+#define CTRLMMR_MAIN_DEVSTAT_BKUP_MMC_PORT_MASK		GENMASK(17, 17)
+#define CTRLMMR_MAIN_DEVSTAT_BKUP_MMC_PORT_SHIFT	12
 
 #define WKUP_CTRL_MMR0_BASE				0x43000000
 #define MCU_CTRL_MMR0_BASE				0x40f00000
diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig
index ee8b1cd..cc94344 100644
--- a/arch/arm/mach-meson/Kconfig
+++ b/arch/arm/mach-meson/Kconfig
@@ -22,6 +22,16 @@
 	  The Amlogic Meson GXL (S905X and S905D) is an ARM SoC with a
 	  quad-core Cortex-A53 CPU and a Mali-450 GPU.
 
+config MESON_GXM
+	bool "Support Meson GXM"
+	select ARM64
+	select CLK
+	select DM
+	select DM_SERIAL
+	help
+	  The Amlogic Meson GXM (S912) is an ARM SoC with an
+	  octo-core Cortex-A53 CPU and a Mali-T860 GPU.
+
 if MESON_GXBB
 
 config TARGET_ODROID_C2
@@ -64,6 +74,17 @@
 
 endif
 
+if MESON_GXM
+
+config TARGET_KHADAS_VIM2
+	bool "KHADAS-VIM2"
+	help
+	  Khadas VIM2 is a single board computer based on Meson GXM
+	  with 2/3 GiB of RAM, Ethernet, HDMI, 4 USB, micro-SD slot,
+	  eMMC, IR receiver and a 40-pin GPIO header.
+
+endif
+
 config SYS_SOC
 	default "meson"
 
@@ -80,4 +101,6 @@
 
 source "board/amlogic/khadas-vim/Kconfig"
 
+source "board/amlogic/khadas-vim2/Kconfig"
+
 endif
diff --git a/arch/arm/mach-meson/board.c b/arch/arm/mach-meson/board.c
index 1ef7e5a..d6c6253 100644
--- a/arch/arm/mach-meson/board.c
+++ b/arch/arm/mach-meson/board.c
@@ -111,13 +111,13 @@
 	{
 		.virt = 0x0UL,
 		.phys = 0x0UL,
-		.size = 0x80000000UL,
+		.size = 0xc0000000UL,
 		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 			 PTE_BLOCK_INNER_SHARE
 	}, {
-		.virt = 0x80000000UL,
-		.phys = 0x80000000UL,
-		.size = 0x80000000UL,
+		.virt = 0xc0000000UL,
+		.phys = 0xc0000000UL,
+		.size = 0x30000000UL,
 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 			 PTE_BLOCK_NON_SHARE |
 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 847f33d..87b674e 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -23,6 +23,7 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 static struct gptimer *timer_base = (struct gptimer *)CONFIG_SYS_TIMERBASE;
+static ulong get_timer_masked(void);
 
 /*
  * Nothing really to do with interrupts, just starts up a counter.
@@ -67,7 +68,7 @@
 	}
 }
 
-ulong get_timer_masked(void)
+static ulong get_timer_masked(void)
 {
 	/* current tick value */
 	ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ);
diff --git a/arch/arm/mach-orion5x/timer.c b/arch/arm/mach-orion5x/timer.c
index 92725d3..6aaf94a 100644
--- a/arch/arm/mach-orion5x/timer.c
+++ b/arch/arm/mach-orion5x/timer.c
@@ -78,7 +78,7 @@
 #define timestamp gd->arch.tbl
 #define lastdec gd->arch.lastinc
 
-ulong get_timer_masked(void)
+static ulong get_timer_masked(void)
 {
 	ulong now = read_timer();
 
diff --git a/board/amlogic/khadas-vim2/Kconfig b/board/amlogic/khadas-vim2/Kconfig
new file mode 100644
index 0000000..d0af362
--- /dev/null
+++ b/board/amlogic/khadas-vim2/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_KHADAS_VIM2
+
+config SYS_BOARD
+	default "khadas-vim2"
+
+config SYS_VENDOR
+	default "amlogic"
+
+config SYS_CONFIG_NAME
+	default "khadas-vim2"
+
+endif
diff --git a/board/amlogic/khadas-vim2/MAINTAINERS b/board/amlogic/khadas-vim2/MAINTAINERS
new file mode 100644
index 0000000..ca63e31
--- /dev/null
+++ b/board/amlogic/khadas-vim2/MAINTAINERS
@@ -0,0 +1,6 @@
+KHADAS-VIM2
+M:	Neil Armstrong <narmstrong@baylibre.com>
+S:	Maintained
+F:	board/amlogic/khadas-vim2/
+F:	include/configs/khadas-vim2.h
+F:	configs/khadas-vim2_defconfig
diff --git a/board/amlogic/khadas-vim2/Makefile b/board/amlogic/khadas-vim2/Makefile
new file mode 100644
index 0000000..4e7c9a0
--- /dev/null
+++ b/board/amlogic/khadas-vim2/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2016 BayLibre, SAS
+# Author: Neil Armstrong <narmstrong@baylibre.com>
+
+obj-y	:= khadas-vim2.o
diff --git a/board/amlogic/khadas-vim2/README b/board/amlogic/khadas-vim2/README
new file mode 100644
index 0000000..578693f
--- /dev/null
+++ b/board/amlogic/khadas-vim2/README
@@ -0,0 +1,103 @@
+U-Boot for Khadas VIM2
+=======================
+
+Khadas VIM2 is an Open Source DIY Box manufactured by Shenzhen Wesion
+Technology Co., Ltd with the following specifications:
+
+ - Amlogic S912 ARM Cortex-A53 octo-core SoC @ 1.5GHz
+ - ARM Mali T860 GPU
+ - 2/3GB DDR4 SDRAM
+ - 10/100/1000 Ethernet
+ - HDMI 2.0 4K/60Hz display
+ - 40-pin GPIO header
+ - 2 x USB 2.0 Host, 1 x USB 2.0 Type-C OTG
+ - 16GB/32GB/64GB eMMC
+ - 2MB SPI Flash
+ - microSD
+ - SDIO Wifi Module, Bluetooth
+ - Two channels IR receiver
+
+Currently the u-boot port supports the following devices:
+ - serial
+ - eMMC, microSD
+ - Ethernet
+ - I2C
+ - Regulators
+ - Reset controller
+ - Clock controller
+ - USB Host
+ - ADC
+
+U-Boot compilation
+==================
+
+ > export ARCH=arm
+ > export CROSS_COMPILE=aarch64-none-elf-
+ > make khadas-vim2_defconfig
+ > make
+
+Image creation
+==============
+
+Amlogic doesn't provide sources for the firmware and for tools needed
+to create the bootloader image, so it is necessary to obtain them from
+the git tree published by the board vendor:
+
+ > wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ > wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+ > tar xvfJ gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ > tar xvfJ gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+ > export PATH=$PWD/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin:$PWD/gcc-linaro-arm-none-eabi-4.8-2013.11_linux/bin:$PATH
+ > git clone https://github.com/khadas/u-boot -b Vim vim-u-boot
+ > cd vim-u-boot
+ > make kvim_defconfig
+ > make
+ > export FIPDIR=$PWD/fip
+
+Go back to mainline U-Boot source tree then :
+ > mkdir fip
+
+ > cp $FIPDIR/gxl/bl2.bin fip/
+ > cp $FIPDIR/gxl/acs.bin fip/
+ > cp $FIPDIR/gxl/bl21.bin fip/
+ > cp $FIPDIR/gxl/bl30.bin fip/
+ > cp $FIPDIR/gxl/bl301.bin fip/
+ > cp $FIPDIR/gxl/bl31.img fip/
+ > cp u-boot.bin fip/bl33.bin
+
+ > $FIPDIR/blx_fix.sh \
+	fip/bl30.bin \
+	fip/zero_tmp \
+	fip/bl30_zero.bin \
+	fip/bl301.bin \
+	fip/bl301_zero.bin \
+	fip/bl30_new.bin \
+	bl30
+
+ > python $FIPDIR/acs_tool.pyc fip/bl2.bin fip/bl2_acs.bin fip/acs.bin 0
+
+ > $FIPDIR/blx_fix.sh \
+	fip/bl2_acs.bin \
+	fip/zero_tmp \
+	fip/bl2_zero.bin \
+	fip/bl21.bin \
+	fip/bl21_zero.bin \
+	fip/bl2_new.bin \
+	bl2
+
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl30_new.bin
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl31.img
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl33.bin
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl2sig --input fip/bl2_new.bin --output fip/bl2.n.bin.sig
+ > $FIPDIR/gxl/aml_encrypt_gxl --bootmk \
+		--output fip/u-boot.bin \
+		--bl2 fip/bl2.n.bin.sig \
+		--bl30 fip/bl30_new.bin.enc \
+		--bl31 fip/bl31.img.enc \
+		--bl33 fip/bl33.bin.enc
+
+and then write the image to SD with:
+
+ > DEV=/dev/your_sd_device
+ > dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=512 skip=1 seek=1
+ > dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=1 count=444
diff --git a/board/amlogic/khadas-vim2/khadas-vim2.c b/board/amlogic/khadas-vim2/khadas-vim2.c
new file mode 100644
index 0000000..ff56569
--- /dev/null
+++ b/board/amlogic/khadas-vim2/khadas-vim2.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <environment.h>
+#include <asm/io.h>
+#include <asm/arch/gx.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/sm.h>
+#include <asm/arch/eth.h>
+
+#define EFUSE_SN_OFFSET		20
+#define EFUSE_SN_SIZE		16
+#define EFUSE_MAC_OFFSET	52
+#define EFUSE_MAC_SIZE		6
+
+int board_init(void)
+{
+	return 0;
+}
+
+int misc_init_r(void)
+{
+	u8 mac_addr[EFUSE_MAC_SIZE];
+	char serial[EFUSE_SN_SIZE];
+	ssize_t len;
+
+	meson_gx_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
+
+	/* Reset PHY on GPIOZ_14 */
+	clrbits_le32(GX_GPIO_EN(3), BIT(14));
+	clrbits_le32(GX_GPIO_OUT(3), BIT(14));
+	mdelay(10);
+	setbits_le32(GX_GPIO_OUT(3), BIT(14));
+
+	if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
+		len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
+					  mac_addr, EFUSE_MAC_SIZE);
+		if (len == EFUSE_MAC_SIZE && is_valid_ethaddr(mac_addr))
+			eth_env_set_enetaddr("ethaddr", mac_addr);
+	}
+
+	if (!env_get("serial#")) {
+		len = meson_sm_read_efuse(EFUSE_SN_OFFSET, serial,
+					  EFUSE_SN_SIZE);
+		if (len == EFUSE_SN_SIZE)
+			env_set("serial#", serial);
+	}
+
+	return 0;
+}
+
+int ft_board_setup(void *blob, bd_t *bd)
+{
+	meson_gx_init_reserved_memory(blob);
+
+	return 0;
+}
diff --git a/board/armltd/integrator/timer.c b/board/armltd/integrator/timer.c
index 3063884..7ecfa49 100644
--- a/board/armltd/integrator/timer.c
+++ b/board/armltd/integrator/timer.c
@@ -93,31 +93,10 @@
 /*
  * timer without interrupts
  */
-ulong get_timer (ulong base_ticks)
-{
-	return get_timer_masked () - base_ticks;
-}
-
-/* delay usec useconds */
-void __udelay (unsigned long usec)
-{
-	ulong tmo, tmp;
-
-	/* Convert to U-Boot ticks */
-	tmo  = usec * CONFIG_SYS_HZ;
-	tmo /= (1000000L);
-
-	tmp  = get_timer_masked();	/* get current timestamp */
-	tmo += tmp;			/* form target timestamp */
-
-	while (get_timer_masked () < tmo) {/* loop till event */
-		/*NOP*/;
-	}
-}
 
 /* converts the timer reading to U-Boot ticks	       */
 /* the timestamp is the number of ticks since reset    */
-ulong get_timer_masked (void)
+static ulong get_timer_masked (void)
 {
 	/* get current count */
 	unsigned long long now = READ_TIMER;
@@ -138,10 +117,26 @@
 	return timestamp;
 }
 
+ulong get_timer (ulong base_ticks)
+{
+	return get_timer_masked () - base_ticks;
+}
+
-/* waits specified delay value and resets timestamp */
-void udelay_masked (unsigned long usec)
+/* delay usec useconds */
+void __udelay (unsigned long usec)
 {
-	udelay(usec);
+	ulong tmo, tmp;
+
+	/* Convert to U-Boot ticks */
+	tmo  = usec * CONFIG_SYS_HZ;
+	tmo /= (1000000L);
+
+	tmp  = get_timer_masked();	/* get current timestamp */
+	tmo += tmp;			/* form target timestamp */
+
+	while (get_timer_masked () < tmo) {/* loop till event */
+		/*NOP*/;
+	}
 }
 
 /*
diff --git a/board/omicron/calimain/calimain.c b/board/omicron/calimain/calimain.c
index 648d191..6f7b2b8 100644
--- a/board/omicron/calimain/calimain.c
+++ b/board/omicron/calimain/calimain.c
@@ -22,6 +22,7 @@
 #include <asm/arch/pinmux_defs.h>
 #include <asm/arch/davinci_misc.h>
 #include <asm/arch/timer_defs.h>
+#include "../../../drivers/gpio/da8xx_gpio.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
diff --git a/board/ti/ks2_evm/board.c b/board/ti/ks2_evm/board.c
index 274f18e..d81c8e6 100644
--- a/board/ti/ks2_evm/board.c
+++ b/board/ti/ks2_evm/board.c
@@ -146,14 +146,10 @@
 	int nbanks;
 	u64 size[2];
 	u64 start[2];
-	int nodeoffset;
 	u32 ddr3a_size;
-	int unitrd_fixup = 0;
 
 	env = env_get("mem_lpae");
 	lpae = env && simple_strtol(env, NULL, 0);
-	env = env_get("uinitrd_fixup");
-	unitrd_fixup = env && simple_strtol(env, NULL, 0);
 
 	ddr3a_size = 0;
 	if (lpae) {
@@ -191,24 +187,41 @@
 
 	fdt_fixup_memory_banks(blob, start, size, nbanks);
 
+	return 0;
+}
+
+void ft_board_setup_ex(void *blob, bd_t *bd)
+{
+	int lpae;
+	u64 size;
+	char *env;
+	u64 *reserve_start;
+	int unitrd_fixup = 0;
+
+	env = env_get("mem_lpae");
+	lpae = env && simple_strtol(env, NULL, 0);
+	env = env_get("uinitrd_fixup");
+	unitrd_fixup = env && simple_strtol(env, NULL, 0);
+
 	/* Fix up the initrd */
 	if (lpae && unitrd_fixup) {
+		int nodeoffset;
 		int err;
-		u32 *prop1, *prop2;
+		u64 *prop1, *prop2;
 		u64 initrd_start, initrd_end;
 
 		nodeoffset = fdt_path_offset(blob, "/chosen");
 		if (nodeoffset >= 0) {
-			prop1 = (u32 *)fdt_getprop(blob, nodeoffset,
+			prop1 = (u64 *)fdt_getprop(blob, nodeoffset,
 					    "linux,initrd-start", NULL);
-			prop2 = (u32 *)fdt_getprop(blob, nodeoffset,
+			prop2 = (u64 *)fdt_getprop(blob, nodeoffset,
 					    "linux,initrd-end", NULL);
 			if (prop1 && prop2) {
-				initrd_start = __be32_to_cpu(*prop1);
+				initrd_start = __be64_to_cpu(*prop1);
 				initrd_start -= CONFIG_SYS_SDRAM_BASE;
 				initrd_start += CONFIG_SYS_LPAE_SDRAM_BASE;
 				initrd_start = __cpu_to_be64(initrd_start);
-				initrd_end = __be32_to_cpu(*prop2);
+				initrd_end = __be64_to_cpu(*prop2);
 				initrd_end -= CONFIG_SYS_SDRAM_BASE;
 				initrd_end += CONFIG_SYS_LPAE_SDRAM_BASE;
 				initrd_end = __cpu_to_be64(initrd_end);
@@ -240,19 +253,6 @@
 		}
 	}
 
-	return 0;
-}
-
-void ft_board_setup_ex(void *blob, bd_t *bd)
-{
-	int lpae;
-	u64 size;
-	char *env;
-	u64 *reserve_start;
-
-	env = env_get("mem_lpae");
-	lpae = env && simple_strtol(env, NULL, 0);
-
 	if (lpae) {
 		/*
 		 * the initrd and other reserved memory areas are
diff --git a/cmd/fdt.c b/cmd/fdt.c
index 28de467..8a19a3f 100644
--- a/cmd/fdt.c
+++ b/cmd/fdt.c
@@ -596,6 +596,9 @@
 			       fdt_strerror(err));
 			return CMD_RET_FAILURE;
 		}
+#ifdef CONFIG_SOC_KEYSTONE
+		ft_board_setup_ex(working_fdt, gd->bd);
+#endif
 	}
 #endif
 	/* Create a chosen node */
diff --git a/cmd/pxe.c b/cmd/pxe.c
index 5609545..2745553 100644
--- a/cmd/pxe.c
+++ b/cmd/pxe.c
@@ -471,6 +471,7 @@
 	char *name;
 	char *menu;
 	char *kernel;
+	char *config;
 	char *append;
 	char *initrd;
 	char *fdt;
@@ -538,6 +539,9 @@
 	if (label->kernel)
 		free(label->kernel);
 
+	if (label->config)
+		free(label->config);
+
 	if (label->append)
 		free(label->append);
 
@@ -618,6 +622,7 @@
 	char initrd_str[28];
 	char mac_str[29] = "";
 	char ip_str[68] = "";
+	char *fit_addr = NULL;
 	int bootm_argc = 2;
 	int len = 0;
 	ulong kernel_addr;
@@ -699,6 +704,18 @@
 	}
 
 	bootm_argv[1] = env_get("kernel_addr_r");
+	/* for FIT, append the configuration identifier */
+	if (label->config) {
+		int len = strlen(bootm_argv[1]) + strlen(label->config) + 1;
+
+		fit_addr = malloc(len);
+		if (!fit_addr) {
+			printf("malloc fail (FIT address)\n");
+			return 1;
+		}
+		snprintf(fit_addr, len, "%s%s", bootm_argv[1], label->config);
+		bootm_argv[1] = fit_addr;
+	}
 
 	/*
 	 * fdt usage is optional:
@@ -758,7 +775,7 @@
 			fdtfilefree = malloc(len);
 			if (!fdtfilefree) {
 				printf("malloc fail (FDT filename)\n");
-				return 1;
+				goto cleanup;
 			}
 
 			snprintf(fdtfilefree, len, "%s%s%s%s%s%s",
@@ -772,7 +789,7 @@
 			if (err < 0) {
 				printf("Skipping %s for failure retrieving fdt\n",
 						label->name);
-				return 1;
+				goto cleanup;
 			}
 		} else {
 			bootm_argv[3] = NULL;
@@ -803,6 +820,10 @@
 		do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
 #endif
 	unmap_sysmem(buf);
+
+cleanup:
+	if (fit_addr)
+		free(fit_addr);
 	return 1;
 }
 
@@ -1188,6 +1209,33 @@
 }
 
 /*
+ * Handles parsing a 'kernel' label.
+ * expecting "filename" or "<fit_filename>#cfg"
+ */
+static int parse_label_kernel(char **c, struct pxe_label *label)
+{
+	char *s;
+	int err;
+
+	err = parse_sliteral(c, &label->kernel);
+	if (err < 0)
+		return err;
+
+	s = strstr(label->kernel, "#");
+	if (!s)
+		return 1;
+
+	label->config = malloc(strlen(s) + 1);
+	if (!label->config)
+		return -ENOMEM;
+
+	strcpy(label->config, s);
+	*s = 0;
+
+	return 1;
+}
+
+/*
  * Parses a label and adds it to the list of labels for a menu.
  *
  * A label ends when we either get to the end of a file, or
@@ -1228,7 +1276,7 @@
 
 		case T_KERNEL:
 		case T_LINUX:
-			err = parse_sliteral(c, &label->kernel);
+			err = parse_label_kernel(c, label);
 			break;
 
 		case T_APPEND:
diff --git a/common/bootm_os.c b/common/bootm_os.c
index f4bd905..f302135 100644
--- a/common/bootm_os.c
+++ b/common/bootm_os.c
@@ -505,10 +505,17 @@
 	/* please define platform specific arch_preboot_os() */
 }
 
+/* Allow for board specific config before we boot */
+__weak void board_preboot_os(void)
+{
+	/* please define board specific board_preboot_os() */
+}
+
 int boot_selected_os(int argc, char * const argv[], int state,
 		     bootm_headers_t *images, boot_os_fn *boot_fn)
 {
 	arch_preboot_os();
+	board_preboot_os();
 	boot_fn(state, argc, argv, images);
 
 	/* Stand-alone may return when 'autostart' is 'no' */
diff --git a/configs/khadas-vim2_defconfig b/configs/khadas-vim2_defconfig
new file mode 100644
index 0000000..f21e3a8
--- /dev/null
+++ b/configs/khadas-vim2_defconfig
@@ -0,0 +1,51 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MESON=y
+CONFIG_SYS_TEXT_BASE=0x01000000
+CONFIG_MESON_GXM=y
+CONFIG_TARGET_KHADAS_VIM2=y
+CONFIG_DEBUG_UART_BASE=0xc81004c0
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_IDENT_STRING=" khadas-vim2"
+CONFIG_DEFAULT_DEVICE_TREE="meson-gxm-khadas-vim2"
+CONFIG_DEBUG_UART=y
+CONFIG_OF_BOARD_SETUP=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_IMI is not set
+CONFIG_CMD_ADC=y
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_REGULATOR=y
+CONFIG_ADC=y
+CONFIG_SARADC_MESON=y
+CONFIG_OF_CONTROL=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_RESET=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_MESON_GX=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_MESON_GXL=y
+CONFIG_DEBUG_UART_MESON=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_MESON_SERIAL=y
+CONFIG_OF_LIBFDT_OVERLAY=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_XHCI_DWC3_OF_SIMPLE=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_STORAGE=y
+CONFIG_PHY=y
+CONFIG_MESON_GXL_USB_PHY=y
+CONFIG_MTD=y
diff --git a/doc/README.pxe b/doc/README.pxe
index 98862cd..42f913c 100644
--- a/doc/README.pxe
+++ b/doc/README.pxe
@@ -140,6 +140,13 @@
 		      (or FIT image) at <path>. it will be stored at the address
 		      indicated in the kernel_addr_r environment variable, and
 		      that address will be passed to bootm to boot this kernel.
+		      For FIT image, The configuration specification can be
+		      appended to the file name, with the format:
+		        <path>#<conf>[#<extra-conf[#...]]
+		      It will passed to bootm with that address.
+		      (see: doc/uImage.FIT/command_syntax_extensions.txt)
+		      It useful for overlay selection in pxe file
+		      (see: doc/uImage.FIT/overlay-fdt-boot.txt)
 
 append <string>	    - use <string> as the kernel command line when booting this
 		      label.
diff --git a/drivers/gpio/da8xx_gpio.c b/drivers/gpio/da8xx_gpio.c
index b0d49cb..bd79448 100644
--- a/drivers/gpio/da8xx_gpio.c
+++ b/drivers/gpio/da8xx_gpio.c
@@ -11,11 +11,14 @@
 #include <fdtdec.h>
 #include <asm/io.h>
 #include <asm/gpio.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/davinci_misc.h>
 #include <dt-bindings/gpio/gpio.h>
 
+#include "da8xx_gpio.h"
+
 #ifndef CONFIG_DM_GPIO
+#include <asm/arch/hardware.h>
+#include <asm/arch/davinci_misc.h>
+
 static struct gpio_registry {
 	int is_registered;
 	char name[GPIO_NAME_SIZE];
@@ -530,6 +533,7 @@
 
 static const struct udevice_id davinci_gpio_ids[] = {
 	{ .compatible = "ti,dm6441-gpio" },
+	{ .compatible = "ti,k2g-gpio" },
 	{ }
 };
 
diff --git a/drivers/gpio/da8xx_gpio.h b/drivers/gpio/da8xx_gpio.h
new file mode 100644
index 0000000..1de9ec7
--- /dev/null
+++ b/drivers/gpio/da8xx_gpio.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef _GPIO_DA8XX_DEFS_H_
+#define _GPIO_DA8XX_DEFS_H_
+
+struct davinci_gpio {
+	unsigned int dir;
+	unsigned int out_data;
+	unsigned int set_data;
+	unsigned int clr_data;
+	unsigned int in_data;
+	unsigned int set_rising;
+	unsigned int clr_rising;
+	unsigned int set_falling;
+	unsigned int clr_falling;
+	unsigned int intstat;
+};
+
+struct davinci_gpio_bank {
+	int num_gpio;
+	unsigned int irq_num;
+	unsigned int irq_mask;
+	unsigned long *in_use;
+	struct davinci_gpio *base;
+};
+
+#define GPIO_NAME_SIZE		20
+#define MAX_NUM_GPIOS		144
+#define GPIO_BIT(gp)		((gp) & 0x1F)
+
+#ifdef CONFIG_DM_GPIO
+
+/* Information about a GPIO bank */
+struct davinci_gpio_platdata {
+	int bank_index;
+	ulong base;	/* address of registers in physical memory */
+	const char *port_name;
+};
+#endif
+
+#endif
diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c
index b311b80..138de59 100644
--- a/drivers/mmc/tmio-common.c
+++ b/drivers/mmc/tmio-common.c
@@ -372,10 +372,18 @@
 }
 
 /* check if the address is DMA'able */
-static bool tmio_sd_addr_is_dmaable(unsigned long addr)
+static bool tmio_sd_addr_is_dmaable(const char *src)
 {
+	uintptr_t addr = (uintptr_t)src;
+
 	if (!IS_ALIGNED(addr, TMIO_SD_DMA_MINALIGN))
 		return false;
+
+#if defined(CONFIG_RCAR_GEN3)
+	/* Gen3 DMA has 32bit limit */
+	if (addr >> 32)
+		return false;
+#endif
 
 #if defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARM64) && \
 	defined(CONFIG_SPL_BUILD)
@@ -486,7 +494,7 @@
 	if (data) {
 		/* use DMA if the HW supports it and the buffer is aligned */
 		if (priv->caps & TMIO_SD_CAP_DMA_INTERNAL &&
-		    tmio_sd_addr_is_dmaable((long)data->src))
+		    tmio_sd_addr_is_dmaable(data->src))
 			ret = tmio_sd_dma_xfer(dev, data);
 		else
 			ret = tmio_sd_pio_xfer(dev, data);
diff --git a/drivers/rtc/isl1208.c b/drivers/rtc/isl1208.c
index 22ac0d2..59a60b7 100644
--- a/drivers/rtc/isl1208.c
+++ b/drivers/rtc/isl1208.c
@@ -52,6 +52,24 @@
 #define RTC_STAT_BIT_RTCF	0x01	/* REAL TIME CLOCK FAIL BIT */
 
 /*
+ * Read an RTC register
+ */
+
+static int isl1208_rtc_read8(struct udevice *dev, unsigned int reg)
+{
+	return dm_i2c_reg_read(dev, reg);
+}
+
+/*
+ * Write an RTC register
+ */
+
+static int isl1208_rtc_write8(struct udevice *dev, unsigned int reg, int val)
+{
+	return dm_i2c_reg_write(dev, reg, val);
+}
+
+/*
  * Get the current time from the RTC
  */
 
@@ -161,6 +179,8 @@
 	.get = isl1208_rtc_get,
 	.set = isl1208_rtc_set,
 	.reset = isl1208_rtc_reset,
+	.read8 = isl1208_rtc_read8,
+	.write8 = isl1208_rtc_write8,
 };
 
 static const struct udevice_id isl1208_rtc_ids[] = {
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 18b47d9..d248d79 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -272,7 +272,7 @@
 {
 	struct btrfs_leaf *leaf = &p->nodes[0]->leaf;
 
-	if (p->slots[0] >= leaf->header.nritems)
+	if (p->slots[0] + 1 >= leaf->header.nritems)
 		return jump_leaf(p, 1);
 
 	p->slots[0]++;
diff --git a/include/configs/khadas-vim2.h b/include/configs/khadas-vim2.h
new file mode 100644
index 0000000..7ef8f42
--- /dev/null
+++ b/include/configs/khadas-vim2.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Configuration for Khadas VIM2
+ *
+ * Copyright (C) 2017 Baylibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_MISC_INIT_R
+
+#define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxm-khadas-vim2.dtb\0"
+
+#include <configs/meson-gx-common.h>
+
+#endif /* __CONFIG_H */