feat(mt8196): add SPM basic features support

This patch mainly collects and organizes SPM state information to
facilitate debugging when issues arise.

Signed-off-by: Wenzhen Yu <wenzhen.yu@mediatek.com>
Change-Id: Ie51cffeb1d683d65d88701fc63c426b20b22492f
diff --git a/plat/mediatek/drivers/spm/mt8196/mt_spm_dispatcher.c b/plat/mediatek/drivers/spm/mt8196/mt_spm_dispatcher.c
new file mode 100644
index 0000000..879b20d
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8196/mt_spm_dispatcher.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <lpm_v2/mt_lpm_dispatch.h>
+#include <lpm_v2/mt_lpm_smc.h>
+#include <mt_spm_conservation.h>
+#include <mt_spm_dispatcher.h>
+#include <mt_spm_internal.h>
+#include <mt_spm_reg.h>
+#include <mt_spm_smc.h>
+#include <mt_spm_suspend.h>
+#include <pcm_def.h>
+
+#define SPM_FW_BASE_SIZE	0x100000
+
+static void mt_spm_pcm_wdt(int enable, uint64_t time)
+{
+	mmio_write_32(PCM_TIMER_VAL, time);
+	__spm_set_pcm_wdt(enable);
+}
+
+static uint32_t mt_spm_phypll_mode_check(void)
+{
+	uint32_t val = mmio_read_32(SPM_POWER_ON_VAL0);
+
+	return val;
+}
+
+static uint64_t mt_spm_compatible_smc_id(uint64_t lp_id)
+{
+	switch (lp_id) {
+	case MT_LPM_SPMC_COMPAT_LK_FW_INIT:
+		lp_id = MT_SPM_SMC_UID_FW_INIT;
+		break;
+	default:
+		break;
+	}
+	return lp_id;
+}
+
+uint64_t mt_spm_dispatcher(u_register_t lp_id, u_register_t act,
+			   u_register_t arg1, u_register_t arg2,
+			   void *handle, struct smccc_res *smccc_ret)
+{
+	uint64_t ret = 0;
+
+	if (act & MT_LPM_SMC_ACT_COMPAT) {
+		lp_id = mt_spm_compatible_smc_id(lp_id);
+		act &= ~(MT_LPM_SMC_ACT_COMPAT);
+	}
+
+	switch (lp_id) {
+	case MT_SPM_SMC_UID_STATUS:
+		if (!(arg2 & MT_SPM_STATUS_SUSPEND_SLEEP))
+			break;
+		if (act & MT_LPM_SMC_ACT_SET)
+			/* Legacy audio check from kernel */
+			mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SLEEP, NULL);
+		else if (act & MT_LPM_SMC_ACT_CLR)
+			mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SYSTEM_PDN,
+						NULL);
+		break;
+	case MT_SPM_SMC_UID_PCM_WDT:
+		if (act & MT_LPM_SMC_ACT_SET)
+			mt_spm_pcm_wdt(1, arg2);
+		else if (act & MT_LPM_SMC_ACT_CLR)
+			mt_spm_pcm_wdt(0, arg2);
+		break;
+	case MT_SPM_SMC_UID_PHYPLL_MODE:
+		if (act & MT_LPM_SMC_ACT_GET)
+			ret = mt_spm_phypll_mode_check();
+		break;
+	case MT_SPM_SMC_UID_SET_PENDING_IRQ_INIT:
+		spm_set_irq_num((uint32_t)arg1);
+		break;
+	default:
+		break;
+	}
+	return ret;
+}
+
+int mt_spm_dispatcher_init(void)
+{
+	mt_lpm_dispatcher_registry(MT_LPM_SMC_USER_SPM,
+				   mt_spm_dispatcher);
+	return 0;
+}
diff --git a/plat/mediatek/drivers/spm/mt8196/mt_spm_dispatcher.h b/plat/mediatek/drivers/spm/mt8196/mt_spm_dispatcher.h
new file mode 100644
index 0000000..cf6d11c
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8196/mt_spm_dispatcher.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_DISPATCHER_H
+#define MT_SPM_DISPATCHER_H
+
+int mt_spm_dispatcher_init(void);
+#endif /* MT_SPM_DISPATCHER_H */
diff --git a/plat/mediatek/drivers/spm/mt8196/mt_spm_hwreq.c b/plat/mediatek/drivers/spm/mt8196/mt_spm_hwreq.c
new file mode 100644
index 0000000..1d6c9d8
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8196/mt_spm_hwreq.c
@@ -0,0 +1,707 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <mt_spm_hwreq.h>
+#include <mt_spm_reg.h>
+
+/* Ddren, apsrc and emi resource have become hw resource_req.
+ * So we don't need to use HW CG for request resource.
+ */
+#define SPM_HWCG_DDREN_PWR_MB		0
+#define SPM_HWCG_DDREN_PWR_MSB_MB	0
+#define SPM_HWCG_DDREN_MODULE_BUSY_MB	0
+
+/* VRF18 */
+#define SPM_HWCG_VRF18_PWR_MB		0
+#define SPM_HWCG_VRF18_PWR_MSB_MB	0
+#define SPM_HWCG_VRF18_MODULE_BUSY_MB	0
+
+/* INFRA */
+#define SPM_HWCG_INFRA_PWR_MB		SPM_HWCG_VRF18_PWR_MB
+#define SPM_HWCG_INFRA_PWR_MSB_MB	SPM_HWCG_VRF18_PWR_MSB_MB
+#define SPM_HWCG_INFRA_MODULE_BUSY_MB	0
+
+/* PMIC */
+#define SPM_HWCG_PMIC_PWR_MB		SPM_HWCG_VRF18_PWR_MB
+#define SPM_HWCG_PMIC_PWR_MSB_MB	SPM_HWCG_VRF18_PWR_MSB_MB
+#define SPM_HWCG_PMIC_MODULE_BUSY_MB	0
+
+/* F26M */
+#define SPM_HWCG_F26M_PWR_MB		SPM_HWCG_PMIC_PWR_MB
+#define SPM_HWCG_F26M_PWR_MSB_MB	SPM_HWCG_PMIC_PWR_MSB_MB
+#define SPM_HWCG_F26M_MODULE_BUSY_MB	0
+
+/* VCORE */
+#define SPM_HWCG_VCORE_PWR_MB		SPM_HWCG_F26M_PWR_MB
+#define SPM_HWCG_VCORE_PWR_MSB_MB	SPM_HWCG_F26M_PWR_MSB_MB
+#define SPM_HWCG_VCORE_MODULE_BUSY_MB	SPM_HWCG_F26M_MODULE_BUSY_MB
+
+#define INFRA_SW_CG_MB			0
+
+struct spm_hwcg_info {
+	uint32_t pwr;
+	uint32_t pwr_msb;
+	uint32_t module_busy;
+};
+
+#define HWCG_INFO_INIT(_info) ({ \
+	_info.pwr = _info.pwr_msb = _info.module_busy = 0; })
+
+#define DECLARE_HWCG_REG(_name_, _info) ({ \
+	_info.pwr = REG_PWR_STATUS_##_name_##_REQ_MASK; \
+	_info.pwr_msb = REG_PWR_STATUS_MSB_##_name_##_REQ_MASK; \
+	_info.module_busy = REG_MODULE_BUSY_##_name_##_REQ_MASK; })
+
+#define DECLARE_HWCG_DEFAULT(_name_, _info) ({ \
+	_info.pwr = SPM_HWCG_##_name_##_PWR_MB; \
+	_info.pwr_msb = SPM_HWCG_##_name_##_PWR_MSB_MB; \
+	_info.module_busy = SPM_HWCG_##_name_##_MODULE_BUSY_MB; })
+
+#define PERI_REQ_EN_INFO_INIT(_info) ({_info.req_en = 0; })
+
+#define PERI_REQ_STA_INFO_INIT(_info) ({_info.req_sta = 0; })
+
+#define DECLARE_PERI_REQ_EN_REG(_offset, _info) ({ \
+	_info.req_en = REG_PERI_REQ_EN(_offset); })
+
+#define DECLARE_PERI_REQ_STA_REG(_offset, _info) ({ \
+	_info.req_sta = REG_PERI_REQ_STA(_offset); })
+
+#define DECLARE_PERI_REQ_DEFAULT(_name_, _info) ({ \
+	_info.req_en = PERI_REQ_##_name_##_MB; })
+
+#define PERI_REQ_EN_MASK		0x3FFFFF
+
+static uint32_t spm_hwcg_index2res(uint32_t idx)
+{
+	uint32_t res;
+
+	if (idx >= HWCG_MAX)
+		return 0;
+
+	switch (idx) {
+	case HWCG_DDREN:
+		res = (MT_SPM_DRAM_S0 | MT_SPM_DRAM_S1 | MT_SPM_EMI);
+		break;
+	case HWCG_VRF18:
+		res = MT_SPM_SYSPLL;
+		break;
+	case HWCG_INFRA:
+		res = MT_SPM_INFRA;
+		break;
+	case HWCG_PMIC:
+		res = MT_SPM_PMIC;
+		break;
+	case HWCG_F26M:
+		res = MT_SPM_26M;
+		break;
+	case HWCG_VCORE:
+		res = MT_SPM_VCORE;
+		break;
+	default:
+		res = 0;
+	}
+	return res;
+}
+
+static uint32_t spm_hwcg_ctrl_get(struct spm_hwcg_info *info,
+				  enum spm_hwcg_setting type)
+{
+	uint32_t reg = 0;
+
+	if (!info)
+		return 0;
+
+	switch (type) {
+	case HWCG_PWR:
+		reg = info->pwr;
+		break;
+	case HWCG_PWR_MSB:
+		reg = info->pwr_msb;
+		break;
+	default:
+		reg = info->module_busy;
+		break;
+	}
+	return reg;
+}
+
+static void __spm_hwcg_ctrl(struct spm_hwcg_info *info,
+			    enum spm_hwcg_setting type,
+			    uint32_t is_set, uint32_t val)
+{
+	uint32_t reg;
+
+	reg = spm_hwcg_ctrl_get(info, type);
+
+	if (!reg)
+		return;
+
+	if (is_set)
+		mmio_setbits_32(reg, val);
+	else
+		mmio_clrbits_32(reg, val);
+}
+
+void spm_hwcg_ctrl(uint32_t res, enum spm_hwcg_setting type,
+		   uint32_t is_set, uint32_t val)
+{
+	struct spm_hwcg_info info;
+
+	if (res & (MT_SPM_DRAM_S0 | MT_SPM_DRAM_S1 | MT_SPM_EMI))
+		DECLARE_HWCG_REG(DDREN, info);
+	else if (res & MT_SPM_SYSPLL)
+		DECLARE_HWCG_REG(VRF18, info);
+	else if (res & MT_SPM_INFRA)
+		DECLARE_HWCG_REG(INFRA, info);
+	else if (res & MT_SPM_PMIC)
+		DECLARE_HWCG_REG(PMIC, info);
+	else if (res & MT_SPM_26M)
+		DECLARE_HWCG_REG(F26M, info);
+	else if (res & MT_SPM_VCORE)
+		DECLARE_HWCG_REG(VCORE, info);
+	else
+		HWCG_INFO_INIT(info);
+
+	if (info.pwr)
+		__spm_hwcg_ctrl(&info, type, is_set, val);
+}
+
+void spm_hwcg_ctrl_by_index(uint32_t idx, enum spm_hwcg_setting type,
+			    uint32_t is_set, uint32_t val)
+{
+	uint32_t res = spm_hwcg_index2res(idx);
+
+	if (res)
+		spm_hwcg_ctrl(res, type, is_set, val);
+}
+
+static uint32_t spm_hwcg_mask_get(uint32_t res, enum spm_hwcg_setting type)
+{
+	struct spm_hwcg_info info;
+	uint32_t raw_val = 0, reg = 0;
+
+	if (res & (MT_SPM_DRAM_S0 | MT_SPM_DRAM_S1 | MT_SPM_EMI))
+		DECLARE_HWCG_REG(DDREN, info);
+	else if (res & MT_SPM_SYSPLL)
+		DECLARE_HWCG_REG(VRF18, info);
+	else if (res & MT_SPM_INFRA)
+		DECLARE_HWCG_REG(INFRA, info);
+	else if (res & MT_SPM_PMIC)
+		DECLARE_HWCG_REG(PMIC, info);
+	else if (res & MT_SPM_26M)
+		DECLARE_HWCG_REG(F26M, info);
+	else if (res & MT_SPM_VCORE)
+		DECLARE_HWCG_REG(VCORE, info);
+	else
+		HWCG_INFO_INIT(info);
+
+	if (!info.pwr)
+		return 0;
+
+	reg = spm_hwcg_ctrl_get(&info, type);
+
+	if (!reg)
+		return 0;
+
+	raw_val = ~mmio_read_32(reg);
+
+	return raw_val;
+}
+
+static uint32_t spm_hwcg_get_default(uint32_t res, enum spm_hwcg_setting type)
+{
+	struct spm_hwcg_info info;
+
+	if (res & (MT_SPM_DRAM_S0 | MT_SPM_DRAM_S1 | MT_SPM_EMI))
+		DECLARE_HWCG_DEFAULT(DDREN, info);
+	else if (res & MT_SPM_SYSPLL)
+		DECLARE_HWCG_DEFAULT(VRF18, info);
+	else if (res & MT_SPM_INFRA)
+		DECLARE_HWCG_DEFAULT(INFRA, info);
+	else if (res & MT_SPM_PMIC)
+		DECLARE_HWCG_DEFAULT(PMIC, info);
+	else if (res & MT_SPM_26M)
+		DECLARE_HWCG_DEFAULT(F26M, info);
+	else if (res & MT_SPM_VCORE)
+		DECLARE_HWCG_DEFAULT(VCORE, info);
+	else
+		HWCG_INFO_INIT(info);
+
+	if (!info.pwr)
+		return 0;
+
+	return spm_hwcg_ctrl_get(&info, type);
+}
+
+uint32_t spm_hwcg_get_status(uint32_t idx, enum spm_hwcg_setting type)
+{
+	uint32_t val = 0;
+
+	switch (type) {
+	case HWCG_PWR:
+		val = mmio_read_32(PWR_STATUS);
+		break;
+	case HWCG_PWR_MSB:
+		val = mmio_read_32(PWR_STATUS_MSB);
+		break;
+	default:
+		break;
+	}
+	return val;
+}
+
+int spm_hwcg_get_setting(uint32_t res, enum spm_hwcg_sta_type sta_type,
+			 enum spm_hwcg_setting type,
+			 struct spm_hwcg_sta *sta)
+{
+	int ret = 0;
+
+	if (!sta)
+		return -1;
+
+	switch (sta_type) {
+	case HWCG_STA_DEFAULT_MASK:
+		sta->sta = spm_hwcg_get_default(res, type);
+		break;
+	case HWCG_STA_MASK:
+		sta->sta = spm_hwcg_mask_get(res, type);
+		break;
+	default:
+		ret = -1;
+		MT_SPM_HW_CG_STA_INIT(sta);
+		break;
+	}
+	return ret;
+}
+
+int spm_hwcg_get_setting_by_index(uint32_t idx,
+				  enum spm_hwcg_sta_type sta_type,
+				  enum spm_hwcg_setting type,
+				  struct spm_hwcg_sta *sta)
+{
+	uint32_t res = spm_hwcg_index2res(idx);
+
+	return spm_hwcg_get_setting(res, sta_type, type, sta);
+}
+
+int spm_hwcg_name(uint32_t idex, char *name, size_t sz)
+{
+	int ret = 0;
+
+	if (!name)
+		return -1;
+
+	switch (idex) {
+	case HWCG_DDREN:
+		ret = snprintf(name, sz - 1, "dram");
+		break;
+	case HWCG_VRF18:
+		ret = snprintf(name, sz - 1, "vrf18");
+		break;
+	case HWCG_INFRA:
+		ret = snprintf(name, sz - 1, "infra");
+		break;
+	case HWCG_PMIC:
+		ret = snprintf(name, sz - 1, "pmic");
+		break;
+	case HWCG_F26M:
+		ret = snprintf(name, sz - 1, "26m");
+		break;
+	case HWCG_VCORE:
+		ret = snprintf(name, sz - 1, "vcore");
+		break;
+	default:
+		ret = -1;
+		break;
+	}
+
+	if (ret < 0)
+		ret = -1;
+
+	name[sz-1] = '\0';
+
+	return ret;
+}
+
+static void spm_infra_swcg_init(void)
+{
+	mmio_write_32(INFRA_SW_CG_MASK, ~INFRA_SW_CG_MB);
+}
+
+static void spm_hwcg_init(void)
+{
+	/* HW CG for ddren, apsrc, emi resource req */
+	mmio_write_32(REG_PWR_STATUS_DDREN_REQ_MASK,
+		      ~SPM_HWCG_DDREN_PWR_MB);
+	mmio_write_32(REG_PWR_STATUS_MSB_DDREN_REQ_MASK,
+		      ~SPM_HWCG_DDREN_PWR_MSB_MB);
+	mmio_write_32(REG_MODULE_BUSY_DDREN_REQ_MASK,
+		      ~SPM_HWCG_DDREN_MODULE_BUSY_MB);
+
+	/* HW CG for vrf18 resource req */
+	mmio_write_32(REG_PWR_STATUS_VRF18_REQ_MASK,
+		      ~SPM_HWCG_VRF18_PWR_MB);
+	mmio_write_32(REG_PWR_STATUS_MSB_VRF18_REQ_MASK,
+		      ~SPM_HWCG_VRF18_PWR_MSB_MB);
+	mmio_write_32(REG_MODULE_BUSY_VRF18_REQ_MASK,
+		      ~SPM_HWCG_VRF18_MODULE_BUSY_MB);
+
+	/* HW CG for infra resource req */
+	mmio_write_32(REG_PWR_STATUS_INFRA_REQ_MASK,
+		      ~SPM_HWCG_INFRA_PWR_MB);
+	mmio_write_32(REG_PWR_STATUS_MSB_INFRA_REQ_MASK,
+		      ~SPM_HWCG_INFRA_PWR_MSB_MB);
+	mmio_write_32(REG_MODULE_BUSY_INFRA_REQ_MASK,
+		      ~SPM_HWCG_INFRA_MODULE_BUSY_MB);
+
+	/* HW CG for pmic resource req */
+	mmio_write_32(REG_PWR_STATUS_PMIC_REQ_MASK,
+		      ~SPM_HWCG_PMIC_PWR_MB);
+	mmio_write_32(REG_PWR_STATUS_MSB_PMIC_REQ_MASK,
+		      ~SPM_HWCG_PMIC_PWR_MSB_MB);
+	mmio_write_32(REG_MODULE_BUSY_PMIC_REQ_MASK,
+		      ~SPM_HWCG_PMIC_MODULE_BUSY_MB);
+
+	/* HW CG for f26m resource req */
+	mmio_write_32(REG_PWR_STATUS_F26M_REQ_MASK,
+		      ~SPM_HWCG_F26M_PWR_MB);
+	mmio_write_32(REG_PWR_STATUS_MSB_F26M_REQ_MASK,
+		      ~SPM_HWCG_F26M_PWR_MSB_MB);
+	mmio_write_32(REG_MODULE_BUSY_F26M_REQ_MASK,
+		      ~SPM_HWCG_F26M_MODULE_BUSY_MB);
+
+	/* HW CG for vcore resource req */
+	mmio_write_32(REG_PWR_STATUS_VCORE_REQ_MASK,
+		      ~SPM_HWCG_VCORE_PWR_MB);
+	mmio_write_32(REG_PWR_STATUS_MSB_VCORE_REQ_MASK,
+		      ~SPM_HWCG_VCORE_PWR_MSB_MB);
+	mmio_write_32(REG_MODULE_BUSY_VCORE_REQ_MASK,
+		      ~SPM_HWCG_VCORE_MODULE_BUSY_MB);
+}
+
+#define PERI_CG(ofs)		(PERICFG_AO_BASE + 0x10 + (0x4 * (ofs)))
+#define PERI_REQ_DEFAULT_MB	(BIT(PERI_REQ_EN_FLASHIF) | \
+				 BIT(PERI_REQ_EN_AP_DMA) | \
+				 BIT(PERI_REQ_EN_UART1) | \
+				 BIT(PERI_REQ_EN_UART2) | \
+				 BIT(PERI_REQ_EN_UART4) | \
+				 BIT(PERI_REQ_EN_UART5) | \
+				 BIT(PERI_REQ_EN_PWM) | \
+				 BIT(PERI_REQ_EN_SPI0) | \
+				 BIT(PERI_REQ_EN_SPI0_INCR16) | \
+				 BIT(PERI_REQ_EN_SPI1) | \
+				 BIT(PERI_REQ_EN_SPI2) | \
+				 BIT(PERI_REQ_EN_SPI3) | \
+				 BIT(PERI_REQ_EN_SPI4) | \
+				 BIT(PERI_REQ_EN_SPI5) | \
+				 BIT(PERI_REQ_EN_SPI6) | \
+				 BIT(PERI_REQ_EN_SPI7) | \
+				 BIT(PERI_REQ_EN_IMP_IIC))
+
+/* For MSDC reqesut WA: PERI_REQ_EN_RSV_FOR_MSDC */
+#define PERI_REQ_APSRC_MB		(PERI_REQ_DEFAULT_MB | \
+					 BIT(PERI_REQ_EN_RSV_FOR_MSDC))
+
+#define PERI_REQ_DDREN_MB		(PERI_REQ_DEFAULT_MB | \
+					 BIT(PERI_REQ_EN_USB) | \
+					 BIT(PERI_REQ_EN_UFS0) | \
+					 BIT(PERI_REQ_EN_PEXTP1) | \
+					 BIT(PERI_REQ_EN_PEXTP0) | \
+					 BIT(PERI_REQ_EN_PERI_BUS_TRAFFIC))
+#define PERI_REQ_EMI_MB		(PERI_REQ_DEFAULT_MB)
+#define PERI_REQ_INFRA_MB	(PERI_REQ_DEFAULT_MB)
+#define PERI_REQ_SYSPLL_MB	(PERI_REQ_DEFAULT_MB)
+#define PERI_REQ_F26M_MB	(PERI_REQ_DEFAULT_MB)
+
+uint32_t spm_peri_req_get_status(uint32_t idx, enum spm_peri_req_status type)
+{
+	uint32_t val = 0, reg = 0;
+	struct spm_peri_req_info info;
+
+	switch (type) {
+	case PERI_RES_REQ_EN:
+
+		switch (idx) {
+		case PERI_REQ_DDREN:
+			DECLARE_PERI_REQ_STA_REG(PERI_REQ_DDREN, info);
+
+			break;
+		case PERI_REQ_EMI:
+			DECLARE_PERI_REQ_STA_REG(PERI_REQ_EMI, info);
+
+			break;
+		case PERI_REQ_APSRC:
+			DECLARE_PERI_REQ_STA_REG(PERI_REQ_APSRC, info);
+
+			break;
+		case PERI_REQ_SYSPLL:
+			DECLARE_PERI_REQ_STA_REG(PERI_REQ_SYSPLL, info);
+
+			break;
+		case PERI_REQ_INFRA:
+			DECLARE_PERI_REQ_STA_REG(PERI_REQ_INFRA, info);
+
+			break;
+		case PERI_REQ_F26M:
+			DECLARE_PERI_REQ_STA_REG(PERI_REQ_F26M, info);
+
+			break;
+		default:
+			PERI_REQ_STA_INFO_INIT(info);
+			break;
+		}
+
+		if (!info.req_sta)
+			return 0;
+
+		reg = info.req_sta;
+		val = (mmio_read_32(reg) & PERI_REQ_EN_MASK);
+
+		break;
+	default:
+		break;
+	}
+	return val;
+}
+
+int spm_peri_req_name(uint32_t idex, char *name, size_t sz)
+{
+	int ret = 0;
+
+	if (!name)
+		return -1;
+
+	switch (idex) {
+	case PERI_REQ_DDREN:
+		ret = snprintf(name, sz - 1, "ddren");
+		break;
+	case PERI_REQ_EMI:
+		ret = snprintf(name, sz - 1, "emi");
+		break;
+	case PERI_REQ_APSRC:
+		ret = snprintf(name, sz - 1, "apsrc");
+		break;
+	case PERI_REQ_SYSPLL:
+		ret = snprintf(name, sz - 1, "syspll");
+		break;
+	case PERI_REQ_INFRA:
+		ret = snprintf(name, sz - 1, "infra");
+		break;
+	case PERI_REQ_F26M:
+		ret = snprintf(name, sz - 1, "26m_pmic_vcore");
+		break;
+	default:
+		ret = -1;
+		break;
+	}
+
+	if (ret < 0)
+		ret = -1;
+
+	name[sz-1] = '\0';
+
+	return ret;
+}
+
+uint32_t spm_peri_req_get_status_raw(enum spm_peri_req_status_raw type,
+				     uint32_t idx,
+				     char *name, size_t sz)
+{
+	return 0;
+}
+
+static uint32_t spm_peri_req_get_default(uint32_t res)
+{
+	struct spm_peri_req_info info;
+
+	if (res & MT_SPM_DRAM_S1)
+		DECLARE_PERI_REQ_DEFAULT(DDREN, info);
+	else if (res & MT_SPM_EMI)
+		DECLARE_PERI_REQ_DEFAULT(EMI, info);
+	else if (res & MT_SPM_DRAM_S0)
+		DECLARE_PERI_REQ_DEFAULT(APSRC, info);
+	else if (res & MT_SPM_SYSPLL)
+		DECLARE_PERI_REQ_DEFAULT(SYSPLL, info);
+	else if (res & MT_SPM_INFRA)
+		DECLARE_PERI_REQ_DEFAULT(INFRA, info);
+	else if (res & (MT_SPM_PMIC | MT_SPM_26M | MT_SPM_VCORE))
+		DECLARE_PERI_REQ_DEFAULT(F26M, info);
+	else
+		PERI_REQ_EN_INFO_INIT(info);
+
+	return info.req_en;
+}
+
+static uint32_t spm_peri_req_mask_get(uint32_t res)
+{
+	struct spm_peri_req_info info;
+	uint32_t raw_val = 0, reg = 0;
+
+	if (res & MT_SPM_DRAM_S1)
+		DECLARE_PERI_REQ_EN_REG(PERI_REQ_DDREN, info);
+	else if (res & MT_SPM_EMI)
+		DECLARE_PERI_REQ_EN_REG(PERI_REQ_EMI, info);
+	else if (res & MT_SPM_DRAM_S0)
+		DECLARE_PERI_REQ_EN_REG(PERI_REQ_APSRC, info);
+	else if (res & MT_SPM_SYSPLL)
+		DECLARE_PERI_REQ_EN_REG(PERI_REQ_SYSPLL, info);
+	else if (res & MT_SPM_INFRA)
+		DECLARE_PERI_REQ_EN_REG(PERI_REQ_INFRA, info);
+	else if (res & (MT_SPM_PMIC | MT_SPM_26M | MT_SPM_VCORE))
+		DECLARE_PERI_REQ_EN_REG(PERI_REQ_F26M, info);
+	else
+		PERI_REQ_EN_INFO_INIT(info);
+
+	if (!info.req_en)
+		return 0;
+
+	reg = info.req_en;
+
+	raw_val = (mmio_read_32(reg) & PERI_REQ_EN_MASK);
+
+	return raw_val;
+}
+
+int spm_peri_req_get_setting(uint32_t res,
+			     enum spm_peri_req_sta_type sta_type,
+			     struct spm_peri_req_sta *sta)
+{
+	int ret = 0;
+
+	if (!sta)
+		return -1;
+
+	switch (sta_type) {
+	case PERI_REQ_STA_DEFAULT_MASK:
+		sta->sta = spm_peri_req_get_default(res);
+		break;
+	case PERI_REQ_STA_MASK:
+		sta->sta = spm_peri_req_mask_get(res);
+		break;
+	default:
+		ret = -1;
+		MT_SPM_HW_CG_STA_INIT(sta);
+		break;
+	}
+	return ret;
+}
+
+static uint32_t spm_peri_req_index2res(uint32_t idx)
+{
+	uint32_t res;
+
+	if (idx >= PERI_REQ_MAX)
+		return 0;
+
+	switch (idx) {
+	case PERI_REQ_DDREN:
+		res = MT_SPM_DRAM_S1;
+		break;
+	case PERI_REQ_EMI:
+		res = MT_SPM_EMI;
+		break;
+	case PERI_REQ_APSRC:
+		res = MT_SPM_DRAM_S0;
+		break;
+	case PERI_REQ_SYSPLL:
+		res = MT_SPM_SYSPLL;
+		break;
+	case PERI_REQ_INFRA:
+		res = MT_SPM_INFRA;
+		break;
+	case PERI_REQ_F26M:
+		res = (MT_SPM_PMIC | MT_SPM_26M | MT_SPM_VCORE);
+		break;
+	default:
+		res = 0;
+	}
+	return res;
+
+}
+
+int spm_peri_req_get_setting_by_index(uint32_t idx,
+				      enum spm_peri_req_sta_type sta_type,
+				      struct spm_peri_req_sta *sta)
+{
+	uint32_t res = spm_peri_req_index2res(idx);
+
+	return spm_peri_req_get_setting(res, sta_type, sta);
+}
+
+static void __spm_peri_req_ctrl(struct spm_peri_req_info *info,
+				uint32_t is_set, uint32_t val)
+{
+	uint32_t raw_val, reg;
+
+	reg = info->req_en;
+
+	if (!reg)
+		return;
+
+	raw_val = (mmio_read_32(reg) & PERI_REQ_EN_MASK);
+
+	if (is_set)
+		raw_val |= val;
+	else
+		raw_val &= ~val;
+
+	mmio_write_32(reg, raw_val);
+}
+
+void spm_peri_req_ctrl(uint32_t res,
+		       uint32_t is_set, uint32_t val)
+{
+	struct spm_peri_req_info info;
+
+	if (res & MT_SPM_DRAM_S1)
+		DECLARE_PERI_REQ_EN_REG(PERI_REQ_DDREN, info);
+	else if (res & MT_SPM_EMI)
+		DECLARE_PERI_REQ_EN_REG(PERI_REQ_EMI, info);
+	else if (res & MT_SPM_DRAM_S0)
+		DECLARE_PERI_REQ_EN_REG(PERI_REQ_APSRC, info);
+	else if (res & MT_SPM_SYSPLL)
+		DECLARE_PERI_REQ_EN_REG(PERI_REQ_SYSPLL, info);
+	else if (res & MT_SPM_INFRA)
+		DECLARE_PERI_REQ_EN_REG(PERI_REQ_INFRA, info);
+	else if (res & (MT_SPM_PMIC | MT_SPM_26M | MT_SPM_VCORE))
+		DECLARE_PERI_REQ_EN_REG(PERI_REQ_F26M, info);
+	else
+		PERI_REQ_EN_INFO_INIT(info);
+
+	if (info.req_en)
+		__spm_peri_req_ctrl(&info, is_set, val);
+}
+
+void spm_peri_req_ctrl_by_index(uint32_t idx,
+				uint32_t is_set, uint32_t val)
+{
+	uint32_t res = spm_peri_req_index2res(idx);
+
+	if (res)
+		spm_peri_req_ctrl(res, is_set, val);
+}
+
+static void spm_peri_req_init(void)
+{
+	mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_DDREN), PERI_REQ_DDREN_MB);
+	mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_EMI), PERI_REQ_EMI_MB);
+	mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_APSRC), PERI_REQ_APSRC_MB);
+	mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_INFRA), PERI_REQ_INFRA_MB);
+	mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_SYSPLL), PERI_REQ_SYSPLL_MB);
+	mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_F26M), PERI_REQ_F26M_MB);
+}
+
+void spm_hwreq_init(void)
+{
+	spm_infra_swcg_init();
+	spm_hwcg_init();
+	spm_peri_req_init();
+}
diff --git a/plat/mediatek/drivers/spm/mt8196/mt_spm_hwreq.h b/plat/mediatek/drivers/spm/mt8196/mt_spm_hwreq.h
new file mode 100644
index 0000000..e403726
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8196/mt_spm_hwreq.h
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_HWREQ_H
+#define MT_SPM_HWREQ_H
+
+#include <drivers/spm/mt_spm_resource_req.h>
+
+/* Resource requirement which HW CG support */
+enum {
+	HWCG_DDREN = 0,
+	HWCG_VRF18,
+	HWCG_INFRA,
+	HWCG_PMIC,
+	HWCG_F26M,
+	HWCG_VCORE,
+	HWCG_MAX
+};
+
+/* Signal that monitor by HW CG  */
+enum spm_hwcg_setting {
+	HWCG_PWR,
+	HWCG_PWR_MSB,
+	HWCG_MODULE_BUSY,
+	HWCG_SETTING_MAX
+};
+
+enum spm_pwr_status {
+	HWCG_PWR_MD1 = 0,
+	HWCG_PWR_CONN,
+	HWCG_PWR_APIFR_IO,
+	HWCG_PWR_APIFR_MEM,
+	HWCG_PWR_PERI,
+	HWCG_PWR_PERI_ETHER,
+	HWCG_PWR_SSUSB_PD_PHY_P0,
+	HWCG_PWR_SSUSB_P0,
+	HWCG_PWR_SSUSB_P1,
+	HWCG_PWR_SSUSB_P23,
+	HWCG_PWR_SSUSB_PHY_P2,
+	HWCG_PWR_UFS0,
+	HWCG_PWR_UFS0_PHY,
+	HWCG_PWR_PEXTP_MAC0,
+	HWCG_PWR_PEXTP_MAC1,
+	HWCG_PWR_PEXTP_MAC2,
+	HWCG_PWR_PEXTP_PHY0,
+	HWCG_PWR_PEXTP_PHY1,
+	HWCG_PWR_PEXTP_PHY3,
+	HWCG_PWR_AUDIO,
+	HWCG_PWR_ADSP_CORE1,
+	HWCG_PWR_ADSP_TOP,
+	HWCG_PWR_ADSP_INFRA,
+	HWCG_PWR_ADSP_AO,
+	HWCG_PWR_MM_PROC,
+	HWCG_PWR_SCP,
+	HWCG_PWR_SCP2,
+	HWCG_PWR_DPYD0,
+	HWCG_PWR_DPYD1,
+	HWCG_PWR_DPYD2,
+	HWCG_PWR_DPYD3,
+	HWCG_PWR_DPYA0
+};
+
+CASSERT(HWCG_PWR_SSUSB_P1 == 8, spm_pwr_status_err);
+CASSERT(HWCG_PWR_PEXTP_PHY0 == 16, spm_pwr_status_err);
+CASSERT(HWCG_PWR_MM_PROC == 24, spm_pwr_status_err);
+
+enum spm_hwcg_module_busy {
+	HWCG_MODULE_ADSP = 0,
+	HWCG_MODULE_MMPLL,
+	HWCG_MODULE_TVDPLL,
+	HWCG_MODULE_MSDCPLL,
+	HWCG_MODULE_UNIVPLL
+};
+
+enum spm_hwcg_sta_type {
+	HWCG_STA_DEFAULT_MASK,
+	HWCG_STA_MASK
+};
+
+/* Signal that monitor by HW CG  */
+enum spm_peri_req_setting {
+	PERI_REQ_EN  = 0,
+	PERI_REQ_SETTING_MAX
+};
+
+/* Resource requirement which PERI REQ support */
+enum spm_peri_req {
+	PERI_REQ_F26M = 0,
+	PERI_REQ_INFRA,
+	PERI_REQ_SYSPLL,
+	PERI_REQ_APSRC,
+	PERI_REQ_EMI,
+	PERI_REQ_DDREN,
+	PERI_REQ_MAX
+};
+
+enum spm_peri_req_sta_type {
+	PERI_REQ_STA_DEFAULT_MASK,
+	PERI_REQ_STA_MASK,
+	PERI_REQ_STA_MAX
+};
+
+enum spm_peri_req_status {
+	PERI_RES_REQ_EN,
+	PERI_REQ_STATUS_MAX
+};
+
+enum spm_peri_req_status_raw {
+	PERI_REQ_STATUS_RAW_NUM,
+	PERI_REQ_STATUS_RAW_NAME,
+	PERI_REQ_STATUS_RAW_STA,
+	PERI_REQ_STATUS_RAW_MAX
+};
+
+enum spm_peri_req_en {
+	PERI_REQ_EN_FLASHIF = 0,
+	PERI_REQ_EN_AP_DMA,
+	PERI_REQ_EN_UART0,
+	PERI_REQ_EN_UART1,
+	PERI_REQ_EN_UART2,
+	PERI_REQ_EN_UART3,
+	PERI_REQ_EN_UART4,
+	PERI_REQ_EN_UART5,
+	PERI_REQ_EN_PWM,
+	PERI_REQ_EN_SPI0,
+	PERI_REQ_EN_SPI0_INCR16,
+	PERI_REQ_EN_SPI1,
+	PERI_REQ_EN_SPI2,
+	PERI_REQ_EN_SPI3,
+	PERI_REQ_EN_SPI4,
+	PERI_REQ_EN_SPI5,
+	PERI_REQ_EN_SPI6,
+	PERI_REQ_EN_SPI7,
+	PERI_REQ_EN_IMP_IIC,
+	PERI_REQ_EN_MSDC1,
+	PERI_REQ_EN_MSDC2,
+	PERI_REQ_EN_USB,
+	PERI_REQ_EN_UFS0,
+	PERI_REQ_EN_PEXTP1,
+	PERI_REQ_EN_PEXTP0,
+	PERI_REQ_EN_RSV_DUMMY0,
+	PERI_REQ_EN_PERI_BUS_TRAFFIC,
+	PERI_REQ_EN_RSV_DUMMY1,
+	PERI_REQ_EN_RSV_FOR_MSDC,
+	PERI_REQ_EN_MAX
+};
+
+CASSERT(PERI_REQ_EN_PWM == 8, spm_peri_req_en_err);
+CASSERT(PERI_REQ_EN_SPI6 == 16, spm_peri_req_en_err);
+CASSERT(PERI_REQ_EN_PEXTP0 == 24, spm_peri_req_en_err);
+
+struct spm_peri_req_sta {
+	uint32_t sta;
+};
+
+struct spm_peri_req_info {
+	uint32_t req_en;
+	uint32_t req_sta;
+};
+
+struct spm_hwcg_sta {
+	uint32_t sta;
+};
+
+#define MT_SPM_HW_CG_STA_INIT(_x)	({ if (_x) _x->sta = 0; })
+
+#define INFRA_AO_OFFSET(offset)		(INFRACFG_AO_BASE + offset)
+#define INFRA_SW_CG_MASK		INFRA_AO_OFFSET(0x060)
+
+#define REG_PERI_REQ_EN(N)	(PERICFG_AO_BASE + 0x070 + 0x4 * (N))
+#define REG_PERI_REQ_STA(N)	(PERICFG_AO_BASE + 0x0A0 + 0x4 * (N))
+
+void spm_hwreq_init(void);
+
+/* Res:
+ *	Please refer the mt_spm_resource_req.h.
+ *	Section of SPM resource request internal bit_mask.
+ */
+void spm_hwcg_ctrl(uint32_t res, enum spm_hwcg_setting type,
+		   uint32_t is_set, uint32_t val);
+
+/* Idx:
+ *	index of HWCG setting.
+ */
+void spm_hwcg_ctrl_by_index(uint32_t idx, enum spm_hwcg_setting type,
+			    uint32_t is_set, uint32_t val);
+
+/* Res:
+ *	Please refer the mt_spm_resource_req.h.
+ *	Section of SPM resource request internal bit_mask.
+ */
+int spm_hwcg_get_setting(uint32_t res, enum spm_hwcg_sta_type sta_type,
+			 enum spm_hwcg_setting type,
+			 struct spm_hwcg_sta *sta);
+
+/* Idx:
+ *	index of HWCG setting.
+ */
+int spm_hwcg_get_setting_by_index(uint32_t idx,
+				  enum spm_hwcg_sta_type sta_type,
+				  enum spm_hwcg_setting type,
+				  struct spm_hwcg_sta *sta);
+
+uint32_t spm_hwcg_get_status(uint32_t idx, enum spm_hwcg_setting type);
+
+int spm_hwcg_name(uint32_t idex, char *name, size_t sz);
+
+static inline uint32_t spm_hwcg_num(void)
+{
+	return HWCG_MAX;
+}
+
+static inline uint32_t spm_hwcg_setting_num(void)
+{
+	return HWCG_SETTING_MAX;
+}
+
+uint32_t spm_peri_req_get_status(uint32_t idx, enum spm_peri_req_status type);
+uint32_t spm_peri_req_get_status_raw(enum spm_peri_req_status_raw type,
+				     uint32_t idx,
+				     char *name, size_t sz);
+
+static inline uint32_t spm_peri_req_num(void)
+{
+	return PERI_REQ_MAX;
+}
+
+static inline uint32_t spm_peri_req_setting_num(void)
+{
+	return PERI_REQ_SETTING_MAX;
+}
+
+int spm_peri_req_get_setting_by_index(uint32_t idx,
+				      enum spm_peri_req_sta_type sta_type,
+				      struct spm_peri_req_sta *sta);
+
+void spm_peri_req_ctrl_by_index(uint32_t idx,
+				uint32_t is_set, uint32_t val);
+
+int spm_peri_req_name(uint32_t idex, char *name, size_t sz);
+
+#endif /* MT_SPM_HWREQ_H */
diff --git a/plat/mediatek/drivers/spm/mt8196/mt_spm_stats.c b/plat/mediatek/drivers/spm/mt8196/mt_spm_stats.c
new file mode 100644
index 0000000..adf784d
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8196/mt_spm_stats.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+
+#include <mt_spm.h>
+#include <mt_spm_reg.h>
+#include <mt_spm_stats.h>
+
+#define READ_AND_MASK_16BIT(addr)	(mmio_read_32(addr) & 0xFFFF)
+
+void mt_spm_update_lp_stat(struct spm_lp_stat *stat)
+{
+	if (!stat)
+		return;
+
+	stat->record[SPM_STAT_MCUSYS].count += 1;
+	stat->record[SPM_STAT_MCUSYS].duration +=
+			mmio_read_32(SPM_BK_PCM_TIMER);
+	stat->record[SPM_STAT_D1_2].count +=
+			READ_AND_MASK_16BIT(SPM_APSRC_EVENT_COUNT_STA);
+	stat->record[SPM_STAT_D2].count +=
+			READ_AND_MASK_16BIT(SPM_EMI_EVENT_COUNT_STA);
+	stat->record[SPM_STAT_D3].count +=
+			READ_AND_MASK_16BIT(SPM_VRF18_EVENT_COUNT_STA);
+	stat->record[SPM_STAT_D4].count +=
+			READ_AND_MASK_16BIT(SPM_INFRA_EVENT_COUNT_STA);
+	stat->record[SPM_STAT_D6X].count +=
+			READ_AND_MASK_16BIT(SPM_PMIC_EVENT_COUNT_STA);
+	stat->record[SPM_STAT_F26M].count +=
+			READ_AND_MASK_16BIT(SPM_SRCCLKENA_EVENT_COUNT_STA);
+	stat->record[SPM_STAT_F26M].duration +=
+			READ_AND_MASK_16BIT(SPM_BK_VTCXO_DUR);
+	stat->record[SPM_STAT_VCORE].count +=
+			READ_AND_MASK_16BIT(SPM_VCORE_EVENT_COUNT_STA);
+	stat->record[SPM_STAT_VCORE].duration +=
+			mmio_read_32(SPM_SW_RSV_4);
+}
+
+uint64_t mt_spm_get_lp_stat(struct spm_lp_stat *stat,
+			    uint32_t index, uint32_t type)
+{
+
+	uint64_t ret;
+
+	if (!stat || index >= NUM_SPM_STAT)
+		return 0;
+
+	switch (type) {
+	case SPM_SLP_COUNT:
+		ret = stat->record[index].count;
+		break;
+	case SPM_SLP_DURATION:
+		ret = stat->record[index].duration;
+		break;
+	default:
+		ret = 0;
+		break;
+	}
+
+	return ret;
+}
diff --git a/plat/mediatek/drivers/spm/mt8196/mt_spm_stats.h b/plat/mediatek/drivers/spm/mt8196/mt_spm_stats.h
new file mode 100644
index 0000000..6ec7156
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8196/mt_spm_stats.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_STATS_H
+#define MT_SPM_STATS_H
+
+#include <stdint.h>
+
+enum spm_stat_type {
+	SPM_SLP_COUNT,
+	SPM_SLP_DURATION,
+};
+
+enum spm_stat_state {
+	SPM_STAT_MCUSYS,
+	SPM_STAT_F26M,
+	SPM_STAT_VCORE,
+	SPM_STAT_D1_2,
+	SPM_STAT_D2,
+	SPM_STAT_D3,
+	SPM_STAT_D4,
+	SPM_STAT_D6X,
+	NUM_SPM_STAT,
+};
+
+struct spm_lp_stat_record {
+	uint64_t count;
+	uint64_t duration;
+};
+
+struct spm_lp_stat {
+	struct spm_lp_stat_record record[NUM_SPM_STAT];
+};
+
+void mt_spm_update_lp_stat(struct spm_lp_stat *stat);
+
+uint64_t mt_spm_get_lp_stat(struct spm_lp_stat *stat,
+			    uint32_t index, uint32_t type);
+
+#endif /* MT_SPM_STATS_H */
diff --git a/plat/mediatek/drivers/spm/mt8196/pcm_def.h b/plat/mediatek/drivers/spm/mt8196/pcm_def.h
new file mode 100644
index 0000000..1e29bc6
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8196/pcm_def.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PCM_DEF_H
+#define PCM_DEF_H
+
+#define CTRL0_SC_26M_CK_OFF			BIT(0)
+#define CTRL0_SC_VLP_BUS_CK_OFF			BIT(1)
+#define CTRL0_SC_PMIF_CK_OFF			BIT(2)
+#define CTRL0_SC_AXI_CK_OFF			BIT(3)
+#define CTRL0_SC_AXI_MEM_CK_OFF			BIT(4)
+#define CTRL0_SC_MD26M_CK_OFF			BIT(5)
+#define CTRL0_SC_MD32K_CK_OFF			BIT(6)
+#define CTRL0_SC_VLP_26M_CLK_SEL		BIT(7)
+#define CTRL0_SC_26M_CK_SEL			BIT(8)
+#define CTRL0_SC_TOP_26M_CLK_SEL		BIT(9)
+#define CTRL0_SC_SYS_TIMER_CLK_32K_SEL		BIT(10)
+#define CTRL0_SC_CIRQ_CLK_32K_SEL		BIT(11)
+#define CTRL0_SC_AXI_DCM_DIS			BIT(12)
+#define CTRL0_SC_CKSQ0_OFF			BIT(13)
+#define CTRL0_SC_CKSQ1_OFF			BIT(14)
+#define CTRL0_VCORE_PWR_ISO			BIT(15)
+#define CTRL0_VCORE_PWR_ISO_PRE			BIT(16)
+#define CTRL0_VCORE_PWR_RST_B			BIT(17)
+#define CTRL0_VCORE_RESTORE_ENABLE		BIT(18)
+#define CTRL0_SC_TOP_RESTORE_26M_CLK_SEL	BIT(19)
+#define CTRL0_AOC_VCORE_SRAM_ISO_DIN		BIT(20)
+#define CTRL0_AOC_VCORE_SRAM_LATCH_ENB		BIT(21)
+#define CTRL0_AOC_VCORE_ANA_ISO			BIT(22)
+#define CTRL0_AOC_VCORE_ANA_ISO_PRE		BIT(23)
+#define CTRL0_AOC_VLPTOP_SRAM_ISO_DIN		BIT(24)
+#define CTRL0_AOC_VLPTOP_SRAM_LATCH_ENB		BIT(25)
+#define CTRL0_AOC_VCORE_IO_ISO			BIT(26)
+#define CTRL0_AOC_VCORE_IO_LATCH_ENB		BIT(27)
+#define CTRL0_RTFF_VCORE_SAVE			BIT(28)
+#define CTRL0_RTFF_VCORE_NRESTORE		BIT(29)
+#define CTRL0_RTFF_VCORE_CLK_DIS		BIT(30)
+
+#define CTRL1_PWRAP_SLEEP_REQ			BIT(0)
+#define CTRL1_IM_SLP_EN				BIT(1)
+#define CTRL1_SPM_LEAVE_VCORE_OFF_REQ		BIT(2)
+#define CTRL1_SPM_CK_SEL0			BIT(4)
+#define CTRL1_SPM_CK_SEL1			BIT(5)
+#define CTRL1_TIMER_SET				BIT(6)
+#define CTRL1_TIMER_CLR				BIT(7)
+#define CTRL1_SPM_LEAVE_DEEPIDLE_REQ		BIT(8)
+#define CTRL1_SPM_LEAVE_SUSPEND_REQ		BIT(9)
+#define CTRL1_CSYSPWRUPACK			BIT(10)
+#define CTRL1_SRCCLKENO0			BIT(11)
+#define CTRL1_SRCCLKENO1			BIT(12)
+#define CTRL1_SRCCLKENO2			BIT(13)
+#define CTRL1_SPM_APSRC_INTERNAL_ACK		BIT(14)
+#define CTRL1_SPM_EMI_INTERNAL_ACK		BIT(15)
+#define CTRL1_SPM_DDREN_INTERNAL_ACK		BIT(16)
+#define CTRL1_SPM_INFRA_INTERNAL_ACK		BIT(17)
+#define CTRL1_SPM_VRF18_INTERNAL_ACK		BIT(18)
+#define CTRL1_SPM_VCORE_INTERNAL_ACK		BIT(19)
+#define CTRL1_SPM_VCORE_RESTORE_ACK		BIT(20)
+#define CTRL1_SPM_PMIC_INTERNAL_ACK		BIT(21)
+#define CTRL1_PMIC_IRQ_REQ_EN			BIT(22)
+#define CTRL1_WDT_KICK_P			BIT(23)
+#define CTRL1_FORCE_DDREN_WAKE			BIT(24)
+#define CTRL1_FORCE_F26M_WAKE			BIT(25)
+#define CTRL1_FORCE_APSRC_WAKE			BIT(26)
+#define CTRL1_FORCE_INFRA_WAKE			BIT(27)
+#define CTRL1_FORCE_VRF18_WAKE			BIT(28)
+#define CTRL1_FORCE_VCORE_WAKE			BIT(29)
+#define CTRL1_FORCE_EMI_WAKE			BIT(30)
+#define CTRL1_FORCE_PMIC_WAKE			BIT(31)
+
+
+#define CTRL2_MD32PCM_IRQ_TRIG_BIT		BIT(31)
+
+#define STA0_SRCCLKENI0				BIT(0)
+#define STA0_SRCCLKENI1				BIT(1)
+#define STA0_MD_SRCCLKENA			BIT(2)
+#define STA0_MD_SRCCLKENA1			BIT(3)
+#define STA0_MD_DDREN_REQ			BIT(4)
+#define STA0_CONN_DDREN_REQ			BIT(5)
+#define STA0_SSPM_SRCCLKENA			BIT(6)
+#define STA0_SSPM_APSRC_REQ			BIT(7)
+#define STA0_MD_STATE				BIT(8)
+#define STA0_RC2SPM_SRCCLKENO_0_ACK		BIT(9)
+#define STA0_MM_STATE				BIT(10)
+#define STA0_SSPM_STATE				BIT(11)
+#define STA0_CPUEB_STATE			BIT(12)
+#define STA0_CONN_STATE				BIT(13)
+#define STA0_CONN_VCORE_REQ			BIT(14)
+#define STA0_CONN_SRCCLKENA			BIT(15)
+#define STA0_CONN_SRCCLKENB			BIT(16)
+#define STA0_CONN_APSRC_REQ			BIT(17)
+#define STA0_SCP_STATE				BIT(18)
+#define STA0_CSYSPWRUPREQ			BIT(19)
+#define STA0_PWRAP_SLEEP_ACK			BIT(20)
+#define STA0_DPM_STATE				BIT(21)
+#define STA0_AUDIO_DSP_STATE			BIT(22)
+#define STA0_PMIC_IRQ_ACK			BIT(23)
+#define STA0_RESERVED_BIT_24			BIT(24)
+#define STA0_RESERVED_BIT_25			BIT(25)
+#define STA0_RESERVED_BIT_26			BIT(26)
+#define STA0_DVFS_STATE				BIT(27)
+#define STA0_RESERVED_BIT_28			BIT(28)
+#define STA0_RESERVED_BIT_29			BIT(29)
+#define STA0_SC_HW_S1_ACK_ALL			BIT(30)
+#define STA0_DDREN_STATE			BIT(31)
+
+#define R12_PCM_TIMER_B				BIT(0)
+#define R12_TWAM_PMSR_DVFSRC_ALCO		BIT(1)
+#define R12_KP_IRQ_B				BIT(2)
+#define R12_APWDT_EVENT_B			BIT(3)
+#define R12_APXGPT_EVENT_B			BIT(4)
+#define R12_CONN2AP_WAKEUP_B			BIT(5)
+#define R12_EINT_EVENT_B			BIT(6)
+#define R12_CONN_WDT_IRQ_B			BIT(7)
+#define R12_CCIF0_EVENT_B			BIT(8)
+#define R12_CCIF1_EVENT_B			BIT(9)
+#define R12_SSPM2SPM_WAKEUP_B			BIT(10)
+#define R12_SCP2SPM_WAKEUP_B			BIT(11)
+#define R12_ADSP2SPM_WAKEUP_B			BIT(12)
+#define R12_PCM_WDT_WAKEUP_B			BIT(13)
+#define R12_USB0_CDSC_B				BIT(14)
+#define R12_USB0_POWERDWN_B			BIT(15)
+#define R12_UART_EVENT_B			BIT(16)
+#define R12_DEBUGTOP_FLAG_IRQ_B			BIT(17)
+#define R12_SYS_TIMER_EVENT_B			BIT(18)
+#define R12_EINT_EVENT_SECURE_B			BIT(19)
+#define R12_AFE_IRQ_MCU_B			BIT(20)
+#define R12_THERM_CTRL_EVENT_B			BIT(21)
+#define R12_SYS_CIRQ_IRQ_B			BIT(22)
+#define R12_PBUS_EVENT_B			BIT(23)
+#define R12_CSYSPWREQ_B				BIT(24)
+#define R12_MD_WDT_B				BIT(25)
+#define R12_AP2AP_PEER_WAKEUP_B			BIT(26)
+#define R12_SEJ_B				BIT(27)
+#define R12_CPU_WAKEUP				BIT(28)
+#define R12_APUSYS_WAKE_HOST_B			BIT(29)
+#define R12_PCIE_WAKE_B				BIT(30)
+#define R12_MSDC_WAKE_B				BIT(31)
+
+#define EVENT_F26M_WAKE				BIT(0)
+#define EVENT_F26M_SLEEP			BIT(1)
+#define EVENT_INFRA_WAKE			BIT(2)
+#define EVENT_INFRA_SLEEP			BIT(3)
+#define EVENT_EMI_WAKE				BIT(4)
+#define EVENT_EMI_SLEEP				BIT(5)
+#define EVENT_APSRC_WAKE			BIT(6)
+#define EVENT_APSRC_SLEEP			BIT(7)
+#define EVENT_VRF18_WAKE			BIT(8)
+#define EVENT_VRF18_SLEEP			BIT(9)
+#define EVENT_DVFS_WAKE				BIT(10)
+#define EVENT_DDREN_WAKE			BIT(11)
+#define EVENT_DDREN_SLEEP			BIT(12)
+#define EVENT_VCORE_WAKE			BIT(13)
+#define EVENT_VCORE_SLEEP			BIT(14)
+#define EVENT_PMIC_WAKE				BIT(15)
+#define EVENT_PMIC_SLEEP			BIT(16)
+#define EVENT_CPUEB_STATE			BIT(17)
+#define EVENT_SSPM_STATE			BIT(18)
+#define EVENT_DPM_STATE				BIT(19)
+#define EVENT_SPM_LEAVE_VCORE_OFF_ACK		BIT(20)
+#define EVENT_SW_SSPM_ADSP_SCP_MAILBOX_WAKE	BIT(21)
+#define EVENT_SPM_LEAVE_SUSPEND_ACK		BIT(22)
+#define EVENT_SPM_LEAVE_DEEPIDLE_ACK		BIT(23)
+#define EVENT_CROSS_REQ_APU_l3			BIT(24)
+#define EVENT_DFD_SOC_MTCMOS_REQ_IPIC_WAKE	BIT(25)
+#define EVENT_AOVBUS_WAKE			BIT(26)
+#define EVENT_AOVBUS_SLEEP			BIT(27)
+
+enum SPM_WAKE_SRC_LIST {
+	WAKE_SRC_STA1_PCM_TIMER = BIT(0),
+	WAKE_SRC_STA1_TWAM_PMSR_DVFSRC = BIT(1),
+	WAKE_SRC_STA1_KP_IRQ_B = BIT(2),
+	WAKE_SRC_STA1_APWDT_EVENT_B = BIT(3),
+	WAKE_SRC_STA1_APXGPT1_EVENT_B = BIT(4),
+	WAKE_SRC_STA1_CONN2AP_SPM_WAKEUP_B = BIT(5),
+	WAKE_SRC_STA1_EINT_EVENT_B = BIT(6),
+	WAKE_SRC_STA1_CONN_WDT_IRQ_B = BIT(7),
+	WAKE_SRC_STA1_CCIF0_EVENT_B = BIT(8),
+	WAKE_SRC_STA1_CCIF1_EVENT_B = BIT(9),
+	WAKE_SRC_STA1_SC_SSPM2SPM_WAKEUP_B = BIT(10),
+	WAKE_SRC_STA1_SC_SCP2SPM_WAKEUP_B = BIT(11),
+	WAKE_SRC_STA1_SC_ADSP2SPM_WAKEUP_B = BIT(12),
+	WAKE_SRC_STA1_PCM_WDT_WAKEUP_B = BIT(13),
+	WAKE_SRC_STA1_USB_CDSC_B = BIT(14),
+	WAKE_SRC_STA1_USB_POWERDWN_B = BIT(15),
+	WAKE_SRC_STA1_AP_UART_B = BIT(16),
+	WAKE_SRC_STA1_DEBUGTOP_FLAG_IRQ_B = BIT(17),
+	WAKE_SRC_STA1_SYS_TIMER_EVENT_B = BIT(18),
+	WAKE_SRC_STA1_EINT_EVENT_SECURE_B = BIT(19),
+	WAKE_SRC_STA1_AFE_IRQ_MCU_B = BIT(20),
+	WAKE_SRC_STA1_THERM_CTRL_EVENT_B = BIT(21),
+	WAKE_SRC_STA1_SYS_CIRQ_IRQ_B = BIT(22),
+	WAKE_SRC_STA1_PBUS_EVENT_B = BIT(23),
+	WAKE_SRC_STA1_CSYSPWREQ_B = BIT(24),
+	WAKE_SRC_STA1_MD1_WDT_B = BIT(25),
+	WAKE_SRC_STA1_AP2AP_PEER_WAKEUPEVENT_B = BIT(26),
+	WAKE_SRC_STA1_SEJ_EVENT_B = BIT(27),
+	WAKE_SRC_STA1_SPM_CPU_WAKEUPEVENT_B = BIT(28),
+	WAKE_SRC_STA1_APUSYS_WAKE_HOST_B = BIT(29),
+	WAKE_SRC_STA1_PCIE_B = BIT(30),
+	WAKE_SRC_STA1_MSDC_B = BIT(31),
+};
+
+extern const char *wakesrc_str[32];
+
+#endif /* PCM_DEF_H */
diff --git a/plat/mediatek/drivers/spm/mt8196/sleep_def.h b/plat/mediatek/drivers/spm/mt8196/sleep_def.h
new file mode 100644
index 0000000..1860416
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8196/sleep_def.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SLEEP_DEF_H
+#define SLEEP_DEF_H
+
+/* --- SPM Flag Define --- */
+#define SPM_FLAG_DISABLE_INFRA_PDN			BIT(0)
+#define SPM_FLAG_DISABLE_DPM_PDN			BIT(1)
+#define SPM_FLAG_DISABLE_MCUPM_PDN			BIT(2)
+#define SPM_FLAG_RESERVED_BIT_3				BIT(3)
+#define SPM_FLAG_DISABLE_VLP_PDN			BIT(4)
+#define SPM_FLAG_DISABLE_VLPCLK_SWITCH			BIT(5)
+#define SPM_FLAG_DISABLE_SSPM_SRAM_SLEEP		BIT(6)
+#define SPM_FLAG_RESERVED_BIT_7				BIT(7)
+#define SPM_FLAG_DISABLE_VCORE_DVS			BIT(8)
+#define SPM_FLAG_DISABLE_DDR_DFS			BIT(9)
+#define SPM_FLAG_DISABLE_EMI_DFS			BIT(10)
+#define SPM_FLAG_DISABLE_BUS_DFS			BIT(11)
+#define SPM_FLAG_DISABLE_COMMON_SCENARIO		BIT(12)
+#define SPM_FLAG_RESERVED_BIT_13			BIT(13)
+#define SPM_FLAG_RESERVED_BIT_14			BIT(14)
+#define SPM_FLAG_RESERVED_BIT_15			BIT(15)
+#define SPM_FLAG_KEEP_CSYSPWRACK_HIGH			BIT(16)
+#define SPM_FLAG_ENABLE_MT8196_IVI			BIT(17)
+#define SPM_FLAG_ENABLE_SPM_DBG_WDT_DUMP		BIT(18)
+#define SPM_FLAG_RUN_COMMON_SCENARIO			BIT(19)
+#define SPM_FLAG_USE_SRCCLKENO2				BIT(20)
+#define SPM_FLAG_ENABLE_AOV				BIT(21)
+#define SPM_FLAG_ENABLE_MD_MUMTAS			BIT(22)
+#define SPM_FLAG_ENABLE_COMMON_SODI5			BIT(23)
+#define SPM_FLAG_ENABLE_MT8196_E1_WA			BIT(24)
+#define SPM_FLAG_ENABLE_MT8196_EMI_E1_WA		BIT(25)
+#define SPM_FLAG_VCORE_STATE				BIT(26)
+#define SPM_FLAG_VTCXO_STATE				BIT(27)
+#define SPM_FLAG_INFRA_STATE				BIT(28)
+#define SPM_FLAG_APSRC_STATE				BIT(29)
+#define SPM_FLAG_VRF18_STATE				BIT(30)
+#define SPM_FLAG_DDREN_STATE				BIT(31)
+
+/* --- SPM Flag1 Define --- */
+#define SPM_FLAG1_DISABLE_AXI_BUS_TO_26M		BIT(0)
+#define SPM_FLAG1_DISABLE_SYSPLL_OFF			BIT(1)
+#define SPM_FLAG1_DISABLE_PWRAP_CLK_SWITCH		BIT(2)
+#define SPM_FLAG1_DISABLE_CSOPLU_OFF			BIT(3)
+#define SPM_FLAG1_FW_SET_CSOPLU_ON			BIT(4)
+#define SPM_FLAG1_DISABLE_EMI_CLK_TO_CSOPLU		BIT(5)
+#define SPM_FLAG1_DISABLE_NO_RESUME			BIT(6)
+#define SPM_FLAG1_RESERVED_BIT_7			BIT(7)
+#define SPM_FLAG1_RESERVED_BIT_8			BIT(8)
+#define SPM_FLAG1_RESERVED_BIT_9			BIT(9)
+#define SPM_FLAG1_DISABLE_SRCLKEN_LOW			BIT(10)
+#define SPM_FLAG1_DISABLE_SCP_CLK_SWITCH		BIT(11)
+#define SPM_FLAG1_DISABLE_TOP_26M_CK_OFF		BIT(12)
+#define SPM_FLAG1_DISABLE_PCM_26M_SWITCH		BIT(13)
+#define SPM_FLAG1_DISABLE_CKSQ_OFF			BIT(14)
+#define SPM_FLAG1_DO_DPSW_0P725V			BIT(15)
+#define SPM_FLAG1_ENABLE_ALCO_TRACE			BIT(16)
+#define SPM_FLAG1_ENABLE_SUSPEND_AVS			BIT(17)
+#define SPM_FLAG1_DISABLE_TVCORE_OFF			BIT(18)
+#define SPM_FLAG1_ENABLE_CSOPLU_OFF			BIT(19)
+#define SPM_FLAG1_DISABLE_INFRA_SRAM_SLEEP		BIT(20)
+#define SPM_FLAG1_DISABLE_AXI_MEM_CLK_OFF		BIT(21)
+#define SPM_FLAG1_RESERVED_BIT_22			BIT(22)
+#define SPM_FLAG1_RESERVED_BIT_23			BIT(23)
+#define SPM_FLAG1_DISABLE_SCP_VREQ_MASK_CONTROL		BIT(24)
+#define SPM_FLAG1_RESERVED_BIT_25			BIT(25)
+#define SPM_FLAG1_RESERVED_BIT_26			BIT(26)
+#define SPM_FLAG1_RESERVED_BIT_27			BIT(27)
+#define SPM_FLAG1_RESERVED_BIT_28			BIT(28)
+#define SPM_FLAG1_RESERVED_BIT_29			BIT(29)
+#define SPM_FLAG1_ENABLE_WAKE_PROF			BIT(30)
+#define SPM_FLAG1_ENABLE_SLEEP_PROF			BIT(31)
+
+/* --- SPM DEBUG Define --- */
+#define SPM_DBG_DEBUG_IDX_26M_WAKE			BIT(0)
+#define SPM_DBG_DEBUG_IDX_26M_SLEEP			BIT(1)
+#define SPM_DBG_DEBUG_IDX_INFRA_WAKE			BIT(2)
+#define SPM_DBG_DEBUG_IDX_INFRA_SLEEP			BIT(3)
+#define SPM_DBG_DEBUG_IDX_APSRC_WAKE			BIT(4)
+#define SPM_DBG_DEBUG_IDX_APSRC_SLEEP			BIT(5)
+#define SPM_DBG_DEBUG_IDX_VRF18_WAKE			BIT(6)
+#define SPM_DBG_DEBUG_IDX_VRF18_SLEEP			BIT(7)
+#define SPM_DBG_DEBUG_IDX_VCORE_WAKE			BIT(8)
+#define SPM_DBG_DEBUG_IDX_VCORE_SLEEP			BIT(9)
+#define SPM_DBG_DEBUG_IDX_DDREN_WAKE			BIT(10)
+#define SPM_DBG_DEBUG_IDX_DDREN_SLEEP			BIT(11)
+#define SPM_DBG_DEBUG_IDX_PMIC_WAKE			BIT(12)
+#define SPM_DBG_DEBUG_IDX_PMIC_SLEEP			BIT(13)
+#define SPM_DBG_DEBUG_IDX_EMI_WAKE			BIT(14)
+#define SPM_DBG_DEBUG_IDX_EMI_SLEEP			BIT(15)
+#define SPM_DBG_DEBUG_IDX_AOVBUS_WAKE			BIT(16)
+#define SPM_DBG_DEBUG_IDX_AOVBUS_SLEEP			BIT(17)
+#define SPM_DBG_DEBUG_IDX_CURRENT_IS_CM			BIT(18)
+#define SPM_DBG_DEBUG_IDX_SYSRAM_ON			BIT(19)
+#define SPM_DBG_DEBUG_IDX_WAIT_SSPM			BIT(20)
+#define SPM_DBG_DEBUG_IDX_SSPM_SRAM_SLP			BIT(21)
+#define SPM_DBG_DEBUG_IDX_SSPM_SRAM_ON			BIT(22)
+#define SPM_DBG_DEBUG_IDX_SPM_DVFS_NO_REQ		BIT(23)
+#define SPM_DBG_DEBUG_IDX_VCORE_LP_MODE		        BIT(24)
+#define SPM_DBG_DEBUG_IDX_SPM_NORMAL_WAKEUP		BIT(28)
+#define SPM_DBG_DEBUG_IDX_SPM_WAKEUP_BY_NONE		BIT(29)
+/* --- SPM DEBUG1 Define --- */
+#define SPM_DBG1_DEBUG_IDX_CURRENT_IS_LP		BIT(0)
+#define SPM_DBG1_DEBUG_IDX_VCORE_DVFS_START		BIT(1)
+#define SPM_DBG1_DEBUG_IDX_SYSPLL_OFF			BIT(2)
+#define SPM_DBG1_DEBUG_IDX_SYSPLL_ON			BIT(3)
+#define SPM_DBG1_DEBUG_IDX_VMDDRVDDQ_ON			BIT(4)
+#define SPM_DBG1_DEBUG_IDX_INFRA_MTCMOS_OFF		BIT(5)
+#define SPM_DBG1_DEBUG_IDX_INFRA_MTCMOS_ON		BIT(6)
+#define SPM_DBG1_DEBUG_IDX_VTCXO_SLEEP_ABORT_0		BIT(7)
+#define SPM_DBG1_DEBUG_IDX_VTCXO_SLEEP_ABORT_1		BIT(8)
+#define SPM_DBG1_DEBUG_IDX_VCORE_SLEEP_ABORT_0		BIT(9)
+#define SPM_DBG1_DEBUG_IDX_VCORE_SLEEP_ABORT_1		BIT(10)
+#define SPM_DBG1_DEBUG_IDX_PWRAP_CLK_TO_CSOPLU		BIT(11)
+#define SPM_DBG1_DEBUG_IDX_PWRAP_CLK_TO_26M		BIT(12)
+#define SPM_DBG1_DEBUG_IDX_SCP_CLK_TO_32K		BIT(13)
+#define SPM_DBG1_DEBUG_IDX_SCP_CLK_TO_26M		BIT(14)
+#define SPM_DBG1_DEBUG_IDX_BUS_CLK_OFF			BIT(15)
+#define SPM_DBG1_DEBUG_IDX_BUS_CLK_ON			BIT(16)
+#define SPM_DBG1_DEBUG_IDX_SRCLKEN2_LOW			BIT(17)
+#define SPM_DBG1_DEBUG_IDX_SRCLKEN2_HIGH		BIT(18)
+#define SPM_DBG1_RESERVED_BIT_19			BIT(19)
+#define SPM_DBG1_DEBUG_IDX_CSOPLU_IS_OFF_BUT_SHOULD_ON	BIT(20)
+#define SPM_DBG1_DEBUG_IDX_PMIC_IRQ_ACK_LOW_ABORT	BIT(21)
+#define SPM_DBG1_DEBUG_IDX_PMIC_IRQ_ACK_HIGH_ABORT	BIT(22)
+#define SPM_DBG1_DEBUG_IDX_PWRAP_SLEEP_ACK_LOW_ABORT	BIT(23)
+#define SPM_DBG1_DEBUG_IDX_PWRAP_SLEEP_ACK_HIGH_ABORT	BIT(24)
+#define SPM_DBG1_DEBUG_IDX_VMDDRVDDQ_OFF		BIT(25)
+#define SPM_DBG1_DEBUG_IDX_SCP_SLP_ACK_LOW_ABORT	BIT(26)
+#define SPM_DBG1_DEBUG_IDX_SCP_SLP_ACK_HIGH_ABORT	BIT(27)
+#define SPM_DBG1_DEBUG_IDX_SPM_PMIF_CMD_RDY_ABORT	BIT(28)
+#define SPM_DBG1_DEBUG_IDX_EMI_PDN_RDY_ABORT		BIT(29)
+#define SPM_DBG1_DEBUG_IDX_LVTS_WRONG_DEVICE_ID		BIT(30)
+#define SPM_DBG1_DEBUG_IDX_DISABLE_DVFSRC		BIT(31)
+
+/* --- SPM PCM_WDT_LATCH3 Define --- */
+#define SPM_WDT_LATCH3_RESOURCE_STATE_AOV_INFRA_ON	BIT(0)
+#define SPM_WDT_LATCH3_RESOURCE_STATE_26M_INFRA_ON	BIT(1)
+#define SPM_WDT_LATCH3_RESOURCE_STATE_AOV_CLK_ON	BIT(2)
+#define SPM_WDT_LATCH3_RESOURCE_STATE_26M_CLK_ON	BIT(3)
+#define SPM_WDT_LATCH3_RESOURCE_STATE_AOV_EMI_ON	BIT(4)
+#define SPM_WDT_LATCH3_RESOURCE_STATE_26M_EMI_ON	BIT(5)
+#endif /* SLEEP_DEF_H */
diff --git a/plat/mediatek/mt8196/include/platform_def.h b/plat/mediatek/mt8196/include/platform_def.h
index 1c01483..330b825 100644
--- a/plat/mediatek/mt8196/include/platform_def.h
+++ b/plat/mediatek/mt8196/include/platform_def.h
@@ -273,4 +273,59 @@
  ******************************************************************************/
 #define SYSTIMER_BASE		(0x1C400000)
 
