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