Merge "fix(rd1ae): fix rd1-ae device tree" into integration
diff --git a/docs/plat/arm/automotive_rd/index.rst b/docs/plat/arm/automotive_rd/index.rst
index d0db6ac..04ca2b9 100644
--- a/docs/plat/arm/automotive_rd/index.rst
+++ b/docs/plat/arm/automotive_rd/index.rst
@@ -11,15 +11,34 @@
 Boot Sequence
 -------------
 
-BL2 –> BL31 –> BL33
+The boot process starts from RSE (Runtime Security Engine) that loads the
+Application Processor (AP) BL2 image and signals the System Control Processor (SCP)
+to power up the AP. The AP then runs AP BL2
 
-The boot process starts from RSE (Runtime Security Engine) that loads the BL2 image
-and signals the System Control Processor (SCP) to power up the Application Processor (AP).
-The AP then runs BL2, which loads the rest of the images, including the runtime firmware
-BL31, and proceeds to execute it. Finally, it passes control to the non-secure world
-BL33 (u-boot).
+The primary compute boot flow follows the following steps:
 
-BL2 performs the actions described in the `Trusted Board Boot (TBB)`_ document.
+1. AP BL2:
+
+   * Performs the actions described in the `Trusted Board Boot (TBB)`_ document.
+   * Copies the AP BL31 image from Secure Flash to Secure SRAM
+   * Copies the AP BL32 (OP-TEE) image from Secure Flash to Secure DRAM
+   * Copies the AP BL33 (U-Boot) image from Secure Flash to Normal DRAM
+   * Transfers the execution to AP BL31
+
+2. AP BL31:
+
+   * Initializes Trusted Firmware-A Services
+   * Transfers the execution to AP BL32 and then transfers the execution to AP BL33
+   * During runtime, acts as the Secure Monitor, handling SMC calls,
+     and context switching between secure and non-secure worlds.
+
+3. AP BL32:
+
+   * Initializes OP-TEE environment
+   * Initializes Secure Partitions
+   * Transfers the execution back to AP BL31
+   * During runtime, it facilitates secure communication between the
+     normal world environment (e.g. Linux) and the Trusted Execution Environment.
 
 Build Procedure (TF-A only)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -41,6 +60,9 @@
       COT=tbbr \
       ARM_ROTPK_LOCATION=devel_rsa \
       ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \
+      BL32=<path to optee binary> \
+      SPD=spmd \
+      SPMD_SPM_AT_SEL2=0 \
       BL33=<path to u-boot binary> \
 
 *Copyright (c) 2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index a8e0c8d..0b53d1d 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -24,6 +24,7 @@
    mt8188
    mt8192
    mt8195
+   mt8196
    nvidia-tegra
    warp7
    imx8
diff --git a/docs/plat/mt8196.rst b/docs/plat/mt8196.rst
new file mode 100644
index 0000000..e4b6c63
--- /dev/null
+++ b/docs/plat/mt8196.rst
@@ -0,0 +1,23 @@
+MediaTek 8196
+=============
+
+MediaTek 8196 (MT8196) is a 64-bit ARM SoC introduced by MediaTek in 2024.
+The chip incorporates eight cores - four Cortex-A720 cores, three Cortex-X4
+cores and one Cortex-X925 core.
+Cortex-A720 can operate at up to 2.1 GHz.
+Cortex-X4 can operate at up to 2.8 GHz.
+Cortex-X925 can operate at up to 3.6 GHz.
+
+Boot Sequence
+-------------
+
+::
+
+    Boot Rom --> Coreboot --> TF-A BL31 --> Depthcharge --> Linux Kernel
+
+How to Build
+------------
+
+.. code:: shell
+
+    make CROSS_COMPILE=aarch64-linux-gnu- PLAT=mt8196 DEBUG=1 COREBOOT=1
diff --git a/drivers/renesas/common/io/io_rcar.c b/drivers/renesas/common/io/io_rcar.c
index 66662c1..1529dc0 100644
--- a/drivers/renesas/common/io/io_rcar.c
+++ b/drivers/renesas/common/io/io_rcar.c
@@ -149,6 +149,9 @@
 static uint64_t rcar_image_header_prttn[RCAR_MAX_BL3X_IMAGE + 2U] = { 0U };
 static uint64_t rcar_image_number = { 0U };
 static uint32_t rcar_cert_load = { 0U };
