diff --git a/plat/mediatek/drivers/spm/common/dbg_ctrl.h b/plat/mediatek/drivers/spm/common/dbg_ctrl.h
new file mode 100644
index 000000000..aea2fb8b1
--- /dev/null
+++ b/plat/mediatek/drivers/spm/common/dbg_ctrl.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DBG_CTRL_H
+#define DBG_CTRL_H
+
+/* SPM_WAKEUP_MISC */
+#define WAKE_MISC_TWAM		BIT(18)
+#define WAKE_MISC_PCM_TIMER	BIT(19)
+#define WAKE_MISC_CPU_WAKE	BIT(20)
+
+struct dbg_ctrl {
+	uint32_t count;
+	uint32_t duration;
+	void *ext;
+};
+
+enum dbg_ctrl_enum {
+	DBG_CTRL_COUNT,
+	DBG_CTRL_DURATION,
+	DBG_CTRL_MAX,
+};
+
+#endif /* DBG_CTRL_H */
diff --git a/plat/mediatek/drivers/spm/common/mt_spm_common.h b/plat/mediatek/drivers/spm/common/mt_spm_common.h
new file mode 100644
index 000000000..b44361ed4
--- /dev/null
+++ b/plat/mediatek/drivers/spm/common/mt_spm_common.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights resrved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_COMMON_H
+#define MT_SPM_COMMON_H
+
+#include <lib/bakery_lock.h>
+#include <lib/spinlock.h>
+/*
+ * ARM v8.2, the cache will turn off automatically when cpu
+ * power down. So, there is no doubt to use the spin_lock here
+ */
+#if !HW_ASSISTED_COHERENCY
+#define MT_SPM_USING_BAKERY_LOCK
+#endif
+
+#ifdef MT_SPM_USING_BAKERY_LOCK
+DECLARE_BAKERY_LOCK(spm_lock);
+#define plat_spm_lock() \
+	bakery_lock_get(&spm_lock)
+
+#define plat_spm_unlock() \
+	bakery_lock_release(&spm_lock)
+#else
+extern spinlock_t spm_lock;
+#define plat_spm_lock() \
+	spin_lock(&spm_lock)
+
+#define plat_spm_unlock() \
+	spin_unlock(&spm_lock)
+#endif
+
+#define MT_SPM_ERR_NO_FW_LOAD		-1
+#define MT_SPM_ERR_KICKED		-2
+#define MT_SPM_ERR_RUNNING		-3
+#define MT_SPM_ERR_FW_NOT_FOUND		-4
+#define MT_SPM_ERR_INVALID		-5
+#define MT_SPM_ERR_OVERFLOW		-6
+
+static inline void spm_lock_get(void)
+{
+	plat_spm_lock();
+}
+
+static inline void spm_lock_release(void)
+{
+	plat_spm_unlock();
+}
+
+#endif /* MT_SPM_COMMON_H */
diff --git a/plat/mediatek/drivers/spm/common/mt_spm_constraint.h b/plat/mediatek/drivers/spm/common/mt_spm_constraint.h
new file mode 100644
index 000000000..0dbbfb344
--- /dev/null
+++ b/plat/mediatek/drivers/spm/common/mt_spm_constraint.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_CONSTRAINT_H
+#define MT_SPM_CONSTRAINT_H
+
+#include <lpm_v2/mt_lp_rm.h>
+
+#define MT_RM_CONSTRAINT_ALLOW_CPU_BUCK_OFF	BIT(0)
+#define MT_RM_CONSTRAINT_ALLOW_DRAM_S0		BIT(1)
+#define MT_RM_CONSTRAINT_ALLOW_DRAM_S1		BIT(2)
+#define MT_RM_CONSTRAINT_ALLOW_VCORE_LP		BIT(3)
+#define MT_RM_CONSTRAINT_ALLOW_INFRA_PDN	BIT(4)
+#define MT_RM_CONSTRAINT_ALLOW_BUS26M_OFF	BIT(5)
+#define MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND	BIT(6) /* System suspend */
+#define MT_RM_CONSTRAINT_ALLOW_BBLPM		BIT(7)
+#define MT_RM_CONSTRAINT_ALLOW_XO_UFS		BIT(8)
+#define MT_RM_CONSTRAINT_ALLOW_GPS_STATE	BIT(9)
+#define MT_RM_CONSTRAINT_ALLOW_LVTS_STATE	BIT(10)
+#define MT_RM_CONSTRAINT_ALLOW_AP_PLAT_SUSPEND	BIT(11) /* Kernel suspend */
+#define MT_RM_CONSTRAINT_ALLOW_VCORE_OFF	BIT(12)
+
+#define MT_SPM_RC_INVALID		0x0
+#define MT_SPM_RC_VALID_SW		BIT(0)
+#define MT_SPM_RC_VALID_FW		BIT(1)
+#define MT_SPM_RC_VALID_RESIDNECY	BIT(2)
+#define MT_SPM_RC_VALID_COND_CHECK	BIT(3)
+#define MT_SPM_RC_VALID_COND_LATCH	BIT(4)
+#define MT_SPM_RC_VALID_UFS_H8		BIT(5)
+#define MT_SPM_RC_VALID_FLIGHTMODE	BIT(6)
+#define MT_SPM_RC_VALID_XSOC_BBLPM	BIT(7)
+#define MT_SPM_RC_VALID_TRACE_EVENT	BIT(8)
+#define MT_SPM_RC_VALID_TRACE_TIME	BIT(9)
+#define MT_SPM_RC_VALID_NOTIFY		BIT(10)
+
+#define MT_SPM_RC_VALID		(MT_SPM_RC_VALID_SW | MT_SPM_RC_VALID_FW)
+
+#define IS_MT_RM_RC_READY(status) \
+	((status & MT_SPM_RC_VALID) == MT_SPM_RC_VALID)
+
+struct constraint_status {
+	uint16_t id;
+	uint16_t is_valid;
+	uint64_t is_cond_block;
+	uint32_t enter_cnt;
+	uint64_t all_pll_dump;
+	unsigned long long residency;
+	struct mt_spm_cond_tables *cond_res;
+};
+
+enum constraint_status_update_type {
+	CONSTRAINT_UPDATE_VALID,
+	CONSTRAINT_UPDATE_COND_CHECK,
+	CONSTRAINT_RESIDNECY,
+};
+
+enum constraint_status_get_type {
+	CONSTRAINT_GET_VALID = 0xD0000000,
+	CONSTRAINT_GET_ENTER_CNT,
+	CONSTRAINT_GET_RESIDENCY,
+	CONSTRAINT_GET_COND_EN,
+	CONSTRAINT_COND_BLOCK,
+	CONSTRAINT_GET_COND_BLOCK_LATCH,
+	CONSTRAINT_GET_COND_BLOCK_DETAIL,
+	CONSTRAINT_GET_RESIDNECY,
+};
+
+struct rc_common_state {
+	unsigned int id;
+	unsigned int act;
+	unsigned int type;
+	void *value;
+};
+
+#define MT_SPM_RC_BBLPM_MODE	(MT_SPM_RC_VALID_UFS_H8 | \
+				 MT_SPM_RC_VALID_FLIGHTMODE | \
+				 MT_SPM_RC_VALID_XSOC_BBLPM)
+
+#define IS_MT_SPM_RC_BBLPM_MODE(st) \
+	((st & (MT_SPM_RC_BBLPM_MODE)) == MT_SPM_RC_BBLPM_MODE)
+
+#define IS_MT_SPM_RC_NOTIFY_ENABLE(st) \
+	((st & (MT_SPM_RC_VALID_NOTIFY)))
+
+#define MT_SPM_RC_EXTERN_STATUS_SET(v, st)	({v |= (st & 0xffff); })
+#define MT_SPM_RC_EXTERN_STATUS_CLR(v, st)	({v &= ~(st & 0xffff); })
+
+#endif /* MT_SPM_CONSTRAINT_H */
diff --git a/plat/mediatek/drivers/spm/common/mt_spm_smc.h b/plat/mediatek/drivers/spm/common/mt_spm_smc.h
new file mode 100644
index 000000000..62f090f65
--- /dev/null
+++ b/plat/mediatek/drivers/spm/common/mt_spm_smc.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_SMC_H
+#define MT_SPM_SMC_H
+
+/*
+ * SPM dispatcher's smc id definition
+ * Please adding custom smc id here for spm dispatcher
+ */
+#define MT_SPM_STATUS_SUSPEND_SLEEP	BIT(27)
+
+enum mt_spm_smc_uid {
+	MT_SPM_SMC_UID_STATUS,
+	MT_SPM_SMC_UID_PCM_WDT,
+	MT_SPM_SMC_UID_PCM_TIMER,
+	MT_SPM_SMC_UID_FW_TYPE,
+	MT_SPM_SMC_UID_PHYPLL_MODE,
+	MT_SPM_SMC_UID_SET_PENDING_IRQ_INIT,
+	MT_SPM_SMC_UID_FW_INIT = 0x5731,
+};
+
+/*
+ * SPM dbg dispatcher's smc id definition
+ * Please adding custom smc id here for spm dbg dispatcher
+ */
+enum mt_spm_dbg_smc_uid {
+	MT_SPM_DBG_SMC_UID_IDLE_PWR_CTRL,
+	MT_SPM_DBG_SMC_UID_IDLE_CNT,
+	MT_SPM_DBG_SMC_UID_SUSPEND_PWR_CTRL,
+	MT_SPM_DBG_SMC_UID_SUSPEND_DBG_CTRL,
+	MT_SPM_DBG_SMC_UID_FS,
+	MT_SPM_DBG_SMC_UID_RC_SWITCH,
+	MT_SPM_DBG_SMC_UID_RC_CNT,
+	MT_SPM_DBG_SMC_UID_COND_CHECK,
+	MT_SPM_DBG_SMC_UID_COND_BLOCK,
+	MT_SPM_DBG_SMC_UID_BLOCK_LATCH,
+	MT_SPM_DBG_SMC_UID_BLOCK_DETAIL,
+	MT_SPM_DBG_SMC_UID_RES_NUM,
+	MT_SPM_DBG_SMC_UID_RES_REQ,
+	MT_SPM_DBG_SMC_UID_RES_USAGE,
+	MT_SPM_DBG_SMC_UID_RES_USER_NUM,
+	MT_SPM_DBG_SMC_UID_RES_USER_VALID,
+	MT_SPM_DBG_SMC_UID_RES_USER_NAME,
+	MT_SPM_DBG_SMC_UID_DOE_RESOURCE_CTRL,
+	MT_SPM_DBG_SMC_UID_DOE_RC,
+	MT_SPM_DBG_SMC_UID_RC_COND_CTRL,
+	MT_SPM_DBG_SMC_UID_RC_RES_CTRL,
+	MT_SPM_DBG_SMC_UID_RC_RES_INFO,
+	MT_SPM_DBG_SMC_UID_RC_BBLPM,
+	MT_SPM_DBG_SMC_UID_RC_TRACE,
+	MT_SPM_DBG_SMC_UID_RC_TRACE_TIME,
+	MT_SPM_DBG_SMC_UID_DUMP_PLL,
+	MT_SPM_DBG_SMC_HWCG_NUM,
+	MT_SPM_DBG_SMC_HWCG_STATUS,
+	MT_SPM_DBG_SMC_HWCG_SETTING,
+	MT_SPM_DBG_SMC_HWCG_DEF_SETTING,
+	MT_SPM_DBG_SMC_HWCG_RES_NAME,
+	MT_SPM_DBG_SMC_UID_RC_NOTIFY_CTRL,
+	MT_SPM_DBG_SMC_VCORE_LP_ENABLE,
+	MT_SPM_DBG_SMC_VCORE_LP_VOLT,
+	MT_SPM_DBG_SMC_VSRAM_LP_ENABLE,
+	MT_SPM_DBG_SMC_VSRAM_LP_VOLT,
+	MT_SPM_DBG_SMC_PERI_REQ_NUM,
+	MT_SPM_DBG_SMC_PERI_REQ_STATUS,
+	MT_SPM_DBG_SMC_PERI_REQ_SETTING,
+	MT_SPM_DBG_SMC_PERI_REQ_DEF_SETTING,
+	MT_SPM_DBG_SMC_PERI_REQ_RES_NAME,
+	MT_SPM_DBG_SMC_PERI_REQ_STATUS_RAW,
+	MT_SPM_DBG_SMC_IDLE_PWR_STAT,
+	MT_SPM_DBG_SMC_SUSPEND_PWR_STAT,
+	MT_SPM_DBG_SMC_LP_REQ_STAT,
+	MT_SPM_DBG_SMC_COMMON_SODI_CTRL,
+	MT_SPM_DBG_SMC_SPM_TIMESTAMP,
+	MT_SPM_DBG_SMC_SPM_TIMESTAMP_SIZE,
+	MT_SPM_DBG_SMC_UID_COMMON_SODI_PWR_CTRL,
+};
+
+enum wake_status_enum {
+	WAKE_STA_ASSERT_PC,
+	WAKE_STA_R12,
+	WAKE_STA_R12_EXT,
+	WAKE_STA_RAW_STA,
+	WAKE_STA_RAW_EXT_STA,
+	WAKE_STA_WAKE_MISC,
+	WAKE_STA_TIMER_OUT,
+	WAKE_STA_R13,
+	WAKE_STA_IDLE_STA,
+	WAKE_STA_REQ_STA,
+	WAKE_STA_DEBUG_FLAG,
+	WAKE_STA_DEBUG_FLAG1,
+	WAKE_STA_EVENT_REG,
+	WAKE_STA_ISR,
+	WAKE_STA_MAX_COUNT,
+};
+
+#endif /* MT_SPM_SMC_H */
diff --git a/plat/mediatek/drivers/spm/common/rules.mk b/plat/mediatek/drivers/spm/common/rules.mk
new file mode 100644
index 000000000..50273de46
--- /dev/null
+++ b/plat/mediatek/drivers/spm/common/rules.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2025, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+#Prologue, init variable
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+#Define your module name
+MODULE := spm_common
+
+#Add your source code here
+LOCAL_SRCS-y :=
+
+#Epilogue, build as module
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
+$(eval $(call add_defined_option,CONFIG_MTK_VCOREDVFS_SUPPORT))
diff --git a/plat/mediatek/drivers/spm/mt8196/mt_spm.c b/plat/mediatek/drivers/spm/mt8196/mt_spm.c
new file mode 100644
index 000000000..fee5b4c74
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8196/mt_spm.c
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <arch.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/delay_timer.h>
+#include <drivers/gpio.h>
+#include <lib/bakery_lock.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <platform_def.h>
+
+#include <constraints/mt_spm_rc_api.h>
+#include <constraints/mt_spm_rc_internal.h>
+#include <drivers/spm/mt_spm_resource_req.h>
+#include <lib/mtk_init/mtk_init.h>
+#include <lib/pm/mtk_pm.h>
+#include <lpm_v2/mt_lp_rm.h>
+#include <lpm_v2/mt_lp_rqm.h>
+#include <lpm_v2/mt_lpm_smc.h>
+#include <mt_plat_spm_setting.h>
+#include <mt_spm.h>
+#include <mt_spm_common.h>
+#include <mt_spm_conservation.h>
+#include <mt_spm_constraint.h>
+#include <mt_spm_dispatcher.h>
+#include <mt_spm_hwreq.h>
+#include <mt_spm_idle.h>
+#include <mt_spm_internal.h>
+#include <mt_spm_reg.h>
+#include <mt_spm_suspend.h>
+#include <mtk_mmap_pool.h>
+#include <sleep_def.h>
+
+#ifdef MT_SPM_USING_BAKERY_LOCK
+DEFINE_BAKERY_LOCK(spm_lock);
+#define plat_spm_lock_init() \
+	bakery_lock_init(&spm_lock)
+#else
+spinlock_t spm_lock;
+#define plat_spm_lock_init()
+#endif
+
+uint32_t mt_spm_version;
+
+static uint32_t spm_irq_num;
+
+void spm_set_sysclk_settle(void)
+{
+	uint32_t settle;
+
+	mmio_write_32(SPM_CLK_SETTLE, SPM_SYSCLK_SETTLE);
+	settle = mmio_read_32(SPM_CLK_SETTLE);
+
+	INFO("md_settle = %u, settle = %u\n", SPM_SYSCLK_SETTLE, settle);
+}
+
+void spm_set_irq_num(uint32_t num)
+{
+	spm_irq_num = num;
+}
+
+void spm_irq0_handler(uint64_t x1, uint64_t x2)
+{
+	if (x2 == 0) {
+		mmio_setbits_32(SPM_IRQ_MASK, ISRM_ALL_EXC_TWAM);
+		mmio_write_32(SPM_IRQ_STA, x1);
+		mmio_write_32(SPM_SWINT_CLR, PCM_SW_INT0);
+	}
+}
+
+static int spm_ap_mdsrc_ack(void)
+{
+	int ack, md_state = 0;
+
+	/* Check ap_mdsrc_ack = 1'b1, for md internal resource on ack */
+	ack = !!(mmio_read_32(AP_MDSRC_REQ) & AP_MDSMSRC_ACK_LSB);
+
+	if (!ack) {
+		/* Check md_apsrc_req = 1'b0, for md state 0:sleep, 1:wakeup */
+		md_state = !!(mmio_read_32(SPM_REQ_STA_10)
+			      & MD_APSRC_REQ_LSB);
+
+		ERROR("[SPM] error: md_sleep = %d\n", md_state);
+		ERROR("%s can not get AP_MDSRC_ACK\n", __func__);
+		return -1;
+	}
+	return 0;
+}
+
+static void spm_ap_mdsrc_req(int set)
+{
+	spm_lock_get();
+
+	if (set)
+		mmio_setbits_32(AP_MDSRC_REQ, AP_MDSMSRC_REQ_LSB);
+	else
+		mmio_clrbits_32(AP_MDSRC_REQ, AP_MDSMSRC_REQ_LSB);
+
+	spm_lock_release();
+}
+
+static int spm_is_md_sleep(void *priv)
+{
+	int md_state = 0;
+	int *sleep = (int *)priv;
+
+	if (!priv)
+		return -1;
+
+	/* Check md_apsrc_req = 1'b0, for md state 0:sleep, 1:wakeup */
+	md_state = !!(mmio_read_32(SPM_REQ_STA_10)
+		      & MD_APSRC_REQ_LSB);
+
+	if (md_state == 0)
+		*sleep = 1;
+	else
+		*sleep = 0;
+
+	return 0;
+}
+
+static void spm_ap_gpueb_pll_control(int set)
+{
+	spm_lock_get();
+
+	if (set)
+		mmio_setbits_32(SPM2GPUPM_CON, SC_MFG_PLL_EN_LSB);
+	else
+		mmio_clrbits_32(SPM2GPUPM_CON, SC_MFG_PLL_EN_LSB);
+
+	spm_lock_release();
+}
+
+static uint32_t spm_ap_gpueb_get_pwr_status(void)
+{
+	uint32_t ret;
+
+	ret = mmio_read_32(XPU_PWR_STATUS);
+
+	return ret;
+}
+
+static uint32_t spm_ap_gpueb_get_mfg0_pwr_con(void)
+{
+	uint32_t ret;
+
+	ret = mmio_read_32(MFG0_PWR_CON);
+
+	return ret;
+}
+
+#ifndef MTK_PLAT_SPM_UNSUPPORT
+struct mt_lp_res_req rq_xo_fpm = {
+	.res_id = MT_LP_RQ_XO_FPM,
+	.res_rq = MT_SPM_XO_FPM,
+	.res_usage = 0,
+};
+
+struct mt_lp_res_req rq_26m = {
+	.res_id = MT_LP_RQ_26M,
+	.res_rq = MT_SPM_26M,
+	.res_usage = 0,
+};
+
+struct mt_lp_res_req rq_infra = {
+	.res_id = MT_LP_RQ_INFRA,
+	.res_rq = MT_SPM_INFRA,
+	.res_usage = 0,
+};
+
+struct mt_lp_res_req rq_syspll = {
+	.res_id = MT_LP_RQ_SYSPLL,
+	.res_rq = MT_SPM_SYSPLL,
+	.res_usage = 0,
+};
+
+struct mt_lp_res_req rq_dram_s0 = {
+	.res_id = MT_LP_RQ_DRAM,
+	.res_rq = MT_SPM_DRAM_S0,
+	.res_usage = 0,
+};
+
+struct mt_lp_res_req rq_dram_s1 = {
+	.res_id = MT_LP_RQ_DRAM,
+	.res_rq = MT_SPM_DRAM_S1,
+	.res_usage = 0,
+};
+
+struct mt_lp_res_req rq_vcore = {
+	.res_id = MT_LP_RQ_VCORE,
+	.res_rq = MT_SPM_VCORE,
+	.res_usage = 0,
+};
+
+struct mt_lp_res_req rq_emi = {
+	.res_id = MT_LP_RQ_EMI,
+	.res_rq = MT_SPM_EMI,
+	.res_usage = 0,
+};
+
+struct mt_lp_res_req rq_pmic = {
+	.res_id = MT_LP_RQ_PMIC,
+	.res_rq = MT_SPM_PMIC,
+	.res_usage = 0,
+};
+
+struct mt_lp_res_req *spm_resources[] = {
+	&rq_xo_fpm,
+	&rq_26m,
+	&rq_infra,
+	&rq_syspll,
+	&rq_dram_s0,
+	&rq_dram_s1,
+	&rq_vcore,
+	&rq_emi,
+	&rq_pmic,
+	NULL,
+};
+
+struct mt_resource_req_manager plat_mt8196_rq = {
+	.res = spm_resources,
+};
+
+struct mt_resource_constraint plat_constraint_vcore = {
+	.is_valid = spm_is_valid_rc_vcore,
+	.update = spm_update_rc_vcore,
+	.allow = spm_allow_rc_vcore,
+	.run = spm_run_rc_vcore,
+	.reset = spm_reset_rc_vcore,
+	.get_status = spm_get_status_rc_vcore,
+};
+
+struct mt_resource_constraint plat_constraint_bus26m = {
+	.is_valid = spm_is_valid_rc_bus26m,
+	.update = spm_update_rc_bus26m,
+	.allow = spm_allow_rc_bus26m,
+	.run = spm_run_rc_bus26m,
+	.reset = spm_reset_rc_bus26m,
+	.get_status = spm_get_status_rc_bus26m,
+};
+
+struct mt_resource_constraint plat_constraint_syspll = {
+	.is_valid = spm_is_valid_rc_syspll,
+	.update = spm_update_rc_syspll,
+	.allow = spm_allow_rc_syspll,
+	.run = spm_run_rc_syspll,
+	.reset = spm_reset_rc_syspll,
+	.get_status = spm_get_status_rc_syspll,
+};
+
+struct mt_resource_constraint *plat_constraints[] = {
+	&plat_constraint_vcore,
+	&plat_constraint_bus26m,
+	&plat_constraint_syspll,
+	NULL,
+};
+#endif
+
+int mt_spm_hwctrl(uint32_t type, int set, void *priv)
+{
+	int ret = 0;
+
+	if (type == PLAT_AP_MDSRC_REQ) {
+		spm_ap_mdsrc_req(set);
+	} else if (type == PLAT_AP_MDSRC_ACK) {
+		ret = spm_ap_mdsrc_ack();
+	} else if (type == PLAT_AP_IS_MD_SLEEP) {
+		ret = spm_is_md_sleep(priv);
+	} else if (type == PLAT_AP_MDSRC_SETTLE) {
+		if (!priv)
+			return -1;
+		*(int *)priv = AP_MDSRC_REQ_MD_26M_SETTLE;
+	} else if (type == PLAT_AP_GPUEB_PLL_CONTROL) {
+		spm_ap_gpueb_pll_control(set);
+	} else if (type == PLAT_AP_GPUEB_PWR_STATUS) {
+		if (!priv)
+			return -1;
+		*(uint32_t *)priv = spm_ap_gpueb_get_pwr_status();
+	} else if (type == PLAT_AP_GPUEB_MFG0_PWR_CON) {
+		if (!priv)
+			return -1;
+		*(uint32_t *)priv = spm_ap_gpueb_get_mfg0_pwr_con();
+	} else if (type == PLAT_AP_SPM_RESOURCE_REQUEST_UPDATE) {
+		struct spm_lp_scen *spmlp = NULL;
+
+#ifdef MT_SPM_COMMON_SODI_SUPPORT
+		mt_spm_common_sodi_get_spm_lp(&spmlp);
+#else
+#if defined(MT_SPM_FEATURE_SUPPORT)
+		mt_spm_idle_generic_get_spm_lp(&spmlp);
+#endif
+#endif
+		if (!spmlp)
+			return -1;
+		__spm_set_power_control(spmlp->pwrctrl, *(uint32_t *)priv);
+		ret = __spm_wait_spm_request_ack(*(uint32_t *)priv,
+						 SPM_ACK_TIMEOUT_US);
+	} else if (type == PLAT_AP_SPM_WDT_TRIGGER) {
+		mmio_write_32(PCM_WDT_VAL, 0x1);
+		mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY |
+				REG_PCM_WDT_EN_LSB | REG_PCM_WDT_WAKE_LSB);
+	} else {
+		/* Not supported type */
+		return -1;
+	}
+
+	return ret;
+}
+
+#ifndef MTK_PLAT_SPM_UNSUPPORT
+struct mt_resource_manager plat_mt8196_rm = {
+	.update = NULL,
+	.hwctrl = mt_spm_hwctrl,
+	.consts = plat_constraints,
+};
+#else
+struct mt_resource_manager plat_mt8196_rm = {
+	.hwctrl = mt_spm_hwctrl,
+};
+#endif
+
+/* Determine for spm sw resource user */
+static struct mt_lp_resource_user spm_res_user;
+
+struct mt_lp_resource_user *get_spm_res_user(void)
+{
+	return &spm_res_user;
+}
+
+#ifdef MT_SPM_COMMON_SODI_SUPPORT
+int mt_spm_common_sodi_get_spm_pcm_flag(uint32_t  *lp, uint32_t idx)
+{
+	struct spm_lp_scen *spmlp;
+	struct pwr_ctrl *pwrctrl;
+
+	mt_spm_common_sodi_get_spm_lp(&spmlp);
+
+	pwrctrl = spmlp->pwrctrl;
+
+	if (!lp || idx > 1)
+		return -1;
+
+	switch (idx) {
+	case 0:
+		*lp = pwrctrl->pcm_flags;
+		break;
+	case 1:
+		*lp = pwrctrl->pcm_flags;
+		break;
+	default:
+		return -1;
+	}
+	return 0;
+}
+
+void mt_spm_common_sodi_en(bool en)
+{
+	struct spm_lp_scen *spmlp;
+	struct pwr_ctrl *pwrctrl;
+
+	mt_spm_common_sodi_get_spm_lp(&spmlp);
+	pwrctrl = spmlp->pwrctrl;
+#if defined(CONFIG_MTK_VCOREDVFS_SUPPORT)
+	__spm_sync_vcore_dvfs_pcm_flags(&pwrctrl->pcm_flags,
+					&__spm_vcorefs.pwrctrl->pcm_flags);
+#endif
+	if (en)
+		pwrctrl->pcm_flags |= SPM_FLAG_ENABLE_COMMON_SODI5;
+	else
+		pwrctrl->pcm_flags &= (~SPM_FLAG_ENABLE_COMMON_SODI5);
+
+	/* Set PCM flags */
+	__spm_set_pcm_flags(pwrctrl);
+
+	__spm_send_cpu_wakeup_event();
+}
+
+int mt_spm_common_sodi_get_spm_lp(struct spm_lp_scen **lp)
+{
+	if (!lp)
+		return -1;
+
+	*lp = &__spm_common_sodi;
+	return 0;
+}
+
+void mt_spm_set_common_sodi_pwrctr(void)
+{
+	struct resource_req_status common_sodi_spm_resource_req = {
+		.id = MT_LP_RQ_ID_ALL_USAGE,
+		.val = 0,
+	};
+	struct spm_lp_scen *spmlp;
+
+	mt_lp_rq_get_status(PLAT_RQ_REQ_USAGE,
+			&common_sodi_spm_resource_req);
+	mt_spm_common_sodi_get_spm_lp(&spmlp);
+
+	__spm_set_power_control(spmlp->pwrctrl,
+		common_sodi_spm_resource_req.val);
+}
+
+void mt_spm_set_common_sodi_pcm_flags(void)
+{
+	struct spm_lp_scen *spmlp;
+	struct pwr_ctrl *pwrctrl;
+
+	mt_spm_common_sodi_get_spm_lp(&spmlp);
+	pwrctrl = spmlp->pwrctrl;
+#if defined(CONFIG_MTK_VCOREDVFS_SUPPORT)
+	/* Set PCM flags */
+	__spm_sync_vcore_dvfs_pcm_flags(&pwrctrl->pcm_flags,
+					&__spm_vcorefs.pwrctrl->pcm_flags);
+#endif
+	__spm_set_pcm_flags(pwrctrl);
+
+	__spm_send_cpu_wakeup_event();
+
+}
+#endif
+
+static void spm_gpio_init(void)
+{
+	gpio_set_direction(EC_SUSPEND_PIN, GPIO_DIR_OUT);
+	gpio_set_value(EC_SUSPEND_PIN, GPIO_LEVEL_HIGH);
+}
+
+int spm_boot_init(void)
+{
+	plat_spm_lock_init();
+
+#if defined(MT_SPM_FEATURE_SUPPORT)
+	plat_spm_pmic_wrap_init();
+#endif
+	mt_lp_rm_register(&plat_mt8196_rm);
+
+#ifndef MTK_PLAT_SPM_UNSUPPORT
+	mt_lp_resource_request_manager_register(&plat_mt8196_rq);
+	mt_lp_resource_user_register("SPM", &spm_res_user);
+	mt_spm_dispatcher_init();
+#endif
+#if defined(MT_SPM_FEATURE_SUPPORT)
+	spm_hwreq_init();
+#endif
+	spm_gpio_init();
+
+	spm_irq_num = 0xFFFFFFFF;
+
+	INFO("[%s:%d] - spm finished, version = %u, PC = 0x%x\n",
+		__func__, __LINE__,
+		mt_spm_version, mmio_read_32(MD32PCM_PC));
+	return 0;
+}
+MTK_PLAT_SETUP_1_INIT(spm_boot_init);
diff --git a/plat/mediatek/drivers/spm/mt8196/mt_spm.h b/plat/mediatek/drivers/spm/mt8196/mt_spm.h
new file mode 100644
index 000000000..bc6fa44e5
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8196/mt_spm.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_H
+#define MT_SPM_H
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include <lib/pm/mtk_pm.h>
+#include <lpm_v2/mt_lp_rq.h>
+
+#ifdef __GNUC__
+#define spm_likely(x)		__builtin_expect(!!(x), 1)
+#define spm_unlikely(x)		__builtin_expect(!!(x), 0)
+#else
+#define spm_likely(x)		(x)
+#define spm_unlikely(x)		(x)
+#endif
+
+#define CLK_SCP_CFG_0		(CKSYS_BASE + 0x1A0)
+#define INFRA_BUS_DCM_CTRL	(INFRACFG_AO_BASE + 0x070)
+#define RG_AXI_DCM_DIS_EN	BIT(21)
+#define RG_PLLCK_SEL_NO_SPM	BIT(22)
+
+#define MT_SPM_TIME_GET(tm)	({ (tm) = el3_uptime(); })
+
+#define MT_SPM_VERSION_ES	0x0
+#define MT_SPM_VERSION_CS	0x1
+
+#define SPM_FW_NO_RESUME	1
+#define MCUSYS_MTCMOS_ON	0
+#define WAKEUP_LOG_ON		0
+
+#define MT_SPM_USING_SRCLKEN_RC
+/* SPM extern operand definition */
+#define MT_SPM_EX_OP_CLR_26M_RECORD		BIT(0)
+#define MT_SPM_EX_OP_SET_WDT			BIT(1)
+#define MT_SPM_EX_OP_NON_GENERIC_RESOURCE_REQ	BIT(2)
+#define MT_SPM_EX_OP_SET_SUSPEND_MODE		BIT(3)
+#define MT_SPM_EX_OP_SET_IS_ADSP		BIT(4)
+#define MT_SPM_EX_OP_SRCLKEN_RC_BBLPM		BIT(5)
+#define MT_SPM_EX_OP_HW_S1_DETECT		BIT(6)
+#define MT_SPM_EX_OP_TRACE_LP			BIT(7)
+#define MT_SPM_EX_OP_TRACE_SUSPEND		BIT(8)
+#define MT_SPM_EX_OP_TRACE_TIMESTAMP_EN		BIT(9)
+#define MT_SPM_EX_OP_TIME_CHECK			BIT(10)
+#define MT_SPM_EX_OP_TIME_OBS			BIT(11)
+#define MT_SPM_EX_OP_SET_IS_USB_HEADSET		BIT(12)
+#define MT_SPM_EX_OP_SET_IS_FM_AUDIO		BIT(13)
+#define MT_SPM_EX_OP_DEVICES_SAVE		BIT(14)
+#define MT_SPM_EX_OP_NOTIFY_INFRA_OFF		BIT(15)
+
+#define MT_BUS26M_EXT_LP_26M_ON_MODE	(MT_SPM_EX_OP_SET_IS_ADSP | \
+					 MT_SPM_EX_OP_SET_IS_FM_AUDIO)
+
+#define MT_VCORE_EXT_LP_VCORE_ON_MODE	(MT_SPM_EX_OP_SET_IS_ADSP | \
+					 MT_SPM_EX_OP_SET_IS_FM_AUDIO)
+
+/* EN SPM INFRA DEBUG OUT */
+#define DEBUGSYS_DEBUG_EN_REG	(DBGSYS_DEM_BASE + 0x94)
+
+/* INFRA_AO_DEBUG_CON */
+#define INFRA_AO_DBG_CON0	(INFRACFG_AO_BASE + 0x500)
+#define INFRA_AO_DBG_CON1	(INFRACFG_AO_BASE + 0x504)
+#define INFRA_AO_DBG_CON2	(INFRACFG_AO_BASE + 0x508)
+#define INFRA_AO_DBG_CON3	(INFRACFG_AO_BASE + 0x50C)
+
+/* SPM init. related registers */
+#define VLP_AO_APC_CON			(VLP_AO_DEVAPC_APB_BASE + 0xF00)
+#define VLP_AO_MAS_SEC_0		(VLP_AO_DEVAPC_APB_BASE + 0xA00)
+#define SCP_CFGREG_PERI_BUS_CTRL0	(SCP_CFGREG_BASE + 0x24)
+#define MODULE_SW_CG_0_MASK		(INFRACFG_AO_BASE + 0x060)
+#define VLP_DBG_MON_SEL0_ADDR		(VLPCFG_BUS_BASE + 0x108)
+#define VLP_DBG_MON_SEL1_ADDR		(VLPCFG_BUS_BASE + 0x10C)
+#define VLP_CLKSQ_CON1			(VLP_CKSYS_BASE + 0x224)
+#define VLP_AP_PLL_CON3			(VLP_CKSYS_BASE + 0x264)
+
+/* SPM SRAM Data */
+#define SPM_SRAM_TIMESTAMP_START	(SPM_SRAM_BASE + 0xF80)
+#define SPM_SRAM_TIMESTAMP_END		(SPM_SRAM_BASE + 0xFFC)
+#define SPM_SRAM_TIMESTAMP_SIZE \
+	(((SPM_SRAM_TIMESTAMP_END - SPM_SRAM_TIMESTAMP_START) >> 2) + 1)
+
+/* AP_MDSRC_REQ MD 26M ON settle time (3ms) */
+#define AP_MDSRC_REQ_MD_26M_SETTLE	3
+
+/* Setting the SPM settle time*/
+#define SPM_SYSCLK_SETTLE	0x60FE	/* 1685us */
+
+/* Setting the SPM req/ack time*/
+#define SPM_ACK_TIMEOUT_US	1000
+
+/* Settine the firmware status check for SPM PC */
+#define SPM_PC_CHECKABLE
+
+enum {
+	SPM_ARGS_SPMFW_IDX_KICK = 0,
+	SPM_ARGS_SPMFW_INIT,
+	SPM_ARGS_SUSPEND,
+	SPM_ARGS_SUSPEND_FINISH,
+	SPM_ARGS_SODI,
+	SPM_ARGS_SODI_FINISH,
+	SPM_ARGS_DPIDLE,
+	SPM_ARGS_DPIDLE_FINISH,
+	SPM_ARGS_PCM_WDT,
+	SPM_ARGS_SUSPEND_CALLBACK,
+	SPM_ARGS_HARDWARE_CG_CHECK,
+	SPM_ARGS_NUM,
+};
+
+typedef enum {
+	WR_NONE = 0,
+	WR_UART_BUSY,
+	WR_ABORT,
+	WR_PCM_TIMER,
+	WR_WAKE_SRC,
+	WR_DVFSRC,
+	WR_TWAM,
+	WR_PMSR,
+	WR_SPM_ACK_CHK,
+	WR_UNKNOWN,
+} wake_reason_t;
+
+struct pwr_ctrl;
+struct spm_lp_scen;
+
+void spm_set_irq_num(uint32_t num);
+void spm_irq0_handler(uint64_t x1, uint64_t x2);
+struct mt_lp_resource_user *get_spm_res_user(void);
+int mt_spm_common_sodi_get_spm_pcm_flag(uint32_t  *lp, uint32_t idx);
+void mt_spm_common_sodi_en(bool en);
+int mt_spm_common_sodi_get_spm_lp(struct spm_lp_scen **lp);
+void mt_spm_set_common_sodi_pwrctr(void);
+void mt_spm_set_common_sodi_pcm_flags(void);
+int spm_boot_init(void);
+void spm_dvfsfw_init(uint64_t boot_up_opp, uint64_t dram_issue);
+extern uint32_t mt_spm_version;
+extern struct pwr_ctrl spm_init_ctrl;
+/* Support by bl31_plat_setup.c */
+uint32_t is_abnormal_boot(void);
+
+#endif /* MT_SPM_H */
diff --git a/plat/mediatek/drivers/spm/mt8196/mt_spm_conservation.c b/plat/mediatek/drivers/spm/mt8196/mt_spm_conservation.c
new file mode 100644
index 000000000..16d9f29d6
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8196/mt_spm_conservation.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include <lib/pm/mtk_pm.h>
+#include <lpm_v2/mt_lp_rqm.h>
+#include <mt_spm.h>
+#include <mt_spm_common.h>
+#include <mt_spm_conservation.h>
+#include <mt_spm_reg.h>
+#include <mt_spm_vcorefs.h>
+
+#define MT_RESUMETIME_THRESHOLD_MAX	5
+#define IS_RESUME_OVERTIME(delta) \
+	(delta > MT_RESUMETIME_THRESHOLD_MAX)
+
+static struct wake_status spm_wakesta; /* Record last wakesta */
+static wake_reason_t spm_wake_reason = WR_NONE;
+static struct resource_req_status generic_spm_resource_req = {
+	.id = MT_LP_RQ_ID_ALL_USAGE,
+	.val = 0,
+};
+
+#define do_spm_init(pwrctrl)	({ int local_ret = 0; local_ret; })
+#define do_spm_run(pwrctrl)	__spm_send_cpu_wakeup_event()
+
+static int go_to_spm_before_wfi(int state_id, uint32_t ext_opand,
+				struct spm_lp_scen *spm_lp,
+				uint32_t resource_req)
+{
+	int ret = 0;
+	struct pwr_ctrl *pwrctrl;
+
+	pwrctrl = spm_lp->pwrctrl;
+
+#if SPM_FW_NO_RESUME == 0
+	ret = do_spm_init(pwrctrl);
+
+	if (ret)
+		return ret;
+#endif
+	__spm_set_power_control(pwrctrl, resource_req);
+	__spm_set_wakeup_event(pwrctrl);
+#if defined(CONFIG_MTK_VCOREDVFS_SUPPORT)
+	__spm_sync_vcore_dvfs_power_control(pwrctrl, __spm_vcorefs.pwrctrl);
+#endif
+	if (mt_spm_version == MT_SPM_VERSION_ES)
+		pwrctrl->pcm_flags |= (SPM_FLAG_ENABLE_MT8196_E1_WA |
+				       SPM_FLAG_ENABLE_MT8196_EMI_E1_WA);
+
+#ifdef MTK_SPM_IVI_SUPPORT
+	pwrctrl->pcm_flags |= SPM_FLAG_ENABLE_MT8196_IVI;
+#endif
+
+	__spm_set_pcm_flags(pwrctrl);
+
+#ifdef HW_S1_DETECT
+	if (ext_opand & MT_SPM_EX_OP_HW_S1_DETECT)
+		spm_hw_s1_state_monitor_resume();
+#endif
+	do_spm_run(pwrctrl);
+	return ret;
+}
+
+static void go_to_spm_after_wfi(int state_id, uint32_t ext_opand,
+				struct spm_lp_scen *spm_lp,
+				struct wake_status **status)
+{
+	uint32_t ext_status = 0;
+
+	spm_wakesta.tr.comm.resumetime = 0;
+	spm_wakesta.tr.comm.times_h = spm_wakesta.tr.comm.times_l = 0;
+
+	if (ext_opand & MT_SPM_EX_OP_HW_S1_DETECT)
+		spm_hw_s1_state_monitor_pause(&ext_status);
+
+	__spm_ext_int_wakeup_req_clr();
+
+	__spm_get_wakeup_status(&spm_wakesta, ext_status);
+
+	if (status)
+		*status = &spm_wakesta;
+
+#ifndef MT_SPM_COMMON_SODI_SUPPORT
+	__spm_clean_after_wakeup();
+#endif
+	spm_wake_reason = __spm_output_wake_reason(&spm_wakesta);
+}
+
+int spm_conservation(int state_id, uint32_t ext_opand,
+		     struct spm_lp_scen *spm_lp, uint32_t resource_req)
+{
+	uint32_t rc_state = resource_req;
+
+	if (!spm_lp)
+		return -1;
+
+	spm_lock_get();
+
+	/* Uart bk/rs is needed if infra off for legacy project
+	 * leave code here for reference.
+	 */
+	if (ext_opand & MT_SPM_EX_OP_NOTIFY_INFRA_OFF) {
+#ifndef MTK_PLAT_SPM_UART_UNSUPPORT
+		/* Notify UART to sleep */
+		mt_uart_save();
+#endif
+	}
+
+	if (!(ext_opand & MT_SPM_EX_OP_NON_GENERIC_RESOURCE_REQ)) {
+		/* Resource request */
+		mt_lp_rq_get_status(PLAT_RQ_REQ_USAGE,
+				    &generic_spm_resource_req);
+		rc_state |= generic_spm_resource_req.val;
+	}
+	go_to_spm_before_wfi(state_id, ext_opand, spm_lp, rc_state);
+
+	spm_lock_release();
+
+	return 0;
+}
+
+void spm_conservation_finish(int state_id, uint32_t ext_opand,
+			     struct spm_lp_scen *spm_lp,
+			     struct wake_status **status)
+{
+	/* Uart bk/rs is needed if infra off for legacy project
+	 * leave code here for reference.
+	 */
+	if (ext_opand & MT_SPM_EX_OP_NOTIFY_INFRA_OFF) {
+#ifndef MTK_PLAT_SPM_UART_UNSUPPORT
+		/* Notify UART to wakeup */
+		mt_uart_restore();
+#endif
+	}
+
+	spm_lock_get();
+	go_to_spm_after_wfi(state_id, ext_opand, spm_lp, status);
+#ifdef MT_SPM_COMMON_SODI_SUPPORT
+	/* Restore common sodi mask and resource req setting */
+	mt_spm_set_common_sodi_pwrctr();
+	mt_spm_set_common_sodi_pcm_flags();
+#endif
+	spm_lock_release();
+}
+
+int spm_conservation_get_result(struct wake_status **res)
+{
+	if (!res)
+		return -1;
+	*res = &spm_wakesta;
+	return 0;
+}
diff --git a/plat/mediatek/drivers/spm/mt8196/mt_spm_conservation.h b/plat/mediatek/drivers/spm/mt8196/mt_spm_conservation.h
new file mode 100644
index 000000000..692180a58
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8196/mt_spm_conservation.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_CONSERVATION_H
+#define MT_SPM_CONSERVATION_H
+
+#include <mt_spm.h>
+#include <mt_spm_internal.h>
+
+int spm_conservation(int state_id, uint32_t ext_opand,
+		     struct spm_lp_scen *spm_lp,
+		     uint32_t resource_req);
+
+void spm_conservation_finish(int state_id, uint32_t ext_opand,
+			     struct spm_lp_scen *spm_lp,
+			     struct wake_status **status);
+
+int spm_conservation_get_result(struct wake_status **res);
+
+int spm_conservation_fw_run(uint32_t first, void *pwrctrl);
+
+int spm_conservation_wakeup_obs(int IsSet, int cat,
+				uint32_t wake_src_bits);
+
+void mt_uart_save(void);
+void mt_uart_restore(void);
+#endif /* MT_SPM_CONSERVATION_H */
diff --git a/plat/mediatek/drivers/spm/mt8196/mt_spm_internal.c b/plat/mediatek/drivers/spm/mt8196/mt_spm_internal.c
new file mode 100644
index 000000000..355c49262
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8196/mt_spm_internal.c
@@ -0,0 +1,825 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include <drivers/spm/mt_spm_resource_req.h>
+#include <mt_plat_spm_setting.h>
+#include <mt_spm.h>
+#include <mt_spm_internal.h>
+#include <mt_spm_reg.h>
+#include <pmic_wrap/inc/mt_spm_pmic_wrap.h>
+
+/**************************************
+ * Define and Declare
+ **************************************/
+#define SPM_INIT_DONE_US	20 /* Simulation result */
+
+wake_reason_t __spm_output_wake_reason(const struct wake_status *wakesta)
+{
+	uint32_t i;
+	wake_reason_t wr = WR_UNKNOWN;
+
+	if (!wakesta)
+		return WR_UNKNOWN;
+
+	if (wakesta->is_abort) {
+		INFO("SPM EARLY WAKE r13 = 0x%x, ", wakesta->tr.comm.r13);
+#ifndef MTK_PLAT_SPM_PMIC_WRAP_DUMP_UNSUPPORT
+		mt_spm_dump_pmic_warp_reg();
+#endif
+	}
+
+	if (wakesta->tr.comm.r12 & R12_PCM_TIMER_B) {
+
+		if (wakesta->wake_misc & WAKE_MISC_PCM_TIMER_EVENT)
+			wr = WR_PCM_TIMER;
+	}
+
+	for (i = 2; i < 32; i++) {
+		if (wakesta->tr.comm.r12 & (1U << i))
+			wr = WR_WAKE_SRC;
+	}
+
+	return wr;
+}
+
+void __spm_init_pcm_register(void)
+{
+	/* Disable r0 and r7 to control power */
+	mmio_write_32(PCM_PWR_IO_EN, 0);
+}
+
+void __spm_set_power_control(const struct pwr_ctrl *pwrctrl,
+			     uint32_t resource_usage)
+{
+	/* SPM_SRC_REQ */
+	mmio_write_32(SPM_SRC_REQ,
+		      ((pwrctrl->reg_spm_adsp_mailbox_req & 0x1) << 0) |
+		      (((pwrctrl->reg_spm_apsrc_req |
+		      !!(resource_usage & MT_SPM_DRAM_S0)) & 0x1) << 1) |
+		      (((pwrctrl->reg_spm_ddren_req |
+		      !!(resource_usage & MT_SPM_DRAM_S1)) & 0x1) << 2) |
+		      ((pwrctrl->reg_spm_dvfs_req & 0x1) << 3) |
+		      (((pwrctrl->reg_spm_emi_req |
+		      !!(resource_usage & MT_SPM_EMI)) & 0x1) << 4) |
+		      (((pwrctrl->reg_spm_f26m_req |
+		      !!(resource_usage & (MT_SPM_26M |
+		      MT_SPM_XO_FPM))) & 0x1) << 5) |
+		      (((pwrctrl->reg_spm_infra_req |
+		      !!(resource_usage & MT_SPM_INFRA)) & 0x1) << 6) |
+		      (((pwrctrl->reg_spm_pmic_req |
+		      !!(resource_usage & MT_SPM_PMIC)) & 0x1) << 7) |
+		      (((u32)pwrctrl->reg_spm_scp_mailbox_req & 0x1) << 8) |
+		      (((u32)pwrctrl->reg_spm_sspm_mailbox_req & 0x1) << 9) |
+		      (((u32)pwrctrl->reg_spm_sw_mailbox_req & 0x1) << 10) |
+		      ((((u32)pwrctrl->reg_spm_vcore_req |
+		      !!(resource_usage & MT_SPM_VCORE)) & 0x1) << 11) |
+		      ((((u32)pwrctrl->reg_spm_vrf18_req |
+		      !!(resource_usage & MT_SPM_SYSPLL)) & 0x1) << 12) |
+		      (((u32)pwrctrl->adsp_mailbox_state & 0x1) << 16) |
+		      (((u32)pwrctrl->apsrc_state & 0x1) << 17) |
+		      (((u32)pwrctrl->ddren_state & 0x1) << 18) |
+		      (((u32)pwrctrl->dvfs_state & 0x1) << 19) |
+		      (((u32)pwrctrl->emi_state & 0x1) << 20) |
+		      (((u32)pwrctrl->f26m_state & 0x1) << 21) |
+		      (((u32)pwrctrl->infra_state & 0x1) << 22) |
+		      (((u32)pwrctrl->pmic_state & 0x1) << 23) |
+		      (((u32)pwrctrl->scp_mailbox_state & 0x1) << 24) |
+		      (((u32)pwrctrl->sspm_mailbox_state & 0x1) << 25) |
+		      (((u32)pwrctrl->sw_mailbox_state & 0x1) << 26) |
+		      (((u32)pwrctrl->vcore_state & 0x1) << 27) |
+		      (((u32)pwrctrl->vrf18_state & 0x1) << 28));
+
+	/* SPM_SRC_MASK_0 */
+	mmio_write_32(SPM_SRC_MASK_0,
+		      (((u32)pwrctrl->reg_apifr_apsrc_rmb & 0x1) << 0) |
+		      (((u32)pwrctrl->reg_apifr_ddren_rmb & 0x1) << 1) |
+		      (((u32)pwrctrl->reg_apifr_emi_rmb & 0x1) << 2) |
+		      (((u32)pwrctrl->reg_apifr_infra_rmb & 0x1) << 3) |
+		      (((u32)pwrctrl->reg_apifr_pmic_rmb & 0x1) << 4) |
+		      (((u32)pwrctrl->reg_apifr_srcclkena_mb & 0x1) << 5) |
+		      (((u32)pwrctrl->reg_apifr_vcore_rmb & 0x1) << 6) |
+		      (((u32)pwrctrl->reg_apifr_vrf18_rmb & 0x1) << 7) |
+		      (((u32)pwrctrl->reg_apu_apsrc_rmb & 0x1) << 8) |
+		      (((u32)pwrctrl->reg_apu_ddren_rmb & 0x1) << 9) |
+		      (((u32)pwrctrl->reg_apu_emi_rmb & 0x1) << 10) |
+		      (((u32)pwrctrl->reg_apu_infra_rmb & 0x1) << 11) |
+		      (((u32)pwrctrl->reg_apu_pmic_rmb & 0x1) << 12) |
+		      (((u32)pwrctrl->reg_apu_srcclkena_mb & 0x1) << 13) |
+		      (((u32)pwrctrl->reg_apu_vcore_rmb & 0x1) << 14) |
+		      (((u32)pwrctrl->reg_apu_vrf18_rmb & 0x1) << 15) |
+		      (((u32)pwrctrl->reg_audio_apsrc_rmb & 0x1) << 16) |
+		      (((u32)pwrctrl->reg_audio_ddren_rmb & 0x1) << 17) |
+		      (((u32)pwrctrl->reg_audio_emi_rmb & 0x1) << 18) |
+		      (((u32)pwrctrl->reg_audio_infra_rmb & 0x1) << 19) |
+		      (((u32)pwrctrl->reg_audio_pmic_rmb & 0x1) << 20) |
+		      (((u32)pwrctrl->reg_audio_srcclkena_mb & 0x1) << 21) |
+		      (((u32)pwrctrl->reg_audio_vcore_rmb & 0x1) << 22) |
+		      (((u32)pwrctrl->reg_audio_vrf18_rmb & 0x1) << 23));
+
+	/* SPM_SRC_MASK_1 */
+	mmio_write_32(SPM_SRC_MASK_1,
+		      (((u32)pwrctrl->reg_audio_dsp_apsrc_rmb & 0x1) << 0) |
+		      (((u32)pwrctrl->reg_audio_dsp_ddren_rmb & 0x1) << 1) |
+		      (((u32)pwrctrl->reg_audio_dsp_emi_rmb & 0x1) << 2) |
+		      (((u32)pwrctrl->reg_audio_dsp_infra_rmb & 0x1) << 3) |
+		      (((u32)pwrctrl->reg_audio_dsp_pmic_rmb & 0x1) << 4) |
+		      (((u32)pwrctrl->reg_audio_dsp_srcclkena_mb & 0x1) << 5) |
+		      (((u32)pwrctrl->reg_audio_dsp_vcore_rmb & 0x1) << 6) |
+		      (((u32)pwrctrl->reg_audio_dsp_vrf18_rmb & 0x1) << 7) |
+		      (((u32)pwrctrl->reg_cam_apsrc_rmb & 0x1) << 8) |
+		      (((u32)pwrctrl->reg_cam_ddren_rmb & 0x1) << 9) |
+		      (((u32)pwrctrl->reg_cam_emi_rmb & 0x1) << 10) |
+		      (((u32)pwrctrl->reg_cam_infra_rmb & 0x1) << 11) |
+		      (((u32)pwrctrl->reg_cam_pmic_rmb & 0x1) << 12) |
+		      (((u32)pwrctrl->reg_cam_srcclkena_mb & 0x1) << 13) |
+		      (((u32)pwrctrl->reg_cam_vrf18_rmb & 0x1) << 14) |
+		      (((u32)pwrctrl->reg_ccif_apsrc_rmb & 0xfff) << 15));
+
+	/* SPM_SRC_MASK_2 */
+	mmio_write_32(SPM_SRC_MASK_2,
+		      (((u32)pwrctrl->reg_ccif_emi_rmb & 0xfff) << 0) |
+		      (((u32)pwrctrl->reg_ccif_infra_rmb & 0xfff) << 12));
+
+	/* SPM_SRC_MASK_3 */
+	mmio_write_32(SPM_SRC_MASK_3,
+		      (((u32)pwrctrl->reg_ccif_pmic_rmb & 0xfff) << 0) |
+		      (((u32)pwrctrl->reg_ccif_srcclkena_mb & 0xfff) << 12));
+
+	/* SPM_SRC_MASK_4 */
+	mmio_write_32(SPM_SRC_MASK_4,
+		      (((u32)pwrctrl->reg_ccif_vcore_rmb & 0xfff) << 0) |
+		      (((u32)pwrctrl->reg_ccif_vrf18_rmb & 0xfff) << 12) |
+		      (((u32)pwrctrl->reg_ccu_apsrc_rmb & 0x1) << 24) |
+		      (((u32)pwrctrl->reg_ccu_ddren_rmb & 0x1) << 25) |
+		      (((u32)pwrctrl->reg_ccu_emi_rmb & 0x1) << 26) |
+		      (((u32)pwrctrl->reg_ccu_infra_rmb & 0x1) << 27) |
+		      (((u32)pwrctrl->reg_ccu_pmic_rmb & 0x1) << 28) |
+		      (((u32)pwrctrl->reg_ccu_srcclkena_mb & 0x1) << 29) |
+		      (((u32)pwrctrl->reg_ccu_vrf18_rmb & 0x1) << 30) |
+		      (((u32)pwrctrl->reg_cg_check_apsrc_rmb & 0x1) << 31));
+
+	/* SPM_SRC_MASK_5 */
+	mmio_write_32(SPM_SRC_MASK_5,
+		      (((u32)pwrctrl->reg_cg_check_ddren_rmb & 0x1) << 0) |
+		      (((u32)pwrctrl->reg_cg_check_emi_rmb & 0x1) << 1) |
+		      (((u32)pwrctrl->reg_cg_check_infra_rmb & 0x1) << 2) |
+		      (((u32)pwrctrl->reg_cg_check_pmic_rmb & 0x1) << 3) |
+		      (((u32)pwrctrl->reg_cg_check_srcclkena_mb & 0x1) << 4) |
+		      (((u32)pwrctrl->reg_cg_check_vcore_rmb & 0x1) << 5) |
+		      (((u32)pwrctrl->reg_cg_check_vrf18_rmb & 0x1) << 6) |
+		      (((u32)pwrctrl->reg_cksys_apsrc_rmb & 0x1) << 7) |
+		      (((u32)pwrctrl->reg_cksys_ddren_rmb & 0x1) << 8) |
+		      (((u32)pwrctrl->reg_cksys_emi_rmb & 0x1) << 9) |
+		      (((u32)pwrctrl->reg_cksys_infra_rmb & 0x1) << 10) |
+		      (((u32)pwrctrl->reg_cksys_pmic_rmb & 0x1) << 11) |
+		      (((u32)pwrctrl->reg_cksys_srcclkena_mb & 0x1) << 12) |
+		      (((u32)pwrctrl->reg_cksys_vcore_rmb & 0x1) << 13) |
+		      (((u32)pwrctrl->reg_cksys_vrf18_rmb & 0x1) << 14) |
+		      (((u32)pwrctrl->reg_cksys_1_apsrc_rmb & 0x1) << 15) |
+		      (((u32)pwrctrl->reg_cksys_1_ddren_rmb & 0x1) << 16) |
+		      (((u32)pwrctrl->reg_cksys_1_emi_rmb & 0x1) << 17) |
+		      (((u32)pwrctrl->reg_cksys_1_infra_rmb & 0x1) << 18) |
+		      (((u32)pwrctrl->reg_cksys_1_pmic_rmb & 0x1) << 19) |
+		      (((u32)pwrctrl->reg_cksys_1_srcclkena_mb & 0x1) << 20) |
+		      (((u32)pwrctrl->reg_cksys_1_vcore_rmb & 0x1) << 21) |
+		      (((u32)pwrctrl->reg_cksys_1_vrf18_rmb & 0x1) << 22));
+
+	/* SPM_SRC_MASK_6 */
+	mmio_write_32(SPM_SRC_MASK_6,
+		      (((u32)pwrctrl->reg_cksys_2_apsrc_rmb & 0x1) << 0) |
+		      (((u32)pwrctrl->reg_cksys_2_ddren_rmb & 0x1) << 1) |
+		      (((u32)pwrctrl->reg_cksys_2_emi_rmb & 0x1) << 2) |
+		      (((u32)pwrctrl->reg_cksys_2_infra_rmb & 0x1) << 3) |
+		      (((u32)pwrctrl->reg_cksys_2_pmic_rmb & 0x1) << 4) |
+		      (((u32)pwrctrl->reg_cksys_2_srcclkena_mb & 0x1) << 5) |
+		      (((u32)pwrctrl->reg_cksys_2_vcore_rmb & 0x1) << 6) |
+		      (((u32)pwrctrl->reg_cksys_2_vrf18_rmb & 0x1) << 7) |
+		      (((u32)pwrctrl->reg_conn_apsrc_rmb & 0x1) << 8) |
+		      (((u32)pwrctrl->reg_conn_ddren_rmb & 0x1) << 9) |
+		      (((u32)pwrctrl->reg_conn_emi_rmb & 0x1) << 10) |
+		      (((u32)pwrctrl->reg_conn_infra_rmb & 0x1) << 11) |
+		      (((u32)pwrctrl->reg_conn_pmic_rmb & 0x1) << 12) |
+		      (((u32)pwrctrl->reg_conn_srcclkena_mb & 0x1) << 13) |
+		      (((u32)pwrctrl->reg_conn_srcclkenb_mb & 0x1) << 14) |
+		      (((u32)pwrctrl->reg_conn_vcore_rmb & 0x1) << 15) |
+		      (((u32)pwrctrl->reg_conn_vrf18_rmb & 0x1) << 16) |
+		      (((u32)pwrctrl->reg_corecfg_apsrc_rmb & 0x1) << 17) |
+		      (((u32)pwrctrl->reg_corecfg_ddren_rmb & 0x1) << 18) |
+		      (((u32)pwrctrl->reg_corecfg_emi_rmb & 0x1) << 19) |
+		      (((u32)pwrctrl->reg_corecfg_infra_rmb & 0x1) << 20) |
+		      (((u32)pwrctrl->reg_corecfg_pmic_rmb & 0x1) << 21) |
+		      (((u32)pwrctrl->reg_corecfg_srcclkena_mb & 0x1) << 22) |
+		      (((u32)pwrctrl->reg_corecfg_vcore_rmb & 0x1) << 23) |
+		      (((u32)pwrctrl->reg_corecfg_vrf18_rmb & 0x1) << 24));
+
+	/* SPM_SRC_MASK_7 */
+	mmio_write_32(SPM_SRC_MASK_7,
+		      (((u32)pwrctrl->reg_cpueb_apsrc_rmb & 0x1) << 0) |
+		      (((u32)pwrctrl->reg_cpueb_ddren_rmb & 0x1) << 1) |
+		      (((u32)pwrctrl->reg_cpueb_emi_rmb & 0x1) << 2) |
+		      (((u32)pwrctrl->reg_cpueb_infra_rmb & 0x1) << 3) |
+		      (((u32)pwrctrl->reg_cpueb_pmic_rmb & 0x1) << 4) |
+		      (((u32)pwrctrl->reg_cpueb_srcclkena_mb & 0x1) << 5) |
+		      (((u32)pwrctrl->reg_cpueb_vcore_rmb & 0x1) << 6) |
+		      (((u32)pwrctrl->reg_cpueb_vrf18_rmb & 0x1) << 7) |
+		      (((u32)pwrctrl->reg_disp0_apsrc_rmb & 0x1) << 8) |
+		      (((u32)pwrctrl->reg_disp0_ddren_rmb & 0x1) << 9) |
+		      (((u32)pwrctrl->reg_disp0_emi_rmb & 0x1) << 10) |
+		      (((u32)pwrctrl->reg_disp0_infra_rmb & 0x1) << 11) |
+		      (((u32)pwrctrl->reg_disp0_pmic_rmb & 0x1) << 12) |
+		      (((u32)pwrctrl->reg_disp0_srcclkena_mb & 0x1) << 13) |
+		      (((u32)pwrctrl->reg_disp0_vrf18_rmb & 0x1) << 14) |
+		      (((u32)pwrctrl->reg_disp1_apsrc_rmb & 0x1) << 15) |
+		      (((u32)pwrctrl->reg_disp1_ddren_rmb & 0x1) << 16) |
+		      (((u32)pwrctrl->reg_disp1_emi_rmb & 0x1) << 17) |
+		      (((u32)pwrctrl->reg_disp1_infra_rmb & 0x1) << 18) |
+		      (((u32)pwrctrl->reg_disp1_pmic_rmb & 0x1) << 19) |
+		      (((u32)pwrctrl->reg_disp1_srcclkena_mb & 0x1) << 20) |
+		      (((u32)pwrctrl->reg_disp1_vrf18_rmb & 0x1) << 21) |
+		      (((u32)pwrctrl->reg_dpm_apsrc_rmb & 0xf) << 22) |
+		      (((u32)pwrctrl->reg_dpm_ddren_rmb & 0xf) << 26));
+
+	/* SPM_SRC_MASK_8 */
+	mmio_write_32(SPM_SRC_MASK_8,
+		      (((u32)pwrctrl->reg_dpm_emi_rmb & 0xf) << 0) |
+		      (((u32)pwrctrl->reg_dpm_infra_rmb & 0xf) << 4) |
+		      (((u32)pwrctrl->reg_dpm_pmic_rmb & 0xf) << 8) |
+		      (((u32)pwrctrl->reg_dpm_srcclkena_mb & 0xf) << 12) |
+		      (((u32)pwrctrl->reg_dpm_vcore_rmb & 0xf) << 16) |
+		      (((u32)pwrctrl->reg_dpm_vrf18_rmb & 0xf) << 20) |
+		      (((u32)pwrctrl->reg_dpmaif_apsrc_rmb & 0x1) << 24) |
+		      (((u32)pwrctrl->reg_dpmaif_ddren_rmb & 0x1) << 25) |
+		      (((u32)pwrctrl->reg_dpmaif_emi_rmb & 0x1) << 26) |
+		      (((u32)pwrctrl->reg_dpmaif_infra_rmb & 0x1) << 27) |
+		      (((u32)pwrctrl->reg_dpmaif_pmic_rmb & 0x1) << 28) |
+		      (((u32)pwrctrl->reg_dpmaif_srcclkena_mb & 0x1) << 29) |
+		      (((u32)pwrctrl->reg_dpmaif_vcore_rmb & 0x1) << 30) |
+		      (((u32)pwrctrl->reg_dpmaif_vrf18_rmb & 0x1) << 31));
+
+	/* SPM_SRC_MASK_9 */
+	mmio_write_32(SPM_SRC_MASK_9,
+		      (((u32)pwrctrl->reg_dvfsrc_level_rmb & 0x1) << 0) |
+		      (((u32)pwrctrl->reg_emisys_apsrc_rmb & 0x1) << 1) |
+		      (((u32)pwrctrl->reg_emisys_ddren_rmb & 0x1) << 2) |
+		      (((u32)pwrctrl->reg_emisys_emi_rmb & 0x1) << 3) |
+		      (((u32)pwrctrl->reg_emisys_infra_rmb & 0x1) << 4) |
+		      (((u32)pwrctrl->reg_emisys_pmic_rmb & 0x1) << 5) |
+		      (((u32)pwrctrl->reg_emisys_srcclkena_mb & 0x1) << 6) |
+		      (((u32)pwrctrl->reg_emisys_vcore_rmb & 0x1) << 7) |
+		      (((u32)pwrctrl->reg_emisys_vrf18_rmb & 0x1) << 8) |
+		      (((u32)pwrctrl->reg_gce_apsrc_rmb & 0x1) << 9) |
+		      (((u32)pwrctrl->reg_gce_ddren_rmb & 0x1) << 10) |
+		      (((u32)pwrctrl->reg_gce_emi_rmb & 0x1) << 11) |
+		      (((u32)pwrctrl->reg_gce_infra_rmb & 0x1) << 12) |
+		      (((u32)pwrctrl->reg_gce_pmic_rmb & 0x1) << 13) |
+		      (((u32)pwrctrl->reg_gce_srcclkena_mb & 0x1) << 14) |
+		      (((u32)pwrctrl->reg_gce_vcore_rmb & 0x1) << 15) |
+		      (((u32)pwrctrl->reg_gce_vrf18_rmb & 0x1) << 16) |
+		      (((u32)pwrctrl->reg_gpueb_apsrc_rmb & 0x1) << 17) |
+		      (((u32)pwrctrl->reg_gpueb_ddren_rmb & 0x1) << 18) |
+		      (((u32)pwrctrl->reg_gpueb_emi_rmb & 0x1) << 19) |
+		      (((u32)pwrctrl->reg_gpueb_infra_rmb & 0x1) << 20) |
+		      (((u32)pwrctrl->reg_gpueb_pmic_rmb & 0x1) << 21) |
+		      (((u32)pwrctrl->reg_gpueb_srcclkena_mb & 0x1) << 22) |
+		      (((u32)pwrctrl->reg_gpueb_vcore_rmb & 0x1) << 23) |
+		      (((u32)pwrctrl->reg_gpueb_vrf18_rmb & 0x1) << 24) |
+		      (((u32)pwrctrl->reg_hwccf_apsrc_rmb & 0x1) << 25) |
+		      (((u32)pwrctrl->reg_hwccf_ddren_rmb & 0x1) << 26) |
+		      (((u32)pwrctrl->reg_hwccf_emi_rmb & 0x1) << 27) |
+		      (((u32)pwrctrl->reg_hwccf_infra_rmb & 0x1) << 28) |
+		      (((u32)pwrctrl->reg_hwccf_pmic_rmb & 0x1) << 29) |
+		      (((u32)pwrctrl->reg_hwccf_srcclkena_mb & 0x1) << 30) |
+		      (((u32)pwrctrl->reg_hwccf_vcore_rmb & 0x1) << 31));
+
+	/* SPM_SRC_MASK_10 */
+	mmio_write_32(SPM_SRC_MASK_10,
+		      (((u32)pwrctrl->reg_hwccf_vrf18_rmb & 0x1) << 0) |
+		      (((u32)pwrctrl->reg_img_apsrc_rmb & 0x1) << 1) |
+		      (((u32)pwrctrl->reg_img_ddren_rmb & 0x1) << 2) |
+		      (((u32)pwrctrl->reg_img_emi_rmb & 0x1) << 3) |
+		      (((u32)pwrctrl->reg_img_infra_rmb & 0x1) << 4) |
+		      (((u32)pwrctrl->reg_img_pmic_rmb & 0x1) << 5) |
+		      (((u32)pwrctrl->reg_img_srcclkena_mb & 0x1) << 6) |
+		      (((u32)pwrctrl->reg_img_vrf18_rmb & 0x1) << 7) |
+		      (((u32)pwrctrl->reg_infrasys_apsrc_rmb & 0x1) << 8) |
+		      (((u32)pwrctrl->reg_infrasys_ddren_rmb & 0x1) << 9) |
+		      (((u32)pwrctrl->reg_infrasys_emi_rmb & 0x1) << 10) |
+		      (((u32)pwrctrl->reg_infrasys_infra_rmb & 0x1) << 11) |
+		      (((u32)pwrctrl->reg_infrasys_pmic_rmb & 0x1) << 12) |
+		      (((u32)pwrctrl->reg_infrasys_srcclkena_mb & 0x1) << 13) |
+		      (((u32)pwrctrl->reg_infrasys_vcore_rmb & 0x1) << 14) |
+		      (((u32)pwrctrl->reg_infrasys_vrf18_rmb & 0x1) << 15) |
+		      (((u32)pwrctrl->reg_ipic_infra_rmb & 0x1) << 16) |
+		      (((u32)pwrctrl->reg_ipic_vrf18_rmb & 0x1) << 17) |
+		      (((u32)pwrctrl->reg_mcu_apsrc_rmb & 0x1) << 18) |
+		      (((u32)pwrctrl->reg_mcu_ddren_rmb & 0x1) << 19) |
+		      (((u32)pwrctrl->reg_mcu_emi_rmb & 0x1) << 20) |
+		      (((u32)pwrctrl->reg_mcu_infra_rmb & 0x1) << 21) |
+		      (((u32)pwrctrl->reg_mcu_pmic_rmb & 0x1) << 22) |
+		      (((u32)pwrctrl->reg_mcu_srcclkena_mb & 0x1) << 23) |
+		      (((u32)pwrctrl->reg_mcu_vcore_rmb & 0x1) << 24) |
+		      (((u32)pwrctrl->reg_mcu_vrf18_rmb & 0x1) << 25) |
+		      (((u32)pwrctrl->reg_md_apsrc_rmb & 0x1) << 26) |
+		      (((u32)pwrctrl->reg_md_ddren_rmb & 0x1) << 27) |
+		      (((u32)pwrctrl->reg_md_emi_rmb & 0x1) << 28) |
+		      (((u32)pwrctrl->reg_md_infra_rmb & 0x1) << 29) |
+		      (((u32)pwrctrl->reg_md_pmic_rmb & 0x1) << 30) |
+		      (((u32)pwrctrl->reg_md_srcclkena_mb & 0x1) << 31));
+
+	/* SPM_SRC_MASK_11 */
+	mmio_write_32(SPM_SRC_MASK_11,
+		      (((u32)pwrctrl->reg_md_srcclkena1_mb & 0x1) << 0) |
+		      (((u32)pwrctrl->reg_md_vcore_rmb & 0x1) << 1) |
+		      (((u32)pwrctrl->reg_md_vrf18_rmb & 0x1) << 2) |
+		      (((u32)pwrctrl->reg_mm_proc_apsrc_rmb & 0x1) << 3) |
+		      (((u32)pwrctrl->reg_mm_proc_ddren_rmb & 0x1) << 4) |
+		      (((u32)pwrctrl->reg_mm_proc_emi_rmb & 0x1) << 5) |
+		      (((u32)pwrctrl->reg_mm_proc_infra_rmb & 0x1) << 6) |
+		      (((u32)pwrctrl->reg_mm_proc_pmic_rmb & 0x1) << 7) |
+		      (((u32)pwrctrl->reg_mm_proc_srcclkena_mb & 0x1) << 8) |
+		      (((u32)pwrctrl->reg_mm_proc_vcore_rmb & 0x1) << 9) |
+		      (((u32)pwrctrl->reg_mm_proc_vrf18_rmb & 0x1) << 10) |
+		      (((u32)pwrctrl->reg_mml0_apsrc_rmb & 0x1) << 11) |
+		      (((u32)pwrctrl->reg_mml0_ddren_rmb & 0x1) << 12) |
+		      (((u32)pwrctrl->reg_mml0_emi_rmb & 0x1) << 13) |
+		      (((u32)pwrctrl->reg_mml0_infra_rmb & 0x1) << 14) |
+		      (((u32)pwrctrl->reg_mml0_pmic_rmb & 0x1) << 15) |
+		      (((u32)pwrctrl->reg_mml0_srcclkena_mb & 0x1) << 16) |
+		      (((u32)pwrctrl->reg_mml0_vrf18_rmb & 0x1) << 17) |
+		      (((u32)pwrctrl->reg_mml1_apsrc_rmb & 0x1) << 18) |
+		      (((u32)pwrctrl->reg_mml1_ddren_rmb & 0x1) << 19) |
+		      (((u32)pwrctrl->reg_mml1_emi_rmb & 0x1) << 20) |
+		      (((u32)pwrctrl->reg_mml1_infra_rmb & 0x1) << 21) |
+		      (((u32)pwrctrl->reg_mml1_pmic_rmb & 0x1) << 22) |
+		      (((u32)pwrctrl->reg_mml1_srcclkena_mb & 0x1) << 23) |
+		      (((u32)pwrctrl->reg_mml1_vrf18_rmb & 0x1) << 24) |
+		      (((u32)pwrctrl->reg_ovl0_apsrc_rmb & 0x1) << 25) |
+		      (((u32)pwrctrl->reg_ovl0_ddren_rmb & 0x1) << 26) |
+		      (((u32)pwrctrl->reg_ovl0_emi_rmb & 0x1) << 27) |
+		      (((u32)pwrctrl->reg_ovl0_infra_rmb & 0x1) << 28) |
+		      (((u32)pwrctrl->reg_ovl0_pmic_rmb & 0x1) << 29) |
+		      (((u32)pwrctrl->reg_ovl0_srcclkena_mb & 0x1) << 30) |
+		      (((u32)pwrctrl->reg_ovl0_vrf18_rmb & 0x1) << 31));
+
+	mmio_write_32(SPM_SRC_MASK_12,
+		      (((u32)pwrctrl->reg_ovl1_apsrc_rmb & 0x1) << 0) |
+		      (((u32)pwrctrl->reg_ovl1_ddren_rmb & 0x1) << 1) |
+		      (((u32)pwrctrl->reg_ovl1_emi_rmb & 0x1) << 2) |
+		      (((u32)pwrctrl->reg_ovl1_infra_rmb & 0x1) << 3) |
+		      (((u32)pwrctrl->reg_ovl1_pmic_rmb & 0x1) << 4) |
+		      (((u32)pwrctrl->reg_ovl1_srcclkena_mb & 0x1) << 5) |
+		      (((u32)pwrctrl->reg_ovl1_vrf18_rmb & 0x1) << 6) |
+		      (((u32)pwrctrl->reg_pcie0_apsrc_rmb & 0x1) << 7) |
+		      (((u32)pwrctrl->reg_pcie0_ddren_rmb & 0x1) << 8) |
+		      (((u32)pwrctrl->reg_pcie0_emi_rmb & 0x1) << 9) |
+		      (((u32)pwrctrl->reg_pcie0_infra_rmb & 0x1) << 10) |
+		      (((u32)pwrctrl->reg_pcie0_pmic_rmb & 0x1) << 11) |
+		      (((u32)pwrctrl->reg_pcie0_srcclkena_mb & 0x1) << 12) |
+		      (((u32)pwrctrl->reg_pcie0_vcore_rmb & 0x1) << 13) |
+		      (((u32)pwrctrl->reg_pcie0_vrf18_rmb & 0x1) << 14) |
+		      (((u32)pwrctrl->reg_pcie1_apsrc_rmb & 0x1) << 15) |
+		      (((u32)pwrctrl->reg_pcie1_ddren_rmb & 0x1) << 16) |
+		      (((u32)pwrctrl->reg_pcie1_emi_rmb & 0x1) << 17) |
+		      (((u32)pwrctrl->reg_pcie1_infra_rmb & 0x1) << 18) |
+		      (((u32)pwrctrl->reg_pcie1_pmic_rmb & 0x1) << 19) |
+		      (((u32)pwrctrl->reg_pcie1_srcclkena_mb & 0x1) << 20) |
+		      (((u32)pwrctrl->reg_pcie1_vcore_rmb & 0x1) << 21) |
+		      (((u32)pwrctrl->reg_pcie1_vrf18_rmb & 0x1) << 22) |
+		      (((u32)pwrctrl->reg_perisys_apsrc_rmb & 0x1) << 23) |
+		      (((u32)pwrctrl->reg_perisys_ddren_rmb & 0x1) << 24) |
+		      (((u32)pwrctrl->reg_perisys_emi_rmb & 0x1) << 25) |
+		      (((u32)pwrctrl->reg_perisys_infra_rmb & 0x1) << 26) |
+		      (((u32)pwrctrl->reg_perisys_pmic_rmb & 0x1) << 27) |
+		      (((u32)pwrctrl->reg_perisys_srcclkena_mb & 0x1) << 28) |
+		      (((u32)pwrctrl->reg_perisys_vcore_rmb & 0x1) << 29) |
+		      (((u32)pwrctrl->reg_perisys_vrf18_rmb & 0x1) << 30) |
+		      (((u32)pwrctrl->reg_pmsr_apsrc_rmb & 0x1) << 31));
+
+	/* SPM_SRC_MASK_13 */
+	mmio_write_32(SPM_SRC_MASK_13,
+		      (((u32)pwrctrl->reg_pmsr_ddren_rmb & 0x1) << 0) |
+		      (((u32)pwrctrl->reg_pmsr_emi_rmb & 0x1) << 1) |
+		      (((u32)pwrctrl->reg_pmsr_infra_rmb & 0x1) << 2) |
+		      (((u32)pwrctrl->reg_pmsr_pmic_rmb & 0x1) << 3) |
+		      (((u32)pwrctrl->reg_pmsr_srcclkena_mb & 0x1) << 4) |
+		      (((u32)pwrctrl->reg_pmsr_vcore_rmb & 0x1) << 5) |
+		      (((u32)pwrctrl->reg_pmsr_vrf18_rmb & 0x1) << 6) |
+		      (((u32)pwrctrl->reg_scp_apsrc_rmb & 0x1) << 7) |
+		      (((u32)pwrctrl->reg_scp_ddren_rmb & 0x1) << 8) |
+		      (((u32)pwrctrl->reg_scp_emi_rmb & 0x1) << 9) |
+		      (((u32)pwrctrl->reg_scp_infra_rmb & 0x1) << 10) |
+		      (((u32)pwrctrl->reg_scp_pmic_rmb & 0x1) << 11) |
+		      (((u32)pwrctrl->reg_scp_srcclkena_mb & 0x1) << 12) |
+		      (((u32)pwrctrl->reg_scp_vcore_rmb & 0x1) << 13) |
+		      (((u32)pwrctrl->reg_scp_vrf18_rmb & 0x1) << 14) |
+		      (((u32)pwrctrl->reg_spu_hwr_apsrc_rmb & 0x1) << 15) |
+		      (((u32)pwrctrl->reg_spu_hwr_ddren_rmb & 0x1) << 16) |
+		      (((u32)pwrctrl->reg_spu_hwr_emi_rmb & 0x1) << 17) |
+		      (((u32)pwrctrl->reg_spu_hwr_infra_rmb & 0x1) << 18) |
+		      (((u32)pwrctrl->reg_spu_hwr_pmic_rmb & 0x1) << 19) |
+		      (((u32)pwrctrl->reg_spu_hwr_srcclkena_mb & 0x1) << 20) |
+		      (((u32)pwrctrl->reg_spu_hwr_vcore_rmb & 0x1) << 21) |
+		      (((u32)pwrctrl->reg_spu_hwr_vrf18_rmb & 0x1) << 22) |
+		      (((u32)pwrctrl->reg_spu_ise_apsrc_rmb & 0x1) << 23) |
+		      (((u32)pwrctrl->reg_spu_ise_ddren_rmb & 0x1) << 24) |
+		      (((u32)pwrctrl->reg_spu_ise_emi_rmb & 0x1) << 25) |
+		      (((u32)pwrctrl->reg_spu_ise_infra_rmb & 0x1) << 26) |
+		      (((u32)pwrctrl->reg_spu_ise_pmic_rmb & 0x1) << 27) |
+		      (((u32)pwrctrl->reg_spu_ise_srcclkena_mb & 0x1) << 28) |
+		      (((u32)pwrctrl->reg_spu_ise_vcore_rmb & 0x1) << 29) |
+		      (((u32)pwrctrl->reg_spu_ise_vrf18_rmb & 0x1) << 30));
+
+	/* SPM_SRC_MASK_14 */
+	mmio_write_32(SPM_SRC_MASK_14,
+		      (((u32)pwrctrl->reg_srcclkeni_infra_rmb & 0x3) << 0) |
+		      (((u32)pwrctrl->reg_srcclkeni_pmic_rmb & 0x3) << 2) |
+		      (((u32)pwrctrl->reg_srcclkeni_srcclkena_mb & 0x3) << 4) |
+		      (((u32)pwrctrl->reg_srcclkeni_vcore_rmb & 0x3) << 6) |
+		      (((u32)pwrctrl->reg_sspm_apsrc_rmb & 0x1) << 8) |
+		      (((u32)pwrctrl->reg_sspm_ddren_rmb & 0x1) << 9) |
+		      (((u32)pwrctrl->reg_sspm_emi_rmb & 0x1) << 10) |
+		      (((u32)pwrctrl->reg_sspm_infra_rmb & 0x1) << 11) |
+		      (((u32)pwrctrl->reg_sspm_pmic_rmb & 0x1) << 12) |
+		      (((u32)pwrctrl->reg_sspm_srcclkena_mb & 0x1) << 13) |
+		      (((u32)pwrctrl->reg_sspm_vrf18_rmb & 0x1) << 14) |
+		      (((u32)pwrctrl->reg_ssrsys_apsrc_rmb & 0x1) << 15) |
+		      (((u32)pwrctrl->reg_ssrsys_ddren_rmb & 0x1) << 16) |
+		      (((u32)pwrctrl->reg_ssrsys_emi_rmb & 0x1) << 17) |
+		      (((u32)pwrctrl->reg_ssrsys_infra_rmb & 0x1) << 18) |
+		      (((u32)pwrctrl->reg_ssrsys_pmic_rmb & 0x1) << 19) |
+		      (((u32)pwrctrl->reg_ssrsys_srcclkena_mb & 0x1) << 20) |
+		      (((u32)pwrctrl->reg_ssrsys_vcore_rmb & 0x1) << 21) |
+		      (((u32)pwrctrl->reg_ssrsys_vrf18_rmb & 0x1) << 22) |
+		      (((u32)pwrctrl->reg_ssusb_apsrc_rmb & 0x1) << 23) |
+		      (((u32)pwrctrl->reg_ssusb_ddren_rmb & 0x1) << 24) |
+		      (((u32)pwrctrl->reg_ssusb_emi_rmb & 0x1) << 25) |
+		      (((u32)pwrctrl->reg_ssusb_infra_rmb & 0x1) << 26) |
+		      (((u32)pwrctrl->reg_ssusb_pmic_rmb & 0x1) << 27) |
+		      (((u32)pwrctrl->reg_ssusb_srcclkena_mb & 0x1) << 28) |
+		      (((u32)pwrctrl->reg_ssusb_vcore_rmb & 0x1) << 29) |
+		      (((u32)pwrctrl->reg_ssusb_vrf18_rmb & 0x1) << 30) |
+		      (((u32)pwrctrl->reg_uart_hub_infra_rmb & 0x1) << 31));
+
+	/* SPM_SRC_MASK_15 */
+	mmio_write_32(SPM_SRC_MASK_15,
+		      (((u32)pwrctrl->reg_uart_hub_pmic_rmb & 0x1) << 0) |
+		      (((u32)pwrctrl->reg_uart_hub_srcclkena_mb & 0x1) << 1) |
+		      (((u32)pwrctrl->reg_uart_hub_vcore_rmb & 0x1) << 2) |
+		      (((u32)pwrctrl->reg_uart_hub_vrf18_rmb & 0x1) << 3) |
+		      (((u32)pwrctrl->reg_ufs_apsrc_rmb & 0x1) << 4) |
+		      (((u32)pwrctrl->reg_ufs_ddren_rmb & 0x1) << 5) |
+		      (((u32)pwrctrl->reg_ufs_emi_rmb & 0x1) << 6) |
+		      (((u32)pwrctrl->reg_ufs_infra_rmb & 0x1) << 7) |
+		      (((u32)pwrctrl->reg_ufs_pmic_rmb & 0x1) << 8) |
+		      (((u32)pwrctrl->reg_ufs_srcclkena_mb & 0x1) << 9) |
+		      (((u32)pwrctrl->reg_ufs_vcore_rmb & 0x1) << 10) |
+		      (((u32)pwrctrl->reg_ufs_vrf18_rmb & 0x1) << 11) |
+		      (((u32)pwrctrl->reg_vdec_apsrc_rmb & 0x1) << 12) |
+		      (((u32)pwrctrl->reg_vdec_ddren_rmb & 0x1) << 13) |
+		      (((u32)pwrctrl->reg_vdec_emi_rmb & 0x1) << 14) |
+		      (((u32)pwrctrl->reg_vdec_infra_rmb & 0x1) << 15) |
+		      (((u32)pwrctrl->reg_vdec_pmic_rmb & 0x1) << 16) |
+		      (((u32)pwrctrl->reg_vdec_srcclkena_mb & 0x1) << 17) |
+		      (((u32)pwrctrl->reg_vdec_vrf18_rmb & 0x1) << 18) |
+		      (((u32)pwrctrl->reg_venc_apsrc_rmb & 0x1) << 19) |
+		      (((u32)pwrctrl->reg_venc_ddren_rmb & 0x1) << 20) |
+		      (((u32)pwrctrl->reg_venc_emi_rmb & 0x1) << 21) |
+		      (((u32)pwrctrl->reg_venc_infra_rmb & 0x1) << 22) |
+		      (((u32)pwrctrl->reg_venc_pmic_rmb & 0x1) << 23) |
+		      (((u32)pwrctrl->reg_venc_srcclkena_mb & 0x1) << 24) |
+		      (((u32)pwrctrl->reg_venc_vrf18_rmb & 0x1) << 25) |
+		      (((u32)pwrctrl->reg_vlpcfg_apsrc_rmb & 0x1) << 26) |
+		      (((u32)pwrctrl->reg_vlpcfg_ddren_rmb & 0x1) << 27) |
+		      (((u32)pwrctrl->reg_vlpcfg_emi_rmb & 0x1) << 28) |
+		      (((u32)pwrctrl->reg_vlpcfg_infra_rmb & 0x1) << 29) |
+		      (((u32)pwrctrl->reg_vlpcfg_pmic_rmb & 0x1) << 30) |
+		      (((u32)pwrctrl->reg_vlpcfg_srcclkena_mb & 0x1) << 31));
+
+	/* SPM_SRC_MASK_16 */
+	mmio_write_32(SPM_SRC_MASK_16,
+		      (((u32)pwrctrl->reg_vlpcfg_vcore_rmb & 0x1) << 0) |
+		      (((u32)pwrctrl->reg_vlpcfg_vrf18_rmb & 0x1) << 1) |
+		      (((u32)pwrctrl->reg_vlpcfg1_apsrc_rmb & 0x1) << 2) |
+		      (((u32)pwrctrl->reg_vlpcfg1_ddren_rmb & 0x1) << 3) |
+		      (((u32)pwrctrl->reg_vlpcfg1_emi_rmb & 0x1) << 4) |
+		      (((u32)pwrctrl->reg_vlpcfg1_infra_rmb & 0x1) << 5) |
+		      (((u32)pwrctrl->reg_vlpcfg1_pmic_rmb & 0x1) << 6) |
+		      (((u32)pwrctrl->reg_vlpcfg1_srcclkena_mb & 0x1) << 7) |
+		      (((u32)pwrctrl->reg_vlpcfg1_vcore_rmb & 0x1) << 8) |
+		      (((u32)pwrctrl->reg_vlpcfg1_vrf18_rmb & 0x1) << 9));
+
+	/* SPM_SRC_MASK_17 */
+	mmio_write_32(SPM_SRC_MASK_17,
+		      (((u32)pwrctrl->reg_spm_sw_vcore_rmb & 0xffff) << 0) |
+		      (((u32)pwrctrl->reg_spm_sw_pmic_rmb & 0xffff) << 16));
+
+	/* SPM_SRC_MASK_18 */
+	mmio_write_32(SPM_SRC_MASK_18,
+		      (((u32)pwrctrl->reg_spm_sw_srcclkena_mb & 0xffff) << 0));
+
+	/* SPM_EVENT_CON_MISC */
+	mmio_write_32(SPM_EVENT_CON_MISC,
+		      (((u32)pwrctrl->reg_srcclken_fast_resp & 0x1) << 0) |
+		      (((u32)pwrctrl->reg_csyspwrup_ack_mask & 0x1) << 1));
+
+	/* SPM_WAKE_MASK*/
+	mmio_write_32(SPM_WAKEUP_EVENT_MASK,
+		      (((u32)pwrctrl->reg_wake_mask & 0xffffffff) << 0));
+
+	/* SPM_WAKEUP_EVENT_EXT_MASK */
+	mmio_write_32(SPM_WAKEUP_EVENT_EXT_MASK,
+		      (((u32)pwrctrl->reg_ext_wake_mask & 0xffffffff) << 0));
+}
+
+#define CHECK_ONE	0xffffffff
+#define CHECK_ZERO	0x0
+static int32_t __spm_check_ack(u32 reg, u32 mask, u32 check_en)
+{
+	u32 val;
+
+	val = mmio_read_32(reg);
+	if ((val & mask) == (mask & check_en))
+		return 0;
+	return -1;
+}
+
+int32_t __spm_wait_spm_request_ack(u32 spm_resource_req, u32 timeout_us)
+{
+	u32 spm_ctrl0_mask, spm_ctrl1_mask;
+	int32_t ret, retry;
+
+	if (spm_resource_req == 0)
+		return 0;
+
+	spm_ctrl0_mask = 0;
+	spm_ctrl1_mask = 0;
+
+	if (spm_resource_req & (MT_SPM_XO_FPM | MT_SPM_26M))
+		spm_ctrl0_mask |=  CTRL0_SC_MD26M_CK_OFF;
+
+	if (spm_resource_req & MT_SPM_VCORE)
+		spm_ctrl1_mask |= CTRL1_SPM_VCORE_INTERNAL_ACK;
+	if (spm_resource_req & MT_SPM_PMIC)
+		spm_ctrl1_mask |= CTRL1_SPM_PMIC_INTERNAL_ACK;
+	if (spm_resource_req & MT_SPM_INFRA)
+		spm_ctrl1_mask |= CTRL1_SPM_INFRA_INTERNAL_ACK;
+	if (spm_resource_req & MT_SPM_SYSPLL)
+		spm_ctrl1_mask |= CTRL1_SPM_VRF18_INTERNAL_ACK;
+	if (spm_resource_req & MT_SPM_EMI)
+		spm_ctrl1_mask |= CTRL1_SPM_EMI_INTERNAL_ACK;
+	if (spm_resource_req & MT_SPM_DRAM_S0)
+		spm_ctrl1_mask |= CTRL1_SPM_APSRC_INTERNAL_ACK;
+	if (spm_resource_req & MT_SPM_DRAM_S1)
+		spm_ctrl1_mask |= CTRL1_SPM_DDREN_INTERNAL_ACK;
+
+	retry = -1;
+	ret = 0;
+
+	while (retry++ < timeout_us) {
+		udelay(1);
+		if (spm_ctrl0_mask != 0) {
+			ret = __spm_check_ack(MD32PCM_SCU_CTRL0,
+					      spm_ctrl0_mask,
+					      CHECK_ZERO);
+			if (ret)
+				continue;
+		}
+		if (spm_ctrl1_mask != 0) {
+			ret = __spm_check_ack(MD32PCM_SCU_CTRL1,
+					      spm_ctrl1_mask,
+					      CHECK_ONE);
+			if (ret)
+				continue;
+		}
+		break;
+	}
+
+	return ret;
+}
+
+void __spm_set_wakeup_event(const struct pwr_ctrl *pwrctrl)
+{
+	u32 val, mask;
+
+	/* Toggle event counter clear */
+	mmio_write_32(SPM_EVENT_COUNTER_CLEAR, REG_SPM_EVENT_COUNTER_CLR_LSB);
+	/* Toggle for reset SYS TIMER start point */
+	mmio_setbits_32(SYS_TIMER_CON, SYS_TIMER_START_EN_LSB);
+
+	if (pwrctrl->timer_val_cust == 0)
+		val = pwrctrl->timer_val ? pwrctrl->timer_val : PCM_TIMER_MAX;
+	else
+		val = pwrctrl->timer_val_cust;
+
+	mmio_write_32(PCM_TIMER_VAL, val);
+	mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY | REG_PCM_TIMER_EN_LSB);
+
+	/* Unmask AP wakeup source */
+	if (pwrctrl->wake_src_cust == 0)
+		mask = pwrctrl->wake_src;
+	else
+		mask = pwrctrl->wake_src_cust;
+
+	if (pwrctrl->reg_csyspwrup_ack_mask)
+		mask &= ~R12_CSYSPWREQ_B;
+	mmio_write_32(SPM_WAKEUP_EVENT_MASK, ~mask);
+
+	/* Unmask SPM ISR (keep TWAM setting) */
+	mmio_setbits_32(SPM_IRQ_MASK, ISRM_RET_IRQ_AUX);
+
+	/* Toggle event counter clear */
+	mmio_write_32(SPM_EVENT_COUNTER_CLEAR, 0);
+	/* Toggle for reset SYS TIMER start point */
+	mmio_clrbits_32(SYS_TIMER_CON, SYS_TIMER_START_EN_LSB);
+}
+
+void __spm_set_fw_resume_option(struct pwr_ctrl *pwrctrl)
+{
+#if SPM_FW_NO_RESUME
+    /* Do Nothing */
+#else
+	pwrctrl->pcm_flags1 |= SPM_FLAG1_DISABLE_NO_RESUME;
+#endif
+}
+
+void __spm_set_pcm_flags(struct pwr_ctrl *pwrctrl)
+{
+	/* Set PCM flags and data */
+	if (pwrctrl->pcm_flags_cust_clr != 0)
+		pwrctrl->pcm_flags &= ~pwrctrl->pcm_flags_cust_clr;
+	if (pwrctrl->pcm_flags_cust_set != 0)
+		pwrctrl->pcm_flags |= pwrctrl->pcm_flags_cust_set;
+	if (pwrctrl->pcm_flags1_cust_clr != 0)
+		pwrctrl->pcm_flags1 &= ~pwrctrl->pcm_flags1_cust_clr;
+	if (pwrctrl->pcm_flags1_cust_set != 0)
+		pwrctrl->pcm_flags1 |= pwrctrl->pcm_flags1_cust_set;
+
+	mmio_write_32(SPM_SW_FLAG_0, pwrctrl->pcm_flags);
+
+	mmio_write_32(SPM_SW_FLAG_1, pwrctrl->pcm_flags1);
+
+	mmio_write_32(SPM_SW_RSV_7, pwrctrl->pcm_flags);
+
+	mmio_write_32(SPM_SW_RSV_8, pwrctrl->pcm_flags1);
+}
+
+void __spm_kick_pcm_to_run(struct pwr_ctrl *pwrctrl)
+{
+	/* Waiting for loading SPMFW done*/
+	while (mmio_read_32(MD32PCM_DMA0_RLCT) != 0x0)
+		;
+
+	__spm_set_pcm_flags(pwrctrl);
+
+	udelay(SPM_INIT_DONE_US);
+}
+
+void __spm_get_wakeup_status(struct wake_status *wakesta,
+			     uint32_t ext_status)
+{
+	/* Get wakeup event */
+	wakesta->tr.comm.r12 = mmio_read_32(SPM_BK_WAKE_EVENT);
+	wakesta->r12_ext = mmio_read_32(SPM_WAKEUP_EXT_STA);
+	wakesta->tr.comm.raw_sta = mmio_read_32(SPM_WAKEUP_STA);
+	wakesta->raw_ext_sta = mmio_read_32(SPM_WAKEUP_EXT_STA);
+	wakesta->md32pcm_wakeup_sta = mmio_read_32(MD32PCM_WAKEUP_STA);
+	wakesta->md32pcm_event_sta = mmio_read_32(MD32PCM_EVENT_STA);
+	wakesta->wake_misc = mmio_read_32(SPM_BK_WAKE_MISC);
+
+	/* Get sleep time */
+	wakesta->tr.comm.timer_out = mmio_read_32(SPM_BK_PCM_TIMER);
+	wakesta->tr.comm.r13 = mmio_read_32(MD32PCM_SCU_STA0);
+	wakesta->tr.comm.req_sta0 = mmio_read_32(SPM_REQ_STA_0);
+	wakesta->tr.comm.req_sta1 = mmio_read_32(SPM_REQ_STA_1);
+	wakesta->tr.comm.req_sta2 = mmio_read_32(SPM_REQ_STA_2);
+	wakesta->tr.comm.req_sta3 = mmio_read_32(SPM_REQ_STA_3);
+	wakesta->tr.comm.req_sta4 = mmio_read_32(SPM_REQ_STA_4);
+	wakesta->tr.comm.req_sta5 = mmio_read_32(SPM_REQ_STA_5);
+	wakesta->tr.comm.req_sta6 = mmio_read_32(SPM_REQ_STA_6);
+	wakesta->tr.comm.req_sta7 = mmio_read_32(SPM_REQ_STA_7);
+	wakesta->tr.comm.req_sta8 = mmio_read_32(SPM_REQ_STA_8);
+	wakesta->tr.comm.req_sta9 = mmio_read_32(SPM_REQ_STA_9);
+	wakesta->tr.comm.req_sta10 = mmio_read_32(SPM_REQ_STA_10);
+	wakesta->tr.comm.req_sta11 = mmio_read_32(SPM_REQ_STA_11);
+	wakesta->tr.comm.req_sta12 = mmio_read_32(SPM_REQ_STA_12);
+	wakesta->tr.comm.req_sta13 = mmio_read_32(SPM_REQ_STA_13);
+	wakesta->tr.comm.req_sta14 = mmio_read_32(SPM_REQ_STA_14);
+	wakesta->tr.comm.req_sta15 = mmio_read_32(SPM_REQ_STA_15);
+	wakesta->tr.comm.req_sta16 = mmio_read_32(SPM_REQ_STA_16);
+
+	/* Get debug flag for PCM execution check */
+	wakesta->tr.comm.debug_flag = mmio_read_32(PCM_WDT_LATCH_SPARE_0);
+	wakesta->tr.comm.debug_flag1 = mmio_read_32(PCM_WDT_LATCH_SPARE_1);
+
+	/* Get backup SW flag status */
+	wakesta->tr.comm.b_sw_flag0 = mmio_read_32(SPM_SW_RSV_7);
+	wakesta->tr.comm.b_sw_flag1 = mmio_read_32(SPM_SW_RSV_8);
+
+	/* Get ISR status */
+	wakesta->isr = mmio_read_32(SPM_IRQ_STA);
+
+	/* Get SW flag status */
+	wakesta->sw_flag0 = mmio_read_32(SPM_SW_FLAG_0);
+	wakesta->sw_flag1 = mmio_read_32(SPM_SW_FLAG_1);
+
+	/* Check abort */
+	wakesta->is_abort = wakesta->tr.comm.debug_flag1 & DEBUG_ABORT_MASK_1;
+}
+
+void __spm_clean_after_wakeup(void)
+{
+	/*
+	 * Copy SPM_WAKEUP_STA to SPM_BK_WAKE_EVENT
+	 * before clear SPM_WAKEUP_STA
+	 *
+	 * CPU dormant driver @kernel will copy  edge-trig IRQ pending
+	 * (recorded @SPM_BK_WAKE_EVENT) to GIC
+	 */
+	mmio_write_32(SPM_BK_WAKE_EVENT, mmio_read_32(SPM_WAKEUP_STA) |
+		mmio_read_32(SPM_BK_WAKE_EVENT));
+
+	mmio_write_32(SPM_CPU_WAKEUP_EVENT, 0);
+
+	/* Clean wakeup event raw status (for edge trigger event) */
+	mmio_write_32(SPM_WAKEUP_EVENT_MASK, 0xefffffff);
+
+	/* Clean ISR status (except TWAM) */
+	mmio_setbits_32(SPM_IRQ_MASK,  ISRM_ALL_EXC_TWAM);
+	mmio_write_32(SPM_IRQ_STA, ISRC_ALL_EXC_TWAM);
+	mmio_write_32(SPM_SWINT_CLR, PCM_SW_INT_ALL);
+}
+
+void __spm_set_pcm_wdt(int en)
+{
+	/* Enable PCM WDT (normal mode) to start count if needed */
+	if (en) {
+		mmio_clrsetbits_32(PCM_CON1, REG_PCM_WDT_WAKE_LSB,
+				   SPM_REGWR_CFG_KEY);
+
+		if (mmio_read_32(PCM_TIMER_VAL) > PCM_TIMER_MAX)
+			mmio_write_32(PCM_TIMER_VAL, PCM_TIMER_MAX);
+		mmio_write_32(PCM_WDT_VAL, mmio_read_32(PCM_TIMER_VAL) +
+			      PCM_WDT_TIMEOUT);
+		mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY |
+				REG_PCM_WDT_EN_LSB);
+	} else {
+		mmio_clrsetbits_32(PCM_CON1, REG_PCM_WDT_EN_LSB,
+				   SPM_REGWR_CFG_KEY);
+	}
+}
+
+u32 __spm_get_pcm_timer_val(void)
+{
+	return mmio_read_32(PCM_TIMER_VAL) >> 15;
+}
+
+void __spm_send_cpu_wakeup_event(void)
+{
+	mmio_write_32(SPM_CPU_WAKEUP_EVENT, 1);
+}
+
+void __spm_ext_int_wakeup_req_clr(void)
+{
+	u32 cpu = plat_my_core_pos();
+
+	mmio_write_32(EXT_INT_WAKEUP_REQ_CLR, (1U << cpu));
+
+	/* Clear spm2mcupm wakeup interrupt status */
+	mmio_clrbits_32(SPM2MCUPM_CON, SPM2MCUPM_SW_INT_LSB);
+}
+
+void __spm_hw_s1_state_monitor(int en, uint32_t *status)
+{
+	uint32_t reg;
+
+	if (en) {
+		mmio_clrsetbits_32(SPM_ACK_CHK_CON_3,
+				   SPM_ACK_CHK_3_CON_CLR_ALL,
+				   SPM_ACK_CHK_3_CON_EN);
+	} else {
+
+		reg = mmio_read_32(SPM_ACK_CHK_CON_3);
+
+		if (reg & SPM_ACK_CHK_3_CON_RESULT) {
+			if (status)
+				*status |= SPM_INTERNAL_STATUS_HW_S1;
+		}
+		mmio_clrsetbits_32(SPM_ACK_CHK_CON_3, SPM_ACK_CHK_3_CON_EN,
+				   (SPM_ACK_CHK_3_CON_HW_MODE_TRIG |
+				   SPM_ACK_CHK_3_CON_CLR_ALL));
+	}
+}
diff --git a/plat/mediatek/drivers/spm/mt8196/mt_spm_internal.h b/plat/mediatek/drivers/spm/mt8196/mt_spm_internal.h
new file mode 100644
index 000000000..5e08f3da4
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8196/mt_spm_internal.h
@@ -0,0 +1,1206 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_INTERNAL_H
+#define MT_SPM_INTERNAL_H
+
+#include <dbg_ctrl.h>
+#include <mt_spm.h>
+#include <mt_spm_stats.h>
+
+/**************************************
+ * Config and Parameter
+ **************************************/
+#define POWER_ON_VAL0_DEF	0x0000F100
+/* SPM_POWER_ON_VAL1 */
+#define POWER_ON_VAL1_DEF	0x003FFE20
+/* SPM_WAKE_MASK*/
+#define SPM_WAKEUP_EVENT_MASK_DEF	0xEFFFFFFF
+
+#define PCM_WDT_TIMEOUT		(30 * 32768)    /* 30s */
+#define PCM_TIMER_MAX		(0xFFFFFFFF)
+/**************************************
+ * Define and Declare
+ **************************************/
+/* PCM_PWR_IO_EN */
+#define PCM_PWRIO_EN_R0		BIT(0)
+#define PCM_PWRIO_EN_R7		BIT(7)
+#define PCM_RF_SYNC_R0		BIT(16)
+#define PCM_RF_SYNC_R6		BIT(22)
+#define PCM_RF_SYNC_R7		BIT(23)
+
+/* SPM_SWINT */
+#define PCM_SW_INT0		BIT(0)
+#define PCM_SW_INT1		BIT(1)
+#define PCM_SW_INT2		BIT(2)
+#define PCM_SW_INT3		BIT(3)
+#define PCM_SW_INT4		BIT(4)
+#define PCM_SW_INT5		BIT(5)
+#define PCM_SW_INT6		BIT(6)
+#define PCM_SW_INT7		BIT(7)
+#define PCM_SW_INT8		BIT(8)
+#define PCM_SW_INT9		BIT(9)
+#define PCM_SW_INT_ALL		(PCM_SW_INT9 | PCM_SW_INT8 | PCM_SW_INT7 | \
+				 PCM_SW_INT6 | PCM_SW_INT5 | PCM_SW_INT4 | \
+				 PCM_SW_INT3 | PCM_SW_INT2 | PCM_SW_INT1 | \
+				 PCM_SW_INT0)
+
+/* SPM_AP_STANDBY_CON */
+#define WFI_OP_AND		1
+#define WFI_OP_OR		0
+
+/* SPM_IRQ_MASK */
+#define ISRM_TWAM		BIT(2)
+#define ISRM_PCM_RETURN		BIT(3)
+#define ISRM_RET_IRQ0		BIT(8)
+#define ISRM_RET_IRQ1		BIT(9)
+#define ISRM_RET_IRQ2		BIT(10)
+#define ISRM_RET_IRQ3		BIT(11)
+#define ISRM_RET_IRQ4		BIT(12)
+#define ISRM_RET_IRQ5		BIT(13)
+#define ISRM_RET_IRQ6		BIT(14)
+#define ISRM_RET_IRQ7		BIT(15)
+#define ISRM_RET_IRQ8		BIT(16)
+#define ISRM_RET_IRQ9		BIT(17)
+#define ISRM_RET_IRQ_AUX	((ISRM_RET_IRQ9) | (ISRM_RET_IRQ8) | \
+				 (ISRM_RET_IRQ7) | (ISRM_RET_IRQ6) | \
+				 (ISRM_RET_IRQ5) | (ISRM_RET_IRQ4) | \
+				 (ISRM_RET_IRQ3) | (ISRM_RET_IRQ2) | \
+				 (ISRM_RET_IRQ1))
+#define ISRM_ALL_EXC_TWAM	(ISRM_RET_IRQ_AUX)
+#define ISRM_ALL		(ISRM_ALL_EXC_TWAM | ISRM_TWAM)
+
+/* SPM_IRQ_STA */
+#define ISRS_TWAM		BIT(2)
+#define ISRS_PCM_RETURN		BIT(3)
+#define ISRC_TWAM		ISRS_TWAM
+#define ISRC_ALL_EXC_TWAM	ISRS_PCM_RETURN
+#define ISRC_ALL		(ISRC_ALL_EXC_TWAM | ISRC_TWAM)
+
+/* SPM_WAKEUP_MISC */
+#define WAKE_MISC_GIC_WAKEUP			0x3FF  /* bit0 ~ bit9 */
+#define WAKE_MISC_DVFSRC_IRQ			DVFSRC_IRQ_LSB
+#define WAKE_MISC_REG_CPU_WAKEUP		SPM_WAKEUP_MISC_REG_CPU_WAKEUP_LSB
+#define WAKE_MISC_PCM_TIMER_EVENT		PCM_TIMER_EVENT_LSB
+#define WAKE_MISC_PMIC_OUT_B			(BIT(19) | BIT(20))
+#define WAKE_MISC_TWAM_IRQ_B			TWAM_IRQ_B_LSB
+#define WAKE_MISC_SPM_ACK_CHK_WAKEUP_0		SPM_ACK_CHK_WAKEUP_0_LSB
+#define WAKE_MISC_SPM_ACK_CHK_WAKEUP_1		SPM_ACK_CHK_WAKEUP_1_LSB
+#define WAKE_MISC_SPM_ACK_CHK_WAKEUP_2		SPM_ACK_CHK_WAKEUP_2_LSB
+#define WAKE_MISC_SPM_ACK_CHK_WAKEUP_3		SPM_ACK_CHK_WAKEUP_3_LSB
+#define WAKE_MISC_SPM_ACK_CHK_WAKEUP_ALL	SPM_ACK_CHK_WAKEUP_ALL_LSB
+#define WAKE_MISC_PMIC_IRQ_ACK			PMIC_IRQ_ACK_LSB
+#define WAKE_MISC_PMIC_SCP_IRQ			PMIC_SCP_IRQ_LSB
+
+/* MD32PCM ADDR for SPM code fetch */
+#define MD32PCM_BASE				(SPM_BASE + 0x0A00)
+#define MD32PCM_CFGREG_SW_RSTN			(MD32PCM_BASE + 0x0000)
+#define MD32PCM_DMA0_SRC			(MD32PCM_BASE + 0x0200)
+#define MD32PCM_DMA0_DST			(MD32PCM_BASE + 0x0204)
+#define MD32PCM_DMA0_WPPT			(MD32PCM_BASE + 0x0208)
+#define MD32PCM_DMA0_WPTO			(MD32PCM_BASE + 0x020C)
+#define MD32PCM_DMA0_COUNT			(MD32PCM_BASE + 0x0210)
+#define MD32PCM_DMA0_CON			(MD32PCM_BASE + 0x0214)
+#define MD32PCM_DMA0_START			(MD32PCM_BASE + 0x0218)
+#define MD32PCM_DMA0_RLCT			(MD32PCM_BASE + 0x0224)
+#define MD32PCM_INTC_IRQ_RAW_STA		(MD32PCM_BASE + 0x033C)
+
+/* ABORT MASK for DEBUG FOORTPRINT */
+#define DEBUG_ABORT_MASK (SPM_DBG_DEBUG_IDX_DRAM_SREF_ABORT_IN_APSRC | \
+			  SPM_DBG_DEBUG_IDX_DRAM_SREF_ABORT_IN_DDREN)
+
+#define DEBUG_ABORT_MASK_1 (SPM_DBG1_DEBUG_IDX_VTCXO_SLEEP_ABORT_0 | \
+			    SPM_DBG1_DEBUG_IDX_VTCXO_SLEEP_ABORT_1 | \
+			    SPM_DBG1_DEBUG_IDX_VCORE_SLEEP_ABORT_0 | \
+			    SPM_DBG1_DEBUG_IDX_VCORE_SLEEP_ABORT_1 | \
+			    SPM_DBG1_DEBUG_IDX_PMIC_IRQ_ACK_LOW_ABORT | \
+			    SPM_DBG1_DEBUG_IDX_PMIC_IRQ_ACK_HIGH_ABORT | \
+			    SPM_DBG1_DEBUG_IDX_PWRAP_SLEEP_ACK_LOW_ABORT | \
+			    SPM_DBG1_DEBUG_IDX_PWRAP_SLEEP_ACK_HIGH_ABORT | \
+			    SPM_DBG1_DEBUG_IDX_SCP_SLP_ACK_LOW_ABORT | \
+			    SPM_DBG1_DEBUG_IDX_SCP_SLP_ACK_HIGH_ABORT | \
+			    SPM_DBG1_DEBUG_IDX_SPM_PMIF_CMD_RDY_ABORT)
+
+struct pwr_ctrl {
+
+	/* For SPM */
+	uint32_t pcm_flags;
+	uint32_t pcm_flags_cust;
+	uint32_t pcm_flags_cust_set;
+	uint32_t pcm_flags_cust_clr;
+	uint32_t pcm_flags1;
+	uint32_t pcm_flags1_cust;
+	uint32_t pcm_flags1_cust_set;
+	uint32_t pcm_flags1_cust_clr;
+	uint32_t timer_val;
+	uint32_t timer_val_cust;
+	uint32_t timer_val_ramp_en;
+	uint32_t timer_val_ramp_en_sec;
+	uint32_t wake_src;
+	uint32_t wake_src_cust;
+	uint32_t wakelock_timer_val;
+	uint8_t wdt_disable;
+	/* Auto-gen Start */
+
+	/* SPM_CLK_CON */
+	uint8_t reg_spm_lock_infra_dcm_lsb;
+	uint8_t reg_cxo32k_remove_en_lsb;
+	uint8_t reg_spm_leave_suspend_merge_mask_lsb;
+	uint8_t reg_sysclk0_src_mb_lsb;
+	uint8_t reg_sysclk1_src_mb_lsb;
+	uint8_t reg_sysclk2_src_mb_lsb;
+
+	/* SPM_AP_STANDBY_CON */
+	uint8_t reg_wfi_op;
+	uint8_t reg_wfi_type;
+	uint8_t reg_mp0_cputop_idle_mask;
+	uint8_t reg_mp1_cputop_idle_mask;
+	uint8_t reg_mcusys_idle_mask;
+	uint8_t reg_csyspwrup_req_mask_lsb;
+	uint8_t reg_wfi_af_sel;
+	uint8_t reg_cpu_sleep_wfi;
+
+	/* SPM_SRC_REQ */
+	uint8_t reg_spm_adsp_mailbox_req;
+	uint8_t reg_spm_apsrc_req;
+	uint8_t reg_spm_ddren_req;
+	uint8_t reg_spm_dvfs_req;
+	uint8_t reg_spm_emi_req;
+	uint8_t reg_spm_f26m_req;
+	uint8_t reg_spm_infra_req;
+	uint8_t reg_spm_pmic_req;
+	uint8_t reg_spm_scp_mailbox_req;
+	uint8_t reg_spm_sspm_mailbox_req;
+	uint8_t reg_spm_sw_mailbox_req;
+	uint8_t reg_spm_vcore_req;
+	uint8_t reg_spm_vrf18_req;
+	uint8_t adsp_mailbox_state;
+	uint8_t apsrc_state;
+	uint8_t ddren_state;
+	uint8_t dvfs_state;
+	uint8_t emi_state;
+	uint8_t f26m_state;
+	uint8_t infra_state;
+	uint8_t pmic_state;
+	uint8_t scp_mailbox_state;
+	uint8_t sspm_mailbox_state;
+	uint8_t sw_mailbox_state;
+	uint8_t vcore_state;
+	uint8_t vrf18_state;
+
+	/* SPM_SRC_MASK_0 */
+	uint8_t reg_apifr_apsrc_rmb;
+	uint8_t reg_apifr_ddren_rmb;
+	uint8_t reg_apifr_emi_rmb;
+	uint8_t reg_apifr_infra_rmb;
+	uint8_t reg_apifr_pmic_rmb;
+	uint8_t reg_apifr_srcclkena_mb;
+	uint8_t reg_apifr_vcore_rmb;
+	uint8_t reg_apifr_vrf18_rmb;
+	uint8_t reg_apu_apsrc_rmb;
+	uint8_t reg_apu_ddren_rmb;
+	uint8_t reg_apu_emi_rmb;
+	uint8_t reg_apu_infra_rmb;
+	uint8_t reg_apu_pmic_rmb;
+	uint8_t reg_apu_srcclkena_mb;
+	uint8_t reg_apu_vcore_rmb;
+	uint8_t reg_apu_vrf18_rmb;
+	uint8_t reg_audio_apsrc_rmb;
+	uint8_t reg_audio_ddren_rmb;
+	uint8_t reg_audio_emi_rmb;
+	uint8_t reg_audio_infra_rmb;
+	uint8_t reg_audio_pmic_rmb;
+	uint8_t reg_audio_srcclkena_mb;
+	uint8_t reg_audio_vcore_rmb;
+	uint8_t reg_audio_vrf18_rmb;
+
+	/* SPM_SRC_MASK_1 */
+	uint8_t reg_audio_dsp_apsrc_rmb;
+	uint8_t reg_audio_dsp_ddren_rmb;
+	uint8_t reg_audio_dsp_emi_rmb;
+	uint8_t reg_audio_dsp_infra_rmb;
+	uint8_t reg_audio_dsp_pmic_rmb;
+	uint8_t reg_audio_dsp_srcclkena_mb;
+	uint8_t reg_audio_dsp_vcore_rmb;
+	uint8_t reg_audio_dsp_vrf18_rmb;
+	uint8_t reg_cam_apsrc_rmb;
+	uint8_t reg_cam_ddren_rmb;
+	uint8_t reg_cam_emi_rmb;
+	uint8_t reg_cam_infra_rmb;
+	uint8_t reg_cam_pmic_rmb;
+	uint8_t reg_cam_srcclkena_mb;
+	uint8_t reg_cam_vrf18_rmb;
+	uint32_t reg_ccif_apsrc_rmb;
+
+	/* SPM_SRC_MASK_2 */
+	uint32_t reg_ccif_emi_rmb;
+	uint32_t reg_ccif_infra_rmb;
+
+	/* SPM_SRC_MASK_3 */
+	uint32_t reg_ccif_pmic_rmb;
+	uint32_t reg_ccif_srcclkena_mb;
+
+	/* SPM_SRC_MASK_4 */
+	uint32_t reg_ccif_vcore_rmb;
+	uint32_t reg_ccif_vrf18_rmb;
+	uint8_t reg_ccu_apsrc_rmb;
+	uint8_t reg_ccu_ddren_rmb;
+	uint8_t reg_ccu_emi_rmb;
+	uint8_t reg_ccu_infra_rmb;
+	uint8_t reg_ccu_pmic_rmb;
+	uint8_t reg_ccu_srcclkena_mb;
+	uint8_t reg_ccu_vrf18_rmb;
+	uint8_t reg_cg_check_apsrc_rmb;
+
+	/* SPM_SRC_MASK_5 */
+	uint8_t reg_cg_check_ddren_rmb;
+	uint8_t reg_cg_check_emi_rmb;
+	uint8_t reg_cg_check_infra_rmb;
+	uint8_t reg_cg_check_pmic_rmb;
+	uint8_t reg_cg_check_srcclkena_mb;
+	uint8_t reg_cg_check_vcore_rmb;
+	uint8_t reg_cg_check_vrf18_rmb;
+	uint8_t reg_cksys_apsrc_rmb;
+	uint8_t reg_cksys_ddren_rmb;
+	uint8_t reg_cksys_emi_rmb;
+	uint8_t reg_cksys_infra_rmb;
+	uint8_t reg_cksys_pmic_rmb;
+	uint8_t reg_cksys_srcclkena_mb;
+	uint8_t reg_cksys_vcore_rmb;
+	uint8_t reg_cksys_vrf18_rmb;
+	uint8_t reg_cksys_1_apsrc_rmb;
+	uint8_t reg_cksys_1_ddren_rmb;
+	uint8_t reg_cksys_1_emi_rmb;
+	uint8_t reg_cksys_1_infra_rmb;
+	uint8_t reg_cksys_1_pmic_rmb;
+	uint8_t reg_cksys_1_srcclkena_mb;
+	uint8_t reg_cksys_1_vcore_rmb;
+	uint8_t reg_cksys_1_vrf18_rmb;
+
+	/* SPM_SRC_MASK_6 */
+	uint8_t reg_cksys_2_apsrc_rmb;
+	uint8_t reg_cksys_2_ddren_rmb;
+	uint8_t reg_cksys_2_emi_rmb;
+	uint8_t reg_cksys_2_infra_rmb;
+	uint8_t reg_cksys_2_pmic_rmb;
+	uint8_t reg_cksys_2_srcclkena_mb;
+	uint8_t reg_cksys_2_vcore_rmb;
+	uint8_t reg_cksys_2_vrf18_rmb;
+	uint8_t reg_conn_apsrc_rmb;
+	uint8_t reg_conn_ddren_rmb;
+	uint8_t reg_conn_emi_rmb;
+	uint8_t reg_conn_infra_rmb;
+	uint8_t reg_conn_pmic_rmb;
+	uint8_t reg_conn_srcclkena_mb;
+	uint8_t reg_conn_srcclkenb_mb;
+	uint8_t reg_conn_vcore_rmb;
+	uint8_t reg_conn_vrf18_rmb;
+	uint8_t reg_corecfg_apsrc_rmb;
+	uint8_t reg_corecfg_ddren_rmb;
+	uint8_t reg_corecfg_emi_rmb;
+	uint8_t reg_corecfg_infra_rmb;
+	uint8_t reg_corecfg_pmic_rmb;
+	uint8_t reg_corecfg_srcclkena_mb;
+	uint8_t reg_corecfg_vcore_rmb;
+	uint8_t reg_corecfg_vrf18_rmb;
+
+	/* SPM_SRC_MASK_7 */
+	uint8_t reg_cpueb_apsrc_rmb;
+	uint8_t reg_cpueb_ddren_rmb;
+	uint8_t reg_cpueb_emi_rmb;
+	uint8_t reg_cpueb_infra_rmb;
+	uint8_t reg_cpueb_pmic_rmb;
+	uint8_t reg_cpueb_srcclkena_mb;
+	uint8_t reg_cpueb_vcore_rmb;
+	uint8_t reg_cpueb_vrf18_rmb;
+	uint8_t reg_disp0_apsrc_rmb;
+	uint8_t reg_disp0_ddren_rmb;
+	uint8_t reg_disp0_emi_rmb;
+	uint8_t reg_disp0_infra_rmb;
+	uint8_t reg_disp0_pmic_rmb;
+	uint8_t reg_disp0_srcclkena_mb;
+	uint8_t reg_disp0_vrf18_rmb;
+	uint8_t reg_disp1_apsrc_rmb;
+	uint8_t reg_disp1_ddren_rmb;
+	uint8_t reg_disp1_emi_rmb;
+	uint8_t reg_disp1_infra_rmb;
+	uint8_t reg_disp1_pmic_rmb;
+	uint8_t reg_disp1_srcclkena_mb;
+	uint8_t reg_disp1_vrf18_rmb;
+	uint8_t reg_dpm_apsrc_rmb;
+	uint8_t reg_dpm_ddren_rmb;
+
+	/* SPM_SRC_MASK_8 */
+	uint8_t reg_dpm_emi_rmb;
+	uint8_t reg_dpm_infra_rmb;
+	uint8_t reg_dpm_pmic_rmb;
+	uint8_t reg_dpm_srcclkena_mb;
+	uint8_t reg_dpm_vcore_rmb;
+	uint8_t reg_dpm_vrf18_rmb;
+	uint8_t reg_dpmaif_apsrc_rmb;
+	uint8_t reg_dpmaif_ddren_rmb;
+	uint8_t reg_dpmaif_emi_rmb;
+	uint8_t reg_dpmaif_infra_rmb;
+	uint8_t reg_dpmaif_pmic_rmb;
+	uint8_t reg_dpmaif_srcclkena_mb;
+	uint8_t reg_dpmaif_vcore_rmb;
+	uint8_t reg_dpmaif_vrf18_rmb;
+
+	/* SPM_SRC_MASK_9 */
+	uint8_t reg_dvfsrc_level_rmb;
+	uint8_t reg_emisys_apsrc_rmb;
+	uint8_t reg_emisys_ddren_rmb;
+	uint8_t reg_emisys_emi_rmb;
+	uint8_t reg_emisys_infra_rmb;
+	uint8_t reg_emisys_pmic_rmb;
+	uint8_t reg_emisys_srcclkena_mb;
+	uint8_t reg_emisys_vcore_rmb;
+	uint8_t reg_emisys_vrf18_rmb;
+	uint8_t reg_gce_apsrc_rmb;
+	uint8_t reg_gce_ddren_rmb;
+	uint8_t reg_gce_emi_rmb;
+	uint8_t reg_gce_infra_rmb;
+	uint8_t reg_gce_pmic_rmb;
+	uint8_t reg_gce_srcclkena_mb;
+	uint8_t reg_gce_vcore_rmb;
+	uint8_t reg_gce_vrf18_rmb;
+	uint8_t reg_gpueb_apsrc_rmb;
+	uint8_t reg_gpueb_ddren_rmb;
+	uint8_t reg_gpueb_emi_rmb;
+	uint8_t reg_gpueb_infra_rmb;
+	uint8_t reg_gpueb_pmic_rmb;
+	uint8_t reg_gpueb_srcclkena_mb;
+	uint8_t reg_gpueb_vcore_rmb;
+	uint8_t reg_gpueb_vrf18_rmb;
+	uint8_t reg_hwccf_apsrc_rmb;
+	uint8_t reg_hwccf_ddren_rmb;
+	uint8_t reg_hwccf_emi_rmb;
+	uint8_t reg_hwccf_infra_rmb;
+	uint8_t reg_hwccf_pmic_rmb;
+	uint8_t reg_hwccf_srcclkena_mb;
+	uint8_t reg_hwccf_vcore_rmb;
+
+	/* SPM_SRC_MASK_10 */
+	uint8_t reg_hwccf_vrf18_rmb;
+	uint8_t reg_img_apsrc_rmb;
+	uint8_t reg_img_ddren_rmb;
+	uint8_t reg_img_emi_rmb;
+	uint8_t reg_img_infra_rmb;
+	uint8_t reg_img_pmic_rmb;
+	uint8_t reg_img_srcclkena_mb;
+	uint8_t reg_img_vrf18_rmb;
+	uint8_t reg_infrasys_apsrc_rmb;
+	uint8_t reg_infrasys_ddren_rmb;
+	uint8_t reg_infrasys_emi_rmb;
+	uint8_t reg_infrasys_infra_rmb;
+	uint8_t reg_infrasys_pmic_rmb;
+	uint8_t reg_infrasys_srcclkena_mb;
+	uint8_t reg_infrasys_vcore_rmb;
+	uint8_t reg_infrasys_vrf18_rmb;
+	uint8_t reg_ipic_infra_rmb;
+	uint8_t reg_ipic_vrf18_rmb;
+	uint8_t reg_mcu_apsrc_rmb;
+	uint8_t reg_mcu_ddren_rmb;
+	uint8_t reg_mcu_emi_rmb;
+	uint8_t reg_mcu_infra_rmb;
+	uint8_t reg_mcu_pmic_rmb;
+	uint8_t reg_mcu_srcclkena_mb;
+	uint8_t reg_mcu_vcore_rmb;
+	uint8_t reg_mcu_vrf18_rmb;
+	uint8_t reg_md_apsrc_rmb;
+	uint8_t reg_md_ddren_rmb;
+	uint8_t reg_md_emi_rmb;
+	uint8_t reg_md_infra_rmb;
+	uint8_t reg_md_pmic_rmb;
+	uint8_t reg_md_srcclkena_mb;
+
+	/* SPM_SRC_MASK_11 */
+	uint8_t reg_md_srcclkena1_mb;
+	uint8_t reg_md_vcore_rmb;
+	uint8_t reg_md_vrf18_rmb;
+	uint8_t reg_mm_proc_apsrc_rmb;
+	uint8_t reg_mm_proc_ddren_rmb;
+	uint8_t reg_mm_proc_emi_rmb;
+	uint8_t reg_mm_proc_infra_rmb;
+	uint8_t reg_mm_proc_pmic_rmb;
+	uint8_t reg_mm_proc_srcclkena_mb;
+	uint8_t reg_mm_proc_vcore_rmb;
+	uint8_t reg_mm_proc_vrf18_rmb;
+	uint8_t reg_mml0_apsrc_rmb;
+	uint8_t reg_mml0_ddren_rmb;
+	uint8_t reg_mml0_emi_rmb;
+	uint8_t reg_mml0_infra_rmb;
+	uint8_t reg_mml0_pmic_rmb;
+	uint8_t reg_mml0_srcclkena_mb;
+	uint8_t reg_mml0_vrf18_rmb;
+	uint8_t reg_mml1_apsrc_rmb;
+	uint8_t reg_mml1_ddren_rmb;
+	uint8_t reg_mml1_emi_rmb;
+	uint8_t reg_mml1_infra_rmb;
+	uint8_t reg_mml1_pmic_rmb;
+	uint8_t reg_mml1_srcclkena_mb;
+	uint8_t reg_mml1_vrf18_rmb;
+	uint8_t reg_ovl0_apsrc_rmb;
+	uint8_t reg_ovl0_ddren_rmb;
+	uint8_t reg_ovl0_emi_rmb;
+	uint8_t reg_ovl0_infra_rmb;
+	uint8_t reg_ovl0_pmic_rmb;
+	uint8_t reg_ovl0_srcclkena_mb;
+	uint8_t reg_ovl0_vrf18_rmb;
+
+	/* SPM_SRC_MASK_12 */
+	uint8_t reg_ovl1_apsrc_rmb;
+	uint8_t reg_ovl1_ddren_rmb;
+	uint8_t reg_ovl1_emi_rmb;
+	uint8_t reg_ovl1_infra_rmb;
+	uint8_t reg_ovl1_pmic_rmb;
+	uint8_t reg_ovl1_srcclkena_mb;
+	uint8_t reg_ovl1_vrf18_rmb;
+	uint8_t reg_pcie0_apsrc_rmb;
+	uint8_t reg_pcie0_ddren_rmb;
+	uint8_t reg_pcie0_emi_rmb;
+	uint8_t reg_pcie0_infra_rmb;
+	uint8_t reg_pcie0_pmic_rmb;
+	uint8_t reg_pcie0_srcclkena_mb;
+	uint8_t reg_pcie0_vcore_rmb;
+	uint8_t reg_pcie0_vrf18_rmb;
+	uint8_t reg_pcie1_apsrc_rmb;
+	uint8_t reg_pcie1_ddren_rmb;
+	uint8_t reg_pcie1_emi_rmb;
+	uint8_t reg_pcie1_infra_rmb;
+	uint8_t reg_pcie1_pmic_rmb;
+	uint8_t reg_pcie1_srcclkena_mb;
+	uint8_t reg_pcie1_vcore_rmb;
+	uint8_t reg_pcie1_vrf18_rmb;
+	uint8_t reg_perisys_apsrc_rmb;
+	uint8_t reg_perisys_ddren_rmb;
+	uint8_t reg_perisys_emi_rmb;
+	uint8_t reg_perisys_infra_rmb;
+	uint8_t reg_perisys_pmic_rmb;
+	uint8_t reg_perisys_srcclkena_mb;
+	uint8_t reg_perisys_vcore_rmb;
+	uint8_t reg_perisys_vrf18_rmb;
+	uint8_t reg_pmsr_apsrc_rmb;
+
+	/* SPM_SRC_MASK_13 */
+	uint8_t reg_pmsr_ddren_rmb;
+	uint8_t reg_pmsr_emi_rmb;
+	uint8_t reg_pmsr_infra_rmb;
+	uint8_t reg_pmsr_pmic_rmb;
+	uint8_t reg_pmsr_srcclkena_mb;
+	uint8_t reg_pmsr_vcore_rmb;
+	uint8_t reg_pmsr_vrf18_rmb;
+	uint8_t reg_scp_apsrc_rmb;
+	uint8_t reg_scp_ddren_rmb;
+	uint8_t reg_scp_emi_rmb;
+	uint8_t reg_scp_infra_rmb;
+	uint8_t reg_scp_pmic_rmb;
+	uint8_t reg_scp_srcclkena_mb;
+	uint8_t reg_scp_vcore_rmb;
+	uint8_t reg_scp_vrf18_rmb;
+	uint8_t reg_spu_hwr_apsrc_rmb;
+	uint8_t reg_spu_hwr_ddren_rmb;
+	uint8_t reg_spu_hwr_emi_rmb;
+	uint8_t reg_spu_hwr_infra_rmb;
+	uint8_t reg_spu_hwr_pmic_rmb;
+	uint8_t reg_spu_hwr_srcclkena_mb;
+	uint8_t reg_spu_hwr_vcore_rmb;
+	uint8_t reg_spu_hwr_vrf18_rmb;
+	uint8_t reg_spu_ise_apsrc_rmb;
+	uint8_t reg_spu_ise_ddren_rmb;
+	uint8_t reg_spu_ise_emi_rmb;
+	uint8_t reg_spu_ise_infra_rmb;
+	uint8_t reg_spu_ise_pmic_rmb;
+	uint8_t reg_spu_ise_srcclkena_mb;
+	uint8_t reg_spu_ise_vcore_rmb;
+	uint8_t reg_spu_ise_vrf18_rmb;
+
+	/* SPM_SRC_MASK_14 */
+	uint8_t reg_srcclkeni_infra_rmb;
+	uint8_t reg_srcclkeni_pmic_rmb;
+	uint8_t reg_srcclkeni_srcclkena_mb;
+	uint8_t reg_srcclkeni_vcore_rmb;
+	uint8_t reg_sspm_apsrc_rmb;
+	uint8_t reg_sspm_ddren_rmb;
+	uint8_t reg_sspm_emi_rmb;
+	uint8_t reg_sspm_infra_rmb;
+	uint8_t reg_sspm_pmic_rmb;
+	uint8_t reg_sspm_srcclkena_mb;
+	uint8_t reg_sspm_vrf18_rmb;
+	uint8_t reg_ssrsys_apsrc_rmb;
+	uint8_t reg_ssrsys_ddren_rmb;
+	uint8_t reg_ssrsys_emi_rmb;
+	uint8_t reg_ssrsys_infra_rmb;
+	uint8_t reg_ssrsys_pmic_rmb;
+	uint8_t reg_ssrsys_srcclkena_mb;
+	uint8_t reg_ssrsys_vcore_rmb;
+	uint8_t reg_ssrsys_vrf18_rmb;
+	uint8_t reg_ssusb_apsrc_rmb;
+	uint8_t reg_ssusb_ddren_rmb;
+	uint8_t reg_ssusb_emi_rmb;
+	uint8_t reg_ssusb_infra_rmb;
+	uint8_t reg_ssusb_pmic_rmb;
+	uint8_t reg_ssusb_srcclkena_mb;
+	uint8_t reg_ssusb_vcore_rmb;
+	uint8_t reg_ssusb_vrf18_rmb;
+	uint8_t reg_uart_hub_infra_rmb;
+
+	/* SPM_SRC_MASK_15 */
+	uint8_t reg_uart_hub_pmic_rmb;
+	uint8_t reg_uart_hub_srcclkena_mb;
+	uint8_t reg_uart_hub_vcore_rmb;
+	uint8_t reg_uart_hub_vrf18_rmb;
+	uint8_t reg_ufs_apsrc_rmb;
+	uint8_t reg_ufs_ddren_rmb;
+	uint8_t reg_ufs_emi_rmb;
+	uint8_t reg_ufs_infra_rmb;
+	uint8_t reg_ufs_pmic_rmb;
+	uint8_t reg_ufs_srcclkena_mb;
+	uint8_t reg_ufs_vcore_rmb;
+	uint8_t reg_ufs_vrf18_rmb;
+	uint8_t reg_vdec_apsrc_rmb;
+	uint8_t reg_vdec_ddren_rmb;
+	uint8_t reg_vdec_emi_rmb;
+	uint8_t reg_vdec_infra_rmb;
+	uint8_t reg_vdec_pmic_rmb;
+	uint8_t reg_vdec_srcclkena_mb;
+	uint8_t reg_vdec_vrf18_rmb;
+	uint8_t reg_venc_apsrc_rmb;
+	uint8_t reg_venc_ddren_rmb;
+	uint8_t reg_venc_emi_rmb;
+	uint8_t reg_venc_infra_rmb;
+	uint8_t reg_venc_pmic_rmb;
+	uint8_t reg_venc_srcclkena_mb;
+	uint8_t reg_venc_vrf18_rmb;
+	uint8_t reg_vlpcfg_apsrc_rmb;
+	uint8_t reg_vlpcfg_ddren_rmb;
+	uint8_t reg_vlpcfg_emi_rmb;
+	uint8_t reg_vlpcfg_infra_rmb;
+	uint8_t reg_vlpcfg_pmic_rmb;
+	uint8_t reg_vlpcfg_srcclkena_mb;
+
+	/* SPM_SRC_MASK_16 */
+	uint8_t reg_vlpcfg_vcore_rmb;
+	uint8_t reg_vlpcfg_vrf18_rmb;
+	uint8_t reg_vlpcfg1_apsrc_rmb;
+	uint8_t reg_vlpcfg1_ddren_rmb;
+	uint8_t reg_vlpcfg1_emi_rmb;
+	uint8_t reg_vlpcfg1_infra_rmb;
+	uint8_t reg_vlpcfg1_pmic_rmb;
+	uint8_t reg_vlpcfg1_srcclkena_mb;
+	uint8_t reg_vlpcfg1_vcore_rmb;
+	uint8_t reg_vlpcfg1_vrf18_rmb;
+
+	/* SPM_EVENT_CON_MISC */
+	uint8_t reg_srcclken_fast_resp;
+	uint8_t reg_csyspwrup_ack_mask;
+
+	/* SPM_SRC_MASK_17 */
+	uint32_t reg_spm_sw_vcore_rmb;
+	uint32_t reg_spm_sw_pmic_rmb;
+
+	/* SPM_SRC_MASK_18 */
+	uint32_t reg_spm_sw_srcclkena_mb;
+
+	/* SPM_WAKE_MASK*/
+	uint32_t reg_wake_mask;
+
+	/* SPM_WAKEUP_EVENT_EXT_MASK */
+	uint32_t reg_ext_wake_mask;
+};
+
+enum pwr_ctrl_enum {
+	PW_PCM_FLAGS,
+	PW_PCM_FLAGS_CUST,
+	PW_PCM_FLAGS_CUST_SET,
+	PW_PCM_FLAGS_CUST_CLR,
+	PW_PCM_FLAGS1,
+	PW_PCM_FLAGS1_CUST,
+	PW_PCM_FLAGS1_CUST_SET,
+	PW_PCM_FLAGS1_CUST_CLR,
+	PW_TIMER_VAL,
+	PW_TIMER_VAL_CUST,
+	PW_TIMER_VAL_RAMP_EN,
+	PW_TIMER_VAL_RAMP_EN_SEC,
+	PW_WAKE_SRC,
+	PW_WAKE_SRC_CUST,
+	PW_WAKELOCK_TIMER_VAL,
+	PW_WDT_DISABLE,
+
+	/* SPM_SRC_REQ */
+	PW_REG_SPM_ADSP_MAILBOX_REQ,
+	PW_REG_SPM_APSRC_REQ,
+	PW_REG_SPM_DDREN_REQ,
+	PW_REG_SPM_DVFS_REQ,
+	PW_REG_SPM_EMI_REQ,
+	PW_REG_SPM_F26M_REQ,
+	PW_REG_SPM_INFRA_REQ,
+	PW_REG_SPM_PMIC_REQ,
+	PW_REG_SPM_SCP_MAILBOX_REQ,
+	PW_REG_SPM_SSPM_MAILBOX_REQ,
+	PW_REG_SPM_SW_MAILBOX_REQ,
+	PW_REG_SPM_VCORE_REQ,
+	PW_REG_SPM_VRF18_REQ,
+
+	/* SPM_SRC_MASK_0 */
+	PW_REG_APIFR_APSRC_RMB,
+	PW_REG_APIFR_DDREN_RMB,
+	PW_REG_APIFR_EMI_RMB,
+	PW_REG_APIFR_INFRA_RMB,
+	PW_REG_APIFR_PMIC_RMB,
+	PW_REG_APIFR_SRCCLKENA_MB,
+	PW_REG_APIFR_VCORE_RMB,
+	PW_REG_APIFR_VRF18_RMB,
+	PW_REG_APU_APSRC_RMB,
+	PW_REG_APU_DDREN_RMB,
+	PW_REG_APU_EMI_RMB,
+	PW_REG_APU_INFRA_RMB,
+	PW_REG_APU_PMIC_RMB,
+	PW_REG_APU_SRCCLKENA_MB,
+	PW_REG_APU_VCORE_RMB,
+	PW_REG_APU_VRF18_RMB,
+	PW_REG_AUDIO_APSRC_RMB,
+	PW_REG_AUDIO_DDREN_RMB,
+	PW_REG_AUDIO_EMI_RMB,
+	PW_REG_AUDIO_INFRA_RMB,
+	PW_REG_AUDIO_PMIC_RMB,
+	PW_REG_AUDIO_SRCCLKENA_MB,
+	PW_REG_AUDIO_VCORE_RMB,
+	PW_REG_AUDIO_VRF18_RMB,
+
+	/* SPM_SRC_MASK_1 */
+	PW_REG_AUDIO_DSP_APSRC_RMB,
+	PW_REG_AUDIO_DSP_DDREN_RMB,
+	PW_REG_AUDIO_DSP_EMI_RMB,
+	PW_REG_AUDIO_DSP_INFRA_RMB,
+	PW_REG_AUDIO_DSP_PMIC_RMB,
+	PW_REG_AUDIO_DSP_SRCCLKENA_MB,
+	PW_REG_AUDIO_DSP_VCORE_RMB,
+	PW_REG_AUDIO_DSP_VRF18_RMB,
+	PW_REG_CAM_APSRC_RMB,
+	PW_REG_CAM_DDREN_RMB,
+	PW_REG_CAM_EMI_RMB,
+	PW_REG_CAM_INFRA_RMB,
+	PW_REG_CAM_PMIC_RMB,
+	PW_REG_CAM_SRCCLKENA_MB,
+	PW_REG_CAM_VRF18_RMB,
+	PW_REG_CCIF_APSRC_RMB,
+
+	/* SPM_SRC_MASK_2 */
+	PW_REG_CCIF_EMI_RMB,
+	PW_REG_CCIF_INFRA_RMB,
+
+	/* SPM_SRC_MASK_3 */
+	PW_REG_CCIF_PMIC_RMB,
+	PW_REG_CCIF_SRCCLKENA_MB,
+
+	/* SPM_SRC_MASK_4 */
+	PW_REG_CCIF_VCORE_RMB,
+	PW_REG_CCIF_VRF18_RMB,
+	PW_REG_CCU_APSRC_RMB,
+	PW_REG_CCU_DDREN_RMB,
+	PW_REG_CCU_EMI_RMB,
+	PW_REG_CCU_INFRA_RMB,
+	PW_REG_CCU_PMIC_RMB,
+	PW_REG_CCU_SRCCLKENA_MB,
+	PW_REG_CCU_VRF18_RMB,
+	PW_REG_CG_CHECK_APSRC_RMB,
+
+	/* SPM_SRC_MASK_5 */
+	PW_REG_CG_CHECK_DDREN_RMB,
+	PW_REG_CG_CHECK_EMI_RMB,
+	PW_REG_CG_CHECK_INFRA_RMB,
+	PW_REG_CG_CHECK_PMIC_RMB,
+	PW_REG_CG_CHECK_SRCCLKENA_MB,
+	PW_REG_CG_CHECK_VCORE_RMB,
+	PW_REG_CG_CHECK_VRF18_RMB,
+	PW_REG_CKSYS_APSRC_RMB,
+	PW_REG_CKSYS_DDREN_RMB,
+	PW_REG_CKSYS_EMI_RMB,
+	PW_REG_CKSYS_INFRA_RMB,
+	PW_REG_CKSYS_PMIC_RMB,
+	PW_REG_CKSYS_SRCCLKENA_MB,
+	PW_REG_CKSYS_VCORE_RMB,
+	PW_REG_CKSYS_VRF18_RMB,
+	PW_REG_CKSYS_1_APSRC_RMB,
+	PW_REG_CKSYS_1_DDREN_RMB,
+	PW_REG_CKSYS_1_EMI_RMB,
+	PW_REG_CKSYS_1_INFRA_RMB,
+	PW_REG_CKSYS_1_PMIC_RMB,
+	PW_REG_CKSYS_1_SRCCLKENA_MB,
+	PW_REG_CKSYS_1_VCORE_RMB,
+	PW_REG_CKSYS_1_VRF18_RMB,
+
+	/* SPM_SRC_MASK_6 */
+	PW_REG_CKSYS_2_APSRC_RMB,
+	PW_REG_CKSYS_2_DDREN_RMB,
+	PW_REG_CKSYS_2_EMI_RMB,
+	PW_REG_CKSYS_2_INFRA_RMB,
+	PW_REG_CKSYS_2_PMIC_RMB,
+	PW_REG_CKSYS_2_SRCCLKENA_MB,
+	PW_REG_CKSYS_2_VCORE_RMB,
+	PW_REG_CKSYS_2_VRF18_RMB,
+	PW_REG_CONN_APSRC_RMB,
+	PW_REG_CONN_DDREN_RMB,
+	PW_REG_CONN_EMI_RMB,
+	PW_REG_CONN_INFRA_RMB,
+	PW_REG_CONN_PMIC_RMB,
+	PW_REG_CONN_SRCCLKENA_MB,
+	PW_REG_CONN_SRCCLKENB_MB,
+	PW_REG_CONN_VCORE_RMB,
+	PW_REG_CONN_VRF18_RMB,
+	PW_REG_CORECFG_APSRC_RMB,
+	PW_REG_CORECFG_DDREN_RMB,
+	PW_REG_CORECFG_EMI_RMB,
+	PW_REG_CORECFG_INFRA_RMB,
+	PW_REG_CORECFG_PMIC_RMB,
+	PW_REG_CORECFG_SRCCLKENA_MB,
+	PW_REG_CORECFG_VCORE_RMB,
+	PW_REG_CORECFG_VRF18_RMB,
+
+	/* SPM_SRC_MASK_7 */
+	PW_REG_CPUEB_APSRC_RMB,
+	PW_REG_CPUEB_DDREN_RMB,
+	PW_REG_CPUEB_EMI_RMB,
+	PW_REG_CPUEB_INFRA_RMB,
+	PW_REG_CPUEB_PMIC_RMB,
+	PW_REG_CPUEB_SRCCLKENA_MB,
+	PW_REG_CPUEB_VCORE_RMB,
+	PW_REG_CPUEB_VRF18_RMB,
+	PW_REG_DISP0_APSRC_RMB,
+	PW_REG_DISP0_DDREN_RMB,
+	PW_REG_DISP0_EMI_RMB,
+	PW_REG_DISP0_INFRA_RMB,
+	PW_REG_DISP0_PMIC_RMB,
+	PW_REG_DISP0_SRCCLKENA_MB,
+	PW_REG_DISP0_VRF18_RMB,
+	PW_REG_DISP1_APSRC_RMB,
+	PW_REG_DISP1_DDREN_RMB,
+	PW_REG_DISP1_EMI_RMB,
+	PW_REG_DISP1_INFRA_RMB,
+	PW_REG_DISP1_PMIC_RMB,
+	PW_REG_DISP1_SRCCLKENA_MB,
+	PW_REG_DISP1_VRF18_RMB,
+	PW_REG_DPM_APSRC_RMB,
+	PW_REG_DPM_DDREN_RMB,
+
+	/* SPM_SRC_MASK_8 */
+	PW_REG_DPM_EMI_RMB,
+	PW_REG_DPM_INFRA_RMB,
+	PW_REG_DPM_PMIC_RMB,
+	PW_REG_DPM_SRCCLKENA_MB,
+	PW_REG_DPM_VCORE_RMB,
+	PW_REG_DPM_VRF18_RMB,
+	PW_REG_DPMAIF_APSRC_RMB,
+	PW_REG_DPMAIF_DDREN_RMB,
+	PW_REG_DPMAIF_EMI_RMB,
+	PW_REG_DPMAIF_INFRA_RMB,
+	PW_REG_DPMAIF_PMIC_RMB,
+	PW_REG_DPMAIF_SRCCLKENA_MB,
+	PW_REG_DPMAIF_VCORE_RMB,
+	PW_REG_DPMAIF_VRF18_RMB,
+
+	/* SPM_SRC_MASK_9 */
+	PW_REG_DVFSRC_LEVEL_RMB,
+	PW_REG_EMISYS_APSRC_RMB,
+	PW_REG_EMISYS_DDREN_RMB,
+	PW_REG_EMISYS_EMI_RMB,
+	PW_REG_EMISYS_INFRA_RMB,
+	PW_REG_EMISYS_PMIC_RMB,
+	PW_REG_EMISYS_SRCCLKENA_MB,
+	PW_REG_EMISYS_VCORE_RMB,
+	PW_REG_EMISYS_VRF18_RMB,
+	PW_REG_GCE_APSRC_RMB,
+	PW_REG_GCE_DDREN_RMB,
+	PW_REG_GCE_EMI_RMB,
+	PW_REG_GCE_INFRA_RMB,
+	PW_REG_GCE_PMIC_RMB,
+	PW_REG_GCE_SRCCLKENA_MB,
+	PW_REG_GCE_VCORE_RMB,
+	PW_REG_GCE_VRF18_RMB,
+	PW_REG_GPUEB_APSRC_RMB,
+	PW_REG_GPUEB_DDREN_RMB,
+	PW_REG_GPUEB_EMI_RMB,
+	PW_REG_GPUEB_INFRA_RMB,
+	PW_REG_GPUEB_PMIC_RMB,
+	PW_REG_GPUEB_SRCCLKENA_MB,
+	PW_REG_GPUEB_VCORE_RMB,
+	PW_REG_GPUEB_VRF18_RMB,
+	PW_REG_HWCCF_APSRC_RMB,
+	PW_REG_HWCCF_DDREN_RMB,
+	PW_REG_HWCCF_EMI_RMB,
+	PW_REG_HWCCF_INFRA_RMB,
+	PW_REG_HWCCF_PMIC_RMB,
+	PW_REG_HWCCF_SRCCLKENA_MB,
+	PW_REG_HWCCF_VCORE_RMB,
+
+	/* SPM_SRC_MASK_10 */
+	PW_REG_HWCCF_VRF18_RMB,
+	PW_REG_IMG_APSRC_RMB,
+	PW_REG_IMG_DDREN_RMB,
+	PW_REG_IMG_EMI_RMB,
+	PW_REG_IMG_INFRA_RMB,
+	PW_REG_IMG_PMIC_RMB,
+	PW_REG_IMG_SRCCLKENA_MB,
+	PW_REG_IMG_VRF18_RMB,
+	PW_REG_INFRASYS_APSRC_RMB,
+	PW_REG_INFRASYS_DDREN_RMB,
+	PW_REG_INFRASYS_EMI_RMB,
+	PW_REG_INFRASYS_INFRA_RMB,
+	PW_REG_INFRASYS_PMIC_RMB,
+	PW_REG_INFRASYS_SRCCLKENA_MB,
+	PW_REG_INFRASYS_VCORE_RMB,
+	PW_REG_INFRASYS_VRF18_RMB,
+	PW_REG_IPIC_INFRA_RMB,
+	PW_REG_IPIC_VRF18_RMB,
+	PW_REG_MCU_APSRC_RMB,
+	PW_REG_MCU_DDREN_RMB,
+	PW_REG_MCU_EMI_RMB,
+	PW_REG_MCU_INFRA_RMB,
+	PW_REG_MCU_PMIC_RMB,
+	PW_REG_MCU_SRCCLKENA_MB,
+	PW_REG_MCU_VCORE_RMB,
+	PW_REG_MCU_VRF18_RMB,
+	PW_REG_MD_APSRC_RMB,
+	PW_REG_MD_DDREN_RMB,
+	PW_REG_MD_EMI_RMB,
+	PW_REG_MD_INFRA_RMB,
+	PW_REG_MD_PMIC_RMB,
+	PW_REG_MD_SRCCLKENA_MB,
+
+	/* SPM_SRC_MASK_11 */
+	PW_REG_MD_SRCCLKENA1_MB,
+	PW_REG_MD_VCORE_RMB,
+	PW_REG_MD_VRF18_RMB,
+	PW_REG_MM_PROC_APSRC_RMB,
+	PW_REG_MM_PROC_DDREN_RMB,
+	PW_REG_MM_PROC_EMI_RMB,
+	PW_REG_MM_PROC_INFRA_RMB,
+	PW_REG_MM_PROC_PMIC_RMB,
+	PW_REG_MM_PROC_SRCCLKENA_MB,
+	PW_REG_MM_PROC_VCORE_RMB,
+	PW_REG_MM_PROC_VRF18_RMB,
+	PW_REG_MML0_APSRC_RMB,
+	PW_REG_MML0_DDREN_RMB,
+	PW_REG_MML0_EMI_RMB,
+	PW_REG_MML0_INFRA_RMB,
+	PW_REG_MML0_PMIC_RMB,
+	PW_REG_MML0_SRCCLKENA_MB,
+	PW_REG_MML0_VRF18_RMB,
+	PW_REG_MML1_APSRC_RMB,
+	PW_REG_MML1_DDREN_RMB,
+	PW_REG_MML1_EMI_RMB,
+	PW_REG_MML1_INFRA_RMB,
+	PW_REG_MML1_PMIC_RMB,
+	PW_REG_MML1_SRCCLKENA_MB,
+	PW_REG_MML1_VRF18_RMB,
+	PW_REG_OVL0_APSRC_RMB,
+	PW_REG_OVL0_DDREN_RMB,
+	PW_REG_OVL0_EMI_RMB,
+	PW_REG_OVL0_INFRA_RMB,
+	PW_REG_OVL0_PMIC_RMB,
+	PW_REG_OVL0_SRCCLKENA_MB,
+	PW_REG_OVL0_VRF18_RMB,
+
+	/* SPM_SRC_MASK_12 */
+	PW_REG_OVL1_APSRC_RMB,
+	PW_REG_OVL1_DDREN_RMB,
+	PW_REG_OVL1_EMI_RMB,
+	PW_REG_OVL1_INFRA_RMB,
+	PW_REG_OVL1_PMIC_RMB,
+	PW_REG_OVL1_SRCCLKENA_MB,
+	PW_REG_OVL1_VRF18_RMB,
+	PW_REG_PCIE0_APSRC_RMB,
+	PW_REG_PCIE0_DDREN_RMB,
+	PW_REG_PCIE0_EMI_RMB,
+	PW_REG_PCIE0_INFRA_RMB,
+	PW_REG_PCIE0_PMIC_RMB,
+	PW_REG_PCIE0_SRCCLKENA_MB,
+	PW_REG_PCIE0_VCORE_RMB,
+	PW_REG_PCIE0_VRF18_RMB,
+	PW_REG_PCIE1_APSRC_RMB,
+	PW_REG_PCIE1_DDREN_RMB,
+	PW_REG_PCIE1_EMI_RMB,
+	PW_REG_PCIE1_INFRA_RMB,
+	PW_REG_PCIE1_PMIC_RMB,
+	PW_REG_PCIE1_SRCCLKENA_MB,
+	PW_REG_PCIE1_VCORE_RMB,
+	PW_REG_PCIE1_VRF18_RMB,
+	PW_REG_PERISYS_APSRC_RMB,
+	PW_REG_PERISYS_DDREN_RMB,
+	PW_REG_PERISYS_EMI_RMB,
+	PW_REG_PERISYS_INFRA_RMB,
+	PW_REG_PERISYS_PMIC_RMB,
+	PW_REG_PERISYS_SRCCLKENA_MB,
+	PW_REG_PERISYS_VCORE_RMB,
+	PW_REG_PERISYS_VRF18_RMB,
+	PW_REG_PMSR_APSRC_RMB,
+
+	/* SPM_SRC_MASK_13 */
+	PW_REG_PMSR_DDREN_RMB,
+	PW_REG_PMSR_EMI_RMB,
+	PW_REG_PMSR_INFRA_RMB,
+	PW_REG_PMSR_PMIC_RMB,
+	PW_REG_PMSR_SRCCLKENA_MB,
+	PW_REG_PMSR_VCORE_RMB,
+	PW_REG_PMSR_VRF18_RMB,
+	PW_REG_SCP_APSRC_RMB,
+	PW_REG_SCP_DDREN_RMB,
+	PW_REG_SCP_EMI_RMB,
+	PW_REG_SCP_INFRA_RMB,
+	PW_REG_SCP_PMIC_RMB,
+	PW_REG_SCP_SRCCLKENA_MB,
+	PW_REG_SCP_VCORE_RMB,
+	PW_REG_SCP_VRF18_RMB,
+	PW_REG_SPU_HWR_APSRC_RMB,
+	PW_REG_SPU_HWR_DDREN_RMB,
+	PW_REG_SPU_HWR_EMI_RMB,
+	PW_REG_SPU_HWR_INFRA_RMB,
+	PW_REG_SPU_HWR_PMIC_RMB,
+	PW_REG_SPU_HWR_SRCCLKENA_MB,
+	PW_REG_SPU_HWR_VCORE_RMB,
+	PW_REG_SPU_HWR_VRF18_RMB,
+	PW_REG_SPU_ISE_APSRC_RMB,
+	PW_REG_SPU_ISE_DDREN_RMB,
+	PW_REG_SPU_ISE_EMI_RMB,
+	PW_REG_SPU_ISE_INFRA_RMB,
+	PW_REG_SPU_ISE_PMIC_RMB,
+	PW_REG_SPU_ISE_SRCCLKENA_MB,
+	PW_REG_SPU_ISE_VCORE_RMB,
+	PW_REG_SPU_ISE_VRF18_RMB,
+
+	/* SPM_SRC_MASK_14 */
+	PW_REG_SRCCLKENI_INFRA_RMB,
+	PW_REG_SRCCLKENI_PMIC_RMB,
+	PW_REG_SRCCLKENI_SRCCLKENA_MB,
+	PW_REG_SRCCLKENI_VCORE_RMB,
+	PW_REG_SSPM_APSRC_RMB,
+	PW_REG_SSPM_DDREN_RMB,
+	PW_REG_SSPM_EMI_RMB,
+	PW_REG_SSPM_INFRA_RMB,
+	PW_REG_SSPM_PMIC_RMB,
+	PW_REG_SSPM_SRCCLKENA_MB,
+	PW_REG_SSPM_VRF18_RMB,
+	PW_REG_SSRSYS_APSRC_RMB,
+	PW_REG_SSRSYS_DDREN_RMB,
+	PW_REG_SSRSYS_EMI_RMB,
+	PW_REG_SSRSYS_INFRA_RMB,
+	PW_REG_SSRSYS_PMIC_RMB,
+	PW_REG_SSRSYS_SRCCLKENA_MB,
+	PW_REG_SSRSYS_VCORE_RMB,
+	PW_REG_SSRSYS_VRF18_RMB,
+	PW_REG_SSUSB_APSRC_RMB,
+	PW_REG_SSUSB_DDREN_RMB,
+	PW_REG_SSUSB_EMI_RMB,
+	PW_REG_SSUSB_INFRA_RMB,
+	PW_REG_SSUSB_PMIC_RMB,
+	PW_REG_SSUSB_SRCCLKENA_MB,
+	PW_REG_SSUSB_VCORE_RMB,
+	PW_REG_SSUSB_VRF18_RMB,
+	PW_REG_UART_HUB_INFRA_RMB,
+
+	/* SPM_SRC_MASK_15 */
+	PW_REG_UART_HUB_PMIC_RMB,
+	PW_REG_UART_HUB_SRCCLKENA_MB,
+	PW_REG_UART_HUB_VCORE_RMB,
+	PW_REG_UART_HUB_VRF18_RMB,
+	PW_REG_UFS_APSRC_RMB,
+	PW_REG_UFS_DDREN_RMB,
+	PW_REG_UFS_EMI_RMB,
+	PW_REG_UFS_INFRA_RMB,
+	PW_REG_UFS_PMIC_RMB,
+	PW_REG_UFS_SRCCLKENA_MB,
+	PW_REG_UFS_VCORE_RMB,
+	PW_REG_UFS_VRF18_RMB,
+	PW_REG_VDEC_APSRC_RMB,
+	PW_REG_VDEC_DDREN_RMB,
+	PW_REG_VDEC_EMI_RMB,
+	PW_REG_VDEC_INFRA_RMB,
+	PW_REG_VDEC_PMIC_RMB,
+	PW_REG_VDEC_SRCCLKENA_MB,
+	PW_REG_VDEC_VRF18_RMB,
+	PW_REG_VENC_APSRC_RMB,
+	PW_REG_VENC_DDREN_RMB,
+	PW_REG_VENC_EMI_RMB,
+	PW_REG_VENC_INFRA_RMB,
+	PW_REG_VENC_PMIC_RMB,
+	PW_REG_VENC_SRCCLKENA_MB,
+	PW_REG_VENC_VRF18_RMB,
+	PW_REG_VLPCFG_APSRC_RMB,
+	PW_REG_VLPCFG_DDREN_RMB,
+	PW_REG_VLPCFG_EMI_RMB,
+	PW_REG_VLPCFG_INFRA_RMB,
+	PW_REG_VLPCFG_PMIC_RMB,
+	PW_REG_VLPCFG_SRCCLKENA_MB,
+
+	/* SPM_SRC_MASK_16 */
+	PW_REG_VLPCFG_VCORE_RMB,
+	PW_REG_VLPCFG_VRF18_RMB,
+	PW_REG_VLPCFG1_APSRC_RMB,
+	PW_REG_VLPCFG1_DDREN_RMB,
+	PW_REG_VLPCFG1_EMI_RMB,
+	PW_REG_VLPCFG1_INFRA_RMB,
+	PW_REG_VLPCFG1_PMIC_RMB,
+	PW_REG_VLPCFG1_SRCCLKENA_MB,
+	PW_REG_VLPCFG1_VCORE_RMB,
+	PW_REG_VLPCFG1_VRF18_RMB,
+
+	/* SPM_EVENT_CON_MISC */
+	PW_REG_SRCCLKEN_FAST_RESP,
+	PW_REG_CSYSPWRUP_ACK_MASK,
+
+	/* SPM_SRC_MASK_17 */
+	PW_REG_SPM_SW_VCORE_RMB,
+	PW_REG_SPM_SW_PMIC_RMB,
+
+	/* SPM_SRC_MASK_18 */
+	PW_REG_SPM_SW_SRCCLKENA_MB,
+
+	/* SPM_WAKE_MASK*/
+	PW_REG_WAKEUP_EVENT_MASK,
+
+	/* SPM_WAKEUP_EVENT_EXT_MASK */
+	PW_REG_EXT_WAKEUP_EVENT_MASK,
+
+	PW_MAX_COUNT,
+};
+
+/* spm_internal.c internal status */
+#define SPM_INTERNAL_STATUS_HW_S1	BIT(0)
+
+/*
+ * HW_TARG_GROUP_SEL_3		: 3b'1 (pcm_reg_13)
+ * HW_TARG_SIGNAL_SEL_3		: 5b'10101
+ * HW_TRIG_GROUP_SEL_3		: 3'b100 (trig_reserve)
+ * HW_TRIG_SIGNAL_SEL_3		: 5'b1100 (trig_reserve[24]=sc_hw_s1_req)
+ */
+#define SPM_ACK_CHK_3_SEL_HW_S1		(0x00350098)
+#define SPM_ACK_CHK_3_HW_S1_CNT		(1)
+
+#define SPM_ACK_CHK_3_CON_HW_MODE_TRIG	(0x800)
+/* BIT[0]: SW_EN, BIT[4]: STA_EN, BIT[8]: HW_EN */
+#define SPM_ACK_CHK_3_CON_EN		(0x110)
+#define SPM_ACK_CHK_3_CON_CLR_ALL	(0x2)
+/* BIT[15]: RESULT */
+#define SPM_ACK_CHK_3_CON_RESULT	(0x8000)
+
+struct wake_status_trace_comm {
+	uint32_t debug_flag;			/* PCM_WDT_LATCH_SPARE_0 */
+	uint32_t debug_flag1;			/* PCM_WDT_LATCH_SPARE_1 */
+	uint32_t timer_out;			/* SPM_SW_RSV_6*/
+	uint32_t b_sw_flag0;			/* SPM_SW_RSV_7 */
+	uint32_t b_sw_flag1;			/* SPM_SW_RSV_7 */
+	uint32_t r12;				/* SPM_SW_RSV_0 */
+	uint32_t r13;				/* PCM_REG13_DATA */
+	uint32_t req_sta0;			/* SRC_REQ_STA_0 */
+	uint32_t req_sta1;			/* SRC_REQ_STA_1 */
+	uint32_t req_sta2;			/* SRC_REQ_STA_2 */
+	uint32_t req_sta3;			/* SRC_REQ_STA_3 */
+	uint32_t req_sta4;			/* SRC_REQ_STA_4 */
+	uint32_t req_sta5;			/* SRC_REQ_STA_5 */
+	uint32_t req_sta6;			/* SRC_REQ_STA_6 */
+	uint32_t req_sta7;			/* SRC_REQ_STA_7 */
+	uint32_t req_sta8;			/* SRC_REQ_STA_8 */
+	uint32_t req_sta9;			/* SRC_REQ_STA_9 */
+	uint32_t req_sta10;			/* SRC_REQ_STA_10 */
+	uint32_t req_sta11;			/* SRC_REQ_STA_11 */
+	uint32_t req_sta12;			/* SRC_REQ_STA_12 */
+	uint32_t req_sta13;			/* SRC_REQ_STA_13 */
+	uint32_t req_sta14;			/* SRC_REQ_STA_14 */
+	uint32_t req_sta15;			/* SRC_REQ_STA_15 */
+	uint32_t req_sta16;			/* SRC_REQ_STA_16 */
+	uint32_t raw_sta;			/* SPM_WAKEUP_STA */
+	uint32_t times_h;			/* Timestamp high bits */
+	uint32_t times_l;			/* Timestamp low bits */
+	uint32_t resumetime;			/* Timestamp low bits */
+};
+
+struct wake_status_trace {
+	struct wake_status_trace_comm comm;
+	/* Add suspend or idle part bellow */
+};
+
+struct wake_status {
+	struct wake_status_trace tr;
+	uint32_t r12_ext;			/* SPM_WAKEUP_EXT_STA */
+	uint32_t raw_ext_sta;			/* SPM_WAKEUP_EXT_STA */
+	uint32_t md32pcm_wakeup_sta;		/* MD32PCM_WAKEUP_STA */
+	uint32_t md32pcm_event_sta;		/* MD32PCM_EVENT_STA */
+	uint32_t wake_misc;			/* SPM_SW_RSV_5 */
+	uint32_t sw_flag0;			/* SPM_SW_FLAG_0 */
+	uint32_t sw_flag1;			/* SPM_SW_FLAG_1 */
+	uint32_t isr;				/* SPM_IRQ_STA */
+	uint32_t log_index;
+	uint32_t is_abort;
+};
+
+struct spm_lp_scen {
+	struct pcm_desc *pcmdesc;
+	struct pwr_ctrl *pwrctrl;
+	struct dbg_ctrl *dbgctrl;
+	struct spm_lp_stat *lpstat;
+};
+
+extern struct spm_lp_scen __spm_vcorefs;
+typedef uint32_t u32;
+
+void __spm_init_pcm_register(void);	/* init r0 and r7 */
+void __spm_set_power_control(const struct pwr_ctrl *pwrctrl,
+			     uint32_t resource_usage);
+void __spm_set_wakeup_event(const struct pwr_ctrl *pwrctrl);
+void __spm_kick_pcm_to_run(struct pwr_ctrl *pwrctrl);
+void __spm_set_pcm_flags(struct pwr_ctrl *pwrctrl);
+void __spm_send_cpu_wakeup_event(void);
+
+void __spm_get_wakeup_status(struct wake_status *wakesta,
+			     uint32_t ext_status);
+void __spm_clean_after_wakeup(void);
+wake_reason_t __spm_output_wake_reason(const struct wake_status *wakesta);
+
+void __spm_sync_vcore_dvfs_power_control(struct pwr_ctrl *dest_pwr_ctrl,
+					 const struct pwr_ctrl *src_pwr_ctrl);
+void __spm_sync_vcore_dvfs_pcm_flags(uint32_t *dest_pcm_flags,
+				     const uint32_t *src_pcm_flags);
+
+void __spm_set_pcm_wdt(int en);
+uint32_t __spm_get_pcm_timer_val(void);
+uint32_t _spm_get_wake_period(int pwake_time, wake_reason_t last_wr);
+void __spm_set_fw_resume_option(struct pwr_ctrl *pwrctrl);
+void __spm_ext_int_wakeup_req_clr(void);
+
+static inline void set_pwrctrl_pcm_flags(struct pwr_ctrl *pwrctrl,
+					 uint32_t flags)
+{
+	if (pwrctrl->pcm_flags_cust == 0)
+		pwrctrl->pcm_flags = flags;
+	else
+		pwrctrl->pcm_flags = pwrctrl->pcm_flags_cust;
+}
+
+static inline void set_pwrctrl_pcm_flags1(struct pwr_ctrl *pwrctrl,
+					  uint32_t flags)
+{
+	if (pwrctrl->pcm_flags1_cust == 0)
+		pwrctrl->pcm_flags1 = flags;
+	else
+		pwrctrl->pcm_flags1 = pwrctrl->pcm_flags1_cust;
+}
+
+void __spm_hw_s1_state_monitor(int en, uint32_t *status);
+
+static inline void spm_hw_s1_state_monitor_resume(void)
+{
+	__spm_hw_s1_state_monitor(1, NULL);
+}
+static inline void spm_hw_s1_state_monitor_pause(uint32_t *status)
+{
+	__spm_hw_s1_state_monitor(0, status);
+}
+
+int32_t __spm_wait_spm_request_ack(uint32_t spm_resource_req,
+				   uint32_t timeout_us);
+
+#endif /* MT_SPM_INTERNAL */
diff --git a/plat/mediatek/drivers/spm/rules.mk b/plat/mediatek/drivers/spm/rules.mk
index b7128dba1..174d1b154 100644
--- a/plat/mediatek/drivers/spm/rules.mk
+++ b/plat/mediatek/drivers/spm/rules.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2023, MediaTek Inc. All rights reserved.
+# Copyright (c) 2025, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -7,8 +7,6 @@
 LOCAL_DIR := $(call GET_LOCAL_DIR)
 MODULE := spm
 
