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.

Signed-off-by: Wenzhen Yu <wenzhen.yu@mediatek.com>
Change-Id: I9facb6bf9962bb2d5fcacd945846bfaeb4c87a55
This commit is contained in:
Wenzhen Yu 2024-12-16 20:00:23 +08:00
parent fb57af70ae
commit a24b53e0e5
13 changed files with 3160 additions and 3 deletions

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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))

View file

@ -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);

View file

@ -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 */

View file

@ -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;
}

View file

@ -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 */

View file

@ -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));
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2023, MediaTek Inc. All rights reserved.
# Copyright (c) 2025, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -7,8 +7,6 @@
LOCAL_DIR := $(call GET_LOCAL_DIR)
MODULE := spm
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
ifneq ($(CONFIG_MTK_SPM_VERSION),)
PLAT_INCLUDES += -I${LOCAL_DIR}/$(MTK_SOC)
PLAT_INCLUDES += -I${LOCAL_DIR}/version/notifier/inc
@ -17,4 +15,34 @@ SUB_RULES-y += ${LOCAL_DIR}/$(CONFIG_MTK_SPM_VERSION)
$(eval $(call add_define,SPM_PLAT_IMPL))
endif
ifeq ($(CONFIG_MTK_SPM_VERSION), mt8196)
ifeq ($(CONFIG_MTK_SPM_SUPPORT), y)
ifeq ($(CONFIG_MTK_SPM_COMMON_SUPPORT), y)
include ${LOCAL_DIR}/$(CONFIG_MTK_SPM_VERSION)/plat_conf.mk
PLAT_INCLUDES += -I${LOCAL_DIR}
PLAT_INCLUDES += -I${LOCAL_DIR}/version
PLAT_INCLUDES += -I${LOCAL_DIR}/common
endif
endif
$(eval $(call add_defined_option,CONFIG_MTK_VCOREDVFS_SUPPORT))
ifneq ($(CONFIG_MTK_SPM_COMMON_SUPPORT), y)
LOCAL_SRCS-${CONFIG_MTK_SPM_SUPPORT} += ${LOCAL_DIR}/mt_spm_early_init.c
endif
ifneq ($(CONFIG_MTK_SPM_COMMON_SUPPORT), y)
LOCAL_SRCS-${CONFIG_MTK_SPM_SUPPORT} += ${LOCAL_DIR}/mt_spm_early_init.c
endif
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
SUB_RULES-${MTK_SPM_COMMON_DRV} += ${LOCAL_DIR}/common
SUB_RULES-${MTK_SPM_COMMON_DRV} += ${LOCAL_DIR}/version
$(eval $(call add_defined_option,CONFIG_MTK_SPM_COMMON_SUPPORT))
else
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
endif
$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))

View file

@ -50,6 +50,8 @@ CPU_PWR_TOPOLOGY := group_4_3_1
CPU_PM_CORE_ARCH64_ONLY := y
CPU_PM_DOMAIN_CORE_ONLY := n
CPU_PM_SUSPEND_NOTIFY := y
CONFIG_MTK_SPM_SUPPORT := y
CONFIG_MTK_SPM_COMMON_SUPPORT := y
CPU_PM_TINYSYS_SUPPORT := y
MTK_PUBEVENT_ENABLE := y
CONFIG_MTK_PMIC := y