+/*******************************************************************************
+ * CKSYS related constants
+ ******************************************************************************/
+#define CKSYS_BASE		(IO_PHYS)
+
+/*******************************************************************************
+ * VLP AO related constants
+ ******************************************************************************/
+#define VLPCFG_BUS_BASE		(IO_PHYS + 0x0C001000)
+#define VLPCFG_BUS_SIZE		(0x1000)
+#define VLP_AO_DEVAPC_APB_BASE	(IO_PHYS + 0x0C550000)
+#define VLP_AO_DEVAPC_APB_SIZE	(0x1000)
+
+/*******************************************************************************
+ * SCP registers
+ ******************************************************************************/
+#define SCP_CLK_CTRL_BASE	(IO_PHYS + 0x0CF21000)
+#define SCP_CLK_CTRL_SIZE	(0x1000)
+
+#define SCP_CFGREG_BASE		(IO_PHYS + 0x0CF24000)
+#define SCP_CFGREG_SIZE		(0x1000)
+
+/*******************************************************************************
+ * VLP CKSYS related constants
+ ******************************************************************************/
+#define VLP_CKSYS_BASE		(IO_PHYS + 0x0C016000)
+#define VLP_CKSYS_SIZE		0x1000
+
+/*******************************************************************************
+ * PERI related constants use PERI secure address to garuantee access
+ ******************************************************************************/
+#define PERICFG_AO_SIZE		0x1000
+#define PERI_CG0_STA		(PERICFG_AO_BASE + 0x10)
+#define PERI_CLK_CON		(PERICFG_AO_BASE + 0x20)
+#define PERI_CG1_CLR		(PERICFG_AO_BASE + 0x30)
+
+/******************************************************************************
+ * LPM syssram related constants
+ *****************************************************************************/
+#define MTK_LPM_SRAM_BASE	0x11B000
+#define MTK_LPM_SRAM_MAP_SIZE	0x1000
+
+/*******************************************************************************
+ * SSPM_MBOX_3 related constants
+ ******************************************************************************/
+#define SSPM_MBOX_3_BASE	(IO_PHYS + 0x0C380000)
+#define SSPM_MBOX_3_SIZE	0x1000
+
+/*******************************************************************************
+ * SSPM related constants
+ ******************************************************************************/
+#define SSPM_REG_OFFSET		(0x40000)
+#define SSPM_CFGREG_BASE	(IO_PHYS + 0x0C300000 + SSPM_REG_OFFSET)
+#define SSPM_CFGREG_SIZE	(0x1000)
+
 #endif /* PLATFORM_DEF_H */