refactor(allwinner): move DTB change code into allwinner/common

So far the H616 was the only Allwinner SoC needed to amend the DTB, to
reserve the DRAM portion that BL31 occupies.
To allow other SoCs to modify the DTB as well, without duplicating code,
move the DTB change routines into Allwinner common code, and generalise
the current code to allow other modifications.

No functional change intended.

Change-Id: I080ea07b6470367f3c2573a4368f8ef5196d411c
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Samuel Holland <samuel@sholland.org>
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index 34fdaf6..cf559fb 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -65,6 +65,23 @@
 $(eval $(call assert_boolean,SUNXI_SETUP_REGULATORS))
 $(eval $(call add_define,SUNXI_SETUP_REGULATORS))
 
+SUNXI_BL31_IN_DRAM	?=	0
+$(eval $(call assert_boolean,SUNXI_BL31_IN_DRAM))
+
+ifeq (${SUNXI_BL31_IN_DRAM},1)
+SUNXI_AMEND_DTB		:=	1
+$(eval $(call add_define,SUNXI_BL31_IN_DRAM))
+endif
+
+SUNXI_AMEND_DTB		?=	0
+$(eval $(call assert_boolean,SUNXI_AMEND_DTB))
+$(eval $(call add_define,SUNXI_AMEND_DTB))
+
+ifeq (${SUNXI_AMEND_DTB},1)
+BL31_SOURCES		+=	common/fdt_fixup.c			\
+				${AW_PLAT}/common/sunxi_prepare_dtb.c
+endif
+
 # The bootloader is guaranteed to only run on CPU 0 by the boot ROM.
 COLD_BOOT_SINGLE_CPU		:=	1
 
diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h
index 6cf4670..efea736 100644
--- a/plat/allwinner/common/include/sunxi_private.h
+++ b/plat/allwinner/common/include/sunxi_private.h
@@ -41,7 +41,7 @@
 int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb);
 void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param);
 
-#ifdef SUNXI_BL31_IN_DRAM
+#if SUNXI_AMEND_DTB
 void sunxi_prepare_dtb(void *fdt);
 #else
 static inline void sunxi_prepare_dtb(void *fdt)
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index 14049e8..ed3dbd4 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -180,6 +180,7 @@
 
 	sunxi_pmic_setup(soc_id, fdt);
 
+	/* Change the DTB if the configuration requires so. */
 	sunxi_prepare_dtb(fdt);
 
 	INFO("BL31: Platform setup done\n");
diff --git a/plat/allwinner/common/sunxi_prepare_dtb.c b/plat/allwinner/common/sunxi_prepare_dtb.c
new file mode 100644
index 0000000..93428ac
--- /dev/null
+++ b/plat/allwinner/common/sunxi_prepare_dtb.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2021, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <libfdt.h>
+
+#include <common/debug.h>
+#include <common/fdt_fixup.h>
+#include <common/fdt_wrappers.h>
+
+#include <sunxi_private.h>
+
+void sunxi_prepare_dtb(void *fdt)
+{
+	int ret;
+
+	if (fdt == NULL || fdt_check_header(fdt) != 0) {
+		return;
+	}
+
+	ret = fdt_open_into(fdt, fdt, 0x10000);
+	if (ret < 0) {
+		ERROR("Preparing devicetree at %p: error %d\n", fdt, ret);
+		return;
+	}
+
+#ifdef SUNXI_BL31_IN_DRAM
+	/* Reserve memory used by Trusted Firmware. */
+	if (fdt_add_reserved_memory(fdt, "tf-a@40000000", BL31_BASE,
+				    BL31_LIMIT - BL31_BASE)) {
+		WARN("Failed to add reserved memory nodes to DT.\n");
+		return;
+	}
+#endif
+
+	ret = fdt_pack(fdt);
+	if (ret < 0) {
+		ERROR("Failed to pack devicetree at %p: error %d\n",
+		      fdt, ret);
+	} else {
+		clean_dcache_range((uintptr_t)fdt, fdt_blob_size(fdt));
+		INFO("Changed devicetree.\n");
+	}
+}