+#if (RCAR_RPC_HYPERFLASH_ABLOADER == 1)
+static uint32_t rcar_image_offset = 0U;
+#endif
 
 static io_type_t device_type_rcar(void)
 {
@@ -196,8 +199,10 @@
 
 		*offset = rcar_image_header[addr];
 
-		if (mmio_read_32(MFISBTSTSR) & MFISBTSTSR_BOOT_PARTITION)
-			*offset += 0x800000;
+#if (RCAR_RPC_HYPERFLASH_ABLOADER == 1)
+		*offset += rcar_image_offset;
+#endif
+
 		*cert = RCAR_CERT_SIZE;
 		*cert *= RCAR_ATTR_GET_CERTOFF(name_offset[i].attr);
 		*cert += RCAR_SDRAM_certESS;
@@ -499,6 +504,15 @@
 	 */
 	offset = name == EMMC_DEV_ID ? RCAR_EMMC_CERT_HEADER :
 	    RCAR_FLASH_CERT_HEADER;
+
+#if (RCAR_RPC_HYPERFLASH_ABLOADER == 1)
+	rcar_image_offset = 0;
+	if ((name == FLASH_DEV_ID) &&
+	    (mmio_read_32(MFISBTSTSR) & MFISBTSTSR_BOOT_PARTITION)) {
+		rcar_image_offset = 0x800000;
+	}
+#endif
+
 	rc = io_seek(handle, IO_SEEK_SET, offset);
 	if (rc != IO_SUCCESS) {
 		WARN("Firmware Image Package header failed to seek\n");
diff --git a/fdts/rd1ae.dts b/fdts/rd1ae.dts
index 08f771d..26eaa65 100644
--- a/fdts/rd1ae.dts
+++ b/fdts/rd1ae.dts
@@ -255,6 +255,21 @@
 		#size-cells = <2>;
 		ranges;
 
+		timer@2a810000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x2a810000 0 0x10000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			clock-frequency = <250000000>;
+			ranges;
+
+			frame@2a830000 {
+				frame-number = <0>;
+				interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0 0x2a830000 0x0 0x10000>;
+			};
+		};
+
 		gic: interrupt-controller@30000000 {
 			compatible = "arm,gic-v3";
 			reg = <0x0 0x30000000 0 0x10000>,	// GICD
diff --git a/fdts/tc-base.dtsi b/fdts/tc-base.dtsi
index 735d429..e898399 100644
--- a/fdts/tc-base.dtsi
+++ b/fdts/tc-base.dtsi
@@ -405,34 +405,50 @@
 	dpu_aclk: dpu_aclk {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
-		clock-frequency = <VENCODER_TIMING_CLK>;
+		clock-frequency = <LCD_TIMING_CLK>;
 		clock-output-names = "fpga:dpu_aclk";
 	};
 
 	dpu_pixel_clk: dpu-pixel-clk {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
-		clock-frequency = <VENCODER_TIMING_CLK>;
+		clock-frequency = <LCD_TIMING_CLK>;
 		clock-output-names = "pxclk";
 	};
 #endif /* !TC_DPU_USE_SCMI_CLK */
 
+#if TC_DPU_USE_SIMPLE_PANEL
+	vpanel {
+		compatible = "panel-dpi";
+		post-init-providers = <&pl0>;
+		port {
+			lcd_in: endpoint {
+				remote-endpoint = <&dp_pl0_out0>;
+			};
+		};
+
+		panel-timing {
+			LCD_TIMING;
+		};
+	};
+
+#else
 	vencoder {
 		compatible = "drm,virtual-encoder";
 		port {
-			vencoder_in: endpoint {
+			lcd_in: endpoint {
 				remote-endpoint = <&dp_pl0_out0>;
 			};
 		};
 
 		display-timings {
 			timing-panel {
-				VENCODER_TIMING;
+				LCD_TIMING;
 			};
 		};
 
 	};
-
+#endif
 	ethernet: ethernet@ETHERNET_ADDR {
 		reg = <0x0 ADDRESSIFY(ETHERNET_ADDR) 0x0 0x10000>;
 		interrupts = <GIC_SPI ETHERNET_INT IRQ_TYPE_LEVEL_HIGH 0>;
@@ -575,7 +591,7 @@
 				port@0 {
 					reg = <0>;
 					dp_pl0_out0: endpoint {
-						remote-endpoint = <&vencoder_in>;
+						remote-endpoint = <&lcd_in>;
 					};
 				};
 			};
diff --git a/fdts/tc-fpga.dtsi b/fdts/tc-fpga.dtsi
index 08b9ae5..af140bb 100644
--- a/fdts/tc-fpga.dtsi
+++ b/fdts/tc-fpga.dtsi
@@ -8,9 +8,9 @@
 #define GIC_GICR_OFFSET		0x1000000
 #define UART_OFFSET		0x10000
 /* 1440x3200@120 framebuffer */
-#define VENCODER_TIMING_CLK 836000000
-#define VENCODER_TIMING								\
-	clock-frequency = <VENCODER_TIMING_CLK>;				\
+#define LCD_TIMING_CLK 836000000
+#define LCD_TIMING								\
+	clock-frequency = <LCD_TIMING_CLK>;					\
 	hactive = <1440>;							\
 	vactive = <3200>;							\
 	hfront-porch = <136>;							\
@@ -25,6 +25,19 @@
 		stdout-path = "serial0:38400n8";
 	};
 
+#if TC_FPGA_ANDROID_IMG_IN_RAM
+	reserved-memory {
+		phram@0x880000000 {
+			/*
+			 * starting from 0x8_8000_0000 reserve some memory
+			 * android image will be side loaded to this location
+			 */
+			reg = <0x8 0x80000000  HI(ANDROID_FS_SIZE) LO(ANDROID_FS_SIZE)>
+			no-map;
+		};
+	};
+#endif /* TC_FPGA_ANDROID_IMG_IN_RAM */
+
 	ethernet: ethernet@ETHERNET_ADDR {
 		compatible = "smsc,lan9115";
 		phy-mode = "mii";
diff --git a/fdts/tc-fvp.dtsi b/fdts/tc-fvp.dtsi
index f57e21d..960730c 100644
--- a/fdts/tc-fvp.dtsi
+++ b/fdts/tc-fvp.dtsi
@@ -10,9 +10,9 @@
 
 #ifdef TC_RESOLUTION_1920X1080P60
 
-#define VENCODER_TIMING_CLK 148500000
-#define VENCODER_TIMING								\
-	clock-frequency = <VENCODER_TIMING_CLK>;				\
+#define LCD_TIMING_CLK 148500000
+#define LCD_TIMING								\
+	clock-frequency = <LCD_TIMING_CLK>;					\
 	hactive = <1920>;							\
 	vactive = <1080>;							\
 	hfront-porch = <88>;							\
@@ -24,9 +24,9 @@
 
 #else /* TC_RESOLUTION_640X480P60 */
 
-#define VENCODER_TIMING_CLK 25175000
-#define VENCODER_TIMING								\
-	clock-frequency = <VENCODER_TIMING_CLK>;				\
+#define LCD_TIMING_CLK 25175000
+#define LCD_TIMING								\
+	clock-frequency = <LCD_TIMING_CLK>;					\
 	hactive = <640>;							\
 	vactive = <480>;							\
 	hfront-porch = <16>;							\
diff --git a/include/lib/cpus/aarch64/cortex_alto.h b/include/lib/cpus/aarch64/cortex_alto.h
new file mode 100644
index 0000000..1c8786a
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_alto.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_ALTO_H
+#define CORTEX_ALTO_H
+
+#define CORTEX_ALTO_MIDR					U(0x411FD900)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_ALTO_IMP_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_ALTO_IMP_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_ALTO_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT	U(1)
+
+/*******************************************************************************
+ * SME Control registers
+ ******************************************************************************/
+#define CORTEX_ALTO_SVCRSM					S0_3_C4_C2_3
+#define CORTEX_ALTO_SVCRZA					S0_3_C4_C4_3
+
+#endif /* CORTEX_ALTO_H */
diff --git a/lib/cpus/aarch64/cortex_alto.S b/lib/cpus/aarch64/cortex_alto.S
new file mode 100644
index 0000000..c0815f9
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_alto.S
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_alto.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Alto must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Alto supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start cortex_alto
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end cortex_alto
+
+func cortex_alto_core_pwr_dwn
+#if ENABLE_SME_FOR_NS
+        /* ---------------------------------------------------
+         * Disable SME if enabled and supported
+         * ---------------------------------------------------
+         */
+	mrs     x0, ID_AA64PFR1_EL1
+	ubfx	x0, x0, #ID_AA64PFR1_EL1_SME_SHIFT, \
+		#ID_AA64PFR1_EL1_SME_WIDTH
+        cmp     x0, #SME_NOT_IMPLEMENTED
+	b.eq	1f
+	msr	CORTEX_ALTO_SVCRSM, xzr
+	msr	CORTEX_ALTO_SVCRZA, xzr
+1:
+#endif
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set CORTEX_ALTO_IMP_CPUPWRCTLR_EL1, \
+		CORTEX_ALTO_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
+	isb
+	ret
+endfunc cortex_alto_core_pwr_dwn
+
+.section .rodata.cortex_alto_regs, "aS"
+cortex_alto_regs: /* The ASCII list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_alto_cpu_reg_dump
+	adr 	x6, cortex_alto_regs
+	mrs	x8, CORTEX_ALTO_IMP_CPUECTLR_EL1
+	ret
+endfunc cortex_alto_cpu_reg_dump
+
+declare_cpu_ops cortex_alto, CORTEX_ALTO_MIDR, \
+	cortex_alto_reset_func, \
+	cortex_alto_core_pwr_dwn
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_fw_config.dts b/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_fw_config.dts
index 53cd3b0..89e30e9 100644
--- a/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_fw_config.dts
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_fw_config.dts
@@ -12,6 +12,12 @@
 	dtb-registry {
 		compatible = "fconf,dyn_cfg-dtb_registry";
 
+		tos_fw-config {
+			load-address = <0x0 0x70000>;
+			max-size = <0x1000>;
+			id = <TOS_FW_CONFIG_ID>;
+		};
+
 		hw-config {
 			load-address = <0x0 0x83000000>;
 			max-size = <0x8000>;
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_optee_spmc_manifest.dts b/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_optee_spmc_manifest.dts
new file mode 100644
index 0000000..c28cadf
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_optee_spmc_manifest.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+	compatible = "arm,ffa-core-manifest-1.0";
+	#address-cells = <2>;
+	#size-cells = <1>;
+
+	/*
+	 * BL32 image details needed by SPMC
+	 */
+
+	attribute {
+		spmc_id = <0x8000>;
+		maj_ver = <0x1>;
+		min_ver = <0x0>;
+		exec_state = <0x0>;
+		load_address = <0x0 0xffc00000>;
+		entrypoint = <0x0 0xffc00000>;
+		binary_size = <0x00400000>;
+	};
+};
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/include/platform_def.h b/plat/arm/board/automotive_rd/platform/rd1ae/include/platform_def.h
index 44c8ee3..b71be40 100644
--- a/plat/arm/board/automotive_rd/platform/rd1ae/include/platform_def.h
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/include/platform_def.h
@@ -45,6 +45,9 @@
 #define PLAT_CSS_MHU_BASE			UL(0x2A920000)
 #define PLAT_ARM_NSTIMER_FRAME_ID		U(0)
 
+#define PLAT_ARM_SPMC_BASE		        UL(0xFFC00000)
+#define PLAT_ARM_SPMC_SIZE		        UL(0x00400000)
+
 #define SOC_CSS_SEC_UART_BASE			UL(0x2A410000)
 #define SOC_CSS_NSEC_UART_BASE			UL(0x2A400000)
 #define SOC_CSS_UART_SIZE			UL(0x10000)
@@ -115,10 +118,14 @@
 						MT_SECURE)
 
 #define RD1AE_MAP_NS_DRAM1	MAP_REGION_FLAT(ARM_DRAM1_BASE,	\
-						ARM_DRAM1_SIZE,	\
+						ARM_DRAM1_SIZE - PLAT_ARM_SPMC_SIZE, \
 						MT_MEMORY | MT_RW | \
 						MT_NS)
 
+#define RD1AE_MAP_S_DRAM1	MAP_REGION_FLAT(PLAT_ARM_SPMC_BASE, \
+						PLAT_ARM_SPMC_SIZE,	\
+						MT_MEMORY | MT_RW | MT_SECURE)
+
 #define RD1AE_DEVICE_BASE	(0x20000000)
 #define RD1AE_DEVICE_SIZE	(0x20000000)
 #define RD1AE_MAP_DEVICE	MAP_REGION_FLAT(RD1AE_DEVICE_BASE, \
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk b/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk
index 35cd8a1..6773ae0 100644
--- a/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk
@@ -32,6 +32,7 @@
 GIC_ENABLE_V4_EXTN			:=	1
 GICV3_SUPPORT_GIC600			:=	1
 HW_ASSISTED_COHERENCY			:=	1
+NEED_BL32				:=	yes
 PLAT_MHU_VERSION			:=	1
 RESET_TO_BL2				:=	1
 SVE_VECTOR_LEN				:=	128
@@ -68,15 +69,19 @@
 
 # Add the FDT_SOURCES and options for Dynamic Config
 FDT_SOURCES	+=	${RD1AE_BASE}/fdts/${PLAT}_fw_config.dts	\
-			fdts/${PLAT}.dts
+			fdts/${PLAT}.dts				\
+			${RD1AE_BASE}/fdts/${PLAT}_optee_spmc_manifest.dts
 
 FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
 HW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}.dtb
+TOS_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_optee_spmc_manifest.dtb
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
 # Add the HW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${HW_CONFIG},--hw-config,${HW_CONFIG}))
+# Add the TOS_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TOS_FW_CONFIG},--tos-fw-config,${TOS_FW_CONFIG}))
 
 ifeq (${TRUSTED_BOARD_BOOT},1)
 FIP_BL2_ARGS	:=	tb-fw
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl2_mem_params_desc.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl2_mem_params_desc.c
index 30cc90f..8d0b96f 100644
--- a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl2_mem_params_desc.c
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl2_mem_params_desc.c
@@ -36,7 +36,7 @@
 		.image_info.image_base = BL31_BASE,
 		.image_info.image_max_size = BL31_LIMIT - BL31_BASE,
 
-		.next_handoff_image_id = BL33_IMAGE_ID,
+		.next_handoff_image_id = BL32_IMAGE_ID,
 	},
 	/* Fill HW_CONFIG related information */
 	{
@@ -48,6 +48,30 @@
 			VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
 		.next_handoff_image_id = INVALID_IMAGE_ID,
 	},
