feat(mt8196): add APUMMU setting
APUMMU is the MMU in APU, which is responsible for inner address
mapping. The APU kernel driver will setup the APUMMU by SMC call.
Change-Id: Iad7532883e42c288aeb0d23ab419f4dc6d8630f2
diff --git a/plat/mediatek/drivers/apusys/apusys.c b/plat/mediatek/drivers/apusys/apusys.c
index dfe1dcf..ee4fe5a 100644
--- a/plat/mediatek/drivers/apusys/apusys.c
+++ b/plat/mediatek/drivers/apusys/apusys.c
@@ -68,6 +68,9 @@
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING:
ret = apusys_kernel_apusys_rv_cg_ungating();
break;
+ case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_APUMMU:
+ ret = apusys_kernel_apusys_rv_setup_apummu();
+ break;
default:
ERROR(MODULE_TAG "%s unknown request_ops = %x\n", MODULE_TAG, request_ops);
break;
diff --git a/plat/mediatek/drivers/apusys/apusys.h b/plat/mediatek/drivers/apusys/apusys.h
index ed4e195..2def47d 100644
--- a/plat/mediatek/drivers/apusys/apusys.h
+++ b/plat/mediatek/drivers/apusys/apusys.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,6 +23,7 @@
MTK_APUSYS_KERNEL_OP_APUSYS_RV_CLEAR_WDT_ISR, /* 10 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_GATING, /* 11 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING, /* 12 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_APUMMU, /* 13 */
MTK_APUSYS_KERNEL_OP_NUM,
};
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
index f18a1a7..f8059ba 100644
--- a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
+++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
@@ -17,6 +17,10 @@
#include "apusys_rv_pwr_ctrl.h"
#include "emi_mpu.h"
+#ifdef CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT
+#include "apusys_ammu.h"
+#endif
+
static spinlock_t apusys_rv_lock;
void apusys_rv_mbox_mpu_init(void)
@@ -166,5 +170,39 @@
mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN);
spin_unlock(&apusys_rv_lock);
+ return 0;
+}
+
+int apusys_kernel_apusys_rv_setup_apummu(void)
+{
+ spin_lock(&apusys_rv_lock);
+
+#ifdef CONFIG_MTK_APUSYS_SEC_CTRL
+ sec_set_rv_dns();
+#endif
+
+#ifdef CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT
+ uint32_t apummu_tcm_sz_select = 0;
+
+ if (APU_MD32_TCM_SZ <= 0x20000)
+ apummu_tcm_sz_select = APUMMU_PAGE_LEN_128KB;
+ else if (APU_MD32_TCM_SZ <= 0x40000)
+ apummu_tcm_sz_select = APUMMU_PAGE_LEN_256KB;
+ else if (APU_MD32_TCM_SZ <= 0x80000)
+ apummu_tcm_sz_select = APUMMU_PAGE_LEN_512KB;
+ else if (APU_MD32_TCM_SZ <= 0x100000)
+ apummu_tcm_sz_select = APUMMU_PAGE_LEN_1MB;
+ else {
+ ERROR("%s: APU_MD32_TCM_SZ = 0x%x > 1MB", __func__, APU_MD32_TCM_SZ);
+ spin_unlock(&apusys_rv_lock);
+ return -EINVAL;
+ }
+
+ INFO("%s: apummu_tcm_sz_select = %u\n", __func__, apummu_tcm_sz_select);
+ rv_boot(APU_SEC_FW_IOVA, 0, APUMMU_PAGE_LEN_1MB,
+ APU_MD32_TCM, apummu_tcm_sz_select);
+#endif
+
+ spin_unlock(&apusys_rv_lock);
return 0;
}
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h
index 0a59319..b57fc4d 100644
--- a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h
+++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h
@@ -99,5 +99,6 @@
int apusys_kernel_apusys_rv_clear_wdt_isr(void);
int apusys_kernel_apusys_rv_cg_gating(void);
int apusys_kernel_apusys_rv_cg_ungating(void);
+int apusys_kernel_apusys_rv_setup_apummu(void);
#endif /* APUSYS_RV_H */
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.c b/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.c
new file mode 100644
index 0000000..fa1cd2c
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <errno.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+#include "apusys_ammu.h"
+#include <apusys_security_ctrl_perm.h>
+#include <mtk_mmap_pool.h>
+
+static void apummu_set_segment_offset0(uint32_t vsid_idx, uint8_t seg_idx, uint32_t input_adr,
+ uint8_t res_bits, uint8_t page_sel, uint8_t page_len)
+{
+ mmio_write_32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, APUMMU_SEG_OFFSET_0),
+ APUMMU_BUILD_SEGMENT_OFFSET0(input_adr, res_bits, page_sel, page_len));
+}
+
+static void apummu_set_segment_offset1(uint32_t vsid_idx, uint8_t seg_idx, uint32_t output_adr,
+ uint8_t res0, uint8_t iommu_en, uint8_t res1)
+{
+ mmio_write_32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, APUMMU_SEG_OFFSET_1),
+ APUMMU_BUILD_SEGMENT_OFFSET1(output_adr, res0, iommu_en, res1));
+}
+
+static void apummu_set_segment_offset2(uint32_t vsid_idx, uint8_t seg_idx, uint8_t resv,
+ uint8_t domain, uint8_t acp_en, uint8_t aw_clr,
+ uint8_t aw_invalid, uint8_t ar_exclu, uint8_t ar_sepcu,
+ uint8_t aw_cache_allocate, uint8_t aw_slc_en,
+ uint8_t aw_slb_en, uint8_t ar_cache_allocate,
+ uint8_t ar_slc_en, uint8_t ar_slb_en, uint8_t ro,
+ uint8_t ns)
+{
+ mmio_write_32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, APUMMU_SEG_OFFSET_2),
+ APUMMU_BUILD_SEGMENT_OFFSET2(resv, domain, acp_en, aw_clr, aw_invalid,
+ ar_exclu, ar_sepcu, aw_cache_allocate,
+ aw_slc_en, aw_slb_en, ar_cache_allocate,
+ ar_slc_en, ar_slb_en, ro, ns));
+}
+
+static void apummu_vsid_segment_enable_init(uint8_t vsid_idx)
+{
+ mmio_write_32(APUMMU_VSID_SEGMENT_ENABLE(vsid_idx), 0);
+}
+
+static void apummu_set_single_segment(uint8_t vsid_idx, uint8_t seg_idx)
+{
+ mmio_setbits_32(APUMMU_VSID_SEGMENT_ENABLE(vsid_idx), BIT(seg_idx));
+}
+
+static int apummu_enable_vsid(uint32_t vsid_idx)
+{
+ if (vsid_idx > (APUMMU_VSID_ACTIVE - 1) &&
+ vsid_idx < (APUMMU_RSV_VSID_IDX_END - APUMMU_VSID_RSV + 1)) {
+ ERROR("invalid vsid index %d\n", vsid_idx);
+ return -1;
+ }
+
+ mmio_write_32(APUMMU_VSID_ENABLE_BASE(vsid_idx), BIT(vsid_idx & APUMMU_VSID_EN_MASK));
+ mmio_write_32(APUMMU_VSID_VALID_BASE(vsid_idx), BIT(vsid_idx & APUMMU_VSID_EN_MASK));
+
+ return 0;
+}
+
+static void apummu_enable(void)
+{
+ mmio_setbits_32(APUMMU_CMU_TOP_BASE, 0x1);
+}
+
+static void apummu_vsid_sram_config(void)
+{
+ uint32_t idx;
+ uint32_t base = (APUMMU_VSID_SRAM_TOTAL - APUMMU_VSID_RSV);
+
+ for (idx = 0; idx < APUMMU_VSID_RSV; idx++) {
+ mmio_write_32(APUMMU_VSID(APUMMU_RSV_VSID_IDX_START + idx),
+ APUMMU_VSID_DESC(base + idx));
+ apummu_vsid_segment_enable_init(base + idx);
+ }
+}
+
+static void apummu_bind_vsid(uint32_t tcu_base, uint32_t vsid_idx, uint8_t cor_id,
+ uint8_t hw_thread, uint8_t cor_valid, uint8_t vsid_valid)
+{
+ mmio_write_32((tcu_base + hw_thread * VSID_THREAD_SZ),
+ (((cor_id & VSID_CORID_MASK) << VSID_CORID_OFF) |
+ ((vsid_idx & VSID_IDX_MASK) << VSID_IDX_OFF) |
+ ((cor_valid & VSID_VALID_MASK) << VSID_COR_VALID_OFF) |
+ ((vsid_valid & VSID_VALID_MASK) << VSID_VALID_OFF)));
+}
+
+static int apummu_rv_bind_vsid(uint8_t hw_thread)
+{
+ uint8_t cor_id = 0, cor_valid = 0, vsid_valid = 1;
+
+ if (hw_thread > APUMMU_HW_THREAD_MAX) {
+ ERROR("%s: the hw thread id (%d) is not valid for rv/logger\n", __func__,
+ hw_thread);
+ return -EINVAL;
+ }
+
+ apummu_bind_vsid(APUMMU_RCX_UPRV_TCU_BASE, APUMMU_UPRV_RSV_VSID, cor_id, hw_thread,
+ cor_valid, vsid_valid);
+
+ return 0;
+}
+
+static int apummu_apmcu_bind_vsid(uint8_t hw_thread)
+{
+ uint8_t cor_id = 0, cor_valid = 0, vsid_valid = 1;
+
+ if (hw_thread > APUMMU_HW_THREAD_MAX) {
+ ERROR("%s: the hw thread id (%d) is not valid for apmcu\n", __func__, hw_thread);
+ return -EINVAL;
+ }
+
+ apummu_bind_vsid(APUMMU_RCX_EXTM_TCU_BASE, APUMMU_APMCU_RSV_VSID, cor_id, hw_thread,
+ cor_valid, vsid_valid);
+
+ return 0;
+}
+
+static int apummu_add_map(uint32_t vsid_idx, uint8_t seg_idx, uint64_t input_adr,
+ uint64_t output_adr, uint8_t page_sel, uint8_t page_len,
+ uint8_t domain, uint8_t ns)
+{
+ uint8_t smmu_sid;
+ bool smmu_sec_id;
+
+ if (seg_idx > APUMMU_SEG_MAX) {
+ ERROR("seg_idx is illegal (0x%x)\n", seg_idx);
+ return -EINVAL;
+ }
+
+ smmu_sec_id = false;
+ if (ns == 0)
+ smmu_sid = SMMU_NORMAL_1_4G_SID;
+ else
+ smmu_sid = (output_adr > 0xFFFFFFFF) ? SMMU_NORMAL_4_16G_SID
+ : SMMU_NORMAL_1_4G_SID;
+
+ /* fill segment */
+ apummu_set_segment_offset0(vsid_idx, seg_idx, (input_adr >> APUMMU_ADDR_SHIFT), 0,
+ page_sel, page_len);
+ apummu_set_segment_offset1(vsid_idx, seg_idx, (output_adr >> APUMMU_ADDR_SHIFT),
+ smmu_sid, 0, smmu_sec_id);
+ apummu_set_segment_offset2(vsid_idx, seg_idx, 0, domain,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ns);
+ apummu_set_single_segment(vsid_idx, seg_idx);
+
+ return 0;
+}
+
+static int apummu_get_dns(enum apusys_dev_type engine_type, enum apusys_sec_level sec_level,
+ uint8_t *domain, uint8_t *ns)
+{
+ int ret = 0;
+
+ if (engine_type != APUSYS_DEVICE_NUM) {
+ ret = sec_get_dns(engine_type, sec_level, domain, ns);
+ if (ret)
+ ERROR("engine:%d, sec: %d\n", engine_type, sec_level);
+ } else {
+ *domain = 7;
+ *ns = 1;
+ }
+
+ return ret;
+}
+
+static void apummu_init(void)
+{
+ apummu_vsid_sram_config();
+ mmio_write_32((APU_VCORE_CONFIG_BASE + APUMMU_SSID_SID_WIDTH_CTRL),
+ CSR_SMMU_AXMMUSID_WIDTH);
+ apummu_enable();
+}
+
+static void virtual_engine_thread(void)
+{
+ mmio_write_32((APUMMU_RCX_EXTM_TCU_BASE + APUMMU_INT_D2T_TBL0_OFS), APUMMU_THD_ID_TEE);
+}
+
+static int apummu_add_apmcu_map(uint32_t seg0_input, uint32_t seg0_output,
+ enum apummu_page_size page_size)
+{
+ int i, ret;
+ uint8_t domain, ns, seg;
+
+ ret = apummu_get_dns(APUSYS_DEVICE_NUM, SEC_LEVEL_SECURE, &domain, &ns);
+ if (ret) {
+ return ret;
+ }
+
+ seg = 0;
+ ret = apummu_add_map(APUMMU_APMCU_RSV_DESC_IDX, seg, seg0_input, seg0_output, 0,
+ page_size, domain, ns);
+ seg += 1;
+ if (ret)
+ return ret;
+
+ for (i = 0; i < 4; i++) {
+ ret = apummu_add_map(APUMMU_APMCU_RSV_DESC_IDX, seg,
+ APUSYS_TCM + (i * APUMMU_1M_SIZE),
+ APUSYS_TCM + (i * APUMMU_1M_SIZE),
+ 0, APUMMU_PAGE_LEN_1MB, domain, ns);
+ seg += 1;
+ if (ret)
+ return ret;
+ }
+
+ ret = apummu_enable_vsid(APUMMU_APMCU_RSV_VSID);
+
+ return ret;
+}
+
+static int apummu_add_rv_boot_map(uint32_t seg0_output, uint32_t seg1_output, uint32_t seg2_output)
+{
+ int ret;
+ uint8_t domain, ns;
+
+ ret = apummu_get_dns(APUSYS_DEVICE_UP, SEC_LEVEL_SECURE, &domain, &ns);
+ if (ret) {
+ ERROR("sec get dns fail %d\n", ret);
+ return ret;
+ }
+
+ /* must be in order */
+ ret |= apummu_add_map(APUMMU_RSV_VSID_DESC_IDX_END, 0, 0, seg0_output, 0,
+ APUMMU_PAGE_LEN_1MB, domain, ns);
+ ret |= apummu_add_map(APUMMU_RSV_VSID_DESC_IDX_END, 1, 0, seg1_output, 0,
+ APUMMU_PAGE_LEN_512MB, domain, ns);
+
+ ret |= apummu_get_dns(APUSYS_DEVICE_UP, SEC_LEVEL_NORMAL, &domain, &ns);
+ if (ret) {
+ return ret;
+ }
+
+ ret |= apummu_add_map(APUMMU_RSV_VSID_DESC_IDX_END, 2,
+ 0, seg2_output, 0, APUMMU_PAGE_LEN_4GB,
+ domain, ns);
+ if (ret) {
+ ERROR("sec add map fail %d\n", ret);
+ return ret;
+ }
+
+ ret = apummu_enable_vsid(APUMMU_UPRV_RSV_VSID);
+
+ return ret;
+}
+
+int rv_boot(uint32_t uP_seg_output, uint8_t uP_hw_thread,
+ enum apummu_page_size logger_page_size,
+ uint32_t XPU_seg_output, enum apummu_page_size XPU_page_size)
+{
+ int ret = 0;
+
+ apummu_init();
+
+ ret = apummu_add_rv_boot_map(uP_seg_output, 0, 0);
+ if (ret) {
+ return ret;
+ }
+
+ ret = apummu_rv_bind_vsid(uP_hw_thread);
+ if (ret)
+ return ret;
+
+ ret = apummu_rv_bind_vsid(uP_hw_thread + 1);
+ if (ret)
+ return ret;
+
+ virtual_engine_thread();
+
+ ret = apummu_add_apmcu_map(XPU_seg_output, XPU_seg_output,
+ XPU_page_size);
+ if (ret)
+ return ret;
+
+ ret = apummu_apmcu_bind_vsid(APUMMU_THD_ID_TEE);
+
+ return ret;
+}
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.h b/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.h
new file mode 100644
index 0000000..61defc9
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.h
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_AMMU_H
+#define APUSYS_AMMU_H
+
+#include <platform_def.h>
+
+/* CMU */
+#define APUMMU_CMU_TOP_BASE (APU_CMU_TOP)
+#define APUMMU_CMU_TOP_TOPOLOGY (APUMMU_CMU_TOP_BASE + 0x04)
+#define APUMMU_VSID_ENABLE_OFFSET (0x50)
+#define APUMMU_VSID_VALID_OFFSET (0xb0)
+
+#define VSID_OFFSET(vsid_idx) (((vsid_idx) >> 5) * 0x4)
+
+#define APUMMU_VSID_ENABLE_BASE(vsid_idx) \
+ (APUMMU_CMU_TOP_BASE + VSID_OFFSET(vsid_idx) + APUMMU_VSID_ENABLE_OFFSET)
+#define APUMMU_VSID_VALID_BASE(vsid_idx) \
+ (APUMMU_CMU_TOP_BASE + VSID_OFFSET(vsid_idx) + APUMMU_VSID_VALID_OFFSET)
+
+/* VSID SRAM */
+#define APUMMU_VSID_BASE (APUMMU_CMU_TOP_BASE + 0x1000)
+#define APUMMU_VSID_DESC_BASE (APUMMU_VSID_BASE + 0x400)
+#define APUMMU_VSID_SRAM_SZIE (0x5C00)
+#define APUMMU_VSID_TBL_SZIE (0xF4)
+
+#define APUMMU_VSID(vsid_idx) (APUMMU_VSID_BASE + (vsid_idx) * 4)
+#define APUMMU_VSID_DESC(vsid_idx) \
+ (APUMMU_VSID_DESC_BASE + (vsid_idx) * APUMMU_VSID_TBL_SZIE)
+
+/* TCU RCX */
+#define APU_VCORE_CONFIG_BASE (APU_RCX_VCORE_CONFIG)
+#define APUMMU_RCX_EXTM_TCU_BASE (APU_RCX_EXTM_TCU)
+#define APUMMU_RCX_UPRV_TCU_BASE (APU_RCX_UPRV_TCU)
+
+#define APUMMU_SSID_SID_WIDTH_CTRL (0xCC0)
+#define CSR_SMMU_AXMMUSID_WIDTH BIT(7)
+#define APUMMU_1M_SIZE (0x100000)
+
+#define SMMU_NORMAL_0_1G_SID (0x8)
+#define SMMU_NORMAL_1_4G_SID (0x9)
+#define SMMU_NORMAL_4_16G_SID (0xA)
+
+enum apummu_page_size {
+ APUMMU_PAGE_LEN_128KB = 0,
+ APUMMU_PAGE_LEN_256KB,
+ APUMMU_PAGE_LEN_512KB,
+ APUMMU_PAGE_LEN_1MB,
+ APUMMU_PAGE_LEN_128MB,
+ APUMMU_PAGE_LEN_256MB,
+ APUMMU_PAGE_LEN_512MB,
+ APUMMU_PAGE_LEN_4GB,
+};
+
+#define APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, seg_offset) \
+ (APUMMU_VSID_DESC(vsid_idx) + (seg_idx) * 0xC + (seg_offset) * 0x04 + 0x4)
+
+#define APUMMU_VSID_SEGMENT_ENABLE(vsid_idx) (APUMMU_VSID_DESC(vsid_idx))
+
+#define APUMMU_VSID_SRAM_TOTAL (APUMMU_VSID_SRAM_SZIE / APUMMU_VSID_TBL_SZIE)
+#define APUMMU_RSV_VSID_DESC_IDX_END (APUMMU_VSID_SRAM_TOTAL - 1)
+#define APUMMU_UPRV_RSV_DESC_IDX (APUMMU_RSV_VSID_DESC_IDX_END) /* 53 */
+#define APUMMU_LOGGER_RSV_DESC_IDX (APUMMU_RSV_VSID_DESC_IDX_END - 1)
+#define APUMMU_APMCU_RSV_DESC_IDX (APUMMU_RSV_VSID_DESC_IDX_END - 2)
+#define APUMMU_GPU_RSV_DESC_IDX (APUMMU_RSV_VSID_DESC_IDX_END - 3)
+
+#define APUMMU_SEG_OFFSET_0 (0)
+#define APUMMU_SEG_OFFSET_1 (1)
+#define APUMMU_SEG_OFFSET_2 (2)
+#define APUMMU_VSID_EN_MASK (0x1f)
+
+#define APUMMU_HW_THREAD_MAX (7)
+#define APUMMU_SEG_MAX (9)
+#define APUMMU_ADDR_SHIFT (12)
+
+#define VSID_THREAD_SZ (0x4)
+#define VSID_CORID_MASK (0x7f)
+#define VSID_CORID_OFF (11)
+#define VSID_IDX_MASK (0xff)
+#define VSID_IDX_OFF (3)
+#define VSID_VALID_MASK (0x1)
+#define VSID_COR_VALID_OFF (1)
+#define VSID_VALID_OFF (0)
+
+#define APUMMU_VSID_ACTIVE (32)
+#define APUMMU_VSID_RSV (4)
+#define APUMMU_VSID_UNUSED (12)
+#define APUMMU_VSID_USE_MAX (APUMMU_VSID_ACTIVE + APUMMU_VSID_RSV)
+
+#if ((APUMMU_VSID_RSV + APUMMU_VSID_ACTIVE + APUMMU_VSID_UNUSED + 1) > APUMMU_VSID_SRAM_TOTAL)
+#error APUMMU VSID Overflow
+#endif
+
+#define APUMMU_RSV_VSID_IDX_END (254)
+#define APUMMU_RSV_VSID_IDX_START (APUMMU_RSV_VSID_IDX_END - APUMMU_VSID_RSV + 1)
+
+#if ((APUMMU_RSV_VSID_IDX_END - APUMMU_RSV_VSID_IDX_START) > APUMMU_VSID_RSV)
+#error APUMMU VSID RSV Overflow
+#endif
+
+/* Reserve */
+#define APUMMU_UPRV_RSV_VSID (APUMMU_RSV_VSID_IDX_END)
+#define APUMMU_LOGGER_RSV_VSID (APUMMU_RSV_VSID_IDX_END - 1)
+#define APUMMU_APMCU_RSV_VSID (APUMMU_RSV_VSID_IDX_END - 2)
+#define APUMMU_GPU_RSV_VSID (APUMMU_RSV_VSID_IDX_END - 3)
+
+/* VSID bit mask */
+#define APUMMU_VSID_MAX_MASK_WORD ((APUMMU_VSID_USE_MAX + 32 - 1) / 32)
+
+/* VSID fields */
+#define READ_VSID_FIELD(vids, sg, offset, shift, mask) \
+ ((mmio_read_32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, offset)) >> sift) & mask)
+#define READ_VSID_FIELD_OFFESET0(vids, sg, shift, mask) \
+ READ_VSID_FIELD(vids, sg, 0, shift, mask)
+#define READ_VSID_FIELD_OFFESET1(vids, sg, shift, mask) \
+ READ_VSID_FIELD(vids, sg, 1, shift, mask)
+#define READ_VSID_FIELD_OFFESET2(vids, sg, shift, mask) \
+ READ_VSID_FIELD(vids, sg, 2, shift, mask)
+
+/* Get segment offset 0 data - 0x00 */
+#define APUMMU_SEGMENT_GET_INPUT(vsid, seg) \
+ READ_VSID_FIELD_OFFESET0(vsid, seg, 10, 0x3FFFFF)
+#define APUMMU_SEGMENT_GET_OFFSET0_RSRV(vsid, seg) \
+ READ_VSID_FIELD_OFFESET0(vsid, seg, 6, 0xF)
+#define APUMMU_SEGMENT_GET_PAGELEN(vsid, seg) \
+ READ_VSID_FIELD_OFFESET0(vsid, seg, 0, 0x7)
+#define APUMMU_SEGMENT_GET_PAGESEL(vsid, seg) \
+ READ_VSID_FIELD_OFFESET0(vsid, seg, 3, 0x7)
+
+/* Get segment offset 1 data - 0x04 */
+#define APUMMU_SEGMENT_GET_IOMMU_EN(vsid, seg) \
+ READ_VSID_FIELD_OFFESET1(vsid, seg, 1, 0x1)
+#define APUMMU_SEGMENT_GET_OFFSET1_RSRV0(vsid, seg) \
+ READ_VSID_FIELD_OFFESET1(vsid, seg, 2, 0xFF)
+#define APUMMU_SEGMENT_GET_OFFSET1_RSRV1(vsid, seg) \
+ READ_VSID_FIELD_OFFESET1(vsid, seg, 0, 0x1)
+#define APUMMU_SEGMENT_GET_OUTPUT(vsid, seg) \
+ READ_VSID_FIELD_OFFESET1(vsid, seg, 10, 0x3FFFFF)
+
+/* Get segment offset 2 data - 0x08 */
+#define APUMMU_SEGMENT_GET_ACP_EN(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 12, 0x1)
+#define APUMMU_SEGMENT_GET_AR_CACHE_ALLOC(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 4, 0x1)
+#define APUMMU_SEGMENT_GET_AR_EXCLU(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 9, 0x1)
+#define APUMMU_SEGMENT_GET_AR_SEPCU(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 8, 0x1)
+#define APUMMU_SEGMENT_GET_AR_SLB_EN(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 2, 0x1)
+#define APUMMU_SEGMENT_GET_AR_SLC_EN(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 3, 0x1)
+#define APUMMU_SEGMENT_GET_AW_CACHE_ALLOC(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 7, 0x1)
+#define APUMMU_SEGMENT_GET_AW_CLR(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 11, 0x1)
+#define APUMMU_SEGMENT_GET_AW_INVALID(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 10, 0x1)
+#define APUMMU_SEGMENT_GET_AW_SLB_EN(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 5, 0x1)
+#define APUMMU_SEGMENT_GET_AW_SLC_EN(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 6, 0x1)
+#define APUMMU_SEGMENT_GET_DOMAIN(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 13, 0xF)
+#define APUMMU_SEGMENT_GET_NS(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 0, 0x1)
+
+/* Build segment data */
+/* Build segment offset 0 (0x00) data */
+#define APUMMU_VSID_SEGMENT_00_INPUT(input_adr) (((input_adr) & 0x3fffff) << 10)
+#define APUMMU_VSID_SEGMENT_00_PAGESEL(page_sel) (((page_sel) & 0x7) << 3)
+#define APUMMU_VSID_SEGMENT_00_PAGELEN(page_len) (((page_len) & 0x7) << 0)
+#define APUMMU_VSID_SEGMENT_00_RESV(resv) (((resv) & 0xf) << 6)
+
+#define APUMMU_BUILD_SEGMENT_OFFSET0(input_adr, resv, page_sel, page_len) \
+ (APUMMU_VSID_SEGMENT_00_INPUT(input_adr) | \
+ APUMMU_VSID_SEGMENT_00_RESV(resv) | \
+ APUMMU_VSID_SEGMENT_00_PAGESEL(page_sel) | \
+ APUMMU_VSID_SEGMENT_00_PAGELEN(page_len))
+
+/* Build segment offset 1 (0x04) data */
+#define APUMMU_VSID_SEGMENT_04_IOMMU_EN(iommu_en) (((iommu_en) & 0x1) << 1)
+#define APUMMU_VSID_SEGMENT_04_OUTPUT(output_adr) (((output_adr) & 0x3fffff) << 10)
+#define APUMMU_VSID_SEGMENT_04_RESV0(resv0) (((resv0) & 0xff) << 2)
+#define APUMMU_VSID_SEGMENT_04_RESV1(resv1) (((resv1) & 0x1) << 0)
+
+#define APUMMU_BUILD_SEGMENT_OFFSET1(output_adr, resv0, iommu_en, resv1) \
+ (APUMMU_VSID_SEGMENT_04_OUTPUT(output_adr) | \
+ APUMMU_VSID_SEGMENT_04_RESV0(resv0) | \
+ APUMMU_VSID_SEGMENT_04_IOMMU_EN(iommu_en) | \
+ APUMMU_VSID_SEGMENT_04_RESV1(resv1))
+
+/* Build segment offset 2 (0x08) data */
+#define APUMMU_VSID_SEGMENT_08_DOMAIN_MASK (0xf)
+#define APUMMU_VSID_SEGMENT_08_DOMAIN_SHIFT (13)
+#define APUMMU_VSID_SEGMENT_08_RESV_MASK (0x7fff)
+#define APUMMU_VSID_SEGMENT_08_RESV_SHIFT (17)
+
+#define APUMMU_VSID_SEGMENT_08_DOMAIN(domain) \
+ (((domain) & APUMMU_VSID_SEGMENT_08_DOMAIN_MASK) << APUMMU_VSID_SEGMENT_08_DOMAIN_SHIFT)
+#define APUMMU_VSID_SEGMENT_08_RESV(resv) \
+ (((resv) & APUMMU_VSID_SEGMENT_08_RESV_MASK) << APUMMU_VSID_SEGMENT_08_RESV_SHIFT)
+
+#define APUMMU_VSID_SEGMENT_08_ACP_EN(acp_en) (((acp_en) & 0x1) << 12)
+#define APUMMU_VSID_SEGMENT_08_AR_EXCLU(ar_exclu) (((ar_exclu) & 0x1) << 9)
+#define APUMMU_VSID_SEGMENT_08_AR_SEPCU(ar_sepcu) (((ar_sepcu) & 0x1) << 8)
+#define APUMMU_VSID_SEGMENT_08_AR_SLB_EN(ar_slb_en) (((ar_slb_en) & 0x1) << 2)
+#define APUMMU_VSID_SEGMENT_08_AR_SLC_EN(ar_slc_en) (((ar_slc_en) & 0x1) << 3)
+#define APUMMU_VSID_SEGMENT_08_AW_CLR(aw_clr) (((aw_clr) & 0x1) << 11)
+#define APUMMU_VSID_SEGMENT_08_AW_INVALID(aw_invalid) (((aw_invalid) & 0x1) << 10)
+#define APUMMU_VSID_SEGMENT_08_AW_SLB_EN(aw_slb_en) (((aw_slb_en) & 0x1) << 5)
+#define APUMMU_VSID_SEGMENT_08_AW_SLC_EN(aw_slc_en) (((aw_slc_en) & 0x1) << 6)
+#define APUMMU_VSID_SEGMENT_08_NS(ns) (((ns) & 0x1) << 0)
+#define APUMMU_VSID_SEGMENT_08_RO(ro) (((ro) & 0x1) << 1)
+
+#define APUMMU_VSID_SEGMENT_08_AR_CACHE_ALLOCATE(ar_cache_allocate) \
+ (((ar_cache_allocate) & 0x1) << 4)
+#define APUMMU_VSID_SEGMENT_08_AW_CACHE_ALLOCATE(aw_cache_allocate) \
+ (((aw_cache_allocate) & 0x1) << 7)
+
+#define APUMMU_BUILD_SEGMENT_OFFSET2(resv, domain, acp_en, aw_clr, \
+ aw_invalid, ar_exclu, ar_sepcu, \
+ aw_cache_allocate, aw_slc_en, aw_slb_en, ar_cache_allocate, \
+ ar_slc_en, ar_slb_en, ro, ns) \
+ ((APUMMU_VSID_SEGMENT_08_RESV(resv)) |\
+ (APUMMU_VSID_SEGMENT_08_DOMAIN(domain)) |\
+ (APUMMU_VSID_SEGMENT_08_ACP_EN(acp_en)) |\
+ (APUMMU_VSID_SEGMENT_08_AW_CLR(aw_clr)) |\
+ (APUMMU_VSID_SEGMENT_08_AW_INVALID(aw_invalid)) |\
+ (APUMMU_VSID_SEGMENT_08_AR_EXCLU(ar_exclu)) |\
+ (APUMMU_VSID_SEGMENT_08_AR_SEPCU(ar_sepcu)) |\
+ (APUMMU_VSID_SEGMENT_08_AW_CACHE_ALLOCATE(aw_cache_allocate)) |\
+ (APUMMU_VSID_SEGMENT_08_AW_SLC_EN(aw_slc_en)) |\
+ (APUMMU_VSID_SEGMENT_08_AW_SLB_EN(aw_slb_en)) |\
+ (APUMMU_VSID_SEGMENT_08_AR_CACHE_ALLOCATE(ar_cache_allocate)) |\
+ (APUMMU_VSID_SEGMENT_08_AR_SLC_EN(ar_slc_en)) |\
+ (APUMMU_VSID_SEGMENT_08_AR_SLB_EN(ar_slb_en)) |\
+ (APUMMU_VSID_SEGMENT_08_RO(ro)) | (APUMMU_VSID_SEGMENT_08_NS(ns)))
+
+/* Build segment offset 3 (0x0c) data */
+#define APUMMU_VSID_SEGMENT_0C_RESV(rsv) (((rsv) & 0x7fffffff) << 0)
+#define APUMMU_VSID_SEGMENT_0C_SEG_VALID(seg_valid) (((seg_valid) & 0x1U) << 31)
+#define APUMMU_BUILD_SEGMENT_OFFSET3(seg_valid, rsv) \
+ ((uint32_t)APUMMU_VSID_SEGMENT_0C_SEG_VALID(seg_valid) | \
+ APUMMU_VSID_SEGMENT_0C_RESV(rsv))
+
+#define APUMMU_INT_D2T_TBL0_OFS (0x40)
+
+#define APUSYS_TCM (0x4d100000)
+
+enum {
+ APUMMU_THD_ID_APMCU_NORMAL = 0,
+ APUMMU_THD_ID_TEE,
+};
+
+int rv_boot(uint32_t uP_seg_output, uint8_t uP_hw_thread,
+ enum apummu_page_size logger_page_size, uint32_t XPU_seg_output,
+ enum apummu_page_size XPU_page_size);
+
+#endif
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.c b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.c
new file mode 100644
index 0000000..f6c8f58
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include "apusys_security_ctrl_perm.h"
+#include "apusys_security_ctrl_perm_plat.h"
+
+#define SEC_CTRL_APU_SEC_CON_BASE (0x190F5000)
+#define SEC_CTRL_RV_DOMAIN_OFS (0x60)
+#define SEC_CTRL_RV_NS_OFS (0x64)
+#define SEC_CTRL_RV_DOMAIN_SHF (4)
+#define SEC_CTRL_RV_NS_SHF (1)
+
+#define SEC_LEVEL_NORMAL_DOMAIN (7)
+#define SEC_LEVEL_NORMAL_NS (1)
+#define SEC_LEVEL_SAPU_DOMAIN (5)
+#define SEC_LEVEL_SAPU_NS (1)
+#define SEC_LEVEL_AOV_DOMAIN (14)
+#define SEC_LEVEL_AOV_NS (1)
+#define SEC_LEVEL_UP_SECURE_DOMAIN (5)
+#define SEC_LEVEL_UP_SECURE_NS (0)
+#define SEC_LEVEL_MVPU_SECURE_DOMAIN (7)
+#define SEC_LEVEL_MVPU_SECURE_NS (0)
+#define SEC_LEVEL_MDLA_SECURE_DOMAIN (14)
+#define SEC_LEVEL_MDLA_SECURE_NS (0)
+#define DOMAIN(SEC_LVL) SEC_LEVEL_##SEC_LVL##_DOMAIN
+#define NS(SEC_LVL) SEC_LEVEL_##SEC_LVL##_NS
+
+int sec_get_dns(enum apusys_dev_type dev_type, enum apusys_sec_level sec_level,
+ uint8_t *domain, uint8_t *ns)
+{
+ if ((dev_type < 0) || (dev_type >= APUSYS_DEVICE_NUM)) {
+ ERROR("invalid dev type %d\n", dev_type);
+ return -EINVAL;
+ }
+
+ if ((sec_level < 0) || (sec_level >= SEC_LEVEL_NUM)) {
+ ERROR("invalid sec_level %d\n", sec_level);
+ return -EINVAL;
+ }
+
+ switch (sec_level) {
+ case SEC_LEVEL_NORMAL:
+ *domain = DOMAIN(NORMAL);
+ *ns = NS(NORMAL);
+ break;
+ case SEC_LEVEL_SECURE:
+ switch (dev_type) {
+ case APUSYS_DEVICE_MVPU:
+ *domain = DOMAIN(MVPU_SECURE);
+ *ns = NS(MVPU_SECURE);
+ break;
+ case APUSYS_DEVICE_MDLA:
+ *domain = DOMAIN(MDLA_SECURE);
+ *ns = NS(MDLA_SECURE);
+ break;
+ case APUSYS_DEVICE_UP:
+ *domain = DOMAIN(UP_SECURE);
+ *ns = NS(UP_SECURE);
+ break;
+ default:
+ ERROR("invalid dev type %d\n", dev_type);
+ return -EINVAL;
+ };
+ break;
+ case SEC_LEVEL_SAPU:
+ *domain = DOMAIN(SAPU);
+ *ns = NS(SAPU);
+ break;
+ case SEC_LEVEL_AOV:
+ *domain = DOMAIN(AOV);
+ *ns = NS(AOV);
+ break;
+ default:
+ ERROR("invalid sec_level %d\n", sec_level);
+ return -EINVAL;
+ };
+
+ return 0;
+}
+
+int sec_set_rv_dns(void)
+{
+ uint8_t normal_domain;
+ uint8_t normal_ns;
+ uint8_t sec_domain;
+ uint8_t sec_ns;
+ int ret;
+
+ ret = sec_get_dns(APUSYS_DEVICE_UP, SEC_LEVEL_SECURE, &sec_domain, &sec_ns);
+ if (ret) {
+ ERROR("%s failed.\n", __func__);
+ return ret;
+ }
+
+ ret = sec_get_dns(APUSYS_DEVICE_UP, SEC_LEVEL_NORMAL, &normal_domain, &normal_ns);
+ if (ret) {
+ ERROR("%s failed.\n", __func__);
+ return ret;
+ }
+
+ mmio_write_32(SEC_CTRL_APU_SEC_CON_BASE + SEC_CTRL_RV_DOMAIN_OFS,
+ (sec_domain << SEC_CTRL_RV_DOMAIN_SHF) | normal_domain);
+ mmio_write_32(SEC_CTRL_APU_SEC_CON_BASE + SEC_CTRL_RV_NS_OFS,
+ (sec_ns << SEC_CTRL_RV_NS_SHF) | normal_ns);
+
+ return 0;
+}
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.h b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.h
new file mode 100644
index 0000000..d57a536
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_SECURITY_CTRL_PERM_PLAT_H
+#define APUSYS_SECURITY_CTRL_PERM_PLAT_H
+
+enum apusys_dev_type {
+ APUSYS_DEVICE_MDLA,
+ APUSYS_DEVICE_EDPA,
+ APUSYS_DEVICE_MVPU,
+ APUSYS_DEVICE_UP,
+ APUSYS_DEVICE_NUM,
+};
+
+#endif /* APUSYS_SECURITY_CTRL_PERM_PLAT_H */
diff --git a/plat/mediatek/drivers/apusys/mt8196/rules.mk b/plat/mediatek/drivers/apusys/mt8196/rules.mk
index 44c294d..348051a 100644
--- a/plat/mediatek/drivers/apusys/mt8196/rules.mk
+++ b/plat/mediatek/drivers/apusys/mt8196/rules.mk
@@ -13,8 +13,10 @@
PLAT_INCLUDES += -I${MTK_PLAT}/drivers/emi/${MTK_SOC}
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
LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_security_ctrl_plat.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_security_ctrl_perm_plat.c
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/apusys/rules.mk b/plat/mediatek/drivers/apusys/rules.mk
index 3c2fd2a..6197995 100644
--- a/plat/mediatek/drivers/apusys/rules.mk
+++ b/plat/mediatek/drivers/apusys/rules.mk
@@ -13,11 +13,14 @@
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_EMI_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_SEC_CTRL))
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
SUB_RULES-y := ${LOCAL_DIR}/${MTK_SOC}
SUB_RULES-y += ${LOCAL_DIR}/devapc
SUB_RULES-y += ${LOCAL_DIR}/apusys_rv/2.0
+SUB_RULES-${CONFIG_MTK_APUSYS_SEC_CTRL} += $(LOCAL_DIR)/security_ctrl
$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
diff --git a/plat/mediatek/drivers/apusys/security_ctrl/apusys_security_ctrl_perm.h b/plat/mediatek/drivers/apusys/security_ctrl/apusys_security_ctrl_perm.h
new file mode 100644
index 0000000..17ccacf
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/security_ctrl/apusys_security_ctrl_perm.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SECURITY_CTRL_PERM_H
+#define SECURITY_CTRL_PERM_H
+
+#include "apusys_security_ctrl_perm_plat.h"
+
+enum apusys_sec_level {
+ SEC_LEVEL_NORMAL,
+ SEC_LEVEL_SECURE,
+ SEC_LEVEL_SAPU,
+ SEC_LEVEL_AOV,
+ SEC_LEVEL_NUM,
+};
+
+int sec_set_rv_dns(void);
+int sec_get_dns(enum apusys_dev_type dev_type, enum apusys_sec_level sec_level,
+ uint8_t *domain, uint8_t *ns);
+
+#endif
diff --git a/plat/mediatek/drivers/apusys/security_ctrl/rules.mk b/plat/mediatek/drivers/apusys/security_ctrl/rules.mk
new file mode 100644
index 0000000..a7ed5c9
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/security_ctrl/rules.mk
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_INCLUDES += -I${MTK_PLAT}/drivers/apusys/security_ctrl
+PLAT_INCLUDES += -I${MTK_PLAT}/drivers/apusys/${MTK_SOC}
diff --git a/plat/mediatek/mt8196/include/platform_def.h b/plat/mediatek/mt8196/include/platform_def.h
index 50a8a33..5602584 100644
--- a/plat/mediatek/mt8196/include/platform_def.h
+++ b/plat/mediatek/mt8196/include/platform_def.h
@@ -34,7 +34,11 @@
* APUSYS related constants
******************************************************************************/
#define APUSYS_BASE (IO_PHYS + 0x09000000)
+#define APU_RCX_UPRV_TCU (IO_PHYS + 0x09060000)
+#define APU_RCX_EXTM_TCU (IO_PHYS + 0x09061000)
+#define APU_CMU_TOP (IO_PHYS + 0x09067000)
#define APUSYS_CE_BASE (IO_PHYS + 0x090B0000)
+#define APU_RCX_VCORE_CONFIG (IO_PHYS + 0x090E0000)
#define APU_AO_CTRL (IO_PHYS + 0x090F2000)
#define APU_SEC_CON (IO_PHYS + 0x090F5000)
#define APUSYS_CTRL_DAPC_AO_BASE (IO_PHYS + 0x090FC000)
diff --git a/plat/mediatek/mt8196/plat_config.mk b/plat/mediatek/mt8196/plat_config.mk
index 92c7c48..41292f2 100644
--- a/plat/mediatek/mt8196/plat_config.mk
+++ b/plat/mediatek/mt8196/plat_config.mk
@@ -27,6 +27,8 @@
CONFIG_ARCH_ARM_V9 := y
CONFIG_MTK_APUSYS_EMI_SUPPORT := n
+CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT := y
+CONFIG_MTK_APUSYS_SEC_CTRL := y
CONFIG_MTK_MCUSYS := y
MCUSYS_VERSION := v1
CONFIG_MTK_PM_SUPPORT := y