Merge branch 'master' of git://git.denx.de/u-boot-spi

- Various MTD fixes from Boris
- Zap various unused / legacy paths.
- pxa3xx NAND update from Miquel

Signed-off-by: Tom Rini <trini@konsulko.com>
diff --git a/Kconfig b/Kconfig
index dca9bb4..42672a9 100644
--- a/Kconfig
+++ b/Kconfig
@@ -86,6 +86,7 @@
 	select SUPPORT_RAW_INITRD
 	select SYS_LONGHELP
 	imply CMD_MII if NET
+	imply USB_STORAGE
 	imply USE_BOOTCOMMAND
 	help
 	  Select this to enable various options and commands which are suitable
@@ -290,6 +291,14 @@
 	  device memory. Assure this size does not extend past expected storage
 	  space.
 
+config FIT_ENABLE_RSASSA_PSS_SUPPORT
+	bool "Support rsassa-pss signature scheme of FIT image contents"
+	depends on FIT_SIGNATURE
+	default n
+	help
+	  Enable this to support the pss padding algorithm as described
+	  in the rfc8017 (https://tools.ietf.org/html/rfc8017).
+
 config FIT_VERBOSE
 	bool "Show verbose messages when FIT images fail"
 	help
diff --git a/MAINTAINERS b/MAINTAINERS
index abdb6dc..8ea8ef9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2,6 +2,8 @@
 
 	P: Person (obsolete)
 	M: Mail patches to: FullName <address@domain>
+	R: Designated reviewer: FullName <address@domain>
+	   These reviewers should be CCed on patches.
 	L: Mailing list that is relevant to this area
 	W: Web-page with status/info
 	Q: Patchwork web based patch tracking system site
@@ -158,6 +160,26 @@
 F:	arch/arm/cpu/pxa/
 F:	arch/arm/include/asm/arch-pxa/
 
+ARM MEDIATEK
+M:	Ryder Lee <ryder.lee@mediatek.com>
+M:	Weijie Gao <weijie.gao@mediatek.com>
+S:	Maintained
+F:	arch/arm/mach-mediatek/
+F:	arch/arm/include/asm/arch-mediatek/
+F:	board/mediatek/
+F:	doc/README.mediatek
+F:	drivers/clk/mediatek/
+F:	drivers/mmc/mtk-sd.c
+F:	drivers/pinctrl/mediatek/
+F:	drivers/power/domain/mtk-power-domain.c
+F:	drivers/ram/mediatek/
+F:	drivers/spi/mtk_qspi.c
+F:	drivers/timer/mtk_timer.c
+F:	drivers/watchdog/mtk_wdt.c
+F:	tools/mtk_image.c
+F:	tools/mtk_image.h
+N:	mediatek
+
 ARM OWL
 M:	Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
 S:	Maintained
@@ -394,6 +416,7 @@
 
 EFI PAYLOAD
 M:	Alexander Graf <agraf@suse.de>
+R:	Heinrich Schuchardt <xypron.glpk@gmx.de>
 S:	Maintained
 T:	git git://github.com/agraf/u-boot.git
 F:	doc/README.uefi
diff --git a/Makefile b/Makefile
index 552687d..0d11ff9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0+
 
-VERSION = 2018
-PATCHLEVEL = 11
+VERSION = 2019
+PATCHLEVEL = 01
 SUBLEVEL =
-EXTRAVERSION =
+EXTRAVERSION = -rc1
 NAME =
 
 # *DOCUMENTATION*
@@ -443,7 +443,7 @@
 
 no-dot-config-targets := clean clobber mrproper distclean \
 			 help %docs check% coccicheck \
-			 ubootversion backup tests
+			 ubootversion backup tests check qcheck
 
 config-targets := 0
 mixed-targets  := 0
@@ -852,6 +852,8 @@
 ALL-$(CONFIG_OF_SEPARATE) += u-boot-dtb-tegra.bin
 endif
 
+ALL-$(CONFIG_ARCH_MEDIATEK) += u-boot-mtk.bin
+
 # Add optional build target if defined in board/cpu/soc headers
 ifneq ($(CONFIG_BUILD_TARGET),)
 ALL-y += $(CONFIG_BUILD_TARGET:"%"=%)
@@ -918,6 +920,34 @@
 	@echo "before sending patches to the mailing list."
 	@echo "===================================================="
 endif
+ifeq ($(CONFIG_MMC),y)
+ifneq ($(CONFIG_DM_MMC)$(CONFIG_OF_CONTROL)$(CONFIG_BLK),yyy)
+	@echo "===================== WARNING ======================"
+	@echo "This board does not use CONFIG_DM_MMC. Please update"
+	@echo "the board to use CONFIG_DM_MMC before the v2019.04 release."
+	@echo "Failure to update by the deadline may result in board removal."
+	@echo "See doc/driver-model/MIGRATION.txt for more info."
+	@echo "===================================================="
+endif
+endif
+ifeq ($(CONFIG_USB),y)
+ifneq ($(CONFIG_DM_USB)$(CONFIG_OF_CONTROL)$(CONFIG_BLK),yyy)
+	@echo "===================== WARNING ======================"
+	@echo "This board does not use CONFIG_DM_USB. Please update"
+	@echo "the board to use CONFIG_DM_USB before the v2019.07 release."
+	@echo "Failure to update by the deadline may result in board removal."
+	@echo "See doc/driver-model/MIGRATION.txt for more info."
+	@echo "===================================================="
+endif
+endif
+ifeq ($(CONFIG_LIBATA)$(CONFIG_DM_SCSI)$(CONFIG_MVSATA_IDE),y)
+	@echo "===================== WARNING ======================"
+	@echo "This board does not use CONFIG_DM_SCSI. Please update"
+	@echo "the storage controller to use CONFIG_DM_SCSI before the v2019.07 release."
+	@echo "Failure to update by the deadline may result in board removal."
+	@echo "See doc/driver-model/MIGRATION.txt for more info."
+	@echo "===================================================="
+endif
 	@# Check that this build does not use CONFIG options that we do not
 	@# know about unless they are in Kconfig. All the existing CONFIG
 	@# options are whitelisted, so new ones should not be added.
@@ -1048,9 +1078,11 @@
 
 # binman
 # ---------------------------------------------------------------------------
+# Use 'make BINMAN_DEBUG=1' to enable debugging
 quiet_cmd_binman = BINMAN  $@
-cmd_binman = $(srctree)/tools/binman/binman -d u-boot.dtb -O . \
-		-I . -I $(srctree)/board/$(BOARDDIR) $<
+cmd_binman = $(srctree)/tools/binman/binman -u -d u-boot.dtb -O . -m \
+		-I . -I $(srctree) -I $(srctree)/board/$(BOARDDIR) \
+		$(if $(BINMAN_DEBUG),-D) $(BINMAN_$(@F)) $<
 
 OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex
 
@@ -1359,6 +1391,26 @@
 	$(Q)$(OBJCOPY) -I binary $(PLATFORM_ELFFLAGS) $< u-boot-elf.o
 	$(call if_changed,u-boot-elf)
 
+# MediaTek's ARM-based u-boot needs a header to contains its load address
+# which is parsed by the BootROM.
+# If the SPL build is enabled, the header will be added to the spl binary,
+# and the spl binary and the u-boot.img will be combined into one file.
+# Otherwise the header will be added to the u-boot.bin directly.
+
+ifeq ($(CONFIG_SPL),y)
+spl/u-boot-spl-mtk.bin: spl/u-boot-spl
+
+u-boot-mtk.bin: u-boot.dtb u-boot.img spl/u-boot-spl-mtk.bin FORCE
+	$(call if_changed,binman)
+else
+MKIMAGEFLAGS_u-boot-mtk.bin = -T mtk_image \
+	-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) \
+	-n "$(patsubst "%",%,$(CONFIG_MTK_BROM_HEADER_INFO))"
+
+u-boot-mtk.bin: u-boot.bin FORCE
+	$(call if_changed,mkimage)
+endif
+
 ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(ARCH)/Makefile.postlink)
 
 # Rule to link u-boot
@@ -1703,6 +1755,7 @@
 	@echo  'Test targets:'
 	@echo  ''
 	@echo  '  check           - Run all automated tests that use sandbox'
+	@echo  '  qcheck          - Run quick automated tests that use sandbox'
 	@echo  ''
 	@echo  'Other generic targets:'
 	@echo  '  all		  - Build all necessary images depending on configuration'
@@ -1745,6 +1798,9 @@
 tests check:
 	$(srctree)/test/run
 
+qcheck:
+	$(srctree)/test/run quick
+
 # Documentation targets
 # ---------------------------------------------------------------------------
 DOC_TARGETS := xmldocs latexdocs pdfdocs htmldocs epubdocs cleandocs \
diff --git a/arch/Kconfig b/arch/Kconfig
index 9fdd2f7..947070f 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -91,6 +91,7 @@
 	select SPI
 	select SUPPORT_OF_CONTROL
 	imply BITREVERSE
+	select BLOBLIST
 	imply CMD_DM
 	imply CMD_GETTIME
 	imply CMD_HASH
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index 9920d2e..fff6591 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -16,6 +16,20 @@
  * access: "lr"/"sr".
  */
 
+/*
+ * Typically 8 least significant bits of Build Configuration Register (BCR)
+ * describe version of the HW block in question. Moreover if decoded version
+ * is 0 this means given HW block is absent - this is especially useful because
+ * we may safely read BRC regardless HW block existence while an attempt to
+ * access any other AUX regs associated with this HW block lead to imediate
+ * "instruction error" exception.
+ *
+ * I.e. before using any cofigurable HW block it's required to make sure it
+ * exists at all, and for that we introduce a special macro below.
+ */
+#define ARC_BCR_VERSION_MASK	GENMASK(7, 0)
+#define ARC_FEATURE_EXISTS(bcr)	!!(__builtin_arc_lr(bcr) & ARC_BCR_VERSION_MASK)
+
 #define ARC_AUX_IDENTITY	0x04
 #define ARC_AUX_STATUS32	0x0a
 
@@ -73,7 +87,7 @@
 #define ARC_BCR_CLUSTER		0xcf
 
 /* MMU Management regs */
-#define ARC_AUX_MMU_BCR		0x06f
+#define ARC_AUX_MMU_BCR		0x6f
 
 /* IO coherency related auxiliary registers */
 #define ARC_AUX_IO_COH_ENABLE	0x500
@@ -81,6 +95,15 @@
 #define ARC_AUX_IO_COH_AP0_BASE	0x508
 #define ARC_AUX_IO_COH_AP0_SIZE	0x509
 
+/* XY-memory related */
+#define ARC_AUX_XY_BUILD	0x79
+
+/* DSP-extensions related auxiliary registers */
+#define ARC_AUX_DSP_BUILD	0x7A
+
+/* ARC Subsystems related auxiliary registers */
+#define ARC_AUX_SUBSYS_BUILD	0xF0
+
 #ifndef __ASSEMBLY__
 /* Accessors for auxiliary registers */
 #define read_aux_reg(reg)	__builtin_arc_lr(reg)
diff --git a/arch/arc/lib/cpu.c b/arch/arc/lib/cpu.c
index a969a16..07daaa8 100644
--- a/arch/arc/lib/cpu.c
+++ b/arch/arc/lib/cpu.c
@@ -4,6 +4,7 @@
  */
 
 #include <common.h>
+#include <malloc.h>
 #include <asm/arcregs.h>
 #include <asm/cache.h>
 
@@ -35,34 +36,193 @@
 }
 
 #ifdef CONFIG_DISPLAY_CPUINFO
-const char *decode_identity(void)
+const char *arc_700_version(int arcver, char *name, int name_len)
 {
-	int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff;
+	const char *arc_ver;
+
+	switch (arcver) {
+	case 0x32:
+		arc_ver = "v4.4-4.5";
+		break;
+	case 0x33:
+		arc_ver = "v4.6-v4.9";
+		break;
+	case 0x34:
+		arc_ver = "v4.10";
+		break;
+	case 0x35:
+		arc_ver = "v4.11";
+		break;
+	default:
+		arc_ver = "unknown version";
+	}
+
+	snprintf(name, name_len, "ARC 700 %s", arc_ver);
+
+	return name;
+}
+
+struct em_template_t {
+	const bool cache;
+	const bool dsp;
+	const bool xymem;
+	const char name[8];
+};
+
+static const struct em_template_t em_versions[] = {
+	{false,	false,	false,	"EM4"},
+	{true,	false,	false,	"EM6"},
+	{false,	true,	false,	"EM5D"},
+	{true,	true,	false,	"EM7D"},
+	{false,	true,	true,	"EM9D"},
+	{true,	true,	true,	"EM11D"},
+};
+
+const char *arc_em_version(int arcver, char *name, int name_len)
+{
+	const char *arc_name = "EM";
+	const char *arc_ver;
+	bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD);
+	bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD);
+	bool xymem = ARC_FEATURE_EXISTS(ARC_AUX_XY_BUILD);
+	int i;
+
+	for (i = 0; i++ < sizeof(em_versions) / sizeof(struct em_template_t);) {
+		if (em_versions[i].cache == cache &&
+		    em_versions[i].dsp == dsp &&
+		    em_versions[i].xymem == xymem) {
+			arc_name = em_versions[i].name;
+			break;
+		}
+	}
 
 	switch (arcver) {
-	/* ARCompact cores */
-	case 0x32: return "ARC 700 v4.4-4.5";
-	case 0x33: return "ARC 700 v4.6-v4.9";
-	case 0x34: return "ARC 700 v4.10";
-	case 0x35: return "ARC 700 v4.11";
+	case 0x41:
+		arc_ver = "v1.1a";
+		break;
+	case 0x42:
+		arc_ver = "v3.0";
+		break;
+	case 0x43:
+		arc_ver = "v4.0";
+		break;
+	case 0x44:
+		arc_ver = "v5.0";
+		break;
+	default:
+		arc_ver = "unknown version";
+	}
+
+	snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver);
+
+	return name;
+}
+
+struct hs_template_t {
+	const bool cache;
+	const bool mmu;
+	const bool dual_issue;
+	const bool dsp;
+	const char name[8];
+};
+
+static const struct hs_template_t hs_versions[] = {
+	{false,	false,	false,	false,	"HS34"},
+	{true,	false,	false,	false,	"HS36"},
+	{true,	true,	false,	false,	"HS38"},
+	{false,	false,	true,	false,	"HS44"},
+	{true,	false,	true,	false,	"HS46"},
+	{true,	true,	true,	false,	"HS48"},
+	{false,	false,	true,	true,	"HS45D"},
+	{true,	false,	true,	true,	"HS47D"},
+};
 
-	/* ARCv2 cores */
-	case 0x41: return "ARC EM v1.1a";
-	case 0x42: return "ARC EM v3.0";
-	case 0x43: return "ARC EM v4.0";
-	case 0x50: return "ARC HS v1.0";
-	case 0x51: return "ARC EM v2.0";
-	case 0x52: return "ARC EM v2.1";
-	case 0x53: return "ARC HS v3.0";
-	case 0x54: return "ARC HS v4.0";
+const char *arc_hs_version(int arcver, char *name, int name_len)
+{
+	const char *arc_name = "HS";
+	const char *arc_ver;
+	bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD);
+	bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD);
+	bool mmu = !!read_aux_reg(ARC_AUX_MMU_BCR);
+	bool dual_issue = arcver == 0x54 ? true : false;
+	int i;
 
-	default: return "Unknown ARC core";
+	for (i = 0; i++ < sizeof(hs_versions) / sizeof(struct hs_template_t);) {
+		if (hs_versions[i].cache == cache &&
+		    hs_versions[i].mmu == mmu &&
+		    hs_versions[i].dual_issue == dual_issue &&
+		    hs_versions[i].dsp == dsp) {
+			arc_name = hs_versions[i].name;
+			break;
+		}
 	}
+
+	switch (arcver) {
+	case 0x50:
+		arc_ver = "v1.0";
+		break;
+	case 0x51:
+		arc_ver = "v2.0";
+		break;
+	case 0x52:
+		arc_ver = "v2.1c";
+		break;
+	case 0x53:
+		arc_ver = "v3.0";
+		break;
+	case 0x54:
+		arc_ver = "v4.0";
+		break;
+	default:
+		arc_ver = "unknown version";
+	}
+
+	snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver);
+
+	return name;
+}
+
+const char *decode_identity(void)
+{
+#define MAX_CPU_NAME_LEN	64
+
+	int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff;
+	char *name = malloc(MAX_CPU_NAME_LEN);
+
+	if (arcver >= 0x50)
+		return arc_hs_version(arcver, name, MAX_CPU_NAME_LEN);
+	else if (arcver >= 0x40)
+		return arc_em_version(arcver, name, MAX_CPU_NAME_LEN);
+	else if (arcver >= 0x30)
+		return arc_700_version(arcver, name, MAX_CPU_NAME_LEN);
+	else
+		return "Unknown ARC core";
+}
+
+const char *decode_subsystem(void)
+{
+	int subsys_type = read_aux_reg(ARC_AUX_SUBSYS_BUILD) & GENMASK(3, 0);
+
+	switch (subsys_type) {
+	case 0: return NULL;
+	case 2: return "ARC Sensor & Control IP Subsystem";
+	case 3: return "ARC Data Fusion IP Subsystem";
+	case 4: return "ARC Secure Subsystem";
+	default: return "Unknown subsystem";
+	};
 }
 
 __weak int print_cpuinfo(void)
 {
-	printf("CPU:   %s\n", decode_identity());
+	const char *subsys_name = decode_subsystem();
+	char mhz[8];
+
+	printf("CPU:   %s at %s MHz\n", decode_identity(),
+	       strmhz(mhz, gd->cpu_clk));
+
+	if (subsys_name)
+		printf("Subsys:%s\n", subsys_name);
+
 	return 0;
 }
 #endif /* CONFIG_DISPLAY_CPUINFO */
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f5d4d39..13ba774 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -664,6 +664,20 @@
 	  targeted at media players and tablet computers. We currently
 	  support the S905 (GXBaby) 64-bit SoC.
 
+config ARCH_MEDIATEK
+	bool "MediaTek SoCs"
+	select BINMAN
+	select DM
+	select OF_CONTROL
+	select SPL_DM if SPL
+	select SPL_LIBCOMMON_SUPPORT if SPL
+	select SPL_LIBGENERIC_SUPPORT if SPL
+	select SPL_OF_CONTROL if SPL
+	select SUPPORT_SPL
+	help
+	  Support for the MediaTek SoCs family developed by MediaTek Inc.
+	  Please refer to doc/README.mediatek for more information.
+
 config ARCH_LPC32XX
 	bool "NXP LPC32xx platform"
 	select CPU_ARM926EJS
@@ -770,6 +784,7 @@
 	imply CMD_DM
 	imply FAT_WRITE
 	imply SYS_THUMB_BUILD
+	imply ARCH_MISC_INIT if DISPLAY_CPUINFO
 
 config TARGET_S32V234EVB
 	bool "Support s32v234evb"
@@ -928,6 +943,7 @@
 	select OF_CONTROL
 	select SPL_BOARD_INIT if SPL
 	select SPL_CLK if SPL
+	select SPL_SEPARATE_BSS if SPL
 	select SUPPORT_SPL
 	imply BOARD_LATE_INIT
 	imply CMD_DM
@@ -1449,6 +1465,8 @@
 
 source "arch/arm/mach-meson/Kconfig"
 
+source "arch/arm/mach-mediatek/Kconfig"
+
 source "arch/arm/mach-qemu/Kconfig"
 
 source "arch/arm/mach-rockchip/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 4b6c5e1..c38ef3c 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -62,6 +62,7 @@
 machine-$(CONFIG_ARCH_KEYSTONE)		+= keystone
 # TODO: rename CONFIG_KIRKWOOD -> CONFIG_ARCH_KIRKWOOD
 machine-$(CONFIG_KIRKWOOD)		+= kirkwood
+machine-$(CONFIG_ARCH_MEDIATEK)		+= mediatek
 machine-$(CONFIG_ARCH_MESON)		+= meson
 machine-$(CONFIG_ARCH_MVEBU)		+= mvebu
 # TODO: rename CONFIG_TEGRA -> CONFIG_ARCH_TEGRA
diff --git a/arch/arm/cpu/armv7/smccc-call.S b/arch/arm/cpu/armv7/smccc-call.S
index 0d8b59e..eae69e3 100644
--- a/arch/arm/cpu/armv7/smccc-call.S
+++ b/arch/arm/cpu/armv7/smccc-call.S
@@ -7,6 +7,8 @@
 #include <asm/opcodes-sec.h>
 #include <asm/opcodes-virt.h>
 
+	.section	.text.efi_runtime
+
 #define UNWIND(x...)
 	/*
 	 * Wrap c macros in asm macros to delay expansion until after the
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index 81edec0..0cb6dd3 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -205,6 +205,15 @@
 	mov	r2, r3, lsl #4		@ shift variant field for combined value
 	orr	r2, r4, r2		@ r2 has combined CPU variant + revision
 
+/* Early stack for ERRATA that needs into call C code */
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
+	ldr	r0, =(CONFIG_SPL_STACK)
+#else
+	ldr	r0, =(CONFIG_SYS_INIT_SP_ADDR)
+#endif
+	bic	r0, r0, #7	/* 8-byte alignment for ABI compliance */
+	mov	sp, r0
+
 #ifdef CONFIG_ARM_ERRATA_798870
 	cmp	r2, #0x30		@ Applies to lower than R3p0
 	bge	skip_errata_798870      @ skip if not affected rev
diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig
index ff42791..1c12bbd 100644
--- a/arch/arm/cpu/armv8/Kconfig
+++ b/arch/arm/cpu/armv8/Kconfig
@@ -96,6 +96,7 @@
 config PSCI_RESET
 	bool "Use PSCI for reset and shutdown"
 	default y
+	select ARM_SMCCC if OF_CONTROL
 	depends on !ARCH_EXYNOS7 && !ARCH_BCM283X && \
 		   !TARGET_LS2080A_SIMU && !TARGET_LS2080AQDS && \
 		   !TARGET_LS2080ARDB && !TARGET_LS2080A_EMU && \
diff --git a/arch/arm/cpu/armv8/fwcall.c b/arch/arm/cpu/armv8/fwcall.c
index 0ba3dad..9957c29 100644
--- a/arch/arm/cpu/armv8/fwcall.c
+++ b/arch/arm/cpu/armv8/fwcall.c
@@ -7,7 +7,6 @@
 
 #include <asm-offsets.h>
 #include <config.h>
-#include <efi_loader.h>
 #include <version.h>
 #include <asm/macro.h>
 #include <asm/psci.h>
@@ -19,7 +18,7 @@
  * x0~x7: input arguments
  * x0~x3: output arguments
  */
-static void __efi_runtime hvc_call(struct pt_regs *args)
+static void hvc_call(struct pt_regs *args)
 {
 	asm volatile(
 		"ldr x0, %0\n"
@@ -53,7 +52,7 @@
  * x0~x3: output arguments
  */
 
-void __efi_runtime smc_call(struct pt_regs *args)
+void smc_call(struct pt_regs *args)
 {
 	asm volatile(
 		"ldr x0, %0\n"
@@ -83,9 +82,9 @@
  * use PSCI on U-Boot running below a hypervisor, please detect
  * this and set the flag accordingly.
  */
-static const __efi_runtime_data bool use_smc_for_psci = true;
+static const bool use_smc_for_psci = true;
 
-void __noreturn __efi_runtime psci_system_reset(void)
+void __noreturn psci_system_reset(void)
 {
 	struct pt_regs regs;
 
@@ -100,7 +99,7 @@
 		;
 }
 
-void __noreturn __efi_runtime psci_system_off(void)
+void __noreturn psci_system_off(void)
 {
 	struct pt_regs regs;
 
@@ -114,44 +113,3 @@
 	while (1)
 		;
 }
-
-#ifdef CONFIG_CMD_POWEROFF
-int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-	puts("poweroff ...\n");
-
-	udelay(50000); /* wait 50 ms */
-
-	disable_interrupts();
-
-	psci_system_off();
-
-	/*NOTREACHED*/
-	return 0;
-}
-#endif
-
-#ifdef CONFIG_PSCI_RESET
-void reset_misc(void)
-{
-	psci_system_reset();
-}
-
-#ifdef CONFIG_EFI_LOADER
-void __efi_runtime EFIAPI efi_reset_system(
-			enum efi_reset_type reset_type,
-			efi_status_t reset_status,
-			unsigned long data_size, void *reset_data)
-{
-	if (reset_type == EFI_RESET_COLD ||
-	    reset_type == EFI_RESET_WARM ||
-	    reset_type == EFI_RESET_PLATFORM_SPECIFIC) {
-		psci_system_reset();
-	} else if (reset_type == EFI_RESET_SHUTDOWN) {
-		psci_system_off();
-	}
-
-	while (1) { }
-}
-#endif /* CONFIG_EFI_LOADER */
-#endif /* CONFIG_PSCI_RESET */
diff --git a/arch/arm/cpu/armv8/smccc-call.S b/arch/arm/cpu/armv8/smccc-call.S
index 16c9e29..86de4b4 100644
--- a/arch/arm/cpu/armv8/smccc-call.S
+++ b/arch/arm/cpu/armv8/smccc-call.S
@@ -6,6 +6,8 @@
 #include <linux/arm-smccc.h>
 #include <generated/asm-offsets.h>
 
+	.section	.text.efi_runtime
+
 	.macro SMCCC instr
 	.cfi_startproc
 	\instr	#0
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 84b7e53..c5960d3 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -59,7 +59,8 @@
 	meson-gxl-s905x-p212.dtb \
 	meson-gxl-s905x-libretech-cc.dtb \
 	meson-gxl-s905x-khadas-vim.dtb \
-	meson-gxm-khadas-vim2.dtb
+	meson-gxm-khadas-vim2.dtb \
+	meson-axg-s400.dtb
 dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
 	tegra20-medcom-wide.dtb \
 	tegra20-paz00.dtb \
@@ -156,6 +157,7 @@
 	zynq-zybo-z7.dtb
 dtb-$(CONFIG_ARCH_ZYNQMP) += \
 	avnet-ultra96-rev1.dtb			\
+	zynqmp-mini.dtb				\
 	zynqmp-mini-emmc0.dtb			\
 	zynqmp-mini-emmc1.dtb			\
 	zynqmp-mini-nand.dtb			\
@@ -187,7 +189,8 @@
 	am335x-icev2.dtb \
 	am335x-pxm50.dtb \
 	am335x-rut.dtb \
-	am335x-pdu001.dtb
+	am335x-pdu001.dtb \
+	am335x-chiliboard.dtb
 dtb-$(CONFIG_AM43XX) += am437x-gp-evm.dtb am437x-sk-evm.dtb	\
 	am43x-epos-evm.dtb \
 	am437x-idk-evm.dtb \
@@ -562,6 +565,10 @@
 
 dtb-$(CONFIG_SOC_K3_AM6) += k3-am654-base-board.dtb k3-am654-r5-base-board.dtb
 
+dtb-$(CONFIG_ARCH_MEDIATEK) += \
+	mt7623n-bananapi-bpi-r2.dtb \
+	mt7629-rfb.dtb
+
 targets += $(dtb-y)
 
 # Add any required device tree compiler flags here
diff --git a/arch/arm/dts/am335x-baltos.dts b/arch/arm/dts/am335x-baltos.dts
new file mode 100644
index 0000000..f939cf6
--- /dev/null
+++ b/arch/arm/dts/am335x-baltos.dts
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * VScom OnRISC
+ * http://www.vscom.de
+ */
+
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+	model = "OnRISC Baltos";
+	compatible = "vscom,onrisc", "ti,am33xx";
+
+	chosen {
+		stdout-path = &uart0;
+	};
+
+	cpus {
+		cpu@0 {
+			cpu0-supply = <&vdd1_reg>;
+		};
+	};
+
+	vbat: fixedregulator@0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vbat";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-boot-on;
+	};
+};
+
+&am33xx_pinmux {
+	mmc1_pins: pinmux_mmc1_pins {
+		pinctrl-single,pins = <
+			0xf0 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_dat3.mmc0_dat3 */
+			0xf4 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_dat2.mmc0_dat2 */
+			0xf8 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_dat1.mmc0_dat1 */
+			0xfc (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_dat0.mmc0_dat0 */
+			0x100 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_clk.mmc0_clk */
+			0x104 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_cmd.mmc0_cmd */
+		>;
+	};
+
+	i2c1_pins: pinmux_i2c1_pins {
+		pinctrl-single,pins = <
+			0x158 0x2a      /* spi0_d1.i2c1_sda_mux3, INPUT | MODE2 */
+			0x15c 0x2a      /* spi0_cs0.i2c1_scl_mux3, INPUT | MODE2 */
+		>;
+	};
+
+	tps65910_pins: pinmux_tps65910_pins {
+		pinctrl-single,pins = <
+			0x078 (PIN_INPUT_PULLUP | MUX_MODE7)      /* gpmc_ben1.gpio1[28] */
+		>;
+
+	};
+	tca6416_pins: pinmux_tca6416_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x9b4, PIN_INPUT_PULLUP | MUX_MODE7)      /* xdma_event_intr1.gpio0[20] tca6416 stuff */
+		>;
+	};
+
+	uart0_pins: pinmux_uart0_pins {
+		pinctrl-single,pins = <
+			0x170 (PIN_INPUT_PULLUP | MUX_MODE0)	/* uart0_rxd.uart0_rxd */
+			0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)		/* uart0_txd.uart0_txd */
+		>;
+	};
+
+	cpsw_default: cpsw_default {
+		pinctrl-single,pins = <
+			/* Slave 1 */
+			0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1)       /* mii1_crs.rmii1_crs_dv */
+			0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE1)      /* mii1_tx_en.rmii1_txen */
+			0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE1)      /* mii1_txd1.rmii1_txd1 */
+			0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE1)      /* mii1_txd0.rmii1_txd0 */
+			0x13c (PIN_INPUT_PULLDOWN | MUX_MODE1)      /* mii1_rxd1.rmii1_rxd1 */
+			0x140 (PIN_INPUT_PULLDOWN | MUX_MODE1)      /* mii1_rxd0.rmii1_rxd0 */
+			0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0)      /* rmii1_ref_clk.rmii1_refclk */
+
+
+			/* Slave 2 */
+			0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a0.rgmii2_tctl */
+			0x44 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a1.rgmii2_rctl */
+			0x48 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a2.rgmii2_td3 */
+			0x4c (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a3.rgmii2_td2 */
+			0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a4.rgmii2_td1 */
+			0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a5.rgmii2_td0 */
+			0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a6.rgmii2_tclk */
+			0x5c (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a7.rgmii2_rclk */
+			0x60 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a8.rgmii2_rd3 */
+			0x64 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a9.rgmii2_rd2 */
+			0x68 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a10.rgmii2_rd1 */
+			0x6c (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a11.rgmii2_rd0 */
+		>;
+	};
+
+	cpsw_sleep: cpsw_sleep {
+		pinctrl-single,pins = <
+			/* Slave 1 reset value */
+			0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+
+			/* Slave 2 reset value*/
+			0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x44 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x48 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x4c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x58 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x5c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x60 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+		>;
+	};
+
+	davinci_mdio_default: davinci_mdio_default {
+		pinctrl-single,pins = <
+			/* MDIO */
+			0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)	/* mdio_data.mdio_data */
+			0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)			/* mdio_clk.mdio_clk */
+		>;
+	};
+
+	davinci_mdio_sleep: davinci_mdio_sleep {
+		pinctrl-single,pins = <
+			/* MDIO reset value */
+			0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+		>;
+	};
+
+	nandflash_pins_s0: nandflash_pins_s0 {
+		pinctrl-single,pins = <
+			0x0 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad0.gpmc_ad0 */
+			0x4 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad1.gpmc_ad1 */
+			0x8 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad2.gpmc_ad2 */
+			0xc (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad3.gpmc_ad3 */
+			0x10 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad4.gpmc_ad4 */
+			0x14 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad5.gpmc_ad5 */
+			0x18 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad6.gpmc_ad6 */
+			0x1c (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad7.gpmc_ad7 */
+			0x70 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_wait0.gpmc_wait0 */
+			0x74 (PIN_INPUT_PULLUP | MUX_MODE7)	/* gpmc_wpn.gpio0_30 */
+			0x7c (PIN_OUTPUT | MUX_MODE0)		/* gpmc_csn0.gpmc_csn0  */
+			0x90 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_advn_ale.gpmc_advn_ale */
+			0x94 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_oen_ren.gpmc_oen_ren */
+			0x98 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_wen.gpmc_wen */
+			0x9c (PIN_OUTPUT | MUX_MODE0)		/* gpmc_be0n_cle.gpmc_be0n_cle */
+		>;
+	};
+};
+
+&elm {
+	status = "okay";
+};
+
+&gpmc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&nandflash_pins_s0>;
+	ranges = <0 0 0x08000000 0x10000000>;	/* CS0: NAND */
+	status = "okay";
+
+	nand@0,0 {
+		reg = <0 0 0>; /* CS0, offset 0 */
+		nand-bus-width = <8>;
+		ti,nand-ecc-opt = "bch8";
+		ti,nand-xfer-type = "polled";
+
+		gpmc,device-nand = "true";
+		gpmc,device-width = <1>;
+		gpmc,sync-clk-ps = <0>;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <44>;
+		gpmc,cs-wr-off-ns = <44>;
+		gpmc,adv-on-ns = <6>;
+		gpmc,adv-rd-off-ns = <34>;
+		gpmc,adv-wr-off-ns = <44>;
+		gpmc,we-on-ns = <0>;
+		gpmc,we-off-ns = <40>;
+		gpmc,oe-on-ns = <0>;
+		gpmc,oe-off-ns = <54>;
+		gpmc,access-ns = <64>;
+		gpmc,rd-cycle-ns = <82>;
+		gpmc,wr-cycle-ns = <82>;
+		gpmc,wait-on-read = "true";
+		gpmc,wait-on-write = "true";
+		gpmc,bus-turnaround-ns = <0>;
+		gpmc,cycle2cycle-delay-ns = <0>;
+		gpmc,clk-activation-ns = <0>;
+		gpmc,wait-monitoring-ns = <0>;
+		gpmc,wr-access-ns = <40>;
+		gpmc,wr-data-mux-bus-ns = <0>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+		elm_id = <&elm>;
+
+		boot@0 {
+		       label = "SPL";
+		       reg = <0x0 0x20000>;
+		};
+		boot@20000{
+		       label = "SPL.backup1";
+		       reg = <0x20000 0x20000>;
+		};
+		boot@40000 {
+		       label = "SPL.backup2";
+		       reg = <0x40000 0x20000>;
+		};
+		boot@60000 {
+		       label = "SPL.backup3";
+		       reg = <0x60000 0x20000>;
+		};
+		boot@80000 {
+		       label = "u-boot";
+		       reg = <0x80000 0x1e0000>;
+		};
+		boot@260000 {
+		       label = "UBI";
+		       reg = <0x260000 0xfda0000>;
+		};
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins>;
+
+	status = "okay";
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins>;
+
+	status = "okay";
+	clock-frequency = <1000>;
+
+	tps: tps@2d {
+		reg = <0x2d>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <28 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&tps65910_pins>;
+	};
+
+	at24@50 {
+		compatible = "at24,24c02";
+		pagesize = <8>;
+		reg = <0x50>;
+	};
+
+	tca6416: gpio@20 {
+		compatible = "ti,tca6416";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <20 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&tca6416_pins>;
+	};
+};
+
+&usb {
+	status = "okay";
+};
+
+&usb_ctrl_mod {
+	status = "okay";
+};
+
+&usb0_phy {
+	status = "okay";
+};
+
+&usb1_phy {
+	status = "okay";
+};
+
+&usb0 {
+	status = "okay";
+	dr_mode = "host";
+};
+
+&usb1 {
+	status = "okay";
+	dr_mode = "host";
+};
+
+&cppi41dma  {
+	status = "okay";
+};
+
+/include/ "tps65910.dtsi"
+
+&tps {
+	vcc1-supply = <&vbat>;
+	vcc2-supply = <&vbat>;
+	vcc3-supply = <&vbat>;
+	vcc4-supply = <&vbat>;
+	vcc5-supply = <&vbat>;
+	vcc6-supply = <&vbat>;
+	vcc7-supply = <&vbat>;
+	vccio-supply = <&vbat>;
+
+	ti,en-ck32k-xtal = <1>;
+
+	regulators {
+		vrtc_reg: regulator@0 {
+			regulator-always-on;
+		};
+
+		vio_reg: regulator@1 {
+			regulator-always-on;
+		};
+
+		vdd1_reg: regulator@2 {
+			/* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
+			regulator-name = "vdd_mpu";
+			regulator-min-microvolt = <912500>;
+			regulator-max-microvolt = <1312500>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		vdd2_reg: regulator@3 {
+			/* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
+			regulator-name = "vdd_core";
+			regulator-min-microvolt = <912500>;
+			regulator-max-microvolt = <1150000>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		vdd3_reg: regulator@4 {
+			regulator-always-on;
+		};
+
+		vdig1_reg: regulator@5 {
+			regulator-always-on;
+		};
+
+		vdig2_reg: regulator@6 {
+			regulator-always-on;
+		};
+
+		vpll_reg: regulator@7 {
+			regulator-always-on;
+		};
+
+		vdac_reg: regulator@8 {
+			regulator-always-on;
+		};
+
+		vaux1_reg: regulator@9 {
+			regulator-always-on;
+		};
+
+		vaux2_reg: regulator@10 {
+			regulator-always-on;
+		};
+
+		vaux33_reg: regulator@11 {
+			regulator-always-on;
+		};
+
+		vmmc_reg: regulator@12 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+		};
+	};
+};
+
+&mac {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&cpsw_default>;
+	pinctrl-1 = <&cpsw_sleep>;
+	dual_emac = <1>;
+
+	status = "okay";
+};
+
+&davinci_mdio {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&davinci_mdio_default>;
+	pinctrl-1 = <&davinci_mdio_sleep>;
+
+	status = "okay";
+};
+
+&cpsw_emac0 {
+	phy_id = <&davinci_mdio>, <0>;
+	phy-mode = "rmii";
+	dual_emac_res_vlan = <1>;
+};
+
+&cpsw_emac1 {
+	phy_id = <&davinci_mdio>, <7>;
+	phy-mode = "rgmii-txid";
+	dual_emac_res_vlan = <2>;
+};
+
+&phy_sel {
+	rmii-clock-ext = <1>;
+};
+
+&mmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc1_pins>;
+	vmmc-supply = <&vmmc_reg>;
+	status = "okay";
+};
+
+&gpio0 {
+	ti,no-reset-on-init;
+};
diff --git a/arch/arm/dts/am335x-chiliboard-u-boot.dtsi b/arch/arm/dts/am335x-chiliboard-u-boot.dtsi
new file mode 100644
index 0000000..4f9d308
--- /dev/null
+++ b/arch/arm/dts/am335x-chiliboard-u-boot.dtsi
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0+ or X11
+/*
+ * Copyright (C) 2018 Grinn Sp. z o.o. -- http://www.grinn-global.com/
+ * Author: Marcin Niestroj <m.niestroj@grinn-global.com>
+ */
+
+/ {
+	chosen {
+		stdout-path = &uart0;
+	};
+};
diff --git a/arch/arm/dts/am335x-chiliboard.dts b/arch/arm/dts/am335x-chiliboard.dts
new file mode 100644
index 0000000..59431b2
--- /dev/null
+++ b/arch/arm/dts/am335x-chiliboard.dts
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2015 Jablotron s.r.o. -- http://www.jablotron.com/
+ * Author: Rostislav Lisovy <lisovy@jablotron.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "am335x-chilisom.dtsi"
+
+/ {
+	model = "AM335x Chiliboard";
+	compatible = "grinn,am335x-chiliboard", "grinn,am335x-chilisom",
+		     "ti,am33xx";
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_gpio_pins>;
+
+		led0 {
+			label = "led0";
+			gpios = <&gpio3 7 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+			linux,default-trigger = "heartbeat";
+		};
+
+		led1 {
+			label = "led1";
+			gpios = <&gpio3 8 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+		};
+	};
+};
+
+&am33xx_pinmux {
+	uart0_pins: pinmux_uart0_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)	/* uart0_rxd.uart0_rxd */
+			AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* uart0_txd.uart0_txd */
+		>;
+	};
+
+	cpsw_default: cpsw_default {
+		pinctrl-single,pins = <
+			/* Slave 1 */
+			AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_crs.rmii1_crs */
+			AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE1)	/* mii1_rxerr.rmii1_rxerr */
+			AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE1)	/* mii1_txen.rmii1_txen */
+			AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE1)	/* mii1_txd1.rmii1_txd1 */
+			AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE1)	/* mii1_txd0.rmii1_txd0 */
+			AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE1)	/* mii1_rxd1.rmii1_rxd1 */
+			AM33XX_IOPAD(0x940, PIN_INPUT_PULLUP | MUX_MODE1)	/* mii1_rxd0.rmii1_rxd0 */
+			AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* rmii1_ref_clk.rmii_ref_clk */
+		>;
+	};
+
+	cpsw_sleep: cpsw_sleep {
+		pinctrl-single,pins = <
+			/* Slave 1 reset value */
+			AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
+		>;
+	};
+
+	davinci_mdio_default: davinci_mdio_default {
+		pinctrl-single,pins = <
+			/* mdio_data.mdio_data */
+			AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)
+			/* mdio_clk.mdio_clk */
+			AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)
+		>;
+	};
+
+	davinci_mdio_sleep: davinci_mdio_sleep {
+		pinctrl-single,pins = <
+			/* MDIO reset value */
+			AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+		>;
+	};
+
+	usb1_drvvbus: usb1_drvvbus {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0xa34, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* usb1_drvvbus.usb1_drvvbus */
+		>;
+	};
+
+	sd_pins: pinmux_sd_card {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x8f0, PIN_INPUT | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+			AM33XX_IOPAD(0x8f4, PIN_INPUT | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+			AM33XX_IOPAD(0x8f8, PIN_INPUT | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+			AM33XX_IOPAD(0x8fc, PIN_INPUT | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+			AM33XX_IOPAD(0x900, PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+			AM33XX_IOPAD(0x904, PIN_INPUT | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+			AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+		>;
+	};
+
+	led_gpio_pins: led_gpio_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x9e4, PIN_OUTPUT | MUX_MODE7) /* emu0.gpio3_7 */
+			AM33XX_IOPAD(0x9e8, PIN_OUTPUT | MUX_MODE7) /* emu1.gpio3_8 */
+		>;
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins>;
+
+	status = "okay";
+};
+
+&ldo4_reg {
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+};
+
+/* Ethernet */
+&mac {
+	slaves = <1>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&cpsw_default>;
+	pinctrl-1 = <&cpsw_sleep>;
+	status = "okay";
+};
+
+&davinci_mdio {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&davinci_mdio_default>;
+	pinctrl-1 = <&davinci_mdio_sleep>;
+	status = "okay";
+};
+
+&cpsw_emac0 {
+	phy_id = <&davinci_mdio>, <0>;
+	phy-mode = "rmii";
+};
+
+&phy_sel {
+	rmii-clock-ext;
+};
+
+/* USB */
+&usb {
+	status = "okay";
+};
+
+&usb_ctrl_mod {
+	status = "okay";
+};
+
+&usb1_phy {
+	status = "okay";
+};
+
+&usb1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb1_drvvbus>;
+
+	status = "okay";
+	dr_mode = "host";
+};
+
+&cppi41dma  {
+	status = "okay";
+};
+
+/* microSD */
+&mmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sd_pins>;
+	vmmc-supply = <&ldo4_reg>;
+	bus-width = <0x4>;
+	cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&tps {
+	interrupt-parent = <&intc>;
+	interrupts = <7>; /* NNMI */
+
+	charger {
+		status = "okay";
+	};
+
+	pwrbutton {
+		status = "okay";
+	};
+};
diff --git a/arch/arm/dts/am335x-chilisom.dtsi b/arch/arm/dts/am335x-chilisom.dtsi
new file mode 100644
index 0000000..1b43ebd
--- /dev/null
+++ b/arch/arm/dts/am335x-chilisom.dtsi
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2015 Jablotron s.r.o. -- http://www.jablotron.com/
+ * Author: Rostislav Lisovy <lisovy@jablotron.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include "am33xx.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	model = "Grinn AM335x ChiliSOM";
+	compatible = "grinn,am335x-chilisom", "ti,am33xx";
+
+	cpus {
+		cpu@0 {
+			cpu0-supply = <&dcdc2_reg>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>; /* 512 MB */
+	};
+};
+
+&am33xx_pinmux {
+	pinctrl-names = "default";
+
+	i2c0_pins: pinmux_i2c0_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c0_sda.i2c0_sda */
+			AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c0_scl.i2c0_scl */
+		>;
+	};
+
+	nandflash_pins: nandflash_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x800, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* gpmc_ad0.gpmc_ad0 */
+			AM33XX_IOPAD(0x804, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* gpmc_ad1.gpmc_ad1 */
+			AM33XX_IOPAD(0x808, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* gpmc_ad2.gpmc_ad2 */
+			AM33XX_IOPAD(0x80c, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* gpmc_ad3.gpmc_ad3 */
+			AM33XX_IOPAD(0x810, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* gpmc_ad4.gpmc_ad4 */
+			AM33XX_IOPAD(0x814, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* gpmc_ad5.gpmc_ad5 */
+			AM33XX_IOPAD(0x818, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* gpmc_ad6.gpmc_ad6 */
+			AM33XX_IOPAD(0x81c, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* gpmc_ad7.gpmc_ad7 */
+
+			AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_wait0.gpmc_wait0 */
+			AM33XX_IOPAD(0x87c, PIN_OUTPUT_PULLUP | MUX_MODE0)	/* gpmc_csn0.gpmc_csn0 */
+			AM33XX_IOPAD(0x890, PIN_OUTPUT_PULLUP | MUX_MODE0)	/* gpmc_advn_ale.gpmc_advn_ale */
+			AM33XX_IOPAD(0x894, PIN_OUTPUT_PULLUP | MUX_MODE0)	/* gpmc_oen_ren.gpmc_oen_ren */
+			AM33XX_IOPAD(0x898, PIN_OUTPUT_PULLUP | MUX_MODE0)	/* gpmc_wen.gpmc_wen */
+			AM33XX_IOPAD(0x89c, PIN_OUTPUT_PULLUP | MUX_MODE0)	/* gpmc_be0n_cle.gpmc_be0n_cle */
+		>;
+	};
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins>;
+
+	status = "okay";
+	clock-frequency = <400000>;
+
+	tps: tps@24 {
+		reg = <0x24>;
+	};
+
+};
+
+/include/ "tps65217.dtsi"
+
+&tps {
+	regulators {
+		dcdc1_reg: regulator@0 {
+			regulator-name = "vdds_dpr";
+			regulator-always-on;
+		};
+
+		dcdc2_reg: regulator@1 {
+			/* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
+			regulator-name = "vdd_mpu";
+			regulator-min-microvolt = <925000>;
+			regulator-max-microvolt = <1325000>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		dcdc3_reg: regulator@2 {
+			/* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
+			regulator-name = "vdd_core";
+			regulator-min-microvolt = <925000>;
+			regulator-max-microvolt = <1150000>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		ldo1_reg: regulator@3 {
+			regulator-name = "vio,vrtc,vdds";
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		ldo2_reg: regulator@4 {
+			regulator-name = "vdd_3v3aux";
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		ldo3_reg: regulator@5 {
+			regulator-name = "vdd_1v8";
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		ldo4_reg: regulator@6 {
+			regulator-name = "vdd_3v3d";
+			regulator-boot-on;
+			regulator-always-on;
+		};
+	};
+};
+
+&rtc {
+	system-power-controller;
+
+	pinctrl-0 = <&ext_wakeup>;
+	pinctrl-names = "default";
+
+	ext_wakeup: ext-wakeup {
+		pins = "ext_wakeup0";
+		input-enable;
+	};
+};
+
+/* NAND Flash */
+&elm {
+	status = "okay";
+};
+
+&gpmc {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&nandflash_pins>;
+	ranges = <0 0 0x08000000 0x01000000>; /* CS0 0 @addr 0x08000000, size 0x01000000 */
+	nand@0,0 {
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
+		rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
+		ti,nand-ecc-opt = "bch8";
+		ti,elm-id = <&elm>;
+		nand-bus-width = <8>;
+		gpmc,device-width = <1>;
+		gpmc,sync-clk-ps = <0>;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <44>;
+		gpmc,cs-wr-off-ns = <44>;
+		gpmc,adv-on-ns = <6>;
+		gpmc,adv-rd-off-ns = <34>;
+		gpmc,adv-wr-off-ns = <44>;
+		gpmc,we-on-ns = <0>;
+		gpmc,we-off-ns = <40>;
+		gpmc,oe-on-ns = <0>;
+		gpmc,oe-off-ns = <54>;
+		gpmc,access-ns = <64>;
+		gpmc,rd-cycle-ns = <82>;
+		gpmc,wr-cycle-ns = <82>;
+		gpmc,bus-turnaround-ns = <0>;
+		gpmc,cycle2cycle-delay-ns = <0>;
+		gpmc,clk-activation-ns = <0>;
+		gpmc,wr-access-ns = <40>;
+		gpmc,wr-data-mux-bus-ns = <0>;
+	};
+};
diff --git a/arch/arm/dts/armada-8040-mcbin.dts b/arch/arm/dts/armada-8040-mcbin.dts
index f912596..7e8e2f7 100644
--- a/arch/arm/dts/armada-8040-mcbin.dts
+++ b/arch/arm/dts/armada-8040-mcbin.dts
@@ -154,6 +154,12 @@
 	status = "okay";
 };
 
+&cpm_mdio {
+	ge_phy: ethernet-phy@0 {
+		reg = <0>;
+	};
+};
+
 &cpm_comphy {
 	/*
 	 * CP0 Serdes Configuration:
@@ -195,6 +201,16 @@
 
 &cps_utmi0 {
 	status = "okay";
+};
+
+&cps_ethernet {
+	status = "okay";
+};
+
+&cps_eth1 {
+	status = "okay";
+	phy = <&ge_phy>;
+	phy-mode = "sgmii";
 };
 
 &cps_pinctl {
diff --git a/arch/arm/dts/keystone-k2g.dtsi b/arch/arm/dts/keystone-k2g.dtsi
index 9bcfea6..bbbb987 100644
--- a/arch/arm/dts/keystone-k2g.dtsi
+++ b/arch/arm/dts/keystone-k2g.dtsi
@@ -85,7 +85,7 @@
 		};
 
 		qspi: qspi@2940000 {
-			compatible =  "cadence,qspi";
+			compatible =  "cdns,qspi-nor";
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0x02940000 0x1000>,
diff --git a/arch/arm/dts/meson-axg-s400.dts b/arch/arm/dts/meson-axg-s400.dts
new file mode 100644
index 0000000..18778ad
--- /dev/null
+++ b/arch/arm/dts/meson-axg-s400.dts
@@ -0,0 +1,554 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 Amlogic, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "meson-axg.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "amlogic,s400", "amlogic,a113d", "amlogic,meson-axg";
+	model = "Amlogic Meson AXG S400 Development Board";
+
+	adc_keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 0>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+
+		button-next {
+			label = "Next";
+			linux,code = <KEY_NEXT>;
+			press-threshold-microvolt = <1116000>; /* 62% */
+		};
+
+		button-prev {
+			label = "Previous";
+			linux,code = <KEY_PREVIOUS>;
+			press-threshold-microvolt = <900000>; /* 50% */
+		};
+
+		button-wifi {
+			label = "Wifi";
+			linux,code = <KEY_WLAN>;
+			press-threshold-microvolt = <684000>; /* 38% */
+		};
+
+		button-up {
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+			press-threshold-microvolt = <468000>; /* 26% */
+		};
+
+		button-down {
+			label = "Volume Down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			press-threshold-microvolt = <252000>; /* 14% */
+		};
+
+		button-voice {
+			label = "Voice";
+			linux,code = <KEY_VOICECOMMAND>;
+			press-threshold-microvolt = <0>; /* 0% */
+		};
+	};
+
+	aliases {
+		serial0 = &uart_AO;
+		serial1 = &uart_A;
+	};
+
+	linein: audio-codec@0 {
+		#sound-dai-cells = <0>;
+		compatible = "everest,es7241";
+		VDDA-supply = <&vcc_3v3>;
+		VDDP-supply = <&vcc_3v3>;
+		VDDD-supply = <&vcc_3v3>;
+		status = "okay";
+		sound-name-prefix = "Linein";
+	};
+
+	lineout: audio-codec@1 {
+		#sound-dai-cells = <0>;
+		compatible = "everest,es7154";
+		VDD-supply = <&vcc_3v3>;
+		PVDD-supply = <&vcc_5v>;
+		status = "okay";
+		sound-name-prefix = "Lineout";
+	};
+
+	spdif_dit: audio-codec@2 {
+		#sound-dai-cells = <0>;
+		compatible = "linux,spdif-dit";
+		status = "okay";
+		sound-name-prefix = "DIT";
+	};
+
+	dmics: audio-codec@3 {
+		#sound-dai-cells = <0>;
+		compatible = "dmic-codec";
+		num-channels = <7>;
+		wakeup-delay-ms = <50>;
+		status = "okay";
+		sound-name-prefix = "MIC";
+	};
+
+	emmc_pwrseq: emmc-pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x40000000>;
+	};
+
+	main_12v: regulator-main_12v {
+		compatible = "regulator-fixed";
+		regulator-name = "12V";
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		regulator-always-on;
+	};
+
+	vcc_3v3: regulator-vcc_3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vddao_3v3>;
+		regulator-always-on;
+	};
+
+	vcc_5v: regulator-vcc_5v {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC5V";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&main_12v>;
+
+		gpio = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	vddao_3v3: regulator-vddao_3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDAO_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&main_12v>;
+		regulator-always-on;
+	};
+
+	vddio_ao18: regulator-vddio_ao18 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDIO_AO18";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vddao_3v3>;
+		regulator-always-on;
+	};
+
+	vddio_boot: regulator-vddio_boot {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDIO_BOOT";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vddao_3v3>;
+		regulator-always-on;
+	};
+
+	usb_pwr: regulator-usb_pwr {
+		compatible = "regulator-fixed";
+		regulator-name = "USB_PWR";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc_5v>;
+
+		gpio = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpio GPIOX_7 GPIO_ACTIVE_LOW>;
+		clocks = <&wifi32k>;
+		clock-names = "ext_clock";
+	};
+
+	speaker-leds {
+		compatible = "gpio-leds";
+
+		aled1 {
+			label = "speaker:aled1";
+			gpios = <&gpio_speaker 7 0>;
+		};
+
+		aled2 {
+			label = "speaker:aled2";
+			gpios = <&gpio_speaker 6 0>;
+		};
+
+		aled3 {
+			label = "speaker:aled3";
+			gpios = <&gpio_speaker 5 0>;
+		};
+
+		aled4 {
+			label = "speaker:aled4";
+			gpios = <&gpio_speaker 4 0>;
+		};
+
+		aled5 {
+			label = "speaker:aled5";
+			gpios = <&gpio_speaker 3 0>;
+		};
+
+		aled6 {
+			label = "speaker:aled6";
+			gpios = <&gpio_speaker 2 0>;
+		};
+	};
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "AXG-S400";
+		audio-aux-devs = <&tdmin_a>, <&tdmin_b>,  <&tdmin_c>,
+				 <&tdmin_lb>, <&tdmout_c>;
+		audio-widgets = "Line", "Lineout",
+				"Line", "Linein",
+				"Speaker", "Speaker1 Left",
+				"Speaker", "Speaker1 Right";
+		audio-routing = "TDMOUT_C IN 0", "FRDDR_A OUT 2",
+				"SPDIFOUT IN 0", "FRDDR_A OUT 3",
+				"TDMOUT_C IN 1", "FRDDR_B OUT 2",
+				"SPDIFOUT IN 1", "FRDDR_B OUT 3",
+				"TDMOUT_C IN 2", "FRDDR_C OUT 2",
+				"SPDIFOUT IN 2", "FRDDR_C OUT 3",
+				"TDM_C Playback", "TDMOUT_C OUT",
+				"TDMIN_A IN 2", "TDM_C Capture",
+				"TDMIN_A IN 5", "TDM_C Loopback",
+				"TDMIN_B IN 2", "TDM_C Capture",
+				"TDMIN_B IN 5", "TDM_C Loopback",
+				"TDMIN_C IN 2", "TDM_C Capture",
+				"TDMIN_C IN 5", "TDM_C Loopback",
+				"TDMIN_LB IN 2", "TDM_C Loopback",
+				"TDMIN_LB IN 5", "TDM_C Capture",
+				"TODDR_A IN 0", "TDMIN_A OUT",
+				"TODDR_B IN 0", "TDMIN_A OUT",
+				"TODDR_C IN 0", "TDMIN_A OUT",
+				"TODDR_A IN 1", "TDMIN_B OUT",
+				"TODDR_B IN 1", "TDMIN_B OUT",
+				"TODDR_C IN 1", "TDMIN_B OUT",
+				"TODDR_A IN 2", "TDMIN_C OUT",
+				"TODDR_B IN 2", "TDMIN_C OUT",
+				"TODDR_C IN 2", "TDMIN_C OUT",
+				"TODDR_A IN 4", "PDM Capture",
+				"TODDR_B IN 4", "PDM Capture",
+				"TODDR_C IN 4", "PDM Capture",
+				"TODDR_A IN 6", "TDMIN_LB OUT",
+				"TODDR_B IN 6", "TDMIN_LB OUT",
+				"TODDR_C IN 6", "TDMIN_LB OUT",
+				"Lineout", "Lineout AOUTL",
+				"Lineout", "Lineout AOUTR",
+				"Speaker1 Left", "SPK1 OUT_A",
+				"Speaker1 Left", "SPK1 OUT_B",
+				"Speaker1 Right", "SPK1 OUT_C",
+				"Speaker1 Right", "SPK1 OUT_D",
+				"Linein AINL", "Linein",
+				"Linein AINR", "Linein";
+		assigned-clocks = <&clkc CLKID_HIFI_PLL>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <589824000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link@0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link@1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link@2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		dai-link@3 {
+			sound-dai = <&toddr_a>;
+		};
+
+		dai-link@4 {
+			sound-dai = <&toddr_b>;
+		};
+
+		dai-link@5 {
+			sound-dai = <&toddr_c>;
+		};
+
+		dai-link@6 {
+			sound-dai = <&tdmif_c>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-rx-mask-1 = <1 1>;
+			mclk-fs = <256>;
+
+			codec@0 {
+				sound-dai = <&lineout>;
+			};
+
+			codec@1 {
+				sound-dai = <&speaker_amp1>;
+			};
+
+			codec@2 {
+				sound-dai = <&linein>;
+			};
+
+		};
+
+		dai-link@7 {
+			sound-dai = <&spdifout>;
+
+			codec {
+				sound-dai = <&spdif_dit>;
+			};
+		};
+
+		dai-link@8 {
+			sound-dai = <&pdm>;
+
+			codec {
+				sound-dai = <&dmics>;
+			};
+		};
+	};
+
+	wifi32k: wifi32k {
+		compatible = "pwm-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		pwms = <&pwm_ab 0 30518 0>; /* PWM_A at 32.768KHz */
+	};
+};
+
+&ethmac {
+	status = "okay";
+	pinctrl-0 = <&eth_rgmii_y_pins>;
+	pinctrl-names = "default";
+	phy-handle = <&eth_phy0>;
+	phy-mode = "rgmii";
+
+	mdio {
+		compatible = "snps,dwmac-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		eth_phy0: ethernet-phy@0 {
+			/* Realtek RTL8211F (0x001cc916) */
+			reg = <0>;
+			eee-broken-1000t;
+		};
+	};
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&ir {
+	status = "okay";
+	pinctrl-0 = <&remote_input_ao_pins>;
+	pinctrl-names = "default";
+};
+
+&i2c1 {
+	status = "okay";
+	pinctrl-0 = <&i2c1_z_pins>;
+	pinctrl-names = "default";
+
+	speaker_amp1: audio-codec@1b {
+		compatible = "ti,tas5707";
+		reg = <0x1b>;
+		reset-gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_LOW>;
+		#sound-dai-cells = <0>;
+		AVDD-supply = <&vcc_3v3>;
+		DVDD-supply = <&vcc_3v3>;
+		PVDD_A-supply = <&main_12v>;
+		PVDD_B-supply = <&main_12v>;
+		PVDD_C-supply = <&main_12v>;
+		PVDD_D-supply = <&main_12v>;
+		sound-name-prefix = "SPK1";
+	};
+};
+
+&i2c_AO {
+	status = "okay";
+	pinctrl-0 = <&i2c_ao_sck_10_pins>, <&i2c_ao_sda_11_pins>;
+	pinctrl-names = "default";
+
+	gpio_speaker: gpio-controller@1f {
+		compatible = "nxp,pca9557";
+		reg = <0x1f>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		vcc-supply = <&vddao_3v3>;
+	};
+};
+
+&pdm {
+	pinctrl-0 = <&pdm_dclk_a14_pins>, <&pdm_din0_pins>,
+		    <&pdm_din1_pins>, <&pdm_din2_pins>, <&pdm_din3_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&pwm_ab {
+	status = "okay";
+	pinctrl-0 = <&pwm_a_x20_pins>;
+	pinctrl-names = "default";
+};
+
+&saradc {
+	status = "okay";
+	vref-supply = <&vddio_ao18>;
+};
+
+/* wifi module */
+&sd_emmc_b {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	pinctrl-0 = <&sdio_pins>;
+	pinctrl-1 = <&sdio_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	max-frequency = <100000000>;
+	non-removable;
+	disable-wp;
+
+	mmc-pwrseq = <&sdio_pwrseq>;
+
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddio_boot>;
+
+	brcmf: wifi@1 {
+		reg = <1>;
+		compatible = "brcm,bcm4329-fmac";
+	};
+};
+
+/* emmc storage */
+&sd_emmc_c {
+	status = "disabled";
+	pinctrl-0 = <&emmc_pins>;
+	pinctrl-1 = <&emmc_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+
+	bus-width = <8>;
+	cap-sd-highspeed;
+	cap-mmc-highspeed;
+	max-frequency = <180000000>;
+	non-removable;
+	disable-wp;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+
+	mmc-pwrseq = <&emmc_pwrseq>;
+
+	vmmc-supply = <&vcc_3v3>;
+	vqmmc-supply = <&vddio_boot>;
+};
+
+&spdifout {
+	pinctrl-0 = <&spdif_out_a20_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&tdmif_a {
+	pinctrl-0 = <&tdma_sclk_pins>, <&tdma_fs_pins>,
+		    <&tdma_din0_pins>, <&tdma_dout0_x15_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&tdmif_b {
+	pinctrl-0 = <&tdmb_sclk_pins>, <&tdmb_fs_pins>,
+		    <&tdmb_din3_pins>, <&mclk_b_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&tdmif_c {
+	pinctrl-0 = <&tdmc_sclk_pins>, <&tdmc_fs_pins>,
+		    <&tdmc_din1_pins>, <&tdmc_dout2_pins>,
+		    <&mclk_c_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&tdmin_a {
+	status = "okay";
+};
+
+&tdmin_b {
+	status = "okay";
+};
+
+&tdmin_c {
+	status = "okay";
+};
+
+&tdmin_lb {
+	status = "okay";
+};
+
+&tdmout_c {
+	status = "okay";
+};
+
+&toddr_a {
+	status = "okay";
+};
+
+&toddr_b {
+	status = "okay";
+};
+
+&toddr_c {
+	status = "okay";
+};
+
+&uart_A {
+	status = "okay";
+	pinctrl-0 = <&uart_a_pins>;
+	pinctrl-names = "default";
+};
+
+&uart_AO {
+	status = "okay";
+	pinctrl-0 = <&uart_ao_a_pins>;
+	pinctrl-names = "default";
+};
diff --git a/arch/arm/dts/meson-axg.dtsi b/arch/arm/dts/meson-axg.dtsi
new file mode 100644
index 0000000..df017db
--- /dev/null
+++ b/arch/arm/dts/meson-axg.dtsi
@@ -0,0 +1,1589 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 Amlogic, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/clock/axg-aoclkc.h>
+#include <dt-bindings/clock/axg-audio-clkc.h>
+#include <dt-bindings/clock/axg-clkc.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/gpio/meson-axg-gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset/amlogic,meson-axg-audio-arb.h>
+#include <dt-bindings/reset/amlogic,meson-axg-reset.h>
+
+/ {
+	compatible = "amlogic,meson-axg";
+
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	tdmif_a: audio-controller@0 {
+		compatible = "amlogic,axg-tdm-iface";
+		#sound-dai-cells = <0>;
+		sound-name-prefix = "TDM_A";
+		clocks = <&clkc_audio AUD_CLKID_MST_A_MCLK>,
+			 <&clkc_audio AUD_CLKID_MST_A_SCLK>,
+			 <&clkc_audio AUD_CLKID_MST_A_LRCLK>;
+		clock-names = "mclk", "sclk", "lrclk";
+		status = "disabled";
+	};
+
+	tdmif_b: audio-controller@1 {
+		compatible = "amlogic,axg-tdm-iface";
+		#sound-dai-cells = <0>;
+		sound-name-prefix = "TDM_B";
+		clocks = <&clkc_audio AUD_CLKID_MST_B_MCLK>,
+			 <&clkc_audio AUD_CLKID_MST_B_SCLK>,
+			 <&clkc_audio AUD_CLKID_MST_B_LRCLK>;
+		clock-names = "mclk", "sclk", "lrclk";
+		status = "disabled";
+	};
+
+	tdmif_c: audio-controller@2 {
+		compatible = "amlogic,axg-tdm-iface";
+		#sound-dai-cells = <0>;
+		sound-name-prefix = "TDM_C";
+		clocks = <&clkc_audio AUD_CLKID_MST_C_MCLK>,
+			 <&clkc_audio AUD_CLKID_MST_C_SCLK>,
+			 <&clkc_audio AUD_CLKID_MST_C_LRCLK>;
+		clock-names = "mclk", "sclk", "lrclk";
+		status = "disabled";
+	};
+
+	ao_alt_xtal: ao_alt_xtal-clk {
+		compatible = "fixed-clock";
+		clock-frequency = <32000000>;
+		clock-output-names = "ao_alt_xtal";
+		#clock-cells = <0>;
+	};
+
+	arm-pmu {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+	};
+
+	cpus {
+		#address-cells = <0x2>;
+		#size-cells = <0x0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			next-level-cache = <&l2>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			next-level-cache = <&l2>;
+		};
+
+		cpu2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+			next-level-cache = <&l2>;
+		};
+
+		cpu3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+			next-level-cache = <&l2>;
+		};
+
+		l2: l2-cache0 {
+			compatible = "cache";
+		};
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* 16 MiB reserved for Hardware ROM Firmware */
+		hwrom_reserved: hwrom@0 {
+			reg = <0x0 0x0 0x0 0x1000000>;
+			no-map;
+		};
+
+		/* Alternate 3 MiB reserved for ARM Trusted Firmware (BL31) */
+		secmon_reserved: secmon@5000000 {
+			reg = <0x0 0x05000000 0x0 0x300000>;
+			no-map;
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		ethmac: ethernet@ff3f0000 {
+			compatible = "amlogic,meson-axg-dwmac", "snps,dwmac";
+			reg = <0x0 0xff3f0000 0x0 0x10000
+			       0x0 0xff634540 0x0 0x8>;
+			interrupts = <GIC_SPI 8 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "macirq";
+			clocks = <&clkc CLKID_ETH>,
+				 <&clkc CLKID_FCLK_DIV2>,
+				 <&clkc CLKID_MPLL2>;
+			clock-names = "stmmaceth", "clkin0", "clkin1";
+			status = "disabled";
+		};
+
+		pdm: audio-controller@ff632000 {
+			compatible = "amlogic,axg-pdm";
+			reg = <0x0 0xff632000 0x0 0x34>;
+			#sound-dai-cells = <0>;
+			sound-name-prefix = "PDM";
+			clocks = <&clkc_audio AUD_CLKID_PDM>,
+				 <&clkc_audio AUD_CLKID_PDM_DCLK>,
+				 <&clkc_audio AUD_CLKID_PDM_SYSCLK>;
+			clock-names = "pclk", "dclk", "sysclk";
+			status = "disabled";
+		};
+
+		periphs: bus@ff634000 {
+			compatible = "simple-bus";
+			reg = <0x0 0xff634000 0x0 0x2000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges = <0x0 0x0 0x0 0xff634000 0x0 0x2000>;
+
+			hwrng: rng@18 {
+				compatible = "amlogic,meson-rng";
+				reg = <0x0 0x18 0x0 0x4>;
+				clocks = <&clkc CLKID_RNG0>;
+				clock-names = "core";
+			};
+
+			pinctrl_periphs: pinctrl@480 {
+				compatible = "amlogic,meson-axg-periphs-pinctrl";
+				#address-cells = <2>;
+				#size-cells = <2>;
+				ranges;
+
+				gpio: bank@480 {
+					reg = <0x0 0x00480 0x0 0x40>,
+					      <0x0 0x004e8 0x0 0x14>,
+					      <0x0 0x00520 0x0 0x14>,
+					      <0x0 0x00430 0x0 0x3c>;
+					reg-names = "mux", "pull", "pull-enable", "gpio";
+					gpio-controller;
+					#gpio-cells = <2>;
+					gpio-ranges = <&pinctrl_periphs 0 0 86>;
+				};
+
+				i2c0_pins: i2c0 {
+					mux {
+						groups = "i2c0_sck",
+							 "i2c0_sda";
+						function = "i2c0";
+					};
+				};
+
+				i2c1_x_pins: i2c1_x {
+					mux {
+						groups = "i2c1_sck_x",
+							 "i2c1_sda_x";
+						function = "i2c1";
+					};
+				};
+
+				i2c1_z_pins: i2c1_z {
+					mux {
+						groups = "i2c1_sck_z",
+							 "i2c1_sda_z";
+						function = "i2c1";
+					};
+				};
+
+				i2c2_a_pins: i2c2_a {
+					mux {
+						groups = "i2c2_sck_a",
+							 "i2c2_sda_a";
+						function = "i2c2";
+					};
+				};
+
+				i2c2_x_pins: i2c2_x {
+					mux {
+						groups = "i2c2_sck_x",
+							 "i2c2_sda_x";
+						function = "i2c2";
+					};
+				};
+
+				i2c3_a6_pins: i2c3_a6 {
+					mux {
+						groups = "i2c3_sda_a6",
+							 "i2c3_sck_a7";
+						function = "i2c3";
+					};
+				};
+
+				i2c3_a12_pins: i2c3_a12 {
+					mux {
+						groups = "i2c3_sda_a12",
+							 "i2c3_sck_a13";
+						function = "i2c3";
+					};
+				};
+
+				i2c3_a19_pins: i2c3_a19 {
+					mux {
+						groups = "i2c3_sda_a19",
+							 "i2c3_sck_a20";
+						function = "i2c3";
+					};
+				};
+
+				emmc_pins: emmc {
+					mux {
+						groups = "emmc_nand_d0",
+							 "emmc_nand_d1",
+							 "emmc_nand_d2",
+							 "emmc_nand_d3",
+							 "emmc_nand_d4",
+							 "emmc_nand_d5",
+							 "emmc_nand_d6",
+							 "emmc_nand_d7",
+							 "emmc_clk",
+							 "emmc_cmd",
+							 "emmc_ds";
+						function = "emmc";
+					};
+				};
+
+				emmc_clk_gate_pins: emmc_clk_gate {
+					mux {
+						groups = "BOOT_8";
+						function = "gpio_periphs";
+					};
+					cfg-pull-down {
+						pins = "BOOT_8";
+						bias-pull-down;
+					};
+				};
+
+				eth_rgmii_x_pins: eth-x-rgmii {
+					mux {
+						groups = "eth_mdio_x",
+							 "eth_mdc_x",
+							 "eth_rgmii_rx_clk_x",
+							 "eth_rx_dv_x",
+							 "eth_rxd0_x",
+							 "eth_rxd1_x",
+							 "eth_rxd2_rgmii",
+							 "eth_rxd3_rgmii",
+							 "eth_rgmii_tx_clk",
+							 "eth_txen_x",
+							 "eth_txd0_x",
+							 "eth_txd1_x",
+							 "eth_txd2_rgmii",
+							 "eth_txd3_rgmii";
+						function = "eth";
+					};
+				};
+
+				eth_rgmii_y_pins: eth-y-rgmii {
+					mux {
+						groups = "eth_mdio_y",
+							 "eth_mdc_y",
+							 "eth_rgmii_rx_clk_y",
+							 "eth_rx_dv_y",
+							 "eth_rxd0_y",
+							 "eth_rxd1_y",
+							 "eth_rxd2_rgmii",
+							 "eth_rxd3_rgmii",
+							 "eth_rgmii_tx_clk",
+							 "eth_txen_y",
+							 "eth_txd0_y",
+							 "eth_txd1_y",
+							 "eth_txd2_rgmii",
+							 "eth_txd3_rgmii";
+						function = "eth";
+					};
+				};
+
+				eth_rmii_x_pins: eth-x-rmii {
+					mux {
+						groups = "eth_mdio_x",
+							 "eth_mdc_x",
+							 "eth_rgmii_rx_clk_x",
+							 "eth_rx_dv_x",
+							 "eth_rxd0_x",
+							 "eth_rxd1_x",
+							 "eth_txen_x",
+							 "eth_txd0_x",
+							 "eth_txd1_x";
+						function = "eth";
+					};
+				};
+
+				eth_rmii_y_pins: eth-y-rmii {
+					mux {
+						groups = "eth_mdio_y",
+							 "eth_mdc_y",
+							 "eth_rgmii_rx_clk_y",
+							 "eth_rx_dv_y",
+							 "eth_rxd0_y",
+							 "eth_rxd1_y",
+							 "eth_txen_y",
+							 "eth_txd0_y",
+							 "eth_txd1_y";
+						function = "eth";
+					};
+				};
+
+				mclk_b_pins: mclk_b {
+					mux {
+						groups = "mclk_b";
+						function = "mclk_b";
+					};
+				};
+
+				mclk_c_pins: mclk_c {
+					mux {
+						groups = "mclk_c";
+						function = "mclk_c";
+					};
+				};
+
+				pdm_dclk_a14_pins: pdm_dclk_a14 {
+					mux {
+						groups = "pdm_dclk_a14";
+						function = "pdm";
+					};
+				};
+
+				pdm_dclk_a19_pins: pdm_dclk_a19 {
+					mux {
+						groups = "pdm_dclk_a19";
+						function = "pdm";
+					};
+				};
+
+				pdm_din0_pins: pdm_din0 {
+					mux {
+						groups = "pdm_din0";
+						function = "pdm";
+					};
+				};
+
+				pdm_din1_pins: pdm_din1 {
+					mux {
+						groups = "pdm_din1";
+						function = "pdm";
+					};
+				};
+
+				pdm_din2_pins: pdm_din2 {
+					mux {
+						groups = "pdm_din2";
+						function = "pdm";
+					};
+				};
+
+				pdm_din3_pins: pdm_din3 {
+					mux {
+						groups = "pdm_din3";
+						function = "pdm";
+					};
+				};
+
+				pwm_a_a_pins: pwm_a_a {
+					mux {
+						groups = "pwm_a_a";
+						function = "pwm_a";
+					};
+				};
+
+				pwm_a_x18_pins: pwm_a_x18 {
+					mux {
+						groups = "pwm_a_x18";
+						function = "pwm_a";
+					};
+				};
+
+				pwm_a_x20_pins: pwm_a_x20 {
+					mux {
+						groups = "pwm_a_x20";
+						function = "pwm_a";
+					};
+				};
+
+				pwm_a_z_pins: pwm_a_z {
+					mux {
+						groups = "pwm_a_z";
+						function = "pwm_a";
+					};
+				};
+
+				pwm_b_a_pins: pwm_b_a {
+					mux {
+						groups = "pwm_b_a";
+						function = "pwm_b";
+					};
+				};
+
+				pwm_b_x_pins: pwm_b_x {
+					mux {
+						groups = "pwm_b_x";
+						function = "pwm_b";
+					};
+				};
+
+				pwm_b_z_pins: pwm_b_z {
+					mux {
+						groups = "pwm_b_z";
+						function = "pwm_b";
+					};
+				};
+
+				pwm_c_a_pins: pwm_c_a {
+					mux {
+						groups = "pwm_c_a";
+						function = "pwm_c";
+					};
+				};
+
+				pwm_c_x10_pins: pwm_c_x10 {
+					mux {
+						groups = "pwm_c_x10";
+						function = "pwm_c";
+					};
+				};
+
+				pwm_c_x17_pins: pwm_c_x17 {
+					mux {
+						groups = "pwm_c_x17";
+						function = "pwm_c";
+					};
+				};
+
+				pwm_d_x11_pins: pwm_d_x11 {
+					mux {
+						groups = "pwm_d_x11";
+						function = "pwm_d";
+					};
+				};
+
+				pwm_d_x16_pins: pwm_d_x16 {
+					mux {
+						groups = "pwm_d_x16";
+						function = "pwm_d";
+					};
+				};
+
+				sdio_pins: sdio {
+					mux {
+						groups = "sdio_d0",
+							 "sdio_d1",
+							 "sdio_d2",
+							 "sdio_d3",
+							 "sdio_cmd",
+							 "sdio_clk";
+						function = "sdio";
+					};
+				};
+
+				sdio_clk_gate_pins: sdio_clk_gate {
+					mux {
+						groups = "GPIOX_4";
+						function = "gpio_periphs";
+					};
+					cfg-pull-down {
+						pins = "GPIOX_4";
+						bias-pull-down;
+					};
+				};
+
+				spdif_in_z_pins: spdif_in_z {
+					mux {
+						groups = "spdif_in_z";
+						function = "spdif_in";
+					};
+				};
+
+				spdif_in_a1_pins: spdif_in_a1 {
+					mux {
+						groups = "spdif_in_a1";
+						function = "spdif_in";
+					};
+				};
+
+				spdif_in_a7_pins: spdif_in_a7 {
+					mux {
+						groups = "spdif_in_a7";
+						function = "spdif_in";
+					};
+				};
+
+				spdif_in_a19_pins: spdif_in_a19 {
+					mux {
+						groups = "spdif_in_a19";
+						function = "spdif_in";
+					};
+				};
+
+				spdif_in_a20_pins: spdif_in_a20 {
+					mux {
+						groups = "spdif_in_a20";
+						function = "spdif_in";
+					};
+				};
+
+				spdif_out_a1_pins: spdif_out_a1 {
+					mux {
+						groups = "spdif_out_a1";
+						function = "spdif_out";
+					};
+				};
+
+				spdif_out_a11_pins: spdif_out_a11 {
+					mux {
+						groups = "spdif_out_a11";
+						function = "spdif_out";
+					};
+				};
+
+				spdif_out_a19_pins: spdif_out_a19 {
+					mux {
+						groups = "spdif_out_a19";
+						function = "spdif_out";
+					};
+				};
+
+				spdif_out_a20_pins: spdif_out_a20 {
+					mux {
+						groups = "spdif_out_a20";
+						function = "spdif_out";
+					};
+				};
+
+				spdif_out_z_pins: spdif_out_z {
+					mux {
+						groups = "spdif_out_z";
+						function = "spdif_out";
+					};
+				};
+
+				spi0_pins: spi0 {
+					mux {
+						groups = "spi0_miso",
+							 "spi0_mosi",
+							 "spi0_clk";
+						function = "spi0";
+					};
+				};
+
+				spi0_ss0_pins: spi0_ss0 {
+					mux {
+						groups = "spi0_ss0";
+						function = "spi0";
+					};
+				};
+
+				spi0_ss1_pins: spi0_ss1 {
+					mux {
+						groups = "spi0_ss1";
+						function = "spi0";
+					};
+				};
+
+				spi0_ss2_pins: spi0_ss2 {
+					mux {
+						groups = "spi0_ss2";
+						function = "spi0";
+					};
+				};
+
+				spi1_a_pins: spi1_a {
+					mux {
+						groups = "spi1_miso_a",
+							 "spi1_mosi_a",
+							 "spi1_clk_a";
+						function = "spi1";
+					};
+				};
+
+				spi1_ss0_a_pins: spi1_ss0_a {
+					mux {
+						groups = "spi1_ss0_a";
+						function = "spi1";
+					};
+				};
+
+				spi1_ss1_pins: spi1_ss1 {
+					mux {
+						groups = "spi1_ss1";
+						function = "spi1";
+					};
+				};
+
+				spi1_x_pins: spi1_x {
+					mux {
+						groups = "spi1_miso_x",
+							 "spi1_mosi_x",
+							 "spi1_clk_x";
+						function = "spi1";
+					};
+				};
+
+				spi1_ss0_x_pins: spi1_ss0_x {
+					mux {
+						groups = "spi1_ss0_x";
+						function = "spi1";
+					};
+				};
+
+				tdma_din0_pins: tdma_din0 {
+					mux {
+						groups = "tdma_din0";
+						function = "tdma";
+					};
+				};
+
+				tdma_dout0_x14_pins: tdma_dout0_x14 {
+					mux {
+						groups = "tdma_dout0_x14";
+						function = "tdma";
+					};
+				};
+
+				tdma_dout0_x15_pins: tdma_dout0_x15 {
+					mux {
+						groups = "tdma_dout0_x15";
+						function = "tdma";
+					};
+				};
+
+				tdma_dout1_pins: tdma_dout1 {
+					mux {
+						groups = "tdma_dout1";
+						function = "tdma";
+					};
+				};
+
+				tdma_din1_pins: tdma_din1 {
+					mux {
+						groups = "tdma_din1";
+						function = "tdma";
+					};
+				};
+
+				tdma_fs_pins: tdma_fs {
+					mux {
+						groups = "tdma_fs";
+						function = "tdma";
+					};
+				};
+
+				tdma_fs_slv_pins: tdma_fs_slv {
+					mux {
+						groups = "tdma_fs_slv";
+						function = "tdma";
+					};
+				};
+
+				tdma_sclk_pins: tdma_sclk {
+					mux {
+						groups = "tdma_sclk";
+						function = "tdma";
+					};
+				};
+
+				tdma_sclk_slv_pins: tdma_sclk_slv {
+					mux {
+						groups = "tdma_sclk_slv";
+						function = "tdma";
+					};
+				};
+
+				tdmb_din0_pins: tdmb_din0 {
+					mux {
+						groups = "tdmb_din0";
+						function = "tdmb";
+					};
+				};
+
+				tdmb_din1_pins: tdmb_din1 {
+					mux {
+						groups = "tdmb_din1";
+						function = "tdmb";
+					};
+				};
+
+				tdmb_din2_pins: tdmb_din2 {
+					mux {
+						groups = "tdmb_din2";
+						function = "tdmb";
+					};
+				};
+
+				tdmb_din3_pins: tdmb_din3 {
+					mux {
+						groups = "tdmb_din3";
+						function = "tdmb";
+					};
+				};
+
+				tdmb_dout0_pins: tdmb_dout0 {
+					mux {
+						groups = "tdmb_dout0";
+						function = "tdmb";
+					};
+				};
+
+				tdmb_dout1_pins: tdmb_dout1 {
+					mux {
+						groups = "tdmb_dout1";
+						function = "tdmb";
+					};
+				};
+
+				tdmb_dout2_pins: tdmb_dout2 {
+					mux {
+						groups = "tdmb_dout2";
+						function = "tdmb";
+					};
+				};
+
+				tdmb_dout3_pins: tdmb_dout3 {
+					mux {
+						groups = "tdmb_dout3";
+						function = "tdmb";
+					};
+				};
+
+				tdmb_fs_pins: tdmb_fs {
+					mux {
+						groups = "tdmb_fs";
+						function = "tdmb";
+					};
+				};
+
+				tdmb_fs_slv_pins: tdmb_fs_slv {
+					mux {
+						groups = "tdmb_fs_slv";
+						function = "tdmb";
+					};
+				};
+
+				tdmb_sclk_pins: tdmb_sclk {
+					mux {
+						groups = "tdmb_sclk";
+						function = "tdmb";
+					};
+				};
+
+				tdmb_sclk_slv_pins: tdmb_sclk_slv {
+					mux {
+						groups = "tdmb_sclk_slv";
+						function = "tdmb";
+					};
+				};
+
+				tdmc_fs_pins: tdmc_fs {
+					mux {
+						groups = "tdmc_fs";
+						function = "tdmc";
+					};
+				};
+
+				tdmc_fs_slv_pins: tdmc_fs_slv {
+					mux {
+						groups = "tdmc_fs_slv";
+						function = "tdmc";
+					};
+				};
+
+				tdmc_sclk_pins: tdmc_sclk {
+					mux {
+						groups = "tdmc_sclk";
+						function = "tdmc";
+					};
+				};
+
+				tdmc_sclk_slv_pins: tdmc_sclk_slv {
+					mux {
+						groups = "tdmc_sclk_slv";
+						function = "tdmc";
+					};
+				};
+
+				tdmc_din0_pins: tdmc_din0 {
+					mux {
+						groups = "tdmc_din0";
+						function = "tdmc";
+					};
+				};
+
+				tdmc_din1_pins: tdmc_din1 {
+					mux {
+						groups = "tdmc_din1";
+						function = "tdmc";
+					};
+				};
+
+				tdmc_din2_pins: tdmc_din2 {
+					mux {
+						groups = "tdmc_din2";
+						function = "tdmc";
+					};
+				};
+
+				tdmc_din3_pins: tdmc_din3 {
+					mux {
+						groups = "tdmc_din3";
+						function = "tdmc";
+					};
+				};
+
+				tdmc_dout0_pins: tdmc_dout0 {
+					mux {
+						groups = "tdmc_dout0";
+						function = "tdmc";
+					};
+				};
+
+				tdmc_dout1_pins: tdmc_dout1 {
+					mux {
+						groups = "tdmc_dout1";
+						function = "tdmc";
+					};
+				};
+
+				tdmc_dout2_pins: tdmc_dout2 {
+					mux {
+						groups = "tdmc_dout2";
+						function = "tdmc";
+					};
+				};
+
+				tdmc_dout3_pins: tdmc_dout3 {
+					mux {
+						groups = "tdmc_dout3";
+						function = "tdmc";
+					};
+				};
+
+				uart_a_pins: uart_a {
+					mux {
+						groups = "uart_tx_a",
+							 "uart_rx_a";
+						function = "uart_a";
+					};
+				};
+
+				uart_a_cts_rts_pins: uart_a_cts_rts {
+					mux {
+						groups = "uart_cts_a",
+							 "uart_rts_a";
+						function = "uart_a";
+					};
+				};
+
+				uart_b_x_pins: uart_b_x {
+					mux {
+						groups = "uart_tx_b_x",
+							 "uart_rx_b_x";
+						function = "uart_b";
+					};
+				};
+
+				uart_b_x_cts_rts_pins: uart_b_x_cts_rts {
+					mux {
+						groups = "uart_cts_b_x",
+							 "uart_rts_b_x";
+						function = "uart_b";
+					};
+				};
+
+				uart_b_z_pins: uart_b_z {
+					mux {
+						groups = "uart_tx_b_z",
+							 "uart_rx_b_z";
+						function = "uart_b";
+					};
+				};
+
+				uart_b_z_cts_rts_pins: uart_b_z_cts_rts {
+					mux {
+						groups = "uart_cts_b_z",
+							 "uart_rts_b_z";
+						function = "uart_b";
+					};
+				};
+
+				uart_ao_b_z_pins: uart_ao_b_z {
+					mux {
+						groups = "uart_ao_tx_b_z",
+							 "uart_ao_rx_b_z";
+						function = "uart_ao_b_z";
+					};
+				};
+
+				uart_ao_b_z_cts_rts_pins: uart_ao_b_z_cts_rts {
+					mux {
+						groups = "uart_ao_cts_b_z",
+							 "uart_ao_rts_b_z";
+						function = "uart_ao_b_z";
+					};
+				};
+			};
+		};
+
+		hiubus: bus@ff63c000 {
+			compatible = "simple-bus";
+			reg = <0x0 0xff63c000 0x0 0x1c00>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges = <0x0 0x0 0x0 0xff63c000 0x0 0x1c00>;
+
+			sysctrl: system-controller@0 {
+				compatible = "amlogic,meson-axg-hhi-sysctrl",
+					     "simple-mfd", "syscon";
+				reg = <0 0 0 0x400>;
+
+				clkc: clock-controller {
+					compatible = "amlogic,axg-clkc";
+					#clock-cells = <1>;
+				};
+			};
+		};
+
+		mailbox: mailbox@ff63dc00 {
+			compatible = "amlogic,meson-gx-mhu", "amlogic,meson-gxbb-mhu";
+			reg = <0 0xff63dc00 0 0x400>;
+			interrupts = <GIC_SPI 208 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 209 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 210 IRQ_TYPE_EDGE_RISING>;
+			#mbox-cells = <1>;
+		};
+
+		audio: bus@ff642000 {
+			compatible = "simple-bus";
+			reg = <0x0 0xff642000 0x0 0x2000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges = <0x0 0x0 0x0 0xff642000 0x0 0x2000>;
+
+			clkc_audio: clock-controller@0 {
+				compatible = "amlogic,axg-audio-clkc";
+				reg = <0x0 0x0 0x0 0xb4>;
+				#clock-cells = <1>;
+
+				clocks = <&clkc CLKID_AUDIO>,
+					 <&clkc CLKID_MPLL0>,
+					 <&clkc CLKID_MPLL1>,
+					 <&clkc CLKID_MPLL2>,
+					 <&clkc CLKID_MPLL3>,
+					 <&clkc CLKID_HIFI_PLL>,
+					 <&clkc CLKID_FCLK_DIV3>,
+					 <&clkc CLKID_FCLK_DIV4>,
+					 <&clkc CLKID_GP0_PLL>;
+				clock-names = "pclk",
+					      "mst_in0",
+					      "mst_in1",
+					      "mst_in2",
+					      "mst_in3",
+					      "mst_in4",
+					      "mst_in5",
+					      "mst_in6",
+					      "mst_in7";
+
+				resets = <&reset RESET_AUDIO>;
+			};
+
+			toddr_a: audio-controller@100 {
+				compatible = "amlogic,axg-toddr";
+				reg = <0x0 0x100 0x0 0x1c>;
+				#sound-dai-cells = <0>;
+				sound-name-prefix = "TODDR_A";
+				interrupts = <GIC_SPI 84 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&clkc_audio AUD_CLKID_TODDR_A>;
+				resets = <&arb AXG_ARB_TODDR_A>;
+				status = "disabled";
+			};
+
+			toddr_b: audio-controller@140 {
+				compatible = "amlogic,axg-toddr";
+				reg = <0x0 0x140 0x0 0x1c>;
+				#sound-dai-cells = <0>;
+				sound-name-prefix = "TODDR_B";
+				interrupts = <GIC_SPI 85 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&clkc_audio AUD_CLKID_TODDR_B>;
+				resets = <&arb AXG_ARB_TODDR_B>;
+				status = "disabled";
+			};
+
+			toddr_c: audio-controller@180 {
+				compatible = "amlogic,axg-toddr";
+				reg = <0x0 0x180 0x0 0x1c>;
+				#sound-dai-cells = <0>;
+				sound-name-prefix = "TODDR_C";
+				interrupts = <GIC_SPI 86 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&clkc_audio AUD_CLKID_TODDR_C>;
+				resets = <&arb AXG_ARB_TODDR_C>;
+				status = "disabled";
+			};
+
+			frddr_a: audio-controller@1c0 {
+				compatible = "amlogic,axg-frddr";
+				reg = <0x0 0x1c0 0x0 0x1c>;
+				#sound-dai-cells = <0>;
+				sound-name-prefix = "FRDDR_A";
+				interrupts = <GIC_SPI 88 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
+				resets = <&arb AXG_ARB_FRDDR_A>;
+				status = "disabled";
+			};
+
+			frddr_b: audio-controller@200 {
+				compatible = "amlogic,axg-frddr";
+				reg = <0x0 0x200 0x0 0x1c>;
+				#sound-dai-cells = <0>;
+				sound-name-prefix = "FRDDR_B";
+				interrupts = <GIC_SPI 89 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&clkc_audio AUD_CLKID_FRDDR_B>;
+				resets = <&arb AXG_ARB_FRDDR_B>;
+				status = "disabled";
+			};
+
+			frddr_c: audio-controller@240 {
+				compatible = "amlogic,axg-frddr";
+				reg = <0x0 0x240 0x0 0x1c>;
+				#sound-dai-cells = <0>;
+				sound-name-prefix = "FRDDR_C";
+				interrupts = <GIC_SPI 90 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&clkc_audio AUD_CLKID_FRDDR_C>;
+				resets = <&arb AXG_ARB_FRDDR_C>;
+				status = "disabled";
+			};
+
+			arb: reset-controller@280 {
+				compatible = "amlogic,meson-axg-audio-arb";
+				reg = <0x0 0x280 0x0 0x4>;
+				#reset-cells = <1>;
+				clocks = <&clkc_audio AUD_CLKID_DDR_ARB>;
+			};
+
+			tdmin_a: audio-controller@300 {
+				compatible = "amlogic,axg-tdmin";
+				reg = <0x0 0x300 0x0 0x40>;
+				sound-name-prefix = "TDMIN_A";
+				clocks = <&clkc_audio AUD_CLKID_TDMIN_A>,
+					 <&clkc_audio AUD_CLKID_TDMIN_A_SCLK>,
+					 <&clkc_audio AUD_CLKID_TDMIN_A_SCLK_SEL>,
+					 <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>,
+					 <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>;
+				clock-names = "pclk", "sclk", "sclk_sel",
+					      "lrclk", "lrclk_sel";
+				status = "disabled";
+			};
+
+			tdmin_b: audio-controller@340 {
+				compatible = "amlogic,axg-tdmin";
+				reg = <0x0 0x340 0x0 0x40>;
+				sound-name-prefix = "TDMIN_B";
+				clocks = <&clkc_audio AUD_CLKID_TDMIN_B>,
+					 <&clkc_audio AUD_CLKID_TDMIN_B_SCLK>,
+					 <&clkc_audio AUD_CLKID_TDMIN_B_SCLK_SEL>,
+					 <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>,
+					 <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>;
+				clock-names = "pclk", "sclk", "sclk_sel",
+					      "lrclk", "lrclk_sel";
+				status = "disabled";
+			};
+
+			tdmin_c: audio-controller@380 {
+				compatible = "amlogic,axg-tdmin";
+				reg = <0x0 0x380 0x0 0x40>;
+				sound-name-prefix = "TDMIN_C";
+				clocks = <&clkc_audio AUD_CLKID_TDMIN_C>,
+					 <&clkc_audio AUD_CLKID_TDMIN_C_SCLK>,
+					 <&clkc_audio AUD_CLKID_TDMIN_C_SCLK_SEL>,
+					 <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>,
+					 <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>;
+				clock-names = "pclk", "sclk", "sclk_sel",
+					      "lrclk", "lrclk_sel";
+				status = "disabled";
+			};
+
+			tdmin_lb: audio-controller@3c0 {
+				compatible = "amlogic,axg-tdmin";
+				reg = <0x0 0x3c0 0x0 0x40>;
+				sound-name-prefix = "TDMIN_LB";
+				clocks = <&clkc_audio AUD_CLKID_TDMIN_LB>,
+					 <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK>,
+					 <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK_SEL>,
+					 <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>,
+					 <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>;
+				clock-names = "pclk", "sclk", "sclk_sel",
+					      "lrclk", "lrclk_sel";
+				status = "disabled";
+			};
+
+			spdifout: audio-controller@480 {
+				compatible = "amlogic,axg-spdifout";
+				reg = <0x0 0x480 0x0 0x50>;
+				#sound-dai-cells = <0>;
+				sound-name-prefix = "SPDIFOUT";
+				clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
+					 <&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
+				clock-names = "pclk", "mclk";
+				status = "disabled";
+			};
+
+			tdmout_a: audio-controller@500 {
+				compatible = "amlogic,axg-tdmout";
+				reg = <0x0 0x500 0x0 0x40>;
+				sound-name-prefix = "TDMOUT_A";
+				clocks = <&clkc_audio AUD_CLKID_TDMOUT_A>,
+					 <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK>,
+					 <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK_SEL>,
+					 <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>,
+					 <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>;
+				clock-names = "pclk", "sclk", "sclk_sel",
+					      "lrclk", "lrclk_sel";
+				status = "disabled";
+			};
+
+			tdmout_b: audio-controller@540 {
+				compatible = "amlogic,axg-tdmout";
+				reg = <0x0 0x540 0x0 0x40>;
+				sound-name-prefix = "TDMOUT_B";
+				clocks = <&clkc_audio AUD_CLKID_TDMOUT_B>,
+					 <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK>,
+					 <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK_SEL>,
+					 <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>,
+					 <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>;
+				clock-names = "pclk", "sclk", "sclk_sel",
+					      "lrclk", "lrclk_sel";
+				status = "disabled";
+			};
+
+			tdmout_c: audio-controller@580 {
+				compatible = "amlogic,axg-tdmout";
+				reg = <0x0 0x580 0x0 0x40>;
+				sound-name-prefix = "TDMOUT_C";
+				clocks = <&clkc_audio AUD_CLKID_TDMOUT_C>,
+					 <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK>,
+					 <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK_SEL>,
+					 <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>,
+					 <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>;
+				clock-names = "pclk", "sclk", "sclk_sel",
+					      "lrclk", "lrclk_sel";
+				status = "disabled";
+			};
+		};
+
+		aobus: bus@ff800000 {
+			compatible = "simple-bus";
+			reg = <0x0 0xff800000 0x0 0x100000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges = <0x0 0x0 0x0 0xff800000 0x0 0x100000>;
+
+			sysctrl_AO: sys-ctrl@0 {
+				compatible = "amlogic,meson-axg-ao-sysctrl", "simple-mfd", "syscon";
+				reg =  <0x0 0x0 0x0 0x100>;
+
+				clkc_AO: clock-controller {
+					compatible = "amlogic,meson-axg-aoclkc";
+					#clock-cells = <1>;
+					#reset-cells = <1>;
+				};
+			};
+
+			pinctrl_aobus: pinctrl@14 {
+				compatible = "amlogic,meson-axg-aobus-pinctrl";
+				#address-cells = <2>;
+				#size-cells = <2>;
+				ranges;
+
+				gpio_ao: bank@14 {
+					reg = <0x0 0x00014 0x0 0x8>,
+					      <0x0 0x0002c 0x0 0x4>,
+					      <0x0 0x00024 0x0 0x8>;
+					reg-names = "mux", "pull", "gpio";
+					gpio-controller;
+					#gpio-cells = <2>;
+					gpio-ranges = <&pinctrl_aobus 0 0 15>;
+				};
+
+				i2c_ao_sck_4_pins: i2c_ao_sck_4 {
+					mux {
+						groups = "i2c_ao_sck_4";
+						function = "i2c_ao";
+					};
+				};
+
+				i2c_ao_sck_8_pins: i2c_ao_sck_8 {
+					mux {
+						groups = "i2c_ao_sck_8";
+						function = "i2c_ao";
+					};
+				};
+
+				i2c_ao_sck_10_pins: i2c_ao_sck_10 {
+					mux {
+						groups = "i2c_ao_sck_10";
+						function = "i2c_ao";
+					};
+				};
+
+				i2c_ao_sda_5_pins: i2c_ao_sda_5 {
+					mux {
+						groups = "i2c_ao_sda_5";
+						function = "i2c_ao";
+					};
+				};
+
+				i2c_ao_sda_9_pins: i2c_ao_sda_9 {
+					mux {
+						groups = "i2c_ao_sda_9";
+						function = "i2c_ao";
+					};
+				};
+
+				i2c_ao_sda_11_pins: i2c_ao_sda_11 {
+					mux {
+						groups = "i2c_ao_sda_11";
+						function = "i2c_ao";
+					};
+				};
+
+				remote_input_ao_pins: remote_input_ao {
+					mux {
+						groups = "remote_input_ao";
+						function = "remote_input_ao";
+					};
+				};
+
+				uart_ao_a_pins: uart_ao_a {
+					mux {
+						groups = "uart_ao_tx_a",
+							 "uart_ao_rx_a";
+						function = "uart_ao_a";
+					};
+				};
+
+				uart_ao_a_cts_rts_pins: uart_ao_a_cts_rts {
+					mux {
+						groups = "uart_ao_cts_a",
+							 "uart_ao_rts_a";
+						function = "uart_ao_a";
+					};
+				};
+
+				uart_ao_b_pins: uart_ao_b {
+					mux {
+						groups = "uart_ao_tx_b",
+							 "uart_ao_rx_b";
+						function = "uart_ao_b";
+					};
+				};
+
+				uart_ao_b_cts_rts_pins: uart_ao_b_cts_rts {
+					mux {
+						groups = "uart_ao_cts_b",
+							 "uart_ao_rts_b";
+						function = "uart_ao_b";
+					};
+				};
+			};
+
+			sec_AO: ao-secure@140 {
+				compatible = "amlogic,meson-gx-ao-secure", "syscon";
+				reg = <0x0 0x140 0x0 0x140>;
+				amlogic,has-chip-id;
+			};
+
+			pwm_AO_cd: pwm@2000 {
+				compatible = "amlogic,meson-axg-ao-pwm";
+				reg = <0x0 0x02000  0x0 0x20>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
+			uart_AO: serial@3000 {
+				compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart";
+				reg = <0x0 0x3000 0x0 0x18>;
+				interrupts = <GIC_SPI 193 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&xtal>, <&clkc_AO CLKID_AO_UART1>, <&xtal>;
+				clock-names = "xtal", "pclk", "baud";
+				status = "disabled";
+			};
+
+			uart_AO_B: serial@4000 {
+				compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart";
+				reg = <0x0 0x4000 0x0 0x18>;
+				interrupts = <GIC_SPI 197 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&xtal>, <&clkc_AO CLKID_AO_UART2>, <&xtal>;
+				clock-names = "xtal", "pclk", "baud";
+				status = "disabled";
+			};
+
+			i2c_AO: i2c@5000 {
+				compatible = "amlogic,meson-axg-i2c";
+				reg = <0x0 0x05000 0x0 0x20>;
+				interrupts = <GIC_SPI 195 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&clkc CLKID_AO_I2C>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			pwm_AO_ab: pwm@7000 {
+				compatible = "amlogic,meson-axg-ao-pwm";
+				reg = <0x0 0x07000 0x0 0x20>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
+			ir: ir@8000 {
+				compatible = "amlogic,meson-gxbb-ir";
+				reg = <0x0 0x8000 0x0 0x20>;
+				interrupts = <GIC_SPI 196 IRQ_TYPE_EDGE_RISING>;
+				status = "disabled";
+			};
+
+			saradc: adc@9000 {
+				compatible = "amlogic,meson-axg-saradc",
+					"amlogic,meson-saradc";
+				reg = <0x0 0x9000 0x0 0x38>;
+				#io-channel-cells = <1>;
+				interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&xtal>,
+					 <&clkc_AO CLKID_AO_SAR_ADC>,
+					 <&clkc_AO CLKID_AO_SAR_ADC_CLK>,
+					 <&clkc_AO CLKID_AO_SAR_ADC_SEL>;
+				clock-names = "clkin", "core", "adc_clk", "adc_sel";
+				status = "disabled";
+			};
+		};
+
+		gic: interrupt-controller@ffc01000 {
+			compatible = "arm,gic-400";
+			reg = <0x0 0xffc01000 0 0x1000>,
+			      <0x0 0xffc02000 0 0x2000>,
+			      <0x0 0xffc04000 0 0x2000>,
+			      <0x0 0xffc06000 0 0x2000>;
+			interrupt-controller;
+			interrupts = <GIC_PPI 9
+				(GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+		};
+
+		cbus: bus@ffd00000 {
+			compatible = "simple-bus";
+			reg = <0x0 0xffd00000 0x0 0x25000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges = <0x0 0x0 0x0 0xffd00000 0x0 0x25000>;
+
+			reset: reset-controller@1004 {
+				compatible = "amlogic,meson-axg-reset";
+				reg = <0x0 0x01004 0x0 0x9c>;
+				#reset-cells = <1>;
+			};
+
+			gpio_intc: interrupt-controller@f080 {
+				compatible = "amlogic,meson-gpio-intc";
+				reg = <0x0 0xf080 0x0 0x10>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				amlogic,channel-interrupts = <64 65 66 67 68 69 70 71>;
+				status = "disabled";
+			};
+
+			pwm_ab: pwm@1b000 {
+				compatible = "amlogic,meson-axg-ee-pwm";
+				reg = <0x0 0x1b000 0x0 0x20>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
+			pwm_cd: pwm@1a000 {
+				compatible = "amlogic,meson-axg-ee-pwm";
+				reg = <0x0 0x1a000 0x0 0x20>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
+			spicc0: spi@13000 {
+				compatible = "amlogic,meson-axg-spicc";
+				reg = <0x0 0x13000 0x0 0x3c>;
+				interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clkc CLKID_SPICC0>;
+				clock-names = "core";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			spicc1: spi@15000 {
+				compatible = "amlogic,meson-axg-spicc";
+				reg = <0x0 0x15000 0x0 0x3c>;
+				interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clkc CLKID_SPICC1>;
+				clock-names = "core";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			i2c3: i2c@1c000 {
+				compatible = "amlogic,meson-axg-i2c";
+				reg = <0x0 0x1c000 0x0 0x20>;
+				interrupts = <GIC_SPI 39 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&clkc CLKID_I2C>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			i2c2: i2c@1d000 {
+				compatible = "amlogic,meson-axg-i2c";
+				reg = <0x0 0x1d000 0x0 0x20>;
+				interrupts = <GIC_SPI 215 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&clkc CLKID_I2C>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			i2c1: i2c@1e000 {
+				compatible = "amlogic,meson-axg-i2c";
+				reg = <0x0 0x1e000 0x0 0x20>;
+				interrupts = <GIC_SPI 214 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&clkc CLKID_I2C>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			i2c0: i2c@1f000 {
+				compatible = "amlogic,meson-axg-i2c";
+				reg = <0x0 0x1f000 0x0 0x20>;
+				interrupts = <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&clkc CLKID_I2C>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			uart_B: serial@23000 {
+				compatible = "amlogic,meson-gx-uart";
+				reg = <0x0 0x23000 0x0 0x18>;
+				interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
+				status = "disabled";
+				clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>;
+				clock-names = "xtal", "pclk", "baud";
+			};
+
+			uart_A: serial@24000 {
+				compatible = "amlogic,meson-gx-uart";
+				reg = <0x0 0x24000 0x0 0x18>;
+				interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
+				status = "disabled";
+				clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>;
+				clock-names = "xtal", "pclk", "baud";
+			};
+		};
+
+		apb: bus@ffe00000 {
+			compatible = "simple-bus";
+			reg = <0x0 0xffe00000 0x0 0x200000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x200000>;
+
+			sd_emmc_b: sd@5000 {
+				compatible = "amlogic,meson-axg-mmc";
+				reg = <0x0 0x5000 0x0 0x800>;
+				interrupts = <GIC_SPI 217 IRQ_TYPE_EDGE_RISING>;
+				status = "disabled";
+				clocks = <&clkc CLKID_SD_EMMC_B>,
+					<&clkc CLKID_SD_EMMC_B_CLK0>,
+					<&clkc CLKID_FCLK_DIV2>;
+				clock-names = "core", "clkin0", "clkin1";
+				resets = <&reset RESET_SD_EMMC_B>;
+			};
+
+			sd_emmc_c: mmc@7000 {
+				compatible = "amlogic,meson-axg-mmc";
+				reg = <0x0 0x7000 0x0 0x800>;
+				interrupts = <GIC_SPI 218 IRQ_TYPE_EDGE_RISING>;
+				status = "disabled";
+				clocks = <&clkc CLKID_SD_EMMC_C>,
+					<&clkc CLKID_SD_EMMC_C_CLK0>,
+					<&clkc CLKID_FCLK_DIV2>;
+				clock-names = "core", "clkin0", "clkin1";
+				resets = <&reset RESET_SD_EMMC_C>;
+			};
+		};
+
+		sram: sram@fffc0000 {
+			compatible = "amlogic,meson-axg-sram", "mmio-sram";
+			reg = <0x0 0xfffc0000 0x0 0x20000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0x0 0xfffc0000 0x20000>;
+
+			cpu_scp_lpri: scp-shmem@0 {
+				compatible = "amlogic,meson-axg-scp-shmem";
+				reg = <0x13000 0x400>;
+			};
+
+			cpu_scp_hpri: scp-shmem@200 {
+				compatible = "amlogic,meson-axg-scp-shmem";
+				reg = <0x13400 0x400>;
+			};
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13
+			(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14
+			(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11
+			(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10
+			(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	xtal: xtal-clk {
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "xtal";
+		#clock-cells = <0>;
+	};
+};
diff --git a/arch/arm/dts/meson-gx.dtsi b/arch/arm/dts/meson-gx.dtsi
index 3c31e21..f1e5cdb 100644
--- a/arch/arm/dts/meson-gx.dtsi
+++ b/arch/arm/dts/meson-gx.dtsi
@@ -35,10 +35,16 @@
 			no-map;
 		};
 
+		/* Alternate 3 MiB reserved for ARM Trusted Firmware (BL31) */
+		secmon_reserved_alt: secmon@5000000 {
+			reg = <0x0 0x05000000 0x0 0x300000>;
+			no-map;
+		};
+
 		linux,cma {
 			compatible = "shared-dma-pool";
 			reusable;
-			size = <0x0 0xbc00000>;
+			size = <0x0 0x10000000>;
 			alignment = <0x0 0x400000>;
 			linux,cma-default;
 		};
@@ -338,7 +344,7 @@
 			ranges = <0x0 0x0 0x0 0xc8100000 0x0 0x100000>;
 
 			sysctrl_AO: sys-ctrl@0 {
-				compatible = "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd";
+				compatible = "amlogic,meson-gx-ao-sysctrl", "simple-mfd", "syscon";
 				reg =  <0x0 0x0 0x0 0x100>;
 
 				pwrc_vpu: power-controller-vpu {
@@ -417,6 +423,19 @@
 			};
 		};
 
+		dmcbus: bus@c8838000 {
+			compatible = "simple-bus";
+			reg = <0x0 0xc8838000 0x0 0x400>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges = <0x0 0x0 0x0 0xc8838000 0x0 0x400>;
+
+			canvas: video-lut@48 {
+				compatible = "amlogic,canvas";
+				reg = <0x0 0x48 0x0 0x14>;
+			};
+		};
+
 		hiubus: bus@c883c000 {
 			compatible = "simple-bus";
 			reg = <0x0 0xc883c000 0x0 0x2000>;
@@ -425,7 +444,7 @@
 			ranges = <0x0 0x0 0x0 0xc883c000 0x0 0x2000>;
 
 			sysctrl: system-controller@0 {
-				compatible = "amlogic,meson-gx-hhi-sysctrl", "syscon", "simple-mfd";
+				compatible = "amlogic,meson-gx-hhi-sysctrl", "simple-mfd", "syscon";
 				reg = <0 0 0 0x400>;
 			};
 
@@ -457,21 +476,21 @@
 
 			sd_emmc_a: mmc@70000 {
 				compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc";
-				reg = <0x0 0x70000 0x0 0x2000>;
+				reg = <0x0 0x70000 0x0 0x800>;
 				interrupts = <GIC_SPI 216 IRQ_TYPE_EDGE_RISING>;
 				status = "disabled";
 			};
 
 			sd_emmc_b: mmc@72000 {
 				compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc";
-				reg = <0x0 0x72000 0x0 0x2000>;
+				reg = <0x0 0x72000 0x0 0x800>;
 				interrupts = <GIC_SPI 217 IRQ_TYPE_EDGE_RISING>;
 				status = "disabled";
 			};
 
 			sd_emmc_c: mmc@74000 {
 				compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc";
-				reg = <0x0 0x74000 0x0 0x2000>;
+				reg = <0x0 0x74000 0x0 0x800>;
 				interrupts = <GIC_SPI 218 IRQ_TYPE_EDGE_RISING>;
 				status = "disabled";
 			};
diff --git a/arch/arm/dts/meson-gxbb-nanopi-k2.dts b/arch/arm/dts/meson-gxbb-nanopi-k2.dts
index 7d5709c..cbe99bd 100644
--- a/arch/arm/dts/meson-gxbb-nanopi-k2.dts
+++ b/arch/arm/dts/meson-gxbb-nanopi-k2.dts
@@ -106,6 +106,42 @@
 		compatible = "mmc-pwrseq-emmc";
 		reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
 	};
+
+	/* CVBS is available on CON1 pin 36, disabled by default */
+	cvbs-connector {
+		compatible = "composite-video-connector";
+		status = "disabled";
+
+		port {
+			cvbs_connector_in: endpoint {
+				remote-endpoint = <&cvbs_vdac_out>;
+			};
+		};
+	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&hdmi_tx_tmds_out>;
+			};
+		};
+	};
+};
+
+&cec_AO {
+	status = "okay";
+	pinctrl-0 = <&ao_cec_pins>;
+	pinctrl-names = "default";
+	hdmi-phandle = <&hdmi_tx>;
+};
+
+&cvbs_vdac_port {
+	cvbs_vdac_out: endpoint {
+		remote-endpoint = <&cvbs_connector_in>;
+	};
 };
 
 &ethmac {
@@ -137,6 +173,18 @@
 	};
 };
 
+&hdmi_tx {
+	status = "okay";
+	pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
+	pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+	hdmi_tx_tmds_out: endpoint {
+		remote-endpoint = <&hdmi_connector_in>;
+	};
+};
+
 &ir {
 	status = "okay";
 	pinctrl-0 = <&remote_input_ao_pins>;
diff --git a/arch/arm/dts/meson-gxbb.dtsi b/arch/arm/dts/meson-gxbb.dtsi
index 562c26a..1ade7e4 100644
--- a/arch/arm/dts/meson-gxbb.dtsi
+++ b/arch/arm/dts/meson-gxbb.dtsi
@@ -307,11 +307,10 @@
 	clock-names = "isfr", "iahb", "venci";
 };
 
-&hiubus {
-	clkc: clock-controller@0 {
+&sysctrl {
+	clkc: clock-controller {
 		compatible = "amlogic,gxbb-clkc";
 		#clock-cells = <1>;
-		reg = <0x0 0x0 0x0 0x3db>;
 	};
 };
 
@@ -391,7 +390,7 @@
 			};
 		};
 
-		spi_pins: spi {
+		spi_pins: spi-pins {
 			mux {
 				groups = "spi_miso",
 					"spi_mosi",
@@ -716,6 +715,7 @@
 		 <&clkc CLKID_SD_EMMC_A_CLK0>,
 		 <&clkc CLKID_FCLK_DIV2>;
 	clock-names = "core", "clkin0", "clkin1";
+	resets = <&reset RESET_SD_EMMC_A>;
 };
 
 &sd_emmc_b {
@@ -723,6 +723,7 @@
 		 <&clkc CLKID_SD_EMMC_B_CLK0>,
 		 <&clkc CLKID_FCLK_DIV2>;
 	clock-names = "core", "clkin0", "clkin1";
+	resets = <&reset RESET_SD_EMMC_B>;
 };
 
 &sd_emmc_c {
@@ -730,6 +731,7 @@
 		 <&clkc CLKID_SD_EMMC_C_CLK0>,
 		 <&clkc CLKID_FCLK_DIV2>;
 	clock-names = "core", "clkin0", "clkin1";
+	resets = <&reset RESET_SD_EMMC_C>;
 };
 
 &spicc {
@@ -749,12 +751,12 @@
 };
 
 &uart_AO {
-	clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>;
+	clocks = <&xtal>, <&clkc_AO CLKID_AO_UART1>, <&xtal>;
 	clock-names = "xtal", "pclk", "baud";
 };
 
 &uart_AO_B {
-	clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>;
+	clocks = <&xtal>, <&clkc_AO CLKID_AO_UART2>, <&xtal>;
 	clock-names = "xtal", "pclk", "baud";
 };
 
diff --git a/arch/arm/dts/meson-gxl-mali.dtsi b/arch/arm/dts/meson-gxl-mali.dtsi
index eb32766..6aaafff 100644
--- a/arch/arm/dts/meson-gxl-mali.dtsi
+++ b/arch/arm/dts/meson-gxl-mali.dtsi
@@ -6,7 +6,7 @@
 
 &apb {
 	mali: gpu@c0000 {
-		compatible = "amlogic,meson-gxbb-mali", "arm,mali-450";
+		compatible = "amlogic,meson-gxl-mali", "arm,mali-450";
 		reg = <0x0 0xc0000 0x0 0x40000>;
 		interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm/dts/meson-gxl-s905x-libretech-cc.dts b/arch/arm/dts/meson-gxl-s905x-libretech-cc.dts
index 3e3eb31..90a56af 100644
--- a/arch/arm/dts/meson-gxl-s905x-libretech-cc.dts
+++ b/arch/arm/dts/meson-gxl-s905x-libretech-cc.dts
@@ -13,7 +13,7 @@
 
 / {
 	compatible = "libretech,cc", "amlogic,s905x", "amlogic,meson-gxl";
-	model = "Libre Technology CC";
+	model = "Libre Computer Board AML-S905X-CC";
 
 	aliases {
 		serial0 = &uart_AO;
@@ -234,9 +234,6 @@
 
 	bus-width = <4>;
 	cap-sd-highspeed;
-	sd-uhs-sdr12;
-	sd-uhs-sdr25;
-	sd-uhs-sdr50;
 	max-frequency = <100000000>;
 	disable-wp;
 
diff --git a/arch/arm/dts/meson-gxl-s905x-p212.dtsi b/arch/arm/dts/meson-gxl-s905x-p212.dtsi
index 3bd4050..a1b3101 100644
--- a/arch/arm/dts/meson-gxl-s905x-p212.dtsi
+++ b/arch/arm/dts/meson-gxl-s905x-p212.dtsi
@@ -191,8 +191,8 @@
 };
 
 &usb2_phy0 {
-        /*
-         * HDMI_5V is also used as supply for the USB VBUS.
-         */
-        phy-supply = <&hdmi_5v>;
+	/*
+	 * HDMI_5V is also used as supply for the USB VBUS.
+	 */
+	phy-supply = <&hdmi_5v>;
 };
diff --git a/arch/arm/dts/meson-gxl.dtsi b/arch/arm/dts/meson-gxl.dtsi
index dba365e..8f0bb3c 100644
--- a/arch/arm/dts/meson-gxl.dtsi
+++ b/arch/arm/dts/meson-gxl.dtsi
@@ -13,14 +13,6 @@
 / {
 	compatible = "amlogic,meson-gxl";
 
-	reserved-memory {
-		/* Alternate 3 MiB reserved for ARM Trusted Firmware (BL31) */
-		secmon_reserved_alt: secmon@5000000 {
-			reg = <0x0 0x05000000 0x0 0x300000>;
-			no-map;
-		};
-	};
-
 	soc {
 		usb0: usb@c9000000 {
 			status = "disabled";
@@ -267,11 +259,10 @@
 	clock-names = "isfr", "iahb", "venci";
 };
 
-&hiubus {
-	clkc: clock-controller@0 {
-		compatible = "amlogic,gxl-clkc", "amlogic,gxbb-clkc";
+&sysctrl {
+	clkc: clock-controller {
+		compatible = "amlogic,gxl-clkc";
 		#clock-cells = <1>;
-		reg = <0x0 0x0 0x0 0x3db>;
 	};
 };
 
@@ -346,7 +337,7 @@
 			};
 		};
 
-		spi_pins: spi {
+		spi_pins: spi-pins {
 			mux {
 				groups = "spi_miso",
 					"spi_mosi",
@@ -725,13 +716,15 @@
 		 <&clkc CLKID_SD_EMMC_A_CLK0>,
 		 <&clkc CLKID_FCLK_DIV2>;
 	clock-names = "core", "clkin0", "clkin1";
+	resets = <&reset RESET_SD_EMMC_A>;
 };
 
 &sd_emmc_b {
 	clocks = <&clkc CLKID_SD_EMMC_B>,
 		 <&clkc CLKID_SD_EMMC_B_CLK0>,
 		 <&clkc CLKID_FCLK_DIV2>;
-       clock-names = "core", "clkin0", "clkin1";
+	clock-names = "core", "clkin0", "clkin1";
+	resets = <&reset RESET_SD_EMMC_B>;
 };
 
 &sd_emmc_c {
@@ -739,6 +732,7 @@
 		 <&clkc CLKID_SD_EMMC_C_CLK0>,
 		 <&clkc CLKID_FCLK_DIV2>;
 	clock-names = "core", "clkin0", "clkin1";
+	resets = <&reset RESET_SD_EMMC_C>;
 };
 
 &spicc {
@@ -758,12 +752,12 @@
 };
 
 &uart_AO {
-	clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>;
+	clocks = <&xtal>, <&clkc_AO CLKID_AO_UART1>, <&xtal>;
 	clock-names = "xtal", "pclk", "baud";
 };
 
 &uart_AO_B {
-	clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>;
+	clocks = <&xtal>, <&clkc_AO CLKID_AO_UART2>, <&xtal>;
 	clock-names = "xtal", "pclk", "baud";
 };
 
diff --git a/arch/arm/dts/meson-gxm-khadas-vim2.dts b/arch/arm/dts/meson-gxm-khadas-vim2.dts
index 0868da4..313f88f 100644
--- a/arch/arm/dts/meson-gxm-khadas-vim2.dts
+++ b/arch/arm/dts/meson-gxm-khadas-vim2.dts
@@ -209,10 +209,34 @@
 	#cooling-cells = <2>;
 };
 
+&cpu1 {
+	#cooling-cells = <2>;
+};
+
+&cpu2 {
+	#cooling-cells = <2>;
+};
+
+&cpu3 {
+	#cooling-cells = <2>;
+};
+
 &cpu4 {
 	#cooling-cells = <2>;
 };
 
+&cpu5 {
+	#cooling-cells = <2>;
+};
+
+&cpu6 {
+	#cooling-cells = <2>;
+};
+
+&cpu7 {
+	#cooling-cells = <2>;
+};
+
 &ethmac {
 	pinctrl-0 = <&eth_pins>;
 	pinctrl-names = "default";
diff --git a/arch/arm/dts/mt7623.dtsi b/arch/arm/dts/mt7623.dtsi
new file mode 100644
index 0000000..f50f4ef
--- /dev/null
+++ b/arch/arm/dts/mt7623.dtsi
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ *
+ * SPDX-License-Identifier: (GPL-2.0 OR MIT)
+ */
+
+#include <dt-bindings/clock/mt7623-clk.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/mt7623-power.h>
+#include "skeleton.dtsi"
+
+/ {
+	compatible = "mediatek,mt7623";
+	interrupt-parent = <&sysirq>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		enable-method = "mediatek,mt6589-smp";
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x0>;
+			clocks = <&infracfg CLK_INFRA_CPUSEL>,
+				 <&apmixedsys CLK_APMIXED_MAINPLL>;
+			clock-names = "cpu", "intermediate";
+			clock-frequency = <1300000000>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x1>;
+			clocks = <&infracfg CLK_INFRA_CPUSEL>,
+				 <&apmixedsys CLK_APMIXED_MAINPLL>;
+			clock-names = "cpu", "intermediate";
+			clock-frequency = <1300000000>;
+		};
+
+		cpu2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x2>;
+			clocks = <&infracfg CLK_INFRA_CPUSEL>,
+				 <&apmixedsys CLK_APMIXED_MAINPLL>;
+			clock-names = "cpu", "intermediate";
+			clock-frequency = <1300000000>;
+		};
+
+		cpu3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x3>;
+			clocks = <&infracfg CLK_INFRA_CPUSEL>,
+				 <&apmixedsys CLK_APMIXED_MAINPLL>;
+			clock-names = "cpu", "intermediate";
+			clock-frequency = <1300000000>;
+		};
+	};
+
+	system_clk: dummy13m {
+		compatible = "fixed-clock";
+		clock-frequency = <13000000>;
+		#clock-cells = <0>;
+	};
+
+	rtc32k: oscillator-1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32000>;
+		clock-output-names = "rtc32k";
+	};
+
+	clk26m: oscillator-0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+		clock-output-names = "clk26m";
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+		clock-frequency = <13000000>;
+		arm,cpu-registers-not-fw-configured;
+	};
+
+	topckgen: clock-controller@10000000 {
+		compatible = "mediatek,mt7623-topckgen";
+		reg = <0x10000000 0x1000>;
+		#clock-cells = <1>;
+		u-boot,dm-pre-reloc;
+	};
+
+	infracfg: syscon@10001000 {
+		compatible = "mediatek,mt7623-infracfg", "syscon";
+		reg = <0x10001000 0x1000>;
+		#clock-cells = <1>;
+		u-boot,dm-pre-reloc;
+	};
+
+	pericfg: syscon@10003000 {
+		compatible = "mediatek,mt7623-pericfg", "syscon";
+		reg = <0x10003000 0x1000>;
+		#clock-cells = <1>;
+		u-boot,dm-pre-reloc;
+	};
+
+	pinctrl: pinctrl@10005000 {
+		compatible = "mediatek,mt7623-pinctrl";
+		reg = <0x10005000 0x1000>;
+
+		gpio: gpio-controller {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+	};
+
+	scpsys: scpsys@10006000 {
+		compatible = "mediatek,mt7623-scpsys";
+		#power-domain-cells = <1>;
+		reg = <0x10006000 0x1000>;
+		infracfg = <&infracfg>;
+		clocks = <&topckgen CLK_TOP_MM_SEL>,
+			 <&topckgen CLK_TOP_MFG_SEL>,
+			 <&topckgen CLK_TOP_ETHIF_SEL>;
+		clock-names = "mm", "mfg", "ethif";
+	};
+
+	watchdog: watchdog@10007000 {
+		compatible = "mediatek,wdt";
+		reg = <0x10007000 0x100>;
+	};
+
+	wdt-reboot {
+		compatible = "wdt-reboot";
+		wdt = <&watchdog>;
+	};
+
+	timer0: timer@10008000 {
+		compatible = "mediatek,timer";
+		reg = <0x10008000 0x80>;
+		interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&system_clk>;
+		clock-names = "system-clk";
+		u-boot,dm-pre-reloc;
+	};
+
+	sysirq: interrupt-controller@10200100 {
+		compatible = "mediatek,sysirq";
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		interrupt-parent = <&gic>;
+		reg = <0x10200100 0x1c>;
+	};
+
+	apmixedsys: clock-controller@10209000 {
+		compatible = "mediatek,mt7623-apmixedsys";
+		reg = <0x10209000 0x1000>;
+		#clock-cells = <1>;
+		u-boot,dm-pre-reloc;
+	};
+
+	gic: interrupt-controller@10211000 {
+		compatible = "arm,cortex-a7-gic";
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		interrupt-parent = <&gic>;
+		reg = <0x10211000 0x1000>,
+		      <0x10212000 0x1000>,
+		      <0x10214000 0x2000>,
+		      <0x10216000 0x2000>;
+	};
+
+	uart0: serial@11002000 {
+		compatible = "mediatek,hsuart";
+		reg = <0x11002000 0x400>;
+		reg-shift = <2>;
+		interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_UART_SEL>,
+			 <&pericfg CLK_PERI_UART0>;
+		clock-names = "baud", "bus";
+		status = "disabled";
+	};
+
+	uart1: serial@11003000 {
+		compatible = "mediatek,hsuart";
+		reg = <0x11003000 0x400>;
+		reg-shift = <2>;
+		interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_UART_SEL>,
+			 <&pericfg CLK_PERI_UART1>;
+		clock-names = "baud", "bus";
+		status = "disabled";
+	};
+
+	uart2: serial@11004000 {
+		compatible = "mediatek,hsuart";
+		reg = <0x11004000 0x400>;
+		reg-shift = <2>;
+		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_UART_SEL>,
+			 <&pericfg CLK_PERI_UART2>;
+		clock-names = "baud", "bus";
+		status = "disabled";
+		u-boot,dm-pre-reloc;
+	};
+
+	uart3: serial@11005000 {
+		compatible = "mediatek,hsuart";
+		reg = <0x11005000 0x400>;
+		reg-shift = <2>;
+		interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_UART_SEL>,
+			 <&pericfg CLK_PERI_UART3>;
+		clock-names = "baud", "bus";
+		status = "disabled";
+	};
+
+	mmc0: mmc@11230000 {
+		compatible = "mediatek,mt7623-mmc";
+		reg = <0x11230000 0x1000>;
+		interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&pericfg CLK_PERI_MSDC30_0>,
+			 <&topckgen CLK_TOP_MSDC30_0_SEL>;
+		clock-names = "source", "hclk";
+		status = "disabled";
+	};
+
+	mmc1: mmc@11240000 {
+		compatible = "mediatek,mt7623-mmc";
+		reg = <0x11240000 0x1000>;
+		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&pericfg CLK_PERI_MSDC30_1>,
+			 <&topckgen CLK_TOP_MSDC30_1_SEL>;
+		clock-names = "source", "hclk";
+		status = "disabled";
+	};
+
+	ethsys: syscon@1b000000 {
+		compatible = "mediatek,mt7623-ethsys";
+		reg = <0x1b000000 0x1000>;
+		#clock-cells = <1>;
+	};
+};
diff --git a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
new file mode 100644
index 0000000..84a77fd
--- /dev/null
+++ b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ *
+ * SPDX-License-Identifier: (GPL-2.0 OR MIT)
+ */
+
+/dts-v1/;
+#include "mt7623.dtsi"
+
+/ {
+	model = "Bananapi BPI-R2";
+	compatible = "bananapi,bpi-r2", "mediatek,mt7623";
+
+	chosen {
+		stdout-path = &uart2;
+		tick-timer = &timer0;
+	};
+
+	reg_1p8v: regulator-1p8v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-1.8V";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	reg_5v: regulator-5v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-5V";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		blue {
+			label = "bpi-r2:pio:blue";
+			gpios = <&gpio 241 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+
+		green {
+			label = "bpi-r2:pio:green";
+			gpios = <&gpio 240 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+
+		red {
+			label = "bpi-r2:pio:red";
+			gpios = <&gpio 239 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_default>;
+	status = "okay";
+	bus-width = <8>;
+	max-frequency = <50000000>;
+	cap-mmc-highspeed;
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_1p8v>;
+	non-removable;
+};
+
+&mmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc1_pins_default>;
+	status = "okay";
+	bus-width = <4>;
+	max-frequency = <50000000>;
+	cap-sd-highspeed;
+	cd-gpios = <&gpio 261 GPIO_ACTIVE_LOW>;
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_3p3v>;
+};
+
+&pinctrl {
+	ephy_default: ephy_default {
+		mux {
+			function = "eth";
+			groups = "mdc_mdio", "ephy";
+		};
+
+		conf {
+			pins = "G2_TXEN", "G2_TXD0", "G2_TXD1", "G2_TXD2",
+			       "G2_TXD3", "G2_TXC", "G2_RXC", "G2_RXD0",
+			       "G2_RXD1", "G2_RXD2", "G2_RXD3", "G2_RXDV",
+			       "MDC", "MDIO";
+			drive-strength = <12>;
+			mediatek,tdsel = <5>;
+		};
+	};
+
+	mmc0_pins_default: mmc0default {
+		mux {
+			function = "msdc";
+			groups =  "msdc0";
+		};
+
+		conf-cmd-data {
+			pins = "MSDC0_CMD", "MSDC0_DAT0", "MSDC0_DAT1",
+			       "MSDC0_DAT2", "MSDC0_DAT3", "MSDC0_DAT4",
+			       "MSDC0_DAT5", "MSDC0_DAT6", "MSDC0_DAT7";
+			input-enable;
+			bias-pull-up;
+		};
+
+		conf-clk {
+			pins = "MSDC0_CLK";
+			bias-pull-down;
+		};
+
+		conf-rst {
+			pins = "MSDC0_RSTB";
+			bias-pull-up;
+		};
+	};
+
+	mmc1_pins_default: mmc1default {
+		mux {
+			function = "msdc";
+			groups =  "msdc1", "msdc1_wp_0";
+		};
+
+		conf-cmd-data {
+			pins = "MSDC1_DAT0", "MSDC1_DAT1", "MSDC1_DAT2",
+			       "MSDC1_DAT3", "MSDC1_DAT3", "MSDC1_CMD";
+			input-enable;
+			drive-strength = <4>;
+			bias-pull-up;
+		};
+
+		conf-clk {
+			pins = "MSDC1_CLK";
+			drive-strength = <4>;
+		};
+
+		conf-wp {
+			pins = "EINT7";
+			input-enable;
+			bias-pull-up;
+		};
+	};
+
+	uart0_pins_a: uart0-default {
+		mux {
+			function = "uart";
+			groups =  "uart0_0_txd_rxd";
+		};
+	};
+
+	uart1_pins_a: uart1-default {
+		mux {
+			function = "uart";
+			groups =  "uart1_0_txd_rxd";
+		};
+	};
+
+	uart2_pins_a: uart2-default {
+		mux {
+			function = "uart";
+			groups =  "uart2_0_txd_rxd";
+		};
+	};
+
+	uart2_pins_b: uart2-alt {
+		mux {
+			function = "uart";
+			groups =  "uart2_1_txd_rxd";
+		};
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins_a>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins_a>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_pins_a>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/mt7629-rfb-u-boot.dtsi b/arch/arm/dts/mt7629-rfb-u-boot.dtsi
new file mode 100644
index 0000000..1ef5568
--- /dev/null
+++ b/arch/arm/dts/mt7629-rfb-u-boot.dtsi
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <config.h>
+/ {
+	binman {
+		filename = "u-boot-mtk.bin";
+		pad-byte = <0xff>;
+
+#ifdef CONFIG_SPL
+		blob {
+			filename = "spl/u-boot-spl-mtk.bin";
+			size = <CONFIG_SPL_PAD_TO>;
+		};
+
+		u-boot-img {
+		};
+#endif
+	};
+};
diff --git a/arch/arm/dts/mt7629-rfb.dts b/arch/arm/dts/mt7629-rfb.dts
new file mode 100644
index 0000000..a6d28a0
--- /dev/null
+++ b/arch/arm/dts/mt7629-rfb.dts
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ *
+ * SPDX-License-Identifier: (GPL-2.0 OR MIT)
+ */
+
+/dts-v1/;
+#include "mt7629.dtsi"
+
+/ {
+	model = "MediaTek MT7629 RFB";
+	compatible = "mediatek,mt7629-rfb", "mediatek,mt7629";
+
+	aliases {
+		spi0 = &qspi;
+	};
+
+	chosen {
+		stdout-path = &uart0;
+		tick-timer = &timer0;
+	};
+};
+
+&pinctrl {
+	qspi_pins: qspi-pins {
+		mux {
+			function = "flash";
+			groups = "spi_nor";
+		};
+	};
+
+	uart0_pins: uart0-default {
+		mux {
+			function = "uart";
+			groups = "uart0_txd_rxd";
+		};
+	};
+
+	watchdog_pins: watchdog-default {
+		mux {
+			function = "watchdog";
+			groups = "watchdog";
+		};
+	};
+};
+
+&qspi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&qspi_pins>;
+	status = "okay";
+
+	spi-flash@0{
+		compatible = "spi-flash";
+		reg = <0>;
+		u-boot,dm-pre-reloc;
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins>;
+	status = "okay";
+};
+
+&watchdog {
+	pinctrl-names = "default";
+	pinctrl-0 = <&watchdog_pins>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/mt7629.dtsi b/arch/arm/dts/mt7629.dtsi
new file mode 100644
index 0000000..e6052bb
--- /dev/null
+++ b/arch/arm/dts/mt7629.dtsi
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ *
+ * SPDX-License-Identifier: (GPL-2.0 OR MIT)
+ */
+
+#include <dt-bindings/clock/mt7629-clk.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/mt7629-power.h>
+#include "skeleton.dtsi"
+
+/ {
+	compatible = "mediatek,mt7629";
+	interrupt-parent = <&sysirq>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		enable-method = "mediatek,mt6589-smp";
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x0>;
+			clock-frequency = <1250000000>;
+		};
+
+		cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x1>;
+			clock-frequency = <1250000000>;
+		};
+	};
+
+	clk20m: oscillator@0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <20000000>;
+		clock-output-names = "clk20m";
+	};
+
+	clk40m: oscillator@1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <40000000>;
+		clock-output-names = "clkxtal";
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+		clock-frequency = <20000000>;
+		arm,cpu-registers-not-fw-configured;
+	};
+
+	infracfg: syscon@10000000 {
+		compatible = "mediatek,mt7629-infracfg", "syscon";
+		reg = <0x10000000 0x1000>;
+		#clock-cells = <1>;
+		u-boot,dm-pre-reloc;
+	};
+
+	pericfg: syscon@10002000 {
+		compatible = "mediatek,mt7629-pericfg", "syscon";
+		reg = <0x10002000 0x1000>;
+		#clock-cells = <1>;
+		u-boot,dm-pre-reloc;
+	};
+
+	timer0: timer@10004000 {
+		compatible = "mediatek,timer";
+		reg = <0x10004000 0x80>;
+		interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_10M_SEL>,
+			 <&topckgen CLK_TOP_CLKXTAL_D4>;
+		clock-names = "mux", "src";
+		u-boot,dm-pre-reloc;
+	};
+
+	scpsys: scpsys@10006000 {
+		compatible = "mediatek,mt7629-scpsys";
+		reg = <0x10006000 0x1000>;
+		clocks = <&topckgen CLK_TOP_HIF_SEL>;
+		clock-names = "hif_sel";
+		assigned-clocks = <&topckgen CLK_TOP_HIF_SEL>;
+		assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>;
+		#power-domain-cells = <1>;
+		infracfg = <&infracfg>;
+	};
+
+	mcucfg: syscon@10200000 {
+		compatible = "mediatek,mt7629-mcucfg", "syscon";
+		reg = <0x10200000 0x1000>;
+		#clock-cells = <1>;
+		u-boot,dm-pre-reloc;
+	};
+
+	sysirq: interrupt-controller@10200a80 {
+		compatible = "mediatek,sysirq";
+		reg = <0x10200a80 0x20>;
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		interrupt-parent = <&gic>;
+	};
+
+	dramc: dramc@10203000 {
+		compatible = "mediatek,mt7629-dramc";
+		reg = <0x10203000 0x600>,	/* EMI */
+		      <0x10213000 0x1000>,	/* DDRPHY */
+		      <0x10214000 0xd00>;	/* DRAMC_AO */
+		clocks = <&topckgen CLK_TOP_DDRPHYCFG_SEL>,
+			 <&topckgen CLK_TOP_SYSPLL1_D8>,
+			 <&topckgen CLK_TOP_MEM_SEL>,
+			 <&topckgen CLK_TOP_DMPLL>;
+		clock-names = "phy", "phy_mux", "mem", "mem_mux";
+		u-boot,dm-pre-reloc;
+	};
+
+	apmixedsys: clock-controller@10209000 {
+		compatible = "mediatek,mt7629-apmixedsys";
+		reg = <0x10209000 0x1000>;
+		#clock-cells = <1>;
+		u-boot,dm-pre-reloc;
+	};
+
+	topckgen: clock-controller@10210000 {
+		compatible = "mediatek,mt7629-topckgen";
+		reg = <0x10210000 0x1000>;
+		#clock-cells = <1>;
+		u-boot,dm-pre-reloc;
+	};
+
+	watchdog: watchdog@10212000 {
+		compatible = "mediatek,wdt";
+		reg = <0x10212000 0x600>;
+		interrupts = <GIC_SPI 128 IRQ_TYPE_EDGE_FALLING>;
+		#reset-cells = <1>;
+		status = "disabled";
+	};
+
+	wdt-reboot {
+		compatible = "wdt-reboot";
+		wdt = <&watchdog>;
+	};
+
+	pinctrl: pinctrl@10217000 {
+		compatible = "mediatek,mt7629-pinctrl";
+		reg = <0x10217000 0x8000>;
+
+		gpio: gpio-controller {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+	};
+
+	gic: interrupt-controller@10300000 {
+		compatible = "arm,gic-400";
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		interrupt-parent = <&gic>;
+		reg = <0x10310000 0x1000>,
+		      <0x10320000 0x1000>,
+		      <0x10340000 0x2000>,
+		      <0x10360000 0x2000>;
+	};
+
+	uart0: serial@11002000 {
+		compatible = "mediatek,hsuart";
+		reg = <0x11002000 0x400>;
+		reg-shift = <2>;
+		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_UART_SEL>,
+			 <&pericfg CLK_PERI_UART0_PD>;
+		clock-names = "baud", "bus";
+		status = "disabled";
+		assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>;
+		assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>;
+		u-boot,dm-pre-reloc;
+	};
+
+	uart1: serial@11003000 {
+		compatible = "mediatek,hsuart";
+		reg = <0x11003000 0x400>;
+		reg-shift = <2>;
+		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_UART_SEL>,
+			 <&pericfg CLK_PERI_UART1_PD>;
+		clock-names = "baud", "bus";
+		assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>;
+		assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>;
+		status = "disabled";
+	};
+
+	uart2: serial@11004000 {
+		compatible = "mediatek,hsuart";
+		reg = <0x11004000 0x400>;
+		reg-shift = <2>;
+		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_UART_SEL>,
+			 <&pericfg CLK_PERI_UART2_PD>;
+		clock-names = "baud", "bus";
+		assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>;
+		assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>;
+		status = "disabled";
+	};
+
+	qspi: qspi@11014000 {
+		compatible = "mediatek,mt7629-qspi";
+		reg = <0x11014000 0xe0>, <0x30000000 0x10000000>;
+		reg-names = "reg_base", "mem_base";
+		status = "disabled";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		u-boot,dm-pre-reloc;
+	};
+
+	ethsys: syscon@1b000000 {
+		compatible = "mediatek,mt7629-ethsys", "syscon";
+		reg = <0x1b000000 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	sgmiisys0: syscon@1b128000 {
+		compatible = "mediatek,mt7629-sgmiisys", "syscon";
+		reg = <0x1b128000 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	sgmiisys1: syscon@1b130000 {
+		compatible = "mediatek,mt7629-sgmiisys", "syscon";
+		reg = <0x1b130000 0x1000>;
+		#clock-cells = <1>;
+	};
+};
diff --git a/arch/arm/dts/r8a7790-lager.dts b/arch/arm/dts/r8a7790-lager.dts
index dcda98c..50312e7 100644
--- a/arch/arm/dts/r8a7790-lager.dts
+++ b/arch/arm/dts/r8a7790-lager.dts
@@ -899,9 +899,6 @@
 	status = "okay";
 
 	port {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
 		vin1ep0: endpoint {
 			remote-endpoint = <&adv7180>;
 			bus-width = <8>;
@@ -926,6 +923,11 @@
 	};
 };
 
+&rwdt {
+	timeout-sec = <60>;
+	status = "okay";
+};
+
 &ssi1 {
 	shared-pin;
 };
diff --git a/arch/arm/dts/r8a7790.dtsi b/arch/arm/dts/r8a7790.dtsi
index ed09e56..0925bdc 100644
--- a/arch/arm/dts/r8a7790.dtsi
+++ b/arch/arm/dts/r8a7790.dtsi
@@ -76,12 +76,12 @@
 			compatible = "arm,cortex-a15";
 			reg = <0>;
 			clock-frequency = <1300000000>;
-			voltage-tolerance = <1>; /* 1% */
 			clocks = <&cpg CPG_CORE R8A7790_CLK_Z>;
-			clock-latency = <300000>; /* 300 us */
 			power-domains = <&sysc R8A7790_PD_CA15_CPU0>;
 			next-level-cache = <&L2_CA15>;
 			capacity-dmips-mhz = <1024>;
+			voltage-tolerance = <1>; /* 1% */
+			clock-latency = <300000>; /* 300 us */
 
 			/* kHz - uV - OPPs unknown yet */
 			operating-points = <1400000 1000000>,
@@ -101,6 +101,16 @@
 			power-domains = <&sysc R8A7790_PD_CA15_CPU1>;
 			next-level-cache = <&L2_CA15>;
 			capacity-dmips-mhz = <1024>;
+			voltage-tolerance = <1>; /* 1% */
+			clock-latency = <300000>; /* 300 us */
+
+			/* kHz - uV - OPPs unknown yet */
+			operating-points = <1400000 1000000>,
+					   <1225000 1000000>,
+					   <1050000 1000000>,
+					   < 875000 1000000>,
+					   < 700000 1000000>,
+					   < 350000 1000000>;
 		};
 
 		cpu2: cpu@2 {
@@ -112,6 +122,16 @@
 			power-domains = <&sysc R8A7790_PD_CA15_CPU2>;
 			next-level-cache = <&L2_CA15>;
 			capacity-dmips-mhz = <1024>;
+			voltage-tolerance = <1>; /* 1% */
+			clock-latency = <300000>; /* 300 us */
+
+			/* kHz - uV - OPPs unknown yet */
+			operating-points = <1400000 1000000>,
+					   <1225000 1000000>,
+					   <1050000 1000000>,
+					   < 875000 1000000>,
+					   < 700000 1000000>,
+					   < 350000 1000000>;
 		};
 
 		cpu3: cpu@3 {
@@ -123,6 +143,16 @@
 			power-domains = <&sysc R8A7790_PD_CA15_CPU3>;
 			next-level-cache = <&L2_CA15>;
 			capacity-dmips-mhz = <1024>;
+			voltage-tolerance = <1>; /* 1% */
+			clock-latency = <300000>; /* 300 us */
+
+			/* kHz - uV - OPPs unknown yet */
+			operating-points = <1400000 1000000>,
+					   <1225000 1000000>,
+					   <1050000 1000000>,
+					   < 875000 1000000>,
+					   < 700000 1000000>,
+					   < 350000 1000000>;
 		};
 
 		cpu4: cpu@100 {
@@ -199,6 +229,24 @@
 		clock-frequency = <0>;
 	};
 
+	pmu-0 {
+		compatible = "arm,cortex-a15-pmu";
+		interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+	};
+
+	pmu-1 {
+		compatible = "arm,cortex-a7-pmu";
+		interrupts-extended = <&gic GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu4>, <&cpu5>, <&cpu6>, <&cpu7>;
+	};
+
 	/* External SCIF clock */
 	scif_clk: scif {
 		compatible = "fixed-clock";
@@ -215,6 +263,16 @@
 		#size-cells = <2>;
 		ranges;
 
+		rwdt: watchdog@e6020000 {
+			compatible = "renesas,r8a7790-wdt",
+				     "renesas,rcar-gen2-wdt";
+			reg = <0 0xe6020000 0 0x0c>;
+			clocks = <&cpg CPG_MOD 402>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 402>;
+			status = "disabled";
+		};
+
 		gpio0: gpio@e6050000 {
 			compatible = "renesas,gpio-r8a7790",
 				     "renesas,rcar-gen2-gpio";
@@ -440,7 +498,7 @@
 
 			smp-sram@0 {
 				compatible = "renesas,smp-sram";
-				reg = <0 0x10>;
+				reg = <0 0x100>;
 			};
 		};
 
@@ -1541,7 +1599,7 @@
 			interrupt-controller;
 			reg = <0 0xf1001000 0 0x1000>, <0 0xf1002000 0 0x2000>,
 			      <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>;
-			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
 			clocks = <&cpg CPG_MOD 408>;
 			clock-names = "clk";
 			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
@@ -1612,6 +1670,33 @@
 			resets = <&cpg 127>;
 		};
 
+		fdp1@fe940000 {
+			compatible = "renesas,fdp1";
+			reg = <0 0xfe940000 0 0x2400>;
+			interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 119>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 119>;
+		};
+
+		fdp1@fe944000 {
+			compatible = "renesas,fdp1";
+			reg = <0 0xfe944000 0 0x2400>;
+			interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 118>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 118>;
+		};
+
+		fdp1@fe948000 {
+			compatible = "renesas,fdp1";
+			reg = <0 0xfe948000 0 0x2400>;
+			interrupts = <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 117>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 117>;
+		};
+
 		jpu: jpeg-codec@fe980000 {
 			compatible = "renesas,jpu-r8a7790",
 				     "renesas,rcar-gen2-jpu";
@@ -1770,10 +1855,10 @@
 
 	timer {
 		compatible = "arm,armv7-timer";
-		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
 	};
 
 	/* External USB clock - can be overridden by the board */
diff --git a/arch/arm/dts/r8a7791-koelsch.dts b/arch/arm/dts/r8a7791-koelsch.dts
index be96bfd..ce22db0 100644
--- a/arch/arm/dts/r8a7791-koelsch.dts
+++ b/arch/arm/dts/r8a7791-koelsch.dts
@@ -640,6 +640,11 @@
 	status = "okay";
 };
 
+&rwdt {
+	timeout-sec = <60>;
+	status = "okay";
+};
+
 &sata0 {
 	status = "okay";
 };
@@ -847,9 +852,6 @@
 	pinctrl-names = "default";
 
 	port {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
 		vin0ep2: endpoint {
 			remote-endpoint = <&adv7612_out>;
 			bus-width = <24>;
@@ -868,9 +870,6 @@
 	pinctrl-names = "default";
 
 	port {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
 		vin1ep: endpoint {
 			remote-endpoint = <&adv7180>;
 			bus-width = <8>;
diff --git a/arch/arm/dts/r8a7791-porter-u-boot.dts b/arch/arm/dts/r8a7791-porter-u-boot.dts
index 797fa9d..275f6b4 100644
--- a/arch/arm/dts/r8a7791-porter-u-boot.dts
+++ b/arch/arm/dts/r8a7791-porter-u-boot.dts
@@ -11,3 +11,8 @@
 &scif0 {
 	u-boot,dm-pre-reloc;
 };
+
+&i2c6 {
+	status = "okay";
+	clock-frequency = <400000>;
+};
diff --git a/arch/arm/dts/r8a7791-porter.dts b/arch/arm/dts/r8a7791-porter.dts
index fa9a57d..f02036e 100644
--- a/arch/arm/dts/r8a7791-porter.dts
+++ b/arch/arm/dts/r8a7791-porter.dts
@@ -374,13 +374,41 @@
 
 &i2c6 {
 	status = "okay";
-	clock-frequency = <400000>;
+	clock-frequency = <100000>;
+
+	pmic@5a {
+		compatible = "dlg,da9063l";
+		reg = <0x5a>;
+		interrupt-parent = <&irqc0>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-controller;
+
+		wdt {
+			compatible = "dlg,da9063-watchdog";
+		};
+	};
+
+	vdd_dvfs: regulator@68 {
+		compatible = "dlg,da9210";
+		reg = <0x68>;
+		interrupt-parent = <&irqc0>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+
+		regulator-min-microvolt = <1000000>;
+		regulator-max-microvolt = <1000000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
 };
 
 &sata0 {
 	status = "okay";
 };
 
+&cpu0 {
+	cpu0-supply = <&vdd_dvfs>;
+};
+
 /* composite video input */
 &vin0 {
 	status = "okay";
@@ -388,9 +416,6 @@
 	pinctrl-names = "default";
 
 	port {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
 		vin0ep: endpoint {
 			remote-endpoint = <&adv7180>;
 			bus-width = <8>;
@@ -483,6 +508,11 @@
 	};
 };
 
+&rwdt {
+	timeout-sec = <60>;
+	status = "okay";
+};
+
 &ssi1 {
 	shared-pin;
 };
diff --git a/arch/arm/dts/r8a7791.dtsi b/arch/arm/dts/r8a7791.dtsi
index d728738..991ac6f 100644
--- a/arch/arm/dts/r8a7791.dtsi
+++ b/arch/arm/dts/r8a7791.dtsi
@@ -75,11 +75,11 @@
 			compatible = "arm,cortex-a15";
 			reg = <0>;
 			clock-frequency = <1500000000>;
-			voltage-tolerance = <1>; /* 1% */
 			clocks = <&cpg CPG_CORE R8A7791_CLK_Z>;
-			clock-latency = <300000>; /* 300 us */
 			power-domains = <&sysc R8A7791_PD_CA15_CPU0>;
 			next-level-cache = <&L2_CA15>;
+			voltage-tolerance = <1>; /* 1% */
+			clock-latency = <300000>; /* 300 us */
 
 			/* kHz - uV - OPPs unknown yet */
 			operating-points = <1500000 1000000>,
@@ -98,6 +98,16 @@
 			clocks = <&cpg CPG_CORE R8A7791_CLK_Z>;
 			power-domains = <&sysc R8A7791_PD_CA15_CPU1>;
 			next-level-cache = <&L2_CA15>;
+			voltage-tolerance = <1>; /* 1% */
+			clock-latency = <300000>; /* 300 us */
+
+			/* kHz - uV - OPPs unknown yet */
+			operating-points = <1500000 1000000>,
+					   <1312500 1000000>,
+					   <1125000 1000000>,
+					   < 937500 1000000>,
+					   < 750000 1000000>,
+					   < 375000 1000000>;
 		};
 
 		L2_CA15: cache-controller-0 {
@@ -123,6 +133,13 @@
 		clock-frequency = <0>;
 	};
 
+	pmu {
+		compatible = "arm,cortex-a15-pmu";
+		interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>;
+	};
+
 	/* External SCIF clock */
 	scif_clk: scif {
 		compatible = "fixed-clock";
@@ -139,6 +156,16 @@
 		#size-cells = <2>;
 		ranges;
 
+		rwdt: watchdog@e6020000 {
+			compatible = "renesas,r8a7791-wdt",
+				     "renesas,rcar-gen2-wdt";
+			reg = <0 0xe6020000 0 0x0c>;
+			clocks = <&cpg CPG_MOD 402>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 402>;
+			status = "disabled";
+		};
+
 		gpio0: gpio@e6050000 {
 			compatible = "renesas,gpio-r8a7791",
 				     "renesas,rcar-gen2-gpio";
@@ -404,7 +431,7 @@
 
 			smp-sram@0 {
 				compatible = "renesas,smp-sram";
-				reg = <0 0x10>;
+				reg = <0 0x100>;
 			};
 		};
 
@@ -1618,6 +1645,24 @@
 			resets = <&cpg 127>;
 		};
 
+		fdp1@fe940000 {
+			compatible = "renesas,fdp1";
+			reg = <0 0xfe940000 0 0x2400>;
+			interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 119>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 119>;
+		};
+
+		fdp1@fe944000 {
+			compatible = "renesas,fdp1";
+			reg = <0 0xfe944000 0 0x2400>;
+			interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 118>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 118>;
+		};
+
 		jpu: jpeg-codec@fe980000 {
 			compatible = "renesas,jpu-r8a7791",
 				     "renesas,rcar-gen2-jpu";
diff --git a/arch/arm/dts/r8a7792-blanche.dts b/arch/arm/dts/r8a7792-blanche.dts
index 023d870..f923012 100644
--- a/arch/arm/dts/r8a7792-blanche.dts
+++ b/arch/arm/dts/r8a7792-blanche.dts
@@ -236,6 +236,11 @@
 	};
 };
 
+&rwdt {
+	timeout-sec = <60>;
+	status = "okay";
+};
+
 &scif0 {
 	pinctrl-0 = <&scif0_pins>;
 	pinctrl-names = "default";
diff --git a/arch/arm/dts/r8a7792.dtsi b/arch/arm/dts/r8a7792.dtsi
index 8e26ded..63a978e 100644
--- a/arch/arm/dts/r8a7792.dtsi
+++ b/arch/arm/dts/r8a7792.dtsi
@@ -82,6 +82,13 @@
 		clock-frequency = <0>;
 	};
 
+	pmu {
+		compatible = "arm,cortex-a15-pmu";
+		interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>;
+	};
+
 	/* External SCIF clock */
 	scif_clk: scif {
 		compatible = "fixed-clock";
@@ -98,6 +105,16 @@
 		#size-cells = <2>;
 		ranges;
 
+		rwdt: watchdog@e6020000 {
+			compatible = "renesas,r8a7792-wdt",
+				     "renesas,rcar-gen2-wdt";
+			reg = <0 0xe6020000 0 0x0c>;
+			clocks = <&cpg CPG_MOD 402>;
+			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+			resets = <&cpg 402>;
+			status = "disabled";
+		};
+
 		gpio0: gpio@e6050000 {
 			compatible = "renesas,gpio-r8a7792",
 				     "renesas,rcar-gen2-gpio";
@@ -338,7 +355,7 @@
 
 			smp-sram@0 {
 				compatible = "renesas,smp-sram";
-				reg = <0 0x10>;
+				reg = <0 0x100>;
 			};
 		};
 
diff --git a/arch/arm/dts/r8a7793-gose.dts b/arch/arm/dts/r8a7793-gose.dts
index 9c89345..6b2f3a4 100644
--- a/arch/arm/dts/r8a7793-gose.dts
+++ b/arch/arm/dts/r8a7793-gose.dts
@@ -596,6 +596,11 @@
 	status = "okay";
 };
 
+&rwdt {
+	timeout-sec = <60>;
+	status = "okay";
+};
+
 &scif0 {
 	pinctrl-0 = <&scif0_pins>;
 	pinctrl-names = "default";
@@ -755,9 +760,6 @@
 	pinctrl-names = "default";
 
 	port {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
 		vin0ep2: endpoint {
 			remote-endpoint = <&adv7612_out>;
 			bus-width = <24>;
@@ -777,9 +779,6 @@
 	status = "okay";
 
 	port {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
 		vin1ep: endpoint {
 			remote-endpoint = <&adv7180_out>;
 			bus-width = <8>;
diff --git a/arch/arm/dts/r8a7793.dtsi b/arch/arm/dts/r8a7793.dtsi
index 8201b4e..620a570 100644
--- a/arch/arm/dts/r8a7793.dtsi
+++ b/arch/arm/dts/r8a7793.dtsi
@@ -67,10 +67,10 @@
 			compatible = "arm,cortex-a15";
 			reg = <0>;
 			clock-frequency = <1500000000>;
-			voltage-tolerance = <1>; /* 1% */
 			clocks = <&cpg CPG_CORE R8A7793_CLK_Z>;
-			clock-latency = <300000>; /* 300 us */
 			power-domains = <&sysc R8A7793_PD_CA15_CPU0>;
+			voltage-tolerance = <1>; /* 1% */
+			clock-latency = <300000>; /* 300 us */
 
 			/* kHz - uV - OPPs unknown yet */
 			operating-points = <1500000 1000000>,
@@ -89,6 +89,17 @@
 			clock-frequency = <1500000000>;
 			clocks = <&cpg CPG_CORE R8A7793_CLK_Z>;
 			power-domains = <&sysc R8A7793_PD_CA15_CPU1>;
+			voltage-tolerance = <1>; /* 1% */
+			clock-latency = <300000>; /* 300 us */
+
+			/* kHz - uV - OPPs unknown yet */
+			operating-points = <1500000 1000000>,
+					   <1312500 1000000>,
+					   <1125000 1000000>,
+					   < 937500 1000000>,
+					   < 750000 1000000>,
+					   < 375000 1000000>;
+			next-level-cache = <&L2_CA15>;
 		};
 
 		L2_CA15: cache-controller-0 {
@@ -107,6 +118,13 @@
 		clock-frequency = <0>;
 	};
 
+	pmu {
+		compatible = "arm,cortex-a15-pmu";
+		interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>;
+	};
+
 	/* External SCIF clock */
 	scif_clk: scif {
 		compatible = "fixed-clock";
@@ -123,6 +141,16 @@
 		#size-cells = <2>;
 		ranges;
 
+		rwdt: watchdog@e6020000 {
+			compatible = "renesas,r8a7793-wdt",
+				     "renesas,rcar-gen2-wdt";
+			reg = <0 0xe6020000 0 0x0c>;
+			clocks = <&cpg CPG_MOD 402>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 402>;
+			status = "disabled";
+		};
+
 		gpio0: gpio@e6050000 {
 			compatible = "renesas,gpio-r8a7793",
 				     "renesas,rcar-gen2-gpio";
@@ -389,7 +417,7 @@
 
 			smp-sram@0 {
 				compatible = "renesas,smp-sram";
-				reg = <0 0x10>;
+				reg = <0 0x100>;
 			};
 		};
 
@@ -1287,6 +1315,24 @@
 			resets = <&cpg 408>;
 		};
 
+		fdp1@fe940000 {
+			compatible = "renesas,fdp1";
+			reg = <0 0xfe940000 0 0x2400>;
+			interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 119>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 119>;
+		};
+
+		fdp1@fe944000 {
+			compatible = "renesas,fdp1";
+			reg = <0 0xfe944000 0 0x2400>;
+			interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 118>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 118>;
+		};
+
 		du: display@feb00000 {
 			compatible = "renesas,du-r8a7793";
 			reg = <0 0xfeb00000 0 0x40000>;
diff --git a/arch/arm/dts/r8a7794-alt.dts b/arch/arm/dts/r8a7794-alt.dts
index af3c67e..ef7e2a8 100644
--- a/arch/arm/dts/r8a7794-alt.dts
+++ b/arch/arm/dts/r8a7794-alt.dts
@@ -178,6 +178,12 @@
 				};
 			};
 		};
+
+		eeprom@50 {
+			compatible = "renesas,r1ex24002", "atmel,24c02";
+			reg = <0x50>;
+			pagesize = <16>;
+		};
 	};
 
 	/*
@@ -327,6 +333,11 @@
 	status = "okay";
 };
 
+&rwdt {
+	timeout-sec = <60>;
+	status = "okay";
+};
+
 &sdhi0 {
 	pinctrl-0 = <&sdhi0_pins>;
 	pinctrl-1 = <&sdhi0_pins_uhs>;
@@ -372,9 +383,6 @@
 	pinctrl-names = "default";
 
 	port {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
 		vin0ep: endpoint {
 			remote-endpoint = <&adv7180>;
 			bus-width = <8>;
diff --git a/arch/arm/dts/r8a7794-silk.dts b/arch/arm/dts/r8a7794-silk.dts
index 50dad43..daec965 100644
--- a/arch/arm/dts/r8a7794-silk.dts
+++ b/arch/arm/dts/r8a7794-silk.dts
@@ -472,9 +472,6 @@
 	pinctrl-names = "default";
 
 	port {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
 		vin0ep: endpoint {
 			remote-endpoint = <&adv7180>;
 			bus-width = <8>;
@@ -537,6 +534,11 @@
 	};
 };
 
+&rwdt {
+	timeout-sec = <60>;
+	status = "okay";
+};
+
 &ssi1 {
 	shared-pin;
 };
diff --git a/arch/arm/dts/r8a7794.dtsi b/arch/arm/dts/r8a7794.dtsi
index 0cc07b3..ea2ca4bdaf 100644
--- a/arch/arm/dts/r8a7794.dtsi
+++ b/arch/arm/dts/r8a7794.dtsi
@@ -100,6 +100,13 @@
 		clock-frequency = <0>;
 	};
 
+	pmu {
+		compatible = "arm,cortex-a7-pmu";
+		interrupts-extended = <&gic GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>;
+	};
+
 	/* External SCIF clock */
 	scif_clk: scif {
 		compatible = "fixed-clock";
@@ -116,6 +123,16 @@
 		#size-cells = <2>;
 		ranges;
 
+		rwdt: watchdog@e6020000 {
+			compatible = "renesas,r8a7794-wdt",
+				     "renesas,rcar-gen2-wdt";
+			reg = <0 0xe6020000 0 0x0c>;
+			clocks = <&cpg CPG_MOD 402>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 402>;
+			status = "disabled";
+		};
+
 		gpio0: gpio@e6050000 {
 			compatible = "renesas,gpio-r8a7794",
 				     "renesas,rcar-gen2-gpio";
@@ -345,7 +362,7 @@
 
 			smp-sram@0 {
 				compatible = "renesas,smp-sram";
-				reg = <0 0x10>;
+				reg = <0 0x100>;
 			};
 		};
 
@@ -1320,6 +1337,15 @@
 			resets = <&cpg 128>;
 		};
 
+		fdp1@fe940000 {
+			compatible = "renesas,fdp1";
+			reg = <0 0xfe940000 0 0x2400>;
+			interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 119>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 119>;
+		};
+
 		du: display@feb00000 {
 			compatible = "renesas,du-r8a7794";
 			reg = <0 0xfeb00000 0 0x40000>;
diff --git a/arch/arm/dts/r8a7795-h3ulcb-u-boot.dts b/arch/arm/dts/r8a7795-h3ulcb-u-boot.dts
index 06bd4f2..ebbd234 100644
--- a/arch/arm/dts/r8a7795-h3ulcb-u-boot.dts
+++ b/arch/arm/dts/r8a7795-h3ulcb-u-boot.dts
@@ -7,3 +7,35 @@
 
 #include "r8a7795-h3ulcb.dts"
 #include "r8a7795-u-boot.dtsi"
+
+/ {
+	cpld {
+		compatible = "renesas,ulcb-cpld";
+		status = "okay";
+		gpio-sck = <&gpio6 8 0>;
+		gpio-mosi = <&gpio6 7 0>;
+		gpio-miso = <&gpio6 10 0>;
+		gpio-sstbz = <&gpio2 3 0>;
+	};
+};
+
+&sdhi2_pins {
+	groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
+	power-source = <1800>;
+};
+
+&sdhi2_pins_uhs {
+	groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
+};
+
+&sdhi0 {
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr104;
+	max-frequency = <208000000>;
+};
+
+&sdhi2 {
+	mmc-hs400-1_8v;
+	max-frequency = <200000000>;
+};
diff --git a/arch/arm/dts/r8a7795-salvator-x-u-boot.dts b/arch/arm/dts/r8a7795-salvator-x-u-boot.dts
index 666fbf5..8be5e41 100644
--- a/arch/arm/dts/r8a7795-salvator-x-u-boot.dts
+++ b/arch/arm/dts/r8a7795-salvator-x-u-boot.dts
@@ -7,3 +7,31 @@
 
 #include "r8a7795-salvator-x.dts"
 #include "r8a7795-u-boot.dtsi"
+
+&sdhi2_pins {
+	groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
+	power-source = <1800>;
+};
+
+&sdhi2_pins_uhs {
+	groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
+};
+
+&sdhi0 {
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr104;
+	max-frequency = <208000000>;
+};
+
+&sdhi2 {
+	mmc-hs400-1_8v;
+	max-frequency = <200000000>;
+};
+
+&sdhi3 {
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr104;
+	max-frequency = <208000000>;
+};
diff --git a/arch/arm/dts/r8a7795-salvator-x.dts b/arch/arm/dts/r8a7795-salvator-x.dts
index 36373d6..446822f 100644
--- a/arch/arm/dts/r8a7795-salvator-x.dts
+++ b/arch/arm/dts/r8a7795-salvator-x.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the Salvator-X board
+ * Device Tree Source for the Salvator-X board with R-Car H3 ES2.0
  *
  * Copyright (C) 2015 Renesas Electronics Corp.
  */
@@ -53,6 +53,12 @@
 	status = "okay";
 };
 
+&sound_card {
+	dais = <&rsnd_port0	/* ak4613 */
+		&rsnd_port1	/* HDMI0  */
+		&rsnd_port2>;	/* HDMI1  */
+};
+
 &hdmi0 {
 	status = "okay";
 
@@ -63,6 +69,12 @@
 				remote-endpoint = <&hdmi0_con>;
 			};
 		};
+		port@2 {
+			reg = <2>;
+			dw_hdmi0_snd_in: endpoint {
+				remote-endpoint = <&rsnd_endpoint1>;
+			};
+		};
 	};
 };
 
@@ -80,6 +92,12 @@
 				remote-endpoint = <&hdmi1_con>;
 			};
 		};
+		port@2 {
+			reg = <2>;
+			dw_hdmi1_snd_in: endpoint {
+				remote-endpoint = <&rsnd_endpoint2>;
+			};
+		};
 	};
 };
 
@@ -91,6 +109,34 @@
 	status = "okay";
 };
 
+&rcar_sound {
+	ports {
+		/* rsnd_port0 is on salvator-common */
+		rsnd_port1: port@1 {
+			rsnd_endpoint1: endpoint {
+				remote-endpoint = <&dw_hdmi0_snd_in>;
+
+				dai-format = "i2s";
+				bitclock-master = <&rsnd_endpoint1>;
+				frame-master = <&rsnd_endpoint1>;
+
+				playback = <&ssi2>;
+			};
+		};
+		rsnd_port2: port@2 {
+			rsnd_endpoint2: endpoint {
+				remote-endpoint = <&dw_hdmi1_snd_in>;
+
+				dai-format = "i2s";
+				bitclock-master = <&rsnd_endpoint2>;
+				frame-master = <&rsnd_endpoint2>;
+
+				playback = <&ssi3>;
+			};
+		};
+	};
+};
+
 &pfc {
 	usb2_pins: usb2 {
 		groups = "usb2";
diff --git a/arch/arm/dts/r8a7795-u-boot.dtsi b/arch/arm/dts/r8a7795-u-boot.dtsi
index 526966a..cc22c57 100644
--- a/arch/arm/dts/r8a7795-u-boot.dtsi
+++ b/arch/arm/dts/r8a7795-u-boot.dtsi
@@ -10,3 +10,13 @@
 &extalr_clk {
 	u-boot,dm-pre-reloc;
 };
+
+&soc {
+	rpc: rpc@0xee200000 {
+		compatible = "renesas,rpc-r8a7795", "renesas,rpc";
+		reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>;
+		clocks = <&cpg CPG_MOD 917>;
+		bank-width = <2>;
+		status = "disabled";
+	};
+};
diff --git a/arch/arm/dts/r8a7795.dtsi b/arch/arm/dts/r8a7795.dtsi
index af77bfe..c87eed7 100644
--- a/arch/arm/dts/r8a7795.dtsi
+++ b/arch/arm/dts/r8a7795.dtsi
@@ -27,6 +27,91 @@
 		i2c7 = &i2c_dvfs;
 	};
 
+	/*
+	 * The external audio clocks are configured as 0 Hz fixed frequency
+	 * clocks by default.
+	 * Boards that provide audio clocks should override them.
+	 */
+	audio_clk_a: audio_clk_a {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	audio_clk_b: audio_clk_b {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	audio_clk_c: audio_clk_c {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	/* External CAN clock - to be overridden by boards that provide it */
+	can_clk: can {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	cluster0_opp: opp_table0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-500000000 {
+			opp-hz = /bits/ 64 <500000000>;
+			opp-microvolt = <830000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1000000000 {
+			opp-hz = /bits/ 64 <1000000000>;
+			opp-microvolt = <830000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1500000000 {
+			opp-hz = /bits/ 64 <1500000000>;
+			opp-microvolt = <830000>;
+			clock-latency-ns = <300000>;
+			opp-suspend;
+		};
+		opp-1600000000 {
+			opp-hz = /bits/ 64 <1600000000>;
+			opp-microvolt = <900000>;
+			clock-latency-ns = <300000>;
+			turbo-mode;
+		};
+		opp-1700000000 {
+			opp-hz = /bits/ 64 <1700000000>;
+			opp-microvolt = <960000>;
+			clock-latency-ns = <300000>;
+			turbo-mode;
+		};
+	};
+
+	cluster1_opp: opp_table1 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-800000000 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1000000000 {
+			opp-hz = /bits/ 64 <1000000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -44,7 +129,7 @@
 		};
 
 		a57_1: cpu@1 {
-			compatible = "arm,cortex-a57","arm,armv8";
+			compatible = "arm,cortex-a57", "arm,armv8";
 			reg = <0x1>;
 			device_type = "cpu";
 			power-domains = <&sysc R8A7795_PD_CA57_CPU1>;
@@ -56,7 +141,7 @@
 		};
 
 		a57_2: cpu@2 {
-			compatible = "arm,cortex-a57","arm,armv8";
+			compatible = "arm,cortex-a57", "arm,armv8";
 			reg = <0x2>;
 			device_type = "cpu";
 			power-domains = <&sysc R8A7795_PD_CA57_CPU2>;
@@ -68,7 +153,7 @@
 		};
 
 		a57_3: cpu@3 {
-			compatible = "arm,cortex-a57","arm,armv8";
+			compatible = "arm,cortex-a57", "arm,armv8";
 			reg = <0x3>;
 			device_type = "cpu";
 			power-domains = <&sysc R8A7795_PD_CA57_CPU3>;
@@ -91,7 +176,7 @@
 		};
 
 		a53_1: cpu@101 {
-			compatible = "arm,cortex-a53","arm,armv8";
+			compatible = "arm,cortex-a53", "arm,armv8";
 			reg = <0x101>;
 			device_type = "cpu";
 			power-domains = <&sysc R8A7795_PD_CA53_CPU1>;
@@ -102,7 +187,7 @@
 		};
 
 		a53_2: cpu@102 {
-			compatible = "arm,cortex-a53","arm,armv8";
+			compatible = "arm,cortex-a53", "arm,armv8";
 			reg = <0x102>;
 			device_type = "cpu";
 			power-domains = <&sysc R8A7795_PD_CA53_CPU2>;
@@ -113,7 +198,7 @@
 		};
 
 		a53_3: cpu@103 {
-			compatible = "arm,cortex-a53","arm,armv8";
+			compatible = "arm,cortex-a53", "arm,armv8";
 			reg = <0x103>;
 			device_type = "cpu";
 			power-domains = <&sysc R8A7795_PD_CA53_CPU3>;
@@ -152,91 +237,6 @@
 		clock-frequency = <0>;
 	};
 
-	/*
-	 * The external audio clocks are configured as 0 Hz fixed frequency
-	 * clocks by default.
-	 * Boards that provide audio clocks should override them.
-	 */
-	audio_clk_a: audio_clk_a {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-
-	audio_clk_b: audio_clk_b {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-
-	audio_clk_c: audio_clk_c {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-
-	/* External CAN clock - to be overridden by boards that provide it */
-	can_clk: can {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-
-	cluster0_opp: opp_table0 {
-		compatible = "operating-points-v2";
-		opp-shared;
-
-		opp-500000000 {
-			opp-hz = /bits/ 64 <500000000>;
-			opp-microvolt = <830000>;
-			clock-latency-ns = <300000>;
-		};
-		opp-1000000000 {
-			opp-hz = /bits/ 64 <1000000000>;
-			opp-microvolt = <830000>;
-			clock-latency-ns = <300000>;
-		};
-		opp-1500000000 {
-			opp-hz = /bits/ 64 <1500000000>;
-			opp-microvolt = <830000>;
-			clock-latency-ns = <300000>;
-			opp-suspend;
-		};
-		opp-1600000000 {
-			opp-hz = /bits/ 64 <1600000000>;
-			opp-microvolt = <900000>;
-			clock-latency-ns = <300000>;
-			turbo-mode;
-		};
-		opp-1700000000 {
-			opp-hz = /bits/ 64 <1700000000>;
-			opp-microvolt = <960000>;
-			clock-latency-ns = <300000>;
-			turbo-mode;
-		};
-	};
-
-	cluster1_opp: opp_table1 {
-		compatible = "operating-points-v2";
-		opp-shared;
-
-		opp-800000000 {
-			opp-hz = /bits/ 64 <800000000>;
-			opp-microvolt = <820000>;
-			clock-latency-ns = <300000>;
-		};
-		opp-1000000000 {
-			opp-hz = /bits/ 64 <1000000000>;
-			opp-microvolt = <820000>;
-			clock-latency-ns = <300000>;
-		};
-		opp-1200000000 {
-			opp-hz = /bits/ 64 <1200000000>;
-			opp-microvolt = <820000>;
-			clock-latency-ns = <300000>;
-		};
-	};
-
 	/* External PCIe clock - can be overridden by the board */
 	pcie_bus_clk: pcie_bus {
 		compatible = "fixed-clock";
@@ -244,18 +244,6 @@
 		clock-frequency = <0>;
 	};
 
-	pmu_a57 {
-		compatible = "arm,cortex-a57-pmu";
-		interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
-		                      <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
-				      <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
-				      <&gic GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-affinity = <&a57_0>,
-				     <&a57_1>,
-				     <&a57_2>,
-				     <&a57_3>;
-	};
-
 	pmu_a53 {
 		compatible = "arm,cortex-a53-pmu";
 		interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
@@ -268,6 +256,18 @@
 				     <&a53_3>;
 	};
 
+	pmu_a57 {
+		compatible = "arm,cortex-a57-pmu";
+		interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&a57_0>,
+				     <&a57_1>,
+				     <&a57_2>,
+				     <&a57_3>;
+	};
+
 	psci {
 		compatible = "arm,psci-1.0", "arm,psci-0.2";
 		method = "smc";
@@ -288,24 +288,7 @@
 		#size-cells = <2>;
 		ranges;
 
-		gic: interrupt-controller@f1010000 {
-			compatible = "arm,gic-400";
-			#interrupt-cells = <3>;
-			#address-cells = <0>;
-			interrupt-controller;
-			reg = <0x0 0xf1010000 0 0x1000>,
-			      <0x0 0xf1020000 0 0x20000>,
-			      <0x0 0xf1040000 0 0x20000>,
-			      <0x0 0xf1060000 0 0x20000>;
-			interrupts = <GIC_PPI 9
-					(GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
-			clocks = <&cpg CPG_MOD 408>;
-			clock-names = "clk";
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 408>;
-		};
-
-		wdt0: watchdog@e6020000 {
+		rwdt: watchdog@e6020000 {
 			compatible = "renesas,r8a7795-wdt", "renesas,rcar-gen3-wdt";
 			reg = <0 0xe6020000 0 0x0c>;
 			clocks = <&cpg CPG_MOD 402>;
@@ -434,6 +417,11 @@
 			resets = <&cpg 905>;
 		};
 
+		pfc: pin-controller@e6060000 {
+			compatible = "renesas,pfc-r8a7795";
+			reg = <0 0xe6060000 0 0x50c>;
+		};
+
 		cpg: clock-controller@e6150000 {
 			compatible = "renesas,r8a7795-cpg-mssr";
 			reg = <0 0xe6150000 0 0x1000>;
@@ -449,20 +437,25 @@
 			reg = <0 0xe6160000 0 0x0200>;
 		};
 
-		prr: chipid@fff00044 {
-			compatible = "renesas,prr";
-			reg = <0 0xfff00044 0 4>;
-		};
-
 		sysc: system-controller@e6180000 {
 			compatible = "renesas,r8a7795-sysc";
 			reg = <0 0xe6180000 0 0x0400>;
 			#power-domain-cells = <1>;
 		};
 
-		pfc: pin-controller@e6060000 {
-			compatible = "renesas,pfc-r8a7795";
-			reg = <0 0xe6060000 0 0x50c>;
+		tsc: thermal@e6198000 {
+			compatible = "renesas,r8a7795-thermal";
+			reg = <0 0xe6198000 0 0x100>,
+			      <0 0xe61a0000 0 0x100>,
+			      <0 0xe61a8000 0 0x100>;
+			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 522>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 522>;
+			#thermal-sensor-cells = <1>;
+			status = "okay";
 		};
 
 		intc_ex: interrupt-controller@e61c0000 {
@@ -481,155 +474,337 @@
 			resets = <&cpg 407>;
 		};
 
-		ipmmu_vi0: mmu@febd0000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xfebd0000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 14>;
+		i2c0: i2c@e6500000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7795",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6500000 0 0x40>;
+			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 931>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
-		};
-
-		ipmmu_vi1: mmu@febe0000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xfebe0000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 15>;
+			resets = <&cpg 931>;
+			dmas = <&dmac1 0x91>, <&dmac1 0x90>,
+			       <&dmac2 0x91>, <&dmac2 0x90>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <110>;
+			status = "disabled";
+		};
+
+		i2c1: i2c@e6508000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7795",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6508000 0 0x40>;
+			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 930>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
+			resets = <&cpg 930>;
+			dmas = <&dmac1 0x93>, <&dmac1 0x92>,
+			       <&dmac2 0x93>, <&dmac2 0x92>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
 			status = "disabled";
 		};
 
-		ipmmu_vp0: mmu@fe990000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xfe990000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 16>;
-			power-domains = <&sysc R8A7795_PD_A3VP>;
-			#iommu-cells = <1>;
+		i2c2: i2c@e6510000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7795",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6510000 0 0x40>;
+			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 929>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 929>;
+			dmas = <&dmac1 0x95>, <&dmac1 0x94>,
+			       <&dmac2 0x95>, <&dmac2 0x94>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
 			status = "disabled";
 		};
 
-		ipmmu_vp1: mmu@fe980000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xfe980000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 17>;
-			power-domains = <&sysc R8A7795_PD_A3VP>;
-			#iommu-cells = <1>;
+		arm_cc630p: crypto@e6601000 {
+			compatible = "arm,cryptocell-630p-ree";
+			interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+			reg = <0x0 0xe6601000 0 0x1000>;
+			clocks = <&cpg CPG_MOD 229>;
+			resets = <&cpg 229>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 		};
 
-		ipmmu_vc0: mmu@fe6b0000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xfe6b0000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 12>;
-			power-domains = <&sysc R8A7795_PD_A3VC>;
-			#iommu-cells = <1>;
+		i2c3: i2c@e66d0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7795",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66d0000 0 0x40>;
+			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 928>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 928>;
+			dmas = <&dmac0 0x97>, <&dmac0 0x96>;
+			dma-names = "tx", "rx";
+			i2c-scl-internal-delay-ns = <110>;
 			status = "disabled";
 		};
 
-		ipmmu_vc1: mmu@fe6f0000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xfe6f0000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 13>;
-			power-domains = <&sysc R8A7795_PD_A3VC>;
-			#iommu-cells = <1>;
+		i2c4: i2c@e66d8000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7795",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66d8000 0 0x40>;
+			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 927>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 927>;
+			dmas = <&dmac0 0x99>, <&dmac0 0x98>;
+			dma-names = "tx", "rx";
+			i2c-scl-internal-delay-ns = <110>;
 			status = "disabled";
 		};
 
-		ipmmu_pv0: mmu@fd800000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xfd800000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 6>;
+		i2c5: i2c@e66e0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7795",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66e0000 0 0x40>;
+			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 919>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
+			resets = <&cpg 919>;
+			dmas = <&dmac0 0x9b>, <&dmac0 0x9a>;
+			dma-names = "tx", "rx";
+			i2c-scl-internal-delay-ns = <110>;
 			status = "disabled";
 		};
 
-		ipmmu_pv1: mmu@fd950000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xfd950000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 7>;
+		i2c6: i2c@e66e8000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7795",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66e8000 0 0x40>;
+			interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 918>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
+			resets = <&cpg 918>;
+			dmas = <&dmac0 0x9d>, <&dmac0 0x9c>;
+			dma-names = "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
 			status = "disabled";
 		};
 
-		ipmmu_pv2: mmu@fd960000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xfd960000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 8>;
+		i2c_dvfs: i2c@e60b0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,iic-r8a7795",
+				     "renesas,rcar-gen3-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe60b0000 0 0x425>;
+			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 926>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
+			resets = <&cpg 926>;
+			dmas = <&dmac0 0x11>, <&dmac0 0x10>;
+			dma-names = "tx", "rx";
 			status = "disabled";
 		};
 
-		ipmmu_pv3: mmu@fd970000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xfd970000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 9>;
+		hscif0: serial@e6540000 {
+			compatible = "renesas,hscif-r8a7795",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe6540000 0 96>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 520>,
+				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x31>, <&dmac1 0x30>,
+			       <&dmac2 0x31>, <&dmac2 0x30>;
+			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
+			resets = <&cpg 520>;
 			status = "disabled";
 		};
 
-		ipmmu_ir: mmu@ff8b0000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xff8b0000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 3>;
-			power-domains = <&sysc R8A7795_PD_A3IR>;
-			#iommu-cells = <1>;
+		hscif1: serial@e6550000 {
+			compatible = "renesas,hscif-r8a7795",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe6550000 0 96>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 519>,
+				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x33>, <&dmac1 0x32>,
+			       <&dmac2 0x33>, <&dmac2 0x32>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 519>;
 			status = "disabled";
 		};
 
-		ipmmu_hc: mmu@e6570000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xe6570000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 2>;
+		hscif2: serial@e6560000 {
+			compatible = "renesas,hscif-r8a7795",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe6560000 0 96>;
+			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 518>,
+				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x35>, <&dmac1 0x34>,
+			       <&dmac2 0x35>, <&dmac2 0x34>;
+			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
+			resets = <&cpg 518>;
 			status = "disabled";
 		};
 
-		ipmmu_rt: mmu@ffc80000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xffc80000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 10>;
+		hscif3: serial@e66a0000 {
+			compatible = "renesas,hscif-r8a7795",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe66a0000 0 96>;
+			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 517>,
+				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x37>, <&dmac0 0x36>;
+			dma-names = "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
+			resets = <&cpg 517>;
 			status = "disabled";
 		};
 
-		ipmmu_mp0: mmu@ec670000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xec670000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 4>;
+		hscif4: serial@e66b0000 {
+			compatible = "renesas,hscif-r8a7795",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe66b0000 0 96>;
+			interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 516>,
+				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x39>, <&dmac0 0x38>;
+			dma-names = "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
+			resets = <&cpg 516>;
 			status = "disabled";
 		};
 
-		ipmmu_ds0: mmu@e6740000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xe6740000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 0>;
+		hsusb: usb@e6590000 {
+			compatible = "renesas,usbhs-r8a7795",
+				     "renesas,rcar-gen3-usbhs";
+			reg = <0 0xe6590000 0 0x100>;
+			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 704>;
+			dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
+			       <&usb_dmac1 0>, <&usb_dmac1 1>;
+			dma-names = "ch0", "ch1", "ch2", "ch3";
+			renesas,buswait = <11>;
+			phys = <&usb2_phy0>;
+			phy-names = "usb";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
+			resets = <&cpg 704>;
+			status = "disabled";
 		};
 
-		ipmmu_ds1: mmu@e7740000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xe7740000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 1>;
+		hsusb3: usb@e659c000 {
+			compatible = "renesas,usbhs-r8a7795",
+				     "renesas,rcar-gen3-usbhs";
+			reg = <0 0xe659c000 0 0x100>;
+			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 705>;
+			dmas = <&usb_dmac2 0>, <&usb_dmac2 1>,
+			       <&usb_dmac3 0>, <&usb_dmac3 1>;
+			dma-names = "ch0", "ch1", "ch2", "ch3";
+			renesas,buswait = <11>;
+			phys = <&usb2_phy3>;
+			phy-names = "usb";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
+			resets = <&cpg 705>;
+			status = "disabled";
 		};
 
-		ipmmu_mm: mmu@e67b0000 {
-			compatible = "renesas,ipmmu-r8a7795";
-			reg = <0 0xe67b0000 0 0x1000>;
-			interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+		usb_dmac0: dma-controller@e65a0000 {
+			compatible = "renesas,r8a7795-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe65a0000 0 0x100>;
+			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 330>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
+			resets = <&cpg 330>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
+		};
+
+		usb_dmac1: dma-controller@e65b0000 {
+			compatible = "renesas,r8a7795-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe65b0000 0 0x100>;
+			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 331>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 331>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
+		};
+
+		usb_dmac2: dma-controller@e6460000 {
+			compatible = "renesas,r8a7795-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe6460000 0 0x100>;
+			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 326>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 326>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
 		};
 
+		usb_dmac3: dma-controller@e6470000 {
+			compatible = "renesas,r8a7795-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe6470000 0 0x100>;
+			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 329>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 329>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
+		};
+
+		usb3_phy0: usb-phy@e65ee000 {
+			compatible = "renesas,r8a7795-usb3-phy",
+				     "renesas,rcar-gen3-usb3-phy";
+			reg = <0 0xe65ee000 0 0x90>;
+			clocks = <&cpg CPG_MOD 328>, <&usb3s0_clk>,
+				 <&usb_extal_clk>;
+			clock-names = "usb3-if", "usb3s_clk", "usb_extal";
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 328>;
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
 		dmac0: dma-controller@e6700000 {
 			compatible = "renesas,dmac-r8a7795",
 				     "renesas,rcar-dmac";
@@ -756,154 +931,207 @@
 			       <&ipmmu_ds1 30>, <&ipmmu_ds1 31>;
 		};
 
-		audma0: dma-controller@ec700000 {
-			compatible = "renesas,dmac-r8a7795",
-				     "renesas,rcar-dmac";
-			reg = <0 0xec700000 0 0x10000>;
-			interrupts = <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "error",
-					"ch0", "ch1", "ch2", "ch3",
-					"ch4", "ch5", "ch6", "ch7",
-					"ch8", "ch9", "ch10", "ch11",
-					"ch12", "ch13", "ch14", "ch15";
-			clocks = <&cpg CPG_MOD 502>;
-			clock-names = "fck";
+		ipmmu_ds0: mmu@e6740000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xe6740000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 0>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 502>;
-			#dma-cells = <1>;
-			dma-channels = <16>;
-			iommus = <&ipmmu_mp0 0>, <&ipmmu_mp0 1>,
-			       <&ipmmu_mp0 2>, <&ipmmu_mp0 3>,
-			       <&ipmmu_mp0 4>, <&ipmmu_mp0 5>,
-			       <&ipmmu_mp0 6>, <&ipmmu_mp0 7>,
-			       <&ipmmu_mp0 8>, <&ipmmu_mp0 9>,
-			       <&ipmmu_mp0 10>, <&ipmmu_mp0 11>,
-			       <&ipmmu_mp0 12>, <&ipmmu_mp0 13>,
-			       <&ipmmu_mp0 14>, <&ipmmu_mp0 15>;
+			#iommu-cells = <1>;
 		};
 
-		audma1: dma-controller@ec720000 {
-			compatible = "renesas,dmac-r8a7795",
-				     "renesas,rcar-dmac";
-			reg = <0 0xec720000 0 0x10000>;
-			interrupts = <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "error",
-					"ch0", "ch1", "ch2", "ch3",
-					"ch4", "ch5", "ch6", "ch7",
-					"ch8", "ch9", "ch10", "ch11",
-					"ch12", "ch13", "ch14", "ch15";
-			clocks = <&cpg CPG_MOD 501>;
-			clock-names = "fck";
+		ipmmu_ds1: mmu@e7740000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xe7740000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 1>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 501>;
-			#dma-cells = <1>;
-			dma-channels = <16>;
-			iommus = <&ipmmu_mp0 16>, <&ipmmu_mp0 17>,
-			       <&ipmmu_mp0 18>, <&ipmmu_mp0 19>,
-			       <&ipmmu_mp0 20>, <&ipmmu_mp0 21>,
-			       <&ipmmu_mp0 22>, <&ipmmu_mp0 23>,
-			       <&ipmmu_mp0 24>, <&ipmmu_mp0 25>,
-			       <&ipmmu_mp0 26>, <&ipmmu_mp0 27>,
-			       <&ipmmu_mp0 28>, <&ipmmu_mp0 29>,
-			       <&ipmmu_mp0 30>, <&ipmmu_mp0 31>;
+			#iommu-cells = <1>;
 		};
 
-		avb: ethernet@e6800000 {
-			compatible = "renesas,etheravb-r8a7795",
-				     "renesas,etheravb-rcar-gen3";
-			reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
-			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "ch0", "ch1", "ch2", "ch3",
-					  "ch4", "ch5", "ch6", "ch7",
-					  "ch8", "ch9", "ch10", "ch11",
-					  "ch12", "ch13", "ch14", "ch15",
-					  "ch16", "ch17", "ch18", "ch19",
-					  "ch20", "ch21", "ch22", "ch23",
-					  "ch24";
-			clocks = <&cpg CPG_MOD 812>;
+		ipmmu_hc: mmu@e6570000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xe6570000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 2>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 812>;
-			phy-mode = "rgmii";
-			iommus = <&ipmmu_ds0 16>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
+			#iommu-cells = <1>;
 		};
 
-		can0: can@e6c30000 {
-			compatible = "renesas,can-r8a7795",
-				     "renesas,rcar-gen3-can";
-			reg = <0 0xe6c30000 0 0x1000>;
-			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 916>,
-			       <&cpg CPG_CORE R8A7795_CLK_CANFD>,
-			       <&can_clk>;
-			clock-names = "clkp1", "clkp2", "can_clk";
-			assigned-clocks = <&cpg CPG_CORE R8A7795_CLK_CANFD>;
-			assigned-clock-rates = <40000000>;
+		ipmmu_ir: mmu@ff8b0000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xff8b0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 3>;
+			power-domains = <&sysc R8A7795_PD_A3IR>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_mm: mmu@e67b0000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xe67b0000 0 0x1000>;
+			interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 916>;
-			status = "disabled";
+			#iommu-cells = <1>;
 		};
 
-		can1: can@e6c38000 {
-			compatible = "renesas,can-r8a7795",
+		ipmmu_mp0: mmu@ec670000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xec670000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 4>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_pv0: mmu@fd800000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xfd800000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 6>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_pv1: mmu@fd950000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xfd950000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 7>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_pv2: mmu@fd960000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xfd960000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 8>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_pv3: mmu@fd970000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xfd970000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 9>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_rt: mmu@ffc80000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xffc80000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 10>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vc0: mmu@fe6b0000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xfe6b0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 12>;
+			power-domains = <&sysc R8A7795_PD_A3VC>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vc1: mmu@fe6f0000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xfe6f0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 13>;
+			power-domains = <&sysc R8A7795_PD_A3VC>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vi0: mmu@febd0000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xfebd0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 14>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vi1: mmu@febe0000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xfebe0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 15>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vp0: mmu@fe990000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xfe990000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 16>;
+			power-domains = <&sysc R8A7795_PD_A3VP>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vp1: mmu@fe980000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xfe980000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 17>;
+			power-domains = <&sysc R8A7795_PD_A3VP>;
+			#iommu-cells = <1>;
+		};
+
+		avb: ethernet@e6800000 {
+			compatible = "renesas,etheravb-r8a7795",
+				     "renesas,etheravb-rcar-gen3";
+			reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
+			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15",
+					  "ch16", "ch17", "ch18", "ch19",
+					  "ch20", "ch21", "ch22", "ch23",
+					  "ch24";
+			clocks = <&cpg CPG_MOD 812>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 812>;
+			phy-mode = "rgmii";
+			iommus = <&ipmmu_ds0 16>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		can0: can@e6c30000 {
+			compatible = "renesas,can-r8a7795",
+				     "renesas,rcar-gen3-can";
+			reg = <0 0xe6c30000 0 0x1000>;
+			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 916>,
+			       <&cpg CPG_CORE R8A7795_CLK_CANFD>,
+			       <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			assigned-clocks = <&cpg CPG_CORE R8A7795_CLK_CANFD>;
+			assigned-clock-rates = <40000000>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 916>;
+			status = "disabled";
+		};
+
+		can1: can@e6c38000 {
+			compatible = "renesas,can-r8a7795",
 				     "renesas,rcar-gen3-can";
 			reg = <0 0xe6c38000 0 0x1000>;
 			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
@@ -943,211 +1171,173 @@
 			};
 		};
 
-		drif00: rif@e6f40000 {
-			compatible = "renesas,r8a7795-drif",
-				     "renesas,rcar-gen3-drif";
-			reg = <0 0xe6f40000 0 0x64>;
-			interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 515>;
-			clock-names = "fck";
-			dmas = <&dmac1 0x20>, <&dmac2 0x20>;
-			dma-names = "rx", "rx";
+		pwm0: pwm@e6e30000 {
+			compatible = "renesas,pwm-r8a7795", "renesas,pwm-rcar";
+			reg = <0 0xe6e30000 0 0x8>;
+			clocks = <&cpg CPG_MOD 523>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 515>;
-			renesas,bonding = <&drif01>;
+			resets = <&cpg 523>;
+			#pwm-cells = <2>;
 			status = "disabled";
 		};
 
-		drif01: rif@e6f50000 {
-			compatible = "renesas,r8a7795-drif",
-				     "renesas,rcar-gen3-drif";
-			reg = <0 0xe6f50000 0 0x64>;
-			interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 514>;
-			clock-names = "fck";
-			dmas = <&dmac1 0x22>, <&dmac2 0x22>;
-			dma-names = "rx", "rx";
+		pwm1: pwm@e6e31000 {
+			compatible = "renesas,pwm-r8a7795", "renesas,pwm-rcar";
+			reg = <0 0xe6e31000 0 0x8>;
+			clocks = <&cpg CPG_MOD 523>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 514>;
-			renesas,bonding = <&drif00>;
+			resets = <&cpg 523>;
+			#pwm-cells = <2>;
 			status = "disabled";
 		};
 
-		drif10: rif@e6f60000 {
-			compatible = "renesas,r8a7795-drif",
-				     "renesas,rcar-gen3-drif";
-			reg = <0 0xe6f60000 0 0x64>;
-			interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 513>;
-			clock-names = "fck";
-			dmas = <&dmac1 0x24>, <&dmac2 0x24>;
-			dma-names = "rx", "rx";
+		pwm2: pwm@e6e32000 {
+			compatible = "renesas,pwm-r8a7795", "renesas,pwm-rcar";
+			reg = <0 0xe6e32000 0 0x8>;
+			clocks = <&cpg CPG_MOD 523>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 513>;
-			renesas,bonding = <&drif11>;
+			resets = <&cpg 523>;
+			#pwm-cells = <2>;
 			status = "disabled";
 		};
 
-		drif11: rif@e6f70000 {
-			compatible = "renesas,r8a7795-drif",
-				     "renesas,rcar-gen3-drif";
-			reg = <0 0xe6f70000 0 0x64>;
-			interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 512>;
-			clock-names = "fck";
-			dmas = <&dmac1 0x26>, <&dmac2 0x26>;
-			dma-names = "rx", "rx";
+		pwm3: pwm@e6e33000 {
+			compatible = "renesas,pwm-r8a7795", "renesas,pwm-rcar";
+			reg = <0 0xe6e33000 0 0x8>;
+			clocks = <&cpg CPG_MOD 523>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 512>;
-			renesas,bonding = <&drif10>;
+			resets = <&cpg 523>;
+			#pwm-cells = <2>;
 			status = "disabled";
 		};
 
-		drif20: rif@e6f80000 {
-			compatible = "renesas,r8a7795-drif",
-				     "renesas,rcar-gen3-drif";
-			reg = <0 0xe6f80000 0 0x64>;
-			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 511>;
-			clock-names = "fck";
-			dmas = <&dmac1 0x28>, <&dmac2 0x28>;
-			dma-names = "rx", "rx";
+		pwm4: pwm@e6e34000 {
+			compatible = "renesas,pwm-r8a7795", "renesas,pwm-rcar";
+			reg = <0 0xe6e34000 0 0x8>;
+			clocks = <&cpg CPG_MOD 523>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 511>;
-			renesas,bonding = <&drif21>;
+			resets = <&cpg 523>;
+			#pwm-cells = <2>;
 			status = "disabled";
 		};
 
-		drif21: rif@e6f90000 {
-			compatible = "renesas,r8a7795-drif",
-				     "renesas,rcar-gen3-drif";
-			reg = <0 0xe6f90000 0 0x64>;
-			interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 510>;
-			clock-names = "fck";
-			dmas = <&dmac1 0x2a>, <&dmac2 0x2a>;
-			dma-names = "rx", "rx";
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 510>;
-			renesas,bonding = <&drif20>;
+		pwm5: pwm@e6e35000 {
+			compatible = "renesas,pwm-r8a7795", "renesas,pwm-rcar";
+			reg = <0 0xe6e35000 0 0x8>;
+			clocks = <&cpg CPG_MOD 523>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 523>;
+			#pwm-cells = <2>;
 			status = "disabled";
 		};
 
-		drif30: rif@e6fa0000 {
-			compatible = "renesas,r8a7795-drif",
-				     "renesas,rcar-gen3-drif";
-			reg = <0 0xe6fa0000 0 0x64>;
-			interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 509>;
-			clock-names = "fck";
-			dmas = <&dmac1 0x2c>, <&dmac2 0x2c>;
-			dma-names = "rx", "rx";
+		pwm6: pwm@e6e36000 {
+			compatible = "renesas,pwm-r8a7795", "renesas,pwm-rcar";
+			reg = <0 0xe6e36000 0 0x8>;
+			clocks = <&cpg CPG_MOD 523>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 509>;
-			renesas,bonding = <&drif31>;
+			resets = <&cpg 523>;
+			#pwm-cells = <2>;
 			status = "disabled";
 		};
 
-		drif31: rif@e6fb0000 {
-			compatible = "renesas,r8a7795-drif",
-				     "renesas,rcar-gen3-drif";
-			reg = <0 0xe6fb0000 0 0x64>;
-			interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 508>;
-			clock-names = "fck";
-			dmas = <&dmac1 0x2e>, <&dmac2 0x2e>;
-			dma-names = "rx", "rx";
+		scif0: serial@e6e60000 {
+			compatible = "renesas,scif-r8a7795",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6e60000 0 64>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 207>,
+				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x51>, <&dmac1 0x50>,
+			       <&dmac2 0x51>, <&dmac2 0x50>;
+			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 508>;
-			renesas,bonding = <&drif30>;
+			resets = <&cpg 207>;
 			status = "disabled";
 		};
 
-		hscif0: serial@e6540000 {
-			compatible = "renesas,hscif-r8a7795",
-				     "renesas,rcar-gen3-hscif",
-				     "renesas,hscif";
-			reg = <0 0xe6540000 0 96>;
-			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 520>,
+		scif1: serial@e6e68000 {
+			compatible = "renesas,scif-r8a7795",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6e68000 0 64>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 206>,
 				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x31>, <&dmac1 0x30>,
-			       <&dmac2 0x31>, <&dmac2 0x30>;
+			dmas = <&dmac1 0x53>, <&dmac1 0x52>,
+			       <&dmac2 0x53>, <&dmac2 0x52>;
 			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 520>;
+			resets = <&cpg 206>;
 			status = "disabled";
 		};
 
-		hscif1: serial@e6550000 {
-			compatible = "renesas,hscif-r8a7795",
-				     "renesas,rcar-gen3-hscif",
-				     "renesas,hscif";
-			reg = <0 0xe6550000 0 96>;
-			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 519>,
+		scif2: serial@e6e88000 {
+			compatible = "renesas,scif-r8a7795",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6e88000 0 64>;
+			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 310>,
 				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x33>, <&dmac1 0x32>,
-			       <&dmac2 0x33>, <&dmac2 0x32>;
+			dmas = <&dmac1 0x13>, <&dmac1 0x12>,
+			       <&dmac2 0x13>, <&dmac2 0x12>;
 			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 519>;
+			resets = <&cpg 310>;
 			status = "disabled";
 		};
 
-		hscif2: serial@e6560000 {
-			compatible = "renesas,hscif-r8a7795",
-				     "renesas,rcar-gen3-hscif",
-				     "renesas,hscif";
-			reg = <0 0xe6560000 0 96>;
-			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 518>,
+		scif3: serial@e6c50000 {
+			compatible = "renesas,scif-r8a7795",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6c50000 0 64>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 204>,
 				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x35>, <&dmac1 0x34>,
-			       <&dmac2 0x35>, <&dmac2 0x34>;
-			dma-names = "tx", "rx", "tx", "rx";
+			dmas = <&dmac0 0x57>, <&dmac0 0x56>;
+			dma-names = "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 518>;
+			resets = <&cpg 204>;
 			status = "disabled";
 		};
 
-		hscif3: serial@e66a0000 {
-			compatible = "renesas,hscif-r8a7795",
-				     "renesas,rcar-gen3-hscif",
-				     "renesas,hscif";
-			reg = <0 0xe66a0000 0 96>;
-			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 517>,
+		scif4: serial@e6c40000 {
+			compatible = "renesas,scif-r8a7795",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6c40000 0 64>;
+			interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 203>,
 				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac0 0x37>, <&dmac0 0x36>;
+			dmas = <&dmac0 0x59>, <&dmac0 0x58>;
 			dma-names = "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 517>;
+			resets = <&cpg 203>;
 			status = "disabled";
 		};
 
-		hscif4: serial@e66b0000 {
-			compatible = "renesas,hscif-r8a7795",
-				     "renesas,rcar-gen3-hscif",
-				     "renesas,hscif";
-			reg = <0 0xe66b0000 0 96>;
-			interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 516>,
+		scif5: serial@e6f30000 {
+			compatible = "renesas,scif-r8a7795",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6f30000 0 64>;
+			interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 202>,
 				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac0 0x39>, <&dmac0 0x38>;
-			dma-names = "tx", "rx";
+			dmas = <&dmac1 0x5b>, <&dmac1 0x5a>,
+			       <&dmac2 0x5b>, <&dmac2 0x5a>;
+			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 516>;
+			resets = <&cpg 202>;
 			status = "disabled";
 		};
 
@@ -1213,304 +1403,379 @@
 			status = "disabled";
 		};
 
-		scif0: serial@e6e60000 {
-			compatible = "renesas,scif-r8a7795",
-				     "renesas,rcar-gen3-scif", "renesas,scif";
-			reg = <0 0xe6e60000 0 64>;
-			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 207>,
-				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
-				 <&scif_clk>;
-			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x51>, <&dmac1 0x50>,
-			       <&dmac2 0x51>, <&dmac2 0x50>;
-			dma-names = "tx", "rx", "tx", "rx";
+		vin0: video@e6ef0000 {
+			compatible = "renesas,vin-r8a7795";
+			reg = <0 0xe6ef0000 0 0x1000>;
+			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 811>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 207>;
+			resets = <&cpg 811>;
+			renesas,id = <0>;
 			status = "disabled";
-		};
 
-		scif1: serial@e6e68000 {
-			compatible = "renesas,scif-r8a7795",
-				     "renesas,rcar-gen3-scif", "renesas,scif";
-			reg = <0 0xe6e68000 0 64>;
-			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 206>,
-				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
-				 <&scif_clk>;
-			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x53>, <&dmac1 0x52>,
-			       <&dmac2 0x53>, <&dmac2 0x52>;
-			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 206>;
-			status = "disabled";
-		};
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
 
-		scif2: serial@e6e88000 {
-			compatible = "renesas,scif-r8a7795",
-				     "renesas,rcar-gen3-scif", "renesas,scif";
-			reg = <0 0xe6e88000 0 64>;
-			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 310>,
-				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
-				 <&scif_clk>;
-			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x13>, <&dmac1 0x12>,
-			       <&dmac2 0x13>, <&dmac2 0x12>;
-			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 310>;
-			status = "disabled";
-		};
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
 
-		scif3: serial@e6c50000 {
-			compatible = "renesas,scif-r8a7795",
-				     "renesas,rcar-gen3-scif", "renesas,scif";
-			reg = <0 0xe6c50000 0 64>;
-			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 204>,
-				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
-				 <&scif_clk>;
-			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac0 0x57>, <&dmac0 0x56>;
-			dma-names = "tx", "rx";
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 204>;
-			status = "disabled";
-		};
+					reg = <1>;
 
-		scif4: serial@e6c40000 {
-			compatible = "renesas,scif-r8a7795",
-				     "renesas,rcar-gen3-scif", "renesas,scif";
-			reg = <0 0xe6c40000 0 64>;
-			interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 203>,
-				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
-				 <&scif_clk>;
-			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac0 0x59>, <&dmac0 0x58>;
-			dma-names = "tx", "rx";
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 203>;
-			status = "disabled";
+					vin0csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin0>;
+					};
+					vin0csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin0>;
+					};
+				};
+			};
 		};
 
-		scif5: serial@e6f30000 {
-			compatible = "renesas,scif-r8a7795",
-				     "renesas,rcar-gen3-scif", "renesas,scif";
-			reg = <0 0xe6f30000 0 64>;
-			interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 202>,
-				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
-				 <&scif_clk>;
-			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x5b>, <&dmac1 0x5a>,
-			       <&dmac2 0x5b>, <&dmac2 0x5a>;
-			dma-names = "tx", "rx", "tx", "rx";
+		vin1: video@e6ef1000 {
+			compatible = "renesas,vin-r8a7795";
+			reg = <0 0xe6ef1000 0 0x1000>;
+			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 810>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 202>;
+			resets = <&cpg 810>;
+			renesas,id = <1>;
 			status = "disabled";
-		};
 
-		i2c_dvfs: i2c@e60b0000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,iic-r8a7795",
-				     "renesas,rcar-gen3-iic",
-				     "renesas,rmobile-iic";
-			reg = <0 0xe60b0000 0 0x425>;
-			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 926>;
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 926>;
-			dmas = <&dmac0 0x11>, <&dmac0 0x10>;
-			dma-names = "tx", "rx";
-			status = "disabled";
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin1csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin1>;
+					};
+					vin1csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin1>;
+					};
+				};
+			};
 		};
 
-		i2c0: i2c@e6500000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a7795",
-				     "renesas,rcar-gen3-i2c";
-			reg = <0 0xe6500000 0 0x40>;
-			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 931>;
+		vin2: video@e6ef2000 {
+			compatible = "renesas,vin-r8a7795";
+			reg = <0 0xe6ef2000 0 0x1000>;
+			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 809>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 931>;
-			dmas = <&dmac1 0x91>, <&dmac1 0x90>,
-			       <&dmac2 0x91>, <&dmac2 0x90>;
-			dma-names = "tx", "rx", "tx", "rx";
-			i2c-scl-internal-delay-ns = <110>;
+			resets = <&cpg 809>;
+			renesas,id = <2>;
 			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin2csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin2>;
+					};
+					vin2csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin2>;
+					};
+				};
+			};
 		};
 
-		i2c1: i2c@e6508000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a7795",
-				     "renesas,rcar-gen3-i2c";
-			reg = <0 0xe6508000 0 0x40>;
-			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 930>;
+		vin3: video@e6ef3000 {
+			compatible = "renesas,vin-r8a7795";
+			reg = <0 0xe6ef3000 0 0x1000>;
+			interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 808>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 930>;
-			dmas = <&dmac1 0x93>, <&dmac1 0x92>,
-			       <&dmac2 0x93>, <&dmac2 0x92>;
-			dma-names = "tx", "rx", "tx", "rx";
-			i2c-scl-internal-delay-ns = <6>;
+			resets = <&cpg 808>;
+			renesas,id = <3>;
 			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin3csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin3>;
+					};
+					vin3csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin3>;
+					};
+				};
+			};
 		};
 
-		i2c2: i2c@e6510000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a7795",
-				     "renesas,rcar-gen3-i2c";
-			reg = <0 0xe6510000 0 0x40>;
-			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 929>;
+		vin4: video@e6ef4000 {
+			compatible = "renesas,vin-r8a7795";
+			reg = <0 0xe6ef4000 0 0x1000>;
+			interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 807>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 929>;
-			dmas = <&dmac1 0x95>, <&dmac1 0x94>,
-			       <&dmac2 0x95>, <&dmac2 0x94>;
-			dma-names = "tx", "rx", "tx", "rx";
-			i2c-scl-internal-delay-ns = <6>;
+			resets = <&cpg 807>;
+			renesas,id = <4>;
 			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin4csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin4>;
+					};
+					vin4csi41: endpoint@3 {
+						reg = <3>;
+						remote-endpoint= <&csi41vin4>;
+					};
+				};
+			};
 		};
 
-		i2c3: i2c@e66d0000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a7795",
-				     "renesas,rcar-gen3-i2c";
-			reg = <0 0xe66d0000 0 0x40>;
-			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 928>;
+		vin5: video@e6ef5000 {
+			compatible = "renesas,vin-r8a7795";
+			reg = <0 0xe6ef5000 0 0x1000>;
+			interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 806>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 928>;
-			dmas = <&dmac0 0x97>, <&dmac0 0x96>;
-			dma-names = "tx", "rx";
-			i2c-scl-internal-delay-ns = <110>;
+			resets = <&cpg 806>;
+			renesas,id = <5>;
 			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin5csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin5>;
+					};
+					vin5csi41: endpoint@3 {
+						reg = <3>;
+						remote-endpoint= <&csi41vin5>;
+					};
+				};
+			};
 		};
 
-		i2c4: i2c@e66d8000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a7795",
-				     "renesas,rcar-gen3-i2c";
-			reg = <0 0xe66d8000 0 0x40>;
-			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 927>;
+		vin6: video@e6ef6000 {
+			compatible = "renesas,vin-r8a7795";
+			reg = <0 0xe6ef6000 0 0x1000>;
+			interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 805>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 927>;
-			dmas = <&dmac0 0x99>, <&dmac0 0x98>;
-			dma-names = "tx", "rx";
-			i2c-scl-internal-delay-ns = <110>;
+			resets = <&cpg 805>;
+			renesas,id = <6>;
 			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin6csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin6>;
+					};
+					vin6csi41: endpoint@3 {
+						reg = <3>;
+						remote-endpoint= <&csi41vin6>;
+					};
+				};
+			};
 		};
 
-		i2c5: i2c@e66e0000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a7795",
-				     "renesas,rcar-gen3-i2c";
-			reg = <0 0xe66e0000 0 0x40>;
-			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 919>;
+		vin7: video@e6ef7000 {
+			compatible = "renesas,vin-r8a7795";
+			reg = <0 0xe6ef7000 0 0x1000>;
+			interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 804>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 919>;
-			dmas = <&dmac0 0x9b>, <&dmac0 0x9a>;
-			dma-names = "tx", "rx";
-			i2c-scl-internal-delay-ns = <110>;
+			resets = <&cpg 804>;
+			renesas,id = <7>;
 			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin7csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin7>;
+					};
+					vin7csi41: endpoint@3 {
+						reg = <3>;
+						remote-endpoint= <&csi41vin7>;
+					};
+				};
+			};
 		};
 
-		i2c6: i2c@e66e8000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a7795",
-				     "renesas,rcar-gen3-i2c";
-			reg = <0 0xe66e8000 0 0x40>;
-			interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 918>;
+		drif00: rif@e6f40000 {
+			compatible = "renesas,r8a7795-drif",
+				     "renesas,rcar-gen3-drif";
+			reg = <0 0xe6f40000 0 0x64>;
+			interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 515>;
+			clock-names = "fck";
+			dmas = <&dmac1 0x20>, <&dmac2 0x20>;
+			dma-names = "rx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 918>;
-			dmas = <&dmac0 0x9d>, <&dmac0 0x9c>;
-			dma-names = "tx", "rx";
-			i2c-scl-internal-delay-ns = <6>;
+			resets = <&cpg 515>;
+			renesas,bonding = <&drif01>;
 			status = "disabled";
 		};
 
-		pwm0: pwm@e6e30000 {
-			compatible = "renesas,pwm-r8a7795", "renesas,pwm-rcar";
-			reg = <0 0xe6e30000 0 0x8>;
-			clocks = <&cpg CPG_MOD 523>;
+		drif01: rif@e6f50000 {
+			compatible = "renesas,r8a7795-drif",
+				     "renesas,rcar-gen3-drif";
+			reg = <0 0xe6f50000 0 0x64>;
+			interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 514>;
+			clock-names = "fck";
+			dmas = <&dmac1 0x22>, <&dmac2 0x22>;
+			dma-names = "rx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 523>;
-			#pwm-cells = <2>;
+			resets = <&cpg 514>;
+			renesas,bonding = <&drif00>;
 			status = "disabled";
 		};
 
-		pwm1: pwm@e6e31000 {
-			compatible = "renesas,pwm-r8a7795", "renesas,pwm-rcar";
-			reg = <0 0xe6e31000 0 0x8>;
-			clocks = <&cpg CPG_MOD 523>;
+		drif10: rif@e6f60000 {
+			compatible = "renesas,r8a7795-drif",
+				     "renesas,rcar-gen3-drif";
+			reg = <0 0xe6f60000 0 0x64>;
+			interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 513>;
+			clock-names = "fck";
+			dmas = <&dmac1 0x24>, <&dmac2 0x24>;
+			dma-names = "rx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 523>;
-			#pwm-cells = <2>;
+			resets = <&cpg 513>;
+			renesas,bonding = <&drif11>;
 			status = "disabled";
 		};
-
-		pwm2: pwm@e6e32000 {
-			compatible = "renesas,pwm-r8a7795", "renesas,pwm-rcar";
-			reg = <0 0xe6e32000 0 0x8>;
-			clocks = <&cpg CPG_MOD 523>;
+
+		drif11: rif@e6f70000 {
+			compatible = "renesas,r8a7795-drif",
+				     "renesas,rcar-gen3-drif";
+			reg = <0 0xe6f70000 0 0x64>;
+			interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 512>;
+			clock-names = "fck";
+			dmas = <&dmac1 0x26>, <&dmac2 0x26>;
+			dma-names = "rx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 523>;
-			#pwm-cells = <2>;
+			resets = <&cpg 512>;
+			renesas,bonding = <&drif10>;
 			status = "disabled";
 		};
 
-		pwm3: pwm@e6e33000 {
-			compatible = "renesas,pwm-r8a7795", "renesas,pwm-rcar";
-			reg = <0 0xe6e33000 0 0x8>;
-			clocks = <&cpg CPG_MOD 523>;
+		drif20: rif@e6f80000 {
+			compatible = "renesas,r8a7795-drif",
+				     "renesas,rcar-gen3-drif";
+			reg = <0 0xe6f80000 0 0x64>;
+			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 511>;
+			clock-names = "fck";
+			dmas = <&dmac1 0x28>, <&dmac2 0x28>;
+			dma-names = "rx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 523>;
-			#pwm-cells = <2>;
+			resets = <&cpg 511>;
+			renesas,bonding = <&drif21>;
 			status = "disabled";
 		};
 
-		pwm4: pwm@e6e34000 {
-			compatible = "renesas,pwm-r8a7795", "renesas,pwm-rcar";
-			reg = <0 0xe6e34000 0 0x8>;
-			clocks = <&cpg CPG_MOD 523>;
+		drif21: rif@e6f90000 {
+			compatible = "renesas,r8a7795-drif",
+				     "renesas,rcar-gen3-drif";
+			reg = <0 0xe6f90000 0 0x64>;
+			interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 510>;
+			clock-names = "fck";
+			dmas = <&dmac1 0x2a>, <&dmac2 0x2a>;
+			dma-names = "rx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 523>;
-			#pwm-cells = <2>;
+			resets = <&cpg 510>;
+			renesas,bonding = <&drif20>;
 			status = "disabled";
 		};
 
-		pwm5: pwm@e6e35000 {
-			compatible = "renesas,pwm-r8a7795", "renesas,pwm-rcar";
-			reg = <0 0xe6e35000 0 0x8>;
-			clocks = <&cpg CPG_MOD 523>;
+		drif30: rif@e6fa0000 {
+			compatible = "renesas,r8a7795-drif",
+				     "renesas,rcar-gen3-drif";
+			reg = <0 0xe6fa0000 0 0x64>;
+			interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 509>;
+			clock-names = "fck";
+			dmas = <&dmac1 0x2c>, <&dmac2 0x2c>;
+			dma-names = "rx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 523>;
-			#pwm-cells = <2>;
+			resets = <&cpg 509>;
+			renesas,bonding = <&drif31>;
 			status = "disabled";
 		};
 
-		pwm6: pwm@e6e36000 {
-			compatible = "renesas,pwm-r8a7795", "renesas,pwm-rcar";
-			reg = <0 0xe6e36000 0 0x8>;
-			clocks = <&cpg CPG_MOD 523>;
+		drif31: rif@e6fb0000 {
+			compatible = "renesas,r8a7795-drif",
+				     "renesas,rcar-gen3-drif";
+			reg = <0 0xe6fb0000 0 0x64>;
+			interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 508>;
+			clock-names = "fck";
+			dmas = <&dmac1 0x2e>, <&dmac2 0x2e>;
+			dma-names = "rx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 523>;
-			#pwm-cells = <2>;
+			resets = <&cpg 508>;
+			renesas,bonding = <&drif30>;
 			status = "disabled";
 		};
 
@@ -1708,209 +1973,172 @@
 					dma-names = "rx", "tx", "rxu", "txu";
 				};
 			};
-		};
-
-		sata: sata@ee300000 {
-			compatible = "renesas,sata-r8a7795",
-				     "renesas,rcar-gen3-sata";
-			reg = <0 0xee300000 0 0x200000>;
-			interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 815>;
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 815>;
-			status = "disabled";
-			iommus = <&ipmmu_hc 2>;
-		};
-
-		usb3_phy0: usb-phy@e65ee000 {
-			compatible = "renesas,r8a7795-usb3-phy",
-				     "renesas,rcar-gen3-usb3-phy";
-			reg = <0 0xe65ee000 0 0x90>;
-			clocks = <&cpg CPG_MOD 328>, <&usb3s0_clk>,
-				 <&usb_extal_clk>;
-			clock-names = "usb3-if", "usb3s_clk", "usb_extal";
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 328>;
-			#phy-cells = <0>;
-			status = "disabled";
-		};
-
-		xhci0: usb@ee000000 {
-			compatible = "renesas,xhci-r8a7795", "renesas,rcar-gen3-xhci";
-			reg = <0 0xee000000 0 0xc00>;
-			interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 328>;
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 328>;
-			status = "disabled";
-		};
-
-		usb3_peri0: usb@ee020000 {
-			compatible = "renesas,r8a7795-usb3-peri",
-				     "renesas,rcar-gen3-usb3-peri";
-			reg = <0 0xee020000 0 0x400>;
-			interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 328>;
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 328>;
-			status = "disabled";
-		};
-
-		usb_dmac0: dma-controller@e65a0000 {
-			compatible = "renesas,r8a7795-usb-dmac",
-				     "renesas,usb-dmac";
-			reg = <0 0xe65a0000 0 0x100>;
-			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "ch0", "ch1";
-			clocks = <&cpg CPG_MOD 330>;
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 330>;
-			#dma-cells = <1>;
-			dma-channels = <2>;
-		};
-
-		usb_dmac1: dma-controller@e65b0000 {
-			compatible = "renesas,r8a7795-usb-dmac",
-				     "renesas,usb-dmac";
-			reg = <0 0xe65b0000 0 0x100>;
-			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "ch0", "ch1";
-			clocks = <&cpg CPG_MOD 331>;
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 331>;
-			#dma-cells = <1>;
-			dma-channels = <2>;
-		};
 
-		usb_dmac2: dma-controller@e6460000 {
-			compatible = "renesas,r8a7795-usb-dmac",
-				     "renesas,usb-dmac";
-			reg = <0 0xe6460000 0 0x100>;
-			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "ch0", "ch1";
-			clocks = <&cpg CPG_MOD 326>;
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 326>;
-			#dma-cells = <1>;
-			dma-channels = <2>;
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+				};
+				port@1 {
+					reg = <1>;
+				};
+				port@2 {
+					reg = <2>;
+				};
+			};
 		};
 
-		usb_dmac3: dma-controller@e6470000 {
-			compatible = "renesas,r8a7795-usb-dmac",
-				     "renesas,usb-dmac";
-			reg = <0 0xe6470000 0 0x100>;
-			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "ch0", "ch1";
-			clocks = <&cpg CPG_MOD 329>;
+		audma0: dma-controller@ec700000 {
+			compatible = "renesas,dmac-r8a7795",
+				     "renesas,rcar-dmac";
+			reg = <0 0xec700000 0 0x10000>;
+			interrupts = <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5", "ch6", "ch7",
+					"ch8", "ch9", "ch10", "ch11",
+					"ch12", "ch13", "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 502>;
+			clock-names = "fck";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 329>;
+			resets = <&cpg 502>;
 			#dma-cells = <1>;
-			dma-channels = <2>;
-		};
-
-		rpc: rpc@0xee200000 {
-			compatible = "renesas,rpc-r8a7795", "renesas,rpc";
-			reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>;
-			clocks = <&cpg CPG_MOD 917>;
-			bank-width = <2>;
-			status = "disabled";
-		};
-
-		sdhi0: sd@ee100000 {
-			compatible = "renesas,sdhi-r8a7795",
-				     "renesas,rcar-gen3-sdhi";
-			reg = <0 0xee100000 0 0x2000>;
-			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 314>;
-			max-frequency = <200000000>;
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 314>;
-			status = "disabled";
+			dma-channels = <16>;
+			iommus = <&ipmmu_mp0 0>, <&ipmmu_mp0 1>,
+			       <&ipmmu_mp0 2>, <&ipmmu_mp0 3>,
+			       <&ipmmu_mp0 4>, <&ipmmu_mp0 5>,
+			       <&ipmmu_mp0 6>, <&ipmmu_mp0 7>,
+			       <&ipmmu_mp0 8>, <&ipmmu_mp0 9>,
+			       <&ipmmu_mp0 10>, <&ipmmu_mp0 11>,
+			       <&ipmmu_mp0 12>, <&ipmmu_mp0 13>,
+			       <&ipmmu_mp0 14>, <&ipmmu_mp0 15>;
 		};
 
-		sdhi1: sd@ee120000 {
-			compatible = "renesas,sdhi-r8a7795",
-				     "renesas,rcar-gen3-sdhi";
-			reg = <0 0xee120000 0 0x2000>;
-			interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 313>;
-			max-frequency = <200000000>;
+		audma1: dma-controller@ec720000 {
+			compatible = "renesas,dmac-r8a7795",
+				     "renesas,rcar-dmac";
+			reg = <0 0xec720000 0 0x10000>;
+			interrupts = <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5", "ch6", "ch7",
+					"ch8", "ch9", "ch10", "ch11",
+					"ch12", "ch13", "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 501>;
+			clock-names = "fck";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 313>;
-			status = "disabled";
+			resets = <&cpg 501>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+			iommus = <&ipmmu_mp0 16>, <&ipmmu_mp0 17>,
+			       <&ipmmu_mp0 18>, <&ipmmu_mp0 19>,
+			       <&ipmmu_mp0 20>, <&ipmmu_mp0 21>,
+			       <&ipmmu_mp0 22>, <&ipmmu_mp0 23>,
+			       <&ipmmu_mp0 24>, <&ipmmu_mp0 25>,
+			       <&ipmmu_mp0 26>, <&ipmmu_mp0 27>,
+			       <&ipmmu_mp0 28>, <&ipmmu_mp0 29>,
+			       <&ipmmu_mp0 30>, <&ipmmu_mp0 31>;
 		};
 
-		sdhi2: sd@ee140000 {
-			compatible = "renesas,sdhi-r8a7795",
-				     "renesas,rcar-gen3-sdhi";
-			reg = <0 0xee140000 0 0x2000>;
-			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 312>;
-			max-frequency = <200000000>;
+		xhci0: usb@ee000000 {
+			compatible = "renesas,xhci-r8a7795", "renesas,rcar-gen3-xhci";
+			reg = <0 0xee000000 0 0xc00>;
+			interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 328>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 312>;
+			resets = <&cpg 328>;
 			status = "disabled";
 		};
 
-		sdhi3: sd@ee160000 {
-			compatible = "renesas,sdhi-r8a7795",
-				     "renesas,rcar-gen3-sdhi";
-			reg = <0 0xee160000 0 0x2000>;
-			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 311>;
-			max-frequency = <200000000>;
+		usb3_peri0: usb@ee020000 {
+			compatible = "renesas,r8a7795-usb3-peri",
+				     "renesas,rcar-gen3-usb3-peri";
+			reg = <0 0xee020000 0 0x400>;
+			interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 328>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 311>;
+			resets = <&cpg 328>;
 			status = "disabled";
 		};
 
-		usb2_phy0: usb-phy@ee080200 {
-			compatible = "renesas,usb2-phy-r8a7795",
-				     "renesas,rcar-gen3-usb2-phy";
-			reg = <0 0xee080200 0 0x700>;
+		ohci0: usb@ee080000 {
+			compatible = "generic-ohci";
+			reg = <0 0xee080000 0 0x100>;
 			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 703>;
+			phys = <&usb2_phy0>;
+			phy-names = "usb";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 703>;
-			#phy-cells = <0>;
 			status = "disabled";
 		};
 
-		usb2_phy1: usb-phy@ee0a0200 {
-			compatible = "renesas,usb2-phy-r8a7795",
-				     "renesas,rcar-gen3-usb2-phy";
-			reg = <0 0xee0a0200 0 0x700>;
+		ohci1: usb@ee0a0000 {
+			compatible = "generic-ohci";
+			reg = <0 0xee0a0000 0 0x100>;
+			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 702>;
+			phys = <&usb2_phy1>;
+			phy-names = "usb";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 702>;
-			#phy-cells = <0>;
 			status = "disabled";
 		};
 
-		usb2_phy2: usb-phy@ee0c0200 {
-			compatible = "renesas,usb2-phy-r8a7795",
-				     "renesas,rcar-gen3-usb2-phy";
-			reg = <0 0xee0c0200 0 0x700>;
+		ohci2: usb@ee0c0000 {
+			compatible = "generic-ohci";
+			reg = <0 0xee0c0000 0 0x100>;
+			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 701>;
+			phys = <&usb2_phy2>;
+			phy-names = "usb";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 701>;
-			#phy-cells = <0>;
 			status = "disabled";
 		};
 
-		usb2_phy3: usb-phy@ee0e0200 {
-			compatible = "renesas,usb2-phy-r8a7795",
-				     "renesas,rcar-gen3-usb2-phy";
-			reg = <0 0xee0e0200 0 0x700>;
+		ohci3: usb@ee0e0000 {
+			compatible = "generic-ohci";
+			reg = <0 0xee0e0000 0 0x100>;
 			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 700>;
+			phys = <&usb2_phy3>;
+			phy-names = "usb";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 700>;
-			#phy-cells = <0>;
 			status = "disabled";
 		};
 
@@ -1966,88 +2194,129 @@
 			status = "disabled";
 		};
 
-		ohci0: usb@ee080000 {
-			compatible = "generic-ohci";
-			reg = <0 0xee080000 0 0x100>;
+		usb2_phy0: usb-phy@ee080200 {
+			compatible = "renesas,usb2-phy-r8a7795",
+				     "renesas,rcar-gen3-usb2-phy";
+			reg = <0 0xee080200 0 0x700>;
 			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 703>;
-			phys = <&usb2_phy0>;
-			phy-names = "usb";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 703>;
+			#phy-cells = <0>;
 			status = "disabled";
 		};
 
-		ohci1: usb@ee0a0000 {
-			compatible = "generic-ohci";
-			reg = <0 0xee0a0000 0 0x100>;
-			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+		usb2_phy1: usb-phy@ee0a0200 {
+			compatible = "renesas,usb2-phy-r8a7795",
+				     "renesas,rcar-gen3-usb2-phy";
+			reg = <0 0xee0a0200 0 0x700>;
 			clocks = <&cpg CPG_MOD 702>;
-			phys = <&usb2_phy1>;
-			phy-names = "usb";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 702>;
+			#phy-cells = <0>;
 			status = "disabled";
 		};
 
-		ohci2: usb@ee0c0000 {
-			compatible = "generic-ohci";
-			reg = <0 0xee0c0000 0 0x100>;
-			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+		usb2_phy2: usb-phy@ee0c0200 {
+			compatible = "renesas,usb2-phy-r8a7795",
+				     "renesas,rcar-gen3-usb2-phy";
+			reg = <0 0xee0c0200 0 0x700>;
 			clocks = <&cpg CPG_MOD 701>;
-			phys = <&usb2_phy2>;
-			phy-names = "usb";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 701>;
+			#phy-cells = <0>;
 			status = "disabled";
 		};
 
-		ohci3: usb@ee0e0000 {
-			compatible = "generic-ohci";
-			reg = <0 0xee0e0000 0 0x100>;
+		usb2_phy3: usb-phy@ee0e0200 {
+			compatible = "renesas,usb2-phy-r8a7795",
+				     "renesas,rcar-gen3-usb2-phy";
+			reg = <0 0xee0e0200 0 0x700>;
 			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 700>;
-			phys = <&usb2_phy3>;
-			phy-names = "usb";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 700>;
+			#phy-cells = <0>;
 			status = "disabled";
 		};
 
-		hsusb: usb@e6590000 {
-			compatible = "renesas,usbhs-r8a7795",
-				     "renesas,rcar-gen3-usbhs";
-			reg = <0 0xe6590000 0 0x100>;
-			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 704>;
-			dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
-			       <&usb_dmac1 0>, <&usb_dmac1 1>;
-			dma-names = "ch0", "ch1", "ch2", "ch3";
-			renesas,buswait = <11>;
-			phys = <&usb2_phy0>;
-			phy-names = "usb";
+		sdhi0: sd@ee100000 {
+			compatible = "renesas,sdhi-r8a7795",
+				     "renesas,rcar-gen3-sdhi";
+			reg = <0 0xee100000 0 0x2000>;
+			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 314>;
+			max-frequency = <200000000>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 704>;
+			resets = <&cpg 314>;
 			status = "disabled";
 		};
 
-		hsusb3: usb@e659c000 {
-			compatible = "renesas,usbhs-r8a7795",
-				     "renesas,rcar-gen3-usbhs";
-			reg = <0 0xe659c000 0 0x100>;
-			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 705>;
-			dmas = <&usb_dmac2 0>, <&usb_dmac2 1>,
-			       <&usb_dmac3 0>, <&usb_dmac3 1>;
-			dma-names = "ch0", "ch1", "ch2", "ch3";
-			renesas,buswait = <11>;
-			phys = <&usb2_phy3>;
-			phy-names = "usb";
+		sdhi1: sd@ee120000 {
+			compatible = "renesas,sdhi-r8a7795",
+				     "renesas,rcar-gen3-sdhi";
+			reg = <0 0xee120000 0 0x2000>;
+			interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 313>;
+			max-frequency = <200000000>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 705>;
+			resets = <&cpg 313>;
 			status = "disabled";
 		};
 
+		sdhi2: sd@ee140000 {
+			compatible = "renesas,sdhi-r8a7795",
+				     "renesas,rcar-gen3-sdhi";
+			reg = <0 0xee140000 0 0x2000>;
+			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 312>;
+			max-frequency = <200000000>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 312>;
+			status = "disabled";
+		};
+
+		sdhi3: sd@ee160000 {
+			compatible = "renesas,sdhi-r8a7795",
+				     "renesas,rcar-gen3-sdhi";
+			reg = <0 0xee160000 0 0x2000>;
+			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 311>;
+			max-frequency = <200000000>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 311>;
+			status = "disabled";
+		};
+
+		sata: sata@ee300000 {
+			compatible = "renesas,sata-r8a7795",
+				     "renesas,rcar-gen3-sata";
+			reg = <0 0xee300000 0 0x200000>;
+			interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 815>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 815>;
+			status = "disabled";
+			iommus = <&ipmmu_hc 2>;
+		};
+
+		gic: interrupt-controller@f1010000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0x0 0xf1010000 0 0x1000>,
+			      <0x0 0xf1020000 0 0x20000>,
+			      <0x0 0xf1040000 0 0x20000>,
+			      <0x0 0xf1060000 0 0x20000>;
+			interrupts = <GIC_PPI 9
+					(GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&cpg CPG_MOD 408>;
+			clock-names = "clk";
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 408>;
+		};
+
 		pciec0: pcie@fe000000 {
 			compatible = "renesas,pcie-r8a7795",
 				     "renesas,pcie-rcar-gen3";
@@ -2138,28 +2407,28 @@
 			reg = <0 0xfe890000 0 0x2000>;
 			interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 820>;
-			power-domains = <&sysc R8A7795_PD_A3VC>;
-			resets = <&cpg 820>;
-		};
-
-		vspbc: vsp@fe920000 {
-			compatible = "renesas,vsp2";
-			reg = <0 0xfe920000 0 0x8000>;
-			interrupts = <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 624>;
-			power-domains = <&sysc R8A7795_PD_A3VP>;
-			resets = <&cpg 624>;
+			power-domains = <&sysc R8A7795_PD_A3VC>;
+			resets = <&cpg 820>;
+		};
 
-			renesas,fcp = <&fcpvb1>;
+		fdp1@fe940000 {
+			compatible = "renesas,fdp1";
+			reg = <0 0xfe940000 0 0x2400>;
+			interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 119>;
+			power-domains = <&sysc R8A7795_PD_A3VP>;
+			resets = <&cpg 119>;
+			renesas,fcp = <&fcpf0>;
 		};
 
-		fcpvb1: fcp@fe92f000 {
-			compatible = "renesas,fcpv";
-			reg = <0 0xfe92f000 0 0x200>;
-			clocks = <&cpg CPG_MOD 606>;
+		fdp1@fe944000 {
+			compatible = "renesas,fdp1";
+			reg = <0 0xfe944000 0 0x2400>;
+			interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 118>;
 			power-domains = <&sysc R8A7795_PD_A3VP>;
-			resets = <&cpg 606>;
-			iommus = <&ipmmu_vp1 7>;
+			resets = <&cpg 118>;
+			renesas,fcp = <&fcpf1>;
 		};
 
 		fcpf0: fcp@fe950000 {
@@ -2180,17 +2449,6 @@
 			iommus = <&ipmmu_vp1 1>;
 		};
 
-		vspbd: vsp@fe960000 {
-			compatible = "renesas,vsp2";
-			reg = <0 0xfe960000 0 0x8000>;
-			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 626>;
-			power-domains = <&sysc R8A7795_PD_A3VP>;
-			resets = <&cpg 626>;
-
-			renesas,fcp = <&fcpvb0>;
-		};
-
 		fcpvb0: fcp@fe96f000 {
 			compatible = "renesas,fcpv";
 			reg = <0 0xfe96f000 0 0x200>;
@@ -2200,15 +2458,13 @@
 			iommus = <&ipmmu_vp0 5>;
 		};
 
-		vspi0: vsp@fe9a0000 {
-			compatible = "renesas,vsp2";
-			reg = <0 0xfe9a0000 0 0x8000>;
-			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 631>;
+		fcpvb1: fcp@fe92f000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfe92f000 0 0x200>;
+			clocks = <&cpg CPG_MOD 606>;
 			power-domains = <&sysc R8A7795_PD_A3VP>;
-			resets = <&cpg 631>;
-
-			renesas,fcp = <&fcpvi0>;
+			resets = <&cpg 606>;
+			iommus = <&ipmmu_vp1 7>;
 		};
 
 		fcpvi0: fcp@fe9af000 {
@@ -2220,17 +2476,6 @@
 			iommus = <&ipmmu_vp0 8>;
 		};
 
-		vspi1: vsp@fe9b0000 {
-			compatible = "renesas,vsp2";
-			reg = <0 0xfe9b0000 0 0x8000>;
-			interrupts = <GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 630>;
-			power-domains = <&sysc R8A7795_PD_A3VP>;
-			resets = <&cpg 630>;
-
-			renesas,fcp = <&fcpvi1>;
-		};
-
 		fcpvi1: fcp@fe9bf000 {
 			compatible = "renesas,fcpv";
 			reg = <0 0xfe9bf000 0 0x200>;
@@ -2240,9 +2485,58 @@
 			iommus = <&ipmmu_vp1 9>;
 		};
 
+		fcpvd0: fcp@fea27000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea27000 0 0x200>;
+			clocks = <&cpg CPG_MOD 603>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 603>;
+			iommus = <&ipmmu_vi0 8>;
+		};
+
+		fcpvd1: fcp@fea2f000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea2f000 0 0x200>;
+			clocks = <&cpg CPG_MOD 602>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 602>;
+			iommus = <&ipmmu_vi0 9>;
+		};
+
+		fcpvd2: fcp@fea37000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea37000 0 0x200>;
+			clocks = <&cpg CPG_MOD 601>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 601>;
+			iommus = <&ipmmu_vi1 10>;
+		};
+
+		vspbd: vsp@fe960000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfe960000 0 0x8000>;
+			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 626>;
+			power-domains = <&sysc R8A7795_PD_A3VP>;
+			resets = <&cpg 626>;
+
+			renesas,fcp = <&fcpvb0>;
+		};
+
+		vspbc: vsp@fe920000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfe920000 0 0x8000>;
+			interrupts = <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 624>;
+			power-domains = <&sysc R8A7795_PD_A3VP>;
+			resets = <&cpg 624>;
+
+			renesas,fcp = <&fcpvb1>;
+		};
+
 		vspd0: vsp@fea20000 {
 			compatible = "renesas,vsp2";
-			reg = <0 0xfea20000 0 0x8000>;
+			reg = <0 0xfea20000 0 0x5000>;
 			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 623>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
@@ -2251,18 +2545,9 @@
 			renesas,fcp = <&fcpvd0>;
 		};
 
-		fcpvd0: fcp@fea27000 {
-			compatible = "renesas,fcpv";
-			reg = <0 0xfea27000 0 0x200>;
-			clocks = <&cpg CPG_MOD 603>;
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 603>;
-			iommus = <&ipmmu_vi0 8>;
-		};
-
 		vspd1: vsp@fea28000 {
 			compatible = "renesas,vsp2";
-			reg = <0 0xfea28000 0 0x8000>;
+			reg = <0 0xfea28000 0 0x5000>;
 			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 622>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
@@ -2271,18 +2556,9 @@
 			renesas,fcp = <&fcpvd1>;
 		};
 
-		fcpvd1: fcp@fea2f000 {
-			compatible = "renesas,fcpv";
-			reg = <0 0xfea2f000 0 0x200>;
-			clocks = <&cpg CPG_MOD 602>;
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 602>;
-			iommus = <&ipmmu_vi0 9>;
-		};
-
 		vspd2: vsp@fea30000 {
 			compatible = "renesas,vsp2";
-			reg = <0 0xfea30000 0 0x8000>;
+			reg = <0 0xfea30000 0 0x5000>;
 			interrupts = <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 621>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
@@ -2291,33 +2567,159 @@
 			renesas,fcp = <&fcpvd2>;
 		};
 
-		fcpvd2: fcp@fea37000 {
-			compatible = "renesas,fcpv";
-			reg = <0 0xfea37000 0 0x200>;
-			clocks = <&cpg CPG_MOD 601>;
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 601>;
-			iommus = <&ipmmu_vi1 10>;
+		vspi0: vsp@fe9a0000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfe9a0000 0 0x8000>;
+			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 631>;
+			power-domains = <&sysc R8A7795_PD_A3VP>;
+			resets = <&cpg 631>;
+
+			renesas,fcp = <&fcpvi0>;
 		};
 
-		fdp1@fe940000 {
-			compatible = "renesas,fdp1";
-			reg = <0 0xfe940000 0 0x2400>;
-			interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 119>;
+		vspi1: vsp@fe9b0000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfe9b0000 0 0x8000>;
+			interrupts = <GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 630>;
 			power-domains = <&sysc R8A7795_PD_A3VP>;
-			resets = <&cpg 119>;
-			renesas,fcp = <&fcpf0>;
+			resets = <&cpg 630>;
+
+			renesas,fcp = <&fcpvi1>;
 		};
 
-		fdp1@fe944000 {
-			compatible = "renesas,fdp1";
-			reg = <0 0xfe944000 0 0x2400>;
-			interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 118>;
-			power-domains = <&sysc R8A7795_PD_A3VP>;
-			resets = <&cpg 118>;
-			renesas,fcp = <&fcpf1>;
+		csi20: csi2@fea80000 {
+			compatible = "renesas,r8a7795-csi2";
+			reg = <0 0xfea80000 0 0x10000>;
+			interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 714>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 714>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					csi20vin0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&vin0csi20>;
+					};
+					csi20vin1: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&vin1csi20>;
+					};
+					csi20vin2: endpoint@2 {
+						reg = <2>;
+						remote-endpoint = <&vin2csi20>;
+					};
+					csi20vin3: endpoint@3 {
+						reg = <3>;
+						remote-endpoint = <&vin3csi20>;
+					};
+					csi20vin4: endpoint@4 {
+						reg = <4>;
+						remote-endpoint = <&vin4csi20>;
+					};
+					csi20vin5: endpoint@5 {
+						reg = <5>;
+						remote-endpoint = <&vin5csi20>;
+					};
+					csi20vin6: endpoint@6 {
+						reg = <6>;
+						remote-endpoint = <&vin6csi20>;
+					};
+					csi20vin7: endpoint@7 {
+						reg = <7>;
+						remote-endpoint = <&vin7csi20>;
+					};
+				};
+			};
+		};
+
+		csi40: csi2@feaa0000 {
+			compatible = "renesas,r8a7795-csi2";
+			reg = <0 0xfeaa0000 0 0x10000>;
+			interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 716>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 716>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					csi40vin0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&vin0csi40>;
+					};
+					csi40vin1: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&vin1csi40>;
+					};
+					csi40vin2: endpoint@2 {
+						reg = <2>;
+						remote-endpoint = <&vin2csi40>;
+					};
+					csi40vin3: endpoint@3 {
+						reg = <3>;
+						remote-endpoint = <&vin3csi40>;
+					};
+				};
+			};
+		};
+
+		csi41: csi2@feab0000 {
+			compatible = "renesas,r8a7795-csi2";
+			reg = <0 0xfeab0000 0 0x10000>;
+			interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 715>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			resets = <&cpg 715>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					csi41vin4: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&vin4csi41>;
+					};
+					csi41vin5: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&vin5csi41>;
+					};
+					csi41vin6: endpoint@2 {
+						reg = <2>;
+						remote-endpoint = <&vin6csi41>;
+					};
+					csi41vin7: endpoint@3 {
+						reg = <3>;
+						remote-endpoint = <&vin7csi41>;
+					};
+				};
+			};
 		};
 
 		hdmi0: hdmi@fead0000 {
@@ -2342,6 +2744,10 @@
 				port@1 {
 					reg = <1>;
 				};
+				port@2 {
+					/* HDMI sound */
+					reg = <2>;
+				};
 			};
 		};
 
@@ -2367,6 +2773,10 @@
 				port@1 {
 					reg = <1>;
 				};
+				port@2 {
+					/* HDMI sound */
+					reg = <2>;
+				};
 			};
 		};
 
@@ -2417,38 +2827,12 @@
 			};
 		};
 
-		tsc: thermal@e6198000 {
-			compatible = "renesas,r8a7795-thermal";
-			reg = <0 0xe6198000 0 0x100>,
-			      <0 0xe61a0000 0 0x100>,
-			      <0 0xe61a8000 0 0x100>;
-			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 522>;
-			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-			resets = <&cpg 522>;
-			#thermal-sensor-cells = <1>;
-			status = "okay";
+		prr: chipid@fff00044 {
+			compatible = "renesas,prr";
+			reg = <0 0xfff00044 0 4>;
 		};
 	};
 
-	timer {
-		compatible = "arm,armv8-timer";
-		interrupts-extended = <&gic GIC_PPI 13
-				       (GIC_CPU_MASK_SIMPLE(8) |
-				       IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 14
-				       (GIC_CPU_MASK_SIMPLE(8) |
-				       IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 11
-				       (GIC_CPU_MASK_SIMPLE(8) |
-				       IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 10
-				       (GIC_CPU_MASK_SIMPLE(8) |
-				       IRQ_TYPE_LEVEL_LOW)>;
-	};
-
 	thermal-zones {
 		sensor_thermal1: sensor-thermal1 {
 			polling-delay-passive = <250>;
@@ -2458,12 +2842,12 @@
 			trips {
 				sensor1_passive: sensor1-passive {
 					temperature = <95000>;
-					hysteresis = <2000>;
+					hysteresis = <1000>;
 					type = "passive";
 				};
 				sensor1_crit: sensor1-crit {
 					temperature = <120000>;
-					hysteresis = <2000>;
+					hysteresis = <1000>;
 					type = "critical";
 				};
 			};
@@ -2484,12 +2868,12 @@
 			trips {
 				sensor2_passive: sensor2-passive {
 					temperature = <95000>;
-					hysteresis = <2000>;
+					hysteresis = <1000>;
 					type = "passive";
 				};
 				sensor2_crit: sensor2-crit {
 					temperature = <120000>;
-					hysteresis = <2000>;
+					hysteresis = <1000>;
 					type = "critical";
 				};
 			};
@@ -2510,12 +2894,12 @@
 			trips {
 				sensor3_passive: sensor3-passive {
 					temperature = <95000>;
-					hysteresis = <2000>;
+					hysteresis = <1000>;
 					type = "passive";
 				};
 				sensor3_crit: sensor3-crit {
 					temperature = <120000>;
-					hysteresis = <2000>;
+					hysteresis = <1000>;
 					type = "critical";
 				};
 			};
@@ -2529,6 +2913,14 @@
 		};
 	};
 
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
 	/* External USB clocks - can be overridden by the board */
 	usb3s0_clk: usb3s0 {
 		compatible = "fixed-clock";
diff --git a/arch/arm/dts/r8a7796-m3ulcb-u-boot.dts b/arch/arm/dts/r8a7796-m3ulcb-u-boot.dts
index a1d13cc..4e96008 100644
--- a/arch/arm/dts/r8a7796-m3ulcb-u-boot.dts
+++ b/arch/arm/dts/r8a7796-m3ulcb-u-boot.dts
@@ -7,3 +7,35 @@
 
 #include "r8a7796-m3ulcb.dts"
 #include "r8a7796-u-boot.dtsi"
+
+/ {
+	cpld {
+		compatible = "renesas,ulcb-cpld";
+		status = "okay";
+		gpio-sck = <&gpio6 8 0>;
+		gpio-mosi = <&gpio6 7 0>;
+		gpio-miso = <&gpio6 10 0>;
+		gpio-sstbz = <&gpio2 3 0>;
+	};
+};
+
+&sdhi2_pins {
+	groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
+	power-source = <1800>;
+};
+
+&sdhi2_pins_uhs {
+	groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
+};
+
+&sdhi0 {
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr104;
+	max-frequency = <208000000>;
+};
+
+&sdhi2 {
+	mmc-hs400-1_8v;
+	max-frequency = <200000000>;
+};
diff --git a/arch/arm/dts/r8a7796-salvator-x-u-boot.dts b/arch/arm/dts/r8a7796-salvator-x-u-boot.dts
index 7a8ad27..44b2f9f 100644
--- a/arch/arm/dts/r8a7796-salvator-x-u-boot.dts
+++ b/arch/arm/dts/r8a7796-salvator-x-u-boot.dts
@@ -7,3 +7,31 @@
 
 #include "r8a7796-salvator-x.dts"
 #include "r8a7796-u-boot.dtsi"
+
+&sdhi2_pins {
+	groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
+	power-source = <1800>;
+};
+
+&sdhi2_pins_uhs {
+	groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
+};
+
+&sdhi0 {
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr104;
+	max-frequency = <208000000>;
+};
+
+&sdhi2 {
+	mmc-hs400-1_8v;
+	max-frequency = <200000000>;
+};
+
+&sdhi3 {
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr104;
+	max-frequency = <208000000>;
+};
diff --git a/arch/arm/dts/r8a7796-salvator-x.dts b/arch/arm/dts/r8a7796-salvator-x.dts
index 62aa27d..052d72a 100644
--- a/arch/arm/dts/r8a7796-salvator-x.dts
+++ b/arch/arm/dts/r8a7796-salvator-x.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the Salvator-X board
+ * Device Tree Source for the Salvator-X board with R-Car M3-W
  *
  * Copyright (C) 2016 Renesas Electronics Corp.
  */
@@ -37,6 +37,11 @@
 		      "dclkin.0", "dclkin.1", "dclkin.2";
 };
 
+&sound_card {
+	dais = <&rsnd_port0	/* ak4613 */
+		&rsnd_port1>;	/* HDMI0  */
+};
+
 &hdmi0 {
 	status = "okay";
 
@@ -47,9 +52,32 @@
 				remote-endpoint = <&hdmi0_con>;
 			};
 		};
+		port@2 {
+			reg = <2>;
+			dw_hdmi0_snd_in: endpoint {
+				remote-endpoint = <&rsnd_endpoint1>;
+			};
+		};
 	};
 };
 
 &hdmi0_con {
 	remote-endpoint = <&rcar_dw_hdmi0_out>;
 };
+
+&rcar_sound {
+	ports {
+		/* rsnd_port0 is on salvator-common */
+		rsnd_port1: port@1 {
+			rsnd_endpoint1: endpoint {
+				remote-endpoint = <&dw_hdmi0_snd_in>;
+
+				dai-format = "i2s";
+				bitclock-master = <&rsnd_endpoint1>;
+				frame-master = <&rsnd_endpoint1>;
+
+				playback = <&ssi2>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/dts/r8a7796-u-boot.dtsi b/arch/arm/dts/r8a7796-u-boot.dtsi
index 7cc60bc..4655259 100644
--- a/arch/arm/dts/r8a7796-u-boot.dtsi
+++ b/arch/arm/dts/r8a7796-u-boot.dtsi
@@ -10,3 +10,13 @@
 &extalr_clk {
 	u-boot,dm-pre-reloc;
 };
+
+&soc {
+	rpc: rpc@0xee200000 {
+		compatible = "renesas,rpc-r8a7796", "renesas,rpc";
+		reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>;
+		clocks = <&cpg CPG_MOD 917>;
+		bank-width = <2>;
+		status = "disabled";
+	};
+};
diff --git a/arch/arm/dts/r8a7796.dtsi b/arch/arm/dts/r8a7796.dtsi
index 011f0e5..bf860f0 100644
--- a/arch/arm/dts/r8a7796.dtsi
+++ b/arch/arm/dts/r8a7796.dtsi
@@ -2,7 +2,7 @@
 /*
  * Device Tree Source for the r8a7796 SoC
  *
- * Copyright (C) 2016 Renesas Electronics Corp.
+ * Copyright (C) 2016-2017 Renesas Electronics Corp.
  */
 
 #include <dt-bindings/clock/r8a7796-cpg-mssr.h>
@@ -57,6 +57,72 @@
 		clock-frequency = <0>;
 	};
 
+	cluster0_opp: opp_table0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-500000000 {
+			opp-hz = /bits/ 64 <500000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1000000000 {
+			opp-hz = /bits/ 64 <1000000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1500000000 {
+			opp-hz = /bits/ 64 <1500000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1600000000 {
+			opp-hz = /bits/ 64 <1600000000>;
+			opp-microvolt = <900000>;
+			clock-latency-ns = <300000>;
+			turbo-mode;
+		};
+		opp-1700000000 {
+			opp-hz = /bits/ 64 <1700000000>;
+			opp-microvolt = <900000>;
+			clock-latency-ns = <300000>;
+			turbo-mode;
+		};
+		opp-1800000000 {
+			opp-hz = /bits/ 64 <1800000000>;
+			opp-microvolt = <960000>;
+			clock-latency-ns = <300000>;
+			turbo-mode;
+		};
+	};
+
+	cluster1_opp: opp_table1 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-800000000 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1000000000 {
+			opp-hz = /bits/ 64 <1000000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1300000000 {
+			opp-hz = /bits/ 64 <1300000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+			turbo-mode;
+		};
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -74,7 +140,7 @@
 		};
 
 		a57_1: cpu@1 {
-			compatible = "arm,cortex-a57","arm,armv8";
+			compatible = "arm,cortex-a57", "arm,armv8";
 			reg = <0x1>;
 			device_type = "cpu";
 			power-domains = <&sysc R8A7796_PD_CA57_CPU1>;
@@ -97,7 +163,7 @@
 		};
 
 		a53_1: cpu@101 {
-			compatible = "arm,cortex-a53","arm,armv8";
+			compatible = "arm,cortex-a53", "arm,armv8";
 			reg = <0x101>;
 			device_type = "cpu";
 			power-domains = <&sysc R8A7796_PD_CA53_CPU1>;
@@ -108,7 +174,7 @@
 		};
 
 		a53_2: cpu@102 {
-			compatible = "arm,cortex-a53","arm,armv8";
+			compatible = "arm,cortex-a53", "arm,armv8";
 			reg = <0x102>;
 			device_type = "cpu";
 			power-domains = <&sysc R8A7796_PD_CA53_CPU2>;
@@ -119,7 +185,7 @@
 		};
 
 		a53_3: cpu@103 {
-			compatible = "arm,cortex-a53","arm,armv8";
+			compatible = "arm,cortex-a53", "arm,armv8";
 			reg = <0x103>;
 			device_type = "cpu";
 			power-domains = <&sysc R8A7796_PD_CA53_CPU3>;
@@ -158,72 +224,6 @@
 		clock-frequency = <0>;
 	};
 
-	cluster0_opp: opp_table0 {
-		compatible = "operating-points-v2";
-		opp-shared;
-
-		opp-500000000 {
-			opp-hz = /bits/ 64 <500000000>;
-			opp-microvolt = <820000>;
-			clock-latency-ns = <300000>;
-		};
-		opp-1000000000 {
-			opp-hz = /bits/ 64 <1000000000>;
-			opp-microvolt = <820000>;
-			clock-latency-ns = <300000>;
-		};
-		opp-1500000000 {
-			opp-hz = /bits/ 64 <1500000000>;
-			opp-microvolt = <820000>;
-			clock-latency-ns = <300000>;
-		};
-		opp-1600000000 {
-			opp-hz = /bits/ 64 <1600000000>;
-			opp-microvolt = <900000>;
-			clock-latency-ns = <300000>;
-			turbo-mode;
-		};
-		opp-1700000000 {
-			opp-hz = /bits/ 64 <1700000000>;
-			opp-microvolt = <900000>;
-			clock-latency-ns = <300000>;
-			turbo-mode;
-		};
-		opp-1800000000 {
-			opp-hz = /bits/ 64 <1800000000>;
-			opp-microvolt = <960000>;
-			clock-latency-ns = <300000>;
-			turbo-mode;
-		};
-	};
-
-	cluster1_opp: opp_table1 {
-		compatible = "operating-points-v2";
-		opp-shared;
-
-		opp-800000000 {
-			opp-hz = /bits/ 64 <800000000>;
-			opp-microvolt = <820000>;
-			clock-latency-ns = <300000>;
-		};
-		opp-1000000000 {
-			opp-hz = /bits/ 64 <1000000000>;
-			opp-microvolt = <820000>;
-			clock-latency-ns = <300000>;
-		};
-		opp-1200000000 {
-			opp-hz = /bits/ 64 <1200000000>;
-			opp-microvolt = <820000>;
-			clock-latency-ns = <300000>;
-		};
-		opp-1300000000 {
-			opp-hz = /bits/ 64 <1300000000>;
-			opp-microvolt = <820000>;
-			clock-latency-ns = <300000>;
-			turbo-mode;
-		};
-	};
-
 	/* External PCIe clock - can be overridden by the board */
 	pcie_bus_clk: pcie_bus {
 		compatible = "fixed-clock";
@@ -231,13 +231,6 @@
 		clock-frequency = <0>;
 	};
 
-	pmu_a57 {
-		compatible = "arm,cortex-a57-pmu";
-		interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
-				      <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-affinity = <&a57_0>, <&a57_1>;
-	};
-
 	pmu_a53 {
 		compatible = "arm,cortex-a53-pmu";
 		interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
@@ -247,6 +240,13 @@
 		interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, <&a53_3>;
 	};
 
+	pmu_a57 {
+		compatible = "arm,cortex-a57-pmu";
+		interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&a57_0>, <&a57_1>;
+	};
+
 	psci {
 		compatible = "arm,psci-1.0", "arm,psci-0.2";
 		method = "smc";
@@ -259,31 +259,14 @@
 		clock-frequency = <0>;
 	};
 
-	soc {
+	soc: soc {
 		compatible = "simple-bus";
 		interrupt-parent = <&gic>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		ranges;
 
-		gic: interrupt-controller@f1010000 {
-			compatible = "arm,gic-400";
-			#interrupt-cells = <3>;
-			#address-cells = <0>;
-			interrupt-controller;
-			reg = <0x0 0xf1010000 0 0x1000>,
-			      <0x0 0xf1020000 0 0x20000>,
-			      <0x0 0xf1040000 0 0x20000>,
-			      <0x0 0xf1060000 0 0x20000>;
-			interrupts = <GIC_PPI 9
-					(GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
-			clocks = <&cpg CPG_MOD 408>;
-			clock-names = "clk";
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 408>;
-		};
-
-		wdt0: watchdog@e6020000 {
+		rwdt: watchdog@e6020000 {
 			compatible = "renesas,r8a7796-wdt",
 				     "renesas,rcar-gen3-wdt";
 			reg = <0 0xe6020000 0 0x0c>;
@@ -418,245 +401,75 @@
 			reg = <0 0xe6060000 0 0x50c>;
 		};
 
-		ipmmu_vi0: mmu@febd0000 {
-			compatible = "renesas,ipmmu-r8a7796";
-			reg = <0 0xfebd0000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 9>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
+		cpg: clock-controller@e6150000 {
+			compatible = "renesas,r8a7796-cpg-mssr";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>, <&extalr_clk>;
+			clock-names = "extal", "extalr";
+			#clock-cells = <2>;
+			#power-domain-cells = <0>;
+			#reset-cells = <1>;
 		};
 
-		ipmmu_vc0: mmu@fe6b0000 {
-			compatible = "renesas,ipmmu-r8a7796";
-			reg = <0 0xfe6b0000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 8>;
-			power-domains = <&sysc R8A7796_PD_A3VC>;
-			#iommu-cells = <1>;
-			status = "disabled";
+		rst: reset-controller@e6160000 {
+			compatible = "renesas,r8a7796-rst";
+			reg = <0 0xe6160000 0 0x0200>;
 		};
 
-		ipmmu_pv0: mmu@fd800000 {
-			compatible = "renesas,ipmmu-r8a7796";
-			reg = <0 0xfd800000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 5>;
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a7796-sysc";
+			reg = <0 0xe6180000 0 0x0400>;
+			#power-domain-cells = <1>;
+		};
+
+		tsc: thermal@e6198000 {
+			compatible = "renesas,r8a7796-thermal";
+			reg = <0 0xe6198000 0 0x100>,
+			      <0 0xe61a0000 0 0x100>,
+			      <0 0xe61a8000 0 0x100>;
+			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 522>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
+			resets = <&cpg 522>;
+			#thermal-sensor-cells = <1>;
+			status = "okay";
 		};
 
-		ipmmu_pv1: mmu@fd950000 {
-			compatible = "renesas,ipmmu-r8a7796";
-			reg = <0 0xfd950000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 6>;
+		intc_ex: interrupt-controller@e61c0000 {
+			compatible = "renesas,intc-ex-r8a7796", "renesas,irqc";
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			reg = <0 0xe61c0000 0 0x200>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 407>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
-			status = "disabled";
+			resets = <&cpg 407>;
 		};
 
-		ipmmu_ir: mmu@ff8b0000 {
-			compatible = "renesas,ipmmu-r8a7796";
-			reg = <0 0xff8b0000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 3>;
-			power-domains = <&sysc R8A7796_PD_A3IR>;
-			#iommu-cells = <1>;
+		i2c0: i2c@e6500000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7796",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6500000 0 0x40>;
+			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 931>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 931>;
+			dmas = <&dmac1 0x91>, <&dmac1 0x90>,
+			       <&dmac2 0x91>, <&dmac2 0x90>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <110>;
 			status = "disabled";
 		};
 
-		ipmmu_hc: mmu@e6570000 {
-			compatible = "renesas,ipmmu-r8a7796";
-			reg = <0 0xe6570000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 2>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
-			status = "disabled";
-		};
-
-		ipmmu_rt: mmu@ffc80000 {
-			compatible = "renesas,ipmmu-r8a7796";
-			reg = <0 0xffc80000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 7>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
-			status = "disabled";
-		};
-
-		ipmmu_mp: mmu@ec670000 {
-			compatible = "renesas,ipmmu-r8a7796";
-			reg = <0 0xec670000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 4>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
-		};
-
-		ipmmu_ds0: mmu@e6740000 {
-			compatible = "renesas,ipmmu-r8a7796";
-			reg = <0 0xe6740000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 0>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
-		};
-
-		ipmmu_ds1: mmu@e7740000 {
-			compatible = "renesas,ipmmu-r8a7796";
-			reg = <0 0xe7740000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 1>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
-		};
-
-		ipmmu_mm: mmu@e67b0000 {
-			compatible = "renesas,ipmmu-r8a7796";
-			reg = <0 0xe67b0000 0 0x1000>;
-			interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
-		};
-
-		cpg: clock-controller@e6150000 {
-			compatible = "renesas,r8a7796-cpg-mssr";
-			reg = <0 0xe6150000 0 0x1000>;
-			clocks = <&extal_clk>, <&extalr_clk>;
-			clock-names = "extal", "extalr";
-			#clock-cells = <2>;
-			#power-domain-cells = <0>;
-			#reset-cells = <1>;
-		};
-
-		rst: reset-controller@e6160000 {
-			compatible = "renesas,r8a7796-rst";
-			reg = <0 0xe6160000 0 0x0200>;
-		};
-
-		prr: chipid@fff00044 {
-			compatible = "renesas,prr";
-			reg = <0 0xfff00044 0 4>;
-		};
-
-		sysc: system-controller@e6180000 {
-			compatible = "renesas,r8a7796-sysc";
-			reg = <0 0xe6180000 0 0x0400>;
-			#power-domain-cells = <1>;
-		};
-
-		intc_ex: interrupt-controller@e61c0000 {
-			compatible = "renesas,intc-ex-r8a7796", "renesas,irqc";
-			#interrupt-cells = <2>;
-			interrupt-controller;
-			reg = <0 0xe61c0000 0 0x200>;
-			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 407>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 407>;
-		};
-
-		i2c_dvfs: i2c@e60b0000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,iic-r8a7796",
-				     "renesas,rcar-gen3-iic",
-				     "renesas,rmobile-iic";
-			reg = <0 0xe60b0000 0 0x425>;
-			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 926>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 926>;
-			dmas = <&dmac0 0x11>, <&dmac0 0x10>;
-			dma-names = "tx", "rx";
-			status = "disabled";
-		};
-
-		pwm0: pwm@e6e30000 {
-			compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar";
-			reg = <0 0xe6e30000 0 8>;
-			#pwm-cells = <2>;
-			clocks = <&cpg CPG_MOD 523>;
-			resets = <&cpg 523>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			status = "disabled";
-		};
-
-		pwm1: pwm@e6e31000 {
-			compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar";
-			reg = <0 0xe6e31000 0 8>;
-			#pwm-cells = <2>;
-			clocks = <&cpg CPG_MOD 523>;
-			resets = <&cpg 523>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			status = "disabled";
-		};
-
-		pwm2: pwm@e6e32000 {
-			compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar";
-			reg = <0 0xe6e32000 0 8>;
-			#pwm-cells = <2>;
-			clocks = <&cpg CPG_MOD 523>;
-			resets = <&cpg 523>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			status = "disabled";
-		};
-
-		pwm3: pwm@e6e33000 {
-			compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar";
-			reg = <0 0xe6e33000 0 8>;
-			#pwm-cells = <2>;
-			clocks = <&cpg CPG_MOD 523>;
-			resets = <&cpg 523>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			status = "disabled";
-		};
-
-		pwm4: pwm@e6e34000 {
-			compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar";
-			reg = <0 0xe6e34000 0 8>;
-			#pwm-cells = <2>;
-			clocks = <&cpg CPG_MOD 523>;
-			resets = <&cpg 523>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			status = "disabled";
-		};
-
-		pwm5: pwm@e6e35000 {
-			compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar";
-			reg = <0 0xe6e35000 0 8>;
-			#pwm-cells = <2>;
-			clocks = <&cpg CPG_MOD 523>;
-			resets = <&cpg 523>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			status = "disabled";
-		};
-
-		pwm6: pwm@e6e36000 {
-			compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar";
-			reg = <0 0xe6e36000 0 8>;
-			#pwm-cells = <2>;
-			clocks = <&cpg CPG_MOD 523>;
-			resets = <&cpg 523>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			status = "disabled";
-		};
-
-		i2c0: i2c@e6500000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a7796",
-				     "renesas,rcar-gen3-i2c";
-			reg = <0 0xe6500000 0 0x40>;
-			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 931>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 931>;
-			dmas = <&dmac1 0x91>, <&dmac1 0x90>,
-			       <&dmac2 0x91>, <&dmac2 0x90>;
-			dma-names = "tx", "rx", "tx", "rx";
-			i2c-scl-internal-delay-ns = <110>;
-			status = "disabled";
-		};
-
 		i2c1: i2c@e6508000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -755,247 +568,40 @@
 			status = "disabled";
 		};
 
-		can0: can@e6c30000 {
-			compatible = "renesas,can-r8a7796",
-				     "renesas,rcar-gen3-can";
-			reg = <0 0xe6c30000 0 0x1000>;
-			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 916>,
-			       <&cpg CPG_CORE R8A7796_CLK_CANFD>,
-			       <&can_clk>;
-			clock-names = "clkp1", "clkp2", "can_clk";
-			assigned-clocks = <&cpg CPG_CORE R8A7796_CLK_CANFD>;
-			assigned-clock-rates = <40000000>;
+		i2c_dvfs: i2c@e60b0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,iic-r8a7796",
+				     "renesas,rcar-gen3-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe60b0000 0 0x425>;
+			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 926>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 916>;
+			resets = <&cpg 926>;
+			dmas = <&dmac0 0x11>, <&dmac0 0x10>;
+			dma-names = "tx", "rx";
 			status = "disabled";
 		};
 
-		can1: can@e6c38000 {
-			compatible = "renesas,can-r8a7796",
-				     "renesas,rcar-gen3-can";
-			reg = <0 0xe6c38000 0 0x1000>;
-			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 915>,
-			       <&cpg CPG_CORE R8A7796_CLK_CANFD>,
-			       <&can_clk>;
-			clock-names = "clkp1", "clkp2", "can_clk";
-			assigned-clocks = <&cpg CPG_CORE R8A7796_CLK_CANFD>;
-			assigned-clock-rates = <40000000>;
+		hscif0: serial@e6540000 {
+			compatible = "renesas,hscif-r8a7796",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe6540000 0 0x60>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 520>,
+				 <&cpg CPG_CORE R8A7796_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x31>, <&dmac1 0x30>,
+			       <&dmac2 0x31>, <&dmac2 0x30>;
+			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 915>;
+			resets = <&cpg 520>;
 			status = "disabled";
 		};
 
-		canfd: can@e66c0000 {
-			compatible = "renesas,r8a7796-canfd",
-				     "renesas,rcar-gen3-canfd";
-			reg = <0 0xe66c0000 0 0x8000>;
-			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
-				   <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 914>,
-			       <&cpg CPG_CORE R8A7796_CLK_CANFD>,
-			       <&can_clk>;
-			clock-names = "fck", "canfd", "can_clk";
-			assigned-clocks = <&cpg CPG_CORE R8A7796_CLK_CANFD>;
-			assigned-clock-rates = <40000000>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 914>;
-			status = "disabled";
-
-			channel0 {
-				status = "disabled";
-			};
-
-			channel1 {
-				status = "disabled";
-			};
-		};
-
-		drif00: rif@e6f40000 {
-			compatible = "renesas,r8a7796-drif",
-				     "renesas,rcar-gen3-drif";
-			reg = <0 0xe6f40000 0 0x64>;
-			interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 515>;
-			clock-names = "fck";
-			dmas = <&dmac1 0x20>, <&dmac2 0x20>;
-			dma-names = "rx", "rx";
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 515>;
-			renesas,bonding = <&drif01>;
-			status = "disabled";
-		};
-
-		drif01: rif@e6f50000 {
-			compatible = "renesas,r8a7796-drif",
-				     "renesas,rcar-gen3-drif";
-			reg = <0 0xe6f50000 0 0x64>;
-			interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 514>;
-			clock-names = "fck";
-			dmas = <&dmac1 0x22>, <&dmac2 0x22>;
-			dma-names = "rx", "rx";
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 514>;
-			renesas,bonding = <&drif00>;
-			status = "disabled";
-		};
-
-		drif10: rif@e6f60000 {
-			compatible = "renesas,r8a7796-drif",
-				     "renesas,rcar-gen3-drif";
-			reg = <0 0xe6f60000 0 0x64>;
-			interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 513>;
-			clock-names = "fck";
-			dmas = <&dmac1 0x24>, <&dmac2 0x24>;
-			dma-names = "rx", "rx";
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 513>;
-			renesas,bonding = <&drif11>;
-			status = "disabled";
-		};
-
-		drif11: rif@e6f70000 {
-			compatible = "renesas,r8a7796-drif",
-				     "renesas,rcar-gen3-drif";
-			reg = <0 0xe6f70000 0 0x64>;
-			interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 512>;
-			clock-names = "fck";
-			dmas = <&dmac1 0x26>, <&dmac2 0x26>;
-			dma-names = "rx", "rx";
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 512>;
-			renesas,bonding = <&drif10>;
-			status = "disabled";
-		};
-
-		drif20: rif@e6f80000 {
-			compatible = "renesas,r8a7796-drif",
-				     "renesas,rcar-gen3-drif";
-			reg = <0 0xe6f80000 0 0x64>;
-			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 511>;
-			clock-names = "fck";
-			dmas = <&dmac1 0x28>, <&dmac2 0x28>;
-			dma-names = "rx", "rx";
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 511>;
-			renesas,bonding = <&drif21>;
-			status = "disabled";
-		};
-
-		drif21: rif@e6f90000 {
-			compatible = "renesas,r8a7796-drif",
-				     "renesas,rcar-gen3-drif";
-			reg = <0 0xe6f90000 0 0x64>;
-			interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 510>;
-			clock-names = "fck";
-			dmas = <&dmac1 0x2a>, <&dmac2 0x2a>;
-			dma-names = "rx", "rx";
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 510>;
-			renesas,bonding = <&drif20>;
-			status = "disabled";
-		};
-
-		drif30: rif@e6fa0000 {
-			compatible = "renesas,r8a7796-drif",
-				     "renesas,rcar-gen3-drif";
-			reg = <0 0xe6fa0000 0 0x64>;
-			interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 509>;
-			clock-names = "fck";
-			dmas = <&dmac1 0x2c>, <&dmac2 0x2c>;
-			dma-names = "rx", "rx";
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 509>;
-			renesas,bonding = <&drif31>;
-			status = "disabled";
-		};
-
-		drif31: rif@e6fb0000 {
-			compatible = "renesas,r8a7796-drif",
-				     "renesas,rcar-gen3-drif";
-			reg = <0 0xe6fb0000 0 0x64>;
-			interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 508>;
-			clock-names = "fck";
-			dmas = <&dmac1 0x2e>, <&dmac2 0x2e>;
-			dma-names = "rx", "rx";
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 508>;
-			renesas,bonding = <&drif30>;
-			status = "disabled";
-		};
-
-		avb: ethernet@e6800000 {
-			compatible = "renesas,etheravb-r8a7796",
-				     "renesas,etheravb-rcar-gen3";
-			reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
-			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "ch0", "ch1", "ch2", "ch3",
-					  "ch4", "ch5", "ch6", "ch7",
-					  "ch8", "ch9", "ch10", "ch11",
-					  "ch12", "ch13", "ch14", "ch15",
-					  "ch16", "ch17", "ch18", "ch19",
-					  "ch20", "ch21", "ch22", "ch23",
-					  "ch24";
-			clocks = <&cpg CPG_MOD 812>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 812>;
-			phy-mode = "rgmii";
-			iommus = <&ipmmu_ds0 16>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
-		hscif0: serial@e6540000 {
-			compatible = "renesas,hscif-r8a7796",
-				     "renesas,rcar-gen3-hscif",
-				     "renesas,hscif";
-			reg = <0 0xe6540000 0 0x60>;
-			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 520>,
-				 <&cpg CPG_CORE R8A7796_CLK_S3D1>,
-				 <&scif_clk>;
-			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x31>, <&dmac1 0x30>,
-			       <&dmac2 0x31>, <&dmac2 0x30>;
-			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 520>;
-			status = "disabled";
-		};
-
 		hscif1: serial@e6550000 {
 			compatible = "renesas,hscif-r8a7796",
 				     "renesas,rcar-gen3-hscif",
@@ -1066,162 +672,61 @@
 			status = "disabled";
 		};
 
-		scif0: serial@e6e60000 {
-			compatible = "renesas,scif-r8a7796",
-				     "renesas,rcar-gen3-scif", "renesas,scif";
-			reg = <0 0xe6e60000 0 64>;
-			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 207>,
-				 <&cpg CPG_CORE R8A7796_CLK_S3D1>,
-				 <&scif_clk>;
-			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x51>, <&dmac1 0x50>,
-			       <&dmac2 0x51>, <&dmac2 0x50>;
-			dma-names = "tx", "rx", "tx", "rx";
+		hsusb: usb@e6590000 {
+			compatible = "renesas,usbhs-r8a7796",
+				     "renesas,rcar-gen3-usbhs";
+			reg = <0 0xe6590000 0 0x100>;
+			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 704>;
+			dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
+			       <&usb_dmac1 0>, <&usb_dmac1 1>;
+			dma-names = "ch0", "ch1", "ch2", "ch3";
+			renesas,buswait = <11>;
+			phys = <&usb2_phy0>;
+			phy-names = "usb";
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 207>;
+			resets = <&cpg 704>;
 			status = "disabled";
 		};
 
-		scif1: serial@e6e68000 {
-			compatible = "renesas,scif-r8a7796",
-				     "renesas,rcar-gen3-scif", "renesas,scif";
-			reg = <0 0xe6e68000 0 64>;
-			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 206>,
-				 <&cpg CPG_CORE R8A7796_CLK_S3D1>,
-				 <&scif_clk>;
-			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x53>, <&dmac1 0x52>,
-			       <&dmac2 0x53>, <&dmac2 0x52>;
-			dma-names = "tx", "rx", "tx", "rx";
+		usb_dmac0: dma-controller@e65a0000 {
+			compatible = "renesas,r8a7796-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe65a0000 0 0x100>;
+			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 330>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 206>;
-			status = "disabled";
+			resets = <&cpg 330>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
 		};
 
-		scif2: serial@e6e88000 {
-			compatible = "renesas,scif-r8a7796",
-				     "renesas,rcar-gen3-scif", "renesas,scif";
-			reg = <0 0xe6e88000 0 64>;
-			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 310>,
-				 <&cpg CPG_CORE R8A7796_CLK_S3D1>,
-				 <&scif_clk>;
-			clock-names = "fck", "brg_int", "scif_clk";
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 310>;
-			status = "disabled";
-		};
-
-		scif3: serial@e6c50000 {
-			compatible = "renesas,scif-r8a7796",
-				     "renesas,rcar-gen3-scif", "renesas,scif";
-			reg = <0 0xe6c50000 0 64>;
-			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 204>,
-				 <&cpg CPG_CORE R8A7796_CLK_S3D1>,
-				 <&scif_clk>;
-			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac0 0x57>, <&dmac0 0x56>;
-			dma-names = "tx", "rx";
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 204>;
-			status = "disabled";
-		};
-
-		scif4: serial@e6c40000 {
-			compatible = "renesas,scif-r8a7796",
-				     "renesas,rcar-gen3-scif", "renesas,scif";
-			reg = <0 0xe6c40000 0 64>;
-			interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 203>,
-				 <&cpg CPG_CORE R8A7796_CLK_S3D1>,
-				 <&scif_clk>;
-			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac0 0x59>, <&dmac0 0x58>;
-			dma-names = "tx", "rx";
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 203>;
-			status = "disabled";
-		};
-
-		scif5: serial@e6f30000 {
-			compatible = "renesas,scif-r8a7796",
-				     "renesas,rcar-gen3-scif", "renesas,scif";
-			reg = <0 0xe6f30000 0 64>;
-			interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 202>,
-				 <&cpg CPG_CORE R8A7796_CLK_S3D1>,
-				 <&scif_clk>;
-			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x5b>, <&dmac1 0x5a>,
-			       <&dmac2 0x5b>, <&dmac2 0x5a>;
-			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 202>;
-			status = "disabled";
-		};
-
-		msiof0: spi@e6e90000 {
-			compatible = "renesas,msiof-r8a7796",
-				     "renesas,rcar-gen3-msiof";
-			reg = <0 0xe6e90000 0 0x0064>;
-			interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 211>;
-			dmas = <&dmac1 0x41>, <&dmac1 0x40>,
-			       <&dmac2 0x41>, <&dmac2 0x40>;
-			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 211>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
-		msiof1: spi@e6ea0000 {
-			compatible = "renesas,msiof-r8a7796",
-				     "renesas,rcar-gen3-msiof";
-			reg = <0 0xe6ea0000 0 0x0064>;
-			interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 210>;
-			dmas = <&dmac1 0x43>, <&dmac1 0x42>,
-			       <&dmac2 0x43>, <&dmac2 0x42>;
-			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 210>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
-		msiof2: spi@e6c00000 {
-			compatible = "renesas,msiof-r8a7796",
-				     "renesas,rcar-gen3-msiof";
-			reg = <0 0xe6c00000 0 0x0064>;
-			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 209>;
-			dmas = <&dmac0 0x45>, <&dmac0 0x44>;
-			dma-names = "tx", "rx";
+		usb_dmac1: dma-controller@e65b0000 {
+			compatible = "renesas,r8a7796-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe65b0000 0 0x100>;
+			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 331>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 209>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
+			resets = <&cpg 331>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
 		};
 
-		msiof3: spi@e6c10000 {
-			compatible = "renesas,msiof-r8a7796",
-				     "renesas,rcar-gen3-msiof";
-			reg = <0 0xe6c10000 0 0x0064>;
-			interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 208>;
-			dmas = <&dmac0 0x47>, <&dmac0 0x46>;
-			dma-names = "tx", "rx";
+		usb3_phy0: usb-phy@e65ee000 {
+			compatible = "renesas,r8a7796-usb3-phy",
+				     "renesas,rcar-gen3-usb3-phy";
+			reg = <0 0xe65ee000 0 0x90>;
+			clocks = <&cpg CPG_MOD 328>, <&usb3s0_clk>,
+				 <&usb_extal_clk>;
+			clock-names = "usb3-if", "usb3s_clk", "usb_extal";
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 208>;
-			#address-cells = <1>;
-			#size-cells = <0>;
+			resets = <&cpg 328>;
+			#phy-cells = <0>;
 			status = "disabled";
 		};
 
@@ -1351,312 +856,801 @@
 			       <&ipmmu_ds1 30>, <&ipmmu_ds1 31>;
 		};
 
-		audma0: dma-controller@ec700000 {
-			compatible = "renesas,dmac-r8a7796",
-				     "renesas,rcar-dmac";
-			reg = <0 0xec700000 0 0x10000>;
-			interrupts = <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "error",
-					"ch0", "ch1", "ch2", "ch3",
-					"ch4", "ch5", "ch6", "ch7",
-					"ch8", "ch9", "ch10", "ch11",
-					"ch12", "ch13", "ch14", "ch15";
-			clocks = <&cpg CPG_MOD 502>;
-			clock-names = "fck";
+		ipmmu_ds0: mmu@e6740000 {
+			compatible = "renesas,ipmmu-r8a7796";
+			reg = <0 0xe6740000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 0>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 502>;
-			#dma-cells = <1>;
-			dma-channels = <16>;
-			iommus = <&ipmmu_mp 0>, <&ipmmu_mp 1>,
-			       <&ipmmu_mp 2>, <&ipmmu_mp 3>,
-			       <&ipmmu_mp 4>, <&ipmmu_mp 5>,
-			       <&ipmmu_mp 6>, <&ipmmu_mp 7>,
-			       <&ipmmu_mp 8>, <&ipmmu_mp 9>,
-			       <&ipmmu_mp 10>, <&ipmmu_mp 11>,
-			       <&ipmmu_mp 12>, <&ipmmu_mp 13>,
-			       <&ipmmu_mp 14>, <&ipmmu_mp 15>;
+			#iommu-cells = <1>;
 		};
 
-		audma1: dma-controller@ec720000 {
-			compatible = "renesas,dmac-r8a7796",
-				     "renesas,rcar-dmac";
-			reg = <0 0xec720000 0 0x10000>;
-			interrupts = <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "error",
-					"ch0", "ch1", "ch2", "ch3",
-					"ch4", "ch5", "ch6", "ch7",
-					"ch8", "ch9", "ch10", "ch11",
-					"ch12", "ch13", "ch14", "ch15";
-			clocks = <&cpg CPG_MOD 501>;
-			clock-names = "fck";
+		ipmmu_ds1: mmu@e7740000 {
+			compatible = "renesas,ipmmu-r8a7796";
+			reg = <0 0xe7740000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 1>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 501>;
-			#dma-cells = <1>;
-			dma-channels = <16>;
-			iommus = <&ipmmu_mp 16>, <&ipmmu_mp 17>,
-			       <&ipmmu_mp 18>, <&ipmmu_mp 19>,
-			       <&ipmmu_mp 20>, <&ipmmu_mp 21>,
-			       <&ipmmu_mp 22>, <&ipmmu_mp 23>,
-			       <&ipmmu_mp 24>, <&ipmmu_mp 25>,
-			       <&ipmmu_mp 26>, <&ipmmu_mp 27>,
-			       <&ipmmu_mp 28>, <&ipmmu_mp 29>,
-			       <&ipmmu_mp 30>, <&ipmmu_mp 31>;
+			#iommu-cells = <1>;
 		};
 
-		usb_dmac0: dma-controller@e65a0000 {
-			compatible = "renesas,r8a7796-usb-dmac",
-				     "renesas,usb-dmac";
-			reg = <0 0xe65a0000 0 0x100>;
-			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "ch0", "ch1";
-			clocks = <&cpg CPG_MOD 330>;
+		ipmmu_hc: mmu@e6570000 {
+			compatible = "renesas,ipmmu-r8a7796";
+			reg = <0 0xe6570000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 2>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 330>;
-			#dma-cells = <1>;
-			dma-channels = <2>;
+			#iommu-cells = <1>;
 		};
 
-		usb_dmac1: dma-controller@e65b0000 {
-			compatible = "renesas,r8a7796-usb-dmac",
-				     "renesas,usb-dmac";
-			reg = <0 0xe65b0000 0 0x100>;
-			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "ch0", "ch1";
-			clocks = <&cpg CPG_MOD 331>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 331>;
-			#dma-cells = <1>;
-			dma-channels = <2>;
+		ipmmu_ir: mmu@ff8b0000 {
+			compatible = "renesas,ipmmu-r8a7796";
+			reg = <0 0xff8b0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 3>;
+			power-domains = <&sysc R8A7796_PD_A3IR>;
+			#iommu-cells = <1>;
 		};
 
-		hsusb: usb@e6590000 {
-			compatible = "renesas,usbhs-r8a7796",
-				     "renesas,rcar-gen3-usbhs";
-			reg = <0 0xe6590000 0 0x100>;
-			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 704>;
-			dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
-			       <&usb_dmac1 0>, <&usb_dmac1 1>;
-			dma-names = "ch0", "ch1", "ch2", "ch3";
-			renesas,buswait = <11>;
-			phys = <&usb2_phy0>;
-			phy-names = "usb";
+		ipmmu_mm: mmu@e67b0000 {
+			compatible = "renesas,ipmmu-r8a7796";
+			reg = <0 0xe67b0000 0 0x1000>;
+			interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 704>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_mp: mmu@ec670000 {
+			compatible = "renesas,ipmmu-r8a7796";
+			reg = <0 0xec670000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 4>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_pv0: mmu@fd800000 {
+			compatible = "renesas,ipmmu-r8a7796";
+			reg = <0 0xfd800000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 5>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_pv1: mmu@fd950000 {
+			compatible = "renesas,ipmmu-r8a7796";
+			reg = <0 0xfd950000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 6>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_rt: mmu@ffc80000 {
+			compatible = "renesas,ipmmu-r8a7796";
+			reg = <0 0xffc80000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 7>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vc0: mmu@fe6b0000 {
+			compatible = "renesas,ipmmu-r8a7796";
+			reg = <0 0xfe6b0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 8>;
+			power-domains = <&sysc R8A7796_PD_A3VC>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vi0: mmu@febd0000 {
+			compatible = "renesas,ipmmu-r8a7796";
+			reg = <0 0xfebd0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 9>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		avb: ethernet@e6800000 {
+			compatible = "renesas,etheravb-r8a7796",
+				     "renesas,etheravb-rcar-gen3";
+			reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
+			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15",
+					  "ch16", "ch17", "ch18", "ch19",
+					  "ch20", "ch21", "ch22", "ch23",
+					  "ch24";
+			clocks = <&cpg CPG_MOD 812>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 812>;
+			phy-mode = "rgmii";
+			iommus = <&ipmmu_ds0 16>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		can0: can@e6c30000 {
+			compatible = "renesas,can-r8a7796",
+				     "renesas,rcar-gen3-can";
+			reg = <0 0xe6c30000 0 0x1000>;
+			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 916>,
+			       <&cpg CPG_CORE R8A7796_CLK_CANFD>,
+			       <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			assigned-clocks = <&cpg CPG_CORE R8A7796_CLK_CANFD>;
+			assigned-clock-rates = <40000000>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 916>;
+			status = "disabled";
+		};
+
+		can1: can@e6c38000 {
+			compatible = "renesas,can-r8a7796",
+				     "renesas,rcar-gen3-can";
+			reg = <0 0xe6c38000 0 0x1000>;
+			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 915>,
+			       <&cpg CPG_CORE R8A7796_CLK_CANFD>,
+			       <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			assigned-clocks = <&cpg CPG_CORE R8A7796_CLK_CANFD>;
+			assigned-clock-rates = <40000000>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 915>;
+			status = "disabled";
+		};
+
+		canfd: can@e66c0000 {
+			compatible = "renesas,r8a7796-canfd",
+				     "renesas,rcar-gen3-canfd";
+			reg = <0 0xe66c0000 0 0x8000>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+				   <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 914>,
+			       <&cpg CPG_CORE R8A7796_CLK_CANFD>,
+			       <&can_clk>;
+			clock-names = "fck", "canfd", "can_clk";
+			assigned-clocks = <&cpg CPG_CORE R8A7796_CLK_CANFD>;
+			assigned-clock-rates = <40000000>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 914>;
+			status = "disabled";
+
+			channel0 {
+				status = "disabled";
+			};
+
+			channel1 {
+				status = "disabled";
+			};
+		};
+
+		pwm0: pwm@e6e30000 {
+			compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar";
+			reg = <0 0xe6e30000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm1: pwm@e6e31000 {
+			compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar";
+			reg = <0 0xe6e31000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm2: pwm@e6e32000 {
+			compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar";
+			reg = <0 0xe6e32000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm3: pwm@e6e33000 {
+			compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar";
+			reg = <0 0xe6e33000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm4: pwm@e6e34000 {
+			compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar";
+			reg = <0 0xe6e34000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm5: pwm@e6e35000 {
+			compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar";
+			reg = <0 0xe6e35000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm6: pwm@e6e36000 {
+			compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar";
+			reg = <0 0xe6e36000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scif0: serial@e6e60000 {
+			compatible = "renesas,scif-r8a7796",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6e60000 0 64>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 207>,
+				 <&cpg CPG_CORE R8A7796_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x51>, <&dmac1 0x50>,
+			       <&dmac2 0x51>, <&dmac2 0x50>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 207>;
+			status = "disabled";
+		};
+
+		scif1: serial@e6e68000 {
+			compatible = "renesas,scif-r8a7796",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6e68000 0 64>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 206>,
+				 <&cpg CPG_CORE R8A7796_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x53>, <&dmac1 0x52>,
+			       <&dmac2 0x53>, <&dmac2 0x52>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 206>;
+			status = "disabled";
+		};
+
+		scif2: serial@e6e88000 {
+			compatible = "renesas,scif-r8a7796",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6e88000 0 64>;
+			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 310>,
+				 <&cpg CPG_CORE R8A7796_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 310>;
+			status = "disabled";
+		};
+
+		scif3: serial@e6c50000 {
+			compatible = "renesas,scif-r8a7796",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6c50000 0 64>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 204>,
+				 <&cpg CPG_CORE R8A7796_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x57>, <&dmac0 0x56>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 204>;
+			status = "disabled";
+		};
+
+		scif4: serial@e6c40000 {
+			compatible = "renesas,scif-r8a7796",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6c40000 0 64>;
+			interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 203>,
+				 <&cpg CPG_CORE R8A7796_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x59>, <&dmac0 0x58>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 203>;
+			status = "disabled";
+		};
+
+		scif5: serial@e6f30000 {
+			compatible = "renesas,scif-r8a7796",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6f30000 0 64>;
+			interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 202>,
+				 <&cpg CPG_CORE R8A7796_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x5b>, <&dmac1 0x5a>,
+			       <&dmac2 0x5b>, <&dmac2 0x5a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 202>;
+			status = "disabled";
+		};
+
+		msiof0: spi@e6e90000 {
+			compatible = "renesas,msiof-r8a7796",
+				     "renesas,rcar-gen3-msiof";
+			reg = <0 0xe6e90000 0 0x0064>;
+			interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 211>;
+			dmas = <&dmac1 0x41>, <&dmac1 0x40>,
+			       <&dmac2 0x41>, <&dmac2 0x40>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 211>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		msiof1: spi@e6ea0000 {
+			compatible = "renesas,msiof-r8a7796",
+				     "renesas,rcar-gen3-msiof";
+			reg = <0 0xe6ea0000 0 0x0064>;
+			interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 210>;
+			dmas = <&dmac1 0x43>, <&dmac1 0x42>,
+			       <&dmac2 0x43>, <&dmac2 0x42>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 210>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		msiof2: spi@e6c00000 {
+			compatible = "renesas,msiof-r8a7796",
+				     "renesas,rcar-gen3-msiof";
+			reg = <0 0xe6c00000 0 0x0064>;
+			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 209>;
+			dmas = <&dmac0 0x45>, <&dmac0 0x44>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 209>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		msiof3: spi@e6c10000 {
+			compatible = "renesas,msiof-r8a7796",
+				     "renesas,rcar-gen3-msiof";
+			reg = <0 0xe6c10000 0 0x0064>;
+			interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 208>;
+			dmas = <&dmac0 0x47>, <&dmac0 0x46>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 208>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		vin0: video@e6ef0000 {
+			compatible = "renesas,vin-r8a7796";
+			reg = <0 0xe6ef0000 0 0x1000>;
+			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 811>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 811>;
+			renesas,id = <0>;
 			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin0csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin0>;
+					};
+					vin0csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin0>;
+					};
+				};
+			};
 		};
 
-		usb3_phy0: usb-phy@e65ee000 {
-			compatible = "renesas,r8a7796-usb3-phy",
-				     "renesas,rcar-gen3-usb3-phy";
-			reg = <0 0xe65ee000 0 0x90>;
-			clocks = <&cpg CPG_MOD 328>, <&usb3s0_clk>,
-				 <&usb_extal_clk>;
-			clock-names = "usb3-if", "usb3s_clk", "usb_extal";
+		vin1: video@e6ef1000 {
+			compatible = "renesas,vin-r8a7796";
+			reg = <0 0xe6ef1000 0 0x1000>;
+			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 810>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 328>;
-			#phy-cells = <0>;
+			resets = <&cpg 810>;
+			renesas,id = <1>;
 			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin1csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin1>;
+					};
+					vin1csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin1>;
+					};
+				};
+			};
 		};
 
-		xhci0: usb@ee000000 {
-			compatible = "renesas,xhci-r8a7796",
-				     "renesas,rcar-gen3-xhci";
-			reg = <0 0xee000000 0 0xc00>;
-			interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 328>;
+		vin2: video@e6ef2000 {
+			compatible = "renesas,vin-r8a7796";
+			reg = <0 0xe6ef2000 0 0x1000>;
+			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 809>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 328>;
+			resets = <&cpg 809>;
+			renesas,id = <2>;
 			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin2csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin2>;
+					};
+					vin2csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin2>;
+					};
+				};
+			};
 		};
 
-		usb3_peri0: usb@ee020000 {
-			compatible = "renesas,r8a7796-usb3-peri",
-				     "renesas,rcar-gen3-usb3-peri";
-			reg = <0 0xee020000 0 0x400>;
-			interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 328>;
+		vin3: video@e6ef3000 {
+			compatible = "renesas,vin-r8a7796";
+			reg = <0 0xe6ef3000 0 0x1000>;
+			interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 808>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 328>;
+			resets = <&cpg 808>;
+			renesas,id = <3>;
 			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin3csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin3>;
+					};
+					vin3csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin3>;
+					};
+				};
+			};
 		};
 
-		ohci0: usb@ee080000 {
-			compatible = "generic-ohci";
-			reg = <0 0xee080000 0 0x100>;
-			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 703>;
-			phys = <&usb2_phy0>;
-			phy-names = "usb";
+		vin4: video@e6ef4000 {
+			compatible = "renesas,vin-r8a7796";
+			reg = <0 0xe6ef4000 0 0x1000>;
+			interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 807>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 703>;
+			resets = <&cpg 807>;
+			renesas,id = <4>;
 			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin4csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin4>;
+					};
+					vin4csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin4>;
+					};
+				};
+			};
 		};
 
-		ehci0: usb@ee080100 {
-			compatible = "generic-ehci";
-			reg = <0 0xee080100 0 0x100>;
-			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 703>;
-			phys = <&usb2_phy0>;
-			phy-names = "usb";
-			companion= <&ohci0>;
+		vin5: video@e6ef5000 {
+			compatible = "renesas,vin-r8a7796";
+			reg = <0 0xe6ef5000 0 0x1000>;
+			interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 806>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 703>;
+			resets = <&cpg 806>;
+			renesas,id = <5>;
 			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin5csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin5>;
+					};
+					vin5csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin5>;
+					};
+				};
+			};
 		};
 
-		usb2_phy0: usb-phy@ee080200 {
-			compatible = "renesas,usb2-phy-r8a7796",
-				     "renesas,rcar-gen3-usb2-phy";
-			reg = <0 0xee080200 0 0x700>;
-			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 703>;
+		vin6: video@e6ef6000 {
+			compatible = "renesas,vin-r8a7796";
+			reg = <0 0xe6ef6000 0 0x1000>;
+			interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 805>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 703>;
-			#phy-cells = <0>;
+			resets = <&cpg 805>;
+			renesas,id = <6>;
 			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin6csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin6>;
+					};
+					vin6csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin6>;
+					};
+				};
+			};
 		};
 
-		ohci1: usb@ee0a0000 {
-			compatible = "generic-ohci";
-			reg = <0 0xee0a0000 0 0x100>;
-			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 702>;
-			phys = <&usb2_phy1>;
-			phy-names = "usb";
+		vin7: video@e6ef7000 {
+			compatible = "renesas,vin-r8a7796";
+			reg = <0 0xe6ef7000 0 0x1000>;
+			interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 804>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 702>;
+			resets = <&cpg 804>;
+			renesas,id = <7>;
 			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin7csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin7>;
+					};
+					vin7csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin7>;
+					};
+				};
+			};
 		};
 
-		ehci1: usb@ee0a0100 {
-			compatible = "generic-ehci";
-			reg = <0 0xee0a0100 0 0x100>;
-			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 702>;
-			phys = <&usb2_phy1>;
-			phy-names = "usb";
-			companion= <&ohci1>;
+		drif00: rif@e6f40000 {
+			compatible = "renesas,r8a7796-drif",
+				     "renesas,rcar-gen3-drif";
+			reg = <0 0xe6f40000 0 0x64>;
+			interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 515>;
+			clock-names = "fck";
+			dmas = <&dmac1 0x20>, <&dmac2 0x20>;
+			dma-names = "rx", "rx";
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 702>;
+			resets = <&cpg 515>;
+			renesas,bonding = <&drif01>;
 			status = "disabled";
 		};
 
-		usb2_phy1: usb-phy@ee0a0200 {
-			compatible = "renesas,usb2-phy-r8a7796",
-				     "renesas,rcar-gen3-usb2-phy";
-			reg = <0 0xee0a0200 0 0x700>;
-			clocks = <&cpg CPG_MOD 702>;
+		drif01: rif@e6f50000 {
+			compatible = "renesas,r8a7796-drif",
+				     "renesas,rcar-gen3-drif";
+			reg = <0 0xe6f50000 0 0x64>;
+			interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 514>;
+			clock-names = "fck";
+			dmas = <&dmac1 0x22>, <&dmac2 0x22>;
+			dma-names = "rx", "rx";
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 702>;
-			#phy-cells = <0>;
+			resets = <&cpg 514>;
+			renesas,bonding = <&drif00>;
 			status = "disabled";
 		};
 
-		rpc: rpc@0xee200000 {
-			compatible = "renesas,rpc-r8a7796", "renesas,rpc";
-			reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>;
-			clocks = <&cpg CPG_MOD 917>;
-			bank-width = <2>;
+		drif10: rif@e6f60000 {
+			compatible = "renesas,r8a7796-drif",
+				     "renesas,rcar-gen3-drif";
+			reg = <0 0xe6f60000 0 0x64>;
+			interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 513>;
+			clock-names = "fck";
+			dmas = <&dmac1 0x24>, <&dmac2 0x24>;
+			dma-names = "rx", "rx";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 513>;
+			renesas,bonding = <&drif11>;
 			status = "disabled";
 		};
 
-		sdhi0: sd@ee100000 {
-			compatible = "renesas,sdhi-r8a7796",
-				     "renesas,rcar-gen3-sdhi";
-			reg = <0 0xee100000 0 0x2000>;
-			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 314>;
-			max-frequency = <200000000>;
+		drif11: rif@e6f70000 {
+			compatible = "renesas,r8a7796-drif",
+				     "renesas,rcar-gen3-drif";
+			reg = <0 0xe6f70000 0 0x64>;
+			interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 512>;
+			clock-names = "fck";
+			dmas = <&dmac1 0x26>, <&dmac2 0x26>;
+			dma-names = "rx", "rx";
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 314>;
+			resets = <&cpg 512>;
+			renesas,bonding = <&drif10>;
 			status = "disabled";
 		};
 
-		sdhi1: sd@ee120000 {
-			compatible = "renesas,sdhi-r8a7796",
-				     "renesas,rcar-gen3-sdhi";
-			reg = <0 0xee120000 0 0x2000>;
-			interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 313>;
-			max-frequency = <200000000>;
+		drif20: rif@e6f80000 {
+			compatible = "renesas,r8a7796-drif",
+				     "renesas,rcar-gen3-drif";
+			reg = <0 0xe6f80000 0 0x64>;
+			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 511>;
+			clock-names = "fck";
+			dmas = <&dmac1 0x28>, <&dmac2 0x28>;
+			dma-names = "rx", "rx";
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 313>;
+			resets = <&cpg 511>;
+			renesas,bonding = <&drif21>;
 			status = "disabled";
 		};
 
-		sdhi2: sd@ee140000 {
-			compatible = "renesas,sdhi-r8a7796",
-				     "renesas,rcar-gen3-sdhi";
-			reg = <0 0xee140000 0 0x2000>;
-			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 312>;
-			max-frequency = <200000000>;
+		drif21: rif@e6f90000 {
+			compatible = "renesas,r8a7796-drif",
+				     "renesas,rcar-gen3-drif";
+			reg = <0 0xe6f90000 0 0x64>;
+			interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 510>;
+			clock-names = "fck";
+			dmas = <&dmac1 0x2a>, <&dmac2 0x2a>;
+			dma-names = "rx", "rx";
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 312>;
+			resets = <&cpg 510>;
+			renesas,bonding = <&drif20>;
 			status = "disabled";
 		};
 
-		sdhi3: sd@ee160000 {
-			compatible = "renesas,sdhi-r8a7796",
-				     "renesas,rcar-gen3-sdhi";
-			reg = <0 0xee160000 0 0x2000>;
-			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 311>;
-			max-frequency = <200000000>;
+		drif30: rif@e6fa0000 {
+			compatible = "renesas,r8a7796-drif",
+				     "renesas,rcar-gen3-drif";
+			reg = <0 0xe6fa0000 0 0x64>;
+			interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 509>;
+			clock-names = "fck";
+			dmas = <&dmac1 0x2c>, <&dmac2 0x2c>;
+			dma-names = "rx", "rx";
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 311>;
+			resets = <&cpg 509>;
+			renesas,bonding = <&drif31>;
 			status = "disabled";
 		};
 
-		tsc: thermal@e6198000 {
-			compatible = "renesas,r8a7796-thermal";
-			reg = <0 0xe6198000 0 0x100>,
-			      <0 0xe61a0000 0 0x100>,
-			      <0 0xe61a8000 0 0x100>;
-			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 522>;
+		drif31: rif@e6fb0000 {
+			compatible = "renesas,r8a7796-drif",
+				     "renesas,rcar-gen3-drif";
+			reg = <0 0xe6fb0000 0 0x64>;
+			interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 508>;
+			clock-names = "fck";
+			dmas = <&dmac1 0x2e>, <&dmac2 0x2e>;
+			dma-names = "rx", "rx";
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 522>;
-			#thermal-sensor-cells = <1>;
-			status = "okay";
+			resets = <&cpg 508>;
+			renesas,bonding = <&drif30>;
+			status = "disabled";
 		};
 
 		rcar_sound: sound@ec500000 {
@@ -1853,16 +1847,335 @@
 					dma-names = "rx", "tx", "rxu", "txu";
 				};
 			};
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+				};
+				port@1 {
+					reg = <1>;
+				};
+			};
 		};
 
+		audma0: dma-controller@ec700000 {
+			compatible = "renesas,dmac-r8a7796",
+				     "renesas,rcar-dmac";
+			reg = <0 0xec700000 0 0x10000>;
+			interrupts = <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5", "ch6", "ch7",
+					"ch8", "ch9", "ch10", "ch11",
+					"ch12", "ch13", "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 502>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 502>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+			iommus = <&ipmmu_mp 0>, <&ipmmu_mp 1>,
+			       <&ipmmu_mp 2>, <&ipmmu_mp 3>,
+			       <&ipmmu_mp 4>, <&ipmmu_mp 5>,
+			       <&ipmmu_mp 6>, <&ipmmu_mp 7>,
+			       <&ipmmu_mp 8>, <&ipmmu_mp 9>,
+			       <&ipmmu_mp 10>, <&ipmmu_mp 11>,
+			       <&ipmmu_mp 12>, <&ipmmu_mp 13>,
+			       <&ipmmu_mp 14>, <&ipmmu_mp 15>;
+		};
+
+		audma1: dma-controller@ec720000 {
+			compatible = "renesas,dmac-r8a7796",
+				     "renesas,rcar-dmac";
+			reg = <0 0xec720000 0 0x10000>;
+			interrupts = <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5", "ch6", "ch7",
+					"ch8", "ch9", "ch10", "ch11",
+					"ch12", "ch13", "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 501>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 501>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+			iommus = <&ipmmu_mp 16>, <&ipmmu_mp 17>,
+			       <&ipmmu_mp 18>, <&ipmmu_mp 19>,
+			       <&ipmmu_mp 20>, <&ipmmu_mp 21>,
+			       <&ipmmu_mp 22>, <&ipmmu_mp 23>,
+			       <&ipmmu_mp 24>, <&ipmmu_mp 25>,
+			       <&ipmmu_mp 26>, <&ipmmu_mp 27>,
+			       <&ipmmu_mp 28>, <&ipmmu_mp 29>,
+			       <&ipmmu_mp 30>, <&ipmmu_mp 31>;
+		};
+
+		xhci0: usb@ee000000 {
+			compatible = "renesas,xhci-r8a7796",
+				     "renesas,rcar-gen3-xhci";
+			reg = <0 0xee000000 0 0xc00>;
+			interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 328>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 328>;
+			status = "disabled";
+		};
+
+		usb3_peri0: usb@ee020000 {
+			compatible = "renesas,r8a7796-usb3-peri",
+				     "renesas,rcar-gen3-usb3-peri";
+			reg = <0 0xee020000 0 0x400>;
+			interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 328>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 328>;
+			status = "disabled";
+		};
+
+		ohci0: usb@ee080000 {
+			compatible = "generic-ohci";
+			reg = <0 0xee080000 0 0x100>;
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			phys = <&usb2_phy0>;
+			phy-names = "usb";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 703>;
+			status = "disabled";
+		};
+
+		ohci1: usb@ee0a0000 {
+			compatible = "generic-ohci";
+			reg = <0 0xee0a0000 0 0x100>;
+			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 702>;
+			phys = <&usb2_phy1>;
+			phy-names = "usb";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 702>;
+			status = "disabled";
+		};
+
+		ehci0: usb@ee080100 {
+			compatible = "generic-ehci";
+			reg = <0 0xee080100 0 0x100>;
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			phys = <&usb2_phy0>;
+			phy-names = "usb";
+			companion= <&ohci0>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 703>;
+			status = "disabled";
+		};
+
+		ehci1: usb@ee0a0100 {
+			compatible = "generic-ehci";
+			reg = <0 0xee0a0100 0 0x100>;
+			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 702>;
+			phys = <&usb2_phy1>;
+			phy-names = "usb";
+			companion= <&ohci1>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 702>;
+			status = "disabled";
+		};
+
+		usb2_phy0: usb-phy@ee080200 {
+			compatible = "renesas,usb2-phy-r8a7796",
+				     "renesas,rcar-gen3-usb2-phy";
+			reg = <0 0xee080200 0 0x700>;
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 703>;
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
+		usb2_phy1: usb-phy@ee0a0200 {
+			compatible = "renesas,usb2-phy-r8a7796",
+				     "renesas,rcar-gen3-usb2-phy";
+			reg = <0 0xee0a0200 0 0x700>;
+			clocks = <&cpg CPG_MOD 702>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 702>;
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
+		sdhi0: sd@ee100000 {
+			compatible = "renesas,sdhi-r8a7796",
+				     "renesas,rcar-gen3-sdhi";
+			reg = <0 0xee100000 0 0x2000>;
+			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 314>;
+			max-frequency = <200000000>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 314>;
+			status = "disabled";
+		};
+
+		sdhi1: sd@ee120000 {
+			compatible = "renesas,sdhi-r8a7796",
+				     "renesas,rcar-gen3-sdhi";
+			reg = <0 0xee120000 0 0x2000>;
+			interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 313>;
+			max-frequency = <200000000>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 313>;
+			status = "disabled";
+		};
+
+		sdhi2: sd@ee140000 {
+			compatible = "renesas,sdhi-r8a7796",
+				     "renesas,rcar-gen3-sdhi";
+			reg = <0 0xee140000 0 0x2000>;
+			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 312>;
+			max-frequency = <200000000>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 312>;
+			status = "disabled";
+		};
+
+		sdhi3: sd@ee160000 {
+			compatible = "renesas,sdhi-r8a7796",
+				     "renesas,rcar-gen3-sdhi";
+			reg = <0 0xee160000 0 0x2000>;
+			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 311>;
+			max-frequency = <200000000>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 311>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller@f1010000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0x0 0xf1010000 0 0x1000>,
+			      <0x0 0xf1020000 0 0x20000>,
+			      <0x0 0xf1040000 0 0x20000>,
+			      <0x0 0xf1060000 0 0x20000>;
+			interrupts = <GIC_PPI 9
+					(GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&cpg CPG_MOD 408>;
+			clock-names = "clk";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 408>;
+		};
+
 		pciec0: pcie@fe000000 {
+			compatible = "renesas,pcie-r8a7796",
+				     "renesas,pcie-rcar-gen3";
 			reg = <0 0xfe000000 0 0x80000>;
-			/* placeholder */
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x00 0xff>;
+			device_type = "pci";
+			ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000
+				0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000
+				0x02000000 0 0x30000000 0 0x30000000 0 0x08000000
+				0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
+			/* Map all possible DDR as inbound ranges */
+			dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>;
+			interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
+			clock-names = "pcie", "pcie_bus";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 319>;
+			status = "disabled";
 		};
 
 		pciec1: pcie@ee800000 {
+			compatible = "renesas,pcie-r8a7796",
+				     "renesas,pcie-rcar-gen3";
 			reg = <0 0xee800000 0 0x80000>;
-			/* placeholder */
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x00 0xff>;
+			device_type = "pci";
+			ranges = <0x01000000 0 0x00000000 0 0xee900000 0 0x00100000
+				0x02000000 0 0xeea00000 0 0xeea00000 0 0x00200000
+				0x02000000 0 0xc0000000 0 0xc0000000 0 0x08000000
+				0x42000000 0 0xc8000000 0 0xc8000000 0 0x08000000>;
+			/* Map all possible DDR as inbound ranges */
+			dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>;
+			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0 0 0 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 318>, <&pcie_bus_clk>;
+			clock-names = "pcie", "pcie_bus";
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 318>;
+			status = "disabled";
+		};
+
+		imr-lx4@fe860000 {
+			compatible = "renesas,r8a7796-imr-lx4",
+				     "renesas,imr-lx4";
+			reg = <0 0xfe860000 0 0x2000>;
+			interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 823>;
+			power-domains = <&sysc R8A7796_PD_A3VC>;
+			resets = <&cpg 823>;
+		};
+
+		imr-lx4@fe870000 {
+			compatible = "renesas,r8a7796-imr-lx4",
+				     "renesas,imr-lx4";
+			reg = <0 0xfe870000 0 0x2000>;
+			interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 822>;
+			power-domains = <&sysc R8A7796_PD_A3VC>;
+			resets = <&cpg 822>;
 		};
 
 		fdp1@fe940000 {
@@ -1883,17 +2196,6 @@
 			resets = <&cpg 615>;
 		};
 
-		vspb: vsp@fe960000 {
-			compatible = "renesas,vsp2";
-			reg = <0 0xfe960000 0 0x8000>;
-			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 626>;
-			power-domains = <&sysc R8A7796_PD_A3VC>;
-			resets = <&cpg 626>;
-
-			renesas,fcp = <&fcpvb0>;
-		};
-
 		fcpvb0: fcp@fe96f000 {
 			compatible = "renesas,fcpv";
 			reg = <0 0xfe96f000 0 0x200>;
@@ -1902,17 +2204,6 @@
 			resets = <&cpg 607>;
 		};
 
-		vspi0: vsp@fe9a0000 {
-			compatible = "renesas,vsp2";
-			reg = <0 0xfe9a0000 0 0x8000>;
-			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 631>;
-			power-domains = <&sysc R8A7796_PD_A3VC>;
-			resets = <&cpg 631>;
-
-			renesas,fcp = <&fcpvi0>;
-		};
-
 		fcpvi0: fcp@fe9af000 {
 			compatible = "renesas,fcpv";
 			reg = <0 0xfe9af000 0 0x200>;
@@ -1922,9 +2213,47 @@
 			iommus = <&ipmmu_vc0 19>;
 		};
 
+		fcpvd0: fcp@fea27000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea27000 0 0x200>;
+			clocks = <&cpg CPG_MOD 603>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 603>;
+			iommus = <&ipmmu_vi0 8>;
+		};
+
+		fcpvd1: fcp@fea2f000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea2f000 0 0x200>;
+			clocks = <&cpg CPG_MOD 602>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 602>;
+			iommus = <&ipmmu_vi0 9>;
+		};
+
+		fcpvd2: fcp@fea37000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea37000 0 0x200>;
+			clocks = <&cpg CPG_MOD 601>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 601>;
+			iommus = <&ipmmu_vi0 10>;
+		};
+
+		vspb: vsp@fe960000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfe960000 0 0x8000>;
+			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 626>;
+			power-domains = <&sysc R8A7796_PD_A3VC>;
+			resets = <&cpg 626>;
+
+			renesas,fcp = <&fcpvb0>;
+		};
+
 		vspd0: vsp@fea20000 {
 			compatible = "renesas,vsp2";
-			reg = <0 0xfea20000 0 0x8000>;
+			reg = <0 0xfea20000 0 0x5000>;
 			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 623>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
@@ -1933,18 +2262,9 @@
 			renesas,fcp = <&fcpvd0>;
 		};
 
-		fcpvd0: fcp@fea27000 {
-			compatible = "renesas,fcpv";
-			reg = <0 0xfea27000 0 0x200>;
-			clocks = <&cpg CPG_MOD 603>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 603>;
-			iommus = <&ipmmu_vi0 8>;
-		};
-
 		vspd1: vsp@fea28000 {
 			compatible = "renesas,vsp2";
-			reg = <0 0xfea28000 0 0x8000>;
+			reg = <0 0xfea28000 0 0x5000>;
 			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 622>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
@@ -1953,18 +2273,9 @@
 			renesas,fcp = <&fcpvd1>;
 		};
 
-		fcpvd1: fcp@fea2f000 {
-			compatible = "renesas,fcpv";
-			reg = <0 0xfea2f000 0 0x200>;
-			clocks = <&cpg CPG_MOD 602>;
-			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 602>;
-			iommus = <&ipmmu_vi0 9>;
-		};
-
 		vspd2: vsp@fea30000 {
 			compatible = "renesas,vsp2";
-			reg = <0 0xfea30000 0 0x8000>;
+			reg = <0 0xfea30000 0 0x5000>;
 			interrupts = <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 621>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
@@ -1973,15 +2284,128 @@
 			renesas,fcp = <&fcpvd2>;
 		};
 
-		fcpvd2: fcp@fea37000 {
-			compatible = "renesas,fcpv";
-			reg = <0 0xfea37000 0 0x200>;
-			clocks = <&cpg CPG_MOD 601>;
+		vspi0: vsp@fe9a0000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfe9a0000 0 0x8000>;
+			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 631>;
+			power-domains = <&sysc R8A7796_PD_A3VC>;
+			resets = <&cpg 631>;
+
+			renesas,fcp = <&fcpvi0>;
+		};
+
+		csi20: csi2@fea80000 {
+			compatible = "renesas,r8a7796-csi2";
+			reg = <0 0xfea80000 0 0x10000>;
+			interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 714>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-			resets = <&cpg 601>;
-			iommus = <&ipmmu_vi0 10>;
+			resets = <&cpg 714>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					csi20vin0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&vin0csi20>;
+					};
+					csi20vin1: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&vin1csi20>;
+					};
+					csi20vin2: endpoint@2 {
+						reg = <2>;
+						remote-endpoint = <&vin2csi20>;
+					};
+					csi20vin3: endpoint@3 {
+						reg = <3>;
+						remote-endpoint = <&vin3csi20>;
+					};
+					csi20vin4: endpoint@4 {
+						reg = <4>;
+						remote-endpoint = <&vin4csi20>;
+					};
+					csi20vin5: endpoint@5 {
+						reg = <5>;
+						remote-endpoint = <&vin5csi20>;
+					};
+					csi20vin6: endpoint@6 {
+						reg = <6>;
+						remote-endpoint = <&vin6csi20>;
+					};
+					csi20vin7: endpoint@7 {
+						reg = <7>;
+						remote-endpoint = <&vin7csi20>;
+					};
+				};
+			};
 		};
 
+		csi40: csi2@feaa0000 {
+			compatible = "renesas,r8a7796-csi2";
+			reg = <0 0xfeaa0000 0 0x10000>;
+			interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 716>;
+			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+			resets = <&cpg 716>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					csi40vin0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&vin0csi40>;
+					};
+					csi40vin1: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&vin1csi40>;
+					};
+					csi40vin2: endpoint@2 {
+						reg = <2>;
+						remote-endpoint = <&vin2csi40>;
+					};
+					csi40vin3: endpoint@3 {
+						reg = <3>;
+						remote-endpoint = <&vin3csi40>;
+					};
+					csi40vin4: endpoint@4 {
+						reg = <4>;
+						remote-endpoint = <&vin4csi40>;
+					};
+					csi40vin5: endpoint@5 {
+						reg = <5>;
+						remote-endpoint = <&vin5csi40>;
+					};
+					csi40vin6: endpoint@6 {
+						reg = <6>;
+						remote-endpoint = <&vin6csi40>;
+					};
+					csi40vin7: endpoint@7 {
+						reg = <7>;
+						remote-endpoint = <&vin7csi40>;
+					};
+				};
+
+			};
+		};
+
 		hdmi0: hdmi@fead0000 {
 			compatible = "renesas,r8a7796-hdmi", "renesas,rcar-gen3-hdmi";
 			reg = <0 0xfead0000 0 0x10000>;
@@ -2004,6 +2428,10 @@
 				port@1 {
 					reg = <1>;
 				};
+				port@2 {
+					/* HDMI sound */
+					reg = <2>;
+				};
 			};
 		};
 
@@ -2047,35 +2475,12 @@
 			};
 		};
 
-		imr-lx4@fe860000 {
-			compatible = "renesas,r8a7796-imr-lx4",
-				     "renesas,imr-lx4";
-			reg = <0 0xfe860000 0 0x2000>;
-			interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 823>;
-			power-domains = <&sysc R8A7796_PD_A3VC>;
-			resets = <&cpg 823>;
-		};
-
-		imr-lx4@fe870000 {
-			compatible = "renesas,r8a7796-imr-lx4",
-				     "renesas,imr-lx4";
-			reg = <0 0xfe870000 0 0x2000>;
-			interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 822>;
-			power-domains = <&sysc R8A7796_PD_A3VC>;
-			resets = <&cpg 822>;
+		prr: chipid@fff00044 {
+			compatible = "renesas,prr";
+			reg = <0 0xfff00044 0 4>;
 		};
 	};
 
-	timer {
-		compatible = "arm,armv8-timer";
-		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
-	};
-
 	thermal-zones {
 		sensor_thermal1: sensor-thermal1 {
 			polling-delay-passive = <250>;
@@ -2085,12 +2490,12 @@
 			trips {
 				sensor1_passive: sensor1-passive {
 					temperature = <95000>;
-					hysteresis = <2000>;
+					hysteresis = <1000>;
 					type = "passive";
 				};
 				sensor1_crit: sensor1-crit {
 					temperature = <120000>;
-					hysteresis = <2000>;
+					hysteresis = <1000>;
 					type = "critical";
 				};
 			};
@@ -2111,12 +2516,12 @@
 			trips {
 				sensor2_passive: sensor2-passive {
 					temperature = <95000>;
-					hysteresis = <2000>;
+					hysteresis = <1000>;
 					type = "passive";
 				};
 				sensor2_crit: sensor2-crit {
 					temperature = <120000>;
-					hysteresis = <2000>;
+					hysteresis = <1000>;
 					type = "critical";
 				};
 			};
@@ -2137,12 +2542,12 @@
 			trips {
 				sensor3_passive: sensor3-passive {
 					temperature = <95000>;
-					hysteresis = <2000>;
+					hysteresis = <1000>;
 					type = "passive";
 				};
 				sensor3_crit: sensor3-crit {
 					temperature = <120000>;
-					hysteresis = <2000>;
+					hysteresis = <1000>;
 					type = "critical";
 				};
 			};
@@ -2156,6 +2561,14 @@
 		};
 	};
 
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
 	/* External USB clocks - can be overridden by the board */
 	usb3s0_clk: usb3s0 {
 		compatible = "fixed-clock";
diff --git a/arch/arm/dts/r8a77965-salvator-x-u-boot.dts b/arch/arm/dts/r8a77965-salvator-x-u-boot.dts
index 06002b6..9e0cd26 100644
--- a/arch/arm/dts/r8a77965-salvator-x-u-boot.dts
+++ b/arch/arm/dts/r8a77965-salvator-x-u-boot.dts
@@ -7,3 +7,34 @@
 
 #include "r8a77965-salvator-x.dts"
 #include "r8a77965-u-boot.dtsi"
+
+&sdhi2_pins {
+	groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
+	power-source = <1800>;
+};
+
+&sdhi2_pins_uhs {
+	groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
+};
+
+&sdhi0 {
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr104;
+	max-frequency = <208000000>;
+	status = "okay";
+};
+
+&sdhi2 {
+	mmc-hs400-1_8v;
+	max-frequency = <200000000>;
+	status = "okay";
+};
+
+&sdhi3 {
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr104;
+	max-frequency = <208000000>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/r8a77965-salvator-x.dts b/arch/arm/dts/r8a77965-salvator-x.dts
index 75d890d..340a3c7 100644
--- a/arch/arm/dts/r8a77965-salvator-x.dts
+++ b/arch/arm/dts/r8a77965-salvator-x.dts
@@ -19,3 +19,31 @@
 		reg = <0x0 0x48000000 0x0 0x78000000>;
 	};
 };
+
+&du {
+	clocks = <&cpg CPG_MOD 724>,
+		 <&cpg CPG_MOD 723>,
+		 <&cpg CPG_MOD 721>,
+		 <&versaclock5 1>,
+		 <&x21_clk>,
+		 <&versaclock5 2>;
+	clock-names = "du.0", "du.1", "du.3",
+		      "dclkin.0", "dclkin.1", "dclkin.3";
+};
+
+&hdmi0 {
+	status = "okay";
+
+	ports {
+		port@1 {
+			reg = <1>;
+			rcar_dw_hdmi0_out: endpoint {
+				remote-endpoint = <&hdmi0_con>;
+			};
+		};
+	};
+};
+
+&hdmi0_con {
+	remote-endpoint = <&rcar_dw_hdmi0_out>;
+};
diff --git a/arch/arm/dts/r8a77965-u-boot.dtsi b/arch/arm/dts/r8a77965-u-boot.dtsi
index f002311..cbd29b3 100644
--- a/arch/arm/dts/r8a77965-u-boot.dtsi
+++ b/arch/arm/dts/r8a77965-u-boot.dtsi
@@ -10,3 +10,112 @@
 &extalr_clk {
 	u-boot,dm-pre-reloc;
 };
+
+&soc {
+	rpc: rpc@0xee200000 {
+		compatible = "renesas,rpc-r8a77965", "renesas,rpc";
+		reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>;
+		clocks = <&cpg CPG_MOD 917>;
+		bank-width = <2>;
+		status = "disabled";
+	};
+
+	sdhi0: sd@ee100000 {
+		compatible = "renesas,sdhi-r8a77965";
+		reg = <0 0xee100000 0 0x2000>;
+		interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cpg CPG_MOD 314>;
+		max-frequency = <200000000>;
+		power-domains = <&sysc 32>;
+		resets = <&cpg 314>;
+		status = "disabled";
+	};
+
+	sdhi1: sd@ee120000 {
+		compatible = "renesas,sdhi-r8a77965";
+		reg = <0 0xee120000 0 0x2000>;
+		interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cpg CPG_MOD 313>;
+		max-frequency = <200000000>;
+		power-domains = <&sysc 32>;
+		resets = <&cpg 313>;
+		status = "disabled";
+	};
+
+	sdhi2: sd@ee140000 {
+		compatible = "renesas,sdhi-r8a77965";
+		reg = <0 0xee140000 0 0x2000>;
+		interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cpg CPG_MOD 312>;
+		max-frequency = <200000000>;
+		power-domains = <&sysc 32>;
+		resets = <&cpg 312>;
+		status = "disabled";
+	};
+
+	sdhi3: sd@ee160000 {
+		compatible = "renesas,sdhi-r8a77965";
+		reg = <0 0xee160000 0 0x2000>;
+		interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cpg CPG_MOD 311>;
+		max-frequency = <200000000>;
+		power-domains = <&sysc 32>;
+		resets = <&cpg 311>;
+		status = "disabled";
+	};
+
+	ehci0: usb@ee080100 {
+		compatible = "generic-ehci";
+		reg = <0 0xee080100 0 0x100>;
+		interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cpg CPG_MOD 703>;
+		phys = <&usb2_phy0>;
+		phy-names = "usb";
+		companion= <&ohci0>;
+		power-domains = <&sysc 32>;
+		resets = <&cpg 703>;
+	};
+
+	usb2_phy0: usb-phy@ee080200 {
+		compatible = "renesas,usb2-phy-r8a77965",
+			     "renesas,rcar-gen3-usb2-phy";
+		reg = <0 0xee080200 0 0x700>;
+		interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cpg CPG_MOD 703>;
+		power-domains = <&sysc 32>;
+		resets = <&cpg 703>;
+		#phy-cells = <0>;
+	};
+
+	ehci1: usb@ee0a0100 {
+		compatible = "generic-ehci";
+		reg = <0 0xee0a0100 0 0x100>;
+		interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cpg CPG_MOD 702>;
+		phys = <&usb2_phy1>;
+		phy-names = "usb";
+		companion= <&ohci1>;
+		power-domains = <&sysc 32>;
+		resets = <&cpg 702>;
+	};
+
+	usb2_phy1: usb-phy@ee0a0200 {
+		compatible = "renesas,usb2-phy-r8a77965",
+			     "renesas,rcar-gen3-usb2-phy";
+		reg = <0 0xee0a0200 0 0x700>;
+		clocks = <&cpg CPG_MOD 702>;
+		power-domains = <&sysc 32>;
+		resets = <&cpg 702>;
+		#phy-cells = <0>;
+	};
+
+	xhci0: usb@ee000000 {
+		compatible = "renesas,xhci-r8a77965",
+			     "renesas,rcar-gen3-xhci";
+		reg = <0 0xee000000 0 0xc00>;
+		interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cpg CPG_MOD 328>;
+		power-domains = <&sysc 32>;
+		resets = <&cpg 328>;
+	};
+};
diff --git a/arch/arm/dts/r8a77965.dtsi b/arch/arm/dts/r8a77965.dtsi
index 7a5d68b..ef8cdc6 100644
--- a/arch/arm/dts/r8a77965.dtsi
+++ b/arch/arm/dts/r8a77965.dtsi
@@ -8,8 +8,9 @@
  * Copyright (C) 2016 Renesas Electronics Corp.
  */
 
-#include <dt-bindings/clock/renesas-cpg-mssr.h>
+#include <dt-bindings/clock/r8a77965-cpg-mssr.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/r8a77965-sysc.h>
 
 #define CPG_AUDIO_CLK_I		10
 
@@ -19,14 +20,46 @@
 	#size-cells = <2>;
 
 	aliases {
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		i2c4 = &i2c4;
+		i2c5 = &i2c5;
+		i2c6 = &i2c6;
 		i2c7 = &i2c_dvfs;
 	};
 
-	psci {
-		compatible = "arm,psci-1.0", "arm,psci-0.2";
-		method = "smc";
+	/*
+	 * The external audio clocks are configured as 0 Hz fixed frequency
+	 * clocks by default.
+	 * Boards that provide audio clocks should override them.
+	 */
+	audio_clk_a: audio_clk_a {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	audio_clk_b: audio_clk_b {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	audio_clk_c: audio_clk_c {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
 	};
 
+	/* External CAN clock - to be overridden by boards that provide it */
+	can_clk: can {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -35,23 +68,23 @@
 			compatible = "arm,cortex-a57", "arm,armv8";
 			reg = <0x0>;
 			device_type = "cpu";
-			power-domains = <&sysc 0>;
+			power-domains = <&sysc R8A77965_PD_CA57_CPU0>;
 			next-level-cache = <&L2_CA57>;
 			enable-method = "psci";
 		};
 
 		a57_1: cpu@1 {
-			compatible = "arm,cortex-a57","arm,armv8";
+			compatible = "arm,cortex-a57", "arm,armv8";
 			reg = <0x1>;
 			device_type = "cpu";
-			power-domains = <&sysc 1>;
+			power-domains = <&sysc R8A77965_PD_CA57_CPU1>;
 			next-level-cache = <&L2_CA57>;
 			enable-method = "psci";
 		};
 
 		L2_CA57: cache-controller-0 {
 			compatible = "cache";
-			power-domains = <&sysc 12>;
+			power-domains = <&sysc R8A77965_PD_CA57_SCU>;
 			cache-unified;
 			cache-level = <2>;
 		};
@@ -71,34 +104,24 @@
 		clock-frequency = <0>;
 	};
 
-	/*
-	 * The external audio clocks are configured as 0 Hz fixed frequency
-	 * clocks by default.
-	 * Boards that provide audio clocks should override them.
-	 */
-	audio_clk_a: audio_clk_a {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-
-	audio_clk_b: audio_clk_b {
+	/* External PCIe clock - can be overridden by the board */
+	pcie_bus_clk: pcie_bus {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
 		clock-frequency = <0>;
 	};
 
-	audio_clk_c: audio_clk_c {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
+	pmu_a57 {
+		compatible = "arm,cortex-a57-pmu";
+		interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&a57_0>,
+				     <&a57_1>;
 	};
 
-	/* External CAN clock - to be overridden by boards that provide it */
-	can_clk: can {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2";
+		method = "smc";
 	};
 
 	/* External SCIF clock - to be overridden by boards that provide it */
@@ -108,95 +131,21 @@
 		clock-frequency = <0>;
 	};
 
-	/* External PCIe clock - can be overridden by the board */
-	pcie_bus_clk: pcie_bus {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-
-	/* External USB clocks - can be overridden by the board */
-	usb3s0_clk: usb3s0 {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-
-	usb_extal_clk: usb_extal {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-
-	timer {
-		compatible = "arm,armv8-timer";
-		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
-	};
-
-	pmu_a57 {
-		compatible = "arm,cortex-a57-pmu";
-		interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
-				      <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-affinity = <&a57_0>,
-				     <&a57_1>;
-	};
-
-	soc {
+	soc: soc {
 		compatible = "simple-bus";
 		interrupt-parent = <&gic>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		ranges;
 
-		gic: interrupt-controller@f1010000 {
-			compatible = "arm,gic-400";
-			#interrupt-cells = <3>;
-			#address-cells = <0>;
-			interrupt-controller;
-			reg = <0x0 0xf1010000 0 0x1000>,
-			      <0x0 0xf1020000 0 0x20000>,
-			      <0x0 0xf1040000 0 0x20000>,
-			      <0x0 0xf1060000 0 0x20000>;
-			interrupts = <GIC_PPI 9
-					(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
-			clocks = <&cpg CPG_MOD 408>;
-			clock-names = "clk";
-			power-domains = <&sysc 32>;
-			resets = <&cpg 408>;
-		};
-
-		pfc: pin-controller@e6060000 {
-			compatible = "renesas,pfc-r8a77965";
-			reg = <0 0xe6060000 0 0x50c>;
-		};
-
-		cpg: clock-controller@e6150000 {
-			compatible = "renesas,r8a77965-cpg-mssr";
-			reg = <0 0xe6150000 0 0x1000>;
-			clocks = <&extal_clk>, <&extalr_clk>;
-			clock-names = "extal", "extalr";
-			#clock-cells = <2>;
-			#power-domain-cells = <0>;
-			#reset-cells = <1>;
-		};
-
-		rst: reset-controller@e6160000 {
-			compatible = "renesas,r8a77965-rst";
-			reg = <0 0xe6160000 0 0x0200>;
-		};
-
-		prr: chipid@fff00044 {
-			compatible = "renesas,prr";
-			reg = <0 0xfff00044 0 4>;
-		};
-
-		sysc: system-controller@e6180000 {
-			compatible = "renesas,r8a77965-sysc";
-			reg = <0 0xe6180000 0 0x0400>;
-			#power-domain-cells = <1>;
+		rwdt: watchdog@e6020000 {
+			compatible = "renesas,r8a77965-wdt",
+				     "renesas,rcar-gen3-wdt";
+			reg = <0 0xe6020000 0 0x0c>;
+			clocks = <&cpg CPG_MOD 402>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 402>;
+			status = "disabled";
 		};
 
 		gpio0: gpio@e6050000 {
@@ -210,7 +159,7 @@
 			#interrupt-cells = <2>;
 			interrupt-controller;
 			clocks = <&cpg CPG_MOD 912>;
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 912>;
 		};
 
@@ -225,7 +174,7 @@
 			#interrupt-cells = <2>;
 			interrupt-controller;
 			clocks = <&cpg CPG_MOD 911>;
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 911>;
 		};
 
@@ -240,7 +189,7 @@
 			#interrupt-cells = <2>;
 			interrupt-controller;
 			clocks = <&cpg CPG_MOD 910>;
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 910>;
 		};
 
@@ -255,7 +204,7 @@
 			#interrupt-cells = <2>;
 			interrupt-controller;
 			clocks = <&cpg CPG_MOD 909>;
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 909>;
 		};
 
@@ -270,7 +219,7 @@
 			#interrupt-cells = <2>;
 			interrupt-controller;
 			clocks = <&cpg CPG_MOD 908>;
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 908>;
 		};
 
@@ -285,7 +234,7 @@
 			#interrupt-cells = <2>;
 			interrupt-controller;
 			clocks = <&cpg CPG_MOD 907>;
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 907>;
 		};
 
@@ -300,7 +249,7 @@
 			#interrupt-cells = <2>;
 			interrupt-controller;
 			clocks = <&cpg CPG_MOD 906>;
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 906>;
 		};
 
@@ -315,10 +264,51 @@
 			#interrupt-cells = <2>;
 			interrupt-controller;
 			clocks = <&cpg CPG_MOD 905>;
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 905>;
 		};
 
+		pfc: pin-controller@e6060000 {
+			compatible = "renesas,pfc-r8a77965";
+			reg = <0 0xe6060000 0 0x50c>;
+		};
+
+		cpg: clock-controller@e6150000 {
+			compatible = "renesas,r8a77965-cpg-mssr";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>, <&extalr_clk>;
+			clock-names = "extal", "extalr";
+			#clock-cells = <2>;
+			#power-domain-cells = <0>;
+			#reset-cells = <1>;
+		};
+
+		rst: reset-controller@e6160000 {
+			compatible = "renesas,r8a77965-rst";
+			reg = <0 0xe6160000 0 0x0200>;
+		};
+
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a77965-sysc";
+			reg = <0 0xe6180000 0 0x0400>;
+			#power-domain-cells = <1>;
+		};
+
+		tsc: thermal@e6198000 {
+			compatible = "renesas,r8a77965-thermal";
+			reg = <0 0xe6198000 0 0x100>,
+			      <0 0xe61a0000 0 0x100>,
+			      <0 0xe61a8000 0 0x100>;
+			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 522>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 522>;
+			#thermal-sensor-cells = <1>;
+			status = "okay";
+		};
+
 		intc_ex: interrupt-controller@e61c0000 {
 			compatible = "renesas,intc-ex-r8a77965", "renesas,irqc";
 			#interrupt-cells = <2>;
@@ -331,85 +321,362 @@
 				      GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH
 				      GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 407>;
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 407>;
 		};
 
-		dmac0: dma-controller@e6700000 {
-			compatible = "renesas,dmac-r8a77965",
-				     "renesas,rcar-dmac";
-			reg = <0 0xe6700000 0 0x10000>;
-			interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "error",
-					"ch0", "ch1", "ch2", "ch3",
-					"ch4", "ch5", "ch6", "ch7",
-					"ch8", "ch9", "ch10", "ch11",
-					"ch12", "ch13", "ch14", "ch15";
-			clocks = <&cpg CPG_MOD 219>;
-			clock-names = "fck";
-			power-domains = <&sysc 32>;
-			resets = <&cpg 219>;
-			#dma-cells = <1>;
-			dma-channels = <16>;
+		i2c0: i2c@e6500000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77965",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6500000 0 0x40>;
+			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 931>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 931>;
+			dmas = <&dmac1 0x91>, <&dmac1 0x90>,
+			       <&dmac2 0x91>, <&dmac2 0x90>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <110>;
+			status = "disabled";
 		};
 
-		dmac1: dma-controller@e7300000 {
-			compatible = "renesas,dmac-r8a77965",
-				     "renesas,rcar-dmac";
-			reg = <0 0xe7300000 0 0x10000>;
-			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "error",
-					"ch0", "ch1", "ch2", "ch3",
-					"ch4", "ch5", "ch6", "ch7",
-					"ch8", "ch9", "ch10", "ch11",
-					"ch12", "ch13", "ch14", "ch15";
-			clocks = <&cpg CPG_MOD 218>;
-			clock-names = "fck";
-			power-domains = <&sysc 32>;
-			resets = <&cpg 218>;
-			#dma-cells = <1>;
-			dma-channels = <16>;
+		i2c1: i2c@e6508000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77965",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6508000 0 0x40>;
+			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 930>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 930>;
+			dmas = <&dmac1 0x93>, <&dmac1 0x92>,
+			       <&dmac2 0x93>, <&dmac2 0x92>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
 		};
 
-		dmac2: dma-controller@e7310000 {
-			compatible = "renesas,dmac-r8a77965",
-				     "renesas,rcar-dmac";
-			reg = <0 0xe7310000 0 0x10000>;
-			interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH
+		i2c2: i2c@e6510000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77965",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6510000 0 0x40>;
+			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 929>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 929>;
+			dmas = <&dmac1 0x95>, <&dmac1 0x94>,
+			       <&dmac2 0x95>, <&dmac2 0x94>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c3: i2c@e66d0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77965",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66d0000 0 0x40>;
+			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 928>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 928>;
+			dmas = <&dmac0 0x97>, <&dmac0 0x96>;
+			dma-names = "tx", "rx";
+			i2c-scl-internal-delay-ns = <110>;
+			status = "disabled";
+		};
+
+		i2c4: i2c@e66d8000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77965",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66d8000 0 0x40>;
+			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 927>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 927>;
+			dmas = <&dmac0 0x99>, <&dmac0 0x98>;
+			dma-names = "tx", "rx";
+			i2c-scl-internal-delay-ns = <110>;
+			status = "disabled";
+		};
+
+		i2c5: i2c@e66e0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77965",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66e0000 0 0x40>;
+			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 919>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 919>;
+			dmas = <&dmac0 0x9b>, <&dmac0 0x9a>;
+			dma-names = "tx", "rx";
+			i2c-scl-internal-delay-ns = <110>;
+			status = "disabled";
+		};
+
+		i2c6: i2c@e66e8000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77965",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66e8000 0 0x40>;
+			interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 918>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 918>;
+			dmas = <&dmac0 0x9d>, <&dmac0 0x9c>;
+			dma-names = "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c_dvfs: i2c@e60b0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,iic-r8a77965",
+				     "renesas,rcar-gen3-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe60b0000 0 0x425>;
+			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 926>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 926>;
+			dmas = <&dmac0 0x11>, <&dmac0 0x10>;
+			dma-names = "tx", "rx";
+			status = "disabled";
+		};
+
+		hscif0: serial@e6540000 {
+			compatible = "renesas,hscif-r8a77965",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe6540000 0 0x60>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 520>,
+				 <&cpg CPG_CORE R8A77965_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x31>, <&dmac1 0x30>,
+			       <&dmac2 0x31>, <&dmac2 0x30>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 520>;
+			status = "disabled";
+		};
+
+		hscif1: serial@e6550000 {
+			compatible = "renesas,hscif-r8a77965",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe6550000 0 0x60>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 519>,
+				 <&cpg CPG_CORE R8A77965_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x33>, <&dmac1 0x32>,
+			       <&dmac2 0x33>, <&dmac2 0x32>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 519>;
+			status = "disabled";
+		};
+
+		hscif2: serial@e6560000 {
+			compatible = "renesas,hscif-r8a77965",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe6560000 0 0x60>;
+			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 518>,
+				 <&cpg CPG_CORE R8A77965_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x35>, <&dmac1 0x34>,
+			       <&dmac2 0x35>, <&dmac2 0x34>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 518>;
+			status = "disabled";
+		};
+
+		hscif3: serial@e66a0000 {
+			compatible = "renesas,hscif-r8a77965",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe66a0000 0 0x60>;
+			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 517>,
+				 <&cpg CPG_CORE R8A77965_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x37>, <&dmac0 0x36>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 517>;
+			status = "disabled";
+		};
+
+		hscif4: serial@e66b0000 {
+			compatible = "renesas,hscif-r8a77965",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe66b0000 0 0x60>;
+			interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 516>,
+				 <&cpg CPG_CORE R8A77965_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x39>, <&dmac0 0x38>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 516>;
+			status = "disabled";
+		};
+
+		hsusb: usb@e6590000 {
+			compatible = "renesas,usbhs-r8a7796",
+				     "renesas,rcar-gen3-usbhs";
+			reg = <0 0xe6590000 0 0x100>;
+			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 704>;
+			dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
+			       <&usb_dmac1 0>, <&usb_dmac1 1>;
+			dma-names = "ch0", "ch1", "ch2", "ch3";
+			renesas,buswait = <11>;
+			phys = <&usb2_phy0>;
+			phy-names = "usb";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 704>;
+			status = "disabled";
+		};
+
+		usb_dmac0: dma-controller@e65a0000 {
+			compatible = "renesas,r8a77965-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe65a0000 0 0x100>;
+			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 330>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 330>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
+		};
+
+		usb_dmac1: dma-controller@e65b0000 {
+			compatible = "renesas,r8a77965-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe65b0000 0 0x100>;
+			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 331>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 331>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
+		};
+
+		usb3_phy0: usb-phy@e65ee000 {
+			compatible = "renesas,r8a77965-usb3-phy",
+				     "renesas,rcar-gen3-usb3-phy";
+			reg = <0 0xe65ee000 0 0x90>;
+			clocks = <&cpg CPG_MOD 328>, <&usb3s0_clk>,
+				 <&usb_extal_clk>;
+			clock-names = "usb3-if", "usb3s_clk", "usb_extal";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 328>;
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
+		dmac0: dma-controller@e6700000 {
+			compatible = "renesas,dmac-r8a77965",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6700000 0 0x10000>;
+			interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5", "ch6", "ch7",
+					"ch8", "ch9", "ch10", "ch11",
+					"ch12", "ch13", "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 219>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 219>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+		};
+
+		dmac1: dma-controller@e7300000 {
+			compatible = "renesas,dmac-r8a77965",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe7300000 0 0x10000>;
+			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5", "ch6", "ch7",
+					"ch8", "ch9", "ch10", "ch11",
+					"ch12", "ch13", "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 218>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 218>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+		};
+
+		dmac2: dma-controller@e7310000 {
+			compatible = "renesas,dmac-r8a77965",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe7310000 0 0x10000>;
+			interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH
 				      GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH
 				      GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH
 				      GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH
@@ -431,25 +698,229 @@
 					"ch12", "ch13", "ch14", "ch15";
 			clocks = <&cpg CPG_MOD 217>;
 			clock-names = "fck";
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 217>;
 			#dma-cells = <1>;
 			dma-channels = <16>;
 		};
 
+		ipmmu_ds0: mmu@e6740000 {
+			compatible = "renesas,ipmmu-r8a77965";
+			reg = <0 0xe6740000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 0>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_ds1: mmu@e7740000 {
+			compatible = "renesas,ipmmu-r8a77965";
+			reg = <0 0xe7740000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 1>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_hc: mmu@e6570000 {
+			compatible = "renesas,ipmmu-r8a77965";
+			reg = <0 0xe6570000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 2>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_ir: mmu@ff8b0000 {
+			compatible = "renesas,ipmmu-r8a77965";
+			reg = <0 0xff8b0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 3>;
+			power-domains = <&sysc R8A77965_PD_A3IR>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_mm: mmu@e67b0000 {
+			compatible = "renesas,ipmmu-r8a77965";
+			reg = <0 0xe67b0000 0 0x1000>;
+			interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_mp: mmu@ec670000 {
+			compatible = "renesas,ipmmu-r8a77965";
+			reg = <0 0xec670000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 4>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_pv0: mmu@fd800000 {
+			compatible = "renesas,ipmmu-r8a77965";
+			reg = <0 0xfd800000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 6>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_rt: mmu@ffc80000 {
+			compatible = "renesas,ipmmu-r8a77965";
+			reg = <0 0xffc80000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 10>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vc0: mmu@fe6b0000 {
+			compatible = "renesas,ipmmu-r8a77965";
+			reg = <0 0xfe6b0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 12>;
+			power-domains = <&sysc R8A77965_PD_A3VC>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vi0: mmu@febd0000 {
+			compatible = "renesas,ipmmu-r8a77965";
+			reg = <0 0xfebd0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 14>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vp0: mmu@fe990000 {
+			compatible = "renesas,ipmmu-r8a77965";
+			reg = <0 0xfe990000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 16>;
+			power-domains = <&sysc R8A77965_PD_A3VP>;
+			#iommu-cells = <1>;
+		};
+
+		avb: ethernet@e6800000 {
+			compatible = "renesas,etheravb-r8a77965",
+				     "renesas,etheravb-rcar-gen3";
+			reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
+			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15",
+					  "ch16", "ch17", "ch18", "ch19",
+					  "ch20", "ch21", "ch22", "ch23",
+					  "ch24";
+			clocks = <&cpg CPG_MOD 812>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 812>;
+			phy-mode = "rgmii";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		pwm0: pwm@e6e30000 {
+			compatible = "renesas,pwm-r8a77965", "renesas,pwm-rcar";
+			reg = <0 0xe6e30000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm1: pwm@e6e31000 {
+			compatible = "renesas,pwm-r8a77965", "renesas,pwm-rcar";
+			reg = <0 0xe6e31000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm2: pwm@e6e32000 {
+			compatible = "renesas,pwm-r8a77965", "renesas,pwm-rcar";
+			reg = <0 0xe6e32000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm3: pwm@e6e33000 {
+			compatible = "renesas,pwm-r8a77965", "renesas,pwm-rcar";
+			reg = <0 0xe6e33000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm4: pwm@e6e34000 {
+			compatible = "renesas,pwm-r8a77965", "renesas,pwm-rcar";
+			reg = <0 0xe6e34000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm5: pwm@e6e35000 {
+			compatible = "renesas,pwm-r8a77965", "renesas,pwm-rcar";
+			reg = <0 0xe6e35000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm6: pwm@e6e36000 {
+			compatible = "renesas,pwm-r8a77965", "renesas,pwm-rcar";
+			reg = <0 0xe6e36000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
 		scif0: serial@e6e60000 {
 			compatible = "renesas,scif-r8a77965",
 				     "renesas,rcar-gen3-scif", "renesas,scif";
 			reg = <0 0xe6e60000 0 64>;
 			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 207>,
-				 <&cpg CPG_CORE 20>,
+				 <&cpg CPG_CORE R8A77965_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
 			dmas = <&dmac1 0x51>, <&dmac1 0x50>,
 			       <&dmac2 0x51>, <&dmac2 0x50>;
 			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 207>;
 			status = "disabled";
 		};
@@ -460,13 +931,13 @@
 			reg = <0 0xe6e68000 0 64>;
 			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 206>,
-				 <&cpg CPG_CORE 20>,
+				 <&cpg CPG_CORE R8A77965_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
 			dmas = <&dmac1 0x53>, <&dmac1 0x52>,
 			       <&dmac2 0x53>, <&dmac2 0x52>;
 			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 206>;
 			status = "disabled";
 		};
@@ -477,10 +948,10 @@
 			reg = <0 0xe6e88000 0 64>;
 			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 310>,
-				 <&cpg CPG_CORE 20>,
+				 <&cpg CPG_CORE R8A77965_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 310>;
 			status = "disabled";
 		};
@@ -491,12 +962,12 @@
 			reg = <0 0xe6c50000 0 64>;
 			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 204>,
-				 <&cpg CPG_CORE 20>,
+				 <&cpg CPG_CORE R8A77965_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
 			dmas = <&dmac0 0x57>, <&dmac0 0x56>;
 			dma-names = "tx", "rx";
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 204>;
 			status = "disabled";
 		};
@@ -507,12 +978,12 @@
 			reg = <0 0xe6c40000 0 64>;
 			interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 203>,
-				 <&cpg CPG_CORE 20>,
+				 <&cpg CPG_CORE R8A77965_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
 			dmas = <&dmac0 0x59>, <&dmac0 0x58>;
 			dma-names = "tx", "rx";
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 203>;
 			status = "disabled";
 		};
@@ -523,125 +994,420 @@
 			reg = <0 0xe6f30000 0 64>;
 			interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 202>,
-				 <&cpg CPG_CORE 20>,
+				 <&cpg CPG_CORE R8A77965_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
 			dmas = <&dmac1 0x5b>, <&dmac1 0x5a>,
 			       <&dmac2 0x5b>, <&dmac2 0x5a>;
 			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 202>;
 			status = "disabled";
 		};
 
-		avb: ethernet@e6800000 {
-			compatible = "renesas,etheravb-r8a77965",
-				     "renesas,etheravb-rcar-gen3";
-			reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
-			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "ch0", "ch1", "ch2", "ch3",
-					  "ch4", "ch5", "ch6", "ch7",
-					  "ch8", "ch9", "ch10", "ch11",
-					  "ch12", "ch13", "ch14", "ch15",
-					  "ch16", "ch17", "ch18", "ch19",
-					  "ch20", "ch21", "ch22", "ch23",
-					  "ch24";
-			clocks = <&cpg CPG_MOD 812>;
-			power-domains = <&sysc 32>;
-			resets = <&cpg 812>;
-			phy-mode = "rgmii";
+		msiof0: spi@e6e90000 {
+			compatible = "renesas,msiof-r8a77965",
+				     "renesas,rcar-gen3-msiof";
+			reg = <0 0xe6e90000 0 0x0064>;
+			interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 211>;
+			dmas = <&dmac1 0x41>, <&dmac1 0x40>,
+			       <&dmac2 0x41>, <&dmac2 0x40>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 211>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		msiof1: spi@e6ea0000 {
+			compatible = "renesas,msiof-r8a77965",
+				     "renesas,rcar-gen3-msiof";
+			reg = <0 0xe6ea0000 0 0x0064>;
+			interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 210>;
+			dmas = <&dmac1 0x43>, <&dmac1 0x42>,
+			       <&dmac2 0x43>, <&dmac2 0x42>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 210>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		msiof2: spi@e6c00000 {
+			compatible = "renesas,msiof-r8a77965",
+				     "renesas,rcar-gen3-msiof";
+			reg = <0 0xe6c00000 0 0x0064>;
+			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 209>;
+			dmas = <&dmac0 0x45>, <&dmac0 0x44>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 209>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		msiof3: spi@e6c10000 {
+			compatible = "renesas,msiof-r8a77965",
+				     "renesas,rcar-gen3-msiof";
+			reg = <0 0xe6c10000 0 0x0064>;
+			interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 208>;
+			dmas = <&dmac0 0x47>, <&dmac0 0x46>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 208>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			status = "disabled";
+		};
+
+		vin0: video@e6ef0000 {
+			compatible = "renesas,vin-r8a77965";
+			reg = <0 0xe6ef0000 0 0x1000>;
+			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 811>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 811>;
+			renesas,id = <0>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin0csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin0>;
+					};
+					vin0csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin0>;
+					};
+				};
+			};
+		};
+
+		vin1: video@e6ef1000 {
+			compatible = "renesas,vin-r8a77965";
+			reg = <0 0xe6ef1000 0 0x1000>;
+			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 810>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 810>;
+			renesas,id = <1>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin1csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin1>;
+					};
+					vin1csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin1>;
+					};
+				};
+			};
+		};
+
+		vin2: video@e6ef2000 {
+			compatible = "renesas,vin-r8a77965";
+			reg = <0 0xe6ef2000 0 0x1000>;
+			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 809>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 809>;
+			renesas,id = <2>;
+			status = "disabled";
-		};
-
-		csi20: csi2@fea80000 {
-			reg = <0 0xfea80000 0 0x10000>;
-			/* placeholder */
 
 			ports {
 				#address-cells = <1>;
 				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin2csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin2>;
+					};
+					vin2csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin2>;
+					};
+				};
 			};
 		};
 
-		csi40: csi2@feaa0000 {
-			reg = <0 0xfeaa0000 0 0x10000>;
-			/* placeholder */
+		vin3: video@e6ef3000 {
+			compatible = "renesas,vin-r8a77965";
+			reg = <0 0xe6ef3000 0 0x1000>;
+			interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 808>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 808>;
+			renesas,id = <3>;
+			status = "disabled";
 
 			ports {
 				#address-cells = <1>;
 				#size-cells = <0>;
-			};
-		};
-
-		vin0: video@e6ef0000 {
-			reg = <0 0xe6ef0000 0 0x1000>;
-			/* placeholder */
-		};
 
-		vin1: video@e6ef1000 {
-			reg = <0 0xe6ef1000 0 0x1000>;
-			/* placeholder */
-		};
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
 
-		vin2: video@e6ef2000 {
-			reg = <0 0xe6ef2000 0 0x1000>;
-			/* placeholder */
-		};
+					reg = <1>;
 
-		vin3: video@e6ef3000 {
-			reg = <0 0xe6ef3000 0 0x1000>;
-			/* placeholder */
+					vin3csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin3>;
+					};
+					vin3csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin3>;
+					};
+				};
+			};
 		};
 
 		vin4: video@e6ef4000 {
+			compatible = "renesas,vin-r8a77965";
 			reg = <0 0xe6ef4000 0 0x1000>;
-			/* placeholder */
+			interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 807>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 807>;
+			renesas,id = <4>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin4csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin4>;
+					};
+					vin4csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin4>;
+					};
+				};
+			};
 		};
 
 		vin5: video@e6ef5000 {
+			compatible = "renesas,vin-r8a77965";
 			reg = <0 0xe6ef5000 0 0x1000>;
-			/* placeholder */
+			interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 806>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 806>;
+			renesas,id = <5>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin5csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin5>;
+					};
+					vin5csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin5>;
+					};
+				};
+			};
 		};
 
 		vin6: video@e6ef6000 {
+			compatible = "renesas,vin-r8a77965";
 			reg = <0 0xe6ef6000 0 0x1000>;
-			/* placeholder */
+			interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 805>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 805>;
+			renesas,id = <6>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin6csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin6>;
+					};
+					vin6csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin6>;
+					};
+				};
+			};
 		};
 
 		vin7: video@e6ef7000 {
+			compatible = "renesas,vin-r8a77965";
 			reg = <0 0xe6ef7000 0 0x1000>;
+			interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 804>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 804>;
+			renesas,id = <7>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin7csi20: endpoint@0 {
+						reg = <0>;
+						remote-endpoint= <&csi20vin7>;
+					};
+					vin7csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin7>;
+					};
+				};
+			};
+		};
+
+		rcar_sound: sound@ec500000 {
+			reg =	<0 0xec500000 0 0x1000>, /* SCU */
+				<0 0xec5a0000 0 0x100>,  /* ADG */
+				<0 0xec540000 0 0x1000>, /* SSIU */
+				<0 0xec541000 0 0x280>,  /* SSI */
+				<0 0xec740000 0 0x200>;  /* Audio DMAC peri peri*/
 			/* placeholder */
+
+			rcar_sound,dvc {
+				dvc0: dvc-0 {
+				};
+				dvc1: dvc-1 {
+				};
+			};
+
+			rcar_sound,src {
+				src0: src-0 {
+				};
+				src1: src-1 {
+				};
+			};
+
+			rcar_sound,ssi {
+				ssi0: ssi-0 {
+				};
+				ssi1: ssi-1 {
+				};
+			};
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+				};
+				port@1 {
+					reg = <1>;
+				};
+			};
+		};
+
+		xhci0: usb@ee000000 {
+			compatible = "renesas,xhci-r8a77965",
+				     "renesas,rcar-gen3-xhci";
+			reg = <0 0xee000000 0 0xc00>;
+			interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 328>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 328>;
+			status = "disabled";
 		};
 
+		usb3_peri0: usb@ee020000 {
+			compatible = "renesas,r8a77965-usb3-peri",
+				     "renesas,rcar-gen3-usb3-peri";
+			reg = <0 0xee020000 0 0x400>;
+			interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 328>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 328>;
+			status = "disabled";
+		};
+
 		ohci0: usb@ee080000 {
+			compatible = "generic-ohci";
 			reg = <0 0xee080000 0 0x100>;
-			/* placeholder */
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			phys = <&usb2_phy0>;
+			phy-names = "usb";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 703>;
+			status = "disabled";
+		};
+
+		ohci1: usb@ee0a0000 {
+			compatible = "generic-ohci";
+			reg = <0 0xee0a0000 0 0x100>;
+			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 702>;
+			phys = <&usb2_phy1>;
+			phy-names = "usb";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 702>;
+			status = "disabled";
 		};
 
 		ehci0: usb@ee080100 {
@@ -651,139 +1417,402 @@
 			clocks = <&cpg CPG_MOD 703>;
 			phys = <&usb2_phy0>;
 			phy-names = "usb";
-			companion= <&ohci0>;
-			power-domains = <&sysc 32>;
+			companion = <&ohci0>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 703>;
 			status = "disabled";
 		};
 
+		ehci1: usb@ee0a0100 {
+			compatible = "generic-ehci";
+			reg = <0 0xee0a0100 0 0x100>;
+			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 702>;
+			phys = <&usb2_phy1>;
+			phy-names = "usb";
+			companion = <&ohci1>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 702>;
+			status = "disabled";
+		};
+
 		usb2_phy0: usb-phy@ee080200 {
 			compatible = "renesas,usb2-phy-r8a77965",
 				     "renesas,rcar-gen3-usb2-phy";
 			reg = <0 0xee080200 0 0x700>;
 			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 703>;
-			power-domains = <&sysc 32>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 			resets = <&cpg 703>;
 			#phy-cells = <0>;
 			status = "disabled";
 		};
 
-		ohci1: usb@ee0a0000 {
-			reg = <0 0xee0a0000 0 0x100>;
-			/* placeholder */
+		usb2_phy1: usb-phy@ee0a0200 {
+			compatible = "renesas,usb2-phy-r8a77965",
+				     "renesas,rcar-gen3-usb2-phy";
+			reg = <0 0xee0a0200 0 0x700>;
+			clocks = <&cpg CPG_MOD 703>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 703>;
+			#phy-cells = <0>;
+			status = "disabled";
 		};
 
-		ehci1: usb@ee0a0100 {
-			compatible = "generic-ehci";
-			reg = <0 0xee0a0100 0 0x100>;
-			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 702>;
-			phys = <&usb2_phy1>;
-			phy-names = "usb";
-			companion= <&ohci1>;
-			power-domains = <&sysc 32>;
-			resets = <&cpg 702>;
+		sdhi0: sd@ee100000 {
+			compatible = "renesas,sdhi-r8a77965",
+				     "renesas,rcar-gen3-sdhi";
+			reg = <0 0xee100000 0 0x2000>;
+			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 314>;
+			max-frequency = <200000000>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 314>;
+			status = "disabled";
+		};
+
+		sdhi1: sd@ee120000 {
+			compatible = "renesas,sdhi-r8a77965",
+				     "renesas,rcar-gen3-sdhi";
+			reg = <0 0xee120000 0 0x2000>;
+			interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 313>;
+			max-frequency = <200000000>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 313>;
+			status = "disabled";
+		};
+
+		sdhi2: sd@ee140000 {
+			compatible = "renesas,sdhi-r8a77965",
+				     "renesas,rcar-gen3-sdhi";
+			reg = <0 0xee140000 0 0x2000>;
+			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 312>;
+			max-frequency = <200000000>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 312>;
+			status = "disabled";
+		};
+
+		sdhi3: sd@ee160000 {
+			compatible = "renesas,sdhi-r8a77965",
+				     "renesas,rcar-gen3-sdhi";
+			reg = <0 0xee160000 0 0x2000>;
+			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 311>;
+			max-frequency = <200000000>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 311>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller@f1010000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0x0 0xf1010000 0 0x1000>,
+			      <0x0 0xf1020000 0 0x20000>,
+			      <0x0 0xf1040000 0 0x20000>,
+			      <0x0 0xf1060000 0 0x20000>;
+			interrupts = <GIC_PPI 9
+					(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&cpg CPG_MOD 408>;
+			clock-names = "clk";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 408>;
+		};
+
+		pciec0: pcie@fe000000 {
+			compatible = "renesas,pcie-r8a77965",
+				     "renesas,pcie-rcar-gen3";
+			reg = <0 0xfe000000 0 0x80000>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x00 0xff>;
+			device_type = "pci";
+			ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000
+				0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000
+				0x02000000 0 0x30000000 0 0x30000000 0 0x08000000
+				0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
+			/* Map all possible DDR as inbound ranges */
+			dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>;
+			interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
+			clock-names = "pcie", "pcie_bus";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 319>;
 			status = "disabled";
 		};
 
-		i2c0: i2c@e6500000 {
-			reg = <0 0xe6500000 0 0x40>;
-			/* placeholder */
+		pciec1: pcie@ee800000 {
+			compatible = "renesas,pcie-r8a77965",
+				     "renesas,pcie-rcar-gen3";
+			reg = <0 0xee800000 0 0x80000>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x00 0xff>;
+			device_type = "pci";
+			ranges = <0x01000000 0 0x00000000 0 0xee900000 0 0x00100000
+				0x02000000 0 0xeea00000 0 0xeea00000 0 0x00200000
+				0x02000000 0 0xc0000000 0 0xc0000000 0 0x08000000
+				0x42000000 0 0xc8000000 0 0xc8000000 0 0x08000000>;
+			/* Map all possible DDR as inbound ranges */
+			dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>;
+			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0 0 0 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 318>, <&pcie_bus_clk>;
+			clock-names = "pcie", "pcie_bus";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 318>;
+			status = "disabled";
 		};
 
-		i2c1: i2c@e6508000 {
-			reg = <0 0xe6508000 0 0x40>;
-			/* placeholder */
+		fcpf0: fcp@fe950000 {
+			compatible = "renesas,fcpf";
+			reg = <0 0xfe950000 0 0x200>;
+			clocks = <&cpg CPG_MOD 615>;
+			power-domains = <&sysc R8A77965_PD_A3VP>;
+			resets = <&cpg 615>;
 		};
 
-		i2c2: i2c@e6510000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
+		vspb: vsp@fe960000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfe960000 0 0x8000>;
+			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 626>;
+			power-domains = <&sysc R8A77965_PD_A3VP>;
+			resets = <&cpg 626>;
 
-			reg = <0 0xe6510000 0 0x40>;
-			/* placeholder */
+			renesas,fcp = <&fcpvb0>;
 		};
 
-		i2c3: i2c@e66d0000 {
-			reg = <0 0xe66d0000 0 0x40>;
-			/* placeholder */
+		fcpvb0: fcp@fe96f000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfe96f000 0 0x200>;
+			clocks = <&cpg CPG_MOD 607>;
+			power-domains = <&sysc R8A77965_PD_A3VP>;
+			resets = <&cpg 607>;
 		};
 
-		i2c4: i2c@e66d8000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
+		vspi0: vsp@fe9a0000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfe9a0000 0 0x8000>;
+			interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 631>;
+			power-domains = <&sysc R8A77965_PD_A3VP>;
+			resets = <&cpg 631>;
 
-			reg = <0 0xe66d8000 0 0x40>;
-			/* placeholder */
+			renesas,fcp = <&fcpvi0>;
 		};
 
-		i2c5: i2c@e66e0000 {
-			reg = <0 0xe66e0000 0 0x40>;
-			/* placeholder */
+		fcpvi0: fcp@fe9af000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfe9af000 0 0x200>;
+			clocks = <&cpg CPG_MOD 611>;
+			power-domains = <&sysc R8A77965_PD_A3VP>;
+			resets = <&cpg 611>;
 		};
 
-		i2c6: i2c@e66e8000 {
-			reg = <0 0xe66e8000 0 0x40>;
-			/* placeholder */
-		};
+		vspd0: vsp@fea20000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfea20000 0 0x5000>;
+			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 623>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 623>;
 
-		i2c_dvfs: i2c@e60b0000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,iic-r8a77965",
-				     "renesas,rcar-gen3-iic",
-				     "renesas,rmobile-iic";
-			reg = <0 0xe60b0000 0 0x425>;
-			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 926>;
-			power-domains = <&sysc 32>;
-			resets = <&cpg 926>;
-			dmas = <&dmac0 0x11>, <&dmac0 0x10>;
-			dma-names = "tx", "rx";
-			status = "disabled";
+			renesas,fcp = <&fcpvd0>;
 		};
 
-		pwm0: pwm@e6e30000 {
-			reg = <0 0xe6e30000 0 8>;
-			/* placeholder */
+		fcpvd0: fcp@fea27000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea27000 0 0x200>;
+			clocks = <&cpg CPG_MOD 603>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 603>;
 		};
 
-		pwm1: pwm@e6e31000 {
-			reg = <0 0xe6e31000 0 8>;
-			#pwm-cells = <2>;
-			/* placeholder */
-		};
+		vspd1: vsp@fea28000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfea28000 0 0x5000>;
+			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 622>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 622>;
 
-		pwm2: pwm@e6e32000 {
-			reg = <0 0xe6e32000 0 8>;
-			/* placeholder */
+			renesas,fcp = <&fcpvd1>;
 		};
 
-		pwm3: pwm@e6e33000 {
-			reg = <0 0xe6e33000 0 8>;
-			/* placeholder */
+		fcpvd1: fcp@fea2f000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea2f000 0 0x200>;
+			clocks = <&cpg CPG_MOD 602>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 602>;
 		};
 
-		pwm4: pwm@e6e34000 {
-			reg = <0 0xe6e34000 0 8>;
-			/* placeholder */
+		csi20: csi2@fea80000 {
+			compatible = "renesas,r8a77965-csi2";
+			reg = <0 0xfea80000 0 0x10000>;
+			interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 714>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 714>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					csi20vin0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&vin0csi20>;
+					};
+					csi20vin1: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&vin1csi20>;
+					};
+					csi20vin2: endpoint@2 {
+						reg = <2>;
+						remote-endpoint = <&vin2csi20>;
+					};
+					csi20vin3: endpoint@3 {
+						reg = <3>;
+						remote-endpoint = <&vin3csi20>;
+					};
+					csi20vin4: endpoint@4 {
+						reg = <4>;
+						remote-endpoint = <&vin4csi20>;
+					};
+					csi20vin5: endpoint@5 {
+						reg = <5>;
+						remote-endpoint = <&vin5csi20>;
+					};
+					csi20vin6: endpoint@6 {
+						reg = <6>;
+						remote-endpoint = <&vin6csi20>;
+					};
+					csi20vin7: endpoint@7 {
+						reg = <7>;
+						remote-endpoint = <&vin7csi20>;
+					};
+				};
+			};
 		};
 
-		pwm5: pwm@e6e35000 {
-			reg = <0 0xe6e35000 0 8>;
-			/* placeholder */
+		csi40: csi2@feaa0000 {
+			compatible = "renesas,r8a77965-csi2";
+			reg = <0 0xfeaa0000 0 0x10000>;
+			interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 716>;
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 716>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					csi40vin0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&vin0csi40>;
+					};
+					csi40vin1: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&vin1csi40>;
+					};
+					csi40vin2: endpoint@2 {
+						reg = <2>;
+						remote-endpoint = <&vin2csi40>;
+					};
+					csi40vin3: endpoint@3 {
+						reg = <3>;
+						remote-endpoint = <&vin3csi40>;
+					};
+					csi40vin4: endpoint@4 {
+						reg = <4>;
+						remote-endpoint = <&vin4csi40>;
+					};
+					csi40vin5: endpoint@5 {
+						reg = <5>;
+						remote-endpoint = <&vin5csi40>;
+					};
+					csi40vin6: endpoint@6 {
+						reg = <6>;
+						remote-endpoint = <&vin6csi40>;
+					};
+					csi40vin7: endpoint@7 {
+						reg = <7>;
+						remote-endpoint = <&vin7csi40>;
+					};
+				};
+			};
 		};
 
-		pwm6: pwm@e6e36000 {
-			reg = <0 0xe6e36000 0 8>;
-			/* placeholder */
+		hdmi0: hdmi@fead0000 {
+			compatible = "renesas,r8a77965-hdmi",
+				     "renesas,rcar-gen3-hdmi";
+			reg = <0 0xfead0000 0 0x10000>;
+			interrupts = <GIC_SPI 389 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 729>,
+				 <&cpg CPG_CORE R8A77965_CLK_HDMI>;
+			clock-names = "iahb", "isfr";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 729>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+					dw_hdmi0_in: endpoint {
+						remote-endpoint = <&du_out_hdmi0>;
+					};
+				};
+				port@1 {
+					reg = <1>;
+				};
+			};
 		};
 
 		du: display@feb00000 {
-			reg = <0 0xfeb00000 0 0x80000>,
-			      <0 0xfeb90000 0 0x14>;
-			/* placeholder */
+			compatible = "renesas,du-r8a77965";
+			reg = <0 0xfeb00000 0 0x80000>;
+			reg-names = "du";
+			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 724>,
+				 <&cpg CPG_MOD 723>,
+				 <&cpg CPG_MOD 721>;
+			clock-names = "du.0", "du.1", "du.3";
+			status = "disabled";
+
+			vsps = <&vspd0 0 &vspd1 0 &vspd0 1>;
 
 			ports {
 				#address-cells = <1>;
@@ -797,6 +1826,7 @@
 				port@1 {
 					reg = <1>;
 					du_out_hdmi0: endpoint {
+						remote-endpoint = <&dw_hdmi0_in>;
 					};
 				};
 				port@2 {
@@ -807,139 +1837,74 @@
 			};
 		};
 
-		hsusb: usb@e6590000 {
-			reg = <0 0xe6590000 0 0x100>;
-			/* placeholder */
-		};
-
-		pciec0: pcie@fe000000 {
-			reg = <0 0xfe000000 0 0x80000>;
-			/* placeholder */
+		prr: chipid@fff00044 {
+			compatible = "renesas,prr";
+			reg = <0 0xfff00044 0 4>;
 		};
+	};
 
-		pciec1: pcie@ee800000 {
-			reg = <0 0xee800000 0 0x80000>;
-			/* placeholder */
-		};
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+	};
 
-		rcar_sound: sound@ec500000 {
-			reg =	<0 0xec500000 0 0x1000>, /* SCU */
-				<0 0xec5a0000 0 0x100>,  /* ADG */
-				<0 0xec540000 0 0x1000>, /* SSIU */
-				<0 0xec541000 0 0x280>,  /* SSI */
-				<0 0xec740000 0 0x200>;  /* Audio DMAC peri peri*/
-			/* placeholder */
+	thermal-zones {
+		sensor_thermal1: sensor-thermal1 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+			thermal-sensors = <&tsc 0>;
 
-			rcar_sound,dvc {
-				dvc0: dvc-0 {
-				};
-				dvc1: dvc-1 {
+			trips {
+				sensor1_crit: sensor1-crit {
+					temperature = <120000>;
+					hysteresis = <1000>;
+					type = "critical";
 				};
 			};
+		};
 
-			rcar_sound,src {
-				src0: src-0 {
-				};
-				src1: src-1 {
-				};
-			};
+		sensor_thermal2: sensor-thermal2 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+			thermal-sensors = <&tsc 1>;
 
-			rcar_sound,ssi {
-				ssi0: ssi-0 {
-				};
-				ssi1: ssi-1 {
+			trips {
+				sensor2_crit: sensor2-crit {
+					temperature = <120000>;
+					hysteresis = <1000>;
+					type = "critical";
 				};
 			};
 		};
 
-		usb2_phy1: usb-phy@ee0a0200 {
-			compatible = "renesas,usb2-phy-r8a77965",
-				     "renesas,rcar-gen3-usb2-phy";
-			reg = <0 0xee0a0200 0 0x700>;
-			clocks = <&cpg CPG_MOD 702>;
-			power-domains = <&sysc 32>;
-			resets = <&cpg 702>;
-			#phy-cells = <0>;
-			status = "disabled";
-		};
-
-		rpc: rpc@0xee200000 {
-			compatible = "renesas,rpc-r8a77965", "renesas,rpc";
-			reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>;
-			clocks = <&cpg CPG_MOD 917>;
-			bank-width = <2>;
-			status = "disabled";
-		};
-
-		sdhi0: sd@ee100000 {
-			compatible = "renesas,sdhi-r8a77965";
-			reg = <0 0xee100000 0 0x2000>;
-			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 314>;
-			max-frequency = <200000000>;
-			power-domains = <&sysc 32>;
-			resets = <&cpg 314>;
-			status = "disabled";
-		};
-
-		sdhi1: sd@ee120000 {
-			compatible = "renesas,sdhi-r8a77965";
-			reg = <0 0xee120000 0 0x2000>;
-			interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 313>;
-			max-frequency = <200000000>;
-			power-domains = <&sysc 32>;
-			resets = <&cpg 313>;
-			status = "disabled";
-		};
-
-		sdhi2: sd@ee140000 {
-			compatible = "renesas,sdhi-r8a77965";
-			reg = <0 0xee140000 0 0x2000>;
-			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 312>;
-			max-frequency = <200000000>;
-			power-domains = <&sysc 32>;
-			resets = <&cpg 312>;
-			status = "disabled";
-		};
-
-		sdhi3: sd@ee160000 {
-			compatible = "renesas,sdhi-r8a77965";
-			reg = <0 0xee160000 0 0x2000>;
-			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 311>;
-			max-frequency = <200000000>;
-			power-domains = <&sysc 32>;
-			resets = <&cpg 311>;
-			status = "disabled";
-		};
-
-		usb3_phy0: usb-phy@e65ee000 {
-			reg = <0 0xe65ee000 0 0x90>;
-			#phy-cells = <0>;
-			/* placeholder */
-		};
+		sensor_thermal3: sensor-thermal3 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+			thermal-sensors = <&tsc 2>;
 
-		usb3_peri0: usb@ee020000 {
-			reg = <0 0xee020000 0 0x400>;
-			/* placeholder */
+			trips {
+				sensor3_crit: sensor3-crit {
+					temperature = <120000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
 		};
+	};
 
-		xhci0: usb@ee000000 {
-			compatible = "renesas,xhci-r8a77965",
-				     "renesas,rcar-gen3-xhci";
-			reg = <0 0xee000000 0 0xc00>;
-			interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 328>;
-			power-domains = <&sysc 32>;
-			resets = <&cpg 328>;
-			status = "disabled";
-		};
+	/* External USB clocks - can be overridden by the board */
+	usb3s0_clk: usb3s0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
 
-		wdt0: watchdog@e6020000 {
-			reg = <0 0xe6020000 0 0x0c>;
-			/* placeholder */
-		};
+	usb_extal_clk: usb_extal {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
 	};
 };
diff --git a/arch/arm/dts/r8a77970-eagle-u-boot.dts b/arch/arm/dts/r8a77970-eagle-u-boot.dts
index 7ab71a1..5b17f1d 100644
--- a/arch/arm/dts/r8a77970-eagle-u-boot.dts
+++ b/arch/arm/dts/r8a77970-eagle-u-boot.dts
@@ -7,3 +7,48 @@
 
 #include "r8a77970-eagle.dts"
 #include "r8a77970-u-boot.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	aliases {
+		spi0 = &rpc;
+	};
+};
+
+&avb {
+	pinctrl-0 = <&avb0_pins>;
+	pinctrl-names = "default";
+
+};
+
+&phy0 {
+	reset-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
+};
+
+&pfc {
+	avb0_pins: avb {
+		mux {
+			groups = "avb0_link", "avb0_mdio", "avb0_rgmii", "avb0_txcrefclk";
+			function = "avb0";
+		};
+	};
+};
+
+&rpc {
+	num-cs = <1>;
+	status = "okay";
+	spi-max-frequency = <50000000>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	flash0: spi-flash@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "s25fs512s", "spi-flash", "jedec,spi-nor";
+		spi-max-frequency = <50000000>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <1>;
+		reg = <0>;
+		status = "okay";
+	};
+};
diff --git a/arch/arm/dts/r8a77970-eagle.dts b/arch/arm/dts/r8a77970-eagle.dts
index 5dcad63..b6d5332 100644
--- a/arch/arm/dts/r8a77970-eagle.dts
+++ b/arch/arm/dts/r8a77970-eagle.dts
@@ -8,7 +8,6 @@
 
 /dts-v1/;
 #include "r8a77970.dtsi"
-#include <dt-bindings/gpio/gpio.h>
 
 / {
 	model = "Renesas Eagle board based on r8a77970";
@@ -17,7 +16,6 @@
 	aliases {
 		serial0 = &scif0;
 		ethernet0 = &avb;
-		spi0 = &rpc;
 	};
 
 	chosen {
@@ -30,11 +28,57 @@
 		/* first 128MB is reserved for secure area. */
 		reg = <0x0 0x48000000 0x0 0x38000000>;
 	};
+
+	hdmi-out {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_out: endpoint {
+				remote-endpoint = <&adv7511_out>;
+			};
+		};
+	};
+
+	d3p3: regulator-fixed {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	lvds-decoder {
+		compatible = "thine,thc63lvd1024";
+
+		vcc-supply = <&d3p3>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				thc63lvd1024_in: endpoint {
+					remote-endpoint = <&lvds0_out>;
+				};
+			};
+
+			port@2 {
+				reg = <2>;
+				thc63lvd1024_out: endpoint {
+					remote-endpoint = <&adv7511_in>;
+				};
+			};
+		};
+	};
 };
 
 &avb {
-	pinctrl-0 = <&avb0_pins>;
+	pinctrl-0 = <&avb_pins>;
 	pinctrl-names = "default";
+
 	renesas,no-ether-link;
 	phy-handle = <&phy0>;
 	phy-mode = "rgmii-id";
@@ -45,7 +89,16 @@
 		reg = <0>;
 		interrupt-parent = <&gpio1>;
 		interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
-		reset-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&canfd {
+	pinctrl-0 = <&canfd0_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	channel0 {
+		status = "okay";
 	};
 };
 
@@ -70,16 +123,51 @@
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
+
+	hdmi@39 {
+		compatible = "adi,adv7511w";
+		reg = <0x39>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
+
+		adi,input-depth = <8>;
+		adi,input-colorspace = "rgb";
+		adi,input-clock = "1x";
+		adi,input-style = <1>;
+		adi,input-justification = "evenly";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				adv7511_in: endpoint {
+					remote-endpoint = <&thc63lvd1024_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				adv7511_out: endpoint {
+					remote-endpoint = <&hdmi_con_out>;
+				};
+			};
+		};
+	};
 };
 
 &pfc {
-	avb0_pins: avb {
-		mux {
-			groups = "avb0_link", "avb0_mdio", "avb0_rgmii", "avb0_txcrefclk";
-			function = "avb0";
-		};
+	avb_pins: avb0 {
+		groups = "avb0_mdio", "avb0_rgmii", "avb0_txcrefclk";
+		function = "avb0";
 	};
 
+	canfd0_pins: canfd0 {
+		groups = "canfd0_data_a";
+		function = "canfd0";
+	};
+
 	i2c0_pins: i2c0 {
 		groups = "i2c0";
 		function = "i2c0";
@@ -91,25 +179,6 @@
 	};
 };
 
-&rpc {
-	num-cs = <1>;
-	status = "okay";
-	spi-max-frequency = <50000000>;
-	#address-cells = <1>;
-	#size-cells = <0>;
-
-	flash0: spi-flash@0 {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		compatible = "s25fs512s", "spi-flash", "jedec,spi-nor";
-		spi-max-frequency = <50000000>;
-		spi-tx-bus-width = <1>;
-		spi-rx-bus-width = <1>;
-		reg = <0>;
-		status = "okay";
-	};
-};
-
 &rwdt {
 	timeout-sec = <60>;
 	status = "okay";
@@ -119,5 +188,21 @@
 	pinctrl-0 = <&scif0_pins>;
 	pinctrl-names = "default";
 
+	status = "okay";
+};
+
+&du {
 	status = "okay";
 };
+
+&lvds0 {
+	status = "okay";
+
+	ports {
+		port@1 {
+			lvds0_out: endpoint {
+				remote-endpoint = <&thc63lvd1024_in>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/dts/r8a77970-u-boot.dtsi b/arch/arm/dts/r8a77970-u-boot.dtsi
index 8fb7fe9..2903fdb 100644
--- a/arch/arm/dts/r8a77970-u-boot.dtsi
+++ b/arch/arm/dts/r8a77970-u-boot.dtsi
@@ -10,3 +10,13 @@
 &extalr_clk {
 	u-boot,dm-pre-reloc;
 };
+
+&soc {
+	rpc: rpc@0xee200000 {
+		compatible = "renesas,rpc-r8a77970", "renesas,rpc";
+		reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>;
+		clocks = <&cpg CPG_MOD 917>;
+		bank-width = <2>;
+		status = "disabled";
+	};
+};
diff --git a/arch/arm/dts/r8a77970.dtsi b/arch/arm/dts/r8a77970.dtsi
index 8dc599e..a0808c9 100644
--- a/arch/arm/dts/r8a77970.dtsi
+++ b/arch/arm/dts/r8a77970.dtsi
@@ -38,6 +38,16 @@
 			enable-method = "psci";
 		};
 
+		a53_1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <1>;
+			clocks = <&cpg CPG_CORE R8A77970_CLK_Z2>;
+			power-domains = <&sysc R8A77970_PD_CA53_CPU1>;
+			next-level-cache = <&L2_CA53>;
+			enable-method = "psci";
+		};
+
 		L2_CA53: cache-controller {
 			compatible = "cache";
 			power-domains = <&sysc R8A77970_PD_CA53_SCU>;
@@ -60,11 +70,25 @@
 		clock-frequency = <0>;
 	};
 
+	pmu_a53 {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&a53_0>, <&a53_1>;
+	};
+
 	psci {
 		compatible = "arm,psci-1.0", "arm,psci-0.2";
 		method = "smc";
 	};
 
+	/* External CAN clock - to be overridden by boards that provide it */
+	can_clk: can {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
 	/* External SCIF clock - to be overridden by boards that provide it */
 	scif_clk: scif {
 		compatible = "fixed-clock";
@@ -72,7 +96,7 @@
 		clock-frequency = <0>;
 	};
 
-	soc {
+	soc: soc {
 		compatible = "simple-bus";
 		interrupt-parent = <&gic>;
 
@@ -80,23 +104,6 @@
 		#size-cells = <2>;
 		ranges;
 
-		gic: interrupt-controller@f1010000 {
-			compatible = "arm,gic-400";
-			#interrupt-cells = <3>;
-			#address-cells = <0>;
-			interrupt-controller;
-			reg = <0 0xf1010000 0 0x1000>,
-			      <0 0xf1020000 0 0x20000>,
-			      <0 0xf1040000 0 0x20000>,
-			      <0 0xf1060000 0 0x20000>;
-			interrupts = <GIC_PPI 9	(GIC_CPU_MASK_SIMPLE(1) |
-				      IRQ_TYPE_LEVEL_HIGH)>;
-			clocks = <&cpg CPG_MOD 408>;
-			clock-names = "clk";
-			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
-			resets = <&cpg 408>;
-		};
-
 		rwdt: watchdog@e6020000 {
 			compatible = "renesas,r8a77970-wdt",
 				     "renesas,rcar-gen3-wdt";
@@ -107,75 +114,6 @@
 			status = "disabled";
 		};
 
-		cpg: clock-controller@e6150000 {
-			compatible = "renesas,r8a77970-cpg-mssr";
-			reg = <0 0xe6150000 0 0x1000>;
-			clocks = <&extal_clk>, <&extalr_clk>;
-			clock-names = "extal", "extalr";
-			#clock-cells = <2>;
-			#power-domain-cells = <0>;
-			#reset-cells = <1>;
-		};
-
-		rst: reset-controller@e6160000 {
-			compatible = "renesas,r8a77970-rst";
-			reg = <0 0xe6160000 0 0x200>;
-		};
-
-		sysc: system-controller@e6180000 {
-			compatible = "renesas,r8a77970-sysc";
-			reg = <0 0xe6180000 0 0x440>;
-			#power-domain-cells = <1>;
-		};
-
-		ipmmu_vi0: mmu@febd0000 {
-			compatible = "renesas,ipmmu-r8a77970";
-			reg = <0 0xfebd0000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 9>;
-			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
-			status = "disabled";
-		};
-
-		ipmmu_ir: mmu@ff8b0000 {
-			compatible = "renesas,ipmmu-r8a77970";
-			reg = <0 0xff8b0000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 3>;
-			power-domains = <&sysc R8A77970_PD_A3IR>;
-			#iommu-cells = <1>;
-			status = "disabled";
-		};
-
-		ipmmu_rt: mmu@ffc80000 {
-			compatible = "renesas,ipmmu-r8a77970";
-			reg = <0 0xffc80000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 7>;
-			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
-		};
-
-		ipmmu_ds1: mmu@e7740000 {
-			compatible = "renesas,ipmmu-r8a77970";
-			reg = <0 0xe7740000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 1>;
-			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
-		};
-
-		ipmmu_mm: mmu@e67b0000 {
-			compatible = "renesas,ipmmu-r8a77970";
-			reg = <0 0xe67b0000 0 0x1000>;
-			interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
-			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
-			#iommu-cells = <1>;
-		};
-
-		pfc: pin-controller@e6060000 {
-			compatible = "renesas,pfc-r8a77970";
-			reg = <0 0xe6060000 0 0x504>;
-		};
-
 		gpio0: gpio@e6050000 {
 			compatible = "renesas,gpio-r8a77970",
 				     "renesas,rcar-gen3-gpio";
@@ -266,6 +204,32 @@
 			resets = <&cpg 907>;
 		};
 
+		pfc: pin-controller@e6060000 {
+			compatible = "renesas,pfc-r8a77970";
+			reg = <0 0xe6060000 0 0x504>;
+		};
+
+		cpg: clock-controller@e6150000 {
+			compatible = "renesas,r8a77970-cpg-mssr";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>, <&extalr_clk>;
+			clock-names = "extal", "extalr";
+			#clock-cells = <2>;
+			#power-domain-cells = <0>;
+			#reset-cells = <1>;
+		};
+
+		rst: reset-controller@e6160000 {
+			compatible = "renesas,r8a77970-rst";
+			reg = <0 0xe6160000 0 0x200>;
+		};
+
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a77970-sysc";
+			reg = <0 0xe6180000 0 0x440>;
+			#power-domain-cells = <1>;
+		};
+
 		intc_ex: interrupt-controller@e61c0000 {
 			compatible = "renesas,intc-ex-r8a77970", "renesas,irqc";
 			#interrupt-cells = <2>;
@@ -282,67 +246,6 @@
 			resets = <&cpg 407>;
 		};
 
-		prr: chipid@fff00044 {
-			compatible = "renesas,prr";
-			reg = <0 0xfff00044 0 4>;
-		};
-
-		dmac1: dma-controller@e7300000 {
-			compatible = "renesas,dmac-r8a77970",
-				     "renesas,rcar-dmac";
-			reg = <0 0xe7300000 0 0x10000>;
-			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "error",
-					  "ch0", "ch1", "ch2", "ch3",
-					  "ch4", "ch5", "ch6", "ch7";
-			clocks = <&cpg CPG_MOD 218>;
-			clock-names = "fck";
-			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
-			resets = <&cpg 218>;
-			#dma-cells = <1>;
-			dma-channels = <8>;
-			iommus = <&ipmmu_ds1 0>, <&ipmmu_ds1 1>,
-			       <&ipmmu_ds1 2>, <&ipmmu_ds1 3>,
-			       <&ipmmu_ds1 4>, <&ipmmu_ds1 5>,
-			       <&ipmmu_ds1 6>, <&ipmmu_ds1 7>;
-		};
-
-		dmac2: dma-controller@e7310000 {
-			compatible = "renesas,dmac-r8a77970",
-				     "renesas,rcar-dmac";
-			reg = <0 0xe7310000 0 0x10000>;
-			interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "error",
-					  "ch0", "ch1", "ch2", "ch3",
-					  "ch4", "ch5", "ch6", "ch7";
-			clocks = <&cpg CPG_MOD 217>;
-			clock-names = "fck";
-			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
-			resets = <&cpg 217>;
-			#dma-cells = <1>;
-			dma-channels = <8>;
-			iommus = <&ipmmu_ds1 16>, <&ipmmu_ds1 17>,
-			       <&ipmmu_ds1 18>, <&ipmmu_ds1 19>,
-			       <&ipmmu_ds1 20>, <&ipmmu_ds1 21>,
-			       <&ipmmu_ds1 22>, <&ipmmu_ds1 23>;
-		};
-
 		i2c0: i2c@e6500000 {
 			compatible = "renesas,i2c-r8a77970",
 				     "renesas,rcar-gen3-i2c";
@@ -497,8 +400,79 @@
 			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
 			resets = <&cpg 517>;
 			status = "disabled";
+		};
+
+		canfd: can@e66c0000 {
+			compatible = "renesas,r8a77970-canfd",
+				     "renesas,rcar-gen3-canfd";
+			reg = <0 0xe66c0000 0 0x8000>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 914>,
+				 <&cpg CPG_CORE R8A77970_CLK_CANFD>,
+				 <&can_clk>;
+			clock-names = "fck", "canfd", "can_clk";
+			assigned-clocks = <&cpg CPG_CORE R8A77970_CLK_CANFD>;
+			assigned-clock-rates = <40000000>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 914>;
+			status = "disabled";
+
+			channel0 {
+				status = "disabled";
+			};
+
+			channel1 {
+				status = "disabled";
+			};
 		};
 
+		avb: ethernet@e6800000 {
+			compatible = "renesas,etheravb-r8a77970",
+				     "renesas,etheravb-rcar-gen3";
+			reg = <0 0xe6800000 0 0x800>;
+			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15",
+					  "ch16", "ch17", "ch18", "ch19",
+					  "ch20", "ch21", "ch22", "ch23",
+					  "ch24";
+			clocks = <&cpg CPG_MOD 812>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 812>;
+			phy-mode = "rgmii";
+			iommus = <&ipmmu_rt 3>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		scif0: serial@e6e60000 {
 			compatible = "renesas,scif-r8a77970",
 				     "renesas,rcar-gen3-scif",
@@ -570,65 +544,358 @@
 			status = "disabled";
 		};
 
-		avb: ethernet@e6800000 {
-			compatible = "renesas,etheravb-r8a77970",
-				     "renesas,etheravb-rcar-gen3";
-			reg = <0 0xe6800000 0 0x800>;
-			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "ch0", "ch1", "ch2", "ch3",
-					  "ch4", "ch5", "ch6", "ch7",
-					  "ch8", "ch9", "ch10", "ch11",
-					  "ch12", "ch13", "ch14", "ch15",
-					  "ch16", "ch17", "ch18", "ch19",
-					  "ch20", "ch21", "ch22", "ch23",
-					  "ch24";
-			clocks = <&cpg CPG_MOD 812>;
+
+		vin0: video@e6ef0000 {
+			compatible = "renesas,vin-r8a77970";
+			reg = <0 0xe6ef0000 0 0x1000>;
+			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 811>;
 			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
-			resets = <&cpg 812>;
-			phy-mode = "rgmii";
-			iommus = <&ipmmu_rt 3>;
-			#address-cells = <1>;
-			#size-cells = <0>;
+			resets = <&cpg 811>;
+			renesas,id = <0>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin0csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin0>;
+					};
+				};
+			};
+		};
+
+		vin1: video@e6ef1000 {
+			compatible = "renesas,vin-r8a77970";
+			reg = <0 0xe6ef1000 0 0x1000>;
+			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 810>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 810>;
+			renesas,id = <1>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin1csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin1>;
+					};
+				};
+			};
+		};
+
+		vin2: video@e6ef2000 {
+			compatible = "renesas,vin-r8a77970";
+			reg = <0 0xe6ef2000 0 0x1000>;
+			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 809>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 809>;
+			renesas,id = <2>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin2csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin2>;
+					};
+				};
+			};
+		};
+
+		vin3: video@e6ef3000 {
+			compatible = "renesas,vin-r8a77970";
+			reg = <0 0xe6ef3000 0 0x1000>;
+			interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 808>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 808>;
+			renesas,id = <3>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					vin3csi40: endpoint@2 {
+						reg = <2>;
+						remote-endpoint= <&csi40vin3>;
+					};
+				};
+			};
+		};
+
+		dmac1: dma-controller@e7300000 {
+			compatible = "renesas,dmac-r8a77970",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe7300000 0 0x10000>;
+			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7";
+			clocks = <&cpg CPG_MOD 218>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 218>;
+			#dma-cells = <1>;
+			dma-channels = <8>;
+			iommus = <&ipmmu_ds1 0>, <&ipmmu_ds1 1>,
+			       <&ipmmu_ds1 2>, <&ipmmu_ds1 3>,
+			       <&ipmmu_ds1 4>, <&ipmmu_ds1 5>,
+			       <&ipmmu_ds1 6>, <&ipmmu_ds1 7>;
+		};
+
+		dmac2: dma-controller@e7310000 {
+			compatible = "renesas,dmac-r8a77970",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe7310000 0 0x10000>;
+			interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7";
+			clocks = <&cpg CPG_MOD 217>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 217>;
+			#dma-cells = <1>;
+			dma-channels = <8>;
+			iommus = <&ipmmu_ds1 16>, <&ipmmu_ds1 17>,
+			       <&ipmmu_ds1 18>, <&ipmmu_ds1 19>,
+			       <&ipmmu_ds1 20>, <&ipmmu_ds1 21>,
+			       <&ipmmu_ds1 22>, <&ipmmu_ds1 23>;
+		};
+
+		ipmmu_ds1: mmu@e7740000 {
+			compatible = "renesas,ipmmu-r8a77970";
+			reg = <0 0xe7740000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 0>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_ir: mmu@ff8b0000 {
+			compatible = "renesas,ipmmu-r8a77970";
+			reg = <0 0xff8b0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 3>;
+			power-domains = <&sysc R8A77970_PD_A3IR>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_mm: mmu@e67b0000 {
+			compatible = "renesas,ipmmu-r8a77970";
+			reg = <0 0xe67b0000 0 0x1000>;
+			interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
 		};
 
-		rpc: rpc@0xee200000 {
-			compatible = "renesas,rpc-r8a77970", "renesas,rpc";
-			reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>;
-			clocks = <&cpg CPG_MOD 917>;
-			bank-width = <2>;
+		ipmmu_rt: mmu@ffc80000 {
+			compatible = "renesas,ipmmu-r8a77970";
+			reg = <0 0xffc80000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 7>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vi0: mmu@febd0000 {
+			compatible = "renesas,ipmmu-r8a77970";
+			reg = <0 0xfebd0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 9>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		gic: interrupt-controller@f1010000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0 0xf1010000 0 0x1000>,
+			      <0 0xf1020000 0 0x20000>,
+			      <0 0xf1040000 0 0x20000>,
+			      <0 0xf1060000 0 0x20000>;
+			interrupts = <GIC_PPI 9	(GIC_CPU_MASK_SIMPLE(2) |
+				      IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&cpg CPG_MOD 408>;
+			clock-names = "clk";
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 408>;
+		};
+
+		vspd0: vsp@fea20000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfea20000 0 0x5000>;
+			interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 623>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 623>;
+			renesas,fcp = <&fcpvd0>;
+		};
+
+		fcpvd0: fcp@fea27000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea27000 0 0x200>;
+			clocks = <&cpg CPG_MOD 603>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 603>;
+		};
+
+		csi40: csi2@feaa0000 {
+			compatible = "renesas,r8a77970-csi2";
+			reg = <0 0xfeaa0000 0 0x10000>;
+			interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 716>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 716>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					reg = <1>;
+
+					csi40vin0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&vin0csi40>;
+					};
+					csi40vin1: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&vin1csi40>;
+					};
+					csi40vin2: endpoint@2 {
+						reg = <2>;
+						remote-endpoint = <&vin2csi40>;
+					};
+					csi40vin3: endpoint@3 {
+						reg = <3>;
+						remote-endpoint = <&vin3csi40>;
+					};
+				};
+			};
+		};
+
+		du: display@feb00000 {
+			compatible = "renesas,du-r8a77970";
+			reg = <0 0xfeb00000 0 0x80000>;
+			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 724>;
+			clock-names = "du.0";
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 724>;
+			vsps = <&vspd0>;
 			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					du_out_rgb: endpoint {
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					du_out_lvds0: endpoint {
+						remote-endpoint = <&lvds0_in>;
+					};
+				};
+			};
+		};
+
+		lvds0: lvds-encoder@feb90000 {
+			compatible = "renesas,r8a77970-lvds";
+			reg = <0 0xfeb90000 0 0x14>;
+			clocks = <&cpg CPG_MOD 727>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 727>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					lvds0_in: endpoint {
+						remote-endpoint =
+							<&du_out_lvds0>;
+					};
+				};
+				port@1 {
+					reg = <1>;
+					lvds0_out: endpoint {
+					};
+				};
+			};
+		};
+
+		prr: chipid@fff00044 {
+			compatible = "renesas,prr";
+			reg = <0 0xfff00044 0 4>;
 		};
 	};
 
 	timer {
 		compatible = "arm,armv8-timer";
-		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
 	};
 };
diff --git a/arch/arm/dts/r8a77990-ebisu-u-boot.dts b/arch/arm/dts/r8a77990-ebisu-u-boot.dts
index 8d4ea88..b030d5c 100644
--- a/arch/arm/dts/r8a77990-ebisu-u-boot.dts
+++ b/arch/arm/dts/r8a77990-ebisu-u-boot.dts
@@ -7,3 +7,180 @@
 
 #include "r8a77990-ebisu.dts"
 #include "r8a77990-u-boot.dtsi"
+
+/ {
+	reg_1p8v: regulator0 {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-1.8V";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	reg_3p3v: regulator1 {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	vcc_sdhi0: regulator-vcc-sdhi0 {
+		compatible = "regulator-fixed";
+
+		regulator-name = "SDHI0 Vcc";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+
+		gpio = <&gpio5 17 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	vccq_sdhi0: regulator-vccq-sdhi0 {
+		compatible = "regulator-gpio";
+
+		regulator-name = "SDHI0 VccQ";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+
+		gpios = <&gpio5 18 GPIO_ACTIVE_HIGH>;
+		gpios-states = <1>;
+		states = <3300000 1
+			  1800000 0>;
+	};
+
+	vcc_sdhi1: regulator-vcc-sdhi1 {
+		compatible = "regulator-fixed";
+
+		regulator-name = "SDHI1 Vcc";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+
+		gpio = <&gpio0 4 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	vccq_sdhi1: regulator-vccq-sdhi1 {
+		compatible = "regulator-gpio";
+
+		regulator-name = "SDHI1 VccQ";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+
+		gpios = <&gpio3 15 GPIO_ACTIVE_HIGH>;
+		gpios-states = <1>;
+		states = <3300000 1
+			  1800000 0>;
+	};
+};
+
+&pfc {
+	pinctrl-0 = <&scif_clk_pins>;
+	pinctrl-names = "default";
+
+	scif2_pins: scif2 {
+		groups = "scif2_data_a";
+		function = "scif2";
+	};
+
+	scif_clk_pins: scif_clk {
+		groups = "scif_clk_a";
+		function = "scif_clk";
+	};
+
+	sdhi0_pins: sd0 {
+		groups = "sdhi0_data4", "sdhi0_ctrl";
+		function = "sdhi0";
+		power-source = <3300>;
+	};
+
+	sdhi0_pins_uhs: sd0_uhs {
+		groups = "sdhi0_data4", "sdhi0_ctrl";
+		function = "sdhi0";
+		power-source = <1800>;
+	};
+
+	sdhi1_pins: sd1 {
+		groups = "sdhi1_data4", "sdhi1_ctrl";
+		function = "sdhi1";
+		power-source = <3300>;
+	};
+
+	sdhi1_pins_uhs: sd1_uhs {
+		groups = "sdhi1_data4", "sdhi1_ctrl";
+		function = "sdhi1";
+		power-source = <1800>;
+	};
+
+	sdhi3_pins: sd2 {
+		groups = "sdhi3_data8", "sdhi3_ctrl", "sdhi3_ds";
+		function = "sdhi3";
+		power-source = <1800>;
+	};
+
+	sdhi3_pins_uhs: sd2_uhs {
+		groups = "sdhi3_data8", "sdhi3_ctrl", "sdhi3_ds";
+		function = "sdhi3";
+		power-source = <1800>;
+	};
+};
+
+&scif2 {
+	pinctrl-0 = <&scif2_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&sdhi0 {
+	/* full size SD */
+	pinctrl-0 = <&sdhi0_pins>;
+	pinctrl-1 = <&sdhi0_pins_uhs>;
+	pinctrl-names = "default", "state_uhs";
+
+	vmmc-supply = <&vcc_sdhi0>;
+	vqmmc-supply = <&vccq_sdhi0>;
+	cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
+	wp-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
+	bus-width = <4>;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	status = "okay";
+	max-frequency = <208000000>;
+};
+
+&sdhi1 {
+	/* microSD */
+	pinctrl-0 = <&sdhi1_pins>;
+	pinctrl-1 = <&sdhi1_pins_uhs>;
+	pinctrl-names = "default", "state_uhs";
+
+	vmmc-supply = <&vcc_sdhi1>;
+	vqmmc-supply = <&vccq_sdhi1>;
+	cd-gpios = <&gpio3 14 GPIO_ACTIVE_LOW>;
+	bus-width = <4>;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	status = "okay";
+	max-frequency = <208000000>;
+};
+
+&sdhi3 {
+	/* used for on-board 8bit eMMC */
+	pinctrl-0 = <&sdhi3_pins>;
+	pinctrl-1 = <&sdhi3_pins_uhs>;
+	pinctrl-names = "default", "state_uhs";
+
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_1p8v>;
+	bus-width = <8>;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	non-removable;
+	status = "okay";
+};
diff --git a/arch/arm/dts/r8a77990-ebisu.dts b/arch/arm/dts/r8a77990-ebisu.dts
index 5e3c195..2bc3a48 100644
--- a/arch/arm/dts/r8a77990-ebisu.dts
+++ b/arch/arm/dts/r8a77990-ebisu.dts
@@ -28,24 +28,6 @@
 		/* first 128MB is reserved for secure area. */
 		reg = <0x0 0x48000000 0x0 0x38000000>;
 	};
-
-	reg_1p8v: regulator0 {
-		compatible = "regulator-fixed";
-		regulator-name = "fixed-1.8V";
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <1800000>;
-		regulator-boot-on;
-		regulator-always-on;
-	};
-
-	reg_3p3v: regulator1 {
-		compatible = "regulator-fixed";
-		regulator-name = "fixed-3.3V";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		regulator-boot-on;
-		regulator-always-on;
-	};
 };
 
 &avb {
@@ -73,10 +55,11 @@
 	clock-frequency = <48000000>;
 };
 
-&pfc {
-	pinctrl-0 = <&scif_clk_pins>;
-	pinctrl-names = "default";
+&ohci0 {
+	status = "okay";
+};
 
+&pfc {
 	avb_pins: avb {
 		mux {
 			groups = "avb_link", "avb_mii";
@@ -84,65 +67,35 @@
 		};
 	};
 
-	scif2_pins: scif2 {
-		groups = "scif2_data_a";
-		function = "scif2";
-	};
-
-	scif_clk_pins: scif_clk {
-		groups = "scif_clk_a";
-		function = "scif_clk";
-	};
-
-	sdhi3_pins: sd2 {
-		groups = "sdhi3_data8", "sdhi3_ctrl";
-		function = "sdhi3";
-		power-source = <1800>;
-	};
-
-	sdhi3_pins_uhs: sd2_uhs {
-		groups = "sdhi3_data8", "sdhi3_ctrl";
-		function = "sdhi3";
-		power-source = <1800>;
-	};
-
-	usb0_pins: usb0 {
-		groups = "usb0";
+	usb0_pins: usb {
+		groups = "usb0_b";
 		function = "usb0";
 	};
-};
-
-&usb2_phy0 {
-	pinctrl-0 = <&usb0_pins>;
-	pinctrl-name = "default";
 
-	status = "okay";
+	usb30_pins: usb30 {
+		groups = "usb30";
+		function = "usb30";
+	};
 };
 
-&sdhi0 {
+&rwdt {
+	timeout-sec = <60>;
 	status = "okay";
 };
 
-&sdhi1 {
+&scif2 {
 	status = "okay";
 };
 
-&sdhi3 {
-	/* used for on-board 8bit eMMC */
-	pinctrl-0 = <&sdhi3_pins>;
-	pinctrl-1 = <&sdhi3_pins_uhs>;
-	pinctrl-names = "default", "state_uhs";
+&usb2_phy0 {
+	pinctrl-0 = <&usb0_pins>;
+	pinctrl-names = "default";
 
-	vmmc-supply = <&reg_3p3v>;
-	vqmmc-supply = <&reg_1p8v>;
-	bus-width = <8>;
-	mmc-hs200-1_8v;
-	non-removable;
 	status = "okay";
 };
 
-&scif2 {
-	pinctrl-0 = <&scif2_pins>;
+&xhci0 {
+	pinctrl-0 = <&usb30_pins>;
 	pinctrl-names = "default";
 
 	status = "okay";
diff --git a/arch/arm/dts/r8a77990-u-boot.dtsi b/arch/arm/dts/r8a77990-u-boot.dtsi
index 564c258..288e57e 100644
--- a/arch/arm/dts/r8a77990-u-boot.dtsi
+++ b/arch/arm/dts/r8a77990-u-boot.dtsi
@@ -6,3 +6,37 @@
  */
 
 #include "r8a779x-u-boot.dtsi"
+
+&soc {
+	rpc: rpc@0xee200000 {
+		compatible = "renesas,rpc-r8a77990", "renesas,rpc";
+		reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>;
+		clocks = <&cpg CPG_MOD 917>;
+		bank-width = <2>;
+		status = "disabled";
+	};
+
+	sdhi0: sd@ee100000 {
+		compatible = "renesas,sdhi-r8a77990";
+		reg = <0 0xee100000 0 0x2000>;
+		clocks = <&cpg CPG_MOD 314>;
+		max-frequency = <200000000>;
+		status = "disabled";
+	};
+
+	sdhi1: sd@ee120000 {
+		compatible = "renesas,sdhi-r8a77990";
+		reg = <0 0xee120000 0 0x2000>;
+		clocks = <&cpg CPG_MOD 313>;
+		max-frequency = <200000000>;
+		status = "disabled";
+	};
+
+	sdhi3: sd@ee160000 {
+		compatible = "renesas,sdhi-r8a77990";
+		reg = <0 0xee160000 0 0x2000>;
+		clocks = <&cpg CPG_MOD 311>;
+		max-frequency = <200000000>;
+		status = "disabled";
+	};
+};
diff --git a/arch/arm/dts/r8a77990.dtsi b/arch/arm/dts/r8a77990.dtsi
index ad20ea1..ae89260 100644
--- a/arch/arm/dts/r8a77990.dtsi
+++ b/arch/arm/dts/r8a77990.dtsi
@@ -18,16 +18,24 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		/* 1 core only at this point */
 		a53_0: cpu@0 {
 			compatible = "arm,cortex-a53", "arm,armv8";
-			reg = <0x0>;
+			reg = <0>;
 			device_type = "cpu";
 			power-domains = <&sysc 5>;
 			next-level-cache = <&L2_CA53>;
 			enable-method = "psci";
 		};
 
+		a53_1: cpu@1 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <1>;
+			device_type = "cpu";
+			power-domains = <&sysc 6>;
+			next-level-cache = <&L2_CA53>;
+			enable-method = "psci";
+		};
+
 		L2_CA53: cache-controller-0 {
 			compatible = "cache";
 			power-domains = <&sysc 21>;
@@ -45,8 +53,9 @@
 
 	pmu_a53 {
 		compatible = "arm,cortex-a53-pmu";
-		interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-affinity = <&a53_0>;
+		interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&a53_0>, <&a53_1>;
 	};
 
 	psci {
@@ -61,6 +70,16 @@
 		#size-cells = <2>;
 		ranges;
 
+		rwdt: watchdog@e6020000 {
+			compatible = "renesas,r8a77990-wdt",
+				     "renesas,rcar-gen3-wdt";
+			reg = <0 0xe6020000 0 0x0c>;
+			clocks = <&cpg CPG_MOD 402>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 402>;
+			status = "disabled";
+		};
+
 		gpio0: gpio@e6050000 {
 			compatible = "renesas,gpio-r8a77990",
 				     "renesas,rcar-gen3-gpio";
@@ -166,43 +185,6 @@
 			resets = <&cpg 906>;
 		};
 
-		ohci0: usb@ee080000 {
-			compatible = "generic-ohci";
-			reg = <0 0xee080000 0 0x100>;
-			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 703>;
-			phys = <&usb2_phy0>;
-			phy-names = "usb";
-			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
-			resets = <&cpg 703>;
-			status = "disabled";
-		};
-
-		ehci0: usb@ee080100 {
-			compatible = "generic-ehci";
-			reg = <0 0xee080100 0 0x100>;
-			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 703>;
-			phys = <&usb2_phy0>;
-			phy-names = "usb";
-			companion = <&ohci0>;
-			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
-			resets = <&cpg 703>;
-			status = "disabled";
-		};
-
-		usb2_phy0: usb-phy@ee080200 {
-			compatible = "renesas,usb2-phy-r8a7790",
-				     "renesas,rcar-gen3-usb2-phy";
-			reg = <0 0xee080200 0 0x700>;
-			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 703>;
-			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
-			resets = <&cpg 703>;
-			#phy-cells = <0>;
-			status = "disabled";
-		};
-
 		pfc: pin-controller@e6060000 {
 			compatible = "renesas,pfc-r8a77990";
 			reg = <0 0xe6060000 0 0x508>;
@@ -223,40 +205,97 @@
 			reg = <0 0xe6160000 0 0x0200>;
 		};
 
-		sdhi0: sd@ee100000 {
-			compatible = "renesas,sdhi-r8a77990";
-			reg = <0 0xee100000 0 0x2000>;
-			clocks = <&cpg CPG_MOD 314>;
-			max-frequency = <200000000>;
-			status = "disabled";
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a77990-sysc";
+			reg = <0 0xe6180000 0 0x0400>;
+			#power-domain-cells = <1>;
 		};
 
-		sdhi1: sd@ee120000 {
-			compatible = "renesas,sdhi-r8a77990";
-			reg = <0 0xee120000 0 0x2000>;
-			clocks = <&cpg CPG_MOD 313>;
-			max-frequency = <200000000>;
-			status = "disabled";
+		ipmmu_ds0: mmu@e6740000 {
+			compatible = "renesas,ipmmu-r8a77990";
+			reg = <0 0xe6740000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 0>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
 		};
 
-		sdhi3: sd@ee160000 {
-			compatible = "renesas,sdhi-r8a77990";
-			reg = <0 0xee160000 0 0x2000>;
-			clocks = <&cpg CPG_MOD 311>;
-			max-frequency = <200000000>;
-			status = "disabled";
+		ipmmu_ds1: mmu@e7740000 {
+			compatible = "renesas,ipmmu-r8a77990";
+			reg = <0 0xe7740000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 1>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
 		};
 
-		sysc: system-controller@e6180000 {
-			compatible = "renesas,r8a77990-sysc";
-			reg = <0 0xe6180000 0 0x0400>;
-			#power-domain-cells = <1>;
+		ipmmu_hc: mmu@e6570000 {
+			compatible = "renesas,ipmmu-r8a77990";
+			reg = <0 0xe6570000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 2>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
 		};
 
+		ipmmu_mm: mmu@e67b0000 {
+			compatible = "renesas,ipmmu-r8a77990";
+			reg = <0 0xe67b0000 0 0x1000>;
+			interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_mp: mmu@ec670000 {
+			compatible = "renesas,ipmmu-r8a77990";
+			reg = <0 0xec670000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 4>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_pv0: mmu@fd800000 {
+			compatible = "renesas,ipmmu-r8a77990";
+			reg = <0 0xfd800000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 6>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_rt: mmu@ffc80000 {
+			compatible = "renesas,ipmmu-r8a77990";
+			reg = <0 0xffc80000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 10>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vc0: mmu@fe6b0000 {
+			compatible = "renesas,ipmmu-r8a77990";
+			reg = <0 0xfe6b0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 12>;
+			power-domains = <&sysc R8A77990_PD_A3VC>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vi0: mmu@febd0000 {
+			compatible = "renesas,ipmmu-r8a77990";
+			reg = <0 0xfebd0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 14>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vp0: mmu@fe990000 {
+			compatible = "renesas,ipmmu-r8a77990";
+			reg = <0 0xfe990000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 16>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
 		avb: ethernet@e6800000 {
 			compatible = "renesas,etheravb-r8a77990",
 				     "renesas,etheravb-rcar-gen3";
-			reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
+			reg = <0 0xe6800000 0 0x800>;
 			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
@@ -310,6 +349,54 @@
 			status = "disabled";
 		};
 
+		xhci0: usb@ee000000 {
+			compatible = "renesas,xhci-r8a77990",
+				     "renesas,rcar-gen3-xhci";
+			reg = <0 0xee000000 0 0xc00>;
+			interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 328>;
+			power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+			resets = <&cpg 328>;
+			status = "disabled";
+		};
+
+		ohci0: usb@ee080000 {
+			compatible = "generic-ohci";
+			reg = <0 0xee080000 0 0x100>;
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			phys = <&usb2_phy0>;
+			phy-names = "usb";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 703>;
+			status = "disabled";
+		};
+
+		ehci0: usb@ee080100 {
+			compatible = "generic-ehci";
+			reg = <0 0xee080100 0 0x100>;
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			phys = <&usb2_phy0>;
+			phy-names = "usb";
+			companion = <&ohci0>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 703>;
+			status = "disabled";
+		};
+
+		usb2_phy0: usb-phy@ee080200 {
+			compatible = "renesas,usb2-phy-r8a77990",
+				     "renesas,rcar-gen3-usb2-phy";
+			reg = <0 0xee080200 0 0x700>;
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 703>;
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
 		gic: interrupt-controller@f1010000 {
 			compatible = "arm,gic-400";
 			#interrupt-cells = <3>;
@@ -320,7 +407,7 @@
 			      <0x0 0xf1040000 0 0x20000>,
 			      <0x0 0xf1060000 0 0x20000>;
 			interrupts = <GIC_PPI 9
-					(GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
+					(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
 			clocks = <&cpg CPG_MOD 408>;
 			clock-names = "clk";
 			power-domains = <&sysc 32>;
@@ -331,21 +418,13 @@
 			compatible = "renesas,prr";
 			reg = <0 0xfff00044 0 4>;
 		};
-
-		rpc: rpc@0xee200000 {
-			compatible = "renesas,rpc-r8a77990", "renesas,rpc";
-			reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>;
-			clocks = <&cpg CPG_MOD 917>;
-			bank-width = <2>;
-			status = "disabled";
-		};
 	};
 
 	timer {
 		compatible = "arm,armv8-timer";
-		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
 	};
 };
diff --git a/arch/arm/dts/r8a77995-draak.dts b/arch/arm/dts/r8a77995-draak.dts
index 711d487..a8e8f26 100644
--- a/arch/arm/dts/r8a77995-draak.dts
+++ b/arch/arm/dts/r8a77995-draak.dts
@@ -56,6 +56,27 @@
 		};
 	};
 
+	composite-in {
+		compatible = "composite-video-connector";
+
+		port {
+			composite_con_in: endpoint {
+				remote-endpoint = <&adv7180_in>;
+			};
+		};
+	};
+
+	hdmi-in {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&adv7612_in>;
+			};
+		};
+	};
+
 	memory@48000000 {
 		device_type = "memory";
 		/* first 128MB is reserved for secure area. */
@@ -79,6 +100,12 @@
 		regulator-boot-on;
 		regulator-always-on;
 	};
+
+	x12_clk: x12 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <74250000>;
+	};
 };
 
 &extal_clk {
@@ -88,7 +115,7 @@
 &pfc {
 	avb0_pins: avb {
 		mux {
-			groups = "avb0_link", "avb0_mdc", "avb0_mii";
+			groups = "avb0_link", "avb0_mdio", "avb0_mii";
 			function = "avb0";
 		};
 	};
@@ -139,6 +166,11 @@
 		groups = "usb0";
 		function = "usb0";
 	};
+
+	vin4_pins_cvbs: vin4 {
+		groups = "vin4_data8", "vin4_sync", "vin4_clk";
+		function = "vin4";
+	};
 };
 
 &i2c0 {
@@ -151,6 +183,77 @@
 		reg = <0x50>;
 		pagesize = <8>;
 	};
+
+	composite-in@20 {
+		compatible = "adi,adv7180cp";
+		reg = <0x20>;
+
+		port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				adv7180_in: endpoint {
+					remote-endpoint = <&composite_con_in>;
+				};
+			};
+
+			port@3 {
+				reg = <3>;
+
+				/*
+				 * The VIN4 video input path is shared between
+				 * CVBS and HDMI inputs through SW[49-53]
+				 * switches.
+				 *
+				 * CVBS is the default selection, link it to
+				 * VIN4 here.
+				 */
+				adv7180_out: endpoint {
+					remote-endpoint = <&vin4_in>;
+				};
+			};
+		};
+
+	};
+
+	hdmi-decoder@4c {
+		compatible = "adi,adv7612";
+		reg = <0x4c>;
+		default-input = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				adv7612_in: endpoint {
+					remote-endpoint = <&hdmi_con_in>;
+				};
+			};
+
+			port@2 {
+				reg = <2>;
+
+				/*
+				 * The VIN4 video input path is shared between
+				 * CVBS and HDMI inputs through SW[49-53]
+				 * switches.
+				 *
+				 * CVBS is the default selection, leave HDMI
+				 * not connected here.
+				 */
+				adv7612_out: endpoint {
+					pclk-sample = <0>;
+					hsync-active = <0>;
+					vsync-active = <0>;
+				};
+			};
+		};
+	};
 };
 
 &i2c1 {
@@ -164,6 +267,11 @@
 	pinctrl-names = "default";
 	status = "okay";
 
+	clocks = <&cpg CPG_MOD 724>,
+		 <&cpg CPG_MOD 723>,
+		 <&x12_clk>;
+	clock-names = "du.0", "du.1", "dclkin.0";
+
 	ports {
 		port@0 {
 			endpoint {
@@ -242,4 +350,24 @@
 &rwdt {
 	timeout-sec = <60>;
 	status = "okay";
+};
+
+&vin4 {
+	pinctrl-0 = <&vin4_pins_cvbs>;
+	pinctrl-names = "default";
+
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+
+			vin4_in: endpoint {
+				remote-endpoint = <&adv7180_out>;
+			};
+		};
+	};
 };
diff --git a/arch/arm/dts/r8a77995-u-boot.dtsi b/arch/arm/dts/r8a77995-u-boot.dtsi
index e0852c8..1f6efaf 100644
--- a/arch/arm/dts/r8a77995-u-boot.dtsi
+++ b/arch/arm/dts/r8a77995-u-boot.dtsi
@@ -6,3 +6,13 @@
  */
 
 #include "r8a779x-u-boot.dtsi"
+
+&soc {
+	rpc: rpc@0xee200000 {
+		compatible = "renesas,rpc-r8a77995", "renesas,rpc";
+		reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>;
+		clocks = <&cpg CPG_MOD 917>;
+		bank-width = <2>;
+		status = "disabled";
+	};
+};
diff --git a/arch/arm/dts/r8a77995.dtsi b/arch/arm/dts/r8a77995.dtsi
index 1d49279..1efef62 100644
--- a/arch/arm/dts/r8a77995.dtsi
+++ b/arch/arm/dts/r8a77995.dtsi
@@ -15,9 +15,11 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
-	psci {
-		compatible = "arm,psci-1.0", "arm,psci-0.2";
-		method = "smc";
+	/* External CAN clock - to be overridden by boards that provide it */
+	can_clk: can {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
 	};
 
 	cpus {
@@ -48,48 +50,29 @@
 		clock-frequency = <0>;
 	};
 
-	/* External CAN clock - to be overridden by boards that provide it */
-	can_clk: can {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-
 	pmu_a53 {
 		compatible = "arm,cortex-a53-pmu";
 		interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2";
+		method = "smc";
+	};
+
 	scif_clk: scif {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
 		clock-frequency = <0>;
 	};
 
-	soc {
+	soc: soc {
 		compatible = "simple-bus";
 		interrupt-parent = <&gic>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		ranges;
 
-		gic: interrupt-controller@f1010000 {
-			compatible = "arm,gic-400";
-			#interrupt-cells = <3>;
-			#address-cells = <0>;
-			interrupt-controller;
-			reg = <0x0 0xf1010000 0 0x1000>,
-			      <0x0 0xf1020000 0 0x20000>,
-			      <0x0 0xf1040000 0 0x20000>,
-			      <0x0 0xf1060000 0 0x20000>;
-			interrupts = <GIC_PPI 9
-					(GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
-			clocks = <&cpg CPG_MOD 408>;
-			clock-names = "clk";
-			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-			resets = <&cpg 408>;
-		};
-
 		rwdt: watchdog@e6020000 {
 			compatible = "renesas,r8a77995-wdt",
 				     "renesas,rcar-gen3-wdt";
@@ -100,211 +83,9 @@
 			status = "disabled";
 		};
 
-		ipmmu_vi0: mmu@febd0000 {
-			compatible = "renesas,ipmmu-r8a77995";
-			reg = <0 0xfebd0000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 14>;
-			#iommu-cells = <1>;
-			status = "disabled";
-		};
-
-		ipmmu_vp0: mmu@fe990000 {
-			compatible = "renesas,ipmmu-r8a77995";
-			reg = <0 0xfe990000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 16>;
-			#iommu-cells = <1>;
-			status = "disabled";
-		};
-
-		ipmmu_vc0: mmu@fe6b0000 {
-			compatible = "renesas,ipmmu-r8a77995";
-			reg = <0 0xfe6b0000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 12>;
-			#iommu-cells = <1>;
-			status = "disabled";
-		};
-
-		ipmmu_pv0: mmu@fd800000 {
-			compatible = "renesas,ipmmu-r8a77995";
-			reg = <0 0xfd800000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 6>;
-			#iommu-cells = <1>;
-			status = "disabled";
-		};
-
-		ipmmu_hc: mmu@e6570000 {
-			compatible = "renesas,ipmmu-r8a77995";
-			reg = <0 0xe6570000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 2>;
-			#iommu-cells = <1>;
-			status = "disabled";
-		};
-
-		ipmmu_rt: mmu@ffc80000 {
-			compatible = "renesas,ipmmu-r8a77995";
-			reg = <0 0xffc80000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 10>;
-			#iommu-cells = <1>;
-			status = "disabled";
-		};
-
-		ipmmu_mp: mmu@ec670000 {
-			compatible = "renesas,ipmmu-r8a77995";
-			reg = <0 0xec670000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 4>;
-			#iommu-cells = <1>;
-			status = "disabled";
-		};
-
-		ipmmu_ds0: mmu@e6740000 {
-			compatible = "renesas,ipmmu-r8a77995";
-			reg = <0 0xe6740000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 0>;
-			#iommu-cells = <1>;
-			status = "disabled";
-		};
-
-		ipmmu_ds1: mmu@e7740000 {
-			compatible = "renesas,ipmmu-r8a77995";
-			reg = <0 0xe7740000 0 0x1000>;
-			renesas,ipmmu-main = <&ipmmu_mm 1>;
-			#iommu-cells = <1>;
-			status = "disabled";
-		};
-
-		ipmmu_mm: mmu@e67b0000 {
-			compatible = "renesas,ipmmu-r8a77995";
-			reg = <0 0xe67b0000 0 0x1000>;
-			interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
-			#iommu-cells = <1>;
-			status = "disabled";
-		};
-
-
-		cpg: clock-controller@e6150000 {
-			compatible = "renesas,r8a77995-cpg-mssr";
-			reg = <0 0xe6150000 0 0x1000>;
-			clocks = <&extal_clk>;
-			clock-names = "extal";
-			#clock-cells = <2>;
-			#power-domain-cells = <0>;
-			#reset-cells = <1>;
-		};
-
-		rst: reset-controller@e6160000 {
-			compatible = "renesas,r8a77995-rst";
-			reg = <0 0xe6160000 0 0x0200>;
-		};
-
-		pfc: pin-controller@e6060000 {
-			compatible = "renesas,pfc-r8a77995";
-			reg = <0 0xe6060000 0 0x508>;
-		};
-
-		prr: chipid@fff00044 {
-			compatible = "renesas,prr";
-			reg = <0 0xfff00044 0 4>;
-		};
-
-		sysc: system-controller@e6180000 {
-			compatible = "renesas,r8a77995-sysc";
-			reg = <0 0xe6180000 0 0x0400>;
-			#power-domain-cells = <1>;
-		};
-
-		intc_ex: interrupt-controller@e61c0000 {
-			compatible = "renesas,intc-ex-r8a77995", "renesas,irqc";
-			#interrupt-cells = <2>;
-			interrupt-controller;
-			reg = <0 0xe61c0000 0 0x200>;
-			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 407>;
-			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-			resets = <&cpg 407>;
-		};
-
-		dmac0: dma-controller@e6700000 {
-			compatible = "renesas,dmac-r8a77995",
-				     "renesas,rcar-dmac";
-			reg = <0 0xe6700000 0 0x10000>;
-			interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "error",
-					"ch0", "ch1", "ch2", "ch3",
-					"ch4", "ch5", "ch6", "ch7";
-			clocks = <&cpg CPG_MOD 219>;
-			clock-names = "fck";
-			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-			resets = <&cpg 219>;
-			#dma-cells = <1>;
-			dma-channels = <8>;
-		};
-
-		dmac1: dma-controller@e7300000 {
-			compatible = "renesas,dmac-r8a77995",
-				     "renesas,rcar-dmac";
-			reg = <0 0xe7300000 0 0x10000>;
-			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "error",
-					"ch0", "ch1", "ch2", "ch3",
-					"ch4", "ch5", "ch6", "ch7";
-			clocks = <&cpg CPG_MOD 218>;
-			clock-names = "fck";
-			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-			resets = <&cpg 218>;
-			#dma-cells = <1>;
-			dma-channels = <8>;
-		};
-
-		dmac2: dma-controller@e7310000 {
-			compatible = "renesas,dmac-r8a77995",
-				     "renesas,rcar-dmac";
-			reg = <0 0xe7310000 0 0x10000>;
-			interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "error",
-					"ch0", "ch1", "ch2", "ch3",
-					"ch4", "ch5", "ch6", "ch7";
-			clocks = <&cpg CPG_MOD 217>;
-			clock-names = "fck";
-			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-			resets = <&cpg 217>;
-			#dma-cells = <1>;
-			dma-channels = <8>;
-		};
-
 		gpio0: gpio@e6050000 {
 			compatible = "renesas,gpio-r8a77995",
-				     "renesas,rcar-gen3-gpio",
-				     "renesas,gpio-rcar";
+				     "renesas,rcar-gen3-gpio";
 			reg = <0 0xe6050000 0 0x50>;
 			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
 			#gpio-cells = <2>;
@@ -319,8 +100,7 @@
 
 		gpio1: gpio@e6051000 {
 			compatible = "renesas,gpio-r8a77995",
-				     "renesas,rcar-gen3-gpio",
-				     "renesas,gpio-rcar";
+				     "renesas,rcar-gen3-gpio";
 			reg = <0 0xe6051000 0 0x50>;
 			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
 			#gpio-cells = <2>;
@@ -335,8 +115,7 @@
 
 		gpio2: gpio@e6052000 {
 			compatible = "renesas,gpio-r8a77995",
-				     "renesas,rcar-gen3-gpio",
-				     "renesas,gpio-rcar";
+				     "renesas,rcar-gen3-gpio";
 			reg = <0 0xe6052000 0 0x50>;
 			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
 			#gpio-cells = <2>;
@@ -351,8 +130,7 @@
 
 		gpio3: gpio@e6053000 {
 			compatible = "renesas,gpio-r8a77995",
-				     "renesas,rcar-gen3-gpio",
-				     "renesas,gpio-rcar";
+				     "renesas,rcar-gen3-gpio";
 			reg = <0 0xe6053000 0 0x50>;
 			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
 			#gpio-cells = <2>;
@@ -367,8 +145,7 @@
 
 		gpio4: gpio@e6054000 {
 			compatible = "renesas,gpio-r8a77995",
-				     "renesas,rcar-gen3-gpio",
-				     "renesas,gpio-rcar";
+				     "renesas,rcar-gen3-gpio";
 			reg = <0 0xe6054000 0 0x50>;
 			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
 			#gpio-cells = <2>;
@@ -383,8 +160,7 @@
 
 		gpio5: gpio@e6055000 {
 			compatible = "renesas,gpio-r8a77995",
-				     "renesas,rcar-gen3-gpio",
-				     "renesas,gpio-rcar";
+				     "renesas,rcar-gen3-gpio";
 			reg = <0 0xe6055000 0 0x50>;
 			interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
 			#gpio-cells = <2>;
@@ -399,8 +175,7 @@
 
 		gpio6: gpio@e6055400 {
 			compatible = "renesas,gpio-r8a77995",
-				     "renesas,rcar-gen3-gpio",
-				     "renesas,gpio-rcar";
+				     "renesas,rcar-gen3-gpio";
 			reg = <0 0xe6055400 0 0x50>;
 			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
 			#gpio-cells = <2>;
@@ -413,38 +188,162 @@
 			resets = <&cpg 906>;
 		};
 
-		can0: can@e6c30000 {
-			compatible = "renesas,can-r8a77995",
-				     "renesas,rcar-gen3-can";
-			reg = <0 0xe6c30000 0 0x1000>;
-			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 916>,
-			       <&cpg CPG_CORE R8A77995_CLK_CANFD>,
-			       <&can_clk>;
-			clock-names = "clkp1", "clkp2", "can_clk";
-			assigned-clocks = <&cpg CPG_CORE R8A77995_CLK_CANFD>;
-			assigned-clock-rates = <40000000>;
-			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-			resets = <&cpg 916>;
-			status = "disabled";
+		pfc: pin-controller@e6060000 {
+			compatible = "renesas,pfc-r8a77995";
+			reg = <0 0xe6060000 0 0x508>;
 		};
 
-		can1: can@e6c38000 {
-			compatible = "renesas,can-r8a77995",
-				     "renesas,rcar-gen3-can";
-			reg = <0 0xe6c38000 0 0x1000>;
-			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 915>,
-			       <&cpg CPG_CORE R8A77995_CLK_CANFD>,
-			       <&can_clk>;
-			clock-names = "clkp1", "clkp2", "can_clk";
-			assigned-clocks = <&cpg CPG_CORE R8A77995_CLK_CANFD>;
-			assigned-clock-rates = <40000000>;
+		cpg: clock-controller@e6150000 {
+			compatible = "renesas,r8a77995-cpg-mssr";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>;
+			clock-names = "extal";
+			#clock-cells = <2>;
+			#power-domain-cells = <0>;
+			#reset-cells = <1>;
+		};
+
+		rst: reset-controller@e6160000 {
+			compatible = "renesas,r8a77995-rst";
+			reg = <0 0xe6160000 0 0x0200>;
+		};
+
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a77995-sysc";
+			reg = <0 0xe6180000 0 0x0400>;
+			#power-domain-cells = <1>;
+		};
+
+		thermal: thermal@e6190000 {
+			compatible = "renesas,thermal-r8a77995";
+			reg = <0 0xe6190000 0 0x10>, <0 0xe6190100 0 0x38>;
+			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 522>;
 			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-			resets = <&cpg 915>;
+			resets = <&cpg 522>;
+			#thermal-sensor-cells = <0>;
+		};
+
+		intc_ex: interrupt-controller@e61c0000 {
+			compatible = "renesas,intc-ex-r8a77995", "renesas,irqc";
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			reg = <0 0xe61c0000 0 0x200>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 407>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 407>;
+		};
+
+		hscif0: serial@e6540000 {
+			compatible = "renesas,hscif-r8a77995",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe6540000 0 0x60>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 520>,
+				 <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x31>, <&dmac1 0x30>,
+			       <&dmac2 0x31>, <&dmac2 0x30>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 520>;
 			status = "disabled";
 		};
 
+		hscif3: serial@e66a0000 {
+			compatible = "renesas,hscif-r8a77995",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe66a0000 0 0x60>;
+			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 517>,
+				 <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x37>, <&dmac0 0x36>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 517>;
+			status = "disabled";
+		};
+
+		i2c0: i2c@e6500000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77995",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6500000 0 0x40>;
+			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 931>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 931>;
+			dmas = <&dmac1 0x91>, <&dmac1 0x90>,
+			       <&dmac2 0x91>, <&dmac2 0x90>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c1: i2c@e6508000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77995",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6508000 0 0x40>;
+			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 930>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 930>;
+			dmas = <&dmac1 0x93>, <&dmac1 0x92>,
+			       <&dmac2 0x93>, <&dmac2 0x92>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c2: i2c@e6510000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77995",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6510000 0 0x40>;
+			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 929>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 929>;
+			dmas = <&dmac1 0x95>, <&dmac1 0x94>,
+			       <&dmac2 0x95>, <&dmac2 0x94>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c3: i2c@e66d0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77995",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66d0000 0 0x40>;
+			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 928>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 928>;
+			dmas = <&dmac0 0x97>, <&dmac0 0x96>;
+			dma-names = "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
 		canfd: can@e66c0000 {
 			compatible = "renesas,r8a77995-canfd",
 				     "renesas,rcar-gen3-canfd";
@@ -470,6 +369,159 @@
 			};
 		};
 
+		dmac0: dma-controller@e6700000 {
+			compatible = "renesas,dmac-r8a77995",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6700000 0 0x10000>;
+			interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5", "ch6", "ch7";
+			clocks = <&cpg CPG_MOD 219>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 219>;
+			#dma-cells = <1>;
+			dma-channels = <8>;
+		};
+
+		dmac1: dma-controller@e7300000 {
+			compatible = "renesas,dmac-r8a77995",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe7300000 0 0x10000>;
+			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5", "ch6", "ch7";
+			clocks = <&cpg CPG_MOD 218>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 218>;
+			#dma-cells = <1>;
+			dma-channels = <8>;
+		};
+
+		dmac2: dma-controller@e7310000 {
+			compatible = "renesas,dmac-r8a77995",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe7310000 0 0x10000>;
+			interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5", "ch6", "ch7";
+			clocks = <&cpg CPG_MOD 217>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 217>;
+			#dma-cells = <1>;
+			dma-channels = <8>;
+		};
+
+		ipmmu_ds0: mmu@e6740000 {
+			compatible = "renesas,ipmmu-r8a77995";
+			reg = <0 0xe6740000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 0>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_ds1: mmu@e7740000 {
+			compatible = "renesas,ipmmu-r8a77995";
+			reg = <0 0xe7740000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 1>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_hc: mmu@e6570000 {
+			compatible = "renesas,ipmmu-r8a77995";
+			reg = <0 0xe6570000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 2>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_mm: mmu@e67b0000 {
+			compatible = "renesas,ipmmu-r8a77995";
+			reg = <0 0xe67b0000 0 0x1000>;
+			interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_mp: mmu@ec670000 {
+			compatible = "renesas,ipmmu-r8a77995";
+			reg = <0 0xec670000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 4>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_pv0: mmu@fd800000 {
+			compatible = "renesas,ipmmu-r8a77995";
+			reg = <0 0xfd800000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 6>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_rt: mmu@ffc80000 {
+			compatible = "renesas,ipmmu-r8a77995";
+			reg = <0 0xffc80000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 10>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vc0: mmu@fe6b0000 {
+			compatible = "renesas,ipmmu-r8a77995";
+			reg = <0 0xfe6b0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 12>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vi0: mmu@febd0000 {
+			compatible = "renesas,ipmmu-r8a77995";
+			reg = <0 0xfebd0000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 14>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
+		ipmmu_vp0: mmu@fe990000 {
+			compatible = "renesas,ipmmu-r8a77995";
+			reg = <0 0xfe990000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 16>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+		};
+
 		avb: ethernet@e6800000 {
 			compatible = "renesas,etheravb-r8a77995",
 				     "renesas,etheravb-rcar-gen3";
@@ -509,94 +561,42 @@
 			clocks = <&cpg CPG_MOD 812>;
 			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
 			resets = <&cpg 812>;
-			phy-mode = "rgmii";
-			iommus = <&ipmmu_ds0 16>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
-		scif2: serial@e6e88000 {
-			compatible = "renesas,scif-r8a77995",
-				     "renesas,rcar-gen3-scif", "renesas,scif";
-			reg = <0 0xe6e88000 0 64>;
-			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 310>,
-				 <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
-				 <&scif_clk>;
-			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x13>, <&dmac1 0x12>,
-			       <&dmac2 0x13>, <&dmac2 0x12>;
-			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-			resets = <&cpg 310>;
-			status = "disabled";
-		};
-
-		i2c0: i2c@e6500000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a77995",
-				     "renesas,rcar-gen3-i2c";
-			reg = <0 0xe6500000 0 0x40>;
-			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 931>;
-			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-			resets = <&cpg 931>;
-			dmas = <&dmac1 0x91>, <&dmac1 0x90>,
-			       <&dmac2 0x91>, <&dmac2 0x90>;
-			dma-names = "tx", "rx", "tx", "rx";
-			i2c-scl-internal-delay-ns = <6>;
-			status = "disabled";
-		};
-
-		i2c1: i2c@e6508000 {
+			phy-mode = "rgmii";
+			iommus = <&ipmmu_ds0 16>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a77995",
-				     "renesas,rcar-gen3-i2c";
-			reg = <0 0xe6508000 0 0x40>;
-			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 930>;
-			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-			resets = <&cpg 930>;
-			dmas = <&dmac1 0x93>, <&dmac1 0x92>,
-			       <&dmac2 0x93>, <&dmac2 0x92>;
-			dma-names = "tx", "rx", "tx", "rx";
-			i2c-scl-internal-delay-ns = <6>;
 			status = "disabled";
 		};
 
-		i2c2: i2c@e6510000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a77995",
-				     "renesas,rcar-gen3-i2c";
-			reg = <0 0xe6510000 0 0x40>;
-			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 929>;
+		can0: can@e6c30000 {
+			compatible = "renesas,can-r8a77995",
+				     "renesas,rcar-gen3-can";
+			reg = <0 0xe6c30000 0 0x1000>;
+			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 916>,
+			       <&cpg CPG_CORE R8A77995_CLK_CANFD>,
+			       <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			assigned-clocks = <&cpg CPG_CORE R8A77995_CLK_CANFD>;
+			assigned-clock-rates = <40000000>;
 			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-			resets = <&cpg 929>;
-			dmas = <&dmac1 0x95>, <&dmac1 0x94>,
-			       <&dmac2 0x95>, <&dmac2 0x94>;
-			dma-names = "tx", "rx", "tx", "rx";
-			i2c-scl-internal-delay-ns = <6>;
+			resets = <&cpg 916>;
 			status = "disabled";
 		};
 
-		i2c3: i2c@e66d0000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a77995",
-				     "renesas,rcar-gen3-i2c";
-			reg = <0 0xe66d0000 0 0x40>;
-			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 928>;
+		can1: can@e6c38000 {
+			compatible = "renesas,can-r8a77995",
+				     "renesas,rcar-gen3-can";
+			reg = <0 0xe6c38000 0 0x1000>;
+			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 915>,
+			       <&cpg CPG_CORE R8A77995_CLK_CANFD>,
+			       <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			assigned-clocks = <&cpg CPG_CORE R8A77995_CLK_CANFD>;
+			assigned-clock-rates = <40000000>;
 			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-			resets = <&cpg 928>;
-			dmas = <&dmac0 0x97>, <&dmac0 0x96>;
-			dma-names = "tx", "rx";
-			i2c-scl-internal-delay-ns = <6>;
+			resets = <&cpg 915>;
 			status = "disabled";
 		};
 
@@ -640,38 +640,199 @@
 			status = "disabled";
 		};
 
-		sdhi2: sd@ee140000 {
-			compatible = "renesas,sdhi-r8a77995",
-				     "renesas,rcar-gen3-sdhi";
-			reg = <0 0xee140000 0 0x2000>;
-			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 312>;
-			max-frequency = <200000000>;
+		scif0: serial@e6e60000 {
+			compatible = "renesas,scif-r8a77995",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6e60000 0 64>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 207>,
+				 <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x51>, <&dmac1 0x50>,
+			       <&dmac2 0x51>, <&dmac2 0x50>;
+			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-			resets = <&cpg 312>;
+			resets = <&cpg 207>;
 			status = "disabled";
 		};
 
-		ehci0: usb@ee080100 {
-			compatible = "generic-ehci";
-			reg = <0 0xee080100 0 0x100>;
+		scif1: serial@e6e68000 {
+			compatible = "renesas,scif-r8a77995",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6e68000 0 64>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 206>,
+				 <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x53>, <&dmac1 0x52>,
+			       <&dmac2 0x53>, <&dmac2 0x52>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 206>;
+			status = "disabled";
+		};
+
+		scif2: serial@e6e88000 {
+			compatible = "renesas,scif-r8a77995",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6e88000 0 64>;
+			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 310>,
+				 <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x13>, <&dmac1 0x12>,
+			       <&dmac2 0x13>, <&dmac2 0x12>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 310>;
+			status = "disabled";
+		};
+
+		scif3: serial@e6c50000 {
+			compatible = "renesas,scif-r8a77995",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6c50000 0 64>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 204>,
+				 <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x57>, <&dmac0 0x56>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 204>;
+			status = "disabled";
+		};
+
+		scif4: serial@e6c40000 {
+			compatible = "renesas,scif-r8a77995",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6c40000 0 64>;
+			interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 203>,
+				 <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x59>, <&dmac0 0x58>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 203>;
+			status = "disabled";
+		};
+
+		scif5: serial@e6f30000 {
+			compatible = "renesas,scif-r8a77995",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6f30000 0 64>;
+			interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 202>,
+				 <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x5b>, <&dmac1 0x5a>,
+			       <&dmac2 0x5b>, <&dmac2 0x5a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 202>;
+			status = "disabled";
+		};
+
+		msiof0: spi@e6e90000 {
+			compatible = "renesas,msiof-r8a77995",
+				     "renesas,rcar-gen3-msiof";
+			reg = <0 0xe6e90000 0 0x64>;
+			interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 211>;
+			dmas = <&dmac1 0x41>, <&dmac1 0x40>,
+			       <&dmac2 0x41>, <&dmac2 0x40>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 211>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		msiof1: spi@e6ea0000 {
+			compatible = "renesas,msiof-r8a77995",
+				     "renesas,rcar-gen3-msiof";
+			reg = <0 0xe6ea0000 0 0x64>;
+			interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 210>;
+			dmas = <&dmac1 0x43>, <&dmac1 0x42>,
+			       <&dmac2 0x43>, <&dmac2 0x42>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 210>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		msiof2: spi@e6c00000 {
+			compatible = "renesas,msiof-r8a77995",
+				     "renesas,rcar-gen3-msiof";
+			reg = <0 0xe6c00000 0 0x64>;
+			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 209>;
+			dmas = <&dmac0 0x45>, <&dmac0 0x44>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 209>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		msiof3: spi@e6c10000 {
+			compatible = "renesas,msiof-r8a77995",
+				     "renesas,rcar-gen3-msiof";
+			reg = <0 0xe6c10000 0 0x64>;
+			interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 208>;
+			dmas = <&dmac0 0x47>, <&dmac0 0x46>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 208>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		vin4: video@e6ef4000 {
+			compatible = "renesas,vin-r8a77995";
+			reg = <0 0xe6ef4000 0 0x1000>;
+			interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 807>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 807>;
+			renesas,id = <4>;
+			status = "disabled";
+		};
+
+		ohci0: usb@ee080000 {
+			compatible = "generic-ohci";
+			reg = <0 0xee080000 0 0x100>;
 			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 703>;
 			phys = <&usb2_phy0>;
 			phy-names = "usb";
-			companion = <&ohci0>;
 			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
 			resets = <&cpg 703>;
 			status = "disabled";
 		};
 
-		ohci0: usb@ee080000 {
-			compatible = "generic-ohci";
-			reg = <0 0xee080000 0 0x100>;
+		ehci0: usb@ee080100 {
+			compatible = "generic-ehci";
+			reg = <0 0xee080100 0 0x100>;
 			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 703>;
 			phys = <&usb2_phy0>;
 			phy-names = "usb";
+			companion = <&ohci0>;
 			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
 			resets = <&cpg 703>;
 			status = "disabled";
@@ -689,6 +850,35 @@
 			status = "disabled";
 		};
 
+		sdhi2: sd@ee140000 {
+			compatible = "renesas,sdhi-r8a77995",
+				     "renesas,rcar-gen3-sdhi";
+			reg = <0 0xee140000 0 0x2000>;
+			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 312>;
+			max-frequency = <200000000>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 312>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller@f1010000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0x0 0xf1010000 0 0x1000>,
+			      <0x0 0xf1020000 0 0x20000>,
+			      <0x0 0xf1040000 0 0x20000>,
+			      <0x0 0xf1060000 0 0x20000>;
+			interrupts = <GIC_PPI 9
+					(GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&cpg CPG_MOD 408>;
+			clock-names = "clk";
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 408>;
+		};
+
 		vspbs: vsp@fe960000 {
 			compatible = "renesas,vsp2";
 			reg = <0 0xfe960000 0 0x8000>;
@@ -699,18 +889,9 @@
 			renesas,fcp = <&fcpvb0>;
 		};
 
-		fcpvb0: fcp@fe96f000 {
-			compatible = "renesas,fcpv";
-			reg = <0 0xfe96f000 0 0x200>;
-			clocks = <&cpg CPG_MOD 607>;
-			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-			resets = <&cpg 607>;
-			iommus = <&ipmmu_vp0 5>;
-		};
-
 		vspd0: vsp@fea20000 {
 			compatible = "renesas,vsp2";
-			reg = <0 0xfea20000 0 0x8000>;
+			reg = <0 0xfea20000 0 0x5000>;
 			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 623>;
 			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
@@ -718,18 +899,9 @@
 			renesas,fcp = <&fcpvd0>;
 		};
 
-		fcpvd0: fcp@fea27000 {
-			compatible = "renesas,fcpv";
-			reg = <0 0xfea27000 0 0x200>;
-			clocks = <&cpg CPG_MOD 603>;
-			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-			resets = <&cpg 603>;
-			iommus = <&ipmmu_vi0 8>;
-		};
-
 		vspd1: vsp@fea28000 {
 			compatible = "renesas,vsp2";
-			reg = <0 0xfea28000 0 0x8000>;
+			reg = <0 0xfea28000 0 0x5000>;
 			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 622>;
 			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
@@ -737,6 +909,24 @@
 			renesas,fcp = <&fcpvd1>;
 		};
 
+		fcpvb0: fcp@fe96f000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfe96f000 0 0x200>;
+			clocks = <&cpg CPG_MOD 607>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 607>;
+			iommus = <&ipmmu_vp0 5>;
+		};
+
+		fcpvd0: fcp@fea27000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea27000 0 0x200>;
+			clocks = <&cpg CPG_MOD 603>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 603>;
+			iommus = <&ipmmu_vi0 8>;
+		};
+
 		fcpvd1: fcp@fea2f000 {
 			compatible = "renesas,fcpv";
 			reg = <0 0xfea2f000 0 0x200>;
@@ -781,12 +971,28 @@
 			};
 		};
 
-		rpc: rpc@0xee200000 {
-			compatible = "renesas,rpc-r8a77995", "renesas,rpc";
-			reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>;
-			clocks = <&cpg CPG_MOD 917>;
-			bank-width = <2>;
-			status = "disabled";
+		prr: chipid@fff00044 {
+			compatible = "renesas,prr";
+			reg = <0 0xfff00044 0 4>;
+		};
+	};
+
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+			thermal-sensors = <&thermal>;
+
+			trips {
+				cpu-crit {
+					temperature = <120000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+			};
 		};
 	};
 
diff --git a/arch/arm/dts/rk3399-puma.dtsi b/arch/arm/dts/rk3399-puma.dtsi
index 6e7e1e3..11ffcb7 100644
--- a/arch/arm/dts/rk3399-puma.dtsi
+++ b/arch/arm/dts/rk3399-puma.dtsi
@@ -503,7 +503,7 @@
 &sdmmc {
 	u-boot,dm-pre-reloc;
 	clock-frequency = <150000000>;
-	clock-freq-min-max = <100000 150000000>;
+	max-frequency = <40000000>;
 	supports-sd;
 	bus-width = <4>;
 	cap-mmc-highspeed;
diff --git a/arch/arm/dts/rv1108.dtsi b/arch/arm/dts/rv1108.dtsi
index acfd97e..215d885 100644
--- a/arch/arm/dts/rv1108.dtsi
+++ b/arch/arm/dts/rv1108.dtsi
@@ -121,8 +121,35 @@
 	};
 
 	grf: syscon@10300000 {
-		compatible = "rockchip,rv1108-grf", "syscon";
+		compatible = "rockchip,rv1108-grf", "syscon", "simple-mfd";
 		reg = <0x10300000 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		u2phy: usb2-phy@100 {
+			compatible = "rockchip,rv1108-usb2phy";
+			reg = <0x100 0x0c>;
+			clocks = <&cru SCLK_USBPHY>;
+			clock-names = "phyclk";
+			#clock-cells = <0>;
+			clock-output-names = "usbphy";
+			rockchip,usbgrf = <&usbgrf>;
+			status = "disabled";
+
+			u2phy_otg: otg-port {
+				interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "otg-mux";
+				#phy-cells = <0>;
+				status = "disabled";
+			};
+
+			u2phy_host: host-port {
+				interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "linestate";
+				#phy-cells = <0>;
+				status = "disabled";
+			};
+		};
 	};
 
 	saradc: saradc@1038c000 {
@@ -141,6 +168,11 @@
 		reg = <0x20060000 0x1000>;
 	};
 
+	usbgrf: syscon@202a0000 {
+		compatible = "rockchip,rv1108-usbgrf", "syscon";
+		reg = <0x202a0000 0x1000>;
+	};
+
 	cru: clock-controller@20200000 {
 		compatible = "rockchip,rv1108-cru";
 		reg = <0x20200000 0x1000>;
@@ -200,12 +232,19 @@
 	};
 
 	usb20_otg: usb@30180000 {
-		compatible = "rockchip,rv1108-usb", "rockchip,rk3288-usb",
+		compatible = "rockchip,rv1108-usb", "rockchip,rk3066-usb",
 			     "snps,dwc2";
 		reg = <0x30180000 0x40000>;
 		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
-		hnp-srp-disable;
+		clocks = <&cru HCLK_OTG>;
+		clock-names = "otg";
 		dr_mode = "otg";
+		g-np-tx-fifo-size = <16>;
+		g-rx-fifo-size = <280>;
+		g-tx-fifo-size = <256 128 128 64 32 16>;
+		g-use-dma;
+		phys = <&u2phy_otg>;
+		phy-names = "usb2-phy";
 		status = "disabled";
 	};
 
@@ -427,6 +466,35 @@
 			};
 		};
 
+		emmc {
+			emmc_clk: emmc-clk {
+				rockchip,pins = <2 RK_PB6 RK_FUNC_1 &pcfg_pull_none_drv_8ma>;
+			};
+
+			emmc_cmd: emmc-cmd {
+				rockchip,pins = <2 RK_PB4 RK_FUNC_2 &pcfg_pull_up_drv_8ma>;
+			};
+
+			emmc_pwren: emmc-pwren {
+				rockchip,pins = <2 RK_PC2 RK_FUNC_2 &pcfg_pull_none>;
+			};
+
+			emmc_bus1: emmc-bus1 {
+				rockchip,pins = <2 RK_PA0 RK_FUNC_2 &pcfg_pull_up_drv_8ma>;
+			};
+
+			emmc_bus8: emmc-bus8 {
+				rockchip,pins = <2 RK_PA0 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+						<2 RK_PA1 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+						<2 RK_PA2 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+						<2 RK_PA3 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+						<2 RK_PA4 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+						<2 RK_PA5 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+						<2 RK_PA6 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+						<2 RK_PA7 RK_FUNC_2 &pcfg_pull_up_drv_8ma>;
+			};
+		};
+
 		sdmmc {
 			sdmmc_clk: sdmmc-clk {
 				rockchip,pins = <3 RK_PC4 RK_FUNC_1 &pcfg_pull_none_drv_4ma>;
diff --git a/arch/arm/dts/salvator-common.dtsi b/arch/arm/dts/salvator-common.dtsi
index a36e0eb..7d3d866 100644
--- a/arch/arm/dts/salvator-common.dtsi
+++ b/arch/arm/dts/salvator-common.dtsi
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for common parts of Salvator-X board variants
  *
  * Copyright (C) 2015-2016 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /*
@@ -36,7 +33,7 @@
 / {
 	aliases {
 		serial0 = &scif2;
-		serial1 = &scif1;
+		serial1 = &hscif1;
 		ethernet0 = &avb;
 	};
 
@@ -66,6 +63,29 @@
 		enable-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
 	};
 
+	cvbs-in {
+		compatible = "composite-video-connector";
+		label = "CVBS IN";
+
+		port {
+			cvbs_con: endpoint {
+				remote-endpoint = <&adv7482_ain7>;
+			};
+		};
+	};
+
+	hdmi-in {
+		compatible = "hdmi-connector";
+		label = "HDMI IN";
+		type = "a";
+
+		port {
+			hdmi_in_con: endpoint {
+				remote-endpoint = <&adv7482_hdmi>;
+			};
+		};
+	};
+
 	reg_1p8v: regulator0 {
 		compatible = "regulator-fixed";
 		regulator-name = "fixed-1.8V";
@@ -93,20 +113,12 @@
 		regulator-always-on;
 	};
 
-	rsnd_ak4613: sound {
-		compatible = "simple-audio-card";
+	sound_card: sound {
+		compatible = "audio-graph-card";
 
-		simple-audio-card,format = "left_j";
-		simple-audio-card,bitclock-master = <&sndcpu>;
-		simple-audio-card,frame-master = <&sndcpu>;
+		label = "rcar-sound";
 
-		sndcpu: simple-audio-card,cpu {
-			sound-dai = <&rcar_sound>;
-		};
-
-		sndcodec: simple-audio-card,codec {
-			sound-dai = <&ak4613>;
-		};
+		dais = <&rsnd_port0>;
 	};
 
 	vbus0_usb2: regulator-vbus0-usb2 {
@@ -268,6 +280,37 @@
 	};
 };
 
+&csi20 {
+	status = "okay";
+
+	ports {
+		port@0 {
+			reg = <0>;
+			csi20_in: endpoint {
+				clock-lanes = <0>;
+				data-lanes = <1>;
+				remote-endpoint = <&adv7482_txb>;
+			};
+		};
+	};
+};
+
+&csi40 {
+	status = "okay";
+
+	ports {
+		port@0 {
+			reg = <0>;
+
+			csi40_in: endpoint {
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				remote-endpoint = <&adv7482_txa>;
+			};
+		};
+	};
+};
+
 &du {
 	pinctrl-0 = <&du_pins>;
 	pinctrl-names = "default";
@@ -295,6 +338,15 @@
 	clock-frequency = <32768>;
 };
 
+&hscif1 {
+	pinctrl-0 = <&hscif1_pins>;
+	pinctrl-names = "default";
+
+	uart-has-rtscts;
+	/* Please only enable hscif1 or scif1 */
+	status = "okay";
+};
+
 &hsusb {
 	dr_mode = "otg";
 	status = "okay";
@@ -322,6 +374,12 @@
 		asahi-kasei,out4-single-end;
 		asahi-kasei,out5-single-end;
 		asahi-kasei,out6-single-end;
+
+		port {
+			ak4613_endpoint: endpoint {
+				remote-endpoint = <&rsnd_endpoint0>;
+			};
+		};
 	};
 
 	cs2000: clk_multiplier@4f {
@@ -359,6 +417,55 @@
 
 		shunt-resistor-micro-ohms = <5000>;
 	};
+
+	video-receiver@70 {
+		compatible = "adi,adv7482";
+		reg = <0x70>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		interrupt-parent = <&gpio6>;
+		interrupt-names = "intrq1", "intrq2";
+		interrupts = <30 IRQ_TYPE_LEVEL_LOW>,
+			     <31 IRQ_TYPE_LEVEL_LOW>;
+
+		port@7 {
+			reg = <7>;
+
+			adv7482_ain7: endpoint {
+				remote-endpoint = <&cvbs_con>;
+			};
+		};
+
+		port@8 {
+			reg = <8>;
+
+			adv7482_hdmi: endpoint {
+				remote-endpoint = <&hdmi_in_con>;
+			};
+		};
+
+		port@a {
+			reg = <10>;
+
+			adv7482_txa: endpoint {
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				remote-endpoint = <&csi40_in>;
+			};
+		};
+
+		port@b {
+			reg = <11>;
+
+			adv7482_txb: endpoint {
+				clock-lanes = <0>;
+				data-lanes = <1>;
+				remote-endpoint = <&csi20_in>;
+			};
+		};
+	};
 };
 
 &i2c_dvfs {
@@ -376,6 +483,8 @@
 		#interrupt-cells = <2>;
 		gpio-controller;
 		#gpio-cells = <2>;
+		rohm,ddr-backup-power = <0xf>;
+		rohm,rstbmode-level;
 
 		regulators {
 			dvfs: dvfs {
@@ -387,6 +496,12 @@
 			};
 		};
 	};
+
+	eeprom@50 {
+		compatible = "rohm,br24t01", "atmel,24c01";
+		reg = <0x50>;
+		pagesize = <8>;
+	};
 };
 
 &ohci0 {
@@ -416,12 +531,12 @@
 
 	avb_pins: avb {
 		mux {
-			groups = "avb_link", "avb_mdc", "avb_mii";
+			groups = "avb_link", "avb_mdio", "avb_mii";
 			function = "avb";
 		};
 
-		pins_mdc {
-			groups = "avb_mdc";
+		pins_mdio {
+			groups = "avb_mdio";
 			drive-strength = <24>;
 		};
 
@@ -437,6 +552,11 @@
 		function = "du";
 	};
 
+	hscif1_pins: hscif1 {
+		groups = "hscif1_data_a", "hscif1_ctrl_a";
+		function = "hscif1";
+	};
+
 	i2c2_pins: i2c2 {
 		groups = "i2c2_a";
 		function = "i2c2";
@@ -480,13 +600,13 @@
 	};
 
 	sdhi2_pins: sd2 {
-		groups = "sdhi2_data8", "sdhi2_ctrl";
+		groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
 		function = "sdhi2";
-		power-source = <1800>;
+		power-source = <3300>;
 	};
 
 	sdhi2_pins_uhs: sd2_uhs {
-		groups = "sdhi2_data8", "sdhi2_ctrl";
+		groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
 		function = "sdhi2";
 		power-source = <1800>;
 	};
@@ -581,10 +701,18 @@
 		 <&audio_clk_c>,
 		 <&cpg CPG_CORE CPG_AUDIO_CLK_I>;
 
+	ports {
+		rsnd_port0: port@0 {
+			rsnd_endpoint0: endpoint {
+				remote-endpoint = <&ak4613_endpoint>;
+
+				dai-format = "left_j";
+				bitclock-master = <&rsnd_endpoint0>;
+				frame-master = <&rsnd_endpoint0>;
+
-	rcar_sound,dai {
-		dai0 {
-			playback = <&ssi0 &src0 &dvc0>;
-			capture  = <&ssi1 &src1 &dvc1>;
+				playback = <&ssi0 &src0 &dvc0>;
+				capture  = <&ssi1 &src1 &dvc1>;
+			};
 		};
 	};
 };
@@ -594,7 +722,8 @@
 	pinctrl-names = "default";
 
 	uart-has-rtscts;
-	status = "okay";
+	/* Please only enable hscif1 or scif1 */
+	/* status = "okay"; */
 };
 
 &scif2 {
@@ -689,7 +818,39 @@
 	clock-frequency = <100000000>;
 };
 
+&vin0 {
+	status = "okay";
+};
+
+&vin1 {
+	status = "okay";
+};
+
+&vin2 {
+	status = "okay";
+};
+
+&vin3 {
+	status = "okay";
+};
+
-&wdt0 {
+&vin4 {
+	status = "okay";
+};
+
+&vin5 {
+	status = "okay";
+};
+
+&vin6 {
+	status = "okay";
+};
+
+&vin7 {
+	status = "okay";
+};
+
+&rwdt {
 	timeout-sec = <60>;
 	status = "okay";
 };
diff --git a/arch/arm/dts/salvator-x.dtsi b/arch/arm/dts/salvator-x.dtsi
index 468868c..ddee50e 100644
--- a/arch/arm/dts/salvator-x.dtsi
+++ b/arch/arm/dts/salvator-x.dtsi
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Salvator-X board
  *
  * Copyright (C) 2015-2016 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include "salvator-common.dtsi"
@@ -20,6 +17,8 @@
 };
 
 &i2c4 {
+	clock-frequency = <400000>;
+
 	versaclock5: clock-generator@6a {
 		compatible = "idt,5p49v5923";
 		reg = <0x6a>;
diff --git a/arch/arm/dts/socfpga.dtsi b/arch/arm/dts/socfpga.dtsi
index 3144494..2458d67 100644
--- a/arch/arm/dts/socfpga.dtsi
+++ b/arch/arm/dts/socfpga.dtsi
@@ -1,9 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- *  Copyright (C) 2012 Altera <www.altera.com>
+ * Copyright (C) 2012 Altera <www.altera.com>
  */
 
-#include "skeleton.dtsi"
 #include <dt-bindings/reset/altr,rst-mgr.h>
 
 / {
@@ -11,34 +10,26 @@
 	#size-cells = <1>;
 
 	aliases {
-		ethernet0 = &gmac0;
-		ethernet1 = &gmac1;
-		i2c0 = &i2c0;
-		i2c1 = &i2c1;
-		i2c2 = &i2c2;
-		i2c3 = &i2c3;
 		serial0 = &uart0;
 		serial1 = &uart1;
 		timer0 = &timer0;
 		timer1 = &timer1;
 		timer2 = &timer2;
 		timer3 = &timer3;
-		spi0 = &qspi;
-		spi1 = &spi0;
-		spi2 = &spi1;
 	};
 
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
+		enable-method = "altr,socfpga-smp";
 
-		cpu@0 {
+		cpu0: cpu@0 {
 			compatible = "arm,cortex-a9";
 			device_type = "cpu";
 			reg = <0>;
 			next-level-cache = <&L2>;
 		};
-		cpu@1 {
+		cpu1: cpu@1 {
 			compatible = "arm,cortex-a9";
 			device_type = "cpu";
 			reg = <1>;
@@ -46,6 +37,15 @@
 		};
 	};
 
+	pmu: pmu@ff111000 {
+		compatible = "arm,cortex-a9-pmu";
+		interrupt-parent = <&intc>;
+		interrupts = <0 176 4>, <0 177 4>;
+		interrupt-affinity = <&cpu0>, <&cpu1>;
+		reg = <0xff111000 0x1000>,
+		      <0xff113000 0x1000>;
+	};
+
 	intc: intc@fffed000 {
 		compatible = "arm,cortex-a9-gic";
 		#interrupt-cells = <3>;
@@ -63,7 +63,7 @@
 		ranges;
 
 		amba {
-			compatible = "arm,amba-bus";
+			compatible = "simple-bus";
 			#address-cells = <1>;
 			#size-cells = <1>;
 			ranges;
@@ -87,6 +87,14 @@
 			};
 		};
 
+		base_fpga_region {
+			compatible = "fpga-region";
+			fpga-mgr = <&fpgamgr0>;
+
+			#address-cells = <0x1>;
+			#size-cells = <0x1>;
+		};
+
 		can0: can@ffc00000 {
 			compatible = "bosch,d_can";
 			reg = <0xffc00000 0x1000>;
@@ -131,7 +139,7 @@
 						compatible = "fixed-clock";
 					};
 
-					main_pll: main_pll {
+					main_pll: main_pll@40 {
 						#address-cells = <1>;
 						#size-cells = <0>;
 						#clock-cells = <0>;
@@ -139,7 +147,7 @@
 						clocks = <&osc1>;
 						reg = <0x40>;
 
-						mpuclk: mpuclk {
+						mpuclk: mpuclk@48 {
 							#clock-cells = <0>;
 							compatible = "altr,socfpga-perip-clk";
 							clocks = <&main_pll>;
@@ -147,7 +155,7 @@
 							reg = <0x48>;
 						};
 
-						mainclk: mainclk {
+						mainclk: mainclk@4c {
 							#clock-cells = <0>;
 							compatible = "altr,socfpga-perip-clk";
 							clocks = <&main_pll>;
@@ -155,29 +163,29 @@
 							reg = <0x4C>;
 						};
 
-						dbg_base_clk: dbg_base_clk {
+						dbg_base_clk: dbg_base_clk@50 {
 							#clock-cells = <0>;
 							compatible = "altr,socfpga-perip-clk";
-							clocks = <&main_pll>;
+							clocks = <&main_pll>, <&osc1>;
 							div-reg = <0xe8 0 9>;
 							reg = <0x50>;
 						};
 
-						main_qspi_clk: main_qspi_clk {
+						main_qspi_clk: main_qspi_clk@54 {
 							#clock-cells = <0>;
 							compatible = "altr,socfpga-perip-clk";
 							clocks = <&main_pll>;
 							reg = <0x54>;
 						};
 
-						main_nand_sdmmc_clk: main_nand_sdmmc_clk {
+						main_nand_sdmmc_clk: main_nand_sdmmc_clk@58 {
 							#clock-cells = <0>;
 							compatible = "altr,socfpga-perip-clk";
 							clocks = <&main_pll>;
 							reg = <0x58>;
 						};
 
-						cfg_h2f_usr0_clk: cfg_h2f_usr0_clk {
+						cfg_h2f_usr0_clk: cfg_h2f_usr0_clk@5c {
 							#clock-cells = <0>;
 							compatible = "altr,socfpga-perip-clk";
 							clocks = <&main_pll>;
@@ -185,7 +193,7 @@
 						};
 					};
 
-					periph_pll: periph_pll {
+					periph_pll: periph_pll@80 {
 						#address-cells = <1>;
 						#size-cells = <0>;
 						#clock-cells = <0>;
@@ -193,42 +201,42 @@
 						clocks = <&osc1>, <&osc2>, <&f2s_periph_ref_clk>;
 						reg = <0x80>;
 
-						emac0_clk: emac0_clk {
+						emac0_clk: emac0_clk@88 {
 							#clock-cells = <0>;
 							compatible = "altr,socfpga-perip-clk";
 							clocks = <&periph_pll>;
 							reg = <0x88>;
 						};
 
-						emac1_clk: emac1_clk {
+						emac1_clk: emac1_clk@8c {
 							#clock-cells = <0>;
 							compatible = "altr,socfpga-perip-clk";
 							clocks = <&periph_pll>;
 							reg = <0x8C>;
 						};
 
-						per_qspi_clk: per_qsi_clk {
+						per_qspi_clk: per_qsi_clk@90 {
 							#clock-cells = <0>;
 							compatible = "altr,socfpga-perip-clk";
 							clocks = <&periph_pll>;
 							reg = <0x90>;
 						};
 
-						per_nand_mmc_clk: per_nand_mmc_clk {
+						per_nand_mmc_clk: per_nand_mmc_clk@94 {
 							#clock-cells = <0>;
 							compatible = "altr,socfpga-perip-clk";
 							clocks = <&periph_pll>;
 							reg = <0x94>;
 						};
 
-						per_base_clk: per_base_clk {
+						per_base_clk: per_base_clk@98 {
 							#clock-cells = <0>;
 							compatible = "altr,socfpga-perip-clk";
 							clocks = <&periph_pll>;
 							reg = <0x98>;
 						};
 
-						h2f_usr1_clk: h2f_usr1_clk {
+						h2f_usr1_clk: h2f_usr1_clk@9c {
 							#clock-cells = <0>;
 							compatible = "altr,socfpga-perip-clk";
 							clocks = <&periph_pll>;
@@ -236,7 +244,7 @@
 						};
 					};
 
-					sdram_pll: sdram_pll {
+					sdram_pll: sdram_pll@c0 {
 						#address-cells = <1>;
 						#size-cells = <0>;
 						#clock-cells = <0>;
@@ -244,28 +252,28 @@
 						clocks = <&osc1>, <&osc2>, <&f2s_sdram_ref_clk>;
 						reg = <0xC0>;
 
-						ddr_dqs_clk: ddr_dqs_clk {
+						ddr_dqs_clk: ddr_dqs_clk@c8 {
 							#clock-cells = <0>;
 							compatible = "altr,socfpga-perip-clk";
 							clocks = <&sdram_pll>;
 							reg = <0xC8>;
 						};
 
-						ddr_2x_dqs_clk: ddr_2x_dqs_clk {
+						ddr_2x_dqs_clk: ddr_2x_dqs_clk@cc {
 							#clock-cells = <0>;
 							compatible = "altr,socfpga-perip-clk";
 							clocks = <&sdram_pll>;
 							reg = <0xCC>;
 						};
 
-						ddr_dq_clk: ddr_dq_clk {
+						ddr_dq_clk: ddr_dq_clk@d0 {
 							#clock-cells = <0>;
 							compatible = "altr,socfpga-perip-clk";
 							clocks = <&sdram_pll>;
 							reg = <0xD0>;
 						};
 
-						h2f_usr2_clk: h2f_usr2_clk {
+						h2f_usr2_clk: h2f_usr2_clk@d4 {
 							#clock-cells = <0>;
 							compatible = "altr,socfpga-perip-clk";
 							clocks = <&sdram_pll>;
@@ -312,7 +320,7 @@
 					l3_sp_clk: l3_sp_clk {
 						#clock-cells = <0>;
 						compatible = "altr,socfpga-gate-clk";
-						clocks = <&mainclk>;
+						clocks = <&l3_mp_clk>;
 						div-reg = <0x64 2 2>;
 					};
 
@@ -343,7 +351,7 @@
 					dbg_clk: dbg_clk {
 						#clock-cells = <0>;
 						compatible = "altr,socfpga-gate-clk";
-						clocks = <&dbg_base_clk>;
+						clocks = <&dbg_at_clk>;
 						div-reg = <0x68 2 2>;
 						clk-gate = <0x60 5>;
 					};
@@ -446,6 +454,14 @@
 						clk-phase = <0 135>;
 					};
 
+					sdmmc_clk_divided: sdmmc_clk_divided {
+						#clock-cells = <0>;
+						compatible = "altr,socfpga-gate-clk";
+						clocks = <&sdmmc_clk>;
+						clk-gate = <0xa0 8>;
+						fixed-divider = <4>;
+					};
+
 					nand_x_clk: nand_x_clk {
 						#clock-cells = <0>;
 						compatible = "altr,socfpga-gate-clk";
@@ -453,10 +469,17 @@
 						clk-gate = <0xa0 9>;
 					};
 
+					nand_ecc_clk: nand_ecc_clk {
+						#clock-cells = <0>;
+						compatible = "altr,socfpga-gate-clk";
+						clocks = <&nand_x_clk>;
+						clk-gate = <0xa0 9>;
+					};
+
 					nand_clk: nand_clk {
 						#clock-cells = <0>;
 						compatible = "altr,socfpga-gate-clk";
-						clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>;
+						clocks = <&nand_x_clk>;
 						clk-gate = <0xa0 10>;
 						fixed-divider = <4>;
 					};
@@ -467,8 +490,58 @@
 						clocks = <&f2s_periph_ref_clk>, <&main_qspi_clk>, <&per_qspi_clk>;
 						clk-gate = <0xa0 11>;
 					};
+
+					ddr_dqs_clk_gate: ddr_dqs_clk_gate {
+						#clock-cells = <0>;
+						compatible = "altr,socfpga-gate-clk";
+						clocks = <&ddr_dqs_clk>;
+						clk-gate = <0xd8 0>;
+					};
+
+					ddr_2x_dqs_clk_gate: ddr_2x_dqs_clk_gate {
+						#clock-cells = <0>;
+						compatible = "altr,socfpga-gate-clk";
+						clocks = <&ddr_2x_dqs_clk>;
+						clk-gate = <0xd8 1>;
+					};
+
+					ddr_dq_clk_gate: ddr_dq_clk_gate {
+						#clock-cells = <0>;
+						compatible = "altr,socfpga-gate-clk";
+						clocks = <&ddr_dq_clk>;
+						clk-gate = <0xd8 2>;
+					};
+
+					h2f_user2_clk: h2f_user2_clk {
+						#clock-cells = <0>;
+						compatible = "altr,socfpga-gate-clk";
+						clocks = <&h2f_usr2_clk>;
+						clk-gate = <0xd8 3>;
+					};
+
 				};
-			};
+		};
+
+		fpga_bridge0: fpga_bridge@ff400000 {
+			compatible = "altr,socfpga-lwhps2fpga-bridge";
+			reg = <0xff400000 0x100000>;
+			resets = <&rst LWHPS2FPGA_RESET>;
+			clocks = <&l4_main_clk>;
+		};
+
+		fpga_bridge1: fpga_bridge@ff500000 {
+			compatible = "altr,socfpga-hps2fpga-bridge";
+			reg = <0xff500000 0x10000>;
+			resets = <&rst HPS2FPGA_RESET>;
+			clocks = <&l4_main_clk>;
+		};
+
+		fpgamgr0: fpgamgr@ff706000 {
+			compatible = "altr,socfpga-fpga-mgr";
+			reg = <0xff706000 0x1000
+			       0xffb90000 0x4>;
+			interrupts = <0 175 4>;
+		};
 
 		gmac0: ethernet@ff700000 {
 			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac";
@@ -477,12 +550,14 @@
 			interrupts = <0 115 4>;
 			interrupt-names = "macirq";
 			mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */
-			clocks = <&emac0_clk>;
+			clocks = <&emac_0_clk>;
 			clock-names = "stmmaceth";
 			resets = <&rst EMAC0_RESET>;
 			reset-names = "stmmaceth";
 			snps,multicast-filter-bins = <256>;
 			snps,perfect-filter-entries = <128>;
+			tx-fifo-depth = <4096>;
+			rx-fifo-depth = <4096>;
 			status = "disabled";
 		};
 
@@ -493,60 +568,14 @@
 			interrupts = <0 120 4>;
 			interrupt-names = "macirq";
 			mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */
-			clocks = <&emac1_clk>;
+			clocks = <&emac_1_clk>;
 			clock-names = "stmmaceth";
 			resets = <&rst EMAC1_RESET>;
 			reset-names = "stmmaceth";
 			snps,multicast-filter-bins = <256>;
 			snps,perfect-filter-entries = <128>;
-			status = "disabled";
-		};
-
-		i2c0: i2c@ffc04000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "snps,designware-i2c";
-			reg = <0xffc04000 0x1000>;
-			clocks = <&l4_sp_clk>;
-			resets = <&rst I2C0_RESET>;
-			reset-names = "i2c";
-			interrupts = <0 158 0x4>;
-			status = "disabled";
-		};
-
-		i2c1: i2c@ffc05000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "snps,designware-i2c";
-			reg = <0xffc05000 0x1000>;
-			clocks = <&l4_sp_clk>;
-			resets = <&rst I2C1_RESET>;
-			reset-names = "i2c";
-			interrupts = <0 159 0x4>;
-			status = "disabled";
-		};
-
-		i2c2: i2c@ffc06000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "snps,designware-i2c";
-			reg = <0xffc06000 0x1000>;
-			clocks = <&l4_sp_clk>;
-			resets = <&rst I2C2_RESET>;
-			reset-names = "i2c";
-			interrupts = <0 160 0x4>;
-			status = "disabled";
-		};
-
-		i2c3: i2c@ffc07000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "snps,designware-i2c";
-			reg = <0xffc07000 0x1000>;
-			clocks = <&l4_sp_clk>;
-			resets = <&rst I2C3_RESET>;
-			reset-names = "i2c";
-			interrupts = <0 161 0x4>;
+			tx-fifo-depth = <4096>;
+			rx-fifo-depth = <4096>;
 			status = "disabled";
 		};
 
@@ -555,12 +584,11 @@
 			#size-cells = <0>;
 			compatible = "snps,dw-apb-gpio";
 			reg = <0xff708000 0x1000>;
-			clocks = <&per_base_clk>;
+			clocks = <&l4_mp_clk>;
 			status = "disabled";
 
 			porta: gpio-controller@0 {
 				compatible = "snps,dw-apb-gpio-port";
-				bank-name = "porta";
 				gpio-controller;
 				#gpio-cells = <2>;
 				snps,nr-gpios = <29>;
@@ -576,12 +604,11 @@
 			#size-cells = <0>;
 			compatible = "snps,dw-apb-gpio";
 			reg = <0xff709000 0x1000>;
-			clocks = <&per_base_clk>;
+			clocks = <&l4_mp_clk>;
 			status = "disabled";
 
 			portb: gpio-controller@0 {
 				compatible = "snps,dw-apb-gpio-port";
-				bank-name = "portb";
 				gpio-controller;
 				#gpio-cells = <2>;
 				snps,nr-gpios = <29>;
@@ -597,12 +624,11 @@
 			#size-cells = <0>;
 			compatible = "snps,dw-apb-gpio";
 			reg = <0xff70a000 0x1000>;
-			clocks = <&per_base_clk>;
+			clocks = <&l4_mp_clk>;
 			status = "disabled";
 
 			portc: gpio-controller@0 {
 				compatible = "snps,dw-apb-gpio-port";
-				bank-name = "portc";
 				gpio-controller;
 				#gpio-cells = <2>;
 				snps,nr-gpios = <27>;
@@ -613,17 +639,70 @@
 			};
 		};
 
-		sdr: sdr@ffc25000 {
-			compatible = "syscon";
-			reg = <0xffc25000 0x1000>;
+		i2c0: i2c@ffc04000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc04000 0x1000>;
+			resets = <&rst I2C0_RESET>;
+			clocks = <&l4_sp_clk>;
+			interrupts = <0 158 0x4>;
+			status = "disabled";
 		};
 
-		sdramedac {
-			compatible = "altr,sdram-edac";
-			altr,sdr-syscon = <&sdr>;
-			interrupts = <0 39 4>;
+		i2c1: i2c@ffc05000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc05000 0x1000>;
+			resets = <&rst I2C1_RESET>;
+			clocks = <&l4_sp_clk>;
+			interrupts = <0 159 0x4>;
+			status = "disabled";
+		};
+
+		i2c2: i2c@ffc06000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc06000 0x1000>;
+			resets = <&rst I2C2_RESET>;
+			clocks = <&l4_sp_clk>;
+			interrupts = <0 160 0x4>;
+			status = "disabled";
+		};
+
+		i2c3: i2c@ffc07000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc07000 0x1000>;
+			resets = <&rst I2C3_RESET>;
+			clocks = <&l4_sp_clk>;
+			interrupts = <0 161 0x4>;
+			status = "disabled";
 		};
 
+		eccmgr: eccmgr {
+			compatible = "altr,socfpga-ecc-manager";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			l2-ecc@ffd08140 {
+				compatible = "altr,socfpga-l2-ecc";
+				reg = <0xffd08140 0x4>;
+				interrupts = <0 36 1>, <0 37 1>;
+			};
+
+			ocram-ecc@ffd08144 {
+				compatible = "altr,socfpga-ocram-ecc";
+				reg = <0xffd08144 0x4>;
+				iram = <&ocram>;
+				interrupts = <0 178 1>, <0 179 1>;
+			};
+		};
+
 		L2: l2-cache@fffef000 {
 			compatible = "arm,pl310-cache";
 			reg = <0xfffef000 0x1000>;
@@ -632,36 +711,89 @@
 			cache-level = <2>;
 			arm,tag-latency = <1 1 1>;
 			arm,data-latency = <2 1 1>;
+			prefetch-data = <1>;
+			prefetch-instr = <1>;
+			arm,shared-override;
+			arm,double-linefill = <1>;
+			arm,double-linefill-incr = <0>;
+			arm,double-linefill-wrap = <1>;
+			arm,prefetch-drop = <0>;
+			arm,prefetch-offset = <7>;
+		};
+
+		l3regs@0xff800000 {
+			compatible = "altr,l3regs", "syscon";
+			reg = <0xff800000 0x1000>;
 		};
 
-		mmc0: dwmmc0@ff704000 {
+		mmc: dwmmc0@ff704000 {
 			compatible = "altr,socfpga-dw-mshc";
 			reg = <0xff704000 0x1000>;
 			interrupts = <0 139 4>;
 			fifo-depth = <0x400>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			clocks = <&l4_mp_clk>, <&sdmmc_clk>;
+			clocks = <&l4_mp_clk>, <&sdmmc_clk_divided>;
 			clock-names = "biu", "ciu";
+			status = "disabled";
+		};
+
+		nand0: nand@ff900000 {
+			#address-cells = <0x1>;
+			#size-cells = <0x1>;
+			compatible = "altr,socfpga-denali-nand";
+			reg = <0xff900000 0x100000>,
+			      <0xffb80000 0x10000>;
+			reg-names = "nand_data", "denali_reg";
+			interrupts = <0x0 0x90 0x4>;
+			dma-mask = <0xffffffff>;
+			clocks = <&nand_clk>, <&nand_x_clk>, <&nand_ecc_clk>;
+			clock-names = "nand", "nand_x", "ecc";
+			status = "disabled";
+		};
+
+		ocram: sram@ffff0000 {
+			compatible = "mmio-sram";
+			reg = <0xffff0000 0x10000>;
 		};
 
 		qspi: spi@ff705000 {
-			compatible = "cadence,qspi";
-			#address-cells = <1>;
+			compatible = "cdns,qspi-nor";
+                        #address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0xff705000 0x1000>,
-				<0xffa00000 0x1000>;
+			      <0xffa00000 0x1000>;
 			interrupts = <0 151 4>;
-			clocks = <&qspi_clk>;
-			ext-decoder = <0>;  /* external decoder */
-			num-cs = <4>;
 			cdns,fifo-depth = <128>;
 			cdns,fifo-width = <4>;
 			cdns,trigger-address = <0x00000000>;
-			bus-num = <2>;
+			clocks = <&qspi_clk>;
 			status = "disabled";
 		};
 
+		rst: rstmgr@ffd05000 {
+			#reset-cells = <1>;
+			compatible = "altr,rst-mgr";
+			reg = <0xffd05000 0x1000>;
+			altr,modrst-offset = <0x10>;
+		};
+
+		scu: snoop-control-unit@fffec000 {
+			compatible = "arm,cortex-a9-scu";
+			reg = <0xfffec000 0x100>;
+		};
+
+		sdr: sdr@ffc25000 {
+			compatible = "altr,sdr-ctl", "syscon";
+			reg = <0xffc25000 0x1000>;
+		};
+
+		sdramedac {
+			compatible = "altr,sdram-edac";
+			altr,sdr-syscon = <&sdr>;
+			interrupts = <0 39 4>;
+		};
+
 		spi0: spi@fff00000 {
 			compatible = "snps,dw-apb-ssi";
 			#address-cells = <1>;
@@ -669,10 +801,7 @@
 			reg = <0xfff00000 0x1000>;
 			interrupts = <0 154 4>;
 			num-cs = <4>;
-			bus-num = <0>;
-			tx-dma-channel = <&pdma 16>;
-			rx-dma-channel = <&pdma 17>;
-			clocks = <&per_base_clk>;
+			clocks = <&spi_m_clk>;
 			status = "disabled";
 		};
 
@@ -681,20 +810,22 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0xfff01000 0x1000>;
-			interrupts = <0 156 4>;
+			interrupts = <0 155 4>;
 			num-cs = <4>;
-			bus-num = <1>;
-			tx-dma-channel = <&pdma 20>;
-			rx-dma-channel = <&pdma 21>;
-			clocks = <&per_base_clk>;
+			clocks = <&spi_m_clk>;
 			status = "disabled";
 		};
 
+		sysmgr: sysmgr@ffd08000 {
+			compatible = "altr,sys-mgr", "syscon";
+			reg = <0xffd08000 0x4000>;
+		};
+
 		/* Local timer */
 		timer@fffec600 {
 			compatible = "arm,cortex-a9-twd-timer";
 			reg = <0xfffec600 0x100>;
-			interrupts = <1 13 0xf04>;
+			interrupts = <1 13 0xf01>;
 			clocks = <&mpu_periph_clk>;
 		};
 
@@ -704,6 +835,8 @@
 			reg = <0xffc08000 0x1000>;
 			clocks = <&l4_sp_clk>;
 			clock-names = "timer";
+			resets = <&rst SPTIMER0_RESET>;
+			reset-names = "timer";
 		};
 
 		timer1: timer1@ffc09000 {
@@ -712,6 +845,8 @@
 			reg = <0xffc09000 0x1000>;
 			clocks = <&l4_sp_clk>;
 			clock-names = "timer";
+			resets = <&rst SPTIMER1_RESET>;
+			reset-names = "timer";
 		};
 
 		timer2: timer2@ffd00000 {
@@ -720,6 +855,8 @@
 			reg = <0xffd00000 0x1000>;
 			clocks = <&osc1>;
 			clock-names = "timer";
+			resets = <&rst OSC1TIMER0_RESET>;
+			reset-names = "timer";
 		};
 
 		timer3: timer3@ffd01000 {
@@ -728,6 +865,8 @@
 			reg = <0xffd01000 0x1000>;
 			clocks = <&osc1>;
 			clock-names = "timer";
+			resets = <&rst OSC1TIMER1_RESET>;
+			reset-names = "timer";
 		};
 
 		uart0: serial0@ffc02000 {
@@ -737,7 +876,9 @@
 			reg-shift = <2>;
 			reg-io-width = <4>;
 			clocks = <&l4_sp_clk>;
-			clock-frequency = <100000000>;
+			dmas = <&pdma 28>,
+			       <&pdma 29>;
+			dma-names = "tx", "rx";
 		};
 
 		uart1: serial1@ffc03000 {
@@ -747,16 +888,12 @@
 			reg-shift = <2>;
 			reg-io-width = <4>;
 			clocks = <&l4_sp_clk>;
-			clock-frequency = <100000000>;
+			dmas = <&pdma 30>,
+			       <&pdma 31>;
+			dma-names = "tx", "rx";
 		};
 
-		rst: rstmgr@ffd05000 {
-			#reset-cells = <1>;
-			compatible = "altr,rst-mgr";
-			reg = <0xffd05000 0x1000>;
-		};
-
-		usbphy0: usbphy@0 {
+		usbphy0: usbphy {
 			#phy-cells = <0>;
 			compatible = "usb-nop-xceiv";
 			status = "okay";
@@ -768,6 +905,8 @@
 			interrupts = <0 125 4>;
 			clocks = <&usb_mp_clk>;
 			clock-names = "otg";
+			resets = <&rst USB0_RESET>;
+			reset-names = "dwc2";
 			phys = <&usbphy0>;
 			phy-names = "usb2-phy";
 			status = "disabled";
@@ -779,6 +918,8 @@
 			interrupts = <0 128 4>;
 			clocks = <&usb_mp_clk>;
 			clock-names = "otg";
+			resets = <&rst USB1_RESET>;
+			reset-names = "dwc2";
 			phys = <&usbphy0>;
 			phy-names = "usb2-phy";
 			status = "disabled";
@@ -799,10 +940,5 @@
 			clocks = <&osc1>;
 			status = "disabled";
 		};
-
-		sysmgr: sysmgr@ffd08000 {
-			compatible = "altr,sys-mgr", "syscon";
-			reg = <0xffd08000 0x4000>;
-		};
 	};
 };
diff --git a/arch/arm/dts/socfpga_arria10.dtsi b/arch/arm/dts/socfpga_arria10.dtsi
index 46f2fd4..2c5249c 100644
--- a/arch/arm/dts/socfpga_arria10.dtsi
+++ b/arch/arm/dts/socfpga_arria10.dtsi
@@ -748,7 +748,7 @@
 		};
 
 		qspi: spi@ff809000 {
-			compatible = "cdns,qspi-nor", "cadence,qspi";
+			compatible = "cdns,qspi-nor";
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0xff809000 0x100>,
diff --git a/arch/arm/dts/socfpga_arria5.dtsi b/arch/arm/dts/socfpga_arria5.dtsi
index b117383..22dbf07 100644
--- a/arch/arm/dts/socfpga_arria5.dtsi
+++ b/arch/arm/dts/socfpga_arria5.dtsi
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: GPL-2.0
 /*
- *  Copyright (C) 2013 Altera Corporation <www.altera.com>
+ * Copyright (C) 2013 Altera Corporation <www.altera.com>
  */
 
 /dts-v1/;
@@ -19,13 +19,10 @@
 		};
 
 		mmc0: dwmmc0@ff704000 {
-			num-slots = <1>;
 			broken-cd;
 			bus-width = <4>;
 			cap-mmc-highspeed;
 			cap-sd-highspeed;
-			drvsel = <3>;
-			smplsel = <0>;
 		};
 
 		sysmgr@ffd08000 {
@@ -33,3 +30,7 @@
 		};
 	};
 };
+
+&watchdog0 {
+	status = "okay";
+};
diff --git a/arch/arm/dts/socfpga_arria5_socdk-u-boot.dtsi b/arch/arm/dts/socfpga_arria5_socdk-u-boot.dtsi
new file mode 100644
index 0000000..c44d1ee
--- /dev/null
+++ b/arch/arm/dts/socfpga_arria5_socdk-u-boot.dtsi
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * U-Boot additions
+ *
+ * Copyright (C) 2013 Altera Corporation <www.altera.com>
+ * Copyright (c) 2018 Simon Goldschmidt
+ */
+
+/{
+	aliases {
+		spi0 = "/soc/spi@ff705000";
+		udc0 = &usb1;
+	};
+
+	soc {
+		u-boot,dm-pre-reloc;
+	};
+};
+
+&watchdog0 {
+	status = "disabled";
+};
+
+&mmc {
+	u-boot,dm-pre-reloc;
+};
+
+&qspi {
+	u-boot,dm-pre-reloc;
+};
+
+&flash {
+	compatible = "n25q00", "spi-flash";
+	u-boot,dm-pre-reloc;
+};
+
+&uart0 {
+	clock-frequency = <100000000>;
+	u-boot,dm-pre-reloc;
+};
+
+&uart1 {
+	clock-frequency = <100000000>;
+};
+
+&porta {
+	bank-name = "porta";
+};
+
+&portb {
+	bank-name = "portb";
+};
+
+&portc {
+	bank-name = "portc";
+};
diff --git a/arch/arm/dts/socfpga_arria5_socdk.dts b/arch/arm/dts/socfpga_arria5_socdk.dts
index 6f4de2f..90e676e 100644
--- a/arch/arm/dts/socfpga_arria5_socdk.dts
+++ b/arch/arm/dts/socfpga_arria5_socdk.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- *  Copyright (C) 2013 Altera Corporation <www.altera.com>
+ * Copyright (C) 2013 Altera Corporation <www.altera.com>
  */
 
 #include "socfpga_arria5.dtsi"
@@ -10,34 +10,52 @@
 	compatible = "altr,socfpga-arria5", "altr,socfpga";
 
 	chosen {
-		bootargs = "console=ttyS0,115200";
+		bootargs = "earlyprintk";
 		stdout-path = "serial0:115200n8";
 	};
 
-	memory {
+	memory@0 {
 		name = "memory";
 		device_type = "memory";
 		reg = <0x0 0x40000000>; /* 1GB */
 	};
 
 	aliases {
-		/* this allow the ethaddr uboot environment variable contents
-		 * to be added to the gmac1 device tree blob.
-		 */
+		/* this allow the ethaddr uboot environmnet variable contents
+		* to be added to the gmac1 device tree blob.
+		*/
 		ethernet0 = &gmac1;
-		udc0 = &usb1;
 	};
 
+	leds {
+		compatible = "gpio-leds";
+		hps0 {
+			label = "hps_led0";
+			gpios = <&porta 0 1>;
+		};
+
+		hps1 {
+			label = "hps_led1";
+			gpios = <&portb 11 1>;
+		};
+
+		hps2 {
+			label = "hps_led2";
+			gpios = <&porta 17 1>;
+		};
+
+		hps3 {
+			label = "hps_led3";
+			gpios = <&porta 18 1>;
+		};
+	};
+
 	regulator_3_3v: 3-3-v-regulator {
 		compatible = "regulator-fixed";
 		regulator-name = "3.3V";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 	};
-
-	soc {
-		u-boot,dm-pre-reloc;
-	};
 };
 
 &gmac1 {
@@ -54,8 +72,28 @@
 	rxc-skew-ps = <2000>;
 };
 
+&gpio0 {
+	status = "okay";
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
 &i2c0 {
 	status = "okay";
+	clock-frequency = <100000>;
+
+	/*
+	 * adjust the falling times to decrease the i2c frequency to 50Khz
+	 * because the LCD module does not work at the standard 100Khz
+	 */
+	i2c-sda-falling-time-ns = <5000>;
+	i2c-scl-falling-time-ns = <5000>;
 
 	eeprom@51 {
 		compatible = "atmel,24c32";
@@ -72,35 +110,42 @@
 &mmc0 {
 	vmmc-supply = <&regulator_3_3v>;
 	vqmmc-supply = <&regulator_3_3v>;
-	bus-width = <4>;
-	u-boot,dm-pre-reloc;
-};
-
-&usb1 {
 	status = "okay";
 };
 
 &qspi {
 	status = "okay";
-	u-boot,dm-pre-reloc;
 
-	flash0: n25q00@0 {
-		u-boot,dm-pre-reloc;
+	flash: flash@0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "n25q00", "spi-flash";
-		reg = <0>;      /* chip select */
-		spi-max-frequency = <50000000>;
+		compatible = "n25q256a";
+		reg = <0>;
+		spi-max-frequency = <100000000>;
+
 		m25p,fast-read;
-		page-size = <256>;
-		block-size = <16>; /* 2^16, 64KB */
+		cdns,page-size = <256>;
+		cdns,block-size = <16>;
+		cdns,read-delay = <4>;
 		cdns,tshsl-ns = <50>;
 		cdns,tsd2d-ns = <50>;
 		cdns,tchsh-ns = <4>;
 		cdns,tslch-ns = <4>;
+
+		partition@qspi-boot {
+			/* 8MB for raw data. */
+			label = "Flash 0 Raw Data";
+			reg = <0x0 0x800000>;
+		};
+
+		partition@qspi-rootfs {
+			/* 120MB for jffs2 data. */
+			label = "Flash 0 jffs2 Filesystem";
+			reg = <0x800000 0x7800000>;
+		};
 	};
 };
 
-&uart0 {
-	u-boot,dm-pre-reloc;
+&usb1 {
+	status = "okay";
 };
diff --git a/arch/arm/dts/socfpga_cyclone5.dtsi b/arch/arm/dts/socfpga_cyclone5.dtsi
index 8f356cb..319a71e 100644
--- a/arch/arm/dts/socfpga_cyclone5.dtsi
+++ b/arch/arm/dts/socfpga_cyclone5.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- *  Copyright (C) 2012 Altera Corporation <www.altera.com>
+ * Copyright (C) 2012 Altera Corporation <www.altera.com>
  */
 
 /dts-v1/;
@@ -19,13 +19,10 @@
 		};
 
 		mmc0: dwmmc0@ff704000 {
-			num-slots = <1>;
 			broken-cd;
 			bus-width = <4>;
 			cap-mmc-highspeed;
 			cap-sd-highspeed;
-			drvsel = <3>;
-			smplsel = <0>;
 		};
 
 		sysmgr@ffd08000 {
@@ -33,3 +30,7 @@
 		};
 	};
 };
+
+&watchdog0 {
+	status = "okay";
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_dbm_soc1.dts b/arch/arm/dts/socfpga_cyclone5_dbm_soc1.dts
index 139a70f..a387071 100644
--- a/arch/arm/dts/socfpga_cyclone5_dbm_soc1.dts
+++ b/arch/arm/dts/socfpga_cyclone5_dbm_soc1.dts
@@ -47,9 +47,20 @@
 	status = "okay";
 };
 
+&porta {
+	bank-name = "porta";
+};
+
+&portb {
+	bank-name = "portb";
+};
+
+&portc {
+	bank-name = "portc";
+};
+
 &mmc0 {
 	status = "okay";
-	bus-width = <4>;
 	u-boot,dm-pre-reloc;
 };
 
@@ -61,3 +72,7 @@
 &uart0 {
 	u-boot,dm-pre-reloc;
 };
+
+&watchdog0 {
+	status = "disabled";
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_de0_nano_soc-u-boot.dtsi b/arch/arm/dts/socfpga_cyclone5_de0_nano_soc-u-boot.dtsi
new file mode 100644
index 0000000..08d81da
--- /dev/null
+++ b/arch/arm/dts/socfpga_cyclone5_de0_nano_soc-u-boot.dtsi
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * U-Boot additions
+ *
+ * Copyright Altera Corporation (C) 2015
+ * Copyright (c) 2018 Simon Goldschmidt
+ */
+
+/{
+	aliases {
+		udc0 = &usb1;
+	};
+
+	soc {
+		u-boot,dm-pre-reloc;
+	};
+};
+
+&watchdog0 {
+	status = "disabled";
+};
+
+&mmc {
+	u-boot,dm-pre-reloc;
+};
+
+&uart0 {
+	clock-frequency = <100000000>;
+	u-boot,dm-pre-reloc;
+};
+
+&uart1 {
+	clock-frequency = <100000000>;
+};
+
+&porta {
+	bank-name = "porta";
+};
+
+&portb {
+	bank-name = "portb";
+};
+
+&portc {
+	bank-name = "portc";
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_de0_nano_soc.dts b/arch/arm/dts/socfpga_cyclone5_de0_nano_soc.dts
index d504150..67076e1 100644
--- a/arch/arm/dts/socfpga_cyclone5_de0_nano_soc.dts
+++ b/arch/arm/dts/socfpga_cyclone5_de0_nano_soc.dts
@@ -1,32 +1,43 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright Altera Corporation (C) 2015
+ * Copyright Altera Corporation (C) 2015. All rights reserved.
  */
 
 #include "socfpga_cyclone5.dtsi"
 
 / {
-	model = "Terasic DE0-Nano(Atlas)";
-	compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+	model = "Terasic DE-0(Atlas)";
+	compatible = "terasic,de0-atlas", "altr,socfpga-cyclone5", "altr,socfpga";
 
 	chosen {
-		bootargs = "console=ttyS0,115200";
+		bootargs = "earlyprintk";
 		stdout-path = "serial0:115200n8";
 	};
 
+	memory@0 {
+		name = "memory";
+		device_type = "memory";
+		reg = <0x0 0x40000000>; /* 1GB */
+	};
+
 	aliases {
 		ethernet0 = &gmac1;
-		udc0 = &usb1;
 	};
 
-	memory {
-		name = "memory";
-		device_type = "memory";
-		reg = <0x0 0x40000000>; /* 1GB */
+	regulator_3_3v: 3-3-v-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
 	};
 
-	soc {
-		u-boot,dm-pre-reloc;
+	leds {
+		compatible = "gpio-leds";
+		hps0 {
+			label = "hps_led0";
+			gpios = <&portb 24 0>;
+			linux,default-trigger = "heartbeat";
+		};
 	};
 };
 
@@ -34,14 +45,20 @@
 	status = "okay";
 	phy-mode = "rgmii";
 
+	txd0-skew-ps = <0>; /* -420ps */
+	txd1-skew-ps = <0>; /* -420ps */
+	txd2-skew-ps = <0>; /* -420ps */
+	txd3-skew-ps = <0>; /* -420ps */
+	rxd0-skew-ps = <420>; /* 0ps */
+	rxd1-skew-ps = <420>; /* 0ps */
+	rxd2-skew-ps = <420>; /* 0ps */
+	rxd3-skew-ps = <420>; /* 0ps */
+	txen-skew-ps = <0>; /* -420ps */
+	txc-skew-ps = <1860>; /* 960ps */
+	rxdv-skew-ps = <420>; /* 0ps */
+	rxc-skew-ps = <1680>; /* 780ps */
+
-	rxd0-skew-ps = <420>;
-	rxd1-skew-ps = <420>;
-	rxd2-skew-ps = <420>;
-	rxd3-skew-ps = <420>;
-	txen-skew-ps = <0>;
-	txc-skew-ps = <1860>;
-	rxdv-skew-ps = <420>;
-	rxc-skew-ps = <1680>;
+	max-frame-size = <3800>;
 };
 
 &gpio0 {
@@ -58,8 +75,9 @@
 
 &i2c0 {
 	status = "okay";
+	clock-frequency = <100000>;
 
-	dxl345: adxl345@0 {
+	adxl345: adxl345@53 {
 		compatible = "adi,adxl345";
 		reg = <0x53>;
 
@@ -69,14 +87,15 @@
 };
 
 &mmc0 {
+	vmmc-supply = <&regulator_3_3v>;
+	vqmmc-supply = <&regulator_3_3v>;
 	status = "okay";
-	u-boot,dm-pre-reloc;
 };
 
-&usb1 {
+&uart0 {
 	status = "okay";
 };
 
-&uart0 {
-	u-boot,dm-pre-reloc;
+&usb1 {
+	status = "okay";
 };
diff --git a/arch/arm/dts/socfpga_cyclone5_de10_nano.dts b/arch/arm/dts/socfpga_cyclone5_de10_nano.dts
index d4dd9e9b..e910574 100644
--- a/arch/arm/dts/socfpga_cyclone5_de10_nano.dts
+++ b/arch/arm/dts/socfpga_cyclone5_de10_nano.dts
@@ -58,6 +58,18 @@
 	status = "okay";
 };
 
+&porta {
+	bank-name = "porta";
+};
+
+&portb {
+	bank-name = "portb";
+};
+
+&portc {
+	bank-name = "portc";
+};
+
 &mmc0 {
 	status = "okay";
 	u-boot,dm-pre-reloc;
@@ -70,3 +82,7 @@
 &uart0 {
 	u-boot,dm-pre-reloc;
 };
+
+&watchdog0 {
+	status = "disabled";
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_de1_soc.dts b/arch/arm/dts/socfpga_cyclone5_de1_soc.dts
index f622922..4f076bc 100644
--- a/arch/arm/dts/socfpga_cyclone5_de1_soc.dts
+++ b/arch/arm/dts/socfpga_cyclone5_de1_soc.dts
@@ -56,6 +56,18 @@
 	status = "okay";
 };
 
+&porta {
+	bank-name = "porta";
+};
+
+&portb {
+	bank-name = "portb";
+};
+
+&portc {
+	bank-name = "portc";
+};
+
 &mmc0 {
 	status = "okay";
 	u-boot,dm-pre-reloc;
@@ -68,3 +80,7 @@
 &uart0 {
 	u-boot,dm-pre-reloc;
 };
+
+&watchdog0 {
+	status = "disabled";
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_is1.dts b/arch/arm/dts/socfpga_cyclone5_is1.dts
index 4e94d86..b7054bf 100644
--- a/arch/arm/dts/socfpga_cyclone5_is1.dts
+++ b/arch/arm/dts/socfpga_cyclone5_is1.dts
@@ -55,6 +55,10 @@
 	status = "okay";
 };
 
+&porta {
+	bank-name = "porta";
+};
+
 &i2c0 {
 	status = "okay";
 
@@ -107,3 +111,7 @@
 &uart0 {
 	u-boot,dm-pre-reloc;
 };
+
+&watchdog0 {
+	status = "disabled";
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_socdk-u-boot.dtsi b/arch/arm/dts/socfpga_cyclone5_socdk-u-boot.dtsi
new file mode 100644
index 0000000..9436e0f
--- /dev/null
+++ b/arch/arm/dts/socfpga_cyclone5_socdk-u-boot.dtsi
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * U-Boot additions
+ *
+ * Copyright (C) 2012 Altera Corporation <www.altera.com>
+ * Copyright (c) 2018 Simon Goldschmidt
+ */
+
+/{
+	aliases {
+		spi0 = "/soc/spi@ff705000";
+		udc0 = &usb1;
+	};
+
+	soc {
+		u-boot,dm-pre-reloc;
+	};
+};
+
+&can0 {
+	status = "okay";
+};
+
+&watchdog0 {
+	status = "disabled";
+};
+
+&mmc {
+	u-boot,dm-pre-reloc;
+};
+
+&qspi {
+	u-boot,dm-pre-reloc;
+};
+
+&flash0 {
+	compatible = "n25q00", "spi-flash";
+	u-boot,dm-pre-reloc;
+
+	partition@qspi-boot {
+		/* 8MB for raw data. */
+		label = "Flash 0 Raw Data";
+		reg = <0x0 0x800000>;
+	};
+
+	partition@qspi-rootfs {
+		/* 120MB for jffs2 data. */
+		label = "Flash 0 jffs2 Filesystem";
+		reg = <0x800000 0x7800000>;
+	};
+};
+
+&uart0 {
+	clock-frequency = <100000000>;
+	u-boot,dm-pre-reloc;
+};
+
+&uart1 {
+	clock-frequency = <100000000>;
+};
+
+&porta {
+	bank-name = "porta";
+};
+
+&portb {
+	bank-name = "portb";
+};
+
+&portc {
+	bank-name = "portc";
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_socdk.dts b/arch/arm/dts/socfpga_cyclone5_socdk.dts
index c28be67..6f138b2 100644
--- a/arch/arm/dts/socfpga_cyclone5_socdk.dts
+++ b/arch/arm/dts/socfpga_cyclone5_socdk.dts
@@ -1,43 +1,65 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- *  Copyright (C) 2012 Altera Corporation <www.altera.com>
+ * Copyright (C) 2012 Altera Corporation <www.altera.com>
  */
 
 #include "socfpga_cyclone5.dtsi"
 
 / {
 	model = "Altera SOCFPGA Cyclone V SoC Development Kit";
-	compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+	compatible = "altr,socfpga-cyclone5-socdk", "altr,socfpga-cyclone5", "altr,socfpga";
 
 	chosen {
-		bootargs = "console=ttyS0,115200";
+		bootargs = "earlyprintk";
 		stdout-path = "serial0:115200n8";
 	};
 
-	memory {
+	memory@0 {
 		name = "memory";
 		device_type = "memory";
 		reg = <0x0 0x40000000>; /* 1GB */
 	};
 
 	aliases {
-		/* this allow the ethaddr uboot environment variable contents
+		/* this allow the ethaddr uboot environmnet variable contents
 		 * to be added to the gmac1 device tree blob.
 		 */
 		ethernet0 = &gmac1;
-		udc0 = &usb1;
 	};
 
+	leds {
+		compatible = "gpio-leds";
+		hps0 {
+			label = "hps_led0";
+			gpios = <&portb 15 1>;
+		};
+
+		hps1 {
+			label = "hps_led1";
+			gpios = <&portb 14 1>;
+		};
+
+		hps2 {
+			label = "hps_led2";
+			gpios = <&portb 13 1>;
+		};
+
+		hps3 {
+			label = "hps_led3";
+			gpios = <&portb 12 1>;
+		};
+	};
+
 	regulator_3_3v: 3-3-v-regulator {
 		compatible = "regulator-fixed";
 		regulator-name = "3.3V";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 	};
+};
 
-	soc {
-		u-boot,dm-pre-reloc;
-	};
+&can0 {
+	status = "okay";
 };
 
 &gmac1 {
@@ -68,6 +90,14 @@
 
 &i2c0 {
 	status = "okay";
+	clock-frequency = <100000>;
+
+	/*
+	 * adjust the falling times to decrease the i2c frequency to 50Khz
+	 * because the LCD module does not work at the standard 100Khz
+	 */
+	i2c-sda-falling-time-ns = <5000>;
+	i2c-scl-falling-time-ns = <5000>;
 
 	eeprom@51 {
 		compatible = "atmel,24c32";
@@ -82,39 +112,55 @@
 };
 
 &mmc0 {
-	status = "okay";
-	u-boot,dm-pre-reloc;
-
 	cd-gpios = <&portb 18 0>;
 	vmmc-supply = <&regulator_3_3v>;
 	vqmmc-supply = <&regulator_3_3v>;
+	status = "okay";
 };
 
 &qspi {
 	status = "okay";
-	u-boot,dm-pre-reloc;
 
 	flash0: n25q00@0 {
-		u-boot,dm-pre-reloc;
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "n25q00", "spi-flash";
-		reg = <0>;      /* chip select */
+		compatible = "n25q00";
+		reg = <0>;	/* chip select */
 		spi-max-frequency = <100000000>;
+
 		m25p,fast-read;
-		page-size = <256>;
-		block-size = <16>; /* 2^16, 64KB */
+		cdns,page-size = <256>;
+		cdns,block-size = <16>;
+		cdns,read-delay = <4>;
 		cdns,tshsl-ns = <50>;
 		cdns,tsd2d-ns = <50>;
 		cdns,tchsh-ns = <4>;
 		cdns,tslch-ns = <4>;
+
+		partition@qspi-boot {
+			/* 8MB for raw data. */
+			label = "Flash 0 Raw Data";
+			reg = <0x0 0x800000>;
+		};
+
+		partition@qspi-rootfs {
+			/* 120MB for jffs2 data. */
+			label = "Flash 0 jffs2 Filesystem";
+			reg = <0x800000 0x7800000>;
+		};
 	};
 };
 
-&usb1 {
+&spi0 {
 	status = "okay";
+
+	spidev@0 {
+		compatible = "rohm,dh2228fv";
+		reg = <0>;
+		spi-max-frequency = <1000000>;
+	};
 };
 
-&uart0 {
-	u-boot,dm-pre-reloc;
+&usb1 {
+	status = "okay";
 };
diff --git a/arch/arm/dts/socfpga_cyclone5_sockit-u-boot.dtsi b/arch/arm/dts/socfpga_cyclone5_sockit-u-boot.dtsi
new file mode 100644
index 0000000..648f1bd
--- /dev/null
+++ b/arch/arm/dts/socfpga_cyclone5_sockit-u-boot.dtsi
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * U-Boot additions
+ *
+ * Copyright (C) 2013 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ * Copyright (c) 2018 Simon Goldschmidt
+ */
+
+/{
+	aliases {
+		spi0 = "/soc/spi@ff705000";
+		udc0 = &usb1;
+	};
+
+	soc {
+		u-boot,dm-pre-reloc;
+	};
+};
+
+&watchdog0 {
+	status = "disabled";
+};
+
+&mmc {
+	u-boot,dm-pre-reloc;
+};
+
+&qspi {
+	u-boot,dm-pre-reloc;
+};
+
+&flash {
+	compatible = "n25q00", "spi-flash";
+	u-boot,dm-pre-reloc;
+};
+
+&uart0 {
+	clock-frequency = <100000000>;
+	u-boot,dm-pre-reloc;
+};
+
+&uart1 {
+	clock-frequency = <100000000>;
+};
+
+&porta {
+	bank-name = "porta";
+};
+
+&portb {
+	bank-name = "portb";
+};
+
+&portc {
+	bank-name = "portc";
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_sockit.dts b/arch/arm/dts/socfpga_cyclone5_sockit.dts
index c7a6cf2..c155ff0 100644
--- a/arch/arm/dts/socfpga_cyclone5_sockit.dts
+++ b/arch/arm/dts/socfpga_cyclone5_sockit.dts
@@ -1,32 +1,121 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- *  Copyright (C) 2014 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ * Copyright (C) 2013 Steffen Trumtrar <s.trumtrar@pengutronix.de>
  */
 
 #include "socfpga_cyclone5.dtsi"
 
 / {
 	model = "Terasic SoCkit";
-	compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+	compatible = "terasic,socfpga-cyclone5-sockit", "altr,socfpga-cyclone5", "altr,socfpga";
 
 	chosen {
-		bootargs = "console=ttyS0,115200";
+		bootargs = "earlyprintk";
 		stdout-path = "serial0:115200n8";
 	};
 
+	memory@0 {
+		name = "memory";
+		device_type = "memory";
+		reg = <0x0 0x40000000>; /* 1GB */
+	};
+
 	aliases {
+		/* this allow the ethaddr uboot environmnet variable contents
+		 * to be added to the gmac1 device tree blob.
+		 */
 		ethernet0 = &gmac1;
-		udc0 = &usb1;
 	};
 
-	memory {
-		name = "memory";
-		device_type = "memory";
-		reg = <0x0 0x40000000>; /* 1GB */
+	leds {
+		compatible = "gpio-leds";
+
+		hps_led0 {
+			label = "hps:blue:led0";
+			gpios = <&portb 24 0>;	/* HPS_GPIO53 */
+			linux,default-trigger = "heartbeat";
+		};
+
+		hps_led1 {
+			label = "hps:blue:led1";
+			gpios = <&portb 25 0>;	/* HPS_GPIO54 */
+			linux,default-trigger = "heartbeat";
+		};
+
+		hps_led2 {
+			label = "hps:blue:led2";
+			gpios = <&portb 26 0>;	/* HPS_GPIO55 */
+			linux,default-trigger = "heartbeat";
+		};
+
+		hps_led3 {
+			label = "hps:blue:led3";
+			gpios = <&portb 27 0>;	/* HPS_GPIO56 */
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		hps_sw0 {
+			label = "hps_sw0";
+			gpios = <&portc 20 0>;	/* HPS_GPI7 */
+			linux,input-type = <5>;	/* EV_SW */
+			linux,code = <0x0>;	/* SW_LID */
+		};
+
+		hps_sw1 {
+			label = "hps_sw1";
+			gpios = <&portc 19 0>;	/* HPS_GPI6 */
+			linux,input-type = <5>;	/* EV_SW */
+			linux,code = <0x5>;	/* SW_DOCK */
+		};
+
+		hps_sw2 {
+			label = "hps_sw2";
+			gpios = <&portc 18 0>;	/* HPS_GPI5 */
+			linux,input-type = <5>;	/* EV_SW */
+			linux,code = <0xa>;	/* SW_KEYPAD_SLIDE */
+		};
+
+		hps_sw3 {
+			label = "hps_sw3";
+			gpios = <&portc 17 0>;	/* HPS_GPI4 */
+			linux,input-type = <5>;	/* EV_SW */
+			linux,code = <0xc>;	/* SW_ROTATE_LOCK */
+		};
+
+		hps_hkey0 {
+			label = "hps_hkey0";
+			gpios = <&portc 21 1>;	/* HPS_GPI8 */
+			linux,code = <187>;	/* KEY_F17 */
+		};
+
+		hps_hkey1 {
+			label = "hps_hkey1";
+			gpios = <&portc 22 1>;	/* HPS_GPI9 */
+			linux,code = <188>;	/* KEY_F18 */
+		};
+
+		hps_hkey2 {
+			label = "hps_hkey2";
+			gpios = <&portc 23 1>;	/* HPS_GPI10 */
+			linux,code = <189>;	/* KEY_F19 */
+		};
+
+		hps_hkey3 {
+			label = "hps_hkey3";
+			gpios = <&portc 24 1>;	/* HPS_GPI11 */
+			linux,code = <190>;	/* KEY_F20 */
+		};
 	};
 
-	soc {
-		u-boot,dm-pre-reloc;
+	regulator_3_3v: vcc3p3-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC3P3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
 	};
 };
 
@@ -44,46 +133,50 @@
 	rxc-skew-ps = <2000>;
 };
 
-&gpio0 {
+&gpio0 {	/* GPIO 0..29 */
 	status = "okay";
 };
 
-&gpio1 {
+&gpio1 {	/* GPIO 30..57 */
 	status = "okay";
 };
 
-&gpio2 {
+&gpio2 {	/* GPIO 58..66 (HLGPI 0..13 at offset 13) */
 	status = "okay";
 };
 
-&i2c0 {
+&i2c1 {
 	status = "okay";
 
+	accel1: accelerometer@53 {
+		compatible = "adi,adxl345";
+		reg = <0x53>;
+
-	rtc: rtc@68 {
-		compatible = "stm,m41t82";
-		reg = <0x68>;
+		interrupt-parent = <&portc>;
+		interrupts = <3 2>;
 	};
 };
 
 &mmc0 {
+	vmmc-supply = <&regulator_3_3v>;
+	vqmmc-supply = <&regulator_3_3v>;
 	status = "okay";
-	u-boot,dm-pre-reloc;
 };
 
 &qspi {
 	status = "okay";
-	u-boot,dm-pre-reloc;
 
-	flash0: n25q00@0 {
-		u-boot,dm-pre-reloc;
+	flash: flash@0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "n25q00", "spi-flash";
-		reg = <0>;      /* chip select */
-		spi-max-frequency = <50000000>;
+		compatible = "n25q00";
+		reg = <0>;
+		spi-max-frequency = <100000000>;
+
 		m25p,fast-read;
-		page-size = <256>;
-		block-size = <16>; /* 2^16, 64KB */
+		cdns,page-size = <256>;
+		cdns,block-size = <16>;
+		cdns,read-delay = <4>;
 		cdns,tshsl-ns = <50>;
 		cdns,tsd2d-ns = <50>;
 		cdns,tchsh-ns = <4>;
@@ -94,7 +187,3 @@
 &usb1 {
 	status = "okay";
 };
-
-&uart0 {
-	u-boot,dm-pre-reloc;
-};
diff --git a/arch/arm/dts/socfpga_cyclone5_socrates-u-boot.dtsi b/arch/arm/dts/socfpga_cyclone5_socrates-u-boot.dtsi
new file mode 100644
index 0000000..31bd1db
--- /dev/null
+++ b/arch/arm/dts/socfpga_cyclone5_socrates-u-boot.dtsi
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * U-Boot additions
+ *
+ * Copyright (C) 2014 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ * Copyright (c) 2018 Simon Goldschmidt
+ */
+
+/{
+	aliases {
+		spi0 = "/soc/spi@ff705000";
+		udc0 = &usb1;
+	};
+
+	soc {
+		u-boot,dm-pre-reloc;
+	};
+};
+
+&watchdog0 {
+	status = "disabled";
+};
+
+&mmc {
+	u-boot,dm-pre-reloc;
+};
+
+&qspi {
+	u-boot,dm-pre-reloc;
+};
+
+&flash {
+	compatible = "n25q256a", "spi-flash";
+	u-boot,dm-pre-reloc;
+};
+
+&uart0 {
+	clock-frequency = <100000000>;
+	u-boot,dm-pre-reloc;
+};
+
+&uart1 {
+	clock-frequency = <100000000>;
+};
+
+&usb1 {
+	status = "okay";
+};
+
+&porta {
+	bank-name = "porta";
+};
+
+&portb {
+	bank-name = "portb";
+};
+
+&portc {
+	bank-name = "portc";
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_socrates.dts b/arch/arm/dts/socfpga_cyclone5_socrates.dts
index 8cde990..93c3fa4 100644
--- a/arch/arm/dts/socfpga_cyclone5_socrates.dts
+++ b/arch/arm/dts/socfpga_cyclone5_socrates.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- *  Copyright (C) 2014 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ * Copyright (C) 2014 Steffen Trumtrar <s.trumtrar@pengutronix.de>
  */
 
 #include "socfpga_cyclone5.dtsi"
@@ -9,83 +9,88 @@
 	model = "EBV SOCrates";
 	compatible = "ebv,socrates", "altr,socfpga-cyclone5", "altr,socfpga";
 
-	chosen {
-		bootargs = "console=ttyS0,115200";
-		stdout-path = "serial0:115200n8";
-	};
-
 	aliases {
-		/*
-		 * This allows the ethaddr uboot environment variable
-		 * contents to be added to the gmac1 device tree blob.
-		 */
 		ethernet0 = &gmac1;
-		udc0 = &usb1;
 	};
 
-	memory {
+	chosen {
+		bootargs = "earlyprintk";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
 		name = "memory";
 		device_type = "memory";
 		reg = <0x0 0x40000000>; /* 1GB */
 	};
 
-	soc {
-		u-boot,dm-pre-reloc;
+	leds: gpio-leds {
 	};
 };
 
 &gmac1 {
-	status = "okay";
 	phy-mode = "rgmii";
+	status = "okay";
+};
+
+&gpio0 {
+	status = "okay";
+};
 
-	rxd0-skew-ps = <0>;
-	rxd1-skew-ps = <0>;
-	rxd2-skew-ps = <0>;
-	rxd3-skew-ps = <0>;
-	txen-skew-ps = <0>;
-	txc-skew-ps = <2600>;
-	rxdv-skew-ps = <0>;
-	rxc-skew-ps = <2000>;
+&gpio1 {
+	status = "okay";
 };
 
 &i2c0 {
 	status = "okay";
 
 	rtc: rtc@68 {
-		compatible = "stm,m41t82";
+		compatible = "st,m41t82";
 		reg = <0x68>;
 	};
 };
 
-&mmc0 {
+&leds {
+	compatible = "gpio-leds";
+
+	led0 {
+		label = "led:green:heartbeat";
+		gpios = <&porta 28 1>;
+		linux,default-trigger = "heartbeat";
+	};
+
+	led1 {
+		label = "led:green:D7";
+		gpios = <&portb 19 1>;
+	};
+
+	led2 {
+		label = "led:green:D8";
+		gpios = <&portb 25 1>;
+	};
+};
+
+&mmc {
 	status = "okay";
-	u-boot,dm-pre-reloc;
 };
 
 &qspi {
 	status = "okay";
+	u-boot,dm-pre-reloc;
 
-	flash0: n25q00@0 {
+	flash: flash@0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "n25q00", "spi-flash";
-		reg = <0>;      /* chip select */
-		spi-max-frequency = <50000000>;
+		compatible = "n25q256a";
+		reg = <0>;
+		spi-max-frequency = <100000000>;
 		m25p,fast-read;
-		page-size = <256>;
-		block-size = <16>; /* 2^16, 64KB */
+		cdns,read-delay = <4>;
 		cdns,tshsl-ns = <50>;
 		cdns,tsd2d-ns = <50>;
 		cdns,tchsh-ns = <4>;
 		cdns,tslch-ns = <4>;
+		status = "okay";
+		u-boot,dm-pre-reloc;
 	};
 };
-
-&usb1 {
-	disable-over-current;
-	status = "okay";
-};
-
-&uart0 {
-	u-boot,dm-pre-reloc;
-};
diff --git a/arch/arm/dts/socfpga_cyclone5_sr1500.dts b/arch/arm/dts/socfpga_cyclone5_sr1500.dts
index 86c61fe..6a6c29b 100644
--- a/arch/arm/dts/socfpga_cyclone5_sr1500.dts
+++ b/arch/arm/dts/socfpga_cyclone5_sr1500.dts
@@ -50,6 +50,18 @@
 	status = "okay";
 };
 
+&porta {
+	bank-name = "porta";
+};
+
+&portb {
+	bank-name = "portb";
+};
+
+&portc {
+	bank-name = "portc";
+};
+
 &i2c0 {
 	status = "okay";
 	speed-mode = <0>;
diff --git a/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi b/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi
new file mode 100644
index 0000000..360b946
--- /dev/null
+++ b/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR X11)
+/*
+ * U-Boot additions
+ *
+ * Copyright (C) 2015 Marek Vasut <marex@denx.de>
+ * Copyright (c) 2018 Simon Goldschmidt
+ */
+
+/{
+	aliases {
+		spi0 = "/soc/spi@ff705000";
+		udc0 = &usb0;
+	};
+
+	soc {
+		u-boot,dm-pre-reloc;
+	};
+};
+
+&watchdog0 {
+	status = "disabled";
+};
+
+&mmc {
+	u-boot,dm-pre-reloc;
+};
+
+&qspi {
+	u-boot,dm-pre-reloc;
+
+	n25q128@0 {
+		compatible = "n25q128", "spi-flash";
+		u-boot,dm-pre-reloc;
+	};
+	n25q00@1 {
+		compatible = "n25q00", "spi-flash";
+		u-boot,dm-pre-reloc;
+	};
+};
+
+&uart0 {
+	clock-frequency = <100000000>;
+	u-boot,dm-pre-reloc;
+};
+
+&uart1 {
+	clock-frequency = <100000000>;
+};
+
+&porta {
+	bank-name = "porta";
+};
+
+&portb {
+	bank-name = "portb";
+};
+
+&portc {
+	bank-name = "portc";
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_vining_fpga.dts b/arch/arm/dts/socfpga_cyclone5_vining_fpga.dts
index 85ab563..355b3db 100644
--- a/arch/arm/dts/socfpga_cyclone5_vining_fpga.dts
+++ b/arch/arm/dts/socfpga_cyclone5_vining_fpga.dts
@@ -1,100 +1,238 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: (GPL-2.0+ OR X11)
 /*
  * Copyright (C) 2015 Marek Vasut <marex@denx.de>
  */
 
 #include "socfpga_cyclone5.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 
 / {
 	model = "samtec VIN|ING FPGA";
-	compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+	compatible = "samtec,vining", "altr,socfpga-cyclone5", "altr,socfpga";
 
 	chosen {
-		bootargs = "console=ttyS0,115200";
+		bootargs = "earlyprintk";
 		stdout-path = "serial0:115200n8";
 	};
 
+	memory@0 {
+		name = "memory";
+		device_type = "memory";
+		reg = <0x0 0x40000000>; /* 1GB */
+	};
+
 	aliases {
+		/*
+		 * This allow the ethaddr uboot environment variable contents
+		 * to be added to the gmac1 device tree blob.
+		 */
 		ethernet0 = &gmac1;
-		udc0 = &usb0;
+		ethernet1 = &gmac0;
 	};
 
-	memory {
-		name = "memory";
-		device_type = "memory";
-		reg = <0x0 0x40000000>; /* 1GB */
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		hps_temp0 {
+			label = "BTN_0";			/* TEMP_OS */
+			gpios = <&portc 18 GPIO_ACTIVE_LOW>;	/* HPS_GPIO60 */
+			linux,code = <BTN_0>;
+		};
+
+		hps_hkey0 {
+			label = "BTN_1";			/* DIS_PWR */
+			gpios = <&portc 19 GPIO_ACTIVE_LOW>;	/* HPS_GPIO61 */
+			linux,code = <BTN_1>;
+		};
+
+		hps_hkey1 {
+			label = "hps_hkey1";			/* POWER_DOWN */
+			gpios = <&portc 20 GPIO_ACTIVE_LOW>;	/* HPS_GPIO62 */
+			linux,code = <KEY_POWER>;
+		};
 	};
 
-	soc {
-		u-boot,dm-pre-reloc;
+	regulator-usb-nrst {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_nrst";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&portb 5 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <70000>;
+		enable-active-high;
+		regulator-always-on;
 	};
 };
 
 &gmac1 {
 	status = "okay";
 	phy-mode = "rgmii";
+	phy-handle = <&phy1>;
 
-	rxd0-skew-ps = <0>;
-	rxd1-skew-ps = <0>;
-	rxd2-skew-ps = <0>;
-	rxd3-skew-ps = <0>;
-	txen-skew-ps = <0>;
-	txc-skew-ps = <2600>;
-	rxdv-skew-ps = <0>;
-	rxc-skew-ps = <2000>;
+	snps,reset-gpio = <&porta 0 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <10000 10000 10000>;
+
+	mdio0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "snps,dwmac-mdio";
+		phy1: ethernet-phy@1 {
+			reg = <1>;
+			rxd0-skew-ps = <0>;
+			rxd1-skew-ps = <0>;
+			rxd2-skew-ps = <0>;
+			rxd3-skew-ps = <0>;
+			txen-skew-ps = <0>;
+			txc-skew-ps = <2600>;
+			rxdv-skew-ps = <0>;
+			rxc-skew-ps = <2000>;
+		};
+	};
 };
 
-&gpio0 {
+&gpio0 {	/* GPIO 0..29 */
 	status = "okay";
 };
 
-&gpio1 {
+&gpio1 {	/* GPIO 30..57 */
 	status = "okay";
 };
 
-&gpio2 {
+&gpio2 {	/* GPIO 58..66 (HLGPI 0..13 at offset 13) */
 	status = "okay";
 };
 
 &i2c0 {
 	status = "okay";
+
+	gpio: pca9557@1f {
+		compatible = "nxp,pca9557";
+		reg = <0x1f>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	temp: lm75@48 {
+		compatible = "lm75";
+		reg = <0x48>;
+	};
+
+	at24@50 {
+		compatible = "atmel,24c01";
+		pagesize = <8>;
+		reg = <0x50>;
+	};
+
+	i2cswitch@70 {
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+
+		i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+
+		i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+		};
+
+		i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+		};
+
+		i2c@6 {	/* Backplane EEPROM */
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+			eeprom@51 {
+				compatible = "atmel,24c01";
+				pagesize = <8>;
+				reg = <0x51>;
+			};
+		};
+
+		i2c@7 {	/* Power board EEPROM */
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+			eeprom@51 {
+				compatible = "atmel,24c01";
+				pagesize = <8>;
+				reg = <0x51>;
+			};
+		};
+	};
+};
+
+&i2c1 {
+	status = "okay";
+	clock-frequency = <100000>;
 
-	rtc: rtc@68 {
-		compatible = "stm,m41t82";
-		reg = <0x68>;
+	at24@50 {
+		compatible = "atmel,24c02";
+		pagesize = <8>;
+		reg = <0x50>;
 	};
 };
 
 &qspi {
 	status = "okay";
-	u-boot,dm-pre-reloc;
 
-	flash0: n25q128@0 {
-		u-boot,dm-pre-reloc;
+	n25q128@0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "n25q128", "spi-flash";
-		reg = <0>;      /* chip select */
-		spi-max-frequency = <50000000>;
+		compatible = "n25q128";
+		reg = <0>;		/* chip select */
+		spi-max-frequency = <100000000>;
 		m25p,fast-read;
-		page-size = <256>;
-		block-size = <16>; /* 2^16, 64KB */
+
+		cdns,page-size = <256>;
+		cdns,block-size = <16>;
+		cdns,read-delay = <4>;
 		cdns,tshsl-ns = <50>;
 		cdns,tsd2d-ns = <50>;
 		cdns,tchsh-ns = <4>;
 		cdns,tslch-ns = <4>;
 	};
 
-	flash1: n25q00@1 {
-		u-boot,dm-pre-reloc;
+	n25q00@1 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "n25q00", "spi-flash";
-		reg = <1>;      /* chip select */
-		spi-max-frequency = <50000000>;
+		compatible = "n25q00";
+		reg = <1>;		/* chip select */
+		spi-max-frequency = <100000000>;
 		m25p,fast-read;
-		page-size = <256>;
-		block-size = <16>; /* 2^16, 64KB */
+
+		cdns,page-size = <256>;
+		cdns,block-size = <16>;
+		cdns,read-delay = <4>;
 		cdns,tshsl-ns = <50>;
 		cdns,tsd2d-ns = <50>;
 		cdns,tchsh-ns = <4>;
@@ -103,13 +241,11 @@
 };
 
 &usb0 {
+	dr_mode = "host";
 	status = "okay";
 };
 
 &usb1 {
+	dr_mode = "peripheral";
 	status = "okay";
 };
-
-&uart0 {
-	u-boot,dm-pre-reloc;
-};
diff --git a/arch/arm/dts/stv0991.dts b/arch/arm/dts/stv0991.dts
index bceac09..98bd5df 100644
--- a/arch/arm/dts/stv0991.dts
+++ b/arch/arm/dts/stv0991.dts
@@ -26,7 +26,7 @@
 	};
 
 	qspi: spi@80203000 {
-			compatible = "cadence,qspi";
+			compatible = "cdns,qspi-nor";
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0x80203000 0x100>,
diff --git a/arch/arm/dts/ulcb.dtsi b/arch/arm/dts/ulcb.dtsi
index ab88665..0ead552 100644
--- a/arch/arm/dts/ulcb.dtsi
+++ b/arch/arm/dts/ulcb.dtsi
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the R-Car Gen3 ULCB board
  *
  * Copyright (C) 2016 Renesas Electronics Corp.
  * Copyright (C) 2016 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include <dt-bindings/gpio/gpio.h>
@@ -24,15 +21,6 @@
 		stdout-path = "serial0:115200n8";
 	};
 
-	cpld {
-		compatible = "renesas,ulcb-cpld";
-		status = "okay";
-		gpio-sck = <&gpio6 8 0>;
-		gpio-mosi = <&gpio6 7 0>;
-		gpio-miso = <&gpio6 10 0>;
-		gpio-sstbz = <&gpio2 3 0>;
-	};
-
 	audio_clkout: audio-clkout {
 		/*
 		 * This is same as <&rcar_sound 0>
@@ -252,6 +240,32 @@
 
 &i2c_dvfs {
 	status = "okay";
+
+	pmic: pmic@30 {
+		pinctrl-0 = <&irq0_pins>;
+		pinctrl-names = "default";
+
+		compatible = "rohm,bd9571mwv";
+		reg = <0x30>;
+		interrupt-parent = <&intc_ex>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		rohm,ddr-backup-power = <0xf>;
+		rohm,rstbmode-pulse;
+
+		regulators {
+			dvfs: dvfs {
+				regulator-name = "dvfs";
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <1030000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+		};
+	};
 };
 
 &ohci1 {
@@ -264,12 +278,12 @@
 
 	avb_pins: avb {
 		mux {
-			groups = "avb_link", "avb_mdc", "avb_mii";
+			groups = "avb_link", "avb_mdio", "avb_mii";
 			function = "avb";
 		};
 
-		pins_mdc {
-			groups = "avb_mdc";
+		pins_mdio {
+			groups = "avb_mdio";
 			drive-strength = <24>;
 		};
 
@@ -285,6 +299,11 @@
 		function = "i2c2";
 	};
 
+	irq0_pins: irq0 {
+		groups = "intc_ex_irq0";
+		function = "intc_ex";
+	};
+
 	scif2_pins: scif2 {
 		groups = "scif2_data_a";
 		function = "scif2";
@@ -308,13 +327,13 @@
 	};
 
 	sdhi2_pins: sd2 {
-		groups = "sdhi2_data8", "sdhi2_ctrl";
+		groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
 		function = "sdhi2";
-		power-source = <1800>;
+		power-source = <3300>;
 	};
 
 	sdhi2_pins_uhs: sd2_uhs {
-		groups = "sdhi2_data8", "sdhi2_ctrl";
+		groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
 		function = "sdhi2";
 		power-source = <1800>;
 	};
@@ -425,7 +444,7 @@
 	status = "okay";
 };
 
-&wdt0 {
+&rwdt {
 	timeout-sec = <60>;
 	status = "okay";
 };
diff --git a/arch/arm/dts/zynq-cse-qspi-single.dts b/arch/arm/dts/zynq-cse-qspi-single.dts
index 3252d6a..0d680df 100644
--- a/arch/arm/dts/zynq-cse-qspi-single.dts
+++ b/arch/arm/dts/zynq-cse-qspi-single.dts
@@ -7,6 +7,6 @@
 
 #include "zynq-cse-qspi.dtsi"
 
-&qspi {
+&flash0 {
 	spi-rx-bus-width = <4>;
 };
diff --git a/arch/arm/dts/zynq-cse-qspi.dtsi b/arch/arm/dts/zynq-cse-qspi.dtsi
index 2b16946..65af408 100644
--- a/arch/arm/dts/zynq-cse-qspi.dtsi
+++ b/arch/arm/dts/zynq-cse-qspi.dtsi
@@ -59,7 +59,7 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			num-cs = <1>;
-			flash@0 {
+			flash0: flash@0 {
 				compatible = "n25q128a11";
 				reg = <0x0>;
 				spi-tx-bus-width = <1>;
diff --git a/arch/arm/dts/zynqmp-mini-emmc0.dts b/arch/arm/dts/zynqmp-mini-emmc0.dts
index 24dd1ab..2213bb2 100644
--- a/arch/arm/dts/zynqmp-mini-emmc0.dts
+++ b/arch/arm/dts/zynqmp-mini-emmc0.dts
@@ -10,7 +10,7 @@
 /dts-v1/;
 
 / {
-	model = "ZynqMP MINI EMMC";
+	model = "ZynqMP MINI EMMC0";
 	compatible = "xlnx,zynqmp";
 	#address-cells = <2>;
 	#size-cells = <2>;
@@ -53,6 +53,7 @@
 			status = "disabled";
 			reg = <0x0 0xff160000 0x0 0x1000>;
 			clock-names = "clk_xin", "clk_ahb";
+			clocks = <&clk_xin &clk_xin>;
 			xlnx,device_id = <0>;
 		};
 	};
diff --git a/arch/arm/dts/zynqmp-mini-emmc1.dts b/arch/arm/dts/zynqmp-mini-emmc1.dts
index 530ab3c..0538da4 100644
--- a/arch/arm/dts/zynqmp-mini-emmc1.dts
+++ b/arch/arm/dts/zynqmp-mini-emmc1.dts
@@ -10,7 +10,7 @@
 /dts-v1/;
 
 / {
-	model = "ZynqMP MINI EMMC";
+	model = "ZynqMP MINI EMMC1";
 	compatible = "xlnx,zynqmp";
 	#address-cells = <2>;
 	#size-cells = <2>;
diff --git a/arch/arm/dts/zynqmp-mini.dts b/arch/arm/dts/zynqmp-mini.dts
new file mode 100644
index 0000000..1faee9e
--- /dev/null
+++ b/arch/arm/dts/zynqmp-mini.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP Mini Configuration
+ *
+ * (C) Copyright 2017, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+/dts-v1/;
+
+/ {
+	model = "ZynqMP MINI";
+	compatible = "xlnx,zynqmp";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		serial0 = &dcc;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0xfffc0000 0x0 0x40000>, <0x0 0x0 0x0 0x80000000>;
+	};
+
+	dcc: dcc {
+		compatible = "arm,dcc";
+		status = "disabled";
+		u-boot,dm-pre-reloc;
+	};
+};
+
+&dcc {
+	status = "okay";
+};
diff --git a/arch/arm/dts/zynqmp-zc1232-revA.dts b/arch/arm/dts/zynqmp-zc1232-revA.dts
index ea1ca56..5c212ba 100644
--- a/arch/arm/dts/zynqmp-zc1232-revA.dts
+++ b/arch/arm/dts/zynqmp-zc1232-revA.dts
@@ -41,7 +41,7 @@
 &qspi {
 	status = "okay";
 	flash@0 {
-		compatible = "m25p80"; /* 32MB FIXME */
+		compatible = "m25p80", "spi-flash"; /* 32MB FIXME */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zc1254-revA.dts b/arch/arm/dts/zynqmp-zc1254-revA.dts
index 2493883..881aacc 100644
--- a/arch/arm/dts/zynqmp-zc1254-revA.dts
+++ b/arch/arm/dts/zynqmp-zc1254-revA.dts
@@ -41,7 +41,7 @@
 &qspi {
 	status = "okay";
 	flash@0 {
-		compatible = "m25p80"; /* 32MB */
+		compatible = "m25p80", "spi-flash"; /* 32MB */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zc1275-revA.dts b/arch/arm/dts/zynqmp-zc1275-revA.dts
index 2543a67..7403f15 100644
--- a/arch/arm/dts/zynqmp-zc1275-revA.dts
+++ b/arch/arm/dts/zynqmp-zc1275-revA.dts
@@ -41,7 +41,7 @@
 &qspi {
 	status = "okay";
 	flash@0 {
-		compatible = "m25p80"; /* 32MB */
+		compatible = "m25p80", "spi-flash"; /* 32MB */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zc1275-revB.dts b/arch/arm/dts/zynqmp-zc1275-revB.dts
index f694fae..e84b2da 100644
--- a/arch/arm/dts/zynqmp-zc1275-revB.dts
+++ b/arch/arm/dts/zynqmp-zc1275-revB.dts
@@ -42,7 +42,7 @@
 &qspi {
 	status = "okay";
 	flash@0 {
-		compatible = "m25p80"; /* 32MB */
+		compatible = "m25p80", "spi-flash"; /* 32MB */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts b/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts
index c794c91..9768dfe 100644
--- a/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts
+++ b/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts
@@ -101,7 +101,7 @@
 &qspi {
 	status = "okay";
 	flash@0 {
-		compatible = "m25p80"; /* Micron MT25QU512ABB8ESF */
+		compatible = "m25p80", "spi-flash"; /* Micron MT25QU512ABB8ESF */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts b/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts
index fb49b4f..9afbbb6 100644
--- a/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts
+++ b/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts
@@ -177,6 +177,35 @@
 	status = "okay";
 };
 
+&qspi {
+	status = "okay";
+	flash@0 {
+		compatible = "m25p80", "spi-flash"; /* 32MB */
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>; /* also DUAL configuration possible */
+		spi-max-frequency = <108000000>; /* Based on DC1 spec */
+		partition@qspi-fsbl-uboot { /* for testing purpose */
+			label = "qspi-fsbl-uboot";
+			reg = <0x0 0x100000>;
+		};
+		partition@qspi-linux { /* for testing purpose */
+			label = "qspi-linux";
+			reg = <0x100000 0x500000>;
+		};
+		partition@qspi-device-tree { /* for testing purpose */
+			label = "qspi-device-tree";
+			reg = <0x600000 0x20000>;
+		};
+		partition@qspi-rootfs { /* for testing purpose */
+			label = "qspi-rootfs";
+			reg = <0x620000 0x5E0000>;
+		};
+	};
+};
+
 &rtc {
 	status = "okay";
 };
diff --git a/arch/arm/dts/zynqmp-zcu100-revC.dts b/arch/arm/dts/zynqmp-zcu100-revC.dts
index 2fffe17..05491e9 100644
--- a/arch/arm/dts/zynqmp-zcu100-revC.dts
+++ b/arch/arm/dts/zynqmp-zcu100-revC.dts
@@ -104,6 +104,7 @@
 
 	ltc2954: ltc2954 { /* U7 */
 		compatible = "lltc,ltc2954", "lltc,ltc2952";
+		status = "disabled";
 		trigger-gpios = <&gpio 26 GPIO_ACTIVE_LOW>; /* INT line - input */
 		/* If there is HW watchdog on mezzanine this signal should be connected there */
 		watchdog-gpios = <&gpio 35 GPIO_ACTIVE_HIGH>; /* MIO on PAD */
diff --git a/arch/arm/dts/zynqmp-zcu102-revA.dts b/arch/arm/dts/zynqmp-zcu102-revA.dts
index ac7035f..05be919f6 100644
--- a/arch/arm/dts/zynqmp-zcu102-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu102-revA.dts
@@ -422,6 +422,7 @@
 				temperature-stability = <50>;
 				factory-fout = <300000000>;
 				clock-frequency = <300000000>;
+				clock-output-names = "si570_user";
 			};
 		};
 		i2c@3 {
@@ -435,6 +436,7 @@
 				temperature-stability = <50>; /* copy from zc702 */
 				factory-fout = <156250000>;
 				clock-frequency = <148500000>;
+				clock-output-names = "si570_mgt";
 			};
 		};
 		i2c@4 {
diff --git a/arch/arm/dts/zynqmp-zcu104-revA.dts b/arch/arm/dts/zynqmp-zcu104-revA.dts
index 6a4b701..431dff5 100644
--- a/arch/arm/dts/zynqmp-zcu104-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu104-revA.dts
@@ -169,7 +169,7 @@
 &qspi {
 	status = "okay";
 	flash@0 {
-		compatible = "m25p80"; /* n25q512a 128MiB */
+		compatible = "m25p80", "spi-flash"; /* n25q512a 128MiB */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zcu104-revC.dts b/arch/arm/dts/zynqmp-zcu104-revC.dts
index fe742b8..becc6a0 100644
--- a/arch/arm/dts/zynqmp-zcu104-revC.dts
+++ b/arch/arm/dts/zynqmp-zcu104-revC.dts
@@ -175,7 +175,7 @@
 &qspi {
 	status = "okay";
 	flash@0 {
-		compatible = "m25p80"; /* n25q512a 128MiB */
+		compatible = "m25p80", "spi-flash"; /* n25q512a 128MiB */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zcu106-revA.dts b/arch/arm/dts/zynqmp-zcu106-revA.dts
index a30268b..7735e9d 100644
--- a/arch/arm/dts/zynqmp-zcu106-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu106-revA.dts
@@ -395,6 +395,7 @@
 				temperature-stability = <50>;
 				factory-fout = <300000000>;
 				clock-frequency = <300000000>;
+				clock-output-names = "si570_user";
 			};
 		};
 		i2c@3 {
@@ -408,6 +409,7 @@
 				temperature-stability = <50>; /* copy from zc702 */
 				factory-fout = <156250000>;
 				clock-frequency = <148500000>;
+				clock-output-names = "si570_mgt";
 			};
 		};
 		i2c@4 {
@@ -512,7 +514,7 @@
 	status = "okay";
 	is-dual = <1>;
 	flash@0 {
-		compatible = "m25p80"; /* 32MB */
+		compatible = "m25p80", "spi-flash"; /* 32MB */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zcu111-revA.dts b/arch/arm/dts/zynqmp-zcu111-revA.dts
index 6c1a0f7..172e6cc 100644
--- a/arch/arm/dts/zynqmp-zcu111-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu111-revA.dts
@@ -318,6 +318,7 @@
 				temperature-stability = <50>;
 				factory-fout = <300000000>;
 				clock-frequency = <300000000>;
+				clock-output-names = "si570_user";
 			};
 		};
 		i2c@3 {
@@ -331,6 +332,7 @@
 				temperature-stability = <50>;
 				factory-fout = <156250000>;
 				clock-frequency = <148500000>;
+				clock-output-names = "si570_mgt";
 			};
 		};
 		i2c@4 {
@@ -449,7 +451,7 @@
 	status = "okay";
 	is-dual = <1>;
 	flash@0 {
-		compatible = "m25p80"; /* 32MB */
+		compatible = "m25p80", "spi-flash"; /* 32MB */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		reg = <0x0>;
diff --git a/arch/arm/include/asm/arch-mediatek/gpio.h b/arch/arm/include/asm/arch-mediatek/gpio.h
new file mode 100644
index 0000000..4ea1020
--- /dev/null
+++ b/arch/arm/include/asm/arch-mediatek/gpio.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef __MEDIATEK_GPIO_H
+#define __MEDIATEK_GPIO_H
+
+#endif	/* __MEDIATEK_GPIO_H */
diff --git a/arch/arm/include/asm/arch-mediatek/misc.h b/arch/arm/include/asm/arch-mediatek/misc.h
new file mode 100644
index 0000000..2530e78
--- /dev/null
+++ b/arch/arm/include/asm/arch-mediatek/misc.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef __MEDIATEK_MISC_H_
+#define __MEDIATEK_MISC_H_
+
+#define VER_BASE		0x08000000
+#define VER_SIZE		0x10
+
+#define APHW_CODE		0x00
+#define APHW_SUBCODE		0x04
+#define APHW_VER		0x08
+#define APSW_VER		0x0c
+
+#endif /* __MEDIATEK_MISC_H_ */
diff --git a/arch/arm/include/asm/arch-meson/axg.h b/arch/arm/include/asm/arch-meson/axg.h
new file mode 100644
index 0000000..d293f2a
--- /dev/null
+++ b/arch/arm/include/asm/arch-meson/axg.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#ifndef __AXG_H__
+#define __AXG_H__
+
+#define AXG_AOBUS_BASE		0xff800000
+#define AXG_PERIPHS_BASE	0xff634400
+#define AXG_HIU_BASE		0xff63c000
+#define AXG_ETH_BASE		0xff3f0000
+
+/* Always-On Peripherals registers */
+#define AXG_AO_ADDR(off)	(AXG_AOBUS_BASE + ((off) << 2))
+
+#define AXG_AO_SEC_GP_CFG0	AXG_AO_ADDR(0x90)
+#define AXG_AO_SEC_GP_CFG3	AXG_AO_ADDR(0x93)
+#define AXG_AO_SEC_GP_CFG4	AXG_AO_ADDR(0x94)
+#define AXG_AO_SEC_GP_CFG5	AXG_AO_ADDR(0x95)
+
+#define AXG_AO_BOOT_DEVICE	0xF
+#define AXG_AO_MEM_SIZE_MASK	0xFFFF0000
+#define AXG_AO_MEM_SIZE_SHIFT	16
+#define AXG_AO_BL31_RSVMEM_SIZE_MASK	0xFFFF0000
+#define AXG_AO_BL31_RSVMEM_SIZE_SHIFT	16
+#define AXG_AO_BL32_RSVMEM_SIZE_MASK	0xFFFF
+
+/* Peripherals registers */
+#define AXG_PERIPHS_ADDR(off)	(AXG_PERIPHS_BASE + ((off) << 2))
+
+#define AXG_ETH_REG_0		AXG_PERIPHS_ADDR(0x50)
+#define AXG_ETH_REG_1		AXG_PERIPHS_ADDR(0x51)
+
+#define AXG_ETH_REG_0_PHY_INTF_RGMII	BIT(0)
+#define AXG_ETH_REG_0_PHY_INTF_RMII	BIT(2)
+#define AXG_ETH_REG_0_TX_PHASE(x)	(((x) & 3) << 5)
+#define AXG_ETH_REG_0_TX_RATIO(x)	(((x) & 7) << 7)
+#define AXG_ETH_REG_0_PHY_CLK_EN	BIT(10)
+#define AXG_ETH_REG_0_INVERT_RMII_CLK	BIT(11)
+#define AXG_ETH_REG_0_CLK_EN		BIT(12)
+
+/* HIU registers */
+#define AXG_HIU_ADDR(off)	(AXG_HIU_BASE + ((off) << 2))
+
+#define AXG_MEM_PD_REG_0	AXG_HIU_ADDR(0x40)
+
+/* Ethernet memory power domain */
+#define AXG_MEM_PD_REG_0_ETH_MASK	(BIT(2) | BIT(3))
+
+#endif /* __AXG_H__ */
diff --git a/arch/arm/include/asm/arch-meson/boot.h b/arch/arm/include/asm/arch-meson/boot.h
new file mode 100644
index 0000000..a90fe55
--- /dev/null
+++ b/arch/arm/include/asm/arch-meson/boot.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#ifndef __MESON_BOOT_H__
+#define __MESON_BOOT_H__
+
+/* Boot device */
+#define BOOT_DEVICE_RESERVED    0
+#define BOOT_DEVICE_EMMC        1
+#define BOOT_DEVICE_NAND        2
+#define BOOT_DEVICE_SPI         3
+#define BOOT_DEVICE_SD          4
+#define BOOT_DEVICE_USB         5
+
+int meson_get_boot_device(void);
+
+#endif /* __MESON_BOOT_H__ */
diff --git a/arch/arm/include/asm/arch-meson/clock-axg.h b/arch/arm/include/asm/arch-meson/clock-axg.h
new file mode 100644
index 0000000..1ef88e4
--- /dev/null
+++ b/arch/arm/include/asm/arch-meson/clock-axg.h
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2016 - AmLogic, Inc.
+ * Copyright 2018 - Beniamino Galvani <b.galvani@gmail.com>
+ * Copyright 2018 - BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+#ifndef _ARCH_MESON_CLOCK_AXG_H_
+#define _ARCH_MESON_CLOCK_AXG_H_
+
+/*
+ * Clock controller register offsets
+ *
+ * Register offsets from the data sheet are listed in comment blocks below.
+ * Those offsets must be multiplied by 4 before adding them to the base address
+ * to get the right value
+ */
+#define HHI_GP0_PLL_CNTL		0x40
+#define HHI_GP0_PLL_CNTL2		0x44
+#define HHI_GP0_PLL_CNTL3		0x48
+#define HHI_GP0_PLL_CNTL4		0x4c
+#define HHI_GP0_PLL_CNTL5		0x50
+#define HHI_GP0_PLL_STS			0x54
+#define HHI_GP0_PLL_CNTL1		0x58
+#define HHI_HIFI_PLL_CNTL		0x80
+#define HHI_HIFI_PLL_CNTL2		0x84
+#define HHI_HIFI_PLL_CNTL3		0x88
+#define HHI_HIFI_PLL_CNTL4		0x8C
+#define HHI_HIFI_PLL_CNTL5		0x90
+#define HHI_HIFI_PLL_STS		0x94
+#define HHI_HIFI_PLL_CNTL1		0x98
+
+#define HHI_XTAL_DIVN_CNTL		0xbc
+#define HHI_GCLK2_MPEG0			0xc0
+#define HHI_GCLK2_MPEG1			0xc4
+#define HHI_GCLK2_MPEG2			0xc8
+#define HHI_GCLK2_OTHER			0xd0
+#define HHI_GCLK2_AO			0xd4
+#define HHI_PCIE_PLL_CNTL		0xd8
+#define HHI_PCIE_PLL_CNTL1		0xdC
+#define HHI_PCIE_PLL_CNTL2		0xe0
+#define HHI_PCIE_PLL_CNTL3		0xe4
+#define HHI_PCIE_PLL_CNTL4		0xe8
+#define HHI_PCIE_PLL_CNTL5		0xec
+#define HHI_PCIE_PLL_CNTL6		0xf0
+#define HHI_PCIE_PLL_STS		0xf4
+
+#define HHI_MEM_PD_REG0			0x100
+#define HHI_VPU_MEM_PD_REG0		0x104
+#define HHI_VIID_CLK_DIV		0x128
+#define HHI_VIID_CLK_CNTL		0x12c
+
+#define HHI_GCLK_MPEG0			0x140
+#define HHI_GCLK_MPEG1			0x144
+#define HHI_GCLK_MPEG2			0x148
+#define HHI_GCLK_OTHER			0x150
+#define HHI_GCLK_AO			0x154
+#define HHI_SYS_CPU_CLK_CNTL1		0x15c
+#define HHI_SYS_CPU_RESET_CNTL		0x160
+#define HHI_VID_CLK_DIV			0x164
+#define HHI_SPICC_HCLK_CNTL		0x168
+
+#define HHI_MPEG_CLK_CNTL		0x174
+#define HHI_VID_CLK_CNTL		0x17c
+#define HHI_TS_CLK_CNTL			0x190
+#define HHI_VID_CLK_CNTL2		0x194
+#define HHI_SYS_CPU_CLK_CNTL0		0x19c
+#define HHI_VID_PLL_CLK_DIV		0x1a0
+#define HHI_VPU_CLK_CNTL		0x1bC
+
+#define HHI_VAPBCLK_CNTL		0x1F4
+
+#define HHI_GEN_CLK_CNTL		0x228
+
+#define HHI_VDIN_MEAS_CLK_CNTL		0x250
+#define HHI_NAND_CLK_CNTL		0x25C
+#define HHI_SD_EMMC_CLK_CNTL		0x264
+
+#define HHI_MPLL_CNTL			0x280
+#define HHI_MPLL_CNTL2			0x284
+#define HHI_MPLL_CNTL3			0x288
+#define HHI_MPLL_CNTL4			0x28C
+#define HHI_MPLL_CNTL5			0x290
+#define HHI_MPLL_CNTL6			0x294
+#define HHI_MPLL_CNTL7			0x298
+#define HHI_MPLL_CNTL8			0x29C
+#define HHI_MPLL_CNTL9			0x2A0
+#define HHI_MPLL_CNTL10			0x2A4
+
+#define HHI_MPLL3_CNTL0			0x2E0
+#define HHI_MPLL3_CNTL1			0x2E4
+#define HHI_PLL_TOP_MISC		0x2E8
+
+#define HHI_SYS_PLL_CNTL1		0x2FC
+#define HHI_SYS_PLL_CNTL		0x300
+#define HHI_SYS_PLL_CNTL2		0x304
+#define HHI_SYS_PLL_CNTL3		0x308
+#define HHI_SYS_PLL_CNTL4		0x30c
+#define HHI_SYS_PLL_CNTL5		0x310
+#define HHI_SYS_PLL_STS			0x314
+#define HHI_DPLL_TOP_I			0x318
+#define HHI_DPLL_TOP2_I			0x31C
+
+#endif
diff --git a/arch/arm/include/asm/arch-meson/clock.h b/arch/arm/include/asm/arch-meson/clock-gx.h
similarity index 98%
rename from arch/arm/include/asm/arch-meson/clock.h
rename to arch/arm/include/asm/arch-meson/clock-gx.h
index c0ff00f..13a2e76 100644
--- a/arch/arm/include/asm/arch-meson/clock.h
+++ b/arch/arm/include/asm/arch-meson/clock-gx.h
@@ -3,8 +3,8 @@
  * Copyright 2016 - AmLogic, Inc.
  * Copyright 2018 - Beniamino Galvani <b.galvani@gmail.com>
  */
-#ifndef _ARCH_MESON_CLOCK_H_
-#define _ARCH_MESON_CLOCK_H_
+#ifndef _ARCH_MESON_CLOCK_GX_H_
+#define _ARCH_MESON_CLOCK_GX_H_
 
 /*
  * Clock controller register offsets
diff --git a/arch/arm/include/asm/arch-meson/eth.h b/arch/arm/include/asm/arch-meson/eth.h
index 1aa0872..08acc5c 100644
--- a/arch/arm/include/asm/arch-meson/eth.h
+++ b/arch/arm/include/asm/arch-meson/eth.h
@@ -10,13 +10,13 @@
 #include <phy.h>
 
 enum {
-	/* Use GXL Internal RMII PHY */
-	MESON_GXL_USE_INTERNAL_RMII_PHY = 1,
+	/* Use Internal RMII PHY */
+	MESON_USE_INTERNAL_RMII_PHY = 1,
 };
 
 /* Configure the Ethernet MAC with the requested interface mode
  * with some optional flags.
  */
-void meson_gx_eth_init(phy_interface_t mode, unsigned int flags);
+void meson_eth_init(phy_interface_t mode, unsigned int flags);
 
 #endif /* __MESON_ETH_H__ */
diff --git a/arch/arm/include/asm/arch-meson/gx.h b/arch/arm/include/asm/arch-meson/gx.h
index 4bc9475..b781ba9 100644
--- a/arch/arm/include/asm/arch-meson/gx.h
+++ b/arch/arm/include/asm/arch-meson/gx.h
@@ -21,6 +21,7 @@
 #define GX_AO_SEC_GP_CFG4	GX_AO_ADDR(0x94)
 #define GX_AO_SEC_GP_CFG5	GX_AO_ADDR(0x95)
 
+#define GX_AO_BOOT_DEVICE	0xF
 #define GX_AO_MEM_SIZE_MASK	0xFFFF0000
 #define GX_AO_MEM_SIZE_SHIFT	16
 #define GX_AO_BL31_RSVMEM_SIZE_MASK	0xFFFF0000
diff --git a/arch/arm/include/asm/arch-meson/mem.h b/arch/arm/include/asm/arch-meson/mem.h
index 6281833..a65100a 100644
--- a/arch/arm/include/asm/arch-meson/mem.h
+++ b/arch/arm/include/asm/arch-meson/mem.h
@@ -10,6 +10,7 @@
 /* Configure the reserved memory zones exported by the secure registers
  * into EFI and DTB reserved memory entries.
  */
-void meson_gx_init_reserved_memory(void *fdt);
+void meson_board_add_reserved_memory(void *fdt, u64 start, u64 size);
+void meson_init_reserved_memory(void *fdt);
 
 #endif /* __MESON_MEM_H__ */
diff --git a/arch/arm/include/asm/arch-rockchip/clock.h b/arch/arm/include/asm/arch-rockchip/clock.h
index 1d5b3a0..0eb19ca 100644
--- a/arch/arm/include/asm/arch-rockchip/clock.h
+++ b/arch/arm/include/asm/arch-rockchip/clock.h
@@ -43,6 +43,12 @@
 	unsigned int glb_srst_snd_value;
 };
 
+struct softreset_reg {
+        void __iomem *base;
+        unsigned int sf_reset_offset;
+        unsigned int sf_reset_num;
+};
+
 /**
  * clk_get_divisor() - Calculate the required clock divisior
  *
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h
index b18de9f..15eeb9c 100644
--- a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h
@@ -69,16 +69,21 @@
 #define MHz		1000000
 #define KHz		1000
 #define OSC_HZ		(24*MHz)
-#define APLL_HZ		(600*MHz)
+#define LPLL_HZ		(600*MHz)
+#define BPLL_HZ		(600*MHz)
 #define GPLL_HZ		(594*MHz)
 #define CPLL_HZ		(384*MHz)
 #define PPLL_HZ		(676*MHz)
 
 #define PMU_PCLK_HZ	(48*MHz)
 
-#define ACLKM_CORE_HZ	(300*MHz)
-#define ATCLK_CORE_HZ	(300*MHz)
-#define PCLK_DBG_HZ	(100*MHz)
+#define ACLKM_CORE_L_HZ	(300*MHz)
+#define ATCLK_CORE_L_HZ	(300*MHz)
+#define PCLK_DBG_L_HZ	(100*MHz)
+
+#define ACLKM_CORE_B_HZ	(300*MHz)
+#define ATCLK_CORE_B_HZ	(300*MHz)
+#define PCLK_DBG_B_HZ	(100*MHz)
 
 #define PERIHP_ACLK_HZ	(148500*KHz)
 #define PERIHP_HCLK_HZ	(148500*KHz)
@@ -98,4 +103,13 @@
 	APLL_L_600_MHZ,
 };
 
+enum apll_b_frequencies {
+	APLL_B_600_MHZ,
+};
+
+void rk3399_configure_cpu_l(struct rk3399_cru *cru,
+			    enum apll_l_frequencies apll_l_freq);
+void rk3399_configure_cpu_b(struct rk3399_cru *cru,
+			    enum apll_b_frequencies apll_b_freq);
+
 #endif	/* __ASM_ARCH_CRU_RK3399_H_ */
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h
index 3cc2ed0..7697e96 100644
--- a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h
+++ b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h
@@ -11,7 +11,11 @@
 #define OSC_HZ		(24 * 1000 * 1000)
 
 #define APLL_HZ		(600 * 1000000)
-#define GPLL_HZ		(594 * 1000000)
+#define GPLL_HZ		(1188 * 1000000)
+#define ACLK_PERI_HZ	(148500000)
+#define HCLK_PERI_HZ	(148500000)
+#define PCLK_PERI_HZ	(74250000)
+#define ACLK_BUS_HZ	(148500000)
 
 struct rv1108_clk_priv {
 	struct rv1108_cru *cru;
@@ -80,6 +84,11 @@
 	WORK_MODE_NORMAL	= 1,
 	DSMPD_SHIFT             = 3,
 	DSMPD_MASK		= 1 << DSMPD_SHIFT,
+	INTEGER_MODE			= 1,
+	GLOBAL_POWER_DOWN_SHIFT		= 0,
+	GLOBAL_POWER_DOWN_MASK		= 1 << GLOBAL_POWER_DOWN_SHIFT,
+	GLOBAL_POWER_DOWN		= 1,
+	GLOBAL_POWER_UP			= 0,
 
 	/* CLKSEL0_CON */
 	CORE_PLL_SEL_SHIFT	= 8,
@@ -90,11 +99,77 @@
 	CORE_CLK_DIV_SHIFT	= 0,
 	CORE_CLK_DIV_MASK	= 0x1f << CORE_CLK_DIV_SHIFT,
 
+	/* CLKSEL_CON1 */
+	PCLK_DBG_DIV_CON_SHIFT		= 4,
+	PCLK_DBG_DIV_CON_MASK		= 0xf << PCLK_DBG_DIV_CON_SHIFT,
+	ACLK_CORE_DIV_CON_SHIFT		= 0,
+	ACLK_CORE_DIV_CON_MASK		= 7 << ACLK_CORE_DIV_CON_SHIFT,
+
+	/* CLKSEL_CON2 */
+	ACLK_BUS_PLL_SEL_SHIFT		= 8,
+	ACLK_BUS_PLL_SEL_MASK		= 3 << ACLK_BUS_PLL_SEL_SHIFT,
+	ACLK_BUS_PLL_SEL_GPLL		= 0,
+	ACLK_BUS_PLL_SEL_APLL		= 1,
+	ACLK_BUS_PLL_SEL_DPLL		= 2,
+	ACLK_BUS_DIV_CON_SHIFT		= 0,
+	ACLK_BUS_DIV_CON_MASK		= 0x1f << ACLK_BUS_DIV_CON_SHIFT,
+	ACLK_BUS_DIV_CON_WIDTH		= 5,
+
+	/* CLKSEL_CON3 */
+	PCLK_BUS_DIV_CON_SHIFT		= 8,
+	PCLK_BUS_DIV_CON_MASK		= 0x1f << PCLK_BUS_DIV_CON_SHIFT,
+	HCLK_BUS_DIV_CON_SHIFT		= 0,
+	HCLK_BUS_DIV_CON_MASK		= 0x1f,
+
+	/* CLKSEL_CON4 */
+	CLK_DDR_PLL_SEL_SHIFT		= 8,
+	CLK_DDR_PLL_SEL_MASK		= 0x3 << CLK_DDR_PLL_SEL_SHIFT,
+	CLK_DDR_DIV_CON_SHIFT		= 0,
+	CLK_DDR_DIV_CON_MASK		= 0x3 << CLK_DDR_DIV_CON_SHIFT,
+
+	/* CLKSEL_CON19 */
+	CLK_I2C1_PLL_SEL_SHIFT		= 15,
+	CLK_I2C1_PLL_SEL_MASK		= 1 << CLK_I2C1_PLL_SEL_SHIFT,
+	CLK_I2C1_PLL_SEL_DPLL		= 0,
+	CLK_I2C1_PLL_SEL_GPLL		= 1,
+	CLK_I2C1_DIV_CON_SHIFT		= 8,
+	CLK_I2C1_DIV_CON_MASK		= 0x7f << CLK_I2C1_DIV_CON_SHIFT,
+	CLK_I2C0_PLL_SEL_SHIFT		= 7,
+	CLK_I2C0_PLL_SEL_MASK		= 1 << CLK_I2C0_PLL_SEL_SHIFT,
+	CLK_I2C0_DIV_CON_SHIFT		= 0,
+	CLK_I2C0_DIV_CON_MASK		= 0x7f,
+	I2C_DIV_CON_WIDTH		= 7,
+
+	/* CLKSEL_CON20 */
+	CLK_I2C3_PLL_SEL_SHIFT		= 15,
+	CLK_I2C3_PLL_SEL_MASK		= 1 << CLK_I2C3_PLL_SEL_SHIFT,
+	CLK_I2C3_PLL_SEL_DPLL		= 0,
+	CLK_I2C3_PLL_SEL_GPLL		= 1,
+	CLK_I2C3_DIV_CON_SHIFT		= 8,
+	CLK_I2C3_DIV_CON_MASK		= 0x7f << CLK_I2C3_DIV_CON_SHIFT,
+	CLK_I2C2_PLL_SEL_SHIFT		= 7,
+	CLK_I2C2_PLL_SEL_MASK		= 1 << CLK_I2C2_PLL_SEL_SHIFT,
+	CLK_I2C2_DIV_CON_SHIFT		= 0,
+	CLK_I2C2_DIV_CON_MASK		= 0x7f,
+
 	/* CLKSEL_CON22 */
 	CLK_SARADC_DIV_CON_SHIFT= 0,
 	CLK_SARADC_DIV_CON_MASK	= GENMASK(9, 0),
 	CLK_SARADC_DIV_CON_WIDTH= 10,
 
+	/* CLKSEL_CON23 */
+	ACLK_PERI_PLL_SEL_SHIFT		= 15,
+	ACLK_PERI_PLL_SEL_MASK		= 1 << ACLK_PERI_PLL_SEL_SHIFT,
+	ACLK_PERI_PLL_SEL_GPLL		= 0,
+	ACLK_PERI_PLL_SEL_DPLL		= 1,
+	PCLK_PERI_DIV_CON_SHIFT		= 10,
+	PCLK_PERI_DIV_CON_MASK		= 0x1f << PCLK_PERI_DIV_CON_SHIFT,
+	HCLK_PERI_DIV_CON_SHIFT		= 5,
+	HCLK_PERI_DIV_CON_MASK		= 0x1f << HCLK_PERI_DIV_CON_SHIFT,
+	ACLK_PERI_DIV_CON_SHIFT		= 0,
+	ACLK_PERI_DIV_CON_MASK		= 0x1f,
+	PERI_DIV_CON_WIDTH		= 5,
+
 	/* CLKSEL24_CON */
 	MAC_PLL_SEL_SHIFT	= 12,
 	MAC_PLL_SEL_MASK	= 1 << MAC_PLL_SEL_SHIFT,
@@ -105,6 +180,17 @@
 	MAC_CLK_DIV_MASK	= 0x1f,
 	MAC_CLK_DIV_SHIFT	= 0,
 
+	/* CLKSEL25_CON */
+	EMMC_PLL_SEL_SHIFT	= 12,
+	EMMC_PLL_SEL_MASK	= 3 << EMMC_PLL_SEL_SHIFT,
+	EMMC_PLL_SEL_DPLL	= 0,
+	EMMC_PLL_SEL_GPLL,
+	EMMC_PLL_SEL_OSC,
+
+	/* CLKSEL26_CON */
+	EMMC_CLK_DIV_SHIFT	= 8,
+	EMMC_CLK_DIV_MASK	= 0xff << EMMC_CLK_DIV_SHIFT,
+
 	/* CLKSEL27_CON */
 	SFC_PLL_SEL_SHIFT	= 7,
 	SFC_PLL_SEL_MASK	= 1 << SFC_PLL_SEL_SHIFT,
@@ -112,5 +198,61 @@
 	SFC_PLL_SEL_GPLL	= 1,
 	SFC_CLK_DIV_SHIFT	= 0,
 	SFC_CLK_DIV_MASK	= 0x3f << SFC_CLK_DIV_SHIFT,
+
+	/* CLKSEL28_CON */
+	ACLK_VIO1_PLL_SEL_SHIFT		= 14,
+	ACLK_VIO1_PLL_SEL_MASK		= 3 << ACLK_VIO1_PLL_SEL_SHIFT,
+	VIO_PLL_SEL_DPLL		= 0,
+	VIO_PLL_SEL_GPLL		= 1,
+	ACLK_VIO1_CLK_DIV_SHIFT		= 8,
+	ACLK_VIO1_CLK_DIV_MASK		= 0x1f << ACLK_VIO1_CLK_DIV_SHIFT,
+	CLK_VIO_DIV_CON_WIDTH		= 5,
+	ACLK_VIO0_PLL_SEL_SHIFT		= 6,
+	ACLK_VIO0_PLL_SEL_MASK		= 3 << ACLK_VIO0_PLL_SEL_SHIFT,
+	ACLK_VIO0_CLK_DIV_SHIFT		= 0,
+	ACLK_VIO0_CLK_DIV_MASK		= 0x1f << ACLK_VIO0_CLK_DIV_SHIFT,
+
+	/* CLKSEL29_CON */
+	PCLK_VIO_CLK_DIV_SHIFT		= 8,
+	PCLK_VIO_CLK_DIV_MASK		= 0x1f << PCLK_VIO_CLK_DIV_SHIFT,
+	HCLK_VIO_CLK_DIV_SHIFT		= 0,
+	HCLK_VIO_CLK_DIV_MASK		= 0x1f << HCLK_VIO_CLK_DIV_SHIFT,
+
+	/* CLKSEL32_CON */
+	DCLK_VOP_SEL_SHIFT		= 7,
+	DCLK_VOP_SEL_MASK		= 1 << DCLK_VOP_SEL_SHIFT,
+	DCLK_VOP_SEL_HDMI		= 0,
+	DCLK_VOP_SEL_PLL		= 1,
+	DCLK_VOP_PLL_SEL_SHIFT		= 6,
+	DCLK_VOP_PLL_SEL_MASK		= 1 << DCLK_VOP_PLL_SEL_SHIFT,
+	DCLK_VOP_PLL_SEL_GPLL		= 0,
+	DCLK_VOP_PLL_SEL_DPLL		= 1,
+	DCLK_VOP_CLK_DIV_SHIFT		= 0,
+	DCLK_VOP_CLK_DIV_MASK		= 0x3f << DCLK_VOP_CLK_DIV_SHIFT,
+	DCLK_VOP_DIV_CON_WIDTH		= 6,
+
+	/* SOFTRST1_CON*/
+	DDRPHY_SRSTN_CLKDIV_REQ_SHIFT	= 0,
+	DDRPHY_SRSTN_CLKDIV_REQ		= 1,
+	DDRPHY_SRSTN_CLKDIV_DIS		= 0,
+	DDRPHY_SRSTN_CLKDIV_REQ_MASK	= 1 << DDRPHY_SRSTN_CLKDIV_REQ_SHIFT,
+	DDRPHY_SRSTN_REQ_SHIFT		= 1,
+	DDRPHY_SRSTN_REQ		= 1,
+	DDRPHY_SRSTN_DIS		= 0,
+	DDRPHY_SRSTN_REQ_MASK		= 1 << DDRPHY_SRSTN_REQ_SHIFT,
+	DDRPHY_PSRSTN_REQ_SHIFT		= 2,
+	DDRPHY_PSRSTN_REQ		= 1,
+	DDRPHY_PSRSTN_DIS		= 0,
+	DDRPHY_PSRSTN_REQ_MASK		= 1 << DDRPHY_PSRSTN_REQ_SHIFT,
+
+	/* SOFTRST2_CON*/
+	DDRUPCTL_PSRSTN_REQ_SHIFT	= 0,
+	DDRUPCTL_PSRSTN_REQ		= 1,
+	DDRUPCTL_PSRSTN_DIS		= 0,
+	DDRUPCTL_PSRSTN_REQ_MASK	= 1 << DDRUPCTL_PSRSTN_REQ_SHIFT,
+	DDRUPCTL_NSRSTN_REQ_SHIFT	= 1,
+	DDRUPCTL_NSRSTN_REQ		= 1,
+	DDRUPCTL_NSRSTN_DIS		= 0,
+	DDRUPCTL_NSRSTN_REQ_MASK	= 1 << DDRUPCTL_NSRSTN_REQ_SHIFT,
 };
 #endif
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3188.h b/arch/arm/include/asm/arch-rockchip/grf_rk3188.h
index 28a159c..d051976 100644
--- a/arch/arm/include/asm/arch-rockchip/grf_rk3188.h
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3188.h
@@ -205,4 +205,46 @@
 	ATO_AE_SHIFT		= 0,
 	ATO_AE_MASK		= 1,
 };
+
+/* GRF_UOC_CON0 */
+enum {
+	SIDDQ_SHIFT		= 13,
+	SIDDQ_MASK		= 1 << SIDDQ_SHIFT,
+
+	BYPASSSEL_SHIFT		= 9,
+	BYPASSSEL_MASK		= 1 << BYPASSSEL_SHIFT,
+
+	BYPASSDMEN_SHIFT	= 8,
+	BYPASSDMEN_MASK		= 1 << BYPASSDMEN_SHIFT,
+
+	UOC_DISABLE_SHIFT	= 4,
+	UOC_DISABLE_MASK	= 1 << UOC_DISABLE_SHIFT,
+
+	COMMON_ON_N_SHIFT	= 0,
+	COMMON_ON_N_MASK	= 1 << COMMON_ON_N_SHIFT,
+};
+
+/* GRF_UOC_CON2 */
+enum {
+	SOFT_CON_SEL_SHIFT	= 2,
+	SOFT_CON_SEL_MASK	= 1 << SOFT_CON_SEL_SHIFT,
+};
+
+/* GRF_UOC0_CON3 */
+enum {
+	TERMSEL_FULLSPEED_SHIFT	= 5,
+	TERMSEL_FULLSPEED_MASK	= 1 << TERMSEL_FULLSPEED_SHIFT,
+
+	XCVRSELECT_SHIFT	= 3,
+	XCVRSELECT_FSTRANSC	= 1,
+	XCVRSELECT_MASK		= 3 << XCVRSELECT_SHIFT,
+
+	OPMODE_SHIFT		= 1,
+	OPMODE_NODRIVING	= 1,
+	OPMODE_MASK		= 3 << OPMODE_SHIFT,
+
+	SUSPENDN_SHIFT		= 0,
+	SUSPENDN_MASK		= 1 << SUSPENDN_SHIFT,
+};
+
 #endif
diff --git a/arch/arm/lib/crt0_aarch64_efi.S b/arch/arm/lib/crt0_aarch64_efi.S
index 0db4360..cb205fa 100644
--- a/arch/arm/lib/crt0_aarch64_efi.S
+++ b/arch/arm/lib/crt0_aarch64_efi.S
@@ -28,13 +28,13 @@
 	.short	2				/* nr_sections */
 	.long	0				/* TimeDateStamp */
 	.long	0				/* PointerToSymbolTable */
-	.long	1				/* NumberOfSymbols */
+	.long	0				/* NumberOfSymbols */
 	.short	section_table - optional_header	/* SizeOfOptionalHeader */
-	/*
-	 * Characteristics: IMAGE_FILE_DEBUG_STRIPPED |
-	 * IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LINE_NUMS_STRIPPED
-	 */
-	.short	0x206
+	/* Characteristics */
+	.short	(IMAGE_FILE_EXECUTABLE_IMAGE | \
+		 IMAGE_FILE_LINE_NUMS_STRIPPED | \
+		 IMAGE_FILE_LOCAL_SYMS_STRIPPED | \
+		 IMAGE_FILE_DEBUG_STRIPPED)
 optional_header:
 	.short	0x20b				/* PE32+ format */
 	.byte	0x02				/* MajorLinkerVersion */
diff --git a/arch/arm/lib/crt0_arm_efi.S b/arch/arm/lib/crt0_arm_efi.S
index 23db49f..5470e2f 100644
--- a/arch/arm/lib/crt0_arm_efi.S
+++ b/arch/arm/lib/crt0_arm_efi.S
@@ -27,16 +27,16 @@
 	.short	2				/* nr_sections */
 	.long	0				/* TimeDateStamp */
 	.long	0				/* PointerToSymbolTable */
-	.long	1				/* NumberOfSymbols */
+	.long	0				/* NumberOfSymbols */
 	.short	section_table - optional_header	/* SizeOfOptionalHeader */
-	/*
-	 * Characteristics: IMAGE_FILE_32BIT_MACHINE |
-	 * IMAGE_FILE_DEBUG_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE |
-	 * IMAGE_FILE_LINE_NUMS_STRIPPED
-	 */
-	.short	0x306
+	/* Characteristics */
+	.short	(IMAGE_FILE_EXECUTABLE_IMAGE | \
+		 IMAGE_FILE_LINE_NUMS_STRIPPED | \
+		 IMAGE_FILE_LOCAL_SYMS_STRIPPED | \
+		 IMAGE_FILE_32BIT_MACHINE | \
+		 IMAGE_FILE_DEBUG_STRIPPED)
 optional_header:
-	.short	0x10b				/* PE32+ format */
+	.short	0x10b				/* PE32 format */
 	.byte	0x02				/* MajorLinkerVersion */
 	.byte	0x14				/* MinorLinkerVersion */
 	.long	_edata - _start			/* SizeOfCode */
diff --git a/arch/arm/mach-k3/Makefile b/arch/arm/mach-k3/Makefile
index 406dda3..bd4ab36 100644
--- a/arch/arm/mach-k3/Makefile
+++ b/arch/arm/mach-k3/Makefile
@@ -5,5 +5,5 @@
 
 obj-$(CONFIG_SOC_K3_AM6) += am6_init.o
 obj-$(CONFIG_ARM64) += arm64-mmu.o
-obj-$(CONFIG_CPU_V7R) += r5_mpu.o
+obj-$(CONFIG_CPU_V7R) += r5_mpu.o lowlevel_init.o
 obj-y += common.o
diff --git a/arch/arm/mach-k3/lowlevel_init.S b/arch/arm/mach-k3/lowlevel_init.S
new file mode 100644
index 0000000..70c5d1c
--- /dev/null
+++ b/arch/arm/mach-k3/lowlevel_init.S
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ *	Lokesh Vutla <lokeshvutla@ti.com>
+ */
+
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+
+	mrc	p15, 0, r0, c0, c0, 5		@ Read MPIDR
+	and	r0, #0xff
+	cmp	r0, #0x0
+	bne	park_cpu
+	bx	lr
+park_cpu:
+	wfi
+	b	park_cpu
+
+ENDPROC(lowlevel_init)
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
new file mode 100644
index 0000000..7a733e9
--- /dev/null
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -0,0 +1,39 @@
+if ARCH_MEDIATEK
+
+config SYS_SOC
+	default "mediatek"
+
+config SYS_VENDOR
+	default "mediatek"
+
+choice
+	prompt "MediaTek board select"
+
+config TARGET_MT7623
+	bool "MediaTek MT7623 SoC"
+	select CPU_V7A
+	select ARCH_MISC_INIT
+	help
+	  The MediaTek MT7623 is a ARM-based SoC with a quad-core Cortex-A7
+	  including NEON and GPU, Mali-450 graphics, several DDR3 options,
+	  crypto engine, built-in Wi-Fi / Bluetooth combo chip, JPEG decoder,
+	  video interfaces supporting HDMI and MIPI, and video codec support.
+	  Peripherals include Gigabit Ethernet, switch, USB3.0 and OTG, PCIe,
+	  I2S, PCM, S/PDIF, UART, SPI, I2C, IR TX/RX, and PWM.
+
+config TARGET_MT7629
+	bool "MediaTek MT7629 SoC"
+	select CPU_V7A
+	select SPL
+	select ARCH_MISC_INIT
+	help
+	  The MediaTek MT7629 is a ARM-based SoC with a dual-core Cortex-A7
+	  including DDR3, crypto engine, 3x3 11n/ac Wi-Fi, Gigabit Ethernet,
+	  switch, USB3.0, PCIe, UART, SPI, I2C and PWM.
+
+endchoice
+
+source "board/mediatek/mt7623/Kconfig"
+source "board/mediatek/mt7629/Kconfig"
+
+endif
diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
new file mode 100644
index 0000000..b5d3a37
--- /dev/null
+++ b/arch/arm/mach-mediatek/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier:	GPL-2.0
+
+obj-y	+= cpu.o
+obj-$(CONFIG_SPL_BUILD)	+= spl.o
+
+obj-$(CONFIG_TARGET_MT7623) += mt7623/
+obj-$(CONFIG_TARGET_MT7629) += mt7629/
diff --git a/arch/arm/mach-mediatek/cpu.c b/arch/arm/mach-mediatek/cpu.c
new file mode 100644
index 0000000..b37e299
--- /dev/null
+++ b/arch/arm/mach-mediatek/cpu.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <wdt.h>
+#include <dm/uclass-internal.h>
+
+int arch_misc_init(void)
+{
+	struct udevice *wdt;
+	int ret;
+
+	ret = uclass_first_device_err(UCLASS_WDT, &wdt);
+	if (!ret)
+		wdt_stop(wdt);
+
+	return 0;
+}
+
+int arch_cpu_init(void)
+{
+	icache_enable();
+
+	return 0;
+}
+
+void enable_caches(void)
+{
+	/* Enable D-cache. I-cache is already enabled in start.S */
+	dcache_enable();
+}
diff --git a/arch/arm/mach-mediatek/init.h b/arch/arm/mach-mediatek/init.h
new file mode 100644
index 0000000..1d896fb
--- /dev/null
+++ b/arch/arm/mach-mediatek/init.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef __MEDIATEK_INIT_H_
+#define __MEDIATEK_INIT_H_
+
+extern int mtk_soc_early_init(void);
+
+#endif /* __MEDIATEK_INIT_H_ */
diff --git a/arch/arm/mach-mediatek/mt7623/Makefile b/arch/arm/mach-mediatek/mt7623/Makefile
new file mode 100644
index 0000000..007eb4a
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7623/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier:	GPL-2.0
+
+obj-y += init.o
+obj-y += lowlevel_init.o
diff --git a/arch/arm/mach-mediatek/mt7623/init.c b/arch/arm/mach-mediatek/mt7623/init.c
new file mode 100644
index 0000000..0ee8c66
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7623/init.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#include <common.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+#include <asm/arch/misc.h>
+
+#include "preloader.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct boot_argument *preloader_param;
+
+int mtk_soc_early_init(void)
+{
+	return 0;
+}
+
+int dram_init(void)
+{
+	u32 i;
+
+	if (((size_t)preloader_param >= CONFIG_SYS_SDRAM_BASE) &&
+	    ((size_t)preloader_param % sizeof(size_t) == 0) &&
+	    preloader_param->magic == BOOT_ARGUMENT_MAGIC &&
+	    preloader_param->dram_rank_num <=
+	    ARRAY_SIZE(preloader_param->dram_rank_size)) {
+		gd->ram_size = 0;
+
+		for (i = 0; i < preloader_param->dram_rank_num; i++)
+			gd->ram_size += preloader_param->dram_rank_size[i];
+	} else {
+		gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE,
+					    SZ_2G);
+	}
+
+	return 0;
+}
+
+int print_cpuinfo(void)
+{
+	void __iomem *chipid;
+	u32 swver;
+
+	chipid = ioremap(VER_BASE, VER_SIZE);
+	swver = readl(chipid + APSW_VER);
+
+	printf("CPU:   MediaTek MT7623 E%d\n", (swver & 0xf) + 1);
+
+	return 0;
+}
diff --git a/arch/arm/mach-mediatek/mt7623/lowlevel_init.S b/arch/arm/mach-mediatek/mt7623/lowlevel_init.S
new file mode 100644
index 0000000..afb9476
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7623/lowlevel_init.S
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#include <linux/linkage.h>
+
+.extern	preloader_param
+
+ENTRY(save_boot_params)
+	ldr	r6, =preloader_param
+	str	r4, [r6]
+	b	save_boot_params_ret
+ENDPROC(save_boot_params)
+
+ENTRY(lowlevel_init)
+	/* enable SMP bit */
+	mrc	p15, 0, r0, c1, c0, 1
+	orr	r0, r0, #0x40
+	mcr	p15, 0, r0, c1, c0, 1
+	mov	pc, lr
+ENDPROC(lowlevel_init)
diff --git a/arch/arm/mach-mediatek/mt7623/preloader.h b/arch/arm/mach-mediatek/mt7623/preloader.h
new file mode 100644
index 0000000..2d2c71a
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7623/preloader.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef __PRELOADER_H_
+#define __PRELOADER_H_
+
+enum forbidden_mode {
+	F_FACTORY_MODE = 0x0001
+};
+
+union lk_hdr {
+	struct {
+		u32 magic;
+		u32 size;
+		char name[32];
+		u32 loadaddr;
+	};
+
+	u8 data[512];
+};
+
+struct sec_limit {
+	unsigned int magic_num;
+	enum forbidden_mode forbid_mode;
+};
+
+enum bootmode {
+	NORMAL_BOOT = 0,
+	META_BOOT = 1,
+	RECOVERY_BOOT = 2,
+	SW_REBOOT = 3,
+	FACTORY_BOOT = 4,
+	ADVMETA_BOOT = 5,
+	ATE_FACTORY_BOOT = 6,
+	ALARM_BOOT = 7,
+
+	KERNEL_POWER_OFF_CHARGING_BOOT = 8,
+	LOW_POWER_OFF_CHARGING_BOOT = 9,
+
+	FAST_BOOT = 99,
+	DOWNLOAD_BOOT = 100,
+	UNKNOWN_BOOT
+};
+
+enum boot_reason {
+	BR_POWER_KEY = 0,
+	BR_USB,
+	BR_RTC,
+	BR_WDT,
+	BR_WDT_BY_PASS_PWK,
+	BR_TOOL_BY_PASS_PWK,
+	BR_2SEC_REBOOT,
+	BR_UNKNOWN
+};
+
+enum meta_com_type {
+	META_UNKNOWN_COM = 0,
+	META_UART_COM,
+	META_USB_COM
+};
+
+struct da_info_t {
+	u32 addr;
+	u32 arg1;
+	u32 arg2;
+	u32 len;
+	u32 sig_len;
+};
+
+struct boot_argument {
+	u32 magic;
+	enum bootmode boot_mode;
+	u32 e_flag;
+	u32 log_port;
+	u32 log_baudrate;
+	u8 log_enable;
+	u8 part_num;
+	u8 reserved[2];
+	u32 dram_rank_num;
+	u32 dram_rank_size[4];
+	u32 boot_reason;
+	enum meta_com_type meta_com_type;
+	u32 meta_com_id;
+	u32 boot_time;
+	struct da_info_t da_info;
+	struct sec_limit sec_limit;
+	union lk_hdr *part_info;
+	u8 md_type[4];
+	u32 ddr_reserve_enable;
+	u32 ddr_reserve_success;
+	u32 chip_ver;
+	char pl_version[8];
+};
+
+#define BOOT_ARGUMENT_MAGIC	0x504c504c
+
+#endif /* __PRELOADER_H_ */
diff --git a/arch/arm/mach-mediatek/mt7629/Makefile b/arch/arm/mach-mediatek/mt7629/Makefile
new file mode 100644
index 0000000..007eb4a
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7629/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier:	GPL-2.0
+
+obj-y += init.o
+obj-y += lowlevel_init.o
diff --git a/arch/arm/mach-mediatek/mt7629/init.c b/arch/arm/mach-mediatek/mt7629/init.c
new file mode 100644
index 0000000..ba91a6e
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7629/init.c
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <ram.h>
+#include <asm/arch/misc.h>
+#include <asm/sections.h>
+#include <dm/uclass.h>
+#include <linux/io.h>
+
+#include <dt-bindings/clock/mt7629-clk.h>
+
+#define L2_CFG_BASE		0x10200000
+#define L2_CFG_SIZE		0x1000
+#define L2_SHARE_CFG_MP0	0x7f0
+#define L2_SHARE_MODE_OFF	BIT(8)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int mtk_pll_early_init(void)
+{
+	unsigned long pll_rates[] = {
+		[CLK_APMIXED_ARMPLL] = 1250000000,
+		[CLK_APMIXED_MAINPLL] = 1120000000,
+		[CLK_APMIXED_UNIV2PLL] = 1200000000,
+		[CLK_APMIXED_ETH1PLL] = 500000000,
+		[CLK_APMIXED_ETH2PLL] = 700000000,
+		[CLK_APMIXED_SGMIPLL] = 650000000,
+	};
+	struct udevice *dev;
+	int ret, i;
+
+	ret = uclass_get_device_by_driver(UCLASS_CLK,
+			DM_GET_DRIVER(mtk_clk_apmixedsys), &dev);
+	if (ret)
+		return ret;
+
+	/* configure default rate then enable apmixedsys */
+	for (i = 0; i < ARRAY_SIZE(pll_rates); i++) {
+		struct clk clk = { .id = i, .dev = dev };
+
+		ret = clk_set_rate(&clk, pll_rates[i]);
+		if (ret)
+			return ret;
+
+		ret = clk_enable(&clk);
+		if (ret)
+			return ret;
+	}
+
+	/* setup mcu bus */
+	ret = uclass_get_device_by_driver(UCLASS_SYSCON,
+			DM_GET_DRIVER(mtk_mcucfg), &dev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int mtk_soc_early_init(void)
+{
+	struct udevice *dev;
+	int ret;
+
+	/* initialize early clocks */
+	ret = mtk_pll_early_init();
+	if (ret)
+		return ret;
+
+	ret = uclass_first_device_err(UCLASS_RAM, &dev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int mach_cpu_init(void)
+{
+	void __iomem *base;
+
+	base = ioremap(L2_CFG_BASE, L2_CFG_SIZE);
+
+	/* disable L2C shared mode */
+	writel(L2_SHARE_MODE_OFF, base + L2_SHARE_CFG_MP0);
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	struct ram_info ram;
+	struct udevice *dev;
+	int ret;
+
+	ret = uclass_first_device_err(UCLASS_RAM, &dev);
+	if (ret)
+		return ret;
+
+	ret = ram_get_info(dev, &ram);
+	if (ret)
+		return ret;
+
+	debug("RAM init base=%lx, size=%x\n", ram.base, ram.size);
+
+	gd->ram_size = ram.size;
+
+	return 0;
+}
+
+int print_cpuinfo(void)
+{
+	void __iomem *chipid;
+	u32 hwcode, swver;
+
+	chipid = ioremap(VER_BASE, VER_SIZE);
+	hwcode = readl(chipid + APHW_CODE);
+	swver = readl(chipid + APSW_VER);
+
+	printf("CPU:   MediaTek MT%04x E%d\n", hwcode, (swver & 0xf) + 1);
+
+	return 0;
+}
diff --git a/arch/arm/mach-mediatek/mt7629/lowlevel_init.S b/arch/arm/mach-mediatek/mt7629/lowlevel_init.S
new file mode 100644
index 0000000..90dd4ea
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7629/lowlevel_init.S
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+
+#ifndef CONFIG_SPL_BUILD
+	/* Return to U-Boot via saved link register */
+	mov	pc, lr
+#else
+	/*
+	 * Arch timer :
+	 * set CNTFRQ = 20Mhz, set CNTVOFF = 0
+	 */
+	movw	r0, #0x2d00
+	movt	r0, #0x131
+	mcr	p15, 0, r0, c14, c0, 0
+
+	/* enable SMP bit */
+	mrc	p15, 0, r0, c1, c0, 1
+	orr	r0, r0, #0x40
+	mcr	p15, 0, r0, c1, c0, 1
+
+	/* if MP core, handle secondary cores */
+	mrc	p15, 0, r0, c0, c0, 5
+	ands	r1, r0, #0x40000000
+	bne	go			@ Go if UP
+	ands	r0, r0, #0x0f
+	beq	go			@ Go if core0 on primary core tile
+	b	secondary
+
+go:
+	/* master CPU */
+	mov	pc, lr
+
+secondary:
+	/* read slave CPU number into r0 firstly */
+	mrc	p15, 0, r0, c0, c0, 5
+	and	r0, r0, #0x0f
+
+loop:
+	dsb
+	isb
+	wfi				@Zzz...
+	b	loop
+#endif
+ENDPROC(lowlevel_init)
diff --git a/arch/arm/mach-mediatek/spl.c b/arch/arm/mach-mediatek/spl.c
new file mode 100644
index 0000000..9b3590f
--- /dev/null
+++ b/arch/arm/mach-mediatek/spl.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <spl.h>
+
+#include "init.h"
+
+void board_init_f(ulong dummy)
+{
+	int ret;
+
+	ret = spl_early_init();
+	if (ret)
+		hang();
+
+	/* enable console uart printing */
+	preloader_console_init();
+
+	/* soc early initialization */
+	ret = mtk_soc_early_init();
+	if (ret)
+		hang();
+}
+
+u32 spl_boot_device(void)
+{
+#if defined(CONFIG_SPL_SPI_SUPPORT)
+	return BOOT_DEVICE_SPI;
+#elif defined(CONFIG_SPL_MMC_SUPPORT)
+	return BOOT_DEVICE_MMC1;
+#elif defined(CONFIG_SPL_NAND_SUPPORT)
+	return BOOT_DEVICE_NAND;
+#elif defined(CONFIG_SPL_NOR_SUPPORT)
+	return BOOT_DEVICE_NOR;
+#else
+	return BOOT_DEVICE_NONE;
+#endif
+}
diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig
index cc94344..11077bc 100644
--- a/arch/arm/mach-meson/Kconfig
+++ b/arch/arm/mach-meson/Kconfig
@@ -1,89 +1,49 @@
 if ARCH_MESON
 
-config MESON_GXBB
-	bool "Support Meson GXBaby"
-	select ARM64
-	select CLK
-	select DM
-	select DM_SERIAL
-	imply CMD_DM
-	help
-	  The Amlogic Meson GXBaby (S905) is an ARM SoC with a
-	  quad-core Cortex-A53 CPU and a Mali-450 GPU.
-
-config MESON_GXL
-	bool "Support Meson GXL"
+config MESON64_COMMON
+	bool
 	select ARM64
 	select CLK
 	select DM
 	select DM_SERIAL
+	select SYSCON
+	select REGMAP
+	select BOARD_LATE_INIT
 	imply CMD_DM
-	help
-	  The Amlogic Meson GXL (S905X and S905D) is an ARM SoC with a
-	  quad-core Cortex-A53 CPU and a Mali-450 GPU.
-
-config MESON_GXM
-	bool "Support Meson GXM"
-	select ARM64
-	select CLK
-	select DM
-	select DM_SERIAL
-	help
-	  The Amlogic Meson GXM (S912) is an ARM SoC with an
-	  octo-core Cortex-A53 CPU and a Mali-T860 GPU.
-
-if MESON_GXBB
-
-config TARGET_ODROID_C2
-	bool "ODROID-C2"
-	help
-	  ODROID-C2 is a single board computer based on Meson GXBaby
-	  with 2 GiB of RAM, Gigabit Ethernet, HDMI, 4 USB, micro-SD
-	  slot, eMMC, IR receiver and a 40-pin GPIO header.
 
-config TARGET_NANOPI_K2
-	bool "NANOPI_K2"
-	help
-	  NANOPI_K2 is a single board computer based on Meson GXBaby
-	  with 2 GiB of RAM, Gigabit Ethernet,AP6212 Wifi, HDMI, 4 USB,
-	  micro-SD slot, eMMC, IR receiver and a 40-pin GPIO header.
-endif
+config MESON_GX
+	bool
+	select MESON64_COMMON
 
-if MESON_GXL
+choice
+	prompt "Platform select"
+	default MESON_GXBB
 
-config TARGET_P212
-	bool "P212"
+config MESON_GXBB
+	bool "GXBB"
+	select MESON_GX
 	help
-	  P212 is a reference dessign board based on Meson GXL S905X SoC
-	  with 2 GiB of RAM, Ethernet, HDMI, 2 USB, micro-SD slot,
-	  eMMC, IR receiver, CVBS+Audio jack and a SDIO WiFi module.
+	  Select this if your SoC is an S905
 
-config TARGET_LIBRETECH_CC
-	bool "LIBRETECH-CC"
+config MESON_GXL
+	bool "GXL"
+	select MESON_GX
 	help
-	  LibreTech CC is a single board computer based on Meson GXL
-	  with 2 GiB of RAM, Ethernet, HDMI, 4 USB, micro-SD slot,
-	  eMMC, IR receiver and a 40-pin GPIO header.
+	  Select this if your SoC is an S905X/D or S805X
 
-config TARGET_KHADAS_VIM
-	bool "KHADAS-VIM"
+config MESON_GXM
+	bool "GXM"
+	select MESON_GX
 	help
-	  Khadas VIM is a single board computer based on Meson GXL
-	  with 2 GiB of RAM, Ethernet, HDMI, 4 USB, micro-SD slot,
-	  eMMC, IR receiver and a 40-pin GPIO header.
+	  Select this if your SoC is an S912
 
-endif
-
-if MESON_GXM
-
-config TARGET_KHADAS_VIM2
-	bool "KHADAS-VIM2"
+config MESON_AXG
+	bool "AXG"
+	select MESON64_COMMON
 	help
-	  Khadas VIM2 is a single board computer based on Meson GXM
-	  with 2/3 GiB of RAM, Ethernet, HDMI, 4 USB, micro-SD slot,
-	  eMMC, IR receiver and a 40-pin GPIO header.
+		Select this if your SoC is an A113X/D
 
-endif
+endchoice
 
 config SYS_SOC
 	default "meson"
@@ -91,16 +51,32 @@
 config SYS_MALLOC_F_LEN
 	default 0x1000
 
-source "board/amlogic/odroid-c2/Kconfig"
-
-source "board/amlogic/nanopi-k2/Kconfig"
-
-source "board/amlogic/p212/Kconfig"
-
-source "board/amlogic/libretech-cc/Kconfig"
+config SYS_VENDOR
+	string "Vendor name"
+	default "amlogic"
+	help
+	  This option contains information about board name.
+	  Based on this option board/<CONFIG_SYS_VENDOR>/<CONFIG_SYS_BOARD> will
+	  be used.
 
-source "board/amlogic/khadas-vim/Kconfig"
+config SYS_BOARD
+	string "Board name"
+	default "odroid-c2" if MESON_GXBB
+	default "p212" if MESON_GXL
+	default "q200" if MESON_GXM
+	default "s400" if MESON_AXG
+	default ""
+	help
+	  This option contains information about board name.
+	  Based on this option board/<CONFIG_SYS_VENDOR>/<CONFIG_SYS_BOARD> will
+	  be used.
 
-source "board/amlogic/khadas-vim2/Kconfig"
+config SYS_CONFIG_NAME
+	string "Board configuration name"
+	default "meson64"
+	help
+	  This option contains information about board configuration name.
+	  Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
+	  will be used for board configuration.
 
 endif
diff --git a/arch/arm/mach-meson/Makefile b/arch/arm/mach-meson/Makefile
index 8ad9b3e..b716e1a 100644
--- a/arch/arm/mach-meson/Makefile
+++ b/arch/arm/mach-meson/Makefile
@@ -2,4 +2,6 @@
 #
 # Copyright (c) 2016 Beniamino Galvani <b.galvani@gmail.com>
 
-obj-y += board.o sm.o eth.o
+obj-y += board-common.o sm.o
+obj-$(CONFIG_MESON_GX) += board-gx.o
+obj-$(CONFIG_MESON_AXG) += board-axg.o
diff --git a/arch/arm/mach-meson/board-axg.c b/arch/arm/mach-meson/board-axg.c
new file mode 100644
index 0000000..173905e
--- /dev/null
+++ b/arch/arm/mach-meson/board-axg.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
+ * (C) Copyright 2018 Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <common.h>
+#include <asm/arch/boot.h>
+#include <asm/arch/eth.h>
+#include <asm/arch/axg.h>
+#include <asm/arch/mem.h>
+#include <asm/io.h>
+#include <asm/armv8/mmu.h>
+#include <linux/sizes.h>
+#include <phy.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int meson_get_boot_device(void)
+{
+	return readl(AXG_AO_SEC_GP_CFG0) & AXG_AO_BOOT_DEVICE;
+}
+
+/* Configure the reserved memory zones exported by the secure registers
+ * into EFI and DTB reserved memory entries.
+ */
+void meson_init_reserved_memory(void *fdt)
+{
+	u64 bl31_size, bl31_start;
+	u64 bl32_size, bl32_start;
+	u32 reg;
+
+	/*
+	 * Get ARM Trusted Firmware reserved memory zones in :
+	 * - AO_SEC_GP_CFG3: bl32 & bl31 size in KiB, can be 0
+	 * - AO_SEC_GP_CFG5: bl31 physical start address, can be NULL
+	 * - AO_SEC_GP_CFG4: bl32 physical start address, can be NULL
+	 */
+	reg = readl(AXG_AO_SEC_GP_CFG3);
+
+	bl31_size = ((reg & AXG_AO_BL31_RSVMEM_SIZE_MASK)
+			>> AXG_AO_BL31_RSVMEM_SIZE_SHIFT) * SZ_1K;
+	bl32_size = (reg & AXG_AO_BL32_RSVMEM_SIZE_MASK) * SZ_1K;
+
+	bl31_start = readl(AXG_AO_SEC_GP_CFG5);
+	bl32_start = readl(AXG_AO_SEC_GP_CFG4);
+
+	/* Add BL31 reserved zone */
+	if (bl31_start && bl31_size)
+		meson_board_add_reserved_memory(fdt, bl31_start, bl31_size);
+
+	/* Add BL32 reserved zone */
+	if (bl32_start && bl32_size)
+		meson_board_add_reserved_memory(fdt, bl32_start, bl32_size);
+}
+
+phys_size_t get_effective_memsize(void)
+{
+	/* Size is reported in MiB, convert it in bytes */
+	return ((readl(AXG_AO_SEC_GP_CFG0) & AXG_AO_MEM_SIZE_MASK)
+			>> AXG_AO_MEM_SIZE_SHIFT) * SZ_1M;
+}
+
+static struct mm_region axg_mem_map[] = {
+	{
+		.virt = 0x0UL,
+		.phys = 0x0UL,
+		.size = 0x80000000UL,
+		.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
+	}, {
+		/* List terminator */
+		0,
+	}
+};
+
+struct mm_region *mem_map = axg_mem_map;
+
+/* Configure the Ethernet MAC with the requested interface mode
+ * with some optional flags.
+ */
+void meson_eth_init(phy_interface_t mode, unsigned int flags)
+{
+	switch (mode) {
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		/* Set RGMII mode */
+		setbits_le32(AXG_ETH_REG_0, AXG_ETH_REG_0_PHY_INTF_RGMII |
+			     AXG_ETH_REG_0_TX_PHASE(1) |
+			     AXG_ETH_REG_0_TX_RATIO(4) |
+			     AXG_ETH_REG_0_PHY_CLK_EN |
+			     AXG_ETH_REG_0_CLK_EN);
+		break;
+
+	case PHY_INTERFACE_MODE_RMII:
+		/* Set RMII mode */
+		out_le32(AXG_ETH_REG_0, AXG_ETH_REG_0_PHY_INTF_RMII |
+					AXG_ETH_REG_0_INVERT_RMII_CLK |
+					AXG_ETH_REG_0_CLK_EN);
+		break;
+
+	default:
+		printf("Invalid Ethernet interface mode\n");
+		return;
+	}
+
+	/* Enable power gate */
+	clrbits_le32(AXG_MEM_PD_REG_0, AXG_MEM_PD_REG_0_ETH_MASK);
+}
diff --git a/arch/arm/mach-meson/board-common.c b/arch/arm/mach-meson/board-common.c
new file mode 100644
index 0000000..8c41301
--- /dev/null
+++ b/arch/arm/mach-meson/board-common.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
+ */
+
+#include <common.h>
+#include <asm/arch/boot.h>
+#include <linux/libfdt.h>
+#include <linux/err.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/sm.h>
+#include <asm/armv8/mmu.h>
+#include <asm/unaligned.h>
+#include <efi_loader.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+__weak int board_init(void)
+{
+	return 0;
+}
+
+int dram_init(void)
+{
+	const fdt64_t *val;
+	int offset;
+	int len;
+
+	offset = fdt_path_offset(gd->fdt_blob, "/memory");
+	if (offset < 0)
+		return -EINVAL;
+
+	val = fdt_getprop(gd->fdt_blob, offset, "reg", &len);
+	if (len < sizeof(*val) * 2)
+		return -EINVAL;
+
+	/* Use unaligned access since cache is still disabled */
+	gd->ram_size = get_unaligned_be64(&val[1]);
+
+	return 0;
+}
+
+__weak int meson_ft_board_setup(void *blob, bd_t *bd)
+{
+	return 0;
+}
+
+int ft_board_setup(void *blob, bd_t *bd)
+{
+	meson_init_reserved_memory(blob);
+
+	return meson_ft_board_setup(blob, bd);
+}
+
+void meson_board_add_reserved_memory(void *fdt, u64 start, u64 size)
+{
+	int ret;
+
+	ret = fdt_add_mem_rsv(fdt, start, size);
+	if (ret)
+		printf("Could not reserve zone @ 0x%llx\n", start);
+
+	if (IS_ENABLED(CONFIG_EFI_LOADER)) {
+		efi_add_memory_map(start,
+				   ALIGN(size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT,
+				   EFI_RESERVED_MEMORY_TYPE, false);
+	}
+}
+
+static void meson_set_boot_source(void)
+{
+	const char *source;
+
+	switch (meson_get_boot_device()) {
+	case BOOT_DEVICE_EMMC:
+		source = "emmc";
+		break;
+
+	case BOOT_DEVICE_NAND:
+		source = "nand";
+		break;
+
+	case BOOT_DEVICE_SPI:
+		source = "spi";
+		break;
+
+	case BOOT_DEVICE_SD:
+		source = "sd";
+		break;
+
+	case BOOT_DEVICE_USB:
+		source = "usb";
+		break;
+
+	default:
+		source = "unknown";
+	}
+
+	env_set("boot_source", source);
+}
+
+__weak int meson_board_late_init(void)
+{
+	return 0;
+}
+
+int board_late_init(void)
+{
+	meson_set_boot_source();
+
+	return meson_board_late_init();
+}
+
+void reset_cpu(ulong addr)
+{
+	psci_system_reset();
+}
diff --git a/arch/arm/mach-meson/board-gx.c b/arch/arm/mach-meson/board-gx.c
new file mode 100644
index 0000000..e41552d
--- /dev/null
+++ b/arch/arm/mach-meson/board-gx.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
+ * (C) Copyright 2018 Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <common.h>
+#include <asm/arch/boot.h>
+#include <asm/arch/eth.h>
+#include <asm/arch/gx.h>
+#include <asm/arch/mem.h>
+#include <asm/io.h>
+#include <asm/armv8/mmu.h>
+#include <linux/sizes.h>
+#include <phy.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int meson_get_boot_device(void)
+{
+	return readl(GX_AO_SEC_GP_CFG0) & GX_AO_BOOT_DEVICE;
+}
+
+/* Configure the reserved memory zones exported by the secure registers
+ * into EFI and DTB reserved memory entries.
+ */
+void meson_init_reserved_memory(void *fdt)
+{
+	u64 bl31_size, bl31_start;
+	u64 bl32_size, bl32_start;
+	u32 reg;
+
+	/*
+	 * Get ARM Trusted Firmware reserved memory zones in :
+	 * - AO_SEC_GP_CFG3: bl32 & bl31 size in KiB, can be 0
+	 * - AO_SEC_GP_CFG5: bl31 physical start address, can be NULL
+	 * - AO_SEC_GP_CFG4: bl32 physical start address, can be NULL
+	 */
+	reg = readl(GX_AO_SEC_GP_CFG3);
+
+	bl31_size = ((reg & GX_AO_BL31_RSVMEM_SIZE_MASK)
+			>> GX_AO_BL31_RSVMEM_SIZE_SHIFT) * SZ_1K;
+	bl32_size = (reg & GX_AO_BL32_RSVMEM_SIZE_MASK) * SZ_1K;
+
+	bl31_start = readl(GX_AO_SEC_GP_CFG5);
+	bl32_start = readl(GX_AO_SEC_GP_CFG4);
+
+	/*
+	 * Early Meson GX Firmware revisions did not provide the reserved
+	 * memory zones in the registers, keep fixed memory zone handling.
+	 */
+	if (IS_ENABLED(CONFIG_MESON_GX) &&
+	    !reg && !bl31_start && !bl32_start) {
+		bl31_start = 0x10000000;
+		bl31_size = 0x200000;
+	}
+
+	/* Add first 16MiB reserved zone */
+	meson_board_add_reserved_memory(fdt, 0, GX_FIRMWARE_MEM_SIZE);
+
+	/* Add BL31 reserved zone */
+	if (bl31_start && bl31_size)
+		meson_board_add_reserved_memory(fdt, bl31_start, bl31_size);
+
+	/* Add BL32 reserved zone */
+	if (bl32_start && bl32_size)
+		meson_board_add_reserved_memory(fdt, bl32_start, bl32_size);
+}
+
+phys_size_t get_effective_memsize(void)
+{
+	/* Size is reported in MiB, convert it in bytes */
+	return ((readl(GX_AO_SEC_GP_CFG0) & GX_AO_MEM_SIZE_MASK)
+			>> GX_AO_MEM_SIZE_SHIFT) * SZ_1M;
+}
+
+static struct mm_region gx_mem_map[] = {
+	{
+		.virt = 0x0UL,
+		.phys = 0x0UL,
+		.size = 0xc0000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
+		.virt = 0xc0000000UL,
+		.phys = 0xc0000000UL,
+		.size = 0x30000000UL,
+		.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 = gx_mem_map;
+
+/* Configure the Ethernet MAC with the requested interface mode
+ * with some optional flags.
+ */
+void meson_eth_init(phy_interface_t mode, unsigned int flags)
+{
+	switch (mode) {
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		/* Set RGMII mode */
+		setbits_le32(GX_ETH_REG_0, GX_ETH_REG_0_PHY_INTF |
+			     GX_ETH_REG_0_TX_PHASE(1) |
+			     GX_ETH_REG_0_TX_RATIO(4) |
+			     GX_ETH_REG_0_PHY_CLK_EN |
+			     GX_ETH_REG_0_CLK_EN);
+		break;
+
+	case PHY_INTERFACE_MODE_RMII:
+		/* Set RMII mode */
+		out_le32(GX_ETH_REG_0, GX_ETH_REG_0_INVERT_RMII_CLK |
+					 GX_ETH_REG_0_CLK_EN);
+
+		/* Use GXL RMII Internal PHY */
+		if (IS_ENABLED(CONFIG_MESON_GXL) &&
+		    (flags & MESON_USE_INTERNAL_RMII_PHY)) {
+			writel(0x10110181, GX_ETH_REG_2);
+			writel(0xe40908ff, GX_ETH_REG_3);
+		}
+
+		break;
+
+	default:
+		printf("Invalid Ethernet interface mode\n");
+		return;
+	}
+
+	/* Enable power gate */
+	clrbits_le32(GX_MEM_PD_REG_0, GX_MEM_PD_REG_0_ETH_MASK);
+}
diff --git a/arch/arm/mach-meson/board.c b/arch/arm/mach-meson/board.c
deleted file mode 100644
index d6c6253..0000000
--- a/arch/arm/mach-meson/board.c
+++ /dev/null
@@ -1,130 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
- */
-
-#include <common.h>
-#include <linux/libfdt.h>
-#include <linux/err.h>
-#include <asm/arch/gx.h>
-#include <asm/arch/sm.h>
-#include <asm/armv8/mmu.h>
-#include <asm/unaligned.h>
-#include <linux/sizes.h>
-#include <efi_loader.h>
-#include <asm/io.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-int dram_init(void)
-{
-	const fdt64_t *val;
-	int offset;
-	int len;
-
-	offset = fdt_path_offset(gd->fdt_blob, "/memory");
-	if (offset < 0)
-		return -EINVAL;
-
-	val = fdt_getprop(gd->fdt_blob, offset, "reg", &len);
-	if (len < sizeof(*val) * 2)
-		return -EINVAL;
-
-	/* Use unaligned access since cache is still disabled */
-	gd->ram_size = get_unaligned_be64(&val[1]);
-
-	return 0;
-}
-
-phys_size_t get_effective_memsize(void)
-{
-	/* Size is reported in MiB, convert it in bytes */
-	return ((readl(GX_AO_SEC_GP_CFG0) & GX_AO_MEM_SIZE_MASK)
-			>> GX_AO_MEM_SIZE_SHIFT) * SZ_1M;
-}
-
-static void meson_board_add_reserved_memory(void *fdt, u64 start, u64 size)
-{
-	int ret;
-
-	ret = fdt_add_mem_rsv(fdt, start, size);
-	if (ret)
-		printf("Could not reserve zone @ 0x%llx\n", start);
-
-	if (IS_ENABLED(CONFIG_EFI_LOADER)) {
-		efi_add_memory_map(start,
-				   ALIGN(size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT,
-				   EFI_RESERVED_MEMORY_TYPE, false);
-	}
-}
-
-void meson_gx_init_reserved_memory(void *fdt)
-{
-	u64 bl31_size, bl31_start;
-	u64 bl32_size, bl32_start;
-	u32 reg;
-
-	/*
-	 * Get ARM Trusted Firmware reserved memory zones in :
-	 * - AO_SEC_GP_CFG3: bl32 & bl31 size in KiB, can be 0
-	 * - AO_SEC_GP_CFG5: bl31 physical start address, can be NULL
-	 * - AO_SEC_GP_CFG4: bl32 physical start address, can be NULL
-	 */
-
-	reg = readl(GX_AO_SEC_GP_CFG3);
-
-	bl31_size = ((reg & GX_AO_BL31_RSVMEM_SIZE_MASK)
-			>> GX_AO_BL31_RSVMEM_SIZE_SHIFT) * SZ_1K;
-	bl32_size = (reg & GX_AO_BL32_RSVMEM_SIZE_MASK) * SZ_1K;
-
-	bl31_start = readl(GX_AO_SEC_GP_CFG5);
-	bl32_start = readl(GX_AO_SEC_GP_CFG4);
-
-	/*
-	 * Early Meson GX Firmware revisions did not provide the reserved
-	 * memory zones in the registers, keep fixed memory zone handling.
-	 */
-	if (IS_ENABLED(CONFIG_MESON_GX) &&
-	    !reg && !bl31_start && !bl32_start) {
-		bl31_start = 0x10000000;
-		bl31_size = 0x200000;
-	}
-
-	/* Add first 16MiB reserved zone */
-	meson_board_add_reserved_memory(fdt, 0, GX_FIRMWARE_MEM_SIZE);
-
-	/* Add BL31 reserved zone */
-	if (bl31_start && bl31_size)
-		meson_board_add_reserved_memory(fdt, bl31_start, bl31_size);
-
-	/* Add BL32 reserved zone */
-	if (bl32_start && bl32_size)
-		meson_board_add_reserved_memory(fdt, bl32_start, bl32_size);
-}
-
-void reset_cpu(ulong addr)
-{
-	psci_system_reset();
-}
-
-static struct mm_region gx_mem_map[] = {
-	{
-		.virt = 0x0UL,
-		.phys = 0x0UL,
-		.size = 0xc0000000UL,
-		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
-			 PTE_BLOCK_INNER_SHARE
-	}, {
-		.virt = 0xc0000000UL,
-		.phys = 0xc0000000UL,
-		.size = 0x30000000UL,
-		.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 = gx_mem_map;
diff --git a/arch/arm/mach-meson/eth.c b/arch/arm/mach-meson/eth.c
deleted file mode 100644
index 8b28bc8..0000000
--- a/arch/arm/mach-meson/eth.c
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
-
-#include <common.h>
-#include <dm.h>
-#include <asm/io.h>
-#include <asm/arch/gx.h>
-#include <asm/arch/eth.h>
-#include <phy.h>
-
-/* Configure the Ethernet MAC with the requested interface mode
- * with some optional flags.
- */
-void meson_gx_eth_init(phy_interface_t mode, unsigned int flags)
-{
-	switch (mode) {
-	case PHY_INTERFACE_MODE_RGMII:
-	case PHY_INTERFACE_MODE_RGMII_ID:
-	case PHY_INTERFACE_MODE_RGMII_RXID:
-	case PHY_INTERFACE_MODE_RGMII_TXID:
-		/* Set RGMII mode */
-		setbits_le32(GX_ETH_REG_0, GX_ETH_REG_0_PHY_INTF |
-			     GX_ETH_REG_0_TX_PHASE(1) |
-			     GX_ETH_REG_0_TX_RATIO(4) |
-			     GX_ETH_REG_0_PHY_CLK_EN |
-			     GX_ETH_REG_0_CLK_EN);
-		break;
-
-	case PHY_INTERFACE_MODE_RMII:
-		/* Set RMII mode */
-		out_le32(GX_ETH_REG_0, GX_ETH_REG_0_INVERT_RMII_CLK |
-					 GX_ETH_REG_0_CLK_EN);
-
-		/* Use GXL RMII Internal PHY */
-		if (IS_ENABLED(CONFIG_MESON_GXL) &&
-		    (flags & MESON_GXL_USE_INTERNAL_RMII_PHY)) {
-			writel(0x10110181, GX_ETH_REG_2);
-			writel(0xe40908ff, GX_ETH_REG_3);
-		}
-
-		break;
-
-	default:
-		printf("Invalid Ethernet interface mode\n");
-		return;
-	}
-
-	/* Enable power gate */
-	clrbits_le32(GX_MEM_PD_REG_0, GX_MEM_PD_REG_0_ETH_MASK);
-}
diff --git a/arch/arm/mach-meson/sm.c b/arch/arm/mach-meson/sm.c
index 0bba5e4..a07b468 100644
--- a/arch/arm/mach-meson/sm.c
+++ b/arch/arm/mach-meson/sm.c
@@ -6,7 +6,6 @@
  */
 
 #include <common.h>
-#include <asm/arch/gx.h>
 #include <linux/kernel.h>
 
 #define FN_GET_SHARE_MEM_INPUT_BASE	0x82000020
diff --git a/arch/arm/mach-mvebu/cpu.c b/arch/arm/mach-mvebu/cpu.c
index 0d2d398..aa1be8e 100644
--- a/arch/arm/mach-mvebu/cpu.c
+++ b/arch/arm/mach-mvebu/cpu.c
@@ -261,6 +261,9 @@
 		case MV_88F68XX_A0_ID:
 			puts("A0");
 			break;
+		case MV_88F68XX_B0_ID:
+			puts("B0");
+			break;
 		default:
 			printf("?? (%x)", revid);
 			break;
diff --git a/arch/arm/mach-mvebu/include/mach/soc.h b/arch/arm/mach-mvebu/include/mach/soc.h
index 6e2e14e..01577f4 100644
--- a/arch/arm/mach-mvebu/include/mach/soc.h
+++ b/arch/arm/mach-mvebu/include/mach/soc.h
@@ -27,6 +27,7 @@
 /* A38x revisions */
 #define MV_88F68XX_Z1_ID	0x0
 #define MV_88F68XX_A0_ID	0x4
+#define MV_88F68XX_B0_ID	0xa
 
 /* TCLK Core Clock definition */
 #ifndef CONFIG_SYS_TCLK
diff --git a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h
index 50b2358..365332d 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h
+++ b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h
@@ -233,6 +233,7 @@
 /* A38x revisions */
 #define MV_88F68XX_Z1_ID		0x0
 #define MV_88F68XX_A0_ID		0x4
+#define MV_88F68XX_B0_ID		0xa
 /* A39x revisions */
 #define MV_88F69XX_Z1_ID		0x2
 
diff --git a/arch/arm/mach-rmobile/Kconfig b/arch/arm/mach-rmobile/Kconfig
index d82023a..c6e5f75 100644
--- a/arch/arm/mach-rmobile/Kconfig
+++ b/arch/arm/mach-rmobile/Kconfig
@@ -13,6 +13,11 @@
 	select ARM64
 	select PHY
 	select CMD_CACHE
+	imply CMD_FS_UUID
+	imply CMD_GPT
+	imply CMD_UUID
+	imply CMD_MMC_SWRITE if MMC
+	imply SUPPORT_EMMC_RPMB if MMC
 
 endchoice
 
diff --git a/arch/arm/mach-rmobile/cpu_info.c b/arch/arm/mach-rmobile/cpu_info.c
index c9ebc9f..65a9ca8 100644
--- a/arch/arm/mach-rmobile/cpu_info.c
+++ b/arch/arm/mach-rmobile/cpu_info.c
@@ -5,6 +5,7 @@
  */
 #include <common.h>
 #include <asm/io.h>
+#include <linux/ctype.h>
 
 /* R-Car Gen3 caches are enabled in memmap-gen3.c */
 #ifndef CONFIG_RCAR_GEN3
@@ -67,19 +68,41 @@
 	{ 0x0, "CPU" },
 };
 
-int print_cpuinfo(void)
+static int rmobile_cpuinfo_idx(void)
 {
 	int i = 0;
 	u32 cpu_type = rmobile_get_cpu_type();
-	for (; i < ARRAY_SIZE(rmobile_cpuinfo); i++) {
-		if (rmobile_cpuinfo[i].cpu_type == cpu_type) {
-			printf("CPU: Renesas Electronics %s rev %d.%d\n",
-			       rmobile_cpuinfo[i].cpu_name,
-			       rmobile_get_cpu_rev_integer(),
-			       rmobile_get_cpu_rev_fraction());
+
+	for (; i < ARRAY_SIZE(rmobile_cpuinfo); i++)
+		if (rmobile_cpuinfo[i].cpu_type == cpu_type)
 			break;
-		}
-	}
+
+	return i;
+}
+
+#ifdef CONFIG_ARCH_MISC_INIT
+int arch_misc_init(void)
+{
+	int i, idx = rmobile_cpuinfo_idx();
+	char cpu[10] = { 0 };
+
+	for (i = 0; i < sizeof(cpu); i++)
+		cpu[i] = tolower(rmobile_cpuinfo[idx].cpu_name[i]);
+
+	env_set("platform", cpu);
+
+	return 0;
+}
+#endif
+
+int print_cpuinfo(void)
+{
+	int i = rmobile_cpuinfo_idx();
+
+	printf("CPU: Renesas Electronics %s rev %d.%d\n",
+		rmobile_cpuinfo[i].cpu_name, rmobile_get_cpu_rev_integer(),
+		rmobile_get_cpu_rev_fraction());
+
 	return 0;
 }
 #endif /* CONFIG_DISPLAY_CPUINFO */
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 145d96b..6dc8e3a 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -35,6 +35,7 @@
 	select SPL_RAM
 	select SPL_DRIVERS_MISC_SUPPORT
 	select SPL_ROCKCHIP_EARLYRETURN_TO_BROM
+	select DEBUG_UART_BOARD_INIT
 	select BOARD_LATE_INIT
 	select ROCKCHIP_BROM_HELPER
 	help
@@ -156,6 +157,14 @@
 	  The Rockchip RV1108 is a ARM-based SoC with a single-core Cortex-A7
 	  and a DSP.
 
+config ROCKCHIP_USB_UART
+	bool "Route uart output to usb pins"
+	help
+	  Rockchip SoCs have the ability to route the signals of the debug
+	  uart through the d+ and d- pins of a specific usb phy to enable
+	  some form of closed-case debugging. With this option supported
+	  SoCs will enable this routing as a debug measure.
+
 config SPL_ROCKCHIP_BACK_TO_BROM
 	bool "SPL returns to bootrom"
 	default y if ROCKCHIP_RK3036
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 05706c4..368302e 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -33,6 +33,7 @@
 obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board.o
 obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board.o
 obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399-board.o
+obj-$(CONFIG_ROCKCHIP_RV1108) += rv1108-board.o
 endif
 
 obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram_common.o
diff --git a/arch/arm/mach-rockchip/rk3188-board-spl.c b/arch/arm/mach-rockchip/rk3188-board-spl.c
index 98ca971..3c6c3d3 100644
--- a/arch/arm/mach-rockchip/rk3188-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3188-board-spl.c
@@ -16,6 +16,7 @@
 #include <asm/io.h>
 #include <asm/arch/bootrom.h>
 #include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3188.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/periph.h>
 #include <asm/arch/pmu_rk3188.h>
@@ -92,23 +93,38 @@
 	return ret;
 }
 
-void board_init_f(ulong dummy)
+void board_debug_uart_init(void)
 {
-	struct udevice *pinctrl, *dev;
-	int ret;
-
-	/* Example code showing how to enable the debug UART on RK3188 */
-#ifdef EARLY_UART
-#include <asm/arch/grf_rk3188.h>
 	/* Enable early UART on the RK3188 */
 #define GRF_BASE	0x20008000
 	struct rk3188_grf * const grf = (void *)GRF_BASE;
+	enum {
+		GPIO1B1_SHIFT		= 2,
+		GPIO1B1_MASK		= 3,
+		GPIO1B1_GPIO		= 0,
+		GPIO1B1_UART2_SOUT,
 
+		GPIO1B0_SHIFT		= 0,
+		GPIO1B0_MASK		= 3,
+		GPIO1B0_GPIO		= 0,
+		GPIO1B0_UART2_SIN,
+	};
+
+	/* Enable early UART on the RK3188 */
 	rk_clrsetreg(&grf->gpio1b_iomux,
 		     GPIO1B1_MASK << GPIO1B1_SHIFT |
 		     GPIO1B0_MASK << GPIO1B0_SHIFT,
 		     GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT |
 		     GPIO1B0_UART2_SIN << GPIO1B0_SHIFT);
+}
+
+void board_init_f(ulong dummy)
+{
+	struct udevice *pinctrl, *dev;
+	int ret;
+
+#define EARLY_UART
+#ifdef EARLY_UART
 	/*
 	 * Debug UART can be used from here if required:
 	 *
@@ -124,6 +140,25 @@
 	printch('\n');
 #endif
 
+#ifdef CONFIG_ROCKCHIP_USB_UART
+	rk_clrsetreg(&grf->uoc0_con[0],
+		     SIDDQ_MASK | UOC_DISABLE_MASK | COMMON_ON_N_MASK,
+		     1 << SIDDQ_SHIFT | 1 << UOC_DISABLE_SHIFT |
+		     1 << COMMON_ON_N_SHIFT);
+	rk_clrsetreg(&grf->uoc0_con[2],
+		     SOFT_CON_SEL_MASK, 1 << SOFT_CON_SEL_SHIFT);
+	rk_clrsetreg(&grf->uoc0_con[3],
+		     OPMODE_MASK | XCVRSELECT_MASK |
+		     TERMSEL_FULLSPEED_MASK | SUSPENDN_MASK,
+		     OPMODE_NODRIVING << OPMODE_SHIFT |
+		     XCVRSELECT_FSTRANSC << XCVRSELECT_SHIFT |
+		     1 << TERMSEL_FULLSPEED_SHIFT |
+		     1 << SUSPENDN_SHIFT);
+	rk_clrsetreg(&grf->uoc0_con[0],
+		     BYPASSSEL_MASK | BYPASSDMEN_MASK,
+		     1 << BYPASSSEL_SHIFT | 1 << BYPASSDMEN_SHIFT);
+#endif
+
 	ret = spl_early_init();
 	if (ret) {
 		debug("spl_early_init() failed: %d\n", ret);
diff --git a/arch/arm/mach-rockchip/rk3399-board-spl.c b/arch/arm/mach-rockchip/rk3399-board-spl.c
index 43350e3..0198c6c 100644
--- a/arch/arm/mach-rockchip/rk3399-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3399-board-spl.c
@@ -202,13 +202,13 @@
 
 	ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
 	if (ret) {
-		debug("Pinctrl init failed: %d\n", ret);
+		pr_err("Pinctrl init failed: %d\n", ret);
 		return;
 	}
 
 	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
 	if (ret) {
-		debug("DRAM init failed: %d\n", ret);
+		pr_err("DRAM init failed: %d\n", ret);
 		return;
 	}
 }
diff --git a/arch/arm/mach-rockchip/rv1108-board.c b/arch/arm/mach-rockchip/rv1108-board.c
new file mode 100644
index 0000000..3412f2c
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1108-board.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2015 Google, Inc
+ */
+
+#include <common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
+#include <usb.h>
+#include <usb/dwc2_udc.h>
+
+static struct dwc2_plat_otg_data rv1108_otg_data = {
+	.rx_fifo_sz	= 512,
+	.np_tx_fifo_sz	= 16,
+	.tx_fifo_sz	= 128,
+};
+
+int board_usb_init(int index, enum usb_init_type init)
+{
+	const void *blob = gd->fdt_blob;
+	bool matched = false;
+	int node, phy_node;
+	u32 grf_phy_offset;
+	const char *mode;
+
+	/* find the usb_otg node */
+	node = fdt_node_offset_by_compatible(blob, -1, "rockchip,rk3066-usb");
+	while (node > 0) {
+		mode = fdt_getprop(blob, node, "dr_mode", NULL);
+		if (mode && strcmp(mode, "otg") == 0) {
+			matched = true;
+			break;
+		}
+
+		node = fdt_node_offset_by_compatible(blob, node,
+						     "rockchip,rk3066-usb");
+	}
+
+	if (!matched) {
+		debug("usb_otg device not found\n");
+		return -ENODEV;
+	}
+
+	rv1108_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
+
+	node = fdtdec_lookup_phandle(blob, node, "phys");
+	if (node <= 0) {
+		debug("phys node not found\n");
+		return -ENODEV;
+	}
+
+	phy_node = fdt_parent_offset(blob, node);
+	if (phy_node <= 0) {
+		debug("usb phy node not found\n");
+		return -ENODEV;
+	}
+
+	rv1108_otg_data.phy_of_node = phy_node;
+	grf_phy_offset = fdtdec_get_addr(blob, node, "reg");
+
+	/* find the grf node */
+	node = fdt_node_offset_by_compatible(blob, -1,
+					     "rockchip,rv1108-grf");
+	if (node <= 0) {
+		debug("grf node not found\n");
+		return -ENODEV;
+	}
+
+	rv1108_otg_data.regs_phy = grf_phy_offset + fdtdec_get_addr(blob, node,
+								    "reg");
+
+	return dwc2_udc_probe(&rv1108_otg_data);
+}
+
+int board_usb_cleanup(int index, enum usb_init_type init)
+{
+	return 0;
+}
+#endif
diff --git a/arch/arm/mach-socfpga/include/mach/base_addr_ac5.h b/arch/arm/mach-socfpga/include/mach/base_addr_ac5.h
index bb9e3fa..2725e9f 100644
--- a/arch/arm/mach-socfpga/include/mach/base_addr_ac5.h
+++ b/arch/arm/mach-socfpga/include/mach/base_addr_ac5.h
@@ -6,6 +6,7 @@
 #ifndef _SOCFPGA_BASE_ADDRS_H_
 #define _SOCFPGA_BASE_ADDRS_H_
 
+#define SOCFPGA_FPGA_SLAVES_ADDRESS	0xc0000000
 #define SOCFPGA_STM_ADDRESS		0xfc000000
 #define SOCFPGA_DAP_ADDRESS		0xff000000
 #define SOCFPGA_EMAC0_ADDRESS		0xff700000
diff --git a/arch/arm/mach-socfpga/include/mach/misc.h b/arch/arm/mach-socfpga/include/mach/misc.h
index 4fc9570..2660992 100644
--- a/arch/arm/mach-socfpga/include/mach/misc.h
+++ b/arch/arm/mach-socfpga/include/mach/misc.h
@@ -6,6 +6,8 @@
 #ifndef _MISC_H_
 #define _MISC_H_
 
+#include <asm/sections.h>
+
 void dwmac_deassert_reset(const unsigned int of_reset_id, const u32 phymode);
 
 struct bsel {
@@ -23,6 +25,13 @@
 
 #ifdef CONFIG_TARGET_SOCFPGA_GEN5
 void socfpga_sdram_remap_zero(void);
+static inline bool socfpga_is_booting_from_fpga(void)
+{
+	if ((__image_copy_start >= (char *)SOCFPGA_FPGA_SLAVES_ADDRESS) &&
+	    (__image_copy_start < (char *)SOCFPGA_STM_ADDRESS))
+		return true;
+	return false;
+}
 #endif
 
 #ifdef CONFIG_TARGET_SOCFPGA_ARRIA10
diff --git a/arch/arm/mach-socfpga/misc_gen5.c b/arch/arm/mach-socfpga/misc_gen5.c
index 429c3d6..5fa4093 100644
--- a/arch/arm/mach-socfpga/misc_gen5.c
+++ b/arch/arm/mach-socfpga/misc_gen5.c
@@ -177,6 +177,8 @@
 
 void socfpga_sdram_remap_zero(void)
 {
+	u32 remap;
+
 	socfpga_nic301_slave_ns();
 
 	/*
@@ -187,7 +189,12 @@
 	setbits_le32(&scu_regs->sacr, 0xfff);
 
 	/* Configure the L2 controller to make SDRAM start at 0 */
-	writel(0x1, &nic301_regs->remap);	/* remap.mpuzero */
+	remap = 0x1; /* remap.mpuzero */
+	/* Keep fpga bridge enabled when running from FPGA onchip RAM */
+	if (socfpga_is_booting_from_fpga())
+		remap |= 0x8; /* remap.hps2fpga */
+	writel(remap, &nic301_regs->remap);
+
 	writel(0x1, &pl310->pl310_addr_filter_start);
 }
 
diff --git a/arch/arm/mach-socfpga/spl_gen5.c b/arch/arm/mach-socfpga/spl_gen5.c
index be318cc..ccdc661 100644
--- a/arch/arm/mach-socfpga/spl_gen5.c
+++ b/arch/arm/mach-socfpga/spl_gen5.c
@@ -92,8 +92,11 @@
 
 	/* Put everything into reset but L4WD0. */
 	socfpga_per_reset_all();
-	/* Put FPGA bridges into reset too. */
-	socfpga_bridges_reset(1);
+
+	if (!socfpga_is_booting_from_fpga()) {
+		/* Put FPGA bridges into reset too. */
+		socfpga_bridges_reset(1);
+	}
 
 	socfpga_per_reset(SOCFPGA_RESET(SDR), 0);
 	socfpga_per_reset(SOCFPGA_RESET(UART0), 0);
@@ -163,5 +166,6 @@
 		hang();
 	}
 
-	socfpga_bridges_reset(1);
+	if (!socfpga_is_booting_from_fpga())
+		socfpga_bridges_reset(1);
 }
diff --git a/arch/arm/mach-socfpga/wrap_sdram_config.c b/arch/arm/mach-socfpga/wrap_sdram_config.c
index 8cfacc7..2b072cc 100644
--- a/arch/arm/mach-socfpga/wrap_sdram_config.c
+++ b/arch/arm/mach-socfpga/wrap_sdram_config.c
@@ -251,7 +251,7 @@
 		RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS,
 };
 
-struct socfpga_sdram_io_config io_config = {
+static const struct socfpga_sdram_io_config io_config = {
 	.delay_per_dchain_tap		= IO_DELAY_PER_DCHAIN_TAP,
 	.delay_per_dqs_en_dchain_tap	= IO_DELAY_PER_DQS_EN_DCHAIN_TAP,
 	.delay_per_opa_tap		= IO_DELAY_PER_OPA_TAP,
@@ -269,7 +269,7 @@
 	.shift_dqs_en_when_shift_dqs	= IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS,
 };
 
-struct socfpga_sdram_misc_config misc_config = {
+static const struct socfpga_sdram_misc_config misc_config = {
 	.afi_rate_ratio			= AFI_RATE_RATIO,
 	.calib_lfifo_offset		= CALIB_LFIFO_OFFSET,
 	.calib_vfifo_offset		= CALIB_VFIFO_OFFSET,
diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c
index 0e01f8e..b893358 100644
--- a/arch/arm/mach-stm32mp/cpu.c
+++ b/arch/arm/mach-stm32mp/cpu.c
@@ -306,7 +306,7 @@
 
 	ret = misc_read(dev, BSEC_OTP_MAC * 4 + STM32_BSEC_OTP_OFFSET,
 			otp, sizeof(otp));
-	if (ret)
+	if (ret < 0)
 		return ret;
 
 	for (i = 0; i < 6; i++)
@@ -344,7 +344,7 @@
 
 	ret = misc_read(dev, BSEC_OTP_SERIAL * 4 + STM32_BSEC_OTP_OFFSET,
 			otp, sizeof(otp));
-	if (ret)
+	if (ret < 0)
 		return ret;
 
 	sprintf(serial_string, "%08x%08x%08x", otp[0], otp[1], otp[2]);
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 560dc9b..3c54f51 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -230,6 +230,7 @@
 	select PHY_SUN4I_USB
 	select SUNXI_GEN_SUN6I
 	select MMC_SUNXI_HAS_NEW_MODE
+	select MMC_SUNXI_HAS_MODE_SWITCH
 	select SUPPORT_SPL
 
 config MACH_SUN8I_H3
@@ -281,6 +282,7 @@
 	select SUN6I_PRCM
 	select SUNXI_DE2
 	select SUNXI_GEN_SUN6I
+	select MMC_SUNXI_HAS_NEW_MODE
 	select SUPPORT_SPL
 	select SUNXI_DRAM_DW
 	select SUNXI_DRAM_DW_32BIT
diff --git a/arch/arm/mach-sunxi/dram_sun8i_a33.c b/arch/arm/mach-sunxi/dram_sun8i_a33.c
index d9aa0c6..1da2727 100644
--- a/arch/arm/mach-sunxi/dram_sun8i_a33.c
+++ b/arch/arm/mach-sunxi/dram_sun8i_a33.c
@@ -334,7 +334,7 @@
 	struct dram_para para = {
 		.cs1 = 0,
 		.bank = 1,
-		.rank = 1,
+		.rank = 2,
 		.rows = 15,
 		.bus_width = 16,
 		.page_size = 2048,
diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi
index 70e34cf..1e7d0a6 100644
--- a/arch/mips/dts/mt7628a.dtsi
+++ b/arch/mips/dts/mt7628a.dtsi
@@ -164,7 +164,7 @@
 	};
 
 	eth@10110000 {
-		compatible = "mediatek,mt7622-eth";
+		compatible = "mediatek,mt7628-eth";
 		reg = <0x10100000 0x10000
 		       0x10110000 0x8000>;
 
diff --git a/arch/nds32/cpu/n1213/start.S b/arch/nds32/cpu/n1213/start.S
index aa9457f..cf966e2 100644
--- a/arch/nds32/cpu/n1213/start.S
+++ b/arch/nds32/cpu/n1213/start.S
@@ -201,14 +201,6 @@
 #endif
 
 /*
- * Do CPU critical regs init only at reboot,
- * not when booting from ram
- */
-#ifdef CONFIG_INIT_CRITICAL
-	jal	cpu_init_crit		! Do CPU critical regs init
-#endif
-
-/*
  * Set stackpointer in internal RAM to call board_init_f
  * $sp must be 8-byte alignment for ABI compliance.
  */
@@ -319,49 +311,6 @@
 	jr	$lp			/* jump to board_init_r() */
 
 /*
- * Initialize CPU critical registers
- *
- *	1.	Setup control registers
- *		1.1 Mask all IRQs
- *		1.2 Flush cache and TLB
- *		1.3 Disable MMU and cache
- *	2.	Setup memory timing
- */
-
-cpu_init_crit:
-
-	move	$r0, $lp		/* push	ra */
-
-	/* Disable Interrupts by clear GIE in $PSW reg */
-	setgie.d
-
-	/* Flush caches and TLB */
-	/* Invalidate caches */
-	jal	invalidate_icac
-	jal	invalidate_dcac
-
-	/* Flush TLB */
-	mfsr	$p0, $MMU_CFG
-	andi	$p0, $p0, 0x3			! MMPS
-	li	$p1, 0x2			! TLB MMU
-	bne	$p0, $p1, 1f
-	tlbop	flushall			! Flush TLB
-
-1:
-	! Disable MMU, Dcache
-	! Whitiger is MMU disabled when reset
-	! Disable the D$
-	mfsr	$p0, MR_CAC_CTL			! Get the $CACHE_CTL reg
-	li	$p1, DIS_DCAC
-	and	$p0, $p0, $p1			! Set DC_EN bit
-	mtsr	$p0, MR_CAC_CTL			! write back the $CACHE_CTL reg
-	isb
-
-	move	$lp, $r0
-2:
-	ret
-
-/*
  * Invalidate I$
  */
 invalidate_icac:
diff --git a/arch/powerpc/cpu/mpc8xx/start.S b/arch/powerpc/cpu/mpc8xx/start.S
index 8dde4be..b8bdaae 100644
--- a/arch/powerpc/cpu/mpc8xx/start.S
+++ b/arch/powerpc/cpu/mpc8xx/start.S
@@ -144,9 +144,11 @@
 	ori	r2, r2, CONFIG_SYS_DER@l
 	mtspr	DER, r2
 
-	/* set up the stack in internal DPRAM */
+	/* set up the stack on top of internal DPRAM */
 	lis	r3, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE)@h
 	ori	r3, r3, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE)@l
+	stw	r0, -4(r3)
+	stw	r0, -8(r3)
 	addi	r1, r3, -8
 
 	bl	board_init_f_alloc_reserve
diff --git a/arch/powerpc/dts/Makefile b/arch/powerpc/dts/Makefile
index a19aa56..172bed4 100644
--- a/arch/powerpc/dts/Makefile
+++ b/arch/powerpc/dts/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0+
 
 dtb-$(CONFIG_TARGET_T2080QDS) += t2080qds.dtb
+dtb-$(CONFIG_MCR3000) += mcr3000.dtb
 
 targets += $(dtb-y)
 
diff --git a/arch/powerpc/dts/mcr3000.dts b/arch/powerpc/dts/mcr3000.dts
new file mode 100644
index 0000000..5abf111
--- /dev/null
+++ b/arch/powerpc/dts/mcr3000.dts
@@ -0,0 +1,22 @@
+/*
+ * MCR3000 Device Tree Source
+ *
+ * Copyright 2017 CS Systemes d'Information
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/dts-v1/;
+
+/ {
+	WDT: watchdog@0 {
+		compatible = "fsl,pq1-wdt";
+	};
+	SERIAL: smc@0 {
+		compatible = "fsl,pq1-smc";
+	};
+
+	chosen {
+		stdout-path = &SERIAL;
+	};
+};
diff --git a/arch/powerpc/include/asm/spl.h b/arch/powerpc/include/asm/spl.h
index cd6d31c..60a7d37 100644
--- a/arch/powerpc/include/asm/spl.h
+++ b/arch/powerpc/include/asm/spl.h
@@ -8,7 +8,4 @@
 
 #define BOOT_DEVICE_NOR		1
 
-/* Linker symbols */
-extern char __bss_start[], __bss_end[];
-
 #endif
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 168ca3d..732a357 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -16,27 +16,50 @@
 
 endchoice
 
+# board-specific options below
 source "board/AndesTech/ax25-ae350/Kconfig"
 source "board/emulation/qemu-riscv/Kconfig"
 
+# platform-specific options below
+source "arch/riscv/cpu/ax25/Kconfig"
+
+# architecture-specific options below
+
 choice
-	prompt "CPU selection"
-	default CPU_RISCV_32
+	prompt "Base ISA"
+	default ARCH_RV32I
 
-config CPU_RISCV_32
-	bool "RISC-V 32-bit"
+config ARCH_RV32I
+	bool "RV32I"
 	select 32BIT
 	help
-	  Choose this option to build an U-Boot for RISCV32 architecture.
+	  Choose this option to target the RV32I base integer instruction set.
 
-config CPU_RISCV_64
-	bool "RISC-V 64-bit"
+config ARCH_RV64I
+	bool "RV64I"
 	select 64BIT
+	select PHYS_64BIT
 	help
-	  Choose this option to build an U-Boot for RISCV64 architecture.
+	  Choose this option to target the RV64I base integer instruction set.
 
 endchoice
 
+config RISCV_ISA_C
+	bool "Emit compressed instructions"
+	default y
+	help
+	  Adds "C" to the ISA subsets that the toolchain is allowed to emit
+	  when building U-Boot, which results in compressed instructions in the
+	  U-Boot binary.
+
+config RISCV_ISA_A
+	def_bool y
+
+config RISCV_SMODE
+	bool "Run in S-Mode"
+	help
+	  Enable this option to build U-Boot for RISC-V S-Mode
+
 config 32BIT
 	bool
 
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 8fb6a88..55d7c65 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -3,6 +3,26 @@
 # Copyright (C) 2017 Andes Technology Corporation.
 # Rick Chen, Andes Technology Corporation <rick@andestech.com>
 
+ifeq ($(CONFIG_ARCH_RV64I),y)
+	ARCH_BASE = rv64im
+	ABI = lp64
+endif
+ifeq ($(CONFIG_ARCH_RV32I),y)
+	ARCH_BASE = rv32im
+	ABI = ilp32
+endif
+ifeq ($(CONFIG_RISCV_ISA_A),y)
+	ARCH_A = a
+endif
+ifeq ($(CONFIG_RISCV_ISA_C),y)
+	ARCH_C = c
+endif
+
+ARCH_FLAGS = -march=$(ARCH_BASE)$(ARCH_A)$(ARCH_C) -mabi=$(ABI)
+
+PLATFORM_CPPFLAGS	+= $(ARCH_FLAGS)
+CFLAGS_EFI		+= $(ARCH_FLAGS)
+
 head-y := arch/riscv/cpu/start.o
 
 libs-y += arch/riscv/cpu/
diff --git a/arch/riscv/config.mk b/arch/riscv/config.mk
index cc5d8d1..ff4fe64 100644
--- a/arch/riscv/config.mk
+++ b/arch/riscv/config.mk
@@ -14,16 +14,12 @@
 64bit-emul		:= elf64lriscv
 
 ifdef CONFIG_32BIT
-PLATFORM_CPPFLAGS	+= -march=rv32ima -mabi=ilp32
 PLATFORM_LDFLAGS	+= -m $(32bit-emul)
-CFLAGS_EFI		+= -march=rv32ima -mabi=ilp32
 EFI_LDS			:= elf_riscv32_efi.lds
 endif
 
 ifdef CONFIG_64BIT
-PLATFORM_CPPFLAGS	+= -march=rv64ima -mabi=lp64
 PLATFORM_LDFLAGS	+= -m $(64bit-emul)
-CFLAGS_EFI		+= -march=rv64ima -mabi=lp64
 EFI_LDS			:= elf_riscv64_efi.lds
 endif
 
@@ -31,7 +27,8 @@
 LDFLAGS_STANDALONE += -T $(srctree)/examples/standalone/riscv.lds
 
 PLATFORM_CPPFLAGS	+= -ffixed-gp -fpic
-PLATFORM_RELFLAGS	+= -fno-common -gdwarf-2 -ffunction-sections
+PLATFORM_RELFLAGS	+= -fno-common -gdwarf-2 -ffunction-sections \
+			   -fdata-sections
 LDFLAGS_u-boot		+= --gc-sections -static -pie
 
 EFI_CRT0		:= crt0_riscv_efi.o
diff --git a/arch/riscv/cpu/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig
new file mode 100644
index 0000000..6c7022f
--- /dev/null
+++ b/arch/riscv/cpu/ax25/Kconfig
@@ -0,0 +1,7 @@
+config RISCV_NDS
+	bool "AndeStar V5 ISA support"
+	default n
+	help
+		Say Y here if you plan to run U-Boot on AndeStar v5
+		platforms and use some specific features which are
+		provided by Andes Technology AndeStar V5 Families.
diff --git a/arch/riscv/cpu/ax25/Makefile b/arch/riscv/cpu/ax25/Makefile
index 2ab0342..318bacc 100644
--- a/arch/riscv/cpu/ax25/Makefile
+++ b/arch/riscv/cpu/ax25/Makefile
@@ -4,3 +4,4 @@
 # Rick Chen, Andes Technology Corporation <rick@andestech.com>
 
 obj-y	:= cpu.o
+obj-y	+= cache.o
diff --git a/arch/riscv/cpu/ax25/cache.c b/arch/riscv/cpu/ax25/cache.c
new file mode 100644
index 0000000..6600ac2
--- /dev/null
+++ b/arch/riscv/cpu/ax25/cache.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017 Andes Technology Corporation
+ * Rick Chen, Andes Technology Corporation <rick@andestech.com>
+ */
+
+#include <common.h>
+
+void icache_enable(void)
+{
+#ifndef CONFIG_SYS_ICACHE_OFF
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"csrr t1, mcache_ctl\n\t"
+		"ori t0, t1, 0x1\n\t"
+		"csrw mcache_ctl, t0\n\t"
+	);
+#endif
+#endif
+}
+
+void icache_disable(void)
+{
+#ifndef CONFIG_SYS_ICACHE_OFF
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"fence.i\n\t"
+		"csrr t1, mcache_ctl\n\t"
+		"andi t0, t1, ~0x1\n\t"
+		"csrw mcache_ctl, t0\n\t"
+	);
+#endif
+#endif
+}
+
+void dcache_enable(void)
+{
+#ifndef CONFIG_SYS_DCACHE_OFF
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"csrr t1, mcache_ctl\n\t"
+		"ori t0, t1, 0x2\n\t"
+		"csrw mcache_ctl, t0\n\t"
+	);
+#endif
+#endif
+}
+
+void dcache_disable(void)
+{
+#ifndef CONFIG_SYS_DCACHE_OFF
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"fence\n\t"
+		"csrr t1, mcache_ctl\n\t"
+		"andi t0, t1, ~0x2\n\t"
+		"csrw mcache_ctl, t0\n\t"
+	);
+#endif
+#endif
+}
+
+int icache_status(void)
+{
+	int ret = 0;
+
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"csrr t1, mcache_ctl\n\t"
+		"andi	%0, t1, 0x01\n\t"
+		: "=r" (ret)
+		:
+		: "memory"
+	);
+#endif
+
+	return ret;
+}
+
+int dcache_status(void)
+{
+	int ret = 0;
+
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"csrr t1, mcache_ctl\n\t"
+		"andi	%0, t1, 0x02\n\t"
+		: "=r" (ret)
+		:
+		: "memory"
+	);
+#endif
+
+	return ret;
+}
diff --git a/arch/riscv/cpu/ax25/cpu.c b/arch/riscv/cpu/ax25/cpu.c
index fddcc15..76689b2 100644
--- a/arch/riscv/cpu/ax25/cpu.c
+++ b/arch/riscv/cpu/ax25/cpu.c
@@ -6,6 +6,7 @@
 
 /* CPU specific code */
 #include <common.h>
+#include <asm/cache.h>
 
 /*
  * cleanup_before_linux() is called just before we call linux
@@ -18,6 +19,9 @@
 	disable_interrupts();
 
 	/* turn off I/D-cache */
+	cache_flush();
+	icache_disable();
+	dcache_disable();
 
 	return 0;
 }
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
index ae57fb8..d9f820c 100644
--- a/arch/riscv/cpu/cpu.c
+++ b/arch/riscv/cpu/cpu.c
@@ -6,6 +6,12 @@
 #include <common.h>
 #include <asm/csr.h>
 
+/*
+ * prior_stage_fdt_address must be stored in the data section since it is used
+ * before the bss section is available.
+ */
+phys_addr_t prior_stage_fdt_address __attribute__((section(".data")));
+
 enum {
 	ISA_INVALID = 0,
 	ISA_32BIT,
diff --git a/arch/riscv/cpu/qemu/cpu.c b/arch/riscv/cpu/qemu/cpu.c
index 6c7a327..25d97d0 100644
--- a/arch/riscv/cpu/qemu/cpu.c
+++ b/arch/riscv/cpu/qemu/cpu.c
@@ -15,7 +15,7 @@
 {
 	disable_interrupts();
 
-	/* turn off I/D-cache */
+	cache_flush();
 
 	return 0;
 }
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index 7cd7755..64246a4 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -16,56 +16,45 @@
 #include <asm/encoding.h>
 
 #ifdef CONFIG_32BIT
-#define LREG 			lw
-#define SREG 			sw
-#define REGBYTES 		4
+#define LREG			lw
+#define SREG			sw
+#define REGBYTES		4
 #define RELOC_TYPE		R_RISCV_32
 #define SYM_INDEX		0x8
 #define SYM_SIZE		0x10
 #else
-#define LREG 			ld
-#define SREG 			sd
-#define REGBYTES 		8
+#define LREG			ld
+#define SREG			sd
+#define REGBYTES		8
 #define RELOC_TYPE		R_RISCV_64
 #define SYM_INDEX		0x20
 #define SYM_SIZE		0x18
 #endif
 
-.section      .text
+.section .text
 .globl _start
 _start:
-	j handle_reset
+	/* save hart id and dtb pointer */
+	mv	s0, a0
+	mv	s1, a1
 
-nmi_vector:
-	j nmi_vector
+	la	t0, trap_entry
+	csrw	MODE_PREFIX(tvec), t0
 
-trap_vector:
-	j trap_entry
+	/* mask all interrupts */
+	csrw	MODE_PREFIX(ie), zero
 
-.global trap_entry
-handle_reset:
-	li t0, CONFIG_SYS_SDRAM_BASE
-	SREG a2, 0(t0)
-	la t0, trap_entry
-	csrw mtvec, t0
-	csrwi mstatus, 0
-	csrwi mie, 0
+	/* Enable cache */
+	jal	icache_enable
+	jal	dcache_enable
 
 /*
- * Do CPU critical regs init only at reboot,
- * not when booting from ram
- */
-#ifdef CONFIG_INIT_CRITICAL
-	jal cpu_init_crit	/* Do CPU critical regs init */
-#endif
-
-/*
  * Set stackpointer in internal/ex RAM to call board_init_f
  */
 call_board_init_f:
-	li  t0, -16
-	li  t1, CONFIG_SYS_INIT_SP_ADDR
-	and sp, t1, t0	/* force 16 byte alignment */
+	li	t0, -16
+	li	t1, CONFIG_SYS_INIT_SP_ADDR
+	and	sp, t1, t0		/* force 16 byte alignment */
 
 #ifdef CONFIG_DEBUG_UART
 	jal	debug_uart_init
@@ -75,11 +64,15 @@
 	mv	a0, sp
 	jal	board_init_f_alloc_reserve
 	mv	sp, a0
+
+	la	t0, prior_stage_fdt_address
+	SREG	s1, 0(t0)
+
 	jal	board_init_f_init_reserve
 
-	mv  a0, zero	/* a0 <-- boot_flags = 0 */
-	la t5, board_init_f
-	jr t5		/* jump to board_init_f() */
+	mv	a0, zero		/* a0 <-- boot_flags = 0 */
+	la	t5, board_init_f
+	jr	t5			/* jump to board_init_f() */
 
 /*
  * void relocate_code (addr_sp, gd, addr_moni)
@@ -90,203 +83,207 @@
  */
 .globl relocate_code
 relocate_code:
-	mv  s2, a0	/* save addr_sp */
-	mv  s3, a1	/* save addr of gd */
-	mv  s4, a2	/* save addr of destination */
+	mv	s2, a0			/* save addr_sp */
+	mv	s3, a1			/* save addr of gd */
+	mv	s4, a2			/* save addr of destination */
 
 /*
  *Set up the stack
  */
 stack_setup:
-	mv sp, s2
-	la t0, _start
-	sub t6, s4, t0	/* t6 <- relocation offset */
-	beq t0, s4, clear_bss	/* skip relocation */
+	mv	sp, s2
+	la	t0, _start
+	sub	t6, s4, t0		/* t6 <- relocation offset */
+	beq	t0, s4, clear_bss	/* skip relocation */
 
-	mv t1, s4	/* t1 <- scratch for copy_loop */
-	la t3, __bss_start
-	sub t3, t3, t0	/* t3 <- __bss_start_ofs */
-	add t2, t0, t3	/* t2 <- source end address */
+	mv	t1, s4			/* t1 <- scratch for copy_loop */
+	la	t3, __bss_start
+	sub	t3, t3, t0		/* t3 <- __bss_start_ofs */
+	add	t2, t0, t3		/* t2 <- source end address */
 
 copy_loop:
-	LREG t5, 0(t0)
-	addi t0, t0, REGBYTES
-	SREG t5, 0(t1)
-	addi t1, t1, REGBYTES
-	blt t0, t2, copy_loop
+	LREG	t5, 0(t0)
+	addi	t0, t0, REGBYTES
+	SREG	t5, 0(t1)
+	addi	t1, t1, REGBYTES
+	blt	t0, t2, copy_loop
 
 /*
  * Update dynamic relocations after board_init_f
  */
 fix_rela_dyn:
-	la  t1, __rel_dyn_start
-	la  t2, __rel_dyn_end
-	beq t1, t2, clear_bss
-	add t1, t1, t6			/* t1 <- rela_dyn_start in RAM */
-	add t2, t2, t6			/* t2 <- rela_dyn_end in RAM */
+	la	t1, __rel_dyn_start
+	la	t2, __rel_dyn_end
+	beq	t1, t2, clear_bss
+	add	t1, t1, t6		/* t1 <- rela_dyn_start in RAM */
+	add	t2, t2, t6		/* t2 <- rela_dyn_end in RAM */
 
 /*
  * skip first reserved entry: address, type, addend
  */
-	bne t1, t2, 7f
+	bne	t1, t2, 7f
 
 6:
-	LREG  t5, -(REGBYTES*2)(t1)	/* t5 <-- relocation info:type */
-	li  t3, R_RISCV_RELATIVE	/* reloc type R_RISCV_RELATIVE */
-	bne t5, t3, 8f			/* skip non-RISCV_RELOC entries */
-	LREG t3, -(REGBYTES*3)(t1)
-	LREG t5, -(REGBYTES)(t1)	/* t5 <-- addend */
-	add t5, t5, t6			/* t5 <-- location to fix up in RAM */
-	add t3, t3, t6			/* t3 <-- location to fix up in RAM */
-	SREG t5, 0(t3)
+	LREG	t5, -(REGBYTES*2)(t1)	/* t5 <-- relocation info:type */
+	li	t3, R_RISCV_RELATIVE	/* reloc type R_RISCV_RELATIVE */
+	bne	t5, t3, 8f		/* skip non-RISCV_RELOC entries */
+	LREG	t3, -(REGBYTES*3)(t1)
+	LREG	t5, -(REGBYTES)(t1)	/* t5 <-- addend */
+	add	t5, t5, t6		/* t5 <-- location to fix up in RAM */
+	add	t3, t3, t6		/* t3 <-- location to fix up in RAM */
+	SREG	t5, 0(t3)
 7:
-	addi t1, t1, (REGBYTES*3)
-	ble t1, t2, 6b
+	addi	t1, t1, (REGBYTES*3)
+	ble	t1, t2, 6b
 
 8:
-	la  t4, __dyn_sym_start
-	add t4, t4, t6
+	la	t4, __dyn_sym_start
+	add	t4, t4, t6
 
 9:
-	LREG  t5, -(REGBYTES*2)(t1)	/* t5 <-- relocation info:type */
-	srli t0, t5, SYM_INDEX		/* t0 <--- sym table index */
-	andi t5, t5, 0xFF		/* t5 <--- relocation type */
-	li  t3, RELOC_TYPE
-	bne t5, t3, 10f 		/* skip non-addned entries */
+	LREG	t5, -(REGBYTES*2)(t1)	/* t5 <-- relocation info:type */
+	srli	t0, t5, SYM_INDEX	/* t0 <--- sym table index */
+	andi	t5, t5, 0xFF		/* t5 <--- relocation type */
+	li	t3, RELOC_TYPE
+	bne	t5, t3, 10f		/* skip non-addned entries */
 
-	LREG t3, -(REGBYTES*3)(t1)
-	li t5, SYM_SIZE
-	mul t0, t0, t5
-	add s1, t4, t0
-	LREG t5, REGBYTES(s1)
-	add t5, t5, t6			/* t5 <-- location to fix up in RAM */
-	add t3, t3, t6			/* t3 <-- location to fix up in RAM */
-	SREG t5, 0(t3)
+	LREG	t3, -(REGBYTES*3)(t1)
+	li	t5, SYM_SIZE
+	mul	t0, t0, t5
+	add	s5, t4, t0
+	LREG	t5, REGBYTES(s5)
+	add	t5, t5, t6		/* t5 <-- location to fix up in RAM */
+	add	t3, t3, t6		/* t3 <-- location to fix up in RAM */
+	SREG	t5, 0(t3)
 10:
-	addi t1, t1, (REGBYTES*3)
-	ble t1, t2, 9b
+	addi	t1, t1, (REGBYTES*3)
+	ble	t1, t2, 9b
 
 /*
  * trap update
 */
-	la t0, trap_entry
-	add t0, t0, t6
-	csrw mtvec, t0
+	la	t0, trap_entry
+	add	t0, t0, t6
+	csrw	MODE_PREFIX(tvec), t0
 
 clear_bss:
-	la t0, __bss_start		/* t0 <- rel __bss_start in FLASH */
-	add t0, t0, t6			/* t0 <- rel __bss_start in RAM */
-	la t1, __bss_end		/* t1 <- rel __bss_end in FLASH */
-	add t1, t1, t6			/* t1 <- rel __bss_end in RAM */
-	li t2, 0x00000000		/* clear */
-	beq t0, t1, call_board_init_r
+	la	t0, __bss_start		/* t0 <- rel __bss_start in FLASH */
+	add	t0, t0, t6		/* t0 <- rel __bss_start in RAM */
+	la	t1, __bss_end		/* t1 <- rel __bss_end in FLASH */
+	add	t1, t1, t6		/* t1 <- rel __bss_end in RAM */
+	beq	t0, t1, call_board_init_r
 
 clbss_l:
-	SREG t2, 0(t0)			/* clear loop... */
-	addi t0, t0, REGBYTES
-	bne t0, t1, clbss_l
+	SREG	zero, 0(t0)		/* clear loop... */
+	addi	t0, t0, REGBYTES
+	bne	t0, t1, clbss_l
 
 /*
  * We are done. Do not return, instead branch to second part of board
  * initialization, now running from RAM.
  */
 call_board_init_r:
-	la t0, board_init_r
-	mv t4, t0			/* offset of board_init_r() */
-	add t4, t4, t6			/* real address of board_init_r() */
+	jal	invalidate_icache_all
+	jal	flush_dcache_all
+	la	t0, board_init_r
+	mv	t4, t0			/* offset of board_init_r() */
+	add	t4, t4, t6		/* real address of board_init_r() */
 /*
  * setup parameters for board_init_r
  */
-	mv a0, s3			/* gd_t */
-	mv a1, s4			/* dest_addr */
+	mv	a0, s3			/* gd_t */
+	mv	a1, s4			/* dest_addr */
 
 /*
  * jump to it ...
  */
-	jr t4				/* jump to board_init_r() */
+	jr	t4			/* jump to board_init_r() */
 
 /*
  * trap entry
  */
+.align 2
 trap_entry:
-	addi sp, sp, -32*REGBYTES
-	SREG x1, 1*REGBYTES(sp)
-	SREG x2, 2*REGBYTES(sp)
-	SREG x3, 3*REGBYTES(sp)
-	SREG x4, 4*REGBYTES(sp)
-	SREG x5, 5*REGBYTES(sp)
-	SREG x6, 6*REGBYTES(sp)
-	SREG x7, 7*REGBYTES(sp)
-	SREG x8, 8*REGBYTES(sp)
-	SREG x9, 9*REGBYTES(sp)
-	SREG x10, 10*REGBYTES(sp)
-	SREG x11, 11*REGBYTES(sp)
-	SREG x12, 12*REGBYTES(sp)
-	SREG x13, 13*REGBYTES(sp)
-	SREG x14, 14*REGBYTES(sp)
-	SREG x15, 15*REGBYTES(sp)
-	SREG x16, 16*REGBYTES(sp)
-	SREG x17, 17*REGBYTES(sp)
-	SREG x18, 18*REGBYTES(sp)
-	SREG x19, 19*REGBYTES(sp)
-	SREG x20, 20*REGBYTES(sp)
-	SREG x21, 21*REGBYTES(sp)
-	SREG x22, 22*REGBYTES(sp)
-	SREG x23, 23*REGBYTES(sp)
-	SREG x24, 24*REGBYTES(sp)
-	SREG x25, 25*REGBYTES(sp)
-	SREG x26, 26*REGBYTES(sp)
-	SREG x27, 27*REGBYTES(sp)
-	SREG x28, 28*REGBYTES(sp)
-	SREG x29, 29*REGBYTES(sp)
-	SREG x30, 30*REGBYTES(sp)
-	SREG x31, 31*REGBYTES(sp)
-	csrr a0, mcause
-	csrr a1, mepc
-	mv a2, sp
-	jal handle_trap
-	csrw mepc, a0
+	addi	sp, sp, -32*REGBYTES
+	SREG	x1, 1*REGBYTES(sp)
+	SREG	x2, 2*REGBYTES(sp)
+	SREG	x3, 3*REGBYTES(sp)
+	SREG	x4, 4*REGBYTES(sp)
+	SREG	x5, 5*REGBYTES(sp)
+	SREG	x6, 6*REGBYTES(sp)
+	SREG	x7, 7*REGBYTES(sp)
+	SREG	x8, 8*REGBYTES(sp)
+	SREG	x9, 9*REGBYTES(sp)
+	SREG	x10, 10*REGBYTES(sp)
+	SREG	x11, 11*REGBYTES(sp)
+	SREG	x12, 12*REGBYTES(sp)
+	SREG	x13, 13*REGBYTES(sp)
+	SREG	x14, 14*REGBYTES(sp)
+	SREG	x15, 15*REGBYTES(sp)
+	SREG	x16, 16*REGBYTES(sp)
+	SREG	x17, 17*REGBYTES(sp)
+	SREG	x18, 18*REGBYTES(sp)
+	SREG	x19, 19*REGBYTES(sp)
+	SREG	x20, 20*REGBYTES(sp)
+	SREG	x21, 21*REGBYTES(sp)
+	SREG	x22, 22*REGBYTES(sp)
+	SREG	x23, 23*REGBYTES(sp)
+	SREG	x24, 24*REGBYTES(sp)
+	SREG	x25, 25*REGBYTES(sp)
+	SREG	x26, 26*REGBYTES(sp)
+	SREG	x27, 27*REGBYTES(sp)
+	SREG	x28, 28*REGBYTES(sp)
+	SREG	x29, 29*REGBYTES(sp)
+	SREG	x30, 30*REGBYTES(sp)
+	SREG	x31, 31*REGBYTES(sp)
+	csrr	a0, MODE_PREFIX(cause)
+	csrr	a1, MODE_PREFIX(epc)
+	mv	a2, sp
+	jal	handle_trap
+	csrw	MODE_PREFIX(epc), a0
 
+#ifdef CONFIG_RISCV_SMODE
+/*
+ * Remain in S-mode after sret
+ */
+	li	t0, SSTATUS_SPP
+#else
 /*
  * Remain in M-mode after mret
  */
-	li t0, MSTATUS_MPP
-	csrs mstatus, t0
-	LREG x1, 1*REGBYTES(sp)
-	LREG x2, 2*REGBYTES(sp)
-	LREG x3, 3*REGBYTES(sp)
-	LREG x4, 4*REGBYTES(sp)
-	LREG x5, 5*REGBYTES(sp)
-	LREG x6, 6*REGBYTES(sp)
-	LREG x7, 7*REGBYTES(sp)
-	LREG x8, 8*REGBYTES(sp)
-	LREG x9, 9*REGBYTES(sp)
-	LREG x10, 10*REGBYTES(sp)
-	LREG x11, 11*REGBYTES(sp)
-	LREG x12, 12*REGBYTES(sp)
-	LREG x13, 13*REGBYTES(sp)
-	LREG x14, 14*REGBYTES(sp)
-	LREG x15, 15*REGBYTES(sp)
-	LREG x16, 16*REGBYTES(sp)
-	LREG x17, 17*REGBYTES(sp)
-	LREG x18, 18*REGBYTES(sp)
-	LREG x19, 19*REGBYTES(sp)
-	LREG x20, 20*REGBYTES(sp)
-	LREG x21, 21*REGBYTES(sp)
-	LREG x22, 22*REGBYTES(sp)
-	LREG x23, 23*REGBYTES(sp)
-	LREG x24, 24*REGBYTES(sp)
-	LREG x25, 25*REGBYTES(sp)
-	LREG x26, 26*REGBYTES(sp)
-	LREG x27, 27*REGBYTES(sp)
-	LREG x28, 28*REGBYTES(sp)
-	LREG x29, 29*REGBYTES(sp)
-	LREG x30, 30*REGBYTES(sp)
-	LREG x31, 31*REGBYTES(sp)
-	addi sp, sp, 32*REGBYTES
-	mret
-
-#ifdef CONFIG_INIT_CRITICAL
-cpu_init_crit:
-    ret
+	li	t0, MSTATUS_MPP
 #endif
+	csrs	MODE_PREFIX(status), t0
+	LREG	x1, 1*REGBYTES(sp)
+	LREG	x2, 2*REGBYTES(sp)
+	LREG	x3, 3*REGBYTES(sp)
+	LREG	x4, 4*REGBYTES(sp)
+	LREG	x5, 5*REGBYTES(sp)
+	LREG	x6, 6*REGBYTES(sp)
+	LREG	x7, 7*REGBYTES(sp)
+	LREG	x8, 8*REGBYTES(sp)
+	LREG	x9, 9*REGBYTES(sp)
+	LREG	x10, 10*REGBYTES(sp)
+	LREG	x11, 11*REGBYTES(sp)
+	LREG	x12, 12*REGBYTES(sp)
+	LREG	x13, 13*REGBYTES(sp)
+	LREG	x14, 14*REGBYTES(sp)
+	LREG	x15, 15*REGBYTES(sp)
+	LREG	x16, 16*REGBYTES(sp)
+	LREG	x17, 17*REGBYTES(sp)
+	LREG	x18, 18*REGBYTES(sp)
+	LREG	x19, 19*REGBYTES(sp)
+	LREG	x20, 20*REGBYTES(sp)
+	LREG	x21, 21*REGBYTES(sp)
+	LREG	x22, 22*REGBYTES(sp)
+	LREG	x23, 23*REGBYTES(sp)
+	LREG	x24, 24*REGBYTES(sp)
+	LREG	x25, 25*REGBYTES(sp)
+	LREG	x26, 26*REGBYTES(sp)
+	LREG	x27, 27*REGBYTES(sp)
+	LREG	x28, 28*REGBYTES(sp)
+	LREG	x29, 29*REGBYTES(sp)
+	LREG	x30, 30*REGBYTES(sp)
+	LREG	x31, 31*REGBYTES(sp)
+	addi	sp, sp, 32*REGBYTES
+	MODE_PREFIX(ret)
diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile
index a1b06ff..b400def 100644
--- a/arch/riscv/dts/Makefile
+++ b/arch/riscv/dts/Makefile
@@ -1,6 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0+
 
-dtb-$(CONFIG_TARGET_AX25_AE350) += ae350.dtb
 targets += $(dtb-y)
 
 DTC_FLAGS += -R 4 -p 0x1000
diff --git a/arch/riscv/dts/ae350.dts b/arch/riscv/dts/ae350.dts
index 4717ae8..e48c298 100644
--- a/arch/riscv/dts/ae350.dts
+++ b/arch/riscv/dts/ae350.dts
@@ -12,15 +12,14 @@
 	};
 
 	chosen {
-		bootargs = "console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0xf0300000 debug loglevel=7";
+		bootargs = "console=ttyS0,38400n8  debug loglevel=7";
 		stdout-path = "uart0:38400n8";
 	};
 
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
-		timebase-frequency = <10000000>;
-
+		timebase-frequency = <60000000>;
 		CPU0: cpu@0 {
 			device_type = "cpu";
 			reg = <0>;
@@ -29,7 +28,8 @@
 			riscv,isa = "rv64imafdc";
 			mmu-type = "riscv,sv39";
 			clock-frequency = <60000000>;
-
+			d-cache-size = <0x8000>;
+			d-cache-line-size = <32>;
 			CPU0_intc: interrupt-controller {
 				#interrupt-cells = <1>;
 				interrupt-controller;
@@ -48,13 +48,6 @@
 		#size-cells = <2>;
 		compatible = "andestech,riscv-ae350-soc";
 		ranges;
-	};
-
-	plmt0@e6000000 {
-		compatible = "riscv,plmt0";
-		interrupts-extended = <&CPU0_intc 7>;
-		reg = <0x0 0xe6000000 0x0 0x100000>;
-	};
 
 	plic0: interrupt-controller@e4000000 {
 		compatible = "riscv,plic0";
@@ -62,7 +55,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		reg = <0x0 0xe4000000 0x0 0x2000000>;
-		riscv,ndev=<31>;
+		riscv,ndev=<71>;
 		interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
 	};
 
@@ -76,6 +69,13 @@
 		interrupts-extended = <&CPU0_intc 3>;
 	};
 
+	plmt0@e6000000 {
+		compatible = "riscv,plmt0";
+			interrupts-extended = <&CPU0_intc 7>;
+			reg = <0x0 0xe6000000 0x0 0x100000>;
+		};
+	};
+
 	spiclk: virt_100mhz {
 		#clock-cells = <0>;
 		compatible = "fixed-clock";
@@ -85,7 +85,7 @@
 	timer0: timer@f0400000 {
 		compatible = "andestech,atcpit100";
 		reg = <0x0 0xf0400000 0x0 0x1000>;
-		clock-frequency = <40000000>;
+		clock-frequency = <60000000>;
 		interrupts = <3 4>;
 		interrupt-parent = <&plic0>;
 	};
@@ -119,11 +119,89 @@
 		interrupt-parent = <&plic0>;
 	};
 
+	dma0: dma@f0c00000 {
+		compatible = "andestech,atcdmac300";
+		reg = <0x0 0xf0c00000 0x0 0x1000>;
+		interrupts = <10 4 64 4 65 4 66 4 67 4 68 4 69 4 70 4 71 4>;
+		dma-channels = <8>;
+		interrupt-parent = <&plic0>;
+	};
+
+	lcd0: lcd@e0200000 {
+		compatible = "andestech,atflcdc100";
+		reg = <0x0 0xe0200000 0x0 0x1000>;
+		interrupts = <20 4>;
+		interrupt-parent = <&plic0>;
+	};
+
 	smc0: smc@e0400000 {
 		compatible = "andestech,atfsmc020";
 		reg = <0x0 0xe0400000 0x0 0x1000>;
 	};
 
+	snd0: snd@f0d00000 {
+		compatible = "andestech,atfac97";
+		reg = <0x0 0xf0d00000 0x0 0x1000>;
+		interrupts = <17 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	virtio_mmio@fe007000 {
+		interrupts = <0x17 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe007000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe006000 {
+		interrupts = <0x16 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe006000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe005000 {
+		interrupts = <0x15 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe005000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe004000 {
+		interrupts = <0x14 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe004000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe003000 {
+		interrupts = <0x13 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe003000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe002000 {
+		interrupts = <0x12 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe002000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe001000 {
+		interrupts = <0x11 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe001000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe000000 {
+		interrupts = <0x10 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe000000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
 	nor@0,0 {
 		compatible = "cfi-flash";
 		reg = <0x0 0x88000000 0x0 0x1000>;
@@ -138,9 +216,8 @@
 		#size-cells = <0>;
 		num-cs = <1>;
 		clocks = <&spiclk>;
-		interrupts = <3 4>;
+		interrupts = <4 4>;
 		interrupt-parent = <&plic0>;
-
 		flash@0 {
 			compatible = "spi-flash";
 			spi-max-frequency = <50000000>;
diff --git a/arch/riscv/dts/ae350_32.dts b/arch/riscv/dts/ae350_32.dts
new file mode 100644
index 0000000..0679827
--- /dev/null
+++ b/arch/riscv/dts/ae350_32.dts
@@ -0,0 +1,229 @@
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "andestech,a25";
+	model = "andestech,a25";
+
+	aliases {
+		uart0 = &serial0;
+		spi0 = &spi;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,38400n8  debug loglevel=7";
+		stdout-path = "uart0:38400n8";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		timebase-frequency = <60000000>;
+		CPU0: cpu@0 {
+			device_type = "cpu";
+			reg = <0>;
+			status = "okay";
+			compatible = "riscv";
+			riscv,isa = "rv32imafdc";
+			mmu-type = "riscv,sv32";
+			clock-frequency = <60000000>;
+			d-cache-size = <0x8000>;
+			d-cache-line-size = <32>;
+			CPU0_intc: interrupt-controller {
+				#interrupt-cells = <1>;
+				interrupt-controller;
+				compatible = "riscv,cpu-intc";
+			};
+		};
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x00000000 0x40000000>;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "andestech,riscv-ae350-soc";
+		ranges;
+
+	plic0: interrupt-controller@e4000000 {
+		compatible = "riscv,plic0";
+		#address-cells = <1>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		reg = <0xe4000000 0x2000000>;
+		riscv,ndev=<71>;
+		interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
+	};
+
+	plic1: interrupt-controller@e6400000 {
+		compatible = "riscv,plic1";
+		#address-cells = <1>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		reg = <0xe6400000 0x400000>;
+		riscv,ndev=<1>;
+		interrupts-extended = <&CPU0_intc 3>;
+	};
+
+	plmt0@e6000000 {
+		compatible = "riscv,plmt0";
+			interrupts-extended = <&CPU0_intc 7>;
+			reg = <0xe6000000 0x100000>;
+		};
+	};
+
+	spiclk: virt_100mhz {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <100000000>;
+	};
+
+	timer0: timer@f0400000 {
+		compatible = "andestech,atcpit100";
+		reg = <0xf0400000 0x1000>;
+		clock-frequency = <60000000>;
+		interrupts = <3 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	serial0: serial@f0300000 {
+		compatible = "andestech,uart16550", "ns16550a";
+		reg = <0xf0300000 0x1000>;
+		interrupts = <9 4>;
+		clock-frequency = <19660800>;
+		reg-shift = <2>;
+		reg-offset = <32>;
+		no-loopback-test = <1>;
+		interrupt-parent = <&plic0>;
+	};
+
+	mac0: mac@e0100000 {
+		compatible = "andestech,atmac100";
+		reg = <0xe0100000 0x1000>;
+		interrupts = <19 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	mmc0: mmc@f0e00000 {
+		compatible = "andestech,atfsdc010";
+		max-frequency = <100000000>;
+		clock-freq-min-max = <400000 100000000>;
+		fifo-depth = <0x10>;
+		reg = <0xf0e00000 0x1000>;
+		interrupts = <18 4>;
+		cap-sd-highspeed;
+		interrupt-parent = <&plic0>;
+	};
+
+	dma0: dma@f0c00000 {
+		compatible = "andestech,atcdmac300";
+		reg = <0xf0c00000 0x1000>;
+		interrupts = <10 4 64 4 65 4 66 4 67 4 68 4 69 4 70 4 71 4>;
+		dma-channels = <8>;
+		interrupt-parent = <&plic0>;
+	};
+
+	lcd0: lcd@e0200000 {
+		compatible = "andestech,atflcdc100";
+		reg = <0xe0200000 0x1000>;
+		interrupts = <20 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	smc0: smc@e0400000 {
+		compatible = "andestech,atfsmc020";
+		reg = <0xe0400000 0x1000>;
+	};
+
+	snd0: snd@f0d00000 {
+		compatible = "andestech,atfac97";
+		reg = <0xf0d00000 0x1000>;
+		interrupts = <17 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	virtio_mmio@fe007000 {
+		interrupts = <0x17 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0xfe007000 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe006000 {
+		interrupts = <0x16 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0xfe006000 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe005000 {
+		interrupts = <0x15 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0xfe005000 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe004000 {
+		interrupts = <0x14 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0xfe004000 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe003000 {
+		interrupts = <0x13 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0xfe003000 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe002000 {
+		interrupts = <0x12 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0xfe002000 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe001000 {
+		interrupts = <0x11 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0xfe001000 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe000000 {
+		interrupts = <0x10 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0xfe000000 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	nor@0,0 {
+		compatible = "cfi-flash";
+		reg = <0x88000000 0x1000>;
+		bank-width = <2>;
+		device-width = <1>;
+	};
+
+	spi: spi@f0b00000 {
+		compatible = "andestech,atcspi200";
+		reg = <0xf0b00000 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		num-cs = <1>;
+		clocks = <&spiclk>;
+		interrupts = <4 4>;
+		interrupt-parent = <&plic0>;
+		flash@0 {
+			compatible = "spi-flash";
+			spi-max-frequency = <50000000>;
+			reg = <0>;
+			spi-cpol;
+			spi-cpha;
+		};
+	};
+};
diff --git a/arch/riscv/dts/ae350_64.dts b/arch/riscv/dts/ae350_64.dts
new file mode 100644
index 0000000..e48c298
--- /dev/null
+++ b/arch/riscv/dts/ae350_64.dts
@@ -0,0 +1,229 @@
+/dts-v1/;
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	compatible = "andestech,ax25";
+	model = "andestech,ax25";
+
+	aliases {
+		uart0 = &serial0;
+		spi0 = &spi;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,38400n8  debug loglevel=7";
+		stdout-path = "uart0:38400n8";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		timebase-frequency = <60000000>;
+		CPU0: cpu@0 {
+			device_type = "cpu";
+			reg = <0>;
+			status = "okay";
+			compatible = "riscv";
+			riscv,isa = "rv64imafdc";
+			mmu-type = "riscv,sv39";
+			clock-frequency = <60000000>;
+			d-cache-size = <0x8000>;
+			d-cache-line-size = <32>;
+			CPU0_intc: interrupt-controller {
+				#interrupt-cells = <1>;
+				interrupt-controller;
+				compatible = "riscv,cpu-intc";
+			};
+		};
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x00000000 0x0 0x40000000>;
+	};
+
+	soc {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		compatible = "andestech,riscv-ae350-soc";
+		ranges;
+
+	plic0: interrupt-controller@e4000000 {
+		compatible = "riscv,plic0";
+		#address-cells = <2>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		reg = <0x0 0xe4000000 0x0 0x2000000>;
+		riscv,ndev=<71>;
+		interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
+	};
+
+	plic1: interrupt-controller@e6400000 {
+		compatible = "riscv,plic1";
+		#address-cells = <2>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		reg = <0x0 0xe6400000 0x0 0x400000>;
+		riscv,ndev=<1>;
+		interrupts-extended = <&CPU0_intc 3>;
+	};
+
+	plmt0@e6000000 {
+		compatible = "riscv,plmt0";
+			interrupts-extended = <&CPU0_intc 7>;
+			reg = <0x0 0xe6000000 0x0 0x100000>;
+		};
+	};
+
+	spiclk: virt_100mhz {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <100000000>;
+	};
+
+	timer0: timer@f0400000 {
+		compatible = "andestech,atcpit100";
+		reg = <0x0 0xf0400000 0x0 0x1000>;
+		clock-frequency = <60000000>;
+		interrupts = <3 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	serial0: serial@f0300000 {
+		compatible = "andestech,uart16550", "ns16550a";
+		reg = <0x0 0xf0300000 0x0 0x1000>;
+		interrupts = <9 4>;
+		clock-frequency = <19660800>;
+		reg-shift = <2>;
+		reg-offset = <32>;
+		no-loopback-test = <1>;
+		interrupt-parent = <&plic0>;
+	};
+
+	mac0: mac@e0100000 {
+		compatible = "andestech,atmac100";
+		reg = <0x0 0xe0100000 0x0 0x1000>;
+		interrupts = <19 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	mmc0: mmc@f0e00000 {
+		compatible = "andestech,atfsdc010";
+		max-frequency = <100000000>;
+		clock-freq-min-max = <400000 100000000>;
+		fifo-depth = <0x10>;
+		reg = <0x0 0xf0e00000 0x0 0x1000>;
+		interrupts = <18 4>;
+		cap-sd-highspeed;
+		interrupt-parent = <&plic0>;
+	};
+
+	dma0: dma@f0c00000 {
+		compatible = "andestech,atcdmac300";
+		reg = <0x0 0xf0c00000 0x0 0x1000>;
+		interrupts = <10 4 64 4 65 4 66 4 67 4 68 4 69 4 70 4 71 4>;
+		dma-channels = <8>;
+		interrupt-parent = <&plic0>;
+	};
+
+	lcd0: lcd@e0200000 {
+		compatible = "andestech,atflcdc100";
+		reg = <0x0 0xe0200000 0x0 0x1000>;
+		interrupts = <20 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	smc0: smc@e0400000 {
+		compatible = "andestech,atfsmc020";
+		reg = <0x0 0xe0400000 0x0 0x1000>;
+	};
+
+	snd0: snd@f0d00000 {
+		compatible = "andestech,atfac97";
+		reg = <0x0 0xf0d00000 0x0 0x1000>;
+		interrupts = <17 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	virtio_mmio@fe007000 {
+		interrupts = <0x17 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe007000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe006000 {
+		interrupts = <0x16 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe006000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe005000 {
+		interrupts = <0x15 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe005000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe004000 {
+		interrupts = <0x14 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe004000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe003000 {
+		interrupts = <0x13 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe003000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe002000 {
+		interrupts = <0x12 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe002000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe001000 {
+		interrupts = <0x11 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe001000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe000000 {
+		interrupts = <0x10 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe000000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	nor@0,0 {
+		compatible = "cfi-flash";
+		reg = <0x0 0x88000000 0x0 0x1000>;
+		bank-width = <2>;
+		device-width = <1>;
+	};
+
+	spi: spi@f0b00000 {
+		compatible = "andestech,atcspi200";
+		reg = <0x0 0xf0b00000 0x0 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		num-cs = <1>;
+		clocks = <&spiclk>;
+		interrupts = <4 4>;
+		interrupt-parent = <&plic0>;
+		flash@0 {
+			compatible = "spi-flash";
+			spi-max-frequency = <50000000>;
+			reg = <0>;
+			spi-cpol;
+			spi-cpha;
+		};
+	};
+};
diff --git a/arch/riscv/include/asm/barrier.h b/arch/riscv/include/asm/barrier.h
new file mode 100644
index 0000000..a3f60a8
--- /dev/null
+++ b/arch/riscv/include/asm/barrier.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2013 Regents of the University of California
+ * Copyright (C) 2017 SiFive
+ *
+ * Taken from Linux arch/riscv/include/asm/barrier.h, which is based on
+ * arch/arm/include/asm/barrier.h
+ */
+
+#ifndef _ASM_RISCV_BARRIER_H
+#define _ASM_RISCV_BARRIER_H
+
+#ifndef __ASSEMBLY__
+
+#define nop()		__asm__ __volatile__ ("nop")
+
+#define RISCV_FENCE(p, s) \
+	__asm__ __volatile__ ("fence " #p "," #s : : : "memory")
+
+/* These barriers need to enforce ordering on both devices or memory. */
+#define mb()		RISCV_FENCE(iorw,iorw)
+#define rmb()		RISCV_FENCE(ir,ir)
+#define wmb()		RISCV_FENCE(ow,ow)
+
+/* These barriers do not need to enforce ordering on devices, just memory. */
+#define __smp_mb()	RISCV_FENCE(rw,rw)
+#define __smp_rmb()	RISCV_FENCE(r,r)
+#define __smp_wmb()	RISCV_FENCE(w,w)
+
+#define __smp_store_release(p, v)					\
+do {									\
+	compiletime_assert_atomic_type(*p);				\
+	RISCV_FENCE(rw,w);						\
+	WRITE_ONCE(*p, v);						\
+} while (0)
+
+#define __smp_load_acquire(p)						\
+({									\
+	typeof(*p) ___p1 = READ_ONCE(*p);				\
+	compiletime_assert_atomic_type(*p);				\
+	RISCV_FENCE(r,rw);						\
+	___p1;								\
+})
+
+/*
+ * This is a very specific barrier: it's currently only used in two places in
+ * the kernel, both in the scheduler.  See include/linux/spinlock.h for the two
+ * orderings it guarantees, but the "critical section is RCsc" guarantee
+ * mandates a barrier on RISC-V.  The sequence looks like:
+ *
+ *    lr.aq lock
+ *    sc    lock <= LOCKED
+ *    smp_mb__after_spinlock()
+ *    // critical section
+ *    lr    lock
+ *    sc.rl lock <= UNLOCKED
+ *
+ * The AQ/RL pair provides a RCpc critical section, but there's not really any
+ * way we can take advantage of that here because the ordering is only enforced
+ * on that one lock.  Thus, we're just doing a full fence.
+ */
+#define smp_mb__after_spinlock()	RISCV_FENCE(rw,rw)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_BARRIER_H */
diff --git a/arch/riscv/include/asm/cache.h b/arch/riscv/include/asm/cache.h
index ca83dd6..ec8fe20 100644
--- a/arch/riscv/include/asm/cache.h
+++ b/arch/riscv/include/asm/cache.h
@@ -7,6 +7,9 @@
 #ifndef _ASM_RISCV_CACHE_H
 #define _ASM_RISCV_CACHE_H
 
+/* cache */
+void	cache_flush(void);
+
 /*
  * The current upper bound for RISCV L1 data cache line sizes is 32 bytes.
  * We use that value for aligning DMA buffers unless the board config has
diff --git a/arch/riscv/include/asm/encoding.h b/arch/riscv/include/asm/encoding.h
index 9ea50ce..97cf906 100644
--- a/arch/riscv/include/asm/encoding.h
+++ b/arch/riscv/include/asm/encoding.h
@@ -7,6 +7,12 @@
 #ifndef RISCV_CSR_ENCODING_H
 #define RISCV_CSR_ENCODING_H
 
+#ifdef CONFIG_RISCV_SMODE
+#define MODE_PREFIX(__suffix)	s##__suffix
+#else
+#define MODE_PREFIX(__suffix)	m##__suffix
+#endif
+
 #define MSTATUS_UIE	0x00000001
 #define MSTATUS_SIE	0x00000002
 #define MSTATUS_HIE	0x00000004
diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
index f4a76d87..acf5a96 100644
--- a/arch/riscv/include/asm/io.h
+++ b/arch/riscv/include/asm/io.h
@@ -10,22 +10,13 @@
 #ifdef __KERNEL__
 
 #include <linux/types.h>
+#include <asm/barrier.h>
 #include <asm/byteorder.h>
 
 static inline void sync(void)
 {
 }
 
-/*
- * Given a physical address and a length, return a virtual address
- * that can be used to access the memory range with the caching
- * properties specified by "flags".
- */
-#define MAP_NOCACHE	(0)
-#define MAP_WRCOMBINE	(0)
-#define MAP_WRBACK	(0)
-#define MAP_WRTHROUGH	(0)
-
 #ifdef CONFIG_ARCH_MAP_SYSMEM
 static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
 {
@@ -48,25 +39,7 @@
 }
 #endif
 
-static inline void *
-map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
-{
-	return (void *)paddr;
-}
-
 /*
- * Take down a mapping set up by map_physmem().
- */
-static inline void unmap_physmem(void *vaddr, unsigned long flags)
-{
-}
-
-static inline phys_addr_t virt_to_phys(void *vaddr)
-{
-	return (phys_addr_t)(vaddr);
-}
-
-/*
  * Generic virtual read/write.  Note that we don't support half-word
  * read/writes.  We define __arch_*[bl] here, and leave __arch_*w
  * to the architecture specific code.
@@ -74,12 +47,12 @@
 #define __arch_getb(a)			(*(unsigned char *)(a))
 #define __arch_getw(a)			(*(unsigned short *)(a))
 #define __arch_getl(a)			(*(unsigned int *)(a))
-#define __arch_getq(a)			(*(unsigned long *)(a))
+#define __arch_getq(a)			(*(unsigned long long *)(a))
 
 #define __arch_putb(v, a)		(*(unsigned char *)(a) = (v))
 #define __arch_putw(v, a)		(*(unsigned short *)(a) = (v))
 #define __arch_putl(v, a)		(*(unsigned int *)(a) = (v))
-#define __arch_putq(v, a)		(*(unsigned long *)(a) = (v))
+#define __arch_putq(v, a)		(*(unsigned long long *)(a) = (v))
 
 #define __raw_writeb(v, a)		__arch_putb(v, a)
 #define __raw_writew(v, a)		__arch_putw(v, a)
@@ -91,13 +64,9 @@
 #define __raw_readl(a)			__arch_getl(a)
 #define __raw_readq(a)			__arch_getq(a)
 
-/*
- * TODO: The kernel offers some more advanced versions of barriers, it might
- * have some advantages to use them instead of the simple one here.
- */
-#define dmb()		__asm__ __volatile__ ("" : : : "memory")
-#define __iormb()	dmb()
-#define __iowmb()	dmb()
+#define dmb()		mb()
+#define __iormb()	rmb()
+#define __iowmb()	wmb()
 
 static inline void writeb(u8 val, volatile void __iomem *addr)
 {
@@ -152,7 +121,7 @@
 
 static inline u64 readq(const volatile void __iomem *addr)
 {
-	u32	val;
+	u64	val;
 
 	val = __arch_getq(addr);
 	__iormb();
@@ -487,4 +456,7 @@
 
 #endif	/* __mem_isa */
 #endif	/* __KERNEL__ */
+
+#include <asm-generic/io.h>
+
 #endif	/* __ASM_RISCV_IO_H */
diff --git a/arch/riscv/include/asm/posix_types.h b/arch/riscv/include/asm/posix_types.h
index 7438dbe..0fc0520 100644
--- a/arch/riscv/include/asm/posix_types.h
+++ b/arch/riscv/include/asm/posix_types.h
@@ -37,10 +37,10 @@
 #ifdef __GNUC__
 typedef __SIZE_TYPE__		__kernel_size_t;
 #else
-typedef unsigned int		__kernel_size_t;
+typedef unsigned long		__kernel_size_t;
 #endif
-typedef int			__kernel_ssize_t;
-typedef int			__kernel_ptrdiff_t;
+typedef long			__kernel_ssize_t;
+typedef long			__kernel_ptrdiff_t;
 typedef long			__kernel_time_t;
 typedef long			__kernel_suseconds_t;
 typedef long			__kernel_clock_t;
diff --git a/arch/riscv/include/asm/types.h b/arch/riscv/include/asm/types.h
index bd86271..403cf9a 100644
--- a/arch/riscv/include/asm/types.h
+++ b/arch/riscv/include/asm/types.h
@@ -21,7 +21,11 @@
  */
 #ifdef __KERNEL__
 
+#ifdef CONFIG_ARCH_RV64I
+#define BITS_PER_LONG 64
+#else
 #define BITS_PER_LONG 32
+#endif
 
 #include <stddef.h>
 
diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
index 2b5ccce..124aeef 100644
--- a/arch/riscv/lib/bootm.c
+++ b/arch/riscv/lib/bootm.c
@@ -8,6 +8,8 @@
 
 #include <common.h>
 #include <command.h>
+#include <dm.h>
+#include <dm/root.h>
 #include <image.h>
 #include <asm/byteorder.h>
 #include <asm/csr.h>
@@ -26,26 +28,41 @@
 	return 0;
 }
 
-int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
+/**
+ * announce_and_cleanup() - Print message and prepare for kernel boot
+ *
+ * @fake: non-zero to do everything except actually boot
+ */
+static void announce_and_cleanup(int fake)
 {
-	void	(*kernel)(ulong hart, void *dtb);
-
-	/*
-	 * allow the PREP bootm subcommand, it is required for bootm to work
-	 */
-	if (flag & BOOTM_STATE_OS_PREP)
-		return 0;
+	printf("\nStarting kernel ...%s\n\n", fake ?
+		"(fake run for tracing)" : "");
+	bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
+#ifdef CONFIG_BOOTSTAGE_FDT
+	bootstage_fdt_add_report();
+#endif
+#ifdef CONFIG_BOOTSTAGE_REPORT
+	bootstage_report();
+#endif
 
-	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
-		return 1;
+#ifdef CONFIG_USB_DEVICE
+	udc_disconnect();
+#endif
 
-	kernel = (void (*)(ulong, void *))images->ep;
+	board_quiesce_devices();
 
-	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+	/*
+	 * Call remove function of all devices with a removal flag set.
+	 * This may be useful for last-stage operations, like cancelling
+	 * of DMA operation or releasing device internal buffers.
+	 */
+	dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
 
-	debug("## Transferring control to Linux (at address %08lx) ...\n",
-	       (ulong)kernel);
+	cleanup_before_linux();
+}
 
+static void boot_prep_linux(bootm_headers_t *images)
+{
 	if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
 #ifdef CONFIG_OF_LIBFDT
 		debug("using: FDT\n");
@@ -54,24 +71,50 @@
 			hang();
 		}
 #endif
+	} else {
+		printf("Device tree not found or missing FDT support\n");
+		hang();
 	}
+}
+
+static void boot_jump_linux(bootm_headers_t *images, int flag)
+{
+	void (*kernel)(ulong hart, void *dtb);
+	int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
 
-	/* we assume that the kernel is in place */
-	printf("\nStarting kernel ...\n\n");
+	kernel = (void (*)(ulong, void *))images->ep;
 
-	/*
-	 * Call remove function of all devices with a removal flag set.
-	 * This may be useful for last-stage operations, like cancelling
-	 * of DMA operation or releasing device internal buffers.
-	 */
-	dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
+	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
 
-	cleanup_before_linux();
+	debug("## Transferring control to Linux (at address %08lx) ...\n",
+	      (ulong)kernel);
 
-	if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
-		kernel(csr_read(mhartid), images->ft_addr);
+	announce_and_cleanup(fake);
 
-	/* does not return */
+	if (!fake) {
+		if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
+			kernel(csr_read(mhartid), images->ft_addr);
+	}
+}
+
+int do_bootm_linux(int flag, int argc, char * const argv[],
+		   bootm_headers_t *images)
+{
+	/* No need for those on RISC-V */
+	if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE)
+		return -1;
 
-	return 1;
+	if (flag & BOOTM_STATE_OS_PREP) {
+		boot_prep_linux(images);
+		return 0;
+	}
+
+	if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) {
+		boot_jump_linux(images, flag);
+		return 0;
+	}
+
+	boot_prep_linux(images);
+	boot_jump_linux(images, flag);
+	return 0;
 }
diff --git a/arch/riscv/lib/cache.c b/arch/riscv/lib/cache.c
index 1d67c49..ae5c607 100644
--- a/arch/riscv/lib/cache.c
+++ b/arch/riscv/lib/cache.c
@@ -6,44 +6,68 @@
 
 #include <common.h>
 
+void invalidate_icache_all(void)
+{
+	asm volatile ("fence.i" ::: "memory");
+}
+
+void flush_dcache_all(void)
+{
+	asm volatile ("fence" :::"memory");
+}
 void flush_dcache_range(unsigned long start, unsigned long end)
 {
+	flush_dcache_all();
 }
 
 void invalidate_icache_range(unsigned long start, unsigned long end)
 {
+	/*
+	 * RISC-V does not have an instruction for invalidating parts of the
+	 * instruction cache. Invalidate all of it instead.
+	 */
+	invalidate_icache_all();
 }
 
 void invalidate_dcache_range(unsigned long start, unsigned long end)
 {
+	flush_dcache_all();
+}
+
+void cache_flush(void)
+{
+	invalidate_icache_all();
+	flush_dcache_all();
 }
 
 void flush_cache(unsigned long addr, unsigned long size)
 {
+	invalidate_icache_all();
+	flush_dcache_all();
 }
 
-void icache_enable(void)
+__weak void icache_enable(void)
 {
 }
 
-void icache_disable(void)
+__weak void icache_disable(void)
 {
 }
 
-int icache_status(void)
+__weak int icache_status(void)
 {
 	return 0;
 }
 
-void dcache_enable(void)
+__weak void dcache_enable(void)
 {
 }
 
-void dcache_disable(void)
+__weak void dcache_disable(void)
 {
 }
 
-int dcache_status(void)
+__weak int dcache_status(void)
 {
 	return 0;
 }
diff --git a/arch/riscv/lib/crt0_riscv_efi.S b/arch/riscv/lib/crt0_riscv_efi.S
index 18f61f5..b7b5329 100644
--- a/arch/riscv/lib/crt0_riscv_efi.S
+++ b/arch/riscv/lib/crt0_riscv_efi.S
@@ -41,13 +41,13 @@
 	.short	2				/* nr_sections */
 	.long	0				/* TimeDateStamp */
 	.long	0				/* PointerToSymbolTable */
-	.long	1				/* NumberOfSymbols */
+	.long	0				/* NumberOfSymbols */
 	.short	section_table - optional_header	/* SizeOfOptionalHeader */
-	/*
-	 * Characteristics: IMAGE_FILE_DEBUG_STRIPPED |
-	 * IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LINE_NUMS_STRIPPED
-	 */
-	.short	0x206
+	/* Characteristics */
+	.short	(IMAGE_FILE_EXECUTABLE_IMAGE | \
+		 IMAGE_FILE_LINE_NUMS_STRIPPED | \
+		 IMAGE_FILE_LOCAL_SYMS_STRIPPED | \
+		 IMAGE_FILE_DEBUG_STRIPPED)
 optional_header:
 	.short	0x20b				/* PE32+ format */
 	.byte	0x02				/* MajorLinkerVersion */
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c
index 0a0995a..3aff006 100644
--- a/arch/riscv/lib/interrupts.c
+++ b/arch/riscv/lib/interrupts.c
@@ -12,7 +12,7 @@
 #include <asm/system.h>
 #include <asm/encoding.h>
 
-static void _exit_trap(int code, uint epc, struct pt_regs *regs);
+static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs);
 
 int interrupt_init(void)
 {
@@ -34,17 +34,30 @@
 	return 0;
 }
 
-uint handle_trap(uint mcause, uint epc, struct pt_regs *regs)
+ulong handle_trap(ulong cause, ulong epc, struct pt_regs *regs)
 {
-	uint is_int;
+	ulong is_irq, irq;
 
-	is_int = (mcause & MCAUSE_INT);
-	if ((is_int) && ((mcause & MCAUSE_CAUSE)  == IRQ_M_EXT))
-		external_interrupt(0);	/* handle_m_ext_interrupt */
-	else if ((is_int) && ((mcause & MCAUSE_CAUSE)  == IRQ_M_TIMER))
-		timer_interrupt(0);	/* handle_m_timer_interrupt */
-	else
-		_exit_trap(mcause, epc, regs);
+	is_irq = (cause & MCAUSE_INT);
+	irq = (cause & ~MCAUSE_INT);
+
+	if (is_irq) {
+		switch (irq) {
+		case IRQ_M_EXT:
+		case IRQ_S_EXT:
+			external_interrupt(0);	/* handle external interrupt */
+			break;
+		case IRQ_M_TIMER:
+		case IRQ_S_TIMER:
+			timer_interrupt(0);	/* handle timer interrupt */
+			break;
+		default:
+			_exit_trap(cause, epc, regs);
+			break;
+		};
+	} else {
+		_exit_trap(cause, epc, regs);
+	}
 
 	return epc;
 }
@@ -60,16 +73,33 @@
 {
 }
 
-static void _exit_trap(int code, uint epc, struct pt_regs *regs)
+static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs)
 {
 	static const char * const exception_code[] = {
 		"Instruction address misaligned",
 		"Instruction access fault",
 		"Illegal instruction",
 		"Breakpoint",
-		"Load address misaligned"
+		"Load address misaligned",
+		"Load access fault",
+		"Store/AMO address misaligned",
+		"Store/AMO access fault",
+		"Environment call from U-mode",
+		"Environment call from S-mode",
+		"Reserved",
+		"Environment call from M-mode",
+		"Instruction page fault",
+		"Load page fault",
+		"Reserved",
+		"Store/AMO page fault",
 	};
 
-	printf("exception code: %d , %s , epc %08x , ra %08lx\n",
-		code, exception_code[code], epc, regs->ra);
+	if (code < ARRAY_SIZE(exception_code)) {
+		printf("exception code: %ld , %s , epc %lx , ra %lx\n",
+		       code, exception_code[code], epc, regs->ra);
+	} else {
+		printf("Reserved\n");
+	}
+
+	hang();
 }
diff --git a/arch/riscv/lib/setjmp.S b/arch/riscv/lib/setjmp.S
index 8f5a6a2..72bc924 100644
--- a/arch/riscv/lib/setjmp.S
+++ b/arch/riscv/lib/setjmp.S
@@ -6,7 +6,7 @@
 #include <config.h>
 #include <linux/linkage.h>
 
-#ifdef CONFIG_CPU_RISCV_64
+#ifdef CONFIG_ARCH_RV64I
 #define STORE_IDX(reg, idx)	sd reg, (idx*8)(a0)
 #define LOAD_IDX(reg, idx)	ld reg, (idx*8)(a0)
 #else
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index 6098945..fdfb209 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -2,7 +2,7 @@
 /*
  * Copyright (c) 2011 The Chromium OS Authors.
  */
-#define DEBUG
+
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
@@ -105,8 +105,8 @@
 	state = state_get_current();
 	list_for_each_entry(mentry, &state->mapmem_head, sibling_node) {
 		if (mentry->tag == paddr) {
-			printf("%s: Used map from %lx to %p\n", __func__,
-			       (ulong)paddr, mentry->ptr);
+			debug("%s: Used map from %lx to %p\n", __func__,
+			      (ulong)paddr, mentry->ptr);
 			return mentry->ptr;
 		}
 	}
@@ -152,7 +152,7 @@
 		       __func__, ptr, (ulong)gd->ram_size);
 		os_abort();
 	}
-	printf("%s: Used map from %p to %lx\n", __func__, ptr, mentry->tag);
+	debug("%s: Used map from %p to %lx\n", __func__, ptr, mentry->tag);
 
 	return mentry->tag;
 }
diff --git a/arch/sandbox/cpu/eth-raw-os.c b/arch/sandbox/cpu/eth-raw-os.c
index 75bfaa4..8d05bc2 100644
--- a/arch/sandbox/cpu/eth-raw-os.c
+++ b/arch/sandbox/cpu/eth-raw-os.c
@@ -11,6 +11,7 @@
 #include <netinet/in.h>
 #include <netinet/ip.h>
 #include <netinet/udp.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -23,6 +24,8 @@
 #include <linux/if_ether.h>
 #include <linux/if_packet.h>
 
+#include <os.h>
+
 struct sandbox_eth_raw_if_nameindex *sandbox_eth_raw_if_nameindex(void)
 {
 	return (struct sandbox_eth_raw_if_nameindex *)if_nameindex();
@@ -71,7 +74,7 @@
 
 	/* Prepare device struct */
 	priv->local_bind_sd = -1;
-	priv->device = malloc(sizeof(struct sockaddr_ll));
+	priv->device = os_malloc(sizeof(struct sockaddr_ll));
 	if (priv->device == NULL)
 		return -ENOMEM;
 	device = priv->device;
@@ -144,7 +147,7 @@
 	/* Prepare device struct */
 	priv->local_bind_sd = -1;
 	priv->local_bind_udp_port = 0;
-	priv->device = malloc(sizeof(struct sockaddr_in));
+	priv->device = os_malloc(sizeof(struct sockaddr_in));
 	if (priv->device == NULL)
 		return -ENOMEM;
 	device = priv->device;
@@ -279,7 +282,7 @@
 
 void sandbox_eth_raw_os_stop(struct eth_sandbox_raw_priv *priv)
 {
-	free(priv->device);
+	os_free(priv->device);
 	priv->device = NULL;
 	close(priv->sd);
 	priv->sd = -1;
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 325ded5..62e05c5 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -98,9 +98,8 @@
 	exit(exit_code);
 }
 
-int os_write_file(const char *name, const void *buf, int size)
+int os_write_file(const char *fname, const void *buf, int size)
 {
-	char fname[256];
 	int fd;
 
 	fd = os_open(fname, OS_O_WRONLY | OS_O_CREAT | OS_O_TRUNC);
@@ -110,14 +109,53 @@
 	}
 	if (os_write(fd, buf, size) != size) {
 		printf("Cannot write to file '%s'\n", fname);
+		os_close(fd);
 		return -EIO;
 	}
 	os_close(fd);
-	printf("Write '%s', size %#x (%d)\n", name, size, size);
 
 	return 0;
 }
 
+int os_read_file(const char *fname, void **bufp, int *sizep)
+{
+	off_t size;
+	int ret = -EIO;
+	int fd;
+
+	fd = os_open(fname, OS_O_RDONLY);
+	if (fd < 0) {
+		printf("Cannot open file '%s'\n", fname);
+		goto err;
+	}
+	size = os_lseek(fd, 0, OS_SEEK_END);
+	if (size < 0) {
+		printf("Cannot seek to end of file '%s'\n", fname);
+		goto err;
+	}
+	if (os_lseek(fd, 0, OS_SEEK_SET) < 0) {
+		printf("Cannot seek to start of file '%s'\n", fname);
+		goto err;
+	}
+	*bufp = os_malloc(size);
+	if (!*bufp) {
+		printf("Not enough memory to read file '%s'\n", fname);
+		ret = -ENOMEM;
+		goto err;
+	}
+	if (os_read(fd, *bufp, size) != size) {
+		printf("Cannot read from file '%s'\n", fname);
+		goto err;
+	}
+	os_close(fd);
+	*sizep = size;
+
+	return 0;
+err:
+	os_close(fd);
+	return ret;
+}
+
 /* Restore tty state when we exit */
 static struct termios orig_term;
 static bool term_setup;
@@ -343,7 +381,7 @@
 
 	while (node) {
 		next = node->next;
-		free(node);
+		os_free(node);
 		node = next;
 	}
 }
@@ -368,7 +406,7 @@
 	/* Create a buffer upfront, with typically sufficient size */
 	dirlen = strlen(dirname) + 2;
 	len = dirlen + 256;
-	fname = malloc(len);
+	fname = os_malloc(len);
 	if (!fname) {
 		ret = -ENOMEM;
 		goto done;
@@ -381,7 +419,7 @@
 			ret = errno;
 			break;
 		}
-		next = malloc(sizeof(*node) + strlen(entry->d_name) + 1);
+		next = os_malloc(sizeof(*node) + strlen(entry->d_name) + 1);
 		if (!next) {
 			os_dirent_free(head);
 			ret = -ENOMEM;
@@ -390,10 +428,10 @@
 		if (dirlen + strlen(entry->d_name) > len) {
 			len = dirlen + strlen(entry->d_name);
 			old_fname = fname;
-			fname = realloc(fname, len);
+			fname = os_realloc(fname, len);
 			if (!fname) {
-				free(old_fname);
-				free(next);
+				os_free(old_fname);
+				os_free(next);
 				os_dirent_free(head);
 				ret = -ENOMEM;
 				goto done;
@@ -427,7 +465,7 @@
 
 done:
 	closedir(dir);
-	free(fname);
+	os_free(fname);
 	return ret;
 }
 
@@ -525,20 +563,48 @@
 	return 0;
 }
 
-static int add_args(char ***argvp, const char *add_args[], int count)
+/**
+ * add_args() - Allocate a new argv with the given args
+ *
+ * This is used to create a new argv array with all the old arguments and some
+ * new ones that are passed in
+ *
+ * @argvp:  Returns newly allocated args list
+ * @add_args: Arguments to add, each a string
+ * @count: Number of arguments in @add_args
+ * @return 0 if OK, -ENOMEM if out of memory
+ */
+static int add_args(char ***argvp, char *add_args[], int count)
 {
-	char **argv;
+	char **argv, **ap;
 	int argc;
 
-	for (argv = *argvp, argc = 0; (*argvp)[argc]; argc++)
+	for (argc = 0; (*argvp)[argc]; argc++)
 		;
 
-	argv = malloc((argc + count + 1) * sizeof(char *));
+	argv = os_malloc((argc + count + 1) * sizeof(char *));
 	if (!argv) {
 		printf("Out of memory for %d argv\n", count);
 		return -ENOMEM;
 	}
+	for (ap = *argvp, argc = 0; *ap; ap++) {
+		char *arg = *ap;
+
+		/* Drop args that we don't want to propagate */
+		if (*arg == '-' && strlen(arg) == 2) {
+			switch (arg[1]) {
+			case 'j':
+			case 'm':
+				ap++;
+				continue;
+			}
+		} else if (!strcmp(arg, "--rm_memory")) {
+			ap++;
+			continue;
+		}
+		argv[argc++] = arg;
+	}
-	memcpy(argv, *argvp, argc * sizeof(char *));
+
 	memcpy(argv + argc, add_args, count * sizeof(char *));
 	argv[argc + count] = NULL;
 
@@ -546,21 +612,27 @@
 	return 0;
 }
 
-int os_jump_to_image(const void *dest, int size)
+/**
+ * os_jump_to_file() - Jump to a new program
+ *
+ * This saves the memory buffer, sets up arguments to the new process, then
+ * execs it.
+ *
+ * @fname: Filename to exec
+ * @return does not return on success, any return value is an error
+ */
+static int os_jump_to_file(const char *fname)
 {
 	struct sandbox_state *state = state_get_current();
-	char fname[30], mem_fname[30];
+	char mem_fname[30];
 	int fd, err;
-	const char *extra_args[5];
+	char *extra_args[5];
 	char **argv = state->argv;
+	int argc;
 #ifdef DEBUG
-	int argc, i;
+	int i;
 #endif
 
-	err = make_exec(fname, dest, size);
-	if (err)
-		return err;
-
 	strcpy(mem_fname, "/tmp/u-boot.mem.XXXXXX");
 	fd = mkstemp(mem_fname);
 	if (fd < 0)
@@ -573,14 +645,16 @@
 	os_fd_restore();
 
 	extra_args[0] = "-j";
-	extra_args[1] = fname;
+	extra_args[1] = (char *)fname;
 	extra_args[2] = "-m";
 	extra_args[3] = mem_fname;
-	extra_args[4] = "--rm_memory";
-	err = add_args(&argv, extra_args,
-		       sizeof(extra_args) / sizeof(extra_args[0]));
+	argc = 4;
+	if (state->ram_buf_rm)
+		extra_args[argc++] = "--rm_memory";
+	err = add_args(&argv, extra_args, argc);
 	if (err)
 		return err;
+	argv[0] = (char *)fname;
 
 #ifdef DEBUG
 	for (i = 0; argv[i]; i++)
@@ -591,13 +665,28 @@
 		os_exit(2);
 
 	err = execv(fname, argv);
-	free(argv);
-	if (err)
+	os_free(argv);
+	if (err) {
+		perror("Unable to run image");
+		printf("Image filename '%s'\n", mem_fname);
 		return err;
+	}
 
 	return unlink(fname);
 }
 
+int os_jump_to_image(const void *dest, int size)
+{
+	char fname[30];
+	int err;
+
+	err = make_exec(fname, dest, size);
+	if (err)
+		return err;
+
+	return os_jump_to_file(fname);
+}
+
 int os_find_u_boot(char *fname, int maxlen)
 {
 	struct sandbox_state *state = state_get_current();
@@ -646,9 +735,10 @@
 	}
 
 	/* Look for 'u-boot' in the parent directory of spl/ */
-	p = strstr(fname, "/spl/");
+	p = strstr(fname, "spl/");
 	if (p) {
-		strcpy(p, p + 4);
+		/* Remove the "spl" characters */
+		memmove(p, p + 4, strlen(p + 4) + 1);
 		fd = os_open(fname, O_RDONLY);
 		if (fd >= 0) {
 			close(fd);
@@ -661,17 +751,7 @@
 
 int os_spl_to_uboot(const char *fname)
 {
-	struct sandbox_state *state = state_get_current();
-	char *argv[state->argc + 1];
-	int ret;
-
-	memcpy(argv, state->argv, sizeof(char *) * (state->argc + 1));
-	argv[0] = (char *)fname;
-	ret = execv(fname, argv);
-	if (ret)
-		return ret;
-
-	return unlink(fname);
+	return os_jump_to_file(fname);
 }
 
 void os_localtime(struct rtc_time *rt)
diff --git a/arch/sandbox/cpu/sdl.c b/arch/sandbox/cpu/sdl.c
index adcb738..c7a8d94 100644
--- a/arch/sandbox/cpu/sdl.c
+++ b/arch/sandbox/cpu/sdl.c
@@ -9,6 +9,10 @@
 #include <sound.h>
 #include <asm/state.h>
 
+enum {
+	SAMPLE_RATE	= 22050,
+};
+
 static struct sdl_info {
 	SDL_Surface *screen;
 	int width;
@@ -18,6 +22,7 @@
 	uint frequency;
 	uint audio_pos;
 	uint audio_size;
+	uint sample_rate;
 	uint8_t *audio_data;
 	bool audio_active;
 	bool inited;
@@ -263,27 +268,8 @@
 	if (sdl.audio_active)
 		return 0;
 
-	/*
-	 * At present all sandbox sounds crash. This is probably due to
-	 * symbol name conflicts with U-Boot. We can remove the malloc()
-	 * probles with:
-	 *
-	 * #define USE_DL_PREFIX
-	 *
-	 * and get this:
-	 *
-	 * Assertion 'e->pollfd->fd == e->fd' failed at pulse/mainloop.c:676,
-	 *		function dispatch_pollfds(). Aborting.
-	 *
-	 * The right solution is probably to make U-Boot's names private or
-	 * link os.c and sdl.c against their libraries before liking with
-	 * U-Boot. TBD. For now sound is disabled.
-	 */
-	printf("(Warning: sandbox sound disabled)\n");
-	return 0;
-
 	/* Set the audio format */
-	wanted.freq = 22050;
+	wanted.freq = SAMPLE_RATE;
 	wanted.format = AUDIO_S16;
 	wanted.channels = 1;    /* 1 = mono, 2 = stereo */
 	wanted.samples = 1024;  /* Good low-latency value for callback */
@@ -309,6 +295,7 @@
 		goto err;
 	}
 	sdl.audio_active = true;
+	sdl.sample_rate = wanted.freq;
 
 	return 0;
 
@@ -322,7 +309,8 @@
 	if (!sdl.audio_active)
 		return -1;
 	sdl.frequency = frequency;
-	sound_create_square_wave((unsigned short *)sdl.audio_data,
+	sound_create_square_wave(sdl.sample_rate,
+				 (unsigned short *)sdl.audio_data,
 				 sdl.audio_size, frequency);
 	sdl.audio_pos = 0;
 	SDL_PauseAudio(0);
diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
index 42c149a..5005ed2 100644
--- a/arch/sandbox/cpu/spl.c
+++ b/arch/sandbox/cpu/spl.c
@@ -37,12 +37,39 @@
 		return ret;
 	}
 
-	/* Hopefully this will not return */
-	return os_spl_to_uboot(fname);
+	/* Set up spl_image to boot from jump_to_image_no_args() */
+	spl_image->arg = strdup(fname);
+	if (!spl_image->arg)
+		return log_msg_ret("Setup exec filename", -ENOMEM);
+
+	return 0;
 }
 SPL_LOAD_IMAGE_METHOD("sandbox", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
 
 void spl_board_init(void)
 {
+	struct sandbox_state *state = state_get_current();
+	struct udevice *dev;
+
 	preloader_console_init();
+	if (state->show_of_platdata) {
+		/*
+		 * Scan all the devices so that we can output their platform
+		 * data. See sandbox_spl_probe().
+		 */
+		printf("Scanning misc devices\n");
+		for (uclass_first_device(UCLASS_MISC, &dev);
+		     dev;
+		     uclass_next_device(&dev))
+			;
+	}
+}
+
+void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+{
+	const char *fname = spl_image->arg;
+
+	os_fd_restore();
+	os_spl_to_uboot(fname);
+	hang();
 }
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index 2ee3b48..b1566a8 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -283,6 +283,15 @@
 SANDBOX_CMDLINE_OPT_SHORT(log_level, 'L', 1,
 			  "Set log level (0=panic, 7=debug)");
 
+static int sandbox_cmdline_cb_show_of_platdata(struct sandbox_state *state,
+					       const char *arg)
+{
+	state->show_of_platdata = true;
+
+	return 0;
+}
+SANDBOX_CMDLINE_OPT(show_of_platdata, 0, "Show of-platdata in SPL");
+
 int board_run_command(const char *cmdline)
 {
 	printf("## Commands are disabled. Please enable CONFIG_CMDLINE.\n");
@@ -296,6 +305,16 @@
 	gd->ram_size = state->ram_size;
 }
 
+void state_show(struct sandbox_state *state)
+{
+	char **p;
+
+	printf("Arguments:\n");
+	for (p = state->argv; *p; p++)
+		printf("%s ", *p);
+	printf("\n");
+}
+
 int main(int argc, char *argv[])
 {
 	struct sandbox_state *state;
diff --git a/arch/sandbox/cpu/u-boot-spl.lds b/arch/sandbox/cpu/u-boot-spl.lds
index f97abdf..de65b01 100644
--- a/arch/sandbox/cpu/u-boot-spl.lds
+++ b/arch/sandbox/cpu/u-boot-spl.lds
@@ -14,7 +14,7 @@
 	}
 
 	__u_boot_sandbox_option_start = .;
-	_u_boot_sandbox_getopt : { *(.u_boot_sandbox_getopt) }
+	_u_boot_sandbox_getopt : { KEEP(*(.u_boot_sandbox_getopt)) }
 	__u_boot_sandbox_option_end = .;
 
 	__bss_start = .;
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index fb866e8..ce3c88c 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -20,6 +20,7 @@
 
 	cros_ec: cros-ec {
 		reg = <0 0>;
+		u-boot,dm-pre-reloc;
 		compatible = "google,cros-ec-sandbox";
 
 		/*
@@ -27,6 +28,7 @@
 		 * that the STM32L flash erases to 0, not 0xff.
 		 */
 		flash {
+			u-boot,dm-pre-reloc;
 			image-pos = <0x08000000>;
 			size = <0x20000>;
 			erase-value = <0>;
@@ -59,6 +61,7 @@
 	};
 
 	gpio_a: gpios@0 {
+		u-boot,dm-pre-reloc;
 		gpio-controller;
 		compatible = "sandbox,gpio";
 		#gpio-cells = <1>;
@@ -67,6 +70,7 @@
 	};
 
 	gpio_b: gpios@1 {
+		u-boot,dm-pre-reloc;
 		gpio-controller;
 		compatible = "sandbox,gpio";
 		#gpio-cells = <2>;
@@ -91,19 +95,11 @@
 		eeprom@2c {
 			reg = <0x2c>;
 			compatible = "i2c-eeprom";
-			emul {
-				compatible = "sandbox,i2c-eeprom";
-				sandbox,filename = "i2c.bin";
-				sandbox,size = <128>;
-			};
 		};
 
 		rtc_0: rtc@43 {
 			reg = <0x43>;
 			compatible = "sandbox-rtc";
-			emul {
-				compatible = "sandbox,i2c-rtc";
-			};
 		};
 		sandbox_pmic: sandbox_pmic {
 			reg = <0x40>;
@@ -112,6 +108,23 @@
 		mc34708: pmic@41 {
 			reg = <0x41>;
 		};
+
+		i2c_emul: emul {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0xff>;
+			compatible = "sandbox,i2c-emul-parent";
+			emul-eeprom {
+				reg = <0x2c>;
+				compatible = "sandbox,i2c-eeprom";
+				sandbox,filename = "i2c.bin";
+				sandbox,size = <256>;
+			};
+			emul0 {
+				reg = <0x43>;
+				compatible = "sandbox,i2c-rtc";
+			};
+		};
 	};
 
 	lcd {
@@ -178,12 +191,14 @@
 	};
 
 	spi@0 {
+		u-boot,dm-pre-reloc;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		reg = <0 0>;
 		compatible = "sandbox,spi";
 		cs-gpios = <0>, <&gpio_a 0>;
 		firmware_storage_spi: flash@0 {
+			u-boot,dm-pre-reloc;
 			reg = <0>;
 			compatible = "spansion,m25p16", "sandbox,spi-flash";
 			spi-max-frequency = <40000000>;
@@ -239,6 +254,7 @@
 	};
 
 	tpm {
+		u-boot,dm-pre-reloc;
 		compatible = "google,sandbox-tpm";
 	};
 
@@ -256,6 +272,7 @@
 
 	/* Needs to be available prior to relocation */
 	uart0: serial {
+		u-boot,dm-spl;
 		compatible = "sandbox,serial";
 		sandbox,text-colour = "cyan";
 		pinctrl-names = "default";
@@ -350,3 +367,10 @@
 
 #include "cros-ec-keyboard.dtsi"
 #include "sandbox_pmic.dtsi"
+
+&cros_ec {
+	u-boot,dm-pre-reloc;
+	keyboard-controller {
+		u-boot,dm-pre-reloc;
+	};
+};
diff --git a/arch/sandbox/dts/sandbox64.dts b/arch/sandbox/dts/sandbox64.dts
index 2c6d351..d30fd62 100644
--- a/arch/sandbox/dts/sandbox64.dts
+++ b/arch/sandbox/dts/sandbox64.dts
@@ -90,19 +90,11 @@
 		eeprom@2c {
 			reg = <0x2c>;
 			compatible = "i2c-eeprom";
-			emul {
-				compatible = "sandbox,i2c-eeprom";
-				sandbox,filename = "i2c.bin";
-				sandbox,size = <128>;
-			};
 		};
 
 		rtc_0: rtc@43 {
 			reg = <0x43>;
 			compatible = "sandbox-rtc";
-			emul {
-				compatible = "sandbox,i2c-rtc";
-			};
 		};
 		sandbox_pmic: sandbox_pmic {
 			reg = <0x40>;
@@ -111,6 +103,19 @@
 		mc34708: pmic@41 {
 			reg = <0x41>;
 		};
+
+		i2c_emul: emul {
+			reg = <0xff>;
+			compatible = "sandbox,i2c-emul-parent";
+			emul-eeprom {
+				compatible = "sandbox,i2c-eeprom";
+				sandbox,filename = "i2c.bin";
+				sandbox,size = <256>;
+			};
+			emul0 {
+				compatible = "sandbox,i2c-rtc";
+			};
+		};
 	};
 
 	lcd {
diff --git a/arch/sandbox/dts/sandbox_pmic.dtsi b/arch/sandbox/dts/sandbox_pmic.dtsi
index 5ecafaa..565c382 100644
--- a/arch/sandbox/dts/sandbox_pmic.dtsi
+++ b/arch/sandbox/dts/sandbox_pmic.dtsi
@@ -11,40 +11,6 @@
 &sandbox_pmic {
 	compatible = "sandbox,pmic";
 
-	pmic_emul {
-		compatible = "sandbox,i2c-pmic";
-
-		/*
-		 * Default PMICs register values are set by macro
-		 * VAL2REG(min, step, value) [uV/uA]
-		 * VAL2OMREG(mode id)
-		 * reg-defaults - byte array
-		 */
-		reg-defaults = /bits/ 8 <
-			/* BUCK1 */
-			VAL2REG(800000, 25000, 1000000)
-			VAL2REG(150000, 25000, 150000)
-			VAL2OMREG(BUCK_OM_OFF)
-			/* BUCK2 */
-			VAL2REG(750000, 50000, 3000000)
-			VAL2REG(150000, 25000, 150000)
-			VAL2OMREG(0)
-			/* LDO1 */
-			VAL2REG(800000, 25000, 1600000)
-			VAL2REG(100000, 50000, 150000)
-			VAL2OMREG(LDO_OM_OFF)
-			/* LDO2 */
-			VAL2REG(750000, 50000, 3000000)
-			VAL2REG(150000, 25000, 150000)
-			VAL2OMREG(0)
-			/* reg[12:15] - not used */
-			0x00
-			0x00
-			0x00
-			0x00
-		>;
-	};
-
 	buck1 {
 		regulator-name = "SUPPLY_1.2V";
 		regulator-min-microvolt = <1200000>;
@@ -84,10 +50,45 @@
 
 &mc34708 {
 	compatible = "fsl,mc34708";
+};
 
-	pmic_emul {
+&i2c_emul {
+	emul_pmic0: pmic-emul0 {
 		compatible = "sandbox,i2c-pmic";
 
+		/*
+		 * Default PMICs register values are set by macro
+		 * VAL2REG(min, step, value) [uV/uA]
+		 * VAL2OMREG(mode id)
+		 * reg-defaults - byte array
+		 */
+		reg-defaults = /bits/ 8 <
+			/* BUCK1 */
+			VAL2REG(800000, 25000, 1000000)
+			VAL2REG(150000, 25000, 150000)
+			VAL2OMREG(BUCK_OM_OFF)
+			/* BUCK2 */
+			VAL2REG(750000, 50000, 3000000)
+			VAL2REG(150000, 25000, 150000)
+			VAL2OMREG(0)
+			/* LDO1 */
+			VAL2REG(800000, 25000, 1600000)
+			VAL2REG(100000, 50000, 150000)
+			VAL2OMREG(LDO_OM_OFF)
+			/* LDO2 */
+			VAL2REG(750000, 50000, 3000000)
+			VAL2REG(150000, 25000, 150000)
+			VAL2OMREG(0)
+			/* reg[12:15] - not used */
+			0x00
+			0x00
+			0x00
+			0x00
+		>;
+	};
+
+	emul_pmic1: pmic-emul1 {
+		compatible = "sandbox,i2c-pmic";
 		reg-defaults = /bits/ 8 <
 			0x00 0x80 0x08 0xff 0xff 0xff 0x2e 0x01 0x08
 			0x40 0x80 0x81 0x5f 0xff 0xfb 0x1e 0x80 0x18
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 2c6b422..252aa7b 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -266,35 +266,45 @@
 		eeprom@2c {
 			reg = <0x2c>;
 			compatible = "i2c-eeprom";
-			emul {
-				compatible = "sandbox,i2c-eeprom";
-				sandbox,filename = "i2c.bin";
-				sandbox,size = <256>;
-			};
+			sandbox,emul = <&emul_eeprom>;
 		};
 
 		rtc_0: rtc@43 {
 			reg = <0x43>;
 			compatible = "sandbox-rtc";
-			emul {
-				compatible = "sandbox,i2c-rtc";
-			};
+			sandbox,emul = <&emul0>;
 		};
 
 		rtc_1: rtc@61 {
 			reg = <0x61>;
 			compatible = "sandbox-rtc";
-			emul {
+			sandbox,emul = <&emul1>;
+		};
+
+		i2c_emul: emul {
+			reg = <0xff>;
+			compatible = "sandbox,i2c-emul-parent";
+			emul_eeprom: emul-eeprom {
+				compatible = "sandbox,i2c-eeprom";
+				sandbox,filename = "i2c.bin";
+				sandbox,size = <256>;
+			};
+			emul0: emul0 {
+				compatible = "sandbox,i2c-rtc";
+			};
+			emul1: emull {
 				compatible = "sandbox,i2c-rtc";
 			};
 		};
 
 		sandbox_pmic: sandbox_pmic {
 			reg = <0x40>;
+			sandbox,emul = <&emul_pmic0>;
 		};
 
 		mc34708: pmic@41 {
 			reg = <0x41>;
+			sandbox,emul = <&emul_pmic1>;
 		};
 	};
 
diff --git a/arch/sandbox/include/asm/handoff.h b/arch/sandbox/include/asm/handoff.h
new file mode 100644
index 0000000..be4e7b0
--- /dev/null
+++ b/arch/sandbox/include/asm/handoff.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Architecture-specific SPL handoff information for sandbox
+ *
+ * Copyright 2018 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#ifndef __handoff_h
+#define __handoff_h
+
+#define TEST_HANDOFF_MAGIC	0x14f93c7b
+
+struct arch_spl_handoff {
+	ulong	magic;		/* Used for testing */
+};
+
+#endif
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index dcb6d5f..8fabe70 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -89,6 +89,7 @@
 	bool skip_delays;		/* Ignore any time delays (for test) */
 	bool show_test_output;		/* Don't suppress stdout in tests */
 	int default_log_level;		/* Default log level for sandbox */
+	bool show_of_platdata;		/* Show of-platdata in SPL */
 
 	/* Pointer to information for each SPI bus/cs */
 	struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS]
@@ -242,6 +243,13 @@
 void state_reset_for_test(struct sandbox_state *state);
 
 /**
+ * state_show() - Show information about the sandbox state
+ *
+ * @param state		Sandbox state to show
+ */
+void state_show(struct sandbox_state *state);
+
+/**
  * Initialize the test system state
  */
 int state_init(void);
diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h
index 8e60f80..5e81839 100644
--- a/arch/sandbox/include/asm/test.h
+++ b/arch/sandbox/include/asm/test.h
@@ -113,4 +113,12 @@
 int sandbox_pwm_get_config(struct udevice *dev, uint channel, uint *period_nsp,
 			   uint *duty_nsp, bool *enablep, bool *polarityp);
 
+/**
+ * sandbox_sf_set_block_protect() - Set the BP bits of the status register
+ *
+ * @dev: Device to update
+ * @bp_mask: BP bits to set (bits 2:0, so a value of 0 to 7)
+ */
+void sandbox_sf_set_block_protect(struct udevice *dev, int bp_mask);
+
 #endif
diff --git a/arch/x86/config.mk b/arch/x86/config.mk
index 8151e47..b5e8f46 100644
--- a/arch/x86/config.mk
+++ b/arch/x86/config.mk
@@ -34,7 +34,7 @@
 
 # This is used in the top-level Makefile which does not include
 # PLATFORM_LDFLAGS
-LDFLAGS_EFI_PAYLOAD := -Bsymbolic -Bsymbolic-functions -shared --no-undefined
+LDFLAGS_EFI_PAYLOAD := -Bsymbolic -Bsymbolic-functions -shared --no-undefined -s
 
 OBJCOPYFLAGS_EFI := -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
 	-j .rel -j .rela -j .reloc
@@ -65,7 +65,7 @@
 ifeq ($(CONFIG_EFI_APP),y)
 
 PLATFORM_CPPFLAGS += $(CFLAGS_EFI)
-LDFLAGS_FINAL += -znocombreloc -shared
+LDFLAGS_FINAL += -znocombreloc -shared -s
 LDSCRIPT := $(LDSCRIPT_EFI)
 
 else
diff --git a/board/AndesTech/ax25-ae350/MAINTAINERS b/board/AndesTech/ax25-ae350/MAINTAINERS
index 508c6ac..d87446e 100644
--- a/board/AndesTech/ax25-ae350/MAINTAINERS
+++ b/board/AndesTech/ax25-ae350/MAINTAINERS
@@ -3,4 +3,6 @@
 S:	Maintained
 F:	board/AndesTech/ax25-ae350/
 F:	include/configs/ax25-ae350.h
+F:	configs/a25-ae350_32_defconfig
+F:	configs/ax25-ae350_64_defconfig
 F:	configs/ax25-ae350_defconfig
diff --git a/board/AndesTech/ax25-ae350/ax25-ae350.c b/board/AndesTech/ax25-ae350/ax25-ae350.c
index 5f4ca0f..d343453 100644
--- a/board/AndesTech/ax25-ae350/ax25-ae350.c
+++ b/board/AndesTech/ax25-ae350/ax25-ae350.c
@@ -14,6 +14,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+extern phys_addr_t prior_stage_fdt_address;
 /*
  * Miscellaneous platform dependent initializations
  */
@@ -66,7 +67,7 @@
 
 void *board_fdt_blob_setup(void)
 {
-	void **ptr = (void *)CONFIG_SYS_SDRAM_BASE;
+	void **ptr = (void *)&prior_stage_fdt_address;
 	if (fdt_magic(*ptr) == FDT_MAGIC)
 			return (void *)*ptr;
 
diff --git a/board/amlogic/khadas-vim/Kconfig b/board/amlogic/khadas-vim/Kconfig
deleted file mode 100644
index 0fa8db9..0000000
--- a/board/amlogic/khadas-vim/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-if TARGET_KHADAS_VIM
-
-config SYS_BOARD
-	default "khadas-vim"
-
-config SYS_VENDOR
-	default "amlogic"
-
-config SYS_CONFIG_NAME
-	default "khadas-vim"
-
-endif
diff --git a/board/amlogic/khadas-vim/MAINTAINERS b/board/amlogic/khadas-vim/MAINTAINERS
deleted file mode 100644
index 024220a..0000000
--- a/board/amlogic/khadas-vim/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-KHADAS-VIM
-M:	Neil Armstrong <narmstrong@baylibre.com>
-S:	Maintained
-F:	board/amlogic/khadas-vim/
-F:	include/configs/khadas-vim.h
-F:	configs/khadas-vim_defconfig
diff --git a/board/amlogic/khadas-vim/khadas-vim.c b/board/amlogic/khadas-vim/khadas-vim.c
deleted file mode 100644
index 692bf2a..0000000
--- a/board/amlogic/khadas-vim/khadas-vim.c
+++ /dev/null
@@ -1,57 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
-
-#include <common.h>
-#include <dm.h>
-#include <environment.h>
-#include <asm/io.h>
-#include <asm/arch/gx.h>
-#include <asm/arch/mem.h>
-#include <asm/arch/sm.h>
-#include <asm/arch/eth.h>
-
-#define EFUSE_SN_OFFSET		20
-#define EFUSE_SN_SIZE		16
-#define EFUSE_MAC_OFFSET	52
-#define EFUSE_MAC_SIZE		6
-
-int board_init(void)
-{
-	return 0;
-}
-
-int misc_init_r(void)
-{
-	u8 mac_addr[EFUSE_MAC_SIZE];
-	char serial[EFUSE_SN_SIZE];
-	ssize_t len;
-
-	meson_gx_eth_init(PHY_INTERFACE_MODE_RMII,
-			  MESON_GXL_USE_INTERNAL_RMII_PHY);
-
-	if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
-		len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
-					  mac_addr, EFUSE_MAC_SIZE);
-		if (len == EFUSE_MAC_SIZE && is_valid_ethaddr(mac_addr))
-			eth_env_set_enetaddr("ethaddr", mac_addr);
-	}
-
-	if (!env_get("serial#")) {
-		len = meson_sm_read_efuse(EFUSE_SN_OFFSET, serial,
-					  EFUSE_SN_SIZE);
-		if (len == EFUSE_SN_SIZE)
-			env_set("serial#", serial);
-	}
-
-	return 0;
-}
-
-int ft_board_setup(void *blob, bd_t *bd)
-{
-	meson_gx_init_reserved_memory(blob);
-
-	return 0;
-}
diff --git a/board/amlogic/khadas-vim2/Kconfig b/board/amlogic/khadas-vim2/Kconfig
deleted file mode 100644
index d0af362..0000000
--- a/board/amlogic/khadas-vim2/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-if TARGET_KHADAS_VIM2
-
-config SYS_BOARD
-	default "khadas-vim2"
-
-config SYS_VENDOR
-	default "amlogic"
-
-config SYS_CONFIG_NAME
-	default "khadas-vim2"
-
-endif
diff --git a/board/amlogic/khadas-vim2/MAINTAINERS b/board/amlogic/khadas-vim2/MAINTAINERS
deleted file mode 100644
index ca63e31..0000000
--- a/board/amlogic/khadas-vim2/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-KHADAS-VIM2
-M:	Neil Armstrong <narmstrong@baylibre.com>
-S:	Maintained
-F:	board/amlogic/khadas-vim2/
-F:	include/configs/khadas-vim2.h
-F:	configs/khadas-vim2_defconfig
diff --git a/board/amlogic/khadas-vim2/Makefile b/board/amlogic/khadas-vim2/Makefile
deleted file mode 100644
index 4e7c9a0..0000000
--- a/board/amlogic/khadas-vim2/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-#
-# (C) Copyright 2016 BayLibre, SAS
-# Author: Neil Armstrong <narmstrong@baylibre.com>
-
-obj-y	:= khadas-vim2.o
diff --git a/board/amlogic/libretech-cc/Kconfig b/board/amlogic/libretech-cc/Kconfig
deleted file mode 100644
index 7a6f916..0000000
--- a/board/amlogic/libretech-cc/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-if TARGET_LIBRETECH_CC
-
-config SYS_BOARD
-	default "libretech-cc"
-
-config SYS_VENDOR
-	default "amlogic"
-
-config SYS_CONFIG_NAME
-	default "libretech-cc"
-
-endif
diff --git a/board/amlogic/libretech-cc/MAINTAINERS b/board/amlogic/libretech-cc/MAINTAINERS
deleted file mode 100644
index 398ce57..0000000
--- a/board/amlogic/libretech-cc/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-LIBRETECH-CC
-M:	Neil Armstrong <narmstrong@baylibre.com>
-S:	Maintained
-F:	board/amlogic/libretech-cc/
-F:	include/configs/libretech-cc.h
-F:	configs/libretech-cc_defconfig
diff --git a/board/amlogic/libretech-cc/Makefile b/board/amlogic/libretech-cc/Makefile
deleted file mode 100644
index 3b0adf8..0000000
--- a/board/amlogic/libretech-cc/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-#
-# (C) Copyright 2016 BayLibre, SAS
-# Author: Neil Armstrong <narmstrong@baylibre.com>
-
-obj-y	:= libretech-cc.o
diff --git a/board/amlogic/libretech-cc/libretech-cc.c b/board/amlogic/libretech-cc/libretech-cc.c
deleted file mode 100644
index ccab127..0000000
--- a/board/amlogic/libretech-cc/libretech-cc.c
+++ /dev/null
@@ -1,57 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
-
-#include <common.h>
-#include <dm.h>
-#include <environment.h>
-#include <asm/io.h>
-#include <asm/arch/gx.h>
-#include <asm/arch/sm.h>
-#include <asm/arch/eth.h>
-#include <asm/arch/mem.h>
-
-#define EFUSE_SN_OFFSET		20
-#define EFUSE_SN_SIZE		16
-#define EFUSE_MAC_OFFSET	52
-#define EFUSE_MAC_SIZE		6
-
-int board_init(void)
-{
-	return 0;
-}
-
-int misc_init_r(void)
-{
-	u8 mac_addr[EFUSE_MAC_SIZE];
-	char serial[EFUSE_SN_SIZE];
-	ssize_t len;
-
-	meson_gx_eth_init(PHY_INTERFACE_MODE_RMII,
-			  MESON_GXL_USE_INTERNAL_RMII_PHY);
-
-	if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
-		len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
-					  mac_addr, EFUSE_MAC_SIZE);
-		if (len == EFUSE_MAC_SIZE && is_valid_ethaddr(mac_addr))
-			eth_env_set_enetaddr("ethaddr", mac_addr);
-	}
-
-	if (!env_get("serial#")) {
-		len = meson_sm_read_efuse(EFUSE_SN_OFFSET, serial,
-					  EFUSE_SN_SIZE);
-		if (len == EFUSE_SN_SIZE)
-			env_set("serial#", serial);
-	}
-
-	return 0;
-}
-
-int ft_board_setup(void *blob, bd_t *bd)
-{
-	meson_gx_init_reserved_memory(blob);
-
-	return 0;
-}
diff --git a/board/amlogic/nanopi-k2/Kconfig b/board/amlogic/nanopi-k2/Kconfig
deleted file mode 100644
index 374bda2..0000000
--- a/board/amlogic/nanopi-k2/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-if TARGET_NANOPI_K2
-
-config SYS_BOARD
-	default "nanopi-k2"
-
-config SYS_VENDOR
-	default "amlogic"
-
-config SYS_CONFIG_NAME
-	default "nanopi-k2"
-
-endif
diff --git a/board/amlogic/nanopi-k2/MAINTAINERS b/board/amlogic/nanopi-k2/MAINTAINERS
deleted file mode 100644
index 0452bd1..0000000
--- a/board/amlogic/nanopi-k2/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-NANOPI-K2
-M:	Neil Armstrong <narmstrong@baylibre.com>
-S:	Maintained
-F:	board/amlogic/nanopi-k2/
-F:	include/configs/nanopi-k2.h
-F:	configs/nanopi-k2_defconfig
diff --git a/board/amlogic/nanopi-k2/Makefile b/board/amlogic/nanopi-k2/Makefile
deleted file mode 100644
index 7d9b666..0000000
--- a/board/amlogic/nanopi-k2/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# (C) Copyright 2018 Thomas McKahan
-#
-# SPDX-License-Identifier:	GPL-2.0+
-#
-
-obj-y	:= nanopi-k2.o
diff --git a/board/amlogic/nanopi-k2/nanopi-k2.c b/board/amlogic/nanopi-k2/nanopi-k2.c
deleted file mode 100644
index ae29dd6..0000000
--- a/board/amlogic/nanopi-k2/nanopi-k2.c
+++ /dev/null
@@ -1,55 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2018 Thomas McKahan
- */
-
-#include <common.h>
-#include <dm.h>
-#include <environment.h>
-#include <asm/io.h>
-#include <asm/arch/gx.h>
-#include <asm/arch/sm.h>
-#include <asm/arch/eth.h>
-#include <asm/arch/mem.h>
-
-#define EFUSE_SN_OFFSET		20
-#define EFUSE_SN_SIZE		16
-#define EFUSE_MAC_OFFSET	52
-#define EFUSE_MAC_SIZE		6
-
-int board_init(void)
-{
-	return 0;
-}
-
-int misc_init_r(void)
-{
-	u8 mac_addr[EFUSE_MAC_SIZE];
-	char serial[EFUSE_SN_SIZE];
-	ssize_t len;
-
-	meson_gx_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
-
-	if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
-		len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
-					  mac_addr, EFUSE_MAC_SIZE);
-		if (len == EFUSE_MAC_SIZE && is_valid_ethaddr(mac_addr))
-			eth_env_set_enetaddr("ethaddr", mac_addr);
-	}
-
-	if (!env_get("serial#")) {
-		len = meson_sm_read_efuse(EFUSE_SN_OFFSET, serial,
-			EFUSE_SN_SIZE);
-		if (len == EFUSE_SN_SIZE)
-			env_set("serial#", serial);
-	}
-
-	return 0;
-}
-
-int ft_board_setup(void *blob, bd_t *bd)
-{
-	meson_gx_init_reserved_memory(blob);
-
-	return 0;
-}
diff --git a/board/amlogic/odroid-c2/Kconfig b/board/amlogic/odroid-c2/Kconfig
deleted file mode 100644
index 2b16889..0000000
--- a/board/amlogic/odroid-c2/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-if TARGET_ODROID_C2
-
-config SYS_BOARD
-	default "odroid-c2"
-
-config SYS_VENDOR
-	default "amlogic"
-
-config SYS_CONFIG_NAME
-	default "odroid-c2"
-
-endif
diff --git a/board/amlogic/odroid-c2/MAINTAINERS b/board/amlogic/odroid-c2/MAINTAINERS
index 699850f..6a85306 100644
--- a/board/amlogic/odroid-c2/MAINTAINERS
+++ b/board/amlogic/odroid-c2/MAINTAINERS
@@ -1,6 +1,8 @@
 ODROID-C2
 M:	Beniamino Galvani <b.galvani@gmail.com>
+M:	Neil Armstrong <narmstrong@baylibre.com>
 S:	Maintained
 F:	board/amlogic/odroid-c2/
 F:	include/configs/odroid-c2.h
+F:	configs/nanopi-k2_defconfig
 F:	configs/odroid-c2_defconfig
diff --git a/board/amlogic/nanopi-k2/README b/board/amlogic/odroid-c2/README.nanopi-k2
similarity index 100%
rename from board/amlogic/nanopi-k2/README
rename to board/amlogic/odroid-c2/README.nanopi-k2
diff --git a/board/amlogic/odroid-c2/README b/board/amlogic/odroid-c2/README.odroid-c2
similarity index 100%
rename from board/amlogic/odroid-c2/README
rename to board/amlogic/odroid-c2/README.odroid-c2
diff --git a/board/amlogic/odroid-c2/odroid-c2.c b/board/amlogic/odroid-c2/odroid-c2.c
index 2a2755c..62f0f4c 100644
--- a/board/amlogic/odroid-c2/odroid-c2.c
+++ b/board/amlogic/odroid-c2/odroid-c2.c
@@ -17,18 +17,13 @@
 #define EFUSE_MAC_OFFSET	52
 #define EFUSE_MAC_SIZE		6
 
-int board_init(void)
-{
-	return 0;
-}
-
 int misc_init_r(void)
 {
 	u8 mac_addr[EFUSE_MAC_SIZE];
 	char serial[EFUSE_SN_SIZE];
 	ssize_t len;
 
-	meson_gx_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
+	meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
 
 	if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
 		len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
@@ -40,16 +35,9 @@
 	if (!env_get("serial#")) {
 		len = meson_sm_read_efuse(EFUSE_SN_OFFSET, serial,
 			EFUSE_SN_SIZE);
-		if (len == EFUSE_SN_SIZE) 
+		if (len == EFUSE_SN_SIZE)
 			env_set("serial#", serial);
 	}
 
 	return 0;
 }
-
-int ft_board_setup(void *blob, bd_t *bd)
-{
-	meson_gx_init_reserved_memory(blob);
-
-	return 0;
-}
diff --git a/board/amlogic/p212/Kconfig b/board/amlogic/p212/Kconfig
deleted file mode 100644
index 720c92b..0000000
--- a/board/amlogic/p212/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-if TARGET_P212
-
-config SYS_BOARD
-	default "p212"
-
-config SYS_VENDOR
-	default "amlogic"
-
-config SYS_CONFIG_NAME
-	default "p212"
-
-endif
diff --git a/board/amlogic/p212/MAINTAINERS b/board/amlogic/p212/MAINTAINERS
index 6575f17..07ca6f2 100644
--- a/board/amlogic/p212/MAINTAINERS
+++ b/board/amlogic/p212/MAINTAINERS
@@ -3,4 +3,6 @@
 S:	Maintained
 F:	board/amlogic/p212/
 F:	include/configs/p212.h
+F:	configs/khadas-vim_defconfig
+F:	configs/libretech-cc_defconfig
 F:	configs/p212_defconfig
diff --git a/board/amlogic/khadas-vim/README b/board/amlogic/p212/README.khadas-vim
similarity index 100%
rename from board/amlogic/khadas-vim/README
rename to board/amlogic/p212/README.khadas-vim
diff --git a/board/amlogic/libretech-cc/README b/board/amlogic/p212/README.libretech-cc
similarity index 100%
rename from board/amlogic/libretech-cc/README
rename to board/amlogic/p212/README.libretech-cc
diff --git a/board/amlogic/p212/README b/board/amlogic/p212/README.p212
similarity index 100%
rename from board/amlogic/p212/README
rename to board/amlogic/p212/README.p212
diff --git a/board/amlogic/p212/p212.c b/board/amlogic/p212/p212.c
index 00e07d7..546c4d9 100644
--- a/board/amlogic/p212/p212.c
+++ b/board/amlogic/p212/p212.c
@@ -18,19 +18,14 @@
 #define EFUSE_MAC_OFFSET	52
 #define EFUSE_MAC_SIZE		6
 
-int board_init(void)
-{
-	return 0;
-}
-
 int misc_init_r(void)
 {
 	u8 mac_addr[EFUSE_MAC_SIZE];
 	char serial[EFUSE_SN_SIZE];
 	ssize_t len;
 
-	meson_gx_eth_init(PHY_INTERFACE_MODE_RMII,
-			  MESON_GXL_USE_INTERNAL_RMII_PHY);
+	meson_eth_init(PHY_INTERFACE_MODE_RMII,
+		       MESON_USE_INTERNAL_RMII_PHY);
 
 	if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
 		len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
@@ -48,10 +43,3 @@
 
 	return 0;
 }
-
-int ft_board_setup(void *blob, bd_t *bd)
-{
-	meson_gx_init_reserved_memory(blob);
-
-	return 0;
-}
diff --git a/board/amlogic/q200/MAINTAINERS b/board/amlogic/q200/MAINTAINERS
new file mode 100644
index 0000000..be86386
--- /dev/null
+++ b/board/amlogic/q200/MAINTAINERS
@@ -0,0 +1,6 @@
+Q200
+M:	Neil Armstrong <narmstrong@baylibre.com>
+S:	Maintained
+F:	board/amlogic/q200/
+F:	include/configs/q200.h
+F:	configs/khadas-vim2_defconfig
diff --git a/board/amlogic/khadas-vim/Makefile b/board/amlogic/q200/Makefile
similarity index 84%
copy from board/amlogic/khadas-vim/Makefile
copy to board/amlogic/q200/Makefile
index 558c076..fd78fd0 100644
--- a/board/amlogic/khadas-vim/Makefile
+++ b/board/amlogic/q200/Makefile
@@ -3,4 +3,4 @@
 # (C) Copyright 2016 BayLibre, SAS
 # Author: Neil Armstrong <narmstrong@baylibre.com>
 
-obj-y	:= khadas-vim.o
+obj-y	:= q200.o
diff --git a/board/amlogic/khadas-vim2/README b/board/amlogic/q200/README.khadas-vim2
similarity index 100%
rename from board/amlogic/khadas-vim2/README
rename to board/amlogic/q200/README.khadas-vim2
diff --git a/board/amlogic/q200/README.q200 b/board/amlogic/q200/README.q200
new file mode 100644
index 0000000..55d730a
--- /dev/null
+++ b/board/amlogic/q200/README.q200
@@ -0,0 +1,102 @@
+U-Boot for Amlogic Q200
+=======================
+
+Q200 is a reference board manufactured by Amlogic with the following
+specifications:
+
+ - Amlogic S912 ARM Cortex-A53 octo-core SoC @ 1.5GHz
+ - ARM Mali T860 GPU
+ - 2/3GB DDR4 SDRAM
+ - 10/100/1000 Ethernet
+ - HDMI 2.0 4K/60Hz display
+ - 2 x USB 2.0 Host, 1 x USB 2.0 Device
+ - 16GB/32GB/64GB eMMC
+ - 2MB SPI Flash
+ - microSD
+ - SDIO Wifi Module, Bluetooth
+ - IR receiver
+
+Currently the u-boot port supports the following devices:
+ - serial
+ - eMMC, microSD
+ - Ethernet
+ - I2C
+ - Regulators
+ - Reset controller
+ - Clock controller
+ - USB Host
+ - ADC
+
+U-Boot compilation
+==================
+
+ > export ARCH=arm
+ > export CROSS_COMPILE=aarch64-none-elf-
+ > make khadas-vim2_defconfig
+ > make
+
+Image creation
+==============
+
+Amlogic doesn't provide sources for the firmware and for tools needed
+to create the bootloader image, so it is necessary to obtain them from
+the git tree published by the board vendor:
+
+ > wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ > wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+ > tar xvfJ gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ > tar xvfJ gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+ > export PATH=$PWD/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin:$PWD/gcc-linaro-arm-none-eabi-4.8-2013.11_linux/bin:$PATH
+ > git clone https://github.com/BayLibre/u-boot.git -b n-amlogic-openlinux-20170606 amlogic-u-boot
+ > cd amlogic-u-boot
+ > make gxm_q200_v1_defconfig
+ > make
+ > export FIPDIR=$PWD/fip
+
+Go back to mainline U-Boot source tree then :
+ > mkdir fip
+
+ > cp $FIPDIR/gxl/bl2.bin fip/
+ > cp $FIPDIR/gxl/acs.bin fip/
+ > cp $FIPDIR/gxl/bl21.bin fip/
+ > cp $FIPDIR/gxl/bl30.bin fip/
+ > cp $FIPDIR/gxl/bl301.bin fip/
+ > cp $FIPDIR/gxl/bl31.img fip/
+ > cp u-boot.bin fip/bl33.bin
+
+ > $FIPDIR/blx_fix.sh \
+	fip/bl30.bin \
+	fip/zero_tmp \
+	fip/bl30_zero.bin \
+	fip/bl301.bin \
+	fip/bl301_zero.bin \
+	fip/bl30_new.bin \
+	bl30
+
+ > python $FIPDIR/acs_tool.pyc fip/bl2.bin fip/bl2_acs.bin fip/acs.bin 0
+
+ > $FIPDIR/blx_fix.sh \
+	fip/bl2_acs.bin \
+	fip/zero_tmp \
+	fip/bl2_zero.bin \
+	fip/bl21.bin \
+	fip/bl21_zero.bin \
+	fip/bl2_new.bin \
+	bl2
+
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl30_new.bin
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl31.img
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl33.bin
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl2sig --input fip/bl2_new.bin --output fip/bl2.n.bin.sig
+ > $FIPDIR/gxl/aml_encrypt_gxl --bootmk \
+		--output fip/u-boot.bin \
+		--bl2 fip/bl2.n.bin.sig \
+		--bl30 fip/bl30_new.bin.enc \
+		--bl31 fip/bl31.img.enc \
+		--bl33 fip/bl33.bin.enc
+
+and then write the image to SD with:
+
+ > DEV=/dev/your_sd_device
+ > dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=512 skip=1 seek=1
+ > dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=1 count=444
diff --git a/board/amlogic/khadas-vim2/khadas-vim2.c b/board/amlogic/q200/q200.c
similarity index 85%
rename from board/amlogic/khadas-vim2/khadas-vim2.c
rename to board/amlogic/q200/q200.c
index ff56569..6db1b26 100644
--- a/board/amlogic/khadas-vim2/khadas-vim2.c
+++ b/board/amlogic/q200/q200.c
@@ -18,18 +18,13 @@
 #define EFUSE_MAC_OFFSET	52
 #define EFUSE_MAC_SIZE		6
 
-int board_init(void)
-{
-	return 0;
-}
-
 int misc_init_r(void)
 {
 	u8 mac_addr[EFUSE_MAC_SIZE];
 	char serial[EFUSE_SN_SIZE];
 	ssize_t len;
 
-	meson_gx_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
+	meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
 
 	/* Reset PHY on GPIOZ_14 */
 	clrbits_le32(GX_GPIO_EN(3), BIT(14));
@@ -53,10 +48,3 @@
 
 	return 0;
 }
-
-int ft_board_setup(void *blob, bd_t *bd)
-{
-	meson_gx_init_reserved_memory(blob);
-
-	return 0;
-}
diff --git a/board/amlogic/s400/MAINTAINERS b/board/amlogic/s400/MAINTAINERS
new file mode 100644
index 0000000..9ca9836
--- /dev/null
+++ b/board/amlogic/s400/MAINTAINERS
@@ -0,0 +1,6 @@
+S400
+M:	Neil Armstrong <narmstrong@baylibre.com>
+S:	Maintained
+F:	board/amlogic/s400/
+F:	include/configs/s400.h
+F:	configs/s400_defconfig
diff --git a/board/amlogic/khadas-vim/Makefile b/board/amlogic/s400/Makefile
similarity index 84%
rename from board/amlogic/khadas-vim/Makefile
rename to board/amlogic/s400/Makefile
index 558c076..bf03862 100644
--- a/board/amlogic/khadas-vim/Makefile
+++ b/board/amlogic/s400/Makefile
@@ -3,4 +3,4 @@
 # (C) Copyright 2016 BayLibre, SAS
 # Author: Neil Armstrong <narmstrong@baylibre.com>
 
-obj-y	:= khadas-vim.o
+obj-y	:= s400.o
diff --git a/board/amlogic/s400/README b/board/amlogic/s400/README
new file mode 100644
index 0000000..ab21998
--- /dev/null
+++ b/board/amlogic/s400/README
@@ -0,0 +1,110 @@
+U-Boot for Amlogic S400
+=======================
+
+S400 is a reference board manufactured by Amlogic with the following
+specifications:
+
+ - Amlogic A113DX ARM Cortex-A53 quad-core SoC @ 1.2GHz
+ - 1GB DDR4 SDRAM
+ - 10/100 Ethernet
+ - 2 x USB 2.0 Host
+ - eMMC
+ - Infrared receiver
+ - SDIO WiFi Module
+ - MIPI DSI Connector
+ - Audio HAT Connector
+ - PCI-E M.2 Connectors
+
+Schematics are available from Amlogic on demand.
+
+Currently the u-boot port supports the following devices:
+ - serial
+ - eMMC
+ - Ethernet
+ - I2C
+ - Regulators
+ - Reset controller
+ - Clock controller
+ - USB Host
+ - ADC
+
+u-boot compilation
+==================
+
+ > export ARCH=arm
+ > export CROSS_COMPILE=aarch64-none-elf-
+ > make s400_defconfig
+ > make
+
+Image creation
+==============
+
+Amlogic doesn't provide sources for the firmware and for tools needed
+to create the bootloader image, so it is necessary to obtain them from
+the git tree published by the board vendor:
+
+ > wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ > wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+ > tar xvfJ gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ > tar xvfJ gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+ > export PATH=$PWD/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin:$PWD/gcc-linaro-arm-none-eabi-4.8-2013.11_linux/bin:$PATH
+ > git clone https://github.com/BayLibre/u-boot.git -b n-amlogic-openlinux-20170606 amlogic-u-boot
+ > cd amlogic-u-boot
+ > make axg_s400_v1_defconfig
+ > make
+ > export FIPDIR=$PWD/fip
+
+Go back to mainline U-boot source tree then :
+ > mkdir fip
+
+ > cp $FIPDIR/axg/bl2.bin fip/
+ > cp $FIPDIR/axg/acs.bin fip/
+ > cp $FIPDIR/axg/bl21.bin fip/
+ > cp $FIPDIR/axg/bl30.bin fip/
+ > cp $FIPDIR/axg/bl301.bin fip/
+ > cp $FIPDIR/axg/bl31.img fip/
+ > cp u-boot.bin fip/bl33.bin
+
+ > $FIPDIR/blx_fix.sh \
+	fip/bl30.bin \
+	fip/zero_tmp \
+	fip/bl30_zero.bin \
+	fip/bl301.bin \
+	fip/bl301_zero.bin \
+	fip/bl30_new.bin \
+	bl30
+
+ > $FIPDIR/acs_tool.pyc fip/bl2.bin fip/bl2_acs.bin fip/acs.bin 0
+
+ > $FIPDIR/blx_fix.sh \
+	fip/bl2_acs.bin \
+	fip/zero_tmp \
+	fip/bl2_zero.bin \
+	fip/bl21.bin \
+	fip/bl21_zero.bin \
+	fip/bl2_new.bin \
+	bl2
+
+ > $FIPDIR/axg/aml_encrypt_axg --bl3sig --input fip/bl30_new.bin \
+					--output fip/bl30_new.bin.enc \
+					--level v3 --type bl30
+ > $FIPDIR/axg/aml_encrypt_axg --bl3sig --input fip/bl31.img \
+					--output fip/bl31.img.enc \
+					--level v3 --type bl31
+ > $FIPDIR/axg/aml_encrypt_axg --bl3sig --input fip/bl33.bin --compress lz4 \
+					--output fip/bl33.bin.enc \
+					--level v3 --type bl33
+ > $FIPDIR/axg/aml_encrypt_axg --bl2sig --input fip/bl2_new.bin \
+					--output fip/bl2.n.bin.sig
+ > $FIPDIR/axg/aml_encrypt_axg --bootmk \
+		--output fip/u-boot.bin \
+		--bl2 fip/bl2.n.bin.sig \
+		--bl30 fip/bl30_new.bin.enc \
+		--bl31 fip/bl31.img.enc \
+		--bl33 fip/bl33.bin.enc --level v3
+
+and then write the image to SD with:
+
+ > DEV=/dev/your_sd_device
+ > dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=512 skip=1 seek=1
+ > dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=1 count=444
diff --git a/board/amlogic/s400/s400.c b/board/amlogic/s400/s400.c
new file mode 100644
index 0000000..02a0e92
--- /dev/null
+++ b/board/amlogic/s400/s400.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <environment.h>
+#include <asm/io.h>
+#include <asm/arch/axg.h>
+#include <asm/arch/sm.h>
+#include <asm/arch/eth.h>
+#include <asm/arch/mem.h>
+
+int misc_init_r(void)
+{
+	meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
+
+	return 0;
+}
diff --git a/board/armltd/integrator/README b/board/armltd/integrator/README
index 5a0e934..af9dcc1 100644
--- a/board/armltd/integrator/README
+++ b/board/armltd/integrator/README
@@ -36,9 +36,7 @@
 Configuring U-Boot :
 ------------------
 	The makefile contains targets for Integrator platforms of both types
-fitted with all current variants of CM. If these targets are to be used with
-boot process c) above then CONFIG_INIT_CRITICAL may need to be defined to ensure
-that the CM is correctly configured.
+fitted with all current variants of CM.
 
 	There are also targets independent of CM. These may not be suitable for
 boot process c) above. They have been preserved for backward compatibility with
diff --git a/board/cssi/MCR3000/MCR3000.c b/board/cssi/MCR3000/MCR3000.c
index ffbeb14..d26ac35 100644
--- a/board/cssi/MCR3000/MCR3000.c
+++ b/board/cssi/MCR3000/MCR3000.c
@@ -12,6 +12,8 @@
 #include <mpc8xx.h>
 #include <fdt_support.h>
 #include <asm/io.h>
+#include <dm/uclass.h>
+#include <wdt.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -143,3 +145,17 @@
 
 	return 0;
 }
+
+int board_early_init_r(void)
+{
+	struct udevice *watchdog_dev = NULL;
+
+	if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
+		puts("Cannot find watchdog!\n");
+	} else {
+		puts("Enabling watchdog.\n");
+		wdt_start(watchdog_dev, 0xffff, 0);
+	}
+
+	return 0;
+}
diff --git a/board/cssi/MCR3000/u-boot.lds b/board/cssi/MCR3000/u-boot.lds
index a32c0e7..70aef32 100644
--- a/board/cssi/MCR3000/u-boot.lds
+++ b/board/cssi/MCR3000/u-boot.lds
@@ -19,7 +19,6 @@
 		arch/powerpc/cpu/mpc8xx/start.o	(.text)
 		arch/powerpc/cpu/mpc8xx/traps.o	(.text*)
 		arch/powerpc/lib/built-in.o		(.text*)
-		board/cssi/MCR3000/built-in.o	(.text*)
 		drivers/net/built-in.o		(.text*)
 
 		. = DEFINED(env_offset) ? env_offset : .;
@@ -69,6 +68,12 @@
 	__ex_table : { *(__ex_table) }
 	__stop___ex_table = .;
 
+	/*
+	 * _end - This is end of u-boot.bin image.
+	 * dtb will be appended here to make u-boot-dtb.bin
+	 */
+	_end = .;
+
 	. = ALIGN(4096);
 	__init_begin = .;
 	.text.init : { *(.text.init) }
diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig
index 37a80db..56bb533 100644
--- a/board/emulation/qemu-riscv/Kconfig
+++ b/board/emulation/qemu-riscv/Kconfig
@@ -13,7 +13,8 @@
 	default "qemu-riscv"
 
 config SYS_TEXT_BASE
-	default 0x80000000
+	default 0x80000000 if !RISCV_SMODE
+	default 0x80200000 if RISCV_SMODE
 
 config BOARD_SPECIFIC_OPTIONS # dummy
 	def_bool y
@@ -29,5 +30,7 @@
 	imply CMD_EXT2
 	imply CMD_EXT4
 	imply CMD_FAT
+	imply BOARD_LATE_INIT
+	imply OF_BOARD_SETUP
 
 endif
diff --git a/board/emulation/qemu-riscv/MAINTAINERS b/board/emulation/qemu-riscv/MAINTAINERS
index 3c6eb4f..c701c83 100644
--- a/board/emulation/qemu-riscv/MAINTAINERS
+++ b/board/emulation/qemu-riscv/MAINTAINERS
@@ -4,4 +4,6 @@
 F:	board/emulation/qemu-riscv/
 F:	include/configs/qemu-riscv.h
 F:	configs/qemu-riscv32_defconfig
+F:	configs/qemu-riscv32_smode_defconfig
 F:	configs/qemu-riscv64_defconfig
+F:	configs/qemu-riscv64_smode_defconfig
diff --git a/board/emulation/qemu-riscv/qemu-riscv.c b/board/emulation/qemu-riscv/qemu-riscv.c
index 2730a28..d6167aa 100644
--- a/board/emulation/qemu-riscv/qemu-riscv.c
+++ b/board/emulation/qemu-riscv/qemu-riscv.c
@@ -9,8 +9,6 @@
 #include <virtio_types.h>
 #include <virtio.h>
 
-#define MROM_FDT_ADDR	0x1020
-
 int board_init(void)
 {
 	/*
@@ -22,11 +20,70 @@
 	return 0;
 }
 
-void *board_fdt_blob_setup(void)
+int board_late_init(void)
 {
-	/*
-	 * QEMU loads a generated DTB for us immediately
-	 * after the reset vectors in the MROM
-	 */
-	return (void *)MROM_FDT_ADDR;
+	ulong kernel_start;
+	ofnode chosen_node;
+	int ret;
+
+	chosen_node = ofnode_path("/chosen");
+	if (!ofnode_valid(chosen_node)) {
+		debug("No chosen node found, can't get kernel start address\n");
+		return 0;
+	}
+
+#ifdef CONFIG_ARCH_RV64I
+	ret = ofnode_read_u64(chosen_node, "riscv,kernel-start",
+			      (u64 *)&kernel_start);
+#else
+	ret = ofnode_read_u32(chosen_node, "riscv,kernel-start",
+			      (u32 *)&kernel_start);
+#endif
+	if (ret) {
+		debug("Can't find kernel start address in device tree\n");
+		return 0;
+	}
+
+	env_set_hex("kernel_start", kernel_start);
+
+	return 0;
+}
+
+/*
+ * QEMU specifies the location of Linux (supplied with the -kernel argument)
+ * in the device tree using the riscv,kernel-start and riscv,kernel-end
+ * properties. We currently rely on the SBI implementation of BBL to run
+ * Linux and therefore embed Linux as payload in BBL. This causes an issue,
+ * because BBL detects the kernel properties in the device tree and ignores
+ * the Linux payload as a result. To work around this issue, we clear the
+ * kernel properties before booting Linux.
+ *
+ * This workaround can be removed, once we do not require BBL for its SBI
+ * implementation anymore.
+ */
+int ft_board_setup(void *blob, bd_t *bd)
+{
+	int chosen_offset, ret;
+
+	chosen_offset = fdt_path_offset(blob, "/chosen");
+	if (chosen_offset < 0)
+		return 0;
+
+#ifdef CONFIG_ARCH_RV64I
+	ret = fdt_setprop_u64(blob, chosen_offset, "riscv,kernel-start", 0);
+#else
+	ret = fdt_setprop_u32(blob, chosen_offset, "riscv,kernel-start", 0);
+#endif
+	if (ret)
+		return ret;
+
+#ifdef CONFIG_ARCH_RV64I
+	ret = fdt_setprop_u64(blob, chosen_offset, "riscv,kernel-end", 0);
+#else
+	ret = fdt_setprop_u32(blob, chosen_offset, "riscv,kernel-end", 0);
+#endif
+	if (ret)
+		return ret;
+
+	return 0;
 }
diff --git a/board/gardena/smart-gateway-mt7688/board.c b/board/gardena/smart-gateway-mt7688/board.c
index 3a1838e..6e11077 100644
--- a/board/gardena/smart-gateway-mt7688/board.c
+++ b/board/gardena/smart-gateway-mt7688/board.c
@@ -4,11 +4,44 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <led.h>
+#include <net.h>
+#include <spi.h>
+#include <spi_flash.h>
+#include <uuid.h>
+#include <linux/ctype.h>
 #include <linux/io.h>
 
 #define MT76XX_AGPIO_CFG	0x1000003c
 
+#define FACTORY_DATA_OFFS	0xc0000
+#define FACTORY_DATA_SECT_SIZE	0x10000
+#if ((CONFIG_ENV_OFFSET_REDUND + CONFIG_ENV_SIZE_REDUND) > FACTORY_DATA_OFFS)
+#error "U-Boot image with environment too big (overlapping with factory-data)!"
+#endif
+#define FACTORY_DATA_USER_OFFS	0x140
+#define FACTORY_DATA_SIZE	0x1f0
+#define FACTORY_DATA_CRC_LEN	(FACTORY_DATA_SIZE -			\
+				 FACTORY_DATA_USER_OFFS - sizeof(u32))
+
+#define FACTORY_DATA_MAGIC	0xCAFEBABE
+
+struct factory_data_values {
+	u8 pad_1[4];
+	u8 wifi_mac[6];		/* offs: 0x004: binary value */
+	u8 pad_2[30];
+	u8 eth_mac[6];		/* offs: 0x028: binary value */
+	u8 pad_3[FACTORY_DATA_USER_OFFS - 4 - 6 - 30 - 6];
+	/* User values start here at offset 0x140 */
+	u32 crc;
+	u32 magic;
+	u32 version;
+	char ipr_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
+	char hqv_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
+	char unielec_id[UUID_STR_LEN];	/* UUID as string w/o ending \0 */
+};
+
 int board_early_init_f(void)
 {
 	void __iomem *gpio_mode;
@@ -20,10 +53,246 @@
 	return 0;
 }
 
+static bool prepare_uuid_var(const char *fd_ptr, const char *env_var_name,
+			     char errorchar)
+{
+	char str[UUID_STR_LEN + 1] = { 0 };	/* Enough for UUID stuff */
+	bool env_updated = false;
+	char *env;
+	int i;
+
+	memcpy(str, fd_ptr, UUID_STR_LEN);
+
+	/* Convert non-ascii character to 'X' */
+	for (i = 0; i < UUID_STR_LEN; i++) {
+		if (!(isascii(str[i]) && isprint(str[i])))
+			str[i] = errorchar;
+	}
+
+	env = env_get(env_var_name);
+	if (strcmp(env, str)) {
+		env_set(env_var_name, str);
+		env_updated = true;
+	}
+
+	return env_updated;
+}
+
+static void factory_data_env_config(void)
+{
+	struct factory_data_values *fd;
+	struct spi_flash *sf;
+	int env_updated = 0;
+	char str[UUID_STR_LEN + 1];	/* Enough for UUID stuff */
+	char *env;
+	u8 *buf;
+	u32 crc;
+	int ret;
+	u8 *ptr;
+
+	buf = malloc(FACTORY_DATA_SIZE);
+	if (!buf) {
+		printf("F-Data:Unable to allocate buffer\n");
+		return;
+	}
+
+	/*
+	 * Get values from factory-data area in SPI NOR
+	 */
+	sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+			     CONFIG_SF_DEFAULT_CS,
+			     CONFIG_SF_DEFAULT_SPEED,
+			     CONFIG_SF_DEFAULT_MODE);
+	if (!sf) {
+		printf("F-Data:Unable to access SPI NOR flash\n");
+		goto err_free;
+	}
+
+	ret = spi_flash_read(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SIZE,
+			     (void *)buf);
+	if (ret) {
+		printf("F-Data:Unable to read factory-data from SPI NOR\n");
+		goto err_spi_flash;
+	}
+
+	fd = (struct factory_data_values *)buf;
+
+	if (fd->magic != FACTORY_DATA_MAGIC)
+		printf("F-Data:Magic value not correct\n");
+
+	crc = crc32(0, (u8 *)&fd->magic, FACTORY_DATA_CRC_LEN);
+	if (crc != fd->crc)
+		printf("F-Data:CRC not correct\n");
+	else
+		printf("F-Data:factory-data version %x detected\n",
+		       fd->version);
+
+	/* Handle wifi_mac env variable */
+	ptr = fd->wifi_mac;
+	sprintf(str, "%pM", ptr);
+	if (!is_valid_ethaddr(ptr))
+		printf("F-Data:Invalid MAC addr: wifi_mac %s\n", str);
+
+	env = env_get("wifiaddr");
+	if (strcmp(env, str)) {
+		env_set("wifiaddr", str);
+		env_updated = 1;
+	}
+
+	/* Handle eth_mac env variable */
+	ptr = fd->eth_mac;
+	sprintf(str, "%pM", ptr);
+	if (!is_valid_ethaddr(ptr))
+		printf("F-Data:Invalid MAC addr: eth_mac %s\n", str);
+
+	env = env_get("ethaddr");
+	if (strcmp(env, str)) {
+		env_set("ethaddr", str);
+		env_updated = 1;
+	}
+
+	/* Handle UUID env variables */
+	env_updated |= prepare_uuid_var(fd->ipr_id, "linuxmoduleid", 'X');
+	env_updated |= prepare_uuid_var(fd->hqv_id, "linuxmodulehqvid", '\0');
+	env_updated |= prepare_uuid_var(fd->unielec_id,
+					"linuxmoduleunielecid", '\0');
+
+	/* Check if the environment was updated and needs to get stored */
+	if (env_updated != 0) {
+		printf("F-Data:Values don't match env values -> saving\n");
+		env_save();
+	} else {
+		debug("F-Data:Values match current env values\n");
+	}
+
+err_spi_flash:
+	spi_flash_free(sf);
+
+err_free:
+	free(buf);
+}
+
 int board_late_init(void)
 {
 	if (IS_ENABLED(CONFIG_LED))
 		led_default_state();
 
+	factory_data_env_config();
+
 	return 0;
 }
+
+static void copy_or_generate_uuid(char *fd_ptr, const char *env_var_name)
+{
+	char str[UUID_STR_LEN + 1] = { 0 };	/* Enough for UUID stuff */
+	char *env;
+
+	/* Don't use the UUID dest place, as the \0 char won't fit */
+	env = env_get(env_var_name);
+	if (env)
+		strncpy(str, env, UUID_STR_LEN);
+	else
+		gen_rand_uuid_str(str, UUID_STR_FORMAT_STD);
+
+	memcpy(fd_ptr, str, UUID_STR_LEN);
+}
+
+/*
+ * Helper function to provide some sane factory-data values for testing
+ * purpose, when these values are not programmed correctly
+ */
+int do_fd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct factory_data_values *fd;
+	struct spi_flash *sf;
+	u8 *buf;
+	int ret = CMD_RET_FAILURE;
+
+	buf = malloc(FACTORY_DATA_SECT_SIZE);
+	if (!buf) {
+		printf("F-Data:Unable to allocate buffer\n");
+		return CMD_RET_FAILURE;
+	}
+
+	sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+			     CONFIG_SF_DEFAULT_CS,
+			     CONFIG_SF_DEFAULT_SPEED,
+			     CONFIG_SF_DEFAULT_MODE);
+	if (!sf) {
+		printf("F-Data:Unable to access SPI NOR flash\n");
+		goto err_free;
+	}
+
+	/* Generate the factory-data struct */
+
+	/* Fist read complete sector into buffer */
+	ret = spi_flash_read(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE,
+			     (void *)buf);
+	if (ret) {
+		printf("F-Data:spi_flash_read failed (%d)\n", ret);
+		goto err_spi_flash;
+	}
+
+	fd = (struct factory_data_values *)buf;
+	fd->magic = FACTORY_DATA_MAGIC;
+	fd->version = 0x1;
+
+	/* Use existing MAC and UUID values or generate some random ones */
+	if (!eth_env_get_enetaddr("wifiaddr", fd->wifi_mac)) {
+		net_random_ethaddr(fd->wifi_mac);
+		/* to get a different seed value for the MAC address */
+		mdelay(10);
+	}
+
+	if (!eth_env_get_enetaddr("ethaddr", fd->eth_mac))
+		net_random_ethaddr(fd->eth_mac);
+
+	copy_or_generate_uuid(fd->ipr_id, "linuxmoduleid");
+	copy_or_generate_uuid(fd->hqv_id, "linuxmodulehqvid");
+	copy_or_generate_uuid(fd->unielec_id, "linuxmoduleunielecid");
+
+	printf("New factory-data values:\n");
+	printf("wifiaddr=%pM\n", fd->wifi_mac);
+	printf("ethaddr=%pM\n", fd->eth_mac);
+
+	/*
+	 * We don't have the \0 char at the end, so we need to specify the
+	 * length in the printf format instead
+	 */
+	printf("linuxmoduleid=%." __stringify(UUID_STR_LEN) "s\n", fd->ipr_id);
+	printf("linuxmodulehqvid=%." __stringify(UUID_STR_LEN) "s\n",
+	       fd->hqv_id);
+	printf("linuxmoduleunielecid=%." __stringify(UUID_STR_LEN) "s\n",
+	       fd->unielec_id);
+
+	fd->crc = crc32(0, (u8 *)&fd->magic, FACTORY_DATA_CRC_LEN);
+
+	ret = spi_flash_erase(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE);
+	if (ret) {
+		printf("F-Data:spi_flash_erase failed (%d)\n", ret);
+		goto err_spi_flash;
+	}
+
+	ret = spi_flash_write(sf, FACTORY_DATA_OFFS, FACTORY_DATA_SECT_SIZE,
+			      buf);
+	if (ret) {
+		printf("F-Data:spi_flash_write failed (%d)\n", ret);
+		goto err_spi_flash;
+	}
+
+	printf("F-Data:factory-data values written to SPI NOR flash\n");
+
+err_spi_flash:
+	spi_flash_free(sf);
+
+err_free:
+	free(buf);
+
+	return ret;
+}
+
+U_BOOT_CMD(
+	fd_write,	1,	0,	do_fd_write,
+	"Write test factory-data values to SPI NOR",
+	"\n"
+);
diff --git a/board/gdsys/a38x/controlcenterdc.c b/board/gdsys/a38x/controlcenterdc.c
index 824a08f..dd4c083 100644
--- a/board/gdsys/a38x/controlcenterdc.c
+++ b/board/gdsys/a38x/controlcenterdc.c
@@ -34,6 +34,19 @@
 #define DB_GP_88F68XX_GPP_POL_LOW	0x0
 #define DB_GP_88F68XX_GPP_POL_MID	0x0
 
+static int get_tpm(struct udevice **devp)
+{
+	int rc;
+
+	rc = uclass_first_device_err(UCLASS_TPM, devp);
+	if (rc) {
+		printf("Could not find TPM (ret=%d)\n", rc);
+		return CMD_RET_FAILURE;
+	}
+
+	return 0;
+}
+
 /*
  * Define the DDR layout / topology here in the board file. This will
  * be used by the DDR3 init code in the SPL U-Boot version to configure
@@ -266,18 +279,22 @@
 
 int last_stage_init(void)
 {
+	struct udevice *tpm;
+	int ret;
+
 #ifndef CONFIG_SPL_BUILD
 	ccdc_eth_init();
 #endif
-	if (tpm_init() || tpm_startup(TPM_ST_CLEAR) ||
-	    tpm_continue_self_test()) {
+	ret = get_tpm(&tpm);
+	if (ret || tpm_init(tpm) || tpm_startup(tpm, TPM_ST_CLEAR) ||
+	    tpm_continue_self_test(tpm)) {
 		return 1;
 	}
 
 	mdelay(37);
 
-	flush_keys();
-	load_and_run_keyprog();
+	flush_keys(tpm);
+	load_and_run_keyprog(tpm);
 
 	return 0;
 }
diff --git a/board/gdsys/a38x/hre.c b/board/gdsys/a38x/hre.c
index 34c4df7..82b8428 100644
--- a/board/gdsys/a38x/hre.c
+++ b/board/gdsys/a38x/hre.c
@@ -93,19 +93,20 @@
 
 /**
  * @brief get the size of a given (TPM) NV area
+ * @param tpm		TPM device
  * @param index	NV index of the area to get size for
  * @param size	pointer to the size
  * @return 0 on success, != 0 on error
  */
-static int get_tpm_nv_size(uint32_t index, uint32_t *size)
+static int get_tpm_nv_size(struct udevice *tpm, uint32_t index, uint32_t *size)
 {
 	uint32_t err;
 	uint8_t info[72];
 	uint8_t *ptr;
 	uint16_t v16;
 
-	err = tpm_get_capability(TPM_CAP_NV_INDEX, index,
-		info, sizeof(info));
+	err = tpm_get_capability(tpm, TPM_CAP_NV_INDEX, index,
+				 info, sizeof(info));
 	if (err) {
 		printf("tpm_get_capability(CAP_NV_INDEX, %08x) failed: %u\n",
 		       index, err);
@@ -128,13 +129,14 @@
 
 /**
  * @brief search for a key by usage auth and pub key hash.
+ * @param tpm		TPM device
  * @param auth	usage auth of the key to search for
  * @param pubkey_digest	(SHA1) hash of the pub key structure of the key
  * @param[out] handle	the handle of the key iff found
  * @return 0 if key was found in TPM; != 0 if not.
  */
-static int find_key(const uint8_t auth[20], const uint8_t pubkey_digest[20],
-		uint32_t *handle)
+static int find_key(struct udevice *tpm, const uint8_t auth[20],
+		    const uint8_t pubkey_digest[20], uint32_t *handle)
 {
 	uint16_t key_count;
 	uint32_t key_handles[10];
@@ -146,7 +148,8 @@
 	unsigned int i;
 
 	/* fetch list of already loaded keys in the TPM */
-	err = tpm_get_capability(TPM_CAP_HANDLE, TPM_RT_KEY, buf, sizeof(buf));
+	err = tpm_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
+				 sizeof(buf));
 	if (err)
 		return -1;
 	key_count = get_unaligned_be16(buf);
@@ -157,7 +160,8 @@
 	/* now search a(/ the) key which we can access with the given auth */
 	for (i = 0; i < key_count; ++i) {
 		buf_len = sizeof(buf);
-		err = tpm_get_pub_key_oiap(key_handles[i], auth, buf, &buf_len);
+		err = tpm_get_pub_key_oiap(tpm, key_handles[i], auth, buf,
+					   &buf_len);
 		if (err && err != TPM_AUTHFAIL)
 			return -1;
 		if (err)
@@ -173,20 +177,21 @@
 
 /**
  * @brief read CCDM common data from TPM NV
+ * @param tpm		TPM device
  * @return 0 if CCDM common data was found and read, !=0 if something failed.
  */
-static int read_common_data(void)
+static int read_common_data(struct udevice *tpm)
 {
 	uint32_t size = 0;
 	uint32_t err;
 	uint8_t buf[256];
 	sha1_context ctx;
 
-	if (get_tpm_nv_size(NV_COMMON_DATA_INDEX, &size) ||
+	if (get_tpm_nv_size(tpm, NV_COMMON_DATA_INDEX, &size) ||
 	    size < NV_COMMON_DATA_MIN_SIZE)
 		return 1;
-	err = tpm_nv_read_value(NV_COMMON_DATA_INDEX,
-		buf, min(sizeof(buf), size));
+	err = tpm_nv_read_value(tpm, NV_COMMON_DATA_INDEX,
+				buf, min(sizeof(buf), size));
 	if (err) {
 		printf("tpm_nv_read_value() failed: %u\n", err);
 		return 1;
@@ -235,6 +240,7 @@
 
 /**
  * @brief get pointer of a hash register by specification and usage.
+ * @param tpm		TPM device
  * @param spec	specification of a hash register
  * @param mode	access mode (read or write or read/write)
  * @return pointer to hash register if found and valid; NULL else.
@@ -244,7 +250,8 @@
  * The value of automatic registers (PCR register and fixed registers) is
  * loaded or computed on read access.
  */
-static struct h_reg *access_hreg(uint8_t spec, enum access_mode mode)
+static struct h_reg *access_hreg(struct udevice *tpm, uint8_t spec,
+				 enum access_mode mode)
 {
 	struct h_reg *result;
 
@@ -261,13 +268,13 @@
 	if (mode & HREG_RD) {
 		if (!result->valid) {
 			if (IS_PCR_HREG(spec)) {
-				hre_tpm_err = tpm_pcr_read(HREG_IDX(spec),
+				hre_tpm_err = tpm_pcr_read(tpm, HREG_IDX(spec),
 					result->digest, 20);
 				result->valid = (hre_tpm_err == TPM_SUCCESS);
 			} else if (IS_FIX_HREG(spec)) {
 				switch (HREG_IDX(spec)) {
 				case FIX_HREG_DEVICE_ID_HASH:
-					read_common_data();
+					read_common_data(tpm);
 					break;
 				case FIX_HREG_VENDOR:
 					memcpy(result->digest, vendor, 20);
@@ -337,18 +344,19 @@
 	return _dst;
 }
 
-static int hre_op_loadkey(struct h_reg *src_reg, struct h_reg *dst_reg,
-		const void *key, size_t key_size)
+static int hre_op_loadkey(struct udevice *tpm, struct h_reg *src_reg,
+			  struct h_reg *dst_reg, const void *key,
+			  size_t key_size)
 {
 	uint32_t parent_handle;
 	uint32_t key_handle;
 
 	if (!src_reg || !dst_reg || !src_reg->valid || !dst_reg->valid)
 		return -1;
-	if (find_key(src_reg->digest, dst_reg->digest, &parent_handle))
+	if (find_key(tpm, src_reg->digest, dst_reg->digest, &parent_handle))
 		return -1;
-	hre_tpm_err = tpm_load_key2_oiap(parent_handle, key, key_size,
-		src_reg->digest, &key_handle);
+	hre_tpm_err = tpm_load_key2_oiap(tpm, parent_handle, key, key_size,
+					 src_reg->digest, &key_handle);
 	if (hre_tpm_err) {
 		hre_err = HRE_E_TPM_FAILURE;
 		return -1;
@@ -359,11 +367,13 @@
 
 /**
  * @brief executes the next opcode on the hash register engine.
+ * @param tpm		TPM device
  * @param[in,out] ip	pointer to the opcode (instruction pointer)
  * @param[in,out] code_size	(remaining) size of the code
  * @return new instruction pointer on success, NULL on error.
  */
-static const uint8_t *hre_execute_op(const uint8_t **ip, size_t *code_size)
+static const uint8_t *hre_execute_op(struct udevice *tpm, const uint8_t **ip,
+				     size_t *code_size)
 {
 	bool dst_modified = false;
 	uint32_t ins;
@@ -394,10 +404,11 @@
 	if ((opcode & 0x80) && (data_size + 4) > *code_size)
 		return NULL;
 
-	src_reg = access_hreg(src_spec, HREG_RD);
+	src_reg = access_hreg(tpm, src_spec, HREG_RD);
 	if (hre_err || hre_tpm_err)
 		return NULL;
-	dst_reg = access_hreg(dst_spec, (opcode & 0x40) ? HREG_RDWR : HREG_WR);
+	dst_reg = access_hreg(tpm, dst_spec,
+			      (opcode & 0x40) ? HREG_RDWR : HREG_WR);
 	if (hre_err || hre_tpm_err)
 		return NULL;
 
@@ -453,7 +464,7 @@
 		dst_modified = true;
 		break;
 	case HRE_LOADKEY:
-		if (hre_op_loadkey(src_reg, dst_reg, data, data_size))
+		if (hre_op_loadkey(tpm, src_reg, dst_reg, data, data_size))
 			return NULL;
 		break;
 	default:
@@ -461,8 +472,8 @@
 	}
 
 	if (dst_reg && dst_modified && IS_PCR_HREG(dst_spec)) {
-		hre_tpm_err = tpm_extend(HREG_IDX(dst_spec), dst_reg->digest,
-			dst_reg->digest);
+		hre_tpm_err = tpm_extend(tpm, HREG_IDX(dst_spec),
+					 dst_reg->digest, dst_reg->digest);
 		if (hre_tpm_err) {
 			hre_err = HRE_E_TPM_FAILURE;
 			return NULL;
@@ -481,11 +492,12 @@
 
 /**
  * @brief runs a program on the hash register engine.
+ * @param tpm		TPM device
  * @param code		pointer to the (HRE) code.
  * @param code_size	size of the code (in bytes).
  * @return 0 on success, != 0 on failure.
  */
-int hre_run_program(const uint8_t *code, size_t code_size)
+int hre_run_program(struct udevice *tpm, const uint8_t *code, size_t code_size)
 {
 	size_t code_left;
 	const uint8_t *ip = code;
@@ -494,7 +506,7 @@
 	hre_tpm_err = 0;
 	hre_err = HRE_E_OK;
 	while (code_left > 0)
-		if (!hre_execute_op(&ip, &code_left))
+		if (!hre_execute_op(tpm, &ip, &code_left))
 			return -1;
 
 	return hre_err;
diff --git a/board/gdsys/a38x/hre.h b/board/gdsys/a38x/hre.h
index b562928..da983aa 100644
--- a/board/gdsys/a38x/hre.h
+++ b/board/gdsys/a38x/hre.h
@@ -32,6 +32,6 @@
 };
 
 int hre_verify_program(struct key_program *prg);
-int hre_run_program(const uint8_t *code, size_t code_size);
+int hre_run_program(struct udevice *tpm, const uint8_t *code, size_t code_size);
 
 #endif /* __HRE_H */
diff --git a/board/gdsys/a38x/keyprogram.c b/board/gdsys/a38x/keyprogram.c
index 1fb5306..291edc3 100644
--- a/board/gdsys/a38x/keyprogram.c
+++ b/board/gdsys/a38x/keyprogram.c
@@ -12,7 +12,7 @@
 
 #include "hre.h"
 
-int flush_keys(void)
+int flush_keys(struct udevice *tpm)
 {
 	u16 key_count;
 	u8 buf[288];
@@ -21,13 +21,15 @@
 	uint i;
 
 	/* fetch list of already loaded keys in the TPM */
-	err = tpm_get_capability(TPM_CAP_HANDLE, TPM_RT_KEY, buf, sizeof(buf));
+	err = tpm_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
+				 sizeof(buf));
 	if (err)
 		return -1;
 	key_count = get_unaligned_be16(buf);
 	ptr = buf + 2;
 	for (i = 0; i < key_count; ++i, ptr += 4) {
-		err = tpm_flush_specific(get_unaligned_be32(ptr), TPM_RT_KEY);
+		err = tpm_flush_specific(tpm, get_unaligned_be32(ptr),
+					 TPM_RT_KEY);
 		if (err && err != TPM_KEY_OWNER_CONTROL)
 			return err;
 	}
@@ -121,7 +123,7 @@
 	return result;
 }
 
-int load_and_run_keyprog(void)
+int load_and_run_keyprog(struct udevice *tpm)
 {
 	char *cmd = NULL;
 	u8 *binprog = NULL;
@@ -144,7 +146,7 @@
 	if (!prog)
 		return 1;
 
-	if (hre_run_program(prog->code, prog->code_size)) {
+	if (hre_run_program(tpm, prog->code, prog->code_size)) {
 		free(prog);
 		return 1;
 	}
diff --git a/board/gdsys/a38x/keyprogram.h b/board/gdsys/a38x/keyprogram.h
index a4877c7..06889c6 100644
--- a/board/gdsys/a38x/keyprogram.h
+++ b/board/gdsys/a38x/keyprogram.h
@@ -7,7 +7,7 @@
 #ifndef __KEYPROGRAM_H
 #define __KEYPROGRAM_H
 
-int load_and_run_keyprog(void);
-int flush_keys(void);
+int load_and_run_keyprog(struct udevice *tpm);
+int flush_keys(struct udevice *tpm);
 
 #endif /* __KEYPROGRAM_H */
diff --git a/board/gdsys/p1022/controlcenterd-id.c b/board/gdsys/p1022/controlcenterd-id.c
index 7e082df..6ac956c 100644
--- a/board/gdsys/p1022/controlcenterd-id.c
+++ b/board/gdsys/p1022/controlcenterd-id.c
@@ -11,6 +11,7 @@
 #endif
 
 #include <common.h>
+#include <dm.h>
 #include <malloc.h>
 #include <fs.h>
 #include <i2c.h>
@@ -141,6 +142,19 @@
 #define IS_VAR_HREG(spec) (((spec) & 0x38) == 0x10)
 #define HREG_IDX(spec) ((spec) & (IS_PCR_HREG(spec) ? 0x1f : 0x7))
 
+static int get_tpm(struct udevice **devp)
+{
+	int rc;
+
+	rc = uclass_first_device_err(UCLASS_TPM, devp);
+	if (rc) {
+		printf("Could not find TPM (ret=%d)\n", rc);
+		return CMD_RET_FAILURE;
+	}
+
+	return 0;
+}
+
 static const uint8_t vendor[] = "Guntermann & Drunck";
 
 /**
@@ -245,15 +259,15 @@
  * @param size	pointer to the size
  * @return 0 on success, != 0 on error
  */
-static int get_tpm_nv_size(uint32_t index, uint32_t *size)
+static int get_tpm_nv_size(struct udevice *tpm, uint32_t index, uint32_t *size)
 {
 	uint32_t err;
 	uint8_t info[72];
 	uint8_t *ptr;
 	uint16_t v16;
 
-	err = tpm_get_capability(TPM_CAP_NV_INDEX, index,
-		info, sizeof(info));
+	err = tpm_get_capability(tpm, TPM_CAP_NV_INDEX, index,
+				 info, sizeof(info));
 	if (err) {
 		printf("tpm_get_capability(CAP_NV_INDEX, %08x) failed: %u\n",
 		       index, err);
@@ -281,8 +295,8 @@
  * @param[out] handle	the handle of the key iff found
  * @return 0 if key was found in TPM; != 0 if not.
  */
-static int find_key(const uint8_t auth[20], const uint8_t pubkey_digest[20],
-		uint32_t *handle)
+static int find_key(struct udevice *tpm, const uint8_t auth[20],
+		    const uint8_t pubkey_digest[20], uint32_t *handle)
 {
 	uint16_t key_count;
 	uint32_t key_handles[10];
@@ -294,7 +308,8 @@
 	unsigned int i;
 
 	/* fetch list of already loaded keys in the TPM */
-	err = tpm_get_capability(TPM_CAP_HANDLE, TPM_RT_KEY, buf, sizeof(buf));
+	err = tpm_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
+				 sizeof(buf));
 	if (err)
 		return -1;
 	key_count = get_unaligned_be16(buf);
@@ -305,7 +320,8 @@
 	/* now search a(/ the) key which we can access with the given auth */
 	for (i = 0; i < key_count; ++i) {
 		buf_len = sizeof(buf);
-		err = tpm_get_pub_key_oiap(key_handles[i], auth, buf, &buf_len);
+		err = tpm_get_pub_key_oiap(tpm, key_handles[i], auth, buf,
+					   &buf_len);
 		if (err && err != TPM_AUTHFAIL)
 			return -1;
 		if (err)
@@ -323,18 +339,18 @@
  * @brief read CCDM common data from TPM NV
  * @return 0 if CCDM common data was found and read, !=0 if something failed.
  */
-static int read_common_data(void)
+static int read_common_data(struct udevice *tpm)
 {
 	uint32_t size;
 	uint32_t err;
 	uint8_t buf[256];
 	sha1_context ctx;
 
-	if (get_tpm_nv_size(NV_COMMON_DATA_INDEX, &size) ||
+	if (get_tpm_nv_size(tpm, NV_COMMON_DATA_INDEX, &size) ||
 	    size < NV_COMMON_DATA_MIN_SIZE)
 		return 1;
-	err = tpm_nv_read_value(NV_COMMON_DATA_INDEX,
-		buf, min(sizeof(buf), size));
+	err = tpm_nv_read_value(tpm, NV_COMMON_DATA_INDEX,
+				buf, min(sizeof(buf), size));
 	if (err) {
 		printf("tpm_nv_read_value() failed: %u\n", err);
 		return 1;
@@ -467,7 +483,8 @@
  * The value of automatic registers (PCR register and fixed registers) is
  * loaded or computed on read access.
  */
-static struct h_reg *access_hreg(uint8_t spec, enum access_mode mode)
+static struct h_reg *access_hreg(struct udevice *tpm, uint8_t spec,
+				 enum access_mode mode)
 {
 	struct h_reg *result;
 
@@ -484,13 +501,13 @@
 	if (mode & HREG_RD) {
 		if (!result->valid) {
 			if (IS_PCR_HREG(spec)) {
-				hre_tpm_err = tpm_pcr_read(HREG_IDX(spec),
+				hre_tpm_err = tpm_pcr_read(tpm, HREG_IDX(spec),
 					result->digest, 20);
 				result->valid = (hre_tpm_err == TPM_SUCCESS);
 			} else if (IS_FIX_HREG(spec)) {
 				switch (HREG_IDX(spec)) {
 				case FIX_HREG_DEVICE_ID_HASH:
-					read_common_data();
+					read_common_data(tpm);
 					break;
 				case FIX_HREG_SELF_HASH:
 					ccdm_compute_self_hash();
@@ -566,18 +583,19 @@
 	return _dst;
 }
 
-static int hre_op_loadkey(struct h_reg *src_reg, struct h_reg *dst_reg,
-		const void *key, size_t key_size)
+static int hre_op_loadkey(struct udevice *tpm, struct h_reg *src_reg,
+			  struct h_reg *dst_reg, const void *key,
+			  size_t key_size)
 {
 	uint32_t parent_handle;
 	uint32_t key_handle;
 
 	if (!src_reg || !dst_reg || !src_reg->valid || !dst_reg->valid)
 		return -1;
-	if (find_key(src_reg->digest, dst_reg->digest, &parent_handle))
+	if (find_key(tpm, src_reg->digest, dst_reg->digest, &parent_handle))
 		return -1;
-	hre_tpm_err = tpm_load_key2_oiap(parent_handle, key, key_size,
-		src_reg->digest, &key_handle);
+	hre_tpm_err = tpm_load_key2_oiap(tpm, parent_handle, key, key_size,
+					 src_reg->digest, &key_handle);
 	if (hre_tpm_err) {
 		hre_err = HRE_E_TPM_FAILURE;
 		return -1;
@@ -593,7 +611,8 @@
  * @param[in,out] code_size	(remaining) size of the code
  * @return new instruction pointer on success, NULL on error.
  */
-static const uint8_t *hre_execute_op(const uint8_t **ip, size_t *code_size)
+static const uint8_t *hre_execute_op(struct udevice *tpm, const uint8_t **ip,
+				     size_t *code_size)
 {
 	bool dst_modified = false;
 	uint32_t ins;
@@ -624,10 +643,11 @@
 	if ((opcode & 0x80) && (data_size + 4) > *code_size)
 		return NULL;
 
-	src_reg = access_hreg(src_spec, HREG_RD);
+	src_reg = access_hreg(tpm, src_spec, HREG_RD);
 	if (hre_err || hre_tpm_err)
 		return NULL;
-	dst_reg = access_hreg(dst_spec, (opcode & 0x40) ? HREG_RDWR : HREG_WR);
+	dst_reg = access_hreg(tpm, dst_spec,
+			      (opcode & 0x40) ? HREG_RDWR : HREG_WR);
 	if (hre_err || hre_tpm_err)
 		return NULL;
 
@@ -683,7 +703,7 @@
 		dst_modified = true;
 		break;
 	case HRE_LOADKEY:
-		if (hre_op_loadkey(src_reg, dst_reg, data, data_size))
+		if (hre_op_loadkey(tpm, src_reg, dst_reg, data, data_size))
 			return NULL;
 		break;
 	default:
@@ -691,8 +711,8 @@
 	}
 
 	if (dst_reg && dst_modified && IS_PCR_HREG(dst_spec)) {
-		hre_tpm_err = tpm_extend(HREG_IDX(dst_spec), dst_reg->digest,
-			dst_reg->digest);
+		hre_tpm_err = tpm_extend(tpm, HREG_IDX(dst_spec),
+					 dst_reg->digest, dst_reg->digest);
 		if (hre_tpm_err) {
 			hre_err = HRE_E_TPM_FAILURE;
 			return NULL;
@@ -715,7 +735,8 @@
  * @param code_size	size of the code (in bytes).
  * @return 0 on success, != 0 on failure.
  */
-static int hre_run_program(const uint8_t *code, size_t code_size)
+static int hre_run_program(struct udevice *tpm, const uint8_t *code,
+			   size_t code_size)
 {
 	size_t code_left;
 	const uint8_t *ip = code;
@@ -724,7 +745,7 @@
 	hre_tpm_err = 0;
 	hre_err = HRE_E_OK;
 	while (code_left > 0)
-		if (!hre_execute_op(&ip, &code_left))
+		if (!hre_execute_op(tpm, &ip, &code_left))
 			return -1;
 
 	return hre_err;
@@ -929,26 +950,27 @@
 	0x81, 0x2e, 0x30, 0x00, /* opcode: LOAD PCR3, f3 */
 };
 
-static int first_stage_actions(void)
+static int first_stage_actions(struct udevice *tpm)
 {
 	int result = 0;
 	struct key_program *sd_prg = NULL;
 
 	puts("CCDM S1: start actions\n");
 #ifndef CCDM_SECOND_STAGE
-	if (tpm_continue_self_test())
+	if (tpm_continue_self_test(tpm))
 		goto failure;
 #else
-	tpm_continue_self_test();
+	tpm_continue_self_test(tpm);
 #endif
 	mdelay(37);
 
-	if (hre_run_program(prg_stage1_prepare, sizeof(prg_stage1_prepare)))
+	if (hre_run_program(tpm, prg_stage1_prepare,
+			    sizeof(prg_stage1_prepare)))
 		goto failure;
 
 	sd_prg = load_sd_key_program();
 	if (sd_prg) {
-		if (hre_run_program(sd_prg->code, sd_prg->code_size))
+		if (hre_run_program(tpm, sd_prg->code, sd_prg->code_size))
 			goto failure;
 		puts("SD code run successfully\n");
 	} else {
@@ -969,19 +991,22 @@
 #ifdef CCDM_FIRST_STAGE
 static int first_stage_init(void)
 {
-	int res = 0;
+	struct udevice *tpm;
+	int ret;
+
 	puts("CCDM S1\n");
-	if (tpm_init() || tpm_startup(TPM_ST_CLEAR))
+	ret = get_tpm(&tpm);
+	if (ret || tpm_init(tpm) || tpm_startup(tpm, TPM_ST_CLEAR))
 		return 1;
-	res = first_stage_actions();
+	ret = first_stage_actions(tpm);
 #ifndef CCDM_SECOND_STAGE
-	if (!res) {
+	if (!ret) {
 		if (bl2_entry)
 			(*bl2_entry)();
-		res = 1;
+		ret = 1;
 	}
 #endif
-	return res;
+	return ret;
 }
 #endif
 
@@ -1021,24 +1046,28 @@
 	char *mac_path = NULL;
 	ulong image_addr;
 	loff_t image_size;
+	struct udevice *tpm;
 	uint32_t err;
+	int ret;
 
 	printf("CCDM S2\n");
-	if (tpm_init())
+	ret = get_tpm(&tpm);
+	if (ret || tpm_init(tpm))
 		return 1;
-	err = tpm_startup(TPM_ST_CLEAR);
+	err = tpm_startup(tpm, TPM_ST_CLEAR);
 	if (err != TPM_INVALID_POSTINIT)
 		did_first_stage_run = false;
 
 #ifdef CCDM_AUTO_FIRST_STAGE
-	if (!did_first_stage_run && first_stage_actions())
+	if (!did_first_stage_run && first_stage_actions(tpm))
 		goto failure;
 #else
 	if (!did_first_stage_run)
 		goto failure;
 #endif
 
-	if (hre_run_program(prg_stage2_prepare, sizeof(prg_stage2_prepare)))
+	if (hre_run_program(tpm, prg_stage2_prepare,
+			    sizeof(prg_stage2_prepare)))
 		goto failure;
 
 	/* run "prepboot" from env to get "mmcdev" set */
@@ -1083,12 +1112,12 @@
 	}
 	puts("CCDM image OK\n");
 
-	hre_run_program(prg_stage2_success, sizeof(prg_stage2_success));
+	hre_run_program(tpm, prg_stage2_success, sizeof(prg_stage2_success));
 
 	goto end;
 failure:
 	result = 1;
-	hre_run_program(prg_stage_fail, sizeof(prg_stage_fail));
+	hre_run_program(tpm, prg_stage_fail, sizeof(prg_stage_fail));
 end:
 	if (hmac_blob)
 		free(hmac_blob);
diff --git a/board/grinn/chiliboard/board.c b/board/grinn/chiliboard/board.c
index 73a7d82..dc0de62 100644
--- a/board/grinn/chiliboard/board.c
+++ b/board/grinn/chiliboard/board.c
@@ -19,7 +19,6 @@
 #include <environment.h>
 #include <errno.h>
 #include <miiphy.h>
-#include <serial.h>
 #include <spl.h>
 #include <watchdog.h>
 
@@ -69,13 +68,6 @@
 }
 #endif /* CONFIG_SKIP_LOWLEVEL_INIT */
 
-#ifndef CONFIG_DM_SERIAL
-struct serial_device *default_serial_console(void)
-{
-	return &eserial1_device;
-}
-#endif
-
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
 void set_uart_mux_conf(void)
 {
@@ -150,56 +142,3 @@
 	return 0;
 }
 #endif
-
-#if !defined(CONFIG_DM_ETH) && defined(CONFIG_DRIVER_TI_CPSW) && \
-	!defined(CONFIG_SPL_BUILD)
-static void cpsw_control(int enabled)
-{
-	/* VTP can be added here */
-
-	return;
-}
-
-static struct cpsw_slave_data cpsw_slaves[] = {
-	{
-		.slave_reg_ofs	= 0x208,
-		.sliver_reg_ofs	= 0xd80,
-		.phy_addr	= 0,
-	}
-};
-
-static struct cpsw_platform_data cpsw_data = {
-	.mdio_base		= CPSW_MDIO_BASE,
-	.cpsw_base		= CPSW_BASE,
-	.mdio_div		= 0xff,
-	.channels		= 8,
-	.cpdma_reg_ofs		= 0x800,
-	.slaves			= 1,
-	.slave_data		= cpsw_slaves,
-	.ale_reg_ofs		= 0xd00,
-	.ale_entries		= 1024,
-	.host_port_reg_ofs	= 0x108,
-	.hw_stats_reg_ofs	= 0x900,
-	.bd_ram_ofs		= 0x2000,
-	.mac_control		= (1 << 5),
-	.control		= cpsw_control,
-	.host_port_num		= 0,
-	.version		= CPSW_CTRL_VERSION_2,
-};
-
-int board_eth_init(bd_t *bis)
-{
-	int rv, n = 0;
-
-	writel(RMII_MODE_ENABLE | RMII_CHIPCKL_ENABLE, &cdev->miisel);
-	cpsw_slaves[0].phy_if = PHY_INTERFACE_MODE_RMII;
-
-	rv = cpsw_register(&cpsw_data);
-	if (rv < 0)
-		printf("Error %d registering CPSW switch\n", rv);
-	else
-		n += rv;
-
-	return n;
-}
-#endif
diff --git a/board/mediatek/mt7623/Kconfig b/board/mediatek/mt7623/Kconfig
new file mode 100644
index 0000000..a8c670e
--- /dev/null
+++ b/board/mediatek/mt7623/Kconfig
@@ -0,0 +1,13 @@
+if TARGET_MT7623
+
+config SYS_BOARD
+	default "mt7623"
+
+config SYS_CONFIG_NAME
+	default "mt7623"
+
+config MTK_BROM_HEADER_INFO
+	string
+	default "lk=1"
+
+endif
diff --git a/board/mediatek/mt7623/MAINTAINERS b/board/mediatek/mt7623/MAINTAINERS
new file mode 100644
index 0000000..eeb0375
--- /dev/null
+++ b/board/mediatek/mt7623/MAINTAINERS
@@ -0,0 +1,7 @@
+MT7623
+M:	Ryder Lee <ryder.lee@mediatek.com>
+M:	Weijie Gao <weijie.gao@mediatek.com>
+S:	Maintained
+F:	board/mediatek/mt7623
+F:	include/configs/mt7623.h
+F:	configs/mt7623n_bpir2_defconfig
diff --git a/board/mediatek/mt7623/Makefile b/board/mediatek/mt7623/Makefile
new file mode 100644
index 0000000..2b42071
--- /dev/null
+++ b/board/mediatek/mt7623/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier:	GPL-2.0
+
+obj-y += mt7623_rfb.o
diff --git a/board/mediatek/mt7623/mt7623_rfb.c b/board/mediatek/mt7623/mt7623_rfb.c
new file mode 100644
index 0000000..08468b5
--- /dev/null
+++ b/board/mediatek/mt7623/mt7623_rfb.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#include <common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+	/* address of boot parameters */
+	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+
+	return 0;
+}
diff --git a/board/mediatek/mt7629/Kconfig b/board/mediatek/mt7629/Kconfig
new file mode 100644
index 0000000..6055164
--- /dev/null
+++ b/board/mediatek/mt7629/Kconfig
@@ -0,0 +1,17 @@
+if TARGET_MT7629
+
+config SYS_BOARD
+	default "mt7629"
+
+config SYS_CONFIG_NAME
+	default "mt7629"
+
+config MTK_SPL_PAD_SIZE
+	hex
+	default 0x10000
+
+config MTK_BROM_HEADER_INFO
+	string
+	default "media=nor"
+
+endif
diff --git a/board/mediatek/mt7629/MAINTAINERS b/board/mediatek/mt7629/MAINTAINERS
new file mode 100644
index 0000000..424f115
--- /dev/null
+++ b/board/mediatek/mt7629/MAINTAINERS
@@ -0,0 +1,7 @@
+MT7629
+M:	Ryder Lee <ryder.lee@mediatek.com>
+M:	Weijie Gao <weijie.gao@mediatek.com>
+S:	Maintained
+F:	board/mediatek/mt7629
+F:	include/configs/mt7629.h
+F:	configs/mt7629_rfb_defconfig
diff --git a/board/mediatek/mt7629/Makefile b/board/mediatek/mt7629/Makefile
new file mode 100644
index 0000000..83ccbba
--- /dev/null
+++ b/board/mediatek/mt7629/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier:	GPL-2.0
+
+obj-y += mt7629_rfb.o
diff --git a/board/mediatek/mt7629/mt7629_rfb.c b/board/mediatek/mt7629/mt7629_rfb.c
new file mode 100644
index 0000000..08468b5
--- /dev/null
+++ b/board/mediatek/mt7629/mt7629_rfb.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#include <common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+	/* address of boot parameters */
+	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+
+	return 0;
+}
diff --git a/board/qualcomm/dragonboard820c/MAINTAINERS b/board/qualcomm/dragonboard820c/MAINTAINERS
index 56c997e..a157033 100644
--- a/board/qualcomm/dragonboard820c/MAINTAINERS
+++ b/board/qualcomm/dragonboard820c/MAINTAINERS
@@ -1,5 +1,5 @@
 DRAGONBOARD820C BOARD
-M:	Jorge Ramirez-Ortiz <jramirez@baylibre.com>
+M:	Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
 S:	Maintained
 F:	board/qualcomm/dragonboard820c/
 F:	include/configs/dragonboard820c.h
diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index 649127c..153a1fd 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -68,14 +68,7 @@
 #endif
 
 /*
- * http://raspberryalphaomega.org.uk/2013/02/06/automatic-raspberry-pi-board-revision-detection-model-a-b1-and-b2/
- * http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=32733
- * http://git.drogon.net/?p=wiringPi;a=blob;f=wiringPi/wiringPi.c;h=503151f61014418b9c42f4476a6086f75cd4e64b;hb=refs/heads/master#l922
- *
- * In http://lists.denx.de/pipermail/u-boot/2016-January/243752.html
- * ("[U-Boot] [PATCH] rpi: fix up Model B entries") Dom Cobley at the RPi
- * Foundation stated that the following source was accurate:
- * https://github.com/AndrewFromMelbourne/raspberry_pi_revision
+ * https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
  */
 struct rpi_model {
 	const char *name;
@@ -145,6 +138,11 @@
 		DTB_DIR "bcm2837-rpi-3-b-plus.dtb",
 		true,
 	},
+	[0xE] = {
+		"3 Model A+",
+		DTB_DIR "bcm2837-rpi-3-a-plus.dtb",
+		false,
+	},
 };
 
 static const struct rpi_model rpi_models_old_scheme[] = {
diff --git a/board/renesas/salvator-x/salvator-x.c b/board/renesas/salvator-x/salvator-x.c
index 8b15267..8f0247e 100644
--- a/board/renesas/salvator-x/salvator-x.c
+++ b/board/renesas/salvator-x/salvator-x.c
@@ -31,7 +31,6 @@
 {
 }
 
-#define SCIF2_MSTP310		BIT(10)	/* SCIF2 */
 #define DVFS_MSTP926		BIT(26)
 #define HSUSB_MSTP704		BIT(4)	/* HSUSB */
 
@@ -100,3 +99,25 @@
 	writel(RST_CODE, RST_CA57RESCNT);
 #endif
 }
+
+#ifdef CONFIG_MULTI_DTB_FIT
+int board_fit_config_name_match(const char *name)
+{
+	/* PRR driver is not available yet */
+	u32 cpu_type = rmobile_get_cpu_type();
+
+	if ((cpu_type == RMOBILE_CPU_TYPE_R8A7795) &&
+	    !strcmp(name, "r8a7795-salvator-x-u-boot"))
+		return 0;
+
+	if ((cpu_type == RMOBILE_CPU_TYPE_R8A7796) &&
+	    !strcmp(name, "r8a7796-salvator-x-u-boot"))
+		return 0;
+
+	if ((cpu_type == RMOBILE_CPU_TYPE_R8A77965) &&
+	    !strcmp(name, "r8a77965-salvator-x-u-boot"))
+		return 0;
+
+	return -1;
+}
+#endif
diff --git a/board/renesas/ulcb/ulcb.c b/board/renesas/ulcb/ulcb.c
index 63550af..81d6f8f 100644
--- a/board/renesas/ulcb/ulcb.c
+++ b/board/renesas/ulcb/ulcb.c
@@ -30,8 +30,6 @@
 {
 }
 
-#define GSX_MSTP112		BIT(12)	/* 3DG */
-#define SCIF2_MSTP310		BIT(10)	/* SCIF2 */
 #define DVFS_MSTP926		BIT(26)
 #define HSUSB_MSTP704		BIT(4)	/* HSUSB */
 
@@ -84,3 +82,21 @@
 
 	return 0;
 }
+
+#ifdef CONFIG_MULTI_DTB_FIT
+int board_fit_config_name_match(const char *name)
+{
+	/* PRR driver is not available yet */
+	u32 cpu_type = rmobile_get_cpu_type();
+
+	if ((cpu_type == RMOBILE_CPU_TYPE_R8A7795) &&
+	    !strcmp(name, "r8a7795-h3ulcb-u-boot"))
+		return 0;
+
+	if ((cpu_type == RMOBILE_CPU_TYPE_R8A7796) &&
+	    !strcmp(name, "r8a7796-m3ulcb-u-boot"))
+		return 0;
+
+	return -1;
+}
+#endif
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c
index c4b6bae..6fd26a3 100644
--- a/board/samsung/common/board.c
+++ b/board/samsung/common/board.c
@@ -306,14 +306,16 @@
 #ifdef CONFIG_BOARD_LATE_INIT
 int board_late_init(void)
 {
-	stdio_print_current_devices();
+	struct udevice *dev;
+	int ret;
 
-	if (cros_ec_get_error()) {
+	stdio_print_current_devices();
+	ret = uclass_first_device_err(UCLASS_CROS_EC, &dev);
+	if (ret && ret != -ENODEV) {
 		/* Force console on */
 		gd->flags &= ~GD_FLG_SILENT;
 
-		printf("cros-ec communications failure %d\n",
-		       cros_ec_get_error());
+		printf("cros-ec communications failure %d\n", ret);
 		puts("\nPlease reset with Power+Refresh\n\n");
 		panic("Cannot init cros-ec device");
 		return -1;
diff --git a/board/sandbox/README.sandbox b/board/sandbox/README.sandbox
index a28fc9f..9b09404 100644
--- a/board/sandbox/README.sandbox
+++ b/board/sandbox/README.sandbox
@@ -247,25 +247,28 @@
 DHCP
 ....
 
-set autoload no
-set ethact eth1
+setenv autoload no
+setenv ethrotate no
+setenv ethact eth1
 dhcp
 
 PING
 ....
 
-set autoload no
-set ethact eth1
+setenv autoload no
+setenv ethrotate no
+setenv ethact eth1
 dhcp
 ping $gatewayip
 
 TFTP
 ....
 
-set autoload no
-set ethact eth1
+setenv autoload no
+setenv ethrotate no
+setenv ethact eth1
 dhcp
-set serverip WWW.XXX.YYY.ZZZ
+setenv serverip WWW.XXX.YYY.ZZZ
 tftpboot u-boot.bin
 
 The bridge also supports (to a lesser extent) the localhost interface, 'lo'.
@@ -287,7 +290,8 @@
 TFTP
 ....
 
-set ethact eth5
+setenv ethrotate no
+setenv ethact eth5
 tftpboot u-boot.bin
 
 
@@ -418,7 +422,19 @@
 Note that many of these tests are implemented as commands which you can
 run natively on your board if desired (and enabled).
 
-It would be useful to have a central script to run all of these.
+To run all tests use "make check".
+
+
+Memory Map
+----------
+
+Sandbox has its own emulated memory starting at 0. Here are some of the things
+that are mapped into that memory:
+
+      0   CONFIG_SYS_FDT_LOAD_ADDR   Device tree
+   e000   CONFIG_BLOBLIST_ADDR       Blob list
+  10000   CONFIG_MALLOC_F_ADDR       Early memory allocation
+
 
 --
 Simon Glass <sjg@chromium.org>
diff --git a/board/sandbox/sandbox.c b/board/sandbox/sandbox.c
index 0e87674..397e756 100644
--- a/board/sandbox/sandbox.c
+++ b/board/sandbox/sandbox.c
@@ -59,12 +59,15 @@
 #ifdef CONFIG_BOARD_LATE_INIT
 int board_late_init(void)
 {
-	if (cros_ec_get_error()) {
+	struct udevice *dev;
+	int ret;
+
+	ret = uclass_first_device_err(UCLASS_CROS_EC, &dev);
+	if (ret && ret != -ENODEV) {
 		/* Force console on */
 		gd->flags &= ~GD_FLG_SILENT;
 
-		printf("cros-ec communications failure %d\n",
-		       cros_ec_get_error());
+		printf("cros-ec communications failure %d\n", ret);
 		puts("\nPlease reset with Power+Refresh\n\n");
 		panic("Cannot init cros-ec device");
 		return -1;
diff --git a/board/synopsys/axs10x/axs10x.c b/board/synopsys/axs10x/axs10x.c
index c95f7af..ffa7c15 100644
--- a/board/synopsys/axs10x/axs10x.c
+++ b/board/synopsys/axs10x/axs10x.c
@@ -109,3 +109,11 @@
 	writel(cmd, (void __iomem *)AXC003_CREG_CPU_START);
 }
 #endif
+
+int checkboard(void)
+{
+	printf("Board: ARC Software Development Platform AXS%s\n",
+	     is_isa_arcv2() ? "103" : "101");
+
+	return 0;
+};
diff --git a/board/synopsys/emsdp/emsdp.c b/board/synopsys/emsdp/emsdp.c
index b5ec7f1..c0770b5 100644
--- a/board/synopsys/emsdp/emsdp.c
+++ b/board/synopsys/emsdp/emsdp.c
@@ -7,10 +7,46 @@
 #include <dwmmc.h>
 #include <malloc.h>
 
+#include <asm/arcregs.h>
+
 DECLARE_GLOBAL_DATA_PTR;
 
+#define ARC_PERIPHERAL_BASE		0xF0000000
+
+#define CGU_ARC_FMEAS_ARC		(void *)(ARC_PERIPHERAL_BASE + 0x84)
+#define CGU_ARC_FMEAS_ARC_START		BIT(31)
+#define CGU_ARC_FMEAS_ARC_DONE		BIT(30)
+#define CGU_ARC_FMEAS_ARC_CNT_MASK	GENMASK(14, 0)
+#define CGU_ARC_FMEAS_ARC_RCNT_OFFSET	0
+#define CGU_ARC_FMEAS_ARC_FCNT_OFFSET	15
+
+#define SDIO_BASE			(void *)(ARC_PERIPHERAL_BASE + 0x10000)
+
+int mach_cpu_init(void)
+{
+	int rcnt, fcnt;
+	u32 data;
+
+	/* Start frequency measurement */
+	writel(CGU_ARC_FMEAS_ARC_START, CGU_ARC_FMEAS_ARC);
+
+	/* Poll DONE bit */
+	do {
+		data = readl(CGU_ARC_FMEAS_ARC);
+	} while (!(data & CGU_ARC_FMEAS_ARC_DONE));
+
+	/* Amount of reference 100 MHz clocks */
+	rcnt = ((data >> CGU_ARC_FMEAS_ARC_RCNT_OFFSET) &
+	       CGU_ARC_FMEAS_ARC_CNT_MASK);
+
-#define ARC_PERIPHERAL_BASE	0xF0000000
-#define SDIO_BASE		(ARC_PERIPHERAL_BASE + 0x10000)
+	/* Amount of CPU clocks */
+	fcnt = ((data >> CGU_ARC_FMEAS_ARC_FCNT_OFFSET) &
+	       CGU_ARC_FMEAS_ARC_CNT_MASK);
+
+	gd->cpu_clk = ((100 * fcnt) / rcnt) * 1000000;
+
+	return 0;
+}
 
 int board_mmc_init(bd_t *bis)
 {
@@ -24,7 +60,7 @@
 
 	memset(host, 0, sizeof(struct dwmci_host));
 	host->name = "Synopsys Mobile storage";
-	host->ioaddr = (void *)SDIO_BASE;
+	host->ioaddr = SDIO_BASE;
 	host->buswidth = 4;
 	host->dev_index = 0;
 	host->bus_hz = 50000000;
@@ -42,31 +78,32 @@
 }
 
 #define CREG_BASE		0xF0001000
-#define CREG_BOOT_OFFSET	0
-#define CREG_BOOT_WP_OFFSET	8
+#define CREG_BOOT		(void *)(CREG_BASE + 0x0FF0)
+#define CREG_IP_SW_RESET	(void *)(CREG_BASE + 0x0FF0)
+#define CREG_IP_VERSION		(void *)(CREG_BASE + 0x0FF8)
 
-#define CGU_BASE		0xF0000000
-#define CGU_IP_SW_RESET		0x0FF0
+/* Bits in CREG_BOOT register */
+#define CREG_BOOT_WP_BIT	BIT(8)
 
 void reset_cpu(ulong addr)
 {
-	writel(1, (u32 *)(CGU_BASE + CGU_IP_SW_RESET));
+	writel(1, CREG_IP_SW_RESET);
 	while (1)
 		; /* loop forever till reset */
 }
 
 static int do_emsdp_rom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
-	u32 creg_boot = readl((u32 *)(CREG_BASE + CREG_BOOT_OFFSET));
+	u32 creg_boot = readl(CREG_BOOT);
 
 	if (!strcmp(argv[1], "unlock"))
-		creg_boot &= ~BIT(CREG_BOOT_WP_OFFSET);
+		creg_boot &= ~CREG_BOOT_WP_BIT;
 	else if (!strcmp(argv[1], "lock"))
-		creg_boot |= BIT(CREG_BOOT_WP_OFFSET);
+		creg_boot |= CREG_BOOT_WP_BIT;
 	else
 		return CMD_RET_USAGE;
 
-	writel(creg_boot, (u32 *)(CREG_BASE + CREG_BOOT_OFFSET));
+	writel(creg_boot, CREG_BOOT);
 
 	return CMD_RET_SUCCESS;
 }
@@ -97,3 +134,12 @@
 	"rom unlock - Unlock non-volatile memory for writing\n"
 	"emsdp rom lock - Lock non-volatile memory to prevent writing\n"
 );
+
+int checkboard(void)
+{
+	int version = readl(CREG_IP_VERSION);
+
+	printf("Board: ARC EM Software Development Platform v%d.%d\n",
+	       (version >> 16) & 0xff, version & 0xff);
+	return 0;
+};
diff --git a/board/synopsys/hsdk/hsdk.c b/board/synopsys/hsdk/hsdk.c
index b6aefdb..8a2c201 100644
--- a/board/synopsys/hsdk/hsdk.c
+++ b/board/synopsys/hsdk/hsdk.c
@@ -1054,10 +1054,8 @@
 	return 0;
 }
 
-#ifdef CONFIG_DISPLAY_CPUINFO
-int print_cpuinfo(void)
+int checkboard(void)
 {
-	printf("CPU:   ARC HS38 v2.1c\n");
+	puts("Board: Synopsys ARC HS Development Kit\n");
 	return 0;
-}
-#endif /* CONFIG_DISPLAY_CPUINFO */
+};
diff --git a/board/synopsys/iot_devkit/iot_devkit.c b/board/synopsys/iot_devkit/iot_devkit.c
index f8838fb..8424e09 100644
--- a/board/synopsys/iot_devkit/iot_devkit.c
+++ b/board/synopsys/iot_devkit/iot_devkit.c
@@ -189,13 +189,3 @@
 	puts("Board: Synopsys IoT Development Kit\n");
 	return 0;
 };
-
-#ifdef CONFIG_DISPLAY_CPUINFO
-int print_cpuinfo(void)
-{
-	char mhz[8];
-
-	printf("CPU:   ARC EM9D at %s MHz\n", strmhz(mhz, gd->cpu_clk));
-	return 0;
-}
-#endif /* CONFIG_DISPLAY_CPUINFO */
diff --git a/board/vscom/baltos/board.c b/board/vscom/baltos/board.c
index df0a2d2..c5949ad 100644
--- a/board/vscom/baltos/board.c
+++ b/board/vscom/baltos/board.c
@@ -27,7 +27,6 @@
 #include <i2c.h>
 #include <miiphy.h>
 #include <cpsw.h>
-#include <power/tps65217.h>
 #include <power/tps65910.h>
 #include <environment.h>
 #include <watchdog.h>
@@ -35,8 +34,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* GPIO that controls power to DDR on EVM-SK */
-#define GPIO_DDR_VTT_EN		7
+/* GPIO that controls DIP switch and mPCIe slot */
 #define DIP_S1			44
 #define MPCIE_SW		100
 
@@ -248,9 +246,6 @@
 
 void sdram_init(void)
 {
-	gpio_request(GPIO_DDR_VTT_EN, "ddr_vtt_en");
-	gpio_direction_output(GPIO_DDR_VTT_EN, 1);
-
 	config_ddr(400, &ioregs_baltos,
 		   &ddr3_baltos_data,
 		   &ddr3_baltos_cmd_ctrl_data,
diff --git a/board/vscom/baltos/mux.c b/board/vscom/baltos/mux.c
index 94410ae..9c5542e 100644
--- a/board/vscom/baltos/mux.c
+++ b/board/vscom/baltos/mux.c
@@ -34,7 +34,6 @@
 	{OFFSET(mmc0_dat0), (MODE(0) | RXACTIVE | PULLUP_EN)},	/* MMC0_DAT0 */
 	{OFFSET(mmc0_clk), (MODE(0) | RXACTIVE | PULLUP_EN)},	/* MMC0_CLK */
 	{OFFSET(mmc0_cmd), (MODE(0) | RXACTIVE | PULLUP_EN)},	/* MMC0_CMD */
-	//{OFFSET(spi0_cs1), (MODE(5) | RXACTIVE | PULLUP_EN)},	/* MMC0_CD */
 	{-1},
 };
 
@@ -46,11 +45,6 @@
 	{-1},
 };
 
-static struct module_pin_mux gpio0_7_pin_mux[] = {
-	{OFFSET(ecap0_in_pwm0_out), (MODE(7) | PULLUDEN)},	/* GPIO0_7 */
-	{-1},
-};
-
 static struct module_pin_mux rmii1_pin_mux[] = {
 	{OFFSET(mii1_crs), MODE(1) | RXACTIVE},			/* RGMII1_TCTL */
 	{OFFSET(mii1_txen), MODE(1)},			/* RGMII1_TCTL */
@@ -114,7 +108,6 @@
 void enable_board_pin_mux()
 {
 	configure_module_pin_mux(i2c1_pin_mux);
-	configure_module_pin_mux(gpio0_7_pin_mux);
 	configure_module_pin_mux(rgmii2_pin_mux);
 	configure_module_pin_mux(rmii1_pin_mux);
 	configure_module_pin_mux(mmc0_pin_mux);
diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c
index 44fb48b..c946ec3 100644
--- a/board/xilinx/microblaze-generic/microblaze-generic.c
+++ b/board/xilinx/microblaze-generic/microblaze-generic.c
@@ -32,34 +32,13 @@
 
 int dram_init_banksize(void)
 {
-	gd->bd->bi_dram[0].start = ram_base;
-	gd->bd->bi_dram[0].size = get_effective_memsize();
-
-	return 0;
+	return fdtdec_setup_memory_banksize();
 }
 
 int dram_init(void)
 {
-	int node;
-	fdt_addr_t addr;
-	fdt_size_t size;
-	const void *blob = gd->fdt_blob;
-
-	node = fdt_node_offset_by_prop_value(blob, -1, "device_type",
-					     "memory", 7);
-	if (node == -FDT_ERR_NOTFOUND) {
-		debug("DRAM: Can't get memory node\n");
-		return 1;
-	}
-	addr = fdtdec_get_addr_size(blob, node, "reg", &size);
-	if (addr == FDT_ADDR_T_NONE || size == 0) {
-		debug("DRAM: Can't get base address or size\n");
-		return 1;
-	}
-	ram_base = addr;
-
-	gd->ram_top = addr; /* In setup_dest_addr() is done +ram_size */
-	gd->ram_size = size;
+	if (fdtdec_setup_mem_size_base() != 0)
+		return -EINVAL;
 
 	return 0;
 };
diff --git a/board/xilinx/zynq/cmds.c b/board/xilinx/zynq/cmds.c
index 0b2a817..8b48ea3 100644
--- a/board/xilinx/zynq/cmds.c
+++ b/board/xilinx/zynq/cmds.c
@@ -493,6 +493,7 @@
 	return cmd_process_error(zynq_cmd, ret);
 }
 
+#ifdef CONFIG_SYS_LONGHELP
 static char zynq_help_text[] =
 	""
 #ifdef CONFIG_CMD_ZYNQ_RSA
@@ -507,6 +508,7 @@
 	"                  destination address\n"
 #endif
 	;
+#endif
 
 U_BOOT_CMD(zynq,	6,	0,	do_zynq,
 	   "Zynq specific commands", zynq_help_text
diff --git a/board/xilinx/zynq/zynq-cse-nand b/board/xilinx/zynq/zynq-cse-nand
new file mode 120000
index 0000000..9d89a99
--- /dev/null
+++ b/board/xilinx/zynq/zynq-cse-nand
@@ -0,0 +1 @@
+zynq-zc770-xm011
\ No newline at end of file
diff --git a/board/xilinx/zynq/zynq-cse-nor b/board/xilinx/zynq/zynq-cse-nor
new file mode 120000
index 0000000..bb80693
--- /dev/null
+++ b/board/xilinx/zynq/zynq-cse-nor
@@ -0,0 +1 @@
+zynq-zc770-xm012
\ No newline at end of file
diff --git a/board/xilinx/zynqmp/zynqmp-mini b/board/xilinx/zynqmp/zynqmp-mini
new file mode 120000
index 0000000..5a70cd2
--- /dev/null
+++ b/board/xilinx/zynqmp/zynqmp-mini
@@ -0,0 +1 @@
+zynqmp-zcu102-rev1.0
\ No newline at end of file
diff --git a/board/xilinx/zynqmp/zynqmp-mini-emmc0 b/board/xilinx/zynqmp/zynqmp-mini-emmc0
new file mode 120000
index 0000000..f2beed3
--- /dev/null
+++ b/board/xilinx/zynqmp/zynqmp-mini-emmc0
@@ -0,0 +1 @@
+zynqmp-zcu100-revC
\ No newline at end of file
diff --git a/board/xilinx/zynqmp/zynqmp-mini-emmc1 b/board/xilinx/zynqmp/zynqmp-mini-emmc1
new file mode 120000
index 0000000..5a70cd2
--- /dev/null
+++ b/board/xilinx/zynqmp/zynqmp-mini-emmc1
@@ -0,0 +1 @@
+zynqmp-zcu102-rev1.0
\ No newline at end of file
diff --git a/board/xilinx/zynqmp/zynqmp-mini-qspi b/board/xilinx/zynqmp/zynqmp-mini-qspi
new file mode 120000
index 0000000..5a70cd2
--- /dev/null
+++ b/board/xilinx/zynqmp/zynqmp-mini-qspi
@@ -0,0 +1 @@
+zynqmp-zcu102-rev1.0
\ No newline at end of file
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index af91cde..13c404b 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -72,6 +72,7 @@
 		.id = 0x20,
 		.ver = 0x12c,
 		.name = "5cg",
+		.evexists = 1,
 	},
 	{
 		.id = 0x21,
@@ -88,6 +89,7 @@
 		.id = 0x21,
 		.ver = 0x12c,
 		.name = "4cg",
+		.evexists = 1,
 	},
 	{
 		.id = 0x30,
@@ -104,6 +106,7 @@
 		.id = 0x30,
 		.ver = 0x12c,
 		.name = "7cg",
+		.evexists = 1,
 	},
 	{
 		.id = 0x38,
@@ -234,14 +237,18 @@
 
 #define ZYNQMP_VERSION_SIZE		9
 #define ZYNQMP_PL_STATUS_BIT		9
+#define ZYNQMP_IPDIS_VCU_BIT		8
 #define ZYNQMP_PL_STATUS_MASK		BIT(ZYNQMP_PL_STATUS_BIT)
 #define ZYNQMP_CSU_VERSION_MASK		~(ZYNQMP_PL_STATUS_MASK)
+#define ZYNQMP_CSU_VCUDIS_VER_MASK	ZYNQMP_CSU_VERSION_MASK & \
+					~BIT(ZYNQMP_IPDIS_VCU_BIT)
+#define MAX_VARIANTS_EV			3
 
 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
 	!defined(CONFIG_SPL_BUILD)
 static char *zynqmp_get_silicon_idcode_name(void)
 {
-	u32 i, id, ver;
+	u32 i, id, ver, j;
 	char *buf;
 	static char name[ZYNQMP_VERSION_SIZE];
 
@@ -249,24 +256,43 @@
 	ver = chip_id(IDCODE2);
 
 	for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
-		if ((zynqmp_devices[i].id == id) &&
-		    (zynqmp_devices[i].ver == (ver &
-		    ZYNQMP_CSU_VERSION_MASK))) {
-			strncat(name, "zu", 2);
-			strncat(name, zynqmp_devices[i].name,
-				ZYNQMP_VERSION_SIZE - 3);
-			break;
+		if (zynqmp_devices[i].id == id) {
+			if (zynqmp_devices[i].evexists &&
+			    !(ver & ZYNQMP_PL_STATUS_MASK))
+				break;
+			if (zynqmp_devices[i].ver == (ver &
+			    ZYNQMP_CSU_VERSION_MASK))
+				break;
 		}
 	}
 
 	if (i >= ARRAY_SIZE(zynqmp_devices))
 		return "unknown";
 
-	if (!zynqmp_devices[i].evexists)
+	strncat(name, "zu", 2);
+	if (!zynqmp_devices[i].evexists ||
+	    (ver & ZYNQMP_PL_STATUS_MASK)) {
+		strncat(name, zynqmp_devices[i].name,
+			ZYNQMP_VERSION_SIZE - 3);
 		return name;
+	}
 
-	if (ver & ZYNQMP_PL_STATUS_MASK)
-		return name;
+	/*
+	 * Here we are means, PL not powered up and ev variant
+	 * exists. So, we need to ignore VCU disable bit(8) in
+	 * version and findout if its CG or EG/EV variant.
+	 */
+	for (j = 0; j < MAX_VARIANTS_EV; j++, i++) {
+		if ((zynqmp_devices[i].ver & ~BIT(ZYNQMP_IPDIS_VCU_BIT)) ==
+		    (ver & ZYNQMP_CSU_VCUDIS_VER_MASK)) {
+			strncat(name, zynqmp_devices[i].name,
+				ZYNQMP_VERSION_SIZE - 3);
+			break;
+		}
+	}
+
+	if (j >= MAX_VARIANTS_EV)
+		return "unknown";
 
 	if (strstr(name, "eg") || strstr(name, "ev")) {
 		buf = strstr(name, "e");
@@ -517,6 +543,10 @@
 	char *env_targets;
 	int ret;
 
+#if defined(CONFIG_USB_ETHER) && !defined(CONFIG_USB_GADGET_DOWNLOAD)
+	usb_ether_init();
+#endif
+
 	if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
 		debug("Saved variables - Skipping\n");
 		return 0;
diff --git a/cmd/Kconfig b/cmd/Kconfig
index e2973b3..b1cd1c9 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1380,6 +1380,14 @@
 	  Enable the 'conitrace' command which displays the codes received
 	  from the console input as hexadecimal numbers.
 
+config CMD_CLS
+	bool "Enable clear screen command 'cls'"
+	depends on CFB_CONSOLE || DM_VIDEO || LCD || VIDEO
+	default y if LCD
+	help
+	  Enable the 'cls' command which clears the screen contents
+	  on video frame buffer.
+
 config CMD_DISPLAY
 	bool "Enable the 'display' command, for character displays"
 	help
diff --git a/cmd/Makefile b/cmd/Makefile
index 0534ddc..4998643 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -32,6 +32,7 @@
 obj-$(CONFIG_CMD_CACHE) += cache.o
 obj-$(CONFIG_CMD_CBFS) += cbfs.o
 obj-$(CONFIG_CMD_CLK) += clk.o
+obj-$(CONFIG_CMD_CLS) += cls.o
 obj-$(CONFIG_CMD_CONFIG) += config.o
 obj-$(CONFIG_CMD_CONITRACE) += conitrace.o
 obj-$(CONFIG_CMD_CONSOLE) += console.o
@@ -115,6 +116,7 @@
 obj-$(CONFIG_SANDBOX) += host.o
 obj-$(CONFIG_CMD_SATA) += sata.o
 obj-$(CONFIG_CMD_NVME) += nvme.o
+obj-$(CONFIG_SANDBOX) += sb.o
 obj-$(CONFIG_CMD_SF) += sf.o
 obj-$(CONFIG_CMD_SCSI) += scsi.o disk.o
 obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o
diff --git a/cmd/bmp.c b/cmd/bmp.c
index 02bdf48..b8af784 100644
--- a/cmd/bmp.c
+++ b/cmd/bmp.c
@@ -124,8 +124,14 @@
 		break;
 	case 4:
 		addr = simple_strtoul(argv[1], NULL, 16);
-		x = simple_strtoul(argv[2], NULL, 10);
-		y = simple_strtoul(argv[3], NULL, 10);
+		if (!strcmp(argv[2], "m"))
+			x = BMP_ALIGN_CENTER;
+		else
+			x = simple_strtoul(argv[2], NULL, 10);
+		if (!strcmp(argv[3], "m"))
+			y = BMP_ALIGN_CENTER;
+		else
+			y = simple_strtoul(argv[3], NULL, 10);
 		break;
 	default:
 		return CMD_RET_USAGE;
@@ -249,9 +255,11 @@
 	if (!ret) {
 		bool align = false;
 
-# ifdef CONFIG_SPLASH_SCREEN_ALIGN
-		align = true;
-# endif /* CONFIG_SPLASH_SCREEN_ALIGN */
+		if (CONFIG_IS_ENABLED(SPLASH_SCREEN_ALIGN) ||
+		    x == BMP_ALIGN_CENTER ||
+		    y == BMP_ALIGN_CENTER)
+			align = true;
+
 		ret = video_bmp_display(dev, addr, x, y, align);
 	}
 #elif defined(CONFIG_LCD)
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 4d68d80..38679ff 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -148,16 +148,16 @@
 /**
  * copy_fdt() - Copy the device tree to a new location available to EFI
  *
- * The FDT is relocated into a suitable location within the EFI memory map.
- * An additional 12KB is added to the space in case the device tree needs to be
+ * The FDT is copied to a suitable location within the EFI memory map.
+ * Additional 12 KiB are added to the space in case the device tree needs to be
  * expanded later with fdt_open_into().
  *
- * @fdt_addr: On entry, address of start of FDT. On exit, address of relocated
- *	FDT start
- * @fdt_sizep: Returns new size of FDT, including
- * @return new relocated address of FDT
+ * @fdtp:	On entry a pointer to the flattened device tree.
+ *		On exit a pointer to the copy of the flattened device tree.
+ *		FDT start
+ * Return:	status code
  */
-static efi_status_t copy_fdt(ulong *fdt_addrp, ulong *fdt_sizep)
+static efi_status_t copy_fdt(void **fdtp)
 {
 	unsigned long fdt_ram_start = -1L, fdt_pages;
 	efi_status_t ret = 0;
@@ -178,17 +178,19 @@
 	}
 
 	/*
-	 * Give us at least 4KB of breathing room in case the device tree needs
-	 * to be expanded later. Round up to the nearest EFI page boundary.
+	 * Give us at least 12 KiB of breathing room in case the device tree
+	 * needs to be expanded later.
 	 */
-	fdt = map_sysmem(*fdt_addrp, 0);
-	fdt_size = fdt_totalsize(fdt);
-	fdt_size += 4096 * 3;
-	fdt_size = ALIGN(fdt_size + EFI_PAGE_SIZE - 1, EFI_PAGE_SIZE);
-	fdt_pages = fdt_size >> EFI_PAGE_SHIFT;
+	fdt = *fdtp;
+	fdt_pages = efi_size_in_pages(fdt_totalsize(fdt) + 0x3000);
+	fdt_size = fdt_pages << EFI_PAGE_SHIFT;
 
-	/* Safe fdt location is at 127MB */
-	new_fdt_addr = fdt_ram_start + (127 * 1024 * 1024) + fdt_size;
+	/*
+	 * Safe fdt location is at 127 MiB.
+	 * On the sandbox convert from the sandbox address space.
+	 */
+	new_fdt_addr = (uintptr_t)map_sysmem(fdt_ram_start + 0x7f00000 +
+					     fdt_size, 0);
 	ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
 				 EFI_RUNTIME_SERVICES_DATA, fdt_pages,
 				 &new_fdt_addr);
@@ -203,13 +205,11 @@
 			goto done;
 		}
 	}
-
-	new_fdt = map_sysmem(new_fdt_addr, fdt_size);
+	new_fdt = (void *)(uintptr_t)new_fdt_addr;
 	memcpy(new_fdt, fdt, fdt_totalsize(fdt));
 	fdt_set_totalsize(new_fdt, fdt_size);
 
-	*fdt_addrp = new_fdt_addr;
-	*fdt_sizep = fdt_size;
+	*fdtp = (void *)(uintptr_t)new_fdt_addr;
 done:
 	return ret;
 }
@@ -277,7 +277,11 @@
 		if (fdt_get_mem_rsv(fdt, i, &addr, &size) != 0)
 			continue;
 
-		pages = ALIGN(size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT;
+		/* Convert from sandbox address space. */
+		addr = (uintptr_t)map_sysmem(addr, 0);
+
+		pages = efi_size_in_pages(size + (addr & EFI_PAGE_MASK));
+		addr &= ~EFI_PAGE_MASK;
 		if (!efi_add_memory_map(addr, pages, EFI_RESERVED_MEMORY_TYPE,
 					false))
 			printf("FDT memrsv map %d: Failed to add to map\n", i);
@@ -287,7 +291,6 @@
 static efi_status_t efi_install_fdt(ulong fdt_addr)
 {
 	bootm_headers_t img = { 0 };
-	ulong fdt_pages, fdt_size, fdt_start;
 	efi_status_t ret;
 	void *fdt;
 
@@ -297,37 +300,61 @@
 		return EFI_INVALID_PARAMETER;
 	}
 
+	/* Create memory reservation as indicated by the device tree */
+	efi_carve_out_dt_rsv(fdt);
+
 	/* Prepare fdt for payload */
-	ret = copy_fdt(&fdt_addr, &fdt_size);
+	ret = copy_fdt(&fdt);
 	if (ret)
 		return ret;
 
-	unmap_sysmem(fdt);
-	fdt = map_sysmem(fdt_addr, 0);
-	fdt_size = fdt_totalsize(fdt);
 	if (image_setup_libfdt(&img, fdt, 0, NULL)) {
 		printf("ERROR: failed to process device tree\n");
 		return EFI_LOAD_ERROR;
 	}
 
-	efi_carve_out_dt_rsv(fdt);
-
 	/* Link to it in the efi tables */
 	ret = efi_install_configuration_table(&efi_guid_fdt, fdt);
 	if (ret != EFI_SUCCESS)
 		return EFI_OUT_OF_RESOURCES;
 
-	/* And reserve the space in the memory map */
-	fdt_start = fdt_addr;
-	fdt_pages = fdt_size >> EFI_PAGE_SHIFT;
+	return ret;
+}
 
-	ret = efi_add_memory_map(fdt_start, fdt_pages,
-				 EFI_BOOT_SERVICES_DATA, true);
+static efi_status_t bootefi_run_prepare(const char *load_options_path,
+		struct efi_device_path *device_path,
+		struct efi_device_path *image_path,
+		struct efi_loaded_image_obj **image_objp,
+		struct efi_loaded_image **loaded_image_infop)
+{
+	efi_status_t ret;
 
-	return ret;
+	ret = efi_setup_loaded_image(device_path, image_path, image_objp,
+				     loaded_image_infop);
+	if (ret != EFI_SUCCESS)
+		return ret;
+
+	/* Transfer environment variable as load options */
+	set_load_options(*loaded_image_infop, load_options_path);
+
+	return 0;
 }
 
 /**
+ * bootefi_run_finish() - finish up after running an EFI test
+ *
+ * @loaded_image_info: Pointer to a struct which holds the loaded image info
+ * @image_objj: Pointer to a struct which holds the loaded image object
+ */
+static void bootefi_run_finish(struct efi_loaded_image_obj *image_obj,
+			       struct efi_loaded_image *loaded_image_info)
+{
+	efi_restore_gd();
+	free(loaded_image_info->load_options);
+	efi_delete_handle(&image_obj->header);
+}
+
+/**
  * do_bootefi_exec() - execute EFI binary
  *
  * @efi:		address of the binary
@@ -345,7 +372,7 @@
 	efi_handle_t mem_handle = NULL;
 	struct efi_device_path *memdp = NULL;
 	efi_status_t ret;
-	struct efi_loaded_image_obj *image_handle = NULL;
+	struct efi_loaded_image_obj *image_obj = NULL;
 	struct efi_loaded_image *loaded_image_info = NULL;
 
 	EFIAPI efi_status_t (*entry)(efi_handle_t image_handle,
@@ -354,7 +381,7 @@
 	/*
 	 * Special case for efi payload not loaded from disk, such as
 	 * 'bootefi hello' or for example payload loaded directly into
-	 * memory via jtag, etc:
+	 * memory via JTAG, etc:
 	 */
 	if (!device_path && !image_path) {
 		printf("WARNING: using memory device/image path, this may confuse some payloads!\n");
@@ -367,27 +394,25 @@
 		 */
 		ret = efi_create_handle(&mem_handle);
 		if (ret != EFI_SUCCESS)
-			goto exit;
+			return ret; /* TODO: leaks device_path */
 		ret = efi_add_protocol(mem_handle, &efi_guid_device_path,
 				       device_path);
 		if (ret != EFI_SUCCESS)
-			goto exit;
+			goto err_add_protocol;
 	} else {
 		assert(device_path && image_path);
 	}
 
-	ret = efi_setup_loaded_image(device_path, image_path, &image_handle,
-				     &loaded_image_info);
-	if (ret != EFI_SUCCESS)
-		goto exit;
+	ret = bootefi_run_prepare("bootargs", device_path, image_path,
+				  &image_obj, &loaded_image_info);
+	if (ret)
+		goto err_prepare;
 
-	/* Transfer environment variable bootargs as load options */
-	set_load_options(loaded_image_info, "bootargs");
 	/* Load the EFI payload */
-	entry = efi_load_pe(image_handle, efi, loaded_image_info);
+	entry = efi_load_pe(image_obj, efi, loaded_image_info);
 	if (!entry) {
 		ret = EFI_LOAD_ERROR;
-		goto exit;
+		goto err_prepare;
 	}
 
 	if (memdp) {
@@ -405,9 +430,9 @@
 	/* Call our payload! */
 	debug("%s:%d Jumping to 0x%lx\n", __func__, __LINE__, (long)entry);
 
-	if (setjmp(&image_handle->exit_jmp)) {
-		ret = image_handle->exit_status;
-		goto exit;
+	if (setjmp(&image_obj->exit_jmp)) {
+		ret = image_obj->exit_status;
+		goto err_prepare;
 	}
 
 #ifdef CONFIG_ARM64
@@ -418,7 +443,7 @@
 
 		/* Move into EL2 and keep running there */
 		armv8_switch_to_el2((ulong)entry,
-				    (ulong)image_handle,
+				    (ulong)&image_obj->header,
 				    (ulong)&systab, 0, (ulong)efi_run_in_el2,
 				    ES_TO_AARCH64);
 
@@ -435,7 +460,7 @@
 		secure_ram_addr(_do_nonsec_entry)(
 					efi_run_in_hyp,
 					(uintptr_t)entry,
-					(uintptr_t)image_handle,
+					(uintptr_t)&image_obj->header,
 					(uintptr_t)&systab);
 
 		/* Should never reach here, efi exits with longjmp */
@@ -443,18 +468,59 @@
 	}
 #endif
 
-	ret = efi_do_enter(image_handle, &systab, entry);
+	ret = efi_do_enter(&image_obj->header, &systab, entry);
 
-exit:
+err_prepare:
 	/* image has returned, loaded-image obj goes *poof*: */
-	if (image_handle)
-		efi_delete_handle(&image_handle->parent);
+	bootefi_run_finish(image_obj, loaded_image_info);
+
+err_add_protocol:
 	if (mem_handle)
 		efi_delete_handle(mem_handle);
 
 	return ret;
 }
 
+#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
+/**
+ * bootefi_test_prepare() - prepare to run an EFI test
+ *
+ * This sets things up so we can call EFI functions. This involves preparing
+ * the 'gd' pointer and setting up the load ed image data structures.
+ *
+ * @image_objp: loaded_image_infop: Pointer to a struct which will hold the
+ *    loaded image object. This struct will be inited by this function before
+ *    use.
+ * @loaded_image_infop: Pointer to a struct which will hold the loaded image
+ *    info. This struct will be inited by this function before use.
+ * @path: File path to the test being run (often just the test name with a
+ *    backslash before it
+ * @test_func: Address of the test function that is being run
+ * @load_options_path: U-Boot environment variable to use as load options
+ * @return 0 if OK, -ve on error
+ */
+static efi_status_t bootefi_test_prepare
+		(struct efi_loaded_image_obj **image_objp,
+		struct efi_loaded_image **loaded_image_infop, const char *path,
+		ulong test_func, const char *load_options_path)
+{
+	/* Construct a dummy device path */
+	bootefi_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
+					      (uintptr_t)test_func,
+					      (uintptr_t)test_func);
+	if (!bootefi_device_path)
+		return EFI_OUT_OF_RESOURCES;
+	bootefi_image_path = efi_dp_from_file(NULL, 0, path);
+	if (!bootefi_image_path)
+		return EFI_OUT_OF_RESOURCES;
+
+	return bootefi_run_prepare(load_options_path, bootefi_device_path,
+				   bootefi_image_path, image_objp,
+				   loaded_image_infop);
+}
+
+#endif /* CONFIG_CMD_BOOTEFI_SELFTEST */
+
 static int do_bootefi_bootmgr_exec(void)
 {
 	struct efi_device_path *device_path, *file_path;
@@ -527,29 +593,17 @@
 #endif
 #ifdef CONFIG_CMD_BOOTEFI_SELFTEST
 	if (!strcmp(argv[1], "selftest")) {
-		struct efi_loaded_image_obj *image_handle;
+		struct efi_loaded_image_obj *image_obj;
 		struct efi_loaded_image *loaded_image_info;
 
-		/* Construct a dummy device path. */
-		bootefi_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
-						      (uintptr_t)&efi_selftest,
-						      (uintptr_t)&efi_selftest);
-		bootefi_image_path = efi_dp_from_file(NULL, 0, "\\selftest");
-
-		r = efi_setup_loaded_image(bootefi_device_path,
-					   bootefi_image_path, &image_handle,
-					   &loaded_image_info);
-		if (r != EFI_SUCCESS)
+		if (bootefi_test_prepare(&image_obj, &loaded_image_info,
+					 "\\selftest", (uintptr_t)&efi_selftest,
+					 "efi_selftest"))
 			return CMD_RET_FAILURE;
 
-		efi_save_gd();
-		/* Transfer environment variable efi_selftest as load options */
-		set_load_options(loaded_image_info, "efi_selftest");
 		/* Execute the test */
-		r = efi_selftest(image_handle, &systab);
-		efi_restore_gd();
-		free(loaded_image_info->load_options);
-		efi_delete_handle(&image_handle->parent);
+		r = efi_selftest(&image_obj->header, &systab);
+		bootefi_run_finish(image_obj, loaded_image_info);
 		return r != EFI_SUCCESS;
 	} else
 #endif
@@ -608,45 +662,19 @@
 
 void efi_set_bootdev(const char *dev, const char *devnr, const char *path)
 {
-	char filename[32] = { 0 }; /* dp->str is u16[32] long */
-	char *s;
+	struct efi_device_path *device, *image;
+	efi_status_t ret;
 
 	/* efi_set_bootdev is typically called repeatedly, recover memory */
 	efi_free_pool(bootefi_device_path);
 	efi_free_pool(bootefi_image_path);
-	/* If blk_get_device_part_str fails, avoid duplicate free. */
-	bootefi_device_path = NULL;
-	bootefi_image_path = NULL;
-
-	if (strcmp(dev, "Net")) {
-		struct blk_desc *desc;
-		disk_partition_t fs_partition;
-		int part;
 
-		part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition,
-					       1);
-		if (part < 0)
-			return;
-
-		bootefi_device_path = efi_dp_from_part(desc, part);
-	} else {
-#ifdef CONFIG_NET
-		bootefi_device_path = efi_dp_from_eth();
-#endif
-	}
-
-	if (!path)
-		return;
-
-	if (strcmp(dev, "Net")) {
-		/* Add leading / to fs paths, because they're absolute */
-		snprintf(filename, sizeof(filename), "/%s", path);
+	ret = efi_dp_from_name(dev, devnr, path, &device, &image);
+	if (ret == EFI_SUCCESS) {
+		bootefi_device_path = device;
+		bootefi_image_path = image;
 	} else {
-		snprintf(filename, sizeof(filename), "%s", path);
+		bootefi_device_path = NULL;
+		bootefi_image_path = NULL;
 	}
-	/* DOS style file path: */
-	s = filename;
-	while ((s = strchr(s, '/')))
-		*s++ = '\\';
-	bootefi_image_path = efi_dp_from_file(NULL, 0, filename);
 }
diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
index 21f353f..979ac4a 100644
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
@@ -253,6 +253,7 @@
 
 	int len;
 	char *sep;
+	char *default_str;
 	struct bootmenu_entry *entry;
 
 	menu = malloc(sizeof(struct bootmenu_data));
@@ -263,6 +264,10 @@
 	menu->active = 0;
 	menu->first = NULL;
 
+	default_str = env_get("bootmenu_default");
+	if (default_str)
+		menu->active = (int)simple_strtol(default_str, NULL, 10);
+
 	while ((option = bootmenu_getoption(i))) {
 		sep = strchr(option, '=');
 		if (!sep) {
diff --git a/cmd/cls.c b/cmd/cls.c
new file mode 100644
index 0000000..f1ce6e8
--- /dev/null
+++ b/cmd/cls.c
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018
+ * DENX Software Engineering, Anatolij Gustschin <agust@denx.de>
+ *
+ * cls - clear screen command
+ */
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <lcd.h>
+#include <video.h>
+
+static int do_video_clear(cmd_tbl_t *cmdtp, int flag, int argc,
+			  char *const argv[])
+{
+#if defined(CONFIG_DM_VIDEO)
+	struct udevice *dev;
+
+	if (uclass_first_device_err(UCLASS_VIDEO, &dev))
+		return CMD_RET_FAILURE;
+
+	if (video_clear(dev))
+		return CMD_RET_FAILURE;
+#elif defined(CONFIG_CFB_CONSOLE)
+	video_clear();
+#elif defined(CONFIG_LCD)
+	lcd_clear();
+#else
+	return CMD_RET_FAILURE;
+#endif
+	return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(cls,	1, 1, do_video_clear, "clear screen", "");
diff --git a/cmd/eeprom.c b/cmd/eeprom.c
index 9136630..6c29b33 100644
--- a/cmd/eeprom.c
+++ b/cmd/eeprom.c
@@ -124,6 +124,23 @@
 {
 	int ret = 0;
 
+#if defined(CONFIG_DM_I2C) && defined(CONFIG_SYS_I2C_EEPROM_BUS)
+	struct udevice *dev;
+
+	ret = i2c_get_chip_for_busnum(CONFIG_SYS_I2C_EEPROM_BUS, addr[0],
+				      alen - 1, &dev);
+	if (ret) {
+		printf("%s: Cannot find udev for a bus %d\n", __func__,
+		       CONFIG_SYS_I2C_EEPROM_BUS);
+		return CMD_RET_FAILURE;
+	}
+
+	if (read)
+		ret = dm_i2c_read(dev, offset, buffer, len);
+	else
+		ret = dm_i2c_write(dev, offset, buffer, len);
+
+#else /* Non DM I2C support - will be removed */
 #if defined(CONFIG_SYS_I2C_EEPROM_BUS)
 	i2c_set_bus_num(CONFIG_SYS_I2C_EEPROM_BUS);
 #endif
@@ -132,9 +149,9 @@
 		ret = i2c_read(addr[0], offset, alen - 1, buffer, len);
 	else
 		ret = i2c_write(addr[0], offset, alen - 1, buffer, len);
-
+#endif /* CONFIG_DM_I2C && CONFIG_SYS_I2C_EEPROM_BUS */
 	if (ret)
-		ret = 1;
+		ret = CMD_RET_FAILURE;
 
 	return ret;
 }
diff --git a/cmd/fdt.c b/cmd/fdt.c
index 8a19a3f..10d8f32 100644
--- a/cmd/fdt.c
+++ b/cmd/fdt.c
@@ -73,6 +73,40 @@
 	return 0;
 }
 
+static const char * const fdt_member_table[] = {
+	"magic",
+	"totalsize",
+	"off_dt_struct",
+	"off_dt_strings",
+	"off_mem_rsvmap",
+	"version",
+	"last_comp_version",
+	"boot_cpuid_phys",
+	"size_dt_strings",
+	"size_dt_struct",
+};
+
+static int fdt_get_header_value(int argc, char * const argv[])
+{
+	fdt32_t *fdtp = (fdt32_t *)working_fdt;
+	ulong val;
+	int i;
+
+	if (argv[2][0] != 'g')
+		return CMD_RET_FAILURE;
+
+	for (i = 0; i < ARRAY_SIZE(fdt_member_table); i++) {
+		if (strcmp(fdt_member_table[i], argv[4]))
+			continue;
+
+		val = fdt32_to_cpu(fdtp[i]);
+		env_set_hex(argv[3], val);
+		return CMD_RET_SUCCESS;
+	}
+
+	return CMD_RET_FAILURE;
+}
+
 /*
  * Flattened Device Tree command, see the help for parameter definitions.
  */
@@ -202,7 +236,7 @@
 				fdt_strerror(err));
 			return 1;
 		}
-		working_fdt = newaddr;
+		set_working_fdt_addr((ulong)newaddr);
 #ifdef CONFIG_OF_SYSTEM_SETUP
 	/* Call the board-specific fixup routine */
 	} else if (strncmp(argv[1], "sys", 3) == 0) {
@@ -491,6 +525,9 @@
 	 * Display header info
 	 */
 	} else if (argv[1][0] == 'h') {
+		if (argc == 5)
+			return fdt_get_header_value(argc, argv);
+
 		u32 version = fdt_version(working_fdt);
 		printf("magic:\t\t\t0x%x\n", fdt_magic(working_fdt));
 		printf("totalsize:\t\t0x%x (%d)\n", fdt_totalsize(working_fdt),
@@ -1090,7 +1127,8 @@
 	"fdt set    <path> <prop> [<val>]    - Set <property> [to <val>]\n"
 	"fdt mknode <path> <node>            - Create a new node after <path>\n"
 	"fdt rm     <path> [<prop>]          - Delete the node or <property>\n"
-	"fdt header                          - Display header info\n"
+	"fdt header [get <var> <member>]     - Display header info\n"
+	"                                      get - get header member <member> and store it in <var>\n"
 	"fdt bootcpu <id>                    - Set boot cpuid\n"
 	"fdt memory <addr> <size>            - Add/Update memory node\n"
 	"fdt rsvmem print                    - Show current mem reserves\n"
diff --git a/cmd/host.c b/cmd/host.c
index 645dba4..f7d3eae 100644
--- a/cmd/host.c
+++ b/cmd/host.c
@@ -168,11 +168,6 @@
 }
 
 U_BOOT_CMD(
-	sb,	8,	1,	do_host,
-	"Deprecated: use 'host' command instead.", ""
-);
-
-U_BOOT_CMD(
 	host, 8, 1, do_host,
 	"Miscellaneous host commands",
 	"load hostfs - <addr> <filename> [<bytes> <offset>]  - "
diff --git a/cmd/sb.c b/cmd/sb.c
new file mode 100644
index 0000000..5701e03
--- /dev/null
+++ b/cmd/sb.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018, Google Inc.
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <spl.h>
+#include <asm/state.h>
+
+static int do_sb_handoff(cmd_tbl_t *cmdtp, int flag, int argc,
+			 char *const argv[])
+{
+#if CONFIG_IS_ENABLED(HANDOFF)
+	if (gd->spl_handoff)
+		printf("SPL handoff magic %lx\n", gd->spl_handoff->arch.magic);
+	else
+		printf("SPL handoff info not received\n");
+
+	return 0;
+#else
+	printf("Command not supported\n");
+
+	return CMD_RET_USAGE;
+#endif
+}
+
+static int do_sb_state(cmd_tbl_t *cmdtp, int flag, int argc,
+		       char * const argv[])
+{
+	struct sandbox_state *state;
+
+	state = state_get_current();
+	state_show(state);
+
+	return 0;
+}
+
+static cmd_tbl_t cmd_sb_sub[] = {
+	U_BOOT_CMD_MKENT(handoff, 1, 0, do_sb_handoff, "", ""),
+	U_BOOT_CMD_MKENT(state, 1, 0, do_sb_state, "", ""),
+};
+
+static int do_sb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	cmd_tbl_t *c;
+
+	/* Skip past 'sb' */
+	argc--;
+	argv++;
+
+	c = find_cmd_tbl(argv[0], cmd_sb_sub, ARRAY_SIZE(cmd_sb_sub));
+	if (c)
+		return c->cmd(cmdtp, flag, argc, argv);
+	else
+		return CMD_RET_USAGE;
+}
+
+U_BOOT_CMD(
+	sb,	8,	1,	do_sb,
+	"Sandbox status commands",
+	"handoff     - Show handoff data received from SPL\n"
+	"sb state       - Show sandbox state"
+);
diff --git a/cmd/tpm-common.c b/cmd/tpm-common.c
index 5644386..89f2aa0 100644
--- a/cmd/tpm-common.c
+++ b/cmd/tpm-common.c
@@ -264,10 +264,16 @@
 
 int do_tpm_init(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
+	struct udevice *dev;
+	int rc;
+
 	if (argc != 1)
 		return CMD_RET_USAGE;
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
 
-	return report_return_code(tpm_init());
+	return report_return_code(tpm_init(dev));
 }
 
 int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
diff --git a/cmd/tpm-v1.c b/cmd/tpm-v1.c
index 6987000..b75e093 100644
--- a/cmd/tpm-v1.c
+++ b/cmd/tpm-v1.c
@@ -14,7 +14,12 @@
 			  char * const argv[])
 {
 	enum tpm_startup_type mode;
+	struct udevice *dev;
+	int rc;
 
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
 	if (argc != 2)
 		return CMD_RET_USAGE;
 	if (!strcasecmp("TPM_ST_CLEAR", argv[1])) {
@@ -28,13 +33,19 @@
 		return CMD_RET_FAILURE;
 	}
 
-	return report_return_code(tpm_startup(mode));
+	return report_return_code(tpm_startup(dev, mode));
 }
 
 static int do_tpm_nv_define_space(cmd_tbl_t *cmdtp, int flag, int argc,
 				  char * const argv[])
 {
 	u32 index, perm, size;
+	struct udevice *dev;
+	int rc;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
 
 	if (argc != 4)
 		return CMD_RET_USAGE;
@@ -42,22 +53,27 @@
 	perm = simple_strtoul(argv[2], NULL, 0);
 	size = simple_strtoul(argv[3], NULL, 0);
 
-	return report_return_code(tpm_nv_define_space(index, perm, size));
+	return report_return_code(tpm_nv_define_space(dev, index, perm, size));
 }
 
 static int do_tpm_nv_read_value(cmd_tbl_t *cmdtp, int flag, int argc,
 				char * const argv[])
 {
 	u32 index, count, rc;
+	struct udevice *dev;
 	void *data;
 
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
+
 	if (argc != 4)
 		return CMD_RET_USAGE;
 	index = simple_strtoul(argv[1], NULL, 0);
 	data = (void *)simple_strtoul(argv[2], NULL, 0);
 	count = simple_strtoul(argv[3], NULL, 0);
 
-	rc = tpm_nv_read_value(index, data, count);
+	rc = tpm_nv_read_value(dev, index, data, count);
 	if (!rc) {
 		puts("area content:\n");
 		print_byte_string(data, count);
@@ -69,10 +85,15 @@
 static int do_tpm_nv_write_value(cmd_tbl_t *cmdtp, int flag, int argc,
 				 char * const argv[])
 {
+	struct udevice *dev;
 	u32 index, rc;
 	size_t count;
 	void *data;
 
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
+
 	if (argc != 3)
 		return CMD_RET_USAGE;
 	index = simple_strtoul(argv[1], NULL, 0);
@@ -82,7 +103,7 @@
 		return CMD_RET_FAILURE;
 	}
 
-	rc = tpm_nv_write_value(index, data, count);
+	rc = tpm_nv_write_value(dev, index, data, count);
 	free(data);
 
 	return report_return_code(rc);
@@ -91,8 +112,13 @@
 static int do_tpm_extend(cmd_tbl_t *cmdtp, int flag, int argc,
 			 char * const argv[])
 {
-	u32 index, rc;
 	u8 in_digest[20], out_digest[20];
+	struct udevice *dev;
+	u32 index, rc;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
 
 	if (argc != 3)
 		return CMD_RET_USAGE;
@@ -102,7 +128,7 @@
 		return CMD_RET_FAILURE;
 	}
 
-	rc = tpm_extend(index, in_digest, out_digest);
+	rc = tpm_extend(dev, index, in_digest, out_digest);
 	if (!rc) {
 		puts("PCR value after execution of the command:\n");
 		print_byte_string(out_digest, sizeof(out_digest));
@@ -115,15 +141,20 @@
 			   char * const argv[])
 {
 	u32 index, count, rc;
+	struct udevice *dev;
 	void *data;
 
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
+
 	if (argc != 4)
 		return CMD_RET_USAGE;
 	index = simple_strtoul(argv[1], NULL, 0);
 	data = (void *)simple_strtoul(argv[2], NULL, 0);
 	count = simple_strtoul(argv[3], NULL, 0);
 
-	rc = tpm_pcr_read(index, data, count);
+	rc = tpm_pcr_read(dev, index, data, count);
 	if (!rc) {
 		puts("Named PCR content:\n");
 		print_byte_string(data, count);
@@ -135,27 +166,38 @@
 static int do_tpm_tsc_physical_presence(cmd_tbl_t *cmdtp, int flag, int argc,
 					char * const argv[])
 {
+	struct udevice *dev;
 	u16 presence;
+	int rc;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
 
 	if (argc != 2)
 		return CMD_RET_USAGE;
 	presence = (u16)simple_strtoul(argv[1], NULL, 0);
 
-	return report_return_code(tpm_tsc_physical_presence(presence));
+	return report_return_code(tpm_tsc_physical_presence(dev, presence));
 }
 
 static int do_tpm_read_pubek(cmd_tbl_t *cmdtp, int flag, int argc,
 			     char * const argv[])
 {
+	struct udevice *dev;
 	u32 count, rc;
 	void *data;
 
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
+
 	if (argc != 3)
 		return CMD_RET_USAGE;
 	data = (void *)simple_strtoul(argv[1], NULL, 0);
 	count = simple_strtoul(argv[2], NULL, 0);
 
-	rc = tpm_read_pubek(data, count);
+	rc = tpm_read_pubek(dev, data, count);
 	if (!rc) {
 		puts("pubek value:\n");
 		print_byte_string(data, count);
@@ -167,13 +209,19 @@
 static int do_tpm_physical_set_deactivated(cmd_tbl_t *cmdtp, int flag, int argc,
 					   char * const argv[])
 {
+	struct udevice *dev;
 	u8 state;
+	int rc;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
 
 	if (argc != 2)
 		return CMD_RET_USAGE;
 	state = (u8)simple_strtoul(argv[1], NULL, 0);
 
-	return report_return_code(tpm_physical_set_deactivated(state));
+	return report_return_code(tpm_physical_set_deactivated(dev, state));
 }
 
 static int do_tpm_get_capability(cmd_tbl_t *cmdtp, int flag, int argc,
@@ -182,6 +230,11 @@
 	u32 cap_area, sub_cap, rc;
 	void *cap;
 	size_t count;
+	struct udevice *dev;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
 
 	if (argc != 5)
 		return CMD_RET_USAGE;
@@ -190,7 +243,7 @@
 	cap = (void *)simple_strtoul(argv[3], NULL, 0);
 	count = simple_strtoul(argv[4], NULL, 0);
 
-	rc = tpm_get_capability(cap_area, sub_cap, cap, count);
+	rc = tpm_get_capability(dev, cap_area, sub_cap, cap, count);
 	if (!rc) {
 		puts("capability information:\n");
 		print_byte_string(cap, count);
@@ -232,6 +285,12 @@
 			    char * const argv[])
 {
 	u32 index, perm, size;
+	struct udevice *dev;
+	int rc;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
 
 	if (argc != 4)
 		return CMD_RET_USAGE;
@@ -243,14 +302,20 @@
 	index = simple_strtoul(argv[2], NULL, 0);
 	perm = simple_strtoul(argv[3], NULL, 0);
 
-	return report_return_code(tpm_nv_define_space(index, perm, size));
+	return report_return_code(tpm_nv_define_space(dev, index, perm, size));
 }
 
 static int do_tpm_nv_read(cmd_tbl_t *cmdtp, int flag, int argc,
 			  char * const argv[])
 {
 	u32 index, count, err;
+	struct udevice *dev;
 	void *data;
+	int rc;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
 
 	if (argc < 3)
 		return CMD_RET_USAGE;
@@ -263,7 +328,7 @@
 		return CMD_RET_USAGE;
 	}
 
-	err = tpm_nv_read_value(index, data, count);
+	err = tpm_nv_read_value(dev, index, data, count);
 	if (!err) {
 		if (type_string_write_vars(argv[1], data, argv + 3)) {
 			printf("Couldn't write to variables\n");
@@ -279,7 +344,13 @@
 			   char * const argv[])
 {
 	u32 index, count, err;
+	struct udevice *dev;
 	void *data;
+	int rc;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
 
 	if (argc < 3)
 		return CMD_RET_USAGE;
@@ -297,7 +368,7 @@
 		return CMD_RET_USAGE;
 	}
 
-	err = tpm_nv_write_value(index, data, count);
+	err = tpm_nv_write_value(dev, index, data, count);
 	free(data);
 
 	return report_return_code(err);
@@ -309,8 +380,14 @@
 		       char * const argv[])
 {
 	u32 auth_handle, err;
+	struct udevice *dev;
+	int rc;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
 
-	err = tpm_oiap(&auth_handle);
+	err = tpm_oiap(dev, &auth_handle);
 
 	return report_return_code(err);
 }
@@ -324,6 +401,11 @@
 	u8 usage_auth[DIGEST_LENGTH];
 	u8 parent_hash[DIGEST_LENGTH];
 	void *key;
+	struct udevice *dev;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
 
 	if (argc < 5)
 		return CMD_RET_USAGE;
@@ -360,6 +442,12 @@
 	u32 parent_handle, key_len, key_handle, err;
 	u8 usage_auth[DIGEST_LENGTH];
 	void *key;
+	struct udevice *dev;
+	int rc;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
 
 	if (argc < 5)
 		return CMD_RET_USAGE;
@@ -371,7 +459,7 @@
 		return CMD_RET_FAILURE;
 	parse_byte_string(argv[4], usage_auth, NULL);
 
-	err = tpm_load_key2_oiap(parent_handle, key, key_len, usage_auth,
+	err = tpm_load_key2_oiap(dev, parent_handle, key, key_len, usage_auth,
 				 &key_handle);
 	if (!err)
 		printf("Key handle is 0x%x\n", key_handle);
@@ -386,6 +474,12 @@
 	u8 usage_auth[DIGEST_LENGTH];
 	u8 pub_key_buffer[TPM_PUBKEY_MAX_LENGTH];
 	size_t pub_key_len = sizeof(pub_key_buffer);
+	struct udevice *dev;
+	int rc;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
 
 	if (argc < 3)
 		return CMD_RET_USAGE;
@@ -395,7 +489,7 @@
 		return CMD_RET_FAILURE;
 	parse_byte_string(argv[2], usage_auth, NULL);
 
-	err = tpm_get_pub_key_oiap(key_handle, usage_auth, pub_key_buffer,
+	err = tpm_get_pub_key_oiap(dev, key_handle, usage_auth, pub_key_buffer,
 				   &pub_key_len);
 	if (!err) {
 		printf("dump of received pub key structure:\n");
@@ -412,7 +506,13 @@
 static int do_tpm_flush(cmd_tbl_t *cmdtp, int flag, int argc,
 			char * const argv[])
 {
+	struct udevice *dev;
 	int type = 0;
+	int rc;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
 
 	if (argc != 3)
 		return CMD_RET_USAGE;
@@ -451,7 +551,7 @@
 		uint i;
 
 		/* fetch list of already loaded resources in the TPM */
-		err = tpm_get_capability(TPM_CAP_HANDLE, type, buf,
+		err = tpm_get_capability(dev, TPM_CAP_HANDLE, type, buf,
 					 sizeof(buf));
 		if (err) {
 			printf("tpm_get_capability returned error %d.\n", err);
@@ -460,7 +560,7 @@
 		res_count = get_unaligned_be16(buf);
 		ptr = buf + 2;
 		for (i = 0; i < res_count; ++i, ptr += 4)
-			tpm_flush_specific(get_unaligned_be32(ptr), type);
+			tpm_flush_specific(dev, get_unaligned_be32(ptr), type);
 	} else {
 		u32 handle = simple_strtoul(argv[2], NULL, 0);
 
@@ -468,7 +568,7 @@
 			printf("Illegal resource handle %s\n", argv[2]);
 			return -1;
 		}
-		tpm_flush_specific(cpu_to_be32(handle), type);
+		tpm_flush_specific(dev, cpu_to_be32(handle), type);
 	}
 
 	return 0;
diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c
index ffbf35a..bb51834 100644
--- a/cmd/tpm-v2.c
+++ b/cmd/tpm-v2.c
@@ -16,7 +16,12 @@
 			   char * const argv[])
 {
 	enum tpm2_startup_types mode;
+	struct udevice *dev;
+	int ret;
 
+	ret = get_tpm(&dev);
+	if (ret)
+		return ret;
 	if (argc != 2)
 		return CMD_RET_USAGE;
 
@@ -29,14 +34,19 @@
 		return CMD_RET_FAILURE;
 	}
 
-	return report_return_code(tpm2_startup(mode));
+	return report_return_code(tpm2_startup(dev, mode));
 }
 
 static int do_tpm2_self_test(cmd_tbl_t *cmdtp, int flag, int argc,
 			     char * const argv[])
 {
 	enum tpm2_yes_no full_test;
+	struct udevice *dev;
+	int ret;
 
+	ret = get_tpm(&dev);
+	if (ret)
+		return ret;
 	if (argc != 2)
 		return CMD_RET_USAGE;
 
@@ -49,7 +59,7 @@
 		return CMD_RET_FAILURE;
 	}
 
-	return report_return_code(tpm2_self_test(full_test));
+	return report_return_code(tpm2_self_test(dev, full_test));
 }
 
 static int do_tpm2_clear(cmd_tbl_t *cmdtp, int flag, int argc,
@@ -58,6 +68,12 @@
 	u32 handle = 0;
 	const char *pw = (argc < 3) ? NULL : argv[2];
 	const ssize_t pw_sz = pw ? strlen(pw) : 0;
+	struct udevice *dev;
+	int ret;
+
+	ret = get_tpm(&dev);
+	if (ret)
+		return ret;
 
 	if (argc < 2 || argc > 3)
 		return CMD_RET_USAGE;
@@ -72,7 +88,7 @@
 	else
 		return CMD_RET_USAGE;
 
-	return report_return_code(tpm2_clear(handle, pw, pw_sz));
+	return report_return_code(tpm2_clear(dev, handle, pw, pw_sz));
 }
 
 static int do_tpm2_pcr_extend(cmd_tbl_t *cmdtp, int flag, int argc,
@@ -88,7 +104,7 @@
 	if (argc != 3)
 		return CMD_RET_USAGE;
 
-	ret = uclass_first_device_err(UCLASS_TPM, &dev);
+	ret = get_tpm(&dev);
 	if (ret)
 		return ret;
 
@@ -99,7 +115,7 @@
 	if (index >= priv->pcr_count)
 		return -EINVAL;
 
-	rc = tpm2_pcr_extend(index, digest);
+	rc = tpm2_pcr_extend(dev, index, digest);
 
 	unmap_sysmem(digest);
 
@@ -119,7 +135,7 @@
 	if (argc != 3)
 		return CMD_RET_USAGE;
 
-	ret = uclass_first_device_err(UCLASS_TPM, &dev);
+	ret = get_tpm(&dev);
 	if (ret)
 		return ret;
 
@@ -133,7 +149,7 @@
 
 	data = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0);
 
-	rc = tpm2_pcr_read(index, priv->pcr_select_min, data, &updates);
+	rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, data, &updates);
 	if (!rc) {
 		printf("PCR #%u content (%d known updates):\n", index, updates);
 		print_byte_string(data, TPM2_DIGEST_LEN);
@@ -151,6 +167,12 @@
 	u8 *data;
 	size_t count;
 	int i, j;
+	struct udevice *dev;
+	int ret;
+
+	ret = get_tpm(&dev);
+	if (ret)
+		return ret;
 
 	if (argc != 5)
 		return CMD_RET_USAGE;
@@ -160,7 +182,7 @@
 	data = map_sysmem(simple_strtoul(argv[3], NULL, 0), 0);
 	count = simple_strtoul(argv[4], NULL, 0);
 
-	rc = tpm2_get_capability(capability, property, data, count);
+	rc = tpm2_get_capability(dev, capability, property, data, count);
 	if (rc)
 		goto unmap_data;
 
@@ -186,6 +208,12 @@
 {
 	const char *pw = (argc < 2) ? NULL : argv[1];
 	const ssize_t pw_sz = pw ? strlen(pw) : 0;
+	struct udevice *dev;
+	int ret;
+
+	ret = get_tpm(&dev);
+	if (ret)
+		return ret;
 
 	if (argc > 2)
 		return CMD_RET_USAGE;
@@ -193,7 +221,7 @@
 	if (pw_sz > TPM2_DIGEST_LEN)
 		return -EINVAL;
 
-	return report_return_code(tpm2_dam_reset(pw, pw_sz));
+	return report_return_code(tpm2_dam_reset(dev, pw, pw_sz));
 }
 
 static int do_tpm_dam_parameters(cmd_tbl_t *cmdtp, int flag, int argc,
@@ -208,6 +236,12 @@
 	unsigned long int max_tries;
 	unsigned long int recovery_time;
 	unsigned long int lockout_recovery;
+	struct udevice *dev;
+	int ret;
+
+	ret = get_tpm(&dev);
+	if (ret)
+		return ret;
 
 	if (argc < 4 || argc > 5)
 		return CMD_RET_USAGE;
@@ -229,7 +263,7 @@
 	log(LOGC_NONE, LOGL_INFO, "- recoveryTime: %lu\n", recovery_time);
 	log(LOGC_NONE, LOGL_INFO, "- lockoutRecovery: %lu\n", lockout_recovery);
 
-	return report_return_code(tpm2_dam_parameters(pw, pw_sz, max_tries,
+	return report_return_code(tpm2_dam_parameters(dev, pw, pw_sz, max_tries,
 						      recovery_time,
 						      lockout_recovery));
 }
@@ -242,6 +276,12 @@
 	const char *oldpw = (argc == 3) ? NULL : argv[3];
 	const ssize_t newpw_sz = strlen(newpw);
 	const ssize_t oldpw_sz = oldpw ? strlen(oldpw) : 0;
+	struct udevice *dev;
+	int ret;
+
+	ret = get_tpm(&dev);
+	if (ret)
+		return ret;
 
 	if (argc < 3 || argc > 4)
 		return CMD_RET_USAGE;
@@ -260,7 +300,7 @@
 	else
 		return CMD_RET_USAGE;
 
-	return report_return_code(tpm2_change_auth(handle, newpw, newpw_sz,
+	return report_return_code(tpm2_change_auth(dev, handle, newpw, newpw_sz,
 						   oldpw, oldpw_sz));
 }
 
@@ -271,6 +311,12 @@
 	char *key = argv[2];
 	const char *pw = (argc < 4) ? NULL : argv[3];
 	const ssize_t pw_sz = pw ? strlen(pw) : 0;
+	struct udevice *dev;
+	int ret;
+
+	ret = get_tpm(&dev);
+	if (ret)
+		return ret;
 
 	if (strlen(key) != TPM2_DIGEST_LEN)
 		return -EINVAL;
@@ -278,7 +324,7 @@
 	if (argc < 3 || argc > 4)
 		return CMD_RET_USAGE;
 
-	return report_return_code(tpm2_pcr_setauthpolicy(pw, pw_sz, index,
+	return report_return_code(tpm2_pcr_setauthpolicy(dev, pw, pw_sz, index,
 							 key));
 }
 
@@ -290,6 +336,12 @@
 	const ssize_t key_sz = strlen(key);
 	const char *pw = (argc < 4) ? NULL : argv[3];
 	const ssize_t pw_sz = pw ? strlen(pw) : 0;
+	struct udevice *dev;
+	int ret;
+
+	ret = get_tpm(&dev);
+	if (ret)
+		return ret;
 
 	if (strlen(key) != TPM2_DIGEST_LEN)
 		return -EINVAL;
@@ -297,7 +349,7 @@
 	if (argc < 3 || argc > 4)
 		return CMD_RET_USAGE;
 
-	return report_return_code(tpm2_pcr_setauthvalue(pw, pw_sz, index,
+	return report_return_code(tpm2_pcr_setauthvalue(dev, pw, pw_sz, index,
 							key, key_sz));
 }
 
diff --git a/cmd/tpm_test.c b/cmd/tpm_test.c
index f21ad5d..56a5aa4 100644
--- a/cmd/tpm_test.c
+++ b/cmd/tpm_test.c
@@ -7,6 +7,7 @@
 #include <command.h>
 #include <environment.h>
 #include <tpm-v1.h>
+#include "tpm-user-utils.h"
 
 /* Prints error and returns on failure */
 #define TPM_CHECK(tpm_command) do { \
@@ -28,26 +29,26 @@
 #define PHYS_PRESENCE		4
 #define PRESENCE		8
 
-static uint32_t TlclStartupIfNeeded(void)
+static uint32_t TlclStartupIfNeeded(struct udevice *dev)
 {
-	uint32_t result = tpm_startup(TPM_ST_CLEAR);
+	uint32_t result = tpm_startup(dev, TPM_ST_CLEAR);
 
 	return result == TPM_INVALID_POSTINIT ? TPM_SUCCESS : result;
 }
 
-static int test_timer(void)
+static int test_timer(struct udevice *dev)
 {
 	printf("get_timer(0) = %lu\n", get_timer(0));
 	return 0;
 }
 
-static uint32_t tpm_get_flags(uint8_t *disable, uint8_t *deactivated,
-			      uint8_t *nvlocked)
+static uint32_t tpm_get_flags(struct udevice *dev, uint8_t *disable,
+			      uint8_t *deactivated, uint8_t *nvlocked)
 {
 	struct tpm_permanent_flags pflags;
 	uint32_t result;
 
-	result = tpm_get_permanent_flags(&pflags);
+	result = tpm_get_permanent_flags(dev, &pflags);
 	if (result)
 		return result;
 	if (disable)
@@ -62,79 +63,79 @@
 	return 0;
 }
 
-static uint32_t tpm_nv_write_value_lock(uint32_t index)
+static uint32_t tpm_nv_write_value_lock(struct udevice *dev, uint32_t index)
 {
 	debug("TPM: Write lock 0x%x\n", index);
 
-	return tpm_nv_write_value(index, NULL, 0);
+	return tpm_nv_write_value(dev, index, NULL, 0);
 }
 
-static int tpm_is_owned(void)
+static int tpm_is_owned(struct udevice *dev)
 {
 	uint8_t response[TPM_PUBEK_SIZE];
 	uint32_t result;
 
-	result = tpm_read_pubek(response, sizeof(response));
+	result = tpm_read_pubek(dev, response, sizeof(response));
 
 	return result != TPM_SUCCESS;
 }
 
-static int test_early_extend(void)
+static int test_early_extend(struct udevice *dev)
 {
 	uint8_t value_in[20];
 	uint8_t value_out[20];
 
 	printf("Testing earlyextend ...");
-	tpm_init();
-	TPM_CHECK(tpm_startup(TPM_ST_CLEAR));
-	TPM_CHECK(tpm_continue_self_test());
-	TPM_CHECK(tpm_extend(1, value_in, value_out));
+	tpm_init(dev);
+	TPM_CHECK(tpm_startup(dev, TPM_ST_CLEAR));
+	TPM_CHECK(tpm_continue_self_test(dev));
+	TPM_CHECK(tpm_extend(dev, 1, value_in, value_out));
 	printf("done\n");
 	return 0;
 }
 
-static int test_early_nvram(void)
+static int test_early_nvram(struct udevice *dev)
 {
 	uint32_t x;
 
 	printf("Testing earlynvram ...");
-	tpm_init();
-	TPM_CHECK(tpm_startup(TPM_ST_CLEAR));
-	TPM_CHECK(tpm_continue_self_test());
-	TPM_CHECK(tpm_tsc_physical_presence(PRESENCE));
-	TPM_CHECK(tpm_nv_read_value(INDEX0, (uint8_t *)&x, sizeof(x)));
+	tpm_init(dev);
+	TPM_CHECK(tpm_startup(dev, TPM_ST_CLEAR));
+	TPM_CHECK(tpm_continue_self_test(dev));
+	TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
+	TPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)));
 	printf("done\n");
 	return 0;
 }
 
-static int test_early_nvram2(void)
+static int test_early_nvram2(struct udevice *dev)
 {
 	uint32_t x;
 
 	printf("Testing earlynvram2 ...");
-	tpm_init();
-	TPM_CHECK(tpm_startup(TPM_ST_CLEAR));
-	TPM_CHECK(tpm_continue_self_test());
-	TPM_CHECK(tpm_tsc_physical_presence(PRESENCE));
-	TPM_CHECK(tpm_nv_write_value(INDEX0, (uint8_t *)&x, sizeof(x)));
+	tpm_init(dev);
+	TPM_CHECK(tpm_startup(dev, TPM_ST_CLEAR));
+	TPM_CHECK(tpm_continue_self_test(dev));
+	TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
+	TPM_CHECK(tpm_nv_write_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)));
 	printf("done\n");
 	return 0;
 }
 
-static int test_enable(void)
+static int test_enable(struct udevice *dev)
 {
 	uint8_t disable = 0, deactivated = 0;
 
 	printf("Testing enable ...\n");
-	tpm_init();
-	TPM_CHECK(TlclStartupIfNeeded());
-	TPM_CHECK(tpm_self_test_full());
-	TPM_CHECK(tpm_tsc_physical_presence(PRESENCE));
-	TPM_CHECK(tpm_get_flags(&disable, &deactivated, NULL));
+	tpm_init(dev);
+	TPM_CHECK(TlclStartupIfNeeded(dev));
+	TPM_CHECK(tpm_self_test_full(dev));
+	TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
+	TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL));
 	printf("\tdisable is %d, deactivated is %d\n", disable, deactivated);
-	TPM_CHECK(tpm_physical_enable());
-	TPM_CHECK(tpm_physical_set_deactivated(0));
-	TPM_CHECK(tpm_get_flags(&disable, &deactivated, NULL));
+	TPM_CHECK(tpm_physical_enable(dev));
+	TPM_CHECK(tpm_physical_set_deactivated(dev, 0));
+	TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL));
 	printf("\tdisable is %d, deactivated is %d\n", disable, deactivated);
 	if (disable == 1 || deactivated == 1)
 		printf("\tfailed to enable or activate\n");
@@ -147,27 +148,27 @@
 	reset_cpu(0); \
 } while (0)
 
-static int test_fast_enable(void)
+static int test_fast_enable(struct udevice *dev)
 {
 	uint8_t disable = 0, deactivated = 0;
 	int i;
 
 	printf("Testing fastenable ...\n");
-	tpm_init();
-	TPM_CHECK(TlclStartupIfNeeded());
-	TPM_CHECK(tpm_self_test_full());
-	TPM_CHECK(tpm_tsc_physical_presence(PRESENCE));
-	TPM_CHECK(tpm_get_flags(&disable, &deactivated, NULL));
+	tpm_init(dev);
+	TPM_CHECK(TlclStartupIfNeeded(dev));
+	TPM_CHECK(tpm_self_test_full(dev));
+	TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
+	TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL));
 	printf("\tdisable is %d, deactivated is %d\n", disable, deactivated);
 	for (i = 0; i < 2; i++) {
-		TPM_CHECK(tpm_force_clear());
-		TPM_CHECK(tpm_get_flags(&disable, &deactivated, NULL));
+		TPM_CHECK(tpm_force_clear(dev));
+		TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL));
 		printf("\tdisable is %d, deactivated is %d\n", disable,
 		       deactivated);
 		assert(disable == 1 && deactivated == 1);
-		TPM_CHECK(tpm_physical_enable());
-		TPM_CHECK(tpm_physical_set_deactivated(0));
-		TPM_CHECK(tpm_get_flags(&disable, &deactivated, NULL));
+		TPM_CHECK(tpm_physical_enable(dev));
+		TPM_CHECK(tpm_physical_set_deactivated(dev, 0));
+		TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL));
 		printf("\tdisable is %d, deactivated is %d\n", disable,
 		       deactivated);
 		assert(disable == 0 && deactivated == 0);
@@ -176,105 +177,109 @@
 	return 0;
 }
 
-static int test_global_lock(void)
+static int test_global_lock(struct udevice *dev)
 {
 	uint32_t zero = 0;
 	uint32_t result;
 	uint32_t x;
 
 	printf("Testing globallock ...\n");
-	tpm_init();
-	TPM_CHECK(TlclStartupIfNeeded());
-	TPM_CHECK(tpm_self_test_full());
-	TPM_CHECK(tpm_tsc_physical_presence(PRESENCE));
-	TPM_CHECK(tpm_nv_read_value(INDEX0, (uint8_t *)&x, sizeof(x)));
-	TPM_CHECK(tpm_nv_write_value(INDEX0, (uint8_t *)&zero,
+	tpm_init(dev);
+	TPM_CHECK(TlclStartupIfNeeded(dev));
+	TPM_CHECK(tpm_self_test_full(dev));
+	TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
+	TPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)));
+	TPM_CHECK(tpm_nv_write_value(dev, INDEX0, (uint8_t *)&zero,
 				     sizeof(uint32_t)));
-	TPM_CHECK(tpm_nv_read_value(INDEX1, (uint8_t *)&x, sizeof(x)));
-	TPM_CHECK(tpm_nv_write_value(INDEX1, (uint8_t *)&zero,
+	TPM_CHECK(tpm_nv_read_value(dev, INDEX1, (uint8_t *)&x, sizeof(x)));
+	TPM_CHECK(tpm_nv_write_value(dev, INDEX1, (uint8_t *)&zero,
 				     sizeof(uint32_t)));
-	TPM_CHECK(tpm_set_global_lock());
+	TPM_CHECK(tpm_set_global_lock(dev));
 	/* Verifies that write to index0 fails */
 	x = 1;
-	result = tpm_nv_write_value(INDEX0, (uint8_t *)&x, sizeof(x));
+	result = tpm_nv_write_value(dev, INDEX0, (uint8_t *)&x, sizeof(x));
 	assert(result == TPM_AREA_LOCKED);
-	TPM_CHECK(tpm_nv_read_value(INDEX0, (uint8_t *)&x, sizeof(x)));
+	TPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)));
 	assert(x == 0);
 	/* Verifies that write to index1 is still possible */
 	x = 2;
-	TPM_CHECK(tpm_nv_write_value(INDEX1, (uint8_t *)&x, sizeof(x)));
-	TPM_CHECK(tpm_nv_read_value(INDEX1, (uint8_t *)&x, sizeof(x)));
+	TPM_CHECK(tpm_nv_write_value(dev, INDEX1, (uint8_t *)&x, sizeof(x)));
+	TPM_CHECK(tpm_nv_read_value(dev, INDEX1, (uint8_t *)&x, sizeof(x)));
 	assert(x == 2);
 	/* Turns off PP */
-	tpm_tsc_physical_presence(PHYS_PRESENCE);
+	tpm_tsc_physical_presence(dev, PHYS_PRESENCE);
 	/* Verifies that write to index1 fails */
 	x = 3;
-	result = tpm_nv_write_value(INDEX1, (uint8_t *)&x, sizeof(x));
+	result = tpm_nv_write_value(dev, INDEX1, (uint8_t *)&x, sizeof(x));
 	assert(result == TPM_BAD_PRESENCE);
-	TPM_CHECK(tpm_nv_read_value(INDEX1, (uint8_t *)&x, sizeof(x)));
+	TPM_CHECK(tpm_nv_read_value(dev, INDEX1, (uint8_t *)&x, sizeof(x)));
 	assert(x == 2);
 	printf("\tdone\n");
 	return 0;
 }
 
-static int test_lock(void)
+static int test_lock(struct udevice *dev)
 {
 	printf("Testing lock ...\n");
-	tpm_init();
-	tpm_startup(TPM_ST_CLEAR);
-	tpm_self_test_full();
-	tpm_tsc_physical_presence(PRESENCE);
-	tpm_nv_write_value_lock(INDEX0);
+	tpm_init(dev);
+	tpm_startup(dev, TPM_ST_CLEAR);
+	tpm_self_test_full(dev);
+	tpm_tsc_physical_presence(dev, PRESENCE);
+	tpm_nv_write_value_lock(dev, INDEX0);
 	printf("\tLocked 0x%x\n", INDEX0);
 	printf("\tdone\n");
 	return 0;
 }
 
-static void initialise_spaces(void)
+static void initialise_spaces(struct udevice *dev)
 {
 	uint32_t zero = 0;
 	uint32_t perm = TPM_NV_PER_WRITE_STCLEAR | TPM_NV_PER_PPWRITE;
 
 	printf("\tInitialising spaces\n");
-	tpm_nv_set_locked();  /* useful only the first time */
-	tpm_nv_define_space(INDEX0, perm, 4);
-	tpm_nv_write_value(INDEX0, (uint8_t *)&zero, 4);
-	tpm_nv_define_space(INDEX1, perm, 4);
-	tpm_nv_write_value(INDEX1, (uint8_t *)&zero, 4);
-	tpm_nv_define_space(INDEX2, perm, 4);
-	tpm_nv_write_value(INDEX2, (uint8_t *)&zero, 4);
-	tpm_nv_define_space(INDEX3, perm, 4);
-	tpm_nv_write_value(INDEX3, (uint8_t *)&zero, 4);
+	tpm_nv_set_locked(dev);  /* useful only the first time */
+	tpm_nv_define_space(dev, INDEX0, perm, 4);
+	tpm_nv_write_value(dev, INDEX0, (uint8_t *)&zero, 4);
+	tpm_nv_define_space(dev, INDEX1, perm, 4);
+	tpm_nv_write_value(dev, INDEX1, (uint8_t *)&zero, 4);
+	tpm_nv_define_space(dev, INDEX2, perm, 4);
+	tpm_nv_write_value(dev, INDEX2, (uint8_t *)&zero, 4);
+	tpm_nv_define_space(dev, INDEX3, perm, 4);
+	tpm_nv_write_value(dev, INDEX3, (uint8_t *)&zero, 4);
 	perm = TPM_NV_PER_READ_STCLEAR | TPM_NV_PER_WRITE_STCLEAR |
 		TPM_NV_PER_PPWRITE;
-	tpm_nv_define_space(INDEX_INITIALISED, perm, 1);
+	tpm_nv_define_space(dev, INDEX_INITIALISED, perm, 1);
 }
 
-static int test_readonly(void)
+static int test_readonly(struct udevice *dev)
 {
 	uint8_t c;
 	uint32_t index_0, index_1, index_2, index_3;
 	int read0, read1, read2, read3;
 
 	printf("Testing readonly ...\n");
-	tpm_init();
-	tpm_startup(TPM_ST_CLEAR);
-	tpm_self_test_full();
-	tpm_tsc_physical_presence(PRESENCE);
+	tpm_init(dev);
+	tpm_startup(dev, TPM_ST_CLEAR);
+	tpm_self_test_full(dev);
+	tpm_tsc_physical_presence(dev, PRESENCE);
 	/*
 	 * Checks if initialisation has completed by trying to read-lock a
 	 * space that's created at the end of initialisation
 	 */
-	if (tpm_nv_read_value(INDEX_INITIALISED, &c, 0) == TPM_BADINDEX) {
+	if (tpm_nv_read_value(dev, INDEX_INITIALISED, &c, 0) == TPM_BADINDEX) {
 		/* The initialisation did not complete */
-		initialise_spaces();
+		initialise_spaces(dev);
 	}
 
 	/* Checks if spaces are OK or messed up */
-	read0 = tpm_nv_read_value(INDEX0, (uint8_t *)&index_0, sizeof(index_0));
-	read1 = tpm_nv_read_value(INDEX1, (uint8_t *)&index_1, sizeof(index_1));
-	read2 = tpm_nv_read_value(INDEX2, (uint8_t *)&index_2, sizeof(index_2));
-	read3 = tpm_nv_read_value(INDEX3, (uint8_t *)&index_3, sizeof(index_3));
+	read0 = tpm_nv_read_value(dev, INDEX0, (uint8_t *)&index_0,
+				  sizeof(index_0));
+	read1 = tpm_nv_read_value(dev, INDEX1, (uint8_t *)&index_1,
+				  sizeof(index_1));
+	read2 = tpm_nv_read_value(dev, INDEX2, (uint8_t *)&index_2,
+				  sizeof(index_2));
+	read3 = tpm_nv_read_value(dev, INDEX3, (uint8_t *)&index_3,
+				  sizeof(index_3));
 	if (read0 || read1 || read2 || read3) {
 		printf("Invalid contents\n");
 		return 0;
@@ -285,12 +290,14 @@
 	 * I really wish I could use the imperative.
 	 */
 	index_0 += 1;
-	if (tpm_nv_write_value(INDEX0, (uint8_t *)&index_0, sizeof(index_0) !=
+	if (tpm_nv_write_value(dev, INDEX0, (uint8_t *)&index_0,
+			       sizeof(index_0) !=
 		TPM_SUCCESS)) {
 		pr_err("\tcould not write index 0\n");
 	}
-	tpm_nv_write_value_lock(INDEX0);
-	if (tpm_nv_write_value(INDEX0, (uint8_t *)&index_0, sizeof(index_0)) ==
+	tpm_nv_write_value_lock(dev, INDEX0);
+	if (tpm_nv_write_value(dev, INDEX0, (uint8_t *)&index_0,
+			       sizeof(index_0)) ==
 			TPM_SUCCESS)
 		pr_err("\tindex 0 is not locked\n");
 
@@ -298,49 +305,49 @@
 	return 0;
 }
 
-static int test_redefine_unowned(void)
+static int test_redefine_unowned(struct udevice *dev)
 {
 	uint32_t perm;
 	uint32_t result;
 	uint32_t x;
 
 	printf("Testing redefine_unowned ...");
-	tpm_init();
-	TPM_CHECK(TlclStartupIfNeeded());
-	TPM_CHECK(tpm_self_test_full());
-	TPM_CHECK(tpm_tsc_physical_presence(PRESENCE));
-	assert(!tpm_is_owned());
+	tpm_init(dev);
+	TPM_CHECK(TlclStartupIfNeeded(dev));
+	TPM_CHECK(tpm_self_test_full(dev));
+	TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
+	assert(!tpm_is_owned(dev));
 
 	/* Ensures spaces exist. */
-	TPM_CHECK(tpm_nv_read_value(INDEX0, (uint8_t *)&x, sizeof(x)));
-	TPM_CHECK(tpm_nv_read_value(INDEX1, (uint8_t *)&x, sizeof(x)));
+	TPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)));
+	TPM_CHECK(tpm_nv_read_value(dev, INDEX1, (uint8_t *)&x, sizeof(x)));
 
 	/* Redefines spaces a couple of times. */
 	perm = TPM_NV_PER_PPWRITE | TPM_NV_PER_GLOBALLOCK;
-	TPM_CHECK(tpm_nv_define_space(INDEX0, perm, 2 * sizeof(uint32_t)));
-	TPM_CHECK(tpm_nv_define_space(INDEX0, perm, sizeof(uint32_t)));
+	TPM_CHECK(tpm_nv_define_space(dev, INDEX0, perm, 2 * sizeof(uint32_t)));
+	TPM_CHECK(tpm_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t)));
 	perm = TPM_NV_PER_PPWRITE;
-	TPM_CHECK(tpm_nv_define_space(INDEX1, perm, 2 * sizeof(uint32_t)));
-	TPM_CHECK(tpm_nv_define_space(INDEX1, perm, sizeof(uint32_t)));
+	TPM_CHECK(tpm_nv_define_space(dev, INDEX1, perm, 2 * sizeof(uint32_t)));
+	TPM_CHECK(tpm_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t)));
 
 	/* Sets the global lock */
-	tpm_set_global_lock();
+	tpm_set_global_lock(dev);
 
 	/* Verifies that index0 cannot be redefined */
-	result = tpm_nv_define_space(INDEX0, perm, sizeof(uint32_t));
+	result = tpm_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t));
 	assert(result == TPM_AREA_LOCKED);
 
 	/* Checks that index1 can */
-	TPM_CHECK(tpm_nv_define_space(INDEX1, perm, 2 * sizeof(uint32_t)));
-	TPM_CHECK(tpm_nv_define_space(INDEX1, perm, sizeof(uint32_t)));
+	TPM_CHECK(tpm_nv_define_space(dev, INDEX1, perm, 2 * sizeof(uint32_t)));
+	TPM_CHECK(tpm_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t)));
 
 	/* Turns off PP */
-	tpm_tsc_physical_presence(PHYS_PRESENCE);
+	tpm_tsc_physical_presence(dev, PHYS_PRESENCE);
 
 	/* Verifies that neither index0 nor index1 can be redefined */
-	result = tpm_nv_define_space(INDEX0, perm, sizeof(uint32_t));
+	result = tpm_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t));
 	assert(result == TPM_BAD_PRESENCE);
-	result = tpm_nv_define_space(INDEX1, perm, sizeof(uint32_t));
+	result = tpm_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t));
 	assert(result == TPM_BAD_PRESENCE);
 
 	printf("done\n");
@@ -350,38 +357,39 @@
 #define PERMPPGL (TPM_NV_PER_PPWRITE | TPM_NV_PER_GLOBALLOCK)
 #define PERMPP TPM_NV_PER_PPWRITE
 
-static int test_space_perm(void)
+static int test_space_perm(struct udevice *dev)
 {
 	uint32_t perm;
 
 	printf("Testing spaceperm ...");
-	tpm_init();
-	TPM_CHECK(TlclStartupIfNeeded());
-	TPM_CHECK(tpm_continue_self_test());
-	TPM_CHECK(tpm_tsc_physical_presence(PRESENCE));
-	TPM_CHECK(tpm_get_permissions(INDEX0, &perm));
+	tpm_init(dev);
+	TPM_CHECK(TlclStartupIfNeeded(dev));
+	TPM_CHECK(tpm_continue_self_test(dev));
+	TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
+	TPM_CHECK(tpm_get_permissions(dev, INDEX0, &perm));
 	assert((perm & PERMPPGL) == PERMPPGL);
-	TPM_CHECK(tpm_get_permissions(INDEX1, &perm));
+	TPM_CHECK(tpm_get_permissions(dev, INDEX1, &perm));
 	assert((perm & PERMPP) == PERMPP);
 	printf("done\n");
 	return 0;
 }
 
-static int test_startup(void)
+static int test_startup(struct udevice *dev)
 {
 	uint32_t result;
+
 	printf("Testing startup ...\n");
 
-	tpm_init();
-	result = tpm_startup(TPM_ST_CLEAR);
+	tpm_init(dev);
+	result = tpm_startup(dev, TPM_ST_CLEAR);
 	if (result != 0 && result != TPM_INVALID_POSTINIT)
 		printf("\ttpm startup failed with 0x%x\n", result);
-	result = tpm_get_flags(NULL, NULL, NULL);
+	result = tpm_get_flags(dev, NULL, NULL, NULL);
 	if (result != 0)
 		printf("\ttpm getflags failed with 0x%x\n", result);
 	printf("\texecuting SelfTestFull\n");
-	tpm_self_test_full();
-	result = tpm_get_flags(NULL, NULL, NULL);
+	tpm_self_test_full(dev);
+	result = tpm_get_flags(dev, NULL, NULL, NULL);
 	if (result != 0)
 		printf("\ttpm getflags failed with 0x%x\n", result);
 	printf("\tdone\n");
@@ -410,45 +418,48 @@
 } while (0)
 
 
-static int test_timing(void)
+static int test_timing(struct udevice *dev)
 {
-	uint32_t x;
 	uint8_t in[20], out[20];
+	uint32_t x;
 
 	printf("Testing timing ...");
-	tpm_init();
-	TTPM_CHECK(TlclStartupIfNeeded(), 50);
-	TTPM_CHECK(tpm_continue_self_test(), 100);
-	TTPM_CHECK(tpm_self_test_full(), 1000);
-	TTPM_CHECK(tpm_tsc_physical_presence(PRESENCE), 100);
-	TTPM_CHECK(tpm_nv_write_value(INDEX0, (uint8_t *)&x, sizeof(x)), 100);
-	TTPM_CHECK(tpm_nv_read_value(INDEX0, (uint8_t *)&x, sizeof(x)), 100);
-	TTPM_CHECK(tpm_extend(0, in, out), 200);
-	TTPM_CHECK(tpm_set_global_lock(), 50);
-	TTPM_CHECK(tpm_tsc_physical_presence(PHYS_PRESENCE), 100);
+	tpm_init(dev);
+	TTPM_CHECK(TlclStartupIfNeeded(dev), 50);
+	TTPM_CHECK(tpm_continue_self_test(dev), 100);
+	TTPM_CHECK(tpm_self_test_full(dev), 1000);
+	TTPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE), 100);
+	TTPM_CHECK(tpm_nv_write_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)),
+		   100);
+	TTPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)),
+		   100);
+	TTPM_CHECK(tpm_extend(dev, 0, in, out), 200);
+	TTPM_CHECK(tpm_set_global_lock(dev), 50);
+	TTPM_CHECK(tpm_tsc_physical_presence(dev, PHYS_PRESENCE), 100);
 	printf("done\n");
 	return 0;
 }
 
 #define TPM_MAX_NV_WRITES_NOOWNER 64
 
-static int test_write_limit(void)
+static int test_write_limit(struct udevice *dev)
 {
-	printf("Testing writelimit ...\n");
-	int i;
 	uint32_t result;
+	int i;
 
-	tpm_init();
-	TPM_CHECK(TlclStartupIfNeeded());
-	TPM_CHECK(tpm_self_test_full());
-	TPM_CHECK(tpm_tsc_physical_presence(PRESENCE));
-	TPM_CHECK(tpm_force_clear());
-	TPM_CHECK(tpm_physical_enable());
-	TPM_CHECK(tpm_physical_set_deactivated(0));
+	printf("Testing writelimit ...\n");
+	tpm_init(dev);
+	TPM_CHECK(TlclStartupIfNeeded(dev));
+	TPM_CHECK(tpm_self_test_full(dev));
+	TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
+	TPM_CHECK(tpm_force_clear(dev));
+	TPM_CHECK(tpm_physical_enable(dev));
+	TPM_CHECK(tpm_physical_set_deactivated(dev, 0));
 
 	for (i = 0; i < TPM_MAX_NV_WRITES_NOOWNER + 2; i++) {
 		printf("\twriting %d\n", i);
-		result = tpm_nv_write_value(INDEX0, (uint8_t *)&i, sizeof(i));
+		result = tpm_nv_write_value(dev, INDEX0, (uint8_t *)&i,
+					    sizeof(i));
 		switch (result) {
 		case TPM_SUCCESS:
 			break;
@@ -461,12 +472,12 @@
 	}
 
 	/* Reset write count */
-	TPM_CHECK(tpm_force_clear());
-	TPM_CHECK(tpm_physical_enable());
-	TPM_CHECK(tpm_physical_set_deactivated(0));
+	TPM_CHECK(tpm_force_clear(dev));
+	TPM_CHECK(tpm_physical_enable(dev));
+	TPM_CHECK(tpm_physical_set_deactivated(dev, 0));
 
 	/* Try writing again. */
-	TPM_CHECK(tpm_nv_write_value(INDEX0, (uint8_t *)&i, sizeof(i)));
+	TPM_CHECK(tpm_nv_write_value(dev, INDEX0, (uint8_t *)&i, sizeof(i)));
 	printf("\tdone\n");
 	return 0;
 }
@@ -475,7 +486,13 @@
 	int do_test_##XFUNC(cmd_tbl_t *cmd_tbl, int flag, int argc, \
 	char * const argv[]) \
 	{ \
-		return test_##XFUNC(); \
+		struct udevice *dev; \
+		int ret; \
+\
+		ret = get_tpm(&dev); \
+		if (ret) \
+			return ret; \
+		return test_##XFUNC(dev); \
 	}
 
 #define VOIDENT(XNAME) \
diff --git a/common/Kconfig b/common/Kconfig
index d7300c2..57bd16d 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -27,6 +27,15 @@
 	  information when SPL finishes and load it when U-Boot proper starts
 	  up.
 
+config TPL_BOOTSTAGE
+	bool "Boot timing and reported in TPL"
+	depends on BOOTSTAGE
+	help
+	  Enable recording of boot time in SPL. To make this visible to U-Boot
+	  proper, enable BOOTSTAGE_STASH as well. This will stash the timing
+	  information when TPL finishes and load it when U-Boot proper starts
+	  up.
+
 config BOOTSTAGE_REPORT
 	bool "Display a detailed boot timing report before booting the OS"
 	depends on BOOTSTAGE
@@ -290,6 +299,10 @@
 	int
 	default LOGLEVEL
 
+config TPL_LOGLEVEL
+	int
+	default LOGLEVEL
+
 config SILENT_CONSOLE
 	bool "Support a silent console"
 	help
@@ -444,12 +457,22 @@
 
 config SPL_LOG
 	bool "Enable logging support in SPL"
+	depends on LOG
 	help
 	  This enables support for logging of status and debug messages. These
 	  can be displayed on the console, recorded in a memory buffer, or
 	  discarded if not needed. Logging supports various categories and
 	  levels of severity.
 
+config TPL_LOG
+	bool "Enable logging support in TPL"
+	depends on LOG
+	help
+	  This enables support for logging of status and debug messages. These
+	  can be displayed on the console, recorded in a memory buffer, or
+	  discarded if not needed. Logging supports various categories and
+	  levels of severity.
+
 config LOG_MAX_LEVEL
 	int "Maximum log level to record"
 	depends on LOG
@@ -486,6 +509,24 @@
 	    6 - detail
 	    7 - debug
 
+config TPL_LOG_MAX_LEVEL
+	int "Maximum log level to record in TPL"
+	depends on TPL_LOG
+	default 3
+	help
+	  This selects the maximum log level that will be recorded. Any value
+	  higher than this will be ignored. If possible log statements below
+	  this level will be discarded at build time. Levels:
+
+	    0 - panic
+	    1 - critical
+	    2 - error
+	    3 - warning
+	    4 - note
+	    5 - info
+	    6 - detail
+	    7 - debug
+
 config LOG_CONSOLE
 	bool "Allow log output to the console"
 	depends on LOG
@@ -496,9 +537,9 @@
 	  log message is shown - other details like level, category, file and
 	  line number are omitted.
 
-config LOG_SPL_CONSOLE
+config SPL_LOG_CONSOLE
 	bool "Allow log output to the console in SPL"
-	depends on LOG_SPL
+	depends on SPL_LOG
 	default y
 	help
 	  Enables a log driver which writes log records to the console.
@@ -506,6 +547,16 @@
 	  log message is shown - other details like level, category, file and
 	  line number are omitted.
 
+config TPL_LOG_CONSOLE
+	bool "Allow log output to the console in SPL"
+	depends on TPL_LOG
+	default y
+	help
+	  Enables a log driver which writes log records to the console.
+	  Generally the console is the serial port or LCD display. Only the
+	  log message is shown - other details like level, category, file and
+	  line number are omitted.
+
 config LOG_TEST
 	bool "Provide a test for logging"
 	depends on LOG
@@ -660,6 +711,22 @@
 	    * Helpers to access MMC, similar to drivers/fastboot/fb_mmc.c.
 	    * Helpers to alloc/init/free avb ops.
 
+config SPL_HASH
+	bool # "Support hashing API (SHA1, SHA256, etc.)"
+	help
+	  This provides a way to hash data in memory using various supported
+	  algorithms (such as SHA1, MD5, CRC32). The API is defined in hash.h
+	  and the algorithms it supports are defined in common/hash.c. See
+	  also CMD_HASH for command-line access.
+
+config TPL_HASH
+	bool # "Support hashing API (SHA1, SHA256, etc.)"
+	help
+	  This provides a way to hash data in memory using various supported
+	  algorithms (such as SHA1, MD5, CRC32). The API is defined in hash.h
+	  and the algorithms it supports are defined in common/hash.c. See
+	  also CMD_HASH for command-line access.
+
 endmenu
 
 menu "Update support"
@@ -683,4 +750,52 @@
 
 endmenu
 
+menu "Blob list"
+
+config BLOBLIST
+	bool "Support for a bloblist"
+	help
+	  This enables support for a bloblist in U-Boot, which can be passed
+	  from TPL to SPL to U-Boot proper (and potentially to Linux). The
+	  blob list supports multiple binary blobs of data, each with a tag,
+	  so that different U-Boot components can store data which can survive
+	  through to the next stage of the boot.
+
+config SPL_BLOBLIST
+	bool "Support for a bloblist in SPL"
+	depends on BLOBLIST
+	default y if SPL
+	help
+	  This enables a bloblist in SPL. If this is the first part of U-Boot
+	  to run, then the bloblist is set up in SPL and passed to U-Boot
+	  proper. If TPL also has a bloblist, then SPL uses the one from there.
+
+config TPL_BLOBLIST
+	bool "Support for a bloblist in TPL"
+	depends on BLOBLIST
+	default y if TPL
+	help
+	  This enables a bloblist in TPL. The bloblist is set up in TPL and
+	  passed to SPL and U-Boot proper.
+
+config BLOBLIST_SIZE
+	hex "Size of bloblist"
+	depends on BLOBLIST
+	default 0x400
+	help
+	  Sets the size of the bloblist in bytes. This must include all
+	  overhead (alignment, bloblist header, record header). The bloblist
+	  is set up in the first part of U-Boot to run (TPL, SPL or U-Boot
+	  proper), and this sane bloblist is used for subsequent stages.
+
+config BLOBLIST_ADDR
+	hex "Address of bloblist"
+	depends on BLOBLIST
+	default 0xe000 if SANDBOX
+	help
+	  Sets the address of the bloblist, set up by the first part of U-Boot
+	  which runs. Subsequent U-Boot stages typically use the same address.
+
+endmenu
+
 source "common/spl/Kconfig"
diff --git a/common/Makefile b/common/Makefile
index a238836..65d89dc 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -33,7 +33,7 @@
 obj-$(CONFIG_CMD_MII) += miiphyutil.o
 obj-$(CONFIG_PHYLIB) += miiphyutil.o
 
-ifdef CONFIG_CMD_USB
+ifdef CONFIG_USB
 obj-y += usb.o usb_hub.o
 obj-$(CONFIG_USB_STORAGE) += usb_storage.o
 endif
@@ -61,6 +61,7 @@
 endif # !CONFIG_SPL_BUILD
 
 obj-$(CONFIG_$(SPL_TPL_)BOOTSTAGE) += bootstage.o
+obj-$(CONFIG_$(SPL_TPL_)BLOBLIST) += bloblist.o
 
 ifdef CONFIG_SPL_BUILD
 ifdef CONFIG_SPL_DFU_SUPPORT
@@ -68,6 +69,7 @@
 endif
 obj-$(CONFIG_SPL_DFU_SUPPORT) += cli_hush.o
 obj-$(CONFIG_SPL_HASH_SUPPORT) += hash.o
+obj-$(CONFIG_TPL_HASH_SUPPORT) += hash.o
 obj-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o
 obj-$(CONFIG_SPL_LOAD_FIT) += common_fit.o
 obj-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o
@@ -76,7 +78,8 @@
 obj-$(CONFIG_SPL_USB_SUPPORT) += usb.o usb_hub.o
 obj-$(CONFIG_USB_STORAGE) += usb_storage.o
 endif
-endif
+endif # CONFIG_SPL_BUILD
+
 #others
 obj-$(CONFIG_DDR_SPD) += ddr_spd.o
 obj-$(CONFIG_SPD_EEPROM) += ddr_spd.o
@@ -90,14 +93,16 @@
 endif
 else
 obj-y += console.o
-endif
+endif # CONFIG_SPL_BUILD
+
 obj-$(CONFIG_CROS_EC) += cros_ec.o
 obj-y += dlmalloc.o
 ifdef CONFIG_SYS_MALLOC_F
-ifneq ($(CONFIG_$(SPL_)SYS_MALLOC_F_LEN),0)
+ifneq ($(CONFIG_$(SPL_TPL_)SYS_MALLOC_F_LEN),0)
 obj-y += malloc_simple.o
 endif
 endif
+
 obj-y += image.o
 obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o
 obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o
@@ -118,8 +123,8 @@
 obj-$(CONFIG_FSL_DDR_INTERACTIVE) += cli_simple.o cli_readline.o
 obj-$(CONFIG_DFU_OVER_USB) += dfu.o
 obj-y += command.o
-obj-$(CONFIG_$(SPL_)LOG) += log.o
-obj-$(CONFIG_$(SPL_)LOG_CONSOLE) += log_console.o
+obj-$(CONFIG_$(SPL_TPL_)LOG) += log.o
+obj-$(CONFIG_$(SPL_TPL_)LOG_CONSOLE) += log_console.o
 obj-y += s_record.o
 obj-$(CONFIG_CMD_LOADB) += xyzModem.o
 obj-$(CONFIG_$(SPL_TPL_)YMODEM_SUPPORT) += xyzModem.o
diff --git a/common/bloblist.c b/common/bloblist.c
new file mode 100644
index 0000000..b4cf169
--- /dev/null
+++ b/common/bloblist.c
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <bloblist.h>
+#include <log.h>
+#include <mapmem.h>
+#include <spl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct bloblist_rec *bloblist_first_blob(struct bloblist_hdr *hdr)
+{
+	if (hdr->alloced <= hdr->hdr_size)
+		return NULL;
+	return (struct bloblist_rec *)((void *)hdr + hdr->hdr_size);
+}
+
+struct bloblist_rec *bloblist_next_blob(struct bloblist_hdr *hdr,
+					struct bloblist_rec *rec)
+{
+	ulong offset;
+
+	offset = (void *)rec - (void *)hdr;
+	offset += rec->hdr_size + ALIGN(rec->size, BLOBLIST_ALIGN);
+	if (offset >= hdr->alloced)
+		return NULL;
+	return (struct bloblist_rec *)((void *)hdr + offset);
+}
+
+#define foreach_rec(_rec, _hdr) \
+	for (_rec = bloblist_first_blob(_hdr); \
+	     _rec; \
+	     _rec = bloblist_next_blob(_hdr, _rec))
+
+static struct bloblist_rec *bloblist_findrec(uint tag)
+{
+	struct bloblist_hdr *hdr = gd->bloblist;
+	struct bloblist_rec *rec;
+
+	if (!hdr)
+		return NULL;
+
+	foreach_rec(rec, hdr) {
+		if (rec->tag == tag)
+			return rec;
+	}
+
+	return NULL;
+}
+
+static int bloblist_addrec(uint tag, int size, struct bloblist_rec **recp)
+{
+	struct bloblist_hdr *hdr = gd->bloblist;
+	struct bloblist_rec *rec;
+	int new_alloced;
+
+	new_alloced = hdr->alloced + sizeof(*rec) +
+			ALIGN(size, BLOBLIST_ALIGN);
+	if (new_alloced >= hdr->size) {
+		log(LOGC_BLOBLIST, LOGL_ERR,
+		    "Failed to allocate %x bytes size=%x, need size>=%x\n",
+		    size, hdr->size, new_alloced);
+		return log_msg_ret("bloblist add", -ENOSPC);
+	}
+	rec = (void *)hdr + hdr->alloced;
+	hdr->alloced = new_alloced;
+
+	rec->tag = tag;
+	rec->hdr_size = sizeof(*rec);
+	rec->size = size;
+	rec->spare = 0;
+	*recp = rec;
+
+	return 0;
+}
+
+static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size)
+{
+	struct bloblist_rec *rec;
+
+	rec = bloblist_findrec(tag);
+	if (rec) {
+		if (size && size != rec->size)
+			return -ESPIPE;
+	} else {
+		int ret;
+
+		ret = bloblist_addrec(tag, size, &rec);
+		if (ret)
+			return ret;
+	}
+	*recp = rec;
+
+	return 0;
+}
+
+void *bloblist_find(uint tag, int size)
+{
+	struct bloblist_rec *rec;
+
+	rec = bloblist_findrec(tag);
+	if (!rec)
+		return NULL;
+	if (size && size != rec->size)
+		return NULL;
+
+	return (void *)rec + rec->hdr_size;
+}
+
+void *bloblist_add(uint tag, int size)
+{
+	struct bloblist_rec *rec;
+
+	if (bloblist_addrec(tag, size, &rec))
+		return NULL;
+
+	return rec + 1;
+}
+
+int bloblist_ensure_size(uint tag, int size, void **blobp)
+{
+	struct bloblist_rec *rec;
+	int ret;
+
+	ret = bloblist_ensurerec(tag, &rec, size);
+	if (ret)
+		return ret;
+	*blobp = (void *)rec + rec->hdr_size;
+
+	return 0;
+}
+
+void *bloblist_ensure(uint tag, int size)
+{
+	struct bloblist_rec *rec;
+
+	if (bloblist_ensurerec(tag, &rec, size))
+		return NULL;
+
+	return (void *)rec + rec->hdr_size;
+}
+
+static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr)
+{
+	struct bloblist_rec *rec;
+	u32 chksum;
+
+	chksum = crc32(0, (unsigned char *)hdr,
+		       offsetof(struct bloblist_hdr, chksum));
+	foreach_rec(rec, hdr) {
+		chksum = crc32(chksum, (void *)rec, rec->hdr_size);
+		chksum = crc32(chksum, (void *)rec + rec->hdr_size, rec->size);
+	}
+
+	return chksum;
+}
+
+int bloblist_new(ulong addr, uint size, uint flags)
+{
+	struct bloblist_hdr *hdr;
+
+	if (size < sizeof(*hdr))
+		return log_ret(-ENOSPC);
+	if (addr & (BLOBLIST_ALIGN - 1))
+		return log_ret(-EFAULT);
+	hdr = map_sysmem(addr, size);
+	memset(hdr, '\0', sizeof(*hdr));
+	hdr->version = BLOBLIST_VERSION;
+	hdr->hdr_size = sizeof(*hdr);
+	hdr->flags = flags;
+	hdr->magic = BLOBLIST_MAGIC;
+	hdr->size = size;
+	hdr->alloced = hdr->hdr_size;
+	hdr->chksum = 0;
+	gd->bloblist = hdr;
+
+	return 0;
+}
+
+int bloblist_check(ulong addr, uint size)
+{
+	struct bloblist_hdr *hdr;
+	u32 chksum;
+
+	hdr = map_sysmem(addr, sizeof(*hdr));
+	if (hdr->magic != BLOBLIST_MAGIC)
+		return log_msg_ret("Bad magic", -ENOENT);
+	if (hdr->version != BLOBLIST_VERSION)
+		return log_msg_ret("Bad version", -EPROTONOSUPPORT);
+	if (size && hdr->size != size)
+		return log_msg_ret("Bad size", -EFBIG);
+	chksum = bloblist_calc_chksum(hdr);
+	if (hdr->chksum != chksum) {
+		log(LOGC_BLOBLIST, LOGL_ERR, "Checksum %x != %x\n", hdr->chksum,
+		    chksum);
+		return log_msg_ret("Bad checksum", -EIO);
+	}
+	gd->bloblist = hdr;
+
+	return 0;
+}
+
+int bloblist_finish(void)
+{
+	struct bloblist_hdr *hdr = gd->bloblist;
+
+	hdr->chksum = bloblist_calc_chksum(hdr);
+
+	return 0;
+}
+
+int bloblist_init(void)
+{
+	bool expected;
+	int ret = -ENOENT;
+
+	/**
+	 * Wed expect to find an existing bloblist in the first phase of U-Boot
+	 * that runs
+	 */
+	expected = !u_boot_first_phase();
+	if (expected)
+		ret = bloblist_check(CONFIG_BLOBLIST_ADDR,
+				     CONFIG_BLOBLIST_SIZE);
+	if (ret) {
+		log(LOGC_BLOBLIST, expected ? LOGL_WARNING : LOGL_DEBUG,
+		    "Existing bloblist not found: creating new bloblist\n");
+		ret = bloblist_new(CONFIG_BLOBLIST_ADDR, CONFIG_BLOBLIST_SIZE,
+				   0);
+	} else {
+		log(LOGC_BLOBLIST, LOGL_DEBUG, "Found existing bloblist\n");
+	}
+
+	return ret;
+}
diff --git a/common/board_f.c b/common/board_f.c
index a3e80ca..149a722 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -10,6 +10,7 @@
  */
 
 #include <common.h>
+#include <bloblist.h>
 #include <console.h>
 #include <cpu.h>
 #include <dm.h>
@@ -23,6 +24,9 @@
 #include <os.h>
 #include <post.h>
 #include <relocate.h>
+#ifdef CONFIG_SPL
+#include <spl.h>
+#endif
 #include <status_led.h>
 #include <sysreset.h>
 #include <timer.h>
@@ -271,6 +275,17 @@
 	/* TODO: use (ulong)&__bss_end - (ulong)&__text_start; ? */
 	gd->mon_len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE;
 #endif
+	return 0;
+}
+
+static int setup_spl_handoff(void)
+{
+#if CONFIG_IS_ENABLED(HANDOFF)
+	gd->spl_handoff = bloblist_find(BLOBLISTT_SPL_HANDOFF,
+					sizeof(struct spl_handoff));
+	debug("Found SPL hand-off info %p\n", gd->spl_handoff);
+#endif
+
 	return 0;
 }
 
@@ -549,6 +564,16 @@
 	return arch_reserve_stacks();
 }
 
+static int reserve_bloblist(void)
+{
+#ifdef CONFIG_BLOBLIST
+	gd->start_addr_sp -= CONFIG_BLOBLIST_SIZE;
+	gd->new_bloblist = map_sysmem(gd->start_addr_sp, CONFIG_BLOBLIST_SIZE);
+#endif
+
+	return 0;
+}
+
 static int display_new_sp(void)
 {
 	debug("New Stack Pointer is: %08lx\n", gd->start_addr_sp);
@@ -655,6 +680,24 @@
 	return 0;
 }
 
+static int reloc_bloblist(void)
+{
+#ifdef CONFIG_BLOBLIST
+	if (gd->flags & GD_FLG_SKIP_RELOC)
+		return 0;
+	if (gd->new_bloblist) {
+		int size = CONFIG_BLOBLIST_SIZE;
+
+		debug("Copying bloblist from %p to %p, size %x\n",
+		      gd->bloblist, gd->new_bloblist, size);
+		memcpy(gd->new_bloblist, gd->bloblist, size);
+		gd->bloblist = gd->new_bloblist;
+	}
+#endif
+
+	return 0;
+}
+
 static int setup_reloc(void)
 {
 	if (gd->flags & GD_FLG_SKIP_RELOC) {
@@ -802,6 +845,10 @@
 	initf_malloc,
 	log_init,
 	initf_bootstage,	/* uses its own timer, so does not need DM */
+#ifdef CONFIG_BLOBLIST
+	bloblist_init,
+#endif
+	setup_spl_handoff,
 	initf_console_record,
 #if defined(CONFIG_HAVE_FSP)
 	arch_fsp_init,
@@ -899,6 +946,7 @@
 	reserve_global_data,
 	reserve_fdt,
 	reserve_bootstage,
+	reserve_bloblist,
 	reserve_arch,
 	reserve_stacks,
 	dram_init_banksize,
@@ -918,6 +966,7 @@
 	INIT_FUNC_WATCHDOG_RESET
 	reloc_fdt,
 	reloc_bootstage,
+	reloc_bloblist,
 	setup_reloc,
 #if defined(CONFIG_X86) || defined(CONFIG_ARC)
 	copy_uboot_to_ram,
diff --git a/common/board_r.c b/common/board_r.c
index 2f982b1..5f3d27a 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -438,7 +438,8 @@
 	else
 		set_default_env(NULL, 0);
 #ifdef CONFIG_OF_CONTROL
-	env_set_addr("fdtcontroladdr", gd->fdt_blob);
+	env_set_hex("fdtcontroladdr",
+		    (unsigned long)map_to_sysmem(gd->fdt_blob));
 #endif
 
 	/* Initialize from environment */
diff --git a/common/console.c b/common/console.c
index 9a94f32..0b0dd76 100644
--- a/common/console.c
+++ b/common/console.c
@@ -535,6 +535,13 @@
 
 void puts(const char *s)
 {
+#ifdef CONFIG_SANDBOX
+	/* sandbox can send characters to stdout before it has a console */
+	if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
+		os_puts(s);
+		return;
+	}
+#endif
 #ifdef CONFIG_DEBUG_UART
 	if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
 		while (*s) {
diff --git a/common/cros_ec.c b/common/cros_ec.c
index 4ca15e1..e66471e 100644
--- a/common/cros_ec.c
+++ b/common/cros_ec.c
@@ -25,15 +25,3 @@
 	}
 	return dev;
 }
-
-int cros_ec_get_error(void)
-{
-	struct udevice *dev;
-	int ret;
-
-	ret = uclass_get_device(UCLASS_CROS_EC, 0, &dev);
-	if (ret && ret != -ENODEV)
-		return ret;
-
-	return 0;
-}
diff --git a/common/fdt_support.c b/common/fdt_support.c
index e6daa67..3440e42 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -7,6 +7,7 @@
  */
 
 #include <common.h>
+#include <mapmem.h>
 #include <stdio_dev.h>
 #include <linux/ctype.h>
 #include <linux/types.h>
@@ -633,7 +634,7 @@
 	fdt_set_totalsize(blob, actualsize);
 
 	/* Add the new reservation */
-	ret = fdt_add_mem_rsv(blob, (uintptr_t)blob, actualsize);
+	ret = fdt_add_mem_rsv(blob, map_to_sysmem(blob), actualsize);
 	if (ret < 0)
 		return ret;
 
diff --git a/common/image-fit.c b/common/image-fit.c
index 8d39a24..ac901e1 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -165,6 +165,7 @@
 	uint8_t *value;
 	int value_len;
 	char *algo;
+	const char *padding;
 	int required;
 	int ret, i;
 
@@ -184,6 +185,10 @@
 		printf(" (required)");
 	printf("\n");
 
+	padding = fdt_getprop(fit, noffset, "padding", NULL);
+	if (padding)
+		printf("%s  %s padding: %s\n", p, type, padding);
+
 	ret = fit_image_hash_get_value(fit, noffset, &value,
 				       &value_len);
 	printf("%s  %s value:   ", p, type);
diff --git a/common/image-sig.c b/common/image-sig.c
index 5d860e1..4f6b4ec 100644
--- a/common/image-sig.c
+++ b/common/image-sig.c
@@ -71,6 +71,19 @@
 
 };
 
+struct padding_algo padding_algos[] = {
+	{
+		.name = "pkcs-1.5",
+		.verify = padding_pkcs_15_verify,
+	},
+#ifdef CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT
+	{
+		.name = "pss",
+		.verify = padding_pss_verify,
+	}
+#endif /* CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT */
+};
+
 struct checksum_algo *image_get_checksum_algo(const char *full_name)
 {
 	int i;
@@ -106,6 +119,21 @@
 	return NULL;
 }
 
+struct padding_algo *image_get_padding_algo(const char *name)
+{
+	int i;
+
+	if (!name)
+		return NULL;
+
+	for (i = 0; i < ARRAY_SIZE(padding_algos); i++) {
+		if (!strcmp(padding_algos[i].name, name))
+			return &padding_algos[i];
+	}
+
+	return NULL;
+}
+
 /**
  * fit_region_make_list() - Make a list of image regions
  *
@@ -155,6 +183,7 @@
 		char **err_msgp)
 {
 	char *algo_name;
+	const char *padding_name;
 
 	if (fdt_totalsize(fit) > CONFIG_FIT_SIGNATURE_MAX_SIZE) {
 		*err_msgp = "Total size too large";
@@ -165,6 +194,11 @@
 		*err_msgp = "Can't get hash algo property";
 		return -1;
 	}
+
+	padding_name = fdt_getprop(fit, noffset, "padding", NULL);
+	if (!padding_name)
+		padding_name = RSA_DEFAULT_PADDING_NAME;
+
 	memset(info, '\0', sizeof(*info));
 	info->keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
 	info->fit = (void *)fit;
@@ -172,6 +206,7 @@
 	info->name = algo_name;
 	info->checksum = image_get_checksum_algo(algo_name);
 	info->crypto = image_get_crypto_algo(algo_name);
+	info->padding = image_get_padding_algo(padding_name);
 	info->fdt_blob = gd_fdt_blob();
 	info->required_keynode = required_keynode;
 	printf("%s:%s", algo_name, info->keyname);
diff --git a/common/image.c b/common/image.c
index 1c3a772..0659133 100644
--- a/common/image.c
+++ b/common/image.c
@@ -166,6 +166,7 @@
 	{	IH_TYPE_FIRMWARE_IVT, "firmware_ivt", "Firmware with HABv4 IVT" },
 	{       IH_TYPE_PMMC,        "pmmc",        "TI Power Management Micro-Controller Firmware",},
 	{	IH_TYPE_STM32IMAGE, "stm32image", "STMicroelectronics STM32 Image" },
+	{	IH_TYPE_MTKIMAGE,   "mtk_image",   "MediaTek BootROM loadable Image" },
 	{	-1,		    "",		  "",			},
 };
 
diff --git a/common/init/Makefile b/common/init/Makefile
index 4902635..853b56d 100644
--- a/common/init/Makefile
+++ b/common/init/Makefile
@@ -5,3 +5,4 @@
 #
 
 obj-y += board_init.o
+obj-$(CONFIG_$(SPL_TPL_)HANDOFF) += handoff.o
diff --git a/common/init/handoff.c b/common/init/handoff.c
new file mode 100644
index 0000000..e00b43e
--- /dev/null
+++ b/common/init/handoff.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Passing basic information from SPL to U-Boot proper
+ *
+ * Copyright 2018 Google, Inc
+ */
+
+#include <common.h>
+#include <handoff.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void handoff_save_dram(struct spl_handoff *ho)
+{
+	ho->ram_size = gd->ram_size;
+#ifdef CONFIG_NR_DRAM_BANKS
+	{
+		struct bd_info *bd = gd->bd;
+		int i;
+
+		for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+			ho->ram_bank[i].start = bd->bi_dram[i].start;
+			ho->ram_bank[i].size = bd->bi_dram[i].size;
+		}
+	}
+#endif
+}
+
+void handoff_load_dram_size(struct spl_handoff *ho)
+{
+	gd->ram_size = ho->ram_size;
+}
+
+void handoff_load_dram_banks(struct spl_handoff *ho)
+{
+#ifdef CONFIG_NR_DRAM_BANKS
+	{
+		struct bd_info *bd = gd->bd;
+		int i;
+
+		for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+			bd->bi_dram[i].start = ho->ram_bank[i].start;
+			bd->bi_dram[i].size = ho->ram_bank[i].size;
+		}
+	}
+#endif
+}
diff --git a/common/lcd.c b/common/lcd.c
index 2e2bef3..cd63040 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -242,14 +242,6 @@
 	lcd_sync();
 }
 
-static int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc,
-			char *const argv[])
-{
-	lcd_clear();
-	return 0;
-}
-U_BOOT_CMD(cls,	1, 1, do_lcd_clear, "clear screen", "");
-
 static int lcd_init(void *lcdbase)
 {
 	debug("[LCD] Initializing LCD frambuffer at %p\n", lcdbase);
@@ -389,7 +381,6 @@
 
 #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
 #ifdef CONFIG_SPLASH_SCREEN_ALIGN
-#define BMP_ALIGN_CENTER	0x7FFF
 
 static void splash_align_axis(int *axis, unsigned long panel_size,
 					unsigned long picture_size)
diff --git a/common/malloc_simple.c b/common/malloc_simple.c
index 871b544..eabbb70 100644
--- a/common/malloc_simple.c
+++ b/common/malloc_simple.c
@@ -5,6 +5,8 @@
  * Copyright (c) 2014 Google, Inc
  */
 
+#define LOG_CATEGORY LOGC_ALLOC
+
 #include <common.h>
 #include <malloc.h>
 #include <mapmem.h>
@@ -12,40 +14,47 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-void *malloc_simple(size_t bytes)
+static void *alloc_simple(size_t bytes, int align)
 {
-	ulong new_ptr;
+	ulong addr, new_ptr;
 	void *ptr;
 
-	new_ptr = gd->malloc_ptr + bytes;
-	debug("%s: size=%zx, ptr=%lx, limit=%lx: ", __func__, bytes, new_ptr,
-	      gd->malloc_limit);
+	addr = ALIGN(gd->malloc_base + gd->malloc_ptr, align);
+	new_ptr = addr + bytes - gd->malloc_base;
+	log_debug("size=%zx, ptr=%lx, limit=%lx: ", bytes, new_ptr,
+		  gd->malloc_limit);
 	if (new_ptr > gd->malloc_limit) {
-		debug("space exhausted\n");
+		log_err("alloc space exhausted\n");
 		return NULL;
 	}
-	ptr = map_sysmem(gd->malloc_base + gd->malloc_ptr, bytes);
+
+	ptr = map_sysmem(addr, bytes);
 	gd->malloc_ptr = ALIGN(new_ptr, sizeof(new_ptr));
-	debug("%lx\n", (ulong)ptr);
 
 	return ptr;
 }
 
-void *memalign_simple(size_t align, size_t bytes)
+void *malloc_simple(size_t bytes)
 {
-	ulong addr, new_ptr;
 	void *ptr;
 
-	addr = ALIGN(gd->malloc_base + gd->malloc_ptr, align);
-	new_ptr = addr + bytes - gd->malloc_base;
-	if (new_ptr > gd->malloc_limit) {
-		debug("space exhausted\n");
-		return NULL;
-	}
+	ptr = alloc_simple(bytes, 1);
+	if (!ptr)
+		return ptr;
 
-	ptr = map_sysmem(addr, bytes);
-	gd->malloc_ptr = ALIGN(new_ptr, sizeof(new_ptr));
-	debug("%lx\n", (ulong)ptr);
+	log_debug("%lx\n", (ulong)ptr);
+
+	return ptr;
+}
+
+void *memalign_simple(size_t align, size_t bytes)
+{
+	void *ptr;
+
+	ptr = alloc_simple(bytes, align);
+	if (!ptr)
+		return ptr;
+	log_debug("aligned to %lx\n", (ulong)ptr);
 
 	return ptr;
 }
@@ -57,9 +66,16 @@
 	void *ptr;
 
 	ptr = malloc(size);
-	if (ptr)
-		memset(ptr, '\0', size);
+	if (!ptr)
+		return ptr;
+	memset(ptr, '\0', size);
 
 	return ptr;
 }
 #endif
+
+void malloc_simple_info(void)
+{
+	log_info("malloc_simple: %lx bytes used, %lx remain\n", gd->malloc_ptr,
+		 CONFIG_VAL(SYS_MALLOC_F_LEN) - gd->malloc_ptr);
+}
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index d056462..0ddbffc 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -25,8 +25,28 @@
 	  supports MMC, NAND and YMODEM and other methods loading of U-Boot
 	  and the Linux Kernel.  If unsure, say Y.
 
+config HANDOFF
+	bool "Pass hand-off information from SPL to U-Boot proper"
+	depends on BLOBLIST
+	help
+	  It is useful to be able to pass information from SPL to U-Boot
+	  proper to preserve state that is known in SPL and is needed in U-Boot.
+	  Enable this to locate the handoff information in U-Boot proper, early
+	  in boot. It is available in gd->handoff. The state state is set up
+	  in SPL (or TPL if that is being used).
+
 if SPL
 
+config SPL_HANDOFF
+	bool "Pass hand-off information from SPL to U-Boot proper"
+	depends on HANDOFF
+	default y
+	help
+	  This option enables SPL to write handoff information. This can be
+	  used to pass information like the size of SDRAM from SPL to U-Boot
+	  proper. Also SPL can receive information from TPL in the same place
+	  if that is enabled.
+
 config SPL_LDSCRIPT
 	string "Linker script for the SPL stage"
 	default "arch/$(ARCH)/cpu/u-boot-spl.lds"
@@ -135,12 +155,21 @@
 	  location is used. Normally we put the device tree at the end of BSS
 	  but with this option enabled, it goes at _image_binary_end.
 
+config SPL_BANNER_PRINT
+	bool "Enable output of the SPL banner 'U-Boot SPL ...'"
+	default y
+	help
+	  If this option is enabled, SPL will print the banner with version
+	  info. Disabling this option could be useful to reduce TPL boot time
+	  (e.g. approx. 6 ms faster, when output on i.MX6 with 115200 baud).
+
-config SPL_DISABLE_BANNER_PRINT
-	bool "Disable output of the SPL banner 'U-Boot SPL ...'"
+config TPL_BANNER_PRINT
+	bool "Enable output of the TPL banner 'U-Boot TPL ...'"
+	default y
 	help
 	  If this option is enabled, SPL will not print the banner with version
-	  info. Selecting this option could be useful to reduce SPL boot time
-	  (e.g. approx. 6 ms slower, when output on i.MX6 with 115200 baud).
+	  info. Disabling this option could be useful to reduce SPL boot time
+	  (e.g. approx. 6 ms faster, when output on i.MX6 with 115200 baud).
 
 config SPL_DISPLAY_PRINT
 	bool "Display a board-specific message in SPL"
@@ -295,6 +324,16 @@
 	  this option to build system-specific drivers for hash acceleration
 	  as part of an SPL build.
 
+config TPL_HASH_SUPPORT
+	bool "Support hashing drivers in TPL"
+	select SHA1
+	select SHA256
+	help
+	  Enable hashing drivers in SPL. These drivers can be used to
+	  accelerate secure boot processing in secure applications. Enable
+	  this option to build system-specific drivers for hash acceleration
+	  as part of an SPL build.
+
 config SPL_DMA_SUPPORT
 	bool "Support DMA drivers"
 	help
@@ -376,7 +415,7 @@
 	  within SPL.
 
 config SPL_GPIO_SUPPORT
-	bool "Support GPIO"
+	bool "Support GPIO in SPL"
 	help
 	  Enable support for GPIOs (General-purpose Input/Output) in SPL.
 	  GPIOs allow U-Boot to read the state of an input line (high or
@@ -848,6 +887,16 @@
 
 if TPL
 
+config TPL_HANDOFF
+	bool "Pass hand-off information from TPL to SPL and U-Boot proper"
+	depends on HANDOFF
+	default y
+	help
+	  This option enables TPL to write handoff information. This can be
+	  used to pass information like the size of SDRAM from TPL to U-Boot
+	  proper. The information is also available to SPL if it is useful
+	  there.
+
 config TPL_BOARD_INIT
 	bool "Call board-specific initialization in TPL"
 	help
@@ -928,6 +977,17 @@
 	help
 	  Enable environment support in TPL. See SPL_ENV_SUPPORT for details.
 
+config TPL_GPIO_SUPPORT
+	bool "Support GPIO in TPL"
+	help
+	  Enable support for GPIOs (General-purpose Input/Output) in TPL.
+	  GPIOs allow U-Boot to read the state of an input line (high or
+	  low) and set the state of an output line. This can be used to
+	  drive LEDs, control power to various system parts and read user
+	  input. GPIOs can be useful in TPL to enable a 'sign-of-life' LED,
+	  for example. Enable this option to build the drivers in
+	  drivers/gpio as part of an TPL build.
+
 config TPL_I2C_SUPPORT
 	bool "Support I2C"
 	help
@@ -963,6 +1023,22 @@
 	help
 	  Enable support for NAND in TPL. See SPL_NAND_SUPPORT for details.
 
+config TPL_PCI_SUPPORT
+	bool "Support PCI drivers"
+	help
+	  Enable support for PCI in TPL. For platforms that need PCI to boot,
+	  or must perform some init using PCI in SPL, this provides the
+	  necessary driver support. This enables the drivers in drivers/pci
+	  as part of a TPL build.
+
+config TPL_PCH_SUPPORT
+	bool "Support PCH drivers"
+	help
+	  Enable support for PCH (Platform Controller Hub) devices in TPL.
+	  These are used to set up GPIOs and the SPI peripheral early in
+	  boot. This enables the drivers in drivers/pch as part of a TPL
+	  build.
+
 config TPL_RAM_SUPPORT
 	bool "Support booting from RAM"
 	help
@@ -977,6 +1053,15 @@
 	  be already in memory when TPL takes over, e.g. loaded by the boot
 	  ROM.
 
+config TPL_RTC_SUPPORT
+	bool "Support RTC drivers"
+	help
+	  Enable RTC (Real-time Clock) support in TPL. This includes support
+	  for reading and setting the time. Some RTC devices also have some
+	  non-volatile (battery-backed) memory which is accessible if
+	  needed. This enables the drivers in drivers/rtc as part of an TPL
+	  build.
+
 config TPL_SERIAL_SUPPORT
 	bool "Support serial"
 	select TPL_PRINTF
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 12f9359..35120b6 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -7,8 +7,10 @@
  */
 
 #include <common.h>
+#include <bloblist.h>
 #include <binman_sym.h>
 #include <dm.h>
+#include <handoff.h>
 #include <spl.h>
 #include <asm/u-boot.h>
 #include <nand.h>
@@ -44,6 +46,14 @@
  */
 __weak void show_boot_progress(int val) {}
 
+#if defined(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF)
+/* weak, default platform-specific function to initialize dram banks */
+__weak int dram_init_banksize(void)
+{
+	return 0;
+}
+#endif
+
 /*
  * Default function to determine if u-boot or the OS should
  * be started. This implementation always returns 1.
@@ -57,19 +67,12 @@
 #ifdef CONFIG_SPL_OS_BOOT
 __weak int spl_start_uboot(void)
 {
-	puts("SPL: Please implement spl_start_uboot() for your board\n");
-	puts("SPL: Direct Linux boot not active!\n");
+	puts(SPL_TPL_PROMPT
+	     "Please implement spl_start_uboot() for your board\n");
+	puts(SPL_TPL_PROMPT "Direct Linux boot not active!\n");
 	return 1;
 }
 
-/* weak default platform specific function to initialize
- * dram banks
- */
-__weak int dram_init_banksize(void)
-{
-	return 0;
-}
-
 /*
  * Weak default function for arch specific zImage check. Return zero
  * and fill start and end address if image is recognized.
@@ -100,13 +103,13 @@
 	/* fixup the memory dt node */
 	err = fdt_shrink_to_minimum(fdt_blob, 0);
 	if (err == 0) {
-		printf("spl: fdt_shrink_to_minimum err - %d\n", err);
+		printf(SPL_TPL_PROMPT "fdt_shrink_to_minimum err - %d\n", err);
 		return;
 	}
 
 	err = arch_fixup_fdt(fdt_blob);
 	if (err) {
-		printf("spl: arch_fixup_fdt err - %d\n", err);
+		printf(SPL_TPL_PROMPT "arch_fixup_fdt err - %d\n", err);
 		return;
 	}
 #endif
@@ -185,7 +188,7 @@
 	spl_image->os = IH_OS_U_BOOT;
 	spl_image->name = "U-Boot";
 
-	debug("spl: payload image: %32s load addr: 0x%lx size: %d\n",
+	debug(SPL_TPL_PROMPT "payload image: %32s load addr: 0x%lx size: %d\n",
 	      spl_image->name, spl_image->load_addr, spl_image->size);
 
 #ifdef CONFIG_SPL_FIT_SIGNATURE
@@ -255,7 +258,8 @@
 		}
 		spl_image->os = image_get_os(header);
 		spl_image->name = image_get_name(header);
-		debug("spl: payload image: %32s load addr: 0x%lx size: %d\n",
+		debug(SPL_TPL_PROMPT
+		      "payload image: %32s load addr: 0x%lx size: %d\n",
 		      spl_image->name, spl_image->load_addr, spl_image->size);
 #else
 		/* LEGACY image not supported */
@@ -284,7 +288,8 @@
 			spl_image->load_addr = CONFIG_SYS_LOAD_ADDR;
 			spl_image->entry_point = CONFIG_SYS_LOAD_ADDR;
 			spl_image->size = end - start;
-			debug("spl: payload zImage, load addr: 0x%lx size: %d\n",
+			debug(SPL_TPL_PROMPT
+			      "payload zImage, load addr: 0x%lx size: %d\n",
 			      spl_image->load_addr, spl_image->size);
 			return 0;
 		}
@@ -315,6 +320,44 @@
 	debug("image entry point: 0x%lx\n", spl_image->entry_point);
 	image_entry();
 }
+
+#if CONFIG_IS_ENABLED(HANDOFF)
+/**
+ * Set up the SPL hand-off information
+ *
+ * This is initially empty (zero) but can be written by
+ */
+static int setup_spl_handoff(void)
+{
+	struct spl_handoff *ho;
+
+	ho = bloblist_ensure(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff));
+	if (!ho)
+		return -ENOENT;
+
+	return 0;
+}
+
+static int write_spl_handoff(void)
+{
+	struct spl_handoff *ho;
+
+	ho = bloblist_find(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff));
+	if (!ho)
+		return -ENOENT;
+	handoff_save_dram(ho);
+#ifdef CONFIG_SANDBOX
+	ho->arch.magic = TEST_HANDOFF_MAGIC;
+#endif
+	debug(SPL_TPL_PROMPT "Wrote SPL handoff\n");
+
+	return 0;
+}
+#else
+static inline int setup_spl_handoff(void) { return 0; }
+static inline int write_spl_handoff(void) { return 0; }
+
+#endif /* HANDOFF */
 
 static int spl_common_init(bool setup_malloc)
 {
@@ -336,6 +379,30 @@
 		return ret;
 	}
 	bootstage_mark_name(BOOTSTAGE_ID_START_SPL, "spl");
+#if CONFIG_IS_ENABLED(LOG)
+	ret = log_init();
+	if (ret) {
+		debug("%s: Failed to set up logging\n", __func__);
+		return ret;
+	}
+#endif
+	if (CONFIG_IS_ENABLED(BLOBLIST)) {
+		ret = bloblist_init();
+		if (ret) {
+			debug("%s: Failed to set up bloblist: ret=%d\n",
+			      __func__, ret);
+			return ret;
+		}
+	}
+	if (CONFIG_IS_ENABLED(HANDOFF)) {
+		int ret;
+
+		ret = setup_spl_handoff();
+		if (ret) {
+			puts(SPL_TPL_PROMPT "Cannot set up SPL handoff\n");
+			hang();
+		}
+	}
 	if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
 		ret = fdtdec_setup();
 		if (ret) {
@@ -359,6 +426,10 @@
 
 void spl_set_bd(void)
 {
+	/*
+	 * NOTE: On some platforms (e.g. x86) bdata may be in flash and not
+	 * writeable.
+	 */
 	if (!gd->bd)
 		gd->bd = &bdata;
 }
@@ -453,7 +524,7 @@
 		if (loader)
 			printf("Trying to boot from %s\n", loader->name);
 		else
-			puts("SPL: Unsupported Boot Device!\n");
+			puts(SPL_TPL_PROMPT "Unsupported Boot Device!\n");
 #endif
 		if (loader && !spl_load_image(spl_image, loader)) {
 			spl_image->boot_device = spl_boot_list[i];
@@ -474,15 +545,12 @@
 		BOOT_DEVICE_NONE,
 	};
 	struct spl_image_info spl_image;
+	int ret;
 
-	debug(">>spl:board_init_r()\n");
+	debug(">>" SPL_TPL_PROMPT "board_init_r()\n");
 
 	spl_set_bd();
 
-#ifdef CONFIG_SPL_OS_BOOT
-	dram_init_banksize();
-#endif
-
 #if defined(CONFIG_SYS_SPL_MALLOC_START)
 	mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START,
 			CONFIG_SYS_SPL_MALLOC_SIZE);
@@ -504,6 +572,9 @@
 	spl_board_init();
 #endif
 
+	if (IS_ENABLED(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF))
+		dram_init_banksize();
+
 	bootcount_inc();
 
 	memset(&spl_image, '\0', sizeof(spl_image));
@@ -515,11 +586,23 @@
 
 	if (boot_from_devices(&spl_image, spl_boot_list,
 			      ARRAY_SIZE(spl_boot_list))) {
-		puts("SPL: failed to boot from all boot devices\n");
+		puts(SPL_TPL_PROMPT "failed to boot from all boot devices\n");
 		hang();
 	}
 
 	spl_perform_fixups(&spl_image);
+	if (CONFIG_IS_ENABLED(HANDOFF)) {
+		ret = write_spl_handoff();
+		if (ret)
+			printf(SPL_TPL_PROMPT
+			       "SPL hand-off write failed (err=%d)\n", ret);
+	}
+	if (CONFIG_IS_ENABLED(BLOBLIST)) {
+		ret = bloblist_finish();
+		if (ret)
+			printf("Warning: Failed to finish bloblist (ret=%d)\n",
+			       ret);
+	}
 
 #ifdef CONFIG_CPU_V7M
 	spl_image.entry_point |= 0x1;
@@ -556,8 +639,6 @@
 	      gd->malloc_ptr / 1024);
 #endif
 #ifdef CONFIG_BOOTSTAGE_STASH
-	int ret;
-
 	bootstage_mark_name(BOOTSTAGE_ID_END_SPL, "end_spl");
 	ret = bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR,
 			      CONFIG_BOOTSTAGE_STASH_SIZE);
@@ -583,9 +664,9 @@
 
 	gd->have_console = 1;
 
-#ifndef CONFIG_SPL_DISABLE_BANNER_PRINT
-	puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
-			U_BOOT_TIME " " U_BOOT_TZ ")\n");
+#if CONFIG_IS_ENABLED(BANNER_PRINT)
+	puts("\nU-Boot " SPL_TPL_NAME " " PLAIN_VERSION " (" U_BOOT_DATE " - "
+	     U_BOOT_TIME " " U_BOOT_TZ ")\n");
 #endif
 #ifdef CONFIG_SPL_DISPLAY_PRINT
 	spl_display_print();
diff --git a/common/usb.c b/common/usb.c
index 78178c5..b70f614 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -42,7 +42,7 @@
 static int asynch_allowed;
 char usb_started; /* flag for the started/stopped USB status */
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 static struct usb_device usb_dev[USB_MAX_DEVICE];
 static int dev_index;
 
@@ -183,7 +183,7 @@
 	asynch_allowed = !disable;
 	return old_value;
 }
-#endif /* !CONFIG_DM_USB */
+#endif /* !CONFIG_IS_ENABLED(DM_USB) */
 
 
 /*-------------------------------------------------------------------
@@ -849,7 +849,7 @@
  * the USB device are static allocated [USB_MAX_DEVICE].
  */
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 
 /* returns a pointer to the device with the index [index].
  * if the device is not assigned (dev->devnum==-1) returns NULL
@@ -906,7 +906,7 @@
 {
 	return 0;
 }
-#endif /* !CONFIG_DM_USB */
+#endif /* !CONFIG_IS_ENABLED(DM_USB) */
 
 static int usb_hub_port_reset(struct usb_device *dev, struct usb_device *hub)
 {
@@ -1166,7 +1166,7 @@
 	return ret;
 }
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 /*
  * By the time we get here, the device has gotten a new device ID
  * and is in the default state. We need to identify the thing and
@@ -1215,14 +1215,14 @@
 
 bool usb_device_has_child_on_port(struct usb_device *parent, int port)
 {
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	return false;
 #else
 	return parent->children[port] != NULL;
 #endif
 }
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 void usb_find_usb2_hub_address_port(struct usb_device *udev,
 			       uint8_t *hub_address, uint8_t *hub_port)
 {
diff --git a/common/usb_hub.c b/common/usb_hub.c
index e1d93b8..33aaeb8 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -64,7 +64,7 @@
 	return hdev->descriptor.bDeviceProtocol == 3;
 }
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 bool usb_hub_is_root_hub(struct udevice *hub)
 {
 	if (device_get_uclass_id(hub->parent) != UCLASS_USB_HUB)
@@ -125,7 +125,7 @@
 			USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
 			data, sizeof(struct usb_port_status), USB_CNTL_TIMEOUT);
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	if (ret < 0)
 		return ret;
 
@@ -209,7 +209,7 @@
 	      max(100, (int)pgood_delay) + 1000);
 }
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 static struct usb_hub_device hub_dev[USB_MAX_HUB];
 static int usb_hub_index;
 
@@ -273,7 +273,7 @@
 	unsigned short portstatus, portchange;
 	int delay = HUB_SHORT_RESET_TIME; /* start with short reset delay */
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	debug("%s: resetting '%s' port %d...\n", __func__, dev->dev->name,
 	      port + 1);
 #else
@@ -394,7 +394,7 @@
 		break;
 	}
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	struct udevice *child;
 
 	ret = usb_scan_device(dev->dev, port + 1, speed, &child);
@@ -604,7 +604,7 @@
 {
 	struct usb_hub_device *hub;
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 	/* "allocate" Hub device */
 	hub = usb_hub_allocate();
 #else
@@ -788,7 +788,7 @@
 	      (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? \
 	      "" : "no ");
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	/*
 	 * Update USB host controller's internal representation of this hub
 	 * after the hub descriptor is fetched.
@@ -930,7 +930,7 @@
 	return ret;
 }
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 int usb_hub_scan(struct udevice *hub)
 {
 	struct usb_device *udev = dev_get_parent_priv(hub);
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index fdeb2ae..020f0d4 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -539,7 +539,7 @@
 	return 0;
 }
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 /* Search for keyboard and register it if found. */
 int drv_usb_kbd_init(void)
 {
@@ -602,7 +602,7 @@
 
 #endif
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 
 static int usb_kbd_probe(struct udevice *dev)
 {
diff --git a/common/usb_storage.c b/common/usb_storage.c
index 560d605..8c889bb 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -66,7 +66,7 @@
 
 static int usb_max_devs; /* number of highest available usb device */
 
-#ifndef CONFIG_BLK
+#if !CONFIG_IS_ENABLED(BLK)
 static struct blk_desc usb_dev_desc[USB_MAX_STOR_DEV];
 #endif
 
@@ -99,7 +99,7 @@
 	unsigned short	max_xfer_blk;		/* maximum transfer blocks */
 };
 
-#ifndef CONFIG_BLK
+#if !CONFIG_IS_ENABLED(BLK)
 static struct us_data usb_stor[USB_MAX_STOR_DEV];
 #endif
 
@@ -111,7 +111,7 @@
 		      struct blk_desc *dev_desc);
 int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
 		      struct us_data *ss);
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
 static unsigned long usb_stor_read(struct udevice *dev, lbaint_t blknr,
 				   lbaint_t blkcnt, void *buffer);
 static unsigned long usb_stor_write(struct udevice *dev, lbaint_t blknr,
@@ -136,7 +136,7 @@
 int usb_stor_info(void)
 {
 	int count = 0;
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
 	struct udevice *dev;
 
 	for (blk_first_device(IF_TYPE_USB, &dev);
@@ -186,7 +186,7 @@
 {
 	int lun, max_lun;
 
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
 	struct us_data *data;
 	int ret;
 #else
@@ -197,7 +197,7 @@
 #endif
 
 	debug("\n\nProbing for storage\n");
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
 	/*
 	 * We store the us_data in the mass storage device's platdata. It
 	 * is shared by all LUNs (block devices) attached to this mass storage
@@ -299,7 +299,7 @@
 	if (mode == 1)
 		printf("       scanning usb for storage devices... ");
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 	unsigned char i;
 
 	usb_disable_asynch(1); /* asynch transfer not allowed */
@@ -942,7 +942,7 @@
 	size_t __maybe_unused size;
 	int __maybe_unused ret;
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 #ifdef CONFIG_USB_EHCI_HCD
 	/*
 	 * The U-Boot EHCI driver can handle any transfer length as long as
@@ -1119,7 +1119,7 @@
 }
 #endif /* CONFIG_USB_BIN_FIXUP */
 
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
 static unsigned long usb_stor_read(struct udevice *dev, lbaint_t blknr,
 				   lbaint_t blkcnt, void *buffer)
 #else
@@ -1134,14 +1134,14 @@
 	struct us_data *ss;
 	int retry;
 	struct scsi_cmd *srb = &usb_ccb;
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
 	struct blk_desc *block_dev;
 #endif
 
 	if (blkcnt == 0)
 		return 0;
 	/* Setup  device */
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
 	block_dev = dev_get_uclass_platdata(dev);
 	udev = dev_get_parent_priv(dev_get_parent(dev));
 	debug("\nusb_read: udev %d\n", block_dev->devnum);
@@ -1200,7 +1200,7 @@
 	return blkcnt;
 }
 
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
 static unsigned long usb_stor_write(struct udevice *dev, lbaint_t blknr,
 				    lbaint_t blkcnt, const void *buffer)
 #else
@@ -1215,7 +1215,7 @@
 	struct us_data *ss;
 	int retry;
 	struct scsi_cmd *srb = &usb_ccb;
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
 	struct blk_desc *block_dev;
 #endif
 
@@ -1223,7 +1223,7 @@
 		return 0;
 
 	/* Setup  device */
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
 	block_dev = dev_get_uclass_platdata(dev);
 	udev = dev_get_parent_priv(dev_get_parent(dev));
 	debug("\nusb_read: udev %d\n", block_dev->devnum);
@@ -1495,7 +1495,7 @@
 	return 1;
 }
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 
 static int usb_mass_storage_probe(struct udevice *dev)
 {
@@ -1519,7 +1519,7 @@
 	.id	= UCLASS_MASS_STORAGE,
 	.of_match = usb_mass_storage_ids,
 	.probe = usb_mass_storage_probe,
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
 	.platdata_auto_alloc_size	= sizeof(struct us_data),
 #endif
 };
@@ -1540,7 +1540,7 @@
 U_BOOT_USB_DEVICE(usb_mass_storage, mass_storage_id_table);
 #endif
 
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
 static const struct blk_ops usb_storage_ops = {
 	.read	= usb_stor_read,
 	.write	= usb_stor_write,
diff --git a/configs/MCR3000_defconfig b/configs/MCR3000_defconfig
index 29a60e3..33c6073 100644
--- a/configs/MCR3000_defconfig
+++ b/configs/MCR3000_defconfig
@@ -42,6 +42,7 @@
 CONFIG_USE_BOOTCOMMAND=y
 CONFIG_BOOTCOMMAND="run flashboot"
 CONFIG_MISC_INIT_R=y
+CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_HUSH_PARSER=y
 # CONFIG_AUTO_COMPLETE is not set
 CONFIG_SYS_PROMPT="S3K> "
@@ -73,3 +74,9 @@
 CONFIG_SHA256=y
 CONFIG_LZMA=y
 CONFIG_OF_LIBFDT=y
+CONFIG_DM=y
+CONFIG_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="mcr3000"
+CONFIG_WDT=y
+CONFIG_WDT_MPC8xx=y
+CONFIG_DM_SERIAL=y
diff --git a/configs/SBx81LIFKW_defconfig b/configs/SBx81LIFKW_defconfig
index 99526c1..e0ce159 100644
--- a/configs/SBx81LIFKW_defconfig
+++ b/configs/SBx81LIFKW_defconfig
@@ -28,6 +28,7 @@
 CONFIG_I2C_MUX=y
 CONFIG_I2C_MUX_PCA954x=y
 # CONFIG_MMC is not set
+CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_STMICRO=y
 # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
@@ -40,4 +41,5 @@
 CONFIG_DM_RTC=y
 CONFIG_RTC_MV=y
 CONFIG_SPI=y
+CONFIG_DM_SPI=y
 CONFIG_KIRKWOOD_SPI=y
diff --git a/configs/SBx81LIFXCAT_defconfig b/configs/SBx81LIFXCAT_defconfig
index a0abe23..4a6e058 100644
--- a/configs/SBx81LIFXCAT_defconfig
+++ b/configs/SBx81LIFXCAT_defconfig
@@ -32,6 +32,7 @@
 CONFIG_LED=y
 CONFIG_LED_GPIO=y
 # CONFIG_MMC is not set
+CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_STMICRO=y
 # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
@@ -42,4 +43,5 @@
 CONFIG_MV88E61XX_FIXED_PORTS=0x300
 CONFIG_MII=y
 CONFIG_SPI=y
+CONFIG_DM_SPI=y
 CONFIG_KIRKWOOD_SPI=y
diff --git a/configs/ax25-ae350_defconfig b/configs/a25-ae350_32_defconfig
similarity index 93%
rename from configs/ax25-ae350_defconfig
rename to configs/a25-ae350_32_defconfig
index d7c4f40..5837b48 100644
--- a/configs/ax25-ae350_defconfig
+++ b/configs/a25-ae350_32_defconfig
@@ -1,7 +1,6 @@
 CONFIG_RISCV=y
 CONFIG_SYS_TEXT_BASE=0x00000000
 CONFIG_TARGET_AX25_AE350=y
-CONFIG_CPU_RISCV_64=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_NR_DRAM_BANKS=2
 CONFIG_FIT=y
@@ -16,7 +15,7 @@
 CONFIG_BOOTP_PREFER_SERVERIP=y
 CONFIG_CMD_CACHE=y
 CONFIG_OF_BOARD=y
-CONFIG_DEFAULT_DEVICE_TREE="ae350"
+CONFIG_DEFAULT_DEVICE_TREE="ae350_32"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_MMC=y
diff --git a/configs/am335x_baltos_defconfig b/configs/am335x_baltos_defconfig
index a61b13b..05d41ae 100644
--- a/configs/am335x_baltos_defconfig
+++ b/configs/am335x_baltos_defconfig
@@ -1,6 +1,5 @@
 CONFIG_ARM=y
 CONFIG_ARCH_OMAP2PLUS=y
-CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_AM33XX=y
@@ -39,17 +38,26 @@
 CONFIG_MTDIDS_DEFAULT="nand0=omap2-nand.0"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=omap2-nand.0:128k(SPL),128k(SPL.backup1),128k(SPL.backup2),128k(SPL.backup3),1920k(u-boot),-(UBI)"
 CONFIG_CMD_UBI=y
+CONFIG_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="am335x-baltos"
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_SYS_OMAP24_I2C_SPEED=1000
+CONFIG_DM_MMC=y
 CONFIG_MMC_OMAP_HS=y
+CONFIG_MMC_OMAP_HS_ADMA=y
 CONFIG_NAND=y
+CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
+CONFIG_SYS_NAND_U_BOOT_OFFS=0x00080000
 CONFIG_PHY_ADDR_ENABLE=y
-CONFIG_DRIVER_TI_CPSW=y
+CONFIG_PHY_ATHEROS=y
+CONFIG_PHY_SMSC=y
 CONFIG_MII=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SPI=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
+CONFIG_DM_USB=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_USB_MUSB_DSPS=y
@@ -59,7 +67,7 @@
 CONFIG_USB_GADGET_VENDOR_NUM=0x0403
 CONFIG_USB_GADGET_PRODUCT_NUM=0xbd00
 CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_USB_FUNCTION_MASS_STORAGE=y
 CONFIG_USB_ETHER=y
 CONFIG_USBNET_HOST_ADDR="de:ad:be:af:00:00"
 CONFIG_FAT_WRITE=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/am335x_evm_defconfig b/configs/am335x_evm_defconfig
index b6cd49a..6cc170a 100644
--- a/configs/am335x_evm_defconfig
+++ b/configs/am335x_evm_defconfig
@@ -40,15 +40,16 @@
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_DM_ETH=y
-CONFIG_DRIVER_TI_CPSW=y
 CONFIG_PHY_GIGE=y
 CONFIG_MII=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SPI=y
 CONFIG_OMAP3_SPI=y
 CONFIG_TIMER=y
 CONFIG_OMAP_TIMER=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+# CONFIG_SPL_DM_USB is not set
 CONFIG_USB_MUSB_HOST=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_USB_MUSB_TI=y
diff --git a/configs/avnet_ultra96_rev1_defconfig b/configs/avnet_ultra96_rev1_defconfig
index c49c9f2..9ca884e 100644
--- a/configs/avnet_ultra96_rev1_defconfig
+++ b/configs/avnet_ultra96_rev1_defconfig
@@ -92,5 +92,6 @@
 CONFIG_USB_ETHER_ASIX=y
 CONFIG_WDT=y
 CONFIG_WDT_CDNS=y
+CONFIG_SPL_GZIP=y
 CONFIG_OF_LIBFDT_OVERLAY=y
 CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
diff --git a/configs/ax25-ae350_defconfig b/configs/ax25-ae350_64_defconfig
similarity index 92%
copy from configs/ax25-ae350_defconfig
copy to configs/ax25-ae350_64_defconfig
index d7c4f40..b250d3f 100644
--- a/configs/ax25-ae350_defconfig
+++ b/configs/ax25-ae350_64_defconfig
@@ -1,7 +1,7 @@
 CONFIG_RISCV=y
 CONFIG_SYS_TEXT_BASE=0x00000000
 CONFIG_TARGET_AX25_AE350=y
-CONFIG_CPU_RISCV_64=y
+CONFIG_ARCH_RV64I=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_NR_DRAM_BANKS=2
 CONFIG_FIT=y
@@ -16,7 +16,7 @@
 CONFIG_BOOTP_PREFER_SERVERIP=y
 CONFIG_CMD_CACHE=y
 CONFIG_OF_BOARD=y
-CONFIG_DEFAULT_DEVICE_TREE="ae350"
+CONFIG_DEFAULT_DEVICE_TREE="ae350_64"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_MMC=y
diff --git a/configs/bk4r1_defconfig b/configs/bk4r1_defconfig
index cf1fd0b..9e31b4a 100644
--- a/configs/bk4r1_defconfig
+++ b/configs/bk4r1_defconfig
@@ -40,6 +40,7 @@
 CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
 CONFIG_MII=y
+CONFIG_RTC_M41T62=y
 CONFIG_DM_SERIAL=y
 CONFIG_FSL_LPUART=y
 CONFIG_SPI=y
diff --git a/configs/chiliboard_defconfig b/configs/chiliboard_defconfig
index b6cde09..3de0223 100644
--- a/configs/chiliboard_defconfig
+++ b/configs/chiliboard_defconfig
@@ -29,19 +29,27 @@
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nand0=8000000.nand"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=8000000.nand:128k(NAND.SPL),128k(NAND.SPL.backup1),128k(NAND.SPL.backup2),128k(NAND.SPL.backup3),256k(NAND.u-boot-spl-os),1m(NAND.u-boot),128k(NAND.u-boot-env),128k(NAND.u-boot-env.backup1),8m(NAND.kernel),-(NAND.file-system)"
+CONFIG_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="am335x-chiliboard"
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DM_GPIO=y
+CONFIG_MISC=y
+CONFIG_DM_MMC=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_NAND=y
-CONFIG_DRIVER_TI_CPSW=y
+CONFIG_DM_ETH=y
 CONFIG_MII=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SPI=y
 CONFIG_OMAP3_SPI=y
+CONFIG_TIMER=y
+CONFIG_OMAP_TIMER=y
 CONFIG_USB=y
+CONFIG_DM_USB=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_USB_MUSB_DSPS=y
+CONFIG_USB_MUSB_TI=y
 CONFIG_USB_STORAGE=y
 CONFIG_FAT_WRITE=y
 CONFIG_LZO=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/clearfog_gt_8k_defconfig b/configs/clearfog_gt_8k_defconfig
index 6cd1f89..8f766c1 100644
--- a/configs/clearfog_gt_8k_defconfig
+++ b/configs/clearfog_gt_8k_defconfig
@@ -10,7 +10,7 @@
 CONFIG_DEBUG_UART=y
 CONFIG_AHCI=y
 CONFIG_DISTRO_DEFAULTS=y
-CONFIG_NR_DRAM_BANKS=1
+CONFIG_NR_DRAM_BANKS=2
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 # CONFIG_DISPLAY_CPUINFO is not set
diff --git a/configs/dreamplug_defconfig b/configs/dreamplug_defconfig
index 76c7680..d3263cf 100644
--- a/configs/dreamplug_defconfig
+++ b/configs/dreamplug_defconfig
@@ -26,6 +26,7 @@
 CONFIG_DM=y
 CONFIG_MVSATA_IDE=y
 # CONFIG_MMC is not set
+CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_MVGBE=y
@@ -34,6 +35,7 @@
 CONFIG_RTC_MV=y
 CONFIG_SYS_NS16550=y
 CONFIG_SPI=y
+CONFIG_DM_SPI=y
 CONFIG_KIRKWOOD_SPI=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
diff --git a/configs/ds109_defconfig b/configs/ds109_defconfig
index 23f1886..352403e 100644
--- a/configs/ds109_defconfig
+++ b/configs/ds109_defconfig
@@ -23,6 +23,7 @@
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MVTWSI=y
 # CONFIG_MMC is not set
+CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_STMICRO=y
@@ -32,6 +33,7 @@
 CONFIG_RTC_MV=y
 CONFIG_SYS_NS16550=y
 CONFIG_SPI=y
+CONFIG_DM_SPI=y
 CONFIG_KIRKWOOD_SPI=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
diff --git a/configs/gardena-smart-gateway-mt7688-ram_defconfig b/configs/gardena-smart-gateway-mt7688-ram_defconfig
index 9135969..05e7cf9 100644
--- a/configs/gardena-smart-gateway-mt7688-ram_defconfig
+++ b/configs/gardena-smart-gateway-mt7688-ram_defconfig
@@ -10,6 +10,8 @@
 CONFIG_FIT_SIGNATURE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_USE_BOOTCOMMAND=y
+CONFIG_BOOTCOMMAND="cp.b 83000000 84000000 10000 && dhcp uEnv.txt && env import -t ${fileaddr} ${filesize} && run do_u_boot_init; reset"
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
 CONFIG_BOARD_EARLY_INIT_F=y
@@ -31,8 +33,8 @@
 CONFIG_CMD_TIME=y
 CONFIG_CMD_UUID=y
 CONFIG_CMD_MTDPARTS=y
-CONFIG_MTDIDS_DEFAULT="spi-nand0=spi-nand0"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-nand0:-(nand)"
+CONFIG_MTDIDS_DEFAULT="spi-nand0=gd5f,nor0=spi0.0"
+CONFIG_MTDPARTS_DEFAULT="spi0.0:640k(uboot),64k(uboot_env0),64k(uboot_env1),64k(factory),-(unused);gd5f:-(nand)"
 CONFIG_CMD_UBI=y
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688"
diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig
index bd8b035..a08d1db 100644
--- a/configs/gardena-smart-gateway-mt7688_defconfig
+++ b/configs/gardena-smart-gateway-mt7688_defconfig
@@ -13,6 +13,8 @@
 CONFIG_FIT_SIGNATURE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_USE_BOOTCOMMAND=y
+CONFIG_BOOTCOMMAND="cp.b 83000000 84000000 10000 && dhcp uEnv.txt && env import -t ${fileaddr} ${filesize} && run do_u_boot_init; reset"
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
 CONFIG_BOARD_EARLY_INIT_F=y
@@ -34,8 +36,8 @@
 CONFIG_CMD_TIME=y
 CONFIG_CMD_UUID=y
 CONFIG_CMD_MTDPARTS=y
-CONFIG_MTDIDS_DEFAULT="spi-nand0=spi-nand0"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-nand0:-(nand)"
+CONFIG_MTDIDS_DEFAULT="spi-nand0=gd5f,nor0=spi0.0"
+CONFIG_MTDPARTS_DEFAULT="spi0.0:640k(uboot),64k(uboot_env0),64k(uboot_env1),64k(factory),-(unused);gd5f:-(nand)"
 CONFIG_CMD_UBI=y
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688"
diff --git a/configs/khadas-vim2_defconfig b/configs/khadas-vim2_defconfig
index 4bbccc2..6fe861c 100644
--- a/configs/khadas-vim2_defconfig
+++ b/configs/khadas-vim2_defconfig
@@ -2,7 +2,6 @@
 CONFIG_ARCH_MESON=y
 CONFIG_SYS_TEXT_BASE=0x01000000
 CONFIG_MESON_GXM=y
-CONFIG_TARGET_KHADAS_VIM2=y
 CONFIG_DEBUG_UART_BASE=0xc81004c0
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_IDENT_STRING=" khadas-vim2"
diff --git a/configs/khadas-vim_defconfig b/configs/khadas-vim_defconfig
index 0c89d9a..6e855dd 100644
--- a/configs/khadas-vim_defconfig
+++ b/configs/khadas-vim_defconfig
@@ -2,7 +2,6 @@
 CONFIG_ARCH_MESON=y
 CONFIG_SYS_TEXT_BASE=0x01000000
 CONFIG_MESON_GXL=y
-CONFIG_TARGET_KHADAS_VIM=y
 CONFIG_DEBUG_UART_BASE=0xc81004c0
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_IDENT_STRING=" khadas-vim"
diff --git a/configs/libretech-cc_defconfig b/configs/libretech-cc_defconfig
index 36d117c..c2f985f 100644
--- a/configs/libretech-cc_defconfig
+++ b/configs/libretech-cc_defconfig
@@ -2,7 +2,6 @@
 CONFIG_ARCH_MESON=y
 CONFIG_SYS_TEXT_BASE=0x01000000
 CONFIG_MESON_GXL=y
-CONFIG_TARGET_LIBRETECH_CC=y
 CONFIG_DEBUG_UART_BASE=0xc81004c0
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_IDENT_STRING=" libretech-cc"
diff --git a/configs/m53menlo_defconfig b/configs/m53menlo_defconfig
index 795f8a3..dd7aed3 100644
--- a/configs/m53menlo_defconfig
+++ b/configs/m53menlo_defconfig
@@ -49,6 +49,7 @@
 CONFIG_NAND_MXC=y
 CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
+CONFIG_RTC_M41T62=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_HOST_ETHER=y
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig
index 0b21020..02e62e2 100644
--- a/configs/microblaze-generic_defconfig
+++ b/configs/microblaze-generic_defconfig
@@ -16,6 +16,7 @@
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="root=romfs"
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
+CONFIG_DISPLAY_BOARDINFO=y
 CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_NOR_SUPPORT=y
diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig
new file mode 100644
index 0000000..3a4de72
--- /dev/null
+++ b/configs/mt7623n_bpir2_defconfig
@@ -0,0 +1,54 @@
+CONFIG_ARM=y
+CONFIG_SYS_THUMB_BUILD=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x81e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_TARGET_MT7623=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_BOOTDELAY=3
+CONFIG_SYS_CONSOLE_IS_IN_ENV=y
+CONFIG_DEFAULT_FDT_FILE="mt7623n-bananapi-bpi-r2"
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="U-Boot> "
+CONFIG_CMD_BOOTMENU=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_READ=y
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_EMBED=y
+CONFIG_DEFAULT_DEVICE_TREE="mt7623n-bananapi-bpi-r2"
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+# CONFIG_BLOCK_CACHE is not set
+CONFIG_CLK=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_MMC=y
+# CONFIG_MMC_QUIRKS is not set
+CONFIG_MMC_HS400_SUPPORT=y
+CONFIG_MMC_MTK=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7623=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SYSRESET=y
+CONFIG_SYSRESET_WATCHDOG=y
+CONFIG_TIMER=y
+CONFIG_MTK_TIMER=y
+CONFIG_WDT_MTK=y
+CONFIG_LZMA=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/mt7629_rfb_defconfig b/configs/mt7629_rfb_defconfig
new file mode 100644
index 0000000..1729d13
--- /dev/null
+++ b/configs/mt7629_rfb_defconfig
@@ -0,0 +1,73 @@
+CONFIG_ARM=y
+CONFIG_SYS_THUMB_BUILD=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_TARGET_MT7629=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_BOOTDELAY=3
+CONFIG_SYS_CONSOLE_IS_IN_ENV=y
+CONFIG_DEFAULT_FDT_FILE="mt7629-rfb"
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_NOR_SUPPORT=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="U-Boot> "
+CONFIG_CMD_BOOTMENU=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SF_TEST=y
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
+# CONFIG_PARTITIONS is not set
+CONFIG_OF_EMBED=y
+CONFIG_DEFAULT_DEVICE_TREE="mt7629-rfb"
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-parents"
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_DM_GPIO=y
+# CONFIG_MMC is not set
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7629=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_RAM=y
+CONFIG_SPL_RAM=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_MTK_QSPI=y
+CONFIG_SYSRESET=y
+CONFIG_SYSRESET_WATCHDOG=y
+CONFIG_TIMER=y
+CONFIG_SPL_TIMER=y
+CONFIG_MTK_TIMER=y
+CONFIG_WDT_MTK=y
+CONFIG_LZMA=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/mvebu_db_armada8k_defconfig b/configs/mvebu_db_armada8k_defconfig
index cbdc130..bb29d25 100644
--- a/configs/mvebu_db_armada8k_defconfig
+++ b/configs/mvebu_db_armada8k_defconfig
@@ -9,7 +9,7 @@
 CONFIG_DEBUG_UART=y
 CONFIG_AHCI=y
 CONFIG_DISTRO_DEFAULTS=y
-CONFIG_NR_DRAM_BANKS=1
+CONFIG_NR_DRAM_BANKS=2
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 # CONFIG_DISPLAY_CPUINFO is not set
diff --git a/configs/mvebu_mcbin-88f8040_defconfig b/configs/mvebu_mcbin-88f8040_defconfig
index 9f72b76..9df4c51 100644
--- a/configs/mvebu_mcbin-88f8040_defconfig
+++ b/configs/mvebu_mcbin-88f8040_defconfig
@@ -5,11 +5,10 @@
 CONFIG_TARGET_MVEBU_ARMADA_8K=y
 CONFIG_DEBUG_UART_BASE=0xf0512000
 CONFIG_DEBUG_UART_CLOCK=200000000
-CONFIG_SMBIOS_PRODUCT_NAME=""
 CONFIG_DEBUG_UART=y
 CONFIG_AHCI=y
 CONFIG_DISTRO_DEFAULTS=y
-CONFIG_NR_DRAM_BANKS=1
+CONFIG_NR_DRAM_BANKS=2
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 # CONFIG_DISPLAY_CPUINFO is not set
@@ -35,6 +34,7 @@
 CONFIG_MAC_PARTITION=y
 CONFIG_DEFAULT_DEVICE_TREE="armada-8040-mcbin"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_AHCI_MVEBU=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
@@ -48,8 +48,9 @@
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHYLIB=y
+CONFIG_PHY_MARVELL=y
 CONFIG_PHY_GIGE=y
+CONFIG_MVPP2=y
 CONFIG_PCI=y
 CONFIG_DM_PCI=y
 CONFIG_PCIE_DW_MVEBU=y
@@ -72,4 +73,3 @@
 CONFIG_USB_ETHER_MCS7830=y
 CONFIG_USB_ETHER_RTL8152=y
 CONFIG_USB_ETHER_SMSC95XX=y
-CONFIG_SMBIOS_MANUFACTURER=""
diff --git a/configs/nanopi-k2_defconfig b/configs/nanopi-k2_defconfig
index 5c8c747..8bbf48f 100644
--- a/configs/nanopi-k2_defconfig
+++ b/configs/nanopi-k2_defconfig
@@ -1,8 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_MESON=y
 CONFIG_SYS_TEXT_BASE=0x01000000
-CONFIG_MESON_GXBB=y
-CONFIG_TARGET_NANOPI_K2=y
 CONFIG_DEBUG_UART_BASE=0xc81004c0
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_IDENT_STRING=" nanopi-k2"
diff --git a/configs/odroid-c2_defconfig b/configs/odroid-c2_defconfig
index 19196b3..68554ba 100644
--- a/configs/odroid-c2_defconfig
+++ b/configs/odroid-c2_defconfig
@@ -2,7 +2,6 @@
 CONFIG_ARCH_MESON=y
 CONFIG_SYS_TEXT_BASE=0x01000000
 CONFIG_MESON_GXBB=y
-CONFIG_TARGET_ODROID_C2=y
 CONFIG_DEBUG_UART_BASE=0xc81004c0
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_IDENT_STRING=" odroid-c2"
diff --git a/configs/p212_defconfig b/configs/p212_defconfig
index 9e3b1d6..a15064d 100644
--- a/configs/p212_defconfig
+++ b/configs/p212_defconfig
@@ -2,7 +2,6 @@
 CONFIG_ARCH_MESON=y
 CONFIG_SYS_TEXT_BASE=0x01000000
 CONFIG_MESON_GXL=y
-CONFIG_TARGET_P212=y
 CONFIG_DEBUG_UART_BASE=0xc81004c0
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_IDENT_STRING=" p212"
diff --git a/configs/pcm052_defconfig b/configs/pcm052_defconfig
index 0c8e31a..e207df5 100644
--- a/configs/pcm052_defconfig
+++ b/configs/pcm052_defconfig
@@ -35,5 +35,6 @@
 CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
 CONFIG_MII=y
+CONFIG_RTC_M41T62=y
 CONFIG_DM_SERIAL=y
 CONFIG_FSL_LPUART=y
diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu-riscv32_defconfig
index ff1fb1f..6334d8c 100644
--- a/configs/qemu-riscv32_defconfig
+++ b/configs/qemu-riscv32_defconfig
@@ -1,6 +1,9 @@
 CONFIG_RISCV=y
 CONFIG_TARGET_QEMU_VIRT=y
+CONFIG_DISTRO_DEFAULTS=y
 CONFIG_NR_DRAM_BANKS=1
+CONFIG_FIT=y
 CONFIG_DISPLAY_CPUINFO=y
 CONFIG_DISPLAY_BOARDINFO=y
-CONFIG_OF_BOARD=y
+# CONFIG_CMD_MII is not set
+CONFIG_OF_PRIOR_STAGE=y
diff --git a/configs/qemu-riscv32_smode_defconfig b/configs/qemu-riscv32_smode_defconfig
new file mode 100644
index 0000000..0a84ec1
--- /dev/null
+++ b/configs/qemu-riscv32_smode_defconfig
@@ -0,0 +1,10 @@
+CONFIG_RISCV=y
+CONFIG_TARGET_QEMU_VIRT=y
+CONFIG_RISCV_SMODE=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_FIT=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DISPLAY_BOARDINFO=y
+# CONFIG_CMD_MII is not set
+CONFIG_OF_PRIOR_STAGE=y
diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-riscv64_defconfig
index d6c1a5d..2d9ead9 100644
--- a/configs/qemu-riscv64_defconfig
+++ b/configs/qemu-riscv64_defconfig
@@ -1,7 +1,10 @@
 CONFIG_RISCV=y
 CONFIG_TARGET_QEMU_VIRT=y
-CONFIG_CPU_RISCV_64=y
+CONFIG_ARCH_RV64I=y
+CONFIG_DISTRO_DEFAULTS=y
 CONFIG_NR_DRAM_BANKS=1
+CONFIG_FIT=y
 CONFIG_DISPLAY_CPUINFO=y
 CONFIG_DISPLAY_BOARDINFO=y
-CONFIG_OF_BOARD=y
+# CONFIG_CMD_MII is not set
+CONFIG_OF_PRIOR_STAGE=y
diff --git a/configs/qemu-riscv64_smode_defconfig b/configs/qemu-riscv64_smode_defconfig
new file mode 100644
index 0000000..b012443
--- /dev/null
+++ b/configs/qemu-riscv64_smode_defconfig
@@ -0,0 +1,11 @@
+CONFIG_RISCV=y
+CONFIG_TARGET_QEMU_VIRT=y
+CONFIG_ARCH_RV64I=y
+CONFIG_RISCV_SMODE=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_FIT=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DISPLAY_BOARDINFO=y
+# CONFIG_CMD_MII is not set
+CONFIG_OF_PRIOR_STAGE=y
diff --git a/configs/r8a7795_salvator-x_defconfig b/configs/r8a7795_salvator-x_defconfig
index 40712a4..1aa3cef 100644
--- a/configs/r8a7795_salvator-x_defconfig
+++ b/configs/r8a7795_salvator-x_defconfig
@@ -28,6 +28,8 @@
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="r8a7795-salvator-x-u-boot"
+CONFIG_OF_LIST="r8a7795-salvator-x-u-boot r8a7796-salvator-x-u-boot r8a77965-salvator-x-u-boot"
+CONFIG_MULTI_DTB_FIT=y
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
@@ -41,6 +43,7 @@
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_RENESAS_SDHI=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
diff --git a/configs/r8a7795_ulcb_defconfig b/configs/r8a7795_ulcb_defconfig
index f1d150b..3280a35 100644
--- a/configs/r8a7795_ulcb_defconfig
+++ b/configs/r8a7795_ulcb_defconfig
@@ -28,6 +28,8 @@
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="r8a7795-h3ulcb-u-boot"
+CONFIG_OF_LIST="r8a7795-h3ulcb-u-boot r8a7796-m3ulcb-u-boot"
+CONFIG_MULTI_DTB_FIT=y
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
@@ -41,6 +43,7 @@
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_RENESAS_SDHI=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
diff --git a/configs/r8a77965_salvator-x_defconfig b/configs/r8a77965_salvator-x_defconfig
index 72549e2..8204771 100644
--- a/configs/r8a77965_salvator-x_defconfig
+++ b/configs/r8a77965_salvator-x_defconfig
@@ -29,6 +29,8 @@
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="r8a77965-salvator-x-u-boot"
+CONFIG_OF_LIST="r8a7795-salvator-x-u-boot r8a7796-salvator-x-u-boot r8a77965-salvator-x-u-boot"
+CONFIG_MULTI_DTB_FIT=y
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
@@ -42,6 +44,7 @@
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_RENESAS_SDHI=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
diff --git a/configs/r8a7796_salvator-x_defconfig b/configs/r8a7796_salvator-x_defconfig
index 7c39268..a57e475 100644
--- a/configs/r8a7796_salvator-x_defconfig
+++ b/configs/r8a7796_salvator-x_defconfig
@@ -29,6 +29,8 @@
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="r8a7796-salvator-x-u-boot"
+CONFIG_OF_LIST="r8a7795-salvator-x-u-boot r8a7796-salvator-x-u-boot r8a77965-salvator-x-u-boot"
+CONFIG_MULTI_DTB_FIT=y
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
@@ -42,6 +44,7 @@
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_RENESAS_SDHI=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
diff --git a/configs/r8a7796_ulcb_defconfig b/configs/r8a7796_ulcb_defconfig
index ef5c944..20b2dd9 100644
--- a/configs/r8a7796_ulcb_defconfig
+++ b/configs/r8a7796_ulcb_defconfig
@@ -29,6 +29,8 @@
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="r8a7796-m3ulcb-u-boot"
+CONFIG_OF_LIST="r8a7795-h3ulcb-u-boot r8a7796-m3ulcb-u-boot"
+CONFIG_MULTI_DTB_FIT=y
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
@@ -42,6 +44,7 @@
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_RENESAS_SDHI=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
diff --git a/configs/r8a77990_ebisu_defconfig b/configs/r8a77990_ebisu_defconfig
index 7363310..5a8fc04 100644
--- a/configs/r8a77990_ebisu_defconfig
+++ b/configs/r8a77990_ebisu_defconfig
@@ -42,6 +42,7 @@
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_RENESAS_SDHI=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
diff --git a/configs/rock_defconfig b/configs/rock_defconfig
index 28dcd5b..0c41ac9 100644
--- a/configs/rock_defconfig
+++ b/configs/rock_defconfig
@@ -56,6 +56,5 @@
 CONFIG_USB=y
 CONFIG_ROCKCHIP_USB2_PHY=y
 CONFIG_SPL_TINY_MEMSET=y
-CONFIG_TPL_TINY_MEMSET=y
 CONFIG_CMD_DHRYSTONE=y
 CONFIG_ERRNO_STR=y
diff --git a/configs/rpi_0_w_defconfig b/configs/rpi_0_w_defconfig
index d5bf01b..66b0de3 100644
--- a/configs/rpi_0_w_defconfig
+++ b/configs/rpi_0_w_defconfig
@@ -13,6 +13,7 @@
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_FS_UUID=y
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="bcm2835-rpi-zero-w"
 CONFIG_ENV_FAT_INTERFACE="mmc"
diff --git a/configs/rpi_2_defconfig b/configs/rpi_2_defconfig
index a50a815..ba75e52 100644
--- a/configs/rpi_2_defconfig
+++ b/configs/rpi_2_defconfig
@@ -13,6 +13,7 @@
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_FS_UUID=y
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="bcm2836-rpi-2-b"
 CONFIG_ENV_FAT_INTERFACE="mmc"
diff --git a/configs/rpi_3_32b_defconfig b/configs/rpi_3_32b_defconfig
index ec395d2..bbcdd91 100644
--- a/configs/rpi_3_32b_defconfig
+++ b/configs/rpi_3_32b_defconfig
@@ -14,6 +14,7 @@
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_FS_UUID=y
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="bcm2837-rpi-3-b"
 CONFIG_ENV_FAT_INTERFACE="mmc"
diff --git a/configs/rpi_3_defconfig b/configs/rpi_3_defconfig
index ac99f20..54b6303 100644
--- a/configs/rpi_3_defconfig
+++ b/configs/rpi_3_defconfig
@@ -14,6 +14,7 @@
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_FS_UUID=y
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="bcm2837-rpi-3-b"
 CONFIG_ENV_FAT_INTERFACE="mmc"
diff --git a/configs/rpi_defconfig b/configs/rpi_defconfig
index db42ffd..e7820cb 100644
--- a/configs/rpi_defconfig
+++ b/configs/rpi_defconfig
@@ -13,6 +13,7 @@
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_FS_UUID=y
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="bcm2835-rpi-b"
 CONFIG_ENV_FAT_INTERFACE="mmc"
diff --git a/configs/s400_defconfig b/configs/s400_defconfig
new file mode 100644
index 0000000..1bd4b71
--- /dev/null
+++ b/configs/s400_defconfig
@@ -0,0 +1,38 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MESON=y
+CONFIG_SYS_TEXT_BASE=0x01000000
+CONFIG_MESON_AXG=y
+CONFIG_DEBUG_UART_BASE=0xff803000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_IDENT_STRING=" s400"
+CONFIG_DEBUG_UART=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_MISC_INIT_R=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_IMI is not set
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_REGULATOR=y
+CONFIG_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="meson-axg-s400"
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_MESON_GX=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_MESON_AXG=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_RESET=y
+CONFIG_DEBUG_UART_MESON=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_MESON_SERIAL=y
+CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 5a744f4..1a76785 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -5,6 +5,7 @@
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_FIT=y
 CONFIG_FIT_SIGNATURE=y
+CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_BOOTSTAGE=y
 CONFIG_BOOTSTAGE_REPORT=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index f44e80e..452a2ef 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -22,6 +22,7 @@
 CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
 CONFIG_SILENT_CONSOLE=y
 CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_HANDOFF=y
 CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_CMD_CPU=y
diff --git a/configs/vexpress_aemv8a_dram_defconfig b/configs/vexpress_aemv8a_dram_defconfig
index 9848f96..0f0f138 100644
--- a/configs/vexpress_aemv8a_dram_defconfig
+++ b/configs/vexpress_aemv8a_dram_defconfig
@@ -23,12 +23,14 @@
 # CONFIG_CMD_NFS is not set
 CONFIG_CMD_CACHE=y
 # CONFIG_CMD_MISC is not set
+CONFIG_CMD_UBI=y
 # CONFIG_ISO_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 CONFIG_ENV_IS_IN_FLASH=y
 CONFIG_DM=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
+CONFIG_MTD_DEVICE=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
 CONFIG_SYS_FLASH_PROTECTION=y
diff --git a/configs/vexpress_aemv8a_juno_defconfig b/configs/vexpress_aemv8a_juno_defconfig
index ef38915..ed611fe 100644
--- a/configs/vexpress_aemv8a_juno_defconfig
+++ b/configs/vexpress_aemv8a_juno_defconfig
@@ -23,12 +23,14 @@
 # CONFIG_CMD_NFS is not set
 CONFIG_CMD_CACHE=y
 # CONFIG_CMD_MISC is not set
+CONFIG_CMD_UBI=y
 # CONFIG_ISO_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 CONFIG_ENV_IS_IN_FLASH=y
 CONFIG_DM=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
+CONFIG_MTD_DEVICE=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
 CONFIG_SYS_FLASH_PROTECTION=y
diff --git a/configs/vexpress_aemv8a_semi_defconfig b/configs/vexpress_aemv8a_semi_defconfig
index a4d1233..0b3bb65 100644
--- a/configs/vexpress_aemv8a_semi_defconfig
+++ b/configs/vexpress_aemv8a_semi_defconfig
@@ -23,12 +23,14 @@
 # CONFIG_CMD_NFS is not set
 CONFIG_CMD_CACHE=y
 # CONFIG_CMD_MISC is not set
+CONFIG_CMD_UBI=y
 # CONFIG_ISO_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 CONFIG_ENV_IS_IN_FLASH=y
 CONFIG_DM=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
+CONFIG_MTD_DEVICE=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
 CONFIG_SYS_FLASH_PROTECTION=y
diff --git a/configs/vexpress_ca15_tc2_defconfig b/configs/vexpress_ca15_tc2_defconfig
index f4d555b..cabc0c4 100644
--- a/configs/vexpress_ca15_tc2_defconfig
+++ b/configs/vexpress_ca15_tc2_defconfig
@@ -18,8 +18,10 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_NFS is not set
 # CONFIG_CMD_MISC is not set
+CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_FLASH=y
 CONFIG_MTD_NOR_FLASH=y
+CONFIG_MTD_DEVICE=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
 CONFIG_SYS_FLASH_PROTECTION=y
diff --git a/configs/vexpress_ca5x2_defconfig b/configs/vexpress_ca5x2_defconfig
index bdacc60..dc4411d 100644
--- a/configs/vexpress_ca5x2_defconfig
+++ b/configs/vexpress_ca5x2_defconfig
@@ -17,8 +17,10 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_NFS is not set
 # CONFIG_CMD_MISC is not set
+CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_FLASH=y
 CONFIG_MTD_NOR_FLASH=y
+CONFIG_MTD_DEVICE=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
 CONFIG_SYS_FLASH_PROTECTION=y
diff --git a/configs/vexpress_ca9x4_defconfig b/configs/vexpress_ca9x4_defconfig
index 7a90831..9390cf6 100644
--- a/configs/vexpress_ca9x4_defconfig
+++ b/configs/vexpress_ca9x4_defconfig
@@ -17,8 +17,10 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_NFS is not set
 # CONFIG_CMD_MISC is not set
+CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_FLASH=y
 CONFIG_MTD_NOR_FLASH=y
+CONFIG_MTD_DEVICE=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
 CONFIG_SYS_FLASH_PROTECTION=y
diff --git a/configs/vf610twr_defconfig b/configs/vf610twr_defconfig
index a928cd4..504eebb 100644
--- a/configs/vf610twr_defconfig
+++ b/configs/vf610twr_defconfig
@@ -41,4 +41,4 @@
 CONFIG_MII=y
 CONFIG_DM_SERIAL=y
 CONFIG_FSL_LPUART=y
-# CONFIG_EFI_UNICODE_CAPITALIZATION is not set
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/vf610twr_nand_defconfig b/configs/vf610twr_nand_defconfig
index 560776f..0a1e28e 100644
--- a/configs/vf610twr_nand_defconfig
+++ b/configs/vf610twr_nand_defconfig
@@ -41,4 +41,4 @@
 CONFIG_MII=y
 CONFIG_DM_SERIAL=y
 CONFIG_FSL_LPUART=y
-# CONFIG_EFI_UNICODE_CAPITALIZATION is not set
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/x600_defconfig b/configs/x600_defconfig
index c8f5f66..a96f54c 100644
--- a/configs/x600_defconfig
+++ b/configs/x600_defconfig
@@ -52,6 +52,7 @@
 CONFIG_PHY_MICREL_KSZ90X1=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_MII=y
+CONFIG_RTC_M41T62=y
 CONFIG_CONS_INDEX=0
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
diff --git a/configs/xilinx_zynqmp_mini_defconfig b/configs/xilinx_zynqmp_mini_defconfig
new file mode 100644
index 0000000..e54c81c
--- /dev/null
+++ b/configs/xilinx_zynqmp_mini_defconfig
@@ -0,0 +1,52 @@
+CONFIG_ARM=y
+CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_mini_qspi"
+CONFIG_ARCH_ZYNQMP=y
+CONFIG_SYS_TEXT_BASE=0xFFFC0000
+CONFIG_ENV_SIZE=0x80
+CONFIG_SYS_MEM_RSVD_FOR_MMU=y
+CONFIG_ZYNQMP_PSU_INIT_ENABLED=y
+# CONFIG_CMD_ZYNQMP is not set
+# CONFIG_IMAGE_FORMAT_LEGACY is not set
+# CONFIG_BOARD_LATE_INIT is not set
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_CMDLINE_EDITING is not set
+# CONFIG_AUTO_COMPLETE is not set
+# CONFIG_SYS_LONGHELP is not set
+CONFIG_SYS_PROMPT="ZynqMP> "
+# CONFIG_AUTOBOOT is not set
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_BOOTM is not set
+# CONFIG_CMD_BOOTI is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_FDT is not set
+# CONFIG_CMD_GO is not set
+# CONFIG_CMD_RUN is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_MEMTEST=y
+CONFIG_SYS_ALT_MEMTEST=y
+# CONFIG_CMD_DM is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_ECHO is not set
+# CONFIG_CMD_ITEST is not set
+# CONFIG_CMD_SOURCE is not set
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_MISC is not set
+# CONFIG_PARTITIONS is not set
+CONFIG_OF_EMBED=y
+CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini"
+# CONFIG_NET is not set
+# CONFIG_DM_WARN is not set
+# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_MMC is not set
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/xilinx_zynqmp_mini_emmc0_defconfig b/configs/xilinx_zynqmp_mini_emmc0_defconfig
index 917637d..9cdc944 100644
--- a/configs/xilinx_zynqmp_mini_emmc0_defconfig
+++ b/configs/xilinx_zynqmp_mini_emmc0_defconfig
@@ -2,12 +2,11 @@
 CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_mini_emmc"
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x10000
-CONFIG_ENV_SIZE=0x10000
+CONFIG_ENV_SIZE=0x80
+CONFIG_SPL=y
 # CONFIG_CMD_ZYNQMP is not set
-CONFIG_ENV_VARS_UBOOT_CONFIG=y
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_FIT=y
-CONFIG_BOOTDELAY=-1
 CONFIG_SUPPORT_RAW_INITRD=y
 # CONFIG_BOARD_LATE_INIT is not set
 # CONFIG_DISPLAY_CPUINFO is not set
@@ -15,11 +14,14 @@
 # CONFIG_CMDLINE_EDITING is not set
 # CONFIG_AUTO_COMPLETE is not set
 CONFIG_SYS_PROMPT="ZynqMP> "
+# CONFIG_AUTOBOOT is not set
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
 # CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_FDT is not set
 # CONFIG_CMD_GO is not set
 # CONFIG_CMD_RUN is not set
 # CONFIG_CMD_IMI is not set
@@ -42,11 +44,14 @@
 # CONFIG_MP is not set
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-emmc0"
 # CONFIG_NET is not set
+CONFIG_SPL_DM=y
 # CONFIG_DM_WARN is not set
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ZYNQ=y
diff --git a/configs/xilinx_zynqmp_mini_emmc1_defconfig b/configs/xilinx_zynqmp_mini_emmc1_defconfig
index 1ffa528..74ea3a8 100644
--- a/configs/xilinx_zynqmp_mini_emmc1_defconfig
+++ b/configs/xilinx_zynqmp_mini_emmc1_defconfig
@@ -2,12 +2,11 @@
 CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_mini_emmc"
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x10000
-CONFIG_ENV_SIZE=0x10000
+CONFIG_ENV_SIZE=0x80
+CONFIG_SPL=y
 # CONFIG_CMD_ZYNQMP is not set
-CONFIG_ENV_VARS_UBOOT_CONFIG=y
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_FIT=y
-CONFIG_BOOTDELAY=-1
 CONFIG_SUPPORT_RAW_INITRD=y
 # CONFIG_BOARD_LATE_INIT is not set
 # CONFIG_DISPLAY_CPUINFO is not set
@@ -15,11 +14,14 @@
 # CONFIG_CMDLINE_EDITING is not set
 # CONFIG_AUTO_COMPLETE is not set
 CONFIG_SYS_PROMPT="ZynqMP> "
+# CONFIG_AUTOBOOT is not set
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
 # CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_FDT is not set
 # CONFIG_CMD_GO is not set
 # CONFIG_CMD_RUN is not set
 # CONFIG_CMD_IMI is not set
@@ -42,11 +44,14 @@
 # CONFIG_MP is not set
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-emmc1"
 # CONFIG_NET is not set
+CONFIG_SPL_DM=y
 # CONFIG_DM_WARN is not set
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ZYNQ=y
diff --git a/configs/xilinx_zynqmp_mini_nand_defconfig b/configs/xilinx_zynqmp_mini_nand_defconfig
index 74ba0c9..9267f69 100644
--- a/configs/xilinx_zynqmp_mini_nand_defconfig
+++ b/configs/xilinx_zynqmp_mini_nand_defconfig
@@ -2,12 +2,10 @@
 CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_mini_nand"
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x10000
-CONFIG_ENV_SIZE=0x10000
+CONFIG_ENV_SIZE=0x80
 # CONFIG_CMD_ZYNQMP is not set
-CONFIG_ENV_VARS_UBOOT_CONFIG=y
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_FIT=y
-CONFIG_BOOTDELAY=-1
 CONFIG_SUPPORT_RAW_INITRD=y
 # CONFIG_BOARD_LATE_INIT is not set
 # CONFIG_DISPLAY_CPUINFO is not set
@@ -16,6 +14,7 @@
 # CONFIG_AUTO_COMPLETE is not set
 # CONFIG_SYS_LONGHELP is not set
 CONFIG_SYS_PROMPT="ZynqMP> "
+# CONFIG_AUTOBOOT is not set
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
diff --git a/configs/xilinx_zynqmp_mini_qspi_defconfig b/configs/xilinx_zynqmp_mini_qspi_defconfig
index db129b6..de7bf07 100644
--- a/configs/xilinx_zynqmp_mini_qspi_defconfig
+++ b/configs/xilinx_zynqmp_mini_qspi_defconfig
@@ -2,19 +2,20 @@
 CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_mini_qspi"
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0xFFFC0000
-CONFIG_ENV_SIZE=0x578
+CONFIG_ENV_SIZE=0x80
+CONFIG_SPL=y
 CONFIG_SYS_MEM_RSVD_FOR_MMU=y
 CONFIG_ZYNQMP_NO_DDR=y
 # CONFIG_CMD_ZYNQMP is not set
 CONFIG_NR_DRAM_BANKS=1
 # CONFIG_IMAGE_FORMAT_LEGACY is not set
-CONFIG_BOOTDELAY=-1
 # CONFIG_BOARD_LATE_INIT is not set
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_CMDLINE_EDITING is not set
 # CONFIG_AUTO_COMPLETE is not set
 # CONFIG_SYS_LONGHELP is not set
 CONFIG_SYS_PROMPT="ZynqMP> "
+# CONFIG_AUTOBOOT is not set
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
@@ -43,11 +44,14 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_MISC is not set
 # CONFIG_PARTITIONS is not set
+CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-qspi"
 # CONFIG_NET is not set
+CONFIG_SPL_DM=y
 # CONFIG_DM_WARN is not set
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_SPL_DM_SEQ_ALIAS=y
 # CONFIG_MMC is not set
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
diff --git a/configs/xilinx_zynqmp_zcu100_revC_defconfig b/configs/xilinx_zynqmp_zcu100_revC_defconfig
index dc1e7cd..429bfd4 100644
--- a/configs/xilinx_zynqmp_zcu100_revC_defconfig
+++ b/configs/xilinx_zynqmp_zcu100_revC_defconfig
@@ -92,5 +92,6 @@
 CONFIG_USB_ETHER_ASIX=y
 CONFIG_WDT=y
 CONFIG_WDT_CDNS=y
+CONFIG_SPL_GZIP=y
 CONFIG_OF_LIBFDT_OVERLAY=y
 CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
diff --git a/configs/xilinx_zynqmp_zcu102_revA_defconfig b/configs/xilinx_zynqmp_zcu102_revA_defconfig
index 02dd5ed..41a0337 100644
--- a/configs/xilinx_zynqmp_zcu102_revA_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_revA_defconfig
@@ -111,4 +111,5 @@
 CONFIG_USB_GADGET_VENDOR_NUM=0x03FD
 CONFIG_USB_GADGET_PRODUCT_NUM=0x0300
 CONFIG_USB_FUNCTION_THOR=y
+CONFIG_SPL_GZIP=y
 CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
diff --git a/configs/xilinx_zynqmp_zcu104_revC_defconfig b/configs/xilinx_zynqmp_zcu104_revC_defconfig
index 33258e4..0357b17 100644
--- a/configs/xilinx_zynqmp_zcu104_revC_defconfig
+++ b/configs/xilinx_zynqmp_zcu104_revC_defconfig
@@ -1,5 +1,5 @@
 CONFIG_ARM=y
-CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zcu104"
+CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zcu104_revC"
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
@@ -53,6 +53,7 @@
 CONFIG_SYS_I2C_ZYNQ=y
 CONFIG_ZYNQ_I2C1=y
 CONFIG_MISC=y
+CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ZYNQ=y
diff --git a/configs/zynq_cse_nand_defconfig b/configs/zynq_cse_nand_defconfig
index 44ad5bd..608619e 100644
--- a/configs/zynq_cse_nand_defconfig
+++ b/configs/zynq_cse_nand_defconfig
@@ -9,7 +9,11 @@
 # CONFIG_BOARD_LATE_INIT is not set
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
+# CONFIG_CMDLINE_EDITING is not set
+# CONFIG_AUTO_COMPLETE is not set
+# CONFIG_SYS_LONGHELP is not set
 CONFIG_SYS_PROMPT="Zynq> "
+# CONFIG_AUTOBOOT is not set
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
@@ -36,11 +40,11 @@
 # CONFIG_CMD_ITEST is not set
 # CONFIG_CMD_SOURCE is not set
 # CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NET is not set
 # CONFIG_CMD_MISC is not set
 # CONFIG_PARTITIONS is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-cse-nand"
+# CONFIG_NET is not set
 # CONFIG_DM_WARN is not set
 # CONFIG_DM_DEVICE_REMOVE is not set
 CONFIG_SPL_DM_SEQ_ALIAS=y
diff --git a/configs/zynq_cse_nor_defconfig b/configs/zynq_cse_nor_defconfig
index b4831f8..b4f1e31 100644
--- a/configs/zynq_cse_nor_defconfig
+++ b/configs/zynq_cse_nor_defconfig
@@ -6,11 +6,14 @@
 CONFIG_SPL=y
 CONFIG_SPL_STACK_R_ADDR=0x200000
 CONFIG_SYS_MALLOC_LEN=0x1000
-CONFIG_BOOTDELAY=-1
 # CONFIG_BOARD_LATE_INIT is not set
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
+# CONFIG_CMDLINE_EDITING is not set
+# CONFIG_AUTO_COMPLETE is not set
+# CONFIG_SYS_LONGHELP is not set
 CONFIG_SYS_PROMPT="Zynq> "
+# CONFIG_AUTOBOOT is not set
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
@@ -36,11 +39,11 @@
 # CONFIG_CMD_ITEST is not set
 # CONFIG_CMD_SOURCE is not set
 # CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NET is not set
 # CONFIG_CMD_MISC is not set
 # CONFIG_PARTITIONS is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-cse-nor"
+# CONFIG_NET is not set
 # CONFIG_DM_WARN is not set
 # CONFIG_DM_DEVICE_REMOVE is not set
 CONFIG_SPL_DM_SEQ_ALIAS=y
diff --git a/configs/zynq_cse_qspi_defconfig b/configs/zynq_cse_qspi_defconfig
index 2e1e34d..2aee069 100644
--- a/configs/zynq_cse_qspi_defconfig
+++ b/configs/zynq_cse_qspi_defconfig
@@ -11,16 +11,17 @@
 CONFIG_SYS_MALLOC_LEN=0x1000
 # CONFIG_CMD_ZYNQ is not set
 CONFIG_DEBUG_UART=y
-CONFIG_DISTRO_DEFAULTS=y
 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
-CONFIG_BOOTDELAY=-1
-# CONFIG_USE_BOOTCOMMAND is not set
 # CONFIG_BOARD_LATE_INIT is not set
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_ARCH_EARLY_INIT_R is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SPI_LOAD=y
+# CONFIG_CMDLINE_EDITING is not set
+# CONFIG_AUTO_COMPLETE is not set
+# CONFIG_SYS_LONGHELP is not set
 CONFIG_SYS_PROMPT="Zynq> "
+# CONFIG_AUTOBOOT is not set
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
diff --git a/configs/zynq_zc702_defconfig b/configs/zynq_zc702_defconfig
index 5223a9b..27e6bd1 100644
--- a/configs/zynq_zc702_defconfig
+++ b/configs/zynq_zc702_defconfig
@@ -20,6 +20,7 @@
 CONFIG_SYS_PROMPT="Zynq> "
 CONFIG_CMD_THOR_DOWNLOAD=y
 CONFIG_CMD_EEPROM=y
+CONFIG_CMD_MEMTEST=y
 CONFIG_CMD_DFU=y
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_FPGA_LOADBP=y
diff --git a/doc/README.bloblist b/doc/README.bloblist
new file mode 100644
index 0000000..b0e787b
--- /dev/null
+++ b/doc/README.bloblist
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+Blob Lists - bloblist
+=====================
+
+Introduction
+------------
+
+A bloblist provides a way to store collections of binary information (blobs) in
+a central structure. Each record of information is assigned a tag so that its
+owner can find it and update it. Each record is generally described by a C
+structure defined by the code that owns it.
+
+
+Passing state through the boot process
+--------------------------------------
+
+The bloblist is created when the first U-Boot component runs (often SPL,
+sometimes TPL). It is passed through to each successive part of the boot and
+can be accessed as needed. This provides a way to transfer state from one part
+to the next. For example, TPL may determine that a watchdog reset occurred by
+reading an SoC register. Reading the register may reset the value, so that it
+cannot be read a second time. So TPL can store that in a bloblist record which
+can be passed through to SPL and U-Boot proper, which can print a message
+indicating that something went wrong and the watchdog fired.
+
+
+Blobs
+-----
+
+While each blob in the bloblist can be of any length, bloblists are designed to
+hold small amounts of data, typically a few KB at most. It is not possible to
+change the length of a blob once it has been written. Each blob is normally
+created from a C structure which can beused to access its fields.
+
+
+Blob tags
+---------
+
+Each blob has a tag which is a 32-bit number. This uniquely identifies the
+owner of the blob. Blob tags are listed in enum blob_tag_t and are named
+with a BLOBT_ prefix.
+
+
+Single structure
+----------------
+
+There is normally only one bloblist in U-Boot. Since a bloblist can store
+multiple blobs it does not seem useful to allow multiple bloblists. Of course
+there could be reasons for this, such as needing to spread the blobs around in
+different memory areas due to fragmented memory, but it is simpler to just have
+a single bloblist.
+
+
+API
+---
+
+Bloblist provides a fairly simple API which allows blobs to be created  and
+found. All access is via the blob's tag.
+
+
+Finishing the bloblist
+----------------------
+
+When a part of U-Boot is about to jump to the next part, it can 'finish' the
+bloblist in preparation for the next stage. This involves adding a checksum so
+that the next stage can make sure that the data arrived safely. While the
+bloblist is in use, changes can be made which will affect the checksum, so it
+is easier to calculate the checksum at the end after all changes are made.
+
+
+Future work
+-----------
+
+Bootstage has a mechanism to 'stash' its records for passing to the next part.
+This should move to using bloblist, to avoid having its own mechanism for
+passing information between U-Boot parts.
+
+
+Simon Glass
+sjg@chromium.org
+12-Aug-2018
diff --git a/doc/README.distro b/doc/README.distro
index f8e9752..ab6e6f4 100644
--- a/doc/README.distro
+++ b/doc/README.distro
@@ -292,7 +292,7 @@
 device or SD card) or type of boot device (e.g. USB disk). The parameters to
 the func macro (passed in by the internal implementation of the header) are:
 
-- Upper-case disk type (MMC, SATA, SCSI, IDE, USB, DHCP, PXE).
+- Upper-case disk type (MMC, SATA, SCSI, IDE, USB, DHCP, PXE, VIRTIO).
 - Lower-case disk type (same options as above).
 - ID of the specific disk (MMC only) or ignored for other types.
 
@@ -398,6 +398,7 @@
   * scsi
   * ide
   * usb
+  * virtio
 
 Other *boot* variables than the ones defined above are only for internal use
 of the boot environment and are not guaranteed to exist or work in the same
diff --git a/doc/README.iscsi b/doc/README.iscsi
index faee636..3a12438 100644
--- a/doc/README.iscsi
+++ b/doc/README.iscsi
@@ -1,8 +1,6 @@
-iSCSI booting with U-Boot and iPXE
-==================================
+# iSCSI booting with U-Boot and iPXE
 
-Motivation
-----------
+## Motivation
 
 U-Boot has only a reduced set of supported network protocols. The focus for
 network booting has been on UDP based protocols. A TCP stack and HTTP support
@@ -41,8 +39,7 @@
 iPXE can be built as an EFI application (named snp.efi) which can be loaded and
 run by U-Boot.
 
-Boot sequence
--------------
+## Boot sequence
 
 U-Boot loads the EFI application iPXE snp.efi using the bootefi command. This
 application has network access via the simple network protocol offered by
@@ -106,19 +103,16 @@
                                                                       |        |
                                                                       | ~ ~ ~ ~|
 
-Security
---------
+## Security
 
 The iSCSI protocol is not encrypted. The traffic could be secured using IPsec
 but neither U-Boot nor iPXE does support this. So we should at least separate
 the iSCSI traffic from all other network traffic. This can be achieved using a
 virtual local area network (VLAN).
 
-Configuration
--------------
+## Configuration
 
-iPXE
-^^^^
+### iPXE
 
 For running iPXE on arm64 the bin-arm64-efi/snp.efi build target is needed::
 
@@ -157,9 +151,20 @@
     #define DOWNLOAD_PROTO_NFS      /* Network File System Protocol */
     #define DOWNLOAD_PROTO_FILE     /* Local file system access */
 
-Links
------
+### Open-iSCSI
+
+When the root file system is on an iSCSI drive you should disable pings and set
+the replacement timer to a high value [3]:
+
+    node.conn[0].timeo.noop_out_interval = 0
+    node.conn[0].timeo.noop_out_timeout = 0
+    node.session.timeo.replacement_timeout = 86400
+
+## Links
 
 * [1](https://ipxe.org) https://ipxe.org - iPXE open source boot firmware
 * [2](https://www.gnu.org/software/grub/) https://www.gnu.org/software/grub/ -
-  GNU GRUB (Grand Unified Bootloader)
+     GNU GRUB (Grand Unified Bootloader)
+* [3](https://github.com/open-iscsi/open-iscsi/blob/master/README)
+     https://github.com/open-iscsi/open-iscsi/blob/master/README -
+     Open-iSCSI README
diff --git a/doc/README.mediatek b/doc/README.mediatek
new file mode 100644
index 0000000..246579d
--- /dev/null
+++ b/doc/README.mediatek
@@ -0,0 +1,221 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2018 MediaTek Inc.
+# Ryder Lee <ryder.lee@kernel.org>
+
+
+This document describes how to compile the U-Boot and how to change U-Boot
+configuration about the MediaTek SoCs.
+
+
+Build Procedure
+===============
+	-Set the cross compiler:
+
+		# export CROSS_COMPILE=/path/to/toolchain/arm-linux-gnueabi-
+
+	-Clean-up old residuals:
+
+		# make mrproper
+
+	-Configure the U-Boot:
+
+		# make <defconfig_file>
+		# make
+
+		- For the MT7623n bananapi R2 board use "mt7623n_bpir2_defconfig"
+		- For the MT7629 reference board use "mt7629_rfb_defconfig"
+
+
+Boot sequence
+=============
+	-Bootrom -> MTK preloader -> U-Boot
+
+		- MT7623n
+
+	This version of U-Boot doesn't implement SPL. So, MTK preloader binary
+	is needed to boot up:
+
+	https://github.com/BPI-SINOVOIP/BPI-R2-bsp/tree/master/mt-pack/mtk/bpi-r2/bin
+
+
+	-Bootrom -> SPL -> U-Boot
+
+		- MT7629
+
+
+Configuration update
+====================
+	To update the U-Boot configuration, please refer to doc/README.kconfig
+
+
+MediaTek image header
+=====================
+Currently there are two image headers used for MediaTek chips:
+
+	- BootROM image header. This header is used by the first stage bootloader. It records
+	  the desired compatible boot device, integrity information and its load address.
+
+	  The on-chip BootROM will firstly verify integrity and compatibility of the bootloader.
+
+	  If verification passed, the BootROM will then load the bootloader into on-chip SRAM,
+	  and pass control to it.
+
+	  Note that this header is actually a combination of three independent headers:
+	  Device header, BRLYT header and GFH header.
+
+	  Used by U-Boot SPL of MT7629 and preloader of MT7623.
+
+
+	- MediaTek legacy image header. This header was originally used by the legacy image. It
+	  basically records the load address, image size and image name.
+
+	  After all low level initializations passed, the preloader will locate the LK image and
+	  load it into DRAM, and pass control to it.
+
+	  Now this header is used by U-Boot of MT7623.
+
+
+To generate these two headers with mkimage:
+
+	# mkimage -T mtk_image -a <load_addr> -n <option_string> -d <input_file> <image_file>
+
+	- mtk_image means using MediaTek's header generation method.
+
+
+	- load_addr is the load address of this image.
+	  For first stage bootloader like U-Boot SPL or preloader, it usually points to the
+	  on-chip SRAM.
+
+	  For second stage bootloader like U-Boot, it usually points to the DRAM.
+
+
+	- option_string contains options to generate the header.
+
+	  The option string is using the follow format:
+		key1=value1;key2=value2;...
+
+	  The following key names are valid:
+		lk: If lk=1, LK image header is used. Otherwise BootROM image header is used.
+
+		lkname: The name of the LK image header. The maximum length is 32.
+			The default value is "U-Boot".
+
+		media: Desired boot device. The valid values are:
+		nand : Parallel NAND
+		snand: Serial NAND
+		nor  : Serial NOR
+		emmc : eMMC
+		sdmmc: SD
+
+	   nandinfo: Desired NAND device type, a combination of page size, oob size and
+		     optional device capacity. Valid types are:
+		2k+64    : for Serial NAND, 2KiB page size + 64B oob size
+		2k+120   : for Serial NAND, 2KiB page size + 120B oob size
+		2k+128   : for Serial NAND, 2KiB page size + 128B oob size
+		4k+256   : for Serial NAND, 4KiB page size + 256B oob size
+		1g:2k+64 : for Parallel NAND, 2KiB page size + 64B oob size, total 1Gbit size
+		2g:2k+64 : for Parallel NAND, 2KiB page size + 64B oob size, total 2Gbit size
+		4g:2k+64 : for Parallel NAND, 2KiB page size + 64B oob size, total 4Gbit size
+		2g:2k+128: for Parallel NAND, 2KiB page size + 128B oob size, total 2Gbit size
+		4g:2k+128: for Parallel NAND, 2KiB page size + 128B oob size, total 4Gbit size
+
+
+MT7629 partitions on Serial NOR
+===============================
+
+	Start      End       Size       Description
+	00000000 - 0000ffff: 64KiB      U-Boot SPL
+	00010000 - 0005ffff: 320KiB     U-Boot
+	00060000 - 0006ffff: 64KiB      U-Boot env / MediaTek NVRAM
+	00070000 - 000affff: 256KiB     RF calibration data
+	000b0000 - xxxxxxxx: all left   Firmware image
+
+
+BPi-R2 (MT7623N) partitions on SD
+=================================
+	Please note that the last two partitions can vary from different Linux distributions
+	depending on the MBR partition table.
+
+	Start      End       Size       Description
+	00000000 - 000001ff: 512B       Device header (with MBR partition table)
+	00000200 - 000007ff: 1536B      BRLYT header
+	00000800 - 0004ffff: 318KiB     Preloader (with GFH header)
+	00050000 - 000fffff: 704KiB     U-Boot
+	00100000 - 063fffff: 99MiB      Reserved
+	06400000 - 163fffff: 256MiB     Partition 1 (FAT32)
+	16400000 - xxxxxxxx: all left   Partition 2 (ext4)
+
+
+Upgrading notice on Serial NOR
+==============================
+Example: MT7629
+
+	The command sf is used to operate the Serial NOR device:
+
+	- To probe current NOR flash:
+
+		# sf probe
+
+	- To erase a region:
+
+		# sf erase <offset> <len>
+
+	- To write data to an offset:
+
+		# sf write <data_addr> <offset> <len>
+
+	- To boot kernel:
+
+		# bootm 0x300b0000
+
+	The memory address range 0x30000000 - 0x3fffffff is mapped to the NOR flash.
+	The DRAM starts at 0x40000000.
+
+	Please note that the output binary u-boot-mtk.bin is a combination of SPL and U-Boot,
+	and it should be write to beginning of the flash.
+
+	Otherwise you should use standalone files:
+
+		spl/u-boot-spl-mtk.bin for SPL,
+		u-boot.img for U-Boot.
+
+
+Upgrading notice on SD / eMMC
+=============================
+Example: MT7623
+
+	Normally only Preloader and U-Boot can be upgraded within U-Boot, and other partitions
+	should be written in PC.
+
+	- To probe current SD card / eMMC:
+
+		# mmc dev 0 for eMMC
+		# mmc dev 1 for SD
+
+	- To erase a region:
+
+		# mmc erase <blk_offset> <blk_num>
+
+	- To write data to a block offset:
+
+		# mmc write <data_addr> <blk_offset> <blk_num>
+
+	- To load kernel image from partition 1:
+
+		# fatload mmc 0:1 <load_address> <path_to_kernel_uImage> for eMMC
+		# fatload mmc 1:1 <load_address> <path_to_kernel_uImage> for SD
+
+	- To boot kernel:
+
+		# bootm <load_address>
+
+	The DRAM starts at 0x80000000.
+
+	Please note that we use block offset and block count for SD card, not the byte offset.
+	The block size is always 512 bytes for SD card.
+
+
+Documentation
+=============
+	http://wiki.banana-pi.org/Banana_Pi_BPI-R2
diff --git a/doc/README.trace b/doc/README.trace
index 74ba26a..2e7ca33 100644
--- a/doc/README.trace
+++ b/doc/README.trace
@@ -88,7 +88,7 @@
 stdout=serial
 
 Environment size: 117/8188 bytes
-=>sb save host 0 trace 0 ${profoffset}
+=>host save host 0 trace 0 ${profoffset}
 11405888 bytes written in 10 ms (1.1 GiB/s)
 =>reset
 
diff --git a/doc/device-tree-bindings/spi/spi-cadence.txt b/doc/device-tree-bindings/spi/spi-cadence.txt
index 74c8208..69e02c1 100644
--- a/doc/device-tree-bindings/spi/spi-cadence.txt
+++ b/doc/device-tree-bindings/spi/spi-cadence.txt
@@ -2,7 +2,7 @@
 --------------------------------------------
 
 Required properties:
-- compatible		: should be "cadence,qspi".
+- compatible		: should be "cdns,qspi-nor"
 - reg			: 1.Physical base address and size of SPI registers map.
 			  2. Physical base address & size of NOR Flash.
 - clocks		: Clock phandles (see clock bindings for details).
diff --git a/doc/driver-model/MIGRATION.txt b/doc/driver-model/MIGRATION.txt
index 5ebefd6..6b69133 100644
--- a/doc/driver-model/MIGRATION.txt
+++ b/doc/driver-model/MIGRATION.txt
@@ -5,19 +5,46 @@
 2014. This file describes the schedule for deprecation of pre-driver-model
 features.
 
+CONFIG_DM_MMC
+-------------
+
+Status: In progress
+Deadline: 2019.04
+
+The subsystem itself has been converted and maintainers should submit patches
+switching over to using CONFIG_DM_MMC and other base driver model options in
+time for inclusion in the 2019.04 rerelease.
+
+CONFIG_DM_USB
+-------------
+
+Status: In progress
+Deadline: 2019.07
+
+The subsystem itself has been converted along with many of the host controller
+and maintainers should submit patches switching over to using CONFIG_DM_USB and
+other base driver model options in time for inclusion in the 2019.07 rerelease.
+
+CONFIG_SATA
+-----------
+
+Status: In progress
+Deadline: 2019.07
+
+The subsystem itself has been converted along with many of the host controller
+and maintainers should submit patches switching over to using CONFIG_AHCI and
+other base driver model options in time for inclusion in the 2019.07 rerelease.
 
 CONFIG_BLK
 ----------
 
 Status: In progress
-Deadline: 2018.05
-
-Maintainers should submit patches for enabling CONFIG_BLK on all boards in
-time for inclusion in the 2018.05 release. Boards not converted by this
-time may be removed in a subsequent release.
+Deadline: 2019.07
 
-Note that this implies use of driver model for all block devices (e.g.
-MMC, USB, SCSI, SATA).
+In concert with maintainers migrating their block device usage to the
+appropriate DM driver, CONFIG_BLK needs to be set as well.  The final deadline
+here coincides with the final deadline for migration of the various block
+subsystems.
 
 CONFIG_DM_SPI
 CONFIG_DM_SPI_FLASH
diff --git a/doc/uImage.FIT/signature.txt b/doc/uImage.FIT/signature.txt
index a765722..bfff6fd 100644
--- a/doc/uImage.FIT/signature.txt
+++ b/doc/uImage.FIT/signature.txt
@@ -106,6 +106,9 @@
 
 - comment: Additional information about the signer or image
 
+- padding: The padding algorithm, it may be pkcs-1.5 or pss,
+	if no value is provided we assume pkcs-1.5
+
 For config bindings (see Signed Configurations below), the following
 additional properties are optional:
 
diff --git a/drivers/Makefile b/drivers/Makefile
index 4453c62..55de109 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -2,14 +2,19 @@
 
 obj-$(CONFIG_$(SPL_TPL_)CLK) += clk/
 obj-$(CONFIG_$(SPL_TPL_)DM) += core/
+obj-$(CONFIG_$(SPL_TPL_)GPIO_SUPPORT) += gpio/
 obj-$(CONFIG_$(SPL_TPL_)DRIVERS_MISC_SUPPORT) += misc/ sysreset/ firmware/
 obj-$(CONFIG_$(SPL_TPL_)I2C_SUPPORT) += i2c/
+obj-$(CONFIG_$(SPL_TPL_)INPUT) += input/
 obj-$(CONFIG_$(SPL_TPL_)LED) += led/
 obj-$(CONFIG_$(SPL_TPL_)MMC_SUPPORT) += mmc/
 obj-$(CONFIG_$(SPL_TPL_)NAND_SUPPORT) += mtd/nand/raw/
+obj-$(CONFIG_$(SPL_TPL_)PCH_SUPPORT) += pch/
+obj-$(CONFIG_$(SPL_TPL_)PCI_SUPPORT) += pci/
 obj-$(CONFIG_$(SPL_TPL_)PHY) += phy/
 obj-$(CONFIG_$(SPL_TPL_)PINCTRL) += pinctrl/
 obj-$(CONFIG_$(SPL_TPL_)RAM) += ram/
+obj-$(CONFIG_$(SPL_TPL_)RTC_SUPPORT) += rtc/
 obj-$(CONFIG_$(SPL_TPL_)SERIAL_SUPPORT) += serial/
 obj-$(CONFIG_$(SPL_TPL_)SPI_FLASH_SUPPORT) += mtd/spi/
 obj-$(CONFIG_$(SPL_TPL_)SPI_SUPPORT) += spi/
@@ -17,6 +22,7 @@
 obj-$(CONFIG_$(SPL_TPL_)VIRTIO) += virtio/
 obj-$(CONFIG_$(SPL_)DM_MAILBOX) += mailbox/
 obj-$(CONFIG_$(SPL_)REMOTEPROC) += remoteproc/
+obj-$(CONFIG_$(SPL_TPL_)TPM) += tpm/
 
 ifndef CONFIG_TPL_BUILD
 ifdef CONFIG_SPL_BUILD
@@ -24,7 +30,6 @@
 obj-$(CONFIG_SPL_BOOTCOUNT_LIMIT) += bootcount/
 obj-$(CONFIG_SPL_CPU_SUPPORT) += cpu/
 obj-$(CONFIG_SPL_CRYPTO_SUPPORT) += crypto/
-obj-$(CONFIG_SPL_GPIO_SUPPORT) += gpio/
 obj-$(CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT) += ddr/fsl/
 obj-$(CONFIG_ARMADA_38X) += ddr/marvell/a38x/
 obj-$(CONFIG_ARMADA_XP) += ddr/marvell/axp/
@@ -40,9 +45,6 @@
 obj-$(CONFIG_SPL_ETH_SUPPORT) += net/
 obj-$(CONFIG_SPL_ETH_SUPPORT) += net/phy/
 obj-$(CONFIG_SPL_USB_ETHER) += net/phy/
-obj-$(CONFIG_SPL_PCI_SUPPORT) += pci/
-obj-$(CONFIG_SPL_PCH_SUPPORT) += pch/
-obj-$(CONFIG_SPL_RTC_SUPPORT) += rtc/
 obj-$(CONFIG_SPL_MUSB_NEW_SUPPORT) += usb/musb-new/
 obj-$(CONFIG_SPL_USB_GADGET_SUPPORT) += usb/gadget/
 obj-$(CONFIG_SPL_USB_GADGET_SUPPORT) += usb/gadget/udc/
@@ -92,7 +94,6 @@
 obj-y += sound/
 obj-y += spmi/
 obj-y += sysreset/
-obj-y += tpm/
 obj-y += video/
 obj-y += watchdog/
 obj-$(CONFIG_QE) += qe/
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 821b586..9acbb1a 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -9,7 +9,8 @@
 obj-y += imx/
 obj-y += tegra/
 obj-$(CONFIG_ARCH_ASPEED) += aspeed/
-obj-$(CONFIG_ARCH_MESON) += clk_meson.o
+obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
+obj-$(CONFIG_ARCH_MESON) += clk_meson.o clk_meson_axg.o
 obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
 obj-$(CONFIG_ARCH_SOCFPGA) += altera/
 obj-$(CONFIG_CLK_AT91) += at91/
diff --git a/drivers/clk/clk_meson.c b/drivers/clk/clk_meson.c
index c448588..2cb53fb 100644
--- a/drivers/clk/clk_meson.c
+++ b/drivers/clk/clk_meson.c
@@ -6,11 +6,13 @@
  */
 
 #include <common.h>
-#include <asm/arch/clock.h>
+#include <asm/arch/clock-gx.h>
 #include <asm/io.h>
 #include <clk-uclass.h>
 #include <div64.h>
 #include <dm.h>
+#include <regmap.h>
+#include <syscon.h>
 #include <dt-bindings/clock/gxbb-clkc.h>
 #include "clk_meson.h"
 
@@ -65,7 +67,7 @@
 #define XTAL_RATE 24000000
 
 struct meson_clk {
-	void __iomem *addr;
+	struct regmap *map;
 };
 
 static ulong meson_div_get_rate(struct clk *clk, unsigned long id);
@@ -79,7 +81,7 @@
 static ulong meson_mux_get_parent(struct clk *clk, unsigned long id);
 static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id);
 
-struct meson_gate gates[] = {
+static struct meson_gate gates[] = {
 	/* Everything Else (EE) domain gates */
 	MESON_GATE(CLKID_DDR, HHI_GCLK_MPEG0, 0),
 	MESON_GATE(CLKID_DOS, HHI_GCLK_MPEG0, 1),
@@ -217,8 +219,8 @@
 
 	debug("%s: really %sabling %ld\n", __func__, on ? "en" : "dis", id);
 
-	clrsetbits_le32(priv->addr + gate->reg,
-			BIT(gate->bit), on ? BIT(gate->bit) : 0);
+	regmap_update_bits(priv->map, gate->reg,
+			   BIT(gate->bit), on ? BIT(gate->bit) : 0);
 
 	/* Propagate to next gate(s) */
 	switch (id) {
@@ -269,7 +271,7 @@
 	unsigned int rate, parent_rate;
 	struct parm *parm;
 	int parent;
-	u32 reg;
+	uint reg;
 
 	switch (id) {
 	case CLKID_VPU_0_DIV:
@@ -292,7 +294,7 @@
 		return -ENOENT;
 	}
 
-	reg = readl(priv->addr + parm->reg_off);
+	regmap_read(priv->map, parm->reg_off, &reg);
 	reg = PARM_GET(parm->width, parm->shift, reg);
 
 	debug("%s: div of %ld is %d\n", __func__, id, reg + 1);
@@ -318,7 +320,6 @@
 	unsigned long parent_rate;
 	struct parm *parm;
 	int parent;
-	u32 reg;
 	int ret;
 
 	if (current_rate == rate)
@@ -383,9 +384,8 @@
 
 	debug("%s: setting div of %ld to %d\n", __func__, id, new_div);
 
-	reg = readl(priv->addr + parm->reg_off);
-	writel(PARM_SET(parm->width, parm->shift, reg, new_div - 1),
-	       priv->addr + parm->reg_off);
+	regmap_update_bits(priv->map, parm->reg_off, SETPMASK(parm->width, parm->shift),
+			   (new_div - 1) << parm->shift);
 
 	debug("%s: new rate of %ld is %ld\n",
 	      __func__, id, meson_div_get_rate(clk, id));
@@ -446,7 +446,7 @@
 	struct meson_clk *priv = dev_get_priv(clk->dev);
 	struct parm *parm;
 	int *parents;
-	u32 reg;
+	uint reg;
 
 	switch (id) {
 	case CLKID_VPU:
@@ -477,7 +477,7 @@
 		return -ENOENT;
 	}
 
-	reg = readl(priv->addr + parm->reg_off);
+	regmap_read(priv->map, parm->reg_off, &reg);
 	reg = PARM_GET(parm->width, parm->shift, reg);
 
 	debug("%s: parent of %ld is %d (%d)\n",
@@ -494,7 +494,6 @@
 	unsigned int new_index = -EINVAL;
 	struct parm *parm;
 	int *parents;
-	u32 reg;
 	int i;
 
 	if (IS_ERR_VALUE(cur_parent))
@@ -546,9 +545,8 @@
 
 	debug("%s: new index of %ld is %d\n", __func__, id, new_index);
 
-	reg = readl(priv->addr + parm->reg_off);
-	writel(PARM_SET(parm->width, parm->shift, reg, new_index),
-	       priv->addr + parm->reg_off);
+	regmap_update_bits(priv->map, parm->reg_off, SETPMASK(parm->width, parm->shift),
+			   new_index << parm->shift);
 
 	debug("%s: new parent of %ld is %ld\n",
 	      __func__, id, meson_mux_get_parent(clk, id));
@@ -570,7 +568,7 @@
 {
 	struct meson_clk *priv = dev_get_priv(clk->dev);
 	unsigned long parent_rate;
-	u32 reg;
+	uint reg;
 	int parents[] = {
 		-1,
 		-1,
@@ -583,7 +581,7 @@
 	};
 
 	/* mux */
-	reg = readl(priv->addr + HHI_MPEG_CLK_CNTL);
+	regmap_read(priv->map, HHI_MPEG_CLK_CNTL, &reg);
 	reg = (reg >> 12) & 7;
 
 	switch (reg) {
@@ -597,7 +595,7 @@
 	}
 
 	/* divider */
-	reg = readl(priv->addr + HHI_MPEG_CLK_CNTL);
+	regmap_read(priv->map, HHI_MPEG_CLK_CNTL, &reg);
 	reg = reg & ((1 << 7) - 1);
 
 	/* clk81 divider is zero based */
@@ -641,8 +639,9 @@
 {
 	struct meson_clk *priv = dev_get_priv(clk->dev);
 	struct parm *psdm, *pn2;
-	unsigned long reg, sdm, n2;
+	unsigned long sdm, n2;
 	unsigned long parent_rate;
+	uint reg;
 
 	switch (id) {
 	case CLKID_MPLL0:
@@ -665,10 +664,10 @@
 	if (IS_ERR_VALUE(parent_rate))
 		return parent_rate;
 
-	reg = readl(priv->addr + psdm->reg_off);
+	regmap_read(priv->map, psdm->reg_off, &reg);
 	sdm = PARM_GET(psdm->width, psdm->shift, reg);
 
-	reg = readl(priv->addr + pn2->reg_off);
+	regmap_read(priv->map, pn2->reg_off, &reg);
 	n2 = PARM_GET(pn2->width, pn2->shift, reg);
 
 	return mpll_rate_from_params(parent_rate, sdm, n2);
@@ -692,7 +691,7 @@
 	struct parm *pm, *pn, *pod;
 	unsigned long parent_rate_mhz = XTAL_RATE / 1000000;
 	u16 n, m, od;
-	u32 reg;
+	uint reg;
 
 	switch (id) {
 	case CLKID_FIXED_PLL:
@@ -709,13 +708,13 @@
 		return -ENOENT;
 	}
 
-	reg = readl(priv->addr + pn->reg_off);
+	regmap_read(priv->map, pn->reg_off, &reg);
 	n = PARM_GET(pn->width, pn->shift, reg);
 
-	reg = readl(priv->addr + pm->reg_off);
+	regmap_read(priv->map, pm->reg_off, &reg);
 	m = PARM_GET(pm->width, pm->shift, reg);
 
-	reg = readl(priv->addr + pod->reg_off);
+	regmap_read(priv->map, pod->reg_off, &reg);
 	od = PARM_GET(pod->width, pod->shift, reg);
 
 	return ((parent_rate_mhz * m / n) >> od) * 1000000;
@@ -791,7 +790,7 @@
 		return -ENOENT;
 	}
 
-	printf("clock %lu has rate %lu\n", id, rate);
+	debug("clock %lu has rate %lu\n", id, rate);
 	return rate;
 }
 
@@ -876,8 +875,8 @@
 	if (IS_ERR_VALUE(ret))
 		return ret;
 
-	printf("clock %lu has new rate %lu\n", clk->id,
-	       meson_clk_get_rate_by_id(clk, clk->id));
+	debug("clock %lu has new rate %lu\n", clk->id,
+	      meson_clk_get_rate_by_id(clk, clk->id));
 
 	return 0;
 }
@@ -886,9 +885,11 @@
 {
 	struct meson_clk *priv = dev_get_priv(dev);
 
-	priv->addr = dev_read_addr_ptr(dev);
+	priv->map = syscon_node_to_regmap(dev_get_parent(dev)->node);
+	if (IS_ERR(priv->map))
+		return PTR_ERR(priv->map);
 
-	debug("meson-clk: probed at addr %p\n", priv->addr);
+	debug("meson-clk: probed\n");
 
 	return 0;
 }
diff --git a/drivers/clk/clk_meson_axg.c b/drivers/clk/clk_meson_axg.c
new file mode 100644
index 0000000..32cbf75
--- /dev/null
+++ b/drivers/clk/clk_meson_axg.c
@@ -0,0 +1,316 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018 - Beniamino Galvani <b.galvani@gmail.com>
+ * (C) Copyright 2018 - BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <common.h>
+#include <asm/arch/clock-axg.h>
+#include <asm/io.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <div64.h>
+#include <dt-bindings/clock/axg-clkc.h>
+#include "clk_meson.h"
+
+#define XTAL_RATE 24000000
+
+struct meson_clk {
+	struct regmap *map;
+};
+
+static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id);
+
+static struct meson_gate gates[] = {
+	/* Everything Else (EE) domain gates */
+	MESON_GATE(CLKID_SPICC0, HHI_GCLK_MPEG0, 8),
+	MESON_GATE(CLKID_I2C, HHI_GCLK_MPEG0, 9),
+	MESON_GATE(CLKID_UART0, HHI_GCLK_MPEG0, 13),
+	MESON_GATE(CLKID_SPICC1, HHI_GCLK_MPEG0, 15),
+	MESON_GATE(CLKID_SD_EMMC_B, HHI_GCLK_MPEG0, 25),
+	MESON_GATE(CLKID_SD_EMMC_C, HHI_GCLK_MPEG0, 26),
+	MESON_GATE(CLKID_ETH, HHI_GCLK_MPEG1, 3),
+	MESON_GATE(CLKID_UART1, HHI_GCLK_MPEG1, 16),
+
+	/* Always On (AO) domain gates */
+	MESON_GATE(CLKID_AO_I2C, HHI_GCLK_AO, 4),
+
+	/* PLL Gates */
+	/* CLKID_FCLK_DIV2 is critical for the SCPI Processor */
+	MESON_GATE(CLKID_MPLL2, HHI_MPLL_CNTL9, 14),
+	/* CLKID_CLK81 is critical for the system */
+
+	/* Peripheral Gates */
+	MESON_GATE(CLKID_SD_EMMC_B_CLK0, HHI_SD_EMMC_CLK_CNTL, 23),
+	MESON_GATE(CLKID_SD_EMMC_C_CLK0, HHI_NAND_CLK_CNTL, 7),
+};
+
+static int meson_set_gate(struct clk *clk, bool on)
+{
+	struct meson_clk *priv = dev_get_priv(clk->dev);
+	struct meson_gate *gate;
+
+	if (clk->id >= ARRAY_SIZE(gates))
+		return -ENOENT;
+
+	gate = &gates[clk->id];
+
+	if (gate->reg == 0)
+		return 0;
+
+	regmap_update_bits(priv->map, gate->reg,
+			   BIT(gate->bit), on ? BIT(gate->bit) : 0);
+
+	return 0;
+}
+
+static int meson_clk_enable(struct clk *clk)
+{
+	return meson_set_gate(clk, true);
+}
+
+static int meson_clk_disable(struct clk *clk)
+{
+	return meson_set_gate(clk, false);
+}
+
+static unsigned long meson_clk81_get_rate(struct clk *clk)
+{
+	struct meson_clk *priv = dev_get_priv(clk->dev);
+	unsigned long parent_rate;
+	uint reg;
+	int parents[] = {
+		-1,
+		-1,
+		CLKID_FCLK_DIV7,
+		CLKID_MPLL1,
+		CLKID_MPLL2,
+		CLKID_FCLK_DIV4,
+		CLKID_FCLK_DIV3,
+		CLKID_FCLK_DIV5
+	};
+
+	/* mux */
+	regmap_read(priv->map, HHI_MPEG_CLK_CNTL, &reg);
+	reg = (reg >> 12) & 7;
+
+	switch (reg) {
+	case 0:
+		parent_rate = XTAL_RATE;
+		break;
+	case 1:
+		return -ENOENT;
+	default:
+		parent_rate = meson_clk_get_rate_by_id(clk, parents[reg]);
+	}
+
+	/* divider */
+	regmap_read(priv->map, HHI_MPEG_CLK_CNTL, &reg);
+	reg = reg & ((1 << 7) - 1);
+
+	return parent_rate / reg;
+}
+
+static long mpll_rate_from_params(unsigned long parent_rate,
+				  unsigned long sdm,
+				  unsigned long n2)
+{
+	unsigned long divisor = (SDM_DEN * n2) + sdm;
+
+	if (n2 < N2_MIN)
+		return -EINVAL;
+
+	return DIV_ROUND_UP_ULL((u64)parent_rate * SDM_DEN, divisor);
+}
+
+static struct parm meson_mpll0_parm[3] = {
+	{HHI_MPLL_CNTL7, 0, 14}, /* psdm */
+	{HHI_MPLL_CNTL7, 16, 9}, /* pn2 */
+};
+
+static struct parm meson_mpll1_parm[3] = {
+	{HHI_MPLL_CNTL8, 0, 14}, /* psdm */
+	{HHI_MPLL_CNTL8, 16, 9}, /* pn2 */
+};
+
+static struct parm meson_mpll2_parm[3] = {
+	{HHI_MPLL_CNTL9, 0, 14}, /* psdm */
+	{HHI_MPLL_CNTL9, 16, 9}, /* pn2 */
+};
+
+/*
+ * MultiPhase Locked Loops are outputs from a PLL with additional frequency
+ * scaling capabilities. MPLL rates are calculated as:
+ *
+ * f(N2_integer, SDM_IN ) = 2.0G/(N2_integer + SDM_IN/16384)
+ */
+static ulong meson_mpll_get_rate(struct clk *clk, unsigned long id)
+{
+	struct meson_clk *priv = dev_get_priv(clk->dev);
+	struct parm *psdm, *pn2;
+	unsigned long sdm, n2;
+	unsigned long parent_rate;
+	uint reg;
+
+	switch (id) {
+	case CLKID_MPLL0:
+		psdm = &meson_mpll0_parm[0];
+		pn2 = &meson_mpll0_parm[1];
+		break;
+	case CLKID_MPLL1:
+		psdm = &meson_mpll1_parm[0];
+		pn2 = &meson_mpll1_parm[1];
+		break;
+	case CLKID_MPLL2:
+		psdm = &meson_mpll2_parm[0];
+		pn2 = &meson_mpll2_parm[1];
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	parent_rate = meson_clk_get_rate_by_id(clk, CLKID_FIXED_PLL);
+	if (IS_ERR_VALUE(parent_rate))
+		return parent_rate;
+
+	regmap_read(priv->map, psdm->reg_off, &reg);
+	sdm = PARM_GET(psdm->width, psdm->shift, reg);
+
+	regmap_read(priv->map, pn2->reg_off, &reg);
+	n2 = PARM_GET(pn2->width, pn2->shift, reg);
+
+	return mpll_rate_from_params(parent_rate, sdm, n2);
+}
+
+static struct parm meson_fixed_pll_parm[3] = {
+	{HHI_MPLL_CNTL, 0, 9}, /* pm */
+	{HHI_MPLL_CNTL, 9, 5}, /* pn */
+	{HHI_MPLL_CNTL, 16, 2}, /* pod */
+};
+
+static struct parm meson_sys_pll_parm[3] = {
+	{HHI_SYS_PLL_CNTL, 0, 9}, /* pm */
+	{HHI_SYS_PLL_CNTL, 9, 5}, /* pn */
+	{HHI_SYS_PLL_CNTL, 16, 2}, /* pod */
+};
+
+static ulong meson_pll_get_rate(struct clk *clk, unsigned long id)
+{
+	struct meson_clk *priv = dev_get_priv(clk->dev);
+	struct parm *pm, *pn, *pod;
+	unsigned long parent_rate_mhz = XTAL_RATE / 1000000;
+	u16 n, m, od;
+	uint reg;
+
+	switch (id) {
+	case CLKID_FIXED_PLL:
+		pm = &meson_fixed_pll_parm[0];
+		pn = &meson_fixed_pll_parm[1];
+		pod = &meson_fixed_pll_parm[2];
+		break;
+	case CLKID_SYS_PLL:
+		pm = &meson_sys_pll_parm[0];
+		pn = &meson_sys_pll_parm[1];
+		pod = &meson_sys_pll_parm[2];
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	regmap_read(priv->map, pn->reg_off, &reg);
+	n = PARM_GET(pn->width, pn->shift, reg);
+
+	regmap_read(priv->map, pm->reg_off, &reg);
+	m = PARM_GET(pm->width, pm->shift, reg);
+
+	regmap_read(priv->map, pod->reg_off, &reg);
+	od = PARM_GET(pod->width, pod->shift, reg);
+
+	return ((parent_rate_mhz * m / n) >> od) * 1000000;
+}
+
+static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id)
+{
+	ulong rate;
+
+	switch (id) {
+	case CLKID_FIXED_PLL:
+	case CLKID_SYS_PLL:
+		rate = meson_pll_get_rate(clk, id);
+		break;
+	case CLKID_FCLK_DIV2:
+		rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 2;
+		break;
+	case CLKID_FCLK_DIV3:
+		rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 3;
+		break;
+	case CLKID_FCLK_DIV4:
+		rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 4;
+		break;
+	case CLKID_FCLK_DIV5:
+		rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 5;
+		break;
+	case CLKID_FCLK_DIV7:
+		rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 7;
+		break;
+	case CLKID_MPLL0:
+	case CLKID_MPLL1:
+	case CLKID_MPLL2:
+		rate = meson_mpll_get_rate(clk, id);
+		break;
+	case CLKID_CLK81:
+		rate = meson_clk81_get_rate(clk);
+		break;
+	default:
+		if (gates[id].reg != 0) {
+			/* a clock gate */
+			rate = meson_clk81_get_rate(clk);
+			break;
+		}
+		return -ENOENT;
+	}
+
+	debug("clock %lu has rate %lu\n", id, rate);
+	return rate;
+}
+
+static ulong meson_clk_get_rate(struct clk *clk)
+{
+	return meson_clk_get_rate_by_id(clk, clk->id);
+}
+
+static int meson_clk_probe(struct udevice *dev)
+{
+	struct meson_clk *priv = dev_get_priv(dev);
+
+	priv->map = syscon_node_to_regmap(dev_get_parent(dev)->node);
+	if (IS_ERR(priv->map))
+		return PTR_ERR(priv->map);
+
+	debug("meson-clk-axg: probed\n");
+
+	return 0;
+}
+
+static struct clk_ops meson_clk_ops = {
+	.disable	= meson_clk_disable,
+	.enable		= meson_clk_enable,
+	.get_rate	= meson_clk_get_rate,
+};
+
+static const struct udevice_id meson_clk_ids[] = {
+	{ .compatible = "amlogic,axg-clkc" },
+	{ }
+};
+
+U_BOOT_DRIVER(meson_clk_axg) = {
+	.name		= "meson_clk_axg",
+	.id		= UCLASS_CLK,
+	.of_match	= meson_clk_ids,
+	.priv_auto_alloc_size = sizeof(struct meson_clk),
+	.ops		= &meson_clk_ops,
+	.probe		= meson_clk_probe,
+};
diff --git a/drivers/clk/clk_vexpress_osc.c b/drivers/clk/clk_vexpress_osc.c
index 7fef4b2..c692a6d 100644
--- a/drivers/clk/clk_vexpress_osc.c
+++ b/drivers/clk/clk_vexpress_osc.c
@@ -29,7 +29,7 @@
 
 	data = CLK_FUNCTION | priv->osc;
 	err = misc_read(vexpress_cfg, 0, &data, sizeof(data));
-	if (err)
+	if (err < 0)
 		return err;
 
 	return data;
@@ -53,7 +53,7 @@
 	buffer[0] = CLK_FUNCTION | priv->osc;
 	buffer[1] = rate;
 	err = misc_write(vexpress_cfg, 0, buffer, 2 * sizeof(u32));
-	if (err)
+	if (err < 0)
 		return err;
 
 	return rate;
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
new file mode 100644
index 0000000..0632dc8
--- /dev/null
+++ b/drivers/clk/mediatek/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+# Core
+obj-$(CONFIG_ARCH_MEDIATEK) += clk-mtk.o
+
+# SoC Drivers
+obj-$(CONFIG_TARGET_MT7623) += clk-mt7623.o
+obj-$(CONFIG_TARGET_MT7629) += clk-mt7629.o
diff --git a/drivers/clk/mediatek/clk-mt7623.c b/drivers/clk/mediatek/clk-mt7623.c
new file mode 100644
index 0000000..c6b09d8
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7623.c
@@ -0,0 +1,870 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek clock driver for MT7623 SoC
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <dt-bindings/clock/mt7623-clk.h>
+
+#include "clk-mtk.h"
+
+#define MT7623_CLKSQ_STB_CON0		0x18
+#define MT7623_PLL_ISO_CON0		0x24
+#define MT7623_PLL_FMAX			(2000UL * MHZ)
+#define MT7623_CON0_RST_BAR		BIT(27)
+
+#define MCU_AXI_DIV			0x60
+#define AXI_DIV_MSK			GENMASK(4, 0)
+#define AXI_DIV_SEL(x)			(x)
+
+/* apmixedsys */
+#define PLL(_id, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg,	\
+	    _pd_shift, _pcw_reg, _pcw_shift) {				\
+		.id = _id,						\
+		.reg = _reg,						\
+		.pwr_reg = _pwr_reg,					\
+		.en_mask = _en_mask,					\
+		.rst_bar_mask = MT7623_CON0_RST_BAR,			\
+		.fmax = MT7623_PLL_FMAX,				\
+		.flags = _flags,					\
+		.pcwbits = _pcwbits,					\
+		.pd_reg = _pd_reg,					\
+		.pd_shift = _pd_shift,					\
+		.pcw_reg = _pcw_reg,					\
+		.pcw_shift = _pcw_shift,				\
+	}
+
+static const struct mtk_pll_data apmixed_plls[] = {
+	PLL(CLK_APMIXED_ARMPLL, 0x200, 0x20c, 0x80000001, 0,
+	    21, 0x204, 24, 0x204, 0),
+	PLL(CLK_APMIXED_MAINPLL, 0x210, 0x21c, 0xf0000001, HAVE_RST_BAR,
+	    21, 0x210, 4, 0x214, 0),
+	PLL(CLK_APMIXED_UNIVPLL, 0x220, 0x22c, 0xf3000001, HAVE_RST_BAR,
+	    7, 0x220, 4, 0x224, 14),
+	PLL(CLK_APMIXED_MMPLL, 0x230, 0x23c, 0x00000001, 0,
+	    21, 0x230, 4, 0x234, 0),
+	PLL(CLK_APMIXED_MSDCPLL, 0x240, 0x24c, 0x00000001, 0,
+	    21, 0x240, 4, 0x244, 0),
+	PLL(CLK_APMIXED_TVDPLL, 0x250, 0x25c, 0x00000001, 0,
+	    21, 0x250, 4, 0x254, 0),
+	PLL(CLK_APMIXED_AUD1PLL, 0x270, 0x27c, 0x00000001, 0,
+	    31, 0x270, 4, 0x274, 0),
+	PLL(CLK_APMIXED_TRGPLL, 0x280, 0x28c, 0x00000001, 0,
+	    31, 0x280, 4, 0x284, 0),
+	PLL(CLK_APMIXED_ETHPLL, 0x290, 0x29c, 0x00000001, 0,
+	    31, 0x290, 4, 0x294, 0),
+	PLL(CLK_APMIXED_VDECPLL, 0x2a0, 0x2ac, 0x00000001, 0,
+	    31, 0x2a0, 4, 0x2a4, 0),
+	PLL(CLK_APMIXED_HADDS2PLL, 0x2b0, 0x2bc, 0x00000001, 0,
+	    31, 0x2b0, 4, 0x2b4, 0),
+	PLL(CLK_APMIXED_AUD2PLL, 0x2c0, 0x2cc, 0x00000001, 0,
+	    31, 0x2c0, 4, 0x2c4, 0),
+	PLL(CLK_APMIXED_TVD2PLL, 0x2d0, 0x2dc, 0x00000001, 0,
+	    21, 0x2d0, 4, 0x2d4, 0),
+};
+
+/* topckgen */
+#define FACTOR0(_id, _parent, _mult, _div)			\
+	FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED)
+
+#define FACTOR1(_id, _parent, _mult, _div)			\
+	FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN)
+
+#define FACTOR2(_id, _parent, _mult, _div)			\
+	FACTOR(_id, _parent, _mult, _div, 0)
+
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+	FIXED_CLK(CLK_TOP_DPI, CLK_XTAL, 108 * MHZ),
+	FIXED_CLK(CLK_TOP_DMPLL, CLK_XTAL, 400 * MHZ),
+	FIXED_CLK(CLK_TOP_VENCPLL, CLK_XTAL, 295.75 * MHZ),
+	FIXED_CLK(CLK_TOP_HDMI_0_PIX340M, CLK_XTAL, 340 * MHZ),
+	FIXED_CLK(CLK_TOP_HDMI_0_DEEP340M, CLK_XTAL, 340 * MHZ),
+	FIXED_CLK(CLK_TOP_HDMI_0_PLL340M, CLK_XTAL, 340 * MHZ),
+	FIXED_CLK(CLK_TOP_HADDS2_FB, CLK_XTAL, 27 * MHZ),
+	FIXED_CLK(CLK_TOP_WBG_DIG_416M, CLK_XTAL, 416 * MHZ),
+	FIXED_CLK(CLK_TOP_DSI0_LNTC_DSI, CLK_XTAL, 143 * MHZ),
+	FIXED_CLK(CLK_TOP_HDMI_SCL_RX, CLK_XTAL, 27 * MHZ),
+	FIXED_CLK(CLK_TOP_32K_EXTERNAL, CLK_XTAL, 32000),
+	FIXED_CLK(CLK_TOP_HDMITX_CLKDIG_CTS, CLK_XTAL, 300 * MHZ),
+	FIXED_CLK(CLK_TOP_AUD_EXT1, CLK_XTAL, 0),
+	FIXED_CLK(CLK_TOP_AUD_EXT2, CLK_XTAL, 0),
+	FIXED_CLK(CLK_TOP_NFI1X_PAD, CLK_XTAL, 0),
+};
+
+static const struct mtk_fixed_factor top_fixed_divs[] = {
+	FACTOR0(CLK_TOP_SYSPLL, CLK_APMIXED_MAINPLL, 1, 1),
+	FACTOR0(CLK_TOP_SYSPLL_D2, CLK_APMIXED_MAINPLL, 1, 2),
+	FACTOR0(CLK_TOP_SYSPLL_D3, CLK_APMIXED_MAINPLL, 1, 3),
+	FACTOR0(CLK_TOP_SYSPLL_D5, CLK_APMIXED_MAINPLL, 1, 5),
+	FACTOR0(CLK_TOP_SYSPLL_D7, CLK_APMIXED_MAINPLL, 1, 7),
+	FACTOR1(CLK_TOP_SYSPLL1_D2, CLK_TOP_SYSPLL_D2, 1, 2),
+	FACTOR1(CLK_TOP_SYSPLL1_D4, CLK_TOP_SYSPLL_D2, 1, 4),
+	FACTOR1(CLK_TOP_SYSPLL1_D8, CLK_TOP_SYSPLL_D2, 1, 8),
+	FACTOR1(CLK_TOP_SYSPLL1_D16, CLK_TOP_SYSPLL_D2, 1, 16),
+	FACTOR1(CLK_TOP_SYSPLL2_D2, CLK_TOP_SYSPLL_D3, 1, 2),
+	FACTOR1(CLK_TOP_SYSPLL2_D4, CLK_TOP_SYSPLL_D3, 1, 4),
+	FACTOR1(CLK_TOP_SYSPLL2_D8, CLK_TOP_SYSPLL_D3, 1, 8),
+	FACTOR1(CLK_TOP_SYSPLL3_D2, CLK_TOP_SYSPLL_D5, 1, 2),
+	FACTOR1(CLK_TOP_SYSPLL3_D4, CLK_TOP_SYSPLL_D5, 1, 4),
+	FACTOR1(CLK_TOP_SYSPLL4_D2, CLK_TOP_SYSPLL_D7, 1, 2),
+	FACTOR1(CLK_TOP_SYSPLL4_D4, CLK_TOP_SYSPLL_D7, 1, 4),
+
+	FACTOR0(CLK_TOP_UNIVPLL, CLK_APMIXED_UNIVPLL, 1, 1),
+	FACTOR0(CLK_TOP_UNIVPLL_D2, CLK_APMIXED_UNIVPLL, 1, 2),
+	FACTOR0(CLK_TOP_UNIVPLL_D3, CLK_APMIXED_UNIVPLL, 1, 3),
+	FACTOR0(CLK_TOP_UNIVPLL_D5, CLK_APMIXED_UNIVPLL, 1, 5),
+	FACTOR0(CLK_TOP_UNIVPLL_D7, CLK_APMIXED_UNIVPLL, 1, 7),
+	FACTOR0(CLK_TOP_UNIVPLL_D26, CLK_APMIXED_UNIVPLL, 1, 26),
+	FACTOR0(CLK_TOP_UNIVPLL_D52, CLK_APMIXED_UNIVPLL, 1, 52),
+	FACTOR0(CLK_TOP_UNIVPLL_D108, CLK_APMIXED_UNIVPLL, 1, 108),
+	FACTOR0(CLK_TOP_USB_PHY48M, CLK_APMIXED_UNIVPLL, 1, 26),
+	FACTOR1(CLK_TOP_UNIVPLL1_D2, CLK_TOP_UNIVPLL_D2, 1, 2),
+	FACTOR1(CLK_TOP_UNIVPLL1_D4, CLK_TOP_UNIVPLL_D2, 1, 4),
+	FACTOR1(CLK_TOP_UNIVPLL1_D8, CLK_TOP_UNIVPLL_D2, 1, 8),
+	FACTOR1(CLK_TOP_UNIVPLL2_D2, CLK_TOP_UNIVPLL_D3, 1, 2),
+	FACTOR1(CLK_TOP_UNIVPLL2_D4, CLK_TOP_UNIVPLL_D3, 1, 4),
+	FACTOR1(CLK_TOP_UNIVPLL2_D8, CLK_TOP_UNIVPLL_D3, 1, 8),
+	FACTOR1(CLK_TOP_UNIVPLL2_D16, CLK_TOP_UNIVPLL_D3, 1, 16),
+	FACTOR1(CLK_TOP_UNIVPLL2_D32, CLK_TOP_UNIVPLL_D3, 1, 32),
+	FACTOR1(CLK_TOP_UNIVPLL3_D2, CLK_TOP_UNIVPLL_D5, 1, 2),
+	FACTOR1(CLK_TOP_UNIVPLL3_D4, CLK_TOP_UNIVPLL_D5, 1, 4),
+	FACTOR1(CLK_TOP_UNIVPLL3_D8, CLK_TOP_UNIVPLL_D5, 1, 8),
+
+	FACTOR0(CLK_TOP_MSDCPLL, CLK_APMIXED_MSDCPLL, 1, 1),
+	FACTOR0(CLK_TOP_MSDCPLL_D2, CLK_APMIXED_MSDCPLL, 1, 2),
+	FACTOR0(CLK_TOP_MSDCPLL_D4, CLK_APMIXED_MSDCPLL, 1, 4),
+	FACTOR0(CLK_TOP_MSDCPLL_D8, CLK_APMIXED_MSDCPLL, 1, 8),
+
+	FACTOR0(CLK_TOP_MMPLL, CLK_APMIXED_MMPLL, 1, 1),
+	FACTOR0(CLK_TOP_MMPLL_D2, CLK_APMIXED_MMPLL, 1, 2),
+
+	FACTOR1(CLK_TOP_DMPLL_D2, CLK_TOP_DMPLL, 1, 2),
+	FACTOR1(CLK_TOP_DMPLL_D4, CLK_TOP_DMPLL, 1, 4),
+	FACTOR1(CLK_TOP_DMPLL_X2, CLK_TOP_DMPLL, 1, 1),
+
+	FACTOR0(CLK_TOP_TVDPLL, CLK_APMIXED_TVDPLL, 1, 1),
+	FACTOR0(CLK_TOP_TVDPLL_D2, CLK_APMIXED_TVDPLL, 1, 2),
+	FACTOR0(CLK_TOP_TVDPLL_D4, CLK_APMIXED_TVDPLL, 1, 4),
+
+	FACTOR0(CLK_TOP_VDECPLL, CLK_APMIXED_VDECPLL, 1, 1),
+	FACTOR0(CLK_TOP_TVD2PLL, CLK_APMIXED_TVD2PLL, 1, 1),
+	FACTOR0(CLK_TOP_TVD2PLL_D2, CLK_APMIXED_TVD2PLL, 1, 2),
+
+	FACTOR1(CLK_TOP_MIPIPLL, CLK_TOP_DPI, 1, 1),
+	FACTOR1(CLK_TOP_MIPIPLL_D2, CLK_TOP_DPI, 1, 2),
+	FACTOR1(CLK_TOP_MIPIPLL_D4, CLK_TOP_DPI, 1, 4),
+
+	FACTOR1(CLK_TOP_HDMIPLL, CLK_TOP_HDMITX_CLKDIG_CTS, 1, 1),
+	FACTOR1(CLK_TOP_HDMIPLL_D2, CLK_TOP_HDMITX_CLKDIG_CTS, 1, 2),
+	FACTOR1(CLK_TOP_HDMIPLL_D3, CLK_TOP_HDMITX_CLKDIG_CTS, 1, 3),
+
+	FACTOR0(CLK_TOP_ARMPLL_1P3G, CLK_APMIXED_ARMPLL, 1, 1),
+
+	FACTOR1(CLK_TOP_AUDPLL, CLK_TOP_AUDPLL_MUX_SEL, 1, 1),
+	FACTOR1(CLK_TOP_AUDPLL_D4, CLK_TOP_AUDPLL_MUX_SEL, 1, 4),
+	FACTOR1(CLK_TOP_AUDPLL_D8, CLK_TOP_AUDPLL_MUX_SEL, 1, 8),
+	FACTOR1(CLK_TOP_AUDPLL_D16, CLK_TOP_AUDPLL_MUX_SEL, 1, 16),
+	FACTOR1(CLK_TOP_AUDPLL_D24, CLK_TOP_AUDPLL_MUX_SEL, 1, 24),
+
+	FACTOR0(CLK_TOP_AUD1PLL_98M, CLK_APMIXED_AUD1PLL, 1, 3),
+	FACTOR0(CLK_TOP_AUD2PLL_90M, CLK_APMIXED_AUD2PLL, 1, 3),
+	FACTOR0(CLK_TOP_HADDS2PLL_98M, CLK_APMIXED_HADDS2PLL, 1, 3),
+	FACTOR0(CLK_TOP_HADDS2PLL_294M, CLK_APMIXED_HADDS2PLL, 1, 1),
+	FACTOR0(CLK_TOP_ETHPLL_500M, CLK_APMIXED_ETHPLL, 1, 1),
+	FACTOR2(CLK_TOP_CLK26M_D8, CLK_XTAL, 1, 8),
+	FACTOR2(CLK_TOP_32K_INTERNAL, CLK_XTAL, 1, 793),
+	FACTOR1(CLK_TOP_AXISEL_D4, CLK_TOP_AXI_SEL, 1, 4),
+	FACTOR1(CLK_TOP_8BDAC, CLK_TOP_UNIVPLL_D2, 1, 1),
+};
+
+static const int axi_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D2,
+	CLK_TOP_SYSPLL_D5,
+	CLK_TOP_SYSPLL1_D4,
+	CLK_TOP_UNIVPLL_D5,
+	CLK_TOP_UNIVPLL2_D2,
+	CLK_TOP_MMPLL_D2,
+	CLK_TOP_DMPLL_D2
+};
+
+static const int mem_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_DMPLL
+};
+
+static const int ddrphycfg_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D8
+};
+
+static const int mm_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_VENCPLL,
+	CLK_TOP_SYSPLL1_D2,
+	CLK_TOP_SYSPLL1_D4,
+	CLK_TOP_UNIVPLL_D5,
+	CLK_TOP_UNIVPLL1_D2,
+	CLK_TOP_UNIVPLL2_D2,
+	CLK_TOP_DMPLL
+};
+
+static const int pwm_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL2_D4,
+	CLK_TOP_UNIVPLL3_D2,
+	CLK_TOP_UNIVPLL1_D4
+};
+
+static const int vdec_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_VDECPLL,
+	CLK_TOP_SYSPLL_D5,
+	CLK_TOP_SYSPLL1_D4,
+	CLK_TOP_UNIVPLL_D5,
+	CLK_TOP_UNIVPLL2_D2,
+	CLK_TOP_VENCPLL,
+	CLK_TOP_MSDCPLL_D2,
+	CLK_TOP_MMPLL_D2
+};
+
+static const int mfg_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_MMPLL,
+	CLK_TOP_DMPLL_X2,
+	CLK_TOP_MSDCPLL,
+	CLK_XTAL,
+	CLK_TOP_SYSPLL_D3,
+	CLK_TOP_UNIVPLL_D3,
+	CLK_TOP_UNIVPLL1_D2
+};
+
+static const int camtg_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL_D26,
+	CLK_TOP_UNIVPLL2_D2,
+	CLK_TOP_SYSPLL3_D2,
+	CLK_TOP_SYSPLL3_D4,
+	CLK_TOP_MSDCPLL_D2,
+	CLK_TOP_MMPLL_D2
+};
+
+static const int uart_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL2_D8
+};
+
+static const int spi_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL3_D2,
+	CLK_TOP_SYSPLL4_D2,
+	CLK_TOP_UNIVPLL2_D4,
+	CLK_TOP_UNIVPLL1_D8
+};
+
+static const int usb20_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL1_D8,
+	CLK_TOP_UNIVPLL3_D4
+};
+
+static const int msdc30_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_MSDCPLL_D2,
+	CLK_TOP_SYSPLL2_D2,
+	CLK_TOP_SYSPLL1_D4,
+	CLK_TOP_UNIVPLL1_D4,
+	CLK_TOP_UNIVPLL2_D4,
+};
+
+static const int aud_intbus_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D4,
+	CLK_TOP_SYSPLL3_D2,
+	CLK_TOP_SYSPLL4_D2,
+	CLK_TOP_UNIVPLL3_D2,
+	CLK_TOP_UNIVPLL2_D4
+};
+
+static const int pmicspi_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D8,
+	CLK_TOP_SYSPLL2_D4,
+	CLK_TOP_SYSPLL4_D2,
+	CLK_TOP_SYSPLL3_D4,
+	CLK_TOP_SYSPLL2_D8,
+	CLK_TOP_SYSPLL1_D16,
+	CLK_TOP_UNIVPLL3_D4,
+	CLK_TOP_UNIVPLL_D26,
+	CLK_TOP_DMPLL_D2,
+	CLK_TOP_DMPLL_D4
+};
+
+static const int scp_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D8,
+	CLK_TOP_DMPLL_D2,
+	CLK_TOP_DMPLL_D4
+};
+
+static const int dpi0_tve_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_MIPIPLL,
+	CLK_TOP_MIPIPLL_D2,
+	CLK_TOP_MIPIPLL_D4,
+	CLK_XTAL,
+	CLK_TOP_TVDPLL,
+	CLK_TOP_TVDPLL_D2,
+	CLK_TOP_TVDPLL_D4
+};
+
+static const int dpi1_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_TVDPLL,
+	CLK_TOP_TVDPLL_D2,
+	CLK_TOP_TVDPLL_D4
+};
+
+static const int hdmi_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_HDMIPLL,
+	CLK_TOP_HDMIPLL_D2,
+	CLK_TOP_HDMIPLL_D3
+};
+
+static const int apll_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_AUDPLL,
+	CLK_TOP_AUDPLL_D4,
+	CLK_TOP_AUDPLL_D8,
+	CLK_TOP_AUDPLL_D16,
+	CLK_TOP_AUDPLL_D24,
+	CLK_XTAL,
+	CLK_XTAL
+};
+
+static const int rtc_parents[] = {
+	CLK_TOP_32K_INTERNAL,
+	CLK_TOP_32K_EXTERNAL,
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL3_D8
+};
+
+static const int nfi2x_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL2_D2,
+	CLK_TOP_SYSPLL_D7,
+	CLK_TOP_UNIVPLL3_D2,
+	CLK_TOP_SYSPLL2_D4,
+	CLK_TOP_UNIVPLL3_D4,
+	CLK_TOP_SYSPLL4_D4,
+	CLK_XTAL
+};
+
+static const int emmc_hclk_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D2,
+	CLK_TOP_SYSPLL1_D4,
+	CLK_TOP_SYSPLL2_D2
+};
+
+static const int flash_parents[] = {
+	CLK_TOP_CLK26M_D8,
+	CLK_XTAL,
+	CLK_TOP_SYSPLL2_D8,
+	CLK_TOP_SYSPLL3_D4,
+	CLK_TOP_UNIVPLL3_D4,
+	CLK_TOP_SYSPLL4_D2,
+	CLK_TOP_SYSPLL2_D4,
+	CLK_TOP_UNIVPLL2_D4
+};
+
+static const int di_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_TVD2PLL,
+	CLK_TOP_TVD2PLL_D2,
+	CLK_XTAL
+};
+
+static const int nr_osd_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_VENCPLL,
+	CLK_TOP_SYSPLL1_D2,
+	CLK_TOP_SYSPLL1_D4,
+	CLK_TOP_UNIVPLL_D5,
+	CLK_TOP_UNIVPLL1_D2,
+	CLK_TOP_UNIVPLL2_D2,
+	CLK_TOP_DMPLL
+};
+
+static const int hdmirx_bist_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL_D3,
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D16,
+	CLK_TOP_SYSPLL4_D2,
+	CLK_TOP_SYSPLL1_D4,
+	CLK_TOP_VENCPLL,
+	CLK_XTAL
+};
+
+static const int intdir_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_MMPLL,
+	CLK_TOP_SYSPLL_D2,
+	CLK_TOP_UNIVPLL_D2
+};
+
+static const int asm_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL2_D4,
+	CLK_TOP_UNIVPLL2_D2,
+	CLK_TOP_SYSPLL_D5
+};
+
+static const int ms_card_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL3_D8,
+	CLK_TOP_SYSPLL4_D4
+};
+
+static const int ethif_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D2,
+	CLK_TOP_SYSPLL_D5,
+	CLK_TOP_SYSPLL1_D4,
+	CLK_TOP_UNIVPLL_D5,
+	CLK_TOP_UNIVPLL1_D2,
+	CLK_TOP_DMPLL,
+	CLK_TOP_DMPLL_D2
+};
+
+static const int hdmirx_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL_D52
+};
+
+static const int cmsys_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D2,
+	CLK_TOP_UNIVPLL1_D2,
+	CLK_TOP_UNIVPLL_D5,
+	CLK_TOP_SYSPLL_D5,
+	CLK_TOP_SYSPLL2_D2,
+	CLK_TOP_SYSPLL1_D4,
+	CLK_TOP_SYSPLL3_D2,
+	CLK_TOP_SYSPLL2_D4,
+	CLK_TOP_SYSPLL1_D8,
+	CLK_XTAL,
+	CLK_XTAL,
+	CLK_XTAL,
+	CLK_XTAL,
+	CLK_XTAL
+};
+
+static const int clk_8bdac_parents[] = {
+	CLK_TOP_32K_INTERNAL,
+	CLK_TOP_8BDAC,
+	CLK_XTAL,
+	CLK_XTAL
+};
+
+static const int aud2dvd_parents[] = {
+	CLK_TOP_AUD_48K_TIMING,
+	CLK_TOP_AUD_44K_TIMING
+};
+
+static const int padmclk_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL_D26,
+	CLK_TOP_UNIVPLL_D52,
+	CLK_TOP_UNIVPLL_D108,
+	CLK_TOP_UNIVPLL2_D8,
+	CLK_TOP_UNIVPLL2_D16,
+	CLK_TOP_UNIVPLL2_D32
+};
+
+static const int aud_mux_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_AUD1PLL_98M,
+	CLK_TOP_AUD2PLL_90M,
+	CLK_TOP_HADDS2PLL_98M,
+	CLK_TOP_AUD_EXTCK1_DIV,
+	CLK_TOP_AUD_EXTCK2_DIV
+};
+
+static const int aud_src_parents[] = {
+	CLK_TOP_AUD_MUX1_SEL,
+	CLK_TOP_AUD_MUX2_SEL
+};
+
+static const struct mtk_composite top_muxes[] = {
+	MUX_GATE(CLK_TOP_AXI_SEL, axi_parents, 0x40, 0, 3, 7),
+	MUX_GATE(CLK_TOP_MEM_SEL, mem_parents, 0x40, 8, 1, 15),
+	MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, ddrphycfg_parents, 0x40, 16, 1, 23),
+	MUX_GATE_FLAGS(CLK_TOP_MM_SEL, mm_parents, 0x40, 24, 3, 31,
+		       CLK_DOMAIN_SCPSYS),
+
+	MUX_GATE(CLK_TOP_PWM_SEL, pwm_parents, 0x50, 0, 2, 7),
+	MUX_GATE(CLK_TOP_VDEC_SEL, vdec_parents, 0x50, 8, 4, 15),
+	MUX_GATE_FLAGS(CLK_TOP_MFG_SEL, mfg_parents, 0x50, 16, 3, 23,
+		       CLK_DOMAIN_SCPSYS),
+	MUX_GATE(CLK_TOP_CAMTG_SEL, camtg_parents, 0x50, 24, 3, 31),
+
+	MUX_GATE(CLK_TOP_UART_SEL, uart_parents, 0x60, 0, 1, 7),
+	MUX_GATE(CLK_TOP_SPI0_SEL, spi_parents, 0x60, 8, 3, 15),
+	MUX_GATE(CLK_TOP_USB20_SEL, usb20_parents, 0x60, 16, 2, 23),
+	MUX_GATE(CLK_TOP_MSDC30_0_SEL, msdc30_parents, 0x60, 24, 3, 31),
+
+	MUX_GATE(CLK_TOP_MSDC30_1_SEL, msdc30_parents, 0x70, 0, 3, 7),
+	MUX_GATE(CLK_TOP_MSDC30_2_SEL, msdc30_parents, 0x70, 8, 3, 15),
+	MUX_GATE(CLK_TOP_AUDIO_SEL, msdc30_parents, 0x70, 16, 1, 23),
+	MUX_GATE(CLK_TOP_AUDINTBUS_SEL, aud_intbus_parents, 0x70, 24, 3, 31),
+
+	MUX_GATE(CLK_TOP_PMICSPI_SEL, pmicspi_parents, 0x80, 0, 4, 7),
+	MUX_GATE(CLK_TOP_SCP_SEL, scp_parents, 0x80, 8, 2, 15),
+	MUX_GATE(CLK_TOP_DPI0_SEL, dpi0_tve_parents, 0x80, 16, 3, 23),
+	MUX_GATE(CLK_TOP_DPI1_SEL, dpi1_parents, 0x80, 24, 2, 31),
+
+	MUX_GATE(CLK_TOP_TVE_SEL, dpi0_tve_parents, 0x90, 0, 3, 7),
+	MUX_GATE(CLK_TOP_HDMI_SEL, hdmi_parents, 0x90, 8, 2, 15),
+	MUX_GATE(CLK_TOP_APLL_SEL, apll_parents, 0x90, 16, 3, 23),
+
+	MUX_GATE(CLK_TOP_RTC_SEL, rtc_parents, 0xA0, 0, 2, 7),
+	MUX_GATE(CLK_TOP_NFI2X_SEL, nfi2x_parents, 0xA0, 8, 3, 15),
+	MUX_GATE(CLK_TOP_EMMC_HCLK_SEL, emmc_hclk_parents, 0xA0, 24, 2, 31),
+
+	MUX_GATE(CLK_TOP_FLASH_SEL, flash_parents, 0xB0, 0, 3, 7),
+	MUX_GATE(CLK_TOP_DI_SEL, di_parents, 0xB0, 8, 2, 15),
+	MUX_GATE(CLK_TOP_NR_SEL, nr_osd_parents, 0xB0, 16, 3, 23),
+	MUX_GATE(CLK_TOP_OSD_SEL, nr_osd_parents, 0xB0, 24, 3, 31),
+
+	MUX_GATE(CLK_TOP_HDMIRX_BIST_SEL, hdmirx_bist_parents, 0xC0, 0, 3, 7),
+	MUX_GATE(CLK_TOP_INTDIR_SEL, intdir_parents, 0xC0, 8, 2, 15),
+	MUX_GATE(CLK_TOP_ASM_I_SEL, asm_parents, 0xC0, 16, 2, 23),
+	MUX_GATE(CLK_TOP_ASM_M_SEL, asm_parents, 0xC0, 24, 3, 31),
+
+	MUX_GATE(CLK_TOP_ASM_H_SEL, asm_parents, 0xD0, 0, 2, 7),
+	MUX_GATE(CLK_TOP_MS_CARD_SEL, ms_card_parents, 0xD0, 16, 2, 23),
+	MUX_GATE_FLAGS(CLK_TOP_ETHIF_SEL, ethif_parents, 0xD0, 24, 3, 31,
+		       CLK_DOMAIN_SCPSYS),
+
+	MUX_GATE(CLK_TOP_HDMIRX26_24_SEL, hdmirx_parents, 0xE0, 0, 1, 7),
+	MUX_GATE(CLK_TOP_MSDC30_3_SEL, msdc30_parents, 0xE0, 8, 3, 15),
+	MUX_GATE(CLK_TOP_CMSYS_SEL, cmsys_parents, 0xE0, 16, 4, 23),
+
+	MUX_GATE(CLK_TOP_SPI1_SEL, spi_parents, 0xE0, 24, 3, 31),
+	MUX_GATE(CLK_TOP_SPI2_SEL, spi_parents, 0xF0, 0, 3, 7),
+	MUX_GATE(CLK_TOP_8BDAC_SEL, clk_8bdac_parents, 0xF0, 8, 2, 15),
+	MUX_GATE(CLK_TOP_AUD2DVD_SEL, aud2dvd_parents, 0xF0, 16, 1, 23),
+
+	MUX(CLK_TOP_PADMCLK_SEL, padmclk_parents, 0x100, 0, 3),
+
+	MUX(CLK_TOP_AUD_MUX1_SEL, aud_mux_parents, 0x12c, 0, 3),
+	MUX(CLK_TOP_AUD_MUX2_SEL, aud_mux_parents, 0x12c, 3, 3),
+	MUX(CLK_TOP_AUDPLL_MUX_SEL, aud_mux_parents, 0x12c, 6, 3),
+
+	MUX_GATE(CLK_TOP_AUD_K1_SRC_SEL, aud_src_parents, 0x12c, 15, 1, 23),
+	MUX_GATE(CLK_TOP_AUD_K2_SRC_SEL, aud_src_parents, 0x12c, 16, 1, 24),
+	MUX_GATE(CLK_TOP_AUD_K3_SRC_SEL, aud_src_parents, 0x12c, 17, 1, 25),
+	MUX_GATE(CLK_TOP_AUD_K4_SRC_SEL, aud_src_parents, 0x12c, 18, 1, 26),
+	MUX_GATE(CLK_TOP_AUD_K5_SRC_SEL, aud_src_parents, 0x12c, 19, 1, 27),
+	MUX_GATE(CLK_TOP_AUD_K6_SRC_SEL, aud_src_parents, 0x12c, 20, 1, 28),
+};
+
+/* infracfg */
+static const struct mtk_gate_regs infra_cg_regs = {
+	.set_ofs = 0x40,
+	.clr_ofs = 0x44,
+	.sta_ofs = 0x48,
+};
+
+#define GATE_INFRA(_id, _parent, _shift) {			\
+		.id = _id,					\
+		.parent = _parent,				\
+		.regs = &infra_cg_regs,				\
+		.shift = _shift,				\
+		.flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN,	\
+	}
+
+static const struct mtk_gate infra_cgs[] = {
+	GATE_INFRA(CLK_INFRA_DBG, CLK_TOP_AXI_SEL, 0),
+	GATE_INFRA(CLK_INFRA_SMI, CLK_TOP_MM_SEL, 1),
+	GATE_INFRA(CLK_INFRA_QAXI_CM4, CLK_TOP_AXI_SEL, 2),
+	GATE_INFRA(CLK_INFRA_AUD_SPLIN_B, CLK_TOP_HADDS2PLL_294M, 4),
+	GATE_INFRA(CLK_INFRA_AUDIO, CLK_XTAL, 5),
+	GATE_INFRA(CLK_INFRA_EFUSE, CLK_XTAL, 6),
+	GATE_INFRA(CLK_INFRA_L2C_SRAM, CLK_TOP_MM_SEL, 7),
+	GATE_INFRA(CLK_INFRA_M4U, CLK_TOP_MEM_SEL, 8),
+	GATE_INFRA(CLK_INFRA_CONNMCU, CLK_TOP_WBG_DIG_416M, 12),
+	GATE_INFRA(CLK_INFRA_TRNG, CLK_TOP_AXI_SEL, 13),
+	GATE_INFRA(CLK_INFRA_RAMBUFIF, CLK_TOP_MEM_SEL, 14),
+	GATE_INFRA(CLK_INFRA_CPUM, CLK_TOP_MEM_SEL, 15),
+	GATE_INFRA(CLK_INFRA_KP, CLK_TOP_AXI_SEL, 16),
+	GATE_INFRA(CLK_INFRA_CEC, CLK_TOP_RTC_SEL, 18),
+	GATE_INFRA(CLK_INFRA_IRRX, CLK_TOP_AXI_SEL, 19),
+	GATE_INFRA(CLK_INFRA_PMICSPI, CLK_TOP_PMICSPI_SEL, 22),
+	GATE_INFRA(CLK_INFRA_PMICWRAP, CLK_TOP_AXI_SEL, 23),
+	GATE_INFRA(CLK_INFRA_DDCCI, CLK_TOP_AXI_SEL, 24),
+};
+
+/* pericfg */
+static const struct mtk_gate_regs peri0_cg_regs = {
+	.set_ofs = 0x8,
+	.clr_ofs = 0x10,
+	.sta_ofs = 0x18,
+};
+
+static const struct mtk_gate_regs peri1_cg_regs = {
+	.set_ofs = 0xC,
+	.clr_ofs = 0x14,
+	.sta_ofs = 0x1C,
+};
+
+#define GATE_PERI0(_id, _parent, _shift) {			\
+		.id = _id,					\
+		.parent = _parent,				\
+		.regs = &peri0_cg_regs,				\
+		.shift = _shift,				\
+		.flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN,	\
+	}
+
+#define GATE_PERI1(_id, _parent, _shift) {			\
+		.id = _id,					\
+		.parent = _parent,				\
+		.regs = &peri1_cg_regs,				\
+		.shift = _shift,				\
+		.flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN,	\
+	}
+
+static const struct mtk_gate peri_cgs[] = {
+	GATE_PERI0(CLK_PERI_NFI, CLK_TOP_NFI2X_SEL, 0),
+	GATE_PERI0(CLK_PERI_THERM, CLK_TOP_AXI_SEL, 1),
+	GATE_PERI0(CLK_PERI_PWM1, CLK_TOP_AXISEL_D4, 2),
+	GATE_PERI0(CLK_PERI_PWM2, CLK_TOP_AXISEL_D4, 3),
+	GATE_PERI0(CLK_PERI_PWM3, CLK_TOP_AXISEL_D4, 4),
+	GATE_PERI0(CLK_PERI_PWM4, CLK_TOP_AXISEL_D4, 5),
+	GATE_PERI0(CLK_PERI_PWM5, CLK_TOP_AXISEL_D4, 6),
+	GATE_PERI0(CLK_PERI_PWM6, CLK_TOP_AXISEL_D4, 7),
+	GATE_PERI0(CLK_PERI_PWM7, CLK_TOP_AXISEL_D4, 8),
+	GATE_PERI0(CLK_PERI_PWM, CLK_TOP_AXI_SEL, 9),
+	GATE_PERI0(CLK_PERI_USB0, CLK_TOP_USB20_SEL, 10),
+	GATE_PERI0(CLK_PERI_USB1, CLK_TOP_USB20_SEL, 11),
+	GATE_PERI0(CLK_PERI_AP_DMA, CLK_TOP_AXI_SEL, 12),
+	GATE_PERI0(CLK_PERI_MSDC30_0, CLK_TOP_MSDC30_0_SEL, 13),
+	GATE_PERI0(CLK_PERI_MSDC30_1, CLK_TOP_MSDC30_1_SEL, 14),
+	GATE_PERI0(CLK_PERI_MSDC30_2, CLK_TOP_MSDC30_2_SEL, 15),
+	GATE_PERI0(CLK_PERI_MSDC30_3, CLK_TOP_MSDC30_3_SEL, 16),
+	GATE_PERI0(CLK_PERI_MSDC50_3, CLK_TOP_EMMC_HCLK_SEL, 17),
+	GATE_PERI0(CLK_PERI_NLI, CLK_TOP_AXI_SEL, 18),
+	GATE_PERI0(CLK_PERI_UART0, CLK_TOP_AXI_SEL, 19),
+	GATE_PERI0(CLK_PERI_UART1, CLK_TOP_AXI_SEL, 20),
+	GATE_PERI0(CLK_PERI_UART2, CLK_TOP_AXI_SEL, 21),
+	GATE_PERI0(CLK_PERI_UART3, CLK_TOP_AXI_SEL, 22),
+	GATE_PERI0(CLK_PERI_BTIF, CLK_TOP_AXI_SEL, 23),
+	GATE_PERI0(CLK_PERI_I2C0, CLK_TOP_AXI_SEL, 24),
+	GATE_PERI0(CLK_PERI_I2C1, CLK_TOP_AXI_SEL, 25),
+	GATE_PERI0(CLK_PERI_I2C2, CLK_TOP_AXI_SEL, 26),
+	GATE_PERI0(CLK_PERI_I2C3, CLK_XTAL, 27),
+	GATE_PERI0(CLK_PERI_AUXADC, CLK_XTAL, 28),
+	GATE_PERI0(CLK_PERI_SPI0, CLK_TOP_SPI0_SEL, 29),
+	GATE_PERI0(CLK_PERI_ETH, CLK_XTAL, 30),
+	GATE_PERI0(CLK_PERI_USB0_MCU, CLK_TOP_AXI_SEL, 31),
+
+	GATE_PERI1(CLK_PERI_USB1_MCU, CLK_TOP_AXI_SEL, 0),
+	GATE_PERI1(CLK_PERI_USB_SLV, CLK_TOP_AXI_SEL, 1),
+	GATE_PERI1(CLK_PERI_GCPU, CLK_TOP_AXI_SEL, 2),
+	GATE_PERI1(CLK_PERI_NFI_ECC, CLK_TOP_NFI1X_PAD, 3),
+	GATE_PERI1(CLK_PERI_NFI_PAD, CLK_TOP_NFI1X_PAD, 4),
+	GATE_PERI1(CLK_PERI_FLASH, CLK_TOP_NFI2X_SEL, 5),
+	GATE_PERI1(CLK_PERI_HOST89_INT, CLK_TOP_AXI_SEL, 6),
+	GATE_PERI1(CLK_PERI_HOST89_SPI, CLK_TOP_SPI0_SEL, 7),
+	GATE_PERI1(CLK_PERI_HOST89_DVD, CLK_TOP_AUD2DVD_SEL, 8),
+	GATE_PERI1(CLK_PERI_SPI1, CLK_TOP_SPI1_SEL, 9),
+	GATE_PERI1(CLK_PERI_SPI2, CLK_TOP_SPI2_SEL, 10),
+	GATE_PERI1(CLK_PERI_FCI, CLK_TOP_MS_CARD_SEL, 11),
+};
+
+/* ethsys */
+static const struct mtk_gate_regs eth_cg_regs = {
+	.sta_ofs = 0x30,
+};
+
+#define GATE_ETH(_id, _parent, _shift, _flag) {			\
+		.id = _id,					\
+		.parent = _parent,				\
+		.regs = &eth_cg_regs,				\
+		.shift = _shift,				\
+		.flags = CLK_GATE_NO_SETCLR_INV | (_flag),	\
+	}
+
+#define GATE_ETH0(_id, _parent, _shift)				\
+	GATE_ETH(_id, _parent, _shift, CLK_PARENT_APMIXED)
+
+#define GATE_ETH1(_id, _parent, _shift)				\
+	GATE_ETH(_id, _parent, _shift, CLK_PARENT_TOPCKGEN)
+
+static const struct mtk_gate eth_cgs[] = {
+	GATE_ETH1(CLK_ETHSYS_HSDMA, CLK_TOP_ETHIF_SEL, 5),
+	GATE_ETH1(CLK_ETHSYS_ESW, CLK_TOP_ETHPLL_500M, 6),
+	GATE_ETH0(CLK_ETHSYS_GP2, CLK_APMIXED_TRGPLL, 7),
+	GATE_ETH1(CLK_ETHSYS_GP1, CLK_TOP_ETHPLL_500M, 8),
+	GATE_ETH1(CLK_ETHSYS_PCM, CLK_TOP_ETHIF_SEL, 11),
+	GATE_ETH1(CLK_ETHSYS_GDMA, CLK_TOP_ETHIF_SEL, 14),
+	GATE_ETH1(CLK_ETHSYS_I2S, CLK_TOP_ETHIF_SEL, 17),
+	GATE_ETH1(CLK_ETHSYS_CRYPTO, CLK_TOP_ETHIF_SEL, 29),
+};
+
+static const struct mtk_clk_tree mt7623_clk_tree = {
+	.xtal_rate = 26 * MHZ,
+	.xtal2_rate = 26 * MHZ,
+	.fdivs_offs = CLK_TOP_SYSPLL,
+	.muxes_offs = CLK_TOP_AXI_SEL,
+	.plls = apmixed_plls,
+	.fclks = top_fixed_clks,
+	.fdivs = top_fixed_divs,
+	.muxes = top_muxes,
+};
+
+static int mt7623_mcucfg_probe(struct udevice *dev)
+{
+	void __iomem *base;
+
+	base = dev_read_addr_ptr(dev);
+	if (!base)
+		return -ENOENT;
+
+	clrsetbits_le32(base + MCU_AXI_DIV, AXI_DIV_MSK,
+			AXI_DIV_SEL(0x12));
+
+	return 0;
+}
+
+static int mt7623_apmixedsys_probe(struct udevice *dev)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = mtk_common_clk_init(dev, &mt7623_clk_tree);
+	if (ret)
+		return ret;
+
+	/* reduce clock square disable time */
+	writel(0x50001, priv->base + MT7623_CLKSQ_STB_CON0);
+	/* extend control timing to 1us */
+	writel(0x888, priv->base + MT7623_PLL_ISO_CON0);
+
+	return 0;
+}
+
+static int mt7623_topckgen_probe(struct udevice *dev)
+{
+	return mtk_common_clk_init(dev, &mt7623_clk_tree);
+}
+
+static int mt7623_infracfg_probe(struct udevice *dev)
+{
+	return mtk_common_clk_gate_init(dev, &mt7623_clk_tree, infra_cgs);
+}
+
+static int mt7623_pericfg_probe(struct udevice *dev)
+{
+	return mtk_common_clk_gate_init(dev, &mt7623_clk_tree, peri_cgs);
+}
+
+static int mt7623_ethsys_probe(struct udevice *dev)
+{
+	return mtk_common_clk_gate_init(dev, &mt7623_clk_tree, eth_cgs);
+}
+
+static const struct udevice_id mt7623_apmixed_compat[] = {
+	{ .compatible = "mediatek,mt7623-apmixedsys" },
+	{ }
+};
+
+static const struct udevice_id mt7623_topckgen_compat[] = {
+	{ .compatible = "mediatek,mt7623-topckgen" },
+	{ }
+};
+
+static const struct udevice_id mt7623_infracfg_compat[] = {
+	{ .compatible = "mediatek,mt7623-infracfg", },
+	{ }
+};
+
+static const struct udevice_id mt7623_pericfg_compat[] = {
+	{ .compatible = "mediatek,mt7623-pericfg", },
+	{ }
+};
+
+static const struct udevice_id mt7623_ethsys_compat[] = {
+	{ .compatible = "mediatek,mt7623-ethsys" },
+	{ }
+};
+
+static const struct udevice_id mt7623_mcucfg_compat[] = {
+	{ .compatible = "mediatek,mt7623-mcucfg" },
+	{ }
+};
+
+U_BOOT_DRIVER(mtk_mcucfg) = {
+	.name = "mt7623-mcucfg",
+	.id = UCLASS_SYSCON,
+	.of_match = mt7623_mcucfg_compat,
+	.probe = mt7623_mcucfg_probe,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+	.name = "mt7623-clock-apmixedsys",
+	.id = UCLASS_CLK,
+	.of_match = mt7623_apmixed_compat,
+	.probe = mt7623_apmixedsys_probe,
+	.priv_auto_alloc_size = sizeof(struct mtk_clk_priv),
+	.ops = &mtk_clk_apmixedsys_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_topckgen) = {
+	.name = "mt7623-clock-topckgen",
+	.id = UCLASS_CLK,
+	.of_match = mt7623_topckgen_compat,
+	.probe = mt7623_topckgen_probe,
+	.priv_auto_alloc_size = sizeof(struct mtk_clk_priv),
+	.ops = &mtk_clk_topckgen_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_infracfg) = {
+	.name = "mt7623-infracfg",
+	.id = UCLASS_CLK,
+	.of_match = mt7623_infracfg_compat,
+	.probe = mt7623_infracfg_probe,
+	.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
+	.ops = &mtk_clk_gate_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_pericfg) = {
+	.name = "mt7623-pericfg",
+	.id = UCLASS_CLK,
+	.of_match = mt7623_pericfg_compat,
+	.probe = mt7623_pericfg_probe,
+	.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
+	.ops = &mtk_clk_gate_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_ethsys) = {
+	.name = "mt7623-clock-ethsys",
+	.id = UCLASS_CLK,
+	.of_match = mt7623_ethsys_compat,
+	.probe = mt7623_ethsys_probe,
+	.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
+	.ops = &mtk_clk_gate_ops,
+};
diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c
new file mode 100644
index 0000000..2601b6c
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7629.c
@@ -0,0 +1,709 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek clock driver for MT7629 SoC
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <dt-bindings/clock/mt7629-clk.h>
+
+#include "clk-mtk.h"
+
+#define MT7629_CLKSQ_STB_CON0		0x20
+#define MT7629_PLL_ISO_CON0		0x2c
+#define MT7629_PLL_FMAX			(2500UL * MHZ)
+#define MT7629_CON0_RST_BAR		BIT(24)
+
+#define MCU_AXI_DIV			0x640
+#define AXI_DIV_MSK			GENMASK(4, 0)
+#define AXI_DIV_SEL(x)			(x)
+
+#define MCU_BUS_MUX			0x7c0
+#define MCU_BUS_MSK			GENMASK(10, 9)
+#define MCU_BUS_SEL(x)			((x) << 9)
+
+/* apmixedsys */
+#define PLL(_id, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg,	\
+	    _pd_shift, _pcw_reg, _pcw_shift) {				\
+		.id = _id,						\
+		.reg = _reg,						\
+		.pwr_reg = _pwr_reg,					\
+		.en_mask = _en_mask,					\
+		.rst_bar_mask = MT7629_CON0_RST_BAR,			\
+		.fmax = MT7629_PLL_FMAX,				\
+		.flags = _flags,					\
+		.pcwbits = _pcwbits,					\
+		.pd_reg = _pd_reg,					\
+		.pd_shift = _pd_shift,					\
+		.pcw_reg = _pcw_reg,					\
+		.pcw_shift = _pcw_shift,				\
+	}
+
+static const struct mtk_pll_data apmixed_plls[] = {
+	PLL(CLK_APMIXED_ARMPLL, 0x200, 0x20c, 0x1, 0,
+	    21, 0x204, 24, 0x204, 0),
+	PLL(CLK_APMIXED_MAINPLL, 0x210, 0x21c, 0x1, HAVE_RST_BAR,
+	    21, 0x214, 24, 0x214, 0),
+	PLL(CLK_APMIXED_UNIV2PLL, 0x220, 0x22c, 0x1, HAVE_RST_BAR,
+	    7, 0x224, 24, 0x224, 14),
+	PLL(CLK_APMIXED_ETH1PLL, 0x300, 0x310, 0x1, 0,
+	    21, 0x300, 1, 0x304, 0),
+	PLL(CLK_APMIXED_ETH2PLL, 0x314, 0x320, 0x1, 0,
+	    21, 0x314, 1, 0x318, 0),
+	PLL(CLK_APMIXED_SGMIPLL, 0x358, 0x368, 0x1, 0,
+	    21, 0x358, 1, 0x35c, 0),
+};
+
+/* topckgen */
+#define FACTOR0(_id, _parent, _mult, _div)			\
+	FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED)
+
+#define FACTOR1(_id, _parent, _mult, _div)			\
+	FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN)
+
+#define FACTOR2(_id, _parent, _mult, _div)			\
+	FACTOR(_id, _parent, _mult, _div, 0)
+
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+	FIXED_CLK(CLK_TOP_TO_U2_PHY, CLK_XTAL, 31250000),
+	FIXED_CLK(CLK_TOP_TO_U2_PHY_1P, CLK_XTAL, 31250000),
+	FIXED_CLK(CLK_TOP_PCIE0_PIPE_EN, CLK_XTAL, 125000000),
+	FIXED_CLK(CLK_TOP_PCIE1_PIPE_EN, CLK_XTAL, 125000000),
+	FIXED_CLK(CLK_TOP_SSUSB_TX250M, CLK_XTAL, 250000000),
+	FIXED_CLK(CLK_TOP_SSUSB_EQ_RX250M, CLK_XTAL, 250000000),
+	FIXED_CLK(CLK_TOP_SSUSB_CDR_REF, CLK_XTAL, 33333333),
+	FIXED_CLK(CLK_TOP_SSUSB_CDR_FB, CLK_XTAL, 50000000),
+	FIXED_CLK(CLK_TOP_SATA_ASIC, CLK_XTAL, 50000000),
+	FIXED_CLK(CLK_TOP_SATA_RBC, CLK_XTAL, 50000000),
+};
+
+static const struct mtk_fixed_factor top_fixed_divs[] = {
+	FACTOR0(CLK_TOP_TO_USB3_SYS, CLK_APMIXED_ETH1PLL, 1, 4),
+	FACTOR0(CLK_TOP_P1_1MHZ, CLK_APMIXED_ETH1PLL, 1, 500),
+	FACTOR0(CLK_TOP_4MHZ, CLK_APMIXED_ETH1PLL, 1, 125),
+	FACTOR0(CLK_TOP_P0_1MHZ, CLK_APMIXED_ETH1PLL, 1, 500),
+	FACTOR0(CLK_TOP_ETH_500M, CLK_APMIXED_ETH1PLL, 1, 1),
+	FACTOR1(CLK_TOP_TXCLK_SRC_PRE, CLK_TOP_SGMIIPLL_D2, 1, 1),
+	FACTOR2(CLK_TOP_RTC, CLK_XTAL, 1, 1024),
+	FACTOR2(CLK_TOP_PWM_QTR_26M, CLK_XTAL, 1, 1),
+	FACTOR2(CLK_TOP_CPUM_TCK_IN, CLK_XTAL, 1, 1),
+	FACTOR2(CLK_TOP_TO_USB3_DA_TOP, CLK_XTAL, 1, 1),
+	FACTOR2(CLK_TOP_MEMPLL, CLK_XTAL, 32, 1),
+	FACTOR1(CLK_TOP_DMPLL, CLK_TOP_MEMPLL, 1, 1),
+	FACTOR1(CLK_TOP_DMPLL_D4, CLK_TOP_MEMPLL, 1, 4),
+	FACTOR1(CLK_TOP_DMPLL_D8, CLK_TOP_MEMPLL, 1, 8),
+	FACTOR0(CLK_TOP_SYSPLL_D2, CLK_APMIXED_MAINPLL, 1, 2),
+	FACTOR0(CLK_TOP_SYSPLL1_D2, CLK_APMIXED_MAINPLL, 1, 4),
+	FACTOR0(CLK_TOP_SYSPLL1_D4, CLK_APMIXED_MAINPLL, 1, 8),
+	FACTOR0(CLK_TOP_SYSPLL1_D8, CLK_APMIXED_MAINPLL, 1, 16),
+	FACTOR0(CLK_TOP_SYSPLL1_D16, CLK_APMIXED_MAINPLL, 1, 32),
+	FACTOR0(CLK_TOP_SYSPLL2_D2, CLK_APMIXED_MAINPLL, 1, 6),
+	FACTOR0(CLK_TOP_SYSPLL2_D4, CLK_APMIXED_MAINPLL, 1, 12),
+	FACTOR0(CLK_TOP_SYSPLL2_D8, CLK_APMIXED_MAINPLL, 1, 24),
+	FACTOR0(CLK_TOP_SYSPLL_D5, CLK_APMIXED_MAINPLL, 1, 5),
+	FACTOR0(CLK_TOP_SYSPLL3_D2, CLK_APMIXED_MAINPLL, 1, 10),
+	FACTOR0(CLK_TOP_SYSPLL3_D4, CLK_APMIXED_MAINPLL, 1, 20),
+	FACTOR0(CLK_TOP_SYSPLL_D7, CLK_APMIXED_MAINPLL, 1, 7),
+	FACTOR0(CLK_TOP_SYSPLL4_D2, CLK_APMIXED_MAINPLL, 1, 14),
+	FACTOR0(CLK_TOP_SYSPLL4_D4, CLK_APMIXED_MAINPLL, 1, 28),
+	FACTOR0(CLK_TOP_SYSPLL4_D16, CLK_APMIXED_MAINPLL, 1, 112),
+	FACTOR0(CLK_TOP_UNIVPLL, CLK_APMIXED_UNIV2PLL, 1, 2),
+	FACTOR1(CLK_TOP_UNIVPLL1_D2, CLK_TOP_UNIVPLL, 1, 4),
+	FACTOR1(CLK_TOP_UNIVPLL1_D4, CLK_TOP_UNIVPLL, 1, 8),
+	FACTOR1(CLK_TOP_UNIVPLL1_D8, CLK_TOP_UNIVPLL, 1, 16),
+	FACTOR1(CLK_TOP_UNIVPLL_D3, CLK_TOP_UNIVPLL, 1, 3),
+	FACTOR1(CLK_TOP_UNIVPLL2_D2, CLK_TOP_UNIVPLL, 1, 6),
+	FACTOR1(CLK_TOP_UNIVPLL2_D4, CLK_TOP_UNIVPLL, 1, 12),
+	FACTOR1(CLK_TOP_UNIVPLL2_D8, CLK_TOP_UNIVPLL, 1, 24),
+	FACTOR1(CLK_TOP_UNIVPLL2_D16, CLK_TOP_UNIVPLL, 1, 48),
+	FACTOR1(CLK_TOP_UNIVPLL_D5, CLK_TOP_UNIVPLL, 1, 5),
+	FACTOR1(CLK_TOP_UNIVPLL3_D2, CLK_TOP_UNIVPLL, 1, 10),
+	FACTOR1(CLK_TOP_UNIVPLL3_D4, CLK_TOP_UNIVPLL, 1, 20),
+	FACTOR1(CLK_TOP_UNIVPLL3_D16, CLK_TOP_UNIVPLL, 1, 80),
+	FACTOR1(CLK_TOP_UNIVPLL_D7, CLK_TOP_UNIVPLL, 1, 7),
+	FACTOR1(CLK_TOP_UNIVPLL_D80_D4, CLK_TOP_UNIVPLL, 1, 320),
+	FACTOR1(CLK_TOP_UNIV48M, CLK_TOP_UNIVPLL, 1, 25),
+	FACTOR0(CLK_TOP_SGMIIPLL_D2, CLK_APMIXED_SGMIPLL, 1, 2),
+	FACTOR2(CLK_TOP_CLKXTAL_D4, CLK_XTAL, 1, 4),
+	FACTOR1(CLK_TOP_HD_FAXI, CLK_TOP_AXI_SEL, 1, 1),
+	FACTOR1(CLK_TOP_FAXI, CLK_TOP_AXI_SEL, 1, 1),
+	FACTOR1(CLK_TOP_F_FAUD_INTBUS, CLK_TOP_AUD_INTBUS_SEL, 1, 1),
+	FACTOR1(CLK_TOP_AP2WBHIF_HCLK, CLK_TOP_SYSPLL1_D8, 1, 1),
+	FACTOR1(CLK_TOP_10M_INFRAO, CLK_TOP_10M_SEL, 1, 1),
+	FACTOR1(CLK_TOP_MSDC30_1, CLK_TOP_MSDC30_1, 1, 1),
+	FACTOR1(CLK_TOP_SPI, CLK_TOP_SPI0_SEL, 1, 1),
+	FACTOR1(CLK_TOP_SF, CLK_TOP_NFI_INFRA_SEL, 1, 1),
+	FACTOR1(CLK_TOP_FLASH, CLK_TOP_FLASH_SEL, 1, 1),
+	FACTOR1(CLK_TOP_TO_USB3_REF, CLK_TOP_SATA_SEL, 1, 4),
+	FACTOR1(CLK_TOP_TO_USB3_MCU, CLK_TOP_AXI_SEL, 1, 1),
+	FACTOR1(CLK_TOP_TO_USB3_DMA, CLK_TOP_HIF_SEL, 1, 1),
+	FACTOR1(CLK_TOP_FROM_TOP_AHB, CLK_TOP_AXI_SEL, 1, 1),
+	FACTOR1(CLK_TOP_FROM_TOP_AXI, CLK_TOP_HIF_SEL, 1, 1),
+	FACTOR1(CLK_TOP_PCIE1_MAC_EN, CLK_TOP_UNIVPLL1_D4, 1, 1),
+	FACTOR1(CLK_TOP_PCIE0_MAC_EN, CLK_TOP_UNIVPLL1_D4, 1, 1),
+};
+
+static const int axi_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D2,
+	CLK_TOP_SYSPLL_D5,
+	CLK_TOP_SYSPLL1_D4,
+	CLK_TOP_UNIVPLL_D5,
+	CLK_TOP_UNIVPLL2_D2,
+	CLK_TOP_UNIVPLL_D7,
+	CLK_TOP_DMPLL
+};
+
+static const int mem_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_DMPLL
+};
+
+static const int ddrphycfg_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D8
+};
+
+static const int eth_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D2,
+	CLK_TOP_UNIVPLL1_D2,
+	CLK_TOP_SYSPLL1_D4,
+	CLK_TOP_UNIVPLL_D5,
+	CLK_TOP_SGMIIPLL_D2,
+	CLK_TOP_UNIVPLL_D7,
+	CLK_TOP_DMPLL
+};
+
+static const int pwm_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL2_D4
+};
+
+static const int f10m_ref_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SGMIIPLL_D2
+};
+
+static const int nfi_infra_parents[] = {
+	CLK_XTAL,
+	CLK_XTAL,
+	CLK_XTAL,
+	CLK_XTAL,
+	CLK_XTAL,
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL2_D8,
+	CLK_TOP_UNIVPLL3_D4,
+	CLK_TOP_SYSPLL1_D8,
+	CLK_TOP_UNIVPLL1_D8,
+	CLK_TOP_SYSPLL4_D2,
+	CLK_TOP_SYSPLL2_D4,
+	CLK_TOP_UNIVPLL2_D4,
+	CLK_TOP_UNIVPLL3_D2,
+	CLK_TOP_SYSPLL1_D4,
+	CLK_TOP_SYSPLL_D7
+};
+
+static const int flash_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL_D80_D4,
+	CLK_TOP_SYSPLL2_D8,
+	CLK_TOP_SYSPLL3_D4,
+	CLK_TOP_UNIVPLL3_D4,
+	CLK_TOP_UNIVPLL1_D8,
+	CLK_TOP_SYSPLL2_D4,
+	CLK_TOP_UNIVPLL2_D4
+};
+
+static const int uart_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL2_D8
+};
+
+static const int spi0_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL3_D2,
+	CLK_XTAL,
+	CLK_TOP_SYSPLL2_D4,
+	CLK_TOP_SYSPLL4_D2,
+	CLK_TOP_UNIVPLL2_D4,
+	CLK_TOP_UNIVPLL1_D8,
+	CLK_XTAL
+};
+
+static const int spi1_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL3_D2,
+	CLK_XTAL,
+	CLK_TOP_SYSPLL4_D4,
+	CLK_TOP_SYSPLL4_D2,
+	CLK_TOP_UNIVPLL2_D4,
+	CLK_TOP_UNIVPLL1_D8,
+	CLK_XTAL
+};
+
+static const int msdc30_0_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL2_D16,
+	CLK_TOP_UNIV48M
+};
+
+static const int msdc30_1_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL2_D16,
+	CLK_TOP_UNIV48M,
+	CLK_TOP_SYSPLL2_D4,
+	CLK_TOP_UNIVPLL2_D4,
+	CLK_TOP_SYSPLL_D7,
+	CLK_TOP_SYSPLL2_D2,
+	CLK_TOP_UNIVPLL2_D2
+};
+
+static const int ap2wbmcu_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D2,
+	CLK_TOP_UNIV48M,
+	CLK_TOP_SYSPLL1_D8,
+	CLK_TOP_UNIVPLL2_D4,
+	CLK_TOP_SYSPLL_D7,
+	CLK_TOP_SYSPLL2_D2,
+	CLK_TOP_UNIVPLL2_D2
+};
+
+static const int audio_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL3_D4,
+	CLK_TOP_SYSPLL4_D4,
+	CLK_TOP_SYSPLL1_D16
+};
+
+static const int aud_intbus_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D4,
+	CLK_TOP_SYSPLL4_D2,
+	CLK_TOP_DMPLL_D4
+};
+
+static const int pmicspi_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D8,
+	CLK_TOP_SYSPLL3_D4,
+	CLK_TOP_SYSPLL1_D16,
+	CLK_TOP_UNIVPLL3_D4,
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL2_D4,
+	CLK_TOP_DMPLL_D8
+};
+
+static const int scp_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D8,
+	CLK_TOP_UNIVPLL2_D2,
+	CLK_TOP_UNIVPLL2_D4
+};
+
+static const int atb_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D2,
+	CLK_TOP_SYSPLL_D5
+};
+
+static const int hif_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL1_D2,
+	CLK_TOP_UNIVPLL1_D2,
+	CLK_TOP_SYSPLL1_D4,
+	CLK_TOP_UNIVPLL_D5,
+	-1,
+	CLK_TOP_UNIVPLL_D7
+};
+
+static const int sata_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL2_D4
+};
+
+static const int usb20_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL3_D4,
+	CLK_TOP_SYSPLL1_D8
+};
+
+static const int aud1_parents[] = {
+	CLK_XTAL
+};
+
+static const int irrx_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_SYSPLL4_D16
+};
+
+static const int crypto_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_UNIVPLL_D3,
+	CLK_TOP_UNIVPLL1_D2,
+	CLK_TOP_SYSPLL1_D2,
+	CLK_TOP_UNIVPLL_D5,
+	CLK_TOP_SYSPLL_D5,
+	CLK_TOP_UNIVPLL2_D2,
+	CLK_TOP_SYSPLL_D2
+};
+
+static const int gpt10m_parents[] = {
+	CLK_XTAL,
+	CLK_TOP_CLKXTAL_D4
+};
+
+static const struct mtk_composite top_muxes[] = {
+	/* CLK_CFG_0 */
+	MUX_GATE(CLK_TOP_AXI_SEL, axi_parents, 0x40, 0, 3, 7),
+	MUX_GATE(CLK_TOP_MEM_SEL, mem_parents, 0x40, 8, 1, 15),
+	MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, ddrphycfg_parents, 0x40, 16, 1, 23),
+	MUX_GATE(CLK_TOP_ETH_SEL, eth_parents, 0x40, 24, 3, 31),
+
+	/* CLK_CFG_1 */
+	MUX_GATE(CLK_TOP_PWM_SEL, pwm_parents, 0x50, 0, 2, 7),
+	MUX_GATE(CLK_TOP_F10M_REF_SEL, f10m_ref_parents, 0x50, 8, 1, 15),
+	MUX_GATE(CLK_TOP_NFI_INFRA_SEL, nfi_infra_parents, 0x50, 16, 4, 23),
+	MUX_GATE(CLK_TOP_FLASH_SEL, flash_parents, 0x50, 24, 3, 31),
+
+	/* CLK_CFG_2 */
+	MUX_GATE(CLK_TOP_UART_SEL, uart_parents, 0x60, 0, 1, 7),
+	MUX_GATE(CLK_TOP_SPI0_SEL, spi0_parents, 0x60, 8, 3, 15),
+	MUX_GATE(CLK_TOP_SPI1_SEL, spi1_parents, 0x60, 16, 3, 23),
+	MUX_GATE(CLK_TOP_MSDC50_0_SEL, uart_parents, 0x60, 24, 3, 31),
+
+	/* CLK_CFG_3 */
+	MUX_GATE(CLK_TOP_MSDC30_0_SEL, msdc30_0_parents, 0x70, 0, 3, 7),
+	MUX_GATE(CLK_TOP_MSDC30_1_SEL, msdc30_1_parents, 0x70, 8, 3, 15),
+	MUX_GATE(CLK_TOP_AP2WBMCU_SEL, ap2wbmcu_parents, 0x70, 16, 3, 23),
+	MUX_GATE(CLK_TOP_AP2WBHIF_SEL, ap2wbmcu_parents, 0x70, 24, 3, 31),
+
+	/* CLK_CFG_4 */
+	MUX_GATE(CLK_TOP_AUDIO_SEL, audio_parents, 0x80, 0, 2, 7),
+	MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, aud_intbus_parents, 0x80, 8, 2, 15),
+	MUX_GATE(CLK_TOP_PMICSPI_SEL, pmicspi_parents, 0x80, 16, 3, 23),
+	MUX_GATE(CLK_TOP_SCP_SEL, scp_parents, 0x80, 24, 2, 31),
+
+	/* CLK_CFG_5 */
+	MUX_GATE(CLK_TOP_ATB_SEL, atb_parents, 0x90, 0, 2, 7),
+	MUX_GATE_FLAGS(CLK_TOP_HIF_SEL, hif_parents, 0x90, 8, 3, 15,
+		       CLK_DOMAIN_SCPSYS),
+	MUX_GATE(CLK_TOP_SATA_SEL, sata_parents, 0x90, 16, 1, 23),
+	MUX_GATE(CLK_TOP_U2_SEL, usb20_parents, 0x90, 24, 2, 31),
+
+	/* CLK_CFG_6 */
+	MUX_GATE(CLK_TOP_AUD1_SEL, aud1_parents, 0xA0, 0, 1, 7),
+	MUX_GATE(CLK_TOP_AUD2_SEL, aud1_parents, 0xA0, 8, 1, 15),
+	MUX_GATE(CLK_TOP_IRRX_SEL, irrx_parents, 0xA0, 16, 1, 23),
+	MUX_GATE(CLK_TOP_IRTX_SEL, irrx_parents, 0xA0, 24, 1, 31),
+
+	/* CLK_CFG_7 */
+	MUX_GATE(CLK_TOP_SATA_MCU_SEL, scp_parents, 0xB0, 0, 2, 7),
+	MUX_GATE(CLK_TOP_PCIE0_MCU_SEL, scp_parents, 0xB0, 8, 2, 15),
+	MUX_GATE(CLK_TOP_PCIE1_MCU_SEL, scp_parents, 0xB0, 16, 2, 23),
+	MUX_GATE(CLK_TOP_SSUSB_MCU_SEL, scp_parents, 0xB0, 24, 2, 31),
+
+	/* CLK_CFG_8 */
+	MUX_GATE(CLK_TOP_CRYPTO_SEL, crypto_parents, 0xC0, 0, 3, 7),
+	MUX_GATE(CLK_TOP_SGMII_REF_1_SEL, f10m_ref_parents, 0xC0, 8, 1, 15),
+	MUX_GATE(CLK_TOP_10M_SEL, gpt10m_parents, 0xC0, 16, 1, 23),
+};
+
+/* infracfg */
+static const struct mtk_gate_regs infra_cg_regs = {
+	.set_ofs = 0x40,
+	.clr_ofs = 0x44,
+	.sta_ofs = 0x48,
+};
+
+#define GATE_INFRA(_id, _parent, _shift) {			\
+		.id = _id,					\
+		.parent = _parent,				\
+		.regs = &infra_cg_regs,				\
+		.shift = _shift,				\
+		.flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN,	\
+	}
+
+static const struct mtk_gate infra_cgs[] = {
+	GATE_INFRA(CLK_INFRA_DBGCLK_PD, CLK_TOP_HD_FAXI, 0),
+	GATE_INFRA(CLK_INFRA_TRNG_PD, CLK_TOP_HD_FAXI, 2),
+	GATE_INFRA(CLK_INFRA_DEVAPC_PD, CLK_TOP_HD_FAXI, 4),
+	GATE_INFRA(CLK_INFRA_APXGPT_PD, CLK_TOP_10M_INFRAO, 18),
+	GATE_INFRA(CLK_INFRA_SEJ_PD, CLK_TOP_10M_INFRAO, 19),
+};
+
+/* pericfg */
+static const struct mtk_gate_regs peri0_cg_regs = {
+	.set_ofs = 0x8,
+	.clr_ofs = 0x10,
+	.sta_ofs = 0x18,
+};
+
+static const struct mtk_gate_regs peri1_cg_regs = {
+	.set_ofs = 0xC,
+	.clr_ofs = 0x14,
+	.sta_ofs = 0x1C,
+};
+
+#define GATE_PERI0(_id, _parent, _shift) {			\
+		.id = _id,					\
+		.parent = _parent,				\
+		.regs = &peri0_cg_regs,				\
+		.shift = _shift,				\
+		.flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN,	\
+	}
+
+#define GATE_PERI1(_id, _parent, _shift) {			\
+		.id = _id,					\
+		.parent = _parent,				\
+		.regs = &peri1_cg_regs,				\
+		.shift = _shift,				\
+		.flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN,	\
+	}
+
+static const struct mtk_gate peri_cgs[] = {
+	GATE_PERI0(CLK_PERI_PWM1_PD, CLK_TOP_PWM_QTR_26M, 2),
+	GATE_PERI0(CLK_PERI_PWM2_PD, CLK_TOP_PWM_QTR_26M, 3),
+	GATE_PERI0(CLK_PERI_PWM3_PD, CLK_TOP_PWM_QTR_26M, 4),
+	GATE_PERI0(CLK_PERI_PWM4_PD, CLK_TOP_PWM_QTR_26M, 5),
+	GATE_PERI0(CLK_PERI_PWM5_PD, CLK_TOP_PWM_QTR_26M, 6),
+	GATE_PERI0(CLK_PERI_PWM6_PD, CLK_TOP_PWM_QTR_26M, 7),
+	GATE_PERI0(CLK_PERI_PWM7_PD, CLK_TOP_PWM_QTR_26M, 8),
+	GATE_PERI0(CLK_PERI_PWM_PD, CLK_TOP_PWM_QTR_26M, 9),
+	GATE_PERI0(CLK_PERI_AP_DMA_PD, CLK_TOP_FAXI, 12),
+	GATE_PERI0(CLK_PERI_MSDC30_1_PD, CLK_TOP_MSDC30_1, 14),
+	GATE_PERI0(CLK_PERI_UART0_PD, CLK_TOP_FAXI, 17),
+	GATE_PERI0(CLK_PERI_UART1_PD, CLK_TOP_FAXI, 18),
+	GATE_PERI0(CLK_PERI_UART2_PD, CLK_TOP_FAXI, 19),
+	GATE_PERI0(CLK_PERI_UART3_PD, CLK_TOP_FAXI, 20),
+	GATE_PERI0(CLK_PERI_BTIF_PD, CLK_TOP_FAXI, 22),
+	GATE_PERI0(CLK_PERI_I2C0_PD, CLK_TOP_FAXI, 23),
+	GATE_PERI0(CLK_PERI_SPI0_PD, CLK_TOP_SPI, 28),
+	GATE_PERI0(CLK_PERI_SNFI_PD, CLK_TOP_SF, 29),
+	GATE_PERI0(CLK_PERI_NFI_PD, CLK_TOP_FAXI, 30),
+	GATE_PERI0(CLK_PERI_NFIECC_PD, CLK_TOP_FAXI, 31),
+	GATE_PERI1(CLK_PERI_FLASH_PD, CLK_TOP_FLASH, 1),
+};
+
+/* ethsys */
+static const struct mtk_gate_regs eth_cg_regs = {
+	.sta_ofs = 0x30,
+};
+
+#define GATE_ETH(_id, _parent, _shift, _flag) {			\
+		.id = _id,					\
+		.parent = _parent,				\
+		.regs = &eth_cg_regs,				\
+		.shift = _shift,				\
+		.flags = CLK_GATE_NO_SETCLR_INV | (_flag),	\
+	}
+
+#define GATE_ETH0(_id, _parent, _shift)				\
+	GATE_ETH(_id, _parent, _shift, CLK_PARENT_APMIXED)
+
+#define GATE_ETH1(_id, _parent, _shift)				\
+	GATE_ETH(_id, _parent, _shift, CLK_PARENT_TOPCKGEN)
+
+static const struct mtk_gate eth_cgs[] = {
+	GATE_ETH0(CLK_ETH_FE_EN, CLK_APMIXED_ETH2PLL, 6),
+	GATE_ETH1(CLK_ETH_GP2_EN, CLK_TOP_TXCLK_SRC_PRE, 7),
+	GATE_ETH1(CLK_ETH_GP1_EN, CLK_TOP_TXCLK_SRC_PRE, 8),
+	GATE_ETH1(CLK_ETH_GP0_EN, CLK_TOP_TXCLK_SRC_PRE, 9),
+	GATE_ETH1(CLK_ETH_ESW_EN, CLK_TOP_ETH_500M, 16),
+};
+
+static const struct mtk_gate_regs sgmii_cg_regs = {
+	.set_ofs = 0xE4,
+	.clr_ofs = 0xE4,
+	.sta_ofs = 0xE4,
+};
+
+#define GATE_SGMII(_id, _parent, _shift) {			\
+	.id = _id,						\
+	.parent = _parent,					\
+	.regs = &sgmii_cg_regs,					\
+	.shift = _shift,					\
+	.flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN,	\
+}
+
+static const struct mtk_gate sgmii_cgs[] = {
+	GATE_SGMII(CLK_SGMII_TX_EN, CLK_TOP_SSUSB_TX250M, 2),
+	GATE_SGMII(CLK_SGMII_RX_EN, CLK_TOP_SSUSB_EQ_RX250M, 3),
+	GATE_SGMII(CLK_SGMII_CDR_REF, CLK_TOP_SSUSB_CDR_REF, 4),
+	GATE_SGMII(CLK_SGMII_CDR_FB, CLK_TOP_SSUSB_CDR_FB, 5),
+};
+
+static const struct mtk_clk_tree mt7629_clk_tree = {
+	.xtal_rate = 40 * MHZ,
+	.xtal2_rate = 20 * MHZ,
+	.fdivs_offs = CLK_TOP_TO_USB3_SYS,
+	.muxes_offs = CLK_TOP_AXI_SEL,
+	.plls = apmixed_plls,
+	.fclks = top_fixed_clks,
+	.fdivs = top_fixed_divs,
+	.muxes = top_muxes,
+};
+
+static int mt7629_mcucfg_probe(struct udevice *dev)
+{
+	void __iomem *base;
+
+	base = dev_read_addr_ptr(dev);
+	if (!base)
+		return -ENOENT;
+
+	clrsetbits_le32(base + MCU_AXI_DIV, AXI_DIV_MSK,
+			AXI_DIV_SEL(0x12));
+	clrsetbits_le32(base + MCU_BUS_MUX, MCU_BUS_MSK,
+			MCU_BUS_SEL(0x1));
+
+	return 0;
+}
+
+static int mt7629_apmixedsys_probe(struct udevice *dev)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = mtk_common_clk_init(dev, &mt7629_clk_tree);
+	if (ret)
+		return ret;
+
+	/* reduce clock square disable time */
+	writel(0x501, priv->base + MT7629_CLKSQ_STB_CON0);
+	/* extend pwr/iso control timing to 1us */
+	writel(0x80008, priv->base + MT7629_PLL_ISO_CON0);
+
+	return 0;
+}
+
+static int mt7629_topckgen_probe(struct udevice *dev)
+{
+	return mtk_common_clk_init(dev, &mt7629_clk_tree);
+}
+
+static int mt7629_infracfg_probe(struct udevice *dev)
+{
+	return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, infra_cgs);
+}
+
+static int mt7629_pericfg_probe(struct udevice *dev)
+{
+	return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, peri_cgs);
+}
+
+static int mt7629_ethsys_probe(struct udevice *dev)
+{
+	return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, eth_cgs);
+}
+
+static int mt7629_sgmiisys_probe(struct udevice *dev)
+{
+	return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, sgmii_cgs);
+}
+
+static const struct udevice_id mt7629_apmixed_compat[] = {
+	{ .compatible = "mediatek,mt7629-apmixedsys" },
+	{ }
+};
+
+static const struct udevice_id mt7629_topckgen_compat[] = {
+	{ .compatible = "mediatek,mt7629-topckgen" },
+	{ }
+};
+
+static const struct udevice_id mt7629_infracfg_compat[] = {
+	{ .compatible = "mediatek,mt7629-infracfg", },
+	{ }
+};
+
+static const struct udevice_id mt7629_pericfg_compat[] = {
+	{ .compatible = "mediatek,mt7629-pericfg", },
+	{ }
+};
+
+static const struct udevice_id mt7629_ethsys_compat[] = {
+	{ .compatible = "mediatek,mt7629-ethsys", },
+	{ }
+};
+
+static const struct udevice_id mt7629_sgmiisys_compat[] = {
+	{ .compatible = "mediatek,mt7629-sgmiisys", },
+	{ }
+};
+
+static const struct udevice_id mt7629_mcucfg_compat[] = {
+	{ .compatible = "mediatek,mt7629-mcucfg" },
+	{ }
+};
+
+U_BOOT_DRIVER(mtk_mcucfg) = {
+	.name = "mt7629-mcucfg",
+	.id = UCLASS_SYSCON,
+	.of_match = mt7629_mcucfg_compat,
+	.probe = mt7629_mcucfg_probe,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+	.name = "mt7629-clock-apmixedsys",
+	.id = UCLASS_CLK,
+	.of_match = mt7629_apmixed_compat,
+	.probe = mt7629_apmixedsys_probe,
+	.priv_auto_alloc_size = sizeof(struct mtk_clk_priv),
+	.ops = &mtk_clk_apmixedsys_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_topckgen) = {
+	.name = "mt7629-clock-topckgen",
+	.id = UCLASS_CLK,
+	.of_match = mt7629_topckgen_compat,
+	.probe = mt7629_topckgen_probe,
+	.priv_auto_alloc_size = sizeof(struct mtk_clk_priv),
+	.ops = &mtk_clk_topckgen_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_infracfg) = {
+	.name = "mt7629-clock-infracfg",
+	.id = UCLASS_CLK,
+	.of_match = mt7629_infracfg_compat,
+	.probe = mt7629_infracfg_probe,
+	.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
+	.ops = &mtk_clk_gate_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_pericfg) = {
+	.name = "mt7629-clock-pericfg",
+	.id = UCLASS_CLK,
+	.of_match = mt7629_pericfg_compat,
+	.probe = mt7629_pericfg_probe,
+	.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
+	.ops = &mtk_clk_gate_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_ethsys) = {
+	.name = "mt7629-clock-ethsys",
+	.id = UCLASS_CLK,
+	.of_match = mt7629_ethsys_compat,
+	.probe = mt7629_ethsys_probe,
+	.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
+	.ops = &mtk_clk_gate_ops,
+};
+
+U_BOOT_DRIVER(mtk_clk_sgmiisys) = {
+	.name = "mt7629-clock-sgmiisys",
+	.id = UCLASS_CLK,
+	.of_match = mt7629_sgmiisys_compat,
+	.probe = mt7629_sgmiisys_probe,
+	.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
+	.ops = &mtk_clk_gate_ops,
+};
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
new file mode 100644
index 0000000..870b14e
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -0,0 +1,493 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek common clock driver
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <div64.h>
+#include <dm.h>
+#include <asm/io.h>
+
+#include "clk-mtk.h"
+
+#define REG_CON0			0
+#define REG_CON1			4
+
+#define CON0_BASE_EN			BIT(0)
+#define CON0_PWR_ON			BIT(0)
+#define CON0_ISO_EN			BIT(1)
+#define CON1_PCW_CHG			BIT(31)
+
+#define POSTDIV_MASK			0x7
+#define INTEGER_BITS			7
+
+/* scpsys clock off control */
+#define CLK_SCP_CFG0			0x200
+#define CLK_SCP_CFG1			0x204
+#define SCP_ARMCK_OFF_EN		GENMASK(9, 0)
+#define SCP_AXICK_DCM_DIS_EN		BIT(0)
+#define SCP_AXICK_26M_SEL_EN		BIT(4)
+
+/* shared functions */
+
+/*
+ * In case the rate change propagation to parent clocks is undesirable,
+ * this function is recursively called to find the parent to calculate
+ * the accurate frequency.
+ */
+static int mtk_clk_find_parent_rate(struct clk *clk, int id,
+				    const struct driver *drv)
+{
+	struct clk parent = { .id = id, };
+
+	if (drv) {
+		struct udevice *dev;
+
+		if (uclass_get_device_by_driver(UCLASS_CLK, drv, &dev))
+			return -ENODEV;
+
+		parent.dev = dev;
+	} else {
+		parent.dev = clk->dev;
+	}
+
+	return clk_get_rate(&parent);
+}
+
+static int mtk_clk_mux_set_parent(void __iomem *base, u32 parent,
+				  const struct mtk_composite *mux)
+{
+	u32 val, index = 0;
+
+	while (mux->parent[index] != parent)
+		if (++index == mux->num_parents)
+			return -EINVAL;
+
+	/* switch mux to a select parent */
+	val = readl(base + mux->mux_reg);
+	val &= ~(mux->mux_mask << mux->mux_shift);
+
+	val |= index << mux->mux_shift;
+	writel(val, base + mux->mux_reg);
+
+	return 0;
+}
+
+/* apmixedsys functions */
+
+static unsigned long __mtk_pll_recalc_rate(const struct mtk_pll_data *pll,
+					   u32 fin, u32 pcw, int postdiv)
+{
+	int pcwbits = pll->pcwbits;
+	int pcwfbits;
+	u64 vco;
+	u8 c = 0;
+
+	/* The fractional part of the PLL divider. */
+	pcwfbits = pcwbits > INTEGER_BITS ? pcwbits - INTEGER_BITS : 0;
+
+	vco = (u64)fin * pcw;
+
+	if (pcwfbits && (vco & GENMASK(pcwfbits - 1, 0)))
+		c = 1;
+
+	vco >>= pcwfbits;
+
+	if (c)
+		vco++;
+
+	return ((unsigned long)vco + postdiv - 1) / postdiv;
+}
+
+/**
+ * MediaTek PLLs are configured through their pcw value. The pcw value
+ * describes a divider in the PLL feedback loop which consists of 7 bits
+ * for the integer part and the remaining bits (if present) for the
+ * fractional part. Also they have a 3 bit power-of-two post divider.
+ */
+static void mtk_pll_set_rate_regs(struct clk *clk, u32 pcw, int postdiv)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+	const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+	u32 val;
+
+	/* set postdiv */
+	val = readl(priv->base + pll->pd_reg);
+	val &= ~(POSTDIV_MASK << pll->pd_shift);
+	val |= (ffs(postdiv) - 1) << pll->pd_shift;
+
+	/* postdiv and pcw need to set at the same time if on same register */
+	if (pll->pd_reg != pll->pcw_reg) {
+		writel(val, priv->base + pll->pd_reg);
+		val = readl(priv->base + pll->pcw_reg);
+	}
+
+	/* set pcw */
+	val &= ~GENMASK(pll->pcw_shift + pll->pcwbits - 1, pll->pcw_shift);
+	val |= pcw << pll->pcw_shift;
+	val &= ~CON1_PCW_CHG;
+	writel(val, priv->base + pll->pcw_reg);
+
+	val |= CON1_PCW_CHG;
+	writel(val, priv->base + pll->pcw_reg);
+
+	udelay(20);
+}
+
+/**
+ * mtk_pll_calc_values - calculate good values for a given input frequency.
+ * @clk:	The clk
+ * @pcw:	The pcw value (output)
+ * @postdiv:	The post divider (output)
+ * @freq:	The desired target frequency
+ */
+static void mtk_pll_calc_values(struct clk *clk, u32 *pcw, u32 *postdiv,
+				u32 freq)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+	const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+	unsigned long fmin = 1000 * MHZ;
+	u64 _pcw;
+	u32 val;
+
+	if (freq > pll->fmax)
+		freq = pll->fmax;
+
+	for (val = 0; val < 5; val++) {
+		*postdiv = 1 << val;
+		if ((u64)freq * *postdiv >= fmin)
+			break;
+	}
+
+	/* _pcw = freq * postdiv / xtal_rate * 2^pcwfbits */
+	_pcw = ((u64)freq << val) << (pll->pcwbits - INTEGER_BITS);
+	do_div(_pcw, priv->tree->xtal2_rate);
+
+	*pcw = (u32)_pcw;
+}
+
+static ulong mtk_apmixedsys_set_rate(struct clk *clk, ulong rate)
+{
+	u32 pcw = 0;
+	u32 postdiv;
+
+	mtk_pll_calc_values(clk, &pcw, &postdiv, rate);
+	mtk_pll_set_rate_regs(clk, pcw, postdiv);
+
+	return 0;
+}
+
+static ulong mtk_apmixedsys_get_rate(struct clk *clk)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+	const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+	u32 postdiv;
+	u32 pcw;
+
+	postdiv = (readl(priv->base + pll->pd_reg) >> pll->pd_shift) &
+		   POSTDIV_MASK;
+	postdiv = 1 << postdiv;
+
+	pcw = readl(priv->base + pll->pcw_reg) >> pll->pcw_shift;
+	pcw &= GENMASK(pll->pcwbits - 1, 0);
+
+	return __mtk_pll_recalc_rate(pll, priv->tree->xtal2_rate,
+				     pcw, postdiv);
+}
+
+static int mtk_apmixedsys_enable(struct clk *clk)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+	const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+	u32 r;
+
+	r = readl(priv->base + pll->pwr_reg) | CON0_PWR_ON;
+	writel(r, priv->base + pll->pwr_reg);
+	udelay(1);
+
+	r = readl(priv->base + pll->pwr_reg) & ~CON0_ISO_EN;
+	writel(r, priv->base + pll->pwr_reg);
+	udelay(1);
+
+	r = readl(priv->base + pll->reg + REG_CON0);
+	r |= pll->en_mask;
+	writel(r, priv->base + pll->reg + REG_CON0);
+
+	udelay(20);
+
+	if (pll->flags & HAVE_RST_BAR) {
+		r = readl(priv->base + pll->reg + REG_CON0);
+		r |= pll->rst_bar_mask;
+		writel(r, priv->base + pll->reg + REG_CON0);
+	}
+
+	return 0;
+}
+
+static int mtk_apmixedsys_disable(struct clk *clk)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+	const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+	u32 r;
+
+	if (pll->flags & HAVE_RST_BAR) {
+		r = readl(priv->base + pll->reg + REG_CON0);
+		r &= ~pll->rst_bar_mask;
+		writel(r, priv->base + pll->reg + REG_CON0);
+	}
+
+	r = readl(priv->base + pll->reg + REG_CON0);
+	r &= ~CON0_BASE_EN;
+	writel(r, priv->base + pll->reg + REG_CON0);
+
+	r = readl(priv->base + pll->pwr_reg) | CON0_ISO_EN;
+	writel(r, priv->base + pll->pwr_reg);
+
+	r = readl(priv->base + pll->pwr_reg) & ~CON0_PWR_ON;
+	writel(r, priv->base + pll->pwr_reg);
+
+	return 0;
+}
+
+/* topckgen functions */
+
+static ulong mtk_factor_recalc_rate(const struct mtk_fixed_factor *fdiv,
+				    ulong parent_rate)
+{
+	u64 rate = parent_rate * fdiv->mult;
+
+	do_div(rate, fdiv->div);
+
+	return rate;
+}
+
+static int mtk_topckgen_get_factor_rate(struct clk *clk, u32 off)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+	const struct mtk_fixed_factor *fdiv = &priv->tree->fdivs[off];
+	ulong rate;
+
+	switch (fdiv->flags & CLK_PARENT_MASK) {
+	case CLK_PARENT_APMIXED:
+		rate = mtk_clk_find_parent_rate(clk, fdiv->parent,
+				DM_GET_DRIVER(mtk_clk_apmixedsys));
+		break;
+	case CLK_PARENT_TOPCKGEN:
+		rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL);
+		break;
+
+	default:
+		rate = priv->tree->xtal_rate;
+	}
+
+	return mtk_factor_recalc_rate(fdiv, rate);
+}
+
+static int mtk_topckgen_get_mux_rate(struct clk *clk, u32 off)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+	const struct mtk_composite *mux = &priv->tree->muxes[off];
+	u32 index;
+
+	index = readl(priv->base + mux->mux_reg);
+	index &= mux->mux_mask << mux->mux_shift;
+	index = index >> mux->mux_shift;
+
+	if (mux->parent[index])
+		return mtk_clk_find_parent_rate(clk, mux->parent[index],
+						NULL);
+
+	return priv->tree->xtal_rate;
+}
+
+static ulong mtk_topckgen_get_rate(struct clk *clk)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+
+	if (clk->id < priv->tree->fdivs_offs)
+		return priv->tree->fclks[clk->id].rate;
+	else if (clk->id < priv->tree->muxes_offs)
+		return mtk_topckgen_get_factor_rate(clk, clk->id -
+						    priv->tree->fdivs_offs);
+	else
+		return mtk_topckgen_get_mux_rate(clk, clk->id -
+						 priv->tree->muxes_offs);
+}
+
+static int mtk_topckgen_enable(struct clk *clk)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+	const struct mtk_composite *mux;
+	u32 val;
+
+	if (clk->id < priv->tree->muxes_offs)
+		return 0;
+
+	mux = &priv->tree->muxes[clk->id - priv->tree->muxes_offs];
+	if (mux->gate_shift < 0)
+		return 0;
+
+	/* enable clock gate */
+	val = readl(priv->base + mux->gate_reg);
+	val &= ~BIT(mux->gate_shift);
+	writel(val, priv->base + mux->gate_reg);
+
+	if (mux->flags & CLK_DOMAIN_SCPSYS) {
+		/* enable scpsys clock off control */
+		writel(SCP_ARMCK_OFF_EN, priv->base + CLK_SCP_CFG0);
+		writel(SCP_AXICK_DCM_DIS_EN | SCP_AXICK_26M_SEL_EN,
+		       priv->base + CLK_SCP_CFG1);
+	}
+
+	return 0;
+}
+
+static int mtk_topckgen_disable(struct clk *clk)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+	const struct mtk_composite *mux;
+	u32 val;
+
+	if (clk->id < priv->tree->muxes_offs)
+		return 0;
+
+	mux = &priv->tree->muxes[clk->id - priv->tree->muxes_offs];
+	if (mux->gate_shift < 0)
+		return 0;
+
+	/* disable clock gate */
+	val = readl(priv->base + mux->gate_reg);
+	val |= BIT(mux->gate_shift);
+	writel(val, priv->base + mux->gate_reg);
+
+	return 0;
+}
+
+static int mtk_topckgen_set_parent(struct clk *clk, struct clk *parent)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+
+	if (clk->id < priv->tree->muxes_offs)
+		return 0;
+
+	return mtk_clk_mux_set_parent(priv->base, parent->id,
+			&priv->tree->muxes[clk->id - priv->tree->muxes_offs]);
+}
+
+/* CG functions */
+
+static int mtk_clk_gate_enable(struct clk *clk)
+{
+	struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
+	const struct mtk_gate *gate = &priv->gates[clk->id];
+	u32 bit = BIT(gate->shift);
+
+	switch (gate->flags & CLK_GATE_MASK) {
+	case CLK_GATE_SETCLR:
+		writel(bit, priv->base + gate->regs->clr_ofs);
+		break;
+	case CLK_GATE_NO_SETCLR_INV:
+		clrsetbits_le32(priv->base + gate->regs->sta_ofs, bit, bit);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mtk_clk_gate_disable(struct clk *clk)
+{
+	struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
+	const struct mtk_gate *gate = &priv->gates[clk->id];
+	u32 bit = BIT(gate->shift);
+
+	switch (gate->flags & CLK_GATE_MASK) {
+	case CLK_GATE_SETCLR:
+		writel(bit, priv->base + gate->regs->set_ofs);
+		break;
+	case CLK_GATE_NO_SETCLR_INV:
+		clrsetbits_le32(priv->base + gate->regs->sta_ofs, bit, 0);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static ulong mtk_clk_gate_get_rate(struct clk *clk)
+{
+	struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
+	const struct mtk_gate *gate = &priv->gates[clk->id];
+
+	switch (gate->flags & CLK_PARENT_MASK) {
+	case CLK_PARENT_APMIXED:
+		return mtk_clk_find_parent_rate(clk, gate->parent,
+				DM_GET_DRIVER(mtk_clk_apmixedsys));
+		break;
+	case CLK_PARENT_TOPCKGEN:
+		return mtk_clk_find_parent_rate(clk, gate->parent,
+				DM_GET_DRIVER(mtk_clk_topckgen));
+		break;
+
+	default:
+		return priv->tree->xtal_rate;
+	}
+}
+
+const struct clk_ops mtk_clk_apmixedsys_ops = {
+	.enable = mtk_apmixedsys_enable,
+	.disable = mtk_apmixedsys_disable,
+	.set_rate = mtk_apmixedsys_set_rate,
+	.get_rate = mtk_apmixedsys_get_rate,
+};
+
+const struct clk_ops mtk_clk_topckgen_ops = {
+	.enable = mtk_topckgen_enable,
+	.disable = mtk_topckgen_disable,
+	.get_rate = mtk_topckgen_get_rate,
+	.set_parent = mtk_topckgen_set_parent,
+};
+
+const struct clk_ops mtk_clk_gate_ops = {
+	.enable = mtk_clk_gate_enable,
+	.disable = mtk_clk_gate_disable,
+	.get_rate = mtk_clk_gate_get_rate,
+};
+
+int mtk_common_clk_init(struct udevice *dev,
+			const struct mtk_clk_tree *tree)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(dev);
+
+	priv->base = dev_read_addr_ptr(dev);
+	if (!priv->base)
+		return -ENOENT;
+
+	priv->tree = tree;
+
+	return 0;
+}
+
+int mtk_common_clk_gate_init(struct udevice *dev,
+			     const struct mtk_clk_tree *tree,
+			     const struct mtk_gate *gates)
+{
+	struct mtk_cg_priv *priv = dev_get_priv(dev);
+
+	priv->base = dev_read_addr_ptr(dev);
+	if (!priv->base)
+		return -ENOENT;
+
+	priv->tree = tree;
+	priv->gates = gates;
+
+	return 0;
+}
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
new file mode 100644
index 0000000..74152ed
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -0,0 +1,194 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#ifndef __DRV_CLK_MTK_H
+#define __DRV_CLK_MTK_H
+
+#define CLK_XTAL			0
+#define MHZ				(1000 * 1000)
+
+#define HAVE_RST_BAR			BIT(0)
+#define CLK_DOMAIN_SCPSYS		BIT(0)
+
+#define CLK_GATE_SETCLR			BIT(0)
+#define CLK_GATE_SETCLR_INV		BIT(1)
+#define CLK_GATE_NO_SETCLR		BIT(2)
+#define CLK_GATE_NO_SETCLR_INV		BIT(3)
+#define CLK_GATE_MASK			GENMASK(3, 0)
+
+#define CLK_PARENT_APMIXED		BIT(4)
+#define CLK_PARENT_TOPCKGEN		BIT(5)
+#define CLK_PARENT_MASK			GENMASK(5, 4)
+
+/* struct mtk_pll_data - hardware-specific PLLs data */
+struct mtk_pll_data {
+	const int id;
+	u32 reg;
+	u32 pwr_reg;
+	u32 en_mask;
+	u32 pd_reg;
+	int pd_shift;
+	u32 flags;
+	u32 rst_bar_mask;
+	u64 fmax;
+	int pcwbits;
+	u32 pcw_reg;
+	int pcw_shift;
+};
+
+/**
+ * struct mtk_fixed_clk - fixed clocks
+ *
+ * @id:		index of clocks
+ * @parent:	index of parnet clocks
+ * @rate:	fixed rate
+ */
+struct mtk_fixed_clk {
+	const int id;
+	const int parent;
+	unsigned long rate;
+};
+
+#define FIXED_CLK(_id, _parent, _rate) {		\
+		.id = _id,				\
+		.parent = _parent,			\
+		.rate = _rate,				\
+	}
+
+/**
+ * struct mtk_fixed_factor - fixed multiplier and divider clocks
+ *
+ * @id:		index of clocks
+ * @parent:	index of parnet clocks
+ * @mult:	multiplier
+ * @div:	divider
+ * @flag:	hardware-specific flags
+ */
+struct mtk_fixed_factor {
+	const int id;
+	const int parent;
+	u32 mult;
+	u32 div;
+	u32 flags;
+};
+
+#define FACTOR(_id, _parent, _mult, _div, _flags) {	\
+		.id = _id,				\
+		.parent = _parent,			\
+		.mult = _mult,				\
+		.div = _div,				\
+		.flags = _flags,			\
+	}
+
+/**
+ * struct mtk_composite - aggregate clock of mux, divider and gate clocks
+ *
+ * @id:			index of clocks
+ * @parent:		index of parnet clocks
+ * @mux_reg:		hardware-specific mux register
+ * @gate_reg:		hardware-specific gate register
+ * @mux_mask:		mask to the mux bit field
+ * @mux_shift:		shift to the mux bit field
+ * @gate_shift:		shift to the gate bit field
+ * @num_parents:	number of parent clocks
+ * @flags:		hardware-specific flags
+ */
+struct mtk_composite {
+	const int id;
+	const int *parent;
+	u32 mux_reg;
+	u32 gate_reg;
+	u32 mux_mask;
+	signed char mux_shift;
+	signed char gate_shift;
+	signed char num_parents;
+	u16 flags;
+};
+
+#define MUX_GATE_FLAGS(_id, _parents, _reg, _shift, _width, _gate,	\
+		       _flags) {					\
+		.id = _id,						\
+		.mux_reg = _reg,					\
+		.mux_shift = _shift,					\
+		.mux_mask = BIT(_width) - 1,				\
+		.gate_reg = _reg,					\
+		.gate_shift = _gate,					\
+		.parent = _parents,					\
+		.num_parents = ARRAY_SIZE(_parents),			\
+		.flags = _flags,					\
+	}
+
+#define MUX_GATE(_id, _parents, _reg, _shift, _width, _gate)		\
+	MUX_GATE_FLAGS(_id, _parents, _reg, _shift, _width, _gate, 0)
+
+#define MUX(_id, _parents, _reg, _shift, _width) {			\
+		.id = _id,						\
+		.mux_reg = _reg,					\
+		.mux_shift = _shift,					\
+		.mux_mask = BIT(_width) - 1,				\
+		.gate_shift = -1,					\
+		.parent = _parents,					\
+		.num_parents = ARRAY_SIZE(_parents),			\
+		.flags = 0,						\
+	}
+
+struct mtk_gate_regs {
+	u32 sta_ofs;
+	u32 clr_ofs;
+	u32 set_ofs;
+};
+
+/**
+ * struct mtk_gate - gate clocks
+ *
+ * @id:		index of gate clocks
+ * @parent:	index of parnet clocks
+ * @regs:	hardware-specific mux register
+ * @shift:	shift to the gate bit field
+ * @flags:	hardware-specific flags
+ */
+struct mtk_gate {
+	const int id;
+	const int parent;
+	const struct mtk_gate_regs *regs;
+	int shift;
+	u32 flags;
+};
+
+/* struct mtk_clk_tree - clock tree */
+struct mtk_clk_tree {
+	unsigned long xtal_rate;
+	unsigned long xtal2_rate;
+	const int fdivs_offs;
+	const int muxes_offs;
+	const struct mtk_pll_data *plls;
+	const struct mtk_fixed_clk *fclks;
+	const struct mtk_fixed_factor *fdivs;
+	const struct mtk_composite *muxes;
+};
+
+struct mtk_clk_priv {
+	void __iomem *base;
+	const struct mtk_clk_tree *tree;
+};
+
+struct mtk_cg_priv {
+	void __iomem *base;
+	const struct mtk_clk_tree *tree;
+	const struct mtk_gate *gates;
+};
+
+extern const struct clk_ops mtk_clk_apmixedsys_ops;
+extern const struct clk_ops mtk_clk_topckgen_ops;
+extern const struct clk_ops mtk_clk_gate_ops;
+
+int mtk_common_clk_init(struct udevice *dev,
+			const struct mtk_clk_tree *tree);
+int mtk_common_clk_gate_init(struct udevice *dev,
+			     const struct mtk_clk_tree *tree,
+			     const struct mtk_gate *gates);
+
+#endif /* __DRV_CLK_MTK_H */
diff --git a/drivers/clk/renesas/clk-rcar-gen3.c b/drivers/clk/renesas/clk-rcar-gen3.c
index 99698b1..0529fc8 100644
--- a/drivers/clk/renesas/clk-rcar-gen3.c
+++ b/drivers/clk/renesas/clk-rcar-gen3.c
@@ -107,7 +107,7 @@
 	return renesas_clk_get_parent(clk, info, parent);
 }
 
-static int gen3_clk_setup_sdif_div(struct clk *clk)
+static int gen3_clk_setup_sdif_div(struct clk *clk, ulong rate)
 {
 	struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
 	struct cpg_mssr_info *info = priv->info;
@@ -133,7 +133,7 @@
 
 	debug("%s[%i] SDIF offset=%x\n", __func__, __LINE__, core->offset);
 
-	writel(1, priv->base + core->offset);
+	writel((rate == 400000000) ? 0x4 : 0x1, priv->base + core->offset);
 
 	return 0;
 }
@@ -141,10 +141,6 @@
 static int gen3_clk_enable(struct clk *clk)
 {
 	struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
-	int ret = gen3_clk_setup_sdif_div(clk);
-
-	if (ret)
-		return ret;
 
 	return renesas_clk_endisable(clk, priv->base, true);
 }
@@ -328,7 +324,7 @@
 static ulong gen3_clk_set_rate(struct clk *clk, ulong rate)
 {
 	/* Force correct SD-IF divider configuration if applicable */
-	gen3_clk_setup_sdif_div(clk);
+	gen3_clk_setup_sdif_div(clk, rate);
 	return gen3_clk_get_rate64(clk);
 }
 
diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index 26faf88..198914b 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -61,6 +61,11 @@
 	[APLL_L_600_MHZ] = &apll_l_600_cfg,
 };
 
+static const struct pll_div apll_b_600_cfg = PLL_DIVISORS(600*MHz, 1, 2, 1);
+static const struct pll_div *apll_b_cfgs[] = {
+	[APLL_B_600_MHZ] = &apll_b_600_cfg,
+};
+
 enum {
 	/* PLL_CON0 */
 	PLL_FBDIV_MASK			= 0xfff,
@@ -128,6 +133,24 @@
 	ATCLK_CORE_L_DIV_SHIFT		= 0,
 	ATCLK_CORE_L_DIV_MASK		= 0x1f << ATCLK_CORE_L_DIV_SHIFT,
 
+	/* CLKSEL_CON2 */
+	ACLKM_CORE_B_DIV_CON_SHIFT	= 8,
+	ACLKM_CORE_B_DIV_CON_MASK	= 0x1f << ACLKM_CORE_B_DIV_CON_SHIFT,
+	CLK_CORE_B_PLL_SEL_SHIFT	= 6,
+	CLK_CORE_B_PLL_SEL_MASK		= 3 << CLK_CORE_B_PLL_SEL_SHIFT,
+	CLK_CORE_B_PLL_SEL_ALPLL	= 0x0,
+	CLK_CORE_B_PLL_SEL_ABPLL	= 0x1,
+	CLK_CORE_B_PLL_SEL_DPLL		= 0x10,
+	CLK_CORE_B_PLL_SEL_GPLL		= 0x11,
+	CLK_CORE_B_DIV_MASK		= 0x1f,
+	CLK_CORE_B_DIV_SHIFT		= 0,
+
+	/* CLKSEL_CON3 */
+	PCLK_DBG_B_DIV_SHIFT		= 0x8,
+	PCLK_DBG_B_DIV_MASK		= 0x1f << PCLK_DBG_B_DIV_SHIFT,
+	ATCLK_CORE_B_DIV_SHIFT		= 0,
+	ATCLK_CORE_B_DIV_MASK		= 0x1f << ATCLK_CORE_B_DIV_SHIFT,
+
 	/* CLKSEL_CON14 */
 	PCLK_PERIHP_DIV_CON_SHIFT	= 12,
 	PCLK_PERIHP_DIV_CON_MASK	= 0x7 << PCLK_PERIHP_DIV_CON_SHIFT,
@@ -395,25 +418,26 @@
 	return 0;
 }
 
-void rk3399_configure_cpu(struct rk3399_cru *cru,
-			  enum apll_l_frequencies apll_l_freq)
+void rk3399_configure_cpu_l(struct rk3399_cru *cru,
+			    enum apll_l_frequencies apll_l_freq)
 {
 	u32 aclkm_div;
 	u32 pclk_dbg_div;
 	u32 atclk_div;
 
+	/* Setup cluster L */
 	rkclk_set_pll(&cru->apll_l_con[0], apll_l_cfgs[apll_l_freq]);
 
-	aclkm_div = APLL_HZ / ACLKM_CORE_HZ - 1;
-	assert((aclkm_div + 1) * ACLKM_CORE_HZ == APLL_HZ &&
+	aclkm_div = LPLL_HZ / ACLKM_CORE_L_HZ - 1;
+	assert((aclkm_div + 1) * ACLKM_CORE_L_HZ == LPLL_HZ &&
 	       aclkm_div < 0x1f);
 
-	pclk_dbg_div = APLL_HZ / PCLK_DBG_HZ - 1;
-	assert((pclk_dbg_div + 1) * PCLK_DBG_HZ == APLL_HZ &&
+	pclk_dbg_div = LPLL_HZ / PCLK_DBG_L_HZ - 1;
+	assert((pclk_dbg_div + 1) * PCLK_DBG_L_HZ == LPLL_HZ &&
 	       pclk_dbg_div < 0x1f);
 
-	atclk_div = APLL_HZ / ATCLK_CORE_HZ - 1;
-	assert((atclk_div + 1) * ATCLK_CORE_HZ == APLL_HZ &&
+	atclk_div = LPLL_HZ / ATCLK_CORE_L_HZ - 1;
+	assert((atclk_div + 1) * ATCLK_CORE_L_HZ == LPLL_HZ &&
 	       atclk_div < 0x1f);
 
 	rk_clrsetreg(&cru->clksel_con[0],
@@ -428,6 +452,42 @@
 		     pclk_dbg_div << PCLK_DBG_L_DIV_SHIFT |
 		     atclk_div << ATCLK_CORE_L_DIV_SHIFT);
 }
+
+void rk3399_configure_cpu_b(struct rk3399_cru *cru,
+			    enum apll_b_frequencies apll_b_freq)
+{
+	u32 aclkm_div;
+	u32 pclk_dbg_div;
+	u32 atclk_div;
+
+	/* Setup cluster B */
+	rkclk_set_pll(&cru->apll_b_con[0], apll_b_cfgs[apll_b_freq]);
+
+	aclkm_div = BPLL_HZ / ACLKM_CORE_B_HZ - 1;
+	assert((aclkm_div + 1) * ACLKM_CORE_B_HZ == BPLL_HZ &&
+	       aclkm_div < 0x1f);
+
+	pclk_dbg_div = BPLL_HZ / PCLK_DBG_B_HZ - 1;
+	assert((pclk_dbg_div + 1) * PCLK_DBG_B_HZ == BPLL_HZ &&
+	       pclk_dbg_div < 0x1f);
+
+	atclk_div = BPLL_HZ / ATCLK_CORE_B_HZ - 1;
+	assert((atclk_div + 1) * ATCLK_CORE_B_HZ == BPLL_HZ &&
+	       atclk_div < 0x1f);
+
+	rk_clrsetreg(&cru->clksel_con[2],
+		     ACLKM_CORE_B_DIV_CON_MASK | CLK_CORE_B_PLL_SEL_MASK |
+		     CLK_CORE_B_DIV_MASK,
+		     aclkm_div << ACLKM_CORE_B_DIV_CON_SHIFT |
+		     CLK_CORE_B_PLL_SEL_ABPLL << CLK_CORE_B_PLL_SEL_SHIFT |
+		     0 << CLK_CORE_B_DIV_SHIFT);
+
+	rk_clrsetreg(&cru->clksel_con[3],
+		     PCLK_DBG_B_DIV_MASK | ATCLK_CORE_B_DIV_MASK,
+		     pclk_dbg_div << PCLK_DBG_B_DIV_SHIFT |
+		     atclk_div << ATCLK_CORE_B_DIV_SHIFT);
+}
+
 #define I2C_CLK_REG_MASK(bus) \
 			(I2C_DIV_CON_MASK << \
 			CLK_I2C ##bus## _DIV_CON_SHIFT | \
@@ -1026,7 +1086,8 @@
 	u32 hclk_div;
 	u32 pclk_div;
 
-	rk3399_configure_cpu(cru, APLL_L_600_MHZ);
+	rk3399_configure_cpu_l(cru, APLL_L_600_MHZ);
+	rk3399_configure_cpu_b(cru, APLL_B_600_MHZ);
 	/*
 	 * some cru registers changed by bootrom, we'd better reset them to
 	 * reset/default values described in TRM to avoid confusion in kernel.
diff --git a/drivers/clk/rockchip/clk_rv1108.c b/drivers/clk/rockchip/clk_rv1108.c
index 1f9f534..914e2f4 100644
--- a/drivers/clk/rockchip/clk_rv1108.c
+++ b/drivers/clk/rockchip/clk_rv1108.c
@@ -17,6 +17,8 @@
 #include <dm/lists.h>
 #include <dt-bindings/clock/rv1108-cru.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 enum {
 	VCO_MAX_HZ	= 2400U * 1000000,
 	VCO_MIN_HZ	= 600 * 1000000,
@@ -35,6 +37,9 @@
 			 #hz "Hz cannot be hit with PLL "\
 			 "divisors on line " __stringify(__LINE__));
 
+static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1);
+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
+
 /* use integer mode */
 static inline int rv1108_pll_id(enum rk_clk_id clk_id)
 {
@@ -57,6 +62,58 @@
 	return id;
 }
 
+static int rkclk_set_pll(struct rv1108_cru *cru, enum rk_clk_id clk_id,
+			 const struct pll_div *div)
+{
+	int pll_id = rv1108_pll_id(clk_id);
+	struct rv1108_pll *pll = &cru->pll[pll_id];
+
+	/* All PLLs have same VCO and output frequency range restrictions. */
+	uint vco_hz = OSC_HZ / 1000 * div->fbdiv / div->refdiv * 1000;
+	uint output_hz = vco_hz / div->postdiv1 / div->postdiv2;
+
+	debug("PLL at %p: fb=%d, ref=%d, pst1=%d, pst2=%d, vco=%u Hz, output=%u Hz\n",
+	      pll, div->fbdiv, div->refdiv, div->postdiv1,
+	      div->postdiv2, vco_hz, output_hz);
+	assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
+	       output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ);
+
+	/*
+	 * When power on or changing PLL setting,
+	 * we must force PLL into slow mode to ensure output stable clock.
+	 */
+	rk_clrsetreg(&pll->con3, WORK_MODE_MASK,
+		     WORK_MODE_SLOW << WORK_MODE_SHIFT);
+
+	/* use integer mode */
+	rk_setreg(&pll->con3, 1 << DSMPD_SHIFT);
+	/* Power down */
+	rk_setreg(&pll->con3, 1 << GLOBAL_POWER_DOWN_SHIFT);
+
+	rk_clrsetreg(&pll->con0, FBDIV_MASK, div->fbdiv << FBDIV_SHIFT);
+	rk_clrsetreg(&pll->con1, POSTDIV1_MASK | POSTDIV2_MASK | REFDIV_MASK,
+		     (div->postdiv1 << POSTDIV1_SHIFT |
+		     div->postdiv2 << POSTDIV2_SHIFT |
+		     div->refdiv << REFDIV_SHIFT));
+	rk_clrsetreg(&pll->con2, FRACDIV_MASK,
+		     (div->refdiv << REFDIV_SHIFT));
+
+	/* Power Up */
+	rk_clrreg(&pll->con3, 1 << GLOBAL_POWER_DOWN_SHIFT);
+
+	/* waiting for pll lock */
+	while (readl(&pll->con2) & (1 << LOCK_STA_SHIFT))
+		udelay(1);
+
+	/*
+	 * set PLL into normal mode.
+	 */
+	rk_clrsetreg(&pll->con3, WORK_MODE_MASK,
+		     WORK_MODE_NORMAL << WORK_MODE_SHIFT);
+
+	return 0;
+}
+
 static uint32_t rkclk_pll_get_rate(struct rv1108_cru *cru,
 				   enum rk_clk_id clk_id)
 {
@@ -74,7 +131,7 @@
 		fbdiv = (con0 >> FBDIV_SHIFT) & FBDIV_MASK;
 		postdiv1 = (con1 & POSTDIV1_MASK) >> POSTDIV1_SHIFT;
 		postdiv2 = (con1 & POSTDIV2_MASK) >> POSTDIV2_SHIFT;
-		refdiv = (con1 & REFDIV_MASK) >> REFDIV_SHIFT;
+		refdiv = (con1 >> REFDIV_SHIFT) & REFDIV_MASK;
 		freq = (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
 	} else {
 		freq = OSC_HZ;
@@ -154,6 +211,326 @@
 	return rv1108_saradc_get_clk(cru);
 }
 
+static ulong rv1108_aclk_vio1_get_clk(struct rv1108_cru *cru)
+{
+	u32 div, val;
+
+	val = readl(&cru->clksel_con[28]);
+	div = bitfield_extract(val, ACLK_VIO1_CLK_DIV_SHIFT,
+			       CLK_VIO_DIV_CON_WIDTH);
+
+	return DIV_TO_RATE(GPLL_HZ, div);
+}
+
+static ulong rv1108_aclk_vio1_set_clk(struct rv1108_cru *cru, uint hz)
+{
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
+	assert(src_clk_div < 32);
+
+	rk_clrsetreg(&cru->clksel_con[28],
+		     ACLK_VIO1_CLK_DIV_MASK | ACLK_VIO1_PLL_SEL_MASK,
+		     (src_clk_div << ACLK_VIO1_CLK_DIV_SHIFT) |
+		     (VIO_PLL_SEL_GPLL << ACLK_VIO1_PLL_SEL_SHIFT));
+
+	return rv1108_aclk_vio1_get_clk(cru);
+}
+
+static ulong rv1108_aclk_vio0_get_clk(struct rv1108_cru *cru)
+{
+	u32 div, val;
+
+	val = readl(&cru->clksel_con[28]);
+	div = bitfield_extract(val, ACLK_VIO0_CLK_DIV_SHIFT,
+			       CLK_VIO_DIV_CON_WIDTH);
+
+	return DIV_TO_RATE(GPLL_HZ, div);
+}
+
+static ulong rv1108_aclk_vio0_set_clk(struct rv1108_cru *cru, uint hz)
+{
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
+	assert(src_clk_div < 32);
+
+	rk_clrsetreg(&cru->clksel_con[28],
+		     ACLK_VIO0_CLK_DIV_MASK | ACLK_VIO0_PLL_SEL_MASK,
+		     (src_clk_div << ACLK_VIO0_CLK_DIV_SHIFT) |
+		     (VIO_PLL_SEL_GPLL << ACLK_VIO0_PLL_SEL_SHIFT));
+
+	/*HCLK_VIO default div = 4*/
+	rk_clrsetreg(&cru->clksel_con[29],
+		     HCLK_VIO_CLK_DIV_MASK,
+		     3 << HCLK_VIO_CLK_DIV_SHIFT);
+	/*PCLK_VIO default div = 4*/
+	rk_clrsetreg(&cru->clksel_con[29],
+		     PCLK_VIO_CLK_DIV_MASK,
+		     3 << PCLK_VIO_CLK_DIV_SHIFT);
+
+	return rv1108_aclk_vio0_get_clk(cru);
+}
+
+static ulong rv1108_dclk_vop_get_clk(struct rv1108_cru *cru)
+{
+	u32 div, val;
+
+	val = readl(&cru->clksel_con[32]);
+	div = bitfield_extract(val, DCLK_VOP_CLK_DIV_SHIFT,
+			       DCLK_VOP_DIV_CON_WIDTH);
+
+	return DIV_TO_RATE(GPLL_HZ, div);
+}
+
+static ulong rv1108_dclk_vop_set_clk(struct rv1108_cru *cru, uint hz)
+{
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
+	assert(src_clk_div < 64);
+
+	rk_clrsetreg(&cru->clksel_con[32],
+		     DCLK_VOP_CLK_DIV_MASK | DCLK_VOP_PLL_SEL_MASK |
+		     DCLK_VOP_SEL_SHIFT,
+		     (src_clk_div << DCLK_VOP_CLK_DIV_SHIFT) |
+		     (DCLK_VOP_PLL_SEL_GPLL << DCLK_VOP_PLL_SEL_SHIFT) |
+		     (DCLK_VOP_SEL_PLL << DCLK_VOP_SEL_SHIFT));
+
+	return rv1108_dclk_vop_get_clk(cru);
+}
+
+static ulong rv1108_aclk_bus_get_clk(struct rv1108_cru *cru)
+{
+	u32 div, val;
+	ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
+
+	val = readl(&cru->clksel_con[2]);
+	div = bitfield_extract(val, ACLK_BUS_DIV_CON_SHIFT,
+			       ACLK_BUS_DIV_CON_WIDTH);
+
+	return DIV_TO_RATE(parent_rate, div);
+}
+
+static ulong rv1108_aclk_bus_set_clk(struct rv1108_cru *cru, uint hz)
+{
+	int src_clk_div;
+	ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
+
+	src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
+	assert(src_clk_div < 32);
+
+	rk_clrsetreg(&cru->clksel_con[2],
+		     ACLK_BUS_DIV_CON_MASK | ACLK_BUS_PLL_SEL_MASK,
+		     (src_clk_div << ACLK_BUS_DIV_CON_SHIFT) |
+		     (ACLK_BUS_PLL_SEL_GPLL << ACLK_BUS_PLL_SEL_SHIFT));
+
+	return rv1108_aclk_bus_get_clk(cru);
+}
+
+static ulong rv1108_aclk_peri_get_clk(struct rv1108_cru *cru)
+{
+	u32 div, val;
+	ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
+
+	val = readl(&cru->clksel_con[23]);
+	div = bitfield_extract(val, ACLK_PERI_DIV_CON_SHIFT,
+			       PERI_DIV_CON_WIDTH);
+
+	return DIV_TO_RATE(parent_rate, div);
+}
+
+static ulong rv1108_hclk_peri_get_clk(struct rv1108_cru *cru)
+{
+	u32 div, val;
+	ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
+
+	val = readl(&cru->clksel_con[23]);
+	div = bitfield_extract(val, HCLK_PERI_DIV_CON_SHIFT,
+			       PERI_DIV_CON_WIDTH);
+
+	return DIV_TO_RATE(parent_rate, div);
+}
+
+static ulong rv1108_pclk_peri_get_clk(struct rv1108_cru *cru)
+{
+	u32 div, val;
+	ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
+
+	val = readl(&cru->clksel_con[23]);
+	div = bitfield_extract(val, PCLK_PERI_DIV_CON_SHIFT,
+			       PERI_DIV_CON_WIDTH);
+
+	return DIV_TO_RATE(parent_rate, div);
+}
+
+static ulong rv1108_aclk_peri_set_clk(struct rv1108_cru *cru, uint hz)
+{
+	int src_clk_div;
+	ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
+
+	src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
+	assert(src_clk_div < 32);
+
+	rk_clrsetreg(&cru->clksel_con[23],
+		     ACLK_PERI_DIV_CON_MASK | ACLK_PERI_PLL_SEL_MASK,
+		     (src_clk_div << ACLK_PERI_DIV_CON_SHIFT) |
+		     (ACLK_PERI_PLL_SEL_GPLL << ACLK_PERI_PLL_SEL_SHIFT));
+
+	return rv1108_aclk_peri_get_clk(cru);
+}
+
+static ulong rv1108_hclk_peri_set_clk(struct rv1108_cru *cru, uint hz)
+{
+	int src_clk_div;
+	ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
+
+	src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
+	assert(src_clk_div < 32);
+
+	rk_clrsetreg(&cru->clksel_con[23],
+		     HCLK_PERI_DIV_CON_MASK,
+		     (src_clk_div << HCLK_PERI_DIV_CON_SHIFT));
+
+	return rv1108_hclk_peri_get_clk(cru);
+}
+
+static ulong rv1108_pclk_peri_set_clk(struct rv1108_cru *cru, uint hz)
+{
+	int src_clk_div;
+	ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
+
+	src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
+	assert(src_clk_div < 32);
+
+	rk_clrsetreg(&cru->clksel_con[23],
+		     PCLK_PERI_DIV_CON_MASK,
+		     (src_clk_div << PCLK_PERI_DIV_CON_SHIFT));
+
+	return rv1108_pclk_peri_get_clk(cru);
+}
+
+static ulong rv1108_i2c_get_clk(struct rv1108_cru *cru, ulong clk_id)
+{
+	u32 div, con;
+
+	switch (clk_id) {
+	case SCLK_I2C0_PMU:
+		con = readl(&cru->clksel_con[19]);
+		div = bitfield_extract(con, CLK_I2C0_DIV_CON_SHIFT,
+				       I2C_DIV_CON_WIDTH);
+		break;
+	case SCLK_I2C1:
+		con = readl(&cru->clksel_con[19]);
+		div = bitfield_extract(con, CLK_I2C1_DIV_CON_SHIFT,
+				       I2C_DIV_CON_WIDTH);
+		break;
+	case SCLK_I2C2:
+		con = readl(&cru->clksel_con[20]);
+		div = bitfield_extract(con, CLK_I2C2_DIV_CON_SHIFT,
+				       I2C_DIV_CON_WIDTH);
+		break;
+	case SCLK_I2C3:
+		con = readl(&cru->clksel_con[20]);
+		div = bitfield_extract(con, CLK_I2C3_DIV_CON_SHIFT,
+				       I2C_DIV_CON_WIDTH);
+		break;
+	default:
+		printf("do not support this i2c bus\n");
+		return -EINVAL;
+	}
+
+	return DIV_TO_RATE(GPLL_HZ, div);
+}
+
+static ulong rv1108_i2c_set_clk(struct rv1108_cru *cru, ulong clk_id, uint hz)
+{
+	int src_clk_div;
+
+	/* i2c0,4,8 src clock from ppll, i2c1,2,3,5,6,7 src clock from gpll*/
+	src_clk_div = GPLL_HZ / hz;
+	assert(src_clk_div - 1 <= 127);
+
+	switch (clk_id) {
+	case SCLK_I2C0_PMU:
+		rk_clrsetreg(&cru->clksel_con[19],
+			     CLK_I2C0_DIV_CON_MASK | CLK_I2C1_PLL_SEL_MASK,
+			     (src_clk_div << CLK_I2C0_DIV_CON_SHIFT) |
+			     (CLK_I2C1_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT));
+		break;
+	case SCLK_I2C1:
+		rk_clrsetreg(&cru->clksel_con[19],
+			     CLK_I2C1_DIV_CON_MASK | CLK_I2C1_PLL_SEL_MASK,
+			     (src_clk_div << CLK_I2C1_DIV_CON_SHIFT) |
+			     (CLK_I2C1_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT));
+		break;
+	case SCLK_I2C2:
+		rk_clrsetreg(&cru->clksel_con[20],
+			     CLK_I2C2_DIV_CON_MASK | CLK_I2C3_PLL_SEL_MASK,
+			     (src_clk_div << CLK_I2C2_DIV_CON_SHIFT) |
+			     (CLK_I2C3_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT));
+		break;
+	case SCLK_I2C3:
+		rk_clrsetreg(&cru->clksel_con[20],
+			     CLK_I2C3_DIV_CON_MASK | CLK_I2C3_PLL_SEL_MASK,
+			     (src_clk_div << CLK_I2C3_DIV_CON_SHIFT) |
+			     (CLK_I2C3_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT));
+		break;
+	default:
+		printf("do not support this i2c bus\n");
+		return -EINVAL;
+	}
+
+	return rv1108_i2c_get_clk(cru, clk_id);
+}
+
+static ulong rv1108_mmc_get_clk(struct rv1108_cru *cru)
+{
+	u32 div, con;
+	ulong mmc_clk;
+
+	con = readl(&cru->clksel_con[26]);
+	div = bitfield_extract(con, EMMC_CLK_DIV_SHIFT, 8);
+
+	con = readl(&cru->clksel_con[25]);
+
+	if ((con & EMMC_PLL_SEL_MASK) >> EMMC_PLL_SEL_SHIFT == EMMC_PLL_SEL_OSC)
+		mmc_clk = DIV_TO_RATE(OSC_HZ, div) / 2;
+	else
+		mmc_clk = DIV_TO_RATE(GPLL_HZ, div) / 2;
+
+	debug("%s div %d get_clk %ld\n", __func__, div, mmc_clk);
+	return mmc_clk;
+}
+
+static ulong rv1108_mmc_set_clk(struct rv1108_cru *cru, ulong rate)
+{
+	int div;
+	u32 pll_rate;
+
+	div = DIV_ROUND_UP(rkclk_pll_get_rate(cru, CLK_GENERAL), rate);
+
+	if (div < 127) {
+		debug("%s source gpll\n", __func__);
+		rk_clrsetreg(&cru->clksel_con[25], EMMC_PLL_SEL_MASK,
+			    (EMMC_PLL_SEL_GPLL << EMMC_PLL_SEL_SHIFT));
+		pll_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
+	} else {
+		debug("%s source 24m\n", __func__);
+		rk_clrsetreg(&cru->clksel_con[25], EMMC_PLL_SEL_MASK,
+			    (EMMC_PLL_SEL_OSC << EMMC_PLL_SEL_SHIFT));
+		pll_rate = OSC_HZ;
+	}
+
+	div = DIV_ROUND_UP(pll_rate / 2, rate);
+	rk_clrsetreg(&cru->clksel_con[26], EMMC_CLK_DIV_MASK,
+		    ((div - 1) << EMMC_CLK_DIV_SHIFT));
+
+	debug("%s set_rate %ld div %d\n", __func__,  rate, div);
+
+	return DIV_TO_RATE(pll_rate, div);
+}
+
 static ulong rv1108_clk_get_rate(struct clk *clk)
 {
 	struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
@@ -163,6 +540,29 @@
 		return rkclk_pll_get_rate(priv->cru, clk->id);
 	case SCLK_SARADC:
 		return rv1108_saradc_get_clk(priv->cru);
+	case ACLK_VIO0:
+		return rv1108_aclk_vio0_get_clk(priv->cru);
+	case ACLK_VIO1:
+		return rv1108_aclk_vio1_get_clk(priv->cru);
+	case DCLK_VOP:
+		return rv1108_dclk_vop_get_clk(priv->cru);
+	case ACLK_PRE:
+		return rv1108_aclk_bus_get_clk(priv->cru);
+	case ACLK_PERI:
+		return rv1108_aclk_peri_get_clk(priv->cru);
+	case HCLK_PERI:
+		return rv1108_hclk_peri_get_clk(priv->cru);
+	case PCLK_PERI:
+		return rv1108_pclk_peri_get_clk(priv->cru);
+	case SCLK_I2C0_PMU:
+	case SCLK_I2C1:
+	case SCLK_I2C2:
+	case SCLK_I2C3:
+		return rv1108_i2c_get_clk(priv->cru, clk->id);
+	case HCLK_EMMC:
+	case SCLK_EMMC:
+	case SCLK_EMMC_SAMPLE:
+		return rv1108_mmc_get_clk(priv->cru);
 	default:
 		return -ENOENT;
 	}
@@ -183,6 +583,37 @@
 	case SCLK_SARADC:
 		new_rate = rv1108_saradc_set_clk(priv->cru, rate);
 		break;
+	case ACLK_VIO0:
+		new_rate = rv1108_aclk_vio0_set_clk(priv->cru, rate);
+		break;
+	case ACLK_VIO1:
+		new_rate = rv1108_aclk_vio1_set_clk(priv->cru, rate);
+		break;
+	case DCLK_VOP:
+		new_rate = rv1108_dclk_vop_set_clk(priv->cru, rate);
+		break;
+	case ACLK_PRE:
+		new_rate = rv1108_aclk_bus_set_clk(priv->cru, rate);
+		break;
+	case ACLK_PERI:
+		new_rate = rv1108_aclk_peri_set_clk(priv->cru, rate);
+		break;
+	case HCLK_PERI:
+		new_rate = rv1108_hclk_peri_set_clk(priv->cru, rate);
+		break;
+	case PCLK_PERI:
+		new_rate = rv1108_pclk_peri_set_clk(priv->cru, rate);
+		break;
+	case SCLK_I2C0_PMU:
+	case SCLK_I2C1:
+	case SCLK_I2C2:
+	case SCLK_I2C3:
+		new_rate = rv1108_i2c_set_clk(priv->cru, clk->id, rate);
+		break;
+	case HCLK_EMMC:
+	case SCLK_EMMC:
+		new_rate = rv1108_mmc_set_clk(priv->cru, rate);
+		break;
 	default:
 		return -ENOENT;
 	}
@@ -197,14 +628,34 @@
 
 static void rkclk_init(struct rv1108_cru *cru)
 {
-	unsigned int apll = rkclk_pll_get_rate(cru, CLK_ARM);
-	unsigned int dpll = rkclk_pll_get_rate(cru, CLK_DDR);
-	unsigned int gpll = rkclk_pll_get_rate(cru, CLK_GENERAL);
+	unsigned int apll, dpll, gpll;
+	unsigned int aclk_bus, aclk_peri, hclk_peri, pclk_peri;
+
+	aclk_bus = rv1108_aclk_bus_set_clk(cru, ACLK_BUS_HZ / 2);
+	aclk_peri = rv1108_aclk_peri_set_clk(cru, ACLK_PERI_HZ / 2);
+	hclk_peri = rv1108_hclk_peri_set_clk(cru, HCLK_PERI_HZ / 2);
+	pclk_peri = rv1108_pclk_peri_set_clk(cru, PCLK_PERI_HZ / 2);
+	rv1108_aclk_vio0_set_clk(cru, 297000000);
+	rv1108_aclk_vio1_set_clk(cru, 297000000);
+
+	/* configure apll */
+	rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg);
+	rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
+	aclk_bus = rv1108_aclk_bus_set_clk(cru, ACLK_BUS_HZ);
+	aclk_peri = rv1108_aclk_peri_set_clk(cru, ACLK_PERI_HZ);
+	hclk_peri = rv1108_hclk_peri_set_clk(cru, HCLK_PERI_HZ);
+	pclk_peri = rv1108_pclk_peri_set_clk(cru, PCLK_PERI_HZ);
+
+	apll = rkclk_pll_get_rate(cru, CLK_ARM);
+	dpll = rkclk_pll_get_rate(cru, CLK_DDR);
+	gpll = rkclk_pll_get_rate(cru, CLK_GENERAL);
 
 	rk_clrsetreg(&cru->clksel_con[0], CORE_CLK_DIV_MASK,
 		     0 << MAC_CLK_DIV_SHIFT);
 
 	printf("APLL: %d DPLL:%d GPLL:%d\n", apll, dpll, gpll);
+	printf("ACLK_BUS: %d ACLK_PERI:%d HCLK_PERI:%d PCLK_PERI:%d\n",
+	       aclk_bus, aclk_peri, hclk_peri, pclk_peri);
 }
 
 static int rv1108_clk_ofdata_to_platdata(struct udevice *dev)
@@ -228,8 +679,9 @@
 static int rv1108_clk_bind(struct udevice *dev)
 {
 	int ret;
-	struct udevice *sys_child;
+	struct udevice *sys_child, *sf_child;
 	struct sysreset_reg *priv;
+	struct softreset_reg *sf_priv;
 
 	/* The reset driver does not have a device node, so bind it here */
 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
@@ -251,6 +703,17 @@
 	if (ret)
 		debug("Warning: software reset driver bind faile\n");
 #endif
+	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
+					 dev_ofnode(dev), &sf_child);
+	if (ret) {
+		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
+	} else {
+		sf_priv = malloc(sizeof(struct softreset_reg));
+		sf_priv->sf_reset_offset = offsetof(struct rv1108_cru,
+						    softrst_con[0]);
+		sf_priv->sf_reset_num = 13;
+		sf_child->priv = sf_priv;
+	}
 
 	return 0;
 }
@@ -265,8 +728,8 @@
 	.id		= UCLASS_CLK,
 	.of_match	= rv1108_clk_ids,
 	.priv_auto_alloc_size = sizeof(struct rv1108_clk_priv),
-	.ofdata_to_platdata = rv1108_clk_ofdata_to_platdata,
 	.ops		= &rv1108_clk_ops,
 	.bind		= rv1108_clk_bind,
+	.ofdata_to_platdata	= rv1108_clk_ofdata_to_platdata,
 	.probe		= rv1108_clk_probe,
 };
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 47a697f..836bcad 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -699,6 +699,40 @@
 	return -ENODEV;
 }
 
+int device_find_first_child_by_uclass(struct udevice *parent,
+				      enum uclass_id uclass_id,
+				      struct udevice **devp)
+{
+	struct udevice *dev;
+
+	*devp = NULL;
+	list_for_each_entry(dev, &parent->child_head, sibling_node) {
+		if (device_get_uclass_id(dev) == uclass_id) {
+			*devp = dev;
+			return 0;
+		}
+	}
+
+	return -ENODEV;
+}
+
+int device_find_child_by_name(struct udevice *parent, const char *name,
+			      struct udevice **devp)
+{
+	struct udevice *dev;
+
+	*devp = NULL;
+
+	list_for_each_entry(dev, &parent->child_head, sibling_node) {
+		if (!strcmp(dev->name, name)) {
+			*devp = dev;
+			return 0;
+		}
+	}
+
+	return -ENODEV;
+}
+
 struct udevice *dev_get_parent(const struct udevice *child)
 {
 	return child->parent;
diff --git a/drivers/core/dump.c b/drivers/core/dump.c
index 9068084..04217cb 100644
--- a/drivers/core/dump.c
+++ b/drivers/core/dump.c
@@ -15,8 +15,8 @@
 	int i, is_last;
 	struct udevice *child;
 
-	/* print the first 11 characters to not break the tree-format. */
-	printf(" %-10.10s  %d  [ %c ]   %-10.10s  ", dev->uclass->uc_drv->name,
+	/* print the first 20 characters to not break the tree-format. */
+	printf(" %-10.10s  %d  [ %c ]   %-20.20s  ", dev->uclass->uc_drv->name,
 	       dev_get_uclass_index(dev, NULL),
 	       dev->flags & DM_FLAG_ACTIVATED ? '+' : ' ', dev->driver->name);
 
@@ -49,8 +49,8 @@
 
 	root = dm_root();
 	if (root) {
-		printf(" Class    index  Probed  Driver      Name\n");
-		printf("-----------------------------------------\n");
+		printf(" Class    index  Probed  Driver                Name\n");
+		printf("-----------------------------------------------------------\n");
 		show_devices(root, -1, 0);
 	}
 }
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index d9b5280..0e584c1 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -253,15 +253,15 @@
 
 fdt_addr_t ofnode_get_addr_index(ofnode node, int index)
 {
+	int na, ns;
+	fdt_size_t size;
+
 	if (ofnode_is_np(node)) {
 		const __be32 *prop_val;
 		uint flags;
-		u64 size;
-		int na;
-		int ns;
 
-		prop_val = of_get_address(ofnode_to_np(node), index, &size,
-					  &flags);
+		prop_val = of_get_address(ofnode_to_np(node), index,
+					  (u64 *)&size, &flags);
 		if (!prop_val)
 			return FDT_ADDR_T_NONE;
 
@@ -274,8 +274,11 @@
 			return of_read_number(prop_val, na);
 		}
 	} else {
-		return fdt_get_base_address(gd->fdt_blob,
-					    ofnode_to_offset(node));
+		na = ofnode_read_simple_addr_cells(ofnode_get_parent(node));
+		ns = ofnode_read_simple_size_cells(ofnode_get_parent(node));
+		return fdtdec_get_addr_size_fixed(gd->fdt_blob,
+						  ofnode_to_offset(node), "reg",
+						  index, na, ns, &size, true);
 	}
 
 	return FDT_ADDR_T_NONE;
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index d9c5719..9766aea 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -354,10 +354,8 @@
 }
 
 #if CONFIG_IS_ENABLED(OF_CONTROL)
-static int uclass_find_device_by_phandle(enum uclass_id id,
-					 struct udevice *parent,
-					 const char *name,
-					 struct udevice **devp)
+int uclass_find_device_by_phandle(enum uclass_id id, struct udevice *parent,
+				  const char *name, struct udevice **devp)
 {
 	struct udevice *dev;
 	struct uclass *uc;
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index 2cb35f3..c8c47ac 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -9,31 +9,38 @@
 #include <common.h>
 #include <dm.h>
 #include <dm/lists.h>
+#include <efi_loader.h>
 #include <linux/libfdt.h>
 #include <linux/arm-smccc.h>
 #include <linux/errno.h>
 #include <linux/printk.h>
 #include <linux/psci.h>
 
-psci_fn *invoke_psci_fn;
+#define DRIVER_NAME "psci"
 
-static unsigned long __invoke_psci_fn_hvc(unsigned long function_id,
-			unsigned long arg0, unsigned long arg1,
-			unsigned long arg2)
-{
-	struct arm_smccc_res res;
+#define PSCI_METHOD_HVC 1
+#define PSCI_METHOD_SMC 2
 
-	arm_smccc_hvc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
-	return res.a0;
-}
+int __efi_runtime_data psci_method;
 
-static unsigned long __invoke_psci_fn_smc(unsigned long function_id,
-			unsigned long arg0, unsigned long arg1,
-			unsigned long arg2)
+unsigned long __efi_runtime invoke_psci_fn
+		(unsigned long function_id, unsigned long arg0,
+		 unsigned long arg1, unsigned long arg2)
 {
 	struct arm_smccc_res res;
 
-	arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
+	/*
+	 * In the __efi_runtime we need to avoid the switch statement. In some
+	 * cases the compiler creates lookup tables to implement switch. These
+	 * tables are not correctly relocated when SetVirtualAddressMap is
+	 * called.
+	 */
+	if (psci_method == PSCI_METHOD_SMC)
+		arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
+	else if (psci_method == PSCI_METHOD_HVC)
+		arm_smccc_hvc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
+	else
+		res.a0 = PSCI_RET_DISABLED;
 	return res.a0;
 }
 
@@ -67,9 +74,9 @@
 	}
 
 	if (!strcmp("hvc", method)) {
-		invoke_psci_fn = __invoke_psci_fn_hvc;
+		psci_method = PSCI_METHOD_HVC;
 	} else if (!strcmp("smc", method)) {
-		invoke_psci_fn = __invoke_psci_fn_smc;
+		psci_method = PSCI_METHOD_SMC;
 	} else {
 		pr_warn("invalid \"method\" property: %s\n", method);
 		return -EINVAL;
@@ -77,6 +84,67 @@
 
 	return 0;
 }
+
+/**
+ * void do_psci_probe() - probe PSCI firmware driver
+ *
+ * Ensure that psci_method is initialized.
+ */
+static void __maybe_unused do_psci_probe(void)
+{
+	struct udevice *dev;
+
+	uclass_get_device_by_name(UCLASS_FIRMWARE, DRIVER_NAME, &dev);
+}
+
+#if IS_ENABLED(CONFIG_EFI_LOADER) && IS_ENABLED(CONFIG_PSCI_RESET)
+efi_status_t efi_reset_system_init(void)
+{
+	do_psci_probe();
+	return EFI_SUCCESS;
+}
+
+void __efi_runtime EFIAPI efi_reset_system(enum efi_reset_type reset_type,
+					   efi_status_t reset_status,
+					   unsigned long data_size,
+					   void *reset_data)
+{
+	if (reset_type == EFI_RESET_COLD ||
+	    reset_type == EFI_RESET_WARM ||
+	    reset_type == EFI_RESET_PLATFORM_SPECIFIC) {
+		invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
+	} else if (reset_type == EFI_RESET_SHUTDOWN) {
+		invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
+	}
+	while (1)
+		;
+}
+#endif /* IS_ENABLED(CONFIG_EFI_LOADER) && IS_ENABLED(CONFIG_PSCI_RESET) */
+
+#ifdef CONFIG_PSCI_RESET
+void reset_misc(void)
+{
+	do_psci_probe();
+	invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
+}
+#endif /* CONFIG_PSCI_RESET */
+
+#ifdef CONFIG_CMD_POWEROFF
+int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	do_psci_probe();
+
+	puts("poweroff ...\n");
+	udelay(50000); /* wait 50 ms */
+
+	disable_interrupts();
+	invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
+	enable_interrupts();
+
+	log_err("Power off not supported on this platform\n");
+	return CMD_RET_FAILURE;
+}
+#endif
 
 static const struct udevice_id psci_of_match[] = {
 	{ .compatible = "arm,psci" },
@@ -86,7 +154,7 @@
 };
 
 U_BOOT_DRIVER(psci) = {
-	.name = "psci",
+	.name = DRIVER_NAME,
 	.id = UCLASS_FIRMWARE,
 	.of_match = psci_of_match,
 	.bind = psci_bind,
diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c
index 68836a7..e55fb4a 100644
--- a/drivers/gpio/dwapb_gpio.c
+++ b/drivers/gpio/dwapb_gpio.c
@@ -180,6 +180,13 @@
 		plat->pins = fdtdec_get_int(blob, node, "snps,nr-gpios", 0);
 		plat->name = fdt_stringlist_get(blob, node, "bank-name", 0,
 						NULL);
+		if (!plat->name) {
+			/*
+			 * Fall back to node name. This means accessing pins
+			 * via bank name won't work.
+			 */
+			plat->name = fdt_get_name(blob, node, NULL);
+		}
 
 		ret = device_bind(dev, dev->driver, plat->name,
 				  plat, -1, &subdev);
diff --git a/drivers/i2c/i2c-emul-uclass.c b/drivers/i2c/i2c-emul-uclass.c
index a2bdd5a..ae5aae0 100644
--- a/drivers/i2c/i2c-emul-uclass.c
+++ b/drivers/i2c/i2c-emul-uclass.c
@@ -6,8 +6,85 @@
 #include <common.h>
 #include <dm.h>
 #include <i2c.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
+
+/*
+ * i2c emulation works using an 'emul' node at the bus level. Each device in
+ * that node is in the UCLASS_I2C_EMUL uclass, and emulates one i2c device. A
+ * pointer to the device it emulates is in the 'dev' property of the emul device
+ * uclass platdata (struct i2c_emul_platdata), put there by i2c_emul_find().
+ * When sandbox wants an emulator for a device, it calls i2c_emul_find() which
+ * searches for the emulator with the correct address. To find the device for an
+ * emulator, call i2c_emul_get_device().
+ *
+ * The 'emul' node is in the UCLASS_I2C_EMUL_PARENT uclass. We use a separate
+ * uclass so avoid having strange devices on the I2C bus.
+ */
+
+/**
+ * struct i2c_emul_uc_platdata - information about the emulator for this device
+ *
+ * This is used by devices in UCLASS_I2C_EMUL to record information about the
+ * device being emulated. It is accessible with dev_get_uclass_platdata()
+ *
+ * @dev: Device being emulated
+ */
+struct i2c_emul_uc_platdata {
+	struct udevice *dev;
+};
+
+struct udevice *i2c_emul_get_device(struct udevice *emul)
+{
+	struct i2c_emul_uc_platdata *uc_plat = dev_get_uclass_platdata(emul);
+
+	return uc_plat->dev;
+}
+
+int i2c_emul_find(struct udevice *dev, struct udevice **emulp)
+{
+	struct i2c_emul_uc_platdata *uc_plat;
+	struct udevice *emul;
+	int ret;
+
+	ret = uclass_find_device_by_phandle(UCLASS_I2C_EMUL, dev,
+					    "sandbox,emul", &emul);
+	if (ret) {
+		log_err("No emulators for device '%s'\n", dev->name);
+		return ret;
+	}
+	uc_plat = dev_get_uclass_platdata(emul);
+	uc_plat->dev = dev;
+	*emulp = emul;
+
+	return device_probe(emul);
+}
 
 UCLASS_DRIVER(i2c_emul) = {
 	.id		= UCLASS_I2C_EMUL,
 	.name		= "i2c_emul",
+	.per_device_platdata_auto_alloc_size =
+		 sizeof(struct i2c_emul_uc_platdata),
+};
+
+/*
+ * This uclass is a child of the i2c bus. Its platdata is not defined here so
+ * is defined by its parent, UCLASS_I2C, which uses struct dm_i2c_chip. See
+ * per_child_platdata_auto_alloc_size in UCLASS_DRIVER(i2c).
+ */
+UCLASS_DRIVER(i2c_emul_parent) = {
+	.id		= UCLASS_I2C_EMUL_PARENT,
+	.name		= "i2c_emul_parent",
+	.post_bind	= dm_scan_fdt_dev,
+};
+
+static const struct udevice_id i2c_emul_parent_ids[] = {
+	{ .compatible = "sandbox,i2c-emul-parent" },
+	{ }
+};
+
+U_BOOT_DRIVER(i2c_emul_parent_drv) = {
+	.name		= "i2c_emul_parent_drv",
+	.id		= UCLASS_I2C_EMUL_PARENT,
+	.of_match	= i2c_emul_parent_ids,
 };
diff --git a/drivers/i2c/sandbox_i2c.c b/drivers/i2c/sandbox_i2c.c
index 6657851..0dbbaa0 100644
--- a/drivers/i2c/sandbox_i2c.c
+++ b/drivers/i2c/sandbox_i2c.c
@@ -21,33 +21,15 @@
 		    struct dm_i2c_ops **opsp)
 {
 	struct dm_i2c_chip *plat;
-	struct udevice *child;
 	int ret;
 
 	*devp = NULL;
 	*opsp = NULL;
 	plat = dev_get_parent_platdata(dev);
 	if (!plat->emul) {
-		ret = dm_scan_fdt_dev(dev);
+		ret = i2c_emul_find(dev, &plat->emul);
 		if (ret)
 			return ret;
-
-		for (device_find_first_child(dev, &child); child;
-		     device_find_next_child(&child)) {
-			if (device_get_uclass_id(child) != UCLASS_I2C_EMUL)
-				continue;
-
-			ret = device_probe(child);
-			if (ret)
-				return ret;
-
-			break;
-		}
-
-		if (child)
-			plat->emul = child;
-		else
-			return -ENODEV;
 	}
 	*devp = plat->emul;
 	*opsp = i2c_get_ops(plat->emul);
diff --git a/drivers/misc/altera_sysid.c b/drivers/misc/altera_sysid.c
index 883b2a3..eff33f7 100644
--- a/drivers/misc/altera_sysid.c
+++ b/drivers/misc/altera_sysid.c
@@ -35,7 +35,7 @@
 	if (ret)
 		return;
 	ret = misc_read(dev, 0, &sysid, sizeof(sysid));
-	if (ret)
+	if (ret < 0)
 		return;
 
 	stamp = sysid[1];
diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c
index 190505c..2dcdb3d 100644
--- a/drivers/misc/cros_ec.c
+++ b/drivers/misc/cros_ec.c
@@ -13,6 +13,8 @@
  * is not reset.
  */
 
+#define LOG_CATEGORY UCLASS_CROS_EC
+
 #include <common.h>
 #include <command.h>
 #include <dm.h>
@@ -41,6 +43,54 @@
 	CROS_EC_CMD_HASH_TIMEOUT_MS = 2000,
 };
 
+#define INVALID_HCMD 0xFF
+
+/*
+ * Map UHEPI masks to non UHEPI commands in order to support old EC FW
+ * which does not support UHEPI command.
+ */
+static const struct {
+	u8 set_cmd;
+	u8 clear_cmd;
+	u8 get_cmd;
+} event_map[] = {
+	[EC_HOST_EVENT_MAIN] = {
+		INVALID_HCMD, EC_CMD_HOST_EVENT_CLEAR,
+		INVALID_HCMD,
+	},
+	[EC_HOST_EVENT_B] = {
+		INVALID_HCMD, EC_CMD_HOST_EVENT_CLEAR_B,
+		EC_CMD_HOST_EVENT_GET_B,
+	},
+	[EC_HOST_EVENT_SCI_MASK] = {
+		EC_CMD_HOST_EVENT_SET_SCI_MASK, INVALID_HCMD,
+		EC_CMD_HOST_EVENT_GET_SCI_MASK,
+	},
+	[EC_HOST_EVENT_SMI_MASK] = {
+		EC_CMD_HOST_EVENT_SET_SMI_MASK, INVALID_HCMD,
+		EC_CMD_HOST_EVENT_GET_SMI_MASK,
+	},
+	[EC_HOST_EVENT_ALWAYS_REPORT_MASK] = {
+		INVALID_HCMD, INVALID_HCMD, INVALID_HCMD,
+	},
+	[EC_HOST_EVENT_ACTIVE_WAKE_MASK] = {
+		EC_CMD_HOST_EVENT_SET_WAKE_MASK, INVALID_HCMD,
+		EC_CMD_HOST_EVENT_GET_WAKE_MASK,
+	},
+	[EC_HOST_EVENT_LAZY_WAKE_MASK_S0IX] = {
+		EC_CMD_HOST_EVENT_SET_WAKE_MASK, INVALID_HCMD,
+		EC_CMD_HOST_EVENT_GET_WAKE_MASK,
+	},
+	[EC_HOST_EVENT_LAZY_WAKE_MASK_S3] = {
+		EC_CMD_HOST_EVENT_SET_WAKE_MASK, INVALID_HCMD,
+		EC_CMD_HOST_EVENT_GET_WAKE_MASK,
+	},
+	[EC_HOST_EVENT_LAZY_WAKE_MASK_S5] = {
+		EC_CMD_HOST_EVENT_SET_WAKE_MASK, INVALID_HCMD,
+		EC_CMD_HOST_EVENT_GET_WAKE_MASK,
+	},
+};
+
 void cros_ec_dump_data(const char *name, int cmd, const uint8_t *data, int len)
 {
 #ifdef DEBUG
@@ -227,7 +277,7 @@
 	return handle_proto3_response(cdev, dinp, din_len);
 }
 
-static int send_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
+static int send_command(struct cros_ec_dev *dev, uint cmd, int cmd_version,
 			const void *dout, int dout_len,
 			uint8_t **dinp, int din_len)
 {
@@ -330,7 +380,7 @@
  * @param din_len       Maximum size of response in bytes
  * @return number of bytes in response, or -ve on error
  */
-static int ec_command(struct udevice *dev, uint8_t cmd, int cmd_version,
+static int ec_command(struct udevice *dev, uint cmd, int cmd_version,
 		      const void *dout, int dout_len,
 		      void *din, int din_len)
 {
@@ -365,10 +415,14 @@
 int cros_ec_read_id(struct udevice *dev, char *id, int maxlen)
 {
 	struct ec_response_get_version *r;
+	int ret;
 
-	if (ec_command_inptr(dev, EC_CMD_GET_VERSION, 0, NULL, 0,
-			(uint8_t **)&r, sizeof(*r)) != sizeof(*r))
+	ret = ec_command_inptr(dev, EC_CMD_GET_VERSION, 0, NULL, 0,
+			       (uint8_t **)&r, sizeof(*r));
+	if (ret != sizeof(*r)) {
+		log_err("Got rc %d, expected %d\n", ret, sizeof(*r));
 		return -1;
+	}
 
 	if (maxlen > (int)sizeof(r->version_string_ro))
 		maxlen = sizeof(r->version_string_ro);
@@ -381,6 +435,7 @@
 		memcpy(id, r->version_string_rw, maxlen);
 		break;
 	default:
+		log_err("Invalid EC image %d\n", r->current_image);
 		return -1;
 	}
 
@@ -563,6 +618,36 @@
 	return 0;
 }
 
+int cros_ec_get_event_mask(struct udevice *dev, uint type, uint32_t *mask)
+{
+	struct ec_response_host_event_mask rsp;
+	int ret;
+
+	ret = ec_command(dev, type, 0, NULL, 0, &rsp, sizeof(rsp));
+	if (ret < 0)
+		return ret;
+	else if (ret != sizeof(rsp))
+		return -EINVAL;
+
+	*mask = rsp.mask;
+
+	return 0;
+}
+
+int cros_ec_set_event_mask(struct udevice *dev, uint type, uint32_t mask)
+{
+	struct ec_params_host_event_mask req;
+	int ret;
+
+	req.mask = mask;
+
+	ret = ec_command(dev, type, 0, &req, sizeof(req), NULL, 0);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
 int cros_ec_get_host_events(struct udevice *dev, uint32_t *events_ptr)
 {
 	struct ec_response_host_event_mask *resp;
@@ -616,6 +701,17 @@
 	return 0;
 }
 
+int cros_ec_entering_mode(struct udevice *dev, int mode)
+{
+	int rc;
+
+	rc = ec_command(dev, EC_CMD_ENTERING_MODE, 0, &mode, sizeof(mode),
+			NULL, 0);
+	if (rc)
+		return -1;
+	return 0;
+}
+
 static int cros_ec_check_version(struct udevice *dev)
 {
 	struct cros_ec_dev *cdev = dev_get_uclass_priv(dev);
@@ -650,16 +746,14 @@
 	cdev->protocol_version = 3;
 	req.in_data = 0;
 	if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req),
-			     (uint8_t **)&resp, sizeof(*resp)) > 0) {
+			     (uint8_t **)&resp, sizeof(*resp)) > 0)
 		return 0;
-	}
 
 	/* Try sending a version 2 packet */
 	cdev->protocol_version = 2;
 	if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req),
-			     (uint8_t **)&resp, sizeof(*resp)) > 0) {
+			     (uint8_t **)&resp, sizeof(*resp)) > 0)
 		return 0;
-	}
 
 	/*
 	 * Fail if we're still here, since the EC doesn't understand any
@@ -822,6 +916,9 @@
 	uint32_t end, off;
 	int ret;
 
+	if (!burst)
+		return -EINVAL;
+
 	/*
 	 * TODO: round up to the nearest multiple of write size.  Can get away
 	 * without that on link right now because its write size is 4 bytes.
@@ -845,6 +942,35 @@
 }
 
 /**
+ * Run verification on a slot
+ *
+ * @param me     CrosEc instance
+ * @param region Region to run verification on
+ * @return 0 if success or not applicable. Non-zero if verification failed.
+ */
+int cros_ec_efs_verify(struct udevice *dev, enum ec_flash_region region)
+{
+	struct ec_params_efs_verify p;
+	int rv;
+
+	log_info("EFS: EC is verifying updated image...\n");
+	p.region = region;
+
+	rv = ec_command(dev, EC_CMD_EFS_VERIFY, 0, &p, sizeof(p), NULL, 0);
+	if (rv >= 0) {
+		log_info("EFS: Verification success\n");
+		return 0;
+	}
+	if (rv == -EC_RES_INVALID_COMMAND) {
+		log_info("EFS: EC doesn't support EFS_VERIFY command\n");
+		return 0;
+	}
+	log_info("EFS: Verification failed\n");
+
+	return rv;
+}
+
+/**
  * Read a single block from the flash
  *
  * Read a block of data from the EC flash. The size must not exceed the flash
@@ -934,15 +1060,17 @@
 	struct ec_params_vbnvcontext p;
 	int len;
 
-	if (size != EC_VBNV_BLOCK_SIZE)
+	if (size != EC_VBNV_BLOCK_SIZE && size != EC_VBNV_BLOCK_SIZE_V2)
 		return -EINVAL;
 
 	p.op = EC_VBNV_CONTEXT_OP_READ;
 
 	len = ec_command(dev, EC_CMD_VBNV_CONTEXT, EC_VER_VBNV_CONTEXT,
-			&p, sizeof(p), block, EC_VBNV_BLOCK_SIZE);
-	if (len < EC_VBNV_BLOCK_SIZE)
+			 &p, sizeof(uint32_t) + size, block, size);
+	if (len != size) {
+		log_err("Expected %d bytes, got %d\n", size, len);
 		return -EIO;
+	}
 
 	return 0;
 }
@@ -952,19 +1080,33 @@
 	struct ec_params_vbnvcontext p;
 	int len;
 
-	if (size != EC_VBNV_BLOCK_SIZE)
+	if (size != EC_VBNV_BLOCK_SIZE && size != EC_VBNV_BLOCK_SIZE_V2)
 		return -EINVAL;
 	p.op = EC_VBNV_CONTEXT_OP_WRITE;
-	memcpy(p.block, block, sizeof(p.block));
+	memcpy(p.block, block, size);
 
 	len = ec_command_inptr(dev, EC_CMD_VBNV_CONTEXT, EC_VER_VBNV_CONTEXT,
-			&p, sizeof(p), NULL, 0);
+			&p, sizeof(uint32_t) + size, NULL, 0);
 	if (len < 0)
 		return -1;
 
 	return 0;
 }
 
+int cros_ec_battery_cutoff(struct udevice *dev, uint8_t flags)
+{
+	struct ec_params_battery_cutoff p;
+	int len;
+
+	p.flags = flags;
+	len = ec_command(dev, EC_CMD_BATTERY_CUT_OFF, 1, &p, sizeof(p),
+			 NULL, 0);
+
+	if (len < 0)
+		return -1;
+	return 0;
+}
+
 int cros_ec_set_ldo(struct udevice *dev, uint8_t index, uint8_t state)
 {
 	struct ec_params_ldo_set params;
@@ -1136,6 +1278,205 @@
 	if (read_len)
 		memcpy(read_ptr, r->data, read_len);
 
+	return 0;
+}
+
+int cros_ec_check_feature(struct udevice *dev, int feature)
+{
+	struct ec_response_get_features r;
+	int rv;
+
+	rv = ec_command(dev, EC_CMD_GET_FEATURES, 0, &r, sizeof(r), NULL, 0);
+	if (rv)
+		return rv;
+
+	if (feature >= 8 * sizeof(r.flags))
+		return -1;
+
+	return r.flags[feature / 32] & EC_FEATURE_MASK_0(feature);
+}
+
+/*
+ * Query the EC for specified mask indicating enabled events.
+ * The EC maintains separate event masks for SMI, SCI and WAKE.
+ */
+static int cros_ec_uhepi_cmd(struct udevice *dev, uint mask, uint action,
+			     uint64_t *value)
+{
+	int ret;
+	struct ec_params_host_event req;
+	struct ec_response_host_event rsp;
+
+	req.action = action;
+	req.mask_type = mask;
+	if (action != EC_HOST_EVENT_GET)
+		req.value = *value;
+	else
+		*value = 0;
+	ret = ec_command(dev, EC_CMD_HOST_EVENT, 0, &req, sizeof(req), &rsp,
+			 sizeof(rsp));
+
+	if (action != EC_HOST_EVENT_GET)
+		return ret;
+	if (ret == 0)
+		*value = rsp.value;
+
+	return ret;
+}
+
+static int cros_ec_handle_non_uhepi_cmd(struct udevice *dev, uint hcmd,
+					uint action, uint64_t *value)
+{
+	int ret = -1;
+	struct ec_params_host_event_mask req;
+	struct ec_response_host_event_mask rsp;
+
+	if (hcmd == INVALID_HCMD)
+		return ret;
+
+	if (action != EC_HOST_EVENT_GET)
+		req.mask = (uint32_t)*value;
+	else
+		*value = 0;
+
+	ret = ec_command(dev, hcmd, 0, &req, sizeof(req), &rsp, sizeof(rsp));
+	if (action != EC_HOST_EVENT_GET)
+		return ret;
+	if (ret == 0)
+		*value = rsp.mask;
+
+	return ret;
+}
+
+bool cros_ec_is_uhepi_supported(struct udevice *dev)
+{
+#define UHEPI_SUPPORTED 1
+#define UHEPI_NOT_SUPPORTED 2
+	static int uhepi_support;
+
+	if (!uhepi_support) {
+		uhepi_support = cros_ec_check_feature(dev,
+			EC_FEATURE_UNIFIED_WAKE_MASKS) > 0 ? UHEPI_SUPPORTED :
+			UHEPI_NOT_SUPPORTED;
+		log_debug("Chrome EC: UHEPI %s\n",
+			  uhepi_support == UHEPI_SUPPORTED ? "supported" :
+			  "not supported");
+	}
+	return uhepi_support == UHEPI_SUPPORTED;
+}
+
+static int cros_ec_get_mask(struct udevice *dev, uint type)
+{
+	u64 value = 0;
+
+	if (cros_ec_is_uhepi_supported(dev)) {
+		cros_ec_uhepi_cmd(dev, type, EC_HOST_EVENT_GET, &value);
+	} else {
+		assert(type < ARRAY_SIZE(event_map));
+		cros_ec_handle_non_uhepi_cmd(dev, event_map[type].get_cmd,
+					     EC_HOST_EVENT_GET, &value);
+	}
+	return value;
+}
+
+static int cros_ec_clear_mask(struct udevice *dev, uint type, u64 mask)
+{
+	if (cros_ec_is_uhepi_supported(dev))
+		return cros_ec_uhepi_cmd(dev, type, EC_HOST_EVENT_CLEAR, &mask);
+
+	assert(type < ARRAY_SIZE(event_map));
+
+	return cros_ec_handle_non_uhepi_cmd(dev, event_map[type].clear_cmd,
+					    EC_HOST_EVENT_CLEAR, &mask);
+}
+
+uint64_t cros_ec_get_events_b(struct udevice *dev)
+{
+	return cros_ec_get_mask(dev, EC_HOST_EVENT_B);
+}
+
+int cros_ec_clear_events_b(struct udevice *dev, uint64_t mask)
+{
+	log_debug("Chrome EC: clear events_b mask to 0x%016llx\n", mask);
+
+	return cros_ec_clear_mask(dev, EC_HOST_EVENT_B, mask);
+}
+
+int cros_ec_read_limit_power(struct udevice *dev, int *limit_powerp)
+{
+	struct ec_params_charge_state p;
+	struct ec_response_charge_state r;
+	int ret;
+
+	p.cmd = CHARGE_STATE_CMD_GET_PARAM;
+	p.get_param.param = CS_PARAM_LIMIT_POWER;
+	ret = ec_command(dev, EC_CMD_CHARGE_STATE, 0, &p, sizeof(p),
+			 &r, sizeof(r));
+
+	/*
+	 * If our EC doesn't support the LIMIT_POWER parameter, assume that
+	 * LIMIT_POWER is not requested.
+	 */
+	if (ret == -EC_RES_INVALID_PARAM || ret == -EC_RES_INVALID_COMMAND) {
+		log_warning("PARAM_LIMIT_POWER not supported by EC\n");
+		return -ENOSYS;
+	}
+
+	if (ret != sizeof(r.get_param))
+		return -EINVAL;
+
+	*limit_powerp = r.get_param.value;
+	return 0;
+}
+
+int cros_ec_config_powerbtn(struct udevice *dev, uint32_t flags)
+{
+	struct ec_params_config_power_button params;
+	int ret;
+
+	params.flags = flags;
+	ret = ec_command(dev, EC_CMD_CONFIG_POWER_BUTTON, 0,
+			 &params, sizeof(params), NULL, 0);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int cros_ec_get_lid_shutdown_mask(struct udevice *dev)
+{
+	u32 mask;
+	int ret;
+
+	ret = cros_ec_get_event_mask(dev, EC_CMD_HOST_EVENT_GET_SMI_MASK,
+				     &mask);
+	if (ret < 0)
+		return ret;
+
+	return !!(mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED));
+}
+
+int cros_ec_set_lid_shutdown_mask(struct udevice *dev, int enable)
+{
+	u32 mask;
+	int ret;
+
+	ret = cros_ec_get_event_mask(dev, EC_CMD_HOST_EVENT_GET_SMI_MASK,
+				     &mask);
+	if (ret < 0)
+		return ret;
+
+	// Set lid close event state in the EC SMI event mask
+	if (enable)
+		mask |= EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED);
+	else
+		mask &= ~EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED);
+
+	ret = cros_ec_set_event_mask(dev, EC_CMD_HOST_EVENT_SET_SMI_MASK, mask);
+	if (ret < 0)
+		return ret;
+
+	printf("EC: %sabled lid close event\n", enable ? "en" : "dis");
 	return 0;
 }
 
@@ -1144,4 +1485,5 @@
 	.name		= "cros_ec",
 	.per_device_auto_alloc_size = sizeof(struct cros_ec_dev),
 	.post_bind	= dm_scan_fdt_dev,
+	.flags		= DM_UC_FLAG_ALLOC_PRIV_DMA,
 };
diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c
index d741554..429f1a9 100644
--- a/drivers/misc/cros_ec_sandbox.c
+++ b/drivers/misc/cros_ec_sandbox.c
@@ -74,7 +74,7 @@
  * @recovery_req: Keyboard recovery requested
  */
 struct ec_state {
-	uint8_t vbnv_context[EC_VBNV_BLOCK_SIZE];
+	u8 vbnv_context[EC_VBNV_BLOCK_SIZE_V2];
 	struct fdt_cros_ec ec_config;
 	uint8_t *flash_data;
 	int flash_data_len;
diff --git a/drivers/misc/misc_sandbox.c b/drivers/misc/misc_sandbox.c
index e4164f7..f7c5b2e 100644
--- a/drivers/misc/misc_sandbox.c
+++ b/drivers/misc/misc_sandbox.c
@@ -20,7 +20,7 @@
 
 	memcpy(buf, priv->mem + offset, size);
 
-	return 0;
+	return size;
 }
 
 int misc_sandbox_write(struct udevice *dev, int offset, const void *buf,
@@ -30,7 +30,7 @@
 
 	memcpy(priv->mem + offset, buf, size);
 
-	return 0;
+	return size;
 }
 
 int misc_sandbox_ioctl(struct udevice *dev, unsigned long request, void *buf)
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c
index 8a213c9..2520c6a 100644
--- a/drivers/misc/rockchip-efuse.c
+++ b/drivers/misc/rockchip-efuse.c
@@ -65,7 +65,7 @@
 	}
 
 	ret = misc_read(dev, 0, &fuses, sizeof(fuses));
-	if (ret) {
+	if (ret < 0) {
 		printf("%s: misc_read failed\n", __func__);
 		return 0;
 	}
diff --git a/drivers/misc/stm32mp_fuse.c b/drivers/misc/stm32mp_fuse.c
index 2d66135..33943a2 100644
--- a/drivers/misc/stm32mp_fuse.c
+++ b/drivers/misc/stm32mp_fuse.c
@@ -29,6 +29,9 @@
 			return ret;
 		ret = misc_read(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
 				val, 4);
+		if (ret < 0)
+			return ret;
+		ret = 0;
 		break;
 
 	default:
@@ -54,6 +57,9 @@
 			return ret;
 		ret = misc_write(dev, word * 4 + STM32_BSEC_OTP_OFFSET,
 				 &val, 4);
+		if (ret < 0)
+			return ret;
+		ret = 0;
 		break;
 
 	default:
@@ -78,6 +84,9 @@
 		if (ret)
 			return ret;
 		ret = misc_read(dev, word * 4 + STM32_BSEC_OTP_OFFSET, val, 4);
+		if (ret < 0)
+			return ret;
+		ret = 0;
 		break;
 
 	default:
@@ -103,6 +112,9 @@
 			return ret;
 		ret = misc_write(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
 				 &val, 4);
+		if (ret < 0)
+			return ret;
+		ret = 0;
 		break;
 
 	default:
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 27246ee..fbd1396 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -569,6 +569,10 @@
 	bool
 	depends on MMC_SUNXI
 
+config MMC_SUNXI_HAS_MODE_SWITCH
+	bool
+	depends on MMC_SUNXI
+
 config GENERIC_ATMEL_MCI
 	bool "Atmel Multimedia Card Interface support"
 	depends on DM_MMC && BLK && ARCH_AT91
@@ -598,6 +602,17 @@
 	help
 		This can enable ftsdc010 sdio function.
 
+config MMC_MTK
+	bool "MediaTek SD/MMC Card Interface support"
+	depends on ARCH_MEDIATEK
+	depends on BLK && DM_MMC
+	depends on OF_CONTROL
+	help
+	  This selects the MediaTek(R) Secure digital and Multimedia card Interface.
+	  If you have a machine with a integrated SD/MMC card reader, say Y or M here.
+	  This is needed if support for any SD/SDIO/MMC devices is required.
+	  If unsure, say N.
+
 endif
 
 config TEGRA124_MMC_DISABLE_EXT_LOOPBACK
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 23c5b0d..801a26d 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -65,3 +65,4 @@
 obj-$(CONFIG_MMC_UNIPHIER)		+= tmio-common.o uniphier-sd.o
 obj-$(CONFIG_RENESAS_SDHI)		+= tmio-common.o renesas-sdhi.o
 obj-$(CONFIG_MMC_BCM2835)		+= bcm2835_sdhost.o
+obj-$(CONFIG_MMC_MTK)			+= mtk-sd.o
diff --git a/drivers/mmc/meson_gx_mmc.c b/drivers/mmc/meson_gx_mmc.c
index 332f1e1..767dfff 100644
--- a/drivers/mmc/meson_gx_mmc.c
+++ b/drivers/mmc/meson_gx_mmc.c
@@ -278,6 +278,7 @@
 
 static const struct udevice_id meson_mmc_match[] = {
 	{ .compatible = "amlogic,meson-gx-mmc" },
+	{ .compatible = "amlogic,meson-axg-mmc" },
 	{ /* sentinel */ }
 };
 
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index f73f072..76225b7 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -166,6 +166,10 @@
 		cfg->host_caps |= MMC_CAP(MMC_HS_200);
 	if (dev_read_bool(dev, "mmc-hs200-1_2v"))
 		cfg->host_caps |= MMC_CAP(MMC_HS_200);
+	if (dev_read_bool(dev, "mmc-hs400-1_8v"))
+		cfg->host_caps |= MMC_CAP(MMC_HS_400);
+	if (dev_read_bool(dev, "mmc-hs400-1_2v"))
+		cfg->host_caps |= MMC_CAP(MMC_HS_400);
 
 	return 0;
 }
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index d6b9cdc..f5c821e 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1289,6 +1289,10 @@
 	ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
 	int speed;
 
+	/* SD version 1.00 and 1.01 does not support CMD 6 */
+	if (mmc->version == SD_VERSION_1_0)
+		return 0;
+
 	switch (mode) {
 	case SD_LEGACY:
 		speed = UHS_SDR12_BUS_SPEED;
diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c
new file mode 100644
index 0000000..0741a52
--- /dev/null
+++ b/drivers/mmc/mtk-sd.c
@@ -0,0 +1,1394 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek SD/MMC Card Interface driver
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <mmc.h>
+#include <errno.h>
+#include <malloc.h>
+#include <stdbool.h>
+#include <asm/gpio.h>
+#include <dm/pinctrl.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+
+/* MSDC_CFG */
+#define MSDC_CFG_HS400_CK_MODE_EXT	BIT(22)
+#define MSDC_CFG_CKMOD_EXT_M		0x300000
+#define MSDC_CFG_CKMOD_EXT_S		20
+#define MSDC_CFG_CKDIV_EXT_M		0xfff00
+#define MSDC_CFG_CKDIV_EXT_S		8
+#define MSDC_CFG_HS400_CK_MODE		BIT(18)
+#define MSDC_CFG_CKMOD_M		0x30000
+#define MSDC_CFG_CKMOD_S		16
+#define MSDC_CFG_CKDIV_M		0xff00
+#define MSDC_CFG_CKDIV_S		8
+#define MSDC_CFG_CKSTB			BIT(7)
+#define MSDC_CFG_PIO			BIT(3)
+#define MSDC_CFG_RST			BIT(2)
+#define MSDC_CFG_CKPDN			BIT(1)
+#define MSDC_CFG_MODE			BIT(0)
+
+/* MSDC_IOCON */
+#define MSDC_IOCON_W_DSPL		BIT(8)
+#define MSDC_IOCON_DSPL			BIT(2)
+#define MSDC_IOCON_RSPL			BIT(1)
+
+/* MSDC_PS */
+#define MSDC_PS_DAT0			BIT(16)
+#define MSDC_PS_CDDBCE_M		0xf000
+#define MSDC_PS_CDDBCE_S		12
+#define MSDC_PS_CDSTS			BIT(1)
+#define MSDC_PS_CDEN			BIT(0)
+
+/* #define MSDC_INT(EN) */
+#define MSDC_INT_ACMDRDY		BIT(3)
+#define MSDC_INT_ACMDTMO		BIT(4)
+#define MSDC_INT_ACMDCRCERR		BIT(5)
+#define MSDC_INT_CMDRDY			BIT(8)
+#define MSDC_INT_CMDTMO			BIT(9)
+#define MSDC_INT_RSPCRCERR		BIT(10)
+#define MSDC_INT_XFER_COMPL		BIT(12)
+#define MSDC_INT_DATTMO			BIT(14)
+#define MSDC_INT_DATCRCERR		BIT(15)
+
+/* MSDC_FIFOCS */
+#define MSDC_FIFOCS_CLR			BIT(31)
+#define MSDC_FIFOCS_TXCNT_M		0xff0000
+#define MSDC_FIFOCS_TXCNT_S		16
+#define MSDC_FIFOCS_RXCNT_M		0xff
+#define MSDC_FIFOCS_RXCNT_S		0
+
+/* #define SDC_CFG */
+#define SDC_CFG_DTOC_M			0xff000000
+#define SDC_CFG_DTOC_S			24
+#define SDC_CFG_SDIOIDE			BIT(20)
+#define SDC_CFG_SDIO			BIT(19)
+#define SDC_CFG_BUSWIDTH_M		0x30000
+#define SDC_CFG_BUSWIDTH_S		16
+
+/* SDC_CMD */
+#define SDC_CMD_BLK_LEN_M		0xfff0000
+#define SDC_CMD_BLK_LEN_S		16
+#define SDC_CMD_STOP			BIT(14)
+#define SDC_CMD_WR			BIT(13)
+#define SDC_CMD_DTYPE_M			0x1800
+#define SDC_CMD_DTYPE_S			11
+#define SDC_CMD_RSPTYP_M		0x380
+#define SDC_CMD_RSPTYP_S		7
+#define SDC_CMD_CMD_M			0x3f
+#define SDC_CMD_CMD_S			0
+
+/* SDC_STS */
+#define SDC_STS_CMDBUSY			BIT(1)
+#define SDC_STS_SDCBUSY			BIT(0)
+
+/* SDC_ADV_CFG0 */
+#define SDC_RX_ENHANCE_EN		BIT(20)
+
+/* PATCH_BIT0 */
+#define MSDC_INT_DAT_LATCH_CK_SEL_M	0x380
+#define MSDC_INT_DAT_LATCH_CK_SEL_S	7
+
+/* PATCH_BIT1 */
+#define MSDC_PB1_STOP_DLY_M		0xf00
+#define MSDC_PB1_STOP_DLY_S		8
+
+/* PATCH_BIT2 */
+#define MSDC_PB2_CRCSTSENSEL_M		0xe0000000
+#define MSDC_PB2_CRCSTSENSEL_S		29
+#define MSDC_PB2_CFGCRCSTS		BIT(28)
+#define MSDC_PB2_RESPSTSENSEL_M		0x70000
+#define MSDC_PB2_RESPSTSENSEL_S		16
+#define MSDC_PB2_CFGRESP		BIT(15)
+#define MSDC_PB2_RESPWAIT_M		0x0c
+#define MSDC_PB2_RESPWAIT_S		2
+
+/* PAD_TUNE */
+#define MSDC_PAD_TUNE_CMDRRDLY_M	0x7c00000
+#define MSDC_PAD_TUNE_CMDRRDLY_S	22
+#define MSDC_PAD_TUNE_CMD_SEL		BIT(21)
+#define MSDC_PAD_TUNE_CMDRDLY_M		0x1f0000
+#define MSDC_PAD_TUNE_CMDRDLY_S		16
+#define MSDC_PAD_TUNE_RXDLYSEL		BIT(15)
+#define MSDC_PAD_TUNE_RD_SEL		BIT(13)
+#define MSDC_PAD_TUNE_DATRRDLY_M	0x1f00
+#define MSDC_PAD_TUNE_DATRRDLY_S	8
+#define MSDC_PAD_TUNE_DATWRDLY_M	0x1f
+#define MSDC_PAD_TUNE_DATWRDLY_S	0
+
+/* EMMC50_CFG0 */
+#define EMMC50_CFG_CFCSTS_SEL		BIT(4)
+
+/* SDC_FIFO_CFG */
+#define SDC_FIFO_CFG_WRVALIDSEL		BIT(24)
+#define SDC_FIFO_CFG_RDVALIDSEL		BIT(25)
+
+/* SDC_CFG_BUSWIDTH */
+#define MSDC_BUS_1BITS			0x0
+#define MSDC_BUS_4BITS			0x1
+#define MSDC_BUS_8BITS			0x2
+
+#define MSDC_FIFO_SIZE			128
+
+#define PAD_DELAY_MAX			32
+
+#define DEFAULT_CD_DEBOUNCE		8
+
+#define CMD_INTS_MASK	\
+	(MSDC_INT_CMDRDY | MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO)
+
+#define DATA_INTS_MASK	\
+	(MSDC_INT_XFER_COMPL | MSDC_INT_DATTMO | MSDC_INT_DATCRCERR)
+
+/* Register offset */
+struct mtk_sd_regs {
+	u32 msdc_cfg;
+	u32 msdc_iocon;
+	u32 msdc_ps;
+	u32 msdc_int;
+	u32 msdc_inten;
+	u32 msdc_fifocs;
+	u32 msdc_txdata;
+	u32 msdc_rxdata;
+	u32 reserved0[4];
+	u32 sdc_cfg;
+	u32 sdc_cmd;
+	u32 sdc_arg;
+	u32 sdc_sts;
+	u32 sdc_resp[4];
+	u32 sdc_blk_num;
+	u32 sdc_vol_chg;
+	u32 sdc_csts;
+	u32 sdc_csts_en;
+	u32 sdc_datcrc_sts;
+	u32 sdc_adv_cfg0;
+	u32 reserved1[2];
+	u32 emmc_cfg0;
+	u32 emmc_cfg1;
+	u32 emmc_sts;
+	u32 emmc_iocon;
+	u32 sd_acmd_resp;
+	u32 sd_acmd19_trg;
+	u32 sd_acmd19_sts;
+	u32 dma_sa_high4bit;
+	u32 dma_sa;
+	u32 dma_ca;
+	u32 dma_ctrl;
+	u32 dma_cfg;
+	u32 sw_dbg_sel;
+	u32 sw_dbg_out;
+	u32 dma_length;
+	u32 reserved2;
+	u32 patch_bit0;
+	u32 patch_bit1;
+	u32 patch_bit2;
+	u32 reserved3;
+	u32 dat0_tune_crc;
+	u32 dat1_tune_crc;
+	u32 dat2_tune_crc;
+	u32 dat3_tune_crc;
+	u32 cmd_tune_crc;
+	u32 sdio_tune_wind;
+	u32 reserved4[5];
+	u32 pad_tune;
+	u32 pad_tune0;
+	u32 pad_tune1;
+	u32 dat_rd_dly[4];
+	u32 reserved5[2];
+	u32 hw_dbg_sel;
+	u32 main_ver;
+	u32 eco_ver;
+	u32 reserved6[27];
+	u32 pad_ds_tune;
+	u32 reserved7[31];
+	u32 emmc50_cfg0;
+	u32 reserved8[7];
+	u32 sdc_fifo_cfg;
+};
+
+struct msdc_compatible {
+	u8 clk_div_bits;
+	bool pad_tune0;
+	bool async_fifo;
+	bool data_tune;
+	bool busy_check;
+	bool stop_clk_fix;
+	bool enhance_rx;
+};
+
+struct msdc_delay_phase {
+	u8 maxlen;
+	u8 start;
+	u8 final_phase;
+};
+
+struct msdc_plat {
+	struct mmc_config cfg;
+	struct mmc mmc;
+};
+
+struct msdc_tune_para {
+	u32 iocon;
+	u32 pad_tune;
+};
+
+struct msdc_host {
+	struct mtk_sd_regs *base;
+	struct mmc *mmc;
+
+	struct msdc_compatible *dev_comp;
+
+	struct clk src_clk;	/* for SD/MMC bus clock */
+	struct clk h_clk;	/* MSDC core clock */
+
+	u32 src_clk_freq;	/* source clock */
+	u32 mclk;		/* mmc framework required bus clock */
+	u32 sclk;		/* actual calculated bus clock */
+
+	/* operation timeout clocks */
+	u32 timeout_ns;
+	u32 timeout_clks;
+
+	/* tuning options */
+	u32 hs400_ds_delay;
+	u32 hs200_cmd_int_delay;
+	u32 hs200_write_int_delay;
+	u32 latch_ck;
+	u32 r_smpl;		/* sample edge */
+	bool hs400_mode;
+
+	/* whether to use gpio detection or built-in hw detection */
+	bool builtin_cd;
+
+	/* card detection / write protection GPIOs */
+#ifdef CONFIG_DM_GPIO
+	struct gpio_desc gpio_wp;
+	struct gpio_desc gpio_cd;
+#endif
+
+	uint last_resp_type;
+	uint last_data_write;
+
+	enum bus_mode timing;
+
+	struct msdc_tune_para def_tune_para;
+	struct msdc_tune_para saved_tune_para;
+};
+
+static void msdc_reset_hw(struct msdc_host *host)
+{
+	u32 reg;
+
+	setbits_le32(&host->base->msdc_cfg, MSDC_CFG_RST);
+
+	readl_poll_timeout(&host->base->msdc_cfg, reg,
+			   !(reg & MSDC_CFG_RST), 1000000);
+}
+
+static void msdc_fifo_clr(struct msdc_host *host)
+{
+	u32 reg;
+
+	setbits_le32(&host->base->msdc_fifocs, MSDC_FIFOCS_CLR);
+
+	readl_poll_timeout(&host->base->msdc_fifocs, reg,
+			   !(reg & MSDC_FIFOCS_CLR), 1000000);
+}
+
+static u32 msdc_fifo_rx_bytes(struct msdc_host *host)
+{
+	return (readl(&host->base->msdc_fifocs) &
+		MSDC_FIFOCS_RXCNT_M) >> MSDC_FIFOCS_RXCNT_S;
+}
+
+static u32 msdc_fifo_tx_bytes(struct msdc_host *host)
+{
+	return (readl(&host->base->msdc_fifocs) &
+		MSDC_FIFOCS_TXCNT_M) >> MSDC_FIFOCS_TXCNT_S;
+}
+
+static u32 msdc_cmd_find_resp(struct msdc_host *host, struct mmc_cmd *cmd)
+{
+	u32 resp;
+
+	switch (cmd->resp_type) {
+		/* Actually, R1, R5, R6, R7 are the same */
+	case MMC_RSP_R1:
+		resp = 0x1;
+		break;
+	case MMC_RSP_R1b:
+		resp = 0x7;
+		break;
+	case MMC_RSP_R2:
+		resp = 0x2;
+		break;
+	case MMC_RSP_R3:
+		resp = 0x3;
+		break;
+	case MMC_RSP_NONE:
+	default:
+		resp = 0x0;
+		break;
+	}
+
+	return resp;
+}
+
+static u32 msdc_cmd_prepare_raw_cmd(struct msdc_host *host,
+				    struct mmc_cmd *cmd,
+				    struct mmc_data *data)
+{
+	u32 opcode = cmd->cmdidx;
+	u32 resp_type = msdc_cmd_find_resp(host, cmd);
+	uint blocksize = 0;
+	u32 dtype = 0;
+	u32 rawcmd = 0;
+
+	switch (opcode) {
+	case MMC_CMD_WRITE_MULTIPLE_BLOCK:
+	case MMC_CMD_READ_MULTIPLE_BLOCK:
+		dtype = 2;
+		break;
+	case MMC_CMD_WRITE_SINGLE_BLOCK:
+	case MMC_CMD_READ_SINGLE_BLOCK:
+	case SD_CMD_APP_SEND_SCR:
+		dtype = 1;
+		break;
+	case SD_CMD_SWITCH_FUNC: /* same as MMC_CMD_SWITCH */
+	case SD_CMD_SEND_IF_COND: /* same as MMC_CMD_SEND_EXT_CSD */
+	case SD_CMD_APP_SD_STATUS: /* same as MMC_CMD_SEND_STATUS */
+		if (data)
+			dtype = 1;
+	}
+
+	if (data) {
+		if (data->flags == MMC_DATA_WRITE)
+			rawcmd |= SDC_CMD_WR;
+
+		if (data->blocks > 1)
+			dtype = 2;
+
+		blocksize = data->blocksize;
+	}
+
+	rawcmd |= ((opcode << SDC_CMD_CMD_S) & SDC_CMD_CMD_M) |
+		((resp_type << SDC_CMD_RSPTYP_S) & SDC_CMD_RSPTYP_M) |
+		((blocksize << SDC_CMD_BLK_LEN_S) & SDC_CMD_BLK_LEN_M) |
+		((dtype << SDC_CMD_DTYPE_S) & SDC_CMD_DTYPE_M);
+
+	if (opcode == MMC_CMD_STOP_TRANSMISSION)
+		rawcmd |= SDC_CMD_STOP;
+
+	return rawcmd;
+}
+
+static int msdc_cmd_done(struct msdc_host *host, int events,
+			 struct mmc_cmd *cmd)
+{
+	u32 *rsp = cmd->response;
+	int ret = 0;
+
+	if (cmd->resp_type & MMC_RSP_PRESENT) {
+		if (cmd->resp_type & MMC_RSP_136) {
+			rsp[0] = readl(&host->base->sdc_resp[3]);
+			rsp[1] = readl(&host->base->sdc_resp[2]);
+			rsp[2] = readl(&host->base->sdc_resp[1]);
+			rsp[3] = readl(&host->base->sdc_resp[0]);
+		} else {
+			rsp[0] = readl(&host->base->sdc_resp[0]);
+		}
+	}
+
+	if (!(events & MSDC_INT_CMDRDY)) {
+		if (cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK &&
+		    cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK_HS200)
+			/*
+			 * should not clear fifo/interrupt as the tune data
+			 * may have alreay come.
+			 */
+			msdc_reset_hw(host);
+
+		if (events & MSDC_INT_CMDTMO)
+			ret = -ETIMEDOUT;
+		else
+			ret = -EIO;
+	}
+
+	return ret;
+}
+
+static bool msdc_cmd_is_ready(struct msdc_host *host)
+{
+	int ret;
+	u32 reg;
+
+	/* The max busy time we can endure is 20ms */
+	ret = readl_poll_timeout(&host->base->sdc_sts, reg,
+				 !(reg & SDC_STS_CMDBUSY), 20000);
+
+	if (ret) {
+		pr_err("CMD bus busy detected\n");
+		msdc_reset_hw(host);
+		return false;
+	}
+
+	if (host->last_resp_type == MMC_RSP_R1b && host->last_data_write) {
+		ret = readl_poll_timeout(&host->base->msdc_ps, reg,
+					 reg & MSDC_PS_DAT0, 1000000);
+
+		if (ret) {
+			pr_err("Card stuck in programming state!\n");
+			msdc_reset_hw(host);
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static int msdc_start_command(struct msdc_host *host, struct mmc_cmd *cmd,
+			      struct mmc_data *data)
+{
+	u32 rawcmd;
+	u32 status;
+	u32 blocks = 0;
+	int ret;
+
+	if (!msdc_cmd_is_ready(host))
+		return -EIO;
+
+	msdc_fifo_clr(host);
+
+	host->last_resp_type = cmd->resp_type;
+	host->last_data_write = 0;
+
+	rawcmd = msdc_cmd_prepare_raw_cmd(host, cmd, data);
+
+	if (data)
+		blocks = data->blocks;
+
+	writel(CMD_INTS_MASK, &host->base->msdc_int);
+	writel(blocks, &host->base->sdc_blk_num);
+	writel(cmd->cmdarg, &host->base->sdc_arg);
+	writel(rawcmd, &host->base->sdc_cmd);
+
+	ret = readl_poll_timeout(&host->base->msdc_int, status,
+				 status & CMD_INTS_MASK, 1000000);
+
+	if (ret)
+		status = MSDC_INT_CMDTMO;
+
+	return msdc_cmd_done(host, status, cmd);
+}
+
+static void msdc_fifo_read(struct msdc_host *host, u8 *buf, u32 size)
+{
+	u32 *wbuf;
+
+	while ((size_t)buf % 4) {
+		*buf++ = readb(&host->base->msdc_rxdata);
+		size--;
+	}
+
+	wbuf = (u32 *)buf;
+	while (size >= 4) {
+		*wbuf++ = readl(&host->base->msdc_rxdata);
+		size -= 4;
+	}
+
+	buf = (u8 *)wbuf;
+	while (size) {
+		*buf++ = readb(&host->base->msdc_rxdata);
+		size--;
+	}
+}
+
+static void msdc_fifo_write(struct msdc_host *host, const u8 *buf, u32 size)
+{
+	const u32 *wbuf;
+
+	while ((size_t)buf % 4) {
+		writeb(*buf++, &host->base->msdc_txdata);
+		size--;
+	}
+
+	wbuf = (const u32 *)buf;
+	while (size >= 4) {
+		writel(*wbuf++, &host->base->msdc_txdata);
+		size -= 4;
+	}
+
+	buf = (const u8 *)wbuf;
+	while (size) {
+		writeb(*buf++, &host->base->msdc_txdata);
+		size--;
+	}
+}
+
+static int msdc_pio_read(struct msdc_host *host, u8 *ptr, u32 size)
+{
+	u32 status;
+	u32 chksz;
+	int ret = 0;
+
+	while (1) {
+		status = readl(&host->base->msdc_int);
+		writel(status, &host->base->msdc_int);
+		status &= DATA_INTS_MASK;
+
+		if (status & MSDC_INT_DATCRCERR) {
+			ret = -EIO;
+			break;
+		}
+
+		if (status & MSDC_INT_DATTMO) {
+			ret = -ETIMEDOUT;
+			break;
+		}
+
+		if (status & MSDC_INT_XFER_COMPL) {
+			if (size) {
+				pr_err("data not fully read\n");
+				ret = -EIO;
+			}
+
+			break;
+		}
+
+		chksz = min(size, (u32)MSDC_FIFO_SIZE);
+
+		if (msdc_fifo_rx_bytes(host) >= chksz) {
+			msdc_fifo_read(host, ptr, chksz);
+			ptr += chksz;
+			size -= chksz;
+		}
+	}
+
+	return ret;
+}
+
+static int msdc_pio_write(struct msdc_host *host, const u8 *ptr, u32 size)
+{
+	u32 status;
+	u32 chksz;
+	int ret = 0;
+
+	while (1) {
+		status = readl(&host->base->msdc_int);
+		writel(status, &host->base->msdc_int);
+		status &= DATA_INTS_MASK;
+
+		if (status & MSDC_INT_DATCRCERR) {
+			ret = -EIO;
+			break;
+		}
+
+		if (status & MSDC_INT_DATTMO) {
+			ret = -ETIMEDOUT;
+			break;
+		}
+
+		if (status & MSDC_INT_XFER_COMPL) {
+			if (size) {
+				pr_err("data not fully written\n");
+				ret = -EIO;
+			}
+
+			break;
+		}
+
+		chksz = min(size, (u32)MSDC_FIFO_SIZE);
+
+		if (MSDC_FIFO_SIZE - msdc_fifo_tx_bytes(host) >= chksz) {
+			msdc_fifo_write(host, ptr, chksz);
+			ptr += chksz;
+			size -= chksz;
+		}
+	}
+
+	return ret;
+}
+
+static int msdc_start_data(struct msdc_host *host, struct mmc_data *data)
+{
+	u32 size;
+	int ret;
+
+	if (data->flags == MMC_DATA_WRITE)
+		host->last_data_write = 1;
+
+	writel(DATA_INTS_MASK, &host->base->msdc_int);
+
+	size = data->blocks * data->blocksize;
+
+	if (data->flags == MMC_DATA_WRITE)
+		ret = msdc_pio_write(host, (const u8 *)data->src, size);
+	else
+		ret = msdc_pio_read(host, (u8 *)data->dest, size);
+
+	if (ret) {
+		msdc_reset_hw(host);
+		msdc_fifo_clr(host);
+	}
+
+	return ret;
+}
+
+static int msdc_ops_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
+			     struct mmc_data *data)
+{
+	struct msdc_host *host = dev_get_priv(dev);
+	int ret;
+
+	ret = msdc_start_command(host, cmd, data);
+	if (ret)
+		return ret;
+
+	if (data)
+		return msdc_start_data(host, data);
+
+	return 0;
+}
+
+static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
+{
+	u32 timeout, clk_ns;
+	u32 mode = 0;
+
+	host->timeout_ns = ns;
+	host->timeout_clks = clks;
+
+	if (host->sclk == 0) {
+		timeout = 0;
+	} else {
+		clk_ns = 1000000000UL / host->sclk;
+		timeout = (ns + clk_ns - 1) / clk_ns + clks;
+		/* unit is 1048576 sclk cycles */
+		timeout = (timeout + (0x1 << 20) - 1) >> 20;
+		if (host->dev_comp->clk_div_bits == 8)
+			mode = (readl(&host->base->msdc_cfg) &
+				MSDC_CFG_CKMOD_M) >> MSDC_CFG_CKMOD_S;
+		else
+			mode = (readl(&host->base->msdc_cfg) &
+				MSDC_CFG_CKMOD_EXT_M) >> MSDC_CFG_CKMOD_EXT_S;
+		/* DDR mode will double the clk cycles for data timeout */
+		timeout = mode >= 2 ? timeout * 2 : timeout;
+		timeout = timeout > 1 ? timeout - 1 : 0;
+		timeout = timeout > 255 ? 255 : timeout;
+	}
+
+	clrsetbits_le32(&host->base->sdc_cfg, SDC_CFG_DTOC_M,
+			timeout << SDC_CFG_DTOC_S);
+}
+
+static void msdc_set_buswidth(struct msdc_host *host, u32 width)
+{
+	u32 val = readl(&host->base->sdc_cfg);
+
+	val &= ~SDC_CFG_BUSWIDTH_M;
+
+	switch (width) {
+	default:
+	case 1:
+		val |= (MSDC_BUS_1BITS << SDC_CFG_BUSWIDTH_S);
+		break;
+	case 4:
+		val |= (MSDC_BUS_4BITS << SDC_CFG_BUSWIDTH_S);
+		break;
+	case 8:
+		val |= (MSDC_BUS_8BITS << SDC_CFG_BUSWIDTH_S);
+		break;
+	}
+
+	writel(val, &host->base->sdc_cfg);
+}
+
+static void msdc_set_mclk(struct msdc_host *host, enum bus_mode timing, u32 hz)
+{
+	u32 mode;
+	u32 div;
+	u32 sclk;
+	u32 reg;
+
+	if (!hz) {
+		host->mclk = 0;
+		clrbits_le32(&host->base->msdc_cfg, MSDC_CFG_CKPDN);
+		return;
+	}
+
+	if (host->dev_comp->clk_div_bits == 8)
+		clrbits_le32(&host->base->msdc_cfg, MSDC_CFG_HS400_CK_MODE);
+	else
+		clrbits_le32(&host->base->msdc_cfg,
+			     MSDC_CFG_HS400_CK_MODE_EXT);
+
+	if (timing == UHS_DDR50 || timing == MMC_DDR_52 ||
+	    timing == MMC_HS_400) {
+		if (timing == MMC_HS_400)
+			mode = 0x3;
+		else
+			mode = 0x2; /* ddr mode and use divisor */
+
+		if (hz >= (host->src_clk_freq >> 2)) {
+			div = 0; /* mean div = 1/4 */
+			sclk = host->src_clk_freq >> 2; /* sclk = clk / 4 */
+		} else {
+			div = (host->src_clk_freq + ((hz << 2) - 1)) /
+			       (hz << 2);
+			sclk = (host->src_clk_freq >> 2) / div;
+			div = (div >> 1);
+		}
+
+		if (timing == MMC_HS_400 && hz >= (host->src_clk_freq >> 1)) {
+			if (host->dev_comp->clk_div_bits == 8)
+				setbits_le32(&host->base->msdc_cfg,
+					     MSDC_CFG_HS400_CK_MODE);
+			else
+				setbits_le32(&host->base->msdc_cfg,
+					     MSDC_CFG_HS400_CK_MODE_EXT);
+
+			sclk = host->src_clk_freq >> 1;
+			div = 0; /* div is ignore when bit18 is set */
+		}
+	} else if (hz >= host->src_clk_freq) {
+		mode = 0x1; /* no divisor */
+		div = 0;
+		sclk = host->src_clk_freq;
+	} else {
+		mode = 0x0; /* use divisor */
+		if (hz >= (host->src_clk_freq >> 1)) {
+			div = 0; /* mean div = 1/2 */
+			sclk = host->src_clk_freq >> 1; /* sclk = clk / 2 */
+		} else {
+			div = (host->src_clk_freq + ((hz << 2) - 1)) /
+			       (hz << 2);
+			sclk = (host->src_clk_freq >> 2) / div;
+		}
+	}
+
+	clrbits_le32(&host->base->msdc_cfg, MSDC_CFG_CKPDN);
+
+	if (host->dev_comp->clk_div_bits == 8) {
+		div = min(div, (u32)(MSDC_CFG_CKDIV_M >> MSDC_CFG_CKDIV_S));
+		clrsetbits_le32(&host->base->msdc_cfg,
+				MSDC_CFG_CKMOD_M | MSDC_CFG_CKDIV_M,
+				(mode << MSDC_CFG_CKMOD_S) |
+				(div << MSDC_CFG_CKDIV_S));
+	} else {
+		div = min(div, (u32)(MSDC_CFG_CKDIV_EXT_M >>
+				      MSDC_CFG_CKDIV_EXT_S));
+		clrsetbits_le32(&host->base->msdc_cfg,
+				MSDC_CFG_CKMOD_EXT_M | MSDC_CFG_CKDIV_EXT_M,
+				(mode << MSDC_CFG_CKMOD_EXT_S) |
+				(div << MSDC_CFG_CKDIV_EXT_S));
+	}
+
+	readl_poll_timeout(&host->base->msdc_cfg, reg,
+			   reg & MSDC_CFG_CKSTB, 1000000);
+
+	setbits_le32(&host->base->msdc_cfg, MSDC_CFG_CKPDN);
+	host->sclk = sclk;
+	host->mclk = hz;
+	host->timing = timing;
+
+	/* needed because clk changed. */
+	msdc_set_timeout(host, host->timeout_ns, host->timeout_clks);
+
+	/*
+	 * mmc_select_hs400() will drop to 50Mhz and High speed mode,
+	 * tune result of hs200/200Mhz is not suitable for 50Mhz
+	 */
+	if (host->sclk <= 52000000) {
+		writel(host->def_tune_para.iocon, &host->base->msdc_iocon);
+		writel(host->def_tune_para.pad_tune,
+		       &host->base->pad_tune);
+	} else {
+		writel(host->saved_tune_para.iocon, &host->base->msdc_iocon);
+		writel(host->saved_tune_para.pad_tune,
+		       &host->base->pad_tune);
+	}
+
+	dev_dbg(dev, "sclk: %d, timing: %d\n", host->sclk, timing);
+}
+
+static int msdc_ops_set_ios(struct udevice *dev)
+{
+	struct msdc_plat *plat = dev_get_platdata(dev);
+	struct msdc_host *host = dev_get_priv(dev);
+	struct mmc *mmc = &plat->mmc;
+	uint clock = mmc->clock;
+
+	msdc_set_buswidth(host, mmc->bus_width);
+
+	if (mmc->clk_disable)
+		clock = 0;
+	else if (clock < mmc->cfg->f_min)
+		clock = mmc->cfg->f_min;
+
+	if (host->mclk != clock || host->timing != mmc->selected_mode)
+		msdc_set_mclk(host, mmc->selected_mode, clock);
+
+	return 0;
+}
+
+static int msdc_ops_get_cd(struct udevice *dev)
+{
+	struct msdc_host *host = dev_get_priv(dev);
+	u32 val;
+
+	if (host->builtin_cd) {
+		val = readl(&host->base->msdc_ps);
+		return !(val & MSDC_PS_CDSTS);
+	}
+
+#ifdef CONFIG_DM_GPIO
+	if (!host->gpio_cd.dev)
+		return 1;
+
+	return dm_gpio_get_value(&host->gpio_cd);
+#else
+	return 1;
+#endif
+}
+
+static int msdc_ops_get_wp(struct udevice *dev)
+{
+	struct msdc_host *host = dev_get_priv(dev);
+
+#ifdef CONFIG_DM_GPIO
+	if (!host->gpio_wp.dev)
+		return 0;
+
+	return !dm_gpio_get_value(&host->gpio_wp);
+#else
+	return 0;
+#endif
+}
+
+#ifdef MMC_SUPPORTS_TUNING
+static u32 test_delay_bit(u32 delay, u32 bit)
+{
+	bit %= PAD_DELAY_MAX;
+	return delay & (1 << bit);
+}
+
+static int get_delay_len(u32 delay, u32 start_bit)
+{
+	int i;
+
+	for (i = 0; i < (PAD_DELAY_MAX - start_bit); i++) {
+		if (test_delay_bit(delay, start_bit + i) == 0)
+			return i;
+	}
+
+	return PAD_DELAY_MAX - start_bit;
+}
+
+static struct msdc_delay_phase get_best_delay(struct msdc_host *host, u32 delay)
+{
+	int start = 0, len = 0;
+	int start_final = 0, len_final = 0;
+	u8 final_phase = 0xff;
+	struct msdc_delay_phase delay_phase = { 0, };
+
+	if (delay == 0) {
+		dev_err(dev, "phase error: [map:%x]\n", delay);
+		delay_phase.final_phase = final_phase;
+		return delay_phase;
+	}
+
+	while (start < PAD_DELAY_MAX) {
+		len = get_delay_len(delay, start);
+		if (len_final < len) {
+			start_final = start;
+			len_final = len;
+		}
+
+		start += len ? len : 1;
+		if (len >= 12 && start_final < 4)
+			break;
+	}
+
+	/* The rule is to find the smallest delay cell */
+	if (start_final == 0)
+		final_phase = (start_final + len_final / 3) % PAD_DELAY_MAX;
+	else
+		final_phase = (start_final + len_final / 2) % PAD_DELAY_MAX;
+
+	dev_info(dev, "phase: [map:%x] [maxlen:%d] [final:%d]\n",
+		 delay, len_final, final_phase);
+
+	delay_phase.maxlen = len_final;
+	delay_phase.start = start_final;
+	delay_phase.final_phase = final_phase;
+	return delay_phase;
+}
+
+static int msdc_tune_response(struct udevice *dev, u32 opcode)
+{
+	struct msdc_plat *plat = dev_get_platdata(dev);
+	struct msdc_host *host = dev_get_priv(dev);
+	struct mmc *mmc = &plat->mmc;
+	u32 rise_delay = 0, fall_delay = 0;
+	struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0, };
+	struct msdc_delay_phase internal_delay_phase;
+	u8 final_delay, final_maxlen;
+	u32 internal_delay = 0;
+	void __iomem *tune_reg = &host->base->pad_tune;
+	int cmd_err;
+	int i, j;
+
+	if (host->dev_comp->pad_tune0)
+		tune_reg = &host->base->pad_tune0;
+
+	if (mmc->selected_mode == MMC_HS_200 ||
+	    mmc->selected_mode == UHS_SDR104)
+		clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRRDLY_M,
+				host->hs200_cmd_int_delay <<
+				MSDC_PAD_TUNE_CMDRRDLY_S);
+
+	clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
+
+	for (i = 0; i < PAD_DELAY_MAX; i++) {
+		clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY_M,
+				i << MSDC_PAD_TUNE_CMDRDLY_S);
+
+		for (j = 0; j < 3; j++) {
+			mmc_send_tuning(mmc, opcode, &cmd_err);
+			if (!cmd_err) {
+				rise_delay |= (1 << i);
+			} else {
+				rise_delay &= ~(1 << i);
+				break;
+			}
+		}
+	}
+
+	final_rise_delay = get_best_delay(host, rise_delay);
+	/* if rising edge has enough margin, do not scan falling edge */
+	if (final_rise_delay.maxlen >= 12 ||
+	    (final_rise_delay.start == 0 && final_rise_delay.maxlen >= 4))
+		goto skip_fall;
+
+	setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
+	for (i = 0; i < PAD_DELAY_MAX; i++) {
+		clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY_M,
+				i << MSDC_PAD_TUNE_CMDRDLY_S);
+
+		for (j = 0; j < 3; j++) {
+			mmc_send_tuning(mmc, opcode, &cmd_err);
+			if (!cmd_err) {
+				fall_delay |= (1 << i);
+			} else {
+				fall_delay &= ~(1 << i);
+				break;
+			}
+		}
+	}
+
+	final_fall_delay = get_best_delay(host, fall_delay);
+
+skip_fall:
+	final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
+	if (final_maxlen == final_rise_delay.maxlen) {
+		clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
+		clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY_M,
+				final_rise_delay.final_phase <<
+				MSDC_PAD_TUNE_CMDRDLY_S);
+		final_delay = final_rise_delay.final_phase;
+	} else {
+		setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
+		clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY_M,
+				final_fall_delay.final_phase <<
+				MSDC_PAD_TUNE_CMDRDLY_S);
+		final_delay = final_fall_delay.final_phase;
+	}
+
+	if (host->dev_comp->async_fifo || host->hs200_cmd_int_delay)
+		goto skip_internal;
+
+	for (i = 0; i < PAD_DELAY_MAX; i++) {
+		clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRRDLY_M,
+				i << MSDC_PAD_TUNE_CMDRRDLY_S);
+
+		mmc_send_tuning(mmc, opcode, &cmd_err);
+		if (!cmd_err)
+			internal_delay |= (1 << i);
+	}
+
+	dev_err(dev, "Final internal delay: 0x%x\n", internal_delay);
+
+	internal_delay_phase = get_best_delay(host, internal_delay);
+	clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRRDLY_M,
+			internal_delay_phase.final_phase <<
+			MSDC_PAD_TUNE_CMDRRDLY_S);
+
+skip_internal:
+	dev_err(dev, "Final cmd pad delay: %x\n", final_delay);
+	return final_delay == 0xff ? -EIO : 0;
+}
+
+static int msdc_tune_data(struct udevice *dev, u32 opcode)
+{
+	struct msdc_plat *plat = dev_get_platdata(dev);
+	struct msdc_host *host = dev_get_priv(dev);
+	struct mmc *mmc = &plat->mmc;
+	u32 rise_delay = 0, fall_delay = 0;
+	struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0, };
+	u8 final_delay, final_maxlen;
+	void __iomem *tune_reg = &host->base->pad_tune;
+	int cmd_err;
+	int i, ret;
+
+	if (host->dev_comp->pad_tune0)
+		tune_reg = &host->base->pad_tune0;
+
+	clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_DSPL);
+	clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_W_DSPL);
+
+	for (i = 0; i < PAD_DELAY_MAX; i++) {
+		clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
+				i << MSDC_PAD_TUNE_DATRRDLY_S);
+
+		ret = mmc_send_tuning(mmc, opcode, &cmd_err);
+		if (!ret) {
+			rise_delay |= (1 << i);
+		} else if (cmd_err) {
+			/* in this case, retune response is needed */
+			ret = msdc_tune_response(dev, opcode);
+			if (ret)
+				break;
+		}
+	}
+
+	final_rise_delay = get_best_delay(host, rise_delay);
+	if (final_rise_delay.maxlen >= 12 ||
+	    (final_rise_delay.start == 0 && final_rise_delay.maxlen >= 4))
+		goto skip_fall;
+
+	setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_DSPL);
+	setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_W_DSPL);
+
+	for (i = 0; i < PAD_DELAY_MAX; i++) {
+		clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
+				i << MSDC_PAD_TUNE_DATRRDLY_S);
+
+		ret = mmc_send_tuning(mmc, opcode, &cmd_err);
+		if (!ret) {
+			fall_delay |= (1 << i);
+		} else if (cmd_err) {
+			/* in this case, retune response is needed */
+			ret = msdc_tune_response(dev, opcode);
+			if (ret)
+				break;
+		}
+	}
+
+	final_fall_delay = get_best_delay(host, fall_delay);
+
+skip_fall:
+	final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
+	if (final_maxlen == final_rise_delay.maxlen) {
+		clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_DSPL);
+		clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_W_DSPL);
+		clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
+				final_rise_delay.final_phase <<
+				MSDC_PAD_TUNE_DATRRDLY_S);
+		final_delay = final_rise_delay.final_phase;
+	} else {
+		setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_DSPL);
+		setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_W_DSPL);
+		clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
+				final_fall_delay.final_phase <<
+				MSDC_PAD_TUNE_DATRRDLY_S);
+		final_delay = final_fall_delay.final_phase;
+	}
+
+	if (mmc->selected_mode == MMC_HS_200 ||
+	    mmc->selected_mode == UHS_SDR104)
+		clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATWRDLY_M,
+				host->hs200_write_int_delay <<
+				MSDC_PAD_TUNE_DATWRDLY_S);
+
+	dev_err(dev, "Final data pad delay: %x\n", final_delay);
+
+	return final_delay == 0xff ? -EIO : 0;
+}
+
+static int msdc_execute_tuning(struct udevice *dev, uint opcode)
+{
+	struct msdc_plat *plat = dev_get_platdata(dev);
+	struct msdc_host *host = dev_get_priv(dev);
+	struct mmc *mmc = &plat->mmc;
+	int ret;
+
+	if (mmc->selected_mode == MMC_HS_400) {
+		writel(host->hs400_ds_delay, &host->base->pad_ds_tune);
+		/* for hs400 mode it must be set to 0 */
+		clrbits_le32(&host->base->patch_bit2, MSDC_PB2_CFGCRCSTS);
+		host->hs400_mode = true;
+	}
+
+	ret = msdc_tune_response(dev, opcode);
+	if (ret == -EIO) {
+		dev_err(dev, "Tune response fail!\n");
+		return ret;
+	}
+
+	if (!host->hs400_mode) {
+		ret = msdc_tune_data(dev, opcode);
+		if (ret == -EIO)
+			dev_err(dev, "Tune data fail!\n");
+	}
+
+	host->saved_tune_para.iocon = readl(&host->base->msdc_iocon);
+	host->saved_tune_para.pad_tune = readl(&host->base->pad_tune);
+
+	return ret;
+}
+#endif
+
+static void msdc_init_hw(struct msdc_host *host)
+{
+	u32 val;
+	void __iomem *tune_reg = &host->base->pad_tune;
+
+	if (host->dev_comp->pad_tune0)
+		tune_reg = &host->base->pad_tune0;
+
+	/* Configure to MMC/SD mode, clock free running */
+	setbits_le32(&host->base->msdc_cfg, MSDC_CFG_MODE);
+
+	/* Use PIO mode */
+	setbits_le32(&host->base->msdc_cfg, MSDC_CFG_PIO);
+
+	/* Reset */
+	msdc_reset_hw(host);
+
+	/* Enable/disable hw card detection according to fdt option */
+	if (host->builtin_cd)
+		clrsetbits_le32(&host->base->msdc_ps,
+			MSDC_PS_CDDBCE_M,
+			(DEFAULT_CD_DEBOUNCE << MSDC_PS_CDDBCE_S) |
+			MSDC_PS_CDEN);
+	else
+		clrbits_le32(&host->base->msdc_ps, MSDC_PS_CDEN);
+
+	/* Clear all interrupts */
+	val = readl(&host->base->msdc_int);
+	writel(val, &host->base->msdc_int);
+
+	/* Enable data & cmd interrupts */
+	writel(DATA_INTS_MASK | CMD_INTS_MASK, &host->base->msdc_inten);
+
+	writel(0, tune_reg);
+	writel(0, &host->base->msdc_iocon);
+
+	if (host->r_smpl)
+		setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
+	else
+		clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
+
+	writel(0x403c0046, &host->base->patch_bit0);
+	writel(0xffff4089, &host->base->patch_bit1);
+
+	if (host->dev_comp->stop_clk_fix)
+		clrsetbits_le32(&host->base->patch_bit1, MSDC_PB1_STOP_DLY_M,
+				3 << MSDC_PB1_STOP_DLY_S);
+
+	if (host->dev_comp->busy_check)
+		clrbits_le32(&host->base->patch_bit1, (1 << 7));
+
+	setbits_le32(&host->base->emmc50_cfg0, EMMC50_CFG_CFCSTS_SEL);
+
+	if (host->dev_comp->async_fifo) {
+		clrsetbits_le32(&host->base->patch_bit2, MSDC_PB2_RESPWAIT_M,
+				3 << MSDC_PB2_RESPWAIT_S);
+
+		if (host->dev_comp->enhance_rx) {
+			setbits_le32(&host->base->sdc_adv_cfg0,
+				     SDC_RX_ENHANCE_EN);
+		} else {
+			clrsetbits_le32(&host->base->patch_bit2,
+					MSDC_PB2_RESPSTSENSEL_M,
+					2 << MSDC_PB2_RESPSTSENSEL_S);
+			clrsetbits_le32(&host->base->patch_bit2,
+					MSDC_PB2_CRCSTSENSEL_M,
+					2 << MSDC_PB2_CRCSTSENSEL_S);
+		}
+
+		/* use async fifo to avoid tune internal delay */
+		clrbits_le32(&host->base->patch_bit2,
+			     MSDC_PB2_CFGRESP);
+		clrbits_le32(&host->base->patch_bit2,
+			     MSDC_PB2_CFGCRCSTS);
+	}
+
+	if (host->dev_comp->data_tune) {
+		setbits_le32(tune_reg,
+			     MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL);
+		clrsetbits_le32(&host->base->patch_bit0,
+				MSDC_INT_DAT_LATCH_CK_SEL_M,
+				host->latch_ck <<
+				MSDC_INT_DAT_LATCH_CK_SEL_S);
+	} else {
+		/* choose clock tune */
+		setbits_le32(tune_reg, MSDC_PAD_TUNE_RXDLYSEL);
+	}
+
+	/* Configure to enable SDIO mode otherwise sdio cmd5 won't work */
+	setbits_le32(&host->base->sdc_cfg, SDC_CFG_SDIO);
+
+	/* disable detecting SDIO device interrupt function */
+	clrbits_le32(&host->base->sdc_cfg, SDC_CFG_SDIOIDE);
+
+	/* Configure to default data timeout */
+	clrsetbits_le32(&host->base->sdc_cfg, SDC_CFG_DTOC_M,
+			3 << SDC_CFG_DTOC_S);
+
+	if (host->dev_comp->stop_clk_fix) {
+		clrbits_le32(&host->base->sdc_fifo_cfg,
+			     SDC_FIFO_CFG_WRVALIDSEL);
+		clrbits_le32(&host->base->sdc_fifo_cfg,
+			     SDC_FIFO_CFG_RDVALIDSEL);
+	}
+
+	host->def_tune_para.iocon = readl(&host->base->msdc_iocon);
+	host->def_tune_para.pad_tune = readl(&host->base->pad_tune);
+}
+
+static void msdc_ungate_clock(struct msdc_host *host)
+{
+	clk_enable(&host->src_clk);
+	clk_enable(&host->h_clk);
+}
+
+static int msdc_drv_probe(struct udevice *dev)
+{
+	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+	struct msdc_plat *plat = dev_get_platdata(dev);
+	struct msdc_host *host = dev_get_priv(dev);
+	struct mmc_config *cfg = &plat->cfg;
+
+	cfg->name = dev->name;
+
+	host->dev_comp = (struct msdc_compatible *)dev_get_driver_data(dev);
+
+	host->src_clk_freq = clk_get_rate(&host->src_clk);
+
+	if (host->dev_comp->clk_div_bits == 8)
+		cfg->f_min = host->src_clk_freq / (4 * 255);
+	else
+		cfg->f_min = host->src_clk_freq / (4 * 4095);
+	cfg->f_max = host->src_clk_freq / 2;
+
+	cfg->b_max = 1024;
+	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+	host->mmc = &plat->mmc;
+	host->timeout_ns = 100000000;
+	host->timeout_clks = 3 * 1048576;
+
+#ifdef CONFIG_PINCTRL
+	pinctrl_select_state(dev, "default");
+#endif
+
+	msdc_ungate_clock(host);
+	msdc_init_hw(host);
+
+	upriv->mmc = &plat->mmc;
+
+	return 0;
+}
+
+static int msdc_ofdata_to_platdata(struct udevice *dev)
+{
+	struct msdc_plat *plat = dev_get_platdata(dev);
+	struct msdc_host *host = dev_get_priv(dev);
+	struct mmc_config *cfg = &plat->cfg;
+	int ret;
+
+	host->base = (void *)dev_read_addr(dev);
+	if (!host->base)
+		return -EINVAL;
+
+	ret = mmc_of_parse(dev, cfg);
+	if (ret)
+		return ret;
+
+	ret = clk_get_by_name(dev, "source", &host->src_clk);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_get_by_name(dev, "hclk", &host->h_clk);
+	if (ret < 0)
+		return ret;
+
+#ifdef CONFIG_DM_GPIO
+	gpio_request_by_name(dev, "wp-gpios", 0, &host->gpio_wp, GPIOD_IS_IN);
+	gpio_request_by_name(dev, "cd-gpios", 0, &host->gpio_cd, GPIOD_IS_IN);
+#endif
+
+	host->hs400_ds_delay = dev_read_u32_default(dev, "hs400-ds-delay", 0);
+	host->hs200_cmd_int_delay =
+			dev_read_u32_default(dev, "cmd_int_delay", 0);
+	host->hs200_write_int_delay =
+			dev_read_u32_default(dev, "write_int_delay", 0);
+	host->latch_ck = dev_read_u32_default(dev, "latch-ck", 0);
+	host->r_smpl = dev_read_u32_default(dev, "r_smpl", 0);
+	host->builtin_cd = dev_read_u32_default(dev, "builtin-cd", 0);
+
+	return 0;
+}
+
+static int msdc_drv_bind(struct udevice *dev)
+{
+	struct msdc_plat *plat = dev_get_platdata(dev);
+
+	return mmc_bind(dev, &plat->mmc, &plat->cfg);
+}
+
+static const struct dm_mmc_ops msdc_ops = {
+	.send_cmd = msdc_ops_send_cmd,
+	.set_ios = msdc_ops_set_ios,
+	.get_cd = msdc_ops_get_cd,
+	.get_wp = msdc_ops_get_wp,
+#ifdef MMC_SUPPORTS_TUNING
+	.execute_tuning = msdc_execute_tuning,
+#endif
+};
+
+static const struct msdc_compatible mt7623_compat = {
+	.clk_div_bits = 12,
+	.pad_tune0 = true,
+	.async_fifo = true,
+	.data_tune = true,
+	.busy_check = false,
+	.stop_clk_fix = false,
+	.enhance_rx = false
+};
+
+static const struct udevice_id msdc_ids[] = {
+	{ .compatible = "mediatek,mt7623-mmc", .data = (ulong)&mt7623_compat },
+	{}
+};
+
+U_BOOT_DRIVER(mtk_sd_drv) = {
+	.name = "mtk_sd",
+	.id = UCLASS_MMC,
+	.of_match = msdc_ids,
+	.ofdata_to_platdata = msdc_ofdata_to_platdata,
+	.bind = msdc_drv_bind,
+	.probe = msdc_drv_probe,
+	.ops = &msdc_ops,
+	.platdata_auto_alloc_size = sizeof(struct msdc_plat),
+	.priv_auto_alloc_size = sizeof(struct msdc_host),
+};
diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c
index e7f96f8..733b6d6 100644
--- a/drivers/mmc/renesas-sdhi.c
+++ b/drivers/mmc/renesas-sdhi.c
@@ -17,7 +17,9 @@
 
 #include "tmio-common.h"
 
-#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
+    CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
+    CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
 
 /* SCC registers */
 #define RENESAS_SDHI_SCC_DTCNTL			0x800
@@ -107,6 +109,56 @@
 	tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL);
 }
 
+static int renesas_sdhi_hs400(struct udevice *dev)
+{
+	struct tmio_sd_priv *priv = dev_get_priv(dev);
+	struct mmc *mmc = mmc_get_mmc_dev(dev);
+	bool hs400 = (mmc->selected_mode == MMC_HS_400);
+	int ret, taps = hs400 ? priv->nrtaps : 8;
+	u32 reg;
+
+	if (taps == 4)	/* HS400 on 4tap SoC needs different clock */
+		ret = clk_set_rate(&priv->clk, 400000000);
+	else
+		ret = clk_set_rate(&priv->clk, 200000000);
+	if (ret < 0)
+		return ret;
+
+	tmio_sd_writel(priv, 0, RENESAS_SDHI_SCC_RVSREQ);
+
+	reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_TMPPORT2);
+	if (hs400) {
+		reg |= RENESAS_SDHI_SCC_TMPPORT2_HS400EN |
+		       RENESAS_SDHI_SCC_TMPPORT2_HS400OSEL;
+	} else {
+		reg &= ~(RENESAS_SDHI_SCC_TMPPORT2_HS400EN |
+		       RENESAS_SDHI_SCC_TMPPORT2_HS400OSEL);
+	}
+
+	tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_TMPPORT2);
+
+	tmio_sd_writel(priv, (taps << RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT) |
+			     RENESAS_SDHI_SCC_DTCNTL_TAPEN,
+			     RENESAS_SDHI_SCC_DTCNTL);
+
+	if (taps == 4) {
+		tmio_sd_writel(priv, priv->tap_set >> 1,
+			       RENESAS_SDHI_SCC_TAPSET);
+	} else {
+		tmio_sd_writel(priv, priv->tap_set, RENESAS_SDHI_SCC_TAPSET);
+	}
+
+	reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_CKSEL);
+	reg |= RENESAS_SDHI_SCC_CKSEL_DTSEL;
+	tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_CKSEL);
+
+	reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL);
+	reg |= RENESAS_SDHI_SCC_RVSCNTL_RVSEN;
+	tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL);
+
+	return 0;
+}
+
 static void renesas_sdhi_prepare_tuning(struct tmio_sd_priv *priv,
 				       unsigned long tap)
 {
@@ -125,7 +177,6 @@
 				     unsigned int smpcmp)
 {
 	unsigned long tap_cnt;  /* counter of tuning success */
-	unsigned long tap_set;  /* tap position */
 	unsigned long tap_start;/* start position of tuning success */
 	unsigned long tap_end;  /* end position of tuning success */
 	unsigned long ntap;     /* temporary counter of tuning success */
@@ -209,12 +260,12 @@
 		select = true;
 
 	if (select)
-		tap_set = ((tap_start + tap_end) / 2) % tap_num;
+		priv->tap_set = ((tap_start + tap_end) / 2) % tap_num;
 	else
 		return -EIO;
 
 	/* Set SCC */
-	tmio_sd_writel(priv, tap_set, RENESAS_SDHI_SCC_TAPSET);
+	tmio_sd_writel(priv, priv->tap_set, RENESAS_SDHI_SCC_TAPSET);
 
 	/* Enable auto re-tuning */
 	reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL);
@@ -240,6 +291,7 @@
 
 	/* clock tuning is not needed for upto 52MHz */
 	if (!((mmc->selected_mode == MMC_HS_200) ||
+	      (mmc->selected_mode == MMC_HS_400) ||
 	      (mmc->selected_mode == UHS_SDR104) ||
 	      (mmc->selected_mode == UHS_SDR50)))
 		return 0;
@@ -287,19 +339,42 @@
 
 	return ret;
 }
+#else
+static int renesas_sdhi_hs400(struct udevice *dev)
+{
+	return 0;
+}
 #endif
 
 static int renesas_sdhi_set_ios(struct udevice *dev)
 {
-	int ret = tmio_sd_set_ios(dev);
+	struct tmio_sd_priv *priv = dev_get_priv(dev);
+	u32 tmp;
+	int ret;
 
-	mdelay(10);
+	/* Stop the clock before changing its rate to avoid a glitch signal */
+	tmp = tmio_sd_readl(priv, TMIO_SD_CLKCTL);
+	tmp &= ~TMIO_SD_CLKCTL_SCLKEN;
+	tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL);
 
-#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
-	struct tmio_sd_priv *priv = dev_get_priv(dev);
+	ret = renesas_sdhi_hs400(dev);
+	if (ret)
+		return ret;
+
+	ret = tmio_sd_set_ios(dev);
+
+	mdelay(10);
 
-	if (priv->caps & TMIO_SD_CAP_RCAR_UHS)
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
+    CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
+    CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+	struct mmc *mmc = mmc_get_mmc_dev(dev);
+	if ((priv->caps & TMIO_SD_CAP_RCAR_UHS) &&
+	    (mmc->selected_mode != UHS_SDR104) &&
+	    (mmc->selected_mode != MMC_HS_200) &&
+	    (mmc->selected_mode != MMC_HS_400)) {
 		renesas_sdhi_reset_tuning(priv);
+	}
 #endif
 
 	return ret;
@@ -331,7 +406,9 @@
 	.send_cmd = tmio_sd_send_cmd,
 	.set_ios = renesas_sdhi_set_ios,
 	.get_cd = tmio_sd_get_cd,
-#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
+    CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
+    CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
 	.execute_tuning = renesas_sdhi_execute_tuning,
 #endif
 #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
@@ -358,15 +435,45 @@
 	{ /* sentinel */ }
 };
 
+static ulong renesas_sdhi_clk_get_rate(struct tmio_sd_priv *priv)
+{
+	return clk_get_rate(&priv->clk);
+}
+
+static void renesas_sdhi_filter_caps(struct udevice *dev)
+{
+	struct tmio_sd_plat *plat = dev_get_platdata(dev);
+	struct tmio_sd_priv *priv = dev_get_priv(dev);
+
+	if (!(priv->caps & TMIO_SD_CAP_RCAR_GEN3))
+		return;
+
+	/* HS400 is not supported on H3 ES1.x and M3W ES1.0,ES1.1 */
+	if (((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7795) &&
+	    (rmobile_get_cpu_rev_integer() <= 1)) ||
+	    ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7796) &&
+	    (rmobile_get_cpu_rev_integer() == 1) &&
+	    (rmobile_get_cpu_rev_fraction() <= 1)))
+		plat->cfg.host_caps &= ~MMC_MODE_HS400;
+
+	/* H3 ES2.0 uses 4 tuning taps */
+	if ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7795) &&
+	    (rmobile_get_cpu_rev_integer() == 2))
+		priv->nrtaps = 4;
+	else
+		priv->nrtaps = 8;
+}
+
 static int renesas_sdhi_probe(struct udevice *dev)
 {
 	struct tmio_sd_priv *priv = dev_get_priv(dev);
 	u32 quirks = dev_get_driver_data(dev);
 	struct fdt_resource reg_res;
-	struct clk clk;
 	DECLARE_GLOBAL_DATA_PTR;
 	int ret;
 
+	priv->clk_get_rate = renesas_sdhi_clk_get_rate;
+
 	if (quirks == RENESAS_GEN2_QUIRKS) {
 		ret = fdt_get_resource(gd->fdt_blob, dev_of_offset(dev),
 				       "reg", 0, &reg_res);
@@ -380,29 +487,33 @@
 			quirks |= TMIO_SD_CAP_16BIT;
 	}
 
-	ret = clk_get_by_index(dev, 0, &clk);
+	ret = clk_get_by_index(dev, 0, &priv->clk);
 	if (ret < 0) {
 		dev_err(dev, "failed to get host clock\n");
 		return ret;
 	}
 
 	/* set to max rate */
-	priv->mclk = clk_set_rate(&clk, ULONG_MAX);
-	if (IS_ERR_VALUE(priv->mclk)) {
+	ret = clk_set_rate(&priv->clk, 200000000);
+	if (ret < 0) {
 		dev_err(dev, "failed to set rate for host clock\n");
-		clk_free(&clk);
-		return priv->mclk;
+		clk_free(&priv->clk);
+		return ret;
 	}
 
-	ret = clk_enable(&clk);
-	clk_free(&clk);
+	ret = clk_enable(&priv->clk);
 	if (ret) {
 		dev_err(dev, "failed to enable host clock\n");
 		return ret;
 	}
 
 	ret = tmio_sd_probe(dev, quirks);
-#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
+
+	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))
 		renesas_sdhi_reset_tuning(priv);
 #endif
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 147eb9b..9bf040c 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -98,24 +98,21 @@
 static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
 {
 	unsigned int pll, pll_hz, div, n, oclk_dly, sclk_dly;
-	bool new_mode = false;
+	bool new_mode = true;
 	bool calibrate = false;
 	u32 val = 0;
 
-	if (IS_ENABLED(CONFIG_MMC_SUNXI_HAS_NEW_MODE) && (priv->mmc_no == 2))
-		new_mode = true;
+	if (!IS_ENABLED(CONFIG_MMC_SUNXI_HAS_NEW_MODE))
+		new_mode = false;
+
+	/* A83T support new mode only on eMMC */
+	if (IS_ENABLED(CONFIG_MACH_SUN8I_A83T) && priv->mmc_no != 2)
+		new_mode = false;
 
 #if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H6)
 	calibrate = true;
 #endif
 
-	/*
-	 * The MMC clock has an extra /2 post-divider when operating in the new
-	 * mode.
-	 */
-	if (new_mode)
-		hz = hz * 2;
-
 	if (hz <= 24000000) {
 		pll = CCM_MMC_CTRL_OSCM24;
 		pll_hz = 24000000;
@@ -176,7 +173,9 @@
 
 	if (new_mode) {
 #ifdef CONFIG_MMC_SUNXI_HAS_NEW_MODE
+#ifdef CONFIG_MMC_SUNXI_HAS_MODE_SWITCH
 		val = CCM_MMC_CTRL_MODE_SEL_NEW;
+#endif
 		setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);
 #endif
 	} else if (!calibrate) {
diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c
index 0eca83a..2014920 100644
--- a/drivers/mmc/tmio-common.c
+++ b/drivers/mmc/tmio-common.c
@@ -555,55 +555,76 @@
 	tmio_sd_writel(priv, tmp, TMIO_SD_IF_MODE);
 }
 
-static void tmio_sd_set_clk_rate(struct tmio_sd_priv *priv,
-				     struct mmc *mmc)
+static ulong tmio_sd_clk_get_rate(struct tmio_sd_priv *priv)
+{
+	return priv->clk_get_rate(priv);
+}
+
+static void tmio_sd_set_clk_rate(struct tmio_sd_priv *priv, struct mmc *mmc)
 {
 	unsigned int divisor;
-	u32 val, tmp;
+	u32 tmp, val = 0;
+	ulong mclk;
 
-	if (!mmc->clock)
-		return;
+	if (mmc->clock) {
+		mclk = tmio_sd_clk_get_rate(priv);
 
-	divisor = DIV_ROUND_UP(priv->mclk, mmc->clock);
+		divisor = DIV_ROUND_UP(mclk, mmc->clock);
 
-	if (divisor <= 1)
-		val = (priv->caps & TMIO_SD_CAP_RCAR) ?
-		      TMIO_SD_CLKCTL_RCAR_DIV1 : TMIO_SD_CLKCTL_DIV1;
-	else if (divisor <= 2)
-		val = TMIO_SD_CLKCTL_DIV2;
-	else if (divisor <= 4)
-		val = TMIO_SD_CLKCTL_DIV4;
-	else if (divisor <= 8)
-		val = TMIO_SD_CLKCTL_DIV8;
-	else if (divisor <= 16)
-		val = TMIO_SD_CLKCTL_DIV16;
-	else if (divisor <= 32)
-		val = TMIO_SD_CLKCTL_DIV32;
-	else if (divisor <= 64)
-		val = TMIO_SD_CLKCTL_DIV64;
-	else if (divisor <= 128)
-		val = TMIO_SD_CLKCTL_DIV128;
-	else if (divisor <= 256)
-		val = TMIO_SD_CLKCTL_DIV256;
-	else if (divisor <= 512 || !(priv->caps & TMIO_SD_CAP_DIV1024))
-		val = TMIO_SD_CLKCTL_DIV512;
-	else
-		val = TMIO_SD_CLKCTL_DIV1024;
+		/* Do not set divider to 0xff in DDR mode */
+		if (mmc->ddr_mode && (divisor == 1))
+			divisor = 2;
+
+		if (divisor <= 1)
+			val = (priv->caps & TMIO_SD_CAP_RCAR) ?
+			      TMIO_SD_CLKCTL_RCAR_DIV1 : TMIO_SD_CLKCTL_DIV1;
+		else if (divisor <= 2)
+			val = TMIO_SD_CLKCTL_DIV2;
+		else if (divisor <= 4)
+			val = TMIO_SD_CLKCTL_DIV4;
+		else if (divisor <= 8)
+			val = TMIO_SD_CLKCTL_DIV8;
+		else if (divisor <= 16)
+			val = TMIO_SD_CLKCTL_DIV16;
+		else if (divisor <= 32)
+			val = TMIO_SD_CLKCTL_DIV32;
+		else if (divisor <= 64)
+			val = TMIO_SD_CLKCTL_DIV64;
+		else if (divisor <= 128)
+			val = TMIO_SD_CLKCTL_DIV128;
+		else if (divisor <= 256)
+			val = TMIO_SD_CLKCTL_DIV256;
+		else if (divisor <= 512 || !(priv->caps & TMIO_SD_CAP_DIV1024))
+			val = TMIO_SD_CLKCTL_DIV512;
+		else
+			val = TMIO_SD_CLKCTL_DIV1024;
+	}
 
 	tmp = tmio_sd_readl(priv, TMIO_SD_CLKCTL);
-	if (tmp & TMIO_SD_CLKCTL_SCLKEN &&
-	    (tmp & TMIO_SD_CLKCTL_DIV_MASK) == val)
-		return;
+	if (mmc->clock &&
+	    !((tmp & TMIO_SD_CLKCTL_SCLKEN) &&
+	      ((tmp & TMIO_SD_CLKCTL_DIV_MASK) == val))) {
+		/*
+		 * Stop the clock before changing its rate
+		 * to avoid a glitch signal
+		 */
+		tmp &= ~TMIO_SD_CLKCTL_SCLKEN;
+		tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL);
 
-	/* stop the clock before changing its rate to avoid a glitch signal */
-	tmp &= ~TMIO_SD_CLKCTL_SCLKEN;
-	tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL);
+		/* Change the clock rate. */
+		tmp &= ~TMIO_SD_CLKCTL_DIV_MASK;
+		tmp |= val;
+	}
 
-	tmp &= ~TMIO_SD_CLKCTL_DIV_MASK;
-	tmp |= val | TMIO_SD_CLKCTL_OFFEN;
-	tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL);
+	/* Enable or Disable the clock */
+	if (mmc->clk_disable) {
+		tmp |= TMIO_SD_CLKCTL_OFFEN;
+		tmp &= ~TMIO_SD_CLKCTL_SCLKEN;
+	} else {
+		tmp &= ~TMIO_SD_CLKCTL_OFFEN;
+		tmp |= TMIO_SD_CLKCTL_SCLKEN;
+	}
 
-	tmp |= TMIO_SD_CLKCTL_SCLKEN;
 	tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL);
 
 	udelay(1000);
@@ -708,6 +729,7 @@
 	struct tmio_sd_priv *priv = dev_get_priv(dev);
 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
 	fdt_addr_t base;
+	ulong mclk;
 	int ret;
 
 	base = devfdt_get_addr(dev);
@@ -750,10 +772,12 @@
 
 	tmio_sd_host_init(priv);
 
+	mclk = tmio_sd_clk_get_rate(priv);
+
 	plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
-	plat->cfg.f_min = priv->mclk /
+	plat->cfg.f_min = mclk /
 			(priv->caps & TMIO_SD_CAP_DIV1024 ? 1024 : 512);
-	plat->cfg.f_max = priv->mclk;
+	plat->cfg.f_max = mclk;
 	plat->cfg.b_max = U32_MAX; /* max value of TMIO_SD_SECCNT */
 
 	upriv->mmc = &plat->mmc;
diff --git a/drivers/mmc/tmio-common.h b/drivers/mmc/tmio-common.h
index 792b1ba..192026c 100644
--- a/drivers/mmc/tmio-common.h
+++ b/drivers/mmc/tmio-common.h
@@ -117,7 +117,6 @@
 
 struct tmio_sd_priv {
 	void __iomem			*regbase;
-	unsigned long			mclk;
 	unsigned int			version;
 	u32				caps;
 #define TMIO_SD_CAP_NONREMOVABLE	BIT(0)	/* Nonremovable e.g. eMMC */
@@ -133,6 +132,14 @@
 #ifdef CONFIG_DM_REGULATOR
 	struct udevice *vqmmc_dev;
 #endif
+#if CONFIG_IS_ENABLED(CLK)
+	struct clk			clk;
+#endif
+#if CONFIG_IS_ENABLED(RENESAS_SDHI)
+	u8				tap_set;
+	u8				nrtaps;
+#endif
+	ulong (*clk_get_rate)(struct tmio_sd_priv *);
 };
 
 int tmio_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
diff --git a/drivers/mmc/uniphier-sd.c b/drivers/mmc/uniphier-sd.c
index 813c284..6539880 100644
--- a/drivers/mmc/uniphier-sd.c
+++ b/drivers/mmc/uniphier-sd.c
@@ -31,35 +31,45 @@
 	{ /* sentinel */ }
 };
 
+static ulong uniphier_sd_clk_get_rate(struct tmio_sd_priv *priv)
+{
+#if CONFIG_IS_ENABLED(CLK)
+	return clk_get_rate(&priv->clk);
+#elif CONFIG_SPL_BUILD
+	return 100000000;
+#else
+	return 0;
+#endif
+}
+
 static int uniphier_sd_probe(struct udevice *dev)
 {
 	struct tmio_sd_priv *priv = dev_get_priv(dev);
+
+	priv->clk_get_rate = uniphier_sd_clk_get_rate;
+
 #ifndef CONFIG_SPL_BUILD
-	struct clk clk;
 	int ret;
 
-	ret = clk_get_by_index(dev, 0, &clk);
+	ret = clk_get_by_index(dev, 0, &priv->clk);
 	if (ret < 0) {
 		dev_err(dev, "failed to get host clock\n");
 		return ret;
 	}
 
 	/* set to max rate */
-	priv->mclk = clk_set_rate(&clk, ULONG_MAX);
-	if (IS_ERR_VALUE(priv->mclk)) {
+	ret = clk_set_rate(&priv->clk, ULONG_MAX);
+	if (ret < 0) {
 		dev_err(dev, "failed to set rate for host clock\n");
-		clk_free(&clk);
-		return priv->mclk;
+		clk_free(&priv->clk);
+		return ret;
 	}
 
-	ret = clk_enable(&clk);
-	clk_free(&clk);
+	ret = clk_enable(&priv->clk);
 	if (ret) {
 		dev_err(dev, "failed to enable host clock\n");
 		return ret;
 	}
-#else
-	priv->mclk = 100000000;
 #endif
 
 	return tmio_sd_probe(dev, 0);
diff --git a/drivers/mtd/nand/raw/arasan_nfc.c b/drivers/mtd/nand/raw/arasan_nfc.c
index 41db9f8b..dc531cc 100644
--- a/drivers/mtd/nand/raw/arasan_nfc.c
+++ b/drivers/mtd/nand/raw/arasan_nfc.c
@@ -1201,6 +1201,10 @@
 	mtd = nand_to_mtd(nand_chip);
 	nand_set_controller_data(nand_chip, nand);
 
+#ifdef CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
+	nand_chip->options |= NAND_NO_SUBPAGE_WRITE;
+#endif
+
 	/* Set the driver entry points for MTD */
 	nand_chip->cmdfunc = arasan_nand_cmd_function;
 	nand_chip->select_chip = arasan_nand_select_chip;
diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 7fef754..7b9891c 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -57,6 +57,8 @@
 /* Bits for the status register */
 #define STAT_WIP	(1 << 0)
 #define STAT_WEL	(1 << 1)
+#define STAT_BP_SHIFT	2
+#define STAT_BP_MASK	(7 << STAT_BP_SHIFT)
 
 /* Assume all SPI flashes have 3 byte addresses since they do atm */
 #define SF_ADDR_LEN	3
@@ -102,6 +104,14 @@
 	int cs;
 };
 
+void sandbox_sf_set_block_protect(struct udevice *dev, int bp_mask)
+{
+	struct sandbox_spi_flash *sbsf = dev_get_priv(dev);
+
+	sbsf->status &= ~STAT_BP_MASK;
+	sbsf->status |= bp_mask << STAT_BP_SHIFT;
+}
+
 /**
  * This is a very strange probe function. If it has platform data (which may
  * have come from the device tree) then this function gets the filename and
diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c
index 662525f..719a2fd 100644
--- a/drivers/mtd/spi/sf-uclass.c
+++ b/drivers/mtd/spi/sf-uclass.c
@@ -28,6 +28,15 @@
 	return log_ret(sf_get_ops(dev)->erase(dev, offset, len));
 }
 
+int spl_flash_get_sw_write_prot(struct udevice *dev)
+{
+	struct dm_spi_flash_ops *ops = sf_get_ops(dev);
+
+	if (!ops->get_sw_write_prot)
+		return -ENOSYS;
+	return log_ret(ops->get_sw_write_prot(dev));
+}
+
 /*
  * TODO(sjg@chromium.org): This is an old-style function. We should remove
  * it when all SPI flash drivers use dm
diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 26f5c7c..46a5044 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -170,6 +170,9 @@
 /* Flash erase(sectors) operation, support all possible erase commands */
 int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len);
 
+/* Get software write-protect value (BP bits) */
+int spi_flash_cmd_get_sw_write_prot(struct spi_flash *flash);
+
 /* Lock stmicro spi flash region */
 int stm_lock(struct spi_flash *flash, u32 ofs, size_t len);
 
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 4d7320f..00f8558 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -124,6 +124,13 @@
 	return spi_flash_cmd_erase_ops(flash, offset, len);
 }
 
+static int spi_flash_std_get_sw_write_prot(struct udevice *dev)
+{
+	struct spi_flash *flash = dev_get_uclass_priv(dev);
+
+	return spi_flash_cmd_get_sw_write_prot(flash);
+}
+
 static int spi_flash_std_probe(struct udevice *dev)
 {
 	struct spi_slave *slave = dev_get_parent_priv(dev);
@@ -149,6 +156,7 @@
 	.read = spi_flash_std_read,
 	.write = spi_flash_std_write,
 	.erase = spi_flash_std_erase,
+	.get_sw_write_prot = spi_flash_std_get_sw_write_prot,
 };
 
 static const struct udevice_id spi_flash_std_ids[] = {
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index a87bacd..0c2392f 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -110,6 +110,18 @@
 }
 #endif
 
+int spi_flash_cmd_get_sw_write_prot(struct spi_flash *flash)
+{
+	u8 status;
+	int ret;
+
+	ret = read_sr(flash, &status);
+	if (ret)
+		return ret;
+
+	return (status >> 2) & 7;
+}
+
 #ifdef CONFIG_SPI_FLASH_BAR
 /*
  * This "clean_bar" is necessary in a situation when one was accessing
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 19db0a8..4fa26ab 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -838,6 +838,8 @@
 	{ .compatible = "altr,socfpga-stmmac" },
 	{ .compatible = "amlogic,meson6-dwmac" },
 	{ .compatible = "amlogic,meson-gx-dwmac" },
+	{ .compatible = "amlogic,meson-gxbb-dwmac" },
+	{ .compatible = "amlogic,meson-axg-dwmac" },
 	{ .compatible = "st,stm32-dwmac" },
 	{ }
 };
diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
index 3ba3a1f..c979844 100644
--- a/drivers/net/sun8i_emac.c
+++ b/drivers/net/sun8i_emac.c
@@ -60,6 +60,10 @@
 #define SC_ETCS_MASK		GENMASK(1, 0)
 #define SC_ETCS_EXT_GMII	0x1
 #define SC_ETCS_INT_GMII	0x2
+#define SC_ETXDC_MASK		GENMASK(12, 10)
+#define SC_ETXDC_OFFSET		10
+#define SC_ERXDC_MASK		GENMASK(9, 5)
+#define SC_ERXDC_OFFSET		5
 
 #define CONFIG_MDIO_TIMEOUT	(3 * CONFIG_SYS_HZ)
 
@@ -140,6 +144,8 @@
 struct sun8i_eth_pdata {
 	struct eth_pdata eth_pdata;
 	u32 reset_delays[3];
+	int tx_delay_ps;
+	int rx_delay_ps;
 };
 
 
@@ -273,7 +279,8 @@
 	return 0;
 }
 
-static int sun8i_emac_set_syscon(struct emac_eth_dev *priv)
+static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata,
+				 struct emac_eth_dev *priv)
 {
 	int ret;
 	u32 reg;
@@ -312,6 +319,14 @@
 		return -EINVAL;
 	}
 
+	if (pdata->tx_delay_ps)
+		reg |= ((pdata->tx_delay_ps / 100) << SC_ETXDC_OFFSET)
+			 & SC_ETXDC_MASK;
+
+	if (pdata->rx_delay_ps)
+		reg |= ((pdata->rx_delay_ps / 100) << SC_ERXDC_OFFSET)
+			 & SC_ERXDC_MASK;
+
 	writel(reg, priv->sysctl_reg + 0x30);
 
 	return 0;
@@ -784,13 +799,14 @@
 
 static int sun8i_emac_eth_probe(struct udevice *dev)
 {
-	struct eth_pdata *pdata = dev_get_platdata(dev);
+	struct sun8i_eth_pdata *sun8i_pdata = dev_get_platdata(dev);
+	struct eth_pdata *pdata = &sun8i_pdata->eth_pdata;
 	struct emac_eth_dev *priv = dev_get_priv(dev);
 
 	priv->mac_reg = (void *)pdata->iobase;
 
 	sun8i_emac_board_setup(priv);
-	sun8i_emac_set_syscon(priv);
+	sun8i_emac_set_syscon(sun8i_pdata, priv);
 
 	sun8i_mdio_init(dev->name, dev);
 	priv->bus = miiphy_get_dev_by_name(dev->name);
@@ -891,6 +907,18 @@
 	if (!priv->use_internal_phy)
 		parse_phy_pins(dev);
 
+	sun8i_pdata->tx_delay_ps = fdtdec_get_int(gd->fdt_blob, node,
+						  "allwinner,tx-delay-ps", 0);
+	if (sun8i_pdata->tx_delay_ps < 0 || sun8i_pdata->tx_delay_ps > 700)
+		printf("%s: Invalid TX delay value %d\n", __func__,
+		       sun8i_pdata->tx_delay_ps);
+
+	sun8i_pdata->rx_delay_ps = fdtdec_get_int(gd->fdt_blob, node,
+						  "allwinner,rx-delay-ps", 0);
+	if (sun8i_pdata->rx_delay_ps < 0 || sun8i_pdata->rx_delay_ps > 3100)
+		printf("%s: Invalid RX delay value %d\n", __func__,
+		       sun8i_pdata->rx_delay_ps);
+
 #ifdef CONFIG_DM_GPIO
 	if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
 			    "snps,reset-active-low"))
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index bc33126..9bd79b1 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -86,15 +86,24 @@
 /* Set with binary 00011000 to use 1536 byte(1*max length frame/buffer) */
 #define ZYNQ_GEM_DMACR_RXBUF		0x00180000
 
+#if defined(CONFIG_PHYS_64BIT)
+# define ZYNQ_GEM_DMA_BUS_WIDTH		BIT(30) /* 64 bit bus */
+#else
+# define ZYNQ_GEM_DMA_BUS_WIDTH		(0 << 30) /* 32 bit bus */
+#endif
+
 #define ZYNQ_GEM_DMACR_INIT		(ZYNQ_GEM_DMACR_BLENGTH | \
 					ZYNQ_GEM_DMACR_RXSIZE | \
 					ZYNQ_GEM_DMACR_TXSIZE | \
-					ZYNQ_GEM_DMACR_RXBUF)
+					ZYNQ_GEM_DMACR_RXBUF | \
+					ZYNQ_GEM_DMA_BUS_WIDTH)
 
 #define ZYNQ_GEM_TSR_DONE		0x00000020 /* Tx done mask */
 
 #define ZYNQ_GEM_PCS_CTL_ANEG_ENBL	0x1000
 
+#define ZYNQ_GEM_DCFG_DBG6_DMA_64B	BIT(23)
+
 /* Use MII register 1 (MII status register) to detect PHY */
 #define PHY_DETECT_REG  1
 
@@ -143,16 +152,26 @@
 	u32 stat[STAT_SIZE]; /* 0x100 - Octects transmitted Low reg */
 	u32 reserved9[20];
 	u32 pcscntrl;
-	u32 reserved7[143];
+	u32 rserved12[36];
+	u32 dcfg6; /* 0x294 Design config reg6 */
+	u32 reserved7[106];
 	u32 transmit_q1_ptr; /* 0x440 - Transmit priority queue 1 */
 	u32 reserved8[15];
 	u32 receive_q1_ptr; /* 0x480 - Receive priority queue 1 */
+	u32 reserved10[17];
+	u32 upper_txqbase; /* 0x4C8 - Upper tx_q base addr */
+	u32 reserved11[2];
+	u32 upper_rxqbase; /* 0x4D4 - Upper rx_q base addr */
 };
 
 /* BD descriptors */
 struct emac_bd {
 	u32 addr; /* Next descriptor pointer */
 	u32 status;
+#if defined(CONFIG_PHYS_64BIT)
+	u32 addr_hi;
+	u32 reserved;
+#endif
 };
 
 #define RX_BUF 32
@@ -183,6 +202,7 @@
 	struct clk clk;
 	u32 max_speed;
 	bool int_pcs;
+	bool dma_64bit;
 };
 
 static int phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum,
@@ -363,6 +383,23 @@
 	struct emac_bd *dummy_tx_bd = &priv->tx_bd[TX_FREE_DESC];
 	struct emac_bd *dummy_rx_bd = &priv->tx_bd[TX_FREE_DESC + 2];
 
+	if (readl(&regs->dcfg6) & ZYNQ_GEM_DCFG_DBG6_DMA_64B)
+		priv->dma_64bit = true;
+	else
+		priv->dma_64bit = false;
+
+#if defined(CONFIG_PHYS_64BIT)
+	if (!priv->dma_64bit) {
+		printf("ERR: %s: Using 64-bit DMA but HW doesn't support it\n",
+		       __func__);
+		return -EINVAL;
+	}
+#else
+	if (priv->dma_64bit)
+		debug("WARN: %s: Not using 64-bit dma even HW supports it\n",
+		      __func__);
+#endif
+
 	if (!priv->init) {
 		/* Disable all interrupts */
 		writel(0xFFFFFFFF, &regs->idr);
@@ -390,13 +427,21 @@
 		for (i = 0; i < RX_BUF; i++) {
 			priv->rx_bd[i].status = 0xF0000000;
 			priv->rx_bd[i].addr =
-					((ulong)(priv->rxbuffers) +
-							(i * PKTSIZE_ALIGN));
-		}
+					(lower_32_bits((ulong)(priv->rxbuffers)
+							+ (i * PKTSIZE_ALIGN)));
+#if defined(CONFIG_PHYS_64BIT)
+			priv->rx_bd[i].addr_hi =
+					(upper_32_bits((ulong)(priv->rxbuffers)
+							+ (i * PKTSIZE_ALIGN)));
+#endif
+	}
 		/* WRAP bit to last BD */
 		priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
 		/* Write RxBDs to IP */
-		writel((ulong)priv->rx_bd, &regs->rxqbase);
+		writel(lower_32_bits((ulong)priv->rx_bd), &regs->rxqbase);
+#if defined(CONFIG_PHYS_64BIT)
+		writel(upper_32_bits((ulong)priv->rx_bd), &regs->upper_rxqbase);
+#endif
 
 		/* Setup for DMA Configuration register */
 		writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);
@@ -406,12 +451,18 @@
 
 		/* Disable the second priority queue */
 		dummy_tx_bd->addr = 0;
+#if defined(CONFIG_PHYS_64BIT)
+		dummy_tx_bd->addr_hi = 0;
+#endif
 		dummy_tx_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
 				ZYNQ_GEM_TXBUF_LAST_MASK|
 				ZYNQ_GEM_TXBUF_USED_MASK;
 
 		dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK |
 				ZYNQ_GEM_RXBUF_NEW_MASK;
+#if defined(CONFIG_PHYS_64BIT)
+		dummy_rx_bd->addr_hi = 0;
+#endif
 		dummy_rx_bd->status = 0;
 
 		writel((ulong)dummy_tx_bd, &regs->transmit_q1_ptr);
@@ -485,7 +536,8 @@
 
 static int zynq_gem_send(struct udevice *dev, void *ptr, int len)
 {
-	u32 addr, size;
+	dma_addr_t addr;
+	u32 size;
 	struct zynq_gem_priv *priv = dev_get_priv(dev);
 	struct zynq_gem_regs *regs = priv->iobase;
 	struct emac_bd *current_bd = &priv->tx_bd[1];
@@ -493,17 +545,26 @@
 	/* Setup Tx BD */
 	memset(priv->tx_bd, 0, sizeof(struct emac_bd));
 
-	priv->tx_bd->addr = (ulong)ptr;
+	priv->tx_bd->addr = lower_32_bits((ulong)ptr);
+#if defined(CONFIG_PHYS_64BIT)
+	priv->tx_bd->addr_hi = upper_32_bits((ulong)ptr);
+#endif
 	priv->tx_bd->status = (len & ZYNQ_GEM_TXBUF_FRMLEN_MASK) |
 			       ZYNQ_GEM_TXBUF_LAST_MASK;
 	/* Dummy descriptor to mark it as the last in descriptor chain */
 	current_bd->addr = 0x0;
+#if defined(CONFIG_PHYS_64BIT)
+	current_bd->addr_hi = 0x0;
+#endif
 	current_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
 			     ZYNQ_GEM_TXBUF_LAST_MASK|
 			     ZYNQ_GEM_TXBUF_USED_MASK;
 
 	/* setup BD */
-	writel((ulong)priv->tx_bd, &regs->txqbase);
+	writel(lower_32_bits((ulong)priv->tx_bd), &regs->txqbase);
+#if defined(CONFIG_PHYS_64BIT)
+	writel(upper_32_bits((ulong)priv->tx_bd), &regs->upper_txqbase);
+#endif
 
 	addr = (ulong) ptr;
 	addr &= ~(ARCH_DMA_MINALIGN - 1);
@@ -531,7 +592,7 @@
 static int zynq_gem_recv(struct udevice *dev, int flags, uchar **packetp)
 {
 	int frame_len;
-	u32 addr;
+	dma_addr_t addr;
 	struct zynq_gem_priv *priv = dev_get_priv(dev);
 	struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current];
 
@@ -550,8 +611,14 @@
 		return -1;
 	}
 
+#if defined(CONFIG_PHYS_64BIT)
+	addr = (dma_addr_t)((current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK)
+		      | ((dma_addr_t)current_bd->addr_hi << 32));
+#else
 	addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK;
+#endif
 	addr &= ~(ARCH_DMA_MINALIGN - 1);
+
 	*packetp = (uchar *)(uintptr_t)addr;
 
 	return frame_len;
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 0c52337..2cf55cb 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -774,16 +774,19 @@
 			found_multi = false;
 		if (PCI_FUNC(bdf) && !found_multi)
 			continue;
+
 		/* Check only the first access, we don't expect problems */
-		ret = pci_bus_read_config(bus, bdf, PCI_HEADER_TYPE,
-					  &header_type, PCI_SIZE_8);
+		ret = pci_bus_read_config(bus, bdf, PCI_VENDOR_ID, &vendor,
+					  PCI_SIZE_16);
 		if (ret)
 			goto error;
-		pci_bus_read_config(bus, bdf, PCI_VENDOR_ID, &vendor,
-				    PCI_SIZE_16);
+
 		if (vendor == 0xffff || vendor == 0x0000)
 			continue;
 
+		pci_bus_read_config(bus, bdf, PCI_HEADER_TYPE,
+				    &header_type, PCI_SIZE_8);
+
 		if (!PCI_FUNC(bdf))
 			found_multi = header_type & 0x80;
 
diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c
index eaacd40..7d9b75c 100644
--- a/drivers/pci/pci_rom.c
+++ b/drivers/pci/pci_rom.c
@@ -331,6 +331,7 @@
 		return log_msg_ret("No x resolution", -ENXIO);
 	uc_priv->xsize = vesa->x_resolution;
 	uc_priv->ysize = vesa->y_resolution;
+	uc_priv->line_length = vesa->bytes_per_scanline;
 	switch (vesa->bits_per_pixel) {
 	case 32:
 	case 24:
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index ad0b8da..7e6fad3 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -301,6 +301,7 @@
 endif
 
 source "drivers/pinctrl/meson/Kconfig"
+source "drivers/pinctrl/mediatek/Kconfig"
 source "drivers/pinctrl/nxp/Kconfig"
 source "drivers/pinctrl/renesas/Kconfig"
 source "drivers/pinctrl/uniphier/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index a3a6c6d..293bad3 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -16,6 +16,7 @@
 obj-$(CONFIG_PINCTRL_PIC32)	+= pinctrl_pic32.o
 obj-$(CONFIG_PINCTRL_EXYNOS)	+= exynos/
 obj-$(CONFIG_PINCTRL_MESON)	+= meson/
+obj-$(CONFIG_PINCTRL_MTK)	+= mediatek/
 obj-$(CONFIG_ARCH_MVEBU)	+= mvebu/
 obj-$(CONFIG_PINCTRL_SINGLE)	+= pinctrl-single.o
 obj-$(CONFIG_PINCTRL_STI)	+= pinctrl-sti.o
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
new file mode 100644
index 0000000..1bd9a92
--- /dev/null
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -0,0 +1,15 @@
+if ARCH_MEDIATEK
+
+config PINCTRL_MTK
+	depends on PINCTRL_GENERIC
+	bool
+
+config PINCTRL_MT7623
+	bool "MT7623 SoC pinctrl driver"
+	select PINCTRL_MTK
+
+config PINCTRL_MT7629
+	bool "MT7629 SoC pinctrl driver"
+	select PINCTRL_MTK
+
+endif
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
new file mode 100644
index 0000000..f6ef362
--- /dev/null
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+# Core
+obj-$(CONFIG_PINCTRL_MTK) += pinctrl-mtk-common.o
+
+# SoC Drivers
+obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o
+obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7623.c b/drivers/pinctrl/mediatek/pinctrl-mt7623.c
new file mode 100644
index 0000000..fd37dfa
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7623.c
@@ -0,0 +1,1284 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <dm.h>
+
+#include "pinctrl-mtk-common.h"
+
+#define PIN_BOND_REG0		0xb10
+#define PIN_BOND_REG1		0xf20
+#define PIN_BOND_REG2		0xef0
+#define BOND_PCIE_CLR		(0x77 << 3)
+#define BOND_I2S_CLR		0x3
+#define BOND_MSDC0E_CLR		0x1
+
+#define PIN_FIELD15(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits)	\
+	PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit,	\
+		       _x_bits, 15, false)
+
+#define PIN_FIELD16(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits)	\
+	PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit,	\
+		       _x_bits, 16, false)
+
+#define PINS_FIELD16(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits)\
+	PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit,	\
+		       _x_bits, 16, true)
+
+static const struct mtk_pin_field_calc mt7623_pin_mode_range[] = {
+	PIN_FIELD15(0, 278, 0x760, 0x10, 0, 3),
+};
+
+static const struct mtk_pin_field_calc mt7623_pin_dir_range[] = {
+	PIN_FIELD16(0, 175, 0x0, 0x10, 0, 1),
+	PIN_FIELD16(176, 278, 0xc0, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7623_pin_di_range[] = {
+	PIN_FIELD16(0, 278, 0x630, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7623_pin_do_range[] = {
+	PIN_FIELD16(0, 278, 0x500, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7623_pin_ies_range[] = {
+	PINS_FIELD16(0, 6, 0xb20, 0x10, 0, 1),
+	PINS_FIELD16(7, 9, 0xb20, 0x10, 1, 1),
+	PINS_FIELD16(10, 13, 0xb30, 0x10, 3, 1),
+	PINS_FIELD16(14, 15, 0xb30, 0x10, 13, 1),
+	PINS_FIELD16(16, 17, 0xb40, 0x10, 7, 1),
+	PINS_FIELD16(18, 29, 0xb40, 0x10, 13, 1),
+	PINS_FIELD16(30, 32, 0xb40, 0x10, 7, 1),
+	PINS_FIELD16(33, 37, 0xb40, 0x10, 13, 1),
+	PIN_FIELD16(38, 38, 0xb20, 0x10, 13, 1),
+	PINS_FIELD16(39, 42, 0xb40, 0x10, 13, 1),
+	PINS_FIELD16(43, 45, 0xb20, 0x10, 10, 1),
+	PINS_FIELD16(47, 48, 0xb20, 0x10, 11, 1),
+	PIN_FIELD16(49, 49, 0xb20, 0x10, 12, 1),
+	PINS_FIELD16(50, 52, 0xb20, 0x10, 13, 1),
+	PINS_FIELD16(53, 56, 0xb20, 0x10, 14, 1),
+	PINS_FIELD16(57, 58, 0xb20, 0x10, 15, 1),
+	PIN_FIELD16(59, 59, 0xb30, 0x10, 10, 1),
+	PINS_FIELD16(60, 62, 0xb30, 0x10, 0, 1),
+	PINS_FIELD16(63, 65, 0xb30, 0x10, 1, 1),
+	PINS_FIELD16(66, 71, 0xb30, 0x10, 2, 1),
+	PINS_FIELD16(72, 74, 0xb20, 0x10, 12, 1),
+	PINS_FIELD16(75, 76, 0xb30, 0x10, 3, 1),
+	PINS_FIELD16(77, 78, 0xb30, 0x10, 4, 1),
+	PINS_FIELD16(79, 82, 0xb30, 0x10, 5, 1),
+	PINS_FIELD16(83, 84, 0xb30, 0x10, 2, 1),
+	PIN_FIELD16(85, 85, 0xda0, 0x10, 4, 1),
+	PIN_FIELD16(86, 86, 0xd90, 0x10, 4, 1),
+	PINS_FIELD16(87, 90, 0xdb0, 0x10, 4, 1),
+	PINS_FIELD16(101, 104, 0xb30, 0x10, 6, 1),
+	PIN_FIELD16(105, 105, 0xd40, 0x10, 4, 1),
+	PIN_FIELD16(106, 106, 0xd30, 0x10, 4, 1),
+	PINS_FIELD16(107, 110, 0xd50, 0x10, 4, 1),
+	PINS_FIELD16(111, 115, 0xce0, 0x10, 4, 1),
+	PIN_FIELD16(116, 116, 0xcd0, 0x10, 4, 1),
+	PIN_FIELD16(117, 117, 0xcc0, 0x10, 4, 1),
+	PINS_FIELD16(118, 121, 0xce0, 0x10, 4, 1),
+	PINS_FIELD16(122, 125, 0xb30, 0x10, 7, 1),
+	PIN_FIELD16(126, 126, 0xb20, 0x10, 12, 1),
+	PINS_FIELD16(127, 142, 0xb30, 0x10, 9, 1),
+	PINS_FIELD16(143, 160, 0xb30, 0x10, 10, 1),
+	PINS_FIELD16(161, 168, 0xb30, 0x10, 12, 1),
+	PINS_FIELD16(169, 183, 0xb30, 0x10, 10, 1),
+	PINS_FIELD16(184, 186, 0xb30, 0x10, 9, 1),
+	PIN_FIELD16(187, 187, 0xb30, 0x10, 14, 1),
+	PIN_FIELD16(188, 188, 0xb20, 0x10, 13, 1),
+	PINS_FIELD16(189, 193, 0xb30, 0x10, 15, 1),
+	PINS_FIELD16(194, 198, 0xb40, 0x10, 0, 1),
+	PIN_FIELD16(199, 199, 0xb20, 0x10, 1, 1),
+	PINS_FIELD16(200, 202, 0xb40, 0x10, 1, 1),
+	PINS_FIELD16(203, 207, 0xb40, 0x10, 2, 1),
+	PINS_FIELD16(208, 209, 0xb40, 0x10, 3, 1),
+	PIN_FIELD16(210, 210, 0xb40, 0x10, 4, 1),
+	PINS_FIELD16(211, 235, 0xb40, 0x10, 5, 1),
+	PINS_FIELD16(236, 241, 0xb40, 0x10, 6, 1),
+	PINS_FIELD16(242, 243, 0xb40, 0x10, 7, 1),
+	PINS_FIELD16(244, 247, 0xb40, 0x10, 8, 1),
+	PIN_FIELD16(248, 248, 0xb40, 0x10, 9, 1),
+	PINS_FIELD16(249, 257, 0xfc0, 0x10, 4, 1),
+	PIN_FIELD16(258, 258, 0xcb0, 0x10, 4, 1),
+	PIN_FIELD16(259, 259, 0xc90, 0x10, 4, 1),
+	PIN_FIELD16(260, 260, 0x3a0, 0x10, 4, 1),
+	PIN_FIELD16(261, 261, 0xd50, 0x10, 4, 1),
+	PINS_FIELD16(262, 277, 0xb40, 0x10, 12, 1),
+	PIN_FIELD16(278, 278, 0xb40, 0x10, 13, 1),
+};
+
+static const struct mtk_pin_field_calc mt7623_pin_smt_range[] = {
+	PINS_FIELD16(0, 6, 0xb50, 0x10, 0, 1),
+	PINS_FIELD16(7, 9, 0xb50, 0x10, 1, 1),
+	PINS_FIELD16(10, 13, 0xb60, 0x10, 3, 1),
+	PINS_FIELD16(14, 15, 0xb60, 0x10, 13, 1),
+	PINS_FIELD16(16, 17, 0xb70, 0x10, 7, 1),
+	PINS_FIELD16(18, 29, 0xb70, 0x10, 13, 1),
+	PINS_FIELD16(30, 32, 0xb70, 0x10, 7, 1),
+	PINS_FIELD16(33, 37, 0xb70, 0x10, 13, 1),
+	PIN_FIELD16(38, 38, 0xb50, 0x10, 13, 1),
+	PINS_FIELD16(39, 42, 0xb70, 0x10, 13, 1),
+	PINS_FIELD16(43, 45, 0xb50, 0x10, 10, 1),
+	PINS_FIELD16(47, 48, 0xb50, 0x10, 11, 1),
+	PIN_FIELD16(49, 49, 0xb50, 0x10, 12, 1),
+	PINS_FIELD16(50, 52, 0xb50, 0x10, 13, 1),
+	PINS_FIELD16(53, 56, 0xb50, 0x10, 14, 1),
+	PINS_FIELD16(57, 58, 0xb50, 0x10, 15, 1),
+	PIN_FIELD16(59, 59, 0xb60, 0x10, 10, 1),
+	PINS_FIELD16(60, 62, 0xb60, 0x10, 0, 1),
+	PINS_FIELD16(63, 65, 0xb60, 0x10, 1, 1),
+	PINS_FIELD16(66, 71, 0xb60, 0x10, 2, 1),
+	PINS_FIELD16(72, 74, 0xb50, 0x10, 12, 1),
+	PINS_FIELD16(75, 76, 0xb60, 0x10, 3, 1),
+	PINS_FIELD16(77, 78, 0xb60, 0x10, 4, 1),
+	PINS_FIELD16(79, 82, 0xb60, 0x10, 5, 1),
+	PINS_FIELD16(83, 84, 0xb60, 0x10, 2, 1),
+	PIN_FIELD16(85, 85, 0xda0, 0x10, 11, 1),
+	PIN_FIELD16(86, 86, 0xd90, 0x10, 11, 1),
+	PIN_FIELD16(87, 87, 0xdc0, 0x10, 3, 1),
+	PIN_FIELD16(88, 88, 0xdc0, 0x10, 7, 1),
+	PIN_FIELD16(89, 89, 0xdc0, 0x10, 11, 1),
+	PIN_FIELD16(90, 90, 0xdc0, 0x10, 15, 1),
+	PINS_FIELD16(101, 104, 0xb60, 0x10, 6, 1),
+	PIN_FIELD16(105, 105, 0xd40, 0x10, 11, 1),
+	PIN_FIELD16(106, 106, 0xd30, 0x10, 11, 1),
+	PIN_FIELD16(107, 107, 0xd60, 0x10, 3, 1),
+	PIN_FIELD16(108, 108, 0xd60, 0x10, 7, 1),
+	PIN_FIELD16(109, 109, 0xd60, 0x10, 11, 1),
+	PIN_FIELD16(110, 110, 0xd60, 0x10, 15, 1),
+	PIN_FIELD16(111, 111, 0xd00, 0x10, 15, 1),
+	PIN_FIELD16(112, 112, 0xd00, 0x10, 11, 1),
+	PIN_FIELD16(113, 113, 0xd00, 0x10, 7, 1),
+	PIN_FIELD16(114, 114, 0xd00, 0x10, 3, 1),
+	PIN_FIELD16(115, 115, 0xd10, 0x10, 3, 1),
+	PIN_FIELD16(116, 116, 0xcd0, 0x10, 11, 1),
+	PIN_FIELD16(117, 117, 0xcc0, 0x10, 11, 1),
+	PIN_FIELD16(118, 118, 0xcf0, 0x10, 15, 1),
+	PIN_FIELD16(119, 119, 0xcf0, 0x10, 7, 1),
+	PIN_FIELD16(120, 120, 0xcf0, 0x10, 3, 1),
+	PIN_FIELD16(121, 121, 0xcf0, 0x10, 7, 1),
+	PINS_FIELD16(122, 125, 0xb60, 0x10, 7, 1),
+	PIN_FIELD16(126, 126, 0xb50, 0x10, 12, 1),
+	PINS_FIELD16(127, 142, 0xb60, 0x10, 9, 1),
+	PINS_FIELD16(143, 160, 0xb60, 0x10, 10, 1),
+	PINS_FIELD16(161, 168, 0xb60, 0x10, 12, 1),
+	PINS_FIELD16(169, 183, 0xb60, 0x10, 10, 1),
+	PINS_FIELD16(184, 186, 0xb60, 0x10, 9, 1),
+	PIN_FIELD16(187, 187, 0xb60, 0x10, 14, 1),
+	PIN_FIELD16(188, 188, 0xb50, 0x10, 13, 1),
+	PINS_FIELD16(189, 193, 0xb60, 0x10, 15, 1),
+	PINS_FIELD16(194, 198, 0xb70, 0x10, 0, 1),
+	PIN_FIELD16(199, 199, 0xb50, 0x10, 1, 1),
+	PINS_FIELD16(200, 202, 0xb70, 0x10, 1, 1),
+	PINS_FIELD16(203, 207, 0xb70, 0x10, 2, 1),
+	PINS_FIELD16(208, 209, 0xb70, 0x10, 3, 1),
+	PIN_FIELD16(210, 210, 0xb70, 0x10, 4, 1),
+	PINS_FIELD16(211, 235, 0xb70, 0x10, 5, 1),
+	PINS_FIELD16(236, 241, 0xb70, 0x10, 6, 1),
+	PINS_FIELD16(242, 243, 0xb70, 0x10, 7, 1),
+	PINS_FIELD16(244, 247, 0xb70, 0x10, 8, 1),
+	PIN_FIELD16(248, 248, 0xb70, 0x10, 9, 10),
+	PIN_FIELD16(249, 249, 0x140, 0x10, 3, 1),
+	PIN_FIELD16(250, 250, 0x130, 0x10, 15, 1),
+	PIN_FIELD16(251, 251, 0x130, 0x10, 11, 1),
+	PIN_FIELD16(252, 252, 0x130, 0x10, 7, 1),
+	PIN_FIELD16(253, 253, 0x130, 0x10, 3, 1),
+	PIN_FIELD16(254, 254, 0xf40, 0x10, 15, 1),
+	PIN_FIELD16(255, 255, 0xf40, 0x10, 11, 1),
+	PIN_FIELD16(256, 256, 0xf40, 0x10, 7, 1),
+	PIN_FIELD16(257, 257, 0xf40, 0x10, 3, 1),
+	PIN_FIELD16(258, 258, 0xcb0, 0x10, 11, 1),
+	PIN_FIELD16(259, 259, 0xc90, 0x10, 11, 1),
+	PIN_FIELD16(260, 260, 0x3a0, 0x10, 11, 1),
+	PIN_FIELD16(261, 261, 0x0b0, 0x10, 3, 1),
+	PINS_FIELD16(262, 277, 0xb70, 0x10, 12, 1),
+	PIN_FIELD16(278, 278, 0xb70, 0x10, 13, 1),
+};
+
+static const struct mtk_pin_field_calc mt7623_pin_pullen_range[] = {
+	PIN_FIELD16(0, 278, 0x150, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7623_pin_pullsel_range[] = {
+	PIN_FIELD16(0, 278, 0x280, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7623_pin_drv_range[] = {
+	PINS_FIELD16(0, 6, 0xf50, 0x10, 0, 4),
+	PINS_FIELD16(7, 9, 0xf50, 0x10, 4, 4),
+	PINS_FIELD16(10, 13, 0xf50, 0x10, 4, 4),
+	PINS_FIELD16(14, 15, 0xf50, 0x10, 12, 4),
+	PINS_FIELD16(16, 17, 0xf60, 0x10, 0, 4),
+	PINS_FIELD16(18, 21, 0xf60, 0x10, 0, 4),
+	PINS_FIELD16(22, 26, 0xf60, 0x10, 8, 4),
+	PINS_FIELD16(27, 29, 0xf60, 0x10, 12, 4),
+	PINS_FIELD16(30, 32, 0xf60, 0x10, 0, 4),
+	PINS_FIELD16(33, 37, 0xf70, 0x10, 0, 4),
+	PIN_FIELD16(38, 38, 0xf70, 0x10, 4, 4),
+	PINS_FIELD16(39, 42, 0xf70, 0x10, 8, 4),
+	PINS_FIELD16(43, 45, 0xf70, 0x10, 12, 4),
+	PINS_FIELD16(47, 48, 0xf80, 0x10, 0, 4),
+	PIN_FIELD16(49, 49, 0xf80, 0x10, 4, 4),
+	PINS_FIELD16(50, 52, 0xf70, 0x10, 4, 4),
+	PINS_FIELD16(53, 56, 0xf80, 0x10, 12, 4),
+	PINS_FIELD16(60, 62, 0xf90, 0x10, 8, 4),
+	PINS_FIELD16(63, 65, 0xf90, 0x10, 12, 4),
+	PINS_FIELD16(66, 71, 0xfa0, 0x10, 0, 4),
+	PINS_FIELD16(72, 74, 0xf80, 0x10, 4, 4),
+	PIN_FIELD16(85, 85, 0xda0, 0x10, 0, 4),
+	PIN_FIELD16(86, 86, 0xd90, 0x10, 0, 4),
+	PINS_FIELD16(87, 90, 0xdb0, 0x10, 0, 4),
+	PIN_FIELD16(105, 105, 0xd40, 0x10, 0, 4),
+	PIN_FIELD16(106, 106, 0xd30, 0x10, 0, 4),
+	PINS_FIELD16(107, 110, 0xd50, 0x10, 0, 4),
+	PINS_FIELD16(111, 115, 0xce0, 0x10, 0, 4),
+	PIN_FIELD16(116, 116, 0xcd0, 0x10, 0, 4),
+	PIN_FIELD16(117, 117, 0xcc0, 0x10, 0, 4),
+	PINS_FIELD16(118, 121, 0xce0, 0x10, 0, 4),
+	PIN_FIELD16(126, 126, 0xf80, 0x10, 4, 4),
+	PIN_FIELD16(188, 188, 0xf70, 0x10, 4, 4),
+	PINS_FIELD16(189, 193, 0xfe0, 0x10, 8, 4),
+	PINS_FIELD16(194, 198, 0xfe0, 0x10, 12, 4),
+	PIN_FIELD16(199, 199, 0xf50, 0x10, 4, 4),
+	PINS_FIELD16(200, 202, 0xfd0, 0x10, 0, 4),
+	PINS_FIELD16(203, 207, 0xfd0, 0x10, 4, 4),
+	PINS_FIELD16(208, 209, 0xfd0, 0x10, 8, 4),
+	PIN_FIELD16(210, 210, 0xfd0, 0x10, 12, 4),
+	PINS_FIELD16(211, 235, 0xff0, 0x10, 0, 4),
+	PINS_FIELD16(236, 241, 0xff0, 0x10, 4, 4),
+	PINS_FIELD16(242, 243, 0xff0, 0x10, 8, 4),
+	PIN_FIELD16(248, 248, 0xf00, 0x10, 0, 4),
+	PINS_FIELD16(249, 256, 0xfc0, 0x10, 0, 4),
+	PIN_FIELD16(257, 257, 0xce0, 0x10, 0, 4),
+	PIN_FIELD16(258, 258, 0xcb0, 0x10, 0, 4),
+	PIN_FIELD16(259, 259, 0xc90, 0x10, 0, 4),
+	PIN_FIELD16(260, 260, 0x3a0, 0x10, 0, 4),
+	PIN_FIELD16(261, 261, 0xd50, 0x10, 0, 4),
+	PINS_FIELD16(262, 277, 0xf00, 0x10, 8, 4),
+	PIN_FIELD16(278, 278, 0xf70, 0x10, 8, 4),
+};
+
+static const struct mtk_pin_reg_calc mt7623_reg_cals[] = {
+	[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7623_pin_mode_range),
+	[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7623_pin_dir_range),
+	[PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7623_pin_di_range),
+	[PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7623_pin_do_range),
+	[PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7623_pin_ies_range),
+	[PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7623_pin_smt_range),
+	[PINCTRL_PIN_REG_PULLSEL] = MTK_RANGE(mt7623_pin_pullsel_range),
+	[PINCTRL_PIN_REG_PULLEN] = MTK_RANGE(mt7623_pin_pullen_range),
+	[PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7623_pin_drv_range),
+};
+
+static const struct mtk_pin_desc mt7623_pins[] = {
+	MTK_PIN(0, "PWRAP_SPI0_MI", DRV_GRP3),
+	MTK_PIN(1, "PWRAP_SPI0_MO", DRV_GRP3),
+	MTK_PIN(2, "PWRAP_INT", DRV_GRP3),
+	MTK_PIN(3, "PWRAP_SPI0_CK", DRV_GRP3),
+	MTK_PIN(4, "PWRAP_SPI0_CSN", DRV_GRP3),
+	MTK_PIN(5, "PWRAP_SPI0_CK2", DRV_GRP3),
+	MTK_PIN(6, "PWRAP_SPI0_CSN2", DRV_GRP3),
+	MTK_PIN(7, "SPI1_CSN", DRV_GRP3),
+	MTK_PIN(8, "SPI1_MI", DRV_GRP3),
+	MTK_PIN(9, "SPI1_MO", DRV_GRP3),
+	MTK_PIN(10, "RTC32K_CK", DRV_GRP3),
+	MTK_PIN(11, "WATCHDOG", DRV_GRP3),
+	MTK_PIN(12, "SRCLKENA", DRV_GRP3),
+	MTK_PIN(13, "SRCLKENAI", DRV_GRP3),
+	MTK_PIN(14, "URXD2", DRV_GRP1),
+	MTK_PIN(15, "UTXD2", DRV_GRP1),
+	MTK_PIN(16, "I2S5_DATA_IN", DRV_GRP1),
+	MTK_PIN(17, "I2S5_BCK", DRV_GRP1),
+	MTK_PIN(18, "PCM_CLK", DRV_GRP1),
+	MTK_PIN(19, "PCM_SYNC", DRV_GRP1),
+	MTK_PIN(20, "PCM_RX", DRV_GRP1),
+	MTK_PIN(21, "PCM_TX", DRV_GRP1),
+	MTK_PIN(22, "EINT0", DRV_GRP1),
+	MTK_PIN(23, "EINT1", DRV_GRP1),
+	MTK_PIN(24, "EINT2", DRV_GRP1),
+	MTK_PIN(25, "EINT3", DRV_GRP1),
+	MTK_PIN(26, "EINT4", DRV_GRP1),
+	MTK_PIN(27, "EINT5", DRV_GRP1),
+	MTK_PIN(28, "EINT6", DRV_GRP1),
+	MTK_PIN(29, "EINT7", DRV_GRP1),
+	MTK_PIN(30, "I2S5_LRCK", DRV_GRP1),
+	MTK_PIN(31, "I2S5_MCLK", DRV_GRP1),
+	MTK_PIN(32, "I2S5_DATA", DRV_GRP1),
+	MTK_PIN(33, "I2S1_DATA", DRV_GRP1),
+	MTK_PIN(34, "I2S1_DATA_IN", DRV_GRP1),
+	MTK_PIN(35, "I2S1_BCK", DRV_GRP1),
+	MTK_PIN(36, "I2S1_LRCK", DRV_GRP1),
+	MTK_PIN(37, "I2S1_MCLK", DRV_GRP1),
+	MTK_PIN(38, "I2S2_DATA", DRV_GRP1),
+	MTK_PIN(39, "JTMS", DRV_GRP3),
+	MTK_PIN(40, "JTCK", DRV_GRP3),
+	MTK_PIN(41, "JTDI", DRV_GRP3),
+	MTK_PIN(42, "JTDO", DRV_GRP3),
+	MTK_PIN(43, "NCLE", DRV_GRP1),
+	MTK_PIN(44, "NCEB1", DRV_GRP1),
+	MTK_PIN(45, "NCEB0", DRV_GRP1),
+	MTK_PIN(46, "IR", DRV_FIXED),
+	MTK_PIN(47, "NREB", DRV_GRP1),
+	MTK_PIN(48, "NRNB", DRV_GRP1),
+	MTK_PIN(49, "I2S0_DATA", DRV_GRP1),
+	MTK_PIN(50, "I2S2_BCK", DRV_GRP1),
+	MTK_PIN(51, "I2S2_DATA_IN", DRV_GRP1),
+	MTK_PIN(52, "I2S2_LRCK", DRV_GRP1),
+	MTK_PIN(53, "SPI0_CSN", DRV_GRP1),
+	MTK_PIN(54, "SPI0_CK", DRV_GRP1),
+	MTK_PIN(55, "SPI0_MI", DRV_GRP1),
+	MTK_PIN(56, "SPI0_MO", DRV_GRP1),
+	MTK_PIN(57, "SDA1", DRV_FIXED),
+	MTK_PIN(58, "SCL1", DRV_FIXED),
+	MTK_PIN(59, "RAMBUF_I_CLK", DRV_FIXED),
+	MTK_PIN(60, "WB_RSTB", DRV_GRP3),
+	MTK_PIN(61, "F2W_DATA", DRV_GRP3),
+	MTK_PIN(62, "F2W_CLK", DRV_GRP3),
+	MTK_PIN(63, "WB_SCLK", DRV_GRP3),
+	MTK_PIN(64, "WB_SDATA", DRV_GRP3),
+	MTK_PIN(65, "WB_SEN", DRV_GRP3),
+	MTK_PIN(66, "WB_CRTL0", DRV_GRP3),
+	MTK_PIN(67, "WB_CRTL1", DRV_GRP3),
+	MTK_PIN(68, "WB_CRTL2", DRV_GRP3),
+	MTK_PIN(69, "WB_CRTL3", DRV_GRP3),
+	MTK_PIN(70, "WB_CRTL4", DRV_GRP3),
+	MTK_PIN(71, "WB_CRTL5", DRV_GRP3),
+	MTK_PIN(72, "I2S0_DATA_IN", DRV_GRP1),
+	MTK_PIN(73, "I2S0_LRCK", DRV_GRP1),
+	MTK_PIN(74, "I2S0_BCK", DRV_GRP1),
+	MTK_PIN(75, "SDA0", DRV_FIXED),
+	MTK_PIN(76, "SCL0", DRV_FIXED),
+	MTK_PIN(77, "SDA2", DRV_FIXED),
+	MTK_PIN(78, "SCL2", DRV_FIXED),
+	MTK_PIN(79, "URXD0", DRV_FIXED),
+	MTK_PIN(80, "UTXD0", DRV_FIXED),
+	MTK_PIN(81, "URXD1", DRV_FIXED),
+	MTK_PIN(82, "UTXD1", DRV_FIXED),
+	MTK_PIN(83, "LCM_RST", DRV_FIXED),
+	MTK_PIN(84, "DSI_TE", DRV_FIXED),
+	MTK_PIN(85, "MSDC2_CMD", DRV_GRP4),
+	MTK_PIN(86, "MSDC2_CLK", DRV_GRP4),
+	MTK_PIN(87, "MSDC2_DAT0", DRV_GRP4),
+	MTK_PIN(88, "MSDC2_DAT1", DRV_GRP4),
+	MTK_PIN(89, "MSDC2_DAT2", DRV_GRP4),
+	MTK_PIN(90, "MSDC2_DAT3", DRV_GRP4),
+	MTK_PIN(91, "TDN3", DRV_FIXED),
+	MTK_PIN(92, "TDP3", DRV_FIXED),
+	MTK_PIN(93, "TDN2", DRV_FIXED),
+	MTK_PIN(94, "TDP2", DRV_FIXED),
+	MTK_PIN(95, "TCN", DRV_FIXED),
+	MTK_PIN(96, "TCP", DRV_FIXED),
+	MTK_PIN(97, "TDN1", DRV_FIXED),
+	MTK_PIN(98, "TDP1", DRV_FIXED),
+	MTK_PIN(99, "TDN0", DRV_FIXED),
+	MTK_PIN(100, "TDP0", DRV_FIXED),
+	MTK_PIN(101, "SPI2_CSN", DRV_FIXED),
+	MTK_PIN(102, "SPI2_MI", DRV_FIXED),
+	MTK_PIN(103, "SPI2_MO", DRV_FIXED),
+	MTK_PIN(104, "SPI2_CLK", DRV_FIXED),
+	MTK_PIN(105, "MSDC1_CMD", DRV_GRP4),
+	MTK_PIN(106, "MSDC1_CLK", DRV_GRP4),
+	MTK_PIN(107, "MSDC1_DAT0", DRV_GRP4),
+	MTK_PIN(108, "MSDC1_DAT1", DRV_GRP4),
+	MTK_PIN(109, "MSDC1_DAT2", DRV_GRP4),
+	MTK_PIN(110, "MSDC1_DAT3", DRV_GRP4),
+	MTK_PIN(111, "MSDC0_DAT7", DRV_GRP4),
+	MTK_PIN(112, "MSDC0_DAT6", DRV_GRP4),
+	MTK_PIN(113, "MSDC0_DAT5", DRV_GRP4),
+	MTK_PIN(114, "MSDC0_DAT4", DRV_GRP4),
+	MTK_PIN(115, "MSDC0_RSTB", DRV_GRP4),
+	MTK_PIN(116, "MSDC0_CMD", DRV_GRP4),
+	MTK_PIN(117, "MSDC0_CLK", DRV_GRP4),
+	MTK_PIN(118, "MSDC0_DAT3", DRV_GRP4),
+	MTK_PIN(119, "MSDC0_DAT2", DRV_GRP4),
+	MTK_PIN(120, "MSDC0_DAT1", DRV_GRP4),
+	MTK_PIN(121, "MSDC0_DAT0", DRV_GRP4),
+	MTK_PIN(122, "CEC", DRV_FIXED),
+	MTK_PIN(123, "HTPLG", DRV_FIXED),
+	MTK_PIN(124, "HDMISCK", DRV_FIXED),
+	MTK_PIN(125, "HDMISD", DRV_FIXED),
+	MTK_PIN(126, "I2S0_MCLK", DRV_GRP1),
+	MTK_PIN(127, "RAMBUF_IDATA0", DRV_FIXED),
+	MTK_PIN(128, "RAMBUF_IDATA1", DRV_FIXED),
+	MTK_PIN(129, "RAMBUF_IDATA2", DRV_FIXED),
+	MTK_PIN(130, "RAMBUF_IDATA3", DRV_FIXED),
+	MTK_PIN(131, "RAMBUF_IDATA4", DRV_FIXED),
+	MTK_PIN(132, "RAMBUF_IDATA5", DRV_FIXED),
+	MTK_PIN(133, "RAMBUF_IDATA6", DRV_FIXED),
+	MTK_PIN(134, "RAMBUF_IDATA7", DRV_FIXED),
+	MTK_PIN(135, "RAMBUF_IDATA8", DRV_FIXED),
+	MTK_PIN(136, "RAMBUF_IDATA9", DRV_FIXED),
+	MTK_PIN(137, "RAMBUF_IDATA10", DRV_FIXED),
+	MTK_PIN(138, "RAMBUF_IDATA11", DRV_FIXED),
+	MTK_PIN(139, "RAMBUF_IDATA12", DRV_FIXED),
+	MTK_PIN(140, "RAMBUF_IDATA13", DRV_FIXED),
+	MTK_PIN(141, "RAMBUF_IDATA14", DRV_FIXED),
+	MTK_PIN(142, "RAMBUF_IDATA15", DRV_FIXED),
+	MTK_PIN(143, "RAMBUF_ODATA0", DRV_FIXED),
+	MTK_PIN(144, "RAMBUF_ODATA1", DRV_FIXED),
+	MTK_PIN(145, "RAMBUF_ODATA2", DRV_FIXED),
+	MTK_PIN(146, "RAMBUF_ODATA3", DRV_FIXED),
+	MTK_PIN(147, "RAMBUF_ODATA4", DRV_FIXED),
+	MTK_PIN(148, "RAMBUF_ODATA5", DRV_FIXED),
+	MTK_PIN(149, "RAMBUF_ODATA6", DRV_FIXED),
+	MTK_PIN(150, "RAMBUF_ODATA7", DRV_FIXED),
+	MTK_PIN(151, "RAMBUF_ODATA8", DRV_FIXED),
+	MTK_PIN(152, "RAMBUF_ODATA9", DRV_FIXED),
+	MTK_PIN(153, "RAMBUF_ODATA10", DRV_FIXED),
+	MTK_PIN(154, "RAMBUF_ODATA11", DRV_FIXED),
+	MTK_PIN(155, "RAMBUF_ODATA12", DRV_FIXED),
+	MTK_PIN(156, "RAMBUF_ODATA13", DRV_FIXED),
+	MTK_PIN(157, "RAMBUF_ODATA14", DRV_FIXED),
+	MTK_PIN(158, "RAMBUF_ODATA15", DRV_FIXED),
+	MTK_PIN(159, "RAMBUF_BE0", DRV_FIXED),
+	MTK_PIN(160, "RAMBUF_BE1", DRV_FIXED),
+	MTK_PIN(161, "AP2PT_INT", DRV_FIXED),
+	MTK_PIN(162, "AP2PT_INT_CLR", DRV_FIXED),
+	MTK_PIN(163, "PT2AP_INT", DRV_FIXED),
+	MTK_PIN(164, "PT2AP_INT_CLR", DRV_FIXED),
+	MTK_PIN(165, "AP2UP_INT", DRV_FIXED),
+	MTK_PIN(166, "AP2UP_INT_CLR", DRV_FIXED),
+	MTK_PIN(167, "UP2AP_INT", DRV_FIXED),
+	MTK_PIN(168, "UP2AP_INT_CLR", DRV_FIXED),
+	MTK_PIN(169, "RAMBUF_ADDR0", DRV_FIXED),
+	MTK_PIN(170, "RAMBUF_ADDR1", DRV_FIXED),
+	MTK_PIN(171, "RAMBUF_ADDR2", DRV_FIXED),
+	MTK_PIN(172, "RAMBUF_ADDR3", DRV_FIXED),
+	MTK_PIN(173, "RAMBUF_ADDR4", DRV_FIXED),
+	MTK_PIN(174, "RAMBUF_ADDR5", DRV_FIXED),
+	MTK_PIN(175, "RAMBUF_ADDR6", DRV_FIXED),
+	MTK_PIN(176, "RAMBUF_ADDR7", DRV_FIXED),
+	MTK_PIN(177, "RAMBUF_ADDR8", DRV_FIXED),
+	MTK_PIN(178, "RAMBUF_ADDR9", DRV_FIXED),
+	MTK_PIN(179, "RAMBUF_ADDR10", DRV_FIXED),
+	MTK_PIN(180, "RAMBUF_RW", DRV_FIXED),
+	MTK_PIN(181, "RAMBUF_LAST", DRV_FIXED),
+	MTK_PIN(182, "RAMBUF_HP", DRV_FIXED),
+	MTK_PIN(183, "RAMBUF_REQ", DRV_FIXED),
+	MTK_PIN(184, "RAMBUF_ALE", DRV_FIXED),
+	MTK_PIN(185, "RAMBUF_DLE", DRV_FIXED),
+	MTK_PIN(186, "RAMBUF_WDLE", DRV_FIXED),
+	MTK_PIN(187, "RAMBUF_O_CLK", DRV_FIXED),
+	MTK_PIN(188, "I2S2_MCLK", DRV_GRP1),
+	MTK_PIN(189, "I2S3_DATA", DRV_GRP1),
+	MTK_PIN(190, "I2S3_DATA_IN", DRV_GRP1),
+	MTK_PIN(191, "I2S3_BCK", DRV_GRP1),
+	MTK_PIN(192, "I2S3_LRCK", DRV_GRP1),
+	MTK_PIN(193, "I2S3_MCLK", DRV_GRP1),
+	MTK_PIN(194, "I2S4_DATA", DRV_GRP1),
+	MTK_PIN(195, "I2S4_DATA_IN", DRV_GRP1),
+	MTK_PIN(196, "I2S4_BCK", DRV_GRP1),
+	MTK_PIN(197, "I2S4_LRCK", DRV_GRP1),
+	MTK_PIN(198, "I2S4_MCLK", DRV_GRP1),
+	MTK_PIN(199, "SPI1_CLK", DRV_GRP3),
+	MTK_PIN(200, "SPDIF_OUT", DRV_GRP1),
+	MTK_PIN(201, "SPDIF_IN0", DRV_GRP1),
+	MTK_PIN(202, "SPDIF_IN1", DRV_GRP1),
+	MTK_PIN(203, "PWM0", DRV_GRP1),
+	MTK_PIN(204, "PWM1", DRV_GRP1),
+	MTK_PIN(205, "PWM2", DRV_GRP1),
+	MTK_PIN(206, "PWM3", DRV_GRP1),
+	MTK_PIN(207, "PWM4", DRV_GRP1),
+	MTK_PIN(208, "AUD_EXT_CK1", DRV_GRP1),
+	MTK_PIN(209, "AUD_EXT_CK2", DRV_GRP1),
+	MTK_PIN(210, "AUD_CLOCK", DRV_GRP3),
+	MTK_PIN(211, "DVP_RESET", DRV_GRP3),
+	MTK_PIN(212, "DVP_CLOCK", DRV_GRP3),
+	MTK_PIN(213, "DVP_CS", DRV_GRP3),
+	MTK_PIN(214, "DVP_CK", DRV_GRP3),
+	MTK_PIN(215, "DVP_DI", DRV_GRP3),
+	MTK_PIN(216, "DVP_DO", DRV_GRP3),
+	MTK_PIN(217, "AP_CS", DRV_GRP3),
+	MTK_PIN(218, "AP_CK", DRV_GRP3),
+	MTK_PIN(219, "AP_DI", DRV_GRP3),
+	MTK_PIN(220, "AP_DO", DRV_GRP3),
+	MTK_PIN(221, "DVD_BCLK", DRV_GRP3),
+	MTK_PIN(222, "T8032_CLK", DRV_GRP3),
+	MTK_PIN(223, "AP_BCLK", DRV_GRP3),
+	MTK_PIN(224, "HOST_CS", DRV_GRP3),
+	MTK_PIN(225, "HOST_CK", DRV_GRP3),
+	MTK_PIN(226, "HOST_DO0", DRV_GRP3),
+	MTK_PIN(227, "HOST_DO1", DRV_GRP3),
+	MTK_PIN(228, "SLV_CS", DRV_GRP3),
+	MTK_PIN(229, "SLV_CK", DRV_GRP3),
+	MTK_PIN(230, "SLV_DI0", DRV_GRP3),
+	MTK_PIN(231, "SLV_DI1", DRV_GRP3),
+	MTK_PIN(232, "AP2DSP_INT", DRV_GRP3),
+	MTK_PIN(233, "AP2DSP_INT_CLR", DRV_GRP3),
+	MTK_PIN(234, "DSP2AP_INT", DRV_GRP3),
+	MTK_PIN(235, "DSP2AP_INT_CLR", DRV_GRP3),
+	MTK_PIN(236, "EXT_SDIO3", DRV_GRP1),
+	MTK_PIN(237, "EXT_SDIO2", DRV_GRP1),
+	MTK_PIN(238, "EXT_SDIO1", DRV_GRP1),
+	MTK_PIN(239, "EXT_SDIO0", DRV_GRP1),
+	MTK_PIN(240, "EXT_XCS", DRV_GRP1),
+	MTK_PIN(241, "EXT_SCK", DRV_GRP1),
+	MTK_PIN(242, "URTS2", DRV_GRP1),
+	MTK_PIN(243, "UCTS2", DRV_GRP1),
+	MTK_PIN(244, "HDMI_SDA_RX", DRV_FIXED),
+	MTK_PIN(245, "HDMI_SCL_RX", DRV_FIXED),
+	MTK_PIN(246, "MHL_SENCE", DRV_FIXED),
+	MTK_PIN(247, "HDMI_HPD_CBUS_RX", DRV_FIXED),
+	MTK_PIN(248, "HDMI_TESTOUTP_RX", DRV_GRP1),
+	MTK_PIN(249, "MSDC0E_RSTB", DRV_GRP4),
+	MTK_PIN(250, "MSDC0E_DAT7", DRV_GRP4),
+	MTK_PIN(251, "MSDC0E_DAT6", DRV_GRP4),
+	MTK_PIN(252, "MSDC0E_DAT5", DRV_GRP4),
+	MTK_PIN(253, "MSDC0E_DAT4", DRV_GRP4),
+	MTK_PIN(254, "MSDC0E_DAT3", DRV_GRP4),
+	MTK_PIN(255, "MSDC0E_DAT2", DRV_GRP4),
+	MTK_PIN(256, "MSDC0E_DAT1", DRV_GRP4),
+	MTK_PIN(257, "MSDC0E_DAT0", DRV_GRP4),
+	MTK_PIN(258, "MSDC0E_CMD", DRV_GRP4),
+	MTK_PIN(259, "MSDC0E_CLK", DRV_GRP4),
+	MTK_PIN(260, "MSDC0E_DSL", DRV_GRP4),
+	MTK_PIN(261, "MSDC1_INS", DRV_GRP4),
+	MTK_PIN(262, "G2_TXEN", DRV_GRP1),
+	MTK_PIN(263, "G2_TXD3", DRV_GRP1),
+	MTK_PIN(264, "G2_TXD2", DRV_GRP1),
+	MTK_PIN(265, "G2_TXD1", DRV_GRP1),
+	MTK_PIN(266, "G2_TXD0", DRV_GRP1),
+	MTK_PIN(267, "G2_TXC", DRV_GRP1),
+	MTK_PIN(268, "G2_RXC", DRV_GRP1),
+	MTK_PIN(269, "G2_RXD0", DRV_GRP1),
+	MTK_PIN(270, "G2_RXD1", DRV_GRP1),
+	MTK_PIN(271, "G2_RXD2", DRV_GRP1),
+	MTK_PIN(272, "G2_RXD3", DRV_GRP1),
+	MTK_PIN(273, "ESW_INT", DRV_GRP1),
+	MTK_PIN(274, "G2_RXDV", DRV_GRP1),
+	MTK_PIN(275, "MDC", DRV_GRP1),
+	MTK_PIN(276, "MDIO", DRV_GRP1),
+	MTK_PIN(277, "ESW_RST", DRV_GRP1),
+	MTK_PIN(278, "JTAG_RESET", DRV_GRP3),
+	MTK_PIN(279, "USB3_RES_BOND", DRV_GRP1),
+};
+
+/* List all groups consisting of these pins dedicated to the enablement of
+ * certain hardware block and the corresponding mode for all of the pins.
+ * The hardware probably has multiple combinations of these pinouts.
+ */
+
+/* AUDIO EXT CLK */
+static int mt7623_aud_ext_clk0_pins[] = { 208, };
+static int mt7623_aud_ext_clk0_funcs[] = { 1, };
+static int mt7623_aud_ext_clk1_pins[] = { 209, };
+static int mt7623_aud_ext_clk1_funcs[] = { 1, };
+
+/* DISP PWM */
+static int mt7623_disp_pwm_0_pins[] = { 72, };
+static int mt7623_disp_pwm_0_funcs[] = { 5, };
+static int mt7623_disp_pwm_1_pins[] = { 203, };
+static int mt7623_disp_pwm_1_funcs[] = { 2, };
+static int mt7623_disp_pwm_2_pins[] = { 208, };
+static int mt7623_disp_pwm_2_funcs[] = { 5, };
+
+/* ESW */
+static int mt7623_esw_int_pins[] = { 273, };
+static int mt7623_esw_int_funcs[] = { 1, };
+static int mt7623_esw_rst_pins[] = { 277, };
+static int mt7623_esw_rst_funcs[] = { 1, };
+
+/* EPHY */
+static int mt7623_ephy_pins[] = { 262, 263, 264, 265, 266, 267, 268,
+				  269, 270, 271, 272, 274, };
+static int mt7623_ephy_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+/* EXT_SDIO */
+static int mt7623_ext_sdio_pins[] = { 236, 237, 238, 239, 240, 241, };
+static int mt7623_ext_sdio_funcs[] = { 1, 1, 1, 1, 1, 1, };
+
+/* HDMI RX */
+static int mt7623_hdmi_rx_pins[] = { 247, 248, };
+static int mt7623_hdmi_rx_funcs[] = { 1, 1 };
+static int mt7623_hdmi_rx_i2c_pins[] = { 244, 245, };
+static int mt7623_hdmi_rx_i2c_funcs[] = { 1, 1 };
+
+/* HDMI TX */
+static int mt7623_hdmi_cec_pins[] = { 122, };
+static int mt7623_hdmi_cec_funcs[] = { 1, };
+static int mt7623_hdmi_htplg_pins[] = { 123, };
+static int mt7623_hdmi_htplg_funcs[] = { 1, };
+static int mt7623_hdmi_i2c_pins[] = { 124, 125, };
+static int mt7623_hdmi_i2c_funcs[] = { 1, 1 };
+
+/* I2C */
+static int mt7623_i2c0_pins[] = { 75, 76, };
+static int mt7623_i2c0_funcs[] = { 1, 1, };
+static int mt7623_i2c1_0_pins[] = { 57, 58, };
+static int mt7623_i2c1_0_funcs[] = { 1, 1, };
+static int mt7623_i2c1_1_pins[] = { 242, 243, };
+static int mt7623_i2c1_1_funcs[] = { 4, 4, };
+static int mt7623_i2c1_2_pins[] = { 85, 86, };
+static int mt7623_i2c1_2_funcs[] = { 3, 3, };
+static int mt7623_i2c1_3_pins[] = { 105, 106, };
+static int mt7623_i2c1_3_funcs[] = { 3, 3, };
+static int mt7623_i2c1_4_pins[] = { 124, 125, };
+static int mt7623_i2c1_4_funcs[] = { 4, 4, };
+static int mt7623_i2c2_0_pins[] = { 77, 78, };
+static int mt7623_i2c2_0_funcs[] = { 1, 1, };
+static int mt7623_i2c2_1_pins[] = { 89, 90, };
+static int mt7623_i2c2_1_funcs[] = { 3, 3, };
+static int mt7623_i2c2_2_pins[] = { 109, 110, };
+static int mt7623_i2c2_2_funcs[] = { 3, 3, };
+static int mt7623_i2c2_3_pins[] = { 122, 123, };
+static int mt7623_i2c2_3_funcs[] = { 4, 4, };
+
+/* I2S */
+static int mt7623_i2s0_pins[] = { 49, 72, 73, 74, 126, };
+static int mt7623_i2s0_funcs[] = { 1, 1, 1, 1, 1, };
+static int mt7623_i2s1_pins[] = { 33, 34, 35, 36, 37, };
+static int mt7623_i2s1_funcs[] = { 1, 1, 1, 1, 1, };
+static int mt7623_i2s2_bclk_lrclk_mclk_pins[] = { 50, 52, 188, };
+static int mt7623_i2s2_bclk_lrclk_mclk_funcs[] = { 1, 1, 1, };
+static int mt7623_i2s2_data_in_pins[] = { 51, };
+static int mt7623_i2s2_data_in_funcs[] = { 1, };
+static int mt7623_i2s2_data_0_pins[] = { 203, };
+static int mt7623_i2s2_data_0_funcs[] = { 9, };
+static int mt7623_i2s2_data_1_pins[] = { 38,  };
+static int mt7623_i2s2_data_1_funcs[] = { 4, };
+static int mt7623_i2s3_bclk_lrclk_mclk_pins[] = { 191, 192, 193, };
+static int mt7623_i2s3_bclk_lrclk_mclk_funcs[] = { 1, 1, 1, };
+static int mt7623_i2s3_data_in_pins[] = { 190, };
+static int mt7623_i2s3_data_in_funcs[] = { 1, };
+static int mt7623_i2s3_data_0_pins[] = { 204, };
+static int mt7623_i2s3_data_0_funcs[] = { 9, };
+static int mt7623_i2s3_data_1_pins[] = { 2, };
+static int mt7623_i2s3_data_1_funcs[] = { 0, };
+static int mt7623_i2s4_pins[] = { 194, 195, 196, 197, 198, };
+static int mt7623_i2s4_funcs[] = { 1, 1, 1, 1, 1, };
+static int mt7623_i2s5_pins[] = { 16, 17, 30, 31, 32, };
+static int mt7623_i2s5_funcs[] = { 1, 1, 1, 1, 1, };
+
+/* IR */
+static int mt7623_ir_pins[] = { 46, };
+static int mt7623_ir_funcs[] = { 1, };
+
+/* LCD */
+static int mt7623_mipi_tx_pins[] = { 91, 92, 93, 94, 95, 96, 97, 98,
+				     99, 100, };
+static int mt7623_mipi_tx_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+static int mt7623_dsi_te_pins[] = { 84, };
+static int mt7623_dsi_te_funcs[] = { 1, };
+static int mt7623_lcm_rst_pins[] = { 83, };
+static int mt7623_lcm_rst_funcs[] = { 1, };
+
+/* MDC/MDIO */
+static int mt7623_mdc_mdio_pins[] = { 275, 276, };
+static int mt7623_mdc_mdio_funcs[] = { 1, 1, };
+
+/* MSDC */
+static int mt7623_msdc0_pins[] = { 111, 112, 113, 114, 115, 116, 117, 118,
+				   119, 120, 121, };
+static int mt7623_msdc0_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+static int mt7623_msdc1_pins[] = { 105, 106, 107, 108, 109, 110, };
+static int mt7623_msdc1_funcs[] = { 1, 1, 1, 1, 1, 1, };
+static int mt7623_msdc1_ins_pins[] = { 261, };
+static int mt7623_msdc1_ins_funcs[] = { 1, };
+static int mt7623_msdc1_wp_0_pins[] = { 29, };
+static int mt7623_msdc1_wp_0_funcs[] = { 1, };
+static int mt7623_msdc1_wp_1_pins[] = { 55, };
+static int mt7623_msdc1_wp_1_funcs[] = { 3, };
+static int mt7623_msdc1_wp_2_pins[] = { 209, };
+static int mt7623_msdc1_wp_2_funcs[] = { 2, };
+static int mt7623_msdc2_pins[] = { 85, 86, 87, 88, 89, 90, };
+static int mt7623_msdc2_funcs[] = { 1, 1, 1, 1, 1, 1, };
+static int mt7623_msdc3_pins[] = { 249, 250, 251, 252, 253, 254, 255, 256,
+				   257, 258, 259, 260, };
+static int mt7623_msdc3_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+/* NAND */
+static int mt7623_nandc_pins[] = { 43, 47, 48, 111, 112, 113, 114, 115,
+				   116, 117, 118, 119, 120, 121, };
+static int mt7623_nandc_funcs[] = { 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+				   4, 4, };
+static int mt7623_nandc_ceb0_pins[] = { 45, };
+static int mt7623_nandc_ceb0_funcs[] = { 1, };
+static int mt7623_nandc_ceb1_pins[] = { 44, };
+static int mt7623_nandc_ceb1_funcs[] = { 1, };
+
+/* RTC */
+static int mt7623_rtc_pins[] = { 10, };
+static int mt7623_rtc_funcs[] = { 1, };
+
+/* OTG */
+static int mt7623_otg_iddig0_0_pins[] = { 29, };
+static int mt7623_otg_iddig0_0_funcs[] = { 1, };
+static int mt7623_otg_iddig0_1_pins[] = { 44, };
+static int mt7623_otg_iddig0_1_funcs[] = { 2, };
+static int mt7623_otg_iddig0_2_pins[] = { 236, };
+static int mt7623_otg_iddig0_2_funcs[] = { 2, };
+static int mt7623_otg_iddig1_0_pins[] = { 27, };
+static int mt7623_otg_iddig1_0_funcs[] = { 2, };
+static int mt7623_otg_iddig1_1_pins[] = { 47, };
+static int mt7623_otg_iddig1_1_funcs[] = { 2, };
+static int mt7623_otg_iddig1_2_pins[] = { 238, };
+static int mt7623_otg_iddig1_2_funcs[] = { 2, };
+static int mt7623_otg_drv_vbus0_0_pins[] = { 28, };
+static int mt7623_otg_drv_vbus0_0_funcs[] = { 1, };
+static int mt7623_otg_drv_vbus0_1_pins[] = { 45, };
+static int mt7623_otg_drv_vbus0_1_funcs[] = { 2, };
+static int mt7623_otg_drv_vbus0_2_pins[] = { 237, };
+static int mt7623_otg_drv_vbus0_2_funcs[] = { 2, };
+static int mt7623_otg_drv_vbus1_0_pins[] = { 26, };
+static int mt7623_otg_drv_vbus1_0_funcs[] = { 2, };
+static int mt7623_otg_drv_vbus1_1_pins[] = { 48, };
+static int mt7623_otg_drv_vbus1_1_funcs[] = { 2, };
+static int mt7623_otg_drv_vbus1_2_pins[] = { 239, };
+static int mt7623_otg_drv_vbus1_2_funcs[] = { 2, };
+
+/* PCIE */
+static int mt7623_pcie0_0_perst_pins[] = { 208, };
+static int mt7623_pcie0_0_perst_funcs[] = { 3, };
+static int mt7623_pcie0_1_perst_pins[] = { 22, };
+static int mt7623_pcie0_1_perst_funcs[] = { 2, };
+static int mt7623_pcie1_0_perst_pins[] = { 209, };
+static int mt7623_pcie1_0_perst_funcs[] = { 3, };
+static int mt7623_pcie1_1_perst_pins[] = { 23, };
+static int mt7623_pcie1_1_perst_funcs[] = { 2, };
+static int mt7623_pcie2_0_perst_pins[] = { 24, };
+static int mt7623_pcie2_0_perst_funcs[] = { 2, };
+static int mt7623_pcie2_1_perst_pins[] = { 29, };
+static int mt7623_pcie2_1_perst_funcs[] = { 6, };
+static int mt7623_pcie0_0_wake_pins[] = { 28, };
+static int mt7623_pcie0_0_wake_funcs[] = { 6, };
+static int mt7623_pcie0_1_wake_pins[] = { 251, };
+static int mt7623_pcie0_1_wake_funcs[] = { 6, };
+static int mt7623_pcie1_0_wake_pins[] = { 27, };
+static int mt7623_pcie1_0_wake_funcs[] = { 6, };
+static int mt7623_pcie1_1_wake_pins[] = { 253, };
+static int mt7623_pcie1_1_wake_funcs[] = { 6, };
+static int mt7623_pcie2_0_wake_pins[] = { 26, };
+static int mt7623_pcie2_0_wake_funcs[] = { 6, };
+static int mt7623_pcie2_1_wake_pins[] = { 255, };
+static int mt7623_pcie2_1_wake_funcs[] = { 6, };
+static int mt7623_pcie0_clkreq_pins[] = { 250, };
+static int mt7623_pcie0_clkreq_funcs[] = { 6, };
+static int mt7623_pcie1_clkreq_pins[] = { 252, };
+static int mt7623_pcie1_clkreq_funcs[] = { 6, };
+static int mt7623_pcie2_clkreq_pins[] = { 254, };
+static int mt7623_pcie2_clkreq_funcs[] = { 6, };
+/* the pcie_*_rev are only used for MT7623 */
+static int mt7623_pcie0_0_rev_perst_pins[] = { 208, };
+static int mt7623_pcie0_0_rev_perst_funcs[] = { 11, };
+static int mt7623_pcie0_1_rev_perst_pins[] = { 22, };
+static int mt7623_pcie0_1_rev_perst_funcs[] = { 10, };
+static int mt7623_pcie1_0_rev_perst_pins[] = { 209, };
+static int mt7623_pcie1_0_rev_perst_funcs[] = { 11, };
+static int mt7623_pcie1_1_rev_perst_pins[] = { 23, };
+static int mt7623_pcie1_1_rev_perst_funcs[] = { 10, };
+static int mt7623_pcie2_0_rev_perst_pins[] = { 24, };
+static int mt7623_pcie2_0_rev_perst_funcs[] = { 11, };
+static int mt7623_pcie2_1_rev_perst_pins[] = { 29, };
+static int mt7623_pcie2_1_rev_perst_funcs[] = { 14, };
+
+/* PCM */
+static int mt7623_pcm_clk_0_pins[] = { 18, };
+static int mt7623_pcm_clk_0_funcs[] = { 1, };
+static int mt7623_pcm_clk_1_pins[] = { 17, };
+static int mt7623_pcm_clk_1_funcs[] = { 3, };
+static int mt7623_pcm_clk_2_pins[] = { 35, };
+static int mt7623_pcm_clk_2_funcs[] = { 3, };
+static int mt7623_pcm_clk_3_pins[] = { 50, };
+static int mt7623_pcm_clk_3_funcs[] = { 3, };
+static int mt7623_pcm_clk_4_pins[] = { 74, };
+static int mt7623_pcm_clk_4_funcs[] = { 3, };
+static int mt7623_pcm_clk_5_pins[] = { 191, };
+static int mt7623_pcm_clk_5_funcs[] = { 3, };
+static int mt7623_pcm_clk_6_pins[] = { 196, };
+static int mt7623_pcm_clk_6_funcs[] = { 3, };
+static int mt7623_pcm_sync_0_pins[] = { 19, };
+static int mt7623_pcm_sync_0_funcs[] = { 1, };
+static int mt7623_pcm_sync_1_pins[] = { 30, };
+static int mt7623_pcm_sync_1_funcs[] = { 3, };
+static int mt7623_pcm_sync_2_pins[] = { 36, };
+static int mt7623_pcm_sync_2_funcs[] = { 3, };
+static int mt7623_pcm_sync_3_pins[] = { 52, };
+static int mt7623_pcm_sync_3_funcs[] = { 31, };
+static int mt7623_pcm_sync_4_pins[] = { 73, };
+static int mt7623_pcm_sync_4_funcs[] = { 3, };
+static int mt7623_pcm_sync_5_pins[] = { 192, };
+static int mt7623_pcm_sync_5_funcs[] = { 3, };
+static int mt7623_pcm_sync_6_pins[] = { 197, };
+static int mt7623_pcm_sync_6_funcs[] = { 3, };
+static int mt7623_pcm_rx_0_pins[] = { 20, };
+static int mt7623_pcm_rx_0_funcs[] = { 1, };
+static int mt7623_pcm_rx_1_pins[] = { 16, };
+static int mt7623_pcm_rx_1_funcs[] = { 3, };
+static int mt7623_pcm_rx_2_pins[] = { 34, };
+static int mt7623_pcm_rx_2_funcs[] = { 3, };
+static int mt7623_pcm_rx_3_pins[] = { 51, };
+static int mt7623_pcm_rx_3_funcs[] = { 3, };
+static int mt7623_pcm_rx_4_pins[] = { 72, };
+static int mt7623_pcm_rx_4_funcs[] = { 3, };
+static int mt7623_pcm_rx_5_pins[] = { 190, };
+static int mt7623_pcm_rx_5_funcs[] = { 3, };
+static int mt7623_pcm_rx_6_pins[] = { 195, };
+static int mt7623_pcm_rx_6_funcs[] = { 3, };
+static int mt7623_pcm_tx_0_pins[] = { 21, };
+static int mt7623_pcm_tx_0_funcs[] = { 1, };
+static int mt7623_pcm_tx_1_pins[] = { 32, };
+static int mt7623_pcm_tx_1_funcs[] = { 3, };
+static int mt7623_pcm_tx_2_pins[] = { 33, };
+static int mt7623_pcm_tx_2_funcs[] = { 3, };
+static int mt7623_pcm_tx_3_pins[] = { 38, };
+static int mt7623_pcm_tx_3_funcs[] = { 3, };
+static int mt7623_pcm_tx_4_pins[] = { 49, };
+static int mt7623_pcm_tx_4_funcs[] = { 3, };
+static int mt7623_pcm_tx_5_pins[] = { 189, };
+static int mt7623_pcm_tx_5_funcs[] = { 3, };
+static int mt7623_pcm_tx_6_pins[] = { 194, };
+static int mt7623_pcm_tx_6_funcs[] = { 3, };
+
+/* PWM */
+static int mt7623_pwm_ch1_0_pins[] = { 203, };
+static int mt7623_pwm_ch1_0_funcs[] = { 1, };
+static int mt7623_pwm_ch1_1_pins[] = { 208, };
+static int mt7623_pwm_ch1_1_funcs[] = { 2, };
+static int mt7623_pwm_ch1_2_pins[] = { 72, };
+static int mt7623_pwm_ch1_2_funcs[] = { 4, };
+static int mt7623_pwm_ch1_3_pins[] = { 88, };
+static int mt7623_pwm_ch1_3_funcs[] = { 3, };
+static int mt7623_pwm_ch1_4_pins[] = { 108, };
+static int mt7623_pwm_ch1_4_funcs[] = { 3, };
+static int mt7623_pwm_ch2_0_pins[] = { 204, };
+static int mt7623_pwm_ch2_0_funcs[] = { 1, };
+static int mt7623_pwm_ch2_1_pins[] = { 53, };
+static int mt7623_pwm_ch2_1_funcs[] = { 5, };
+static int mt7623_pwm_ch2_2_pins[] = { 88, };
+static int mt7623_pwm_ch2_2_funcs[] = { 6, };
+static int mt7623_pwm_ch2_3_pins[] = { 108, };
+static int mt7623_pwm_ch2_3_funcs[] = { 6, };
+static int mt7623_pwm_ch2_4_pins[] = { 209, };
+static int mt7623_pwm_ch2_4_funcs[] = { 5, };
+static int mt7623_pwm_ch3_0_pins[] = { 205, };
+static int mt7623_pwm_ch3_0_funcs[] = { 1, };
+static int mt7623_pwm_ch3_1_pins[] = { 55, };
+static int mt7623_pwm_ch3_1_funcs[] = { 5, };
+static int mt7623_pwm_ch3_2_pins[] = { 89, };
+static int mt7623_pwm_ch3_2_funcs[] = { 6, };
+static int mt7623_pwm_ch3_3_pins[] = { 109, };
+static int mt7623_pwm_ch3_3_funcs[] = { 6, };
+static int mt7623_pwm_ch4_0_pins[] = { 206, };
+static int mt7623_pwm_ch4_0_funcs[] = { 1, };
+static int mt7623_pwm_ch4_1_pins[] = { 90, };
+static int mt7623_pwm_ch4_1_funcs[] = { 6, };
+static int mt7623_pwm_ch4_2_pins[] = { 110, };
+static int mt7623_pwm_ch4_2_funcs[] = { 6, };
+static int mt7623_pwm_ch4_3_pins[] = { 124, };
+static int mt7623_pwm_ch4_3_funcs[] = { 5, };
+static int mt7623_pwm_ch5_0_pins[] = { 207, };
+static int mt7623_pwm_ch5_0_funcs[] = { 1, };
+static int mt7623_pwm_ch5_1_pins[] = { 125, };
+static int mt7623_pwm_ch5_1_funcs[] = { 5, };
+
+/* PWRAP */
+static int mt7623_pwrap_pins[] = { 0, 1, 2, 3, 4, 5, 6, };
+static int mt7623_pwrap_funcs[] = { 1, 1, 1, 1, 1, 1, 1, };
+
+/* SPDIF */
+static int mt7623_spdif_in0_0_pins[] = { 56, };
+static int mt7623_spdif_in0_0_funcs[] = { 3, };
+static int mt7623_spdif_in0_1_pins[] = { 201, };
+static int mt7623_spdif_in0_1_funcs[] = { 1, };
+static int mt7623_spdif_in1_0_pins[] = { 54, };
+static int mt7623_spdif_in1_0_funcs[] = { 3, };
+static int mt7623_spdif_in1_1_pins[] = { 202, };
+static int mt7623_spdif_in1_1_funcs[] = { 1, };
+static int mt7623_spdif_out_pins[] = { 202, };
+static int mt7623_spdif_out_funcs[] = { 1, };
+
+/* SPI */
+static int mt7623_spi0_pins[] = { 53, 54, 55, 56, };
+static int mt7623_spi0_funcs[] = { 1, 1, 1, 1, };
+static int mt7623_spi1_pins[] = { 7, 199, 8, 9, };
+static int mt7623_spi1_funcs[] = { 1, 1, 1, 1, };
+static int mt7623_spi2_pins[] = { 101, 104, 102, 103, };
+static int mt7623_spi2_funcs[] = { 1, 1, 1, 1, };
+
+/* UART */
+static int mt7623_uart0_0_txd_rxd_pins[] = { 79, 80, };
+static int mt7623_uart0_0_txd_rxd_funcs[] = { 1, 1, };
+static int mt7623_uart0_1_txd_rxd_pins[] = { 87, 88, };
+static int mt7623_uart0_1_txd_rxd_funcs[] = { 5, 5, };
+static int mt7623_uart0_2_txd_rxd_pins[] = { 107, 108, };
+static int mt7623_uart0_2_txd_rxd_funcs[] = { 5, 5, };
+static int mt7623_uart0_3_txd_rxd_pins[] = { 123, 122, };
+static int mt7623_uart0_3_txd_rxd_funcs[] = { 5, 5, };
+static int mt7623_uart0_rts_cts_pins[] = { 22, 23, };
+static int mt7623_uart0_rts_cts_funcs[] = { 1, 1, };
+static int mt7623_uart1_0_txd_rxd_pins[] = { 81, 82, };
+static int mt7623_uart1_0_txd_rxd_funcs[] = { 1, 1, };
+static int mt7623_uart1_1_txd_rxd_pins[] = { 89, 90, };
+static int mt7623_uart1_1_txd_rxd_funcs[] = { 5, 5, };
+static int mt7623_uart1_2_txd_rxd_pins[] = { 109, 110, };
+static int mt7623_uart1_2_txd_rxd_funcs[] = { 5, 5, };
+static int mt7623_uart1_rts_cts_pins[] = { 24, 25, };
+static int mt7623_uart1_rts_cts_funcs[] = { 1, 1, };
+static int mt7623_uart2_0_txd_rxd_pins[] = { 14, 15, };
+static int mt7623_uart2_0_txd_rxd_funcs[] = { 1, 1, };
+static int mt7623_uart2_1_txd_rxd_pins[] = { 200, 201, };
+static int mt7623_uart2_1_txd_rxd_funcs[] = { 6, 6, };
+static int mt7623_uart2_rts_cts_pins[] = { 242, 243, };
+static int mt7623_uart2_rts_cts_funcs[] = { 1, 1, };
+static int mt7623_uart3_txd_rxd_pins[] = { 242, 243, };
+static int mt7623_uart3_txd_rxd_funcs[] = { 2, 2, };
+static int mt7623_uart3_rts_cts_pins[] = { 26, 27, };
+static int mt7623_uart3_rts_cts_funcs[] = { 1, 1, };
+
+/* Watchdog */
+static int mt7623_watchdog_0_pins[] = { 11, };
+static int mt7623_watchdog_0_funcs[] = { 1, };
+static int mt7623_watchdog_1_pins[] = { 121, };
+static int mt7623_watchdog_1_funcs[] = { 5, };
+
+static const struct mtk_group_desc mt7623_groups[] = {
+	PINCTRL_PIN_GROUP("aud_ext_clk0", mt7623_aud_ext_clk0),
+	PINCTRL_PIN_GROUP("aud_ext_clk1", mt7623_aud_ext_clk1),
+	PINCTRL_PIN_GROUP("dsi_te", mt7623_dsi_te),
+	PINCTRL_PIN_GROUP("disp_pwm_0", mt7623_disp_pwm_0),
+	PINCTRL_PIN_GROUP("disp_pwm_1", mt7623_disp_pwm_1),
+	PINCTRL_PIN_GROUP("disp_pwm_2", mt7623_disp_pwm_2),
+	PINCTRL_PIN_GROUP("ephy", mt7623_ephy),
+	PINCTRL_PIN_GROUP("esw_int", mt7623_esw_int),
+	PINCTRL_PIN_GROUP("esw_rst", mt7623_esw_rst),
+	PINCTRL_PIN_GROUP("ext_sdio", mt7623_ext_sdio),
+	PINCTRL_PIN_GROUP("hdmi_cec", mt7623_hdmi_cec),
+	PINCTRL_PIN_GROUP("hdmi_htplg", mt7623_hdmi_htplg),
+	PINCTRL_PIN_GROUP("hdmi_i2c", mt7623_hdmi_i2c),
+	PINCTRL_PIN_GROUP("hdmi_rx", mt7623_hdmi_rx),
+	PINCTRL_PIN_GROUP("hdmi_rx_i2c", mt7623_hdmi_rx_i2c),
+	PINCTRL_PIN_GROUP("i2c0", mt7623_i2c0),
+	PINCTRL_PIN_GROUP("i2c1_0", mt7623_i2c1_0),
+	PINCTRL_PIN_GROUP("i2c1_1", mt7623_i2c1_1),
+	PINCTRL_PIN_GROUP("i2c1_2", mt7623_i2c1_2),
+	PINCTRL_PIN_GROUP("i2c1_3", mt7623_i2c1_3),
+	PINCTRL_PIN_GROUP("i2c1_4", mt7623_i2c1_4),
+	PINCTRL_PIN_GROUP("i2c2_0", mt7623_i2c2_0),
+	PINCTRL_PIN_GROUP("i2c2_1", mt7623_i2c2_1),
+	PINCTRL_PIN_GROUP("i2c2_2", mt7623_i2c2_2),
+	PINCTRL_PIN_GROUP("i2c2_3", mt7623_i2c2_3),
+	PINCTRL_PIN_GROUP("i2s0", mt7623_i2s0),
+	PINCTRL_PIN_GROUP("i2s1", mt7623_i2s1),
+	PINCTRL_PIN_GROUP("i2s4", mt7623_i2s4),
+	PINCTRL_PIN_GROUP("i2s5", mt7623_i2s5),
+	PINCTRL_PIN_GROUP("i2s2_bclk_lrclk_mclk", mt7623_i2s2_bclk_lrclk_mclk),
+	PINCTRL_PIN_GROUP("i2s3_bclk_lrclk_mclk", mt7623_i2s3_bclk_lrclk_mclk),
+	PINCTRL_PIN_GROUP("i2s2_data_in", mt7623_i2s2_data_in),
+	PINCTRL_PIN_GROUP("i2s3_data_in", mt7623_i2s3_data_in),
+	PINCTRL_PIN_GROUP("i2s2_data_0", mt7623_i2s2_data_0),
+	PINCTRL_PIN_GROUP("i2s2_data_1", mt7623_i2s2_data_1),
+	PINCTRL_PIN_GROUP("i2s3_data_0", mt7623_i2s3_data_0),
+	PINCTRL_PIN_GROUP("i2s3_data_1", mt7623_i2s3_data_1),
+	PINCTRL_PIN_GROUP("ir", mt7623_ir),
+	PINCTRL_PIN_GROUP("lcm_rst", mt7623_lcm_rst),
+	PINCTRL_PIN_GROUP("mdc_mdio", mt7623_mdc_mdio),
+	PINCTRL_PIN_GROUP("mipi_tx", mt7623_mipi_tx),
+	PINCTRL_PIN_GROUP("msdc0", mt7623_msdc0),
+	PINCTRL_PIN_GROUP("msdc1", mt7623_msdc1),
+	PINCTRL_PIN_GROUP("msdc1_ins", mt7623_msdc1_ins),
+	PINCTRL_PIN_GROUP("msdc1_wp_0", mt7623_msdc1_wp_0),
+	PINCTRL_PIN_GROUP("msdc1_wp_1", mt7623_msdc1_wp_1),
+	PINCTRL_PIN_GROUP("msdc1_wp_2", mt7623_msdc1_wp_2),
+	PINCTRL_PIN_GROUP("msdc2", mt7623_msdc2),
+	PINCTRL_PIN_GROUP("msdc3", mt7623_msdc3),
+	PINCTRL_PIN_GROUP("nandc", mt7623_nandc),
+	PINCTRL_PIN_GROUP("nandc_ceb0", mt7623_nandc_ceb0),
+	PINCTRL_PIN_GROUP("nandc_ceb1", mt7623_nandc_ceb1),
+	PINCTRL_PIN_GROUP("otg_iddig0_0", mt7623_otg_iddig0_0),
+	PINCTRL_PIN_GROUP("otg_iddig0_1", mt7623_otg_iddig0_1),
+	PINCTRL_PIN_GROUP("otg_iddig0_2", mt7623_otg_iddig0_2),
+	PINCTRL_PIN_GROUP("otg_iddig1_0", mt7623_otg_iddig1_0),
+	PINCTRL_PIN_GROUP("otg_iddig1_1", mt7623_otg_iddig1_1),
+	PINCTRL_PIN_GROUP("otg_iddig1_2", mt7623_otg_iddig1_2),
+	PINCTRL_PIN_GROUP("otg_drv_vbus0_0", mt7623_otg_drv_vbus0_0),
+	PINCTRL_PIN_GROUP("otg_drv_vbus0_1", mt7623_otg_drv_vbus0_1),
+	PINCTRL_PIN_GROUP("otg_drv_vbus0_2", mt7623_otg_drv_vbus0_2),
+	PINCTRL_PIN_GROUP("otg_drv_vbus1_0", mt7623_otg_drv_vbus1_0),
+	PINCTRL_PIN_GROUP("otg_drv_vbus1_1", mt7623_otg_drv_vbus1_1),
+	PINCTRL_PIN_GROUP("otg_drv_vbus1_2", mt7623_otg_drv_vbus1_2),
+	PINCTRL_PIN_GROUP("pcie0_0_perst", mt7623_pcie0_0_perst),
+	PINCTRL_PIN_GROUP("pcie0_1_perst", mt7623_pcie0_1_perst),
+	PINCTRL_PIN_GROUP("pcie1_0_perst", mt7623_pcie1_0_perst),
+	PINCTRL_PIN_GROUP("pcie1_1_perst", mt7623_pcie1_1_perst),
+	PINCTRL_PIN_GROUP("pcie1_1_perst", mt7623_pcie1_1_perst),
+	PINCTRL_PIN_GROUP("pcie0_0_rev_perst", mt7623_pcie0_0_rev_perst),
+	PINCTRL_PIN_GROUP("pcie0_1_rev_perst", mt7623_pcie0_1_rev_perst),
+	PINCTRL_PIN_GROUP("pcie1_0_rev_perst", mt7623_pcie1_0_rev_perst),
+	PINCTRL_PIN_GROUP("pcie1_1_rev_perst", mt7623_pcie1_1_rev_perst),
+	PINCTRL_PIN_GROUP("pcie2_0_rev_perst", mt7623_pcie2_0_rev_perst),
+	PINCTRL_PIN_GROUP("pcie2_1_rev_perst", mt7623_pcie2_1_rev_perst),
+	PINCTRL_PIN_GROUP("pcie2_0_perst", mt7623_pcie2_0_perst),
+	PINCTRL_PIN_GROUP("pcie2_1_perst", mt7623_pcie2_1_perst),
+	PINCTRL_PIN_GROUP("pcie0_0_wake", mt7623_pcie0_0_wake),
+	PINCTRL_PIN_GROUP("pcie0_1_wake", mt7623_pcie0_1_wake),
+	PINCTRL_PIN_GROUP("pcie1_0_wake", mt7623_pcie1_0_wake),
+	PINCTRL_PIN_GROUP("pcie1_1_wake", mt7623_pcie1_1_wake),
+	PINCTRL_PIN_GROUP("pcie2_0_wake", mt7623_pcie2_0_wake),
+	PINCTRL_PIN_GROUP("pcie2_1_wake", mt7623_pcie2_1_wake),
+	PINCTRL_PIN_GROUP("pcie0_clkreq", mt7623_pcie0_clkreq),
+	PINCTRL_PIN_GROUP("pcie1_clkreq", mt7623_pcie1_clkreq),
+	PINCTRL_PIN_GROUP("pcie2_clkreq", mt7623_pcie2_clkreq),
+	PINCTRL_PIN_GROUP("pcm_clk_0", mt7623_pcm_clk_0),
+	PINCTRL_PIN_GROUP("pcm_clk_1", mt7623_pcm_clk_1),
+	PINCTRL_PIN_GROUP("pcm_clk_2", mt7623_pcm_clk_2),
+	PINCTRL_PIN_GROUP("pcm_clk_3", mt7623_pcm_clk_3),
+	PINCTRL_PIN_GROUP("pcm_clk_4", mt7623_pcm_clk_4),
+	PINCTRL_PIN_GROUP("pcm_clk_5", mt7623_pcm_clk_5),
+	PINCTRL_PIN_GROUP("pcm_clk_6", mt7623_pcm_clk_6),
+	PINCTRL_PIN_GROUP("pcm_sync_0", mt7623_pcm_sync_0),
+	PINCTRL_PIN_GROUP("pcm_sync_1", mt7623_pcm_sync_1),
+	PINCTRL_PIN_GROUP("pcm_sync_2", mt7623_pcm_sync_2),
+	PINCTRL_PIN_GROUP("pcm_sync_3", mt7623_pcm_sync_3),
+	PINCTRL_PIN_GROUP("pcm_sync_4", mt7623_pcm_sync_4),
+	PINCTRL_PIN_GROUP("pcm_sync_5", mt7623_pcm_sync_5),
+	PINCTRL_PIN_GROUP("pcm_sync_6", mt7623_pcm_sync_6),
+	PINCTRL_PIN_GROUP("pcm_rx_0", mt7623_pcm_rx_0),
+	PINCTRL_PIN_GROUP("pcm_rx_1", mt7623_pcm_rx_1),
+	PINCTRL_PIN_GROUP("pcm_rx_2", mt7623_pcm_rx_2),
+	PINCTRL_PIN_GROUP("pcm_rx_3", mt7623_pcm_rx_3),
+	PINCTRL_PIN_GROUP("pcm_rx_4", mt7623_pcm_rx_4),
+	PINCTRL_PIN_GROUP("pcm_rx_5", mt7623_pcm_rx_5),
+	PINCTRL_PIN_GROUP("pcm_rx_6", mt7623_pcm_rx_6),
+	PINCTRL_PIN_GROUP("pcm_tx_0", mt7623_pcm_tx_0),
+	PINCTRL_PIN_GROUP("pcm_tx_1", mt7623_pcm_tx_1),
+	PINCTRL_PIN_GROUP("pcm_tx_2", mt7623_pcm_tx_2),
+	PINCTRL_PIN_GROUP("pcm_tx_3", mt7623_pcm_tx_3),
+	PINCTRL_PIN_GROUP("pcm_tx_4", mt7623_pcm_tx_4),
+	PINCTRL_PIN_GROUP("pcm_tx_5", mt7623_pcm_tx_5),
+	PINCTRL_PIN_GROUP("pcm_tx_6", mt7623_pcm_tx_6),
+	PINCTRL_PIN_GROUP("pwm_ch1_0", mt7623_pwm_ch1_0),
+	PINCTRL_PIN_GROUP("pwm_ch1_1", mt7623_pwm_ch1_1),
+	PINCTRL_PIN_GROUP("pwm_ch1_2", mt7623_pwm_ch1_2),
+	PINCTRL_PIN_GROUP("pwm_ch1_3", mt7623_pwm_ch1_3),
+	PINCTRL_PIN_GROUP("pwm_ch1_4", mt7623_pwm_ch1_4),
+	PINCTRL_PIN_GROUP("pwm_ch2_0", mt7623_pwm_ch2_0),
+	PINCTRL_PIN_GROUP("pwm_ch2_1", mt7623_pwm_ch2_1),
+	PINCTRL_PIN_GROUP("pwm_ch2_2", mt7623_pwm_ch2_2),
+	PINCTRL_PIN_GROUP("pwm_ch2_3", mt7623_pwm_ch2_3),
+	PINCTRL_PIN_GROUP("pwm_ch2_4", mt7623_pwm_ch2_4),
+	PINCTRL_PIN_GROUP("pwm_ch3_0", mt7623_pwm_ch3_0),
+	PINCTRL_PIN_GROUP("pwm_ch3_1", mt7623_pwm_ch3_1),
+	PINCTRL_PIN_GROUP("pwm_ch3_2", mt7623_pwm_ch3_2),
+	PINCTRL_PIN_GROUP("pwm_ch3_3", mt7623_pwm_ch3_3),
+	PINCTRL_PIN_GROUP("pwm_ch4_0", mt7623_pwm_ch4_0),
+	PINCTRL_PIN_GROUP("pwm_ch4_1", mt7623_pwm_ch4_1),
+	PINCTRL_PIN_GROUP("pwm_ch4_2", mt7623_pwm_ch4_2),
+	PINCTRL_PIN_GROUP("pwm_ch4_3", mt7623_pwm_ch4_3),
+	PINCTRL_PIN_GROUP("pwm_ch5_0", mt7623_pwm_ch5_0),
+	PINCTRL_PIN_GROUP("pwm_ch5_1", mt7623_pwm_ch5_1),
+	PINCTRL_PIN_GROUP("pwrap", mt7623_pwrap),
+	PINCTRL_PIN_GROUP("rtc", mt7623_rtc),
+	PINCTRL_PIN_GROUP("spdif_in0_0", mt7623_spdif_in0_0),
+	PINCTRL_PIN_GROUP("spdif_in0_1", mt7623_spdif_in0_1),
+	PINCTRL_PIN_GROUP("spdif_in1_0", mt7623_spdif_in1_0),
+	PINCTRL_PIN_GROUP("spdif_in1_1", mt7623_spdif_in1_1),
+	PINCTRL_PIN_GROUP("spdif_out", mt7623_spdif_out),
+	PINCTRL_PIN_GROUP("spi0", mt7623_spi0),
+	PINCTRL_PIN_GROUP("spi1", mt7623_spi1),
+	PINCTRL_PIN_GROUP("spi2", mt7623_spi2),
+	PINCTRL_PIN_GROUP("uart0_0_txd_rxd",  mt7623_uart0_0_txd_rxd),
+	PINCTRL_PIN_GROUP("uart0_1_txd_rxd",  mt7623_uart0_1_txd_rxd),
+	PINCTRL_PIN_GROUP("uart0_2_txd_rxd",  mt7623_uart0_2_txd_rxd),
+	PINCTRL_PIN_GROUP("uart0_3_txd_rxd",  mt7623_uart0_3_txd_rxd),
+	PINCTRL_PIN_GROUP("uart1_0_txd_rxd",  mt7623_uart1_0_txd_rxd),
+	PINCTRL_PIN_GROUP("uart1_1_txd_rxd",  mt7623_uart1_1_txd_rxd),
+	PINCTRL_PIN_GROUP("uart1_2_txd_rxd",  mt7623_uart1_2_txd_rxd),
+	PINCTRL_PIN_GROUP("uart2_0_txd_rxd",  mt7623_uart2_0_txd_rxd),
+	PINCTRL_PIN_GROUP("uart2_1_txd_rxd",  mt7623_uart2_1_txd_rxd),
+	PINCTRL_PIN_GROUP("uart3_txd_rxd",  mt7623_uart3_txd_rxd),
+	PINCTRL_PIN_GROUP("uart0_rts_cts",  mt7623_uart0_rts_cts),
+	PINCTRL_PIN_GROUP("uart1_rts_cts",  mt7623_uart1_rts_cts),
+	PINCTRL_PIN_GROUP("uart2_rts_cts",  mt7623_uart2_rts_cts),
+	PINCTRL_PIN_GROUP("uart3_rts_cts",  mt7623_uart3_rts_cts),
+	PINCTRL_PIN_GROUP("watchdog_0", mt7623_watchdog_0),
+	PINCTRL_PIN_GROUP("watchdog_1", mt7623_watchdog_1),
+};
+
+/* Joint those groups owning the same capability in user point of view which
+ * allows that people tend to use through the device tree.
+ */
+
+static const char *const mt7623_aud_clk_groups[] = { "aud_ext_clk0",
+						"aud_ext_clk1", };
+static const char *const mt7623_disp_pwm_groups[] = { "disp_pwm_0",
+						"disp_pwm_1",
+						"disp_pwm_2", };
+static const char *const mt7623_ethernet_groups[] = { "esw_int", "esw_rst",
+						"ephy", "mdc_mdio", };
+static const char *const mt7623_ext_sdio_groups[] = { "ext_sdio", };
+static const char *const mt7623_hdmi_groups[] = { "hdmi_cec", "hdmi_htplg",
+						"hdmi_i2c", "hdmi_rx",
+						"hdmi_rx_i2c", };
+static const char *const mt7623_i2c_groups[] = { "i2c0", "i2c1_0", "i2c1_1",
+						"i2c1_2", "i2c1_3", "i2c1_4",
+						"i2c2_0", "i2c2_1", "i2c2_2",
+						"i2c2_3", };
+static const char *const mt7623_i2s_groups[] = { "i2s0", "i2s1",
+						"i2s2_bclk_lrclk_mclk",
+						"i2s3_bclk_lrclk_mclk",
+						"i2s4", "i2s5",
+						"i2s2_data_in", "i2s3_data_in",
+						"i2s2_data_0", "i2s2_data_1",
+						"i2s3_data_0", "i2s3_data_1",};
+static const char *const mt7623_ir_groups[] = { "ir", };
+static const char *const mt7623_lcd_groups[] = { "dsi_te", "lcm_rst",
+						"mipi_tx", };
+static const char *const mt7623_msdc_groups[] = { "msdc0", "msdc1",
+						"msdc1_ins", "msdc1_wp_0",
+						"msdc1_wp_1", "msdc1_wp_2",
+						"msdc2", "msdc3", };
+static const char *const mt7623_nandc_groups[] = { "nandc", "nandc_ceb0",
+						"nandc_ceb1", };
+static const char *const mt7623_otg_groups[] = { "otg_iddig0_0",
+						"otg_iddig0_1",
+						"otg_iddig0_2",
+						"otg_iddig1_0",
+						"otg_iddig1_1",
+						"otg_iddig1_2",
+						"otg_drv_vbus0_0",
+						"otg_drv_vbus0_1",
+						"otg_drv_vbus0_2",
+						"otg_drv_vbus1_0",
+						"otg_drv_vbus1_1",
+						"otg_drv_vbus1_2", };
+static const char *const mt7623_pcie_groups[] = { "pcie0_0_perst",
+						"pcie0_1_perst",
+						"pcie1_0_perst",
+						"pcie1_1_perst",
+						"pcie2_0_perst",
+						"pcie2_1_perst",
+						"pcie0_0_rev_perst",
+						"pcie0_1_rev_perst",
+						"pcie1_0_rev_perst",
+						"pcie1_1_rev_perst",
+						"pcie2_0_rev_perst",
+						"pcie2_1_rev_perst",
+						"pcie0_0_wake", "pcie0_1_wake",
+						"pcie2_0_wake", "pcie2_1_wake",
+						"pcie0_clkreq", "pcie1_clkreq",
+						"pcie2_clkreq", };
+static const char *const mt7623_pcm_groups[] = { "pcm_clk_0", "pcm_clk_1",
+						"pcm_clk_2", "pcm_clk_3",
+						"pcm_clk_4", "pcm_clk_5",
+						"pcm_clk_6", "pcm_sync_0",
+						"pcm_sync_1", "pcm_sync_2",
+						"pcm_sync_3", "pcm_sync_4",
+						"pcm_sync_5", "pcm_sync_6",
+						"pcm_rx_0", "pcm_rx_1",
+						"pcm_rx_2", "pcm_rx_3",
+						"pcm_rx_4", "pcm_rx_5",
+						"pcm_rx_6", "pcm_tx_0",
+						"pcm_tx_1", "pcm_tx_2",
+						"pcm_tx_3", "pcm_tx_4",
+						"pcm_tx_5", "pcm_tx_6", };
+static const char *const mt7623_pwm_groups[] = { "pwm_ch1_0", "pwm_ch1_1",
+						"pwm_ch1_2", "pwm_ch2_0",
+						"pwm_ch2_1", "pwm_ch2_2",
+						"pwm_ch3_0", "pwm_ch3_1",
+						"pwm_ch3_2", "pwm_ch4_0",
+						"pwm_ch4_1", "pwm_ch4_2",
+						"pwm_ch4_3", "pwm_ch5_0",
+						"pwm_ch5_1", "pwm_ch5_2",
+						"pwm_ch6_0", "pwm_ch6_1",
+						"pwm_ch6_2", "pwm_ch6_3",
+						"pwm_ch7_0", "pwm_ch7_1",
+						"pwm_ch7_2", };
+static const char *const mt7623_pwrap_groups[] = { "pwrap", };
+static const char *const mt7623_rtc_groups[] = { "rtc", };
+static const char *const mt7623_spi_groups[] = { "spi0", "spi2", "spi2", };
+static const char *const mt7623_spdif_groups[] = { "spdif_in0_0",
+						"spdif_in0_1", "spdif_in1_0",
+						"spdif_in1_1", "spdif_out", };
+static const char *const mt7623_uart_groups[] = { "uart0_0_txd_rxd",
+						"uart0_1_txd_rxd",
+						"uart0_2_txd_rxd",
+						"uart0_3_txd_rxd",
+						"uart1_0_txd_rxd",
+						"uart1_1_txd_rxd",
+						"uart1_2_txd_rxd",
+						"uart2_0_txd_rxd",
+						"uart2_1_txd_rxd",
+						"uart3_txd_rxd",
+						"uart0_rts_cts",
+						"uart1_rts_cts",
+						"uart2_rts_cts",
+						"uart3_rts_cts", };
+static const char *const mt7623_wdt_groups[] = { "watchdog_0", "watchdog_1", };
+
+static const struct mtk_function_desc mt7623_functions[] = {
+	{"audck", mt7623_aud_clk_groups, ARRAY_SIZE(mt7623_aud_clk_groups)},
+	{"disp", mt7623_disp_pwm_groups, ARRAY_SIZE(mt7623_disp_pwm_groups)},
+	{"eth",	mt7623_ethernet_groups, ARRAY_SIZE(mt7623_ethernet_groups)},
+	{"sdio", mt7623_ext_sdio_groups, ARRAY_SIZE(mt7623_ext_sdio_groups)},
+	{"hdmi", mt7623_hdmi_groups, ARRAY_SIZE(mt7623_hdmi_groups)},
+	{"i2c", mt7623_i2c_groups, ARRAY_SIZE(mt7623_i2c_groups)},
+	{"i2s",	mt7623_i2s_groups, ARRAY_SIZE(mt7623_i2s_groups)},
+	{"ir",	mt7623_ir_groups, ARRAY_SIZE(mt7623_ir_groups)},
+	{"lcd", mt7623_lcd_groups, ARRAY_SIZE(mt7623_lcd_groups)},
+	{"msdc", mt7623_msdc_groups, ARRAY_SIZE(mt7623_msdc_groups)},
+	{"nand", mt7623_nandc_groups, ARRAY_SIZE(mt7623_nandc_groups)},
+	{"otg", mt7623_otg_groups, ARRAY_SIZE(mt7623_otg_groups)},
+	{"pcie", mt7623_pcie_groups, ARRAY_SIZE(mt7623_pcie_groups)},
+	{"pcm",	mt7623_pcm_groups, ARRAY_SIZE(mt7623_pcm_groups)},
+	{"pwm",	mt7623_pwm_groups, ARRAY_SIZE(mt7623_pwm_groups)},
+	{"pwrap", mt7623_pwrap_groups, ARRAY_SIZE(mt7623_pwrap_groups)},
+	{"rtc", mt7623_rtc_groups, ARRAY_SIZE(mt7623_rtc_groups)},
+	{"spi",	mt7623_spi_groups, ARRAY_SIZE(mt7623_spi_groups)},
+	{"spdif", mt7623_spdif_groups, ARRAY_SIZE(mt7623_spdif_groups)},
+	{"uart", mt7623_uart_groups, ARRAY_SIZE(mt7623_uart_groups)},
+	{"watchdog", mt7623_wdt_groups, ARRAY_SIZE(mt7623_wdt_groups)},
+};
+
+static struct mtk_pinctrl_soc mt7623_data = {
+	.name = "mt7623_pinctrl",
+	.reg_cal = mt7623_reg_cals,
+	.pins = mt7623_pins,
+	.npins = ARRAY_SIZE(mt7623_pins),
+	.grps = mt7623_groups,
+	.ngrps = ARRAY_SIZE(mt7623_groups),
+	.funcs = mt7623_functions,
+	.nfuncs = ARRAY_SIZE(mt7623_functions),
+};
+
+/*
+ * There are some specific pins have mux functions greater than 8,
+ * and if we want to switch thees high modes we need to disable
+ * bonding constraints firstly.
+ */
+static void mt7623_bonding_disable(struct udevice *dev)
+{
+	mtk_rmw(dev, PIN_BOND_REG0, BOND_PCIE_CLR, BOND_PCIE_CLR);
+	mtk_rmw(dev, PIN_BOND_REG1, BOND_I2S_CLR, BOND_I2S_CLR);
+	mtk_rmw(dev, PIN_BOND_REG2, BOND_MSDC0E_CLR, BOND_MSDC0E_CLR);
+}
+
+static int mtk_pinctrl_mt7623_probe(struct udevice *dev)
+{
+	int err;
+
+	err = mtk_pinctrl_common_probe(dev, &mt7623_data);
+	if (err)
+		return err;
+
+	mt7623_bonding_disable(dev);
+
+	return 0;
+}
+
+static const struct udevice_id mt7623_pctrl_match[] = {
+	{ .compatible = "mediatek,mt7623-pinctrl", },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(mt7623_pinctrl) = {
+	.name = "mt7623_pinctrl",
+	.id = UCLASS_PINCTRL,
+	.of_match = mt7623_pctrl_match,
+	.ops = &mtk_pinctrl_ops,
+	.probe = mtk_pinctrl_mt7623_probe,
+	.priv_auto_alloc_size = sizeof(struct mtk_pinctrl_priv),
+};
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7629.c b/drivers/pinctrl/mediatek/pinctrl-mt7629.c
new file mode 100644
index 0000000..aa6d1c2
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7629.c
@@ -0,0 +1,409 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <dm.h>
+
+#include "pinctrl-mtk-common.h"
+
+#define PIN_FIELD(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits)	\
+	PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit,	\
+		       _x_bits, 32, false)
+
+#define MT7629_PIN(_number, _name)	MTK_PIN(_number, _name, DRV_GRP1)
+
+static const struct mtk_pin_field_calc mt7629_pin_mode_range[] = {
+	PIN_FIELD(0, 78, 0x300, 0x10, 0, 4),
+};
+
+static const struct mtk_pin_field_calc mt7629_pin_dir_range[] = {
+	PIN_FIELD(0, 78, 0x0, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7629_pin_di_range[] = {
+	PIN_FIELD(0, 78, 0x200, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7629_pin_do_range[] = {
+	PIN_FIELD(0, 78, 0x100, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7629_pin_ies_range[] = {
+	PIN_FIELD(0, 10, 0x1000, 0x10, 0, 1),
+	PIN_FIELD(11, 18, 0x2000, 0x10, 0, 1),
+	PIN_FIELD(19, 32, 0x3000, 0x10, 0, 1),
+	PIN_FIELD(33, 48, 0x4000, 0x10, 0, 1),
+	PIN_FIELD(49, 50, 0x5000, 0x10, 0, 1),
+	PIN_FIELD(51, 69, 0x6000, 0x10, 0, 1),
+	PIN_FIELD(70, 78, 0x7000, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7629_pin_smt_range[] = {
+	PIN_FIELD(0, 10, 0x1100, 0x10, 0, 1),
+	PIN_FIELD(11, 18, 0x2100, 0x10, 0, 1),
+	PIN_FIELD(19, 32, 0x3100, 0x10, 0, 1),
+	PIN_FIELD(33, 48, 0x4100, 0x10, 0, 1),
+	PIN_FIELD(49, 50, 0x5100, 0x10, 0, 1),
+	PIN_FIELD(51, 69, 0x6100, 0x10, 0, 1),
+	PIN_FIELD(70, 78, 0x7100, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7629_pin_pullen_range[] = {
+	PIN_FIELD(0, 10, 0x1400, 0x10, 0, 1),
+	PIN_FIELD(11, 18, 0x2400, 0x10, 0, 1),
+	PIN_FIELD(19, 32, 0x3400, 0x10, 0, 1),
+	PIN_FIELD(33, 48, 0x4400, 0x10, 0, 1),
+	PIN_FIELD(49, 50, 0x5400, 0x10, 0, 1),
+	PIN_FIELD(51, 69, 0x6400, 0x10, 0, 1),
+	PIN_FIELD(70, 78, 0x7400, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7629_pin_pullsel_range[] = {
+	PIN_FIELD(0, 10, 0x1500, 0x10, 0, 1),
+	PIN_FIELD(11, 18, 0x2500, 0x10, 0, 1),
+	PIN_FIELD(19, 32, 0x3500, 0x10, 0, 1),
+	PIN_FIELD(33, 48, 0x4500, 0x10, 0, 1),
+	PIN_FIELD(49, 50, 0x5500, 0x10, 0, 1),
+	PIN_FIELD(51, 69, 0x6500, 0x10, 0, 1),
+	PIN_FIELD(70, 78, 0x7500, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7629_pin_drv_range[] = {
+	PIN_FIELD(0, 10, 0x1600, 0x10, 0, 4),
+	PIN_FIELD(11, 18, 0x2600, 0x10, 0, 4),
+	PIN_FIELD(19, 32, 0x3600, 0x10, 0, 4),
+	PIN_FIELD(33, 48, 0x4600, 0x10, 0, 4),
+	PIN_FIELD(49, 50, 0x5600, 0x10, 0, 4),
+	PIN_FIELD(51, 69, 0x6600, 0x10, 0, 4),
+	PIN_FIELD(70, 78, 0x7600, 0x10, 0, 4),
+};
+
+static const struct mtk_pin_reg_calc mt7629_reg_cals[] = {
+	[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7629_pin_mode_range),
+	[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7629_pin_dir_range),
+	[PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7629_pin_di_range),
+	[PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7629_pin_do_range),
+	[PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7629_pin_ies_range),
+	[PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7629_pin_smt_range),
+	[PINCTRL_PIN_REG_PULLSEL] = MTK_RANGE(mt7629_pin_pullsel_range),
+	[PINCTRL_PIN_REG_PULLEN] = MTK_RANGE(mt7629_pin_pullen_range),
+	[PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7629_pin_drv_range),
+};
+
+static const struct mtk_pin_desc mt7629_pins[] = {
+	MT7629_PIN(0, "TOP_5G_CLK"),
+	MT7629_PIN(1, "TOP_5G_DATA"),
+	MT7629_PIN(2, "WF0_5G_HB0"),
+	MT7629_PIN(3, "WF0_5G_HB1"),
+	MT7629_PIN(4, "WF0_5G_HB2"),
+	MT7629_PIN(5, "WF0_5G_HB3"),
+	MT7629_PIN(6, "WF0_5G_HB4"),
+	MT7629_PIN(7, "WF0_5G_HB5"),
+	MT7629_PIN(8, "WF0_5G_HB6"),
+	MT7629_PIN(9, "XO_REQ"),
+	MT7629_PIN(10, "TOP_RST_N"),
+	MT7629_PIN(11, "SYS_WATCHDOG"),
+	MT7629_PIN(12, "EPHY_LED0_N_JTDO"),
+	MT7629_PIN(13, "EPHY_LED1_N_JTDI"),
+	MT7629_PIN(14, "EPHY_LED2_N_JTMS"),
+	MT7629_PIN(15, "EPHY_LED3_N_JTCLK"),
+	MT7629_PIN(16, "EPHY_LED4_N_JTRST_N"),
+	MT7629_PIN(17, "WF2G_LED_N"),
+	MT7629_PIN(18, "WF5G_LED_N"),
+	MT7629_PIN(19, "I2C_SDA"),
+	MT7629_PIN(20, "I2C_SCL"),
+	MT7629_PIN(21, "GPIO_9"),
+	MT7629_PIN(22, "GPIO_10"),
+	MT7629_PIN(23, "GPIO_11"),
+	MT7629_PIN(24, "GPIO_12"),
+	MT7629_PIN(25, "UART1_TXD"),
+	MT7629_PIN(26, "UART1_RXD"),
+	MT7629_PIN(27, "UART1_CTS"),
+	MT7629_PIN(28, "UART1_RTS"),
+	MT7629_PIN(29, "UART2_TXD"),
+	MT7629_PIN(30, "UART2_RXD"),
+	MT7629_PIN(31, "UART2_CTS"),
+	MT7629_PIN(32, "UART2_RTS"),
+	MT7629_PIN(33, "MDI_TP_P1"),
+	MT7629_PIN(34, "MDI_TN_P1"),
+	MT7629_PIN(35, "MDI_RP_P1"),
+	MT7629_PIN(36, "MDI_RN_P1"),
+	MT7629_PIN(37, "MDI_RP_P2"),
+	MT7629_PIN(38, "MDI_RN_P2"),
+	MT7629_PIN(39, "MDI_TP_P2"),
+	MT7629_PIN(40, "MDI_TN_P2"),
+	MT7629_PIN(41, "MDI_TP_P3"),
+	MT7629_PIN(42, "MDI_TN_P3"),
+	MT7629_PIN(43, "MDI_RP_P3"),
+	MT7629_PIN(44, "MDI_RN_P3"),
+	MT7629_PIN(45, "MDI_RP_P4"),
+	MT7629_PIN(46, "MDI_RN_P4"),
+	MT7629_PIN(47, "MDI_TP_P4"),
+	MT7629_PIN(48, "MDI_TN_P4"),
+	MT7629_PIN(49, "SMI_MDC"),
+	MT7629_PIN(50, "SMI_MDIO"),
+	MT7629_PIN(51, "PCIE_PERESET_N"),
+	MT7629_PIN(52, "PWM_0"),
+	MT7629_PIN(53, "GPIO_0"),
+	MT7629_PIN(54, "GPIO_1"),
+	MT7629_PIN(55, "GPIO_2"),
+	MT7629_PIN(56, "GPIO_3"),
+	MT7629_PIN(57, "GPIO_4"),
+	MT7629_PIN(58, "GPIO_5"),
+	MT7629_PIN(59, "GPIO_6"),
+	MT7629_PIN(60, "GPIO_7"),
+	MT7629_PIN(61, "GPIO_8"),
+	MT7629_PIN(62, "SPI_CLK"),
+	MT7629_PIN(63, "SPI_CS"),
+	MT7629_PIN(64, "SPI_MOSI"),
+	MT7629_PIN(65, "SPI_MISO"),
+	MT7629_PIN(66, "SPI_WP"),
+	MT7629_PIN(67, "SPI_HOLD"),
+	MT7629_PIN(68, "UART0_TXD"),
+	MT7629_PIN(69, "UART0_RXD"),
+	MT7629_PIN(70, "TOP_2G_CLK"),
+	MT7629_PIN(71, "TOP_2G_DATA"),
+	MT7629_PIN(72, "WF0_2G_HB0"),
+	MT7629_PIN(73, "WF0_2G_HB1"),
+	MT7629_PIN(74, "WF0_2G_HB2"),
+	MT7629_PIN(75, "WF0_2G_HB3"),
+	MT7629_PIN(76, "WF0_2G_HB4"),
+	MT7629_PIN(77, "WF0_2G_HB5"),
+	MT7629_PIN(78, "WF0_2G_HB6"),
+};
+
+/* List all groups consisting of these pins dedicated to the enablement of
+ * certain hardware block and the corresponding mode for all of the pins.
+ * The hardware probably has multiple combinations of these pinouts.
+ */
+
+/* WF 5G */
+static int mt7629_wf0_5g_pins[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, };
+static int mt7629_wf0_5g_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+/* LED for EPHY */
+static int mt7629_ephy_leds_pins[] = { 12, 13, 14, 15, 16, 17, 18, };
+static int mt7629_ephy_leds_funcs[] = { 1, 1, 1, 1, 1, 1, 1, };
+static int mt7629_ephy_led0_pins[] = { 12, };
+static int mt7629_ephy_led0_funcs[] = { 1, };
+static int mt7629_ephy_led1_pins[] = { 13, };
+static int mt7629_ephy_led1_funcs[] = { 1, };
+static int mt7629_ephy_led2_pins[] = { 14, };
+static int mt7629_ephy_led2_funcs[] = { 1, };
+static int mt7629_ephy_led3_pins[] = { 15, };
+static int mt7629_ephy_led3_funcs[] = { 1, };
+static int mt7629_ephy_led4_pins[] = { 16, };
+static int mt7629_ephy_led4_funcs[] = { 1, };
+static int mt7629_wf2g_led_pins[] = { 17, };
+static int mt7629_wf2g_led_funcs[] = { 1, };
+static int mt7629_wf5g_led_pins[] = { 18, };
+static int mt7629_wf5g_led_funcs[] = { 1, };
+
+/* Watchdog */
+static int mt7629_watchdog_pins[] = { 11, };
+static int mt7629_watchdog_funcs[] = { 1, };
+
+/* LED for GPHY */
+static int mt7629_gphy_leds_0_pins[] = { 21, 22, 23, };
+static int mt7629_gphy_leds_0_funcs[] = { 2, 2, 2, };
+static int mt7629_gphy_led1_0_pins[] = { 21, };
+static int mt7629_gphy_led1_0_funcs[] = { 2, };
+static int mt7629_gphy_led2_0_pins[] = { 22, };
+static int mt7629_gphy_led2_0_funcs[] = { 2, };
+static int mt7629_gphy_led3_0_pins[] = { 23, };
+static int mt7629_gphy_led3_0_funcs[] = { 2, };
+static int mt7629_gphy_leds_1_pins[] = { 57, 58, 59, };
+static int mt7629_gphy_leds_1_funcs[] = { 1, 1, 1, };
+static int mt7629_gphy_led1_1_pins[] = { 57, };
+static int mt7629_gphy_led1_1_funcs[] = { 1, };
+static int mt7629_gphy_led2_1_pins[] = { 58, };
+static int mt7629_gphy_led2_1_funcs[] = { 1, };
+static int mt7629_gphy_led3_1_pins[] = { 59, };
+static int mt7629_gphy_led3_1_funcs[] = { 1, };
+
+/* I2C */
+static int mt7629_i2c_0_pins[] = { 19, 20, };
+static int mt7629_i2c_0_funcs[] = { 1, 1, };
+static int mt7629_i2c_1_pins[] = { 53, 54, };
+static int mt7629_i2c_1_funcs[] = { 1, 1, };
+
+/* SPI */
+static int mt7629_spi_0_pins[] = { 21, 22, 23, 24, };
+static int mt7629_spi_0_funcs[] = { 1, 1, 1, 1, };
+static int mt7629_spi_1_pins[] = { 62, 63, 64, 65, };
+static int mt7629_spi_1_funcs[] = { 1, 1, 1, 1, };
+static int mt7629_spi_wp_pins[] = { 66, };
+static int mt7629_spi_wp_funcs[] = { 1, };
+static int mt7629_spi_hold_pins[] = { 67, };
+static int mt7629_spi_hold_funcs[] = { 1, };
+
+/* UART */
+static int mt7629_uart1_0_txd_rxd_pins[] = { 25, 26, };
+static int mt7629_uart1_0_txd_rxd_funcs[] = { 1, 1, };
+static int mt7629_uart1_1_txd_rxd_pins[] = { 53, 54, };
+static int mt7629_uart1_1_txd_rxd_funcs[] = { 2, 2, };
+static int mt7629_uart2_0_txd_rxd_pins[] = { 29, 30, };
+static int mt7629_uart2_0_txd_rxd_funcs[] = { 1, 1, };
+static int mt7629_uart2_1_txd_rxd_pins[] = { 57, 58, };
+static int mt7629_uart2_1_txd_rxd_funcs[] = { 2, 2, };
+static int mt7629_uart1_0_cts_rts_pins[] = { 27, 28, };
+static int mt7629_uart1_0_cts_rts_funcs[] = { 1, 1, };
+static int mt7629_uart1_1_cts_rts_pins[] = { 55, 56, };
+static int mt7629_uart1_1_cts_rts_funcs[] = { 2, 2, };
+static int mt7629_uart2_0_cts_rts_pins[] = { 31, 32, };
+static int mt7629_uart2_0_cts_rts_funcs[] = { 1, 1, };
+static int mt7629_uart2_1_cts_rts_pins[] = { 59, 60, };
+static int mt7629_uart2_1_cts_rts_funcs[] = { 2, 2, };
+static int mt7629_uart0_txd_rxd_pins[] = { 68, 69, };
+static int mt7629_uart0_txd_rxd_funcs[] = { 1, 1, };
+
+/* MDC/MDIO */
+static int mt7629_mdc_mdio_pins[] = { 49, 50, };
+static int mt7629_mdc_mdio_funcs[] = { 1, 1, };
+
+/* PCIE */
+static int mt7629_pcie_pereset_pins[] = { 51, };
+static int mt7629_pcie_pereset_funcs[] = { 1, };
+static int mt7629_pcie_wake_pins[] = { 55, };
+static int mt7629_pcie_wake_funcs[] = { 1, };
+static int mt7629_pcie_clkreq_pins[] = { 56, };
+static int mt7629_pcie_clkreq_funcs[] = { 1, };
+
+/* PWM */
+static int mt7629_pwm_0_pins[] = { 52, };
+static int mt7629_pwm_0_funcs[] = { 1, };
+static int mt7629_pwm_1_pins[] = { 61, };
+static int mt7629_pwm_1_funcs[] = { 2, };
+
+/* WF 2G */
+static int mt7629_wf0_2g_pins[] = { 70, 71, 72, 73, 74, 75, 76, 77, 78, };
+static int mt7629_wf0_2g_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, };
+
+/* SNFI */
+static int mt7629_snfi_pins[] = { 62, 63, 64, 65, 66, 67 };
+static int mt7629_snfi_funcs[] = { 2, 2, 2, 2, 2, 2 };
+
+/* SPI NOR */
+static int mt7629_snor_pins[] = { 62, 63, 64, 65, 66, 67 };
+static int mt7629_snor_funcs[] = { 1, 1, 1, 1, 1, 1 };
+
+static const struct mtk_group_desc mt7629_groups[] = {
+	PINCTRL_PIN_GROUP("wf0_5g", mt7629_wf0_5g),
+	PINCTRL_PIN_GROUP("ephy_leds", mt7629_ephy_leds),
+	PINCTRL_PIN_GROUP("ephy_led0", mt7629_ephy_led0),
+	PINCTRL_PIN_GROUP("ephy_led1", mt7629_ephy_led1),
+	PINCTRL_PIN_GROUP("ephy_led2", mt7629_ephy_led2),
+	PINCTRL_PIN_GROUP("ephy_led3", mt7629_ephy_led3),
+	PINCTRL_PIN_GROUP("ephy_led4", mt7629_ephy_led4),
+	PINCTRL_PIN_GROUP("wf2g_led", mt7629_wf2g_led),
+	PINCTRL_PIN_GROUP("wf5g_led", mt7629_wf5g_led),
+	PINCTRL_PIN_GROUP("watchdog", mt7629_watchdog),
+	PINCTRL_PIN_GROUP("gphy_leds_0", mt7629_gphy_leds_0),
+	PINCTRL_PIN_GROUP("gphy_led1_0", mt7629_gphy_led1_0),
+	PINCTRL_PIN_GROUP("gphy_led2_0", mt7629_gphy_led2_0),
+	PINCTRL_PIN_GROUP("gphy_led3_0", mt7629_gphy_led3_0),
+	PINCTRL_PIN_GROUP("gphy_leds_1", mt7629_gphy_leds_1),
+	PINCTRL_PIN_GROUP("gphy_led1_1", mt7629_gphy_led1_1),
+	PINCTRL_PIN_GROUP("gphy_led2_1", mt7629_gphy_led2_1),
+	PINCTRL_PIN_GROUP("gphy_led3_1", mt7629_gphy_led3_1),
+	PINCTRL_PIN_GROUP("i2c_0", mt7629_i2c_0),
+	PINCTRL_PIN_GROUP("i2c_1", mt7629_i2c_1),
+	PINCTRL_PIN_GROUP("spi_0", mt7629_spi_0),
+	PINCTRL_PIN_GROUP("spi_1", mt7629_spi_1),
+	PINCTRL_PIN_GROUP("spi_wp", mt7629_spi_wp),
+	PINCTRL_PIN_GROUP("spi_hold", mt7629_spi_hold),
+	PINCTRL_PIN_GROUP("uart1_0_txd_rxd", mt7629_uart1_0_txd_rxd),
+	PINCTRL_PIN_GROUP("uart1_1_txd_rxd", mt7629_uart1_1_txd_rxd),
+	PINCTRL_PIN_GROUP("uart2_0_txd_rxd", mt7629_uart2_0_txd_rxd),
+	PINCTRL_PIN_GROUP("uart2_1_txd_rxd", mt7629_uart2_1_txd_rxd),
+	PINCTRL_PIN_GROUP("uart1_0_cts_rts", mt7629_uart1_0_cts_rts),
+	PINCTRL_PIN_GROUP("uart1_1_cts_rts", mt7629_uart1_1_cts_rts),
+	PINCTRL_PIN_GROUP("uart2_0_cts_rts", mt7629_uart2_0_cts_rts),
+	PINCTRL_PIN_GROUP("uart2_1_cts_rts", mt7629_uart2_1_cts_rts),
+	PINCTRL_PIN_GROUP("uart0_txd_rxd", mt7629_uart0_txd_rxd),
+	PINCTRL_PIN_GROUP("mdc_mdio", mt7629_mdc_mdio),
+	PINCTRL_PIN_GROUP("pcie_pereset", mt7629_pcie_pereset),
+	PINCTRL_PIN_GROUP("pcie_wake", mt7629_pcie_wake),
+	PINCTRL_PIN_GROUP("pcie_clkreq", mt7629_pcie_clkreq),
+	PINCTRL_PIN_GROUP("pwm_0", mt7629_pwm_0),
+	PINCTRL_PIN_GROUP("pwm_1", mt7629_pwm_1),
+	PINCTRL_PIN_GROUP("wf0_2g", mt7629_wf0_2g),
+	PINCTRL_PIN_GROUP("snfi", mt7629_snfi),
+	PINCTRL_PIN_GROUP("spi_nor", mt7629_snor),
+};
+
+/* Joint those groups owning the same capability in user point of view which
+ * allows that people tend to use through the device tree.
+ */
+static const char *const mt7629_ethernet_groups[] = { "mdc_mdio", };
+static const char *const mt7629_i2c_groups[] = { "i2c_0", "i2c_1", };
+static const char *const mt7629_led_groups[] = { "ephy_leds", "ephy_led0",
+						"ephy_led1", "ephy_led2",
+						"ephy_led3", "ephy_led4",
+						"wf2g_led", "wf5g_led",
+						"gphy_leds_0", "gphy_led1_0",
+						"gphy_led2_0", "gphy_led3_0",
+						"gphy_leds_1", "gphy_led1_1",
+						"gphy_led2_1", "gphy_led3_1",};
+static const char *const mt7629_pcie_groups[] = { "pcie_pereset", "pcie_wake",
+						"pcie_clkreq", };
+static const char *const mt7629_pwm_groups[] = { "pwm_0", "pwm_1", };
+static const char *const mt7629_spi_groups[] = { "spi_0", "spi_1", "spi_wp",
+						"spi_hold", };
+static const char *const mt7629_uart_groups[] = { "uart1_0_txd_rxd",
+						"uart1_1_txd_rxd",
+						"uart2_0_txd_rxd",
+						"uart2_1_txd_rxd",
+						"uart1_0_cts_rts",
+						"uart1_1_cts_rts",
+						"uart2_0_cts_rts",
+						"uart2_1_cts_rts",
+						"uart0_txd_rxd", };
+static const char *const mt7629_wdt_groups[] = { "watchdog", };
+static const char *const mt7629_wifi_groups[] = { "wf0_5g", "wf0_2g", };
+static const char *const mt7629_flash_groups[] = { "snfi", "spi_nor" };
+
+static const struct mtk_function_desc mt7629_functions[] = {
+	{"eth",	mt7629_ethernet_groups, ARRAY_SIZE(mt7629_ethernet_groups)},
+	{"i2c", mt7629_i2c_groups, ARRAY_SIZE(mt7629_i2c_groups)},
+	{"led",	mt7629_led_groups, ARRAY_SIZE(mt7629_led_groups)},
+	{"pcie", mt7629_pcie_groups, ARRAY_SIZE(mt7629_pcie_groups)},
+	{"pwm",	mt7629_pwm_groups, ARRAY_SIZE(mt7629_pwm_groups)},
+	{"spi",	mt7629_spi_groups, ARRAY_SIZE(mt7629_spi_groups)},
+	{"uart", mt7629_uart_groups, ARRAY_SIZE(mt7629_uart_groups)},
+	{"watchdog", mt7629_wdt_groups, ARRAY_SIZE(mt7629_wdt_groups)},
+	{"wifi", mt7629_wifi_groups, ARRAY_SIZE(mt7629_wifi_groups)},
+	{"flash", mt7629_flash_groups, ARRAY_SIZE(mt7629_flash_groups)},
+};
+
+static struct mtk_pinctrl_soc mt7629_data = {
+	.name = "mt7629_pinctrl",
+	.reg_cal = mt7629_reg_cals,
+	.pins = mt7629_pins,
+	.npins = ARRAY_SIZE(mt7629_pins),
+	.grps = mt7629_groups,
+	.ngrps = ARRAY_SIZE(mt7629_groups),
+	.funcs = mt7629_functions,
+	.nfuncs = ARRAY_SIZE(mt7629_functions),
+};
+
+static int mtk_pinctrl_mt7629_probe(struct udevice *dev)
+{
+	return mtk_pinctrl_common_probe(dev, &mt7629_data);
+}
+
+static const struct udevice_id mt7629_pctrl_match[] = {
+	{ .compatible = "mediatek,mt7629-pinctrl" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(mt7629_pinctrl) = {
+	.name = "mt7629_pinctrl",
+	.id = UCLASS_PINCTRL,
+	.of_match = mt7629_pctrl_match,
+	.ops = &mtk_pinctrl_ops,
+	.probe = mtk_pinctrl_mt7629_probe,
+	.priv_auto_alloc_size = sizeof(struct mtk_pinctrl_priv),
+};
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
new file mode 100644
index 0000000..938cc75
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -0,0 +1,553 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/pinctrl.h>
+#include <asm/io.h>
+#include <asm-generic/gpio.h>
+
+#include "pinctrl-mtk-common.h"
+
+/**
+ * struct mtk_drive_desc - the structure that holds the information
+ *			    of the driving current
+ * @min:	the minimum current of this group
+ * @max:	the maximum current of this group
+ * @step:	the step current of this group
+ * @scal:	the weight factor
+ *
+ * formula: output = ((input) / step - 1) * scal
+ */
+struct mtk_drive_desc {
+	u8 min;
+	u8 max;
+	u8 step;
+	u8 scal;
+};
+
+/* The groups of drive strength */
+static const struct mtk_drive_desc mtk_drive[] = {
+	[DRV_GRP0] = { 4, 16, 4, 1 },
+	[DRV_GRP1] = { 4, 16, 4, 2 },
+	[DRV_GRP2] = { 2, 8, 2, 1 },
+	[DRV_GRP3] = { 2, 8, 2, 2 },
+	[DRV_GRP4] = { 2, 16, 2, 1 },
+};
+
+static const char *mtk_pinctrl_dummy_name = "_dummy";
+
+static void mtk_w32(struct udevice *dev, u32 reg, u32 val)
+{
+	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+
+	__raw_writel(val, priv->base + reg);
+}
+
+static u32 mtk_r32(struct udevice *dev, u32 reg)
+{
+	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+
+	return __raw_readl(priv->base + reg);
+}
+
+static inline int get_count_order(unsigned int count)
+{
+	int order;
+
+	order = fls(count) - 1;
+	if (count & (count - 1))
+		order++;
+	return order;
+}
+
+void mtk_rmw(struct udevice *dev, u32 reg, u32 mask, u32 set)
+{
+	u32 val;
+
+	val = mtk_r32(dev, reg);
+	val &= ~mask;
+	val |= set;
+	mtk_w32(dev, reg, val);
+}
+
+static int mtk_hw_pin_field_lookup(struct udevice *dev, int pin,
+				   const struct mtk_pin_reg_calc *rc,
+				   struct mtk_pin_field *pfd)
+{
+	const struct mtk_pin_field_calc *c, *e;
+	u32 bits;
+
+	c = rc->range;
+	e = c + rc->nranges;
+
+	while (c < e) {
+		if (pin >= c->s_pin && pin <= c->e_pin)
+			break;
+		c++;
+	}
+
+	if (c >= e)
+		return -EINVAL;
+
+	/* Calculated bits as the overall offset the pin is located at,
+	 * if c->fixed is held, that determines the all the pins in the
+	 * range use the same field with the s_pin.
+	 */
+	bits = c->fixed ? c->s_bit : c->s_bit + (pin - c->s_pin) * (c->x_bits);
+
+	/* Fill pfd from bits. For example 32-bit register applied is assumed
+	 * when c->sz_reg is equal to 32.
+	 */
+	pfd->offset = c->s_addr + c->x_addrs * (bits / c->sz_reg);
+	pfd->bitpos = bits % c->sz_reg;
+	pfd->mask = (1 << c->x_bits) - 1;
+
+	/* pfd->next is used for indicating that bit wrapping-around happens
+	 * which requires the manipulation for bit 0 starting in the next
+	 * register to form the complete field read/write.
+	 */
+	pfd->next = pfd->bitpos + c->x_bits > c->sz_reg ? c->x_addrs : 0;
+
+	return 0;
+}
+
+static int mtk_hw_pin_field_get(struct udevice *dev, int pin,
+				int field, struct mtk_pin_field *pfd)
+{
+	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+	const struct mtk_pin_reg_calc *rc;
+
+	if (field < 0 || field >= PINCTRL_PIN_REG_MAX)
+		return -EINVAL;
+
+	if (priv->soc->reg_cal && priv->soc->reg_cal[field].range)
+		rc = &priv->soc->reg_cal[field];
+	else
+		return -EINVAL;
+
+	return mtk_hw_pin_field_lookup(dev, pin, rc, pfd);
+}
+
+static void mtk_hw_bits_part(struct mtk_pin_field *pf, int *h, int *l)
+{
+	*l = 32 - pf->bitpos;
+	*h = get_count_order(pf->mask) - *l;
+}
+
+static void mtk_hw_write_cross_field(struct udevice *dev,
+				     struct mtk_pin_field *pf, int value)
+{
+	int nbits_l, nbits_h;
+
+	mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
+
+	mtk_rmw(dev, pf->offset, pf->mask << pf->bitpos,
+		(value & pf->mask) << pf->bitpos);
+
+	mtk_rmw(dev, pf->offset + pf->next, BIT(nbits_h) - 1,
+		(value & pf->mask) >> nbits_l);
+}
+
+static void mtk_hw_read_cross_field(struct udevice *dev,
+				    struct mtk_pin_field *pf, int *value)
+{
+	int nbits_l, nbits_h, h, l;
+
+	mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
+
+	l  = (mtk_r32(dev, pf->offset) >> pf->bitpos) & (BIT(nbits_l) - 1);
+	h  = (mtk_r32(dev, pf->offset + pf->next)) & (BIT(nbits_h) - 1);
+
+	*value = (h << nbits_l) | l;
+}
+
+static int mtk_hw_set_value(struct udevice *dev, int pin, int field,
+			    int value)
+{
+	struct mtk_pin_field pf;
+	int err;
+
+	err = mtk_hw_pin_field_get(dev, pin, field, &pf);
+	if (err)
+		return err;
+
+	if (!pf.next)
+		mtk_rmw(dev, pf.offset, pf.mask << pf.bitpos,
+			(value & pf.mask) << pf.bitpos);
+	else
+		mtk_hw_write_cross_field(dev, &pf, value);
+
+	return 0;
+}
+
+static int mtk_hw_get_value(struct udevice *dev, int pin, int field,
+			    int *value)
+{
+	struct mtk_pin_field pf;
+	int err;
+
+	err = mtk_hw_pin_field_get(dev, pin, field, &pf);
+	if (err)
+		return err;
+
+	if (!pf.next)
+		*value = (mtk_r32(dev, pf.offset) >> pf.bitpos) & pf.mask;
+	else
+		mtk_hw_read_cross_field(dev, &pf, value);
+
+	return 0;
+}
+
+static int mtk_get_groups_count(struct udevice *dev)
+{
+	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+
+	return priv->soc->ngrps;
+}
+
+static const char *mtk_get_pin_name(struct udevice *dev,
+				    unsigned int selector)
+{
+	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+
+	if (!priv->soc->grps[selector].name)
+		return mtk_pinctrl_dummy_name;
+
+	return priv->soc->pins[selector].name;
+}
+
+static int mtk_get_pins_count(struct udevice *dev)
+{
+	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+
+	return priv->soc->npins;
+}
+
+static const char *mtk_get_group_name(struct udevice *dev,
+				      unsigned int selector)
+{
+	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+
+	if (!priv->soc->grps[selector].name)
+		return mtk_pinctrl_dummy_name;
+
+	return priv->soc->grps[selector].name;
+}
+
+static int mtk_get_functions_count(struct udevice *dev)
+{
+	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+
+	return priv->soc->nfuncs;
+}
+
+static const char *mtk_get_function_name(struct udevice *dev,
+					 unsigned int selector)
+{
+	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+
+	if (!priv->soc->funcs[selector].name)
+		return mtk_pinctrl_dummy_name;
+
+	return priv->soc->funcs[selector].name;
+}
+
+static int mtk_pinmux_group_set(struct udevice *dev,
+				unsigned int group_selector,
+				unsigned int func_selector)
+{
+	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+	const struct mtk_group_desc *grp =
+			&priv->soc->grps[group_selector];
+	int i;
+
+	for (i = 0; i < grp->num_pins; i++) {
+		int *pin_modes = grp->data;
+
+		mtk_hw_set_value(dev, grp->pins[i], PINCTRL_PIN_REG_MODE,
+				 pin_modes[i]);
+	}
+
+	return 0;
+}
+
+#if CONFIG_IS_ENABLED(PINCONF)
+static const struct pinconf_param mtk_conf_params[] = {
+	{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
+	{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
+	{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
+	{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
+	{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
+	{ "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
+	{ "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
+	{ "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 },
+	{ "output-high", PIN_CONFIG_OUTPUT, 1, },
+	{ "output-low", PIN_CONFIG_OUTPUT, 0, },
+	{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
+};
+
+int mtk_pinconf_drive_set(struct udevice *dev, u32 pin, u32 arg)
+{
+	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+	const struct mtk_pin_desc *desc = &priv->soc->pins[pin];
+	const struct mtk_drive_desc *tb;
+	int err = -ENOTSUPP;
+
+	tb = &mtk_drive[desc->drv_n];
+	/* 4mA when (e8, e4) = (0, 0)
+	 * 8mA when (e8, e4) = (0, 1)
+	 * 12mA when (e8, e4) = (1, 0)
+	 * 16mA when (e8, e4) = (1, 1)
+	 */
+	if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
+		arg = (arg / tb->step - 1) * tb->scal;
+
+		err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DRV, arg);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static int mtk_pinconf_set(struct udevice *dev, unsigned int pin,
+			   unsigned int param, unsigned int arg)
+{
+	int err = 0;
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+	case PIN_CONFIG_BIAS_PULL_UP:
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		arg = (param == PIN_CONFIG_BIAS_DISABLE) ? 0 :
+			(param == PIN_CONFIG_BIAS_PULL_UP) ? 3 : 2;
+
+		err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLSEL,
+				       arg & 1);
+		if (err)
+			goto err;
+
+		err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLEN,
+				       !!(arg & 2));
+		if (err)
+			goto err;
+		break;
+	case PIN_CONFIG_OUTPUT_ENABLE:
+		err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_SMT, 0);
+		if (err)
+			goto err;
+		err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 1);
+		if (err)
+			goto err;
+		break;
+	case PIN_CONFIG_INPUT_ENABLE:
+		err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_IES, 1);
+		if (err)
+			goto err;
+		err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 0);
+		if (err)
+			goto err;
+		break;
+	case PIN_CONFIG_OUTPUT:
+		err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 1);
+		if (err)
+			goto err;
+
+		err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DO, arg);
+		if (err)
+			goto err;
+		break;
+	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+		/* arg = 1: Input mode & SMT enable ;
+		 * arg = 0: Output mode & SMT disable
+		 */
+		arg = arg ? 2 : 1;
+		err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR,
+				       arg & 1);
+		if (err)
+			goto err;
+
+		err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_SMT,
+				       !!(arg & 2));
+		if (err)
+			goto err;
+		break;
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		err = mtk_pinconf_drive_set(dev, pin, arg);
+		if (err)
+			goto err;
+		break;
+
+	default:
+		err = -ENOTSUPP;
+	}
+
+err:
+
+	return err;
+}
+
+static int mtk_pinconf_group_set(struct udevice *dev,
+				 unsigned int group_selector,
+				 unsigned int param, unsigned int arg)
+{
+	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+	const struct mtk_group_desc *grp =
+			&priv->soc->grps[group_selector];
+	int i, ret;
+
+	for (i = 0; i < grp->num_pins; i++) {
+		ret = mtk_pinconf_set(dev, grp->pins[i], param, arg);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+#endif
+
+const struct pinctrl_ops mtk_pinctrl_ops = {
+	.get_pins_count = mtk_get_pins_count,
+	.get_pin_name = mtk_get_pin_name,
+	.get_groups_count = mtk_get_groups_count,
+	.get_group_name = mtk_get_group_name,
+	.get_functions_count = mtk_get_functions_count,
+	.get_function_name = mtk_get_function_name,
+	.pinmux_group_set = mtk_pinmux_group_set,
+#if CONFIG_IS_ENABLED(PINCONF)
+	.pinconf_num_params = ARRAY_SIZE(mtk_conf_params),
+	.pinconf_params = mtk_conf_params,
+	.pinconf_set = mtk_pinconf_set,
+	.pinconf_group_set = mtk_pinconf_group_set,
+#endif
+	.set_state = pinctrl_generic_set_state,
+};
+
+static int mtk_gpio_get(struct udevice *dev, unsigned int off)
+{
+	int val, err;
+
+	err = mtk_hw_get_value(dev->parent, off, PINCTRL_PIN_REG_DI, &val);
+	if (err)
+		return err;
+
+	return !!val;
+}
+
+static int mtk_gpio_set(struct udevice *dev, unsigned int off, int val)
+{
+	return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DO, !!val);
+}
+
+static int mtk_gpio_get_direction(struct udevice *dev, unsigned int off)
+{
+	int val, err;
+
+	err = mtk_hw_get_value(dev->parent, off, PINCTRL_PIN_REG_DIR, &val);
+	if (err)
+		return err;
+
+	return val ? GPIOF_OUTPUT : GPIOF_INPUT;
+}
+
+static int mtk_gpio_direction_input(struct udevice *dev, unsigned int off)
+{
+	return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DIR, 0);
+}
+
+static int mtk_gpio_direction_output(struct udevice *dev,
+				     unsigned int off, int val)
+{
+	mtk_gpio_set(dev, off, val);
+
+	/* And set the requested value */
+	return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DIR, 1);
+}
+
+static int mtk_gpio_request(struct udevice *dev, unsigned int off,
+			    const char *label)
+{
+	return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_MODE, 0);
+}
+
+static int mtk_gpio_probe(struct udevice *dev)
+{
+	struct mtk_pinctrl_priv *priv = dev_get_priv(dev->parent);
+	struct gpio_dev_priv *uc_priv;
+
+	uc_priv = dev_get_uclass_priv(dev);
+	uc_priv->bank_name = priv->soc->name;
+	uc_priv->gpio_count = priv->soc->npins;
+
+	return 0;
+}
+
+static const struct dm_gpio_ops mtk_gpio_ops = {
+	.request = mtk_gpio_request,
+	.set_value = mtk_gpio_set,
+	.get_value = mtk_gpio_get,
+	.get_function = mtk_gpio_get_direction,
+	.direction_input = mtk_gpio_direction_input,
+	.direction_output = mtk_gpio_direction_output,
+};
+
+static struct driver mtk_gpio_driver = {
+	.name = "mediatek_gpio",
+	.id	= UCLASS_GPIO,
+	.probe = mtk_gpio_probe,
+	.ops = &mtk_gpio_ops,
+};
+
+static int mtk_gpiochip_register(struct udevice *parent)
+{
+	struct uclass_driver *drv;
+	struct udevice *dev;
+	int ret;
+	ofnode node;
+
+	drv = lists_uclass_lookup(UCLASS_GPIO);
+	if (!drv)
+		return -ENOENT;
+
+	dev_for_each_subnode(node, parent)
+		if (ofnode_read_bool(node, "gpio-controller")) {
+			ret = 0;
+			break;
+		}
+
+	if (ret)
+		return ret;
+
+	ret = device_bind_with_driver_data(parent, &mtk_gpio_driver,
+					   "mediatek_gpio", 0, node,
+					   &dev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int mtk_pinctrl_common_probe(struct udevice *dev,
+			     struct mtk_pinctrl_soc *soc)
+{
+	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	priv->base = dev_read_addr_ptr(dev);
+	if (priv->base == (void *)FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->soc = soc;
+
+	ret = mtk_gpiochip_register(dev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
new file mode 100644
index 0000000..86559f0
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
@@ -0,0 +1,184 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#ifndef __PINCTRL_MEDIATEK_H__
+#define __PINCTRL_MEDIATEK_H__
+
+#define MTK_RANGE(_a)		{ .range = (_a), .nranges = ARRAY_SIZE(_a), }
+#define MTK_PIN(_number, _name, _drv_n) {				\
+		.number = _number,					\
+		.name = _name,						\
+		.drv_n = _drv_n,					\
+	}
+
+#define PINCTRL_PIN_GROUP(name, id)					\
+	{								\
+		name,							\
+		id##_pins,						\
+		ARRAY_SIZE(id##_pins),					\
+		id##_funcs,						\
+	}
+
+#define PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit,	\
+			_x_bits, _sz_reg, _fixed) {			\
+		.s_pin = _s_pin,					\
+		.e_pin = _e_pin,					\
+		.s_addr = _s_addr,					\
+		.x_addrs = _x_addrs,					\
+		.s_bit = _s_bit,					\
+		.x_bits = _x_bits,					\
+		.sz_reg = _sz_reg,					\
+		.fixed = _fixed,					\
+	}
+
+/* List these attributes which could be modified for the pin */
+enum {
+	PINCTRL_PIN_REG_MODE,
+	PINCTRL_PIN_REG_DIR,
+	PINCTRL_PIN_REG_DI,
+	PINCTRL_PIN_REG_DO,
+	PINCTRL_PIN_REG_IES,
+	PINCTRL_PIN_REG_SMT,
+	PINCTRL_PIN_REG_PULLEN,
+	PINCTRL_PIN_REG_PULLSEL,
+	PINCTRL_PIN_REG_DRV,
+	PINCTRL_PIN_REG_MAX,
+};
+
+/* Group the pins by the driving current */
+enum {
+	DRV_FIXED,
+	DRV_GRP0,
+	DRV_GRP1,
+	DRV_GRP2,
+	DRV_GRP3,
+	DRV_GRP4,
+};
+
+/**
+ * struct mtk_pin_field - the structure that holds the information of the field
+ *			  used to describe the attribute for the pin
+ * @offset:		the register offset relative to the base address
+ * @mask:		the mask used to filter out the field from the register
+ * @bitpos:		the start bit relative to the register
+ * @next:		the indication that the field would be extended to the
+			next register
+ */
+struct mtk_pin_field {
+	u32 offset;
+	u32 mask;
+	u8 bitpos;
+	u8 next;
+};
+
+/**
+ * struct mtk_pin_field_calc - the structure that holds the range providing
+ *			       the guide used to look up the relevant field
+ * @s_pin:		the start pin within the range
+ * @e_pin:		the end pin within the range
+ * @s_addr:		the start address for the range
+ * @x_addrs:		the address distance between two consecutive registers
+ *			within the range
+ * @s_bit:		the start bit for the first register within the range
+ * @x_bits:		the bit distance between two consecutive pins within
+ *			the range
+ * @sz_reg:		the size of bits in a register
+ * @fixed:		the consecutive pins share the same bits with the 1st
+ *			pin
+ */
+struct mtk_pin_field_calc {
+	u16 s_pin;
+	u16 e_pin;
+	u32 s_addr;
+	u8 x_addrs;
+	u8 s_bit;
+	u8 x_bits;
+	u8 sz_reg;
+	u8 fixed;
+};
+
+/**
+ * struct mtk_pin_reg_calc - the structure that holds all ranges used to
+ *			     determine which register the pin would make use of
+ *			     for certain pin attribute.
+ * @range:		     the start address for the range
+ * @nranges:		     the number of items in the range
+ */
+struct mtk_pin_reg_calc {
+	const struct mtk_pin_field_calc *range;
+	unsigned int nranges;
+};
+
+/**
+ * struct mtk_pin_desc - the structure that providing information
+ *			 for each pin of chips
+ * @number:		unique pin number from the global pin number space
+ * @name:		name for this pin
+ * @drv_n:		the index with the driving group
+ */
+struct mtk_pin_desc {
+	unsigned int number;
+	const char *name;
+	u8 drv_n;
+};
+
+/**
+ * struct mtk_group_desc - generic pin group descriptor
+ * @name: name of the pin group
+ * @pins: array of pins that belong to the group
+ * @num_pins: number of pins in the group
+ * @data: pin controller driver specific data
+ */
+struct mtk_group_desc {
+	const char *name;
+	int *pins;
+	int num_pins;
+	void *data;
+};
+
+/**
+ * struct mtk_function_desc - generic function descriptor
+ * @name: name of the function
+ * @group_names: array of pin group names
+ * @num_group_names: number of pin group names
+ */
+struct mtk_function_desc {
+	const char *name;
+	const char * const *group_names;
+	int num_group_names;
+};
+
+/* struct mtk_pin_soc - the structure that holds SoC-specific data */
+struct mtk_pinctrl_soc {
+	const char *name;
+	const struct mtk_pin_reg_calc *reg_cal;
+	const struct mtk_pin_desc *pins;
+	int npins;
+	const struct mtk_group_desc *grps;
+	int ngrps;
+	const struct mtk_function_desc *funcs;
+	int nfuncs;
+};
+
+/**
+ * struct mtk_pinctrl_priv - private data for MTK pinctrl driver
+ *
+ * @base: base address of the pinctrl device
+ * @soc: SoC specific data
+ */
+struct mtk_pinctrl_priv {
+	void __iomem *base;
+	struct mtk_pinctrl_soc *soc;
+};
+
+extern const struct pinctrl_ops mtk_pinctrl_ops;
+
+/* A common read-modify-write helper for MediaTek chips */
+void mtk_rmw(struct udevice *dev, u32 reg, u32 mask, u32 set);
+int mtk_pinctrl_common_probe(struct udevice *dev,
+			     struct mtk_pinctrl_soc *soc);
+
+#endif /* __PINCTRL_MEDIATEK_H__ */
diff --git a/drivers/pinctrl/meson/Kconfig b/drivers/pinctrl/meson/Kconfig
index 27ba890..ee820a5 100644
--- a/drivers/pinctrl/meson/Kconfig
+++ b/drivers/pinctrl/meson/Kconfig
@@ -1,15 +1,27 @@
 if ARCH_MESON
 
 config PINCTRL_MESON
-	depends on PINCTRL_GENERIC
+	select PINCTRL_GENERIC
 	bool
 
+config PINCTRL_MESON_GX_PMX
+	select PINCTRL_MESON
+	bool
+
+config PINCTRL_MESON_AXG_PMX
+	select PINCTRL_MESON
+	bool
+
 config PINCTRL_MESON_GXBB
 	bool "Amlogic Meson GXBB SoC pinctrl driver"
-	select PINCTRL_MESON
+	select PINCTRL_MESON_GX_PMX
 
 config PINCTRL_MESON_GXL
 	bool "Amlogic Meson GXL SoC pinctrl driver"
-	select PINCTRL_MESON
+	select PINCTRL_MESON_GX_PMX
+
+config PINCTRL_MESON_AXG
+	bool "Amlogic Meson AXG SoC pinctrl driver"
+	select PINCTRL_MESON_AXG_PMX
 
 endif
diff --git a/drivers/pinctrl/meson/Makefile b/drivers/pinctrl/meson/Makefile
index 965092c..707287c 100644
--- a/drivers/pinctrl/meson/Makefile
+++ b/drivers/pinctrl/meson/Makefile
@@ -1,5 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0+
 
 obj-y					+= pinctrl-meson.o
+obj-$(CONFIG_PINCTRL_MESON_GX_PMX)	+= pinctrl-meson-gx-pmx.o
+obj-$(CONFIG_PINCTRL_MESON_AXG_PMX)	+= pinctrl-meson-axg-pmx.o
 obj-$(CONFIG_PINCTRL_MESON_GXBB)	+= pinctrl-meson-gxbb.o
 obj-$(CONFIG_PINCTRL_MESON_GXL)		+= pinctrl-meson-gxl.o
+obj-$(CONFIG_PINCTRL_MESON_AXG)		+= pinctrl-meson-axg.o
diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c
new file mode 100644
index 0000000..c82413d
--- /dev/null
+++ b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Jerome Brunet  <jbrunet@baylibre.com>
+ * Copyright (C) 2017 Xingyu Chen <xingyu.chen@amlogic.com>
+ */
+
+#include <asm/gpio.h>
+#include <common.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <linux/io.h>
+#include "pinctrl-meson-axg.h"
+
+static int meson_axg_pmx_get_bank(struct udevice *dev, unsigned int pin,
+				  struct meson_pmx_bank **bank)
+{
+	int i;
+	struct meson_pinctrl *priv = dev_get_priv(dev);
+	struct meson_axg_pmx_data *pmx = priv->data->pmx_data;
+
+	for (i = 0; i < pmx->num_pmx_banks; i++)
+		if (pin >= pmx->pmx_banks[i].first &&
+		    pin <= pmx->pmx_banks[i].last) {
+			*bank = &pmx->pmx_banks[i];
+			return 0;
+		}
+
+	return -EINVAL;
+}
+
+static int meson_axg_pmx_calc_reg_and_offset(struct meson_pmx_bank *bank,
+					     unsigned int pin,
+					     unsigned int *reg,
+					     unsigned int *offset)
+{
+	int shift;
+
+	shift = pin - bank->first;
+
+	*reg = bank->reg + (bank->offset + (shift << 2)) / 32;
+	*offset = (bank->offset + (shift << 2)) % 32;
+
+	return 0;
+}
+
+static int meson_axg_pmx_update_function(struct udevice *dev,
+					 unsigned int pin, unsigned int func)
+{
+	struct meson_pinctrl *priv = dev_get_priv(dev);
+	struct meson_pmx_bank *bank;
+	unsigned int offset;
+	unsigned int reg;
+	unsigned int tmp;
+	int ret;
+
+	ret = meson_axg_pmx_get_bank(dev, pin, &bank);
+	if (ret)
+		return ret;
+
+	meson_axg_pmx_calc_reg_and_offset(bank, pin, &reg, &offset);
+
+	tmp = readl(priv->reg_mux + (reg << 2));
+	tmp &= ~(0xf << offset);
+	tmp |= (func & 0xf) << offset;
+	writel(tmp, priv->reg_mux + (reg << 2));
+
+	return ret;
+}
+
+static int meson_axg_pinmux_group_set(struct udevice *dev,
+				      unsigned int group_selector,
+				      unsigned int func_selector)
+{
+	struct meson_pinctrl *priv = dev_get_priv(dev);
+	const struct meson_pmx_group *group;
+	const struct meson_pmx_func *func;
+	struct meson_pmx_axg_data *pmx_data;
+	int i, ret;
+
+	group = &priv->data->groups[group_selector];
+	pmx_data = (struct meson_pmx_axg_data *)group->data;
+	func = &priv->data->funcs[func_selector];
+
+	debug("pinmux: set group %s func %s\n", group->name, func->name);
+
+	for (i = 0; i < group->num_pins; i++) {
+		ret = meson_axg_pmx_update_function(dev, group->pins[i],
+						    pmx_data->func);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+const struct pinctrl_ops meson_axg_pinctrl_ops = {
+	.get_groups_count = meson_pinctrl_get_groups_count,
+	.get_group_name = meson_pinctrl_get_group_name,
+	.get_functions_count = meson_pinmux_get_functions_count,
+	.get_function_name = meson_pinmux_get_function_name,
+	.pinmux_group_set = meson_axg_pinmux_group_set,
+	.set_state = pinctrl_generic_set_state,
+};
+
+static int meson_axg_gpio_request(struct udevice *dev,
+				  unsigned int offset, const char *label)
+{
+	return meson_axg_pmx_update_function(dev->parent, offset, 0);
+}
+
+static const struct dm_gpio_ops meson_axg_gpio_ops = {
+	.request = meson_axg_gpio_request,
+	.set_value = meson_gpio_set,
+	.get_value = meson_gpio_get,
+	.get_function = meson_gpio_get_direction,
+	.direction_input = meson_gpio_direction_input,
+	.direction_output = meson_gpio_direction_output,
+};
+
+const struct driver meson_axg_gpio_driver = {
+	.name	= "meson-axg-gpio",
+	.id	= UCLASS_GPIO,
+	.probe	= meson_gpio_probe,
+	.ops	= &meson_axg_gpio_ops,
+};
diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg.c b/drivers/pinctrl/meson/pinctrl-meson-axg.c
new file mode 100644
index 0000000..a54fbce
--- /dev/null
+++ b/drivers/pinctrl/meson/pinctrl-meson-axg.c
@@ -0,0 +1,979 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright (C) 2018 Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Based on code from Linux kernel:
+ *  Copyright (c) 2017 Amlogic, Inc. All rights reserved.
+ *  Author: Xingyu Chen <xingyu.chen@amlogic.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <dt-bindings/gpio/meson-axg-gpio.h>
+
+#include "pinctrl-meson-axg.h"
+
+#define EE_OFF	14
+
+/* emmc */
+static const unsigned int emmc_nand_d0_pins[] = {BOOT_0};
+static const unsigned int emmc_nand_d1_pins[] = {BOOT_1};
+static const unsigned int emmc_nand_d2_pins[] = {BOOT_2};
+static const unsigned int emmc_nand_d3_pins[] = {BOOT_3};
+static const unsigned int emmc_nand_d4_pins[] = {BOOT_4};
+static const unsigned int emmc_nand_d5_pins[] = {BOOT_5};
+static const unsigned int emmc_nand_d6_pins[] = {BOOT_6};
+static const unsigned int emmc_nand_d7_pins[] = {BOOT_7};
+
+static const unsigned int emmc_clk_pins[] = {BOOT_8};
+static const unsigned int emmc_cmd_pins[] = {BOOT_10};
+static const unsigned int emmc_ds_pins[]  = {BOOT_13};
+
+/* nand */
+static const unsigned int nand_ce0_pins[] = {BOOT_8};
+static const unsigned int nand_ale_pins[] = {BOOT_9};
+static const unsigned int nand_cle_pins[] = {BOOT_10};
+static const unsigned int nand_wen_clk_pins[] = {BOOT_11};
+static const unsigned int nand_ren_wr_pins[] = {BOOT_12};
+static const unsigned int nand_rb0_pins[] = {BOOT_13};
+
+/* nor */
+static const unsigned int nor_hold_pins[] = {BOOT_3};
+static const unsigned int nor_d_pins[] = {BOOT_4};
+static const unsigned int nor_q_pins[] = {BOOT_5};
+static const unsigned int nor_c_pins[] = {BOOT_6};
+static const unsigned int nor_wp_pins[] = {BOOT_9};
+static const unsigned int nor_cs_pins[] = {BOOT_14};
+
+/* sdio */
+static const unsigned int sdio_d0_pins[] = {GPIOX_0};
+static const unsigned int sdio_d1_pins[] = {GPIOX_1};
+static const unsigned int sdio_d2_pins[] = {GPIOX_2};
+static const unsigned int sdio_d3_pins[] = {GPIOX_3};
+static const unsigned int sdio_clk_pins[] = {GPIOX_4};
+static const unsigned int sdio_cmd_pins[] = {GPIOX_5};
+
+/* spi0 */
+static const unsigned int spi0_clk_pins[] = {GPIOZ_0};
+static const unsigned int spi0_mosi_pins[] = {GPIOZ_1};
+static const unsigned int spi0_miso_pins[] = {GPIOZ_2};
+static const unsigned int spi0_ss0_pins[] = {GPIOZ_3};
+static const unsigned int spi0_ss1_pins[] = {GPIOZ_4};
+static const unsigned int spi0_ss2_pins[] = {GPIOZ_5};
+
+/* spi1 */
+static const unsigned int spi1_clk_x_pins[] = {GPIOX_19};
+static const unsigned int spi1_mosi_x_pins[] = {GPIOX_17};
+static const unsigned int spi1_miso_x_pins[] = {GPIOX_18};
+static const unsigned int spi1_ss0_x_pins[] = {GPIOX_16};
+
+static const unsigned int spi1_clk_a_pins[] = {GPIOA_4};
+static const unsigned int spi1_mosi_a_pins[] = {GPIOA_2};
+static const unsigned int spi1_miso_a_pins[] = {GPIOA_3};
+static const unsigned int spi1_ss0_a_pins[] = {GPIOA_5};
+static const unsigned int spi1_ss1_pins[] = {GPIOA_6};
+
+/* i2c0 */
+static const unsigned int i2c0_sck_pins[] = {GPIOZ_6};
+static const unsigned int i2c0_sda_pins[] = {GPIOZ_7};
+
+/* i2c1 */
+static const unsigned int i2c1_sck_z_pins[] = {GPIOZ_8};
+static const unsigned int i2c1_sda_z_pins[] = {GPIOZ_9};
+
+static const unsigned int i2c1_sck_x_pins[] = {GPIOX_16};
+static const unsigned int i2c1_sda_x_pins[] = {GPIOX_17};
+
+/* i2c2 */
+static const unsigned int i2c2_sck_x_pins[] = {GPIOX_18};
+static const unsigned int i2c2_sda_x_pins[] = {GPIOX_19};
+
+static const unsigned int i2c2_sda_a_pins[] = {GPIOA_17};
+static const unsigned int i2c2_sck_a_pins[] = {GPIOA_18};
+
+/* i2c3 */
+static const unsigned int i2c3_sda_a6_pins[] = {GPIOA_6};
+static const unsigned int i2c3_sck_a7_pins[] = {GPIOA_7};
+
+static const unsigned int i2c3_sda_a12_pins[] = {GPIOA_12};
+static const unsigned int i2c3_sck_a13_pins[] = {GPIOA_13};
+
+static const unsigned int i2c3_sda_a19_pins[] = {GPIOA_19};
+static const unsigned int i2c3_sck_a20_pins[] = {GPIOA_20};
+
+/* uart_a */
+static const unsigned int uart_rts_a_pins[] = {GPIOX_11};
+static const unsigned int uart_cts_a_pins[] = {GPIOX_10};
+static const unsigned int uart_tx_a_pins[] = {GPIOX_8};
+static const unsigned int uart_rx_a_pins[] = {GPIOX_9};
+
+/* uart_b */
+static const unsigned int uart_rts_b_z_pins[] = {GPIOZ_0};
+static const unsigned int uart_cts_b_z_pins[] = {GPIOZ_1};
+static const unsigned int uart_tx_b_z_pins[] = {GPIOZ_2};
+static const unsigned int uart_rx_b_z_pins[] = {GPIOZ_3};
+
+static const unsigned int uart_rts_b_x_pins[] = {GPIOX_18};
+static const unsigned int uart_cts_b_x_pins[] = {GPIOX_19};
+static const unsigned int uart_tx_b_x_pins[] = {GPIOX_16};
+static const unsigned int uart_rx_b_x_pins[] = {GPIOX_17};
+
+/* uart_ao_b */
+static const unsigned int uart_ao_tx_b_z_pins[] = {GPIOZ_8};
+static const unsigned int uart_ao_rx_b_z_pins[] = {GPIOZ_9};
+static const unsigned int uart_ao_cts_b_z_pins[] = {GPIOZ_6};
+static const unsigned int uart_ao_rts_b_z_pins[] = {GPIOZ_7};
+
+/* pwm_a */
+static const unsigned int pwm_a_z_pins[] = {GPIOZ_5};
+
+static const unsigned int pwm_a_x18_pins[] = {GPIOX_18};
+static const unsigned int pwm_a_x20_pins[] = {GPIOX_20};
+
+static const unsigned int pwm_a_a_pins[] = {GPIOA_14};
+
+/* pwm_b */
+static const unsigned int pwm_b_z_pins[] = {GPIOZ_4};
+
+static const unsigned int pwm_b_x_pins[] = {GPIOX_19};
+
+static const unsigned int pwm_b_a_pins[] = {GPIOA_15};
+
+/* pwm_c */
+static const unsigned int pwm_c_x10_pins[] = {GPIOX_10};
+static const unsigned int pwm_c_x17_pins[] = {GPIOX_17};
+
+static const unsigned int pwm_c_a_pins[] = {GPIOA_16};
+
+/* pwm_d */
+static const unsigned int pwm_d_x11_pins[] = {GPIOX_11};
+static const unsigned int pwm_d_x16_pins[] = {GPIOX_16};
+
+/* pwm_vs */
+static const unsigned int pwm_vs_pins[] = {GPIOA_0};
+
+/* spdif_in */
+static const unsigned int spdif_in_z_pins[] = {GPIOZ_4};
+
+static const unsigned int spdif_in_a1_pins[] = {GPIOA_1};
+static const unsigned int spdif_in_a7_pins[] = {GPIOA_7};
+static const unsigned int spdif_in_a19_pins[] = {GPIOA_19};
+static const unsigned int spdif_in_a20_pins[] = {GPIOA_20};
+
+/* spdif_out */
+static const unsigned int spdif_out_z_pins[] = {GPIOZ_5};
+
+static const unsigned int spdif_out_a1_pins[] = {GPIOA_1};
+static const unsigned int spdif_out_a11_pins[] = {GPIOA_11};
+static const unsigned int spdif_out_a19_pins[] = {GPIOA_19};
+static const unsigned int spdif_out_a20_pins[] = {GPIOA_20};
+
+/* jtag_ee */
+static const unsigned int jtag_tdo_x_pins[] = {GPIOX_0};
+static const unsigned int jtag_tdi_x_pins[] = {GPIOX_1};
+static const unsigned int jtag_clk_x_pins[] = {GPIOX_4};
+static const unsigned int jtag_tms_x_pins[] = {GPIOX_5};
+
+/* eth */
+static const unsigned int eth_txd0_x_pins[] = {GPIOX_8};
+static const unsigned int eth_txd1_x_pins[] = {GPIOX_9};
+static const unsigned int eth_txen_x_pins[] = {GPIOX_10};
+static const unsigned int eth_rgmii_rx_clk_x_pins[] = {GPIOX_12};
+static const unsigned int eth_rxd0_x_pins[] = {GPIOX_13};
+static const unsigned int eth_rxd1_x_pins[] = {GPIOX_14};
+static const unsigned int eth_rx_dv_x_pins[] = {GPIOX_15};
+static const unsigned int eth_mdio_x_pins[] = {GPIOX_21};
+static const unsigned int eth_mdc_x_pins[] = {GPIOX_22};
+
+static const unsigned int eth_txd0_y_pins[] = {GPIOY_10};
+static const unsigned int eth_txd1_y_pins[] = {GPIOY_11};
+static const unsigned int eth_txen_y_pins[] = {GPIOY_9};
+static const unsigned int eth_rgmii_rx_clk_y_pins[] = {GPIOY_2};
+static const unsigned int eth_rxd0_y_pins[] = {GPIOY_4};
+static const unsigned int eth_rxd1_y_pins[] = {GPIOY_5};
+static const unsigned int eth_rx_dv_y_pins[] = {GPIOY_3};
+static const unsigned int eth_mdio_y_pins[] = {GPIOY_0};
+static const unsigned int eth_mdc_y_pins[] = {GPIOY_1};
+
+static const unsigned int eth_rxd2_rgmii_pins[] = {GPIOY_6};
+static const unsigned int eth_rxd3_rgmii_pins[] = {GPIOY_7};
+static const unsigned int eth_rgmii_tx_clk_pins[] = {GPIOY_8};
+static const unsigned int eth_txd2_rgmii_pins[] = {GPIOY_12};
+static const unsigned int eth_txd3_rgmii_pins[] = {GPIOY_13};
+
+/* pdm */
+static const unsigned int pdm_dclk_a14_pins[] = {GPIOA_14};
+static const unsigned int pdm_dclk_a19_pins[] = {GPIOA_19};
+static const unsigned int pdm_din0_pins[] = {GPIOA_15};
+static const unsigned int pdm_din1_pins[] = {GPIOA_16};
+static const unsigned int pdm_din2_pins[] = {GPIOA_17};
+static const unsigned int pdm_din3_pins[] = {GPIOA_18};
+
+/* mclk */
+static const unsigned int mclk_c_pins[] = {GPIOA_0};
+static const unsigned int mclk_b_pins[] = {GPIOA_1};
+
+/* tdm */
+static const unsigned int tdma_sclk_pins[] = {GPIOX_12};
+static const unsigned int tdma_sclk_slv_pins[] = {GPIOX_12};
+static const unsigned int tdma_fs_pins[] = {GPIOX_13};
+static const unsigned int tdma_fs_slv_pins[] = {GPIOX_13};
+static const unsigned int tdma_din0_pins[] = {GPIOX_14};
+static const unsigned int tdma_dout0_x14_pins[] = {GPIOX_14};
+static const unsigned int tdma_dout0_x15_pins[] = {GPIOX_15};
+static const unsigned int tdma_dout1_pins[] = {GPIOX_15};
+static const unsigned int tdma_din1_pins[] = {GPIOX_15};
+
+static const unsigned int tdmc_sclk_pins[] = {GPIOA_2};
+static const unsigned int tdmc_sclk_slv_pins[] = {GPIOA_2};
+static const unsigned int tdmc_fs_pins[] = {GPIOA_3};
+static const unsigned int tdmc_fs_slv_pins[] = {GPIOA_3};
+static const unsigned int tdmc_din0_pins[] = {GPIOA_4};
+static const unsigned int tdmc_dout0_pins[] = {GPIOA_4};
+static const unsigned int tdmc_din1_pins[] = {GPIOA_5};
+static const unsigned int tdmc_dout1_pins[] = {GPIOA_5};
+static const unsigned int tdmc_din2_pins[] = {GPIOA_6};
+static const unsigned int tdmc_dout2_pins[] = {GPIOA_6};
+static const unsigned int tdmc_din3_pins[] = {GPIOA_7};
+static const unsigned int tdmc_dout3_pins[] = {GPIOA_7};
+
+static const unsigned int tdmb_sclk_pins[] = {GPIOA_8};
+static const unsigned int tdmb_sclk_slv_pins[] = {GPIOA_8};
+static const unsigned int tdmb_fs_pins[] = {GPIOA_9};
+static const unsigned int tdmb_fs_slv_pins[] = {GPIOA_9};
+static const unsigned int tdmb_din0_pins[] = {GPIOA_10};
+static const unsigned int tdmb_dout0_pins[] = {GPIOA_10};
+static const unsigned int tdmb_din1_pins[] = {GPIOA_11};
+static const unsigned int tdmb_dout1_pins[] = {GPIOA_11};
+static const unsigned int tdmb_din2_pins[] = {GPIOA_12};
+static const unsigned int tdmb_dout2_pins[] = {GPIOA_12};
+static const unsigned int tdmb_din3_pins[] = {GPIOA_13};
+static const unsigned int tdmb_dout3_pins[] = {GPIOA_13};
+
+static struct meson_pmx_group meson_axg_periphs_groups[] = {
+	GPIO_GROUP(GPIOZ_0, EE_OFF),
+	GPIO_GROUP(GPIOZ_1, EE_OFF),
+	GPIO_GROUP(GPIOZ_2, EE_OFF),
+	GPIO_GROUP(GPIOZ_3, EE_OFF),
+	GPIO_GROUP(GPIOZ_4, EE_OFF),
+	GPIO_GROUP(GPIOZ_5, EE_OFF),
+	GPIO_GROUP(GPIOZ_6, EE_OFF),
+	GPIO_GROUP(GPIOZ_7, EE_OFF),
+	GPIO_GROUP(GPIOZ_8, EE_OFF),
+	GPIO_GROUP(GPIOZ_9, EE_OFF),
+	GPIO_GROUP(GPIOZ_10, EE_OFF),
+
+	GPIO_GROUP(BOOT_0, EE_OFF),
+	GPIO_GROUP(BOOT_1, EE_OFF),
+	GPIO_GROUP(BOOT_2, EE_OFF),
+	GPIO_GROUP(BOOT_3, EE_OFF),
+	GPIO_GROUP(BOOT_4, EE_OFF),
+	GPIO_GROUP(BOOT_5, EE_OFF),
+	GPIO_GROUP(BOOT_6, EE_OFF),
+	GPIO_GROUP(BOOT_7, EE_OFF),
+	GPIO_GROUP(BOOT_8, EE_OFF),
+	GPIO_GROUP(BOOT_9, EE_OFF),
+	GPIO_GROUP(BOOT_10, EE_OFF),
+	GPIO_GROUP(BOOT_11, EE_OFF),
+	GPIO_GROUP(BOOT_12, EE_OFF),
+	GPIO_GROUP(BOOT_13, EE_OFF),
+	GPIO_GROUP(BOOT_14, EE_OFF),
+
+	GPIO_GROUP(GPIOA_0, EE_OFF),
+	GPIO_GROUP(GPIOA_1, EE_OFF),
+	GPIO_GROUP(GPIOA_2, EE_OFF),
+	GPIO_GROUP(GPIOA_3, EE_OFF),
+	GPIO_GROUP(GPIOA_4, EE_OFF),
+	GPIO_GROUP(GPIOA_5, EE_OFF),
+	GPIO_GROUP(GPIOA_6, EE_OFF),
+	GPIO_GROUP(GPIOA_7, EE_OFF),
+	GPIO_GROUP(GPIOA_8, EE_OFF),
+	GPIO_GROUP(GPIOA_9, EE_OFF),
+	GPIO_GROUP(GPIOA_10, EE_OFF),
+	GPIO_GROUP(GPIOA_11, EE_OFF),
+	GPIO_GROUP(GPIOA_12, EE_OFF),
+	GPIO_GROUP(GPIOA_13, EE_OFF),
+	GPIO_GROUP(GPIOA_14, EE_OFF),
+	GPIO_GROUP(GPIOA_15, EE_OFF),
+	GPIO_GROUP(GPIOA_16, EE_OFF),
+	GPIO_GROUP(GPIOA_17, EE_OFF),
+	GPIO_GROUP(GPIOA_19, EE_OFF),
+	GPIO_GROUP(GPIOA_20, EE_OFF),
+
+	GPIO_GROUP(GPIOX_0, EE_OFF),
+	GPIO_GROUP(GPIOX_1, EE_OFF),
+	GPIO_GROUP(GPIOX_2, EE_OFF),
+	GPIO_GROUP(GPIOX_3, EE_OFF),
+	GPIO_GROUP(GPIOX_4, EE_OFF),
+	GPIO_GROUP(GPIOX_5, EE_OFF),
+	GPIO_GROUP(GPIOX_6, EE_OFF),
+	GPIO_GROUP(GPIOX_7, EE_OFF),
+	GPIO_GROUP(GPIOX_8, EE_OFF),
+	GPIO_GROUP(GPIOX_9, EE_OFF),
+	GPIO_GROUP(GPIOX_10, EE_OFF),
+	GPIO_GROUP(GPIOX_11, EE_OFF),
+	GPIO_GROUP(GPIOX_12, EE_OFF),
+	GPIO_GROUP(GPIOX_13, EE_OFF),
+	GPIO_GROUP(GPIOX_14, EE_OFF),
+	GPIO_GROUP(GPIOX_15, EE_OFF),
+	GPIO_GROUP(GPIOX_16, EE_OFF),
+	GPIO_GROUP(GPIOX_17, EE_OFF),
+	GPIO_GROUP(GPIOX_18, EE_OFF),
+	GPIO_GROUP(GPIOX_19, EE_OFF),
+	GPIO_GROUP(GPIOX_20, EE_OFF),
+	GPIO_GROUP(GPIOX_21, EE_OFF),
+	GPIO_GROUP(GPIOX_22, EE_OFF),
+
+	GPIO_GROUP(GPIOY_0, EE_OFF),
+	GPIO_GROUP(GPIOY_1, EE_OFF),
+	GPIO_GROUP(GPIOY_2, EE_OFF),
+	GPIO_GROUP(GPIOY_3, EE_OFF),
+	GPIO_GROUP(GPIOY_4, EE_OFF),
+	GPIO_GROUP(GPIOY_5, EE_OFF),
+	GPIO_GROUP(GPIOY_6, EE_OFF),
+	GPIO_GROUP(GPIOY_7, EE_OFF),
+	GPIO_GROUP(GPIOY_8, EE_OFF),
+	GPIO_GROUP(GPIOY_9, EE_OFF),
+	GPIO_GROUP(GPIOY_10, EE_OFF),
+	GPIO_GROUP(GPIOY_11, EE_OFF),
+	GPIO_GROUP(GPIOY_12, EE_OFF),
+	GPIO_GROUP(GPIOY_13, EE_OFF),
+	GPIO_GROUP(GPIOY_14, EE_OFF),
+	GPIO_GROUP(GPIOY_15, EE_OFF),
+
+	/* bank BOOT */
+	GROUP(emmc_nand_d0, 1),
+	GROUP(emmc_nand_d1, 1),
+	GROUP(emmc_nand_d2, 1),
+	GROUP(emmc_nand_d3, 1),
+	GROUP(emmc_nand_d4, 1),
+	GROUP(emmc_nand_d5, 1),
+	GROUP(emmc_nand_d6, 1),
+	GROUP(emmc_nand_d7, 1),
+	GROUP(emmc_clk, 1),
+	GROUP(emmc_cmd, 1),
+	GROUP(emmc_ds, 1),
+	GROUP(nand_ce0, 2),
+	GROUP(nand_ale, 2),
+	GROUP(nand_cle, 2),
+	GROUP(nand_wen_clk, 2),
+	GROUP(nand_ren_wr, 2),
+	GROUP(nand_rb0, 2),
+	GROUP(nor_hold, 3),
+	GROUP(nor_d, 3),
+	GROUP(nor_q, 3),
+	GROUP(nor_c, 3),
+	GROUP(nor_wp, 3),
+	GROUP(nor_cs, 3),
+
+	/* bank GPIOZ */
+	GROUP(spi0_clk, 1),
+	GROUP(spi0_mosi, 1),
+	GROUP(spi0_miso, 1),
+	GROUP(spi0_ss0, 1),
+	GROUP(spi0_ss1, 1),
+	GROUP(spi0_ss2, 1),
+	GROUP(i2c0_sck, 1),
+	GROUP(i2c0_sda, 1),
+	GROUP(i2c1_sck_z, 1),
+	GROUP(i2c1_sda_z, 1),
+	GROUP(uart_rts_b_z, 2),
+	GROUP(uart_cts_b_z, 2),
+	GROUP(uart_tx_b_z, 2),
+	GROUP(uart_rx_b_z, 2),
+	GROUP(pwm_a_z, 2),
+	GROUP(pwm_b_z, 2),
+	GROUP(spdif_in_z, 3),
+	GROUP(spdif_out_z, 3),
+	GROUP(uart_ao_tx_b_z, 2),
+	GROUP(uart_ao_rx_b_z, 2),
+	GROUP(uart_ao_cts_b_z, 2),
+	GROUP(uart_ao_rts_b_z, 2),
+
+	/* bank GPIOX */
+	GROUP(sdio_d0, 1),
+	GROUP(sdio_d1, 1),
+	GROUP(sdio_d2, 1),
+	GROUP(sdio_d3, 1),
+	GROUP(sdio_clk, 1),
+	GROUP(sdio_cmd, 1),
+	GROUP(i2c1_sck_x, 1),
+	GROUP(i2c1_sda_x, 1),
+	GROUP(i2c2_sck_x, 1),
+	GROUP(i2c2_sda_x, 1),
+	GROUP(uart_rts_a, 1),
+	GROUP(uart_cts_a, 1),
+	GROUP(uart_tx_a, 1),
+	GROUP(uart_rx_a, 1),
+	GROUP(uart_rts_b_x, 2),
+	GROUP(uart_cts_b_x, 2),
+	GROUP(uart_tx_b_x, 2),
+	GROUP(uart_rx_b_x, 2),
+	GROUP(jtag_tdo_x, 2),
+	GROUP(jtag_tdi_x, 2),
+	GROUP(jtag_clk_x, 2),
+	GROUP(jtag_tms_x, 2),
+	GROUP(spi1_clk_x, 4),
+	GROUP(spi1_mosi_x, 4),
+	GROUP(spi1_miso_x, 4),
+	GROUP(spi1_ss0_x, 4),
+	GROUP(pwm_a_x18, 3),
+	GROUP(pwm_a_x20, 1),
+	GROUP(pwm_b_x, 3),
+	GROUP(pwm_c_x10, 3),
+	GROUP(pwm_c_x17, 3),
+	GROUP(pwm_d_x11, 3),
+	GROUP(pwm_d_x16, 3),
+	GROUP(eth_txd0_x, 4),
+	GROUP(eth_txd1_x, 4),
+	GROUP(eth_txen_x, 4),
+	GROUP(eth_rgmii_rx_clk_x, 4),
+	GROUP(eth_rxd0_x, 4),
+	GROUP(eth_rxd1_x, 4),
+	GROUP(eth_rx_dv_x, 4),
+	GROUP(eth_mdio_x, 4),
+	GROUP(eth_mdc_x, 4),
+	GROUP(tdma_sclk, 1),
+	GROUP(tdma_sclk_slv, 2),
+	GROUP(tdma_fs, 1),
+	GROUP(tdma_fs_slv, 2),
+	GROUP(tdma_din0, 1),
+	GROUP(tdma_dout0_x14, 2),
+	GROUP(tdma_dout0_x15, 1),
+	GROUP(tdma_dout1, 2),
+	GROUP(tdma_din1, 3),
+
+	/* bank GPIOY */
+	GROUP(eth_txd0_y, 1),
+	GROUP(eth_txd1_y, 1),
+	GROUP(eth_txen_y, 1),
+	GROUP(eth_rgmii_rx_clk_y, 1),
+	GROUP(eth_rxd0_y, 1),
+	GROUP(eth_rxd1_y, 1),
+	GROUP(eth_rx_dv_y, 1),
+	GROUP(eth_mdio_y, 1),
+	GROUP(eth_mdc_y, 1),
+	GROUP(eth_rxd2_rgmii, 1),
+	GROUP(eth_rxd3_rgmii, 1),
+	GROUP(eth_rgmii_tx_clk, 1),
+	GROUP(eth_txd2_rgmii, 1),
+	GROUP(eth_txd3_rgmii, 1),
+
+	/* bank GPIOA */
+	GROUP(spdif_out_a1, 4),
+	GROUP(spdif_out_a11, 3),
+	GROUP(spdif_out_a19, 2),
+	GROUP(spdif_out_a20, 1),
+	GROUP(spdif_in_a1, 3),
+	GROUP(spdif_in_a7, 3),
+	GROUP(spdif_in_a19, 1),
+	GROUP(spdif_in_a20, 2),
+	GROUP(spi1_clk_a, 3),
+	GROUP(spi1_mosi_a, 3),
+	GROUP(spi1_miso_a, 3),
+	GROUP(spi1_ss0_a, 3),
+	GROUP(spi1_ss1, 3),
+	GROUP(pwm_a_a, 3),
+	GROUP(pwm_b_a, 3),
+	GROUP(pwm_c_a, 3),
+	GROUP(pwm_vs, 2),
+	GROUP(i2c2_sda_a, 3),
+	GROUP(i2c2_sck_a, 3),
+	GROUP(i2c3_sda_a6, 4),
+	GROUP(i2c3_sck_a7, 4),
+	GROUP(i2c3_sda_a12, 4),
+	GROUP(i2c3_sck_a13, 4),
+	GROUP(i2c3_sda_a19, 4),
+	GROUP(i2c3_sck_a20, 4),
+	GROUP(pdm_dclk_a14, 1),
+	GROUP(pdm_dclk_a19, 3),
+	GROUP(pdm_din0, 1),
+	GROUP(pdm_din1, 1),
+	GROUP(pdm_din2, 1),
+	GROUP(pdm_din3, 1),
+	GROUP(mclk_c, 1),
+	GROUP(mclk_b, 1),
+	GROUP(tdmc_sclk, 1),
+	GROUP(tdmc_sclk_slv, 2),
+	GROUP(tdmc_fs, 1),
+	GROUP(tdmc_fs_slv, 2),
+	GROUP(tdmc_din0, 2),
+	GROUP(tdmc_dout0, 1),
+	GROUP(tdmc_din1, 2),
+	GROUP(tdmc_dout1, 1),
+	GROUP(tdmc_din2, 2),
+	GROUP(tdmc_dout2, 1),
+	GROUP(tdmc_din3, 2),
+	GROUP(tdmc_dout3, 1),
+	GROUP(tdmb_sclk, 1),
+	GROUP(tdmb_sclk_slv, 2),
+	GROUP(tdmb_fs, 1),
+	GROUP(tdmb_fs_slv, 2),
+	GROUP(tdmb_din0, 2),
+	GROUP(tdmb_dout0, 1),
+	GROUP(tdmb_din1, 2),
+	GROUP(tdmb_dout1, 1),
+	GROUP(tdmb_din2, 2),
+	GROUP(tdmb_dout2, 1),
+	GROUP(tdmb_din3, 2),
+	GROUP(tdmb_dout3, 1),
+};
+
+/* uart_ao_a */
+static const unsigned int uart_ao_tx_a_pins[] = {GPIOAO_0};
+static const unsigned int uart_ao_rx_a_pins[] = {GPIOAO_1};
+static const unsigned int uart_ao_cts_a_pins[] = {GPIOAO_2};
+static const unsigned int uart_ao_rts_a_pins[] = {GPIOAO_3};
+
+/* uart_ao_b */
+static const unsigned int uart_ao_tx_b_pins[] = {GPIOAO_4};
+static const unsigned int uart_ao_rx_b_pins[] = {GPIOAO_5};
+static const unsigned int uart_ao_cts_b_pins[] = {GPIOAO_2};
+static const unsigned int uart_ao_rts_b_pins[] = {GPIOAO_3};
+
+/* i2c_ao */
+static const unsigned int i2c_ao_sck_4_pins[] = {GPIOAO_4};
+static const unsigned int i2c_ao_sda_5_pins[] = {GPIOAO_5};
+static const unsigned int i2c_ao_sck_8_pins[] = {GPIOAO_8};
+static const unsigned int i2c_ao_sda_9_pins[] = {GPIOAO_9};
+static const unsigned int i2c_ao_sck_10_pins[] = {GPIOAO_10};
+static const unsigned int i2c_ao_sda_11_pins[] = {GPIOAO_11};
+
+/* i2c_ao_slave */
+static const unsigned int i2c_ao_slave_sck_pins[] = {GPIOAO_10};
+static const unsigned int i2c_ao_slave_sda_pins[] = {GPIOAO_11};
+
+/* ir_in */
+static const unsigned int remote_input_ao_pins[] = {GPIOAO_6};
+
+/* ir_out */
+static const unsigned int remote_out_ao_pins[] = {GPIOAO_7};
+
+/* pwm_ao_a */
+static const unsigned int pwm_ao_a_pins[] = {GPIOAO_3};
+
+/* pwm_ao_b */
+static const unsigned int pwm_ao_b_ao2_pins[] = {GPIOAO_2};
+static const unsigned int pwm_ao_b_ao12_pins[] = {GPIOAO_12};
+
+/* pwm_ao_c */
+static const unsigned int pwm_ao_c_ao8_pins[] = {GPIOAO_8};
+static const unsigned int pwm_ao_c_ao13_pins[] = {GPIOAO_13};
+
+/* pwm_ao_d */
+static const unsigned int pwm_ao_d_pins[] = {GPIOAO_9};
+
+/* jtag_ao */
+static const unsigned int jtag_ao_tdi_pins[] = {GPIOAO_3};
+static const unsigned int jtag_ao_tdo_pins[] = {GPIOAO_4};
+static const unsigned int jtag_ao_clk_pins[] = {GPIOAO_5};
+static const unsigned int jtag_ao_tms_pins[] = {GPIOAO_7};
+
+static struct meson_pmx_group meson_axg_aobus_groups[] = {
+	GPIO_GROUP(GPIOAO_0, 0),
+	GPIO_GROUP(GPIOAO_1, 0),
+	GPIO_GROUP(GPIOAO_2, 0),
+	GPIO_GROUP(GPIOAO_3, 0),
+	GPIO_GROUP(GPIOAO_4, 0),
+	GPIO_GROUP(GPIOAO_5, 0),
+	GPIO_GROUP(GPIOAO_6, 0),
+	GPIO_GROUP(GPIOAO_7, 0),
+	GPIO_GROUP(GPIOAO_8, 0),
+	GPIO_GROUP(GPIOAO_9, 0),
+	GPIO_GROUP(GPIOAO_10, 0),
+	GPIO_GROUP(GPIOAO_11, 0),
+	GPIO_GROUP(GPIOAO_12, 0),
+	GPIO_GROUP(GPIOAO_13, 0),
+	GPIO_GROUP(GPIO_TEST_N, 0),
+
+	/* bank AO */
+	GROUP(uart_ao_tx_a, 1),
+	GROUP(uart_ao_rx_a, 1),
+	GROUP(uart_ao_cts_a, 2),
+	GROUP(uart_ao_rts_a, 2),
+	GROUP(uart_ao_tx_b, 1),
+	GROUP(uart_ao_rx_b, 1),
+	GROUP(uart_ao_cts_b, 1),
+	GROUP(uart_ao_rts_b, 1),
+	GROUP(i2c_ao_sck_4, 2),
+	GROUP(i2c_ao_sda_5, 2),
+	GROUP(i2c_ao_sck_8, 2),
+	GROUP(i2c_ao_sda_9, 2),
+	GROUP(i2c_ao_sck_10, 2),
+	GROUP(i2c_ao_sda_11, 2),
+	GROUP(i2c_ao_slave_sck, 1),
+	GROUP(i2c_ao_slave_sda, 1),
+	GROUP(remote_input_ao, 1),
+	GROUP(remote_out_ao, 1),
+	GROUP(pwm_ao_a, 3),
+	GROUP(pwm_ao_b_ao2, 3),
+	GROUP(pwm_ao_b_ao12, 3),
+	GROUP(pwm_ao_c_ao8, 3),
+	GROUP(pwm_ao_c_ao13, 3),
+	GROUP(pwm_ao_d, 3),
+	GROUP(jtag_ao_tdi, 4),
+	GROUP(jtag_ao_tdo, 4),
+	GROUP(jtag_ao_clk, 4),
+	GROUP(jtag_ao_tms, 4),
+};
+
+static const char * const gpio_periphs_groups[] = {
+	"GPIOZ_0", "GPIOZ_1", "GPIOZ_2", "GPIOZ_3", "GPIOZ_4",
+	"GPIOZ_5", "GPIOZ_6", "GPIOZ_7", "GPIOZ_8", "GPIOZ_9",
+	"GPIOZ_10",
+
+	"BOOT_0", "BOOT_1", "BOOT_2", "BOOT_3", "BOOT_4",
+	"BOOT_5", "BOOT_6", "BOOT_7", "BOOT_8", "BOOT_9",
+	"BOOT_10", "BOOT_11", "BOOT_12", "BOOT_13", "BOOT_14",
+
+	"GPIOA_0", "GPIOA_1", "GPIOA_2", "GPIOA_3", "GPIOA_4",
+	"GPIOA_5", "GPIOA_6", "GPIOA_7", "GPIOA_8", "GPIOA_9",
+	"GPIOA_10", "GPIOA_11", "GPIOA_12", "GPIOA_13", "GPIOA_14",
+	"GPIOA_15", "GPIOA_16", "GPIOA_17", "GPIOA_18", "GPIOA_19",
+	"GPIOA_20",
+
+	"GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", "GPIOX_4",
+	"GPIOX_5", "GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9",
+	"GPIOX_10", "GPIOX_11", "GPIOX_12", "GPIOX_13", "GPIOX_14",
+	"GPIOX_15", "GPIOX_16", "GPIOX_17", "GPIOX_18", "GPIOX_19",
+	"GPIOX_20", "GPIOX_21", "GPIOX_22",
+
+	"GPIOY_0", "GPIOY_1", "GPIOY_2", "GPIOY_3", "GPIOY_4",
+	"GPIOY_5", "GPIOY_6", "GPIOY_7", "GPIOY_8", "GPIOY_9",
+	"GPIOY_10", "GPIOY_11", "GPIOY_12", "GPIOY_13", "GPIOY_14",
+	"GPIOY_15",
+};
+
+static const char * const emmc_groups[] = {
+	"emmc_nand_d0", "emmc_nand_d1", "emmc_nand_d2",
+	"emmc_nand_d3", "emmc_nand_d4", "emmc_nand_d5",
+	"emmc_nand_d6", "emmc_nand_d7",
+	"emmc_clk", "emmc_cmd", "emmc_ds",
+};
+
+static const char * const nand_groups[] = {
+	"emmc_nand_d0", "emmc_nand_d1", "emmc_nand_d2",
+	"emmc_nand_d3", "emmc_nand_d4", "emmc_nand_d5",
+	"emmc_nand_d6", "emmc_nand_d7",
+	"nand_ce0", "nand_ale", "nand_cle",
+	"nand_wen_clk", "nand_ren_wr", "nand_rb0",
+};
+
+static const char * const nor_groups[] = {
+	"nor_d", "nor_q", "nor_c", "nor_cs",
+	"nor_hold", "nor_wp",
+};
+
+static const char * const sdio_groups[] = {
+	"sdio_d0", "sdio_d1", "sdio_d2", "sdio_d3",
+	"sdio_cmd", "sdio_clk",
+};
+
+static const char * const spi0_groups[] = {
+	"spi0_clk", "spi0_mosi", "spi0_miso", "spi0_ss0",
+	"spi0_ss1", "spi0_ss2"
+};
+
+static const char * const spi1_groups[] = {
+	"spi1_clk_x", "spi1_mosi_x", "spi1_miso_x", "spi1_ss0_x",
+	"spi1_clk_a", "spi1_mosi_a", "spi1_miso_a", "spi1_ss0_a",
+	"spi1_ss1"
+};
+
+static const char * const uart_a_groups[] = {
+	"uart_tx_a", "uart_rx_a", "uart_cts_a", "uart_rts_a",
+};
+
+static const char * const uart_b_groups[] = {
+	"uart_tx_b_z", "uart_rx_b_z", "uart_cts_b_z", "uart_rts_b_z",
+	"uart_tx_b_x", "uart_rx_b_x", "uart_cts_b_x", "uart_rts_b_x",
+};
+
+static const char * const uart_ao_b_z_groups[] = {
+	"uart_ao_tx_b_z", "uart_ao_rx_b_z",
+	"uart_ao_cts_b_z", "uart_ao_rts_b_z",
+};
+
+static const char * const i2c0_groups[] = {
+	"i2c0_sck", "i2c0_sda",
+};
+
+static const char * const i2c1_groups[] = {
+	"i2c1_sck_z", "i2c1_sda_z",
+	"i2c1_sck_x", "i2c1_sda_x",
+};
+
+static const char * const i2c2_groups[] = {
+	"i2c2_sck_x", "i2c2_sda_x",
+	"i2c2_sda_a", "i2c2_sck_a",
+};
+
+static const char * const i2c3_groups[] = {
+	"i2c3_sda_a6", "i2c3_sck_a7",
+	"i2c3_sda_a12", "i2c3_sck_a13",
+	"i2c3_sda_a19", "i2c3_sck_a20",
+};
+
+static const char * const eth_groups[] = {
+	"eth_rxd2_rgmii", "eth_rxd3_rgmii", "eth_rgmii_tx_clk",
+	"eth_txd2_rgmii", "eth_txd3_rgmii",
+	"eth_txd0_x", "eth_txd1_x", "eth_txen_x", "eth_rgmii_rx_clk_x",
+	"eth_rxd0_x", "eth_rxd1_x", "eth_rx_dv_x", "eth_mdio_x",
+	"eth_mdc_x",
+	"eth_txd0_y", "eth_txd1_y", "eth_txen_y", "eth_rgmii_rx_clk_y",
+	"eth_rxd0_y", "eth_rxd1_y", "eth_rx_dv_y", "eth_mdio_y",
+	"eth_mdc_y",
+};
+
+static const char * const pwm_a_groups[] = {
+	"pwm_a_z", "pwm_a_x18", "pwm_a_x20", "pwm_a_a",
+};
+
+static const char * const pwm_b_groups[] = {
+	"pwm_b_z", "pwm_b_x", "pwm_b_a",
+};
+
+static const char * const pwm_c_groups[] = {
+	"pwm_c_x10", "pwm_c_x17", "pwm_c_a",
+};
+
+static const char * const pwm_d_groups[] = {
+	"pwm_d_x11", "pwm_d_x16",
+};
+
+static const char * const pwm_vs_groups[] = {
+	"pwm_vs",
+};
+
+static const char * const spdif_out_groups[] = {
+	"spdif_out_z", "spdif_out_a1", "spdif_out_a11",
+	"spdif_out_a19", "spdif_out_a20",
+};
+
+static const char * const spdif_in_groups[] = {
+	"spdif_in_z", "spdif_in_a1", "spdif_in_a7",
+	"spdif_in_a19", "spdif_in_a20",
+};
+
+static const char * const jtag_ee_groups[] = {
+	"jtag_tdo_x", "jtag_tdi_x", "jtag_clk_x",
+	"jtag_tms_x",
+};
+
+static const char * const pdm_groups[] = {
+	"pdm_din0", "pdm_din1", "pdm_din2", "pdm_din3",
+	"pdm_dclk_a14", "pdm_dclk_a19",
+};
+
+static const char * const gpio_aobus_groups[] = {
+	"GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
+	"GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
+	"GPIOAO_10", "GPIOAO_11", "GPIOAO_12", "GPIOAO_13",
+	"GPIO_TEST_N",
+};
+
+static const char * const uart_ao_a_groups[] = {
+	"uart_ao_tx_a", "uart_ao_rx_a", "uart_ao_cts_a", "uart_ao_rts_a",
+};
+
+static const char * const uart_ao_b_groups[] = {
+	"uart_ao_tx_b", "uart_ao_rx_b", "uart_ao_cts_b", "uart_ao_rts_b",
+};
+
+static const char * const i2c_ao_groups[] = {
+	"i2c_ao_sck_4", "i2c_ao_sda_5",
+	"i2c_ao_sck_8", "i2c_ao_sda_9",
+	"i2c_ao_sck_10", "i2c_ao_sda_11",
+};
+
+static const char * const i2c_ao_slave_groups[] = {
+	"i2c_ao_slave_sck", "i2c_ao_slave_sda",
+};
+
+static const char * const remote_input_ao_groups[] = {
+	"remote_input_ao",
+};
+
+static const char * const remote_out_ao_groups[] = {
+	"remote_out_ao",
+};
+
+static const char * const pwm_ao_a_groups[] = {
+	"pwm_ao_a",
+};
+
+static const char * const pwm_ao_b_groups[] = {
+	"pwm_ao_b_ao2", "pwm_ao_b_ao12",
+};
+
+static const char * const pwm_ao_c_groups[] = {
+	"pwm_ao_c_ao8", "pwm_ao_c_ao13",
+};
+
+static const char * const pwm_ao_d_groups[] = {
+	"pwm_ao_d",
+};
+
+static const char * const jtag_ao_groups[] = {
+	"jtag_ao_tdi", "jtag_ao_tdo", "jtag_ao_clk", "jtag_ao_tms",
+};
+
+static const char * const mclk_c_groups[] = {
+	"mclk_c",
+};
+
+static const char * const mclk_b_groups[] = {
+	"mclk_b",
+};
+
+static const char * const tdma_groups[] = {
+	"tdma_sclk", "tdma_sclk_slv", "tdma_fs", "tdma_fs_slv",
+	"tdma_din0", "tdma_dout0_x14", "tdma_dout0_x15", "tdma_dout1",
+	"tdma_din1",
+};
+
+static const char * const tdmc_groups[] = {
+	"tdmc_sclk", "tdmc_sclk_slv", "tdmc_fs", "tdmc_fs_slv",
+	"tdmc_din0", "tdmc_dout0", "tdmc_din1",	"tdmc_dout1",
+	"tdmc_din2", "tdmc_dout2", "tdmc_din3",	"tdmc_dout3",
+};
+
+static const char * const tdmb_groups[] = {
+	"tdmb_sclk", "tdmb_sclk_slv", "tdmb_fs", "tdmb_fs_slv",
+	"tdmb_din0", "tdmb_dout0", "tdmb_din1",	"tdmb_dout1",
+	"tdmb_din2", "tdmb_dout2", "tdmb_din3",	"tdmb_dout3",
+};
+
+static struct meson_pmx_func meson_axg_periphs_functions[] = {
+	FUNCTION(gpio_periphs),
+	FUNCTION(emmc),
+	FUNCTION(nor),
+	FUNCTION(spi0),
+	FUNCTION(spi1),
+	FUNCTION(sdio),
+	FUNCTION(nand),
+	FUNCTION(uart_a),
+	FUNCTION(uart_b),
+	FUNCTION(uart_ao_b_z),
+	FUNCTION(i2c0),
+	FUNCTION(i2c1),
+	FUNCTION(i2c2),
+	FUNCTION(i2c3),
+	FUNCTION(eth),
+	FUNCTION(pwm_a),
+	FUNCTION(pwm_b),
+	FUNCTION(pwm_c),
+	FUNCTION(pwm_d),
+	FUNCTION(pwm_vs),
+	FUNCTION(spdif_out),
+	FUNCTION(spdif_in),
+	FUNCTION(jtag_ee),
+	FUNCTION(pdm),
+	FUNCTION(mclk_b),
+	FUNCTION(mclk_c),
+	FUNCTION(tdma),
+	FUNCTION(tdmb),
+	FUNCTION(tdmc),
+};
+
+static struct meson_pmx_func meson_axg_aobus_functions[] = {
+	FUNCTION(gpio_aobus),
+	FUNCTION(uart_ao_a),
+	FUNCTION(uart_ao_b),
+	FUNCTION(i2c_ao),
+	FUNCTION(i2c_ao_slave),
+	FUNCTION(remote_input_ao),
+	FUNCTION(remote_out_ao),
+	FUNCTION(pwm_ao_a),
+	FUNCTION(pwm_ao_b),
+	FUNCTION(pwm_ao_c),
+	FUNCTION(pwm_ao_d),
+	FUNCTION(jtag_ao),
+};
+
+static struct meson_bank meson_axg_periphs_banks[] = {
+	/*   name    first      last      pullen  pull    dir     out     in  */
+	BANK("Z",    GPIOZ_0,	GPIOZ_10, 3,  0,  3,  0,  9,  0,  10, 0,  11, 0),
+	BANK("BOOT", BOOT_0,	BOOT_14,  4,  0,  4,  0,  12, 0,  13, 0,  14, 0),
+	BANK("A",    GPIOA_0,	GPIOA_20, 0,  0,  0,  0,  0,  0,  1,  0,  2,  0),
+	BANK("X",    GPIOX_0,	GPIOX_22, 2,  0,  2,  0,  6,  0,  7,  0,  8,  0),
+	BANK("Y",    GPIOY_0,	GPIOY_15, 1,  0,  1,  0,  3,  0,  4,  0,  5,  0),
+};
+
+static struct meson_bank meson_axg_aobus_banks[] = {
+	/*   name    first      last       pullen  pull    dir     out     in  */
+	BANK("AO",   GPIOAO_0,  GPIOAO_13, 0,  16,  0, 0,  0,  0,  0, 16,  1,  0),
+};
+
+static struct meson_pmx_bank meson_axg_periphs_pmx_banks[] = {
+	/*	 name	 first		lask	   reg	offset  */
+	BANK_PMX("Z",	 GPIOZ_0, GPIOZ_10, 0x2, 0),
+	BANK_PMX("BOOT", BOOT_0,  BOOT_14,  0x0, 0),
+	BANK_PMX("A",	 GPIOA_0, GPIOA_20, 0xb, 0),
+	BANK_PMX("X",	 GPIOX_0, GPIOX_22, 0x4, 0),
+	BANK_PMX("Y",	 GPIOY_0, GPIOY_15, 0x8, 0),
+};
+
+static struct meson_axg_pmx_data meson_axg_periphs_pmx_banks_data = {
+	.pmx_banks	= meson_axg_periphs_pmx_banks,
+	.num_pmx_banks = ARRAY_SIZE(meson_axg_periphs_pmx_banks),
+};
+
+static struct meson_pmx_bank meson_axg_aobus_pmx_banks[] = {
+	BANK_PMX("AO", GPIOAO_0, GPIOAO_13, 0x0, 0),
+};
+
+static struct meson_axg_pmx_data meson_axg_aobus_pmx_banks_data = {
+	.pmx_banks	= meson_axg_aobus_pmx_banks,
+	.num_pmx_banks = ARRAY_SIZE(meson_axg_aobus_pmx_banks),
+};
+
+struct meson_pinctrl_data meson_axg_periphs_pinctrl_data = {
+	.name		= "periphs-banks",
+	.pin_base	= 11,
+	.groups		= meson_axg_periphs_groups,
+	.funcs		= meson_axg_periphs_functions,
+	.banks		= meson_axg_periphs_banks,
+	.num_pins	= 100,
+	.num_groups	= ARRAY_SIZE(meson_axg_periphs_groups),
+	.num_funcs	= ARRAY_SIZE(meson_axg_periphs_functions),
+	.num_banks	= ARRAY_SIZE(meson_axg_periphs_banks),
+	.gpio_driver	= &meson_axg_gpio_driver,
+	.pmx_data	= &meson_axg_periphs_pmx_banks_data,
+};
+
+struct meson_pinctrl_data meson_axg_aobus_pinctrl_data = {
+	.name		= "aobus-banks",
+	.pin_base	= 0,
+	.groups		= meson_axg_aobus_groups,
+	.funcs		= meson_axg_aobus_functions,
+	.banks		= meson_axg_aobus_banks,
+	.num_pins	= 14,
+	.num_groups	= ARRAY_SIZE(meson_axg_aobus_groups),
+	.num_funcs	= ARRAY_SIZE(meson_axg_aobus_functions),
+	.num_banks	= ARRAY_SIZE(meson_axg_aobus_banks),
+	.gpio_driver	= &meson_axg_gpio_driver,
+	.pmx_data	= &meson_axg_aobus_pmx_banks_data,
+};
+
+static const struct udevice_id meson_axg_pinctrl_match[] = {
+	{
+		.compatible = "amlogic,meson-axg-periphs-pinctrl",
+		.data = (ulong)&meson_axg_periphs_pinctrl_data,
+	},
+	{
+		.compatible = "amlogic,meson-axg-aobus-pinctrl",
+		.data = (ulong)&meson_axg_aobus_pinctrl_data,
+	},
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(meson_axg_pinctrl) = {
+	.name = "meson-axg-pinctrl",
+	.id = UCLASS_PINCTRL,
+	.of_match = of_match_ptr(meson_axg_pinctrl_match),
+	.probe = meson_pinctrl_probe,
+	.priv_auto_alloc_size = sizeof(struct meson_pinctrl),
+	.ops = &meson_axg_pinctrl_ops,
+};
diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg.h b/drivers/pinctrl/meson/pinctrl-meson-axg.h
new file mode 100644
index 0000000..c8d2b3a
--- /dev/null
+++ b/drivers/pinctrl/meson/pinctrl-meson-axg.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2017 Jerome Brunet  <jbrunet@baylibre.com>
+ * Copyright (C) 2017 Xingyu Chen <xingyu.chen@amlogic.com>
+ */
+
+#ifndef __PINCTRL_MESON_AXG_H__
+#define __PINCTRL_MESON_AXG_H__
+
+#include "pinctrl-meson.h"
+
+struct meson_pmx_bank {
+	const char *name;
+	unsigned int first;
+	unsigned int last;
+	unsigned int reg;
+	unsigned int offset;
+};
+
+struct meson_axg_pmx_data {
+	struct meson_pmx_bank *pmx_banks;
+	unsigned int num_pmx_banks;
+};
+
+#define BANK_PMX(n, f, l, r, o)				\
+	{							\
+		.name   = n,					\
+		.first	= f,					\
+		.last	= l,					\
+		.reg	= r,					\
+		.offset = o,					\
+	}
+
+struct meson_pmx_axg_data {
+	unsigned int func;
+};
+
+#define PMX_DATA(f)							\
+	{								\
+		.func = f,						\
+	}
+
+#define GROUP(grp, f)							\
+	{								\
+		.name = #grp,						\
+		.pins = grp ## _pins,                                   \
+		.num_pins = ARRAY_SIZE(grp ## _pins),			\
+		.data = (const struct meson_pmx_axg_data[]){		\
+			PMX_DATA(f),					\
+		},							\
+	}
+
+#define GPIO_GROUP(gpio, b)						\
+	{								\
+		.name = #gpio,						\
+		.pins = (const unsigned int[]){ PIN(gpio, b) },		\
+		.num_pins = 1,						\
+		.data = (const struct meson_pmx_axg_data[]){		\
+			PMX_DATA(0),					\
+		},							\
+	}
+
+extern const struct pinctrl_ops meson_axg_pinctrl_ops;
+extern const struct driver meson_axg_gpio_driver;
+
+#endif /* __PINCTRL_MESON_AXG_H__ */
diff --git a/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c b/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c
new file mode 100644
index 0000000..fc1538e
--- /dev/null
+++ b/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 - Beniamino Galvani <b.galvani@gmail.com>
+ */
+
+#include <asm/gpio.h>
+#include <common.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <linux/io.h>
+#include "pinctrl-meson-gx.h"
+
+static void meson_gx_pinmux_disable_other_groups(struct meson_pinctrl *priv,
+						 unsigned int pin,
+						 int sel_group)
+{
+	struct meson_pmx_group *group;
+	struct meson_gx_pmx_data *pmx_data;
+	void __iomem *addr;
+	int i, j;
+
+	for (i = 0; i < priv->data->num_groups; i++) {
+		group = &priv->data->groups[i];
+		pmx_data = (struct meson_gx_pmx_data *)group->data;
+		if (pmx_data->is_gpio || i == sel_group)
+			continue;
+
+		for (j = 0; j < group->num_pins; j++) {
+			if (group->pins[j] == pin) {
+				/* We have found a group using the pin */
+				debug("pinmux: disabling %s\n", group->name);
+				addr = priv->reg_mux + pmx_data->reg * 4;
+				writel(readl(addr) & ~BIT(pmx_data->bit), addr);
+			}
+		}
+	}
+}
+
+static int meson_gx_pinmux_group_set(struct udevice *dev,
+				     unsigned int group_selector,
+				     unsigned int func_selector)
+{
+	struct meson_pinctrl *priv = dev_get_priv(dev);
+	const struct meson_pmx_group *group;
+	const struct meson_pmx_func *func;
+	struct meson_gx_pmx_data *pmx_data;
+	void __iomem *addr;
+	int i;
+
+	group = &priv->data->groups[group_selector];
+	pmx_data = (struct meson_gx_pmx_data *)group->data;
+	func = &priv->data->funcs[func_selector];
+
+	debug("pinmux: set group %s func %s\n", group->name, func->name);
+
+	/*
+	 * Disable groups using the same pins.
+	 * The selected group is not disabled to avoid glitches.
+	 */
+	for (i = 0; i < group->num_pins; i++) {
+		meson_gx_pinmux_disable_other_groups(priv,
+						     group->pins[i],
+						     group_selector);
+	}
+
+	/* Function 0 (GPIO) doesn't need any additional setting */
+	if (func_selector) {
+		addr = priv->reg_mux + pmx_data->reg * 4;
+		writel(readl(addr) | BIT(pmx_data->bit), addr);
+	}
+
+	return 0;
+}
+
+const struct pinctrl_ops meson_gx_pinctrl_ops = {
+	.get_groups_count = meson_pinctrl_get_groups_count,
+	.get_group_name = meson_pinctrl_get_group_name,
+	.get_functions_count = meson_pinmux_get_functions_count,
+	.get_function_name = meson_pinmux_get_function_name,
+	.pinmux_group_set = meson_gx_pinmux_group_set,
+	.set_state = pinctrl_generic_set_state,
+};
+
+static const struct dm_gpio_ops meson_gx_gpio_ops = {
+	.set_value = meson_gpio_set,
+	.get_value = meson_gpio_get,
+	.get_function = meson_gpio_get_direction,
+	.direction_input = meson_gpio_direction_input,
+	.direction_output = meson_gpio_direction_output,
+};
+
+const struct driver meson_gx_gpio_driver = {
+	.name	= "meson-gx-gpio",
+	.id	= UCLASS_GPIO,
+	.probe	= meson_gpio_probe,
+	.ops	= &meson_gx_gpio_ops,
+};
diff --git a/drivers/pinctrl/meson/pinctrl-meson-gx.h b/drivers/pinctrl/meson/pinctrl-meson-gx.h
new file mode 100644
index 0000000..4c1aa1a
--- /dev/null
+++ b/drivers/pinctrl/meson/pinctrl-meson-gx.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
+ * Copyright (C) 2017 Jerome Brunet  <jbrunet@baylibre.com>
+ */
+
+#ifndef __PINCTRL_MESON_GX_H__
+#define __PINCTRL_MESON_GX_H__
+
+#include "pinctrl-meson.h"
+
+struct meson_gx_pmx_data {
+	bool is_gpio;
+	unsigned int reg;
+	unsigned int bit;
+};
+
+#define PMX_DATA(r, b, g)						\
+	{								\
+		.reg = r,						\
+		.bit = b,						\
+		.is_gpio = g,						\
+	}
+
+#define GROUP(grp, r, b)						\
+	{								\
+		.name = #grp,						\
+		.pins = grp ## _pins,					\
+		.num_pins = ARRAY_SIZE(grp ## _pins),			\
+			.data = (const struct meson_gx_pmx_data[]){	\
+			PMX_DATA(r, b, false),				\
+		},							\
+	}
+
+#define GPIO_GROUP(gpio, b)						\
+	{								\
+		.name = #gpio,						\
+		.pins = (const unsigned int[]){ PIN(gpio, b) },		\
+		.num_pins = 1,						\
+		.data = (const struct meson_gx_pmx_data[]){		\
+			PMX_DATA(0, 0, true),				\
+		},							\
+	}
+
+extern const struct pinctrl_ops meson_gx_pinctrl_ops;
+extern const struct driver meson_gx_gpio_driver;
+
+#endif /* __PINCTRL_MESON_GX_H__ */
diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c
index a8e47e3..22e8b05 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c
@@ -11,7 +11,7 @@
 #include <dm/pinctrl.h>
 #include <dt-bindings/gpio/meson-gxbb-gpio.h>
 
-#include "pinctrl-meson.h"
+#include "pinctrl-meson-gx.h"
 
 #define EE_OFF	15
 
@@ -417,6 +417,7 @@
 	.num_groups	= ARRAY_SIZE(meson_gxbb_periphs_groups),
 	.num_funcs	= ARRAY_SIZE(meson_gxbb_periphs_functions),
 	.num_banks	= ARRAY_SIZE(meson_gxbb_periphs_banks),
+	.gpio_driver	= &meson_gx_gpio_driver,
 };
 
 struct meson_pinctrl_data meson_gxbb_aobus_pinctrl_data = {
@@ -429,6 +430,7 @@
 	.num_groups	= ARRAY_SIZE(meson_gxbb_aobus_groups),
 	.num_funcs	= ARRAY_SIZE(meson_gxbb_aobus_functions),
 	.num_banks	= ARRAY_SIZE(meson_gxbb_aobus_banks),
+	.gpio_driver	= &meson_gx_gpio_driver,
 };
 
 static const struct udevice_id meson_gxbb_pinctrl_match[] = {
@@ -449,5 +451,5 @@
 	.of_match = of_match_ptr(meson_gxbb_pinctrl_match),
 	.probe = meson_pinctrl_probe,
 	.priv_auto_alloc_size = sizeof(struct meson_pinctrl),
-	.ops = &meson_pinctrl_ops,
+	.ops = &meson_gx_pinctrl_ops,
 };
diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c
index ba6e353..1819eee 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-gxl.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c
@@ -11,7 +11,7 @@
 #include <dm/pinctrl.h>
 #include <dt-bindings/gpio/meson-gxl-gpio.h>
 
-#include "pinctrl-meson.h"
+#include "pinctrl-meson-gx.h"
 
 #define EE_OFF	11
 
@@ -699,6 +699,7 @@
 	.num_groups	= ARRAY_SIZE(meson_gxl_periphs_groups),
 	.num_funcs	= ARRAY_SIZE(meson_gxl_periphs_functions),
 	.num_banks	= ARRAY_SIZE(meson_gxl_periphs_banks),
+	.gpio_driver	= &meson_gx_gpio_driver,
 };
 
 struct meson_pinctrl_data meson_gxl_aobus_pinctrl_data = {
@@ -711,6 +712,7 @@
 	.num_groups	= ARRAY_SIZE(meson_gxl_aobus_groups),
 	.num_funcs	= ARRAY_SIZE(meson_gxl_aobus_functions),
 	.num_banks	= ARRAY_SIZE(meson_gxl_aobus_banks),
+	.gpio_driver	= &meson_gx_gpio_driver,
 };
 
 static const struct udevice_id meson_gxl_pinctrl_match[] = {
@@ -731,5 +733,5 @@
 	.of_match = of_match_ptr(meson_gxl_pinctrl_match),
 	.probe = meson_pinctrl_probe,
 	.priv_auto_alloc_size = sizeof(struct meson_pinctrl),
-	.ops = &meson_pinctrl_ops,
+	.ops = &meson_gx_pinctrl_ops,
 };
diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c
index 387c241..0bd6152 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.c
+++ b/drivers/pinctrl/meson/pinctrl-meson.c
@@ -20,15 +20,15 @@
 
 static const char *meson_pinctrl_dummy_name = "_dummy";
 
-static int meson_pinctrl_get_groups_count(struct udevice *dev)
+int meson_pinctrl_get_groups_count(struct udevice *dev)
 {
 	struct meson_pinctrl *priv = dev_get_priv(dev);
 
 	return priv->data->num_groups;
 }
 
-static const char *meson_pinctrl_get_group_name(struct udevice *dev,
-						unsigned selector)
+const char *meson_pinctrl_get_group_name(struct udevice *dev,
+					 unsigned int selector)
 {
 	struct meson_pinctrl *priv = dev_get_priv(dev);
 
@@ -38,87 +38,21 @@
 	return priv->data->groups[selector].name;
 }
 
-static int meson_pinmux_get_functions_count(struct udevice *dev)
+int meson_pinmux_get_functions_count(struct udevice *dev)
 {
 	struct meson_pinctrl *priv = dev_get_priv(dev);
 
 	return priv->data->num_funcs;
 }
 
-static const char *meson_pinmux_get_function_name(struct udevice *dev,
-						  unsigned selector)
+const char *meson_pinmux_get_function_name(struct udevice *dev,
+					   unsigned int selector)
 {
 	struct meson_pinctrl *priv = dev_get_priv(dev);
 
 	return priv->data->funcs[selector].name;
 }
 
-static void meson_pinmux_disable_other_groups(struct meson_pinctrl *priv,
-					      unsigned int pin, int sel_group)
-{
-	struct meson_pmx_group *group;
-	void __iomem *addr;
-	int i, j;
-
-	for (i = 0; i < priv->data->num_groups; i++) {
-		group = &priv->data->groups[i];
-		if (group->is_gpio || i == sel_group)
-			continue;
-
-		for (j = 0; j < group->num_pins; j++) {
-			if (group->pins[j] == pin) {
-				/* We have found a group using the pin */
-				debug("pinmux: disabling %s\n", group->name);
-				addr = priv->reg_mux + group->reg * 4;
-				writel(readl(addr) & ~BIT(group->bit), addr);
-			}
-		}
-	}
-}
-
-static int meson_pinmux_group_set(struct udevice *dev,
-				  unsigned group_selector,
-				  unsigned func_selector)
-{
-	struct meson_pinctrl *priv = dev_get_priv(dev);
-	const struct meson_pmx_group *group;
-	const struct meson_pmx_func *func;
-	void __iomem *addr;
-	int i;
-
-	group = &priv->data->groups[group_selector];
-	func = &priv->data->funcs[func_selector];
-
-	debug("pinmux: set group %s func %s\n", group->name, func->name);
-
-	/*
-	 * Disable groups using the same pins.
-	 * The selected group is not disabled to avoid glitches.
-	 */
-	for (i = 0; i < group->num_pins; i++) {
-		meson_pinmux_disable_other_groups(priv,
-						  group->pins[i],
-						  group_selector);
-	}
-
-	/* Function 0 (GPIO) doesn't need any additional setting */
-	if (func_selector) {
-		addr = priv->reg_mux + group->reg * 4;
-		writel(readl(addr) | BIT(group->bit), addr);
-	}
-
-	return 0;
-}
-
-const struct pinctrl_ops meson_pinctrl_ops = {
-	.get_groups_count = meson_pinctrl_get_groups_count,
-	.get_group_name = meson_pinctrl_get_group_name,
-	.get_functions_count = meson_pinmux_get_functions_count,
-	.get_function_name = meson_pinmux_get_function_name,
-	.pinmux_group_set = meson_pinmux_group_set,
-	.set_state = pinctrl_generic_set_state,
-};
-
 static int meson_gpio_calc_reg_and_bit(struct udevice *dev, unsigned int offset,
 				       enum meson_reg_type reg_type,
 				       unsigned int *reg, unsigned int *bit)
@@ -149,7 +83,7 @@
 	return 0;
 }
 
-static int meson_gpio_get(struct udevice *dev, unsigned int offset)
+int meson_gpio_get(struct udevice *dev, unsigned int offset)
 {
 	struct meson_pinctrl *priv = dev_get_priv(dev->parent);
 	unsigned int reg, bit;
@@ -162,7 +96,7 @@
 	return !!(readl(priv->reg_gpio + reg) & BIT(bit));
 }
 
-static int meson_gpio_set(struct udevice *dev, unsigned int offset, int value)
+int meson_gpio_set(struct udevice *dev, unsigned int offset, int value)
 {
 	struct meson_pinctrl *priv = dev_get_priv(dev->parent);
 	unsigned int reg, bit;
@@ -177,7 +111,7 @@
 	return 0;
 }
 
-static int meson_gpio_get_direction(struct udevice *dev, unsigned int offset)
+int meson_gpio_get_direction(struct udevice *dev, unsigned int offset)
 {
 	struct meson_pinctrl *priv = dev_get_priv(dev->parent);
 	unsigned int reg, bit, val;
@@ -192,7 +126,7 @@
 	return (val & BIT(bit)) ? GPIOF_INPUT : GPIOF_OUTPUT;
 }
 
-static int meson_gpio_direction_input(struct udevice *dev, unsigned int offset)
+int meson_gpio_direction_input(struct udevice *dev, unsigned int offset)
 {
 	struct meson_pinctrl *priv = dev_get_priv(dev->parent);
 	unsigned int reg, bit;
@@ -207,8 +141,8 @@
 	return 0;
 }
 
-static int meson_gpio_direction_output(struct udevice *dev,
-				       unsigned int offset, int value)
+int meson_gpio_direction_output(struct udevice *dev,
+				unsigned int offset, int value)
 {
 	struct meson_pinctrl *priv = dev_get_priv(dev->parent);
 	unsigned int reg, bit;
@@ -229,7 +163,7 @@
 	return 0;
 }
 
-static int meson_gpio_probe(struct udevice *dev)
+int meson_gpio_probe(struct udevice *dev)
 {
 	struct meson_pinctrl *priv = dev_get_priv(dev->parent);
 	struct gpio_dev_priv *uc_priv;
@@ -241,21 +175,6 @@
 	return 0;
 }
 
-static const struct dm_gpio_ops meson_gpio_ops = {
-	.set_value = meson_gpio_set,
-	.get_value = meson_gpio_get,
-	.get_function = meson_gpio_get_direction,
-	.direction_input = meson_gpio_direction_input,
-	.direction_output = meson_gpio_direction_output,
-};
-
-static struct driver meson_gpio_driver = {
-	.name	= "meson-gpio",
-	.id	= UCLASS_GPIO,
-	.probe	= meson_gpio_probe,
-	.ops	= &meson_gpio_ops,
-};
-
 static fdt_addr_t parse_address(int offset, const char *name, int na, int ns)
 {
 	int index, len = 0;
@@ -334,7 +253,7 @@
 	sprintf(name, "meson-gpio");
 
 	/* Create child device UCLASS_GPIO and bind it */
-	device_bind(dev, &meson_gpio_driver, name, NULL, gpio, &gpio_dev);
+	device_bind(dev, priv->data->gpio_driver, name, NULL, gpio, &gpio_dev);
 	dev_set_of_offset(gpio_dev, gpio);
 
 	return 0;
diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h
index 6ec89ba..bdee721 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.h
+++ b/drivers/pinctrl/meson/pinctrl-meson.h
@@ -12,9 +12,7 @@
 	const char *name;
 	const unsigned int *pins;
 	unsigned int num_pins;
-	bool is_gpio;
-	unsigned int reg;
-	unsigned int bit;
+	const void *data;
 };
 
 struct meson_pmx_func {
@@ -33,6 +31,8 @@
 	unsigned int num_groups;
 	unsigned int num_funcs;
 	unsigned int num_banks;
+	const struct driver *gpio_driver;
+	void *pmx_data;
 };
 
 struct meson_pinctrl {
@@ -89,23 +89,6 @@
 
 #define PIN(x, b)	(b + x)
 
-#define GROUP(grp, r, b)						\
-	{								\
-		.name = #grp,						\
-		.pins = grp ## _pins,					\
-		.num_pins = ARRAY_SIZE(grp ## _pins),			\
-		.reg = r,						\
-		.bit = b,						\
-	 }
-
-#define GPIO_GROUP(gpio, b)						\
-	{								\
-		.name = #gpio,						\
-		.pins = (const unsigned int[]){ PIN(gpio, b) },		\
-		.num_pins = 1,						\
-		.is_gpio = true,					\
-	 }
-
 #define FUNCTION(fn)							\
 	{								\
 		.name = #fn,						\
@@ -131,6 +114,20 @@
 
 extern const struct pinctrl_ops meson_pinctrl_ops;
 
+int meson_pinctrl_get_groups_count(struct udevice *dev);
+const char *meson_pinctrl_get_group_name(struct udevice *dev,
+					 unsigned int selector);
+int meson_pinmux_get_functions_count(struct udevice *dev);
+const char *meson_pinmux_get_function_name(struct udevice *dev,
+					   unsigned int selector);
 int meson_pinctrl_probe(struct udevice *dev);
 
+int meson_gpio_get(struct udevice *dev, unsigned int offset);
+int meson_gpio_set(struct udevice *dev, unsigned int offset, int value);
+int meson_gpio_get_direction(struct udevice *dev, unsigned int offset);
+int meson_gpio_direction_input(struct udevice *dev, unsigned int offset);
+int meson_gpio_direction_output(struct udevice *dev, unsigned int offset,
+				int value);
+int meson_gpio_probe(struct udevice *dev);
+
 #endif /* __PINCTRL_MESON_H__ */
diff --git a/drivers/power/domain/Kconfig b/drivers/power/domain/Kconfig
index a08b428..93deaef 100644
--- a/drivers/power/domain/Kconfig
+++ b/drivers/power/domain/Kconfig
@@ -23,6 +23,13 @@
           Enable support for manipulating NXP i.MX8 on-SoC power domains via IPC
           requests to the SCU.
 
+config MTK_POWER_DOMAIN
+	bool "Enable the MediaTek power domain driver"
+	depends on POWER_DOMAIN && ARCH_MEDIATEK
+	help
+	  Enable support for manipulating MediaTek power domains via MMIO
+	  mapped registers.
+
 config MESON_GX_VPU_POWER_DOMAIN
 	bool "Enable Amlogic Meson GX VPU power domain driver"
 	depends on ARCH_MESON
diff --git a/drivers/power/domain/Makefile b/drivers/power/domain/Makefile
index b08d18f..695aafe 100644
--- a/drivers/power/domain/Makefile
+++ b/drivers/power/domain/Makefile
@@ -6,6 +6,7 @@
 obj-$(CONFIG_$(SPL_)POWER_DOMAIN) += power-domain-uclass.o
 obj-$(CONFIG_BCM6328_POWER_DOMAIN) += bcm6328-power-domain.o
 obj-$(CONFIG_IMX8_POWER_DOMAIN) += imx8-power-domain.o
+obj-$(CONFIG_MTK_POWER_DOMAIN) += mtk-power-domain.o
 obj-$(CONFIG_MESON_GX_VPU_POWER_DOMAIN) += meson-gx-pwrc-vpu.o
 obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain.o
 obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain-test.o
diff --git a/drivers/power/domain/mtk-power-domain.c b/drivers/power/domain/mtk-power-domain.c
new file mode 100644
index 0000000..c67e880
--- /dev/null
+++ b/drivers/power/domain/mtk-power-domain.c
@@ -0,0 +1,406 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <power-domain-uclass.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <linux/iopoll.h>
+
+#include <dt-bindings/power/mt7623-power.h>
+#include <dt-bindings/power/mt7629-power.h>
+
+#define SPM_EN			(0xb16 << 16 | 0x1)
+#define SPM_VDE_PWR_CON		0x0210
+#define SPM_MFG_PWR_CON		0x0214
+#define SPM_ISP_PWR_CON		0x0238
+#define SPM_DIS_PWR_CON		0x023c
+#define SPM_CONN_PWR_CON	0x0280
+#define SPM_BDP_PWR_CON		0x029c
+#define SPM_ETH_PWR_CON		0x02a0
+#define SPM_HIF_PWR_CON		0x02a4
+#define SPM_IFR_MSC_PWR_CON	0x02a8
+#define SPM_ETHSYS_PWR_CON	0x2e0
+#define SPM_HIF0_PWR_CON	0x2e4
+#define SPM_HIF1_PWR_CON	0x2e8
+#define SPM_PWR_STATUS		0x60c
+#define SPM_PWR_STATUS_2ND	0x610
+
+#define PWR_RST_B_BIT		BIT(0)
+#define PWR_ISO_BIT		BIT(1)
+#define PWR_ON_BIT		BIT(2)
+#define PWR_ON_2ND_BIT		BIT(3)
+#define PWR_CLK_DIS_BIT		BIT(4)
+
+#define PWR_STATUS_CONN		BIT(1)
+#define PWR_STATUS_DISP		BIT(3)
+#define PWR_STATUS_MFG		BIT(4)
+#define PWR_STATUS_ISP		BIT(5)
+#define PWR_STATUS_VDEC		BIT(7)
+#define PWR_STATUS_BDP		BIT(14)
+#define PWR_STATUS_ETH		BIT(15)
+#define PWR_STATUS_HIF		BIT(16)
+#define PWR_STATUS_IFR_MSC	BIT(17)
+#define PWR_STATUS_ETHSYS	BIT(24)
+#define PWR_STATUS_HIF0		BIT(25)
+#define PWR_STATUS_HIF1		BIT(26)
+
+/* Infrasys configuration */
+#define INFRA_TOPDCM_CTRL	0x10
+#define INFRA_TOPAXI_PROT_EN	0x220
+#define INFRA_TOPAXI_PROT_STA1	0x228
+
+#define DCM_TOP_EN		BIT(0)
+
+enum scp_domain_type {
+	SCPSYS_MT7623,
+	SCPSYS_MT7629,
+};
+
+struct scp_domain;
+
+struct scp_domain_data {
+	struct scp_domain *scpd;
+	u32 sta_mask;
+	int ctl_offs;
+	u32 sram_pdn_bits;
+	u32 sram_pdn_ack_bits;
+	u32 bus_prot_mask;
+};
+
+struct scp_domain {
+	void __iomem *base;
+	void __iomem *infracfg;
+	enum scp_domain_type type;
+	struct scp_domain_data *data;
+};
+
+static struct scp_domain_data scp_domain_mt7623[] = {
+	[MT7623_POWER_DOMAIN_CONN] = {
+		.sta_mask = PWR_STATUS_CONN,
+		.ctl_offs = SPM_CONN_PWR_CON,
+		.bus_prot_mask = BIT(8) | BIT(2),
+	},
+	[MT7623_POWER_DOMAIN_DISP] = {
+		.sta_mask = PWR_STATUS_DISP,
+		.ctl_offs = SPM_DIS_PWR_CON,
+		.sram_pdn_bits = GENMASK(11, 8),
+		.bus_prot_mask = BIT(2),
+	},
+	[MT7623_POWER_DOMAIN_MFG] = {
+		.sta_mask = PWR_STATUS_MFG,
+		.ctl_offs = SPM_MFG_PWR_CON,
+		.sram_pdn_bits = GENMASK(11, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+	},
+	[MT7623_POWER_DOMAIN_VDEC] = {
+		.sta_mask = PWR_STATUS_VDEC,
+		.ctl_offs = SPM_VDE_PWR_CON,
+		.sram_pdn_bits = GENMASK(11, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+	},
+	[MT7623_POWER_DOMAIN_ISP] = {
+		.sta_mask = PWR_STATUS_ISP,
+		.ctl_offs = SPM_ISP_PWR_CON,
+		.sram_pdn_bits = GENMASK(11, 8),
+		.sram_pdn_ack_bits = GENMASK(13, 12),
+	},
+	[MT7623_POWER_DOMAIN_BDP] = {
+		.sta_mask = PWR_STATUS_BDP,
+		.ctl_offs = SPM_BDP_PWR_CON,
+		.sram_pdn_bits = GENMASK(11, 8),
+	},
+	[MT7623_POWER_DOMAIN_ETH] = {
+		.sta_mask = PWR_STATUS_ETH,
+		.ctl_offs = SPM_ETH_PWR_CON,
+		.sram_pdn_bits = GENMASK(11, 8),
+		.sram_pdn_ack_bits = GENMASK(15, 12),
+	},
+	[MT7623_POWER_DOMAIN_HIF] = {
+		.sta_mask = PWR_STATUS_HIF,
+		.ctl_offs = SPM_HIF_PWR_CON,
+		.sram_pdn_bits = GENMASK(11, 8),
+		.sram_pdn_ack_bits = GENMASK(15, 12),
+	},
+	[MT7623_POWER_DOMAIN_IFR_MSC] = {
+		.sta_mask = PWR_STATUS_IFR_MSC,
+		.ctl_offs = SPM_IFR_MSC_PWR_CON,
+	},
+};
+
+static struct scp_domain_data scp_domain_mt7629[] = {
+	[MT7629_POWER_DOMAIN_ETHSYS] = {
+		.sta_mask = PWR_STATUS_ETHSYS,
+		.ctl_offs = SPM_ETHSYS_PWR_CON,
+		.sram_pdn_bits = GENMASK(11, 8),
+		.sram_pdn_ack_bits = GENMASK(15, 12),
+		.bus_prot_mask = (BIT(3) | BIT(17)),
+	},
+	[MT7629_POWER_DOMAIN_HIF0] = {
+		.sta_mask = PWR_STATUS_HIF0,
+		.ctl_offs = SPM_HIF0_PWR_CON,
+		.sram_pdn_bits = GENMASK(11, 8),
+		.sram_pdn_ack_bits = GENMASK(15, 12),
+		.bus_prot_mask = GENMASK(25, 24),
+	},
+	[MT7629_POWER_DOMAIN_HIF1] = {
+		.sta_mask = PWR_STATUS_HIF1,
+		.ctl_offs = SPM_HIF1_PWR_CON,
+		.sram_pdn_bits = GENMASK(11, 8),
+		.sram_pdn_ack_bits = GENMASK(15, 12),
+		.bus_prot_mask = GENMASK(28, 26),
+	},
+};
+
+/**
+ * This function enables the bus protection bits for disabled power
+ * domains so that the system does not hang when some unit accesses the
+ * bus while in power down.
+ */
+static int mtk_infracfg_set_bus_protection(void __iomem *infracfg,
+					   u32 mask)
+{
+	u32 val;
+
+	clrsetbits_le32(infracfg + INFRA_TOPAXI_PROT_EN, mask, mask);
+
+	return readl_poll_timeout(infracfg + INFRA_TOPAXI_PROT_STA1, val,
+				  (val & mask) == mask, 100);
+}
+
+static int mtk_infracfg_clear_bus_protection(void __iomem *infracfg,
+					     u32 mask)
+{
+	u32 val;
+
+	clrbits_le32(infracfg + INFRA_TOPAXI_PROT_EN, mask);
+
+	return readl_poll_timeout(infracfg + INFRA_TOPAXI_PROT_STA1, val,
+				  !(val & mask), 100);
+}
+
+static int scpsys_domain_is_on(struct scp_domain_data *data)
+{
+	struct scp_domain *scpd = data->scpd;
+	u32 sta = readl(scpd->base + SPM_PWR_STATUS) &
+			data->sta_mask;
+	u32 sta2 = readl(scpd->base + SPM_PWR_STATUS_2ND) &
+			 data->sta_mask;
+
+	/*
+	 * A domain is on when both status bits are set. If only one is set
+	 * return an error. This happens while powering up a domain
+	 */
+	if (sta && sta2)
+		return true;
+	if (!sta && !sta2)
+		return false;
+
+	return -EINVAL;
+}
+
+static int scpsys_power_on(struct power_domain *power_domain)
+{
+	struct scp_domain *scpd = dev_get_priv(power_domain->dev);
+	struct scp_domain_data *data = &scpd->data[power_domain->id];
+	void __iomem *ctl_addr = scpd->base + data->ctl_offs;
+	u32 pdn_ack = data->sram_pdn_ack_bits;
+	u32 val;
+	int ret, tmp;
+
+	writel(SPM_EN, scpd->base);
+
+	val = readl(ctl_addr);
+	val |= PWR_ON_BIT;
+	writel(val, ctl_addr);
+
+	val |= PWR_ON_2ND_BIT;
+	writel(val, ctl_addr);
+
+	ret = readx_poll_timeout(scpsys_domain_is_on, data, tmp, tmp > 0,
+				 100);
+	if (ret < 0)
+		return ret;
+
+	val &= ~PWR_CLK_DIS_BIT;
+	writel(val, ctl_addr);
+
+	val &= ~PWR_ISO_BIT;
+	writel(val, ctl_addr);
+
+	val |= PWR_RST_B_BIT;
+	writel(val, ctl_addr);
+
+	val &= ~data->sram_pdn_bits;
+	writel(val, ctl_addr);
+
+	ret = readl_poll_timeout(ctl_addr, tmp, !(tmp & pdn_ack), 100);
+	if (ret < 0)
+		return ret;
+
+	if (data->bus_prot_mask) {
+		ret = mtk_infracfg_clear_bus_protection(scpd->infracfg,
+							data->bus_prot_mask);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int scpsys_power_off(struct power_domain *power_domain)
+{
+	struct scp_domain *scpd = dev_get_priv(power_domain->dev);
+	struct scp_domain_data *data = &scpd->data[power_domain->id];
+	void __iomem *ctl_addr = scpd->base + data->ctl_offs;
+	u32 pdn_ack = data->sram_pdn_ack_bits;
+	u32 val;
+	int ret, tmp;
+
+	if (data->bus_prot_mask) {
+		ret = mtk_infracfg_set_bus_protection(scpd->infracfg,
+						      data->bus_prot_mask);
+		if (ret)
+			return ret;
+	}
+
+	val = readl(ctl_addr);
+	val |= data->sram_pdn_bits;
+	writel(val, ctl_addr);
+
+	ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == pdn_ack,
+				 100);
+	if (ret < 0)
+		return ret;
+
+	val |= PWR_ISO_BIT;
+	writel(val, ctl_addr);
+
+	val &= ~PWR_RST_B_BIT;
+	writel(val, ctl_addr);
+
+	val |= PWR_CLK_DIS_BIT;
+	writel(val, ctl_addr);
+
+	val &= ~PWR_ON_BIT;
+	writel(val, ctl_addr);
+
+	val &= ~PWR_ON_2ND_BIT;
+	writel(val, ctl_addr);
+
+	ret = readx_poll_timeout(scpsys_domain_is_on, data, tmp, !tmp, 100);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int scpsys_power_request(struct power_domain *power_domain)
+{
+	struct scp_domain *scpd = dev_get_priv(power_domain->dev);
+	struct scp_domain_data *data;
+
+	data = &scpd->data[power_domain->id];
+	data->scpd = scpd;
+
+	return 0;
+}
+
+static int scpsys_power_free(struct power_domain *power_domain)
+{
+	return 0;
+}
+
+static int mtk_power_domain_hook(struct udevice *dev)
+{
+	struct scp_domain *scpd = dev_get_priv(dev);
+
+	scpd->type = (enum scp_domain_type)dev_get_driver_data(dev);
+
+	switch (scpd->type) {
+	case SCPSYS_MT7623:
+		scpd->data = scp_domain_mt7623;
+		break;
+	case SCPSYS_MT7629:
+		scpd->data = scp_domain_mt7629;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mtk_power_domain_probe(struct udevice *dev)
+{
+	struct ofnode_phandle_args args;
+	struct scp_domain *scpd = dev_get_priv(dev);
+	struct regmap *regmap;
+	struct clk_bulk bulk;
+	int err;
+
+	scpd->base = dev_read_addr_ptr(dev);
+	if (!scpd->base)
+		return -ENOENT;
+
+	err = mtk_power_domain_hook(dev);
+	if (err)
+		return err;
+
+	/* get corresponding syscon phandle */
+	err = dev_read_phandle_with_args(dev, "infracfg", NULL, 0, 0, &args);
+	if (err)
+		return err;
+
+	regmap = syscon_node_to_regmap(args.node);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	scpd->infracfg = regmap_get_range(regmap, 0);
+	if (!scpd->infracfg)
+		return -ENOENT;
+
+	/* enable Infra DCM */
+	setbits_le32(scpd->infracfg + INFRA_TOPDCM_CTRL, DCM_TOP_EN);
+
+	err = clk_get_bulk(dev, &bulk);
+	if (err)
+		return err;
+
+	return clk_enable_bulk(&bulk);
+}
+
+static const struct udevice_id mtk_power_domain_ids[] = {
+	{
+		.compatible = "mediatek,mt7623-scpsys",
+		.data = SCPSYS_MT7623,
+	},
+	{
+		.compatible = "mediatek,mt7629-scpsys",
+		.data = SCPSYS_MT7629,
+	},
+	{ /* sentinel */ }
+};
+
+struct power_domain_ops mtk_power_domain_ops = {
+	.free = scpsys_power_free,
+	.off = scpsys_power_off,
+	.on = scpsys_power_on,
+	.request = scpsys_power_request,
+};
+
+U_BOOT_DRIVER(mtk_power_domain) = {
+	.name = "mtk_power_domain",
+	.id = UCLASS_POWER_DOMAIN,
+	.ops = &mtk_power_domain_ops,
+	.probe = mtk_power_domain_probe,
+	.of_match = mtk_power_domain_ids,
+	.priv_auto_alloc_size = sizeof(struct scp_domain),
+};
diff --git a/drivers/power/pmic/act8846.c b/drivers/power/pmic/act8846.c
index b0c759c..186fa90 100644
--- a/drivers/power/pmic/act8846.c
+++ b/drivers/power/pmic/act8846.c
@@ -50,7 +50,7 @@
 
 	regulators_node = dev_read_subnode(dev, "regulators");
 	if (!ofnode_valid(regulators_node)) {
-		debug("%s: %s regulators subnode not found!", __func__,
+		debug("%s: %s regulators subnode not found!\n", __func__,
 		      dev->name);
 		return -ENXIO;
 	}
diff --git a/drivers/power/pmic/as3722.c b/drivers/power/pmic/as3722.c
index 63df613..54adcbf 100644
--- a/drivers/power/pmic/as3722.c
+++ b/drivers/power/pmic/as3722.c
@@ -45,14 +45,14 @@
 
 	ret = pmic_reg_read(dev, AS3722_ASIC_ID1);
 	if (ret < 0) {
-		pr_err("failed to read ID1 register: %d", ret);
+		pr_err("failed to read ID1 register: %d\n", ret);
 		return ret;
 	}
 	*idp = ret;
 
 	ret = pmic_reg_read(dev, AS3722_ASIC_ID2);
 	if (ret < 0) {
-		pr_err("failed to read ID2 register: %d", ret);
+		pr_err("failed to read ID2 register: %d\n", ret);
 		return ret;
 	}
 	*revisionp = ret;
@@ -70,7 +70,7 @@
 
 	ret = pmic_reg_write(dev, AS3722_SD_VOLTAGE(sd), value);
 	if (ret < 0) {
-		pr_err("failed to write SD%u voltage register: %d", sd, ret);
+		pr_err("failed to write SD%u voltage register: %d\n", sd, ret);
 		return ret;
 	}
 
@@ -86,8 +86,8 @@
 
 	ret = pmic_reg_write(dev, AS3722_LDO_VOLTAGE(ldo), value);
 	if (ret < 0) {
-		pr_err("failed to write LDO%u voltage register: %d", ldo,
-		      ret);
+		pr_err("failed to write LDO%u voltage register: %d\n", ldo,
+		       ret);
 		return ret;
 	}
 
@@ -101,12 +101,12 @@
 
 	ret = as3722_read_id(dev, &id, &revision);
 	if (ret < 0) {
-		pr_err("failed to read ID: %d", ret);
+		pr_err("failed to read ID: %d\n", ret);
 		return ret;
 	}
 
 	if (id != AS3722_DEVICE_ID) {
-		pr_err("unknown device");
+		pr_err("unknown device\n");
 		return -ENOENT;
 	}
 
diff --git a/drivers/power/pmic/as3722_gpio.c b/drivers/power/pmic/as3722_gpio.c
index 36f4fbf..96943bc 100644
--- a/drivers/power/pmic/as3722_gpio.c
+++ b/drivers/power/pmic/as3722_gpio.c
@@ -25,7 +25,7 @@
 
 	err = pmic_reg_write(pmic, AS3722_GPIO_CONTROL(gpio), value);
 	if (err) {
-		pr_err("failed to configure GPIO#%u: %d", gpio, err);
+		pr_err("failed to configure GPIO#%u: %d\n", gpio, err);
 		return err;
 	}
 
@@ -45,7 +45,7 @@
 
 	err = pmic_reg_read(pmic, AS3722_GPIO_SIGNAL_OUT);
 	if (err < 0) {
-		pr_err("failed to read GPIO signal out register: %d", err);
+		pr_err("failed to read GPIO signal out register: %d\n", err);
 		return err;
 	}
 	value = err;
@@ -60,7 +60,7 @@
 
 	err = pmic_reg_write(pmic, AS3722_GPIO_SIGNAL_OUT, value);
 	if (err) {
-		pr_err("failed to set GPIO#%u %s: %d", gpio, l, err);
+		pr_err("failed to set GPIO#%u %s: %d\n", gpio, l, err);
 		return err;
 	}
 
@@ -83,13 +83,14 @@
 
 	err = pmic_reg_write(pmic, AS3722_GPIO_CONTROL(gpio), value);
 	if (err) {
-		pr_err("failed to configure GPIO#%u as output: %d", gpio, err);
+		pr_err("failed to configure GPIO#%u as output: %d\n", gpio,
+		       err);
 		return err;
 	}
 
 	err = as3722_gpio_set_value(pmic, gpio, value);
 	if (err < 0) {
-		pr_err("failed to set GPIO#%u high: %d", gpio, err);
+		pr_err("failed to set GPIO#%u high: %d\n", gpio, err);
 		return err;
 	}
 
diff --git a/drivers/power/pmic/i2c_pmic_emul.c b/drivers/power/pmic/i2c_pmic_emul.c
index 61fa76a..80efc02 100644
--- a/drivers/power/pmic/i2c_pmic_emul.c
+++ b/drivers/power/pmic/i2c_pmic_emul.c
@@ -104,7 +104,7 @@
 static int sandbox_i2c_pmic_ofdata_to_platdata(struct udevice *emul)
 {
 	struct sandbox_i2c_pmic_plat_data *plat = dev_get_platdata(emul);
-	struct udevice *pmic_dev = dev_get_parent(emul);
+	struct udevice *pmic_dev = i2c_emul_get_device(emul);
 	struct uc_pmic_priv *priv = dev_get_uclass_priv(pmic_dev);
 	const u8 *reg_defaults;
 
diff --git a/drivers/power/pmic/lp873x.c b/drivers/power/pmic/lp873x.c
index 432ad4c..4ae4043 100644
--- a/drivers/power/pmic/lp873x.c
+++ b/drivers/power/pmic/lp873x.c
@@ -24,7 +24,7 @@
 			  int len)
 {
 	if (dm_i2c_write(dev, reg, buff, len)) {
-		pr_err("write error to device: %p register: %#x!", dev, reg);
+		pr_err("write error to device: %p register: %#x!\n", dev, reg);
 		return -EIO;
 	}
 
@@ -34,7 +34,7 @@
 static int lp873x_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 {
 	if (dm_i2c_read(dev, reg, buff, len)) {
-		pr_err("read error from device: %p register: %#x!", dev, reg);
+		pr_err("read error from device: %p register: %#x!\n", dev, reg);
 		return -EIO;
 	}
 
@@ -48,7 +48,7 @@
 
 	regulators_node = dev_read_subnode(dev, "regulators");
 	if (!ofnode_valid(regulators_node)) {
-		debug("%s: %s regulators subnode not found!", __func__,
+		debug("%s: %s regulators subnode not found!\n", __func__,
 		      dev->name);
 		return -ENXIO;
 	}
diff --git a/drivers/power/pmic/lp87565.c b/drivers/power/pmic/lp87565.c
index 450dbb8..3e5fc60 100644
--- a/drivers/power/pmic/lp87565.c
+++ b/drivers/power/pmic/lp87565.c
@@ -26,7 +26,7 @@
 
 	ret = dm_i2c_write(dev, reg, buff, len);
 	if (ret)
-		pr_err("write error to device: %p register: %#x!", dev, reg);
+		pr_err("write error to device: %p register: %#x!\n", dev, reg);
 
 	return ret;
 }
@@ -37,7 +37,7 @@
 
 	ret = dm_i2c_read(dev, reg, buff, len);
 	if (ret)
-		pr_err("read error from device: %p register: %#x!", dev, reg);
+		pr_err("read error from device: %p register: %#x!\n", dev, reg);
 
 	return ret;
 }
@@ -49,7 +49,7 @@
 
 	regulators_node = dev_read_subnode(dev, "regulators");
 	if (!ofnode_valid(regulators_node)) {
-		debug("%s: %s regulators subnode not found!", __func__,
+		debug("%s: %s regulators subnode not found!\n", __func__,
 		      dev->name);
 		return -ENXIO;
 	}
diff --git a/drivers/power/pmic/max77686.c b/drivers/power/pmic/max77686.c
index 834713a..8e3a8cf 100644
--- a/drivers/power/pmic/max77686.c
+++ b/drivers/power/pmic/max77686.c
@@ -28,7 +28,7 @@
 			  int len)
 {
 	if (dm_i2c_write(dev, reg, buff, len)) {
-		pr_err("write error to device: %p register: %#x!", dev, reg);
+		pr_err("write error to device: %p register: %#x!\n", dev, reg);
 		return -EIO;
 	}
 
@@ -38,7 +38,7 @@
 static int max77686_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 {
 	if (dm_i2c_read(dev, reg, buff, len)) {
-		pr_err("read error from device: %p register: %#x!", dev, reg);
+		pr_err("read error from device: %p register: %#x!\n", dev, reg);
 		return -EIO;
 	}
 
@@ -52,8 +52,8 @@
 
 	regulators_node = dev_read_subnode(dev, "voltage-regulators");
 	if (!ofnode_valid(regulators_node)) {
-		debug("%s: %s regulators subnode not found!", __func__,
-							     dev->name);
+		debug("%s: %s regulators subnode not found!\n", __func__,
+		      dev->name);
 		return -ENXIO;
 	}
 
diff --git a/drivers/power/pmic/max8997.c b/drivers/power/pmic/max8997.c
index 0dcdbad..dbae155 100644
--- a/drivers/power/pmic/max8997.c
+++ b/drivers/power/pmic/max8997.c
@@ -23,7 +23,7 @@
 
 	ret = dm_i2c_write(dev, reg, buff, len);
 	if (ret)
-		pr_err("write error to device: %p register: %#x!", dev, reg);
+		pr_err("write error to device: %p register: %#x!\n", dev, reg);
 
 	return ret;
 }
@@ -34,7 +34,7 @@
 
 	ret = dm_i2c_read(dev, reg, buff, len);
 	if (ret)
-		pr_err("read error from device: %p register: %#x!", dev, reg);
+		pr_err("read error from device: %p register: %#x!\n", dev, reg);
 
 	return ret;
 }
diff --git a/drivers/power/pmic/max8998.c b/drivers/power/pmic/max8998.c
index f571add..f58d9f2 100644
--- a/drivers/power/pmic/max8998.c
+++ b/drivers/power/pmic/max8998.c
@@ -23,7 +23,7 @@
 
 	ret = dm_i2c_write(dev, reg, buff, len);
 	if (ret)
-		pr_err("write error to device: %p register: %#x!", dev, reg);
+		pr_err("write error to device: %p register: %#x!\n", dev, reg);
 
 	return ret;
 }
@@ -34,7 +34,7 @@
 
 	ret = dm_i2c_read(dev, reg, buff, len);
 	if (ret)
-		pr_err("read error from device: %p register: %#x!", dev, reg);
+		pr_err("read error from device: %p register: %#x!\n", dev, reg);
 
 	return ret;
 }
diff --git a/drivers/power/pmic/mc34708.c b/drivers/power/pmic/mc34708.c
index 2b2fc72..66253a4 100644
--- a/drivers/power/pmic/mc34708.c
+++ b/drivers/power/pmic/mc34708.c
@@ -38,7 +38,7 @@
 
 	ret = dm_i2c_write(dev, reg, buf, len);
 	if (ret)
-		printf("write error to device: %p register: %#x!", dev, reg);
+		printf("write error to device: %p register: %#x!\n", dev, reg);
 
 	return ret;
 }
@@ -53,7 +53,7 @@
 
 	ret = dm_i2c_read(dev, reg, buf, len);
 	if (ret)
-		printf("read error from device: %p register: %#x!", dev, reg);
+		printf("read error from device: %p register: %#x!\n", dev, reg);
 
 	buff[0] = buf[2];
 	buff[1] = buf[1];
diff --git a/drivers/power/pmic/palmas.c b/drivers/power/pmic/palmas.c
index 250a5d3..36be119 100644
--- a/drivers/power/pmic/palmas.c
+++ b/drivers/power/pmic/palmas.c
@@ -24,7 +24,7 @@
 			  int len)
 {
 	if (dm_i2c_write(dev, reg, buff, len)) {
-		pr_err("write error to device: %p register: %#x!", dev, reg);
+		pr_err("write error to device: %p register: %#x!\n", dev, reg);
 		return -EIO;
 	}
 
@@ -34,7 +34,7 @@
 static int palmas_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 {
 	if (dm_i2c_read(dev, reg, buff, len)) {
-		pr_err("read error from device: %p register: %#x!", dev, reg);
+		pr_err("read error from device: %p register: %#x!\n", dev, reg);
 		return -EIO;
 	}
 
@@ -60,14 +60,14 @@
 	}
 
 	if (!ofnode_valid(pmic_node)) {
-		debug("%s: %s pmic subnode not found!", __func__, dev->name);
+		debug("%s: %s pmic subnode not found!\n", __func__, dev->name);
 		return -ENXIO;
 	}
 
 	regulators_node = ofnode_find_subnode(pmic_node, "regulators");
 
 	if (!ofnode_valid(regulators_node)) {
-		debug("%s: %s reg subnode not found!", __func__, dev->name);
+		debug("%s: %s reg subnode not found!\n", __func__, dev->name);
 		return -ENXIO;
 	}
 
diff --git a/drivers/power/pmic/pfuze100.c b/drivers/power/pmic/pfuze100.c
index 8a5a899..6cf5f35 100644
--- a/drivers/power/pmic/pfuze100.c
+++ b/drivers/power/pmic/pfuze100.c
@@ -31,7 +31,7 @@
 			  int len)
 {
 	if (dm_i2c_write(dev, reg, buff, len)) {
-		pr_err("write error to device: %p register: %#x!", dev, reg);
+		pr_err("write error to device: %p register: %#x!\n", dev, reg);
 		return -EIO;
 	}
 
@@ -41,7 +41,7 @@
 static int pfuze100_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 {
 	if (dm_i2c_read(dev, reg, buff, len)) {
-		pr_err("read error from device: %p register: %#x!", dev, reg);
+		pr_err("read error from device: %p register: %#x!\n", dev, reg);
 		return -EIO;
 	}
 
@@ -55,7 +55,7 @@
 
 	regulators_node = dev_read_subnode(dev, "regulators");
 	if (!ofnode_valid(regulators_node)) {
-		debug("%s: %s regulators subnode not found!", __func__,
+		debug("%s: %s regulators subnode not found!\n", __func__,
 		      dev->name);
 		return -ENXIO;
 	}
diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
index c60dfff..25c339a 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -29,7 +29,7 @@
 
 	ret = dm_i2c_write(dev, reg, buff, len);
 	if (ret) {
-		debug("write error to device: %p register: %#x!", dev, reg);
+		debug("write error to device: %p register: %#x!\n", dev, reg);
 		return ret;
 	}
 
@@ -42,7 +42,7 @@
 
 	ret = dm_i2c_read(dev, reg, buff, len);
 	if (ret) {
-		debug("read error from device: %p register: %#x!", dev, reg);
+		debug("read error from device: %p register: %#x!\n", dev, reg);
 		return ret;
 	}
 
@@ -57,7 +57,7 @@
 
 	regulators_node = dev_read_subnode(dev, "regulators");
 	if (!ofnode_valid(regulators_node)) {
-		debug("%s: %s regulators subnode not found!", __func__,
+		debug("%s: %s regulators subnode not found!\n", __func__,
 		      dev->name);
 		return -ENXIO;
 	}
diff --git a/drivers/power/pmic/rn5t567.c b/drivers/power/pmic/rn5t567.c
index c3be3fe..f238396 100644
--- a/drivers/power/pmic/rn5t567.c
+++ b/drivers/power/pmic/rn5t567.c
@@ -24,7 +24,7 @@
 
 	ret = dm_i2c_write(dev, reg, buff, len);
 	if (ret) {
-		debug("write error to device: %p register: %#x!", dev, reg);
+		debug("write error to device: %p register: %#x!\n", dev, reg);
 		return ret;
 	}
 
@@ -37,7 +37,7 @@
 
 	ret = dm_i2c_read(dev, reg, buff, len);
 	if (ret) {
-		debug("read error from device: %p register: %#x!", dev, reg);
+		debug("read error from device: %p register: %#x!\n", dev, reg);
 		return ret;
 	}
 
diff --git a/drivers/power/pmic/s2mps11.c b/drivers/power/pmic/s2mps11.c
index e45d4bc..f2aab6c 100644
--- a/drivers/power/pmic/s2mps11.c
+++ b/drivers/power/pmic/s2mps11.c
@@ -30,7 +30,7 @@
 
 	ret = dm_i2c_write(dev, reg, buff, len);
 	if (ret)
-		pr_err("write error to device: %p register: %#x!", dev, reg);
+		pr_err("write error to device: %p register: %#x!\n", dev, reg);
 
 	return ret;
 }
@@ -41,7 +41,7 @@
 
 	ret = dm_i2c_read(dev, reg, buff, len);
 	if (ret)
-		pr_err("read error from device: %p register: %#x!", dev, reg);
+		pr_err("read error from device: %p register: %#x!\n", dev, reg);
 
 	return ret;
 }
@@ -53,8 +53,8 @@
 
 	regulators_node = dev_read_subnode(dev, "voltage-regulators");
 	if (!ofnode_valid(regulators_node)) {
-		debug("%s: %s regulators subnode not found!", __func__,
-							     dev->name);
+		debug("%s: %s regulators subnode not found!\n", __func__,
+		      dev->name);
 		return -ENXIO;
 	}
 
diff --git a/drivers/power/pmic/s5m8767.c b/drivers/power/pmic/s5m8767.c
index 54e44ce..b5ddd49 100644
--- a/drivers/power/pmic/s5m8767.c
+++ b/drivers/power/pmic/s5m8767.c
@@ -27,7 +27,7 @@
 			  int len)
 {
 	if (dm_i2c_write(dev, reg, buff, len)) {
-		pr_err("write error to device: %p register: %#x!", dev, reg);
+		pr_err("write error to device: %p register: %#x!\n", dev, reg);
 		return -EIO;
 	}
 
@@ -37,7 +37,7 @@
 static int s5m8767_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 {
 	if (dm_i2c_read(dev, reg, buff, len)) {
-		pr_err("read error from device: %p register: %#x!", dev, reg);
+		pr_err("read error from device: %p register: %#x!\n", dev, reg);
 		return -EIO;
 	}
 
@@ -56,7 +56,7 @@
 
 	node = dev_read_subnode(dev, "regulators");
 	if (!ofnode_valid(node)) {
-		debug("%s: %s regulators subnode not found!", __func__,
+		debug("%s: %s regulators subnode not found!\n", __func__,
 		      dev->name);
 		return -ENXIO;
 	}
diff --git a/drivers/power/pmic/sandbox.c b/drivers/power/pmic/sandbox.c
index 64e2f27..d787091 100644
--- a/drivers/power/pmic/sandbox.c
+++ b/drivers/power/pmic/sandbox.c
@@ -28,7 +28,7 @@
 			      const uint8_t *buff, int len)
 {
 	if (dm_i2c_write(dev, reg, buff, len)) {
-		pr_err("write error to device: %p register: %#x!", dev, reg);
+		pr_err("write error to device: %p register: %#x!\n", dev, reg);
 		return -EIO;
 	}
 
@@ -39,7 +39,7 @@
 			     uint8_t *buff, int len)
 {
 	if (dm_i2c_read(dev, reg, buff, len)) {
-		pr_err("read error from device: %p register: %#x!", dev, reg);
+		pr_err("read error from device: %p register: %#x!\n", dev, reg);
 		return -EIO;
 	}
 
diff --git a/drivers/power/pmic/stpmu1.c b/drivers/power/pmic/stpmu1.c
index 82351b6..47af012 100644
--- a/drivers/power/pmic/stpmu1.c
+++ b/drivers/power/pmic/stpmu1.c
@@ -61,7 +61,7 @@
 
 	regulators_node = dev_read_subnode(dev, "regulators");
 	if (!ofnode_valid(regulators_node)) {
-		dev_dbg(dev, "regulators subnode not found!");
+		dev_dbg(dev, "regulators subnode not found!\n");
 		return -ENXIO;
 	}
 	dev_dbg(dev, "found regulators subnode\n");
diff --git a/drivers/power/pmic/tps65090.c b/drivers/power/pmic/tps65090.c
index 1d3bf00..5b1d19f 100644
--- a/drivers/power/pmic/tps65090.c
+++ b/drivers/power/pmic/tps65090.c
@@ -26,7 +26,7 @@
 			  int len)
 {
 	if (dm_i2c_write(dev, reg, buff, len)) {
-		pr_err("write error to device: %p register: %#x!", dev, reg);
+		pr_err("write error to device: %p register: %#x!\n", dev, reg);
 		return -EIO;
 	}
 
@@ -39,8 +39,8 @@
 
 	ret = dm_i2c_read(dev, reg, buff, len);
 	if (ret) {
-		pr_err("read error %d from device: %p register: %#x!", ret, dev,
-		      reg);
+		pr_err("read error %d from device: %p register: %#x!\n", ret,
+		       dev, reg);
 		return -EIO;
 	}
 
@@ -54,7 +54,7 @@
 
 	regulators_node = dev_read_subnode(dev, "regulators");
 	if (!ofnode_valid(regulators_node)) {
-		debug("%s: %s regulators subnode not found!", __func__,
+		debug("%s: %s regulators subnode not found!\n", __func__,
 		      dev->name);
 		return -ENXIO;
 	}
diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
index e14c1cf..976ec66 100644
--- a/drivers/ram/Makefile
+++ b/drivers/ram/Makefile
@@ -13,3 +13,4 @@
 obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
 
 obj-$(CONFIG_K3_AM654_DDRSS) += k3-am654-ddrss.o
+obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
diff --git a/drivers/ram/mediatek/Makefile b/drivers/ram/mediatek/Makefile
new file mode 100644
index 0000000..95507b5
--- /dev/null
+++ b/drivers/ram/mediatek/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2018 MediaTek Inc.
+#
+# SPDX-License-Identifier:      GPL-2.0
+#
+
+obj-$(CONFIG_TARGET_MT7629) = ddr3-mt7629.o
diff --git a/drivers/ram/mediatek/ddr3-mt7629.c b/drivers/ram/mediatek/ddr3-mt7629.c
new file mode 100644
index 0000000..b413f49
--- /dev/null
+++ b/drivers/ram/mediatek/ddr3-mt7629.c
@@ -0,0 +1,766 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek DDR3 driver for MT7629 SoC
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Wu Zou <wu.zou@mediatek.com>
+ *	   Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <ram.h>
+#include <asm/io.h>
+
+/* EMI */
+#define EMI_CONA			0x000
+#define EMI_CONF			0x028
+#define EMI_CONM			0x060
+
+/* DDR PHY */
+#define DDRPHY_PLL1			0x0000
+#define DDRPHY_PLL2			0x0004
+#define DDRPHY_PLL3			0x0008
+#define DDRPHY_PLL4			0x000c
+#define DDRPHY_PLL5			0x0010
+#define DDRPHY_PLL7			0x0018
+#define DDRPHY_B0_DLL_ARPI0		0x0080
+#define DDRPHY_B0_DLL_ARPI1		0x0084
+#define DDRPHY_B0_DLL_ARPI2		0x0088
+#define DDRPHY_B0_DLL_ARPI3		0x008c
+#define DDRPHY_B0_DLL_ARPI4		0x0090
+#define DDRPHY_B0_DLL_ARPI5		0x0094
+#define DDRPHY_B0_DQ2			0x00a0
+#define DDRPHY_B0_DQ3			0x00a4
+#define DDRPHY_B0_DQ4			0x00a8
+#define DDRPHY_B0_DQ5			0x00ac
+#define DDRPHY_B0_DQ6			0x00b0
+#define DDRPHY_B0_DQ7			0x00b4
+#define DDRPHY_B0_DQ8			0x00b8
+#define DDRPHY_B1_DLL_ARPI0		0x0100
+#define DDRPHY_B1_DLL_ARPI1		0x0104
+#define DDRPHY_B1_DLL_ARPI2		0x0108
+#define DDRPHY_B1_DLL_ARPI3		0x010c
+#define DDRPHY_B1_DLL_ARPI4		0x0110
+#define DDRPHY_B1_DLL_ARPI5		0x0114
+#define DDRPHY_B1_DQ2			0x0120
+#define DDRPHY_B1_DQ3			0x0124
+#define DDRPHY_B1_DQ4			0x0128
+#define DDRPHY_B1_DQ5			0x012c
+#define DDRPHY_B1_DQ6			0x0130
+#define DDRPHY_B1_DQ7			0x0134
+#define DDRPHY_B1_DQ8			0x0138
+#define DDRPHY_CA_DLL_ARPI0		0x0180
+#define DDRPHY_CA_DLL_ARPI1		0x0184
+#define DDRPHY_CA_DLL_ARPI2		0x0188
+#define DDRPHY_CA_DLL_ARPI3		0x018c
+#define DDRPHY_CA_DLL_ARPI4		0x0190
+#define DDRPHY_CA_DLL_ARPI5		0x0194
+#define DDRPHY_CA_CMD2			0x01a0
+#define DDRPHY_CA_CMD3			0x01a4
+#define DDRPHY_CA_CMD5			0x01ac
+#define DDRPHY_CA_CMD6			0x01b0
+#define DDRPHY_CA_CMD7			0x01b4
+#define DDRPHY_CA_CMD8			0x01b8
+#define DDRPHY_MISC_VREF_CTRL		0x0264
+#define DDRPHY_MISC_IMP_CTRL0		0x0268
+#define DDRPHY_MISC_IMP_CTRL1		0x026c
+#define DDRPHY_MISC_SHU_OPT		0x0270
+#define DDRPHY_MISC_SPM_CTRL0		0x0274
+#define DDRPHY_MISC_SPM_CTRL1		0x0278
+#define DDRPHY_MISC_SPM_CTRL2		0x027c
+#define DDRPHY_MISC_CG_CTRL0		0x0284
+#define DDRPHY_MISC_CG_CTRL1		0x0288
+#define DDRPHY_MISC_CG_CTRL2		0x028c
+#define DDRPHY_MISC_CG_CTRL4		0x0294
+#define DDRPHY_MISC_CTRL0		0x029c
+#define DDRPHY_MISC_CTRL1		0x02a0
+#define DDRPHY_MISC_CTRL3		0x02a8
+#define DDRPHY_MISC_RXDVS1		0x05e4
+#define DDRPHY_SHU1_B0_DQ4		0x0c10
+#define DDRPHY_SHU1_B0_DQ5		0x0c14
+#define DDRPHY_SHU1_B0_DQ6		0x0c18
+#define DDRPHY_SHU1_B0_DQ7		0x0c1c
+#define DDRPHY_SHU1_B1_DQ4		0x0c90
+#define DDRPHY_SHU1_B1_DQ5		0x0c94
+#define DDRPHY_SHU1_B1_DQ6		0x0c98
+#define DDRPHY_SHU1_B1_DQ7		0x0c9c
+#define DDRPHY_SHU1_CA_CMD2		0x0d08
+#define DDRPHY_SHU1_CA_CMD4		0x0d10
+#define DDRPHY_SHU1_CA_CMD5		0x0d14
+#define DDRPHY_SHU1_CA_CMD6		0x0d18
+#define DDRPHY_SHU1_CA_CMD7		0x0d1c
+#define DDRPHY_SHU1_PLL0		0x0d80
+#define DDRPHY_SHU1_PLL1		0x0d84
+#define DDRPHY_SHU1_PLL4		0x0d90
+#define DDRPHY_SHU1_PLL5		0x0d94
+#define DDRPHY_SHU1_PLL6		0x0d98
+#define DDRPHY_SHU1_PLL7		0x0d9C
+#define DDRPHY_SHU1_PLL8		0x0da0
+#define DDRPHY_SHU1_PLL9		0x0da4
+#define DDRPHY_SHU1_PLL10		0x0da8
+#define DDRPHY_SHU1_PLL11		0x0dac
+#define DDRPHY_SHU1_R0_B0_DQ2		0x0e08
+#define DDRPHY_SHU1_R0_B0_DQ3		0x0e0c
+#define DDRPHY_SHU1_R0_B0_DQ4		0x0e10
+#define DDRPHY_SHU1_R0_B0_DQ5		0x0e14
+#define DDRPHY_SHU1_R0_B0_DQ6		0x0e18
+#define DDRPHY_SHU1_R0_B0_DQ7		0x0e1c
+#define DDRPHY_SHU1_R0_B1_DQ2		0x0e58
+#define DDRPHY_SHU1_R0_B1_DQ3		0x0e5c
+#define DDRPHY_SHU1_R0_B1_DQ4		0x0e60
+#define DDRPHY_SHU1_R0_B1_DQ5		0x0e64
+#define DDRPHY_SHU1_R0_B1_DQ6		0x0e68
+#define DDRPHY_SHU1_R0_B1_DQ7		0x0e6c
+#define DDRPHY_SHU1_R0_CA_CMD9		0x0ec4
+#define DDRPHY_SHU1_R1_B0_DQ2		0x0f08
+#define DDRPHY_SHU1_R1_B0_DQ3		0x0f0c
+#define DDRPHY_SHU1_R1_B0_DQ4		0x0f10
+#define DDRPHY_SHU1_R1_B0_DQ5		0x0f14
+#define DDRPHY_SHU1_R1_B0_DQ6		0x0f18
+#define DDRPHY_SHU1_R1_B0_DQ7		0x0f1c
+#define DDRPHY_SHU1_R1_B1_DQ2		0x0f58
+#define DDRPHY_SHU1_R1_B1_DQ3		0x0f5c
+#define DDRPHY_SHU1_R1_B1_DQ4		0x0f60
+#define DDRPHY_SHU1_R1_B1_DQ5		0x0f64
+#define DDRPHY_SHU1_R1_B1_DQ6		0x0f68
+#define DDRPHY_SHU1_R1_B1_DQ7		0x0f6c
+#define DDRPHY_SHU1_R1_CA_CMD9		0x0fc4
+
+/* DRAMC */
+#define DRAMC_DDRCONF0			0x0000
+#define DRAMC_DRAMCTRL			0x0004
+#define DRAMC_MISCTL0			0x0008
+#define DRAMC_PERFCTL0			0x000c
+#define DRAMC_ARBCTL			0x0010
+#define DRAMC_RSTMASK			0x001c
+#define DRAMC_PADCTRL			0x0020
+#define DRAMC_CKECTRL			0x0024
+#define DRAMC_RKCFG			0x0034
+#define DRAMC_DRAMC_PD_CTRL		0x0038
+#define DRAMC_CLKAR			0x003c
+#define DRAMC_CLKCTRL			0x0040
+#define DRAMC_SREFCTRL			0x0048
+#define DRAMC_REFCTRL0			0x004c
+#define DRAMC_REFCTRL1			0x0050
+#define DRAMC_REFRATRE_FILTER		0x0054
+#define DRAMC_ZQCS			0x0058
+#define DRAMC_MRS			0x005c
+#define DRAMC_SPCMD			0x0060
+#define DRAMC_SPCMDCTRL			0x0064
+#define DRAMC_HW_MRR_FUN		0x0074
+#define DRAMC_TEST2_1			0x0094
+#define DRAMC_TEST2_2			0x0098
+#define DRAMC_TEST2_3			0x009c
+#define DRAMC_TEST2_4			0x00a0
+#define DRAMC_CATRAINING1		0x00b0
+#define DRAMC_DUMMY_RD			0x00d0
+#define DRAMC_SHUCTRL			0x00d4
+#define DRAMC_SHUCTRL2			0x00dc
+#define DRAMC_STBCAL			0x0200
+#define DRAMC_STBCAL1			0x0204
+#define DRAMC_EYESCAN			0x020c
+#define DRAMC_DVFSDLL			0x0210
+#define DRAMC_SHU_ACTIM0		0x0800
+#define DRAMC_SHU_ACTIM1		0x0804
+#define DRAMC_SHU_ACTIM2		0x0808
+#define DRAMC_SHU_ACTIM3		0x080c
+#define DRAMC_SHU_ACTIM4		0x0810
+#define DRAMC_SHU_ACTIM5		0x0814
+#define DRAMC_SHU_ACTIM_XRT		0x081c
+#define DRAMC_SHU_AC_TIME_05T		0x0820
+#define DRAMC_SHU_CONF0			0x0840
+#define DRAMC_SHU_CONF1			0x0844
+#define DRAMC_SHU_CONF2			0x0848
+#define DRAMC_SHU_CONF3			0x084c
+#define DRAMC_SHU_RANKCTL		0x0858
+#define DRAMC_SHU_CKECTRL		0x085c
+#define DRAMC_SHU_ODTCTRL		0x0860
+#define DRAMC_SHU_PIPE			0x0878
+#define DRAMC_SHU_SELPH_CA1		0x0880
+#define DRAMC_SHU_SELPH_CA2		0x0884
+#define DRAMC_SHU_SELPH_CA3		0x0888
+#define DRAMC_SHU_SELPH_CA4		0x088c
+#define DRAMC_SHU_SELPH_CA5		0x0890
+#define DRAMC_SHU_SELPH_CA6		0x0894
+#define DRAMC_SHU_SELPH_CA7		0x0898
+#define DRAMC_SHU_SELPH_CA8		0x089c
+#define DRAMC_SHU_SELPH_DQS0		0x08a0
+#define DRAMC_SHU_SELPH_DQS1		0x08a4
+#define DRAMC_SHU1_DRVING1		0x08a8
+#define DRAMC_SHU1_DRVING2		0x08ac
+#define DRAMC_SHU1_WODT			0x08c0
+#define DRAMC_SHU_SCINTV		0x08c8
+#define DRAMC_SHURK0_DQSCTL		0x0a00
+#define DRAMC_SHURK0_DQSIEN		0x0a04
+#define DRAMC_SHURK0_SELPH_ODTEN0	0x0a1c
+#define DRAMC_SHURK0_SELPH_ODTEN1	0x0a20
+#define DRAMC_SHURK0_SELPH_DQSG0	0x0a24
+#define DRAMC_SHURK0_SELPH_DQSG1	0x0a28
+#define DRAMC_SHURK0_SELPH_DQ0		0x0a2c
+#define DRAMC_SHURK0_SELPH_DQ1		0x0a30
+#define DRAMC_SHURK0_SELPH_DQ2		0x0a34
+#define DRAMC_SHURK0_SELPH_DQ3		0x0a38
+#define DRAMC_SHURK1_DQSCTL		0x0b00
+#define DRAMC_SHURK1_SELPH_ODTEN0	0x0b1c
+#define DRAMC_SHURK1_SELPH_ODTEN1	0x0b20
+#define DRAMC_SHURK1_SELPH_DQSG0	0x0b24
+#define DRAMC_SHURK1_SELPH_DQSG1	0x0b28
+#define DRAMC_SHURK1_SELPH_DQ0		0x0b2c
+#define DRAMC_SHURK1_SELPH_DQ1		0x0b30
+#define DRAMC_SHURK1_SELPH_DQ2		0x0b34
+#define DRAMC_SHURK1_SELPH_DQ3		0x0b38
+#define DRAMC_SHURK2_SELPH_ODTEN0	0x0c1c
+#define DRAMC_SHURK2_SELPH_ODTEN1	0x0c20
+#define DRAMC_SHU_DQSG_RETRY		0x0c54
+
+#define EMI_COL_ADDR_MASK		GENMASK(13, 12)
+#define EMI_COL_ADDR_SHIFT		12
+#define WALKING_PATTERN			0x12345678
+#define WALKING_STEP			0x4000000
+
+struct mtk_ddr3_priv {
+	fdt_addr_t emi;
+	fdt_addr_t ddrphy;
+	fdt_addr_t dramc_ao;
+	struct clk phy;
+	struct clk phy_mux;
+	struct clk mem;
+	struct clk mem_mux;
+};
+
+#ifdef CONFIG_SPL_BUILD
+static int mtk_ddr3_rank_size_detect(struct udevice *dev)
+{
+	struct mtk_ddr3_priv *priv = dev_get_priv(dev);
+	int step;
+	u32 start, test;
+
+	/* To detect size, we have to make sure it's single rank
+	 * and it has maximum addressing region
+	 */
+
+	writel(WALKING_PATTERN, CONFIG_SYS_SDRAM_BASE);
+
+	if (readl(CONFIG_SYS_SDRAM_BASE) != WALKING_PATTERN)
+		return -EINVAL;
+
+	for (step = 0; step < 5; step++) {
+		writel(~WALKING_PATTERN, CONFIG_SYS_SDRAM_BASE +
+		       (WALKING_STEP << step));
+
+		start = readl(CONFIG_SYS_SDRAM_BASE);
+		test = readl(CONFIG_SYS_SDRAM_BASE + (WALKING_STEP << step));
+		if ((test != ~WALKING_PATTERN) || test == start)
+			break;
+	}
+
+	step = step ? step - 1 : 3;
+	clrsetbits_le32(priv->emi + EMI_CONA, EMI_COL_ADDR_MASK,
+			step << EMI_COL_ADDR_SHIFT);
+
+	return 0;
+}
+
+static int mtk_ddr3_init(struct udevice *dev)
+{
+	struct mtk_ddr3_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = clk_set_parent(&priv->phy, &priv->phy_mux);
+	if (ret)
+		return ret;
+
+	/* EMI Setting */
+	writel(0x00003010, priv->emi + EMI_CONA);
+	writel(0x00000000, priv->emi + EMI_CONF);
+	writel(0x000006b8, priv->emi + EMI_CONM);
+	/* DQS */
+	writel(0x20c00, priv->dramc_ao + DRAMC_SHU1_DRVING1);
+	/* Clock */
+	writel(0x8320c83, priv->dramc_ao + DRAMC_SHU1_DRVING2);
+
+	/* DDRPHY setting */
+	writel(0x2201, priv->dramc_ao + DRAMC_DRAMCTRL);
+	writel(0x3000000c, priv->dramc_ao + DRAMC_CLKCTRL);
+	writel(0xe08, priv->ddrphy + DDRPHY_CA_CMD5);
+	writel(0x60e, priv->ddrphy + DDRPHY_SHU1_CA_CMD5);
+	writel(0x0, priv->ddrphy + DDRPHY_MISC_SPM_CTRL1);
+	writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_SPM_CTRL0);
+	writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_SPM_CTRL2);
+	writel(0x6003bf, priv->ddrphy + DDRPHY_MISC_CG_CTRL2);
+	writel(0x13300000, priv->ddrphy + DDRPHY_MISC_CG_CTRL4);
+
+	writel(0x1, priv->ddrphy + DDRPHY_SHU1_CA_CMD7);
+	writel(0x21, priv->ddrphy + DDRPHY_SHU1_B0_DQ7);
+	writel(0x1, priv->ddrphy + DDRPHY_SHU1_B1_DQ7);
+	writel(0xfff0, priv->ddrphy + DDRPHY_CA_CMD2);
+	writel(0x0, priv->ddrphy + DDRPHY_B0_DQ2);
+	writel(0x0, priv->ddrphy + DDRPHY_B1_DQ2);
+	writel(0x7, priv->ddrphy + DDRPHY_MISC_RXDVS1);
+	writel(0x10, priv->ddrphy + DDRPHY_PLL3);
+	writel(0x8e8e0000, priv->ddrphy + DDRPHY_MISC_VREF_CTRL);
+	writel(0x2e0040, priv->ddrphy + DDRPHY_MISC_IMP_CTRL0);
+	writel(0x50060e, priv->ddrphy + DDRPHY_SHU1_B0_DQ5);
+	writel(0x50060e, priv->ddrphy + DDRPHY_SHU1_B1_DQ5);
+	udelay(1);
+
+	writel(0x10, priv->ddrphy + DDRPHY_B0_DQ3);
+	writel(0x10, priv->ddrphy + DDRPHY_B1_DQ3);
+	writel(0x3f600, priv->ddrphy + DDRPHY_MISC_CG_CTRL1);
+	writel(0x1010, priv->ddrphy + DDRPHY_B0_DQ4);
+	writel(0x1110e0e, priv->ddrphy + DDRPHY_B0_DQ5);
+	writel(0x10c10d0, priv->ddrphy + DDRPHY_B0_DQ6);
+	writel(0x3110e0e, priv->ddrphy + DDRPHY_B0_DQ5);
+	writel(0x1010, priv->ddrphy + DDRPHY_B1_DQ4);
+	writel(0x1110e0e, priv->ddrphy + DDRPHY_B1_DQ5);
+	writel(0x10c10d0, priv->ddrphy + DDRPHY_B1_DQ6);
+	writel(0x3110e0e, priv->ddrphy + DDRPHY_B1_DQ5);
+	writel(0x7fffffc, priv->ddrphy + DDRPHY_CA_CMD3);
+	writel(0xc0010, priv->ddrphy + DDRPHY_CA_CMD6);
+	writel(0x101, priv->ddrphy + DDRPHY_SHU1_CA_CMD2);
+	writel(0x41e, priv->ddrphy + DDRPHY_B0_DQ3);
+	writel(0x41e, priv->ddrphy + DDRPHY_B1_DQ3);
+	writel(0x180101, priv->ddrphy + DDRPHY_CA_CMD8);
+	writel(0x0, priv->ddrphy + DDRPHY_MISC_IMP_CTRL1);
+	writel(0x11400000, priv->ddrphy + DDRPHY_MISC_CG_CTRL4);
+	writel(0xfff0f0f0, priv->ddrphy + DDRPHY_MISC_SHU_OPT);
+	writel(0x1f, priv->ddrphy + DDRPHY_MISC_CG_CTRL0);
+
+	writel(0x0, priv->ddrphy + DDRPHY_SHU1_CA_CMD6);
+	writel(0x0, priv->ddrphy + DDRPHY_SHU1_B0_DQ6);
+	writel(0x0, priv->ddrphy + DDRPHY_SHU1_B1_DQ6);
+	writel(0x40000, priv->ddrphy + DDRPHY_PLL4);
+	writel(0x0, priv->ddrphy + DDRPHY_PLL1);
+	writel(0x0, priv->ddrphy + DDRPHY_PLL2);
+	writel(0x666008, priv->ddrphy + DDRPHY_CA_DLL_ARPI5);
+	writel(0x80666008, priv->ddrphy + DDRPHY_B0_DLL_ARPI5);
+	writel(0x80666008, priv->ddrphy + DDRPHY_B1_DLL_ARPI5);
+	writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI0);
+	writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI0);
+	writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI0);
+	writel(0x400, priv->ddrphy + DDRPHY_CA_DLL_ARPI2);
+	writel(0x20400, priv->ddrphy + DDRPHY_B0_DLL_ARPI2);
+	writel(0x20400, priv->ddrphy + DDRPHY_B1_DLL_ARPI2);
+	writel(0x0, priv->ddrphy + DDRPHY_SHU1_PLL9);
+	writel(0x0, priv->ddrphy + DDRPHY_SHU1_PLL11);
+	writel(0xf7f, priv->ddrphy + DDRPHY_SHU1_PLL0);
+	writel(0x40000, priv->ddrphy + DDRPHY_SHU1_PLL8);
+	writel(0x40000, priv->ddrphy + DDRPHY_SHU1_PLL10);
+	writel(0xe57800fe, priv->ddrphy + DDRPHY_SHU1_PLL4);
+	writel(0xe57800fe, priv->ddrphy + DDRPHY_SHU1_PLL6);
+
+	writel(0xB5000000, priv->ddrphy + DDRPHY_SHU1_PLL5);
+	writel(0xB5000000, priv->ddrphy + DDRPHY_SHU1_PLL7);
+
+	writel(0x14d0002, priv->ddrphy + DDRPHY_PLL5);
+	writel(0x14d0002, priv->ddrphy + DDRPHY_PLL7);
+	writel(0x80040000, priv->ddrphy + DDRPHY_SHU1_PLL8);
+	writel(0x80040000, priv->ddrphy + DDRPHY_SHU1_PLL10);
+	writel(0xf, priv->ddrphy + DDRPHY_SHU1_PLL1);
+	writel(0x4, priv->ddrphy + DDRPHY_CA_DLL_ARPI0);
+	writel(0x1, priv->ddrphy + DDRPHY_B0_DLL_ARPI0);
+	writel(0x1, priv->ddrphy + DDRPHY_B1_DLL_ARPI0);
+	writel(0x698600, priv->ddrphy + DDRPHY_CA_DLL_ARPI5);
+	writel(0xc0778600, priv->ddrphy + DDRPHY_B0_DLL_ARPI5);
+	writel(0xc0778600, priv->ddrphy + DDRPHY_B1_DLL_ARPI5);
+	writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI4);
+	writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI4);
+	writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI4);
+	writel(0x2ba800, priv->ddrphy + DDRPHY_CA_DLL_ARPI1);
+	writel(0x2ae806, priv->ddrphy + DDRPHY_B0_DLL_ARPI1);
+	writel(0xae806, priv->ddrphy + DDRPHY_B1_DLL_ARPI1);
+	writel(0xba000, priv->ddrphy + DDRPHY_CA_DLL_ARPI3);
+	writel(0x2e800, priv->ddrphy + DDRPHY_B0_DLL_ARPI3);
+	writel(0x2e800, priv->ddrphy + DDRPHY_B1_DLL_ARPI3);
+	writel(0x0, priv->ddrphy + DDRPHY_SHU1_CA_CMD4);
+	writel(0x0, priv->ddrphy + DDRPHY_SHU1_B0_DQ4);
+	writel(0x0, priv->ddrphy + DDRPHY_SHU1_B1_DQ4);
+	writel(0x4, priv->ddrphy + DDRPHY_CA_DLL_ARPI0);
+	writel(0x1, priv->ddrphy + DDRPHY_B0_DLL_ARPI0);
+	writel(0x1, priv->ddrphy + DDRPHY_B1_DLL_ARPI0);
+	writel(0x32cf0000, priv->ddrphy + DDRPHY_SHU1_CA_CMD6);
+	writel(0x32cd0000, priv->ddrphy + DDRPHY_SHU1_B0_DQ6);
+	writel(0x32cd0000, priv->ddrphy + DDRPHY_SHU1_B1_DQ6);
+	writel(0x80010000, priv->ddrphy + DDRPHY_PLL1);
+	writel(0x80000000, priv->ddrphy + DDRPHY_PLL2);
+	udelay(100);
+
+	writel(0xc, priv->ddrphy + DDRPHY_CA_DLL_ARPI0);
+	writel(0x9, priv->ddrphy + DDRPHY_B0_DLL_ARPI0);
+	writel(0x9, priv->ddrphy + DDRPHY_B1_DLL_ARPI0);
+	writel(0xd0000, priv->ddrphy + DDRPHY_PLL4);
+	udelay(1);
+
+	writel(0x82, priv->ddrphy + DDRPHY_MISC_CTRL1);
+	writel(0x2, priv->dramc_ao + DRAMC_DDRCONF0);
+	writel(0x3acf0000, priv->ddrphy + DDRPHY_SHU1_CA_CMD6);
+	writel(0x3acd0000, priv->ddrphy + DDRPHY_SHU1_B0_DQ6);
+	writel(0x3acd0000, priv->ddrphy + DDRPHY_SHU1_B1_DQ6);
+	udelay(1);
+
+	writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI2);
+	writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI2);
+	writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI2);
+	writel(0x80, priv->ddrphy + DDRPHY_MISC_CTRL1);
+	writel(0x0, priv->dramc_ao + DRAMC_DDRCONF0);
+	writel(0x80000000, priv->ddrphy + DDRPHY_PLL1);
+	udelay(1);
+
+	writel(0x698e00, priv->ddrphy + DDRPHY_CA_DLL_ARPI5);
+	udelay(1);
+
+	writel(0xc0778e00, priv->ddrphy + DDRPHY_B0_DLL_ARPI5);
+	udelay(1);
+
+	writel(0xc0778e00, priv->ddrphy + DDRPHY_B1_DLL_ARPI5);
+	udelay(1);
+
+	ret = clk_set_parent(&priv->mem, &priv->mem_mux);
+	if (ret)
+		return ret;
+
+	/* DDR PHY PLL setting */
+	writel(0x51e, priv->ddrphy + DDRPHY_B0_DQ3);
+	writel(0x51e, priv->ddrphy + DDRPHY_B1_DQ3);
+	writel(0x8100008c, priv->ddrphy + DDRPHY_MISC_CTRL1);
+	writel(0x80101, priv->ddrphy + DDRPHY_CA_CMD8);
+	writel(0x100, priv->ddrphy + DDRPHY_CA_CMD7);
+	writel(0x0, priv->ddrphy + DDRPHY_CA_CMD7);
+	writel(0x0, priv->ddrphy + DDRPHY_B0_DQ7);
+	writel(0x0, priv->ddrphy + DDRPHY_B1_DQ7);
+	writel(0x51e, priv->ddrphy + DDRPHY_B0_DQ3);
+	writel(0xff051e, priv->ddrphy + DDRPHY_B1_DQ3);
+	writel(0x0, priv->ddrphy + DDRPHY_B0_DQ2);
+	writel(0x1ff, priv->ddrphy + DDRPHY_B1_DQ2);
+
+	/* Update initial setting */
+	writel(0x5fc, priv->ddrphy + DDRPHY_B0_DQ3);
+	writel(0xff05fc, priv->ddrphy + DDRPHY_B1_DQ3);
+	writel(0x10c12d9, priv->ddrphy + DDRPHY_B0_DQ6);
+	writel(0x10c12d9, priv->ddrphy + DDRPHY_B1_DQ6);
+	writel(0xc0259, priv->ddrphy + DDRPHY_CA_CMD6);
+	writel(0x4000, priv->ddrphy + DDRPHY_B0_DQ2);
+	writel(0x41ff, priv->ddrphy + DDRPHY_B1_DQ2);
+	writel(0x0, priv->ddrphy + DDRPHY_B0_DQ8);
+	writel(0x100, priv->ddrphy + DDRPHY_B1_DQ8);
+	writel(0x3110e0e, priv->ddrphy + DDRPHY_B0_DQ5);
+	writel(0x3110e0e, priv->ddrphy + DDRPHY_B1_DQ5);
+	writel(0x51060e, priv->ddrphy + DDRPHY_SHU1_B0_DQ5);
+	writel(0x51060e, priv->ddrphy + DDRPHY_SHU1_B1_DQ5);
+	writel(0x39eff6, priv->dramc_ao + DRAMC_SHU_SCINTV);
+	writel(0x204ffff, priv->dramc_ao + DRAMC_CLKAR);
+	writel(0x31b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
+	writel(0x0, priv->dramc_ao + DRAMC_PERFCTL0);
+	writel(0x80000, priv->dramc_ao + DRAMC_PERFCTL0);
+
+	/* Dramc setting PC3 */
+	writel(0x65714001, priv->dramc_ao + DRAMC_REFCTRL0);
+
+	writel(0x11351131, priv->ddrphy + DDRPHY_MISC_CTRL3);
+	writel(0x200600, priv->dramc_ao + DRAMC_SHU_DQSG_RETRY);
+	writel(0x101d007, priv->dramc_ao + DRAMC_SHUCTRL2);
+	writel(0xe090601, priv->dramc_ao + DRAMC_DVFSDLL);
+	writel(0x20003000, priv->dramc_ao + DRAMC_DDRCONF0);
+	writel(0x3900020f, priv->ddrphy + DDRPHY_MISC_CTRL0);
+	writel(0xa20810bf, priv->dramc_ao + DRAMC_SHU_CONF0);
+	writel(0x30050, priv->dramc_ao + DRAMC_SHU_ODTCTRL);
+	writel(0x25712000, priv->dramc_ao + DRAMC_REFCTRL0);
+	writel(0xb0100000, priv->dramc_ao + DRAMC_STBCAL);
+	writel(0x8000000, priv->dramc_ao + DRAMC_SREFCTRL);
+	writel(0xc0000000, priv->dramc_ao + DRAMC_SHU_PIPE);
+	writel(0x731004, priv->dramc_ao + DRAMC_RKCFG);
+	writel(0x8007320f, priv->dramc_ao + DRAMC_SHU_CONF2);
+	writel(0x2a7c0, priv->dramc_ao + DRAMC_SHU_SCINTV);
+	writel(0xc110, priv->dramc_ao + DRAMC_SHUCTRL);
+	writel(0x30000700, priv->dramc_ao + DRAMC_REFCTRL1);
+	writel(0x6543b321, priv->dramc_ao + DRAMC_REFRATRE_FILTER);
+
+	/* Update PCDDR3 default setting */
+	writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA1);
+	writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA2);
+	writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA3);
+	writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA4);
+	writel(0x10000111, priv->dramc_ao + DRAMC_SHU_SELPH_CA5);
+	writel(0x1000000, priv->dramc_ao + DRAMC_SHU_SELPH_CA6);
+	writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA7);
+	writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA8);
+	writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_CA_CMD9);
+	writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_CA_CMD9);
+	writel(0x11112222, priv->dramc_ao + DRAMC_SHU_SELPH_DQS0);
+	writel(0x33331111, priv->dramc_ao + DRAMC_SHU_SELPH_DQS1);
+	writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ0);
+	writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ1);
+	writel(0x33331111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ2);
+	writel(0x33331111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ3);
+	writel(0x11112222, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ0);
+	writel(0x11112222, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ1);
+	writel(0x33331111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ2);
+	writel(0x33331111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ3);
+	writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7);
+	writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ7);
+	writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7);
+	writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ7);
+	writel(0x0, priv->dramc_ao + DRAMC_SHURK0_SELPH_ODTEN0);
+	writel(0x0, priv->dramc_ao + DRAMC_SHURK0_SELPH_ODTEN1);
+	writel(0x0, priv->dramc_ao + DRAMC_SHURK1_SELPH_ODTEN0);
+	writel(0x0, priv->dramc_ao + DRAMC_SHURK1_SELPH_ODTEN1);
+	writel(0x0, priv->dramc_ao + DRAMC_SHURK2_SELPH_ODTEN0);
+	writel(0x66666666, priv->dramc_ao + DRAMC_SHURK2_SELPH_ODTEN1);
+	writel(0x2c000b0f, priv->dramc_ao + DRAMC_SHU_CONF1);
+	writel(0x11111111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG0);
+	writel(0x64646464, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG1);
+	writel(0x11111111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQSG0);
+	writel(0x64646464, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQSG1);
+	writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ2);
+	writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ3);
+	writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ4);
+	writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ5);
+	writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ6);
+	writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ2);
+	writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ3);
+	writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ4);
+	writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ5);
+	writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ6);
+	writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ2);
+	writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ3);
+	writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ4);
+	writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ5);
+	writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ6);
+	writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ2);
+	writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ3);
+	writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ4);
+	writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ5);
+	writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ6);
+	writel(0x20000001, priv->dramc_ao + DRAMC_SHU_RANKCTL);
+	writel(0x2, priv->dramc_ao + DRAMC_SHURK0_DQSCTL);
+	writel(0x2, priv->dramc_ao + DRAMC_SHURK1_DQSCTL);
+	writel(0x4020b07, priv->dramc_ao + DRAMC_SHU_ACTIM0);
+	writel(0xb060400, priv->dramc_ao + DRAMC_SHU_ACTIM1);
+	writel(0x8090200, priv->dramc_ao + DRAMC_SHU_ACTIM2);
+	writel(0x810018, priv->dramc_ao + DRAMC_SHU_ACTIM3);
+	writel(0x1e9700ff, priv->dramc_ao + DRAMC_SHU_ACTIM4);
+	writel(0x1000908, priv->dramc_ao + DRAMC_SHU_ACTIM5);
+	writel(0x801040b, priv->dramc_ao + DRAMC_SHU_ACTIM_XRT);
+	writel(0x20000D1, priv->dramc_ao + DRAMC_SHU_AC_TIME_05T);
+	writel(0x80010000, priv->ddrphy + DDRPHY_PLL2);
+	udelay(500);
+
+	writel(0x81080000, priv->dramc_ao + DRAMC_MISCTL0);
+	writel(0xacf13, priv->dramc_ao + DRAMC_PERFCTL0);
+	writel(0xacf12, priv->dramc_ao + DRAMC_PERFCTL0);
+	writel(0x80, priv->dramc_ao + DRAMC_ARBCTL);
+	writel(0x9, priv->dramc_ao + DRAMC_PADCTRL);
+	writel(0x80000107, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL);
+	writel(0x3000000c, priv->dramc_ao + DRAMC_CLKCTRL);
+	writel(0x25714001, priv->dramc_ao + DRAMC_REFCTRL0);
+	writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
+	writel(0x4300000, priv->dramc_ao + DRAMC_CATRAINING1);
+	writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
+	writel(0x731414, priv->dramc_ao + DRAMC_RKCFG);
+	writel(0x733414, priv->dramc_ao + DRAMC_RKCFG);
+	udelay(20);
+
+	writel(0x80002050, priv->dramc_ao + DRAMC_CKECTRL);
+	udelay(100);
+
+	writel(0x400000, priv->dramc_ao + DRAMC_MRS);
+	writel(0x401800, priv->dramc_ao + DRAMC_MRS);
+	writel(0x1, priv->dramc_ao + DRAMC_SPCMD);
+	writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
+	udelay(100);
+
+	writel(0x601800, priv->dramc_ao + DRAMC_MRS);
+	writel(0x600000, priv->dramc_ao + DRAMC_MRS);
+	writel(0x1, priv->dramc_ao + DRAMC_SPCMD);
+	writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
+	udelay(100);
+
+	writel(0x200000, priv->dramc_ao + DRAMC_MRS);
+	writel(0x200400, priv->dramc_ao + DRAMC_MRS);
+	writel(0x1, priv->dramc_ao + DRAMC_SPCMD);
+	writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
+	udelay(100);
+
+	writel(0x400, priv->dramc_ao + DRAMC_MRS);
+	writel(0x1d7000, priv->dramc_ao + DRAMC_MRS);
+	writel(0x1, priv->dramc_ao + DRAMC_SPCMD);
+	writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
+	udelay(100);
+
+	writel(0x702201, priv->dramc_ao + DRAMC_DRAMCTRL);
+	writel(0x10, priv->dramc_ao + DRAMC_SPCMD);
+	writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
+	writel(0x20, priv->dramc_ao + DRAMC_SPCMD);
+	writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
+	writel(0x1, priv->dramc_ao + DRAMC_HW_MRR_FUN);
+	writel(0x702301, priv->dramc_ao + DRAMC_DRAMCTRL);
+	writel(0x702301, priv->dramc_ao + DRAMC_DRAMCTRL);
+	writel(0xa56, priv->dramc_ao + DRAMC_ZQCS);
+	writel(0xff0000, priv->dramc_ao + DRAMC_SHU_CONF3);
+	writel(0x15b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
+	writel(0x2cb00b0f, priv->dramc_ao + DRAMC_SHU_CONF1);
+	writel(0x65714001, priv->dramc_ao + DRAMC_REFCTRL0);
+	writel(0x48000000, priv->dramc_ao + DRAMC_SREFCTRL);
+	writel(0xc0000107, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL);
+	writel(0x10002, priv->dramc_ao + DRAMC_EYESCAN);
+	writel(0x15e00, priv->dramc_ao + DRAMC_STBCAL1);
+	writel(0x100000, priv->dramc_ao + DRAMC_TEST2_1);
+	writel(0x4000, priv->dramc_ao + DRAMC_TEST2_2);
+	writel(0x12000480, priv->dramc_ao + DRAMC_TEST2_3);
+	writel(0x301d007, priv->dramc_ao + DRAMC_SHUCTRL2);
+	writel(0x4782321, priv->dramc_ao + DRAMC_DRAMCTRL);
+	writel(0x30210000, priv->dramc_ao + DRAMC_SHU_CKECTRL);
+	writel(0x20000, priv->dramc_ao + DRAMC_DUMMY_RD);
+	writel(0x4080110d, priv->dramc_ao + DRAMC_TEST2_4);
+	writel(0x30000721, priv->dramc_ao + DRAMC_REFCTRL1);
+	writel(0x0, priv->dramc_ao + DRAMC_RSTMASK);
+	writel(0x4782320, priv->dramc_ao + DRAMC_DRAMCTRL);
+	writel(0x80002000, priv->dramc_ao + DRAMC_CKECTRL);
+	writel(0x45714001, priv->dramc_ao + DRAMC_REFCTRL0);
+
+	/* Apply config before calibration */
+	writel(0x120, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL);
+	writel(0x11351131, priv->ddrphy + DDRPHY_MISC_CTRL3);
+	writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_CG_CTRL0);
+	writel(0x2a7fe, priv->dramc_ao + DRAMC_SHU_SCINTV);
+	writel(0xff01ff, priv->dramc_ao + DRAMC_SHU_CONF3);
+	writel(0x4782320, priv->dramc_ao + DRAMC_DRAMCTRL);
+	writel(0xa56, priv->dramc_ao + DRAMC_ZQCS);
+	writel(0x80000000, priv->dramc_ao + DRAMC_SHU1_WODT);
+	writel(0x21, priv->ddrphy + DDRPHY_SHU1_B0_DQ7);
+	writel(0x1, priv->ddrphy + DDRPHY_SHU1_B1_DQ7);
+	writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
+	writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
+	writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
+	writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
+	writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
+	writel(0x10002, priv->dramc_ao + DRAMC_EYESCAN);
+	writel(0x8100008c, priv->ddrphy + DDRPHY_MISC_CTRL1);
+	writel(0x45714001, priv->dramc_ao + DRAMC_REFCTRL0);
+	writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
+	writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
+
+	/* Write leveling */
+	writel(0x1f2e2e00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7);
+	writel(0x202f2f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7);
+	writel(0x33221100, priv->dramc_ao + DRAMC_SHU_SELPH_DQS1);
+	writel(0x11112222, priv->dramc_ao + DRAMC_SHU_SELPH_DQS0);
+
+	/* RX dqs gating cal */
+	writel(0x11111010, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG0);
+	writel(0x20201717, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG1);
+	writel(0x1d1f, priv->dramc_ao + DRAMC_SHURK0_DQSIEN);
+
+	/* RX window per-bit cal */
+	writel(0x03030404, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ2);
+	writel(0x01010303, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ3);
+	writel(0x01010303, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ4);
+	writel(0x01010000, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ5);
+	writel(0x03030606, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ2);
+	writel(0x02020202, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ3);
+	writel(0x04040303, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ4);
+	writel(0x06060101, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ5);
+
+	/* RX datlat cal */
+	writel(0x28b00a0e, priv->dramc_ao + DRAMC_SHU_CONF1);
+
+	/* TX window per-byte with 2UI cal */
+	writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ0);
+	writel(0x22220000, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ2);
+	writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ1);
+	writel(0x22220000, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ3);
+	writel(0x1f2e2e00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7);
+	writel(0x202f2f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7);
+
+	return mtk_ddr3_rank_size_detect(dev);
+}
+#endif
+
+static int mtk_ddr3_probe(struct udevice *dev)
+{
+	struct mtk_ddr3_priv *priv = dev_get_priv(dev);
+
+	priv->emi = dev_read_addr_index(dev, 0);
+	if (priv->emi == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->ddrphy = dev_read_addr_index(dev, 1);
+	if (priv->ddrphy == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->dramc_ao = dev_read_addr_index(dev, 2);
+	if (priv->dramc_ao == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+#ifdef CONFIG_SPL_BUILD
+	int ret;
+
+	ret = clk_get_by_index(dev, 0, &priv->phy);
+	if (ret)
+		return ret;
+
+	ret = clk_get_by_index(dev, 1, &priv->phy_mux);
+	if (ret)
+		return ret;
+
+	ret = clk_get_by_index(dev, 2, &priv->mem);
+	if (ret)
+		return ret;
+
+	ret = clk_get_by_index(dev, 3, &priv->mem_mux);
+	if (ret)
+		return ret;
+
+	ret = mtk_ddr3_init(dev);
+	if (ret)
+		return ret;
+#endif
+	return 0;
+}
+
+static int mtk_ddr3_get_info(struct udevice *dev, struct ram_info *info)
+{
+	struct mtk_ddr3_priv *priv = dev_get_priv(dev);
+	u32 val = readl(priv->emi + EMI_CONA);
+
+	info->base = CONFIG_SYS_SDRAM_BASE;
+
+	switch ((val & EMI_COL_ADDR_MASK) >> EMI_COL_ADDR_SHIFT) {
+	case 0:
+		info->size = SZ_128M;
+		break;
+	case 1:
+		info->size = SZ_256M;
+		break;
+	case 2:
+		info->size = SZ_512M;
+		break;
+	case 3:
+		info->size = SZ_1G;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct ram_ops mtk_ddr3_ops = {
+	.get_info = mtk_ddr3_get_info,
+};
+
+static const struct udevice_id mtk_ddr3_ids[] = {
+	{ .compatible = "mediatek,mt7629-dramc" },
+	{ }
+};
+
+U_BOOT_DRIVER(mediatek_ddr3) = {
+	.name     = "mediatek_ddr3",
+	.id       = UCLASS_RAM,
+	.of_match = mtk_ddr3_ids,
+	.ops      = &mtk_ddr3_ops,
+	.probe    = mtk_ddr3_probe,
+	.priv_auto_alloc_size = sizeof(struct mtk_ddr3_priv),
+};
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index bcc01b1..fd0009b 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -60,6 +60,16 @@
 	  This driver supports reading and writing the RTC/calendar and detects
 	  total power failures.
 
+config RTC_RV3029
+	bool "Enable RV3029 driver"
+	depends on DM_RTC
+	help
+	  The MicroCrystal RV3029 is a I2C Real Time Clock (RTC) with 8-byte
+	  battery-backed SRAM.
+
+	  This driver supports reading and writing the RTC/calendar and the
+	  battery-baced SRAM section.
+
 config RTC_RX8010SJ
 	bool "Enable RX8010SJ driver"
 	depends on DM_RTC
@@ -94,4 +104,10 @@
 	  clock with a wide array of features and 50 bytes of general-purpose,
 	  battery-backed RAM. The driver supports access to the clock and RAM.
 
+config RTC_M41T62
+	bool "Enable M41T62 driver"
+	help
+	  Enable driver for ST's M41T62 compatible RTC devices (like RV-4162).
+	  It is a serial (I2C) real-time clock (RTC) with alarm.
+
 endmenu
diff --git a/drivers/rtc/m41t62.c b/drivers/rtc/m41t62.c
index 1374383..2ee7e00 100644
--- a/drivers/rtc/m41t62.c
+++ b/drivers/rtc/m41t62.c
@@ -1,5 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
+ * (C) Copyright 2018
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de.
+ *
  * (C) Copyright 2008
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  *
@@ -15,6 +18,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <dm.h>
 #include <rtc.h>
 #include <i2c.h>
 
@@ -49,12 +53,8 @@
 
 #define M41T80_ALHOUR_HT	(1 << 6)	/* HT: Halt Update Bit */
 
-int rtc_get(struct rtc_time *tm)
+static void m41t62_update_rtc_time(struct rtc_time *tm, u8 *buf)
 {
-	u8 buf[M41T62_DATETIME_REG_SIZE];
-
-	i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE);
-
 	debug("%s: raw read data - sec=%02x, min=%02x, hr=%02x, "
 	      "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n",
 	      __FUNCTION__,
@@ -77,20 +77,14 @@
 	      __FUNCTION__,
 	      tm->tm_sec, tm->tm_min, tm->tm_hour,
 	      tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
-
-	return 0;
 }
 
-int rtc_set(struct rtc_time *tm)
+static void m41t62_set_rtc_buf(const struct rtc_time *tm, u8 *buf)
 {
-	u8 buf[M41T62_DATETIME_REG_SIZE];
-
 	debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 	      tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
 	      tm->tm_hour, tm->tm_min, tm->tm_sec);
 
-	i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE);
-
 	/* Merge time-data and register flags into buf[0..7] */
 	buf[M41T62_REG_SSEC] = 0;
 	buf[M41T62_REG_SEC] =
@@ -107,8 +101,99 @@
 		bin2bcd(tm->tm_mon) | (buf[M41T62_REG_MON] & ~0x1f);
 	/* assume 20YY not 19YY */
 	buf[M41T62_REG_YEAR] = bin2bcd(tm->tm_year % 100);
+}
+
+#ifdef CONFIG_DM_RTC
+static int m41t62_rtc_get(struct udevice *dev, struct rtc_time *tm)
+{
+	u8 buf[M41T62_DATETIME_REG_SIZE];
+	int ret;
+
+	ret = dm_i2c_read(dev, 0, buf, sizeof(buf));
+	if (ret)
+		return ret;
+
+	m41t62_update_rtc_time(tm, buf);
+
+	return 0;
+}
+
+static int m41t62_rtc_set(struct udevice *dev, const struct rtc_time *tm)
+{
+	u8 buf[M41T62_DATETIME_REG_SIZE];
+	int ret;
+
+	ret = dm_i2c_read(dev, 0, buf, sizeof(buf));
+	if (ret)
+		return ret;
+
+	m41t62_set_rtc_buf(tm, buf);
+
+	ret = dm_i2c_write(dev, 0, buf, sizeof(buf));
+	if (ret) {
+		printf("I2C write failed in %s()\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int m41t62_rtc_reset(struct udevice *dev)
+{
+	u8 val;
+
+	/*
+	 * M41T82: Make sure HT (Halt Update) bit is cleared.
+	 * This bit is 0 in M41T62 so its save to clear it always.
+	 */
+
+	int ret = dm_i2c_read(dev, M41T62_REG_ALARM_HOUR, &val, sizeof(val));
+
+	val &= ~M41T80_ALHOUR_HT;
+	ret |= dm_i2c_write(dev, M41T62_REG_ALARM_HOUR, &val, sizeof(val));
+
+	return ret;
+}
+
+static const struct rtc_ops m41t62_rtc_ops = {
+	.get = m41t62_rtc_get,
+	.set = m41t62_rtc_set,
+	.reset = m41t62_rtc_reset,
+};
+
+static const struct udevice_id m41t62_rtc_ids[] = {
+	{ .compatible = "st,m41t62" },
+	{ .compatible = "microcrystal,rv4162" },
+	{ }
+};
+
+U_BOOT_DRIVER(rtc_m41t62) = {
+	.name	= "rtc-m41t62",
+	.id	= UCLASS_RTC,
+	.of_match = m41t62_rtc_ids,
+	.ops	= &m41t62_rtc_ops,
+};
+
+#else /* NON DM RTC code - will be removed */
+int rtc_get(struct rtc_time *tm)
+{
+	u8 buf[M41T62_DATETIME_REG_SIZE];
+
+	i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE);
+	m41t62_update_rtc_time(tm, buf);
+
+	return 0;
+}
+
+int rtc_set(struct rtc_time *tm)
+{
+	u8 buf[M41T62_DATETIME_REG_SIZE];
+
+	i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE);
+	m41t62_set_rtc_buf(tm, buf);
 
-	if (i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE)) {
+	if (i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, buf,
+		      M41T62_DATETIME_REG_SIZE)) {
 		printf("I2C write failed in %s()\n", __func__);
 		return -1;
 	}
@@ -128,3 +213,4 @@
 	val &= ~M41T80_ALHOUR_HT;
 	i2c_write(CONFIG_SYS_I2C_RTC_ADDR, M41T62_REG_ALARM_HOUR, 1, &val, 1);
 }
+#endif /* CONFIG_DM_RTC */
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
index b8a7a8b..6528ddf 100644
--- a/drivers/rtc/rtc-lib.c
+++ b/drivers/rtc/rtc-lib.c
@@ -31,10 +31,14 @@
 /*
  * rtc_to_tm - Converts u64 to rtc_time.
  * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
+ *
+ * This function is copied from rtc_time64_to_tm() in the Linux kernel.
+ * But in U-Boot January is month 1 and we do not subtract 1900 from the year.
  */
 void rtc_to_tm(u64 time, struct rtc_time *tm)
 {
-	unsigned int month, year, secs, days;
+	unsigned int month, year, secs;
+	int days;
 
 	days = div_u64_rem(time, 86400, &secs);
 
diff --git a/drivers/rtc/rtc-uclass.c b/drivers/rtc/rtc-uclass.c
index c676f0f..a0a238a 100644
--- a/drivers/rtc/rtc-uclass.c
+++ b/drivers/rtc/rtc-uclass.c
@@ -122,4 +122,5 @@
 UCLASS_DRIVER(rtc) = {
 	.name		= "rtc",
 	.id		= UCLASS_RTC,
+	.post_bind	= dm_scan_fdt_dev,
 };
diff --git a/drivers/rtc/rv3029.c b/drivers/rtc/rv3029.c
index dd4d060..38acb9c 100644
--- a/drivers/rtc/rv3029.c
+++ b/drivers/rtc/rv3029.c
@@ -1,189 +1,495 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2010
- * Heiko Schocher, DENX Software Engineering, hs@denx.de
+ * (C) Copyright 2018 Theobroma Systems Design und Consulting GmbH
+ *
+ * Based on a the Linux rtc-rv3029c2.c driver written by:
+ *   Gregory Hermant <gregory.hermant@calao-systems.com>
+ *   Michael Buesch <m@bues.ch>
  */
+
 #include <common.h>
 #include <command.h>
+#include <dm.h>
 #include <i2c.h>
 #include <rtc.h>
 
-#define RTC_RV3029_CTRL1	0x00
-#define RTC_RV3029_CTRL1_EERE	(1 << 3)
-
-#define RTC_RV3029_CTRL_STATUS	0x03
-#define RTC_RV3029_CTRLS_EEBUSY	(1 << 7)
+#define RTC_RV3029_PAGE_LEN             7
 
-#define RTC_RV3029_CTRL_RESET	0x04
-#define RTC_RV3029_CTRL_SYS_R	(1 << 4)
+/* control section */
+#define RV3029_ONOFF_CTRL		0x00
+#define RV3029_ONOFF_CTRL_WE		BIT(0)
+#define RV3029_ONOFF_CTRL_TE		BIT(1)
+#define RV3029_ONOFF_CTRL_TAR		BIT(2)
+#define RV3029_ONOFF_CTRL_EERE		BIT(3)
+#define RV3029_ONOFF_CTRL_SRON		BIT(4)
+#define RV3029_ONOFF_CTRL_TD0		BIT(5)
+#define RV3029_ONOFF_CTRL_TD1		BIT(6)
+#define RV3029_ONOFF_CTRL_CLKINT	BIT(7)
+#define RV3029_IRQ_CTRL			0x01
+#define RV3029_IRQ_CTRL_AIE		BIT(0)
+#define RV3029_IRQ_CTRL_TIE		BIT(1)
+#define RV3029_IRQ_CTRL_V1IE		BIT(2)
+#define RV3029_IRQ_CTRL_V2IE		BIT(3)
+#define RV3029_IRQ_CTRL_SRIE		BIT(4)
+#define RV3029_IRQ_FLAGS		0x02
+#define RV3029_IRQ_FLAGS_AF		BIT(0)
+#define RV3029_IRQ_FLAGS_TF		BIT(1)
+#define RV3029_IRQ_FLAGS_V1IF		BIT(2)
+#define RV3029_IRQ_FLAGS_V2IF		BIT(3)
+#define RV3029_IRQ_FLAGS_SRF		BIT(4)
+#define RV3029_STATUS			0x03
+#define RV3029_STATUS_VLOW1		BIT(2)
+#define RV3029_STATUS_VLOW2		BIT(3)
+#define RV3029_STATUS_SR		BIT(4)
+#define RV3029_STATUS_PON		BIT(5)
+#define RV3029_STATUS_EEBUSY		BIT(7)
+#define RV3029_RST_CTRL			0x04
+#define RV3029_RST_CTRL_SYSR		BIT(4)
+#define RV3029_CONTROL_SECTION_LEN	0x05
 
-#define RTC_RV3029_CLOCK_PAGE	0x08
-#define RTC_RV3029_PAGE_LEN	7
+/* watch section */
+#define RV3029_W_SEC			0x08
+#define RV3029_W_MINUTES		0x09
+#define RV3029_W_HOURS			0x0A
+#define RV3029_REG_HR_12_24		BIT(6) /* 24h/12h mode */
+#define RV3029_REG_HR_PM		BIT(5) /* PM/AM bit in 12h mode */
+#define RV3029_W_DATE			0x0B
+#define RV3029_W_DAYS			0x0C
+#define RV3029_W_MONTHS			0x0D
+#define RV3029_W_YEARS			0x0E
 
-#define RV3029C2_W_SECONDS	0x00
-#define RV3029C2_W_MINUTES	0x01
-#define RV3029C2_W_HOURS	0x02
-#define RV3029C2_W_DATE		0x03
-#define RV3029C2_W_DAYS		0x04
-#define RV3029C2_W_MONTHS	0x05
-#define RV3029C2_W_YEARS	0x06
+/* eeprom control section */
+#define RV3029_CONTROL_E2P_EECTRL	0x30
+#define RV3029_TRICKLE_1K		BIT(4) /* 1.5K resistance */
+#define RV3029_TRICKLE_5K		BIT(5) /* 5K   resistance */
+#define RV3029_TRICKLE_20K		BIT(6) /* 20K  resistance */
+#define RV3029_TRICKLE_80K		BIT(7) /* 80K  resistance */
+#define RV3029_TRICKLE_MASK		(RV3029_TRICKLE_1K |\
+					 RV3029_TRICKLE_5K |\
+					 RV3029_TRICKLE_20K |\
+					 RV3029_TRICKLE_80K)
+#define RV3029_TRICKLE_SHIFT		4
 
-#define RV3029C2_REG_HR_12_24          (1 << 6)  /* 24h/12h mode */
-#define RV3029C2_REG_HR_PM             (1 << 5)  /* PM/AM bit in 12h mode */
 
-#define RTC_RV3029_EEPROM_CTRL	0x30
-#define RTC_RV3029_TRICKLE_1K	(1 << 4)
-#define RTC_RV3029_TRICKLE_5K	(1 << 5)
-#define RTC_RV3029_TRICKLE_20K	(1 << 6)
-#define RTC_RV3029_TRICKLE_80K	(1 << 7)
-
-int rtc_get( struct rtc_time *tmp )
+static int rv3029_rtc_get(struct udevice *dev, struct rtc_time *tm)
 {
-	int	ret;
-	unsigned char buf[RTC_RV3029_PAGE_LEN];
+	u8 regs[RTC_RV3029_PAGE_LEN];
+	int ret;
 
-	ret = i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CLOCK_PAGE, 1, buf, \
-			RTC_RV3029_PAGE_LEN);
-	if (ret) {
+	ret = dm_i2c_read(dev, RV3029_W_SEC, regs, sizeof(regs));
+	if (ret < 0) {
 		printf("%s: error reading RTC: %x\n", __func__, ret);
-		return -1;
+		return -EIO;
+	}
+
+	tm->tm_sec = bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]);
+	tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]);
+
+	/* HR field has a more complex interpretation */
+	{
+		const u8 _hr = regs[RV3029_W_HOURS - RV3029_W_SEC];
+
+		if (_hr & RV3029_REG_HR_12_24) {
+			/* 12h format */
+			tm->tm_hour = bcd2bin(_hr & 0x1f);
+			if (_hr & RV3029_REG_HR_PM)	/* PM flag set */
+				tm->tm_hour += 12;
+		} else {
+			/* 24h format */
+			tm->tm_hour = bcd2bin(_hr & 0x3f);
+		}
 	}
-	tmp->tm_sec  = bcd2bin( buf[RV3029C2_W_SECONDS] & 0x7f);
-	tmp->tm_min  = bcd2bin( buf[RV3029C2_W_MINUTES] & 0x7f);
-	if (buf[RV3029C2_W_HOURS] & RV3029C2_REG_HR_12_24) {
-		/* 12h format */
-		tmp->tm_hour = bcd2bin(buf[RV3029C2_W_HOURS] & 0x1f);
-		if (buf[RV3029C2_W_HOURS] & RV3029C2_REG_HR_PM)
-			/* PM flag set */
-			tmp->tm_hour += 12;
-	} else
-		tmp->tm_hour = bcd2bin(buf[RV3029C2_W_HOURS] & 0x3f);
 
-	tmp->tm_mday = bcd2bin( buf[RV3029C2_W_DATE] & 0x3F );
-	tmp->tm_mon  = bcd2bin( buf[RV3029C2_W_MONTHS] & 0x1F );
-	tmp->tm_wday = bcd2bin( buf[RV3029C2_W_DAYS] & 0x07 );
+	tm->tm_mday = bcd2bin(regs[RV3029_W_DATE - RV3029_W_SEC]);
+	tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS - RV3029_W_SEC]) - 1;
 	/* RTC supports only years > 1999 */
-	tmp->tm_year = bcd2bin( buf[RV3029C2_W_YEARS]) + 2000;
-	tmp->tm_yday = 0;
-	tmp->tm_isdst = 0;
+	tm->tm_year = bcd2bin(regs[RV3029_W_YEARS - RV3029_W_SEC]) + 2000;
+	tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS - RV3029_W_SEC]) - 1;
 
-	debug( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-		tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
+	tm->tm_yday = 0;
+	tm->tm_isdst = 0;
+
+	debug("%s: %4d-%02d-%02d (wday=%d) %2d:%02d:%02d\n",
+	      __func__, tm->tm_year, tm->tm_mon, tm->tm_mday,
+	      tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
 
 	return 0;
 }
 
-int rtc_set( struct rtc_time *tmp )
+static int rv3029_rtc_set(struct udevice *dev, const struct rtc_time *tm)
 {
-	int	ret;
-	unsigned char buf[RTC_RV3029_PAGE_LEN];
+	u8 regs[RTC_RV3029_PAGE_LEN];
 
-	debug( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+	debug("%s: %4d-%02d-%02d (wday=%d( %2d:%02d:%02d\n",
+	      __func__, tm->tm_year, tm->tm_mon, tm->tm_mday,
+	      tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
 
-	if (tmp->tm_year < 2000) {
-		printf("RTC: year %d < 2000 not possible\n", tmp->tm_year);
-		return -1;
+
+	if (tm->tm_year < 2000) {
+		printf("%s: year %d (before 2000) not supported\n",
+		       __func__, tm->tm_year);
+		return -EINVAL;
 	}
-	buf[RV3029C2_W_SECONDS] = bin2bcd(tmp->tm_sec);
-	buf[RV3029C2_W_MINUTES] = bin2bcd(tmp->tm_min);
-	buf[RV3029C2_W_HOURS] = bin2bcd(tmp->tm_hour);
-	/* set 24h format */
-	buf[RV3029C2_W_HOURS] &= ~RV3029C2_REG_HR_12_24;
-	buf[RV3029C2_W_DATE] = bin2bcd(tmp->tm_mday);
-	buf[RV3029C2_W_DAYS] = bin2bcd(tmp->tm_wday);
-	buf[RV3029C2_W_MONTHS] = bin2bcd(tmp->tm_mon);
-	tmp->tm_year -= 2000;
-	buf[RV3029C2_W_YEARS] = bin2bcd(tmp->tm_year);
-	ret = i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CLOCK_PAGE, 1,
-			buf, RTC_RV3029_PAGE_LEN);
 
-	/* give the RTC some time to update */
-	udelay(1000);
-	return ret;
+	regs[RV3029_W_SEC - RV3029_W_SEC] = bin2bcd(tm->tm_sec);
+	regs[RV3029_W_MINUTES - RV3029_W_SEC] = bin2bcd(tm->tm_min);
+	regs[RV3029_W_HOURS - RV3029_W_SEC] = bin2bcd(tm->tm_hour);
+	regs[RV3029_W_DATE - RV3029_W_SEC] = bin2bcd(tm->tm_mday);
+	regs[RV3029_W_MONTHS - RV3029_W_SEC] = bin2bcd(tm->tm_mon + 1);
+	regs[RV3029_W_DAYS - RV3029_W_SEC] = bin2bcd(tm->tm_wday + 1) & 0x7;
+	regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 2000);
+
+	return dm_i2c_write(dev, RV3029_W_SEC, regs, sizeof(regs));
 }
 
-/* sets EERE-Bit  (automatic EEPROM refresh) */
-static void set_eere_bit(int state)
+static int rv3029_rtc_reset(struct udevice *dev)
 {
-	unsigned char reg_ctrl1;
+	u8 ctrl = RV3029_RST_CTRL_SYSR;
+	unsigned long start;
+	const unsigned long timeout_ms = 10000;
+	int ret;
+
+	/* trigger the system-reset */
+	ret = dm_i2c_write(dev, RV3029_RST_CTRL, &ctrl, 1);
+	if (ret < 0)
+		return -EIO;
+
+	/* wait for the system-reset to complete */
+	start = get_timer(0);
+	do {
+		if (get_timer(start) > timeout_ms)
+			return -ETIMEDOUT;
+
+		ret = dm_i2c_read(dev, RV3029_RST_CTRL, &ctrl, 1);
+		if (ret < 0)
+			return -EIO;
+	} while (ctrl & RV3029_RST_CTRL_SYSR);
+
+	return 0;
+}
+
+static int rv3029_rtc_read8(struct udevice *dev, unsigned int reg)
+{
+	u8 data;
+	int ret;
+
+	ret = dm_i2c_read(dev, reg, &data, sizeof(data));
+	return ret < 0 ? ret : data;
+}
+
+static int rv3029_rtc_write8(struct udevice *dev, unsigned int reg, int val)
+{
+	u8 data = val;
+
+	return dm_i2c_write(dev, reg, &data, 1);
+}
 
-	(void)i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL1, 1,
-			&reg_ctrl1, 1);
+#if defined(OF_CONTROL)
+static int rv3029_get_sr(struct udevice *dev, u8 *buf)
+{
+	int ret = dm_i2c_read(dev, RV3029_STATUS, buf, 1);
 
-	if (state)
-		reg_ctrl1 |= RTC_RV3029_CTRL1_EERE;
-	else
-		reg_ctrl1 &= (~RTC_RV3029_CTRL1_EERE);
+	if (ret < 0)
+		return -EIO;
 
-	(void)i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL1, 1,
-		&reg_ctrl1, 1);
+	dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
+	return 0;
 }
 
-/* waits until EEPROM page is no longer busy (times out after 10ms*loops) */
-static int wait_eebusy(int loops)
+static int rv3029_set_sr(struct udevice *dev, u8 val)
 {
-	int i;
-	unsigned char ctrl_status;
+	int ret;
 
-	for (i = 0; i < loops; i++) {
-		(void)i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL_STATUS,
-			1, &ctrl_status, 1);
+	ret = dm_i2c_read(dev, RV3029_STATUS, &val, 1);
+	if (ret < 0)
+		return -EIO;
+
+	dev_dbg(dev, "status = 0x%.2x (%d)\n", val, val);
+	return 0;
+}
+
+static int rv3029_eeprom_busywait(struct udevice *dev)
+{
+	int i, ret;
+	u8 sr;
 
-		if ((ctrl_status & RTC_RV3029_CTRLS_EEBUSY) == 0)
+	for (i = 100; i > 0; i--) {
+		ret = rv3029_get_sr(dev, &sr);
+		if (ret < 0)
+			break;
+		if (!(sr & RV3029_STATUS_EEBUSY))
 			break;
 		udelay(10000);
 	}
-	return i;
+	if (i <= 0) {
+		dev_err(dev, "EEPROM busy wait timeout.\n");
+		return -ETIMEDOUT;
+	}
+
+	return ret;
 }
 
-void rtc_reset (void)
+static int rv3029_update_bits(struct udevice *dev, u8 reg, u8 mask, u8 set)
 {
-	unsigned char buf[RTC_RV3029_PAGE_LEN];
+	u8 buf;
+	int ret;
 
-	buf[0] = RTC_RV3029_CTRL_SYS_R;
-	(void)i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL_RESET, 1,
-			buf, 1);
+	ret = dm_i2c_read(dev, reg, &buf, 1);
+	if (ret < 0)
+		return ret;
 
-#if defined(CONFIG_SYS_RV3029_TCR)
-	/*
-	 * because EEPROM_CTRL register is in EEPROM page it is necessary to
-	 * disable automatic EEPROM refresh and check if EEPROM is busy
-	 * before EEPORM_CTRL register may be accessed
-	 */
-	set_eere_bit(0);
-	wait_eebusy(100);
-	/* read current trickle charger setting */
-	(void)i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_EEPROM_CTRL,
-			1, buf, 1);
-	/* enable automatic EEPROM refresh again */
-	set_eere_bit(1);
+	if ((buf & mask) == (set && mask))
+		return 0;
 
-	/*
-	 * to minimize EEPROM access write trickle charger setting only if it
-	 * differs from current value
-	 */
-	if ((buf[0] & 0xF0) != CONFIG_SYS_RV3029_TCR) {
-		buf[0] = (buf[0] & 0x0F) | CONFIG_SYS_RV3029_TCR;
-		/*
-		 * write trickle charger setting (disable autom. EEPROM
-		 * refresh and wait until EEPROM is idle)
-		 */
-		set_eere_bit(0);
-		wait_eebusy(100);
-		(void)i2c_write(CONFIG_SYS_I2C_RTC_ADDR,
-				RTC_RV3029_EEPROM_CTRL, 1, buf, 1);
-		/*
-		 * it is necessary to wait 10ms before EEBUSY-Bit may be read
-		 * (this is not documented in the data sheet yet, but the
-		 * manufacturer recommends it)
+	buf = (buf & ~mask) | (set & mask);
+	ret = dm_i2c_read(dev, reg, &buf, 1);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int rv3029_eeprom_exit(struct udevice *dev)
+{
+	/* Re-enable eeprom refresh */
+	return rv3029_update_bits(dev, RV3029_ONOFF_CTRL,
+				  RV3029_ONOFF_CTRL_EERE,
+				  RV3029_ONOFF_CTRL_EERE);
+}
+
+static int rv3029_eeprom_enter(struct udevice *dev)
+{
+	int ret;
+	u8 sr;
+
+	/* Check whether we are in the allowed voltage range. */
+	ret = rv3029_get_sr(dev, &sr);
+	if (ret < 0)
+		return ret;
+	if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
+		/* We clear the bits and retry once just in case
+		 * we had a brown out in early startup.
 		 */
+		sr &= ~RV3029_STATUS_VLOW1;
+		sr &= ~RV3029_STATUS_VLOW2;
+		ret = rv3029_set_sr(dev, sr);
+		if (ret < 0)
+			return ret;
 		udelay(10000);
-		/* wait until EEPROM write access is finished */
-		wait_eebusy(100);
-		set_eere_bit(1);
+		ret = rv3029_get_sr(dev, &sr);
+		if (ret < 0)
+			return ret;
+		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
+			dev_err(dev, "Supply voltage is too low to safely access the EEPROM.\n");
+			return -ENODEV;
+		}
 	}
+
+	/* Disable eeprom refresh. */
+	ret = rv3029_update_bits(dev,
+				 RV3029_ONOFF_CTRL, RV3029_ONOFF_CTRL_EERE, 0);
+	if (ret < 0)
+		return ret;
+
+	/* Wait for any previous eeprom accesses to finish. */
+	ret = rv3029_eeprom_busywait(dev);
+	if (ret < 0)
+		rv3029_eeprom_exit(dev);
+
+	return ret;
+}
+
+static int rv3029_eeprom_read(struct udevice *dev, u8 reg,
+			      u8 buf[], size_t len)
+{
+	int ret, err;
+
+	err = rv3029_eeprom_enter(dev);
+	if (err < 0)
+		return err;
+
+	ret = dm_i2c_read(dev, reg, buf, len);
+
+	err = rv3029_eeprom_exit(dev);
+	if (err < 0)
+		return err;
+
+	return ret;
+}
+
+static int rv3029_eeprom_write(struct udevice *dev, u8 reg,
+			       u8 const buf[], size_t len)
+{
+	int ret;
+	size_t i;
+	u8 tmp;
+
+	ret = rv3029_eeprom_enter(dev);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < len; i++, reg++) {
+		ret = dm_i2c_read(dev, reg, &tmp, 1);
+		if (ret < 0)
+			break;
+		if (tmp != buf[i]) {
+			ret = dm_i2c_write(dev, reg, &buf[i], 1);
+			if (ret < 0)
+				break;
+		}
+		ret = rv3029_eeprom_busywait(dev);
+		if (ret < 0)
+			break;
+	}
+
+	ret = rv3029_eeprom_exit(dev);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int rv3029_eeprom_update_bits(struct udevice *dev,
+				     u8 reg, u8 mask, u8 set)
+{
+	u8 buf;
+	int ret;
+
+	ret = rv3029_eeprom_read(dev, reg, &buf, 1);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * If the EEPROM already reads the correct bitpattern, we don't need
+	 * to update it.
+	 */
+	if ((buf & mask) == (set & mask))
+		return 0;
+
+	buf = (buf & ~mask) | (set & mask);
+	ret = rv3029_eeprom_write(dev, reg, &buf, 1);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static void rv3029_trickle_config(struct udevice *dev)
+{
+	static const struct rv3029_trickle_tab_elem {
+		u32 r;		/* resistance in ohms */
+		u8 conf;	/* trickle config bits */
+	} rv3029_trickle_tab[] = {
+		{
+			.r	= 1076,
+			.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
+				  RV3029_TRICKLE_20K | RV3029_TRICKLE_80K,
+		}, {
+			.r	= 1091,
+			.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
+				  RV3029_TRICKLE_20K,
+		}, {
+			.r	= 1137,
+			.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
+				  RV3029_TRICKLE_80K,
+		}, {
+			.r	= 1154,
+			.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_5K,
+		}, {
+			.r	= 1371,
+			.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_20K |
+				  RV3029_TRICKLE_80K,
+		}, {
+			.r	= 1395,
+			.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_20K,
+		}, {
+			.r	= 1472,
+			.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_80K,
+		}, {
+			.r	= 1500,
+			.conf	= RV3029_TRICKLE_1K,
+		}, {
+			.r	= 3810,
+			.conf	= RV3029_TRICKLE_5K | RV3029_TRICKLE_20K |
+				  RV3029_TRICKLE_80K,
+		}, {
+			.r	= 4000,
+			.conf	= RV3029_TRICKLE_5K | RV3029_TRICKLE_20K,
+		}, {
+			.r	= 4706,
+			.conf	= RV3029_TRICKLE_5K | RV3029_TRICKLE_80K,
+		}, {
+			.r	= 5000,
+			.conf	= RV3029_TRICKLE_5K,
+		}, {
+			.r	= 16000,
+			.conf	= RV3029_TRICKLE_20K | RV3029_TRICKLE_80K,
+		}, {
+			.r	= 20000,
+			.conf	= RV3029_TRICKLE_20K,
+		}, {
+			.r	= 80000,
+			.conf	= RV3029_TRICKLE_80K,
+		},
+	};
+	int err;
+	u32 ohms;
+	u8 trickle_set_bits = 0;
+
+	/* Configure the trickle charger. */
+	err = dev_read_u32(dev, "trickle-resistor-ohms", &ohms);
+
+	if (!err) {
+		/* Find trickle-charger config */
+		for (int i = 0; i < ARRAY_SIZE(rv3029_trickle_tab); i++)
+			if (rv3029_trickle_tab[i].r >= ohms) {
+				dev_dbg(dev, "trickle charger at %d ohms\n",
+					rv3029_trickle_tab[i].r);
+				trickle_set_bits = rv3029_trickle_tab[i].conf;
+				break;
+			}
+	}
+
+	dev_dbg(dev, "trickle charger config 0x%x\n", trickle_set_bits);
+	err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
+					RV3029_TRICKLE_MASK,
+					trickle_set_bits);
+	if (err < 0)
+		dev_dbg(dev, "failed to update trickle charger\n");
+}
+#else
+static inline void rv3029_trickle_config(struct udevice *dev)
+{
+}
 #endif
+
+static int rv3029_probe(struct udevice *dev)
+{
+	i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS |
+				DM_I2C_CHIP_WR_ADDRESS);
+
+	rv3029_trickle_config(dev);
+	return 0;
 }
+
+static const struct rtc_ops rv3029_rtc_ops = {
+	.get = rv3029_rtc_get,
+	.set = rv3029_rtc_set,
+	.read8 = rv3029_rtc_read8,
+	.write8 = rv3029_rtc_write8,
+	.reset = rv3029_rtc_reset,
+};
+
+static const struct udevice_id rv3029_rtc_ids[] = {
+	{ .compatible = "mc,rv3029" },
+	{ .compatible = "mc,rv3029c2" },
+	{ }
+};
+
+U_BOOT_DRIVER(rtc_rv3029) = {
+	.name	= "rtc-rv3029",
+	.id	= UCLASS_RTC,
+	.probe	= rv3029_probe,
+	.of_match = rv3029_rtc_ids,
+	.ops	= &rv3029_rtc_ops,
+};
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 6625a65..3bcc61e 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -368,6 +368,16 @@
 	  You will need to provide parameters to make this work. The driver
 	  will be available until the real driver model serial is running.
 
+config DEBUG_UART_MTK
+	bool "MediaTek High-speed UART"
+	depends on MTK_SERIAL
+	help
+	  Select this to enable a debug UART using the MediaTek High-speed
+	  UART driver.
+	  You will need to provide parameters to make this work. The
+	  driver will be available until the real driver model serial is
+	  running.
+
 endchoice
 
 config DEBUG_UART_BASE
@@ -698,6 +708,16 @@
 	  This driver supports the Cadence UART. It is found e.g. in Xilinx
 	  Zynq/ZynqMP.
 
+config MTK_SERIAL
+	bool "MediaTek High-speed UART support"
+	depends on DM_SERIAL
+	help
+	  Select this to enable UART support for MediaTek High-speed UART
+	  devices. This driver uses driver model and requires a device
+	  tree binding to operate.
+	  The High-speed UART is compatible with the ns16550a UART and have
+	  its own high-speed registers.
+
 config MPC8XX_CONS
 	bool "Console driver for MPC8XX"
 	depends on MPC8xx
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index a48458f..b6377b1 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -67,6 +67,7 @@
 obj-$(CONFIG_NULLDEV_SERIAL) += serial_nulldev.o
 obj-$(CONFIG_OWL_SERIAL) += serial_owl.o
 obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o
+obj-$(CONFIG_MTK_SERIAL) += serial_mtk.o
 
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_USB_TTY) += usbtty.o
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index f21c240..25b9d17 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -272,26 +272,12 @@
 	serial_dout(&com_port->lcr, UART_LCRVAL);
 }
 
-static inline int NS16550_read_baud_divisor(struct NS16550 *com_port)
-{
-	int ret;
-
-	serial_dout(&com_port->lcr, UART_LCR_BKSE | UART_LCRVAL);
-	ret = serial_din(&com_port->dll) & 0xff;
-	ret |= (serial_din(&com_port->dlm) & 0xff) << 8;
-	serial_dout(&com_port->lcr, UART_LCRVAL);
-
-	return ret;
-}
-
 static inline void _debug_uart_putc(int ch)
 {
 	struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
 
-	while (!(serial_din(&com_port->lsr) & UART_LSR_THRE)) {
-		if (!NS16550_read_baud_divisor(com_port))
-			return;
-	}
+	while (!(serial_din(&com_port->lsr) & UART_LSR_THRE))
+		;
 	serial_dout(&com_port->thr, ch);
 }
 
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index c499601..09365ba 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -119,7 +119,6 @@
 serial_initfunc(atmel_serial_initialize);
 serial_initfunc(mcf_serial_initialize);
 serial_initfunc(mpc85xx_serial_initialize);
-serial_initfunc(mpc8xx_serial_initialize);
 serial_initfunc(mxc_serial_initialize);
 serial_initfunc(ns16550_serial_initialize);
 serial_initfunc(pl01x_serial_initialize);
@@ -173,7 +172,6 @@
 	atmel_serial_initialize();
 	mcf_serial_initialize();
 	mpc85xx_serial_initialize();
-	mpc8xx_serial_initialize();
 	mxc_serial_initialize();
 	ns16550_serial_initialize();
 	pl01x_serial_initialize();
diff --git a/drivers/serial/serial_mpc8xx.c b/drivers/serial/serial_mpc8xx.c
index 292912b..50d6e70 100644
--- a/drivers/serial/serial_mpc8xx.c
+++ b/drivers/serial/serial_mpc8xx.c
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <dm.h>
 #include <serial.h>
 #include <watchdog.h>
 #include <asm/cpm_8xx.h>
@@ -35,9 +36,9 @@
 	uchar	txbuf;	/* tx buffers */
 };
 
-static void serial_setdivisor(cpm8xx_t __iomem *cp)
+static void serial_setdivisor(cpm8xx_t __iomem *cp, int baudrate)
 {
-	int divisor = (gd->cpu_clk + 8 * gd->baudrate) / 16 / gd->baudrate;
+	int divisor = (gd->cpu_clk + 8 * baudrate) / 16 / baudrate;
 
 	if (divisor / 16 > 0x1000) {
 		/* bad divisor, assume 50MHz clock and 9600 baud */
@@ -58,7 +59,7 @@
  * as serial console interface.
  */
 
-static void smc_setbrg(void)
+static int serial_mpc8xx_setbrg(struct udevice *dev, int baudrate)
 {
 	immap_t __iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR;
 	cpm8xx_t __iomem *cp = &(im->im_cpm);
@@ -71,10 +72,12 @@
 
 	out_be32(&cp->cp_simode, 0);
 
-	serial_setdivisor(cp);
+	serial_setdivisor(cp, baudrate);
+
+	return 0;
 }
 
-static int smc_init(void)
+static int serial_mpc8xx_probe(struct udevice *dev)
 {
 	immap_t __iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR;
 	smc_t __iomem *sp;
@@ -139,7 +142,7 @@
 	out_8(&sp->smc_smce, 0xff);
 
 	/* Set up the baud rate generator */
-	smc_setbrg();
+	serial_mpc8xx_setbrg(dev, gd->baudrate);
 
 	/* Make the first buffer the only buffer. */
 	setbits_be16(&rtx->txbd.cbd_sc, BD_SC_WRAP);
@@ -166,14 +169,14 @@
 	return 0;
 }
 
-static void smc_putc(const char c)
+static int serial_mpc8xx_putc(struct udevice *dev, const char c)
 {
 	immap_t	__iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR;
 	cpm8xx_t	__iomem *cpmp = &(im->im_cpm);
 	struct serialbuffer	__iomem *rtx;
 
 	if (c == '\n')
-		smc_putc('\r');
+		serial_mpc8xx_putc(dev, '\r');
 
 	rtx = (struct serialbuffer __iomem *)&cpmp->cp_dpmem[CPM_SERIAL_BASE];
 
@@ -184,15 +187,11 @@
 
 	while (in_be16(&rtx->txbd.cbd_sc) & BD_SC_READY)
 		WATCHDOG_RESET();
-}
 
-static void smc_puts(const char *s)
-{
-	while (*s)
-		smc_putc(*s++);
+	return 0;
 }
 
-static int smc_getc(void)
+static int serial_mpc8xx_getc(struct udevice *dev)
 {
 	immap_t	__iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR;
 	cpm8xx_t	__iomem *cpmp = &(im->im_cpm);
@@ -222,34 +221,37 @@
 	return c;
 }
 
-static int smc_tstc(void)
+static int serial_mpc8xx_pending(struct udevice *dev, bool input)
 {
 	immap_t	__iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR;
 	cpm8xx_t	__iomem *cpmp = &(im->im_cpm);
 	struct serialbuffer	__iomem *rtx;
 
+	if (!input)
+		return 0;
+
 	rtx = (struct serialbuffer __iomem *)&cpmp->cp_dpmem[CPM_SERIAL_BASE];
 
 	return !(in_be16(&rtx->rxbd.cbd_sc) & BD_SC_EMPTY);
 }
 
-struct serial_device serial_smc_device = {
-	.name	= "serial_smc",
-	.start	= smc_init,
-	.stop	= NULL,
-	.setbrg	= smc_setbrg,
-	.getc	= smc_getc,
-	.tstc	= smc_tstc,
-	.putc	= smc_putc,
-	.puts	= smc_puts,
+static const struct dm_serial_ops serial_mpc8xx_ops = {
+	.putc = serial_mpc8xx_putc,
+	.pending = serial_mpc8xx_pending,
+	.getc = serial_mpc8xx_getc,
+	.setbrg = serial_mpc8xx_setbrg,
 };
 
-__weak struct serial_device *default_serial_console(void)
-{
-	return &serial_smc_device;
-}
+static const struct udevice_id serial_mpc8xx_ids[] = {
+	{ .compatible = "fsl,pq1-smc" },
+	{ }
+};
 
-void mpc8xx_serial_initialize(void)
-{
-	serial_register(&serial_smc_device);
-}
+U_BOOT_DRIVER(serial_mpc8xx) = {
+	.name	= "serial_mpc8xx",
+	.id	= UCLASS_SERIAL,
+	.of_match = serial_mpc8xx_ids,
+	.probe = serial_mpc8xx_probe,
+	.ops	= &serial_mpc8xx_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/serial/serial_mtk.c b/drivers/serial/serial_mtk.c
new file mode 100644
index 0000000..bce1be8
--- /dev/null
+++ b/drivers/serial/serial_mtk.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek High-speed UART driver
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <div64.h>
+#include <dm.h>
+#include <errno.h>
+#include <serial.h>
+#include <watchdog.h>
+#include <asm/io.h>
+#include <asm/types.h>
+
+struct mtk_serial_regs {
+	u32 rbr;
+	u32 ier;
+	u32 fcr;
+	u32 lcr;
+	u32 mcr;
+	u32 lsr;
+	u32 msr;
+	u32 spr;
+	u32 mdr1;
+	u32 highspeed;
+	u32 sample_count;
+	u32 sample_point;
+	u32 fracdiv_l;
+	u32 fracdiv_m;
+	u32 escape_en;
+	u32 guard;
+	u32 rx_sel;
+};
+
+#define thr rbr
+#define iir fcr
+#define dll rbr
+#define dlm ier
+
+#define UART_LCR_WLS_8	0x03		/* 8 bit character length */
+#define UART_LCR_DLAB	0x80		/* Divisor latch access bit */
+
+#define UART_LSR_DR	0x01		/* Data ready */
+#define UART_LSR_THRE	0x20		/* Xmit holding register empty */
+
+/* the data is correct if the real baud is within 3%. */
+#define BAUD_ALLOW_MAX(baud)	((baud) + (baud) * 3 / 100)
+#define BAUD_ALLOW_MIX(baud)	((baud) - (baud) * 3 / 100)
+
+struct mtk_serial_priv {
+	struct mtk_serial_regs __iomem *regs;
+	u32 clock;
+};
+
+static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud)
+{
+	bool support_clk12m_baud115200;
+	u32 quot, samplecount, realbaud;
+
+	if ((baud <= 115200) && (priv->clock == 12000000))
+		support_clk12m_baud115200 = true;
+	else
+		support_clk12m_baud115200 = false;
+
+	if (baud <= 115200) {
+		writel(0, &priv->regs->highspeed);
+		quot = DIV_ROUND_CLOSEST(priv->clock, 16 * baud);
+
+		if (support_clk12m_baud115200) {
+			writel(3, &priv->regs->highspeed);
+			quot = DIV_ROUND_CLOSEST(priv->clock, 256 * baud);
+			if (quot == 0)
+				quot = 1;
+
+			samplecount = DIV_ROUND_CLOSEST(priv->clock,
+							quot * baud);
+			if (samplecount != 0) {
+				realbaud = priv->clock / samplecount / quot;
+				if ((realbaud > BAUD_ALLOW_MAX(baud)) ||
+				    (realbaud < BAUD_ALLOW_MIX(baud))) {
+					pr_info("baud %d can't be handled\n",
+						baud);
+				}
+			} else {
+				pr_info("samplecount is 0\n");
+			}
+		}
+	} else if (baud <= 576000) {
+		writel(2, &priv->regs->highspeed);
+
+		/* Set to next lower baudrate supported */
+		if ((baud == 500000) || (baud == 576000))
+			baud = 460800;
+		quot = DIV_ROUND_UP(priv->clock, 4 * baud);
+	} else {
+		writel(3, &priv->regs->highspeed);
+		quot = DIV_ROUND_UP(priv->clock, 256 * baud);
+	}
+
+	/* set divisor */
+	writel(UART_LCR_WLS_8 | UART_LCR_DLAB, &priv->regs->lcr);
+	writel(quot & 0xff, &priv->regs->dll);
+	writel((quot >> 8) & 0xff, &priv->regs->dlm);
+	writel(UART_LCR_WLS_8, &priv->regs->lcr);
+
+	if (baud > 460800) {
+		u32 tmp;
+
+		tmp = DIV_ROUND_CLOSEST(priv->clock, quot * baud);
+		writel(tmp - 1, &priv->regs->sample_count);
+		writel((tmp - 2) >> 1, &priv->regs->sample_point);
+	} else {
+		writel(0, &priv->regs->sample_count);
+		writel(0xff, &priv->regs->sample_point);
+	}
+
+	if (support_clk12m_baud115200) {
+		writel(samplecount - 1, &priv->regs->sample_count);
+		writel((samplecount - 2) >> 1, &priv->regs->sample_point);
+	}
+}
+
+static int mtk_serial_setbrg(struct udevice *dev, int baudrate)
+{
+	struct mtk_serial_priv *priv = dev_get_priv(dev);
+
+	_mtk_serial_setbrg(priv, baudrate);
+
+	return 0;
+}
+
+static int mtk_serial_putc(struct udevice *dev, const char ch)
+{
+	struct mtk_serial_priv *priv = dev_get_priv(dev);
+
+	if (!(readl(&priv->regs->lsr) & UART_LSR_THRE))
+		return -EAGAIN;
+
+	writel(ch, &priv->regs->thr);
+
+	if (ch == '\n')
+		WATCHDOG_RESET();
+
+	return 0;
+}
+
+static int mtk_serial_getc(struct udevice *dev)
+{
+	struct mtk_serial_priv *priv = dev_get_priv(dev);
+
+	if (!(readl(&priv->regs->lsr) & UART_LSR_DR))
+		return -EAGAIN;
+
+	return readl(&priv->regs->rbr);
+}
+
+static int mtk_serial_pending(struct udevice *dev, bool input)
+{
+	struct mtk_serial_priv *priv = dev_get_priv(dev);
+
+	if (input)
+		return (readl(&priv->regs->lsr) & UART_LSR_DR) ? 1 : 0;
+	else
+		return (readl(&priv->regs->lsr) & UART_LSR_THRE) ? 0 : 1;
+}
+
+static int mtk_serial_probe(struct udevice *dev)
+{
+	struct mtk_serial_priv *priv = dev_get_priv(dev);
+
+	/* Disable interrupt */
+	writel(0, &priv->regs->ier);
+
+	return 0;
+}
+
+static int mtk_serial_ofdata_to_platdata(struct udevice *dev)
+{
+	struct mtk_serial_priv *priv = dev_get_priv(dev);
+	fdt_addr_t addr;
+	struct clk clk;
+	int err;
+
+	addr = dev_read_addr(dev);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->regs = map_physmem(addr, 0, MAP_NOCACHE);
+
+	err = clk_get_by_index(dev, 0, &clk);
+	if (!err) {
+		err = clk_get_rate(&clk);
+		if (!IS_ERR_VALUE(err))
+			priv->clock = err;
+	} else if (err != -ENOENT && err != -ENODEV && err != -ENOSYS) {
+		debug("mtk_serial: failed to get clock\n");
+		return err;
+	}
+
+	if (!priv->clock)
+		priv->clock = dev_read_u32_default(dev, "clock-frequency", 0);
+
+	if (!priv->clock) {
+		debug("mtk_serial: clock not defined\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct dm_serial_ops mtk_serial_ops = {
+	.putc = mtk_serial_putc,
+	.pending = mtk_serial_pending,
+	.getc = mtk_serial_getc,
+	.setbrg = mtk_serial_setbrg,
+};
+
+static const struct udevice_id mtk_serial_ids[] = {
+	{ .compatible = "mediatek,hsuart" },
+	{ .compatible = "mediatek,mt6577-uart" },
+	{ }
+};
+
+U_BOOT_DRIVER(serial_mtk) = {
+	.name = "serial_mtk",
+	.id = UCLASS_SERIAL,
+	.of_match = mtk_serial_ids,
+	.ofdata_to_platdata = mtk_serial_ofdata_to_platdata,
+	.priv_auto_alloc_size = sizeof(struct mtk_serial_priv),
+	.probe = mtk_serial_probe,
+	.ops = &mtk_serial_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+#ifdef CONFIG_DEBUG_UART_MTK
+
+#include <debug_uart.h>
+
+static inline void _debug_uart_init(void)
+{
+	struct mtk_serial_priv priv;
+
+	priv.regs = (void *) CONFIG_DEBUG_UART_BASE;
+	priv.clock = CONFIG_DEBUG_UART_CLOCK;
+
+	writel(0, &priv.regs->ier);
+
+	_mtk_serial_setbrg(&priv, CONFIG_BAUDRATE);
+}
+
+static inline void _debug_uart_putc(int ch)
+{
+	struct mtk_serial_regs __iomem *regs =
+		(void *) CONFIG_DEBUG_UART_BASE;
+
+	while (!(readl(&regs->lsr) & UART_LSR_THRE))
+		;
+
+	writel(ch, &regs->thr);
+}
+
+DEBUG_UART_FUNCS
+
+#endif
\ No newline at end of file
diff --git a/drivers/sound/sound-i2s.c b/drivers/sound/sound-i2s.c
index 9f09e3b..f0f0b79 100644
--- a/drivers/sound/sound-i2s.c
+++ b/drivers/sound/sound-i2s.c
@@ -185,7 +185,8 @@
 		return -1;
 	}
 
-	sound_create_square_wave((unsigned short *)data,
+	sound_create_square_wave(g_i2stx_pri.samplingrate,
+				 (unsigned short *)data,
 				 data_size / sizeof(unsigned short),
 				 frequency);
 
diff --git a/drivers/sound/sound.c b/drivers/sound/sound.c
index 9694081..4f0ad0d 100644
--- a/drivers/sound/sound.c
+++ b/drivers/sound/sound.c
@@ -7,11 +7,11 @@
 #include <common.h>
 #include <sound.h>
 
-void sound_create_square_wave(unsigned short *data, int size, uint32_t freq)
+void sound_create_square_wave(uint sample_rate, unsigned short *data, int size,
+			      uint freq)
 {
-	const int sample = 48000;
 	const unsigned short amplitude = 16000; /* between 1 and 32767 */
-	const int period = freq ? sample / freq : 0;
+	const int period = freq ? sample_rate / freq : 0;
 	const int half = period / 2;
 
 	assert(freq);
@@ -25,12 +25,10 @@
 		for (i = 0; size && i < half; i++) {
 			size -= 2;
 			*data++ = amplitude;
-			*data++ = amplitude;
 		}
 		for (i = 0; size && i < period - half; i++) {
 			size -= 2;
 			*data++ = -amplitude;
-			*data++ = -amplitude;
 		}
 	}
 }
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index 29db6fa..11fce9c 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -329,7 +329,7 @@
 };
 
 static const struct udevice_id cadence_spi_ids[] = {
-	{ .compatible = "cadence,qspi" },
+	{ .compatible = "cdns,qspi-nor" },
 	{ }
 };
 
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index b84255b..2bc289a 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -15,6 +15,8 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#define SPI_DEFAULT_SPEED_HZ 100000
+
 static int spi_set_speed_mode(struct udevice *bus, int speed, int mode)
 {
 	struct dm_spi_ops *ops;
@@ -58,7 +60,7 @@
 			speed = spi->max_hz;
 	}
 	if (!speed)
-		speed = 100000;
+		speed = SPI_DEFAULT_SPEED_HZ;
 	if (speed != slave->speed) {
 		int ret = spi_set_speed_mode(bus, speed, slave->mode);
 
@@ -300,7 +302,13 @@
 		}
 		plat = dev_get_parent_platdata(dev);
 		plat->cs = cs;
-		plat->max_hz = speed;
+		if (speed) {
+			plat->max_hz = speed;
+		} else {
+			printf("Warning: SPI speed fallback to %u kHz\n",
+			       SPI_DEFAULT_SPEED_HZ / 1000);
+			plat->max_hz = SPI_DEFAULT_SPEED_HZ;
+		}
 		plat->mode = mode;
 		created = true;
 	} else if (ret) {
@@ -374,7 +382,8 @@
 	int value;
 
 	plat->cs = dev_read_u32_default(dev, "reg", -1);
-	plat->max_hz = dev_read_u32_default(dev, "spi-max-frequency", 0);
+	plat->max_hz = dev_read_u32_default(dev, "spi-max-frequency",
+					    SPI_DEFAULT_SPEED_HZ);
 	if (dev_read_bool(dev, "spi-cpol"))
 		mode |= SPI_CPOL;
 	if (dev_read_bool(dev, "spi-cpha"))
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index d0cfc35..b0e6f32 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -160,4 +160,11 @@
 	help
 	  Select this to enable Time-Stamp Counter (TSC) timer for x86.
 
+config MTK_TIMER
+	bool "MediaTek timer support"
+	depends on TIMER
+	help
+	  Select this to enable support for the timer found on
+	  MediaTek devices.
+
 endmenu
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index 7f19c49..c4fbab2 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -18,3 +18,4 @@
 obj-$(CONFIG_STI_TIMER)		+= sti-timer.o
 obj-$(CONFIG_STM32_TIMER)	+= stm32_timer.o
 obj-$(CONFIG_X86_TSC_TIMER)	+= tsc_timer.o
+obj-$(CONFIG_MTK_TIMER)		+= mtk_timer.o
diff --git a/drivers/timer/mtk_timer.c b/drivers/timer/mtk_timer.c
new file mode 100644
index 0000000..b5e76bd
--- /dev/null
+++ b/drivers/timer/mtk_timer.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek timer driver
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <timer.h>
+#include <asm/io.h>
+
+#define MTK_GPT4_CTRL	0x40
+#define MTK_GPT4_CLK	0x44
+#define MTK_GPT4_CNT	0x48
+
+#define GPT4_ENABLE	BIT(0)
+#define GPT4_CLEAR	BIT(1)
+#define GPT4_FREERUN	GENMASK(5, 4)
+#define GPT4_CLK_SYS	0x0
+#define GPT4_CLK_DIV1	0x0
+
+struct mtk_timer_priv {
+	void __iomem *base;
+};
+
+static int mtk_timer_get_count(struct udevice *dev, u64 *count)
+{
+	struct mtk_timer_priv *priv = dev_get_priv(dev);
+	u32 val = readl(priv->base + MTK_GPT4_CNT);
+
+	*count = timer_conv_64(val);
+
+	return 0;
+}
+
+static int mtk_timer_probe(struct udevice *dev)
+{
+	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct mtk_timer_priv *priv = dev_get_priv(dev);
+	struct clk clk, parent;
+	int ret;
+
+	priv->base = dev_read_addr_ptr(dev);
+	if (!priv->base)
+		return -ENOENT;
+
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret)
+		return ret;
+
+	ret = clk_get_by_index(dev, 1, &parent);
+	if (!ret) {
+		ret = clk_set_parent(&clk, &parent);
+		if (ret)
+			return ret;
+	}
+
+	uc_priv->clock_rate = clk_get_rate(&clk);
+	if (!uc_priv->clock_rate)
+		return -EINVAL;
+
+	return 0;
+}
+
+static const struct timer_ops mtk_timer_ops = {
+	.get_count = mtk_timer_get_count,
+};
+
+static const struct udevice_id mtk_timer_ids[] = {
+	{ .compatible = "mediatek,timer" },
+	{ }
+};
+
+U_BOOT_DRIVER(mtk_timer) = {
+	.name = "mtk_timer",
+	.id = UCLASS_TIMER,
+	.of_match = mtk_timer_ids,
+	.priv_auto_alloc_size = sizeof(struct mtk_timer_priv),
+	.probe = mtk_timer_probe,
+	.ops = &mtk_timer_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/tpm/tpm_tis_lpc.c b/drivers/tpm/tpm_tis_lpc.c
index e993fd9..30194bc 100644
--- a/drivers/tpm/tpm_tis_lpc.c
+++ b/drivers/tpm/tpm_tis_lpc.c
@@ -388,6 +388,27 @@
 	return offset;
 }
 
+static int tpm_tis_lpc_close(struct udevice *dev)
+{
+	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
+	struct tpm_locality *regs = priv->regs;
+	u8 locality = 0;
+
+	if (tpm_read_word(priv, &regs[locality].access) &
+	    TIS_ACCESS_ACTIVE_LOCALITY) {
+		tpm_write_word(priv, TIS_ACCESS_ACTIVE_LOCALITY,
+			       &regs[locality].access);
+
+		if (tis_wait_reg(priv, &regs[locality].access,
+				 TIS_ACCESS_ACTIVE_LOCALITY, 0) == -ETIMEDOUT) {
+			printf("%s:%d - failed to release locality %d\n",
+			       __FILE__, __LINE__, locality);
+			return -ETIMEDOUT;
+		}
+	}
+	return 0;
+}
+
 static int tpm_tis_lpc_open(struct udevice *dev)
 {
 	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
@@ -395,6 +416,12 @@
 	u8 locality = 0; /* we use locality zero for everything. */
 	int ret;
 
+	ret = tpm_tis_lpc_close(dev);
+	if (ret) {
+		printf("%s: Failed to close TPM\n", __func__);
+		return ret;
+	}
+
 	/* now request access to locality. */
 	tpm_write_word(priv, TIS_ACCESS_REQUEST_USE, &regs[locality].access);
 
@@ -410,27 +437,7 @@
 
 	tpm_write_word(priv, TIS_STS_COMMAND_READY,
 		       &regs[locality].tpm_status);
-	return 0;
-}
-
-static int tpm_tis_lpc_close(struct udevice *dev)
-{
-	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
-	struct tpm_locality *regs = priv->regs;
-	u8 locality = 0;
-
-	if (tpm_read_word(priv, &regs[locality].access) &
-	    TIS_ACCESS_ACTIVE_LOCALITY) {
-		tpm_write_word(priv, TIS_ACCESS_ACTIVE_LOCALITY,
-			       &regs[locality].access);
 
-		if (tis_wait_reg(priv, &regs[locality].access,
-				 TIS_ACCESS_ACTIVE_LOCALITY, 0) == -ETIMEDOUT) {
-			printf("%s:%d - failed to release locality %d\n",
-			       __FILE__, __LINE__, locality);
-			return -ETIMEDOUT;
-		}
-	}
 	return 0;
 }
 
diff --git a/drivers/tpm/tpm_tis_sandbox.c b/drivers/tpm/tpm_tis_sandbox.c
index 79517f0..3336f55 100644
--- a/drivers/tpm/tpm_tis_sandbox.c
+++ b/drivers/tpm/tpm_tis_sandbox.c
@@ -187,9 +187,11 @@
 
 	code = get_unaligned_be32(sendbuf + sizeof(uint16_t) +
 				  sizeof(uint32_t));
+#ifdef DEBUG
 	printf("tpm: %zd bytes, recv_len %zd, cmd = %x\n", send_size,
 	       *recv_len, code);
 	print_buffer(0, sendbuf, 1, send_size, 0);
+#endif
 	switch (code) {
 	case TPM_CMD_GET_CAPABILITY:
 		type = get_unaligned_be32(sendbuf + 14);
@@ -306,6 +308,10 @@
 		printf("Unknown tpm command %02x\n", code);
 		return -ENOSYS;
 	}
+#ifdef DEBUG
+	printf("tpm: rx recv_len %zd\n", *recv_len);
+	print_buffer(0, recvbuf, 1, *recv_len, 0);
+#endif
 
 	return 0;
 }
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 4fbe172..d456beb 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -47,6 +47,11 @@
 	  declared with the U_BOOT_USB_DEVICE() macro and will be
 	  automatically probed when found on the bus.
 
+config SPL_DM_USB
+	bool "Enable driver model for USB in SPL"
+	depends on DM_USB
+	default y
+
 source "drivers/usb/host/Kconfig"
 
 source "drivers/usb/dwc3/Kconfig"
@@ -65,6 +70,7 @@
 
 config USB_STORAGE
 	bool "USB Mass Storage support"
+	depends on !(BLK && !DM_USB)
 	---help---
 	  Say Y here if you want to connect USB mass storage devices to your
 	  board's USB port.
diff --git a/drivers/usb/common/Makefile b/drivers/usb/common/Makefile
index 55e0547..3bedbf2 100644
--- a/drivers/usb/common/Makefile
+++ b/drivers/usb/common/Makefile
@@ -3,6 +3,6 @@
 # (C) Copyright 2016 Freescale Semiconductor, Inc.
 #
 
-obj-$(CONFIG_DM_USB) += common.o
+obj-$(CONFIG_$(SPL_)DM_USB) += common.o
 obj-$(CONFIG_USB_EHCI_FSL) += fsl-dt-fixup.o fsl-errata.o
 obj-$(CONFIG_USB_XHCI_FSL) += fsl-dt-fixup.o fsl-errata.o
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 1ab5cee..f1ca619 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -789,7 +789,7 @@
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 
 int dwc3_init(struct dwc3 *dwc)
 {
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 58fe91d..cfe2988 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -712,7 +712,7 @@
 	/* device lock */
 	spinlock_t		lock;
 
-#if defined(__UBOOT__) && defined(CONFIG_DM_USB)
+#if defined(__UBOOT__) && CONFIG_IS_ENABLED(DM_USB)
 	struct udevice		*dev;
 #else
 	struct device		*dev;
diff --git a/drivers/usb/eth/usb_ether.c b/drivers/usb/eth/usb_ether.c
index 1ce3361..3aca9ac 100644
--- a/drivers/usb/eth/usb_ether.c
+++ b/drivers/usb/eth/usb_ether.c
@@ -271,7 +271,7 @@
 	}
 
 	usb_max_eth_dev = 0;
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	/*
 	 * TODO: We should add U_BOOT_USB_DEVICE() declarations to each USB
 	 * Ethernet driver and then most of this file can be removed.
diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c
index 0a84f68..bd596ce 100644
--- a/drivers/usb/gadget/ci_udc.c
+++ b/drivers/usb/gadget/ci_udc.c
@@ -1015,7 +1015,7 @@
 	if (driver->speed != USB_SPEED_FULL && driver->speed != USB_SPEED_HIGH)
 		return -EINVAL;
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	ret = usb_setup_ehci_gadget(&controller.ctrl);
 #else
 	ret = usb_lowlevel_init(0, USB_INIT_DEVICE, (void **)&controller.ctrl);
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 90ef1f0..193583b 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -100,7 +100,7 @@
 	struct usb_gadget	*gadget;
 	struct usb_request	*req;		/* for control responses */
 	struct usb_request	*stat_req;	/* for cdc & rndis status */
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	struct udevice		*usb_udev;
 #endif
 
@@ -2337,7 +2337,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 int dm_usb_init(struct eth_dev *e_dev)
 {
 	struct udevice *dev = NULL;
@@ -2362,7 +2362,7 @@
 	unsigned long ts;
 	unsigned long timeout = USB_CONNECT_TIMEOUT;
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	if (dm_usb_init(dev)) {
 		pr_err("USB ether not found\n");
 		return -ENODEV;
@@ -2541,7 +2541,7 @@
 	}
 
 	usb_gadget_unregister_driver(&priv->eth_driver);
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 	board_usb_cleanup(0, USB_INIT_DEVICE);
 #endif
 }
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index cb8c315..285c20a 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -3,8 +3,8 @@
 # (C) Copyright 2000-2007
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
-ifdef CONFIG_DM_USB
-obj-$(CONFIG_CMD_USB) += usb-uclass.o
+ifdef CONFIG_$(SPL_)DM_USB
+obj-y += usb-uclass.o
 obj-$(CONFIG_SANDBOX) += usb-sandbox.o
 endif
 
diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c
index b6f008a..a62a2f8 100644
--- a/drivers/usb/host/dwc2.c
+++ b/drivers/usb/host/dwc2.c
@@ -29,7 +29,7 @@
 #define MAX_ENDPOINT			16
 
 struct dwc2_priv {
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	uint8_t aligned_buffer[DWC2_DATA_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN);
 	uint8_t status_buffer[DWC2_STATUS_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN);
 #ifdef CONFIG_DM_REGULATOR
@@ -54,7 +54,7 @@
 	struct reset_ctl_bulk	resets;
 };
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 /* We need cacheline-aligned buffers for DMA transfers and dcache support */
 DEFINE_ALIGN_BUFFER(uint8_t, aligned_buffer_addr, DWC2_DATA_BUF_SIZE,
 		ARCH_DMA_MINALIGN);
@@ -168,7 +168,7 @@
 	mdelay(100);
 }
 
-#if defined(CONFIG_DM_USB) && defined(CONFIG_DM_REGULATOR)
+#if CONFIG_IS_ENABLED(DM_USB) && defined(CONFIG_DM_REGULATOR)
 static int dwc_vbus_supply_init(struct udevice *dev)
 {
 	struct dwc2_priv *priv = dev_get_priv(dev);
@@ -211,7 +211,7 @@
 	return 0;
 }
 
-#if defined(CONFIG_DM_USB)
+#if CONFIG_IS_ENABLED(DM_USB)
 static int dwc_vbus_supply_exit(struct udevice *dev)
 {
 	return 0;
@@ -1222,7 +1222,7 @@
 			DWC2_HPRT0_PRTRST);
 }
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 		       int len, struct devrequest *setup)
 {
@@ -1267,7 +1267,7 @@
 }
 #endif
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 static int dwc2_submit_control_msg(struct udevice *dev, struct usb_device *udev,
 				   unsigned long pipe, void *buffer, int length,
 				   struct devrequest *setup)
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index 66dc63d..6900848 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -14,7 +14,7 @@
 
 #include "ehci.h"
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 
 int ehci_hcd_init(int index, enum usb_init_type init,
 		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index a8fb2b8..23e7e71 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -25,7 +25,7 @@
 #define CONFIG_USB_MAX_CONTROLLER_COUNT 1
 #endif
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 struct ehci_fsl_priv {
 	struct ehci_ctrl ehci;
 	fdt_addr_t hcd_base;
@@ -34,7 +34,7 @@
 #endif
 
 static void set_txfifothresh(struct usb_ehci *, u32);
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 static int ehci_fsl_init(struct ehci_fsl_priv *priv, struct usb_ehci *ehci,
 		  struct ehci_hccr *hccr, struct ehci_hcor *hcor);
 #else
@@ -54,7 +54,7 @@
 	}
 }
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 static int ehci_fsl_ofdata_to_platdata(struct udevice *dev)
 {
 	struct ehci_fsl_priv *priv = dev_get_priv(dev);
@@ -183,7 +183,7 @@
 }
 #endif
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 static int ehci_fsl_init(struct ehci_fsl_priv *priv, struct usb_ehci *ehci,
 		  struct ehci_hccr *hccr, struct ehci_hcor *hcor)
 #else
@@ -192,7 +192,7 @@
 #endif
 {
 	const char *phy_type = NULL;
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 	size_t len;
 	char current_usb_controller[5];
 #endif
@@ -218,7 +218,7 @@
 	out_be32(&ehci->snoop2, 0x80000000 | SNOOP_SIZE_2GB);
 
 	/* Init phy */
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	if (priv->phy_type)
 		phy_type = priv->phy_type;
 #else
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d1d8f08..4b28db7 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -30,7 +30,7 @@
  */
 #define HCHALT_TIMEOUT (8 * 1000)
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 static struct ehci_ctrl ehcic[CONFIG_USB_MAX_CONTROLLER_COUNT];
 #endif
 
@@ -111,7 +111,7 @@
 
 static struct ehci_ctrl *ehci_get_ctrl(struct usb_device *udev)
 {
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	return dev_get_priv(usb_get_bus(udev->dev));
 #else
 	return udev->controller;
@@ -973,7 +973,7 @@
 	}
 }
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 void ehci_set_controller_priv(int index, void *priv, const struct ehci_ops *ops)
 {
 	struct ehci_ctrl *ctrl = &ehcic[index];
@@ -1097,7 +1097,7 @@
 	return 0;
 }
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 int usb_lowlevel_stop(int index)
 {
 	ehci_shutdown(&ehcic[index]);
@@ -1518,7 +1518,7 @@
 	return result;
 }
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
 			    void *buffer, int length)
 {
@@ -1556,7 +1556,7 @@
 }
 #endif
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 static int ehci_submit_control_msg(struct udevice *dev, struct usb_device *udev,
 				   unsigned long pipe, void *buffer, int length,
 				   struct devrequest *setup)
diff --git a/drivers/usb/host/ehci-marvell.c b/drivers/usb/host/ehci-marvell.c
index 73432f2..8efe6b6 100644
--- a/drivers/usb/host/ehci-marvell.c
+++ b/drivers/usb/host/ehci-marvell.c
@@ -38,7 +38,7 @@
 /*
  * USB 2.0 Bridge Address Decoding registers setup
  */
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 
 struct ehci_mvebu_priv {
 	struct ehci_ctrl ehci;
@@ -228,4 +228,4 @@
 	return 0;
 }
 
-#endif /* CONFIG_DM_USB */
+#endif /* CONFIG_IS_ENABLED(DM_USB) */
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index be010b1..1acf08d 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -335,7 +335,7 @@
 	return 0;
 }
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 int ehci_hcd_init(int index, enum usb_init_type init,
 		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 6150f3d..04e7c5e 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -19,7 +19,7 @@
 	struct phy phy;
 };
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 static int ehci_pci_init(struct udevice *dev, struct ehci_hccr **ret_hccr,
 			  struct ehci_hcor **ret_hcor)
 {
@@ -121,9 +121,9 @@
 {
 	return 0;
 }
-#endif /* nCONFIG_DM_USB */
+#endif /* !CONFIG_IS_ENABLED(DM_USB) */
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 static int ehci_pci_probe(struct udevice *dev)
 {
 	struct ehci_hccr *hccr;
@@ -173,4 +173,4 @@
 
 U_BOOT_PCI_DEVICE(ehci_pci, ehci_pci_supported);
 
-#endif /* CONFIG_DM_USB */
+#endif /* CONFIG_IS_ENABLED(DM_USB) */
diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index 22e5afa..a16cf13 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -153,7 +153,7 @@
 	return 0;
 }
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 int ehci_hcd_init(int index, enum usb_init_type init,
 		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 6ea9f10..3b6f889 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -120,7 +120,7 @@
 #define invalidate_dcache_iso_td(addr) invalidate_dcache_buffer(addr, 32)
 #define invalidate_dcache_hcca(addr) invalidate_dcache_buffer(addr, 256)
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 /*
  * The various ohci_mdelay(1) calls in the code seem unnecessary. We keep
  * them around when building for older boards not yet converted to the dm
@@ -131,7 +131,7 @@
 #define ohci_mdelay(x) mdelay(x)
 #endif
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 /* global ohci_t */
 static ohci_t gohci;
 /* this must be aligned to a 256 byte boundary */
@@ -1691,7 +1691,7 @@
 	return 0;
 }
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 /* submit routines called from usb.c */
 int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 		int transfer_len)
@@ -1980,7 +1980,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 
 /*-------------------------------------------------------------------------*/
 
@@ -2130,7 +2130,7 @@
 }
 #endif
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 static int ohci_submit_control_msg(struct udevice *dev, struct usb_device *udev,
 				   unsigned long pipe, void *buffer, int length,
 				   struct devrequest *setup)
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index fba78dc..f9f02cb 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -27,7 +27,7 @@
 #define ED_ALIGNMENT 16
 #endif
 
-#if defined CONFIG_DM_USB && ARCH_DMA_MINALIGN > 32
+#if CONFIG_IS_ENABLED(DM_USB) && ARCH_DMA_MINALIGN > 32
 #define TD_ALIGNMENT ARCH_DMA_MINALIGN
 #else
 #define TD_ALIGNMENT 32
@@ -406,7 +406,7 @@
 	const char	*slot_name;
 } ohci_t;
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 extern struct dm_usb_ops ohci_usb_ops;
 
 int ohci_register(struct udevice *dev, struct ohci_regs *regs);
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c
index 80754d7..dd0d156 100644
--- a/drivers/usb/host/xhci-dwc3.c
+++ b/drivers/usb/host/xhci-dwc3.c
@@ -109,7 +109,7 @@
 			GFLADJ_30MHZ(val));
 }
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 static int xhci_dwc3_setup_phy(struct udevice *dev)
 {
 	struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
diff --git a/drivers/usb/host/xhci-fsl.c b/drivers/usb/host/xhci-fsl.c
index 047a8df..c0b98a8 100644
--- a/drivers/usb/host/xhci-fsl.c
+++ b/drivers/usb/host/xhci-fsl.c
@@ -19,7 +19,7 @@
 #include <dm.h>
 
 /* Declare global data pointer */
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 static struct fsl_xhci fsl_xhci;
 unsigned long ctr_addr[] = FSL_USB_XHCI_ADDR;
 #else
@@ -107,7 +107,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 static int xhci_fsl_probe(struct udevice *dev)
 {
 	struct xhci_fsl_priv *priv = dev_get_priv(dev);
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index da5dbd9..04ab540 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -723,7 +723,7 @@
 	int slot_id = udev->slot_id;
 	int speed = udev->speed;
 	int route = 0;
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	struct usb_device *dev = udev;
 	struct usb_hub_device *hub;
 #endif
@@ -739,7 +739,7 @@
 	/* Only the control endpoint is valid - one endpoint context */
 	slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1));
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	/* Calculate the route string for this device */
 	port_num = dev->portnr;
 	while (!usb_hub_is_root_hub(dev->dev)) {
@@ -782,7 +782,7 @@
 		BUG();
 	}
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	/* Set up TT fields to support FS/LS devices */
 	if (speed == USB_SPEED_LOW || speed == USB_SPEED_FULL) {
 		struct udevice *parent = udev->dev;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 9ded14c..44c5f2d 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -108,13 +108,13 @@
 	},
 };
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 static struct xhci_ctrl xhcic[CONFIG_USB_MAX_CONTROLLER_COUNT];
 #endif
 
 struct xhci_ctrl *xhci_get_ctrl(struct usb_device *udev)
 {
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	struct udevice *dev;
 
 	/* Find the USB controller */
@@ -741,7 +741,7 @@
 	return 0;
 }
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 int usb_alloc_device(struct usb_device *udev)
 {
 	return _xhci_alloc_device(udev);
@@ -1256,7 +1256,7 @@
 	return 0;
 }
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 int submit_control_msg(struct usb_device *udev, unsigned long pipe,
 		       void *buffer, int length, struct devrequest *setup)
 {
@@ -1340,9 +1340,9 @@
 
 	return 0;
 }
-#endif /* CONFIG_DM_USB */
+#endif /* CONFIG_IS_ENABLED(DM_USB) */
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 
 static int xhci_submit_control_msg(struct udevice *dev, struct usb_device *udev,
 				   unsigned long pipe, void *buffer, int length,
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index a7555b2..6017504 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1211,7 +1211,7 @@
 #define XHCI_STS_CNR		(1 << 11)
 
 struct xhci_ctrl {
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	struct udevice *dev;
 #endif
 	struct xhci_hccr *hccr;	/* R/O registers, not need for volatile */
diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index 2bf918e..d40772b 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -19,7 +19,7 @@
 	struct urb urb;
 };
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 struct musb_host_data musb_host;
 #endif
 
@@ -243,7 +243,7 @@
 	return 0;
 }
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 int usb_lowlevel_stop(int index)
 {
 	if (!musb_host.host) {
@@ -300,9 +300,9 @@
 {
 	return musb_lowlevel_init(&musb_host);
 }
-#endif /* !CONFIG_DM_USB */
+#endif /* !CONFIG_IS_ENABLED(DM_USB) */
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 static int musb_submit_control_msg(struct udevice *dev, struct usb_device *udev,
 				   unsigned long pipe, void *buffer, int length,
 				   struct devrequest *setup)
@@ -364,7 +364,7 @@
 	.destroy_int_queue = musb_destroy_int_queue,
 	.reset_root_port = musb_reset_root_port,
 };
-#endif /* CONFIG_DM_USB */
+#endif /* CONFIG_IS_ENABLED(DM_USB) */
 #endif /* CONFIG_USB_MUSB_HOST */
 
 #ifdef CONFIG_USB_MUSB_GADGET
@@ -425,7 +425,7 @@
 	struct musb **musbp;
 
 	switch (plat->mode) {
-#if defined(CONFIG_USB_MUSB_HOST) && !defined(CONFIG_DM_USB)
+#if defined(CONFIG_USB_MUSB_HOST) && !CONFIG_IS_ENABLED(DM_USB)
 	case MUSB_HOST:
 		musbp = &musb_host.host;
 		break;
diff --git a/drivers/usb/musb-new/omap2430.c b/drivers/usb/musb-new/omap2430.c
index 342d76b..58aed72 100644
--- a/drivers/usb/musb-new/omap2430.c
+++ b/drivers/usb/musb-new/omap2430.c
@@ -135,7 +135,7 @@
 	.disable	= omap2430_musb_disable,
 };
 
-#if defined(CONFIG_DM_USB)
+#if CONFIG_IS_ENABLED(DM_USB)
 
 struct omap2430_musb_platdata {
 	void *base;
@@ -276,4 +276,4 @@
 	.priv_auto_alloc_size = sizeof(struct musb_host_data),
 };
 
-#endif /* CONFIG_DM_USB */
+#endif /* CONFIG_IS_ENABLED(DM_USB) */
diff --git a/drivers/usb/musb-new/ti-musb.c b/drivers/usb/musb-new/ti-musb.c
index 9fbe2d6..ee09607 100644
--- a/drivers/usb/musb-new/ti-musb.c
+++ b/drivers/usb/musb-new/ti-musb.c
@@ -19,7 +19,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 
 /* USB 2.0 PHY Control */
 #define CM_PHY_PWRDN			(1 << 0)
@@ -251,4 +251,4 @@
 	.bind = ti_musb_wrapper_bind,
 };
 
-#endif /* CONFIG_DM_USB */
+#endif /* CONFIG_IS_ENABLED(DM_USB) */
diff --git a/drivers/usb/musb-new/usb-compat.h b/drivers/usb/musb-new/usb-compat.h
index 760bd78..f2c18ad 100644
--- a/drivers/usb/musb-new/usb-compat.h
+++ b/drivers/usb/musb-new/usb-compat.h
@@ -67,7 +67,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 static inline struct usb_device *usb_dev_get_parent(struct usb_device *udev)
 {
 	struct udevice *parent = udev->dev->parent;
diff --git a/drivers/video/rockchip/rk_mipi.c b/drivers/video/rockchip/rk_mipi.c
index 4fe8f47..4f1a0f3 100644
--- a/drivers/video/rockchip/rk_mipi.c
+++ b/drivers/video/rockchip/rk_mipi.c
@@ -106,7 +106,7 @@
 	rk_mipi_dsi_write(regs, VSYNC_ACTIVE_LOW, val);
 
 	val = (timing->flags & DISPLAY_FLAGS_DE_LOW) ? 1 : 0;
-	rk_mipi_dsi_write(regs, DISPLAY_FLAGS_DE_LOW, val);
+	rk_mipi_dsi_write(regs, DATAEN_ACTIVE_LOW, val);
 
 	val = (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) ? 1 : 0;
 	rk_mipi_dsi_write(regs, COLORM_ACTIVE_LOW, val);
@@ -241,7 +241,7 @@
 
 	/* select the suitable value for fsfreqrang reg */
 	for (i = 0; i < ARRAY_SIZE(freq_rang); i++) {
-		if (ddr_clk / (MHz) >= freq_rang[i][0])
+		if (ddr_clk / (MHz) <= freq_rang[i][0])
 			break;
 	}
 	if (i == ARRAY_SIZE(freq_rang)) {
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index 1874887..2ca19d4 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -272,6 +272,14 @@
 		s++;    /* ; */
 		s = parsenum(s, &col);
 
+		/*
+		 * Video origin is [0, 0], terminal origin is [1, 1].
+		 */
+		if (row)
+			--row;
+		if (col)
+			--col;
+
 		set_cursor_position(priv, row, col);
 
 		break;
@@ -344,7 +352,7 @@
 			switch (val) {
 			case 0:
 				/* all attributes off */
-				video_set_default_colors(vid_priv);
+				video_set_default_colors(dev->parent, false);
 				break;
 			case 1:
 				/* bold */
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index 44dfa71..f307cf2 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -115,18 +115,29 @@
 	return 0;
 }
 
-void video_set_default_colors(struct video_priv *priv)
+void video_set_default_colors(struct udevice *dev, bool invert)
 {
+	struct video_priv *priv = dev_get_uclass_priv(dev);
+	int fore, back;
+
 #ifdef CONFIG_SYS_WHITE_ON_BLACK
 	/* White is used when switching to bold, use light gray here */
-	priv->fg_col_idx = VID_LIGHT_GRAY;
-	priv->colour_fg = vid_console_color(priv, VID_LIGHT_GRAY);
-	priv->colour_bg = vid_console_color(priv, VID_BLACK);
+	fore = VID_LIGHT_GRAY;
+	back = VID_BLACK;
 #else
-	priv->fg_col_idx = VID_BLACK;
-	priv->colour_fg = vid_console_color(priv, VID_BLACK);
-	priv->colour_bg = vid_console_color(priv, VID_WHITE);
+	fore = VID_BLACK;
+	back = VID_WHITE;
 #endif
+	if (invert) {
+		int temp;
+
+		temp = fore;
+		fore = back;
+		back = temp;
+	}
+	priv->fg_col_idx = fore;
+	priv->colour_fg = vid_console_color(priv, fore);
+	priv->colour_bg = vid_console_color(priv, back);
 }
 
 /* Flush video activity to the caches */
@@ -215,11 +226,13 @@
 
 	/* Set up the line and display size */
 	priv->fb = map_sysmem(plat->base, plat->size);
-	priv->line_length = priv->xsize * VNBYTES(priv->bpix);
+	if (!priv->line_length)
+		priv->line_length = priv->xsize * VNBYTES(priv->bpix);
+
 	priv->fb_size = priv->line_length * priv->ysize;
 
 	/* Set up colors  */
-	video_set_default_colors(priv);
+	video_set_default_colors(dev, false);
 
 	if (!CONFIG_IS_ENABLED(NO_FB_CLEAR))
 		video_clear(dev);
diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c
index 1377e19..2898b0b 100644
--- a/drivers/video/video_bmp.c
+++ b/drivers/video/video_bmp.c
@@ -7,6 +7,7 @@
 #include <bmp_layout.h>
 #include <dm.h>
 #include <mapmem.h>
+#include <splash.h>
 #include <video.h>
 #include <watchdog.h>
 #include <asm/unaligned.h>
@@ -140,8 +141,6 @@
 }
 #endif /* CONFIG_BMP_16BPP */
 
-#define BMP_ALIGN_CENTER	0x7fff
-
 /**
  * video_splash_align_axis() - Align a single coordinate
  *
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 4796da0..b6974ad 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -103,6 +103,14 @@
 	   Select this to enable Cadence watchdog timer, which can be found on some
 	   Xilinx Microzed Platform.
 
+config WDT_MTK
+	bool "MediaTek watchdog timer support"
+	depends on WDT && ARCH_MEDIATEK
+	help
+	  Select this to enable watchdog timer for MediaTek SoCs.
+	  The watchdog timer is stopped when initialized.
+	  It performs full SoC reset.
+
 config XILINX_TB_WATCHDOG
 	bool "Xilinx Axi watchdog timer support"
 	depends on WDT
@@ -136,4 +144,11 @@
 	   Select this to enable Ralink / Mediatek watchdog timer,
 	   which can be found on some MediaTek chips.
 
+config WDT_MPC8xx
+	bool "MPC8xx watchdog timer support"
+	depends on WDT && MPC8xx
+	select CONFIG_MPC8xx_WATCHDOG
+	help
+	   Select this to enable mpc8xx watchdog timer
+
 endmenu
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index b8f2842..74738ee 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -24,3 +24,4 @@
 obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
 obj-$(CONFIG_MPC8xx_WATCHDOG) += mpc8xx_wdt.o
 obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
+obj-$(CONFIG_WDT_MTK) += mtk_wdt.o
diff --git a/drivers/watchdog/mpc8xx_wdt.c b/drivers/watchdog/mpc8xx_wdt.c
index ccb06ac..c24c2a9 100644
--- a/drivers/watchdog/mpc8xx_wdt.c
+++ b/drivers/watchdog/mpc8xx_wdt.c
@@ -4,6 +4,8 @@
  */
 
 #include <common.h>
+#include <dm.h>
+#include <wdt.h>
 #include <mpc8xx.h>
 #include <asm/cpm_8xx.h>
 #include <asm/io.h>
@@ -16,3 +18,52 @@
 	out_be16(&immap->im_siu_conf.sc_swsr, 0xaa39);	/* write magic2 */
 }
 
+#ifdef CONFIG_WDT_MPC8xx
+static int mpc8xx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
+
+	out_be32(&immap->im_siu_conf.sc_sypcr, CONFIG_SYS_SYPCR);
+
+	if (!(in_be32(&immap->im_siu_conf.sc_sypcr) & SYPCR_SWE))
+		return -EBUSY;
+	return 0;
+
+}
+
+static int mpc8xx_wdt_stop(struct udevice *dev)
+{
+	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
+
+	out_be32(&immap->im_siu_conf.sc_sypcr, CONFIG_SYS_SYPCR & ~SYPCR_SWE);
+
+	if (in_be32(&immap->im_siu_conf.sc_sypcr) & SYPCR_SWE)
+		return -EBUSY;
+	return 0;
+}
+
+static int mpc8xx_wdt_reset(struct udevice *dev)
+{
+	hw_watchdog_reset();
+
+	return 0;
+}
+
+static const struct wdt_ops mpc8xx_wdt_ops = {
+	.start = mpc8xx_wdt_start,
+	.reset = mpc8xx_wdt_reset,
+	.stop = mpc8xx_wdt_stop,
+};
+
+static const struct udevice_id mpc8xx_wdt_ids[] = {
+	{ .compatible = "fsl,pq1-wdt" },
+	{}
+};
+
+U_BOOT_DRIVER(wdt_mpc8xx) = {
+	.name = "wdt_mpc8xx",
+	.id = UCLASS_WDT,
+	.of_match = mpc8xx_wdt_ids,
+	.ops = &mpc8xx_wdt_ops,
+};
+#endif /* CONFIG_WDT_MPC8xx */
diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
new file mode 100644
index 0000000..0b50173
--- /dev/null
+++ b/drivers/watchdog/mtk_wdt.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Watchdog driver for MediaTek SoCs
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <wdt.h>
+#include <asm/io.h>
+
+#define MTK_WDT_MODE			0x00
+#define MTK_WDT_LENGTH			0x04
+#define MTK_WDT_RESTART			0x08
+#define MTK_WDT_STATUS			0x0c
+#define MTK_WDT_INTERVAL		0x10
+#define MTK_WDT_SWRST			0x14
+#define MTK_WDT_REQ_MODE		0x30
+#define MTK_WDT_DEBUG_CTL		0x40
+
+#define WDT_MODE_KEY			(0x22 << 24)
+#define WDT_MODE_EN			BIT(0)
+#define WDT_MODE_EXTPOL			BIT(1)
+#define WDT_MODE_EXTEN			BIT(2)
+#define WDT_MODE_IRQ_EN			BIT(3)
+#define WDT_MODE_DUAL_EN		BIT(6)
+
+#define WDT_LENGTH_KEY			0x8
+#define WDT_LENGTH_TIMEOUT(n)		((n) << 5)
+
+#define WDT_RESTART_KEY			0x1971
+#define WDT_SWRST_KEY			0x1209
+
+struct mtk_wdt_priv {
+	void __iomem *base;
+};
+
+static int mtk_wdt_reset(struct udevice *dev)
+{
+	struct mtk_wdt_priv *priv = dev_get_priv(dev);
+
+	/* Reload watchdog duration */
+	writel(WDT_RESTART_KEY, priv->base + MTK_WDT_RESTART);
+
+	return 0;
+}
+
+static int mtk_wdt_stop(struct udevice *dev)
+{
+	struct mtk_wdt_priv *priv = dev_get_priv(dev);
+
+	clrsetbits_le32(priv->base + MTK_WDT_MODE, WDT_MODE_EN, WDT_MODE_KEY);
+
+	return 0;
+}
+
+static int mtk_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+	struct mtk_wdt_priv *priv = dev_get_priv(dev);
+
+	/* Kick watchdog to prevent counter == 0 */
+	writel(WDT_RESTART_KEY, priv->base + MTK_WDT_RESTART);
+
+	/* Reset */
+	writel(WDT_SWRST_KEY, priv->base + MTK_WDT_SWRST);
+	hang();
+
+	return 0;
+}
+
+static void mtk_wdt_set_timeout(struct udevice *dev, unsigned int timeout)
+{
+	struct mtk_wdt_priv *priv = dev_get_priv(dev);
+
+	/*
+	 * One bit is the value of 512 ticks
+	 * The clock has 32 KHz
+	 */
+	timeout = WDT_LENGTH_TIMEOUT(timeout << 6) | WDT_LENGTH_KEY;
+	writel(timeout, priv->base + MTK_WDT_LENGTH);
+
+	mtk_wdt_reset(dev);
+}
+
+static int mtk_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+	struct mtk_wdt_priv *priv = dev_get_priv(dev);
+
+	mtk_wdt_set_timeout(dev, timeout);
+
+	/* Enable watchdog reset signal */
+	setbits_le32(priv->base + MTK_WDT_MODE,
+		     WDT_MODE_EN | WDT_MODE_KEY | WDT_MODE_EXTEN);
+
+	return 0;
+}
+
+static int mtk_wdt_probe(struct udevice *dev)
+{
+	struct mtk_wdt_priv *priv = dev_get_priv(dev);
+
+	priv->base = dev_read_addr_ptr(dev);
+	if (!priv->base)
+		return -ENOENT;
+
+	/* Clear status */
+	clrsetbits_le32(priv->base + MTK_WDT_MODE,
+			WDT_MODE_IRQ_EN | WDT_MODE_EXTPOL, WDT_MODE_KEY);
+
+	return mtk_wdt_stop(dev);
+}
+
+static const struct wdt_ops mtk_wdt_ops = {
+	.start = mtk_wdt_start,
+	.reset = mtk_wdt_reset,
+	.stop = mtk_wdt_stop,
+	.expire_now = mtk_wdt_expire_now,
+};
+
+static const struct udevice_id mtk_wdt_ids[] = {
+	{ .compatible = "mediatek,wdt"},
+	{}
+};
+
+U_BOOT_DRIVER(mtk_wdt) = {
+	.name = "mtk_wdt",
+	.id = UCLASS_WDT,
+	.of_match = mtk_wdt_ids,
+	.priv_auto_alloc_size = sizeof(struct mtk_wdt_priv),
+	.probe = mtk_wdt_probe,
+	.ops = &mtk_wdt_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/dts/Makefile b/dts/Makefile
index 9a9a3d5..cd6e9a9 100644
--- a/dts/Makefile
+++ b/dts/Makefile
@@ -61,4 +61,4 @@
 clean-files := dt.dtb.S dt-spl.dtb.S
 
 # Let clean descend into dts directories
-subdir- += ../arch/arm/dts ../arch/microblaze/dts ../arch/mips/dts ../arch/sandbox/dts ../arch/x86/dts ../arch/powerpc/dts
+subdir- += ../arch/arm/dts ../arch/microblaze/dts ../arch/mips/dts ../arch/sandbox/dts ../arch/x86/dts ../arch/powerpc/dts ../arch/riscv/dts
diff --git a/fs/fs.c b/fs/fs.c
index adae98d..cb26517 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -365,6 +365,7 @@
 	for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes); i++, info++) {
 		if (!info->probe(fs_dev_desc, &fs_partition)) {
 			fs_type = info->fstype;
+			fs_dev_part = part;
 			return 0;
 		}
 	}
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index c83fc01..dffd6b2 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -122,6 +122,13 @@
 	struct list_head log_head;	/* List of struct log_device */
 	int log_fmt;			/* Mask containing log format info */
 #endif
+#if CONFIG_IS_ENABLED(BLOBLIST)
+	struct bloblist_hdr *bloblist;	/* Bloblist information */
+	struct bloblist_hdr *new_bloblist;	/* Relocated blolist info */
+# ifdef CONFIG_SPL
+	struct spl_handoff *spl_handoff;
+# endif
+#endif
 } gd_t;
 #endif
 
diff --git a/include/asm-generic/pe.h b/include/asm-generic/pe.h
index 9a8b5e8..faae534 100644
--- a/include/asm-generic/pe.h
+++ b/include/asm-generic/pe.h
@@ -11,6 +11,24 @@
 #ifndef _ASM_PE_H
 #define _ASM_PE_H
 
+/* Characteristics */
+#define IMAGE_FILE_RELOCS_STRIPPED		0x0001
+#define IMAGE_FILE_EXECUTABLE_IMAGE		0x0002
+#define IMAGE_FILE_LINE_NUMS_STRIPPED		0x0004
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED		0x0008
+#define IMAGE_FILE_AGGRESSIVE_WS_TRIM		0x0010
+#define IMAGE_FILE_LARGE_ADDRESS_AWARE		0x0020
+/* Reserved					0x0040 */
+#define IMAGE_FILE_BYTES_REVERSED_LO		0x0080
+#define IMAGE_FILE_32BIT_MACHINE		0x0100
+#define IMAGE_FILE_DEBUG_STRIPPED		0x0200
+#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP	0x0400
+#define IMAGE_FILE_NET_RUN_FROM_SWAP		0x0800
+#define IMAGE_FILE_SYSTEM			0x1000
+#define IMAGE_FILE_DLL				0x2000
+#define IMAGE_FILE_UP_SYSTEM_ONLY		0x4000
+#define IMAGE_FILE_BYTES_REVERSED_HI		0x8000
+
 /* Subsystem type */
 #define IMAGE_SUBSYSTEM_EFI_APPLICATION		10
 #define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER	11
diff --git a/include/bloblist.h b/include/bloblist.h
new file mode 100644
index 0000000..8514401
--- /dev/null
+++ b/include/bloblist.h
@@ -0,0 +1,195 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * This provides a standard way of passing information between boot phases
+ * (TPL -> SPL -> U-Boot proper.)
+ *
+ * A list of blobs of data, tagged with their owner. The list resides in memory
+ * and can be updated by SPL, U-Boot, etc.
+ *
+ * Copyright 2018 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#ifndef __BLOBLIST_H
+#define __BLOBLIST_H
+
+enum {
+	BLOBLIST_VERSION	= 0,
+	BLOBLIST_MAGIC		= 0xb00757a3,
+	BLOBLIST_ALIGN		= 16,
+};
+
+enum bloblist_tag_t {
+	BLOBLISTT_NONE = 0,
+
+	/* Vendor-specific tags are permitted here */
+	BLOBLISTT_EC_HOSTEVENT,		/* Chromium OS EC host-event mask */
+	BLOBLISTT_SPL_HANDOFF,		/* Hand-off info from SPL */
+	BLOBLISTT_VBOOT_CTX,		/* Chromium OS verified boot context */
+	BLOBLISTT_VBOOT_HANDOFF,	/* Chromium OS internal handoff info */
+};
+
+/**
+ * struct bloblist_hdr - header for the bloblist
+ *
+ * This is stored at the start of the bloblist which is always on a 16-byte
+ * boundary. Records follow this header. The bloblist normally stays in the
+ * same place in memory as SPL and U-Boot execute, but it can be safely moved
+ * around.
+ *
+ * None of the bloblist structures contain pointers but it is possible to put
+ * pointers inside a bloblist record if desired. This is not encouraged,
+ * since it can make part of the bloblist inaccessible if the pointer is
+ * no-longer valid. It is better to just store all the data inside a bloblist
+ * record.
+ *
+ * Each bloblist record is aligned to a 16-byte boundary and follows immediately
+ * from the last.
+ *
+ * @version: BLOBLIST_VERSION
+ * @hdr_size: Size of this header, normally sizeof(struct bloblist_hdr). The
+ *	first bloblist_rec starts at this offset from the start of the header
+ * @flags: Space for BLOBLISTF_... flags (none yet)
+ * @magic: BLOBLIST_MAGIC
+ * @size: Total size of all records (non-zero if valid) including this header.
+ *	The bloblist extends for this many bytes from the start of this header.
+ * @alloced: Total size allocated for this bloblist. When adding new records,
+ *	the bloblist can grow up to this size. This starts out as
+ *	sizeof(bloblist_hdr) since we need at least that much space to store a
+ *	valid bloblist
+ * @spare: Space space
+ * @chksum: CRC32 for the entire bloblist allocated area. Since any of the
+ *	blobs can be altered after being created, this checksum is only valid
+ *	when the bloblist is finalised before jumping to the next stage of boot.
+ *	Note: @chksum is last to make it easier to exclude it from the checksum
+ *	calculation.
+ */
+struct bloblist_hdr {
+	u32 version;
+	u32 hdr_size;
+	u32 flags;
+	u32 magic;
+
+	u32 size;
+	u32 alloced;
+	u32 spare;
+	u32 chksum;
+};
+
+/**
+ * struct bloblist_rec - record for the bloblist
+ *
+ * NOTE: Only exported for testing purposes. Do not use this struct.
+ *
+ * The bloblist contains a number of records each consisting of this record
+ * structure followed by the data contained. Each records is 16-byte aligned.
+ *
+ * @tag: Tag indicating what the record contains
+ * @hdr_size: Size of this header, normally sizeof(struct bloblist_rec). The
+ *	record's data starts at this offset from the start of the record
+ * @size: Size of record in bytes, excluding the header size. This does not
+ *	need to be aligned (e.g. 3 is OK).
+ * @spare: Spare space for other things
+ */
+struct bloblist_rec {
+	u32 tag;
+	u32 hdr_size;
+	u32 size;
+	u32 spare;
+};
+
+/**
+ * bloblist_find() - Find a blob
+ *
+ * Searches the bloblist and returns the blob with the matching tag
+ *
+ * @tag:	Tag to search for (enum bloblist_tag_t)
+ * @size:	Expected size of the blob
+ * @return pointer to blob if found, or NULL if not found, or a blob was found
+ *	but it is the wrong size
+ */
+void *bloblist_find(uint tag, int size);
+
+/**
+ * bloblist_add() - Add a new blob
+ *
+ * Add a new blob to the bloblist
+ *
+ * This should only be called if you konw there is no existing blob for a
+ * particular tag. It is typically safe to call in the first phase of U-Boot
+ * (e.g. TPL or SPL). After that, bloblist_ensure() should be used instead.
+ *
+ * @tag:	Tag to add (enum bloblist_tag_t)
+ * @size:	Size of the blob
+ * @return pointer to the newly added block, or NULL if there is not enough
+ *	space for the blob
+ */
+void *bloblist_add(uint tag, int size);
+
+/**
+ * bloblist_ensure_size() - Find or add a blob
+ *
+ * Find an existing blob, or add a new one if not found
+ *
+ * @tag:	Tag to add (enum bloblist_tag_t)
+ * @size:	Size of the blob
+ * @blobp:	Returns a pointer to blob on success
+ * @return 0 if OK, -ENOSPC if it is missing and could not be added due to lack
+ *	of space, or -ESPIPE it exists but has the wrong size
+ */
+int bloblist_ensure_size(uint tag, int size, void **blobp);
+
+/**
+ * bloblist_ensure() - Find or add a blob
+ *
+ * Find an existing blob, or add a new one if not found
+ *
+ * @tag:	Tag to add (enum bloblist_tag_t)
+ * @size:	Size of the blob
+ * @return pointer to blob, or NULL if it is missing and could not be added due
+ *	to lack of space, or it exists but has the wrong size
+ */
+void *bloblist_ensure(uint tag, int size);
+
+/**
+ * bloblist_new() - Create a new, empty bloblist of a given size
+ *
+ * @addr: Address of bloblist
+ * @size: Initial size for bloblist
+ * @flags: Flags to use for bloblist
+ * @return 0 if OK, -EFAULT if addr is not aligned correctly, -ENOSPC is the
+ *	area is not large enough
+ */
+int bloblist_new(ulong addr, uint size, uint flags);
+
+/**
+ * bloblist_check() - Check if a bloblist exists
+ *
+ * @addr: Address of bloblist
+ * @size: Expected size of blobsize, or 0 to detect the size
+ * @return 0 if OK, -ENOENT if the magic number doesn't match (indicating that
+ *	there problem is no bloblist at the given address), -EPROTONOSUPPORT
+ *	if the version does not match, -EIO if the checksum does not match,
+ *	-EFBIG if the expected size does not match the detected size
+ */
+int bloblist_check(ulong addr, uint size);
+
+/**
+ * bloblist_finish() - Set up the bloblist for the next U-Boot part
+ *
+ * This sets the correct checksum for the bloblist. This ensures that the
+ * bloblist will be detected correctly by the next phase of U-Boot.
+ *
+ * @return 0
+ */
+int bloblist_finish(void);
+
+/**
+ * bloblist_init() - Init the bloblist system with a single bloblist
+ *
+ * This uses CONFIG_BLOBLIST_ADDR and CONFIG_BLOBLIST_SIZE to set up a bloblist
+ * for use by U-Boot.
+ */
+int bloblist_init(void);
+
+#endif /* __BLOBLIST_H */
diff --git a/include/common.h b/include/common.h
index cfbdf7e..faf512e 100644
--- a/include/common.h
+++ b/include/common.h
@@ -106,6 +106,17 @@
 void board_show_dram(phys_size_t size);
 
 /**
+ * Get the uppermost pointer that is valid to access
+ *
+ * Some systems may not map all of their address space. This function allows
+ * boards to indicate what their highest support pointer value is for DRAM
+ * access.
+ *
+ * @param total_size	Size of U-Boot (unused?)
+ */
+ulong board_get_usable_ram_top(ulong total_size);
+
+/**
  * arch_fixup_fdt() - Write arch-specific information to fdt
  *
  * Defined in arch/$(ARCH)/lib/bootm-fdt.c
@@ -542,11 +553,6 @@
 #endif
 #endif
 
-#ifdef CONFIG_INIT_CRITICAL
-#error CONFIG_INIT_CRITICAL is deprecated!
-#error Read section CONFIG_SKIP_LOWLEVEL_INIT in README.
-#endif
-
 #define ROUND(a,b)		(((a) + (b) - 1) & ~((b) - 1))
 
 /*
diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
index 5838eb3..555efb7 100644
--- a/include/config_distro_bootcmd.h
+++ b/include/config_distro_bootcmd.h
@@ -99,9 +99,9 @@
 #define BOOTEFI_NAME "bootia32.efi"
 #elif defined(CONFIG_X86_RUN_64BIT)
 #define BOOTEFI_NAME "bootx64.efi"
-#elif defined(CONFIG_CPU_RISCV_32)
+#elif defined(CONFIG_ARCH_RV32I)
 #define BOOTEFI_NAME "bootriscv32.efi"
-#elif defined(CONFIG_CPU_RISCV_64)
+#elif defined(CONFIG_ARCH_RV64I)
 #define BOOTEFI_NAME "bootriscv64.efi"
 #endif
 #endif
@@ -242,6 +242,18 @@
 	BOOT_TARGET_DEVICES_references_USB_without_CONFIG_CMD_USB
 #endif
 
+#ifdef CONFIG_CMD_VIRTIO
+#define BOOTENV_SHARED_VIRTIO	BOOTENV_SHARED_BLKDEV(virtio)
+#define BOOTENV_DEV_VIRTIO	BOOTENV_DEV_BLKDEV
+#define BOOTENV_DEV_NAME_VIRTIO	BOOTENV_DEV_NAME_BLKDEV
+#else
+#define BOOTENV_SHARED_VIRTIO
+#define BOOTENV_DEV_VIRTIO \
+	BOOT_TARGET_DEVICES_references_VIRTIO_without_CONFIG_CMD_VIRTIO
+#define BOOTENV_DEV_NAME_VIRTIO \
+	BOOT_TARGET_DEVICES_references_VIRTIO_without_CONFIG_CMD_VIRTIO
+#endif
+
 #if defined(CONFIG_CMD_DHCP)
 #if defined(CONFIG_EFI_LOADER)
 /* http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xml */
@@ -257,10 +269,10 @@
 #elif defined(__i386__)
 #define BOOTENV_EFI_PXE_ARCH "0x6"
 #define BOOTENV_EFI_PXE_VCI "PXEClient:Arch:00006:UNDI:003000"
-#elif defined(CONFIG_CPU_RISCV_32) || ((defined(__riscv) && __riscv_xlen == 32))
+#elif defined(CONFIG_ARCH_RV32I) || ((defined(__riscv) && __riscv_xlen == 32))
 #define BOOTENV_EFI_PXE_ARCH "0x19"
 #define BOOTENV_EFI_PXE_VCI "PXEClient:Arch:00025:UNDI:003000"
-#elif defined(CONFIG_CPU_RISCV_64) || ((defined(__riscv) && __riscv_xlen == 64))
+#elif defined(CONFIG_ARCH_RV64I) || ((defined(__riscv) && __riscv_xlen == 64))
 #define BOOTENV_EFI_PXE_ARCH "0x1b"
 #define BOOTENV_EFI_PXE_VCI "PXEClient:Arch:00027:UNDI:003000"
 #elif defined(CONFIG_SANDBOX)
@@ -350,6 +362,7 @@
 	BOOTENV_SHARED_IDE \
 	BOOTENV_SHARED_UBIFS \
 	BOOTENV_SHARED_EFI \
+	BOOTENV_SHARED_VIRTIO \
 	"boot_prefixes=/ /boot/\0" \
 	"boot_scripts=boot.scr.uimg boot.scr\0" \
 	"boot_script_dhcp=boot.scr.uimg\0" \
diff --git a/include/configs/alt.h b/include/configs/alt.h
index cc6a7bf..3f7f379 100644
--- a/include/configs/alt.h
+++ b/include/configs/alt.h
@@ -39,8 +39,7 @@
 #define CONFIG_SYS_CLK_FREQ	RMOBILE_XTAL_CLK
 
 #define CONFIG_EXTRA_ENV_SETTINGS	\
-	"fdt_high=0xffffffff\0"		\
-	"initrd_high=0xffffffff\0"
+	"bootm_size=0x10000000\0"
 
 /* SPL support */
 #define CONFIG_SPL_TEXT_BASE		0xe6300000
diff --git a/include/configs/am65x_evm.h b/include/configs/am65x_evm.h
index 484c5ef..31749c6 100644
--- a/include/configs/am65x_evm.h
+++ b/include/configs/am65x_evm.h
@@ -29,7 +29,9 @@
 #define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME	"tispl.bin"
 #endif
 
+#ifndef CONFIG_CPU_V7R
 #define CONFIG_SKIP_LOWLEVEL_INIT
+#endif
 
 #define CONFIG_SPL_MAX_SIZE		CONFIG_SYS_K3_MAX_DOWNLODABLE_IMAGE_SIZE
 #define CONFIG_SYS_INIT_SP_ADDR         (CONFIG_SPL_TEXT_BASE +	\
diff --git a/include/configs/baltos.h b/include/configs/baltos.h
index 006b049..ccbdc0a 100644
--- a/include/configs/baltos.h
+++ b/include/configs/baltos.h
@@ -34,15 +34,8 @@
 /* FIT support */
 #define CONFIG_SYS_BOOTM_LEN         SZ_64M
 
-/* UBI Support */
-
-/* I2C configuration */
-
 #ifdef CONFIG_NAND
-#define CONFIG_SYS_NAND_U_BOOT_OFFS	0x00080000
-#ifdef CONFIG_SPL_OS_BOOT
-#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x00200000 /* kernel offset */
-#endif
+
 #define NANDARGS \
 	"mtdids=" CONFIG_MTDIDS_DEFAULT "\0" \
 	"mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0" \
@@ -264,10 +257,6 @@
 #define CONFIG_AM335X_USB1
 #define CONFIG_AM335X_USB1_MODE MUSB_OTG
 
-/* Network. */
-#define CONFIG_PHY_SMSC
-#define CONFIG_PHY_ATHEROS
-
 /* NAND support */
 #ifdef CONFIG_NAND
 #define GPMC_NAND_ECC_LP_x8_LAYOUT	1
diff --git a/include/configs/da850evm.h b/include/configs/da850evm.h
index ba878eb..14a3046 100644
--- a/include/configs/da850evm.h
+++ b/include/configs/da850evm.h
@@ -124,8 +124,9 @@
 #ifdef CONFIG_SPL_BUILD
 #define CONFIG_SYS_SPI_BASE		DAVINCI_SPI1_BASE
 #define CONFIG_SF_DEFAULT_SPEED		30000000
-#define CONFIG_ENV_SPI_MAX_HZ	CONFIG_SF_DEFAULT_SPEED
 #endif
+#define CONFIG_ENV_SPI_MAX_HZ	0
+#define CONFIG_ENV_SPI_MODE	0
 
 #ifdef CONFIG_USE_SPIFLASH
 #define CONFIG_SYS_SPI_U_BOOT_OFFS	0x8000
diff --git a/include/configs/edminiv2.h b/include/configs/edminiv2.h
index 89aa11c..645fc3f 100644
--- a/include/configs/edminiv2.h
+++ b/include/configs/edminiv2.h
@@ -29,7 +29,6 @@
  * High Level Configuration Options (easy to change)
  */
 
-#define CONFIG_MARVELL		1
 #define CONFIG_FEROCEON		1	/* CPU Core subversion */
 #define CONFIG_88F5182		1	/* SOC Name */
 
diff --git a/include/configs/emsdp.h b/include/configs/emsdp.h
index 385d59e..9a205ed 100644
--- a/include/configs/emsdp.h
+++ b/include/configs/emsdp.h
@@ -11,7 +11,7 @@
 #define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE
 
 #define CONFIG_SYS_SDRAM_BASE		0x10000000
-#define CONFIG_SYS_SDRAM_SIZE		SZ_8M
+#define CONFIG_SYS_SDRAM_SIZE		SZ_16M
 
 #define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_SDRAM_BASE + SZ_1M)
 
diff --git a/include/configs/evb_rv1108.h b/include/configs/evb_rv1108.h
index 34739c7..b742d98 100644
--- a/include/configs/evb_rv1108.h
+++ b/include/configs/evb_rv1108.h
@@ -11,11 +11,14 @@
 /*
  * Default environment settings
  */
+#undef CONFIG_EXTRA_ENV_SETTINGS
 #define CONFIG_EXTRA_ENV_SETTINGS                                       \
 	"netdev=eth0\0"                                                 \
 	"ipaddr=172.16.12.50\0"                                         \
 	"serverip=172.16.12.69\0"					\
 	""
+
+#undef CONFIG_BOOTCOMMAND
 #define CONFIG_BOOTCOMMAND						\
 	"sf probe;"							\
 	"sf read 0x62000000 0x140800 0x500000;"				\
diff --git a/include/configs/gose.h b/include/configs/gose.h
index 36ac88a..8f0e378 100644
--- a/include/configs/gose.h
+++ b/include/configs/gose.h
@@ -35,8 +35,7 @@
 #define CONFIG_SYS_CLK_FREQ	RMOBILE_XTAL_CLK
 
 #define CONFIG_EXTRA_ENV_SETTINGS	\
-	"fdt_high=0xffffffff\0"		\
-	"initrd_high=0xffffffff\0"
+	"bootm_size=0x10000000\0"
 
 /* SPL support */
 #define CONFIG_SPL_TEXT_BASE		0xe6300000
diff --git a/include/configs/khadas-vim.h b/include/configs/khadas-vim.h
deleted file mode 100644
index 6615f77..0000000
--- a/include/configs/khadas-vim.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for Khadas VIM
- *
- * Copyright (C) 2017 Baylibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-#define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxl-s905x-khadas-vim.dtb\0"
-
-#include <configs/meson-gx-common.h>
-
-#endif /* __CONFIG_H */
diff --git a/include/configs/khadas-vim2.h b/include/configs/khadas-vim2.h
deleted file mode 100644
index 7ef8f42..0000000
--- a/include/configs/khadas-vim2.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for Khadas VIM2
- *
- * Copyright (C) 2017 Baylibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-#define CONFIG_MISC_INIT_R
-
-#define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxm-khadas-vim2.dtb\0"
-
-#include <configs/meson-gx-common.h>
-
-#endif /* __CONFIG_H */
diff --git a/include/configs/km/km_arm.h b/include/configs/km/km_arm.h
index e258517..0de83f6 100644
--- a/include/configs/km/km_arm.h
+++ b/include/configs/km/km_arm.h
@@ -22,7 +22,6 @@
 /*
  * High Level Configuration Options (easy to change)
  */
-#define CONFIG_MARVELL
 #define CONFIG_FEROCEON_88FR131		/* CPU Core subversion */
 #define CONFIG_KW88F6281		/* SOC Name */
 
diff --git a/include/configs/koelsch.h b/include/configs/koelsch.h
index ef26a14..33c8bd4 100644
--- a/include/configs/koelsch.h
+++ b/include/configs/koelsch.h
@@ -35,8 +35,7 @@
 #define CONFIG_SYS_CLK_FREQ	RMOBILE_XTAL_CLK
 
 #define CONFIG_EXTRA_ENV_SETTINGS	\
-	"fdt_high=0xffffffff\0"		\
-	"initrd_high=0xffffffff\0"
+	"bootm_size=0x10000000\0"
 
 /* SPL support */
 #define CONFIG_SPL_TEXT_BASE		0xe6300000
diff --git a/include/configs/lager.h b/include/configs/lager.h
index 08498c6..89c5d01 100644
--- a/include/configs/lager.h
+++ b/include/configs/lager.h
@@ -36,8 +36,7 @@
 #define CONFIG_SYS_CLK_FREQ	RMOBILE_XTAL_CLK
 
 #define CONFIG_EXTRA_ENV_SETTINGS	\
-	"fdt_high=0xffffffff\0"		\
-	"initrd_high=0xffffffff\0"
+	"bootm_size=0x10000000\0"
 
 /* SPL support */
 #define CONFIG_SPL_TEXT_BASE		0xe6300000
diff --git a/include/configs/libretech-cc.h b/include/configs/libretech-cc.h
deleted file mode 100644
index a0856f9..0000000
--- a/include/configs/libretech-cc.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for LibreTech CC
- *
- * Copyright (C) 2017 Baylibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-#define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxl-s905x-libretech-cc.dtb\0"
-
-#include <configs/meson-gx-common.h>
-
-#endif /* __CONFIG_H */
diff --git a/include/configs/m53menlo.h b/include/configs/m53menlo.h
index 94214b1..3fca28d 100644
--- a/include/configs/m53menlo.h
+++ b/include/configs/m53menlo.h
@@ -110,7 +110,6 @@
  * RTC
  */
 #ifdef CONFIG_CMD_DATE
-#define CONFIG_RTC_M41T62
 #define CONFIG_SYS_I2C_RTC_ADDR		0x68
 #define CONFIG_SYS_M41T11_BASE_YEAR	2000
 #endif
diff --git a/include/configs/meson-gx-common.h b/include/configs/meson-gx-common.h
deleted file mode 100644
index c46522e..0000000
--- a/include/configs/meson-gx-common.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for Amlogic Meson GX SoCs
- * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
- */
-
-#ifndef __MESON_GX_COMMON_CONFIG_H
-#define __MESON_GX_COMMON_CONFIG_H
-
-#define CONFIG_CPU_ARMV8
-#define CONFIG_REMAKE_ELF
-#define CONFIG_ENV_SIZE			0x2000
-#define CONFIG_SYS_MAXARGS		32
-#define CONFIG_SYS_MALLOC_LEN		(32 << 20)
-#define CONFIG_SYS_CBSIZE		1024
-
-#define CONFIG_SYS_SDRAM_BASE		0
-#define CONFIG_SYS_INIT_SP_ADDR		0x20000000
-#define CONFIG_SYS_LOAD_ADDR		CONFIG_SYS_TEXT_BASE
-
-/* Generic Interrupt Controller Definitions */
-#define GICD_BASE			0xc4301000
-#define GICC_BASE			0xc4302000
-
-#ifdef CONFIG_CMD_USB
-#define BOOT_TARGET_DEVICES_USB(func) func(USB, usb, 0)
-#else
-#define BOOT_TARGET_DEVICES_USB(func)
-#endif
-
-#define BOOT_TARGET_DEVICES(func) \
-	func(MMC, mmc, 0) \
-	func(MMC, mmc, 1) \
-	func(MMC, mmc, 2) \
-	BOOT_TARGET_DEVICES_USB(func) \
-	func(PXE, pxe, na) \
-	func(DHCP, dhcp, na)
-
-#include <config_distro_bootcmd.h>
-
-#define CONFIG_EXTRA_ENV_SETTINGS \
-	"fdt_addr_r=0x01000000\0" \
-	"scriptaddr=0x1f000000\0" \
-	"kernel_addr_r=0x01080000\0" \
-	"pxefile_addr_r=0x01080000\0" \
-	"ramdisk_addr_r=0x13000000\0" \
-	MESON_FDTFILE_SETTING \
-	BOOTENV
-
-#define CONFIG_SYS_BOOTM_LEN    (64 << 20)      /* 64 MiB */
-
-#endif /* __MESON_GX_COMMON_CONFIG_H */
diff --git a/include/configs/meson64.h b/include/configs/meson64.h
new file mode 100644
index 0000000..40ac079
--- /dev/null
+++ b/include/configs/meson64.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Configuration for Amlogic Meson 64bits SoCs
+ * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
+ */
+
+#ifndef __MESON64_CONFIG_H
+#define __MESON64_CONFIG_H
+
+/* Generic Interrupt Controller Definitions */
+#if defined(CONFIG_MESON_AXG)
+#define GICD_BASE			0xffc01000
+#define GICC_BASE			0xffc02000
+#else /* MESON GXL and GXBB */
+#define GICD_BASE			0xc4301000
+#define GICC_BASE			0xc4302000
+#endif
+
+#define CONFIG_CPU_ARMV8
+#define CONFIG_REMAKE_ELF
+#define CONFIG_ENV_SIZE			0x2000
+#define CONFIG_SYS_MAXARGS		32
+#define CONFIG_SYS_MALLOC_LEN		(32 << 20)
+#define CONFIG_SYS_CBSIZE		1024
+
+#define CONFIG_SYS_SDRAM_BASE		0
+#define CONFIG_SYS_INIT_SP_ADDR		0x20000000
+#define CONFIG_SYS_LOAD_ADDR		CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_BOOTM_LEN		(64 << 20) /* 64 MiB */
+
+/* ROM USB boot support, auto-execute boot.scr at scriptaddr */
+#define BOOTENV_DEV_ROMUSB(devtypeu, devtypel, instance) \
+	"bootcmd_romusb=" \
+		"if test \"${boot_source}\" = \"usb\" && " \
+				"test -n \"${scriptaddr}\"; then " \
+			"echo '(ROM USB boot)'; " \
+			"source ${scriptaddr}; " \
+		"fi\0"
+
+#define BOOTENV_DEV_NAME_ROMUSB(devtypeu, devtypel, instance)	\
+		"romusb "
+
+#ifdef CONFIG_CMD_USB
+#define BOOT_TARGET_DEVICES_USB(func) func(USB, usb, 0)
+#else
+#define BOOT_TARGET_DEVICES_USB(func)
+#endif
+
+#ifndef BOOT_TARGET_DEVICES
+#define BOOT_TARGET_DEVICES(func) \
+	func(ROMUSB, romusb, na)  \
+	func(MMC, mmc, 0) \
+	func(MMC, mmc, 1) \
+	func(MMC, mmc, 2) \
+	BOOT_TARGET_DEVICES_USB(func) \
+	func(PXE, pxe, na) \
+	func(DHCP, dhcp, na)
+#endif
+
+#ifndef CONFIG_EXTRA_ENV_SETTINGS
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"fdt_addr_r=0x08008000\0" \
+	"scriptaddr=0x08000000\0" \
+	"kernel_addr_r=0x08080000\0" \
+	"pxefile_addr_r=0x01080000\0" \
+	"ramdisk_addr_r=0x13000000\0" \
+	"fdtfile=amlogic/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
+	BOOTENV
+#endif
+
+#include <config_distro_bootcmd.h>
+
+#endif /* __MESON64_CONFIG_H */
diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h
new file mode 100644
index 0000000..68da920
--- /dev/null
+++ b/include/configs/mt7623.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Configuration for MediaTek MT7623 SoC
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef __MT7623_H
+#define __MT7623_H
+
+#include <linux/sizes.h>
+
+/* Miscellaneous configurable options */
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+#define CONFIG_CMDLINE_TAG
+
+#define CONFIG_SYS_MAXARGS		8
+#define CONFIG_SYS_BOOTM_LEN		SZ_64M
+#define CONFIG_SYS_CBSIZE		SZ_1K
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE +	\
+					sizeof(CONFIG_SYS_PROMPT) + 16)
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN		SZ_4M
+
+/* Environment */
+#define CONFIG_ENV_SIZE			SZ_4K
+/* Allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+/* Preloader -> Uboot */
+#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_TEXT_BASE + SZ_2M - \
+					 GENERATED_GBL_DATA_SIZE)
+
+/* UBoot -> Kernel */
+#define CONFIG_LOADADDR			0x84000000
+#define CONFIG_SYS_LOAD_ADDR		CONFIG_LOADADDR
+
+/* MMC */
+#define MMC_SUPPORTS_TUNING
+#define CONFIG_SUPPORT_EMMC_BOOT
+
+/* DRAM */
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+
+/* This is neede for kernel booting */
+#define FDT_HIGH			"fdt_high=0xac000000\0"
+
+/* Extra environment variables */
+#define CONFIG_EXTRA_ENV_SETTINGS	\
+	FDT_HIGH
+
+#endif
diff --git a/include/configs/mt7629.h b/include/configs/mt7629.h
new file mode 100644
index 0000000..a665a5e
--- /dev/null
+++ b/include/configs/mt7629.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Configuration for MediaTek MT7629 SoC
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#ifndef __MT7629_H
+#define __MT7629_H
+
+#include <linux/sizes.h>
+
+/* Miscellaneous configurable options */
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+#define CONFIG_CMDLINE_TAG
+
+#define CONFIG_SYS_MAXARGS		8
+#define CONFIG_SYS_BOOTM_LEN		SZ_64M
+#define CONFIG_SYS_CBSIZE		SZ_1K
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE +	\
+					sizeof(CONFIG_SYS_PROMPT) + 16)
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN		SZ_4M
+
+/* Environment */
+#define CONFIG_ENV_SIZE			SZ_4K
+/* Allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+/* Defines for SPL */
+#define CONFIG_SPL_STACK		0x106000
+#define CONFIG_SPL_TEXT_BASE		0x201000
+#define CONFIG_SPL_MAX_SIZE		SZ_64K
+#define CONFIG_SPL_MAX_FOOTPRINT	SZ_64K
+#define CONFIG_SPL_PAD_TO		0x10000
+
+#define CONFIG_SPI_ADDR			0x30000000
+#define CONFIG_SYS_SPI_U_BOOT_OFFS	CONFIG_SPL_PAD_TO
+#define CONFIG_SYS_UBOOT_BASE		(CONFIG_SPI_ADDR + CONFIG_SPL_PAD_TO)
+
+/* SPL -> Uboot */
+#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_TEXT_BASE + SZ_2M - \
+					 GENERATED_GBL_DATA_SIZE)
+
+/* UBoot -> Kernel */
+#define CONFIG_SYS_SPL_ARGS_ADDR	0x40000000
+#define CONFIG_LOADADDR			0x42007f1c
+#define CONFIG_SYS_LOAD_ADDR		CONFIG_LOADADDR
+
+/* DRAM */
+#define CONFIG_SYS_SDRAM_BASE		0x40000000
+
+#endif
diff --git a/include/configs/mv-common.h b/include/configs/mv-common.h
index 5eeb5a1..a803093 100644
--- a/include/configs/mv-common.h
+++ b/include/configs/mv-common.h
@@ -19,7 +19,6 @@
 /*
  * High Level Configuration Options (easy to change)
  */
-#define CONFIG_MARVELL		1
 
 /*
  * Custom CONFIG_SYS_TEXT_BASE can be done in <board>.h
diff --git a/include/configs/nanopi-k2.h b/include/configs/nanopi-k2.h
deleted file mode 100644
index ef53f20..0000000
--- a/include/configs/nanopi-k2.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for NANOPI-K2
- * (C) Copyright 2018 Thomas McKahan
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-/* Serial setup */
-
-#define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxbb-nanopi-k2.dtb\0"
-
-#include <configs/meson-gx-common.h>
-
-#endif /* __CONFIG_H */
diff --git a/include/configs/odroid-c2.h b/include/configs/odroid-c2.h
deleted file mode 100644
index d117b18..0000000
--- a/include/configs/odroid-c2.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for ODROID-C2
- * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-/* Serial setup */
-
-#define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxbb-odroidc2.dtb\0"
-
-#include <configs/meson-gx-common.h>
-
-#endif /* __CONFIG_H */
diff --git a/include/configs/p212.h b/include/configs/p212.h
deleted file mode 100644
index 2aa9f5d..0000000
--- a/include/configs/p212.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for Amlogic P212
- *
- * Copyright (C) 2017 Baylibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-/* Serial setup */
-
-#define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxl-s905x-p212.dtb\0"
-
-#include <configs/meson-gx-common.h>
-
-#endif /* __CONFIG_H */
diff --git a/include/configs/pcm052.h b/include/configs/pcm052.h
index 9997795..e125a38 100644
--- a/include/configs/pcm052.h
+++ b/include/configs/pcm052.h
@@ -58,7 +58,6 @@
 #define CONFIG_SYS_I2C_MXC
 
 /* RTC (actually an RV-4162 but M41T62-compatible) */
-#define CONFIG_RTC_M41T62
 #define CONFIG_SYS_I2C_RTC_ADDR 0x68
 #define CONFIG_SYS_RTC_BUS_NUM 2
 
diff --git a/include/configs/porter.h b/include/configs/porter.h
index e56dc3f..9950f80 100644
--- a/include/configs/porter.h
+++ b/include/configs/porter.h
@@ -40,8 +40,7 @@
 #define CONFIG_SYS_CLK_FREQ	RMOBILE_XTAL_CLK
 
 #define CONFIG_EXTRA_ENV_SETTINGS	\
-	"fdt_high=0xffffffff\0"		\
-	"initrd_high=0xffffffff\0"
+	"bootm_size=0x10000000\0"
 
 /* SPL support */
 #define CONFIG_SPL_TEXT_BASE		0xe6300000
diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h
index d279c23..b29d155 100644
--- a/include/configs/qemu-riscv.h
+++ b/include/configs/qemu-riscv.h
@@ -15,7 +15,35 @@
 
 #define CONFIG_SYS_MALLOC_LEN		SZ_8M
 
+#define CONFIG_SYS_BOOTM_LEN		SZ_16M
+
 /* Environment options */
 #define CONFIG_ENV_SIZE			SZ_4K
 
+#define BOOT_TARGET_DEVICES(func) \
+	func(QEMU, qemu, na) \
+	func(VIRTIO, virtio, 0) \
+	func(DHCP, dhcp, na)
+
+#include <config_distro_bootcmd.h>
+
+#define BOOTENV_DEV_QEMU(devtypeu, devtypel, instance) \
+	"bootcmd_qemu=" \
+		"if env exists kernel_start; then " \
+			"bootm ${kernel_start} - ${fdtcontroladdr};" \
+		"fi;\0"
+
+#define BOOTENV_DEV_NAME_QEMU(devtypeu, devtypel, instance) \
+	"qemu "
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"fdt_high=0xffffffffffffffff\0" \
+	"initrd_high=0xffffffffffffffff\0" \
+	"kernel_addr_r=0x81000000\0" \
+	"fdt_addr_r=0x82000000\0" \
+	"scriptaddr=0x82100000\0" \
+	"pxefile_addr_r=0x82200000\0" \
+	"ramdisk_addr_r=0x82300000\0" \
+	BOOTENV
+
 #endif /* __CONFIG_H */
diff --git a/include/configs/rcar-gen3-common.h b/include/configs/rcar-gen3-common.h
index 435d108..6c2fa6a 100644
--- a/include/configs/rcar-gen3-common.h
+++ b/include/configs/rcar-gen3-common.h
@@ -59,8 +59,7 @@
 #define CONFIG_ENV_SIZE_REDUND	(CONFIG_ENV_SIZE)
 
 #define CONFIG_EXTRA_ENV_SETTINGS	\
-	"fdt_high=0xffffffffffffffff\0"	\
-	"initrd_high=0xffffffffffffffff\0"
+	"bootm_size=0x10000000\0"
 
 #define CONFIG_BOOTCOMMAND	\
 	"tftp 0x48080000 Image; " \
diff --git a/include/configs/rpi.h b/include/configs/rpi.h
index 37be6db..9ce4176 100644
--- a/include/configs/rpi.h
+++ b/include/configs/rpi.h
@@ -148,6 +148,7 @@
 
 #define BOOT_TARGET_DEVICES(func) \
 	func(MMC, mmc, 0) \
+	func(MMC, mmc, 1) \
 	func(USB, usb, 0) \
 	func(PXE, pxe, na) \
 	func(DHCP, dhcp, na)
diff --git a/include/configs/rv1108_common.h b/include/configs/rv1108_common.h
index 2ab3b85..16d4e2e 100644
--- a/include/configs/rv1108_common.h
+++ b/include/configs/rv1108_common.h
@@ -17,6 +17,9 @@
 #define CONFIG_SYS_TIMER_BASE		0x10350020
 #define CONFIG_SYS_TIMER_COUNTER	(CONFIG_SYS_TIMER_BASE + 8)
 
+/* MMC/SD IP block */
+#define CONFIG_BOUNCE_BUFFER
+
 #define CONFIG_SYS_SDRAM_BASE		0x60000000
 #define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_TEXT_BASE + 0x100000)
 #define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x2000000)
@@ -25,3 +28,18 @@
 #define CONFIG_USB_OHCI_NEW
 #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS	1
 #endif
+
+#ifndef CONFIG_SPL_BUILD
+#define ENV_MEM_LAYOUT_SETTINGS \
+	"scriptaddr=0x60000000\0" \
+	"fdt_addr_r=0x61f00000\0" \
+	"kernel_addr_r=0x62000000\0" \
+	"ramdisk_addr_r=0x64000000\0"
+
+#include <config_distro_bootcmd.h>
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	ENV_MEM_LAYOUT_SETTINGS \
+	"fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \
+	"partitions=" PARTS_DEFAULT \
+	BOOTENV
+#endif
diff --git a/include/configs/silk.h b/include/configs/silk.h
index a94928b..112806c 100644
--- a/include/configs/silk.h
+++ b/include/configs/silk.h
@@ -40,8 +40,7 @@
 #define CONFIG_SYS_CLK_FREQ	RMOBILE_XTAL_CLK
 
 #define CONFIG_EXTRA_ENV_SETTINGS	\
-	"fdt_high=0xffffffff\0"		\
-	"initrd_high=0xffffffff\0"
+	"bootm_size=0x10000000\0"
 
 /* SPL support */
 #define CONFIG_SPL_TEXT_BASE		0xe6300000
diff --git a/include/configs/stout.h b/include/configs/stout.h
index b72b565..93d9805 100644
--- a/include/configs/stout.h
+++ b/include/configs/stout.h
@@ -44,8 +44,7 @@
 #define CONFIG_SYS_CLK_FREQ	RMOBILE_XTAL_CLK
 
 #define CONFIG_EXTRA_ENV_SETTINGS	\
-	"fdt_high=0xffffffff\0"		\
-	"initrd_high=0xffffffff\0"
+	"bootm_size=0x10000000\0"
 
 /* SPL support */
 #define CONFIG_SPL_TEXT_BASE		0xe6300000
diff --git a/include/configs/vexpress_common.h b/include/configs/vexpress_common.h
index 267b230..47ea89d 100644
--- a/include/configs/vexpress_common.h
+++ b/include/configs/vexpress_common.h
@@ -120,7 +120,7 @@
 #define CONFIG_INITRD_TAG		1
 
 /* Size of malloc() pool */
-#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 128 * 1024)
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 512 * 1024) /* >= 512 KiB */
 
 #define SCTL_BASE			V2M_SYSCTL
 #define VEXPRESS_FLASHPROG_FLVPPEN	(1 << 0)
diff --git a/include/configs/x600.h b/include/configs/x600.h
index a6835eb..639da80 100644
--- a/include/configs/x600.h
+++ b/include/configs/x600.h
@@ -75,7 +75,6 @@
 #define CONFIG_SYS_I2C_SLAVE			0x02
 #define CONFIG_I2C_CHIPADDRESS			0x50
 
-#define CONFIG_RTC_M41T62	1
 #define CONFIG_SYS_I2C_RTC_ADDR	0x68
 
 /* FPGA config options */
diff --git a/include/configs/xilinx_zynqmp_mini.h b/include/configs/xilinx_zynqmp_mini.h
index 00ca3d4..7138851 100644
--- a/include/configs/xilinx_zynqmp_mini.h
+++ b/include/configs/xilinx_zynqmp_mini.h
@@ -12,9 +12,12 @@
 
 #define CONFIG_SYS_MEMTEST_SCRATCH     0xfffc0000
 
+#define CONFIG_EXTRA_ENV_SETTINGS
+
 #include <configs/xilinx_zynqmp.h>
 
 /* Undef unneeded configs */
+#undef CONFIG_BOOTCOMMAND
 #undef CONFIG_EXTRA_ENV_SETTINGS
 #undef CONFIG_SYS_MALLOC_LEN
 #undef CONFIG_ZLIB
diff --git a/include/configs/xilinx_zynqmp_zcu104_revC.h b/include/configs/xilinx_zynqmp_zcu104_revC.h
new file mode 100644
index 0000000..8b3ae36
--- /dev/null
+++ b/include/configs/xilinx_zynqmp_zcu104_revC.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Configuration for Xilinx ZynqMP zcu104
+ *
+ * (C) Copyright 2018 Xilinx, Inc.
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+#ifndef __CONFIG_ZYNQMP_ZCU104_REVC_H
+#define __CONFIG_ZYNQMP_ZCU104_REVC_H
+
+#include <configs/xilinx_zynqmp_zcu104.h>
+
+#define CONFIG_ZYNQ_GEM_EEPROM_ADDR 0x54
+#define CONFIG_ZYNQ_EEPROM_BUS 1
+
+#endif /* __CONFIG_ZYNQMP_ZCU104_REVC_H */
diff --git a/include/cros_ec.h b/include/cros_ec.h
index 4771e6b..f4b9b7a 100644
--- a/include/cros_ec.h
+++ b/include/cros_ec.h
@@ -187,6 +187,14 @@
 			  uint32_t set_flags,
 			  struct ec_response_flash_protect *resp);
 
+/**
+ * Notify EC of current boot mode
+ *
+ * @param dev		CROS-EC device
+ * @param vboot_mode    Verified boot mode
+ * @return 0 if ok, <0 on error
+ */
+int cros_ec_entering_mode(struct udevice *dev, int mode);
 
 /**
  * Run internal tests on the cros_ec interface.
@@ -397,4 +405,85 @@
 int cros_ec_i2c_tunnel(struct udevice *dev, int port, struct i2c_msg *msg,
 		       int nmsgs);
 
+/**
+ * cros_ec_get_events_b() - Get event mask B
+ *
+ * @return value of event mask, default value of 0 if it could not be read
+ */
+uint64_t cros_ec_get_events_b(struct udevice *dev);
+
+/**
+ * cros_ec_clear_events_b() - Clear even mask B
+ *
+ * Any pending events in the B range are cleared
+ *
+ * @return 0 if OK, -ve on error
+ */
+int cros_ec_clear_events_b(struct udevice *dev, uint64_t mask);
+
+/**
+ * cros_ec_efs_verify() - tell the EC to verify one of its images
+ *
+ * @param dev		CROS-EC device
+ * @param region	Flash region to query
+ * @return 0 if OK, -ve on error
+ */
+int cros_ec_efs_verify(struct udevice *dev, enum ec_flash_region region);
+
+/**
+ * cros_ec_battery_cutoff() - Request that the battery be cut off
+ *
+ * This tells the battery to stop supplying power. This is used before shipping
+ * a device to ensure that the battery remains charged while the device is
+ * shipped or sitting on the shelf waiting to be purchased.
+ *
+ * @param dev		CROS-EC device
+ * @param flags		Flags to use (EC_BATTERY_CUTOFF_FLAG_...)
+ * @return 0 if OK, -ve on error
+ */
+int cros_ec_battery_cutoff(struct udevice *dev, uint8_t flags);
+
+/**
+ * cros_ec_read_limit_power() - Check if power is limited by batter/charger
+ *
+ * Sometimes the battery is low and / or the device is connected to a charger
+ * that cannot supply much power.
+ *
+ * @param dev		CROS-EC device
+ * @param limit_powerp	Returns whether power is limited (0 or 1)
+ * @return 0 if OK, -ENOSYS if the EC does not support this comment, -EINVAL
+ *		if the EC returned an invalid response
+ */
+int cros_ec_read_limit_power(struct udevice *dev, int *limit_powerp);
+
+/**
+ * cros_ec_config_powerbtn() - Configure the behaviour of the power button
+ *
+ * @param dev		CROS-EC device
+ * @param flags		Flags to use (EC_POWER_BUTTON_...)
+ * @return 0 if OK, -ve on error
+ */
+int cros_ec_config_powerbtn(struct udevice *dev, uint32_t flags);
+
+/**
+ * cros_ec_get_lid_shutdown_mask() - Set the lid shutdown mask
+ *
+ * Determines whether a lid close event is reported
+ *
+ * @param dev		CROS-EC device
+ * @return shufdown mas if OK, -ve on error
+ */
+int cros_ec_get_lid_shutdown_mask(struct udevice *dev);
+
+/**
+ * cros_ec_set_lid_shutdown_mask() - Set the lid shutdown mask
+ *
+ * Set whether a lid close event is reported
+ *
+ * @param dev		CROS-EC device
+ * @param enable	true to enable reporting, false to disable
+ * @return shufdown mas if OK, -ve on error
+ */
+int cros_ec_set_lid_shutdown_mask(struct udevice *dev, int enable);
+
 #endif
diff --git a/include/dm/device.h b/include/dm/device.h
index 8479344..27a6d7b 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -525,6 +525,8 @@
  * This is used to locate an existing child of a device which is of a given
  * uclass.
  *
+ * The device is NOT probed
+ *
  * @parent:	Parent device to search
  * @uclass_id:	Uclass to look for
  * @devp:	Returns device found, if any
@@ -535,6 +537,29 @@
 				     struct udevice **devp);
 
 /**
+ * device_find_first_child_by_uclass() - Find the first child of a device in uc
+ *
+ * @parent: Parent device to search
+ * @uclass_id:	Uclass to look for
+ * @devp: Returns first child device in that uclass, if any
+ * @return 0 if found, else -ENODEV
+ */
+int device_find_first_child_by_uclass(struct udevice *parent,
+				      enum uclass_id uclass_id,
+				      struct udevice **devp);
+
+/**
+ * device_find_child_by_name() - Find a child by device name
+ *
+ * @parent:	Parent device to search
+ * @name:	Name to look for
+ * @devp:	Returns device found, if any
+ * @return 0 if found, else -ENODEV
+ */
+int device_find_child_by_name(struct udevice *parent, const char *name,
+			      struct udevice **devp);
+
+/**
  * device_has_children() - check if a device has any children
  *
  * @dev:	Device to check
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index 2fc9fa3..d206ee2 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -237,6 +237,16 @@
 int ofnode_read_s32_default(ofnode node, const char *propname, s32 def);
 
 /**
+ * ofnode_read_u64() - Read a 64-bit integer from a property
+ *
+ * @node:	valid node reference to read property from
+ * @propname:	name of the property to read from
+ * @outp:	place to put value (if found)
+ * @return 0 if OK, -ve on error
+ */
+int ofnode_read_u64(ofnode node, const char *propname, u64 *outp);
+
+/**
  * ofnode_read_u64_default() - Read a 64-bit integer from a property
  *
  * @ref:	valid node reference to read property from
@@ -323,7 +333,7 @@
  * ofnode_get_name() - get the name of a node
  *
  * @node: valid node to look up
- * @return name or node
+ * @return name of node
  */
 const char *ofnode_get_name(ofnode node);
 
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index c91dca1..a5fcb69 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -21,10 +21,10 @@
 	UCLASS_TEST_DUMMY,
 	UCLASS_SPI_EMUL,	/* sandbox SPI device emulator */
 	UCLASS_I2C_EMUL,	/* sandbox I2C device emulator */
+	UCLASS_I2C_EMUL_PARENT,	/* parent for I2C device emulators */
 	UCLASS_PCI_EMUL,	/* sandbox PCI device emulator */
 	UCLASS_USB_EMUL,	/* sandbox USB bus device emulator */
 	UCLASS_AXI_EMUL,	/* sandbox AXI bus device emulator */
-	UCLASS_SIMPLE_BUS,	/* bus with child devices */
 
 	/* U-Boot uclasses start here - in alphabetical order */
 	UCLASS_ADC,		/* Analog-to-digital converter */
@@ -78,6 +78,7 @@
 	UCLASS_RTC,		/* Real time clock device */
 	UCLASS_SCSI,		/* SCSI device */
 	UCLASS_SERIAL,		/* Serial UART */
+	UCLASS_SIMPLE_BUS,	/* Bus with child devices */
 	UCLASS_SMEM,		/* Shared memory interface */
 	UCLASS_SPI,		/* SPI bus */
 	UCLASS_SPMI,		/* System Power Management Interface bus */
diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h
index 30d5a4f..8a4839e 100644
--- a/include/dm/uclass-internal.h
+++ b/include/dm/uclass-internal.h
@@ -143,6 +143,23 @@
 				 struct udevice **devp);
 
 /**
+ * uclass_find_device_by_phandle() - Find a uclass device by phandle
+ *
+ * This searches the devices in the uclass for one with the given phandle.
+ *
+ * The device is NOT probed, it is merely returned.
+ *
+ * @id: ID to look up
+ * @parent: Parent device containing the phandle pointer
+ * @name: Name of property in the parent device node
+ * @devp: Returns pointer to device (there is only one for each node)
+ * @return 0 if OK, -ENOENT if there is no @name present in the node, other
+ *	-ve on error
+ */
+int uclass_find_device_by_phandle(enum uclass_id id, struct udevice *parent,
+				  const char *name, struct udevice **devp);
+
+/**
  * uclass_bind_device() - Associate device with a uclass
  *
  * Connect the device into uclass's list of devices.
diff --git a/include/dt-bindings/clock/axg-aoclkc.h b/include/dt-bindings/clock/axg-aoclkc.h
new file mode 100644
index 0000000..6195501
--- /dev/null
+++ b/include/dt-bindings/clock/axg-aoclkc.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/*
+ * Copyright (c) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Copyright (c) 2018 Amlogic, inc.
+ * Author: Qiufang Dai <qiufang.dai@amlogic.com>
+ */
+
+#ifndef DT_BINDINGS_CLOCK_AMLOGIC_MESON_AXG_AOCLK
+#define DT_BINDINGS_CLOCK_AMLOGIC_MESON_AXG_AOCLK
+
+#define CLKID_AO_REMOTE		0
+#define CLKID_AO_I2C_MASTER	1
+#define CLKID_AO_I2C_SLAVE	2
+#define CLKID_AO_UART1		3
+#define CLKID_AO_UART2		4
+#define CLKID_AO_IR_BLASTER	5
+#define CLKID_AO_SAR_ADC	6
+#define CLKID_AO_CLK81		7
+#define CLKID_AO_SAR_ADC_SEL	8
+#define CLKID_AO_SAR_ADC_DIV	9
+#define CLKID_AO_SAR_ADC_CLK	10
+#define CLKID_AO_ALT_XTAL	11
+
+#endif
diff --git a/include/dt-bindings/clock/axg-audio-clkc.h b/include/dt-bindings/clock/axg-audio-clkc.h
new file mode 100644
index 0000000..fd9c362
--- /dev/null
+++ b/include/dt-bindings/clock/axg-audio-clkc.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Copyright (c) 2018 Baylibre SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+#ifndef __AXG_AUDIO_CLKC_BINDINGS_H
+#define __AXG_AUDIO_CLKC_BINDINGS_H
+
+#define AUD_CLKID_SLV_SCLK0		9
+#define AUD_CLKID_SLV_SCLK1		10
+#define AUD_CLKID_SLV_SCLK2		11
+#define AUD_CLKID_SLV_SCLK3		12
+#define AUD_CLKID_SLV_SCLK4		13
+#define AUD_CLKID_SLV_SCLK5		14
+#define AUD_CLKID_SLV_SCLK6		15
+#define AUD_CLKID_SLV_SCLK7		16
+#define AUD_CLKID_SLV_SCLK8		17
+#define AUD_CLKID_SLV_SCLK9		18
+#define AUD_CLKID_SLV_LRCLK0		19
+#define AUD_CLKID_SLV_LRCLK1		20
+#define AUD_CLKID_SLV_LRCLK2		21
+#define AUD_CLKID_SLV_LRCLK3		22
+#define AUD_CLKID_SLV_LRCLK4		23
+#define AUD_CLKID_SLV_LRCLK5		24
+#define AUD_CLKID_SLV_LRCLK6		25
+#define AUD_CLKID_SLV_LRCLK7		26
+#define AUD_CLKID_SLV_LRCLK8		27
+#define AUD_CLKID_SLV_LRCLK9		28
+#define AUD_CLKID_DDR_ARB		29
+#define AUD_CLKID_PDM			30
+#define AUD_CLKID_TDMIN_A		31
+#define AUD_CLKID_TDMIN_B		32
+#define AUD_CLKID_TDMIN_C		33
+#define AUD_CLKID_TDMIN_LB		34
+#define AUD_CLKID_TDMOUT_A		35
+#define AUD_CLKID_TDMOUT_B		36
+#define AUD_CLKID_TDMOUT_C		37
+#define AUD_CLKID_FRDDR_A		38
+#define AUD_CLKID_FRDDR_B		39
+#define AUD_CLKID_FRDDR_C		40
+#define AUD_CLKID_TODDR_A		41
+#define AUD_CLKID_TODDR_B		42
+#define AUD_CLKID_TODDR_C		43
+#define AUD_CLKID_LOOPBACK		44
+#define AUD_CLKID_SPDIFIN		45
+#define AUD_CLKID_SPDIFOUT		46
+#define AUD_CLKID_RESAMPLE		47
+#define AUD_CLKID_POWER_DETECT		48
+#define AUD_CLKID_MST_A_MCLK		49
+#define AUD_CLKID_MST_B_MCLK		50
+#define AUD_CLKID_MST_C_MCLK		51
+#define AUD_CLKID_MST_D_MCLK		52
+#define AUD_CLKID_MST_E_MCLK		53
+#define AUD_CLKID_MST_F_MCLK		54
+#define AUD_CLKID_SPDIFOUT_CLK		55
+#define AUD_CLKID_SPDIFIN_CLK		56
+#define AUD_CLKID_PDM_DCLK		57
+#define AUD_CLKID_PDM_SYSCLK		58
+#define AUD_CLKID_MST_A_SCLK		79
+#define AUD_CLKID_MST_B_SCLK		80
+#define AUD_CLKID_MST_C_SCLK		81
+#define AUD_CLKID_MST_D_SCLK		82
+#define AUD_CLKID_MST_E_SCLK		83
+#define AUD_CLKID_MST_F_SCLK		84
+#define AUD_CLKID_MST_A_LRCLK		86
+#define AUD_CLKID_MST_B_LRCLK		87
+#define AUD_CLKID_MST_C_LRCLK		88
+#define AUD_CLKID_MST_D_LRCLK		89
+#define AUD_CLKID_MST_E_LRCLK		90
+#define AUD_CLKID_MST_F_LRCLK		91
+#define AUD_CLKID_TDMIN_A_SCLK_SEL	116
+#define AUD_CLKID_TDMIN_B_SCLK_SEL	117
+#define AUD_CLKID_TDMIN_C_SCLK_SEL	118
+#define AUD_CLKID_TDMIN_LB_SCLK_SEL	119
+#define AUD_CLKID_TDMOUT_A_SCLK_SEL	120
+#define AUD_CLKID_TDMOUT_B_SCLK_SEL	121
+#define AUD_CLKID_TDMOUT_C_SCLK_SEL	122
+#define AUD_CLKID_TDMIN_A_SCLK		123
+#define AUD_CLKID_TDMIN_B_SCLK		124
+#define AUD_CLKID_TDMIN_C_SCLK		125
+#define AUD_CLKID_TDMIN_LB_SCLK		126
+#define AUD_CLKID_TDMOUT_A_SCLK		127
+#define AUD_CLKID_TDMOUT_B_SCLK		128
+#define AUD_CLKID_TDMOUT_C_SCLK		129
+#define AUD_CLKID_TDMIN_A_LRCLK		130
+#define AUD_CLKID_TDMIN_B_LRCLK		131
+#define AUD_CLKID_TDMIN_C_LRCLK		132
+#define AUD_CLKID_TDMIN_LB_LRCLK	133
+#define AUD_CLKID_TDMOUT_A_LRCLK	134
+#define AUD_CLKID_TDMOUT_B_LRCLK	135
+#define AUD_CLKID_TDMOUT_C_LRCLK	136
+
+#endif /* __AXG_AUDIO_CLKC_BINDINGS_H */
diff --git a/include/dt-bindings/clock/axg-clkc.h b/include/dt-bindings/clock/axg-clkc.h
new file mode 100644
index 0000000..fd1f938
--- /dev/null
+++ b/include/dt-bindings/clock/axg-clkc.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Meson-AXG clock tree IDs
+ *
+ * Copyright (c) 2017 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __AXG_CLKC_H
+#define __AXG_CLKC_H
+
+#define CLKID_SYS_PLL				0
+#define CLKID_FIXED_PLL				1
+#define CLKID_FCLK_DIV2				2
+#define CLKID_FCLK_DIV3				3
+#define CLKID_FCLK_DIV4				4
+#define CLKID_FCLK_DIV5				5
+#define CLKID_FCLK_DIV7				6
+#define CLKID_GP0_PLL				7
+#define CLKID_CLK81				10
+#define CLKID_MPLL0				11
+#define CLKID_MPLL1				12
+#define CLKID_MPLL2				13
+#define CLKID_MPLL3				14
+#define CLKID_DDR				15
+#define CLKID_AUDIO_LOCKER			16
+#define CLKID_MIPI_DSI_HOST			17
+#define CLKID_ISA				18
+#define CLKID_PL301				19
+#define CLKID_PERIPHS				20
+#define CLKID_SPICC0				21
+#define CLKID_I2C				22
+#define CLKID_RNG0				23
+#define CLKID_UART0				24
+#define CLKID_MIPI_DSI_PHY			25
+#define CLKID_SPICC1				26
+#define CLKID_PCIE_A				27
+#define CLKID_PCIE_B				28
+#define CLKID_HIU_IFACE				29
+#define CLKID_ASSIST_MISC			30
+#define CLKID_SD_EMMC_B				31
+#define CLKID_SD_EMMC_C				32
+#define CLKID_DMA				33
+#define CLKID_SPI				34
+#define CLKID_AUDIO				35
+#define CLKID_ETH				36
+#define CLKID_UART1				37
+#define CLKID_G2D				38
+#define CLKID_USB0				39
+#define CLKID_USB1				40
+#define CLKID_RESET				41
+#define CLKID_USB				42
+#define CLKID_AHB_ARB0				43
+#define CLKID_EFUSE				44
+#define CLKID_BOOT_ROM				45
+#define CLKID_AHB_DATA_BUS			46
+#define CLKID_AHB_CTRL_BUS			47
+#define CLKID_USB1_DDR_BRIDGE			48
+#define CLKID_USB0_DDR_BRIDGE			49
+#define CLKID_MMC_PCLK				50
+#define CLKID_VPU_INTR				51
+#define CLKID_SEC_AHB_AHB3_BRIDGE		52
+#define CLKID_GIC				53
+#define CLKID_AO_MEDIA_CPU			54
+#define CLKID_AO_AHB_SRAM			55
+#define CLKID_AO_AHB_BUS			56
+#define CLKID_AO_IFACE				57
+#define CLKID_AO_I2C				58
+#define CLKID_SD_EMMC_B_CLK0			59
+#define CLKID_SD_EMMC_C_CLK0			60
+#define CLKID_HIFI_PLL				69
+#define CLKID_PCIE_CML_EN0			79
+#define CLKID_PCIE_CML_EN1			80
+#define CLKID_MIPI_ENABLE			81
+#define CLKID_GEN_CLK				84
+
+#endif /* __AXG_CLKC_H */
diff --git a/include/dt-bindings/clock/mt7623-clk.h b/include/dt-bindings/clock/mt7623-clk.h
new file mode 100644
index 0000000..71ced15
--- /dev/null
+++ b/include/dt-bindings/clock/mt7623-clk.h
@@ -0,0 +1,413 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT2701_H
+#define _DT_BINDINGS_CLK_MT2701_H
+
+/* TOPCKGEN */
+#define CLK_TOP_FCLKS_OFF			0
+
+#define CLK_TOP_DPI				0
+#define CLK_TOP_DMPLL				1
+#define CLK_TOP_VENCPLL				2
+#define CLK_TOP_HDMI_0_PIX340M			3
+#define CLK_TOP_HDMI_0_DEEP340M			4
+#define CLK_TOP_HDMI_0_PLL340M			5
+#define CLK_TOP_HADDS2_FB			6
+#define CLK_TOP_WBG_DIG_416M			7
+#define CLK_TOP_DSI0_LNTC_DSI			8
+#define CLK_TOP_HDMI_SCL_RX			9
+#define CLK_TOP_32K_EXTERNAL			10
+#define CLK_TOP_HDMITX_CLKDIG_CTS		11
+#define CLK_TOP_AUD_EXT1			12
+#define CLK_TOP_AUD_EXT2			13
+#define CLK_TOP_NFI1X_PAD			14
+
+#define CLK_TOP_SYSPLL				15
+#define CLK_TOP_SYSPLL_D2			16
+#define CLK_TOP_SYSPLL_D3			17
+#define CLK_TOP_SYSPLL_D5			18
+#define CLK_TOP_SYSPLL_D7			19
+#define CLK_TOP_SYSPLL1_D2			20
+#define CLK_TOP_SYSPLL1_D4			21
+#define CLK_TOP_SYSPLL1_D8			22
+#define CLK_TOP_SYSPLL1_D16			23
+#define CLK_TOP_SYSPLL2_D2			24
+#define CLK_TOP_SYSPLL2_D4			25
+#define CLK_TOP_SYSPLL2_D8			26
+#define CLK_TOP_SYSPLL3_D2			27
+#define CLK_TOP_SYSPLL3_D4			28
+#define CLK_TOP_SYSPLL4_D2			29
+#define CLK_TOP_SYSPLL4_D4			30
+#define CLK_TOP_UNIVPLL				31
+#define CLK_TOP_UNIVPLL_D2			32
+#define CLK_TOP_UNIVPLL_D3			33
+#define CLK_TOP_UNIVPLL_D5			34
+#define CLK_TOP_UNIVPLL_D7			35
+#define CLK_TOP_UNIVPLL_D26			36
+#define CLK_TOP_UNIVPLL_D52			37
+#define CLK_TOP_UNIVPLL_D108			38
+#define CLK_TOP_USB_PHY48M			39
+#define CLK_TOP_UNIVPLL1_D2			40
+#define CLK_TOP_UNIVPLL1_D4			41
+#define CLK_TOP_UNIVPLL1_D8			42
+#define CLK_TOP_UNIVPLL2_D2			43
+#define CLK_TOP_UNIVPLL2_D4			44
+#define CLK_TOP_UNIVPLL2_D8			45
+#define CLK_TOP_UNIVPLL2_D16			46
+#define CLK_TOP_UNIVPLL2_D32			47
+#define CLK_TOP_UNIVPLL3_D2			48
+#define CLK_TOP_UNIVPLL3_D4			49
+#define CLK_TOP_UNIVPLL3_D8			50
+#define CLK_TOP_MSDCPLL				51
+#define CLK_TOP_MSDCPLL_D2			52
+#define CLK_TOP_MSDCPLL_D4			53
+#define CLK_TOP_MSDCPLL_D8			54
+#define CLK_TOP_MMPLL				55
+#define CLK_TOP_MMPLL_D2			56
+#define CLK_TOP_DMPLL_D2			57
+#define CLK_TOP_DMPLL_D4			58
+#define CLK_TOP_DMPLL_X2			59
+#define CLK_TOP_TVDPLL				60
+#define CLK_TOP_TVDPLL_D2			61
+#define CLK_TOP_TVDPLL_D4			62
+#define CLK_TOP_VDECPLL				63
+#define CLK_TOP_TVD2PLL				64
+#define CLK_TOP_TVD2PLL_D2			65
+#define CLK_TOP_MIPIPLL				66
+#define CLK_TOP_MIPIPLL_D2			67
+#define CLK_TOP_MIPIPLL_D4			68
+#define CLK_TOP_HDMIPLL				69
+#define CLK_TOP_HDMIPLL_D2			70
+#define CLK_TOP_HDMIPLL_D3			71
+#define CLK_TOP_ARMPLL_1P3G			72
+#define CLK_TOP_AUDPLL				73
+#define CLK_TOP_AUDPLL_D4			74
+#define CLK_TOP_AUDPLL_D8			75
+#define CLK_TOP_AUDPLL_D16			76
+#define CLK_TOP_AUDPLL_D24			77
+#define CLK_TOP_AUD1PLL_98M			78
+#define CLK_TOP_AUD2PLL_90M			79
+#define CLK_TOP_HADDS2PLL_98M			80
+#define CLK_TOP_HADDS2PLL_294M			81
+#define CLK_TOP_ETHPLL_500M			82
+#define CLK_TOP_CLK26M_D8			83
+#define CLK_TOP_32K_INTERNAL			84
+#define CLK_TOP_AXISEL_D4			85
+#define CLK_TOP_8BDAC				86
+
+#define CLK_TOP_AXI_SEL				87
+#define CLK_TOP_MEM_SEL				88
+#define CLK_TOP_DDRPHYCFG_SEL			89
+#define CLK_TOP_MM_SEL				90
+#define CLK_TOP_PWM_SEL				91
+#define CLK_TOP_VDEC_SEL			92
+#define CLK_TOP_MFG_SEL				93
+#define CLK_TOP_CAMTG_SEL			94
+#define CLK_TOP_UART_SEL			95
+#define CLK_TOP_SPI0_SEL			96
+#define CLK_TOP_USB20_SEL			97
+#define CLK_TOP_MSDC30_0_SEL			98
+#define CLK_TOP_MSDC30_1_SEL			99
+#define CLK_TOP_MSDC30_2_SEL			100
+#define CLK_TOP_AUDIO_SEL			101
+#define CLK_TOP_AUDINTBUS_SEL			102
+#define CLK_TOP_PMICSPI_SEL			103
+#define CLK_TOP_SCP_SEL				104
+#define CLK_TOP_DPI0_SEL			105
+#define CLK_TOP_DPI1_SEL			106
+#define CLK_TOP_TVE_SEL				107
+#define CLK_TOP_HDMI_SEL			108
+#define CLK_TOP_APLL_SEL			109
+#define CLK_TOP_RTC_SEL				110
+#define CLK_TOP_NFI2X_SEL			111
+#define CLK_TOP_EMMC_HCLK_SEL			112
+#define CLK_TOP_FLASH_SEL			113
+#define CLK_TOP_DI_SEL				114
+#define CLK_TOP_NR_SEL				115
+#define CLK_TOP_OSD_SEL				116
+#define CLK_TOP_HDMIRX_BIST_SEL			117
+#define CLK_TOP_INTDIR_SEL			118
+#define CLK_TOP_ASM_I_SEL			119
+#define CLK_TOP_ASM_M_SEL			120
+#define CLK_TOP_ASM_H_SEL			121
+#define CLK_TOP_MS_CARD_SEL			122
+#define CLK_TOP_ETHIF_SEL			123
+#define CLK_TOP_HDMIRX26_24_SEL			124
+#define CLK_TOP_MSDC30_3_SEL			125
+#define CLK_TOP_CMSYS_SEL			126
+#define CLK_TOP_SPI1_SEL			127
+#define CLK_TOP_SPI2_SEL			128
+#define CLK_TOP_8BDAC_SEL			129
+#define CLK_TOP_AUD2DVD_SEL			130
+#define CLK_TOP_PADMCLK_SEL			131
+#define CLK_TOP_AUD_MUX1_SEL			132
+#define CLK_TOP_AUD_MUX2_SEL			133
+#define CLK_TOP_AUDPLL_MUX_SEL			134
+#define CLK_TOP_AUD_K1_SRC_SEL			135
+#define CLK_TOP_AUD_K2_SRC_SEL			136
+#define CLK_TOP_AUD_K3_SRC_SEL			137
+#define CLK_TOP_AUD_K4_SRC_SEL			138
+#define CLK_TOP_AUD_K5_SRC_SEL			139
+#define CLK_TOP_AUD_K6_SRC_SEL			140
+
+#define CLK_TOP_AUD_EXTCK1_DIV			141
+#define CLK_TOP_AUD_EXTCK2_DIV			142
+#define CLK_TOP_AUD_MUX1_DIV			143
+#define CLK_TOP_AUD_MUX2_DIV			144
+#define CLK_TOP_AUD_K1_SRC_DIV			145
+#define CLK_TOP_AUD_K2_SRC_DIV			146
+#define CLK_TOP_AUD_K3_SRC_DIV			147
+#define CLK_TOP_AUD_K4_SRC_DIV			148
+#define CLK_TOP_AUD_K5_SRC_DIV			149
+#define CLK_TOP_AUD_K6_SRC_DIV			150
+#define CLK_TOP_AUD_48K_TIMING			151
+#define CLK_TOP_AUD_44K_TIMING			152
+#define CLK_TOP_AUD_I2S1_MCLK			153
+#define CLK_TOP_AUD_I2S2_MCLK			154
+#define CLK_TOP_AUD_I2S3_MCLK			155
+#define CLK_TOP_AUD_I2S4_MCLK			156
+#define CLK_TOP_AUD_I2S5_MCLK			157
+#define CLK_TOP_AUD_I2S6_MCLK			158
+#define CLK_TOP_NR				159
+
+/* APMIXEDSYS */
+#define CLK_APMIXED_ARMPLL			0
+#define CLK_APMIXED_MAINPLL			1
+#define CLK_APMIXED_UNIVPLL			2
+#define CLK_APMIXED_MMPLL			3
+#define CLK_APMIXED_MSDCPLL			4
+#define CLK_APMIXED_TVDPLL			5
+#define CLK_APMIXED_AUD1PLL			6
+#define CLK_APMIXED_TRGPLL			7
+#define CLK_APMIXED_ETHPLL			8
+#define CLK_APMIXED_VDECPLL			9
+#define CLK_APMIXED_HADDS2PLL			10
+#define CLK_APMIXED_AUD2PLL			11
+#define CLK_APMIXED_TVD2PLL			12
+#define CLK_APMIXED_NR				13
+
+/* INFRACFG */
+#define CLK_INFRA_DBG				0
+#define CLK_INFRA_SMI				1
+#define CLK_INFRA_QAXI_CM4			2
+#define CLK_INFRA_AUD_SPLIN_B			3
+#define CLK_INFRA_AUDIO				4
+#define CLK_INFRA_EFUSE				5
+#define CLK_INFRA_L2C_SRAM			6
+#define CLK_INFRA_M4U				7
+#define CLK_INFRA_CONNMCU			8
+#define CLK_INFRA_TRNG				9
+#define CLK_INFRA_RAMBUFIF			10
+#define CLK_INFRA_CPUM				11
+#define CLK_INFRA_KP				12
+#define CLK_INFRA_CEC				13
+#define CLK_INFRA_IRRX				14
+#define CLK_INFRA_PMICSPI			15
+#define CLK_INFRA_PMICWRAP			16
+#define CLK_INFRA_DDCCI				17
+#define CLK_INFRA_CPUSEL			18
+#define CLK_INFRA_NR				19
+
+/* PERICFG */
+#define CLK_PERI_NFI				0
+#define CLK_PERI_THERM				1
+#define CLK_PERI_PWM1				2
+#define CLK_PERI_PWM2				3
+#define CLK_PERI_PWM3				4
+#define CLK_PERI_PWM4				5
+#define CLK_PERI_PWM5				6
+#define CLK_PERI_PWM6				7
+#define CLK_PERI_PWM7				8
+#define CLK_PERI_PWM				9
+#define CLK_PERI_USB0				10
+#define CLK_PERI_USB1				11
+#define CLK_PERI_AP_DMA				12
+#define CLK_PERI_MSDC30_0			13
+#define CLK_PERI_MSDC30_1			14
+#define CLK_PERI_MSDC30_2			15
+#define CLK_PERI_MSDC30_3			16
+#define CLK_PERI_MSDC50_3			17
+#define CLK_PERI_NLI				18
+#define CLK_PERI_UART0				19
+#define CLK_PERI_UART1				20
+#define CLK_PERI_UART2				21
+#define CLK_PERI_UART3				22
+#define CLK_PERI_BTIF				23
+#define CLK_PERI_I2C0				24
+#define CLK_PERI_I2C1				25
+#define CLK_PERI_I2C2				26
+#define CLK_PERI_I2C3				27
+#define CLK_PERI_AUXADC				28
+#define CLK_PERI_SPI0				39
+#define CLK_PERI_ETH				30
+#define CLK_PERI_USB0_MCU			31
+
+#define CLK_PERI_USB1_MCU			32
+#define CLK_PERI_USB_SLV			33
+#define CLK_PERI_GCPU				34
+#define CLK_PERI_NFI_ECC			35
+#define CLK_PERI_NFI_PAD			36
+#define CLK_PERI_FLASH				37
+#define CLK_PERI_HOST89_INT			38
+#define CLK_PERI_HOST89_SPI			39
+#define CLK_PERI_HOST89_DVD			40
+#define CLK_PERI_SPI1				41
+#define CLK_PERI_SPI2				42
+#define CLK_PERI_FCI				43
+#define CLK_PERI_NR				44
+
+/* AUDIO */
+#define CLK_AUD_AFE				0
+#define CLK_AUD_LRCK_DETECT			1
+#define CLK_AUD_I2S				2
+#define CLK_AUD_APLL_TUNER			3
+#define CLK_AUD_HDMI				4
+#define CLK_AUD_SPDF				5
+#define CLK_AUD_SPDF2				6
+#define CLK_AUD_APLL				7
+#define CLK_AUD_TML				8
+#define CLK_AUD_AHB_IDLE_EXT			9
+#define CLK_AUD_AHB_IDLE_INT			10
+
+#define CLK_AUD_I2SIN1				11
+#define CLK_AUD_I2SIN2				12
+#define CLK_AUD_I2SIN3				13
+#define CLK_AUD_I2SIN4				14
+#define CLK_AUD_I2SIN5				15
+#define CLK_AUD_I2SIN6				16
+#define CLK_AUD_I2SO1				17
+#define CLK_AUD_I2SO2				18
+#define CLK_AUD_I2SO3				19
+#define CLK_AUD_I2SO4				20
+#define CLK_AUD_I2SO5				21
+#define CLK_AUD_I2SO6				22
+#define CLK_AUD_ASRCI1				23
+#define CLK_AUD_ASRCI2				24
+#define CLK_AUD_ASRCO1				25
+#define CLK_AUD_ASRCO2				26
+#define CLK_AUD_ASRC11				27
+#define CLK_AUD_ASRC12				28
+#define CLK_AUD_HDMIRX				29
+#define CLK_AUD_INTDIR				30
+#define CLK_AUD_A1SYS				31
+#define CLK_AUD_A2SYS				32
+#define CLK_AUD_AFE_CONN			33
+#define CLK_AUD_AFE_PCMIF			34
+#define CLK_AUD_AFE_MRGIF			35
+
+#define CLK_AUD_MMIF_UL1			36
+#define CLK_AUD_MMIF_UL2			37
+#define CLK_AUD_MMIF_UL3			38
+#define CLK_AUD_MMIF_UL4			39
+#define CLK_AUD_MMIF_UL5			40
+#define CLK_AUD_MMIF_UL6			41
+#define CLK_AUD_MMIF_DL1			42
+#define CLK_AUD_MMIF_DL2			43
+#define CLK_AUD_MMIF_DL3			44
+#define CLK_AUD_MMIF_DL4			45
+#define CLK_AUD_MMIF_DL5			46
+#define CLK_AUD_MMIF_DL6			47
+#define CLK_AUD_MMIF_DLMCH			48
+#define CLK_AUD_MMIF_ARB1			49
+#define CLK_AUD_MMIF_AWB1			50
+#define CLK_AUD_MMIF_AWB2			51
+#define CLK_AUD_MMIF_DAI			52
+
+#define CLK_AUD_DMIC1				53
+#define CLK_AUD_DMIC2				54
+#define CLK_AUD_ASRCI3				55
+#define CLK_AUD_ASRCI4				56
+#define CLK_AUD_ASRCI5				57
+#define CLK_AUD_ASRCI6				58
+#define CLK_AUD_ASRCO3				59
+#define CLK_AUD_ASRCO4				60
+#define CLK_AUD_ASRCO5				61
+#define CLK_AUD_ASRCO6				62
+#define CLK_AUD_MEM_ASRC1			63
+#define CLK_AUD_MEM_ASRC2			64
+#define CLK_AUD_MEM_ASRC3			65
+#define CLK_AUD_MEM_ASRC4			66
+#define CLK_AUD_MEM_ASRC5			67
+#define CLK_AUD_DSD_ENC				68
+#define CLK_AUD_ASRC_BRG			60
+#define CLK_AUD_NR				70
+
+/* MMSYS */
+#define CLK_MM_SMI_COMMON			0
+#define CLK_MM_SMI_LARB0			1
+#define CLK_MM_CMDQ				2
+#define CLK_MM_MUTEX				3
+#define CLK_MM_DISP_COLOR			4
+#define CLK_MM_DISP_BLS				5
+#define CLK_MM_DISP_WDMA			6
+#define CLK_MM_DISP_RDMA			7
+#define CLK_MM_DISP_OVL				8
+#define CLK_MM_MDP_TDSHP			9
+#define CLK_MM_MDP_WROT				10
+#define CLK_MM_MDP_WDMA				11
+#define CLK_MM_MDP_RSZ1				12
+#define CLK_MM_MDP_RSZ0				13
+#define CLK_MM_MDP_RDMA				14
+#define CLK_MM_MDP_BLS_26M			15
+#define CLK_MM_CAM_MDP				16
+#define CLK_MM_FAKE_ENG				17
+#define CLK_MM_MUTEX_32K			18
+#define CLK_MM_DISP_RDMA1			19
+#define CLK_MM_DISP_UFOE			20
+
+#define CLK_MM_DSI_ENGINE			21
+#define CLK_MM_DSI_DIG				22
+#define CLK_MM_DPI_DIGL				23
+#define CLK_MM_DPI_ENGINE			24
+#define CLK_MM_DPI1_DIGL			25
+#define CLK_MM_DPI1_ENGINE			26
+#define CLK_MM_TVE_OUTPUT			27
+#define CLK_MM_TVE_INPUT			28
+#define CLK_MM_HDMI_PIXEL			29
+#define CLK_MM_HDMI_PLL				30
+#define CLK_MM_HDMI_AUDIO			31
+#define CLK_MM_HDMI_SPDIF			32
+#define CLK_MM_TVE_FMM				33
+#define CLK_MM_NR				34
+
+/* IMGSYS */
+#define CLK_IMG_SMI_COMM			0
+#define CLK_IMG_RESZ				1
+#define CLK_IMG_JPGDEC_SMI			2
+#define CLK_IMG_JPGDEC				3
+#define CLK_IMG_VENC_LT				4
+#define CLK_IMG_VENC				5
+#define CLK_IMG_NR				6
+
+/* VDEC */
+#define CLK_VDEC_CKGEN				0
+#define CLK_VDEC_LARB				1
+#define CLK_VDEC_NR				2
+
+/* HIFSYS */
+#define CLK_HIFSYS_USB0PHY			0
+#define CLK_HIFSYS_USB1PHY			1
+#define CLK_HIFSYS_PCIE0			2
+#define CLK_HIFSYS_PCIE1			3
+#define CLK_HIFSYS_PCIE2			4
+#define CLK_HIFSYS_NR				5
+
+/* ETHSYS */
+#define CLK_ETHSYS_HSDMA			0
+#define CLK_ETHSYS_ESW				1
+#define CLK_ETHSYS_GP2				2
+#define CLK_ETHSYS_GP1				3
+#define CLK_ETHSYS_PCM				4
+#define CLK_ETHSYS_GDMA				5
+#define CLK_ETHSYS_I2S				6
+#define CLK_ETHSYS_CRYPTO			7
+#define CLK_ETHSYS_NR				8
+
+/* G3DSYS */
+#define CLK_G3DSYS_CORE				0
+#define CLK_G3DSYS_NR				1
+
+#endif /* _DT_BINDINGS_CLK_MT2701_H */
diff --git a/include/dt-bindings/clock/mt7629-clk.h b/include/dt-bindings/clock/mt7629-clk.h
new file mode 100644
index 0000000..0bbfbfa
--- /dev/null
+++ b/include/dt-bindings/clock/mt7629-clk.h
@@ -0,0 +1,206 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT7629_H
+#define _DT_BINDINGS_CLK_MT7629_H
+
+/* TOPCKGEN */
+#define CLK_TOP_FCLKS_OFF		0
+
+#define CLK_TOP_TO_U2_PHY		0
+#define CLK_TOP_TO_U2_PHY_1P		1
+#define CLK_TOP_PCIE0_PIPE_EN		2
+#define CLK_TOP_PCIE1_PIPE_EN		3
+#define CLK_TOP_SSUSB_TX250M		4
+#define CLK_TOP_SSUSB_EQ_RX250M		5
+#define CLK_TOP_SSUSB_CDR_REF		6
+#define CLK_TOP_SSUSB_CDR_FB		7
+#define CLK_TOP_SATA_ASIC		8
+#define CLK_TOP_SATA_RBC		9
+
+#define CLK_TOP_TO_USB3_SYS		10
+#define CLK_TOP_P1_1MHZ			11
+#define CLK_TOP_4MHZ			12
+#define CLK_TOP_P0_1MHZ			13
+#define CLK_TOP_ETH_500M		14
+#define CLK_TOP_TXCLK_SRC_PRE		15
+#define CLK_TOP_RTC			16
+#define CLK_TOP_PWM_QTR_26M		17
+#define CLK_TOP_CPUM_TCK_IN		18
+#define CLK_TOP_TO_USB3_DA_TOP		19
+#define CLK_TOP_MEMPLL			20
+#define CLK_TOP_DMPLL			21
+#define CLK_TOP_DMPLL_D4		22
+#define CLK_TOP_DMPLL_D8		23
+#define CLK_TOP_SYSPLL_D2		24
+#define CLK_TOP_SYSPLL1_D2		25
+#define CLK_TOP_SYSPLL1_D4		26
+#define CLK_TOP_SYSPLL1_D8		27
+#define CLK_TOP_SYSPLL1_D16		28
+#define CLK_TOP_SYSPLL2_D2		29
+#define CLK_TOP_SYSPLL2_D4		30
+#define CLK_TOP_SYSPLL2_D8		31
+#define CLK_TOP_SYSPLL_D5		32
+#define CLK_TOP_SYSPLL3_D2		33
+#define CLK_TOP_SYSPLL3_D4		34
+#define CLK_TOP_SYSPLL_D7		35
+#define CLK_TOP_SYSPLL4_D2		36
+#define CLK_TOP_SYSPLL4_D4		37
+#define CLK_TOP_SYSPLL4_D16		38
+#define CLK_TOP_UNIVPLL			39
+#define CLK_TOP_UNIVPLL1_D2		40
+#define CLK_TOP_UNIVPLL1_D4		41
+#define CLK_TOP_UNIVPLL1_D8		42
+#define CLK_TOP_UNIVPLL_D3		43
+#define CLK_TOP_UNIVPLL2_D2		44
+#define CLK_TOP_UNIVPLL2_D4		45
+#define CLK_TOP_UNIVPLL2_D8		46
+#define CLK_TOP_UNIVPLL2_D16		47
+#define CLK_TOP_UNIVPLL_D5		48
+#define CLK_TOP_UNIVPLL3_D2		49
+#define CLK_TOP_UNIVPLL3_D4		50
+#define CLK_TOP_UNIVPLL3_D16		51
+#define CLK_TOP_UNIVPLL_D7		52
+#define CLK_TOP_UNIVPLL_D80_D4		53
+#define CLK_TOP_UNIV48M			54
+#define CLK_TOP_SGMIIPLL_D2		55
+#define CLK_TOP_CLKXTAL_D4		56
+#define CLK_TOP_HD_FAXI			57
+#define CLK_TOP_FAXI			58
+#define CLK_TOP_F_FAUD_INTBUS		59
+#define CLK_TOP_AP2WBHIF_HCLK		60
+#define CLK_TOP_10M_INFRAO		61
+#define CLK_TOP_MSDC30_1		62
+#define CLK_TOP_SPI			63
+#define CLK_TOP_SF			64
+#define CLK_TOP_FLASH			65
+#define CLK_TOP_TO_USB3_REF		66
+#define CLK_TOP_TO_USB3_MCU		67
+#define CLK_TOP_TO_USB3_DMA		68
+#define CLK_TOP_FROM_TOP_AHB		69
+#define CLK_TOP_FROM_TOP_AXI		70
+#define CLK_TOP_PCIE1_MAC_EN		71
+#define CLK_TOP_PCIE0_MAC_EN		72
+
+#define CLK_TOP_AXI_SEL			73
+#define CLK_TOP_MEM_SEL			74
+#define CLK_TOP_DDRPHYCFG_SEL		75
+#define CLK_TOP_ETH_SEL			76
+#define CLK_TOP_PWM_SEL			77
+#define CLK_TOP_F10M_REF_SEL		78
+#define CLK_TOP_NFI_INFRA_SEL		79
+#define CLK_TOP_FLASH_SEL		80
+#define CLK_TOP_UART_SEL		81
+#define CLK_TOP_SPI0_SEL		82
+#define CLK_TOP_SPI1_SEL		83
+#define CLK_TOP_MSDC50_0_SEL		84
+#define CLK_TOP_MSDC30_0_SEL		85
+#define CLK_TOP_MSDC30_1_SEL		86
+#define CLK_TOP_AP2WBMCU_SEL		87
+#define CLK_TOP_AP2WBHIF_SEL		88
+#define CLK_TOP_AUDIO_SEL		89
+#define CLK_TOP_AUD_INTBUS_SEL		90
+#define CLK_TOP_PMICSPI_SEL		91
+#define CLK_TOP_SCP_SEL			92
+#define CLK_TOP_ATB_SEL			93
+#define CLK_TOP_HIF_SEL			94
+#define CLK_TOP_SATA_SEL		95
+#define CLK_TOP_U2_SEL			96
+#define CLK_TOP_AUD1_SEL		97
+#define CLK_TOP_AUD2_SEL		98
+#define CLK_TOP_IRRX_SEL		99
+#define CLK_TOP_IRTX_SEL		100
+#define CLK_TOP_SATA_MCU_SEL		101
+#define CLK_TOP_PCIE0_MCU_SEL		102
+#define CLK_TOP_PCIE1_MCU_SEL		103
+#define CLK_TOP_SSUSB_MCU_SEL		104
+#define CLK_TOP_CRYPTO_SEL		105
+#define CLK_TOP_SGMII_REF_1_SEL		106
+#define CLK_TOP_10M_SEL			107
+#define CLK_TOP_NR_CLK			108
+
+/* INFRACFG */
+#define CLK_INFRA_MUX1_SEL		0
+#define CLK_INFRA_DBGCLK_PD		1
+#define CLK_INFRA_TRNG_PD		2
+#define CLK_INFRA_DEVAPC_PD		3
+#define CLK_INFRA_APXGPT_PD		4
+#define CLK_INFRA_SEJ_PD		5
+#define CLK_INFRA_NR_CLK		6
+
+/* PERICFG */
+#define CLK_PERIBUS_SEL			0
+#define CLK_PERI_PWM1_PD		1
+#define CLK_PERI_PWM2_PD		2
+#define CLK_PERI_PWM3_PD		3
+#define CLK_PERI_PWM4_PD		4
+#define CLK_PERI_PWM5_PD		5
+#define CLK_PERI_PWM6_PD		6
+#define CLK_PERI_PWM7_PD		7
+#define CLK_PERI_PWM_PD			8
+#define CLK_PERI_AP_DMA_PD		9
+#define CLK_PERI_MSDC30_1_PD		10
+#define CLK_PERI_UART0_PD		11
+#define CLK_PERI_UART1_PD		12
+#define CLK_PERI_UART2_PD		13
+#define CLK_PERI_UART3_PD		14
+#define CLK_PERI_BTIF_PD		15
+#define CLK_PERI_I2C0_PD		16
+#define CLK_PERI_SPI0_PD		17
+#define CLK_PERI_SNFI_PD		18
+#define CLK_PERI_NFI_PD			19
+#define CLK_PERI_NFIECC_PD		20
+#define CLK_PERI_FLASH_PD		21
+#define CLK_PERI_NR_CLK			22
+
+/* APMIXEDSYS */
+#define CLK_APMIXED_ARMPLL		0
+#define CLK_APMIXED_MAINPLL		1
+#define CLK_APMIXED_UNIV2PLL		2
+#define CLK_APMIXED_ETH1PLL		3
+#define CLK_APMIXED_ETH2PLL		4
+#define CLK_APMIXED_SGMIPLL		5
+#define CLK_APMIXED_NR_CLK		6
+
+/* SSUSBSYS */
+#define CLK_SSUSB_U2_PHY_1P_EN		0
+#define CLK_SSUSB_U2_PHY_EN		1
+#define CLK_SSUSB_REF_EN		2
+#define CLK_SSUSB_SYS_EN		3
+#define CLK_SSUSB_MCU_EN		4
+#define CLK_SSUSB_DMA_EN		5
+#define CLK_SSUSB_NR_CLK		6
+
+/* PCIESYS */
+#define CLK_PCIE_P1_AUX_EN		0
+#define CLK_PCIE_P1_OBFF_EN		1
+#define CLK_PCIE_P1_AHB_EN		2
+#define CLK_PCIE_P1_AXI_EN		3
+#define CLK_PCIE_P1_MAC_EN		4
+#define CLK_PCIE_P1_PIPE_EN		5
+#define CLK_PCIE_P0_AUX_EN		6
+#define CLK_PCIE_P0_OBFF_EN		7
+#define CLK_PCIE_P0_AHB_EN		8
+#define CLK_PCIE_P0_AXI_EN		9
+#define CLK_PCIE_P0_MAC_EN		10
+#define CLK_PCIE_P0_PIPE_EN		11
+#define CLK_PCIE_NR_CLK			12
+
+/* ETHSYS */
+#define CLK_ETH_FE_EN			0
+#define CLK_ETH_GP2_EN			1
+#define CLK_ETH_GP1_EN			2
+#define CLK_ETH_GP0_EN			3
+#define CLK_ETH_ESW_EN			4
+#define CLK_ETH_NR_CLK			5
+
+/* SGMIISYS */
+#define CLK_SGMII_TX_EN			0
+#define CLK_SGMII_RX_EN			1
+#define CLK_SGMII_CDR_REF		2
+#define CLK_SGMII_CDR_FB		3
+#define CLK_SGMII_NR_CLK		4
+
+#endif /* _DT_BINDINGS_CLK_MT7629_H */
diff --git a/include/dt-bindings/clock/r8a77965-cpg-mssr.h b/include/dt-bindings/clock/r8a77965-cpg-mssr.h
new file mode 100644
index 0000000..6d3b5a9
--- /dev/null
+++ b/include/dt-bindings/clock/r8a77965-cpg-mssr.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 Jacopo Mondi <jacopo+renesas@jmondi.org>
+ */
+#ifndef __DT_BINDINGS_CLOCK_R8A77965_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R8A77965_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* r8a77965 CPG Core Clocks */
+#define R8A77965_CLK_Z			0
+#define R8A77965_CLK_ZR			1
+#define R8A77965_CLK_ZG			2
+#define R8A77965_CLK_ZTR		3
+#define R8A77965_CLK_ZTRD2		4
+#define R8A77965_CLK_ZT			5
+#define R8A77965_CLK_ZX			6
+#define R8A77965_CLK_S0D1		7
+#define R8A77965_CLK_S0D2		8
+#define R8A77965_CLK_S0D3		9
+#define R8A77965_CLK_S0D4		10
+#define R8A77965_CLK_S0D6		11
+#define R8A77965_CLK_S0D8		12
+#define R8A77965_CLK_S0D12		13
+#define R8A77965_CLK_S1D1		14
+#define R8A77965_CLK_S1D2		15
+#define R8A77965_CLK_S1D4		16
+#define R8A77965_CLK_S2D1		17
+#define R8A77965_CLK_S2D2		18
+#define R8A77965_CLK_S2D4		19
+#define R8A77965_CLK_S3D1		20
+#define R8A77965_CLK_S3D2		21
+#define R8A77965_CLK_S3D4		22
+#define R8A77965_CLK_LB			23
+#define R8A77965_CLK_CL			24
+#define R8A77965_CLK_ZB3		25
+#define R8A77965_CLK_ZB3D2		26
+#define R8A77965_CLK_CR			27
+#define R8A77965_CLK_CRD2		28
+#define R8A77965_CLK_SD0H		29
+#define R8A77965_CLK_SD0		30
+#define R8A77965_CLK_SD1H		31
+#define R8A77965_CLK_SD1		32
+#define R8A77965_CLK_SD2H		33
+#define R8A77965_CLK_SD2		34
+#define R8A77965_CLK_SD3H		35
+#define R8A77965_CLK_SD3		36
+#define R8A77965_CLK_SSP2		37
+#define R8A77965_CLK_SSP1		38
+#define R8A77965_CLK_SSPRS		39
+#define R8A77965_CLK_RPC		40
+#define R8A77965_CLK_RPCD2		41
+#define R8A77965_CLK_MSO		42
+#define R8A77965_CLK_CANFD		43
+#define R8A77965_CLK_HDMI		44
+#define R8A77965_CLK_CSI0		45
+#define R8A77965_CLK_CP			46
+#define R8A77965_CLK_CPEX		47
+#define R8A77965_CLK_R			48
+#define R8A77965_CLK_OSC		49
+
+#endif /* __DT_BINDINGS_CLOCK_R8A77965_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/r8a77990-cpg-mssr.h b/include/dt-bindings/clock/r8a77990-cpg-mssr.h
index c806fce..a596a48 100644
--- a/include/dt-bindings/clock/r8a77990-cpg-mssr.h
+++ b/include/dt-bindings/clock/r8a77990-cpg-mssr.h
@@ -56,8 +56,7 @@
 #define R8A77990_CLK_LV0		45
 #define R8A77990_CLK_LV1		46
 #define R8A77990_CLK_CSI0		47
-#define R8A77990_CLK_POST3		48
-#define R8A77990_CLK_CP			49
-#define R8A77990_CLK_CPEX		50
+#define R8A77990_CLK_CP			48
+#define R8A77990_CLK_CPEX		49
 
 #endif /* __DT_BINDINGS_CLOCK_R8A77990_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/rv1108-cru.h b/include/dt-bindings/clock/rv1108-cru.h
index 9219a50..10ed9d1 100644
--- a/include/dt-bindings/clock/rv1108-cru.h
+++ b/include/dt-bindings/clock/rv1108-cru.h
@@ -14,7 +14,6 @@
 #define ARMCLK				3
 
 /* sclk gates (special clocks) */
-#define SCLK_MAC			64
 #define SCLK_SPI0			65
 #define SCLK_NANDC			67
 #define SCLK_SDMMC			68
@@ -35,20 +34,77 @@
 #define SCLK_SDMMC_SAMPLE		84
 #define SCLK_SDIO_SAMPLE		85
 #define SCLK_EMMC_SAMPLE		86
-#define SCLK_MAC_RX			87
-#define SCLK_MAC_TX			88
-#define SCLK_MACREF			89
-#define SCLK_MACREF_OUT			90
-#define SCLK_SARADC			91
+#define SCLK_VENC_CORE			87
+#define SCLK_HEVC_CORE			88
+#define SCLK_HEVC_CABAC			89
+#define SCLK_PWM0_PMU			90
+#define SCLK_I2C0_PMU			91
+#define SCLK_WIFI			92
+#define SCLK_CIFOUT			93
+#define SCLK_MIPI_CSI_OUT		94
+#define SCLK_CIF0			95
+#define SCLK_CIF1			96
+#define SCLK_CIF2			97
+#define SCLK_CIF3			98
+#define SCLK_DSP			99
+#define SCLK_DSP_IOP			100
+#define SCLK_DSP_EPP			101
+#define SCLK_DSP_EDP			102
+#define SCLK_DSP_EDAP			103
+#define SCLK_CVBS_HOST			104
+#define SCLK_HDMI_SFR			105
+#define SCLK_HDMI_CEC			106
+#define SCLK_CRYPTO			107
+#define SCLK_SPI			108
+#define SCLK_SARADC			109
+#define SCLK_TSADC			110
+#define SCLK_MAC_PRE			111
+#define SCLK_MAC			112
+#define SCLK_MAC_RX			113
+#define SCLK_MAC_REF			114
+#define SCLK_MAC_REFOUT			115
+#define SCLK_DSP_PFM			116
+#define SCLK_RGA			117
+#define SCLK_I2C1			118
+#define SCLK_I2C2			119
+#define SCLK_I2C3			120
+#define SCLK_PWM			121
+#define SCLK_ISP			122
+#define SCLK_USBPHY			123
+#define SCLK_I2S0_SRC			124
+#define SCLK_I2S1_SRC			125
+#define SCLK_I2S2_SRC			126
+#define SCLK_UART0_SRC			127
+#define SCLK_UART1_SRC			128
+#define SCLK_UART2_SRC			129
+#define SCLK_MAC_TX			130
+#define SCLK_MACREF			131
+#define SCLK_MACREF_OUT			132
 
+#define DCLK_VOP_SRC			185
+#define DCLK_HDMIPHY			186
+#define DCLK_VOP			187
 
 /* aclk gates */
 #define ACLK_DMAC			192
 #define ACLK_PRE			193
 #define ACLK_CORE			194
 #define ACLK_ENMCORE			195
-#define ACLK_GMAC			196
-
+#define ACLK_RKVENC			196
+#define ACLK_RKVDEC			197
+#define ACLK_VPU			198
+#define ACLK_CIF0			199
+#define ACLK_VIO0			200
+#define ACLK_VIO1			201
+#define ACLK_VOP			202
+#define ACLK_IEP			203
+#define ACLK_RGA			204
+#define ACLK_ISP			205
+#define ACLK_CIF1			206
+#define ACLK_CIF2			207
+#define ACLK_CIF3			208
+#define ACLK_PERI			209
+#define ACLK_GMAC			210
 
 /* pclk gates */
 #define PCLK_GPIO1			256
@@ -67,12 +123,24 @@
 #define PCLK_PWM			269
 #define PCLK_TIMER			270
 #define PCLK_PERI			271
-#define PCLK_GMAC			272
-#define PCLK_SARADC			273
+#define PCLK_GPIO0_PMU			272
+#define PCLK_I2C0_PMU			273
+#define PCLK_PWM0_PMU			274
+#define PCLK_ISP			275
+#define PCLK_VIO			276
+#define PCLK_MIPI_DSI			277
+#define PCLK_HDMI_CTRL			278
+#define PCLK_SARADC			279
+#define PCLK_DSP_CFG			280
+#define PCLK_BUS			281
+#define PCLK_EFUSE0			282
+#define PCLK_EFUSE1			283
+#define PCLK_WDT			284
+#define PCLK_GMAC			285
 
 /* hclk gates */
 #define HCLK_I2S0_8CH			320
-#define HCLK_I2S1_8CH			321
+#define HCLK_I2S1_2CH			321
 #define HCLK_I2S2_2CH			322
 #define HCLK_NANDC			323
 #define HCLK_SDMMC			324
@@ -80,20 +148,37 @@
 #define HCLK_EMMC			326
 #define HCLK_PERI			327
 #define HCLK_SFC			328
+#define HCLK_RKVENC			329
+#define HCLK_RKVDEC			330
+#define HCLK_CIF0			331
+#define HCLK_VIO			332
+#define HCLK_VOP			333
+#define HCLK_IEP			334
+#define HCLK_RGA			335
+#define HCLK_ISP			336
+#define HCLK_CRYPTO_MST			337
+#define HCLK_CRYPTO_SLV			338
+#define HCLK_HOST0			339
+#define HCLK_OTG			340
+#define HCLK_CIF1			341
+#define HCLK_CIF2			342
+#define HCLK_CIF3			343
+#define HCLK_BUS			344
+#define HCLK_VPU			345
 
-#define CLK_NR_CLKS			(HCLK_SFC + 1)
+#define CLK_NR_CLKS			(HCLK_VPU + 1)
 
 /* reset id */
-#define SRST_CORE_PO_AD		0
+#define SRST_CORE_PO_AD			0
 #define SRST_CORE_AD			1
 #define SRST_L2_AD			2
-#define SRST_CPU_NIU_AD		3
+#define SRST_CPU_NIU_AD			3
 #define SRST_CORE_PO			4
 #define SRST_CORE			5
-#define SRST_L2			6
+#define SRST_L2				6
 #define SRST_CORE_DBG			8
 #define PRST_DBG			9
-#define RST_DAP			10
+#define RST_DAP				10
 #define PRST_DBG_NIU			11
 #define ARST_STRC_SYS_AD		15
 
@@ -160,9 +245,9 @@
 #define HRST_SYSBUS			75
 #define PRST_USBGRF			76
 
-#define ARST_PERIPH_NIU		80
-#define HRST_PERIPH_NIU		81
-#define PRST_PERIPH_NIU		82
+#define ARST_PERIPH_NIU			80
+#define HRST_PERIPH_NIU			81
+#define PRST_PERIPH_NIU			82
 #define HRST_PERIPH			83
 #define HRST_SDMMC			84
 #define HRST_SDIO			85
@@ -180,7 +265,7 @@
 #define HRST_HOST0_AUX			96
 #define HRST_HOST0_ARB			97
 #define SRST_HOST0_EHCIPHY		98
-#define SRST_HOST0_UTMI		99
+#define SRST_HOST0_UTMI			99
 #define SRST_USBPOR			100
 #define SRST_UTMI0			101
 #define SRST_UTMI1			102
@@ -227,21 +312,21 @@
 #define HRST_VPU_NIU			141
 #define ARST_VPU			142
 #define HRST_VPU			143
-#define ARST_RKVDEC_NIU		144
-#define HRST_RKVDEC_NIU		145
+#define ARST_RKVDEC_NIU			144
+#define HRST_RKVDEC_NIU			145
 #define ARST_RKVDEC			146
 #define HRST_RKVDEC			147
 #define SRST_RKVDEC_CABAC		148
 #define SRST_RKVDEC_CORE		149
-#define ARST_RKVENC_NIU		150
-#define HRST_RKVENC_NIU		151
+#define ARST_RKVENC_NIU			150
+#define HRST_RKVENC_NIU			151
 #define ARST_RKVENC			152
 #define HRST_RKVENC			153
 #define SRST_RKVENC_CORE		154
 
 #define SRST_DSP_CORE			156
 #define SRST_DSP_SYS			157
-#define SRST_DSP_GLOBAL		158
+#define SRST_DSP_GLOBAL			158
 #define SRST_DSP_OECM			159
 #define PRST_DSP_IOP_NIU		160
 #define ARST_DSP_EPP_NIU		161
@@ -259,7 +344,7 @@
 #define SRST_PMU_I2C0			173
 #define PRST_PMU_I2C0			174
 #define PRST_PMU_GPIO0			175
-#define PRST_PMU_INTMEM		176
+#define PRST_PMU_INTMEM			176
 #define PRST_PMU_PWM0			177
 #define SRST_PMU_PWM0			178
 #define PRST_PMU_GRF			179
diff --git a/include/dt-bindings/gpio/meson-axg-gpio.h b/include/dt-bindings/gpio/meson-axg-gpio.h
new file mode 100644
index 0000000..25bb1ff
--- /dev/null
+++ b/include/dt-bindings/gpio/meson-axg-gpio.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017 Amlogic, Inc. All rights reserved.
+ * Author: Xingyu Chen <xingyu.chen@amlogic.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _DT_BINDINGS_MESON_AXG_GPIO_H
+#define _DT_BINDINGS_MESON_AXG_GPIO_H
+
+/* First GPIO chip */
+#define GPIOAO_0	0
+#define GPIOAO_1	1
+#define GPIOAO_2	2
+#define GPIOAO_3	3
+#define GPIOAO_4	4
+#define GPIOAO_5	5
+#define GPIOAO_6	6
+#define GPIOAO_7	7
+#define GPIOAO_8	8
+#define GPIOAO_9	9
+#define GPIOAO_10	10
+#define GPIOAO_11	11
+#define GPIOAO_12	12
+#define GPIOAO_13	13
+#define GPIO_TEST_N 14
+
+/* Second GPIO chip */
+#define GPIOZ_0		0
+#define GPIOZ_1		1
+#define GPIOZ_2		2
+#define GPIOZ_3		3
+#define GPIOZ_4		4
+#define GPIOZ_5		5
+#define GPIOZ_6		6
+#define GPIOZ_7		7
+#define GPIOZ_8		8
+#define GPIOZ_9		9
+#define GPIOZ_10	10
+#define BOOT_0		11
+#define BOOT_1		12
+#define BOOT_2		13
+#define BOOT_3		14
+#define BOOT_4		15
+#define BOOT_5		16
+#define BOOT_6		17
+#define BOOT_7		18
+#define BOOT_8		19
+#define BOOT_9		20
+#define BOOT_10		21
+#define BOOT_11		22
+#define BOOT_12		23
+#define BOOT_13		24
+#define BOOT_14		25
+#define GPIOA_0	    26
+#define GPIOA_1		27
+#define GPIOA_2		28
+#define GPIOA_3		29
+#define GPIOA_4		30
+#define GPIOA_5		31
+#define GPIOA_6		32
+#define GPIOA_7		33
+#define GPIOA_8		34
+#define GPIOA_9		35
+#define GPIOA_10	36
+#define GPIOA_11	37
+#define GPIOA_12	38
+#define GPIOA_13	39
+#define GPIOA_14	40
+#define GPIOA_15	41
+#define GPIOA_16	42
+#define GPIOA_17	43
+#define GPIOA_18	44
+#define GPIOA_19	45
+#define GPIOA_20	46
+#define GPIOX_0		47
+#define GPIOX_1		48
+#define GPIOX_2		49
+#define GPIOX_3		50
+#define GPIOX_4		51
+#define GPIOX_5		52
+#define GPIOX_6		53
+#define GPIOX_7		54
+#define GPIOX_8		55
+#define GPIOX_9		56
+#define GPIOX_10	57
+#define GPIOX_11	58
+#define GPIOX_12	59
+#define GPIOX_13	60
+#define GPIOX_14	61
+#define GPIOX_15	62
+#define GPIOX_16	63
+#define GPIOX_17	64
+#define GPIOX_18	65
+#define GPIOX_19	66
+#define GPIOX_20	67
+#define GPIOX_21	68
+#define GPIOX_22	69
+#define GPIOY_0		70
+#define GPIOY_1		71
+#define GPIOY_2		72
+#define GPIOY_3		73
+#define GPIOY_4		74
+#define GPIOY_5		75
+#define GPIOY_6		76
+#define GPIOY_7		77
+#define GPIOY_8		78
+#define GPIOY_9		79
+#define GPIOY_10	80
+#define GPIOY_11	81
+#define GPIOY_12	82
+#define GPIOY_13	83
+#define GPIOY_14	84
+#define GPIOY_15	85
+
+#endif /* _DT_BINDINGS_MESON_AXG_GPIO_H */
diff --git a/include/dt-bindings/power/mt7623-power.h b/include/dt-bindings/power/mt7623-power.h
new file mode 100644
index 0000000..0e73bb4
--- /dev/null
+++ b/include/dt-bindings/power/mt7623-power.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_MT7623_POWER_H
+#define _DT_BINDINGS_MT7623_POWER_H
+
+#define MT7623_POWER_DOMAIN_CONN	0
+#define MT7623_POWER_DOMAIN_DISP	1
+#define MT7623_POWER_DOMAIN_MFG		2
+#define MT7623_POWER_DOMAIN_VDEC	3
+#define MT7623_POWER_DOMAIN_ISP		4
+#define MT7623_POWER_DOMAIN_BDP		5
+#define MT7623_POWER_DOMAIN_ETH		6
+#define MT7623_POWER_DOMAIN_HIF		7
+#define MT7623_POWER_DOMAIN_IFR_MSC	8
+
+#endif /* _DT_BINDINGS_MT7623_POWER_H */
diff --git a/include/dt-bindings/power/mt7629-power.h b/include/dt-bindings/power/mt7629-power.h
new file mode 100644
index 0000000..c7e6130
--- /dev/null
+++ b/include/dt-bindings/power/mt7629-power.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_MT7629_POWER_H
+#define _DT_BINDINGS_MT7629_POWER_H
+
+#define MT7629_POWER_DOMAIN_ETHSYS	0
+#define MT7629_POWER_DOMAIN_HIF0	1
+#define MT7629_POWER_DOMAIN_HIF1	2
+
+#endif /* _DT_BINDINGS_MT7629_POWER_H */
diff --git a/include/dt-bindings/power/r8a77990-sysc.h b/include/dt-bindings/power/r8a77990-sysc.h
index 1409c73..944d85b 100644
--- a/include/dt-bindings/power/r8a77990-sysc.h
+++ b/include/dt-bindings/power/r8a77990-sysc.h
@@ -11,8 +11,14 @@
  * (e.g. SYSCISR, Interrupt Status Register)
  */
 
-#define R8A77990_PD_CA53_CPU0		 5
+#define R8A77990_PD_CA53_CPU0		5
+#define R8A77990_PD_CA53_CPU1		6
+#define R8A77990_PD_CR7			13
+#define R8A77990_PD_A3VC		14
+#define R8A77990_PD_3DG_A		17
+#define R8A77990_PD_3DG_B		18
 #define R8A77990_PD_CA53_SCU		21
+#define R8A77990_PD_A2VC1		26
 
 /* Always-on power area */
 #define R8A77990_PD_ALWAYS_ON		32
diff --git a/include/dt-bindings/reset/amlogic,meson-axg-audio-arb.h b/include/dt-bindings/reset/amlogic,meson-axg-audio-arb.h
new file mode 100644
index 0000000..05c3636
--- /dev/null
+++ b/include/dt-bindings/reset/amlogic,meson-axg-audio-arb.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT)
+ *
+ * Copyright (c) 2018 Baylibre SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+#ifndef _DT_BINDINGS_AMLOGIC_MESON_AXG_AUDIO_ARB_H
+#define _DT_BINDINGS_AMLOGIC_MESON_AXG_AUDIO_ARB_H
+
+#define AXG_ARB_TODDR_A	0
+#define AXG_ARB_TODDR_B	1
+#define AXG_ARB_TODDR_C	2
+#define AXG_ARB_FRDDR_A	3
+#define AXG_ARB_FRDDR_B	4
+#define AXG_ARB_FRDDR_C	5
+
+#endif /* _DT_BINDINGS_AMLOGIC_MESON_AXG_AUDIO_ARB_H */
diff --git a/include/dt-bindings/reset/amlogic,meson-axg-reset.h b/include/dt-bindings/reset/amlogic,meson-axg-reset.h
new file mode 100644
index 0000000..ad6f55d
--- /dev/null
+++ b/include/dt-bindings/reset/amlogic,meson-axg-reset.h
@@ -0,0 +1,124 @@
+/*
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Copyright (c) 2017 Amlogic, inc.
+ * Author: Yixun Lan <yixun.lan@amlogic.com>
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR BSD)
+ */
+
+#ifndef _DT_BINDINGS_AMLOGIC_MESON_AXG_RESET_H
+#define _DT_BINDINGS_AMLOGIC_MESON_AXG_RESET_H
+
+/*	RESET0					*/
+#define RESET_HIU			0
+#define RESET_PCIE_A			1
+#define RESET_PCIE_B			2
+#define RESET_DDR_TOP			3
+/*					4	*/
+#define RESET_VIU			5
+#define RESET_PCIE_PHY			6
+#define RESET_PCIE_APB			7
+/*					8	*/
+/*					9	*/
+#define RESET_VENC			10
+#define RESET_ASSIST			11
+/*					12	*/
+#define RESET_VCBUS			13
+/*					14	*/
+/*					15	*/
+#define RESET_GIC			16
+#define RESET_CAPB3_DECODE		17
+/*					18-21	*/
+#define RESET_SYS_CPU_CAPB3		22
+#define RESET_CBUS_CAPB3		23
+#define RESET_AHB_CNTL			24
+#define RESET_AHB_DATA			25
+#define RESET_VCBUS_CLK81		26
+#define RESET_MMC			27
+/*					28-31	*/
+/*	RESET1					*/
+/*					32	*/
+/*					33	*/
+#define RESET_USB_OTG			34
+#define RESET_DDR			35
+#define RESET_AO_RESET			36
+/*					37	*/
+#define RESET_AHB_SRAM			38
+/*					39	*/
+/*					40	*/
+#define RESET_DMA			41
+#define RESET_ISA			42
+#define RESET_ETHERNET			43
+/*					44	*/
+#define RESET_SD_EMMC_B			45
+#define RESET_SD_EMMC_C			46
+#define RESET_ROM_BOOT			47
+#define RESET_SYS_CPU_0			48
+#define RESET_SYS_CPU_1			49
+#define RESET_SYS_CPU_2			50
+#define RESET_SYS_CPU_3			51
+#define RESET_SYS_CPU_CORE_0		52
+#define RESET_SYS_CPU_CORE_1		53
+#define RESET_SYS_CPU_CORE_2		54
+#define RESET_SYS_CPU_CORE_3		55
+#define RESET_SYS_PLL_DIV		56
+#define RESET_SYS_CPU_AXI		57
+#define RESET_SYS_CPU_L2		58
+#define RESET_SYS_CPU_P			59
+#define RESET_SYS_CPU_MBIST		60
+/*					61-63	*/
+/*	RESET2					*/
+/*					64	*/
+/*					65	*/
+#define RESET_AUDIO			66
+/*					67	*/
+#define RESET_MIPI_HOST			68
+#define RESET_AUDIO_LOCKER		69
+#define RESET_GE2D			70
+/*					71-76	*/
+#define RESET_AO_CPU_RESET		77
+/*					78-95	*/
+/*	RESET3					*/
+#define RESET_RING_OSCILLATOR		96
+/*					97-127	*/
+/*	RESET4					*/
+/*					128	*/
+/*					129	*/
+#define RESET_MIPI_PHY			130
+/*					131-140	*/
+#define RESET_VENCL			141
+#define RESET_I2C_MASTER_2		142
+#define RESET_I2C_MASTER_1		143
+/*					144-159	*/
+/*	RESET5					*/
+/*					160-191	*/
+/*	RESET6					*/
+#define RESET_PERIPHS_GENERAL		192
+#define RESET_PERIPHS_SPICC		193
+/*					194	*/
+/*					195	*/
+#define RESET_PERIPHS_I2C_MASTER_0	196
+/*					197-200	*/
+#define RESET_PERIPHS_UART_0		201
+#define RESET_PERIPHS_UART_1		202
+/*					203-204	*/
+#define RESET_PERIPHS_SPI_0		205
+#define RESET_PERIPHS_I2C_MASTER_3	206
+/*					207-223	*/
+/*	RESET7					*/
+#define RESET_USB_DDR_0			224
+#define RESET_USB_DDR_1			225
+#define RESET_USB_DDR_2			226
+#define RESET_USB_DDR_3			227
+/*					228	*/
+#define RESET_DEVICE_MMC_ARB		229
+/*					230	*/
+#define RESET_VID_LOCK			231
+#define RESET_A9_DMC_PIPEL		232
+#define RESET_DMC_VPU_PIPEL		233
+/*					234-255	*/
+
+#endif
diff --git a/include/dt-bindings/reset/axg-aoclkc.h b/include/dt-bindings/reset/axg-aoclkc.h
new file mode 100644
index 0000000..d342c0b
--- /dev/null
+++ b/include/dt-bindings/reset/axg-aoclkc.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/*
+ * Copyright (c) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Copyright (c) 2018 Amlogic, inc.
+ * Author: Qiufang Dai <qiufang.dai@amlogic.com>
+ */
+
+#ifndef DT_BINDINGS_RESET_AMLOGIC_MESON_AXG_AOCLK
+#define DT_BINDINGS_RESET_AMLOGIC_MESON_AXG_AOCLK
+
+#define RESET_AO_REMOTE		0
+#define RESET_AO_I2C_MASTER	1
+#define RESET_AO_I2C_SLAVE	2
+#define RESET_AO_UART1		3
+#define RESET_AO_UART2		4
+#define RESET_AO_IR_BLASTER	5
+
+#endif
diff --git a/include/efi.h b/include/efi.h
index b1deb60..b5e2c64 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -96,7 +96,7 @@
 typedef unsigned long efi_status_t;
 typedef u64 efi_physical_addr_t;
 typedef u64 efi_virtual_addr_t;
-typedef void *efi_handle_t;
+typedef struct efi_object *efi_handle_t;
 
 #define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
 	{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, \
diff --git a/include/efi_api.h b/include/efi_api.h
index e850b95..aef77b6 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -85,10 +85,10 @@
 	efi_status_t (EFIAPI *check_event)(struct efi_event *event);
 #define EFI_NATIVE_INTERFACE	0x00000000
 	efi_status_t (EFIAPI *install_protocol_interface)(
-			void **handle, const efi_guid_t *protocol,
+			efi_handle_t *handle, const efi_guid_t *protocol,
 			int protocol_interface_type, void *protocol_interface);
 	efi_status_t (EFIAPI *reinstall_protocol_interface)(
-			void *handle, const efi_guid_t *protocol,
+			efi_handle_t handle, const efi_guid_t *protocol,
 			void *old_interface, void *new_interface);
 	efi_status_t (EFIAPI *uninstall_protocol_interface)(
 			efi_handle_t handle, const efi_guid_t *protocol,
@@ -164,9 +164,9 @@
 	efi_status_t (EFIAPI *locate_protocol)(const efi_guid_t *protocol,
 			void *registration, void **protocol_interface);
 	efi_status_t (EFIAPI *install_multiple_protocol_interfaces)(
-			void **handle, ...);
+			efi_handle_t *handle, ...);
 	efi_status_t (EFIAPI *uninstall_multiple_protocol_interfaces)(
-			void *handle, ...);
+			efi_handle_t handle, ...);
 	efi_status_t (EFIAPI *calculate_crc32)(const void *data,
 					       efi_uintn_t data_size,
 					       u32 *crc32);
@@ -241,8 +241,8 @@
 	efi_status_t (EFIAPI *query_capsule_caps)(
 			struct efi_capsule_header **capsule_header_array,
 			efi_uintn_t capsule_count,
-			u64 maximum_capsule_size,
-			u32 reset_type);
+			u64 *maximum_capsule_size,
+			u32 *reset_type);
 	efi_status_t (EFIAPI *query_variable_info)(
 			u32 attributes,
 			u64 *maximum_variable_storage_size,
@@ -965,7 +965,7 @@
 	struct efi_time last_access_time;
 	struct efi_time modification_time;
 	u64 attribute;
-	s16 file_name[0];
+	u16 file_name[0];
 };
 
 struct efi_file_system_info {
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 1417c35..53f0816 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -167,28 +167,41 @@
 	struct list_head open_infos;
 };
 
-/*
- * UEFI has a poor man's OO model where one "object" can be polymorphic and have
- * multiple different protocols (classes) attached to it.
+/**
+ * struct efi_object - dereferenced EFI handle
+ *
+ * @link:	pointers to put the handle into a linked list
+ * @protocols:	linked list with the protocol interfaces installed on this
+ *		handle
+ *
+ * UEFI offers a flexible and expandable object model. The objects in the UEFI
+ * API are devices, drivers, and loaded images. struct efi_object is our storage
+ * structure for these objects.
  *
- * This struct is the parent struct for all of our actual implementation objects
- * that can include it to make themselves an EFI object
+ * When including this structure into a larger structure always put it first so
+ * that when deleting a handle the whole encompassing structure can be freed.
+ *
+ * A pointer to this structure is referred to as a handle. Typedef efi_handle_t
+ * has been created for such pointers.
  */
 struct efi_object {
 	/* Every UEFI object is part of a global object list */
 	struct list_head link;
 	/* The list of protocols */
 	struct list_head protocols;
-	/* The object spawner can either use this for data or as identifier */
-	void *handle;
 };
 
 /**
  * struct efi_loaded_image_obj - handle of a loaded image
+ *
+ * @header:		EFI object header
+ * @reloc_base:		base address for the relocated image
+ * @reloc_size:		size of the relocated image
+ * @exit_jmp:		long jump buffer for returning form started image
+ * @entry:		entry address of the relocated image
  */
 struct efi_loaded_image_obj {
-	/* Generic EFI object parent class data */
-	struct efi_object parent;
+	struct efi_object header;
 	void *reloc_base;
 	aligned_u64 reloc_size;
 	efi_status_t exit_status;
@@ -290,11 +303,11 @@
 /* Call this to set the current device name */
 void efi_set_bootdev(const char *dev, const char *devnr, const char *path);
 /* Add a new object to the object list. */
-void efi_add_handle(struct efi_object *obj);
+void efi_add_handle(efi_handle_t obj);
 /* Create handle */
 efi_status_t efi_create_handle(efi_handle_t *handle);
 /* Delete handle */
-void efi_delete_handle(struct efi_object *obj);
+void efi_delete_handle(efi_handle_t obj);
 /* Call this to validate a handle and find the EFI object for it */
 struct efi_object *efi_search_obj(const efi_handle_t handle);
 /* Find a protocol on a handle */
@@ -331,7 +344,16 @@
 /* open file from device-path: */
 struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp);
 
-
+/**
+ * efi_size_in_pages() - convert size in bytes to size in pages
+ *
+ * This macro returns the number of EFI memory pages required to hold 'size'
+ * bytes.
+ *
+ * @size:	size in bytes
+ * Return:	size in pages
+ */
+#define efi_size_in_pages(size) ((size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT)
 /* Generic EFI memory allocator, call this to get memory */
 void *efi_alloc(uint64_t len, int memory_type);
 /* More specific EFI memory allocator, called by EFI payloads */
@@ -419,6 +441,10 @@
 efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path,
 				    struct efi_device_path **device_path,
 				    struct efi_device_path **file_path);
+efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
+			      const char *path,
+			      struct efi_device_path **device,
+			      struct efi_device_path **file);
 
 #define EFI_DP_TYPE(_dp, _type, _subtype) \
 	(((_dp)->type == DEVICE_PATH_TYPE_##_type) && \
@@ -492,6 +518,29 @@
 				     u32 attributes, efi_uintn_t data_size,
 				     void *data);
 
+/*
+ * See section 3.1.3 in the v2.7 UEFI spec for more details on
+ * the layout of EFI_LOAD_OPTION.  In short it is:
+ *
+ *    typedef struct _EFI_LOAD_OPTION {
+ *        UINT32 Attributes;
+ *        UINT16 FilePathListLength;
+ *        // CHAR16 Description[];   <-- variable length, NULL terminated
+ *        // EFI_DEVICE_PATH_PROTOCOL FilePathList[];
+ *						 <-- FilePathListLength bytes
+ *        // UINT8 OptionalData[];
+ *    } EFI_LOAD_OPTION;
+ */
+struct efi_load_option {
+	u32 attributes;
+	u16 file_path_length;
+	u16 *label;
+	struct efi_device_path *file_path;
+	u8 *optional_data;
+};
+
+void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data);
+unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data);
 void *efi_bootmgr_load(struct efi_device_path **device_path,
 		       struct efi_device_path **file_path);
 
diff --git a/include/efi_selftest.h b/include/efi_selftest.h
index 56beac3..49d3d6d 100644
--- a/include/efi_selftest.h
+++ b/include/efi_selftest.h
@@ -129,7 +129,6 @@
  * @setup:	set up the unit test
  * @teardown:	tear down the unit test
  * @execute:	execute the unit test
- * @setup_ok:	setup was successful (set at runtime)
  * @on_request:	test is only executed on request
  */
 struct efi_unit_test {
@@ -139,7 +138,6 @@
 		     const struct efi_system_table *systable);
 	int (*execute)(void);
 	int (*teardown)(void);
-	int setup_ok;
 	bool on_request;
 };
 
diff --git a/include/environment/ti/boot.h b/include/environment/ti/boot.h
index 3c9c87f..5891009 100644
--- a/include/environment/ti/boot.h
+++ b/include/environment/ti/boot.h
@@ -34,9 +34,9 @@
 	"partitions_android=" \
 	"uuid_disk=${uuid_gpt_disk};" \
 	"name=xloader,start=128K,size=256K,uuid=${uuid_gpt_xloader};" \
-	"name=bootloader,size=1792K,uuid=${uuid_gpt_bootloader};" \
+	"name=bootloader,size=2048K,uuid=${uuid_gpt_bootloader};" \
+	"name=reserved,start=2432K,size=256K,uuid=${uuid_gpt_reserved};" \
 	"name=misc,size=128K,uuid=${uuid_gpt_misc};" \
-	"name=reserved,size=256K,uuid=${uuid_gpt_reserved};" \
 	"name=efs,size=16M,uuid=${uuid_gpt_efs};" \
 	"name=crypto,size=16K,uuid=${uuid_gpt_crypto};" \
 	"name=recovery,size=40M,uuid=${uuid_gpt_recovery};" \
diff --git a/include/fdtdec.h b/include/fdtdec.h
index c26df50..b15da00 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -956,6 +956,7 @@
  * Called when CONFIG_OF_BOARD is defined, or if CONFIG_OF_SEPARATE is defined
  * and the board implements it.
  */
+void *board_fdt_blob_setup(void);
 
 /*
  * Decode the size of memory
diff --git a/include/handoff.h b/include/handoff.h
new file mode 100644
index 0000000..aacb0f5
--- /dev/null
+++ b/include/handoff.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Passing basic information from SPL to U-Boot proper
+ *
+ * Copyright 2018 Google, Inc
+ */
+
+#ifndef __HANDOFF_H
+#define __HANDOFF_H
+
+#if CONFIG_IS_ENABLED(HANDOFF)
+
+#include <asm/handoff.h>
+
+/**
+ * struct spl_handoff - information passed from SPL to U-Boot proper
+ *
+ * @ram_size: Value to use for gd->ram_size
+ */
+struct spl_handoff {
+	struct arch_spl_handoff arch;
+	u64 ram_size;
+#ifdef CONFIG_NR_DRAM_BANKS
+	struct {
+		u64 start;
+		u64 size;
+	} ram_bank[CONFIG_NR_DRAM_BANKS];
+#endif
+};
+
+void handoff_save_dram(struct spl_handoff *ho);
+void handoff_load_dram_size(struct spl_handoff *ho);
+void handoff_load_dram_banks(struct spl_handoff *ho);
+#endif
+
+#endif
diff --git a/include/i2c.h b/include/i2c.h
index d33f827..ccffc19 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -536,6 +536,27 @@
  */
 void i2c_dump_msgs(struct i2c_msg *msg, int nmsgs);
 
+/**
+ * i2c_emul_find() - Find an emulator for an i2c sandbox device
+ *
+ * This looks at the device's 'emul' phandle
+ *
+ * @dev: Device to find an emulator for
+ * @emulp: Returns the associated emulator, if found *
+ * @return 0 if OK, -ENOENT or -ENODEV if not found
+ */
+int i2c_emul_find(struct udevice *dev, struct udevice **emulp);
+
+/**
+ * i2c_emul_get_device() - Find the device being emulated
+ *
+ * Given an emulator this returns the associated device
+ *
+ * @emul: Emulator for the device
+ * @return device that @emul is emulating
+ */
+struct udevice *i2c_emul_get_device(struct udevice *emul);
+
 #ifndef CONFIG_DM_I2C
 
 /*
diff --git a/include/image.h b/include/image.h
index 031c355..83a2d41 100644
--- a/include/image.h
+++ b/include/image.h
@@ -30,6 +30,7 @@
 #define IMAGE_ENABLE_FIT	1
 #define IMAGE_ENABLE_OF_LIBFDT	1
 #define CONFIG_FIT_VERBOSE	1 /* enable fit_format_{error,warning}() */
+#define CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT 1
 #define CONFIG_FIT_ENABLE_SHA256_SUPPORT
 #define CONFIG_SHA1
 #define CONFIG_SHA256
@@ -278,6 +279,7 @@
 	IH_TYPE_PMMC,            /* TI Power Management Micro-Controller Firmware */
 	IH_TYPE_STM32IMAGE,		/* STMicroelectronics STM32 Image */
 	IH_TYPE_SOCFPGAIMAGE_V1,	/* Altera SOCFPGA A10 Preloader	*/
+	IH_TYPE_MTKIMAGE,		/* MediaTek BootROM loadable Image */
 
 	IH_TYPE_COUNT,			/* Number of image types */
 };
@@ -1100,6 +1102,7 @@
 	int node_offset;		/* Offset of signature node */
 	const char *name;		/* Algorithm name */
 	struct checksum_algo *checksum;	/* Checksum algorithm information */
+	struct padding_algo *padding;	/* Padding algorithm information */
 	struct crypto_algo *crypto;	/* Crypto algorithm information */
 	const void *fdt_blob;		/* FDT containing public keys */
 	int required_keynode;		/* Node offset of key to use: -1=any */
@@ -1185,6 +1188,13 @@
 		      uint8_t *sig, uint sig_len);
 };
 
+struct padding_algo {
+	const char *name;
+	int (*verify)(struct image_sign_info *info,
+		      uint8_t *pad, int pad_len,
+		      const uint8_t *hash, int hash_len);
+};
+
 /**
  * image_get_checksum_algo() - Look up a checksum algorithm
  *
@@ -1202,6 +1212,14 @@
 struct crypto_algo *image_get_crypto_algo(const char *full_name);
 
 /**
+ * image_get_padding_algo() - Look up a padding algorithm
+ *
+ * @param name		Name of padding algorithm
+ * @return pointer to algorithm information, or NULL if not found
+ */
+struct padding_algo *image_get_padding_algo(const char *name);
+
+/**
  * fit_image_verify_required_sigs() - Verify signatures marked as 'required'
  *
  * @fit:		FIT to check
diff --git a/include/linux/psci.h b/include/linux/psci.h
index 8d13bd2..9433df8 100644
--- a/include/linux/psci.h
+++ b/include/linux/psci.h
@@ -88,10 +88,8 @@
 #define PSCI_RET_DISABLED			-8
 
 #ifdef CONFIG_ARM_PSCI_FW
-typedef unsigned long (psci_fn)(unsigned long, unsigned long,
-				unsigned long, unsigned long);
-
-extern psci_fn *invoke_psci_fn;
+unsigned long invoke_psci_fn(unsigned long a0, unsigned long a1,
+			     unsigned long a2, unsigned long a3);
 #else
 unsigned long invoke_psci_fn(unsigned long a0, unsigned long a1,
 			     unsigned long a2, unsigned long a3)
diff --git a/include/log.h b/include/log.h
index a872fc6..0f2bc19 100644
--- a/include/log.h
+++ b/include/log.h
@@ -47,6 +47,8 @@
 	LOGC_DT,	/* Device-tree */
 	LOGC_EFI,	/* EFI implementation */
 	LOGC_ALLOC,	/* Memory allocation */
+	LOGC_SANDBOX,	/* Related to the sandbox board */
+	LOGC_BLOBLIST,	/* Bloblist */
 
 	LOGC_COUNT,	/* Number of log categories */
 	LOGC_END,	/* Sentinel value for a list of log categories */
@@ -107,14 +109,19 @@
 #define log_io(_fmt...)
 #endif
 
+#if CONFIG_IS_ENABLED(LOG)
+
 /* Emit a log record if the level is less that the maximum */
 #define log(_cat, _level, _fmt, _args...) ({ \
 	int _l = _level; \
-	if (_l <= _LOG_MAX_LEVEL) \
+	if (CONFIG_IS_ENABLED(LOG) && _l <= _LOG_MAX_LEVEL) \
 		_log((enum log_category_t)(_cat), _l, __FILE__, __LINE__, \
 		      __func__, \
 		      pr_fmt(_fmt), ##_args); \
 	})
+#else
+#define log(_cat, _level, _fmt, _args...)
+#endif
 
 #ifdef DEBUG
 #define _DEBUG	1
@@ -174,7 +181,16 @@
 	({ if (!(x) && _DEBUG) \
 		__assert_fail(#x, __FILE__, __LINE__, __func__); })
 
-#ifdef CONFIG_LOG_ERROR_RETURN
+#if CONFIG_IS_ENABLED(LOG) && defined(CONFIG_LOG_ERROR_RETURN)
+/*
+ * Log an error return value, possibly with a message. Usage:
+ *
+ *	return log_ret(fred_call());
+ *
+ * or:
+ *
+ *	return log_msg_ret("fred failed", fred_call());
+ */
 #define log_ret(_ret) ({ \
 	int __ret = (_ret); \
 	if (__ret < 0) \
@@ -189,8 +205,9 @@
 	__ret; \
 	})
 #else
+/* Non-logging versions of the above which just return the error code */
 #define log_ret(_ret) (_ret)
-#define log_msg_ret(_msg, _ret) (_ret)
+#define log_msg_ret(_msg, _ret) ((void)(_msg), _ret)
 #endif
 
 /**
diff --git a/include/malloc.h b/include/malloc.h
index 8175c75..b714fed 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -880,6 +880,7 @@
 void *calloc(size_t nmemb, size_t size);
 void *memalign_simple(size_t alignment, size_t bytes);
 void *realloc_simple(void *ptr, size_t size);
+void malloc_simple_info(void);
 #else
 
 # ifdef USE_DL_PREFIX
diff --git a/include/misc.h b/include/misc.h
index 5051585..12d1325 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -13,7 +13,7 @@
  * @buf: pointer to data buffer
  * @size: data size in bytes to read the device
  *
- * Return: 0 if OK, -ve on error
+ * Return: number of bytes read if OK (may be 0 if EOF), -ve on error
  */
 int misc_read(struct udevice *dev, int offset, void *buf, int size);
 
@@ -24,7 +24,7 @@
  * @buf: pointer to data buffer
  * @size: data size in bytes to write the device
  *
- * Return: 0 if OK, -ve on error
+ * Return: number of bytes written if OK (may be < @size), -ve on error
  */
 int misc_write(struct udevice *dev, int offset, void *buf, int size);
 
@@ -90,7 +90,7 @@
 	 * @buf: pointer to data buffer
 	 * @size: data size in bytes to read the device
 	 *
-	 * Return: 0 if OK, -ve on error
+	 * Return: number of bytes read if OK (may be 0 if EOF), -ve on error
 	 */
 	int (*read)(struct udevice *dev, int offset, void *buf, int size);
 
@@ -101,7 +101,7 @@
 	 * @buf: pointer to data buffer
 	 * @size: data size in bytes to write the device
 	 *
-	 * Return: 0 if OK, -ve on error
+	 * Return: number of bytes written if OK (may be < @size), -ve on error
 	 */
 	int (*write)(struct udevice *dev, int offset, const void *buf,
 		     int size);
diff --git a/include/os.h b/include/os.h
index 28eb625..6f33b08 100644
--- a/include/os.h
+++ b/include/os.h
@@ -350,4 +350,18 @@
  */
 int os_write_file(const char *name, const void *buf, int size);
 
+/**
+ * os_read_file() - Read a file from the host filesystem
+ *
+ * This can be useful when reading test data into sandbox for use by test
+ * routines. The data is allocated using os_malloc() and should be freed by
+ * the caller.
+ *
+ * @name:	File path to read from
+ * @bufp:	Returns buffer containing data read
+ * @sizep:	Returns size of data
+ * @return 0 if OK, -ve on error
+ */
+int os_read_file(const char *name, void **bufp, int *sizep);
+
 #endif
diff --git a/include/serial.h b/include/serial.h
index ec25db6..9133d07 100644
--- a/include/serial.h
+++ b/include/serial.h
@@ -224,7 +224,6 @@
 void atmel_serial_initialize(void);
 void mcf_serial_initialize(void);
 void mpc85xx_serial_initialize(void);
-void mpc8xx_serial_initialize(void);
 void mxc_serial_initialize(void);
 void ns16550_serial_initialize(void);
 void pl01x_serial_initialize(void);
diff --git a/include/sound.h b/include/sound.h
index 3269f23..77bfe6a 100644
--- a/include/sound.h
+++ b/include/sound.h
@@ -31,11 +31,13 @@
 /*
  * Generates square wave sound data for 1 second
  *
+ * @param sample_rate   Sample rate in Hz
  * @param data          data buffer pointer
  * @param size          size of the buffer
  * @param freq          frequency of the wave
  */
-void sound_create_square_wave(unsigned short *data, int size, uint32_t freq);
+void sound_create_square_wave(uint sample_rate, unsigned short *data, int size,
+			      uint freq);
 
 /*
  * Initialises audio sub system
diff --git a/include/spi_flash.h b/include/spi_flash.h
index 0ec98fb..e427e96 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -112,6 +112,19 @@
 	int (*write)(struct udevice *dev, u32 offset, size_t len,
 		     const void *buf);
 	int (*erase)(struct udevice *dev, u32 offset, size_t len);
+	/**
+	 * get_sw_write_prot() - Check state of software write-protect feature
+	 *
+	 * SPI flash chips can lock a region of the flash defined by a
+	 * 'protected area'. This function checks if this protected area is
+	 * defined.
+	 *
+	 * @dev:	SPI flash device
+	 * @return 0 if no region is write-protected, 1 if a region is
+	 *	write-protected, -ENOSYS if the driver does not implement this,
+	 *	other -ve value on error
+	 */
+	int (*get_sw_write_prot)(struct udevice *dev);
 };
 
 /* Access the serial operations for a device */
@@ -153,6 +166,20 @@
  */
 int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len);
 
+/**
+ * spl_flash_get_sw_write_prot() - Check state of software write-protect feature
+ *
+ * SPI flash chips can lock a region of the flash defined by a
+ * 'protected area'. This function checks if this protected area is
+ * defined.
+ *
+ * @dev:	SPI flash device
+ * @return 0 if no region is write-protected, 1 if a region is
+ *	write-protected, -ENOSYS if the driver does not implement this,
+ *	other -ve value on error
+ */
+int spl_flash_get_sw_write_prot(struct udevice *dev);
+
 int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
 			   unsigned int max_hz, unsigned int spi_mode,
 			   struct udevice **devp);
diff --git a/include/spl.h b/include/spl.h
index 9a439f4..ee92832 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -11,6 +11,7 @@
 /* Platform-specific defines */
 #include <linux/compiler.h>
 #include <asm/spl.h>
+#include <handoff.h>
 
 /* Value in r0 indicates we booted from U-Boot */
 #define UBOOT_NOT_LOADED_FROM_SPL	0x13578642
@@ -21,6 +22,46 @@
 #define MMCSD_MODE_FS		2
 #define MMCSD_MODE_EMMCBOOT	3
 
+/*
+ * u_boot_first_phase() - check if this is the first U-Boot phase
+ *
+ * U-Boot has up to three phases: TPL, SPL and U-Boot proper. Depending on the
+ * build flags we can determine whether the current build is for the first
+ * phase of U-Boot or not. If there is no SPL, then this is U-Boot proper. If
+ * there is SPL but no TPL, the the first phase is SPL. If there is TPL, then
+ * it is the first phase.
+ *
+ * @returns true if this is the first phase of U-Boot
+ *
+ */
+static inline bool u_boot_first_phase(void)
+{
+	if (IS_ENABLED(CONFIG_TPL)) {
+		if (IS_ENABLED(CONFIG_TPL_BUILD))
+			return true;
+	} else if (IS_ENABLED(CONFIG_SPL)) {
+		if (IS_ENABLED(CONFIG_SPL_BUILD))
+			return true;
+	} else {
+		return true;
+	}
+
+	return false;
+}
+
+/* A string name for SPL or TPL */
+#ifdef CONFIG_SPL_BUILD
+# ifdef CONFIG_TPL_BUILD
+#  define SPL_TPL_NAME	"tpl"
+# else
+#  define SPL_TPL_NAME	"spl"
+# endif
+# define SPL_TPL_PROMPT	SPL_TPL_NAME ": "
+#else
+# define SPL_TPL_NAME	""
+# define SPL_TPL_PROMPT	""
+#endif
+
 struct spl_image_info {
 	const char *name;
 	u8 os;
diff --git a/include/test/suites.h b/include/test/suites.h
index abb3a4b..77d863b 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -23,6 +23,7 @@
 int cmd_ut_category(const char *name, struct unit_test *tests, int n_ents,
 		    int argc, char * const argv[]);
 
+int do_ut_bloblist(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_compression(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 int do_ut_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
diff --git a/include/tpm-common.h b/include/tpm-common.h
index 5f8bc6b..3d88b44 100644
--- a/include/tpm-common.h
+++ b/include/tpm-common.h
@@ -26,6 +26,8 @@
 /* Max buffer size supported by our tpm */
 #define TPM_DEV_BUFSIZE		1260
 
+#define TPM_PCR_MINIMUM_DIGEST_SIZE 20
+
 /**
  * enum tpm_version - The version of the TPM stack to be used
  * @TPM_V1:		Use TPM v1.x stack
@@ -174,12 +176,40 @@
 int do_##cmd(cmd_tbl_t *cmdtp, int flag,		\
 	     int argc, char * const argv[])		\
 {							\
+	struct udevice *dev;				\
+	int rc;						\
+							\
+	rc = get_tpm(&dev);				\
+	if (rc)						\
+		return rc;				\
 	if (argc != 1)					\
 		return CMD_RET_USAGE;			\
-	return report_return_code(cmd());		\
+	return report_return_code(cmd(dev));		\
 }
 
 /**
+ * tpm_open() - Request access to locality 0 for the caller
+ *
+ * After all commands have been completed the caller is supposed to
+ * call tpm_close().
+ *
+ * @dev - TPM device
+ * Returns 0 on success, -ve on failure.
+ */
+int tpm_open(struct udevice *dev);
+
+/**
+ * tpm_close() - Close the current session
+ *
+ * Releasing the locked locality. Returns 0 on success, -ve 1 on
+ * failure (in case lock removal did not succeed).
+ *
+ * @dev - TPM device
+ * Returns 0 on success, -ve on failure.
+ */
+int tpm_close(struct udevice *dev);
+
+/**
  * tpm_get_desc() - Get a text description of the TPM
  *
  * @dev:	Device to check
@@ -202,6 +232,7 @@
  * Note that the outgoing data is inspected to determine command type
  * (ordinal) and a timeout is used for that command type.
  *
+ * @dev - TPM device
  * @sendbuf - buffer of the data to send
  * @send_size size of the data to send
  * @recvbuf - memory to save the response to
@@ -216,9 +247,10 @@
 /**
  * Initialize TPM device.  It must be called before any TPM commands.
  *
+ * @dev - TPM device
  * @return 0 on success, non-0 on error.
  */
-int tpm_init(void);
+int tpm_init(struct udevice *dev);
 
 /**
  * Retrieve the array containing all the v1 (resp. v2) commands.
diff --git a/include/tpm-v1.h b/include/tpm-v1.h
index be2eca9..45b7a48 100644
--- a/include/tpm-v1.h
+++ b/include/tpm-v1.h
@@ -282,64 +282,72 @@
 /**
  * Issue a TPM_Startup command.
  *
+ * @param dev		TPM device
  * @param mode		TPM startup mode
  * @return return code of the operation
  */
-u32 tpm_startup(enum tpm_startup_type mode);
+u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode);
 
 /**
  * Issue a TPM_SelfTestFull command.
  *
+ * @param dev		TPM device
  * @return return code of the operation
  */
-u32 tpm_self_test_full(void);
+u32 tpm_self_test_full(struct udevice *dev);
 
 /**
  * Issue a TPM_ContinueSelfTest command.
  *
+ * @param dev		TPM device
  * @return return code of the operation
  */
-u32 tpm_continue_self_test(void);
+u32 tpm_continue_self_test(struct udevice *dev);
 
 /**
  * Issue a TPM_NV_DefineSpace command.  The implementation is limited
  * to specify TPM_NV_ATTRIBUTES and size of the area.  The area index
  * could be one of the special value listed in enum tpm_nv_index.
  *
+ * @param dev		TPM device
  * @param index		index of the area
  * @param perm		TPM_NV_ATTRIBUTES of the area
  * @param size		size of the area
  * @return return code of the operation
  */
-u32 tpm_nv_define_space(u32 index, u32 perm, u32 size);
+u32 tpm_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size);
 
 /**
  * Issue a TPM_NV_ReadValue command.  This implementation is limited
  * to read the area from offset 0.  The area index could be one of
  * the special value listed in enum tpm_nv_index.
  *
+ * @param dev		TPM device
  * @param index		index of the area
  * @param data		output buffer of the area contents
  * @param count		size of output buffer
  * @return return code of the operation
  */
-u32 tpm_nv_read_value(u32 index, void *data, u32 count);
+u32 tpm_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count);
 
 /**
  * Issue a TPM_NV_WriteValue command.  This implementation is limited
  * to write the area from offset 0.  The area index could be one of
  * the special value listed in enum tpm_nv_index.
  *
+ * @param dev		TPM device
  * @param index		index of the area
  * @param data		input buffer to be wrote to the area
  * @param length	length of data bytes of input buffer
  * @return return code of the operation
  */
-u32 tpm_nv_write_value(u32 index, const void *data, u32 length);
+u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data,
+		       u32 length);
 
 /**
  * Issue a TPM_Extend command.
  *
+ * @param dev		TPM device
  * @param index		index of the PCR
  * @param in_digest	160-bit value representing the event to be
  *			recorded
@@ -347,69 +355,78 @@
  *			command
  * @return return code of the operation
  */
-u32 tpm_extend(u32 index, const void *in_digest, void *out_digest);
+u32 tpm_extend(struct udevice *dev, u32 index, const void *in_digest,
+	       void *out_digest);
 
 /**
  * Issue a TPM_PCRRead command.
  *
+ * @param dev		TPM device
  * @param index		index of the PCR
  * @param data		output buffer for contents of the named PCR
  * @param count		size of output buffer
  * @return return code of the operation
  */
-u32 tpm_pcr_read(u32 index, void *data, size_t count);
+u32 tpm_pcr_read(struct udevice *dev, u32 index, void *data, size_t count);
 
 /**
  * Issue a TSC_PhysicalPresence command.  TPM physical presence flag
  * is bit-wise OR'ed of flags listed in enum tpm_physical_presence.
  *
+ * @param dev		TPM device
  * @param presence	TPM physical presence flag
  * @return return code of the operation
  */
-u32 tpm_tsc_physical_presence(u16 presence);
+u32 tpm_tsc_physical_presence(struct udevice *dev, u16 presence);
 
 /**
  * Issue a TPM_ReadPubek command.
  *
+ * @param dev		TPM device
  * @param data		output buffer for the public endorsement key
  * @param count		size of output buffer
  * @return return code of the operation
  */
-u32 tpm_read_pubek(void *data, size_t count);
+u32 tpm_read_pubek(struct udevice *dev, void *data, size_t count);
 
 /**
  * Issue a TPM_ForceClear command.
  *
+ * @param dev		TPM device
  * @return return code of the operation
  */
-u32 tpm_force_clear(void);
+u32 tpm_force_clear(struct udevice *dev);
 
 /**
  * Issue a TPM_PhysicalEnable command.
  *
+ * @param dev		TPM device
  * @return return code of the operation
  */
-u32 tpm_physical_enable(void);
+u32 tpm_physical_enable(struct udevice *dev);
 
 /**
  * Issue a TPM_PhysicalDisable command.
  *
+ * @param dev		TPM device
  * @return return code of the operation
  */
-u32 tpm_physical_disable(void);
+u32 tpm_physical_disable(struct udevice *dev);
 
 /**
  * Issue a TPM_PhysicalSetDeactivated command.
  *
+ * @param dev		TPM device
  * @param state		boolean state of the deactivated flag
  * @return return code of the operation
  */
-u32 tpm_physical_set_deactivated(u8 state);
+u32 tpm_physical_set_deactivated(struct udevice *dev, u8 state);
 
 /**
  * Issue a TPM_GetCapability command.  This implementation is limited
  * to query sub_cap index that is 4-byte wide.
  *
+ * @param dev		TPM device
  * @param cap_area	partition of capabilities
  * @param sub_cap	further definition of capability, which is
  *			limited to be 4-byte wide
@@ -417,15 +434,17 @@
  * @param count		size of output buffer
  * @return return code of the operation
  */
-u32 tpm_get_capability(u32 cap_area, u32 sub_cap, void *cap, size_t count);
+u32 tpm_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap,
+		       void *cap, size_t count);
 
 /**
  * Issue a TPM_FlushSpecific command for a AUTH resource.
  *
+ * @param dev		TPM device
  * @param auth_handle	handle of the auth session
  * @return return code of the operation
  */
-u32 tpm_terminate_auth_session(u32 auth_handle);
+u32 tpm_terminate_auth_session(struct udevice *dev, u32 auth_handle);
 
 /**
  * Issue a TPM_OIAP command to setup an object independent authorization
@@ -434,22 +453,25 @@
  * If there was already an OIAP session active it is terminated and a new
  * session is set up.
  *
+ * @param dev		TPM device
  * @param auth_handle	pointer to the (new) auth handle or NULL.
  * @return return code of the operation
  */
-u32 tpm_oiap(u32 *auth_handle);
+u32 tpm_oiap(struct udevice *dev, u32 *auth_handle);
 
 /**
  * Ends an active OIAP session.
  *
+ * @param dev		TPM device
  * @return return code of the operation
  */
-u32 tpm_end_oiap(void);
+u32 tpm_end_oiap(struct udevice *dev);
 
 /**
  * Issue a TPM_LoadKey2 (Auth1) command using an OIAP session for authenticating
  * the usage of the parent key.
  *
+ * @param dev		TPM device
  * @param parent_handle	handle of the parent key.
  * @param key		pointer to the key structure (TPM_KEY or TPM_KEY12).
  * @param key_length	size of the key structure
@@ -457,13 +479,15 @@
  * @param key_handle	pointer to the key handle
  * @return return code of the operation
  */
-u32 tpm_load_key2_oiap(u32 parent_handle, const void *key, size_t key_length,
-		       const void *parent_key_usage_auth, u32 *key_handle);
+u32 tpm_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key,
+		       size_t key_length, const void *parent_key_usage_auth,
+		       u32 *key_handle);
 
 /**
  * Issue a TPM_GetPubKey (Auth1) command using an OIAP session for
  * authenticating the usage of the key.
  *
+ * @param dev		TPM device
  * @param key_handle	handle of the key
  * @param usage_auth	usage auth for the key
  * @param pubkey	pointer to the pub key buffer; may be NULL if the pubkey
@@ -473,45 +497,51 @@
  *			of the stored TPM_PUBKEY structure (iff pubkey != NULL).
  * @return return code of the operation
  */
-u32 tpm_get_pub_key_oiap(u32 key_handle, const void *usage_auth, void *pubkey,
+u32 tpm_get_pub_key_oiap(struct udevice *dev, u32 key_handle,
+			 const void *usage_auth, void *pubkey,
 			 size_t *pubkey_len);
 
 /**
  * Get the TPM permanent flags value
  *
+ * @param dev		TPM device
  * @param pflags	Place to put permanent flags
  * @return return code of the operation
  */
-u32 tpm_get_permanent_flags(struct tpm_permanent_flags *pflags);
+u32 tpm_get_permanent_flags(struct udevice *dev,
+			    struct tpm_permanent_flags *pflags);
 
 /**
  * Get the TPM permissions
  *
+ * @param dev		TPM device
  * @param perm		Returns permissions value
  * @return return code of the operation
  */
-u32 tpm_get_permissions(u32 index, u32 *perm);
+u32 tpm_get_permissions(struct udevice *dev, u32 index, u32 *perm);
 
 /**
  * Flush a resource with a given handle and type from the TPM
  *
+ * @param dev		TPM device
  * @param key_handle           handle of the resource
  * @param resource_type                type of the resource
  * @return return code of the operation
  */
-u32 tpm_flush_specific(u32 key_handle, u32 resource_type);
+u32 tpm_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type);
 
 #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
 /**
  * Search for a key by usage AuthData and the hash of the parent's pub key.
  *
+ * @param dev		TPM device
  * @param auth	        Usage auth of the key to search for
  * @param pubkey_digest	SHA1 hash of the pub key structure of the key
  * @param[out] handle	The handle of the key (Non-null iff found)
  * @return 0 if key was found in TPM; != 0 if not.
  */
-u32 tpm_find_key_sha1(const u8 auth[20], const u8 pubkey_digest[20],
-		      u32 *handle);
+u32 tpm_find_key_sha1(struct udevice *dev, const u8 auth[20],
+		      const u8 pubkey_digest[20], u32 *handle);
 #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
 
 /**
@@ -519,38 +549,43 @@
  * that the TPM may legally return fewer bytes than requested by retrying
  * until @p count bytes have been received.
  *
+ * @param dev		TPM device
  * @param data		output buffer for the random bytes
  * @param count		size of output buffer
  * @return return code of the operation
  */
-u32 tpm_get_random(void *data, u32 count);
+u32 tpm_get_random(struct udevice *dev, void *data, u32 count);
 
 /**
  * tpm_finalise_physical_presence() - Finalise physical presence
  *
+ * @param dev		TPM device
  * @return return code of the operation (0 = success)
  */
-u32 tpm_finalise_physical_presence(void);
+u32 tpm_finalise_physical_presence(struct udevice *dev);
 
 /**
  * tpm_nv_set_locked() - lock the non-volatile space
  *
+ * @param dev		TPM device
  * @return return code of the operation (0 = success)
  */
-u32 tpm_nv_set_locked(void);
+u32 tpm_nv_set_locked(struct udevice *dev);
 
 /**
  * tpm_set_global_lock() - set the global lock
  *
+ * @param dev		TPM device
  * @return return code of the operation (0 = success)
  */
-u32 tpm_set_global_lock(void);
+u32 tpm_set_global_lock(struct udevice *dev);
 
 /**
  * tpm_resume() - start up the TPM from resume (after suspend)
  *
+ * @param dev		TPM device
  * @return return code of the operation (0 = success)
  */
-u32 tpm_resume(void);
+u32 tpm_resume(struct udevice *dev);
 
 #endif /* __TPM_V1_H */
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index c77b416..2f2e66d 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -131,45 +131,51 @@
 /**
  * Issue a TPM2_Startup command.
  *
+ * @dev		TPM device
  * @mode	TPM startup mode
  *
  * @return code of the operation
  */
-u32 tpm2_startup(enum tpm2_startup_types mode);
+u32 tpm2_startup(struct udevice *dev, enum tpm2_startup_types mode);
 
 /**
  * Issue a TPM2_SelfTest command.
  *
+ * @dev		TPM device
  * @full_test	Asking to perform all tests or only the untested ones
  *
  * @return code of the operation
  */
-u32 tpm2_self_test(enum tpm2_yes_no full_test);
+u32 tpm2_self_test(struct udevice *dev, enum tpm2_yes_no full_test);
 
 /**
  * Issue a TPM2_Clear command.
  *
+ * @dev		TPM device
  * @handle	Handle
  * @pw		Password
  * @pw_sz	Length of the password
  *
  * @return code of the operation
  */
-u32 tpm2_clear(u32 handle, const char *pw, const ssize_t pw_sz);
+u32 tpm2_clear(struct udevice *dev, u32 handle, const char *pw,
+	       const ssize_t pw_sz);
 
 /**
  * Issue a TPM2_PCR_Extend command.
  *
+ * @dev		TPM device
  * @index	Index of the PCR
  * @digest	Value representing the event to be recorded
  *
  * @return code of the operation
  */
-u32 tpm2_pcr_extend(u32 index, const uint8_t *digest);
+u32 tpm2_pcr_extend(struct udevice *dev, u32 index, const uint8_t *digest);
 
 /**
  * Issue a TPM2_PCR_Read command.
  *
+ * @dev		TPM device
  * @idx		Index of the PCR
  * @idx_min_sz	Minimum size in bytes of the pcrSelect array
  * @data	Output buffer for contents of the named PCR
@@ -177,13 +183,14 @@
  *
  * @return code of the operation
  */
-u32 tpm2_pcr_read(u32 idx, unsigned int idx_min_sz, void *data,
-		  unsigned int *updates);
+u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz,
+		  void *data, unsigned int *updates);
 
 /**
  * Issue a TPM2_GetCapability command.  This implementation is limited
  * to query property index that is 4-byte wide.
  *
+ * @dev		TPM device
  * @capability	Partition of capabilities
  * @property	Further definition of capability, limited to be 4 bytes wide
  * @buf		Output buffer for capability information
@@ -191,22 +198,24 @@
  *
  * @return code of the operation
  */
-u32 tpm2_get_capability(u32 capability, u32 property, void *buf,
-			size_t prop_count);
+u32 tpm2_get_capability(struct udevice *dev, u32 capability, u32 property,
+			void *buf, size_t prop_count);
 
 /**
  * Issue a TPM2_DictionaryAttackLockReset command.
  *
+ * @dev		TPM device
  * @pw		Password
  * @pw_sz	Length of the password
  *
  * @return code of the operation
  */
-u32 tpm2_dam_reset(const char *pw, const ssize_t pw_sz);
+u32 tpm2_dam_reset(struct udevice *dev, const char *pw, const ssize_t pw_sz);
 
 /**
  * Issue a TPM2_DictionaryAttackParameters command.
  *
+ * @dev		TPM device
  * @pw		Password
  * @pw_sz	Length of the password
  * @max_tries	Count of authorizations before lockout
@@ -215,13 +224,15 @@
  *
  * @return code of the operation
  */
-u32 tpm2_dam_parameters(const char *pw, const ssize_t pw_sz,
-			unsigned int max_tries, unsigned int recovery_time,
+u32 tpm2_dam_parameters(struct udevice *dev, const char *pw,
+			const ssize_t pw_sz, unsigned int max_tries,
+			unsigned int recovery_time,
 			unsigned int lockout_recovery);
 
 /**
  * Issue a TPM2_HierarchyChangeAuth command.
  *
+ * @dev		TPM device
  * @handle	Handle
  * @newpw	New password
  * @newpw_sz	Length of the new password
@@ -230,12 +241,14 @@
  *
  * @return code of the operation
  */
-int tpm2_change_auth(u32 handle, const char *newpw, const ssize_t newpw_sz,
-		     const char *oldpw, const ssize_t oldpw_sz);
+int tpm2_change_auth(struct udevice *dev, u32 handle, const char *newpw,
+		     const ssize_t newpw_sz, const char *oldpw,
+		     const ssize_t oldpw_sz);
 
 /**
  * Issue a TPM_PCR_SetAuthPolicy command.
  *
+ * @dev		TPM device
  * @pw		Platform password
  * @pw_sz	Length of the password
  * @index	Index of the PCR
@@ -243,12 +256,13 @@
  *
  * @return code of the operation
  */
-u32 tpm2_pcr_setauthpolicy(const char *pw, const ssize_t pw_sz, u32 index,
-			   const char *key);
+u32 tpm2_pcr_setauthpolicy(struct udevice *dev, const char *pw,
+			   const ssize_t pw_sz, u32 index, const char *key);
 
 /**
  * Issue a TPM_PCR_SetAuthValue command.
  *
+ * @dev		TPM device
  * @pw		Platform password
  * @pw_sz	Length of the password
  * @index	Index of the PCR
@@ -257,7 +271,8 @@
  *
  * @return code of the operation
  */
-u32 tpm2_pcr_setauthvalue(const char *pw, const ssize_t pw_sz, u32 index,
-			  const char *key, const ssize_t key_sz);
+u32 tpm2_pcr_setauthvalue(struct udevice *dev, const char *pw,
+			  const ssize_t pw_sz, u32 index, const char *key,
+			  const ssize_t key_sz);
 
 #endif /* __TPM_V2_H */
diff --git a/include/u-boot/rsa.h b/include/u-boot/rsa.h
index 68bcb14..2d3024d 100644
--- a/include/u-boot/rsa.h
+++ b/include/u-boot/rsa.h
@@ -97,6 +97,16 @@
 int rsa_verify(struct image_sign_info *info,
 	       const struct image_region region[], int region_count,
 	       uint8_t *sig, uint sig_len);
+
+int padding_pkcs_15_verify(struct image_sign_info *info,
+			   uint8_t *msg, int msg_len,
+			   const uint8_t *hash, int hash_len);
+
+#ifdef CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT
+int padding_pss_verify(struct image_sign_info *info,
+		       uint8_t *msg, int msg_len,
+		       const uint8_t *hash, int hash_len);
+#endif /* CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT */
 #else
 static inline int rsa_verify(struct image_sign_info *info,
 		const struct image_region region[], int region_count,
@@ -104,8 +114,26 @@
 {
 	return -ENXIO;
 }
+
+static inline int padding_pkcs_15_verify(struct image_sign_info *info,
+					 uint8_t *msg, int msg_len,
+					 const uint8_t *hash, int hash_len)
+{
+	return -ENXIO;
+}
+
+#ifdef CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT
+static inline int padding_pss_verify(struct image_sign_info *info,
+				     uint8_t *msg, int msg_len,
+				     const uint8_t *hash, int hash_len)
+{
+	return -ENXIO;
+}
+#endif /* CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT */
 #endif
 
+#define RSA_DEFAULT_PADDING_NAME		"pkcs-1.5"
+
 #define RSA2048_BYTES	(2048 / 8)
 #define RSA4096_BYTES	(4096 / 8)
 
diff --git a/include/usb.h b/include/usb.h
index b6b48a8..420a30e 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -140,7 +140,7 @@
 	int act_len;			/* transferred bytes */
 	int maxchild;			/* Number of ports if hub */
 	int portnr;			/* Port number, 1=first */
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 	/* parent hub, or NULL if this is the root hub */
 	struct usb_device *parent;
 	struct usb_device *children[USB_MAXCHILDREN];
@@ -148,7 +148,7 @@
 #endif
 	/* slot_id - for xHCI enabled devices */
 	unsigned int slot_id;
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 	struct udevice *dev;		/* Pointer to associated device */
 	struct udevice *controller_dev;	/* Pointer to associated controller */
 #endif
@@ -173,7 +173,7 @@
 int usb_lowlevel_init(int index, enum usb_init_type init, void **controller);
 int usb_lowlevel_stop(int index);
 
-#if defined(CONFIG_USB_MUSB_HOST) || defined(CONFIG_DM_USB)
+#if defined(CONFIG_USB_MUSB_HOST) || CONFIG_IS_ENABLED(DM_USB)
 int usb_reset_root_port(struct usb_device *dev);
 #else
 #define usb_reset_root_port(dev)
@@ -187,7 +187,7 @@
 			int transfer_len, int interval);
 
 #if defined CONFIG_USB_EHCI_HCD || defined CONFIG_USB_MUSB_HOST \
-	|| defined(CONFIG_DM_USB)
+	|| CONFIG_IS_ENABLED(DM_USB)
 struct int_queue *create_int_queue(struct usb_device *dev, unsigned long pipe,
 	int queuesize, int elementsize, void *buffer, int interval);
 int destroy_int_queue(struct usb_device *dev, struct int_queue *queue);
@@ -588,7 +588,7 @@
 	struct usb_tt tt;		/* Transaction Translator */
 };
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 /**
  * struct usb_platdata - Platform data about a USB controller
  *
@@ -912,7 +912,7 @@
  */
 void usb_stor_reset(void);
 
-#else /* !CONFIG_DM_USB */
+#else /* !CONFIG_IS_ENABLED(DM_USB) */
 
 struct usb_device *usb_get_dev_index(int index);
 
diff --git a/include/video.h b/include/video.h
index 75200f0..1d57b48 100644
--- a/include/video.h
+++ b/include/video.h
@@ -61,7 +61,9 @@
  * @font_size:	Font size in pixels (0 to use a default value)
  * @fb:		Frame buffer
  * @fb_size:	Frame buffer size
- * @line_length:	Length of each frame buffer line, in bytes
+ * @line_length:	Length of each frame buffer line, in bytes. This can be
+ *		set by the driver, but if not, the uclass will set it after
+ *		probing
  * @colour_fg:	Foreground colour (pixel value)
  * @colour_bg:	Background colour (pixel value)
  * @flush_dcache:	true to enable flushing of the data cache after
@@ -191,9 +193,10 @@
 /**
  * Set default colors and attributes
  *
- * @priv	device information
+ * @dev:	video device
+ * @invert	true to invert colours
  */
-void video_set_default_colors(struct video_priv *priv);
+void video_set_default_colors(struct udevice *dev, bool invert);
 
 #endif /* CONFIG_DM_VIDEO */
 
diff --git a/lib/Kconfig b/lib/Kconfig
index 847e797..0333ab1 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -301,6 +301,14 @@
 	help
 	  This enables support for LZO compression algorithm.r
 
+config SPL_LZ4
+	bool "Enable LZ4 decompression support in SPL"
+	help
+	  This enables support for tge LZ4 decompression algorithm in SPL. LZ4
+	  is a lossless data compression algorithm that is focused on
+	  fast compression and decompression speed. It belongs to the LZ77
+	  family of byte-oriented compression schemes.
+
 config SPL_LZO
 	bool "Enable LZO decompression support in SPL"
 	help
diff --git a/lib/Makefile b/lib/Makefile
index fb69441..8321355 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -8,7 +8,7 @@
 obj-$(CONFIG_EFI) += efi/
 obj-$(CONFIG_EFI_LOADER) += efi_driver/
 obj-$(CONFIG_EFI_LOADER) += efi_loader/
-obj-$(CONFIG_EFI_LOADER) += efi_selftest/
+obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += efi_selftest/
 obj-$(CONFIG_LZMA) += lzma/
 obj-$(CONFIG_BZIP2) += bzip2/
 obj-$(CONFIG_TIZEN) += tizen/
@@ -38,7 +38,6 @@
 obj-y += initcall.o
 obj-$(CONFIG_LMB) += lmb.o
 obj-y += ldiv.o
-obj-$(CONFIG_LZ4) += lz4_wrapper.o
 obj-$(CONFIG_MD5) += md5.o
 obj-y += net_utils.o
 obj-$(CONFIG_PHYSMEM) += physmem.o
@@ -64,6 +63,7 @@
 obj-$(CONFIG_$(SPL_)ZLIB) += zlib/
 obj-$(CONFIG_$(SPL_)GZIP) += gunzip.o
 obj-$(CONFIG_$(SPL_)LZO) += lzo/
+obj-$(CONFIG_$(SPL_)LZ4) += lz4_wrapper.o
 
 obj-$(CONFIG_LIBAVB) += libavb/
 
diff --git a/lib/efi/efi.c b/lib/efi/efi.c
index c6639f9..2c6a508 100644
--- a/lib/efi/efi.c
+++ b/lib/efi/efi.c
@@ -69,7 +69,7 @@
 	efi_putc(priv, ' ');
 
 	ret = boot->open_protocol(priv->parent_image, &loaded_image_guid,
-				  (void **)&loaded_image, &priv->parent_image,
+				  (void **)&loaded_image, priv->parent_image,
 				  NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
 	if (ret) {
 		efi_puts(priv, "Failed to get loaded image protocol\n");
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index 0c5764d..a095df3 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- *  EFI utils
+ *  EFI boot manager
  *
  *  Copyright (c) 2017 Rob Clark
  */
@@ -9,6 +9,7 @@
 #include <charset.h>
 #include <malloc.h>
 #include <efi_loader.h>
+#include <asm/unaligned.h>
 
 static const struct efi_boot_services *bs;
 static const struct efi_runtime_services *rs;
@@ -30,42 +31,68 @@
  */
 
 
+/* Parse serialized data and transform it into efi_load_option structure */
+void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data)
+{
+	lo->attributes = get_unaligned_le32(data);
+	data += sizeof(u32);
+
+	lo->file_path_length = get_unaligned_le16(data);
+	data += sizeof(u16);
+
+	/* FIXME */
+	lo->label = (u16 *)data;
+	data += (u16_strlen(lo->label) + 1) * sizeof(u16);
+
+	/* FIXME */
+	lo->file_path = (struct efi_device_path *)data;
+	data += lo->file_path_length;
+
+	lo->optional_data = data;
+}
+
 /*
- * See section 3.1.3 in the v2.7 UEFI spec for more details on
- * the layout of EFI_LOAD_OPTION.  In short it is:
- *
- *    typedef struct _EFI_LOAD_OPTION {
- *        UINT32 Attributes;
- *        UINT16 FilePathListLength;
- *        // CHAR16 Description[];   <-- variable length, NULL terminated
- *        // EFI_DEVICE_PATH_PROTOCOL FilePathList[];  <-- FilePathListLength bytes
- *        // UINT8 OptionalData[];
- *    } EFI_LOAD_OPTION;
+ * Serialize efi_load_option structure into byte stream for BootXXXX.
+ * Return a size of allocated data.
  */
-struct load_option {
-	u32 attributes;
-	u16 file_path_length;
-	u16 *label;
-	struct efi_device_path *file_path;
-	u8 *optional_data;
-};
-
-/* parse an EFI_LOAD_OPTION, as described above */
-static void parse_load_option(struct load_option *lo, void *ptr)
+unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data)
 {
-	lo->attributes = *(u32 *)ptr;
-	ptr += sizeof(u32);
+	unsigned long label_len, option_len;
+	unsigned long size;
+	u8 *p;
+
+	label_len = (u16_strlen(lo->label) + 1) * sizeof(u16);
+	option_len = strlen((char *)lo->optional_data);
 
-	lo->file_path_length = *(u16 *)ptr;
-	ptr += sizeof(u16);
+	/* total size */
+	size = sizeof(lo->attributes);
+	size += sizeof(lo->file_path_length);
+	size += label_len;
+	size += lo->file_path_length;
+	size += option_len + 1;
+	p = malloc(size);
+	if (!p)
+		return 0;
 
-	lo->label = ptr;
-	ptr += (u16_strlen(lo->label) + 1) * 2;
+	/* copy data */
+	*data = p;
+	memcpy(p, &lo->attributes, sizeof(lo->attributes));
+	p += sizeof(lo->attributes);
 
-	lo->file_path = ptr;
-	ptr += lo->file_path_length;
+	memcpy(p, &lo->file_path_length, sizeof(lo->file_path_length));
+	p += sizeof(lo->file_path_length);
 
-	lo->optional_data = ptr;
+	memcpy(p, lo->label, label_len);
+	p += label_len;
+
+	memcpy(p, lo->file_path, lo->file_path_length);
+	p += lo->file_path_length;
+
+	memcpy(p, lo->optional_data, option_len);
+	p += option_len;
+	*(char *)p = '\0';
+
+	return size;
 }
 
 /* free() the result */
@@ -100,7 +127,7 @@
 static void *try_load_entry(uint16_t n, struct efi_device_path **device_path,
 			    struct efi_device_path **file_path)
 {
-	struct load_option lo;
+	struct efi_load_option lo;
 	u16 varname[] = L"Boot0000";
 	u16 hexmap[] = L"0123456789ABCDEF";
 	void *load_option, *image = NULL;
@@ -115,7 +142,7 @@
 	if (!load_option)
 		return NULL;
 
-	parse_load_option(&lo, load_option);
+	efi_deserialize_load_option(&lo, load_option);
 
 	if (lo.attributes & LOAD_OPTION_ACTIVE) {
 		efi_status_t ret;
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index da978d2..cc9efbb 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -26,6 +26,14 @@
 /* List of all events */
 LIST_HEAD(efi_events);
 
+/*
+ * If we're running on nasty systems (32bit ARM booting into non-EFI Linux)
+ * we need to do trickery with caches. Since we don't want to break the EFI
+ * aware boot path, only apply hacks when loading exiting directly (breaking
+ * direct Linux EFI booting along the way - oh well).
+ */
+static bool efi_is_direct_boot = true;
+
 #ifdef CONFIG_ARM
 /*
  * The "gd" pointer lives in a register on ARM and AArch64 that we declare
@@ -416,13 +424,12 @@
  *
  * The protocols list is initialized. The object handle is set.
  */
-void efi_add_handle(struct efi_object *obj)
+void efi_add_handle(efi_handle_t handle)
 {
-	if (!obj)
+	if (!handle)
 		return;
-	INIT_LIST_HEAD(&obj->protocols);
-	obj->handle = obj;
-	list_add_tail(&obj->link, &efi_obj_list);
+	INIT_LIST_HEAD(&handle->protocols);
+	list_add_tail(&handle->link, &efi_obj_list);
 }
 
 /**
@@ -440,7 +447,7 @@
 		return EFI_OUT_OF_RESOURCES;
 
 	efi_add_handle(obj);
-	*handle = obj->handle;
+	*handle = obj;
 
 	return EFI_SUCCESS;
 }
@@ -536,13 +543,13 @@
  *
  * @obj: handle to delete
  */
-void efi_delete_handle(struct efi_object *obj)
+void efi_delete_handle(efi_handle_t handle)
 {
-	if (!obj)
+	if (!handle)
 		return;
-	efi_remove_all_protocols(obj->handle);
-	list_del(&obj->link);
-	free(obj);
+	efi_remove_all_protocols(handle);
+	list_del(&handle->link);
+	free(handle);
 }
 
 /**
@@ -927,7 +934,7 @@
 	struct efi_object *efiobj;
 
 	list_for_each_entry(efiobj, &efi_obj_list, link) {
-		if (efiobj->handle == handle)
+		if (efiobj == handle)
 			return efiobj;
 	}
 
@@ -1019,7 +1026,7 @@
  * Return: status code
  */
 static efi_status_t EFIAPI efi_install_protocol_interface(
-			void **handle, const efi_guid_t *protocol,
+			efi_handle_t *handle, const efi_guid_t *protocol,
 			int protocol_interface_type, void *protocol_interface)
 {
 	efi_status_t r;
@@ -1052,7 +1059,7 @@
 
 /**
  * efi_get_drivers() - get all drivers associated to a controller
- * @efiobj:               handle of the controller
+ * @handle:               handle of the controller
  * @protocol:             protocol GUID (optional)
  * @number_of_drivers:    number of child controllers
  * @driver_handle_buffer: handles of the the drivers
@@ -1061,7 +1068,7 @@
  *
  * Return: status code
  */
-static efi_status_t efi_get_drivers(struct efi_object *efiobj,
+static efi_status_t efi_get_drivers(efi_handle_t handle,
 				    const efi_guid_t *protocol,
 				    efi_uintn_t *number_of_drivers,
 				    efi_handle_t **driver_handle_buffer)
@@ -1072,7 +1079,7 @@
 	bool duplicate;
 
 	/* Count all driver associations */
-	list_for_each_entry(handler, &efiobj->protocols, link) {
+	list_for_each_entry(handler, &handle->protocols, link) {
 		if (protocol && guidcmp(handler->guid, protocol))
 			continue;
 		list_for_each_entry(item, &handler->open_infos, link) {
@@ -1090,7 +1097,7 @@
 	if (!*driver_handle_buffer)
 		return EFI_OUT_OF_RESOURCES;
 	/* Collect unique driver handles */
-	list_for_each_entry(handler, &efiobj->protocols, link) {
+	list_for_each_entry(handler, &handle->protocols, link) {
 		if (protocol && guidcmp(handler->guid, protocol))
 			continue;
 		list_for_each_entry(item, &handler->open_infos, link) {
@@ -1117,7 +1124,7 @@
 
 /**
  * efi_disconnect_all_drivers() - disconnect all drivers from a controller
- * @efiobj:       handle of the controller
+ * @handle:       handle of the controller
  * @protocol:     protocol GUID (optional)
  * @child_handle: handle of the child to destroy
  *
@@ -1128,16 +1135,16 @@
  *
  * Return: status code
  */
-static efi_status_t efi_disconnect_all_drivers(
-				struct efi_object *efiobj,
-				const efi_guid_t *protocol,
-				efi_handle_t child_handle)
+static efi_status_t efi_disconnect_all_drivers
+				(efi_handle_t handle,
+				 const efi_guid_t *protocol,
+				 efi_handle_t child_handle)
 {
 	efi_uintn_t number_of_drivers;
 	efi_handle_t *driver_handle_buffer;
 	efi_status_t r, ret;
 
-	ret = efi_get_drivers(efiobj, protocol, &number_of_drivers,
+	ret = efi_get_drivers(handle, protocol, &number_of_drivers,
 			      &driver_handle_buffer);
 	if (ret != EFI_SUCCESS)
 		return ret;
@@ -1145,7 +1152,7 @@
 	ret = EFI_NOT_FOUND;
 	while (number_of_drivers) {
 		r = EFI_CALL(efi_disconnect_controller(
-				efiobj->handle,
+				handle,
 				driver_handle_buffer[--number_of_drivers],
 				child_handle));
 		if (r == EFI_SUCCESS)
@@ -1156,21 +1163,19 @@
 }
 
 /**
- * efi_uninstall_protocol_interface() - uninstall protocol interface
+ * efi_uninstall_protocol() - uninstall protocol interface
+ *
  * @handle:             handle from which the protocol shall be removed
  * @protocol:           GUID of the protocol to be removed
  * @protocol_interface: interface to be removed
  *
- * This function implements the UninstallProtocolInterface service.
- *
- * See the Unified Extensible Firmware Interface (UEFI) specification for
- * details.
+ * This function DOES NOT delete a handle without installed protocol.
  *
  * Return: status code
  */
-static efi_status_t EFIAPI efi_uninstall_protocol_interface(
-				efi_handle_t handle, const efi_guid_t *protocol,
-				void *protocol_interface)
+static efi_status_t efi_uninstall_protocol
+			(efi_handle_t handle, const efi_guid_t *protocol,
+			 void *protocol_interface)
 {
 	struct efi_object *efiobj;
 	struct efi_handler *handler;
@@ -1178,8 +1183,6 @@
 	struct efi_open_protocol_info_item *pos;
 	efi_status_t r;
 
-	EFI_ENTRY("%p, %pUl, %p", handle, protocol, protocol_interface);
-
 	/* Check handle */
 	efiobj = efi_search_obj(handle);
 	if (!efiobj) {
@@ -1210,7 +1213,41 @@
 	}
 	r = efi_remove_protocol(handle, protocol, protocol_interface);
 out:
-	return EFI_EXIT(r);
+	return r;
+}
+
+/**
+ * efi_uninstall_protocol_interface() - uninstall protocol interface
+ * @handle:             handle from which the protocol shall be removed
+ * @protocol:           GUID of the protocol to be removed
+ * @protocol_interface: interface to be removed
+ *
+ * This function implements the UninstallProtocolInterface service.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ *
+ * Return: status code
+ */
+static efi_status_t EFIAPI efi_uninstall_protocol_interface
+			(efi_handle_t handle, const efi_guid_t *protocol,
+			 void *protocol_interface)
+{
+	efi_status_t ret;
+
+	EFI_ENTRY("%p, %pUl, %p", handle, protocol, protocol_interface);
+
+	ret = efi_uninstall_protocol(handle, protocol, protocol_interface);
+	if (ret != EFI_SUCCESS)
+		goto out;
+
+	/* If the last protocol has been removed, delete the handle. */
+	if (list_empty(&handle->protocols)) {
+		list_del(&handle->link);
+		free(handle);
+	}
+out:
+	return EFI_EXIT(ret);
 }
 
 /**
@@ -1240,7 +1277,7 @@
  * @search_type: selection criterion
  * @protocol:    GUID of the protocol
  * @search_key:  registration key
- * @efiobj:      handle
+ * @handle:      handle
  *
  * See the documentation of the LocateHandle service in the UEFI specification.
  *
@@ -1248,7 +1285,7 @@
  */
 static int efi_search(enum efi_locate_search_type search_type,
 		      const efi_guid_t *protocol, void *search_key,
-		      struct efi_object *efiobj)
+		      efi_handle_t handle)
 {
 	efi_status_t ret;
 
@@ -1259,7 +1296,7 @@
 		/* TODO: RegisterProtocolNotify is not implemented yet */
 		return -1;
 	case BY_PROTOCOL:
-		ret = efi_search_protocol(efiobj->handle, protocol, NULL);
+		ret = efi_search_protocol(handle, protocol, NULL);
 		return (ret != EFI_SUCCESS);
 	default:
 		/* Invalid search type */
@@ -1331,7 +1368,7 @@
 	/* Then fill the array */
 	list_for_each_entry(efiobj, &efi_obj_list, link) {
 		if (!efi_search(search_type, protocol, search_key, efiobj))
-			*buffer++ = efiobj->handle;
+			*buffer++ = efiobj;
 	}
 
 	return EFI_SUCCESS;
@@ -1489,7 +1526,7 @@
 	}
 
 	/* Add internal object to object list */
-	efi_add_handle(&obj->parent);
+	efi_add_handle(&obj->header);
 
 	if (info_ptr)
 		*info_ptr = info;
@@ -1506,7 +1543,7 @@
 		 * When asking for the device path interface, return
 		 * bootefi_device_path
 		 */
-		ret = efi_add_protocol(obj->parent.handle,
+		ret = efi_add_protocol(&obj->header,
 				       &efi_guid_device_path, device_path);
 		if (ret != EFI_SUCCESS)
 			goto failure;
@@ -1516,7 +1553,7 @@
 	 * When asking for the loaded_image interface, just
 	 * return handle which points to loaded_image_info
 	 */
-	ret = efi_add_protocol(obj->parent.handle,
+	ret = efi_add_protocol(&obj->header,
 			       &efi_guid_loaded_image, info);
 	if (ret != EFI_SUCCESS)
 		goto failure;
@@ -1678,6 +1715,8 @@
 
 	EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
 
+	efi_is_direct_boot = false;
+
 	/* call the image! */
 	if (setjmp(&image_obj->exit_jmp)) {
 		/*
@@ -1786,6 +1825,21 @@
 }
 
 /**
+ * efi_exit_caches() - fix up caches for EFI payloads if necessary
+ */
+static void efi_exit_caches(void)
+{
+#if defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
+	/*
+	 * Grub on 32bit ARM needs to have caches disabled before jumping into
+	 * a zImage, but does not know of all cache layers. Give it a hand.
+	 */
+	if (efi_is_direct_boot)
+		cleanup_before_linux();
+#endif
+}
+
+/**
  * efi_exit_boot_services() - stop all boot services
  * @image_handle: handle of the loaded image
  * @map_key:      key of the memory map
@@ -1838,6 +1892,9 @@
 
 	board_quiesce_devices();
 
+	/* Fix up caches for EFI payloads if necessary */
+	efi_exit_caches();
+
 	/* This stops all lingering devices */
 	bootm_disable_interrupts();
 
@@ -2176,7 +2233,7 @@
 
 		efiobj = list_entry(lhandle, struct efi_object, link);
 
-		ret = efi_search_protocol(efiobj->handle, protocol, &handler);
+		ret = efi_search_protocol(efiobj, protocol, &handler);
 		if (ret == EFI_SUCCESS) {
 			*protocol_interface = handler->protocol_interface;
 			return EFI_EXIT(EFI_SUCCESS);
@@ -2279,8 +2336,8 @@
  *
  * Return: status code
  */
-static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(
-			void **handle, ...)
+static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces
+				(efi_handle_t *handle, ...)
 {
 	EFI_ENTRY("%p", handle);
 
@@ -2316,7 +2373,7 @@
 	for (; i; --i) {
 		protocol = efi_va_arg(argptr, efi_guid_t*);
 		protocol_interface = efi_va_arg(argptr, void*);
-		EFI_CALL(efi_uninstall_protocol_interface(handle, protocol,
+		EFI_CALL(efi_uninstall_protocol_interface(*handle, protocol,
 							  protocol_interface));
 	}
 	efi_va_end(argptr);
@@ -2339,7 +2396,7 @@
  * Return: status code
  */
 static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
-			void *handle, ...)
+			efi_handle_t handle, ...)
 {
 	EFI_ENTRY("%p", handle);
 
@@ -2358,16 +2415,21 @@
 		if (!protocol)
 			break;
 		protocol_interface = efi_va_arg(argptr, void*);
-		r = EFI_CALL(efi_uninstall_protocol_interface(
-						handle, protocol,
-						protocol_interface));
+		r = efi_uninstall_protocol(handle, protocol,
+					   protocol_interface);
 		if (r != EFI_SUCCESS)
 			break;
 		i++;
 	}
 	efi_va_end(argptr);
-	if (r == EFI_SUCCESS)
+	if (r == EFI_SUCCESS) {
+		/* If the last protocol has been removed, delete the handle. */
+		if (list_empty(&handle->protocols)) {
+			list_del(&handle->link);
+			free(handle);
+		}
 		return EFI_EXIT(r);
+	}
 
 	/* If an error occurred undo all changes. */
 	efi_va_start(argptr, handle);
@@ -2380,7 +2442,8 @@
 	}
 	efi_va_end(argptr);
 
-	return EFI_EXIT(r);
+	/* In case of an error always return EFI_INVALID_PARAMETER */
+	return EFI_EXIT(EFI_INVALID_PARAMETER);
 }
 
 /**
@@ -2553,10 +2616,10 @@
  *
  * Return: status code
  */
-static efi_status_t EFIAPI efi_open_protocol(
-			void *handle, const efi_guid_t *protocol,
-			void **protocol_interface, void *agent_handle,
-			void *controller_handle, uint32_t attributes)
+static efi_status_t EFIAPI efi_open_protocol
+			(efi_handle_t handle, const efi_guid_t *protocol,
+			 void **protocol_interface, efi_handle_t agent_handle,
+			 efi_handle_t controller_handle, uint32_t attributes)
 {
 	struct efi_handler *handler;
 	efi_status_t r = EFI_INVALID_PARAMETER;
@@ -2828,13 +2891,19 @@
 
 	EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, old_interface,
 		  new_interface);
-	ret = EFI_CALL(efi_uninstall_protocol_interface(handle, protocol,
-							old_interface));
+
+	/* Uninstall protocol but do not delete handle */
+	ret = efi_uninstall_protocol(handle, protocol, old_interface);
 	if (ret != EFI_SUCCESS)
 		goto out;
-	ret = EFI_CALL(efi_install_protocol_interface(&handle, protocol,
-						      EFI_NATIVE_INTERFACE,
-						      new_interface));
+
+	/* Install the new protocol */
+	ret = efi_add_protocol(handle, protocol, new_interface);
+	/*
+	 * The UEFI spec does not specify what should happen to the handle
+	 * if in case of an error no protocol interface remains on the handle.
+	 * So let's do nothing here.
+	 */
 	if (ret != EFI_SUCCESS)
 		goto out;
 	/*
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index 0225222..66c33a5 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -205,7 +205,7 @@
 	/*
 	 * Not all terminals understand CSI [18t for querying the console size.
 	 * We should adhere to escape sequences documented in the console_codes
-	 * manpage and the ECMA-48 standard.
+	 * man page and the ECMA-48 standard.
 	 *
 	 * So here we follow a different approach. We position the cursor to the
 	 * bottom right and query its position. Before leaving the function we
@@ -480,7 +480,7 @@
  *
  * This gets called when we have already parsed CSI.
  *
- * @modifiers:  bitmask (shift, alt, ctrl)
+ * @modifiers:  bit mask (shift, alt, ctrl)
  * @return:	the unmodified code
  */
 static int analyze_modifiers(struct efi_key_state *key_state)
@@ -1051,34 +1051,34 @@
 efi_status_t efi_console_register(void)
 {
 	efi_status_t r;
-	struct efi_object *efi_console_output_obj;
-	struct efi_object *efi_console_input_obj;
+	efi_handle_t console_output_handle;
+	efi_handle_t console_input_handle;
 
 	/* Set up mode information */
 	query_console_size();
 
 	/* Create handles */
-	r = efi_create_handle((efi_handle_t *)&efi_console_output_obj);
+	r = efi_create_handle(&console_output_handle);
 	if (r != EFI_SUCCESS)
 		goto out_of_memory;
 
-	r = efi_add_protocol(efi_console_output_obj->handle,
+	r = efi_add_protocol(console_output_handle,
 			     &efi_guid_text_output_protocol, &efi_con_out);
 	if (r != EFI_SUCCESS)
 		goto out_of_memory;
-	systab.con_out_handle = efi_console_output_obj->handle;
-	systab.stderr_handle = efi_console_output_obj->handle;
+	systab.con_out_handle = console_output_handle;
+	systab.stderr_handle = console_output_handle;
 
-	r = efi_create_handle((efi_handle_t *)&efi_console_input_obj);
+	r = efi_create_handle(&console_input_handle);
 	if (r != EFI_SUCCESS)
 		goto out_of_memory;
 
-	r = efi_add_protocol(efi_console_input_obj->handle,
+	r = efi_add_protocol(console_input_handle,
 			     &efi_guid_text_input_protocol, &efi_con_in);
 	if (r != EFI_SUCCESS)
 		goto out_of_memory;
-	systab.con_in_handle = efi_console_input_obj->handle;
-	r = efi_add_protocol(efi_console_input_obj->handle,
+	systab.con_in_handle = console_input_handle;
+	r = efi_add_protocol(console_input_handle,
 			     &efi_guid_text_input_ex_protocol, &efi_con_in_ex);
 	if (r != EFI_SUCCESS)
 		goto out_of_memory;
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index 46a24f7..d949823 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -82,7 +82,7 @@
 
 /*
  * Compare two device-paths, stopping when the shorter of the two hits
- * an End* node.  This is useful to, for example, compare a device-path
+ * an End* node. This is useful to, for example, compare a device-path
  * representing a device with one representing a file on the device, or
  * a device with a parent device.
  */
@@ -109,16 +109,17 @@
 }
 
 /*
- * See UEFI spec (section 3.1.2, about short-form device-paths..
- * tl;dr: we can have a device-path that starts with a USB WWID
- * or USB Class node, and a few other cases which don't encode
- * the full device path with bus hierarchy:
+ * We can have device paths that start with a USB WWID or a USB Class node,
+ * and a few other cases which don't encode the full device path with bus
+ * hierarchy:
  *
  *   - MESSAGING:USB_WWID
  *   - MESSAGING:USB_CLASS
  *   - MEDIA:FILE_PATH
  *   - MEDIA:HARD_DRIVE
  *   - MESSAGING:URI
+ *
+ * See UEFI spec (section 3.1.2, about short-form device-paths)
  */
 static struct efi_device_path *shorten_path(struct efi_device_path *dp)
 {
@@ -150,7 +151,7 @@
 		struct efi_device_path *obj_dp;
 		efi_status_t ret;
 
-		ret = efi_search_protocol(efiobj->handle,
+		ret = efi_search_protocol(efiobj,
 					  &efi_guid_device_path, &handler);
 		if (ret != EFI_SUCCESS)
 			continue;
@@ -644,7 +645,7 @@
 /*
  * Create a device node for a block device partition.
  *
- * @buf		buffer to which the device path is wirtten
+ * @buf		buffer to which the device path is written
  * @desc	block device descriptor
  * @part	partition number, 0 identifies a block device
  */
@@ -709,7 +710,7 @@
 /*
  * Create a device path for a block device or one of its partitions.
  *
- * @buf		buffer to which the device path is wirtten
+ * @buf		buffer to which the device path is written
  * @desc	block device descriptor
  * @part	partition number, 0 identifies a block device
  */
@@ -728,7 +729,7 @@
 	/*
 	 * We *could* make a more accurate path, by looking at if_type
 	 * and handling all the different cases like we do for non-
-	 * legacy (ie CONFIG_BLK=y) case.  But most important thing
+	 * legacy (i.e. CONFIG_BLK=y) case. But most important thing
 	 * is just to have a unique device-path for if_type+devnum.
 	 * So map things to a fictitious USB device.
 	 */
@@ -752,7 +753,7 @@
 	return dp_part_node(buf, desc, part);
 }
 
-/* Construct a device-path from a partition on a blk device: */
+/* Construct a device-path from a partition on a block device: */
 struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part)
 {
 	void *buf, *start;
@@ -771,7 +772,7 @@
 /*
  * Create a device node for a block device partition.
  *
- * @buf		buffer to which the device path is wirtten
+ * @buf		buffer to which the device path is written
  * @desc	block device descriptor
  * @part	partition number, 0 identifies a block device
  */
@@ -791,7 +792,7 @@
 	return buf;
 }
 
-/* convert path to an UEFI style path (ie. DOS style backslashes and utf16) */
+/* convert path to an UEFI style path (i.e. DOS style backslashes and UTF-16) */
 static void path_to_uefi(u16 *uefi, const char *path)
 {
 	while (*path) {
@@ -941,3 +942,53 @@
 	*file_path = fp;
 	return EFI_SUCCESS;
 }
+
+efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
+			      const char *path,
+			      struct efi_device_path **device,
+			      struct efi_device_path **file)
+{
+	int is_net;
+	struct blk_desc *desc = NULL;
+	disk_partition_t fs_partition;
+	int part = 0;
+	char filename[32] = { 0 }; /* dp->str is u16[32] long */
+	char *s;
+
+	if (path && !file)
+		return EFI_INVALID_PARAMETER;
+
+	is_net = !strcmp(dev, "Net");
+	if (!is_net) {
+		part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition,
+					       1);
+		if (part < 0)
+			return EFI_INVALID_PARAMETER;
+
+		if (device)
+			*device = efi_dp_from_part(desc, part);
+	} else {
+#ifdef CONFIG_NET
+		if (device)
+			*device = efi_dp_from_eth();
+#endif
+	}
+
+	if (!path)
+		return EFI_SUCCESS;
+
+	if (!is_net) {
+		/* Add leading / to fs paths, because they're absolute */
+		snprintf(filename, sizeof(filename), "/%s", path);
+	} else {
+		snprintf(filename, sizeof(filename), "%s", path);
+	}
+	/* DOS style file path: */
+	s = filename;
+	while ((s = strchr(s, '/')))
+		*s++ = '\\';
+	*file = efi_dp_from_file(((!is_net && device) ? desc : NULL),
+				 part, filename);
+
+	return EFI_SUCCESS;
+}
diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c
index 0082236..e219f84 100644
--- a/lib/efi_loader/efi_device_path_to_text.c
+++ b/lib/efi_loader/efi_device_path_to_text.c
@@ -269,9 +269,9 @@
  * for details.
  *
  * device_node		device node to be converted
- * display_only		true if the shorter text represenation shall be used
+ * display_only		true if the shorter text representation shall be used
  * allow_shortcuts	true if shortcut forms may be used
- * @return		text represenation of the device path
+ * @return		text representation of the device path
  *			NULL if out of memory of device_path is NULL
  */
 static uint16_t EFIAPI *efi_convert_device_node_to_text(
@@ -302,9 +302,9 @@
  * for details.
  *
  * device_path		device path to be converted
- * display_only		true if the shorter text represenation shall be used
+ * display_only		true if the shorter text representation shall be used
  * allow_shortcuts	true if shortcut forms may be used
- * @return		text represenation of the device path
+ * @return		text representation of the device path
  *			NULL if out of memory of device_path is NULL
  */
 static uint16_t EFIAPI *efi_convert_device_path_to_text(
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 13fcc1b..c037526 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -14,26 +14,30 @@
 
 const efi_guid_t efi_block_io_guid = BLOCK_IO_GUID;
 
+/**
+ * struct efi_disk_obj - EFI disk object
+ *
+ * @header:	EFI object header
+ * @ops:	EFI disk I/O protocol interface
+ * @ifname:	interface name for block device
+ * @dev_index:	device index of block device
+ * @media:	block I/O media information
+ * @dp:		device path to the block device
+ * @part:	partition
+ * @volume:	simple file system protocol of the partition
+ * @offset:	offset into disk for simple partition
+ * @desc:	internal block device descriptor
+ */
 struct efi_disk_obj {
-	/* Generic EFI object parent class data */
-	struct efi_object parent;
-	/* EFI Interface callback struct for block I/O */
+	struct efi_object header;
 	struct efi_block_io ops;
-	/* U-Boot ifname for block device */
 	const char *ifname;
-	/* U-Boot dev_index for block device */
 	int dev_index;
-	/* EFI Interface Media descriptor struct, referenced by ops */
 	struct efi_block_io_media media;
-	/* EFI device path to this block device */
 	struct efi_device_path *dp;
-	/* partition # */
 	unsigned int part;
-	/* handle to filesys proto (for partition objects) */
 	struct efi_simple_file_system_protocol *volume;
-	/* Offset into disk for simple partitions */
 	lbaint_t offset;
-	/* Internal block device */
 	struct blk_desc *desc;
 };
 
@@ -246,7 +250,7 @@
 		return EFI_OUT_OF_RESOURCES;
 
 	/* Hook up to the device list */
-	efi_add_handle(&diskobj->parent);
+	efi_add_handle(&diskobj->header);
 
 	/* Fill in object data */
 	if (part) {
@@ -258,18 +262,18 @@
 		diskobj->dp = efi_dp_from_part(desc, part);
 	}
 	diskobj->part = part;
-	ret = efi_add_protocol(diskobj->parent.handle, &efi_block_io_guid,
+	ret = efi_add_protocol(&diskobj->header, &efi_block_io_guid,
 			       &diskobj->ops);
 	if (ret != EFI_SUCCESS)
 		return ret;
-	ret = efi_add_protocol(diskobj->parent.handle, &efi_guid_device_path,
+	ret = efi_add_protocol(&diskobj->header, &efi_guid_device_path,
 			       diskobj->dp);
 	if (ret != EFI_SUCCESS)
 		return ret;
 	if (part >= 1) {
 		diskobj->volume = efi_simple_file_system(desc, part,
 							 diskobj->dp);
-		ret = efi_add_protocol(diskobj->parent.handle,
+		ret = efi_add_protocol(&diskobj->header,
 				       &efi_simple_file_system_protocol_guid,
 				       diskobj->volume);
 		if (ret != EFI_SUCCESS)
@@ -381,7 +385,7 @@
 
 		/* Partitions show up as block devices in EFI */
 		disks += efi_disk_create_partitions(
-					disk->parent.handle, desc, if_typename,
+					&disk->header, desc, if_typename,
 					desc->devnum, dev->name);
 	}
 #else
@@ -426,9 +430,9 @@
 			disks++;
 
 			/* Partitions show up as block devices in EFI */
-			disks += efi_disk_create_partitions(
-						disk->parent.handle, desc,
-						if_typename, i, devname);
+			disks += efi_disk_create_partitions
+						(&disk->header, desc,
+						 if_typename, i, devname);
 		}
 	}
 #endif
diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c
index beb4fba..128cb0a 100644
--- a/lib/efi_loader/efi_file.c
+++ b/lib/efi_loader/efi_file.c
@@ -563,7 +563,7 @@
 		if (fh->isdir)
 			info->attribute |= EFI_FILE_DIRECTORY;
 
-		ascii2unicode((u16 *)info->file_name, filename);
+		ascii2unicode(info->file_name, filename);
 	} else if (!guidcmp(info_type, &efi_file_system_info_guid)) {
 		struct efi_file_system_info *info = buffer;
 		disk_partition_t part;
diff --git a/lib/efi_loader/efi_gop.c b/lib/efi_loader/efi_gop.c
index a4aa9bc..d62ce45 100644
--- a/lib/efi_loader/efi_gop.c
+++ b/lib/efi_loader/efi_gop.c
@@ -16,15 +16,22 @@
 
 static const efi_guid_t efi_gop_guid = EFI_GOP_GUID;
 
+/**
+ * struct efi_gop_obj - graphical output protocol object
+ *
+ * @header:	EFI object header
+ * @ops:	graphical output protocol interface
+ * @info:	graphical output mode information
+ * @mode:	graphical output mode
+ * @bpix:	bits per pixel
+ * @fb:		frame buffer
+ */
 struct efi_gop_obj {
-	/* Generic EFI object parent class data */
-	struct efi_object parent;
-	/* EFI Interface callback struct for gop */
+	struct efi_object header;
 	struct efi_gop ops;
-	/* The only mode we support */
 	struct efi_gop_mode_info info;
 	struct efi_gop_mode mode;
-	/* Fields we only have acces to during init */
+	/* Fields we only have access to during init */
 	u32 bpix;
 	void *fb;
 };
@@ -236,12 +243,12 @@
 }
 
 /*
- * Gcc can't optimize our BLT function well, but we need to make sure that
+ * GCC can't optimize our BLT function well, but we need to make sure that
  * our 2-dimensional loop gets executed very quickly, otherwise the system
  * will feel slow.
  *
  * By manually putting all obvious branch targets into functions which call
- * our generic blt function with constants, the compiler can successfully
+ * our generic BLT function with constants, the compiler can successfully
  * optimize for speed.
  */
 static efi_status_t gop_blt_video_fill(struct efi_gop *this,
@@ -439,13 +446,13 @@
 	}
 
 	/* Hook up to the device list */
-	efi_add_handle(&gopobj->parent);
+	efi_add_handle(&gopobj->header);
 
 	/* Fill in object data */
-	ret = efi_add_protocol(gopobj->parent.handle, &efi_gop_guid,
+	ret = efi_add_protocol(&gopobj->header, &efi_gop_guid,
 			       &gopobj->ops);
 	if (ret != EFI_SUCCESS) {
-		printf("ERROR: Failure adding gop protocol\n");
+		printf("ERROR: Failure adding GOP protocol\n");
 		return ret;
 	}
 	gopobj->ops.query_mode = gop_query_mode;
@@ -463,7 +470,10 @@
 	if (bpix == LCD_COLOR32)
 #endif
 	{
-		/* With 32bit color space we can directly expose the fb */
+		/*
+		 * With 32bit color space we can directly expose the frame
+		 * buffer
+		 */
 		gopobj->mode.fb_base = fb_base;
 		gopobj->mode.fb_size = fb_size;
 	}
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index 5bd4f4d..4bb5174 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -11,6 +11,7 @@
 #include <mapmem.h>
 #include <watchdog.h>
 #include <linux/list_sort.h>
+#include <linux/sizes.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -294,6 +295,12 @@
 {
 	struct list_head *lhandle;
 
+	/*
+	 * Prealign input max address, so we simplify our matching
+	 * logic below and can just reuse it as return pointer.
+	 */
+	max_addr &= ~EFI_PAGE_MASK;
+
 	list_for_each(lhandle, &efi_mem) {
 		struct efi_mem_list *lmem = list_entry(lhandle,
 			struct efi_mem_list, link);
@@ -378,7 +385,7 @@
 		/* Reserve that map in our memory maps */
 		ret = efi_add_memory_map(addr, pages, memory_type, true);
 		if (ret == addr) {
-			*memory = (uintptr_t)map_sysmem(addr, len);
+			*memory = addr;
 		} else {
 			/* Map would overlap, bail out */
 			r = EFI_OUT_OF_RESOURCES;
@@ -391,7 +398,7 @@
 void *efi_alloc(uint64_t len, int memory_type)
 {
 	uint64_t ret = 0;
-	uint64_t pages = (len + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
+	uint64_t pages = efi_size_in_pages(len);
 	efi_status_t r;
 
 	r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, memory_type, pages,
@@ -412,12 +419,11 @@
 efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
 {
 	uint64_t r = 0;
-	uint64_t addr = map_to_sysmem((void *)(uintptr_t)memory);
 
-	r = efi_add_memory_map(addr, pages, EFI_CONVENTIONAL_MEMORY, false);
+	r = efi_add_memory_map(memory, pages, EFI_CONVENTIONAL_MEMORY, false);
 	/* Merging of adjacent free regions is missing */
 
-	if (r == addr)
+	if (r == memory)
 		return EFI_SUCCESS;
 
 	return EFI_NOT_FOUND;
@@ -435,8 +441,8 @@
 {
 	efi_status_t r;
 	struct efi_pool_allocation *alloc;
-	u64 num_pages = (size + sizeof(struct efi_pool_allocation) +
-			 EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
+	u64 num_pages = efi_size_in_pages(size +
+					  sizeof(struct efi_pool_allocation));
 
 	if (!buffer)
 		return EFI_INVALID_PARAMETER;
@@ -545,17 +551,51 @@
 
 __weak void efi_add_known_memory(void)
 {
+	u64 ram_top = board_get_usable_ram_top(0) & ~EFI_PAGE_MASK;
 	int i;
 
+	/* Fix for 32bit targets with ram_top at 4G */
+	if (!ram_top)
+		ram_top = 0x100000000ULL;
+
 	/* Add RAM */
 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
-		u64 ram_start = gd->bd->bi_dram[i].start;
-		u64 ram_size = gd->bd->bi_dram[i].size;
-		u64 start = (ram_start + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
-		u64 pages = (ram_size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
+		u64 ram_end, ram_start, pages;
+
+		ram_start = (uintptr_t)map_sysmem(gd->bd->bi_dram[i].start, 0);
+		ram_end = ram_start + gd->bd->bi_dram[i].size;
+
+		/* Remove partial pages */
+		ram_end &= ~EFI_PAGE_MASK;
+		ram_start = (ram_start + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
+
+		if (ram_end <= ram_start) {
+			/* Invalid mapping, keep going. */
+			continue;
+		}
+
+		pages = (ram_end - ram_start) >> EFI_PAGE_SHIFT;
+
+		efi_add_memory_map(ram_start, pages,
+				   EFI_CONVENTIONAL_MEMORY, false);
 
-		efi_add_memory_map(start, pages, EFI_CONVENTIONAL_MEMORY,
-				   false);
+		/*
+		 * Boards may indicate to the U-Boot memory core that they
+		 * can not support memory above ram_top. Let's honor this
+		 * in the efi_loader subsystem too by declaring any memory
+		 * above ram_top as "already occupied by firmware".
+		 */
+		if (ram_top < ram_start) {
+			/* ram_top is before this region, reserve all */
+			efi_add_memory_map(ram_start, pages,
+					   EFI_BOOT_SERVICES_DATA, true);
+		} else if ((ram_top >= ram_start) && (ram_top < ram_end)) {
+			/* ram_top is inside this region, reserve parts */
+			pages = (ram_end - ram_top) >> EFI_PAGE_SHIFT;
+
+			efi_add_memory_map(ram_top, pages,
+					   EFI_BOOT_SERVICES_DATA, true);
+		}
 	}
 }
 
@@ -563,6 +603,7 @@
 static void add_u_boot_and_runtime(void)
 {
 	unsigned long runtime_start, runtime_end, runtime_pages;
+	unsigned long runtime_mask = EFI_PAGE_MASK;
 	unsigned long uboot_start, uboot_pages;
 	unsigned long uboot_stack_size = 16 * 1024 * 1024;
 
@@ -571,10 +612,22 @@
 	uboot_pages = (gd->ram_top - uboot_start) >> EFI_PAGE_SHIFT;
 	efi_add_memory_map(uboot_start, uboot_pages, EFI_LOADER_DATA, false);
 
-	/* Add Runtime Services */
-	runtime_start = (ulong)&__efi_runtime_start & ~EFI_PAGE_MASK;
+#if defined(__aarch64__)
+	/*
+	 * Runtime Services must be 64KiB aligned according to the
+	 * "AArch64 Platforms" section in the UEFI spec (2.7+).
+	 */
+
+	runtime_mask = SZ_64K - 1;
+#endif
+
+	/*
+	 * Add Runtime Services. We mark surrounding boottime code as runtime as
+	 * well to fulfill the runtime alignment constraints but avoid padding.
+	 */
+	runtime_start = (ulong)&__efi_runtime_start & ~runtime_mask;
 	runtime_end = (ulong)&__efi_runtime_stop;
-	runtime_end = (runtime_end + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
+	runtime_end = (runtime_end + runtime_mask) & ~runtime_mask;
 	runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT;
 	efi_add_memory_map(runtime_start, runtime_pages,
 			   EFI_RUNTIME_SERVICES_CODE, false);
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index 4e8b2d5..c7d9da8 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -14,6 +14,8 @@
 static struct efi_pxe_packet *dhcp_ack;
 static bool new_rx_packet;
 static void *new_tx_packet;
+static void *transmit_buffer;
+
 /*
  * The notification function of this event is called in every timer cycle
  * to check if a new network packet has been received.
@@ -24,33 +26,85 @@
  */
 static struct efi_event *wait_for_packet;
 
+/**
+ * struct efi_net_obj - EFI object representing a network interface
+ *
+ * @header:	EFI object header
+ * @net:	simple network protocol interface
+ * @net_mode:	status of the network interface
+ * @pxe:	PXE base code protocol interface
+ * @pxe_mode:	status of the PXE base code protocol
+ */
 struct efi_net_obj {
-	/* Generic EFI object parent class data */
-	struct efi_object parent;
-	/* EFI Interface callback struct for network */
+	struct efi_object header;
 	struct efi_simple_network net;
 	struct efi_simple_network_mode net_mode;
-	/* PXE struct to transmit dhcp data */
 	struct efi_pxe pxe;
 	struct efi_pxe_mode pxe_mode;
 };
 
+/*
+ * efi_net_start() - start the network interface
+ *
+ * This function implements the Start service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:	pointer to the protocol instance
+ * Return:	status code
+ */
 static efi_status_t EFIAPI efi_net_start(struct efi_simple_network *this)
 {
+	efi_status_t ret = EFI_SUCCESS;
+
 	EFI_ENTRY("%p", this);
 
+	/* Check parameters */
+	if (!this) {
+		ret = EFI_INVALID_PARAMETER;
+		goto out;
+	}
+
-	return EFI_EXIT(EFI_SUCCESS);
+	if (this->mode->state != EFI_NETWORK_STOPPED)
+		ret = EFI_ALREADY_STARTED;
+	else
+		this->mode->state = EFI_NETWORK_STARTED;
+out:
+	return EFI_EXIT(ret);
 }
 
+/*
+ * efi_net_stop() - stop the network interface
+ *
+ * This function implements the Stop service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:	pointer to the protocol instance
+ * Return:	status code
+ */
 static efi_status_t EFIAPI efi_net_stop(struct efi_simple_network *this)
 {
+	efi_status_t ret = EFI_SUCCESS;
+
 	EFI_ENTRY("%p", this);
 
-	return EFI_EXIT(EFI_SUCCESS);
+	/* Check parameters */
+	if (!this) {
+		ret = EFI_INVALID_PARAMETER;
+		goto out;
+	}
+
+	if (this->mode->state == EFI_NETWORK_STOPPED)
+		ret = EFI_NOT_STARTED;
+	else
+		this->mode->state = EFI_NETWORK_STOPPED;
+out:
+	return EFI_EXIT(ret);
 }
 
 /*
- * Initialize network adapter and allocate transmit and receive buffers.
+ * efi_net_initialize() - initialize the network interface
  *
  * This function implements the Initialize service of the
  * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
@@ -59,7 +113,7 @@
  * @this:	pointer to the protocol instance
  * @extra_rx:	extra receive buffer to be allocated
  * @extra_tx:	extra transmit buffer to be allocated
- * @return:	status code
+ * Return:	status code
  */
 static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this,
 					      ulong extra_rx, ulong extra_tx)
@@ -69,9 +123,10 @@
 
 	EFI_ENTRY("%p, %lx, %lx", this, extra_rx, extra_tx);
 
+	/* Check parameters */
 	if (!this) {
 		r = EFI_INVALID_PARAMETER;
-		goto error;
+		goto out;
 	}
 
 	/* Setup packet buffers */
@@ -84,32 +139,83 @@
 	ret = eth_init();
 	if (ret < 0) {
 		eth_halt();
+		this->mode->state = EFI_NETWORK_STOPPED;
 		r = EFI_DEVICE_ERROR;
+		goto out;
+	} else {
+		this->mode->state = EFI_NETWORK_INITIALIZED;
 	}
-
-error:
+out:
 	return EFI_EXIT(r);
 }
 
+/*
+ * efi_net_reset() - reinitialize the network interface
+ *
+ * This function implements the Reset service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:			pointer to the protocol instance
+ * @extended_verification:	execute exhaustive verification
+ * Return:			status code
+ */
 static efi_status_t EFIAPI efi_net_reset(struct efi_simple_network *this,
 					 int extended_verification)
 {
 	EFI_ENTRY("%p, %x", this, extended_verification);
 
-	return EFI_EXIT(EFI_SUCCESS);
+	return EFI_EXIT(EFI_CALL(efi_net_initialize(this, 0, 0)));
 }
 
+/*
+ * efi_net_shutdown() - shut down the network interface
+ *
+ * This function implements the Shutdown service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:	pointer to the protocol instance
+ * Return:	status code
+ */
 static efi_status_t EFIAPI efi_net_shutdown(struct efi_simple_network *this)
 {
+	efi_status_t ret = EFI_SUCCESS;
+
 	EFI_ENTRY("%p", this);
 
+	/* Check parameters */
+	if (!this) {
+		ret = EFI_INVALID_PARAMETER;
+		goto out;
+	}
+
-	return EFI_EXIT(EFI_SUCCESS);
+	eth_halt();
+	this->mode->state = EFI_NETWORK_STOPPED;
+
+out:
+	return EFI_EXIT(ret);
 }
 
-static efi_status_t EFIAPI efi_net_receive_filters(
-		struct efi_simple_network *this, u32 enable, u32 disable,
-		int reset_mcast_filter, ulong mcast_filter_count,
-		struct efi_mac_address *mcast_filter)
+/*
+ * efi_net_receive_filters() - mange multicast receive filters
+ *
+ * This function implements the ReceiveFilters service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:		pointer to the protocol instance
+ * @enable:		bit mask of receive filters to enable
+ * @disable:		bit mask of receive filters to disable
+ * @reset_mcast_filter:	true resets contents of the filters
+ * @mcast_filter_count:	number of hardware MAC addresses in the new filters list
+ * @mcast_filter:	list of new filters
+ * Return:		status code
+ */
+static efi_status_t EFIAPI efi_net_receive_filters
+		(struct efi_simple_network *this, u32 enable, u32 disable,
+		 int reset_mcast_filter, ulong mcast_filter_count,
+		 struct efi_mac_address *mcast_filter)
 {
 	EFI_ENTRY("%p, %x, %x, %x, %lx, %p", this, enable, disable,
 		  reset_mcast_filter, mcast_filter_count, mcast_filter);
@@ -117,15 +223,40 @@
 	return EFI_EXIT(EFI_UNSUPPORTED);
 }
 
-static efi_status_t EFIAPI efi_net_station_address(
-		struct efi_simple_network *this, int reset,
-		struct efi_mac_address *new_mac)
+/*
+ * efi_net_station_address() - set the hardware MAC address
+ *
+ * This function implements the StationAddress service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:	pointer to the protocol instance
+ * @reset:	if true reset the address to default
+ * @new_mac:	new MAC address
+ * Return:	status code
+ */
+static efi_status_t EFIAPI efi_net_station_address
+		(struct efi_simple_network *this, int reset,
+		 struct efi_mac_address *new_mac)
 {
 	EFI_ENTRY("%p, %x, %p", this, reset, new_mac);
 
 	return EFI_EXIT(EFI_UNSUPPORTED);
 }
 
+/*
+ * efi_net_statistics() - reset or collect statistics of the network interface
+ *
+ * This function implements the Statistics service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:	pointer to the protocol instance
+ * @reset:	if true, the statistics are reset
+ * @stat_size:	size of the statistics table
+ * @stat_table:	table to receive the statistics
+ * Return:	status code
+ */
 static efi_status_t EFIAPI efi_net_statistics(struct efi_simple_network *this,
 					      int reset, ulong *stat_size,
 					      void *stat_table)
@@ -135,6 +266,19 @@
 	return EFI_EXIT(EFI_UNSUPPORTED);
 }
 
+/*
+ * efi_net_mcastiptomac() - translate multicast IP address to MAC address
+ *
+ * This function implements the Statistics service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:	pointer to the protocol instance
+ * @ipv6:	true if the IP address is an IPv6 address
+ * @ip:		IP address
+ * @mac:	MAC address
+ * Return:	status code
+ */
 static efi_status_t EFIAPI efi_net_mcastiptomac(struct efi_simple_network *this,
 						int ipv6,
 						struct efi_ip_address *ip,
@@ -145,6 +289,19 @@
 	return EFI_EXIT(EFI_INVALID_PARAMETER);
 }
 
+/**
+ * efi_net_nvdata() - read or write NVRAM
+ *
+ * This function implements the GetStatus service of the Simple Network
+ * Protocol. See the UEFI spec for details.
+ *
+ * @this:		the instance of the Simple Network Protocol
+ * @readwrite:		true for read, false for write
+ * @offset:		offset in NVRAM
+ * @buffer_size:	size of buffer
+ * @buffer:		buffer
+ * Return:		status code
+ */
 static efi_status_t EFIAPI efi_net_nvdata(struct efi_simple_network *this,
 					  int read_write, ulong offset,
 					  ulong buffer_size, char *buffer)
@@ -155,13 +312,42 @@
 	return EFI_EXIT(EFI_UNSUPPORTED);
 }
 
+/**
+ * efi_net_get_status() - get interrupt status
+ *
+ * This function implements the GetStatus service of the Simple Network
+ * Protocol. See the UEFI spec for details.
+ *
+ * @this:		the instance of the Simple Network Protocol
+ * @int_status:		interface status
+ * @txbuf:		transmission buffer
+ */
 static efi_status_t EFIAPI efi_net_get_status(struct efi_simple_network *this,
 					      u32 *int_status, void **txbuf)
 {
+	efi_status_t ret = EFI_SUCCESS;
+
 	EFI_ENTRY("%p, %p, %p", this, int_status, txbuf);
 
 	efi_timer_check();
 
+	/* Check parameters */
+	if (!this) {
+		ret = EFI_INVALID_PARAMETER;
+		goto out;
+	}
+
+	switch (this->mode->state) {
+	case EFI_NETWORK_STOPPED:
+		ret = EFI_NOT_STARTED;
+		goto out;
+	case EFI_NETWORK_STARTED:
+		ret = EFI_DEVICE_ERROR;
+		goto out;
+	default:
+		break;
+	}
+
 	if (int_status) {
 		/* We send packets synchronously, so nothing is outstanding */
 		*int_status = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
@@ -172,65 +358,103 @@
 		*txbuf = new_tx_packet;
 
 	new_tx_packet = NULL;
-
-	return EFI_EXIT(EFI_SUCCESS);
+out:
+	return EFI_EXIT(ret);
 }
 
-static efi_status_t EFIAPI efi_net_transmit(struct efi_simple_network *this,
-		size_t header_size, size_t buffer_size, void *buffer,
-		struct efi_mac_address *src_addr,
-		struct efi_mac_address *dest_addr, u16 *protocol)
+/**
+ * efi_net_transmit() - transmit a packet
+ *
+ * This function implements the Transmit service of the Simple Network Protocol.
+ * See the UEFI spec for details.
+ *
+ * @this:		the instance of the Simple Network Protocol
+ * @header_size:	size of the media header
+ * @buffer_size:	size of the buffer to receive the packet
+ * @buffer:		buffer to receive the packet
+ * @src_addr:		source hardware MAC address
+ * @dest_addr:		destination hardware MAC address
+ * @protocol:		type of header to build
+ * Return:		status code
+ */
+static efi_status_t EFIAPI efi_net_transmit
+		(struct efi_simple_network *this, size_t header_size,
+		 size_t buffer_size, void *buffer,
+		 struct efi_mac_address *src_addr,
+		 struct efi_mac_address *dest_addr, u16 *protocol)
 {
+	efi_status_t ret = EFI_SUCCESS;
+
 	EFI_ENTRY("%p, %lu, %lu, %p, %p, %p, %p", this,
 		  (unsigned long)header_size, (unsigned long)buffer_size,
 		  buffer, src_addr, dest_addr, protocol);
 
 	efi_timer_check();
 
+	/* Check parameters */
+	if (!this) {
+		ret = EFI_INVALID_PARAMETER;
+		goto out;
+	}
+
+	/* We do not support jumbo packets */
+	if (buffer_size > PKTSIZE_ALIGN) {
+		ret = EFI_INVALID_PARAMETER;
+		goto out;
+	}
+
 	if (header_size) {
-		/* We would need to create the header if header_size != 0 */
-		return EFI_EXIT(EFI_INVALID_PARAMETER);
+		/*
+		 * TODO: We would need to create the header
+		 * if header_size != 0
+		 */
+		ret = EFI_INVALID_PARAMETER;
+		goto out;
+	}
+
+	switch (this->mode->state) {
+	case EFI_NETWORK_STOPPED:
+		ret = EFI_NOT_STARTED;
+		goto out;
+	case EFI_NETWORK_STARTED:
+		ret = EFI_DEVICE_ERROR;
+		goto out;
+	default:
+		break;
 	}
 
-#ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
 	/* Ethernet packets always fit, just bounce */
-	memcpy(efi_bounce_buffer, buffer, buffer_size);
-	net_send_packet(efi_bounce_buffer, buffer_size);
-#else
-	net_send_packet(buffer, buffer_size);
-#endif
+	memcpy(transmit_buffer, buffer, buffer_size);
+	net_send_packet(transmit_buffer, buffer_size);
 
 	new_tx_packet = buffer;
 
-	return EFI_EXIT(EFI_SUCCESS);
-}
-
-static void efi_net_push(void *pkt, int len)
-{
-	new_rx_packet = true;
-	wait_for_packet->is_signaled = true;
+out:
+	return EFI_EXIT(ret);
 }
 
-/*
- * Receive a packet from a network interface.
+/**
+ * efi_net_receive() - receive a packet from a network interface
  *
  * This function implements the Receive service of the Simple Network Protocol.
  * See the UEFI spec for details.
  *
- * @this	the instance of the Simple Network Protocol
- * @header_size	size of the media header
- * @buffer_size	size of the buffer to receive the packet
- * @buffer	buffer to receive the packet
- * @src_addr	source MAC address
- * @dest_addr	destination MAC address
- * @protocol	protocol
- * @return	status code
+ * @this:		the instance of the Simple Network Protocol
+ * @header_size:	size of the media header
+ * @buffer_size:	size of the buffer to receive the packet
+ * @buffer:		buffer to receive the packet
+ * @src_addr:		source MAC address
+ * @dest_addr:		destination MAC address
+ * @protocol:		protocol
+ * Return:		status code
  */
-static efi_status_t EFIAPI efi_net_receive(struct efi_simple_network *this,
-		size_t *header_size, size_t *buffer_size, void *buffer,
-		struct efi_mac_address *src_addr,
-		struct efi_mac_address *dest_addr, u16 *protocol)
+static efi_status_t EFIAPI efi_net_receive
+		(struct efi_simple_network *this, size_t *header_size,
+		 size_t *buffer_size, void *buffer,
+		 struct efi_mac_address *src_addr,
+		 struct efi_mac_address *dest_addr, u16 *protocol)
 {
+	efi_status_t ret = EFI_SUCCESS;
 	struct ethernet_hdr *eth_hdr;
 	size_t hdr_size = sizeof(struct ethernet_hdr);
 	u16 protlen;
@@ -238,14 +462,35 @@
 	EFI_ENTRY("%p, %p, %p, %p, %p, %p, %p", this, header_size,
 		  buffer_size, buffer, src_addr, dest_addr, protocol);
 
+	/* Execute events */
 	efi_timer_check();
 
+	/* Check parameters */
+	if (!this) {
+		ret = EFI_INVALID_PARAMETER;
+		goto out;
+	}
+
+	switch (this->mode->state) {
+	case EFI_NETWORK_STOPPED:
+		ret = EFI_NOT_STARTED;
+		goto out;
+	case EFI_NETWORK_STARTED:
+		ret = EFI_DEVICE_ERROR;
+		goto out;
+	default:
+		break;
+	}
+
-	if (!new_rx_packet)
-		return EFI_EXIT(EFI_NOT_READY);
+	if (!new_rx_packet) {
+		ret = EFI_NOT_READY;
+		goto out;
+	}
 	/* Check that we at least received an Ethernet header */
 	if (net_rx_packet_len < sizeof(struct ethernet_hdr)) {
 		new_rx_packet = false;
-		return EFI_EXIT(EFI_NOT_READY);
+		ret = EFI_NOT_READY;
+		goto out;
 	}
 	/* Fill export parameters */
 	eth_hdr = (struct ethernet_hdr *)net_rx_packet;
@@ -263,18 +508,24 @@
 	if (protocol)
 		*protocol = protlen;
 	if (*buffer_size < net_rx_packet_len) {
-		/* Packet doesn't fit, try again with bigger buf */
+		/* Packet doesn't fit, try again with bigger buffer */
 		*buffer_size = net_rx_packet_len;
-		return EFI_EXIT(EFI_BUFFER_TOO_SMALL);
+		ret = EFI_BUFFER_TOO_SMALL;
+		goto out;
 	}
 	/* Copy packet */
 	memcpy(buffer, net_rx_packet, net_rx_packet_len);
 	*buffer_size = net_rx_packet_len;
 	new_rx_packet = false;
-
-	return EFI_EXIT(EFI_SUCCESS);
+out:
+	return EFI_EXIT(ret);
 }
 
+/**
+ * efi_net_set_dhcp_ack() - take note of a selected DHCP IP address
+ *
+ * This function is called by dhcp_handler().
+ */
 void efi_net_set_dhcp_ack(void *pkt, int len)
 {
 	int maxsize = sizeof(*dhcp_ack);
@@ -285,8 +536,22 @@
 	memcpy(dhcp_ack, pkt, min(len, maxsize));
 }
 
-/*
- * Check if a new network packet has been received.
+/**
+ * efi_net_push() - callback for received network packet
+ *
+ * This function is called when a network packet is received by eth_rx().
+ *
+ * @pkt:	network packet
+ * @len:	length
+ */
+static void efi_net_push(void *pkt, int len)
+{
+	new_rx_packet = true;
+	wait_for_packet->is_signaled = true;
+}
+
+/**
+ * efi_network_timer_notify() - check if a new network packet has been received
  *
  * This notification function is called in every timer cycle.
  *
@@ -296,47 +561,65 @@
 static void EFIAPI efi_network_timer_notify(struct efi_event *event,
 					    void *context)
 {
+	struct efi_simple_network *this = (struct efi_simple_network *)context;
+
 	EFI_ENTRY("%p, %p", event, context);
 
+	/*
+	 * Some network drivers do not support calling eth_rx() before
+	 * initialization.
+	 */
+	if (!this || this->mode->state != EFI_NETWORK_INITIALIZED)
+		goto out;
+
 	if (!new_rx_packet) {
 		push_packet = efi_net_push;
 		eth_rx();
 		push_packet = NULL;
 	}
+out:
 	EFI_EXIT(EFI_SUCCESS);
 }
 
-/* This gets called from do_bootefi_exec(). */
+/**
+ * efi_net_register() - register the simple network protocol
+ *
+ * This gets called from do_bootefi_exec().
+ */
 efi_status_t efi_net_register(void)
 {
-	struct efi_net_obj *netobj;
+	struct efi_net_obj *netobj = NULL;
 	efi_status_t r;
 
 	if (!eth_get_dev()) {
-		/* No eth device active, don't expose any */
+		/* No network device active, don't expose any */
 		return EFI_SUCCESS;
 	}
 
-	/* We only expose the "active" eth device, so one is enough */
+	/* We only expose the "active" network device, so one is enough */
 	netobj = calloc(1, sizeof(*netobj));
-	if (!netobj) {
-		printf("ERROR: Out of memory\n");
-		return EFI_OUT_OF_RESOURCES;
-	}
+	if (!netobj)
+		goto out_of_resources;
+
+	/* Allocate an aligned transmit buffer */
+	transmit_buffer = calloc(1, PKTSIZE_ALIGN + PKTALIGN);
+	if (!transmit_buffer)
+		goto out_of_resources;
+	transmit_buffer = (void *)ALIGN((uintptr_t)transmit_buffer, PKTALIGN);
 
 	/* Hook net up to the device list */
-	efi_add_handle(&netobj->parent);
+	efi_add_handle(&netobj->header);
 
 	/* Fill in object data */
-	r = efi_add_protocol(netobj->parent.handle, &efi_net_guid,
+	r = efi_add_protocol(&netobj->header, &efi_net_guid,
 			     &netobj->net);
 	if (r != EFI_SUCCESS)
 		goto failure_to_add_protocol;
-	r = efi_add_protocol(netobj->parent.handle, &efi_guid_device_path,
+	r = efi_add_protocol(&netobj->header, &efi_guid_device_path,
 			     efi_dp_from_eth());
 	if (r != EFI_SUCCESS)
 		goto failure_to_add_protocol;
-	r = efi_add_protocol(netobj->parent.handle, &efi_pxe_guid,
+	r = efi_add_protocol(&netobj->header, &efi_pxe_guid,
 			     &netobj->pxe);
 	if (r != EFI_SUCCESS)
 		goto failure_to_add_protocol;
@@ -385,13 +668,13 @@
 	 * iPXE is running at TPL_CALLBACK most of the time. Use a higher TPL.
 	 */
 	r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_NOTIFY,
-			     efi_network_timer_notify, NULL, NULL,
+			     efi_network_timer_notify, &netobj->net, NULL,
 			     &network_timer_event);
 	if (r != EFI_SUCCESS) {
 		printf("ERROR: Failed to register network event\n");
 		return r;
 	}
-	/* Network is time critical, create event in every timer cyle */
+	/* Network is time critical, create event in every timer cycle */
 	r = efi_set_timer(network_timer_event, EFI_TIMER_PERIODIC, 0);
 	if (r != EFI_SUCCESS) {
 		printf("ERROR: Failed to set network timer\n");
@@ -402,4 +685,9 @@
 failure_to_add_protocol:
 	printf("ERROR: Failure to add protocol\n");
 	return r;
+out_of_resources:
+	free(netobj);
+	/* free(transmit_buffer) not needed yet */
+	printf("ERROR: Out of memory\n");
+	return EFI_OUT_OF_RESOURCES;
 }
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index f059dc9..95844ef 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -141,7 +141,9 @@
 		do_reset(NULL, 0, 0, NULL);
 		break;
 	case EFI_RESET_SHUTDOWN:
-		/* We don't have anything to map this to */
+#ifdef CONFIG_CMD_POWEROFF
+		do_poweroff(NULL, 0, 0, NULL);
+#endif
 		break;
 	}
 
@@ -282,7 +284,7 @@
 	}, {
 		/* invalidate_*cache_all are gone */
 		.ptr = &efi_runtime_services.set_virtual_address_map,
-		.patchto = &efi_invalid_parameter,
+		.patchto = &efi_unimplemented,
 	}, {
 		/* RTC accessors are gone */
 		.ptr = &efi_runtime_services.get_time,
@@ -378,6 +380,9 @@
 			ulong symidx = rel->info >> SYM_INDEX;
 			extern struct dyn_sym __dyn_sym_start[];
 			newaddr = __dyn_sym_start[symidx].addr + offset;
+#ifdef IS_RELA
+			newaddr -= CONFIG_SYS_TEXT_BASE;
+#endif
 			break;
 		}
 #endif
@@ -623,8 +628,8 @@
 efi_status_t __efi_runtime EFIAPI efi_query_capsule_caps(
 			struct efi_capsule_header **capsule_header_array,
 			efi_uintn_t capsule_count,
-			u64 maximum_capsule_size,
-			u32 reset_type)
+			u64 *maximum_capsule_size,
+			u32 *reset_type)
 {
 	return EFI_UNSUPPORTED;
 }
diff --git a/lib/efi_loader/efi_smbios.c b/lib/efi_loader/efi_smbios.c
index 38e42fa..a814884 100644
--- a/lib/efi_loader/efi_smbios.c
+++ b/lib/efi_loader/efi_smbios.c
@@ -7,6 +7,7 @@
 
 #include <common.h>
 #include <efi_loader.h>
+#include <mapmem.h>
 #include <smbios.h>
 
 static const efi_guid_t smbios_guid = SMBIOS_TABLE_GUID;
@@ -19,17 +20,19 @@
 efi_status_t efi_smbios_register(void)
 {
 	/* Map within the low 32 bits, to allow for 32bit SMBIOS tables */
-	u64 dmi = U32_MAX;
+	u64 dmi_addr = U32_MAX;
 	efi_status_t ret;
+	void *dmi;
 
 	/* Reserve 4kiB page for SMBIOS */
 	ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
-				 EFI_RUNTIME_SERVICES_DATA, 1, &dmi);
+				 EFI_RUNTIME_SERVICES_DATA, 1, &dmi_addr);
 
 	if (ret != EFI_SUCCESS) {
 		/* Could not find space in lowmem, use highmem instead */
 		ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES,
-					 EFI_RUNTIME_SERVICES_DATA, 1, &dmi);
+					 EFI_RUNTIME_SERVICES_DATA, 1,
+					 &dmi_addr);
 
 		if (ret != EFI_SUCCESS)
 			return ret;
@@ -39,11 +42,14 @@
 	 * Generate SMBIOS tables - we know that efi_allocate_pages() returns
 	 * a 4k-aligned address, so it is safe to assume that
 	 * write_smbios_table() will write the table at that address.
+	 *
+	 * Note that on sandbox, efi_allocate_pages() unfortunately returns a
+	 * pointer even though it uses a uint64_t type. Convert it.
 	 */
-	assert(!(dmi & 0xf));
-	write_smbios_table(dmi);
+	assert(!(dmi_addr & 0xf));
+	dmi = (void *)(uintptr_t)dmi_addr;
+	write_smbios_table(map_to_sysmem(dmi));
 
 	/* And expose them to our EFI payload */
-	return efi_install_configuration_table(&smbios_guid,
-					       (void *)(uintptr_t)dmi);
+	return efi_install_configuration_table(&smbios_guid, dmi);
 }
diff --git a/lib/efi_loader/helloworld.c b/lib/efi_loader/helloworld.c
index 3b8de5b..2905479 100644
--- a/lib/efi_loader/helloworld.c
+++ b/lib/efi_loader/helloworld.c
@@ -17,6 +17,16 @@
 static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID;
 static const efi_guid_t smbios_guid = SMBIOS_TABLE_GUID;
 
+/**
+ * hw_memcmp() - compare memory areas
+ *
+ * @buf1:	pointer to first area
+ * @buf2:	pointer to second area
+ * @length:	number of bytes to compare
+ * Return:	0 if both memory areas are the same, otherwise the sign of the
+ *		result value is the same as the sign of ghe difference between
+ *		the first differing pair of bytes taken as u8.
+ */
 static int hw_memcmp(const void *buf1, const void *buf2, size_t length)
 {
 	const u8 *pos1 = buf1;
@@ -31,12 +41,12 @@
 	return 0;
 }
 
-/*
- * Entry point of the EFI application.
+/**
+ * efi_main() - entry point of the EFI application.
  *
- * @handle	handle of the loaded image
- * @systable	system table
- * @return	status code
+ * @handle:	handle of the loaded image
+ * @systable:	system table
+ * @return:	status code
  */
 efi_status_t EFIAPI efi_main(efi_handle_t handle,
 			     struct efi_system_table *systable)
@@ -48,7 +58,8 @@
 	efi_uintn_t i;
 	u16 rev[] = L"0.0.0";
 
-	con_out->output_string(con_out, L"Hello, world!\n");
+	/* UEFI requires CR LF */
+	con_out->output_string(con_out, L"Hello, world!\r\n");
 
 	/* Print the revision number */
 	rev[0] = (systable->hdr.revision >> 16) + '0';
@@ -65,27 +76,30 @@
 
 	con_out->output_string(con_out, L"Running on UEFI ");
 	con_out->output_string(con_out, rev);
-	con_out->output_string(con_out, L"\n");
+	con_out->output_string(con_out, L"\r\n");
 
 	/* Get the loaded image protocol */
 	ret = boottime->handle_protocol(handle, &loaded_image_guid,
 					(void **)&loaded_image);
 	if (ret != EFI_SUCCESS) {
-		con_out->output_string(con_out,
-				       L"Cannot open loaded image protocol\n");
+		con_out->output_string
+			(con_out, L"Cannot open loaded image protocol\r\n");
 		goto out;
 	}
 	/* Find configuration tables */
 	for (i = 0; i < systable->nr_tables; ++i) {
 		if (!hw_memcmp(&systable->tables[i].guid, &fdt_guid,
 			       sizeof(efi_guid_t)))
-			con_out->output_string(con_out, L"Have device tree\n");
+			con_out->output_string
+					(con_out, L"Have device tree\r\n");
 		if (!hw_memcmp(&systable->tables[i].guid, &acpi_guid,
 			       sizeof(efi_guid_t)))
-			con_out->output_string(con_out, L"Have ACPI 2.0 table\n");
+			con_out->output_string
+					(con_out, L"Have ACPI 2.0 table\r\n");
 		if (!hw_memcmp(&systable->tables[i].guid, &smbios_guid,
 			       sizeof(efi_guid_t)))
-			con_out->output_string(con_out, L"Have SMBIOS table\n");
+			con_out->output_string
+					(con_out, L"Have SMBIOS table\r\n");
 	}
 	/* Output the load options */
 	con_out->output_string(con_out, L"Load options: ");
@@ -94,7 +108,7 @@
 				       (u16 *)loaded_image->load_options);
 	else
 		con_out->output_string(con_out, L"<none>");
-	con_out->output_string(con_out, L"\n");
+	con_out->output_string(con_out, L"\r\n");
 
 out:
 	boottime->exit(handle, ret, 0, NULL);
diff --git a/lib/efi_selftest/Kconfig b/lib/efi_selftest/Kconfig
index b526967..59f9f36 100644
--- a/lib/efi_selftest/Kconfig
+++ b/lib/efi_selftest/Kconfig
@@ -1,6 +1,6 @@
 config CMD_BOOTEFI_SELFTEST
 	bool "Allow booting an EFI efi_selftest"
-	depends on CMD_BOOTEFI && !SANDBOX
+	depends on CMD_BOOTEFI
 	imply FAT
 	imply FAT_WRITE
 	help
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index 2f55d9d..743b482 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -10,7 +10,7 @@
 CFLAGS_efi_selftest_miniapp_return.o := $(CFLAGS_EFI) -Os -ffreestanding
 CFLAGS_REMOVE_efi_selftest_miniapp_return.o := $(CFLAGS_NON_EFI) -Os
 
-obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += \
+obj-y += \
 efi_selftest.o \
 efi_selftest_bitblt.o \
 efi_selftest_config_table.o \
@@ -21,11 +21,13 @@
 efi_selftest_devicepath_util.o \
 efi_selftest_events.o \
 efi_selftest_event_groups.o \
+efi_selftest_exception.o \
 efi_selftest_exitbootservices.o \
 efi_selftest_fdt.o \
 efi_selftest_gop.o \
 efi_selftest_loaded_image.o \
 efi_selftest_manageprotocols.o \
+efi_selftest_memory.o \
 efi_selftest_rtc.o \
 efi_selftest_snp.o \
 efi_selftest_textinput.o \
@@ -37,20 +39,16 @@
 efi_selftest_variables.o \
 efi_selftest_watchdog.o
 
-ifeq ($(CONFIG_CMD_BOOTEFI_SELFTEST),y)
 obj-$(CONFIG_CPU_V7) += efi_selftest_unaligned.o
-endif
 
 ifeq ($(CONFIG_BLK)$(CONFIG_PARTITIONS),yy)
-obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += efi_selftest_block_device.o
+obj-y += efi_selftest_block_device.o
 endif
 
 # TODO: As of v2018.01 the relocation code for the EFI application cannot
 # be built on x86_64.
 ifeq ($(CONFIG_X86_64)$(CONFIG_SANDBOX),)
 
-ifneq ($(CONFIG_CMD_BOOTEFI_SELFTEST),)
-
 obj-y += \
 efi_selftest_startimage_exit.o \
 efi_selftest_startimage_return.o
@@ -74,5 +72,3 @@
 $(obj)/efi_selftest_startimage_return.o: $(obj)/efi_miniapp_file_image_return.h
 
 endif
-
-endif
diff --git a/lib/efi_selftest/efi_selftest.c b/lib/efi_selftest/efi_selftest.c
index dd338db..5b01610 100644
--- a/lib/efi_selftest/efi_selftest.c
+++ b/lib/efi_selftest/efi_selftest.c
@@ -18,6 +18,7 @@
 static const struct efi_runtime_services *runtime;
 static efi_handle_t handle;
 static u16 reset_message[] = L"Selftest completed";
+static int *setup_status;
 
 /*
  * Exit the boot services.
@@ -74,20 +75,20 @@
  */
 static int setup(struct efi_unit_test *test, unsigned int *failures)
 {
-	if (!test->setup) {
-		test->setup_ok = EFI_ST_SUCCESS;
+	int ret;
+
+	if (!test->setup)
 		return EFI_ST_SUCCESS;
-	}
 	efi_st_printc(EFI_LIGHTBLUE, "\nSetting up '%s'\n", test->name);
-	test->setup_ok = test->setup(handle, systable);
-	if (test->setup_ok != EFI_ST_SUCCESS) {
+	ret = test->setup(handle, systable);
+	if (ret != EFI_ST_SUCCESS) {
 		efi_st_error("Setting up '%s' failed\n", test->name);
 		++*failures;
 	} else {
 		efi_st_printc(EFI_LIGHTGREEN,
 			      "Setting up '%s' succeeded\n", test->name);
 	}
-	return test->setup_ok;
+	return ret;
 }
 
 /*
@@ -186,18 +187,20 @@
 void efi_st_do_tests(const u16 *testname, unsigned int phase,
 		     unsigned int steps, unsigned int *failures)
 {
+	int i = 0;
 	struct efi_unit_test *test;
 
 	for (test = ll_entry_start(struct efi_unit_test, efi_unit_test);
-	     test < ll_entry_end(struct efi_unit_test, efi_unit_test); ++test) {
+	     test < ll_entry_end(struct efi_unit_test, efi_unit_test);
+	     ++test, ++i) {
 		if (testname ?
 		    efi_st_strcmp_16_8(testname, test->name) : test->on_request)
 			continue;
 		if (test->phase != phase)
 			continue;
 		if (steps & EFI_ST_SETUP)
-			setup(test, failures);
-		if (steps & EFI_ST_EXECUTE && test->setup_ok == EFI_ST_SUCCESS)
+			setup_status[i] = setup(test, failures);
+		if (steps & EFI_ST_EXECUTE && setup_status[i] == EFI_ST_SUCCESS)
 			execute(test, failures);
 		if (steps & EFI_ST_TEARDOWN)
 			teardown(test, failures);
@@ -271,6 +274,16 @@
 			      ll_entry_count(struct efi_unit_test,
 					     efi_unit_test));
 
+	/* Allocate buffer for setup results */
+	ret = boottime->allocate_pool(EFI_RUNTIME_SERVICES_DATA, sizeof(int) *
+				      ll_entry_count(struct efi_unit_test,
+						     efi_unit_test),
+				      (void **)&setup_status);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("Allocate pool failed\n");
+		return ret;
+	}
+
 	/* Execute boottime tests */
 	efi_st_do_tests(testname, EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
 			EFI_ST_SETUP | EFI_ST_EXECUTE | EFI_ST_TEARDOWN,
diff --git a/lib/efi_selftest/efi_selftest_config_table.c b/lib/efi_selftest/efi_selftest_config_table.c
index 2aa3fc7..0bc5da6 100644
--- a/lib/efi_selftest/efi_selftest_config_table.c
+++ b/lib/efi_selftest/efi_selftest_config_table.c
@@ -18,7 +18,7 @@
 		 0x17, 0x2e, 0x51, 0x6b, 0x49, 0x75);
 
 /*
- * Notification function, increments the notfication count if parameter
+ * Notification function, increments the notification count if parameter
  * context is provided.
  *
  * @event	notified event
@@ -33,23 +33,23 @@
 }
 
 /*
- * Check crc32 of a table.
+ * Check CRC32 of a table.
  */
 static int check_table(const void *table)
 {
 	efi_status_t ret;
 	u32 crc32, res;
-	/* Casting from const to not const */
+	/* Casting from constant to not constant */
 	struct efi_table_hdr *hdr = (struct efi_table_hdr *)table;
 
 	crc32 = hdr->crc32;
 	/*
-	 * Setting the crc32 of the 'const' table to zero is easier than
+	 * Setting the CRC32 of the 'const' table to zero is easier than
 	 * copying
 	 */
 	hdr->crc32 = 0;
 	ret = boottime->calculate_crc32(table, hdr->headersize, &res);
-	/* Reset table crc32 so it stays constant */
+	/* Reset table CRC32 so it stays constant */
 	hdr->crc32 = crc32;
 	if (ret != EFI_ST_SUCCESS) {
 		efi_st_error("CalculateCrc32 failed\n");
@@ -203,7 +203,7 @@
 		return EFI_ST_FAILURE;
 	}
 	if (tabcnt > 1) {
-		efi_st_error("Duplicate table guid\n");
+		efi_st_error("Duplicate table GUID\n");
 		return EFI_ST_FAILURE;
 	}
 	if (table != &tables[1]) {
diff --git a/lib/efi_selftest/efi_selftest_controllers.c b/lib/efi_selftest/efi_selftest_controllers.c
index d08c377..38720bb 100644
--- a/lib/efi_selftest/efi_selftest_controllers.c
+++ b/lib/efi_selftest/efi_selftest_controllers.c
@@ -33,7 +33,7 @@
  * Count child controllers
  *
  * @handle	handle on which child controllers are installed
- * @protocol	protocol for which the child controlles where installed
+ * @protocol	protocol for which the child controllers were installed
  * @count	number of child controllers
  * @return	status code
  */
diff --git a/lib/efi_selftest/efi_selftest_crc32.c b/lib/efi_selftest/efi_selftest_crc32.c
index 8555b8f..4881e8a 100644
--- a/lib/efi_selftest/efi_selftest_crc32.c
+++ b/lib/efi_selftest/efi_selftest_crc32.c
@@ -5,7 +5,7 @@
  * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
  *
  * This unit test checks the CalculateCrc32 bootservice and checks the
- * headers of the system table, the boot services tablle, and the runtime
+ * headers of the system table, the boot services table, and the runtime
  * services table before and after ExitBootServices().
  */
 
@@ -19,7 +19,7 @@
 {
 	efi_status_t ret;
 	u32 crc32, res;
-	/* Casting from const to not const */
+	/* Casting from constant to not constant */
 	struct efi_table_hdr *hdr = (struct efi_table_hdr *)table;
 
 	if (!hdr->signature) {
diff --git a/lib/efi_selftest/efi_selftest_devicepath.c b/lib/efi_selftest/efi_selftest_devicepath.c
index adcf531..105ce2c 100644
--- a/lib/efi_selftest/efi_selftest_devicepath.c
+++ b/lib/efi_selftest/efi_selftest_devicepath.c
@@ -257,7 +257,7 @@
 static int execute(void)
 {
 	struct efi_device_path *remaining_dp;
-	void *handle;
+	efi_handle_t handle;
 	/*
 	 * This device path node ends with the letter 't' of 'u-boot'.
 	 * The following '.bin' does not belong to the node but is
diff --git a/lib/efi_selftest/efi_selftest_event_groups.c b/lib/efi_selftest/efi_selftest_event_groups.c
index 9b3c513..5a7980c 100644
--- a/lib/efi_selftest/efi_selftest_event_groups.c
+++ b/lib/efi_selftest/efi_selftest_event_groups.c
@@ -19,7 +19,7 @@
 		 0x0e, 0x5b, 0x45, 0xc0, 0x56, 0x91);
 
 /*
- * Notification function, increments the notfication count if parameter
+ * Notification function, increments the notification count if parameter
  * context is provided.
  *
  * @event	notified event
@@ -114,7 +114,7 @@
 					      (unsigned int)i, (unsigned int)j,
 					      (unsigned int)counter[j]);
 				efi_st_error(
-					"Nofification function not called\n");
+					"Notification function not called\n");
 				return EFI_ST_FAILURE;
 			}
 		}
diff --git a/lib/efi_selftest/efi_selftest_events.c b/lib/efi_selftest/efi_selftest_events.c
index 47f9f99..ed99a53 100644
--- a/lib/efi_selftest/efi_selftest_events.c
+++ b/lib/efi_selftest/efi_selftest_events.c
@@ -17,7 +17,7 @@
 static struct efi_boot_services *boottime;
 
 /*
- * Notification function, increments the notfication count if parameter
+ * Notification function, increments the notification count if parameter
  * context is provided.
  *
  * @event	notified event
diff --git a/lib/efi_selftest/efi_selftest_exception.c b/lib/efi_selftest/efi_selftest_exception.c
new file mode 100644
index 0000000..76cfb88
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_exception.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * efi_selftest_exception
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * Test the handling of exceptions by trying to execute an undefined
+ * instruction.
+ */
+
+#include <efi_selftest.h>
+
+/**
+ * undefined_instruction() - try to executed an undefined instruction
+ */
+static void undefined_instruction(void)
+{
+#if defined(CONFIG_ARM)
+	/*
+	 * 0xe7f...f.	is undefined in ARM mode
+	 * 0xde..	is undefined in Thumb mode
+	 */
+	asm volatile (".word 0xe7f7defb\n");
+#elif defined(CONFIG_RISCV)
+	asm volatile (".word 0xffffffff\n");
+#elif defined(CONFIG_X86)
+	asm volatile (".word 0xffff\n");
+#endif
+}
+
+/**
+ * execute() - execute unit test
+ *
+ * Return:	EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+	undefined_instruction();
+
+	efi_st_error("An undefined instruction exception was not raised\n");
+
+	return EFI_ST_FAILURE;
+}
+
+EFI_UNIT_TEST(exception) = {
+	.name = "exception",
+	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+	.execute = execute,
+	.on_request = true,
+};
diff --git a/lib/efi_selftest/efi_selftest_fdt.c b/lib/efi_selftest/efi_selftest_fdt.c
index c7bc242..d545d51 100644
--- a/lib/efi_selftest/efi_selftest_fdt.c
+++ b/lib/efi_selftest/efi_selftest_fdt.c
@@ -16,7 +16,7 @@
 static struct efi_boot_services *boottime;
 static const char *fdt;
 
-/* This should be sufficent for */
+/* This should be sufficient for */
 #define BUFFERSIZE 0x100000
 
 static efi_guid_t fdt_guid = EFI_FDT_GUID;
diff --git a/lib/efi_selftest/efi_selftest_loaded_image.c b/lib/efi_selftest/efi_selftest_loaded_image.c
index f9b54ae..ea2b380 100644
--- a/lib/efi_selftest/efi_selftest_loaded_image.c
+++ b/lib/efi_selftest/efi_selftest_loaded_image.c
@@ -53,7 +53,7 @@
 		efi_st_error("ProtocolsPerHandle failed\n");
 		return EFI_ST_FAILURE;
 	}
-	if (!protocol_buffer_count | !protocol_buffer) {
+	if (!protocol_buffer_count || !protocol_buffer) {
 		efi_st_error("ProtocolsPerHandle returned no protocol\n");
 		return EFI_ST_FAILURE;
 	}
diff --git a/lib/efi_selftest/efi_selftest_manageprotocols.c b/lib/efi_selftest/efi_selftest_manageprotocols.c
index b09e4cd..0ff35ce 100644
--- a/lib/efi_selftest/efi_selftest_manageprotocols.c
+++ b/lib/efi_selftest/efi_selftest_manageprotocols.c
@@ -189,7 +189,14 @@
 	/*
 	 * Test error handling in UninstallMultipleProtocols
 	 *
-	 * Try to uninstall more protocols than there are installed.
+	 * These are the installed protocol interfaces on handle 2:
+	 *
+	 *   guid1 interface4
+	 *   guid2 interface2
+	 *
+	 * Try to uninstall more protocols than there are installed. This
+	 * should return an error EFI_INVALID_PARAMETER. All deleted protocols
+	 * should be reinstalled.
 	 */
 	ret = boottime->uninstall_multiple_protocol_interfaces(
 						handle2,
@@ -197,13 +204,18 @@
 						&guid2, &interface2,
 						&guid3, &interface3,
 						NULL);
-	if (ret == EFI_SUCCESS) {
+	if (ret != EFI_INVALID_PARAMETER) {
+		printf("%lx", ret);
 		efi_st_error("UninstallMultipleProtocolInterfaces did not catch error\n");
 		return EFI_ST_FAILURE;
 	}
 
 	/*
 	 * Test LocateHandleBuffer with ByProtocol
+	 *
+	 * These are the handles with a guid1 protocol interface installed:
+	 *
+	 *	handle1, handle2
 	 */
 	count = buffer_size;
 	ret = boottime->locate_handle_buffer(BY_PROTOCOL, &guid1, NULL,
@@ -213,7 +225,7 @@
 		return EFI_ST_FAILURE;
 	}
 	if (count != 2) {
-		efi_st_error("LocateHandleBuffer failed to locate new handles\n");
+		efi_st_error("UninstallMultipleProtocolInterfaces deleted handle\n");
 		return EFI_ST_FAILURE;
 	}
 	ret = find_in_buffer(handle1, count, buffer);
diff --git a/lib/efi_selftest/efi_selftest_memory.c b/lib/efi_selftest/efi_selftest_memory.c
new file mode 100644
index 0000000..24b4438
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_memory.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * efi_selftest_memory
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * This unit test checks the following runtime services:
+ * AllocatePages, FreePages, GetMemoryMap
+ *
+ * The memory type used for the device tree is checked.
+ */
+
+#include <efi_selftest.h>
+
+#define EFI_ST_NUM_PAGES 8
+
+static const efi_guid_t fdt_guid = EFI_FDT_GUID;
+static struct efi_boot_services *boottime;
+static u64 fdt_addr;
+
+/**
+ * setup() - setup unit test
+ *
+ * @handle:	handle of the loaded image
+ * @systable:	system table
+ * Return:	EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+		 const struct efi_system_table *systable)
+{
+	size_t i;
+
+	boottime = systable->boottime;
+
+	for (i = 0; i < systable->nr_tables; ++i) {
+		if (!efi_st_memcmp(&systable->tables[i].guid, &fdt_guid,
+				   sizeof(efi_guid_t))) {
+			if (fdt_addr) {
+				efi_st_error("Duplicate device tree\n");
+				return EFI_ST_FAILURE;
+			}
+			fdt_addr = (uintptr_t)systable->tables[i].table;
+		}
+	}
+	return EFI_ST_SUCCESS;
+}
+
+/**
+ * find_in_memory_map() - check matching memory map entry exists
+ *
+ * @memory_map:		memory map
+ * @desc_size:		number of memory map entries
+ * @addr:		physical address to find in the map
+ * @type:		expected memory type
+ * Return:		EFI_ST_SUCCESS for success
+ */
+static int find_in_memory_map(efi_uintn_t map_size,
+			      struct efi_mem_desc *memory_map,
+			      efi_uintn_t desc_size,
+			      u64 addr, int memory_type)
+{
+	efi_uintn_t i;
+	bool found = false;
+
+	for (i = 0; map_size; ++i, map_size -= desc_size) {
+		struct efi_mem_desc *entry = &memory_map[i];
+
+		if (addr >= entry->physical_start &&
+		    addr < entry->physical_start +
+			    (entry->num_pages << EFI_PAGE_SHIFT)) {
+			if (found) {
+				efi_st_error("Duplicate memory map entry\n");
+				return EFI_ST_FAILURE;
+			}
+			found = true;
+			if (memory_type != entry->type) {
+				efi_st_error
+					("Wrong memory type %d, expected %d\n",
+					 entry->type, memory_type);
+				return EFI_ST_FAILURE;
+			}
+		}
+	}
+	if (!found) {
+		efi_st_error("Missing memory map entry\n");
+		return EFI_ST_FAILURE;
+	}
+	return EFI_ST_SUCCESS;
+}
+
+/*
+ * execute() - execute unit test
+ *
+ * Return:	EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+	u64 p1;
+	u64 p2;
+	efi_uintn_t map_size = 0;
+	efi_uintn_t map_key;
+	efi_uintn_t desc_size;
+	u32 desc_version;
+	struct efi_mem_desc *memory_map;
+	efi_status_t ret;
+
+	/* Allocate two page ranges with different memory type */
+	ret = boottime->allocate_pages(EFI_ALLOCATE_ANY_PAGES,
+				       EFI_RUNTIME_SERVICES_CODE,
+				       EFI_ST_NUM_PAGES, &p1);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("AllocatePages did not return EFI_SUCCESS\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = boottime->allocate_pages(EFI_ALLOCATE_ANY_PAGES,
+				       EFI_RUNTIME_SERVICES_DATA,
+				       EFI_ST_NUM_PAGES, &p2);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("AllocatePages did not return EFI_SUCCESS\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/* Load memory map */
+	ret = boottime->get_memory_map(&map_size, NULL, &map_key, &desc_size,
+				       &desc_version);
+	if (ret != EFI_BUFFER_TOO_SMALL) {
+		efi_st_error
+			("GetMemoryMap did not return EFI_BUFFER_TOO_SMALL\n");
+		return EFI_ST_FAILURE;
+	}
+	/* Allocate extra space for newly allocated memory */
+	map_size += sizeof(struct efi_mem_desc);
+	ret = boottime->allocate_pool(EFI_BOOT_SERVICES_DATA, map_size,
+				      (void **)&memory_map);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("AllocatePool did not return EFI_SUCCESS\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = boottime->get_memory_map(&map_size, memory_map, &map_key,
+				       &desc_size, &desc_version);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("GetMemoryMap did not return EFI_SUCCESS\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/* Check memory map entries */
+	if (find_in_memory_map(map_size, memory_map, desc_size, p1,
+			       EFI_RUNTIME_SERVICES_CODE) != EFI_ST_SUCCESS)
+		return EFI_ST_FAILURE;
+	if (find_in_memory_map(map_size, memory_map, desc_size, p2,
+			       EFI_RUNTIME_SERVICES_DATA) != EFI_ST_SUCCESS)
+		return EFI_ST_FAILURE;
+
+	/* Free memory */
+	ret = boottime->free_pages(p1, EFI_ST_NUM_PAGES);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("FreePages did not return EFI_SUCCESS\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = boottime->free_pages(p2, EFI_ST_NUM_PAGES);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("FreePages did not return EFI_SUCCESS\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = boottime->free_pool(memory_map);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("FreePool did not return EFI_SUCCESS\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/* Check memory reservation for the device tree */
+	if (fdt_addr &&
+	    find_in_memory_map(map_size, memory_map, desc_size, fdt_addr,
+			       EFI_RUNTIME_SERVICES_DATA) != EFI_ST_SUCCESS) {
+		efi_st_error
+			("Device tree not marked as runtime services data\n");
+		return EFI_ST_FAILURE;
+	}
+	return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(memory) = {
+	.name = "memory",
+	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+	.setup = setup,
+	.execute = execute,
+};
diff --git a/lib/efi_selftest/efi_selftest_snp.c b/lib/efi_selftest/efi_selftest_snp.c
index 09bd53d..e10a34b 100644
--- a/lib/efi_selftest/efi_selftest_snp.c
+++ b/lib/efi_selftest/efi_selftest_snp.c
@@ -103,7 +103,7 @@
 	struct dhcp p = {};
 
 	/*
-	 * Fill ethernet header
+	 * Fill Ethernet header
 	 */
 	boottime->copy_mem(p.eth_hdr.et_dest, (void *)BROADCAST_MAC, ARP_HLEN);
 	boottime->copy_mem(p.eth_hdr.et_src, &net->mode->current_address,
@@ -229,19 +229,19 @@
 		return EFI_ST_FAILURE;
 	}
 	/*
-	 * Initialize network adapter.
+	 * Start network adapter.
 	 */
-	ret = net->initialize(net, 0, 0);
-	if (ret != EFI_SUCCESS) {
-		efi_st_error("Failed to initialize network adapter\n");
+	ret = net->start(net);
+	if (ret != EFI_SUCCESS && ret != EFI_ALREADY_STARTED) {
+		efi_st_error("Failed to start network adapter\n");
 		return EFI_ST_FAILURE;
 	}
 	/*
-	 * Start network adapter.
+	 * Initialize network adapter.
 	 */
-	ret = net->start(net);
+	ret = net->initialize(net, 0, 0);
 	if (ret != EFI_SUCCESS) {
-		efi_st_error("Failed to start network adapter\n");
+		efi_st_error("Failed to initialize network adapter\n");
 		return EFI_ST_FAILURE;
 	}
 	return EFI_ST_SUCCESS;
diff --git a/lib/efi_selftest/efi_selftest_textinput.c b/lib/efi_selftest/efi_selftest_textinput.c
index 164fbff..b90671c 100644
--- a/lib/efi_selftest/efi_selftest_textinput.c
+++ b/lib/efi_selftest/efi_selftest_textinput.c
@@ -5,7 +5,7 @@
  * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
  *
  * Provides a unit test for the EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
- * The unicode character and the scan code are printed for text
+ * The Unicode character and the scan code are printed for text
  * input. To run the test:
  *
  *	setenv efi_selftest text input
diff --git a/lib/efi_selftest/efi_selftest_tpl.c b/lib/efi_selftest/efi_selftest_tpl.c
index 61ae46b..97d256a 100644
--- a/lib/efi_selftest/efi_selftest_tpl.c
+++ b/lib/efi_selftest/efi_selftest_tpl.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * efi_selftest_events
+ * efi_selftest_tpl
  *
  * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
  *
diff --git a/lib/efi_selftest/efi_selftest_unicode_collation.c b/lib/efi_selftest/efi_selftest_unicode_collation.c
index 9765bd3..7529430 100644
--- a/lib/efi_selftest/efi_selftest_unicode_collation.c
+++ b/lib/efi_selftest/efi_selftest_unicode_collation.c
@@ -52,7 +52,7 @@
 						    c1, c2);
 	if (ret) {
 		efi_st_error(
-			"stri_coll(\"%ps\", \"%ps\") = %zu\n", c1, c2, ret);
+			"stri_coll(\"%ps\", \"%ps\") = %d\n", c1, c2, (int)ret);
 		return EFI_ST_FAILURE;
 	}
 
@@ -60,7 +60,7 @@
 						    c1, c3);
 	if (ret >= 0) {
 		efi_st_error(
-			"stri_coll(\"%ps\", \"%ps\") = %zu\n", c1, c3, ret);
+			"stri_coll(\"%ps\", \"%ps\") = %d\n", c1, c3, (int)ret);
 		return EFI_ST_FAILURE;
 	}
 
@@ -68,7 +68,7 @@
 						    c3, c1);
 	if (ret <= 0) {
 		efi_st_error(
-			"stri_coll(\"%ps\", \"%ps\") = %zu\n", c3, c1, ret);
+			"stri_coll(\"%ps\", \"%ps\") = %d\n", c3, c1, (int)ret);
 		return EFI_ST_FAILURE;
 	}
 
diff --git a/lib/efi_selftest/efi_selftest_variables.c b/lib/efi_selftest/efi_selftest_variables.c
index 146378f..e4c389a 100644
--- a/lib/efi_selftest/efi_selftest_variables.c
+++ b/lib/efi_selftest/efi_selftest_variables.c
@@ -4,10 +4,8 @@
  *
  * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
  *
- * This unit test checks the following protocol services:
- * ConnectController, DisconnectController,
- * InstallProtocol, ReinstallProtocol, UninstallProtocol,
- * OpenProtocol, CloseProtcol, OpenProtocolInformation
+ * This unit test checks the runtime services for variables:
+ * GetVariable, GetNextVariableName, SetVariable, QueryVariableInfo.
  */
 
 #include <efi_selftest.h>
diff --git a/lib/efi_selftest/efi_selftest_watchdog.c b/lib/efi_selftest/efi_selftest_watchdog.c
index bff2330..cbc6761 100644
--- a/lib/efi_selftest/efi_selftest_watchdog.c
+++ b/lib/efi_selftest/efi_selftest_watchdog.c
@@ -35,7 +35,7 @@
 static bool watchdog_reset;
 
 /*
- * Notification function, increments the notfication count if parameter
+ * Notification function, increments the notification count if parameter
  * context is provided.
  *
  * @event	notified event
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index a420ba1..cbdc077 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -11,6 +11,7 @@
 #include <errno.h>
 #include <fdtdec.h>
 #include <fdt_support.h>
+#include <mapmem.h>
 #include <linux/libfdt.h>
 #include <serial.h>
 #include <asm/sections.h>
@@ -1198,7 +1199,8 @@
 # else
 static int uncompress_blob(const void *src, ulong sz_src, void **dstp)
 {
-	return -ENOTSUPP;
+	*dstp = (void *)src;
+	return 0;
 }
 # endif
 #endif
@@ -1252,8 +1254,9 @@
 #  if CONFIG_IS_ENABLED(OF_PRIOR_STAGE)
 	gd->fdt_blob = (void *)prior_stage_fdt_address;
 #  else
-	gd->fdt_blob = (void *)env_get_ulong("fdtcontroladdr", 16,
-						(uintptr_t)gd->fdt_blob);
+	gd->fdt_blob = map_sysmem
+		(env_get_ulong("fdtcontroladdr", 16,
+			       (unsigned long)map_to_sysmem(gd->fdt_blob)), 0);
 #  endif
 # endif
 
diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c
index 05ac67b..fb5e07b 100644
--- a/lib/rsa/rsa-sign.c
+++ b/lib/rsa/rsa-sign.c
@@ -387,13 +387,16 @@
 	}
 }
 
-static int rsa_sign_with_key(RSA *rsa, struct checksum_algo *checksum_algo,
+static int rsa_sign_with_key(RSA *rsa, struct padding_algo *padding_algo,
+			     struct checksum_algo *checksum_algo,
 		const struct image_region region[], int region_count,
 		uint8_t **sigp, uint *sig_size)
 {
 	EVP_PKEY *key;
+	EVP_PKEY_CTX *ckey;
 	EVP_MD_CTX *context;
-	int size, ret = 0;
+	int ret = 0;
+	size_t size;
 	uint8_t *sig;
 	int i;
 
@@ -409,7 +412,7 @@
 	size = EVP_PKEY_size(key);
 	sig = malloc(size);
 	if (!sig) {
-		fprintf(stderr, "Out of memory for signature (%d bytes)\n",
+		fprintf(stderr, "Out of memory for signature (%zu bytes)\n",
 			size);
 		ret = -ENOMEM;
 		goto err_alloc;
@@ -421,22 +424,43 @@
 		goto err_create;
 	}
 	EVP_MD_CTX_init(context);
-	if (!EVP_SignInit(context, checksum_algo->calculate_sign())) {
+
+	ckey = EVP_PKEY_CTX_new(key, NULL);
+	if (!ckey) {
+		ret = rsa_err("EVP key context creation failed");
+		goto err_create;
+	}
+
+	if (EVP_DigestSignInit(context, &ckey,
+			       checksum_algo->calculate_sign(),
+			       NULL, key) <= 0) {
 		ret = rsa_err("Signer setup failed");
 		goto err_sign;
 	}
 
+#ifdef CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT
+	if (padding_algo && !strcmp(padding_algo->name, "pss")) {
+		if (EVP_PKEY_CTX_set_rsa_padding(ckey,
+						 RSA_PKCS1_PSS_PADDING) <= 0) {
+			ret = rsa_err("Signer padding setup failed");
+			goto err_sign;
+		}
+	}
+#endif /* CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT */
+
 	for (i = 0; i < region_count; i++) {
-		if (!EVP_SignUpdate(context, region[i].data, region[i].size)) {
+		if (!EVP_DigestSignUpdate(context, region[i].data,
+					  region[i].size)) {
 			ret = rsa_err("Signing data failed");
 			goto err_sign;
 		}
 	}
 
-	if (!EVP_SignFinal(context, sig, sig_size, key)) {
+	if (!EVP_DigestSignFinal(context, sig, &size)) {
 		ret = rsa_err("Could not obtain signature");
 		goto err_sign;
 	}
+
 	#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
 		(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02070000fL)
 		EVP_MD_CTX_cleanup(context);
@@ -446,7 +470,7 @@
 	EVP_MD_CTX_destroy(context);
 	EVP_PKEY_free(key);
 
-	debug("Got signature: %d bytes, expected %d\n", *sig_size, size);
+	debug("Got signature: %d bytes, expected %zu\n", *sig_size, size);
 	*sigp = sig;
 	*sig_size = size;
 
@@ -483,7 +507,7 @@
 	ret = rsa_get_priv_key(info->keydir, info->keyname, e, &rsa);
 	if (ret)
 		goto err_priv;
-	ret = rsa_sign_with_key(rsa, info->checksum, region,
+	ret = rsa_sign_with_key(rsa, info->padding, info->checksum, region,
 				region_count, sigp, sig_len);
 	if (ret)
 		goto err_sign;
diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
index bc83354..9734f6d 100644
--- a/lib/rsa/rsa-verify.c
+++ b/lib/rsa/rsa-verify.c
@@ -57,31 +57,247 @@
 	return ret;
 }
 
+int padding_pkcs_15_verify(struct image_sign_info *info,
+			   uint8_t *msg, int msg_len,
+			   const uint8_t *hash, int hash_len)
+{
+	struct checksum_algo *checksum = info->checksum;
+	int ret, pad_len = msg_len - checksum->checksum_len;
+
+	/* Check pkcs1.5 padding bytes. */
+	ret = rsa_verify_padding(msg, pad_len, checksum);
+	if (ret) {
+		debug("In RSAVerify(): Padding check failed!\n");
+		return -EINVAL;
+	}
+
+	/* Check hash. */
+	if (memcmp((uint8_t *)msg + pad_len, hash, msg_len - pad_len)) {
+		debug("In RSAVerify(): Hash check failed!\n");
+		return -EACCES;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT
+static void u32_i2osp(uint32_t val, uint8_t *buf)
+{
+	buf[0] = (uint8_t)((val >> 24) & 0xff);
+	buf[1] = (uint8_t)((val >> 16) & 0xff);
+	buf[2] = (uint8_t)((val >>  8) & 0xff);
+	buf[3] = (uint8_t)((val >>  0) & 0xff);
+}
+
+/**
+ * mask_generation_function1() - generate an octet string
+ *
+ * Generate an octet string used to check rsa signature.
+ * It use an input octet string and a hash function.
+ *
+ * @checksum:	A Hash function
+ * @seed:	Specifies an input variable octet string
+ * @seed_len:	Size of the input octet string
+ * @output:	Specifies the output octet string
+ * @output_len:	Size of the output octet string
+ * @return 0 if the octet string was correctly generated, others on error
+ */
+static int mask_generation_function1(struct checksum_algo *checksum,
+				     uint8_t *seed, int seed_len,
+				     uint8_t *output, int output_len)
+{
+	struct image_region region[2];
+	int ret = 0, i, i_output = 0, region_count = 2;
+	uint32_t counter = 0;
+	uint8_t buf_counter[4], *tmp;
+	int hash_len = checksum->checksum_len;
+
+	memset(output, 0, output_len);
+
+	region[0].data = seed;
+	region[0].size = seed_len;
+	region[1].data = &buf_counter[0];
+	region[1].size = 4;
+
+	tmp = malloc(hash_len);
+	if (!tmp) {
+		debug("%s: can't allocate array tmp\n", __func__);
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	while (i_output < output_len) {
+		u32_i2osp(counter, &buf_counter[0]);
+
+		ret = checksum->calculate(checksum->name,
+					  region, region_count,
+					  tmp);
+		if (ret < 0) {
+			debug("%s: Error in checksum calculation\n", __func__);
+			goto out;
+		}
+
+		i = 0;
+		while ((i_output < output_len) && (i < hash_len)) {
+			output[i_output] = tmp[i];
+			i_output++;
+			i++;
+		}
+
+		counter++;
+	}
+
+out:
+	free(tmp);
+
+	return ret;
+}
+
+static int compute_hash_prime(struct checksum_algo *checksum,
+			      uint8_t *pad, int pad_len,
+			      uint8_t *hash, int hash_len,
+			      uint8_t *salt, int salt_len,
+			      uint8_t *hprime)
+{
+	struct image_region region[3];
+	int ret, region_count = 3;
+
+	region[0].data = pad;
+	region[0].size = pad_len;
+	region[1].data = hash;
+	region[1].size = hash_len;
+	region[2].data = salt;
+	region[2].size = salt_len;
+
+	ret = checksum->calculate(checksum->name, region, region_count, hprime);
+	if (ret < 0) {
+		debug("%s: Error in checksum calculation\n", __func__);
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+int padding_pss_verify(struct image_sign_info *info,
+		       uint8_t *msg, int msg_len,
+		       const uint8_t *hash, int hash_len)
+{
+	uint8_t *masked_db = NULL;
+	int masked_db_len = msg_len - hash_len - 1;
+	uint8_t *h = NULL, *hprime = NULL;
+	int h_len = hash_len;
+	uint8_t *db_mask = NULL;
+	int db_mask_len = masked_db_len;
+	uint8_t *db = NULL, *salt = NULL;
+	int db_len = masked_db_len, salt_len = msg_len - hash_len - 2;
+	uint8_t pad_zero[8] = { 0 };
+	int ret, i, leftmost_bits = 1;
+	uint8_t leftmost_mask;
+	struct checksum_algo *checksum = info->checksum;
+
+	/* first, allocate everything */
+	masked_db = malloc(masked_db_len);
+	h = malloc(h_len);
+	db_mask = malloc(db_mask_len);
+	db = malloc(db_len);
+	salt = malloc(salt_len);
+	hprime = malloc(hash_len);
+	if (!masked_db || !h || !db_mask || !db || !salt || !hprime) {
+		printf("%s: can't allocate some buffer\n", __func__);
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* step 4: check if the last byte is 0xbc */
+	if (msg[msg_len - 1] != 0xbc) {
+		printf("%s: invalid pss padding (0xbc is missing)\n", __func__);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* step 5 */
+	memcpy(masked_db, msg, masked_db_len);
+	memcpy(h, msg + masked_db_len, h_len);
+
+	/* step 6 */
+	leftmost_mask = (0xff >> (8 - leftmost_bits)) << (8 - leftmost_bits);
+	if (masked_db[0] & leftmost_mask) {
+		printf("%s: invalid pss padding ", __func__);
+		printf("(leftmost bit of maskedDB not zero)\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* step 7 */
+	mask_generation_function1(checksum, h, h_len, db_mask, db_mask_len);
+
+	/* step 8 */
+	for (i = 0; i < db_len; i++)
+		db[i] = masked_db[i] ^ db_mask[i];
+
+	/* step 9 */
+	db[0] &= 0xff >> leftmost_bits;
+
+	/* step 10 */
+	if (db[0] != 0x01) {
+		printf("%s: invalid pss padding ", __func__);
+		printf("(leftmost byte of db isn't 0x01)\n");
+		ret = EINVAL;
+		goto out;
+	}
+
+	/* step 11 */
+	memcpy(salt, &db[1], salt_len);
+
+	/* step 12 & 13 */
+	compute_hash_prime(checksum, pad_zero, 8,
+			   (uint8_t *)hash, hash_len,
+			   salt, salt_len, hprime);
+
+	/* step 14 */
+	ret = memcmp(h, hprime, hash_len);
+
+out:
+	free(hprime);
+	free(salt);
+	free(db);
+	free(db_mask);
+	free(h);
+	free(masked_db);
+
+	return ret;
+}
+#endif
+
 /**
  * rsa_verify_key() - Verify a signature against some data using RSA Key
  *
  * Verify a RSA PKCS1.5 signature against an expected hash using
  * the RSA Key properties in prop structure.
  *
+ * @info:	Specifies key and FIT information
  * @prop:	Specifies key
  * @sig:	Signature
  * @sig_len:	Number of bytes in signature
  * @hash:	Pointer to the expected hash
  * @key_len:	Number of bytes in rsa key
- * @algo:	Checksum algo structure having information on DER encoding etc.
  * @return 0 if verified, -ve on error
  */
-static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig,
+static int rsa_verify_key(struct image_sign_info *info,
+			  struct key_prop *prop, const uint8_t *sig,
 			  const uint32_t sig_len, const uint8_t *hash,
-			  const uint32_t key_len, struct checksum_algo *algo)
+			  const uint32_t key_len)
 {
-	int pad_len;
 	int ret;
 #if !defined(USE_HOSTCC)
 	struct udevice *mod_exp_dev;
 #endif
+	struct checksum_algo *checksum = info->checksum;
+	struct padding_algo *padding = info->padding;
+	int hash_len = checksum->checksum_len;
 
-	if (!prop || !sig || !hash || !algo)
+	if (!prop || !sig || !hash || !checksum)
 		return -EIO;
 
 	if (sig_len != (prop->num_bits / 8)) {
@@ -89,7 +305,7 @@
 		return -EINVAL;
 	}
 
-	debug("Checksum algorithm: %s", algo->name);
+	debug("Checksum algorithm: %s", checksum->name);
 
 	/* Sanity check for stack size */
 	if (sig_len > RSA_MAX_SIG_BITS / 8) {
@@ -116,19 +332,10 @@
 		return ret;
 	}
 
-	pad_len = key_len - algo->checksum_len;
-
-	/* Check pkcs1.5 padding bytes. */
-	ret = rsa_verify_padding(buf, pad_len, algo);
+	ret = padding->verify(info, buf, key_len, hash, hash_len);
 	if (ret) {
-		debug("In RSAVerify(): Padding check failed!\n");
-		return -EINVAL;
-	}
-
-	/* Check hash. */
-	if (memcmp((uint8_t *)buf + pad_len, hash, sig_len - pad_len)) {
-		debug("In RSAVerify(): Hash check failed!\n");
-		return -EACCES;
+		debug("In RSAVerify(): padding check failed!\n");
+		return ret;
 	}
 
 	return 0;
@@ -182,8 +389,8 @@
 		return -EFAULT;
 	}
 
-	ret = rsa_verify_key(&prop, sig, sig_len, hash,
-			     info->crypto->key_len, info->checksum);
+	ret = rsa_verify_key(info, &prop, sig, sig_len, hash,
+			     info->crypto->key_len);
 
 	return ret;
 }
diff --git a/lib/smbios.c b/lib/smbios.c
index 326eb00..e8ee55c 100644
--- a/lib/smbios.c
+++ b/lib/smbios.c
@@ -6,6 +6,7 @@
  */
 
 #include <common.h>
+#include <mapmem.h>
 #include <smbios.h>
 #include <tables_csum.h>
 #include <version.h>
@@ -72,9 +73,10 @@
 
 static int smbios_write_type0(ulong *current, int handle)
 {
-	struct smbios_type0 *t = (struct smbios_type0 *)*current;
+	struct smbios_type0 *t;
 	int len = sizeof(struct smbios_type0);
 
+	t = map_sysmem(*current, len);
 	memset(t, 0, sizeof(struct smbios_type0));
 	fill_smbios_header(t, SMBIOS_BIOS_INFORMATION, len, handle);
 	t->vendor = smbios_add_string(t->eos, "U-Boot");
@@ -101,16 +103,18 @@
 
 	len = t->length + smbios_string_table_len(t->eos);
 	*current += len;
+	unmap_sysmem(t);
 
 	return len;
 }
 
 static int smbios_write_type1(ulong *current, int handle)
 {
-	struct smbios_type1 *t = (struct smbios_type1 *)*current;
+	struct smbios_type1 *t;
 	int len = sizeof(struct smbios_type1);
 	char *serial_str = env_get("serial#");
 
+	t = map_sysmem(*current, len);
 	memset(t, 0, sizeof(struct smbios_type1));
 	fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle);
 	t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER);
@@ -122,15 +126,17 @@
 
 	len = t->length + smbios_string_table_len(t->eos);
 	*current += len;
+	unmap_sysmem(t);
 
 	return len;
 }
 
 static int smbios_write_type2(ulong *current, int handle)
 {
-	struct smbios_type2 *t = (struct smbios_type2 *)*current;
+	struct smbios_type2 *t;
 	int len = sizeof(struct smbios_type2);
 
+	t = map_sysmem(*current, len);
 	memset(t, 0, sizeof(struct smbios_type2));
 	fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle);
 	t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER);
@@ -140,15 +146,17 @@
 
 	len = t->length + smbios_string_table_len(t->eos);
 	*current += len;
+	unmap_sysmem(t);
 
 	return len;
 }
 
 static int smbios_write_type3(ulong *current, int handle)
 {
-	struct smbios_type3 *t = (struct smbios_type3 *)*current;
+	struct smbios_type3 *t;
 	int len = sizeof(struct smbios_type3);
 
+	t = map_sysmem(*current, len);
 	memset(t, 0, sizeof(struct smbios_type3));
 	fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle);
 	t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER);
@@ -160,6 +168,7 @@
 
 	len = t->length + smbios_string_table_len(t->eos);
 	*current += len;
+	unmap_sysmem(t);
 
 	return len;
 }
@@ -198,9 +207,10 @@
 
 static int smbios_write_type4(ulong *current, int handle)
 {
-	struct smbios_type4 *t = (struct smbios_type4 *)*current;
+	struct smbios_type4 *t;
 	int len = sizeof(struct smbios_type4);
 
+	t = map_sysmem(*current, len);
 	memset(t, 0, sizeof(struct smbios_type4));
 	fill_smbios_header(t, SMBIOS_PROCESSOR_INFORMATION, len, handle);
 	t->processor_type = SMBIOS_PROCESSOR_TYPE_CENTRAL;
@@ -214,32 +224,37 @@
 
 	len = t->length + smbios_string_table_len(t->eos);
 	*current += len;
+	unmap_sysmem(t);
 
 	return len;
 }
 
 static int smbios_write_type32(ulong *current, int handle)
 {
-	struct smbios_type32 *t = (struct smbios_type32 *)*current;
+	struct smbios_type32 *t;
 	int len = sizeof(struct smbios_type32);
 
+	t = map_sysmem(*current, len);
 	memset(t, 0, sizeof(struct smbios_type32));
 	fill_smbios_header(t, SMBIOS_SYSTEM_BOOT_INFORMATION, len, handle);
 
 	*current += len;
+	unmap_sysmem(t);
 
 	return len;
 }
 
 static int smbios_write_type127(ulong *current, int handle)
 {
-	struct smbios_type127 *t = (struct smbios_type127 *)*current;
+	struct smbios_type127 *t;
 	int len = sizeof(struct smbios_type127);
 
+	t = map_sysmem(*current, len);
 	memset(t, 0, sizeof(struct smbios_type127));
 	fill_smbios_header(t, SMBIOS_END_OF_TABLE, len, handle);
 
 	*current += len;
+	unmap_sysmem(t);
 
 	return len;
 }
@@ -257,6 +272,7 @@
 ulong write_smbios_table(ulong addr)
 {
 	struct smbios_entry *se;
+	ulong table_addr;
 	ulong tables;
 	int len = 0;
 	int max_struct_size = 0;
@@ -268,7 +284,7 @@
 	/* 16 byte align the table address */
 	addr = ALIGN(addr, 16);
 
-	se = (struct smbios_entry *)(uintptr_t)addr;
+	se = map_sysmem(addr, sizeof(struct smbios_entry));
 	memset(se, 0, sizeof(struct smbios_entry));
 
 	addr += sizeof(struct smbios_entry);
@@ -290,7 +306,24 @@
 	se->max_struct_size = max_struct_size;
 	memcpy(se->intermediate_anchor, "_DMI_", 5);
 	se->struct_table_length = len;
-	se->struct_table_address = tables;
+
+	/*
+	 * We must use a pointer here so things work correctly on sandbox. The
+	 * user of this table is not aware of the mapping of addresses to
+	 * sandbox's DRAM buffer.
+	 */
+	table_addr = (ulong)map_sysmem(tables, 0);
+	if (sizeof(table_addr) > sizeof(u32) && table_addr > (ulong)UINT_MAX) {
+		/*
+		 * We need to put this >32-bit pointer into the table but the
+		 * field is only 32 bits wide.
+		 */
+		printf("WARNING: SMBIOS table_address overflow %llx\n",
+		       (unsigned long long)table_addr);
+		table_addr = 0;
+	}
+	se->struct_table_address = table_addr;
+
 	se->struct_count = handle;
 
 	/* calculate checksums */
@@ -298,6 +331,7 @@
 	isize = sizeof(struct smbios_entry) - SMBIOS_INTERMEDIATE_OFFSET;
 	se->intermediate_checksum = table_compute_checksum(istart, isize);
 	se->checksum = table_compute_checksum(se, sizeof(struct smbios_entry));
+	unmap_sysmem(se);
 
 	return addr;
 }
diff --git a/lib/string.c b/lib/string.c
index c4ca944..af17c16 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -15,6 +15,7 @@
  *    reentrant and should be faster). Use only strsep() in new code, please.
  */
 
+#include <config.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
diff --git a/lib/tpm-common.c b/lib/tpm-common.c
index a440639..6afe59b 100644
--- a/lib/tpm-common.c
+++ b/lib/tpm-common.c
@@ -151,9 +151,9 @@
 	return get_unaligned_be32(response + return_code_offset);
 }
 
-u32 tpm_sendrecv_command(const void *command, void *response, size_t *size_ptr)
+u32 tpm_sendrecv_command(struct udevice *dev, const void *command,
+			 void *response, size_t *size_ptr)
 {
-	struct udevice *dev;
 	int err, ret;
 	u8 response_buffer[COMMAND_BUFFER_SIZE];
 	size_t response_length;
@@ -166,9 +166,6 @@
 		response_length = sizeof(response_buffer);
 	}
 
-	ret = uclass_first_device_err(UCLASS_TPM, &dev);
-	if (ret)
-		return ret;
 	err = tpm_xfer(dev, command, tpm_command_size(command),
 		       response, &response_length);
 
@@ -188,14 +185,7 @@
 	return ret;
 }
 
-int tpm_init(void)
+int tpm_init(struct udevice *dev)
 {
-	struct udevice *dev;
-	int err;
-
-	err = uclass_first_device_err(UCLASS_TPM, &dev);
-	if (err)
-		return err;
-
 	return tpm_open(dev);
 }
diff --git a/lib/tpm-utils.h b/lib/tpm-utils.h
index a9cb7dc..d680d14 100644
--- a/lib/tpm-utils.h
+++ b/lib/tpm-utils.h
@@ -19,24 +19,6 @@
 #define tpm_u32(x) tpm_u16((x) >> 16), tpm_u16((x) & 0xFFFF)
 
 /**
- * tpm_open() - Request access to locality 0 for the caller
- *
- * After all commands have been completed the caller is supposed to
- * call tpm_close().
- *
- * Returns 0 on success, -ve on failure.
- */
-int tpm_open(struct udevice *dev);
-
-/**
- * tpm_close() - Close the current session
- *
- * Releasing the locked locality. Returns 0 on success, -ve 1 on
- * failure (in case lock removal did not succeed).
- */
-int tpm_close(struct udevice *dev);
-
-/**
  * Pack data into a byte string.  The data types are specified in
  * the format string: 'b' means unsigned byte, 'w' unsigned word,
  * 'd' unsigned double word, and 's' byte string.  The data are a
@@ -96,6 +78,7 @@
  *			is a bidirectional
  * @return return code of the TPM response
  */
-u32 tpm_sendrecv_command(const void *command, void *response, size_t *size_ptr);
+u32 tpm_sendrecv_command(struct udevice *dev, const void *command,
+			 void *response, size_t *size_ptr);
 
 #endif /* __TPM_UTILS_H */
diff --git a/lib/tpm-v1.c b/lib/tpm-v1.c
index 9d45c3d..f29e62f 100644
--- a/lib/tpm-v1.c
+++ b/lib/tpm-v1.c
@@ -31,7 +31,7 @@
 
 #endif /* CONFIG_TPM_AUTH_SESSIONS */
 
-u32 tpm_startup(enum tpm_startup_type mode)
+u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode)
 {
 	const u8 command[12] = {
 		0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0,
@@ -44,49 +44,49 @@
 			     mode_offset, mode))
 		return TPM_LIB_ERROR;
 
-	return tpm_sendrecv_command(buf, NULL, NULL);
+	return tpm_sendrecv_command(dev, buf, NULL, NULL);
 }
 
-u32 tpm_resume(void)
+u32 tpm_resume(struct udevice *dev)
 {
-	return tpm_startup(TPM_ST_STATE);
+	return tpm_startup(dev, TPM_ST_STATE);
 }
 
-u32 tpm_self_test_full(void)
+u32 tpm_self_test_full(struct udevice *dev)
 {
 	const u8 command[10] = {
 		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50,
 	};
-	return tpm_sendrecv_command(command, NULL, NULL);
+	return tpm_sendrecv_command(dev, command, NULL, NULL);
 }
 
-u32 tpm_continue_self_test(void)
+u32 tpm_continue_self_test(struct udevice *dev)
 {
 	const u8 command[10] = {
 		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53,
 	};
-	return tpm_sendrecv_command(command, NULL, NULL);
+	return tpm_sendrecv_command(dev, command, NULL, NULL);
 }
 
-u32 tpm_clear_and_reenable(void)
+u32 tpm_clear_and_reenable(struct udevice *dev)
 {
 	u32 ret;
 
 	log_info("TPM: Clear and re-enable\n");
-	ret = tpm_force_clear();
+	ret = tpm_force_clear(dev);
 	if (ret != TPM_SUCCESS) {
 		log_err("Can't initiate a force clear\n");
 		return ret;
 	}
 
 #if IS_ENABLED(CONFIG_TPM_V1)
-	ret = tpm_physical_enable();
+	ret = tpm_physical_enable(dev);
 	if (ret != TPM_SUCCESS) {
 		log_err("TPM: Can't set enabled state\n");
 		return ret;
 	}
 
-	ret = tpm_physical_set_deactivated(0);
+	ret = tpm_physical_set_deactivated(dev, 0);
 	if (ret != TPM_SUCCESS) {
 		log_err("TPM: Can't set deactivated state\n");
 		return ret;
@@ -96,7 +96,7 @@
 	return TPM_SUCCESS;
 }
 
-u32 tpm_nv_define_space(u32 index, u32 perm, u32 size)
+u32 tpm_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size)
 {
 	const u8 command[101] = {
 		0x0, 0xc1,		/* TPM_TAG */
@@ -136,15 +136,15 @@
 			     size_offset, size))
 		return TPM_LIB_ERROR;
 
-	return tpm_sendrecv_command(buf, NULL, NULL);
+	return tpm_sendrecv_command(dev, buf, NULL, NULL);
 }
 
-u32 tpm_nv_set_locked(void)
+u32 tpm_nv_set_locked(struct udevice *dev)
 {
-	return tpm_nv_define_space(TPM_NV_INDEX_LOCK, 0, 0);
+	return tpm_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0);
 }
 
-u32 tpm_nv_read_value(u32 index, void *data, u32 count)
+u32 tpm_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count)
 {
 	const u8 command[22] = {
 		0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf,
@@ -163,7 +163,7 @@
 			     index_offset, index,
 			     length_offset, count))
 		return TPM_LIB_ERROR;
-	err = tpm_sendrecv_command(buf, response, &response_length);
+	err = tpm_sendrecv_command(dev, buf, response, &response_length);
 	if (err)
 		return err;
 	if (unpack_byte_string(response, response_length, "d",
@@ -178,7 +178,8 @@
 	return 0;
 }
 
-u32 tpm_nv_write_value(u32 index, const void *data, u32 length)
+u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data,
+		       u32 length)
 {
 	const u8 command[256] = {
 		0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd,
@@ -201,21 +202,22 @@
 			     length_offset, length,
 			     data_offset, data, length))
 		return TPM_LIB_ERROR;
-	err = tpm_sendrecv_command(buf, response, &response_length);
+	err = tpm_sendrecv_command(dev, buf, response, &response_length);
 	if (err)
 		return err;
 
 	return 0;
 }
 
-uint32_t tpm_set_global_lock(void)
+uint32_t tpm_set_global_lock(struct udevice *dev)
 {
 	u32 x;
 
-	return tpm_nv_write_value(TPM_NV_INDEX_0, (uint8_t *)&x, 0);
+	return tpm_nv_write_value(dev, TPM_NV_INDEX_0, (uint8_t *)&x, 0);
 }
 
-u32 tpm_extend(u32 index, const void *in_digest, void *out_digest)
+u32 tpm_extend(struct udevice *dev, u32 index, const void *in_digest,
+	       void *out_digest)
 {
 	const u8 command[34] = {
 		0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14,
@@ -234,7 +236,7 @@
 			     in_digest_offset, in_digest,
 			     PCR_DIGEST_LENGTH))
 		return TPM_LIB_ERROR;
-	err = tpm_sendrecv_command(buf, response, &response_length);
+	err = tpm_sendrecv_command(dev, buf, response, &response_length);
 	if (err)
 		return err;
 
@@ -246,7 +248,7 @@
 	return 0;
 }
 
-u32 tpm_pcr_read(u32 index, void *data, size_t count)
+u32 tpm_pcr_read(struct udevice *dev, u32 index, void *data, size_t count)
 {
 	const u8 command[14] = {
 		0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15,
@@ -264,7 +266,7 @@
 			     0, command, sizeof(command),
 			     index_offset, index))
 		return TPM_LIB_ERROR;
-	err = tpm_sendrecv_command(buf, response, &response_length);
+	err = tpm_sendrecv_command(dev, buf, response, &response_length);
 	if (err)
 		return err;
 	if (unpack_byte_string(response, response_length, "s",
@@ -274,7 +276,7 @@
 	return 0;
 }
 
-u32 tpm_tsc_physical_presence(u16 presence)
+u32 tpm_tsc_physical_presence(struct udevice *dev, u16 presence)
 {
 	const u8 command[12] = {
 		0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x0,
@@ -287,19 +289,19 @@
 			     presence_offset, presence))
 		return TPM_LIB_ERROR;
 
-	return tpm_sendrecv_command(buf, NULL, NULL);
+	return tpm_sendrecv_command(dev, buf, NULL, NULL);
 }
 
-u32 tpm_finalise_physical_presence(void)
+u32 tpm_finalise_physical_presence(struct udevice *dev)
 {
 	const u8 command[12] = {
 		0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x2, 0xa0,
 	};
 
-	return tpm_sendrecv_command(command, NULL, NULL);
+	return tpm_sendrecv_command(dev, command, NULL, NULL);
 }
 
-u32 tpm_read_pubek(void *data, size_t count)
+u32 tpm_read_pubek(struct udevice *dev, void *data, size_t count)
 {
 	const u8 command[30] = {
 		0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c,
@@ -312,7 +314,7 @@
 	u32 data_size;
 	u32 err;
 
-	err = tpm_sendrecv_command(command, response, &response_length);
+	err = tpm_sendrecv_command(dev, command, response, &response_length);
 	if (err)
 		return err;
 	if (unpack_byte_string(response, response_length, "d",
@@ -330,34 +332,34 @@
 	return 0;
 }
 
-u32 tpm_force_clear(void)
+u32 tpm_force_clear(struct udevice *dev)
 {
 	const u8 command[10] = {
 		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d,
 	};
 
-	return tpm_sendrecv_command(command, NULL, NULL);
+	return tpm_sendrecv_command(dev, command, NULL, NULL);
 }
 
-u32 tpm_physical_enable(void)
+u32 tpm_physical_enable(struct udevice *dev)
 {
 	const u8 command[10] = {
 		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f,
 	};
 
-	return tpm_sendrecv_command(command, NULL, NULL);
+	return tpm_sendrecv_command(dev, command, NULL, NULL);
 }
 
-u32 tpm_physical_disable(void)
+u32 tpm_physical_disable(struct udevice *dev)
 {
 	const u8 command[10] = {
 		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70,
 	};
 
-	return tpm_sendrecv_command(command, NULL, NULL);
+	return tpm_sendrecv_command(dev, command, NULL, NULL);
 }
 
-u32 tpm_physical_set_deactivated(u8 state)
+u32 tpm_physical_set_deactivated(struct udevice *dev, u8 state)
 {
 	const u8 command[11] = {
 		0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72,
@@ -370,10 +372,11 @@
 			     state_offset, state))
 		return TPM_LIB_ERROR;
 
-	return tpm_sendrecv_command(buf, NULL, NULL);
+	return tpm_sendrecv_command(dev, buf, NULL, NULL);
 }
 
-u32 tpm_get_capability(u32 cap_area, u32 sub_cap, void *cap, size_t count)
+u32 tpm_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap,
+		       void *cap, size_t count)
 {
 	const u8 command[22] = {
 		0x0, 0xc1,		/* TPM_TAG */
@@ -397,7 +400,7 @@
 			     cap_area_offset, cap_area,
 			     sub_cap_offset, sub_cap))
 		return TPM_LIB_ERROR;
-	err = tpm_sendrecv_command(buf, response, &response_length);
+	err = tpm_sendrecv_command(dev, buf, response, &response_length);
 	if (err)
 		return err;
 	if (unpack_byte_string(response, response_length, "d",
@@ -412,7 +415,8 @@
 	return 0;
 }
 
-u32 tpm_get_permanent_flags(struct tpm_permanent_flags *pflags)
+u32 tpm_get_permanent_flags(struct udevice *dev,
+			    struct tpm_permanent_flags *pflags)
 {
 	const u8 command[22] = {
 		0x0, 0xc1,		/* TPM_TAG */
@@ -429,7 +433,7 @@
 	u32 err;
 	u32 data_size;
 
-	err = tpm_sendrecv_command(command, response, &response_length);
+	err = tpm_sendrecv_command(dev, command, response, &response_length);
 	if (err)
 		return err;
 	if (unpack_byte_string(response, response_length, "d",
@@ -450,7 +454,7 @@
 	return 0;
 }
 
-u32 tpm_get_permissions(u32 index, u32 *perm)
+u32 tpm_get_permissions(struct udevice *dev, u32 index, u32 *perm)
 {
 	const u8 command[22] = {
 		0x0, 0xc1,		/* TPM_TAG */
@@ -468,7 +472,7 @@
 	if (pack_byte_string(buf, sizeof(buf), "d", 0, command, sizeof(command),
 			     index_offset, index))
 		return TPM_LIB_ERROR;
-	err = tpm_sendrecv_command(buf, response, &response_length);
+	err = tpm_sendrecv_command(dev, buf, response, &response_length);
 	if (err)
 		return err;
 	if (unpack_byte_string(response, response_length, "d",
@@ -479,7 +483,7 @@
 }
 
 #ifdef CONFIG_TPM_FLUSH_RESOURCES
-u32 tpm_flush_specific(u32 key_handle, u32 resource_type)
+u32 tpm_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type)
 {
 	const u8 command[18] = {
 		0x00, 0xc1,             /* TPM_TAG */
@@ -500,7 +504,7 @@
 			     resource_type_offset, resource_type))
 		return TPM_LIB_ERROR;
 
-	err = tpm_sendrecv_command(buf, response, &response_length);
+	err = tpm_sendrecv_command(dev, buf, response, &response_length);
 	if (err)
 		return err;
 	return 0;
@@ -638,7 +642,7 @@
 	return TPM_SUCCESS;
 }
 
-u32 tpm_terminate_auth_session(u32 auth_handle)
+u32 tpm_terminate_auth_session(struct udevice *dev, u32 auth_handle)
 {
 	const u8 command[18] = {
 		0x00, 0xc1,		/* TPM_TAG */
@@ -657,19 +661,19 @@
 	if (oiap_session.valid && oiap_session.handle == auth_handle)
 		oiap_session.valid = 0;
 
-	return tpm_sendrecv_command(request, NULL, NULL);
+	return tpm_sendrecv_command(dev, request, NULL, NULL);
 }
 
-u32 tpm_end_oiap(void)
+u32 tpm_end_oiap(struct udevice *dev)
 {
 	u32 err = TPM_SUCCESS;
 
 	if (oiap_session.valid)
-		err = tpm_terminate_auth_session(oiap_session.handle);
+		err = tpm_terminate_auth_session(dev, oiap_session.handle);
 	return err;
 }
 
-u32 tpm_oiap(u32 *auth_handle)
+u32 tpm_oiap(struct udevice *dev, u32 *auth_handle)
 {
 	const u8 command[10] = {
 		0x00, 0xc1,		/* TPM_TAG */
@@ -683,9 +687,9 @@
 	u32 err;
 
 	if (oiap_session.valid)
-		tpm_terminate_auth_session(oiap_session.handle);
+		tpm_terminate_auth_session(dev, oiap_session.handle);
 
-	err = tpm_sendrecv_command(command, response, &response_length);
+	err = tpm_sendrecv_command(dev, command, response, &response_length);
 	if (err)
 		return err;
 	if (unpack_byte_string(response, response_length, "ds",
@@ -699,8 +703,9 @@
 	return 0;
 }
 
-u32 tpm_load_key2_oiap(u32 parent_handle, const void *key, size_t key_length,
-		       const void *parent_key_usage_auth, u32 *key_handle)
+u32 tpm_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key,
+		       size_t key_length, const void *parent_key_usage_auth,
+		       u32 *key_handle)
 {
 	const u8 command[14] = {
 		0x00, 0xc2,		/* TPM_TAG */
@@ -719,7 +724,7 @@
 	u32 err;
 
 	if (!oiap_session.valid) {
-		err = tpm_oiap(NULL);
+		err = tpm_oiap(dev, NULL);
 		if (err)
 			return err;
 	}
@@ -739,7 +744,7 @@
 				  parent_key_usage_auth);
 	if (err)
 		return err;
-	err = tpm_sendrecv_command(request, response, &response_length);
+	err = tpm_sendrecv_command(dev, request, response, &response_length);
 	if (err) {
 		if (err == TPM_AUTHFAIL)
 			oiap_session.valid = 0;
@@ -764,7 +769,8 @@
 	return 0;
 }
 
-u32 tpm_get_pub_key_oiap(u32 key_handle, const void *usage_auth, void *pubkey,
+u32 tpm_get_pub_key_oiap(struct udevice *dev, u32 key_handle,
+			 const void *usage_auth, void *pubkey,
 			 size_t *pubkey_len)
 {
 	const u8 command[14] = {
@@ -783,7 +789,7 @@
 	u32 err;
 
 	if (!oiap_session.valid) {
-		err = tpm_oiap(NULL);
+		err = tpm_oiap(dev, NULL);
 		if (err)
 			return err;
 	}
@@ -799,7 +805,7 @@
 				  request + sizeof(command), usage_auth);
 	if (err)
 		return err;
-	err = tpm_sendrecv_command(request, response, &response_length);
+	err = tpm_sendrecv_command(dev, request, response, &response_length);
 	if (err) {
 		if (err == TPM_AUTHFAIL)
 			oiap_session.valid = 0;
@@ -829,8 +835,8 @@
 }
 
 #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
-u32 tpm_find_key_sha1(const u8 auth[20], const u8 pubkey_digest[20],
-		      u32 *handle)
+u32 tpm_find_key_sha1(struct udevice *dev, const u8 auth[20],
+		      const u8 pubkey_digest[20], u32 *handle)
 {
 	u16 key_count;
 	u32 key_handles[10];
@@ -842,7 +848,8 @@
 	unsigned int i;
 
 	/* fetch list of already loaded keys in the TPM */
-	err = tpm_get_capability(TPM_CAP_HANDLE, TPM_RT_KEY, buf, sizeof(buf));
+	err = tpm_get_capability(dev, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
+				 sizeof(buf));
 	if (err)
 		return -1;
 	key_count = get_unaligned_be16(buf);
@@ -870,7 +877,7 @@
 
 #endif /* CONFIG_TPM_AUTH_SESSIONS */
 
-u32 tpm_get_random(void *data, u32 count)
+u32 tpm_get_random(struct udevice *dev, void *data, u32 count)
 {
 	const u8 command[14] = {
 		0x0, 0xc1,		/* TPM_TAG */
@@ -894,7 +901,8 @@
 				     0, command, sizeof(command),
 				     length_offset, this_bytes))
 			return TPM_LIB_ERROR;
-		err = tpm_sendrecv_command(buf, response, &response_length);
+		err = tpm_sendrecv_command(dev, buf, response,
+					   &response_length);
 		if (err)
 			return err;
 		if (unpack_byte_string(response, response_length, "d",
diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index f1bbca8..f89592d 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -10,7 +10,7 @@
 #include <tpm-v2.h>
 #include "tpm-utils.h"
 
-u32 tpm2_startup(enum tpm2_startup_types mode)
+u32 tpm2_startup(struct udevice *dev, enum tpm2_startup_types mode)
 {
 	const u8 command_v2[12] = {
 		tpm_u16(TPM2_ST_NO_SESSIONS),
@@ -24,14 +24,14 @@
 	 * Note TPM2_Startup command will return RC_SUCCESS the first time,
 	 * but will return RC_INITIALIZE otherwise.
 	 */
-	ret = tpm_sendrecv_command(command_v2, NULL, NULL);
+	ret = tpm_sendrecv_command(dev, command_v2, NULL, NULL);
 	if (ret && ret != TPM2_RC_INITIALIZE)
 		return ret;
 
 	return 0;
 }
 
-u32 tpm2_self_test(enum tpm2_yes_no full_test)
+u32 tpm2_self_test(struct udevice *dev, enum tpm2_yes_no full_test)
 {
 	const u8 command_v2[12] = {
 		tpm_u16(TPM2_ST_NO_SESSIONS),
@@ -40,10 +40,11 @@
 		full_test,
 	};
 
-	return tpm_sendrecv_command(command_v2, NULL, NULL);
+	return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
 }
 
-u32 tpm2_clear(u32 handle, const char *pw, const ssize_t pw_sz)
+u32 tpm2_clear(struct udevice *dev, u32 handle, const char *pw,
+	       const ssize_t pw_sz)
 {
 	u8 command_v2[COMMAND_BUFFER_SIZE] = {
 		tpm_u16(TPM2_ST_SESSIONS),	/* TAG */
@@ -75,10 +76,10 @@
 	if (ret)
 		return TPM_LIB_ERROR;
 
-	return tpm_sendrecv_command(command_v2, NULL, NULL);
+	return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
 }
 
-u32 tpm2_pcr_extend(u32 index, const uint8_t *digest)
+u32 tpm2_pcr_extend(struct udevice *dev, u32 index, const uint8_t *digest)
 {
 	u8 command_v2[COMMAND_BUFFER_SIZE] = {
 		tpm_u16(TPM2_ST_SESSIONS),	/* TAG */
@@ -113,11 +114,11 @@
 	if (ret)
 		return TPM_LIB_ERROR;
 
-	return tpm_sendrecv_command(command_v2,	NULL, NULL);
+	return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
 }
 
-u32 tpm2_pcr_read(u32 idx, unsigned int idx_min_sz, void *data,
-		  unsigned int *updates)
+u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz,
+		  void *data, unsigned int *updates)
 {
 	u8 idx_array_sz = max(idx_min_sz, DIV_ROUND_UP(idx, 8));
 	u8 command_v2[COMMAND_BUFFER_SIZE] = {
@@ -142,7 +143,7 @@
 			     17 + pcr_sel_idx, pcr_sel_bit))
 		return TPM_LIB_ERROR;
 
-	ret = tpm_sendrecv_command(command_v2, response, &response_len);
+	ret = tpm_sendrecv_command(dev, command_v2, response, &response_len);
 	if (ret)
 		return ret;
 
@@ -158,8 +159,8 @@
 	return 0;
 }
 
-u32 tpm2_get_capability(u32 capability, u32 property, void *buf,
-			size_t prop_count)
+u32 tpm2_get_capability(struct udevice *dev, u32 capability, u32 property,
+			void *buf, size_t prop_count)
 {
 	u8 command_v2[COMMAND_BUFFER_SIZE] = {
 		tpm_u16(TPM2_ST_NO_SESSIONS),		/* TAG */
@@ -175,7 +176,7 @@
 	unsigned int properties_off;
 	int ret;
 
-	ret = tpm_sendrecv_command(command_v2, response, &response_len);
+	ret = tpm_sendrecv_command(dev, command_v2, response, &response_len);
 	if (ret)
 		return ret;
 
@@ -191,7 +192,7 @@
 	return 0;
 }
 
-u32 tpm2_dam_reset(const char *pw, const ssize_t pw_sz)
+u32 tpm2_dam_reset(struct udevice *dev, const char *pw, const ssize_t pw_sz)
 {
 	u8 command_v2[COMMAND_BUFFER_SIZE] = {
 		tpm_u16(TPM2_ST_SESSIONS),	/* TAG */
@@ -223,11 +224,12 @@
 	if (ret)
 		return TPM_LIB_ERROR;
 
-	return tpm_sendrecv_command(command_v2, NULL, NULL);
+	return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
 }
 
-u32 tpm2_dam_parameters(const char *pw, const ssize_t pw_sz,
-			unsigned int max_tries, unsigned int recovery_time,
+u32 tpm2_dam_parameters(struct udevice *dev, const char *pw,
+			const ssize_t pw_sz, unsigned int max_tries,
+			unsigned int recovery_time,
 			unsigned int lockout_recovery)
 {
 	u8 command_v2[COMMAND_BUFFER_SIZE] = {
@@ -271,11 +273,12 @@
 	if (ret)
 		return TPM_LIB_ERROR;
 
-	return tpm_sendrecv_command(command_v2, NULL, NULL);
+	return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
 }
 
-int tpm2_change_auth(u32 handle, const char *newpw, const ssize_t newpw_sz,
-		     const char *oldpw, const ssize_t oldpw_sz)
+int tpm2_change_auth(struct udevice *dev, u32 handle, const char *newpw,
+		     const ssize_t newpw_sz, const char *oldpw,
+		     const ssize_t oldpw_sz)
 {
 	unsigned int offset = 27;
 	u8 command_v2[COMMAND_BUFFER_SIZE] = {
@@ -315,11 +318,11 @@
 	if (ret)
 		return TPM_LIB_ERROR;
 
-	return tpm_sendrecv_command(command_v2, NULL, NULL);
+	return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
 }
 
-u32 tpm2_pcr_setauthpolicy(const char *pw, const ssize_t pw_sz, u32 index,
-			   const char *key)
+u32 tpm2_pcr_setauthpolicy(struct udevice *dev, const char *pw,
+			   const ssize_t pw_sz, u32 index, const char *key)
 {
 	u8 command_v2[COMMAND_BUFFER_SIZE] = {
 		tpm_u16(TPM2_ST_SESSIONS),	/* TAG */
@@ -370,11 +373,12 @@
 	if (ret)
 		return TPM_LIB_ERROR;
 
-	return tpm_sendrecv_command(command_v2, NULL, NULL);
+	return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
 }
 
-u32 tpm2_pcr_setauthvalue(const char *pw, const ssize_t pw_sz, u32 index,
-			  const char *key, const ssize_t key_sz)
+u32 tpm2_pcr_setauthvalue(struct udevice *dev, const char *pw,
+			  const ssize_t pw_sz, u32 index, const char *key,
+			  const ssize_t key_sz)
 {
 	u8 command_v2[COMMAND_BUFFER_SIZE] = {
 		tpm_u16(TPM2_ST_SESSIONS),	/* TAG */
@@ -415,5 +419,5 @@
 	if (ret)
 		return TPM_LIB_ERROR;
 
-	return tpm_sendrecv_command(command_v2, NULL, NULL);
+	return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
 }
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 4dceb6d..a4f16bb 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -381,7 +381,7 @@
 
 quiet_cmd_efi_ld = LD      $@
 cmd_efi_ld = $(LD) -nostdlib -znocombreloc -T $(EFI_LDS_PATH) -shared \
-		-Bsymbolic $^ -o $@
+		-Bsymbolic -s $^ -o $@
 
 EFI_LDS_PATH = $(srctree)/arch/$(ARCH)/lib/$(EFI_LDS)
 
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index 7416abe..22bd8f7 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -219,6 +219,8 @@
 ALL-$(CONFIG_ARCH_ZYNQ)		+= $(obj)/boot.bin
 ALL-$(CONFIG_ARCH_ZYNQMP)	+= $(obj)/boot.bin
 
+ALL-$(CONFIG_ARCH_MEDIATEK)	+= $(obj)/u-boot-spl-mtk.bin
+
 all:	$(ALL-y)
 
 quiet_cmd_cat = CAT     $@
@@ -349,6 +351,15 @@
 $(obj)/sunxi-spl-with-ecc.bin: $(obj)/sunxi-spl.bin
 	$(call if_changed,sunxi_spl_image_builder)
 
+
+# MediaTek's specific SPL build
+MKIMAGEFLAGS_u-boot-spl-mtk.bin = -T mtk_image \
+	-a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) \
+	-n "$(patsubst "%",%,$(CONFIG_MTK_BROM_HEADER_INFO))"
+
+$(obj)/u-boot-spl-mtk.bin: $(obj)/u-boot-spl.bin FORCE
+	$(call if_changed,mkimage)
+
 # Rule to link u-boot-spl
 # May be overridden by arch/$(ARCH)/config.mk
 quiet_cmd_u-boot-spl ?= LD      $@
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 1404fd8..b8addea 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -960,7 +960,6 @@
 CONFIG_IMX_VIDEO_SKIP
 CONFIG_INETSPACE_V2
 CONFIG_INITRD_TAG
-CONFIG_INIT_CRITICAL
 CONFIG_INIT_IGNORE_ERROR
 CONFIG_INI_ALLOW_MULTILINE
 CONFIG_INI_CASE_INSENSITIVE
@@ -1199,7 +1198,6 @@
 CONFIG_MALTA
 CONFIG_MARCO_MEMSET
 CONFIG_MARUBUN_PCCARD
-CONFIG_MARVELL
 CONFIG_MARVELL_GPIO
 CONFIG_MARVELL_MFP
 CONFIG_MASK_AER_AO
@@ -1662,7 +1660,6 @@
 CONFIG_RTC_FTRTC010
 CONFIG_RTC_IMXDI
 CONFIG_RTC_M41T11
-CONFIG_RTC_M41T62
 CONFIG_RTC_MC13XXX
 CONFIG_RTC_MCFRRTC
 CONFIG_RTC_MCP79411
@@ -4055,7 +4052,6 @@
 CONFIG_SYS_RTC_OSCILLATOR
 CONFIG_SYS_RTC_REG_BASE_ADDR
 CONFIG_SYS_RTC_SETUP
-CONFIG_SYS_RV3029_TCR
 CONFIG_SYS_RX_ETH_BUFFER
 CONFIG_SYS_SATA
 CONFIG_SYS_SATA1
diff --git a/test/Makefile b/test/Makefile
index 1e43473..2fe41f4 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -2,6 +2,7 @@
 #
 # (C) Copyright 2012 The Chromium Authors
 
+obj-$(CONFIG_SANDBOX) += bloblist.o
 obj-$(CONFIG_UNIT_TEST) += cmd_ut.o
 obj-$(CONFIG_UNIT_TEST) += ut.o
 obj-$(CONFIG_SANDBOX) += command_ut.o
diff --git a/test/README b/test/README
index 873a4e1..4bc9ca3 100644
--- a/test/README
+++ b/test/README
@@ -10,11 +10,15 @@
 
 To run most tests on sandbox, type this:
 
-    test/run
+    make check
 
 in the U-Boot directory. Note that only the pytest suite is run using this
 command.
 
+Some tests take ages to run. To run just the quick ones, type this:
+
+    make qcheck
+
 
 Sandbox
 -------
diff --git a/test/bloblist.c b/test/bloblist.c
new file mode 100644
index 0000000..89bdb01
--- /dev/null
+++ b/test/bloblist.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2018, Google Inc. All rights reserved.
+ */
+
+#include <common.h>
+#include <bloblist.h>
+#include <log.h>
+#include <mapmem.h>
+#include <test/suites.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Declare a new compression test */
+#define BLOBLIST_TEST(_name, _flags) \
+		UNIT_TEST(_name, _flags, bloblist_test)
+
+enum {
+	TEST_TAG		= 1,
+	TEST_TAG2		= 2,
+	TEST_TAG_MISSING	= 3,
+
+	TEST_SIZE		= 10,
+	TEST_SIZE2		= 20,
+
+	TEST_ADDR		= CONFIG_BLOBLIST_ADDR,
+	TEST_BLOBLIST_SIZE	= 0x100,
+};
+
+static struct bloblist_hdr *clear_bloblist(void)
+{
+	struct bloblist_hdr *hdr;
+
+	/* Clear out any existing bloblist so we have a clean slate */
+	hdr = map_sysmem(CONFIG_BLOBLIST_ADDR, TEST_BLOBLIST_SIZE);
+	memset(hdr, '\0', TEST_BLOBLIST_SIZE);
+
+	return hdr;
+}
+
+static int bloblist_test_init(struct unit_test_state *uts)
+{
+	struct bloblist_hdr *hdr;
+
+	hdr = clear_bloblist();
+	ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+	ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+	hdr->version++;
+	ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR,
+						     TEST_BLOBLIST_SIZE));
+
+	ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10, 0));
+	ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0));
+	ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+
+	ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+	ut_assertok(bloblist_finish());
+	ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+	hdr->flags++;
+	ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+
+	return 1;
+}
+BLOBLIST_TEST(bloblist_test_init, 0);
+
+static int bloblist_test_blob(struct unit_test_state *uts)
+{
+	struct bloblist_hdr *hdr;
+	struct bloblist_rec *rec, *rec2;
+	char *data;
+
+	/* At the start there should be no records */
+	hdr = clear_bloblist();
+	ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
+	ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+
+	/* Add a record and check that we can find it */
+	data = bloblist_add(TEST_TAG, TEST_SIZE);
+	rec = (void *)(hdr + 1);
+	ut_asserteq_ptr(rec + 1, data);
+	data = bloblist_find(TEST_TAG, TEST_SIZE);
+	ut_asserteq_ptr(rec + 1, data);
+
+	/* Check the 'ensure' method */
+	ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
+	ut_assertnull(bloblist_ensure(TEST_TAG, TEST_SIZE2));
+	rec2 = (struct bloblist_rec *)(data + ALIGN(TEST_SIZE, BLOBLIST_ALIGN));
+
+	/* Check for a non-existent record */
+	ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
+	ut_asserteq_ptr(rec2 + 1, bloblist_ensure(TEST_TAG2, TEST_SIZE2));
+	ut_assertnull(bloblist_find(TEST_TAG_MISSING, 0));
+
+	return 0;
+}
+BLOBLIST_TEST(bloblist_test_blob, 0);
+
+static int bloblist_test_bad_blob(struct unit_test_state *uts)
+{
+	struct bloblist_hdr *hdr;
+	void *data;
+
+	hdr = clear_bloblist();
+	ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+	data = hdr + 1;
+	data += sizeof(struct bloblist_rec);
+	ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
+	ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
+
+	return 0;
+}
+BLOBLIST_TEST(bloblist_test_bad_blob, 0);
+
+static int bloblist_test_checksum(struct unit_test_state *uts)
+{
+	struct bloblist_hdr *hdr;
+	char *data, *data2;
+
+	hdr = clear_bloblist();
+	ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+	ut_assertok(bloblist_finish());
+	ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+
+	/*
+	 * Now change things amd make sure that the checksum notices. We cannot
+	 * change the size or alloced fields, since that will crash the code.
+	 * It has to rely on these being correct.
+	 */
+	hdr->flags--;
+	ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+	hdr->flags++;
+
+	hdr->size--;
+	ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+	hdr->size++;
+
+	hdr->spare++;
+	ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+	hdr->spare--;
+
+	hdr->chksum++;
+	ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+	hdr->chksum--;
+
+	/* Make sure the checksum changes when we add blobs */
+	data = bloblist_add(TEST_TAG, TEST_SIZE);
+	ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+
+	data2 = bloblist_add(TEST_TAG2, TEST_SIZE2);
+	ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+	ut_assertok(bloblist_finish());
+
+	/* It should also change if we change the data */
+	ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+	*data += 1;
+	ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+	*data -= 1;
+
+	ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+	*data2 += 1;
+	ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+	*data2 -= 1;
+
+	/*
+	 * Changing data outside the range of valid data should not affect
+	 * the checksum.
+	 */
+	ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+	data[TEST_SIZE]++;
+	data2[TEST_SIZE2]++;
+	ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+
+	return 0;
+}
+
+BLOBLIST_TEST(bloblist_test_checksum, 0);
+
+int do_ut_bloblist(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	struct unit_test *tests = ll_entry_start(struct unit_test,
+						 bloblist_test);
+	const int n_ents = ll_entry_count(struct unit_test, bloblist_test);
+
+	return cmd_ut_category("bloblist", tests, n_ents, argc, argv);
+}
diff --git a/test/cmd_ut.c b/test/cmd_ut.c
index b7e01a4..56924a5 100644
--- a/test/cmd_ut.c
+++ b/test/cmd_ut.c
@@ -55,6 +55,8 @@
 #ifdef CONFIG_SANDBOX
 	U_BOOT_CMD_MKENT(compression, CONFIG_SYS_MAXARGS, 1, do_ut_compression,
 			 "", ""),
+	U_BOOT_CMD_MKENT(bloblist, CONFIG_SYS_MAXARGS, 1, do_ut_bloblist,
+			 "", ""),
 #endif
 };
 
@@ -97,6 +99,7 @@
 static char ut_help_text[] =
 	"all - execute all enabled tests\n"
 #ifdef CONFIG_SANDBOX
+	"ut bloblist - Test bloblist implementation\n"
 	"ut compression - Test compressors and bootm decompression\n"
 #endif
 #ifdef CONFIG_UT_DM
diff --git a/test/dm/i2c.c b/test/dm/i2c.c
index 772f62b..cbbd4aa 100644
--- a/test/dm/i2c.c
+++ b/test/dm/i2c.c
@@ -35,7 +35,7 @@
 	 */
 	ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
 	ut_assertok(dm_i2c_probe(bus, chip, 0, &dev));
-	ut_asserteq(-ENODEV, dm_i2c_probe(bus, no_chip, 0, &dev));
+	ut_asserteq(-ENOENT, dm_i2c_probe(bus, no_chip, 0, &dev));
 	ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_I2C, 1, &bus));
 
 	return 0;
diff --git a/test/dm/misc.c b/test/dm/misc.c
index 6127966..4d4232a 100644
--- a/test/dm/misc.c
+++ b/test/dm/misc.c
@@ -21,9 +21,9 @@
 	ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "misc-test", &dev));
 
 	/* Read / write tests */
-	ut_assertok(misc_write(dev, 0, "TEST", 4));
-	ut_assertok(misc_write(dev, 4, "WRITE", 5));
-	ut_assertok(misc_read(dev, 0, buf, 9));
+	ut_asserteq(4, misc_write(dev, 0, "TEST", 4));
+	ut_asserteq(5, misc_write(dev, 4, "WRITE", 5));
+	ut_asserteq(9, misc_read(dev, 0, buf, 9));
 
 	ut_assertok(memcmp(buf, "TESTWRITE", 9));
 
diff --git a/test/dm/rtc.c b/test/dm/rtc.c
index e2bc648..7188742 100644
--- a/test/dm/rtc.c
+++ b/test/dm/rtc.c
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <i2c.h>
 #include <rtc.h>
 #include <asm/io.h>
 #include <asm/test.h>
@@ -60,7 +61,7 @@
 	ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
 	ut_assertok(dm_rtc_get(dev, &now));
 
-	ut_assertok(device_find_first_child(dev, &emul));
+	ut_assertok(i2c_emul_find(dev, &emul));
 	ut_assert(emul != NULL);
 
 	/* Tell the RTC to go into manual mode */
@@ -125,7 +126,7 @@
 	ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
 	ut_assertok(dm_rtc_get(dev, &now));
 
-	ut_assertok(device_find_first_child(dev, &emul));
+	ut_assertok(i2c_emul_find(dev, &emul));
 	ut_assert(emul != NULL);
 
 	old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, 0);
@@ -154,9 +155,9 @@
 	ut_assertok(uclass_get_device(UCLASS_RTC, 1, &dev2));
 	ut_assertok(dm_rtc_get(dev2, &now2));
 
-	ut_assertok(device_find_first_child(dev1, &emul1));
+	ut_assertok(i2c_emul_find(dev1, &emul1));
 	ut_assert(emul1 != NULL);
-	ut_assertok(device_find_first_child(dev2, &emul2));
+	ut_assertok(i2c_emul_find(dev2, &emul2));
 	ut_assert(emul2 != NULL);
 
 	offset = sandbox_i2c_rtc_set_offset(emul1, false, -1);
diff --git a/test/dm/sf.c b/test/dm/sf.c
index 35241b9..3788d59 100644
--- a/test/dm/sf.c
+++ b/test/dm/sf.c
@@ -6,16 +6,67 @@
 #include <common.h>
 #include <dm.h>
 #include <fdtdec.h>
+#include <mapmem.h>
+#include <os.h>
 #include <spi.h>
 #include <spi_flash.h>
 #include <asm/state.h>
+#include <asm/test.h>
 #include <dm/test.h>
 #include <dm/util.h>
 #include <test/ut.h>
 
-/* Test that sandbox SPI flash works correctly */
+/* Simple test of sandbox SPI flash */
 static int dm_test_spi_flash(struct unit_test_state *uts)
 {
+	struct udevice *dev, *emul;
+	int full_size = 0x200000;
+	int size = 0x10000;
+	u8 *src, *dst;
+	int i;
+
+	src = map_sysmem(0x20000, full_size);
+	ut_assertok(os_write_file("spi.bin", src, full_size));
+	ut_assertok(uclass_first_device_err(UCLASS_SPI_FLASH, &dev));
+
+	dst = map_sysmem(0x20000 + full_size, full_size);
+	ut_assertok(spi_flash_read_dm(dev, 0, size, dst));
+	ut_assertok(memcmp(src, dst, size));
+
+	/* Erase */
+	ut_assertok(spi_flash_erase_dm(dev, 0, size));
+	ut_assertok(spi_flash_read_dm(dev, 0, size, dst));
+	for (i = 0; i < size; i++)
+		ut_asserteq(dst[i], 0xff);
+
+	/* Write some new data */
+	for (i = 0; i < size; i++)
+		src[i] = i;
+	ut_assertok(spi_flash_write_dm(dev, 0, size, src));
+	ut_assertok(spi_flash_read_dm(dev, 0, size, dst));
+	ut_assertok(memcmp(src, dst, size));
+
+	/* Try the write-protect stuff */
+	ut_assertok(uclass_first_device_err(UCLASS_SPI_EMUL, &emul));
+	ut_asserteq(0, spl_flash_get_sw_write_prot(dev));
+	sandbox_sf_set_block_protect(emul, 1);
+	ut_asserteq(1, spl_flash_get_sw_write_prot(dev));
+	sandbox_sf_set_block_protect(emul, 0);
+	ut_asserteq(0, spl_flash_get_sw_write_prot(dev));
+
+	/*
+	 * Since we are about to destroy all devices, we must tell sandbox
+	 * to forget the emulation device
+	 */
+	sandbox_sf_unbind_emul(state_get_current(), 0, 0);
+
+	return 0;
+}
+DM_TEST(dm_test_spi_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Functional test that sandbox SPI flash works correctly */
+static int dm_test_spi_flash_func(struct unit_test_state *uts)
+{
 	/*
 	 * Create an empty test file and run the SPI flash tests. This is a
 	 * long way from being a unit test, but it does test SPI device and
@@ -28,7 +79,7 @@
 	 * benefit is worth the extra complexity.
 	 */
 	ut_asserteq(0, run_command_list(
-		"sb save hostfs - 0 spi.bin 200000;"
+		"host save hostfs - 0 spi.bin 200000;"
 		"sf probe;"
 		"sf test 0 10000", -1,  0));
 	/*
@@ -39,4 +90,4 @@
 
 	return 0;
 }
-DM_TEST(dm_test_spi_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+DM_TEST(dm_test_spi_flash_func, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index e43acb2..0fbd9be 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -611,3 +611,50 @@
 }
 DM_TEST(dm_test_fdt_disable_enable_by_path, DM_TESTF_SCAN_PDATA |
 					    DM_TESTF_SCAN_FDT);
+
+/* Test a few uclass phandle functions */
+static int dm_test_fdt_phandle(struct unit_test_state *uts)
+{
+	struct udevice *back, *dev, *dev2;
+
+	ut_assertok(uclass_find_first_device(UCLASS_PANEL_BACKLIGHT, &back));
+	ut_asserteq(-ENOENT, uclass_find_device_by_phandle(UCLASS_REGULATOR,
+							back, "missing", &dev));
+	ut_assertok(uclass_find_device_by_phandle(UCLASS_REGULATOR, back,
+						  "power-supply", &dev));
+	ut_asserteq(0, device_active(dev));
+	ut_asserteq_str("ldo1", dev->name);
+	ut_assertok(uclass_get_device_by_phandle(UCLASS_REGULATOR, back,
+						 "power-supply", &dev2));
+	ut_asserteq_ptr(dev, dev2);
+
+	return 0;
+}
+DM_TEST(dm_test_fdt_phandle, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test device_find_first_child_by_uclass() */
+static int dm_test_first_child(struct unit_test_state *uts)
+{
+	struct udevice *i2c, *dev, *dev2;
+
+	ut_assertok(uclass_first_device_err(UCLASS_I2C, &i2c));
+	ut_assertok(device_find_first_child_by_uclass(i2c, UCLASS_RTC, &dev));
+	ut_asserteq_str("rtc@43", dev->name);
+	ut_assertok(device_find_child_by_name(i2c, "rtc@43", &dev2));
+	ut_asserteq_ptr(dev, dev2);
+	ut_assertok(device_find_child_by_name(i2c, "rtc@61", &dev2));
+	ut_asserteq_str("rtc@61", dev2->name);
+
+	ut_assertok(device_find_first_child_by_uclass(i2c, UCLASS_I2C_EEPROM,
+						      &dev));
+	ut_asserteq_str("eeprom@2c", dev->name);
+	ut_assertok(device_find_child_by_name(i2c, "eeprom@2c", &dev2));
+	ut_asserteq_ptr(dev, dev2);
+
+	ut_asserteq(-ENODEV, device_find_first_child_by_uclass(i2c,
+							UCLASS_VIDEO, &dev));
+	ut_asserteq(-ENODEV, device_find_child_by_name(i2c, "missing", &dev));
+
+	return 0;
+}
+DM_TEST(dm_test_first_child, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/dm/video.c b/test/dm/video.c
index 7def338..5d1faac 100644
--- a/test/dm/video.c
+++ b/test/dm/video.c
@@ -178,12 +178,12 @@
 
 	/* test set-cursor: [%d;%df */
 	vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd");
-	ut_asserteq(142, compress_frame_buffer(dev));
+	ut_asserteq(143, compress_frame_buffer(dev));
 
 	/* test colors (30-37 fg color, 40-47 bg color) */
 	vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */
 	vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */
-	ut_asserteq(265, compress_frame_buffer(dev));
+	ut_asserteq(272, compress_frame_buffer(dev));
 
 	return 0;
 }
diff --git a/test/fs/fs-test.sh b/test/fs/fs-test.sh
index 86308cf..721af71 100755
--- a/test/fs/fs-test.sh
+++ b/test/fs/fs-test.sh
@@ -194,7 +194,7 @@
 		;;
 
 		sb)
-		PREFIX="sb "
+		PREFIX="host "
 		WRITE="save"
 		SUFFIX="fs -"
 		;;
@@ -217,11 +217,11 @@
 
 	# In u-boot commands, <interface> stands for host or hostfs
 	# hostfs maps to the host fs.
-	# host maps to the "sb bind" that we do
+	# host maps to the "host bind" that we do
 
 	$UBOOT << EOF
 sb=$5
-setenv bind 'if test "\$sb" != sb; then sb bind 0 "$1"; fi'
+setenv bind 'if test "\$sb" != sb; then host bind 0 "$1"; fi'
 run bind
 # Test Case 1 - ls
 ${PREFIX}ls host${SUFFIX} $6
@@ -229,7 +229,7 @@
 ${PREFIX}ls host${SUFFIX} invalid_d
 #
 # We want ${PREFIX}size host 0:0 $3 for host commands and
-# sb size hostfs - $3 for hostfs commands.
+# host size hostfs - $3 for hostfs commands.
 # 1MB is 0x0010 0000
 # Test Case 2a - size of small file
 ${PREFIX}size host${SUFFIX} ${FPATH}$FILE_SMALL
@@ -575,7 +575,7 @@
 
 # In each loop, for a given file system image, we test both the
 # fs command, like load/size/write, the file system specific command
-# like: ext4load/ext4size/ext4write and the sb load/ls/save commands.
+# like: ext4load/ext4size/ext4write and the host load/ls/save commands.
 for fs in ext4 fat16 fat32; do
 
 	echo "Creating $fs image if not already present."
@@ -583,11 +583,11 @@
 	MD5_FILE_FS="${MD5_FILE}.${fs}"
 	create_image $IMAGE $fs
 
-	# sb commands test
+	# host commands test
 	echo "Creating files in $fs image if not already present."
 	create_files $IMAGE $MD5_FILE_FS
 
-	# Lets mount the image and test sb hostfs commands
+	# Lets mount the image and test host hostfs commands
 	mkdir -p "$MOUNT_DIR"
 	case "$fs" in
 		fat*)
diff --git a/test/py/tests/test_bind.py b/test/py/tests/test_bind.py
index f21b705..dee3fee 100644
--- a/test/py/tests/test_bind.py
+++ b/test/py/tests/test_bind.py
@@ -13,7 +13,7 @@
 	else:
 		leaf = leaf + '`'
 	leaf = leaf + '-- ' + name
-	line = ' *{:10.10}  [0-9]*  \[ [ +] \]   {:10.10}  {}$'.format(uclass, drv,leaf)
+	line = ' *{:10.10}  [0-9]*  \[ [ +] \]   {:20.20}  {}$'.format(uclass, drv, leaf)
 	prog = re.compile(line)
 	for l in lines:
 		if prog.match(l):
@@ -28,31 +28,31 @@
 	response = u_boot_console.run_command("bind  /bind-test generic_simple_bus")
 	assert response == ''
 	tree = u_boot_console.run_command("dm tree")
-	assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
+	assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
 	assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, False)
-	assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
+	assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
 
 	#Unbind child #1. No error expected and all devices should be there except for bind-test-child1
 	response = u_boot_console.run_command("unbind  /bind-test/bind-test-child1")
 	assert response == ''
 	tree = u_boot_console.run_command("dm tree")
-	assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
+	assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
 	assert "bind-test-child1" not in tree
-	assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
+	assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
 
 	#bind child #1. No error expected and all devices should be there
 	response = u_boot_console.run_command("bind  /bind-test/bind-test-child1 phy_sandbox")
 	assert response == ''
 	tree = u_boot_console.run_command("dm tree")
-	assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
+	assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
 	assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, True)
-	assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, False)
+	assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, False)
 
 	#Unbind child #2. No error expected and all devices should be there except for bind-test-child2
 	response = u_boot_console.run_command("unbind  /bind-test/bind-test-child2")
 	assert response == ''
 	tree = u_boot_console.run_command("dm tree")
-	assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
+	assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
 	assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, True)
 	assert "bind-test-child2" not in tree
 
@@ -61,9 +61,9 @@
 	response = u_boot_console.run_command("bind /bind-test/bind-test-child2 generic_simple_bus")
 	assert response == ''
 	tree = u_boot_console.run_command("dm tree")
-	assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
+	assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
 	assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, False)
-	assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
+	assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
 
 	#Unbind parent. No error expected. All devices should be removed and unbound
 	response = u_boot_console.run_command("unbind  /bind-test")
@@ -89,9 +89,9 @@
 	response = u_boot_console.run_command("bind  /bind-test generic_simple_bus")
 	assert response == ''
 	tree = u_boot_console.run_command("dm tree")
-	assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
+	assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
 	assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, False)
-	assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
+	assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
 
 	response = u_boot_console.run_command("unbind  /bind-test")
 	assert response == ''
@@ -138,7 +138,7 @@
 	response = u_boot_console.run_command("unbind  simple_bus {}".format(child_of_child2_index))
 	assert response == ''
 	tree = u_boot_console.run_command("dm tree")
-	assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
+	assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
 	assert not in_tree(tree, "generic_simple_bus", "simple_bus", "generic_simple_bus", 2, True)
 	child_of_child2_line = get_next_line(tree, "bind-test-child2")
 	assert child_of_child2_line == ""
@@ -161,7 +161,7 @@
 	assert response == ''
 
 	tree = u_boot_console.run_command("dm tree")
-	assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
+	assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
 
 	child_of_child2_line = get_next_line(tree, "bind-test-child2")
 	assert child_of_child2_line == ""
diff --git a/test/py/tests/test_efi_selftest.py b/test/py/tests/test_efi_selftest.py
index e0833ff..36b35ee 100644
--- a/test/py/tests/test_efi_selftest.py
+++ b/test/py/tests/test_efi_selftest.py
@@ -8,12 +8,14 @@
 
 @pytest.mark.buildconfigspec('cmd_bootefi_selftest')
 def test_efi_selftest(u_boot_console):
-	"""
-	Run bootefi selftest
-	"""
+	"""Test the UEFI implementation
 
+	:param u_boot_console: U-Boot console
+
+	This function executes all selftests that are not marked as on request.
+	"""
 	u_boot_console.run_command(cmd='setenv efi_selftest')
-	u_boot_console.run_command(cmd='bootefi selftest', wait_for_prompt=False)
+	u_boot_console.run_command(cmd='bootefi selftest ${fdtcontroladdr}', wait_for_prompt=False)
 	m = u_boot_console.p.expect(['Summary: 0 failures', 'Press any key'])
 	if m != 0:
 		raise Exception('Failures occurred during the EFI selftest')
diff --git a/test/py/tests/test_fit.py b/test/py/tests/test_fit.py
index 34696e9..49d6fea 100755
--- a/test/py/tests/test_fit.py
+++ b/test/py/tests/test_fit.py
@@ -99,15 +99,15 @@
 # then run the 'bootm' command, then save out memory from the places where
 # we expect 'bootm' to write things. Then quit.
 base_script = '''
-sb load hostfs 0 %(fit_addr)x %(fit)s
+host load hostfs 0 %(fit_addr)x %(fit)s
 fdt addr %(fit_addr)x
 bootm start %(fit_addr)x
 bootm loados
-sb save hostfs 0 %(kernel_addr)x %(kernel_out)s %(kernel_size)x
-sb save hostfs 0 %(fdt_addr)x %(fdt_out)s %(fdt_size)x
-sb save hostfs 0 %(ramdisk_addr)x %(ramdisk_out)s %(ramdisk_size)x
-sb save hostfs 0 %(loadables1_addr)x %(loadables1_out)s %(loadables1_size)x
-sb save hostfs 0 %(loadables2_addr)x %(loadables2_out)s %(loadables2_size)x
+host save hostfs 0 %(kernel_addr)x %(kernel_out)s %(kernel_size)x
+host save hostfs 0 %(fdt_addr)x %(fdt_out)s %(fdt_size)x
+host save hostfs 0 %(ramdisk_addr)x %(ramdisk_out)s %(ramdisk_size)x
+host save hostfs 0 %(loadables1_addr)x %(loadables1_out)s %(loadables1_size)x
+host save hostfs 0 %(loadables2_addr)x %(loadables2_out)s %(loadables2_size)x
 '''
 
 @pytest.mark.boardspec('sandbox')
diff --git a/test/py/tests/test_fs/test_basic.py b/test/py/tests/test_fs/test_basic.py
index c067cc9..140ca29 100644
--- a/test/py/tests/test_fs/test_basic.py
+++ b/test/py/tests/test_fs/test_basic.py
@@ -13,6 +13,7 @@
 from fstest_defs import *
 
 @pytest.mark.boardspec('sandbox')
+@pytest.mark.slow
 class TestFsBasic(object):
     def test_fs1(self, u_boot_console, fs_obj_basic):
         """
diff --git a/test/py/tests/test_fs/test_ext.py b/test/py/tests/test_fs/test_ext.py
index 38217d0..06cad55 100644
--- a/test/py/tests/test_fs/test_ext.py
+++ b/test/py/tests/test_fs/test_ext.py
@@ -13,6 +13,7 @@
 from fstest_defs import *
 
 @pytest.mark.boardspec('sandbox')
+@pytest.mark.slow
 class TestFsExt(object):
     def test_fs_ext1(self, u_boot_console, fs_obj_ext):
         """
diff --git a/test/py/tests/test_fs/test_mkdir.py b/test/py/tests/test_fs/test_mkdir.py
index d9da97b..b3fe11c 100644
--- a/test/py/tests/test_fs/test_mkdir.py
+++ b/test/py/tests/test_fs/test_mkdir.py
@@ -11,6 +11,7 @@
 import pytest
 
 @pytest.mark.boardspec('sandbox')
+@pytest.mark.slow
 class TestMkdir(object):
     def test_mkdir1(self, u_boot_console, fs_obj_mkdir):
         """
diff --git a/test/py/tests/test_fs/test_unlink.py b/test/py/tests/test_fs/test_unlink.py
index 69c1a6e..2b81746 100644
--- a/test/py/tests/test_fs/test_unlink.py
+++ b/test/py/tests/test_fs/test_unlink.py
@@ -12,6 +12,7 @@
 import pytest
 
 @pytest.mark.boardspec('sandbox')
+@pytest.mark.slow
 class TestUnlink(object):
     def test_unlink1(self, u_boot_console, fs_obj_unlink):
         """
diff --git a/test/py/tests/test_handoff.py b/test/py/tests/test_handoff.py
new file mode 100644
index 0000000..0ee9722
--- /dev/null
+++ b/test/py/tests/test_handoff.py
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2016 Google, Inc
+
+import pytest
+
+# Magic number to check that SPL handoff is working
+TEST_HANDOFF_MAGIC = 0x14f93c7b
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('spl')
+def test_handoff(u_boot_console):
+    """Test that of-platdata can be generated and used in sandbox"""
+    cons = u_boot_console
+    response = cons.run_command('sb handoff')
+    assert ('SPL handoff magic %x' % TEST_HANDOFF_MAGIC) in response
diff --git a/test/py/tests/test_ofplatdata.py b/test/py/tests/test_ofplatdata.py
index dd8a09f..98103ee 100644
--- a/test/py/tests/test_ofplatdata.py
+++ b/test/py/tests/test_ofplatdata.py
@@ -3,11 +3,40 @@
 
 import pytest
 
-OF_PLATDATA_OUTPUT = ''
+OF_PLATDATA_OUTPUT = '''
+of-platdata probe:
+bool 1
+byte 05
+bytearray 06 00 00
+int 1
+intarray 2 3 4 0
+longbytearray 09 0a 0b 0c 0d 0e 0f 10 11
+string message
+stringarray "multi-word" "message" ""
+of-platdata probe:
+bool 0
+byte 08
+bytearray 01 23 34
+int 3
+intarray 5 0 0 0
+longbytearray 09 00 00 00 00 00 00 00 00
+string message2
+stringarray "another" "multi-word" "message"
+of-platdata probe:
+bool 0
+byte 00
+bytearray 00 00 00
+int 0
+intarray 0 0 0 0
+longbytearray 00 00 00 00 00 00 00 00 00
+string <NULL>
+stringarray "one" "" ""
+'''
 
 @pytest.mark.buildconfigspec('spl_of_platdata')
 def test_ofplatdata(u_boot_console):
     """Test that of-platdata can be generated and used in sandbox"""
     cons = u_boot_console
+    cons.restart_uboot_with_flags(['--show_of_platdata'])
     output = cons.get_spawn_output().replace('\r', '')
     assert OF_PLATDATA_OUTPUT in output
diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
index e9cbd57..4627ceb 100644
--- a/test/py/tests/test_vboot.py
+++ b/test/py/tests/test_vboot.py
@@ -74,7 +74,7 @@
         cons.restart_uboot()
         with cons.log.section('Verified boot %s %s' % (sha_algo, test_type)):
             output = cons.run_command_list(
-                ['sb load hostfs - 100 %stest.fit' % tmpdir,
+                ['host load hostfs - 100 %stest.fit' % tmpdir,
                 'fdt addr 100',
                 'bootm 100'])
         assert(expect_string in ''.join(output))
@@ -126,7 +126,7 @@
             handle.write(struct.pack(">I", size))
         return struct.unpack(">I", total_size)[0]
 
-    def test_with_algo(sha_algo):
+    def test_with_algo(sha_algo, padding):
         """Test verified boot with the given hash algorithm.
 
         This is the main part of the test code. The same procedure is followed
@@ -144,7 +144,7 @@
 
         # Build the FIT, but don't sign anything yet
         cons.log.action('%s: Test FIT with signed images' % sha_algo)
-        make_fit('sign-images-%s.its' % sha_algo)
+        make_fit('sign-images-%s%s.its' % (sha_algo , padding))
         run_bootm(sha_algo, 'unsigned images', 'dev-', True)
 
         # Sign images with our dev keys
@@ -155,7 +155,7 @@
         dtc('sandbox-u-boot.dts')
 
         cons.log.action('%s: Test FIT with signed configuration' % sha_algo)
-        make_fit('sign-configs-%s.its' % sha_algo)
+        make_fit('sign-configs-%s%s.its' % (sha_algo , padding))
         run_bootm(sha_algo, 'unsigned config', '%s+ OK' % sha_algo, True)
 
         # Sign images with our dev keys
@@ -204,7 +204,7 @@
     fit_check_sign = cons.config.build_dir + '/tools/fit_check_sign'
     dtc_args = '-I dts -O dtb -i %s' % tmpdir
     dtb = '%ssandbox-u-boot.dtb' % tmpdir
-    sig_node = '/configurations/conf@1/signature@1'
+    sig_node = '/configurations/conf-1/signature'
 
     # Create an RSA key pair
     public_exponent = 65537
@@ -226,8 +226,10 @@
         # afterwards.
         old_dtb = cons.config.dtb
         cons.config.dtb = dtb
-        test_with_algo('sha1')
-        test_with_algo('sha256')
+        test_with_algo('sha1','')
+        test_with_algo('sha1','-pss')
+        test_with_algo('sha256','')
+        test_with_algo('sha256','-pss')
     finally:
         # Go back to the original U-Boot with the correct dtb.
         cons.config.dtb = old_dtb
diff --git a/test/py/tests/vboot/sign-configs-sha1-pss.its b/test/py/tests/vboot/sign-configs-sha1-pss.its
new file mode 100644
index 0000000..72a5637
--- /dev/null
+++ b/test/py/tests/vboot/sign-configs-sha1-pss.its
@@ -0,0 +1,46 @@
+/dts-v1/;
+
+/ {
+	description = "Chrome OS kernel image with one or more FDT blobs";
+	#address-cells = <1>;
+
+	images {
+		kernel {
+			data = /incbin/("test-kernel.bin");
+			type = "kernel_noload";
+			arch = "sandbox";
+			os = "linux";
+			compression = "none";
+			load = <0x4>;
+			entry = <0x8>;
+			kernel-version = <1>;
+			hash-1 {
+				algo = "sha1";
+			};
+		};
+		fdt-1 {
+			description = "snow";
+			data = /incbin/("sandbox-kernel.dtb");
+			type = "flat_dt";
+			arch = "sandbox";
+			compression = "none";
+			fdt-version = <1>;
+			hash-1 {
+				algo = "sha1";
+			};
+		};
+	};
+	configurations {
+		default = "conf-1";
+		conf-1 {
+			kernel = "kernel";
+			fdt = "fdt-1";
+			signature {
+				algo = "sha1,rsa2048";
+				padding = "pss";
+				key-name-hint = "dev";
+				sign-images = "fdt", "kernel";
+			};
+		};
+	};
+};
diff --git a/test/py/tests/vboot/sign-configs-sha1.its b/test/py/tests/vboot/sign-configs-sha1.its
index db2ed79..d8bc1fa 100644
--- a/test/py/tests/vboot/sign-configs-sha1.its
+++ b/test/py/tests/vboot/sign-configs-sha1.its
@@ -5,7 +5,7 @@
 	#address-cells = <1>;
 
 	images {
-		kernel@1 {
+		kernel {
 			data = /incbin/("test-kernel.bin");
 			type = "kernel_noload";
 			arch = "sandbox";
@@ -14,28 +14,28 @@
 			load = <0x4>;
 			entry = <0x8>;
 			kernel-version = <1>;
-			hash@1 {
+			hash-1 {
 				algo = "sha1";
 			};
 		};
-		fdt@1 {
+		fdt-1 {
 			description = "snow";
 			data = /incbin/("sandbox-kernel.dtb");
 			type = "flat_dt";
 			arch = "sandbox";
 			compression = "none";
 			fdt-version = <1>;
-			hash@1 {
+			hash-1 {
 				algo = "sha1";
 			};
 		};
 	};
 	configurations {
-		default = "conf@1";
-		conf@1 {
-			kernel = "kernel@1";
-			fdt = "fdt@1";
-			signature@1 {
+		default = "conf-1";
+		conf-1 {
+			kernel = "kernel";
+			fdt = "fdt-1";
+			signature {
 				algo = "sha1,rsa2048";
 				key-name-hint = "dev";
 				sign-images = "fdt", "kernel";
diff --git a/test/py/tests/vboot/sign-configs-sha256-pss.its b/test/py/tests/vboot/sign-configs-sha256-pss.its
new file mode 100644
index 0000000..7bdcc7e
--- /dev/null
+++ b/test/py/tests/vboot/sign-configs-sha256-pss.its
@@ -0,0 +1,46 @@
+/dts-v1/;
+
+/ {
+	description = "Chrome OS kernel image with one or more FDT blobs";
+	#address-cells = <1>;
+
+	images {
+		kernel {
+			data = /incbin/("test-kernel.bin");
+			type = "kernel_noload";
+			arch = "sandbox";
+			os = "linux";
+			compression = "none";
+			load = <0x4>;
+			entry = <0x8>;
+			kernel-version = <1>;
+			hash-1 {
+				algo = "sha256";
+			};
+		};
+		fdt-1 {
+			description = "snow";
+			data = /incbin/("sandbox-kernel.dtb");
+			type = "flat_dt";
+			arch = "sandbox";
+			compression = "none";
+			fdt-version = <1>;
+			hash-1 {
+				algo = "sha256";
+			};
+		};
+	};
+	configurations {
+		default = "conf-1";
+		conf-1 {
+			kernel = "kernel";
+			fdt = "fdt-1";
+			signature {
+				algo = "sha256,rsa2048";
+				padding = "pss";
+				key-name-hint = "dev";
+				sign-images = "fdt", "kernel";
+			};
+		};
+	};
+};
diff --git a/test/py/tests/vboot/sign-configs-sha256.its b/test/py/tests/vboot/sign-configs-sha256.its
index 1b3432e..f5591aa 100644
--- a/test/py/tests/vboot/sign-configs-sha256.its
+++ b/test/py/tests/vboot/sign-configs-sha256.its
@@ -5,7 +5,7 @@
 	#address-cells = <1>;
 
 	images {
-		kernel@1 {
+		kernel {
 			data = /incbin/("test-kernel.bin");
 			type = "kernel_noload";
 			arch = "sandbox";
@@ -14,28 +14,28 @@
 			load = <0x4>;
 			entry = <0x8>;
 			kernel-version = <1>;
-			hash@1 {
+			hash-1 {
 				algo = "sha256";
 			};
 		};
-		fdt@1 {
+		fdt-1 {
 			description = "snow";
 			data = /incbin/("sandbox-kernel.dtb");
 			type = "flat_dt";
 			arch = "sandbox";
 			compression = "none";
 			fdt-version = <1>;
-			hash@1 {
+			hash-1 {
 				algo = "sha256";
 			};
 		};
 	};
 	configurations {
-		default = "conf@1";
-		conf@1 {
-			kernel = "kernel@1";
-			fdt = "fdt@1";
-			signature@1 {
+		default = "conf-1";
+		conf-1 {
+			kernel = "kernel";
+			fdt = "fdt-1";
+			signature {
 				algo = "sha256,rsa2048";
 				key-name-hint = "dev";
 				sign-images = "fdt", "kernel";
diff --git a/test/py/tests/vboot/sign-images-sha1-pss.its b/test/py/tests/vboot/sign-images-sha1-pss.its
new file mode 100644
index 0000000..ded7ae4
--- /dev/null
+++ b/test/py/tests/vboot/sign-images-sha1-pss.its
@@ -0,0 +1,44 @@
+/dts-v1/;
+
+/ {
+	description = "Chrome OS kernel image with one or more FDT blobs";
+	#address-cells = <1>;
+
+	images {
+		kernel {
+			data = /incbin/("test-kernel.bin");
+			type = "kernel_noload";
+			arch = "sandbox";
+			os = "linux";
+			compression = "none";
+			load = <0x4>;
+			entry = <0x8>;
+			kernel-version = <1>;
+			signature {
+				algo = "sha1,rsa2048";
+				padding = "pss";
+				key-name-hint = "dev";
+			};
+		};
+		fdt-1 {
+			description = "snow";
+			data = /incbin/("sandbox-kernel.dtb");
+			type = "flat_dt";
+			arch = "sandbox";
+			compression = "none";
+			fdt-version = <1>;
+			signature {
+				algo = "sha1,rsa2048";
+				padding = "pss";
+				key-name-hint = "dev";
+			};
+		};
+	};
+	configurations {
+		default = "conf-1";
+		conf-1 {
+			kernel = "kernel";
+			fdt = "fdt-1";
+		};
+	};
+};
diff --git a/test/py/tests/vboot/sign-images-sha1.its b/test/py/tests/vboot/sign-images-sha1.its
index f69326a..18c759e 100644
--- a/test/py/tests/vboot/sign-images-sha1.its
+++ b/test/py/tests/vboot/sign-images-sha1.its
@@ -5,7 +5,7 @@
 	#address-cells = <1>;
 
 	images {
-		kernel@1 {
+		kernel {
 			data = /incbin/("test-kernel.bin");
 			type = "kernel_noload";
 			arch = "sandbox";
@@ -14,29 +14,29 @@
 			load = <0x4>;
 			entry = <0x8>;
 			kernel-version = <1>;
-			signature@1 {
+			signature {
 				algo = "sha1,rsa2048";
 				key-name-hint = "dev";
 			};
 		};
-		fdt@1 {
+		fdt-1 {
 			description = "snow";
 			data = /incbin/("sandbox-kernel.dtb");
 			type = "flat_dt";
 			arch = "sandbox";
 			compression = "none";
 			fdt-version = <1>;
-			signature@1 {
+			signature {
 				algo = "sha1,rsa2048";
 				key-name-hint = "dev";
 			};
 		};
 	};
 	configurations {
-		default = "conf@1";
-		conf@1 {
-			kernel = "kernel@1";
-			fdt = "fdt@1";
+		default = "conf-1";
+		conf-1 {
+			kernel = "kernel";
+			fdt = "fdt-1";
 		};
 	};
 };
diff --git a/test/py/tests/vboot/sign-images-sha256-pss.its b/test/py/tests/vboot/sign-images-sha256-pss.its
new file mode 100644
index 0000000..34850cc
--- /dev/null
+++ b/test/py/tests/vboot/sign-images-sha256-pss.its
@@ -0,0 +1,44 @@
+/dts-v1/;
+
+/ {
+	description = "Chrome OS kernel image with one or more FDT blobs";
+	#address-cells = <1>;
+
+	images {
+		kernel {
+			data = /incbin/("test-kernel.bin");
+			type = "kernel_noload";
+			arch = "sandbox";
+			os = "linux";
+			compression = "none";
+			load = <0x4>;
+			entry = <0x8>;
+			kernel-version = <1>;
+			signature {
+				algo = "sha256,rsa2048";
+				padding = "pss";
+				key-name-hint = "dev";
+			};
+		};
+		fdt-1 {
+			description = "snow";
+			data = /incbin/("sandbox-kernel.dtb");
+			type = "flat_dt";
+			arch = "sandbox";
+			compression = "none";
+			fdt-version = <1>;
+			signature {
+				algo = "sha256,rsa2048";
+				padding = "pss";
+				key-name-hint = "dev";
+			};
+		};
+	};
+	configurations {
+		default = "conf-1";
+		conf-1 {
+			kernel = "kernel";
+			fdt = "fdt-1";
+		};
+	};
+};
diff --git a/test/py/tests/vboot/sign-images-sha256.its b/test/py/tests/vboot/sign-images-sha256.its
index e6aa9fc..bb0f8ee 100644
--- a/test/py/tests/vboot/sign-images-sha256.its
+++ b/test/py/tests/vboot/sign-images-sha256.its
@@ -5,7 +5,7 @@
 	#address-cells = <1>;
 
 	images {
-		kernel@1 {
+		kernel {
 			data = /incbin/("test-kernel.bin");
 			type = "kernel_noload";
 			arch = "sandbox";
@@ -14,29 +14,29 @@
 			load = <0x4>;
 			entry = <0x8>;
 			kernel-version = <1>;
-			signature@1 {
+			signature {
 				algo = "sha256,rsa2048";
 				key-name-hint = "dev";
 			};
 		};
-		fdt@1 {
+		fdt-1 {
 			description = "snow";
 			data = /incbin/("sandbox-kernel.dtb");
 			type = "flat_dt";
 			arch = "sandbox";
 			compression = "none";
 			fdt-version = <1>;
-			signature@1 {
+			signature {
 				algo = "sha256,rsa2048";
 				key-name-hint = "dev";
 			};
 		};
 	};
 	configurations {
-		default = "conf@1";
-		conf@1 {
-			kernel = "kernel@1";
-			fdt = "fdt@1";
+		default = "conf-1";
+		conf-1 {
+			kernel = "kernel";
+			fdt = "fdt-1";
 		};
 	};
 };
diff --git a/test/py/u_boot_console_base.py b/test/py/u_boot_console_base.py
index 326b2ac..e044eb3 100644
--- a/test/py/u_boot_console_base.py
+++ b/test/py/u_boot_console_base.py
@@ -16,7 +16,7 @@
 import u_boot_spawn
 
 # Regexes for text we expect U-Boot to send to the console.
-pattern_u_boot_spl_signon = re.compile('(U-Boot SPL \\d{4}\\.\\d{2}[^\r\n]*\\))')
+pattern_u_boot_spl_signon = re.compile('(U-Boot spl \\d{4}\\.\\d{2}[^\r\n]*\\))')
 pattern_u_boot_main_signon = re.compile('(U-Boot \\d{4}\\.\\d{2}[^\r\n]*\\))')
 pattern_stop_autoboot_prompt = re.compile('Hit any key to stop autoboot: ')
 pattern_unknown_command = re.compile('Unknown command \'.*\' - try \'help\'')
diff --git a/test/py/u_boot_console_sandbox.py b/test/py/u_boot_console_sandbox.py
index 778f6d0..836f5a9 100644
--- a/test/py/u_boot_console_sandbox.py
+++ b/test/py/u_boot_console_sandbox.py
@@ -24,6 +24,7 @@
         """
 
         super(ConsoleSandbox, self).__init__(log, config, max_fifo_fill=1024)
+        self.sandbox_flags = []
 
     def get_spawn(self):
         """Connect to a fresh U-Boot instance.
@@ -51,8 +52,25 @@
             '-d',
             self.config.dtb
         ]
+        cmd += self.sandbox_flags
         return Spawn(cmd, cwd=self.config.source_dir)
 
+    def restart_uboot_with_flags(self, flags):
+        """Run U-Boot with the given command-line flags
+
+        Args:
+            flags: List of flags to pass, each a string
+
+        Returns:
+            A u_boot_spawn.Spawn object that is attached to U-Boot.
+        """
+
+        try:
+            self.sandbox_flags = flags
+            return self.restart_uboot()
+        finally:
+            self.sandbox_flags = []
+
     def kill(self, sig):
         """Send a specific Unix signal to the sandbox process.
 
diff --git a/test/run b/test/run
index fb8ff5d..55a6649 100755
--- a/test/run
+++ b/test/run
@@ -1,6 +1,7 @@
 #!/bin/bash
 
 # Script to run all U-Boot tests that use sandbox.
+#  $1: tests to run (empty for all, 'quick' for quick ones only)
 
 # Runs a test and checks the exit code to decide if it passed
 #  $1:         Test name
@@ -12,14 +13,17 @@
 	[ $? -ne 0 ] && failures=$((failures+1))
 }
 
+# SKip slow tests if requested
+[ "$1" == "quick" ] && mark_expr="not slow"
+
 failures=0
 
 # Run all tests that the standard sandbox build can support
-run_test "sandbox" ./test/py/test.py --bd sandbox --build
+run_test "sandbox" ./test/py/test.py --bd sandbox --build -m "${mark_expr}"
 
 # Run tests which require sandbox_spl
 run_test "sandbox_spl" ./test/py/test.py --bd sandbox_spl --build \
-	-k test_ofplatdata.py
+	-k 'test_ofplatdata or test_handoff'
 
 # Run tests for the flat-device-tree version of sandbox. This is a special
 # build which does not enable CONFIG_OF_LIVE for the live device tree, so we can
@@ -36,7 +40,9 @@
 
 run_test "binman" ./tools/binman/binman -t
 run_test "patman" ./tools/patman/patman --test
-run_test "buildman" ./tools/buildman/buildman -t
+
+[ "$1" == "quick" ] && skip=--skip-net-tests
+run_test "buildman" ./tools/buildman/buildman -t ${skip}
 run_test "fdt" ./tools/dtoc/test_fdt -t
 run_test "dtoc" ./tools/dtoc/dtoc -t
 
diff --git a/tools/.gitignore b/tools/.gitignore
index c8cdaef..e5ede22 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -24,6 +24,7 @@
 /mksunxiboot
 /mxsboot
 /ncb
+/prelink-riscv
 /proftool
 /relocate-rela
 /sunxi-spl-image-builder
diff --git a/tools/Makefile b/tools/Makefile
index 3c0521f..c93d17a 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -116,6 +116,7 @@
 			$(LIBFDT_OBJS) \
 			gpimage.o \
 			gpimage-common.o \
+			mtk_image.o \
 			$(RSA_OBJS-y)
 
 dumpimage-objs := $(dumpimage-mkimage-objs) dumpimage.o
diff --git a/tools/binman/README b/tools/binman/README
index b64dedf..04ed2b79 100644
--- a/tools/binman/README
+++ b/tools/binman/README
@@ -723,6 +723,12 @@
 the DTC environment variable. This can be useful when the system dtc is too
 old.
 
+To enable a full backtrace and other debugging features in binman, pass
+BINMAN_DEBUG=1 to your build:
+
+   make sandbox_defconfig
+   make BINMAN_DEBUG=1
+
 
 History / Credits
 -----------------
diff --git a/tools/binman/etype/blob.py b/tools/binman/etype/blob.py
index 642a0e4..ae80bbe 100644
--- a/tools/binman/etype/blob.py
+++ b/tools/binman/etype/blob.py
@@ -60,7 +60,7 @@
             except AttributeError:
                 data = lz4.compress(data)
             '''
-            data = tools.Run('lz4', '-c', self._pathname, )
+            data = tools.Run('lz4', '-c', self._pathname)
         self.SetContents(data)
         return True
 
diff --git a/tools/binman/etype/u_boot_elf.py b/tools/binman/etype/u_boot_elf.py
index 134b6cc..f83860d 100644
--- a/tools/binman/etype/u_boot_elf.py
+++ b/tools/binman/etype/u_boot_elf.py
@@ -30,9 +30,8 @@
             out_fname = tools.GetOutputFilename('%s.stripped' % uniq)
             tools.WriteFile(out_fname, tools.ReadFile(self._pathname))
             tools.Run('strip', out_fname)
-            self.SetContents(tools.ReadFile(out_fname))
-        else:
-            self.SetContents(tools.ReadFile(self._pathname))
+            self._pathname = out_fname
+        Entry_blob.ReadBlobContents(self)
         return True
 
     def GetDefaultFilename(self):
diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py
index 05f8299..6a6c83b 100644
--- a/tools/buildman/builder.py
+++ b/tools/buildman/builder.py
@@ -290,6 +290,7 @@
         self._re_function = re.compile('(.*): In function.*')
         self._re_files = re.compile('In file included from.*')
         self._re_warning = re.compile('(.*):(\d*):(\d*): warning: .*')
+        self._re_dtb_warning = re.compile('(.*): Warning .*')
         self._re_note = re.compile('(.*):(\d*):(\d*): note: this is the location of the previous.*')
 
         self.queue = Queue.Queue()
@@ -788,7 +789,8 @@
                             self._re_files.match(line)):
                         last_func = line
                     else:
-                        is_warning = self._re_warning.match(line)
+                        is_warning = (self._re_warning.match(line) or
+                                      self._re_dtb_warning.match(line))
                         is_note = self._re_note.match(line)
                         if is_warning or (last_was_warning and is_note):
                             if last_func:
@@ -1194,10 +1196,11 @@
                 Print('   ' + line, newline=True, colour=col)
 
 
-        better = []     # List of boards fixed since last commit
-        worse = []      # List of new broken boards since last commit
-        new = []        # List of boards that didn't exist last time
-        unknown = []    # List of boards that were not built
+        ok_boards = []      # List of boards fixed since last commit
+        warn_boards = []    # List of boards with warnings since last commit
+        err_boards = []     # List of new broken boards since last commit
+        new_boards = []     # List of boards that didn't exist last time
+        unknown_boards = [] # List of boards that were not built
 
         for target in board_dict:
             if target not in board_selected:
@@ -1208,13 +1211,19 @@
                 base_outcome = self._base_board_dict[target].rc
                 outcome = board_dict[target]
                 if outcome.rc == OUTCOME_UNKNOWN:
-                    unknown.append(target)
+                    unknown_boards.append(target)
                 elif outcome.rc < base_outcome:
-                    better.append(target)
+                    if outcome.rc == OUTCOME_WARNING:
+                        warn_boards.append(target)
+                    else:
+                        ok_boards.append(target)
                 elif outcome.rc > base_outcome:
-                    worse.append(target)
+                    if outcome.rc == OUTCOME_WARNING:
+                        warn_boards.append(target)
+                    else:
+                        err_boards.append(target)
             else:
-                new.append(target)
+                new_boards.append(target)
 
         # Get a list of errors that have appeared, and disappeared
         better_err, worse_err = _CalcErrorDelta(self._base_err_lines,
@@ -1223,16 +1232,18 @@
                 self._base_warn_line_boards, warn_lines, warn_line_boards, 'w')
 
         # Display results by arch
-        if (better or worse or unknown or new or worse_err or better_err
-                or worse_warn or better_warn):
+        if any((ok_boards, warn_boards, err_boards, unknown_boards, new_boards,
+                worse_err, better_err, worse_warn, better_warn)):
             arch_list = {}
-            self.AddOutcome(board_selected, arch_list, better, '',
+            self.AddOutcome(board_selected, arch_list, ok_boards, '',
                     self.col.GREEN)
-            self.AddOutcome(board_selected, arch_list, worse, '+',
+            self.AddOutcome(board_selected, arch_list, warn_boards, 'w+',
+                    self.col.YELLOW)
+            self.AddOutcome(board_selected, arch_list, err_boards, '+',
                     self.col.RED)
-            self.AddOutcome(board_selected, arch_list, new, '*', self.col.BLUE)
+            self.AddOutcome(board_selected, arch_list, new_boards, '*', self.col.BLUE)
             if self._show_unknown:
-                self.AddOutcome(board_selected, arch_list, unknown, '?',
+                self.AddOutcome(board_selected, arch_list, unknown_boards, '?',
                         self.col.MAGENTA)
             for arch, target_list in arch_list.iteritems():
                 Print('%10s: %s' % (arch, target_list))
diff --git a/tools/buildman/cmdline.py b/tools/buildman/cmdline.py
index 49a8a13..93d09ca 100644
--- a/tools/buildman/cmdline.py
+++ b/tools/buildman/cmdline.py
@@ -66,7 +66,7 @@
     parser.add_option('-l', '--list-error-boards', action='store_true',
           default=False, help='Show a list of boards next to each error/warning')
     parser.add_option('--list-tool-chains', action='store_true', default=False,
-          help='List available tool chains')
+          help='List available tool chains (use -v to see probing detail)')
     parser.add_option('-n', '--dry-run', action='store_true', dest='dry_run',
           default=False, help="Do a dry run (describe actions, but do nothing)")
     parser.add_option('-N', '--no-subdirs', action='store_true', dest='no_subdirs',
diff --git a/tools/buildman/control.py b/tools/buildman/control.py
index 96f8ccf..c900211 100644
--- a/tools/buildman/control.py
+++ b/tools/buildman/control.py
@@ -164,7 +164,7 @@
 
     if no_toolchains:
         toolchains.GetSettings()
-        toolchains.Scan(options.list_tool_chains)
+        toolchains.Scan(options.list_tool_chains and options.verbose)
     if options.list_tool_chains:
         toolchains.List()
         print
diff --git a/tools/buildman/test.py b/tools/buildman/test.py
index 61a4626..de02f61 100644
--- a/tools/buildman/test.py
+++ b/tools/buildman/test.py
@@ -46,8 +46,9 @@
 make: *** [common/libcommon.o] Error 2
 Make failed
 ''',
-    '''main.c: In function 'main_loop3':
-main.c:280:6: warning: unused variable 'mary' [-Wunused-variable]
+    '''arch/arm/dts/socfpga_arria10_socdk_sdmmc.dtb: Warning \
+(avoid_unnecessary_addr_size): /clocks: unnecessary #address-cells/#size-cells \
+without "ranges" or child "reg" property
 ''',
     '''powerpc-linux-ld: warning: dot moved backwards before `.bss'
 powerpc-linux-ld: warning: dot moved backwards before `.bss'
@@ -96,6 +97,8 @@
 
 BASE_DIR = 'base'
 
+OUTCOME_OK, OUTCOME_WARN, OUTCOME_ERR = range(3)
+
 class Options:
     """Class that holds build options"""
     pass
@@ -165,9 +168,10 @@
         result.combined = result.stdout + result.stderr
         return result
 
-    def assertSummary(self, text, arch, plus, boards, ok=False):
+    def assertSummary(self, text, arch, plus, boards, outcome=OUTCOME_ERR):
         col = self._col
-        expected_colour = col.GREEN if ok else col.RED
+        expected_colour = (col.GREEN if outcome == OUTCOME_OK else
+                           col.YELLOW if outcome == OUTCOME_WARN else col.RED)
         expect = '%10s: ' % arch
         # TODO(sjg@chromium.org): If plus is '', we shouldn't need this
         expect += ' ' + col.Color(expected_colour, plus)
@@ -191,6 +195,8 @@
         build.do_make = self.Make
         board_selected = self.boards.GetSelectedDict()
 
+        # Build the boards for the pre-defined commits and warnings/errors
+        # associated with each. This calls our Make() to inject the fake output.
         build.BuildBoards(self.commits, board_selected, keep_outputs=False,
                           verbose=False)
         lines = terminal.GetPrintTestLines()
@@ -206,33 +212,49 @@
         build.ShowSummary(self.commits, board_selected)
         #terminal.EchoPrintTestLines()
         lines = terminal.GetPrintTestLines()
+
+        # Upstream commit: no errors
         self.assertEqual(lines[0].text, '01: %s' % commits[0][1])
+
+        # Second commit: all archs should fail with warnings
         self.assertEqual(lines[1].text, '02: %s' % commits[1][1])
 
-        # We expect all archs to fail
         col = terminal.Color()
-        self.assertSummary(lines[2].text, 'sandbox', '+', ['board4'])
-        self.assertSummary(lines[3].text, 'arm', '+', ['board1'])
-        self.assertSummary(lines[4].text, 'powerpc', '+', ['board2', 'board3'])
+        self.assertSummary(lines[2].text, 'sandbox', 'w+', ['board4'],
+                           outcome=OUTCOME_WARN)
+        self.assertSummary(lines[3].text, 'arm', 'w+', ['board1'],
+                           outcome=OUTCOME_WARN)
+        self.assertSummary(lines[4].text, 'powerpc', 'w+', ['board2', 'board3'],
+                           outcome=OUTCOME_WARN)
 
-        # Now we should have the compiler warning
+        # Second commit: The warnings should be listed
         self.assertEqual(lines[5].text, 'w+%s' %
                 errors[0].rstrip().replace('\n', '\nw+'))
         self.assertEqual(lines[5].colour, col.MAGENTA)
 
+        # Third commit: Still fails
         self.assertEqual(lines[6].text, '03: %s' % commits[2][1])
         self.assertSummary(lines[7].text, 'sandbox', '+', ['board4'])
-        self.assertSummary(lines[8].text, 'arm', '', ['board1'], ok=True)
+        self.assertSummary(lines[8].text, 'arm', '', ['board1'],
+                           outcome=OUTCOME_OK)
         self.assertSummary(lines[9].text, 'powerpc', '+', ['board2', 'board3'])
 
-        # Compiler error
+        # Expect a compiler error
         self.assertEqual(lines[10].text, '+%s' %
                 errors[1].rstrip().replace('\n', '\n+'))
 
+        # Fourth commit: Compile errors are fixed, just have warning for board3
         self.assertEqual(lines[11].text, '04: %s' % commits[3][1])
-        self.assertSummary(lines[12].text, 'sandbox', '', ['board4'], ok=True)
-        self.assertSummary(lines[13].text, 'powerpc', '', ['board2', 'board3'],
-                ok=True)
+        self.assertSummary(lines[12].text, 'sandbox', 'w+', ['board4'],
+                           outcome=OUTCOME_WARN)
+        expect = '%10s: ' % 'powerpc'
+        expect += ' ' + col.Color(col.GREEN, '')
+        expect += '  '
+        expect += col.Color(col.GREEN, ' %s' % 'board2')
+        expect += ' ' + col.Color(col.YELLOW, 'w+')
+        expect += '  '
+        expect += col.Color(col.YELLOW, ' %s' % 'board3')
+        self.assertEqual(lines[13].text, expect)
 
         # Compile error fixed
         self.assertEqual(lines[14].text, '-%s' %
@@ -243,9 +265,11 @@
                 errors[2].rstrip().replace('\n', '\nw+'))
         self.assertEqual(lines[15].colour, col.MAGENTA)
 
+        # Fifth commit
         self.assertEqual(lines[16].text, '05: %s' % commits[4][1])
         self.assertSummary(lines[17].text, 'sandbox', '+', ['board4'])
-        self.assertSummary(lines[18].text, 'powerpc', '', ['board3'], ok=True)
+        self.assertSummary(lines[18].text, 'powerpc', '', ['board3'],
+                           outcome=OUTCOME_OK)
 
         # The second line of errors[3] is a duplicate, so buildman will drop it
         expect = errors[3].rstrip().split('\n')
@@ -256,8 +280,10 @@
         self.assertEqual(lines[20].text, 'w-%s' %
                 errors[2].rstrip().replace('\n', '\nw-'))
 
+        # Sixth commit
         self.assertEqual(lines[21].text, '06: %s' % commits[5][1])
-        self.assertSummary(lines[22].text, 'sandbox', '', ['board4'], ok=True)
+        self.assertSummary(lines[22].text, 'sandbox', '', ['board4'],
+                           outcome=OUTCOME_OK)
 
         # The second line of errors[3] is a duplicate, so buildman will drop it
         expect = errors[3].rstrip().split('\n')
@@ -268,6 +294,7 @@
         self.assertEqual(lines[24].text, 'w-%s' %
                 errors[0].rstrip().replace('\n', '\nw-'))
 
+        # Seventh commit
         self.assertEqual(lines[25].text, '07: %s' % commits[6][1])
         self.assertSummary(lines[26].text, 'sandbox', '+', ['board4'])
 
diff --git a/tools/file2include.c b/tools/file2include.c
index b98af30..775440c 100644
--- a/tools/file2include.c
+++ b/tools/file2include.c
@@ -18,7 +18,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
-#include <malloc.h>
 
 /* Size of the blocks written to the compressed file */
 #define BLOCK_SIZE 8
diff --git a/tools/image-host.c b/tools/image-host.c
index 09e4f47..88b3295 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -157,6 +157,7 @@
 {
 	const char *node_name;
 	char *algo_name;
+	const char *padding_name;
 
 	node_name = fit_get_name(fit, noffset, NULL);
 	if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
@@ -165,6 +166,8 @@
 		return -1;
 	}
 
+	padding_name = fdt_getprop(fit, noffset, "padding", NULL);
+
 	memset(info, '\0', sizeof(*info));
 	info->keydir = keydir;
 	info->keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
@@ -173,6 +176,7 @@
 	info->name = strdup(algo_name);
 	info->checksum = image_get_checksum_algo(algo_name);
 	info->crypto = image_get_crypto_algo(algo_name);
+	info->padding = image_get_padding_algo(padding_name);
 	info->require_keys = require_keys;
 	info->engine_id = engine_id;
 	if (!info->checksum || !info->crypto) {
diff --git a/tools/mtk_image.c b/tools/mtk_image.c
new file mode 100644
index 0000000..2706d2d
--- /dev/null
+++ b/tools/mtk_image.c
@@ -0,0 +1,749 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Generate MediaTek BootROM header for SPL/U-Boot images
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <image.h>
+#include <u-boot/sha256.h>
+#include "imagetool.h"
+#include "mtk_image.h"
+
+/* NAND header for SPI-NAND with 2KB page + 64B spare */
+static const union nand_boot_header snand_hdr_2k_64_data = {
+	.data = {
+		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+		0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00,
+		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D,
+		0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7,
+		0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8,
+		0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00
+	}
+};
+
+/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
+static const union nand_boot_header snand_hdr_2k_128_data = {
+	.data = {
+		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
+		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13,
+		0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3,
+		0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7,
+		0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00
+	}
+};
+
+/* NAND header for SPI-NAND with 4KB page + 256B spare */
+static const union nand_boot_header snand_hdr_4k_256_data = {
+	.data = {
+		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+		0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00,
+		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3,
+		0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57,
+		0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F,
+		0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00
+	}
+};
+
+/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */
+static const union nand_boot_header nand_hdr_1gb_2k_64_data = {
+	.data = {
+		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
+		0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12,
+		0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C,
+		0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82,
+		0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00
+	}
+};
+
+/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */
+static const union nand_boot_header nand_hdr_2gb_2k_64_data = {
+	.data = {
+		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
+		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D,
+		0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1,
+		0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95,
+		0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00
+	}
+};
+
+/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */
+static const union nand_boot_header nand_hdr_4gb_2k_64_data = {
+	.data = {
+		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
+		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32,
+		0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B,
+		0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87,
+		0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00
+	}
+};
+
+/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */
+static const union nand_boot_header nand_hdr_2gb_2k_128_data = {
+	.data = {
+		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
+		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A,
+		0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC,
+		0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0,
+		0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00
+	}
+};
+
+/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */
+static const union nand_boot_header nand_hdr_4gb_2k_128_data = {
+	.data = {
+		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
+		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45,
+		0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46,
+		0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2,
+		0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00
+	}
+};
+
+static const struct nand_header_type {
+	const char *name;
+	const union nand_boot_header *data;
+} nand_headers[] = {
+	{
+		.name = "2k+64",
+		.data = &snand_hdr_2k_64_data
+	}, {
+		.name = "2k+120",
+		.data = &snand_hdr_2k_128_data
+	}, {
+		.name = "2k+128",
+		.data = &snand_hdr_2k_128_data
+	}, {
+		.name = "4k+256",
+		.data = &snand_hdr_4k_256_data
+	}, {
+		.name = "1g:2k+64",
+		.data = &nand_hdr_1gb_2k_64_data
+	}, {
+		.name = "2g:2k+64",
+		.data = &nand_hdr_2gb_2k_64_data
+	}, {
+		.name = "4g:2k+64",
+		.data = &nand_hdr_4gb_2k_64_data
+	}, {
+		.name = "2g:2k+128",
+		.data = &nand_hdr_2gb_2k_128_data
+	}, {
+		.name = "4g:2k+128",
+		.data = &nand_hdr_4gb_2k_128_data
+	}
+};
+
+static const struct brom_img_type {
+	const char *name;
+	enum brlyt_img_type type;
+} brom_images[] = {
+	{
+		.name = "nand",
+		.type = BRLYT_TYPE_NAND
+	}, {
+		.name = "emmc",
+		.type = BRLYT_TYPE_EMMC
+	}, {
+		.name = "nor",
+		.type = BRLYT_TYPE_NOR
+	}, {
+		.name = "sdmmc",
+		.type = BRLYT_TYPE_SDMMC
+	}, {
+		.name = "snand",
+		.type = BRLYT_TYPE_SNAND
+	}
+};
+
+/* Image type selected by user */
+static enum brlyt_img_type hdr_media;
+static int use_lk_hdr;
+
+/* LK image name */
+static char lk_name[32] = "U-Boot";
+
+/* NAND header selected by user */
+static const union nand_boot_header *hdr_nand;
+
+/* GFH header + 2 * 4KB pages of NAND */
+static char hdr_tmp[sizeof(struct gfh_header) + 0x2000];
+
+static int mtk_image_check_image_types(uint8_t type)
+{
+	if (type == IH_TYPE_MTKIMAGE)
+		return EXIT_SUCCESS;
+	else
+		return EXIT_FAILURE;
+}
+
+static int mtk_brom_parse_imagename(const char *imagename)
+{
+#define is_blank_char(c) \
+	((c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == ' ')
+
+	char *buf = strdup(imagename), *key, *val, *end, *next;
+	int i;
+
+	/* User passed arguments from image name */
+	static const char *media = "";
+	static const char *nandinfo = "";
+	static const char *lk = "";
+
+	key = buf;
+	while (key) {
+		next = strchr(key, ';');
+		if (next)
+			*next = 0;
+
+		val = strchr(key, '=');
+		if (val) {
+			*val++ = 0;
+
+			/* Trim key */
+			while (is_blank_char(*key))
+				key++;
+
+			end = key + strlen(key) - 1;
+			while ((end >= key) && is_blank_char(*end))
+				end--;
+			end++;
+
+			if (is_blank_char(*end))
+				*end = 0;
+
+			/* Trim value */
+			while (is_blank_char(*val))
+				val++;
+
+			end = val + strlen(val) - 1;
+			while ((end >= val) && is_blank_char(*end))
+				end--;
+			end++;
+
+			if (is_blank_char(*end))
+				*end = 0;
+
+			/* record user passed arguments */
+			if (!strcmp(key, "media"))
+				media = val;
+
+			if (!strcmp(key, "nandinfo"))
+				nandinfo = val;
+
+			if (!strcmp(key, "lk"))
+				lk = val;
+
+			if (!strcmp(key, "lkname"))
+				strncpy(lk_name, val, sizeof(lk_name));
+		}
+
+		if (next)
+			key = next + 1;
+		else
+			break;
+	}
+
+	/* if user specified LK image header, skip following checks */
+	if (lk && lk[0] == '1') {
+		use_lk_hdr = 1;
+		free(buf);
+		return 0;
+	}
+
+	/* parse media type */
+	for (i = 0; i < ARRAY_SIZE(brom_images); i++) {
+		if (!strcmp(brom_images[i].name, media)) {
+			hdr_media = brom_images[i].type;
+			break;
+		}
+	}
+
+	/* parse nand header type */
+	for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
+		if (!strcmp(nand_headers[i].name, nandinfo)) {
+			hdr_nand = nand_headers[i].data;
+			break;
+		}
+	}
+
+	free(buf);
+
+	if (hdr_media == BRLYT_TYPE_INVALID) {
+		fprintf(stderr, "Error: media type is invalid or missing.\n");
+		fprintf(stderr, "       Please specify -n \"media=<type>\"\n");
+		return -EINVAL;
+	}
+
+	if ((hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) &&
+	    !hdr_nand) {
+		fprintf(stderr, "Error: nand info is invalid or missing.\n");
+		fprintf(stderr, "       Please specify -n \"media=%s;"
+				"nandinfo=<info>\"\n", media);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mtk_image_check_params(struct image_tool_params *params)
+{
+	if (!params->addr) {
+		fprintf(stderr, "Error: Load Address must be set.\n");
+		return -EINVAL;
+	}
+
+	if (!params->imagename) {
+		fprintf(stderr, "Error: Image Name must be set.\n");
+		return -EINVAL;
+	}
+
+	return mtk_brom_parse_imagename(params->imagename);
+}
+
+static int mtk_image_vrec_header(struct image_tool_params *params,
+				 struct image_type_params *tparams)
+{
+	if (use_lk_hdr) {
+		tparams->header_size = sizeof(union lk_hdr);
+		tparams->hdr = &hdr_tmp;
+		memset(&hdr_tmp, 0xff, tparams->header_size);
+		return 0;
+	}
+
+	if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
+		tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize);
+	else
+		tparams->header_size = sizeof(struct gen_device_header);
+
+	tparams->header_size += sizeof(struct gfh_header);
+	tparams->hdr = &hdr_tmp;
+
+	memset(&hdr_tmp, 0xff, tparams->header_size);
+
+	return SHA256_SUM_LEN;
+}
+
+static int mtk_image_verify_gen_header(const uint8_t *ptr, int print)
+{
+	union gen_boot_header *gbh = (union gen_boot_header *)ptr;
+	struct brom_layout_header *bh;
+	struct gfh_header *gfh;
+	const char *bootmedia;
+
+	if (!strcmp(gbh->name, SF_BOOT_NAME))
+		bootmedia = "Serial NOR";
+	else if (!strcmp(gbh->name, EMMC_BOOT_NAME))
+		bootmedia = "eMMC";
+	else if (!strcmp(gbh->name, SDMMC_BOOT_NAME))
+		bootmedia = "SD/MMC";
+	else
+		return -1;
+
+	if (print)
+		printf("Boot Media:   %s\n", bootmedia);
+
+	if (le32_to_cpu(gbh->version) != 1 ||
+	    le32_to_cpu(gbh->size) != sizeof(union gen_boot_header))
+		return -1;
+
+	bh = (struct brom_layout_header *)(ptr + le32_to_cpu(gbh->size));
+
+	if (strcmp(bh->name, BRLYT_NAME))
+		return -1;
+
+	if (le32_to_cpu(bh->magic) != BRLYT_MAGIC ||
+	    (le32_to_cpu(bh->type) != BRLYT_TYPE_NOR &&
+	    le32_to_cpu(bh->type) != BRLYT_TYPE_EMMC &&
+	    le32_to_cpu(bh->type) != BRLYT_TYPE_SDMMC))
+		return -1;
+
+	gfh = (struct gfh_header *)(ptr + le32_to_cpu(bh->header_size));
+
+	if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
+		return -1;
+
+	if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_GEN)
+		return -1;
+
+	if (print)
+		printf("Load Address: %08x\n",
+		       le32_to_cpu(gfh->file_info.load_addr) +
+		       le32_to_cpu(gfh->file_info.jump_offset));
+
+	return 0;
+}
+
+static int mtk_image_verify_nand_header(const uint8_t *ptr, int print)
+{
+	union nand_boot_header *nh = (union nand_boot_header *)ptr;
+	struct brom_layout_header *bh;
+	struct gfh_header *gfh;
+	const char *bootmedia;
+
+	if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
+	    strcmp(nh->id, NAND_BOOT_ID))
+		return -1;
+
+	bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh->pagesize));
+
+	if (strcmp(bh->name, BRLYT_NAME))
+		return -1;
+
+	if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) {
+		return -1;
+	} else {
+		if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND)
+			bootmedia = "Parallel NAND";
+		else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND)
+			bootmedia = "Serial NAND";
+		else
+			return -1;
+	}
+
+	if (print) {
+		printf("Boot Media: %s\n", bootmedia);
+
+		if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) {
+			uint64_t capacity =
+				(uint64_t)le16_to_cpu(nh->numblocks) *
+				(uint64_t)le16_to_cpu(nh->pages_of_block) *
+				(uint64_t)le16_to_cpu(nh->pagesize) * 8;
+			printf("Capacity:     %dGb\n",
+			       (uint32_t)(capacity >> 30));
+		}
+
+		if (le16_to_cpu(nh->pagesize) >= 1024)
+			printf("Page Size:    %dKB\n",
+			       le16_to_cpu(nh->pagesize) >> 10);
+		else
+			printf("Page Size:    %dB\n",
+			       le16_to_cpu(nh->pagesize));
+
+		printf("Spare Size:   %dB\n", le16_to_cpu(nh->oobsize));
+	}
+
+	gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize));
+
+	if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
+		return -1;
+
+	if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_NAND)
+		return -1;
+
+	if (print)
+		printf("Load Address: %08x\n",
+		       le32_to_cpu(gfh->file_info.load_addr) +
+		       le32_to_cpu(gfh->file_info.jump_offset));
+
+	return 0;
+}
+
+static int mtk_image_verify_header(unsigned char *ptr, int image_size,
+				   struct image_tool_params *params)
+{
+	union lk_hdr *lk = (union lk_hdr *)ptr;
+
+	/* nothing to verify for LK image header */
+	if (le32_to_cpu(lk->magic) == LK_PART_MAGIC)
+		return 0;
+
+	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
+		return mtk_image_verify_nand_header(ptr, 0);
+	else
+		return mtk_image_verify_gen_header(ptr, 0);
+
+	return -1;
+}
+
+static void mtk_image_print_header(const void *ptr)
+{
+	union lk_hdr *lk = (union lk_hdr *)ptr;
+
+	if (le32_to_cpu(lk->magic) == LK_PART_MAGIC) {
+		printf("Image Type:   MediaTek LK Image\n");
+		printf("Load Address: %08x\n", le32_to_cpu(lk->loadaddr));
+		return;
+	}
+
+	printf("Image Type:   MediaTek BootROM Loadable Image\n");
+
+	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
+		mtk_image_verify_nand_header(ptr, 1);
+	else
+		mtk_image_verify_gen_header(ptr, 1);
+}
+
+static void put_brom_layout_header(struct brom_layout_header *hdr, int type)
+{
+	strncpy(hdr->name, BRLYT_NAME, sizeof(hdr->name));
+	hdr->version = cpu_to_le32(1);
+	hdr->magic = cpu_to_le32(BRLYT_MAGIC);
+	hdr->type = cpu_to_le32(type);
+}
+
+static void put_ghf_common_header(struct gfh_common_header *gfh, int size,
+				  int type, int ver)
+{
+	memcpy(gfh->magic, GFH_HEADER_MAGIC, sizeof(gfh->magic));
+	gfh->version = ver;
+	gfh->size = cpu_to_le16(size);
+	gfh->type = cpu_to_le16(type);
+}
+
+static void put_ghf_header(struct gfh_header *gfh, int file_size,
+			   int dev_hdr_size, int load_addr, int flash_type)
+{
+	memset(gfh, 0, sizeof(struct gfh_header));
+
+	/* GFH_FILE_INFO header */
+	put_ghf_common_header(&gfh->file_info.gfh, sizeof(gfh->file_info),
+			      GFH_TYPE_FILE_INFO, 1);
+	strncpy(gfh->file_info.name, GFH_FILE_INFO_NAME,
+		sizeof(gfh->file_info.name));
+	gfh->file_info.unused = cpu_to_le32(1);
+	gfh->file_info.file_type = cpu_to_le16(1);
+	gfh->file_info.flash_type = flash_type;
+	gfh->file_info.sig_type = GFH_SIG_TYPE_SHA256;
+	gfh->file_info.load_addr = cpu_to_le32(load_addr - sizeof(*gfh));
+	gfh->file_info.total_size = cpu_to_le32(file_size - dev_hdr_size);
+	gfh->file_info.max_size = cpu_to_le32(file_size);
+	gfh->file_info.hdr_size = sizeof(*gfh);
+	gfh->file_info.sig_size = SHA256_SUM_LEN;
+	gfh->file_info.jump_offset = sizeof(*gfh);
+	gfh->file_info.processed = cpu_to_le32(1);
+
+	/* GFH_BL_INFO header */
+	put_ghf_common_header(&gfh->bl_info.gfh, sizeof(gfh->bl_info),
+			      GFH_TYPE_BL_INFO, 1);
+	gfh->bl_info.attr = cpu_to_le32(1);
+
+	/* GFH_BROM_CFG header */
+	put_ghf_common_header(&gfh->brom_cfg.gfh, sizeof(gfh->brom_cfg),
+			      GFH_TYPE_BROM_CFG, 3);
+	gfh->brom_cfg.cfg_bits = cpu_to_le32(
+		GFH_BROM_CFG_USBDL_AUTO_DETECT_DIS |
+		GFH_BROM_CFG_USBDL_BY_KCOL0_TIMEOUT_EN |
+		GFH_BROM_CFG_USBDL_BY_FLAG_TIMEOUT_EN);
+	gfh->brom_cfg.usbdl_by_kcol0_timeout_ms = cpu_to_le32(5000);
+
+	/* GFH_BL_SEC_KEY header */
+	put_ghf_common_header(&gfh->bl_sec_key.gfh, sizeof(gfh->bl_sec_key),
+			      GFH_TYPE_BL_SEC_KEY, 1);
+
+	/* GFH_ANTI_CLONE header */
+	put_ghf_common_header(&gfh->anti_clone.gfh, sizeof(gfh->anti_clone),
+			      GFH_TYPE_ANTI_CLONE, 1);
+	gfh->anti_clone.ac_offset = cpu_to_le32(0x10);
+	gfh->anti_clone.ac_len = cpu_to_le32(0x80);
+
+	/* GFH_BROM_SEC_CFG header */
+	put_ghf_common_header(&gfh->brom_sec_cfg.gfh,
+			      sizeof(gfh->brom_sec_cfg),
+			      GFH_TYPE_BROM_SEC_CFG, 1);
+	gfh->brom_sec_cfg.cfg_bits =
+		cpu_to_le32(BROM_SEC_CFG_JTAG_EN | BROM_SEC_CFG_UART_EN);
+}
+
+static void put_hash(uint8_t *buff, int size)
+{
+	sha256_context ctx;
+
+	sha256_starts(&ctx);
+	sha256_update(&ctx, buff, size);
+	sha256_finish(&ctx, buff + size);
+}
+
+static void mtk_image_set_gen_header(void *ptr, off_t filesize,
+				     uint32_t loadaddr)
+{
+	struct gen_device_header *hdr = (struct gen_device_header *)ptr;
+	struct gfh_header *gfh;
+	const char *bootname = NULL;
+
+	if (hdr_media == BRLYT_TYPE_NOR)
+		bootname = SF_BOOT_NAME;
+	else if (hdr_media == BRLYT_TYPE_EMMC)
+		bootname = EMMC_BOOT_NAME;
+	else if (hdr_media == BRLYT_TYPE_SDMMC)
+		bootname = SDMMC_BOOT_NAME;
+
+	/* Generic device header */
+	strncpy(hdr->boot.name, bootname, sizeof(hdr->boot.name));
+	hdr->boot.version = cpu_to_le32(1);
+	hdr->boot.size = cpu_to_le32(sizeof(hdr->boot));
+
+	/* BRLYT header */
+	put_brom_layout_header(&hdr->brlyt, hdr_media);
+	hdr->brlyt.header_size = cpu_to_le32(sizeof(struct gen_device_header));
+	hdr->brlyt.total_size = cpu_to_le32(filesize);
+	hdr->brlyt.header_size_2 = hdr->brlyt.header_size;
+	hdr->brlyt.total_size_2 = hdr->brlyt.total_size;
+
+	/* GFH header */
+	gfh = (struct gfh_header *)(ptr + sizeof(struct gen_device_header));
+	put_ghf_header(gfh, filesize, sizeof(struct gen_device_header),
+		       loadaddr, GFH_FLASH_TYPE_GEN);
+
+	/* Generate SHA256 hash */
+	put_hash((uint8_t *)gfh,
+		 filesize - sizeof(struct gen_device_header) - SHA256_SUM_LEN);
+}
+
+static void mtk_image_set_nand_header(void *ptr, off_t filesize,
+				      uint32_t loadaddr)
+{
+	union nand_boot_header *nh = (union nand_boot_header *)ptr;
+	struct brom_layout_header *brlyt;
+	struct gfh_header *gfh;
+	uint32_t payload_pages;
+	int i;
+
+	/* NAND device header, repeat 4 times */
+	for (i = 0; i < 4; i++)
+		memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
+
+	/* BRLYT header */
+	payload_pages = (filesize + le16_to_cpu(hdr_nand->pagesize) - 1) /
+			le16_to_cpu(hdr_nand->pagesize);
+	brlyt = (struct brom_layout_header *)
+		(ptr + le16_to_cpu(hdr_nand->pagesize));
+	put_brom_layout_header(brlyt, hdr_media);
+	brlyt->header_size = cpu_to_le32(2);
+	brlyt->total_size = cpu_to_le32(payload_pages);
+	brlyt->header_size_2 = brlyt->header_size;
+	brlyt->total_size_2 = brlyt->total_size;
+	brlyt->unused = cpu_to_le32(1);
+
+	/* GFH header */
+	gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(hdr_nand->pagesize));
+	put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand->pagesize),
+		       loadaddr, GFH_FLASH_TYPE_NAND);
+
+	/* Generate SHA256 hash */
+	put_hash((uint8_t *)gfh,
+		 filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN);
+}
+
+static void mtk_image_set_header(void *ptr, struct stat *sbuf, int ifd,
+				 struct image_tool_params *params)
+{
+	union lk_hdr *lk = (union lk_hdr *)ptr;
+
+	if (use_lk_hdr) {
+		lk->magic = cpu_to_le32(LK_PART_MAGIC);
+		lk->size = cpu_to_le32(sbuf->st_size - sizeof(union lk_hdr));
+		lk->loadaddr = cpu_to_le32(params->addr);
+		lk->mode = 0xffffffff; /* must be non-zero */
+		memset(lk->name, 0, sizeof(lk->name));
+		strncpy(lk->name, lk_name, sizeof(lk->name));
+		return;
+	}
+
+	if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
+		mtk_image_set_nand_header(ptr, sbuf->st_size, params->addr);
+	else
+		mtk_image_set_gen_header(ptr, sbuf->st_size, params->addr);
+}
+
+U_BOOT_IMAGE_TYPE(
+	mtk_image,
+	"MediaTek BootROM Loadable Image support",
+	0,
+	NULL,
+	mtk_image_check_params,
+	mtk_image_verify_header,
+	mtk_image_print_header,
+	mtk_image_set_header,
+	NULL,
+	mtk_image_check_image_types,
+	NULL,
+	mtk_image_vrec_header
+);
diff --git a/tools/mtk_image.h b/tools/mtk_image.h
new file mode 100644
index 0000000..0a9eab3
--- /dev/null
+++ b/tools/mtk_image.h
@@ -0,0 +1,199 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * MediaTek BootROM header definitions
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _MTK_IMAGE_H
+#define _MTK_IMAGE_H
+
+/* Device header definitions */
+
+/* Header for NOR/SD/eMMC */
+union gen_boot_header {
+	struct {
+		char name[12];
+		__le32 version;
+		__le32 size;
+	};
+
+	uint8_t pad[0x200];
+};
+
+#define EMMC_BOOT_NAME		"EMMC_BOOT"
+#define SF_BOOT_NAME		"SF_BOOT"
+#define SDMMC_BOOT_NAME		"SDMMC_BOOT"
+
+/* Header for NAND */
+union nand_boot_header {
+	struct {
+		char name[12];
+		char version[4];
+		char id[8];
+		__le16 ioif;
+		__le16 pagesize;
+		__le16 addrcycles;
+		__le16 oobsize;
+		__le16 pages_of_block;
+		__le16 numblocks;
+		__le16 writesize_shift;
+		__le16 erasesize_shift;
+		uint8_t dummy[60];
+		uint8_t ecc_parity[28];
+	};
+
+	uint8_t data[0x80];
+};
+
+#define NAND_BOOT_NAME		"BOOTLOADER!"
+#define NAND_BOOT_VERSION	"V006"
+#define NAND_BOOT_ID		"NFIINFO"
+
+/* BootROM layout header */
+struct brom_layout_header {
+	char name[8];
+	__le32 version;
+	__le32 header_size;
+	__le32 total_size;
+	__le32 magic;
+	__le32 type;
+	__le32 header_size_2;
+	__le32 total_size_2;
+	__le32 unused;
+};
+
+#define BRLYT_NAME		"BRLYT"
+#define BRLYT_MAGIC		0x42424242
+
+enum brlyt_img_type {
+	BRLYT_TYPE_INVALID = 0,
+	BRLYT_TYPE_NAND = 0x10002,
+	BRLYT_TYPE_EMMC = 0x10005,
+	BRLYT_TYPE_NOR = 0x10007,
+	BRLYT_TYPE_SDMMC = 0x10008,
+	BRLYT_TYPE_SNAND = 0x10009
+};
+
+/* Combined device header for NOR/SD/eMMC */
+struct gen_device_header {
+	union gen_boot_header boot;
+
+	union {
+		struct brom_layout_header brlyt;
+		uint8_t brlyt_pad[0x400];
+	};
+};
+
+/* BootROM header definitions */
+struct gfh_common_header {
+	uint8_t magic[3];
+	uint8_t version;
+	__le16 size;
+	__le16 type;
+};
+
+#define GFH_HEADER_MAGIC	"MMM"
+
+#define GFH_TYPE_FILE_INFO	0
+#define GFH_TYPE_BL_INFO	1
+#define GFH_TYPE_BROM_CFG	7
+#define GFH_TYPE_BL_SEC_KEY	3
+#define GFH_TYPE_ANTI_CLONE	2
+#define GFH_TYPE_BROM_SEC_CFG	8
+
+struct gfh_file_info {
+	struct gfh_common_header gfh;
+	char name[12];
+	__le32 unused;
+	__le16 file_type;
+	uint8_t flash_type;
+	uint8_t sig_type;
+	__le32 load_addr;
+	__le32 total_size;
+	__le32 max_size;
+	__le32 hdr_size;
+	__le32 sig_size;
+	__le32 jump_offset;
+	__le32 processed;
+};
+
+#define GFH_FILE_INFO_NAME	"FILE_INFO"
+
+#define GFH_FLASH_TYPE_GEN	5
+#define GFH_FLASH_TYPE_NAND	2
+
+#define GFH_SIG_TYPE_NONE	0
+#define GFH_SIG_TYPE_SHA256	1
+
+struct gfh_bl_info {
+	struct gfh_common_header gfh;
+	__le32 attr;
+};
+
+struct gfh_brom_cfg {
+	struct gfh_common_header gfh;
+	__le32 cfg_bits;
+	__le32 usbdl_by_auto_detect_timeout_ms;
+	uint8_t unused[0x48];
+	__le32 usbdl_by_kcol0_timeout_ms;
+	__le32 usbdl_by_flag_timeout_ms;
+	uint32_t pad;
+};
+
+#define GFH_BROM_CFG_USBDL_BY_AUTO_DETECT_TIMEOUT_EN	0x02
+#define GFH_BROM_CFG_USBDL_AUTO_DETECT_DIS		0x10
+#define GFH_BROM_CFG_USBDL_BY_KCOL0_TIMEOUT_EN		0x80
+#define GFH_BROM_CFG_USBDL_BY_FLAG_TIMEOUT_EN		0x100
+
+struct gfh_bl_sec_key {
+	struct gfh_common_header gfh;
+	uint8_t pad[0x20c];
+};
+
+struct gfh_anti_clone {
+	struct gfh_common_header gfh;
+	uint8_t ac_b2k;
+	uint8_t ac_b2c;
+	uint16_t pad;
+	__le32 ac_offset;
+	__le32 ac_len;
+};
+
+struct gfh_brom_sec_cfg {
+	struct gfh_common_header gfh;
+	__le32 cfg_bits;
+	char customer_name[0x20];
+	__le32 pad;
+};
+
+#define BROM_SEC_CFG_JTAG_EN	1
+#define BROM_SEC_CFG_UART_EN	2
+
+struct gfh_header {
+	struct gfh_file_info file_info;
+	struct gfh_bl_info bl_info;
+	struct gfh_brom_cfg brom_cfg;
+	struct gfh_bl_sec_key bl_sec_key;
+	struct gfh_anti_clone anti_clone;
+	struct gfh_brom_sec_cfg brom_sec_cfg;
+};
+
+/* LK image header */
+
+union lk_hdr {
+	struct {
+		__le32 magic;
+		__le32 size;
+		char name[32];
+		__le32 loadaddr;
+		__le32 mode;
+	};
+
+	uint8_t data[512];
+};
+
+#define LK_PART_MAGIC		0x58881688
+
+#endif /* _MTK_IMAGE_H */