refactor(mediatek): update EMI stub implementation

Refactor EMI stub implementation with following changes.
- Move the SiP call handlers to TF-A upstream.
- Move EMI definition used by APUSYS to platform_def.h.
- Remove CONFIG_MTK_APUSYS_EMI_SUPPORT.

Change-Id: I30e1ee7f2ea2d6dc3415adba91cbe310af9b5eeb
Signed-off-by: Yidi Lin <yidilin@chromium.org>
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c
index a0d21c6..6edf9c6 100644
--- a/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c
@@ -6,14 +6,11 @@
 
 #define ENABLE_SMPU_PROTECT	(1)
 
-#if ENABLE_SMPU_PROTECT
-#include "emi.h"
-#endif
-
 #include <common/debug.h>
 #include <lib/mmio.h>
 
 #include <apusys_security_ctrl_plat.h>
+#include <mtk_bl31_interface.h>
 
 #define APUSYS_SEC_FW_EMI_REGION	(23)
 
@@ -71,9 +68,10 @@
 int apusys_plat_setup_sec_mem(void)
 {
 #if ENABLE_SMPU_PROTECT
-	return sip_emi_mpu_set_protection(APU_RESERVE_MEMORY >> EMI_MPU_ALIGN_BITS,
-		(APU_RESERVE_MEMORY + APU_RESERVE_SIZE) >> EMI_MPU_ALIGN_BITS,
-		APUSYS_SEC_FW_EMI_REGION);
+	return emi_mpu_set_protection(APU_RESERVE_MEMORY >> EMI_MPU_ALIGN_BITS,
+				      (APU_RESERVE_MEMORY + APU_RESERVE_SIZE) >>
+				      EMI_MPU_ALIGN_BITS,
+				      APUSYS_SEC_FW_EMI_REGION);
 #else
 	INFO("%s: Bypass SMPU protection setup.\n", __func__);
 	return 0;
diff --git a/plat/mediatek/drivers/apusys/mt8196/rules.mk b/plat/mediatek/drivers/apusys/mt8196/rules.mk
index aeb6d3d..67243da 100644
--- a/plat/mediatek/drivers/apusys/mt8196/rules.mk
+++ b/plat/mediatek/drivers/apusys/mt8196/rules.mk
@@ -8,10 +8,6 @@
 
 MODULE := apusys_${MTK_SOC}
 
-ifeq (${CONFIG_MTK_APUSYS_EMI_SUPPORT}, y)
-PLAT_INCLUDES += -I${MTK_PLAT}/drivers/emi/common
-endif
-
 LOCAL_SRCS-y := ${LOCAL_DIR}/apusys_ammu.c
 LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_devapc.c
 LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_power.c
diff --git a/plat/mediatek/drivers/apusys/rules.mk b/plat/mediatek/drivers/apusys/rules.mk
index 24cc79c..f487c11 100644
--- a/plat/mediatek/drivers/apusys/rules.mk
+++ b/plat/mediatek/drivers/apusys/rules.mk
@@ -13,7 +13,6 @@
 PLAT_INCLUDES += -I${LOCAL_DIR} -I${LOCAL_DIR}/${MTK_SOC} -I${LOCAL_DIR}/apusys_rv/2.0
 
 $(eval $(call add_defined_option,CONFIG_MTK_APUSYS_CE_SUPPORT))
-$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_EMI_SUPPORT))
 $(eval $(call add_defined_option,CONFIG_MTK_APUSYS_LOGTOP_SUPPORT))
 $(eval $(call add_defined_option,CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT))
 $(eval $(call add_defined_option,CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT))