-$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
-
 ifneq ($(CONFIG_MTK_SPM_VERSION),)
 PLAT_INCLUDES += -I${LOCAL_DIR}/$(MTK_SOC)
 PLAT_INCLUDES += -I${LOCAL_DIR}/version/notifier/inc
@@ -17,4 +15,34 @@ SUB_RULES-y += ${LOCAL_DIR}/$(CONFIG_MTK_SPM_VERSION)
 $(eval $(call add_define,SPM_PLAT_IMPL))
 endif
 
+ifeq ($(CONFIG_MTK_SPM_VERSION), mt8196)
+ifeq ($(CONFIG_MTK_SPM_SUPPORT), y)
+ifeq ($(CONFIG_MTK_SPM_COMMON_SUPPORT), y)
+include ${LOCAL_DIR}/$(CONFIG_MTK_SPM_VERSION)/plat_conf.mk
+PLAT_INCLUDES += -I${LOCAL_DIR}
+PLAT_INCLUDES += -I${LOCAL_DIR}/version
+PLAT_INCLUDES += -I${LOCAL_DIR}/common
+endif
+endif
+
+$(eval $(call add_defined_option,CONFIG_MTK_VCOREDVFS_SUPPORT))
+
+ifneq ($(CONFIG_MTK_SPM_COMMON_SUPPORT), y)
+LOCAL_SRCS-${CONFIG_MTK_SPM_SUPPORT} += ${LOCAL_DIR}/mt_spm_early_init.c
+endif
+
+ifneq ($(CONFIG_MTK_SPM_COMMON_SUPPORT), y)
+LOCAL_SRCS-${CONFIG_MTK_SPM_SUPPORT} += ${LOCAL_DIR}/mt_spm_early_init.c
+endif
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
+
+SUB_RULES-${MTK_SPM_COMMON_DRV} += ${LOCAL_DIR}/common
+SUB_RULES-${MTK_SPM_COMMON_DRV} += ${LOCAL_DIR}/version
+
+$(eval $(call add_defined_option,CONFIG_MTK_SPM_COMMON_SUPPORT))
+else
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
+endif
+
 $(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
diff --git a/plat/mediatek/mt8196/plat_config.mk b/plat/mediatek/mt8196/plat_config.mk
index 7d4309757..f45ec6478 100644
--- a/plat/mediatek/mt8196/plat_config.mk
+++ b/plat/mediatek/mt8196/plat_config.mk
@@ -50,6 +50,8 @@ CPU_PWR_TOPOLOGY := group_4_3_1
 CPU_PM_CORE_ARCH64_ONLY := y
 CPU_PM_DOMAIN_CORE_ONLY := n
 CPU_PM_SUSPEND_NOTIFY := y
+CONFIG_MTK_SPM_SUPPORT := y
+CONFIG_MTK_SPM_COMMON_SUPPORT := y
 CPU_PM_TINYSYS_SUPPORT := y
 MTK_PUBEVENT_ENABLE := y
 CONFIG_MTK_PMIC := y