From b2098a724a1302dae3349937b455312ea8c26e5c Mon Sep 17 00:00:00 2001
From: handsomeyingyan <handsomeyingyan@github.com>
Date: Fri, 16 Apr 2021 09:42:12 +0800
Subject: [PATCH] initial supoort for Pine64 PineCube

---
 arch/arm/dts/Makefile                  |   3 +-
 arch/arm/dts/sun8i-s3-pinecube.dts     | 246 +++++++++++++++++++++++++
 arch/arm/dts/sun8i-v3.dtsi             |  27 +++
 arch/arm/dts/sun8i-v3s.dtsi            | 173 +++++++++++++++++
 arch/arm/include/asm/arch-sunxi/gpio.h |   1 +
 arch/arm/mach-sunxi/Kconfig            |   3 +-
 board/sunxi/MAINTAINERS                |   5 +
 board/sunxi/board.c                    |   4 +
 configs/pinecube_defconfig             |  23 +++
 drivers/clk/sunxi/clk_v3s.c            |  13 ++
 drivers/gpio/sunxi_gpio.c              |   1 +
 drivers/mtd/spi/Kconfig                |   6 +
 drivers/mtd/spi/spi-nor-ids.c          |   5 +
 drivers/net/sun8i_emac.c               |  15 +-
 drivers/power/Kconfig                  |   4 +-
 15 files changed, 520 insertions(+), 9 deletions(-)
 create mode 100644 arch/arm/dts/sun8i-s3-pinecube.dts
 create mode 100644 arch/arm/dts/sun8i-v3.dtsi
 create mode 100644 configs/pinecube_defconfig

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 6c265f6a..225fc877 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -568,7 +568,8 @@ dtb-$(CONFIG_MACH_SUN8I_R40) += \
 	sun8i-r40-bananapi-m2-ultra.dtb \
 	sun8i-v40-bananapi-m2-berry.dtb
 dtb-$(CONFIG_MACH_SUN8I_V3S) += \
-	sun8i-v3s-licheepi-zero.dtb
+	sun8i-v3s-licheepi-zero.dtb \
+	sun8i-s3-pinecube.dtb
 dtb-$(CONFIG_MACH_SUN50I_H5) += \
 	sun50i-h5-bananapi-m2-plus.dtb \
 	sun50i-h5-emlid-neutis-n5-devboard.dtb \
diff --git a/arch/arm/dts/sun8i-s3-pinecube.dts b/arch/arm/dts/sun8i-s3-pinecube.dts
new file mode 100644
index 00000000..2d4a9726
--- /dev/null
+++ b/arch/arm/dts/sun8i-s3-pinecube.dts
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR X11)
+/*
+ * Copyright 2019 Icenowy Zheng <icenowy@aosc.io>
+ */
+
+/dts-v1/;
+#include "sun8i-v3.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "PineCube IP Camera";
+	compatible = "pine64,pinecube", "allwinner,sun8i-s3";
+
+	aliases {
+		serial0 = &uart2;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led1 {
+			label = "pine64:ir:led1";
+			gpios = <&pio 1 10 GPIO_ACTIVE_LOW>; /* PB10 */
+		};
+
+		led2 {
+			label = "pine64:ir:led2";
+			gpios = <&pio 1 12 GPIO_ACTIVE_LOW>; /* PB12 */
+		};
+	};
+
+	reg_vcc5v0: vcc5v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+
+	reg_vcc_wifi: vcc-wifi {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-wifi";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&pio 1 2 GPIO_ACTIVE_LOW>; /* PB2 WIFI-EN */
+		vin-supply = <&reg_dcdc3>;
+		startup-delay-us = <200000>;
+	};
+
+	wifi_pwrseq: wifi_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&pio 1 3 GPIO_ACTIVE_LOW>; /* PB3 WIFI-RST */
+		post-power-on-delay-ms = <200>;
+	};
+};
+
+&csi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&csi1_8bit_pins>;
+	status = "okay";
+
+	port {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi1_ep: endpoint {
+			remote-endpoint = <&ov5640_ep>;
+			bus-width = <8>;
+			hsync-active = <1>; /* Active high */
+			vsync-active = <0>; /* Active low */
+			data-active = <1>;  /* Active high */
+			pclk-sample = <1>;  /* Rising */
+		};
+	};
+};
+
+&emac {
+	phy-handle = <&int_mii_phy>;
+	phy-mode = "mii";
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	axp209: pmic@34 {
+		compatible = "x-powers,axp203",
+			     "x-powers,axp209";
+		reg = <0x34>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+	};
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pe_pins>;
+	status = "okay";
+
+	ov5640: camera@3c {
+		compatible = "ovti,ov5640";
+		reg = <0x3c>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&csi1_mclk_pin>;
+		clocks = <&ccu CLK_CSI1_MCLK>;
+		clock-names = "xclk";
+
+		AVDD-supply = <&reg_ldo3>;
+		DOVDD-supply = <&reg_ldo3>;
+		DVDD-supply = <&reg_ldo4>;
+		reset-gpios = <&pio 4 23 GPIO_ACTIVE_LOW>; /* PE23 */
+		powerdown-gpios = <&pio 4 24 GPIO_ACTIVE_HIGH>; /* PE24 */
+
+		port {
+			ov5640_ep: endpoint {
+				remote-endpoint = <&csi1_ep>;
+				bus-width = <8>;
+				hsync-active = <1>; /* Active high */
+				vsync-active = <0>; /* Active low */
+				data-active = <1>;  /* Active high */
+				pclk-sample = <1>;  /* Rising */
+			};
+		};
+	};
+};
+
+&lradc {
+	vref-supply = <&reg_ldo2>;
+	status = "okay";
+
+	button-200 {
+		label = "Setup";
+		linux,code = <KEY_SETUP>;
+		channel = <0>;
+		voltage = <190000>;
+	};
+};
+
+&mmc0 {
+	vmmc-supply = <&reg_dcdc3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
+	status = "okay";
+};
+
+&mmc1 {
+	vmmc-supply = <&reg_vcc_wifi>;
+	vqmmc-supply = <&reg_dcdc3>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+};
+
+&pio {
+	vcc-pd-supply = <&reg_dcdc3>;
+	vcc-pe-supply = <&reg_ldo3>;
+};
+
+#include "axp209.dtsi"
+
+&ac_power_supply {
+	status = "okay";
+};
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1250000>;
+	regulator-max-microvolt = <1250000>;
+	regulator-name = "vdd-sys-cpu-ephy";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-3v3";
+};
+
+&reg_ldo1 {
+	regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
+&reg_ldo3 {
+	regulator-min-microvolt = <2800000>;
+	regulator-max-microvolt = <2800000>;
+	regulator-name = "avdd-dovdd-2v8-csi";
+	regulator-soft-start;
+	regulator-ramp-delay = <1600>;
+};
+
+&reg_ldo4 {
+	regulator-min-microvolt = <1800000>;
+	regulator-max-microvolt = <1800000>;
+	regulator-name = "dvdd-1v8-csi";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "winbond,w25q128", "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+	};
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&usb_otg {
+	phys = <&usbphy>;
+    	extcon = <&usbphy>;
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbphy {
+	#phy-cells = <0>;
+	usb0_vbus-supply = <&reg_vcc5v0>;
+	status = "okay";
+};
+
+&ehci0 {
+    status = "okay";
+};
+
+&ohci0 {
+    status = "okay";
+};
diff --git a/arch/arm/dts/sun8i-v3.dtsi b/arch/arm/dts/sun8i-v3.dtsi
new file mode 100644
index 00000000..ca4672ed
--- /dev/null
+++ b/arch/arm/dts/sun8i-v3.dtsi
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 Icenowy Zheng <icenowy@aosc.io>
+ */
+
+#include "sun8i-v3s.dtsi"
+
+&ccu {
+	compatible = "allwinner,sun8i-v3-ccu";
+};
+
+&emac {
+	/delete-property/ phy-handle;
+	/delete-property/ phy-mode;
+};
+
+&mdio_mux {
+	external_mdio: mdio@2 {
+		reg = <2>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+};
+
+&pio {
+	compatible = "allwinner,sun8i-v3-pinctrl";
+};
diff --git a/arch/arm/dts/sun8i-v3s.dtsi b/arch/arm/dts/sun8i-v3s.dtsi
index dc62512e..ef9d3e9a 100644
--- a/arch/arm/dts/sun8i-v3s.dtsi
+++ b/arch/arm/dts/sun8i-v3s.dtsi
@@ -153,6 +153,15 @@
 				};
 			};
 		};
+		
+		syscon: system-control@1c00000 {
+			compatible = "allwinner,sun8i-v3s-system-control",
+				 "allwinner,sun8i-h3-system-control";
+			reg = <0x01c00000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+		};
 
 		tcon0: lcd-controller@1c0c000 {
 			compatible = "allwinner,sun8i-v3s-tcon";
@@ -291,6 +300,13 @@
 			interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
 		};
+		
+		lradc: lradc@1c22800 {
+			compatible = "allwinner,sun4i-a10-lradc-keys";
+			reg = <0x01c22800 0x400>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+ 		};
 
 		pio: pinctrl@01c20800 {
 			compatible = "allwinner,sun8i-v3s-pinctrl";
@@ -312,6 +328,32 @@
 				function = "lcd";
 			};
 
+			/omit-if-no-ref/
+			csi1_8bit_pins: csi1-8bit-pins {
+				pins = "PE0", "PE2", "PE3", "PE8", "PE9",
+				       "PE10", "PE11", "PE12", "PE13", "PE14",
+				       "PE15";
+				function = "csi";
+			};
+
+			/omit-if-no-ref/
+			csi1_mclk_pin: csi1-mclk-pin {
+				pins = "PE1";
+				function = "csi";
+			};
+
+			i2c0_pins: i2c0-pins {
+				pins = "PB6", "PB7";
+				function = "i2c0";
+			};
+
+			/omit-if-no-ref/
+			i2c1_pe_pins: i2c1-pe-pins {
+				pins = "PE21", "PE22";
+				function = "i2c1";
+			};
+
+
 			mmc0_pins_a: mmc0@0 {
 				pins = "PF0", "PF1", "PF2", "PF3",
 				       "PF4", "PF5";
@@ -319,6 +361,14 @@
 				drive-strength = <30>;
 				bias-pull-up;
 			};
+
+			mmc1_pins: mmc1-pins {
+				pins = "PG0", "PG1", "PG2", "PG3",
+				       "PG4", "PG5";
+				function = "mmc1";
+				drive-strength = <30>;
+				bias-pull-up;
+			};
 			
 			pwm0_pins: pwm0-pins {
 				pins = "PB4";
@@ -335,6 +385,16 @@
 				function = "uart0";
 				bias-pull-up;
 			};
+
+			spi0_pins: spi0-pins {
+				pins = "PC0", "PC1", "PC2", "PC3";
+				function = "spi0";
+			};
+
+			uart2_pins: uart2-pins {
+				pins = "PB0", "PB1";
+				function = "uart2";
+			};
 			
 		};
 