diff --git a/plat/mediatek/drivers/emi/common/emi.h b/plat/mediatek/drivers/emi/common/emi.h
deleted file mode 100644
index eb2a0d3..0000000
--- a/plat/mediatek/drivers/emi/common/emi.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright (c) 2025, Mediatek Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef EMI_H
-#define EMI_H
-
-#include <stdint.h>
-
-#define EMI_MPU_ALIGN_BITS	12
-
-uint64_t sip_emi_mpu_set_protection(u_register_t start, u_register_t end, u_register_t region);
-
-#endif /* EMI_H */
diff --git a/plat/mediatek/drivers/emi/emi_ctrl.c b/plat/mediatek/drivers/emi/emi_ctrl.c
new file mode 100644
index 0000000..00ac7df
--- /dev/null
+++ b/plat/mediatek/drivers/emi/emi_ctrl.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+
+#include <lib/mtk_init/mtk_init.h>
+#include <mtk_bl31_interface.h>
+#include <mtk_sip_svc.h>
+
+#define NO_PROTECTION	0
+#define SEC_RW		1
+#define SEC_RW_NSEC_R	2
+#define SEC_RW_NSEC_W	3
+#define SEC_R_NSEC_R	4
+#define FORBIDDEN	5
+#define SEC_R_NSEC_RW	6
+
+#define EMIMPU_SET	0
+#define EMIMPU_CLEAR	1
+#define EMIMPU_READ	2
+#define EMIMPU_SLVERR	3
+#define EMIDBG_DUMP	4
+#define EMIDBG_MSG	5
+#define AID_TABLE_SET	6
+#define EMIMPU_CLEAR_MD	7
+#define KP_SET		8
+#define KP_CLEAR	9
+
+#define EMIMPU_READ_SA			0
+#define EMIMPU_READ_EA			1
+#define EMIMPU_READ_APC			2
+#define EMIMPU_READ_ENABLE		3
+#define EMIMPU_READ_AID			4
+#define EMIMPU_CHECK_NS_CPU		5
+#define EMIMPU_CHECK_REGION_INFO	6
+#define EMIMPU_PAGE_BASE_REGION		7
+#define SLBMPU_CLEAR			8
+#define EMIMPU_CHECK_HP_MOD		9
+#define EMI_CLE				10
+#define SLC_PARITY_SELECT		11
+#define SLC_PARITY_CLEAR		12
+
+static uint64_t emi_mpu_read_by_type(unsigned int reg_type, unsigned int region,
+				     unsigned int aid_shift, struct smccc_res *smccc_ret)
+{
+	switch (reg_type) {
+	case EMIMPU_READ_SA:
+		return emi_mpu_read_addr(region, 0x0);
+	case EMIMPU_READ_EA:
+		return emi_mpu_read_addr(region, 0x8);
+	case EMIMPU_READ_ENABLE:
+		return emi_mpu_read_enable(region);
+	case EMIMPU_READ_AID:
+		return emi_mpu_read_aid(region, aid_shift);
+	case EMIMPU_CHECK_REGION_INFO:
+		return emi_mpu_check_region_info(region, &smccc_ret->a1, &smccc_ret->a2);
+	case EMIMPU_CHECK_NS_CPU:
+		return emi_mpu_check_ns_cpu();
+	case EMIMPU_PAGE_BASE_REGION:
+		return emi_mpu_page_base_region();
+	case EMIMPU_CHECK_HP_MOD:
+		return emi_mpu_smc_hp_mod_check();
+	default:
+		return 0;
+	}
+}
+
+static u_register_t sip_emidbg_control(u_register_t op_id,
+				       u_register_t x2,
+				       u_register_t x3,
+				       u_register_t x4,
+				       void *handle,
+				       struct smccc_res *smccc_ret)
+{
+	enum mtk_bl31_status ret;
+
+	switch (op_id) {
+	case EMIDBG_DUMP:
+		return MTK_SIP_E_SUCCESS;
+	case EMIDBG_MSG:
+		return MTK_SIP_E_SUCCESS;
+#ifdef MTK_EMI_MPU_DEBUG
+	case EMIMPU_READ:
+		ret = emi_mpu_read_by_type((unsigned int)x2, (unsigned int)x3,
+					   (unsigned int)x4, smccc_ret);
+		break;
+#endif
+	case EMIMPU_CLEAR_MD:
+		ret = emi_clear_md_violation();
+		break;
+	case KP_CLEAR:
+		ret = emi_kp_clear_violation((unsigned int)x2);
+		break;
+#ifdef CONFIG_MTK_SLB_MPU_CLEAR
+	case SLBMPU_CLEAR:
+		ret = slb_clear_violation((unsigned int)x2);
+		break;
+#endif
+#ifdef CONFIG_MTK_EMI_CLEAR
+	case EMI_CLEAR:
+		ret = emi_clear_violation((unsigned int)x2, (unsigned int)x3);
+		break;
+#endif
+#ifdef CONFIG_MTK_SLC_PARITY
+	case SLC_PARITY_SELECT:
+		ret = slc_parity_select((unsigned int)x2, (unsigned int)x3);
+		break;
+	case SLC_PARITY_CLEAR:
+		ret = slc_parity_clear((unsigned int)x2);
+		break;
+#endif
+	default:
+		return MTK_SIP_E_NOT_SUPPORTED;
+	}
+
+	return mtk_bl31_map_to_sip_error(ret);
+}
+DECLARE_SMC_HANDLER(MTK_SIP_EMIDBG_CONTROL, sip_emidbg_control);
+
+static u_register_t sip_emimpu_control(u_register_t op_id,
+				       u_register_t x2,
+				       u_register_t x3,
+				       u_register_t x4,
+				       void *handle,
+				       struct smccc_res *smccc_ret)
+{
+	enum mtk_bl31_status ret;
+
+	switch (op_id) {
+	case EMIMPU_SET:
+		ret = emi_mpu_set_protection((uint32_t)x2, (uint32_t)x3, (unsigned int)x4);
+		break;
+	case AID_TABLE_SET:
+		ret = emi_mpu_set_aid((unsigned int)x2, (unsigned int)x3);
+		break;
+	case EMIMPU_READ:
+		ret = emi_mpu_read_by_type((unsigned int)x2, (unsigned int)x3,
+					   (unsigned int)x4, smccc_ret);
+		break;
+	case KP_SET:
+		ret = emi_kp_set_protection((size_t)x2, (size_t)x3, (unsigned int)x4);
+		break;
+	case KP_CLEAR:
+		ret = emi_kp_clear_violation((unsigned int)x2);
+		break;
+	default:
+		return MTK_SIP_E_NOT_SUPPORTED;
+	}
+
+	return mtk_bl31_map_to_sip_error(ret);
+}
+DECLARE_SMC_HANDLER(MTK_SIP_BL_EMIMPU_CONTROL, sip_emimpu_control);
+
+static u_register_t sip_tee_emimpu_control(u_register_t op_id,
+					   u_register_t x2,
+					   u_register_t x3,
+					   u_register_t x4,
+					   void *handle,
+					   struct smccc_res *smccc_ret)
+{
+	enum mtk_bl31_status ret;
+
+	switch (op_id) {
+	case EMIMPU_SET:
+		ret = emi_mpu_set_protection((uint32_t)x2, (uint32_t)x3, (unsigned int)x4);
+		break;
+	case EMIMPU_CLEAR:
+		ret = emi_clear_protection((unsigned int)x2);
+		break;
+	default:
+		return MTK_SIP_E_NOT_SUPPORTED;
+	}
+
+	return mtk_bl31_map_to_sip_error(ret);
+}
+DECLARE_SMC_HANDLER(MTK_SIP_TEE_EMI_MPU_CONTROL, sip_tee_emimpu_control);
+
+int emi_mpu_init(void)
+{
+	INFO("[%s] emi mpu initialization\n", __func__);
+
+	emi_protection_init();
+
+	return 0;
+}
+MTK_PLAT_SETUP_0_INIT(emi_mpu_init);
diff --git a/plat/mediatek/drivers/emi/emi_stub.c b/plat/mediatek/drivers/emi/emi_stub.c
index 3682bf7..abe559a 100644
--- a/plat/mediatek/drivers/emi/emi_stub.c
+++ b/plat/mediatek/drivers/emi/emi_stub.c
@@ -3,13 +3,95 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#include <common/debug.h>
 