+	/* Fill BL32 related information */
+	{
+		.image_id = BL32_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+			VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
+		.ep_info.pc = BL32_BASE,
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+			VERSION_2, image_info_t, 0),
+		.image_info.image_base = BL32_BASE,
+		.image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+
+		.next_handoff_image_id = BL33_IMAGE_ID,
+	},
+	/* Fill TOS_FW_CONFIG related information */
+	{
+		.image_id = TOS_FW_CONFIG_ID,
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+			VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+			VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
 	/* Fill BL33 related information */
 	{
 		.image_id = BL33_IMAGE_ID,
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl31_setup.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl31_setup.c
index ce7bad7..6cfe34a 100644
--- a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl31_setup.c
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl31_setup.c
@@ -26,3 +26,14 @@
 {
 	return css_scmi_override_pm_ops(ops);
 }
+
+#if defined(SPD_spmd) && (SPMC_AT_EL3 == 0)
+/*
+ * A dummy implementation of the platform handler for Group0 secure interrupt.
+ */
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	(void)intid;
+	return -1;
+}
+#endif /* defined(SPD_spmd) && (SPMC_AT_EL3 == 0) */
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_plat.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_plat.c
index e917330..229ab24 100644
--- a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_plat.c
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_plat.c
@@ -19,6 +19,7 @@
 #if IMAGE_BL2
 	RD1AE_MAP_NS_DRAM1,
 #endif
+	RD1AE_MAP_S_DRAM1,
 	{0}
 };
 
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 0156b31..dddecfd 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -218,7 +218,8 @@
 				lib/cpus/aarch64/cortex_gelas.S		\
 				lib/cpus/aarch64/nevis.S		\
 				lib/cpus/aarch64/travis.S		\
-				lib/cpus/aarch64/cortex_arcadia.S
+				lib/cpus/aarch64/cortex_arcadia.S	\
+				lib/cpus/aarch64/cortex_alto.S
 endif
 
 else
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index 86fce0e..7f24f84 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -207,7 +207,21 @@
 #if defined(TARGET_FLAVOUR_FPGA)
 #undef V2M_FLASH0_BASE
 #undef V2M_FLASH0_SIZE
+#if TC_FPGA_FIP_IMG_IN_RAM
+/*
+ * Note that this is just used for the FIP, which is not required
+ * anymore once Linux has commenced booting. So we are safe allowing
+ * Linux to also make use of this memory and it doesn't need to be
+ * carved out of the devicetree.
+ *
+ * This only needs to match the RAM load address that we give the FIP
+ * on either the FPGA or FVP command line so there is no need to link
+ * it to say halfway through the RAM or anything like that.
+ */
+#define V2M_FLASH0_BASE			UL(0xB0000000)
+#else
 #define V2M_FLASH0_BASE			UL(0x0C000000)
+#endif
 #define V2M_FLASH0_SIZE			UL(0x02000000)
 #endif
 
@@ -242,10 +256,28 @@
 
 #if TARGET_PLATFORM <= 2
 #define PLAT_ARM_DRAM2_BASE		ULL(0x8080000000)
+#define PLAT_ARM_DRAM2_SIZE             ULL(0x180000000)
 #elif TARGET_PLATFORM >= 3
-#define PLAT_ARM_DRAM2_BASE		ULL(0x880000000)
-#endif /* TARGET_PLATFORM >= 3 */
-#define PLAT_ARM_DRAM2_SIZE		ULL(0x180000000)
+
+#if TC_FPGA_ANDROID_IMG_IN_RAM
+/* 10GB reserved for system+userdata+vendor images */
+#define SYSTEM_IMAGE_SIZE		0xC0000000	/* 3GB */
+#define USERDATA_IMAGE_SIZE		0x140000000	/* 5GB */
+#define VENDOR_IMAGE_SIZE		0x20000000 	/* 512MB */
+#define RESERVE_IMAGE_SIZE		0x60000000      /* 1.5GB */
+#define ANDROID_FS_SIZE			(SYSTEM_IMAGE_SIZE + \
+					 USERDATA_IMAGE_SIZE + \
+					 VENDOR_IMAGE_SIZE + RESERVE_IMAGE_SIZE)
+
+#define PLAT_ARM_DRAM2_BASE		ULL(0x880000000) + ANDROID_FS_SIZE
+#define PLAT_ARM_DRAM2_SIZE		ULL(0x380000000) - ANDROID_FS_SIZE
+#else
+#define PLAT_ARM_DRAM2_BASE             ULL(0x880000000)
+#define PLAT_ARM_DRAM2_SIZE             ULL(0x380000000)
+#endif /* TC_FPGA_ANDROID_IMG_IN_RAM */
+
+#endif /* TARGET_VERSION >= 3 */
+
 #define PLAT_ARM_DRAM2_END		(PLAT_ARM_DRAM2_BASE + PLAT_ARM_DRAM2_SIZE - 1ULL)
 
 #define TC_NS_MTE_SIZE			(256 * SZ_1M)
@@ -341,13 +373,13 @@
  * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current
  * SCP_BL2 size plus a little space for growth.
  */
-#define PLAT_CSS_MAX_SCP_BL2_SIZE	0x20000
+#define PLAT_CSS_MAX_SCP_BL2_SIZE	0x30000
 
 /*
  * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current
  * SCP_BL2U size plus a little space for growth.
  */
-#define PLAT_CSS_MAX_SCP_BL2U_SIZE	0x20000
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE	0x30000
 
 #if TARGET_PLATFORM <= 2
 /* TZC Related Constants */
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 9cd3011..3178c06 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -77,12 +77,24 @@
         $(error TARGET_FLAVOUR must be fvp or fpga)
 endif
 
+# Support for loading Android Image to DRAM
+TC_FPGA_ANDROID_IMG_IN_RAM := 0
+
+# Support Loading of FIP image to DRAM
+TC_FPGA_FIP_IMG_IN_RAM := 0
+
+# Use simple panel instead of vencoder with DPU
+TC_DPU_USE_SIMPLE_PANEL := 0
+
 $(eval $(call add_defines, \
 	TARGET_PLATFORM \
 	TARGET_FLAVOUR_$(call uppercase,${TARGET_FLAVOUR}) \
 	TC_RESOLUTION_$(call uppercase,${TC_RESOLUTION}) \
 	TC_DPU_USE_SCMI_CLK \
 	TC_SCMI_PD_CTRL_EN \
+	TC_FPGA_ANDROID_IMG_IN_RAM \
+	TC_FPGA_FIP_IMG_IN_RAM \
+	TC_DPU_USE_SIMPLE_PANEL \
 ))
 
 CSS_LOAD_SCP_IMAGES	:=	1