@@ -382,9 +442,122 @@
 			reg-io-width = <4>;
 			clocks = <&ccu CLK_BUS_UART2>;
 			resets = <&ccu RST_BUS_UART2>;
+			pinctrl-0 = <&uart2_pins>;
+			pinctrl-names = "default";
+			status = "disabled";
+		};
+		
+		i2c0: i2c@1c2ac00 {
+			compatible = "allwinner,sun6i-a31-i2c";
+			reg = <0x01c2ac00 0x400>;
+			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_I2C0>;
+			resets = <&ccu RST_BUS_I2C0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pins>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c1: i2c@1c2b000 {
+			compatible = "allwinner,sun6i-a31-i2c";
+			reg = <0x01c2b000 0x400>;
+			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_I2C1>;
+			resets = <&ccu RST_BUS_I2C1>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		emac: ethernet@1c30000 {
+			compatible = "allwinner,sun8i-v3s-emac";
+			syscon = <&syscon>;
+			reg = <0x01c30000 0x10000>;
+			interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq";
+			resets = <&ccu RST_BUS_EMAC>;
+			reset-names = "stmmaceth";
+			clocks = <&ccu CLK_BUS_EMAC>;
+			clock-names = "stmmaceth";
+			phy-handle = <&int_mii_phy>;
+			phy-mode = "mii";
+			status = "disabled";
+
+			mdio: mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "snps,dwmac-mdio";
+			};
+
+			mdio_mux: mdio-mux {
+				compatible = "allwinner,sun8i-h3-mdio-mux";
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				mdio-parent-bus = <&mdio>;
+				/* Only one MDIO is usable at the time */
+				internal_mdio: mdio@1 {
+					compatible = "allwinner,sun8i-h3-mdio-internal";
+					reg = <1>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					int_mii_phy: ethernet-phy@1 {
+						compatible = "ethernet-phy-ieee802.3-c22";
+						reg = <1>;
+						clocks = <&ccu CLK_BUS_EPHY>;
+						resets = <&ccu RST_BUS_EPHY>;
+					};
+				};
+			};
+		};
+		
+        		ehci0: usb@01c1a000 {
+            			compatible = "allwinner,sun8i-v3s-ehci", "generic-ehci";
+            			reg = <0x01c1a000 0x100>;
+            			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+            			clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>;
+            			resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>;
+            			status = "disabled";
+        		};
+
+        		ohci0: usb@01c1a400 {
+            			compatible = "allwinner,sun8i-v3s-ohci", "generic-ohci";
+            			reg = <0x01c1a400 0x100>;
+            			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+            			clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>, <&ccu CLK_USB_OHCI0>;
+            			resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>;
+            			status = "disabled";
+        		};
+
+		spi0: spi@1c68000 {
+			compatible = "allwinner,sun8i-h3-spi";
+			reg = <0x01c68000 0x1000>;
+			interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
+			clock-names = "ahb", "mod";
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi0_pins>;
+			resets = <&ccu RST_BUS_SPI0>;
 			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
 		};
 
+		csi1: camera@1cb4000 {
+			compatible = "allwinner,sun8i-v3s-csi";
+			reg = <0x01cb4000 0x3000>;
+			interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_CSI>,
+				 <&ccu CLK_CSI1_SCLK>,
+				 <&ccu CLK_DRAM_CSI>;
+			clock-names = "bus", "mod", "ram";
+			resets = <&ccu RST_BUS_CSI>;
+ 			status = "disabled";
+ 		};
+
 		gic: interrupt-controller@01c81000 {
 			compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
 			reg = <0x01c81000 0x1000>,
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index afa8eccc..84431343 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -158,6 +158,7 @@ enum sunxi_gpio_number {
 #define SUN5I_GPB_TWI1		2
 #define SUN4I_GPB_TWI2		2
 #define SUN5I_GPB_TWI2		2
+#define SUN8I_V3S_GPB_TWI0	2
 #define SUN4I_GPB_UART0		2
 #define SUN5I_GPB_UART0		2
 #define SUN8I_GPB_UART2		2
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 6e911151..e2aa0b95 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -260,7 +260,7 @@ config MACH_SUN8I_R40
 	select PHY_SUN4I_USB
 
 config MACH_SUN8I_V3S
-	bool "sun8i (Allwinner V3s)"
+	bool "sun8i (Allwinner V3/V3s/S3/S3L)"
 	select CPU_V7A
 	select CPU_V7_HAS_NONSEC
 	select CPU_V7_HAS_VIRT
@@ -371,7 +371,6 @@ choice
 config SUNXI_DRAM_DDR3_1333
 	bool "DDR3 1333"
 	select SUNXI_DRAM_DDR3
-	depends on !MACH_SUN8I_V3S
 	---help---
 	This option is the original only supported memory type, which suits
 	many H3/H5/A64 boards available now.
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index 1180b86d..5c53b2c8 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -440,6 +440,11 @@ M:	Vasily Khoruzhick <anarsoul@gmail.com>
 S:	Maintained
 F:	configs/pinebook_defconfig
 
+PINECUBE BOARD:
+M:	Icenowy Zheng <icenowy@aosc.io>
+S:	Maintained
+F:	configs/pinecube_defconfig
+
 PINE64 BOARDS
 M:	Andre Przywara <andre.przywara@arm.com>
 S:	Maintained
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index c6b6a7fc..a03ce6ca 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -101,6 +101,10 @@ void i2c_init_board(void)
 	sunxi_gpio_set_cfgpin(SUNXI_GPH(14), SUN6I_GPH_TWI0);
 	sunxi_gpio_set_cfgpin(SUNXI_GPH(15), SUN6I_GPH_TWI0);
 	clock_twi_onoff(0, 1);
+#elif defined(CONFIG_MACH_SUN8I_V3S)
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(6), 2);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(7), 2);
+	clock_twi_onoff(0, 1);
 #elif defined(CONFIG_MACH_SUN8I)
 	sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN8I_GPH_TWI0);
 	sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN8I_GPH_TWI0);