-#include "common/emi.h"
-#include <mtk_sip_svc.h>
+#include <mtk_bl31_interface.h>
 
-uint64_t sip_emi_mpu_set_protection(u_register_t start, u_register_t end,
-				    u_register_t region)
+uint64_t emi_mpu_read_addr(unsigned int region, unsigned int offset)
+{
+	return 0;
+}
+
+uint64_t emi_mpu_read_enable(unsigned int region)
+{
+	return 0;
+}
+
+uint64_t emi_mpu_read_aid(unsigned int region, unsigned int aid_shift)
+{
+	return 0;
+}
+
+uint64_t emi_mpu_check_ns_cpu(void)
+{
+	return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+enum mtk_bl31_status emi_kp_set_protection(size_t start, size_t end, unsigned int region)
+{
+	return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+enum mtk_bl31_status emi_kp_clear_violation(unsigned int emiid)
+{
+	return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+enum mtk_bl31_status emi_clear_protection(unsigned int region)
+{
+	return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+enum mtk_bl31_status emi_clear_md_violation(void)
+{
+	return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+uint64_t emi_mpu_check_region_info(unsigned int region, uint64_t *sa, uint64_t *ea)
+{
+	return 0;
+}
+
+uint64_t emi_mpu_page_base_region(void)
+{
+	return 0;
+}
+
+uint64_t emi_mpu_smc_hp_mod_check(void)
+{
+	return 0;
+}
+
+enum mtk_bl31_status slb_clear_violation(unsigned int id)
+{
+	return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+enum mtk_bl31_status emi_clear_violation(unsigned int id, unsigned int type)
+{
+	return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+enum mtk_bl31_status slc_parity_select(unsigned int id, unsigned int port)
+{
+	return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+enum mtk_bl31_status slc_parity_clear(unsigned int id)
+{
+	return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+enum mtk_bl31_status emi_mpu_set_aid(unsigned int region, unsigned int num)
+{
+	return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+void emi_protection_init(void)
+{
+}
+
+enum mtk_bl31_status emi_mpu_set_protection(uint32_t start, uint32_t end,
+					    unsigned int region)
 {
-	return MTK_SIP_E_NOT_SUPPORTED;
+	return MTK_BL31_STATUS_NOT_SUPPORTED;
 }
diff --git a/plat/mediatek/drivers/emi/rules.mk b/plat/mediatek/drivers/emi/rules.mk
index 9f462bb..ffe1817 100644
--- a/plat/mediatek/drivers/emi/rules.mk
+++ b/plat/mediatek/drivers/emi/rules.mk
@@ -8,8 +8,9 @@
 
 MODULE := emi
 
+LOCAL_SRCS-y := $(LOCAL_DIR)/emi_ctrl.c
 ifeq ($(MTKLIB_PATH),)
-LOCAL_SRCS-y := $(LOCAL_DIR)/emi_stub.c
+LOCAL_SRCS-y += $(LOCAL_DIR)/emi_stub.c
 endif
 
 $(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/include/mtk_bl31_interface.h b/plat/mediatek/include/mtk_bl31_interface.h
index e124cfe..2216553 100644
--- a/plat/mediatek/include/mtk_bl31_interface.h
+++ b/plat/mediatek/include/mtk_bl31_interface.h
@@ -8,6 +8,7 @@
 #define __MTK_BL31_INTERFACE_H__
 
 #include <stdbool.h>
+#include <stddef.h>
 #include <stdint.h>
 
 enum mtk_bl31_status {
@@ -59,4 +60,25 @@
 bool ufs_is_clk_status_off(void);
 void ufs_set_clk_status(bool on);
 
+/* EMI interfaces */
+uint64_t emi_mpu_read_addr(unsigned int region, unsigned int offset);
+uint64_t emi_mpu_read_enable(unsigned int region);
+uint64_t emi_mpu_read_aid(unsigned int region, unsigned int aid_shift);
+uint64_t emi_mpu_check_ns_cpu(void);
+enum mtk_bl31_status emi_mpu_set_protection(uint32_t start, uint32_t end,
+					    unsigned int region);
+enum mtk_bl31_status emi_kp_set_protection(size_t start, size_t end, unsigned int region);
+enum mtk_bl31_status emi_kp_clear_violation(unsigned int emiid);
+enum mtk_bl31_status emi_clear_protection(unsigned int region);
+enum mtk_bl31_status emi_clear_md_violation(void);
+uint64_t emi_mpu_check_region_info(unsigned int region, uint64_t *sa, uint64_t *ea);
+uint64_t emi_mpu_page_base_region(void);
+uint64_t emi_mpu_smc_hp_mod_check(void);
+enum mtk_bl31_status slb_clear_violation(unsigned int id);
+enum mtk_bl31_status emi_clear_violation(unsigned int id, unsigned int type);
+enum mtk_bl31_status slc_parity_select(unsigned int id, unsigned int port);
+enum mtk_bl31_status slc_parity_clear(unsigned int id);
+enum mtk_bl31_status emi_mpu_set_aid(unsigned int region, unsigned int num);
+void emi_protection_init(void);
+
 #endif /* __MTK_BL31_INTERFACE_H__ */
diff --git a/plat/mediatek/mt8196/include/platform_def.h b/plat/mediatek/mt8196/include/platform_def.h
index ad0bf68..fb5212a 100644
--- a/plat/mediatek/mt8196/include/platform_def.h
+++ b/plat/mediatek/mt8196/include/platform_def.h
@@ -230,6 +230,7 @@
 #define SUB_EMI_APB_BASE		(IO_PHYS + 0x00529000)
 #define SUB_INFRA_EMI_DEBUG_CFG_BASE	(IO_PHYS + 0x00525000)
 #define SUB_INFRACFG_AO_MEM_BASE	(IO_PHYS + 0x00504000)
+#define EMI_MPU_ALIGN_BITS		12
 
 /*******************************************************************************
  * System counter frequency related constants
diff --git a/plat/mediatek/mt8196/plat_config.mk b/plat/mediatek/mt8196/plat_config.mk
index 7412756..35a3901 100644
--- a/plat/mediatek/mt8196/plat_config.mk
+++ b/plat/mediatek/mt8196/plat_config.mk
@@ -27,7 +27,6 @@
 
 CONFIG_ARCH_ARM_V9 := y
 CONFIG_MTK_APUSYS_CE_SUPPORT := y
-CONFIG_MTK_APUSYS_EMI_SUPPORT := y
 CONFIG_MTK_APUSYS_LOGTOP_SUPPORT := y
 CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT := y
 CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT := y