Merge "feat(mediatek): add vcp driver support" into integration
diff --git a/plat/mediatek/drivers/vcp/mt8196/vcp_helper.h b/plat/mediatek/drivers/vcp/mt8196/vcp_helper.h
new file mode 100644
index 0000000..3d87d40
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/mt8196/vcp_helper.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef VCP_HELPER_H
+#define VCP_HELPER_H
+
+#define MTK_VCP_SRAM_SIZE (0x60000)
+
+/* Export extern API */
+uint32_t get_mmup_fw_size(void);
+uint64_t get_mmup_l2tcm_offset(void);
+
+/* SMC calls OPS */
+enum mtk_tinysys_vcp_kernel_op {
+ MTK_TINYSYS_VCP_KERNEL_OP_RESET_SET = 0,
+ MTK_TINYSYS_VCP_KERNEL_OP_RESET_RELEASE,
+ MTK_TINYSYS_VCP_KERNEL_OP_COLD_BOOT_VCP,
+ MTK_TINYSYS_MMUP_KERNEL_OP_RESET_SET,
+ MTK_TINYSYS_MMUP_KERNEL_OP_RESET_RELEASE,
+ MTK_TINYSYS_MMUP_KERNEL_OP_SET_L2TCM_OFFSET,
+ MTK_TINYSYS_MMUP_KERNEL_OP_SET_FW_SIZE,
+ MTK_TINYSYS_MMUP_KERNEL_OP_COLD_BOOT_MMUP,
+ MTK_TINYSYS_VCP_KERNEL_OP_NUM,
+};
+
+#endif /* VCP_HELPER_H */
diff --git a/plat/mediatek/drivers/vcp/mt8196/vcp_reg.h b/plat/mediatek/drivers/vcp/mt8196/vcp_reg.h
new file mode 100644
index 0000000..4aa8332
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/mt8196/vcp_reg.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef VCP_REG_H
+#define VCP_REG_H
+
+#include <platform_def.h>
+
+#define MTK_VCP_REG_BASE (IO_PHYS + 0x21800000)
+#define MTK_VCP_REG_BANK_SIZE (0x1000)
+
+/*******************************************************************************
+ * VCP power related setting
+ ******************************************************************************/
+#define VCP_POWER_STATUS (0xE60)
+#define MMUP_PWR_STA_BIT (30)
+#define MMUP_PWR_STA_EN ((uint32_t)(0x3))
+
+/*******************************************************************************
+ * VCP registers
+ ******************************************************************************/
+/* cfgreg */
+#define VCP_R_CFGREG (MTK_VCP_REG_BASE + 0x3d0000)
+
+#define VCP_R_CORE0_SW_RSTN_CLR (VCP_R_CFGREG + 0x0000)
+#define VCP_R_CORE0_SW_RSTN_SET (VCP_R_CFGREG + 0x0004)
+#define VCP_R_CORE1_SW_RSTN_CLR (VCP_R_CFGREG + 0x0008)
+#define VCP_R_CORE1_SW_RSTN_SET (VCP_R_CFGREG + 0x000c)
+#define VCP_R_GIPC_IN_SET (VCP_R_CFGREG + 0x0028)
+#define VCP_R_GIPC_IN_CLR (VCP_R_CFGREG + 0x002c)
+#define B_GIPC3_SETCLR_1 BIT(13)
+
+/* cfgreg_core0 */
+#define VCP_R_CFGREG_CORE0 (MTK_VCP_REG_BASE + 0x20a000)
+
+#define VCP_R_CORE0_STATUS (VCP_R_CFGREG_CORE0 + 0x0070)
+
+#define CORE0_R_GPR5 (VCP_R_CFGREG_CORE0 + 0x0054)
+#define VCP_GPR_C0_H0_REBOOT CORE0_R_GPR5
+#define CORE0_R_GPR6 (VCP_R_CFGREG_CORE0 + 0x0058)
+#define VCP_GPR_C0_H1_REBOOT CORE0_R_GPR6
+#define VCP_CORE_RDY_TO_REBOOT (0x34)
+#define VCP_CORE_REBOOT_OK BIT(0)
+
+/* cfgreg_core1 */
+#define VCP_R_CFGREG_CORE1 (MTK_VCP_REG_BASE + 0x20d000)
+
+#define VCP_R_CORE1_STATUS (VCP_R_CFGREG_CORE1 + 0x0070)
+#define CORE1_R_GPR5 (VCP_R_CFGREG_CORE1 + 0x0054)
+#define VCP_GPR_CORE1_REBOOT CORE1_R_GPR5
+
+/* sec */
+#define VCP_R_SEC_CTRL (MTK_VCP_REG_BASE + 0x270000)
+#define VCP_OFFSET_ENABLE_P BIT(13)
+#define VCP_OFFSET_ENABLE_B BIT(12)
+#define VCP_R_SEC_CTRL_2 (VCP_R_SEC_CTRL + 0x0004)
+#define CORE0_SEC_BIT_SEL BIT(0)
+#define CORE1_SEC_BIT_SEL BIT(8)
+#define VCP_GPR0_CFGREG_SEC (VCP_R_SEC_CTRL + 0x0040)
+#define VCP_GPR1_CFGREG_SEC (VCP_R_SEC_CTRL + 0x0044)
+#define VCP_GPR2_CFGREG_SEC (VCP_R_SEC_CTRL + 0x0048)
+#define VCP_GPR3_CFGREG_SEC (VCP_R_SEC_CTRL + 0x004C)
+#define VCP_R_SEC_DOMAIN (VCP_R_SEC_CTRL + 0x0080)
+#define VCP_DOMAIN_ID U(13)
+#define VCP_DOMAIN_MASK U(0xF)
+#define VCP_CORE0_TH0_PM_AXI_DOMAIN (0)
+#define VCP_CORE0_TH0_DM_AXI_DOMAIN (4)
+#define VCP_S_DMA0_DOMAIN (12)
+#define VCP_HWCCF_DOMAIN (16)
+#define VCP_CORE0_TH1_PM_AXI_DOMAIN (20)
+#define VCP_CORE0_TH1_DM_AXI_DOMAIN (24)
+#define VCP_DOMAIN_SET ((VCP_DOMAIN_ID << VCP_CORE0_TH0_PM_AXI_DOMAIN) | \
+ (VCP_DOMAIN_ID << VCP_CORE0_TH0_DM_AXI_DOMAIN) | \
+ (VCP_DOMAIN_ID << VCP_CORE0_TH1_PM_AXI_DOMAIN) | \
+ (VCP_DOMAIN_ID << VCP_CORE0_TH1_DM_AXI_DOMAIN) | \
+ (VCP_DOMAIN_ID << VCP_S_DMA0_DOMAIN))
+#define VCP_R_SEC_DOMAIN_MMPC (VCP_R_SEC_CTRL + 0x0084)
+#define VCP_CORE_MMPC_PM_AXI_DOMAIN (0)
+#define VCP_CORE_MMPC_DM_AXI_DOMAIN (4)
+#define VCP_DOMAIN_SET_MMPC ((VCP_DOMAIN_ID << VCP_CORE_MMPC_PM_AXI_DOMAIN) | \
+ (VCP_DOMAIN_ID << VCP_CORE_MMPC_DM_AXI_DOMAIN))
+#define R_L2TCM_OFFSET_RANGE_0_LOW (VCP_R_SEC_CTRL + 0x00B0)
+#define R_L2TCM_OFFSET_RANGE_0_HIGH (VCP_R_SEC_CTRL + 0x00B4)
+#define R_L2TCM_OFFSET (VCP_R_SEC_CTRL + 0x00D0)
+#define VCP_R_DYN_SECURE (VCP_R_SEC_CTRL + 0x01d0)
+#define VCP_NS_I0 BIT(4)
+#define VCP_NS_D0 BIT(6)
+#define VCP_NS_SECURE_B_REGION_ENABLE (24)
+#define RESET_NS_SECURE_B_REGION U(0xFF)
+#define VCP_R_DYN_SECURE_TH1 (VCP_R_SEC_CTRL + 0x01d4)
+#define VCP_NS_I1 BIT(5)
+#define VCP_NS_D1 BIT(7)
+#define VCP_R_S_DOM_EN0_31 (VCP_R_SEC_CTRL + 0x0200)
+#define VCP_R_S_DOM_EN32_63 (VCP_R_SEC_CTRL + 0x0204)
+#define VCP_R_NS_DOM_EN0_31 (VCP_R_SEC_CTRL + 0x0208)
+#define VCP_R_NS_DOM_EN32_63 (VCP_R_SEC_CTRL + 0x020c)
+/* IOMMU */
+#define VCP_R_AXIOMMUEN_DEV_APC (VCP_R_SEC_CTRL + 0x0088)
+#define VCP_R_CFG_DEVAPC_AO_BASE (MTK_VCP_REG_BASE + 0x2d0000)
+
+#endif /* VCP_REG_H */
diff --git a/plat/mediatek/drivers/vcp/rules.mk b/plat/mediatek/drivers/vcp/rules.mk
new file mode 100644
index 0000000..9e342de
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/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 := vcp
+
+SUB_RULES-y := $(LOCAL_DIR)/rv
+
+$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
diff --git a/plat/mediatek/drivers/vcp/rv/mmup_common.c b/plat/mediatek/drivers/vcp/rv/mmup_common.c
new file mode 100644
index 0000000..a6d0819
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/rv/mmup_common.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <inttypes.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include "mmup_common.h"
+#include "vcp_helper.h"
+#include "vcp_reg.h"
+
+#define MODULE_TAG "[MMUP]"
+
+bool mmup_smc_rstn_set(bool boot_ok)
+{
+ if (mmio_read_32(VCP_GPR_CORE1_REBOOT) != 0 &&
+ mmio_read_32(VCP_R_CORE1_STATUS) != 0 &&
+ (mmio_read_32(VCP_R_GIPC_IN_SET) & B_GIPC3_SETCLR_1) == 0 &&
+ (mmio_read_32(VCP_R_GIPC_IN_CLR) & B_GIPC3_SETCLR_1) == 0 &&
+ mmio_read_32(VCP_GPR_CORE1_REBOOT) != VCP_CORE_RDY_TO_REBOOT) {
+ ERROR("%s: [%s] mmup reset set fail!GIPC 0x%x 0x%x REBOOT 0x%x\n",
+ MODULE_TAG, __func__, mmio_read_32(VCP_R_GIPC_IN_SET),
+ mmio_read_32(VCP_R_GIPC_IN_CLR),
+ mmio_read_32(VCP_GPR_CORE1_REBOOT));
+ return false;
+ }
+
+ mmio_write_32(VCP_R_CORE1_SW_RSTN_SET, BIT(0));
+
+ /* reset sec control */
+ mmio_write_32(VCP_R_SEC_CTRL_2, 0);
+
+ /* reset domain setting */
+ mmio_write_32(VCP_R_S_DOM_EN0_31, 0x0);
+ mmio_write_32(VCP_R_S_DOM_EN32_63, 0x0);
+ mmio_write_32(VCP_R_NS_DOM_EN0_31, 0x0);
+ mmio_write_32(VCP_R_NS_DOM_EN32_63, 0x0);
+
+ /* reset sec setting */
+ mmio_clrbits_32(VCP_R_DYN_SECURE,
+ RESET_NS_SECURE_B_REGION << VCP_NS_SECURE_B_REGION_ENABLE);
+
+ if (boot_ok)
+ mmio_write_32(VCP_GPR_CORE1_REBOOT, VCP_CORE_REBOOT_OK);
+
+ dsbsy();
+ return true;
+}
+
+bool mmup_smc_rstn_clr(void)
+{
+ if ((mmio_read_32(VCP_R_CORE1_SW_RSTN_SET) & BIT(0)) == 1) {
+ ERROR("%s: [%s] mmup not reset set !\n", MODULE_TAG, __func__);
+ return false;
+ }
+
+ if ((get_mmup_fw_size() == 0) || get_mmup_l2tcm_offset() == 0) {
+ ERROR("%s: [%s] mmup no enough l2tcm to run !\n", MODULE_TAG, __func__);
+ return false;
+ }
+
+ mmio_write_32(VCP_R_SEC_DOMAIN_MMPC, VCP_DOMAIN_SET_MMPC);
+
+ /* enable IOVA Mode */
+ mmio_write_32(VCP_R_AXIOMMUEN_DEV_APC, BIT(0));
+
+ /* reset secure setting */
+ mmio_setbits_32(VCP_R_SEC_CTRL_2, CORE1_SEC_BIT_SEL);
+
+ /* l2tcm offset*/
+ mmio_setbits_32(VCP_R_SEC_CTRL, VCP_OFFSET_ENABLE_P | VCP_OFFSET_ENABLE_B);
+ mmio_write_32(R_L2TCM_OFFSET_RANGE_0_LOW, 0x0);
+ mmio_write_32(R_L2TCM_OFFSET_RANGE_0_HIGH, round_up(get_mmup_fw_size(), PAGE_SIZE));
+ mmio_write_32(R_L2TCM_OFFSET, get_mmup_l2tcm_offset());
+
+ /* start vcp-mmup */
+ mmio_write_32(VCP_R_CORE1_SW_RSTN_CLR, BIT(0));
+ dsbsy();
+ return true;
+}
diff --git a/plat/mediatek/drivers/vcp/rv/mmup_common.h b/plat/mediatek/drivers/vcp/rv/mmup_common.h
new file mode 100644
index 0000000..e70d25f
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/rv/mmup_common.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MMUP_COMMON_H
+#define MMUP_COMMON_H
+
+bool mmup_smc_rstn_set(bool boot_ok);
+bool mmup_smc_rstn_clr(void);
+
+#endif /* MMUP_COMMON_H */
diff --git a/plat/mediatek/drivers/vcp/rv/rules.mk b/plat/mediatek/drivers/vcp/rv/rules.mk
new file mode 100644
index 0000000..e637067
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/rv/rules.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := vcp_rv_${MTK_SOC}
+
+PLAT_INCLUDES += -I${MTK_PLAT}/drivers/vcp/${MTK_SOC}
+
+LOCAL_SRCS-${CONFIG_MTK_TINYSYS_VCP} := ${LOCAL_DIR}/vcp_common.c
+LOCAL_SRCS-${CONFIG_MTK_TINYSYS_VCP} += ${LOCAL_DIR}/mmup_common.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/vcp/rv/vcp_common.c b/plat/mediatek/drivers/vcp/rv/vcp_common.c
new file mode 100644
index 0000000..9dfb133
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/rv/vcp_common.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <smccc_helpers.h>
+
+#include "mmup_common.h"
+#include <mtk_mmap_pool.h>
+#include <mtk_sip_svc.h>
+#include "vcp_helper.h"
+#include "vcp_reg.h"
+
+#define MODULE_TAG "[VCP]"
+
+static const mmap_region_t vcp_mmap[] MTK_MMAP_SECTION = {
+ MAP_REGION_FLAT(VCP_R_CFGREG, MTK_VCP_REG_BANK_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(VCP_R_CFGREG_CORE0, MTK_VCP_REG_BANK_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(VCP_R_CFGREG_CORE1, MTK_VCP_REG_BANK_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(VCP_R_SEC_CTRL, MTK_VCP_REG_BANK_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ {0}
+};
+DECLARE_MTK_MMAP_REGIONS(vcp_mmap);
+
+/* vcp-mmup l2tcm memory offset */
+static uint64_t g_l2tcm_offset;
+static uint32_t g_mmup_fw_size;
+
+static bool get_vcp_pwr_status(void)
+{
+#if defined(SPM_BASE)
+ uint32_t spm_pwr_sta = mmio_read_32(SPM_BASE + VCP_POWER_STATUS);
+
+ if (!(spm_pwr_sta & (MMUP_PWR_STA_EN << MMUP_PWR_STA_BIT))) {
+ ERROR("%s: pwr_sta:%x, bit:%d disable\n", MODULE_TAG,
+ spm_pwr_sta, MMUP_PWR_STA_BIT);
+ return false;
+ }
+#endif
+ return true;
+}
+
+uint32_t get_mmup_fw_size(void)
+{
+ return g_mmup_fw_size;
+}
+
+uint64_t get_mmup_l2tcm_offset(void)
+{
+ return g_l2tcm_offset;
+}
+
+static bool vcp_cold_boot_reset(void)
+{
+ mmio_write_32(VCP_GPR2_CFGREG_SEC, 0);
+ mmio_write_32(VCP_GPR3_CFGREG_SEC, 0);
+
+ return true;
+}
+
+static bool mmup_cold_boot_reset(void)
+{
+ mmio_write_32(VCP_GPR0_CFGREG_SEC, 0);
+ mmio_write_32(VCP_GPR1_CFGREG_SEC, 0);
+
+ return true;
+}
+
+static bool vcp_set_mmup_l2tcm_offset(uint64_t l2tcm_offset)
+{
+ g_l2tcm_offset = l2tcm_offset;
+
+ if (g_l2tcm_offset > MTK_VCP_SRAM_SIZE) {
+ g_l2tcm_offset = 0;
+ return false;
+ }
+
+ return true;
+}
+
+static bool vcp_set_mmup_fw_size(uint64_t fw_size)
+{
+ g_mmup_fw_size = fw_size;
+
+ if (g_mmup_fw_size > MTK_VCP_SRAM_SIZE - g_l2tcm_offset) {
+ g_mmup_fw_size = 0;
+ return false;
+ }
+
+ return true;
+}
+
+static bool vcp_smc_rstn_set(bool boot_ok)
+{
+ if (mmio_read_32(VCP_GPR_C0_H0_REBOOT) != 0 &&
+ mmio_read_32(VCP_R_CORE0_STATUS) != 0 &&
+ (mmio_read_32(VCP_R_GIPC_IN_SET) & B_GIPC3_SETCLR_1) == 0 &&
+ (mmio_read_32(VCP_R_GIPC_IN_CLR) & B_GIPC3_SETCLR_1) == 0 &&
+ mmio_read_32(VCP_GPR_C0_H0_REBOOT) != VCP_CORE_RDY_TO_REBOOT &&
+ mmio_read_32(VCP_GPR_C0_H1_REBOOT) != VCP_CORE_RDY_TO_REBOOT) {
+ ERROR("%s: [%s] mmup reset set fail!GIPC 0x%x 0x%x REBOOT 0x%x 0x%x\n",
+ MODULE_TAG, __func__, mmio_read_32(VCP_R_GIPC_IN_SET),
+ mmio_read_32(VCP_R_GIPC_IN_CLR),
+ mmio_read_32(VCP_GPR_C0_H0_REBOOT),
+ mmio_read_32(VCP_GPR_C0_H1_REBOOT));
+ return false;
+ }
+
+ mmio_write_32(VCP_R_CORE0_SW_RSTN_SET, BIT(0));
+
+ /* reset sec control */
+ mmio_write_32(VCP_R_SEC_CTRL_2, 0);
+
+ /* reset domain setting */
+ mmio_write_32(VCP_R_S_DOM_EN0_31, 0x0);
+ mmio_write_32(VCP_R_S_DOM_EN32_63, 0x0);
+ mmio_write_32(VCP_R_NS_DOM_EN0_31, 0x0);
+ mmio_write_32(VCP_R_NS_DOM_EN32_63, 0x0);
+
+ /* reset sec setting */
+ mmio_clrbits_32(VCP_R_DYN_SECURE,
+ RESET_NS_SECURE_B_REGION << VCP_NS_SECURE_B_REGION_ENABLE);
+
+ if (boot_ok) {
+ mmio_write_32(VCP_GPR_C0_H0_REBOOT, VCP_CORE_REBOOT_OK);
+ mmio_write_32(VCP_GPR_C0_H1_REBOOT, VCP_CORE_REBOOT_OK);
+ }
+
+ dsbsy();
+ return true;
+}
+
+static bool vcp_smc_rstn_clr(void)
+{
+ if ((mmio_read_32(VCP_R_CORE0_SW_RSTN_SET) & BIT(0)) == 1) {
+ ERROR("%s: [%s] mmup not reset set !\n", MODULE_TAG, __func__);
+ return false;
+ }
+
+ mmio_clrsetbits_32(VCP_R_SEC_DOMAIN,
+ ~(VCP_DOMAIN_MASK << VCP_HWCCF_DOMAIN), VCP_DOMAIN_SET);
+
+ /* enable IOVA Mode */
+ mmio_write_32(VCP_R_AXIOMMUEN_DEV_APC, BIT(0));
+
+ /* reset secure setting */
+ mmio_setbits_32(VCP_R_SEC_CTRL_2, CORE0_SEC_BIT_SEL);
+ mmio_clrbits_32(VCP_R_DYN_SECURE, VCP_NS_I0 | VCP_NS_D0);
+ mmio_clrbits_32(VCP_R_DYN_SECURE_TH1, VCP_NS_I1 | VCP_NS_D1);
+
+ /* start vcp */
+ mmio_write_32(VCP_R_CORE0_SW_RSTN_CLR, BIT(0));
+ dsbsy();
+ return true;
+}
+
+static u_register_t tinysys_vcp_kernel_control(u_register_t arg0,
+ u_register_t arg1,
+ u_register_t arg2,
+ u_register_t arg3,
+ void *handle,
+ struct smccc_res *smccc_ret)
+{
+ uint32_t request_ops;
+ uint64_t ret = MTK_SIP_E_SUCCESS;
+
+ if (!get_vcp_pwr_status())
+ return MTK_SIP_E_NOT_SUPPORTED;
+
+ request_ops = (uint32_t)arg0;
+
+ switch (request_ops) {
+ case MTK_TINYSYS_VCP_KERNEL_OP_RESET_SET:
+ ret = vcp_smc_rstn_set((bool)!!arg1);
+ break;
+ case MTK_TINYSYS_VCP_KERNEL_OP_RESET_RELEASE:
+ ret = vcp_smc_rstn_clr();
+ break;
+ case MTK_TINYSYS_VCP_KERNEL_OP_COLD_BOOT_VCP:
+ ret = vcp_cold_boot_reset();
+ break;
+ case MTK_TINYSYS_MMUP_KERNEL_OP_RESET_SET:
+ ret = mmup_smc_rstn_set((bool)!!arg1);
+ break;
+ case MTK_TINYSYS_MMUP_KERNEL_OP_RESET_RELEASE:
+ ret = mmup_smc_rstn_clr();
+ break;
+ case MTK_TINYSYS_MMUP_KERNEL_OP_SET_L2TCM_OFFSET:
+ ret = vcp_set_mmup_l2tcm_offset(arg1);
+ break;
+ case MTK_TINYSYS_MMUP_KERNEL_OP_SET_FW_SIZE:
+ ret = vcp_set_mmup_fw_size(arg1);
+ break;
+ case MTK_TINYSYS_MMUP_KERNEL_OP_COLD_BOOT_MMUP:
+ ret = mmup_cold_boot_reset();
+ break;
+ default:
+ ERROR("%s: %s, unknown request_ops = %x\n", MODULE_TAG, __func__, request_ops);
+ ret = MTK_SIP_E_INVALID_PARAM;
+ break;
+ }
+
+ return ret;
+}
+
+/* Register SiP SMC service */
+DECLARE_SMC_HANDLER(MTK_SIP_KERNEL_VCP_CONTROL, tinysys_vcp_kernel_control);
diff --git a/plat/mediatek/include/mtk_sip_def.h b/plat/mediatek/include/mtk_sip_def.h
index a86a46c..ff12408 100644
--- a/plat/mediatek/include/mtk_sip_def.h
+++ b/plat/mediatek/include/mtk_sip_def.h
@@ -17,7 +17,8 @@
_func(MTK_SIP_AUDIO_CONTROL, 0x517) \
_func(MTK_SIP_APUSYS_CONTROL, 0x51E) \
_func(MTK_SIP_DP_CONTROL, 0x523) \
- _func(MTK_SIP_KERNEL_GIC_OP, 0x526)
+ _func(MTK_SIP_KERNEL_GIC_OP, 0x526) \
+ _func(MTK_SIP_KERNEL_VCP_CONTROL, 0x52C)
#define MTK_SIP_SMC_FROM_S_EL1_TABLE(_func) \
_func(MTK_SIP_TEE_MPU_PERM_SET, 0x031)
diff --git a/plat/mediatek/mt8196/plat_config.mk b/plat/mediatek/mt8196/plat_config.mk
index dd83b9a..dc78701 100644
--- a/plat/mediatek/mt8196/plat_config.mk
+++ b/plat/mediatek/mt8196/plat_config.mk
@@ -36,6 +36,7 @@
CONFIG_MTK_CPU_SUSPEND_EN := y
CONFIG_MTK_SPM_VERSION := mt8196
CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND := y
+CONFIG_MTK_TINYSYS_VCP := y
CPU_PM_TINYSYS_SUPPORT := y
MTK_PUBEVENT_ENABLE := y
diff --git a/plat/mediatek/mt8196/platform.mk b/plat/mediatek/mt8196/platform.mk
index 062735b..0d6ca24 100644
--- a/plat/mediatek/mt8196/platform.mk
+++ b/plat/mediatek/mt8196/platform.mk
@@ -28,6 +28,7 @@
MODULES-y += $(MTK_PLAT)/drivers/dp
MODULES-y += $(MTK_PLAT)/drivers/mcusys
MODULES-y += $(MTK_PLAT)/drivers/timer
+MODULES-y += $(MTK_PLAT)/drivers/vcp
MODULES-y += $(MTK_PLAT)/helpers
MODULES-y += $(MTK_PLAT)/topology