diff --git a/configs/pinecube_defconfig b/configs/pinecube_defconfig
new file mode 100644
index 00000000..fec01aeb
--- /dev/null
+++ b/configs/pinecube_defconfig
@@ -0,0 +1,23 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_SPL=y
+CONFIG_MACH_SUN8I_V3S=y
+CONFIG_SUNXI_DRAM_DDR3_1333=y
+CONFIG_DRAM_CLK=504
+CONFIG_DRAM_ODT_EN=y
+CONFIG_I2C0_ENABLE=y
+CONFIG_SPL_I2C_SUPPORT=y
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-s3-pinecube"
+CONFIG_DM_MTD=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_XTX=y
+CONFIG_SUN8I_EMAC=y
+CONFIG_AXP209_POWER=y
+CONFIG_AXP_DCDC2_VOLT=1250
+CONFIG_AXP_DCDC3_VOLT=3300
+CONFIG_AXP_ALDO3_VOLT_SLOPE_08=y
+CONFIG_AXP_ALDO3_INRUSH_QUIRK=y
+CONFIG_CONS_INDEX=3
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
diff --git a/drivers/clk/sunxi/clk_v3s.c b/drivers/clk/sunxi/clk_v3s.c
index b79446cc..9a65df83 100644
--- a/drivers/clk/sunxi/clk_v3s.c
+++ b/drivers/clk/sunxi/clk_v3s.c
@@ -17,16 +17,22 @@ static struct ccu_clk_gate v3s_gates[] = {
 	[CLK_BUS_MMC0]		= GATE(0x060, BIT(8)),
 	[CLK_BUS_MMC1]		= GATE(0x060, BIT(9)),
 	[CLK_BUS_MMC2]		= GATE(0x060, BIT(10)),
+	[CLK_BUS_EMAC]		= GATE(0x060, BIT(17)),
 	[CLK_BUS_SPI0]		= GATE(0x060, BIT(20)),
 	[CLK_BUS_OTG]		= GATE(0x060, BIT(24)),
+	[CLK_BUS_EHCI0]		= GATE(0x060, BIT(26)),
+	[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_EPHY]		= GATE(0x070, BIT(0)),
+
 	[CLK_SPI0]		= GATE(0x0a0, BIT(31)),
 
 	[CLK_USB_PHY0]          = GATE(0x0cc, BIT(8)),
+	[CLK_USB_OHCI0]         = GATE(0x0cc, BIT(16)),
 };
 
 static struct ccu_reset v3s_resets[] = {
@@ -35,12 +41,17 @@ static struct ccu_reset v3s_resets[] = {
 	[RST_BUS_MMC0]		= RESET(0x2c0, BIT(8)),
 	[RST_BUS_MMC1]		= RESET(0x2c0, BIT(9)),
 	[RST_BUS_MMC2]		= RESET(0x2c0, BIT(10)),
+	[RST_BUS_EMAC]		= RESET(0x2c0, BIT(17)),
 	[RST_BUS_SPI0]		= RESET(0x2c0, BIT(20)),
 	[RST_BUS_OTG]		= RESET(0x2c0, BIT(24)),
+	[RST_BUS_EHCI0]		= RESET(0x2c0, BIT(26)),
+	[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_EPHY]		= RESET(0x2c8, BIT(2)),
 };
 
 static const struct ccu_desc v3s_ccu_desc = {
@@ -56,6 +67,8 @@ static int v3s_clk_bind(struct udevice *dev)
 static const struct udevice_id v3s_clk_ids[] = {
 	{ .compatible = "allwinner,sun8i-v3s-ccu",
 	  .data = (ulong)&v3s_ccu_desc },
+	{ .compatible = "allwinner,sun8i-v3-ccu",
+	  .data = (ulong)&v3s_ccu_desc },
 	{ }
 };
 
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index 68418aa5..f6e27126 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -351,6 +351,7 @@ static const struct udevice_id sunxi_gpio_ids[] = {
 	ID("allwinner,sun8i-a83t-pinctrl",	a_all),
 	ID("allwinner,sun8i-h3-pinctrl",	a_all),
 	ID("allwinner,sun8i-r40-pinctrl",	a_all),
+	ID("allwinner,sun8i-v3-pinctrl",	a_all),
 	ID("allwinner,sun8i-v3s-pinctrl",	a_all),
 	ID("allwinner,sun9i-a80-pinctrl",	a_all),
 	ID("allwinner,sun50i-a64-pinctrl",	a_all),
diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
index 018e8c59..723485ba 100644
--- a/drivers/mtd/spi/Kconfig
+++ b/drivers/mtd/spi/Kconfig
@@ -152,6 +152,12 @@ config SPI_FLASH_XMC
 	  Add support for various XMC (Wuhan Xinxin Semiconductor
 	  Manufacturing Corp.) SPI flash chips (XM25xxx)
 
+config SPI_FLASH_XTX
+	bool "XTX SPI flash support"
+	help
+	  Add support for various XTX (Shenzhen Xin Tian Xia Tech) SPI flash
+	  chips (XTX25FxxxB)
+
 endif
 
 config SPI_FLASH_USE_4K_SECTORS
diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 114ebacd..e470ba24 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -319,6 +319,11 @@ const struct flash_info spi_nor_ids[] = {
 	/* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */
 	{ INFO("XM25QH64A", 0x207017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ INFO("XM25QH128A", 0x207018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+#endif
+#ifdef CONFIG_SPI_FLASH_XTX
+	/* XTX (Shenzhen Xin Tian Xia Tech) */
+	{ INFO("xt25f32b", 0x0b4016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ INFO("xt25f128b", 0x0b4018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 #endif
 	{ },
 };
diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
index e2b05ace..29d68d5c 100644
--- a/drivers/net/sun8i_emac.c
+++ b/drivers/net/sun8i_emac.c
@@ -56,9 +56,11 @@
 #define RX_TOTAL_BUFSIZE	(CONFIG_ETH_BUFSIZE * CONFIG_RX_DESCR_NUM)
 
 #define H3_EPHY_DEFAULT_VALUE	0x58000
+#define V3S_EPHY_DEFAULT_VALUE	0x38000
 #define H3_EPHY_DEFAULT_MASK	GENMASK(31, 15)
 #define H3_EPHY_ADDR_SHIFT	20
 #define REG_PHY_ADDR_MASK	GENMASK(4, 0)
+#define H3_EPHY_CLK_SEL		BIT(18) /* 1: 24MHz, 0: 25MHz */
 #define H3_EPHY_LED_POL		BIT(17)	/* 1: active low, 0: active high */
 #define H3_EPHY_SHUTDOWN	BIT(16)	/* 1: shutdown, 0: power up */
 #define H3_EPHY_SELECT		BIT(15) /* 1: internal PHY, 0: external PHY */
@@ -112,6 +114,7 @@ enum emac_variant {
 	A64_EMAC,
 	R40_GMAC,
 	H6_EMAC,
+	V3S_EMAC,
 };
 
 struct emac_dma_desc {
@@ -279,10 +282,11 @@ static int sun8i_emac_set_syscon_ephy(struct emac_eth_dev *priv, u32 *reg)
 		 * needs to be configured and powered up before use
 		*/
 		*reg &= ~H3_EPHY_DEFAULT_MASK;
-		*reg |=  H3_EPHY_DEFAULT_VALUE;
+		*reg |= ((priv->variant == V3S_EMAC) ? V3S_EPHY_DEFAULT_VALUE :  H3_EPHY_DEFAULT_VALUE);
 		*reg |= priv->phyaddr << H3_EPHY_ADDR_SHIFT;
 		*reg &= ~H3_EPHY_SHUTDOWN;
 		*reg |= H3_EPHY_SELECT;
+		*reg |= H3_EPHY_CLK_SEL;
 	} else
 		/* This is to select External Gigabit PHY on
 		 * the boards with H3 SoC.
@@ -311,7 +315,7 @@ static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata,
 
 	reg = readl(priv->sysctl_reg + 0x30);
 
-	if (priv->variant == H3_EMAC || priv->variant == H6_EMAC) {
+	if (priv->variant == H3_EMAC || priv->variant == H6_EMAC || priv->variant == V3S_EMAC) {
 		ret = sun8i_emac_set_syscon_ephy(priv, &reg);
 		if (ret)
 			return ret;
@@ -320,7 +324,8 @@ static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata,
 	reg &= ~(SC_ETCS_MASK | SC_EPIT);
 	if (priv->variant == H3_EMAC ||
 	    priv->variant == A64_EMAC ||
-	    priv->variant == H6_EMAC)
+	    priv->variant == H6_EMAC ||
+	    priv->variant == V3S_EMAC)
 		reg &= ~SC_RMII_EN;
 
 	switch (priv->interface) {
@@ -985,7 +990,7 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev)
 		return -EINVAL;
 	}
 
-	if (priv->variant == H3_EMAC) {
+	if (priv->variant == H3_EMAC || priv->variant == V3S_EMAC) {
 		ret = sun8i_get_ephy_nodes(priv);
 		if (ret)
 			return ret;
@@ -1038,6 +1043,8 @@ static const struct udevice_id sun8i_emac_eth_ids[] = {
 		.data = (uintptr_t)R40_GMAC },
 	{.compatible = "allwinner,sun50i-h6-emac",
 		.data = (uintptr_t)H6_EMAC },
+	{.compatible = "allwinner,sun8i-v3s-emac",
+		.data = (uintptr_t)V3S_EMAC },
 	{ }
 };
 
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 5910926f..02050f6f 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -14,7 +14,7 @@ choice
 	default AXP209_POWER if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
 	default AXP221_POWER if MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_R40
 	default AXP818_POWER if MACH_SUN8I_A83T
-	default SUNXI_NO_PMIC if MACH_SUNXI_H3_H5 || MACH_SUN50I
+	default SUNXI_NO_PMIC if MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_V3S
 
 config SUNXI_NO_PMIC
 	bool "board without a pmic"
@@ -32,7 +32,7 @@ config AXP152_POWER
 
 config AXP209_POWER
 	bool "axp209 pmic support"
-	depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
+	depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUN8I_V3S
 	select AXP_PMIC_BUS
 	select CMD_POWEROFF
 	---help---
-- 
2.31.1

