Merge tag 'arc-fixes-for-2019.04-rc1' of git://git.denx.de/u-boot-arc

A couple of trivial fixes and improvements for ARC

Most notable are:
 * Move of ENV_SIZE/ENV_OFFSET to Kconfig
 * Fix with private structure allocation for arc_uart
 * Definition of CONFIG_SYS_CACHELINE_SIZE useful for building drivers
diff --git a/README b/README
index 17d56b8..aed6b96 100644
--- a/README
+++ b/README
@@ -1429,15 +1429,6 @@
 		forwarded through a router.
 		(Environment variable "netmask")
 
-- Multicast TFTP Mode:
-		CONFIG_MCAST_TFTP
-
-		Defines whether you want to support multicast TFTP as per
-		rfc-2090; for example to work with atftp.  Lets lots of targets
-		tftp down the same boot image concurrently.  Note: the Ethernet
-		driver in use must provide a function: mcast() to join/leave a
-		multicast group.
-
 - BOOTP Recovery Mode:
 		CONFIG_BOOTP_RANDOM_DELAY
 
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2298e6e..cefa8f4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -846,6 +846,7 @@
 	select CMD_GPIO
 	select CMD_MMC if MMC
 	select CMD_USB if DISTRO_DEFAULTS
+	select CLK
 	select DM
 	select DM_ETH
 	select DM_GPIO
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index ce5e845..5c3225b 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -399,6 +399,7 @@
 dtb-$(CONFIG_MACH_SUN8I_V3S) += \
 	sun8i-v3s-licheepi-zero.dtb
 dtb-$(CONFIG_MACH_SUN50I_H5) += \
+	sun50i-h5-emlid-neutis-n5-devboard.dtb \
 	sun50i-h5-libretech-all-h3-cc.dtb \
 	sun50i-h5-nanopi-neo2.dtb \
 	sun50i-h5-nanopi-neo-plus2.dtb \
diff --git a/arch/arm/dts/sun50i-h5-emlid-neutis-n5-devboard.dts b/arch/arm/dts/sun50i-h5-emlid-neutis-n5-devboard.dts
new file mode 100644
index 0000000..493947c
--- /dev/null
+++ b/arch/arm/dts/sun50i-h5-emlid-neutis-n5-devboard.dts
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2018 Aleksandr Aleksandrov <aleksandr.aleksandrov@emlid.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h5-emlid-neutis-n5.dtsi"
+
+/ {
+	model = "Emlid Neutis N5 Developer board";
+	compatible = "emlid,emlid-neutis-n5-devboard",
+		"emlid,emlid-neutis-n5",
+		"allwinner,sun50i-h5";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
+	reg_usb0_vbus: usb0-vbus {
+		compatible = "regulator-fixed";
+		regulator-name = "usb0-vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		gpio = <&r_pio 0 9 GPIO_ACTIVE_HIGH>;   /* PL9 */
+		status = "okay";
+	};
+
+	vdd_cpux: gpio-regulator {
+		compatible = "regulator-gpio";
+		pinctrl-names = "default";
+		regulator-name = "vdd-cpux";
+		regulator-type = "voltage";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1100000>;
+		regulator-max-microvolt = <1300000>;
+		regulator-ramp-delay = <50>; /* 4ms */
+		gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */
+		gpios-states = <0x1>;
+		states = <1100000 0x0
+			  1300000 0x1>;
+	};
+};
+
+&codec {
+	allwinner,audio-routing =
+		"Line Out", "LINEOUT",
+		"LINEIN", "Line In",
+		"MIC1", "Mic",
+		"MIC2", "Mic",
+		"Mic",  "MBIAS";
+	status = "okay";
+};
+
+&de {
+	status = "okay";
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&ehci2 {
+	status = "okay";
+};
+
+&ehci3 {
+	status = "okay";
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&ohci2 {
+	status = "okay";
+};
+
+&ohci3 {
+	status = "okay";
+};
+
+&emac {
+	phy-handle = <&int_mii_phy>;
+	phy-mode = "mii";
+	allwinner,leds-active-low;
+	status = "okay";
+};
+
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
+&mmc0 {
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins_a>;
+	status = "okay";
+};
+
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usbphy {
+	usb0_id_det-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */
+	usb0_vbus-supply = <&reg_usb0_vbus>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/sun50i-h5-emlid-neutis-n5.dtsi b/arch/arm/dts/sun50i-h5-emlid-neutis-n5.dtsi
new file mode 100644
index 0000000..8e1e37d
--- /dev/null
+++ b/arch/arm/dts/sun50i-h5-emlid-neutis-n5.dtsi
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2018 Aleksandr Aleksandrov <aleksandr.aleksandrov@emlid.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h5.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	reg_vcc3v3: vcc3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	wifi_pwrseq: wifi_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		pinctrl-names = "default";
+		reset-gpios = <&pio 2 7 GPIO_ACTIVE_LOW>; /* PC7 */
+		post-power-on-delay-ms = <200>;
+	};
+};
+
+&mmc1 {
+	vmmc-supply = <&reg_vcc3v3>;
+	vqmmc-supply = <&reg_vcc3v3>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+
+	brcmf: wifi@1 {
+		reg = <1>;
+		compatible = "brcm,bcm4329-fmac";
+		interrupt-parent = <&r_pio>;
+		interrupts = <0 5 IRQ_TYPE_LEVEL_LOW>;	/* PL5 */
+		interrupt-names = "host-wake";
+	};
+};
+
+&mmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_8bit_pins>;
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <8>;
+	non-removable;
+	cap-mmc-hw-reset;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/sun9i-a80-cubieboard4.dts b/arch/arm/dts/sun9i-a80-cubieboard4.dts
index 1526b41..85da85f 100644
--- a/arch/arm/dts/sun9i-a80-cubieboard4.dts
+++ b/arch/arm/dts/sun9i-a80-cubieboard4.dts
@@ -47,7 +47,6 @@
 #include "sun9i-a80.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/pinctrl/sun4i-a10.h>
 
 / {
 	model = "Cubietech Cubieboard4";
@@ -63,8 +62,6 @@
 
 	leds {
 		compatible = "gpio-leds";
-		pinctrl-names = "default";
-		pinctrl-0 = <&led_pins_cubieboard4>;
 
 		green {
 			label = "cubieboard4:green:usr";
@@ -76,18 +73,96 @@
 			gpios = <&pio 7 6 GPIO_ACTIVE_HIGH>; /* PH6 */
 		};
 	};
+
+	vga-connector {
+		compatible = "vga-connector";
+		label = "vga";
+		ddc-i2c-bus = <&i2c3>;
+
+		port {
+			vga_con_in: endpoint {
+				remote-endpoint = <&vga_dac_out>;
+			};
+		};
+	};
+
+	vga-dac {
+		compatible = "corpro,gm7123", "adi,adv7123", "dumb-vga-dac";
+		vdd-supply = <&reg_dcdc1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0>;
+
+				vga_dac_in: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&tcon0_out_vga>;
+				};
+			};
+
+			port@1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <1>;
+
+				vga_dac_out: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&vga_con_in>;
+				};
+			};
+		};
+	};
+
+	wifi_pwrseq: wifi-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		clocks = <&ac100_rtc 1>;
+		clock-names = "ext_clock";
+		/* enables internal regulator and de-asserts reset */
+		reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 WL-PMU-EN */
+	};
+};
+
+&de {
+	status = "okay";
+};
+
+&i2c3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c3_pins>;
+	status = "okay";
 };
 
 &mmc0 {
 	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins>, <&mmc0_cd_pin_cubieboard4>;
+	pinctrl-0 = <&mmc0_pins>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 18 GPIO_ACTIVE_HIGH>; /* PH18 */
-	cd-inverted;
+	cd-gpios = <&pio 7 18 GPIO_ACTIVE_LOW>; /* PH18 */
 	status = "okay";
 };
 
+&mmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc1_pins>;
+	vmmc-supply = <&reg_dldo1>;
+	vqmmc-supply = <&reg_cldo3>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+};
+
+&mmc1_pins {
+	bias-pull-up;
+};
+
 &mmc2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc2_8bit_pins>;
@@ -100,23 +175,12 @@
 
 &mmc2_8bit_pins {
 	/* Increase drive strength for DDR modes */
-	allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+	drive-strength = <40>;
 };
 
-&pio {
-	led_pins_cubieboard4: led-pins@0 {
-		allwinner,pins = "PH6", "PH17";
-		allwinner,function = "gpio_out";
-		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-	};
-
-	mmc0_cd_pin_cubieboard4: mmc0_cd_pin@0 {
-		allwinner,pins = "PH18";
-		allwinner,function = "gpio_in";
-		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
-	};
+&osc32k {
+	/* osc32k input is from AC100 */
+	clocks = <&ac100_rtc 0>;
 };
 
 &r_ir {
@@ -248,14 +312,166 @@
 			reg_rtc_ldo: rtc_ldo {
 				regulator-name = "vcc-rtc-vdd1v8-io";
 			};
+
+			sw {
+				/* unused */
+			};
+		};
+	};
+
+	axp806: pmic@745 {
+		compatible = "x-powers,axp806";
+		reg = <0x745>;
+		interrupt-parent = <&nmi_intc>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		bldoin-supply = <&reg_dcdce>;
+
+		regulators {
+			reg_s_aldo1: aldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-name = "avcc";
+			};
+
+			aldo2 {
+				/*
+				 * unused, but use a different name to
+				 * avoid name clash with axp809's aldo's
+				 */
+				regulator-name = "s_aldo2";
+			};
+
+			aldo3 {
+				/*
+				 * unused, but use a different name to
+				 * avoid name clash with axp809's aldo's
+				 */
+				regulator-name = "s_aldo3";
+			};
+
+			reg_bldo1: bldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <1700000>;
+				regulator-max-microvolt = <1900000>;
+				regulator-name = "vcc18-efuse-adc-display-csi";
+			};
+
+			reg_bldo2: bldo2 {
+				regulator-always-on;
+				regulator-min-microvolt = <1700000>;
+				regulator-max-microvolt = <1900000>;
+				regulator-name =
+					"vdd18-drampll-vcc18-pll-cpvdd";
+			};
+
+			bldo3 {
+				/* unused */
+			};
+
+			reg_bldo4: bldo4 {
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-name = "vcc12-hsic";
+			};
+
+			reg_cldo1: cldo1 {
+				/*
+				 * This was 3V in the original design, but
+				 * 3.3V is the recommended supply voltage
+				 * for the Ethernet PHY.
+				 */
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc-gmac-phy";
+			};
+
+			reg_cldo2: cldo2 {
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-name = "afvcc-cam";
+			};
+
+			reg_cldo3: cldo3 {
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-name = "vcc-io-wifi-codec-io2";
+			};
+
+			reg_dcdca: dcdca {
+				regulator-always-on;
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-cpub";
+			};
+
+			reg_dcdcd: dcdcd {
+				regulator-always-on;
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-vpu";
+			};
+
+			reg_dcdce: dcdce {
+				regulator-always-on;
+				regulator-min-microvolt = <2100000>;
+				regulator-max-microvolt = <2100000>;
+				regulator-name = "vcc-bldo-codec-ldoin";
+			};
+
+			sw {
+				/*
+				 * unused, but use a different name to
+				 * avoid name clash with axp809's sw
+				 */
+				regulator-name = "s_sw";
+			};
+		};
+	};
+
+	ac100: codec@e89 {
+		compatible = "x-powers,ac100";
+		reg = <0xe89>;
+
+		ac100_codec: codec {
+			compatible = "x-powers,ac100-codec";
+			interrupt-parent = <&r_pio>;
+			interrupts = <0 9 IRQ_TYPE_LEVEL_LOW>; /* PL9 */
+			#clock-cells = <0>;
+			clock-output-names = "4M_adda";
+		};
+
+		ac100_rtc: rtc {
+			compatible = "x-powers,ac100-rtc";
+			interrupt-parent = <&nmi_intc>;
+			interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+			clocks = <&ac100_codec>;
+			#clock-cells = <1>;
+			clock-output-names = "cko1_rtc",
+					     "cko2_rtc",
+					     "cko3_rtc";
 		};
 	};
 };
 
 #include "axp809.dtsi"
 
+&tcon0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&lcd0_rgb888_pins>;
+};
+
+&tcon0_out {
+	tcon0_out_vga: endpoint@0 {
+		reg = <0>;
+		remote-endpoint = <&vga_dac_in>;
+	};
+};
+
 &uart0 {
 	pinctrl-names = "default";
-	pinctrl-0 = <&uart0_pins_a>;
+	pinctrl-0 = <&uart0_ph_pins>;
 	status = "okay";
 };
diff --git a/arch/arm/dts/sun9i-a80-cx-a99.dts b/arch/arm/dts/sun9i-a80-cx-a99.dts
index a30b6fe..cf126bb 100644
--- a/arch/arm/dts/sun9i-a80-cx-a99.dts
+++ b/arch/arm/dts/sun9i-a80-cx-a99.dts
@@ -365,7 +365,7 @@
  */
 &uart0 {
 	pinctrl-names = "default";
-	pinctrl-0 = <&uart0_pins_a>;
+	pinctrl-0 = <&uart0_ph_pins>;
 	status = "okay";
 };
 
diff --git a/arch/arm/dts/sun9i-a80-optimus.dts b/arch/arm/dts/sun9i-a80-optimus.dts
index 7fd22e8..58a199b 100644
--- a/arch/arm/dts/sun9i-a80-optimus.dts
+++ b/arch/arm/dts/sun9i-a80-optimus.dts
@@ -46,7 +46,6 @@
 #include "sun9i-a80.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/pinctrl/sun4i-a10.h>
 
 / {
 	model = "Merrii A80 Optimus Board";
@@ -63,11 +62,8 @@
 
 	leds {
 		compatible = "gpio-leds";
-		pinctrl-names = "default";
-		pinctrl-0 = <&led_pins_optimus>, <&led_r_pins_optimus>;
 
 		/* The LED names match those found on the board */
-
 		led2 {
 			label = "optimus:led2:usr";
 			gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>;
@@ -87,8 +83,6 @@
 	reg_usb1_vbus: usb1-vbus {
 		compatible = "regulator-fixed";
 		pinctrl-names = "default";
-		pinctrl-0 = <&usb1_vbus_pin_optimus>;
-		regulator-name = "usb1-vbus";
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
 		enable-active-high;
@@ -98,13 +92,19 @@
 	reg_usb3_vbus: usb3-vbus {
 		compatible = "regulator-fixed";
 		pinctrl-names = "default";
-		pinctrl-0 = <&usb3_vbus_pin_optimus>;
-		regulator-name = "usb3-vbus";
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
 		enable-active-high;
 		gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
 	};
+
+	wifi_pwrseq: wifi-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		clocks = <&ac100_rtc 1>;
+		clock-names = "ext_clock";
+		/* enables internal regulator and de-asserts reset */
+		reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 WL-PMU-EN */
+	};
 };
 
 &ehci0 {
@@ -112,7 +112,8 @@
 };
 
 &ehci1 {
-	status = "okay";
+	/* Enable if HSIC peripheral is connected */
+	status = "disabled";
 };
 
 &ehci2 {
@@ -121,14 +122,28 @@
 
 &mmc0 {
 	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins>, <&mmc0_cd_pin_optimus>;
+	pinctrl-0 = <&mmc0_pins>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 18 GPIO_ACTIVE_HIGH>; /* PH8 */
-	cd-inverted;
+	cd-gpios = <&pio 7 18 GPIO_ACTIVE_LOW>; /* PH8 */
 	status = "okay";
 };
 
+&mmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc1_pins>;
+	vmmc-supply = <&reg_dldo1>;
+	vqmmc-supply = <&reg_cldo3>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+};
+
+&mmc1_pins {
+	bias-pull-up;
+};
+
 &mmc2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc2_8bit_pins>;
@@ -141,7 +156,7 @@
 
 &mmc2_8bit_pins {
 	/* Increase drive strength for DDR modes */
-	allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+	drive-strength = <40>;
 };
 
 &ohci0 {
@@ -152,49 +167,15 @@
 	status = "okay";
 };
 
-&pio {
-	led_pins_optimus: led-pins@0 {
-		allwinner,pins = "PH0", "PH1";
-		allwinner,function = "gpio_out";
-		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-	};
-
-	mmc0_cd_pin_optimus: mmc0_cd_pin@0 {
-		allwinner,pins = "PH18";
-		allwinner,function = "gpio_in";
-		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
-	};
-
-	usb1_vbus_pin_optimus: usb1_vbus_pin@1 {
-		allwinner,pins = "PH4";
-		allwinner,function = "gpio_out";
-		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-	};
-
-	usb3_vbus_pin_optimus: usb3_vbus_pin@1 {
-		allwinner,pins = "PH5";
-		allwinner,function = "gpio_out";
-		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-	};
+&osc32k {
+	/* osc32k input is from AC100 */
+	clocks = <&ac100_rtc 0>;
 };
 
 &r_ir {
 	status = "okay";
 };
 
-&r_pio {
-	led_r_pins_optimus: led-pins@1 {
-		allwinner,pins = "PM15";
-		allwinner,function = "gpio_out";
-		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-	};
-};
-
 &r_rsb {
 	status = "okay";
 
@@ -320,6 +301,146 @@
 			reg_rtc_ldo: rtc_ldo {
 				regulator-name = "vcc-rtc-vdd1v8-io";
 			};
+
+			sw {
+				/* unused */
+			};
+		};
+	};
+
+	axp806: pmic@745 {
+		compatible = "x-powers,axp806";
+		reg = <0x745>;
+		interrupt-parent = <&nmi_intc>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		bldoin-supply = <&reg_dcdce>;
+
+		regulators {
+			reg_s_aldo1: aldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-name = "avcc";
+			};
+
+			aldo2 {
+				/*
+				 * unused, but use a different name to
+				 * avoid name clash with axp809's aldo's
+				 */
+				regulator-name = "s_aldo2";
+			};
+
+			aldo3 {
+				/*
+				 * unused, but use a different name to
+				 * avoid name clash with axp809's aldo's
+				 */
+				regulator-name = "s_aldo3";
+			};
+
+			reg_bldo1: bldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <1700000>;
+				regulator-max-microvolt = <1900000>;
+				regulator-name = "vcc18-efuse-adc-display-csi";
+			};
+
+			reg_bldo2: bldo2 {
+				regulator-always-on;
+				regulator-min-microvolt = <1700000>;
+				regulator-max-microvolt = <1900000>;
+				regulator-name =
+					"vdd18-drampll-vcc18-pll-cpvdd";
+			};
+
+			bldo3 {
+				/* unused */
+			};
+
+			reg_bldo4: bldo4 {
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-name = "vcc12-hsic";
+			};
+
+			reg_cldo1: cldo1 {
+				/*
+				 * This was 3V in the original design, but
+				 * 3.3V is the recommended supply voltage
+				 * for the Ethernet PHY.
+				 */
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc-gmac-phy";
+			};
+
+			reg_cldo2: cldo2 {
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-name = "afvcc-cam";
+			};
+
+			reg_cldo3: cldo3 {
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-name = "vcc-io-wifi-codec-io2";
+			};
+
+			reg_dcdca: dcdca {
+				regulator-always-on;
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-cpub";
+			};
+
+			reg_dcdcd: dcdcd {
+				regulator-always-on;
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-vpu";
+			};
+
+			reg_dcdce: dcdce {
+				regulator-always-on;
+				regulator-min-microvolt = <2100000>;
+				regulator-max-microvolt = <2100000>;
+				regulator-name = "vcc-bldo-codec-ldoin";
+			};
+
+			sw {
+				/*
+				 * unused, but use a different name to
+				 * avoid name clash with axp809's sw
+				 */
+				regulator-name = "s_sw";
+			};
+		};
+	};
+
+	ac100: codec@e89 {
+		compatible = "x-powers,ac100";
+		reg = <0xe89>;
+
+		ac100_codec: codec {
+			compatible = "x-powers,ac100-codec";
+			interrupt-parent = <&r_pio>;
+			interrupts = <0 9 IRQ_TYPE_LEVEL_LOW>; /* PL9 */
+			#clock-cells = <0>;
+			clock-output-names = "4M_adda";
+		};
+
+		ac100_rtc: rtc {
+			compatible = "x-powers,ac100-rtc";
+			interrupt-parent = <&nmi_intc>;
+			interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+			clocks = <&ac100_codec>;
+			#clock-cells = <1>;
+			clock-output-names = "cko1_rtc",
+					     "cko2_rtc",
+					     "cko3_rtc";
 		};
 	};
 };
@@ -328,7 +449,7 @@
 
 &uart0 {
 	pinctrl-names = "default";
-	pinctrl-0 = <&uart0_pins_a>;
+	pinctrl-0 = <&uart0_ph_pins>;
 	status = "okay";
 };
 
@@ -338,7 +459,9 @@
 };
 
 &usbphy2 {
-	status = "okay";
+	phy-supply = <&reg_bldo4>;
+	/* Enable if HSIC peripheral is connected */
+	status = "disabled";
 };
 
 &usbphy3 {
diff --git a/arch/arm/dts/sun9i-a80.dtsi b/arch/arm/dts/sun9i-a80.dtsi
index 92412b2..25591d6 100644
--- a/arch/arm/dts/sun9i-a80.dtsi
+++ b/arch/arm/dts/sun9i-a80.dtsi
@@ -42,13 +42,18 @@
  *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#include "skeleton64.dtsi"
-
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
-#include <dt-bindings/pinctrl/sun4i-a10.h>
+#include <dt-bindings/clock/sun9i-a80-ccu.h>
+#include <dt-bindings/clock/sun9i-a80-de.h>
+#include <dt-bindings/clock/sun9i-a80-usb.h>
+#include <dt-bindings/reset/sun9i-a80-ccu.h>
+#include <dt-bindings/reset/sun9i-a80-de.h>
+#include <dt-bindings/reset/sun9i-a80-usb.h>
 
 / {
+	#address-cells = <2>;
+	#size-cells = <2>;
 	interrupt-parent = <&gic>;
 
 	cpus {
@@ -58,57 +63,76 @@
 		cpu0: cpu@0 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
+			cci-control-port = <&cci_control0>;
+			clock-frequency = <12000000>;
+			enable-method = "allwinner,sun9i-a80-smp";
 			reg = <0x0>;
 		};
 
 		cpu1: cpu@1 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
+			cci-control-port = <&cci_control0>;
+			clock-frequency = <12000000>;
+			enable-method = "allwinner,sun9i-a80-smp";
 			reg = <0x1>;
 		};
 
 		cpu2: cpu@2 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
+			cci-control-port = <&cci_control0>;
+			clock-frequency = <12000000>;
+			enable-method = "allwinner,sun9i-a80-smp";
 			reg = <0x2>;
 		};
 
 		cpu3: cpu@3 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
+			cci-control-port = <&cci_control0>;
+			clock-frequency = <12000000>;
+			enable-method = "allwinner,sun9i-a80-smp";
 			reg = <0x3>;
 		};
 
 		cpu4: cpu@100 {
 			compatible = "arm,cortex-a15";
 			device_type = "cpu";
+			cci-control-port = <&cci_control1>;
+			clock-frequency = <18000000>;
+			enable-method = "allwinner,sun9i-a80-smp";
 			reg = <0x100>;
 		};
 
 		cpu5: cpu@101 {
 			compatible = "arm,cortex-a15";
 			device_type = "cpu";
+			cci-control-port = <&cci_control1>;
+			clock-frequency = <18000000>;
+			enable-method = "allwinner,sun9i-a80-smp";
 			reg = <0x101>;
 		};
 
 		cpu6: cpu@102 {
 			compatible = "arm,cortex-a15";
 			device_type = "cpu";
+			cci-control-port = <&cci_control1>;
+			clock-frequency = <18000000>;
+			enable-method = "allwinner,sun9i-a80-smp";
 			reg = <0x102>;
 		};
 
 		cpu7: cpu@103 {
 			compatible = "arm,cortex-a15";
 			device_type = "cpu";
+			cci-control-port = <&cci_control1>;
+			clock-frequency = <18000000>;
+			enable-method = "allwinner,sun9i-a80-smp";
 			reg = <0x103>;
 		};
 	};
 