diff --git a/plat/mediatek/drivers/gpio/mtgpio_common.h b/plat/mediatek/drivers/gpio/mtgpio_common.h
index d6b858c..a93a065 100644
--- a/plat/mediatek/drivers/gpio/mtgpio_common.h
+++ b/plat/mediatek/drivers/gpio/mtgpio_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -97,7 +97,7 @@
 	}
 
 struct mt_pin_info {
-	uint8_t id;
+	uint16_t id;
 	uint8_t flag;
 	uint8_t bit;
 	uint16_t base;
diff --git a/plat/mediatek/drivers/timer/mt_timer.h b/plat/mediatek/drivers/timer/mt_timer.h
index 1c08f90..fafbbcf 100644
--- a/plat/mediatek/drivers/timer/mt_timer.h
+++ b/plat/mediatek/drivers/timer/mt_timer.h
@@ -7,7 +7,12 @@
 #ifndef MT_TIMER_H
 #define MT_TIMER_H
 
+#include "platform_def.h"
+
+#ifndef SYSTIMER_BASE
 #define SYSTIMER_BASE       (0x10017000)
+#endif
+
 #define CNTCR_REG           (SYSTIMER_BASE + 0x0)
 #define CNTSR_REG           (SYSTIMER_BASE + 0x4)
 #define CNTSYS_L_REG        (SYSTIMER_BASE + 0x8)
diff --git a/plat/mediatek/helpers/armv9/arch_helpers.S b/plat/mediatek/helpers/armv9/arch_helpers.S
new file mode 100644
index 0000000..f96fff9
--- /dev/null
+++ b/plat/mediatek/helpers/armv9/arch_helpers.S
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2024, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cpu_macros.S>
+#include <platform_def.h>
+#if CONFIG_MTK_MCUSYS
+#include <mcucfg.h>
+#endif
+
+	/*
+	 * Declare as weak function so that can be
+	 * overwritten by platform helpers
+	 */
+	.weak platform_mem_init
+	.weak plat_core_pos_by_mpidr
+	.weak plat_my_core_pos
+	.weak plat_mediatek_calc_core_pos
+	.global plat_mpidr_by_core_pos
+	.global plat_reset_handler
+
+	/* -----------------------------------------------------
+	 * unsigned long plat_mpidr_by_core_pos(uint32_t cpuid)
+	 * This function calcuate mpidr by cpu pos if cpu
+	 * topology is linear.
+	 *
+	 * Clobbers: x0-x1
+	 * -----------------------------------------------------
+	 */
+func plat_mpidr_by_core_pos
+	lsl x0, x0, #MPIDR_AFF1_SHIFT
+	mrs x1, mpidr_el1
+	and x1, x1, #MPIDR_MT_MASK
+	orr x0, x0, x1
+	ret
+endfunc plat_mpidr_by_core_pos
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_my_core_pos(void)
+	 *  This function uses the plat_arm_calc_core_pos()
+	 *  definition to get the index of the calling CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	b plat_mediatek_calc_core_pos
+endfunc plat_my_core_pos
+
+	/* -----------------------------------------------------
+	 * int plat_mediatek_calc_core_pos(u_register_t mpidr);
+	 *
+	 * In ARMv8.2, AFF2 is cluster id, AFF1 is core id and
+	 * AFF0 is thread id. There is only one cluster in ARMv8.2
+	 * and one thread in current implementation.
+	 *
+	 * With this function: CorePos = CoreID (AFF1)
+	 * we do it with x0 = (x0 >> 8) & 0xff
+	 * -----------------------------------------------------
+	 */
+func plat_mediatek_calc_core_pos
+	b plat_core_pos_by_mpidr
+endfunc plat_mediatek_calc_core_pos
+
+	/* ------------------------------------------------------
+	 * int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
+	 *
+	 * This function implements a part of the critical
+	 * interface between the psci generic layer and the
+	 * platform that allows the former to query the platform
+	 * to convert an MPIDR to a unique linear index.
+	 *
+	 * Clobbers: x0-x1
+	 * ------------------------------------------------------
+	 */
+func plat_core_pos_by_mpidr
+	mov	x1, #MPIDR_AFFLVL_MASK
+	and	x0, x1, x0, lsr #MPIDR_AFF1_SHIFT
+	ret
+endfunc plat_core_pos_by_mpidr
+
+	/* --------------------------------------------------------
+	 * void platform_mem_init (void);
+	 *
+	 * Any memory init, relocation to be done before the
+	 * platform boots. Called very early in the boot process.
+	 * --------------------------------------------------------
+	 */
+func platform_mem_init
+	ret
+endfunc platform_mem_init
+
+func plat_reset_handler
+#if CONFIG_MTK_MCUSYS
+	mov x10, x30
+	bl plat_my_core_pos
+	mov x30, x10
+	mov w1, #0x1
+	lsl w1, w1, w0
+	ldr x0, =CPC_MCUSYS_CPU_ON_SW_HINT_SET
+	str w1, [x0]
+	dsb sy
+#endif
+
+	ret
+endfunc plat_reset_handler
diff --git a/plat/mediatek/include/armv9/arch_def.h b/plat/mediatek/include/armv9/arch_def.h
new file mode 100644
index 0000000..d1d5a14
--- /dev/null
+++ b/plat/mediatek/include/armv9/arch_def.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2024, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ARCH_DEF_H
+#define ARCH_DEF_H
+
+#include <arch.h>
+
+/* Topology constants */
+#ifndef PLAT_MAX_PWR_LVL
+#define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL2
+#endif
+#define PLAT_MAX_RET_STATE		MPIDR_AFFLVL1
+
+#ifndef PLAT_MAX_OFF_STATE
+#define PLAT_MAX_OFF_STATE		MPIDR_AFFLVL2
+#endif
+
+#define PLATFORM_SYSTEM_COUNT         1
+#define PLATFORM_CLUSTER_COUNT        1
+#define PLATFORM_CLUSTER0_CORE_COUNT  8
+#define PLATFORM_CORE_COUNT	(PLATFORM_CLUSTER0_CORE_COUNT)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	8
+#define PLATFORM_NUM_AFFS		(PLATFORM_SYSTEM_COUNT +	\
+					 PLATFORM_CLUSTER_COUNT +	\
+					 PLATFORM_CORE_COUNT)
+
+/* Cachline size */
+#define CACHE_WRITEBACK_SHIFT	6
+#define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
+#endif /* ARCH_DEF_H */
diff --git a/plat/mediatek/lib/pm/armv9_0/rules.mk b/plat/mediatek/lib/pm/armv9_0/rules.mk
new file mode 100644
index 0000000..08a7957
--- /dev/null
+++ b/plat/mediatek/lib/pm/armv9_0/rules.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := armv${CONFIG_MTK_PM_ARCH}
+
+LOCAL_SRCS-y :=
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/mt8196/drivers/gpio/mtgpio.c b/plat/mediatek/mt8196/drivers/gpio/mtgpio.c
new file mode 100644
index 0000000..6257159
--- /dev/null
+++ b/plat/mediatek/mt8196/drivers/gpio/mtgpio.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <platform_def.h>
+#include <mtgpio.h>
+
+typedef enum {
+	REG_0 = 0,
+	REG_1,
+	REG_2,
+	REG_3,
+	REG_4,
+	REG_5,
+	REG_6,
+	REG_7,
+	REG_8,
+	REG_9,
+	REG_10,
+	REG_11,
+	REG_12,
+	REG_13,
+	REG_14
+} RegEnum;
+
+uintptr_t mt_gpio_find_reg_addr(uint32_t pin)
+{
+	uintptr_t reg_addr = 0U;
+	struct mt_pin_info gpio_info;
+
+	assert(pin < MAX_GPIO_PIN);
+
+	gpio_info = mt_pin_infos[pin];
+
+	switch (gpio_info.base & 0xF) {
+	case REG_0:
+		reg_addr = IOCFG_RT_BASE;
+		break;
+	case REG_1:
+		reg_addr = IOCFG_RM1_BASE;
+		break;
+	case REG_2:
+		reg_addr = IOCFG_RM2_BASE;
+		break;
+	case REG_3:
+		reg_addr = IOCFG_RB_BASE;
+		break;
+	case REG_4:
+		reg_addr = IOCFG_BM1_BASE;
+		break;
+	case REG_5:
+		reg_addr = IOCFG_BM2_BASE;
+		break;
+	case REG_6:
+		reg_addr = IOCFG_BM3_BASE;
+		break;
+	case REG_7:
+		reg_addr = IOCFG_LT_BASE;
+		break;
+	case REG_8:
+		reg_addr = IOCFG_LM1_BASE;
+		break;
+	case REG_9:
+		reg_addr = IOCFG_LM2_BASE;
+		break;
+	case REG_10:
+		reg_addr = IOCFG_LB1_BASE;
+		break;
+	case REG_11:
+		reg_addr = IOCFG_LB2_BASE;
+		break;
+	case REG_12:
+		reg_addr = IOCFG_TM1_BASE;
+		break;
+	case REG_13:
+		reg_addr = IOCFG_TM2_BASE;
+		break;
+	case REG_14:
+		reg_addr = IOCFG_TM3_BASE;
+		break;
+	default:
+		break;
+	}
+
+	return reg_addr;
+}
diff --git a/plat/mediatek/mt8196/drivers/gpio/mtgpio.h b/plat/mediatek/mt8196/drivers/gpio/mtgpio.h
new file mode 100644
index 0000000..a33bdad
--- /dev/null
+++ b/plat/mediatek/mt8196/drivers/gpio/mtgpio.h
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_GPIO_H
+#define MT_GPIO_H
+
+#include <mtgpio_common.h>
+
+/* Enumeration for GPIO pin */
+typedef enum GPIO_PIN {
+	GPIO_UNSUPPORTED = -1,
+	GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6,
+	GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, GPIO13, GPIO14,
+	GPIO15, GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22,
+	GPIO23, GPIO24, GPIO25, GPIO26, GPIO27, GPIO28, GPIO29, GPIO30,
+	GPIO31, GPIO32, GPIO33, GPIO34, GPIO35, GPIO36, GPIO37, GPIO38,
+	GPIO39, GPIO40, GPIO41, GPIO42, GPIO43, GPIO44, GPIO45, GPIO46,
+	GPIO47, GPIO48, GPIO49, GPIO50, GPIO51, GPIO52, GPIO53, GPIO54,
+	GPIO55, GPIO56, GPIO57, GPIO58, GPIO59, GPIO60, GPIO61, GPIO62,
+	GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70,
+	GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78,
+	GPIO79, GPIO80, GPIO81, GPIO82, GPIO83, GPIO84, GPIO85, GPIO86,
+	GPIO87, GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, GPIO93, GPIO94,
+	GPIO95, GPIO96, GPIO97, GPIO98, GPIO99, GPIO100, GPIO101, GPIO102,
+	GPIO103, GPIO104, GPIO105, GPIO106, GPIO107, GPIO108, GPIO109, GPIO110,
+	GPIO111, GPIO112, GPIO113, GPIO114, GPIO115, GPIO116, GPIO117, GPIO118,
+	GPIO119, GPIO120, GPIO121, GPIO122, GPIO123, GPIO124, GPIO125, GPIO126,
+	GPIO127, GPIO128, GPIO129, GPIO130, GPIO131, GPIO132, GPIO133, GPIO134,
+	GPIO135, GPIO136, GPIO137, GPIO138, GPIO139, GPIO140, GPIO141, GPIO142,
+	GPIO143, GPIO144, GPIO145, GPIO146, GPIO147, GPIO148, GPIO149, GPIO150,
+	GPIO151, GPIO152, GPIO153, GPIO154, GPIO155, GPIO156, GPIO157, GPIO158,
+	GPIO159, GPIO160, GPIO161, GPIO162, GPIO163, GPIO164, GPIO165, GPIO166,
+	GPIO167, GPIO168, GPIO169, GPIO170, GPIO171, GPIO172, GPIO173, GPIO174,
+	GPIO175, GPIO176, GPIO177, GPIO178, GPIO179, GPIO180, GPIO181, GPIO182,
+	GPIO183, GPIO184, GPIO185, GPIO186, GPIO187, GPIO188, GPIO189, GPIO190,
+	GPIO191, GPIO192, GPIO193, GPIO194, GPIO195, GPIO196, GPIO197, GPIO198,
+	GPIO199, GPIO200, GPIO201, GPIO202, GPIO203, GPIO204, GPIO205, GPIO206,
+	GPIO207, GPIO208, GPIO209, GPIO210, GPIO211, GPIO212, GPIO213, GPIO214,
+	GPIO215, GPIO216, GPIO217, GPIO218, GPIO219, GPIO220, GPIO221, GPIO222,
+	GPIO223, GPIO224, GPIO225, GPIO226, GPIO227, GPIO228, GPIO229, GPIO230,
+	GPIO231, GPIO232, GPIO233, GPIO234, GPIO235, GPIO236, GPIO237, GPIO238,
+	GPIO239, GPIO240, GPIO241, GPIO242, GPIO243, GPIO244, GPIO245, GPIO246,
+	GPIO247, GPIO248, GPIO249, GPIO250, GPIO251, GPIO252, GPIO253, GPIO254,
+	GPIO255, GPIO256, GPIO257, GPIO258, GPIO259, GPIO260, GPIO261, GPIO262,
+	GPIO263, GPIO264, GPIO265, GPIO266, GPIO267, GPIO268, GPIO269, GPIO270,
+	MT_GPIO_BASE_MAX
+} GPIO_PIN;
+
+static const struct mt_pin_info mt_pin_infos[] = {
+	PIN(0, 0, 0, 0x18, 0x90),
+	PIN(1, 0, 1, 0x18, 0x90),
+	PIN(2, 0, 1, 0x1b, 0x70),
+	PIN(3, 0, 2, 0x1b, 0x70),
+	PIN(4, 0, 3, 0x1b, 0x70),
+	PIN(5, 0, 4, 0x1b, 0x70),
+	PIN(6, 0, 5, 0x1b, 0x70),
+	PIN(7, 0, 6, 0x1b, 0x70),
+	PIN(8, 0, 7, 0x1b, 0x70),
+	PIN(9, 0, 14, 0x29, 0xa0),
+	PIN(10, 0, 12, 0x29, 0xa0),
+	PIN(11, 0, 2, 0x18, 0x90),
+	PIN(12, 0, 13, 0x29, 0xa0),
+	PIN(13, 0, 1, 0x26, 0x90),
+	PIN(14, 0, 0, 0x13, 0x80),
+	PIN(15, 0, 2, 0x26, 0x90),
+	PIN(16, 0, 3, 0x26, 0x90),
+	PIN(17, 0, 4, 0x26, 0x90),
+	PIN(18, 0, 5, 0x26, 0x90),
+	PIN(19, 0, 6, 0x26, 0x90),
+	PIN(20, 0, 1, 0x13, 0x80),
+	PIN(21, 0, 3, 0x12, 0x80),
+	PIN(22, 0, 4, 0x12, 0x80),
+	PIN(23, 0, 5, 0x12, 0x80),
+	PIN(24, 0, 6, 0x12, 0x80),
+	PIN(25, 0, 7, 0x12, 0x80),
+	PIN(26, 0, 8, 0x12, 0x80),
+	PIN(27, 0, 9, 0x12, 0x80),
+	PIN(28, 0, 10, 0x12, 0x80),
+	PIN(29, 0, 11, 0x12, 0x80),
+	PIN(30, 0, 12, 0x12, 0x80),
+	PIN(31, 0, 13, 0x12, 0x80),
+	PIN(32, 0, 8, 0x11, 0x80),
+	PIN(33, 0, 9, 0x11, 0x80),
+	PIN(34, 0, 10, 0x11, 0x80),
+	PIN(35, 0, 11, 0x11, 0x80),
+	PIN(36, 0, 12, 0x11, 0x80),
+	PIN(37, 0, 13, 0x11, 0x80),
+	PIN(38, 0, 14, 0x11, 0x80),
+	PIN(39, 0, 6, 0x18, 0x90),
+	PIN(40, 0, 3, 0x18, 0x90),
+	PIN(41, 0, 5, 0x18, 0x90),
+	PIN(42, 0, 4, 0x18, 0x90),
+	PIN(43, 0, 7, 0x18, 0x90),
+	PIN(44, 0, 8, 0x18, 0x90),
+	PIN(45, 0, 9, 0x18, 0x90),
+	PIN(46, 0, 10, 0x18, 0x90),
+	PIN(47, 0, 13, 0x18, 0x90),
+	PIN(48, 0, 11, 0x18, 0x90),
+	PIN(49, 0, 14, 0x18, 0x90),
+	PIN(50, 0, 12, 0x18, 0x90),
+	PIN(51, 0, 15, 0x18, 0x90),
+	PIN(52, 0, 7, 0x29, 0xa0),
+	PIN(53, 0, 8, 0x29, 0xa0),
+	PIN(54, 0, 2, 0x29, 0xa0),
+	PIN(55, 0, 1, 0x29, 0xa0),
+	PIN(56, 0, 5, 0x29, 0xa0),
+	PIN(57, 0, 6, 0x29, 0xa0),
+	PIN(58, 0, 3, 0x29, 0xa0),
+	PIN(59, 0, 4, 0x29, 0xa0),
+	PIN(60, 1, 0, 0x29, 0xb0),
+	PIN(61, 0, 10, 0x29, 0xa0),
+	PIN(62, 0, 9, 0x29, 0xa0),
+	PIN(63, 0, 18, 0x29, 0xa0),
+	PIN(64, 0, 0, 0x29, 0xa0),
+	PIN(65, 0, 11, 0x29, 0xa0),
+	PIN(66, 0, 24, 0x29, 0xa0),
+	PIN(67, 0, 21, 0x29, 0xa0),
+	PIN(68, 0, 20, 0x29, 0xa0),
+	PIN(69, 0, 25, 0x29, 0xa0),
+	PIN(70, 0, 16, 0x29, 0xa0),
+	PIN(71, 0, 15, 0x29, 0xa0),
+	PIN(72, 0, 23, 0x29, 0xa0),
+	PIN(73, 0, 19, 0x29, 0xa0),
+	PIN(74, 0, 17, 0x29, 0xa0),
+	PIN(75, 0, 2, 0x1a, 0x80),
+	PIN(76, 0, 3, 0x1a, 0x80),
+	PIN(77, 0, 4, 0x1a, 0x80),
+	PIN(78, 0, 5, 0x1a, 0x80),
+	PIN(79, 0, 0, 0x1a, 0x80),
+	PIN(80, 0, 1, 0x1a, 0x80),
+	PIN(81, 0, 9, 0x1b, 0x70),
+	PIN(82, 0, 10, 0x1b, 0x70),
+	PIN(83, 0, 12, 0x1b, 0x70),
+	PIN(84, 0, 11, 0x1b, 0x70),
+	PIN(85, 0, 13, 0x1b, 0x70),
+	PIN(86, 0, 14, 0x1b, 0x70),
+	PIN(87, 0, 16, 0x1b, 0x70),
+	PIN(88, 0, 15, 0x1b, 0x70),
+	PIN(89, 0, 0, 0x1b, 0x70),
+	PIN(90, 0, 8, 0x1b, 0x70),
+	PIN(91, 0, 6, 0x1c, 0x80),
+	PIN(92, 0, 7, 0x1c, 0x80),
+	PIN(93, 0, 8, 0x1c, 0x80),
+	PIN(94, 0, 4, 0x1c, 0x80),
+	PIN(95, 0, 1, 0x1c, 0x80),
+	PIN(96, 0, 3, 0x1c, 0x80),
+	PIN(97, 0, 2, 0x1c, 0x80),
+	PIN(98, 0, 5, 0x1c, 0x80),
+	PIN(99, 0, 9, 0x1c, 0x80),
+	PIN(100, 0, 12, 0x1c, 0x80),
+	PIN(101, 0, 10, 0x1c, 0x80),
+	PIN(102, 0, 13, 0x1c, 0x80),
+	PIN(103, 0, 0, 0x1c, 0x80),
+	PIN(104, 0, 11, 0x1c, 0x80),
+	PIN(105, 0, 14, 0x1c, 0x80),
+	PIN(106, 0, 0, 0x15, 0x80),
+	PIN(107, 0, 1, 0x15, 0x80),
+	PIN(108, 0, 3, 0x15, 0x80),
+	PIN(109, 0, 2, 0x15, 0x80),
+	PIN(110, 0, 4, 0x15, 0x80),
+	PIN(111, 0, 5, 0x15, 0x80),
+	PIN(112, 0, 7, 0x15, 0x80),
+	PIN(113, 0, 6, 0x15, 0x80),
+	PIN(114, 0, 8, 0x15, 0x80),
+	PIN(115, 0, 9, 0x15, 0x80),
+	PIN(116, 0, 11, 0x15, 0x80),
+	PIN(117, 0, 10, 0x15, 0x80),
+	PIN(118, 0, 9, 0x26, 0x90),
+	PIN(119, 0, 10, 0x26, 0x90),
+	PIN(120, 0, 12, 0x26, 0x90),
+	PIN(121, 0, 11, 0x26, 0x90),
+	PIN(122, 0, 0, 0x26, 0x90),
+	PIN(123, 0, 7, 0x26, 0x90),
+	PIN(124, 0, 8, 0x26, 0x90),
+	PIN(125, 1, 0, 0x17, 0x80),
+	PIN(126, 1, 1, 0x17, 0x80),
+	PIN(127, 1, 2, 0x17, 0x80),
+	PIN(128, 1, 3, 0x17, 0x80),
+	PIN(129, 1, 4, 0x17, 0x80),
+	PIN(130, 1, 5, 0x17, 0x80),
+	PIN(131, 1, 9, 0x17, 0x80),
+	PIN(132, 1, 11, 0x17, 0x80),
+	PIN(133, 1, 10, 0x17, 0x80),
+	PIN(134, 1, 6, 0x17, 0x80),
+	PIN(135, 1, 8, 0x17, 0x80),
+	PIN(136, 1, 7, 0x17, 0x80),
+	PIN(137, 1, 10, 0x14, 0x70),
+	PIN(138, 1, 11, 0x14, 0x70),
+	PIN(139, 1, 12, 0x14, 0x70),
+	PIN(140, 1, 13, 0x14, 0x70),
+	PIN(141, 1, 14, 0x14, 0x70),
+	PIN(142, 1, 15, 0x14, 0x70),
+	PIN(143, 1, 16, 0x14, 0x70),
+	PIN(144, 1, 17, 0x14, 0x70),
+	PIN(145, 1, 0, 0x14, 0x70),
+	PIN(146, 1, 1, 0x14, 0x70),
+	PIN(147, 1, 2, 0x14, 0x70),
+	PIN(148, 1, 3, 0x14, 0x70),
+	PIN(149, 1, 4, 0x14, 0x70),
+	PIN(150, 1, 5, 0x14, 0x70),
+	PIN(151, 1, 6, 0x14, 0x70),
+	PIN(152, 1, 7, 0x14, 0x70),
+	PIN(153, 1, 9, 0x14, 0x70),
+	PIN(154, 1, 8, 0x14, 0x70),
+	PIN(155, 1, 18, 0x14, 0x70),
+	PIN(156, 1, 19, 0x14, 0x70),
+	PIN(157, 0, 1, 0x12, 0x80),
+	PIN(158, 0, 2, 0x12, 0x80),
+	PIN(159, 0, 0, 0x12, 0x80),
+	PIN(160, 0, 22, 0x13, 0x80),
+	PIN(161, 0, 20, 0x13, 0x80),
+	PIN(162, 0, 23, 0x13, 0x80),
+	PIN(163, 0, 21, 0x13, 0x80),
+	PIN(164, 0, 12, 0x13, 0x80),
+	PIN(165, 0, 14, 0x13, 0x80),
+	PIN(166, 0, 13, 0x13, 0x80),
+	PIN(167, 0, 15, 0x13, 0x80),
+	PIN(168, 0, 16, 0x13, 0x80),
+	PIN(169, 0, 17, 0x13, 0x80),
+	PIN(170, 0, 19, 0x13, 0x80),
+	PIN(171, 0, 18, 0x13, 0x80),
+	PIN(172, 0, 10, 0x13, 0x80),
+	PIN(173, 0, 11, 0x13, 0x80),
+	PIN(174, 0, 15, 0x11, 0x80),
+	PIN(175, 0, 16, 0x11, 0x80),
+	PIN(176, 0, 17, 0x11, 0x80),
+	PIN(177, 0, 18, 0x11, 0x80),
+	PIN(178, 0, 6, 0x11, 0x80),
+	PIN(179, 0, 7, 0x11, 0x80),
+	PIN(180, 0, 0, 0x11, 0x80),
+	PIN(181, 0, 1, 0x11, 0x80),
+	PIN(182, 0, 2, 0x11, 0x80),
+	PIN(183, 0, 3, 0x11, 0x80),
+	PIN(184, 0, 4, 0x11, 0x80),
+	PIN(185, 0, 5, 0x11, 0x80),
+	PIN(186, 0, 4, 0x1d, 0xc0),
+	PIN(187, 0, 5, 0x1d, 0xc0),
+	PIN(188, 0, 12, 0x1d, 0xc0),
+	PIN(189, 0, 17, 0x1d, 0xc0),
+	PIN(190, 0, 13, 0x1d, 0xc0),
+	PIN(191, 0, 18, 0x1d, 0xc0),
+	PIN(192, 0, 0, 0x1d, 0xc0),
+	PIN(193, 0, 6, 0x1d, 0xc0),
+	PIN(194, 0, 14, 0x1d, 0xc0),
+	PIN(195, 0, 19, 0x1d, 0xc0),
+	PIN(196, 0, 1, 0x1d, 0xc0),
+	PIN(197, 0, 7, 0x1d, 0xc0),
+	PIN(198, 0, 15, 0x1d, 0xc0),
+	PIN(199, 0, 20, 0x1d, 0xc0),
+	PIN(200, 0, 22, 0x1d, 0xc0),
+	PIN(201, 0, 25, 0x1d, 0xc0),
+	PIN(202, 0, 16, 0x1d, 0xc0),
+	PIN(203, 0, 21, 0x1d, 0xc0),
+	PIN(204, 0, 2, 0x1d, 0xc0),
+	PIN(205, 0, 3, 0x1d, 0xc0),
+	PIN(206, 0, 8, 0x1d, 0xc0),
+	PIN(207, 0, 9, 0x1d, 0xc0),
+	PIN(208, 0, 10, 0x1d, 0xc0),
+	PIN(209, 0, 11, 0x1d, 0xc0),
+	PIN(210, 0, 0, 0x2e, 0x90),
+	PIN(211, 0, 1, 0x2e, 0x90),
+	PIN(212, 0, 2, 0x2e, 0x90),
+	PIN(213, 0, 3, 0x2e, 0x90),
+	PIN(214, 0, 23, 0x1d, 0xc0),
+	PIN(215, 0, 24, 0x1d, 0xc0),
+	PIN(216, 0, 4, 0x2e, 0x90),
+	PIN(217, 1, 1, 0x2e, 0xa0),
+	PIN(218, 1, 2, 0x2e, 0xa0),
+	PIN(219, 1, 0, 0x2e, 0xa0),
+	PIN(220, 0, 5, 0x2e, 0x90),
+	PIN(221, 0, 6, 0x2e, 0x90),
+	PIN(222, 0, 8, 0x2e, 0x90),
+	PIN(223, 0, 7, 0x2e, 0x90),
+	PIN(224, 1, 3, 0x2e, 0xa0),
+	PIN(225, 1, 4, 0x2e, 0xa0),
+	PIN(226, 1, 5, 0x2e, 0xa0),
+	PIN(227, 1, 6, 0x2e, 0xa0),
+	PIN(228, 1, 7, 0x2e, 0xa0),
+	PIN(229, 1, 8, 0x2e, 0xa0),
+	PIN(230, 0, 13, 0x2f, 0x70),
+	PIN(231, 0, 14, 0x2f, 0x70),
+	PIN(232, 0, 10, 0x2f, 0x70),
+	PIN(233, 0, 0, 0x2f, 0x70),
+	PIN(234, 0, 3, 0x2f, 0x70),
+	PIN(235, 0, 1, 0x2f, 0x70),
+	PIN(236, 0, 2, 0x2f, 0x70),
+	PIN(237, 0, 6, 0x2f, 0x70),
+	PIN(238, 0, 5, 0x2f, 0x70),
+	PIN(239, 0, 19, 0x2f, 0x70),
+	PIN(240, 0, 18, 0x2f, 0x70),
+	PIN(241, 0, 16, 0x2f, 0x70),
+	PIN(242, 0, 17, 0x2f, 0x70),
+	PIN(243, 0, 15, 0x2f, 0x70),
+	PIN(244, 0, 12, 0x2f, 0x70),
+	PIN(245, 0, 9, 0x2f, 0x70),
+	PIN(246, 0, 8, 0x2f, 0x70),
+	PIN(247, 0, 7, 0x2f, 0x70),
+	PIN(248, 0, 4, 0x2f, 0x70),
+	PIN(249, 0, 20, 0x2f, 0x70),
+	PIN(250, 0, 11, 0x2f, 0x70),
+	PIN(251, 0, 2, 0x13, 0x80),
+	PIN(252, 0, 3, 0x13, 0x80),
+	PIN(253, 0, 4, 0x13, 0x80),
+	PIN(254, 0, 5, 0x13, 0x80),
+	PIN(255, 0, 6, 0x13, 0x80),
+	PIN(256, 0, 7, 0x13, 0x80),
+	PIN(257, 0, 8, 0x13, 0x80),
+	PIN(258, 0, 9, 0x13, 0x80),
+	PIN(259, 1, 9, 0x2e, 0xa0),
+	PIN(260, 1, 10, 0x2e, 0xa0),
+	PIN(261, 1, 11, 0x2e, 0xa0),
+	PIN(262, 1, 12, 0x2e, 0xa0),
+	PIN(263, 1, 13, 0x2e, 0xa0),
+	PIN(264, 1, 14, 0x2e, 0xa0),
+	PIN(265, 1, 15, 0x2e, 0xa0),
+	PIN(266, 1, 16, 0x2e, 0xa0),
+	PIN(267, 1, 2, 0x2f, 0x80),
+	PIN(268, 1, 3, 0x2f, 0x80),
+	PIN(269, 1, 0, 0x2f, 0x80),
+	PIN(270, 1, 1, 0x2f, 0x80),
+};
+
+#endif /* MT_GPIO_H */
diff --git a/plat/mediatek/mt8196/include/plat_macros.S b/plat/mediatek/mt8196/include/plat_macros.S
new file mode 100644
index 0000000..c646edd
--- /dev/null
+++ b/plat/mediatek/mt8196/include/plat_macros.S
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2024, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <platform_def.h>
+
+.section .rodata.gic_reg_name, "aS"
+gicc_regs:
+	.asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+gicd_pend_reg:
+	.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n"	\
+		" Offset:\t\t\tvalue\n"
+newline:
+	.asciz "\n"
+spacer:
+	.asciz ":\t\t0x"
+
+.section .rodata.cci_reg_name, "aS"
+cci_iface_regs:
+	.asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , ""
+
+	/* ---------------------------------------------
+	 * The below macro prints out relevant GIC
+	 * registers whenever an unhandled exception
+	 * is taken in BL31.
+	 * Clobbers: x0 - x10, x26, x27, sp
+	 * ---------------------------------------------
+	 */
+	.macro plat_crash_print_regs
+	/* TODO: leave implementation to GIC owner */
+	.endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/mediatek/mt8196/include/plat_private.h b/plat/mediatek/mt8196/include/plat_private.h
new file mode 100644
index 0000000..1ed1973
--- /dev/null
+++ b/plat/mediatek/mt8196/include/plat_private.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2024, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_PRIVATE_H
+#define PLAT_PRIVATE_H
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+void plat_configure_mmu_el3(uintptr_t total_base,
+			    uintptr_t total_size,
+			    uintptr_t ro_start,
+			    uintptr_t ro_limit);
+
+#endif /* PLAT_PRIVATE_H */
diff --git a/plat/mediatek/mt8196/include/platform_def.h b/plat/mediatek/mt8196/include/platform_def.h
new file mode 100644
index 0000000..5b45d92
--- /dev/null
+++ b/plat/mediatek/mt8196/include/platform_def.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2024, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <plat/common/common_def.h>
+
+#include <arch_def.h>
+
+#define PLAT_PRIMARY_CPU	(0x0)
+
+#define MT_GIC_BASE		(0x0C400000)
+#define MCUCFG_BASE		(0x0C000000)
+#define MCUCFG_REG_SIZE		(0x50000)
+#define IO_PHYS			(0x10000000)
+
+/* Aggregate of all devices for MMU mapping */
+#define MTK_DEV_RNG1_BASE	(IO_PHYS)
+#define MTK_DEV_RNG1_SIZE	(0x10000000)
+
+#define TOPCKGEN_BASE		(IO_PHYS)
+
+/*******************************************************************************
+ * AUDIO related constants
+ ******************************************************************************/
+#define AUDIO_BASE		(IO_PHYS + 0x0a110000)
+
+/*******************************************************************************
+ * SPM related constants
+ ******************************************************************************/
+#define SPM_BASE		(IO_PHYS + 0x0C004000)
+
+/*******************************************************************************
+ * GPIO related constants
+ ******************************************************************************/
+#define GPIO_BASE		(IO_PHYS + 0x0002D000)
+#define RGU_BASE		(IO_PHYS + 0x0C00B000)
+#define DRM_BASE		(IO_PHYS + 0x0000D000)
+#define IOCFG_RT_BASE		(IO_PHYS + 0x02000000)
+#define IOCFG_RM1_BASE		(IO_PHYS + 0x02020000)
+#define IOCFG_RM2_BASE		(IO_PHYS + 0x02040000)
+#define IOCFG_RB_BASE		(IO_PHYS + 0x02060000)
+#define IOCFG_BM1_BASE		(IO_PHYS + 0x02820000)
+#define IOCFG_BM2_BASE		(IO_PHYS + 0x02840000)
+#define IOCFG_BM3_BASE		(IO_PHYS + 0x02860000)
+#define IOCFG_LT_BASE		(IO_PHYS + 0x03000000)
+#define IOCFG_LM1_BASE		(IO_PHYS + 0x03020000)
+#define IOCFG_LM2_BASE		(IO_PHYS + 0x03040000)
+#define IOCFG_LB1_BASE		(IO_PHYS + 0x030f0000)
+#define IOCFG_LB2_BASE		(IO_PHYS + 0x03110000)
+#define IOCFG_TM1_BASE		(IO_PHYS + 0x03800000)
+#define IOCFG_TM2_BASE		(IO_PHYS + 0x03820000)
+#define IOCFG_TM3_BASE		(IO_PHYS + 0x03860000)
+
+/*******************************************************************************
+ * UART related constants
+ ******************************************************************************/
+#define UART0_BASE	(IO_PHYS + 0x06000000)
+#define UART_BAUDRATE	(115200)
+
+/*******************************************************************************
+ * Infra IOMMU related constants
+ ******************************************************************************/
+#define INFRACFG_AO_BASE	(IO_PHYS + 0x00001000)
+#define INFRACFG_AO_MEM_BASE	(IO_PHYS + 0x00404000)
+#define PERICFG_AO_BASE		(IO_PHYS + 0x06630000)
+#define PERICFG_AO_REG_SIZE	(0x1000)
+
+/*******************************************************************************
+ * GIC-600 & interrupt handling related constants
+ ******************************************************************************/
+/* Base MTK_platform compatible GIC memory map */
+#define BASE_GICD_BASE		(MT_GIC_BASE)
+#define MT_GIC_RDIST_BASE	(MT_GIC_BASE + 0x40000)
+#define MTK_GIC_REG_SIZE	0x400000
+
+/*******************************************************************************
+ * MM IOMMU & SMI related constants
+ ******************************************************************************/
+#define SMI_LARB_0_BASE		(IO_PHYS + 0x0c022000)
+#define SMI_LARB_1_BASE		(IO_PHYS + 0x0c023000)
+#define SMI_LARB_2_BASE		(IO_PHYS + 0x0c102000)
+#define SMI_LARB_3_BASE		(IO_PHYS + 0x0c103000)
+#define SMI_LARB_4_BASE		(IO_PHYS + 0x04013000)
+#define SMI_LARB_5_BASE		(IO_PHYS + 0x04f02000)
+#define SMI_LARB_6_BASE		(IO_PHYS + 0x04f03000)
+#define SMI_LARB_7_BASE		(IO_PHYS + 0x04e04000)
+#define SMI_LARB_9_BASE		(IO_PHYS + 0x05001000)
+#define SMI_LARB_10_BASE	(IO_PHYS + 0x05120000)
+#define SMI_LARB_11A_BASE	(IO_PHYS + 0x05230000)
+#define SMI_LARB_11B_BASE	(IO_PHYS + 0x05530000)
+#define SMI_LARB_11C_BASE	(IO_PHYS + 0x05630000)
+#define SMI_LARB_12_BASE	(IO_PHYS + 0x05340000)
+#define SMI_LARB_13_BASE	(IO_PHYS + 0x06001000)
+#define SMI_LARB_14_BASE	(IO_PHYS + 0x06002000)
+#define SMI_LARB_15_BASE	(IO_PHYS + 0x05140000)
+#define SMI_LARB_16A_BASE	(IO_PHYS + 0x06008000)
+#define SMI_LARB_16B_BASE	(IO_PHYS + 0x0600a000)
+#define SMI_LARB_17A_BASE	(IO_PHYS + 0x06009000)
+#define SMI_LARB_17B_BASE	(IO_PHYS + 0x0600b000)
+#define SMI_LARB_19_BASE	(IO_PHYS + 0x0a010000)
+#define SMI_LARB_21_BASE	(IO_PHYS + 0x0802e000)
+#define SMI_LARB_23_BASE	(IO_PHYS + 0x0800d000)
+#define SMI_LARB_27_BASE	(IO_PHYS + 0x07201000)
+#define SMI_LARB_28_BASE	(IO_PHYS + 0x00000000)
+#define SMI_LARB_REG_RNG_SIZE	(0x1000)
+
+/*******************************************************************************
+ * APMIXEDSYS related constants
+ ******************************************************************************/
+#define APMIXEDSYS		(IO_PHYS + 0x0000C000)
+
+/*******************************************************************************
+ * VPPSYS related constants
+ ******************************************************************************/
+#define VPPSYS0_BASE		(IO_PHYS + 0x04000000)
+#define VPPSYS1_BASE		(IO_PHYS + 0x04f00000)
+
+/*******************************************************************************
+ * VDOSYS related constants
+ ******************************************************************************/
+#define VDOSYS0_BASE		(IO_PHYS + 0x0C01D000)
+#define VDOSYS1_BASE		(IO_PHYS + 0x0C100000)
+
+/*******************************************************************************
+ * EMI MPU related constants
+ *******************************************************************************/
+#define EMI_MPU_BASE		(IO_PHYS + 0x00428000)
+#define SUB_EMI_MPU_BASE	(IO_PHYS + 0x00528000)
+
+/*******************************************************************************
+ * System counter frequency related constants
+ ******************************************************************************/
+#define SYS_COUNTER_FREQ_IN_HZ	(13000000)
+#define SYS_COUNTER_FREQ_IN_MHZ	(13)
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+#define PLATFORM_STACK_SIZE		(0x800)
+#define SOC_CHIP_ID			U(0x8196)
+
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+#define TZRAM_BASE			(0x94600000)
+#define TZRAM_SIZE			(0x00200000)
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL3-1 at the top of the Trusted SRAM (just below the shared memory, if
+ * present). BL31_BASE is calculated using the current BL3-1 debug size plus a
+ * little space for growth.
+ */
+#define BL31_BASE			(TZRAM_BASE + 0x1000)
+#define BL31_LIMIT			(TZRAM_BASE + TZRAM_SIZE)
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 39)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 39)
+#define MAX_XLAT_TABLES			(128)
+#define MAX_MMAP_REGIONS		(512)
+
+/*******************************************************************************
+ * CPU PM definitions
+ *******************************************************************************/
+#define PLAT_CPU_PM_B_BUCK_ISO_ID	(6)
+#define PLAT_CPU_PM_ILDO_ID		(6)
+#define CPU_IDLE_SRAM_BASE		(0x11B000)
+#define CPU_IDLE_SRAM_SIZE		(0x1000)
+
+/*******************************************************************************
+ * SYSTIMER related definitions
+ ******************************************************************************/
+#define SYSTIMER_BASE		(0x1C400000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/mediatek/mt8196/plat_config.mk b/plat/mediatek/mt8196/plat_config.mk
new file mode 100644
index 0000000..dd83b9a
--- /dev/null
+++ b/plat/mediatek/mt8196/plat_config.mk
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Separate text code and read only data
+SEPARATE_CODE_AND_RODATA := 1
+
+# ARMv8.2 and above need enable HW assist coherence
+HW_ASSISTED_COHERENCY := 1
+
+# No need coherency memory because of HW assistency
+USE_COHERENT_MEM := 0
+
+# GIC600
+GICV3_SUPPORT_GIC600 := 1
+
+#
+# MTK options
+#
+PLAT_EXTRA_RODATA_INCLUDES := 1
+USE_PMIC_WRAP_INIT_V2 := 1
+
+# Configs for A78 and A55
+CTX_INCLUDE_AARCH32_REGS := 0
+
+CONFIG_ARCH_ARM_V9 := y
+CONFIG_MTK_MCUSYS := y
+MCUSYS_VERSION := v1
+CONFIG_MTK_PM_SUPPORT := y
+CONFIG_MTK_PM_ARCH := 9_0
+CONFIG_MTK_CPU_PM_SUPPORT := y
+CONFIG_MTK_CPU_PM_ARCH := 5_4
+CONFIG_MTK_SMP_EN := n
+CONFIG_MTK_CPU_SUSPEND_EN := y
+CONFIG_MTK_SPM_VERSION := mt8196
+CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND := y
+CPU_PM_TINYSYS_SUPPORT := y
+MTK_PUBEVENT_ENABLE := y
+
+ENABLE_FEAT_AMU := 1
+ENABLE_FEAT_ECV := 1
+ENABLE_FEAT_FGT := 1
+ENABLE_FEAT_HCX := 1
+ENABLE_SVE_FOR_SWD := 1
diff --git a/plat/mediatek/mt8196/plat_mmap.c b/plat/mediatek/mt8196/plat_mmap.c
new file mode 100644
index 0000000..f7f819a
--- /dev/null
+++ b/plat/mediatek/mt8196/plat_mmap.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <platform_def.h>
+
+#include <mtk_mmap_pool.h>
+
+static const mmap_region_t plat_mmap[] = {
+	MAP_REGION_FLAT(MT_GIC_BASE, MTK_GIC_REG_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(MTK_DEV_RNG1_BASE, MTK_DEV_RNG1_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(CPU_IDLE_SRAM_BASE, CPU_IDLE_SRAM_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	{ 0 }
+};
+DECLARE_MTK_MMAP_REGIONS(plat_mmap);
diff --git a/plat/mediatek/mt8196/platform.mk b/plat/mediatek/mt8196/platform.mk
new file mode 100644
index 0000000..fede717
--- /dev/null
+++ b/plat/mediatek/mt8196/platform.mk
@@ -0,0 +1,56 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+MTK_PLAT := plat/mediatek
+MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
+MTK_SOC := ${PLAT}
+ARM_ARCH_MAJOR := 9
+
+include plat/mediatek/build_helpers/mtk_build_helpers.mk
+include drivers/arm/gic/v3/gicv3.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+
+PLAT_INCLUDES := -I${MTK_PLAT}/common \
+                 -I${MTK_PLAT}/drivers/gpio/ \
+		 -I${MTK_PLAT}/include \
+		 -I${MTK_PLAT}/include/${ARCH_VERSION} \
+		 -I${MTK_PLAT} \
+		 -I${MTK_PLAT_SOC}/drivers/gpio/ \
+		 -I${MTK_PLAT_SOC}/include \
+		 -Idrivers/arm/gic \
+
+MODULES-y += $(MTK_PLAT)/common
+MODULES-y += $(MTK_PLAT)/lib/mtk_init
+MODULES-y += $(MTK_PLAT)/lib/pm
+MODULES-y += $(MTK_PLAT)/drivers/mcusys
+MODULES-y += $(MTK_PLAT)/drivers/timer
+MODULES-y += $(MTK_PLAT)/helpers
+MODULES-y += $(MTK_PLAT)/topology
+
+PLAT_BL_COMMON_SOURCES := common/desc_image_load.c \
+			  drivers/ti/uart/aarch64/16550_console.S \
+			  lib/bl_aux_params/bl_aux_params.c
+
+BL31_SOURCES += drivers/delay_timer/delay_timer.c \
+		drivers/delay_timer/generic_delay_timer.c \
+		drivers/gpio/gpio.c \
+		lib/cpus/aarch64/cortex_a720.S	\
+		lib/cpus/aarch64/cortex_x4.S	\
+		lib/cpus/aarch64/cortex_x925.S \
+		${GICV3_SOURCES} \
+		${XLAT_TABLES_LIB_SRCS} \
+		plat/common/plat_gicv3.c \
+		plat/common/plat_psci_common.c \
+		plat/common/aarch64/crash_console_helpers.S \
+		${MTK_PLAT}/common/mtk_plat_common.c \
+		${MTK_PLAT}/common/params_setup.c \
+                ${MTK_PLAT}/drivers/gpio/mtgpio_common.c \
+                $(MTK_PLAT)/$(MTK_SOC)/drivers/gpio/mtgpio.c \
+		$(MTK_PLAT)/$(MTK_SOC)/plat_mmap.c
+
+include plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
+
+include lib/coreboot/coreboot.mk
diff --git a/plat/mediatek/topology/armv9/topology.c b/plat/mediatek/topology/armv9/topology.c
new file mode 100644
index 0000000..d6ecc83
--- /dev/null
+++ b/plat/mediatek/topology/armv9/topology.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <lib/psci/psci.h>
+#include <platform_def.h>
+
+#pragma weak plat_get_power_domain_tree_desc
+
+static const unsigned char mtk_power_domain_tree_desc[] = {
+	/* Number of root nodes */
+	PLATFORM_SYSTEM_COUNT,
+	/* Number of children for the root node */
+	PLATFORM_CLUSTER_COUNT,
+	/* Number of children for the first cluster node */
+	PLATFORM_CLUSTER0_CORE_COUNT
+};
+
+/*******************************************************************************
+ * This function returns the default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return mtk_power_domain_tree_desc;
+}
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index 4813949..c19eb36 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -148,6 +148,13 @@
 endif
 $(eval $(call add_define,RCAR_RPC_HYPERFLASH_LOCKED))
 
+# Support A/B switching with RPC HYPERFLASH access by default
+# Use together with https://github.com/marex/abloader .
+ifndef RCAR_RPC_HYPERFLASH_ABLOADER
+RCAR_RPC_HYPERFLASH_ABLOADER := 0
+endif
+$(eval $(call add_define,RCAR_RPC_HYPERFLASH_ABLOADER))
+
 # Process RCAR_SECURE_BOOT flag
 ifndef RCAR_SECURE_BOOT
 RCAR_SECURE_BOOT := 1
diff --git a/plat/rpi/common/include/rpi_shared.h b/plat/rpi/common/include/rpi_shared.h
index 8562c3d..d22fc64 100644
--- a/plat/rpi/common/include/rpi_shared.h
+++ b/plat/rpi/common/include/rpi_shared.h
@@ -52,4 +52,4 @@
 
 void plat_rpi_bl31_custom_setup(void);
 
-#endif /* RPI3_PRIVATE_H */
+#endif /* RPI3_SHARED_H */
diff --git a/plat/rpi/common/rpi3_common.c b/plat/rpi/common/rpi3_common.c
index 8976496..4e3c9f2 100644
--- a/plat/rpi/common/rpi3_common.c
+++ b/plat/rpi/common/rpi3_common.c
@@ -14,6 +14,7 @@
 #include <bl31/interrupt_mgmt.h>
 #include <drivers/console.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
 
 #include <rpi_hw.h>
 #include <rpi_shared.h>
@@ -225,3 +226,10 @@
 	/* Secure interrupts are signalled on the FIQ line always. */
 	return  __builtin_ctz(SCR_FIQ_BIT);
 }
+
+#if MEASURED_BOOT || TRUSTED_BOARD_BOOT
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
+#endif
diff --git a/plat/rpi/common/rpi3_trusted_boot.c b/plat/rpi/common/rpi3_trusted_boot.c
index f6c669f..86a70d6 100644
--- a/plat/rpi/common/rpi3_trusted_boot.c
+++ b/plat/rpi/common/rpi3_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,8 +29,3 @@
 {
 	return 1;
 }
-
-int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
-{
-	return get_mbedtls_heap_helper(heap_addr, heap_size);
-}
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index 190c096..4fc0add 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -17,6 +17,7 @@
 #include <openssl/engine.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
+#include <openssl/ssl.h>
 
 #include "cert.h"
 #include "cmd_opt.h"
@@ -214,6 +215,13 @@
 	EVP_PKEY *pkey;
 	ENGINE *e;
 
+#if !USING_OPENSSL3
+	if (!OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL)) {
+		fprintf(stderr, "Failed to init SSL\n");
+		return NULL;
+	}
+#endif
+
 	ENGINE_load_builtin_engines();
 	e = ENGINE_by_id("pkcs11");
 	if (!e) {
diff --git a/tools/renesas/rcar_layout_create/makefile b/tools/renesas/rcar_layout_create/makefile
index 7a64b19..f89f379 100644
--- a/tools/renesas/rcar_layout_create/makefile
+++ b/tools/renesas/rcar_layout_create/makefile
@@ -102,7 +102,7 @@
 	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).bin
 
 $(OUTPUT_FILE_SA0): $(MEMORY_DEF_SA0) $(OBJ_FILE_SA0) | $$(@D)/
-	$(aarch64-ld) $(OBJ_FILE_SA0) -nostdlib -T $(MEMORY_DEF_SA0) -o $(OUTPUT_FILE_SA0) -Wl,-Map $(FILE_NAME_SA0).map
+	$(aarch64-ld) $(OBJ_FILE_SA0) -nostdlib -static -Wl,--build-id=none -T $(MEMORY_DEF_SA0) -o $(OUTPUT_FILE_SA0) -Wl,-Map $(FILE_NAME_SA0).map
 
 $(FILE_NAME_SA6).srec: $(OUTPUT_FILE_SA6) | $$(@D)/
 	$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).srec
@@ -111,7 +111,7 @@
 	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).bin
 
 $(OUTPUT_FILE_SA6): $(MEMORY_DEF_SA6) $(OBJ_FILE_SA6) | $$(@D)/
-	$(aarch64-ld) $(OBJ_FILE_SA6) -nostdlib -T $(MEMORY_DEF_SA6) -o $(OUTPUT_FILE_SA6) -Wl,-Map $(FILE_NAME_SA6).map
+	$(aarch64-ld) $(OBJ_FILE_SA6) -nostdlib -static -Wl,--build-id=none -T $(MEMORY_DEF_SA6) -o $(OUTPUT_FILE_SA6) -Wl,-Map $(FILE_NAME_SA6).map
 
 ###################################################
 # Compile