Merge tag 'fsl-qoriq-next-2023-3-14' of https://source.denx.de/u-boot/custodians/u-boot-fsl-qoriq into next

Enable DM_SERIAL for freescale ls2080a
Drop non DM_ETH code for freescale:
  lx2160a/ls2080rdb/ls2080aqds/ls1088a
diff --git a/MAINTAINERS b/MAINTAINERS
index e29c16c..91d40ea 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1336,6 +1336,7 @@
 S:	Maintained
 F:	arch/sandbox/
 F:	doc/arch/sandbox.rst
+F:	drivers/*/*sandbox*.c
 F:	include/dt-bindings/*/sandbox*.h
 
 SEAMA
@@ -1460,8 +1461,12 @@
 F:	configs/k2l_hs_evm_defconfig
 F:	configs/am65x_hs_evm_r5_defconfig
 F:	configs/am65x_hs_evm_a53_defconfig
+F:	configs/j7200_hs_evm_a72_defconfig
+F:	configs/j7200_hs_evm_r5_defconfig
 F:	configs/j721e_hs_evm_a72_defconfig
 F:	configs/j721e_hs_evm_r5_defconfig
+F:	configs/j721s2_hs_evm_a72_defconfig
+F:	configs/j721s2_hs_evm_r5_defconfig
 
 TPM DRIVERS
 M:	Ilias Apalodimas <ilias.apalodimas@linaro.org>
diff --git a/Makefile b/Makefile
index c00683b..613b2c6 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
 VERSION = 2023
 PATCHLEVEL = 04
 SUBLEVEL =
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
 NAME =
 
 # *DOCUMENTATION*
@@ -1335,6 +1335,7 @@
 		-a opensbi-path=${OPENSBI} \
 		-a default-dt=$(default_dt) \
 		-a scp-path=$(SCP) \
+		-a rockchip-tpl-path=$(ROCKCHIP_TPL) \
 		-a spl-bss-pad=$(if $(CONFIG_SPL_SEPARATE_BSS),,1) \
 		-a tpl-bss-pad=$(if $(CONFIG_TPL_SEPARATE_BSS),,1) \
 		-a spl-dtb=$(CONFIG_SPL_OF_REAL) \
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 7a577de..c160e884 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -165,7 +165,13 @@
 	rk3399pro-rock-pi-n10.dtb
 
 dtb-$(CONFIG_ROCKCHIP_RK3568) += \
-	rk3568-evb.dtb
+	rk3568-evb.dtb \
+	rk3566-radxa-cm3-io.dtb \
+	rk3568-rock-3a.dtb
+
+dtb-$(CONFIG_ROCKCHIP_RK3588) += \
+	rk3588-edgeble-neu6a-io.dtb \
+	rk3588-rock-5b.dtb
 
 dtb-$(CONFIG_ROCKCHIP_RV1108) += \
 	rv1108-elgin-r1.dtb \
diff --git a/arch/arm/dts/px30.dtsi b/arch/arm/dts/px30.dtsi
index bfa3580..3152bf1 100644
--- a/arch/arm/dts/px30.dtsi
+++ b/arch/arm/dts/px30.dtsi
@@ -1366,6 +1366,7 @@
 			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&pmucru PCLK_GPIO0_PMU>;
 			gpio-controller;
+			gpio-ranges = <&pinctrl 0 0 32>;
 			#gpio-cells = <2>;
 
 			interrupt-controller;
@@ -1378,6 +1379,7 @@
 			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cru PCLK_GPIO1>;
 			gpio-controller;
+			gpio-ranges = <&pinctrl 0 32 32>;
 			#gpio-cells = <2>;
 
 			interrupt-controller;
@@ -1390,6 +1392,7 @@
 			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cru PCLK_GPIO2>;
 			gpio-controller;
+			gpio-ranges = <&pinctrl 0 64 32>;
 			#gpio-cells = <2>;
 
 			interrupt-controller;
@@ -1402,6 +1405,7 @@
 			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cru PCLK_GPIO3>;
 			gpio-controller;
+			gpio-ranges = <&pinctrl 0 96 32>;
 			#gpio-cells = <2>;
 
 			interrupt-controller;
diff --git a/arch/arm/dts/r8a77980-condor-u-boot.dts b/arch/arm/dts/r8a77980-condor-u-boot.dts
index 576a74e..f4a3b43 100644
--- a/arch/arm/dts/r8a77980-condor-u-boot.dts
+++ b/arch/arm/dts/r8a77980-condor-u-boot.dts
@@ -12,6 +12,23 @@
 	aliases {
 		spi0 = &rpc;
 	};
+
+	sysinfo {
+		compatible = "renesas,rcar-sysinfo";
+		i2c-eeprom = <&sysinfo_eeprom>;
+		bootph-all;
+	};
+};
+
+&i2c0 {
+	bootph-all;
+
+	sysinfo_eeprom: eeprom@50 {
+		compatible = "rohm,br24t01", "atmel,24c01";
+		reg = <0x50>;
+		pagesize = <8>;
+		bootph-all;
+	};
 };
 
 &rpc {
diff --git a/arch/arm/dts/r8a77995-draak-u-boot.dts b/arch/arm/dts/r8a77995-draak-u-boot.dts
index 0ea2570..41ceae1 100644
--- a/arch/arm/dts/r8a77995-draak-u-boot.dts
+++ b/arch/arm/dts/r8a77995-draak-u-boot.dts
@@ -8,6 +8,25 @@
 #include "r8a77995-draak.dts"
 #include "r8a77995-u-boot.dtsi"
 
+/ {
+	sysinfo {
+		compatible = "renesas,rcar-sysinfo";
+		i2c-eeprom = <&sysinfo_eeprom>;
+		bootph-all;
+	};
+};
+
+&i2c0 {
+	bootph-all;
+
+	sysinfo_eeprom: eeprom@50 {
+		compatible = "rohm,br24t01", "atmel,24c01";
+		reg = <0x50>;
+		pagesize = <8>;
+		bootph-all;
+	};
+};
+
 &rpc {
 	reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0x04000000>;
 	status = "disabled";
diff --git a/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi b/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi
new file mode 100644
index 0000000..a27a3ad
--- /dev/null
+++ b/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018-2019 Rockchip Electronics Co., Ltd
+ */
+#include "rk3308-u-boot.dtsi"
+
+/ {
+	chosen {
+		u-boot,spl-boot-order = "same-as-spl", &emmc;
+	};
+};
+
+&uart0 {
+	bootph-all;
+	clock-frequency = <24000000>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3308-rock-pi-s.dts b/arch/arm/dts/rk3308-rock-pi-s.dts
new file mode 100644
index 0000000..b5a8691
--- /dev/null
+++ b/arch/arm/dts/rk3308-rock-pi-s.dts
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (C) 2023 Akash Gajjar <gajjar04akash@gmail.com>
+ * Copyright (c) 2023 Jagan Teki <jagan@openedev.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include "rk3308.dtsi"
+
+/ {
+	model = "Radxa ROCK Pi S";
+	compatible = "radxa,rockpis", "rockchip,rk3308";
+
+	aliases {
+		ethernet0 = &mac;
+		mmc0 = &emmc;
+		mmc1 = &sdmmc;
+	};
+
+	chosen {
+		stdout-path = "serial0:1500000n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&green_led_gio>, <&heartbeat_led_gpio>;
+
+		green-led {
+			default-state = "on";
+			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+			label = "rockpis:green:power";
+			linux,default-trigger = "default-on";
+		};
+
+		blue-led {
+			default-state = "on";
+			gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
+			label = "rockpis:blue:user";
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		pinctrl-0 = <&wifi_enable_h>;
+		pinctrl-names = "default";
+		reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>;
+	};
+
+	vcc_1v8: vcc-1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v8";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc_io>;
+	};
+
+	vcc_io: vcc-io {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_io";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vcc_ddr: vcc-ddr {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_ddr";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1500000>;
+		regulator-max-microvolt = <1500000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vcc5v0_otg: vcc5v0-otg {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&otg_vbus_drv>;
+		regulator-name = "vcc5v0_otg";
+		regulator-always-on;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vcc5v0_sys: vcc5v0-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+
+	vdd_core: vdd-core {
+		compatible = "pwm-regulator";
+		pwms = <&pwm0 0 5000 1>;
+		pwm-supply = <&vcc5v0_sys>;
+		regulator-name = "vdd_core";
+		regulator-min-microvolt = <827000>;
+		regulator-max-microvolt = <1340000>;
+		regulator-init-microvolt = <1015000>;
+		regulator-settling-time-up-us = <250>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vdd_log: vdd-log {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_log";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1050000>;
+		regulator-max-microvolt = <1050000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_core>;
+};
+
+&emmc {
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	non-removable;
+	vmmc-supply = <&vcc_io>;
+	status = "okay";
+};
+
+&mac {
+	clock_in_out = "output";
+	phy-supply = <&vcc_io>;
+	snps,reset-gpio = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 50000 50000>;
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+};
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rtc_32k>;
+
+	leds {
+		green_led_gio: green-led-gpio {
+			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		heartbeat_led_gpio: heartbeat-led-gpio {
+			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	usb {
+		otg_vbus_drv: otg-vbus-drv {
+			rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	sdio-pwrseq {
+		wifi_enable_h: wifi-enable-h {
+			rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		wifi_host_wake: wifi-host-wake {
+			rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
+};
+
+&pwm0 {
+	status = "okay";
+	pinctrl-0 = <&pwm0_pin_pull_down>;
+};
+
+&saradc {
+	vref-supply = <&vcc_1v8>;
+	status = "okay";
+};
+
+&sdio {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	cap-sd-highspeed;
+	cap-sdio-irq;
+	keep-power-in-suspend;
+	max-frequency = <1000000>;
+	mmc-pwrseq = <&sdio_pwrseq>;
+	non-removable;
+	sd-uhs-sdr104;
+	status = "okay";
+};
+
+&sdmmc {
+	cap-sd-highspeed;
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart4 {
+	status = "okay";
+
+	bluetooth {
+		compatible = "realtek,rtl8723bs-bt";
+		device-wake-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
+		host-wake-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+&wdt {
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi b/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
index 3e88ed4..c5acfe4 100644
--- a/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
+++ b/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
@@ -92,6 +92,16 @@
 		0xffffffff
 		0xffffffff
 		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
 
 		0x00000004
 		0x0000000a
diff --git a/arch/arm/dts/rk3328-sdram-ddr4-666.dtsi b/arch/arm/dts/rk3328-sdram-ddr4-666.dtsi
index 0859649..c5fa290 100644
--- a/arch/arm/dts/rk3328-sdram-ddr4-666.dtsi
+++ b/arch/arm/dts/rk3328-sdram-ddr4-666.dtsi
@@ -89,6 +89,16 @@
 		0xffffffff
 		0xffffffff
 		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
 
 		0x00000004
 		0x0000000c
diff --git a/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi b/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
index d63c761..07f27b2 100644
--- a/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
+++ b/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
@@ -92,6 +92,16 @@
 		0xffffffff
 		0xffffffff
 		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
 
 		0x00000004
 		0x0000000b
diff --git a/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi b/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
index df42bb2..d53d3a0 100644
--- a/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
+++ b/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
@@ -92,6 +92,16 @@
 		0xffffffff
 		0xffffffff
 		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
 
 		0x00000004
 		0x0000000b
diff --git a/arch/arm/dts/rk3399-nanopi-r4s-u-boot.dtsi b/arch/arm/dts/rk3399-nanopi-r4s-u-boot.dtsi
index cd16425..69800cc 100644
--- a/arch/arm/dts/rk3399-nanopi-r4s-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-nanopi-r4s-u-boot.dtsi
@@ -14,3 +14,25 @@
 
 #include "rk3399-nanopi4-u-boot.dtsi"
 #include "rk3399-sdram-lpddr4-100.dtsi"
+
+/ {
+	smbios {
+		compatible = "u-boot,sysinfo-smbios";
+
+		smbios {
+			system {
+				manufacturer = "FriendlyELEC";
+				product = "NanoPi R4S";
+			};
+
+			baseboard {
+				manufacturer = "FriendlyELEC";
+				product = "NanoPi R4S";
+			};
+
+			chassis {
+				manufacturer = "FriendlyELEC";
+			};
+		};
+	};
+};
diff --git a/arch/arm/dts/rk3566-radxa-cm3-io-u-boot.dtsi b/arch/arm/dts/rk3566-radxa-cm3-io-u-boot.dtsi
new file mode 100644
index 0000000..4e79173
--- /dev/null
+++ b/arch/arm/dts/rk3566-radxa-cm3-io-u-boot.dtsi
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2021 Rockchip Electronics Co., Ltd
+ */
+
+#include "rk356x-u-boot.dtsi"
+
+/ {
+	chosen {
+		stdout-path = &uart2;
+	};
+};
+
+&uart2 {
+	clock-frequency = <24000000>;
+	bootph-all;
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3566-radxa-cm3-io.dts b/arch/arm/dts/rk3566-radxa-cm3-io.dts
new file mode 100644
index 0000000..d89d526
--- /dev/null
+++ b/arch/arm/dts/rk3566-radxa-cm3-io.dts
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Radxa Limited
+ * Copyright (c) 2022 Amarula Solutions(India)
+ */
+
+/dts-v1/;
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "rk3566.dtsi"
+#include "rk3566-radxa-cm3.dtsi"
+
+/ {
+	model = "Radxa Compute Module 3(CM3) IO Board";
+	compatible = "radxa,cm3-io", "radxa,cm3", "rockchip,rk3566";
+
+	aliases {
+		mmc1 = &sdmmc0;
+	};
+
+	chosen: chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	gmac1_clkin: external-gmac1-clock {
+		compatible = "fixed-clock";
+		clock-frequency = <125000000>;
+		clock-output-names = "gmac1_clkin";
+		#clock-cells = <0>;
+	};
+
+	hdmi-con {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-1 {
+			gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_LOW>;
+			color = <LED_COLOR_ID_GREEN>;
+			function = LED_FUNCTION_ACTIVITY;
+			linux,default-trigger = "heartbeat";
+			pinctrl-names = "default";
+			pinctrl-0 = <&pi_nled_activity>;
+		};
+	};
+
+	vcc5v0_usb30: vcc5v0-usb30-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_usb30";
+		enable-active-high;
+		gpio = <&gpio3 RK_PC2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_usb30_en_h>;
+		regulator-always-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc_sys>;
+	};
+
+	vcca1v8_image: vcca1v8-image-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcca1v8_image";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc_1v8_p>;
+	};
+
+	vdda0v9_image: vdda0v9-image-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcca0v9_image";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <900000>;
+		regulator-max-microvolt = <900000>;
+		vin-supply = <&vdda_0v9>;
+	};
+};
+
+&combphy1 {
+	status = "okay";
+};
+
+&gmac1 {
+	assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
+	assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&gmac1_clkin>;
+	assigned-clock-rates = <0>, <125000000>;
+	clock_in_out = "input";
+	phy-handle = <&rgmii_phy1>;
+	phy-mode = "rgmii";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac1m0_miim
+		     &gmac1m0_tx_bus2
+		     &gmac1m0_rx_bus2
+		     &gmac1m0_rgmii_clk
+		     &gmac1m0_rgmii_bus
+		     &gmac1m0_clkinout>;
+	snps,reset-gpio = <&gpio4 RK_PC2 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	/* Reset time is 20ms, 100ms for rtl8211f */
+	snps,reset-delays-us = <0 20000 100000>;
+	tx_delay = <0x46>;
+	rx_delay = <0x2e>;
+	status = "okay";
+};
+
+&hdmi {
+	avdd-0v9-supply = <&vdda0v9_image>;
+	avdd-1v8-supply = <&vcca1v8_image>;
+	status = "okay";
+};
+
+&hdmi_in {
+	hdmi_in_vp0: endpoint {
+		remote-endpoint = <&vp0_out_hdmi>;
+	};
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
+&hdmi_sound {
+	status = "okay";
+};
+
+&mdio1 {
+	rgmii_phy1: ethernet-phy@0 {
+		compatible="ethernet-phy-ieee802.3-c22";
+		reg= <0x0>;
+	};
+};
+
+&pinctrl {
+	gmac1 {
+		gmac1m0_miim: gmac1m0-miim {
+			rockchip,pins =
+				/* gmac1_mdcm0 */
+				<3 RK_PC4 3 &pcfg_pull_none_drv_level_15>,
+				/* gmac1_mdiom0 */
+				<3 RK_PC5 3 &pcfg_pull_none_drv_level_15>;
+		};
+
+		gmac1m0_rx_bus2: gmac1m0-rx-bus2 {
+			rockchip,pins =
+				/* gmac1_rxd0m0 */
+				<3 RK_PB1 3 &pcfg_pull_none_drv_level_15>,
+				/* gmac1_rxd1m0 */
+				<3 RK_PB2 3 &pcfg_pull_none_drv_level_15>,
+				/* gmac1_rxdvcrsm0 */
+				<3 RK_PB3 3 &pcfg_pull_none_drv_level_15>;
+		};
+
+		gmac1m0_tx_bus2: gmac1m0-tx-bus2 {
+			rockchip,pins =
+				/* gmac1_txd0m0 */
+				<3 RK_PB5 3 &pcfg_pull_none_drv_level_15>,
+				/* gmac1_txd1m0 */
+				<3 RK_PB6 3 &pcfg_pull_none_drv_level_15>,
+				/* gmac1_txenm0 */
+				<3 RK_PB7 3 &pcfg_pull_none_drv_level_15>;
+		};
+
+		gmac1m0_rgmii_clk: gmac1m0-rgmii-clk {
+			rockchip,pins =
+				/* gmac1_rxclkm0 */
+				<3 RK_PA7 3 &pcfg_pull_none_drv_level_15>,
+				/* gmac1_txclkm0 */
+				<3 RK_PA6 3 &pcfg_pull_none_drv_level_15>;
+		};
+
+		gmac1m0_rgmii_bus: gmac1m0-rgmii-bus {
+			rockchip,pins =
+				/* gmac1_rxd2m0 */
+				<3 RK_PA4 3 &pcfg_pull_none_drv_level_15>,
+				/* gmac1_rxd3m0 */
+				<3 RK_PA5 3 &pcfg_pull_none_drv_level_15>,
+				/* gmac1_txd2m0 */
+				<3 RK_PA2 3 &pcfg_pull_none_drv_level_15>,
+				/* gmac1_txd3m0 */
+				<3 RK_PA3 3 &pcfg_pull_none_drv_level_15>;
+		};
+
+		gmac1m0_clkinout: gmac1m0-clkinout {
+			rockchip,pins =
+				/* gmac1_mclkinoutm0 */
+				<3 RK_PC0 3 &pcfg_pull_none_drv_level_15>;
+		};
+	};
+
+	leds {
+		pi_nled_activity: pi-nled-activity {
+			rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	sdcard {
+		sdmmc_pwren: sdmmc-pwren {
+			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	usb {
+		vcc5v0_usb30_en_h: vcc5v0-host-en-h {
+			rockchip,pins = <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&sdmmc0 {
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	disable-wp;
+	vqmmc-supply = <&vccio_sd>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det &sdmmc0_pwren>;
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&usb2phy0_host {
+	phy-supply = <&vcc5v0_usb30>;
+	status = "okay";
+};
+
+&usb2phy1_host {
+	status = "okay";
+};
+
+&usb2phy1_otg {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host1_xhci {
+	status = "okay";
+};
+
+&vop {
+	assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
+	assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+	status = "okay";
+};
+
+&vop_mmu {
+	status = "okay";
+};
+
+&vp0 {
+	vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
+		reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+		remote-endpoint = <&hdmi_in_vp0>;
+	};
+};
diff --git a/arch/arm/dts/rk3566-radxa-cm3.dtsi b/arch/arm/dts/rk3566-radxa-cm3.dtsi
new file mode 100644
index 0000000..45de263
--- /dev/null
+++ b/arch/arm/dts/rk3566-radxa-cm3.dtsi
@@ -0,0 +1,425 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Radxa Limited
+ * Copyright (c) 2022 Amarula Solutions(India)
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	compatible = "radxa,cm3", "rockchip,rk3566";
+
+	aliases {
+		mmc0 = &sdhci;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+			function = LED_FUNCTION_STATUS;
+			linux,default-trigger = "timer";
+			default-state = "on";
+			pinctrl-names = "default";
+			pinctrl-0 = <&user_led2>;
+		};
+	};
+
+	vcc_sys: vcc-sys-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+
+	vcc_1v8: vcc-1v8-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v8";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc_1v8_p>;
+	};
+
+	vcc_3v3: vcc-3v3-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_3v3";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc3v3_sys>;
+	};
+
+	vcca_1v8: vcca-1v8-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcca_1v8";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc_1v8_p>;
+	};
+
+	sdio_pwrseq: pwrseq-sdio {
+		compatible = "mmc-pwrseq-simple";
+		clocks = <&rk817 1>;
+		clock-names = "ext_clock";
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_reg_on_h>;
+		reset-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&gpu {
+	mali-supply = <&vdd_gpu_npu>;
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	vdd_cpu: regulator@1c {
+		compatible = "tcs,tcs4525";
+		reg = <0x1c>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <712500>;
+		regulator-max-microvolt = <1390000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+
+	rk817: pmic@20 {
+		compatible = "rockchip,rk817";
+		reg = <0x20>;
+		#clock-cells = <1>;
+		clock-output-names = "rk817-clkout1", "rk817-clkout2";
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int_l>;
+		rockchip,system-power-controller;
+		wakeup-source;
+
+		vcc1-supply = <&vcc_sys>;
+		vcc2-supply = <&vcc_sys>;
+		vcc3-supply = <&vcc_sys>;
+		vcc4-supply = <&vcc_sys>;
+		vcc5-supply = <&vcc_sys>;
+		vcc6-supply = <&vcc_sys>;
+		vcc7-supply = <&vcc_sys>;
+
+		regulators {
+			vdd_logic: DCDC_REG1 {
+				regulator-name = "vdd_logic";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <900000>;
+				};
+			};
+
+			vdd_gpu_npu: DCDC_REG2 {
+				regulator-name = "vdd_gpu_npu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-initial-mode = <0x2>;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vcc3v3_sys: DCDC_REG4 {
+				regulator-name = "vcc3v3_sys";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcca1v8_pmu: LDO_REG1 {
+				regulator-name = "vcca1v8_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vdda_0v9: LDO_REG2 {
+				regulator-name = "vdda_0v9";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_pmu: LDO_REG3 {
+				regulator-name = "vdda0v9_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <900000>;
+				};
+			};
+
+			vccio_acodec: LDO_REG4 {
+				regulator-name = "vccio_acodec";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-name = "vccio_sd";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_pmu: LDO_REG6 {
+				regulator-name = "vcc3v3_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcc_1v8_p: LDO_REG7 {
+				regulator-name = "vcc_1v8_p";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc1v8_dvp: LDO_REG8 {
+				regulator-name = "vcc1v8_dvp";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc2v8_dvp: LDO_REG9 {
+				regulator-name = "vcc2v8_dvp";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+		};
+	};
+};
+
+&pinctrl {
+	bluetooth {
+		bt_host_wake_h: bt-host-wake-h {
+			rockchip,pins = <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		bt_reg_on_h: bt-reg-on-h {
+			rockchip,pins = <2 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		bt_wake_host_h: bt-wake-host-h {
+			rockchip,pins = <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		pmic_int_l: pmic-int-l {
+			rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	leds {
+		user_led2: user-led2 {
+			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	wifi {
+		wifi_reg_on_h: wifi-reg-on-h {
+			rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		wifi_host_wake_h: wifi-host-wake-h {
+			rockchip,pins = <2 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pmu_io_domains {
+	pmuio1-supply = <&vcc3v3_pmu>;
+	pmuio2-supply = <&vcc_3v3>;
+	vccio1-supply = <&vccio_acodec>;
+	vccio2-supply = <&vcc_1v8>;
+	vccio3-supply = <&vccio_sd>;
+	vccio4-supply = <&vcc_1v8>;
+	vccio5-supply = <&vcc_3v3>;
+	vccio6-supply = <&vcc_3v3>;
+	vccio7-supply = <&vcc_3v3>;
+	status = "okay";
+};
+
+&saradc {
+	vref-supply = <&vcca_1v8>;
+	status = "okay";
+};
+
+&sdmmc1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	bus-width = <4>;
+	disable-wp;
+	cap-sd-highspeed;
+	cap-sdio-irq;
+	keep-power-in-suspend;
+	mmc-pwrseq = <&sdio_pwrseq>;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_clk &sdmmc1_cmd>;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc_3v3>;
+	vqmmc-supply = <&vcc_1v8>;
+	status = "okay";
+
+	wifi@1 {
+		compatible = "brcm,bcm43455-fmac";
+		reg = <1>;
+		interrupt-parent = <&gpio2>;
+		interrupts = <RK_PC1 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "host-wake";
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_host_wake_h>;
+	};
+};
+
+&sdhci {
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	mmc-hs200-1_8v;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+	vmmc-supply = <&vcc_3v3>;
+	vqmmc-supply = <&vcc_1v8>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1m0_ctsn &uart1m0_rtsn &uart1m0_xfer>;
+	status = "okay";
+
+	bluetooth {
+		compatible = "brcm,bcm4345c5";
+		clocks = <&rk817 1>;
+		clock-names = "lpo";
+		device-wakeup-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>;
+		host-wakeup-gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&bt_host_wake_h &bt_reg_on_h &bt_wake_host_h>;
+		vbat-supply = <&vcc_3v3>;
+		vddio-supply = <&vcc_1v8>;
+	};
+};
+
+&usb2phy0 {
+	status = "okay";
+};
+
+&usb2phy1 {
+	status = "okay";
+};
+
+&tsadc {
+	rockchip,hw-tshut-mode = <1>;
+	rockchip,hw-tshut-polarity = <0>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3568-evb.dts b/arch/arm/dts/rk3568-evb.dts
index 6978655..6747925 100644
--- a/arch/arm/dts/rk3568-evb.dts
+++ b/arch/arm/dts/rk3568-evb.dts
@@ -6,13 +6,22 @@
 
 /dts-v1/;
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
 #include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
 #include "rk3568.dtsi"
 
 / {
 	model = "Rockchip RK3568 EVB1 DDR4 V10 Board";
 	compatible = "rockchip,rk3568-evb1-v10", "rockchip,rk3568";
 
+	aliases {
+		ethernet0 = &gmac0;
+		ethernet1 = &gmac1;
+		mmc0 = &sdmmc0;
+		mmc1 = &sdhci;
+	};
+
 	chosen: chosen {
 		stdout-path = "serial2:1500000n8";
 	};
@@ -26,6 +35,44 @@
 		regulator-max-microvolt = <12000000>;
 	};
 
+	hdmi-con {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_work: led-0 {
+			gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
+			function = LED_FUNCTION_HEARTBEAT;
+			color = <LED_COLOR_ID_BLUE>;
+			linux,default-trigger = "heartbeat";
+			pinctrl-names = "default";
+			pinctrl-0 = <&led_work_en>;
+		};
+	};
+
+	rk809-sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,name = "Analog RK809";
+		simple-audio-card,mclk-fs = <256>;
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s1_8ch>;
+		};
+		simple-audio-card,codec {
+			sound-dai = <&rk809>;
+		};
+	};
+
 	vcc3v3_sys: vcc3v3-sys {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc3v3_sys";
@@ -46,10 +93,50 @@
 		vin-supply = <&dc_12v>;
 	};
 
+	vcc5v0_usb: vcc5v0-usb {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_usb";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	vcc5v0_usb_host: vcc5v0-usb-host {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_usb_host_en>;
+		regulator-name = "vcc5v0_usb_host";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
+	vcc5v0_usb_otg: vcc5v0-usb-otg {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_usb_otg_en>;
+		regulator-name = "vcc5v0_usb_otg";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
 	vcc3v3_lcd0_n: vcc3v3-lcd0-n {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc3v3_lcd0_n";
-		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc3v3_sys>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc3v3_lcd0_n_en>;
 
 		regulator-state-mem {
 			regulator-off-in-suspend;
@@ -59,21 +146,547 @@
 	vcc3v3_lcd1_n: vcc3v3-lcd1-n {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc3v3_lcd1_n";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc3v3_sys>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc3v3_lcd1_n_en>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&combphy0 {
+	status = "okay";
+};
+
+&combphy1 {
+	status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&gmac0 {
+	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
+	assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>;
+	assigned-clock-rates = <0>, <125000000>;
+	clock_in_out = "output";
+	phy-handle = <&rgmii_phy0>;
+	phy-mode = "rgmii-id";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac0_miim
+		     &gmac0_tx_bus2
+		     &gmac0_rx_bus2
+		     &gmac0_rgmii_clk
+		     &gmac0_rgmii_bus>;
+	status = "okay";
+};
+
+&gmac1 {
+	assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
+	assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>;
+	assigned-clock-rates = <0>, <125000000>;
+	clock_in_out = "output";
+	phy-handle = <&rgmii_phy1>;
+	phy-mode = "rgmii-id";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac1m1_miim
+		     &gmac1m1_tx_bus2
+		     &gmac1m1_rx_bus2
+		     &gmac1m1_rgmii_clk
+		     &gmac1m1_rgmii_bus>;
+	status = "okay";
+};
+
+&gpu {
+	mali-supply = <&vdd_gpu>;
+	status = "okay";
+};
+
+&hdmi {
+	avdd-0v9-supply = <&vdda0v9_image>;
+	avdd-1v8-supply = <&vcca1v8_image>;
+	status = "okay";
+};
+
+&hdmi_in {
+	hdmi_in_vp0: endpoint {
+		remote-endpoint = <&vp0_out_hdmi>;
+	};
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
+&hdmi_sound {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	vdd_cpu: regulator@1c {
+		compatible = "tcs,tcs4525";
+		reg = <0x1c>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu";
+		regulator-always-on;
 		regulator-boot-on;
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <1150000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc5v0_sys>;
 
 		regulator-state-mem {
 			regulator-off-in-suspend;
 		};
 	};
+
+	rk809: pmic@20 {
+		compatible = "rockchip,rk809";
+		reg = <0x20>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+		assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+		assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
+		#clock-cells = <1>;
+		clock-names = "mclk";
+		clocks = <&cru I2S1_MCLKOUT_TX>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int>, <&i2s1m0_mclk>;
+		rockchip,system-power-controller;
+		#sound-dai-cells = <0>;
+		vcc1-supply = <&vcc3v3_sys>;
+		vcc2-supply = <&vcc3v3_sys>;
+		vcc3-supply = <&vcc3v3_sys>;
+		vcc4-supply = <&vcc3v3_sys>;
+		vcc5-supply = <&vcc3v3_sys>;
+		vcc6-supply = <&vcc3v3_sys>;
+		vcc7-supply = <&vcc3v3_sys>;
+		vcc8-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc3v3_sys>;
+		wakeup-source;
+
+		regulators {
+			vdd_logic: DCDC_REG1 {
+				regulator-name = "vdd_logic";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_gpu: DCDC_REG2 {
+				regulator-name = "vdd_gpu";
+				regulator-always-on;
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-initial-mode = <0x2>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vdd_npu: DCDC_REG4 {
+				regulator-name = "vdd_npu";
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8: DCDC_REG5 {
+				regulator-name = "vcc_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_image: LDO_REG1 {
+				regulator-name = "vdda0v9_image";
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_0v9: LDO_REG2 {
+				regulator-name = "vdda_0v9";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_pmu: LDO_REG3 {
+				regulator-name = "vdda0v9_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <900000>;
+				};
+			};
+
+			vccio_acodec: LDO_REG4 {
+				regulator-name = "vccio_acodec";
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-name = "vccio_sd";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_pmu: LDO_REG6 {
+				regulator-name = "vcc3v3_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcca_1v8: LDO_REG7 {
+				regulator-name = "vcca_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca1v8_pmu: LDO_REG8 {
+				regulator-name = "vcca1v8_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcca1v8_image: LDO_REG9 {
+				regulator-name = "vcca1v8_image";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3: SWITCH_REG1 {
+				regulator-name = "vcc_3v3";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_sd: SWITCH_REG2 {
+				regulator-name = "vcc3v3_sd";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+
+		codec {
+			mic-in-differential;
+		};
+	};
+};
+
+&i2c1 {
+	status = "okay";
+
+	touchscreen0: goodix@14 {
+		compatible = "goodix,gt1151";
+		reg = <0x14>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PB5 IRQ_TYPE_EDGE_FALLING>;
+		AVDD28-supply = <&vcc3v3_lcd0_n>;
+		irq-gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&touch_int &touch_rst>;
+		reset-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>;
+		VDDIO-supply = <&vcc3v3_lcd0_n>;
+	};
+};
+
+&i2s0_8ch {
+	status = "okay";
+};
+
+&i2s1_8ch {
+	rockchip,trcm-sync-tx-only;
+	status = "okay";
+};
+
+&mdio0 {
+	rgmii_phy0: ethernet-phy@0 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x0>;
+		reset-assert-us = <20000>;
+		reset-deassert-us = <100000>;
+		reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&mdio1 {
+	rgmii_phy1: ethernet-phy@0 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x0>;
+		reset-assert-us = <20000>;
+		reset-deassert-us = <100000>;
+		reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&pinctrl {
+	display {
+		vcc3v3_lcd0_n_en: vcc3v3_lcd0_n_en {
+			rockchip,pins = <0 RK_PC7 0 &pcfg_pull_none>;
+		};
+		vcc3v3_lcd1_n_en: vcc3v3_lcd1_n_en {
+			rockchip,pins = <0 RK_PC5 0 &pcfg_pull_none>;
+		};
+	};
+
+	leds {
+		led_work_en: led_work_en {
+			rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		pmic_int: pmic_int {
+			rockchip,pins =
+				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	touchscreen {
+		touch_int: touch_int {
+			rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+		touch_rst: touch_rst {
+			rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	usb {
+		vcc5v0_usb_host_en: vcc5v0_usb_host_en {
+			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+		vcc5v0_usb_otg_en: vcc5v0_usb_otg_en {
+			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pmu_io_domains {
+	pmuio1-supply = <&vcc3v3_pmu>;
+	pmuio2-supply = <&vcc3v3_pmu>;
+	vccio1-supply = <&vccio_acodec>;
+	vccio2-supply = <&vcc_1v8>;
+	vccio3-supply = <&vccio_sd>;
+	vccio4-supply = <&vcc_1v8>;
+	vccio5-supply = <&vcc_3v3>;
+	vccio6-supply = <&vcc_1v8>;
+	vccio7-supply = <&vcc_3v3>;
+	status = "okay";
+};
+
+&saradc {
+	vref-supply = <&vcca_1v8>;
+	status = "okay";
 };
 
 &sdhci {
 	bus-width = <8>;
 	max-frequency = <200000000>;
 	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+	status = "okay";
+};
+
+&sdmmc0 {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc3v3_sd>;
+	vqmmc-supply = <&vccio_sd>;
+	status = "okay";
+};
+
+&tsadc {
+	rockchip,hw-tshut-mode = <1>;
+	rockchip,hw-tshut-polarity = <0>;
 	status = "okay";
 };
 
 &uart2 {
 	status = "okay";
 };
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&usb_host0_xhci {
+	extcon = <&usb2phy0>;
+	status = "okay";
+};
+
+&usb_host1_ehci {
+	status = "okay";
+};
+
+&usb_host1_ohci {
+	status = "okay";
+};
+
+&usb_host1_xhci {
+	status = "okay";
+};
+
+&usb2phy0 {
+	status = "okay";
+};
+
+&usb2phy0_host {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
+
+&usb2phy0_otg {
+	phy-supply = <&vcc5v0_usb_otg>;
+	status = "okay";
+};
+
+&usb2phy1 {
+	status = "okay";
+};
+
+&usb2phy1_host {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
+
+&usb2phy1_otg {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
+
+&vop {
+	assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
+	assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+	status = "okay";
+};
+
+&vop_mmu {
+	status = "okay";
+};
+
+&vp0 {
+	vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
+		reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+		remote-endpoint = <&hdmi_in_vp0>;
+	};
+};
diff --git a/arch/arm/dts/rk3568-rock-3a-u-boot.dtsi b/arch/arm/dts/rk3568-rock-3a-u-boot.dtsi
new file mode 100644
index 0000000..ed47efa
--- /dev/null
+++ b/arch/arm/dts/rk3568-rock-3a-u-boot.dtsi
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2021 Rockchip Electronics Co., Ltd
+ * (C) Copyright 2023 Akash Gajjar <gajjar04akash@gmail.com>
+ */
+
+#include "rk356x-u-boot.dtsi"
+
+/ {
+	chosen {
+		stdout-path = &uart2;
+		u-boot,spl-boot-order = "same-as-spl", &sdmmc0;
+	};
+};
+
+&sdmmc0 {
+	status = "okay";
+};
+
+&uart2 {
+	clock-frequency = <24000000>;
+	bootph-all;
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3568-rock-3a.dts b/arch/arm/dts/rk3568-rock-3a.dts
new file mode 100644
index 0000000..a2f2baa
--- /dev/null
+++ b/arch/arm/dts/rk3568-rock-3a.dts
@@ -0,0 +1,609 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2023 Akash Gajjar <gajjar04akash@gmail.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3568.dtsi"
+
+/ {
+	model = "Radxa ROCK3 Model A";
+	compatible = "radxa,rock3a", "rockchip,rk3568";
+
+	chosen: chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	gmac1_clkin: external-gmac1-clock {
+		compatible = "fixed-clock";
+		clock-frequency = <125000000>;
+		clock-output-names = "gmac1_clkin";
+		#clock-cells = <0>;
+	};
+
+	vcc12v_dcin: vcc12v-dcin-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc12v_dcin";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	vcc3v3_sys: vcc3v3-sys-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc5v0_sys: vcc5v0-sys-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc5v0_usb: vcc5v0-usb-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_usb";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc5v0_usb_host: vcc5v0-usb-host-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_usb_host_en>;
+		regulator-name = "vcc5v0_usb_host";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
+	vcc5v0_usb_hub: vcc5v0-usb-hub-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_usb_hub_en>;
+		regulator-name = "vcc5v0_usb_hub";
+		regulator-always-on;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
+	vcc5v0_usb_otg: vcc5v0-usb-otg-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		regulator-name = "vcc5v0_usb_otg";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
+	vcc_cam: vcc-cam-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc_cam_en>;
+		regulator-name = "vcc_cam";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc3v3_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+
+	vcc_mipi: vcc-mipi-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc_mipi_en>;
+		regulator-name = "vcc_mipi";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc3v3_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&combphy0 {
+	status = "okay";
+};
+
+&combphy1 {
+	status = "okay";
+};
+
+&combphy2 {
+	status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&gmac1 {
+	assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
+	assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&gmac1_clkin>;
+	clock_in_out = "input";
+	phy-handle = <&rgmii_phy1>;
+	phy-mode = "rgmii-id";
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	vdd_cpu: regulator@1c {
+		compatible = "tcs,tcs4525";
+		reg = <0x1c>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <1150000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc5v0_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+
+	rk809: pmic@20 {
+		compatible = "rockchip,rk809";
+		reg = <0x20>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+		assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+		assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
+		#clock-cells = <1>;
+		clock-names = "mclk";
+		clocks = <&cru I2S1_MCLKOUT_TX>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int>, <&i2s1m0_mclk>;
+		rockchip,system-power-controller;
+		#sound-dai-cells = <0>;
+		vcc1-supply = <&vcc3v3_sys>;
+		vcc2-supply = <&vcc3v3_sys>;
+		vcc3-supply = <&vcc3v3_sys>;
+		vcc4-supply = <&vcc3v3_sys>;
+		vcc5-supply = <&vcc3v3_sys>;
+		vcc6-supply = <&vcc3v3_sys>;
+		vcc7-supply = <&vcc3v3_sys>;
+		vcc8-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc3v3_sys>;
+		wakeup-source;
+
+		regulators {
+			vdd_logic: DCDC_REG1 {
+				regulator-name = "vdd_logic";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_gpu: DCDC_REG2 {
+				regulator-name = "vdd_gpu";
+				regulator-always-on;
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-initial-mode = <0x2>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vdd_npu: DCDC_REG4 {
+				regulator-name = "vdd_npu";
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8: DCDC_REG5 {
+				regulator-name = "vcc_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_image: LDO_REG1 {
+				regulator-name = "vdda0v9_image";
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_0v9: LDO_REG2 {
+				regulator-name = "vdda_0v9";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_pmu: LDO_REG3 {
+				regulator-name = "vdda0v9_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <900000>;
+				};
+			};
+
+			vccio_acodec: LDO_REG4 {
+				regulator-name = "vccio_acodec";
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-name = "vccio_sd";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_pmu: LDO_REG6 {
+				regulator-name = "vcc3v3_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcca_1v8: LDO_REG7 {
+				regulator-name = "vcca_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca1v8_pmu: LDO_REG8 {
+				regulator-name = "vcca1v8_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcca1v8_image: LDO_REG9 {
+				regulator-name = "vcca1v8_image";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3: SWITCH_REG1 {
+				regulator-name = "vcc_3v3";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_sd: SWITCH_REG2 {
+				regulator-name = "vcc3v3_sd";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+
+		codec {
+			mic-in-differential;
+		};
+	};
+};
+
+&i2c3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c3m1_xfer>;
+	status = "disabled";
+};
+
+&i2c4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c4m1_xfer>;
+	status = "disabled";
+};
+
+&i2c5 {
+	status = "okay";
+
+	hym8563: rtc@51 {
+		compatible = "haoyu,hym8563";
+		reg = <0x51>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
+		#clock-cells = <0>;
+		clock-output-names = "rtcic_32kout";
+		pinctrl-names = "default";
+		pinctrl-0 = <&hym8563_int>;
+		wakeup-source;
+	};
+};
+
+&i2s0_8ch {
+	status = "okay";
+};
+
+&i2s1_8ch {
+	rockchip,trcm-sync-tx-only;
+	status = "okay";
+};
+
+&mdio1 {
+	rgmii_phy1: ethernet-phy@0 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&eth_phy_rst>;
+		reset-assert-us = <20000>;
+		reset-deassert-us = <100000>;
+		reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&pinctrl {
+	cam {
+		vcc_cam_en: vcc_cam_en {
+			rockchip,pins = <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	display {
+		vcc_mipi_en: vcc_mipi_en {
+			rockchip,pins = <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	ethernet {
+		eth_phy_rst: eth_phy_rst {
+			rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	hym8563 {
+		hym8563_int: hym8563-int {
+			rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	leds {
+		led_user_en: led_user_en {
+			rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pcie {
+		pcie_enable_h: pcie-enable-h {
+			rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		pcie_reset_h: pcie-reset-h {
+			rockchip,pins = <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		pmic_int: pmic_int {
+			rockchip,pins =
+				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	usb {
+		vcc5v0_usb_host_en: vcc5v0_usb_host_en {
+			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+		vcc5v0_usb_hub_en: vcc5v0_usb_hub_en {
+			rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+		vcc5v0_usb_otg_en: vcc5v0_usb_otg_en {
+			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	bt {
+		bt_enable: bt-enable {
+			rockchip,pins = <4 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		bt_host_wake: bt-host-wake {
+			rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+
+		bt_wake: bt-wake {
+			rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	sdio-pwrseq {
+		wifi_enable: wifi-enable {
+			rockchip,pins = <3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pmu_io_domains {
+	pmuio1-supply = <&vcc3v3_pmu>;
+	pmuio2-supply = <&vcc3v3_pmu>;
+	vccio1-supply = <&vccio_acodec>;
+	vccio2-supply = <&vcc_1v8>;
+	vccio3-supply = <&vccio_sd>;
+	vccio4-supply = <&vcc_1v8>;
+	vccio5-supply = <&vcc_3v3>;
+	vccio6-supply = <&vcc_1v8>;
+	vccio7-supply = <&vcc_3v3>;
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&usb_host0_xhci {
+	extcon = <&usb2phy0>;
+	status = "okay";
+};
+
+&usb_host1_ehci {
+	status = "okay";
+};
+
+&usb_host1_ohci {
+	status = "okay";
+};
+
+&usb_host1_xhci {
+	status = "okay";
+};
+
+&usb2phy0 {
+	status = "okay";
+};
+
+&usb2phy0_host {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
+
+&usb2phy0_otg {
+	phy-supply = <&vcc5v0_usb_otg>;
+	status = "okay";
+};
+
+&usb2phy1 {
+	status = "okay";
+};
+
+&usb2phy1_host {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
+
+&usb2phy1_otg {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3568.dtsi b/arch/arm/dts/rk3568.dtsi
index 2bdf8c7..ba67b58 100644
--- a/arch/arm/dts/rk3568.dtsi
+++ b/arch/arm/dts/rk3568.dtsi
@@ -42,6 +42,128 @@
 		reg = <0x0 0xfe190200 0x0 0x20>;
 	};
 
+	pcie30_phy_grf: syscon@fdcb8000 {
+		compatible = "rockchip,rk3568-pcie3-phy-grf", "syscon";
+		reg = <0x0 0xfdcb8000 0x0 0x10000>;
+	};
+
+	pcie30phy: phy@fe8c0000 {
+		compatible = "rockchip,rk3568-pcie3-phy";
+		reg = <0x0 0xfe8c0000 0x0 0x20000>;
+		#phy-cells = <0>;
+		clocks = <&pmucru CLK_PCIE30PHY_REF_M>, <&pmucru CLK_PCIE30PHY_REF_N>,
+			 <&cru PCLK_PCIE30PHY>;
+		clock-names = "refclk_m", "refclk_n", "pclk";
+		resets = <&cru SRST_PCIE30PHY>;
+		reset-names = "phy";
+		rockchip,phy-grf = <&pcie30_phy_grf>;
+		status = "disabled";
+	};
+
+	pcie3x1: pcie@fe270000 {
+		compatible = "rockchip,rk3568-pcie";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		bus-range = <0x0 0xf>;
+		clocks = <&cru ACLK_PCIE30X1_MST>, <&cru ACLK_PCIE30X1_SLV>,
+			 <&cru ACLK_PCIE30X1_DBI>, <&cru PCLK_PCIE30X1>,
+			 <&cru CLK_PCIE30X1_AUX_NDFT>;
+		clock-names = "aclk_mst", "aclk_slv",
+			      "aclk_dbi", "pclk", "aux";
+		device_type = "pci";
+		interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &pcie3x1_intc 0>,
+				<0 0 0 2 &pcie3x1_intc 1>,
+				<0 0 0 3 &pcie3x1_intc 2>,
+				<0 0 0 4 &pcie3x1_intc 3>;
+		linux,pci-domain = <1>;
+		num-ib-windows = <6>;
+		num-ob-windows = <2>;
+		max-link-speed = <3>;
+		msi-map = <0x0 &gic 0x1000 0x1000>;
+		num-lanes = <1>;
+		phys = <&pcie30phy>;
+		phy-names = "pcie-phy";
+		power-domains = <&power RK3568_PD_PIPE>;
+		reg = <0x3 0xc0400000 0x0 0x00400000>,
+		      <0x0 0xfe270000 0x0 0x00010000>,
+		      <0x3 0x7f000000 0x0 0x01000000>;
+		ranges = <0x01000000 0x0 0x3ef00000 0x3 0x7ef00000 0x0 0x00100000>,
+			 <0x02000000 0x0 0x00000000 0x3 0x40000000 0x0 0x3ef00000>;
+		reg-names = "dbi", "apb", "config";
+		resets = <&cru SRST_PCIE30X1_POWERUP>;
+		reset-names = "pipe";
+		/* bifurcation; lane1 when using 1+1 */
+		status = "disabled";
+
+		pcie3x1_intc: legacy-interrupt-controller {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <1>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SPI 157 IRQ_TYPE_EDGE_RISING>;
+		};
+	};
+
+	pcie3x2: pcie@fe280000 {
+		compatible = "rockchip,rk3568-pcie";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		bus-range = <0x0 0xf>;
+		clocks = <&cru ACLK_PCIE30X2_MST>, <&cru ACLK_PCIE30X2_SLV>,
+			 <&cru ACLK_PCIE30X2_DBI>, <&cru PCLK_PCIE30X2>,
+			 <&cru CLK_PCIE30X2_AUX_NDFT>;
+		clock-names = "aclk_mst", "aclk_slv",
+			      "aclk_dbi", "pclk", "aux";
+		device_type = "pci";
+		interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &pcie3x2_intc 0>,
+				<0 0 0 2 &pcie3x2_intc 1>,
+				<0 0 0 3 &pcie3x2_intc 2>,
+				<0 0 0 4 &pcie3x2_intc 3>;
+		linux,pci-domain = <2>;
+		num-ib-windows = <6>;
+		num-ob-windows = <2>;
+		max-link-speed = <3>;
+		msi-map = <0x0 &gic 0x2000 0x1000>;
+		num-lanes = <2>;
+		phys = <&pcie30phy>;
+		phy-names = "pcie-phy";
+		power-domains = <&power RK3568_PD_PIPE>;
+		reg = <0x3 0xc0800000 0x0 0x00400000>,
+		      <0x0 0xfe280000 0x0 0x00010000>,
+		      <0x3 0xbf000000 0x0 0x01000000>;
+		ranges = <0x01000000 0x0 0x3ef00000 0x3 0xbef00000 0x0 0x00100000>,
+			 <0x02000000 0x0 0x00000000 0x3 0x80000000 0x0 0x3ef00000>;
+		reg-names = "dbi", "apb", "config";
+		resets = <&cru SRST_PCIE30X2_POWERUP>;
+		reset-names = "pipe";
+		/* bifurcation; lane0 when using 1+1 */
+		status = "disabled";
+
+		pcie3x2_intc: legacy-interrupt-controller {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <1>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SPI 162 IRQ_TYPE_EDGE_RISING>;
+		};
+	};
+
 	gmac0: ethernet@fe2a0000 {
 		compatible = "rockchip,rk3568-gmac", "snps,dwmac-4.20a";
 		reg = <0x0 0xfe2a0000 0x0 0x10000>;
diff --git a/arch/arm/dts/rk356x-u-boot.dtsi b/arch/arm/dts/rk356x-u-boot.dtsi
index 580e576..ecf88e0 100644
--- a/arch/arm/dts/rk356x-u-boot.dtsi
+++ b/arch/arm/dts/rk356x-u-boot.dtsi
@@ -20,6 +20,23 @@
 		bootph-all;
 		status = "okay";
 	};
+
+	otp: nvmem@fe38c000 {
+		compatible = "rockchip,rk3568-otp";
+		reg = <0x0 0xfe38c000 0x0 0x4000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		status = "okay";
+
+		cpu_id: id@a {
+			reg = <0x0a 0x10>;
+		};
+	};
+};
+
+&combphy1 {
+	/delete-property/ assigned-clocks;
+	/delete-property/ assigned-clock-rates;
 };
 
 &cru {
diff --git a/arch/arm/dts/rk356x.dtsi b/arch/arm/dts/rk356x.dtsi
index 319981c..6492ace 100644
--- a/arch/arm/dts/rk356x.dtsi
+++ b/arch/arm/dts/rk356x.dtsi
@@ -592,6 +592,46 @@
 		status = "disabled";
 	};
 
+	vpu: video-codec@fdea0400 {
+		compatible = "rockchip,rk3568-vpu";
+		reg = <0x0 0xfdea0000 0x0 0x800>;
+		interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+		clock-names = "aclk", "hclk";
+		iommus = <&vdpu_mmu>;
+		power-domains = <&power RK3568_PD_VPU>;
+	};
+
+	vdpu_mmu: iommu@fdea0800 {
+		compatible = "rockchip,rk3568-iommu";
+		reg = <0x0 0xfdea0800 0x0 0x40>;
+		interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+		clock-names = "aclk", "iface";
+		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+		power-domains = <&power RK3568_PD_VPU>;
+		#iommu-cells = <0>;
+	};
+
+	vepu: video-codec@fdee0000 {
+		compatible = "rockchip,rk3568-vepu";
+		reg = <0x0 0xfdee0000 0x0 0x800>;
+		interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_JENC>, <&cru HCLK_JENC>;
+		clock-names = "aclk", "hclk";
+		iommus = <&vepu_mmu>;
+		power-domains = <&power RK3568_PD_RGA>;
+	};
+
+	vepu_mmu: iommu@fdee0800 {
+		compatible = "rockchip,rk3568-iommu";
+		reg = <0x0 0xfdee0800 0x0 0x40>;
+		interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_JENC>, <&cru HCLK_JENC>;
+		clock-names = "aclk", "iface";
+		power-domains = <&power RK3568_PD_RGA>;
+		#iommu-cells = <0>;
+	};
+
 	sdmmc2: mmc@fe000000 {
 		compatible = "rockchip,rk3568-dw-mshc", "rockchip,rk3288-dw-mshc";
 		reg = <0x0 0xfe000000 0x0 0x4000>;
@@ -697,6 +737,62 @@
 		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
+	};
+
+	dsi0: dsi@fe060000 {
+		compatible = "rockchip,rk3568-mipi-dsi", "snps,dw-mipi-dsi";
+		reg = <0x00 0xfe060000 0x00 0x10000>;
+		interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+		clock-names = "pclk", "hclk";
+		clocks = <&cru PCLK_DSITX_0>, <&cru HCLK_VO>;
+		phy-names = "dphy";
+		phys = <&dsi_dphy0>;
+		power-domains = <&power RK3568_PD_VO>;
+		reset-names = "apb";
+		resets = <&cru SRST_P_DSITX_0>;
+		rockchip,grf = <&grf>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			dsi0_in: port@0 {
+				reg = <0>;
+			};
+
+			dsi0_out: port@1 {
+				reg = <1>;
+			};
+		};
+	};
+
+	dsi1: dsi@fe070000 {
+		compatible = "rockchip,rk3568-mipi-dsi", "snps,dw-mipi-dsi";
+		reg = <0x0 0xfe070000 0x0 0x10000>;
+		interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+		clock-names = "pclk", "hclk";
+		clocks = <&cru PCLK_DSITX_1>, <&cru HCLK_VO>;
+		phy-names = "dphy";
+		phys = <&dsi_dphy1>;
+		power-domains = <&power RK3568_PD_VO>;
+		reset-names = "apb";
+		resets = <&cru SRST_P_DSITX_1>;
+		rockchip,grf = <&grf>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			dsi1_in: port@0 {
+				reg = <0>;
+			};
+
+			dsi1_out: port@1 {
+				reg = <1>;
+			};
+		};
 	};
 
 	hdmi: hdmi@fe0a0000 {
@@ -953,20 +1049,6 @@
 		status = "disabled";
 	};
 
-	spdif: spdif@fe460000 {
-		compatible = "rockchip,rk3568-spdif";
-		reg = <0x0 0xfe460000 0x0 0x1000>;
-		interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
-		clock-names = "mclk", "hclk";
-		clocks = <&cru MCLK_SPDIF_8CH>, <&cru HCLK_SPDIF_8CH>;
-		dmas = <&dmac1 1>;
-		dma-names = "tx";
-		pinctrl-names = "default";
-		pinctrl-0 = <&spdifm0_tx>;
-		#sound-dai-cells = <0>;
-		status = "disabled";
-	};
-
 	i2s0_8ch: i2s@fe400000 {
 		compatible = "rockchip,rk3568-i2s-tdm";
 		reg = <0x0 0xfe400000 0x0 0x1000>;
@@ -1009,6 +1091,28 @@
 		status = "disabled";
 	};
 
+	i2s2_2ch: i2s@fe420000 {
+		compatible = "rockchip,rk3568-i2s-tdm";
+		reg = <0x0 0xfe420000 0x0 0x1000>;
+		interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+		assigned-clocks = <&cru CLK_I2S2_2CH_SRC>;
+		assigned-clock-rates = <1188000000>;
+		clocks = <&cru MCLK_I2S2_2CH>, <&cru MCLK_I2S2_2CH>, <&cru HCLK_I2S2_2CH>;
+		clock-names = "mclk_tx", "mclk_rx", "hclk";
+		dmas = <&dmac1 4>, <&dmac1 5>;
+		dma-names = "tx", "rx";
+		resets = <&cru SRST_M_I2S2_2CH>;
+		reset-names = "m";
+		rockchip,grf = <&grf>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2s2m0_sclktx
+				&i2s2m0_lrcktx
+				&i2s2m0_sdi
+				&i2s2m0_sdo>;
+		#sound-dai-cells = <0>;
+		status = "disabled";
+	};
+
 	i2s3_2ch: i2s@fe430000 {
 		compatible = "rockchip,rk3568-i2s-tdm";
 		reg = <0x0 0xfe430000 0x0 0x1000>;
@@ -1046,6 +1150,20 @@
 		status = "disabled";
 	};
 
+	spdif: spdif@fe460000 {
+		compatible = "rockchip,rk3568-spdif";
+		reg = <0x0 0xfe460000 0x0 0x1000>;
+		interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+		clock-names = "mclk", "hclk";
+		clocks = <&cru MCLK_SPDIF_8CH>, <&cru HCLK_SPDIF_8CH>;
+		dmas = <&dmac1 1>;
+		dma-names = "tx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&spdifm0_tx>;
+		#sound-dai-cells = <0>;
+		status = "disabled";
+	};
+
 	dmac0: dma-controller@fe530000 {
 		compatible = "arm,pl330", "arm,primecell";
 		reg = <0x0 0xfe530000 0x0 0x4000>;
@@ -1594,6 +1712,42 @@
 		status = "disabled";
 	};
 
+	csi_dphy: phy@fe870000 {
+		compatible = "rockchip,rk3568-csi-dphy";
+		reg = <0x0 0xfe870000 0x0 0x10000>;
+		clocks = <&cru PCLK_MIPICSIPHY>;
+		clock-names = "pclk";
+		#phy-cells = <0>;
+		resets = <&cru SRST_P_MIPICSIPHY>;
+		reset-names = "apb";
+		rockchip,grf = <&grf>;
+		status = "disabled";
+	};
+
+	dsi_dphy0: mipi-dphy@fe850000 {
+		compatible = "rockchip,rk3568-dsi-dphy";
+		reg = <0x0 0xfe850000 0x0 0x10000>;
+		clock-names = "ref", "pclk";
+		clocks = <&pmucru CLK_MIPIDSIPHY0_REF>, <&cru PCLK_MIPIDSIPHY0>;
+		#phy-cells = <0>;
+		power-domains = <&power RK3568_PD_VO>;
+		reset-names = "apb";
+		resets = <&cru SRST_P_MIPIDSIPHY0>;
+		status = "disabled";
+	};
+
+	dsi_dphy1: mipi-dphy@fe860000 {
+		compatible = "rockchip,rk3568-dsi-dphy";
+		reg = <0x0 0xfe860000 0x0 0x10000>;
+		clock-names = "ref", "pclk";
+		clocks = <&pmucru CLK_MIPIDSIPHY1_REF>, <&cru PCLK_MIPIDSIPHY1>;
+		#phy-cells = <0>;
+		power-domains = <&power RK3568_PD_VO>;
+		reset-names = "apb";
+		resets = <&cru SRST_P_MIPIDSIPHY1>;
+		status = "disabled";
+	};
+
 	usb2phy0: usb2phy@fe8a0000 {
 		compatible = "rockchip,rk3568-usb2phy";
 		reg = <0x0 0xfe8a0000 0x0 0x10000>;
@@ -1652,6 +1806,7 @@
 			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&pmucru PCLK_GPIO0>, <&pmucru DBCLK_GPIO0>;
 			gpio-controller;
+			gpio-ranges = <&pinctrl 0 0 32>;
 			#gpio-cells = <2>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
@@ -1663,6 +1818,7 @@
 			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>;
 			gpio-controller;
+			gpio-ranges = <&pinctrl 0 32 32>;
 			#gpio-cells = <2>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
@@ -1674,6 +1830,7 @@
 			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>;
 			gpio-controller;
+			gpio-ranges = <&pinctrl 0 64 32>;
 			#gpio-cells = <2>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
@@ -1685,6 +1842,7 @@
 			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cru PCLK_GPIO3>, <&cru DBCLK_GPIO3>;
 			gpio-controller;
+			gpio-ranges = <&pinctrl 0 96 32>;
 			#gpio-cells = <2>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
@@ -1696,6 +1854,7 @@
 			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cru PCLK_GPIO4>, <&cru DBCLK_GPIO4>;
 			gpio-controller;
+			gpio-ranges = <&pinctrl 0 128 32>;
 			#gpio-cells = <2>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
diff --git a/arch/arm/dts/rk3588-edgeble-neu6a-io-u-boot.dtsi b/arch/arm/dts/rk3588-edgeble-neu6a-io-u-boot.dtsi
new file mode 100644
index 0000000..3235bd3
--- /dev/null
+++ b/arch/arm/dts/rk3588-edgeble-neu6a-io-u-boot.dtsi
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#include "rk3588-u-boot.dtsi"
+
+/ {
+	aliases {
+		mmc0 = &sdmmc;
+	};
+
+	chosen {
+		stdout-path = &uart2;
+		u-boot,spl-boot-order = &sdmmc;
+	};
+};
+
+&sdmmc {
+	bus-width = <4>;
+	bootph-all;
+	u-boot,spl-fifo-mode;
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3588-edgeble-neu6a-io.dts b/arch/arm/dts/rk3588-edgeble-neu6a-io.dts
new file mode 100644
index 0000000..b515438
--- /dev/null
+++ b/arch/arm/dts/rk3588-edgeble-neu6a-io.dts
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+/dts-v1/;
+#include "rk3588.dtsi"
+#include "rk3588-edgeble-neu6a.dtsi"
+
+/ {
+	model = "Edgeble Neu6A IO Board";
+	compatible = "edgeble,neural-compute-module-6a-io",
+		     "edgeble,neural-compute-module-6a", "rockchip,rk3588";
+
+	aliases {
+		serial2 = &uart2;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+};
+
+&uart2 {
+	pinctrl-0 = <&uart2m0_xfer>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3588-edgeble-neu6a.dtsi b/arch/arm/dts/rk3588-edgeble-neu6a.dtsi
new file mode 100644
index 0000000..38e1a1e
--- /dev/null
+++ b/arch/arm/dts/rk3588-edgeble-neu6a.dtsi
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+/ {
+	compatible = "edgeble,neural-compute-module-6a", "rockchip,rk3588";
+
+	aliases {
+		mmc0 = &sdhci;
+	};
+
+	vcc12v_dcin: vcc12v-dcin-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc12v_dcin";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+};
+
+&sdhci {
+	bus-width = <8>;
+	no-sdio;
+	no-sd;
+	non-removable;
+	max-frequency = <200000000>;
+	mmc-hs400-1_8v;
+	mmc-hs400-enhanced-strobe;
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3588-pinctrl.dtsi b/arch/arm/dts/rk3588-pinctrl.dtsi
new file mode 100644
index 0000000..244c66f
--- /dev/null
+++ b/arch/arm/dts/rk3588-pinctrl.dtsi
@@ -0,0 +1,516 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ */
+
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rockchip-pinconf.dtsi"
+
+/*
+ * This file is auto generated by pin2dts tool, please keep these code
+ * by adding changes at end of this file.
+ */
+&pinctrl {
+	clk32k {
+		/omit-if-no-ref/
+		clk32k_out1: clk32k-out1 {
+			rockchip,pins =
+				/* clk32k_out1 */
+				<2 RK_PC5 1 &pcfg_pull_none>;
+		};
+
+	};
+
+	eth0 {
+		/omit-if-no-ref/
+		eth0_pins: eth0-pins {
+			rockchip,pins =
+				/* eth0_refclko_25m */
+				<2 RK_PC3 1 &pcfg_pull_none>;
+		};
+
+	};
+
+	fspi {
+		/omit-if-no-ref/
+		fspim1_pins: fspim1-pins {
+			rockchip,pins =
+				/* fspi_clk_m1 */
+				<2 RK_PB3 3 &pcfg_pull_up_drv_level_2>,
+				/* fspi_cs0n_m1 */
+				<2 RK_PB4 3 &pcfg_pull_up_drv_level_2>,
+				/* fspi_d0_m1 */
+				<2 RK_PA6 3 &pcfg_pull_up_drv_level_2>,
+				/* fspi_d1_m1 */
+				<2 RK_PA7 3 &pcfg_pull_up_drv_level_2>,
+				/* fspi_d2_m1 */
+				<2 RK_PB0 3 &pcfg_pull_up_drv_level_2>,
+				/* fspi_d3_m1 */
+				<2 RK_PB1 3 &pcfg_pull_up_drv_level_2>;
+		};
+
+		/omit-if-no-ref/
+		fspim1_cs1: fspim1-cs1 {
+			rockchip,pins =
+				/* fspi_cs1n_m1 */
+				<2 RK_PB5 3 &pcfg_pull_up_drv_level_2>;
+		};
+	};
+
+	gmac0 {
+		/omit-if-no-ref/
+		gmac0_miim: gmac0-miim {
+			rockchip,pins =
+				/* gmac0_mdc */
+				<4 RK_PC4 1 &pcfg_pull_none>,
+				/* gmac0_mdio */
+				<4 RK_PC5 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac0_clkinout: gmac0-clkinout {
+			rockchip,pins =
+				/* gmac0_mclkinout */
+				<4 RK_PC3 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac0_rx_bus2: gmac0-rx-bus2 {
+			rockchip,pins =
+				/* gmac0_rxd0 */
+				<2 RK_PC1 1 &pcfg_pull_none>,
+				/* gmac0_rxd1 */
+				<2 RK_PC2 1 &pcfg_pull_none>,
+				/* gmac0_rxdv_crs */
+				<4 RK_PC2 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac0_tx_bus2: gmac0-tx-bus2 {
+			rockchip,pins =
+				/* gmac0_txd0 */
+				<2 RK_PB6 1 &pcfg_pull_none>,
+				/* gmac0_txd1 */
+				<2 RK_PB7 1 &pcfg_pull_none>,
+				/* gmac0_txen */
+				<2 RK_PC0 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac0_rgmii_clk: gmac0-rgmii-clk {
+			rockchip,pins =
+				/* gmac0_rxclk */
+				<2 RK_PB0 1 &pcfg_pull_none>,
+				/* gmac0_txclk */
+				<2 RK_PB3 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac0_rgmii_bus: gmac0-rgmii-bus {
+			rockchip,pins =
+				/* gmac0_rxd2 */
+				<2 RK_PA6 1 &pcfg_pull_none>,
+				/* gmac0_rxd3 */
+				<2 RK_PA7 1 &pcfg_pull_none>,
+				/* gmac0_txd2 */
+				<2 RK_PB1 1 &pcfg_pull_none>,
+				/* gmac0_txd3 */
+				<2 RK_PB2 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac0_ppsclk: gmac0-ppsclk {
+			rockchip,pins =
+				/* gmac0_ppsclk */
+				<2 RK_PC4 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac0_ppstring: gmac0-ppstring {
+			rockchip,pins =
+				/* gmac0_ppstring */
+				<2 RK_PB5 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac0_ptp_refclk: gmac0-ptp-refclk {
+			rockchip,pins =
+				/* gmac0_ptp_refclk */
+				<2 RK_PB4 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac0_txer: gmac0-txer {
+			rockchip,pins =
+				/* gmac0_txer */
+				<4 RK_PC6 1 &pcfg_pull_none>;
+		};
+
+	};
+
+	hdmi {
+		/omit-if-no-ref/
+		hdmim0_tx1_cec: hdmim0-tx1-cec {
+			rockchip,pins =
+				/* hdmim0_tx1_cec */
+				<2 RK_PC4 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim0_tx1_scl: hdmim0-tx1-scl {
+			rockchip,pins =
+				/* hdmim0_tx1_scl */
+				<2 RK_PB5 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim0_tx1_sda: hdmim0-tx1-sda {
+			rockchip,pins =
+				/* hdmim0_tx1_sda */
+				<2 RK_PB4 4 &pcfg_pull_none>;
+		};
+	};
+
+	i2c0 {
+		/omit-if-no-ref/
+		i2c0m1_xfer: i2c0m1-xfer {
+			rockchip,pins =
+				/* i2c0_scl_m1 */
+				<4 RK_PC5 9 &pcfg_pull_none_smt>,
+				/* i2c0_sda_m1 */
+				<4 RK_PC6 9 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2c2 {
+		/omit-if-no-ref/
+		i2c2m1_xfer: i2c2m1-xfer {
+			rockchip,pins =
+				/* i2c2_scl_m1 */
+				<2 RK_PC1 9 &pcfg_pull_none_smt>,
+				/* i2c2_sda_m1 */
+				<2 RK_PC0 9 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2c3 {
+		/omit-if-no-ref/
+		i2c3m3_xfer: i2c3m3-xfer {
+			rockchip,pins =
+				/* i2c3_scl_m3 */
+				<2 RK_PB2 9 &pcfg_pull_none_smt>,
+				/* i2c3_sda_m3 */
+				<2 RK_PB3 9 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2c4 {
+		/omit-if-no-ref/
+		i2c4m1_xfer: i2c4m1-xfer {
+			rockchip,pins =
+				/* i2c4_scl_m1 */
+				<2 RK_PB5 9 &pcfg_pull_none_smt>,
+				/* i2c4_sda_m1 */
+				<2 RK_PB4 9 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2c5 {
+		/omit-if-no-ref/
+		i2c5m4_xfer: i2c5m4-xfer {
+			rockchip,pins =
+				/* i2c5_scl_m4 */
+				<2 RK_PB6 9 &pcfg_pull_none_smt>,
+				/* i2c5_sda_m4 */
+				<2 RK_PB7 9 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2c6 {
+		/omit-if-no-ref/
+		i2c6m2_xfer: i2c6m2-xfer {
+			rockchip,pins =
+				/* i2c6_scl_m2 */
+				<2 RK_PC3 9 &pcfg_pull_none_smt>,
+				/* i2c6_sda_m2 */
+				<2 RK_PC2 9 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2c7 {
+		/omit-if-no-ref/
+		i2c7m1_xfer: i2c7m1-xfer {
+			rockchip,pins =
+				/* i2c7_scl_m1 */
+				<4 RK_PC3 9 &pcfg_pull_none_smt>,
+				/* i2c7_sda_m1 */
+				<4 RK_PC4 9 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2c8 {
+		/omit-if-no-ref/
+		i2c8m1_xfer: i2c8m1-xfer {
+			rockchip,pins =
+				/* i2c8_scl_m1 */
+				<2 RK_PB0 9 &pcfg_pull_none_smt>,
+				/* i2c8_sda_m1 */
+				<2 RK_PB1 9 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2s2 {
+		/omit-if-no-ref/
+		i2s2m0_lrck: i2s2m0-lrck {
+			rockchip,pins =
+				/* i2s2m0_lrck */
+				<2 RK_PC0 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s2m0_mclk: i2s2m0-mclk {
+			rockchip,pins =
+				/* i2s2m0_mclk */
+				<2 RK_PB6 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s2m0_sclk: i2s2m0-sclk {
+			rockchip,pins =
+				/* i2s2m0_sclk */
+				<2 RK_PB7 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s2m0_sdi: i2s2m0-sdi {
+			rockchip,pins =
+				/* i2s2m0_sdi */
+				<2 RK_PC3 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s2m0_sdo: i2s2m0-sdo {
+			rockchip,pins =
+				/* i2s2m0_sdo */
+				<4 RK_PC3 2 &pcfg_pull_none>;
+		};
+	};
+
+	pwm2 {
+		/omit-if-no-ref/
+		pwm2m2_pins: pwm2m2-pins {
+			rockchip,pins =
+				/* pwm2_m2 */
+				<4 RK_PC2 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm4 {
+		/omit-if-no-ref/
+		pwm4m1_pins: pwm4m1-pins {
+			rockchip,pins =
+				/* pwm4_m1 */
+				<4 RK_PC3 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm5 {
+		/omit-if-no-ref/
+		pwm5m2_pins: pwm5m2-pins {
+			rockchip,pins =
+				/* pwm5_m2 */
+				<4 RK_PC4 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm6 {
+		/omit-if-no-ref/
+		pwm6m2_pins: pwm6m2-pins {
+			rockchip,pins =
+				/* pwm6_m2 */
+				<4 RK_PC5 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm7 {
+		/omit-if-no-ref/
+		pwm7m3_pins: pwm7m3-pins {
+			rockchip,pins =
+				/* pwm7_ir_m3 */
+				<4 RK_PC6 11 &pcfg_pull_none>;
+		};
+	};
+
+	sdio {
+		/omit-if-no-ref/
+		sdiom0_pins: sdiom0-pins {
+			rockchip,pins =
+				/* sdio_clk_m0 */
+				<2 RK_PB3 2 &pcfg_pull_none>,
+				/* sdio_cmd_m0 */
+				<2 RK_PB2 2 &pcfg_pull_none>,
+				/* sdio_d0_m0 */
+				<2 RK_PA6 2 &pcfg_pull_none>,
+				/* sdio_d1_m0 */
+				<2 RK_PA7 2 &pcfg_pull_none>,
+				/* sdio_d2_m0 */
+				<2 RK_PB0 2 &pcfg_pull_none>,
+				/* sdio_d3_m0 */
+				<2 RK_PB1 2 &pcfg_pull_none>;
+		};
+	};
+
+	spi1 {
+		/omit-if-no-ref/
+		spi1m0_pins: spi1m0-pins {
+			rockchip,pins =
+				/* spi1_clk_m0 */
+				<2 RK_PC0 8 &pcfg_pull_up_drv_level_1>,
+				/* spi1_miso_m0 */
+				<2 RK_PC1 8 &pcfg_pull_up_drv_level_1>,
+				/* spi1_mosi_m0 */
+				<2 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi1m0_cs0: spi1m0-cs0 {
+			rockchip,pins =
+				/* spi1_cs0_m0 */
+				<2 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi1m0_cs1: spi1m0-cs1 {
+			rockchip,pins =
+				/* spi1_cs1_m0 */
+				<2 RK_PC4 8 &pcfg_pull_up_drv_level_1>;
+		};
+	};
+
+	spi3 {
+		/omit-if-no-ref/
+		spi3m0_pins: spi3m0-pins {
+			rockchip,pins =
+				/* spi3_clk_m0 */
+				<4 RK_PC6 8 &pcfg_pull_up_drv_level_1>,
+				/* spi3_miso_m0 */
+				<4 RK_PC4 8 &pcfg_pull_up_drv_level_1>,
+				/* spi3_mosi_m0 */
+				<4 RK_PC5 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi3m0_cs0: spi3m0-cs0 {
+			rockchip,pins =
+				/* spi3_cs0_m0 */
+				<4 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi3m0_cs1: spi3m0-cs1 {
+			rockchip,pins =
+				/* spi3_cs1_m0 */
+				<4 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
+		};
+	};
+
+	uart1 {
+		/omit-if-no-ref/
+		uart1m0_xfer: uart1m0-xfer {
+			rockchip,pins =
+				/* uart1_rx_m0 */
+				<2 RK_PB6 10 &pcfg_pull_up>,
+				/* uart1_tx_m0 */
+				<2 RK_PB7 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart1m0_ctsn: uart1m0-ctsn {
+			rockchip,pins =
+				/* uart1m0_ctsn */
+				<2 RK_PC1 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart1m0_rtsn: uart1m0-rtsn {
+			rockchip,pins =
+				/* uart1m0_rtsn */
+				<2 RK_PC0 10 &pcfg_pull_none>;
+		};
+	};
+
+	uart6 {
+		/omit-if-no-ref/
+		uart6m0_xfer: uart6m0-xfer {
+			rockchip,pins =
+				/* uart6_rx_m0 */
+				<2 RK_PA6 10 &pcfg_pull_up>,
+				/* uart6_tx_m0 */
+				<2 RK_PA7 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart6m0_ctsn: uart6m0-ctsn {
+			rockchip,pins =
+				/* uart6m0_ctsn */
+				<2 RK_PB1 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart6m0_rtsn: uart6m0-rtsn {
+			rockchip,pins =
+				/* uart6m0_rtsn */
+				<2 RK_PB0 10 &pcfg_pull_none>;
+		};
+	};
+
+	uart7 {
+		/omit-if-no-ref/
+		uart7m0_xfer: uart7m0-xfer {
+			rockchip,pins =
+				/* uart7_rx_m0 */
+				<2 RK_PB4 10 &pcfg_pull_up>,
+				/* uart7_tx_m0 */
+				<2 RK_PB5 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart7m0_ctsn: uart7m0-ctsn {
+			rockchip,pins =
+				/* uart7m0_ctsn */
+				<4 RK_PC6 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart7m0_rtsn: uart7m0-rtsn {
+			rockchip,pins =
+				/* uart7m0_rtsn */
+				<4 RK_PC2 10 &pcfg_pull_none>;
+		};
+	};
+
+	uart9 {
+		/omit-if-no-ref/
+		uart9m0_xfer: uart9m0-xfer {
+			rockchip,pins =
+				/* uart9_rx_m0 */
+				<2 RK_PC4 10 &pcfg_pull_up>,
+				/* uart9_tx_m0 */
+				<2 RK_PC2 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart9m0_ctsn: uart9m0-ctsn {
+			rockchip,pins =
+				/* uart9m0_ctsn */
+				<4 RK_PC5 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart9m0_rtsn: uart9m0-rtsn {
+			rockchip,pins =
+				/* uart9m0_rtsn */
+				<4 RK_PC4 10 &pcfg_pull_none>;
+		};
+	};
+};
diff --git a/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi b/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi
new file mode 100644
index 0000000..bee4c32
--- /dev/null
+++ b/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Collabora Ltd.
+ */
+
+#include "rk3588-u-boot.dtsi"
+
+/ {
+	aliases {
+		mmc0 = &sdmmc;
+	};
+
+	chosen {
+		u-boot,spl-boot-order = &sdmmc;
+	};
+};
+
+&sdmmc {
+	bus-width = <4>;
+	bootph-pre-ram;
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3588-rock-5b.dts b/arch/arm/dts/rk3588-rock-5b.dts
new file mode 100644
index 0000000..95805cb
--- /dev/null
+++ b/arch/arm/dts/rk3588-rock-5b.dts
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include "rk3588.dtsi"
+
+/ {
+	model = "Radxa ROCK 5 Model B";
+	compatible = "radxa,rock-5b", "rockchip,rk3588";
+
+	aliases {
+		mmc0 = &sdhci;
+		serial2 = &uart2;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	vcc5v0_sys: vcc5v0-sys-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+};
+
+&sdhci {
+	bus-width = <8>;
+	no-sdio;
+	no-sd;
+	non-removable;
+	max-frequency = <200000000>;
+	mmc-hs400-1_8v;
+	mmc-hs400-enhanced-strobe;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-0 = <&uart2m0_xfer>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3588-u-boot.dtsi b/arch/arm/dts/rk3588-u-boot.dtsi
new file mode 100644
index 0000000..4c8ac80
--- /dev/null
+++ b/arch/arm/dts/rk3588-u-boot.dtsi
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#include "rockchip-u-boot.dtsi"
+#include "rk3588s-u-boot.dtsi"
diff --git a/arch/arm/dts/rk3588.dtsi b/arch/arm/dts/rk3588.dtsi
new file mode 100644
index 0000000..d085e57
--- /dev/null
+++ b/arch/arm/dts/rk3588.dtsi
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ */
+
+#include "rk3588s.dtsi"
+#include "rk3588-pinctrl.dtsi"
+
+/ {
+	gmac0: ethernet@fe1b0000 {
+		compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
+		reg = <0x0 0xfe1b0000 0x0 0x10000>;
+		interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = "macirq", "eth_wake_irq";
+		clocks = <&cru CLK_GMAC_125M>, <&cru CLK_GMAC_50M>,
+			 <&cru PCLK_GMAC0>, <&cru ACLK_GMAC0>,
+			 <&cru CLK_GMAC0_PTP_REF>;
+		clock-names = "stmmaceth", "clk_mac_ref",
+			      "pclk_mac", "aclk_mac",
+			      "ptp_ref";
+		power-domains = <&power RK3588_PD_GMAC>;
+		resets = <&cru SRST_A_GMAC0>;
+		reset-names = "stmmaceth";
+		rockchip,grf = <&sys_grf>;
+		rockchip,php-grf = <&php_grf>;
+		snps,axi-config = <&gmac0_stmmac_axi_setup>;
+		snps,mixed-burst;
+		snps,mtl-rx-config = <&gmac0_mtl_rx_setup>;
+		snps,mtl-tx-config = <&gmac0_mtl_tx_setup>;
+		snps,tso;
+		status = "disabled";
+
+		mdio0: mdio {
+			compatible = "snps,dwmac-mdio";
+			#address-cells = <0x1>;
+			#size-cells = <0x0>;
+		};
+
+		gmac0_stmmac_axi_setup: stmmac-axi-config {
+			snps,blen = <0 0 0 0 16 8 4>;
+			snps,wr_osr_lmt = <4>;
+			snps,rd_osr_lmt = <8>;
+		};
+
+		gmac0_mtl_rx_setup: rx-queues-config {
+			snps,rx-queues-to-use = <2>;
+			queue0 {};
+			queue1 {};
+		};
+
+		gmac0_mtl_tx_setup: tx-queues-config {
+			snps,tx-queues-to-use = <2>;
+			queue0 {};
+			queue1 {};
+		};
+	};
+};
diff --git a/arch/arm/dts/rk3588s-pinctrl.dtsi b/arch/arm/dts/rk3588s-pinctrl.dtsi
new file mode 100644
index 0000000..4818167
--- /dev/null
+++ b/arch/arm/dts/rk3588s-pinctrl.dtsi
@@ -0,0 +1,3403 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ */
+
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rockchip-pinconf.dtsi"
+
+/*
+ * This file is auto generated by pin2dts tool, please keep these code
+ * by adding changes at end of this file.
+ */
+&pinctrl {
+	auddsm {
+		/omit-if-no-ref/
+		auddsm_pins: auddsm-pins {
+			rockchip,pins =
+				/* auddsm_ln */
+				<3 RK_PA1 4 &pcfg_pull_none>,
+				/* auddsm_lp */
+				<3 RK_PA2 4 &pcfg_pull_none>,
+				/* auddsm_rn */
+				<3 RK_PA3 4 &pcfg_pull_none>,
+				/* auddsm_rp */
+				<3 RK_PA4 4 &pcfg_pull_none>;
+		};
+	};
+
+	bt1120 {
+		/omit-if-no-ref/
+		bt1120_pins: bt1120-pins {
+			rockchip,pins =
+				/* bt1120_clkout */
+				<4 RK_PB0 2 &pcfg_pull_none>,
+				/* bt1120_d0 */
+				<4 RK_PA0 2 &pcfg_pull_none>,
+				/* bt1120_d1 */
+				<4 RK_PA1 2 &pcfg_pull_none>,
+				/* bt1120_d2 */
+				<4 RK_PA2 2 &pcfg_pull_none>,
+				/* bt1120_d3 */
+				<4 RK_PA3 2 &pcfg_pull_none>,
+				/* bt1120_d4 */
+				<4 RK_PA4 2 &pcfg_pull_none>,
+				/* bt1120_d5 */
+				<4 RK_PA5 2 &pcfg_pull_none>,
+				/* bt1120_d6 */
+				<4 RK_PA6 2 &pcfg_pull_none>,
+				/* bt1120_d7 */
+				<4 RK_PA7 2 &pcfg_pull_none>,
+				/* bt1120_d8 */
+				<4 RK_PB2 2 &pcfg_pull_none>,
+				/* bt1120_d9 */
+				<4 RK_PB3 2 &pcfg_pull_none>,
+				/* bt1120_d10 */
+				<4 RK_PB4 2 &pcfg_pull_none>,
+				/* bt1120_d11 */
+				<4 RK_PB5 2 &pcfg_pull_none>,
+				/* bt1120_d12 */
+				<4 RK_PB6 2 &pcfg_pull_none>,
+				/* bt1120_d13 */
+				<4 RK_PB7 2 &pcfg_pull_none>,
+				/* bt1120_d14 */
+				<4 RK_PC0 2 &pcfg_pull_none>,
+				/* bt1120_d15 */
+				<4 RK_PC1 2 &pcfg_pull_none>;
+		};
+	};
+
+	can0 {
+		/omit-if-no-ref/
+		can0m0_pins: can0m0-pins {
+			rockchip,pins =
+				/* can0_rx_m0 */
+				<0 RK_PC0 11 &pcfg_pull_none>,
+				/* can0_tx_m0 */
+				<0 RK_PB7 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		can0m1_pins: can0m1-pins {
+			rockchip,pins =
+				/* can0_rx_m1 */
+				<4 RK_PD5 9 &pcfg_pull_none>,
+				/* can0_tx_m1 */
+				<4 RK_PD4 9 &pcfg_pull_none>;
+		};
+	};
+
+	can1 {
+		/omit-if-no-ref/
+		can1m0_pins: can1m0-pins {
+			rockchip,pins =
+				/* can1_rx_m0 */
+				<3 RK_PB5 9 &pcfg_pull_none>,
+				/* can1_tx_m0 */
+				<3 RK_PB6 9 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		can1m1_pins: can1m1-pins {
+			rockchip,pins =
+				/* can1_rx_m1 */
+				<4 RK_PB2 12 &pcfg_pull_none>,
+				/* can1_tx_m1 */
+				<4 RK_PB3 12 &pcfg_pull_none>;
+		};
+	};
+
+	can2 {
+		/omit-if-no-ref/
+		can2m0_pins: can2m0-pins {
+			rockchip,pins =
+				/* can2_rx_m0 */
+				<3 RK_PC4 9 &pcfg_pull_none>,
+				/* can2_tx_m0 */
+				<3 RK_PC5 9 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		can2m1_pins: can2m1-pins {
+			rockchip,pins =
+				/* can2_rx_m1 */
+				<0 RK_PD4 10 &pcfg_pull_none>,
+				/* can2_tx_m1 */
+				<0 RK_PD5 10 &pcfg_pull_none>;
+		};
+	};
+
+	cif {
+		/omit-if-no-ref/
+		cif_clk: cif-clk {
+			rockchip,pins =
+				/* cif_clkout */
+				<4 RK_PB4 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		cif_dvp_clk: cif-dvp-clk {
+			rockchip,pins =
+				/* cif_clkin */
+				<4 RK_PB0 1 &pcfg_pull_none>,
+				/* cif_href */
+				<4 RK_PB2 1 &pcfg_pull_none>,
+				/* cif_vsync */
+				<4 RK_PB3 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		cif_dvp_bus16: cif-dvp-bus16 {
+			rockchip,pins =
+				/* cif_d8 */
+				<3 RK_PC4 1 &pcfg_pull_none>,
+				/* cif_d9 */
+				<3 RK_PC5 1 &pcfg_pull_none>,
+				/* cif_d10 */
+				<3 RK_PC6 1 &pcfg_pull_none>,
+				/* cif_d11 */
+				<3 RK_PC7 1 &pcfg_pull_none>,
+				/* cif_d12 */
+				<3 RK_PD0 1 &pcfg_pull_none>,
+				/* cif_d13 */
+				<3 RK_PD1 1 &pcfg_pull_none>,
+				/* cif_d14 */
+				<3 RK_PD2 1 &pcfg_pull_none>,
+				/* cif_d15 */
+				<3 RK_PD3 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		cif_dvp_bus8: cif-dvp-bus8 {
+			rockchip,pins =
+				/* cif_d0 */
+				<4 RK_PA0 1 &pcfg_pull_none>,
+				/* cif_d1 */
+				<4 RK_PA1 1 &pcfg_pull_none>,
+				/* cif_d2 */
+				<4 RK_PA2 1 &pcfg_pull_none>,
+				/* cif_d3 */
+				<4 RK_PA3 1 &pcfg_pull_none>,
+				/* cif_d4 */
+				<4 RK_PA4 1 &pcfg_pull_none>,
+				/* cif_d5 */
+				<4 RK_PA5 1 &pcfg_pull_none>,
+				/* cif_d6 */
+				<4 RK_PA6 1 &pcfg_pull_none>,
+				/* cif_d7 */
+				<4 RK_PA7 1 &pcfg_pull_none>;
+		};
+	};
+
+	clk32k {
+		/omit-if-no-ref/
+		clk32k_in: clk32k-in {
+			rockchip,pins =
+				/* clk32k_in */
+				<0 RK_PB2 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		clk32k_out0: clk32k-out0 {
+			rockchip,pins =
+				/* clk32k_out0 */
+				<0 RK_PB2 2 &pcfg_pull_none>;
+		};
+	};
+
+	cpu {
+		/omit-if-no-ref/
+		cpu_pins: cpu-pins {
+			rockchip,pins =
+				/* cpu_big0_avs */
+				<0 RK_PD1 2 &pcfg_pull_none>,
+				/* cpu_big1_avs */
+				<0 RK_PD5 2 &pcfg_pull_none>;
+		};
+	};
+
+	ddrphych0 {
+		/omit-if-no-ref/
+		ddrphych0_pins: ddrphych0-pins {
+			rockchip,pins =
+				/* ddrphych0_dtb0 */
+				<4 RK_PA0 7 &pcfg_pull_none>,
+				/* ddrphych0_dtb1 */
+				<4 RK_PA1 7 &pcfg_pull_none>,
+				/* ddrphych0_dtb2 */
+				<4 RK_PA2 7 &pcfg_pull_none>,
+				/* ddrphych0_dtb3 */
+				<4 RK_PA3 7 &pcfg_pull_none>;
+		};
+	};
+
+	ddrphych1 {
+		/omit-if-no-ref/
+		ddrphych1_pins: ddrphych1-pins {
+			rockchip,pins =
+				/* ddrphych1_dtb0 */
+				<4 RK_PA4 7 &pcfg_pull_none>,
+				/* ddrphych1_dtb1 */
+				<4 RK_PA5 7 &pcfg_pull_none>,
+				/* ddrphych1_dtb2 */
+				<4 RK_PA6 7 &pcfg_pull_none>,
+				/* ddrphych1_dtb3 */
+				<4 RK_PA7 7 &pcfg_pull_none>;
+		};
+	};
+
+	ddrphych2 {
+		/omit-if-no-ref/
+		ddrphych2_pins: ddrphych2-pins {
+			rockchip,pins =
+				/* ddrphych2_dtb0 */
+				<4 RK_PB0 7 &pcfg_pull_none>,
+				/* ddrphych2_dtb1 */
+				<4 RK_PB1 7 &pcfg_pull_none>,
+				/* ddrphych2_dtb2 */
+				<4 RK_PB2 7 &pcfg_pull_none>,
+				/* ddrphych2_dtb3 */
+				<4 RK_PB3 7 &pcfg_pull_none>;
+		};
+	};
+
+	ddrphych3 {
+		/omit-if-no-ref/
+		ddrphych3_pins: ddrphych3-pins {
+			rockchip,pins =
+				/* ddrphych3_dtb0 */
+				<4 RK_PB4 7 &pcfg_pull_none>,
+				/* ddrphych3_dtb1 */
+				<4 RK_PB5 7 &pcfg_pull_none>,
+				/* ddrphych3_dtb2 */
+				<4 RK_PB6 7 &pcfg_pull_none>,
+				/* ddrphych3_dtb3 */
+				<4 RK_PB7 7 &pcfg_pull_none>;
+		};
+	};
+
+	dp0 {
+		/omit-if-no-ref/
+		dp0m0_pins: dp0m0-pins {
+			rockchip,pins =
+				/* dp0_hpdin_m0 */
+				<4 RK_PB4 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		dp0m1_pins: dp0m1-pins {
+			rockchip,pins =
+				/* dp0_hpdin_m1 */
+				<0 RK_PC4 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		dp0m2_pins: dp0m2-pins {
+			rockchip,pins =
+				/* dp0_hpdin_m2 */
+				<1 RK_PA0 5 &pcfg_pull_none>;
+		};
+	};
+
+	dp1 {
+		/omit-if-no-ref/
+		dp1m0_pins: dp1m0-pins {
+			rockchip,pins =
+				/* dp1_hpdin_m0 */
+				<3 RK_PD5 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		dp1m1_pins: dp1m1-pins {
+			rockchip,pins =
+				/* dp1_hpdin_m1 */
+				<0 RK_PC5 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		dp1m2_pins: dp1m2-pins {
+			rockchip,pins =
+				/* dp1_hpdin_m2 */
+				<1 RK_PA1 5 &pcfg_pull_none>;
+		};
+	};
+
+	emmc {
+		/omit-if-no-ref/
+		emmc_rstnout: emmc-rstnout {
+			rockchip,pins =
+				/* emmc_rstn */
+				<2 RK_PA3 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		emmc_bus8: emmc-bus8 {
+			rockchip,pins =
+				/* emmc_d0 */
+				<2 RK_PD0 1 &pcfg_pull_up_drv_level_2>,
+				/* emmc_d1 */
+				<2 RK_PD1 1 &pcfg_pull_up_drv_level_2>,
+				/* emmc_d2 */
+				<2 RK_PD2 1 &pcfg_pull_up_drv_level_2>,
+				/* emmc_d3 */
+				<2 RK_PD3 1 &pcfg_pull_up_drv_level_2>,
+				/* emmc_d4 */
+				<2 RK_PD4 1 &pcfg_pull_up_drv_level_2>,
+				/* emmc_d5 */
+				<2 RK_PD5 1 &pcfg_pull_up_drv_level_2>,
+				/* emmc_d6 */
+				<2 RK_PD6 1 &pcfg_pull_up_drv_level_2>,
+				/* emmc_d7 */
+				<2 RK_PD7 1 &pcfg_pull_up_drv_level_2>;
+		};
+
+		/omit-if-no-ref/
+		emmc_clk: emmc-clk {
+			rockchip,pins =
+				/* emmc_clkout */
+				<2 RK_PA1 1 &pcfg_pull_up_drv_level_2>;
+		};
+
+		/omit-if-no-ref/
+		emmc_cmd: emmc-cmd {
+			rockchip,pins =
+				/* emmc_cmd */
+				<2 RK_PA0 1 &pcfg_pull_up_drv_level_2>;
+		};
+
+		/omit-if-no-ref/
+		emmc_data_strobe: emmc-data-strobe {
+			rockchip,pins =
+				/* emmc_data_strobe */
+				<2 RK_PA2 1 &pcfg_pull_none>;
+		};
+	};
+
+	eth1 {
+		/omit-if-no-ref/
+		eth1_pins: eth1-pins {
+			rockchip,pins =
+				/* eth1_refclko_25m */
+				<3 RK_PA6 1 &pcfg_pull_none>;
+		};
+	};
+
+	fspi {
+		/omit-if-no-ref/
+		fspim0_pins: fspim0-pins {
+			rockchip,pins =
+				/* fspi_clk_m0 */
+				<2 RK_PA0 2 &pcfg_pull_up_drv_level_2>,
+				/* fspi_cs0n_m0 */
+				<2 RK_PD6 2 &pcfg_pull_up_drv_level_2>,
+				/* fspi_d0_m0 */
+				<2 RK_PD0 2 &pcfg_pull_up_drv_level_2>,
+				/* fspi_d1_m0 */
+				<2 RK_PD1 2 &pcfg_pull_up_drv_level_2>,
+				/* fspi_d2_m0 */
+				<2 RK_PD2 2 &pcfg_pull_up_drv_level_2>,
+				/* fspi_d3_m0 */
+				<2 RK_PD3 2 &pcfg_pull_up_drv_level_2>;
+		};
+
+		/omit-if-no-ref/
+		fspim0_cs1: fspim0-cs1 {
+			rockchip,pins =
+				/* fspi_cs1n_m0 */
+				<2 RK_PD7 2 &pcfg_pull_up_drv_level_2>;
+		};
+
+		/omit-if-no-ref/
+		fspim2_pins: fspim2-pins {
+			rockchip,pins =
+				/* fspi_clk_m2 */
+				<3 RK_PA5 5 &pcfg_pull_up_drv_level_2>,
+				/* fspi_cs0n_m2 */
+				<3 RK_PC4 2 &pcfg_pull_up_drv_level_2>,
+				/* fspi_d0_m2 */
+				<3 RK_PA0 5 &pcfg_pull_up_drv_level_2>,
+				/* fspi_d1_m2 */
+				<3 RK_PA1 5 &pcfg_pull_up_drv_level_2>,
+				/* fspi_d2_m2 */
+				<3 RK_PA2 5 &pcfg_pull_up_drv_level_2>,
+				/* fspi_d3_m2 */
+				<3 RK_PA3 5 &pcfg_pull_up_drv_level_2>;
+		};
+
+		/omit-if-no-ref/
+		fspim2_cs1: fspim2-cs1 {
+			rockchip,pins =
+				/* fspi_cs1n_m2 */
+				<3 RK_PC5 2 &pcfg_pull_up_drv_level_2>;
+		};
+	};
+
+	gmac1 {
+		/omit-if-no-ref/
+		gmac1_miim: gmac1-miim {
+			rockchip,pins =
+				/* gmac1_mdc */
+				<3 RK_PC2 1 &pcfg_pull_none>,
+				/* gmac1_mdio */
+				<3 RK_PC3 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac1_clkinout: gmac1-clkinout {
+			rockchip,pins =
+				/* gmac1_mclkinout */
+				<3 RK_PB6 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac1_rx_bus2: gmac1-rx-bus2 {
+			rockchip,pins =
+				/* gmac1_rxd0 */
+				<3 RK_PA7 1 &pcfg_pull_none>,
+				/* gmac1_rxd1 */
+				<3 RK_PB0 1 &pcfg_pull_none>,
+				/* gmac1_rxdv_crs */
+				<3 RK_PB1 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac1_tx_bus2: gmac1-tx-bus2 {
+			rockchip,pins =
+				/* gmac1_txd0 */
+				<3 RK_PB3 1 &pcfg_pull_none>,
+				/* gmac1_txd1 */
+				<3 RK_PB4 1 &pcfg_pull_none>,
+				/* gmac1_txen */
+				<3 RK_PB5 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac1_rgmii_clk: gmac1-rgmii-clk {
+			rockchip,pins =
+				/* gmac1_rxclk */
+				<3 RK_PA5 1 &pcfg_pull_none>,
+				/* gmac1_txclk */
+				<3 RK_PA4 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac1_rgmii_bus: gmac1-rgmii-bus {
+			rockchip,pins =
+				/* gmac1_rxd2 */
+				<3 RK_PA2 1 &pcfg_pull_none>,
+				/* gmac1_rxd3 */
+				<3 RK_PA3 1 &pcfg_pull_none>,
+				/* gmac1_txd2 */
+				<3 RK_PA0 1 &pcfg_pull_none>,
+				/* gmac1_txd3 */
+				<3 RK_PA1 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac1_ppsclk: gmac1-ppsclk {
+			rockchip,pins =
+				/* gmac1_ppsclk */
+				<3 RK_PC1 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac1_ppstrig: gmac1-ppstrig {
+			rockchip,pins =
+				/* gmac1_ppstrig */
+				<3 RK_PC0 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac1_ptp_ref_clk: gmac1-ptp-ref-clk {
+			rockchip,pins =
+				/* gmac1_ptp_ref_clk */
+				<3 RK_PB7 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		gmac1_txer: gmac1-txer {
+			rockchip,pins =
+				/* gmac1_txer */
+				<3 RK_PB2 1 &pcfg_pull_none>;
+		};
+	};
+
+	gpu {
+		/omit-if-no-ref/
+		gpu_pins: gpu-pins {
+			rockchip,pins =
+				/* gpu_avs */
+				<0 RK_PC5 2 &pcfg_pull_none>;
+		};
+	};
+
+	hdmi {
+		/omit-if-no-ref/
+		hdmim0_rx_cec: hdmim0-rx-cec {
+			rockchip,pins =
+				/* hdmim0_rx_cec */
+				<4 RK_PB5 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim0_rx_hpdin: hdmim0-rx-hpdin {
+			rockchip,pins =
+				/* hdmim0_rx_hpdin */
+				<4 RK_PB6 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim0_rx_scl: hdmim0-rx-scl {
+			rockchip,pins =
+				/* hdmim0_rx_scl */
+				<0 RK_PD2 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim0_rx_sda: hdmim0-rx-sda {
+			rockchip,pins =
+				/* hdmim0_rx_sda */
+				<0 RK_PD1 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim0_tx0_cec: hdmim0-tx0-cec {
+			rockchip,pins =
+				/* hdmim0_tx0_cec */
+				<4 RK_PC1 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim0_tx0_hpd: hdmim0-tx0-hpd {
+			rockchip,pins =
+				/* hdmim0_tx0_hpd */
+				<1 RK_PA5 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim0_tx0_scl: hdmim0-tx0-scl {
+			rockchip,pins =
+				/* hdmim0_tx0_scl */
+				<4 RK_PB7 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim0_tx0_sda: hdmim0-tx0-sda {
+			rockchip,pins =
+				/* hdmim0_tx0_sda */
+				<4 RK_PC0 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim0_tx1_hpd: hdmim0-tx1-hpd {
+			rockchip,pins =
+				/* hdmim0_tx1_hpd */
+				<1 RK_PA6 5 &pcfg_pull_none>;
+		};
+		/omit-if-no-ref/
+		hdmim1_rx_cec: hdmim1-rx-cec {
+			rockchip,pins =
+				/* hdmim1_rx_cec */
+				<3 RK_PD1 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim1_rx_hpdin: hdmim1-rx-hpdin {
+			rockchip,pins =
+				/* hdmim1_rx_hpdin */
+				<3 RK_PD4 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim1_rx_scl: hdmim1-rx-scl {
+			rockchip,pins =
+				/* hdmim1_rx_scl */
+				<3 RK_PD2 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim1_rx_sda: hdmim1-rx-sda {
+			rockchip,pins =
+				/* hdmim1_rx_sda */
+				<3 RK_PD3 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim1_tx0_cec: hdmim1-tx0-cec {
+			rockchip,pins =
+				/* hdmim1_tx0_cec */
+				<0 RK_PD1 13 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim1_tx0_hpd: hdmim1-tx0-hpd {
+			rockchip,pins =
+				/* hdmim1_tx0_hpd */
+				<3 RK_PD4 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim1_tx0_scl: hdmim1-tx0-scl {
+			rockchip,pins =
+				/* hdmim1_tx0_scl */
+				<0 RK_PD5 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim1_tx0_sda: hdmim1-tx0-sda {
+			rockchip,pins =
+				/* hdmim1_tx0_sda */
+				<0 RK_PD4 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim1_tx1_cec: hdmim1-tx1-cec {
+			rockchip,pins =
+				/* hdmim1_tx1_cec */
+				<0 RK_PD2 13 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim1_tx1_hpd: hdmim1-tx1-hpd {
+			rockchip,pins =
+				/* hdmim1_tx1_hpd */
+				<3 RK_PB7 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim1_tx1_scl: hdmim1-tx1-scl {
+			rockchip,pins =
+				/* hdmim1_tx1_scl */
+				<3 RK_PC6 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim1_tx1_sda: hdmim1-tx1-sda {
+			rockchip,pins =
+				/* hdmim1_tx1_sda */
+				<3 RK_PC5 5 &pcfg_pull_none>;
+		};
+		/omit-if-no-ref/
+		hdmim2_rx_cec: hdmim2-rx-cec {
+			rockchip,pins =
+				/* hdmim2_rx_cec */
+				<1 RK_PB7 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim2_rx_hpdin: hdmim2-rx-hpdin {
+			rockchip,pins =
+				/* hdmim2_rx_hpdin */
+				<1 RK_PB6 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim2_rx_scl: hdmim2-rx-scl {
+			rockchip,pins =
+				/* hdmim2_rx_scl */
+				<1 RK_PD6 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim2_rx_sda: hdmim2-rx-sda {
+			rockchip,pins =
+				/* hdmim2_rx_sda */
+				<1 RK_PD7 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim2_tx0_scl: hdmim2-tx0-scl {
+			rockchip,pins =
+				/* hdmim2_tx0_scl */
+				<3 RK_PC7 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim2_tx0_sda: hdmim2-tx0-sda {
+			rockchip,pins =
+				/* hdmim2_tx0_sda */
+				<3 RK_PD0 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim2_tx1_cec: hdmim2-tx1-cec {
+			rockchip,pins =
+				/* hdmim2_tx1_cec */
+				<3 RK_PC4 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim2_tx1_scl: hdmim2-tx1-scl {
+			rockchip,pins =
+				/* hdmim2_tx1_scl */
+				<1 RK_PA4 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim2_tx1_sda: hdmim2-tx1-sda {
+			rockchip,pins =
+				/* hdmim2_tx1_sda */
+				<1 RK_PA3 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmi_debug0: hdmi-debug0 {
+			rockchip,pins =
+				/* hdmi_debug0 */
+				<1 RK_PA7 7 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmi_debug1: hdmi-debug1 {
+			rockchip,pins =
+				/* hdmi_debug1 */
+				<1 RK_PB0 7 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmi_debug2: hdmi-debug2 {
+			rockchip,pins =
+				/* hdmi_debug2 */
+				<1 RK_PB1 7 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmi_debug3: hdmi-debug3 {
+			rockchip,pins =
+				/* hdmi_debug3 */
+				<1 RK_PB2 7 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmi_debug4: hdmi-debug4 {
+			rockchip,pins =
+				/* hdmi_debug4 */
+				<1 RK_PB3 7 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmi_debug5: hdmi-debug5 {
+			rockchip,pins =
+				/* hdmi_debug5 */
+				<1 RK_PB4 7 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmi_debug6: hdmi-debug6 {
+			rockchip,pins =
+				/* hdmi_debug6 */
+				<1 RK_PA0 7 &pcfg_pull_none>;
+		};
+	};
+
+	i2c0 {
+		/omit-if-no-ref/
+		i2c0m0_xfer: i2c0m0-xfer {
+			rockchip,pins =
+				/* i2c0_scl_m0 */
+				<0 RK_PB3 2 &pcfg_pull_none_smt>,
+				/* i2c0_sda_m0 */
+				<0 RK_PA6 2 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c0m2_xfer: i2c0m2-xfer {
+			rockchip,pins =
+				/* i2c0_scl_m2 */
+				<0 RK_PD1 3 &pcfg_pull_none_smt>,
+				/* i2c0_sda_m2 */
+				<0 RK_PD2 3 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2c1 {
+		/omit-if-no-ref/
+		i2c1m0_xfer: i2c1m0-xfer {
+			rockchip,pins =
+				/* i2c1_scl_m0 */
+				<0 RK_PB5 9 &pcfg_pull_none_smt>,
+				/* i2c1_sda_m0 */
+				<0 RK_PB6 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c1m1_xfer: i2c1m1-xfer {
+			rockchip,pins =
+				/* i2c1_scl_m1 */
+				<0 RK_PB0 2 &pcfg_pull_none_smt>,
+				/* i2c1_sda_m1 */
+				<0 RK_PB1 2 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c1m2_xfer: i2c1m2-xfer {
+			rockchip,pins =
+				/* i2c1_scl_m2 */
+				<0 RK_PD4 9 &pcfg_pull_none_smt>,
+				/* i2c1_sda_m2 */
+				<0 RK_PD5 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c1m3_xfer: i2c1m3-xfer {
+			rockchip,pins =
+				/* i2c1_scl_m3 */
+				<2 RK_PD4 9 &pcfg_pull_none_smt>,
+				/* i2c1_sda_m3 */
+				<2 RK_PD5 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c1m4_xfer: i2c1m4-xfer {
+			rockchip,pins =
+				/* i2c1_scl_m4 */
+				<1 RK_PD2 9 &pcfg_pull_none_smt>,
+				/* i2c1_sda_m4 */
+				<1 RK_PD3 9 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2c2 {
+		/omit-if-no-ref/
+		i2c2m0_xfer: i2c2m0-xfer {
+			rockchip,pins =
+				/* i2c2_scl_m0 */
+				<0 RK_PB7 9 &pcfg_pull_none_smt>,
+				/* i2c2_sda_m0 */
+				<0 RK_PC0 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c2m2_xfer: i2c2m2-xfer {
+			rockchip,pins =
+				/* i2c2_scl_m2 */
+				<2 RK_PA3 9 &pcfg_pull_none_smt>,
+				/* i2c2_sda_m2 */
+				<2 RK_PA2 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c2m3_xfer: i2c2m3-xfer {
+			rockchip,pins =
+				/* i2c2_scl_m3 */
+				<1 RK_PC5 9 &pcfg_pull_none_smt>,
+				/* i2c2_sda_m3 */
+				<1 RK_PC4 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c2m4_xfer: i2c2m4-xfer {
+			rockchip,pins =
+				/* i2c2_scl_m4 */
+				<1 RK_PA1 9 &pcfg_pull_none_smt>,
+				/* i2c2_sda_m4 */
+				<1 RK_PA0 9 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2c3 {
+		/omit-if-no-ref/
+		i2c3m0_xfer: i2c3m0-xfer {
+			rockchip,pins =
+				/* i2c3_scl_m0 */
+				<1 RK_PC1 9 &pcfg_pull_none_smt>,
+				/* i2c3_sda_m0 */
+				<1 RK_PC0 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c3m1_xfer: i2c3m1-xfer {
+			rockchip,pins =
+				/* i2c3_scl_m1 */
+				<3 RK_PB7 9 &pcfg_pull_none_smt>,
+				/* i2c3_sda_m1 */
+				<3 RK_PC0 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c3m2_xfer: i2c3m2-xfer {
+			rockchip,pins =
+				/* i2c3_scl_m2 */
+				<4 RK_PA4 9 &pcfg_pull_none_smt>,
+				/* i2c3_sda_m2 */
+				<4 RK_PA5 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c3m4_xfer: i2c3m4-xfer {
+			rockchip,pins =
+				/* i2c3_scl_m4 */
+				<4 RK_PD0 9 &pcfg_pull_none_smt>,
+				/* i2c3_sda_m4 */
+				<4 RK_PD1 9 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2c4 {
+		/omit-if-no-ref/
+		i2c4m0_xfer: i2c4m0-xfer {
+			rockchip,pins =
+				/* i2c4_scl_m0 */
+				<3 RK_PA6 9 &pcfg_pull_none_smt>,
+				/* i2c4_sda_m0 */
+				<3 RK_PA5 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c4m2_xfer: i2c4m2-xfer {
+			rockchip,pins =
+				/* i2c4_scl_m2 */
+				<0 RK_PC5 9 &pcfg_pull_none_smt>,
+				/* i2c4_sda_m2 */
+				<0 RK_PC4 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c4m3_xfer: i2c4m3-xfer {
+			rockchip,pins =
+				/* i2c4_scl_m3 */
+				<1 RK_PA3 9 &pcfg_pull_none_smt>,
+				/* i2c4_sda_m3 */
+				<1 RK_PA2 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c4m4_xfer: i2c4m4-xfer {
+			rockchip,pins =
+				/* i2c4_scl_m4 */
+				<1 RK_PC7 9 &pcfg_pull_none_smt>,
+				/* i2c4_sda_m4 */
+				<1 RK_PC6 9 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2c5 {
+		/omit-if-no-ref/
+		i2c5m0_xfer: i2c5m0-xfer {
+			rockchip,pins =
+				/* i2c5_scl_m0 */
+				<3 RK_PC7 9 &pcfg_pull_none_smt>,
+				/* i2c5_sda_m0 */
+				<3 RK_PD0 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c5m1_xfer: i2c5m1-xfer {
+			rockchip,pins =
+				/* i2c5_scl_m1 */
+				<4 RK_PB6 9 &pcfg_pull_none_smt>,
+				/* i2c5_sda_m1 */
+				<4 RK_PB7 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c5m2_xfer: i2c5m2-xfer {
+			rockchip,pins =
+				/* i2c5_scl_m2 */
+				<4 RK_PA6 9 &pcfg_pull_none_smt>,
+				/* i2c5_sda_m2 */
+				<4 RK_PA7 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c5m3_xfer: i2c5m3-xfer {
+			rockchip,pins =
+				/* i2c5_scl_m3 */
+				<1 RK_PB6 9 &pcfg_pull_none_smt>,
+				/* i2c5_sda_m3 */
+				<1 RK_PB7 9 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2c6 {
+		/omit-if-no-ref/
+		i2c6m0_xfer: i2c6m0-xfer {
+			rockchip,pins =
+				/* i2c6_scl_m0 */
+				<0 RK_PD0 9 &pcfg_pull_none_smt>,
+				/* i2c6_sda_m0 */
+				<0 RK_PC7 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c6m1_xfer: i2c6m1-xfer {
+			rockchip,pins =
+				/* i2c6_scl_m1 */
+				<1 RK_PC3 9 &pcfg_pull_none_smt>,
+				/* i2c6_sda_m1 */
+				<1 RK_PC2 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c6m3_xfer: i2c6m3-xfer {
+			rockchip,pins =
+				/* i2c6_scl_m3 */
+				<4 RK_PB1 9 &pcfg_pull_none_smt>,
+				/* i2c6_sda_m3 */
+				<4 RK_PB0 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c6m4_xfer: i2c6m4-xfer {
+			rockchip,pins =
+				/* i2c6_scl_m4 */
+				<3 RK_PA1 9 &pcfg_pull_none_smt>,
+				/* i2c6_sda_m4 */
+				<3 RK_PA0 9 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2c7 {
+		/omit-if-no-ref/
+		i2c7m0_xfer: i2c7m0-xfer {
+			rockchip,pins =
+				/* i2c7_scl_m0 */
+				<1 RK_PD0 9 &pcfg_pull_none_smt>,
+				/* i2c7_sda_m0 */
+				<1 RK_PD1 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c7m2_xfer: i2c7m2-xfer {
+			rockchip,pins =
+				/* i2c7_scl_m2 */
+				<3 RK_PD2 9 &pcfg_pull_none_smt>,
+				/* i2c7_sda_m2 */
+				<3 RK_PD3 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c7m3_xfer: i2c7m3-xfer {
+			rockchip,pins =
+				/* i2c7_scl_m3 */
+				<4 RK_PB2 9 &pcfg_pull_none_smt>,
+				/* i2c7_sda_m3 */
+				<4 RK_PB3 9 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2c8 {
+		/omit-if-no-ref/
+		i2c8m0_xfer: i2c8m0-xfer {
+			rockchip,pins =
+				/* i2c8_scl_m0 */
+				<4 RK_PD2 9 &pcfg_pull_none_smt>,
+				/* i2c8_sda_m0 */
+				<4 RK_PD3 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c8m2_xfer: i2c8m2-xfer {
+			rockchip,pins =
+				/* i2c8_scl_m2 */
+				<1 RK_PD6 9 &pcfg_pull_none_smt>,
+				/* i2c8_sda_m2 */
+				<1 RK_PD7 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c8m3_xfer: i2c8m3-xfer {
+			rockchip,pins =
+				/* i2c8_scl_m3 */
+				<4 RK_PC0 9 &pcfg_pull_none_smt>,
+				/* i2c8_sda_m3 */
+				<4 RK_PC1 9 &pcfg_pull_none_smt>;
+		};
+
+		/omit-if-no-ref/
+		i2c8m4_xfer: i2c8m4-xfer {
+			rockchip,pins =
+				/* i2c8_scl_m4 */
+				<3 RK_PC2 9 &pcfg_pull_none_smt>,
+				/* i2c8_sda_m4 */
+				<3 RK_PC3 9 &pcfg_pull_none_smt>;
+		};
+	};
+
+	i2s0 {
+		/omit-if-no-ref/
+		i2s0_lrck: i2s0-lrck {
+			rockchip,pins =
+				/* i2s0_lrck */
+				<1 RK_PC5 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s0_mclk: i2s0-mclk {
+			rockchip,pins =
+				/* i2s0_mclk */
+				<1 RK_PC2 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s0_sclk: i2s0-sclk {
+			rockchip,pins =
+				/* i2s0_sclk */
+				<1 RK_PC3 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s0_sdi0: i2s0-sdi0 {
+			rockchip,pins =
+				/* i2s0_sdi0 */
+				<1 RK_PD4 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s0_sdi1: i2s0-sdi1 {
+			rockchip,pins =
+				/* i2s0_sdi1 */
+				<1 RK_PD3 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s0_sdi2: i2s0-sdi2 {
+			rockchip,pins =
+				/* i2s0_sdi2 */
+				<1 RK_PD2 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s0_sdi3: i2s0-sdi3 {
+			rockchip,pins =
+				/* i2s0_sdi3 */
+				<1 RK_PD1 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s0_sdo0: i2s0-sdo0 {
+			rockchip,pins =
+				/* i2s0_sdo0 */
+				<1 RK_PC7 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s0_sdo1: i2s0-sdo1 {
+			rockchip,pins =
+				/* i2s0_sdo1 */
+				<1 RK_PD0 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s0_sdo2: i2s0-sdo2 {
+			rockchip,pins =
+				/* i2s0_sdo2 */
+				<1 RK_PD1 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s0_sdo3: i2s0-sdo3 {
+			rockchip,pins =
+				/* i2s0_sdo3 */
+				<1 RK_PD2 1 &pcfg_pull_none>;
+		};
+	};
+
+	i2s1 {
+		/omit-if-no-ref/
+		i2s1m0_lrck: i2s1m0-lrck {
+			rockchip,pins =
+				/* i2s1m0_lrck */
+				<4 RK_PA2 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m0_mclk: i2s1m0-mclk {
+			rockchip,pins =
+				/* i2s1m0_mclk */
+				<4 RK_PA0 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m0_sclk: i2s1m0-sclk {
+			rockchip,pins =
+				/* i2s1m0_sclk */
+				<4 RK_PA1 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m0_sdi0: i2s1m0-sdi0 {
+			rockchip,pins =
+				/* i2s1m0_sdi0 */
+				<4 RK_PA5 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m0_sdi1: i2s1m0-sdi1 {
+			rockchip,pins =
+				/* i2s1m0_sdi1 */
+				<4 RK_PA6 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m0_sdi2: i2s1m0-sdi2 {
+			rockchip,pins =
+				/* i2s1m0_sdi2 */
+				<4 RK_PA7 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m0_sdi3: i2s1m0-sdi3 {
+			rockchip,pins =
+				/* i2s1m0_sdi3 */
+				<4 RK_PB0 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m0_sdo0: i2s1m0-sdo0 {
+			rockchip,pins =
+				/* i2s1m0_sdo0 */
+				<4 RK_PB1 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m0_sdo1: i2s1m0-sdo1 {
+			rockchip,pins =
+				/* i2s1m0_sdo1 */
+				<4 RK_PB2 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m0_sdo2: i2s1m0-sdo2 {
+			rockchip,pins =
+				/* i2s1m0_sdo2 */
+				<4 RK_PB3 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m0_sdo3: i2s1m0-sdo3 {
+			rockchip,pins =
+				/* i2s1m0_sdo3 */
+				<4 RK_PB4 3 &pcfg_pull_none>;
+		};
+		/omit-if-no-ref/
+		i2s1m1_lrck: i2s1m1-lrck {
+			rockchip,pins =
+				/* i2s1m1_lrck */
+				<0 RK_PB7 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m1_mclk: i2s1m1-mclk {
+			rockchip,pins =
+				/* i2s1m1_mclk */
+				<0 RK_PB5 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m1_sclk: i2s1m1-sclk {
+			rockchip,pins =
+				/* i2s1m1_sclk */
+				<0 RK_PB6 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m1_sdi0: i2s1m1-sdi0 {
+			rockchip,pins =
+				/* i2s1m1_sdi0 */
+				<0 RK_PC5 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m1_sdi1: i2s1m1-sdi1 {
+			rockchip,pins =
+				/* i2s1m1_sdi1 */
+				<0 RK_PC6 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m1_sdi2: i2s1m1-sdi2 {
+			rockchip,pins =
+				/* i2s1m1_sdi2 */
+				<0 RK_PC7 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m1_sdi3: i2s1m1-sdi3 {
+			rockchip,pins =
+				/* i2s1m1_sdi3 */
+				<0 RK_PD0 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m1_sdo0: i2s1m1-sdo0 {
+			rockchip,pins =
+				/* i2s1m1_sdo0 */
+				<0 RK_PD1 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m1_sdo1: i2s1m1-sdo1 {
+			rockchip,pins =
+				/* i2s1m1_sdo1 */
+				<0 RK_PD2 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m1_sdo2: i2s1m1-sdo2 {
+			rockchip,pins =
+				/* i2s1m1_sdo2 */
+				<0 RK_PD4 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s1m1_sdo3: i2s1m1-sdo3 {
+			rockchip,pins =
+				/* i2s1m1_sdo3 */
+				<0 RK_PD5 1 &pcfg_pull_none>;
+		};
+	};
+
+	i2s2 {
+		/omit-if-no-ref/
+		i2s2m1_lrck: i2s2m1-lrck {
+			rockchip,pins =
+				/* i2s2m1_lrck */
+				<3 RK_PB6 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s2m1_mclk: i2s2m1-mclk {
+			rockchip,pins =
+				/* i2s2m1_mclk */
+				<3 RK_PB4 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s2m1_sclk: i2s2m1-sclk {
+			rockchip,pins =
+				/* i2s2m1_sclk */
+				<3 RK_PB5 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s2m1_sdi: i2s2m1-sdi {
+			rockchip,pins =
+				/* i2s2m1_sdi */
+				<3 RK_PB2 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s2m1_sdo: i2s2m1-sdo {
+			rockchip,pins =
+				/* i2s2m1_sdo */
+				<3 RK_PB3 3 &pcfg_pull_none>;
+		};
+	};
+
+	i2s3 {
+		/omit-if-no-ref/
+		i2s3_lrck: i2s3-lrck {
+			rockchip,pins =
+				/* i2s3_lrck */
+				<3 RK_PA2 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s3_mclk: i2s3-mclk {
+			rockchip,pins =
+				/* i2s3_mclk */
+				<3 RK_PA0 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s3_sclk: i2s3-sclk {
+			rockchip,pins =
+				/* i2s3_sclk */
+				<3 RK_PA1 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s3_sdi: i2s3-sdi {
+			rockchip,pins =
+				/* i2s3_sdi */
+				<3 RK_PA4 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		i2s3_sdo: i2s3-sdo {
+			rockchip,pins =
+				/* i2s3_sdo */
+				<3 RK_PA3 3 &pcfg_pull_none>;
+		};
+	};
+
+	jtag {
+		/omit-if-no-ref/
+		jtagm0_pins: jtagm0-pins {
+			rockchip,pins =
+				/* jtag_tck_m0 */
+				<4 RK_PD2 5 &pcfg_pull_none>,
+				/* jtag_tms_m0 */
+				<4 RK_PD3 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		jtagm1_pins: jtagm1-pins {
+			rockchip,pins =
+				/* jtag_tck_m1 */
+				<4 RK_PD0 5 &pcfg_pull_none>,
+				/* jtag_tms_m1 */
+				<4 RK_PD1 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		jtagm2_pins: jtagm2-pins {
+			rockchip,pins =
+				/* jtag_tck_m2 */
+				<0 RK_PB5 2 &pcfg_pull_none>,
+				/* jtag_tms_m2 */
+				<0 RK_PB6 2 &pcfg_pull_none>;
+		};
+	};
+
+	litcpu {
+		/omit-if-no-ref/
+		litcpu_pins: litcpu-pins {
+			rockchip,pins =
+				/* litcpu_avs */
+				<0 RK_PD3 1 &pcfg_pull_none>;
+		};
+	};
+
+	mcu {
+		/omit-if-no-ref/
+		mcum0_pins: mcum0-pins {
+			rockchip,pins =
+				/* mcu_jtag_tck_m0 */
+				<4 RK_PD4 5 &pcfg_pull_none>,
+				/* mcu_jtag_tms_m0 */
+				<4 RK_PD5 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		mcum1_pins: mcum1-pins {
+			rockchip,pins =
+				/* mcu_jtag_tck_m1 */
+				<3 RK_PD4 6 &pcfg_pull_none>,
+				/* mcu_jtag_tms_m1 */
+				<3 RK_PD5 6 &pcfg_pull_none>;
+		};
+	};
+
+	mipi {
+		/omit-if-no-ref/
+		mipim0_camera0_clk: mipim0-camera0-clk {
+			rockchip,pins =
+				/* mipim0_camera0_clk */
+				<4 RK_PB1 1 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		mipim0_camera1_clk: mipim0-camera1-clk {
+			rockchip,pins =
+				/* mipim0_camera1_clk */
+				<1 RK_PB6 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		mipim0_camera2_clk: mipim0-camera2-clk {
+			rockchip,pins =
+				/* mipim0_camera2_clk */
+				<1 RK_PB7 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		mipim0_camera3_clk: mipim0-camera3-clk {
+			rockchip,pins =
+				/* mipim0_camera3_clk */
+				<1 RK_PD6 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		mipim0_camera4_clk: mipim0-camera4-clk {
+			rockchip,pins =
+				/* mipim0_camera4_clk */
+				<1 RK_PD7 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		mipim1_camera0_clk: mipim1-camera0-clk {
+			rockchip,pins =
+				/* mipim1_camera0_clk */
+				<3 RK_PA5 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		mipim1_camera1_clk: mipim1-camera1-clk {
+			rockchip,pins =
+				/* mipim1_camera1_clk */
+				<3 RK_PA6 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		mipim1_camera2_clk: mipim1-camera2-clk {
+			rockchip,pins =
+				/* mipim1_camera2_clk */
+				<3 RK_PA7 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		mipim1_camera3_clk: mipim1-camera3-clk {
+			rockchip,pins =
+				/* mipim1_camera3_clk */
+				<3 RK_PB0 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		mipim1_camera4_clk: mipim1-camera4-clk {
+			rockchip,pins =
+				/* mipim1_camera4_clk */
+				<3 RK_PB1 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		mipi_te0: mipi-te0 {
+			rockchip,pins =
+				/* mipi_te0 */
+				<3 RK_PC2 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		mipi_te1: mipi-te1 {
+			rockchip,pins =
+				/* mipi_te1 */
+				<3 RK_PC3 2 &pcfg_pull_none>;
+		};
+	};
+
+	npu {
+		/omit-if-no-ref/
+		npu_pins: npu-pins {
+			rockchip,pins =
+				/* npu_avs */
+				<0 RK_PC6 2 &pcfg_pull_none>;
+		};
+	};
+
+	pcie20x1 {
+		/omit-if-no-ref/
+		pcie20x1m0_pins: pcie20x1m0-pins {
+			rockchip,pins =
+				/* pcie20x1_2_clkreqn_m0 */
+				<3 RK_PC7 4 &pcfg_pull_none>,
+				/* pcie20x1_2_perstn_m0 */
+				<3 RK_PD1 4 &pcfg_pull_none>,
+				/* pcie20x1_2_waken_m0 */
+				<3 RK_PD0 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pcie20x1m1_pins: pcie20x1m1-pins {
+			rockchip,pins =
+				/* pcie20x1_2_clkreqn_m1 */
+				<4 RK_PB7 4 &pcfg_pull_none>,
+				/* pcie20x1_2_perstn_m1 */
+				<4 RK_PC1 4 &pcfg_pull_none>,
+				/* pcie20x1_2_waken_m1 */
+				<4 RK_PC0 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pcie20x1_2_button_rstn: pcie20x1-2-button-rstn {
+			rockchip,pins =
+				/* pcie20x1_2_button_rstn */
+				<4 RK_PB3 4 &pcfg_pull_none>;
+		};
+	};
+
+	pcie30phy {
+		/omit-if-no-ref/
+		pcie30phy_pins: pcie30phy-pins {
+			rockchip,pins =
+				/* pcie30phy_dtb0 */
+				<1 RK_PC4 4 &pcfg_pull_none>,
+				/* pcie30phy_dtb1 */
+				<1 RK_PD1 4 &pcfg_pull_none>;
+		};
+	};
+
+	pcie30x1 {
+		/omit-if-no-ref/
+		pcie30x1m0_pins: pcie30x1m0-pins {
+			rockchip,pins =
+				/* pcie30x1_0_clkreqn_m0 */
+				<0 RK_PC0 12 &pcfg_pull_none>,
+				/* pcie30x1_0_perstn_m0 */
+				<0 RK_PC5 12 &pcfg_pull_none>,
+				/* pcie30x1_0_waken_m0 */
+				<0 RK_PC4 12 &pcfg_pull_none>,
+				/* pcie30x1_1_clkreqn_m0 */
+				<0 RK_PB5 12 &pcfg_pull_none>,
+				/* pcie30x1_1_perstn_m0 */
+				<0 RK_PB7 12 &pcfg_pull_none>,
+				/* pcie30x1_1_waken_m0 */
+				<0 RK_PB6 12 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pcie30x1m1_pins: pcie30x1m1-pins {
+			rockchip,pins =
+				/* pcie30x1_0_clkreqn_m1 */
+				<4 RK_PA3 4 &pcfg_pull_none>,
+				/* pcie30x1_0_perstn_m1 */
+				<4 RK_PA5 4 &pcfg_pull_none>,
+				/* pcie30x1_0_waken_m1 */
+				<4 RK_PA4 4 &pcfg_pull_none>,
+				/* pcie30x1_1_clkreqn_m1 */
+				<4 RK_PA0 4 &pcfg_pull_none>,
+				/* pcie30x1_1_perstn_m1 */
+				<4 RK_PA2 4 &pcfg_pull_none>,
+				/* pcie30x1_1_waken_m1 */
+				<4 RK_PA1 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pcie30x1m2_pins: pcie30x1m2-pins {
+			rockchip,pins =
+				/* pcie30x1_0_clkreqn_m2 */
+				<1 RK_PB5 4 &pcfg_pull_none>,
+				/* pcie30x1_0_perstn_m2 */
+				<1 RK_PB4 4 &pcfg_pull_none>,
+				/* pcie30x1_0_waken_m2 */
+				<1 RK_PB3 4 &pcfg_pull_none>,
+				/* pcie30x1_1_clkreqn_m2 */
+				<1 RK_PA0 4 &pcfg_pull_none>,
+				/* pcie30x1_1_perstn_m2 */
+				<1 RK_PA7 4 &pcfg_pull_none>,
+				/* pcie30x1_1_waken_m2 */
+				<1 RK_PA1 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pcie30x1_0_button_rstn: pcie30x1-0-button-rstn {
+			rockchip,pins =
+				/* pcie30x1_0_button_rstn */
+				<4 RK_PB1 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pcie30x1_1_button_rstn: pcie30x1-1-button-rstn {
+			rockchip,pins =
+				/* pcie30x1_1_button_rstn */
+				<4 RK_PB2 4 &pcfg_pull_none>;
+		};
+	};
+
+	pcie30x2 {
+		/omit-if-no-ref/
+		pcie30x2m0_pins: pcie30x2m0-pins {
+			rockchip,pins =
+				/* pcie30x2_clkreqn_m0 */
+				<0 RK_PD1 12 &pcfg_pull_none>,
+				/* pcie30x2_perstn_m0 */
+				<0 RK_PD4 12 &pcfg_pull_none>,
+				/* pcie30x2_waken_m0 */
+				<0 RK_PD2 12 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pcie30x2m1_pins: pcie30x2m1-pins {
+			rockchip,pins =
+				/* pcie30x2_clkreqn_m1 */
+				<4 RK_PA6 4 &pcfg_pull_none>,
+				/* pcie30x2_perstn_m1 */
+				<4 RK_PB0 4 &pcfg_pull_none>,
+				/* pcie30x2_waken_m1 */
+				<4 RK_PA7 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pcie30x2m2_pins: pcie30x2m2-pins {
+			rockchip,pins =
+				/* pcie30x2_clkreqn_m2 */
+				<3 RK_PD2 4 &pcfg_pull_none>,
+				/* pcie30x2_perstn_m2 */
+				<3 RK_PD4 4 &pcfg_pull_none>,
+				/* pcie30x2_waken_m2 */
+				<3 RK_PD3 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pcie30x2m3_pins: pcie30x2m3-pins {
+			rockchip,pins =
+				/* pcie30x2_clkreqn_m3 */
+				<1 RK_PD7 4 &pcfg_pull_none>,
+				/* pcie30x2_perstn_m3 */
+				<1 RK_PB7 4 &pcfg_pull_none>,
+				/* pcie30x2_waken_m3 */
+				<1 RK_PB6 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pcie30x2_button_rstn: pcie30x2-button-rstn {
+			rockchip,pins =
+				/* pcie30x2_button_rstn */
+				<3 RK_PC1 4 &pcfg_pull_none>;
+		};
+	};
+
+	pcie30x4 {
+		/omit-if-no-ref/
+		pcie30x4m0_pins: pcie30x4m0-pins {
+			rockchip,pins =
+				/* pcie30x4_clkreqn_m0 */
+				<0 RK_PC6 12 &pcfg_pull_none>,
+				/* pcie30x4_perstn_m0 */
+				<0 RK_PD0 12 &pcfg_pull_none>,
+				/* pcie30x4_waken_m0 */
+				<0 RK_PC7 12 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pcie30x4m1_pins: pcie30x4m1-pins {
+			rockchip,pins =
+				/* pcie30x4_clkreqn_m1 */
+				<4 RK_PB4 4 &pcfg_pull_none>,
+				/* pcie30x4_perstn_m1 */
+				<4 RK_PB6 4 &pcfg_pull_none>,
+				/* pcie30x4_waken_m1 */
+				<4 RK_PB5 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pcie30x4m2_pins: pcie30x4m2-pins {
+			rockchip,pins =
+				/* pcie30x4_clkreqn_m2 */
+				<3 RK_PC4 4 &pcfg_pull_none>,
+				/* pcie30x4_perstn_m2 */
+				<3 RK_PC6 4 &pcfg_pull_none>,
+				/* pcie30x4_waken_m2 */
+				<3 RK_PC5 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pcie30x4m3_pins: pcie30x4m3-pins {
+			rockchip,pins =
+				/* pcie30x4_clkreqn_m3 */
+				<1 RK_PB0 4 &pcfg_pull_none>,
+				/* pcie30x4_perstn_m3 */
+				<1 RK_PB2 4 &pcfg_pull_none>,
+				/* pcie30x4_waken_m3 */
+				<1 RK_PB1 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pcie30x4_button_rstn: pcie30x4-button-rstn {
+			rockchip,pins =
+				/* pcie30x4_button_rstn */
+				<3 RK_PD5 4 &pcfg_pull_none>;
+		};
+	};
+
+	pdm0 {
+		/omit-if-no-ref/
+		pdm0m0_clk: pdm0m0-clk {
+			rockchip,pins =
+				/* pdm0_clk0_m0 */
+				<1 RK_PC6 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm0m0_clk1: pdm0m0-clk1 {
+			rockchip,pins =
+				/* pdm0m0_clk1 */
+				<1 RK_PC4 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm0m0_sdi0: pdm0m0-sdi0 {
+			rockchip,pins =
+				/* pdm0m0_sdi0 */
+				<1 RK_PD5 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm0m0_sdi1: pdm0m0-sdi1 {
+			rockchip,pins =
+				/* pdm0m0_sdi1 */
+				<1 RK_PD1 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm0m0_sdi2: pdm0m0-sdi2 {
+			rockchip,pins =
+				/* pdm0m0_sdi2 */
+				<1 RK_PD2 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm0m0_sdi3: pdm0m0-sdi3 {
+			rockchip,pins =
+				/* pdm0m0_sdi3 */
+				<1 RK_PD3 3 &pcfg_pull_none>;
+		};
+		/omit-if-no-ref/
+		pdm0m1_clk: pdm0m1-clk {
+			rockchip,pins =
+				/* pdm0_clk0_m1 */
+				<0 RK_PC0 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm0m1_clk1: pdm0m1-clk1 {
+			rockchip,pins =
+				/* pdm0m1_clk1 */
+				<0 RK_PC4 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm0m1_sdi0: pdm0m1-sdi0 {
+			rockchip,pins =
+				/* pdm0m1_sdi0 */
+				<0 RK_PC7 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm0m1_sdi1: pdm0m1-sdi1 {
+			rockchip,pins =
+				/* pdm0m1_sdi1 */
+				<0 RK_PD0 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm0m1_sdi2: pdm0m1-sdi2 {
+			rockchip,pins =
+				/* pdm0m1_sdi2 */
+				<0 RK_PD4 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm0m1_sdi3: pdm0m1-sdi3 {
+			rockchip,pins =
+				/* pdm0m1_sdi3 */
+				<0 RK_PD6 2 &pcfg_pull_none>;
+		};
+	};
+
+	pdm1 {
+		/omit-if-no-ref/
+		pdm1m0_clk: pdm1m0-clk {
+			rockchip,pins =
+				/* pdm1_clk0_m0 */
+				<4 RK_PD5 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm1m0_clk1: pdm1m0-clk1 {
+			rockchip,pins =
+				/* pdm1m0_clk1 */
+				<4 RK_PD4 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm1m0_sdi0: pdm1m0-sdi0 {
+			rockchip,pins =
+				/* pdm1m0_sdi0 */
+				<4 RK_PD3 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm1m0_sdi1: pdm1m0-sdi1 {
+			rockchip,pins =
+				/* pdm1m0_sdi1 */
+				<4 RK_PD2 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm1m0_sdi2: pdm1m0-sdi2 {
+			rockchip,pins =
+				/* pdm1m0_sdi2 */
+				<4 RK_PD1 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm1m0_sdi3: pdm1m0-sdi3 {
+			rockchip,pins =
+				/* pdm1m0_sdi3 */
+				<4 RK_PD0 2 &pcfg_pull_none>;
+		};
+		/omit-if-no-ref/
+		pdm1m1_clk: pdm1m1-clk {
+			rockchip,pins =
+				/* pdm1_clk0_m1 */
+				<1 RK_PB4 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm1m1_clk1: pdm1m1-clk1 {
+			rockchip,pins =
+				/* pdm1m1_clk1 */
+				<1 RK_PB3 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm1m1_sdi0: pdm1m1-sdi0 {
+			rockchip,pins =
+				/* pdm1m1_sdi0 */
+				<1 RK_PA7 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm1m1_sdi1: pdm1m1-sdi1 {
+			rockchip,pins =
+				/* pdm1m1_sdi1 */
+				<1 RK_PB0 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm1m1_sdi2: pdm1m1-sdi2 {
+			rockchip,pins =
+				/* pdm1m1_sdi2 */
+				<1 RK_PB1 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pdm1m1_sdi3: pdm1m1-sdi3 {
+			rockchip,pins =
+				/* pdm1m1_sdi3 */
+				<1 RK_PB2 2 &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		/omit-if-no-ref/
+		pmic_pins: pmic-pins {
+			rockchip,pins =
+				/* pmic_int_l */
+				<0 RK_PA7 0 &pcfg_pull_up>,
+				/* pmic_sleep1 */
+				<0 RK_PA2 1 &pcfg_pull_none>,
+				/* pmic_sleep2 */
+				<0 RK_PA3 1 &pcfg_pull_none>,
+				/* pmic_sleep3 */
+				<0 RK_PC1 1 &pcfg_pull_none>,
+				/* pmic_sleep4 */
+				<0 RK_PC2 1 &pcfg_pull_none>,
+				/* pmic_sleep5 */
+				<0 RK_PC3 1 &pcfg_pull_none>,
+				/* pmic_sleep6 */
+				<0 RK_PD6 1 &pcfg_pull_none>;
+		};
+	};
+
+	pmu {
+		/omit-if-no-ref/
+		pmu_pins: pmu-pins {
+			rockchip,pins =
+				/* pmu_debug */
+				<0 RK_PA5 3 &pcfg_pull_none>;
+		};
+	};
+
+	pwm0 {
+		/omit-if-no-ref/
+		pwm0m0_pins: pwm0m0-pins {
+			rockchip,pins =
+				/* pwm0_m0 */
+				<0 RK_PB7 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm0m1_pins: pwm0m1-pins {
+			rockchip,pins =
+				/* pwm0_m1 */
+				<1 RK_PD2 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm0m2_pins: pwm0m2-pins {
+			rockchip,pins =
+				/* pwm0_m2 */
+				<1 RK_PA2 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm1 {
+		/omit-if-no-ref/
+		pwm1m0_pins: pwm1m0-pins {
+			rockchip,pins =
+				/* pwm1_m0 */
+				<0 RK_PC0 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm1m1_pins: pwm1m1-pins {
+			rockchip,pins =
+				/* pwm1_m1 */
+				<1 RK_PD3 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm1m2_pins: pwm1m2-pins {
+			rockchip,pins =
+				/* pwm1_m2 */
+				<1 RK_PA3 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm2 {
+		/omit-if-no-ref/
+		pwm2m0_pins: pwm2m0-pins {
+			rockchip,pins =
+				/* pwm2_m0 */
+				<0 RK_PC4 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm2m1_pins: pwm2m1-pins {
+			rockchip,pins =
+				/* pwm2_m1 */
+				<3 RK_PB1 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm3 {
+		/omit-if-no-ref/
+		pwm3m0_pins: pwm3m0-pins {
+			rockchip,pins =
+				/* pwm3_ir_m0 */
+				<0 RK_PD4 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm3m1_pins: pwm3m1-pins {
+			rockchip,pins =
+				/* pwm3_ir_m1 */
+				<3 RK_PB2 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm3m2_pins: pwm3m2-pins {
+			rockchip,pins =
+				/* pwm3_ir_m2 */
+				<1 RK_PC2 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm3m3_pins: pwm3m3-pins {
+			rockchip,pins =
+				/* pwm3_ir_m3 */
+				<1 RK_PA7 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm4 {
+		/omit-if-no-ref/
+		pwm4m0_pins: pwm4m0-pins {
+			rockchip,pins =
+				/* pwm4_m0 */
+				<0 RK_PC5 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm5 {
+		/omit-if-no-ref/
+		pwm5m0_pins: pwm5m0-pins {
+			rockchip,pins =
+				/* pwm5_m0 */
+				<0 RK_PB1 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm5m1_pins: pwm5m1-pins {
+			rockchip,pins =
+				/* pwm5_m1 */
+				<0 RK_PC6 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm6 {
+		/omit-if-no-ref/
+		pwm6m0_pins: pwm6m0-pins {
+			rockchip,pins =
+				/* pwm6_m0 */
+				<0 RK_PC7 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm6m1_pins: pwm6m1-pins {
+			rockchip,pins =
+				/* pwm6_m1 */
+				<4 RK_PC1 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm7 {
+		/omit-if-no-ref/
+		pwm7m0_pins: pwm7m0-pins {
+			rockchip,pins =
+				/* pwm7_ir_m0 */
+				<0 RK_PD0 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm7m1_pins: pwm7m1-pins {
+			rockchip,pins =
+				/* pwm7_ir_m1 */
+				<4 RK_PD4 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm7m2_pins: pwm7m2-pins {
+			rockchip,pins =
+				/* pwm7_ir_m2 */
+				<1 RK_PC3 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm8 {
+		/omit-if-no-ref/
+		pwm8m0_pins: pwm8m0-pins {
+			rockchip,pins =
+				/* pwm8_m0 */
+				<3 RK_PA7 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm8m1_pins: pwm8m1-pins {
+			rockchip,pins =
+				/* pwm8_m1 */
+				<4 RK_PD0 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm8m2_pins: pwm8m2-pins {
+			rockchip,pins =
+				/* pwm8_m2 */
+				<3 RK_PD0 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm9 {
+		/omit-if-no-ref/
+		pwm9m0_pins: pwm9m0-pins {
+			rockchip,pins =
+				/* pwm9_m0 */
+				<3 RK_PB0 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm9m1_pins: pwm9m1-pins {
+			rockchip,pins =
+				/* pwm9_m1 */
+				<4 RK_PD1 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm9m2_pins: pwm9m2-pins {
+			rockchip,pins =
+				/* pwm9_m2 */
+				<3 RK_PD1 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm10 {
+		/omit-if-no-ref/
+		pwm10m0_pins: pwm10m0-pins {
+			rockchip,pins =
+				/* pwm10_m0 */
+				<3 RK_PA0 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm10m1_pins: pwm10m1-pins {
+			rockchip,pins =
+				/* pwm10_m1 */
+				<4 RK_PD3 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm10m2_pins: pwm10m2-pins {
+			rockchip,pins =
+				/* pwm10_m2 */
+				<3 RK_PD3 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm11 {
+		/omit-if-no-ref/
+		pwm11m0_pins: pwm11m0-pins {
+			rockchip,pins =
+				/* pwm11_ir_m0 */
+				<3 RK_PA1 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm11m1_pins: pwm11m1-pins {
+			rockchip,pins =
+				/* pwm11_ir_m1 */
+				<4 RK_PB4 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm11m2_pins: pwm11m2-pins {
+			rockchip,pins =
+				/* pwm11_ir_m2 */
+				<1 RK_PC4 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm11m3_pins: pwm11m3-pins {
+			rockchip,pins =
+				/* pwm11_ir_m3 */
+				<3 RK_PD5 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm12 {
+		/omit-if-no-ref/
+		pwm12m0_pins: pwm12m0-pins {
+			rockchip,pins =
+				/* pwm12_m0 */
+				<3 RK_PB5 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm12m1_pins: pwm12m1-pins {
+			rockchip,pins =
+				/* pwm12_m1 */
+				<4 RK_PB5 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm13 {
+		/omit-if-no-ref/
+		pwm13m0_pins: pwm13m0-pins {
+			rockchip,pins =
+				/* pwm13_m0 */
+				<3 RK_PB6 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm13m1_pins: pwm13m1-pins {
+			rockchip,pins =
+				/* pwm13_m1 */
+				<4 RK_PB6 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm13m2_pins: pwm13m2-pins {
+			rockchip,pins =
+				/* pwm13_m2 */
+				<1 RK_PB7 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm14 {
+		/omit-if-no-ref/
+		pwm14m0_pins: pwm14m0-pins {
+			rockchip,pins =
+				/* pwm14_m0 */
+				<3 RK_PC2 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm14m1_pins: pwm14m1-pins {
+			rockchip,pins =
+				/* pwm14_m1 */
+				<4 RK_PB2 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm14m2_pins: pwm14m2-pins {
+			rockchip,pins =
+				/* pwm14_m2 */
+				<1 RK_PD6 11 &pcfg_pull_none>;
+		};
+	};
+
+	pwm15 {
+		/omit-if-no-ref/
+		pwm15m0_pins: pwm15m0-pins {
+			rockchip,pins =
+				/* pwm15_ir_m0 */
+				<3 RK_PC3 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm15m1_pins: pwm15m1-pins {
+			rockchip,pins =
+				/* pwm15_ir_m1 */
+				<4 RK_PB3 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm15m2_pins: pwm15m2-pins {
+			rockchip,pins =
+				/* pwm15_ir_m2 */
+				<1 RK_PC6 11 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		pwm15m3_pins: pwm15m3-pins {
+			rockchip,pins =
+				/* pwm15_ir_m3 */
+				<1 RK_PD7 11 &pcfg_pull_none>;
+		};
+	};
+
+	refclk {
+		/omit-if-no-ref/
+		refclk_pins: refclk-pins {
+			rockchip,pins =
+				/* refclk_out */
+				<0 RK_PA0 1 &pcfg_pull_none>;
+		};
+	};
+
+	sata {
+		/omit-if-no-ref/
+		sata_pins: sata-pins {
+			rockchip,pins =
+				/* sata_cp_pod */
+				<0 RK_PC6 13 &pcfg_pull_none>,
+				/* sata_cpdet */
+				<0 RK_PD4 13 &pcfg_pull_none>,
+				/* sata_mp_switch */
+				<0 RK_PD5 13 &pcfg_pull_none>;
+		};
+	};
+
+	sata0 {
+		/omit-if-no-ref/
+		sata0m0_pins: sata0m0-pins {
+			rockchip,pins =
+				/* sata0_act_led_m0 */
+				<4 RK_PB6 6 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		sata0m1_pins: sata0m1-pins {
+			rockchip,pins =
+				/* sata0_act_led_m1 */
+				<1 RK_PB3 6 &pcfg_pull_none>;
+		};
+	};
+
+	sata1 {
+		/omit-if-no-ref/
+		sata1m0_pins: sata1m0-pins {
+			rockchip,pins =
+				/* sata1_act_led_m0 */
+				<4 RK_PB5 6 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		sata1m1_pins: sata1m1-pins {
+			rockchip,pins =
+				/* sata1_act_led_m1 */
+				<1 RK_PA1 6 &pcfg_pull_none>;
+		};
+	};
+
+	sata2 {
+		/omit-if-no-ref/
+		sata2m0_pins: sata2m0-pins {
+			rockchip,pins =
+				/* sata2_act_led_m0 */
+				<4 RK_PB1 6 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		sata2m1_pins: sata2m1-pins {
+			rockchip,pins =
+				/* sata2_act_led_m1 */
+				<1 RK_PB7 6 &pcfg_pull_none>;
+		};
+	};
+
+	sdio {
+		/omit-if-no-ref/
+		sdiom1_pins: sdiom1-pins {
+			rockchip,pins =
+				/* sdio_clk_m1 */
+				<3 RK_PA5 2 &pcfg_pull_none>,
+				/* sdio_cmd_m1 */
+				<3 RK_PA4 2 &pcfg_pull_none>,
+				/* sdio_d0_m1 */
+				<3 RK_PA0 2 &pcfg_pull_none>,
+				/* sdio_d1_m1 */
+				<3 RK_PA1 2 &pcfg_pull_none>,
+				/* sdio_d2_m1 */
+				<3 RK_PA2 2 &pcfg_pull_none>,
+				/* sdio_d3_m1 */
+				<3 RK_PA3 2 &pcfg_pull_none>;
+		};
+	};
+
+	sdmmc {
+		/omit-if-no-ref/
+		sdmmc_bus4: sdmmc-bus4 {
+			rockchip,pins =
+				/* sdmmc_d0 */
+				<4 RK_PD0 1 &pcfg_pull_up_drv_level_2>,
+				/* sdmmc_d1 */
+				<4 RK_PD1 1 &pcfg_pull_up_drv_level_2>,
+				/* sdmmc_d2 */
+				<4 RK_PD2 1 &pcfg_pull_up_drv_level_2>,
+				/* sdmmc_d3 */
+				<4 RK_PD3 1 &pcfg_pull_up_drv_level_2>;
+		};
+
+		/omit-if-no-ref/
+		sdmmc_clk: sdmmc-clk {
+			rockchip,pins =
+				/* sdmmc_clk */
+				<4 RK_PD5 1 &pcfg_pull_up_drv_level_2>;
+		};
+
+		/omit-if-no-ref/
+		sdmmc_cmd: sdmmc-cmd {
+			rockchip,pins =
+				/* sdmmc_cmd */
+				<4 RK_PD4 1 &pcfg_pull_up_drv_level_2>;
+		};
+
+		/omit-if-no-ref/
+		sdmmc_det: sdmmc-det {
+			rockchip,pins =
+				/* sdmmc_det */
+				<0 RK_PA4 1 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		sdmmc_pwren: sdmmc-pwren {
+			rockchip,pins =
+				/* sdmmc_pwren */
+				<0 RK_PA5 2 &pcfg_pull_none>;
+		};
+	};
+
+	spdif0 {
+		/omit-if-no-ref/
+		spdif0m0_tx: spdif0m0-tx {
+			rockchip,pins =
+				/* spdif0m0_tx */
+				<1 RK_PB6 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		spdif0m1_tx: spdif0m1-tx {
+			rockchip,pins =
+				/* spdif0m1_tx */
+				<4 RK_PB4 6 &pcfg_pull_none>;
+		};
+	};
+
+	spdif1 {
+		/omit-if-no-ref/
+		spdif1m0_tx: spdif1m0-tx {
+			rockchip,pins =
+				/* spdif1m0_tx */
+				<1 RK_PB7 3 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		spdif1m1_tx: spdif1m1-tx {
+			rockchip,pins =
+				/* spdif1m1_tx */
+				<4 RK_PB1 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		spdif1m2_tx: spdif1m2-tx {
+			rockchip,pins =
+				/* spdif1m2_tx */
+				<4 RK_PC1 3 &pcfg_pull_none>;
+		};
+	};
+
+	spi0 {
+		/omit-if-no-ref/
+		spi0m0_pins: spi0m0-pins {
+			rockchip,pins =
+				/* spi0_clk_m0 */
+				<0 RK_PC6 8 &pcfg_pull_up_drv_level_1>,
+				/* spi0_miso_m0 */
+				<0 RK_PC7 8 &pcfg_pull_up_drv_level_1>,
+				/* spi0_mosi_m0 */
+				<0 RK_PC0 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi0m0_cs0: spi0m0-cs0 {
+			rockchip,pins =
+				/* spi0_cs0_m0 */
+				<0 RK_PD1 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi0m0_cs1: spi0m0-cs1 {
+			rockchip,pins =
+				/* spi0_cs1_m0 */
+				<0 RK_PB7 8 &pcfg_pull_up_drv_level_1>;
+		};
+		/omit-if-no-ref/
+		spi0m1_pins: spi0m1-pins {
+			rockchip,pins =
+				/* spi0_clk_m1 */
+				<4 RK_PA2 8 &pcfg_pull_up_drv_level_1>,
+				/* spi0_miso_m1 */
+				<4 RK_PA0 8 &pcfg_pull_up_drv_level_1>,
+				/* spi0_mosi_m1 */
+				<4 RK_PA1 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi0m1_cs0: spi0m1-cs0 {
+			rockchip,pins =
+				/* spi0_cs0_m1 */
+				<4 RK_PB2 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi0m1_cs1: spi0m1-cs1 {
+			rockchip,pins =
+				/* spi0_cs1_m1 */
+				<4 RK_PB1 8 &pcfg_pull_up_drv_level_1>;
+		};
+		/omit-if-no-ref/
+		spi0m2_pins: spi0m2-pins {
+			rockchip,pins =
+				/* spi0_clk_m2 */
+				<1 RK_PB3 8 &pcfg_pull_up_drv_level_1>,
+				/* spi0_miso_m2 */
+				<1 RK_PB1 8 &pcfg_pull_up_drv_level_1>,
+				/* spi0_mosi_m2 */
+				<1 RK_PB2 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi0m2_cs0: spi0m2-cs0 {
+			rockchip,pins =
+				/* spi0_cs0_m2 */
+				<1 RK_PB4 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi0m2_cs1: spi0m2-cs1 {
+			rockchip,pins =
+				/* spi0_cs1_m2 */
+				<1 RK_PB5 8 &pcfg_pull_up_drv_level_1>;
+		};
+		/omit-if-no-ref/
+		spi0m3_pins: spi0m3-pins {
+			rockchip,pins =
+				/* spi0_clk_m3 */
+				<3 RK_PD3 8 &pcfg_pull_up_drv_level_1>,
+				/* spi0_miso_m3 */
+				<3 RK_PD1 8 &pcfg_pull_up_drv_level_1>,
+				/* spi0_mosi_m3 */
+				<3 RK_PD2 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi0m3_cs0: spi0m3-cs0 {
+			rockchip,pins =
+				/* spi0_cs0_m3 */
+				<3 RK_PD4 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi0m3_cs1: spi0m3-cs1 {
+			rockchip,pins =
+				/* spi0_cs1_m3 */
+				<3 RK_PD5 8 &pcfg_pull_up_drv_level_1>;
+		};
+	};
+
+	spi1 {
+		/omit-if-no-ref/
+		spi1m1_pins: spi1m1-pins {
+			rockchip,pins =
+				/* spi1_clk_m1 */
+				<3 RK_PC1 8 &pcfg_pull_up_drv_level_1>,
+				/* spi1_miso_m1 */
+				<3 RK_PC0 8 &pcfg_pull_up_drv_level_1>,
+				/* spi1_mosi_m1 */
+				<3 RK_PB7 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi1m1_cs0: spi1m1-cs0 {
+			rockchip,pins =
+				/* spi1_cs0_m1 */
+				<3 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi1m1_cs1: spi1m1-cs1 {
+			rockchip,pins =
+				/* spi1_cs1_m1 */
+				<3 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi1m2_pins: spi1m2-pins {
+			rockchip,pins =
+				/* spi1_clk_m2 */
+				<1 RK_PD2 8 &pcfg_pull_up_drv_level_1>,
+				/* spi1_miso_m2 */
+				<1 RK_PD0 8 &pcfg_pull_up_drv_level_1>,
+				/* spi1_mosi_m2 */
+				<1 RK_PD1 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi1m2_cs0: spi1m2-cs0 {
+			rockchip,pins =
+				/* spi1_cs0_m2 */
+				<1 RK_PD3 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi1m2_cs1: spi1m2-cs1 {
+			rockchip,pins =
+				/* spi1_cs1_m2 */
+				<1 RK_PD5 8 &pcfg_pull_up_drv_level_1>;
+		};
+	};
+
+	spi2 {
+		/omit-if-no-ref/
+		spi2m0_pins: spi2m0-pins {
+			rockchip,pins =
+				/* spi2_clk_m0 */
+				<1 RK_PA6 8 &pcfg_pull_up_drv_level_1>,
+				/* spi2_miso_m0 */
+				<1 RK_PA4 8 &pcfg_pull_up_drv_level_1>,
+				/* spi2_mosi_m0 */
+				<1 RK_PA5 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi2m0_cs0: spi2m0-cs0 {
+			rockchip,pins =
+				/* spi2_cs0_m0 */
+				<1 RK_PA7 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi2m0_cs1: spi2m0-cs1 {
+			rockchip,pins =
+				/* spi2_cs1_m0 */
+				<1 RK_PB0 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi2m1_pins: spi2m1-pins {
+			rockchip,pins =
+				/* spi2_clk_m1 */
+				<4 RK_PA6 8 &pcfg_pull_up_drv_level_1>,
+				/* spi2_miso_m1 */
+				<4 RK_PA4 8 &pcfg_pull_up_drv_level_1>,
+				/* spi2_mosi_m1 */
+				<4 RK_PA5 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi2m1_cs0: spi2m1-cs0 {
+			rockchip,pins =
+				/* spi2_cs0_m1 */
+				<4 RK_PA7 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi2m1_cs1: spi2m1-cs1 {
+			rockchip,pins =
+				/* spi2_cs1_m1 */
+				<4 RK_PB0 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi2m2_pins: spi2m2-pins {
+			rockchip,pins =
+				/* spi2_clk_m2 */
+				<0 RK_PA5 1 &pcfg_pull_up_drv_level_1>,
+				/* spi2_miso_m2 */
+				<0 RK_PB3 1 &pcfg_pull_up_drv_level_1>,
+				/* spi2_mosi_m2 */
+				<0 RK_PA6 1 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi2m2_cs0: spi2m2-cs0 {
+			rockchip,pins =
+				/* spi2_cs0_m2 */
+				<0 RK_PB1 1 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi2m2_cs1: spi2m2-cs1 {
+			rockchip,pins =
+				/* spi2_cs1_m2 */
+				<0 RK_PB0 1 &pcfg_pull_up_drv_level_1>;
+		};
+	};
+
+	spi3 {
+		/omit-if-no-ref/
+		spi3m1_pins: spi3m1-pins {
+			rockchip,pins =
+				/* spi3_clk_m1 */
+				<4 RK_PB7 8 &pcfg_pull_up_drv_level_1>,
+				/* spi3_miso_m1 */
+				<4 RK_PB5 8 &pcfg_pull_up_drv_level_1>,
+				/* spi3_mosi_m1 */
+				<4 RK_PB6 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi3m1_cs0: spi3m1-cs0 {
+			rockchip,pins =
+				/* spi3_cs0_m1 */
+				<4 RK_PC0 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi3m1_cs1: spi3m1-cs1 {
+			rockchip,pins =
+				/* spi3_cs1_m1 */
+				<4 RK_PC1 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi3m2_pins: spi3m2-pins {
+			rockchip,pins =
+				/* spi3_clk_m2 */
+				<0 RK_PD3 8 &pcfg_pull_up_drv_level_1>,
+				/* spi3_miso_m2 */
+				<0 RK_PD0 8 &pcfg_pull_up_drv_level_1>,
+				/* spi3_mosi_m2 */
+				<0 RK_PD2 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi3m2_cs0: spi3m2-cs0 {
+			rockchip,pins =
+				/* spi3_cs0_m2 */
+				<0 RK_PD4 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi3m2_cs1: spi3m2-cs1 {
+			rockchip,pins =
+				/* spi3_cs1_m2 */
+				<0 RK_PD5 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi3m3_pins: spi3m3-pins {
+			rockchip,pins =
+				/* spi3_clk_m3 */
+				<3 RK_PD0 8 &pcfg_pull_up_drv_level_1>,
+				/* spi3_miso_m3 */
+				<3 RK_PC6 8 &pcfg_pull_up_drv_level_1>,
+				/* spi3_mosi_m3 */
+				<3 RK_PC7 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi3m3_cs0: spi3m3-cs0 {
+			rockchip,pins =
+				/* spi3_cs0_m3 */
+				<3 RK_PC4 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi3m3_cs1: spi3m3-cs1 {
+			rockchip,pins =
+				/* spi3_cs1_m3 */
+				<3 RK_PC5 8 &pcfg_pull_up_drv_level_1>;
+		};
+	};
+
+	spi4 {
+		/omit-if-no-ref/
+		spi4m0_pins: spi4m0-pins {
+			rockchip,pins =
+				/* spi4_clk_m0 */
+				<1 RK_PC2 8 &pcfg_pull_up_drv_level_1>,
+				/* spi4_miso_m0 */
+				<1 RK_PC0 8 &pcfg_pull_up_drv_level_1>,
+				/* spi4_mosi_m0 */
+				<1 RK_PC1 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi4m0_cs0: spi4m0-cs0 {
+			rockchip,pins =
+				/* spi4_cs0_m0 */
+				<1 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi4m0_cs1: spi4m0-cs1 {
+			rockchip,pins =
+				/* spi4_cs1_m0 */
+				<1 RK_PC4 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi4m1_pins: spi4m1-pins {
+			rockchip,pins =
+				/* spi4_clk_m1 */
+				<3 RK_PA2 8 &pcfg_pull_up_drv_level_1>,
+				/* spi4_miso_m1 */
+				<3 RK_PA0 8 &pcfg_pull_up_drv_level_1>,
+				/* spi4_mosi_m1 */
+				<3 RK_PA1 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi4m1_cs0: spi4m1-cs0 {
+			rockchip,pins =
+				/* spi4_cs0_m1 */
+				<3 RK_PA3 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi4m1_cs1: spi4m1-cs1 {
+			rockchip,pins =
+				/* spi4_cs1_m1 */
+				<3 RK_PA4 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi4m2_pins: spi4m2-pins {
+			rockchip,pins =
+				/* spi4_clk_m2 */
+				<1 RK_PA2 8 &pcfg_pull_up_drv_level_1>,
+				/* spi4_miso_m2 */
+				<1 RK_PA0 8 &pcfg_pull_up_drv_level_1>,
+				/* spi4_mosi_m2 */
+				<1 RK_PA1 8 &pcfg_pull_up_drv_level_1>;
+		};
+
+		/omit-if-no-ref/
+		spi4m2_cs0: spi4m2-cs0 {
+			rockchip,pins =
+				/* spi4_cs0_m2 */
+				<1 RK_PA3 8 &pcfg_pull_up_drv_level_1>;
+		};
+	};
+
+	tsadc {
+		/omit-if-no-ref/
+		tsadcm1_shut: tsadcm1-shut {
+			rockchip,pins =
+				/* tsadcm1_shut */
+				<0 RK_PA2 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		tsadc_shut: tsadc-shut {
+			rockchip,pins =
+				/* tsadc_shut */
+				<0 RK_PA1 2 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		tsadc_shut_org: tsadc-shut-org {
+			rockchip,pins =
+				/* tsadc_shut_org */
+				<0 RK_PA1 1 &pcfg_pull_none>;
+		};
+	};
+
+	uart0 {
+		/omit-if-no-ref/
+		uart0m0_xfer: uart0m0-xfer {
+			rockchip,pins =
+				/* uart0_rx_m0 */
+				<0 RK_PC4 4 &pcfg_pull_up>,
+				/* uart0_tx_m0 */
+				<0 RK_PC5 4 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart0m1_xfer: uart0m1-xfer {
+			rockchip,pins =
+				/* uart0_rx_m1 */
+				<0 RK_PB0 4 &pcfg_pull_up>,
+				/* uart0_tx_m1 */
+				<0 RK_PB1 4 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart0m2_xfer: uart0m2-xfer {
+			rockchip,pins =
+				/* uart0_rx_m2 */
+				<4 RK_PA4 10 &pcfg_pull_up>,
+				/* uart0_tx_m2 */
+				<4 RK_PA3 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart0_ctsn: uart0-ctsn {
+			rockchip,pins =
+				/* uart0_ctsn */
+				<0 RK_PD1 4 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart0_rtsn: uart0-rtsn {
+			rockchip,pins =
+				/* uart0_rtsn */
+				<0 RK_PC6 4 &pcfg_pull_none>;
+		};
+	};
+
+	uart1 {
+		/omit-if-no-ref/
+		uart1m1_xfer: uart1m1-xfer {
+			rockchip,pins =
+				/* uart1_rx_m1 */
+				<1 RK_PB7 10 &pcfg_pull_up>,
+				/* uart1_tx_m1 */
+				<1 RK_PB6 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart1m1_ctsn: uart1m1-ctsn {
+			rockchip,pins =
+				/* uart1m1_ctsn */
+				<1 RK_PD7 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart1m1_rtsn: uart1m1-rtsn {
+			rockchip,pins =
+				/* uart1m1_rtsn */
+				<1 RK_PD6 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart1m2_xfer: uart1m2-xfer {
+			rockchip,pins =
+				/* uart1_rx_m2 */
+				<0 RK_PD2 10 &pcfg_pull_up>,
+				/* uart1_tx_m2 */
+				<0 RK_PD1 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart1m2_ctsn: uart1m2-ctsn {
+			rockchip,pins =
+				/* uart1m2_ctsn */
+				<0 RK_PD0 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart1m2_rtsn: uart1m2-rtsn {
+			rockchip,pins =
+				/* uart1m2_rtsn */
+				<0 RK_PC7 10 &pcfg_pull_none>;
+		};
+	};
+
+	uart2 {
+		/omit-if-no-ref/
+		uart2m0_xfer: uart2m0-xfer {
+			rockchip,pins =
+				/* uart2_rx_m0 */
+				<0 RK_PB6 10 &pcfg_pull_up>,
+				/* uart2_tx_m0 */
+				<0 RK_PB5 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart2m1_xfer: uart2m1-xfer {
+			rockchip,pins =
+				/* uart2_rx_m1 */
+				<4 RK_PD1 10 &pcfg_pull_up>,
+				/* uart2_tx_m1 */
+				<4 RK_PD0 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart2m2_xfer: uart2m2-xfer {
+			rockchip,pins =
+				/* uart2_rx_m2 */
+				<3 RK_PB2 10 &pcfg_pull_up>,
+				/* uart2_tx_m2 */
+				<3 RK_PB1 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart2_ctsn: uart2-ctsn {
+			rockchip,pins =
+				/* uart2_ctsn */
+				<3 RK_PB4 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart2_rtsn: uart2-rtsn {
+			rockchip,pins =
+				/* uart2_rtsn */
+				<3 RK_PB3 10 &pcfg_pull_none>;
+		};
+	};
+
+	uart3 {
+		/omit-if-no-ref/
+		uart3m0_xfer: uart3m0-xfer {
+			rockchip,pins =
+				/* uart3_rx_m0 */
+				<1 RK_PC0 10 &pcfg_pull_up>,
+				/* uart3_tx_m0 */
+				<1 RK_PC1 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart3m1_xfer: uart3m1-xfer {
+			rockchip,pins =
+				/* uart3_rx_m1 */
+				<3 RK_PB6 10 &pcfg_pull_up>,
+				/* uart3_tx_m1 */
+				<3 RK_PB5 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart3m2_xfer: uart3m2-xfer {
+			rockchip,pins =
+				/* uart3_rx_m2 */
+				<4 RK_PA6 10 &pcfg_pull_up>,
+				/* uart3_tx_m2 */
+				<4 RK_PA5 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart3_ctsn: uart3-ctsn {
+			rockchip,pins =
+				/* uart3_ctsn */
+				<1 RK_PC3 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart3_rtsn: uart3-rtsn {
+			rockchip,pins =
+				/* uart3_rtsn */
+				<1 RK_PC2 10 &pcfg_pull_none>;
+		};
+	};
+
+	uart4 {
+		/omit-if-no-ref/
+		uart4m0_xfer: uart4m0-xfer {
+			rockchip,pins =
+				/* uart4_rx_m0 */
+				<1 RK_PD3 10 &pcfg_pull_up>,
+				/* uart4_tx_m0 */
+				<1 RK_PD2 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart4m1_xfer: uart4m1-xfer {
+			rockchip,pins =
+				/* uart4_rx_m1 */
+				<3 RK_PD0 10 &pcfg_pull_up>,
+				/* uart4_tx_m1 */
+				<3 RK_PD1 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart4m2_xfer: uart4m2-xfer {
+			rockchip,pins =
+				/* uart4_rx_m2 */
+				<1 RK_PB2 10 &pcfg_pull_up>,
+				/* uart4_tx_m2 */
+				<1 RK_PB3 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart4_ctsn: uart4-ctsn {
+			rockchip,pins =
+				/* uart4_ctsn */
+				<1 RK_PC7 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart4_rtsn: uart4-rtsn {
+			rockchip,pins =
+				/* uart4_rtsn */
+				<1 RK_PC5 10 &pcfg_pull_none>;
+		};
+	};
+
+	uart5 {
+		/omit-if-no-ref/
+		uart5m0_xfer: uart5m0-xfer {
+			rockchip,pins =
+				/* uart5_rx_m0 */
+				<4 RK_PD4 10 &pcfg_pull_up>,
+				/* uart5_tx_m0 */
+				<4 RK_PD5 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart5m0_ctsn: uart5m0-ctsn {
+			rockchip,pins =
+				/* uart5m0_ctsn */
+				<4 RK_PD2 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart5m0_rtsn: uart5m0-rtsn {
+			rockchip,pins =
+				/* uart5m0_rtsn */
+				<4 RK_PD3 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart5m1_xfer: uart5m1-xfer {
+			rockchip,pins =
+				/* uart5_rx_m1 */
+				<3 RK_PC5 10 &pcfg_pull_up>,
+				/* uart5_tx_m1 */
+				<3 RK_PC4 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart5m1_ctsn: uart5m1-ctsn {
+			rockchip,pins =
+				/* uart5m1_ctsn */
+				<2 RK_PA2 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart5m1_rtsn: uart5m1-rtsn {
+			rockchip,pins =
+				/* uart5m1_rtsn */
+				<2 RK_PA3 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart5m2_xfer: uart5m2-xfer {
+			rockchip,pins =
+				/* uart5_rx_m2 */
+				<2 RK_PD4 10 &pcfg_pull_up>,
+				/* uart5_tx_m2 */
+				<2 RK_PD5 10 &pcfg_pull_up>;
+		};
+	};
+
+	uart6 {
+		/omit-if-no-ref/
+		uart6m1_xfer: uart6m1-xfer {
+			rockchip,pins =
+				/* uart6_rx_m1 */
+				<1 RK_PA0 10 &pcfg_pull_up>,
+				/* uart6_tx_m1 */
+				<1 RK_PA1 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart6m1_ctsn: uart6m1-ctsn {
+			rockchip,pins =
+				/* uart6m1_ctsn */
+				<1 RK_PA3 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart6m1_rtsn: uart6m1-rtsn {
+			rockchip,pins =
+				/* uart6m1_rtsn */
+				<1 RK_PA2 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart6m2_xfer: uart6m2-xfer {
+			rockchip,pins =
+				/* uart6_rx_m2 */
+				<1 RK_PD1 10 &pcfg_pull_up>,
+				/* uart6_tx_m2 */
+				<1 RK_PD0 10 &pcfg_pull_up>;
+		};
+	};
+
+	uart7 {
+		/omit-if-no-ref/
+		uart7m1_xfer: uart7m1-xfer {
+			rockchip,pins =
+				/* uart7_rx_m1 */
+				<3 RK_PC1 10 &pcfg_pull_up>,
+				/* uart7_tx_m1 */
+				<3 RK_PC0 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart7m1_ctsn: uart7m1-ctsn {
+			rockchip,pins =
+				/* uart7m1_ctsn */
+				<3 RK_PC3 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart7m1_rtsn: uart7m1-rtsn {
+			rockchip,pins =
+				/* uart7m1_rtsn */
+				<3 RK_PC2 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart7m2_xfer: uart7m2-xfer {
+			rockchip,pins =
+				/* uart7_rx_m2 */
+				<1 RK_PB4 10 &pcfg_pull_up>,
+				/* uart7_tx_m2 */
+				<1 RK_PB5 10 &pcfg_pull_up>;
+		};
+	};
+
+	uart8 {
+		/omit-if-no-ref/
+		uart8m0_xfer: uart8m0-xfer {
+			rockchip,pins =
+				/* uart8_rx_m0 */
+				<4 RK_PB1 10 &pcfg_pull_up>,
+				/* uart8_tx_m0 */
+				<4 RK_PB0 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart8m0_ctsn: uart8m0-ctsn {
+			rockchip,pins =
+				/* uart8m0_ctsn */
+				<4 RK_PB3 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart8m0_rtsn: uart8m0-rtsn {
+			rockchip,pins =
+				/* uart8m0_rtsn */
+				<4 RK_PB2 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart8m1_xfer: uart8m1-xfer {
+			rockchip,pins =
+				/* uart8_rx_m1 */
+				<3 RK_PA3 10 &pcfg_pull_up>,
+				/* uart8_tx_m1 */
+				<3 RK_PA2 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart8m1_ctsn: uart8m1-ctsn {
+			rockchip,pins =
+				/* uart8m1_ctsn */
+				<3 RK_PA5 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart8m1_rtsn: uart8m1-rtsn {
+			rockchip,pins =
+				/* uart8m1_rtsn */
+				<3 RK_PA4 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart8_xfer: uart8-xfer {
+			rockchip,pins =
+				/* uart8_rx_ */
+				<4 RK_PB1 10 &pcfg_pull_up>;
+		};
+	};
+
+	uart9 {
+		/omit-if-no-ref/
+		uart9m1_xfer: uart9m1-xfer {
+			rockchip,pins =
+				/* uart9_rx_m1 */
+				<4 RK_PB5 10 &pcfg_pull_up>,
+				/* uart9_tx_m1 */
+				<4 RK_PB4 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart9m1_ctsn: uart9m1-ctsn {
+			rockchip,pins =
+				/* uart9m1_ctsn */
+				<4 RK_PA1 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart9m1_rtsn: uart9m1-rtsn {
+			rockchip,pins =
+				/* uart9m1_rtsn */
+				<4 RK_PA0 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart9m2_xfer: uart9m2-xfer {
+			rockchip,pins =
+				/* uart9_rx_m2 */
+				<3 RK_PD4 10 &pcfg_pull_up>,
+				/* uart9_tx_m2 */
+				<3 RK_PD5 10 &pcfg_pull_up>;
+		};
+
+		/omit-if-no-ref/
+		uart9m2_ctsn: uart9m2-ctsn {
+			rockchip,pins =
+				/* uart9m2_ctsn */
+				<3 RK_PD3 10 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		uart9m2_rtsn: uart9m2-rtsn {
+			rockchip,pins =
+				/* uart9m2_rtsn */
+				<3 RK_PD2 10 &pcfg_pull_none>;
+		};
+	};
+
+	vop {
+		/omit-if-no-ref/
+		vop_pins: vop-pins {
+			rockchip,pins =
+				/* vop_post_empty */
+				<1 RK_PA2 1 &pcfg_pull_none>;
+		};
+	};
+};
+
+/*
+ * This part is edited handly.
+ */
+&pinctrl {
+	bt656 {
+		/omit-if-no-ref/
+		bt656_pins: bt656-pins {
+			rockchip,pins =
+				/* bt1120_clkout */
+				<4 RK_PB0 2 &pcfg_pull_none_drv_level_2>,
+				/* bt1120_d0 */
+				<4 RK_PA0 2 &pcfg_pull_none_drv_level_2>,
+				/* bt1120_d1 */
+				<4 RK_PA1 2 &pcfg_pull_none_drv_level_2>,
+				/* bt1120_d2 */
+				<4 RK_PA2 2 &pcfg_pull_none_drv_level_2>,
+				/* bt1120_d3 */
+				<4 RK_PA3 2 &pcfg_pull_none_drv_level_2>,
+				/* bt1120_d4 */
+				<4 RK_PA4 2 &pcfg_pull_none_drv_level_2>,
+				/* bt1120_d5 */
+				<4 RK_PA5 2 &pcfg_pull_none_drv_level_2>,
+				/* bt1120_d6 */
+				<4 RK_PA6 2 &pcfg_pull_none_drv_level_2>,
+				/* bt1120_d7 */
+				<4 RK_PA7 2 &pcfg_pull_none_drv_level_2>;
+		};
+	};
+
+	gpio-func {
+		/omit-if-no-ref/
+		tsadc_gpio_func: tsadc-gpio-func {
+			rockchip,pins =
+				<0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
diff --git a/arch/arm/dts/rk3588s-u-boot.dtsi b/arch/arm/dts/rk3588s-u-boot.dtsi
new file mode 100644
index 0000000..1e225d7
--- /dev/null
+++ b/arch/arm/dts/rk3588s-u-boot.dtsi
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#include "rockchip-u-boot.dtsi"
+
+/ {
+	dmc {
+		compatible = "rockchip,rk3588-dmc";
+		bootph-all;
+		status = "okay";
+	};
+
+	pmu1_grf: syscon@fd58a000 {
+		bootph-all;
+		compatible = "rockchip,rk3588-pmu1-grf", "syscon";
+		reg = <0x0 0xfd58a000 0x0 0x2000>;
+	};
+
+	sdmmc: mmc@fe2c0000 {
+		compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
+		reg = <0x0 0xfe2c0000 0x0 0x4000>;
+		interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>,
+			 <&scmi_clk SCMI_HCLK_SD>, <&scmi_clk SCMI_CCLK_SD>;
+		clock-names = "ciu-drive", "ciu-sample", "biu", "ciu";
+		fifo-depth = <0x100>;
+		max-frequency = <200000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>;
+		status = "disabled";
+	};
+
+	otp: nvmem@fecc0000 {
+		compatible = "rockchip,rk3588-otp";
+		reg = <0x0 0xfecc0000 0x0 0x400>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		status = "okay";
+
+		cpu_id: id@7 {
+			reg = <0x07 0x10>;
+		};
+	};
+};
+
+&xin24m {
+	bootph-all;
+	status = "okay";
+};
+
+&cru {
+	bootph-pre-ram;
+	status = "okay";
+};
+
+&sys_grf {
+	bootph-pre-ram;
+	status = "okay";
+};
+
+&uart2 {
+	clock-frequency = <24000000>;
+	bootph-pre-ram;
+	status = "okay";
+};
+
+&ioc {
+	bootph-pre-ram;
+};
diff --git a/arch/arm/dts/rk3588s.dtsi b/arch/arm/dts/rk3588s.dtsi
new file mode 100644
index 0000000..005cde6
--- /dev/null
+++ b/arch/arm/dts/rk3588s.dtsi
@@ -0,0 +1,1703 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ */
+
+#include <dt-bindings/clock/rockchip,rk3588-cru.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/power/rk3588-power.h>
+#include <dt-bindings/reset/rockchip,rk3588-cru.h>
+
+/ {
+	compatible = "rockchip,rk3588";
+
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu_l0>;
+				};
+				core1 {
+					cpu = <&cpu_l1>;
+				};
+				core2 {
+					cpu = <&cpu_l2>;
+				};
+				core3 {
+					cpu = <&cpu_l3>;
+				};
+			};
+			cluster1 {
+				core0 {
+					cpu = <&cpu_b0>;
+				};
+				core1 {
+					cpu = <&cpu_b1>;
+				};
+			};
+			cluster2 {
+				core0 {
+					cpu = <&cpu_b2>;
+				};
+				core1 {
+					cpu = <&cpu_b3>;
+				};
+			};
+		};
+
+		cpu_l0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0>;
+			enable-method = "psci";
+			capacity-dmips-mhz = <530>;
+			clocks = <&scmi_clk SCMI_CLK_CPUL>;
+			cpu-idle-states = <&CPU_SLEEP>;
+			i-cache-size = <32768>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <128>;
+			d-cache-size = <32768>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_cache_l0>;
+			dynamic-power-coefficient = <228>;
+			#cooling-cells = <2>;
+		};
+
+		cpu_l1: cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x100>;
+			enable-method = "psci";
+			capacity-dmips-mhz = <530>;
+			clocks = <&scmi_clk SCMI_CLK_CPUL>;
+			cpu-idle-states = <&CPU_SLEEP>;
+			i-cache-size = <32768>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <128>;
+			d-cache-size = <32768>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_cache_l1>;
+			dynamic-power-coefficient = <228>;
+			#cooling-cells = <2>;
+		};
+
+		cpu_l2: cpu@200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x200>;
+			enable-method = "psci";
+			capacity-dmips-mhz = <530>;
+			clocks = <&scmi_clk SCMI_CLK_CPUL>;
+			cpu-idle-states = <&CPU_SLEEP>;
+			i-cache-size = <32768>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <128>;
+			d-cache-size = <32768>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_cache_l2>;
+			dynamic-power-coefficient = <228>;
+			#cooling-cells = <2>;
+		};
+
+		cpu_l3: cpu@300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x300>;
+			enable-method = "psci";
+			capacity-dmips-mhz = <530>;
+			clocks = <&scmi_clk SCMI_CLK_CPUL>;
+			cpu-idle-states = <&CPU_SLEEP>;
+			i-cache-size = <32768>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <128>;
+			d-cache-size = <32768>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_cache_l3>;
+			dynamic-power-coefficient = <228>;
+			#cooling-cells = <2>;
+		};
+
+		cpu_b0: cpu@400 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a76";
+			reg = <0x400>;
+			enable-method = "psci";
+			capacity-dmips-mhz = <1024>;
+			clocks = <&scmi_clk SCMI_CLK_CPUB01>;
+			cpu-idle-states = <&CPU_SLEEP>;
+			i-cache-size = <65536>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			d-cache-size = <65536>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <256>;
+			next-level-cache = <&l2_cache_b0>;
+			dynamic-power-coefficient = <416>;
+			#cooling-cells = <2>;
+		};
+
+		cpu_b1: cpu@500 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a76";
+			reg = <0x500>;
+			enable-method = "psci";
+			capacity-dmips-mhz = <1024>;
+			clocks = <&scmi_clk SCMI_CLK_CPUB01>;
+			cpu-idle-states = <&CPU_SLEEP>;
+			i-cache-size = <65536>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			d-cache-size = <65536>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <256>;
+			next-level-cache = <&l2_cache_b1>;
+			dynamic-power-coefficient = <416>;
+			#cooling-cells = <2>;
+		};
+
+		cpu_b2: cpu@600 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a76";
+			reg = <0x600>;
+			enable-method = "psci";
+			capacity-dmips-mhz = <1024>;
+			clocks = <&scmi_clk SCMI_CLK_CPUB23>;
+			cpu-idle-states = <&CPU_SLEEP>;
+			i-cache-size = <65536>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			d-cache-size = <65536>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <256>;
+			next-level-cache = <&l2_cache_b2>;
+			dynamic-power-coefficient = <416>;
+			#cooling-cells = <2>;
+		};
+
+		cpu_b3: cpu@700 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a76";
+			reg = <0x700>;
+			enable-method = "psci";
+			capacity-dmips-mhz = <1024>;
+			clocks = <&scmi_clk SCMI_CLK_CPUB23>;
+			cpu-idle-states = <&CPU_SLEEP>;
+			i-cache-size = <65536>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			d-cache-size = <65536>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <256>;
+			next-level-cache = <&l2_cache_b3>;
+			dynamic-power-coefficient = <416>;
+			#cooling-cells = <2>;
+		};
+
+		idle-states {
+			entry-method = "psci";
+			CPU_SLEEP: cpu-sleep {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x0010000>;
+				entry-latency-us = <100>;
+				exit-latency-us = <120>;
+				min-residency-us = <1000>;
+			};
+		};
+
+		l2_cache_l0: l2-cache-l0 {
+			compatible = "cache";
+			cache-size = <131072>;
+			cache-line-size = <64>;
+			cache-sets = <512>;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_l1: l2-cache-l1 {
+			compatible = "cache";
+			cache-size = <131072>;
+			cache-line-size = <64>;
+			cache-sets = <512>;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_l2: l2-cache-l2 {
+			compatible = "cache";
+			cache-size = <131072>;
+			cache-line-size = <64>;
+			cache-sets = <512>;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_l3: l2-cache-l3 {
+			compatible = "cache";
+			cache-size = <131072>;
+			cache-line-size = <64>;
+			cache-sets = <512>;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_b0: l2-cache-b0 {
+			compatible = "cache";
+			cache-size = <524288>;
+			cache-line-size = <64>;
+			cache-sets = <1024>;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_b1: l2-cache-b1 {
+			compatible = "cache";
+			cache-size = <524288>;
+			cache-line-size = <64>;
+			cache-sets = <1024>;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_b2: l2-cache-b2 {
+			compatible = "cache";
+			cache-size = <524288>;
+			cache-line-size = <64>;
+			cache-sets = <1024>;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_b3: l2-cache-b3 {
+			compatible = "cache";
+			cache-size = <524288>;
+			cache-line-size = <64>;
+			cache-sets = <1024>;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l3_cache: l3-cache {
+			compatible = "cache";
+			cache-size = <3145728>;
+			cache-line-size = <64>;
+			cache-sets = <4096>;
+		};
+	};
+
+	firmware {
+		optee: optee {
+			compatible = "linaro,optee-tz";
+			method = "smc";
+		};
+
+		scmi: scmi {
+			compatible = "arm,scmi-smc";
+			arm,smc-id = <0x82000010>;
+			shmem = <&scmi_shmem>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			scmi_clk: protocol@14 {
+				reg = <0x14>;
+				assigned-clocks = <&scmi_clk SCMI_CLK_CPUB01>,
+						  <&scmi_clk SCMI_CLK_CPUB23>;
+				assigned-clock-rates = <1200000000>,
+						       <1200000000>;
+				#clock-cells = <1>;
+			};
+
+			scmi_reset: protocol@16 {
+				reg = <0x16>;
+				#reset-cells = <1>;
+			};
+		};
+	};
+
+	pmu-a55 {
+		compatible = "arm,cortex-a55-pmu";
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition0>;
+	};
+
+	pmu-a76 {
+		compatible = "arm,cortex-a76-pmu";
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition1>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	spll: clock-0 {
+		compatible = "fixed-clock";
+		clock-frequency = <702000000>;
+		clock-output-names = "spll";
+		#clock-cells = <0>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_PPI 12 IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt";
+	};
+
+	xin24m: clock-1 {
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "xin24m";
+		#clock-cells = <0>;
+	};
+
+	xin32k: clock-2 {
+		compatible = "fixed-clock";
+		clock-frequency = <32768>;
+		clock-output-names = "xin32k";
+		#clock-cells = <0>;
+	};
+
+	pmu_sram: sram@10f000 {
+		compatible = "mmio-sram";
+		reg = <0x0 0x0010f000 0x0 0x100>;
+		ranges = <0 0x0 0x0010f000 0x100>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		scmi_shmem: sram@0 {
+			compatible = "arm,scmi-shmem";
+			reg = <0x0 0x100>;
+		};
+	};
+
+	sys_grf: syscon@fd58c000 {
+		compatible = "rockchip,rk3588-sys-grf", "syscon";
+		reg = <0x0 0xfd58c000 0x0 0x1000>;
+	};
+
+	php_grf: syscon@fd5b0000 {
+		compatible = "rockchip,rk3588-php-grf", "syscon";
+		reg = <0x0 0xfd5b0000 0x0 0x1000>;
+	};
+
+	ioc: syscon@fd5f0000 {
+		compatible = "rockchip,rk3588-ioc", "syscon";
+		reg = <0x0 0xfd5f0000 0x0 0x10000>;
+	};
+
+	system_sram1: sram@fd600000 {
+		compatible = "mmio-sram";
+		reg = <0x0 0xfd600000 0x0 0x100000>;
+		ranges = <0x0 0x0 0xfd600000 0x100000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+
+	cru: clock-controller@fd7c0000 {
+		compatible = "rockchip,rk3588-cru";
+		reg = <0x0 0xfd7c0000 0x0 0x5c000>;
+		assigned-clocks =
+			<&cru PLL_PPLL>, <&cru PLL_AUPLL>,
+			<&cru PLL_NPLL>, <&cru PLL_GPLL>,
+			<&cru ACLK_CENTER_ROOT>,
+			<&cru HCLK_CENTER_ROOT>, <&cru ACLK_CENTER_LOW_ROOT>,
+			<&cru ACLK_TOP_ROOT>, <&cru PCLK_TOP_ROOT>,
+			<&cru ACLK_LOW_TOP_ROOT>, <&cru PCLK_PMU0_ROOT>,
+			<&cru HCLK_PMU_CM0_ROOT>, <&cru ACLK_VOP>,
+			<&cru ACLK_BUS_ROOT>, <&cru CLK_150M_SRC>,
+			<&cru CLK_GPU>;
+		assigned-clock-rates =
+			<100000000>, <786432000>,
+			<850000000>, <1188000000>,
+			<702000000>,
+			<400000000>, <500000000>,
+			<800000000>, <100000000>,
+			<400000000>, <100000000>,
+			<200000000>, <500000000>,
+			<375000000>, <150000000>,
+			<200000000>;
+		rockchip,grf = <&php_grf>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	i2c0: i2c@fd880000 {
+		compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xfd880000 0x0 0x1000>;
+		interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru CLK_I2C0>, <&cru PCLK_I2C0>;
+		clock-names = "i2c", "pclk";
+		pinctrl-0 = <&i2c0m0_xfer>;
+		pinctrl-names = "default";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	uart0: serial@fd890000 {
+		compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xfd890000 0x0 0x100>;
+		interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac0 6>, <&dmac0 7>;
+		dma-names = "tx", "rx";
+		pinctrl-0 = <&uart0m1_xfer>;
+		pinctrl-names = "default";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		status = "disabled";
+	};
+
+	pwm0: pwm@fd8b0000 {
+		compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xfd8b0000 0x0 0x10>;
+		clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
+		clock-names = "pwm", "pclk";
+		pinctrl-0 = <&pwm0m0_pins>;
+		pinctrl-names = "default";
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm1: pwm@fd8b0010 {
+		compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xfd8b0010 0x0 0x10>;
+		clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
+		clock-names = "pwm", "pclk";
+		pinctrl-0 = <&pwm1m0_pins>;
+		pinctrl-names = "default";
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm2: pwm@fd8b0020 {
+		compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xfd8b0020 0x0 0x10>;
+		clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
+		clock-names = "pwm", "pclk";
+		pinctrl-0 = <&pwm2m0_pins>;
+		pinctrl-names = "default";
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm3: pwm@fd8b0030 {
+		compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xfd8b0030 0x0 0x10>;
+		clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
+		clock-names = "pwm", "pclk";
+		pinctrl-0 = <&pwm3m0_pins>;
+		pinctrl-names = "default";
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pmu: power-management@fd8d8000 {
+		compatible = "rockchip,rk3588-pmu", "syscon", "simple-mfd";
+		reg = <0x0 0xfd8d8000 0x0 0x400>;
+
+		power: power-controller {
+			compatible = "rockchip,rk3588-power-controller";
+			#address-cells = <1>;
+			#power-domain-cells = <1>;
+			#size-cells = <0>;
+			status = "okay";
+
+			/* These power domains are grouped by VD_NPU */
+			power-domain@RK3588_PD_NPU {
+				reg = <RK3588_PD_NPU>;
+				#power-domain-cells = <0>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				power-domain@RK3588_PD_NPUTOP {
+					reg = <RK3588_PD_NPUTOP>;
+					clocks = <&cru HCLK_NPU_ROOT>,
+						 <&cru PCLK_NPU_ROOT>,
+						 <&cru CLK_NPU_DSU0>,
+						 <&cru HCLK_NPU_CM0_ROOT>;
+					pm_qos = <&qos_npu0_mwr>,
+						 <&qos_npu0_mro>,
+						 <&qos_mcu_npu>;
+					#power-domain-cells = <0>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					power-domain@RK3588_PD_NPU1 {
+						reg = <RK3588_PD_NPU1>;
+						clocks = <&cru HCLK_NPU_ROOT>,
+							 <&cru PCLK_NPU_ROOT>,
+							 <&cru CLK_NPU_DSU0>;
+						pm_qos = <&qos_npu1>;
+						#power-domain-cells = <0>;
+					};
+					power-domain@RK3588_PD_NPU2 {
+						reg = <RK3588_PD_NPU2>;
+						clocks = <&cru HCLK_NPU_ROOT>,
+							 <&cru PCLK_NPU_ROOT>,
+							 <&cru CLK_NPU_DSU0>;
+						pm_qos = <&qos_npu2>;
+						#power-domain-cells = <0>;
+					};
+				};
+			};
+			/* These power domains are grouped by VD_GPU */
+			power-domain@RK3588_PD_GPU {
+				reg = <RK3588_PD_GPU>;
+				clocks = <&cru CLK_GPU>,
+					 <&cru CLK_GPU_COREGROUP>,
+					 <&cru CLK_GPU_STACKS>;
+				pm_qos = <&qos_gpu_m0>,
+					 <&qos_gpu_m1>,
+					 <&qos_gpu_m2>,
+					 <&qos_gpu_m3>;
+				#power-domain-cells = <0>;
+			};
+			/* These power domains are grouped by VD_VCODEC */
+			power-domain@RK3588_PD_VCODEC {
+				reg = <RK3588_PD_VCODEC>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				#power-domain-cells = <0>;
+
+				power-domain@RK3588_PD_RKVDEC0 {
+					reg = <RK3588_PD_RKVDEC0>;
+					clocks = <&cru HCLK_RKVDEC0>,
+						 <&cru HCLK_VDPU_ROOT>,
+						 <&cru ACLK_VDPU_ROOT>,
+						 <&cru ACLK_RKVDEC0>,
+						 <&cru ACLK_RKVDEC_CCU>;
+					pm_qos = <&qos_rkvdec0>;
+					#power-domain-cells = <0>;
+				};
+				power-domain@RK3588_PD_RKVDEC1 {
+					reg = <RK3588_PD_RKVDEC1>;
+					clocks = <&cru HCLK_RKVDEC1>,
+						 <&cru HCLK_VDPU_ROOT>,
+						 <&cru ACLK_VDPU_ROOT>,
+						 <&cru ACLK_RKVDEC1>;
+					pm_qos = <&qos_rkvdec1>;
+					#power-domain-cells = <0>;
+				};
+				power-domain@RK3588_PD_VENC0 {
+					reg = <RK3588_PD_VENC0>;
+					clocks = <&cru HCLK_RKVENC0>,
+						 <&cru ACLK_RKVENC0>;
+					pm_qos = <&qos_rkvenc0_m0ro>,
+						 <&qos_rkvenc0_m1ro>,
+						 <&qos_rkvenc0_m2wo>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+					#power-domain-cells = <0>;
+
+					power-domain@RK3588_PD_VENC1 {
+						reg = <RK3588_PD_VENC1>;
+						clocks = <&cru HCLK_RKVENC1>,
+							 <&cru HCLK_RKVENC0>,
+							 <&cru ACLK_RKVENC0>,
+							 <&cru ACLK_RKVENC1>;
+						pm_qos = <&qos_rkvenc1_m0ro>,
+							 <&qos_rkvenc1_m1ro>,
+							 <&qos_rkvenc1_m2wo>;
+						#power-domain-cells = <0>;
+					};
+				};
+			};
+			/* These power domains are grouped by VD_LOGIC */
+			power-domain@RK3588_PD_VDPU {
+				reg = <RK3588_PD_VDPU>;
+				clocks = <&cru HCLK_VDPU_ROOT>,
+					 <&cru ACLK_VDPU_LOW_ROOT>,
+					 <&cru ACLK_VDPU_ROOT>,
+					 <&cru ACLK_JPEG_DECODER_ROOT>,
+					 <&cru ACLK_IEP2P0>,
+					 <&cru HCLK_IEP2P0>,
+					 <&cru ACLK_JPEG_ENCODER0>,
+					 <&cru HCLK_JPEG_ENCODER0>,
+					 <&cru ACLK_JPEG_ENCODER1>,
+					 <&cru HCLK_JPEG_ENCODER1>,
+					 <&cru ACLK_JPEG_ENCODER2>,
+					 <&cru HCLK_JPEG_ENCODER2>,
+					 <&cru ACLK_JPEG_ENCODER3>,
+					 <&cru HCLK_JPEG_ENCODER3>,
+					 <&cru ACLK_JPEG_DECODER>,
+					 <&cru HCLK_JPEG_DECODER>,
+					 <&cru ACLK_RGA2>,
+					 <&cru HCLK_RGA2>;
+				pm_qos = <&qos_iep>,
+					 <&qos_jpeg_dec>,
+					 <&qos_jpeg_enc0>,
+					 <&qos_jpeg_enc1>,
+					 <&qos_jpeg_enc2>,
+					 <&qos_jpeg_enc3>,
+					 <&qos_rga2_mro>,
+					 <&qos_rga2_mwo>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				#power-domain-cells = <0>;
+
+
+				power-domain@RK3588_PD_AV1 {
+					reg = <RK3588_PD_AV1>;
+					clocks = <&cru PCLK_AV1>,
+						 <&cru ACLK_AV1>,
+						 <&cru HCLK_VDPU_ROOT>;
+					pm_qos = <&qos_av1>;
+					#power-domain-cells = <0>;
+				};
+				power-domain@RK3588_PD_RKVDEC0 {
+					reg = <RK3588_PD_RKVDEC0>;
+					clocks = <&cru HCLK_RKVDEC0>,
+						 <&cru HCLK_VDPU_ROOT>,
+						 <&cru ACLK_VDPU_ROOT>,
+						 <&cru ACLK_RKVDEC0>;
+					pm_qos = <&qos_rkvdec0>;
+					#power-domain-cells = <0>;
+				};
+				power-domain@RK3588_PD_RKVDEC1 {
+					reg = <RK3588_PD_RKVDEC1>;
+					clocks = <&cru HCLK_RKVDEC1>,
+						 <&cru HCLK_VDPU_ROOT>,
+						 <&cru ACLK_VDPU_ROOT>;
+					pm_qos = <&qos_rkvdec1>;
+					#power-domain-cells = <0>;
+				};
+				power-domain@RK3588_PD_RGA30 {
+					reg = <RK3588_PD_RGA30>;
+					clocks = <&cru ACLK_RGA3_0>,
+						 <&cru HCLK_RGA3_0>;
+					pm_qos = <&qos_rga3_0>;
+					#power-domain-cells = <0>;
+				};
+			};
+			power-domain@RK3588_PD_VOP {
+				reg = <RK3588_PD_VOP>;
+				clocks = <&cru PCLK_VOP_ROOT>,
+					 <&cru HCLK_VOP_ROOT>,
+					 <&cru ACLK_VOP>;
+				pm_qos = <&qos_vop_m0>,
+					 <&qos_vop_m1>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				#power-domain-cells = <0>;
+
+				power-domain@RK3588_PD_VO0 {
+					reg = <RK3588_PD_VO0>;
+					clocks = <&cru PCLK_VO0_ROOT>,
+						 <&cru PCLK_VO0_S_ROOT>,
+						 <&cru HCLK_VO0_S_ROOT>,
+						 <&cru ACLK_VO0_ROOT>,
+						 <&cru HCLK_HDCP0>,
+						 <&cru ACLK_HDCP0>,
+						 <&cru HCLK_VOP_ROOT>;
+					pm_qos = <&qos_hdcp0>;
+					#power-domain-cells = <0>;
+				};
+			};
+			power-domain@RK3588_PD_VO1 {
+				reg = <RK3588_PD_VO1>;
+				clocks = <&cru PCLK_VO1_ROOT>,
+					 <&cru PCLK_VO1_S_ROOT>,
+					 <&cru HCLK_VO1_S_ROOT>,
+					 <&cru HCLK_HDCP1>,
+					 <&cru ACLK_HDCP1>,
+					 <&cru ACLK_HDMIRX_ROOT>,
+					 <&cru HCLK_VO1USB_TOP_ROOT>;
+				pm_qos = <&qos_hdcp1>,
+					 <&qos_hdmirx>;
+				#power-domain-cells = <0>;
+			};
+			power-domain@RK3588_PD_VI {
+				reg = <RK3588_PD_VI>;
+				clocks = <&cru HCLK_VI_ROOT>,
+					 <&cru PCLK_VI_ROOT>,
+					 <&cru HCLK_ISP0>,
+					 <&cru ACLK_ISP0>,
+					 <&cru HCLK_VICAP>,
+					 <&cru ACLK_VICAP>;
+				pm_qos = <&qos_isp0_mro>,
+					 <&qos_isp0_mwo>,
+					 <&qos_vicap_m0>,
+					 <&qos_vicap_m1>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				#power-domain-cells = <0>;
+
+				power-domain@RK3588_PD_ISP1 {
+					reg = <RK3588_PD_ISP1>;
+					clocks = <&cru HCLK_ISP1>,
+						 <&cru ACLK_ISP1>,
+						 <&cru HCLK_VI_ROOT>,
+						 <&cru PCLK_VI_ROOT>;
+					pm_qos = <&qos_isp1_mwo>,
+						 <&qos_isp1_mro>;
+					#power-domain-cells = <0>;
+				};
+				power-domain@RK3588_PD_FEC {
+					reg = <RK3588_PD_FEC>;
+					clocks = <&cru HCLK_FISHEYE0>,
+						 <&cru ACLK_FISHEYE0>,
+						 <&cru HCLK_FISHEYE1>,
+						 <&cru ACLK_FISHEYE1>,
+						 <&cru PCLK_VI_ROOT>;
+					pm_qos = <&qos_fisheye0>,
+						 <&qos_fisheye1>;
+					#power-domain-cells = <0>;
+				};
+			};
+			power-domain@RK3588_PD_RGA31 {
+				reg = <RK3588_PD_RGA31>;
+				clocks = <&cru HCLK_RGA3_1>,
+					 <&cru ACLK_RGA3_1>;
+				pm_qos = <&qos_rga3_1>;
+				#power-domain-cells = <0>;
+			};
+			power-domain@RK3588_PD_USB {
+				reg = <RK3588_PD_USB>;
+				clocks = <&cru PCLK_PHP_ROOT>,
+					 <&cru ACLK_USB_ROOT>,
+					 <&cru HCLK_USB_ROOT>,
+					 <&cru HCLK_HOST0>,
+					 <&cru HCLK_HOST_ARB0>,
+					 <&cru HCLK_HOST1>,
+					 <&cru HCLK_HOST_ARB1>;
+				pm_qos = <&qos_usb3_0>,
+					 <&qos_usb3_1>,
+					 <&qos_usb2host_0>,
+					 <&qos_usb2host_1>;
+				#power-domain-cells = <0>;
+			};
+			power-domain@RK3588_PD_GMAC {
+				reg = <RK3588_PD_GMAC>;
+				clocks = <&cru PCLK_PHP_ROOT>,
+					 <&cru ACLK_PCIE_ROOT>,
+					 <&cru ACLK_PHP_ROOT>;
+				#power-domain-cells = <0>;
+			};
+			power-domain@RK3588_PD_PCIE {
+				reg = <RK3588_PD_PCIE>;
+				clocks = <&cru PCLK_PHP_ROOT>,
+					 <&cru ACLK_PCIE_ROOT>,
+					 <&cru ACLK_PHP_ROOT>;
+				#power-domain-cells = <0>;
+			};
+			power-domain@RK3588_PD_SDIO {
+				reg = <RK3588_PD_SDIO>;
+				clocks = <&cru HCLK_SDIO>,
+					 <&cru HCLK_NVM_ROOT>;
+				pm_qos = <&qos_sdio>;
+				#power-domain-cells = <0>;
+			};
+			power-domain@RK3588_PD_AUDIO {
+				reg = <RK3588_PD_AUDIO>;
+				clocks = <&cru HCLK_AUDIO_ROOT>,
+					 <&cru PCLK_AUDIO_ROOT>;
+				#power-domain-cells = <0>;
+			};
+			power-domain@RK3588_PD_SDMMC {
+				reg = <RK3588_PD_SDMMC>;
+				pm_qos = <&qos_sdmmc>;
+				#power-domain-cells = <0>;
+			};
+		};
+	};
+
+	qos_gpu_m0: qos@fdf35000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf35000 0x0 0x20>;
+	};
+
+	qos_gpu_m1: qos@fdf35200 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf35200 0x0 0x20>;
+	};
+
+	qos_gpu_m2: qos@fdf35400 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf35400 0x0 0x20>;
+	};
+
+	qos_gpu_m3: qos@fdf35600 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf35600 0x0 0x20>;
+	};
+
+	qos_rga3_1: qos@fdf36000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf36000 0x0 0x20>;
+	};
+
+	qos_sdio: qos@fdf39000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf39000 0x0 0x20>;
+	};
+
+	qos_sdmmc: qos@fdf3d800 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf3d800 0x0 0x20>;
+	};
+
+	qos_usb3_1: qos@fdf3e000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf3e000 0x0 0x20>;
+	};
+
+	qos_usb3_0: qos@fdf3e200 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf3e200 0x0 0x20>;
+	};
+
+	qos_usb2host_0: qos@fdf3e400 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf3e400 0x0 0x20>;
+	};
+
+	qos_usb2host_1: qos@fdf3e600 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf3e600 0x0 0x20>;
+	};
+
+	qos_fisheye0: qos@fdf40000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf40000 0x0 0x20>;
+	};
+
+	qos_fisheye1: qos@fdf40200 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf40200 0x0 0x20>;
+	};
+
+	qos_isp0_mro: qos@fdf40400 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf40400 0x0 0x20>;
+	};
+
+	qos_isp0_mwo: qos@fdf40500 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf40500 0x0 0x20>;
+	};
+
+	qos_vicap_m0: qos@fdf40600 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf40600 0x0 0x20>;
+	};
+
+	qos_vicap_m1: qos@fdf40800 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf40800 0x0 0x20>;
+	};
+
+	qos_isp1_mwo: qos@fdf41000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf41000 0x0 0x20>;
+	};
+
+	qos_isp1_mro: qos@fdf41100 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf41100 0x0 0x20>;
+	};
+
+	qos_rkvenc0_m0ro: qos@fdf60000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf60000 0x0 0x20>;
+	};
+
+	qos_rkvenc0_m1ro: qos@fdf60200 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf60200 0x0 0x20>;
+	};
+
+	qos_rkvenc0_m2wo: qos@fdf60400 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf60400 0x0 0x20>;
+	};
+
+	qos_rkvenc1_m0ro: qos@fdf61000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf61000 0x0 0x20>;
+	};
+
+	qos_rkvenc1_m1ro: qos@fdf61200 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf61200 0x0 0x20>;
+	};
+
+	qos_rkvenc1_m2wo: qos@fdf61400 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf61400 0x0 0x20>;
+	};
+
+	qos_rkvdec0: qos@fdf62000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf62000 0x0 0x20>;
+	};
+
+	qos_rkvdec1: qos@fdf63000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf63000 0x0 0x20>;
+	};
+
+	qos_av1: qos@fdf64000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf64000 0x0 0x20>;
+	};
+
+	qos_iep: qos@fdf66000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf66000 0x0 0x20>;
+	};
+
+	qos_jpeg_dec: qos@fdf66200 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf66200 0x0 0x20>;
+	};
+
+	qos_jpeg_enc0: qos@fdf66400 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf66400 0x0 0x20>;
+	};
+
+	qos_jpeg_enc1: qos@fdf66600 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf66600 0x0 0x20>;
+	};
+
+	qos_jpeg_enc2: qos@fdf66800 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf66800 0x0 0x20>;
+	};
+
+	qos_jpeg_enc3: qos@fdf66a00 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf66a00 0x0 0x20>;
+	};
+
+	qos_rga2_mro: qos@fdf66c00 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf66c00 0x0 0x20>;
+	};
+
+	qos_rga2_mwo: qos@fdf66e00 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf66e00 0x0 0x20>;
+	};
+
+	qos_rga3_0: qos@fdf67000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf67000 0x0 0x20>;
+	};
+
+	qos_vdpu: qos@fdf67200 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf67200 0x0 0x20>;
+	};
+
+	qos_npu1: qos@fdf70000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf70000 0x0 0x20>;
+	};
+
+	qos_npu2: qos@fdf71000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf71000 0x0 0x20>;
+	};
+
+	qos_npu0_mwr: qos@fdf72000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf72000 0x0 0x20>;
+	};
+
+	qos_npu0_mro: qos@fdf72200 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf72200 0x0 0x20>;
+	};
+
+	qos_mcu_npu: qos@fdf72400 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf72400 0x0 0x20>;
+	};
+
+	qos_hdcp0: qos@fdf80000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf80000 0x0 0x20>;
+	};
+
+	qos_hdcp1: qos@fdf81000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf81000 0x0 0x20>;
+	};
+
+	qos_hdmirx: qos@fdf81200 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf81200 0x0 0x20>;
+	};
+
+	qos_vop_m0: qos@fdf82000 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf82000 0x0 0x20>;
+	};
+
+	qos_vop_m1: qos@fdf82200 {
+		compatible = "rockchip,rk3588-qos", "syscon";
+		reg = <0x0 0xfdf82200 0x0 0x20>;
+	};
+
+	gmac1: ethernet@fe1c0000 {
+		compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
+		reg = <0x0 0xfe1c0000 0x0 0x10000>;
+		interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = "macirq", "eth_wake_irq";
+		clocks = <&cru CLK_GMAC_125M>, <&cru CLK_GMAC_50M>,
+			 <&cru PCLK_GMAC1>, <&cru ACLK_GMAC1>,
+			 <&cru CLK_GMAC1_PTP_REF>;
+		clock-names = "stmmaceth", "clk_mac_ref",
+			      "pclk_mac", "aclk_mac",
+			      "ptp_ref";
+		power-domains = <&power RK3588_PD_GMAC>;
+		resets = <&cru SRST_A_GMAC1>;
+		reset-names = "stmmaceth";
+		rockchip,grf = <&sys_grf>;
+		rockchip,php-grf = <&php_grf>;
+		snps,axi-config = <&gmac1_stmmac_axi_setup>;
+		snps,mixed-burst;
+		snps,mtl-rx-config = <&gmac1_mtl_rx_setup>;
+		snps,mtl-tx-config = <&gmac1_mtl_tx_setup>;
+		snps,tso;
+		status = "disabled";
+
+		mdio1: mdio {
+			compatible = "snps,dwmac-mdio";
+			#address-cells = <0x1>;
+			#size-cells = <0x0>;
+		};
+
+		gmac1_stmmac_axi_setup: stmmac-axi-config {
+			snps,blen = <0 0 0 0 16 8 4>;
+			snps,wr_osr_lmt = <4>;
+			snps,rd_osr_lmt = <8>;
+		};
+
+		gmac1_mtl_rx_setup: rx-queues-config {
+			snps,rx-queues-to-use = <2>;
+			queue0 {};
+			queue1 {};
+		};
+
+		gmac1_mtl_tx_setup: tx-queues-config {
+			snps,tx-queues-to-use = <2>;
+			queue0 {};
+			queue1 {};
+		};
+	};
+
+	sdhci: mmc@fe2e0000 {
+		compatible = "rockchip,rk3588-dwcmshc";
+		reg = <0x0 0xfe2e0000 0x0 0x10000>;
+		interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH 0>;
+		assigned-clocks = <&cru BCLK_EMMC>, <&cru TMCLK_EMMC>, <&cru CCLK_EMMC>;
+		assigned-clock-rates = <200000000>, <24000000>, <200000000>;
+		clocks = <&cru CCLK_EMMC>, <&cru HCLK_EMMC>,
+			 <&cru ACLK_EMMC>, <&cru BCLK_EMMC>,
+			 <&cru TMCLK_EMMC>;
+		clock-names = "core", "bus", "axi", "block", "timer";
+		max-frequency = <200000000>;
+		resets = <&cru SRST_C_EMMC>, <&cru SRST_H_EMMC>,
+			 <&cru SRST_A_EMMC>, <&cru SRST_B_EMMC>,
+			 <&cru SRST_T_EMMC>;
+		reset-names = "core", "bus", "axi", "block", "timer";
+		status = "disabled";
+	};
+
+	gic: interrupt-controller@fe600000 {
+		compatible = "arm,gic-v3";
+		reg = <0x0 0xfe600000 0 0x10000>, /* GICD */
+		      <0x0 0xfe680000 0 0x100000>; /* GICR */
+		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-controller;
+		mbi-alias = <0x0 0xfe610000>;
+		mbi-ranges = <424 56>;
+		msi-controller;
+		#interrupt-cells = <4>;
+
+		ppi-partitions {
+			ppi_partition0: interrupt-partition-0 {
+				affinity = <&cpu_l0 &cpu_l1 &cpu_l2 &cpu_l3>;
+			};
+
+			ppi_partition1: interrupt-partition-1 {
+				affinity = <&cpu_b0 &cpu_b1 &cpu_b2 &cpu_b3>;
+			};
+		};
+	};
+
+	dmac0: dma-controller@fea10000 {
+		compatible = "arm,pl330", "arm,primecell";
+		reg = <0x0 0xfea10000 0x0 0x4000>;
+		interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH 0>;
+		arm,pl330-periph-burst;
+		clocks = <&cru ACLK_DMAC0>;
+		clock-names = "apb_pclk";
+		#dma-cells = <1>;
+	};
+
+	dmac1: dma-controller@fea30000 {
+		compatible = "arm,pl330", "arm,primecell";
+		reg = <0x0 0xfea30000 0x0 0x4000>;
+		interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH 0>;
+		arm,pl330-periph-burst;
+		clocks = <&cru ACLK_DMAC1>;
+		clock-names = "apb_pclk";
+		#dma-cells = <1>;
+	};
+
+	i2c1: i2c@fea90000 {
+		compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xfea90000 0x0 0x1000>;
+		clocks = <&cru CLK_I2C1>, <&cru PCLK_I2C1>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH 0>;
+		pinctrl-0 = <&i2c1m0_xfer>;
+		pinctrl-names = "default";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c2: i2c@feaa0000 {
+		compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xfeaa0000 0x0 0x1000>;
+		clocks = <&cru CLK_I2C2>, <&cru PCLK_I2C2>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH 0>;
+		pinctrl-0 = <&i2c2m0_xfer>;
+		pinctrl-names = "default";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c3: i2c@feab0000 {
+		compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xfeab0000 0x0 0x1000>;
+		clocks = <&cru CLK_I2C3>, <&cru PCLK_I2C3>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH 0>;
+		pinctrl-0 = <&i2c3m0_xfer>;
+		pinctrl-names = "default";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c4: i2c@feac0000 {
+		compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xfeac0000 0x0 0x1000>;
+		clocks = <&cru CLK_I2C4>, <&cru PCLK_I2C4>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH 0>;
+		pinctrl-0 = <&i2c4m0_xfer>;
+		pinctrl-names = "default";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c5: i2c@fead0000 {
+		compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xfead0000 0x0 0x1000>;
+		clocks = <&cru CLK_I2C5>, <&cru PCLK_I2C5>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH 0>;
+		pinctrl-0 = <&i2c5m0_xfer>;
+		pinctrl-names = "default";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi0: spi@feb00000 {
+		compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+		reg = <0x0 0xfeb00000 0x0 0x1000>;
+		interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru CLK_SPI0>, <&cru PCLK_SPI0>;
+		clock-names = "spiclk", "apb_pclk";
+		dmas = <&dmac0 14>, <&dmac0 15>;
+		dma-names = "tx", "rx";
+		num-cs = <2>;
+		pinctrl-0 = <&spi0m0_cs0 &spi0m0_cs1 &spi0m0_pins>;
+		pinctrl-names = "default";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi1: spi@feb10000 {
+		compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+		reg = <0x0 0xfeb10000 0x0 0x1000>;
+		interrupts = <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru CLK_SPI1>, <&cru PCLK_SPI1>;
+		clock-names = "spiclk", "apb_pclk";
+		dmas = <&dmac0 16>, <&dmac0 17>;
+		dma-names = "tx", "rx";
+		num-cs = <2>;
+		pinctrl-0 = <&spi1m1_cs0 &spi1m1_cs1 &spi1m1_pins>;
+		pinctrl-names = "default";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi2: spi@feb20000 {
+		compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+		reg = <0x0 0xfeb20000 0x0 0x1000>;
+		interrupts = <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru CLK_SPI2>, <&cru PCLK_SPI2>;
+		clock-names = "spiclk", "apb_pclk";
+		dmas = <&dmac1 15>, <&dmac1 16>;
+		dma-names = "tx", "rx";
+		num-cs = <2>;
+		pinctrl-0 = <&spi2m2_cs0 &spi2m2_cs1 &spi2m2_pins>;
+		pinctrl-names = "default";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi3: spi@feb30000 {
+		compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+		reg = <0x0 0xfeb30000 0x0 0x1000>;
+		interrupts = <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru CLK_SPI3>, <&cru PCLK_SPI3>;
+		clock-names = "spiclk", "apb_pclk";
+		dmas = <&dmac1 17>, <&dmac1 18>;
+		dma-names = "tx", "rx";
+		num-cs = <2>;
+		pinctrl-0 = <&spi3m1_cs0 &spi3m1_cs1 &spi3m1_pins>;
+		pinctrl-names = "default";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	uart1: serial@feb40000 {
+		compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xfeb40000 0x0 0x100>;
+		interrupts = <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac0 8>, <&dmac0 9>;
+		dma-names = "tx", "rx";
+		pinctrl-0 = <&uart1m1_xfer>;
+		pinctrl-names = "default";
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		status = "disabled";
+	};
+
+	uart2: serial@feb50000 {
+		compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xfeb50000 0x0 0x100>;
+		interrupts = <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac0 10>, <&dmac0 11>;
+		dma-names = "tx", "rx";
+		pinctrl-0 = <&uart2m1_xfer>;
+		pinctrl-names = "default";
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		status = "disabled";
+	};
+
+	uart3: serial@feb60000 {
+		compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xfeb60000 0x0 0x100>;
+		interrupts = <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac0 12>, <&dmac0 13>;
+		dma-names = "tx", "rx";
+		pinctrl-0 = <&uart3m1_xfer>;
+		pinctrl-names = "default";
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		status = "disabled";
+	};
+
+	uart4: serial@feb70000 {
+		compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xfeb70000 0x0 0x100>;
+		interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac1 9>, <&dmac1 10>;
+		dma-names = "tx", "rx";
+		pinctrl-0 = <&uart4m1_xfer>;
+		pinctrl-names = "default";
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		status = "disabled";
+	};
+
+	uart5: serial@feb80000 {
+		compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xfeb80000 0x0 0x100>;
+		interrupts = <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac1 11>, <&dmac1 12>;
+		dma-names = "tx", "rx";
+		pinctrl-0 = <&uart5m1_xfer>;
+		pinctrl-names = "default";
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		status = "disabled";
+	};
+
+	uart6: serial@feb90000 {
+		compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xfeb90000 0x0 0x100>;
+		interrupts = <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru SCLK_UART6>, <&cru PCLK_UART6>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac1 13>, <&dmac1 14>;
+		dma-names = "tx", "rx";
+		pinctrl-0 = <&uart6m1_xfer>;
+		pinctrl-names = "default";
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		status = "disabled";
+	};
+
+	uart7: serial@feba0000 {
+		compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xfeba0000 0x0 0x100>;
+		interrupts = <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru SCLK_UART7>, <&cru PCLK_UART7>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac2 7>, <&dmac2 8>;
+		dma-names = "tx", "rx";
+		pinctrl-0 = <&uart7m1_xfer>;
+		pinctrl-names = "default";
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		status = "disabled";
+	};
+
+	uart8: serial@febb0000 {
+		compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xfebb0000 0x0 0x100>;
+		interrupts = <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru SCLK_UART8>, <&cru PCLK_UART8>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac2 9>, <&dmac2 10>;
+		dma-names = "tx", "rx";
+		pinctrl-0 = <&uart8m1_xfer>;
+		pinctrl-names = "default";
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		status = "disabled";
+	};
+
+	uart9: serial@febc0000 {
+		compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xfebc0000 0x0 0x100>;
+		interrupts = <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru SCLK_UART9>, <&cru PCLK_UART9>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac2 11>, <&dmac2 12>;
+		dma-names = "tx", "rx";
+		pinctrl-0 = <&uart9m1_xfer>;
+		pinctrl-names = "default";
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		status = "disabled";
+	};
+
+	pwm4: pwm@febd0000 {
+		compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xfebd0000 0x0 0x10>;
+		clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
+		clock-names = "pwm", "pclk";
+		pinctrl-0 = <&pwm4m0_pins>;
+		pinctrl-names = "default";
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm5: pwm@febd0010 {
+		compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xfebd0010 0x0 0x10>;
+		clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
+		clock-names = "pwm", "pclk";
+		pinctrl-0 = <&pwm5m0_pins>;
+		pinctrl-names = "default";
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm6: pwm@febd0020 {
+		compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xfebd0020 0x0 0x10>;
+		clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
+		clock-names = "pwm", "pclk";
+		pinctrl-0 = <&pwm6m0_pins>;
+		pinctrl-names = "default";
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm7: pwm@febd0030 {
+		compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xfebd0030 0x0 0x10>;
+		clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
+		clock-names = "pwm", "pclk";
+		pinctrl-0 = <&pwm7m0_pins>;
+		pinctrl-names = "default";
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm8: pwm@febe0000 {
+		compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xfebe0000 0x0 0x10>;
+		clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+		clock-names = "pwm", "pclk";
+		pinctrl-0 = <&pwm8m0_pins>;
+		pinctrl-names = "default";
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm9: pwm@febe0010 {
+		compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xfebe0010 0x0 0x10>;
+		clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+		clock-names = "pwm", "pclk";
+		pinctrl-0 = <&pwm9m0_pins>;
+		pinctrl-names = "default";
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm10: pwm@febe0020 {
+		compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xfebe0020 0x0 0x10>;
+		clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+		clock-names = "pwm", "pclk";
+		pinctrl-0 = <&pwm10m0_pins>;
+		pinctrl-names = "default";
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm11: pwm@febe0030 {
+		compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xfebe0030 0x0 0x10>;
+		clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+		clock-names = "pwm", "pclk";
+		pinctrl-0 = <&pwm11m0_pins>;
+		pinctrl-names = "default";
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm12: pwm@febf0000 {
+		compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xfebf0000 0x0 0x10>;
+		clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
+		clock-names = "pwm", "pclk";
+		pinctrl-0 = <&pwm12m0_pins>;
+		pinctrl-names = "default";
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm13: pwm@febf0010 {
+		compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xfebf0010 0x0 0x10>;
+		clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
+		clock-names = "pwm", "pclk";
+		pinctrl-0 = <&pwm13m0_pins>;
+		pinctrl-names = "default";
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm14: pwm@febf0020 {
+		compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xfebf0020 0x0 0x10>;
+		clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
+		clock-names = "pwm", "pclk";
+		pinctrl-0 = <&pwm14m0_pins>;
+		pinctrl-names = "default";
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm15: pwm@febf0030 {
+		compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xfebf0030 0x0 0x10>;
+		clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
+		clock-names = "pwm", "pclk";
+		pinctrl-0 = <&pwm15m0_pins>;
+		pinctrl-names = "default";
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	i2c6: i2c@fec80000 {
+		compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xfec80000 0x0 0x1000>;
+		clocks = <&cru CLK_I2C6>, <&cru PCLK_I2C6>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH 0>;
+		pinctrl-0 = <&i2c6m0_xfer>;
+		pinctrl-names = "default";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c7: i2c@fec90000 {
+		compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xfec90000 0x0 0x1000>;
+		clocks = <&cru CLK_I2C7>, <&cru PCLK_I2C7>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH 0>;
+		pinctrl-0 = <&i2c7m0_xfer>;
+		pinctrl-names = "default";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c8: i2c@feca0000 {
+		compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xfeca0000 0x0 0x1000>;
+		clocks = <&cru CLK_I2C8>, <&cru PCLK_I2C8>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH 0>;
+		pinctrl-0 = <&i2c8m0_xfer>;
+		pinctrl-names = "default";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi4: spi@fecb0000 {
+		compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+		reg = <0x0 0xfecb0000 0x0 0x1000>;
+		interrupts = <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru CLK_SPI4>, <&cru PCLK_SPI4>;
+		clock-names = "spiclk", "apb_pclk";
+		dmas = <&dmac2 13>, <&dmac2 14>;
+		dma-names = "tx", "rx";
+		num-cs = <2>;
+		pinctrl-0 = <&spi4m0_cs0 &spi4m0_cs1 &spi4m0_pins>;
+		pinctrl-names = "default";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	dmac2: dma-controller@fed10000 {
+		compatible = "arm,pl330", "arm,primecell";
+		reg = <0x0 0xfed10000 0x0 0x4000>;
+		interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH 0>;
+		arm,pl330-periph-burst;
+		clocks = <&cru ACLK_DMAC2>;
+		clock-names = "apb_pclk";
+		#dma-cells = <1>;
+	};
+
+	system_sram2: sram@ff001000 {
+		compatible = "mmio-sram";
+		reg = <0x0 0xff001000 0x0 0xef000>;
+		ranges = <0x0 0x0 0xff001000 0xef000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+
+	pinctrl: pinctrl {
+		compatible = "rockchip,rk3588-pinctrl";
+		ranges;
+		rockchip,grf = <&ioc>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		gpio0: gpio@fd8a0000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xfd8a0000 0x0 0x100>;
+			interrupts = <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&cru PCLK_GPIO0>, <&cru DBCLK_GPIO0>;
+			gpio-controller;
+			gpio-ranges = <&pinctrl 0 0 32>;
+			interrupt-controller;
+			#gpio-cells = <2>;
+			#interrupt-cells = <2>;
+		};
+
+		gpio1: gpio@fec20000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xfec20000 0x0 0x100>;
+			interrupts = <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>;
+			gpio-controller;
+			gpio-ranges = <&pinctrl 0 32 32>;
+			interrupt-controller;
+			#gpio-cells = <2>;
+			#interrupt-cells = <2>;
+		};
+
+		gpio2: gpio@fec30000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xfec30000 0x0 0x100>;
+			interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>;
+			gpio-controller;
+			gpio-ranges = <&pinctrl 0 64 32>;
+			interrupt-controller;
+			#gpio-cells = <2>;
+			#interrupt-cells = <2>;
+		};
+
+		gpio3: gpio@fec40000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xfec40000 0x0 0x100>;
+			interrupts = <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&cru PCLK_GPIO3>, <&cru DBCLK_GPIO3>;
+			gpio-controller;
+			gpio-ranges = <&pinctrl 0 96 32>;
+			interrupt-controller;
+			#gpio-cells = <2>;
+			#interrupt-cells = <2>;
+		};
+
+		gpio4: gpio@fec50000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xfec50000 0x0 0x100>;
+			interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&cru PCLK_GPIO4>, <&cru DBCLK_GPIO4>;
+			gpio-controller;
+			gpio-ranges = <&pinctrl 0 128 32>;
+			interrupt-controller;
+			#gpio-cells = <2>;
+			#interrupt-cells = <2>;
+		};
+	};
+};
+
+#include "rk3588s-pinctrl.dtsi"
diff --git a/arch/arm/dts/rockchip-u-boot.dtsi b/arch/arm/dts/rockchip-u-boot.dtsi
index 6c662a7..2878b80 100644
--- a/arch/arm/dts/rockchip-u-boot.dtsi
+++ b/arch/arm/dts/rockchip-u-boot.dtsi
@@ -20,9 +20,12 @@
 		mkimage {
 			filename = "idbloader.img";
 			args = "-n", CONFIG_SYS_SOC, "-T", "rksd";
-#ifdef CONFIG_TPL
 			multiple-data-files;
 
+#ifdef CONFIG_ROCKCHIP_EXTERNAL_TPL
+			rockchip-tpl {
+			};
+#elif defined(CONFIG_TPL)
 			u-boot-tpl {
 			};
 #endif
@@ -134,9 +137,12 @@
 		mkimage {
 			filename = "idbloader-spi.img";
 			args = "-n", CONFIG_SYS_SOC, "-T", "rkspi";
-#ifdef CONFIG_TPL
 			multiple-data-files;
 
+#ifdef CONFIG_ROCKCHIP_EXTERNAL_TPL
+			rockchip-tpl {
+			};
+#elif defined(CONFIG_TPL)
 			u-boot-tpl {
 			};
 #endif
diff --git a/arch/arm/dts/sama7g5.dtsi b/arch/arm/dts/sama7g5.dtsi
index 6388a60..746a5ba 100644
--- a/arch/arm/dts/sama7g5.dtsi
+++ b/arch/arm/dts/sama7g5.dtsi
@@ -151,7 +151,7 @@
 				  0x1 0x0 0x48000000 0x8000000
 				  0x2 0x0 0x50000000 0x8000000
 				  0x3 0x0 0x58000000 0x8000000>;
-			clocks = <&pmc PMC_TYPE_CORE 13>; /* PMC_MCK1 */
+			clocks = <&pmc PMC_TYPE_CORE 23>; /* PMC_MCK1 */
 			status = "disabled";
 
 			nand_controller: nand-controller {
diff --git a/arch/arm/include/asm/arch-rk3588/boot0.h b/arch/arm/include/asm/arch-rk3588/boot0.h
new file mode 100644
index 0000000..dea2b20
--- /dev/null
+++ b/arch/arm/include/asm/arch-rk3588/boot0.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __ASM_ARCH_BOOT0_H__
+#define __ASM_ARCH_BOOT0_H__
+
+#include <asm/arch-rockchip/boot0.h>
+
+#endif
diff --git a/arch/arm/include/asm/arch-rk3588/gpio.h b/arch/arm/include/asm/arch-rk3588/gpio.h
new file mode 100644
index 0000000..b48c0a5
--- /dev/null
+++ b/arch/arm/include/asm/arch-rk3588/gpio.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __ASM_ARCH_GPIO_H__
+#define __ASM_ARCH_GPIO_H__
+
+#include <asm/arch-rockchip/gpio.h>
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/clock.h b/arch/arm/include/asm/arch-rockchip/clock.h
index 566bdcc..90e66c7 100644
--- a/arch/arm/include/asm/arch-rockchip/clock.h
+++ b/arch/arm/include/asm/arch-rockchip/clock.h
@@ -22,6 +22,14 @@
 	ROCKCHIP_SYSCON_PMUSGRF,
 	ROCKCHIP_SYSCON_CIC,
 	ROCKCHIP_SYSCON_MSCH,
+	ROCKCHIP_SYSCON_USBGRF,
+	ROCKCHIP_SYSCON_PCIE30_PHY_GRF,
+	ROCKCHIP_SYSCON_PHP_GRF,
+	ROCKCHIP_SYSCON_PIPE_PHY0_GRF,
+	ROCKCHIP_SYSCON_PIPE_PHY1_GRF,
+	ROCKCHIP_SYSCON_PIPE_PHY2_GRF,
+	ROCKCHIP_SYSCON_VOP_GRF,
+	ROCKCHIP_SYSCON_VO_GRF,
 };
 
 /* Standard Rockchip clock numbers */
@@ -61,6 +69,15 @@
 	.frac = _frac,						\
 }
 
+#define RK3588_PLL_RATE(_rate, _p, _m, _s, _k)			\
+{								\
+	.rate	= _rate##U,					\
+	.p = _p,						\
+	.m = _m,						\
+	.s = _s,						\
+	.k = _k,						\
+}
+
 struct rockchip_pll_rate_table {
 	unsigned long rate;
 	unsigned int nr;
@@ -74,6 +91,11 @@
 	unsigned int postdiv2;
 	unsigned int dsmpd;
 	unsigned int frac;
+	/* for RK3588 */
+	unsigned int m;
+	unsigned int p;
+	unsigned int s;
+	unsigned int k;
 };
 
 enum rockchip_pll_type {
@@ -82,6 +104,7 @@
 	pll_rk3328,
 	pll_rk3366,
 	pll_rk3399,
+	pll_rk3588,
 };
 
 struct rockchip_pll_clock {
@@ -171,5 +194,6 @@
  * Return: 0 success, or error value
  */
 int rockchip_reset_bind(struct udevice *pdev, u32 reg_offset, u32 reg_number);
+int rockchip_get_scmi_clk(struct udevice **devp);
 
 #endif
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3588.h b/arch/arm/include/asm/arch-rockchip/cru_rk3588.h
new file mode 100644
index 0000000..3ea59e9
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3588.h
@@ -0,0 +1,451 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 Rockchip Electronics Co. Ltd.
+ * Author: Elaine Zhang <zhangqing@rock-chips.com>
+ */
+
+#ifndef _ASM_ARCH_CRU_RK3588_H
+#define _ASM_ARCH_CRU_RK3588_H
+
+#define MHz		1000000
+#define KHz		1000
+#define OSC_HZ		(24 * MHz)
+
+#define CPU_PVTPLL_HZ	(1008 * MHz)
+#define LPLL_HZ		(816 * MHz)
+#define GPLL_HZ		(1188 * MHz)
+#define CPLL_HZ		(1500 * MHz)
+#define NPLL_HZ         (850 * MHz)
+#define PPLL_HZ		(1100 * MHz)
+
+/* RK3588 pll id */
+enum rk3588_pll_id {
+	B0PLL,
+	B1PLL,
+	LPLL,
+	CPLL,
+	GPLL,
+	NPLL,
+	V0PLL,
+	AUPLL,
+	PPLL,
+	PLL_COUNT,
+};
+
+struct rk3588_clk_info {
+	unsigned long id;
+	char *name;
+	bool is_cru;
+};
+
+struct rk3588_clk_priv {
+	struct rk3588_cru *cru;
+	struct rk3588_grf *grf;
+	ulong ppll_hz;
+	ulong gpll_hz;
+	ulong cpll_hz;
+	ulong npll_hz;
+	ulong v0pll_hz;
+	ulong aupll_hz;
+	ulong armclk_hz;
+	ulong armclk_enter_hz;
+	ulong armclk_init_hz;
+	bool sync_kernel;
+	bool set_armclk_rate;
+};
+
+struct rk3588_pll {
+	unsigned int con0;
+	unsigned int con1;
+	unsigned int con2;
+	unsigned int con3;
+	unsigned int con4;
+	unsigned int reserved0[3];
+};
+
+struct rk3588_cru {
+	struct rk3588_pll pll[18];
+	unsigned int reserved0[16];/* Address Offset: 0x0240 */
+	unsigned int mode_con00;/* Address Offset: 0x0280 */
+	unsigned int reserved1[31];/* Address Offset: 0x0284 */
+	unsigned int clksel_con[178]; /* Address Offset: 0x0300 */
+	unsigned int reserved2[142];/* Address Offset: 0x05c8 */
+	unsigned int clkgate_con[78];/* Address Offset: 0x0800 */
+	unsigned int reserved3[50];/* Address Offset: 0x0938 */
+	unsigned int softrst_con[78];/* Address Offset: 0x0400 */
+	unsigned int reserved4[50];/* Address Offset: 0x0b38 */
+	unsigned int glb_cnt_th;/* Address Offset: 0x0c00 */
+	unsigned int glb_rst_st;/* Address Offset: 0x0c04 */
+	unsigned int glb_srst_fst;/* Address Offset: 0x0c08 */
+	unsigned int glb_srsr_snd; /* Address Offset: 0x0c0c */
+	unsigned int glb_rst_con;/* Address Offset: 0x0c10 */
+	unsigned int reserved5[4];/* Address Offset: 0x0c14 */
+	unsigned int sdio_con[2];/* Address Offset: 0x0c24 */
+	unsigned int reserved7;/* Address Offset: 0x0c2c */
+	unsigned int sdmmc_con[2];/* Address Offset: 0x0c30 */
+	unsigned int reserved8[48562];/* Address Offset: 0x0c38 */
+	unsigned int pmuclksel_con[21]; /* Address Offset: 0x0100 */
+	unsigned int reserved9[299];/* Address Offset: 0x0c38 */
+	unsigned int pmuclkgate_con[9]; /* Address Offset: 0x0100 */
+};
+
+check_member(rk3588_cru, mode_con00, 0x280);
+check_member(rk3588_cru, pmuclksel_con[1], 0x30304);
+
+struct pll_rate_table {
+	unsigned long rate;
+	unsigned int m;
+	unsigned int p;
+	unsigned int s;
+	unsigned int k;
+};
+
+#define RK3588_PLL_CON(x)		((x) * 0x4)
+#define RK3588_MODE_CON			0x280
+
+#define RK3588_PHP_CRU_BASE		0x8000
+#define RK3588_PMU_CRU_BASE		0x30000
+#define RK3588_BIGCORE0_CRU_BASE	0x50000
+#define RK3588_BIGCORE1_CRU_BASE	0x52000
+#define RK3588_DSU_CRU_BASE		0x58000
+
+#define RK3588_PLL_CON(x)		((x) * 0x4)
+#define RK3588_MODE_CON0		0x280
+#define RK3588_CLKSEL_CON(x)		((x) * 0x4 + 0x300)
+#define RK3588_CLKGATE_CON(x)		((x) * 0x4 + 0x800)
+#define RK3588_SOFTRST_CON(x)		((x) * 0x4 + 0xa00)
+#define RK3588_GLB_CNT_TH		0xc00
+#define RK3588_GLB_SRST_FST		0xc08
+#define RK3588_GLB_SRST_SND		0xc0c
+#define RK3588_GLB_RST_CON		0xc10
+#define RK3588_GLB_RST_ST		0xc04
+#define RK3588_SDIO_CON0		0xC24
+#define RK3588_SDIO_CON1		0xC28
+#define RK3588_SDMMC_CON0		0xC30
+#define RK3588_SDMMC_CON1		0xC34
+
+#define RK3588_PHP_CLKGATE_CON(x)	((x) * 0x4 + RK3588_PHP_CRU_BASE + 0x800)
+#define RK3588_PHP_SOFTRST_CON(x)	((x) * 0x4 + RK3588_PHP_CRU_BASE + 0xa00)
+
+#define RK3588_PMU_PLL_CON(x)		((x) * 0x4 + RK3588_PHP_CRU_BASE)
+#define RK3588_PMU_CLKSEL_CON(x)	((x) * 0x4 + RK3588_PMU_CRU_BASE + 0x300)
+#define RK3588_PMU_CLKGATE_CON(x)	((x) * 0x4 + RK3588_PMU_CRU_BASE + 0x800)
+#define RK3588_PMU_SOFTRST_CON(x)	((x) * 0x4 + RK3588_PMU_CRU_BASE + 0xa00)
+
+#define RK3588_B0_PLL_CON(x)		((x) * 0x4 + RK3588_BIGCORE0_CRU_BASE)
+#define RK3588_B0_PLL_MODE_CON		(RK3588_BIGCORE0_CRU_BASE + 0x280)
+#define RK3588_BIGCORE0_CLKSEL_CON(x)	((x) * 0x4 + RK3588_BIGCORE0_CRU_BASE + 0x300)
+#define RK3588_BIGCORE0_CLKGATE_CON(x)	((x) * 0x4 + RK3588_BIGCORE0_CRU_BASE + 0x800)
+#define RK3588_BIGCORE0_SOFTRST_CON(x)	((x) * 0x4 + RK3588_BIGCORE0_CRU_BASE + 0xa00)
+#define RK3588_B1_PLL_CON(x)		((x) * 0x4 + RK3588_BIGCORE1_CRU_BASE)
+#define RK3588_B1_PLL_MODE_CON		(RK3588_BIGCORE1_CRU_BASE + 0x280)
+#define RK3588_BIGCORE1_CLKSEL_CON(x)	((x) * 0x4 + RK3588_BIGCORE1_CRU_BASE + 0x300)
+#define RK3588_BIGCORE1_CLKGATE_CON(x)	((x) * 0x4 + RK3588_BIGCORE1_CRU_BASE + 0x800)
+#define RK3588_BIGCORE1_SOFTRST_CON(x)	((x) * 0x4 + RK3588_BIGCORE1_CRU_BASE + 0xa00)
+#define RK3588_LPLL_CON(x)		((x) * 0x4 + RK3588_DSU_CRU_BASE)
+#define RK3588_LPLL_MODE_CON		(RK3588_DSU_CRU_BASE + 0x280)
+#define RK3588_DSU_CLKSEL_CON(x)	((x) * 0x4 + RK3588_DSU_CRU_BASE + 0x300)
+#define RK3588_DSU_CLKGATE_CON(x)	((x) * 0x4 + RK3588_DSU_CRU_BASE + 0x800)
+#define RK3588_DSU_SOFTRST_CON(x)	((x) * 0x4 + RK3588_DSU_CRU_BASE + 0xa00)
+
+enum {
+	/* CRU_CLK_SEL8_CON */
+	ACLK_LOW_TOP_ROOT_SRC_SEL_SHIFT		= 14,
+	ACLK_LOW_TOP_ROOT_SRC_SEL_MASK		= 1 << ACLK_LOW_TOP_ROOT_SRC_SEL_SHIFT,
+	ACLK_LOW_TOP_ROOT_SRC_SEL_GPLL		= 0,
+	ACLK_LOW_TOP_ROOT_SRC_SEL_CPLL,
+	ACLK_LOW_TOP_ROOT_DIV_SHIFT		= 9,
+	ACLK_LOW_TOP_ROOT_DIV_MASK		= 0x1f << ACLK_LOW_TOP_ROOT_DIV_SHIFT,
+	PCLK_TOP_ROOT_SEL_SHIFT			= 7,
+	PCLK_TOP_ROOT_SEL_MASK			= 3 << PCLK_TOP_ROOT_SEL_SHIFT,
+	PCLK_TOP_ROOT_SEL_100M			= 0,
+	PCLK_TOP_ROOT_SEL_50M,
+	PCLK_TOP_ROOT_SEL_24M,
+	ACLK_TOP_ROOT_SRC_SEL_SHIFT		= 5,
+	ACLK_TOP_ROOT_SRC_SEL_MASK		= 3 << ACLK_TOP_ROOT_SRC_SEL_SHIFT,
+	ACLK_TOP_ROOT_SRC_SEL_GPLL		= 0,
+	ACLK_TOP_ROOT_SRC_SEL_CPLL,
+	ACLK_TOP_ROOT_SRC_SEL_AUPLL,
+	ACLK_TOP_ROOT_DIV_SHIFT			= 0,
+	ACLK_TOP_ROOT_DIV_MASK			= 0x1f << ACLK_TOP_ROOT_DIV_SHIFT,
+
+	/* CRU_CLK_SEL9_CON */
+	ACLK_TOP_S400_SEL_SHIFT			= 8,
+	ACLK_TOP_S400_SEL_MASK			= 3 << ACLK_TOP_S400_SEL_SHIFT,
+	ACLK_TOP_S400_SEL_400M			= 0,
+	ACLK_TOP_S400_SEL_200M,
+	ACLK_TOP_S200_SEL_SHIFT			= 6,
+	ACLK_TOP_S200_SEL_MASK			= 3 << ACLK_TOP_S200_SEL_SHIFT,
+	ACLK_TOP_S200_SEL_200M			= 0,
+	ACLK_TOP_S200_SEL_100M,
+
+	/* CRU_CLK_SEL38_CON */
+	CLK_I2C8_SEL_SHIFT			= 13,
+	CLK_I2C8_SEL_MASK			= 1 << CLK_I2C8_SEL_SHIFT,
+	CLK_I2C7_SEL_SHIFT			= 12,
+	CLK_I2C7_SEL_MASK			= 1 << CLK_I2C7_SEL_SHIFT,
+	CLK_I2C6_SEL_SHIFT			= 11,
+	CLK_I2C6_SEL_MASK			= 1 << CLK_I2C6_SEL_SHIFT,
+	CLK_I2C5_SEL_SHIFT			= 10,
+	CLK_I2C5_SEL_MASK			= 1 << CLK_I2C5_SEL_SHIFT,
+	CLK_I2C4_SEL_SHIFT			= 9,
+	CLK_I2C4_SEL_MASK			= 1 << CLK_I2C4_SEL_SHIFT,
+	CLK_I2C3_SEL_SHIFT			= 8,
+	CLK_I2C3_SEL_MASK			= 1 << CLK_I2C3_SEL_SHIFT,
+	CLK_I2C2_SEL_SHIFT			= 7,
+	CLK_I2C2_SEL_MASK			= 1 << CLK_I2C2_SEL_SHIFT,
+	CLK_I2C1_SEL_SHIFT			= 6,
+	CLK_I2C1_SEL_MASK			= 1 << CLK_I2C1_SEL_SHIFT,
+	ACLK_BUS_ROOT_SEL_SHIFT			= 5,
+	ACLK_BUS_ROOT_SEL_MASK			= 3 << ACLK_BUS_ROOT_SEL_SHIFT,
+	ACLK_BUS_ROOT_SEL_GPLL			= 0,
+	ACLK_BUS_ROOT_SEL_CPLL,
+	ACLK_BUS_ROOT_DIV_SHIFT			= 0,
+	ACLK_BUS_ROOT_DIV_MASK			= 0x1f << ACLK_BUS_ROOT_DIV_SHIFT,
+
+	/* CRU_CLK_SEL40_CON */
+	CLK_SARADC_SEL_SHIFT			= 14,
+	CLK_SARADC_SEL_MASK			= 0x1 << CLK_SARADC_SEL_SHIFT,
+	CLK_SARADC_SEL_GPLL			= 0,
+	CLK_SARADC_SEL_24M,
+	CLK_SARADC_DIV_SHIFT			= 6,
+	CLK_SARADC_DIV_MASK			= 0xff << CLK_SARADC_DIV_SHIFT,
+
+	/* CRU_CLK_SEL41_CON */
+	CLK_UART_SRC_SEL_SHIFT			= 14,
+	CLK_UART_SRC_SEL_MASK			= 0x1 << CLK_UART_SRC_SEL_SHIFT,
+	CLK_UART_SRC_SEL_GPLL			= 0,
+	CLK_UART_SRC_SEL_CPLL,
+	CLK_UART_SRC_DIV_SHIFT			= 9,
+	CLK_UART_SRC_DIV_MASK			= 0x1f << CLK_UART_SRC_DIV_SHIFT,
+	CLK_TSADC_SEL_SHIFT			= 8,
+	CLK_TSADC_SEL_MASK			= 0x1 << CLK_TSADC_SEL_SHIFT,
+	CLK_TSADC_SEL_GPLL			= 0,
+	CLK_TSADC_SEL_24M,
+	CLK_TSADC_DIV_SHIFT			= 0,
+	CLK_TSADC_DIV_MASK			= 0xff << CLK_TSADC_DIV_SHIFT,
+
+	/* CRU_CLK_SEL42_CON */
+	CLK_UART_FRAC_NUMERATOR_SHIFT		= 16,
+	CLK_UART_FRAC_NUMERATOR_MASK		= 0xffff << 16,
+	CLK_UART_FRAC_DENOMINATOR_SHIFT		= 0,
+	CLK_UART_FRAC_DENOMINATOR_MASK		= 0xffff,
+
+	/* CRU_CLK_SEL43_CON */
+	CLK_UART_SEL_SHIFT			= 0,
+	CLK_UART_SEL_MASK			= 0x3 << CLK_UART_SEL_SHIFT,
+	CLK_UART_SEL_SRC			= 0,
+	CLK_UART_SEL_FRAC,
+	CLK_UART_SEL_XIN24M,
+
+	/* CRU_CLK_SEL59_CON */
+	CLK_PWM2_SEL_SHIFT			= 14,
+	CLK_PWM2_SEL_MASK			= 3 << CLK_PWM2_SEL_SHIFT,
+	CLK_PWM1_SEL_SHIFT			= 12,
+	CLK_PWM1_SEL_MASK			= 3 << CLK_PWM1_SEL_SHIFT,
+	CLK_SPI4_SEL_SHIFT			= 10,
+	CLK_SPI4_SEL_MASK			= 3 << CLK_SPI4_SEL_SHIFT,
+	CLK_SPI3_SEL_SHIFT			= 8,
+	CLK_SPI3_SEL_MASK			= 3 << CLK_SPI3_SEL_SHIFT,
+	CLK_SPI2_SEL_SHIFT			= 6,
+	CLK_SPI2_SEL_MASK			= 3 << CLK_SPI2_SEL_SHIFT,
+	CLK_SPI1_SEL_SHIFT			= 4,
+	CLK_SPI1_SEL_MASK			= 3 << CLK_SPI1_SEL_SHIFT,
+	CLK_SPI0_SEL_SHIFT			= 2,
+	CLK_SPI0_SEL_MASK			= 3 << CLK_SPI0_SEL_SHIFT,
+	CLK_SPI_SEL_200M			= 0,
+	CLK_SPI_SEL_150M,
+	CLK_SPI_SEL_24M,
+
+	/* CRU_CLK_SEL60_CON */
+	CLK_PWM3_SEL_SHIFT			= 0,
+	CLK_PWM3_SEL_MASK			= 3 << CLK_PWM3_SEL_SHIFT,
+	CLK_PWM_SEL_100M			= 0,
+	CLK_PWM_SEL_50M,
+	CLK_PWM_SEL_24M,
+
+	/* CRU_CLK_SEL62_CON */
+	DCLK_DECOM_SEL_SHIFT			= 5,
+	DCLK_DECOM_SEL_MASK			= 1 << DCLK_DECOM_SEL_SHIFT,
+	DCLK_DECOM_SEL_GPLL			= 0,
+	DCLK_DECOM_SEL_SPLL,
+	DCLK_DECOM_DIV_SHIFT			= 0,
+	DCLK_DECOM_DIV_MASK			= 0x1F << DCLK_DECOM_DIV_SHIFT,
+
+	/* CRU_CLK_SEL77_CON */
+	CCLK_EMMC_SEL_SHIFT			= 14,
+	CCLK_EMMC_SEL_MASK			= 3 << CCLK_EMMC_SEL_SHIFT,
+	CCLK_EMMC_SEL_GPLL			= 0,
+	CCLK_EMMC_SEL_CPLL,
+	CCLK_EMMC_SEL_24M,
+	CCLK_EMMC_DIV_SHIFT			= 8,
+	CCLK_EMMC_DIV_MASK			= 0x3f << CCLK_EMMC_DIV_SHIFT,
+
+	/* CRU_CLK_SEL78_CON */
+	SCLK_SFC_SEL_SHIFT			= 12,
+	SCLK_SFC_SEL_MASK			= 3 << SCLK_SFC_SEL_SHIFT,
+	SCLK_SFC_SEL_GPLL			= 0,
+	SCLK_SFC_SEL_CPLL,
+	SCLK_SFC_SEL_24M,
+	SCLK_SFC_DIV_SHIFT			= 6,
+	SCLK_SFC_DIV_MASK			= 0x3f << SCLK_SFC_DIV_SHIFT,
+	BCLK_EMMC_SEL_SHIFT			= 5,
+	BCLK_EMMC_SEL_MASK			= 1 << BCLK_EMMC_SEL_SHIFT,
+	BCLK_EMMC_SEL_GPLL			= 0,
+	BCLK_EMMC_SEL_CPLL,
+	BCLK_EMMC_DIV_SHIFT			= 0,
+	BCLK_EMMC_DIV_MASK			= 0x1f << BCLK_EMMC_DIV_SHIFT,
+
+	/* CRU_CLK_SEL81_CON */
+	CLK_GMAC1_PTP_SEL_SHIFT			= 13,
+	CLK_GMAC1_PTP_SEL_MASK			= 1 << CLK_GMAC1_PTP_SEL_SHIFT,
+	CLK_GMAC1_PTP_SEL_CPLL			= 0,
+	CLK_GMAC1_PTP_DIV_SHIFT			= 7,
+	CLK_GMAC1_PTP_DIV_MASK			= 0x3f << CLK_GMAC1_PTP_DIV_SHIFT,
+	CLK_GMAC0_PTP_SEL_SHIFT			= 6,
+	CLK_GMAC0_PTP_SEL_MASK			= 1 << CLK_GMAC0_PTP_SEL_SHIFT,
+	CLK_GMAC0_PTP_SEL_CPLL			= 0,
+	CLK_GMAC0_PTP_DIV_SHIFT			= 0,
+	CLK_GMAC0_PTP_DIV_MASK			= 0x3f << CLK_GMAC0_PTP_DIV_SHIFT,
+
+	/* CRU_CLK_SEL83_CON */
+	CLK_GMAC_125M_SEL_SHIFT			= 15,
+	CLK_GMAC_125M_SEL_MASK			= 1 << CLK_GMAC_125M_SEL_SHIFT,
+	CLK_GMAC_125M_SEL_GPLL			= 0,
+	CLK_GMAC_125M_SEL_CPLL,
+	CLK_GMAC_125M_DIV_SHIFT			= 8,
+	CLK_GMAC_125M_DIV_MASK			= 0x7f << CLK_GMAC_125M_DIV_SHIFT,
+
+	/* CRU_CLK_SEL84_CON */
+	CLK_GMAC_50M_SEL_SHIFT			= 7,
+	CLK_GMAC_50M_SEL_MASK			= 1 << CLK_GMAC_50M_SEL_SHIFT,
+	CLK_GMAC_50M_SEL_GPLL			= 0,
+	CLK_GMAC_50M_SEL_CPLL,
+	CLK_GMAC_50M_DIV_SHIFT			= 0,
+	CLK_GMAC_50M_DIV_MASK			= 0x7f << CLK_GMAC_50M_DIV_SHIFT,
+
+	/* CRU_CLK_SEL110_CON */
+	HCLK_VOP_ROOT_SEL_SHIFT			= 10,
+	HCLK_VOP_ROOT_SEL_MASK			= 3 << HCLK_VOP_ROOT_SEL_SHIFT,
+	HCLK_VOP_ROOT_SEL_200M			= 0,
+	HCLK_VOP_ROOT_SEL_100M,
+	HCLK_VOP_ROOT_SEL_50M,
+	HCLK_VOP_ROOT_SEL_24M,
+	ACLK_VOP_LOW_ROOT_SEL_SHIFT		= 8,
+	ACLK_VOP_LOW_ROOT_SEL_MASK		= 3 << ACLK_VOP_LOW_ROOT_SEL_SHIFT,
+	ACLK_VOP_LOW_ROOT_SEL_400M		= 0,
+	ACLK_VOP_LOW_ROOT_SEL_200M,
+	ACLK_VOP_LOW_ROOT_SEL_100M,
+	ACLK_VOP_LOW_ROOT_SEL_24M,
+	ACLK_VOP_ROOT_SEL_SHIFT			= 5,
+	ACLK_VOP_ROOT_SEL_MASK			= 3 << ACLK_VOP_ROOT_SEL_SHIFT,
+	ACLK_VOP_ROOT_SEL_GPLL			= 0,
+	ACLK_VOP_ROOT_SEL_CPLL,
+	ACLK_VOP_ROOT_SEL_AUPLL,
+	ACLK_VOP_ROOT_SEL_NPLL,
+	ACLK_VOP_ROOT_SEL_SPLL,
+	ACLK_VOP_ROOT_DIV_SHIFT			= 0,
+	ACLK_VOP_ROOT_DIV_MASK			= 0x1f << ACLK_VOP_ROOT_DIV_SHIFT,
+
+	/* CRU_CLK_SEL111_CON */
+	DCLK1_VOP_SRC_SEL_SHIFT			= 14,
+	DCLK1_VOP_SRC_SEL_MASK			= 3 << DCLK1_VOP_SRC_SEL_SHIFT,
+	DCLK1_VOP_SRC_DIV_SHIFT			= 9,
+	DCLK1_VOP_SRC_DIV_MASK			= 0x1f << DCLK1_VOP_SRC_DIV_SHIFT,
+	DCLK0_VOP_SRC_SEL_SHIFT			= 7,
+	DCLK0_VOP_SRC_SEL_MASK			= 3 << DCLK0_VOP_SRC_SEL_SHIFT,
+	DCLK_VOP_SRC_SEL_GPLL			= 0,
+	DCLK_VOP_SRC_SEL_CPLL,
+	DCLK_VOP_SRC_SEL_V0PLL,
+	DCLK_VOP_SRC_SEL_AUPLL,
+	DCLK0_VOP_SRC_DIV_SHIFT			= 0,
+	DCLK0_VOP_SRC_DIV_MASK			= 0x7f << DCLK0_VOP_SRC_DIV_SHIFT,
+
+	/* CRU_CLK_SEL112_CON */
+	DCLK2_VOP_SEL_SHIFT			= 11,
+	DCLK2_VOP_SEL_MASK			= 3 << DCLK2_VOP_SEL_SHIFT,
+	DCLK1_VOP_SEL_SHIFT			= 9,
+	DCLK1_VOP_SEL_MASK			= 3 << DCLK1_VOP_SEL_SHIFT,
+	DCLK0_VOP_SEL_SHIFT			= 7,
+	DCLK0_VOP_SEL_MASK			= 3 << DCLK0_VOP_SEL_SHIFT,
+	DCLK2_VOP_SRC_SEL_SHIFT			= 5,
+	DCLK2_VOP_SRC_SEL_MASK			= 3 << DCLK2_VOP_SRC_SEL_SHIFT,
+	DCLK2_VOP_SRC_DIV_SHIFT			= 0,
+	DCLK2_VOP_SRC_DIV_MASK			= 0x1f << DCLK2_VOP_SRC_DIV_SHIFT,
+
+	/* CRU_CLK_SEL113_CON */
+	DCLK3_VOP_SRC_SEL_SHIFT			= 7,
+	DCLK3_VOP_SRC_SEL_MASK			= 3 << DCLK3_VOP_SRC_SEL_SHIFT,
+	DCLK3_VOP_SRC_DIV_SHIFT			= 0,
+	DCLK3_VOP_SRC_DIV_MASK			= 0x7f << DCLK3_VOP_SRC_DIV_SHIFT,
+
+	/* CRU_CLK_SEL117_CON */
+	CLK_AUX16MHZ_1_DIV_SHIFT		= 8,
+	CLK_AUX16MHZ_1_DIV_MASK			= 0xff << CLK_AUX16MHZ_1_DIV_SHIFT,
+	CLK_AUX16MHZ_0_DIV_SHIFT		= 0,
+	CLK_AUX16MHZ_0_DIV_MASK			= 0xff << CLK_AUX16MHZ_0_DIV_SHIFT,
+
+	/* CRU_CLK_SEL165_CON */
+	PCLK_CENTER_ROOT_SEL_SHIFT		= 6,
+	PCLK_CENTER_ROOT_SEL_MASK		= 3 << PCLK_CENTER_ROOT_SEL_SHIFT,
+	PCLK_CENTER_ROOT_SEL_200M		= 0,
+	PCLK_CENTER_ROOT_SEL_100M,
+	PCLK_CENTER_ROOT_SEL_50M,
+	PCLK_CENTER_ROOT_SEL_24M,
+	HCLK_CENTER_ROOT_SEL_SHIFT		= 4,
+	HCLK_CENTER_ROOT_SEL_MASK		= 3 << HCLK_CENTER_ROOT_SEL_SHIFT,
+	HCLK_CENTER_ROOT_SEL_400M		= 0,
+	HCLK_CENTER_ROOT_SEL_200M,
+	HCLK_CENTER_ROOT_SEL_100M,
+	HCLK_CENTER_ROOT_SEL_24M,
+	ACLK_CENTER_LOW_ROOT_SEL_SHIFT		= 2,
+	ACLK_CENTER_LOW_ROOT_SEL_MASK		= 3 << ACLK_CENTER_LOW_ROOT_SEL_SHIFT,
+	ACLK_CENTER_LOW_ROOT_SEL_500M		= 0,
+	ACLK_CENTER_LOW_ROOT_SEL_250M,
+	ACLK_CENTER_LOW_ROOT_SEL_100M,
+	ACLK_CENTER_LOW_ROOT_SEL_24M,
+	ACLK_CENTER_ROOT_SEL_SHIFT		= 0,
+	ACLK_CENTER_ROOT_SEL_MASK		= 3 << ACLK_CENTER_ROOT_SEL_SHIFT,
+	ACLK_CENTER_ROOT_SEL_700M		= 0,
+	ACLK_CENTER_ROOT_SEL_400M,
+	ACLK_CENTER_ROOT_SEL_200M,
+	ACLK_CENTER_ROOT_SEL_24M,
+
+	/* CRU_CLK_SEL172_CON */
+	CCLK_SDIO_SRC_SEL_SHIFT			= 8,
+	CCLK_SDIO_SRC_SEL_MASK			= 3 << CCLK_SDIO_SRC_SEL_SHIFT,
+	CCLK_SDIO_SRC_SEL_GPLL			= 0,
+	CCLK_SDIO_SRC_SEL_CPLL,
+	CCLK_SDIO_SRC_SEL_24M,
+	CCLK_SDIO_SRC_DIV_SHIFT			= 2,
+	CCLK_SDIO_SRC_DIV_MASK			= 0x3f << CCLK_SDIO_SRC_DIV_SHIFT,
+
+	/* CRU_CLK_SEL176_CON */
+	CLK_PCIE_PHY1_PLL_DIV_SHIFT		= 6,
+	CLK_PCIE_PHY1_PLL_DIV_MASK		= 0x3f << CLK_PCIE_PHY1_PLL_DIV_SHIFT,
+	CLK_PCIE_PHY0_PLL_DIV_SHIFT		= 0,
+	CLK_PCIE_PHY0_PLL_DIV_MASK		= 0x3f << CLK_PCIE_PHY0_PLL_DIV_SHIFT,
+
+	/* CRU_CLK_SEL177_CON */
+	CLK_PCIE_PHY2_REF_SEL_SHIFT		= 8,
+	CLK_PCIE_PHY2_REF_SEL_MASK		= 1 << CLK_PCIE_PHY2_REF_SEL_SHIFT,
+	CLK_PCIE_PHY1_REF_SEL_SHIFT		= 7,
+	CLK_PCIE_PHY1_REF_SEL_MASK		= 1 << CLK_PCIE_PHY1_REF_SEL_SHIFT,
+	CLK_PCIE_PHY0_REF_SEL_SHIFT		= 6,
+	CLK_PCIE_PHY0_REF_SEL_MASK		= 1 << CLK_PCIE_PHY0_REF_SEL_SHIFT,
+	CLK_PCIE_PHY_REF_SEL_24M		= 0,
+	CLK_PCIE_PHY_REF_SEL_PPLL,
+	CLK_PCIE_PHY2_PLL_DIV_SHIFT		= 0,
+	CLK_PCIE_PHY2_PLL_DIV_MASK		= 0x3f << CLK_PCIE_PHY2_PLL_DIV_SHIFT,
+
+	/* PMUCRU_CLK_SEL2_CON */
+	CLK_PMU1PWM_SEL_SHIFT			= 9,
+	CLK_PMU1PWM_SEL_MASK			= 3 << CLK_PMU1PWM_SEL_SHIFT,
+
+	/* PMUCRU_CLK_SEL3_CON */
+	CLK_I2C0_SEL_SHIFT			= 6,
+	CLK_I2C0_SEL_MASK			= 1 << CLK_I2C0_SEL_SHIFT,
+	CLK_I2C_SEL_200M			= 0,
+	CLK_I2C_SEL_100M,
+};
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3588.h b/arch/arm/include/asm/arch-rockchip/grf_rk3588.h
new file mode 100644
index 0000000..e069406
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3588.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __SOC_ROCKCHIP_RK3588_GRF_H__
+#define __SOC_ROCKCHIP_RK3588_GRF_H__
+
+struct rk3588_pmu1grf {
+	unsigned int soc_con[12];
+	unsigned int reserved0[(0x0050 - 0x002c) / 4 - 1];
+	unsigned int biu_con;
+	unsigned int biu_sts;
+	unsigned int reserved1[(0x0060 - 0x0054) / 4 - 1];
+	unsigned int soc_sts;
+	unsigned int reserved2[(0x0080 - 0x0060) / 4 - 1];
+	unsigned int mem_con[4];
+	unsigned int reserved3[(0x0200 - 0x008c) / 4 - 1];
+	unsigned int os_reg[8];
+	unsigned int reserved4[(0x0230 - 0x021c) / 4 - 1];
+	unsigned int rst_sts;
+	unsigned int rst_clr;
+	unsigned int reserved5[(0x0380 - 0x0234) / 4 - 1];
+	unsigned int sd_detect_con;
+	unsigned int reserved6[(0x0390 - 0x0380) / 4 - 1];
+	unsigned int sd_detect_sts;
+	unsigned int reserved7[(0x03a0 - 0x0390) / 4 - 1];
+	unsigned int sd_detect_clr;
+	unsigned int reserved8[(0x03b0 - 0x03a0) / 4 - 1];
+	unsigned int sd_detect_cnt;
+};
+
+check_member(rk3588_pmu1grf, sd_detect_cnt, 0x03b0);
+
+#endif /*__SOC_ROCKCHIP_RK3588_GRF_H__ */
diff --git a/arch/arm/include/asm/arch-rockchip/ioc_rk3588.h b/arch/arm/include/asm/arch-rockchip/ioc_rk3588.h
new file mode 100644
index 0000000..5a656f8
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/ioc_rk3588.h
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021 Rockchip Electronics Co., Ltd.
+ */
+#ifndef _ASM_ARCH_IOC_RK3588_H
+#define _ASM_ARCH_IOC_RK3588_H
+
+struct rk3588_bus_ioc {
+	unsigned int reserved0000[3];      /* Address Offset: 0x0000 */
+	unsigned int gpio0b_iomux_sel_h;   /* Address Offset: 0x000C */
+	unsigned int gpio0c_iomux_sel_l;   /* Address Offset: 0x0010 */
+	unsigned int gpio0c_iomux_sel_h;   /* Address Offset: 0x0014 */
+	unsigned int gpio0d_iomux_sel_l;   /* Address Offset: 0x0018 */
+	unsigned int gpio0d_iomux_sel_h;   /* Address Offset: 0x001C */
+	unsigned int gpio1a_iomux_sel_l;   /* Address Offset: 0x0020 */
+	unsigned int gpio1a_iomux_sel_h;   /* Address Offset: 0x0024 */
+	unsigned int gpio1b_iomux_sel_l;   /* Address Offset: 0x0028 */
+	unsigned int gpio1b_iomux_sel_h;   /* Address Offset: 0x002C */
+	unsigned int gpio1c_iomux_sel_l;   /* Address Offset: 0x0030 */
+	unsigned int gpio1c_iomux_sel_h;   /* Address Offset: 0x0034 */
+	unsigned int gpio1d_iomux_sel_l;   /* Address Offset: 0x0038 */
+	unsigned int gpio1d_iomux_sel_h;   /* Address Offset: 0x003C */
+	unsigned int gpio2a_iomux_sel_l;   /* Address Offset: 0x0040 */
+	unsigned int gpio2a_iomux_sel_h;   /* Address Offset: 0x0044 */
+	unsigned int gpio2b_iomux_sel_l;   /* Address Offset: 0x0048 */
+	unsigned int gpio2b_iomux_sel_h;   /* Address Offset: 0x004C */
+	unsigned int gpio2c_iomux_sel_l;   /* Address Offset: 0x0050 */
+	unsigned int gpio2c_iomux_sel_h;   /* Address Offset: 0x0054 */
+	unsigned int gpio2d_iomux_sel_l;   /* Address Offset: 0x0058 */
+	unsigned int gpio2d_iomux_sel_h;   /* Address Offset: 0x005C */
+	unsigned int gpio3a_iomux_sel_l;   /* Address Offset: 0x0060 */
+	unsigned int gpio3a_iomux_sel_h;   /* Address Offset: 0x0064 */
+	unsigned int gpio3b_iomux_sel_l;   /* Address Offset: 0x0068 */
+	unsigned int gpio3b_iomux_sel_h;   /* Address Offset: 0x006C */
+	unsigned int gpio3c_iomux_sel_l;   /* Address Offset: 0x0070 */
+	unsigned int gpio3c_iomux_sel_h;   /* Address Offset: 0x0074 */
+	unsigned int gpio3d_iomux_sel_l;   /* Address Offset: 0x0078 */
+	unsigned int gpio3d_iomux_sel_h;   /* Address Offset: 0x007C */
+	unsigned int gpio4a_iomux_sel_l;   /* Address Offset: 0x0080 */
+	unsigned int gpio4a_iomux_sel_h;   /* Address Offset: 0x0084 */
+	unsigned int gpio4b_iomux_sel_l;   /* Address Offset: 0x0088 */
+	unsigned int gpio4b_iomux_sel_h;   /* Address Offset: 0x008C */
+	unsigned int gpio4c_iomux_sel_l;   /* Address Offset: 0x0090 */
+	unsigned int gpio4c_iomux_sel_h;   /* Address Offset: 0x0094 */
+	unsigned int gpio4d_iomux_sel_l;   /* Address Offset: 0x0098 */
+	unsigned int gpio4d_iomux_sel_h;   /* Address Offset: 0x009C */
+};
+
+check_member(rk3588_bus_ioc, gpio4d_iomux_sel_h, 0x009C);
+
+struct rk3588_pmu1_ioc {
+	unsigned int gpio0a_iomux_sel_l;   /* Address Offset: 0x0000 */
+	unsigned int gpio0a_iomux_sel_h;   /* Address Offset: 0x0004 */
+	unsigned int gpio0b_iomux_sel_l;   /* Address Offset: 0x0008 */
+	unsigned int reserved0012;         /* Address Offset: 0x000C */
+	unsigned int gpio0a_ds_l;          /* Address Offset: 0x0010 */
+	unsigned int gpio0a_ds_h;          /* Address Offset: 0x0014 */
+	unsigned int gpio0b_ds_l;          /* Address Offset: 0x0018 */
+	unsigned int reserved0028;         /* Address Offset: 0x001C */
+	unsigned int gpio0a_p;             /* Address Offset: 0x0020 */
+	unsigned int gpio0b_p;             /* Address Offset: 0x0024 */
+	unsigned int gpio0a_ie;            /* Address Offset: 0x0028 */
+	unsigned int gpio0b_ie;            /* Address Offset: 0x002C */
+	unsigned int gpio0a_smt;           /* Address Offset: 0x0030 */
+	unsigned int gpio0b_smt;           /* Address Offset: 0x0034 */
+	unsigned int gpio0a_pdis;          /* Address Offset: 0x0038 */
+	unsigned int gpio0b_pdis;          /* Address Offset: 0x003C */
+	unsigned int xin_con;              /* Address Offset: 0x0040 */
+};
+
+check_member(rk3588_pmu1_ioc, xin_con, 0x0040);
+
+struct rk3588_pmu2_ioc {
+	unsigned int gpio0b_iomux_sel_h;  /* Address Offset: 0x0000 */
+	unsigned int gpio0c_iomux_sel_l;  /* Address Offset: 0x0004 */
+	unsigned int gpio0c_iomux_sel_h;  /* Address Offset: 0x0008 */
+	unsigned int gpio0d_iomux_sel_l;  /* Address Offset: 0x000C */
+	unsigned int gpio0d_iomux_sel_h;  /* Address Offset: 0x0010 */
+	unsigned int gpio0b_ds_h;         /* Address Offset: 0x0014 */
+	unsigned int gpio0c_ds_l;         /* Address Offset: 0x0018 */
+	unsigned int gpio0c_ds_h;         /* Address Offset: 0x001C */
+	unsigned int gpio0d_ds_l;         /* Address Offset: 0x0020 */
+	unsigned int gpio0d_ds_h;         /* Address Offset: 0x0024 */
+	unsigned int gpio0b_p;            /* Address Offset: 0x0028 */
+	unsigned int gpio0c_p;            /* Address Offset: 0x002C */
+	unsigned int gpio0d_p;            /* Address Offset: 0x0030 */
+	unsigned int gpio0b_ie;           /* Address Offset: 0x0034 */
+	unsigned int gpio0c_ie;           /* Address Offset: 0x0038 */
+	unsigned int gpio0d_ie;           /* Address Offset: 0x003C */
+	unsigned int gpio0b_smt;          /* Address Offset: 0x0040 */
+	unsigned int gpio0c_smt;          /* Address Offset: 0x0044 */
+	unsigned int gpio0d_smt;          /* Address Offset: 0x0048 */
+	unsigned int gpio0b_pdis;         /* Address Offset: 0x004C */
+	unsigned int gpio0c_pdis;         /* Address Offset: 0x0050 */
+	unsigned int gpio0d_pdis;         /* Address Offset: 0x0054 */
+};
+
+check_member(rk3588_pmu2_ioc, gpio0d_pdis, 0x0054);
+
+#endif
+
diff --git a/arch/arm/include/asm/arch-rockchip/sdram.h b/arch/arm/include/asm/arch-rockchip/sdram.h
index cf2a7b7..4fb45ac 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram.h
@@ -8,10 +8,13 @@
 
 enum {
 	DDR4 = 0,
-	DDR3 = 0x3,
-	LPDDR2 = 0x5,
-	LPDDR3 = 0x6,
-	LPDDR4 = 0x7,
+	DDR3 = 3,
+	LPDDR2 = 5,
+	LPDDR3 = 6,
+	LPDDR4 = 7,
+	LPDDR4X = 8,
+	LPDDR5 = 9,
+	DDR5 = 10,
 	UNUSED = 0xFF
 };
 
@@ -21,16 +24,16 @@
  * [30]		row_3_4_ch0
  * [29:28]	chinfo
  * [27]		rank_ch1
- * [26:25]	col_ch1
+ * [26:25]	cs0_col_ch1
  * [24]		bk_ch1
  * [23:22]	low bits of cs0_row_ch1
  * [21:20]	low bits of cs1_row_ch1
  * [19:18]	bw_ch1
- * [17:16]	dbw_ch1;
- * [15:13]	ddrtype
+ * [17:16]	dbw_ch1
+ * [15:13]	low bits of ddrtype
  * [12]		channelnum
- * [11]		rank_ch0
- * [10:9]	col_ch0,
+ * [11]		low bit of rank_ch0
+ * [10:9]	cs0_col_ch0
  * [8]		bk_ch0
  * [7:6]	low bits of cs0_row_ch0
  * [5:4]	low bits of cs1_row_ch0
@@ -61,6 +64,11 @@
 
 /*
  * sys_reg3 bitfield struct
+ * [31:28]	version
+ * [16]		cs3_delta_row
+ * [15]		cs2_delta_row
+ * [14]		high bit of rank_ch0
+ * [13:12]	high bits of ddrtype
  * [7]		high bit of cs0_row_ch1
  * [6]		high bit of cs1_row_ch1
  * [5]		high bit of cs0_row_ch0
@@ -70,6 +78,8 @@
  */
 #define SYS_REG_VERSION_SHIFT			28
 #define SYS_REG_VERSION_MASK			0xf
+#define SYS_REG_EXTEND_DDRTYPE_SHIFT		12
+#define SYS_REG_EXTEND_DDRTYPE_MASK		3
 #define SYS_REG_EXTEND_CS0_ROW_SHIFT(ch)	(5 + (ch) * 2)
 #define SYS_REG_EXTEND_CS0_ROW_MASK		1
 #define SYS_REG_EXTEND_CS1_ROW_SHIFT(ch)	(4 + (ch) * 2)
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index b678ec4..0390431 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -286,7 +286,11 @@
 	select REGMAP
 	select SYSCON
 	select BOARD_LATE_INIT
+	select DM_REGULATOR_FIXED
+	select DM_RESET
 	imply ROCKCHIP_COMMON_BOARD
+	imply ROCKCHIP_OTP
+	imply MISC_INIT_R
 	help
 	  The Rockchip RK3568 is a ARM-based SoC with quad-core Cortex-A55,
 	  including NEON and GPU, 512K L3 cache, Mali-G52 based graphics,
@@ -294,6 +298,27 @@
 	  and video codec support. Peripherals include Gigabit Ethernet,
 	  USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs.
 
+config ROCKCHIP_RK3588
+	bool "Support Rockchip RK3588"
+	select ARM64
+	select SUPPORT_SPL
+	select SPL
+	select CLK
+	select PINCTRL
+	select RAM
+	select REGMAP
+	select SYSCON
+	select BOARD_LATE_INIT
+	imply ROCKCHIP_COMMON_BOARD
+	imply ROCKCHIP_OTP
+	imply MISC_INIT_R
+	help
+	  The Rockchip RK3588 is a ARM-based SoC with quad-core Cortex-A76 and
+	  quad-core Cortex-A55 including NEON and GPU, 6TOPS NPU, Mali-G610 MP4,
+	  HDMI Out, HDMI In, DP, eDP, MIPI DSI, MIPI CSI2, LPDDR4/4X/5, eMMC5.1,
+	  SD3.0/MMC4.5, USB OTG 3.0, Type-C, USB 2.0, PCIe 3.0, SATA 3, Ethernet,
+	  SDIO3.0 I2C, UART, SPI, GPIO and PWM.
+
 config ROCKCHIP_RV1108
 	bool "Support Rockchip RV1108"
 	select CPU_V7A
@@ -401,6 +426,14 @@
 	  common board is a basic TPL board init which can be shared for most
 	  of SoCs to avoid copy-paste for different SoCs.
 
+config ROCKCHIP_EXTERNAL_TPL
+	bool "Use external TPL binary"
+	default y if ROCKCHIP_RK3568
+	help
+	  Some Rockchip SoCs require an external TPL to initialize DRAM.
+	  Enable this option and build with ROCKCHIP_TPL=/path/to/ddr.bin to
+	  include the external TPL in the image built by binman.
+
 config ROCKCHIP_BOOT_MODE_REG
 	hex "Rockchip boot mode flag register address"
 	help
@@ -491,6 +524,7 @@
 source "arch/arm/mach-rockchip/rk3368/Kconfig"
 source "arch/arm/mach-rockchip/rk3399/Kconfig"
 source "arch/arm/mach-rockchip/rk3568/Kconfig"
+source "arch/arm/mach-rockchip/rk3588/Kconfig"
 source "arch/arm/mach-rockchip/rv1108/Kconfig"
 source "arch/arm/mach-rockchip/rv1126/Kconfig"
 endif
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index e3d4a8b..1dc9206 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -44,6 +44,7 @@
 obj-$(CONFIG_ROCKCHIP_RK3368) += rk3368/
 obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399/
 obj-$(CONFIG_ROCKCHIP_RK3568) += rk3568/
+obj-$(CONFIG_ROCKCHIP_RK3588) += rk3588/
 obj-$(CONFIG_ROCKCHIP_RV1108) += rv1108/
 obj-$(CONFIG_ROCKCHIP_RV1126) += rv1126/
 
diff --git a/arch/arm/mach-rockchip/board.c b/arch/arm/mach-rockchip/board.c
index ebffb6c..f1f70c8 100644
--- a/arch/arm/mach-rockchip/board.c
+++ b/arch/arm/mach-rockchip/board.c
@@ -323,7 +323,7 @@
 #ifdef CONFIG_MISC_INIT_R
 __weak int misc_init_r(void)
 {
-	const u32 cpuid_offset = 0x7;
+	const u32 cpuid_offset = CFG_CPUID_OFFSET;
 	const u32 cpuid_length = 0x10;
 	u8 cpuid[cpuid_length];
 	int ret;
diff --git a/arch/arm/mach-rockchip/misc.c b/arch/arm/mach-rockchip/misc.c
index b350f18..849014d 100644
--- a/arch/arm/mach-rockchip/misc.c
+++ b/arch/arm/mach-rockchip/misc.c
@@ -23,7 +23,7 @@
 
 int rockchip_setup_macaddr(void)
 {
-#if IS_ENABLED(CONFIG_CMD_NET)
+#if CONFIG_IS_ENABLED(HASH) && CONFIG_IS_ENABLED(SHA256)
 	int ret;
 	const char *cpuid = env_get("cpuid#");
 	u8 hash[SHA256_SUM_LEN];
@@ -52,6 +52,10 @@
 	mac_addr[0] &= 0xfe;  /* clear multicast bit */
 	mac_addr[0] |= 0x02;  /* set local assignment bit (IEEE802) */
 	eth_env_set_enetaddr("ethaddr", mac_addr);
+
+	/* Make a valid MAC address for ethernet1 */
+	mac_addr[5] ^= 0x01;
+	eth_env_set_enetaddr("eth1addr", mac_addr);
 #endif
 	return 0;
 }
diff --git a/arch/arm/mach-rockchip/rk3568/rk3568.c b/arch/arm/mach-rockchip/rk3568/rk3568.c
index 22eeb77..4a08820a 100644
--- a/arch/arm/mach-rockchip/rk3568/rk3568.c
+++ b/arch/arm/mach-rockchip/rk3568/rk3568.c
@@ -7,6 +7,7 @@
 #include <dm.h>
 #include <asm/armv8/mmu.h>
 #include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
 #include <asm/arch-rockchip/grf_rk3568.h>
 #include <asm/arch-rockchip/hardware.h>
 #include <dt-bindings/clock/rk3568-cru.h>
@@ -23,6 +24,16 @@
 #define SGRF_SOC_CON4			0x10
 #define EMMC_HPROT_SECURE_CTRL		0x03
 #define SDMMC0_HPROT_SECURE_CTRL	0x01
+
+#define PMU_BASE_ADDR		0xfdd90000
+#define PMU_NOC_AUTO_CON0	(0x70)
+#define PMU_NOC_AUTO_CON1	(0x74)
+#define EDP_PHY_GRF_BASE	0xfdcb0000
+#define EDP_PHY_GRF_CON0	(EDP_PHY_GRF_BASE + 0x00)
+#define EDP_PHY_GRF_CON10	(EDP_PHY_GRF_BASE + 0x28)
+#define CPU_GRF_BASE		0xfdc30000
+#define GRF_CORE_PVTPLL_CON0	(0x10)
+
 /* PMU_GRF_GPIO0D_IOMUX_L */
 enum {
 	GPIO0D1_SHIFT		= 4,
@@ -70,6 +81,12 @@
 	}
 };
 
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+	[BROM_BOOTSOURCE_EMMC] = "/sdhci@fe310000",
+	[BROM_BOOTSOURCE_SPINOR] = "/spi@fe300000/flash@0",
+	[BROM_BOOTSOURCE_SD] = "/mmc@fe2b0000",
+};
+
 struct mm_region *mem_map = rk3568_mem_map;
 
 void board_debug_uart_init(void)
@@ -91,6 +108,20 @@
 int arch_cpu_init(void)
 {
 #ifdef CONFIG_SPL_BUILD
+	/*
+	 * When perform idle operation, corresponding clock can
+	 * be opened or gated automatically.
+	 */
+	writel(0xffffffff, PMU_BASE_ADDR + PMU_NOC_AUTO_CON0);
+	writel(0x000f000f, PMU_BASE_ADDR + PMU_NOC_AUTO_CON1);
+
+	/* Disable eDP phy by default */
+	writel(0x00070007, EDP_PHY_GRF_CON10);
+	writel(0x0ff10ff1, EDP_PHY_GRF_CON0);
+
+	/* Set core pvtpll ring length */
+	writel(0x00ff002b, CPU_GRF_BASE + GRF_CORE_PVTPLL_CON0);
+
 	/* Set the emmc sdmmc0 to secure */
 	rk_clrreg(SGRF_BASE + SGRF_SOC_CON4, (EMMC_HPROT_SECURE_CTRL << 11
 		| SDMMC0_HPROT_SECURE_CTRL << 4));
diff --git a/arch/arm/mach-rockchip/rk3588/Kconfig b/arch/arm/mach-rockchip/rk3588/Kconfig
new file mode 100644
index 0000000..aee71ca
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3588/Kconfig
@@ -0,0 +1,56 @@
+if ROCKCHIP_RK3588
+
+config TARGET_RK3588_NEU6
+	bool "Edgeble Neural Compute Module 6(Neu6) SoM"
+	select BOARD_LATE_INIT
+	help
+	  Neu6:
+	  Neural Compute Module 6A(Neu6a) is a 96boards SoM-CB compute module
+	  based on Rockchip RK3588 from Edgeble AI.
+
+	  Neu6-IO:
+	  Neural Compute Module 6(Neu6) IO board is an industrial form factor
+	  IO board and Neu6a needs to mount on top of this IO board in order to
+	  create complete Edgeble Neural Compute Module 6(Neu6) IO platform.
+
+config TARGET_ROCK5B_RK3588
+	bool "Radxa ROCK5B RK3588 board"
+	select BOARD_LATE_INIT
+	help
+	  Radxa ROCK5B is a Rockchip RK3588 based SBC (Single Board Computer)
+	  by Radxa.
+
+	  There are tree variants depending on the DRAM size : 4G, 8G and 16G.
+
+	  Specification:
+
+	  Rockchip Rk3588 SoC
+	  4x ARM Cortex-A76, 4x ARM Cortex-A55
+	  4/8/16GB memory LPDDR4x
+	  Mali G610MC4 GPU
+	  MIPI CSI 2 multiple lanes connector
+	  eMMC module connector
+	  uSD slot (up to 128GB)
+	  2x USB 2.0, 2x USB 3.0
+	  2x HDMI output, 1x HDMI input
+	  Ethernet port
+	  40-pin IO header including UART, SPI, I2C and 5V DC power in
+	  USB PD over USB Type-C
+	  Size: 85mm x 54mm
+
+config ROCKCHIP_BOOT_MODE_REG
+	default 0xfd588080
+
+config ROCKCHIP_STIMER_BASE
+	default 0xfd8c8000
+
+config SYS_SOC
+	default "rk3588"
+
+config SYS_MALLOC_F_LEN
+	default 0x80000
+
+source board/edgeble/neural-compute-module-6/Kconfig
+source board/radxa/rock5b-rk3588/Kconfig
+
+endif
diff --git a/arch/arm/mach-rockchip/rk3588/Makefile b/arch/arm/mach-rockchip/rk3588/Makefile
new file mode 100644
index 0000000..4003eea
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3588/Makefile
@@ -0,0 +1,9 @@
+#
+# (C) Copyright 2021 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y += rk3588.o
+obj-y += clk_rk3588.o
+obj-y += syscon_rk3588.o
diff --git a/arch/arm/mach-rockchip/rk3588/clk_rk3588.c b/arch/arm/mach-rockchip/rk3588/clk_rk3588.c
new file mode 100644
index 0000000..3df0bf2
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3588/clk_rk3588.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2020 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3588.h>
+#include <linux/err.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+	return uclass_get_device_by_driver(UCLASS_CLK,
+			DM_DRIVER_GET(rockchip_rk3588_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+	struct rk3588_clk_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	ret = rockchip_get_clk(&dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv = dev_get_priv(dev);
+
+	return priv->cru;
+}
diff --git a/arch/arm/mach-rockchip/rk3588/rk3588.c b/arch/arm/mach-rockchip/rk3588/rk3588.c
new file mode 100644
index 0000000..2ee1db4
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3588/rk3588.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/armv8/mmu.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/ioc_rk3588.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define FIREWALL_DDR_BASE		0xfe030000
+#define FW_DDR_MST5_REG			0x54
+#define FW_DDR_MST13_REG		0x74
+#define FW_DDR_MST21_REG		0x94
+#define FW_DDR_MST26_REG		0xa8
+#define FW_DDR_MST27_REG		0xac
+#define FIREWALL_SYSMEM_BASE		0xfe038000
+#define FW_SYSM_MST5_REG		0x54
+#define FW_SYSM_MST13_REG		0x74
+#define FW_SYSM_MST21_REG		0x94
+#define FW_SYSM_MST26_REG		0xa8
+#define FW_SYSM_MST27_REG		0xac
+
+#define PMU1_IOC_BASE			0xfd5f0000
+#define PMU2_IOC_BASE			0xfd5f4000
+
+#define BUS_IOC_BASE			0xfd5f8000
+#define BUS_IOC_GPIO2A_IOMUX_SEL_L	0x40
+#define BUS_IOC_GPIO2B_IOMUX_SEL_L	0x48
+#define BUS_IOC_GPIO2D_IOMUX_SEL_L	0x58
+#define BUS_IOC_GPIO2D_IOMUX_SEL_H	0x5c
+#define BUS_IOC_GPIO3A_IOMUX_SEL_L	0x60
+
+static struct mm_region rk3588_mem_map[] = {
+	{
+		.virt = 0x0UL,
+		.phys = 0x0UL,
+		.size = 0xf0000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
+		.virt = 0xf0000000UL,
+		.phys = 0xf0000000UL,
+		.size = 0x10000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	},  {
+		.virt = 0x900000000,
+		.phys = 0x900000000,
+		.size = 0x150000000,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	},  {
+		/* List terminator */
+		0,
+	}
+};
+
+struct mm_region *mem_map = rk3588_mem_map;
+
+/* GPIO0B_IOMUX_SEL_H */
+enum {
+	GPIO0B5_SHIFT		= 4,
+	GPIO0B5_MASK		= GENMASK(7, 4),
+	GPIO0B5_REFER		= 8,
+	GPIO0B5_UART2_TX_M0	= 10,
+
+	GPIO0B6_SHIFT		= 8,
+	GPIO0B6_MASK		= GENMASK(11, 8),
+	GPIO0B6_REFER		= 8,
+	GPIO0B6_UART2_RX_M0	= 10,
+};
+
+void board_debug_uart_init(void)
+{
+	__maybe_unused static struct rk3588_bus_ioc * const bus_ioc = (void *)BUS_IOC_BASE;
+	static struct rk3588_pmu2_ioc * const pmu2_ioc = (void *)PMU2_IOC_BASE;
+
+	/* Refer to BUS_IOC */
+	rk_clrsetreg(&pmu2_ioc->gpio0b_iomux_sel_h,
+		     GPIO0B6_MASK | GPIO0B5_MASK,
+		     GPIO0B6_REFER << GPIO0B6_SHIFT |
+		     GPIO0B5_REFER << GPIO0B5_SHIFT);
+
+	/* UART2_M0 Switch iomux */
+	rk_clrsetreg(&bus_ioc->gpio0b_iomux_sel_h,
+		     GPIO0B6_MASK | GPIO0B5_MASK,
+		     GPIO0B6_UART2_RX_M0 << GPIO0B6_SHIFT |
+		     GPIO0B5_UART2_TX_M0 << GPIO0B5_SHIFT);
+}
+
+#ifdef CONFIG_SPL_BUILD
+void rockchip_stimer_init(void)
+{
+	/* If Timer already enabled, don't re-init it */
+	u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + 0x4);
+
+	if (reg & 0x1)
+		return;
+
+	asm volatile("msr CNTFRQ_EL0, %0" : : "r" (CONFIG_COUNTER_FREQUENCY));
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 0x14);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 0x18);
+	writel(0x1, CONFIG_ROCKCHIP_STIMER_BASE + 0x4);
+}
+#endif
+
+#ifndef CONFIG_TPL_BUILD
+int arch_cpu_init(void)
+{
+#ifdef CONFIG_SPL_BUILD
+	int secure_reg;
+
+	/* Set the SDMMC eMMC crypto_ns FSPI access secure area */
+	secure_reg = readl(FIREWALL_DDR_BASE + FW_DDR_MST5_REG);
+	secure_reg &= 0xffff;
+	writel(secure_reg, FIREWALL_DDR_BASE + FW_DDR_MST5_REG);
+	secure_reg = readl(FIREWALL_DDR_BASE + FW_DDR_MST13_REG);
+	secure_reg &= 0xffff;
+	writel(secure_reg, FIREWALL_DDR_BASE + FW_DDR_MST13_REG);
+	secure_reg = readl(FIREWALL_DDR_BASE + FW_DDR_MST21_REG);
+	secure_reg &= 0xffff;
+	writel(secure_reg, FIREWALL_DDR_BASE + FW_DDR_MST21_REG);
+	secure_reg = readl(FIREWALL_DDR_BASE + FW_DDR_MST26_REG);
+	secure_reg &= 0xffff;
+	writel(secure_reg, FIREWALL_DDR_BASE + FW_DDR_MST26_REG);
+	secure_reg = readl(FIREWALL_DDR_BASE + FW_DDR_MST27_REG);
+	secure_reg &= 0xffff0000;
+	writel(secure_reg, FIREWALL_DDR_BASE + FW_DDR_MST27_REG);
+
+	secure_reg = readl(FIREWALL_SYSMEM_BASE + FW_SYSM_MST5_REG);
+	secure_reg &= 0xffff;
+	writel(secure_reg, FIREWALL_SYSMEM_BASE + FW_SYSM_MST5_REG);
+	secure_reg = readl(FIREWALL_SYSMEM_BASE + FW_SYSM_MST13_REG);
+	secure_reg &= 0xffff;
+	writel(secure_reg, FIREWALL_SYSMEM_BASE + FW_SYSM_MST13_REG);
+	secure_reg = readl(FIREWALL_SYSMEM_BASE + FW_SYSM_MST21_REG);
+	secure_reg &= 0xffff;
+	writel(secure_reg, FIREWALL_SYSMEM_BASE + FW_SYSM_MST21_REG);
+	secure_reg = readl(FIREWALL_SYSMEM_BASE + FW_SYSM_MST26_REG);
+	secure_reg &= 0xffff;
+	writel(secure_reg, FIREWALL_SYSMEM_BASE + FW_SYSM_MST26_REG);
+	secure_reg = readl(FIREWALL_SYSMEM_BASE + FW_SYSM_MST27_REG);
+	secure_reg &= 0xffff0000;
+	writel(secure_reg, FIREWALL_SYSMEM_BASE + FW_SYSM_MST27_REG);
+#endif
+
+	return 0;
+}
+#endif
diff --git a/arch/arm/mach-rockchip/rk3588/syscon_rk3588.c b/arch/arm/mach-rockchip/rk3588/syscon_rk3588.c
new file mode 100644
index 0000000..e8772d3
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3588/syscon_rk3588.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2021 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+
+static const struct udevice_id rk3588_syscon_ids[] = {
+	{ .compatible = "rockchip,rk3588-sys-grf", .data = ROCKCHIP_SYSCON_GRF },
+	{ .compatible = "rockchip,rk3588-pmu1-grf", .data = ROCKCHIP_SYSCON_PMUGRF },
+	{ .compatible = "rockchip,rk3588-vop-grf", .data = ROCKCHIP_SYSCON_VOP_GRF },
+	{ .compatible = "rockchip,rk3588-vo-grf",  .data = ROCKCHIP_SYSCON_VO_GRF },
+	{ .compatible = "rockchip,pcie30-phy-grf", .data = ROCKCHIP_SYSCON_PCIE30_PHY_GRF },
+	{ .compatible = "rockchip,rk3588-php-grf", .data = ROCKCHIP_SYSCON_PHP_GRF },
+	{ .compatible = "rockchip,pipe-phy-grf",   .data = ROCKCHIP_SYSCON_PIPE_PHY0_GRF },
+	{ .compatible = "rockchip,pipe-phy-grf",   .data = ROCKCHIP_SYSCON_PIPE_PHY1_GRF },
+	{ .compatible = "rockchip,pipe-phy-grf",   .data = ROCKCHIP_SYSCON_PIPE_PHY2_GRF },
+	{ .compatible = "rockchip,rk3588-pmu",     .data = ROCKCHIP_SYSCON_PMU },
+	{ }
+};
+
+U_BOOT_DRIVER(syscon_rk3588) = {
+	.name = "rk3588_syscon",
+	.id = UCLASS_SYSCON,
+	.of_match = rk3588_syscon_ids,
+#if CONFIG_IS_ENABLED(OF_REAL)
+	.bind = dm_scan_fdt_dev,
+#endif
+};
diff --git a/arch/arm/mach-rockchip/sdram.c b/arch/arm/mach-rockchip/sdram.c
index e086c47..1d17a74 100644
--- a/arch/arm/mach-rockchip/sdram.c
+++ b/arch/arm/mach-rockchip/sdram.c
@@ -37,13 +37,19 @@
 
 int dram_init_banksize(void)
 {
-	size_t top = min((unsigned long)(gd->ram_size + CFG_SYS_SDRAM_BASE),
-			 (unsigned long)(gd->ram_top));
+	size_t ram_top = (unsigned long)(gd->ram_size + CFG_SYS_SDRAM_BASE);
+	size_t top = min((unsigned long)ram_top, (unsigned long)(gd->ram_top));
 
 #ifdef CONFIG_ARM64
 	/* Reserve 0x200000 for ATF bl31 */
 	gd->bd->bi_dram[0].start = 0x200000;
 	gd->bd->bi_dram[0].size = top - gd->bd->bi_dram[0].start;
+
+	/* Add usable memory beyond the blob of space for peripheral near 4GB */
+	if (ram_top > SZ_4G && top < SZ_4G) {
+		gd->bd->bi_dram[1].start = SZ_4G;
+		gd->bd->bi_dram[1].size = ram_top - gd->bd->bi_dram[1].start;
+	}
 #else
 #ifdef CONFIG_SPL_OPTEE_IMAGE
 	struct tos_parameter_t *tos_parameter;
@@ -88,9 +94,15 @@
 	u32 sys_reg3 = readl(reg + 4);
 	u32 ch_num = 1 + ((sys_reg2 >> SYS_REG_NUM_CH_SHIFT)
 		       & SYS_REG_NUM_CH_MASK);
+	u32 version = (sys_reg3 >> SYS_REG_VERSION_SHIFT) &
+		      SYS_REG_VERSION_MASK;
 
 	dram_type = (sys_reg2 >> SYS_REG_DDRTYPE_SHIFT) & SYS_REG_DDRTYPE_MASK;
+	if (version >= 3)
+		dram_type |= ((sys_reg3 >> SYS_REG_EXTEND_DDRTYPE_SHIFT) &
+			      SYS_REG_EXTEND_DDRTYPE_MASK) << 3;
 	debug("%s %x %x\n", __func__, (u32)reg, sys_reg2);
+	debug("%s %x %x\n", __func__, (u32)reg + 4, sys_reg3);
 	for (ch = 0; ch < ch_num; ch++) {
 		rank = 1 + (sys_reg2 >> SYS_REG_RANK_SHIFT(ch) &
 			SYS_REG_RANK_MASK);
@@ -98,8 +110,7 @@
 			  SYS_REG_COL_MASK);
 		cs1_col = cs0_col;
 		bk = 3 - ((sys_reg2 >> SYS_REG_BK_SHIFT(ch)) & SYS_REG_BK_MASK);
-		if ((sys_reg3 >> SYS_REG_VERSION_SHIFT &
-		     SYS_REG_VERSION_MASK) == 0x2) {
+		if (version >= 2) {
 			cs1_col = 9 + (sys_reg3 >> SYS_REG_CS1_COL_SHIFT(ch) &
 				  SYS_REG_CS1_COL_MASK);
 			if (((sys_reg3 >> SYS_REG_EXTEND_CS0_ROW_SHIFT(ch) &
@@ -176,7 +187,7 @@
 	 *   2. update board_get_usable_ram_top() and dram_init_banksize()
 	 *   to reserve memory for peripheral space after previous update.
 	 */
-	if (size_mb > (SDRAM_MAX_SIZE >> 20))
+	if (!IS_ENABLED(CONFIG_ARM64) && size_mb > (SDRAM_MAX_SIZE >> 20))
 		size_mb = (SDRAM_MAX_SIZE >> 20);
 
 	return (size_t)size_mb << 20;
diff --git a/arch/sandbox/include/asm/types.h b/arch/sandbox/include/asm/types.h
index c1a5d2a..5f4b649 100644
--- a/arch/sandbox/include/asm/types.h
+++ b/arch/sandbox/include/asm/types.h
@@ -18,11 +18,7 @@
 /*
  * Number of bits in a C 'long' on this architecture.
  */
-#ifdef	CONFIG_PHYS_64BIT
-#define BITS_PER_LONG 64
-#else	/* CONFIG_PHYS_64BIT */
-#define BITS_PER_LONG 32
-#endif	/* CONFIG_PHYS_64BIT */
+#define BITS_PER_LONG CONFIG_SANDBOX_BITS_PER_LONG
 
 #ifdef	CONFIG_PHYS_64BIT
 typedef unsigned long long dma_addr_t;
diff --git a/arch/x86/dts/efi-x86_app.dts b/arch/x86/dts/efi-x86_app.dts
index 6d843a9..59e2e40 100644
--- a/arch/x86/dts/efi-x86_app.dts
+++ b/arch/x86/dts/efi-x86_app.dts
@@ -27,6 +27,7 @@
 	};
 	efi-fb {
 		compatible = "efi-fb";
+		bootph-some-ram;
 	};
 
 };
diff --git a/arch/x86/lib/bdinfo.c b/arch/x86/lib/bdinfo.c
index 0cb79b0..1539007 100644
--- a/arch/x86/lib/bdinfo.c
+++ b/arch/x86/lib/bdinfo.c
@@ -8,6 +8,7 @@
 #include <common.h>
 #include <efi.h>
 #include <init.h>
+#include <asm/cpu.h>
 #include <asm/efi.h>
 #include <asm/global_data.h>
 
@@ -16,6 +17,11 @@
 void arch_print_bdinfo(void)
 {
 	bdinfo_print_num_l("prev table", gd->arch.table);
+	bdinfo_print_num_l("clock_rate", gd->arch.clock_rate);
+	bdinfo_print_num_l("tsc_base", gd->arch.tsc_base);
+	bdinfo_print_num_l("vendor", gd->arch.x86_vendor);
+	bdinfo_print_str(" name", cpu_vendor_name(gd->arch.x86_vendor));
+	bdinfo_print_num_l("model", gd->arch.x86_model);
 
 	if (IS_ENABLED(CONFIG_EFI_STUB))
 		efi_show_bdinfo();
diff --git a/arch/x86/lib/fsp/fsp_graphics.c b/arch/x86/lib/fsp/fsp_graphics.c
index b07c666..2bcc49f 100644
--- a/arch/x86/lib/fsp/fsp_graphics.c
+++ b/arch/x86/lib/fsp/fsp_graphics.c
@@ -106,7 +106,7 @@
 	vesa->phys_base_ptr = dm_pci_read_bar32(dev, 2);
 	gd->fb_base = vesa->phys_base_ptr;
 
-	ret = vesa_setup_video_priv(vesa, uc_priv, plat);
+	ret = vesa_setup_video_priv(vesa, vesa->phys_base_ptr, uc_priv, plat);
 	if (ret)
 		goto err;
 
diff --git a/board/edgeble/neural-compute-module-2/MAINTAINERS b/board/edgeble/neural-compute-module-2/MAINTAINERS
index 38edb3a..bd24052 100644
--- a/board/edgeble/neural-compute-module-2/MAINTAINERS
+++ b/board/edgeble/neural-compute-module-2/MAINTAINERS
@@ -1,4 +1,4 @@
-RV1126-ECM0
+RV1126-NEU2
 M:	Jagan Teki <jagan@edgeble.ai>
 S:	Maintained
 F:	board/edgeble/neural-compute-module-2
diff --git a/board/edgeble/neural-compute-module-6/Kconfig b/board/edgeble/neural-compute-module-6/Kconfig
new file mode 100644
index 0000000..c445454
--- /dev/null
+++ b/board/edgeble/neural-compute-module-6/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_RK3588_NEU6
+
+config SYS_BOARD
+	default "neural-compute-module-6"
+
+config SYS_VENDOR
+	default "edgeble"
+
+config SYS_CONFIG_NAME
+	default "neural-compute-module-6"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+
+endif
diff --git a/board/edgeble/neural-compute-module-6/MAINTAINERS b/board/edgeble/neural-compute-module-6/MAINTAINERS
new file mode 100644
index 0000000..249df95
--- /dev/null
+++ b/board/edgeble/neural-compute-module-6/MAINTAINERS
@@ -0,0 +1,6 @@
+RK3588-NEU6
+M:	Jagan Teki <jagan@edgeble.ai>
+S:	Maintained
+F:	board/edgeble/neural-compute-module-6
+F:	include/configs/neural-compute-module-6.h
+F:	configs/neu6a-io-rk3588_defconfig
diff --git a/board/edgeble/neural-compute-module-6/Makefile b/board/edgeble/neural-compute-module-6/Makefile
new file mode 100644
index 0000000..28310b1
--- /dev/null
+++ b/board/edgeble/neural-compute-module-6/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y += neu6.o
diff --git a/board/edgeble/neural-compute-module-6/neu6.c b/board/edgeble/neural-compute-module-6/neu6.c
new file mode 100644
index 0000000..3d2262c
--- /dev/null
+++ b/board/edgeble/neural-compute-module-6/neu6.c
@@ -0,0 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
diff --git a/board/radxa/rock5b-rk3588/Kconfig b/board/radxa/rock5b-rk3588/Kconfig
new file mode 100644
index 0000000..8f14446
--- /dev/null
+++ b/board/radxa/rock5b-rk3588/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_ROCK5B_RK3588
+
+config SYS_BOARD
+	default "rock5b-rk3588"
+
+config SYS_VENDOR
+	default "radxa"
+
+config SYS_CONFIG_NAME
+	default "rock5b-rk3588"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+
+endif
diff --git a/board/radxa/rock5b-rk3588/MAINTAINERS b/board/radxa/rock5b-rk3588/MAINTAINERS
new file mode 100644
index 0000000..693751e
--- /dev/null
+++ b/board/radxa/rock5b-rk3588/MAINTAINERS
@@ -0,0 +1,6 @@
+ROCK5B-RK3588
+M:	Eugen Hristev <eugen.hristev@collabora.com>
+S:	Maintained
+F:	board/radxa/rock5b-rk3588
+F:	include/configs/rock5b-rk3588
+F:	configs/rock5b-rk3588_defconfig
diff --git a/board/radxa/rock5b-rk3588/Makefile b/board/radxa/rock5b-rk3588/Makefile
new file mode 100644
index 0000000..95d8135
--- /dev/null
+++ b/board/radxa/rock5b-rk3588/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier:     GPL-2.0+
+#
+# Copyright (c) 2022 Collabora Ltd.
+#
+
+obj-y += rock5b-rk3588.o
diff --git a/board/radxa/rock5b-rk3588/rock5b-rk3588.c b/board/radxa/rock5b-rk3588/rock5b-rk3588.c
new file mode 100644
index 0000000..5c3b52b9
--- /dev/null
+++ b/board/radxa/rock5b-rk3588/rock5b-rk3588.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2023 Collabora Ltd.
+ */
+
+#include <fdtdec.h>
+#include <fdt_support.h>
+
+#ifdef CONFIG_OF_BOARD_SETUP
+int rock5b_add_reserved_memory_fdt_nodes(void *new_blob)
+{
+	struct fdt_memory gap1 = {
+		.start = 0x3fc000000,
+		.end = 0x3fc4fffff,
+	};
+	struct fdt_memory gap2 = {
+		.start = 0x3fff00000,
+		.end = 0x3ffffffff,
+	};
+	unsigned long flags = FDTDEC_RESERVED_MEMORY_NO_MAP;
+	unsigned int ret;
+
+	/*
+	 * Inject the reserved-memory nodes into the DTS
+	 */
+	ret = fdtdec_add_reserved_memory(new_blob, "gap1", &gap1,  NULL, 0,
+					 NULL, flags);
+	if (ret)
+		return ret;
+
+	return fdtdec_add_reserved_memory(new_blob, "gap2", &gap2,  NULL, 0,
+					  NULL, flags);
+}
+
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+	return rock5b_add_reserved_memory_fdt_nodes(blob);
+}
+#endif
diff --git a/board/rockchip/evb_rk3308/MAINTAINERS b/board/rockchip/evb_rk3308/MAINTAINERS
index 0af119a..fe2c5f0 100644
--- a/board/rockchip/evb_rk3308/MAINTAINERS
+++ b/board/rockchip/evb_rk3308/MAINTAINERS
@@ -4,3 +4,10 @@
 F:      board/rockchip/evb_rk3308
 F:      include/configs/evb_rk3308.h
 F:      configs/evb-rk3308_defconfig
+
+ROCK-PI-S
+M:      Akash Gajjar <gajjar04akash@gmail.com>
+S:      Maintained
+F:      configs/rock-pi-s-rk3308_defconfig
+F:      arch/arm/dts/rk3308-rock-pi-s.dts
+F:      arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi
diff --git a/board/rockchip/evb_rk3568/MAINTAINERS b/board/rockchip/evb_rk3568/MAINTAINERS
index b6ea498..6b2e7c7 100644
--- a/board/rockchip/evb_rk3568/MAINTAINERS
+++ b/board/rockchip/evb_rk3568/MAINTAINERS
@@ -4,3 +4,17 @@
 F:      board/rockchip/evb_rk3568
 F:      include/configs/evb_rk3568.h
 F:      configs/evb-rk3568_defconfig
+F:	arch/arm/dts/rk3568-evb-boot.dtsi
+F:	arch/arm/dts/rk3568-evb.dts
+
+RADXA-CM3
+M:	Jagan Teki <jagan@amarulasolutions.com>
+S:	Maintained
+F:	configs/radxa-cm3-io-rk3566_defconfig
+
+ROCK-3A
+M:      Akash Gajjar <gajjar04akash@gmail.com>
+S:      Maintained
+F:      configs/rock-3a-rk3568_defconfig
+F:      arch/arm/dts/rk3568-rock-3a.dts
+F:      arch/arm/dts/rk3568-rock-3a-u-boot.dtsi
diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c
index bf002f8..f709904 100644
--- a/cmd/bdinfo.c
+++ b/cmd/bdinfo.c
@@ -26,6 +26,11 @@
 	print_size(size, "\n");
 }
 
+void bdinfo_print_str(const char *name, const char *str)
+{
+	printf("%-12s= %s\n", name, str);
+}
+
 void bdinfo_print_num_l(const char *name, ulong value)
 {
 	printf("%-12s= 0x%0*lx\n", name, 2 * (int)sizeof(value), value);
@@ -83,11 +88,15 @@
 		       device_active(dev) ? "" : "in");
 		if (device_active(dev)) {
 			struct video_priv *upriv = dev_get_uclass_priv(dev);
+			struct video_uc_plat *plat = dev_get_uclass_plat(dev);
 
 			bdinfo_print_num_ll("FB base", (ulong)upriv->fb);
-			if (upriv->copy_fb)
+			if (upriv->copy_fb) {
 				bdinfo_print_num_ll("FB copy",
 						    (ulong)upriv->copy_fb);
+				bdinfo_print_num_l(" copy size",
+						   plat->copy_size);
+			}
 			printf("%-12s= %dx%dx%d\n", "FB size", upriv->xsize,
 			       upriv->ysize, 1 << upriv->bpix);
 		}
diff --git a/cmd/cls.c b/cmd/cls.c
index 40a32ee..1125a3f 100644
--- a/cmd/cls.c
+++ b/cmd/cls.c
@@ -8,7 +8,7 @@
 #include <common.h>
 #include <command.h>
 #include <dm.h>
-#include <video.h>
+#include <video_console.h>
 
 #define CSI "\x1b["
 
@@ -17,14 +17,24 @@
 {
 	__maybe_unused struct udevice *dev;
 
-	/*  Send clear screen and home */
+	/*
+	 * Send clear screen and home
+	 *
+	 * FIXME(Heinrich Schuchardt <xypron.glpk@gmx.de>): This should go
+	 * through an API and only be written to serial terminals, not video
+	 * displays
+	 */
 	printf(CSI "2J" CSI "1;1H");
-	if (IS_ENABLED(CONFIG_VIDEO) && !IS_ENABLED(CONFIG_VIDEO_ANSI)) {
-		if (uclass_first_device_err(UCLASS_VIDEO, &dev))
+	if (IS_ENABLED(CONFIG_VIDEO_ANSI))
+		return 0;
+
+	if (IS_ENABLED(CONFIG_VIDEO)) {
+		if (uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev))
 			return CMD_RET_FAILURE;
-		if (video_clear(dev))
+		if (vidconsole_clear_and_reset(dev))
 			return CMD_RET_FAILURE;
 	}
+
 	return CMD_RET_SUCCESS;
 }
 
diff --git a/cmd/fdt.c b/cmd/fdt.c
index f38fe90..04b664e 100644
--- a/cmd/fdt.c
+++ b/cmd/fdt.c
@@ -478,7 +478,7 @@
 					/* Get address */
 					char buf[19];
 
-					snprintf(buf, sizeof(buf), "0x%lx",
+					snprintf(buf, sizeof(buf), "%lx",
 						 (ulong)map_to_sysmem(nodep));
 					env_set(var, buf);
 				} else if (subcmd[0] == 's') {
diff --git a/common/Kconfig b/common/Kconfig
index 5c66fd9..7ff6255 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -1154,15 +1154,3 @@
 
 config IO_TRACE
 	bool
-
-config USB_HUB_DEBOUNCE_TIMEOUT
-	int "Timeout in milliseconds for USB HUB connection"
-	depends on USB
-	default 1000
-	help
-	  Value in milliseconds of the USB connection timeout, the max delay to
-	  wait the hub port status to be connected steadily after being powered
-	  off and powered on in the usb hub driver.
-	  This define allows to increase the HUB_DEBOUNCE_TIMEOUT default
-	  value = 1s because some usb device needs around 1.5s to be initialized
-	  and a 2s value should solve detection issue on problematic USB keys.
diff --git a/common/Makefile b/common/Makefile
index 252e965..a50302d 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -24,7 +24,7 @@
 obj-$(CONFIG_PHYLIB) += miiphyutil.o
 
 obj-$(CONFIG_USB_HOST) += usb.o usb_hub.o
-obj-$(CONFIG_USB_GADGET) += usb.o usb_hub.o
+obj-$(CONFIG_USB_GADGET) += usb.o
 obj-$(CONFIG_USB_STORAGE) += usb_storage.o
 obj-$(CONFIG_USB_ONBOARD_HUB) += usb_onboard_hub.o
 
diff --git a/common/console.c b/common/console.c
index e4301a4..71ad8ef 100644
--- a/common/console.c
+++ b/common/console.c
@@ -842,7 +842,7 @@
 		return -ENOSPC;
 
 	return membuff_readline((struct membuff *)&gd->console_out, str,
-				maxlen, ' ');
+				maxlen, '\0');
 }
 
 int console_record_avail(void)
diff --git a/common/main.c b/common/main.c
index 682f335..7c70de2 100644
--- a/common/main.c
+++ b/common/main.c
@@ -13,6 +13,7 @@
 #include <command.h>
 #include <console.h>
 #include <env.h>
+#include <fdtdec.h>
 #include <init.h>
 #include <net.h>
 #include <version_string.h>
diff --git a/configs/efi-x86_app64_defconfig b/configs/efi-x86_app64_defconfig
index 605d49f..dae4884 100644
--- a/configs/efi-x86_app64_defconfig
+++ b/configs/efi-x86_app64_defconfig
@@ -22,6 +22,7 @@
 # CONFIG_CMD_BOOTM is not set
 CONFIG_CMD_PART=y
 # CONFIG_CMD_NET is not set
+CONFIG_CMD_CACHE=y
 CONFIG_CMD_TIME=y
 CONFIG_CMD_EXT2=y
 CONFIG_CMD_EXT4=y
@@ -39,7 +40,9 @@
 CONFIG_USE_ROOTPATH=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
+CONFIG_CONSOLE_SCROLL_LINES=5
 # CONFIG_REGEX is not set
+CONFIG_CMD_DHRYSTONE=y
 # CONFIG_GZIP is not set
 CONFIG_EFI=y
 CONFIG_EFI_APP_64BIT=y
diff --git a/configs/evb-rk3568_defconfig b/configs/evb-rk3568_defconfig
index c7e0e5a..0f72925 100644
--- a/configs/evb-rk3568_defconfig
+++ b/configs/evb-rk3568_defconfig
@@ -65,5 +65,4 @@
 CONFIG_DEBUG_UART_SHIFT=2
 CONFIG_SYS_NS16550_MEM32=y
 CONFIG_SYSRESET=y
-# CONFIG_BINMAN_FDT is not set
 CONFIG_ERRNO_STR=y
diff --git a/configs/j7200_evm_a72_defconfig b/configs/j7200_evm_a72_defconfig
index e33b3f1..7490313 100644
--- a/configs/j7200_evm_a72_defconfig
+++ b/configs/j7200_evm_a72_defconfig
@@ -1,6 +1,5 @@
 CONFIG_ARM=y
 CONFIG_ARCH_K3=y
-CONFIG_TI_SECURE_DEVICE=y
 CONFIG_SYS_MALLOC_LEN=0x2000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SPL_GPIO=y
@@ -33,7 +32,7 @@
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000
 CONFIG_OF_BOARD_SETUP=y
-CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; if test ${boot_fit} -eq 1; then run get_fit_${boot}; run get_overlaystring; run run_fit; else; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern; fi;"
+CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern"
 CONFIG_LOGLEVEL=7
 CONFIG_SPL_MAX_SIZE=0xc0000
 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
diff --git a/configs/j7200_evm_r5_defconfig b/configs/j7200_evm_r5_defconfig
index 94a6523..00ec48b 100644
--- a/configs/j7200_evm_r5_defconfig
+++ b/configs/j7200_evm_r5_defconfig
@@ -1,6 +1,5 @@
 CONFIG_ARM=y
 CONFIG_ARCH_K3=y
-CONFIG_TI_SECURE_DEVICE=y
 CONFIG_SYS_MALLOC_LEN=0x2000000
 CONFIG_SYS_MALLOC_F_LEN=0x70000
 CONFIG_SPL_GPIO=y
@@ -28,6 +27,7 @@
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT_ADDRESS=0x80080000
+CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
 CONFIG_USE_BOOTCOMMAND=y
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_MAX_SIZE=0xc0000
diff --git a/configs/j7200_hs_evm_a72_defconfig b/configs/j7200_hs_evm_a72_defconfig
new file mode 100644
index 0000000..e4f3c46
--- /dev/null
+++ b/configs/j7200_hs_evm_a72_defconfig
@@ -0,0 +1,204 @@
+CONFIG_ARM=y
+CONFIG_ARCH_K3=y
+CONFIG_TI_SECURE_DEVICE=y
+CONFIG_SYS_MALLOC_LEN=0x2000000
+CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_SPL_GPIO=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_SOC_K3_J721E=y
+CONFIG_TARGET_J7200_A72_EVM=y
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80480000
+CONFIG_ENV_SIZE=0x20000
+CONFIG_ENV_OFFSET=0x680000
+CONFIG_DM_GPIO=y
+CONFIG_SPL_DM_SPI=y
+CONFIG_DEFAULT_DEVICE_TREE="k3-j7200-common-proc-board"
+CONFIG_SPL_TEXT_BASE=0x80080000
+CONFIG_DM_RESET=y
+CONFIG_SPL_MMC=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_DRIVERS_MISC=y
+CONFIG_SPL_STACK_R_ADDR=0x82000000
+CONFIG_ENV_OFFSET_REDUND=0x6A0000
+CONFIG_SPL_FS_FAT=y
+CONFIG_SPL_LIBDISK_SUPPORT=y
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI=y
+# CONFIG_PSCI_RESET is not set
+CONFIG_DISTRO_DEFAULTS=y
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_fit_${boot}; run get_overlaystring; run run_fit"
+CONFIG_LOGLEVEL=7
+CONFIG_SPL_MAX_SIZE=0xc0000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x80a00000
+CONFIG_SPL_BSS_MAX_SIZE=0x80000
+CONFIG_SPL_BOARD_INIT=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_STACK_R=y
+CONFIG_SYS_SPL_MALLOC=y
+CONFIG_SYS_SPL_MALLOC_SIZE=0x800000
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400
+CONFIG_SPL_DMA=y
+CONFIG_SPL_ENV_SUPPORT=y
+CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img"
+CONFIG_SPL_I2C=y
+CONFIG_SPL_DM_MAILBOX=y
+CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_DM_SPI_FLASH=y
+CONFIG_SPL_NOR_SUPPORT=y
+CONFIG_SPL_DM_RESET=y
+CONFIG_SPL_POWER_DOMAIN=y
+CONFIG_SPL_RAM_SUPPORT=y
+CONFIG_SPL_RAM_DEVICE=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000
+CONFIG_SPL_USB_GADGET=y
+CONFIG_SPL_DFU=y
+CONFIG_SPL_YMODEM_SUPPORT=y
+CONFIG_SYS_MAXARGS=64
+CONFIG_CMD_ASKENV=y
+CONFIG_CMD_DFU=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_REMOTEPROC=y
+CONFIG_CMD_UFS=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TIME=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0,nor0=47034000.hyperbus"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=47040000.spi.0:512k(ospi.tiboot3),2m(ospi.tispl),4m(ospi.u-boot),128k(ospi.env),128k(ospi.env.backup),1m(ospi.sysfw),-@8m(ospi.rootfs);47034000.hyperbus:512k(hbmc.tiboot3),2m(hbmc.tispl),4m(hbmc.u-boot),256k(hbmc.env),1m(hbmc.sysfw),-@8m(hbmc.rootfs)"
+CONFIG_CMD_UBI=y
+# CONFIG_ISO_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_SPL_MULTI_DTB_FIT=y
+CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_CLK_CCF=y
+CONFIG_CLK_TI_SCI=y
+CONFIG_DFU_MMC=y
+CONFIG_DFU_RAM=y
+CONFIG_DFU_SF=y
+CONFIG_SYS_DFU_DATA_BUF_SIZE=0x40000
+CONFIG_SYS_DFU_MAX_FILE_SIZE=0x800000
+CONFIG_DMA_CHANNELS=y
+CONFIG_TI_K3_NAVSS_UDMA=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x82000000
+CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
+CONFIG_TI_SCI_PROTOCOL=y
+CONFIG_DA8XX_GPIO=y
+CONFIG_DM_PCA953X=y
+CONFIG_DM_I2C=y
+CONFIG_DM_I2C_GPIO=y
+CONFIG_SYS_I2C_OMAP24XX=y
+CONFIG_DM_MAILBOX=y
+CONFIG_K3_SEC_PROXY=y
+CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
+CONFIG_SPL_MMC_HS400_SUPPORT=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ADMA=y
+CONFIG_SPL_MMC_SDHCI_ADMA=y
+CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_FLASH_SHOW_PROGRESS=0
+CONFIG_CFI_FLASH=y
+CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
+CONFIG_FLASH_CFI_MTD=y
+CONFIG_SYS_FLASH_CFI=y
+CONFIG_HBMC_AM654=y
+CONFIG_SYS_MAX_FLASH_BANKS_DETECT=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_STMICRO=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_MULTIPLEXER=y
+CONFIG_MUX_MMIO=y
+CONFIG_PHY_FIXED=y
+CONFIG_TI_AM65_CPSW_NUSS=y
+CONFIG_PHY=y
+CONFIG_SPL_PHY=y
+CONFIG_PHY_CADENCE_TORRENT=y
+CONFIG_PHY_J721E_WIZ=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_GENERIC is not set
+CONFIG_SPL_PINCTRL=y
+# CONFIG_SPL_PINCTRL_GENERIC is not set
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_TI_SCI_POWER_DOMAIN=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_RAM=y
+CONFIG_SPL_RAM=y
+CONFIG_REMOTEPROC_TI_K3_R5F=y
+CONFIG_RESET_TI_SCI=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
+CONFIG_DM_SERIAL=y
+CONFIG_SOC_DEVICE=y
+CONFIG_SOC_DEVICE_TI_K3=y
+CONFIG_SOC_TI=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CADENCE_QSPI=y
+CONFIG_HAS_CQSPI_REF_CLK=y
+CONFIG_CQSPI_REF_CLK=133333333
+CONFIG_SYSRESET=y
+CONFIG_SPL_SYSRESET=y
+CONFIG_SYSRESET_TI_SCI=y
+CONFIG_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_SPL_DM_USB_GADGET=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_CDNS3=y
+CONFIG_USB_CDNS3_GADGET=y
+CONFIG_USB_CDNS3_HOST=y
+CONFIG_SPL_USB_CDNS3_GADGET=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
+CONFIG_USB_GADGET_VENDOR_NUM=0x0451
+CONFIG_USB_GADGET_PRODUCT_NUM=0x6164
+CONFIG_UFS=y
+CONFIG_CADENCE_UFS=y
+CONFIG_TI_J721E_UFS=y
+CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/j7200_hs_evm_r5_defconfig b/configs/j7200_hs_evm_r5_defconfig
new file mode 100644
index 0000000..94a6523
--- /dev/null
+++ b/configs/j7200_hs_evm_r5_defconfig
@@ -0,0 +1,170 @@
+CONFIG_ARM=y
+CONFIG_ARCH_K3=y
+CONFIG_TI_SECURE_DEVICE=y
+CONFIG_SYS_MALLOC_LEN=0x2000000
+CONFIG_SYS_MALLOC_F_LEN=0x70000
+CONFIG_SPL_GPIO=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SOC_K3_J721E=y
+CONFIG_K3_EARLY_CONS=y
+CONFIG_TARGET_J7200_R5_EVM=y
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x41cf5bfc
+CONFIG_ENV_SIZE=0x20000
+CONFIG_DM_GPIO=y
+CONFIG_SPL_DM_SPI=y
+CONFIG_DEFAULT_DEVICE_TREE="k3-j7200-r5-common-proc-board"
+CONFIG_SPL_TEXT_BASE=0x41c00000
+CONFIG_DM_RESET=y
+CONFIG_SPL_MMC=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_DRIVERS_MISC=y
+CONFIG_SPL_STACK_R_ADDR=0x82000000
+CONFIG_SPL_FS_FAT=y
+CONFIG_SPL_LIBDISK_SUPPORT=y
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI=y
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_LOAD_FIT_ADDRESS=0x80080000
+CONFIG_USE_BOOTCOMMAND=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL_MAX_SIZE=0xc0000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x41cf5bfc
+CONFIG_SPL_BSS_MAX_SIZE=0xa000
+CONFIG_SPL_BOARD_INIT=y
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SYS_SPL_MALLOC=y
+CONFIG_HAS_CUSTOM_SPL_MALLOC_START=y
+CONFIG_CUSTOM_SYS_SPL_MALLOC_ADDR=0x84000000
+CONFIG_SYS_SPL_MALLOC_SIZE=0x1000000
+CONFIG_SPL_EARLY_BSS=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400
+CONFIG_SPL_DMA=y
+CONFIG_SPL_ENV_SUPPORT=y
+CONFIG_SPL_FS_EXT4=y
+CONFIG_SPL_I2C=y
+CONFIG_SPL_DM_MAILBOX=y
+CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_DM_SPI_FLASH=y
+CONFIG_SPL_NOR_SUPPORT=y
+CONFIG_SPL_DM_RESET=y
+CONFIG_SPL_POWER_DOMAIN=y
+CONFIG_SPL_RAM_SUPPORT=y
+CONFIG_SPL_RAM_DEVICE=y
+CONFIG_SPL_REMOTEPROC=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000
+CONFIG_SPL_USB_GADGET=y
+CONFIG_SPL_DFU=y
+CONFIG_SPL_YMODEM_SUPPORT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_MAXARGS=64
+CONFIG_SYS_BOOTM_LEN=0x4000000
+CONFIG_CMD_DFU=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_REMOTEPROC=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TIME=y
+CONFIG_CMD_FAT=y
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_SPL_CLK_CCF=y
+CONFIG_SPL_CLK_K3_PLL=y
+CONFIG_SPL_CLK_K3=y
+CONFIG_SYS_DFU_DATA_BUF_SIZE=0x40000
+CONFIG_DMA_CHANNELS=y
+CONFIG_TI_K3_NAVSS_UDMA=y
+CONFIG_TI_SCI_PROTOCOL=y
+CONFIG_DA8XX_GPIO=y
+CONFIG_DM_PCA953X=y
+CONFIG_DM_I2C=y
+CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
+CONFIG_SYS_I2C_OMAP24XX=y
+CONFIG_DM_MAILBOX=y
+CONFIG_K3_SEC_PROXY=y
+CONFIG_FS_LOADER=y
+CONFIG_SPL_FS_LOADER=y
+CONFIG_K3_AVS0=y
+CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_SPL_MMC_HS400_SUPPORT=y
+CONFIG_MMC_SDHCI=y
+CONFIG_SPL_MMC_SDHCI_ADMA=y
+CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_FLASH_SHOW_PROGRESS=0
+CONFIG_CFI_FLASH=y
+CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
+CONFIG_FLASH_CFI_MTD=y
+CONFIG_SYS_FLASH_CFI=y
+CONFIG_HBMC_AM654=y
+CONFIG_SYS_MAX_FLASH_BANKS_DETECT=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_GENERIC is not set
+CONFIG_SPL_PINCTRL=y
+# CONFIG_SPL_PINCTRL_GENERIC is not set
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_TI_SCI_POWER_DOMAIN=y
+CONFIG_TI_POWER_DOMAIN=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_TPS65941=y
+CONFIG_DM_REGULATOR=y
+CONFIG_SPL_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_TPS65941=y
+CONFIG_K3_SYSTEM_CONTROLLER=y
+CONFIG_REMOTEPROC_TI_K3_ARM64=y
+CONFIG_RESET_TI_SCI=y
+CONFIG_DM_SERIAL=y
+CONFIG_SOC_DEVICE=y
+CONFIG_SOC_DEVICE_TI_K3=y
+CONFIG_SOC_TI=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CADENCE_QSPI=y
+CONFIG_HAS_CQSPI_REF_CLK=y
+CONFIG_CQSPI_REF_CLK=133333333
+CONFIG_SYSRESET=y
+CONFIG_SPL_SYSRESET=y
+CONFIG_SYSRESET_TI_SCI=y
+CONFIG_TIMER=y
+CONFIG_SPL_TIMER=y
+CONFIG_OMAP_TIMER=y
+CONFIG_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_SPL_DM_USB_GADGET=y
+CONFIG_USB_CDNS3=y
+CONFIG_USB_CDNS3_GADGET=y
+CONFIG_SPL_USB_CDNS3_GADGET=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
+CONFIG_USB_GADGET_VENDOR_NUM=0x0451
+CONFIG_USB_GADGET_PRODUCT_NUM=0x6164
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_FS_EXT4=y
+CONFIG_FS_FAT_MAX_CLUSTSIZE=16384
+CONFIG_LIB_RATIONAL=y
+CONFIG_SPL_LIB_RATIONAL=y
diff --git a/configs/j721s2_evm_a72_defconfig b/configs/j721s2_evm_a72_defconfig
index 44f22d5..eae4c10 100644
--- a/configs/j721s2_evm_a72_defconfig
+++ b/configs/j721s2_evm_a72_defconfig
@@ -1,6 +1,5 @@
 CONFIG_ARM=y
 CONFIG_ARCH_K3=y
-CONFIG_TI_SECURE_DEVICE=y
 CONFIG_SYS_MALLOC_LEN=0x2000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SPL_GPIO=y
@@ -31,7 +30,7 @@
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000
 CONFIG_OF_BOARD_SETUP=y
-CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; if test ${boot_fit} -eq 1; then run get_fit_${boot}; run get_overlaystring; run run_fit; else; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern; fi;"
+CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern"
 CONFIG_LOGLEVEL=7
 CONFIG_SPL_MAX_SIZE=0xc0000
 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
diff --git a/configs/j721s2_evm_r5_defconfig b/configs/j721s2_evm_r5_defconfig
index 4ddbe8f..343e3c1 100644
--- a/configs/j721s2_evm_r5_defconfig
+++ b/configs/j721s2_evm_r5_defconfig
@@ -1,6 +1,5 @@
 CONFIG_ARM=y
 CONFIG_ARCH_K3=y
-CONFIG_TI_SECURE_DEVICE=y
 CONFIG_SYS_MALLOC_LEN=0x2000000
 CONFIG_SYS_MALLOC_F_LEN=0x10000
 CONFIG_SPL_GPIO=y
@@ -30,6 +29,7 @@
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT_ADDRESS=0x80080000
+CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
 CONFIG_USE_BOOTCOMMAND=y
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_SIZE_LIMIT_SUBTRACT_GD=y
diff --git a/configs/j721s2_hs_evm_a72_defconfig b/configs/j721s2_hs_evm_a72_defconfig
new file mode 100644
index 0000000..dff12ab
--- /dev/null
+++ b/configs/j721s2_hs_evm_a72_defconfig
@@ -0,0 +1,212 @@
+CONFIG_ARM=y
+CONFIG_ARCH_K3=y
+CONFIG_TI_SECURE_DEVICE=y
+CONFIG_SYS_MALLOC_LEN=0x2000000
+CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_SPL_GPIO=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_SOC_K3_J721S2=y
+CONFIG_TARGET_J721S2_A72_EVM=y
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80480000
+CONFIG_ENV_SIZE=0x20000
+CONFIG_ENV_OFFSET=0x680000
+CONFIG_DM_GPIO=y
+CONFIG_SPL_DM_SPI=y
+CONFIG_DEFAULT_DEVICE_TREE="k3-j721s2-common-proc-board"
+CONFIG_SPL_TEXT_BASE=0x80080000
+CONFIG_DM_RESET=y
+CONFIG_SPL_MMC=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_DRIVERS_MISC=y
+CONFIG_SPL_STACK_R_ADDR=0x82000000
+CONFIG_ENV_OFFSET_REDUND=0x6A0000
+CONFIG_SPL_FS_FAT=y
+CONFIG_SPL_LIBDISK_SUPPORT=y
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI=y
+# CONFIG_PSCI_RESET is not set
+CONFIG_DISTRO_DEFAULTS=y
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_fit_${boot}; run get_overlaystring; run run_fit"
+CONFIG_LOGLEVEL=7
+CONFIG_SPL_MAX_SIZE=0xc0000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x80a00000
+CONFIG_SPL_BSS_MAX_SIZE=0x80000
+CONFIG_SPL_BOARD_INIT=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_STACK_R=y
+CONFIG_SYS_SPL_MALLOC=y
+CONFIG_SYS_SPL_MALLOC_SIZE=0x800000
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400
+CONFIG_SPL_DMA=y
+CONFIG_SPL_ENV_SUPPORT=y
+CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img"
+CONFIG_SPL_I2C=y
+CONFIG_SPL_DM_MAILBOX=y
+CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_DM_SPI_FLASH=y
+CONFIG_SPL_NOR_SUPPORT=y
+CONFIG_SPL_DM_RESET=y
+CONFIG_SPL_POWER_DOMAIN=y
+CONFIG_SPL_RAM_SUPPORT=y
+CONFIG_SPL_RAM_DEVICE=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000
+CONFIG_SPL_THERMAL=y
+CONFIG_SPL_USB_GADGET=y
+CONFIG_SPL_DFU=y
+CONFIG_SPL_YMODEM_SUPPORT=y
+CONFIG_SYS_MAXARGS=64
+CONFIG_CMD_ASKENV=y
+CONFIG_CMD_DFU=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_REMOTEPROC=y
+CONFIG_CMD_UFS=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TIME=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0,nor0=47034000.hyperbus"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=47040000.spi.0:512k(ospi.tiboot3),2m(ospi.tispl),4m(ospi.u-boot),256k(ospi.env),256k(ospi.env.backup),57088k@8m(ospi.rootfs),256k(ospi.phypattern);47034000.hyperbus:512k(hbmc.tiboot3),2m(hbmc.tispl),4m(hbmc.u-boot),256k(hbmc.env),-@8m(hbmc.rootfs)"
+CONFIG_CMD_UBI=y
+# CONFIG_ISO_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_SPL_MULTI_DTB_FIT=y
+CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_CLK_CCF=y
+CONFIG_CLK_TI_SCI=y
+CONFIG_DFU_MMC=y
+CONFIG_DFU_RAM=y
+CONFIG_DFU_SF=y
+CONFIG_SYS_DFU_DATA_BUF_SIZE=0x40000
+CONFIG_SYS_DFU_MAX_FILE_SIZE=0x800000
+CONFIG_DMA_CHANNELS=y
+CONFIG_TI_K3_NAVSS_UDMA=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x82000000
+CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
+CONFIG_TI_SCI_PROTOCOL=y
+CONFIG_DA8XX_GPIO=y
+CONFIG_DM_PCA953X=y
+CONFIG_DM_I2C=y
+CONFIG_DM_I2C_GPIO=y
+CONFIG_SYS_I2C_OMAP24XX=y
+CONFIG_DM_MAILBOX=y
+CONFIG_K3_SEC_PROXY=y
+CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
+CONFIG_SPL_MMC_HS400_SUPPORT=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ADMA=y
+CONFIG_SPL_MMC_SDHCI_ADMA=y
+CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_FLASH_SHOW_PROGRESS=0
+CONFIG_CFI_FLASH=y
+CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
+CONFIG_FLASH_CFI_MTD=y
+CONFIG_SYS_FLASH_CFI=y
+CONFIG_SYS_MAX_FLASH_BANKS_DETECT=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_SOFT_RESET=y
+CONFIG_SPI_FLASH_SOFT_RESET_ON_BOOT=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_MT35XU=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_MULTIPLEXER=y
+CONFIG_MUX_MMIO=y
+CONFIG_PHY_TI_DP83867=y
+CONFIG_PHY_FIXED=y
+CONFIG_TI_AM65_CPSW_NUSS=y
+CONFIG_PHY=y
+CONFIG_SPL_PHY=y
+CONFIG_PHY_CADENCE_TORRENT=y
+CONFIG_PHY_J721E_WIZ=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_GENERIC is not set
+CONFIG_SPL_PINCTRL=y
+# CONFIG_SPL_PINCTRL_GENERIC is not set
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_TI_SCI_POWER_DOMAIN=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_RAM=y
+CONFIG_SPL_RAM=y
+CONFIG_REMOTEPROC_TI_K3_DSP=y
+CONFIG_REMOTEPROC_TI_K3_R5F=y
+CONFIG_RESET_TI_SCI=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
+CONFIG_DM_SERIAL=y
+CONFIG_SOC_DEVICE=y
+CONFIG_SOC_DEVICE_TI_K3=y
+CONFIG_SOC_TI=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CADENCE_QSPI=y
+CONFIG_HAS_CQSPI_REF_CLK=y
+CONFIG_CQSPI_REF_CLK=133333333
+CONFIG_SYSRESET=y
+CONFIG_SPL_SYSRESET=y
+CONFIG_SYSRESET_TI_SCI=y
+CONFIG_DM_THERMAL=y
+CONFIG_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_SPL_DM_USB_GADGET=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_CDNS3=y
+CONFIG_USB_CDNS3_GADGET=y
+CONFIG_USB_CDNS3_HOST=y
+CONFIG_SPL_USB_CDNS3_GADGET=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
+CONFIG_USB_GADGET_VENDOR_NUM=0x0451
+CONFIG_USB_GADGET_PRODUCT_NUM=0x6168
+CONFIG_UFS=y
+CONFIG_CADENCE_UFS=y
+CONFIG_TI_J721E_UFS=y
+CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/j721s2_hs_evm_r5_defconfig b/configs/j721s2_hs_evm_r5_defconfig
new file mode 100644
index 0000000..c8433a1
--- /dev/null
+++ b/configs/j721s2_hs_evm_r5_defconfig
@@ -0,0 +1,175 @@
+CONFIG_ARM=y
+CONFIG_ARCH_K3=y
+CONFIG_TI_SECURE_DEVICE=y
+CONFIG_SYS_MALLOC_LEN=0x2000000
+CONFIG_SYS_MALLOC_F_LEN=0x10000
+CONFIG_SPL_GPIO=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SOC_K3_J721S2=y
+CONFIG_K3_EARLY_CONS=y
+CONFIG_TARGET_J721S2_R5_EVM=y
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x41c76000
+CONFIG_ENV_SIZE=0x20000
+CONFIG_DM_GPIO=y
+CONFIG_SPL_DM_SPI=y
+CONFIG_DEFAULT_DEVICE_TREE="k3-j721s2-r5-common-proc-board"
+CONFIG_SPL_TEXT_BASE=0x41c00000
+CONFIG_DM_RESET=y
+CONFIG_SPL_MMC=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_DRIVERS_MISC=y
+CONFIG_SPL_STACK_R_ADDR=0x82000000
+CONFIG_SPL_SIZE_LIMIT=0x80000
+CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK=0x4000
+CONFIG_SPL_FS_FAT=y
+CONFIG_SPL_LIBDISK_SUPPORT=y
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI=y
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_LOAD_FIT_ADDRESS=0x80080000
+CONFIG_USE_BOOTCOMMAND=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL_SIZE_LIMIT_SUBTRACT_GD=y
+CONFIG_SPL_SIZE_LIMIT_SUBTRACT_MALLOC=y
+CONFIG_SPL_MAX_SIZE=0xc0000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x41c76000
+CONFIG_SPL_BSS_MAX_SIZE=0xa000
+CONFIG_SPL_SYS_REPORT_STACK_F_USAGE=y
+CONFIG_SPL_BOARD_INIT=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SYS_SPL_MALLOC=y
+CONFIG_HAS_CUSTOM_SPL_MALLOC_START=y
+CONFIG_CUSTOM_SYS_SPL_MALLOC_ADDR=0x84000000
+CONFIG_SYS_SPL_MALLOC_SIZE=0x1000000
+CONFIG_SPL_EARLY_BSS=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400
+CONFIG_SPL_DMA=y
+CONFIG_SPL_ENV_SUPPORT=y
+CONFIG_SPL_FS_EXT4=y
+CONFIG_SPL_I2C=y
+CONFIG_SPL_DM_MAILBOX=y
+CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_DM_SPI_FLASH=y
+CONFIG_SPL_NOR_SUPPORT=y
+CONFIG_SPL_DM_RESET=y
+CONFIG_SPL_POWER_DOMAIN=y
+CONFIG_SPL_RAM_SUPPORT=y
+CONFIG_SPL_RAM_DEVICE=y
+CONFIG_SPL_REMOTEPROC=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000
+CONFIG_SPL_THERMAL=y
+CONFIG_SPL_USB_GADGET=y
+CONFIG_SPL_DFU=y
+CONFIG_SPL_YMODEM_SUPPORT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_MAXARGS=64
+CONFIG_SYS_BOOTM_LEN=0x4000000
+CONFIG_CMD_DFU=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_REMOTEPROC=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TIME=y
+CONFIG_CMD_FAT=y
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_SPL_CLK_CCF=y
+CONFIG_SPL_CLK_K3_PLL=y
+CONFIG_SPL_CLK_K3=y
+CONFIG_SYS_DFU_DATA_BUF_SIZE=0x40000
+CONFIG_DMA_CHANNELS=y
+CONFIG_TI_K3_NAVSS_UDMA=y
+CONFIG_TI_SCI_PROTOCOL=y
+CONFIG_DA8XX_GPIO=y
+CONFIG_DM_PCA953X=y
+CONFIG_DM_I2C=y
+CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
+CONFIG_SYS_I2C_OMAP24XX=y
+CONFIG_DM_MAILBOX=y
+CONFIG_K3_SEC_PROXY=y
+CONFIG_FS_LOADER=y
+CONFIG_SPL_FS_LOADER=y
+CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_SPL_MMC_HS400_SUPPORT=y
+CONFIG_MMC_SDHCI=y
+CONFIG_SPL_MMC_SDHCI_ADMA=y
+CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_FLASH_SHOW_PROGRESS=0
+CONFIG_CFI_FLASH=y
+CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
+CONFIG_FLASH_CFI_MTD=y
+CONFIG_SYS_FLASH_CFI=y
+CONFIG_SYS_MAX_FLASH_BANKS_DETECT=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_SOFT_RESET=y
+CONFIG_SPI_FLASH_SOFT_RESET_ON_BOOT=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_MT35XU=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_GENERIC is not set
+CONFIG_SPL_PINCTRL=y
+# CONFIG_SPL_PINCTRL_GENERIC is not set
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_TI_POWER_DOMAIN=y
+CONFIG_K3_SYSTEM_CONTROLLER=y
+CONFIG_REMOTEPROC_TI_K3_ARM64=y
+CONFIG_RESET_TI_SCI=y
+CONFIG_DM_SERIAL=y
+CONFIG_SOC_DEVICE=y
+CONFIG_SOC_DEVICE_TI_K3=y
+CONFIG_SOC_TI=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CADENCE_QSPI=y
+CONFIG_HAS_CQSPI_REF_CLK=y
+CONFIG_CQSPI_REF_CLK=133333333
+CONFIG_SYSRESET=y
+CONFIG_SPL_SYSRESET=y
+CONFIG_SYSRESET_TI_SCI=y
+CONFIG_DM_THERMAL=y
+CONFIG_TIMER=y
+CONFIG_SPL_TIMER=y
+CONFIG_OMAP_TIMER=y
+CONFIG_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_SPL_DM_USB_GADGET=y
+CONFIG_USB_CDNS3=y
+CONFIG_USB_CDNS3_GADGET=y
+CONFIG_SPL_USB_CDNS3_GADGET=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
+CONFIG_USB_GADGET_VENDOR_NUM=0x0451
+CONFIG_USB_GADGET_PRODUCT_NUM=0x6168
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_FS_EXT4=y
+CONFIG_FS_FAT_MAX_CLUSTSIZE=16384
+CONFIG_PANIC_HANG=y
+CONFIG_LIB_RATIONAL=y
+CONFIG_SPL_LIB_RATIONAL=y
diff --git a/configs/n2350_defconfig b/configs/n2350_defconfig
index dcb2c96..b85ef0d 100644
--- a/configs/n2350_defconfig
+++ b/configs/n2350_defconfig
@@ -14,7 +14,7 @@
 CONFIG_TARGET_N2350=y
 CONFIG_ENV_SIZE=0x10000
 CONFIG_ENV_OFFSET=0x100000
-CONFIG_ENV_SECT_SIZE=0x10000
+CONFIG_ENV_SECT_SIZE=0x1000
 CONFIG_DEFAULT_DEVICE_TREE="armada-385-thecus-n2350"
 CONFIG_SPL_TEXT_BASE=0x40000030
 CONFIG_SYS_PROMPT="N2350 > "
diff --git a/configs/nanopi-r4s-rk3399_defconfig b/configs/nanopi-r4s-rk3399_defconfig
index 6d2a147..4946e89 100644
--- a/configs/nanopi-r4s-rk3399_defconfig
+++ b/configs/nanopi-r4s-rk3399_defconfig
@@ -72,3 +72,9 @@
 CONFIG_DISPLAY_ROCKCHIP_HDMI=y
 CONFIG_SPL_TINY_MEMSET=y
 CONFIG_ERRNO_STR=y
+CONFIG_MISC=y
+CONFIG_MISC_INIT_R=y
+CONFIG_ROCKCHIP_EFUSE=y
+CONFIG_ROCKCHIP_OTP=y
+CONFIG_SYSINFO=y
+CONFIG_SYSINFO_SMBIOS=y
diff --git a/configs/neu6a-io-rk3588_defconfig b/configs/neu6a-io-rk3588_defconfig
new file mode 100644
index 0000000..fb5a2b7
--- /dev/null
+++ b/configs/neu6a-io-rk3588_defconfig
@@ -0,0 +1,67 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_TEXT_BASE=0x00a00000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc00000
+CONFIG_DEFAULT_DEVICE_TREE="rk3588-edgeble-neu6a-io"
+CONFIG_ROCKCHIP_RK3588=y
+CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
+CONFIG_SPL_MMC=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_STACK_R_ADDR=0x600000
+CONFIG_TARGET_RK3588_NEU6=y
+CONFIG_SPL_STACK=0x400000
+CONFIG_DEBUG_UART_BASE=0xFEB50000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_SYS_LOAD_ADDR=0xc00800
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588-edgeble-neu6a-io.dtb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_MAX_SIZE=0x20000
+CONFIG_SPL_PAD_TO=0x7f8000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x4000000
+CONFIG_SPL_BSS_MAX_SIZE=0x4000
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_ATF=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SPL_SYSCON=y
+CONFIG_SPL_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_SUPPORT_EMMC_RPMB=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_SPL_RAM=y
+CONFIG_DM_RESET=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYSRESET=y
+# CONFIG_BINMAN_FDT is not set
+CONFIG_ERRNO_STR=y
diff --git a/configs/pm9g45_defconfig b/configs/pm9g45_defconfig
index e7b4d96..0afdd0a 100644
--- a/configs/pm9g45_defconfig
+++ b/configs/pm9g45_defconfig
@@ -14,15 +14,15 @@
 CONFIG_DEBUG_UART_BASE=0xffffee00
 CONFIG_DEBUG_UART_CLOCK=132000000
 CONFIG_ENV_OFFSET_REDUND=0x100000
-CONFIG_SYS_LOAD_ADDR=0x22000000
+CONFIG_SYS_LOAD_ADDR=0x70000000
 CONFIG_DEBUG_UART=y
 CONFIG_SYS_MONITOR_LEN=524288
 CONFIG_NAND_BOOT=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS="fbcon=rotate:3 console=tty0 console=ttyS0,115200 root=/dev/mtdblock4 mtdparts=atmel_nand:128k(bootstrap)ro,256k(uboot)ro,1664k(env),2M(linux)ro,-(root) rw rootfstype=jffs2"
+CONFIG_BOOTARGS="console=ttyS0,115200 mtdparts=atmel_nand:128k(bootstrap)ro,640k(uboot)ro,256k(env),256k(env_redundant),256k(spare),512k(dtb),8M(kernel)ro,-(rootfs) root=/dev/mtdblock7 rw rootfstype=jffs2"
 CONFIG_USE_BOOTCOMMAND=y
-CONFIG_BOOTCOMMAND="nand read 0x70000000 0x200000 0x300000;bootm 0x70000000"
+CONFIG_BOOTCOMMAND="nand read 0x70000000 0x180000 0x880000; nand read 0x70080000 0x200000 0x800000; bootz 0x70080000 - 0x70000000"
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_RESET_PHY_R=y
@@ -53,7 +53,6 @@
 CONFIG_AT91_GPIO=y
 CONFIG_GENERIC_ATMEL_MCI=y
 CONFIG_MTD=y
-CONFIG_SYS_NAND_DRIVER_ECC_LAYOUT=y
 # CONFIG_SYS_NAND_USE_FLASH_BBT is not set
 CONFIG_NAND_ATMEL=y
 CONFIG_MACB=y
diff --git a/configs/r8a77980_condor_defconfig b/configs/r8a77980_condor_defconfig
index 0c3493c..e1b3dc5 100644
--- a/configs/r8a77980_condor_defconfig
+++ b/configs/r8a77980_condor_defconfig
@@ -33,6 +33,7 @@
 CONFIG_SYS_MAXARGS=64
 CONFIG_SYS_PBSIZE=2068
 CONFIG_CMD_BOOTZ=y
+CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=10
 CONFIG_CMD_DFU=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
@@ -64,6 +65,9 @@
 CONFIG_RCAR_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_RCAR_I2C=y
+CONFIG_MISC=y
+CONFIG_I2C_EEPROM=y
+CONFIG_SYS_I2C_EEPROM_ADDR=0x50
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS200_SUPPORT=y
@@ -84,6 +88,7 @@
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
 CONFIG_RENESAS_RPC_SPI=y
+CONFIG_SYSINFO=y
 CONFIG_TEE=y
 CONFIG_OPTEE=y
 CONFIG_USB=y
diff --git a/configs/r8a77995_draak_defconfig b/configs/r8a77995_draak_defconfig
index 4ddb66a..a09b33e 100644
--- a/configs/r8a77995_draak_defconfig
+++ b/configs/r8a77995_draak_defconfig
@@ -33,6 +33,7 @@
 CONFIG_SYS_MAXARGS=64
 CONFIG_SYS_PBSIZE=2068
 CONFIG_CMD_BOOTZ=y
+CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=10
 CONFIG_CMD_DFU=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
@@ -65,6 +66,9 @@
 CONFIG_RCAR_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_RCAR_I2C=y
+CONFIG_MISC=y
+CONFIG_I2C_EEPROM=y
+CONFIG_SYS_I2C_EEPROM_ADDR=0x50
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS200_SUPPORT=y
@@ -94,6 +98,7 @@
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
 CONFIG_RENESAS_RPC_SPI=y
+CONFIG_SYSINFO=y
 CONFIG_TEE=y
 CONFIG_OPTEE=y
 CONFIG_USB=y
diff --git a/configs/radxa-cm3-io-rk3566_defconfig b/configs/radxa-cm3-io-rk3566_defconfig
new file mode 100644
index 0000000..2100cf2
--- /dev/null
+++ b/configs/radxa-cm3-io-rk3566_defconfig
@@ -0,0 +1,77 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_TEXT_BASE=0x00a00000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc00000
+CONFIG_DEFAULT_DEVICE_TREE="rk3566-radxa-cm3-io"
+CONFIG_ROCKCHIP_RK3568=y
+CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y
+CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
+CONFIG_SPL_MMC=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_STACK_R_ADDR=0x600000
+CONFIG_TARGET_EVB_RK3568=y
+CONFIG_SPL_STACK=0x400000
+CONFIG_DEBUG_UART_BASE=0xFE660000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_SYS_LOAD_ADDR=0xc00800
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3566-radxa-cm3-io.dtb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_MAX_SIZE=0x20000
+CONFIG_SPL_PAD_TO=0x7f8000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x4000000
+CONFIG_SPL_BSS_MAX_SIZE=0x4000
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_ATF=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SPL_SYSCON=y
+CONFIG_SPL_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_SUPPORT_EMMC_RPMB=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PHY_ROCKCHIP_INNO_USB2=y
+CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_SPL_RAM=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
+CONFIG_ERRNO_STR=y
diff --git a/configs/ringneck-px30_defconfig b/configs/ringneck-px30_defconfig
index 34aee4e..91706d8 100644
--- a/configs/ringneck-px30_defconfig
+++ b/configs/ringneck-px30_defconfig
@@ -107,6 +107,7 @@
 CONFIG_SPL_RAM=y
 CONFIG_TPL_RAM=y
 CONFIG_ROCKCHIP_SDRAM_COMMON=y
+CONFIG_RAM_ROCKCHIP_DDR4=y
 CONFIG_DM_RNG=y
 CONFIG_RNG_ROCKCHIP=y
 # CONFIG_SPECIFY_CONSOLE_INDEX is not set
diff --git a/configs/rock-3a-rk3568_defconfig b/configs/rock-3a-rk3568_defconfig
new file mode 100644
index 0000000..1686c8c
--- /dev/null
+++ b/configs/rock-3a-rk3568_defconfig
@@ -0,0 +1,74 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_TEXT_BASE=0x00a00000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_DEFAULT_DEVICE_TREE="rk3568-rock-3a"
+CONFIG_ROCKCHIP_RK3568=y
+CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y
+CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
+CONFIG_SPL_MMC=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_STACK_R_ADDR=0x600000
+CONFIG_TARGET_EVB_RK3568=y
+CONFIG_DEBUG_UART_BASE=0xFE660000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_SYS_LOAD_ADDR=0xc00800
+CONFIG_DEBUG_UART=y
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc00000
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3568-rock-3a.dtb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_MAX_SIZE=0x20000
+CONFIG_SPL_PAD_TO=0x7f8000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x4000000
+CONFIG_SPL_BSS_MAX_SIZE=0x4000
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_RK8XX=y
+CONFIG_SPL_PMIC_RK8XX=y
+CONFIG_SPL_STACK=0x400000
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_ATF=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGULATOR_RK8XX=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SPL_SYSCON=y
+CONFIG_SPL_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_SUPPORT_EMMC_RPMB=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_SPL_RAM=y
+CONFIG_DM_RESET=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550_MEM32=y
+CONFIG_SYSRESET=y
+# CONFIG_BINMAN_FDT is not set
+CONFIG_ERRNO_STR=y
diff --git a/configs/rock-pi-s-rk3308_defconfig b/configs/rock-pi-s-rk3308_defconfig
new file mode 100644
index 0000000..6c86338
--- /dev/null
+++ b/configs/rock-pi-s-rk3308_defconfig
@@ -0,0 +1,89 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_TEXT_BASE=0x00600000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3308-rock-pi-s"
+CONFIG_ROCKCHIP_RK3308=y
+CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x0
+CONFIG_SPL_DRIVERS_MISC=y
+CONFIG_TARGET_EVB_RK3308=y
+CONFIG_SPL_STACK_R_ADDR=0xc00000
+CONFIG_DEBUG_UART_BASE=0xFF0A0000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_SYS_LOAD_ADDR=0xc00800
+CONFIG_DEBUG_UART=y
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x800000
+CONFIG_ANDROID_BOOT_IMAGE=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_BOOTDELAY=0
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL_MAX_SIZE=0x20000
+CONFIG_SPL_PAD_TO=0x7f8000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x400000
+CONFIG_SPL_BSS_MAX_SIZE=0x2000
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_STACK=0x400000
+CONFIG_SPL_STACK_R=y
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+CONFIG_CMD_GPT=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+# CONFIG_CMD_ITEST is not set
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_SLEEP is not set
+# CONFIG_DOS_PARTITION is not set
+# CONFIG_ISO_PARTITION is not set
+CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+# CONFIG_USB_FUNCTION_FASTBOOT is not set
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_SUPPORT_EMMC_RPMB=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PHY=y
+CONFIG_PINCTRL=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_RAM=y
+CONFIG_DM_RESET=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_SYS_NS16550_MEM32=y
+CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DWC2_OTG=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_SPL_TINY_MEMSET=y
+CONFIG_LZO=y
+CONFIG_ERRNO_STR=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/rock5b-rk3588_defconfig b/configs/rock5b-rk3588_defconfig
new file mode 100644
index 0000000..f3026c7
--- /dev/null
+++ b/configs/rock5b-rk3588_defconfig
@@ -0,0 +1,72 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_TEXT_BASE=0x00a00000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc00000
+CONFIG_DEFAULT_DEVICE_TREE="rk3588-rock-5b"
+CONFIG_DM_RESET=y
+CONFIG_ROCKCHIP_RK3588=y
+CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y
+CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
+CONFIG_SPL_MMC=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_STACK_R_ADDR=0x600000
+CONFIG_TARGET_ROCK5B_RK3588=y
+CONFIG_SPL_STACK=0x400000
+CONFIG_DEBUG_UART_BASE=0xFEB50000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_SYS_LOAD_ADDR=0xc00800
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_FIT_SIGNATURE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588-rock-5b.dtb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_MAX_SIZE=0x20000
+CONFIG_SPL_PAD_TO=0x7f8000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x4000000
+CONFIG_SPL_BSS_MAX_SIZE=0x4000
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_ATF=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SPL_SYSCON=y
+CONFIG_SPL_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_SUPPORT_EMMC_RPMB=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_SPL_RAM=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_SYSRESET=y
+# CONFIG_BINMAN_FDT is not set
+CONFIG_ERRNO_STR=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index 4e0021a..851c3b6 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -33,6 +33,7 @@
 CONFIG_HANDOFF=y
 CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_ENV_SUPPORT=y
+CONFIG_SPL_FPGA=y
 CONFIG_SPL_I2C=y
 CONFIG_SPL_RTC=y
 CONFIG_CMD_CPU=y
@@ -126,6 +127,8 @@
 CONFIG_DM_DEMO_SIMPLE=y
 CONFIG_DM_DEMO_SHAPE=y
 CONFIG_SPL_FIRMWARE=y
+CONFIG_DM_FPGA=y
+CONFIG_SANDBOX_FPGA=y
 CONFIG_GPIO_HOG=y
 CONFIG_QCOM_PMIC_GPIO=y
 CONFIG_SANDBOX_GPIO=y
@@ -237,6 +240,7 @@
 CONFIG_CMD_DHRYSTONE=y
 CONFIG_RSA_VERIFY_WITH_PKEY=y
 CONFIG_TPM=y
+CONFIG_SPL_CRC8=y
 CONFIG_LZ4=y
 CONFIG_ZSTD=y
 CONFIG_ERRNO_STR=y
diff --git a/doc/board/rockchip/rockchip.rst b/doc/board/rockchip/rockchip.rst
index 28c837a..b5563b8 100644
--- a/doc/board/rockchip/rockchip.rst
+++ b/doc/board/rockchip/rockchip.rst
@@ -86,6 +86,14 @@
      - Radxa ROCK Pi 4 (rock-pi-4-rk3399)
      - Rockchip Evb-RK3399 (evb_rk3399)
      - Theobroma Systems RK3399-Q7 SoM - Puma (puma_rk3399)
+
+* rk3568
+     - Rockchip Evb-RK3568 (evb-rk3568)
+
+* rk3588
+     - Edgeble Neural Compute Module 6 SoM - Neu6a (neu6a-io-rk3588)
+     - Radxa ROCK 5B (rock5b-rk3588)
+
 * rv1108
      - Rockchip Evb-rv1108 (evb-rv1108)
      - Elgin-R1 (elgin-rv1108)
@@ -167,6 +175,16 @@
         make evb-rk3399_defconfig
         make CROSS_COMPILE=aarch64-linux-gnu-
 
+To build rk3568 boards:
+
+.. code-block:: bash
+
+        export BL31=../arm-trusted-firmware/build/rk3568/release/bl31/bl31.elf
+        [or]export BL31=../rkbin/bin/rk35/rk3568_bl31_v1.34.elf
+        export ROCKCHIP_TPL=../rkbin/bin/rk35/rk3568_ddr_1560MHz_v1.13.bin
+        make evb-rk3568_defconfig
+        make CROSS_COMPILE=aarch64-linux-gnu-
+
 Flashing
 --------
 
diff --git a/doc/develop/release_cycle.rst b/doc/develop/release_cycle.rst
index 80b50be..7634e3d 100644
--- a/doc/develop/release_cycle.rst
+++ b/doc/develop/release_cycle.rst
@@ -70,7 +70,7 @@
 
 * U-Boot v2023.04-rc3 was released on Mon 27 February 2023.
 
-.. * U-Boot v2023.04-rc4 was released on Mon 13 March 2023.
+* U-Boot v2023.04-rc4 was released on Mon 13 March 2023.
 
 .. * U-Boot v2023.04-rc5 was released on Mon 27 March 2023.
 
diff --git a/doc/develop/uefi/fwu_updates.rst b/doc/develop/uefi/fwu_updates.rst
index 72c850a..e4709d8 100644
--- a/doc/develop/uefi/fwu_updates.rst
+++ b/doc/develop/uefi/fwu_updates.rst
@@ -27,7 +27,8 @@
 media, and its partitioning method. Details of the storage device
 containing the FWU metadata partitions are specified through a U-Boot
 specific device tree property `fwu-mdata-store`. Please refer to
-U-Boot `doc <doc/device-tree-bindings/firmware/fwu-mdata-gpt.yaml>`__
+U-Boot :download:`fwu-mdata-gpt.yaml
+</device-tree-bindings/firmware/fwu-mdata-gpt.yaml>`
 for the device tree bindings.
 
 Enabling the FWU Multi Bank Update feature
diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst
index a944c0f..ffe25ca 100644
--- a/doc/develop/uefi/uefi.rst
+++ b/doc/develop/uefi/uefi.rst
@@ -386,8 +386,8 @@
 updatable images, and the actual dfu alt number to which the image is
 to be written to is determined at runtime, based on the value of the
 update bank to which the image is to be written. For more information
-on the FWU Multi Bank Update feature, please refer `doc
-<doc/develop/uefi/fwu_updates.rst>`__.
+on the FWU Multi Bank Update feature, please refer to
+:doc:`/develop/uefi/fwu_updates`.
 
 When using the FMP for FIT images, the image index value needs to be
 set to 1.
diff --git a/doc/usage/cmd/panic.rst b/doc/usage/cmd/panic.rst
new file mode 100644
index 0000000..115eba5
--- /dev/null
+++ b/doc/usage/cmd/panic.rst
@@ -0,0 +1,33 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+panic command
+=============
+
+Synopis
+-------
+
+::
+
+    panic [message]
+
+Description
+-----------
+
+Display a message and reset the board.
+
+message
+    text to be displayed
+
+Examples
+--------
+
+::
+
+    => panic 'Unrecoverable error'
+    Unrecoverable error
+    resetting ...
+
+Configuration
+-------------
+
+If CONFIG_PANIC_HANG=y, the user has to reset the board manually.
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 840c20c..ebf5eea 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -65,6 +65,7 @@
    cmd/md
    cmd/mmc
    cmd/mtest
+   cmd/panic
    cmd/part
    cmd/pause
    cmd/pinmux
diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index 1686410..d58e897 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -49,6 +49,7 @@
 	def_bool y if RCAR_GEN3
 	depends on CLK_RENESAS
 	select CLK_RCAR_CPG_LIB
+	select DM_RESET
 	help
 	  Enable this to support the clocks on Renesas RCar Gen3 SoC.
 
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index f719f4e..9e379cc 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -16,5 +16,6 @@
 obj-$(CONFIG_ROCKCHIP_RK3368) += clk_rk3368.o
 obj-$(CONFIG_ROCKCHIP_RK3399) += clk_rk3399.o
 obj-$(CONFIG_ROCKCHIP_RK3568) += clk_rk3568.o
+obj-$(CONFIG_ROCKCHIP_RK3588) += clk_rk3588.o
 obj-$(CONFIG_ROCKCHIP_RV1108) += clk_rv1108.o
 obj-$(CONFIG_ROCKCHIP_RV1126) += clk_rv1126.o
diff --git a/drivers/clk/rockchip/clk_pll.c b/drivers/clk/rockchip/clk_pll.c
index 09b97cf..d657ef3 100644
--- a/drivers/clk/rockchip/clk_pll.c
+++ b/drivers/clk/rockchip/clk_pll.c
@@ -45,6 +45,10 @@
 
 #define MIN_FOUTVCO_FREQ	(800 * MHZ)
 #define MAX_FOUTVCO_FREQ	(2000 * MHZ)
+#define RK3588_VCO_MIN_HZ	(2250UL * MHZ)
+#define RK3588_VCO_MAX_HZ	(4500UL * MHZ)
+#define RK3588_FOUT_MIN_HZ	(37UL * MHZ)
+#define RK3588_FOUT_MAX_HZ	(4500UL * MHZ)
 
 int gcd(int m, int n)
 {
@@ -164,6 +168,65 @@
 	return rate_table;
 }
 
+static struct rockchip_pll_rate_table *
+rk3588_pll_clk_set_by_auto(unsigned long fin_hz,
+			   unsigned long fout_hz)
+{
+	struct rockchip_pll_rate_table *rate_table = &rockchip_auto_table;
+	u32 p, m, s;
+	ulong fvco, fref, fout, ffrac;
+
+	if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
+		return NULL;
+
+	if (fout_hz > RK3588_FOUT_MAX_HZ || fout_hz < RK3588_FOUT_MIN_HZ)
+		return NULL;
+
+	if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz) {
+		for (s = 0; s <= 6; s++) {
+			fvco = fout_hz << s;
+			if (fvco < RK3588_VCO_MIN_HZ ||
+			    fvco > RK3588_VCO_MAX_HZ)
+				continue;
+			for (p = 2; p <= 4; p++) {
+				for (m = 64; m <= 1023; m++) {
+					if (fvco == m * fin_hz / p) {
+						rate_table->p = p;
+						rate_table->m = m;
+						rate_table->s = s;
+						rate_table->k = 0;
+						return rate_table;
+					}
+				}
+			}
+		}
+		pr_err("CANNOT FIND Fout by auto,fout = %lu\n", fout_hz);
+	} else {
+		for (s = 0; s <= 6; s++) {
+			fvco = fout_hz << s;
+			if (fvco < RK3588_VCO_MIN_HZ ||
+			    fvco > RK3588_VCO_MAX_HZ)
+				continue;
+			for (p = 1; p <= 4; p++) {
+				for (m = 64; m <= 1023; m++) {
+					if ((fvco >= m * fin_hz / p) && (fvco < (m + 1) * fin_hz / p)) {
+						rate_table->p = p;
+						rate_table->m = m;
+						rate_table->s = s;
+						fref = fin_hz / p;
+						ffrac = fvco - (m * fref);
+						fout = ffrac * 65536;
+						rate_table->k = fout / fref;
+						return rate_table;
+					}
+				}
+			}
+		}
+		pr_err("CANNOT FIND Fout by auto,fout = %lu\n", fout_hz);
+	}
+	return NULL;
+}
+
 static const struct rockchip_pll_rate_table *
 rockchip_get_pll_settings(struct rockchip_pll_clock *pll, ulong rate)
 {
@@ -174,10 +237,14 @@
 			break;
 		rate_table++;
 	}
-	if (rate_table->rate != rate)
-		return rockchip_pll_clk_set_by_auto(24 * MHZ, rate);
-	else
+	if (rate_table->rate != rate) {
+		if (pll->type == pll_rk3588)
+			return rk3588_pll_clk_set_by_auto(24 * MHZ, rate);
+		else
+			return rockchip_pll_clk_set_by_auto(24 * MHZ, rate);
+	} else {
 		return rate_table;
+	}
 }
 
 static int rk3036_pll_set_rate(struct rockchip_pll_clock *pll,
@@ -289,6 +356,192 @@
 			do_div(frac_rate, postdiv1);
 			rate += frac_rate;
 		}
+		return rate;
+	case RKCLK_PLL_MODE_DEEP:
+	default:
+		return 32768;
+	}
+}
+
+#define RK3588_PLLCON(i)		((i) * 0x4)
+#define RK3588_PLLCON0_M_MASK		0x3ff << 0
+#define RK3588_PLLCON0_M_SHIFT		0
+#define RK3588_PLLCON1_P_MASK		0x3f << 0
+#define RK3588_PLLCON1_P_SHIFT		0
+#define RK3588_PLLCON1_S_MASK		0x7 << 6
+#define RK3588_PLLCON1_S_SHIFT		6
+#define RK3588_PLLCON2_K_MASK		0xffff
+#define RK3588_PLLCON2_K_SHIFT		0
+#define RK3588_PLLCON1_PWRDOWN		BIT(13)
+#define RK3588_PLLCON6_LOCK_STATUS	BIT(15)
+#define RK3588_B0PLL_CLKSEL_CON(i)	((i) * 0x4 + 0x50000 + 0x300)
+#define RK3588_B1PLL_CLKSEL_CON(i)	((i) * 0x4 + 0x52000 + 0x300)
+#define RK3588_LPLL_CLKSEL_CON(i)	((i) * 0x4 + 0x58000 + 0x300)
+#define RK3588_CORE_DIV_MASK		0x1f
+#define RK3588_CORE_L02_DIV_SHIFT	0
+#define RK3588_CORE_L13_DIV_SHIFT	7
+#define RK3588_CORE_B02_DIV_SHIFT	8
+#define RK3588_CORE_B13_DIV_SHIFT	0
+
+static int rk3588_pll_set_rate(struct rockchip_pll_clock *pll,
+			       void __iomem *base, ulong pll_id,
+			       ulong drate)
+{
+	const struct rockchip_pll_rate_table *rate;
+
+	rate = rockchip_get_pll_settings(pll, drate);
+	if (!rate) {
+		printf("%s unsupported rate\n", __func__);
+		return -EINVAL;
+	}
+
+	debug("%s: rate settings for %lu p: %d, m: %d, s: %d, k: %d\n",
+	      __func__, rate->rate, rate->p, rate->m, rate->s, rate->k);
+
+	/*
+	 * When power on or changing PLL setting,
+	 * we must force PLL into slow mode to ensure output stable clock.
+	 */
+	if (pll_id == 3)
+		rk_clrsetreg(base + 0x84c, 0x1 << 1, 0x1 << 1);
+
+	rk_clrsetreg(base + pll->mode_offset,
+		     pll->mode_mask << pll->mode_shift,
+		     RKCLK_PLL_MODE_SLOW << pll->mode_shift);
+	if (pll_id == 0)
+		rk_clrsetreg(base + RK3588_B0PLL_CLKSEL_CON(0),
+			     pll->mode_mask << 6,
+			     RKCLK_PLL_MODE_SLOW << 6);
+	else if (pll_id == 1)
+		rk_clrsetreg(base + RK3588_B1PLL_CLKSEL_CON(0),
+			     pll->mode_mask << 6,
+			     RKCLK_PLL_MODE_SLOW << 6);
+	else if (pll_id == 2)
+		rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(5),
+			     pll->mode_mask << 14,
+			     RKCLK_PLL_MODE_SLOW << 14);
+
+	/* Power down */
+	rk_setreg(base + pll->con_offset + RK3588_PLLCON(1),
+		  RK3588_PLLCON1_PWRDOWN);
+
+	rk_clrsetreg(base + pll->con_offset,
+		     RK3588_PLLCON0_M_MASK,
+		     (rate->m << RK3588_PLLCON0_M_SHIFT));
+	rk_clrsetreg(base + pll->con_offset + RK3588_PLLCON(1),
+		     (RK3588_PLLCON1_P_MASK |
+		     RK3588_PLLCON1_S_MASK),
+		     (rate->p << RK3588_PLLCON1_P_SHIFT |
+		     rate->s << RK3588_PLLCON1_S_SHIFT));
+	if (rate->k) {
+		rk_clrsetreg(base + pll->con_offset + RK3588_PLLCON(2),
+			     RK3588_PLLCON2_K_MASK,
+			     rate->k << RK3588_PLLCON2_K_SHIFT);
+	}
+	/* Power up */
+	rk_clrreg(base + pll->con_offset + RK3588_PLLCON(1),
+		  RK3588_PLLCON1_PWRDOWN);
+
+	/* waiting for pll lock */
+	while (!(readl(base + pll->con_offset + RK3588_PLLCON(6)) &
+		RK3588_PLLCON6_LOCK_STATUS)) {
+		udelay(1);
+		debug("%s: wait pll lock, pll_id=%ld\n", __func__, pll_id);
+	}
+
+	rk_clrsetreg(base + pll->mode_offset, pll->mode_mask << pll->mode_shift,
+		     RKCLK_PLL_MODE_NORMAL << pll->mode_shift);
+	if (pll_id == 0) {
+		rk_clrsetreg(base + RK3588_B0PLL_CLKSEL_CON(0),
+			     pll->mode_mask << 6,
+			     2 << 6);
+		rk_clrsetreg(base + RK3588_B0PLL_CLKSEL_CON(0),
+			     RK3588_CORE_DIV_MASK << RK3588_CORE_B02_DIV_SHIFT,
+			     0 << RK3588_CORE_B02_DIV_SHIFT);
+		rk_clrsetreg(base + RK3588_B0PLL_CLKSEL_CON(1),
+			     RK3588_CORE_DIV_MASK << RK3588_CORE_B13_DIV_SHIFT,
+			     0 << RK3588_CORE_B13_DIV_SHIFT);
+	} else if (pll_id == 1) {
+		rk_clrsetreg(base + RK3588_B1PLL_CLKSEL_CON(0),
+			     pll->mode_mask << 6,
+			     2 << 6);
+		rk_clrsetreg(base + RK3588_B1PLL_CLKSEL_CON(0),
+			     RK3588_CORE_DIV_MASK << RK3588_CORE_B02_DIV_SHIFT,
+			     0 << RK3588_CORE_B02_DIV_SHIFT);
+		rk_clrsetreg(base + RK3588_B1PLL_CLKSEL_CON(1),
+			     RK3588_CORE_DIV_MASK << RK3588_CORE_B13_DIV_SHIFT,
+			     0 << RK3588_CORE_B13_DIV_SHIFT);
+	} else if (pll_id == 2) {
+		rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(5),
+			     pll->mode_mask << 14,
+			     2 << 14);
+		rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(6),
+			     RK3588_CORE_DIV_MASK << RK3588_CORE_L13_DIV_SHIFT,
+			     0 << RK3588_CORE_L13_DIV_SHIFT);
+		rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(6),
+			     RK3588_CORE_DIV_MASK << RK3588_CORE_L02_DIV_SHIFT,
+			     0 << RK3588_CORE_L02_DIV_SHIFT);
+		rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(7),
+			     RK3588_CORE_DIV_MASK << RK3588_CORE_L13_DIV_SHIFT,
+			     0 << RK3588_CORE_L13_DIV_SHIFT);
+		rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(7),
+			     RK3588_CORE_DIV_MASK << RK3588_CORE_L02_DIV_SHIFT,
+			     0 << RK3588_CORE_L02_DIV_SHIFT);
+	}
+
+	if (pll_id == 3)
+		rk_clrsetreg(base + 0x84c, 0x1 << 1, 0);
+
+	debug("PLL at %p: con0=%x con1= %x con2= %x mode= %x\n",
+	      pll, readl(base + pll->con_offset),
+	      readl(base + pll->con_offset + 0x4),
+	      readl(base + pll->con_offset + 0x8),
+	      readl(base + pll->mode_offset));
+
+	return 0;
+}
+
+static ulong rk3588_pll_get_rate(struct rockchip_pll_clock *pll,
+				 void __iomem *base, ulong pll_id)
+{
+	u32 m, p, s, k;
+	u32 con = 0, shift, mode;
+	u64 rate, postdiv;
+
+	con = readl(base + pll->mode_offset);
+	shift = pll->mode_shift;
+	if (pll_id == 8)
+		mode = RKCLK_PLL_MODE_NORMAL;
+	else
+		mode = (con & (pll->mode_mask << shift)) >> shift;
+	switch (mode) {
+	case RKCLK_PLL_MODE_SLOW:
+		return OSC_HZ;
+	case RKCLK_PLL_MODE_NORMAL:
+		/* normal mode */
+		con = readl(base + pll->con_offset);
+		m = (con & RK3588_PLLCON0_M_MASK) >>
+			   RK3588_PLLCON0_M_SHIFT;
+		con = readl(base + pll->con_offset + RK3588_PLLCON(1));
+		p = (con & RK3588_PLLCON1_P_MASK) >>
+			   RK3036_PLLCON0_FBDIV_SHIFT;
+		s = (con & RK3588_PLLCON1_S_MASK) >>
+			 RK3588_PLLCON1_S_SHIFT;
+		con = readl(base + pll->con_offset + RK3588_PLLCON(2));
+		k = (con & RK3588_PLLCON2_K_MASK) >>
+			RK3588_PLLCON2_K_SHIFT;
+
+		rate = OSC_HZ / p;
+		rate *= m;
+		if (k) {
+			/* fractional mode */
+			u64 frac_rate64 = OSC_HZ * k;
+
+			postdiv = p * 65536;
+			do_div(frac_rate64, postdiv);
+			rate += frac_rate64;
+		}
+		rate = rate >> s;
 		return rate;
 	case RKCLK_PLL_MODE_DEEP:
 	default:
@@ -311,6 +564,10 @@
 		pll->mode_mask = PLL_RK3328_MODE_MASK;
 		rate = rk3036_pll_get_rate(pll, base, pll_id);
 		break;
+	case pll_rk3588:
+		pll->mode_mask = PLL_MODE_MASK;
+		rate = rk3588_pll_get_rate(pll, base, pll_id);
+		break;
 	default:
 		printf("%s: Unknown pll type for pll clk %ld\n",
 		       __func__, pll_id);
@@ -336,6 +593,10 @@
 		pll->mode_mask = PLL_RK3328_MODE_MASK;
 		ret = rk3036_pll_set_rate(pll, base, pll_id, drate);
 		break;
+	case pll_rk3588:
+		pll->mode_mask = PLL_MODE_MASK;
+		ret = rk3588_pll_set_rate(pll, base, pll_id, drate);
+		break;
 	default:
 		printf("%s: Unknown pll type for pll clk %ld\n",
 		       __func__, pll_id);
diff --git a/drivers/clk/rockchip/clk_rk3568.c b/drivers/clk/rockchip/clk_rk3568.c
index d5e45e7..99c195b 100644
--- a/drivers/clk/rockchip/clk_rk3568.c
+++ b/drivers/clk/rockchip/clk_rk3568.c
@@ -1442,6 +1442,7 @@
 	switch (rate) {
 	case OSC_HZ:
 	case 26 * MHz:
+	case 25 * MHz:
 		src_clk = CLK_SDMMC_SEL_24M;
 		break;
 	case 400 * MHz:
@@ -1631,6 +1632,8 @@
 
 	switch (rate) {
 	case OSC_HZ:
+	case 26 * MHz:
+	case 25 * MHz:
 		src_clk = CCLK_EMMC_SEL_24M;
 		break;
 	case 52 * MHz:
diff --git a/drivers/clk/rockchip/clk_rk3588.c b/drivers/clk/rockchip/clk_rk3588.c
new file mode 100644
index 0000000..5271d94
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rk3588.c
@@ -0,0 +1,1996 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Elaine Zhang <zhangqing@rock-chips.com>
+ */
+
+#include <common.h>
+#include <bitfield.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/cru_rk3588.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/io.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/rockchip,rk3588-cru.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define DIV_TO_RATE(input_rate, div)	((input_rate) / ((div) + 1))
+
+static struct rockchip_pll_rate_table rk3588_pll_rates[] = {
+	/* _mhz, _p, _m, _s, _k */
+	RK3588_PLL_RATE(1500000000, 2, 250, 1, 0),
+	RK3588_PLL_RATE(1200000000, 2, 200, 1, 0),
+	RK3588_PLL_RATE(1188000000, 2, 198, 1, 0),
+	RK3588_PLL_RATE(1100000000, 3, 550, 2, 0),
+	RK3588_PLL_RATE(1008000000, 2, 336, 2, 0),
+	RK3588_PLL_RATE(1000000000, 3, 500, 2, 0),
+	RK3588_PLL_RATE(900000000, 2, 300, 2, 0),
+	RK3588_PLL_RATE(850000000, 3, 425, 2, 0),
+	RK3588_PLL_RATE(816000000, 2, 272, 2, 0),
+	RK3588_PLL_RATE(786432000, 2, 262, 2, 9437),
+	RK3588_PLL_RATE(786000000, 1, 131, 2, 0),
+	RK3588_PLL_RATE(722534400, 8, 963, 2, 24850),
+	RK3588_PLL_RATE(600000000, 2, 200, 2, 0),
+	RK3588_PLL_RATE(594000000, 2, 198, 2, 0),
+	RK3588_PLL_RATE(200000000, 3, 400, 4, 0),
+	RK3588_PLL_RATE(100000000, 3, 400, 5, 0),
+	{ /* sentinel */ },
+};
+
+static struct rockchip_pll_clock rk3588_pll_clks[] = {
+	[B0PLL] = PLL(pll_rk3588, PLL_B0PLL, RK3588_B0_PLL_CON(0),
+		      RK3588_B0_PLL_MODE_CON, 0, 15, 0,
+		      rk3588_pll_rates),
+	[B1PLL] = PLL(pll_rk3588, PLL_B1PLL, RK3588_B1_PLL_CON(8),
+		      RK3588_B1_PLL_MODE_CON, 0, 15, 0,
+		      rk3588_pll_rates),
+	[LPLL] = PLL(pll_rk3588, PLL_LPLL, RK3588_LPLL_CON(16),
+		     RK3588_LPLL_MODE_CON, 0, 15, 0, rk3588_pll_rates),
+	[V0PLL] = PLL(pll_rk3588, PLL_V0PLL, RK3588_PLL_CON(88),
+		      RK3588_MODE_CON0, 4, 15, 0, rk3588_pll_rates),
+	[AUPLL] = PLL(pll_rk3588, PLL_AUPLL, RK3588_PLL_CON(96),
+		      RK3588_MODE_CON0, 6, 15, 0, rk3588_pll_rates),
+	[CPLL] = PLL(pll_rk3588, PLL_CPLL, RK3588_PLL_CON(104),
+		     RK3588_MODE_CON0, 8, 15, 0, rk3588_pll_rates),
+	[GPLL] = PLL(pll_rk3588, PLL_GPLL, RK3588_PLL_CON(112),
+		     RK3588_MODE_CON0, 2, 15, 0, rk3588_pll_rates),
+	[NPLL] = PLL(pll_rk3588, PLL_NPLL, RK3588_PLL_CON(120),
+		     RK3588_MODE_CON0, 0, 15, 0, rk3588_pll_rates),
+	[PPLL] = PLL(pll_rk3588, PLL_PPLL, RK3588_PMU_PLL_CON(128),
+		     RK3588_MODE_CON0, 10, 15, 0, rk3588_pll_rates),
+};
+
+#ifndef CONFIG_SPL_BUILD
+/*
+ *
+ * rational_best_approximation(31415, 10000,
+ *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
+ *
+ * you may look at given_numerator as a fixed point number,
+ * with the fractional part size described in given_denominator.
+ *
+ * for theoretical background, see:
+ * http://en.wikipedia.org/wiki/Continued_fraction
+ */
+static void rational_best_approximation(unsigned long given_numerator,
+					unsigned long given_denominator,
+					unsigned long max_numerator,
+					unsigned long max_denominator,
+					unsigned long *best_numerator,
+					unsigned long *best_denominator)
+{
+	unsigned long n, d, n0, d0, n1, d1;
+
+	n = given_numerator;
+	d = given_denominator;
+	n0 = 0;
+	d1 = 0;
+	n1 = 1;
+	d0 = 1;
+	for (;;) {
+		unsigned long t, a;
+
+		if (n1 > max_numerator || d1 > max_denominator) {
+			n1 = n0;
+			d1 = d0;
+			break;
+		}
+		if (d == 0)
+			break;
+		t = d;
+		a = n / d;
+		d = n % d;
+		n = t;
+		t = n0 + a * n1;
+		n0 = n1;
+		n1 = t;
+		t = d0 + a * d1;
+		d0 = d1;
+		d1 = t;
+	}
+	*best_numerator = n1;
+	*best_denominator = d1;
+}
+#endif
+
+static ulong rk3588_center_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
+{
+	struct rk3588_cru *cru = priv->cru;
+	u32 con, sel, rate;
+
+	switch (clk_id) {
+	case ACLK_CENTER_ROOT:
+		con = readl(&cru->clksel_con[165]);
+		sel = (con & ACLK_CENTER_ROOT_SEL_MASK) >>
+		      ACLK_CENTER_ROOT_SEL_SHIFT;
+		if (sel == ACLK_CENTER_ROOT_SEL_700M)
+			rate = 702 * MHz;
+		else if (sel == ACLK_CENTER_ROOT_SEL_400M)
+			rate = 396 * MHz;
+		else if (sel == ACLK_CENTER_ROOT_SEL_200M)
+			rate = 200 * MHz;
+		else
+			rate = OSC_HZ;
+		break;
+	case ACLK_CENTER_LOW_ROOT:
+		con = readl(&cru->clksel_con[165]);
+		sel = (con & ACLK_CENTER_LOW_ROOT_SEL_MASK) >>
+		      ACLK_CENTER_LOW_ROOT_SEL_SHIFT;
+		if (sel == ACLK_CENTER_LOW_ROOT_SEL_500M)
+			rate = 500 * MHz;
+		else if (sel == ACLK_CENTER_LOW_ROOT_SEL_250M)
+			rate = 250 * MHz;
+		else if (sel == ACLK_CENTER_LOW_ROOT_SEL_100M)
+			rate = 100 * MHz;
+		else
+			rate = OSC_HZ;
+		break;
+	case HCLK_CENTER_ROOT:
+		con = readl(&cru->clksel_con[165]);
+		sel = (con & HCLK_CENTER_ROOT_SEL_MASK) >>
+		      HCLK_CENTER_ROOT_SEL_SHIFT;
+		if (sel == HCLK_CENTER_ROOT_SEL_400M)
+			rate = 396 * MHz;
+		else if (sel == HCLK_CENTER_ROOT_SEL_200M)
+			rate = 200 * MHz;
+		else if (sel == HCLK_CENTER_ROOT_SEL_100M)
+			rate = 100 * MHz;
+		else
+			rate = OSC_HZ;
+		break;
+	case PCLK_CENTER_ROOT:
+		con = readl(&cru->clksel_con[165]);
+		sel = (con & PCLK_CENTER_ROOT_SEL_MASK) >>
+		      PCLK_CENTER_ROOT_SEL_SHIFT;
+		if (sel == PCLK_CENTER_ROOT_SEL_200M)
+			rate = 200 * MHz;
+		else if (sel == PCLK_CENTER_ROOT_SEL_100M)
+			rate = 100 * MHz;
+		else if (sel == PCLK_CENTER_ROOT_SEL_50M)
+			rate = 50 * MHz;
+		else
+			rate = OSC_HZ;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rate;
+}
+
+static ulong rk3588_center_set_clk(struct rk3588_clk_priv *priv,
+				   ulong clk_id, ulong rate)
+{
+	struct rk3588_cru *cru = priv->cru;
+	int src_clk;
+
+	switch (clk_id) {
+	case ACLK_CENTER_ROOT:
+		if (rate >= 700 * MHz)
+			src_clk = ACLK_CENTER_ROOT_SEL_700M;
+		else if (rate >= 396 * MHz)
+			src_clk = ACLK_CENTER_ROOT_SEL_400M;
+		else if (rate >= 200 * MHz)
+			src_clk = ACLK_CENTER_ROOT_SEL_200M;
+		else
+			src_clk = ACLK_CENTER_ROOT_SEL_24M;
+		rk_clrsetreg(&cru->clksel_con[165],
+			     ACLK_CENTER_ROOT_SEL_MASK,
+			     src_clk << ACLK_CENTER_ROOT_SEL_SHIFT);
+		break;
+	case ACLK_CENTER_LOW_ROOT:
+		if (rate >= 500 * MHz)
+			src_clk = ACLK_CENTER_LOW_ROOT_SEL_500M;
+		else if (rate >= 250 * MHz)
+			src_clk = ACLK_CENTER_LOW_ROOT_SEL_250M;
+		else if (rate >= 99 * MHz)
+			src_clk = ACLK_CENTER_LOW_ROOT_SEL_100M;
+		else
+			src_clk = ACLK_CENTER_LOW_ROOT_SEL_24M;
+		rk_clrsetreg(&cru->clksel_con[165],
+			     ACLK_CENTER_LOW_ROOT_SEL_MASK,
+			     src_clk << ACLK_CENTER_LOW_ROOT_SEL_SHIFT);
+		break;
+	case HCLK_CENTER_ROOT:
+		if (rate >= 396 * MHz)
+			src_clk = HCLK_CENTER_ROOT_SEL_400M;
+		else if (rate >= 198 * MHz)
+			src_clk = HCLK_CENTER_ROOT_SEL_200M;
+		else if (rate >= 99 * MHz)
+			src_clk = HCLK_CENTER_ROOT_SEL_100M;
+		else
+			src_clk = HCLK_CENTER_ROOT_SEL_24M;
+		rk_clrsetreg(&cru->clksel_con[165],
+			     HCLK_CENTER_ROOT_SEL_MASK,
+			     src_clk << HCLK_CENTER_ROOT_SEL_SHIFT);
+		break;
+	case PCLK_CENTER_ROOT:
+		if (rate >= 198 * MHz)
+			src_clk = PCLK_CENTER_ROOT_SEL_200M;
+		else if (rate >= 99 * MHz)
+			src_clk = PCLK_CENTER_ROOT_SEL_100M;
+		else if (rate >= 50 * MHz)
+			src_clk = PCLK_CENTER_ROOT_SEL_50M;
+		else
+			src_clk = PCLK_CENTER_ROOT_SEL_24M;
+		rk_clrsetreg(&cru->clksel_con[165],
+			     PCLK_CENTER_ROOT_SEL_MASK,
+			     src_clk << PCLK_CENTER_ROOT_SEL_SHIFT);
+		break;
+	default:
+		printf("do not support this center freq\n");
+		return -EINVAL;
+	}
+
+	return rk3588_center_get_clk(priv, clk_id);
+}
+
+static ulong rk3588_top_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
+{
+	struct rk3588_cru *cru = priv->cru;
+	u32 con, sel, div, rate, prate;
+
+	switch (clk_id) {
+	case ACLK_TOP_ROOT:
+		con = readl(&cru->clksel_con[8]);
+		div = (con & ACLK_TOP_ROOT_DIV_MASK) >>
+		      ACLK_TOP_ROOT_DIV_SHIFT;
+		sel = (con & ACLK_TOP_ROOT_SRC_SEL_MASK) >>
+		      ACLK_TOP_ROOT_SRC_SEL_SHIFT;
+		if (sel == ACLK_TOP_ROOT_SRC_SEL_CPLL)
+			prate = priv->cpll_hz;
+		else
+			prate = priv->gpll_hz;
+		return DIV_TO_RATE(prate, div);
+	case ACLK_LOW_TOP_ROOT:
+		con = readl(&cru->clksel_con[8]);
+		div = (con & ACLK_LOW_TOP_ROOT_DIV_MASK) >>
+		      ACLK_LOW_TOP_ROOT_DIV_SHIFT;
+		sel = (con & ACLK_LOW_TOP_ROOT_SRC_SEL_MASK) >>
+		      ACLK_LOW_TOP_ROOT_SRC_SEL_SHIFT;
+		if (sel == ACLK_LOW_TOP_ROOT_SRC_SEL_CPLL)
+			prate = priv->cpll_hz;
+		else
+			prate = priv->gpll_hz;
+		return DIV_TO_RATE(prate, div);
+	case PCLK_TOP_ROOT:
+		con = readl(&cru->clksel_con[8]);
+		sel = (con & PCLK_TOP_ROOT_SEL_MASK) >> PCLK_TOP_ROOT_SEL_SHIFT;
+		if (sel == PCLK_TOP_ROOT_SEL_100M)
+			rate = 100 * MHz;
+		else if (sel == PCLK_TOP_ROOT_SEL_50M)
+			rate = 50 * MHz;
+		else
+			rate = OSC_HZ;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rate;
+}
+
+static ulong rk3588_top_set_clk(struct rk3588_clk_priv *priv,
+				ulong clk_id, ulong rate)
+{
+	struct rk3588_cru *cru = priv->cru;
+	int src_clk, src_clk_div;
+
+	switch (clk_id) {
+	case ACLK_TOP_ROOT:
+		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+		assert(src_clk_div - 1 <= 31);
+		rk_clrsetreg(&cru->clksel_con[8],
+			     ACLK_TOP_ROOT_DIV_MASK |
+			     ACLK_TOP_ROOT_SRC_SEL_MASK,
+			     (ACLK_TOP_ROOT_SRC_SEL_GPLL <<
+			      ACLK_TOP_ROOT_SRC_SEL_SHIFT) |
+			     (src_clk_div - 1) << ACLK_TOP_ROOT_DIV_SHIFT);
+		break;
+	case ACLK_LOW_TOP_ROOT:
+		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+		assert(src_clk_div - 1 <= 31);
+		rk_clrsetreg(&cru->clksel_con[8],
+			     ACLK_LOW_TOP_ROOT_DIV_MASK |
+			     ACLK_LOW_TOP_ROOT_SRC_SEL_MASK,
+			     (ACLK_LOW_TOP_ROOT_SRC_SEL_GPLL <<
+			      ACLK_LOW_TOP_ROOT_SRC_SEL_SHIFT) |
+			     (src_clk_div - 1) << ACLK_LOW_TOP_ROOT_DIV_SHIFT);
+		break;
+	case PCLK_TOP_ROOT:
+		if (rate == 100 * MHz)
+			src_clk = PCLK_TOP_ROOT_SEL_100M;
+		else if (rate == 50 * MHz)
+			src_clk = PCLK_TOP_ROOT_SEL_50M;
+		else
+			src_clk = PCLK_TOP_ROOT_SEL_24M;
+		rk_clrsetreg(&cru->clksel_con[8],
+			     PCLK_TOP_ROOT_SEL_MASK,
+			     src_clk << PCLK_TOP_ROOT_SEL_SHIFT);
+		break;
+	default:
+		printf("do not support this top freq\n");
+		return -EINVAL;
+	}
+
+	return rk3588_top_get_clk(priv, clk_id);
+}
+
+static ulong rk3588_i2c_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
+{
+	struct rk3588_cru *cru = priv->cru;
+	u32 sel, con;
+	ulong rate;
+
+	switch (clk_id) {
+	case CLK_I2C0:
+		con = readl(&cru->pmuclksel_con[3]);
+		sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT;
+		break;
+	case CLK_I2C1:
+		con = readl(&cru->clksel_con[38]);
+		sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT;
+		break;
+	case CLK_I2C2:
+		con = readl(&cru->clksel_con[38]);
+		sel = (con & CLK_I2C2_SEL_MASK) >> CLK_I2C2_SEL_SHIFT;
+		break;
+	case CLK_I2C3:
+		con = readl(&cru->clksel_con[38]);
+		sel = (con & CLK_I2C3_SEL_MASK) >> CLK_I2C3_SEL_SHIFT;
+		break;
+	case CLK_I2C4:
+		con = readl(&cru->clksel_con[38]);
+		sel = (con & CLK_I2C4_SEL_MASK) >> CLK_I2C4_SEL_SHIFT;
+		break;
+	case CLK_I2C5:
+		con = readl(&cru->clksel_con[38]);
+		sel = (con & CLK_I2C5_SEL_MASK) >> CLK_I2C5_SEL_SHIFT;
+		break;
+	case CLK_I2C6:
+		con = readl(&cru->clksel_con[38]);
+		sel = (con & CLK_I2C6_SEL_MASK) >> CLK_I2C6_SEL_SHIFT;
+		break;
+	case CLK_I2C7:
+		con = readl(&cru->clksel_con[38]);
+		sel = (con & CLK_I2C7_SEL_MASK) >> CLK_I2C7_SEL_SHIFT;
+		break;
+	case CLK_I2C8:
+		con = readl(&cru->clksel_con[38]);
+		sel = (con & CLK_I2C8_SEL_MASK) >> CLK_I2C8_SEL_SHIFT;
+		break;
+	default:
+		return -ENOENT;
+	}
+	if (sel == CLK_I2C_SEL_200M)
+		rate = 200 * MHz;
+	else
+		rate = 100 * MHz;
+
+	return rate;
+}
+
+static ulong rk3588_i2c_set_clk(struct rk3588_clk_priv *priv, ulong clk_id,
+				ulong rate)
+{
+	struct rk3588_cru *cru = priv->cru;
+	int src_clk;
+
+	if (rate >= 198 * MHz)
+		src_clk = CLK_I2C_SEL_200M;
+	else
+		src_clk = CLK_I2C_SEL_100M;
+
+	switch (clk_id) {
+	case CLK_I2C0:
+		rk_clrsetreg(&cru->pmuclksel_con[3], CLK_I2C0_SEL_MASK,
+			     src_clk << CLK_I2C0_SEL_SHIFT);
+		break;
+	case CLK_I2C1:
+		rk_clrsetreg(&cru->clksel_con[38], CLK_I2C1_SEL_MASK,
+			     src_clk << CLK_I2C1_SEL_SHIFT);
+		break;
+	case CLK_I2C2:
+		rk_clrsetreg(&cru->clksel_con[38], CLK_I2C2_SEL_MASK,
+			     src_clk << CLK_I2C2_SEL_SHIFT);
+		break;
+	case CLK_I2C3:
+		rk_clrsetreg(&cru->clksel_con[38], CLK_I2C3_SEL_MASK,
+			     src_clk << CLK_I2C3_SEL_SHIFT);
+		break;
+	case CLK_I2C4:
+		rk_clrsetreg(&cru->clksel_con[38], CLK_I2C4_SEL_MASK,
+			     src_clk << CLK_I2C4_SEL_SHIFT);
+		break;
+	case CLK_I2C5:
+		rk_clrsetreg(&cru->clksel_con[38], CLK_I2C5_SEL_MASK,
+			     src_clk << CLK_I2C5_SEL_SHIFT);
+		break;
+	case CLK_I2C6:
+		rk_clrsetreg(&cru->clksel_con[38], CLK_I2C6_SEL_MASK,
+			     src_clk << CLK_I2C6_SEL_SHIFT);
+		break;
+	case CLK_I2C7:
+		rk_clrsetreg(&cru->clksel_con[38], CLK_I2C7_SEL_MASK,
+			     src_clk << CLK_I2C7_SEL_SHIFT);
+		break;
+	case CLK_I2C8:
+		rk_clrsetreg(&cru->clksel_con[38], CLK_I2C8_SEL_MASK,
+			     src_clk << CLK_I2C8_SEL_SHIFT);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rk3588_i2c_get_clk(priv, clk_id);
+}
+
+static ulong rk3588_spi_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
+{
+	struct rk3588_cru *cru = priv->cru;
+	u32 sel, con;
+
+	con = readl(&cru->clksel_con[59]);
+
+	switch (clk_id) {
+	case CLK_SPI0:
+		sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
+		break;
+	case CLK_SPI1:
+		sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
+		break;
+	case CLK_SPI2:
+		sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT;
+		break;
+	case CLK_SPI3:
+		sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT;
+		break;
+	case CLK_SPI4:
+		sel = (con & CLK_SPI4_SEL_MASK) >> CLK_SPI4_SEL_SHIFT;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	switch (sel) {
+	case CLK_SPI_SEL_200M:
+		return 200 * MHz;
+	case CLK_SPI_SEL_150M:
+		return 150 * MHz;
+	case CLK_SPI_SEL_24M:
+		return OSC_HZ;
+	default:
+		return -ENOENT;
+	}
+}
+
+static ulong rk3588_spi_set_clk(struct rk3588_clk_priv *priv,
+				ulong clk_id, ulong rate)
+{
+	struct rk3588_cru *cru = priv->cru;
+	int src_clk;
+
+	if (rate >= 198 * MHz)
+		src_clk = CLK_SPI_SEL_200M;
+	else if (rate >= 140 * MHz)
+		src_clk = CLK_SPI_SEL_150M;
+	else
+		src_clk = CLK_SPI_SEL_24M;
+
+	switch (clk_id) {
+	case CLK_SPI0:
+		rk_clrsetreg(&cru->clksel_con[59],
+			     CLK_SPI0_SEL_MASK,
+			     src_clk << CLK_SPI0_SEL_SHIFT);
+		break;
+	case CLK_SPI1:
+		rk_clrsetreg(&cru->clksel_con[59],
+			     CLK_SPI1_SEL_MASK,
+			     src_clk << CLK_SPI1_SEL_SHIFT);
+		break;
+	case CLK_SPI2:
+		rk_clrsetreg(&cru->clksel_con[59],
+			     CLK_SPI2_SEL_MASK,
+			     src_clk << CLK_SPI2_SEL_SHIFT);
+		break;
+	case CLK_SPI3:
+		rk_clrsetreg(&cru->clksel_con[59],
+			     CLK_SPI3_SEL_MASK,
+			     src_clk << CLK_SPI3_SEL_SHIFT);
+		break;
+	case CLK_SPI4:
+		rk_clrsetreg(&cru->clksel_con[59],
+			     CLK_SPI4_SEL_MASK,
+			     src_clk << CLK_SPI4_SEL_SHIFT);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rk3588_spi_get_clk(priv, clk_id);
+}
+
+static ulong rk3588_pwm_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
+{
+	struct rk3588_cru *cru = priv->cru;
+	u32 sel, con;
+
+	switch (clk_id) {
+	case CLK_PWM1:
+		con = readl(&cru->clksel_con[59]);
+		sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
+		break;
+	case CLK_PWM2:
+		con = readl(&cru->clksel_con[59]);
+		sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
+		break;
+	case CLK_PWM3:
+		con = readl(&cru->clksel_con[60]);
+		sel = (con & CLK_PWM3_SEL_MASK) >> CLK_PWM3_SEL_SHIFT;
+		break;
+	case CLK_PMU1PWM:
+		con = readl(&cru->pmuclksel_con[2]);
+		sel = (con & CLK_PMU1PWM_SEL_MASK) >> CLK_PMU1PWM_SEL_SHIFT;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	switch (sel) {
+	case CLK_PWM_SEL_100M:
+		return 100 * MHz;
+	case CLK_PWM_SEL_50M:
+		return 50 * MHz;
+	case CLK_PWM_SEL_24M:
+		return OSC_HZ;
+	default:
+		return -ENOENT;
+	}
+}
+
+static ulong rk3588_pwm_set_clk(struct rk3588_clk_priv *priv,
+				ulong clk_id, ulong rate)
+{
+	struct rk3588_cru *cru = priv->cru;
+	int src_clk;
+
+	if (rate >= 99 * MHz)
+		src_clk = CLK_PWM_SEL_100M;
+	else if (rate >= 50 * MHz)
+		src_clk = CLK_PWM_SEL_50M;
+	else
+		src_clk = CLK_PWM_SEL_24M;
+
+	switch (clk_id) {
+	case CLK_PWM1:
+		rk_clrsetreg(&cru->clksel_con[59],
+			     CLK_PWM1_SEL_MASK,
+			     src_clk << CLK_PWM1_SEL_SHIFT);
+		break;
+	case CLK_PWM2:
+		rk_clrsetreg(&cru->clksel_con[59],
+			     CLK_PWM2_SEL_MASK,
+			     src_clk << CLK_PWM2_SEL_SHIFT);
+		break;
+	case CLK_PWM3:
+		rk_clrsetreg(&cru->clksel_con[60],
+			     CLK_PWM3_SEL_MASK,
+			     src_clk << CLK_PWM3_SEL_SHIFT);
+		break;
+	case CLK_PMU1PWM:
+		rk_clrsetreg(&cru->pmuclksel_con[2],
+			     CLK_PMU1PWM_SEL_MASK,
+			     src_clk << CLK_PMU1PWM_SEL_SHIFT);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rk3588_pwm_get_clk(priv, clk_id);
+}
+
+static ulong rk3588_adc_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
+{
+	struct rk3588_cru *cru = priv->cru;
+	u32 div, sel, con, prate;
+
+	switch (clk_id) {
+	case CLK_SARADC:
+		con = readl(&cru->clksel_con[40]);
+		div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT;
+		sel = (con & CLK_SARADC_SEL_MASK) >>
+		      CLK_SARADC_SEL_SHIFT;
+		if (sel == CLK_SARADC_SEL_24M)
+			prate = OSC_HZ;
+		else
+			prate = priv->gpll_hz;
+		return DIV_TO_RATE(prate, div);
+	case CLK_TSADC:
+		con = readl(&cru->clksel_con[41]);
+		div = (con & CLK_TSADC_DIV_MASK) >>
+		      CLK_TSADC_DIV_SHIFT;
+		sel = (con & CLK_TSADC_SEL_MASK) >>
+		      CLK_TSADC_SEL_SHIFT;
+		if (sel == CLK_TSADC_SEL_24M)
+			prate = OSC_HZ;
+		else
+			prate = 100 * MHz;
+		return DIV_TO_RATE(prate, div);
+	default:
+		return -ENOENT;
+	}
+}
+
+static ulong rk3588_adc_set_clk(struct rk3588_clk_priv *priv,
+				ulong clk_id, ulong rate)
+{
+	struct rk3588_cru *cru = priv->cru;
+	int src_clk_div;
+
+	switch (clk_id) {
+	case CLK_SARADC:
+		if (!(OSC_HZ % rate)) {
+			src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
+			assert(src_clk_div - 1 <= 255);
+			rk_clrsetreg(&cru->clksel_con[40],
+				     CLK_SARADC_SEL_MASK |
+				     CLK_SARADC_DIV_MASK,
+				     (CLK_SARADC_SEL_24M <<
+				      CLK_SARADC_SEL_SHIFT) |
+				     (src_clk_div - 1) <<
+				     CLK_SARADC_DIV_SHIFT);
+		} else {
+			src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+			assert(src_clk_div - 1 <= 255);
+			rk_clrsetreg(&cru->clksel_con[40],
+				     CLK_SARADC_SEL_MASK |
+				     CLK_SARADC_DIV_MASK,
+				     (CLK_SARADC_SEL_GPLL <<
+				      CLK_SARADC_SEL_SHIFT) |
+				     (src_clk_div - 1) <<
+				     CLK_SARADC_DIV_SHIFT);
+		}
+		break;
+	case CLK_TSADC:
+		if (!(OSC_HZ % rate)) {
+			src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
+			assert(src_clk_div - 1 <= 255);
+			rk_clrsetreg(&cru->clksel_con[41],
+				     CLK_TSADC_SEL_MASK |
+				     CLK_TSADC_DIV_MASK,
+				     (CLK_TSADC_SEL_24M <<
+				      CLK_TSADC_SEL_SHIFT) |
+				     (src_clk_div - 1) <<
+				     CLK_TSADC_DIV_SHIFT);
+		} else {
+			src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+			assert(src_clk_div - 1 <= 7);
+			rk_clrsetreg(&cru->clksel_con[41],
+				     CLK_TSADC_SEL_MASK |
+				     CLK_TSADC_DIV_MASK,
+				     (CLK_TSADC_SEL_GPLL <<
+				      CLK_TSADC_SEL_SHIFT) |
+				     (src_clk_div - 1) <<
+				     CLK_TSADC_DIV_SHIFT);
+		}
+		break;
+	default:
+		return -ENOENT;
+	}
+	return rk3588_adc_get_clk(priv, clk_id);
+}
+
+static ulong rk3588_mmc_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
+{
+	struct rk3588_cru *cru = priv->cru;
+	u32 sel, con, div, prate;
+
+	switch (clk_id) {
+	case CCLK_SRC_SDIO:
+		con = readl(&cru->clksel_con[172]);
+		div = (con & CCLK_SDIO_SRC_DIV_MASK) >> CCLK_SDIO_SRC_DIV_SHIFT;
+		sel = (con & CCLK_SDIO_SRC_SEL_MASK) >>
+		      CCLK_SDIO_SRC_SEL_SHIFT;
+		if (sel == CCLK_SDIO_SRC_SEL_GPLL)
+			prate = priv->gpll_hz;
+		else if (sel == CCLK_SDIO_SRC_SEL_CPLL)
+			prate = priv->cpll_hz;
+		else
+			prate = OSC_HZ;
+		return DIV_TO_RATE(prate, div);
+	case CCLK_EMMC:
+		con = readl(&cru->clksel_con[77]);
+		div = (con & CCLK_EMMC_DIV_MASK) >> CCLK_EMMC_DIV_SHIFT;
+		sel = (con & CCLK_EMMC_SEL_MASK) >>
+		      CCLK_EMMC_SEL_SHIFT;
+		if (sel == CCLK_EMMC_SEL_GPLL)
+			prate = priv->gpll_hz;
+		else if (sel == CCLK_EMMC_SEL_CPLL)
+			prate = priv->cpll_hz;
+		else
+			prate = OSC_HZ;
+		return DIV_TO_RATE(prate, div);
+	case BCLK_EMMC:
+		con = readl(&cru->clksel_con[78]);
+		div = (con & BCLK_EMMC_DIV_MASK) >> BCLK_EMMC_DIV_SHIFT;
+		sel = (con & BCLK_EMMC_SEL_MASK) >>
+		      BCLK_EMMC_SEL_SHIFT;
+		if (sel == CCLK_EMMC_SEL_CPLL)
+			prate = priv->cpll_hz;
+		else
+			prate = priv->gpll_hz;
+		return DIV_TO_RATE(prate, div);
+	case SCLK_SFC:
+		con = readl(&cru->clksel_con[78]);
+		div = (con & SCLK_SFC_DIV_MASK) >> SCLK_SFC_DIV_SHIFT;
+		sel = (con & SCLK_SFC_SEL_MASK) >>
+		      SCLK_SFC_SEL_SHIFT;
+		if (sel == SCLK_SFC_SEL_GPLL)
+			prate = priv->gpll_hz;
+		else if (sel == SCLK_SFC_SEL_CPLL)
+			prate = priv->cpll_hz;
+		else
+			prate = OSC_HZ;
+		return DIV_TO_RATE(prate, div);
+	case DCLK_DECOM:
+		con = readl(&cru->clksel_con[62]);
+		div = (con & DCLK_DECOM_DIV_MASK) >> DCLK_DECOM_DIV_SHIFT;
+		sel = (con & DCLK_DECOM_SEL_MASK) >>
+		      DCLK_DECOM_SEL_SHIFT;
+		if (sel == DCLK_DECOM_SEL_SPLL)
+			prate = 702 * MHz;
+		else
+			prate = priv->gpll_hz;
+		return DIV_TO_RATE(prate, div);
+	default:
+		return -ENOENT;
+	}
+}
+
+static ulong rk3588_mmc_set_clk(struct rk3588_clk_priv *priv,
+				ulong clk_id, ulong rate)
+{
+	struct rk3588_cru *cru = priv->cru;
+	int src_clk, div;
+
+	switch (clk_id) {
+	case CCLK_SRC_SDIO:
+	case CCLK_EMMC:
+	case SCLK_SFC:
+		if (!(OSC_HZ % rate)) {
+			src_clk = SCLK_SFC_SEL_24M;
+			div = DIV_ROUND_UP(OSC_HZ, rate);
+		} else if (!(priv->cpll_hz % rate)) {
+			src_clk = SCLK_SFC_SEL_CPLL;
+			div = DIV_ROUND_UP(priv->cpll_hz, rate);
+		} else {
+			src_clk = SCLK_SFC_SEL_GPLL;
+			div = DIV_ROUND_UP(priv->gpll_hz, rate);
+		}
+		break;
+	case BCLK_EMMC:
+		if (!(priv->cpll_hz % rate)) {
+			src_clk = CCLK_EMMC_SEL_CPLL;
+			div = DIV_ROUND_UP(priv->cpll_hz, rate);
+		} else {
+			src_clk = CCLK_EMMC_SEL_GPLL;
+			div = DIV_ROUND_UP(priv->gpll_hz, rate);
+		}
+		break;
+	case DCLK_DECOM:
+		if (!(702 * MHz % rate)) {
+			src_clk = DCLK_DECOM_SEL_SPLL;
+			div = DIV_ROUND_UP(702 * MHz, rate);
+		} else {
+			src_clk = DCLK_DECOM_SEL_GPLL;
+			div = DIV_ROUND_UP(priv->gpll_hz, rate);
+		}
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	switch (clk_id) {
+	case CCLK_SRC_SDIO:
+		rk_clrsetreg(&cru->clksel_con[172],
+			     CCLK_SDIO_SRC_SEL_MASK |
+			     CCLK_SDIO_SRC_DIV_MASK,
+			     (src_clk << CCLK_SDIO_SRC_SEL_SHIFT) |
+			     (div - 1) << CCLK_SDIO_SRC_DIV_SHIFT);
+		break;
+	case CCLK_EMMC:
+		rk_clrsetreg(&cru->clksel_con[77],
+			     CCLK_EMMC_SEL_MASK |
+			     CCLK_EMMC_DIV_MASK,
+			     (src_clk << CCLK_EMMC_SEL_SHIFT) |
+			     (div - 1) << CCLK_EMMC_DIV_SHIFT);
+		break;
+	case BCLK_EMMC:
+		rk_clrsetreg(&cru->clksel_con[78],
+			     BCLK_EMMC_DIV_MASK |
+			     BCLK_EMMC_SEL_MASK,
+			     (src_clk << BCLK_EMMC_SEL_SHIFT) |
+			     (div - 1) << BCLK_EMMC_DIV_SHIFT);
+		break;
+	case SCLK_SFC:
+		rk_clrsetreg(&cru->clksel_con[78],
+			     SCLK_SFC_DIV_MASK |
+			     SCLK_SFC_SEL_MASK,
+			     (src_clk << SCLK_SFC_SEL_SHIFT) |
+			     (div - 1) << SCLK_SFC_DIV_SHIFT);
+		break;
+	case DCLK_DECOM:
+		rk_clrsetreg(&cru->clksel_con[62],
+			     DCLK_DECOM_DIV_MASK |
+			     DCLK_DECOM_SEL_MASK,
+			     (src_clk << DCLK_DECOM_SEL_SHIFT) |
+			     (div - 1) << DCLK_DECOM_DIV_SHIFT);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rk3588_mmc_get_clk(priv, clk_id);
+}
+
+#ifndef CONFIG_SPL_BUILD
+static ulong rk3588_aux16m_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
+{
+	struct rk3588_cru *cru = priv->cru;
+	u32 div, con, parent;
+
+	parent = priv->gpll_hz;
+	con = readl(&cru->clksel_con[117]);
+
+	switch (clk_id) {
+	case CLK_AUX16M_0:
+		div = (con & CLK_AUX16MHZ_0_DIV_MASK) >> CLK_AUX16MHZ_0_DIV_SHIFT;
+		return DIV_TO_RATE(parent, div);
+	case CLK_AUX16M_1:
+		div = (con & CLK_AUX16MHZ_1_DIV_MASK) >> CLK_AUX16MHZ_1_DIV_SHIFT;
+		return DIV_TO_RATE(parent, div);
+	default:
+		return -ENOENT;
+	}
+}
+
+static ulong rk3588_aux16m_set_clk(struct rk3588_clk_priv *priv,
+				   ulong clk_id, ulong rate)
+{
+	struct rk3588_cru *cru = priv->cru;
+	u32 div;
+
+	if (!priv->gpll_hz) {
+		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
+		return -ENOENT;
+	}
+
+	div = DIV_ROUND_UP(priv->gpll_hz, rate);
+
+	switch (clk_id) {
+	case CLK_AUX16M_0:
+		rk_clrsetreg(&cru->clksel_con[117], CLK_AUX16MHZ_0_DIV_MASK,
+			     (div - 1) << CLK_AUX16MHZ_0_DIV_SHIFT);
+		break;
+	case CLK_AUX16M_1:
+		rk_clrsetreg(&cru->clksel_con[117], CLK_AUX16MHZ_1_DIV_MASK,
+			     (div - 1) << CLK_AUX16MHZ_1_DIV_SHIFT);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rk3588_aux16m_get_clk(priv, clk_id);
+}
+
+static ulong rk3588_aclk_vop_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
+{
+	struct rk3588_cru *cru = priv->cru;
+	u32 div, sel, con, parent;
+
+	switch (clk_id) {
+	case ACLK_VOP_ROOT:
+	case ACLK_VOP:
+		con = readl(&cru->clksel_con[110]);
+		div = (con & ACLK_VOP_ROOT_DIV_MASK) >> ACLK_VOP_ROOT_DIV_SHIFT;
+		sel = (con & ACLK_VOP_ROOT_SEL_MASK) >> ACLK_VOP_ROOT_SEL_SHIFT;
+		if (sel == ACLK_VOP_ROOT_SEL_GPLL)
+			parent = priv->gpll_hz;
+		else if (sel == ACLK_VOP_ROOT_SEL_CPLL)
+			parent = priv->cpll_hz;
+		else if (sel == ACLK_VOP_ROOT_SEL_AUPLL)
+			parent = priv->aupll_hz;
+		else if (sel == ACLK_VOP_ROOT_SEL_NPLL)
+			parent = priv->npll_hz;
+		else
+			parent = 702 * MHz;
+		return DIV_TO_RATE(parent, div);
+	case ACLK_VOP_LOW_ROOT:
+		con = readl(&cru->clksel_con[110]);
+		sel = (con & ACLK_VOP_LOW_ROOT_SEL_MASK) >>
+		      ACLK_VOP_LOW_ROOT_SEL_SHIFT;
+		if (sel == ACLK_VOP_LOW_ROOT_SEL_400M)
+			return 396 * MHz;
+		else if (sel == ACLK_VOP_LOW_ROOT_SEL_200M)
+			return 200 * MHz;
+		else if (sel == ACLK_VOP_LOW_ROOT_SEL_100M)
+			return 100 * MHz;
+		else
+			return OSC_HZ;
+	case HCLK_VOP_ROOT:
+		con = readl(&cru->clksel_con[110]);
+		sel = (con & HCLK_VOP_ROOT_SEL_MASK) >> HCLK_VOP_ROOT_SEL_SHIFT;
+		if (sel == HCLK_VOP_ROOT_SEL_200M)
+			return 200 * MHz;
+		else if (sel == HCLK_VOP_ROOT_SEL_100M)
+			return 100 * MHz;
+		else if (sel == HCLK_VOP_ROOT_SEL_50M)
+			return 50 * MHz;
+		else
+			return OSC_HZ;
+	default:
+		return -ENOENT;
+	}
+}
+
+static ulong rk3588_aclk_vop_set_clk(struct rk3588_clk_priv *priv,
+				     ulong clk_id, ulong rate)
+{
+	struct rk3588_cru *cru = priv->cru;
+	int src_clk, div;
+
+	switch (clk_id) {
+	case ACLK_VOP_ROOT:
+	case ACLK_VOP:
+		if (rate >= 850 * MHz) {
+			src_clk = ACLK_VOP_ROOT_SEL_NPLL;
+			div = 1;
+		} else if (rate >= 750 * MHz) {
+			src_clk = ACLK_VOP_ROOT_SEL_CPLL;
+			div = 2;
+		} else if (rate >= 700 * MHz) {
+			src_clk = ACLK_VOP_ROOT_SEL_SPLL;
+			div = 1;
+		} else if (!(priv->cpll_hz % rate)) {
+			src_clk = ACLK_VOP_ROOT_SEL_CPLL;
+			div = DIV_ROUND_UP(priv->cpll_hz, rate);
+		} else {
+			src_clk = ACLK_VOP_ROOT_SEL_GPLL;
+			div = DIV_ROUND_UP(priv->gpll_hz, rate);
+		}
+		rk_clrsetreg(&cru->clksel_con[110],
+			     ACLK_VOP_ROOT_DIV_MASK |
+			     ACLK_VOP_ROOT_SEL_MASK,
+			     (src_clk << ACLK_VOP_ROOT_SEL_SHIFT) |
+			     (div - 1) << ACLK_VOP_ROOT_DIV_SHIFT);
+		break;
+	case ACLK_VOP_LOW_ROOT:
+		if (rate == 400 * MHz || rate == 396 * MHz)
+			src_clk = ACLK_VOP_LOW_ROOT_SEL_400M;
+		else if (rate == 200 * MHz)
+			src_clk = ACLK_VOP_LOW_ROOT_SEL_200M;
+		else if (rate == 100 * MHz)
+			src_clk = ACLK_VOP_LOW_ROOT_SEL_100M;
+		else
+			src_clk = ACLK_VOP_LOW_ROOT_SEL_24M;
+		rk_clrsetreg(&cru->clksel_con[110],
+			     ACLK_VOP_LOW_ROOT_SEL_MASK,
+			     src_clk << ACLK_VOP_LOW_ROOT_SEL_SHIFT);
+		break;
+	case HCLK_VOP_ROOT:
+		if (rate == 200 * MHz)
+			src_clk = HCLK_VOP_ROOT_SEL_200M;
+		else if (rate == 100 * MHz)
+			src_clk = HCLK_VOP_ROOT_SEL_100M;
+		else if (rate == 50 * MHz)
+			src_clk = HCLK_VOP_ROOT_SEL_50M;
+		else
+			src_clk = HCLK_VOP_ROOT_SEL_24M;
+		rk_clrsetreg(&cru->clksel_con[110],
+			     HCLK_VOP_ROOT_SEL_MASK,
+			     src_clk << HCLK_VOP_ROOT_SEL_SHIFT);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rk3588_aclk_vop_get_clk(priv, clk_id);
+}
+
+static ulong rk3588_dclk_vop_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
+{
+	struct rk3588_cru *cru = priv->cru;
+	u32 div, sel, con, parent;
+
+	switch (clk_id) {
+	case DCLK_VOP0:
+	case DCLK_VOP0_SRC:
+		con = readl(&cru->clksel_con[111]);
+		div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT;
+		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
+		break;
+	case DCLK_VOP1:
+	case DCLK_VOP1_SRC:
+		con = readl(&cru->clksel_con[111]);
+		div = (con & DCLK1_VOP_SRC_DIV_MASK) >> DCLK1_VOP_SRC_DIV_SHIFT;
+		sel = (con & DCLK1_VOP_SRC_SEL_MASK) >> DCLK1_VOP_SRC_SEL_SHIFT;
+		break;
+	case DCLK_VOP2:
+	case DCLK_VOP2_SRC:
+		con = readl(&cru->clksel_con[112]);
+		div = (con & DCLK2_VOP_SRC_DIV_MASK) >> DCLK2_VOP_SRC_DIV_SHIFT;
+		sel = (con & DCLK2_VOP_SRC_SEL_MASK) >> DCLK2_VOP_SRC_SEL_SHIFT;
+		break;
+	case DCLK_VOP3:
+		con = readl(&cru->clksel_con[113]);
+		div = (con & DCLK3_VOP_SRC_DIV_MASK) >> DCLK3_VOP_SRC_DIV_SHIFT;
+		sel = (con & DCLK3_VOP_SRC_SEL_MASK) >> DCLK3_VOP_SRC_SEL_SHIFT;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	if (sel == DCLK_VOP_SRC_SEL_AUPLL)
+		parent = priv->aupll_hz;
+	else if (sel == DCLK_VOP_SRC_SEL_V0PLL)
+		parent = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL],
+					       priv->cru, V0PLL);
+	else if (sel == DCLK_VOP_SRC_SEL_GPLL)
+		parent = priv->gpll_hz;
+	else if (sel == DCLK_VOP_SRC_SEL_CPLL)
+		parent = priv->cpll_hz;
+	else
+		return -ENOENT;
+
+	return DIV_TO_RATE(parent, div);
+}
+
+#define RK3588_VOP_PLL_LIMIT_FREQ 600000000
+
+static ulong rk3588_dclk_vop_set_clk(struct rk3588_clk_priv *priv,
+				     ulong clk_id, ulong rate)
+{
+	struct rk3588_cru *cru = priv->cru;
+	ulong pll_rate, now, best_rate = 0;
+	u32 i, conid, con, sel, div, best_div = 0, best_sel = 0;
+	u32 mask, div_shift, sel_shift;
+
+	switch (clk_id) {
+	case DCLK_VOP0:
+	case DCLK_VOP0_SRC:
+		conid = 111;
+		con = readl(&cru->clksel_con[111]);
+		sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
+		mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK;
+		div_shift = DCLK0_VOP_SRC_DIV_SHIFT;
+		sel_shift = DCLK0_VOP_SRC_SEL_SHIFT;
+		break;
+	case DCLK_VOP1:
+	case DCLK_VOP1_SRC:
+		conid = 111;
+		con = readl(&cru->clksel_con[111]);
+		sel = (con & DCLK1_VOP_SRC_SEL_MASK) >> DCLK1_VOP_SRC_SEL_SHIFT;
+		mask = DCLK1_VOP_SRC_SEL_MASK | DCLK1_VOP_SRC_DIV_MASK;
+		div_shift = DCLK1_VOP_SRC_DIV_SHIFT;
+		sel_shift = DCLK1_VOP_SRC_SEL_SHIFT;
+		break;
+	case DCLK_VOP2:
+	case DCLK_VOP2_SRC:
+		conid = 112;
+		con = readl(&cru->clksel_con[112]);
+		sel = (con & DCLK2_VOP_SRC_SEL_MASK) >> DCLK2_VOP_SRC_SEL_SHIFT;
+		mask = DCLK2_VOP_SRC_SEL_MASK | DCLK2_VOP_SRC_DIV_MASK;
+		div_shift = DCLK2_VOP_SRC_DIV_SHIFT;
+		sel_shift = DCLK2_VOP_SRC_SEL_SHIFT;
+		break;
+	case DCLK_VOP3:
+		conid = 113;
+		con = readl(&cru->clksel_con[113]);
+		sel = (con & DCLK3_VOP_SRC_SEL_MASK) >> DCLK3_VOP_SRC_SEL_SHIFT;
+		mask = DCLK3_VOP_SRC_SEL_MASK | DCLK3_VOP_SRC_DIV_MASK;
+		div_shift = DCLK3_VOP_SRC_DIV_SHIFT;
+		sel_shift = DCLK3_VOP_SRC_SEL_SHIFT;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	if (sel == DCLK_VOP_SRC_SEL_V0PLL) {
+		div = DIV_ROUND_UP(RK3588_VOP_PLL_LIMIT_FREQ, rate);
+		rk_clrsetreg(&cru->clksel_con[conid],
+			     mask,
+			     DCLK_VOP_SRC_SEL_V0PLL << sel_shift |
+			     ((div - 1) << div_shift));
+		rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL],
+				      priv->cru, V0PLL, div * rate);
+	} else {
+		for (i = 0; i <= DCLK_VOP_SRC_SEL_AUPLL; i++) {
+			switch (i) {
+			case DCLK_VOP_SRC_SEL_GPLL:
+				pll_rate = priv->gpll_hz;
+				break;
+			case DCLK_VOP_SRC_SEL_CPLL:
+				pll_rate = priv->cpll_hz;
+				break;
+			case DCLK_VOP_SRC_SEL_AUPLL:
+				pll_rate = priv->aupll_hz;
+				break;
+			case DCLK_VOP_SRC_SEL_V0PLL:
+				pll_rate = 0;
+				break;
+			default:
+				printf("do not support this vop pll sel\n");
+				return -EINVAL;
+			}
+
+			div = DIV_ROUND_UP(pll_rate, rate);
+			if (div > 255)
+				continue;
+			now = pll_rate / div;
+			if (abs(rate - now) < abs(rate - best_rate)) {
+				best_rate = now;
+				best_div = div;
+				best_sel = i;
+			}
+			debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
+			      pll_rate, best_rate, best_div, best_sel);
+		}
+
+		if (best_rate) {
+			rk_clrsetreg(&cru->clksel_con[conid],
+				     mask,
+				     best_sel << sel_shift |
+				     (best_div - 1) << div_shift);
+		} else {
+			printf("do not support this vop freq %lu\n", rate);
+			return -EINVAL;
+		}
+	}
+	return rk3588_dclk_vop_get_clk(priv, clk_id);
+}
+
+static ulong rk3588_gmac_get_clk(struct rk3588_clk_priv *priv, ulong clk_id)
+{
+	struct rk3588_cru *cru = priv->cru;
+	u32 con, div;
+
+	switch (clk_id) {
+	case CLK_GMAC0_PTP_REF:
+		con = readl(&cru->clksel_con[81]);
+		div = (con & CLK_GMAC0_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT;
+		return DIV_TO_RATE(priv->cpll_hz, div);
+	case CLK_GMAC1_PTP_REF:
+		con = readl(&cru->clksel_con[81]);
+		div = (con & CLK_GMAC1_PTP_DIV_MASK) >> CLK_GMAC1_PTP_DIV_SHIFT;
+		return DIV_TO_RATE(priv->cpll_hz, div);
+	case CLK_GMAC_125M:
+		con = readl(&cru->clksel_con[83]);
+		div = (con & CLK_GMAC_125M_DIV_MASK) >> CLK_GMAC_125M_DIV_SHIFT;
+		return DIV_TO_RATE(priv->cpll_hz, div);
+	case CLK_GMAC_50M:
+		con = readl(&cru->clksel_con[84]);
+		div = (con & CLK_GMAC_50M_DIV_MASK) >> CLK_GMAC_50M_DIV_SHIFT;
+		return DIV_TO_RATE(priv->cpll_hz, div);
+	default:
+		return -ENOENT;
+	}
+}
+
+static ulong rk3588_gmac_set_clk(struct rk3588_clk_priv *priv,
+				 ulong clk_id, ulong rate)
+{
+	struct rk3588_cru *cru = priv->cru;
+	int div;
+
+	div = DIV_ROUND_UP(priv->cpll_hz, rate);
+
+	switch (clk_id) {
+	case CLK_GMAC0_PTP_REF:
+		rk_clrsetreg(&cru->clksel_con[81],
+			     CLK_GMAC0_PTP_DIV_MASK | CLK_GMAC0_PTP_SEL_MASK,
+			     CLK_GMAC0_PTP_SEL_CPLL << CLK_GMAC0_PTP_SEL_SHIFT |
+			     (div - 1) << CLK_GMAC0_PTP_DIV_SHIFT);
+		break;
+	case CLK_GMAC1_PTP_REF:
+		rk_clrsetreg(&cru->clksel_con[81],
+			     CLK_GMAC1_PTP_DIV_MASK | CLK_GMAC1_PTP_SEL_MASK,
+			     CLK_GMAC1_PTP_SEL_CPLL << CLK_GMAC1_PTP_SEL_SHIFT |
+			     (div - 1) << CLK_GMAC1_PTP_DIV_SHIFT);
+		break;
+
+	case CLK_GMAC_125M:
+		rk_clrsetreg(&cru->clksel_con[83],
+			     CLK_GMAC_125M_DIV_MASK | CLK_GMAC_125M_SEL_MASK,
+			     CLK_GMAC_125M_SEL_CPLL << CLK_GMAC_125M_SEL_SHIFT |
+			     (div - 1) << CLK_GMAC_125M_DIV_SHIFT);
+		break;
+	case CLK_GMAC_50M:
+		rk_clrsetreg(&cru->clksel_con[84],
+			     CLK_GMAC_50M_DIV_MASK | CLK_GMAC_50M_SEL_MASK,
+			     CLK_GMAC_50M_SEL_CPLL << CLK_GMAC_50M_SEL_SHIFT |
+			     (div - 1) << CLK_GMAC_50M_DIV_SHIFT);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rk3588_gmac_get_clk(priv, clk_id);
+}
+
+static ulong rk3588_uart_get_rate(struct rk3588_clk_priv *priv, ulong clk_id)
+{
+	struct rk3588_cru *cru = priv->cru;
+	u32 reg, con, fracdiv, div, src, p_src, p_rate;
+	unsigned long m, n;
+
+	switch (clk_id) {
+	case SCLK_UART1:
+		reg = 41;
+		break;
+	case SCLK_UART2:
+		reg = 43;
+		break;
+	case SCLK_UART3:
+		reg = 45;
+		break;
+	case SCLK_UART4:
+		reg = 47;
+		break;
+	case SCLK_UART5:
+		reg = 49;
+		break;
+	case SCLK_UART6:
+		reg = 51;
+		break;
+	case SCLK_UART7:
+		reg = 53;
+		break;
+	case SCLK_UART8:
+		reg = 55;
+		break;
+	case SCLK_UART9:
+		reg = 57;
+		break;
+	default:
+		return -ENOENT;
+	}
+	con = readl(&cru->clksel_con[reg + 2]);
+	src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
+	con = readl(&cru->clksel_con[reg]);
+	div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
+	p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
+	if (p_src == CLK_UART_SRC_SEL_GPLL)
+		p_rate = priv->gpll_hz;
+	else
+		p_rate = priv->cpll_hz;
+
+	if (src == CLK_UART_SEL_SRC) {
+		return DIV_TO_RATE(p_rate, div);
+	} else if (src == CLK_UART_SEL_FRAC) {
+		fracdiv = readl(&cru->clksel_con[reg + 1]);
+		n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
+		n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
+		m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
+		m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
+		return DIV_TO_RATE(p_rate, div) * n / m;
+	} else {
+		return OSC_HZ;
+	}
+}
+
+static ulong rk3588_uart_set_rate(struct rk3588_clk_priv *priv,
+				  ulong clk_id, ulong rate)
+{
+	struct rk3588_cru *cru = priv->cru;
+	u32 reg, clk_src, uart_src, div;
+	unsigned long m = 0, n = 0, val;
+
+	if (priv->gpll_hz % rate == 0) {
+		clk_src = CLK_UART_SRC_SEL_GPLL;
+		uart_src = CLK_UART_SEL_SRC;
+		div = DIV_ROUND_UP(priv->gpll_hz, rate);
+	} else if (priv->cpll_hz % rate == 0) {
+		clk_src = CLK_UART_SRC_SEL_CPLL;
+		uart_src = CLK_UART_SEL_SRC;
+		div = DIV_ROUND_UP(priv->gpll_hz, rate);
+	} else if (rate == OSC_HZ) {
+		clk_src = CLK_UART_SRC_SEL_GPLL;
+		uart_src = CLK_UART_SEL_XIN24M;
+		div = 2;
+	} else {
+		clk_src = CLK_UART_SRC_SEL_GPLL;
+		uart_src = CLK_UART_SEL_FRAC;
+		div = 2;
+		rational_best_approximation(rate, priv->gpll_hz / div,
+					    GENMASK(16 - 1, 0),
+					    GENMASK(16 - 1, 0),
+					    &m, &n);
+	}
+
+	switch (clk_id) {
+	case SCLK_UART1:
+		reg = 41;
+		break;
+	case SCLK_UART2:
+		reg = 43;
+		break;
+	case SCLK_UART3:
+		reg = 45;
+		break;
+	case SCLK_UART4:
+		reg = 47;
+		break;
+	case SCLK_UART5:
+		reg = 49;
+		break;
+	case SCLK_UART6:
+		reg = 51;
+		break;
+	case SCLK_UART7:
+		reg = 53;
+		break;
+	case SCLK_UART8:
+		reg = 55;
+		break;
+	case SCLK_UART9:
+		reg = 57;
+		break;
+	default:
+		return -ENOENT;
+	}
+	rk_clrsetreg(&cru->clksel_con[reg],
+		     CLK_UART_SRC_SEL_MASK |
+		     CLK_UART_SRC_DIV_MASK,
+		     (clk_src << CLK_UART_SRC_SEL_SHIFT) |
+		     ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
+	rk_clrsetreg(&cru->clksel_con[reg + 2],
+		     CLK_UART_SEL_MASK,
+		     (uart_src << CLK_UART_SEL_SHIFT));
+	if (m && n) {
+		val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
+		writel(val, &cru->clksel_con[reg + 1]);
+	}
+
+	return rk3588_uart_get_rate(priv, clk_id);
+}
+
+static ulong rk3588_pciephy_get_rate(struct rk3588_clk_priv *priv, ulong clk_id)
+{
+	struct rk3588_cru *cru = priv->cru;
+	u32 con, div, src;
+
+	switch (clk_id) {
+	case CLK_REF_PIPE_PHY0:
+		con = readl(&cru->clksel_con[177]);
+		src = (con & CLK_PCIE_PHY0_REF_SEL_MASK) >> CLK_PCIE_PHY0_REF_SEL_SHIFT;
+		con = readl(&cru->clksel_con[176]);
+		div = (con & CLK_PCIE_PHY0_PLL_DIV_MASK) >> CLK_PCIE_PHY0_PLL_DIV_SHIFT;
+		break;
+	case CLK_REF_PIPE_PHY1:
+		con = readl(&cru->clksel_con[177]);
+		src = (con & CLK_PCIE_PHY1_REF_SEL_MASK) >> CLK_PCIE_PHY1_REF_SEL_SHIFT;
+		con = readl(&cru->clksel_con[176]);
+		div = (con & CLK_PCIE_PHY1_PLL_DIV_MASK) >> CLK_PCIE_PHY1_PLL_DIV_SHIFT;
+		break;
+	case CLK_REF_PIPE_PHY2:
+		con = readl(&cru->clksel_con[177]);
+		src = (con & CLK_PCIE_PHY2_REF_SEL_MASK) >> CLK_PCIE_PHY2_REF_SEL_SHIFT;
+		div = (con & CLK_PCIE_PHY2_PLL_DIV_MASK) >> CLK_PCIE_PHY2_PLL_DIV_SHIFT;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	if (src == CLK_PCIE_PHY_REF_SEL_PPLL)
+		return DIV_TO_RATE(priv->ppll_hz, div);
+	else
+		return OSC_HZ;
+}
+
+static ulong rk3588_pciephy_set_rate(struct rk3588_clk_priv *priv,
+				     ulong clk_id, ulong rate)
+{
+	struct rk3588_cru *cru = priv->cru;
+	u32 clk_src, div;
+
+	if (rate == OSC_HZ) {
+		clk_src = CLK_PCIE_PHY_REF_SEL_24M;
+		div = 1;
+	} else {
+		clk_src = CLK_PCIE_PHY_REF_SEL_PPLL;
+		div = DIV_ROUND_UP(priv->ppll_hz, rate);
+	}
+
+	switch (clk_id) {
+	case CLK_REF_PIPE_PHY0:
+		rk_clrsetreg(&cru->clksel_con[177], CLK_PCIE_PHY0_REF_SEL_MASK,
+			     (clk_src << CLK_PCIE_PHY0_REF_SEL_SHIFT));
+		rk_clrsetreg(&cru->clksel_con[176], CLK_PCIE_PHY0_PLL_DIV_MASK,
+			     ((div - 1) << CLK_PCIE_PHY0_PLL_DIV_SHIFT));
+		break;
+	case CLK_REF_PIPE_PHY1:
+		rk_clrsetreg(&cru->clksel_con[177], CLK_PCIE_PHY1_REF_SEL_MASK,
+			     (clk_src << CLK_PCIE_PHY1_REF_SEL_SHIFT));
+		rk_clrsetreg(&cru->clksel_con[176], CLK_PCIE_PHY1_PLL_DIV_MASK,
+			     ((div - 1) << CLK_PCIE_PHY1_PLL_DIV_SHIFT));
+		break;
+	case CLK_REF_PIPE_PHY2:
+		rk_clrsetreg(&cru->clksel_con[177], CLK_PCIE_PHY2_REF_SEL_MASK |
+			     CLK_PCIE_PHY2_PLL_DIV_MASK,
+			     (clk_src << CLK_PCIE_PHY2_REF_SEL_SHIFT) |
+			     ((div - 1) << CLK_PCIE_PHY2_PLL_DIV_SHIFT));
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rk3588_pciephy_get_rate(priv, clk_id);
+}
+#endif
+
+static ulong rk3588_clk_get_rate(struct clk *clk)
+{
+	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong rate = 0;
+
+	if (!priv->gpll_hz) {
+		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
+		return -ENOENT;
+	}
+
+	if (!priv->ppll_hz) {
+		priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
+						      priv->cru, PPLL);
+	}
+
+	switch (clk->id) {
+	case PLL_LPLL:
+		rate = rockchip_pll_get_rate(&rk3588_pll_clks[LPLL], priv->cru,
+					     LPLL);
+		break;
+	case PLL_B0PLL:
+		rate = rockchip_pll_get_rate(&rk3588_pll_clks[B0PLL], priv->cru,
+					     B0PLL);
+		break;
+	case PLL_B1PLL:
+		rate = rockchip_pll_get_rate(&rk3588_pll_clks[B1PLL], priv->cru,
+					     B1PLL);
+		break;
+	case PLL_GPLL:
+		rate = rockchip_pll_get_rate(&rk3588_pll_clks[GPLL], priv->cru,
+					     GPLL);
+		break;
+	case PLL_CPLL:
+		rate = rockchip_pll_get_rate(&rk3588_pll_clks[CPLL], priv->cru,
+					     CPLL);
+		break;
+	case PLL_NPLL:
+		rate = rockchip_pll_get_rate(&rk3588_pll_clks[NPLL], priv->cru,
+					     NPLL);
+		break;
+	case PLL_V0PLL:
+		rate = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL], priv->cru,
+					     V0PLL);
+		break;
+	case PLL_AUPLL:
+		rate = rockchip_pll_get_rate(&rk3588_pll_clks[AUPLL], priv->cru,
+					     AUPLL);
+		break;
+	case PLL_PPLL:
+		rate = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL], priv->cru,
+					     PPLL);
+		break;
+	case ACLK_CENTER_ROOT:
+	case PCLK_CENTER_ROOT:
+	case HCLK_CENTER_ROOT:
+	case ACLK_CENTER_LOW_ROOT:
+		rate = rk3588_center_get_clk(priv, clk->id);
+		break;
+	case ACLK_TOP_ROOT:
+	case PCLK_TOP_ROOT:
+	case ACLK_LOW_TOP_ROOT:
+		rate = rk3588_top_get_clk(priv, clk->id);
+		break;
+	case CLK_I2C0:
+	case CLK_I2C1:
+	case CLK_I2C2:
+	case CLK_I2C3:
+	case CLK_I2C4:
+	case CLK_I2C5:
+	case CLK_I2C6:
+	case CLK_I2C7:
+	case CLK_I2C8:
+		rate = rk3588_i2c_get_clk(priv, clk->id);
+		break;
+	case CLK_SPI0:
+	case CLK_SPI1:
+	case CLK_SPI2:
+	case CLK_SPI3:
+	case CLK_SPI4:
+		rate = rk3588_spi_get_clk(priv, clk->id);
+		break;
+	case CLK_PWM1:
+	case CLK_PWM2:
+	case CLK_PWM3:
+	case CLK_PMU1PWM:
+		rate = rk3588_pwm_get_clk(priv, clk->id);
+		break;
+	case CLK_SARADC:
+	case CLK_TSADC:
+		rate = rk3588_adc_get_clk(priv, clk->id);
+		break;
+	case CCLK_SRC_SDIO:
+	case CCLK_EMMC:
+	case BCLK_EMMC:
+	case SCLK_SFC:
+	case DCLK_DECOM:
+		rate = rk3588_mmc_get_clk(priv, clk->id);
+		break;
+	case TCLK_WDT0:
+		rate = OSC_HZ;
+		break;
+#ifndef CONFIG_SPL_BUILD
+	case CLK_AUX16M_0:
+	case CLK_AUX16M_1:
+		rk3588_aux16m_get_clk(priv, clk->id);
+		break;
+	case ACLK_VOP_ROOT:
+	case ACLK_VOP:
+	case ACLK_VOP_LOW_ROOT:
+	case HCLK_VOP_ROOT:
+		rate = rk3588_aclk_vop_get_clk(priv, clk->id);
+		break;
+	case DCLK_VOP0:
+	case DCLK_VOP0_SRC:
+	case DCLK_VOP1:
+	case DCLK_VOP1_SRC:
+	case DCLK_VOP2:
+	case DCLK_VOP2_SRC:
+	case DCLK_VOP3:
+		rate = rk3588_dclk_vop_get_clk(priv, clk->id);
+		break;
+	case CLK_GMAC0_PTP_REF:
+	case CLK_GMAC1_PTP_REF:
+	case CLK_GMAC_125M:
+	case CLK_GMAC_50M:
+		rate = rk3588_gmac_get_clk(priv, clk->id);
+		break;
+	case SCLK_UART1:
+	case SCLK_UART2:
+	case SCLK_UART3:
+	case SCLK_UART4:
+	case SCLK_UART5:
+	case SCLK_UART6:
+	case SCLK_UART7:
+	case SCLK_UART8:
+	case SCLK_UART9:
+		rate = rk3588_uart_get_rate(priv, clk->id);
+		break;
+	case CLK_REF_PIPE_PHY0:
+	case CLK_REF_PIPE_PHY1:
+	case CLK_REF_PIPE_PHY2:
+		rate = rk3588_pciephy_get_rate(priv, clk->id);
+		break;
+#endif
+	default:
+		return -ENOENT;
+	}
+
+	return rate;
+};
+
+static ulong rk3588_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong ret = 0;
+
+	if (!priv->gpll_hz) {
+		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
+		return -ENOENT;
+	}
+
+	if (!priv->ppll_hz) {
+		priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
+						      priv->cru, PPLL);
+	}
+
+	switch (clk->id) {
+	case PLL_CPLL:
+		ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru,
+					    CPLL, rate);
+		priv->cpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[CPLL],
+						      priv->cru, CPLL);
+		break;
+	case PLL_GPLL:
+		ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru,
+					    GPLL, rate);
+		priv->gpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[GPLL],
+						      priv->cru, GPLL);
+		break;
+	case PLL_NPLL:
+		ret = rockchip_pll_set_rate(&rk3588_pll_clks[NPLL], priv->cru,
+					    NPLL, rate);
+		break;
+	case PLL_V0PLL:
+		ret = rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL], priv->cru,
+					    V0PLL, rate);
+		priv->v0pll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL],
+						       priv->cru, V0PLL);
+		break;
+	case PLL_AUPLL:
+		ret = rockchip_pll_set_rate(&rk3588_pll_clks[AUPLL], priv->cru,
+					    AUPLL, rate);
+		priv->aupll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[AUPLL],
+						       priv->cru, AUPLL);
+		break;
+	case PLL_PPLL:
+		ret = rockchip_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru,
+					    PPLL, rate);
+		priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
+						      priv->cru, PPLL);
+		break;
+	case ACLK_CENTER_ROOT:
+	case PCLK_CENTER_ROOT:
+	case HCLK_CENTER_ROOT:
+	case ACLK_CENTER_LOW_ROOT:
+		ret = rk3588_center_set_clk(priv, clk->id, rate);
+		break;
+	case ACLK_TOP_ROOT:
+	case PCLK_TOP_ROOT:
+	case ACLK_LOW_TOP_ROOT:
+		ret = rk3588_top_set_clk(priv, clk->id, rate);
+		break;
+	case CLK_I2C0:
+	case CLK_I2C1:
+	case CLK_I2C2:
+	case CLK_I2C3:
+	case CLK_I2C4:
+	case CLK_I2C5:
+	case CLK_I2C6:
+	case CLK_I2C7:
+	case CLK_I2C8:
+		ret = rk3588_i2c_set_clk(priv, clk->id, rate);
+		break;
+	case CLK_SPI0:
+	case CLK_SPI1:
+	case CLK_SPI2:
+	case CLK_SPI3:
+	case CLK_SPI4:
+		ret = rk3588_spi_set_clk(priv, clk->id, rate);
+		break;
+	case CLK_PWM1:
+	case CLK_PWM2:
+	case CLK_PWM3:
+	case CLK_PMU1PWM:
+		ret = rk3588_pwm_set_clk(priv, clk->id, rate);
+		break;
+	case CLK_SARADC:
+	case CLK_TSADC:
+		ret = rk3588_adc_set_clk(priv, clk->id, rate);
+		break;
+	case CCLK_SRC_SDIO:
+	case CCLK_EMMC:
+	case BCLK_EMMC:
+	case SCLK_SFC:
+	case DCLK_DECOM:
+		ret = rk3588_mmc_set_clk(priv, clk->id, rate);
+		break;
+	case TCLK_WDT0:
+		ret = OSC_HZ;
+		break;
+#ifndef CONFIG_SPL_BUILD
+	case CLK_AUX16M_0:
+	case CLK_AUX16M_1:
+		rk3588_aux16m_set_clk(priv, clk->id, rate);
+		break;
+	case ACLK_VOP_ROOT:
+	case ACLK_VOP:
+	case ACLK_VOP_LOW_ROOT:
+	case HCLK_VOP_ROOT:
+		ret = rk3588_aclk_vop_set_clk(priv, clk->id, rate);
+		break;
+	case DCLK_VOP0:
+	case DCLK_VOP0_SRC:
+	case DCLK_VOP1:
+	case DCLK_VOP1_SRC:
+	case DCLK_VOP2:
+	case DCLK_VOP2_SRC:
+	case DCLK_VOP3:
+		ret = rk3588_dclk_vop_set_clk(priv, clk->id, rate);
+		break;
+	case CLK_GMAC0_PTP_REF:
+	case CLK_GMAC1_PTP_REF:
+	case CLK_GMAC_125M:
+	case CLK_GMAC_50M:
+		ret = rk3588_gmac_set_clk(priv, clk->id, rate);
+		break;
+	case SCLK_UART1:
+	case SCLK_UART2:
+	case SCLK_UART3:
+	case SCLK_UART4:
+	case SCLK_UART5:
+	case SCLK_UART6:
+	case SCLK_UART7:
+	case SCLK_UART8:
+	case SCLK_UART9:
+		ret = rk3588_uart_set_rate(priv, clk->id, rate);
+		break;
+	case CLK_REF_PIPE_PHY0:
+	case CLK_REF_PIPE_PHY1:
+	case CLK_REF_PIPE_PHY2:
+		ret = rk3588_pciephy_set_rate(priv, clk->id, rate);
+		break;
+#endif
+	default:
+		return -ENOENT;
+	}
+
+	return ret;
+};
+
+#define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
+#define ROCKCHIP_MMC_DEGREE_MASK	0x3
+#define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
+#define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
+
+#define PSECS_PER_SEC 1000000000000LL
+/*
+ * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
+ * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
+ */
+#define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
+
+#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
+static int __maybe_unused rk3588_dclk_vop_set_parent(struct clk *clk,
+						     struct clk *parent)
+{
+	struct rk3588_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3588_cru *cru = priv->cru;
+	u32 sel;
+	const char *clock_dev_name = parent->dev->name;
+
+	if (parent->id == PLL_V0PLL)
+		sel = 2;
+	else if (parent->id == PLL_GPLL)
+		sel = 0;
+	else if (parent->id == PLL_CPLL)
+		sel = 1;
+	else
+		sel = 3;
+
+	switch (clk->id) {
+	case DCLK_VOP0_SRC:
+		rk_clrsetreg(&cru->clksel_con[111], DCLK0_VOP_SRC_SEL_MASK,
+			     sel << DCLK0_VOP_SRC_SEL_SHIFT);
+		break;
+	case DCLK_VOP1_SRC:
+		rk_clrsetreg(&cru->clksel_con[111], DCLK1_VOP_SRC_SEL_MASK,
+			     sel << DCLK1_VOP_SRC_SEL_SHIFT);
+		break;
+	case DCLK_VOP2_SRC:
+		rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SRC_SEL_MASK,
+			     sel << DCLK2_VOP_SRC_SEL_SHIFT);
+		break;
+	case DCLK_VOP3:
+		rk_clrsetreg(&cru->clksel_con[113], DCLK3_VOP_SRC_SEL_MASK,
+			     sel << DCLK3_VOP_SRC_SEL_SHIFT);
+		break;
+	case DCLK_VOP0:
+		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
+			sel = 1;
+		else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
+			sel = 2;
+		else
+			sel = 0;
+		rk_clrsetreg(&cru->clksel_con[112], DCLK0_VOP_SEL_MASK,
+			     sel << DCLK0_VOP_SEL_SHIFT);
+		break;
+	case DCLK_VOP1:
+		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
+			sel = 1;
+		else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
+			sel = 2;
+		else
+			sel = 0;
+		rk_clrsetreg(&cru->clksel_con[112], DCLK1_VOP_SEL_MASK,
+			     sel << DCLK1_VOP_SEL_SHIFT);
+		break;
+	case DCLK_VOP2:
+		if (!strcmp(clock_dev_name, "hdmiphypll_clk0"))
+			sel = 1;
+		else if (!strcmp(clock_dev_name, "hdmiphypll_clk1"))
+			sel = 2;
+		else
+			sel = 0;
+		rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SEL_MASK,
+			     sel << DCLK2_VOP_SEL_SHIFT);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int rk3588_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	switch (clk->id) {
+	case DCLK_VOP0_SRC:
+	case DCLK_VOP1_SRC:
+	case DCLK_VOP2_SRC:
+	case DCLK_VOP0:
+	case DCLK_VOP1:
+	case DCLK_VOP2:
+	case DCLK_VOP3:
+		return rk3588_dclk_vop_set_parent(clk, parent);
+	default:
+		return -ENOENT;
+	}
+
+	return 0;
+}
+#endif
+
+static struct clk_ops rk3588_clk_ops = {
+	.get_rate = rk3588_clk_get_rate,
+	.set_rate = rk3588_clk_set_rate,
+#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
+	.set_parent = rk3588_clk_set_parent,
+#endif
+};
+
+static void rk3588_clk_init(struct rk3588_clk_priv *priv)
+{
+	int ret, div;
+
+	div = DIV_ROUND_UP(GPLL_HZ, 300 * MHz);
+	rk_clrsetreg(&priv->cru->clksel_con[38],
+		     ACLK_BUS_ROOT_SEL_MASK |
+		     ACLK_BUS_ROOT_DIV_MASK,
+		     div << ACLK_BUS_ROOT_DIV_SHIFT);
+
+	if (priv->cpll_hz != CPLL_HZ) {
+		ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru,
+					    CPLL, CPLL_HZ);
+		if (!ret)
+			priv->cpll_hz = CPLL_HZ;
+	}
+	if (priv->gpll_hz != GPLL_HZ) {
+		ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru,
+					    GPLL, GPLL_HZ);
+		if (!ret)
+			priv->gpll_hz = GPLL_HZ;
+	}
+
+#ifdef CONFIG_PCI
+	if (priv->ppll_hz != PPLL_HZ) {
+		ret = rockchip_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru,
+					    PPLL, PPLL_HZ);
+		priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL],
+						      priv->cru, PPLL);
+	}
+#endif
+	rk_clrsetreg(&priv->cru->clksel_con[9],
+		     ACLK_TOP_S400_SEL_MASK |
+		     ACLK_TOP_S200_SEL_MASK,
+		     (ACLK_TOP_S400_SEL_400M << ACLK_TOP_S400_SEL_SHIFT) |
+		     (ACLK_TOP_S200_SEL_200M << ACLK_TOP_S200_SEL_SHIFT));
+}
+
+static int rk3588_clk_probe(struct udevice *dev)
+{
+	struct rk3588_clk_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	priv->sync_kernel = false;
+
+#ifdef CONFIG_SPL_BUILD
+	rockchip_pll_set_rate(&rk3588_pll_clks[B0PLL], priv->cru,
+			      B0PLL, LPLL_HZ);
+	rockchip_pll_set_rate(&rk3588_pll_clks[B1PLL], priv->cru,
+			      B1PLL, LPLL_HZ);
+	if (!priv->armclk_enter_hz) {
+		ret = rockchip_pll_set_rate(&rk3588_pll_clks[LPLL], priv->cru,
+					    LPLL, LPLL_HZ);
+		priv->armclk_enter_hz =
+			rockchip_pll_get_rate(&rk3588_pll_clks[LPLL],
+					      priv->cru, LPLL);
+		priv->armclk_init_hz = priv->armclk_enter_hz;
+	}
+#endif
+
+	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	if (IS_ERR(priv->grf))
+		return PTR_ERR(priv->grf);
+
+	rk3588_clk_init(priv);
+
+	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
+	ret = clk_set_defaults(dev, 1);
+	if (ret)
+		debug("%s clk_set_defaults failed %d\n", __func__, ret);
+	else
+		priv->sync_kernel = true;
+
+	return 0;
+}
+
+static int rk3588_clk_ofdata_to_platdata(struct udevice *dev)
+{
+	struct rk3588_clk_priv *priv = dev_get_priv(dev);
+
+	priv->cru = dev_read_addr_ptr(dev);
+
+	return 0;
+}
+
+static int rk3588_clk_bind(struct udevice *dev)
+{
+	int ret;
+	struct udevice *sys_child;
+	struct sysreset_reg *priv;
+
+	/* The reset driver does not have a device node, so bind it here */
+	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
+				 &sys_child);
+	if (ret) {
+		debug("Warning: No sysreset driver: ret=%d\n", ret);
+	} else {
+		priv = malloc(sizeof(struct sysreset_reg));
+		priv->glb_srst_fst_value = offsetof(struct rk3588_cru,
+						    glb_srst_fst);
+		priv->glb_srst_snd_value = offsetof(struct rk3588_cru,
+						    glb_srsr_snd);
+		dev_set_priv(sys_child, priv);
+	}
+
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
+	ret = offsetof(struct rk3588_cru, softrst_con[0]);
+	ret = rockchip_reset_bind(dev, ret, 49158);
+	if (ret)
+		debug("Warning: software reset driver bind faile\n");
+#endif
+
+	return 0;
+}
+
+static const struct udevice_id rk3588_clk_ids[] = {
+	{ .compatible = "rockchip,rk3588-cru" },
+	{ }
+};
+
+U_BOOT_DRIVER(rockchip_rk3588_cru) = {
+	.name		= "rockchip_rk3588_cru",
+	.id		= UCLASS_CLK,
+	.of_match	= rk3588_clk_ids,
+	.priv_auto	= sizeof(struct rk3588_clk_priv),
+	.of_to_plat	= rk3588_clk_ofdata_to_platdata,
+	.ops		= &rk3588_clk_ops,
+	.bind		= rk3588_clk_bind,
+	.probe		= rk3588_clk_probe,
+};
diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c
index 68f3015..f7ad4d6 100644
--- a/drivers/gpio/rk_gpio.c
+++ b/drivers/gpio/rk_gpio.c
@@ -142,6 +142,7 @@
 {
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
+	struct ofnode_phandle_args args;
 	char *end;
 	int ret;
 
@@ -150,9 +151,22 @@
 	if (ret)
 		return ret;
 
-	uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK;
-	end = strrchr(dev->name, '@');
-	priv->bank = trailing_strtoln(dev->name, end);
+	/*
+	 * If "gpio-ranges" is present in the devicetree use it to parse
+	 * the GPIO bank ID, otherwise use the legacy method.
+	 */
+	ret = ofnode_parse_phandle_with_args(dev_ofnode(dev),
+					     "gpio-ranges", NULL, 3,
+					     0, &args);
+	if (!ret || ret != -ENOENT) {
+		uc_priv->gpio_count = args.args[2];
+		priv->bank = args.args[1] / args.args[2];
+	} else {
+		uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK;
+		end = strrchr(dev->name, '@');
+		priv->bank = trailing_strtoln(dev->name, end);
+	}
+
 	priv->name[0] = 'A' + priv->bank;
 	uc_priv->bank_name = priv->name;
 
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index b07261d..b5707a1 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -92,10 +92,6 @@
 	  or through child-nodes that are generated based on the e-fuse map
 	  retrieved from the DTS.
 
-	  This driver currently supports the RK3399 only, but can easily be
-	  extended (by porting the read function from the Linux kernel sources)
-	  to support other recent Rockchip devices.
-
 config ROCKCHIP_OTP
 	bool "Rockchip OTP Support"
 	depends on MISC
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c
index 083ee65..60931a5 100644
--- a/drivers/misc/rockchip-efuse.c
+++ b/drivers/misc/rockchip-efuse.c
@@ -13,50 +13,57 @@
 #include <dm.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/iopoll.h>
+#include <malloc.h>
 #include <misc.h>
 
-#define RK3399_A_SHIFT          16
-#define RK3399_A_MASK           0x3ff
-#define RK3399_NFUSES           32
-#define RK3399_BYTES_PER_FUSE   4
-#define RK3399_STROBSFTSEL      BIT(9)
-#define RK3399_RSB              BIT(7)
-#define RK3399_PD               BIT(5)
-#define RK3399_PGENB            BIT(3)
-#define RK3399_LOAD             BIT(2)
-#define RK3399_STROBE           BIT(1)
-#define RK3399_CSB              BIT(0)
-
-struct rockchip_efuse_regs {
-	u32 ctrl;      /* 0x00  efuse control register */
-	u32 dout;      /* 0x04  efuse data out register */
-	u32 rf;        /* 0x08  efuse redundancy bit used register */
-	u32 _rsvd0;
-	u32 jtag_pass; /* 0x10  JTAG password */
-	u32 strobe_finish_ctrl;
-		       /* 0x14	efuse strobe finish control register */
-};
+#define EFUSE_CTRL		0x0000
+#define RK3036_A_SHIFT		8
+#define RK3036_A_MASK		GENMASK(15, 8)
+#define RK3036_ADDR(n)		((n) << RK3036_A_SHIFT)
+#define RK3128_A_SHIFT		7
+#define RK3128_A_MASK		GENMASK(15, 7)
+#define RK3128_ADDR(n)		((n) << RK3128_A_SHIFT)
+#define RK3288_A_SHIFT		6
+#define RK3288_A_MASK		GENMASK(15, 6)
+#define RK3288_ADDR(n)		((n) << RK3288_A_SHIFT)
+#define RK3399_A_SHIFT		16
+#define RK3399_A_MASK		GENMASK(25, 16)
+#define RK3399_ADDR(n)		((n) << RK3399_A_SHIFT)
+#define RK3399_STROBSFTSEL	BIT(9)
+#define RK3399_RSB		BIT(7)
+#define RK3399_PD		BIT(5)
+#define EFUSE_PGENB		BIT(3)
+#define EFUSE_LOAD		BIT(2)
+#define EFUSE_STROBE		BIT(1)
+#define EFUSE_CSB		BIT(0)
+#define EFUSE_DOUT		0x0004
+#define RK3328_INT_STATUS	0x0018
+#define RK3328_INT_FINISH	BIT(0)
+#define RK3328_DOUT		0x0020
+#define RK3328_AUTO_CTRL	0x0024
+#define RK3328_AUTO_RD		BIT(1)
+#define RK3328_AUTO_ENB		BIT(0)
 
 struct rockchip_efuse_plat {
 	void __iomem *base;
-	struct clk *clk;
 };
 
+struct rockchip_efuse_data {
+	int (*read)(struct udevice *dev, int offset, void *buf, int size);
+	int offset;
+	int size;
+	int block_size;
+};
+
 #if defined(DEBUG)
-static int dump_efuses(struct cmd_tbl *cmdtp, int flag,
-		       int argc, char *const argv[])
+static int dump_efuse(struct cmd_tbl *cmdtp, int flag,
+		      int argc, char *const argv[])
 {
-	/*
-	 * N.B.: This function is tailored towards the RK3399 and assumes that
-	 *       there's always 32 fuses x 32 bits (i.e. 128 bytes of data) to
-	 *       be read.
-	 */
-
 	struct udevice *dev;
-	u8 fuses[128];
-	int ret;
+	u8 data[4];
+	int ret, i;
 
-	/* retrieve the device */
 	ret = uclass_get_device_by_driver(UCLASS_MISC,
 					  DM_DRIVER_GET(rockchip_efuse), &dev);
 	if (ret) {
@@ -64,73 +71,191 @@
 		return 0;
 	}
 
-	ret = misc_read(dev, 0, &fuses, sizeof(fuses));
-	if (ret < 0) {
-		printf("%s: misc_read failed\n", __func__);
-		return 0;
-	}
+	for (i = 0; true; i += sizeof(data)) {
+		ret = misc_read(dev, i, &data, sizeof(data));
+		if (ret < 0)
+			return 0;
 
-	printf("efuse-contents:\n");
-	print_buffer(0, fuses, 1, 128, 16);
+		print_buffer(i, data, 1, sizeof(data), sizeof(data));
+	}
 
 	return 0;
 }
 
 U_BOOT_CMD(
-	rk3399_dump_efuses, 1, 1, dump_efuses,
-	"Dump the content of the efuses",
+	dump_efuse, 1, 1, dump_efuse,
+	"Dump the content of the efuse",
 	""
 );
 #endif
 
-static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset,
+static int rockchip_rk3036_efuse_read(struct udevice *dev, int offset,
 				      void *buf, int size)
 {
-	struct rockchip_efuse_plat *plat = dev_get_plat(dev);
-	struct rockchip_efuse_regs *efuse =
-		(struct rockchip_efuse_regs *)plat->base;
+	struct rockchip_efuse_plat *efuse = dev_get_plat(dev);
+	u8 *buffer = buf;
 
-	unsigned int addr_start, addr_end, addr_offset;
-	u32 out_value;
-	u8  bytes[RK3399_NFUSES * RK3399_BYTES_PER_FUSE];
-	int i = 0;
-	u32 addr;
+	/* Switch to read mode */
+	writel(EFUSE_LOAD, efuse->base + EFUSE_CTRL);
+	udelay(2);
 
-	addr_start = offset / RK3399_BYTES_PER_FUSE;
-	addr_offset = offset % RK3399_BYTES_PER_FUSE;
-	addr_end = DIV_ROUND_UP(offset + size, RK3399_BYTES_PER_FUSE);
+	while (size--) {
+		clrsetbits_le32(efuse->base + EFUSE_CTRL, RK3036_A_MASK,
+				RK3036_ADDR(offset++));
+		udelay(2);
+		setbits_le32(efuse->base + EFUSE_CTRL, EFUSE_STROBE);
+		udelay(2);
+		*buffer++ = (u8)(readl(efuse->base + EFUSE_DOUT) & 0xFF);
+		clrbits_le32(efuse->base + EFUSE_CTRL, EFUSE_STROBE);
+		udelay(2);
+	}
 
-	/* cap to the size of the efuse block */
-	if (addr_end > RK3399_NFUSES)
-		addr_end = RK3399_NFUSES;
+	/* Switch to inactive mode */
+	writel(0x0, efuse->base + EFUSE_CTRL);
 
-	writel(RK3399_LOAD | RK3399_PGENB | RK3399_STROBSFTSEL | RK3399_RSB,
-	       &efuse->ctrl);
-	udelay(1);
-	for (addr = addr_start; addr < addr_end; addr++) {
-		setbits_le32(&efuse->ctrl,
-			     RK3399_STROBE | (addr << RK3399_A_SHIFT));
-		udelay(1);
-		out_value = readl(&efuse->dout);
-		clrbits_le32(&efuse->ctrl, RK3399_STROBE);
-		udelay(1);
+	return 0;
+}
+
+static int rockchip_rk3128_efuse_read(struct udevice *dev, int offset,
+				      void *buf, int size)
+{
+	struct rockchip_efuse_plat *efuse = dev_get_plat(dev);
+	u8 *buffer = buf;
+
+	/* Switch to read mode */
+	writel(EFUSE_LOAD, efuse->base + EFUSE_CTRL);
+	udelay(2);
 
-		memcpy(&bytes[i], &out_value, RK3399_BYTES_PER_FUSE);
-		i += RK3399_BYTES_PER_FUSE;
+	while (size--) {
+		clrsetbits_le32(efuse->base + EFUSE_CTRL, RK3128_A_MASK,
+				RK3128_ADDR(offset++));
+		udelay(2);
+		setbits_le32(efuse->base + EFUSE_CTRL, EFUSE_STROBE);
+		udelay(2);
+		*buffer++ = (u8)(readl(efuse->base + EFUSE_DOUT) & 0xFF);
+		clrbits_le32(efuse->base + EFUSE_CTRL, EFUSE_STROBE);
+		udelay(2);
 	}
 
+	/* Switch to inactive mode */
+	writel(0x0, efuse->base + EFUSE_CTRL);
+
+	return 0;
+}
+
+static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset,
+				      void *buf, int size)
+{
+	struct rockchip_efuse_plat *efuse = dev_get_plat(dev);
+	u8 *buffer = buf;
+
+	/* Switch to read mode */
+	writel(EFUSE_CSB, efuse->base + EFUSE_CTRL);
+	writel(EFUSE_LOAD | EFUSE_PGENB, efuse->base + EFUSE_CTRL);
+	udelay(2);
+
+	while (size--) {
+		clrsetbits_le32(efuse->base + EFUSE_CTRL, RK3288_A_MASK,
+				RK3288_ADDR(offset++));
+		udelay(2);
+		setbits_le32(efuse->base + EFUSE_CTRL, EFUSE_STROBE);
+		udelay(2);
+		*buffer++ = (u8)(readl(efuse->base + EFUSE_DOUT) & 0xFF);
+		clrbits_le32(efuse->base + EFUSE_CTRL, EFUSE_STROBE);
+		udelay(2);
+	}
+
 	/* Switch to standby mode */
-	writel(RK3399_PD | RK3399_CSB, &efuse->ctrl);
+	writel(EFUSE_CSB | EFUSE_PGENB, efuse->base + EFUSE_CTRL);
+
+	return 0;
+}
+
+static int rockchip_rk3328_efuse_read(struct udevice *dev, int offset,
+				      void *buf, int size)
+{
+	struct rockchip_efuse_plat *efuse = dev_get_plat(dev);
+	u32 status, *buffer = buf;
+	int ret;
 
-	memcpy(buf, bytes + addr_offset, size);
+	while (size--) {
+		writel(RK3328_AUTO_RD | RK3328_AUTO_ENB | RK3399_ADDR(offset++),
+		       efuse->base + RK3328_AUTO_CTRL);
+		udelay(1);
+
+		ret = readl_poll_sleep_timeout(efuse->base + RK3328_INT_STATUS,
+			status, (status & RK3328_INT_FINISH), 1, 50);
+		if (ret)
+			return ret;
+
+		*buffer++ = readl(efuse->base + RK3328_DOUT);
+		writel(RK3328_INT_FINISH, efuse->base + RK3328_INT_STATUS);
+	}
 
 	return 0;
 }
 
+static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset,
+				      void *buf, int size)
+{
+	struct rockchip_efuse_plat *efuse = dev_get_plat(dev);
+	u32 *buffer = buf;
+
+	/* Switch to array read mode */
+	writel(EFUSE_LOAD | EFUSE_PGENB | RK3399_STROBSFTSEL | RK3399_RSB,
+	       efuse->base + EFUSE_CTRL);
+	udelay(1);
+
+	while (size--) {
+		setbits_le32(efuse->base + EFUSE_CTRL,
+			     EFUSE_STROBE | RK3399_ADDR(offset++));
+		udelay(1);
+		*buffer++ = readl(efuse->base + EFUSE_DOUT);
+		clrbits_le32(efuse->base + EFUSE_CTRL, EFUSE_STROBE);
+		udelay(1);
+	}
+
+	/* Switch to power-down mode */
+	writel(RK3399_PD | EFUSE_CSB, efuse->base + EFUSE_CTRL);
+
+	return 0;
+}
+
 static int rockchip_efuse_read(struct udevice *dev, int offset,
 			       void *buf, int size)
 {
-	return rockchip_rk3399_efuse_read(dev, offset, buf, size);
+	const struct rockchip_efuse_data *data =
+		(void *)dev_get_driver_data(dev);
+	u32 block_start, block_end, block_offset, blocks;
+	u8 *buffer;
+	int ret;
+
+	if (offset < 0 || !buf || size <= 0 || offset + size > data->size)
+		return -EINVAL;
+
+	if (!data->read)
+		return -ENOSYS;
+
+	offset += data->offset;
+
+	if (data->block_size <= 1)
+		return data->read(dev, offset, buf, size);
+
+	block_start = offset / data->block_size;
+	block_offset = offset % data->block_size;
+	block_end = DIV_ROUND_UP(offset + size, data->block_size);
+	blocks = block_end - block_start;
+
+	buffer = calloc(blocks, data->block_size);
+	if (!buffer)
+		return -ENOMEM;
+
+	ret = data->read(dev, block_start, buffer, blocks);
+	if (!ret)
+		memcpy(buf, buffer + block_offset, size);
+
+	free(buffer);
+	return ret;
 }
 
 static const struct misc_ops rockchip_efuse_ops = {
@@ -142,11 +267,71 @@
 	struct rockchip_efuse_plat *plat = dev_get_plat(dev);
 
 	plat->base = dev_read_addr_ptr(dev);
+
 	return 0;
 }
 
+static const struct rockchip_efuse_data rk3036_data = {
+	.read = rockchip_rk3036_efuse_read,
+	.size = 0x20,
+};
+
+static const struct rockchip_efuse_data rk3128_data = {
+	.read = rockchip_rk3128_efuse_read,
+	.size = 0x40,
+};
+
+static const struct rockchip_efuse_data rk3288_data = {
+	.read = rockchip_rk3288_efuse_read,
+	.size = 0x20,
+};
+
+static const struct rockchip_efuse_data rk3328_data = {
+	.read = rockchip_rk3328_efuse_read,
+	.offset = 0x60,
+	.size = 0x20,
+	.block_size = 4,
+};
+
+static const struct rockchip_efuse_data rk3399_data = {
+	.read = rockchip_rk3399_efuse_read,
+	.size = 0x80,
+	.block_size = 4,
+};
+
 static const struct udevice_id rockchip_efuse_ids[] = {
-	{ .compatible = "rockchip,rk3399-efuse" },
+	{
+		.compatible = "rockchip,rk3036-efuse",
+		.data = (ulong)&rk3036_data,
+	},
+	{
+		.compatible = "rockchip,rk3066a-efuse",
+		.data = (ulong)&rk3288_data,
+	},
+	{
+		.compatible = "rockchip,rk3128-efuse",
+		.data = (ulong)&rk3128_data,
+	},
+	{
+		.compatible = "rockchip,rk3188-efuse",
+		.data = (ulong)&rk3288_data,
+	},
+	{
+		.compatible = "rockchip,rk3228-efuse",
+		.data = (ulong)&rk3288_data,
+	},
+	{
+		.compatible = "rockchip,rk3288-efuse",
+		.data = (ulong)&rk3288_data,
+	},
+	{
+		.compatible = "rockchip,rk3328-efuse",
+		.data = (ulong)&rk3328_data,
+	},
+	{
+		.compatible = "rockchip,rk3399-efuse",
+		.data = (ulong)&rk3399_data,
+	},
 	{}
 };
 
@@ -155,6 +340,6 @@
 	.id = UCLASS_MISC,
 	.of_match = rockchip_efuse_ids,
 	.of_to_plat = rockchip_efuse_of_to_plat,
-	.plat_auto	= sizeof(struct rockchip_efuse_plat),
+	.plat_auto = sizeof(struct rockchip_efuse_plat),
 	.ops = &rockchip_efuse_ops,
 };
diff --git a/drivers/misc/rockchip-otp.c b/drivers/misc/rockchip-otp.c
index cc9a545..c19cd5c 100644
--- a/drivers/misc/rockchip-otp.c
+++ b/drivers/misc/rockchip-otp.c
@@ -6,9 +6,12 @@
 #include <common.h>
 #include <asm/io.h>
 #include <command.h>
+#include <display_options.h>
 #include <dm.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/iopoll.h>
+#include <malloc.h>
 #include <misc.h>
 
 /* OTP Register Offsets */
@@ -47,37 +50,80 @@
 
 #define OTPC_TIMEOUT			10000
 
+#define RK3588_OTPC_AUTO_CTRL		0x0004
+#define RK3588_ADDR_SHIFT		16
+#define RK3588_ADDR(n)			((n) << RK3588_ADDR_SHIFT)
+#define RK3588_BURST_SHIFT		8
+#define RK3588_BURST(n)			((n) << RK3588_BURST_SHIFT)
+#define RK3588_OTPC_AUTO_EN		0x0008
+#define RK3588_AUTO_EN			BIT(0)
+#define RK3588_OTPC_DOUT0		0x0020
+#define RK3588_OTPC_INT_ST		0x0084
+#define RK3588_RD_DONE			BIT(1)
+
 struct rockchip_otp_plat {
 	void __iomem *base;
-	unsigned long secure_conf_base;
-	unsigned long otp_mask_base;
+};
+
+struct rockchip_otp_data {
+	int (*read)(struct udevice *dev, int offset, void *buf, int size);
+	int offset;
+	int size;
+	int block_size;
 };
 
-static int rockchip_otp_wait_status(struct rockchip_otp_plat *otp,
-				    u32 flag)
+#if defined(DEBUG)
+static int dump_otp(struct cmd_tbl *cmdtp, int flag,
+		    int argc, char *const argv[])
 {
-	int delay = OTPC_TIMEOUT;
+	struct udevice *dev;
+	u8 data[4];
+	int ret, i;
 
-	while (!(readl(otp->base + OTPC_INT_STATUS) & flag)) {
-		udelay(1);
-		delay--;
-		if (delay <= 0) {
-			printf("%s: wait init status timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
+	ret = uclass_get_device_by_driver(UCLASS_MISC,
+					  DM_DRIVER_GET(rockchip_otp), &dev);
+	if (ret) {
+		printf("%s: no misc-device found\n", __func__);
+		return 0;
 	}
 
-	/* clean int status */
-	writel(flag, otp->base + OTPC_INT_STATUS);
+	for (i = 0; true; i += sizeof(data)) {
+		ret = misc_read(dev, i, &data, sizeof(data));
+		if (ret < 0)
+			return 0;
+
+		print_buffer(i, data, 1, sizeof(data), sizeof(data));
+	}
 
 	return 0;
 }
 
-static int rockchip_otp_ecc_enable(struct rockchip_otp_plat *otp,
-				   bool enable)
+U_BOOT_CMD(
+	dump_otp, 1, 1, dump_otp,
+	"Dump the content of the otp",
+	""
+);
+#endif
+
+static int rockchip_otp_poll_timeout(struct rockchip_otp_plat *otp,
+				     u32 flag, u32 reg)
 {
-	int ret = 0;
+	u32 status;
+	int ret;
+
+	ret = readl_poll_sleep_timeout(otp->base + reg, status,
+				       (status & flag), 1, OTPC_TIMEOUT);
+	if (ret)
+		return ret;
 
+	/* Clear int flag */
+	writel(flag, otp->base + reg);
+
+	return 0;
+}
+
+static int rockchip_otp_ecc_enable(struct rockchip_otp_plat *otp, bool enable)
+{
 	writel(SBPI_DAP_ADDR_MASK | (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT),
 	       otp->base + OTPC_SBPI_CTRL);
 
@@ -92,11 +138,7 @@
 
 	writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL);
 
-	ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE);
-	if (ret < 0)
-		printf("%s timeout during ecc_enable\n", __func__);
-
-	return ret;
+	return rockchip_otp_poll_timeout(otp, OTPC_SBPI_DONE, OTPC_INT_STATUS);
 }
 
 static int rockchip_px30_otp_read(struct udevice *dev, int offset,
@@ -104,29 +146,61 @@
 {
 	struct rockchip_otp_plat *otp = dev_get_plat(dev);
 	u8 *buffer = buf;
-	int ret = 0;
+	int ret;
 
 	ret = rockchip_otp_ecc_enable(otp, false);
-	if (ret < 0) {
-		printf("%s rockchip_otp_ecc_enable err\n", __func__);
+	if (ret)
 		return ret;
+
+	writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
+	udelay(5);
+
+	while (size--) {
+		writel(offset++ | OTPC_USER_ADDR_MASK,
+		       otp->base + OTPC_USER_ADDR);
+		writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
+		       otp->base + OTPC_USER_ENABLE);
+
+		ret = rockchip_otp_poll_timeout(otp, OTPC_USER_DONE,
+						OTPC_INT_STATUS);
+		if (ret)
+			goto read_end;
+
+		*buffer++ = (u8)(readl(otp->base + OTPC_USER_Q) & 0xFF);
 	}
 
+read_end:
+	writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
+
+	return ret;
+}
+
+static int rockchip_rk3568_otp_read(struct udevice *dev, int offset,
+				    void *buf, int size)
+{
+	struct rockchip_otp_plat *otp = dev_get_plat(dev);
+	u16 *buffer = buf;
+	int ret;
+
+	ret = rockchip_otp_ecc_enable(otp, false);
+	if (ret)
+		return ret;
+
 	writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
 	udelay(5);
+
 	while (size--) {
 		writel(offset++ | OTPC_USER_ADDR_MASK,
 		       otp->base + OTPC_USER_ADDR);
 		writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
 		       otp->base + OTPC_USER_ENABLE);
 
-		ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE);
-		if (ret < 0) {
-			printf("%s timeout during read setup\n", __func__);
+		ret = rockchip_otp_poll_timeout(otp, OTPC_USER_DONE,
+						OTPC_INT_STATUS);
+		if (ret)
 			goto read_end;
-		}
 
-		*buffer++ = readb(otp->base + OTPC_USER_Q);
+		*buffer++ = (u16)(readl(otp->base + OTPC_USER_Q) & 0xFFFF);
 	}
 
 read_end:
@@ -135,10 +209,64 @@
 	return ret;
 }
 
+static int rockchip_rk3588_otp_read(struct udevice *dev, int offset,
+				    void *buf, int size)
+{
+	struct rockchip_otp_plat *otp = dev_get_plat(dev);
+	u32 *buffer = buf;
+	int ret;
+
+	while (size--) {
+		writel(RK3588_ADDR(offset++) | RK3588_BURST(1),
+		       otp->base + RK3588_OTPC_AUTO_CTRL);
+		writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN);
+
+		ret = rockchip_otp_poll_timeout(otp, RK3588_RD_DONE,
+						RK3588_OTPC_INT_ST);
+		if (ret)
+			return ret;
+
+		*buffer++ = readl(otp->base + RK3588_OTPC_DOUT0);
+	}
+
+	return 0;
+}
+
 static int rockchip_otp_read(struct udevice *dev, int offset,
 			     void *buf, int size)
 {
-	return rockchip_px30_otp_read(dev, offset, buf, size);
+	const struct rockchip_otp_data *data =
+		(void *)dev_get_driver_data(dev);
+	u32 block_start, block_end, block_offset, blocks;
+	u8 *buffer;
+	int ret;
+
+	if (offset < 0 || !buf || size <= 0 || offset + size > data->size)
+		return -EINVAL;
+
+	if (!data->read)
+		return -ENOSYS;
+
+	offset += data->offset;
+
+	if (data->block_size <= 1)
+		return data->read(dev, offset, buf, size);
+
+	block_start = offset / data->block_size;
+	block_offset = offset % data->block_size;
+	block_end = DIV_ROUND_UP(offset + size, data->block_size);
+	blocks = block_end - block_start;
+
+	buffer = calloc(blocks, data->block_size);
+	if (!buffer)
+		return -ENOMEM;
+
+	ret = data->read(dev, block_start, buffer, blocks);
+	if (!ret)
+		memcpy(buf, buffer + block_offset, size);
+
+	free(buffer);
+	return ret;
 }
 
 static const struct misc_ops rockchip_otp_ops = {
@@ -147,21 +275,47 @@
 
 static int rockchip_otp_of_to_plat(struct udevice *dev)
 {
-	struct rockchip_otp_plat *otp = dev_get_plat(dev);
+	struct rockchip_otp_plat *plat = dev_get_plat(dev);
 
-	otp->base = dev_read_addr_ptr(dev);
+	plat->base = dev_read_addr_ptr(dev);
 
 	return 0;
 }
 
+static const struct rockchip_otp_data px30_data = {
+	.read = rockchip_px30_otp_read,
+	.size = 0x40,
+};
+
+static const struct rockchip_otp_data rk3568_data = {
+	.read = rockchip_rk3568_otp_read,
+	.size = 0x80,
+	.block_size = 2,
+};
+
+static const struct rockchip_otp_data rk3588_data = {
+	.read = rockchip_rk3588_otp_read,
+	.offset = 0xC00,
+	.size = 0x400,
+	.block_size = 4,
+};
+
 static const struct udevice_id rockchip_otp_ids[] = {
 	{
 		.compatible = "rockchip,px30-otp",
-		.data = (ulong)&rockchip_px30_otp_read,
+		.data = (ulong)&px30_data,
 	},
 	{
 		.compatible = "rockchip,rk3308-otp",
-		.data = (ulong)&rockchip_px30_otp_read,
+		.data = (ulong)&px30_data,
+	},
+	{
+		.compatible = "rockchip,rk3568-otp",
+		.data = (ulong)&rk3568_data,
+	},
+	{
+		.compatible = "rockchip,rk3588-otp",
+		.data = (ulong)&rk3588_data,
 	},
 	{}
 };
@@ -170,7 +324,7 @@
 	.name = "rockchip_otp",
 	.id = UCLASS_MISC,
 	.of_match = rockchip_otp_ids,
-	.ops = &rockchip_otp_ops,
 	.of_to_plat = rockchip_otp_of_to_plat,
-	.plat_auto	= sizeof(struct rockchip_otp_plat),
+	.plat_auto = sizeof(struct rockchip_otp_plat),
+	.ops = &rockchip_otp_ops,
 };
diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c
index 4a1acce..34119f9 100644
--- a/drivers/mmc/renesas-sdhi.c
+++ b/drivers/mmc/renesas-sdhi.c
@@ -977,34 +977,50 @@
 
 	/* optional SDnH clock */
 	ret = clk_get_by_name(dev, "clkh", &priv->clkh);
-	if (ret < 0)
+	if (ret < 0) {
 		dev_dbg(dev, "failed to get clkh\n");
+	} else {
+		ret = clk_set_rate(&priv->clkh, 800000000);
+		if (ret < 0) {
+			dev_err(dev, "failed to set rate for SDnH clock (%d)\n", ret);
+			goto err_clk;
+		}
+	}
 
 	/* set to max rate */
 	ret = clk_set_rate(&priv->clk, 200000000);
 	if (ret < 0) {
-		dev_err(dev, "failed to set rate for host clock\n");
-		clk_free(&priv->clk);
-		return ret;
+		dev_err(dev, "failed to set rate for SDn clock (%d)\n", ret);
+		goto err_clkh;
 	}
 
 	ret = clk_enable(&priv->clk);
 	if (ret) {
-		dev_err(dev, "failed to enable host clock\n");
-		return ret;
+		dev_err(dev, "failed to enable SDn clock (%d)\n", ret);
+		goto err_clkh;
 	}
 
 	priv->quirks = quirks;
 	ret = tmio_sd_probe(dev, quirks);
+	if (ret)
+		goto err_tmio_probe;
 
 	renesas_sdhi_filter_caps(dev);
 
 #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
     CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
     CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
-	if (!ret && (priv->caps & TMIO_SD_CAP_RCAR_UHS))
+	if (priv->caps & TMIO_SD_CAP_RCAR_UHS)
 		renesas_sdhi_reset_tuning(priv);
 #endif
+	return 0;
+
+err_tmio_probe:
+	clk_disable(&priv->clk);
+err_clkh:
+	clk_free(&priv->clkh);
+err_clk:
+	clk_free(&priv->clk);
 	return ret;
 }
 
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c
index 573bf16..3661ce3 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -41,6 +41,14 @@
 	struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
 	int ret;
 
+	/*
+	 * The clock frequency chosen here affects CLKDIV in the dw_mmc core.
+	 * That can be either 0 or 1, but it must be set to 1 for eMMC DDR52
+	 * 8-bit mode.  It will be set to 0 for all other modes.
+	 */
+	if (host->mmc->selected_mode == MMC_DDR_52 && host->mmc->bus_width == 8)
+		freq *= 2;
+
 	ret = clk_set_rate(&priv->clk, freq);
 	if (ret < 0) {
 		debug("%s: err=%d\n", __func__, ret);
diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c
index 47b6e6e..f0dfe63 100644
--- a/drivers/pci/pci_rom.c
+++ b/drivers/pci/pci_rom.c
@@ -325,7 +325,7 @@
 	return ret;
 }
 
-int vesa_setup_video_priv(struct vesa_mode_info *vesa,
+int vesa_setup_video_priv(struct vesa_mode_info *vesa, u64 fb,
 			  struct video_priv *uc_priv,
 			  struct video_uc_plat *plat)
 {
@@ -348,9 +348,9 @@
 
 	/* Use double buffering if enabled */
 	if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->base)
-		plat->copy_base = vesa->phys_base_ptr;
+		plat->copy_base = fb;
 	else
-		plat->base = vesa->phys_base_ptr;
+		plat->base = fb;
 	log_debug("base = %lx, copy_base = %lx\n", plat->base, plat->copy_base);
 	plat->size = vesa->bytes_per_scanline * vesa->y_resolution;
 
@@ -377,7 +377,9 @@
 		return ret;
 	}
 
-	ret = vesa_setup_video_priv(&mode_info.vesa, uc_priv, plat);
+	ret = vesa_setup_video_priv(&mode_info.vesa,
+				    mode_info.vesa.phys_base_ptr, uc_priv,
+				    plat);
 	if (ret) {
 		if (ret == -ENFILE) {
 			/*
diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index e477a6c..1305763 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -11,6 +11,13 @@
 	help
 	  Support for Rockchip USB2.0 PHY with Innosilicon IP block.
 
+config PHY_ROCKCHIP_NANENG_COMBOPHY
+	bool "Support Rockchip NANENG combo PHY Driver"
+	depends on ARCH_ROCKCHIP
+	select PHY
+	help
+	  Enable this to support the Rockchip NANENG combo PHY.
+
 config PHY_ROCKCHIP_PCIE
 	bool "Rockchip PCIe PHY Driver"
 	depends on ARCH_ROCKCHIP
diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
index f6ad3bf..a236877 100644
--- a/drivers/phy/rockchip/Makefile
+++ b/drivers/phy/rockchip/Makefile
@@ -4,6 +4,7 @@
 #
 
 obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2)	+= phy-rockchip-inno-usb2.o
+obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY) += phy-rockchip-naneng-combphy.o
 obj-$(CONFIG_PHY_ROCKCHIP_PCIE)		+= phy-rockchip-pcie.o
 obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3)	+= phy-rockchip-snps-pcie3.o
 obj-$(CONFIG_PHY_ROCKCHIP_TYPEC)	+= phy-rockchip-typec.o
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index b32a498..55e1dbc 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -179,12 +179,21 @@
 	if (IS_ERR(priv->reg_base))
 		return PTR_ERR(priv->reg_base);
 
-	ret = ofnode_read_u32(dev_ofnode(dev), "reg", &reg);
+	ret = ofnode_read_u32_index(dev_ofnode(dev), "reg", 0, &reg);
 	if (ret) {
 		dev_err(dev, "failed to read reg property (ret = %d)\n", ret);
 		return ret;
 	}
 
+	/* support address_cells=2 */
+	if (reg == 0) {
+		if (ofnode_read_u32_index(dev_ofnode(dev), "reg", 1, &reg)) {
+			dev_err(dev, "%s must have reg[1]\n",
+				ofnode_get_name(dev_ofnode(dev)));
+			return -EINVAL;
+		}
+	}
+
 	phy_cfgs = (const struct rockchip_usb2phy_cfg *)
 					dev_get_driver_data(dev);
 	if (!phy_cfgs)
@@ -289,11 +298,65 @@
 	{ /* sentinel */ }
 };
 
+static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
+	{
+		.reg		= 0xfe8a0000,
+		.port_cfgs	= {
+			[USB2PHY_PORT_OTG] = {
+				.phy_sus	= { 0x0000, 8, 0, 0x052, 0x1d1 },
+				.bvalid_det_en	= { 0x0080, 2, 2, 0, 1 },
+				.bvalid_det_st	= { 0x0084, 2, 2, 0, 1 },
+				.bvalid_det_clr = { 0x0088, 2, 2, 0, 1 },
+				.ls_det_en	= { 0x0080, 0, 0, 0, 1 },
+				.ls_det_st	= { 0x0084, 0, 0, 0, 1 },
+				.ls_det_clr	= { 0x0088, 0, 0, 0, 1 },
+				.utmi_avalid	= { 0x00c0, 10, 10, 0, 1 },
+				.utmi_bvalid	= { 0x00c0, 9, 9, 0, 1 },
+				.utmi_ls	= { 0x00c0, 5, 4, 0, 1 },
+			},
+			[USB2PHY_PORT_HOST] = {
+				.phy_sus	= { 0x0004, 8, 0, 0x1d2, 0x1d1 },
+				.ls_det_en	= { 0x0080, 1, 1, 0, 1 },
+				.ls_det_st	= { 0x0084, 1, 1, 0, 1 },
+				.ls_det_clr	= { 0x0088, 1, 1, 0, 1 },
+				.utmi_ls	= { 0x00c0, 17, 16, 0, 1 },
+				.utmi_hstdet	= { 0x00c0, 19, 19, 0, 1 }
+			}
+		},
+	},
+	{
+		.reg		= 0xfe8b0000,
+		.port_cfgs	= {
+			[USB2PHY_PORT_OTG] = {
+				.phy_sus	= { 0x0000, 8, 0, 0x1d2, 0x1d1 },
+				.ls_det_en	= { 0x0080, 0, 0, 0, 1 },
+				.ls_det_st	= { 0x0084, 0, 0, 0, 1 },
+				.ls_det_clr	= { 0x0088, 0, 0, 0, 1 },
+				.utmi_ls	= { 0x00c0, 5, 4, 0, 1 },
+				.utmi_hstdet	= { 0x00c0, 7, 7, 0, 1 }
+			},
+			[USB2PHY_PORT_HOST] = {
+				.phy_sus	= { 0x0004, 8, 0, 0x1d2, 0x1d1 },
+				.ls_det_en	= { 0x0080, 1, 1, 0, 1 },
+				.ls_det_st	= { 0x0084, 1, 1, 0, 1 },
+				.ls_det_clr	= { 0x0088, 1, 1, 0, 1 },
+				.utmi_ls	= { 0x00c0, 17, 16, 0, 1 },
+				.utmi_hstdet	= { 0x00c0, 19, 19, 0, 1 }
+			}
+		},
+	},
+	{ /* sentinel */ }
+};
+
 static const struct udevice_id rockchip_usb2phy_ids[] = {
 	{
 		.compatible = "rockchip,rk3399-usb2phy",
 		.data = (ulong)&rk3399_usb2phy_cfgs,
 	},
+	{
+		.compatible = "rockchip,rk3568-usb2phy",
+		.data = (ulong)&rk3568_phy_cfgs,
+	},
 	{ /* sentinel */ }
 };
 
diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
new file mode 100644
index 0000000..78da5fe
--- /dev/null
+++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
@@ -0,0 +1,441 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip USB3.0/PCIe Gen2/SATA/SGMII combphy driver
+ *
+ * Copyright (C) 2021 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dt-bindings/phy/phy.h>
+#include <generic-phy.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/clock.h>
+#include <regmap.h>
+#include <reset-uclass.h>
+#include <dm/device_compat.h>
+
+#define BIT_WRITEABLE_SHIFT		16
+
+struct rockchip_combphy_priv;
+
+struct combphy_reg {
+	u16 offset;
+	u16 bitend;
+	u16 bitstart;
+	u16 disable;
+	u16 enable;
+};
+
+struct rockchip_combphy_grfcfg {
+	struct combphy_reg pcie_mode_set;
+	struct combphy_reg usb_mode_set;
+	struct combphy_reg sgmii_mode_set;
+	struct combphy_reg qsgmii_mode_set;
+	struct combphy_reg pipe_rxterm_set;
+	struct combphy_reg pipe_txelec_set;
+	struct combphy_reg pipe_txcomp_set;
+	struct combphy_reg pipe_clk_25m;
+	struct combphy_reg pipe_clk_100m;
+	struct combphy_reg pipe_phymode_sel;
+	struct combphy_reg pipe_rate_sel;
+	struct combphy_reg pipe_rxterm_sel;
+	struct combphy_reg pipe_txelec_sel;
+	struct combphy_reg pipe_txcomp_sel;
+	struct combphy_reg pipe_clk_ext;
+	struct combphy_reg pipe_sel_usb;
+	struct combphy_reg pipe_sel_qsgmii;
+	struct combphy_reg pipe_phy_status;
+	struct combphy_reg con0_for_pcie;
+	struct combphy_reg con1_for_pcie;
+	struct combphy_reg con2_for_pcie;
+	struct combphy_reg con3_for_pcie;
+	struct combphy_reg con0_for_sata;
+	struct combphy_reg con1_for_sata;
+	struct combphy_reg con2_for_sata;
+	struct combphy_reg con3_for_sata;
+	struct combphy_reg pipe_con0_for_sata;
+	struct combphy_reg pipe_sgmii_mac_sel;
+	struct combphy_reg pipe_xpcs_phy_ready;
+	struct combphy_reg u3otg0_port_en;
+	struct combphy_reg u3otg1_port_en;
+};
+
+struct rockchip_combphy_cfg {
+	const struct rockchip_combphy_grfcfg *grfcfg;
+	int (*combphy_cfg)(struct rockchip_combphy_priv *priv);
+};
+
+struct rockchip_combphy_priv {
+	u32 mode;
+	void __iomem *mmio;
+	struct udevice *dev;
+	struct regmap *pipe_grf;
+	struct regmap *phy_grf;
+	struct phy *phy;
+	struct reset_ctl phy_rst;
+	struct clk ref_clk;
+	const struct rockchip_combphy_cfg *cfg;
+};
+
+static int param_write(struct regmap *base,
+		       const struct combphy_reg *reg, bool en)
+{
+	u32 val, mask, tmp;
+
+	tmp = en ? reg->enable : reg->disable;
+	mask = GENMASK(reg->bitend, reg->bitstart);
+	val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
+
+	return regmap_write(base, reg->offset, val);
+}
+
+static int rockchip_combphy_pcie_init(struct rockchip_combphy_priv *priv)
+{
+	int ret = 0;
+
+	if (priv->cfg->combphy_cfg) {
+		ret = priv->cfg->combphy_cfg(priv);
+		if (ret) {
+			dev_err(priv->dev, "failed to init phy for pcie\n");
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
+static int rockchip_combphy_usb3_init(struct rockchip_combphy_priv *priv)
+{
+	int ret = 0;
+
+	if (priv->cfg->combphy_cfg) {
+		ret = priv->cfg->combphy_cfg(priv);
+		if (ret) {
+			dev_err(priv->dev, "failed to init phy for usb3\n");
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
+static int rockchip_combphy_sata_init(struct rockchip_combphy_priv *priv)
+{
+	int ret = 0;
+
+	if (priv->cfg->combphy_cfg) {
+		ret = priv->cfg->combphy_cfg(priv);
+		if (ret) {
+			dev_err(priv->dev, "failed to init phy for sata\n");
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
+static int rockchip_combphy_sgmii_init(struct rockchip_combphy_priv *priv)
+{
+	int ret = 0;
+
+	if (priv->cfg->combphy_cfg) {
+		ret = priv->cfg->combphy_cfg(priv);
+		if (ret) {
+			dev_err(priv->dev, "failed to init phy for sgmii\n");
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
+static int rockchip_combphy_set_mode(struct rockchip_combphy_priv *priv)
+{
+	switch (priv->mode) {
+	case PHY_TYPE_PCIE:
+		rockchip_combphy_pcie_init(priv);
+		break;
+	case PHY_TYPE_USB3:
+		rockchip_combphy_usb3_init(priv);
+		break;
+	case PHY_TYPE_SATA:
+		rockchip_combphy_sata_init(priv);
+		break;
+	case PHY_TYPE_SGMII:
+	case PHY_TYPE_QSGMII:
+		return rockchip_combphy_sgmii_init(priv);
+	default:
+		dev_err(priv->dev, "incompatible PHY type\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int rockchip_combphy_init(struct phy *phy)
+{
+	struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev);
+	int ret;
+
+	ret = clk_enable(&priv->ref_clk);
+	if (ret < 0 && ret != -ENOSYS)
+		return ret;
+
+	ret = rockchip_combphy_set_mode(priv);
+	if (ret)
+		goto err_clk;
+
+	reset_deassert(&priv->phy_rst);
+
+	return 0;
+
+err_clk:
+	clk_disable(&priv->ref_clk);
+
+	return ret;
+}
+
+static int rockchip_combphy_exit(struct phy *phy)
+{
+	struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev);
+
+	clk_disable(&priv->ref_clk);
+	reset_assert(&priv->phy_rst);
+
+	return 0;
+}
+
+static int rockchip_combphy_xlate(struct phy *phy, struct ofnode_phandle_args *args)
+{
+	struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev);
+
+	if (args->args_count != 1) {
+		pr_err("invalid number of arguments\n");
+		return -EINVAL;
+	}
+
+	priv->mode = args->args[0];
+
+	return 0;
+}
+
+static const struct phy_ops rochchip_combphy_ops = {
+	.init = rockchip_combphy_init,
+	.exit = rockchip_combphy_exit,
+	.of_xlate = rockchip_combphy_xlate,
+};
+
+static int rockchip_combphy_parse_dt(struct udevice *dev,
+				     struct rockchip_combphy_priv *priv)
+{
+	struct udevice *syscon;
+	int ret;
+
+	ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pipe-grf", &syscon);
+	if (ret) {
+		dev_err(dev, "failed to find peri_ctrl pipe-grf regmap");
+		return ret;
+	}
+	priv->pipe_grf = syscon_get_regmap(syscon);
+
+	ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pipe-phy-grf", &syscon);
+	if (ret) {
+		dev_err(dev, "failed to find peri_ctrl pipe-phy-grf regmap\n");
+		return ret;
+	}
+	priv->phy_grf = syscon_get_regmap(syscon);
+
+	ret = clk_get_by_index(dev, 0, &priv->ref_clk);
+	if (ret) {
+		dev_err(dev, "failed to find ref clock\n");
+		return PTR_ERR(&priv->ref_clk);
+	}
+
+	ret = reset_get_by_index(dev, 0, &priv->phy_rst);
+	if (ret) {
+		dev_err(dev, "no phy reset control specified\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rockchip_combphy_probe(struct udevice *udev)
+{
+	struct rockchip_combphy_priv *priv = dev_get_priv(udev);
+	const struct rockchip_combphy_cfg *phy_cfg;
+
+	priv->mmio = (void __iomem *)dev_read_addr(udev);
+	if (IS_ERR(priv->mmio))
+		return PTR_ERR(priv->mmio);
+
+	phy_cfg = (const struct rockchip_combphy_cfg *)dev_get_driver_data(udev);
+	if (!phy_cfg) {
+		dev_err(udev, "No OF match data provided\n");
+		return -EINVAL;
+	}
+
+	priv->dev = udev;
+	priv->mode = PHY_TYPE_SATA;
+	priv->cfg = phy_cfg;
+
+	return rockchip_combphy_parse_dt(udev, priv);
+}
+
+static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv)
+{
+	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
+	u32 val;
+
+	switch (priv->mode) {
+	case PHY_TYPE_PCIE:
+		/* Set SSC downward spread spectrum */
+		val = readl(priv->mmio + (0x1f << 2));
+		val &= ~GENMASK(5, 4);
+		val |= 0x01 << 4;
+		writel(val, priv->mmio + 0x7c);
+
+		param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
+		param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
+		param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
+		param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
+		break;
+	case PHY_TYPE_USB3:
+		/* Set SSC downward spread spectrum */
+		val = readl(priv->mmio + (0x1f << 2));
+		val &= ~GENMASK(5, 4);
+		val |= 0x01 << 4;
+		writel(val, priv->mmio + 0x7c);
+
+		/* Enable adaptive CTLE for USB3.0 Rx */
+		val = readl(priv->mmio + (0x0e << 2));
+		val &= ~GENMASK(0, 0);
+		val |= 0x01;
+		writel(val, priv->mmio + (0x0e << 2));
+
+		/* Set PLL KVCO fine tuning signals */
+		val = readl(priv->mmio + (0x20 << 2));
+		val &= ~(0x7 << 2);
+		val |= 0x2 << 2;
+		writel(val, priv->mmio + (0x20 << 2));
+
+		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
+		writel(0x4, priv->mmio + (0xb << 2));
+
+		/* Set PLL input clock divider 1/2 */
+		val = readl(priv->mmio + (0x5 << 2));
+		val &= ~(0x3 << 6);
+		val |= 0x1 << 6;
+		writel(val, priv->mmio + (0x5 << 2));
+
+		/* Set PLL loop divider */
+		writel(0x32, priv->mmio + (0x11 << 2));
+
+		/* Set PLL KVCO to min and set PLL charge pump current to max */
+		writel(0xf0, priv->mmio + (0xa << 2));
+
+		param_write(priv->phy_grf, &cfg->pipe_sel_usb, true);
+		param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
+		param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
+		param_write(priv->phy_grf, &cfg->usb_mode_set, true);
+		break;
+	case PHY_TYPE_SATA:
+		writel(0x41, priv->mmio + 0x38);
+		writel(0x8F, priv->mmio + 0x18);
+		param_write(priv->phy_grf, &cfg->con0_for_sata, true);
+		param_write(priv->phy_grf, &cfg->con1_for_sata, true);
+		param_write(priv->phy_grf, &cfg->con2_for_sata, true);
+		param_write(priv->phy_grf, &cfg->con3_for_sata, true);
+		param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
+		break;
+	case PHY_TYPE_SGMII:
+		param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
+		param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
+		param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
+		param_write(priv->phy_grf, &cfg->sgmii_mode_set, true);
+		break;
+	case PHY_TYPE_QSGMII:
+		param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
+		param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
+		param_write(priv->phy_grf, &cfg->pipe_rate_sel, true);
+		param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
+		param_write(priv->phy_grf, &cfg->qsgmii_mode_set, true);
+		break;
+	default:
+		pr_err("%s, phy-type %d\n", __func__, priv->mode);
+		return -EINVAL;
+	}
+
+	/* The default ref clock is 25Mhz */
+	param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
+
+	if (dev_read_bool(priv->dev, "rockchip,enable-ssc")) {
+		val = readl(priv->mmio + (0x7 << 2));
+		val |= BIT(4);
+		writel(val, priv->mmio + (0x7 << 2));
+	}
+
+	return 0;
+}
+
+static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = {
+	/* pipe-phy-grf */
+	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
+	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
+	.sgmii_mode_set		= { 0x0000, 5, 0, 0x00, 0x01 },
+	.qsgmii_mode_set	= { 0x0000, 5, 0, 0x00, 0x21 },
+	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
+	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
+	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
+	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
+	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
+	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
+	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
+	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
+	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
+	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
+	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
+	.pipe_sel_usb		= { 0x000c, 14, 13, 0x00, 0x01 },
+	.pipe_sel_qsgmii	= { 0x000c, 15, 13, 0x00, 0x07 },
+	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
+	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
+	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
+	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
+	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
+	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0119 },
+	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0040 },
+	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c3 },
+	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x4407 },
+	/* pipe-grf */
+	.pipe_con0_for_sata	= { 0x0000, 15, 0, 0x00, 0x2220 },
+	.pipe_sgmii_mac_sel	= { 0x0040, 1, 1, 0x00, 0x01 },
+	.pipe_xpcs_phy_ready	= { 0x0040, 2, 2, 0x00, 0x01 },
+	.u3otg0_port_en		= { 0x0104, 15, 0, 0x0181, 0x1100 },
+	.u3otg1_port_en		= { 0x0144, 15, 0, 0x0181, 0x1100 },
+};
+
+static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = {
+	.grfcfg		= &rk3568_combphy_grfcfgs,
+	.combphy_cfg	= rk3568_combphy_cfg,
+};
+
+static const struct udevice_id rockchip_combphy_ids[] = {
+	{
+		.compatible = "rockchip,rk3568-naneng-combphy",
+		.data = (ulong)&rk3568_combphy_cfgs
+	},
+	{ }
+};
+
+U_BOOT_DRIVER(rockchip_naneng_combphy) = {
+	.name		= "naneng-combphy",
+	.id		= UCLASS_PHY,
+	.of_match	= rockchip_combphy_ids,
+	.ops		= &rochchip_combphy_ops,
+	.probe		= rockchip_combphy_probe,
+	.priv_auto	= sizeof(struct rockchip_combphy_priv),
+};
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
index 25fbe39..1be6252 100644
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
@@ -745,6 +745,19 @@
 	return 0;
 }
 
+static int armada_37xx_pinctrl_bind(struct udevice *dev)
+{
+	/*
+	 * Make sure that the pinctrl driver gets probed after binding
+	 * as on A37XX the pinctrl driver is the one that is also
+	 * registering the GPIO one during probe, so if its not probed
+	 * GPIO-s are not registered as well.
+	 */
+	dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND);
+
+	return 0;
+}
+
 static const struct udevice_id armada_37xx_pinctrl_of_match[] = {
 	{
 		.compatible = "marvell,armada3710-sb-pinctrl",
@@ -762,6 +775,7 @@
 	.id = UCLASS_PINCTRL,
 	.of_match = of_match_ptr(armada_37xx_pinctrl_of_match),
 	.probe = armada_37xx_pinctrl_probe,
+	.bind = armada_37xx_pinctrl_bind,
 	.priv_auto	= sizeof(struct armada_37xx_pinctrl),
 	.ops = &armada_37xx_pinctrl_ops,
 };
diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h
index 59d447e..0ab743e 100644
--- a/drivers/pinctrl/renesas/sh_pfc.h
+++ b/drivers/pinctrl/renesas/sh_pfc.h
@@ -309,21 +309,6 @@
 extern const struct sh_pfc_soc_info r8a77990_pinmux_info;
 extern const struct sh_pfc_soc_info r8a77995_pinmux_info;
 extern const struct sh_pfc_soc_info r8a779a0_pinmux_info;
-extern const struct sh_pfc_soc_info r8a779f0_pinmux_info;
-extern const struct sh_pfc_soc_info r8a779g0_pinmux_info;
-extern const struct sh_pfc_soc_info sh7203_pinmux_info;
-extern const struct sh_pfc_soc_info sh7264_pinmux_info;
-extern const struct sh_pfc_soc_info sh7269_pinmux_info;
-extern const struct sh_pfc_soc_info sh73a0_pinmux_info;
-extern const struct sh_pfc_soc_info sh7720_pinmux_info;
-extern const struct sh_pfc_soc_info sh7722_pinmux_info;
-extern const struct sh_pfc_soc_info sh7723_pinmux_info;
-extern const struct sh_pfc_soc_info sh7724_pinmux_info;
-extern const struct sh_pfc_soc_info sh7734_pinmux_info;
-extern const struct sh_pfc_soc_info sh7757_pinmux_info;
-extern const struct sh_pfc_soc_info sh7785_pinmux_info;
-extern const struct sh_pfc_soc_info sh7786_pinmux_info;
-extern const struct sh_pfc_soc_info shx3_pinmux_info;
 
 /* -----------------------------------------------------------------------------
  * Helper macros to create pin and port lists
diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
index 9884355..90461ae 100644
--- a/drivers/pinctrl/rockchip/Makefile
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -14,5 +14,6 @@
 obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o
 obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o
 obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o
+obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o
 obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o
 obj-$(CONFIG_ROCKCHIP_RV1126) += pinctrl-rv1126.o
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3568.c b/drivers/pinctrl/rockchip/pinctrl-rk3568.c
new file mode 100644
index 0000000..935aed9
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3568.c
@@ -0,0 +1,362 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2020 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+#include "pinctrl-rockchip.h"
+
+static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
+	MR_TOPGRF(RK_GPIO0, RK_PB3, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(0, 0, 0)), /* CAN0 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PA1, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(0, 0, 1)), /* CAN0 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 0)), /* CAN1 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO4, RK_PC3, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 1)), /* CAN1 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO4, RK_PB5, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(4, 4, 0)), /* CAN2 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PB2, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(4, 4, 1)), /* CAN2 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO4, RK_PC4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(6, 6, 0)), /* EDPDP_HPDIN IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO0, RK_PC2, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(6, 6, 1)), /* EDPDP_HPDIN IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PB1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 0)), /* GMAC1 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO4, RK_PA7, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 1)), /* GMAC1 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO4, RK_PD1, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 0)), /* HDMITX IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO0, RK_PC7, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 1)), /* HDMITX IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO0, RK_PB6, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 0)), /* I2C2 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO4, RK_PB4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 1)), /* I2C2 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO1, RK_PA0, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(0, 0, 0)), /* I2C3 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PB6, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(0, 0, 1)), /* I2C3 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO4, RK_PB2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(2, 2, 0)), /* I2C4 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PB1, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(2, 2, 1)), /* I2C4 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PB4, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(4, 4, 0)), /* I2C5 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO4, RK_PD0, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(4, 4, 1)), /* I2C5 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 0)), /* PWM4 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 1)), /* PWM4 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 0)), /* PWM5 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 1)), /* PWM5 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 0)), /* PWM6 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 1)), /* PWM6 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 0)), /* PWM7 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 1)), /* PWM7 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 0)), /* PWM8 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 1)), /* PWM8 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 0)), /* PWM9 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 1)), /* PWM9 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 0)), /* PWM10 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 1)), /* PWM10 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 0)), /* PWM11 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 1)), /* PWM11 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 0)), /* PWM12 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 1)), /* PWM12 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 0)), /* PWM13 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 1)), /* PWM13 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 0)), /* PWM14 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 1)), /* PWM14 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 0)), /* PWM15 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 1)), /* PWM15 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_3, 0x0308, RK_GENMASK_VAL(14, 14, 0)), /* SDMMC2 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PA5, RK_FUNC_5, 0x0308, RK_GENMASK_VAL(14, 14, 1)), /* SDMMC2 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO0, RK_PB5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(0, 0, 0)), /* SPI0 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PD3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(0, 0, 1)), /* SPI0 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO2, RK_PB5, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 0)), /* SPI1 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PC3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 1)), /* SPI1 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(4, 4, 0)), /* SPI2 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PA0, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(4, 4, 1)), /* SPI2 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO4, RK_PB3, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(6, 6, 0)), /* SPI3 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(6, 6, 1)), /* SPI3 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO2, RK_PB4, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(8, 8, 0)), /* UART1 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(8, 8, 1)), /* UART1 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(10, 10, 0)), /* UART2 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(10, 10, 1)), /* UART2 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(12, 12, 0)), /* UART3 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PB7, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(12, 12, 1)), /* UART3 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(14, 14, 0)), /* UART4 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PB2, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(14, 14, 1)), /* UART4 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO2, RK_PA2, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(0, 0, 0)), /* UART5 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PC2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(0, 0, 1)), /* UART5 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO2, RK_PA4, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 0)), /* UART6 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 1)), /* UART6 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO2, RK_PA6, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(5, 4, 0)), /* UART7 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PC4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(5, 4, 1)), /* UART7 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(5, 4, 2)), /* UART7 IO mux selection M2 */
+	MR_TOPGRF(RK_GPIO2, RK_PC5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(6, 6, 0)), /* UART8 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PD7, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(6, 6, 1)), /* UART8 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO2, RK_PB0, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(9, 8, 0)), /* UART9 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO4, RK_PC5, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 1)), /* UART9 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO4, RK_PA4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 2)), /* UART9 IO mux selection M2 */
+	MR_TOPGRF(RK_GPIO1, RK_PA2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(11, 10, 0)), /* I2S1 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PC6, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(11, 10, 1)), /* I2S1 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(11, 10, 2)), /* I2S1 IO mux selection M2 */
+	MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(12, 12, 0)), /* I2S2 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO4, RK_PB6, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(12, 12, 1)), /* I2S2 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PA2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(14, 14, 0)), /* I2S3 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(14, 14, 1)), /* I2S3 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(0, 0, 0)), /* PDM IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD6, RK_FUNC_5, 0x0314, RK_GENMASK_VAL(0, 0, 1)), /* PDM IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO0, RK_PA5, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(3, 2, 0)), /* PCIE20 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 1)), /* PCIE20 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO1, RK_PB0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 2)), /* PCIE20 IO mux selection M2 */
+	MR_TOPGRF(RK_GPIO0, RK_PA4, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PD2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO1, RK_PA5, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux selection M2 */
+	MR_TOPGRF(RK_GPIO0, RK_PA6, RK_FUNC_2, 0x0314, RK_GENMASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PD4, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux selection M2 */
+};
+
+static int rk3568_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
+{
+	struct rockchip_pinctrl_priv *priv = bank->priv;
+	int iomux_num = (pin / 8);
+	struct regmap *regmap;
+	int reg, ret, mask;
+	u8 bit;
+	u32 data;
+
+	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
+
+	if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+		regmap = priv->regmap_pmu;
+	else
+		regmap = priv->regmap_base;
+
+	reg = bank->iomux[iomux_num].offset;
+	if ((pin % 8) >= 4)
+		reg += 0x4;
+	bit = (pin % 4) * 4;
+	mask = 0xf;
+
+	data = (mask << (bit + 16));
+	data |= (mux & mask) << bit;
+	ret = regmap_write(regmap, reg, data);
+
+	return ret;
+}
+
+#define RK3568_PULL_PMU_OFFSET		0x20
+#define RK3568_PULL_GRF_OFFSET		0x80
+#define RK3568_PULL_BITS_PER_PIN	2
+#define RK3568_PULL_PINS_PER_REG	8
+#define RK3568_PULL_BANK_STRIDE		0x10
+
+static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+					 int pin_num, struct regmap **regmap,
+					 int *reg, u8 *bit)
+{
+	struct rockchip_pinctrl_priv *info = bank->priv;
+
+	if (bank->bank_num == 0) {
+		*regmap = info->regmap_pmu;
+		*reg = RK3568_PULL_PMU_OFFSET;
+		*reg += bank->bank_num * RK3568_PULL_BANK_STRIDE;
+	} else {
+		*regmap = info->regmap_base;
+		*reg = RK3568_PULL_GRF_OFFSET;
+		*reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE;
+	}
+
+	*reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
+	*bit = (pin_num % RK3568_PULL_PINS_PER_REG);
+	*bit *= RK3568_PULL_BITS_PER_PIN;
+}
+
+#define RK3568_DRV_PMU_OFFSET		0x70
+#define RK3568_DRV_GRF_OFFSET		0x200
+#define RK3568_DRV_BITS_PER_PIN		8
+#define RK3568_DRV_PINS_PER_REG		2
+#define RK3568_DRV_BANK_STRIDE		0x40
+
+static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+					int pin_num, struct regmap **regmap,
+					int *reg, u8 *bit)
+{
+	struct rockchip_pinctrl_priv *info = bank->priv;
+
+	/* The first 32 pins of the first bank are located in PMU */
+	if (bank->bank_num == 0) {
+		*regmap = info->regmap_pmu;
+		*reg = RK3568_DRV_PMU_OFFSET;
+	} else {
+		*regmap = info->regmap_base;
+		*reg = RK3568_DRV_GRF_OFFSET;
+		*reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE;
+	}
+
+	*reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
+	*bit = (pin_num % RK3568_DRV_PINS_PER_REG);
+	*bit *= RK3568_DRV_BITS_PER_PIN;
+}
+
+#define RK3568_SCHMITT_BITS_PER_PIN		2
+#define RK3568_SCHMITT_PINS_PER_REG		8
+#define RK3568_SCHMITT_BANK_STRIDE		0x10
+#define RK3568_SCHMITT_GRF_OFFSET		0xc0
+#define RK3568_SCHMITT_PMUGRF_OFFSET		0x30
+
+static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
+					   int pin_num, struct regmap **regmap,
+					   int *reg, u8 *bit)
+{
+	struct rockchip_pinctrl_priv *info = bank->priv;
+
+	if (bank->bank_num == 0) {
+		*regmap = info->regmap_pmu;
+		*reg = RK3568_SCHMITT_PMUGRF_OFFSET;
+	} else {
+		*regmap = info->regmap_base;
+		*reg = RK3568_SCHMITT_GRF_OFFSET;
+		*reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE;
+	}
+
+	*reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4);
+	*bit = pin_num % RK3568_SCHMITT_PINS_PER_REG;
+	*bit *= RK3568_SCHMITT_BITS_PER_PIN;
+
+	return 0;
+}
+
+static int rk3568_set_pull(struct rockchip_pin_bank *bank,
+			   int pin_num, int pull)
+{
+	struct regmap *regmap;
+	int reg, ret;
+	u8 bit, type;
+	u32 data;
+
+	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
+		return -ENOTSUPP;
+
+	rk3568_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+	type = bank->pull_type[pin_num / 8];
+	ret = rockchip_translate_pull_value(type, pull);
+	if (ret < 0) {
+		debug("unsupported pull setting %d\n", pull);
+		return ret;
+	}
+
+	/* enable the write to the equivalent lower bits */
+	data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
+
+	data |= (ret << bit);
+	ret = regmap_write(regmap, reg, data);
+
+	return ret;
+}
+
+static int rk3568_set_drive(struct rockchip_pin_bank *bank,
+			    int pin_num, int strength)
+{
+	struct regmap *regmap;
+	int reg;
+	u32 data;
+	u8 bit;
+	int drv = (1 << (strength + 1)) - 1;
+	int ret = 0;
+
+	rk3568_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+
+	/* enable the write to the equivalent lower bits */
+	data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << (bit + 16);
+	data |= (drv << bit);
+
+	ret = regmap_write(regmap, reg, data);
+	if (ret)
+		return ret;
+
+	if (bank->bank_num == 1 && pin_num == 21)
+		reg = 0x0840;
+	else if (bank->bank_num == 2 && pin_num == 2)
+		reg = 0x0844;
+	else if (bank->bank_num == 2 && pin_num == 8)
+		reg = 0x0848;
+	else if (bank->bank_num == 3 && pin_num == 0)
+		reg = 0x084c;
+	else if (bank->bank_num == 3 && pin_num == 6)
+		reg = 0x0850;
+	else if (bank->bank_num == 4 && pin_num == 0)
+		reg = 0x0854;
+	else
+		return 0;
+
+	data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << 16;
+	data |= drv;
+
+	return regmap_write(regmap, reg, data);
+}
+
+static int rk3568_set_schmitt(struct rockchip_pin_bank *bank,
+			      int pin_num, int enable)
+{
+	struct regmap *regmap;
+	int reg;
+	u32 data;
+	u8 bit;
+
+	rk3568_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+
+	/* enable the write to the equivalent lower bits */
+	data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16);
+	data |= (enable << bit);
+
+	return regmap_write(regmap, reg, data);
+}
+
+static struct rockchip_pin_bank rk3568_pin_banks[] = {
+	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
+			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
+			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
+			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT),
+	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT),
+	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT),
+	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT),
+	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT),
+};
+
+static const struct rockchip_pin_ctrl rk3568_pin_ctrl = {
+	.pin_banks		= rk3568_pin_banks,
+	.nr_banks		= ARRAY_SIZE(rk3568_pin_banks),
+	.nr_pins		= 160,
+	.grf_mux_offset		= 0x0,
+	.pmu_mux_offset		= 0x0,
+	.iomux_routes		= rk3568_mux_route_data,
+	.niomux_routes		= ARRAY_SIZE(rk3568_mux_route_data),
+	.set_mux		= rk3568_set_mux,
+	.set_pull		= rk3568_set_pull,
+	.set_drive		= rk3568_set_drive,
+	.set_schmitt		= rk3568_set_schmitt,
+};
+
+static const struct udevice_id rk3568_pinctrl_ids[] = {
+	{
+		.compatible = "rockchip,rk3568-pinctrl",
+		.data = (ulong)&rk3568_pin_ctrl
+	},
+	{ }
+};
+
+U_BOOT_DRIVER(pinctrl_rk3568) = {
+	.name		= "rockchip_rk3568_pinctrl",
+	.id		= UCLASS_PINCTRL,
+	.of_match	= rk3568_pinctrl_ids,
+	.priv_auto	= sizeof(struct rockchip_pinctrl_priv),
+	.ops		= &rockchip_pinctrl_ops,
+#if CONFIG_IS_ENABLED(OF_REAL)
+	.bind		= dm_scan_fdt_dev,
+#endif
+	.probe		= rockchip_pinctrl_probe,
+};
diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile
index 98839ad..36dc050 100644
--- a/drivers/ram/rockchip/Makefile
+++ b/drivers/ram/rockchip/Makefile
@@ -14,5 +14,6 @@
 obj-$(CONFIG_ROCKCHIP_RK3328) = sdram_rk3328.o sdram_pctl_px30.o sdram_phy_px30.o
 obj-$(CONFIG_ROCKCHIP_RK3399) += sdram_rk3399.o
 obj-$(CONFIG_ROCKCHIP_RK3568) += sdram_rk3568.o
+obj-$(CONFIG_ROCKCHIP_RK3588) += sdram_rk3588.o
 obj-$(CONFIG_ROCKCHIP_RV1126) += sdram_rv1126.o sdram_pctl_px30.o
 obj-$(CONFIG_ROCKCHIP_SDRAM_COMMON) += sdram_common.o
diff --git a/drivers/ram/rockchip/sdram_rk3588.c b/drivers/ram/rockchip/sdram_rk3588.c
new file mode 100644
index 0000000..cf56e2a
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_rk3588.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2021 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ram.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/grf_rk3588.h>
+#include <asm/arch-rockchip/sdram.h>
+
+struct dram_info {
+	struct ram_info info;
+	struct rk3588_pmu1grf *pmugrf;
+};
+
+static int rk3588_dmc_probe(struct udevice *dev)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+
+	priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
+	priv->info.base = CFG_SYS_SDRAM_BASE;
+	priv->info.size =
+		rockchip_sdram_size((phys_addr_t)&priv->pmugrf->os_reg[2]) +
+		rockchip_sdram_size((phys_addr_t)&priv->pmugrf->os_reg[4]);
+
+	return 0;
+}
+
+static int rk3588_dmc_get_info(struct udevice *dev, struct ram_info *info)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+
+	*info = priv->info;
+
+	return 0;
+}
+
+static struct ram_ops rk3588_dmc_ops = {
+	.get_info = rk3588_dmc_get_info,
+};
+
+static const struct udevice_id rk3588_dmc_ids[] = {
+	{ .compatible = "rockchip,rk3588-dmc" },
+	{ }
+};
+
+U_BOOT_DRIVER(dmc_rk3588) = {
+	.name = "rockchip_rk3588_dmc",
+	.id = UCLASS_RAM,
+	.of_match = rk3588_dmc_ids,
+	.ops = &rk3588_dmc_ops,
+	.probe = rk3588_dmc_probe,
+	.priv_auto = sizeof(struct dram_info),
+};
diff --git a/drivers/sysinfo/rcar3.c b/drivers/sysinfo/rcar3.c
index c2f4ddf..7b12798 100644
--- a/drivers/sysinfo/rcar3.c
+++ b/drivers/sysinfo/rcar3.c
@@ -16,12 +16,14 @@
 #define BOARD_SALVATOR_X	0x0
 #define BOARD_KRIEK		0x1
 #define BOARD_STARTER_KIT	0x2
+#define BOARD_EAGLE		0x3
 #define BOARD_SALVATOR_XS	0x4
+#define BOARD_CONDOR		0x6
+#define BOARD_DRAAK		0x7
 #define BOARD_EBISU		0x8
 #define BOARD_STARTER_KIT_PRE	0xB
 #define BOARD_EBISU_4D		0xD
-#define BOARD_DRAAK		0xE
-#define BOARD_EAGLE		0xF
+#define BOARD_CONDOR_I		0x10
 
 /**
  * struct sysinfo_rcar_priv - sysinfo private data
@@ -65,6 +67,7 @@
 	const u8 board_rev = priv->val & BOARD_REV_MASK;
 	bool salvator_xs = false;
 	bool ebisu_4d = false;
+	bool condor_i = false;
 	char rev_major = '?';
 	char rev_minor = '?';
 
@@ -138,6 +141,18 @@
 			 "Renesas Kriek board rev %c.%c",
 			 rev_major, rev_minor);
 		return;
+	case BOARD_CONDOR_I:
+		condor_i = true;
+		fallthrough;
+	case BOARD_CONDOR:
+		if (!board_rev) { /* Only rev 0 is valid */
+			rev_major = '1';
+			rev_minor = '0';
+		}
+		snprintf(priv->boardmodel, sizeof(priv->boardmodel),
+			"Renesas Condor%s board rev %c.%c",
+			condor_i ? "-I" : "", rev_major, rev_minor);
+		return;
 	default:
 		snprintf(priv->boardmodel, sizeof(priv->boardmodel),
 			 "Renesas -Unknown- board rev ?.?");
diff --git a/drivers/timer/sandbox_timer.c b/drivers/timer/sandbox_timer.c
index c846bfb..1da7e0c 100644
--- a/drivers/timer/sandbox_timer.c
+++ b/drivers/timer/sandbox_timer.c
@@ -66,6 +66,8 @@
 };
 
 /* This is here in case we don't have a device tree */
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 U_BOOT_DRVINFO(sandbox_timer_non_fdt) = {
 	.name = "sandbox_timer",
 };
+#endif
diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c
index 192c7b7..f86a0b8 100644
--- a/drivers/timer/tsc_timer.c
+++ b/drivers/timer/tsc_timer.c
@@ -404,6 +404,15 @@
 	if (!gd->arch.clock_rate) {
 		unsigned long fast_calibrate;
 
+		/**
+		 * There is no obvious way to obtain this information from EFI
+		 * boot services. This value was measured on a Framework Laptop
+		 * which has a 12th Gen Intel Core
+		 */
+		if (IS_ENABLED(CONFIG_EFI_APP)) {
+			fast_calibrate = 2750;
+			goto done;
+		}
 		fast_calibrate = native_calibrate_tsc();
 		if (fast_calibrate)
 			goto done;
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index ebe6bf9..94fb32d 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -115,6 +115,17 @@
 	  power regulator. An example for such a hub is the Microchip
 	  USB2514B.
 
+config USB_HUB_DEBOUNCE_TIMEOUT
+	int "Timeout in milliseconds for USB HUB connection"
+	default 1000
+	help
+	  Value in milliseconds of the USB connection timeout, the max delay to
+	  wait the hub port status to be connected steadily after being powered
+	  off and powered on in the usb hub driver.
+	  This define allows to increase the HUB_DEBOUNCE_TIMEOUT default
+	  value = 1s because some usb device needs around 1.5s to be initialized
+	  and a 2s value should solve detection issue on problematic USB keys.
+
 if USB_KEYBOARD
 
 config USB_KEYBOARD_FN_KEYS
diff --git a/drivers/video/coreboot.c b/drivers/video/coreboot.c
index d2d87c7..c586475 100644
--- a/drivers/video/coreboot.c
+++ b/drivers/video/coreboot.c
@@ -57,7 +57,7 @@
 		goto err;
 	}
 
-	ret = vesa_setup_video_priv(vesa, uc_priv, plat);
+	ret = vesa_setup_video_priv(vesa, vesa->phys_base_ptr, uc_priv, plat);
 	if (ret) {
 		ret = log_msg_ret("setup", ret);
 		goto err;
diff --git a/drivers/video/efi.c b/drivers/video/efi.c
index b11e42c..28ac15f 100644
--- a/drivers/video/efi.c
+++ b/drivers/video/efi.c
@@ -5,6 +5,8 @@
  * EFI framebuffer driver based on GOP
  */
 
+#define LOG_CATEGORY LOGC_EFI
+
 #include <common.h>
 #include <dm.h>
 #include <efi_api.h>
@@ -50,7 +52,19 @@
 	*size = len;
 }
 
-static int get_mode_info(struct vesa_mode_info *vesa)
+/**
+ * get_mode_info() - Ask EFI for the mode information
+ *
+ * Gets info from the graphics-output protocol
+ *
+ * @vesa: Place to put the mode information
+ * @fbp: Returns the address of the frame buffer
+ * @infop: Returns a pointer to the mode info
+ * Returns: 0 if OK, -ENOSYS if boot services are not available, -ENOTSUPP if
+ * the protocol is not supported by EFI
+ */
+static int get_mode_info(struct vesa_mode_info *vesa, u64 *fbp,
+			 struct efi_gop_mode_info **infop)
 {
 	efi_guid_t efi_gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
 	struct efi_boot_services *boot = efi_get_boot();
@@ -63,41 +77,70 @@
 	ret = boot->locate_protocol(&efi_gop_guid, NULL, (void **)&gop);
 	if (ret)
 		return log_msg_ret("prot", -ENOTSUPP);
-
 	mode = gop->mode;
+	log_debug("maxmode %u, mode %u, info %p, size %lx, fb %lx, fb_size %lx\n",
+		  mode->max_mode, mode->mode, mode->info, mode->info_size,
+		  (ulong)mode->fb_base, (ulong)mode->fb_size);
+
 	vesa->phys_base_ptr = mode->fb_base;
+	*fbp = mode->fb_base;
 	vesa->x_resolution = mode->info->width;
 	vesa->y_resolution = mode->info->height;
+	*infop = mode->info;
 
 	return 0;
 }
 
-static int save_vesa_mode(struct vesa_mode_info *vesa)
+/**
+ * get_mode_from_entry() - Obtain fb info from the EFIET_GOP_MODE payload entry
+ *
+ * This gets the mode information provided by the stub to the payload and puts
+ * it into a vesa structure. It also returns the mode information.
+ *
+ * @vesa: Place to put the mode information
+ * @fbp: Returns the address of the frame buffer
+ * @infop: Returns a pointer to the mode info
+ * Returns: 0 if OK, -ve on error
+ */
+static int get_mode_from_entry(struct vesa_mode_info *vesa, u64 *fbp,
+			       struct efi_gop_mode_info **infop)
 {
-	struct efi_entry_gopmode *mode;
-	const struct efi_framebuffer *fbinfo;
+	struct efi_gop_mode *mode;
 	int size;
 	int ret;
 
-	if (IS_ENABLED(CONFIG_EFI_APP)) {
-		ret = get_mode_info(vesa);
-		if (ret) {
-			printf("EFI graphics output protocol not found\n");
-			return -ENXIO;
-		}
-	} else {
-		ret = efi_info_get(EFIET_GOP_MODE, (void **)&mode, &size);
-		if (ret == -ENOENT) {
-			printf("EFI graphics output protocol mode not found\n");
-			return -ENXIO;
-		}
-		vesa->phys_base_ptr = mode->fb_base;
-		vesa->x_resolution = mode->info->width;
-		vesa->y_resolution = mode->info->height;
+	ret = efi_info_get(EFIET_GOP_MODE, (void **)&mode, &size);
+	if (ret) {
+		printf("EFI graphics output entry not found\n");
+		return ret;
+	}
+	vesa->phys_base_ptr = mode->fb_base;
+	*fbp = mode->fb_base;
+	vesa->x_resolution = mode->info->width;
+	vesa->y_resolution = mode->info->height;
+	*infop = mode->info;
+
+	return 0;
+}
+
+static int save_vesa_mode(struct vesa_mode_info *vesa, u64 *fbp)
+{
+	const struct efi_framebuffer *fbinfo;
+	struct efi_gop_mode_info *info;
+	int ret;
+
+	if (IS_ENABLED(CONFIG_EFI_APP))
+		ret = get_mode_info(vesa, fbp, &info);
+	else
+		ret = get_mode_from_entry(vesa, fbp, &info);
+	if (ret) {
+		printf("EFI graphics output protocol not found (err=%dE)\n",
+		       ret);
+		return ret;
 	}
 
-	if (mode->info->pixel_format < EFI_GOT_BITMASK) {
-		fbinfo = &efi_framebuffer_format_map[mode->info->pixel_format];
+	if (info->pixel_format < EFI_GOT_BITMASK) {
+		fbinfo = &efi_framebuffer_format_map[info->pixel_format];
 		vesa->red_mask_size = fbinfo->red.size;
 		vesa->red_mask_pos = fbinfo->red.pos;
 		vesa->green_mask_size = fbinfo->green.size;
@@ -108,29 +151,28 @@
 		vesa->reserved_mask_pos = fbinfo->rsvd.pos;
 
 		vesa->bits_per_pixel = 32;
-		vesa->bytes_per_scanline = mode->info->pixels_per_scanline * 4;
-	} else if (mode->info->pixel_format == EFI_GOT_BITMASK) {
-		efi_find_pixel_bits(mode->info->pixel_bitmask[0],
+		vesa->bytes_per_scanline = info->pixels_per_scanline * 4;
+	} else if (info->pixel_format == EFI_GOT_BITMASK) {
+		efi_find_pixel_bits(info->pixel_bitmask[0],
 				    &vesa->red_mask_pos,
 				    &vesa->red_mask_size);
-		efi_find_pixel_bits(mode->info->pixel_bitmask[1],
+		efi_find_pixel_bits(info->pixel_bitmask[1],
 				    &vesa->green_mask_pos,
 				    &vesa->green_mask_size);
-		efi_find_pixel_bits(mode->info->pixel_bitmask[2],
+		efi_find_pixel_bits(info->pixel_bitmask[2],
 				    &vesa->blue_mask_pos,
 				    &vesa->blue_mask_size);
-		efi_find_pixel_bits(mode->info->pixel_bitmask[3],
+		efi_find_pixel_bits(info->pixel_bitmask[3],
 				    &vesa->reserved_mask_pos,
 				    &vesa->reserved_mask_size);
 		vesa->bits_per_pixel = vesa->red_mask_size +
 				       vesa->green_mask_size +
 				       vesa->blue_mask_size +
 				       vesa->reserved_mask_size;
-		vesa->bytes_per_scanline = (mode->info->pixels_per_scanline *
+		vesa->bytes_per_scanline = (info->pixels_per_scanline *
 					    vesa->bits_per_pixel) / 8;
 	} else {
-		debug("efi set unknown framebuffer format: %d\n",
-		      mode->info->pixel_format);
+		log_err("Unknown framebuffer format: %d\n", info->pixel_format);
 		return -EINVAL;
 	}
 
@@ -142,19 +184,20 @@
 	struct video_uc_plat *plat = dev_get_uclass_plat(dev);
 	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct vesa_mode_info *vesa = &mode_info.vesa;
+	u64 fb;
 	int ret;
 
 	/* Initialize vesa_mode_info structure */
-	ret = save_vesa_mode(vesa);
+	ret = save_vesa_mode(vesa, &fb);
 	if (ret)
 		goto err;
 
-	ret = vesa_setup_video_priv(vesa, uc_priv, plat);
+	ret = vesa_setup_video_priv(vesa, fb, uc_priv, plat);
 	if (ret)
 		goto err;
 
-	printf("Video: %dx%dx%d\n", uc_priv->xsize, uc_priv->ysize,
-	       vesa->bits_per_pixel);
+	printf("Video: %dx%dx%d @ %lx\n", uc_priv->xsize, uc_priv->ysize,
+	       vesa->bits_per_pixel, (ulong)fb);
 
 	return 0;
 
@@ -163,6 +206,30 @@
 	return ret;
 }
 
+static int efi_video_bind(struct udevice *dev)
+{
+	if (IS_ENABLED(CONFIG_VIDEO_COPY)) {
+		struct video_uc_plat *plat = dev_get_uclass_plat(dev);
+		struct vesa_mode_info vesa;
+		int ret;
+		u64 fb;
+
+		/*
+		 * Initialise vesa_mode_info structure so we can figure out the
+		 * required framebuffer size. If something goes wrong, just do
+		 * without a copy framebuffer
+		 */
+		ret = save_vesa_mode(&vesa, &fb);
+		if (!ret) {
+			/* this is not reached if the EFI call failed */
+			plat->copy_size = vesa.bytes_per_scanline *
+				vesa.y_resolution;
+		}
+	}
+
+	return 0;
+}
+
 static const struct udevice_id efi_video_ids[] = {
 	{ .compatible = "efi-fb" },
 	{ }
@@ -172,5 +239,6 @@
 	.name	= "efi_video",
 	.id	= UCLASS_VIDEO,
 	.of_match = efi_video_ids,
+	.bind	= efi_video_bind,
 	.probe	= efi_video_probe,
 };
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index a5f2350..1225de2 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -656,6 +656,18 @@
 }
 #endif
 
+int vidconsole_clear_and_reset(struct udevice *dev)
+{
+	int ret;
+
+	ret = video_clear(dev_get_parent(dev));
+	if (ret)
+		return ret;
+	vidconsole_position_cursor(dev, 0, 0);
+
+	return 0;
+}
+
 void vidconsole_position_cursor(struct udevice *dev, unsigned col, unsigned row)
 {
 	struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index ab482f1..da89f43 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -78,24 +78,40 @@
 	priv->flush_dcache = flush;
 }
 
+static ulong alloc_fb_(ulong align, ulong size, ulong *addrp)
+{
+	ulong base;
+
+	align = align ? align : 1 << 20;
+	base = *addrp - size;
+	base &= ~(align - 1);
+	size = *addrp - base;
+	*addrp = base;
+
+	return size;
+}
+
 static ulong alloc_fb(struct udevice *dev, ulong *addrp)
 {
 	struct video_uc_plat *plat = dev_get_uclass_plat(dev);
-	ulong base, align, size;
+	ulong size;
 
-	if (!plat->size)
+	if (!plat->size) {
+		if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->copy_size) {
+			size = alloc_fb_(plat->align, plat->copy_size, addrp);
+			plat->copy_base = *addrp;
+			return size;
+		}
+
 		return 0;
+	}
 
 	/* Allow drivers to allocate the frame buffer themselves */
 	if (plat->base)
 		return 0;
 
-	align = plat->align ? plat->align : 1 << 20;
-	base = *addrp - plat->size;
-	base &= ~(align - 1);
-	plat->base = base;
-	size = *addrp - base;
-	*addrp = base;
+	size = alloc_fb_(plat->align, plat->size, addrp);
+	plat->base = *addrp;
 
 	return size;
 }
diff --git a/include/configs/neural-compute-module-6.h b/include/configs/neural-compute-module-6.h
new file mode 100644
index 0000000..52501b7
--- /dev/null
+++ b/include/configs/neural-compute-module-6.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#ifndef __NEURAL_COMPUTE_MODULE_6_H
+#define __NEURAL_COMPUTE_MODULE_6_H
+
+#define ROCKCHIP_DEVICE_SETTINGS \
+		"stdout=serial,vidconsole\0" \
+		"stderr=serial,vidconsole\0"
+
+#include <configs/rk3588_common.h>
+
+#endif /* __NEURAL_COMPUTE_MODULE_6_H */
diff --git a/include/configs/rk3328_common.h b/include/configs/rk3328_common.h
index fadcb93..24b21c0 100644
--- a/include/configs/rk3328_common.h
+++ b/include/configs/rk3328_common.h
@@ -19,7 +19,9 @@
 	"pxefile_addr_r=0x00600000\0" \
 	"fdt_addr_r=0x01f00000\0" \
 	"kernel_addr_r=0x02080000\0" \
-	"ramdisk_addr_r=0x06000000\0"
+	"ramdisk_addr_r=0x06000000\0" \
+	"kernel_comp_addr_r=0x08000000\0" \
+	"kernel_comp_size=0x2000000\0"
 
 #include <config_distro_bootcmd.h>
 #define CFG_EXTRA_ENV_SETTINGS \
diff --git a/include/configs/rk3568_common.h b/include/configs/rk3568_common.h
index ae36010..a5e1dde 100644
--- a/include/configs/rk3568_common.h
+++ b/include/configs/rk3568_common.h
@@ -6,6 +6,8 @@
 #ifndef __CONFIG_RK3568_COMMON_H
 #define __CONFIG_RK3568_COMMON_H
 
+#define CFG_CPUID_OFFSET	0xa
+
 #include "rockchip-common.h"
 
 #define CFG_IRAM_BASE		0xfdcc0000
diff --git a/include/configs/rk3588_common.h b/include/configs/rk3588_common.h
new file mode 100644
index 0000000..abd2013
--- /dev/null
+++ b/include/configs/rk3588_common.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier:     GPL-2.0+ */
+/*
+ * (C) Copyright 2021 Rockchip Electronics Co., Ltd
+ * Copyright (c) 2023 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#ifndef __CONFIG_RK3588_COMMON_H
+#define __CONFIG_RK3588_COMMON_H
+
+#include "rockchip-common.h"
+
+#define CFG_IRAM_BASE			0xff000000
+
+#define CFG_SYS_SDRAM_BASE		0
+#define SDRAM_MAX_SIZE			0xf0000000
+
+#define ENV_MEM_LAYOUT_SETTINGS		\
+	"scriptaddr=0x00c00000\0"	\
+	"pxefile_addr_r=0x00e00000\0"	\
+	"fdt_addr_r=0x0a100000\0"	\
+	"kernel_addr_r=0x02080000\0"	\
+	"ramdisk_addr_r=0x0a200000\0"
+
+#include <config_distro_bootcmd.h>
+#define CFG_EXTRA_ENV_SETTINGS \
+	"fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \
+	"partitions=" PARTS_DEFAULT		\
+	ENV_MEM_LAYOUT_SETTINGS			\
+	ROCKCHIP_DEVICE_SETTINGS		\
+	BOOTENV
+
+#endif /* __CONFIG_RK3588_COMMON_H */
diff --git a/include/configs/rock5b-rk3588.h b/include/configs/rock5b-rk3588.h
new file mode 100644
index 0000000..4f75c80
--- /dev/null
+++ b/include/configs/rock5b-rk3588.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2022 Collabora Ltd.
+ */
+
+#ifndef __ROCK5B_RK3588_H
+#define __ROCK5B_RK3588_H
+
+#define ROCKCHIP_DEVICE_SETTINGS \
+		"stdout=serial,vidconsole\0" \
+		"stderr=serial,vidconsole\0"
+
+#include <configs/rk3588_common.h>
+
+#endif /* __ROCK5B_RK3588_H */
diff --git a/include/configs/rockchip-common.h b/include/configs/rockchip-common.h
index ff8123d..b7c5c66 100644
--- a/include/configs/rockchip-common.h
+++ b/include/configs/rockchip-common.h
@@ -7,6 +7,10 @@
 #define _ROCKCHIP_COMMON_H_
 #include <linux/sizes.h>
 
+#ifndef CFG_CPUID_OFFSET
+#define CFG_CPUID_OFFSET	0x7
+#endif
+
 /* ((CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR - 64) * 512) */
 
 #ifndef CONFIG_SPL_BUILD
diff --git a/include/dt-bindings/clock/rockchip,rk3588-cru.h b/include/dt-bindings/clock/rockchip,rk3588-cru.h
new file mode 100644
index 0000000..b5616bc
--- /dev/null
+++ b/include/dt-bindings/clock/rockchip,rk3588-cru.h
@@ -0,0 +1,766 @@
+/* SPDX-License-Identifier: (GPL-2.0 or MIT) */
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co. Ltd.
+ * Copyright (c) 2022 Collabora Ltd.
+ *
+ * Author: Elaine Zhang <zhangqing@rock-chips.com>
+ * Author: Sebastian Reichel <sebastian.reichel@collabora.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3588_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3588_H
+
+/* cru-clocks indices */
+
+#define PLL_B0PLL			0
+#define PLL_B1PLL			1
+#define PLL_LPLL			2
+#define PLL_V0PLL			3
+#define PLL_AUPLL			4
+#define PLL_CPLL			5
+#define PLL_GPLL			6
+#define PLL_NPLL			7
+#define PLL_PPLL			8
+#define ARMCLK_L			9
+#define ARMCLK_B01			10
+#define ARMCLK_B23			11
+#define PCLK_BIGCORE0_ROOT		12
+#define PCLK_BIGCORE0_PVTM		13
+#define PCLK_BIGCORE1_ROOT		14
+#define PCLK_BIGCORE1_PVTM		15
+#define PCLK_DSU_S_ROOT			16
+#define PCLK_DSU_ROOT			17
+#define PCLK_DSU_NS_ROOT		18
+#define PCLK_LITCORE_PVTM		19
+#define PCLK_DBG			20
+#define PCLK_DSU			21
+#define PCLK_S_DAPLITE			22
+#define PCLK_M_DAPLITE			23
+#define MBIST_MCLK_PDM1			24
+#define MBIST_CLK_ACDCDIG		25
+#define HCLK_I2S2_2CH			26
+#define HCLK_I2S3_2CH			27
+#define CLK_I2S2_2CH_SRC		28
+#define CLK_I2S2_2CH_FRAC		29
+#define CLK_I2S2_2CH			30
+#define MCLK_I2S2_2CH			31
+#define I2S2_2CH_MCLKOUT		32
+#define CLK_DAC_ACDCDIG			33
+#define CLK_I2S3_2CH_SRC		34
+#define CLK_I2S3_2CH_FRAC		35
+#define CLK_I2S3_2CH			36
+#define MCLK_I2S3_2CH			37
+#define I2S3_2CH_MCLKOUT		38
+#define PCLK_ACDCDIG			39
+#define HCLK_I2S0_8CH			40
+#define CLK_I2S0_8CH_TX_SRC		41
+#define CLK_I2S0_8CH_TX_FRAC		42
+#define MCLK_I2S0_8CH_TX		43
+#define CLK_I2S0_8CH_TX			44
+#define CLK_I2S0_8CH_RX_SRC		45
+#define CLK_I2S0_8CH_RX_FRAC		46
+#define MCLK_I2S0_8CH_RX		47
+#define CLK_I2S0_8CH_RX			48
+#define I2S0_8CH_MCLKOUT		49
+#define HCLK_PDM1			50
+#define MCLK_PDM1			51
+#define HCLK_AUDIO_ROOT			52
+#define PCLK_AUDIO_ROOT			53
+#define HCLK_SPDIF0			54
+#define CLK_SPDIF0_SRC			55
+#define CLK_SPDIF0_FRAC			56
+#define MCLK_SPDIF0			57
+#define CLK_SPDIF0			58
+#define CLK_SPDIF1			59
+#define HCLK_SPDIF1			60
+#define CLK_SPDIF1_SRC			61
+#define CLK_SPDIF1_FRAC			62
+#define MCLK_SPDIF1			63
+#define ACLK_AV1_ROOT			64
+#define ACLK_AV1			65
+#define PCLK_AV1_ROOT			66
+#define PCLK_AV1			67
+#define PCLK_MAILBOX0			68
+#define PCLK_MAILBOX1			69
+#define PCLK_MAILBOX2			70
+#define PCLK_PMU2			71
+#define PCLK_PMUCM0_INTMUX		72
+#define PCLK_DDRCM0_INTMUX		73
+#define PCLK_TOP			74
+#define PCLK_PWM1			75
+#define CLK_PWM1			76
+#define CLK_PWM1_CAPTURE		77
+#define PCLK_PWM2			78
+#define CLK_PWM2			79
+#define CLK_PWM2_CAPTURE		80
+#define PCLK_PWM3			81
+#define CLK_PWM3			82
+#define CLK_PWM3_CAPTURE		83
+#define PCLK_BUSTIMER0			84
+#define PCLK_BUSTIMER1			85
+#define CLK_BUS_TIMER_ROOT		86
+#define CLK_BUSTIMER0			87
+#define CLK_BUSTIMER1			88
+#define CLK_BUSTIMER2			89
+#define CLK_BUSTIMER3			90
+#define CLK_BUSTIMER4			91
+#define CLK_BUSTIMER5			92
+#define CLK_BUSTIMER6			93
+#define CLK_BUSTIMER7			94
+#define CLK_BUSTIMER8			95
+#define CLK_BUSTIMER9			96
+#define CLK_BUSTIMER10			97
+#define CLK_BUSTIMER11			98
+#define PCLK_WDT0			99
+#define TCLK_WDT0			100
+#define PCLK_CAN0			101
+#define CLK_CAN0			102
+#define PCLK_CAN1			103
+#define CLK_CAN1			104
+#define PCLK_CAN2			105
+#define CLK_CAN2			106
+#define ACLK_DECOM			107
+#define PCLK_DECOM			108
+#define DCLK_DECOM			109
+#define ACLK_DMAC0			110
+#define ACLK_DMAC1			111
+#define ACLK_DMAC2			112
+#define ACLK_BUS_ROOT			113
+#define ACLK_GIC			114
+#define PCLK_GPIO1			115
+#define DBCLK_GPIO1			116
+#define PCLK_GPIO2			117
+#define DBCLK_GPIO2			118
+#define PCLK_GPIO3			119
+#define DBCLK_GPIO3			120
+#define PCLK_GPIO4			121
+#define DBCLK_GPIO4			122
+#define PCLK_I2C1			123
+#define PCLK_I2C2			124
+#define PCLK_I2C3			125
+#define PCLK_I2C4			126
+#define PCLK_I2C5			127
+#define PCLK_I2C6			128
+#define PCLK_I2C7			129
+#define PCLK_I2C8			130
+#define CLK_I2C1			131
+#define CLK_I2C2			132
+#define CLK_I2C3			133
+#define CLK_I2C4			134
+#define CLK_I2C5			135
+#define CLK_I2C6			136
+#define CLK_I2C7			137
+#define CLK_I2C8			138
+#define PCLK_OTPC_NS			139
+#define CLK_OTPC_NS			140
+#define CLK_OTPC_ARB			141
+#define CLK_OTPC_AUTO_RD_G		142
+#define CLK_OTP_PHY_G			143
+#define PCLK_SARADC			144
+#define CLK_SARADC			145
+#define PCLK_SPI0			146
+#define PCLK_SPI1			147
+#define PCLK_SPI2			148
+#define PCLK_SPI3			149
+#define PCLK_SPI4			150
+#define CLK_SPI0			151
+#define CLK_SPI1			152
+#define CLK_SPI2			153
+#define CLK_SPI3			154
+#define CLK_SPI4			155
+#define ACLK_SPINLOCK			156
+#define PCLK_TSADC			157
+#define CLK_TSADC			158
+#define PCLK_UART1			159
+#define PCLK_UART2			160
+#define PCLK_UART3			161
+#define PCLK_UART4			162
+#define PCLK_UART5			163
+#define PCLK_UART6			164
+#define PCLK_UART7			165
+#define PCLK_UART8			166
+#define PCLK_UART9			167
+#define CLK_UART1_SRC			168
+#define CLK_UART1_FRAC			169
+#define CLK_UART1			170
+#define SCLK_UART1			171
+#define CLK_UART2_SRC			172
+#define CLK_UART2_FRAC			173
+#define CLK_UART2			174
+#define SCLK_UART2			175
+#define CLK_UART3_SRC			176
+#define CLK_UART3_FRAC			177
+#define CLK_UART3			178
+#define SCLK_UART3			179
+#define CLK_UART4_SRC			180
+#define CLK_UART4_FRAC			181
+#define CLK_UART4			182
+#define SCLK_UART4			183
+#define CLK_UART5_SRC			184
+#define CLK_UART5_FRAC			185
+#define CLK_UART5			186
+#define SCLK_UART5			187
+#define CLK_UART6_SRC			188
+#define CLK_UART6_FRAC			189
+#define CLK_UART6			190
+#define SCLK_UART6			191
+#define CLK_UART7_SRC			192
+#define CLK_UART7_FRAC			193
+#define CLK_UART7			194
+#define SCLK_UART7			195
+#define CLK_UART8_SRC			196
+#define CLK_UART8_FRAC			197
+#define CLK_UART8			198
+#define SCLK_UART8			199
+#define CLK_UART9_SRC			200
+#define CLK_UART9_FRAC			201
+#define CLK_UART9			202
+#define SCLK_UART9			203
+#define ACLK_CENTER_ROOT		204
+#define ACLK_CENTER_LOW_ROOT		205
+#define HCLK_CENTER_ROOT		206
+#define PCLK_CENTER_ROOT		207
+#define ACLK_DMA2DDR			208
+#define ACLK_DDR_SHAREMEM		209
+#define ACLK_CENTER_S200_ROOT		210
+#define ACLK_CENTER_S400_ROOT		211
+#define FCLK_DDR_CM0_CORE		212
+#define CLK_DDR_TIMER_ROOT		213
+#define CLK_DDR_TIMER0			214
+#define CLK_DDR_TIMER1			215
+#define TCLK_WDT_DDR			216
+#define CLK_DDR_CM0_RTC			217
+#define PCLK_WDT			218
+#define PCLK_TIMER			219
+#define PCLK_DMA2DDR			220
+#define PCLK_SHAREMEM			221
+#define CLK_50M_SRC			222
+#define CLK_100M_SRC			223
+#define CLK_150M_SRC			224
+#define CLK_200M_SRC			225
+#define CLK_250M_SRC			226
+#define CLK_300M_SRC			227
+#define CLK_350M_SRC			228
+#define CLK_400M_SRC			229
+#define CLK_450M_SRC			230
+#define CLK_500M_SRC			231
+#define CLK_600M_SRC			232
+#define CLK_650M_SRC			233
+#define CLK_700M_SRC			234
+#define CLK_800M_SRC			235
+#define CLK_1000M_SRC			236
+#define CLK_1200M_SRC			237
+#define ACLK_TOP_M300_ROOT		238
+#define ACLK_TOP_M500_ROOT		239
+#define ACLK_TOP_M400_ROOT		240
+#define ACLK_TOP_S200_ROOT		241
+#define ACLK_TOP_S400_ROOT		242
+#define CLK_MIPI_CAMARAOUT_M0		243
+#define CLK_MIPI_CAMARAOUT_M1		244
+#define CLK_MIPI_CAMARAOUT_M2		245
+#define CLK_MIPI_CAMARAOUT_M3		246
+#define CLK_MIPI_CAMARAOUT_M4		247
+#define MCLK_GMAC0_OUT			248
+#define REFCLKO25M_ETH0_OUT		249
+#define REFCLKO25M_ETH1_OUT		250
+#define CLK_CIFOUT_OUT			251
+#define PCLK_MIPI_DCPHY0		252
+#define PCLK_MIPI_DCPHY1		253
+#define PCLK_CSIPHY0			254
+#define PCLK_CSIPHY1			255
+#define ACLK_TOP_ROOT			256
+#define PCLK_TOP_ROOT			257
+#define ACLK_LOW_TOP_ROOT		258
+#define PCLK_CRU			259
+#define PCLK_GPU_ROOT			260
+#define CLK_GPU_SRC			261
+#define CLK_GPU				262
+#define CLK_GPU_COREGROUP		263
+#define CLK_GPU_STACKS			264
+#define PCLK_GPU_PVTM			265
+#define CLK_GPU_PVTM			266
+#define CLK_CORE_GPU_PVTM		267
+#define PCLK_GPU_GRF			268
+#define ACLK_ISP1_ROOT			269
+#define HCLK_ISP1_ROOT			270
+#define CLK_ISP1_CORE			271
+#define CLK_ISP1_CORE_MARVIN		272
+#define CLK_ISP1_CORE_VICAP		273
+#define ACLK_ISP1			274
+#define HCLK_ISP1			275
+#define ACLK_NPU1			276
+#define HCLK_NPU1			277
+#define ACLK_NPU2			278
+#define HCLK_NPU2			279
+#define HCLK_NPU_CM0_ROOT		280
+#define FCLK_NPU_CM0_CORE		281
+#define CLK_NPU_CM0_RTC			282
+#define PCLK_NPU_PVTM			283
+#define PCLK_NPU_GRF			284
+#define CLK_NPU_PVTM			285
+#define CLK_CORE_NPU_PVTM		286
+#define ACLK_NPU0			287
+#define HCLK_NPU0			288
+#define HCLK_NPU_ROOT			289
+#define CLK_NPU_DSU0			290
+#define PCLK_NPU_ROOT			291
+#define PCLK_NPU_TIMER			292
+#define CLK_NPUTIMER_ROOT		293
+#define CLK_NPUTIMER0			294
+#define CLK_NPUTIMER1			295
+#define PCLK_NPU_WDT			296
+#define TCLK_NPU_WDT			297
+#define HCLK_EMMC			298
+#define ACLK_EMMC			299
+#define CCLK_EMMC			300
+#define BCLK_EMMC			301
+#define TMCLK_EMMC			302
+#define SCLK_SFC			303
+#define HCLK_SFC			304
+#define HCLK_SFC_XIP			305
+#define HCLK_NVM_ROOT			306
+#define ACLK_NVM_ROOT			307
+#define CLK_GMAC0_PTP_REF		308
+#define CLK_GMAC1_PTP_REF		309
+#define CLK_GMAC_125M			310
+#define CLK_GMAC_50M			311
+#define ACLK_PHP_GIC_ITS		312
+#define ACLK_MMU_PCIE			313
+#define ACLK_MMU_PHP			314
+#define ACLK_PCIE_4L_DBI		315
+#define ACLK_PCIE_2L_DBI		316
+#define ACLK_PCIE_1L0_DBI		317
+#define ACLK_PCIE_1L1_DBI		318
+#define ACLK_PCIE_1L2_DBI		319
+#define ACLK_PCIE_4L_MSTR		320
+#define ACLK_PCIE_2L_MSTR		321
+#define ACLK_PCIE_1L0_MSTR		322
+#define ACLK_PCIE_1L1_MSTR		323
+#define ACLK_PCIE_1L2_MSTR		324
+#define ACLK_PCIE_4L_SLV		325
+#define ACLK_PCIE_2L_SLV		326
+#define ACLK_PCIE_1L0_SLV		327
+#define ACLK_PCIE_1L1_SLV		328
+#define ACLK_PCIE_1L2_SLV		329
+#define PCLK_PCIE_4L			330
+#define PCLK_PCIE_2L			331
+#define PCLK_PCIE_1L0			332
+#define PCLK_PCIE_1L1			333
+#define PCLK_PCIE_1L2			334
+#define CLK_PCIE_AUX0			335
+#define CLK_PCIE_AUX1			336
+#define CLK_PCIE_AUX2			337
+#define CLK_PCIE_AUX3			338
+#define CLK_PCIE_AUX4			339
+#define CLK_PIPEPHY0_REF		340
+#define CLK_PIPEPHY1_REF		341
+#define CLK_PIPEPHY2_REF		342
+#define PCLK_PHP_ROOT			343
+#define PCLK_GMAC0			344
+#define PCLK_GMAC1			345
+#define ACLK_PCIE_ROOT			346
+#define ACLK_PHP_ROOT			347
+#define ACLK_PCIE_BRIDGE		348
+#define ACLK_GMAC0			349
+#define ACLK_GMAC1			350
+#define CLK_PMALIVE0			351
+#define CLK_PMALIVE1			352
+#define CLK_PMALIVE2			353
+#define ACLK_SATA0			354
+#define ACLK_SATA1			355
+#define ACLK_SATA2			356
+#define CLK_RXOOB0			357
+#define CLK_RXOOB1			358
+#define CLK_RXOOB2			359
+#define ACLK_USB3OTG2			360
+#define SUSPEND_CLK_USB3OTG2		361
+#define REF_CLK_USB3OTG2		362
+#define CLK_UTMI_OTG2			363
+#define CLK_PIPEPHY0_PIPE_G		364
+#define CLK_PIPEPHY1_PIPE_G		365
+#define CLK_PIPEPHY2_PIPE_G		366
+#define CLK_PIPEPHY0_PIPE_ASIC_G	367
+#define CLK_PIPEPHY1_PIPE_ASIC_G	368
+#define CLK_PIPEPHY2_PIPE_ASIC_G	369
+#define CLK_PIPEPHY2_PIPE_U3_G		370
+#define CLK_PCIE1L2_PIPE		371
+#define CLK_PCIE4L_PIPE			372
+#define CLK_PCIE2L_PIPE			373
+#define PCLK_PCIE_COMBO_PIPE_PHY0	374
+#define PCLK_PCIE_COMBO_PIPE_PHY1	375
+#define PCLK_PCIE_COMBO_PIPE_PHY2	376
+#define PCLK_PCIE_COMBO_PIPE_PHY	377
+#define HCLK_RGA3_1			378
+#define ACLK_RGA3_1			379
+#define CLK_RGA3_1_CORE			380
+#define ACLK_RGA3_ROOT			381
+#define HCLK_RGA3_ROOT			382
+#define ACLK_RKVDEC_CCU			383
+#define HCLK_RKVDEC0			384
+#define ACLK_RKVDEC0			385
+#define CLK_RKVDEC0_CA			386
+#define CLK_RKVDEC0_HEVC_CA		387
+#define CLK_RKVDEC0_CORE		388
+#define HCLK_RKVDEC1			389
+#define ACLK_RKVDEC1			390
+#define CLK_RKVDEC1_CA			391
+#define CLK_RKVDEC1_HEVC_CA		392
+#define CLK_RKVDEC1_CORE		393
+#define HCLK_SDIO			394
+#define CCLK_SRC_SDIO			395
+#define ACLK_USB_ROOT			396
+#define HCLK_USB_ROOT			397
+#define HCLK_HOST0			398
+#define HCLK_HOST_ARB0			399
+#define HCLK_HOST1			400
+#define HCLK_HOST_ARB1			401
+#define ACLK_USB3OTG0			402
+#define SUSPEND_CLK_USB3OTG0		403
+#define REF_CLK_USB3OTG0		404
+#define ACLK_USB3OTG1			405
+#define SUSPEND_CLK_USB3OTG1		406
+#define REF_CLK_USB3OTG1		407
+#define UTMI_OHCI_CLK48_HOST0		408
+#define UTMI_OHCI_CLK48_HOST1		409
+#define HCLK_IEP2P0			410
+#define ACLK_IEP2P0			411
+#define CLK_IEP2P0_CORE			412
+#define ACLK_JPEG_ENCODER0		413
+#define HCLK_JPEG_ENCODER0		414
+#define ACLK_JPEG_ENCODER1		415
+#define HCLK_JPEG_ENCODER1		416
+#define ACLK_JPEG_ENCODER2		417
+#define HCLK_JPEG_ENCODER2		418
+#define ACLK_JPEG_ENCODER3		419
+#define HCLK_JPEG_ENCODER3		420
+#define ACLK_JPEG_DECODER		421
+#define HCLK_JPEG_DECODER		422
+#define HCLK_RGA2			423
+#define ACLK_RGA2			424
+#define CLK_RGA2_CORE			425
+#define HCLK_RGA3_0			426
+#define ACLK_RGA3_0			427
+#define CLK_RGA3_0_CORE			428
+#define ACLK_VDPU_ROOT			429
+#define ACLK_VDPU_LOW_ROOT		430
+#define HCLK_VDPU_ROOT			431
+#define ACLK_JPEG_DECODER_ROOT		432
+#define ACLK_VPU			433
+#define HCLK_VPU			434
+#define HCLK_RKVENC0_ROOT		435
+#define ACLK_RKVENC0_ROOT		436
+#define HCLK_RKVENC0			437
+#define ACLK_RKVENC0			438
+#define CLK_RKVENC0_CORE		439
+#define HCLK_RKVENC1_ROOT		440
+#define ACLK_RKVENC1_ROOT		441
+#define HCLK_RKVENC1			442
+#define ACLK_RKVENC1			443
+#define CLK_RKVENC1_CORE		444
+#define ICLK_CSIHOST01			445
+#define ICLK_CSIHOST0			446
+#define ICLK_CSIHOST1			447
+#define PCLK_CSI_HOST_0			448
+#define PCLK_CSI_HOST_1			449
+#define PCLK_CSI_HOST_2			450
+#define PCLK_CSI_HOST_3			451
+#define PCLK_CSI_HOST_4			452
+#define PCLK_CSI_HOST_5			453
+#define ACLK_FISHEYE0			454
+#define HCLK_FISHEYE0			455
+#define CLK_FISHEYE0_CORE		456
+#define ACLK_FISHEYE1			457
+#define HCLK_FISHEYE1			458
+#define CLK_FISHEYE1_CORE		459
+#define CLK_ISP0_CORE			460
+#define CLK_ISP0_CORE_MARVIN		461
+#define CLK_ISP0_CORE_VICAP		462
+#define ACLK_ISP0			463
+#define HCLK_ISP0			464
+#define ACLK_VI_ROOT			465
+#define HCLK_VI_ROOT			466
+#define PCLK_VI_ROOT			467
+#define DCLK_VICAP			468
+#define ACLK_VICAP			469
+#define HCLK_VICAP			470
+#define PCLK_DP0			471
+#define PCLK_DP1			472
+#define PCLK_S_DP0			473
+#define PCLK_S_DP1			474
+#define CLK_DP0				475
+#define CLK_DP1				476
+#define HCLK_HDCP_KEY0			477
+#define ACLK_HDCP0			478
+#define HCLK_HDCP0			479
+#define PCLK_HDCP0			480
+#define HCLK_I2S4_8CH			481
+#define ACLK_TRNG0			482
+#define PCLK_TRNG0			483
+#define ACLK_VO0_ROOT			484
+#define HCLK_VO0_ROOT			485
+#define HCLK_VO0_S_ROOT			486
+#define PCLK_VO0_ROOT			487
+#define PCLK_VO0_S_ROOT			488
+#define PCLK_VO0GRF			489
+#define CLK_I2S4_8CH_TX_SRC		490
+#define CLK_I2S4_8CH_TX_FRAC		491
+#define MCLK_I2S4_8CH_TX		492
+#define CLK_I2S4_8CH_TX			493
+#define HCLK_I2S8_8CH			494
+#define CLK_I2S8_8CH_TX_SRC		495
+#define CLK_I2S8_8CH_TX_FRAC		496
+#define MCLK_I2S8_8CH_TX		497
+#define CLK_I2S8_8CH_TX			498
+#define HCLK_SPDIF2_DP0			499
+#define CLK_SPDIF2_DP0_SRC		500
+#define CLK_SPDIF2_DP0_FRAC		501
+#define MCLK_SPDIF2_DP0			502
+#define CLK_SPDIF2_DP0			503
+#define MCLK_SPDIF2			504
+#define HCLK_SPDIF5_DP1			505
+#define CLK_SPDIF5_DP1_SRC		506
+#define CLK_SPDIF5_DP1_FRAC		507
+#define MCLK_SPDIF5_DP1			508
+#define CLK_SPDIF5_DP1			509
+#define MCLK_SPDIF5			510
+#define PCLK_EDP0			511
+#define CLK_EDP0_24M			512
+#define CLK_EDP0_200M			513
+#define PCLK_EDP1			514
+#define CLK_EDP1_24M			515
+#define CLK_EDP1_200M			516
+#define HCLK_HDCP_KEY1			517
+#define ACLK_HDCP1			518
+#define HCLK_HDCP1			519
+#define PCLK_HDCP1			520
+#define ACLK_HDMIRX			521
+#define PCLK_HDMIRX			522
+#define CLK_HDMIRX_REF			523
+#define CLK_HDMIRX_AUD_SRC		524
+#define CLK_HDMIRX_AUD_FRAC		525
+#define CLK_HDMIRX_AUD			526
+#define CLK_HDMIRX_AUD_P_MUX		527
+#define PCLK_HDMITX0			528
+#define CLK_HDMITX0_EARC		529
+#define CLK_HDMITX0_REF			530
+#define PCLK_HDMITX1			531
+#define CLK_HDMITX1_EARC		532
+#define CLK_HDMITX1_REF			533
+#define CLK_HDMITRX_REFSRC		534
+#define ACLK_TRNG1			535
+#define PCLK_TRNG1			536
+#define ACLK_HDCP1_ROOT			537
+#define ACLK_HDMIRX_ROOT		538
+#define HCLK_VO1_ROOT			539
+#define HCLK_VO1_S_ROOT			540
+#define PCLK_VO1_ROOT			541
+#define PCLK_VO1_S_ROOT			542
+#define PCLK_S_EDP0			543
+#define PCLK_S_EDP1			544
+#define PCLK_S_HDMIRX			545
+#define HCLK_I2S10_8CH			546
+#define CLK_I2S10_8CH_RX_SRC		547
+#define CLK_I2S10_8CH_RX_FRAC		548
+#define CLK_I2S10_8CH_RX		549
+#define MCLK_I2S10_8CH_RX		550
+#define HCLK_I2S7_8CH			551
+#define CLK_I2S7_8CH_RX_SRC		552
+#define CLK_I2S7_8CH_RX_FRAC		553
+#define CLK_I2S7_8CH_RX			554
+#define MCLK_I2S7_8CH_RX		555
+#define HCLK_I2S9_8CH			556
+#define CLK_I2S9_8CH_RX_SRC		557
+#define CLK_I2S9_8CH_RX_FRAC		558
+#define CLK_I2S9_8CH_RX			559
+#define MCLK_I2S9_8CH_RX		560
+#define CLK_I2S5_8CH_TX_SRC		561
+#define CLK_I2S5_8CH_TX_FRAC		562
+#define CLK_I2S5_8CH_TX			563
+#define MCLK_I2S5_8CH_TX		564
+#define HCLK_I2S5_8CH			565
+#define CLK_I2S6_8CH_TX_SRC		566
+#define CLK_I2S6_8CH_TX_FRAC		567
+#define CLK_I2S6_8CH_TX			568
+#define MCLK_I2S6_8CH_TX		569
+#define CLK_I2S6_8CH_RX_SRC		570
+#define CLK_I2S6_8CH_RX_FRAC		571
+#define CLK_I2S6_8CH_RX			572
+#define MCLK_I2S6_8CH_RX		573
+#define I2S6_8CH_MCLKOUT		574
+#define HCLK_I2S6_8CH			575
+#define HCLK_SPDIF3			576
+#define CLK_SPDIF3_SRC			577
+#define CLK_SPDIF3_FRAC			578
+#define CLK_SPDIF3			579
+#define MCLK_SPDIF3			580
+#define HCLK_SPDIF4			581
+#define CLK_SPDIF4_SRC			582
+#define CLK_SPDIF4_FRAC			583
+#define CLK_SPDIF4			584
+#define MCLK_SPDIF4			585
+#define HCLK_SPDIFRX0			586
+#define MCLK_SPDIFRX0			587
+#define HCLK_SPDIFRX1			588
+#define MCLK_SPDIFRX1			589
+#define HCLK_SPDIFRX2			590
+#define MCLK_SPDIFRX2			591
+#define ACLK_VO1USB_TOP_ROOT		592
+#define HCLK_VO1USB_TOP_ROOT		593
+#define CLK_HDMIHDP0			594
+#define CLK_HDMIHDP1			595
+#define PCLK_HDPTX0			596
+#define PCLK_HDPTX1			597
+#define PCLK_USBDPPHY0			598
+#define PCLK_USBDPPHY1			599
+#define ACLK_VOP_ROOT			600
+#define ACLK_VOP_LOW_ROOT		601
+#define HCLK_VOP_ROOT			602
+#define PCLK_VOP_ROOT			603
+#define HCLK_VOP			604
+#define ACLK_VOP			605
+#define DCLK_VOP0_SRC			606
+#define DCLK_VOP1_SRC			607
+#define DCLK_VOP2_SRC			608
+#define DCLK_VOP0			609
+#define DCLK_VOP1			610
+#define DCLK_VOP2			611
+#define DCLK_VOP3			612
+#define PCLK_DSIHOST0			613
+#define PCLK_DSIHOST1			614
+#define CLK_DSIHOST0			615
+#define CLK_DSIHOST1			616
+#define CLK_VOP_PMU			617
+#define ACLK_VOP_DOBY			618
+#define ACLK_VOP_SUB_SRC		619
+#define CLK_USBDP_PHY0_IMMORTAL		620
+#define CLK_USBDP_PHY1_IMMORTAL		621
+#define CLK_PMU0			622
+#define PCLK_PMU0			623
+#define PCLK_PMU0IOC			624
+#define PCLK_GPIO0			625
+#define DBCLK_GPIO0			626
+#define PCLK_I2C0			627
+#define CLK_I2C0			628
+#define HCLK_I2S1_8CH			629
+#define CLK_I2S1_8CH_TX_SRC		630
+#define CLK_I2S1_8CH_TX_FRAC		631
+#define CLK_I2S1_8CH_TX			632
+#define MCLK_I2S1_8CH_TX		633
+#define CLK_I2S1_8CH_RX_SRC		634
+#define CLK_I2S1_8CH_RX_FRAC		635
+#define CLK_I2S1_8CH_RX			636
+#define MCLK_I2S1_8CH_RX		637
+#define I2S1_8CH_MCLKOUT		638
+#define CLK_PMU1_50M_SRC		639
+#define CLK_PMU1_100M_SRC		640
+#define CLK_PMU1_200M_SRC		641
+#define CLK_PMU1_300M_SRC		642
+#define CLK_PMU1_400M_SRC		643
+#define HCLK_PMU1_ROOT			644
+#define PCLK_PMU1_ROOT			645
+#define PCLK_PMU0_ROOT			646
+#define HCLK_PMU_CM0_ROOT		647
+#define PCLK_PMU1			648
+#define CLK_DDR_FAIL_SAFE		649
+#define CLK_PMU1			650
+#define HCLK_PDM0			651
+#define MCLK_PDM0			652
+#define HCLK_VAD			653
+#define FCLK_PMU_CM0_CORE		654
+#define CLK_PMU_CM0_RTC			655
+#define PCLK_PMU1_IOC			656
+#define PCLK_PMU1PWM			657
+#define CLK_PMU1PWM			658
+#define CLK_PMU1PWM_CAPTURE		659
+#define PCLK_PMU1TIMER			660
+#define CLK_PMU1TIMER_ROOT		661
+#define CLK_PMU1TIMER0			662
+#define CLK_PMU1TIMER1			663
+#define CLK_UART0_SRC			664
+#define CLK_UART0_FRAC			665
+#define CLK_UART0			666
+#define SCLK_UART0			667
+#define PCLK_UART0			668
+#define PCLK_PMU1WDT			669
+#define TCLK_PMU1WDT			670
+#define CLK_CR_PARA			671
+#define CLK_USB2PHY_HDPTXRXPHY_REF	672
+#define CLK_USBDPPHY_MIPIDCPPHY_REF	673
+#define CLK_REF_PIPE_PHY0_OSC_SRC	674
+#define CLK_REF_PIPE_PHY1_OSC_SRC	675
+#define CLK_REF_PIPE_PHY2_OSC_SRC	676
+#define CLK_REF_PIPE_PHY0_PLL_SRC	677
+#define CLK_REF_PIPE_PHY1_PLL_SRC	678
+#define CLK_REF_PIPE_PHY2_PLL_SRC	679
+#define CLK_REF_PIPE_PHY0		680
+#define CLK_REF_PIPE_PHY1		681
+#define CLK_REF_PIPE_PHY2		682
+#define SCLK_SDIO_DRV			683
+#define SCLK_SDIO_SAMPLE		684
+#define SCLK_SDMMC_DRV			685
+#define SCLK_SDMMC_SAMPLE		686
+#define CLK_PCIE1L0_PIPE		687
+#define CLK_PCIE1L1_PIPE		688
+#define CLK_BIGCORE0_PVTM		689
+#define CLK_CORE_BIGCORE0_PVTM		690
+#define CLK_BIGCORE1_PVTM		691
+#define CLK_CORE_BIGCORE1_PVTM		692
+#define CLK_LITCORE_PVTM		693
+#define CLK_CORE_LITCORE_PVTM		694
+#define CLK_AUX16M_0			695
+#define CLK_AUX16M_1			696
+#define CLK_PHY0_REF_ALT_P		697
+#define CLK_PHY0_REF_ALT_M		698
+#define CLK_PHY1_REF_ALT_P		699
+#define CLK_PHY1_REF_ALT_M		700
+#define ACLK_ISP1_PRE			701
+#define HCLK_ISP1_PRE			702
+#define HCLK_NVM			703
+#define ACLK_USB			704
+#define HCLK_USB			705
+#define ACLK_JPEG_DECODER_PRE		706
+#define ACLK_VDPU_LOW_PRE		707
+#define ACLK_RKVENC1_PRE		708
+#define HCLK_RKVENC1_PRE		709
+#define HCLK_RKVDEC0_PRE		710
+#define ACLK_RKVDEC0_PRE		711
+#define HCLK_RKVDEC1_PRE		712
+#define ACLK_RKVDEC1_PRE		713
+#define ACLK_HDCP0_PRE			714
+#define HCLK_VO0			715
+#define ACLK_HDCP1_PRE			716
+#define HCLK_VO1			717
+#define ACLK_AV1_PRE			718
+#define PCLK_AV1_PRE			719
+#define HCLK_SDIO_PRE			720
+
+#define CLK_NR_CLKS			(HCLK_SDIO_PRE + 1)
+
+/* scmi-clocks indices */
+
+#define SCMI_CLK_CPUL			0
+#define SCMI_CLK_DSU			1
+#define SCMI_CLK_CPUB01			2
+#define SCMI_CLK_CPUB23			3
+#define SCMI_CLK_DDR			4
+#define SCMI_CLK_GPU			5
+#define SCMI_CLK_NPU			6
+#define SCMI_CLK_SBUS			7
+#define SCMI_PCLK_SBUS			8
+#define SCMI_CCLK_SD			9
+#define SCMI_DCLK_SD			10
+#define SCMI_ACLK_SECURE_NS		11
+#define SCMI_HCLK_SECURE_NS		12
+#define SCMI_TCLK_WDT			13
+#define SCMI_KEYLADDER_CORE		14
+#define SCMI_KEYLADDER_RNG		15
+#define SCMI_ACLK_SECURE_S		16
+#define SCMI_HCLK_SECURE_S		17
+#define SCMI_PCLK_SECURE_S		18
+#define SCMI_CRYPTO_RNG			19
+#define SCMI_CRYPTO_CORE		20
+#define SCMI_CRYPTO_PKA			21
+#define SCMI_SPLL			22
+#define SCMI_HCLK_SD			23
+
+#endif
diff --git a/include/dt-bindings/power/rk3588-power.h b/include/dt-bindings/power/rk3588-power.h
new file mode 100644
index 0000000..1b92fec
--- /dev/null
+++ b/include/dt-bindings/power/rk3588-power.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: (GPL-2.0 or MIT) */
+#ifndef __DT_BINDINGS_POWER_RK3588_POWER_H__
+#define __DT_BINDINGS_POWER_RK3588_POWER_H__
+
+/* VD_LITDSU */
+#define RK3588_PD_CPU_0		0
+#define RK3588_PD_CPU_1		1
+#define RK3588_PD_CPU_2		2
+#define RK3588_PD_CPU_3		3
+
+/* VD_BIGCORE0 */
+#define RK3588_PD_CPU_4		4
+#define RK3588_PD_CPU_5		5
+
+/* VD_BIGCORE1 */
+#define RK3588_PD_CPU_6		6
+#define RK3588_PD_CPU_7		7
+
+/* VD_NPU */
+#define RK3588_PD_NPU		8
+#define RK3588_PD_NPUTOP	9
+#define RK3588_PD_NPU1		10
+#define RK3588_PD_NPU2		11
+
+/* VD_GPU */
+#define RK3588_PD_GPU		12
+
+/* VD_VCODEC */
+#define RK3588_PD_VCODEC	13
+#define RK3588_PD_RKVDEC0	14
+#define RK3588_PD_RKVDEC1	15
+#define RK3588_PD_VENC0		16
+#define RK3588_PD_VENC1		17
+
+/* VD_DD01 */
+#define RK3588_PD_DDR01		18
+
+/* VD_DD23 */
+#define RK3588_PD_DDR23		19
+
+/* VD_LOGIC */
+#define RK3588_PD_CENTER	20
+#define RK3588_PD_VDPU		21
+#define RK3588_PD_RGA30		22
+#define RK3588_PD_AV1		23
+#define RK3588_PD_VOP		24
+#define RK3588_PD_VO0		25
+#define RK3588_PD_VO1		26
+#define RK3588_PD_VI		27
+#define RK3588_PD_ISP1		28
+#define RK3588_PD_FEC		29
+#define RK3588_PD_RGA31		30
+#define RK3588_PD_USB		31
+#define RK3588_PD_PHP		32
+#define RK3588_PD_GMAC		33
+#define RK3588_PD_PCIE		34
+#define RK3588_PD_NVM		35
+#define RK3588_PD_NVM0		36
+#define RK3588_PD_SDIO		37
+#define RK3588_PD_AUDIO		38
+#define RK3588_PD_SECURE	39
+#define RK3588_PD_SDMMC		40
+#define RK3588_PD_CRYPTO	41
+#define RK3588_PD_BUS		42
+
+/* VD_PMU */
+#define RK3588_PD_PMU1		43
+
+#endif
diff --git a/include/dt-bindings/reset/rockchip,rk3588-cru.h b/include/dt-bindings/reset/rockchip,rk3588-cru.h
new file mode 100644
index 0000000..738e56a
--- /dev/null
+++ b/include/dt-bindings/reset/rockchip,rk3588-cru.h
@@ -0,0 +1,754 @@
+/* SPDX-License-Identifier: (GPL-2.0 or MIT) */
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co. Ltd.
+ * Copyright (c) 2022 Collabora Ltd.
+ *
+ * Author: Elaine Zhang <zhangqing@rock-chips.com>
+ * Author: Sebastian Reichel <sebastian.reichel@collabora.com>
+ */
+
+#ifndef _DT_BINDINGS_RESET_ROCKCHIP_RK3588_H
+#define _DT_BINDINGS_RESET_ROCKCHIP_RK3588_H
+
+#define SRST_A_TOP_BIU			0
+#define SRST_P_TOP_BIU			1
+#define SRST_P_CSIPHY0			2
+#define SRST_CSIPHY0			3
+#define SRST_P_CSIPHY1			4
+#define SRST_CSIPHY1			5
+#define SRST_A_TOP_M500_BIU		6
+
+#define SRST_A_TOP_M400_BIU		7
+#define SRST_A_TOP_S200_BIU		8
+#define SRST_A_TOP_S400_BIU		9
+#define SRST_A_TOP_M300_BIU		10
+#define SRST_USBDP_COMBO_PHY0_INIT	11
+#define SRST_USBDP_COMBO_PHY0_CMN	12
+#define SRST_USBDP_COMBO_PHY0_LANE	13
+#define SRST_USBDP_COMBO_PHY0_PCS	14
+#define SRST_USBDP_COMBO_PHY1_INIT	15
+
+#define SRST_USBDP_COMBO_PHY1_CMN	16
+#define SRST_USBDP_COMBO_PHY1_LANE	17
+#define SRST_USBDP_COMBO_PHY1_PCS	18
+#define SRST_DCPHY0			19
+#define SRST_P_MIPI_DCPHY0		20
+#define SRST_P_MIPI_DCPHY0_GRF		21
+
+#define SRST_DCPHY1			22
+#define SRST_P_MIPI_DCPHY1		23
+#define SRST_P_MIPI_DCPHY1_GRF		24
+#define SRST_P_APB2ASB_SLV_CDPHY	25
+#define SRST_P_APB2ASB_SLV_CSIPHY	26
+#define SRST_P_APB2ASB_SLV_VCCIO3_5	27
+#define SRST_P_APB2ASB_SLV_VCCIO6	28
+#define SRST_P_APB2ASB_SLV_EMMCIO	29
+#define SRST_P_APB2ASB_SLV_IOC_TOP	30
+#define SRST_P_APB2ASB_SLV_IOC_RIGHT	31
+
+#define SRST_P_CRU			32
+#define SRST_A_CHANNEL_SECURE2VO1USB	33
+#define SRST_A_CHANNEL_SECURE2CENTER	34
+#define SRST_H_CHANNEL_SECURE2VO1USB	35
+#define SRST_H_CHANNEL_SECURE2CENTER	36
+
+#define SRST_P_CHANNEL_SECURE2VO1USB	37
+#define SRST_P_CHANNEL_SECURE2CENTER	38
+
+#define SRST_H_AUDIO_BIU		39
+#define SRST_P_AUDIO_BIU		40
+#define SRST_H_I2S0_8CH			41
+#define SRST_M_I2S0_8CH_TX		42
+#define SRST_M_I2S0_8CH_RX		43
+#define SRST_P_ACDCDIG			44
+#define SRST_H_I2S2_2CH			45
+#define SRST_H_I2S3_2CH			46
+
+#define SRST_M_I2S2_2CH			47
+#define SRST_M_I2S3_2CH			48
+#define SRST_DAC_ACDCDIG		49
+#define SRST_H_SPDIF0			50
+
+#define SRST_M_SPDIF0			51
+#define SRST_H_SPDIF1			52
+#define SRST_M_SPDIF1			53
+#define SRST_H_PDM1			54
+#define SRST_PDM1			55
+
+#define SRST_A_BUS_BIU			56
+#define SRST_P_BUS_BIU			57
+#define SRST_A_GIC			58
+#define SRST_A_GIC_DBG			59
+#define SRST_A_DMAC0			60
+#define SRST_A_DMAC1			61
+#define SRST_A_DMAC2			62
+#define SRST_P_I2C1			63
+#define SRST_P_I2C2			64
+#define SRST_P_I2C3			65
+#define SRST_P_I2C4			66
+#define SRST_P_I2C5			67
+#define SRST_P_I2C6			68
+#define SRST_P_I2C7			69
+#define SRST_P_I2C8			70
+
+#define SRST_I2C1			71
+#define SRST_I2C2			72
+#define SRST_I2C3			73
+#define SRST_I2C4			74
+#define SRST_I2C5			75
+#define SRST_I2C6			76
+#define SRST_I2C7			77
+#define SRST_I2C8			78
+#define SRST_P_CAN0			79
+#define SRST_CAN0			80
+#define SRST_P_CAN1			81
+#define SRST_CAN1			82
+#define SRST_P_CAN2			83
+#define SRST_CAN2			84
+#define SRST_P_SARADC			85
+
+#define SRST_P_TSADC			86
+#define SRST_TSADC			87
+#define SRST_P_UART1			88
+#define SRST_P_UART2			89
+#define SRST_P_UART3			90
+#define SRST_P_UART4			91
+#define SRST_P_UART5			92
+#define SRST_P_UART6			93
+#define SRST_P_UART7			94
+#define SRST_P_UART8			95
+#define SRST_P_UART9			96
+#define SRST_S_UART1			97
+
+#define SRST_S_UART2			98
+#define SRST_S_UART3			99
+#define SRST_S_UART4			100
+#define SRST_S_UART5			101
+#define SRST_S_UART6			102
+#define SRST_S_UART7			103
+
+#define SRST_S_UART8			104
+#define SRST_S_UART9			105
+#define SRST_P_SPI0			106
+#define SRST_P_SPI1			107
+#define SRST_P_SPI2			108
+#define SRST_P_SPI3			109
+#define SRST_P_SPI4			110
+#define SRST_SPI0			111
+#define SRST_SPI1			112
+#define SRST_SPI2			113
+#define SRST_SPI3			114
+#define SRST_SPI4			115
+
+#define SRST_P_WDT0			116
+#define SRST_T_WDT0			117
+#define SRST_P_SYS_GRF			118
+#define SRST_P_PWM1			119
+#define SRST_PWM1			120
+#define SRST_P_PWM2			121
+#define SRST_PWM2			122
+#define SRST_P_PWM3			123
+#define SRST_PWM3			124
+#define SRST_P_BUSTIMER0		125
+#define SRST_P_BUSTIMER1		126
+#define SRST_BUSTIMER0			127
+
+#define SRST_BUSTIMER1			128
+#define SRST_BUSTIMER2			129
+#define SRST_BUSTIMER3			130
+#define SRST_BUSTIMER4			131
+#define SRST_BUSTIMER5			132
+#define SRST_BUSTIMER6			133
+#define SRST_BUSTIMER7			134
+#define SRST_BUSTIMER8			135
+#define SRST_BUSTIMER9			136
+#define SRST_BUSTIMER10			137
+#define SRST_BUSTIMER11			138
+#define SRST_P_MAILBOX0			139
+#define SRST_P_MAILBOX1			140
+#define SRST_P_MAILBOX2			141
+#define SRST_P_GPIO1			142
+#define SRST_GPIO1			143
+
+#define SRST_P_GPIO2			144
+#define SRST_GPIO2			145
+#define SRST_P_GPIO3			146
+#define SRST_GPIO3			147
+#define SRST_P_GPIO4			148
+#define SRST_GPIO4			149
+#define SRST_A_DECOM			150
+#define SRST_P_DECOM			151
+#define SRST_D_DECOM			152
+#define SRST_P_TOP			153
+#define SRST_A_GICADB_GIC2CORE_BUS	154
+#define SRST_P_DFT2APB			155
+#define SRST_P_APB2ASB_MST_TOP		156
+#define SRST_P_APB2ASB_MST_CDPHY	157
+#define SRST_P_APB2ASB_MST_BOT_RIGHT	158
+
+#define SRST_P_APB2ASB_MST_IOC_TOP	159
+#define SRST_P_APB2ASB_MST_IOC_RIGHT	160
+#define SRST_P_APB2ASB_MST_CSIPHY	161
+#define SRST_P_APB2ASB_MST_VCCIO3_5	162
+#define SRST_P_APB2ASB_MST_VCCIO6	163
+#define SRST_P_APB2ASB_MST_EMMCIO	164
+#define SRST_A_SPINLOCK			165
+#define SRST_P_OTPC_NS			166
+#define SRST_OTPC_NS			167
+#define SRST_OTPC_ARB			168
+
+#define SRST_P_BUSIOC			169
+#define SRST_P_PMUCM0_INTMUX		170
+#define SRST_P_DDRCM0_INTMUX		171
+
+#define SRST_P_DDR_DFICTL_CH0		172
+#define SRST_P_DDR_MON_CH0		173
+#define SRST_P_DDR_STANDBY_CH0		174
+#define SRST_P_DDR_UPCTL_CH0		175
+#define SRST_TM_DDR_MON_CH0		176
+#define SRST_P_DDR_GRF_CH01		177
+#define SRST_DFI_CH0			178
+#define SRST_SBR_CH0			179
+#define SRST_DDR_UPCTL_CH0		180
+#define SRST_DDR_DFICTL_CH0		181
+#define SRST_DDR_MON_CH0		182
+#define SRST_DDR_STANDBY_CH0		183
+#define SRST_A_DDR_UPCTL_CH0		184
+#define SRST_P_DDR_DFICTL_CH1		185
+#define SRST_P_DDR_MON_CH1		186
+#define SRST_P_DDR_STANDBY_CH1		187
+
+#define SRST_P_DDR_UPCTL_CH1		188
+#define SRST_TM_DDR_MON_CH1		189
+#define SRST_DFI_CH1			190
+#define SRST_SBR_CH1			191
+#define SRST_DDR_UPCTL_CH1		192
+#define SRST_DDR_DFICTL_CH1		193
+#define SRST_DDR_MON_CH1		194
+#define SRST_DDR_STANDBY_CH1		195
+#define SRST_A_DDR_UPCTL_CH1		196
+#define SRST_A_DDR01_MSCH0		197
+#define SRST_A_DDR01_RS_MSCH0		198
+#define SRST_A_DDR01_FRS_MSCH0		199
+
+#define SRST_A_DDR01_SCRAMBLE0		200
+#define SRST_A_DDR01_FRS_SCRAMBLE0	201
+#define SRST_A_DDR01_MSCH1		202
+#define SRST_A_DDR01_RS_MSCH1		203
+#define SRST_A_DDR01_FRS_MSCH1		204
+#define SRST_A_DDR01_SCRAMBLE1		205
+#define SRST_A_DDR01_FRS_SCRAMBLE1	206
+#define SRST_P_DDR01_MSCH0		207
+#define SRST_P_DDR01_MSCH1		208
+
+#define SRST_P_DDR_DFICTL_CH2		209
+#define SRST_P_DDR_MON_CH2		210
+#define SRST_P_DDR_STANDBY_CH2		211
+#define SRST_P_DDR_UPCTL_CH2		212
+#define SRST_TM_DDR_MON_CH2		213
+#define SRST_P_DDR_GRF_CH23		214
+#define SRST_DFI_CH2			215
+#define SRST_SBR_CH2			216
+#define SRST_DDR_UPCTL_CH2		217
+#define SRST_DDR_DFICTL_CH2		218
+#define SRST_DDR_MON_CH2		219
+#define SRST_DDR_STANDBY_CH2		220
+#define SRST_A_DDR_UPCTL_CH2		221
+#define SRST_P_DDR_DFICTL_CH3		222
+#define SRST_P_DDR_MON_CH3		223
+#define SRST_P_DDR_STANDBY_CH3		224
+
+#define SRST_P_DDR_UPCTL_CH3		225
+#define SRST_TM_DDR_MON_CH3		226
+#define SRST_DFI_CH3			227
+#define SRST_SBR_CH3			228
+#define SRST_DDR_UPCTL_CH3		229
+#define SRST_DDR_DFICTL_CH3		230
+#define SRST_DDR_MON_CH3		231
+#define SRST_DDR_STANDBY_CH3		232
+#define SRST_A_DDR_UPCTL_CH3		233
+#define SRST_A_DDR23_MSCH2		234
+#define SRST_A_DDR23_RS_MSCH2		235
+#define SRST_A_DDR23_FRS_MSCH2		236
+
+#define SRST_A_DDR23_SCRAMBLE2		237
+#define SRST_A_DDR23_FRS_SCRAMBLE2	238
+#define SRST_A_DDR23_MSCH3		239
+#define SRST_A_DDR23_RS_MSCH3		240
+#define SRST_A_DDR23_FRS_MSCH3		241
+#define SRST_A_DDR23_SCRAMBLE3		242
+#define SRST_A_DDR23_FRS_SCRAMBLE3	243
+#define SRST_P_DDR23_MSCH2		244
+#define SRST_P_DDR23_MSCH3		245
+
+#define SRST_ISP1			246
+#define SRST_ISP1_VICAP			247
+#define SRST_A_ISP1_BIU			248
+#define SRST_H_ISP1_BIU			249
+
+#define SRST_A_RKNN1			250
+#define SRST_A_RKNN1_BIU		251
+#define SRST_H_RKNN1			252
+#define SRST_H_RKNN1_BIU		253
+
+#define SRST_A_RKNN2			254
+#define SRST_A_RKNN2_BIU		255
+#define SRST_H_RKNN2			256
+#define SRST_H_RKNN2_BIU		257
+
+#define SRST_A_RKNN_DSU0		258
+#define SRST_P_NPUTOP_BIU		259
+#define SRST_P_NPU_TIMER		260
+#define SRST_NPUTIMER0			261
+#define SRST_NPUTIMER1			262
+#define SRST_P_NPU_WDT			263
+#define SRST_T_NPU_WDT			264
+#define SRST_P_NPU_PVTM			265
+#define SRST_P_NPU_GRF			266
+#define SRST_NPU_PVTM			267
+
+#define SRST_NPU_PVTPLL			268
+#define SRST_H_NPU_CM0_BIU		269
+#define SRST_F_NPU_CM0_CORE		270
+#define SRST_T_NPU_CM0_JTAG		271
+#define SRST_A_RKNN0			272
+#define SRST_A_RKNN0_BIU		273
+#define SRST_H_RKNN0			274
+#define SRST_H_RKNN0_BIU		275
+
+#define SRST_H_NVM_BIU			276
+#define SRST_A_NVM_BIU			277
+#define SRST_H_EMMC			278
+#define SRST_A_EMMC			279
+#define SRST_C_EMMC			280
+#define SRST_B_EMMC			281
+#define SRST_T_EMMC			282
+#define SRST_S_SFC			283
+#define SRST_H_SFC			284
+#define SRST_H_SFC_XIP			285
+
+#define SRST_P_GRF			286
+#define SRST_P_DEC_BIU			287
+#define SRST_P_PHP_BIU			288
+#define SRST_A_PCIE_GRIDGE		289
+#define SRST_A_PHP_BIU			290
+#define SRST_A_GMAC0			291
+#define SRST_A_GMAC1			292
+#define SRST_A_PCIE_BIU			293
+#define SRST_PCIE0_POWER_UP		294
+#define SRST_PCIE1_POWER_UP		295
+#define SRST_PCIE2_POWER_UP		296
+
+#define SRST_PCIE3_POWER_UP		297
+#define SRST_PCIE4_POWER_UP		298
+#define SRST_P_PCIE0			299
+#define SRST_P_PCIE1			300
+#define SRST_P_PCIE2			301
+#define SRST_P_PCIE3			302
+
+#define SRST_P_PCIE4			303
+#define SRST_A_PHP_GIC_ITS		304
+#define SRST_A_MMU_PCIE			305
+#define SRST_A_MMU_PHP			306
+#define SRST_A_MMU_BIU			307
+
+#define SRST_A_USB3OTG2			308
+
+#define SRST_PMALIVE0			309
+#define SRST_PMALIVE1			310
+#define SRST_PMALIVE2			311
+#define SRST_A_SATA0			312
+#define SRST_A_SATA1			313
+#define SRST_A_SATA2			314
+#define SRST_RXOOB0			315
+#define SRST_RXOOB1			316
+#define SRST_RXOOB2			317
+#define SRST_ASIC0			318
+#define SRST_ASIC1			319
+#define SRST_ASIC2			320
+
+#define SRST_A_RKVDEC_CCU		321
+#define SRST_H_RKVDEC0			322
+#define SRST_A_RKVDEC0			323
+#define SRST_H_RKVDEC0_BIU		324
+#define SRST_A_RKVDEC0_BIU		325
+#define SRST_RKVDEC0_CA			326
+#define SRST_RKVDEC0_HEVC_CA		327
+#define SRST_RKVDEC0_CORE		328
+
+#define SRST_H_RKVDEC1			329
+#define SRST_A_RKVDEC1			330
+#define SRST_H_RKVDEC1_BIU		331
+#define SRST_A_RKVDEC1_BIU		332
+#define SRST_RKVDEC1_CA			333
+#define SRST_RKVDEC1_HEVC_CA		334
+#define SRST_RKVDEC1_CORE		335
+
+#define SRST_A_USB_BIU			336
+#define SRST_H_USB_BIU			337
+#define SRST_A_USB3OTG0			338
+#define SRST_A_USB3OTG1			339
+#define SRST_H_HOST0			340
+#define SRST_H_HOST_ARB0		341
+#define SRST_H_HOST1			342
+#define SRST_H_HOST_ARB1		343
+#define SRST_A_USB_GRF			344
+#define SRST_C_USB2P0_HOST0		345
+
+#define SRST_C_USB2P0_HOST1		346
+#define SRST_HOST_UTMI0			347
+#define SRST_HOST_UTMI1			348
+
+#define SRST_A_VDPU_BIU			349
+#define SRST_A_VDPU_LOW_BIU		350
+#define SRST_H_VDPU_BIU			351
+#define SRST_A_JPEG_DECODER_BIU		352
+#define SRST_A_VPU			353
+#define SRST_H_VPU			354
+#define SRST_A_JPEG_ENCODER0		355
+#define SRST_H_JPEG_ENCODER0		356
+#define SRST_A_JPEG_ENCODER1		357
+#define SRST_H_JPEG_ENCODER1		358
+#define SRST_A_JPEG_ENCODER2		359
+#define SRST_H_JPEG_ENCODER2		360
+
+#define SRST_A_JPEG_ENCODER3		361
+#define SRST_H_JPEG_ENCODER3		362
+#define SRST_A_JPEG_DECODER		363
+#define SRST_H_JPEG_DECODER		364
+#define SRST_H_IEP2P0			365
+#define SRST_A_IEP2P0			366
+#define SRST_IEP2P0_CORE		367
+#define SRST_H_RGA2			368
+#define SRST_A_RGA2			369
+#define SRST_RGA2_CORE			370
+#define SRST_H_RGA3_0			371
+#define SRST_A_RGA3_0			372
+#define SRST_RGA3_0_CORE		373
+
+#define SRST_H_RKVENC0_BIU		374
+#define SRST_A_RKVENC0_BIU		375
+#define SRST_H_RKVENC0			376
+#define SRST_A_RKVENC0			377
+#define SRST_RKVENC0_CORE		378
+
+#define SRST_H_RKVENC1_BIU		379
+#define SRST_A_RKVENC1_BIU		380
+#define SRST_H_RKVENC1			381
+#define SRST_A_RKVENC1			382
+#define SRST_RKVENC1_CORE		383
+
+#define SRST_A_VI_BIU			384
+#define SRST_H_VI_BIU			385
+#define SRST_P_VI_BIU			386
+#define SRST_D_VICAP			387
+#define SRST_A_VICAP			388
+#define SRST_H_VICAP			389
+#define SRST_ISP0			390
+#define SRST_ISP0_VICAP			391
+
+#define SRST_FISHEYE0			392
+#define SRST_FISHEYE1			393
+#define SRST_P_CSI_HOST_0		394
+#define SRST_P_CSI_HOST_1		395
+#define SRST_P_CSI_HOST_2		396
+#define SRST_P_CSI_HOST_3		397
+#define SRST_P_CSI_HOST_4		398
+#define SRST_P_CSI_HOST_5		399
+
+#define SRST_CSIHOST0_VICAP		400
+#define SRST_CSIHOST1_VICAP		401
+#define SRST_CSIHOST2_VICAP		402
+#define SRST_CSIHOST3_VICAP		403
+#define SRST_CSIHOST4_VICAP		404
+#define SRST_CSIHOST5_VICAP		405
+#define SRST_CIFIN			406
+
+#define SRST_A_VOP_BIU			407
+#define SRST_A_VOP_LOW_BIU		408
+#define SRST_H_VOP_BIU			409
+#define SRST_P_VOP_BIU			410
+#define SRST_H_VOP			411
+#define SRST_A_VOP			412
+#define SRST_D_VOP0			413
+#define SRST_D_VOP2HDMI_BRIDGE0		414
+#define SRST_D_VOP2HDMI_BRIDGE1		415
+
+#define SRST_D_VOP1			416
+#define SRST_D_VOP2			417
+#define SRST_D_VOP3			418
+#define SRST_P_VOPGRF			419
+#define SRST_P_DSIHOST0			420
+#define SRST_P_DSIHOST1			421
+#define SRST_DSIHOST0			422
+#define SRST_DSIHOST1			423
+#define SRST_VOP_PMU			424
+#define SRST_P_VOP_CHANNEL_BIU		425
+
+#define SRST_H_VO0_BIU			426
+#define SRST_H_VO0_S_BIU		427
+#define SRST_P_VO0_BIU			428
+#define SRST_P_VO0_S_BIU		429
+#define SRST_A_HDCP0_BIU		430
+#define SRST_P_VO0GRF			431
+#define SRST_H_HDCP_KEY0		432
+#define SRST_A_HDCP0			433
+#define SRST_H_HDCP0			434
+#define SRST_HDCP0			435
+
+#define SRST_P_TRNG0			436
+#define SRST_DP0			437
+#define SRST_DP1			438
+#define SRST_H_I2S4_8CH			439
+#define SRST_M_I2S4_8CH_TX		440
+#define SRST_H_I2S8_8CH			441
+
+#define SRST_M_I2S8_8CH_TX		442
+#define SRST_H_SPDIF2_DP0		443
+#define SRST_M_SPDIF2_DP0		444
+#define SRST_H_SPDIF5_DP1		445
+#define SRST_M_SPDIF5_DP1		446
+
+#define SRST_A_HDCP1_BIU		447
+#define SRST_A_VO1_BIU			448
+#define SRST_H_VOP1_BIU			449
+#define SRST_H_VOP1_S_BIU		450
+#define SRST_P_VOP1_BIU			451
+#define SRST_P_VO1GRF			452
+#define SRST_P_VO1_S_BIU		453
+
+#define SRST_H_I2S7_8CH			454
+#define SRST_M_I2S7_8CH_RX		455
+#define SRST_H_HDCP_KEY1		456
+#define SRST_A_HDCP1			457
+#define SRST_H_HDCP1			458
+#define SRST_HDCP1			459
+#define SRST_P_TRNG1			460
+#define SRST_P_HDMITX0			461
+
+#define SRST_HDMITX0_REF		462
+#define SRST_P_HDMITX1			463
+#define SRST_HDMITX1_REF		464
+#define SRST_A_HDMIRX			465
+#define SRST_P_HDMIRX			466
+#define SRST_HDMIRX_REF			467
+
+#define SRST_P_EDP0			468
+#define SRST_EDP0_24M			469
+#define SRST_P_EDP1			470
+#define SRST_EDP1_24M			471
+#define SRST_M_I2S5_8CH_TX		472
+#define SRST_H_I2S5_8CH			473
+#define SRST_M_I2S6_8CH_TX		474
+
+#define SRST_M_I2S6_8CH_RX		475
+#define SRST_H_I2S6_8CH			476
+#define SRST_H_SPDIF3			477
+#define SRST_M_SPDIF3			478
+#define SRST_H_SPDIF4			479
+#define SRST_M_SPDIF4			480
+#define SRST_H_SPDIFRX0			481
+#define SRST_M_SPDIFRX0			482
+#define SRST_H_SPDIFRX1			483
+#define SRST_M_SPDIFRX1			484
+
+#define SRST_H_SPDIFRX2			485
+#define SRST_M_SPDIFRX2			486
+#define SRST_LINKSYM_HDMITXPHY0		487
+#define SRST_LINKSYM_HDMITXPHY1		488
+#define SRST_VO1_BRIDGE0		489
+#define SRST_VO1_BRIDGE1		490
+
+#define SRST_H_I2S9_8CH			491
+#define SRST_M_I2S9_8CH_RX		492
+#define SRST_H_I2S10_8CH		493
+#define SRST_M_I2S10_8CH_RX		494
+#define SRST_P_S_HDMIRX			495
+
+#define SRST_GPU			496
+#define SRST_SYS_GPU			497
+#define SRST_A_S_GPU_BIU		498
+#define SRST_A_M0_GPU_BIU		499
+#define SRST_A_M1_GPU_BIU		500
+#define SRST_A_M2_GPU_BIU		501
+#define SRST_A_M3_GPU_BIU		502
+#define SRST_P_GPU_BIU			503
+#define SRST_P_GPU_PVTM			504
+
+#define SRST_GPU_PVTM			505
+#define SRST_P_GPU_GRF			506
+#define SRST_GPU_PVTPLL			507
+#define SRST_GPU_JTAG			508
+
+#define SRST_A_AV1_BIU			509
+#define SRST_A_AV1			510
+#define SRST_P_AV1_BIU			511
+#define SRST_P_AV1			512
+
+#define SRST_A_DDR_BIU			513
+#define SRST_A_DMA2DDR			514
+#define SRST_A_DDR_SHAREMEM		515
+#define SRST_A_DDR_SHAREMEM_BIU		516
+#define SRST_A_CENTER_S200_BIU		517
+#define SRST_A_CENTER_S400_BIU		518
+#define SRST_H_AHB2APB			519
+#define SRST_H_CENTER_BIU		520
+#define SRST_F_DDR_CM0_CORE		521
+
+#define SRST_DDR_TIMER0			522
+#define SRST_DDR_TIMER1			523
+#define SRST_T_WDT_DDR			524
+#define SRST_T_DDR_CM0_JTAG		525
+#define SRST_P_CENTER_GRF		526
+#define SRST_P_AHB2APB			527
+#define SRST_P_WDT			528
+#define SRST_P_TIMER			529
+#define SRST_P_DMA2DDR			530
+#define SRST_P_SHAREMEM			531
+#define SRST_P_CENTER_BIU		532
+#define SRST_P_CENTER_CHANNEL_BIU	533
+
+#define SRST_P_USBDPGRF0		534
+#define SRST_P_USBDPPHY0		535
+#define SRST_P_USBDPGRF1		536
+#define SRST_P_USBDPPHY1		537
+#define SRST_P_HDPTX0			538
+#define SRST_P_HDPTX1			539
+#define SRST_P_APB2ASB_SLV_BOT_RIGHT	540
+#define SRST_P_USB2PHY_U3_0_GRF0	541
+#define SRST_P_USB2PHY_U3_1_GRF0	542
+#define SRST_P_USB2PHY_U2_0_GRF0	543
+#define SRST_P_USB2PHY_U2_1_GRF0	544
+#define SRST_HDPTX0_ROPLL		545
+#define SRST_HDPTX0_LCPLL		546
+#define SRST_HDPTX0			547
+#define SRST_HDPTX1_ROPLL		548
+
+#define SRST_HDPTX1_LCPLL		549
+#define SRST_HDPTX1			550
+#define SRST_HDPTX0_HDMIRXPHY_SET	551
+#define SRST_USBDP_COMBO_PHY0		552
+#define SRST_USBDP_COMBO_PHY0_LCPLL	553
+#define SRST_USBDP_COMBO_PHY0_ROPLL	554
+#define SRST_USBDP_COMBO_PHY0_PCS_HS	555
+#define SRST_USBDP_COMBO_PHY1		556
+#define SRST_USBDP_COMBO_PHY1_LCPLL	557
+#define SRST_USBDP_COMBO_PHY1_ROPLL	558
+#define SRST_USBDP_COMBO_PHY1_PCS_HS	559
+#define SRST_HDMIHDP0			560
+#define SRST_HDMIHDP1			561
+
+#define SRST_A_VO1USB_TOP_BIU		562
+#define SRST_H_VO1USB_TOP_BIU		563
+
+#define SRST_H_SDIO_BIU			564
+#define SRST_H_SDIO			565
+#define SRST_SDIO			566
+
+#define SRST_H_RGA3_BIU			567
+#define SRST_A_RGA3_BIU			568
+#define SRST_H_RGA3_1			569
+#define SRST_A_RGA3_1			570
+#define SRST_RGA3_1_CORE		571
+
+#define SRST_REF_PIPE_PHY0		572
+#define SRST_REF_PIPE_PHY1		573
+#define SRST_REF_PIPE_PHY2		574
+
+#define SRST_P_PHPTOP_CRU		575
+#define SRST_P_PCIE2_GRF0		576
+#define SRST_P_PCIE2_GRF1		577
+#define SRST_P_PCIE2_GRF2		578
+#define SRST_P_PCIE2_PHY0		579
+#define SRST_P_PCIE2_PHY1		580
+#define SRST_P_PCIE2_PHY2		581
+#define SRST_P_PCIE3_PHY		582
+#define SRST_P_APB2ASB_SLV_CHIP_TOP	583
+#define SRST_PCIE30_PHY			584
+
+#define SRST_H_PMU1_BIU			585
+#define SRST_P_PMU1_BIU			586
+#define SRST_H_PMU_CM0_BIU		587
+#define SRST_F_PMU_CM0_CORE		588
+#define SRST_T_PMU1_CM0_JTAG		589
+
+#define SRST_DDR_FAIL_SAFE		590
+#define SRST_P_CRU_PMU1			591
+#define SRST_P_PMU1_GRF			592
+#define SRST_P_PMU1_IOC			593
+#define SRST_P_PMU1WDT			594
+#define SRST_T_PMU1WDT			595
+#define SRST_P_PMU1TIMER		596
+#define SRST_PMU1TIMER0			597
+#define SRST_PMU1TIMER1			598
+#define SRST_P_PMU1PWM			599
+#define SRST_PMU1PWM			600
+
+#define SRST_P_I2C0			601
+#define SRST_I2C0			602
+#define SRST_S_UART0			603
+#define SRST_P_UART0			604
+#define SRST_H_I2S1_8CH			605
+#define SRST_M_I2S1_8CH_TX		606
+#define SRST_M_I2S1_8CH_RX		607
+#define SRST_H_PDM0			608
+#define SRST_PDM0			609
+
+#define SRST_H_VAD			610
+#define SRST_HDPTX0_INIT		611
+#define SRST_HDPTX0_CMN			612
+#define SRST_HDPTX0_LANE		613
+#define SRST_HDPTX1_INIT		614
+
+#define SRST_HDPTX1_CMN			615
+#define SRST_HDPTX1_LANE		616
+#define SRST_M_MIPI_DCPHY0		617
+#define SRST_S_MIPI_DCPHY0		618
+#define SRST_M_MIPI_DCPHY1		619
+#define SRST_S_MIPI_DCPHY1		620
+#define SRST_OTGPHY_U3_0		621
+#define SRST_OTGPHY_U3_1		622
+#define SRST_OTGPHY_U2_0		623
+#define SRST_OTGPHY_U2_1		624
+
+#define SRST_P_PMU0GRF			625
+#define SRST_P_PMU0IOC			626
+#define SRST_P_GPIO0			627
+#define SRST_GPIO0			628
+
+#define SRST_A_SECURE_NS_BIU		629
+#define SRST_H_SECURE_NS_BIU		630
+#define SRST_A_SECURE_S_BIU		631
+#define SRST_H_SECURE_S_BIU		632
+#define SRST_P_SECURE_S_BIU		633
+#define SRST_CRYPTO_CORE		634
+
+#define SRST_CRYPTO_PKA			635
+#define SRST_CRYPTO_RNG			636
+#define SRST_A_CRYPTO			637
+#define SRST_H_CRYPTO			638
+#define SRST_KEYLADDER_CORE		639
+#define SRST_KEYLADDER_RNG		640
+#define SRST_A_KEYLADDER		641
+#define SRST_H_KEYLADDER		642
+#define SRST_P_OTPC_S			643
+#define SRST_OTPC_S			644
+#define SRST_WDT_S			645
+
+#define SRST_T_WDT_S			646
+#define SRST_H_BOOTROM			647
+#define SRST_A_DCF			648
+#define SRST_P_DCF			649
+#define SRST_H_BOOTROM_NS		650
+#define SRST_P_KEYLADDER		651
+#define SRST_H_TRNG_S			652
+
+#define SRST_H_TRNG_NS			653
+#define SRST_D_SDMMC_BUFFER		654
+#define SRST_H_SDMMC			655
+#define SRST_H_SDMMC_BUFFER		656
+#define SRST_SDMMC			657
+#define SRST_P_TRNG_CHK			658
+#define SRST_TRNG_S			659
+
+#endif
diff --git a/include/dt-bindings/soc/rockchip,vop2.h b/include/dt-bindings/soc/rockchip,vop2.h
new file mode 100644
index 0000000..6e66a80
--- /dev/null
+++ b/include/dt-bindings/soc/rockchip,vop2.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
+
+#ifndef __DT_BINDINGS_ROCKCHIP_VOP2_H
+#define __DT_BINDINGS_ROCKCHIP_VOP2_H
+
+#define ROCKCHIP_VOP2_EP_RGB0	1
+#define ROCKCHIP_VOP2_EP_HDMI0	2
+#define ROCKCHIP_VOP2_EP_EDP0	3
+#define ROCKCHIP_VOP2_EP_MIPI0	4
+#define ROCKCHIP_VOP2_EP_LVDS0	5
+#define ROCKCHIP_VOP2_EP_MIPI1	6
+#define ROCKCHIP_VOP2_EP_LVDS1	7
+
+#endif /* __DT_BINDINGS_ROCKCHIP_VOP2_H */
diff --git a/include/init.h b/include/init.h
index 699dc24..8873081 100644
--- a/include/init.h
+++ b/include/init.h
@@ -353,6 +353,9 @@
 void bdinfo_print_num_l(const char *name, ulong value);
 void bdinfo_print_num_ll(const char *name, unsigned long long value);
 
+/* Print a string value (for use in arch_print_bdinfo()) */
+void bdinfo_print_str(const char *name, const char *str);
+
 /* Print a clock speed in MHz */
 void bdinfo_print_mhz(const char *name, unsigned long hz);
 
diff --git a/include/test/ut.h b/include/test/ut.h
index 2b0dab3..dddf9ad 100644
--- a/include/test/ut.h
+++ b/include/test/ut.h
@@ -125,36 +125,47 @@
 		 fmt, ##args)
 
 /* Assert that a condition is non-zero */
-#define ut_assert(cond)							\
+#define ut_assert(cond) ({						\
+	int __ret = 0;							\
+									\
 	if (!(cond)) {							\
 		ut_fail(uts, __FILE__, __LINE__, __func__, #cond);	\
-		return CMD_RET_FAILURE;					\
-	}
+		__ret = CMD_RET_FAILURE;				\
+	}								\
+	__ret;								\
+})
 
 /* Assert that a condition is non-zero, with printf() string */
-#define ut_assertf(cond, fmt, args...)					\
+#define ut_assertf(cond, fmt, args...) ({				\
+	int __ret = 0;							\
+									\
 	if (!(cond)) {							\
 		ut_failf(uts, __FILE__, __LINE__, __func__, #cond,	\
 			 fmt, ##args);					\
-		return CMD_RET_FAILURE;					\
-	}
+		__ret = CMD_RET_FAILURE;				\
+	}								\
+	__ret;								\
+})
 
 /* Assert that two int expressions are equal */
-#define ut_asserteq(expr1, expr2) {					\
+#define ut_asserteq(expr1, expr2) ({					\
 	unsigned int _val1 = (expr1), _val2 = (expr2);			\
+	int __ret = 0;							\
 									\
 	if (_val1 != _val2) {						\
 		ut_failf(uts, __FILE__, __LINE__, __func__,		\
 			 #expr1 " == " #expr2,				\
 			 "Expected %#x (%d), got %#x (%d)",		\
 			 _val1, _val1, _val2, _val2);			\
-		return CMD_RET_FAILURE;					\
+		__ret = CMD_RET_FAILURE;				\
 	}								\
-}
+	__ret;								\
+})
 
 /* Assert that two 64 int expressions are equal */
-#define ut_asserteq_64(expr1, expr2) {					\
+#define ut_asserteq_64(expr1, expr2) ({					\
 	u64 _val1 = (expr1), _val2 = (expr2);				\
+	int __ret = 0;							\
 									\
 	if (_val1 != _val2) {						\
 		ut_failf(uts, __FILE__, __LINE__, __func__,		\
@@ -164,43 +175,49 @@
 			 (unsigned long long)_val1,			\
 			 (unsigned long long)_val2,			\
 			 (unsigned long long)_val2);			\
-		return CMD_RET_FAILURE;					\
+		__ret = CMD_RET_FAILURE;				\
 	}								\
-}
+	__ret;								\
+})
 
 /* Assert that two string expressions are equal */
-#define ut_asserteq_str(expr1, expr2) {					\
+#define ut_asserteq_str(expr1, expr2) ({				\
 	const char *_val1 = (expr1), *_val2 = (expr2);			\
+	int __ret = 0;							\
 									\
 	if (strcmp(_val1, _val2)) {					\
 		ut_failf(uts, __FILE__, __LINE__, __func__,		\
 			 #expr1 " = " #expr2,				\
 			 "Expected \"%s\", got \"%s\"", _val1, _val2);	\
-		return CMD_RET_FAILURE;					\
+		__ret = CMD_RET_FAILURE;				\
 	}								\
-}
+	__ret;								\
+})
 
 /*
  * Assert that two string expressions are equal, up to length of the
  * first
  */
-#define ut_asserteq_strn(expr1, expr2) {				\
+#define ut_asserteq_strn(expr1, expr2) ({				\
 	const char *_val1 = (expr1), *_val2 = (expr2);			\
 	int _len = strlen(_val1);					\
+	int __ret = 0;							\
 									\
 	if (memcmp(_val1, _val2, _len)) {				\
 		ut_failf(uts, __FILE__, __LINE__, __func__,		\
 			 #expr1 " = " #expr2,				\
 			 "Expected \"%.*s\", got \"%.*s\"",		\
 			 _len, _val1, _len, _val2);			\
-		return CMD_RET_FAILURE;					\
+		__ret = CMD_RET_FAILURE;				\
 	}								\
-}
+	__ret;								\
+})
 
 /* Assert that two memory areas are equal */
-#define ut_asserteq_mem(expr1, expr2, len) {				\
+#define ut_asserteq_mem(expr1, expr2, len) ({				\
 	const u8 *_val1 = (u8 *)(expr1), *_val2 = (u8 *)(expr2);	\
 	const uint __len = len;						\
+	int __ret = 0;							\
 									\
 	if (memcmp(_val1, _val2, __len)) {				\
 		char __buf1[64 + 1] = "\0";				\
@@ -211,128 +228,163 @@
 			 #expr1 " = " #expr2,				\
 			 "Expected \"%s\", got \"%s\"",			\
 			 __buf1, __buf2);				\
-		return CMD_RET_FAILURE;					\
+		__ret = CMD_RET_FAILURE;				\
 	}								\
-}
+	__ret;								\
+})
 
 /* Assert that two pointers are equal */
-#define ut_asserteq_ptr(expr1, expr2) {					\
+#define ut_asserteq_ptr(expr1, expr2) ({				\
 	const void *_val1 = (expr1), *_val2 = (expr2);			\
+	int __ret = 0;							\
 									\
 	if (_val1 != _val2) {						\
 		ut_failf(uts, __FILE__, __LINE__, __func__,		\
 			 #expr1 " = " #expr2,				\
 			 "Expected %p, got %p", _val1, _val2);		\
-		return CMD_RET_FAILURE;					\
+		__ret = CMD_RET_FAILURE;				\
 	}								\
-}
+	__ret;								\
+})
 
 /* Assert that two addresses (converted from pointers) are equal */
-#define ut_asserteq_addr(expr1, expr2) {				\
+#define ut_asserteq_addr(expr1, expr2) ({				\
 	ulong _val1 = map_to_sysmem(expr1);				\
 	ulong _val2 = map_to_sysmem(expr2);				\
+	int __ret = 0;							\
 									\
 	if (_val1 != _val2) {						\
 		ut_failf(uts, __FILE__, __LINE__, __func__,		\
 			 #expr1 " = " #expr2,				\
 			 "Expected %lx, got %lx", _val1, _val2);	\
-		return CMD_RET_FAILURE;					\
+		__ret = CMD_RET_FAILURE;				\
 	}								\
-}
+	__ret;								\
+})
 
 /* Assert that a pointer is NULL */
-#define ut_assertnull(expr) {					\
+#define ut_assertnull(expr) ({						\
 	const void *_val = (expr);					\
+	int __ret = 0;							\
 									\
-	if (_val) {						\
+	if (_val) {							\
 		ut_failf(uts, __FILE__, __LINE__, __func__,		\
 			 #expr " != NULL",				\
 			 "Expected NULL, got %p", _val);		\
-		return CMD_RET_FAILURE;					\
+		__ret = CMD_RET_FAILURE;				\
 	}								\
-}
+	__ret;								\
+})
 
 /* Assert that a pointer is not NULL */
-#define ut_assertnonnull(expr) {					\
+#define ut_assertnonnull(expr) ({					\
 	const void *_val = (expr);					\
+	int __ret = 0;							\
 									\
-	if (!_val) {						\
+	if (!_val) {							\
 		ut_failf(uts, __FILE__, __LINE__, __func__,		\
 			 #expr " = NULL",				\
 			 "Expected non-null, got NULL");		\
-		return CMD_RET_FAILURE;					\
+		__ret = CMD_RET_FAILURE;				\
 	}								\
-}
+	__ret;								\
+})
 
 /* Assert that a pointer is not an error pointer */
-#define ut_assertok_ptr(expr) {						\
+#define ut_assertok_ptr(expr) ({					\
 	const void *_val = (expr);					\
+	int __ret = 0;							\
 									\
 	if (IS_ERR(_val)) {						\
 		ut_failf(uts, __FILE__, __LINE__, __func__,		\
 			 #expr " = NULL",				\
 			 "Expected pointer, got error %ld",		\
 			 PTR_ERR(_val));				\
-		return CMD_RET_FAILURE;					\
+		__ret = CMD_RET_FAILURE;				\
 	}								\
-}
+	__ret;								\
+})
 
 /* Assert that an operation succeeds (returns 0) */
 #define ut_assertok(cond)	ut_asserteq(0, cond)
 
 /* Assert that the next console output line matches */
-#define ut_assert_nextline(fmt, args...)				\
+#define ut_assert_nextline(fmt, args...) ({				\
+	int __ret = 0;							\
+									\
 	if (ut_check_console_line(uts, fmt, ##args)) {			\
 		ut_failf(uts, __FILE__, __LINE__, __func__,		\
 			 "console", "\nExpected '%s',\n     got '%s'",	\
 			 uts->expect_str, uts->actual_str);		\
-		return CMD_RET_FAILURE;					\
+		__ret = CMD_RET_FAILURE;				\
 	}								\
+	__ret;								\
+})
 
 /* Assert that the next console output line matches up to the length */
-#define ut_assert_nextlinen(fmt, args...)				\
+#define ut_assert_nextlinen(fmt, args...) ({				\
+	int __ret = 0;							\
+									\
 	if (ut_check_console_linen(uts, fmt, ##args)) {			\
 		ut_failf(uts, __FILE__, __LINE__, __func__,		\
 			 "console", "\nExpected '%s',\n     got '%s'",	\
 			 uts->expect_str, uts->actual_str);		\
-		return CMD_RET_FAILURE;					\
+		__ret = CMD_RET_FAILURE;				\
 	}								\
+	__ret;								\
+})
 
 /* Assert that there is a 'next' console output line, and skip it */
-#define ut_assert_skipline()						\
+#define ut_assert_skipline() ({						\
+	int __ret = 0;							\
+									\
 	if (ut_check_skipline(uts)) {					\
 		ut_failf(uts, __FILE__, __LINE__, __func__,		\
 			 "console", "\nExpected a line, got end");	\
-		return CMD_RET_FAILURE;					\
+		__ret = CMD_RET_FAILURE;				\
 	}								\
+	__ret;								\
+})
 
 /* Assert that a following console output line matches */
-#define ut_assert_skip_to_line(fmt, args...)				\
+#define ut_assert_skip_to_line(fmt, args...) ({				\
+	int __ret = 0;							\
+									\
 	if (ut_check_skip_to_line(uts, fmt, ##args)) {			\
 		ut_failf(uts, __FILE__, __LINE__, __func__,		\
 			 "console", "\nExpected '%s',\n     got to '%s'", \
 			 uts->expect_str, uts->actual_str);		\
-		return CMD_RET_FAILURE;					\
+		__ret = CMD_RET_FAILURE;				\
 	}								\
+	__ret;								\
+})
 
 /* Assert that there is no more console output */
-#define ut_assert_console_end()						\
+#define ut_assert_console_end() ({					\
+	int __ret = 0;							\
+									\
 	if (ut_check_console_end(uts)) {				\
 		ut_failf(uts, __FILE__, __LINE__, __func__,		\
 			 "console", "Expected no more output, got '%s'",\
 			 uts->actual_str);				\
-		return CMD_RET_FAILURE;					\
+		__ret = CMD_RET_FAILURE;				\
 	}								\
+	__ret;								\
+})
 
 /* Assert that the next lines are print_buffer() dump at an address */
-#define ut_assert_nextlines_are_dump(total_bytes)			\
+#define ut_assert_nextlines_are_dump(total_bytes) ({			\
+	int __ret = 0;							\
+									\
 	if (ut_check_console_dump(uts, total_bytes)) {			\
 		ut_failf(uts, __FILE__, __LINE__, __func__,		\
 			 "console",					\
 			"Expected dump of length %x bytes, got '%s'",	\
 			 total_bytes, uts->actual_str);			\
-		return CMD_RET_FAILURE;					\
+		__ret = CMD_RET_FAILURE;				\
 	}								\
+	__ret;								\
+})
 
 /* Assert that the next console output line is empty */
 #define ut_assert_nextline_empty()					\
diff --git a/include/vesa.h b/include/vesa.h
index a42c179..9285bfa 100644
--- a/include/vesa.h
+++ b/include/vesa.h
@@ -108,7 +108,21 @@
 
 struct video_priv;
 struct video_uc_plat;
-int vesa_setup_video_priv(struct vesa_mode_info *vesa,
+
+/**
+ * vesa_setup_video_priv() - Set up a video device using VESA information
+ *
+ * The vesa struct is used by various x86 drivers, so this is a common function
+ * to use it to set up the video.
+ *
+ * @vesa: Vesa information to use (vesa->phys_base_ptr is ignored)
+ * @fb: Frame buffer address (since vesa->phys_base_ptr is only 32 bits)
+ * @uc_priv: Video device's uclass-private information
+ * @plat: Video devices's uclass-private platform data
+ * Returns: 0 if OK, -ENXIO if the x resolution is 0, -EEPROTONOSUPPORT if the
+ * pixel format is not supported
+ */
+int vesa_setup_video_priv(struct vesa_mode_info *vesa, u64 fb,
 			  struct video_priv *uc_priv,
 			  struct video_uc_plat *plat);
 int vesa_setup_video(struct udevice *dev, int (*int15_handler)(void));
diff --git a/include/video.h b/include/video.h
index 3f67a93..4d99e5d 100644
--- a/include/video.h
+++ b/include/video.h
@@ -24,6 +24,7 @@
  * @base: Base address of frame buffer, 0 if not yet known
  * @copy_base: Base address of a hardware copy of the frame buffer. See
  *	CONFIG_VIDEO_COPY.
+ * @copy_size: Size of copy framebuffer, used if @size is 0
  * @hide_logo: Hide the logo (used for testing)
  */
 struct video_uc_plat {
@@ -31,6 +32,7 @@
 	uint size;
 	ulong base;
 	ulong copy_base;
+	ulong copy_size;
 	bool hide_logo;
 };
 
diff --git a/include/video_console.h b/include/video_console.h
index 7701032..3db9a7e 100644
--- a/include/video_console.h
+++ b/include/video_console.h
@@ -286,6 +286,15 @@
 				unsigned row);
 
 /**
+ * vidconsole_clear_and_reset() - Clear the console and reset the cursor
+ *
+ * The cursor is placed at the start of the console
+ *
+ * @dev:	vidconsole device to adjust
+ */
+int vidconsole_clear_and_reset(struct udevice *dev);
+
+/**
  * vidconsole_set_cursor_pos() - set cursor position
  *
  * The cursor is set to the new position and the start-of-line information is
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index 4317630..a2d137d 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -77,6 +77,14 @@
 	.cursor_visible = 1,
 };
 
+/**
+ * term_get_char() - read a character from the console
+ *
+ * Wait for up to 100 ms to read a character from the console.
+ *
+ * @c:		pointer to the buffer to receive the character
+ * Return:	0 on success, 1 otherwise
+ */
 static int term_get_char(s32 *c)
 {
 	u64 timeout;
diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
index 5804f69..be95ed4 100644
--- a/lib/efi_loader/efi_variable.c
+++ b/lib/efi_loader/efi_variable.c
@@ -230,8 +230,30 @@
 	u64 time = 0;
 	enum efi_auth_var_type var_type;
 
-	if (!variable_name || !*variable_name || !vendor ||
-	    ((attributes & EFI_VARIABLE_RUNTIME_ACCESS) &&
+	if (!variable_name || !*variable_name || !vendor)
+		return EFI_INVALID_PARAMETER;
+
+	if (data_size && !data)
+		return EFI_INVALID_PARAMETER;
+
+	/* EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is deprecated */
+	if (attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)
+		return EFI_UNSUPPORTED;
+
+	/* Make sure if runtime bit is set, boot service bit is set also */
+	if ((attributes &
+	     (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) ==
+	    EFI_VARIABLE_RUNTIME_ACCESS)
+		return EFI_INVALID_PARAMETER;
+
+	/* only EFI_VARIABLE_NON_VOLATILE attribute is invalid */
+	if ((attributes & EFI_VARIABLE_MASK) == EFI_VARIABLE_NON_VOLATILE)
+		return EFI_INVALID_PARAMETER;
+
+	/* Make sure HR is set with NV, BS and RT */
+	if (attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD &&
+	    (!(attributes & EFI_VARIABLE_NON_VOLATILE) ||
+	     !(attributes & EFI_VARIABLE_RUNTIME_ACCESS) ||
 	     !(attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS)))
 		return EFI_INVALID_PARAMETER;
 
@@ -281,8 +303,6 @@
 
 	/* authenticate a variable */
 	if (IS_ENABLED(CONFIG_EFI_SECURE_BOOT)) {
-		if (attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)
-			return EFI_INVALID_PARAMETER;
 		if (attributes &
 		    EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
 			u32 env_attr;
@@ -300,8 +320,7 @@
 		}
 	} else {
 		if (attributes &
-		    (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS |
-		     EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) {
+		    EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
 			EFI_PRINT("Secure boot is not configured\n");
 			return EFI_INVALID_PARAMETER;
 		}
diff --git a/scripts/build-efi.sh b/scripts/build-efi.sh
index bc9aeeb..46c2880 100755
--- a/scripts/build-efi.sh
+++ b/scripts/build-efi.sh
@@ -96,6 +96,8 @@
 	fi
 	if [[ -n "${serial}" ]]; then
 		extra="-display none -serial mon:stdio"
+	else
+		extra="-serial mon:stdio"
 	fi
 	echo "Running ${qemu}"
 	# Use 512MB since U-Boot EFI likes to have 256MB to play with
diff --git a/scripts/style.py b/scripts/style.py
new file mode 100755
index 0000000..7b73b00
--- /dev/null
+++ b/scripts/style.py
@@ -0,0 +1,180 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2021 Google LLC
+#
+
+"""Changes the functions and class methods in a file to use snake case, updating
+other tools which use them"""
+
+from argparse import ArgumentParser
+import glob
+import os
+import re
+import subprocess
+
+import camel_case
+
+# Exclude functions with these names
+EXCLUDE_NAMES = set(['setUp', 'tearDown', 'setUpClass', 'tearDownClass'])
+
+# Find function definitions in a file
+RE_FUNC = re.compile(r' *def (\w+)\(')
+
+# Where to find files that might call the file being converted
+FILES_GLOB = 'tools/**/*.py'
+
+def collect_funcs(fname):
+    """Collect a list of functions in a file
+
+    Args:
+        fname (str): Filename to read
+
+    Returns:
+        tuple:
+            str: contents of file
+            list of str: List of function names
+    """
+    with open(fname, encoding='utf-8') as inf:
+        data = inf.read()
+        funcs = RE_FUNC.findall(data)
+    return data, funcs
+
+def get_module_name(fname):
+    """Convert a filename to a module name
+
+    Args:
+        fname (str): Filename to convert, e.g. 'tools/patman/command.py'
+
+    Returns:
+        tuple:
+            str: Full module name, e.g. 'patman.command'
+            str: Leaf module name, e.g. 'command'
+            str: Program name, e.g. 'patman'
+    """
+    parts = os.path.splitext(fname)[0].split('/')[1:]
+    module_name = '.'.join(parts)
+    return module_name, parts[-1], parts[0]
+
+def process_caller(data, conv, module_name, leaf):
+    """Process a file that might call another module
+
+    This converts all the camel-case references in the provided file contents
+    with the corresponding snake-case references.
+
+    Args:
+        data (str): Contents of file to convert
+        conv (dict): Identifies to convert
+            key: Current name in camel case, e.g. 'DoIt'
+            value: New name in snake case, e.g. 'do_it'
+        module_name: Name of module as referenced by the file, e.g.
+            'patman.command'
+        leaf: Leaf module name, e.g. 'command'
+
+    Returns:
+        str: New file contents, or None if it was not modified
+    """
+    total = 0
+
+    # Update any simple functions calls into the module
+    for name, new_name in conv.items():
+        newdata, count = re.subn(fr'{leaf}.{name}\(',
+                                 f'{leaf}.{new_name}(', data)
+        total += count
+        data = newdata
+
+    # Deal with files that import symbols individually
+    imports = re.findall(fr'from {module_name} import (.*)\n', data)
+    for item in imports:
+        #print('item', item)
+        names = [n.strip() for n in item.split(',')]
+        new_names = [conv.get(n) or n for n in names]
+        new_line = f"from {module_name} import {', '.join(new_names)}\n"
+        data = re.sub(fr'from {module_name} import (.*)\n', new_line, data)
+        for name in names:
+            new_name = conv.get(name)
+            if new_name:
+                newdata = re.sub(fr'\b{name}\(', f'{new_name}(', data)
+                data = newdata
+
+    # Deal with mocks like:
+    # unittest.mock.patch.object(module, 'Function', ...
+    for name, new_name in conv.items():
+        newdata, count = re.subn(fr"{leaf}, '{name}'",
+                                 f"{leaf}, '{new_name}'", data)
+        total += count
+        data = newdata
+
+    if total or imports:
+        return data
+    return None
+
+def process_file(srcfile, do_write, commit):
+    """Process a file to rename its camel-case functions
+
+    This renames the class methods and functions in a file so that they use
+    snake case. Then it updates other modules that call those functions.
+
+    Args:
+        srcfile (str): Filename to process
+        do_write (bool): True to write back to files, False to do a dry run
+        commit (bool): True to create a commit with the changes
+    """
+    data, funcs = collect_funcs(srcfile)
+    module_name, leaf, prog = get_module_name(srcfile)
+    #print('module_name', module_name)
+    #print(len(funcs))
+    #print(funcs[0])
+    conv = {}
+    for name in funcs:
+        if name not in EXCLUDE_NAMES:
+            conv[name] = camel_case.to_snake(name)
+
+    # Convert name to new_name in the file
+    for name, new_name in conv.items():
+        #print(name, new_name)
+        # Don't match if it is preceded by a '.', since that indicates that
+        # it is calling this same function name but in a different module
+        newdata = re.sub(fr'(?<!\.){name}\(', f'{new_name}(', data)
+        data = newdata
+
+        # But do allow self.xxx
+        newdata = re.sub(fr'self.{name}\(', f'self.{new_name}(', data)
+        data = newdata
+    if do_write:
+        with open(srcfile, 'w', encoding='utf-8') as out:
+            out.write(data)
+
+    # Now find all files which use these functions and update them
+    for fname in glob.glob(FILES_GLOB, recursive=True):
+        with open(fname, encoding='utf-8') as inf:
+            data = inf.read()
+        newdata = process_caller(fname, conv, module_name, leaf)
+        if do_write and newdata:
+            with open(fname, 'w', encoding='utf-8') as out:
+                out.write(newdata)
+
+    if commit:
+        subprocess.call(['git', 'add', '-u'])
+        subprocess.call([
+            'git', 'commit', '-s', '-m',
+            f'''{prog}: Convert camel case in {os.path.basename(srcfile)}
+
+Convert this file to snake case and update all files which use it.
+'''])
+
+
+def main():
+    """Main program"""
+    epilog = 'Convert camel case function names to snake in a file and callers'
+    parser = ArgumentParser(epilog=epilog)
+    parser.add_argument('-c', '--commit', action='store_true',
+                        help='Add a commit with the changes')
+    parser.add_argument('-n', '--dry_run', action='store_true',
+                        help='Dry run, do not write back to files')
+    parser.add_argument('-s', '--srcfile', type=str, required=True, help='Filename to convert')
+    args = parser.parse_args()
+    process_file(args.srcfile, not args.dry_run, args.commit)
+
+if __name__ == '__main__':
+    main()
diff --git a/test/cmd/fdt.c b/test/cmd/fdt.c
index 8ae8a52..22e8c7e 100644
--- a/test/cmd/fdt.c
+++ b/test/cmd/fdt.c
@@ -303,6 +303,149 @@
 }
 FDT_TEST(fdt_test_resize, UT_TESTF_CONSOLE_REC);
 
+static int fdt_test_print_list_common(struct unit_test_state *uts,
+				      const char *opc, const char *node)
+{
+	/*
+	 * Test printing/listing the working FDT
+	 * subnode $node/subnode
+	 */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt %s %s/subnode", opc, node));
+	ut_assert_nextline("subnode {");
+	ut_assert_nextline("\t#address-cells = <0x00000000>;");
+	ut_assert_nextline("\t#size-cells = <0x00000000>;");
+	ut_assert_nextline("\tcompatible = \"u-boot,fdt-subnode-test-device\";");
+	ut_assert_nextline("};");
+	ut_assertok(ut_check_console_end(uts));
+
+	/*
+	 * Test printing/listing the working FDT
+	 * path / string property model
+	 */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt %s / model", opc));
+	ut_assert_nextline("model = \"U-Boot FDT test\"");
+	ut_assertok(ut_check_console_end(uts));
+
+	/*
+	 * Test printing/listing the working FDT
+	 * path $node string property compatible
+	 */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt %s %s compatible", opc, node));
+	ut_assert_nextline("compatible = \"u-boot,fdt-test-device1\"");
+	ut_assertok(ut_check_console_end(uts));
+
+	/*
+	 * Test printing/listing the working FDT
+	 * path $node stringlist property clock-names
+	 */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt %s %s clock-names", opc, node));
+	ut_assert_nextline("clock-names = \"fixed\", \"i2c\", \"spi\", \"uart2\", \"uart1\"");
+	ut_assertok(ut_check_console_end(uts));
+
+	/*
+	 * Test printing/listing the working FDT
+	 * path $node u32 property clock-frequency
+	 */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt %s %s clock-frequency", opc, node));
+	ut_assert_nextline("clock-frequency = <0x00fde800>");
+	ut_assertok(ut_check_console_end(uts));
+
+	/*
+	 * Test printing/listing the working FDT
+	 * path $node empty property u-boot,empty-property
+	 */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt %s %s u-boot,empty-property", opc, node));
+	/*
+	 * This is the only 'fdt print' / 'fdt list' incantation which
+	 * prefixes the property with node path. This has been in U-Boot
+	 * since the beginning of the command 'fdt', keep it.
+	 */
+	ut_assert_nextline("%s u-boot,empty-property", node);
+	ut_assertok(ut_check_console_end(uts));
+
+	/*
+	 * Test printing/listing the working FDT
+	 * path $node prop-encoded array property regs
+	 */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt %s %s regs", opc, node));
+	ut_assert_nextline("regs = <0x00001234 0x00001000>");
+	ut_assertok(ut_check_console_end(uts));
+
+	return 0;
+}
+
+static int fdt_test_print_list(struct unit_test_state *uts, bool print)
+{
+	const char *opc = print ? "print" : "list";
+	char fdt[4096];
+	ulong addr;
+	int ret;
+
+	/* Original source DT */
+	ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt)));
+	addr = map_to_sysmem(fdt);
+	set_working_fdt_addr(addr);
+
+	/* Test printing/listing the working FDT -- node / */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt %s", opc));
+	ut_assert_nextline("/ {");
+	ut_assert_nextline("\t#address-cells = <0x00000001>;");
+	ut_assert_nextline("\t#size-cells = <0x00000001>;");
+	ut_assert_nextline("\tcompatible = \"u-boot,fdt-test\";");
+	ut_assert_nextline("\tmodel = \"U-Boot FDT test\";");
+	ut_assert_nextline("\taliases {");
+	if (print) {
+		ut_assert_nextline("\t\tbadalias = \"/bad/alias\";");
+		ut_assert_nextline("\t\tsubnodealias = \"/test-node@1234/subnode\";");
+		ut_assert_nextline("\t\ttestnodealias = \"/test-node@1234\";");
+	}
+	ut_assert_nextline("\t};");
+	ut_assert_nextline("\ttest-node@1234 {");
+	if (print) {
+		ut_assert_nextline("\t\t#address-cells = <0x00000000>;");
+		ut_assert_nextline("\t\t#size-cells = <0x00000000>;");
+		ut_assert_nextline("\t\tcompatible = \"u-boot,fdt-test-device1\";");
+		ut_assert_nextline("\t\tclock-names = \"fixed\", \"i2c\", \"spi\", \"uart2\", \"uart1\";");
+		ut_assert_nextline("\t\tu-boot,empty-property;");
+		ut_assert_nextline("\t\tclock-frequency = <0x00fde800>;");
+		ut_assert_nextline("\t\tregs = <0x00001234 0x00001000>;");
+		ut_assert_nextline("\t\tsubnode {");
+		ut_assert_nextline("\t\t\t#address-cells = <0x00000000>;");
+		ut_assert_nextline("\t\t\t#size-cells = <0x00000000>;");
+		ut_assert_nextline("\t\t\tcompatible = \"u-boot,fdt-subnode-test-device\";");
+		ut_assert_nextline("\t\t};");
+	}
+	ut_assert_nextline("\t};");
+	ut_assert_nextline("};");
+	ut_assertok(ut_check_console_end(uts));
+
+	ret = fdt_test_print_list_common(uts, opc, "/test-node@1234");
+	if (!ret)
+		ret = fdt_test_print_list_common(uts, opc, "testnodealias");
+
+	return 0;
+}
+
+static int fdt_test_print(struct unit_test_state *uts)
+{
+	return fdt_test_print_list(uts, true);
+}
+FDT_TEST(fdt_test_print, UT_TESTF_CONSOLE_REC);
+
+static int fdt_test_list(struct unit_test_state *uts)
+{
+	return fdt_test_print_list(uts, false);
+}
+FDT_TEST(fdt_test_list, UT_TESTF_CONSOLE_REC);
+
 /* Test 'fdt get value' reading an fdt */
 static int fdt_test_get_value_string(struct unit_test_state *uts,
 				     const char *node, const char *prop,
@@ -653,23 +796,21 @@
 	 * => fdt set /path property
 	 */
 	ut_assertok(console_record_reset_enable());
-	if (sval) {
+	if (sval)
 		ut_assertok(run_commandf("fdt set %s %s %s", path, prop, sval));
-	} else if (integer) {
+	else if (integer)
 		ut_assertok(run_commandf("fdt set %s %s <%d>", path, prop, ival));
-	} else {
+	else
 		ut_assertok(run_commandf("fdt set %s %s", path, prop));
-	}
 
 	/* Validate the property is present and has correct value. */
 	ut_assertok(run_commandf("fdt get value svar %s %s", path, prop));
-	if (sval) {
+	if (sval)
 		ut_asserteq_str(sval, env_get("svar"));
-	} else if (integer) {
+	else if (integer)
 		ut_asserteq(ival, env_get_hex("svar", 0x1234));
-	} else {
+	else
 		ut_assertnull(env_get("svar"));
-	}
 	ut_assertok(ut_check_console_end(uts));
 
 	return 0;
@@ -971,6 +1112,411 @@
 }
 FDT_TEST(fdt_test_bootcpu, UT_TESTF_CONSOLE_REC);
 
+static int fdt_test_header_get(struct unit_test_state *uts,
+			       const char *field, const unsigned long val)
+{
+	/* Test getting valid header entry */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt header get fvar %s", field));
+	ut_asserteq(val, env_get_hex("fvar", 0x1234));
+	ut_assertok(ut_check_console_end(uts));
+
+	/* Test getting malformed header entry */
+	ut_assertok(console_record_reset_enable());
+	ut_asserteq(1, run_commandf("fdt header get fvar typo%stypo", field));
+	ut_assertok(ut_check_console_end(uts));
+
+	return 0;
+}
+
+static int fdt_test_header(struct unit_test_state *uts)
+{
+	char fdt[256];
+	ulong addr;
+
+	ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt)));
+	addr = map_to_sysmem(fdt);
+	set_working_fdt_addr(addr);
+
+	/* Test header print */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt header"));
+	ut_assert_nextline("magic:\t\t\t0x%x", fdt_magic(fdt));
+	ut_assert_nextline("totalsize:\t\t0x%x (%d)", fdt_totalsize(fdt), fdt_totalsize(fdt));
+	ut_assert_nextline("off_dt_struct:\t\t0x%x", fdt_off_dt_struct(fdt));
+	ut_assert_nextline("off_dt_strings:\t\t0x%x", fdt_off_dt_strings(fdt));
+	ut_assert_nextline("off_mem_rsvmap:\t\t0x%x", fdt_off_mem_rsvmap(fdt));
+	ut_assert_nextline("version:\t\t%d", fdt_version(fdt));
+	ut_assert_nextline("last_comp_version:\t%d", fdt_last_comp_version(fdt));
+	ut_assert_nextline("boot_cpuid_phys:\t0x%x", fdt_boot_cpuid_phys(fdt));
+	ut_assert_nextline("size_dt_strings:\t0x%x", fdt_size_dt_strings(fdt));
+	ut_assert_nextline("size_dt_struct:\t\t0x%x", fdt_size_dt_struct(fdt));
+	ut_assert_nextline("number mem_rsv:\t\t0x%x", fdt_num_mem_rsv(fdt));
+	ut_assert_nextline_empty();
+	ut_assertok(ut_check_console_end(uts));
+
+	/* Test header get */
+	fdt_test_header_get(uts, "magic", fdt_magic(fdt));
+	fdt_test_header_get(uts, "totalsize", fdt_totalsize(fdt));
+	fdt_test_header_get(uts, "off_dt_struct", fdt_off_dt_struct(fdt));
+	fdt_test_header_get(uts, "off_dt_strings", fdt_off_dt_strings(fdt));
+	fdt_test_header_get(uts, "off_mem_rsvmap", fdt_off_mem_rsvmap(fdt));
+	fdt_test_header_get(uts, "version", fdt_version(fdt));
+	fdt_test_header_get(uts, "last_comp_version", fdt_last_comp_version(fdt));
+	fdt_test_header_get(uts, "boot_cpuid_phys", fdt_boot_cpuid_phys(fdt));
+	fdt_test_header_get(uts, "size_dt_strings", fdt_size_dt_strings(fdt));
+	fdt_test_header_get(uts, "size_dt_struct", fdt_size_dt_struct(fdt));
+
+	return 0;
+}
+FDT_TEST(fdt_test_header, UT_TESTF_CONSOLE_REC);
+
+static int fdt_test_memory_cells(struct unit_test_state *uts,
+				 const unsigned int cells)
+{
+	unsigned char *pada, *pads;
+	unsigned char *seta, *sets;
+	char fdt[8192];
+	const int size = sizeof(fdt);
+	fdt32_t *regs;
+	ulong addr;
+	char *spc;
+	int i;
+
+	/* Create DT with node /memory { regs = <0x100 0x200>; } and #*cells */
+	ut_assertnonnull(regs = calloc(2 * cells, sizeof(*regs)));
+	ut_assertnonnull(pada = calloc(12, cells));
+	ut_assertnonnull(pads = calloc(12, cells));
+	ut_assertnonnull(seta = calloc(12, cells));
+	ut_assertnonnull(sets = calloc(12, cells));
+	for (i = cells; i >= 1; i--) {
+		regs[cells - 1] = cpu_to_fdt32(i * 0x10000);
+		regs[(cells * 2) - 1] = cpu_to_fdt32(~i);
+		snprintf(seta + (8 * (cells - i)), 9, "%08x", i * 0x10000);
+		snprintf(sets + (8 * (cells - i)), 9, "%08x", ~i);
+		spc = (i != 1) ? " " : "";
+		snprintf(pada + (11 * (cells - i)), 12, "0x%08x%s", i * 0x10000, spc);
+		snprintf(pads + (11 * (cells - i)), 12, "0x%08x%s", ~i, spc);
+	}
+
+	ut_assertok(fdt_create(fdt, size));
+	ut_assertok(fdt_finish_reservemap(fdt));
+	ut_assert(fdt_begin_node(fdt, "") >= 0);
+	ut_assertok(fdt_property_u32(fdt, "#address-cells", cells));
+	ut_assertok(fdt_property_u32(fdt, "#size-cells", cells));
+	ut_assert(fdt_begin_node(fdt, "memory") >= 0);
+	ut_assertok(fdt_property_string(fdt, "device_type", "memory"));
+	ut_assertok(fdt_property(fdt, "reg", &regs, cells * 2));
+	ut_assertok(fdt_end_node(fdt));
+	ut_assertok(fdt_end_node(fdt));
+	ut_assertok(fdt_finish(fdt));
+	fdt_shrink_to_minimum(fdt, 4096);	/* Resize with 4096 extra bytes */
+	addr = map_to_sysmem(fdt);
+	set_working_fdt_addr(addr);
+
+	/* Test updating the memory node */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt memory 0x%s 0x%s", seta, sets));
+	ut_assertok(run_commandf("fdt print /memory"));
+	ut_assert_nextline("memory {");
+	ut_assert_nextline("\tdevice_type = \"memory\";");
+	ut_assert_nextline("\treg = <%s %s>;", pada, pads);
+	ut_assert_nextline("};");
+	ut_assertok(ut_check_console_end(uts));
+
+	free(sets);
+	free(seta);
+	free(pads);
+	free(pada);
+	free(regs);
+
+	return 0;
+}
+
+static int fdt_test_memory(struct unit_test_state *uts)
+{
+	/*
+	 * Test memory fixup for 32 and 64 bit systems, anything bigger is
+	 * so far unsupported and fails because of simple_stroull() being
+	 * 64bit tops in the 'fdt memory' command implementation.
+	 */
+	fdt_test_memory_cells(uts, 1);
+	fdt_test_memory_cells(uts, 2);
+
+	/*
+	 * The 'fdt memory' command is limited to /memory node, it does
+	 * not support any other valid DT memory node format, which is
+	 * either one or multiple /memory@adresss nodes. Therefore, this
+	 * DT variant is not tested here.
+	 */
+
+	return 0;
+}
+FDT_TEST(fdt_test_memory, UT_TESTF_CONSOLE_REC);
+
+static int fdt_test_rsvmem(struct unit_test_state *uts)
+{
+	char fdt[8192];
+	ulong addr;
+
+	ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt)));
+	fdt_shrink_to_minimum(fdt, 4096);	/* Resize with 4096 extra bytes */
+	fdt_add_mem_rsv(fdt, 0x42, 0x1701);
+	fdt_add_mem_rsv(fdt, 0x74656, 0x9);
+	addr = map_to_sysmem(fdt);
+	set_working_fdt_addr(addr);
+
+	/* Test default reserved memory node presence */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt rsvmem print"));
+	ut_assert_nextline("index\t\t   start\t\t    size");
+	ut_assert_nextline("------------------------------------------------");
+	ut_assert_nextline("    %x\t%016x\t%016x", 0, 0x42, 0x1701);
+	ut_assert_nextline("    %x\t%016x\t%016x", 1, 0x74656, 0x9);
+	ut_assertok(ut_check_console_end(uts));
+
+	/* Test add new reserved memory node */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt rsvmem add 0x1234 0x5678"));
+	ut_assertok(run_commandf("fdt rsvmem print"));
+	ut_assert_nextline("index\t\t   start\t\t    size");
+	ut_assert_nextline("------------------------------------------------");
+	ut_assert_nextline("    %x\t%016x\t%016x", 0, 0x42, 0x1701);
+	ut_assert_nextline("    %x\t%016x\t%016x", 1, 0x74656, 0x9);
+	ut_assert_nextline("    %x\t%016x\t%016x", 2, 0x1234, 0x5678);
+	ut_assertok(ut_check_console_end(uts));
+
+	/* Test delete reserved memory node */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt rsvmem delete 0"));
+	ut_assertok(run_commandf("fdt rsvmem print"));
+	ut_assert_nextline("index\t\t   start\t\t    size");
+	ut_assert_nextline("------------------------------------------------");
+	ut_assert_nextline("    %x\t%016x\t%016x", 0, 0x74656, 0x9);
+	ut_assert_nextline("    %x\t%016x\t%016x", 1, 0x1234, 0x5678);
+	ut_assertok(ut_check_console_end(uts));
+
+	/* Test re-add new reserved memory node */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt rsvmem add 0x42 0x1701"));
+	ut_assertok(run_commandf("fdt rsvmem print"));
+	ut_assert_nextline("index\t\t   start\t\t    size");
+	ut_assert_nextline("------------------------------------------------");
+	ut_assert_nextline("    %x\t%016x\t%016x", 0, 0x74656, 0x9);
+	ut_assert_nextline("    %x\t%016x\t%016x", 1, 0x1234, 0x5678);
+	ut_assert_nextline("    %x\t%016x\t%016x", 2, 0x42, 0x1701);
+	ut_assertok(ut_check_console_end(uts));
+
+	/* Test delete nonexistent reserved memory node */
+	ut_assertok(console_record_reset_enable());
+	ut_asserteq(1, run_commandf("fdt rsvmem delete 10"));
+	ut_assert_nextline("libfdt fdt_del_mem_rsv(): FDT_ERR_NOTFOUND");
+	ut_assertok(ut_check_console_end(uts));
+
+	return 0;
+}
+FDT_TEST(fdt_test_rsvmem, UT_TESTF_CONSOLE_REC);
+
+static int fdt_test_chosen(struct unit_test_state *uts)
+{
+	const char *env_bootargs = env_get("bootargs");
+	char fdt[8192];
+	ulong addr;
+
+	ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt)));
+	fdt_shrink_to_minimum(fdt, 4096);	/* Resize with 4096 extra bytes */
+	addr = map_to_sysmem(fdt);
+	set_working_fdt_addr(addr);
+
+	/* Test default chosen node presence, fail as there is no /chosen node */
+	ut_assertok(console_record_reset_enable());
+	ut_asserteq(1, run_commandf("fdt print /chosen"));
+	ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
+	ut_assertok(ut_check_console_end(uts));
+
+	/* Test add new chosen node without initrd */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt chosen"));
+	ut_assertok(run_commandf("fdt print /chosen"));
+	ut_assert_nextline("chosen {");
+	ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */
+	if (env_bootargs)
+		ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs);
+	ut_assert_nextline("};");
+	ut_assertok(ut_check_console_end(uts));
+
+	/* Test add new chosen node with initrd */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt chosen 0x1234 0x5678"));
+	ut_assertok(run_commandf("fdt print /chosen"));
+	ut_assert_nextline("chosen {");
+	ut_assert_nextline("\tlinux,initrd-end = <0x%08x 0x%08x>;",
+			   upper_32_bits(0x1234 + 0x5678 - 1),
+			   lower_32_bits(0x1234 + 0x5678 - 1));
+	ut_assert_nextline("\tlinux,initrd-start = <0x%08x 0x%08x>;",
+			   upper_32_bits(0x1234), lower_32_bits(0x1234));
+	ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */
+	if (env_bootargs)
+		ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs);
+	ut_assert_nextline("};");
+	ut_assertok(ut_check_console_end(uts));
+
+	return 0;
+}
+FDT_TEST(fdt_test_chosen, UT_TESTF_CONSOLE_REC);
+
+static int fdt_test_apply(struct unit_test_state *uts)
+{
+	char fdt[8192], fdto[8192];
+	ulong addr, addro;
+
+	/* Create base DT with __symbols__ node */
+	ut_assertok(fdt_create(fdt, sizeof(fdt)));
+	ut_assertok(fdt_finish_reservemap(fdt));
+	ut_assert(fdt_begin_node(fdt, "") >= 0);
+	ut_assert(fdt_begin_node(fdt, "__symbols__") >= 0);
+	ut_assertok(fdt_end_node(fdt));
+	ut_assertok(fdt_end_node(fdt));
+	ut_assertok(fdt_finish(fdt));
+	fdt_shrink_to_minimum(fdt, 4096);	/* Resize with 4096 extra bytes */
+	addr = map_to_sysmem(fdt);
+	set_working_fdt_addr(addr);
+
+	/* Create DTO which adds single property to root node / */
+	ut_assertok(fdt_create(fdto, sizeof(fdto)));
+	ut_assertok(fdt_finish_reservemap(fdto));
+	ut_assert(fdt_begin_node(fdto, "") >= 0);
+	ut_assert(fdt_begin_node(fdto, "fragment") >= 0);
+	ut_assertok(fdt_property_string(fdto, "target-path", "/"));
+	ut_assert(fdt_begin_node(fdto, "__overlay__") >= 0);
+	ut_assertok(fdt_property_string(fdto, "newstring", "newvalue"));
+	ut_assertok(fdt_end_node(fdto));
+	ut_assertok(fdt_end_node(fdto));
+	ut_assertok(fdt_finish(fdto));
+	addro = map_to_sysmem(fdto);
+
+	/* Test default DT print */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt print /"));
+	ut_assert_nextline("/ {");
+	ut_assert_nextline("\t__symbols__ {");
+	ut_assert_nextline("\t};");
+	ut_assert_nextline("};");
+	ut_assertok(ut_check_console_end(uts));
+
+	/* Test simple DTO application */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt apply 0x%08x", addro));
+	ut_assertok(run_commandf("fdt print /"));
+	ut_assert_nextline("/ {");
+	ut_assert_nextline("\tnewstring = \"newvalue\";");
+	ut_assert_nextline("\t__symbols__ {");
+	ut_assert_nextline("\t};");
+	ut_assert_nextline("};");
+	ut_assertok(ut_check_console_end(uts));
+
+	/*
+	 * Create complex DTO which:
+	 * - modifies newstring property in root node /
+	 * - adds new properties to root node /
+	 * - adds new subnode with properties to root node /
+	 * - adds phandle to the subnode and therefore __symbols__ node
+	 */
+	ut_assertok(fdt_create(fdto, sizeof(fdto)));
+	ut_assertok(fdt_finish_reservemap(fdto));
+	ut_assert(fdt_begin_node(fdto, "") >= 0);
+	ut_assertok(fdt_property_cell(fdto, "#address-cells", 1));
+	ut_assertok(fdt_property_cell(fdto, "#size-cells", 0));
+
+	ut_assert(fdt_begin_node(fdto, "fragment@0") >= 0);
+	ut_assertok(fdt_property_string(fdto, "target-path", "/"));
+	ut_assert(fdt_begin_node(fdto, "__overlay__") >= 0);
+	ut_assertok(fdt_property_string(fdto, "newstring", "newervalue"));
+	ut_assertok(fdt_property_u32(fdto, "newu32", 0x12345678));
+	ut_assertok(fdt_property(fdto, "empty-property", NULL, 0));
+	ut_assert(fdt_begin_node(fdto, "subnode") >= 0);
+	ut_assertok(fdt_property_string(fdto, "subnewstring", "newervalue"));
+	ut_assertok(fdt_property_u32(fdto, "subnewu32", 0x12345678));
+	ut_assertok(fdt_property(fdto, "subempty-property", NULL, 0));
+	ut_assertok(fdt_property_u32(fdto, "phandle", 0x01));
+	ut_assertok(fdt_end_node(fdto));
+	ut_assertok(fdt_end_node(fdto));
+	ut_assertok(fdt_end_node(fdto));
+
+	ut_assert(fdt_begin_node(fdto, "__symbols__") >= 0);
+	ut_assertok(fdt_property_string(fdto, "subnodephandle", "/fragment@0/__overlay__/subnode"));
+	ut_assertok(fdt_end_node(fdto));
+	ut_assertok(fdt_finish(fdto));
+	addro = map_to_sysmem(fdto);
+
+	/* Test complex DTO application */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt apply 0x%08x", addro));
+	ut_assertok(run_commandf("fdt print /"));
+	ut_assert_nextline("/ {");
+	ut_assert_nextline("\tempty-property;");
+	ut_assert_nextline("\tnewu32 = <0x12345678>;");
+	ut_assert_nextline("\tnewstring = \"newervalue\";");
+	ut_assert_nextline("\tsubnode {");
+	ut_assert_nextline("\t\tphandle = <0x00000001>;");
+	ut_assert_nextline("\t\tsubempty-property;");
+	ut_assert_nextline("\t\tsubnewu32 = <0x12345678>;");
+	ut_assert_nextline("\t\tsubnewstring = \"newervalue\";");
+	ut_assert_nextline("\t};");
+	ut_assert_nextline("\t__symbols__ {");
+	ut_assert_nextline("\t\tsubnodephandle = \"/subnode\";");
+	ut_assert_nextline("\t};");
+	ut_assert_nextline("};");
+	ut_assertok(ut_check_console_end(uts));
+
+	/*
+	 * Create complex DTO which:
+	 * - modifies subnewu32 property in subnode via phandle and uses __fixups__ node
+	 */
+	ut_assertok(fdt_create(fdto, sizeof(fdto)));
+	ut_assertok(fdt_finish_reservemap(fdto));
+	ut_assert(fdt_begin_node(fdto, "") >= 0);
+	ut_assertok(fdt_property_cell(fdto, "#address-cells", 1));
+	ut_assertok(fdt_property_cell(fdto, "#size-cells", 0));
+
+	ut_assert(fdt_begin_node(fdto, "fragment@0") >= 0);
+	ut_assertok(fdt_property_u32(fdto, "target", 0xffffffff));
+	ut_assert(fdt_begin_node(fdto, "__overlay__") >= 0);
+	ut_assertok(fdt_property_u32(fdto, "subnewu32", 0xabcdef01));
+	ut_assertok(fdt_end_node(fdto));
+	ut_assertok(fdt_end_node(fdto));
+
+	ut_assert(fdt_begin_node(fdto, "__fixups__") >= 0);
+	ut_assertok(fdt_property_string(fdto, "subnodephandle", "/fragment@0:target:0"));
+	ut_assertok(fdt_end_node(fdto));
+	ut_assertok(fdt_end_node(fdto));
+	ut_assertok(fdt_finish(fdto));
+	addro = map_to_sysmem(fdto);
+
+	/* Test complex DTO application */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("fdt apply 0x%08x", addro));
+	ut_assertok(run_commandf("fdt print /"));
+	ut_assert_nextline("/ {");
+	ut_assert_nextline("\tempty-property;");
+	ut_assert_nextline("\tnewu32 = <0x12345678>;");
+	ut_assert_nextline("\tnewstring = \"newervalue\";");
+	ut_assert_nextline("\tsubnode {");
+	ut_assert_nextline("\t\tphandle = <0x00000001>;");
+	ut_assert_nextline("\t\tsubempty-property;");
+	ut_assert_nextline("\t\tsubnewu32 = <0xabcdef01>;");
+	ut_assert_nextline("\t\tsubnewstring = \"newervalue\";");
+	ut_assert_nextline("\t};");
+	ut_assert_nextline("\t__symbols__ {");
+	ut_assert_nextline("\t\tsubnodephandle = \"/subnode\";");
+	ut_assert_nextline("\t};");
+	ut_assert_nextline("};");
+	ut_assertok(ut_check_console_end(uts));
+
+	return 0;
+}
+FDT_TEST(fdt_test_apply, UT_TESTF_CONSOLE_REC);
+
 int do_ut_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 {
 	struct unit_test *tests = UNIT_TEST_SUITE_START(fdt_test);
diff --git a/test/cmd/pwm.c b/test/cmd/pwm.c
index 2fc0b5e..cf7ee0e 100644
--- a/test/cmd/pwm.c
+++ b/test/cmd/pwm.c
@@ -27,11 +27,11 @@
 	/* pwm <invert> <pwm_dev_num> <channel> <polarity> */
 	/* cros-ec-pwm doesn't support invert */
 	ut_asserteq(1, run_command("pwm invert 0 0 1", 0));
-	ut_assert_nextline("error(-38)")
+	ut_assert_nextline("error(-38)");
 	ut_assert_console_end();
 
 	ut_asserteq(1, run_command("pwm invert 0 0 0", 0));
-	ut_assert_nextline("error(-38)")
+	ut_assert_nextline("error(-38)");
 	ut_assert_console_end();
 
 	/* pwm <config> <pwm_dev_num> <channel> <period_ns> <duty_ns> */
diff --git a/test/dm/acpigen.c b/test/dm/acpigen.c
index 3ec2743..15b2b6f 100644
--- a/test/dm/acpigen.c
+++ b/test/dm/acpigen.c
@@ -1083,7 +1083,7 @@
 	ut_asserteq(NAME_OP, *ptr++);
 	ptr += 10;
 	ut_asserteq(STRING_PREFIX, *ptr++);
-	ut_asserteq_str("baldrick", (char *)ptr)
+	ut_asserteq_str("baldrick", (char *)ptr);
 	ptr += 9;
 
 	ut_asserteq(NAME_OP, *ptr++);
diff --git a/test/dm/misc.c b/test/dm/misc.c
index 1506fde..8bdd8c6 100644
--- a/test/dm/misc.c
+++ b/test/dm/misc.c
@@ -51,13 +51,13 @@
 	/* Read back last issued ioctl */
 	ut_assertok(misc_call(dev, 2, NULL, 0, &last_ioctl,
 			      sizeof(last_ioctl)));
-	ut_asserteq(6, last_ioctl)
+	ut_asserteq(6, last_ioctl);
 
 	ut_assertok(misc_ioctl(dev, 23, NULL));
 	/* Read back last issued ioctl */
 	ut_assertok(misc_call(dev, 2, NULL, 0, &last_ioctl,
 			      sizeof(last_ioctl)));
-	ut_asserteq(23, last_ioctl)
+	ut_asserteq(23, last_ioctl);
 
 	/* Enable / disable tests */
 
diff --git a/test/dm/phy.c b/test/dm/phy.c
index df4c73f..4d4a083 100644
--- a/test/dm/phy.c
+++ b/test/dm/phy.c
@@ -28,22 +28,22 @@
 	/*
 	 * Get the same phy port in 2 different ways and compare.
 	 */
-	ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1_method1))
-	ut_assertok(generic_phy_get_by_index(parent, 0, &phy1_method2))
+	ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1_method1));
+	ut_assertok(generic_phy_get_by_index(parent, 0, &phy1_method2));
 	ut_asserteq(phy1_method1.id, phy1_method2.id);
 
 	/*
 	 * Get the second phy port. Check that the same phy provider (device)
 	 * provides this 2nd phy port, but that the IDs are different
 	 */
-	ut_assertok(generic_phy_get_by_name(parent, "phy2", &phy2))
+	ut_assertok(generic_phy_get_by_name(parent, "phy2", &phy2));
 	ut_asserteq_ptr(phy1_method2.dev, phy2.dev);
 	ut_assert(phy1_method1.id != phy2.id);
 
 	/*
 	 * Get the third phy port. Check that the phy provider is different
 	 */
-	ut_assertok(generic_phy_get_by_name(parent, "phy3", &phy3))
+	ut_assertok(generic_phy_get_by_name(parent, "phy3", &phy3));
 	ut_assert(phy2.dev != phy3.dev);
 
 	/* Try to get a non-existing phy */
diff --git a/test/dm/scmi.c b/test/dm/scmi.c
index 93c7d08..d87e273 100644
--- a/test/dm/scmi.c
+++ b/test/dm/scmi.c
@@ -187,10 +187,10 @@
 	ut_assertnonnull(agent);
 
 	/* Test SCMI resect controller manipulation */
-	ut_assert(!agent->reset[0].asserted)
+	ut_assert(!agent->reset[0].asserted);
 
 	ut_assertok(reset_assert(&scmi_devices->reset[0]));
-	ut_assert(agent->reset[0].asserted)
+	ut_assert(agent->reset[0].asserted);
 
 	ut_assertok(reset_deassert(&scmi_devices->reset[0]));
 	ut_assert(!agent->reset[0].asserted);
diff --git a/test/lib/Makefile b/test/lib/Makefile
index 7e7922f..e0bd9e0 100644
--- a/test/lib/Makefile
+++ b/test/lib/Makefile
@@ -20,6 +20,7 @@
 obj-$(CONFIG_UT_LIB_RSA) += rsa.o
 obj-$(CONFIG_AES) += test_aes.o
 obj-$(CONFIG_GETOPT) += getopt.o
+obj-$(CONFIG_CRC8) += test_crc8.o
 obj-$(CONFIG_UT_LIB_CRYPT) += test_crypt.o
 else
 obj-$(CONFIG_SANDBOX) += kconfig_spl.o
diff --git a/test/lib/kconfig.c b/test/lib/kconfig.c
index 472d2c5..76225ba 100644
--- a/test/lib/kconfig.c
+++ b/test/lib/kconfig.c
@@ -15,12 +15,12 @@
 {
 	ulong val;
 
-	ut_asserteq(1, IS_ENABLED(CONFIG_CMDLINE))
-	ut_asserteq(0, IS_ENABLED(CONFIG__UNDEFINED))
+	ut_asserteq(1, IS_ENABLED(CONFIG_CMDLINE));
+	ut_asserteq(0, IS_ENABLED(CONFIG__UNDEFINED));
 
-	ut_asserteq(1, CONFIG_IS_ENABLED(CMDLINE))
-	ut_asserteq(0, CONFIG_IS_ENABLED(OF_PLATDATA))
-	ut_asserteq(0, CONFIG_IS_ENABLED(_UNDEFINED))
+	ut_asserteq(1, CONFIG_IS_ENABLED(CMDLINE));
+	ut_asserteq(0, CONFIG_IS_ENABLED(OF_PLATDATA));
+	ut_asserteq(0, CONFIG_IS_ENABLED(_UNDEFINED));
 
 	ut_asserteq(0xc000,
 		    IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED, CONFIG_BLOBLIST_ADDR));
diff --git a/test/lib/kconfig_spl.c b/test/lib/kconfig_spl.c
index c89ceaec..8f8a341 100644
--- a/test/lib/kconfig_spl.c
+++ b/test/lib/kconfig_spl.c
@@ -15,9 +15,9 @@
 {
 	ulong val;
 
-	ut_asserteq(0, CONFIG_IS_ENABLED(CMDLINE))
-	ut_asserteq(1, CONFIG_IS_ENABLED(OF_PLATDATA))
-	ut_asserteq(0, CONFIG_IS_ENABLED(_UNDEFINED))
+	ut_asserteq(0, CONFIG_IS_ENABLED(CMDLINE));
+	ut_asserteq(1, CONFIG_IS_ENABLED(OF_PLATDATA));
+	ut_asserteq(0, CONFIG_IS_ENABLED(_UNDEFINED));
 
 	/*
 	 * This fails if CONFIG_TEST_KCONFIG_ENABLE is not enabled, since the
diff --git a/test/lib/test_crc8.c b/test/lib/test_crc8.c
new file mode 100644
index 0000000..0dac97b
--- /dev/null
+++ b/test/lib/test_crc8.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2023, Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
+ *
+ * Unit test for crc8
+ */
+
+#include <test/lib.h>
+#include <test/ut.h>
+#include <u-boot/crc.h>
+
+static int lib_crc8(struct unit_test_state *uts) {
+	const char str[] = {0x20, 0xf4, 0xd8, 0x24, 0x6f, 0x41, 0x91, 0xae,
+			    0x46, 0x61, 0xf6, 0x55, 0xeb, 0x38, 0x47, 0x0f,
+			    0xec, 0xd8};
+	int actual1, actual2, actual3;
+	int expected1 = 0x47, expected2 = 0xea, expected3 = expected1;
+
+	actual1 = crc8(0, str, sizeof(str));
+	ut_asserteq(expected1, actual1);
+	actual2 = crc8(0, str, 7);
+	ut_asserteq(expected2, actual2);
+	actual3 = crc8(actual2, str + 7, sizeof(str) - 7);
+	ut_asserteq(expected3, actual3);
+
+	return 0;
+}
+
+LIB_TEST(lib_crc8, 0);
diff --git a/test/unicode_ut.c b/test/unicode_ut.c
index 382b796..b27d711 100644
--- a/test/unicode_ut.c
+++ b/test/unicode_ut.c
@@ -192,7 +192,7 @@
 		if (!code)
 			break;
 	}
-	ut_asserteq_ptr(s, d2 + 9)
+	ut_asserteq_ptr(s, d2 + 9);
 
 	/* Check characters less than 0x10000 */
 	s = d3;
@@ -203,7 +203,7 @@
 		if (!code)
 			break;
 	}
-	ut_asserteq_ptr(s, d3 + 9)
+	ut_asserteq_ptr(s, d3 + 9);
 
 	/* Check character greater 0xffff */
 	s = d4;
@@ -228,7 +228,7 @@
 
 	/* Commercial at, translates to one character */
 	pos = buffer;
-	ut_assert(!utf8_put('@', &pos))
+	ut_assert(!utf8_put('@', &pos));
 	ut_asserteq(1, pos - buffer);
 	ut_asserteq('@', buffer[0]);
 	ut_assert(!buffer[1]);
diff --git a/tools/.gitignore b/tools/.gitignore
index 788ea26..cda3ea6 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -6,6 +6,7 @@
 /dumpimage
 /easylogo/easylogo
 /envcrc
+/fdt_add_pubkey
 /fdtgrep
 /file2include
 /fit_check_sign
diff --git a/tools/Makefile b/tools/Makefile
index e13effb..38699b0 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -65,6 +65,7 @@
 
 hostprogs-y += dumpimage mkimage
 hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += fit_info fit_check_sign
+hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += fdt_add_pubkey
 
 ifneq ($(CONFIG_CMD_BOOTEFI_SELFTEST)$(CONFIG_FWU_MDATA_GPT_BLK),)
 hostprogs-y += file2include
@@ -150,6 +151,7 @@
 mkimage-objs   := $(dumpimage-mkimage-objs) mkimage.o
 fit_info-objs   := $(dumpimage-mkimage-objs) fit_info.o
 fit_check_sign-objs   := $(dumpimage-mkimage-objs) fit_check_sign.o
+fdt_add_pubkey-objs   := $(dumpimage-mkimage-objs) fdt_add_pubkey.o
 file2include-objs := file2include.o
 
 ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_TOOLS_LIBCRYPTO),)
@@ -187,6 +189,7 @@
 HOSTLDLIBS_dumpimage := $(HOSTLDLIBS_mkimage)
 HOSTLDLIBS_fit_info := $(HOSTLDLIBS_mkimage)
 HOSTLDLIBS_fit_check_sign := $(HOSTLDLIBS_mkimage)
+HOSTLDLIBS_fdt_add_pubkey := $(HOSTLDLIBS_mkimage)
 
 hostprogs-$(CONFIG_EXYNOS5250) += mkexynosspl
 hostprogs-$(CONFIG_EXYNOS5420) += mkexynosspl
diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst
index e65fbff..23cbb99 100644
--- a/tools/binman/binman.rst
+++ b/tools/binman/binman.rst
@@ -406,9 +406,9 @@
 Running binman
 --------------
 
-Type::
+Type:
 
-.. code-block: bash
+.. code-block:: bash
 
    make NO_PYTHON=1 PREFIX=/ install
     binman build -b <board_name>
@@ -1366,6 +1366,24 @@
 
 .. _`BinmanLogging`:
 
+Signing FIT container with private key in an image
+--------------------------------------------------
+
+You can sign FIT container with private key in your image.
+For example::
+
+    $ binman sign -i image.bin -k privatekey -a sha256,rsa4096 fit
+
+binman will extract FIT container, sign and replace it immediately.
+
+If you want to sign and replace FIT container in place::
+
+    $ binman sign -i image.bin -k privatekey -a sha256,rsa4096 -f fit.fit fit
+
+which will sign FIT container with private key and replace it immediately
+inside your image.
+
+
 Logging
 -------
 
@@ -1751,6 +1769,35 @@
     output directory if a single test is run (pass test name at the end of the
     command line
 
+binman sign
+-----------
+
+Usage::
+
+    binman sign [-h] -a ALGO [-f FILE] -i IMAGE -k KEY [paths ...]
+
+positional arguments:
+
+paths
+    Paths within file to sign (wildcard)
+
+options:
+
+-h, --help
+    show this help message and exit
+
+-a ALGO, --algo ALGO
+    Hash algorithm e.g. sha256,rsa4096
+
+-f FILE, --file FILE
+    Input filename to sign
+
+-i IMAGE, --image IMAGE
+    Image filename to update
+
+-k KEY, --key KEY
+    Private key file for signing
+
 binman tool
 -----------
 
diff --git a/tools/binman/cmdline.py b/tools/binman/cmdline.py
index 1b7bbe8..4b875a9 100644
--- a/tools/binman/cmdline.py
+++ b/tools/binman/cmdline.py
@@ -176,6 +176,19 @@
     replace_parser.add_argument('paths', type=str, nargs='*',
                                 help='Paths within file to replace (wildcard)')
 
+    sign_parser = subparsers.add_parser('sign',
+                                           help='Sign entries in image')
+    sign_parser.add_argument('-a', '--algo', type=str, required=True,
+                                help='Hash algorithm e.g. sha256,rsa4096')
+    sign_parser.add_argument('-f', '--file', type=str, required=False,
+                                help='Input filename to sign')
+    sign_parser.add_argument('-i', '--image', type=str, required=True,
+                                help='Image filename to update')
+    sign_parser.add_argument('-k', '--key', type=str, required=True,
+                                help='Private key file for signing')
+    sign_parser.add_argument('paths', type=str, nargs='*',
+                                help='Paths within file to sign (wildcard)')
+
     if HAS_TESTS:
         test_parser = subparsers.add_parser('test', help='Run tests')
         test_parser.add_argument('-P', '--processes', type=int,
diff --git a/tools/binman/control.py b/tools/binman/control.py
index 2f2b489..0febcb7 100644
--- a/tools/binman/control.py
+++ b/tools/binman/control.py
@@ -448,6 +448,31 @@
     AfterReplace(image, allow_resize=allow_resize, write_map=write_map)
     return image
 
+def SignEntries(image_fname, input_fname, privatekey_fname, algo, entry_paths,
+                write_map=False):
+    """Sign and replace the data from one or more entries from input files
+
+    Args:
+        image_fname: Image filename to process
+        input_fname: Single input filename to use if replacing one file, None
+            otherwise
+        algo: Hashing algorithm
+        entry_paths: List of entry paths to sign
+        privatekey_fname: Private key filename
+        write_map (bool): True to write the map file
+    """
+    image_fname = os.path.abspath(image_fname)
+    image = Image.FromFile(image_fname)
+
+    image.mark_build_done()
+
+    BeforeReplace(image, allow_resize=True)
+
+    for entry_path in entry_paths:
+        entry = image.FindEntryPath(entry_path)
+        entry.UpdateSignatures(privatekey_fname, algo, input_fname)
+
+    AfterReplace(image, allow_resize=True, write_map=write_map)
 
 def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded):
     """Prepare the images to be processed and select the device tree
@@ -660,7 +685,7 @@
     tools.set_tool_paths(tool_paths or None)
     bintool.Bintool.set_tool_dir(args.tooldir)
 
-    if args.cmd in ['ls', 'extract', 'replace', 'tool']:
+    if args.cmd in ['ls', 'extract', 'replace', 'tool', 'sign']:
         try:
             tout.init(args.verbosity)
             if args.cmd == 'replace':
@@ -679,6 +704,9 @@
                                do_compress=not args.compressed,
                                allow_resize=not args.fix_size, write_map=args.map)
 
+            if args.cmd == 'sign':
+                SignEntries(args.image, args.file, args.key, args.algo, args.paths)
+
             if args.cmd == 'tool':
                 if args.list:
                     bintool.Bintool.list_all()
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index 9a52b22..b71af80 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -1391,6 +1391,20 @@
 
 
 
+.. _etype_rockchip_tpl:
+
+Entry: rockchip-tpl: Rockchip TPL binary
+----------------------------------------
+
+Properties / Entry arguments:
+    - rockchip-tpl-path: Filename of file to read into the entry,
+                         typically <soc>_ddr_<version>.bin
+
+This entry holds an external TPL binary used by some Rockchip SoCs
+instead of normal U-Boot TPL, typically to initialize DRAM.
+
+
+
 .. _etype_scp:
 
 Entry: scp: System Control Processor (SCP) firmware blob
diff --git a/tools/binman/entry.py b/tools/binman/entry.py
index b10a433..3945690 100644
--- a/tools/binman/entry.py
+++ b/tools/binman/entry.py
@@ -1378,3 +1378,6 @@
         if entries:
             for entry in entries.values():
                 entry.mark_build_done()
+
+    def UpdateSignatures(self, privatekey_fname, algo, input_fname):
+        self.Raise('Updating signatures is not supported with this entry type')
diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py
index 03fe88e..c395706 100644
--- a/tools/binman/etype/fit.py
+++ b/tools/binman/etype/fit.py
@@ -835,3 +835,19 @@
 
     def CheckEntries(self):
         pass
+
+    def UpdateSignatures(self, privatekey_fname, algo, input_fname):
+        uniq = self.GetUniqueName()
+        args = [ '-G', privatekey_fname, '-r', '-o', algo, '-F' ]
+        if input_fname:
+            fname = input_fname
+        else:
+            fname = tools.get_output_filename('%s.fit' % uniq)
+            tools.write_file(fname, self.GetData())
+        args.append(fname)
+
+        if self.mkimage.run_cmd(*args) is None:
+            self.Raise("Missing tool: 'mkimage'")
+
+        data = tools.read_file(fname)
+        self.WriteData(data)
diff --git a/tools/binman/etype/mkimage.py b/tools/binman/etype/mkimage.py
index 27a0c4b..e028c44 100644
--- a/tools/binman/etype/mkimage.py
+++ b/tools/binman/etype/mkimage.py
@@ -156,7 +156,8 @@
             for entry in self._mkimage_entries.values():
                 if not entry.ObtainContents(fake_size=fake_size):
                     return False
-                fnames.append(tools.get_input_filename(entry.GetDefaultFilename()))
+                if entry._pathname:
+                    fnames.append(entry._pathname)
             input_fname = ":".join(fnames)
         else:
             data, input_fname, uniq = self.collect_contents_to_file(
@@ -171,6 +172,13 @@
         outfile = self._filename if self._filename else 'mkimage-out.%s' % uniq
         output_fname = tools.get_output_filename(outfile)
 
+        missing_list = []
+        self.CheckMissing(missing_list)
+        self.missing = bool(missing_list)
+        if self.missing:
+            self.SetContents(b'')
+            return self.allow_missing
+
         args = ['-d', input_fname]
         if self._data_to_imagename:
             args += ['-n', input_fname]
@@ -216,6 +224,20 @@
         if self._imagename:
             self._imagename.SetAllowFakeBlob(allow_fake)
 
+    def CheckMissing(self, missing_list):
+        """Check if any entries in this section have missing external blobs
+
+        If there are missing (non-optional) blobs, the entries are added to the
+        list
+
+        Args:
+            missing_list: List of Entry objects to be added to
+        """
+        for entry in self._mkimage_entries.values():
+            entry.CheckMissing(missing_list)
+        if self._imagename:
+            self._imagename.CheckMissing(missing_list)
+
     def CheckFakedBlobs(self, faked_blobs_list):
         """Check if any entries in this section have faked external blobs
 
diff --git a/tools/binman/etype/rockchip_tpl.py b/tools/binman/etype/rockchip_tpl.py
new file mode 100644
index 0000000..74f58ba
--- /dev/null
+++ b/tools/binman/etype/rockchip_tpl.py
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Entry-type module for Rockchip TPL binary
+#
+
+from binman.etype.blob_named_by_arg import Entry_blob_named_by_arg
+
+class Entry_rockchip_tpl(Entry_blob_named_by_arg):
+    """Rockchip TPL binary
+
+    Properties / Entry arguments:
+        - rockchip-tpl-path: Filename of file to read into the entry,
+                             typically <soc>_ddr_<version>.bin
+
+    This entry holds an external TPL binary used by some Rockchip SoCs
+    instead of normal U-Boot TPL, typically to initialize DRAM.
+    """
+    def __init__(self, section, etype, node):
+        super().__init__(section, etype, node, 'rockchip-tpl')
+        self.external = True
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index f1e14c6..43b4f85 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -90,6 +90,7 @@
 ATF_BL2U_DATA         = b'bl2u'
 OPENSBI_DATA          = b'opensbi'
 SCP_DATA              = b'scp'
+ROCKCHIP_TPL_DATA     = b'rockchip-tpl'
 TEST_FDT1_DATA        = b'fdt1'
 TEST_FDT2_DATA        = b'test-fdt2'
 ENV_DATA              = b'var1=1\nvar2="2"'
@@ -205,6 +206,7 @@
         TestFunctional._MakeInputFile('bl2u.bin', ATF_BL2U_DATA)
         TestFunctional._MakeInputFile('fw_dynamic.bin', OPENSBI_DATA)
         TestFunctional._MakeInputFile('scp.bin', SCP_DATA)
+        TestFunctional._MakeInputFile('rockchip-tpl.bin', ROCKCHIP_TPL_DATA)
 
         # Add a few .dtb files for testing
         TestFunctional._MakeInputFile('%s/test-fdt1.dtb' % TEST_FDT_SUBDIR,
@@ -707,6 +709,14 @@
         AddNode(dtb.GetRoot(), '')
         return tree
 
+    def _CheckSign(self, fit, key):
+        try:
+            tools.run('fit_check_sign', '-k', key, '-f', fit)
+        except:
+            self.fail('Expected signed FIT container')
+            return False
+        return True
+
     def testRun(self):
         """Test a basic run with valid args"""
         result = self._RunBinman('-h')
@@ -6565,6 +6575,107 @@
         err = stderr.getvalue()
         self.assertRegex(err, "Image 'image'.*missing bintools.*: openssl")
 
+    def testPackRockchipTpl(self):
+        """Test that an image with a Rockchip TPL binary can be created"""
+        data = self._DoReadFile('277_rockchip_tpl.dts')
+        self.assertEqual(ROCKCHIP_TPL_DATA, data[:len(ROCKCHIP_TPL_DATA)])
+
+    def testMkimageMissingBlobMultiple(self):
+        """Test missing blob with mkimage entry and multiple-data-files"""
+        with test_util.capture_sys_output() as (stdout, stderr):
+            self._DoTestFile('278_mkimage_missing_multiple.dts', allow_missing=True)
+        err = stderr.getvalue()
+        self.assertIn("is missing external blobs and is non-functional", err)
+
+        with self.assertRaises(ValueError) as e:
+            self._DoTestFile('278_mkimage_missing_multiple.dts', allow_missing=False)
+        self.assertIn("not found in input path", str(e.exception))
+
+    def _PrepareSignEnv(self, dts='280_fit_sign.dts'):
+        """Prepare sign environment
+
+        Create private and public keys, add pubkey into dtb.
+
+        Returns:
+            Tuple:
+                FIT container
+                Image name
+                Private key
+                DTB
+        """
+
+        data = self._DoReadFileRealDtb(dts)
+        updated_fname = tools.get_output_filename('image-updated.bin')
+        tools.write_file(updated_fname, data)
+        dtb = tools.get_output_filename('source.dtb')
+        private_key = tools.get_output_filename('test_key.key')
+        public_key = tools.get_output_filename('test_key.crt')
+        fit = tools.get_output_filename('fit.fit')
+        key_dir = tools.get_output_dir()
+
+        tools.run('openssl', 'req', '-batch' , '-newkey', 'rsa:4096',
+                  '-sha256', '-new',  '-nodes',  '-x509', '-keyout',
+                  private_key, '-out', public_key)
+        tools.run('fdt_add_pubkey', '-a', 'sha256,rsa4096', '-k', key_dir,
+                  '-n', 'test_key', '-r', 'conf', dtb)
+
+        return fit, updated_fname, private_key, dtb
+
+    def testSignSimple(self):
+        """Test that a FIT container can be signed in image"""
+        is_signed = False
+        fit, fname, private_key, dtb = self._PrepareSignEnv()
+
+        # do sign with private key
+        control.SignEntries(fname, None, private_key, 'sha256,rsa4096',
+                            ['fit'])
+        is_signed = self._CheckSign(fit, dtb)
+
+        self.assertEqual(is_signed, True)
+
+    def testSignExactFIT(self):
+        """Test that a FIT container can be signed and replaced in image"""
+        is_signed = False
+        fit, fname, private_key, dtb = self._PrepareSignEnv()
+
+        # Make sure we propagate the toolpath, since mkimage may not be on PATH
+        args = []
+        if self.toolpath:
+            for path in self.toolpath:
+                args += ['--toolpath', path]
+
+        # do sign with private key
+        self._DoBinman(*args, 'sign', '-i', fname, '-k', private_key, '-a',
+                       'sha256,rsa4096', '-f', fit, 'fit')
+        is_signed = self._CheckSign(fit, dtb)
+
+        self.assertEqual(is_signed, True)
+
+    def testSignNonFit(self):
+        """Test a non-FIT entry cannot be signed"""
+        is_signed = False
+        fit, fname, private_key, _ = self._PrepareSignEnv(
+            '281_sign_non_fit.dts')
+
+        # do sign with private key
+        with self.assertRaises(ValueError) as e:
+            self._DoBinman('sign', '-i', fname, '-k', private_key, '-a',
+                       'sha256,rsa4096', '-f', fit, 'u-boot')
+        self.assertIn(
+            "Node '/u-boot': Updating signatures is not supported with this entry type",
+            str(e.exception))
+
+    def testSignMissingMkimage(self):
+        """Test that FIT signing handles a missing mkimage tool"""
+        fit, fname, private_key, _ = self._PrepareSignEnv()
+
+        # try to sign with a missing mkimage tool
+        bintool.Bintool.set_missing_list(['mkimage'])
+        with self.assertRaises(ValueError) as e:
+            control.SignEntries(fname, None, private_key, 'sha256,rsa4096',
+                                ['fit'])
+        self.assertIn("Node '/fit': Missing tool: 'mkimage'", str(e.exception))
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/binman/missing-blob-help b/tools/binman/missing-blob-help
index 4448ac9..f3a44d0 100644
--- a/tools/binman/missing-blob-help
+++ b/tools/binman/missing-blob-help
@@ -34,6 +34,11 @@
 the R5F core(s) to trigger the system reset. One possible source is
 https://github.com/siemens/k3-rti-wdt.
 
+rockchip-tpl:
+An external TPL is required to initialize DRAM. Get the external TPL
+binary and build with ROCKCHIP_TPL=/path/to/ddr.bin. One possible source
+for the external TPL binary is https://github.com/rockchip-linux/rkbin.
+
 tee-os:
 See the documentation for your board. You may need to build Open Portable
 Trusted Execution Environment (OP-TEE) with TEE=/path/to/tee.bin
diff --git a/tools/binman/test/277_rockchip_tpl.dts b/tools/binman/test/277_rockchip_tpl.dts
new file mode 100644
index 0000000..269f56e
--- /dev/null
+++ b/tools/binman/test/277_rockchip_tpl.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		size = <16>;
+
+		rockchip-tpl {
+			filename = "rockchip-tpl.bin";
+		};
+	};
+};
diff --git a/tools/binman/test/278_mkimage_missing_multiple.dts b/tools/binman/test/278_mkimage_missing_multiple.dts
new file mode 100644
index 0000000..f84aea4
--- /dev/null
+++ b/tools/binman/test/278_mkimage_missing_multiple.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		mkimage {
+			args = "-n test -T script";
+			multiple-data-files;
+
+			blob-ext {
+				filename = "missing.bin";
+			};
+		};
+	};
+};
diff --git a/tools/binman/test/280_fit_sign.dts b/tools/binman/test/280_fit_sign.dts
new file mode 100644
index 0000000..b9f17dc
--- /dev/null
+++ b/tools/binman/test/280_fit_sign.dts
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		size = <0x100000>;
+		allow-repack;
+
+		fit {
+			description = "U-Boot";
+			offset = <0x10000>;
+			images {
+				u-boot-1 {
+					description = "U-Boot";
+					type = "standalone";
+					arch = "arm64";
+					os = "u-boot";
+					compression = "none";
+					hash-1 {
+						algo = "sha256";
+					};
+					u-boot {
+					};
+				};
+
+				fdt-1 {
+					description = "test.dtb";
+					type = "flat_dt";
+					arch = "arm64";
+					compression = "none";
+					hash-1 {
+						algo = "sha256";
+					};
+					u-boot-spl-dtb {
+					};
+				};
+
+			};
+
+			configurations {
+				default = "conf-1";
+				conf-1 {
+					description = "u-boot with fdt";
+					firmware = "u-boot-1";
+					fdt = "fdt-1";
+					signature-1 {
+						algo = "sha256,rsa4096";
+						key-name-hint = "test_key";
+						sign-images = "firmware", "fdt";
+					};
+
+				};
+			};
+		};
+
+		fdtmap {
+		};
+	};
+};
diff --git a/tools/binman/test/281_sign_non_fit.dts b/tools/binman/test/281_sign_non_fit.dts
new file mode 100644
index 0000000..e16c954
--- /dev/null
+++ b/tools/binman/test/281_sign_non_fit.dts
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		size = <0x100000>;
+		allow-repack;
+
+		u-boot {
+		};
+		fit {
+			description = "U-Boot";
+			offset = <0x10000>;
+			images {
+				u-boot-1 {
+					description = "U-Boot";
+					type = "standalone";
+					arch = "arm64";
+					os = "u-boot";
+					compression = "none";
+					hash-1 {
+						algo = "sha256";
+					};
+					u-boot {
+					};
+				};
+
+				fdt-1 {
+					description = "test.dtb";
+					type = "flat_dt";
+					arch = "arm64";
+					compression = "none";
+					hash-1 {
+						algo = "sha256";
+					};
+					u-boot-spl-dtb {
+					};
+				};
+
+			};
+
+			configurations {
+				default = "conf-1";
+				conf-1 {
+					description = "u-boot with fdt";
+					firmware = "u-boot-1";
+					fdt = "fdt-1";
+					signature-1 {
+						algo = "sha256,rsa4096";
+						key-name-hint = "test_key";
+						sign-images = "firmware", "fdt";
+					};
+
+				};
+			};
+		};
+
+		fdtmap {
+		};
+	};
+};
diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py
index 8f9130b..241e8e6 100644
--- a/tools/buildman/toolchain.py
+++ b/tools/buildman/toolchain.py
@@ -157,7 +157,9 @@
             Value of that environment variable or arguments
         """
         if which == VAR_CROSS_COMPILE:
-            return self.GetWrapper() + self.cross
+            wrapper = self.GetWrapper()
+            base = '' if self.arch == 'sandbox' else self.path
+            return wrapper + os.path.join(base, self.cross)
         elif which == VAR_PATH:
             return self.path
         elif which == VAR_ARCH:
diff --git a/tools/fdt_add_pubkey.c b/tools/fdt_add_pubkey.c
new file mode 100644
index 0000000..999f5a7
--- /dev/null
+++ b/tools/fdt_add_pubkey.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0+
+#include <image.h>
+#include "fit_common.h"
+
+static const char *cmdname;
+
+static const char *algo_name = "sha1,rsa2048"; /* -a <algo> */
+static const char *keydir = "."; /* -k <keydir> */
+static const char *keyname = "key"; /* -n <keyname> */
+static const char *require_keys; /* -r <conf|image> */
+static const char *keydest; /* argv[n] */
+
+static void print_usage(const char *msg)
+{
+	fprintf(stderr, "Error: %s\n", msg);
+	fprintf(stderr, "Usage: %s [-a <algo>] [-k <keydir>] [-n <keyname>] [-r <conf|image>]"
+			" <fdt blob>\n", cmdname);
+	fprintf(stderr, "Help information: %s [-h]\n", cmdname);
+	exit(EXIT_FAILURE);
+}
+
+static void print_help(void)
+{
+	fprintf(stderr, "Options:\n"
+		"\t-a <algo>       Cryptographic algorithm. Optional parameter, default value: sha1,rsa2048\n"
+		"\t-k <keydir>     Directory with public key. Optional parameter, default value: .\n"
+		"\t-n <keyname>    Public key name. Optional parameter, default value: key\n"
+		"\t-r <conf|image> Required: If present this indicates that the key must be verified for the image / configuration to be considered valid.\n"
+		"\t<fdt blob>      FDT blob file for adding of the public key. Required parameter.\n");
+	exit(EXIT_FAILURE);
+}
+
+static void process_args(int argc, char *argv[])
+{
+	int opt;
+
+	while ((opt = getopt(argc, argv, "a:k:n:r:h")) != -1) {
+		switch (opt) {
+		case 'k':
+			keydir = optarg;
+			break;
+		case 'a':
+			algo_name = optarg;
+			break;
+		case 'n':
+			keyname = optarg;
+			break;
+		case 'r':
+			require_keys = optarg;
+			break;
+		case 'h':
+			print_help();
+		default:
+			print_usage("Invalid option");
+		}
+	}
+	/* The last parameter is expected to be the .dtb to add the public key to */
+	if (optind < argc)
+		keydest = argv[optind];
+
+	if (!keydest)
+		print_usage("Missing dtb file to update");
+}
+
+static void reset_info(struct image_sign_info *info)
+{
+	if (!info)
+		fprintf(stderr, "Error: info is NULL in %s\n", __func__);
+
+	memset(info, 0, sizeof(struct image_sign_info));
+
+	info->keydir = keydir;
+	info->keyname = keyname;
+	info->name = algo_name;
+	info->require_keys = require_keys;
+	info->crypto = image_get_crypto_algo(algo_name);
+
+	if (!info->crypto) {
+		fprintf(stderr, "Unsupported signature algorithm '%s'\n",
+			algo_name);
+		exit(EXIT_FAILURE);
+	}
+}
+
+static int add_pubkey(struct image_sign_info *info)
+{
+	int destfd = -1, ret;
+	void *dest_blob = NULL;
+	struct stat dest_sbuf;
+	size_t size_inc = 0;
+
+	if (!info)
+		fprintf(stderr, "Error: info is NULL in %s\n", __func__);
+
+	do {
+		if (destfd >= 0) {
+			munmap(dest_blob, dest_sbuf.st_size);
+			close(destfd);
+
+			fprintf(stderr, ".dtb too small, increasing size by 1024 bytes\n");
+			size_inc = 1024;
+		}
+
+		destfd = mmap_fdt(cmdname, keydest, size_inc, &dest_blob,
+				  &dest_sbuf, false, false);
+		if (destfd < 0)
+			exit(EXIT_FAILURE);
+
+		ret = info->crypto->add_verify_data(info, dest_blob);
+		if (ret == -ENOSPC)
+			continue;
+		else if (ret < 0)
+			break;
+	} while (ret == -ENOSPC);
+
+	return ret;
+}
+
+int main(int argc, char *argv[])
+{
+	struct image_sign_info info;
+	int ret;
+
+	cmdname = argv[0];
+
+	process_args(argc, argv);
+	reset_info(&info);
+	ret = add_pubkey(&info);
+
+	if (ret < 0) {
+		fprintf(stderr, "%s: Cannot add public key to FIT blob: %s\n",
+			cmdname, strerror(ret));
+		exit(EXIT_FAILURE);
+	}
+
+	exit(EXIT_SUCCESS);
+}
+
diff --git a/tools/rkcommon.c b/tools/rkcommon.c
index 1f1eaa1..96efc11 100644
--- a/tools/rkcommon.c
+++ b/tools/rkcommon.c
@@ -129,12 +129,13 @@
 	{ "rk322x", "RK32", 0x8000 - 0x1000, false, RK_HEADER_V1 },
 	{ "rk3288", "RK32", 0x8000, false, RK_HEADER_V1 },
 	{ "rk3308", "RK33", 0x40000 - 0x1000, false, RK_HEADER_V1 },
-	{ "rk3328", "RK32", 0x8000 - 0x1000, false, RK_HEADER_V1 },
+	{ "rk3328", "RK32", 0x8000 - 0x800, false, RK_HEADER_V1 },
 	{ "rk3368", "RK33", 0x8000 - 0x1000, false, RK_HEADER_V1 },
 	{ "rk3399", "RK33", 0x30000 - 0x2000, false, RK_HEADER_V1 },
 	{ "rv1108", "RK11", 0x1800, false, RK_HEADER_V1 },
 	{ "rv1126", "110B", 0x10000 - 0x1000, false, RK_HEADER_V1 },
-	{ "rk3568", "RK35", 0x14000 - 0x1000, false, RK_HEADER_V2 },
+	{ "rk3568", "RK35", 0x10000 - 0x1000, false, RK_HEADER_V2 },
+	{ "rk3588", "RK35", 0x100000 - 0x1000, false, RK_HEADER_V2 },
 };
 
 /**