-	memory {
-		/* 8GB max. with LPAE */
-		reg = <0 0x20000000 0x02 0>;
-	};
-
 	timer {
 		compatible = "arm,armv7-timer";
 		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
@@ -139,7 +163,7 @@
 		 * would also throw all the PLL clock rates off, or just the
 		 * downstream clocks in the PRCM.
 		 */
-		osc24M: osc24M_clk {
+		osc24M: clk-24M {
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
 			clock-frequency = <24000000>;
@@ -148,244 +172,28 @@
 
 		/*
 		 * The 32k clock is from an external source, normally the
-		 * AC100 codec/RTC chip. This clock is by default enabled
-		 * and clocked at 32768 Hz, from the oscillator connected
-		 * to the AC100. It is configurable, but no such driver or
-		 * bindings exist yet.
+		 * AC100 codec/RTC chip. This serves as a placeholder for
+		 * board dts files to specify the source.
 		 */
-		osc32k: osc32k_clk {
+		osc32k: clk-32k {
 			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <32768>;
+			compatible = "fixed-factor-clock";
+			clock-div = <1>;
+			clock-mult = <1>;
 			clock-output-names = "osc32k";
 		};
 
-		usb_mod_clk: clk@00a08000 {
-			#clock-cells = <1>;
-			#reset-cells = <1>;
-			compatible = "allwinner,sun9i-a80-usb-mod-clk";
-			reg = <0x00a08000 0x4>;
-			clocks = <&ahb1_gates 1>;
-			clock-output-names = "usb0_ahb", "usb_ohci0",
-					     "usb1_ahb", "usb_ohci1",
-					     "usb2_ahb", "usb_ohci2";
-		};
-
-		usb_phy_clk: clk@00a08004 {
-			#clock-cells = <1>;
-			#reset-cells = <1>;
-			compatible = "allwinner,sun9i-a80-usb-phy-clk";
-			reg = <0x00a08004 0x4>;
-			clocks = <&ahb1_gates 1>;
-			clock-output-names = "usb_phy0", "usb_hsic1_480M",
-					     "usb_phy1", "usb_hsic2_480M",
-					     "usb_phy2", "usb_hsic_12M";
-		};
-
-		pll3: clk@06000008 {
-			/* placeholder until implemented */
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-rate = <0>;
-			clock-output-names = "pll3";
-		};
-
-		pll4: clk@0600000c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun9i-a80-pll4-clk";
-			reg = <0x0600000c 0x4>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll4";
-		};
-
-		pll12: clk@0600002c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun9i-a80-pll4-clk";
-			reg = <0x0600002c 0x4>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll12";
-		};
-
-		gt_clk: clk@0600005c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun9i-a80-gt-clk";
-			reg = <0x0600005c 0x4>;
-			clocks = <&osc24M>, <&pll4>, <&pll12>, <&pll12>;
-			clock-output-names = "gt";
-		};
-
-		ahb0: clk@06000060 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun9i-a80-ahb-clk";
-			reg = <0x06000060 0x4>;
-			clocks = <&gt_clk>, <&pll4>, <&pll12>, <&pll12>;
-			clock-output-names = "ahb0";
-		};
-
-		ahb1: clk@06000064 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun9i-a80-ahb-clk";
-			reg = <0x06000064 0x4>;
-			clocks = <&gt_clk>, <&pll4>, <&pll12>, <&pll12>;
-			clock-output-names = "ahb1";
-		};
-
-		ahb2: clk@06000068 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun9i-a80-ahb-clk";
-			reg = <0x06000068 0x4>;
-			clocks = <&gt_clk>, <&pll4>, <&pll12>, <&pll12>;
-			clock-output-names = "ahb2";
-		};
-
-		apb0: clk@06000070 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun9i-a80-apb0-clk";
-			reg = <0x06000070 0x4>;
-			clocks = <&osc24M>, <&pll4>;
-			clock-output-names = "apb0";
-		};
-
-		apb1: clk@06000074 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun9i-a80-apb1-clk";
-			reg = <0x06000074 0x4>;
-			clocks = <&osc24M>, <&pll4>;
-			clock-output-names = "apb1";
-		};
-
-		cci400_clk: clk@06000078 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun9i-a80-gt-clk";
-			reg = <0x06000078 0x4>;
-			clocks = <&osc24M>, <&pll4>, <&pll12>, <&pll12>;
-			clock-output-names = "cci400";
-		};
-
-		mmc0_clk: clk@06000410 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun9i-a80-mmc-clk";
-			reg = <0x06000410 0x4>;
-			clocks = <&osc24M>, <&pll4>;
-			clock-output-names = "mmc0", "mmc0_output",
-					     "mmc0_sample";
-		};
-
-		mmc1_clk: clk@06000414 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun9i-a80-mmc-clk";
-			reg = <0x06000414 0x4>;
-			clocks = <&osc24M>, <&pll4>;
-			clock-output-names = "mmc1", "mmc1_output",
-					     "mmc1_sample";
-		};
-
-		mmc2_clk: clk@06000418 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun9i-a80-mmc-clk";
-			reg = <0x06000418 0x4>;
-			clocks = <&osc24M>, <&pll4>;
-			clock-output-names = "mmc2", "mmc2_output",
-					     "mmc2_sample";
-		};
-
-		mmc3_clk: clk@0600041c {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun9i-a80-mmc-clk";
-			reg = <0x0600041c 0x4>;
-			clocks = <&osc24M>, <&pll4>;
-			clock-output-names = "mmc3", "mmc3_output",
-					     "mmc3_sample";
-		};
-
-		ahb0_gates: clk@06000580 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun9i-a80-ahb0-gates-clk";
-			reg = <0x06000580 0x4>;
-			clocks = <&ahb0>;
-			clock-indices = <0>, <1>, <3>,
-					<5>, <8>, <12>,
-					<13>, <14>,
-					<15>, <16>, <18>,
-					<20>, <21>, <22>,
-					<23>;
-			clock-output-names = "ahb0_fd", "ahb0_ve", "ahb0_gpu",
-					"ahb0_ss", "ahb0_sd", "ahb0_nand1",
-					"ahb0_nand0", "ahb0_sdram",
-					"ahb0_mipi_hsi", "ahb0_sata", "ahb0_ts",
-					"ahb0_spi0", "ahb0_spi1", "ahb0_spi2",
-					"ahb0_spi3";
-		};
-
-		ahb1_gates: clk@06000584 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun9i-a80-ahb1-gates-clk";
-			reg = <0x06000584 0x4>;
-			clocks = <&ahb1>;
-			clock-indices = <0>, <1>,
-					<17>, <21>,
-					<22>, <23>,
-					<24>;
-			clock-output-names = "ahb1_usbotg", "ahb1_usbhci",
-					"ahb1_gmac", "ahb1_msgbox",
-					"ahb1_spinlock", "ahb1_hstimer",
-					"ahb1_dma";
-		};
-
-		ahb2_gates: clk@06000588 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun9i-a80-ahb2-gates-clk";
-			reg = <0x06000588 0x4>;
-			clocks = <&ahb2>;
-			clock-indices = <0>, <1>,
-					<2>, <4>, <5>,
-					<7>, <8>, <11>;
-			clock-output-names = "ahb2_lcd0", "ahb2_lcd1",
-					"ahb2_edp", "ahb2_csi", "ahb2_hdmi",
-					"ahb2_de", "ahb2_mp", "ahb2_mipi_dsi";
-		};
-
-		apb0_gates: clk@06000590 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun9i-a80-apb0-gates-clk";
-			reg = <0x06000590 0x4>;
-			clocks = <&apb0>;
-			clock-indices = <1>, <5>,
-					<11>, <12>, <13>,
-					<15>, <17>, <18>,
-					<19>;
-			clock-output-names = "apb0_spdif", "apb0_pio",
-					"apb0_ac97", "apb0_i2s0", "apb0_i2s1",
-					"apb0_lradc", "apb0_gpadc", "apb0_twd",
-					"apb0_cirtx";
-		};
-
-		apb1_gates: clk@06000594 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun9i-a80-apb1-gates-clk";
-			reg = <0x06000594 0x4>;
-			clocks = <&apb1>;
-			clock-indices = <0>, <1>,
-					<2>, <3>, <4>,
-					<16>, <17>,
-					<18>, <19>,
-					<20>, <21>;
-			clock-output-names = "apb1_i2c0", "apb1_i2c1",
-					"apb1_i2c2", "apb1_i2c3", "apb1_i2c4",
-					"apb1_uart0", "apb1_uart1",
-					"apb1_uart2", "apb1_uart3",
-					"apb1_uart4", "apb1_uart5";
-		};
-
-		cpus_clk: clk@08001410 {
+		cpus_clk: clk@8001410 {
 			compatible = "allwinner,sun9i-a80-cpus-clk";
 			reg = <0x08001410 0x4>;
 			#clock-cells = <0>;
-			clocks = <&osc32k>, <&osc24M>, <&pll4>, <&pll3>;
+			clocks = <&osc32k>, <&osc24M>,
+				 <&ccu CLK_PLL_PERIPH0>,
+				 <&ccu CLK_PLL_AUDIO>;
 			clock-output-names = "cpus";
 		};
 
-		ahbs: ahbs_clk {
+		ahbs: clk-ahbs {
 			compatible = "fixed-factor-clock";
 			#clock-cells = <0>;
 			clock-div = <1>;
@@ -394,7 +202,7 @@
 			clock-output-names = "ahbs";
 		};
 
-		apbs: clk@0800141c {
+		apbs: clk@800141c {
 			compatible = "allwinner,sun8i-a23-apb0-clk";
 			reg = <0x0800141c 0x4>;
 			#clock-cells = <0>;
@@ -402,7 +210,7 @@
 			clock-output-names = "apbs";
 		};
 
-		apbs_gates: clk@08001428 {
+		apbs_gates: clk@8001428 {
 			compatible = "allwinner,sun9i-a80-apbs-gates-clk";
 			reg = <0x08001428 0x4>;
 			#clock-cells = <1>;
@@ -423,7 +231,7 @@
 					"apbs_i2s1", "apbs_twd";
 		};
 
-		r_1wire_clk: clk@08001450 {
+		r_1wire_clk: clk@8001450 {
 			reg = <0x08001450 0x4>;
 			#clock-cells = <0>;
 			compatible = "allwinner,sun4i-a10-mod0-clk";
@@ -431,7 +239,7 @@
 			clock-output-names = "r_1wire";
 		};
 
-		r_ir_clk: clk@08001454 {
+		r_ir_clk: clk@8001454 {
 			reg = <0x08001454 0x4>;
 			#clock-cells = <0>;
 			compatible = "allwinner,sun4i-a10-mod0-clk";
@@ -440,6 +248,12 @@
 		};
 	};
 
+	de: display-engine {
+		compatible = "allwinner,sun9i-a80-display-engine";
+		allwinner,pipelines = <&fe0>, <&fe1>;
+		status = "disabled";
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <1>;
@@ -450,103 +264,149 @@
 		 */
 		ranges = <0 0 0 0x20000000>;
 
-		ehci0: usb@00a00000 {
+		sram_b: sram@20000 {
+			/* 256 KiB secure SRAM at 0x20000 */
+			compatible = "mmio-sram";
+			reg = <0x00020000 0x40000>;
+
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0x00020000 0x40000>;
+
+			smp-sram@1000 {
+				/*
+				 * This is checked by BROM to determine if
+				 * cpu0 should jump to SMP entry vector
+				 */
+				compatible = "allwinner,sun9i-a80-smp-sram";
+				reg = <0x1000 0x8>;
+			};
+		};
+
+		ehci0: usb@a00000 {
 			compatible = "allwinner,sun9i-a80-ehci", "generic-ehci";
 			reg = <0x00a00000 0x100>;
 			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&usb_mod_clk 1>;
-			resets = <&usb_mod_clk 17>;
+			clocks = <&usb_clocks CLK_BUS_HCI0>;
+			resets = <&usb_clocks RST_USB0_HCI>;
 			phys = <&usbphy1>;
 			phy-names = "usb";
 			status = "disabled";
 		};
 
-		ohci0: usb@00a00400 {
+		ohci0: usb@a00400 {
 			compatible = "allwinner,sun9i-a80-ohci", "generic-ohci";
 			reg = <0x00a00400 0x100>;
 			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&usb_mod_clk 1>, <&usb_mod_clk 2>;
-			resets = <&usb_mod_clk 17>;
+			clocks = <&usb_clocks CLK_BUS_HCI0>,
+				 <&usb_clocks CLK_USB_OHCI0>;
+			resets = <&usb_clocks RST_USB0_HCI>;
 			phys = <&usbphy1>;
 			phy-names = "usb";
 			status = "disabled";
 		};
 
-		usbphy1: phy@00a00800 {
+		usbphy1: phy@a00800 {
 			compatible = "allwinner,sun9i-a80-usb-phy";
 			reg = <0x00a00800 0x4>;
-			clocks = <&usb_phy_clk 1>;
+			clocks = <&usb_clocks CLK_USB0_PHY>;
 			clock-names = "phy";
-			resets = <&usb_phy_clk 17>;
+			resets = <&usb_clocks RST_USB0_PHY>;
 			reset-names = "phy";
 			status = "disabled";
 			#phy-cells = <0>;
 		};
 
-		ehci1: usb@00a01000 {
+		ehci1: usb@a01000 {
 			compatible = "allwinner,sun9i-a80-ehci", "generic-ehci";
 			reg = <0x00a01000 0x100>;
 			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&usb_mod_clk 3>;
-			resets = <&usb_mod_clk 18>;
+			clocks = <&usb_clocks CLK_BUS_HCI1>;
+			resets = <&usb_clocks RST_USB1_HCI>;
 			phys = <&usbphy2>;
 			phy-names = "usb";
 			status = "disabled";
 		};
 
-		usbphy2: phy@00a01800 {
+		usbphy2: phy@a01800 {
 			compatible = "allwinner,sun9i-a80-usb-phy";
 			reg = <0x00a01800 0x4>;
-			clocks = <&usb_phy_clk 2>, <&usb_phy_clk 10>,
-				 <&usb_phy_clk 3>;
-			clock-names = "hsic_480M", "hsic_12M", "phy";
-			resets = <&usb_phy_clk 18>, <&usb_phy_clk 19>;
-			reset-names = "hsic", "phy";
+			clocks = <&usb_clocks CLK_USB1_HSIC>,
+				 <&usb_clocks CLK_USB_HSIC>,
+				 <&usb_clocks CLK_USB1_PHY>;
+			clock-names = "hsic_480M",
+				      "hsic_12M",
+				      "phy";
+			resets = <&usb_clocks RST_USB1_HSIC>,
+				 <&usb_clocks RST_USB1_PHY>;
+			reset-names = "hsic",
+				      "phy";
 			status = "disabled";
 			#phy-cells = <0>;
 			/* usb1 is always used with HSIC */
 			phy_type = "hsic";
 		};
 
-		ehci2: usb@00a02000 {
+		ehci2: usb@a02000 {
 			compatible = "allwinner,sun9i-a80-ehci", "generic-ehci";
 			reg = <0x00a02000 0x100>;
 			interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&usb_mod_clk 5>;
-			resets = <&usb_mod_clk 19>;
+			clocks = <&usb_clocks CLK_BUS_HCI2>;
+			resets = <&usb_clocks RST_USB2_HCI>;
 			phys = <&usbphy3>;
 			phy-names = "usb";
 			status = "disabled";
 		};
 
-		ohci2: usb@00a02400 {
+		ohci2: usb@a02400 {
 			compatible = "allwinner,sun9i-a80-ohci", "generic-ohci";
 			reg = <0x00a02400 0x100>;
 			interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&usb_mod_clk 5>, <&usb_mod_clk 6>;
-			resets = <&usb_mod_clk 19>;
+			clocks = <&usb_clocks CLK_BUS_HCI2>,
+				 <&usb_clocks CLK_USB_OHCI2>;
+			resets = <&usb_clocks RST_USB2_HCI>;
 			phys = <&usbphy3>;
 			phy-names = "usb";
 			status = "disabled";
 		};
 
-		usbphy3: phy@00a02800 {
+		usbphy3: phy@a02800 {
 			compatible = "allwinner,sun9i-a80-usb-phy";
 			reg = <0x00a02800 0x4>;
-			clocks = <&usb_phy_clk 4>, <&usb_phy_clk 10>,
-				 <&usb_phy_clk 5>;
-			clock-names = "hsic_480M", "hsic_12M", "phy";
-			resets = <&usb_phy_clk 20>, <&usb_phy_clk 21>;
-			reset-names = "hsic", "phy";
+			clocks = <&usb_clocks CLK_USB2_HSIC>,
+				 <&usb_clocks CLK_USB_HSIC>,
+				 <&usb_clocks CLK_USB2_PHY>;
+			clock-names = "hsic_480M",
+				      "hsic_12M",
+				      "phy";
+			resets = <&usb_clocks RST_USB2_HSIC>,
+				 <&usb_clocks RST_USB2_PHY>;
+			reset-names = "hsic",
+				      "phy";
 			status = "disabled";
 			#phy-cells = <0>;
 		};
 
-		mmc0: mmc@01c0f000 {
+		usb_clocks: clock@a08000 {
+			compatible = "allwinner,sun9i-a80-usb-clks";
+			reg = <0x00a08000 0x8>;
+			clocks = <&ccu CLK_BUS_USB>, <&osc24M>;
+			clock-names = "bus", "hosc";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		cpucfg@1700000 {
+			compatible = "allwinner,sun9i-a80-cpucfg";
+			reg = <0x01700000 0x100>;
+		};
+
+		mmc0: mmc@1c0f000 {
 			compatible = "allwinner,sun9i-a80-mmc";
 			reg = <0x01c0f000 0x1000>;
-			clocks = <&mmc_config_clk 0>, <&mmc0_clk 0>,
-				 <&mmc0_clk 1>, <&mmc0_clk 2>;
+			clocks = <&mmc_config_clk 0>, <&ccu CLK_MMC0>,
+				 <&ccu CLK_MMC0_OUTPUT>,
+				 <&ccu CLK_MMC0_SAMPLE>;
 			clock-names = "ahb", "mmc", "output", "sample";
 			resets = <&mmc_config_clk 0>;
 			reset-names = "ahb";
@@ -556,11 +416,12 @@
 			#size-cells = <0>;
 		};
 
-		mmc1: mmc@01c10000 {
+		mmc1: mmc@1c10000 {
 			compatible = "allwinner,sun9i-a80-mmc";
 			reg = <0x01c10000 0x1000>;
-			clocks = <&mmc_config_clk 1>, <&mmc1_clk 0>,
-				 <&mmc1_clk 1>, <&mmc1_clk 2>;
+			clocks = <&mmc_config_clk 1>, <&ccu CLK_MMC1>,
+				 <&ccu CLK_MMC1_OUTPUT>,
+				 <&ccu CLK_MMC1_SAMPLE>;
 			clock-names = "ahb", "mmc", "output", "sample";
 			resets = <&mmc_config_clk 1>;
 			reset-names = "ahb";
@@ -570,11 +431,12 @@
 			#size-cells = <0>;
 		};
 
-		mmc2: mmc@01c11000 {
+		mmc2: mmc@1c11000 {
 			compatible = "allwinner,sun9i-a80-mmc";
 			reg = <0x01c11000 0x1000>;
-			clocks = <&mmc_config_clk 2>, <&mmc2_clk 0>,
-				 <&mmc2_clk 1>, <&mmc2_clk 2>;
+			clocks = <&mmc_config_clk 2>, <&ccu CLK_MMC2>,
+				 <&ccu CLK_MMC2_OUTPUT>,
+				 <&ccu CLK_MMC2_SAMPLE>;
 			clock-names = "ahb", "mmc", "output", "sample";
 			resets = <&mmc_config_clk 2>;
 			reset-names = "ahb";
@@ -584,11 +446,12 @@
 			#size-cells = <0>;
 		};
 
-		mmc3: mmc@01c12000 {
+		mmc3: mmc@1c12000 {
 			compatible = "allwinner,sun9i-a80-mmc";
 			reg = <0x01c12000 0x1000>;
-			clocks = <&mmc_config_clk 3>, <&mmc3_clk 0>,
-				 <&mmc3_clk 1>, <&mmc3_clk 2>;
+			clocks = <&mmc_config_clk 3>, <&ccu CLK_MMC3>,
+				 <&ccu CLK_MMC3_OUTPUT>,
+				 <&ccu CLK_MMC3_SAMPLE>;
 			clock-names = "ahb", "mmc", "output", "sample";
 			resets = <&mmc_config_clk 3>;
 			reset-names = "ahb";
@@ -598,12 +461,12 @@
 			#size-cells = <0>;
 		};
 
-		mmc_config_clk: clk@01c13000 {
+		mmc_config_clk: clk@1c13000 {
 			compatible = "allwinner,sun9i-a80-mmc-config-clk";
 			reg = <0x01c13000 0x10>;
-			clocks = <&ahb0_gates 8>;
+			clocks = <&ccu CLK_BUS_MMC>;
 			clock-names = "ahb";
-			resets = <&ahb0_resets 8>;
+			resets = <&ccu RST_BUS_MMC>;
 			reset-names = "ahb";
 			#clock-cells = <1>;
 			#reset-cells = <1>;
@@ -611,10 +474,10 @@
 					     "mmc2_config", "mmc3_config";
 		};
 
-		gic: interrupt-controller@01c41000 {
+		gic: interrupt-controller@1c41000 {
 			compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
 			reg = <0x01c41000 0x1000>,
-			      <0x01c42000 0x1000>,
+			      <0x01c42000 0x2000>,
 			      <0x01c44000 0x2000>,
 			      <0x01c46000 0x2000>;
 			interrupt-controller;
@@ -622,37 +485,435 @@
 			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
 		};
 
-		ahb0_resets: reset@060005a0 {
-			#reset-cells = <1>;
-			compatible = "allwinner,sun6i-a31-clock-reset";
-			reg = <0x060005a0 0x4>;
+		cci: cci@1c90000 {
+			compatible = "arm,cci-400";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x01c90000 0x1000>;
+			ranges = <0x0 0x01c90000 0x10000>;
+
+			cci_control0: slave-if@4000 {
+				compatible = "arm,cci-400-ctrl-if";
+				interface-type = "ace";
+				reg = <0x4000 0x1000>;
+			};
+
+			cci_control1: slave-if@5000 {
+				compatible = "arm,cci-400-ctrl-if";
+				interface-type = "ace";
+				reg = <0x5000 0x1000>;
+			};
+
+			pmu@9000 {
+				 compatible = "arm,cci-400-pmu,r1";
+				 reg = <0x9000 0x5000>;
+				 interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+					      <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+					      <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+					      <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+					      <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
+			};
 		};
 
-		ahb1_resets: reset@060005a4 {
+		de_clocks: clock@3000000 {
+			compatible = "allwinner,sun9i-a80-de-clks";
+			reg = <0x03000000 0x30>;
+			clocks = <&ccu CLK_DE>,
+				 <&ccu CLK_SDRAM>,
+				 <&ccu CLK_BUS_DE>;
+			clock-names = "mod",
+				      "dram",
+				      "bus";
+			resets = <&ccu RST_BUS_DE>;
+			#clock-cells = <1>;
 			#reset-cells = <1>;
-			compatible = "allwinner,sun6i-a31-clock-reset";
-			reg = <0x060005a4 0x4>;
 		};
 
-		ahb2_resets: reset@060005a8 {
-			#reset-cells = <1>;
-			compatible = "allwinner,sun6i-a31-clock-reset";
-			reg = <0x060005a8 0x4>;
+		fe0: display-frontend@3100000 {
+			compatible = "allwinner,sun9i-a80-display-frontend";
+			reg = <0x03100000 0x40000>;
+			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&de_clocks CLK_BUS_FE0>, <&de_clocks CLK_FE0>,
+				 <&de_clocks CLK_DRAM_FE0>;
+			clock-names = "ahb", "mod",
+				      "ram";
+			resets = <&de_clocks RST_FE0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				fe0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					fe0_out_deu0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&deu0_in_fe0>;
+					};
+				};
+			};
 		};
 
-		apb0_resets: reset@060005b0 {
-			#reset-cells = <1>;
-			compatible = "allwinner,sun6i-a31-clock-reset";
-			reg = <0x060005b0 0x4>;
+		fe1: display-frontend@3140000 {
+			compatible = "allwinner,sun9i-a80-display-frontend";
+			reg = <0x03140000 0x40000>;
+			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&de_clocks CLK_BUS_FE1>, <&de_clocks CLK_FE1>,
+				 <&de_clocks CLK_DRAM_FE1>;
+			clock-names = "ahb", "mod",
+				      "ram";
+			resets = <&de_clocks RST_FE0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				fe1_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					fe1_out_deu1: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&deu1_in_fe1>;
+					};
+				};
+			};
 		};
 
-		apb1_resets: reset@060005b4 {
-			#reset-cells = <1>;
-			compatible = "allwinner,sun6i-a31-clock-reset";
-			reg = <0x060005b4 0x4>;
+		be0: display-backend@3200000 {
+			compatible = "allwinner,sun9i-a80-display-backend";
+			reg = <0x03200000 0x40000>;
+			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&de_clocks CLK_BUS_BE0>, <&de_clocks CLK_BE0>,
+				 <&de_clocks CLK_DRAM_BE0>;
+			clock-names = "ahb", "mod",
+				      "ram";
+			resets = <&de_clocks RST_BE0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				be0_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					be0_in_deu0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&deu0_out_be0>;
+					};
+
+					be0_in_deu1: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&deu1_out_be0>;
+					};
+				};
+
+				be0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					be0_out_drc0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&drc0_in_be0>;
+					};
+				};
+			};
 		};
 
-		timer@06000c00 {
+		be1: display-backend@3240000 {
+			compatible = "allwinner,sun9i-a80-display-backend";
+			reg = <0x03240000 0x40000>;
+			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&de_clocks CLK_BUS_BE1>, <&de_clocks CLK_BE1>,
+				 <&de_clocks CLK_DRAM_BE1>;
+			clock-names = "ahb", "mod",
+				      "ram";
+			resets = <&de_clocks RST_BE1>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				be1_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					be1_in_deu0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&deu0_out_be1>;
+					};
+
+					be1_in_deu1: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&deu1_out_be1>;
+					};
+				};
+
+				be1_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					be1_out_drc1: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&drc1_in_be1>;
+					};
+				};
+			};
+		};
+
+		deu0: deu@3300000 {
+			compatible = "allwinner,sun9i-a80-deu";
+			reg = <0x03300000 0x40000>;
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&de_clocks CLK_BUS_DEU0>,
+				 <&de_clocks CLK_IEP_DEU0>,
+				 <&de_clocks CLK_DRAM_DEU0>;
+			clock-names = "ahb",
+				      "mod",
+				      "ram";
+			resets = <&de_clocks RST_DEU0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				deu0_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					deu0_in_fe0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&fe0_out_deu0>;
+					};
+				};
+
+				deu0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					deu0_out_be0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&be0_in_deu0>;
+					};
+
+					deu0_out_be1: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&be1_in_deu0>;
+					};
+				};
+			};
+		};
+
+		deu1: deu@3340000 {
+			compatible = "allwinner,sun9i-a80-deu";
+			reg = <0x03340000 0x40000>;
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&de_clocks CLK_BUS_DEU1>,
+				 <&de_clocks CLK_IEP_DEU1>,
+				 <&de_clocks CLK_DRAM_DEU1>;
+			clock-names = "ahb",
+				      "mod",
+				      "ram";
+			resets = <&de_clocks RST_DEU1>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				deu1_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					deu1_in_fe1: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&fe1_out_deu1>;
+					};
+				};
+
+				deu1_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					deu1_out_be0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&be0_in_deu1>;
+					};
+
+					deu1_out_be1: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&be1_in_deu1>;
+					};
+				};
+			};
+		};
+
+		drc0: drc@3400000 {
+			compatible = "allwinner,sun9i-a80-drc";
+			reg = <0x03400000 0x40000>;
+			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&de_clocks CLK_BUS_DRC0>,
+				 <&de_clocks CLK_IEP_DRC0>,
+				 <&de_clocks CLK_DRAM_DRC0>;
+			clock-names = "ahb",
+				      "mod",
+				      "ram";
+			resets = <&de_clocks RST_DRC0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				drc0_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					drc0_in_be0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&be0_out_drc0>;
+					};
+				};
+
+				drc0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					drc0_out_tcon0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&tcon0_in_drc0>;
+					};
+				};
+			};
+		};
+
+		drc1: drc@3440000 {
+			compatible = "allwinner,sun9i-a80-drc";
+			reg = <0x03440000 0x40000>;
+			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&de_clocks CLK_BUS_DRC1>,
+				 <&de_clocks CLK_IEP_DRC1>,
+				 <&de_clocks CLK_DRAM_DRC1>;
+			clock-names = "ahb",
+				      "mod",
+				      "ram";
+			resets = <&de_clocks RST_DRC1>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				drc1_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					drc1_in_be1: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&be1_out_drc1>;
+					};
+				};
+
+				drc1_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					drc1_out_tcon1: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&tcon1_in_drc1>;
+					};
+				};
+			};
+		};
+
+		tcon0: lcd-controller@3c00000 {
+			compatible = "allwinner,sun9i-a80-tcon-lcd";
+			reg = <0x03c00000 0x10000>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_LCD0>, <&ccu CLK_LCD0>;
+			clock-names = "ahb", "tcon-ch0";
+			resets = <&ccu RST_BUS_LCD0>, <&ccu RST_BUS_EDP>;
+			reset-names = "lcd", "edp";
+			clock-output-names = "tcon0-pixel-clock";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon0_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					tcon0_in_drc0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&drc0_out_tcon0>;
+					};
+				};
+
+				tcon0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+			};
+		};
+
+		tcon1: lcd-controller@3c10000 {
+			compatible = "allwinner,sun9i-a80-tcon-tv";
+			reg = <0x03c10000 0x10000>;
+			interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_LCD1>, <&ccu CLK_LCD1>;
+			clock-names = "ahb", "tcon-ch1";
+			resets = <&ccu RST_BUS_LCD1>, <&ccu RST_BUS_EDP>;
+			reset-names = "lcd", "edp";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon1_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					tcon1_in_drc1: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&drc1_out_tcon1>;
+					};
+				};
+
+				tcon1_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+			};
+		};
+
+		ccu: clock@6000000 {
+			compatible = "allwinner,sun9i-a80-ccu";
+			reg = <0x06000000 0x800>;
+			clocks = <&osc24M>, <&osc32k>;
+			clock-names = "hosc", "losc";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		timer@6000c00 {
 			compatible = "allwinner,sun4i-a10-timer";
 			reg = <0x06000c00 0xa0>;
 			interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
@@ -665,13 +926,13 @@
 			clocks = <&osc24M>;
 		};
 
-		wdt: watchdog@06000ca0 {
+		wdt: watchdog@6000ca0 {
 			compatible = "allwinner,sun6i-a31-wdt";
 			reg = <0x06000ca0 0x20>;
 			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
-		pio: pinctrl@06000800 {
+		pio: pinctrl@6000800 {
 			compatible = "allwinner,sun9i-a80-pinctrl";
 			reg = <0x06000800 0x400>;
 			interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
@@ -679,195 +940,206 @@
 				     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&apb0_gates 5>;
+			clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
+			clock-names = "apb", "hosc", "losc";
 			gpio-controller;
 			interrupt-controller;
 			#interrupt-cells = <3>;
 			#size-cells = <0>;
 			#gpio-cells = <3>;
 
-			i2c3_pins_a: i2c3@0 {
-				allwinner,pins = "PG10", "PG11";
-				allwinner,function = "i2c3";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			i2c3_pins: i2c3-pins {
+				pins = "PG10", "PG11";
+				function = "i2c3";
 			};
 
-			mmc0_pins: mmc0 {
-				allwinner,pins = "PF0", "PF1" ,"PF2", "PF3",
-						 "PF4", "PF5";
-				allwinner,function = "mmc0";
-				allwinner,drive = <SUN4I_PINCTRL_30_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			lcd0_rgb888_pins: lcd0-rgb888-pins {
+				pins = "PD0", "PD1", "PD2", "PD3",
+				       "PD4", "PD5", "PD6", "PD7",
+				       "PD8", "PD9", "PD10", "PD11",
+				       "PD12", "PD13", "PD14", "PD15",
+				       "PD16", "PD17", "PD18", "PD19",
+				       "PD20", "PD21", "PD22", "PD23",
+				       "PD24", "PD25", "PD26", "PD27";
+				function = "lcd0";
 			};
 
-			mmc1_pins: mmc1 {
-				allwinner,pins = "PG0", "PG1" ,"PG2", "PG3",
+			mmc0_pins: mmc0-pins {
+				pins = "PF0", "PF1" ,"PF2", "PF3",
+				       "PF4", "PF5";
+				function = "mmc0";
+				drive-strength = <30>;
+				bias-pull-up;
+			};
+
+			mmc1_pins: mmc1-pins {
+				pins = "PG0", "PG1" ,"PG2", "PG3",
 						 "PG4", "PG5";
-				allwinner,function = "mmc1";
-				allwinner,drive = <SUN4I_PINCTRL_30_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+				function = "mmc1";
+				drive-strength = <30>;
+				bias-pull-up;
 			};
 
-			mmc2_8bit_pins: mmc2_8bit {
-				allwinner,pins = "PC6", "PC7", "PC8", "PC9",
-						 "PC10", "PC11", "PC12",
-						 "PC13", "PC14", "PC15",
-						 "PC16";
-				allwinner,function = "mmc2";
-				allwinner,drive = <SUN4I_PINCTRL_30_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			mmc2_8bit_pins: mmc2-8bit-pins {
+				pins = "PC6", "PC7", "PC8", "PC9",
+				       "PC10", "PC11", "PC12",
+				       "PC13", "PC14", "PC15",
+				       "PC16";
+				function = "mmc2";
+				drive-strength = <30>;
+				bias-pull-up;
 			};
 
-			uart0_pins_a: uart0@0 {
-				allwinner,pins = "PH12", "PH13";
-				allwinner,function = "uart0";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			uart0_ph_pins: uart0-ph-pins {
+				pins = "PH12", "PH13";
+				function = "uart0";
 			};
 
-			uart4_pins_a: uart4@0 {
-				allwinner,pins = "PG12", "PG13", "PG14", "PG15";
-				allwinner,function = "uart4";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			uart4_pins: uart4-pins {
+				pins = "PG12", "PG13", "PG14", "PG15";
+				function = "uart4";
 			};
 		};
 
-		uart0: serial@07000000 {
+		uart0: serial@7000000 {
 			compatible = "snps,dw-apb-uart";
 			reg = <0x07000000 0x400>;
 			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
-			clocks = <&apb1_gates 16>;
-			resets = <&apb1_resets 16>;
+			clocks = <&ccu CLK_BUS_UART0>;
+			resets = <&ccu RST_BUS_UART0>;
 			status = "disabled";
 		};
 
-		uart1: serial@07000400 {
+		uart1: serial@7000400 {
 			compatible = "snps,dw-apb-uart";
 			reg = <0x07000400 0x400>;
 			interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
-			clocks = <&apb1_gates 17>;
-			resets = <&apb1_resets 17>;
+			clocks = <&ccu CLK_BUS_UART1>;
+			resets = <&ccu RST_BUS_UART1>;
 			status = "disabled";
 		};
 
-		uart2: serial@07000800 {
+		uart2: serial@7000800 {
 			compatible = "snps,dw-apb-uart";
 			reg = <0x07000800 0x400>;
 			interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
-			clocks = <&apb1_gates 18>;
-			resets = <&apb1_resets 18>;
+			clocks = <&ccu CLK_BUS_UART2>;
+			resets = <&ccu RST_BUS_UART2>;
 			status = "disabled";
 		};
 
-		uart3: serial@07000c00 {
+		uart3: serial@7000c00 {
 			compatible = "snps,dw-apb-uart";
 			reg = <0x07000c00 0x400>;
 			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
-			clocks = <&apb1_gates 19>;
-			resets = <&apb1_resets 19>;
+			clocks = <&ccu CLK_BUS_UART3>;
+			resets = <&ccu RST_BUS_UART3>;
 			status = "disabled";
 		};
 
-		uart4: serial@07001000 {
+		uart4: serial@7001000 {
 			compatible = "snps,dw-apb-uart";
 			reg = <0x07001000 0x400>;
 			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
-			clocks = <&apb1_gates 20>;
-			resets = <&apb1_resets 20>;
+			clocks = <&ccu CLK_BUS_UART4>;
+			resets = <&ccu RST_BUS_UART4>;
 			status = "disabled";
 		};
 
-		uart5: serial@07001400 {
+		uart5: serial@7001400 {
 			compatible = "snps,dw-apb-uart";
 			reg = <0x07001400 0x400>;
 			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
-			clocks = <&apb1_gates 21>;
-			resets = <&apb1_resets 21>;
+			clocks = <&ccu CLK_BUS_UART5>;
+			resets = <&ccu RST_BUS_UART5>;
 			status = "disabled";
 		};
 
-		i2c0: i2c@07002800 {
+		i2c0: i2c@7002800 {
 			compatible = "allwinner,sun6i-a31-i2c";
 			reg = <0x07002800 0x400>;
 			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&apb1_gates 0>;
-			resets = <&apb1_resets 0>;
+			clocks = <&ccu CLK_BUS_I2C0>;
+			resets = <&ccu RST_BUS_I2C0>;
 			status = "disabled";
 			#address-cells = <1>;
 			#size-cells = <0>;
 		};
 
-		i2c1: i2c@07002c00 {
+		i2c1: i2c@7002c00 {
 			compatible = "allwinner,sun6i-a31-i2c";
 			reg = <0x07002c00 0x400>;
 			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&apb1_gates 1>;
-			resets = <&apb1_resets 1>;
+			clocks = <&ccu CLK_BUS_I2C1>;
+			resets = <&ccu RST_BUS_I2C1>;
 			status = "disabled";
 			#address-cells = <1>;
 			#size-cells = <0>;
 		};
 
-		i2c2: i2c@07003000 {
+		i2c2: i2c@7003000 {
 			compatible = "allwinner,sun6i-a31-i2c";
 			reg = <0x07003000 0x400>;
 			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&apb1_gates 2>;
-			resets = <&apb1_resets 2>;
+			clocks = <&ccu CLK_BUS_I2C2>;
+			resets = <&ccu RST_BUS_I2C2>;
 			status = "disabled";
 			#address-cells = <1>;
 			#size-cells = <0>;
 		};
 
-		i2c3: i2c@07003400 {
+		i2c3: i2c@7003400 {
 			compatible = "allwinner,sun6i-a31-i2c";
 			reg = <0x07003400 0x400>;
 			interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&apb1_gates 3>;
-			resets = <&apb1_resets 3>;
+			clocks = <&ccu CLK_BUS_I2C3>;
+			resets = <&ccu RST_BUS_I2C3>;
 			status = "disabled";
 			#address-cells = <1>;
 			#size-cells = <0>;
 		};
 
-		i2c4: i2c@07003800 {
+		i2c4: i2c@7003800 {
 			compatible = "allwinner,sun6i-a31-i2c";
 			reg = <0x07003800 0x400>;
 			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&apb1_gates 4>;
-			resets = <&apb1_resets 4>;
+			clocks = <&ccu CLK_BUS_I2C4>;
+			resets = <&ccu RST_BUS_I2C4>;
 			status = "disabled";
 			#address-cells = <1>;
 			#size-cells = <0>;
 		};
 
-		r_wdt: watchdog@08001000 {
+		r_wdt: watchdog@8001000 {
 			compatible = "allwinner,sun6i-a31-wdt";
 			reg = <0x08001000 0x20>;
 			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
-		apbs_rst: reset@080014b0 {
+		prcm@8001400 {
+			compatible = "allwinner,sun9i-a80-prcm";
+			reg = <0x08001400 0x200>;
+		};
+
+		apbs_rst: reset@80014b0 {
 			reg = <0x080014b0 0x4>;
 			compatible = "allwinner,sun6i-a31-clock-reset";
 			#reset-cells = <1>;
 		};
 
-		nmi_intc: interrupt-controller@080015a0 {
+		nmi_intc: interrupt-controller@80015a0 {
 			compatible = "allwinner,sun9i-a80-nmi";
 			interrupt-controller;
 			#interrupt-cells = <2>;
@@ -875,7 +1147,7 @@
 			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
-		r_ir: ir@08002000 {
+		r_ir: ir@8002000 {
 			compatible = "allwinner,sun5i-a13-ir";
 			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
 			pinctrl-names = "default";
@@ -887,7 +1159,7 @@
 			status = "disabled";
 		};
 
-		r_uart: serial@08002800 {
+		r_uart: serial@8002800 {
 			compatible = "snps,dw-apb-uart";
 			reg = <0x08002800 0x400>;
 			interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
@@ -898,35 +1170,33 @@
 			status = "disabled";
 		};
 
-		r_pio: pinctrl@08002c00 {
+		r_pio: pinctrl@8002c00 {
 			compatible = "allwinner,sun9i-a80-r-pinctrl";
 			reg = <0x08002c00 0x400>;
 			interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&apbs_gates 0>;
+			clocks = <&apbs_gates 0>, <&osc24M>, <&osc32k>;
+			clock-names = "apb", "hosc", "losc";
 			resets = <&apbs_rst 0>;
 			gpio-controller;
 			interrupt-controller;
-			#address-cells = <1>;
-			#size-cells = <0>;
+			#interrupt-cells = <3>;
 			#gpio-cells = <3>;
 
-			r_ir_pins: r_ir {
-				allwinner,pins = "PL6";
-				allwinner,function = "s_cir_rx";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			r_ir_pins: r-ir-pins {
+				pins = "PL6";
+				function = "s_cir_rx";
 			};
 
-			r_rsb_pins: r_rsb {
-				allwinner,pins = "PN0", "PN1";
-				allwinner,function = "s_rsb";
-				allwinner,drive = <SUN4I_PINCTRL_20_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+			r_rsb_pins: r-rsb-pins {
+				pins = "PN0", "PN1";
+				function = "s_rsb";
+				drive-strength = <20>;
+				bias-pull-up;
 			};
 		};
 
-		r_rsb: i2c@08003400 {
+		r_rsb: i2c@8003400 {
 			compatible = "allwinner,sun8i-a23-rsb";
 			reg = <0x08003400 0x400>;
 			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/include/asm/arch-sunxi/ccu.h b/arch/arm/include/asm/arch-sunxi/ccu.h
new file mode 100644
index 0000000..5dd97ab
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/ccu.h
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Amarula Solutions.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#ifndef _ASM_ARCH_CCU_H
+#define _ASM_ARCH_CCU_H
+
+/**
+ * enum ccu_flags - ccu clock/reset flags
+ *
+ * @CCU_CLK_F_IS_VALID:		is given clock gate is valid?
+ * @CCU_RST_F_IS_VALID:		is given reset control is valid?
+ */
+enum ccu_flags {
+	CCU_CLK_F_IS_VALID		= BIT(0),
+	CCU_RST_F_IS_VALID		= BIT(1),
+};
+
+/**
+ * struct ccu_clk_gate - ccu clock gate
+ * @off:	gate offset
+ * @bit:	gate bit
+ * @flags:	ccu clock gate flags
+ */
+struct ccu_clk_gate {
+	u16 off;
+	u32 bit;
+	enum ccu_flags flags;
+};
+
+#define GATE(_off, _bit) {			\
+	.off = _off,				\
+	.bit = _bit,				\
+	.flags = CCU_CLK_F_IS_VALID,		\
+}
+
+/**
+ * struct ccu_reset - ccu reset
+ * @off:	reset offset
+ * @bit:	reset bit
+ * @flags:	ccu reset control flags
+ */
+struct ccu_reset {
+	u16 off;
+	u32 bit;
+	enum ccu_flags flags;
+};
+
+#define RESET(_off, _bit) {			\
+	.off = _off,				\
+	.bit = _bit,				\
+	.flags = CCU_RST_F_IS_VALID,		\
+}
+
+/**
+ * struct ccu_desc - clock control unit descriptor
+ *
+ * @gates:	clock gates
+ * @resets:	reset unit
+ */
+struct ccu_desc {
+	const struct ccu_clk_gate *gates;
+	const struct ccu_reset *resets;
+};
+
+/**
+ * struct ccu_priv - sunxi clock control unit
+ *
+ * @base:	base address
+ * @desc:	ccu descriptor
+ */
+struct ccu_priv {
+	void *base;
+	const struct ccu_desc *desc;
+};
+
+/**
+ * sunxi_clk_probe - common sunxi clock probe
+ * @dev:	clock device
+ */
+int sunxi_clk_probe(struct udevice *dev);
+
+extern struct clk_ops sunxi_clk_ops;
+
+/**
+ * sunxi_reset_bind() - reset binding
+ *
+ * @dev:       reset device
+ * @count:     reset count
+ * @return 0 success, or error value
+ */
+int sunxi_reset_bind(struct udevice *dev, ulong count);
+
+#endif /* _ASM_ARCH_CCU_H */
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index 2daf23f..40a3f84 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -176,6 +176,7 @@
 
 #define SUN5I_GPE_SDC2		3
 #define SUN8I_GPE_TWI2		3
+#define SUN50I_GPE_TWI2		3
 
 #define SUNXI_GPF_SDC0		2
 #define SUNXI_GPF_UART0		4
@@ -193,8 +194,10 @@
 #define SUN4I_GPH_SDC1		5
 #define SUN6I_GPH_TWI0		2
 #define SUN8I_GPH_TWI0		2
+#define SUN50I_GPH_TWI0		2
 #define SUN6I_GPH_TWI1		2
 #define SUN8I_GPH_TWI1		2
+#define SUN50I_GPH_TWI1		2
 #define SUN6I_GPH_TWI2		2
 #define SUN6I_GPH_UART0		2
 #define SUN9I_GPH_UART0		2
diff --git a/arch/powerpc/cpu/mpc85xx/config.mk b/arch/powerpc/cpu/mpc85xx/config.mk
index 44d69ad..7a1d81c 100644
--- a/arch/powerpc/cpu/mpc85xx/config.mk
+++ b/arch/powerpc/cpu/mpc85xx/config.mk
@@ -4,6 +4,7 @@
 # Xianghua Xiao, X.Xiao@motorola.com
 
 PLATFORM_CPPFLAGS += -Wa,-me500 -msoft-float -mno-string
+PLATFORM_RELFLAGS += -msingle-pic-base -fno-jump-tables
 
 # -mspe=yes is needed to have -mno-spe accepted by a buggy GCC;
 # see "[PATCH,rs6000] make -mno-spe work as expected" on
diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S
index 932aa08..dbc7053 100644
--- a/arch/powerpc/cpu/mpc85xx/start.S
+++ b/arch/powerpc/cpu/mpc85xx/start.S
@@ -1216,6 +1216,9 @@
 	mr	r1,r3		/* Transfer to SP(r1) */
 
 	GET_GOT
+	/* Needed for -msingle-pic-base */
+	bl	_GLOBAL_OFFSET_TABLE_@local-4
+	mflr	r30
 
 	/* Pass our potential ePAPR device tree pointer to cpu_init_early_f */
 	mr	r3, r24
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index 9b6e0c4..608a86b 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -182,6 +182,11 @@
 S:	Maintained
 F:	configs/Cubietruck_plus_defconfig
 
+EMLID NEUTIS N5 DEV BOARD
+M:	Aleksandr Aleksandrov <aleksandr.aleksandrov@emlid.com>
+S:	Maintained
+F:	configs/emlid_neutis_n5_devboard_defconfig
+
 GEMEI-G9 TABLET
 M:	Priit Laes <plaes@plaes.org>
 S:	Maintained
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index f022f36..ad14837 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -98,6 +98,10 @@
 	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);
+#elif defined(CONFIG_MACH_SUN50I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(0), SUN50I_GPH_TWI0);
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(1), SUN50I_GPH_TWI0);
+	clock_twi_onoff(0, 1);
 #endif
 #endif
 
@@ -120,6 +124,10 @@
 	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);
+#elif defined(CONFIG_MACH_SUN50I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN50I_GPH_TWI1);
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN50I_GPH_TWI1);
+	clock_twi_onoff(1, 1);
 #endif
 #endif
 
@@ -142,6 +150,10 @@
 	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);
+#elif defined(CONFIG_MACH_SUN50I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPE(14), SUN50I_GPE_TWI2);
+	sunxi_gpio_set_cfgpin(SUNXI_GPE(15), SUN50I_GPE_TWI2);
+	clock_twi_onoff(2, 1);
 #endif
 #endif
 
diff --git a/configs/A10-OLinuXino-Lime_defconfig b/configs/A10-OLinuXino-Lime_defconfig
index 55134a9..9b8891e 100644
--- a/configs/A10-OLinuXino-Lime_defconfig
+++ b/configs/A10-OLinuXino-Lime_defconfig
@@ -22,5 +22,6 @@
 CONFIG_AXP_ALDO3_VOLT=2800
 CONFIG_AXP_ALDO4_VOLT=2800
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/A10s-OLinuXino-M_defconfig b/configs/A10s-OLinuXino-M_defconfig
index d0fb4d7..fcf4890 100644
--- a/configs/A10s-OLinuXino-M_defconfig
+++ b/configs/A10s-OLinuXino-M_defconfig
@@ -18,5 +18,6 @@
 CONFIG_SUN4I_EMAC=y
 CONFIG_AXP152_POWER=y
 CONFIG_CONS_INDEX=2
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/A13-OLinuXinoM_defconfig b/configs/A13-OLinuXinoM_defconfig
index 8837455..aedb0c3 100644
--- a/configs/A13-OLinuXinoM_defconfig
+++ b/configs/A13-OLinuXinoM_defconfig
@@ -19,5 +19,6 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino-micro"
 CONFIG_SUNXI_NO_PMIC=y
 CONFIG_CONS_INDEX=2
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/A13-OLinuXino_defconfig b/configs/A13-OLinuXino_defconfig
index 7b836dd..eb76bf8 100644
--- a/configs/A13-OLinuXino_defconfig
+++ b/configs/A13-OLinuXino_defconfig
@@ -26,6 +26,7 @@
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_AXP_ALDO3_VOLT=3300
 CONFIG_CONS_INDEX=2
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/A20-OLinuXino-Lime2-eMMC_defconfig b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
index 3e9f574..d74afd5 100644
--- a/configs/A20-OLinuXino-Lime2-eMMC_defconfig
+++ b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
@@ -31,6 +31,7 @@
 CONFIG_AXP_ALDO3_INRUSH_QUIRK=y
 CONFIG_AXP_ALDO4_VOLT=2800
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig
index e7ca335..a10cc0b 100644
--- a/configs/A20-OLinuXino-Lime2_defconfig
+++ b/configs/A20-OLinuXino-Lime2_defconfig
@@ -30,6 +30,7 @@
 CONFIG_AXP_ALDO3_INRUSH_QUIRK=y
 CONFIG_AXP_ALDO4_VOLT=2800
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/A20-OLinuXino-Lime_defconfig b/configs/A20-OLinuXino-Lime_defconfig
index 91f5210..9e13792 100644
--- a/configs/A20-OLinuXino-Lime_defconfig
+++ b/configs/A20-OLinuXino-Lime_defconfig
@@ -21,5 +21,6 @@
 CONFIG_AXP_ALDO3_VOLT=2800
 CONFIG_AXP_ALDO4_VOLT=2800
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/A20-OLinuXino_MICRO-eMMC_defconfig b/configs/A20-OLinuXino_MICRO-eMMC_defconfig
index 20964c5..73e6f7c 100644
--- a/configs/A20-OLinuXino_MICRO-eMMC_defconfig
+++ b/configs/A20-OLinuXino_MICRO-eMMC_defconfig
@@ -24,5 +24,6 @@
 CONFIG_AXP_ALDO3_VOLT=2800
 CONFIG_AXP_ALDO4_VOLT=2800
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/A20-OLinuXino_MICRO_defconfig b/configs/A20-OLinuXino_MICRO_defconfig
index cf9bf33..bd68511 100644
--- a/configs/A20-OLinuXino_MICRO_defconfig
+++ b/configs/A20-OLinuXino_MICRO_defconfig
@@ -25,5 +25,6 @@
 CONFIG_AXP_ALDO3_VOLT=2800
 CONFIG_AXP_ALDO4_VOLT=2800
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/A20-Olimex-SOM-EVB_defconfig b/configs/A20-Olimex-SOM-EVB_defconfig
index a31f96c..c38025a 100644
--- a/configs/A20-Olimex-SOM-EVB_defconfig
+++ b/configs/A20-Olimex-SOM-EVB_defconfig
@@ -26,5 +26,6 @@
 CONFIG_AXP_ALDO3_VOLT=2800
 CONFIG_AXP_ALDO4_VOLT=2800
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig b/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig
index c9e9475..778c2ee 100644
--- a/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig
+++ b/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig
@@ -30,6 +30,7 @@
 CONFIG_AXP_ALDO3_VOLT=2800
 CONFIG_AXP_ALDO4_VOLT=2800
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/A20-Olimex-SOM204-EVB_defconfig b/configs/A20-Olimex-SOM204-EVB_defconfig
index 1181832..e853c93 100644
--- a/configs/A20-Olimex-SOM204-EVB_defconfig
+++ b/configs/A20-Olimex-SOM204-EVB_defconfig
@@ -29,6 +29,7 @@
 CONFIG_AXP_ALDO3_VOLT=2800
 CONFIG_AXP_ALDO4_VOLT=2800
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Auxtek-T003_defconfig b/configs/Auxtek-T003_defconfig
index a693cfd..c2a681c 100644
--- a/configs/Auxtek-T003_defconfig
+++ b/configs/Auxtek-T003_defconfig
@@ -15,5 +15,6 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun5i-a10s-auxtek-t003"
 CONFIG_AXP152_POWER=y
 CONFIG_CONS_INDEX=2
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Auxtek-T004_defconfig b/configs/Auxtek-T004_defconfig
index 5c88b2b..bc5fc8c 100644
--- a/configs/Auxtek-T004_defconfig
+++ b/configs/Auxtek-T004_defconfig
@@ -13,5 +13,6 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun5i-a10s-auxtek-t004"
 CONFIG_AXP152_POWER=y
 CONFIG_CONS_INDEX=2
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Bananapi_defconfig b/configs/Bananapi_defconfig
index 41cb9fc..67daec6 100644
--- a/configs/Bananapi_defconfig
+++ b/configs/Bananapi_defconfig
@@ -21,5 +21,6 @@
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Bananapi_m2m_defconfig b/configs/Bananapi_m2m_defconfig
index 990c791..c8dfa7d 100644
--- a/configs/Bananapi_m2m_defconfig
+++ b/configs/Bananapi_m2m_defconfig
@@ -15,6 +15,7 @@
 # CONFIG_SPL_PARTITION_UUIDS is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-r16-bananapi-m2m"
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_USB_FUNCTION_MASS_STORAGE=y
diff --git a/configs/Bananapro_defconfig b/configs/Bananapro_defconfig
index 41fc6a6..cd5d8b6 100644
--- a/configs/Bananapro_defconfig
+++ b/configs/Bananapro_defconfig
@@ -24,5 +24,6 @@
 CONFIG_SUN7I_GMAC=y
 CONFIG_AXP_ALDO4_VOLT=2500
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/CHIP_defconfig b/configs/CHIP_defconfig
index ffdffcd..67fe58b 100644
--- a/configs/CHIP_defconfig
+++ b/configs/CHIP_defconfig
@@ -17,6 +17,7 @@
 CONFIG_AXP_ALDO3_VOLT=3300
 CONFIG_AXP_ALDO4_VOLT=3300
 CONFIG_CONS_INDEX=2
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/CHIP_pro_defconfig b/configs/CHIP_pro_defconfig
index c607adb..618f113 100644
--- a/configs/CHIP_pro_defconfig
+++ b/configs/CHIP_pro_defconfig
@@ -22,6 +22,7 @@
 CONFIG_AXP_ALDO3_VOLT=3300
 CONFIG_AXP_ALDO4_VOLT=3300
 CONFIG_CONS_INDEX=2
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/CSQ_CS908_defconfig b/configs/CSQ_CS908_defconfig
index ffc64d6..9036ffc 100644
--- a/configs/CSQ_CS908_defconfig
+++ b/configs/CSQ_CS908_defconfig
@@ -16,6 +16,7 @@
 CONFIG_SUN7I_GMAC=y
 CONFIG_AXP_ALDO1_VOLT=3300
 CONFIG_AXP_DLDO1_VOLT=3300
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Colombus_defconfig b/configs/Colombus_defconfig
index 77c7e9e..cb65647 100644
--- a/configs/Colombus_defconfig
+++ b/configs/Colombus_defconfig
@@ -26,5 +26,6 @@
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_AXP_ALDO1_VOLT=3300
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Cubieboard2_defconfig b/configs/Cubieboard2_defconfig
index 366f55b..7fe5b83 100644
--- a/configs/Cubieboard2_defconfig
+++ b/configs/Cubieboard2_defconfig
@@ -18,5 +18,6 @@
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Cubieboard_defconfig b/configs/Cubieboard_defconfig
index efc3e25..ccb612a 100644
--- a/configs/Cubieboard_defconfig
+++ b/configs/Cubieboard_defconfig
@@ -17,5 +17,6 @@
 CONFIG_MII=y
 CONFIG_SUN4I_EMAC=y
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Cubietruck_defconfig b/configs/Cubietruck_defconfig
index 86bef3d..3beb515 100644
--- a/configs/Cubietruck_defconfig
+++ b/configs/Cubietruck_defconfig
@@ -28,6 +28,7 @@
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Cubietruck_plus_defconfig b/configs/Cubietruck_plus_defconfig
index 2f43bbd..cecb428 100644
--- a/configs/Cubietruck_plus_defconfig
+++ b/configs/Cubietruck_plus_defconfig
@@ -23,6 +23,7 @@
 CONFIG_AXP_DLDO3_VOLT=2500
 CONFIG_AXP_DLDO4_VOLT=3300
 CONFIG_AXP_FLDO1_VOLT=1200
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Hummingbird_A31_defconfig b/configs/Hummingbird_A31_defconfig
index b3e9d0a..0f0b1c2 100644
--- a/configs/Hummingbird_A31_defconfig
+++ b/configs/Hummingbird_A31_defconfig
@@ -18,5 +18,6 @@
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_AXP_ALDO1_VOLT=3300
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Itead_Ibox_A20_defconfig b/configs/Itead_Ibox_A20_defconfig
index 721bc87..784c4de 100644
--- a/configs/Itead_Ibox_A20_defconfig
+++ b/configs/Itead_Ibox_A20_defconfig
@@ -18,5 +18,6 @@
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Lamobo_R1_defconfig b/configs/Lamobo_R1_defconfig
index 9eb3c08..88f8a15 100644
--- a/configs/Lamobo_R1_defconfig
+++ b/configs/Lamobo_R1_defconfig
@@ -23,5 +23,6 @@
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Linksprite_pcDuino3_Nano_defconfig b/configs/Linksprite_pcDuino3_Nano_defconfig
index 09aae78..72d9b03 100644
--- a/configs/Linksprite_pcDuino3_Nano_defconfig
+++ b/configs/Linksprite_pcDuino3_Nano_defconfig
@@ -21,5 +21,6 @@
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Linksprite_pcDuino3_defconfig b/configs/Linksprite_pcDuino3_defconfig
index 00a49d1..9156f13 100644
--- a/configs/Linksprite_pcDuino3_defconfig
+++ b/configs/Linksprite_pcDuino3_defconfig
@@ -20,5 +20,6 @@
 CONFIG_SUN7I_GMAC=y
 CONFIG_SCSI=y
 CONFIG_DM_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Linksprite_pcDuino_defconfig b/configs/Linksprite_pcDuino_defconfig
index 81dbb72..21cfea1 100644
--- a/configs/Linksprite_pcDuino_defconfig
+++ b/configs/Linksprite_pcDuino_defconfig
@@ -13,5 +13,6 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-pcduino"
 CONFIG_MII=y
 CONFIG_SUN4I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/MK808C_defconfig b/configs/MK808C_defconfig
index f634ac8..367a164 100644
--- a/configs/MK808C_defconfig
+++ b/configs/MK808C_defconfig
@@ -10,5 +10,6 @@
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-mk808c"
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Marsboard_A10_defconfig b/configs/Marsboard_A10_defconfig
index ae7c266..c40e452 100644
--- a/configs/Marsboard_A10_defconfig
+++ b/configs/Marsboard_A10_defconfig
@@ -14,5 +14,6 @@
 CONFIG_SUN4I_EMAC=y
 CONFIG_SUNXI_NO_PMIC=y
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Mele_A1000G_quad_defconfig b/configs/Mele_A1000G_quad_defconfig
index a2c6135..feabbbf 100644
--- a/configs/Mele_A1000G_quad_defconfig
+++ b/configs/Mele_A1000G_quad_defconfig
@@ -19,6 +19,7 @@
 CONFIG_AXP_ALDO1_VOLT=3300
 CONFIG_AXP_DLDO1_VOLT=3300
 CONFIG_AXP_DLDO4_VOLT=3300
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Mele_A1000_defconfig b/configs/Mele_A1000_defconfig
index 4967209..9375c5d 100644
--- a/configs/Mele_A1000_defconfig
+++ b/configs/Mele_A1000_defconfig
@@ -17,5 +17,6 @@
 CONFIG_MII=y
 CONFIG_SUN4I_EMAC=y
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Mele_I7_defconfig b/configs/Mele_I7_defconfig
index aac4fa1..eecf89b 100644
--- a/configs/Mele_I7_defconfig
+++ b/configs/Mele_I7_defconfig
@@ -18,5 +18,6 @@
 CONFIG_AXP_ALDO1_VOLT=3300
 CONFIG_AXP_DLDO1_VOLT=3300
 CONFIG_AXP_DLDO4_VOLT=3300
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Mele_M3_defconfig b/configs/Mele_M3_defconfig
index acd98bc..9738f8b 100644
--- a/configs/Mele_M3_defconfig
+++ b/configs/Mele_M3_defconfig
@@ -17,5 +17,6 @@
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Mele_M5_defconfig b/configs/Mele_M5_defconfig
index e473da7..c76bc9f 100644
--- a/configs/Mele_M5_defconfig
+++ b/configs/Mele_M5_defconfig
@@ -19,5 +19,6 @@
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Mele_M9_defconfig b/configs/Mele_M9_defconfig
index 63bf3fd..d3136c6 100644
--- a/configs/Mele_M9_defconfig
+++ b/configs/Mele_M9_defconfig
@@ -18,5 +18,6 @@
 CONFIG_AXP_ALDO1_VOLT=3300
 CONFIG_AXP_DLDO1_VOLT=3300
 CONFIG_AXP_DLDO4_VOLT=3300
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Mini-X_defconfig b/configs/Mini-X_defconfig
index 161feea..54b40d5 100644
--- a/configs/Mini-X_defconfig
+++ b/configs/Mini-X_defconfig
@@ -12,5 +12,6 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-mini-xplus"
 CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Orangepi_defconfig b/configs/Orangepi_defconfig
index 3ea1d03..dae821a 100644
--- a/configs/Orangepi_defconfig
+++ b/configs/Orangepi_defconfig
@@ -23,5 +23,6 @@
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Orangepi_mini_defconfig b/configs/Orangepi_mini_defconfig
index 737c7a9..e1cbbbd 100644
--- a/configs/Orangepi_mini_defconfig
+++ b/configs/Orangepi_mini_defconfig
@@ -25,5 +25,6 @@
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Sinlinx_SinA31s_defconfig b/configs/Sinlinx_SinA31s_defconfig
index dbc8c08..efa3b86 100644
--- a/configs/Sinlinx_SinA31s_defconfig
+++ b/configs/Sinlinx_SinA31s_defconfig
@@ -19,5 +19,6 @@
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_AXP_DLDO1_VOLT=3300
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Sinlinx_SinA33_defconfig b/configs/Sinlinx_SinA33_defconfig
index df078c4..b92d621 100644
--- a/configs/Sinlinx_SinA33_defconfig
+++ b/configs/Sinlinx_SinA33_defconfig
@@ -20,6 +20,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-a33-sinlinx-sina33"
 CONFIG_DFU_RAM=y
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Sinovoip_BPI_M2_Plus_defconfig b/configs/Sinovoip_BPI_M2_Plus_defconfig
index 35c4718..c2025ee 100644
--- a/configs/Sinovoip_BPI_M2_Plus_defconfig
+++ b/configs/Sinovoip_BPI_M2_Plus_defconfig
@@ -14,6 +14,7 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-bananapi-m2-plus"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Sinovoip_BPI_M2_defconfig b/configs/Sinovoip_BPI_M2_defconfig
index 83ef4b4..fd69ac5 100644
--- a/configs/Sinovoip_BPI_M2_defconfig
+++ b/configs/Sinovoip_BPI_M2_defconfig
@@ -18,5 +18,6 @@
 CONFIG_AXP_ALDO1_VOLT=3300
 CONFIG_AXP_ALDO2_VOLT=1800
 CONFIG_AXP_DLDO1_VOLT=3000
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Sinovoip_BPI_M3_defconfig b/configs/Sinovoip_BPI_M3_defconfig
index 9f04731..ec59feb 100644
--- a/configs/Sinovoip_BPI_M3_defconfig
+++ b/configs/Sinovoip_BPI_M3_defconfig
@@ -24,6 +24,7 @@
 CONFIG_AXP_DCDC5_VOLT=1200
 CONFIG_AXP_DLDO3_VOLT=2500
 CONFIG_AXP_SW_ON=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Wexler_TAB7200_defconfig b/configs/Wexler_TAB7200_defconfig
index 58c65b7..a2351dc 100644
--- a/configs/Wexler_TAB7200_defconfig
+++ b/configs/Wexler_TAB7200_defconfig
@@ -18,6 +18,7 @@
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-wexler-tab7200"
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Wits_Pro_A20_DKT_defconfig b/configs/Wits_Pro_A20_DKT_defconfig
index 1fc7a4d..cc8ba58 100644
--- a/configs/Wits_Pro_A20_DKT_defconfig
+++ b/configs/Wits_Pro_A20_DKT_defconfig
@@ -23,5 +23,6 @@
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/Wobo_i5_defconfig b/configs/Wobo_i5_defconfig
index a0dca6a..17f03c8 100644
--- a/configs/Wobo_i5_defconfig
+++ b/configs/Wobo_i5_defconfig
@@ -15,5 +15,6 @@
 CONFIG_AXP_ALDO3_VOLT=3300
 CONFIG_AXP_ALDO4_VOLT=3300
 CONFIG_CONS_INDEX=2
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/a64-olinuxino_defconfig b/configs/a64-olinuxino_defconfig
index 01fcb86..94ac94c 100644
--- a/configs/a64-olinuxino_defconfig
+++ b/configs/a64-olinuxino_defconfig
@@ -11,5 +11,6 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-olinuxino"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/ba10_tv_box_defconfig b/configs/ba10_tv_box_defconfig
index 846fab2..76a980e 100644
--- a/configs/ba10_tv_box_defconfig
+++ b/configs/ba10_tv_box_defconfig
@@ -16,6 +16,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-ba10-tvbox"
 CONFIG_MII=y
 CONFIG_SUN4I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/bananapi_m1_plus_defconfig b/configs/bananapi_m1_plus_defconfig
index 7286d21..46baf34 100644
--- a/configs/bananapi_m1_plus_defconfig
+++ b/configs/bananapi_m1_plus_defconfig
@@ -21,4 +21,5 @@
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_SCSI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
diff --git a/configs/bananapi_m64_defconfig b/configs/bananapi_m64_defconfig
index aa0ad3c..7dc768f 100644
--- a/configs/bananapi_m64_defconfig
+++ b/configs/bananapi_m64_defconfig
@@ -12,6 +12,7 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-bananapi-m64"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/emlid_neutis_n5_devboard_defconfig b/configs/emlid_neutis_n5_devboard_defconfig
new file mode 100644
index 0000000..3df0ca1
--- /dev/null
+++ b/configs/emlid_neutis_n5_devboard_defconfig
@@ -0,0 +1,13 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_SPL=y
+CONFIG_MACH_SUN50I_H5=y
+CONFIG_DRAM_CLK=408
+CONFIG_DRAM_ZQ=3881977
+CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+CONFIG_NR_DRAM_BANKS=1
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_DEFAULT_DEVICE_TREE="sun50i-h5-emlid-neutis-n5-devboard"
diff --git a/configs/ga10h_v1_1_defconfig b/configs/ga10h_v1_1_defconfig
index 4c88285..0049982 100644
--- a/configs/ga10h_v1_1_defconfig
+++ b/configs/ga10h_v1_1_defconfig
@@ -23,6 +23,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-a33-ga10h-v1.1"
 CONFIG_AXP_DLDO1_VOLT=3300
 CONFIG_CONS_INDEX=5
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/h8_homlet_v2_defconfig b/configs/h8_homlet_v2_defconfig
index 7aad6f0..6e1cc00 100644
--- a/configs/h8_homlet_v2_defconfig
+++ b/configs/h8_homlet_v2_defconfig
@@ -16,6 +16,7 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-a83t-allwinner-h8homlet-v2"
 CONFIG_AXP_DLDO4_VOLT=3300
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/i12-tvbox_defconfig b/configs/i12-tvbox_defconfig
index 4b3a8a3..fea490d 100644
--- a/configs/i12-tvbox_defconfig
+++ b/configs/i12-tvbox_defconfig
@@ -15,5 +15,6 @@
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/icnova-a20-swac_defconfig b/configs/icnova-a20-swac_defconfig
index 07c89a4..99cc7e8 100644
--- a/configs/icnova-a20-swac_defconfig
+++ b/configs/icnova-a20-swac_defconfig
@@ -22,5 +22,6 @@
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/inet1_defconfig b/configs/inet1_defconfig
index 79e594b..b5b94d9 100644
--- a/configs/inet1_defconfig
+++ b/configs/inet1_defconfig
@@ -19,6 +19,7 @@
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-inet1"
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/inet_q972_defconfig b/configs/inet_q972_defconfig
index d15f71a..7f3d04d 100644
--- a/configs/inet_q972_defconfig
+++ b/configs/inet_q972_defconfig
@@ -20,6 +20,7 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31s-inet-q972"
 CONFIG_AXP_DLDO1_VOLT=3300
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/jesurun_q5_defconfig b/configs/jesurun_q5_defconfig
index ce48537..e6f90c0 100644
--- a/configs/jesurun_q5_defconfig
+++ b/configs/jesurun_q5_defconfig
@@ -15,6 +15,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-jesurun-q5"
 CONFIG_MII=y
 CONFIG_SUN4I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/libretech_all_h3_cc_h2_plus_defconfig b/configs/libretech_all_h3_cc_h2_plus_defconfig
index 2c7a3ff..9c2e28f 100644
--- a/configs/libretech_all_h3_cc_h2_plus_defconfig
+++ b/configs/libretech_all_h3_cc_h2_plus_defconfig
@@ -13,5 +13,6 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h2-plus-libretech-all-h3-cc"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/libretech_all_h3_cc_h3_defconfig b/configs/libretech_all_h3_cc_h3_defconfig
index bd2c708..9130a59 100644
--- a/configs/libretech_all_h3_cc_h3_defconfig
+++ b/configs/libretech_all_h3_cc_h3_defconfig
@@ -13,5 +13,6 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-libretech-all-h3-cc"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/libretech_all_h3_cc_h5_defconfig b/configs/libretech_all_h3_cc_h5_defconfig
index 001f53d..eb0d5dc 100644
--- a/configs/libretech_all_h3_cc_h5_defconfig
+++ b/configs/libretech_all_h3_cc_h5_defconfig
@@ -13,5 +13,6 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun50i-h5-libretech-all-h3-cc"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/mixtile_loftq_defconfig b/configs/mixtile_loftq_defconfig
index 9ebb55c..55d0649 100644
--- a/configs/mixtile_loftq_defconfig
+++ b/configs/mixtile_loftq_defconfig
@@ -18,5 +18,6 @@
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_AXP_ALDO1_VOLT=3300
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/mk802_a10s_defconfig b/configs/mk802_a10s_defconfig
index 3fba55e..5a0b502 100644
--- a/configs/mk802_a10s_defconfig
+++ b/configs/mk802_a10s_defconfig
@@ -14,5 +14,6 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun5i-a10s-mk802"
 CONFIG_AXP152_POWER=y
 CONFIG_CONS_INDEX=2
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/mk802_defconfig b/configs/mk802_defconfig
index 1b59348..14f8fee 100644
--- a/configs/mk802_defconfig
+++ b/configs/mk802_defconfig
@@ -10,5 +10,6 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-mk802"
 CONFIG_SUNXI_NO_PMIC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/mk802ii_defconfig b/configs/mk802ii_defconfig
index 7a3f3d1..abd261d 100644
--- a/configs/mk802ii_defconfig
+++ b/configs/mk802ii_defconfig
@@ -9,5 +9,6 @@
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-mk802ii"
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/nanopi_a64_defconfig b/configs/nanopi_a64_defconfig
index cd3b59f..4dfd36e 100644
--- a/configs/nanopi_a64_defconfig
+++ b/configs/nanopi_a64_defconfig
@@ -10,5 +10,6 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-nanopi-a64"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/nanopi_m1_defconfig b/configs/nanopi_m1_defconfig
index bf4e874..c8efce8 100644
--- a/configs/nanopi_m1_defconfig
+++ b/configs/nanopi_m1_defconfig
@@ -11,5 +11,6 @@
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-nanopi-m1"
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/nanopi_m1_plus_defconfig b/configs/nanopi_m1_plus_defconfig
index 66e9091..79b1c69 100644
--- a/configs/nanopi_m1_plus_defconfig
+++ b/configs/nanopi_m1_plus_defconfig
@@ -13,5 +13,6 @@
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-nanopi-m1-plus"
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/nanopi_neo2_defconfig b/configs/nanopi_neo2_defconfig
index ee693be..8892f6c 100644
--- a/configs/nanopi_neo2_defconfig
+++ b/configs/nanopi_neo2_defconfig
@@ -11,5 +11,6 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun50i-h5-nanopi-neo2"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/nanopi_neo_air_defconfig b/configs/nanopi_neo_air_defconfig
index 8c362fa..1495304 100644
--- a/configs/nanopi_neo_air_defconfig
+++ b/configs/nanopi_neo_air_defconfig
@@ -13,5 +13,6 @@
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-nanopi-neo-air"
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/nanopi_neo_defconfig b/configs/nanopi_neo_defconfig
index ffb854b..b963a28 100644
--- a/configs/nanopi_neo_defconfig
+++ b/configs/nanopi_neo_defconfig
@@ -14,5 +14,6 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-nanopi-neo"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/nanopi_neo_plus2_defconfig b/configs/nanopi_neo_plus2_defconfig
index 331dc6a..efb1737 100644
--- a/configs/nanopi_neo_plus2_defconfig
+++ b/configs/nanopi_neo_plus2_defconfig
@@ -13,4 +13,5 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun50i-h5-nanopi-neo-plus2"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
diff --git a/configs/orangepi_2_defconfig b/configs/orangepi_2_defconfig
index b86c0ab..3ad13cb 100644
--- a/configs/orangepi_2_defconfig
+++ b/configs/orangepi_2_defconfig
@@ -16,5 +16,6 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-2"
 CONFIG_SUN8I_EMAC=y
 CONFIG_SY8106A_POWER=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/orangepi_lite_defconfig b/configs/orangepi_lite_defconfig
index de08a8a..e30df9b 100644
--- a/configs/orangepi_lite_defconfig
+++ b/configs/orangepi_lite_defconfig
@@ -11,5 +11,6 @@
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-lite"
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/orangepi_one_defconfig b/configs/orangepi_one_defconfig
index 003f2cc..346a55f 100644
--- a/configs/orangepi_one_defconfig
+++ b/configs/orangepi_one_defconfig
@@ -12,5 +12,6 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-one"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/orangepi_pc2_defconfig b/configs/orangepi_pc2_defconfig
index 7f7e6d3..a74fedd 100644
--- a/configs/orangepi_pc2_defconfig
+++ b/configs/orangepi_pc2_defconfig
@@ -13,6 +13,7 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun50i-h5-orangepi-pc2"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/orangepi_pc_defconfig b/configs/orangepi_pc_defconfig
index fd41e1a..14fcb66 100644
--- a/configs/orangepi_pc_defconfig
+++ b/configs/orangepi_pc_defconfig
@@ -14,5 +14,6 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-pc"
 CONFIG_SUN8I_EMAC=y
 CONFIG_SY8106A_POWER=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/orangepi_pc_plus_defconfig b/configs/orangepi_pc_plus_defconfig
index 1f0bf73..0e7b4d3 100644
--- a/configs/orangepi_pc_plus_defconfig
+++ b/configs/orangepi_pc_plus_defconfig
@@ -15,5 +15,6 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-pc-plus"
 CONFIG_SUN8I_EMAC=y
 CONFIG_SY8106A_POWER=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/orangepi_plus2e_defconfig b/configs/orangepi_plus2e_defconfig
index 9baccde..3e79c84 100644
--- a/configs/orangepi_plus2e_defconfig
+++ b/configs/orangepi_plus2e_defconfig
@@ -16,5 +16,6 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-plus2e"
 CONFIG_SUN8I_EMAC=y
 CONFIG_SY8106A_POWER=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/orangepi_plus_defconfig b/configs/orangepi_plus_defconfig
index 0588799..26bd9c4 100644
--- a/configs/orangepi_plus_defconfig
+++ b/configs/orangepi_plus_defconfig
@@ -18,5 +18,6 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-plus"
 CONFIG_SUN8I_EMAC=y
 CONFIG_SY8106A_POWER=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/orangepi_prime_defconfig b/configs/orangepi_prime_defconfig
index 7e10ebe..d2429b7 100644
--- a/configs/orangepi_prime_defconfig
+++ b/configs/orangepi_prime_defconfig
@@ -11,6 +11,7 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun50i-h5-orangepi-prime"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/orangepi_r1_defconfig b/configs/orangepi_r1_defconfig
index f587bec..cd33551 100644
--- a/configs/orangepi_r1_defconfig
+++ b/configs/orangepi_r1_defconfig
@@ -13,5 +13,6 @@
 # CONFIG_CMD_FLASH is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h2-plus-orangepi-r1"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/orangepi_win_defconfig b/configs/orangepi_win_defconfig
index ab889ea..78c5532 100644
--- a/configs/orangepi_win_defconfig
+++ b/configs/orangepi_win_defconfig
@@ -11,5 +11,6 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-orangepi-win"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/orangepi_zero_defconfig b/configs/orangepi_zero_defconfig
index 0da9c65..e5a4c1d 100644
--- a/configs/orangepi_zero_defconfig
+++ b/configs/orangepi_zero_defconfig
@@ -13,5 +13,6 @@
 # CONFIG_CMD_FLASH is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h2-plus-orangepi-zero"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/orangepi_zero_plus2_defconfig b/configs/orangepi_zero_plus2_defconfig
index 3c6ee03..7ae9227 100644
--- a/configs/orangepi_zero_plus2_defconfig
+++ b/configs/orangepi_zero_plus2_defconfig
@@ -13,5 +13,6 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun50i-h5-orangepi-zero-plus2"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/orangepi_zero_plus_defconfig b/configs/orangepi_zero_plus_defconfig
index 5d783c5..74133fa 100644
--- a/configs/orangepi_zero_plus_defconfig
+++ b/configs/orangepi_zero_plus_defconfig
@@ -13,5 +13,6 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun50i-h5-orangepi-zero-plus"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/parrot_r16_defconfig b/configs/parrot_r16_defconfig
index a607161..80c1bf1 100644
--- a/configs/parrot_r16_defconfig
+++ b/configs/parrot_r16_defconfig
@@ -18,6 +18,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-r16-parrot"
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_CONS_INDEX=5
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/pine64_plus_defconfig b/configs/pine64_plus_defconfig
index a5b87b9..ded4d13 100644
--- a/configs/pine64_plus_defconfig
+++ b/configs/pine64_plus_defconfig
@@ -14,5 +14,6 @@
 CONFIG_PHY_REALTEK=y
 CONFIG_RTL8211E_PINE64_GIGABIT_FIX=y
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/pinebook_defconfig b/configs/pinebook_defconfig
index 5294dbd..935644d 100644
--- a/configs/pinebook_defconfig
+++ b/configs/pinebook_defconfig
@@ -15,6 +15,7 @@
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_DM_PWM=y
 CONFIG_PWM_SUNXI=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
 # CONFIG_USB_GADGET is not set
diff --git a/configs/r7-tv-dongle_defconfig b/configs/r7-tv-dongle_defconfig
index 9c797c5..d993b5d 100644
--- a/configs/r7-tv-dongle_defconfig
+++ b/configs/r7-tv-dongle_defconfig
@@ -13,5 +13,6 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun5i-a10s-r7-tv-dongle"
 CONFIG_AXP152_POWER=y
 CONFIG_CONS_INDEX=2
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/sopine_baseboard_defconfig b/configs/sopine_baseboard_defconfig
index 9ede081..0a189fc 100644
--- a/configs/sopine_baseboard_defconfig
+++ b/configs/sopine_baseboard_defconfig
@@ -16,5 +16,6 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-sopine-baseboard"
 CONFIG_SUN8I_EMAC=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/sun8i_a23_evb_defconfig b/configs/sun8i_a23_evb_defconfig
index 70c4072..563275b 100644
--- a/configs/sun8i_a23_evb_defconfig
+++ b/configs/sun8i_a23_evb_defconfig
@@ -14,5 +14,6 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-a23-evb"
 CONFIG_CONS_INDEX=5
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/sunxi_Gemei_G9_defconfig b/configs/sunxi_Gemei_G9_defconfig
index e07d7c7..06a07df0 100644
--- a/configs/sunxi_Gemei_G9_defconfig
+++ b/configs/sunxi_Gemei_G9_defconfig
@@ -16,5 +16,6 @@
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-gemei-g9"
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/tbs_a711_defconfig b/configs/tbs_a711_defconfig
index b2bcf3b..103ce9b 100644
--- a/configs/tbs_a711_defconfig
+++ b/configs/tbs_a711_defconfig
@@ -19,6 +19,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-a83t-tbs-a711"
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_AXP_DCDC5_VOLT=1200
+CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_USB_FUNCTION_MASS_STORAGE=y
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index eadf7f8..51c931b 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -104,6 +104,7 @@
 source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/owl/Kconfig"
 source "drivers/clk/renesas/Kconfig"
+source "drivers/clk/sunxi/Kconfig"
 source "drivers/clk/tegra/Kconfig"
 source "drivers/clk/uniphier/Kconfig"
 
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 9acbb1a..6a4ff91 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -22,6 +22,7 @@
 obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o
 obj-$(CONFIG_CLK_OWL) += owl/
 obj-$(CONFIG_CLK_RENESAS) += renesas/
+obj-$(CONFIG_ARCH_SUNXI) += sunxi/
 obj-$(CONFIG_CLK_STM32F) += clk_stm32f.o
 obj-$(CONFIG_CLK_STM32MP1) += clk_stm32mp1.o
 obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
diff --git a/drivers/clk/sunxi/Kconfig b/drivers/clk/sunxi/Kconfig
new file mode 100644
index 0000000..5ff101b
--- /dev/null
+++ b/drivers/clk/sunxi/Kconfig
@@ -0,0 +1,89 @@
+config CLK_SUNXI
+	bool "Clock support for Allwinner SoCs"
+	depends on CLK && ARCH_SUNXI
+	select DM_RESET
+	default y
+	help
+	  This enables support for common clock driver API on Allwinner
+	  SoCs.
+
+if CLK_SUNXI
+
+config CLK_SUN4I_A10
+	bool "Clock driver for Allwinner A10/A20"
+	default MACH_SUN4I || MACH_SUN7I
+	help
+	  This enables common clock driver support for platforms based
+	  on Allwinner A10/A20 SoC.
+
+config CLK_SUN5I_A10S
+	bool "Clock driver for Allwinner A10s/A13"
+	default MACH_SUN5I
+	help
+	  This enables common clock driver support for platforms based
+	  on Allwinner A10s/A13 SoC.
+
+config CLK_SUN6I_A31
+	bool "Clock driver for Allwinner A31/A31s"
+	default MACH_SUN6I
+	help
+	  This enables common clock driver support for platforms based
+	  on Allwinner A31/A31s SoC.
+
+config CLK_SUN8I_A23
+	bool "Clock driver for Allwinner A23/A33"
+	default MACH_SUN8I_A23 || MACH_SUN8I_A33
+	help
+	  This enables common clock driver support for platforms based
+	  on Allwinner A23/A33 SoC.
+
+config CLK_SUN8I_A83T
+	bool "Clock driver for Allwinner A83T"
+	default MACH_SUN8I_A83T
+	help
+	  This enables common clock driver support for platforms based
+	  on Allwinner A83T SoC.
+
+config CLK_SUN8I_R40
+	bool "Clock driver for Allwinner R40"
+	default MACH_SUN8I_R40
+	help
+	  This enables common clock driver support for platforms based
+	  on Allwinner R40 SoC.
+
+config CLK_SUN8I_V3S
+	bool "Clock driver for Allwinner V3S"
+	default MACH_SUN8I_V3S
+	help
+	  This enables common clock driver support for platforms based
+	  on Allwinner V3S SoC.
+
+config CLK_SUN9I_A80
+	bool "Clock driver for Allwinner A80"
+	default MACH_SUN9I
+	help
+	  This enables common clock driver support for platforms based
+	  on Allwinner A80 SoC.
+
+config CLK_SUN8I_H3
+	bool "Clock driver for Allwinner H3/H5"
+	default MACH_SUNXI_H3_H5
+	help
+	  This enables common clock driver support for platforms based
+	  on Allwinner H3/H5 SoC.
+
+config CLK_SUN50I_H6
+	bool "Clock driver for Allwinner H6"
+	default MACH_SUN50I_H6
+	help
+	  This enables common clock driver support for platforms based
+	  on Allwinner H6 SoC.
+
+config CLK_SUN50I_A64
+	bool "Clock driver for Allwinner A64"
+	default MACH_SUN50I
+	help
+	  This enables common clock driver support for platforms based
+	  on Allwinner A64 SoC.
+
+endif # CLK_SUNXI
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
new file mode 100644
index 0000000..36fb2ae
--- /dev/null
+++ b/drivers/clk/sunxi/Makefile
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2018 Amarula Solutions.
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+
+obj-$(CONFIG_CLK_SUNXI) += clk_sunxi.o
+
+obj-$(CONFIG_CLK_SUN4I_A10) += clk_a10.o
+obj-$(CONFIG_CLK_SUN5I_A10S) += clk_a10s.o
+obj-$(CONFIG_CLK_SUN6I_A31) += clk_a31.o
+obj-$(CONFIG_CLK_SUN8I_A23) += clk_a23.o
+obj-$(CONFIG_CLK_SUN8I_A83T) += clk_a83t.o
+obj-$(CONFIG_CLK_SUN8I_R40) += clk_r40.o
+obj-$(CONFIG_CLK_SUN8I_V3S) += clk_v3s.o
+obj-$(CONFIG_CLK_SUN9I_A80) += clk_a80.o
+obj-$(CONFIG_CLK_SUN8I_H3) += clk_h3.o
+obj-$(CONFIG_CLK_SUN50I_H6) += clk_h6.o
+obj-$(CONFIG_CLK_SUN50I_A64) += clk_a64.o
diff --git a/drivers/clk/sunxi/clk_a10.c b/drivers/clk/sunxi/clk_a10.c
new file mode 100644
index 0000000..b00f51a
--- /dev/null
+++ b/drivers/clk/sunxi/clk_a10.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 Amarula Solutions.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/arch/ccu.h>
+#include <dt-bindings/clock/sun4i-a10-ccu.h>
+#include <dt-bindings/reset/sun4i-a10-ccu.h>
+
+static struct ccu_clk_gate a10_gates[] = {
+	[CLK_AHB_OTG]		= GATE(0x060, BIT(0)),
+	[CLK_AHB_EHCI0]		= GATE(0x060, BIT(1)),
+	[CLK_AHB_OHCI0]		= GATE(0x060, BIT(2)),
+	[CLK_AHB_EHCI1]		= GATE(0x060, BIT(3)),
+	[CLK_AHB_OHCI1]		= GATE(0x060, BIT(4)),
+
+	[CLK_APB1_UART0]	= GATE(0x06c, BIT(16)),
+	[CLK_APB1_UART1]	= GATE(0x06c, BIT(17)),
+	[CLK_APB1_UART2]	= GATE(0x06c, BIT(18)),
+	[CLK_APB1_UART3]	= GATE(0x06c, BIT(19)),
+	[CLK_APB1_UART4]	= GATE(0x06c, BIT(20)),
+	[CLK_APB1_UART5]	= GATE(0x06c, BIT(21)),
+	[CLK_APB1_UART6]	= GATE(0x06c, BIT(22)),
+	[CLK_APB1_UART7]	= GATE(0x06c, BIT(23)),
+
+	[CLK_USB_OHCI0]		= GATE(0x0cc, BIT(6)),
+	[CLK_USB_OHCI1]		= GATE(0x0cc, BIT(7)),
+	[CLK_USB_PHY]		= GATE(0x0cc, BIT(8)),
+};
+
+static struct ccu_reset a10_resets[] = {
+	[RST_USB_PHY0]		= RESET(0x0cc, BIT(0)),
+	[RST_USB_PHY1]		= RESET(0x0cc, BIT(1)),
+	[RST_USB_PHY2]		= RESET(0x0cc, BIT(2)),
+};
+
+static const struct ccu_desc a10_ccu_desc = {
+	.gates = a10_gates,
+	.resets = a10_resets,
+};
+
+static int a10_clk_bind(struct udevice *dev)
+{
+	return sunxi_reset_bind(dev, ARRAY_SIZE(a10_resets));
+}
+
+static const struct udevice_id a10_ccu_ids[] = {
+	{ .compatible = "allwinner,sun4i-a10-ccu",
+	  .data = (ulong)&a10_ccu_desc },
+	{ .compatible = "allwinner,sun7i-a20-ccu",
+	  .data = (ulong)&a10_ccu_desc },
+	{ }
+};
+
+U_BOOT_DRIVER(clk_sun4i_a10) = {
+	.name		= "sun4i_a10_ccu",
+	.id		= UCLASS_CLK,
+	.of_match	= a10_ccu_ids,
+	.priv_auto_alloc_size	= sizeof(struct ccu_priv),
+	.ops		= &sunxi_clk_ops,
+	.probe		= sunxi_clk_probe,
+	.bind		= a10_clk_bind,
+};
diff --git a/drivers/clk/sunxi/clk_a10s.c b/drivers/clk/sunxi/clk_a10s.c
new file mode 100644
index 0000000..aa904ce
--- /dev/null
+++ b/drivers/clk/sunxi/clk_a10s.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 Amarula Solutions.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/arch/ccu.h>
+#include <dt-bindings/clock/sun5i-ccu.h>
+#include <dt-bindings/reset/sun5i-ccu.h>
+
+static struct ccu_clk_gate a10s_gates[] = {
+	[CLK_AHB_OTG]		= GATE(0x060, BIT(0)),
+	[CLK_AHB_EHCI]		= GATE(0x060, BIT(1)),
+	[CLK_AHB_OHCI]		= GATE(0x060, BIT(2)),
+
+	[CLK_APB1_UART0]	= GATE(0x06c, BIT(16)),
+	[CLK_APB1_UART1]	= GATE(0x06c, BIT(17)),
+	[CLK_APB1_UART2]	= GATE(0x06c, BIT(18)),
+	[CLK_APB1_UART3]	= GATE(0x06c, BIT(19)),
+
+	[CLK_USB_OHCI]		= GATE(0x0cc, BIT(6)),
+	[CLK_USB_PHY0]		= GATE(0x0cc, BIT(8)),
+	[CLK_USB_PHY1]		= GATE(0x0cc, BIT(9)),
+};
+
+static struct ccu_reset a10s_resets[] = {
+	[RST_USB_PHY0]		= RESET(0x0cc, BIT(0)),
+	[RST_USB_PHY1]		= RESET(0x0cc, BIT(1)),
+};
+
+static const struct ccu_desc a10s_ccu_desc = {
+	.gates = a10s_gates,
+	.resets = a10s_resets,
+};
+
+static int a10s_clk_bind(struct udevice *dev)
+{
+	return sunxi_reset_bind(dev, ARRAY_SIZE(a10s_resets));
+}
+
+static const struct udevice_id a10s_ccu_ids[] = {
+	{ .compatible = "allwinner,sun5i-a10s-ccu",
+	  .data = (ulong)&a10s_ccu_desc },
+	{ .compatible = "allwinner,sun5i-a13-ccu",
+	  .data = (ulong)&a10s_ccu_desc },
+	{ }
+};
+
+U_BOOT_DRIVER(clk_sun5i_a10s) = {
+	.name		= "sun5i_a10s_ccu",
+	.id		= UCLASS_CLK,
+	.of_match	= a10s_ccu_ids,
+	.priv_auto_alloc_size	= sizeof(struct ccu_priv),
+	.ops		= &sunxi_clk_ops,
+	.probe		= sunxi_clk_probe,
+	.bind		= a10s_clk_bind,
+};
diff --git a/drivers/clk/sunxi/clk_a23.c b/drivers/clk/sunxi/clk_a23.c
new file mode 100644
index 0000000..854259b
--- /dev/null
+++ b/drivers/clk/sunxi/clk_a23.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 Amarula Solutions B.V.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/arch/ccu.h>
+#include <dt-bindings/clock/sun8i-a23-a33-ccu.h>
+#include <dt-bindings/reset/sun8i-a23-a33-ccu.h>
+
+static struct ccu_clk_gate a23_gates[] = {
+	[CLK_BUS_OTG]		= GATE(0x060, BIT(24)),
+	[CLK_BUS_EHCI]		= GATE(0x060, BIT(26)),
+	[CLK_BUS_OHCI]		= GATE(0x060, BIT(29)),
+
+	[CLK_BUS_UART0]		= GATE(0x06c, BIT(16)),
+	[CLK_BUS_UART1]		= GATE(0x06c, BIT(17)),
+	[CLK_BUS_UART2]		= GATE(0x06c, BIT(18)),
+	[CLK_BUS_UART3]		= GATE(0x06c, BIT(19)),
+	[CLK_BUS_UART4]		= GATE(0x06c, BIT(20)),
+
+	[CLK_USB_PHY0]		= GATE(0x0cc, BIT(8)),
+	[CLK_USB_PHY1]		= GATE(0x0cc, BIT(9)),
+	[CLK_USB_HSIC]		= GATE(0x0cc, BIT(10)),
+	[CLK_USB_HSIC_12M]	= GATE(0x0cc, BIT(11)),
+	[CLK_USB_OHCI]		= GATE(0x0cc, BIT(16)),
+};
+
+static struct ccu_reset a23_resets[] = {
+	[RST_USB_PHY0]		= RESET(0x0cc, BIT(0)),
+	[RST_USB_PHY1]		= RESET(0x0cc, BIT(1)),
+	[RST_USB_HSIC]		= RESET(0x0cc, BIT(2)),
+
+	[RST_BUS_OTG]		= RESET(0x2c0, BIT(24)),
+	[RST_BUS_EHCI]		= RESET(0x2c0, BIT(26)),
+	[RST_BUS_OHCI]		= RESET(0x2c0, BIT(29)),
+
+	[RST_BUS_UART0]		= RESET(0x2d8, BIT(16)),
+	[RST_BUS_UART1]		= RESET(0x2d8, BIT(17)),
+	[RST_BUS_UART2]		= RESET(0x2d8, BIT(18)),
+	[RST_BUS_UART3]		= RESET(0x2d8, BIT(19)),
+	[RST_BUS_UART4]		= RESET(0x2d8, BIT(20)),
+};
+
+static const struct ccu_desc a23_ccu_desc = {
+	.gates = a23_gates,
+	.resets = a23_resets,
+};
+
+static int a23_clk_bind(struct udevice *dev)
+{
+	return sunxi_reset_bind(dev, ARRAY_SIZE(a23_resets));
+}
+
+static const struct udevice_id a23_clk_ids[] = {
+	{ .compatible = "allwinner,sun8i-a23-ccu",
+	  .data = (ulong)&a23_ccu_desc },
+	{ .compatible = "allwinner,sun8i-a33-ccu",
+	  .data = (ulong)&a23_ccu_desc },
+	{ }
+};
+
+U_BOOT_DRIVER(clk_sun8i_a23) = {
+	.name		= "sun8i_a23_ccu",
+	.id		= UCLASS_CLK,
+	.of_match	= a23_clk_ids,
+	.priv_auto_alloc_size	= sizeof(struct ccu_priv),
+	.ops		= &sunxi_clk_ops,
+	.probe		= sunxi_clk_probe,
+	.bind		= a23_clk_bind,
+};
diff --git a/drivers/clk/sunxi/clk_a31.c b/drivers/clk/sunxi/clk_a31.c
new file mode 100644
index 0000000..a38d76c
--- /dev/null
+++ b/drivers/clk/sunxi/clk_a31.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 Amarula Solutions B.V.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/arch/ccu.h>
+#include <dt-bindings/clock/sun6i-a31-ccu.h>
+#include <dt-bindings/reset/sun6i-a31-ccu.h>
+
+static struct ccu_clk_gate a31_gates[] = {
+	[CLK_AHB1_OTG]		= GATE(0x060, BIT(24)),
+	[CLK_AHB1_EHCI0]	= GATE(0x060, BIT(26)),
+	[CLK_AHB1_EHCI1]	= GATE(0x060, BIT(27)),
+	[CLK_AHB1_OHCI0]	= GATE(0x060, BIT(29)),
+	[CLK_AHB1_OHCI1]	= GATE(0x060, BIT(30)),
+	[CLK_AHB1_OHCI2]	= GATE(0x060, BIT(31)),
+
+	[CLK_APB2_UART0]	= GATE(0x06c, BIT(16)),
+	[CLK_APB2_UART1]	= GATE(0x06c, BIT(17)),
+	[CLK_APB2_UART2]	= GATE(0x06c, BIT(18)),
+	[CLK_APB2_UART3]	= GATE(0x06c, BIT(19)),
+	[CLK_APB2_UART4]	= GATE(0x06c, BIT(20)),
+	[CLK_APB2_UART5]	= GATE(0x06c, BIT(21)),
+
+	[CLK_USB_PHY0]		= GATE(0x0cc, BIT(8)),
+	[CLK_USB_PHY1]		= GATE(0x0cc, BIT(9)),
+	[CLK_USB_PHY2]		= GATE(0x0cc, BIT(10)),
+	[CLK_USB_OHCI0]		= GATE(0x0cc, BIT(16)),
+	[CLK_USB_OHCI1]		= GATE(0x0cc, BIT(17)),
+	[CLK_USB_OHCI2]		= GATE(0x0cc, BIT(18)),
+};
+
+static struct ccu_reset a31_resets[] = {
+	[RST_USB_PHY0]		= RESET(0x0cc, BIT(0)),
+	[RST_USB_PHY1]		= RESET(0x0cc, BIT(1)),
+	[RST_USB_PHY2]		= RESET(0x0cc, BIT(2)),
+
+	[RST_AHB1_OTG]		= RESET(0x2c0, BIT(24)),
+	[RST_AHB1_EHCI0]	= RESET(0x2c0, BIT(26)),
+	[RST_AHB1_EHCI1]	= RESET(0x2c0, BIT(27)),
+	[RST_AHB1_OHCI0]	= RESET(0x2c0, BIT(29)),
+	[RST_AHB1_OHCI1]	= RESET(0x2c0, BIT(30)),
+	[RST_AHB1_OHCI2]	= RESET(0x2c0, BIT(31)),
+
+	[RST_APB2_UART0]	= RESET(0x2d8, BIT(16)),
+	[RST_APB2_UART1]	= RESET(0x2d8, BIT(17)),
+	[RST_APB2_UART2]	= RESET(0x2d8, BIT(18)),
+	[RST_APB2_UART3]	= RESET(0x2d8, BIT(19)),
+	[RST_APB2_UART4]	= RESET(0x2d8, BIT(20)),
+	[RST_APB2_UART5]	= RESET(0x2d8, BIT(21)),
+};
+
+static const struct ccu_desc a31_ccu_desc = {
+	.gates = a31_gates,
+	.resets = a31_resets,
+};
+
+static int a31_clk_bind(struct udevice *dev)
+{
+	return sunxi_reset_bind(dev, ARRAY_SIZE(a31_resets));
+}
+
+static const struct udevice_id a31_clk_ids[] = {
+	{ .compatible = "allwinner,sun6i-a31-ccu",
+	  .data = (ulong)&a31_ccu_desc },
+	{ }
+};
+
+U_BOOT_DRIVER(clk_sun6i_a31) = {
+	.name		= "sun6i_a31_ccu",
+	.id		= UCLASS_CLK,
+	.of_match	= a31_clk_ids,
+	.priv_auto_alloc_size	= sizeof(struct ccu_priv),
+	.ops		= &sunxi_clk_ops,
+	.probe		= sunxi_clk_probe,
+	.bind		= a31_clk_bind,
+};
diff --git a/drivers/clk/sunxi/clk_a64.c b/drivers/clk/sunxi/clk_a64.c
new file mode 100644
index 0000000..a2ba6ee
--- /dev/null
+++ b/drivers/clk/sunxi/clk_a64.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Amarula Solutions.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/arch/ccu.h>
+#include <dt-bindings/clock/sun50i-a64-ccu.h>
+#include <dt-bindings/reset/sun50i-a64-ccu.h>
+
+static const struct ccu_clk_gate a64_gates[] = {
+	[CLK_BUS_OTG]		= GATE(0x060, BIT(23)),
+	[CLK_BUS_EHCI0]		= GATE(0x060, BIT(24)),
+	[CLK_BUS_EHCI1]		= GATE(0x060, BIT(25)),
+	[CLK_BUS_OHCI0]		= GATE(0x060, BIT(28)),
+	[CLK_BUS_OHCI1]		= GATE(0x060, BIT(29)),
+
+	[CLK_BUS_UART0]		= GATE(0x06c, BIT(16)),
+	[CLK_BUS_UART1]		= GATE(0x06c, BIT(17)),
+	[CLK_BUS_UART2]		= GATE(0x06c, BIT(18)),
+	[CLK_BUS_UART3]		= GATE(0x06c, BIT(19)),
+	[CLK_BUS_UART4]		= GATE(0x06c, BIT(20)),
+
+	[CLK_USB_PHY0]		= GATE(0x0cc, BIT(8)),
+	[CLK_USB_PHY1]		= GATE(0x0cc, BIT(9)),
+	[CLK_USB_HSIC]		= GATE(0x0cc, BIT(10)),
+	[CLK_USB_HSIC_12M]	= GATE(0x0cc, BIT(11)),
+	[CLK_USB_OHCI0]		= GATE(0x0cc, BIT(16)),
+	[CLK_USB_OHCI1]		= GATE(0x0cc, BIT(17)),
+};
+
+static const struct ccu_reset a64_resets[] = {
+	[RST_USB_PHY0]          = RESET(0x0cc, BIT(0)),
+	[RST_USB_PHY1]          = RESET(0x0cc, BIT(1)),
+	[RST_USB_HSIC]          = RESET(0x0cc, BIT(2)),
+
+	[RST_BUS_OTG]           = RESET(0x2c0, BIT(23)),
+	[RST_BUS_EHCI0]         = RESET(0x2c0, BIT(24)),
+	[RST_BUS_EHCI1]         = RESET(0x2c0, BIT(25)),
+	[RST_BUS_OHCI0]         = RESET(0x2c0, BIT(28)),
+	[RST_BUS_OHCI1]         = RESET(0x2c0, BIT(29)),
+
+	[RST_BUS_UART0]		= RESET(0x2d8, BIT(16)),
+	[RST_BUS_UART1]		= RESET(0x2d8, BIT(17)),
+	[RST_BUS_UART2]		= RESET(0x2d8, BIT(18)),
+	[RST_BUS_UART3]		= RESET(0x2d8, BIT(19)),
+	[RST_BUS_UART4]		= RESET(0x2d8, BIT(20)),
+};
+
+static const struct ccu_desc a64_ccu_desc = {
+	.gates = a64_gates,
+	.resets = a64_resets,
+};
+
+static int a64_clk_bind(struct udevice *dev)
+{
+	return sunxi_reset_bind(dev, ARRAY_SIZE(a64_resets));
+}
+
+static const struct udevice_id a64_ccu_ids[] = {
+	{ .compatible = "allwinner,sun50i-a64-ccu",
+	  .data = (ulong)&a64_ccu_desc },
+	{ }
+};
+
+U_BOOT_DRIVER(clk_sun50i_a64) = {
+	.name		= "sun50i_a64_ccu",
+	.id		= UCLASS_CLK,
+	.of_match	= a64_ccu_ids,
+	.priv_auto_alloc_size	= sizeof(struct ccu_priv),
+	.ops		= &sunxi_clk_ops,
+	.probe		= sunxi_clk_probe,
+	.bind		= a64_clk_bind,
+};
diff --git a/drivers/clk/sunxi/clk_a80.c b/drivers/clk/sunxi/clk_a80.c
new file mode 100644
index 0000000..d6dd6a1
--- /dev/null
+++ b/drivers/clk/sunxi/clk_a80.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Amarula Solutions.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/arch/ccu.h>
+#include <dt-bindings/clock/sun9i-a80-ccu.h>
+#include <dt-bindings/reset/sun9i-a80-ccu.h>
+
+static const struct ccu_clk_gate a80_gates[] = {
+	[CLK_BUS_UART0]		= GATE(0x594, BIT(16)),
+	[CLK_BUS_UART1]		= GATE(0x594, BIT(17)),
+	[CLK_BUS_UART2]		= GATE(0x594, BIT(18)),
+	[CLK_BUS_UART3]		= GATE(0x594, BIT(19)),
+	[CLK_BUS_UART4]		= GATE(0x594, BIT(20)),
+	[CLK_BUS_UART5]		= GATE(0x594, BIT(21)),
+};
+
+static const struct ccu_reset a80_resets[] = {
+	[RST_BUS_UART0]		= RESET(0x5b4, BIT(16)),
+	[RST_BUS_UART1]		= RESET(0x5b4, BIT(17)),
+	[RST_BUS_UART2]		= RESET(0x5b4, BIT(18)),
+	[RST_BUS_UART3]		= RESET(0x5b4, BIT(19)),
+	[RST_BUS_UART4]		= RESET(0x5b4, BIT(20)),
+	[RST_BUS_UART5]		= RESET(0x5b4, BIT(21)),
+};
+
+static const struct ccu_desc a80_ccu_desc = {
+	.gates = a80_gates,
+	.resets = a80_resets,
+};
+
+static int a80_clk_bind(struct udevice *dev)
+{
+	return sunxi_reset_bind(dev, ARRAY_SIZE(a80_resets));
+}
+
+static const struct udevice_id a80_ccu_ids[] = {
+	{ .compatible = "allwinner,sun9i-a80-ccu",
+	  .data = (ulong)&a80_ccu_desc },
+	{ }
+};
+
+U_BOOT_DRIVER(clk_sun9i_a80) = {
+	.name		= "sun9i_a80_ccu",
+	.id		= UCLASS_CLK,
+	.of_match	= a80_ccu_ids,
+	.priv_auto_alloc_size	= sizeof(struct ccu_priv),
+	.ops		= &sunxi_clk_ops,
+	.probe		= sunxi_clk_probe,
+	.bind		= a80_clk_bind,
+};
diff --git a/drivers/clk/sunxi/clk_a83t.c b/drivers/clk/sunxi/clk_a83t.c
new file mode 100644
index 0000000..1ef6ac5
--- /dev/null
+++ b/drivers/clk/sunxi/clk_a83t.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 Amarula Solutions.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/arch/ccu.h>
+#include <dt-bindings/clock/sun8i-a83t-ccu.h>
+#include <dt-bindings/reset/sun8i-a83t-ccu.h>
+
+static struct ccu_clk_gate a83t_gates[] = {
+	[CLK_BUS_OTG]		= GATE(0x060, BIT(24)),
+	[CLK_BUS_EHCI0]		= GATE(0x060, BIT(26)),
+	[CLK_BUS_EHCI1]		= GATE(0x060, BIT(27)),
+	[CLK_BUS_OHCI0]		= GATE(0x060, BIT(29)),
+
+	[CLK_BUS_UART0]		= GATE(0x06c, BIT(16)),
+	[CLK_BUS_UART1]		= GATE(0x06c, BIT(17)),
+	[CLK_BUS_UART2]		= GATE(0x06c, BIT(18)),
+	[CLK_BUS_UART3]		= GATE(0x06c, BIT(19)),
+	[CLK_BUS_UART4]		= GATE(0x06c, BIT(20)),
+
+	[CLK_USB_PHY0]		= GATE(0x0cc, BIT(8)),
+	[CLK_USB_PHY1]		= GATE(0x0cc, BIT(9)),
+	[CLK_USB_HSIC]		= GATE(0x0cc, BIT(10)),
+	[CLK_USB_HSIC_12M]	= GATE(0x0cc, BIT(11)),
+	[CLK_USB_OHCI0]		= GATE(0x0cc, BIT(16)),
+};
+
+static struct ccu_reset a83t_resets[] = {
+	[RST_USB_PHY0]		= RESET(0x0cc, BIT(0)),
+	[RST_USB_PHY1]		= RESET(0x0cc, BIT(1)),
+	[RST_USB_HSIC]		= RESET(0x0cc, BIT(2)),
+
+	[RST_BUS_OTG]		= RESET(0x2c0, BIT(24)),
+	[RST_BUS_EHCI0]		= RESET(0x2c0, BIT(26)),
+	[RST_BUS_EHCI1]		= RESET(0x2c0, BIT(27)),
+	[RST_BUS_OHCI0]		= RESET(0x2c0, BIT(29)),
+
+	[RST_BUS_UART0]		= RESET(0x2d8, BIT(16)),
+	[RST_BUS_UART1]		= RESET(0x2d8, BIT(17)),
+	[RST_BUS_UART2]		= RESET(0x2d8, BIT(18)),
+	[RST_BUS_UART3]		= RESET(0x2d8, BIT(19)),
+	[RST_BUS_UART4]		= RESET(0x2d8, BIT(20)),
+};
+
+static const struct ccu_desc a83t_ccu_desc = {
+	.gates = a83t_gates,
+	.resets = a83t_resets,
+};
+
+static int a83t_clk_bind(struct udevice *dev)
+{
+	return sunxi_reset_bind(dev, ARRAY_SIZE(a83t_resets));
+}
+
+static const struct udevice_id a83t_clk_ids[] = {
+	{ .compatible = "allwinner,sun8i-a83t-ccu",
+	  .data = (ulong)&a83t_ccu_desc },
+	{ }
+};
+
+U_BOOT_DRIVER(clk_sun8i_a83t) = {
+	.name		= "sun8i_a83t_ccu",
+	.id		= UCLASS_CLK,
+	.of_match	= a83t_clk_ids,
+	.priv_auto_alloc_size	= sizeof(struct ccu_priv),
+	.ops		= &sunxi_clk_ops,
+	.probe		= sunxi_clk_probe,
+	.bind		= a83t_clk_bind,
+};
diff --git a/drivers/clk/sunxi/clk_h3.c b/drivers/clk/sunxi/clk_h3.c
new file mode 100644
index 0000000..f82949b
--- /dev/null
+++ b/drivers/clk/sunxi/clk_h3.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 Amarula Solutions.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/arch/ccu.h>
+#include <dt-bindings/clock/sun8i-h3-ccu.h>
+#include <dt-bindings/reset/sun8i-h3-ccu.h>
+
+static struct ccu_clk_gate h3_gates[] = {
+	[CLK_BUS_OTG]		= GATE(0x060, BIT(23)),
+	[CLK_BUS_EHCI0]		= GATE(0x060, BIT(24)),
+	[CLK_BUS_EHCI1]		= GATE(0x060, BIT(25)),
+	[CLK_BUS_EHCI2]		= GATE(0x060, BIT(26)),
+	[CLK_BUS_EHCI3]		= GATE(0x060, BIT(27)),
+	[CLK_BUS_OHCI0]		= GATE(0x060, BIT(28)),
+	[CLK_BUS_OHCI1]		= GATE(0x060, BIT(29)),
+	[CLK_BUS_OHCI2]		= GATE(0x060, BIT(30)),
+	[CLK_BUS_OHCI3]		= GATE(0x060, BIT(31)),
+
+	[CLK_BUS_UART0]		= GATE(0x06c, BIT(16)),
+	[CLK_BUS_UART1]		= GATE(0x06c, BIT(17)),
+	[CLK_BUS_UART2]		= GATE(0x06c, BIT(18)),
+	[CLK_BUS_UART3]		= GATE(0x06c, BIT(19)),
+
+	[CLK_USB_PHY0]		= GATE(0x0cc, BIT(8)),
+	[CLK_USB_PHY1]		= GATE(0x0cc, BIT(9)),
+	[CLK_USB_PHY2]		= GATE(0x0cc, BIT(10)),
+	[CLK_USB_PHY3]		= GATE(0x0cc, BIT(11)),
+	[CLK_USB_OHCI0]		= GATE(0x0cc, BIT(16)),
+	[CLK_USB_OHCI1]		= GATE(0x0cc, BIT(17)),
+	[CLK_USB_OHCI2]		= GATE(0x0cc, BIT(18)),
+	[CLK_USB_OHCI3]		= GATE(0x0cc, BIT(19)),
+};
+
+static struct ccu_reset h3_resets[] = {
+	[RST_USB_PHY0]		= RESET(0x0cc, BIT(0)),
+	[RST_USB_PHY1]		= RESET(0x0cc, BIT(1)),
+	[RST_USB_PHY2]		= RESET(0x0cc, BIT(2)),
+	[RST_USB_PHY3]		= RESET(0x0cc, BIT(3)),
+
+	[RST_BUS_OTG]		= RESET(0x2c0, BIT(23)),
+	[RST_BUS_EHCI0]		= RESET(0x2c0, BIT(24)),
+	[RST_BUS_EHCI1]		= RESET(0x2c0, BIT(25)),
+	[RST_BUS_EHCI2]		= RESET(0x2c0, BIT(26)),
+	[RST_BUS_EHCI3]		= RESET(0x2c0, BIT(27)),
+	[RST_BUS_OHCI0]		= RESET(0x2c0, BIT(28)),
+	[RST_BUS_OHCI1]		= RESET(0x2c0, BIT(29)),
+	[RST_BUS_OHCI2]		= RESET(0x2c0, BIT(30)),
+	[RST_BUS_OHCI3]		= RESET(0x2c0, BIT(31)),
+
+	[RST_BUS_UART0]		= RESET(0x2d8, BIT(16)),
+	[RST_BUS_UART1]		= RESET(0x2d8, BIT(17)),
+	[RST_BUS_UART2]		= RESET(0x2d8, BIT(18)),
+	[RST_BUS_UART3]		= RESET(0x2d8, BIT(19)),
+};
+
+static const struct ccu_desc h3_ccu_desc = {
+	.gates = h3_gates,
+	.resets = h3_resets,
+};
+
+static int h3_clk_bind(struct udevice *dev)
+{
+	return sunxi_reset_bind(dev, ARRAY_SIZE(h3_resets));
+}
+
+static const struct udevice_id h3_ccu_ids[] = {
+	{ .compatible = "allwinner,sun8i-h3-ccu",
+	  .data = (ulong)&h3_ccu_desc },
+	{ .compatible = "allwinner,sun50i-h5-ccu",
+	  .data = (ulong)&h3_ccu_desc },
+	{ }
+};
+
+U_BOOT_DRIVER(clk_sun8i_h3) = {
+	.name		= "sun8i_h3_ccu",
+	.id		= UCLASS_CLK,
+	.of_match	= h3_ccu_ids,
+	.priv_auto_alloc_size	= sizeof(struct ccu_priv),
+	.ops		= &sunxi_clk_ops,
+	.probe		= sunxi_clk_probe,
+	.bind		= h3_clk_bind,
+};
diff --git a/drivers/clk/sunxi/clk_h6.c b/drivers/clk/sunxi/clk_h6.c
new file mode 100644
index 0000000..0da3a40
--- /dev/null
+++ b/drivers/clk/sunxi/clk_h6.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 Amarula Solutions.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/arch/ccu.h>
+#include <dt-bindings/clock/sun50i-h6-ccu.h>
+#include <dt-bindings/reset/sun50i-h6-ccu.h>
+
+static struct ccu_clk_gate h6_gates[] = {
+	[CLK_BUS_UART0]		= GATE(0x90c, BIT(0)),
+	[CLK_BUS_UART1]		= GATE(0x90c, BIT(1)),
+	[CLK_BUS_UART2]		= GATE(0x90c, BIT(2)),
+	[CLK_BUS_UART3]		= GATE(0x90c, BIT(3)),
+};
+
+static struct ccu_reset h6_resets[] = {
+	[RST_BUS_UART0]		= RESET(0x90c, BIT(16)),
+	[RST_BUS_UART1]		= RESET(0x90c, BIT(17)),
+	[RST_BUS_UART2]		= RESET(0x90c, BIT(18)),
+	[RST_BUS_UART3]		= RESET(0x90c, BIT(19)),
+};
+
+static const struct ccu_desc h6_ccu_desc = {
+	.gates = h6_gates,
+	.resets = h6_resets,
+};
+
+static int h6_clk_bind(struct udevice *dev)
+{
+	return sunxi_reset_bind(dev, ARRAY_SIZE(h6_resets));
+}
+
+static const struct udevice_id h6_ccu_ids[] = {
+	{ .compatible = "allwinner,sun50i-h6-ccu",
+	  .data = (ulong)&h6_ccu_desc },
+	{ }
+};
+
+U_BOOT_DRIVER(clk_sun50i_h6) = {
+	.name		= "sun50i_h6_ccu",
+	.id		= UCLASS_CLK,
+	.of_match	= h6_ccu_ids,
+	.priv_auto_alloc_size	= sizeof(struct ccu_priv),
+	.ops		= &sunxi_clk_ops,
+	.probe		= sunxi_clk_probe,
+	.bind		= h6_clk_bind,
+};
diff --git a/drivers/clk/sunxi/clk_r40.c b/drivers/clk/sunxi/clk_r40.c
new file mode 100644
index 0000000..fd7aae9
--- /dev/null
+++ b/drivers/clk/sunxi/clk_r40.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 Amarula Solutions.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/arch/ccu.h>
+#include <dt-bindings/clock/sun8i-r40-ccu.h>
+#include <dt-bindings/reset/sun8i-r40-ccu.h>
+
+static struct ccu_clk_gate r40_gates[] = {
+	[CLK_BUS_OTG]		= GATE(0x060, BIT(25)),
+	[CLK_BUS_EHCI0]		= GATE(0x060, BIT(26)),
+	[CLK_BUS_EHCI1]		= GATE(0x060, BIT(27)),
+	[CLK_BUS_EHCI2]		= GATE(0x060, BIT(28)),
+	[CLK_BUS_OHCI0]		= GATE(0x060, BIT(29)),
+	[CLK_BUS_OHCI1]		= GATE(0x060, BIT(30)),
+	[CLK_BUS_OHCI2]		= GATE(0x060, BIT(31)),
+
+	[CLK_BUS_UART0]		= GATE(0x06c, BIT(16)),
+	[CLK_BUS_UART1]		= GATE(0x06c, BIT(17)),
+	[CLK_BUS_UART2]		= GATE(0x06c, BIT(18)),
+	[CLK_BUS_UART3]		= GATE(0x06c, BIT(19)),
+	[CLK_BUS_UART4]		= GATE(0x06c, BIT(20)),
+	[CLK_BUS_UART5]		= GATE(0x06c, BIT(21)),
+	[CLK_BUS_UART6]		= GATE(0x06c, BIT(22)),
+	[CLK_BUS_UART7]		= GATE(0x06c, BIT(23)),
+
+	[CLK_USB_PHY0]		= GATE(0x0cc, BIT(8)),
+	[CLK_USB_PHY1]		= GATE(0x0cc, BIT(9)),
+	[CLK_USB_PHY2]		= GATE(0x0cc, BIT(10)),
+	[CLK_USB_OHCI0]		= GATE(0x0cc, BIT(16)),
+	[CLK_USB_OHCI1]		= GATE(0x0cc, BIT(17)),
+	[CLK_USB_OHCI2]		= GATE(0x0cc, BIT(18)),
+};
+
+static struct ccu_reset r40_resets[] = {
+	[RST_USB_PHY0]		= RESET(0x0cc, BIT(0)),
+	[RST_USB_PHY1]		= RESET(0x0cc, BIT(1)),
+	[RST_USB_PHY2]		= RESET(0x0cc, BIT(2)),
+
+	[RST_BUS_OTG]		= RESET(0x2c0, BIT(25)),
+	[RST_BUS_EHCI0]		= RESET(0x2c0, BIT(26)),
+	[RST_BUS_EHCI1]		= RESET(0x2c0, BIT(27)),
+	[RST_BUS_EHCI2]		= RESET(0x2c0, BIT(28)),
+	[RST_BUS_OHCI0]		= RESET(0x2c0, BIT(29)),
+	[RST_BUS_OHCI1]		= RESET(0x2c0, BIT(30)),
+	[RST_BUS_OHCI2]		= RESET(0x2c0, BIT(31)),
+
+	[RST_BUS_UART0]		= RESET(0x2d8, BIT(16)),
+	[RST_BUS_UART1]		= RESET(0x2d8, BIT(17)),
+	[RST_BUS_UART2]		= RESET(0x2d8, BIT(18)),
+	[RST_BUS_UART3]		= RESET(0x2d8, BIT(19)),
+	[RST_BUS_UART4]		= RESET(0x2d8, BIT(20)),
+	[RST_BUS_UART5]		= RESET(0x2d8, BIT(21)),
+	[RST_BUS_UART6]		= RESET(0x2d8, BIT(22)),
+	[RST_BUS_UART7]		= RESET(0x2d8, BIT(23)),
+};
+
+static const struct ccu_desc r40_ccu_desc = {
+	.gates = r40_gates,
+	.resets = r40_resets,
+};
+
+static int r40_clk_bind(struct udevice *dev)
+{
+	return sunxi_reset_bind(dev, ARRAY_SIZE(r40_resets));
+}
+
+static const struct udevice_id r40_clk_ids[] = {
+	{ .compatible = "allwinner,sun8i-r40-ccu",
+	  .data = (ulong)&r40_ccu_desc },
+	{ }
+};
+
+U_BOOT_DRIVER(clk_sun8i_r40) = {
+	.name		= "sun8i_r40_ccu",
+	.id		= UCLASS_CLK,
+	.of_match	= r40_clk_ids,
+	.priv_auto_alloc_size	= sizeof(struct ccu_priv),
+	.ops		= &sunxi_clk_ops,
+	.probe		= sunxi_clk_probe,
+	.bind		= r40_clk_bind,
+};
diff --git a/drivers/clk/sunxi/clk_sunxi.c b/drivers/clk/sunxi/clk_sunxi.c
new file mode 100644
index 0000000..62ce299
--- /dev/null
+++ b/drivers/clk/sunxi/clk_sunxi.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Amarula Solutions.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/arch/ccu.h>
+#include <linux/log2.h>
+
+static const struct ccu_clk_gate *priv_to_gate(struct ccu_priv *priv,
+					       unsigned long id)
+{
+	return &priv->desc->gates[id];
+}
+
+static int sunxi_set_gate(struct clk *clk, bool on)
+{
+	struct ccu_priv *priv = dev_get_priv(clk->dev);
+	const struct ccu_clk_gate *gate = priv_to_gate(priv, clk->id);
+	u32 reg;
+
+	if (!(gate->flags & CCU_CLK_F_IS_VALID)) {
+		printf("%s: (CLK#%ld) unhandled\n", __func__, clk->id);
+		return 0;
+	}
+
+	debug("%s: (CLK#%ld) off#0x%x, BIT(%d)\n", __func__,
+	      clk->id, gate->off, ilog2(gate->bit));
+
+	reg = readl(priv->base + gate->off);
+	if (on)
+		reg |= gate->bit;
+	else
+		reg &= ~gate->bit;
+
+	writel(reg, priv->base + gate->off);
+
+	return 0;
+}
+
+static int sunxi_clk_enable(struct clk *clk)
+{
+	return sunxi_set_gate(clk, true);
+}
+
+static int sunxi_clk_disable(struct clk *clk)
+{
+	return sunxi_set_gate(clk, false);
+}
+
+struct clk_ops sunxi_clk_ops = {
+	.enable = sunxi_clk_enable,
+	.disable = sunxi_clk_disable,
+};
+
+int sunxi_clk_probe(struct udevice *dev)
+{
+	struct ccu_priv *priv = dev_get_priv(dev);
+
+	priv->base = dev_read_addr_ptr(dev);
+	if (!priv->base)
+		return -ENOMEM;
+
+	priv->desc = (const struct ccu_desc *)dev_get_driver_data(dev);
+	if (!priv->desc)
+		return -EINVAL;
+
+	return 0;
+}
diff --git a/drivers/clk/sunxi/clk_v3s.c b/drivers/clk/sunxi/clk_v3s.c
new file mode 100644
index 0000000..25ad875
--- /dev/null
+++ b/drivers/clk/sunxi/clk_v3s.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 Amarula Solutions.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/arch/ccu.h>
+#include <dt-bindings/clock/sun8i-v3s-ccu.h>
+#include <dt-bindings/reset/sun8i-v3s-ccu.h>
+
+static struct ccu_clk_gate v3s_gates[] = {
+	[CLK_BUS_OTG]		= GATE(0x060, BIT(24)),
+
+	[CLK_BUS_UART0]		= GATE(0x06c, BIT(16)),
+	[CLK_BUS_UART1]		= GATE(0x06c, BIT(17)),
+	[CLK_BUS_UART2]		= GATE(0x06c, BIT(18)),
+
+	[CLK_USB_PHY0]          = GATE(0x0cc, BIT(8)),
+};
+
+static struct ccu_reset v3s_resets[] = {
+	[RST_USB_PHY0]		= RESET(0x0cc, BIT(0)),
+
+	[RST_BUS_OTG]		= RESET(0x2c0, BIT(24)),
+
+	[RST_BUS_UART0]		= RESET(0x2d8, BIT(16)),
+	[RST_BUS_UART1]		= RESET(0x2d8, BIT(17)),
+	[RST_BUS_UART2]		= RESET(0x2d8, BIT(18)),
+};
+
+static const struct ccu_desc v3s_ccu_desc = {
+	.gates = v3s_gates,
+	.resets = v3s_resets,
+};
+
+static int v3s_clk_bind(struct udevice *dev)
+{
+	return sunxi_reset_bind(dev, ARRAY_SIZE(v3s_resets));
+}
+
+static const struct udevice_id v3s_clk_ids[] = {
+	{ .compatible = "allwinner,sun8i-v3s-ccu",
+	  .data = (ulong)&v3s_ccu_desc },
+	{ }
+};
+
+U_BOOT_DRIVER(clk_sun8i_v3s) = {
+	.name		= "sun8i_v3s_ccu",
+	.id		= UCLASS_CLK,
+	.of_match	= v3s_clk_ids,
+	.priv_auto_alloc_size	= sizeof(struct ccu_priv),
+	.ops		= &sunxi_clk_ops,
+	.probe		= sunxi_clk_probe,
+	.bind		= v3s_clk_bind,
+};
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 4fa26ab..2c5d956 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -380,24 +380,28 @@
 		return -EPERM;
 	}
 
-	length = max(length, ETH_ZLEN);
-
 	memcpy((void *)data_start, packet, length);
+	if (length < ETH_ZLEN) {
+		memset(&((char *)data_start)[length], 0, ETH_ZLEN - length);
+		length = ETH_ZLEN;
+	}
 
 	/* Flush data to be sent */
 	flush_dcache_range(data_start, data_end);
 
 #if defined(CONFIG_DW_ALTDESCRIPTOR)
 	desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
-	desc_p->dmamac_cntl |= (length << DESC_TXCTRL_SIZE1SHFT) &
-			       DESC_TXCTRL_SIZE1MASK;
+	desc_p->dmamac_cntl = (desc_p->dmamac_cntl & ~DESC_TXCTRL_SIZE1MASK) |
+			      ((length << DESC_TXCTRL_SIZE1SHFT) &
+			      DESC_TXCTRL_SIZE1MASK);
 
 	desc_p->txrx_status &= ~(DESC_TXSTS_MSK);
 	desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA;
 #else
-	desc_p->dmamac_cntl |= ((length << DESC_TXCTRL_SIZE1SHFT) &
-			       DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST |
-			       DESC_TXCTRL_TXFIRST;
+	desc_p->dmamac_cntl = (desc_p->dmamac_cntl & ~DESC_TXCTRL_SIZE1MASK) |
+			      ((length << DESC_TXCTRL_SIZE1SHFT) &
+			      DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST |
+			      DESC_TXCTRL_TXFIRST;
 
 	desc_p->txrx_status = DESC_TXSTS_OWNBYDMA;
 #endif
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 94c89c7..c9ee222 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -1151,7 +1151,9 @@
 {
 	struct eth_pdata *pdata = dev_get_platdata(dev);
 
-	pdata->iobase = devfdt_get_addr(dev);
+	pdata->iobase = (phys_addr_t)dev_remap_addr(dev);
+	if (!pdata->iobase)
+		return -EINVAL;
 
 	return macb_late_eth_ofdata_to_platdata(dev);
 }
diff --git a/drivers/net/mvgbe.c b/drivers/net/mvgbe.c
index 74fed7a..037e59e 100644
--- a/drivers/net/mvgbe.c
+++ b/drivers/net/mvgbe.c
@@ -1005,10 +1005,8 @@
 	phy_mode = fdt_getprop(gd->fdt_blob, pnode, "phy-mode", NULL);
 	if (phy_mode)
 		pdata->phy_interface = phy_get_interface_by_name(phy_mode);
-	if (pdata->phy_interface == -1) {
-		debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
-		return -EINVAL;
-	}
+	else
+		pdata->phy_interface = PHY_INTERFACE_MODE_GMII;
 
 	dmvgbe->phy_interface = pdata->phy_interface;
 
diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c
index 8cb04b5..333be8f 100644
--- a/drivers/net/mvneta.c
+++ b/drivers/net/mvneta.c
@@ -27,6 +27,7 @@
 #include <asm/arch/soc.h>
 #include <linux/compat.h>
 #include <linux/mbus.h>
+#include <asm-generic/gpio.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -274,6 +275,9 @@
 	int init;
 	int phyaddr;
 	struct phy_device *phydev;
+#ifdef CONFIG_DM_GPIO
+	struct gpio_desc phy_reset_gpio;
+#endif
 	struct mii_dev *bus;
 };
 
@@ -1749,6 +1753,17 @@
 	if (ret)
 		return ret;
 
+#ifdef CONFIG_DM_GPIO
+	gpio_request_by_name(dev, "phy-reset-gpios", 0,
+			     &pp->phy_reset_gpio, GPIOD_IS_OUT);
+
+	if (dm_gpio_is_valid(&pp->phy_reset_gpio)) {
+		dm_gpio_set_value(&pp->phy_reset_gpio, 1);
+		mdelay(10);
+		dm_gpio_set_value(&pp->phy_reset_gpio, 0);
+	}
+#endif
+
 	return board_network_enable(bus);
 }
 
diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c
index 9b3ab25..bcc6fe9 100644
--- a/drivers/net/mvpp2.c
+++ b/drivers/net/mvpp2.c
@@ -897,7 +897,6 @@
 	void __iomem *base;
 	void __iomem *lms_base;
 	void __iomem *iface_base;
-	void __iomem *mdio_base;
 
 	void __iomem *mpcs_base;
 	void __iomem *xpcs_base;
@@ -928,8 +927,6 @@
 	/* Maximum number of RXQs per port */
 	unsigned int max_port_rxqs;
 
-	struct mii_dev *bus;
-
 	int probe_done;
 	u8 num_ports;
 };
@@ -955,6 +952,7 @@
 
 	/* Per-port registers' base address */
 	void __iomem *base;
+	void __iomem *mdio_base;
 
 	struct mvpp2_rx_queue **rxqs;
 	struct mvpp2_tx_queue **txqs;
@@ -977,6 +975,7 @@
 	phy_interface_t phy_interface;
 	int phy_node;
 	int phyaddr;
+	struct mii_dev *bus;
 #ifdef CONFIG_DM_GPIO
 	struct gpio_desc phy_reset_gpio;
 	struct gpio_desc phy_tx_disable_gpio;
@@ -4500,7 +4499,7 @@
 	struct phy_device *phy_dev;
 
 	if (!port->init || port->link == 0) {
-		phy_dev = phy_connect(port->priv->bus, port->phyaddr, dev,
+		phy_dev = phy_connect(port->bus, port->phyaddr, dev,
 				      port->phy_interface);
 		port->phy_dev = phy_dev;
 		if (!phy_dev) {
@@ -4705,39 +4704,34 @@
 {
 	int port_node = dev_of_offset(dev);
 	const char *phy_mode_str;
-	int phy_node, mdio_off, cp_node;
+	int phy_node;
 	u32 id;
 	u32 phyaddr = 0;
 	int phy_mode = -1;
-	phys_addr_t mdio_addr;
+
+	/* Default mdio_base from the same eth base */
+	if (port->priv->hw_version == MVPP21)
+		port->mdio_base = port->priv->lms_base + MVPP21_SMI;
+	else
+		port->mdio_base = port->priv->iface_base + MVPP22_SMI;
 
 	phy_node = fdtdec_lookup_phandle(gd->fdt_blob, port_node, "phy");
 
 	if (phy_node > 0) {
+		ofnode phy_ofnode;
+		fdt_addr_t phy_base;
+
 		phyaddr = fdtdec_get_int(gd->fdt_blob, phy_node, "reg", 0);
 		if (phyaddr < 0) {
 			dev_err(&pdev->dev, "could not find phy address\n");
 			return -1;
 		}
-		mdio_off = fdt_parent_offset(gd->fdt_blob, phy_node);
 
-		/* TODO: This WA for mdio issue. U-boot 2017 don't have
-		 * mdio driver and on MACHIATOBin board ports from CP1
-		 * connected to mdio on CP0.
-		 * WA is to get mdio address from phy handler parent
-		 * base address. WA should be removed after
-		 * mdio driver implementation.
-		 */
-		mdio_addr = fdtdec_get_uint(gd->fdt_blob,
-					    mdio_off, "reg", 0);
+		phy_ofnode = ofnode_get_parent(offset_to_ofnode(phy_node));
+		phy_base = ofnode_get_addr(phy_ofnode);
+		port->mdio_base = (void *)phy_base;
 
-		cp_node = fdt_parent_offset(gd->fdt_blob, mdio_off);
-		mdio_addr |= fdt_get_base_address((void *)gd->fdt_blob,
-						  cp_node);
-
-		port->priv->mdio_base = (void *)mdio_addr;
-
-		if (port->priv->mdio_base < 0) {
+		if (port->mdio_base < 0) {
 			dev_err(&pdev->dev, "could not find mdio base address\n");
 			return -1;
 		}
@@ -5059,7 +5053,7 @@
 
 /* SMI / MDIO functions */
 
-static int smi_wait_ready(struct mvpp2 *priv)
+static int smi_wait_ready(struct mvpp2_port *priv)
 {
 	u32 timeout = MVPP2_SMI_TIMEOUT;
 	u32 smi_reg;
@@ -5084,7 +5078,7 @@
  */
 static int mpp2_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
 {
-	struct mvpp2 *priv = bus->priv;
+	struct mvpp2_port *priv = bus->priv;
 	u32 smi_reg;
 	u32 timeout;
 
@@ -5139,7 +5133,7 @@
 static int mpp2_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
 			   u16 value)
 {
-	struct mvpp2 *priv = bus->priv;
+	struct mvpp2_port *priv = bus->priv;
 	u32 smi_reg;
 
 	/* check parameters */
@@ -5338,7 +5332,6 @@
 static int mvpp2_base_probe(struct udevice *dev)
 {
 	struct mvpp2 *priv = dev_get_priv(dev);
-	struct mii_dev *bus;
 	void *bd_space;
 	u32 size = 0;
 	int i;
@@ -5397,15 +5390,11 @@
 		priv->lms_base = (void *)devfdt_get_addr_index(dev, 1);
 		if (IS_ERR(priv->lms_base))
 			return PTR_ERR(priv->lms_base);
-
-		priv->mdio_base = priv->lms_base + MVPP21_SMI;
 	} else {
 		priv->iface_base = (void *)devfdt_get_addr_index(dev, 1);
 		if (IS_ERR(priv->iface_base))
 			return PTR_ERR(priv->iface_base);
 
-		priv->mdio_base = priv->iface_base + MVPP22_SMI;
-
 		/* Store common base addresses for all ports */
 		priv->mpcs_base = priv->iface_base + MVPP22_MPCS;
 		priv->xpcs_base = priv->iface_base + MVPP22_XPCS;
@@ -5417,7 +5406,23 @@
 	else
 		priv->max_port_rxqs = 32;
 
-	/* Finally create and register the MDIO bus driver */
+	return 0;
+}
+
+static int mvpp2_probe(struct udevice *dev)
+{
+	struct mvpp2_port *port = dev_get_priv(dev);
+	struct mvpp2 *priv = dev_get_priv(dev->parent);
+	struct mii_dev *bus;
+	int err;
+
+	/* Only call the probe function for the parent once */
+	if (!priv->probe_done)
+		err = mvpp2_base_probe(dev->parent);
+
+	port->priv = dev_get_priv(dev->parent);
+
+	/* Create and register the MDIO bus driver */
 	bus = mdio_alloc();
 	if (!bus) {
 		printf("Failed to allocate MDIO bus\n");
@@ -5427,23 +5432,12 @@
 	bus->read = mpp2_mdio_read;
 	bus->write = mpp2_mdio_write;
 	snprintf(bus->name, sizeof(bus->name), dev->name);
-	bus->priv = (void *)priv;
-	priv->bus = bus;
+	bus->priv = (void *)port;
+	port->bus = bus;
 
-	return mdio_register(bus);
-}
-
-static int mvpp2_probe(struct udevice *dev)
-{
-	struct mvpp2_port *port = dev_get_priv(dev);
-	struct mvpp2 *priv = dev_get_priv(dev->parent);
-	int err;
-
-	/* Only call the probe function for the parent once */
-	if (!priv->probe_done)
-		err = mvpp2_base_probe(dev->parent);
-
-	port->priv = dev_get_priv(dev->parent);
+	err = mdio_register(bus);
+	if (err)
+		return err;
 
 	err = phy_info_parse(dev, port);
 	if (err)
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
index a0abb23..12df098 100644
--- a/drivers/net/phy/aquantia.c
+++ b/drivers/net/phy/aquantia.c
@@ -3,6 +3,7 @@
  * Aquantia PHY drivers
  *
  * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
  */
 #include <config.h>
 #include <common.h>
@@ -19,6 +20,18 @@
 #define AQUNTIA_SPEED_LSB_MASK	0x2000
 #define AQUNTIA_SPEED_MSB_MASK	0x40
 
+#define AQUANTIA_SYSTEM_INTERFACE_SR     0xe812
+#define AQUANTIA_VENDOR_PROVISIONING_REG 0xC441
+#define AQUANTIA_FIRMWARE_ID		 0x20
+#define AQUANTIA_RESERVED_STATUS	 0xc885
+#define AQUANTIA_FIRMWARE_MAJOR_MASK	 0xff00
+#define AQUANTIA_FIRMWARE_MINOR_MASK	 0xff
+#define AQUANTIA_FIRMWARE_BUILD_MASK	 0xf0
+
+#define AQUANTIA_USX_AUTONEG_CONTROL_ENA 0x0008
+#define AQUANTIA_SI_IN_USE_MASK          0x0078
+#define AQUANTIA_SI_USXGMII              0x0018
+
 /* registers in MDIO_MMD_VEND1 region */
 #define GLOBAL_FIRMWARE_ID 0x20
 #define GLOBAL_FAULT 0xc850
@@ -244,6 +257,7 @@
 int aquantia_config(struct phy_device *phydev)
 {
 	u32 val, id, rstatus, fault;
+	u32 reg_val1 = 0;
 
 	id = phy_read(phydev, MDIO_MMD_VEND1, GLOBAL_FIRMWARE_ID);
 	rstatus = phy_read(phydev, MDIO_MMD_VEND1, GLOBAL_RSTATUS_1);
@@ -284,6 +298,21 @@
 			phy_write(phydev, MDIO_MMD_PMAPMD, MII_BMCR,
 				  AQUNTIA_SPEED_LSB_MASK |
 				  AQUNTIA_SPEED_MSB_MASK);
+
+		val = phy_read(phydev, MDIO_MMD_PHYXS,
+			       AQUANTIA_SYSTEM_INTERFACE_SR);
+		/* If SI is USXGMII then start USXGMII autoneg */
+		if ((val & AQUANTIA_SI_IN_USE_MASK) == AQUANTIA_SI_USXGMII) {
+			phy_write(phydev, MDIO_MMD_PHYXS,
+				  AQUANTIA_VENDOR_PROVISIONING_REG,
+				  AQUANTIA_USX_AUTONEG_CONTROL_ENA);
+			printf("%s: system interface USXGMII\n",
+			       phydev->dev->name);
+		} else {
+			printf("%s: system interface XFI\n",
+			       phydev->dev->name);
+		}
+
 	} else if (phydev->interface == PHY_INTERFACE_MODE_SGMII_2500) {
 		/* 2.5GBASE-T mode */
 		phydev->advertising = SUPPORTED_1000baseT_Full;
@@ -299,6 +328,16 @@
 		val = (val & ~AQUNTIA_SPEED_MSB_MASK) | AQUNTIA_SPEED_LSB_MASK;
 		phy_write(phydev, MDIO_MMD_PMAPMD, MII_BMCR, val);
 	}
+
+	val = phy_read(phydev, MDIO_MMD_VEND1, AQUANTIA_RESERVED_STATUS);
+	reg_val1 = phy_read(phydev, MDIO_MMD_VEND1, AQUANTIA_FIRMWARE_ID);
+
+	printf("%s: %s Firmware Version %x.%x.%x\n", phydev->dev->name,
+	       phydev->drv->name,
+	       (reg_val1 & AQUANTIA_FIRMWARE_MAJOR_MASK) >> 8,
+	       reg_val1 & AQUANTIA_FIRMWARE_MINOR_MASK,
+	       (val & AQUANTIA_FIRMWARE_BUILD_MASK) >> 4);
+
 	return 0;
 }
 
diff --git a/drivers/net/phy/micrel_ksz90x1.c b/drivers/net/phy/micrel_ksz90x1.c
index 3951535..63e7b02 100644
--- a/drivers/net/phy/micrel_ksz90x1.c
+++ b/drivers/net/phy/micrel_ksz90x1.c
@@ -123,8 +123,8 @@
 		} else {
 			changed = 1;	/* Value was changed in OF */
 			/* Calculate the register value and fix corner cases */
-			if (val[i] > ps_to_regval * 0xf) {
-				max = (1 << ofcfg->grp[i].size) - 1;
+			max = (1 << ofcfg->grp[i].size) - 1;
+			if (val[i] > ps_to_regval * max) {
 				regval |= max << offset;
 			} else {
 				regval |= (val[i] / ps_to_regval) << offset;
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 236913a..0c8b29d 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -620,7 +620,7 @@
 }
 
 static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
-					    u32 phy_id,
+					    u32 phy_id, bool is_c45,
 					    phy_interface_t interface)
 {
 	struct phy_device *dev;
@@ -650,6 +650,7 @@
 
 	dev->addr = addr;
 	dev->phy_id = phy_id;
+	dev->is_c45 = is_c45;
 	dev->bus = bus;
 
 	dev->drv = get_phy_driver(dev, interface);
@@ -702,13 +703,17 @@
 					     phy_interface_t interface)
 {
 	u32 phy_id = 0xffffffff;
+	bool is_c45;
 
 	while (phy_mask) {
 		int addr = ffs(phy_mask) - 1;
 		int r = get_phy_id(bus, addr, devad, &phy_id);
 		/* If the PHY ID is mostly f's, we didn't find anything */
-		if (r == 0 && (phy_id & 0x1fffffff) != 0x1fffffff)
-			return phy_device_create(bus, addr, phy_id, interface);
+		if (r == 0 && (phy_id & 0x1fffffff) != 0x1fffffff) {
+			is_c45 = (devad == MDIO_DEVAD_NONE) ? false : true;
+			return phy_device_create(bus, addr, phy_id, is_c45,
+						 interface);
+		}
 		phy_mask &= ~(1 << addr);
 	}
 	return NULL;
@@ -895,8 +900,8 @@
 	while (sn > 0) {
 		name = fdt_get_name(gd->fdt_blob, sn, NULL);
 		if (name && strcmp(name, "fixed-link") == 0) {
-			phydev = phy_device_create(bus,
-						   sn, PHY_FIXED_ID, interface);
+			phydev = phy_device_create(bus, sn, PHY_FIXED_ID, false,
+						   interface);
 			break;
 		}
 		sn = fdt_next_subnode(gd->fdt_blob, sn);
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index b3e6578..dd45e11 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -57,6 +57,33 @@
 #define MIIM_RTL8211F_TX_DELAY		0x100
 #define MIIM_RTL8211F_LCR		0x10
 
+static int rtl8211f_phy_extread(struct phy_device *phydev, int addr,
+				int devaddr, int regnum)
+{
+	int oldpage = phy_read(phydev, MDIO_DEVAD_NONE,
+			       MIIM_RTL8211F_PAGE_SELECT);
+	int val;
+
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, devaddr);
+	val = phy_read(phydev, MDIO_DEVAD_NONE, regnum);
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, oldpage);
+
+	return val;
+}
+
+static int rtl8211f_phy_extwrite(struct phy_device *phydev, int addr,
+				 int devaddr, int regnum, u16 val)
+{
+	int oldpage = phy_read(phydev, MDIO_DEVAD_NONE,
+			       MIIM_RTL8211F_PAGE_SELECT);
+
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, devaddr);
+	phy_write(phydev, MDIO_DEVAD_NONE, regnum, val);
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, oldpage);
+
+	return 0;
+}
+
 static int rtl8211b_probe(struct phy_device *phydev)
 {
 #ifdef CONFIG_RTL8211X_PHY_FORCE_MASTER
@@ -336,6 +363,8 @@
 	.config = &rtl8211f_config,
 	.startup = &rtl8211f_startup,
 	.shutdown = &genphy_shutdown,
+	.readext = &rtl8211f_phy_extread,
+	.writeext = &rtl8211f_phy_extwrite,
 };
 
 int phy_realtek_init(void)
diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c
index 590f8ce..1330997 100644
--- a/drivers/net/rtl8139.c
+++ b/drivers/net/rtl8139.c
@@ -183,12 +183,10 @@
 static int rtl_transmit(struct eth_device *dev, void *packet, int length);
 static int rtl_poll(struct eth_device *dev);
 static void rtl_disable(struct eth_device *dev);
-#ifdef CONFIG_MCAST_TFTP/*  This driver already accepts all b/mcast */
-static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, u8 set)
+static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, int join)
 {
 	return (0);
 }
-#endif
 
 static struct pci_device_id supported[] = {
        {PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139},
@@ -229,9 +227,7 @@
 		dev->halt = rtl_disable;
 		dev->send = rtl_transmit;
 		dev->recv = rtl_poll;
-#ifdef CONFIG_MCAST_TFTP
 		dev->mcast = rtl_bcast_addr;
-#endif
 
 		eth_register (dev);
 
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index 03a46da..06a9b4f 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -78,7 +78,30 @@
 			      0, TBI_CR, CONFIG_TSEC_TBICR_SETTINGS);
 }
 
-#ifdef CONFIG_MCAST_TFTP
+/* the 'way' for ethernet-CRC-32. Spliced in from Linux lib/crc32.c
+ * and this is the ethernet-crc method needed for TSEC -- and perhaps
+ * some other adapter -- hash tables
+ */
+#define CRCPOLY_LE 0xedb88320
+static u32 ether_crc(size_t len, unsigned char const *p)
+{
+	int i;
+	u32 crc;
+
+	crc = ~0;
+	while (len--) {
+		crc ^= *p++;
+		for (i = 0; i < 8; i++)
+			crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
+	}
+	/* an reverse the bits, cuz of way they arrive -- last-first */
+	crc = (crc >> 16) | (crc << 16);
+	crc = (crc >> 8 & 0x00ff00ff) | (crc << 8 & 0xff00ff00);
+	crc = (crc >> 4 & 0x0f0f0f0f) | (crc << 4 & 0xf0f0f0f0);
+	crc = (crc >> 2 & 0x33333333) | (crc << 2 & 0xcccccccc);
+	crc = (crc >> 1 & 0x55555555) | (crc << 1 & 0xaaaaaaaa);
+	return crc;
+}
 
 /* CREDITS: linux gianfar driver, slightly adjusted... thanx. */
 
@@ -99,9 +122,10 @@
  * the entry.
  */
 #ifndef CONFIG_DM_ETH
-static int tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set)
+static int tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac,
+			   int join)
 #else
-static int tsec_mcast_addr(struct udevice *dev, const u8 *mcast_mac, int set)
+static int tsec_mcast_addr(struct udevice *dev, const u8 *mcast_mac, int join)
 #endif
 {
 	struct tsec_private *priv = (struct tsec_private *)dev->priv;
@@ -115,14 +139,13 @@
 
 	value = BIT(31 - whichbit);
 
-	if (set)
+	if (join)
 		setbits_be32(&regs->hash.gaddr0 + whichreg, value);
 	else
 		clrbits_be32(&regs->hash.gaddr0 + whichreg, value);
 
 	return 0;
 }
-#endif /* Multicast TFTP ? */
 
 /*
  * Initialized required registers to appropriate values, zeroing
@@ -720,9 +743,7 @@
 	dev->halt = tsec_halt;
 	dev->send = tsec_send;
 	dev->recv = tsec_recv;
-#ifdef CONFIG_MCAST_TFTP
 	dev->mcast = tsec_mcast_addr;
-#endif
 
 	/* Tell U-Boot to get the addr from the env */
 	for (i = 0; i < 6; i++)
@@ -862,9 +883,7 @@
 	.recv = tsec_recv,
 	.free_pkt = tsec_free_pkt,
 	.stop = tsec_halt,
-#ifdef CONFIG_MCAST_TFTP
 	.mcast = tsec_mcast_addr,
-#endif
 };
 
 static const struct udevice_id tsec_ids[] = {
diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
index a7d7e3f..f206fa3 100644
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
@@ -11,10 +11,12 @@
  */
 
 #include <common.h>
+#include <clk.h>
 #include <dm.h>
 #include <dm/device.h>
 #include <generic-phy.h>
 #include <phy-sun4i-usb.h>
+#include <reset.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
@@ -80,6 +82,7 @@
 	enum sun4i_usb_phy_type type;
 	u32 disc_thresh;
 	u8 phyctl_offset;
+	bool dedicated_clocks;
 	bool enable_pmu_unk1;
 	bool phy0_dual_route;
 };
@@ -88,30 +91,21 @@
 	const char *gpio_vbus;
 	const char *gpio_vbus_det;
 	const char *gpio_id_det;
-	int rst_mask;
 } phy_info[] = {
 	{
 		.gpio_vbus = CONFIG_USB0_VBUS_PIN,
 		.gpio_vbus_det = CONFIG_USB0_VBUS_DET,
 		.gpio_id_det = CONFIG_USB0_ID_DET,
-		.rst_mask = (CCM_USB_CTRL_PHY0_RST | CCM_USB_CTRL_PHY0_CLK),
 	},
 	{
 		.gpio_vbus = CONFIG_USB1_VBUS_PIN,
 		.gpio_vbus_det = NULL,
 		.gpio_id_det = NULL,
-		.rst_mask = (CCM_USB_CTRL_PHY1_RST | CCM_USB_CTRL_PHY1_CLK),
 	},
 	{
 		.gpio_vbus = CONFIG_USB2_VBUS_PIN,
 		.gpio_vbus_det = NULL,
 		.gpio_id_det = NULL,
-#ifdef CONFIG_MACH_SUN8I_A83T
-		.rst_mask = (CCM_USB_CTRL_HSIC_RST | CCM_USB_CTRL_HSIC_CLK |
-			     CCM_USB_CTRL_12M_CLK),
-#else
-		.rst_mask = (CCM_USB_CTRL_PHY2_RST | CCM_USB_CTRL_PHY2_CLK),
-#endif
 	},
 	{
 		.gpio_vbus = CONFIG_USB3_VBUS_PIN,
@@ -126,13 +120,13 @@
 	int gpio_vbus;
 	int gpio_vbus_det;
 	int gpio_id_det;
-	int rst_mask;
+	struct clk clocks;
+	struct reset_ctl resets;
 	int id;
 };
 
 struct sun4i_usb_phy_data {
 	void __iomem *base;
-	struct sunxi_ccm_reg *ccm;
 	const struct sun4i_usb_phy_cfg *cfg;
 	struct sun4i_usb_phy_plat *usb_phy;
 };
@@ -266,8 +260,19 @@
 	struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev);
 	struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id];
 	u32 val;
+	int ret;
 
-	setbits_le32(&data->ccm->usb_clk_cfg, usb_phy->rst_mask);
+	ret = clk_enable(&usb_phy->clocks);
+	if (ret) {
+		dev_err(dev, "failed to enable usb_%ldphy clock\n", phy->id);
+		return ret;
+	}
+
+	ret = reset_deassert(&usb_phy->resets);
+	if (ret) {
+		dev_err(dev, "failed to deassert usb_%ldreset reset\n", phy->id);
+		return ret;
+	}
 
 	if (data->cfg->type == sun8i_a83t_phy) {
 		if (phy->id == 0) {
@@ -308,6 +313,7 @@
 {
 	struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev);
 	struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id];
+	int ret;
 
 	if (phy->id == 0) {
 		if (data->cfg->type == sun8i_a83t_phy) {
@@ -320,7 +326,17 @@
 
 	sun4i_usb_phy_passby(phy, false);
 
-	clrbits_le32(&data->ccm->usb_clk_cfg, usb_phy->rst_mask);
+	ret = clk_disable(&usb_phy->clocks);
+	if (ret) {
+		dev_err(dev, "failed to disable usb_%ldphy clock\n", phy->id);
+		return ret;
+	}
+
+	ret = reset_assert(&usb_phy->resets);
+	if (ret) {
+		dev_err(dev, "failed to assert usb_%ldreset reset\n", phy->id);
+		return ret;
+	}
 
 	return 0;
 }
@@ -407,10 +423,6 @@
 	if (IS_ERR(data->base))
 		return PTR_ERR(data->base);
 
-	data->ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
-	if (IS_ERR(data->ccm))
-		return PTR_ERR(data->ccm);
-
 	data->usb_phy = plat;
 	for (i = 0; i < data->cfg->num_phys; i++) {
 		struct sun4i_usb_phy_plat *phy = &plat[i];
@@ -448,6 +460,24 @@
 			sunxi_gpio_set_pull(phy->gpio_id_det, SUNXI_GPIO_PULL_UP);
 		}
 
+		if (data->cfg->dedicated_clocks)
+			snprintf(name, sizeof(name), "usb%d_phy", i);
+		else
+			strlcpy(name, "usb_phy", sizeof(name));
+
+		ret = clk_get_by_name(dev, name, &phy->clocks);
+		if (ret) {
+			dev_err(dev, "failed to get usb%d_phy clock phandle\n", i);
+			return ret;
+		}
+
+		snprintf(name, sizeof(name), "usb%d_reset", i);
+		ret = reset_get_by_name(dev, name, &phy->resets);
+		if (ret) {
+			dev_err(dev, "failed to get usb%d_reset reset phandle\n", i);
+			return ret;
+		}
+
 		if (i || data->cfg->phy0_dual_route) {
 			snprintf(name, sizeof(name), "pmu%d", i);
 			phy->pmu = (void __iomem *)devfdt_get_addr_name(dev, name);
@@ -456,9 +486,6 @@
 		}
 
 		phy->id = i;
-		phy->rst_mask = info->rst_mask;
-		if ((data->cfg->type == sun8i_h3_phy) && (phy->id == 3))
-			phy->rst_mask = (BIT(3) | BIT(11));
 	};
 
 	debug("Allwinner Sun4I USB PHY driver loaded\n");
@@ -470,6 +497,7 @@
 	.type = sun4i_a10_phy,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A10,
+	.dedicated_clocks = false,
 	.enable_pmu_unk1 = false,
 };
 
@@ -478,6 +506,7 @@
 	.type = sun4i_a10_phy,
 	.disc_thresh = 2,
 	.phyctl_offset = REG_PHYCTL_A10,
+	.dedicated_clocks = false,
 	.enable_pmu_unk1 = false,
 };
 
@@ -486,6 +515,7 @@
 	.type = sun6i_a31_phy,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A10,
+	.dedicated_clocks = true,
 	.enable_pmu_unk1 = false,
 };
 
@@ -494,6 +524,7 @@
 	.type = sun4i_a10_phy,
 	.disc_thresh = 2,
 	.phyctl_offset = REG_PHYCTL_A10,
+	.dedicated_clocks = false,
 	.enable_pmu_unk1 = false,
 };
 
@@ -502,6 +533,7 @@
 	.type = sun4i_a10_phy,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A10,
+	.dedicated_clocks = true,
 	.enable_pmu_unk1 = false,
 };
 
@@ -510,6 +542,7 @@
 	.type = sun8i_a33_phy,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A33,
+	.dedicated_clocks = true,
 	.enable_pmu_unk1 = false,
 };
 
@@ -517,6 +550,7 @@
 	.num_phys = 3,
 	.type = sun8i_a83t_phy,
 	.phyctl_offset = REG_PHYCTL_A33,
+	.dedicated_clocks = true,
 };
 
 static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
@@ -524,6 +558,7 @@
 	.type = sun8i_h3_phy,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A33,
+	.dedicated_clocks = true,
 	.enable_pmu_unk1 = true,
 	.phy0_dual_route = true,
 };
@@ -533,6 +568,7 @@
 	.type = sun8i_v3s_phy,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A33,
+	.dedicated_clocks = true,
 	.enable_pmu_unk1 = true,
 	.phy0_dual_route = true,
 };
@@ -542,6 +578,7 @@
 	.type = sun50i_a64_phy,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A33,
+	.dedicated_clocks = true,
 	.enable_pmu_unk1 = true,
 	.phy0_dual_route = true,
 };
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 3a6d61f..a81e767 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -113,4 +113,12 @@
 	help
 	  Support for reset controller on MediaTek SoCs.
 
+config RESET_SUNXI
+	bool "RESET support for Allwinner SoCs"
+	depends on DM_RESET && ARCH_SUNXI
+	default y
+	help
+	  This enables support for common reset driver for
+	  Allwinner SoCs.
+
 endmenu
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 8a4dcab..4fad7d4 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -18,3 +18,4 @@
 obj-$(CONFIG_RESET_MESON) += reset-meson.o
 obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
 obj-$(CONFIG_RESET_MEDIATEK) += reset-mediatek.o
+obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c
new file mode 100644
index 0000000..364dc52
--- /dev/null
+++ b/drivers/reset/reset-sunxi.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 Amarula Solutions.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <reset-uclass.h>
+#include <asm/io.h>
+#include <dm/lists.h>
+#include <linux/log2.h>
+#include <asm/arch/ccu.h>
+
+struct sunxi_reset_priv {
+	void *base;
+	ulong count;
+	const struct ccu_desc *desc;
+};
+
+static const struct ccu_reset *priv_to_reset(struct sunxi_reset_priv *priv,
+					     unsigned long id)
+{
+	return	&priv->desc->resets[id];
+}
+
+static int sunxi_reset_request(struct reset_ctl *reset_ctl)
+{
+	struct sunxi_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+
+	debug("%s: (RST#%ld)\n", __func__, reset_ctl->id);
+
+	if (reset_ctl->id >= priv->count)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int sunxi_reset_free(struct reset_ctl *reset_ctl)
+{
+	debug("%s: (RST#%ld)\n", __func__, reset_ctl->id);
+
+	return 0;
+}
+
+static int sunxi_set_reset(struct reset_ctl *reset_ctl, bool on)
+{
+	struct sunxi_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+	const struct ccu_reset *reset = priv_to_reset(priv, reset_ctl->id);
+	u32 reg;
+
+	if (!(reset->flags & CCU_RST_F_IS_VALID)) {
+		printf("%s: (RST#%ld) unhandled\n", __func__, reset_ctl->id);
+		return 0;
+	}
+
+	debug("%s: (RST#%ld) off#0x%x, BIT(%d)\n", __func__,
+	      reset_ctl->id, reset->off, ilog2(reset->bit));
+
+	reg = readl(priv->base + reset->off);
+	if (on)
+		reg |= reset->bit;
+	else
+		reg &= ~reset->bit;
+
+	writel(reg, priv->base + reset->off);
+
+	return 0;
+}
+
+static int sunxi_reset_assert(struct reset_ctl *reset_ctl)
+{
+	return sunxi_set_reset(reset_ctl, false);
+}
+
+static int sunxi_reset_deassert(struct reset_ctl *reset_ctl)
+{
+	return sunxi_set_reset(reset_ctl, true);
+}
+
+struct reset_ops sunxi_reset_ops = {
+	.request = sunxi_reset_request,
+	.free = sunxi_reset_free,
+	.rst_assert = sunxi_reset_assert,
+	.rst_deassert = sunxi_reset_deassert,
+};
+
+static int sunxi_reset_probe(struct udevice *dev)
+{
+	struct sunxi_reset_priv *priv = dev_get_priv(dev);
+
+	priv->base = dev_read_addr_ptr(dev);
+
+	return 0;
+}
+
+int sunxi_reset_bind(struct udevice *dev, ulong count)
+{
+	struct udevice *rst_dev;
+	struct sunxi_reset_priv *priv;
+	int ret;
+
+	ret = device_bind_driver_to_node(dev, "sunxi_reset", "reset",
+					 dev_ofnode(dev), &rst_dev);
+	if (ret) {
+		debug("failed to bind sunxi_reset driver (ret=%d)\n", ret);
+		return ret;
+	}
+	priv = malloc(sizeof(struct sunxi_reset_priv));
+	priv->count = count;
+	priv->desc = (const struct ccu_desc *)dev_get_driver_data(dev);
+	rst_dev->priv = priv;
+
+	return 0;
+}
+
+U_BOOT_DRIVER(sunxi_reset) = {
+	.name		= "sunxi_reset",
+	.id		= UCLASS_RESET,
+	.ops		= &sunxi_reset_ops,
+	.probe		= sunxi_reset_probe,
+	.priv_auto_alloc_size = sizeof(struct sunxi_reset_priv),
+};
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 3b3d9af..e4993dc 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -2579,9 +2579,6 @@
 	netdev->halt = usb_eth_halt;
 	netdev->priv = l_priv;
 
-#ifdef CONFIG_MCAST_TFTP
-  #error not supported
-#endif
 	eth_register(netdev);
 	return 0;
 }
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index a213c91..60f37f4 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -190,6 +190,7 @@
 	bool "Support for generic EHCI USB controller"
 	depends on OF_CONTROL
 	depends on DM_USB
+	default ARCH_SUNXI
 	default n
 	---help---
 	  Enables support for generic EHCI controller.
@@ -220,6 +221,7 @@
 	bool "Support for generic OHCI USB controller"
 	depends on OF_CONTROL
 	depends on DM_USB
+	default ARCH_SUNXI
 	select USB_HOST
 	---help---
 	  Enables support for generic OHCI controller.
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 948683a..6aa574f 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -15,7 +15,6 @@
 obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
 obj-$(CONFIG_USB_SL811HS) += sl811-hcd.o
 obj-$(CONFIG_USB_OHCI_EP93XX) += ohci-ep93xx.o
-obj-$(CONFIG_USB_OHCI_SUNXI) += ohci-sunxi.o
 obj-$(CONFIG_USB_OHCI_LPC32XX) += ohci-lpc32xx.o
 obj-$(CONFIG_USB_OHCI_GENERIC) += ohci-generic.o
 
@@ -37,7 +36,6 @@
 obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o
 obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o
 obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o
-obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o
 obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o
 obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o
 obj-$(CONFIG_USB_EHCI_VF) += ehci-vf.o
diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c
deleted file mode 100644
index 7a79931..0000000
--- a/drivers/usb/host/ehci-sunxi.c
+++ /dev/null
@@ -1,204 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Sunxi ehci glue
- *
- * Copyright (C) 2015 Hans de Goede <hdegoede@redhat.com>
- * Copyright (C) 2014 Roman Byshko <rbyshko@gmail.com>
- *
- * Based on code from
- * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
- */
-
-#include <common.h>
-#include <asm/arch/clock.h>
-#include <asm/io.h>
-#include <dm.h>
-#include "ehci.h"
-#include <generic-phy.h>
-
-#ifdef CONFIG_SUNXI_GEN_SUN4I
-#define BASE_DIST		0x8000
-#define AHB_CLK_DIST		2
-#else
-#define BASE_DIST		0x1000
-#define AHB_CLK_DIST		1
-#endif
-
-#define SUN6I_AHB_RESET0_CFG_OFFSET 0x2c0
-#define SUN9I_AHB_RESET0_CFG_OFFSET 0x5a0
-
-struct ehci_sunxi_cfg {
-	bool has_reset;
-	u32 extra_ahb_gate_mask;
-	u32 reset0_cfg_offset;
-};
-
-struct ehci_sunxi_priv {
-	struct ehci_ctrl ehci;
-	struct sunxi_ccm_reg *ccm;
-	u32 *reset0_cfg;
-	int ahb_gate_mask; /* Mask of ahb_gate0 clk gate bits for this hcd */
-	struct phy phy;
-	const struct ehci_sunxi_cfg *cfg;
-};
-
-static int ehci_usb_probe(struct udevice *dev)
-{
-	struct usb_platdata *plat = dev_get_platdata(dev);
-	struct ehci_sunxi_priv *priv = dev_get_priv(dev);
-	struct ehci_hccr *hccr = (struct ehci_hccr *)devfdt_get_addr(dev);
-	struct ehci_hcor *hcor;
-	int extra_ahb_gate_mask = 0;
-	u8 reg_mask = 0;
-	int phys, ret;
-
-	priv->cfg = (const struct ehci_sunxi_cfg *)dev_get_driver_data(dev);
-	priv->ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
-	if (IS_ERR(priv->ccm))
-		return PTR_ERR(priv->ccm);
-
-	priv->reset0_cfg = (void *)priv->ccm +
-				   priv->cfg->reset0_cfg_offset;
-
-	phys = dev_count_phandle_with_args(dev, "phys", "#phy-cells");
-	if (phys < 0) {
-		phys = 0;
-		goto no_phy;
-	}
-
-	ret = generic_phy_get_by_name(dev, "usb", &priv->phy);
-	if (ret) {
-		pr_err("failed to get %s usb PHY\n", dev->name);
-		return ret;
-	}
-
-	ret = generic_phy_init(&priv->phy);
-	if (ret) {
-		pr_err("failed to init %s USB PHY\n", dev->name);
-		return ret;
-	}
-
-	ret = generic_phy_power_on(&priv->phy);
-	if (ret) {
-		pr_err("failed to power on %s USB PHY\n", dev->name);
-		return ret;
-	}
-
-no_phy:
-	/*
-	 * This should go away once we've moved to the driver model for
-	 * clocks resp. phys.
-	 */
-	reg_mask = ((uintptr_t)hccr - SUNXI_USB1_BASE) / BASE_DIST;
-	priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_EHCI0;
-	extra_ahb_gate_mask = priv->cfg->extra_ahb_gate_mask;
-	priv->ahb_gate_mask <<= reg_mask * AHB_CLK_DIST;
-	extra_ahb_gate_mask <<= reg_mask * AHB_CLK_DIST;
-
-	setbits_le32(&priv->ccm->ahb_gate0,
-		     priv->ahb_gate_mask | extra_ahb_gate_mask);
-	if (priv->cfg->has_reset)
-		setbits_le32(priv->reset0_cfg,
-			     priv->ahb_gate_mask | extra_ahb_gate_mask);
-
-	hcor = (struct ehci_hcor *)((uintptr_t)hccr +
-				    HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
-
-	return ehci_register(dev, hccr, hcor, NULL, 0, plat->init_type);
-}
-
-static int ehci_usb_remove(struct udevice *dev)
-{
-	struct ehci_sunxi_priv *priv = dev_get_priv(dev);
-	int ret;
-
-	if (generic_phy_valid(&priv->phy)) {
-		ret = generic_phy_exit(&priv->phy);
-		if (ret) {
-			pr_err("failed to exit %s USB PHY\n", dev->name);
-			return ret;
-		}
-	}
-
-	ret = ehci_deregister(dev);
-	if (ret)
-		return ret;
-
-	if (priv->cfg->has_reset)
-		clrbits_le32(priv->reset0_cfg, priv->ahb_gate_mask);
-	clrbits_le32(&priv->ccm->ahb_gate0, priv->ahb_gate_mask);
-
-	return 0;
-}
-
-static const struct ehci_sunxi_cfg sun4i_a10_cfg = {
-	.has_reset = false,
-};
-
-static const struct ehci_sunxi_cfg sun6i_a31_cfg = {
-	.has_reset = true,
-	.reset0_cfg_offset = SUN6I_AHB_RESET0_CFG_OFFSET,
-};
-
-static const struct ehci_sunxi_cfg sun8i_h3_cfg = {
-	.has_reset = true,
-	.extra_ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_OHCI0,
-	.reset0_cfg_offset = SUN6I_AHB_RESET0_CFG_OFFSET,
-};
-
-static const struct ehci_sunxi_cfg sun9i_a80_cfg = {
-	.has_reset = true,
-	.reset0_cfg_offset = SUN9I_AHB_RESET0_CFG_OFFSET,
-};
-
-static const struct udevice_id ehci_usb_ids[] = {
-	{
-		.compatible = "allwinner,sun4i-a10-ehci",
-		.data = (ulong)&sun4i_a10_cfg,
-	},
-	{
-		.compatible = "allwinner,sun5i-a13-ehci",
-		.data = (ulong)&sun4i_a10_cfg,
-	},
-	{
-		.compatible = "allwinner,sun6i-a31-ehci",
-		.data = (ulong)&sun6i_a31_cfg,
-	},
-	{
-		.compatible = "allwinner,sun7i-a20-ehci",
-		.data = (ulong)&sun4i_a10_cfg,
-	},
-	{
-		.compatible = "allwinner,sun8i-a23-ehci",
-		.data = (ulong)&sun6i_a31_cfg,
-	},
-	{
-		.compatible = "allwinner,sun8i-a83t-ehci",
-		.data = (ulong)&sun6i_a31_cfg,
-	},
-	{
-		.compatible = "allwinner,sun8i-h3-ehci",
-		.data = (ulong)&sun8i_h3_cfg,
-	},
-	{
-		.compatible = "allwinner,sun9i-a80-ehci",
-		.data = (ulong)&sun9i_a80_cfg,
-	},
-	{
-		.compatible = "allwinner,sun50i-a64-ehci",
-		.data = (ulong)&sun8i_h3_cfg,
-	},
-	{ /* sentinel */ }
-};
-
-U_BOOT_DRIVER(ehci_sunxi) = {
-	.name	= "ehci_sunxi",
-	.id	= UCLASS_USB,
-	.of_match = ehci_usb_ids,
-	.probe = ehci_usb_probe,
-	.remove = ehci_usb_remove,
-	.ops	= &ehci_usb_ops,
-	.platdata_auto_alloc_size = sizeof(struct usb_platdata),
-	.priv_auto_alloc_size = sizeof(struct ehci_sunxi_priv),
-	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
-};
diff --git a/drivers/usb/host/ohci-sunxi.c b/drivers/usb/host/ohci-sunxi.c
deleted file mode 100644
index bb3c247..0000000
--- a/drivers/usb/host/ohci-sunxi.c
+++ /dev/null
@@ -1,233 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Sunxi ohci glue
- *
- * Copyright (C) 2015 Hans de Goede <hdegoede@redhat.com>
- *
- * Based on code from
- * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
- */
-
-#include <common.h>
-#include <asm/arch/clock.h>
-#include <asm/io.h>
-#include <dm.h>
-#include <usb.h>
-#include "ohci.h"
-#include <generic-phy.h>
-
-#ifdef CONFIG_SUNXI_GEN_SUN4I
-#define BASE_DIST		0x8000
-#define AHB_CLK_DIST		2
-#else
-#define BASE_DIST		0x1000
-#define AHB_CLK_DIST		1
-#endif
-
-#define SUN6I_AHB_RESET0_CFG_OFFSET 0x2c0
-#define SUN9I_AHB_RESET0_CFG_OFFSET 0x5a0
-
-struct ohci_sunxi_cfg {
-	bool has_reset;
-	u32 extra_ahb_gate_mask;
-	u32 extra_usb_gate_mask;
-	u32 reset0_cfg_offset;
-};
-
-struct ohci_sunxi_priv {
-	ohci_t ohci;
-	struct sunxi_ccm_reg *ccm;
-	u32 *reset0_cfg;
-	int ahb_gate_mask; /* Mask of ahb_gate0 clk gate bits for this hcd */
-	int usb_gate_mask; /* Mask of usb_clk_cfg clk gate bits for this hcd */
-	struct phy phy;
-	const struct ohci_sunxi_cfg *cfg;
-};
-
-static fdt_addr_t last_ohci_addr = 0;
-
-static int ohci_usb_probe(struct udevice *dev)
-{
-	struct usb_bus_priv *bus_priv = dev_get_uclass_priv(dev);
-	struct ohci_sunxi_priv *priv = dev_get_priv(dev);
-	struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev);
-	int extra_ahb_gate_mask = 0;
-	u8 reg_mask = 0;
-	int phys, ret;
-
-	if ((fdt_addr_t)regs > last_ohci_addr)
-		last_ohci_addr = (fdt_addr_t)regs;
-
-	priv->cfg = (const struct ohci_sunxi_cfg *)dev_get_driver_data(dev);
-	priv->ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
-	if (IS_ERR(priv->ccm))
-		return PTR_ERR(priv->ccm);
-
-	priv->reset0_cfg = (void *)priv->ccm +
-				   priv->cfg->reset0_cfg_offset;
-
-	phys = dev_count_phandle_with_args(dev, "phys", "#phy-cells");
-	if (phys < 0) {
-		phys = 0;
-		goto no_phy;
-	}
-
-	ret = generic_phy_get_by_name(dev, "usb", &priv->phy);
-	if (ret) {
-		pr_err("failed to get %s usb PHY\n", dev->name);
-		return ret;
-	}
-
-	ret = generic_phy_init(&priv->phy);
-	if (ret) {
-		pr_err("failed to init %s USB PHY\n", dev->name);
-		return ret;
-	}
-
-	ret = generic_phy_power_on(&priv->phy);
-	if (ret) {
-		pr_err("failed to power on %s USB PHY\n", dev->name);
-		return ret;
-	}
-
-no_phy:
-	bus_priv->companion = true;
-
-	/*
-	 * This should go away once we've moved to the driver model for
-	 * clocks resp. phys.
-	 */
-	reg_mask = ((uintptr_t)regs - (SUNXI_USB1_BASE + 0x400)) / BASE_DIST;
-	priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_OHCI0;
-	extra_ahb_gate_mask = priv->cfg->extra_ahb_gate_mask;
-	priv->usb_gate_mask = CCM_USB_CTRL_OHCI0_CLK;
-	priv->ahb_gate_mask <<= reg_mask * AHB_CLK_DIST;
-	extra_ahb_gate_mask <<= reg_mask * AHB_CLK_DIST;
-	priv->usb_gate_mask <<= reg_mask;
-
-	setbits_le32(&priv->ccm->ahb_gate0,
-		     priv->ahb_gate_mask | extra_ahb_gate_mask);
-	setbits_le32(&priv->ccm->usb_clk_cfg,
-		     priv->usb_gate_mask | priv->cfg->extra_usb_gate_mask);
-	if (priv->cfg->has_reset)
-		setbits_le32(priv->reset0_cfg,
-			     priv->ahb_gate_mask | extra_ahb_gate_mask);
-
-	return ohci_register(dev, regs);
-}
-
-static int ohci_usb_remove(struct udevice *dev)
-{
-	struct ohci_sunxi_priv *priv = dev_get_priv(dev);
-	fdt_addr_t base_addr = devfdt_get_addr(dev);
-	int ret;
-
-	if (generic_phy_valid(&priv->phy)) {
-		ret = generic_phy_exit(&priv->phy);
-		if (ret) {
-			pr_err("failed to exit %s USB PHY\n", dev->name);
-			return ret;
-		}
-	}
-
-	ret = ohci_deregister(dev);
-	if (ret)
-		return ret;
-
-	if (priv->cfg->has_reset)
-		clrbits_le32(priv->reset0_cfg, priv->ahb_gate_mask);
-	/*
-	 * On the A64 CLK_USB_OHCI0 is the parent of CLK_USB_OHCI1, so
-	 * we have to wait with bringing down any clock until the last
-	 * OHCI controller is removed.
-	 */
-	if (!priv->cfg->extra_usb_gate_mask || base_addr == last_ohci_addr) {
-		u32 usb_gate_mask = priv->usb_gate_mask;
-
-		usb_gate_mask |= priv->cfg->extra_usb_gate_mask;
-		clrbits_le32(&priv->ccm->usb_clk_cfg, usb_gate_mask);
-	}
-
-	clrbits_le32(&priv->ccm->ahb_gate0, priv->ahb_gate_mask);
-
-	return 0;
-}
-
-static const struct ohci_sunxi_cfg sun4i_a10_cfg = {
-	.has_reset = false,
-};
-
-static const struct ohci_sunxi_cfg sun6i_a31_cfg = {
-	.has_reset = true,
-	.reset0_cfg_offset = SUN6I_AHB_RESET0_CFG_OFFSET,
-};
-
-static const struct ohci_sunxi_cfg sun8i_h3_cfg = {
-	.has_reset = true,
-	.extra_ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_EHCI0,
-	.reset0_cfg_offset = SUN6I_AHB_RESET0_CFG_OFFSET,
-};
-
-static const struct ohci_sunxi_cfg sun9i_a80_cfg = {
-	.has_reset = true,
-	.reset0_cfg_offset = SUN9I_AHB_RESET0_CFG_OFFSET,
-};
-
-static const struct ohci_sunxi_cfg sun50i_a64_cfg = {
-	.has_reset = true,
-	.extra_ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_EHCI0,
-	.extra_usb_gate_mask = CCM_USB_CTRL_OHCI0_CLK,
-	.reset0_cfg_offset = SUN6I_AHB_RESET0_CFG_OFFSET,
-};
-
-static const struct udevice_id ohci_usb_ids[] = {
-	{
-		.compatible = "allwinner,sun4i-a10-ohci",
-		.data = (ulong)&sun4i_a10_cfg,
-	},
-	{
-		.compatible = "allwinner,sun5i-a13-ohci",
-		.data = (ulong)&sun4i_a10_cfg,
-	},
-	{
-		.compatible = "allwinner,sun6i-a31-ohci",
-		.data = (ulong)&sun6i_a31_cfg,
-	},
-	{
-		.compatible = "allwinner,sun7i-a20-ohci",
-		.data = (ulong)&sun4i_a10_cfg,
-	},
-	{
-		.compatible = "allwinner,sun8i-a23-ohci",
-		.data = (ulong)&sun6i_a31_cfg,
-	},
-	{
-		.compatible = "allwinner,sun8i-a83t-ohci",
-		.data = (ulong)&sun6i_a31_cfg,
-	},
-	{
-		.compatible = "allwinner,sun8i-h3-ohci",
-		.data = (ulong)&sun8i_h3_cfg,
-	},
-	{
-		.compatible = "allwinner,sun9i-a80-ohci",
-		.data = (ulong)&sun9i_a80_cfg,
-	},
-	{
-		.compatible = "allwinner,sun50i-a64-ohci",
-		.data = (ulong)&sun50i_a64_cfg,
-	},
-	{ /* sentinel */ }
-};
-
-U_BOOT_DRIVER(usb_ohci) = {
-	.name	= "ohci_sunxi",
-	.id	= UCLASS_USB,
-	.of_match = ohci_usb_ids,
-	.probe = ohci_usb_probe,
-	.remove = ohci_usb_remove,
-	.ops	= &ohci_usb_ops,
-	.platdata_auto_alloc_size = sizeof(struct usb_platdata),
-	.priv_auto_alloc_size = sizeof(struct ohci_sunxi_priv),
-	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
-};
diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c
index f542a18..45eecfe 100644
--- a/drivers/usb/musb-new/sunxi.c
+++ b/drivers/usb/musb-new/sunxi.c
@@ -16,9 +16,11 @@
  * This file is part of the Inventra Controller Driver for Linux.
  */
 #include <common.h>
+#include <clk.h>
 #include <dm.h>
 #include <generic-phy.h>
 #include <phy-sun4i-usb.h>
+#include <reset.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/gpio.h>
@@ -80,16 +82,12 @@
 
 struct sunxi_musb_config {
 	struct musb_hdrc_config *config;
-	bool has_reset;
-	u8 rst_bit;
-	u8 clkgate_bit;
-	u32 off_reset0;
 };
 
 struct sunxi_glue {
 	struct musb_host_data mdata;
-	struct sunxi_ccm_reg *ccm;
-	u32 *reg_reset0;
+	struct clk clk;
+	struct reset_ctl rst;
 	struct sunxi_musb_config *cfg;
 	struct device dev;
 	struct phy phy;
@@ -296,25 +294,28 @@
 
 	pr_debug("%s():\n", __func__);
 
-	ret = generic_phy_init(&glue->phy);
+	ret = clk_enable(&glue->clk);
 	if (ret) {
-		pr_err("failed to init USB PHY\n");
+		dev_err(dev, "failed to enable clock\n");
 		return ret;
 	}
 
+	if (reset_valid(&glue->rst)) {
+		ret = reset_deassert(&glue->rst);
+		if (ret) {
+			dev_err(dev, "failed to deassert reset\n");
+			goto err_clk;
+		}
+	}
+
+	ret = generic_phy_init(&glue->phy);
+	if (ret) {
+		dev_err(dev, "failed to init USB PHY\n");
+		goto err_rst;
+	}
+
 	musb->isr = sunxi_musb_interrupt;
 
-	setbits_le32(&glue->ccm->ahb_gate0, BIT(AHB_GATE_OFFSET_USB0));
-	if (glue->cfg->clkgate_bit)
-		setbits_le32(&glue->ccm->ahb_gate0,
-			     BIT(glue->cfg->clkgate_bit));
-
-	if (glue->cfg->has_reset)
-		setbits_le32(glue->reg_reset0, BIT(AHB_GATE_OFFSET_USB0));
-
-	if (glue->cfg->rst_bit)
-		setbits_le32(glue->reg_reset0, BIT(glue->cfg->rst_bit));
-
 	USBC_ConfigFIFO_Base();
 	USBC_EnableDpDmPullUp(musb->mregs);
 	USBC_EnableIdPullUp(musb->mregs);
@@ -329,6 +330,13 @@
 	USBC_ForceVbusValidToHigh(musb->mregs);
 
 	return 0;
+
+err_rst:
+	if (reset_valid(&glue->rst))
+		reset_assert(&glue->rst);
+err_clk:
+	clk_disable(&glue->clk);
+	return ret;
 }
 
 static int sunxi_musb_exit(struct musb *musb)
@@ -344,16 +352,9 @@
 		}
 	}
 
-	if (glue->cfg->has_reset)
-		clrbits_le32(glue->reg_reset0, BIT(AHB_GATE_OFFSET_USB0));
-
-	if (glue->cfg->rst_bit)
-		clrbits_le32(glue->reg_reset0, BIT(glue->cfg->rst_bit));
-
-	clrbits_le32(&glue->ccm->ahb_gate0, BIT(AHB_GATE_OFFSET_USB0));
-	if (glue->cfg->clkgate_bit)
-		clrbits_le32(&glue->ccm->ahb_gate0,
-			     BIT(glue->cfg->clkgate_bit));
+	if (reset_valid(&glue->rst))
+		reset_assert(&glue->rst);
+	clk_disable(&glue->clk);
 
 	return 0;
 }
@@ -450,11 +451,17 @@
 	if (!glue->cfg)
 		return -EINVAL;
 
-	glue->ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
-	if (IS_ERR(glue->ccm))
-		return PTR_ERR(glue->ccm);
+	ret = clk_get_by_index(dev, 0, &glue->clk);
+	if (ret) {
+		dev_err(dev, "failed to get clock\n");
+		return ret;
+	}
 
-	glue->reg_reset0 = (void *)glue->ccm + glue->cfg->off_reset0;
+	ret = reset_get_by_index(dev, 0, &glue->rst);
+	if (ret && ret != -ENOENT) {
+		dev_err(dev, "failed to get reset\n");
+		return ret;
+	}
 
 	ret = generic_phy_get_by_name(dev, "usb", &glue->phy);
 	if (ret) {
@@ -462,7 +469,6 @@
 		return ret;
 	}
 
-
 	memset(&pdata, 0, sizeof(pdata));
 	pdata.power = 250;
 	pdata.platform_ops = &sunxi_musb_ops;
@@ -505,21 +511,14 @@
 
 static const struct sunxi_musb_config sun4i_a10_cfg = {
 	.config = &musb_config,
-	.has_reset = false,
 };
 
 static const struct sunxi_musb_config sun6i_a31_cfg = {
 	.config = &musb_config,
-	.has_reset = true,
-	.off_reset0 = OFF_SUN6I_AHB_RESET0,
 };
 
 static const struct sunxi_musb_config sun8i_h3_cfg = {
 	.config = &musb_config_h3,
-	.has_reset = true,
-	.rst_bit = 23,
-	.clkgate_bit = 23,
-	.off_reset0 = OFF_SUN6I_AHB_RESET0,
 };
 
 static const struct udevice_id sunxi_musb_ids[] = {
diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h
index af079a7..6033760 100644
--- a/include/configs/sun4i.h
+++ b/include/configs/sun4i.h
@@ -11,10 +11,6 @@
  * A10 specific configuration
  */
 
-#ifdef CONFIG_USB_EHCI_HCD
-#define CONFIG_USB_EHCI_SUNXI
-#endif
-
 /*
  * Include common sunxi configuration where most the settings are
  */
diff --git a/include/configs/sun50i.h b/include/configs/sun50i.h
index 2d73c75..e050a52 100644
--- a/include/configs/sun50i.h
+++ b/include/configs/sun50i.h
@@ -10,11 +10,6 @@
  * A64 specific configuration
  */
 
-#ifdef CONFIG_USB_EHCI_HCD
-#define CONFIG_USB_EHCI_SUNXI
-#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
-#endif
-
 #ifndef CONFIG_MACH_SUN50I_H6
 #define GICD_BASE		0x1c81000
 #define GICC_BASE		0x1c82000
diff --git a/include/configs/sun5i.h b/include/configs/sun5i.h
index c3692ca..ee42af8 100644
--- a/include/configs/sun5i.h
+++ b/include/configs/sun5i.h
@@ -11,10 +11,6 @@
  * High Level Configuration Options
  */
 
-#ifdef CONFIG_USB_EHCI_HCD
-#define CONFIG_USB_EHCI_SUNXI
-#endif
-
 /*
  * Include common sunxi configuration where most the settings are
  */
diff --git a/include/configs/sun6i.h b/include/configs/sun6i.h
index 1523684..1e490da 100644
--- a/include/configs/sun6i.h
+++ b/include/configs/sun6i.h
@@ -14,10 +14,6 @@
  * A31 specific configuration
  */
 
-#ifdef CONFIG_USB_EHCI_HCD
-#define CONFIG_USB_EHCI_SUNXI
-#endif
-
 #define CONFIG_ARMV7_SECURE_BASE	SUNXI_SRAM_B_BASE
 #define CONFIG_ARMV7_SECURE_MAX_SIZE    (64 * 1024) /* 64 KB */
 
diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h
index bb8f217..d2fd586 100644
--- a/include/configs/sun7i.h
+++ b/include/configs/sun7i.h
@@ -12,10 +12,6 @@
  * A20 specific configuration
  */
 
-#ifdef CONFIG_USB_EHCI_HCD
-#define CONFIG_USB_EHCI_SUNXI
-#endif
-
 #define CONFIG_ARMV7_SECURE_BASE	SUNXI_SRAM_B_BASE
 #define CONFIG_ARMV7_SECURE_MAX_SIZE	(64 * 1024) /* 64 KB */
 
diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h
index 7dc8693..9b4675e 100644
--- a/include/configs/sun8i.h
+++ b/include/configs/sun8i.h
@@ -12,10 +12,6 @@
  * A23 specific configuration
  */
 
-#ifdef CONFIG_USB_EHCI_HCD
-#define CONFIG_USB_EHCI_SUNXI
-#endif
-
 /*
  * Include common sunxi configuration where most the settings are
  */
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 9819d99..ed0cfc2 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -295,7 +295,6 @@
 
 #ifdef CONFIG_USB_EHCI_HCD
 #define CONFIG_USB_OHCI_NEW
-#define CONFIG_USB_OHCI_SUNXI
 #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 1
 #endif
 
diff --git a/include/dt-bindings/clock/sun50i-a64-ccu.h b/include/dt-bindings/clock/sun50i-a64-ccu.h
index 370c0a0..d66432c 100644
--- a/include/dt-bindings/clock/sun50i-a64-ccu.h
+++ b/include/dt-bindings/clock/sun50i-a64-ccu.h
@@ -43,6 +43,8 @@
 #ifndef _DT_BINDINGS_CLK_SUN50I_A64_H_
 #define _DT_BINDINGS_CLK_SUN50I_A64_H_
 
+#define CLK_PLL_PERIPH0		11
+
 #define CLK_BUS_MIPI_DSI	28
 #define CLK_BUS_CE		29
 #define CLK_BUS_DMA		30
diff --git a/include/dt-bindings/clock/sun9i-a80-ccu.h b/include/dt-bindings/clock/sun9i-a80-ccu.h
new file mode 100644
index 0000000..6ea1492
--- /dev/null
+++ b/include/dt-bindings/clock/sun9i-a80-ccu.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
+ *
+ * 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.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_SUN9I_A80_CCU_H_
+#define _DT_BINDINGS_CLOCK_SUN9I_A80_CCU_H_
+
+#define CLK_PLL_AUDIO		2
+#define CLK_PLL_PERIPH0		3
+
+#define CLK_C0CPUX		12
+#define CLK_C1CPUX		13
+
+#define CLK_OUT_A		27
+#define CLK_OUT_B		28
+
+#define CLK_NAND0_0		29
+#define CLK_NAND0_1		30
+#define CLK_NAND1_0		31
+#define CLK_NAND1_1		32
+#define CLK_MMC0		33
+#define CLK_MMC0_SAMPLE		34
+#define CLK_MMC0_OUTPUT		35
+#define CLK_MMC1		36
+#define CLK_MMC1_SAMPLE		37
+#define CLK_MMC1_OUTPUT		38
+#define CLK_MMC2		39
+#define CLK_MMC2_SAMPLE		40
+#define CLK_MMC2_OUTPUT		41
+#define CLK_MMC3		42
+#define CLK_MMC3_SAMPLE		43
+#define CLK_MMC3_OUTPUT		44
+#define CLK_TS			45
+#define CLK_SS			46
+#define CLK_SPI0		47
+#define CLK_SPI1		48
+#define CLK_SPI2		49
+#define CLK_SPI3		50
+#define CLK_I2S0		51
+#define CLK_I2S1		52
+#define CLK_SPDIF		53
+#define CLK_SDRAM		54
+#define CLK_DE			55
+#define CLK_EDP			56
+#define CLK_MP			57
+#define CLK_LCD0		58
+#define CLK_LCD1		59
+#define CLK_MIPI_DSI0		60
+#define CLK_MIPI_DSI1		61
+#define CLK_HDMI		62
+#define CLK_HDMI_SLOW		63
+#define CLK_MIPI_CSI		64
+#define CLK_CSI_ISP		65
+#define CLK_CSI_MISC		66
+#define CLK_CSI0_MCLK		67
+#define CLK_CSI1_MCLK		68
+#define CLK_FD			69
+#define CLK_VE			70
+#define CLK_AVS			71
+#define CLK_GPU_CORE		72
+#define CLK_GPU_MEMORY		73
+#define CLK_GPU_AXI		74
+#define CLK_SATA		75
+#define CLK_AC97		76
+#define CLK_MIPI_HSI		77
+#define CLK_GPADC		78
+#define CLK_CIR_TX		79
+
+#define CLK_BUS_FD		80
+#define CLK_BUS_VE		81
+#define CLK_BUS_GPU_CTRL	82
+#define CLK_BUS_SS		83
+#define CLK_BUS_MMC		84
+#define CLK_BUS_NAND0		85
+#define CLK_BUS_NAND1		86
+#define CLK_BUS_SDRAM		87
+#define CLK_BUS_MIPI_HSI	88
+#define CLK_BUS_SATA		89
+#define CLK_BUS_TS		90
+#define CLK_BUS_SPI0		91
+#define CLK_BUS_SPI1		92
+#define CLK_BUS_SPI2		93
+#define CLK_BUS_SPI3		94
+
+#define CLK_BUS_OTG		95
+#define CLK_BUS_USB		96
+#define CLK_BUS_GMAC		97
+#define CLK_BUS_MSGBOX		98
+#define CLK_BUS_SPINLOCK	99
+#define CLK_BUS_HSTIMER		100
+#define CLK_BUS_DMA		101
+
+#define CLK_BUS_LCD0		102
+#define CLK_BUS_LCD1		103
+#define CLK_BUS_EDP		104
+#define CLK_BUS_CSI		105
+#define CLK_BUS_HDMI		106
+#define CLK_BUS_DE		107
+#define CLK_BUS_MP		108
+#define CLK_BUS_MIPI_DSI	109
+
+#define CLK_BUS_SPDIF		110
+#define CLK_BUS_PIO		111
+#define CLK_BUS_AC97		112
+#define CLK_BUS_I2S0		113
+#define CLK_BUS_I2S1		114
+#define CLK_BUS_LRADC		115
+#define CLK_BUS_GPADC		116
+#define CLK_BUS_TWD		117
+#define CLK_BUS_CIR_TX		118
+
+#define CLK_BUS_I2C0		119
+#define CLK_BUS_I2C1		120
+#define CLK_BUS_I2C2		121
+#define CLK_BUS_I2C3		122
+#define CLK_BUS_I2C4		123
+#define CLK_BUS_UART0		124
+#define CLK_BUS_UART1		125
+#define CLK_BUS_UART2		126
+#define CLK_BUS_UART3		127
+#define CLK_BUS_UART4		128
+#define CLK_BUS_UART5		129
+
+#endif /* _DT_BINDINGS_CLOCK_SUN9I_A80_CCU_H_ */
diff --git a/include/dt-bindings/clock/sun9i-a80-de.h b/include/dt-bindings/clock/sun9i-a80-de.h
new file mode 100644
index 0000000..3dad6c3
--- /dev/null
+++ b/include/dt-bindings/clock/sun9i-a80-de.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
+ *
+ * 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.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_SUN9I_A80_DE_H_
+#define _DT_BINDINGS_CLOCK_SUN9I_A80_DE_H_
+
+#define CLK_FE0			0
+#define CLK_FE1			1
+#define CLK_FE2			2
+#define CLK_IEP_DEU0		3
+#define CLK_IEP_DEU1		4
+#define CLK_BE0			5
+#define CLK_BE1			6
+#define CLK_BE2			7
+#define CLK_IEP_DRC0		8
+#define CLK_IEP_DRC1		9
+#define CLK_MERGE		10
+
+#define CLK_DRAM_FE0		11
+#define CLK_DRAM_FE1		12
+#define CLK_DRAM_FE2		13
+#define CLK_DRAM_DEU0		14
+#define CLK_DRAM_DEU1		15
+#define CLK_DRAM_BE0		16
+#define CLK_DRAM_BE1		17
+#define CLK_DRAM_BE2		18
+#define CLK_DRAM_DRC0		19
+#define CLK_DRAM_DRC1		20
+
+#define CLK_BUS_FE0		21
+#define CLK_BUS_FE1		22
+#define CLK_BUS_FE2		23
+#define CLK_BUS_DEU0		24
+#define CLK_BUS_DEU1		25
+#define CLK_BUS_BE0		26
+#define CLK_BUS_BE1		27
+#define CLK_BUS_BE2		28
+#define CLK_BUS_DRC0		29
+#define CLK_BUS_DRC1		30
+
+#endif /* _DT_BINDINGS_CLOCK_SUN9I_A80_DE_H_ */
diff --git a/include/dt-bindings/clock/sun9i-a80-usb.h b/include/dt-bindings/clock/sun9i-a80-usb.h
new file mode 100644
index 0000000..783a60d
--- /dev/null
+++ b/include/dt-bindings/clock/sun9i-a80-usb.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
+ *
+ * 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.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_SUN9I_A80_USB_H_
+#define _DT_BINDINGS_CLOCK_SUN9I_A80_USB_H_
+
+#define CLK_BUS_HCI0	0
+#define CLK_USB_OHCI0	1
+#define CLK_BUS_HCI1	2
+#define CLK_BUS_HCI2	3
+#define CLK_USB_OHCI2	4
+
+#define CLK_USB0_PHY	5
+#define CLK_USB1_HSIC	6
+#define CLK_USB1_PHY	7
+#define CLK_USB2_HSIC	8
+#define CLK_USB2_PHY	9
+#define CLK_USB_HSIC	10
+
+#endif /* _DT_BINDINGS_CLOCK_SUN9I_A80_USB_H_ */
diff --git a/include/dt-bindings/reset/sun9i-a80-ccu.h b/include/dt-bindings/reset/sun9i-a80-ccu.h
new file mode 100644
index 0000000..4b8df4b
--- /dev/null
+++ b/include/dt-bindings/reset/sun9i-a80-ccu.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
+ *
+ * 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.
+ */
+
+#ifndef _DT_BINDINGS_RESET_SUN9I_A80_CCU_H_
+#define _DT_BINDINGS_RESET_SUN9I_A80_CCU_H_
+
+#define RST_BUS_FD		0
+#define RST_BUS_VE		1
+#define RST_BUS_GPU_CTRL	2
+#define RST_BUS_SS		3
+#define RST_BUS_MMC		4
+#define RST_BUS_NAND0		5
+#define RST_BUS_NAND1		6
+#define RST_BUS_SDRAM		7
+#define RST_BUS_SATA		8
+#define RST_BUS_TS		9
+#define RST_BUS_SPI0		10
+#define RST_BUS_SPI1		11
+#define RST_BUS_SPI2		12
+#define RST_BUS_SPI3		13
+
+#define RST_BUS_OTG		14
+#define RST_BUS_OTG_PHY		15
+#define RST_BUS_MIPI_HSI	16
+#define RST_BUS_GMAC		17
+#define RST_BUS_MSGBOX		18
+#define RST_BUS_SPINLOCK	19
+#define RST_BUS_HSTIMER		20
+#define RST_BUS_DMA		21
+
+#define RST_BUS_LCD0		22
+#define RST_BUS_LCD1		23
+#define RST_BUS_EDP		24
+#define RST_BUS_LVDS		25
+#define RST_BUS_CSI		26
+#define RST_BUS_HDMI0		27
+#define RST_BUS_HDMI1		28
+#define RST_BUS_DE		29
+#define RST_BUS_MP		30
+#define RST_BUS_GPU		31
+#define RST_BUS_MIPI_DSI	32
+
+#define RST_BUS_SPDIF		33
+#define RST_BUS_AC97		34
+#define RST_BUS_I2S0		35
+#define RST_BUS_I2S1		36
+#define RST_BUS_LRADC		37
+#define RST_BUS_GPADC		38
+#define RST_BUS_CIR_TX		39
+
+#define RST_BUS_I2C0		40
+#define RST_BUS_I2C1		41
+#define RST_BUS_I2C2		42
+#define RST_BUS_I2C3		43
+#define RST_BUS_I2C4		44
+#define RST_BUS_UART0		45
+#define RST_BUS_UART1		46
+#define RST_BUS_UART2		47
+#define RST_BUS_UART3		48
+#define RST_BUS_UART4		49
+#define RST_BUS_UART5		50
+
+#endif /* _DT_BINDINGS_RESET_SUN9I_A80_CCU_H_ */
diff --git a/include/dt-bindings/reset/sun9i-a80-de.h b/include/dt-bindings/reset/sun9i-a80-de.h
new file mode 100644
index 0000000..2050727
--- /dev/null
+++ b/include/dt-bindings/reset/sun9i-a80-de.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
+ *
+ * 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.
+ */
+
+#ifndef _DT_BINDINGS_RESET_SUN9I_A80_DE_H_
+#define _DT_BINDINGS_RESET_SUN9I_A80_DE_H_
+
+#define RST_FE0		0
+#define RST_FE1		1
+#define RST_FE2		2
+#define RST_DEU0	3
+#define RST_DEU1	4
+#define RST_BE0		5
+#define RST_BE1		6
+#define RST_BE2		7
+#define RST_DRC0	8
+#define RST_DRC1	9
+#define RST_MERGE	10
+
+#endif /* _DT_BINDINGS_RESET_SUN9I_A80_DE_H_ */
diff --git a/include/dt-bindings/reset/sun9i-a80-usb.h b/include/dt-bindings/reset/sun9i-a80-usb.h
new file mode 100644
index 0000000..ee49286
--- /dev/null
+++ b/include/dt-bindings/reset/sun9i-a80-usb.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
+ *
+ * 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.
+ */
+
+#ifndef _DT_BINDINGS_RESET_SUN9I_A80_USB_H_
+#define _DT_BINDINGS_RESET_SUN9I_A80_USB_H_
+
+#define RST_USB0_HCI	0
+#define RST_USB1_HCI	1
+#define RST_USB2_HCI	2
+
+#define RST_USB0_PHY	3
+#define RST_USB1_HSIC	4
+#define RST_USB1_PHY	5
+#define RST_USB2_HSIC	6
+#define RST_USB2_PHY	7
+
+#endif /* _DT_BINDINGS_RESET_SUN9I_A80_USB_H_ */
diff --git a/include/env_callback.h b/include/env_callback.h
index 3c44ff5..507a52e 100644
--- a/include/env_callback.h
+++ b/include/env_callback.h
@@ -32,10 +32,8 @@
 
 #ifdef CONFIG_REGEX
 #define ENV_DOT_ESCAPE "\\"
-#define ETHADDR_WILDCARD "\\d?"
 #else
 #define ENV_DOT_ESCAPE
-#define ETHADDR_WILDCARD
 #endif
 
 #ifdef CONFIG_CMD_DNS
diff --git a/include/env_flags.h b/include/env_flags.h
index cc2c34f..23744e3 100644
--- a/include/env_flags.h
+++ b/include/env_flags.h
@@ -38,7 +38,7 @@
 
 #ifdef CONFIG_CMD_NET
 #ifdef CONFIG_REGEX
-#define ETHADDR_WILDCARD "\\d?"
+#define ETHADDR_WILDCARD "\\d*"
 #else
 #define ETHADDR_WILDCARD
 #endif
diff --git a/include/net.h b/include/net.h
index 51c099d..dd52ed3 100644
--- a/include/net.h
+++ b/include/net.h
@@ -140,9 +140,7 @@
 	int (*recv)(struct udevice *dev, int flags, uchar **packetp);
 	int (*free_pkt)(struct udevice *dev, uchar *packet, int length);
 	void (*stop)(struct udevice *dev);
-#ifdef CONFIG_MCAST_TFTP
 	int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join);
-#endif
 	int (*write_hwaddr)(struct udevice *dev);
 	int (*read_rom_hwaddr)(struct udevice *dev);
 };
@@ -175,9 +173,7 @@
 	int (*send)(struct eth_device *, void *packet, int length);
 	int (*recv)(struct eth_device *);
 	void (*halt)(struct eth_device *);
-#ifdef CONFIG_MCAST_TFTP
-	int (*mcast)(struct eth_device *, const u8 *enetaddr, u8 set);
-#endif
+	int (*mcast)(struct eth_device *, const u8 *enetaddr, int join);
 	int (*write_hwaddr)(struct eth_device *);
 	struct eth_device *next;
 	int index;
@@ -286,12 +282,7 @@
 int eth_rx(void);			/* Check for received packets */
 void eth_halt(void);			/* stop SCC */
 const char *eth_get_name(void);		/* get name of current device */
-
-#ifdef CONFIG_MCAST_TFTP
 int eth_mcast_join(struct in_addr mcast_addr, int join);
-u32 ether_crc(size_t len, unsigned char const *p);
-#endif
-
 
 /**********************************************************************/
 /*
@@ -578,10 +569,6 @@
 extern int net_ntp_time_offset;			/* offset time from UTC */
 #endif
 
-#if defined(CONFIG_MCAST_TFTP)
-extern struct in_addr net_mcast_addr;
-#endif
-
 /* Initialize the network adapter */
 void net_init(void);
 int net_loop(enum proto_t);
diff --git a/include/phy.h b/include/phy.h
index b86fdfb..f23ca63f 100644
--- a/include/phy.h
+++ b/include/phy.h
@@ -138,6 +138,7 @@
 	int pause;
 	int asym_pause;
 	u32 phy_id;
+	bool is_c45;
 	u32 flags;
 };
 
diff --git a/include/reset.h b/include/reset.h
index bc495a9..65aa7a4 100644
--- a/include/reset.h
+++ b/include/reset.h
@@ -306,4 +306,15 @@
 }
 #endif
 
+/**
+ * reset_valid() - check if reset is valid
+ *
+ * @reset_ctl:		the reset to check
+ * @return TRUE if valid, or FALSE
+ */
+static inline bool reset_valid(struct reset_ctl *reset_ctl)
+{
+	return !!reset_ctl->dev;
+}
+
 #endif
diff --git a/net/eth-uclass.c b/net/eth-uclass.c
index 91d861b..2ef20df 100644
--- a/net/eth-uclass.c
+++ b/net/eth-uclass.c
@@ -476,10 +476,8 @@
 			ops->free_pkt += gd->reloc_off;
 		if (ops->stop)
 			ops->stop += gd->reloc_off;
-#ifdef CONFIG_MCAST_TFTP
 		if (ops->mcast)
 			ops->mcast += gd->reloc_off;
-#endif
 		if (ops->write_hwaddr)
 			ops->write_hwaddr += gd->reloc_off;
 		if (ops->read_rom_hwaddr)
diff --git a/net/eth_legacy.c b/net/eth_legacy.c
index 2a9caa3..e250a43 100644
--- a/net/eth_legacy.c
+++ b/net/eth_legacy.c
@@ -291,7 +291,6 @@
 	return num_devices;
 }
 
-#ifdef CONFIG_MCAST_TFTP
 /* Multicast.
  * mcast_addr: multicast ipaddr from which multicast Mac is made
  * join: 1=join, 0=leave.
@@ -310,33 +309,6 @@
 	return eth_current->mcast(eth_current, mcast_mac, join);
 }
 
-/* the 'way' for ethernet-CRC-32. Spliced in from Linux lib/crc32.c
- * and this is the ethernet-crc method needed for TSEC -- and perhaps
- * some other adapter -- hash tables
- */
-#define CRCPOLY_LE 0xedb88320
-u32 ether_crc(size_t len, unsigned char const *p)
-{
-	int i;
-	u32 crc;
-	crc = ~0;
-	while (len--) {
-		crc ^= *p++;
-		for (i = 0; i < 8; i++)
-			crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
-	}
-	/* an reverse the bits, cuz of way they arrive -- last-first */
-	crc = (crc >> 16) | (crc << 16);
-	crc = (crc >> 8 & 0x00ff00ff) | (crc << 8 & 0xff00ff00);
-	crc = (crc >> 4 & 0x0f0f0f0f) | (crc << 4 & 0xf0f0f0f0);
-	crc = (crc >> 2 & 0x33333333) | (crc << 2 & 0xcccccccc);
-	crc = (crc >> 1 & 0x55555555) | (crc << 1 & 0xaaaaaaaa);
-	return crc;
-}
-
-#endif
-
-
 int eth_init(void)
 {
 	struct eth_device *old_current;
diff --git a/net/net.c b/net/net.c
index a5a216c..58b0417 100644
--- a/net/net.c
+++ b/net/net.c
@@ -131,10 +131,6 @@
 struct in_addr net_dns_server2;
 #endif
 
-#ifdef CONFIG_MCAST_TFTP	/* Multicast TFTP */
-struct in_addr net_mcast_addr;
-#endif
-
 /** END OF BOOTP EXTENTIONS **/
 
 /* Our ethernet address */
@@ -657,6 +653,7 @@
 			/* Invalidate the last protocol */
 			eth_set_last_protocol(BOOTP);
 			debug_cond(DEBUG_INT_STATE, "--- net_loop Fail!\n");
+			ret = -ENONET;
 			goto done;
 
 		case NETLOOP_CONTINUE:
@@ -1215,9 +1212,6 @@
 		dst_ip = net_read_ip(&ip->ip_dst);
 		if (net_ip.s_addr && dst_ip.s_addr != net_ip.s_addr &&
 		    dst_ip.s_addr != 0xFFFFFFFF) {
-#ifdef CONFIG_MCAST_TFTP
-			if (net_mcast_addr != dst_ip)
-#endif
 				return;
 		}
 		/* Read source IP address for later use */
diff --git a/net/tftp.c b/net/tftp.c
index a9335b1b7..8fab6d2 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -140,36 +140,6 @@
 static unsigned short tftp_block_size = TFTP_BLOCK_SIZE;
 static unsigned short tftp_block_size_option = TFTP_MTU_BLOCKSIZE;
 
-#ifdef CONFIG_MCAST_TFTP
-#include <malloc.h>
-#define MTFTP_BITMAPSIZE	0x1000
-static unsigned *tftp_mcast_bitmap;
-static int tftp_mcast_prev_hole;
-static int tftp_mcast_bitmap_size = MTFTP_BITMAPSIZE;
-static int tftp_mcast_disabled;
-static int tftp_mcast_master_client;
-static int tftp_mcast_active;
-static int tftp_mcast_port;
-/* can get 'last' block before done..*/
-static ulong tftp_mcast_ending_block;
-
-static void parse_multicast_oack(char *pkt, int len);
-
-static void mcast_cleanup(void)
-{
-	if (net_mcast_addr)
-		eth_mcast_join(net_mcast_addr, 0);
-	if (tftp_mcast_bitmap)
-		free(tftp_mcast_bitmap);
-	tftp_mcast_bitmap = NULL;
-	net_mcast_addr.s_addr = 0;
-	tftp_mcast_active = 0;
-	tftp_mcast_port = 0;
-	tftp_mcast_ending_block = -1;
-}
-
-#endif	/* CONFIG_MCAST_TFTP */
-
 static inline int store_block(int block, uchar *src, unsigned int len)
 {
 	ulong offset = block * tftp_block_size + tftp_block_wrap_offset;
@@ -211,10 +181,6 @@
 		memcpy(ptr, src, len);
 		unmap_sysmem(ptr);
 	}
-#ifdef CONFIG_MCAST_TFTP
-	if (tftp_mcast_active)
-		ext2_set_bit(block, tftp_mcast_bitmap);
-#endif
 
 	if (net_boot_file_size < newsize)
 		net_boot_file_size = newsize;
@@ -292,9 +258,6 @@
 static void restart(const char *msg)
 {
 	printf("\n%s; starting again\n", msg);
-#ifdef CONFIG_MCAST_TFTP
-	mcast_cleanup();
-#endif
 	net_start_again();
 }
 
@@ -349,12 +312,6 @@
 	int len = 0;
 	ushort *s;
 
-#ifdef CONFIG_MCAST_TFTP
-	/* Multicast TFTP.. non-MasterClients do not ACK data. */
-	if (tftp_mcast_active && tftp_state == STATE_DATA &&
-	    tftp_mcast_master_client == 0)
-		return;
-#endif
 	/*
 	 *	We will always be sending some sort of packet, so
 	 *	cobble together the packet headers now.
@@ -389,30 +346,10 @@
 		/* try for more effic. blk size */
 		pkt += sprintf((char *)pkt, "blksize%c%d%c",
 				0, tftp_block_size_option, 0);
-#ifdef CONFIG_MCAST_TFTP
-		/* Check all preconditions before even trying the option */
-		if (!tftp_mcast_disabled) {
-			tftp_mcast_bitmap = malloc(tftp_mcast_bitmap_size);
-			if (tftp_mcast_bitmap && eth_get_dev()->mcast) {
-				free(tftp_mcast_bitmap);
-				tftp_mcast_bitmap = NULL;
-				pkt += sprintf((char *)pkt, "multicast%c%c",
-					0, 0);
-			}
-		}
-#endif /* CONFIG_MCAST_TFTP */
 		len = pkt - xp;
 		break;
 
 	case STATE_OACK:
-#ifdef CONFIG_MCAST_TFTP
-		/* My turn!  Start at where I need blocks I missed. */
-		if (tftp_mcast_active)
-			tftp_cur_block = ext2_find_next_zero_bit(
-				tftp_mcast_bitmap,
-				tftp_mcast_bitmap_size * 8, 0);
-		/* fall through */
-#endif
 
 	case STATE_RECV_WRQ:
 	case STATE_DATA:
@@ -482,10 +419,6 @@
 	int i;
 
 	if (dest != tftp_our_port) {
-#ifdef CONFIG_MCAST_TFTP
-		if (tftp_mcast_active &&
-		    (!tftp_mcast_port || dest != tftp_mcast_port))
-#endif
 			return;
 	}
 	if (tftp_state != STATE_SEND_RRQ && src != tftp_remote_port &&
@@ -566,12 +499,6 @@
 			}
 #endif
 		}
-#ifdef CONFIG_MCAST_TFTP
-		parse_multicast_oack((char *)pkt, len - 1);
-		if ((tftp_mcast_active) && (!tftp_mcast_master_client))
-			tftp_state = STATE_DATA;	/* passive.. */
-		else
-#endif
 #ifdef CONFIG_CMD_TFTPPUT
 		if (tftp_put_active) {
 			/* Get ready to send the first block */
@@ -599,11 +526,6 @@
 			tftp_remote_port = src;
 			new_transfer();
 
-#ifdef CONFIG_MCAST_TFTP
-			if (tftp_mcast_active) { /* start!=1 common if mcast */
-				tftp_prev_block = tftp_cur_block - 1;
-			} else
-#endif
 			if (tftp_cur_block != 1) {	/* Assertion */
 				puts("\nTFTP error: ");
 				printf("First block is not block 1 (%ld)\n",
@@ -633,44 +555,8 @@
 		 *	Acknowledge the block just received, which will prompt
 		 *	the remote for the next one.
 		 */
-#ifdef CONFIG_MCAST_TFTP
-		/* if I am the MasterClient, actively calculate what my next
-		 * needed block is; else I'm passive; not ACKING
-		 */
-		if (tftp_mcast_active) {
-			if (len < tftp_block_size)  {
-				tftp_mcast_ending_block = tftp_cur_block;
-			} else if (tftp_mcast_master_client) {
-				tftp_mcast_prev_hole = ext2_find_next_zero_bit(
-					tftp_mcast_bitmap,
-					tftp_mcast_bitmap_size * 8,
-					tftp_mcast_prev_hole);
-				tftp_cur_block = tftp_mcast_prev_hole;
-				if (tftp_cur_block >
-				    ((tftp_mcast_bitmap_size * 8) - 1)) {
-					debug("tftpfile too big\n");
-					/* try to double it and retry */
-					tftp_mcast_bitmap_size <<= 1;
-					mcast_cleanup();
-					net_start_again();
-					return;
-				}
-				tftp_prev_block = tftp_cur_block;
-			}
-		}
-#endif
 		tftp_send();
 
-#ifdef CONFIG_MCAST_TFTP
-		if (tftp_mcast_active) {
-			if (tftp_mcast_master_client &&
-			    (tftp_cur_block >= tftp_mcast_ending_block)) {
-				puts("\nMulticast tftp done\n");
-				mcast_cleanup();
-				net_set_state(NETLOOP_SUCCESS);
-			}
-		} else
-#endif
 		if (len < tftp_block_size)
 			tftp_complete();
 		break;
@@ -693,9 +579,6 @@
 		case TFTP_ERR_FILE_ALREADY_EXISTS:
 		default:
 			puts("Starting again\n\n");
-#ifdef CONFIG_MCAST_TFTP
-			mcast_cleanup();
-#endif
 			net_start_again();
 			break;
 		}
@@ -873,9 +756,6 @@
 	memset(net_server_ethaddr, 0, 6);
 	/* Revert tftp_block_size to dflt */
 	tftp_block_size = TFTP_BLOCK_SIZE;
-#ifdef CONFIG_MCAST_TFTP
-	mcast_cleanup();
-#endif
 #ifdef CONFIG_TFTP_TSIZE
 	tftp_tsize = 0;
 	tftp_tsize_num_hash = 0;
@@ -924,102 +804,3 @@
 }
 #endif /* CONFIG_CMD_TFTPSRV */
 
-#ifdef CONFIG_MCAST_TFTP
-/*
- * Credits: atftp project.
- */
-
-/*
- * Pick up BcastAddr, Port, and whether I am [now] the master-client.
- * Frame:
- *    +-------+-----------+---+-------~~-------+---+
- *    |  opc  | multicast | 0 | addr, port, mc | 0 |
- *    +-------+-----------+---+-------~~-------+---+
- * The multicast addr/port becomes what I listen to, and if 'mc' is '1' then
- * I am the new master-client so must send ACKs to DataBlocks.  If I am not
- * master-client, I'm a passive client, gathering what DataBlocks I may and
- * making note of which ones I got in my bitmask.
- * In theory, I never go from master->passive..
- * .. this comes in with pkt already pointing just past opc
- */
-static void parse_multicast_oack(char *pkt, int len)
-{
-	int i;
-	struct in_addr addr;
-	char *mc_adr;
-	char *port;
-	char *mc;
-
-	mc_adr = NULL;
-	port = NULL;
-	mc = NULL;
-	/* march along looking for 'multicast\0', which has to start at least
-	 * 14 bytes back from the end.
-	 */
-	for (i = 0; i < len - 14; i++)
-		if (strcmp(pkt + i, "multicast") == 0)
-			break;
-	if (i >= (len - 14)) /* non-Multicast OACK, ign. */
-		return;
-
-	i += 10; /* strlen multicast */
-	mc_adr = pkt + i;
-	for (; i < len; i++) {
-		if (*(pkt + i) == ',') {
-			*(pkt + i) = '\0';
-			if (port) {
-				mc = pkt + i + 1;
-				break;
-			} else {
-				port = pkt + i + 1;
-			}
-		}
-	}
-	if (!port || !mc_adr || !mc)
-		return;
-	if (tftp_mcast_active && tftp_mcast_master_client) {
-		printf("I got a OACK as master Client, WRONG!\n");
-		return;
-	}
-	/* ..I now accept packets destined for this MCAST addr, port */
-	if (!tftp_mcast_active) {
-		if (tftp_mcast_bitmap) {
-			printf("Internal failure! no mcast.\n");
-			free(tftp_mcast_bitmap);
-			tftp_mcast_bitmap = NULL;
-			tftp_mcast_disabled = 1;
-			return;
-		}
-		/* I malloc instead of pre-declare; so that if the file ends
-		 * up being too big for this bitmap I can retry
-		 */
-		tftp_mcast_bitmap = malloc(tftp_mcast_bitmap_size);
-		if (!tftp_mcast_bitmap) {
-			printf("No bitmap, no multicast. Sorry.\n");
-			tftp_mcast_disabled = 1;
-			return;
-		}
-		memset(tftp_mcast_bitmap, 0, tftp_mcast_bitmap_size);
-		tftp_mcast_prev_hole = 0;
-		tftp_mcast_active = 1;
-	}
-	addr = string_to_ip(mc_adr);
-	if (net_mcast_addr.s_addr != addr.s_addr) {
-		if (net_mcast_addr.s_addr)
-			eth_mcast_join(net_mcast_addr, 0);
-		net_mcast_addr = addr;
-		if (eth_mcast_join(net_mcast_addr, 1)) {
-			printf("Fail to set mcast, revert to TFTP\n");
-			tftp_mcast_disabled = 1;
-			mcast_cleanup();
-			net_start_again();
-		}
-	}
-	tftp_mcast_master_client = simple_strtoul((char *)mc, NULL, 10);
-	tftp_mcast_port = (unsigned short)simple_strtoul(port, NULL, 10);
-	printf("Multicast: %s:%d [%d]\n", mc_adr, tftp_mcast_port,
-	       tftp_mcast_master_client);
-	return;
-}
-
-#endif /* Multicast TFTP */
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index f0a0e05..c05fc37 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -1197,7 +1197,6 @@
 CONFIG_MAX_MEM_MAPPED
 CONFIG_MAX_PKT
 CONFIG_MAX_RAM_BANK_SIZE
-CONFIG_MCAST_TFTP
 CONFIG_MCF5249
 CONFIG_MCF5253
 CONFIG_MCFFEC
@@ -4535,7 +4534,6 @@
 CONFIG_USB_EHCI_MXC
 CONFIG_USB_EHCI_MXS
 CONFIG_USB_EHCI_SPEAR
-CONFIG_USB_EHCI_SUNXI
 CONFIG_USB_EHCI_TEGRA
 CONFIG_USB_EHCI_TXFIFO_THRESH
 CONFIG_USB_EHCI_VCT
@@ -4573,7 +4571,6 @@
 CONFIG_USB_OHCI_EP93XX
 CONFIG_USB_OHCI_LPC32XX
 CONFIG_USB_OHCI_NEW
-CONFIG_USB_OHCI_SUNXI
 CONFIG_USB_OTG
 CONFIG_USB_OTG_BLACKLIST_HUB
 CONFIG_USB_PHY_TYPE
diff --git a/test/dm/eth.c b/test/dm/eth.c
index 850eabb..6e002b8 100644
--- a/test/dm/eth.c
+++ b/test/dm/eth.c
@@ -237,7 +237,7 @@
 	env_set("ethact", "eth@10004000");
 	env_set("netretry", "no");
 	sandbox_eth_skip_timeout();
-	ut_asserteq(-ETIMEDOUT, net_loop(PING));
+	ut_asserteq(-ENONET, net_loop(PING));
 	ut_asserteq_str("eth@10004000", env_get("ethact"));
 
 	return 0;