feat(mt8196): add SPM common driver support
This patch mainly initializes the SPM and provides common APIs for SPM
to enable the use of its various features.
Change-Id: I9facb6bf9962bb2d5fcacd945846bfaeb4c87a55
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 0000000..aea2fb8
--- /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 0000000..b44361e
--- /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 0000000..0dbbfb3
--- /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 0000000..62f090f
--- /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 0000000..50273de
--- /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 0000000..fee5b4c
--- /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 0000000..bc6fa44
--- /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 0000000..16d9f29
--- /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 0000000..692180a
--- /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 0000000..355c492
--- /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 0000000..5e08f3d
--- /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 b7128db..174d1b1 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 @@
$(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 7d43097..f45ec64 100644
--- a/plat/mediatek/mt8196/plat_config.mk
+++ b/plat/mediatek/mt8196/plat_config.mk
@@ -50,6 +50,8 @@
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