mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-24 13:55:56 +00:00
Merge changes I1126311e,I6ae5b5b4,I1b907256,I9facb6bf,Ie51cffeb, ... into integration
* changes: feat(mt8196): add vcore dvfs drivers feat(mt8196): add LPM v2 support feat(mt8196): add SPM common version support feat(mt8196): add SPM common driver support feat(mt8196): add SPM basic features support feat(mt8196): add SPM features support feat(mt8196): enable PMIC low power setting feat(mt8196): add mcdi driver feat(mt8196): add pwr_ctrl module for CPU power management feat(mt8196): add mcusys moudles for power management feat(mt8196): add CPC module for power management feat(mt8196): add topology module for power management feat(mt8196): add SPMI driver feat(mt8196): add PMIC driver
This commit is contained in:
commit
cf2df874cd
139 changed files with 25525 additions and 26 deletions
94
plat/mediatek/common/lpm/mt_lpm_dispatch.c
Normal file
94
plat/mediatek/common/lpm/mt_lpm_dispatch.c
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cdefs.h>
|
||||||
|
|
||||||
|
#include <lpm/mt_lpm_dispatch.h>
|
||||||
|
|
||||||
|
struct mt_dispatch_ctrl mt_dispatcher __section("mt_lpm_s") = {
|
||||||
|
.enable = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mt_dispatch_ctrl mt_secure_dispatcher __section("mt_secure_lpm_s") = {
|
||||||
|
.enable = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
u_register_t invoke_mt_lpm_dispatch(u_register_t x1,
|
||||||
|
u_register_t x2,
|
||||||
|
u_register_t x3,
|
||||||
|
u_register_t x4,
|
||||||
|
void *handle,
|
||||||
|
struct smccc_res *smccc_ret)
|
||||||
|
{
|
||||||
|
uint64_t res = 0;
|
||||||
|
uint32_t user;
|
||||||
|
|
||||||
|
if (!IS_MT_LPM_SMC(x1))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
user = MT_LPM_SMC_USER(x1);
|
||||||
|
if ((user < MT_LPM_SMC_USER_MAX) &&
|
||||||
|
(mt_dispatcher.enable & (BIT(user)))) {
|
||||||
|
res = mt_dispatcher.fn[user](MT_LPM_SMC_USER_ID(x1),
|
||||||
|
x2,
|
||||||
|
x3,
|
||||||
|
x4,
|
||||||
|
handle,
|
||||||
|
smccc_ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
DECLARE_SMC_HANDLER(MTK_SIP_MTK_LPM_CONTROL, invoke_mt_lpm_dispatch);
|
||||||
|
|
||||||
|
u_register_t invoke_mt_secure_lpm_dispatch(u_register_t x1,
|
||||||
|
u_register_t x2,
|
||||||
|
u_register_t x3,
|
||||||
|
u_register_t x4,
|
||||||
|
void *handle,
|
||||||
|
struct smccc_res *smccc_ret)
|
||||||
|
{
|
||||||
|
uint64_t res = 0;
|
||||||
|
uint32_t user;
|
||||||
|
|
||||||
|
if (!IS_MT_LPM_SMC(x1))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
user = MT_LPM_SMC_USER(x1);
|
||||||
|
if (mt_secure_dispatcher.enable & (BIT(user))) {
|
||||||
|
res = mt_secure_dispatcher.fn[user](MT_LPM_SMC_USER_ID(x1),
|
||||||
|
x2,
|
||||||
|
x3,
|
||||||
|
x4,
|
||||||
|
handle,
|
||||||
|
smccc_ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
DECLARE_SMC_HANDLER(MTK_SIP_BL_LPM_CONTROL, invoke_mt_secure_lpm_dispatch);
|
||||||
|
|
||||||
|
/* Check lpm smc user number at compile time */
|
||||||
|
CASSERT(MT_LPM_SMC_USER_MAX <= MTK_DISPATCH_ID_MAX,
|
||||||
|
lpm_smc_user_declare_too_large);
|
||||||
|
|
||||||
|
void mt_lpm_dispatcher_registry(unsigned int id, mt_lpm_dispatch_fn fn)
|
||||||
|
{
|
||||||
|
if (id >= MT_LPM_SMC_USER_MAX)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mt_dispatcher.enable |= BIT(id);
|
||||||
|
mt_dispatcher.fn[id] = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt_secure_lpm_dispatcher_registry(unsigned int id, mt_lpm_dispatch_fn fn)
|
||||||
|
{
|
||||||
|
if (id >= MT_LPM_SMC_USER_MAX)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mt_secure_dispatcher.enable |= BIT(id);
|
||||||
|
mt_secure_dispatcher.fn[id] = fn;
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2023, MediaTek Inc. All rights reserved.
|
# Copyright (c) 2023-2025, MediaTek Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
#
|
#
|
||||||
|
@ -11,6 +11,7 @@ MODULE := lpm
|
||||||
LOCAL_SRCS-y := $(LOCAL_DIR)/mt_lp_api.c
|
LOCAL_SRCS-y := $(LOCAL_DIR)/mt_lp_api.c
|
||||||
LOCAL_SRCS-y += $(LOCAL_DIR)/mt_lp_rm.c
|
LOCAL_SRCS-y += $(LOCAL_DIR)/mt_lp_rm.c
|
||||||
LOCAL_SRCS-y += $(LOCAL_DIR)/mt_lp_rq.c
|
LOCAL_SRCS-y += $(LOCAL_DIR)/mt_lp_rq.c
|
||||||
|
LOCAL_SRCS-y += ${LOCAL_DIR}/mt_lpm_dispatch.c
|
||||||
|
|
||||||
PLAT_INCLUDES += -I${LOCAL_DIR}
|
PLAT_INCLUDES += -I${LOCAL_DIR}
|
||||||
|
|
||||||
|
|
90
plat/mediatek/common/lpm_v2/mt_lp_api.c
Normal file
90
plat/mediatek/common/lpm_v2/mt_lp_api.c
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <lpm_v2/mt_lp_api.h>
|
||||||
|
|
||||||
|
#define UPDATE_STATUS(val, status, bit) \
|
||||||
|
((val) ? ((status) | (1 << (bit))) : ((status) & ~(1 << (bit))))
|
||||||
|
|
||||||
|
static uint64_t lp_status;
|
||||||
|
|
||||||
|
int mt_audio_update(int type)
|
||||||
|
{
|
||||||
|
int ret, val;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case AUDIO_AFE_ENTER:
|
||||||
|
case AUDIO_AFE_LEAVE:
|
||||||
|
val = (type == AUDIO_AFE_ENTER) ? 1 : 0;
|
||||||
|
lp_status = UPDATE_STATUS(val, lp_status, AUDIO_AFE);
|
||||||
|
ret = mt_lp_rm_do_update(-1, PLAT_RC_IS_FMAUDIO, &val);
|
||||||
|
break;
|
||||||
|
case AUDIO_DSP_ENTER:
|
||||||
|
case AUDIO_DSP_LEAVE:
|
||||||
|
val = (type == AUDIO_DSP_ENTER) ? 1 : 0;
|
||||||
|
lp_status = UPDATE_STATUS(val, lp_status, AUDIO_DSP);
|
||||||
|
ret = mt_lp_rm_do_update(-1, PLAT_RC_IS_ADSP, &val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_usb_update(int type)
|
||||||
|
{
|
||||||
|
int ret, val;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case LPM_USB_ENTER:
|
||||||
|
case LPM_USB_LEAVE:
|
||||||
|
val = (type == LPM_USB_ENTER) ? 1 : 0;
|
||||||
|
ret = mt_lp_rm_do_update(-1, PLAT_RC_IS_USB_INFRA, &val);
|
||||||
|
break;
|
||||||
|
case USB_HEADSET_ENTER:
|
||||||
|
case USB_HEADSET_LEAVE:
|
||||||
|
val = (type == USB_HEADSET_ENTER) ? 1 : 0;
|
||||||
|
lp_status = UPDATE_STATUS(val, lp_status, USB_HEADSET);
|
||||||
|
ret = mt_lp_rm_do_update(-1, PLAT_RC_IS_USB_HEADSET, &val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t mt_get_lp_scenario_status(void)
|
||||||
|
{
|
||||||
|
return lp_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_gpueb_hwctrl(int type, void *priv)
|
||||||
|
{
|
||||||
|
int ret, val;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case GPUEB_PLL_EN:
|
||||||
|
case GPUEB_PLL_DIS:
|
||||||
|
val = (type == GPUEB_PLL_EN) ? 1 : 0;
|
||||||
|
ret = mt_lp_rm_do_hwctrl(PLAT_AP_GPUEB_PLL_CONTROL, val, priv);
|
||||||
|
break;
|
||||||
|
case GPUEB_GET_PWR_STATUS:
|
||||||
|
ret = mt_lp_rm_do_hwctrl(PLAT_AP_GPUEB_PWR_STATUS, 0, priv);
|
||||||
|
break;
|
||||||
|
case GPUEB_GET_MFG0_PWR_CON:
|
||||||
|
ret = mt_lp_rm_do_hwctrl(PLAT_AP_GPUEB_MFG0_PWR_CON, 0, priv);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
19
plat/mediatek/common/lpm_v2/mt_lp_mmap.c
Normal file
19
plat/mediatek/common/lpm_v2/mt_lp_mmap.c
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
#include <mtk_mmap_pool.h>
|
||||||
|
|
||||||
|
static const mmap_region_t lpm_sram_mmap[] MTK_MMAP_SECTION = {
|
||||||
|
#if (MTK_LPM_SRAM_BASE && MTK_LPM_SRAM_MAP_SIZE)
|
||||||
|
/* LPM used syssram */
|
||||||
|
MAP_REGION_FLAT(MTK_LPM_SRAM_BASE, MTK_LPM_SRAM_MAP_SIZE,
|
||||||
|
MT_DEVICE | MT_RW | MT_SECURE),
|
||||||
|
#endif
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
DECLARE_MTK_MMAP_REGIONS(lpm_sram_mmap);
|
164
plat/mediatek/common/lpm_v2/mt_lp_rm.c
Normal file
164
plat/mediatek/common/lpm_v2/mt_lp_rm.c
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <lpm_v2/mt_lp_rm.h>
|
||||||
|
|
||||||
|
struct platform_mt_resource_manager {
|
||||||
|
unsigned int count;
|
||||||
|
struct mt_resource_manager *plat_rm;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_mt_resource_manager plat_mt_rm;
|
||||||
|
|
||||||
|
int mt_lp_rm_register(struct mt_resource_manager *rm)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
struct mt_resource_constraint *const *rc;
|
||||||
|
|
||||||
|
if ((rm == NULL) || (rm->consts == NULL) ||
|
||||||
|
(plat_mt_rm.plat_rm != NULL)) {
|
||||||
|
return MT_RM_STATUS_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0U, rc = rm->consts; *rc != NULL; i++, rc++) {
|
||||||
|
if ((*rc)->init != NULL)
|
||||||
|
(*rc)->init();
|
||||||
|
}
|
||||||
|
|
||||||
|
plat_mt_rm.plat_rm = rm;
|
||||||
|
plat_mt_rm.count = i;
|
||||||
|
|
||||||
|
return MT_RM_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_lp_rm_reset_constraint(unsigned int idx, unsigned int cpuid, int stateid)
|
||||||
|
{
|
||||||
|
struct mt_resource_constraint const *rc = NULL;
|
||||||
|
|
||||||
|
if ((plat_mt_rm.plat_rm == NULL) || (idx >= plat_mt_rm.count))
|
||||||
|
return MT_RM_STATUS_BAD;
|
||||||
|
|
||||||
|
rc = plat_mt_rm.plat_rm->consts[idx];
|
||||||
|
|
||||||
|
if ((rc == NULL) || (rc->reset == NULL))
|
||||||
|
return MT_RM_STATUS_BAD;
|
||||||
|
|
||||||
|
return rc->reset(cpuid, stateid);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_lp_rm_get_status(unsigned int type, void *priv)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
struct mt_resource_constraint *const *con;
|
||||||
|
struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
|
||||||
|
|
||||||
|
if ((rm == NULL) || (type >= PLAT_RC_MAX))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (con = rm->consts; *con != NULL; con++) {
|
||||||
|
if ((*con)->get_status == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
res = (*con)->get_status(type, priv);
|
||||||
|
if (res == MT_RM_STATUS_STOP)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_lp_rm_do_constraint(unsigned int constraint_id, unsigned int cpuid, int stateid)
|
||||||
|
{
|
||||||
|
int res = MT_RM_STATUS_BAD;
|
||||||
|
struct mt_resource_constraint const *rc;
|
||||||
|
struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
|
||||||
|
|
||||||
|
if ((rm == NULL) || (constraint_id >= plat_mt_rm.count))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
rc = rm->consts[constraint_id];
|
||||||
|
if ((rc != NULL) && (rc->run != NULL))
|
||||||
|
res = rc->run(cpuid, stateid);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_lp_rm_find_constraint(unsigned int idx, unsigned int cpuid,
|
||||||
|
int stateid, void *priv)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
int res = MT_RM_STATUS_BAD;
|
||||||
|
struct mt_resource_constraint *const *rc;
|
||||||
|
struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
|
||||||
|
|
||||||
|
if ((rm == NULL) || (idx >= plat_mt_rm.count))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/* If subsys clk/mtcmos is on, add block-resource-off flag */
|
||||||
|
if (rm->update != NULL) {
|
||||||
|
res = rm->update(rm->consts, plat_mt_rm.count, stateid, priv);
|
||||||
|
if (res != 0)
|
||||||
|
return MT_RM_STATUS_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = MT_RM_STATUS_BAD;
|
||||||
|
for (i = idx, rc = (rm->consts + idx); *rc != NULL; i++, rc++) {
|
||||||
|
if (((*rc)->is_valid != NULL) &&
|
||||||
|
((*rc)->is_valid(cpuid, stateid))) {
|
||||||
|
res = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_lp_rm_find_and_run_constraint(unsigned int idx, unsigned int cpuid,
|
||||||
|
int stateid, void *priv)
|
||||||
|
{
|
||||||
|
int res = MT_RM_STATUS_BAD;
|
||||||
|
|
||||||
|
res = mt_lp_rm_find_constraint(idx, cpuid, stateid, priv);
|
||||||
|
if (res != MT_RM_STATUS_BAD)
|
||||||
|
mt_lp_rm_do_constraint(res, cpuid, stateid);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_lp_rm_do_update(int stateid, int type, void const *p)
|
||||||
|
{
|
||||||
|
int res = MT_RM_STATUS_BAD;
|
||||||
|
struct mt_resource_constraint *const *rc;
|
||||||
|
struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
|
||||||
|
|
||||||
|
if (rm == NULL)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
for (rc = rm->consts; *rc != NULL; rc++) {
|
||||||
|
if ((*rc)->update != NULL) {
|
||||||
|
res = (*rc)->update(stateid, type, p);
|
||||||
|
if (res != MT_RM_STATUS_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_lp_rm_do_hwctrl(unsigned int type, int set, void *priv)
|
||||||
|
{
|
||||||
|
struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
if (!rm || !rm->hwctrl || (type >= PLAT_AP_HW_CTRL_MAX))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
res = rm->hwctrl(type, set, priv);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
239
plat/mediatek/common/lpm_v2/mt_lp_rq.c
Normal file
239
plat/mediatek/common/lpm_v2/mt_lp_rq.c
Normal file
|
@ -0,0 +1,239 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <common/debug.h>
|
||||||
|
#include <drivers/console.h>
|
||||||
|
#include <lib/spinlock.h>
|
||||||
|
|
||||||
|
#include <lpm_v2/mt_lp_rm.h>
|
||||||
|
#include <lpm_v2/mt_lp_rqm.h>
|
||||||
|
|
||||||
|
struct _mt_lp_res_req_m_ {
|
||||||
|
unsigned int uname[MT_LP_RQ_USER_MAX];
|
||||||
|
unsigned int user_num;
|
||||||
|
unsigned int user_valid;
|
||||||
|
unsigned int resource_num;
|
||||||
|
unsigned int generic_resource_req;
|
||||||
|
unsigned int flag;
|
||||||
|
struct mt_resource_req_manager *plat_rqm;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct _mt_lp_res_req_m_ plat_mt_rqm;
|
||||||
|
static spinlock_t mt_lp_rq_lock;
|
||||||
|
|
||||||
|
static int mt_lp_resource_update_and_set(struct mt_lp_resource_user *this);
|
||||||
|
|
||||||
|
static int mt_lp_resource_request(struct mt_lp_resource_user *this,
|
||||||
|
unsigned int resource)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct mt_lp_res_req *const *rs;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if ((this == NULL) || (resource == 0) || (resource > MT_LP_RQ_ALL)) {
|
||||||
|
ERROR("invalid request(%x)\n", resource);
|
||||||
|
return MT_LP_RQ_STA_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock(&mt_lp_rq_lock);
|
||||||
|
|
||||||
|
rs = (plat_mt_rqm.plat_rqm)->res;
|
||||||
|
for (i = 0; i < plat_mt_rqm.resource_num; i++) {
|
||||||
|
if ((resource & rs[i]->res_id) != 0)
|
||||||
|
rs[i]->res_usage |= this->umask;
|
||||||
|
}
|
||||||
|
|
||||||
|
plat_mt_rqm.flag = MT_LP_RQ_FLAG_NEED_UPDATE;
|
||||||
|
spin_unlock(&mt_lp_rq_lock);
|
||||||
|
|
||||||
|
ret = mt_lp_resource_update_and_set(this);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mt_lp_resource_release(struct mt_lp_resource_user *this)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct mt_lp_res_req *const *rs;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (this == NULL)
|
||||||
|
return MT_LP_RQ_STA_BAD;
|
||||||
|
|
||||||
|
spin_lock(&mt_lp_rq_lock);
|
||||||
|
|
||||||
|
rs = (plat_mt_rqm.plat_rqm)->res;
|
||||||
|
for (i = 0; i < plat_mt_rqm.resource_num; i++)
|
||||||
|
rs[i]->res_usage &= ~(this->umask);
|
||||||
|
|
||||||
|
plat_mt_rqm.flag = MT_LP_RQ_FLAG_NEED_UPDATE;
|
||||||
|
spin_unlock(&mt_lp_rq_lock);
|
||||||
|
|
||||||
|
ret = mt_lp_resource_update_and_set(this);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_lp_resource_request_manager_register(struct mt_resource_req_manager *rm)
|
||||||
|
{
|
||||||
|
unsigned int count;
|
||||||
|
struct mt_lp_res_req *const *rs;
|
||||||
|
|
||||||
|
if (!rm || !(rm->res) || (plat_mt_rqm.plat_rqm != NULL))
|
||||||
|
return MT_LP_RQ_STA_BAD;
|
||||||
|
|
||||||
|
rs = rm->res;
|
||||||
|
count = 0;
|
||||||
|
while (*rs != NULL) {
|
||||||
|
count++;
|
||||||
|
rs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
plat_mt_rqm.plat_rqm = rm;
|
||||||
|
plat_mt_rqm.resource_num = count;
|
||||||
|
|
||||||
|
return MT_LP_RQ_STA_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int mt_lp_resource_user_register(char *user, struct mt_lp_resource_user *ru)
|
||||||
|
{
|
||||||
|
int i, len;
|
||||||
|
unsigned int uname;
|
||||||
|
|
||||||
|
if ((plat_mt_rqm.plat_rqm == NULL) || (user == NULL))
|
||||||
|
goto invalid;
|
||||||
|
|
||||||
|
len = strnlen(user, MT_LP_RQ_USER_NAME_LEN);
|
||||||
|
|
||||||
|
uname = 0;
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
uname |= (user[i] << (MT_LP_RQ_USER_CHAR_U * i));
|
||||||
|
|
||||||
|
spin_lock(&mt_lp_rq_lock);
|
||||||
|
|
||||||
|
if (plat_mt_rqm.user_num >= MT_LP_RQ_USER_MAX) {
|
||||||
|
spin_unlock(&mt_lp_rq_lock);
|
||||||
|
goto invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = plat_mt_rqm.user_num;
|
||||||
|
plat_mt_rqm.user_num += 1;
|
||||||
|
plat_mt_rqm.uname[i] = uname;
|
||||||
|
plat_mt_rqm.user_valid |= BIT(i);
|
||||||
|
spin_unlock(&mt_lp_rq_lock);
|
||||||
|
|
||||||
|
ru->umask = BIT(i);
|
||||||
|
ru->uid = i;
|
||||||
|
ru->request = mt_lp_resource_request;
|
||||||
|
ru->release = mt_lp_resource_release;
|
||||||
|
INFO("%s register by %s, uid = %d\n", __func__, user, ru->uid);
|
||||||
|
|
||||||
|
return MT_LP_RQ_STA_OK;
|
||||||
|
|
||||||
|
invalid:
|
||||||
|
ru->uid = MT_LP_RQ_USER_INVALID;
|
||||||
|
ru->umask = 0;
|
||||||
|
ru->request = NULL;
|
||||||
|
ru->release = NULL;
|
||||||
|
return MT_LP_RQ_STA_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_lp_rq_get_status(int type, void *p)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned int update_sta = 0;
|
||||||
|
struct mt_lp_res_req *const *rs;
|
||||||
|
struct resource_req_status *rq_sta = (struct resource_req_status *)p;
|
||||||
|
|
||||||
|
spin_lock(&mt_lp_rq_lock);
|
||||||
|
|
||||||
|
if (plat_mt_rqm.flag) {
|
||||||
|
rs = (plat_mt_rqm.plat_rqm)->res;
|
||||||
|
for (i = 0; i < plat_mt_rqm.resource_num; i++) {
|
||||||
|
if ((rs[i]->res_usage & plat_mt_rqm.user_valid) != 0)
|
||||||
|
update_sta |= rs[i]->res_rq;
|
||||||
|
}
|
||||||
|
|
||||||
|
plat_mt_rqm.generic_resource_req = update_sta;
|
||||||
|
plat_mt_rqm.flag = MT_LP_RQ_FLAG_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case PLAT_RQ_REQ_USAGE:
|
||||||
|
rs = (plat_mt_rqm.plat_rqm)->res;
|
||||||
|
rq_sta->val = plat_mt_rqm.generic_resource_req;
|
||||||
|
if (rq_sta->id < plat_mt_rqm.resource_num)
|
||||||
|
rq_sta->val = rs[rq_sta->id]->res_usage;
|
||||||
|
break;
|
||||||
|
case PLAT_RQ_USER_NUM:
|
||||||
|
rq_sta->val = plat_mt_rqm.user_num;
|
||||||
|
break;
|
||||||
|
case PLAT_RQ_USER_VALID:
|
||||||
|
rq_sta->val = plat_mt_rqm.user_valid;
|
||||||
|
break;
|
||||||
|
case PLAT_RQ_PER_USER_NAME:
|
||||||
|
rq_sta->val = (rq_sta->id < plat_mt_rqm.user_num) ?
|
||||||
|
plat_mt_rqm.uname[rq_sta->id] : 0;
|
||||||
|
break;
|
||||||
|
case PLAT_RQ_REQ_NUM:
|
||||||
|
rq_sta->val = plat_mt_rqm.resource_num;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock(&mt_lp_rq_lock);
|
||||||
|
|
||||||
|
return MT_LP_RQ_STA_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_lp_rq_update_status(int type, void *p)
|
||||||
|
{
|
||||||
|
unsigned int user;
|
||||||
|
struct resource_req_status *rq_sta = (struct resource_req_status *)p;
|
||||||
|
|
||||||
|
spin_lock(&mt_lp_rq_lock);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case PLAT_RQ_USER_VALID:
|
||||||
|
if (rq_sta->id >= plat_mt_rqm.user_num)
|
||||||
|
break;
|
||||||
|
user = BIT(rq_sta->id);
|
||||||
|
plat_mt_rqm.user_valid = (rq_sta->val == 0) ?
|
||||||
|
(plat_mt_rqm.user_valid & ~(user)) :
|
||||||
|
(plat_mt_rqm.user_valid | user);
|
||||||
|
plat_mt_rqm.flag = MT_LP_RQ_FLAG_NEED_UPDATE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock(&mt_lp_rq_lock);
|
||||||
|
|
||||||
|
return MT_LP_RQ_STA_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mt_lp_resource_update_and_set(struct mt_lp_resource_user *this)
|
||||||
|
{
|
||||||
|
unsigned int ret = MT_LP_RQ_STA_OK;
|
||||||
|
struct resource_req_status generic_spm_resource_req = {
|
||||||
|
.id = MT_LP_RQ_ID_ALL_USAGE,
|
||||||
|
.val = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
mt_lp_rq_get_status(PLAT_RQ_REQ_USAGE, &generic_spm_resource_req);
|
||||||
|
ret = mt_lp_rm_do_hwctrl(PLAT_AP_SPM_RESOURCE_REQUEST_UPDATE, 1,
|
||||||
|
&generic_spm_resource_req.val);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
ret = MT_LP_RQ_STA_BAD;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
89
plat/mediatek/common/lpm_v2/mt_lpm_dispatch.c
Normal file
89
plat/mediatek/common/lpm_v2/mt_lpm_dispatch.c
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cdefs.h>
|
||||||
|
|
||||||
|
#include <lpm_v2/mt_lpm_dispatch.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Notice, this data don't link to bss section.
|
||||||
|
* It means data structure won't be set as zero.
|
||||||
|
* Please make sure the member will be initialized.
|
||||||
|
*/
|
||||||
|
struct mt_dispatch_ctrl mt_dispatcher
|
||||||
|
__section("mt_lpm_s") = {
|
||||||
|
.enable = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mt_dispatch_ctrl mt_secure_dispatcher
|
||||||
|
__section("mt_secure_lpm_s") = {
|
||||||
|
.enable = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
u_register_t invoke_mt_lpm_dispatch(u_register_t x1, u_register_t x2,
|
||||||
|
u_register_t x3, u_register_t x4,
|
||||||
|
void *handle, struct smccc_res *smccc_ret)
|
||||||
|
{
|
||||||
|
uint64_t res = 0;
|
||||||
|
uint32_t user;
|
||||||
|
|
||||||
|
if (!IS_MT_LPM_SMC(x1))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
user = MT_LPM_SMC_USER(x1);
|
||||||
|
if ((user < MT_LPM_SMC_USER_MAX) &&
|
||||||
|
(mt_dispatcher.enable & (1 << user))) {
|
||||||
|
res = mt_dispatcher.fn[user](MT_LPM_SMC_USER_ID(x1),
|
||||||
|
x2, x3, x4,
|
||||||
|
handle, smccc_ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
DECLARE_SMC_HANDLER(MTK_SIP_MTK_LPM_CONTROL, invoke_mt_lpm_dispatch);
|
||||||
|
|
||||||
|
u_register_t invoke_mt_secure_lpm_dispatch(u_register_t x1, u_register_t x2,
|
||||||
|
u_register_t x3, u_register_t x4,
|
||||||
|
void *handle,
|
||||||
|
struct smccc_res *smccc_ret)
|
||||||
|
{
|
||||||
|
uint64_t res = 0;
|
||||||
|
unsigned int user;
|
||||||
|
|
||||||
|
if (!IS_MT_LPM_SMC(x1))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
user = MT_LPM_SMC_USER(x1);
|
||||||
|
if (mt_secure_dispatcher.enable & (1 << user)) {
|
||||||
|
res = mt_secure_dispatcher.fn[user](MT_LPM_SMC_USER_ID(x1), x2,
|
||||||
|
x3, x4, handle, smccc_ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
DECLARE_SMC_HANDLER(MTK_SIP_BL_LPM_CONTROL, invoke_mt_secure_lpm_dispatch);
|
||||||
|
|
||||||
|
/* Check lpm smc user number at compile time */
|
||||||
|
CASSERT(MT_LPM_SMC_USER_MAX <= MTK_DISPATCH_ID_MAX,
|
||||||
|
lpm_smc_user_declare_too_large);
|
||||||
|
|
||||||
|
void mt_lpm_dispatcher_registry(unsigned int id, mt_lpm_dispatch_fn fn)
|
||||||
|
{
|
||||||
|
if (id >= MT_LPM_SMC_USER_MAX)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mt_dispatcher.enable |= BIT(id);
|
||||||
|
mt_dispatcher.fn[id] = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt_secure_lpm_dispatcher_registry(unsigned int id, mt_lpm_dispatch_fn fn)
|
||||||
|
{
|
||||||
|
if (id >= MT_LPM_SMC_USER_MAX)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mt_secure_dispatcher.enable |= BIT(id);
|
||||||
|
mt_secure_dispatcher.fn[id] = fn;
|
||||||
|
}
|
19
plat/mediatek/common/lpm_v2/rules.mk
Normal file
19
plat/mediatek/common/lpm_v2/rules.mk
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
#
|
||||||
|
|
||||||
|
LOCAL_DIR := $(call GET_LOCAL_DIR)
|
||||||
|
|
||||||
|
MODULE := lpm_v2
|
||||||
|
|
||||||
|
LOCAL_SRCS-y += ${LOCAL_DIR}/mt_lp_api.c
|
||||||
|
LOCAL_SRCS-y += ${LOCAL_DIR}/mt_lp_rm.c
|
||||||
|
LOCAL_SRCS-y += ${LOCAL_DIR}/mt_lp_rq.c
|
||||||
|
LOCAL_SRCS-y += ${LOCAL_DIR}/mt_lp_mmap.c
|
||||||
|
LOCAL_SRCS-y += ${LOCAL_DIR}/mt_lpm_dispatch.c
|
||||||
|
|
||||||
|
PLAT_INCLUDES += -I${LOCAL_DIR}
|
||||||
|
|
||||||
|
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
|
1009
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_cpu_pm.c
Normal file
1009
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_cpu_pm.c
Normal file
File diff suppressed because it is too large
Load diff
314
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_cpu_pm.h
Normal file
314
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_cpu_pm.h
Normal file
|
@ -0,0 +1,314 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_CPU_PM_H
|
||||||
|
#define MT_CPU_PM_H
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
#include <lib/pm/mtk_pm.h>
|
||||||
|
|
||||||
|
#if !HW_ASSISTED_COHERENCY
|
||||||
|
#define MT_CPU_PM_USING_BAKERY_LOCK
|
||||||
|
#endif /* !HW_ASSISTED_COHERENCY */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable bit of CPU_PM callbacks
|
||||||
|
*/
|
||||||
|
static inline unsigned int CPU_PM_FN(void)
|
||||||
|
{
|
||||||
|
return (MTK_CPUPM_FN_CPUPM_GET_PWR_STATE |
|
||||||
|
MTK_CPUPM_FN_PWR_STATE_VALID |
|
||||||
|
MTK_CPUPM_FN_PWR_ON_CORE_PREPARE |
|
||||||
|
MTK_CPUPM_FN_RESUME_CORE |
|
||||||
|
#ifdef CPU_PM_PWR_REQ
|
||||||
|
MTK_CPUPM_FN_SUSPEND_CLUSTER |
|
||||||
|
#endif /* CPU_PM_PWR_REQ */
|
||||||
|
MTK_CPUPM_FN_RESUME_CLUSTER |
|
||||||
|
MTK_CPUPM_FN_SUSPEND_MCUSYS |
|
||||||
|
MTK_CPUPM_FN_RESUME_MCUSYS |
|
||||||
|
MTK_CPUPM_FN_SMP_INIT |
|
||||||
|
MTK_CPUPM_FN_SMP_CORE_ON |
|
||||||
|
MTK_CPUPM_FN_SMP_CORE_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CPU_PM_ASSERT(_cond) ({ \
|
||||||
|
if (!(_cond)) { \
|
||||||
|
INFO("[%s:%d] - %s\n", __func__, __LINE__, #_cond); \
|
||||||
|
panic(); \
|
||||||
|
} })
|
||||||
|
|
||||||
|
/* related registers */
|
||||||
|
#define SPM_POWERON_CONFIG_EN (SPM_BASE + 0x000)
|
||||||
|
#define SPM_CPU_PWR_STATUS (SPM_BASE + 0x174)
|
||||||
|
|
||||||
|
/* bit-fields of SPM_POWERON_CONFIG_EN */
|
||||||
|
#define PROJECT_CODE (0xB16U << 16)
|
||||||
|
#define BCLK_CG_EN BIT(0)
|
||||||
|
|
||||||
|
#define CPC_PWR_MASK_MCUSYS_MP0 (0xC001)
|
||||||
|
|
||||||
|
#define PER_CLUSTER_PWR_DATA(_p, _cl) ({ \
|
||||||
|
_p.pwr.ppu_pwpr = CLUSTER_PPU_PWPR_##_cl; \
|
||||||
|
_p.pwr.ppu_pwsr = CLUSTER_PPU_PWSR_##_cl; \
|
||||||
|
_p.pwr.ppu_dcdr0 = CLUSTER_PPU_DCDR0_##_cl; \
|
||||||
|
_p.pwr.ppu_dcdr1 = CLUSTER_PPU_DCDR1_##_cl; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define PER_CLUSTER_PWR_CTRL(_val, _cl) ({ \
|
||||||
|
switch (_cl) { \
|
||||||
|
case 0: \
|
||||||
|
PER_CLUSTER_PWR_DATA(_val, 0); \
|
||||||
|
break; \
|
||||||
|
default: \
|
||||||
|
assert(0); \
|
||||||
|
break; \
|
||||||
|
} })
|
||||||
|
|
||||||
|
#define PER_CPU_PWR_DATA(_p, _cl, _c) ({ \
|
||||||
|
_p.rvbaraddr_l = CORE_RVBRADDR_##_cl##_##_c##_L; \
|
||||||
|
_p.rvbaraddr_h = CORE_RVBRADDR_##_cl##_##_c##_H; \
|
||||||
|
_p.pwr.ppu_pwpr = CORE_PPU_PWPR_##_cl##_##_c; \
|
||||||
|
_p.pwr.ppu_pwsr = CORE_PPU_PWSR_##_cl##_##_c; \
|
||||||
|
_p.pwr.ppu_dcdr0 = CORE_PPU_DCDR0_##_cl##_##_c; \
|
||||||
|
_p.pwr.ppu_dcdr1 = CORE_PPU_DCDR1_##_cl##_##_c; })
|
||||||
|
|
||||||
|
#define PER_CPU_PWR_CTRL(_val, _cpu) ({ \
|
||||||
|
switch (_cpu) { \
|
||||||
|
case 0: \
|
||||||
|
PER_CPU_PWR_DATA(_val, 0, 0); \
|
||||||
|
break; \
|
||||||
|
case 1: \
|
||||||
|
PER_CPU_PWR_DATA(_val, 0, 1); \
|
||||||
|
break; \
|
||||||
|
case 2: \
|
||||||
|
PER_CPU_PWR_DATA(_val, 0, 2); \
|
||||||
|
break; \
|
||||||
|
case 3: \
|
||||||
|
PER_CPU_PWR_DATA(_val, 0, 3); \
|
||||||
|
break; \
|
||||||
|
case 4: \
|
||||||
|
PER_CPU_PWR_DATA(_val, 0, 4); \
|
||||||
|
break; \
|
||||||
|
case 5: \
|
||||||
|
PER_CPU_PWR_DATA(_val, 0, 5); \
|
||||||
|
break; \
|
||||||
|
case 6: \
|
||||||
|
PER_CPU_PWR_DATA(_val, 0, 6); \
|
||||||
|
break; \
|
||||||
|
case 7: \
|
||||||
|
PER_CPU_PWR_DATA(_val, 0, 7); \
|
||||||
|
break; \
|
||||||
|
default: \
|
||||||
|
assert(0); \
|
||||||
|
break; \
|
||||||
|
} })
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definition about bootup address for each core
|
||||||
|
* CORE_RVBRADDR_clusterid_cpuid
|
||||||
|
*/
|
||||||
|
#define CORE_RVBRADDR_0_0_L (MCUCFG_BASE + 0x00)
|
||||||
|
#define CORE_RVBRADDR_0_1_L (MCUCFG_BASE + 0x08)
|
||||||
|
#define CORE_RVBRADDR_0_2_L (MCUCFG_BASE + 0x10)
|
||||||
|
#define CORE_RVBRADDR_0_3_L (MCUCFG_BASE + 0x18)
|
||||||
|
#define CORE_RVBRADDR_0_4_L (MCUCFG_BASE + 0x20)
|
||||||
|
#define CORE_RVBRADDR_0_5_L (MCUCFG_BASE + 0x28)
|
||||||
|
#define CORE_RVBRADDR_0_6_L (MCUCFG_BASE + 0x30)
|
||||||
|
#define CORE_RVBRADDR_0_7_L (MCUCFG_BASE + 0x38)
|
||||||
|
|
||||||
|
#define CORE_RVBRADDR_0_0_H (MCUCFG_BASE + 0x04)
|
||||||
|
#define CORE_RVBRADDR_0_1_H (MCUCFG_BASE + 0x0C)
|
||||||
|
#define CORE_RVBRADDR_0_2_H (MCUCFG_BASE + 0x14)
|
||||||
|
#define CORE_RVBRADDR_0_3_H (MCUCFG_BASE + 0x1C)
|
||||||
|
#define CORE_RVBRADDR_0_4_H (MCUCFG_BASE + 0x24)
|
||||||
|
#define CORE_RVBRADDR_0_5_H (MCUCFG_BASE + 0x2C)
|
||||||
|
#define CORE_RVBRADDR_0_6_H (MCUCFG_BASE + 0x34)
|
||||||
|
#define CORE_RVBRADDR_0_7_H (MCUCFG_BASE + 0x3C)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definition about PPU PWPR for each core
|
||||||
|
* PPU_PWPR_clusterid_cpuid
|
||||||
|
*/
|
||||||
|
#define CORE_PPU_PWPR_0_0 (MT_UTILITYBUS_BASE + 0x080000)
|
||||||
|
#define CORE_PPU_PWPR_0_1 (MT_UTILITYBUS_BASE + 0x180000)
|
||||||
|
#define CORE_PPU_PWPR_0_2 (MT_UTILITYBUS_BASE + 0x280000)
|
||||||
|
#define CORE_PPU_PWPR_0_3 (MT_UTILITYBUS_BASE + 0x380000)
|
||||||
|
#define CORE_PPU_PWPR_0_4 (MT_UTILITYBUS_BASE + 0x480000)
|
||||||
|
#define CORE_PPU_PWPR_0_5 (MT_UTILITYBUS_BASE + 0x580000)
|
||||||
|
#define CORE_PPU_PWPR_0_6 (MT_UTILITYBUS_BASE + 0x680000)
|
||||||
|
#define CORE_PPU_PWPR_0_7 (MT_UTILITYBUS_BASE + 0x780000)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definition about PPU PWSR for each core
|
||||||
|
* PPU_PWSR_clusterid_cpuid
|
||||||
|
*/
|
||||||
|
#define CORE_PPU_PWSR_0_0 (MT_UTILITYBUS_BASE + 0x080008)
|
||||||
|
#define CORE_PPU_PWSR_0_1 (MT_UTILITYBUS_BASE + 0x180008)
|
||||||
|
#define CORE_PPU_PWSR_0_2 (MT_UTILITYBUS_BASE + 0x280008)
|
||||||
|
#define CORE_PPU_PWSR_0_3 (MT_UTILITYBUS_BASE + 0x380008)
|
||||||
|
#define CORE_PPU_PWSR_0_4 (MT_UTILITYBUS_BASE + 0x480008)
|
||||||
|
#define CORE_PPU_PWSR_0_5 (MT_UTILITYBUS_BASE + 0x580008)
|
||||||
|
#define CORE_PPU_PWSR_0_6 (MT_UTILITYBUS_BASE + 0x680008)
|
||||||
|
#define CORE_PPU_PWSR_0_7 (MT_UTILITYBUS_BASE + 0x780008)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definition about device delay control 0
|
||||||
|
* PPU_DCDR0_clusterid_cpuid
|
||||||
|
*/
|
||||||
|
#define CORE_PPU_DCDR0_0_0 (MT_UTILITYBUS_BASE + 0x080170)
|
||||||
|
#define CORE_PPU_DCDR0_0_1 (MT_UTILITYBUS_BASE + 0x180170)
|
||||||
|
#define CORE_PPU_DCDR0_0_2 (MT_UTILITYBUS_BASE + 0x280170)
|
||||||
|
#define CORE_PPU_DCDR0_0_3 (MT_UTILITYBUS_BASE + 0x380170)
|
||||||
|
#define CORE_PPU_DCDR0_0_4 (MT_UTILITYBUS_BASE + 0x480170)
|
||||||
|
#define CORE_PPU_DCDR0_0_5 (MT_UTILITYBUS_BASE + 0x580170)
|
||||||
|
#define CORE_PPU_DCDR0_0_6 (MT_UTILITYBUS_BASE + 0x680170)
|
||||||
|
#define CORE_PPU_DCDR0_0_7 (MT_UTILITYBUS_BASE + 0x780170)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definition about device delay control 1
|
||||||
|
* PPU_DCDR0_clusterid_cpuid
|
||||||
|
*/
|
||||||
|
#define CORE_PPU_DCDR1_0_0 (MT_UTILITYBUS_BASE + 0x080174)
|
||||||
|
#define CORE_PPU_DCDR1_0_1 (MT_UTILITYBUS_BASE + 0x180174)
|
||||||
|
#define CORE_PPU_DCDR1_0_2 (MT_UTILITYBUS_BASE + 0x280174)
|
||||||
|
#define CORE_PPU_DCDR1_0_3 (MT_UTILITYBUS_BASE + 0x380174)
|
||||||
|
#define CORE_PPU_DCDR1_0_4 (MT_UTILITYBUS_BASE + 0x480174)
|
||||||
|
#define CORE_PPU_DCDR1_0_5 (MT_UTILITYBUS_BASE + 0x580174)
|
||||||
|
#define CORE_PPU_DCDR1_0_6 (MT_UTILITYBUS_BASE + 0x680174)
|
||||||
|
#define CORE_PPU_DCDR1_0_7 (MT_UTILITYBUS_BASE + 0x780174)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definition about PPU PWPR for cluster
|
||||||
|
* PPU_PWPR_clusterid
|
||||||
|
*/
|
||||||
|
#define CLUSTER_PPU_PWPR_0 (MT_UTILITYBUS_BASE + 0x030000)
|
||||||
|
#define CLUSTER_PPU_PWSR_0 (MT_UTILITYBUS_BASE + 0x030008)
|
||||||
|
#define CLUSTER_PPU_DCDR0_0 (MT_UTILITYBUS_BASE + 0x030170)
|
||||||
|
#define CLUSTER_PPU_DCDR1_0 (MT_UTILITYBUS_BASE + 0x030174)
|
||||||
|
|
||||||
|
struct ppu_pwr_ctrl {
|
||||||
|
unsigned int ppu_pwpr;
|
||||||
|
unsigned int ppu_pwsr;
|
||||||
|
unsigned int ppu_dcdr0;
|
||||||
|
unsigned int ppu_dcdr1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cpu_pwr_ctrl {
|
||||||
|
unsigned int rvbaraddr_l;
|
||||||
|
unsigned int rvbaraddr_h;
|
||||||
|
#ifndef CPU_PM_CORE_ARCH64_ONLY
|
||||||
|
unsigned int arch_addr;
|
||||||
|
#endif /* CPU_PM_CORE_ARCH64_ONLY */
|
||||||
|
struct ppu_pwr_ctrl pwr;
|
||||||
|
unsigned int pwr_ctrl;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cluster_pwr_ctrl {
|
||||||
|
struct ppu_pwr_ctrl pwr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MT_CPUPM_PWR_ON BIT(0)
|
||||||
|
#define MT_CPUPM_PWR_OFF BIT(1)
|
||||||
|
|
||||||
|
#ifdef CPU_PM_SUSPEND_NOTIFY
|
||||||
|
#define PER_CPU_STATUS_S2IDLE BIT(0)
|
||||||
|
#define PER_CPU_STATUS_PDN BIT(1)
|
||||||
|
#define PER_CPU_STATUS_HOTPLUG BIT(2)
|
||||||
|
#define PER_CPU_STATUS_S2IDLE_PDN \
|
||||||
|
(PER_CPU_STATUS_S2IDLE | PER_CPU_STATUS_PDN)
|
||||||
|
|
||||||
|
#define CPUPM_PWR_STATUS(_state, _tar) ((_state & _tar) == _tar)
|
||||||
|
#define IS_CPUPM_SAVE_PWR_STATUS(_state) ( \
|
||||||
|
CPUPM_PWR_STATUS(_state, PER_CPU_STATUS_S2IDLE_PDN) || \
|
||||||
|
(_state & PER_CPU_STATUS_HOTPLUG))
|
||||||
|
|
||||||
|
#ifdef CONFIG_MTK_CPU_ILDO
|
||||||
|
#define CPU_PM_CPU_RET_IS_ENABLED CPU_PM_CPU_RET_MASK
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CPU_PM_RET_SET_SUCCESS = 0,
|
||||||
|
CPU_PM_RET_SET_FAIL
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CPU_EB_RET_STA_REG (CPU_EB_TCM_BASE + CPU_EB_RET_STA_OFFSET)
|
||||||
|
#define CPU_RET_TIMEOUT 100
|
||||||
|
#endif /* CONFIG_MTK_CPU_ILDO */
|
||||||
|
|
||||||
|
struct per_cpu_stage {
|
||||||
|
unsigned int cpu_status;
|
||||||
|
};
|
||||||
|
#endif /* CPU_PM_SUSPEND_NOTIFY */
|
||||||
|
|
||||||
|
#define MCUSYS_STATUS_PDN BIT(0)
|
||||||
|
#define MCUSYS_STATUS_CPUSYS_PROTECT BIT(8)
|
||||||
|
#define MCUSYS_STATUS_MCUSYS_PROTECT BIT(9)
|
||||||
|
|
||||||
|
#ifdef CPU_PM_ACP_FSM
|
||||||
|
#define ACP_FSM_TIMEOUT_MAX (500)
|
||||||
|
#define ACP_FSM_AWARE_TIME (100)
|
||||||
|
#define DO_ACP_FSM_WAIT_TIMEOUT(k_cnt) ({ \
|
||||||
|
if (k_cnt >= ACP_FSM_TIMEOUT_MAX) { \
|
||||||
|
INFO("[%s:%d] - ACP FSM TIMEOUT %u us (> %u)\n", \
|
||||||
|
__func__, __LINE__, k_cnt, ACP_FSM_TIMEOUT_MAX); \
|
||||||
|
panic(); \
|
||||||
|
} else if (k_cnt == ACP_FSM_AWARE_TIME) { \
|
||||||
|
INFO("[%s:%d] - ACP FSM latency exceed %u us\n", \
|
||||||
|
__func__, __LINE__, ACP_FSM_AWARE_TIME); \
|
||||||
|
} \
|
||||||
|
k_cnt++; udelay(1); })
|
||||||
|
#endif /* CPU_PM_ACP_FSM */
|
||||||
|
|
||||||
|
/* cpu_pm function ID */
|
||||||
|
enum mt_cpu_pm_user_id {
|
||||||
|
MCUSYS_STATUS = 0,
|
||||||
|
CPC_COMMAND,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* cpu_pm lp function ID */
|
||||||
|
enum mt_cpu_pm_lp_smc_id {
|
||||||
|
LP_CPC_COMMAND = 0,
|
||||||
|
IRQS_REMAIN_ALLOC,
|
||||||
|
IRQS_REMAIN_CTRL,
|
||||||
|
IRQS_REMAIN_IRQ,
|
||||||
|
IRQS_REMAIN_WAKEUP_CAT,
|
||||||
|
IRQS_REMAIN_WAKEUP_SRC,
|
||||||
|
SUSPEND_SRC,
|
||||||
|
CPU_PM_COUNTER_CTRL,
|
||||||
|
CPU_PM_RECORD_CTRL,
|
||||||
|
SUSPEND_ABORT_REASON,
|
||||||
|
CPU_PM_RET_CTRL
|
||||||
|
};
|
||||||
|
|
||||||
|
enum mt_suspend_abort_reason {
|
||||||
|
MTK_PM_SUSPEND_OK = 0,
|
||||||
|
MTK_PM_SUSPEND_ABORT_PWR_REQ,
|
||||||
|
MTK_PM_SUSPEND_ABORT_LAST_CORE,
|
||||||
|
MTK_PM_SUSPEND_ABORT_RC_INVALID,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mtk_plat_dev_config {
|
||||||
|
int auto_off;
|
||||||
|
unsigned int auto_thres_us;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mt_cpu_pm_record {
|
||||||
|
unsigned int cnt;
|
||||||
|
uint64_t name[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int cpupm_cpu_retention_control(unsigned int enable);
|
||||||
|
unsigned int cpupu_get_cpu_retention_control(void);
|
||||||
|
void mt_plat_cpu_pm_dev_update(struct mtk_plat_dev_config *config);
|
||||||
|
int mt_plat_cpu_pm_dev_config(struct mtk_plat_dev_config **config);
|
||||||
|
int cpupm_set_suspend_state(unsigned int act, unsigned int cpuid);
|
||||||
|
uint64_t mtk_mcusys_off_record_cnt_get(void);
|
||||||
|
uint64_t mtk_mcusys_off_record_name_get(void);
|
||||||
|
uint64_t mtk_suspend_abort_reason_get(void);
|
||||||
|
|
||||||
|
#endif /* MT_CPU_PM_H */
|
701
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_cpu_pm_cpc.c
Normal file
701
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_cpu_pm_cpc.c
Normal file
|
@ -0,0 +1,701 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <drivers/delay_timer.h>
|
||||||
|
#include <lib/spinlock.h>
|
||||||
|
|
||||||
|
#include <lib/pm/mtk_pm.h>
|
||||||
|
#include <mcucfg.h>
|
||||||
|
#include "mt_cpu_pm.h"
|
||||||
|
#include "mt_cpu_pm_cpc.h"
|
||||||
|
#include "mt_smp.h"
|
||||||
|
#include <mt_timer.h>
|
||||||
|
|
||||||
|
#define CHECK_GIC_SGI_PENDING (0)
|
||||||
|
#define MTK_SYS_TIMER_SYNC_SUPPORT (1)
|
||||||
|
#define MCUSYS_CLUSTER_DORMANT_MASK 0xFFFF
|
||||||
|
|
||||||
|
struct mtk_cpc_lat_data {
|
||||||
|
unsigned int on_sum;
|
||||||
|
unsigned int on_min;
|
||||||
|
unsigned int on_max;
|
||||||
|
unsigned int off_sum;
|
||||||
|
unsigned int off_min;
|
||||||
|
unsigned int off_max;
|
||||||
|
unsigned int on_cnt;
|
||||||
|
unsigned int off_cnt;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mtk_cpc_device {
|
||||||
|
union {
|
||||||
|
struct mtk_cpc_lat_data p[DEV_TYPE_NUM];
|
||||||
|
struct {
|
||||||
|
struct mtk_cpc_lat_data cpu[PLATFORM_CORE_COUNT];
|
||||||
|
struct mtk_cpc_lat_data cluster;
|
||||||
|
struct mtk_cpc_lat_data mcusys;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mtk_cpc_device cpc_dev;
|
||||||
|
|
||||||
|
static bool cpu_pm_counter_enabled;
|
||||||
|
static bool cpu_cpc_prof_enabled;
|
||||||
|
|
||||||
|
static void mtk_cpc_auto_dormant_en(unsigned int en)
|
||||||
|
{
|
||||||
|
struct mtk_plat_dev_config *cfg = NULL;
|
||||||
|
|
||||||
|
if (en)
|
||||||
|
mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, CPC_AUTO_OFF_EN);
|
||||||
|
else
|
||||||
|
mmio_clrbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, CPC_AUTO_OFF_EN);
|
||||||
|
|
||||||
|
mt_plat_cpu_pm_dev_config(&cfg);
|
||||||
|
|
||||||
|
if (cfg) {
|
||||||
|
cfg->auto_off = !!en;
|
||||||
|
mt_plat_cpu_pm_dev_update(cfg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mtk_cpc_auto_dormant_tick(unsigned int us)
|
||||||
|
{
|
||||||
|
struct mtk_plat_dev_config *cfg = NULL;
|
||||||
|
|
||||||
|
mmio_write_32(CPC_MCUSYS_CPC_OFF_THRES, US_TO_TICKS(us));
|
||||||
|
|
||||||
|
mt_plat_cpu_pm_dev_config(&cfg);
|
||||||
|
|
||||||
|
if (cfg) {
|
||||||
|
cfg->auto_thres_us = us;
|
||||||
|
mt_plat_cpu_pm_dev_update(cfg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mtk_cpu_pm_mcusys_prot_release(void)
|
||||||
|
{
|
||||||
|
mmio_write_32(CPC_MCUSYS_PWR_ON_MASK, MCUSYS_PROT_CLR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mtk_cpc_last_core_prot(int prot_req, int resp_reg, int resp_ofs)
|
||||||
|
{
|
||||||
|
unsigned int sta, retry;
|
||||||
|
|
||||||
|
retry = 0;
|
||||||
|
|
||||||
|
while (retry < RETRY_CNT_MAX) {
|
||||||
|
mmio_write_32(CPC_MCUSYS_LAST_CORE_REQ, prot_req);
|
||||||
|
udelay(1);
|
||||||
|
sta = (mmio_read_32(resp_reg) >> resp_ofs) & CPC_PROT_RESP_MASK;
|
||||||
|
|
||||||
|
if (sta == PROT_GIVEUP)
|
||||||
|
return CPC_ERR_FAIL;
|
||||||
|
|
||||||
|
if (sta == PROT_SUCCESS) {
|
||||||
|
if (mmio_read_32(CPC_WAKEUP_REQ) ==
|
||||||
|
CPC_WAKEUP_STAT_NONE)
|
||||||
|
return CPC_SUCCESS;
|
||||||
|
|
||||||
|
mtk_cpu_pm_mcusys_prot_release();
|
||||||
|
}
|
||||||
|
|
||||||
|
retry++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CPC_ERR_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mtk_cpu_pm_mcusys_prot_aquire(void)
|
||||||
|
{
|
||||||
|
return mtk_cpc_last_core_prot(MCUSYS_PROT_SET,
|
||||||
|
CPC_MCUSYS_LAST_CORE_RESP,
|
||||||
|
MCUSYS_RESP_OFS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mtk_cpu_pm_cluster_prot_aquire(int cluster)
|
||||||
|
{
|
||||||
|
return mtk_cpc_last_core_prot(CPUSYS_PROT_SET,
|
||||||
|
CPC_MCUSYS_MP_LAST_CORE_RESP,
|
||||||
|
CPUSYS_RESP_OFS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mtk_cpu_pm_cluster_prot_release(int cluster)
|
||||||
|
{
|
||||||
|
mmio_write_32(CPC_MCUSYS_PWR_ON_MASK, CPUSYS_PROT_CLR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_cpu_pm_counter_enabled(void)
|
||||||
|
{
|
||||||
|
return cpu_pm_counter_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mtk_cpc_cluster_cnt_backup(void)
|
||||||
|
{
|
||||||
|
int backup_cnt;
|
||||||
|
int curr_cnt;
|
||||||
|
|
||||||
|
if (is_cpu_pm_counter_enabled() == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Single Cluster */
|
||||||
|
backup_cnt = mmio_read_32(SYSRAM_CLUSTER_CNT_BACKUP);
|
||||||
|
curr_cnt = mmio_read_32(CPC_MCUSYS_CLUSTER_COUNTER);
|
||||||
|
|
||||||
|
/* Get off count if dormant count is 0 */
|
||||||
|
if ((curr_cnt & MCUSYS_CLUSTER_DORMANT_MASK) == 0)
|
||||||
|
curr_cnt = (curr_cnt >> 16) & MCUSYS_CLUSTER_DORMANT_MASK;
|
||||||
|
else
|
||||||
|
curr_cnt = curr_cnt & MCUSYS_CLUSTER_DORMANT_MASK;
|
||||||
|
|
||||||
|
mmio_write_32(SYSRAM_CLUSTER_CNT_BACKUP, backup_cnt + curr_cnt);
|
||||||
|
mmio_write_32(CPC_MCUSYS_CLUSTER_COUNTER_CLR, 0x3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void mtk_cpc_mcusys_off_en(void)
|
||||||
|
{
|
||||||
|
mmio_setbits_32(CPC_MCUSYS_PWR_CTRL, CPC_MCUSYS_OFF_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void mtk_cpc_mcusys_off_dis(void)
|
||||||
|
{
|
||||||
|
mmio_clrbits_32(CPC_MCUSYS_PWR_CTRL, CPC_MCUSYS_OFF_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mtk_cpc_mcusys_off_reflect(void)
|
||||||
|
{
|
||||||
|
mtk_cpc_mcusys_off_dis();
|
||||||
|
mtk_cpu_pm_mcusys_prot_release();
|
||||||
|
}
|
||||||
|
|
||||||
|
int mtk_cpc_mcusys_off_prepare(void)
|
||||||
|
{
|
||||||
|
if (mtk_cpu_pm_mcusys_prot_aquire() != CPC_SUCCESS)
|
||||||
|
return CPC_ERR_FAIL;
|
||||||
|
|
||||||
|
#if CHECK_GIC_SGI_PENDING
|
||||||
|
if (!!(gicr_get_sgi_pending())) {
|
||||||
|
mtk_cpu_pm_mcusys_prot_release();
|
||||||
|
return CPC_ERR_FAIL;
|
||||||
|
}
|
||||||
|
#endif /* CHECK_GIC_SGI_PENDING */
|
||||||
|
mtk_cpc_cluster_cnt_backup();
|
||||||
|
mtk_cpc_mcusys_off_en();
|
||||||
|
|
||||||
|
return CPC_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mtk_cpc_core_on_hint_set(int cpu)
|
||||||
|
{
|
||||||
|
mmio_write_32(CPC_MCUSYS_CPU_ON_SW_HINT_SET, BIT(cpu));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mtk_cpc_core_on_hint_clr(int cpu)
|
||||||
|
{
|
||||||
|
mmio_write_32(CPC_MCUSYS_CPU_ON_SW_HINT_CLR, BIT(cpu));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mtk_cpc_dump_timestamp(void)
|
||||||
|
{
|
||||||
|
unsigned int id;
|
||||||
|
|
||||||
|
for (id = 0; id < CPC_TRACE_ID_NUM; id++) {
|
||||||
|
mmio_write_32(CPC_MCUSYS_TRACE_SEL, id);
|
||||||
|
|
||||||
|
memcpy((void *)(uintptr_t)CPC_TRACE_SRAM(id),
|
||||||
|
(const void *)(uintptr_t)CPC_MCUSYS_TRACE_DATA,
|
||||||
|
CPC_TRACE_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mtk_cpc_time_sync(void)
|
||||||
|
{
|
||||||
|
#if MTK_SYS_TIMER_SYNC_SUPPORT
|
||||||
|
uint64_t kt;
|
||||||
|
uint32_t systime_l, systime_h;
|
||||||
|
|
||||||
|
kt = sched_clock();
|
||||||
|
systime_l = mmio_read_32(CNTSYS_L_REG);
|
||||||
|
systime_h = mmio_read_32(CNTSYS_H_REG);
|
||||||
|
|
||||||
|
/* sync kernel timer to cpc */
|
||||||
|
mmio_write_32(CPC_MCUSYS_CPC_KERNEL_TIME_L_BASE, (uint32_t)kt);
|
||||||
|
mmio_write_32(CPC_MCUSYS_CPC_KERNEL_TIME_H_BASE, (uint32_t)(kt >> 32));
|
||||||
|
|
||||||
|
/* sync system timer to cpc */
|
||||||
|
mmio_write_32(CPC_MCUSYS_CPC_SYSTEM_TIME_L_BASE, systime_l);
|
||||||
|
mmio_write_32(CPC_MCUSYS_CPC_SYSTEM_TIME_H_BASE, systime_h);
|
||||||
|
#endif /* MTK_SYS_TIMER_SYNC_SUPPORT */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mtk_cpc_time_freeze(bool is_freeze)
|
||||||
|
{
|
||||||
|
#if MTK_SYS_TIMER_SYNC_SUPPORT
|
||||||
|
mtk_cpc_time_sync();
|
||||||
|
if (is_freeze)
|
||||||
|
mmio_setbits_32(CPC_MCUSYS_CPC_DBG_SETTING, CPC_FREEZE);
|
||||||
|
else
|
||||||
|
mmio_clrbits_32(CPC_MCUSYS_CPC_DBG_SETTING, CPC_FREEZE);
|
||||||
|
#endif /* MTK_SYS_TIMER_SYNC_SUPPORT */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *mtk_cpc_el3_timesync_handler(const void *arg)
|
||||||
|
{
|
||||||
|
if (arg) {
|
||||||
|
unsigned int *is_time_sync = (unsigned int *)arg;
|
||||||
|
|
||||||
|
if (*is_time_sync)
|
||||||
|
mtk_cpc_time_freeze(false);
|
||||||
|
else
|
||||||
|
mtk_cpc_time_freeze(true);
|
||||||
|
}
|
||||||
|
return (void *)arg;
|
||||||
|
}
|
||||||
|
MT_CPUPM_SUBCRIBE_EL3_UPTIME_SYNC_WITH_KERNEL(mtk_cpc_el3_timesync_handler);
|
||||||
|
|
||||||
|
static void mtk_cpc_config(unsigned int cfg, unsigned int data)
|
||||||
|
{
|
||||||
|
unsigned int reg = 0;
|
||||||
|
|
||||||
|
switch (cfg) {
|
||||||
|
case CPC_SMC_CONFIG_PROF:
|
||||||
|
reg = CPC_MCUSYS_CPC_DBG_SETTING;
|
||||||
|
if (data)
|
||||||
|
mmio_setbits_32(reg, CPC_PROF_EN);
|
||||||
|
else
|
||||||
|
mmio_clrbits_32(reg, CPC_PROF_EN);
|
||||||
|
break;
|
||||||
|
case CPC_SMC_CONFIG_CNT_CLR:
|
||||||
|
reg = CPC_MCUSYS_CLUSTER_COUNTER_CLR;
|
||||||
|
mmio_write_32(reg, 0x3);
|
||||||
|
break;
|
||||||
|
case CPC_SMC_CONFIG_TIME_SYNC:
|
||||||
|
mtk_cpc_time_sync();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int mtk_cpc_read_config(unsigned int cfg)
|
||||||
|
{
|
||||||
|
unsigned int res = 0;
|
||||||
|
|
||||||
|
switch (cfg) {
|
||||||
|
case CPC_SMC_CONFIG_PROF:
|
||||||
|
res = mmio_read_32(CPC_MCUSYS_CPC_DBG_SETTING) & CPC_PROF_EN
|
||||||
|
? 1 : 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PROF_DEV_NAME_LEN 8
|
||||||
|
uint64_t mtk_cpc_prof_dev_name(unsigned int dev_id)
|
||||||
|
{
|
||||||
|
uint64_t ret = 0, tran = 0;
|
||||||
|
unsigned int i = 0;
|
||||||
|
static const char *prof_dev_name[DEV_TYPE_NUM] = {
|
||||||
|
"CPU0",
|
||||||
|
"CPU1",
|
||||||
|
"CPU2",
|
||||||
|
"CPU3",
|
||||||
|
"CPU4",
|
||||||
|
"CPU5",
|
||||||
|
"CPU6",
|
||||||
|
"CPU7",
|
||||||
|
"CPUSYS",
|
||||||
|
"MCUSYS"
|
||||||
|
};
|
||||||
|
|
||||||
|
while ((prof_dev_name[dev_id][i] != '\0') && (i < PROF_DEV_NAME_LEN)) {
|
||||||
|
tran = (uint64_t)(prof_dev_name[dev_id][i] & 0xFF);
|
||||||
|
ret |= (tran << (i << 3));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mtk_cpc_prof_clr(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < DEV_TYPE_NUM; i++)
|
||||||
|
memset((char *)&cpc_dev.p[i], 0,
|
||||||
|
sizeof(struct mtk_cpc_lat_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mtk_cpc_prof_enable(bool enable)
|
||||||
|
{
|
||||||
|
unsigned int reg = 0;
|
||||||
|
|
||||||
|
reg = CPC_MCUSYS_CPC_DBG_SETTING;
|
||||||
|
if (enable)
|
||||||
|
mmio_setbits_32(reg, CPC_PROF_EN);
|
||||||
|
else
|
||||||
|
mmio_clrbits_32(reg, CPC_PROF_EN);
|
||||||
|
|
||||||
|
if ((cpu_cpc_prof_enabled == false) && (enable == true))
|
||||||
|
mtk_cpc_prof_clr();
|
||||||
|
cpu_cpc_prof_enabled = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mtk_cpc_prof_is_enabled(void)
|
||||||
|
{
|
||||||
|
return cpu_cpc_prof_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t mtk_cpc_prof_dev_num(void)
|
||||||
|
{
|
||||||
|
return DEV_TYPE_NUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define cpc_tick_to_us(val) ((val) / 13)
|
||||||
|
uint64_t mtk_cpc_prof_read(unsigned int prof_act, unsigned int dev_type)
|
||||||
|
{
|
||||||
|
uint64_t ret = 0;
|
||||||
|
struct mtk_cpc_lat_data *lat_data;
|
||||||
|
|
||||||
|
if (dev_type >= DEV_TYPE_NUM)
|
||||||
|
return CPC_ERR_FAIL;
|
||||||
|
|
||||||
|
lat_data = &cpc_dev.p[dev_type];
|
||||||
|
|
||||||
|
switch (prof_act) {
|
||||||
|
case CPC_PROF_OFF_CNT:
|
||||||
|
ret = lat_data->off_cnt;
|
||||||
|
break;
|
||||||
|
case CPC_PROF_OFF_AVG:
|
||||||
|
ret = cpc_tick_to_us(lat_data->off_sum / lat_data->off_cnt);
|
||||||
|
break;
|
||||||
|
case CPC_PROF_OFF_MAX:
|
||||||
|
ret = cpc_tick_to_us(lat_data->off_max);
|
||||||
|
break;
|
||||||
|
case CPC_PROF_OFF_MIN:
|
||||||
|
ret = cpc_tick_to_us(lat_data->off_min);
|
||||||
|
break;
|
||||||
|
case CPC_PROF_ON_CNT:
|
||||||
|
ret = lat_data->on_cnt;
|
||||||
|
break;
|
||||||
|
case CPC_PROF_ON_AVG:
|
||||||
|
ret = cpc_tick_to_us(lat_data->on_sum / lat_data->on_cnt);
|
||||||
|
break;
|
||||||
|
case CPC_PROF_ON_MAX:
|
||||||
|
ret = cpc_tick_to_us(lat_data->on_max);
|
||||||
|
break;
|
||||||
|
case CPC_PROF_ON_MIN:
|
||||||
|
ret = cpc_tick_to_us(lat_data->on_min);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t mtk_cpc_prof_latency(unsigned int prof_act, unsigned int arg)
|
||||||
|
{
|
||||||
|
uint64_t res = 0;
|
||||||
|
|
||||||
|
switch (prof_act) {
|
||||||
|
case CPC_PROF_ENABLE:
|
||||||
|
mtk_cpc_prof_enable((bool)arg);
|
||||||
|
break;
|
||||||
|
case CPC_PROF_ENABLED:
|
||||||
|
res = (uint64_t)mtk_cpc_prof_is_enabled();
|
||||||
|
break;
|
||||||
|
case CPC_PROF_DEV_NUM:
|
||||||
|
res = mtk_cpc_prof_dev_num();
|
||||||
|
break;
|
||||||
|
case CPC_PROF_DEV_NAME:
|
||||||
|
res = mtk_cpc_prof_dev_name(arg);
|
||||||
|
break;
|
||||||
|
case CPC_PROF_OFF_CNT:
|
||||||
|
case CPC_PROF_OFF_AVG:
|
||||||
|
case CPC_PROF_OFF_MAX:
|
||||||
|
case CPC_PROF_OFF_MIN:
|
||||||
|
case CPC_PROF_ON_CNT:
|
||||||
|
case CPC_PROF_ON_AVG:
|
||||||
|
case CPC_PROF_ON_MAX:
|
||||||
|
case CPC_PROF_ON_MIN:
|
||||||
|
res = (uint64_t)mtk_cpc_prof_read(prof_act, arg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t mtk_cpc_handler(uint64_t act, uint64_t arg1, uint64_t arg2)
|
||||||
|
{
|
||||||
|
uint64_t res = 0;
|
||||||
|
|
||||||
|
switch (act) {
|
||||||
|
case CPC_SMC_EVENT_GIC_DPG_SET:
|
||||||
|
/* isolated_status = x2; */
|
||||||
|
break;
|
||||||
|
case CPC_SMC_EVENT_CPC_CONFIG:
|
||||||
|
mtk_cpc_config((unsigned int)arg1, (unsigned int)arg2);
|
||||||
|
break;
|
||||||
|
case CPC_SMC_EVENT_READ_CONFIG:
|
||||||
|
res = mtk_cpc_read_config((unsigned int)arg1);
|
||||||
|
break;
|
||||||
|
case CPC_SMC_EVENT_PROF_LATENCY:
|
||||||
|
res = mtk_cpc_prof_latency((unsigned int)arg1,
|
||||||
|
(unsigned int)arg2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t mtk_cpc_trace_dump(uint64_t act, uint64_t arg1, uint64_t arg2)
|
||||||
|
{
|
||||||
|
uint64_t res = 0;
|
||||||
|
|
||||||
|
switch (act) {
|
||||||
|
case CPC_SMC_EVENT_DUMP_TRACE_DATA:
|
||||||
|
mtk_cpc_dump_timestamp();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mtk_cpu_pm_counter_clear(void)
|
||||||
|
{
|
||||||
|
unsigned int cpu = 0;
|
||||||
|
|
||||||
|
for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
|
||||||
|
mmio_write_32(SYSRAM_RECENT_CPU_CNT(cpu), 0);
|
||||||
|
|
||||||
|
mmio_write_32(SYSRAM_RECENT_CLUSTER_CNT, 0);
|
||||||
|
mmio_write_32(SYSRAM_RECENT_MCUSYS_CNT, 0);
|
||||||
|
mmio_write_32(SYSRAM_CPUSYS_CNT, 0);
|
||||||
|
mmio_write_32(SYSRAM_MCUSYS_CNT, 0);
|
||||||
|
mmio_write_32(CPC_MCUSYS_CLUSTER_COUNTER_CLR, 0x3);
|
||||||
|
mmio_write_32(SYSRAM_CLUSTER_CNT_BACKUP, 0x0);
|
||||||
|
mmio_write_32(SYSRAM_RECENT_CNT_TS_H, 0x0);
|
||||||
|
mmio_write_32(SYSRAM_RECENT_CNT_TS_L, 0x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mtk_cpu_pm_counter_enable(bool enable)
|
||||||
|
{
|
||||||
|
cpu_pm_counter_enabled = enable;
|
||||||
|
if (cpu_pm_counter_enabled == false)
|
||||||
|
mtk_cpu_pm_counter_clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mtk_cpu_pm_counter_enabled(void)
|
||||||
|
{
|
||||||
|
return cpu_pm_counter_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define sec_to_us(v) ((v) * 1000 * 1000ULL)
|
||||||
|
#define DUMP_INTERVAL sec_to_us(5)
|
||||||
|
void mtk_cpu_pm_counter_update(unsigned int cpu)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_MTK_CPU_SUSPEND_EN
|
||||||
|
unsigned int cnt = 0, curr_mcusys_cnt = 0, mcusys_cnt = 0;
|
||||||
|
static unsigned int prev_mcusys_cnt = 0,
|
||||||
|
cpu_cnt[PLATFORM_CORE_COUNT] = {0};
|
||||||
|
uint64_t curr_us = 0;
|
||||||
|
static uint64_t last_dump_us;
|
||||||
|
static bool reset;
|
||||||
|
|
||||||
|
if (is_cpu_pm_counter_enabled() == false) {
|
||||||
|
reset = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reset == true) {
|
||||||
|
last_dump_us = sched_clock() / 1000;
|
||||||
|
prev_mcusys_cnt = mmio_read_32(MCUPM_TCM_MCUSYS_COUNTER);
|
||||||
|
mtk_cpu_pm_counter_clear();
|
||||||
|
cpu_cnt[cpu] = 0;
|
||||||
|
reset = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu_cnt[cpu]++;
|
||||||
|
|
||||||
|
curr_us = sched_clock() / 1000;
|
||||||
|
if (curr_us - last_dump_us > DUMP_INTERVAL) {
|
||||||
|
last_dump_us = curr_us;
|
||||||
|
|
||||||
|
/* CPU off count */
|
||||||
|
for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) {
|
||||||
|
mmio_write_32(SYSRAM_RECENT_CPU_CNT(cpu),
|
||||||
|
cpu_cnt[cpu]);
|
||||||
|
cpu_cnt[cpu] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cluster off count */
|
||||||
|
curr_mcusys_cnt = mmio_read_32(MCUPM_TCM_MCUSYS_COUNTER);
|
||||||
|
if (curr_mcusys_cnt >= prev_mcusys_cnt)
|
||||||
|
mcusys_cnt = curr_mcusys_cnt - prev_mcusys_cnt;
|
||||||
|
else
|
||||||
|
mcusys_cnt = curr_mcusys_cnt;
|
||||||
|
prev_mcusys_cnt = mmio_read_32(MCUPM_TCM_MCUSYS_COUNTER);
|
||||||
|
|
||||||
|
cnt = mmio_read_32(CPC_MCUSYS_CLUSTER_COUNTER);
|
||||||
|
/**
|
||||||
|
* bit[0:15] : memory retention
|
||||||
|
* bit[16:31] : memory off
|
||||||
|
*/
|
||||||
|
if ((cnt & MCUSYS_CLUSTER_DORMANT_MASK) == 0)
|
||||||
|
cnt = ((cnt >> 16) & MCUSYS_CLUSTER_DORMANT_MASK);
|
||||||
|
else
|
||||||
|
cnt = cnt & MCUSYS_CLUSTER_DORMANT_MASK;
|
||||||
|
cnt += mmio_read_32(SYSRAM_CLUSTER_CNT_BACKUP);
|
||||||
|
cnt += mcusys_cnt;
|
||||||
|
|
||||||
|
mmio_write_32(SYSRAM_RECENT_CLUSTER_CNT, cnt);
|
||||||
|
mmio_write_32(SYSRAM_CPUSYS_CNT,
|
||||||
|
cnt + mmio_read_32(SYSRAM_CPUSYS_CNT));
|
||||||
|
mmio_write_32(CPC_MCUSYS_CLUSTER_COUNTER_CLR, 0x3);
|
||||||
|
mmio_write_32(SYSRAM_CLUSTER_CNT_BACKUP, 0x0);
|
||||||
|
|
||||||
|
/* MCUSYS off count */
|
||||||
|
mmio_write_32(SYSRAM_RECENT_MCUSYS_CNT,
|
||||||
|
mcusys_cnt);
|
||||||
|
|
||||||
|
mmio_write_32(SYSRAM_MCUSYS_CNT,
|
||||||
|
mmio_read_32(SYSRAM_MCUSYS_CNT) + mcusys_cnt);
|
||||||
|
|
||||||
|
mmio_write_32(SYSRAM_RECENT_CNT_TS_H,
|
||||||
|
(unsigned int)((last_dump_us >> 32) & 0xFFFFFFFF));
|
||||||
|
|
||||||
|
mmio_write_32(SYSRAM_RECENT_CNT_TS_L,
|
||||||
|
(unsigned int)(last_dump_us & 0xFFFFFFFF));
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_MTK_CPU_SUSPEND_EN */
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __mtk_cpc_record_lat(sum, min, max, lat)\
|
||||||
|
do { \
|
||||||
|
if (lat > max) \
|
||||||
|
max = lat; \
|
||||||
|
if ((lat < min) || (min == 0)) \
|
||||||
|
min = lat; \
|
||||||
|
(sum) += (lat); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#ifdef MT_CPU_PM_USING_BAKERY_LOCK
|
||||||
|
DEFINE_BAKERY_LOCK(mt_cpu_pm_cpc_lock);
|
||||||
|
#define plat_cpu_pm_cpc_lock_init() bakery_lock_init(&mt_cpu_pm_cpc_lock)
|
||||||
|
#define plat_cpu_pm_cpc_lock() bakery_lock_get(&mt_cpu_pm_cpc_lock)
|
||||||
|
#define plat_cpu_pm_cpc_unlock() bakery_lock_release(&mt_cpu_pm_cpc_lock)
|
||||||
|
#else
|
||||||
|
spinlock_t mt_cpu_pm_cpc_lock;
|
||||||
|
#define plat_cpu_pm_cpc_lock_init()
|
||||||
|
#define plat_cpu_pm_cpc_lock() spin_lock(&mt_cpu_pm_cpc_lock)
|
||||||
|
#define plat_cpu_pm_cpc_unlock() spin_unlock(&mt_cpu_pm_cpc_lock)
|
||||||
|
#endif /* MT_CPU_PM_USING_BAKERY_LOCK */
|
||||||
|
|
||||||
|
static void mtk_cpc_record_lat(struct mtk_cpc_lat_data *lat,
|
||||||
|
unsigned int on_ticks, unsigned int off_ticks)
|
||||||
|
{
|
||||||
|
if ((on_ticks == 0) || (off_ticks == 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
__mtk_cpc_record_lat(lat->on_sum, lat->on_min, lat->on_max, on_ticks);
|
||||||
|
lat->on_cnt++;
|
||||||
|
__mtk_cpc_record_lat(lat->off_sum, lat->off_min,
|
||||||
|
lat->off_max, off_ticks);
|
||||||
|
lat->off_cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CPC_CPU_LATENCY_MASK 0xFFFF
|
||||||
|
void mtk_cpu_pm_save_cpc_latency(enum dev_type dev_type)
|
||||||
|
{
|
||||||
|
unsigned int lat = 0, lat_on = 0, lat_off = 0;
|
||||||
|
struct mtk_cpc_lat_data *lat_data = NULL;
|
||||||
|
|
||||||
|
if (mtk_cpc_prof_is_enabled() == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
plat_cpu_pm_cpc_lock();
|
||||||
|
|
||||||
|
if (dev_type < DEV_TYPE_CPUSYS) {
|
||||||
|
lat = mmio_read_32(CPC_CPU_ON_LATENCY(dev_type));
|
||||||
|
lat_on = lat & CPC_CPU_LATENCY_MASK;
|
||||||
|
lat = mmio_read_32(CPC_CPU_OFF_LATENCY(dev_type));
|
||||||
|
lat_off = lat & CPC_CPU_LATENCY_MASK;
|
||||||
|
lat_data = &cpc_dev.cpu[dev_type];
|
||||||
|
} else if (dev_type == DEV_TYPE_CPUSYS) {
|
||||||
|
lat_on = mmio_read_32(CPC_CLUSTER_ON_LATENCY);
|
||||||
|
lat_on = lat_on & CPC_CPU_LATENCY_MASK;
|
||||||
|
lat_off = mmio_read_32(CPC_CLUSTER_OFF_LATENCY);
|
||||||
|
lat_off = lat_off & CPC_CPU_LATENCY_MASK;
|
||||||
|
lat_data = &cpc_dev.cluster;
|
||||||
|
} else if (dev_type == DEV_TYPE_MCUSYS) {
|
||||||
|
lat = mmio_read_32(CPC_MCUSYS_ON_LATENCY);
|
||||||
|
lat_on = lat & CPC_CPU_LATENCY_MASK;
|
||||||
|
lat = mmio_read_32(CPC_MCUSYS_OFF_LATENCY);
|
||||||
|
lat_off = lat & CPC_CPU_LATENCY_MASK;
|
||||||
|
lat_data = &cpc_dev.mcusys;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lat_data)
|
||||||
|
mtk_cpc_record_lat(lat_data, lat_on, lat_off);
|
||||||
|
|
||||||
|
plat_cpu_pm_cpc_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RVBARADDR_ONKEEPON_SEL (MCUCFG_BASE + 0x388)
|
||||||
|
|
||||||
|
void mtk_cpc_init(void)
|
||||||
|
{
|
||||||
|
struct mtk_plat_dev_config cfg = {
|
||||||
|
#ifndef CPU_PM_ACP_FSM
|
||||||
|
.auto_off = 1,
|
||||||
|
#else
|
||||||
|
.auto_off = 0,
|
||||||
|
#endif /* CPU_PM_ACP_FSM */
|
||||||
|
.auto_thres_us = MTK_CPC_AUTO_DORMANT_THR_US,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (mmio_read_32(RVBARADDR_ONKEEPON_SEL) == 0x1) {
|
||||||
|
ERROR("ONKEEPON_SEL=%x, CPC_FLOW_CTRL_CFG=%x\n",
|
||||||
|
mmio_read_32(RVBARADDR_ONKEEPON_SEL),
|
||||||
|
mmio_read_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG));
|
||||||
|
mmio_write_32(RVBARADDR_ONKEEPON_SEL, 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_MTK_SMP_EN
|
||||||
|
mt_smp_init();
|
||||||
|
#endif /* CONFIG_MTK_SMP_EN */
|
||||||
|
|
||||||
|
#if CONFIG_MTK_CPU_SUSPEND_EN
|
||||||
|
mtk_cpu_pm_counter_clear();
|
||||||
|
#endif /* CONFIG_MTK_CPU_SUSPEND_EN */
|
||||||
|
|
||||||
|
mtk_cpc_auto_dormant_en(cfg.auto_off);
|
||||||
|
mtk_cpc_auto_dormant_tick(cfg.auto_thres_us);
|
||||||
|
|
||||||
|
mmio_setbits_32(CPC_MCUSYS_CPC_DBG_SETTING,
|
||||||
|
CPC_DBG_EN | CPC_CALC_EN);
|
||||||
|
|
||||||
|
mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG,
|
||||||
|
CPC_OFF_PRE_EN);
|
||||||
|
|
||||||
|
/* enable CPC */
|
||||||
|
mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, CPC_CTRL_ENABLE);
|
||||||
|
|
||||||
|
plat_cpu_pm_cpc_lock_init();
|
||||||
|
}
|
142
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_cpu_pm_cpc.h
Normal file
142
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_cpu_pm_cpc.h
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_CPU_PM_CPC_H
|
||||||
|
#define MT_CPU_PM_CPC_H
|
||||||
|
|
||||||
|
#include <lib/mmio.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
#include <mcucfg.h>
|
||||||
|
#include <mcupm_cfg.h>
|
||||||
|
|
||||||
|
#define NEED_CPUSYS_PROT_WORKAROUND 1
|
||||||
|
|
||||||
|
/* system sram registers */
|
||||||
|
#define CPUIDLE_SRAM_REG(r) (0x11B000 + (r))
|
||||||
|
|
||||||
|
/* db dump */
|
||||||
|
#define CPC_TRACE_SIZE 0x20
|
||||||
|
#define CPC_TRACE_ID_NUM 13
|
||||||
|
#define CPC_TRACE_SRAM(id) (CPUIDLE_SRAM_REG(0x10) + (id) * CPC_TRACE_SIZE)
|
||||||
|
|
||||||
|
/* backup off count */
|
||||||
|
#define SYSRAM_RECENT_CPU_CNT(i) CPUIDLE_SRAM_REG(4 * (i) + 0x1B0)
|
||||||
|
#define SYSRAM_RECENT_CLUSTER_CNT CPUIDLE_SRAM_REG(0x1D0)
|
||||||
|
#define SYSRAM_RECENT_MCUSYS_CNT CPUIDLE_SRAM_REG(0x1D4)
|
||||||
|
#define SYSRAM_RECENT_CNT_TS_L CPUIDLE_SRAM_REG(0x1D8)
|
||||||
|
#define SYSRAM_RECENT_CNT_TS_H CPUIDLE_SRAM_REG(0x1DC)
|
||||||
|
#define SYSRAM_CPUSYS_CNT CPUIDLE_SRAM_REG(0x1E8)
|
||||||
|
#define SYSRAM_MCUSYS_CNT CPUIDLE_SRAM_REG(0x1EC)
|
||||||
|
#define SYSRAM_CLUSTER_CNT_BACKUP CPUIDLE_SRAM_REG(0x1F0)
|
||||||
|
#define MCUPM_TCM_MCUSYS_COUNTER \
|
||||||
|
(CPU_EB_TCM_CNT_BASE + CPU_EB_MCUSYS_CNT_OFST)
|
||||||
|
|
||||||
|
/* CPC_MCUSYS_CPC_FLOW_CTRL_CFG(0x114): debug setting */
|
||||||
|
#define CPC_PWR_ON_SEQ_DIS BIT(1)
|
||||||
|
#define CPC_PWR_ON_PRIORITY BIT(2)
|
||||||
|
#define CPC_AUTO_OFF_EN BIT(5)
|
||||||
|
#define CPC_DORMANT_WAIT_EN BIT(14)
|
||||||
|
#define CPC_CTRL_EN BIT(16)
|
||||||
|
#define CPC_OFF_PRE_EN BIT(29)
|
||||||
|
|
||||||
|
/* CPC_MCUSYS_LAST_CORE_REQ(0x118) : last core protection */
|
||||||
|
#define CPUSYS_PROT_SET BIT(0)
|
||||||
|
#define MCUSYS_PROT_SET BIT(8)
|
||||||
|
/* CPC_PWR_ON_MASK(0x128) : last core protection */
|
||||||
|
#define CPUSYS_PROT_CLR BIT(8)
|
||||||
|
#define MCUSYS_PROT_CLR BIT(9)
|
||||||
|
|
||||||
|
#define CPC_PROT_RESP_MASK (0x3)
|
||||||
|
/* CPC_CPUSYS_LAST_CORE_RESP(0x11C) : last core protection */
|
||||||
|
#define CPUSYS_RESP_OFS (16)
|
||||||
|
/* CPC_MCUSYS_LAST_CORE_RESP(0x124) : last core protection */
|
||||||
|
#define MCUSYS_RESP_OFS (30)
|
||||||
|
|
||||||
|
#define RETRY_CNT_MAX (1000)
|
||||||
|
|
||||||
|
#define PROT_RETRY (0)
|
||||||
|
#define PROT_SUCCESS (1)
|
||||||
|
#define PROT_GIVEUP (2)
|
||||||
|
|
||||||
|
/* CPC_MCUSYS_CPC_DBG_SETTING(0x200): debug setting */
|
||||||
|
#define CPC_PROF_EN BIT(0)
|
||||||
|
#define CPC_DBG_EN BIT(1)
|
||||||
|
#define CPC_FREEZE BIT(2)
|
||||||
|
#define CPC_CALC_EN BIT(3)
|
||||||
|
|
||||||
|
enum mcusys_cpc_lastcore_prot_status {
|
||||||
|
CPC_SUCCESS = 0,
|
||||||
|
CPC_ERR_FAIL,
|
||||||
|
CPC_ERR_TIMEOUT,
|
||||||
|
NF_CPC_ERR
|
||||||
|
};
|
||||||
|
|
||||||
|
enum mcusys_cpc_smc_events {
|
||||||
|
CPC_SMC_EVENT_DUMP_TRACE_DATA,
|
||||||
|
CPC_SMC_EVENT_GIC_DPG_SET,
|
||||||
|
CPC_SMC_EVENT_CPC_CONFIG,
|
||||||
|
CPC_SMC_EVENT_READ_CONFIG,
|
||||||
|
CPC_SMC_EVENT_PROF_LATENCY,
|
||||||
|
NF_CPC_SMC_EVENT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum mcusys_cpc_smc_config {
|
||||||
|
CPC_SMC_CONFIG_PROF,
|
||||||
|
CPC_SMC_CONFIG_CNT_CLR,
|
||||||
|
CPC_SMC_CONFIG_TIME_SYNC,
|
||||||
|
|
||||||
|
NF_CPC_SMC_CONFIG,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum dev_type {
|
||||||
|
DEV_TYPE_CPU_0 = 0,
|
||||||
|
DEV_TYPE_CPUSYS = PLATFORM_CORE_COUNT,
|
||||||
|
DEV_TYPE_MCUSYS,
|
||||||
|
DEV_TYPE_NUM
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CPC_PROF_ENABLE,
|
||||||
|
CPC_PROF_ENABLED,
|
||||||
|
CPC_PROF_DEV_NUM,
|
||||||
|
CPC_PROF_DEV_NAME,
|
||||||
|
CPC_PROF_OFF_CNT,
|
||||||
|
CPC_PROF_OFF_AVG,
|
||||||
|
CPC_PROF_OFF_MAX,
|
||||||
|
CPC_PROF_OFF_MIN,
|
||||||
|
CPC_PROF_ON_CNT,
|
||||||
|
CPC_PROF_ON_AVG,
|
||||||
|
CPC_PROF_ON_MAX,
|
||||||
|
CPC_PROF_ON_MIN,
|
||||||
|
|
||||||
|
CPC_PROF_NUM
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MTK_CPC_AUTO_DORMANT_THR_US (8000)
|
||||||
|
#define US_TO_TICKS(us) ((us) * 26)
|
||||||
|
#define TICKS_TO_US(tick) ((tick) / 26)
|
||||||
|
|
||||||
|
int mtk_cpu_pm_cluster_prot_aquire(int cluster);
|
||||||
|
void mtk_cpu_pm_cluster_prot_release(int cluster);
|
||||||
|
|
||||||
|
void mtk_cpc_mcusys_off_reflect(void);
|
||||||
|
int mtk_cpc_mcusys_off_prepare(void);
|
||||||
|
|
||||||
|
void mtk_cpc_core_on_hint_set(int cpu);
|
||||||
|
void mtk_cpc_core_on_hint_clr(int cpu);
|
||||||
|
void mtk_cpc_time_sync(void);
|
||||||
|
|
||||||
|
uint64_t mtk_cpc_handler(uint64_t act, uint64_t arg1, uint64_t arg2);
|
||||||
|
uint64_t mtk_cpc_trace_dump(uint64_t act, uint64_t arg1, uint64_t arg2);
|
||||||
|
void mtk_cpu_pm_counter_enable(bool enable);
|
||||||
|
bool mtk_cpu_pm_counter_enabled(void);
|
||||||
|
void mtk_cpu_pm_counter_update(unsigned int cpu);
|
||||||
|
void mtk_cpc_prof_enable(bool enable);
|
||||||
|
bool mtk_cpc_prof_is_enabled(void);
|
||||||
|
void mtk_cpu_pm_save_cpc_latency(enum dev_type dev_type);
|
||||||
|
void mtk_cpc_init(void);
|
||||||
|
|
||||||
|
#endif /* MT_CPU_PM_CPC_H */
|
102
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_cpu_pm_mbox.c
Normal file
102
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_cpu_pm_mbox.c
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <lib/mmio.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
#include <mcupm_cfg.h>
|
||||||
|
#include "mt_cpu_pm_mbox.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define mcdi_likely(x) __builtin_expect(!!(x), 1)
|
||||||
|
#define mcdi_unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
|
#else
|
||||||
|
#define mcdi_likely(x) (x)
|
||||||
|
#define mcdi_unlikely(x) (x)
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
|
#define MCUPM_MBOX_3_BASE (CPU_EB_TCM_BASE + CPU_EB_MBOX3_OFFSET)
|
||||||
|
|
||||||
|
#define _mcupm_mbox_write(id, val) \
|
||||||
|
mmio_write_32(MCUPM_MBOX_3_BASE + 4 * (id), val)
|
||||||
|
#define _mcupm_mbox_read(id) \
|
||||||
|
mmio_read_32(MCUPM_MBOX_3_BASE + 4 * (id))
|
||||||
|
|
||||||
|
void mtk_set_mcupm_pll_mode(unsigned int mode)
|
||||||
|
{
|
||||||
|
if (mode < NF_MCUPM_ARMPLL_MODE)
|
||||||
|
_mcupm_mbox_write(MCUPM_MBOX_ARMPLL_MODE, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mtk_get_mcupm_pll_mode(void)
|
||||||
|
{
|
||||||
|
return _mcupm_mbox_read(MCUPM_MBOX_ARMPLL_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mtk_set_mcupm_buck_mode(unsigned int mode)
|
||||||
|
{
|
||||||
|
if (mode < NF_MCUPM_BUCK_MODE)
|
||||||
|
_mcupm_mbox_write(MCUPM_MBOX_BUCK_MODE, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mtk_get_mcupm_buck_mode(void)
|
||||||
|
{
|
||||||
|
return _mcupm_mbox_read(MCUPM_MBOX_BUCK_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mtk_set_cpu_pm_preffered_cpu(unsigned int cpuid)
|
||||||
|
{
|
||||||
|
return _mcupm_mbox_write(MCUPM_MBOX_WAKEUP_CPU, cpuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int mtk_get_cpu_pm_preffered_cpu(void)
|
||||||
|
{
|
||||||
|
return _mcupm_mbox_read(MCUPM_MBOX_WAKEUP_CPU);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mtk_wait_mbox_init_done(void)
|
||||||
|
{
|
||||||
|
int sta = _mcupm_mbox_read(MCUPM_MBOX_TASK_STA);
|
||||||
|
|
||||||
|
if (sta != MCUPM_TASK_INIT)
|
||||||
|
return sta;
|
||||||
|
|
||||||
|
mtk_set_mcupm_pll_mode(MCUPM_ARMPLL_OFF);
|
||||||
|
mtk_set_mcupm_buck_mode(MCUPM_BUCK_OFF_MODE);
|
||||||
|
|
||||||
|
_mcupm_mbox_write(MCUPM_MBOX_PWR_CTRL_EN,
|
||||||
|
MCUPM_MCUSYS_CTRL |
|
||||||
|
MCUPM_CM_CTRL |
|
||||||
|
MCUPM_BUCK_CTRL |
|
||||||
|
MCUPM_ARMPLL_CTRL);
|
||||||
|
|
||||||
|
return sta;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mtk_lp_depd_condition(enum cpupm_mbox_depd_type type)
|
||||||
|
{
|
||||||
|
int ret = 0, status = 0;
|
||||||
|
|
||||||
|
if (type == CPUPM_MBOX_WAIT_DEV_INIT) {
|
||||||
|
status = mtk_wait_mbox_init_done();
|
||||||
|
if (mcdi_unlikely(status != MCUPM_TASK_INIT))
|
||||||
|
ret = -ENXIO;
|
||||||
|
else
|
||||||
|
_mcupm_mbox_write(MCUPM_MBOX_AP_READY, 1);
|
||||||
|
} else if (type == CPUPM_MBOX_WAIT_TASK_READY) {
|
||||||
|
status = _mcupm_mbox_read(MCUPM_MBOX_TASK_STA);
|
||||||
|
if (mcdi_unlikely((status != MCUPM_TASK_WAIT) &&
|
||||||
|
(status != MCUPM_TASK_INIT_FINISH)))
|
||||||
|
ret = -ENXIO;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mtk_set_mcupm_group_hint(unsigned int gmask)
|
||||||
|
{
|
||||||
|
_mcupm_mbox_write(MCUPM_MBOX_GROUP, gmask);
|
||||||
|
}
|
69
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_cpu_pm_mbox.h
Normal file
69
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_cpu_pm_mbox.h
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_CPU_PM_MBOX_H
|
||||||
|
#define MT_CPU_PM_MBOX_H
|
||||||
|
|
||||||
|
#define MCUPM_MBOX_AP_READY 0
|
||||||
|
#define MCUPM_MBOX_GROUP 1
|
||||||
|
#define MCUPM_MBOX_RESERVED_2 2
|
||||||
|
#define MCUPM_MBOX_RESERVED_3 3
|
||||||
|
#define MCUPM_MBOX_PWR_CTRL_EN 4
|
||||||
|
#define MCUPM_MBOX_L3_CACHE_MODE 5
|
||||||
|
#define MCUPM_MBOX_BUCK_MODE 6
|
||||||
|
#define MCUPM_MBOX_ARMPLL_MODE 7
|
||||||
|
|
||||||
|
#define MCUPM_MBOX_TASK_STA 8
|
||||||
|
#define MCUPM_MBOX_RESERVED_9 9
|
||||||
|
#define MCUPM_MBOX_RESERVED_10 10
|
||||||
|
#define MCUPM_MBOX_RESERVED_11 11
|
||||||
|
#define MCUPM_MBOX_WAKEUP_CPU 12
|
||||||
|
|
||||||
|
#define MCUPM_MCUSYS_CTRL BIT(0)
|
||||||
|
#define MCUPM_BUCK_CTRL BIT(1)
|
||||||
|
#define MCUPM_ARMPLL_CTRL BIT(2)
|
||||||
|
#define MCUPM_CM_CTRL BIT(3)
|
||||||
|
|
||||||
|
#define MCUPM_L3_OFF_MODE 0
|
||||||
|
#define MCUPM_L3_DORMANT_MODE 1
|
||||||
|
#define NF_MCUPM_L3_MODE 2U
|
||||||
|
|
||||||
|
#define MCUPM_BUCK_NORMAL_MODE 0
|
||||||
|
#define MCUPM_BUCK_LP_MODE 1
|
||||||
|
#define MCUPM_BUCK_OFF_MODE 2
|
||||||
|
#define NF_MCUPM_BUCK_MODE 3U
|
||||||
|
|
||||||
|
#define MCUPM_ARMPLL_ON 0
|
||||||
|
#define MCUPM_ARMPLL_GATING 1
|
||||||
|
#define MCUPM_ARMPLL_OFF 2
|
||||||
|
#define NF_MCUPM_ARMPLL_MODE 3U
|
||||||
|
|
||||||
|
#define MCUPM_TASK_UNINIT 0
|
||||||
|
#define MCUPM_TASK_INIT 1
|
||||||
|
#define MCUPM_TASK_INIT_FINISH 2
|
||||||
|
#define MCUPM_TASK_WAIT 3
|
||||||
|
#define MCUPM_TASK_RUN 4
|
||||||
|
#define MCUPM_TASK_PAUSE 5
|
||||||
|
|
||||||
|
void mtk_set_mcupm_pll_mode(unsigned int mode);
|
||||||
|
int mtk_get_mcupm_pll_mode(void);
|
||||||
|
|
||||||
|
void mtk_set_mcupm_buck_mode(unsigned int mode);
|
||||||
|
int mtk_get_mcupm_buck_mode(void);
|
||||||
|
|
||||||
|
void mtk_set_cpu_pm_preffered_cpu(unsigned int cpuid);
|
||||||
|
unsigned int mtk_get_cpu_pm_preffered_cpu(void);
|
||||||
|
|
||||||
|
void mtk_set_mcupm_group_hint(unsigned int gmask);
|
||||||
|
|
||||||
|
enum cpupm_mbox_depd_type {
|
||||||
|
CPUPM_MBOX_WAIT_DEV_INIT,
|
||||||
|
CPUPM_MBOX_WAIT_TASK_READY,
|
||||||
|
};
|
||||||
|
|
||||||
|
int mtk_lp_depd_condition(enum cpupm_mbox_depd_type type);
|
||||||
|
|
||||||
|
#endif /* MT_CPU_PM_MBOX_H */
|
187
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_cpu_pm_smc.c
Normal file
187
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_cpu_pm_smc.c
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <lib/spinlock.h>
|
||||||
|
|
||||||
|
#include "mt_cpu_pm.h"
|
||||||
|
#include "mt_cpu_pm_cpc.h"
|
||||||
|
#include "mt_cpu_pm_smc.h"
|
||||||
|
#include "mt_lp_irqremain.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The locker must use the bakery locker when cache turn off.
|
||||||
|
* Using spin_lock will has better performance.
|
||||||
|
*/
|
||||||
|
#ifdef MT_CPU_PM_USING_BAKERY_LOCK
|
||||||
|
DEFINE_BAKERY_LOCK(mt_cpu_pm_smc_lock);
|
||||||
|
#define plat_cpu_pm_smc_lock_init() bakery_lock_init(&mt_cpu_pm_smc_lock)
|
||||||
|
#define plat_cpu_pm_smc_lock() bakery_lock_get(&mt_cpu_pm_smc_lock)
|
||||||
|
#define plat_cpu_pm_smc_unlock() bakery_lock_release(&mt_cpu_pm_smc_lock)
|
||||||
|
#else
|
||||||
|
spinlock_t mt_cpu_pm_smc_lock;
|
||||||
|
#define plat_cpu_pm_smc_lock_init()
|
||||||
|
#define plat_cpu_pm_smc_lock() spin_lock(&mt_cpu_pm_smc_lock)
|
||||||
|
#define plat_cpu_pm_smc_unlock() spin_unlock(&mt_cpu_pm_smc_lock)
|
||||||
|
#endif /* MT_CPU_PM_USING_BAKERY_LOCK */
|
||||||
|
|
||||||
|
static uint64_t cpupm_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 res = 0;
|
||||||
|
|
||||||
|
switch (lp_id) {
|
||||||
|
case CPC_COMMAND:
|
||||||
|
res = mtk_cpc_handler(act, arg1, arg2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t cpupm_lp_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 res = 0;
|
||||||
|
#ifdef CPU_PM_IRQ_REMAIN_ENABLE
|
||||||
|
int ret;
|
||||||
|
#endif
|
||||||
|
switch (lp_id) {
|
||||||
|
case LP_CPC_COMMAND:
|
||||||
|
res = mtk_cpc_handler(act, arg1, arg2);
|
||||||
|
break;
|
||||||
|
#ifdef CPU_PM_IRQ_REMAIN_ENABLE
|
||||||
|
case IRQS_REMAIN_ALLOC:
|
||||||
|
if (act & MT_LPM_SMC_ACT_GET)
|
||||||
|
res = (uint64_t)mt_lp_irqremain_count();
|
||||||
|
break;
|
||||||
|
case IRQS_REMAIN_CTRL:
|
||||||
|
plat_cpu_pm_smc_lock();
|
||||||
|
if (act & MT_LPM_SMC_ACT_SUBMIT)
|
||||||
|
ret = mt_lp_irqremain_submit();
|
||||||
|
else if (act & MT_LPM_SMC_ACT_PUSH) {
|
||||||
|
ret = mt_lp_irqremain_push();
|
||||||
|
if (ret)
|
||||||
|
INFO("Irqs remain push fail\n");
|
||||||
|
} else
|
||||||
|
INFO("Irqs remain control not support! (0x%lx)\n", act);
|
||||||
|
plat_cpu_pm_smc_unlock();
|
||||||
|
break;
|
||||||
|
case IRQS_REMAIN_IRQ:
|
||||||
|
case IRQS_REMAIN_WAKEUP_CAT:
|
||||||
|
case IRQS_REMAIN_WAKEUP_SRC:
|
||||||
|
plat_cpu_pm_smc_lock();
|
||||||
|
if (act & MT_LPM_SMC_ACT_SET) {
|
||||||
|
const struct mt_lp_irqinfo info = {
|
||||||
|
.val = (unsigned int)arg1,
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = mt_lp_irqremain_set((unsigned int)lp_id, &info);
|
||||||
|
if (ret)
|
||||||
|
INFO("Irqs remain command: %lu, set fail\n",
|
||||||
|
lp_id);
|
||||||
|
} else if (act & MT_LPM_SMC_ACT_GET) {
|
||||||
|
struct mt_lp_irqinfo info;
|
||||||
|
|
||||||
|
ret = mt_lp_irqremain_get((unsigned int)arg1,
|
||||||
|
(unsigned int)lp_id, &info);
|
||||||
|
if (ret) {
|
||||||
|
INFO("Irqs remain command: %lu, get fail\n",
|
||||||
|
lp_id);
|
||||||
|
res = 0;
|
||||||
|
} else
|
||||||
|
res = (uint64_t)info.val;
|
||||||
|
} else
|
||||||
|
INFO("Irqs remain command not support! (0x%lx)\n", act);
|
||||||
|
plat_cpu_pm_smc_unlock();
|
||||||
|
break;
|
||||||
|
#ifdef CPU_PM_SUSPEND_NOTIFY
|
||||||
|
case SUSPEND_SRC:
|
||||||
|
ret = cpupm_set_suspend_state((unsigned int)act,
|
||||||
|
(unsigned int)arg1);
|
||||||
|
if (ret)
|
||||||
|
INFO("cpu_pm lp command: %lu, set fail\n", lp_id);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case CPU_PM_COUNTER_CTRL:
|
||||||
|
if (act & MT_LPM_SMC_ACT_SET)
|
||||||
|
mtk_cpu_pm_counter_enable((bool)arg1);
|
||||||
|
else if (act & MT_LPM_SMC_ACT_GET)
|
||||||
|
res = (uint64_t)mtk_cpu_pm_counter_enabled();
|
||||||
|
break;
|
||||||
|
case CPU_PM_RECORD_CTRL:
|
||||||
|
if (act & MT_LPM_SMC_ACT_GET) {
|
||||||
|
if (arg1 == 0)
|
||||||
|
res = mtk_mcusys_off_record_cnt_get();
|
||||||
|
else if (arg1 == 1)
|
||||||
|
res = mtk_mcusys_off_record_name_get();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#if CONFIG_MTK_PM_SUPPORT && CONFIG_MTK_CPU_SUSPEND_EN
|
||||||
|
case SUSPEND_ABORT_REASON:
|
||||||
|
if (act & MT_LPM_SMC_ACT_GET)
|
||||||
|
res = mtk_suspend_abort_reason_get();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_MTK_CPU_ILDO
|
||||||
|
case CPU_PM_RET_CTRL:
|
||||||
|
if (act & MT_LPM_SMC_ACT_SET)
|
||||||
|
res = cpupm_cpu_retention_control((unsigned int) arg1);
|
||||||
|
else if (act & MT_LPM_SMC_ACT_GET)
|
||||||
|
res = cpupu_get_cpu_retention_control();
|
||||||
|
else if (act & MT_LPM_SMC_ACT_COMPAT)
|
||||||
|
res = CPU_PM_CPU_RET_IS_ENABLED;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t secure_cpupm_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 res = 0;
|
||||||
|
|
||||||
|
switch (lp_id) {
|
||||||
|
case CPC_COMMAND:
|
||||||
|
res = mtk_cpc_trace_dump(act, arg1, arg2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cpupm_smc_init(void)
|
||||||
|
{
|
||||||
|
plat_cpu_pm_smc_lock_init();
|
||||||
|
mt_lpm_dispatcher_registry(MT_LPM_SMC_USER_CPU_PM,
|
||||||
|
cpupm_dispatcher);
|
||||||
|
|
||||||
|
mt_lpm_dispatcher_registry(MT_LPM_SMC_USER_CPU_PM_LP,
|
||||||
|
cpupm_lp_dispatcher);
|
||||||
|
|
||||||
|
mt_secure_lpm_dispatcher_registry(MT_LPM_SMC_USER_SECURE_CPU_PM,
|
||||||
|
secure_cpupm_dispatcher);
|
||||||
|
}
|
16
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_cpu_pm_smc.h
Normal file
16
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_cpu_pm_smc.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_CPU_PM_SMC_H
|
||||||
|
#define MT_CPU_PM_SMC_H
|
||||||
|
|
||||||
|
#include <lpm/mt_lp_rm.h>
|
||||||
|
#include <lpm/mt_lpm_dispatch.h>
|
||||||
|
#include <lpm/mt_lpm_smc.h>
|
||||||
|
|
||||||
|
void cpupm_smc_init(void);
|
||||||
|
|
||||||
|
#endif /* MT_CPU_PM_SMC_H */
|
119
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_lp_irqremain.c
Normal file
119
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_lp_irqremain.c
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <drivers/cirq.h>
|
||||||
|
|
||||||
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
#include <lib/pm/mtk_pm.h>
|
||||||
|
#include <lpm/mt_lp_rm.h>
|
||||||
|
#include "mt_cpu_pm.h"
|
||||||
|
#include "mt_lp_irqremain.h"
|
||||||
|
|
||||||
|
static struct mt_irqremain remain_irqs;
|
||||||
|
static struct mt_irqremain *p_irqs;
|
||||||
|
|
||||||
|
int mt_lp_irqremain_push(void)
|
||||||
|
{
|
||||||
|
if (remain_irqs.count >= MT_IRQ_REMAIN_MAX)
|
||||||
|
return -1;
|
||||||
|
remain_irqs.count += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_lp_irqremain_pop(void)
|
||||||
|
{
|
||||||
|
if (remain_irqs.count == 0)
|
||||||
|
return -1;
|
||||||
|
remain_irqs.count -= 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_lp_irqremain_set(unsigned int type,
|
||||||
|
const struct mt_lp_irqinfo *info)
|
||||||
|
{
|
||||||
|
unsigned int idx;
|
||||||
|
|
||||||
|
if (p_irqs || !info)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
idx = remain_irqs.count;
|
||||||
|
switch (type) {
|
||||||
|
case IRQS_REMAIN_IRQ:
|
||||||
|
remain_irqs.irqs[idx] = info->val;
|
||||||
|
break;
|
||||||
|
case IRQS_REMAIN_WAKEUP_CAT:
|
||||||
|
remain_irqs.wakeupsrc_cat[idx] = info->val;
|
||||||
|
break;
|
||||||
|
case IRQS_REMAIN_WAKEUP_SRC:
|
||||||
|
remain_irqs.wakeupsrc[idx] = info->val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_lp_irqremain_get(unsigned int idx, unsigned int type,
|
||||||
|
struct mt_lp_irqinfo *info)
|
||||||
|
{
|
||||||
|
if (!p_irqs || !info || (idx > remain_irqs.count))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case IRQS_REMAIN_IRQ:
|
||||||
|
info->val = remain_irqs.irqs[idx];
|
||||||
|
break;
|
||||||
|
case IRQS_REMAIN_WAKEUP_CAT:
|
||||||
|
info->val = remain_irqs.wakeupsrc_cat[idx];
|
||||||
|
break;
|
||||||
|
case IRQS_REMAIN_WAKEUP_SRC:
|
||||||
|
info->val = remain_irqs.wakeupsrc[idx];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int mt_lp_irqremain_count(void)
|
||||||
|
{
|
||||||
|
return remain_irqs.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_lp_irqremain_submit(void)
|
||||||
|
{
|
||||||
|
if (remain_irqs.count == 0)
|
||||||
|
return -1;
|
||||||
|
set_wakeup_sources(remain_irqs.irqs, remain_irqs.count);
|
||||||
|
mt_lp_rm_do_update(-1, PLAT_RC_UPDATE_REMAIN_IRQS, &remain_irqs);
|
||||||
|
p_irqs = &remain_irqs;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_lp_irqremain_aquire(void)
|
||||||
|
{
|
||||||
|
if (!p_irqs)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
mt_cirq_sw_reset();
|
||||||
|
mt_cirq_clone_gic();
|
||||||
|
mt_cirq_enable();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_lp_irqremain_release(void)
|
||||||
|
{
|
||||||
|
if (!p_irqs)
|
||||||
|
return -1;
|
||||||
|
mt_cirq_flush();
|
||||||
|
mt_cirq_disable();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt_lp_irqremain_init(void)
|
||||||
|
{
|
||||||
|
p_irqs = NULL;
|
||||||
|
}
|
32
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_lp_irqremain.h
Normal file
32
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_lp_irqremain.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_LP_IRQREMAIN_H
|
||||||
|
#define MT_LP_IRQREMAIN_H
|
||||||
|
|
||||||
|
struct mt_lp_irqinfo {
|
||||||
|
unsigned int val;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum mt_lp_irqremain_type {
|
||||||
|
MT_LP_IRQREMAIN_IRQ,
|
||||||
|
MT_LP_IRQREMAIN_WAKEUP_CAT,
|
||||||
|
MT_LP_IRQREMAIN_WAKEUP_SRC,
|
||||||
|
};
|
||||||
|
|
||||||
|
int mt_lp_irqremain_set(unsigned int type,
|
||||||
|
const struct mt_lp_irqinfo *value);
|
||||||
|
int mt_lp_irqremain_get(unsigned int idx, unsigned int type,
|
||||||
|
struct mt_lp_irqinfo *value);
|
||||||
|
unsigned int mt_lp_irqremain_count(void);
|
||||||
|
int mt_lp_irqremain_push(void);
|
||||||
|
int mt_lp_irqremain_pop(void);
|
||||||
|
int mt_lp_irqremain_submit(void);
|
||||||
|
int mt_lp_irqremain_aquire(void);
|
||||||
|
int mt_lp_irqremain_release(void);
|
||||||
|
void mt_lp_irqremain_init(void);
|
||||||
|
|
||||||
|
#endif /* MT_LP_IRQREMAIN_H */
|
94
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_ppu.c
Normal file
94
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_ppu.c
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mt_ppu.h"
|
||||||
|
|
||||||
|
#define MTK_PPU_PWR_DYNAMIC_POLICY_SET(_ctrl, _policy) \
|
||||||
|
mmio_clrsetbits_32(_ctrl->ppu_pwpr, \
|
||||||
|
PPU_PWPR_MASK, \
|
||||||
|
PPU_PWPR_DYNAMIC_MODE | ((_policy) & PPU_PWPR_MASK))
|
||||||
|
|
||||||
|
#define MTK_PPU_PWR_STATIC_POLICY_SET(_ctrl, _policy) \
|
||||||
|
mmio_clrsetbits_32(_ctrl->ppu_pwpr, \
|
||||||
|
PPU_PWPR_MASK | PPU_PWPR_DYNAMIC_MODE, \
|
||||||
|
((_policy) & PPU_PWPR_MASK))
|
||||||
|
|
||||||
|
void mt_smp_ppu_pwr_dynamic_set(struct ppu_pwr_ctrl *ctrl,
|
||||||
|
unsigned int policy)
|
||||||
|
{
|
||||||
|
CPU_PM_ASSERT(ctrl);
|
||||||
|
MTK_PPU_PWR_DYNAMIC_POLICY_SET(ctrl, policy);
|
||||||
|
dmbsy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt_smp_ppu_pwr_static_set(struct ppu_pwr_ctrl *ctrl,
|
||||||
|
unsigned int policy)
|
||||||
|
{
|
||||||
|
CPU_PM_ASSERT(ctrl);
|
||||||
|
MTK_PPU_PWR_STATIC_POLICY_SET(ctrl, policy);
|
||||||
|
dmbsy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt_smp_ppu_pwr_set(struct ppu_pwr_ctrl *ctrl,
|
||||||
|
unsigned int mode,
|
||||||
|
unsigned int policy)
|
||||||
|
{
|
||||||
|
CPU_PM_ASSERT(ctrl);
|
||||||
|
if (mode & PPU_PWPR_DYNAMIC_MODE)
|
||||||
|
MTK_PPU_PWR_DYNAMIC_POLICY_SET(ctrl, policy);
|
||||||
|
else
|
||||||
|
MTK_PPU_PWR_STATIC_POLICY_SET(ctrl, policy);
|
||||||
|
mmio_write_32(ctrl->ppu_dcdr0, MT_PPU_DCDR0);
|
||||||
|
mmio_write_32(ctrl->ppu_dcdr1, MT_PPU_DCDR1);
|
||||||
|
dsbsy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt_smp_ppu_op_set(struct ppu_pwr_ctrl *ctrl,
|
||||||
|
unsigned int mode,
|
||||||
|
unsigned int policy)
|
||||||
|
{
|
||||||
|
unsigned int val;
|
||||||
|
|
||||||
|
CPU_PM_ASSERT(ctrl);
|
||||||
|
|
||||||
|
val = mmio_read_32(ctrl->ppu_pwpr);
|
||||||
|
val &= ~(PPU_PWPR_OP_MASK | PPU_PWPR_OP_DYNAMIC_MODE);
|
||||||
|
|
||||||
|
val |= PPU_PWPR_OP_MODE(policy);
|
||||||
|
if (mode & PPU_PWPR_OP_DYNAMIC_MODE)
|
||||||
|
val |= PPU_PWPR_OP_DYNAMIC_MODE;
|
||||||
|
|
||||||
|
mmio_write_32(ctrl->ppu_pwpr, val);
|
||||||
|
dsbsy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt_smp_ppu_set(struct ppu_pwr_ctrl *ctrl,
|
||||||
|
unsigned int op_mode,
|
||||||
|
unsigned int policy,
|
||||||
|
unsigned int pwr_mode,
|
||||||
|
unsigned int pwr_policy)
|
||||||
|
{
|
||||||
|
unsigned int val;
|
||||||
|
|
||||||
|
CPU_PM_ASSERT(ctrl);
|
||||||
|
val = mmio_read_32(ctrl->ppu_pwpr);
|
||||||
|
|
||||||
|
if (op_mode & PPU_PWPR_OP_DYNAMIC_MODE)
|
||||||
|
val |= (PPU_PWPR_OP_DYNAMIC_MODE |
|
||||||
|
PPU_PWPR_OP_MODE(policy));
|
||||||
|
else
|
||||||
|
val |= PPU_PWPR_OP_MODE(policy);
|
||||||
|
|
||||||
|
if (pwr_mode & PPU_PWPR_DYNAMIC_MODE) {
|
||||||
|
val &= ~(PPU_PWPR_MASK);
|
||||||
|
val |= (PPU_PWPR_DYNAMIC_MODE | (pwr_policy & PPU_PWPR_MASK));
|
||||||
|
} else {
|
||||||
|
val &= ~(PPU_PWPR_MASK | PPU_PWPR_DYNAMIC_MODE);
|
||||||
|
val |= (pwr_policy & PPU_PWPR_MASK);
|
||||||
|
}
|
||||||
|
mmio_write_32(ctrl->ppu_pwpr, val);
|
||||||
|
dsbsy();
|
||||||
|
}
|
68
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_ppu.h
Normal file
68
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_ppu.h
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_PPU_H
|
||||||
|
#define MT_PPU_H
|
||||||
|
|
||||||
|
#include <lib/mmio.h>
|
||||||
|
#include "mt_cpu_pm.h"
|
||||||
|
|
||||||
|
/* PPU PWPR definition */
|
||||||
|
#define PPU_PWPR_MASK 0xF
|
||||||
|
#define PPU_PWPR_MODE_MASK 0x1
|
||||||
|
#define PPU_PWPR_OFF 0
|
||||||
|
#define PPU_PWPR_MEM_RET 2
|
||||||
|
#define PPU_PWPR_FULL_RET 5
|
||||||
|
#define PPU_PWPR_MEM_OFF 6
|
||||||
|
#define PPU_PWPR_FUN_RET 7
|
||||||
|
#define PPU_PWPR_ON 8
|
||||||
|
#define PPU_PWPR_WARM_RESET 10
|
||||||
|
#define PPU_PWPR_DYNAMIC_MODE BIT(8)
|
||||||
|
|
||||||
|
#define PPU_PWPR_OP_MASK 0xF0000
|
||||||
|
#define PPU_PWPR_OP_DYNAMIC_MODE BIT(24)
|
||||||
|
#define PPU_PWPR_OP_MODE(_policy) (((_policy) << 16) & PPU_PWPR_OP_MASK)
|
||||||
|
#define PPU_PWPR_OP_ONE_SLICE_SF_ONLY 0
|
||||||
|
#define PPU_PWPR_OP_ONE_SLICE_HALF_DRAM 1
|
||||||
|
#define PPU_PWPR_OP_ONE_SLICE_FULL_DRAM 3
|
||||||
|
#define PPU_PWPR_OP_ALL_SLICE_SF_ONLY 4
|
||||||
|
#define PPU_PWPR_OP_ALL_SLICE_HALF_DRAM 5
|
||||||
|
#define PPU_PWPR_OP_ALL_SLICE_FULL_DRAM 7
|
||||||
|
|
||||||
|
#define DSU_PPU_PWPR_OP_MODE_DEF (PPU_PWPR_OP_ONE_SLICE_HALF_DRAM)
|
||||||
|
|
||||||
|
/* PPU PWSR definition */
|
||||||
|
#define PPU_PWSR_STATE_ON BIT(3)
|
||||||
|
|
||||||
|
#ifdef CPU_PM_ACP_FSM
|
||||||
|
#define PPU_PWSR_OP_STATUS 0x30000
|
||||||
|
#define PPU_OP_ST_SF_ONLY 0x0
|
||||||
|
#endif /* CPU_PM_ACP_FSM */
|
||||||
|
|
||||||
|
#define MT_PPU_DCDR0 0x00606060
|
||||||
|
#define MT_PPU_DCDR1 0x00006060
|
||||||
|
|
||||||
|
void mt_smp_ppu_pwr_set(struct ppu_pwr_ctrl *ctrl,
|
||||||
|
unsigned int mode,
|
||||||
|
unsigned int policy);
|
||||||
|
|
||||||
|
void mt_smp_ppu_op_set(struct ppu_pwr_ctrl *ctrl,
|
||||||
|
unsigned int mode,
|
||||||
|
unsigned int policy);
|
||||||
|
|
||||||
|
void mt_smp_ppu_pwr_dynamic_set(struct ppu_pwr_ctrl *ctrl,
|
||||||
|
unsigned int policy);
|
||||||
|
|
||||||
|
void mt_smp_ppu_pwr_static_set(struct ppu_pwr_ctrl *ctrl,
|
||||||
|
unsigned int policy);
|
||||||
|
|
||||||
|
void mt_smp_ppu_set(struct ppu_pwr_ctrl *ctrl,
|
||||||
|
unsigned int op_mode,
|
||||||
|
unsigned int policy,
|
||||||
|
unsigned int pwr_mode,
|
||||||
|
unsigned int pwr_policy);
|
||||||
|
|
||||||
|
#endif /* MT_PPU_H */
|
108
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_smp.c
Normal file
108
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_smp.c
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <arch_helpers.h>
|
||||||
|
#include <common/debug.h>
|
||||||
|
#include <drivers/delay_timer.h>
|
||||||
|
#include <plat/common/platform.h>
|
||||||
|
|
||||||
|
#include <lib/pm/mtk_pm.h>
|
||||||
|
#include <mcucfg.h>
|
||||||
|
#include "mt_cpu_pm.h"
|
||||||
|
#include "mt_ppu.h"
|
||||||
|
#include "mt_smp.h"
|
||||||
|
|
||||||
|
#define is_core_power_status_on(_pwr_ctrl)\
|
||||||
|
(!!((mmio_read_32(_pwr_ctrl->pwr.ppu_pwsr)) & (PPU_PWSR_STATE_ON)))
|
||||||
|
|
||||||
|
#ifndef CPU_PM_CORE_ARCH64_ONLY
|
||||||
|
void mt_smp_core_init_arch(int cluster,
|
||||||
|
int cpu,
|
||||||
|
int arm64,
|
||||||
|
struct cpu_pwr_ctrl *pwr_ctrl)
|
||||||
|
{
|
||||||
|
CPU_PM_ASSERT(cluster == 0);
|
||||||
|
CPU_PM_ASSERT(pwr_ctrl);
|
||||||
|
|
||||||
|
/* aa64naa32 in bits[16:23] */
|
||||||
|
if (arm64)
|
||||||
|
mmio_setbits_32(pwr_ctrl->arch_addr,
|
||||||
|
BIT(AA64NAA32_FLAG_START_BIT + cpu));
|
||||||
|
else
|
||||||
|
mmio_clrbits_32(pwr_ctrl->arch_addr,
|
||||||
|
BIT(AA64NAA32_FLAG_START_BIT + cpu));
|
||||||
|
}
|
||||||
|
#endif /* CPU_PM_CORE_ARCH64_ONLY */
|
||||||
|
|
||||||
|
void mt_smp_core_bootup_address_set(int cluster,
|
||||||
|
int cpu,
|
||||||
|
struct cpu_pwr_ctrl *pwr_ctrl,
|
||||||
|
uintptr_t entry)
|
||||||
|
{
|
||||||
|
CPU_PM_ASSERT(pwr_ctrl);
|
||||||
|
|
||||||
|
/* Set bootup address */
|
||||||
|
mmio_write_32(pwr_ctrl->rvbaraddr_l, entry);
|
||||||
|
mmio_write_32(pwr_ctrl->rvbaraddr_h, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_smp_power_core_on(unsigned int cpu_id, struct cpu_pwr_ctrl *pwr_ctrl)
|
||||||
|
{
|
||||||
|
unsigned int val = 0;
|
||||||
|
|
||||||
|
CPU_PM_ASSERT(pwr_ctrl);
|
||||||
|
|
||||||
|
mt_smp_ppu_pwr_set(&pwr_ctrl->pwr, PPU_PWPR_DYNAMIC_MODE, PPU_PWPR_OFF);
|
||||||
|
val = is_core_power_status_on(pwr_ctrl);
|
||||||
|
if (!val) {
|
||||||
|
mmio_clrbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG,
|
||||||
|
GIC_WAKEUP_IGNORE(cpu_id));
|
||||||
|
mmio_setbits_32(SPM_EXT_INT_WAKEUP_REQ_SET, BIT(cpu_id));
|
||||||
|
|
||||||
|
mmio_clrbits_32(SPMC_CONTROL_CONFIG,
|
||||||
|
SPMC_CPU_RESET_PWRON_CONFIG << (cpu_id));
|
||||||
|
dsbsy();
|
||||||
|
isb();
|
||||||
|
|
||||||
|
while (!is_core_power_status_on(pwr_ctrl))
|
||||||
|
DO_SMP_CORE_ON_WAIT_TIMEOUT(cpu_id, val);
|
||||||
|
mmio_setbits_32(SPM_EXT_INT_WAKEUP_REQ_CLR, BIT(cpu_id));
|
||||||
|
} else {
|
||||||
|
mmio_clrbits_32(SPMC_CONTROL_CONFIG,
|
||||||
|
SPMC_CPU_RESET_PWRON_CONFIG << (cpu_id));
|
||||||
|
INFO("[%s:%d] - core_%u have been power on\n",
|
||||||
|
__func__, __LINE__, cpu_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MTK_CPUPM_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_smp_power_core_off(unsigned int cpu_id, struct cpu_pwr_ctrl *pwr_ctrl)
|
||||||
|
{
|
||||||
|
mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG,
|
||||||
|
GIC_WAKEUP_IGNORE(cpu_id));
|
||||||
|
return MTK_CPUPM_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt_smp_init(void)
|
||||||
|
{
|
||||||
|
mmio_write_32(SPM_POWERON_CONFIG_EN, PROJECT_CODE | BCLK_CG_EN);
|
||||||
|
|
||||||
|
/* INFO=SPMC_INIT: clear resetpwron of mcusys/cluster/core0 */
|
||||||
|
mmio_clrbits_32(SPMC_CONTROL_CONFIG, SPMC_MCUSYS_RESET_PWRON_CONFIG);
|
||||||
|
mmio_clrbits_32(SPMC_CONTROL_CONFIG, SPMC_CPUTOP_RESET_PWRON_CONFIG);
|
||||||
|
|
||||||
|
/* Switch DSU ISO/CKDIS control from PCSM to PPU */
|
||||||
|
mmio_setbits_32(CPC_FCM_SPMC_SW_CFG2,
|
||||||
|
(CPUSYS_PPU_CLK_EN_CTRL | CPUSYS_PPU_ISO_CTRL));
|
||||||
|
|
||||||
|
#ifdef SPM_CPU_BUCK_ISO_CON
|
||||||
|
/* Make sure that buck iso have been released before power on */
|
||||||
|
mmio_write_32(SPM_CPU_BUCK_ISO_CON, SPM_CPU_BUCK_ISO_DEFAUT);
|
||||||
|
#endif /* SPM_CPU_BUCK_ISO_CON */
|
||||||
|
}
|
48
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_smp.h
Normal file
48
plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_smp.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_SMP_H
|
||||||
|
#define MT_SMP_H
|
||||||
|
|
||||||
|
#include <lib/mmio.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
#include "mt_cpu_pm.h"
|
||||||
|
|
||||||
|
#define CPUSYS_PPU_CLK_EN_CTRL BIT(12)
|
||||||
|
#define CPUSYS_PPU_ISO_CTRL BIT(13)
|
||||||
|
#define AA64NAA32_FLAG_START_BIT 16
|
||||||
|
|
||||||
|
#define SMP_CORE_TIMEOUT_MAX (50000)
|
||||||
|
#define DO_SMP_CORE_ON_WAIT_TIMEOUT(cpu_id, k_cnt) ({ \
|
||||||
|
if (k_cnt >= SMP_CORE_TIMEOUT_MAX) { \
|
||||||
|
INFO("[%s:%d] - CORE%d ON WAIT TIMEOUT %u us (> %u)\n", \
|
||||||
|
__func__, __LINE__, cpu_id, k_cnt, SMP_CORE_TIMEOUT_MAX); \
|
||||||
|
panic(); \
|
||||||
|
} \
|
||||||
|
k_cnt++; udelay(1); })
|
||||||
|
|
||||||
|
#ifdef CPU_PM_CORE_ARCH64_ONLY
|
||||||
|
#define mt_smp_core_init_arch(_a, _b, _c, _d)
|
||||||
|
#else
|
||||||
|
void mt_smp_core_init_arch(int cluster, int cpu, int arm64,
|
||||||
|
struct cpu_pwr_ctrl *pwr_ctrl);
|
||||||
|
#endif /* CPU_PM_CORE_ARCH64_ONLY */
|
||||||
|
|
||||||
|
void mt_smp_core_bootup_address_set(int cluster,
|
||||||
|
int cpu,
|
||||||
|
struct cpu_pwr_ctrl *pwr_ctrl,
|
||||||
|
uintptr_t entry);
|
||||||
|
|
||||||
|
int mt_smp_power_core_on(unsigned int cpu_id, struct cpu_pwr_ctrl *pwr_ctrl);
|
||||||
|
int mt_smp_power_core_off(unsigned int cpu_id, struct cpu_pwr_ctrl *pwr_ctrl);
|
||||||
|
|
||||||
|
void mt_smp_init(void);
|
||||||
|
|
||||||
|
int mt_smp_cluster_pwpr_init(struct cluster_pwr_ctrl *pwr_ctrl);
|
||||||
|
int mt_smp_cluster_pwpr_op_init(struct cluster_pwr_ctrl *pwr_ctrl);
|
||||||
|
|
||||||
|
#endif /* MT_SMP_H */
|
43
plat/mediatek/drivers/cpu_pm/cpcv5_4/rules.mk
Normal file
43
plat/mediatek/drivers/cpu_pm/cpcv5_4/rules.mk
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
#
|
||||||
|
|
||||||
|
#Prologue, init variable
|
||||||
|
LOCAL_DIR := $(call GET_LOCAL_DIR)
|
||||||
|
|
||||||
|
CPU_PM_PWR_REQ := y
|
||||||
|
CPU_PM_PWR_REQ_DEBUG := n
|
||||||
|
|
||||||
|
#Define your module name
|
||||||
|
MODULE := cpcv${CONFIG_MTK_CPU_PM_ARCH}
|
||||||
|
|
||||||
|
#Add your source code here
|
||||||
|
LOCAL_SRCS-y := ${LOCAL_DIR}/mt_cpu_pm.c \
|
||||||
|
${LOCAL_DIR}/mt_cpu_pm_cpc.c \
|
||||||
|
${LOCAL_DIR}/mt_cpu_pm_smc.c \
|
||||||
|
${LOCAL_DIR}/mt_ppu.c
|
||||||
|
|
||||||
|
LOCAL_SRCS-$(CPU_PM_TINYSYS_SUPPORT) += ${LOCAL_DIR}/mt_cpu_pm_mbox.c
|
||||||
|
LOCAL_SRCS-$(CONFIG_MTK_SMP_EN) += ${LOCAL_DIR}/mt_smp.c
|
||||||
|
|
||||||
|
LOCAL_SRCS-${CPU_PM_IRQ_REMAIN_ENABLE} += ${LOCAL_DIR}/mt_lp_irqremain.c
|
||||||
|
$(eval $(call add_defined_option,CPU_PM_IRQ_REMAIN_ENABLE))
|
||||||
|
|
||||||
|
$(eval $(call add_defined_option,CPU_PM_DOMAIN_CORE_ONLY))
|
||||||
|
$(eval $(call add_defined_option,CPU_PM_CORE_ARCH64_ONLY))
|
||||||
|
$(eval $(call add_defined_option,CPU_PM_TINYSYS_SUPPORT))
|
||||||
|
|
||||||
|
$(eval $(call add_defined_option,CPU_PM_SUSPEND_NOTIFY))
|
||||||
|
|
||||||
|
$(eval $(call add_defined_option,CPU_PM_PWR_REQ))
|
||||||
|
$(eval $(call add_defined_option,CPU_PM_PWR_REQ_DEBUG))
|
||||||
|
|
||||||
|
$(eval $(call add_defined_option,CONFIG_MTK_CPU_ILDO))
|
||||||
|
$(eval $(call add_defined_option,CPU_PM_CPU_RET_MASK))
|
||||||
|
|
||||||
|
#Epilogue, build as module
|
||||||
|
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
|
||||||
|
|
||||||
|
$(eval $(call add_defined_option,CPU_PM_ACP_FSM))
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2022, MediaTek Inc. All rights reserved.
|
# Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
#
|
#
|
||||||
|
@ -10,4 +10,10 @@ MODULE := cpu_pm
|
||||||
|
|
||||||
SUB_RULES-${CONFIG_MTK_CPU_PM_SUPPORT} := $(LOCAL_DIR)/cpcv${CONFIG_MTK_CPU_PM_ARCH}
|
SUB_RULES-${CONFIG_MTK_CPU_PM_SUPPORT} := $(LOCAL_DIR)/cpcv${CONFIG_MTK_CPU_PM_ARCH}
|
||||||
|
|
||||||
|
ifneq ($(CPU_PWR_TOPOLOGY),)
|
||||||
|
SUB_RULES-${CONFIG_MTK_CPU_PM_SUPPORT} += $(LOCAL_DIR)/topology/$(CPU_PWR_TOPOLOGY)
|
||||||
|
else
|
||||||
|
SUB_RULES-${CONFIG_MTK_CPU_PM_SUPPORT} += $(LOCAL_DIR)/topology/default
|
||||||
|
endif
|
||||||
|
|
||||||
$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
|
$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
|
||||||
|
|
125
plat/mediatek/drivers/cpu_pm/topology/default/pwr.c
Normal file
125
plat/mediatek/drivers/cpu_pm/topology/default/pwr.c
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <lib/spinlock.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
#include "../inc/pwr_topology.h"
|
||||||
|
#include <lib/pm/mtk_pm.h>
|
||||||
|
#include <lpm/mt_lp_rm.h>
|
||||||
|
|
||||||
|
#ifdef MT_CPU_PM_USING_BAKERY_LOCK
|
||||||
|
DEFINE_BAKERY_LOCK(mt_pwr_lock);
|
||||||
|
|
||||||
|
#define plat_pwr_lock_init() bakery_lock_init(&mt_pwr_lock)
|
||||||
|
|
||||||
|
#define plat_pwr_lock() bakery_lock_get(&mt_pwr_lock)
|
||||||
|
|
||||||
|
#define plat_pwr_unlock() bakery_lock_release(&mt_pwr_lock)
|
||||||
|
#else
|
||||||
|
spinlock_t mt_pwr_lock;
|
||||||
|
|
||||||
|
#define plat_pwr_lock_init()
|
||||||
|
#define plat_pwr_lock() spin_lock(&mt_pwr_lock)
|
||||||
|
|
||||||
|
#define plat_pwr_unlock() spin_unlock(&mt_pwr_lock)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum mt_pwr_domain_node {
|
||||||
|
MT_PWR_NONMCUSYS = 0,
|
||||||
|
MT_PWR_MCUSYS_PDN,
|
||||||
|
MT_PWR_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
#if CONFIG_MTK_PM_SUPPORT && CONFIG_MTK_CPU_SUSPEND_EN && \
|
||||||
|
!CPU_PM_DOMAIN_CORE_ONLY
|
||||||
|
static int mt_pwr_domain_st[MT_PWR_MAX];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ALL_IN_ONE_GROUP 0xFF
|
||||||
|
unsigned int pwr_domain_coordination(enum pwr_domain_status pwr,
|
||||||
|
const mtk_pstate_type psci_state,
|
||||||
|
const struct mtk_cpupm_pwrstate *state,
|
||||||
|
afflv_prepare fn)
|
||||||
|
{
|
||||||
|
unsigned int pstate = 0;
|
||||||
|
|
||||||
|
#if CONFIG_MTK_PM_SUPPORT && CONFIG_MTK_CPU_SUSPEND_EN && \
|
||||||
|
!CPU_PM_DOMAIN_CORE_ONLY
|
||||||
|
unsigned int is_flush = 0;
|
||||||
|
struct pwr_toplogy tp = {
|
||||||
|
.cur_group_bit = ALL_IN_ONE_GROUP,
|
||||||
|
.group = ALL_IN_ONE_GROUP,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Skip to process smp */
|
||||||
|
if (pwr > PWR_DOMAIN_OFF)
|
||||||
|
return pstate;
|
||||||
|
|
||||||
|
if (!IS_MT_PLAT_PWR_STATE_MCUSYS(state->pwr.state_id)) {
|
||||||
|
plat_pwr_lock();
|
||||||
|
if (pwr == PWR_DOMAIN_OFF)
|
||||||
|
mt_pwr_domain_st[MT_PWR_NONMCUSYS] += 1;
|
||||||
|
else
|
||||||
|
mt_pwr_domain_st[MT_PWR_NONMCUSYS] -= 1;
|
||||||
|
flush_dcache_range(
|
||||||
|
(uintptr_t)&mt_pwr_domain_st[MT_PWR_NONMCUSYS],
|
||||||
|
sizeof(mt_pwr_domain_st[MT_PWR_NONMCUSYS]));
|
||||||
|
plat_pwr_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
plat_pwr_lock();
|
||||||
|
if (state->pwr.afflv >= PLAT_MT_CPU_SUSPEND_CLUSTER)
|
||||||
|
pstate |= MT_CPUPM_PWR_DOMAIN_CLUSTER;
|
||||||
|
|
||||||
|
if (psci_get_pstate_pwrlvl(psci_state) >= PLAT_MT_CPU_SUSPEND_CLUSTER)
|
||||||
|
pstate |= MT_CPUPM_PWR_DOMAIN_PERCORE_DSU;
|
||||||
|
|
||||||
|
if (pwr == PWR_DOMAIN_OFF) {
|
||||||
|
if (IS_PLAT_MCUSYSOFF_AFFLV(state->pwr.afflv) &&
|
||||||
|
(mt_pwr_domain_st[MT_PWR_NONMCUSYS] == 0)) {
|
||||||
|
int ret = MTK_CPUPM_E_OK;
|
||||||
|
|
||||||
|
tp.group = ALL_IN_ONE_GROUP;
|
||||||
|
if (fn)
|
||||||
|
ret = fn(1, state, &tp);
|
||||||
|
|
||||||
|
if (ret == MTK_CPUPM_E_OK) {
|
||||||
|
pstate |= MT_CPUPM_PWR_DOMAIN_MCUSYS;
|
||||||
|
mt_pwr_domain_st[MT_PWR_MCUSYS_PDN] += 1;
|
||||||
|
is_flush = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mt_pwr_domain_st[MT_PWR_MCUSYS_PDN]) {
|
||||||
|
tp.group = 0x0;
|
||||||
|
if (fn)
|
||||||
|
fn(1, state, &tp);
|
||||||
|
pstate |= MT_CPUPM_PWR_DOMAIN_MCUSYS;
|
||||||
|
mt_pwr_domain_st[MT_PWR_MCUSYS_PDN] -= 1;
|
||||||
|
is_flush = 1;
|
||||||
|
}
|
||||||
|
if (mt_pwr_domain_st[MT_PWR_NONMCUSYS] < 0)
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_flush)
|
||||||
|
flush_dcache_range(
|
||||||
|
(uintptr_t)&mt_pwr_domain_st[MT_PWR_MCUSYS_PDN],
|
||||||
|
sizeof(mt_pwr_domain_st[MT_PWR_MCUSYS_PDN]));
|
||||||
|
|
||||||
|
plat_pwr_unlock();
|
||||||
|
#endif
|
||||||
|
return pstate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pwr_topology_init(void)
|
||||||
|
{
|
||||||
|
plat_pwr_lock_init();
|
||||||
|
}
|
13
plat/mediatek/drivers/cpu_pm/topology/default/rules.mk
Normal file
13
plat/mediatek/drivers/cpu_pm/topology/default/rules.mk
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
#
|
||||||
|
|
||||||
|
LOCAL_DIR := $(call GET_LOCAL_DIR)
|
||||||
|
|
||||||
|
MODULE := pwr_topology_default
|
||||||
|
|
||||||
|
LOCAL_SRCS-y := ${LOCAL_DIR}/pwr.c
|
||||||
|
|
||||||
|
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
|
123
plat/mediatek/drivers/cpu_pm/topology/group_4_3_1/pwr.c
Normal file
123
plat/mediatek/drivers/cpu_pm/topology/group_4_3_1/pwr.c
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <lib/spinlock.h>
|
||||||
|
#include <plat/common/platform.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
#include "../inc/pwr_topology.h"
|
||||||
|
#include <lib/pm/mtk_pm.h>
|
||||||
|
#include <lpm/mt_lp_rm.h>
|
||||||
|
|
||||||
|
#define GROUP_CPU_ALL 0x7
|
||||||
|
#define GROUP_0_CPUID_MAX 3
|
||||||
|
#define GROUP_1_CPUID_MAX 6
|
||||||
|
#define GROUP_2_CPUID_MAX 7
|
||||||
|
|
||||||
|
#define IS_ALL_GROUP_OFF(_mask) ((_mask & GROUP_CPU_ALL) == GROUP_CPU_ALL)
|
||||||
|
|
||||||
|
#define GET_GROUPID(_cpuid, _gid) ({ \
|
||||||
|
if (_cpuid <= GROUP_0_CPUID_MAX) \
|
||||||
|
_gid = 0; \
|
||||||
|
else if (_cpuid <= GROUP_1_CPUID_MAX) \
|
||||||
|
_gid = 1; \
|
||||||
|
else \
|
||||||
|
_gid = 2; })
|
||||||
|
|
||||||
|
#define GET_GROUPMASK(_cpuid, _gmask) ({ \
|
||||||
|
if (_cpuid <= GROUP_0_CPUID_MAX) \
|
||||||
|
_gmask = BIT(0); \
|
||||||
|
else if (_cpuid <= GROUP_1_CPUID_MAX) \
|
||||||
|
_gmask = BIT(1);\
|
||||||
|
else if (_cpuid <= GROUP_2_CPUID_MAX) \
|
||||||
|
_gmask = BIT(2); \
|
||||||
|
else \
|
||||||
|
_gmask = 0; })
|
||||||
|
|
||||||
|
#ifdef MT_CPU_PM_USING_BAKERY_LOCK
|
||||||
|
DEFINE_BAKERY_LOCK(mt_pwr_lock);
|
||||||
|
#define plat_pwr_lock_init() bakery_lock_init(&mt_pwr_lock)
|
||||||
|
#define plat_pwr_lock() bakery_lock_get(&mt_pwr_lock)
|
||||||
|
#define plat_pwr_unlock() bakery_lock_release(&mt_pwr_lock)
|
||||||
|
#else
|
||||||
|
spinlock_t mt_pwr_lock;
|
||||||
|
#define plat_pwr_lock_init()
|
||||||
|
#define plat_pwr_lock() spin_lock(&mt_pwr_lock)
|
||||||
|
#define plat_pwr_unlock() spin_unlock(&mt_pwr_lock)
|
||||||
|
#endif /* MT_CPU_PM_USING_BAKERY_LOCK */
|
||||||
|
|
||||||
|
#if CONFIG_MTK_PM_SUPPORT && CONFIG_MTK_CPU_SUSPEND_EN && \
|
||||||
|
!CPU_PM_DOMAIN_CORE_ONLY
|
||||||
|
static unsigned int cpu_groupmask;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned int pwr_domain_coordination(enum pwr_domain_status pwr,
|
||||||
|
const mtk_pstate_type psci_state,
|
||||||
|
const struct mtk_cpupm_pwrstate *state,
|
||||||
|
afflv_prepare fn)
|
||||||
|
{
|
||||||
|
unsigned int pstate = MT_CPUPM_PWR_DOMAIN_CORE;
|
||||||
|
|
||||||
|
#if CONFIG_MTK_PM_SUPPORT && CONFIG_MTK_CPU_SUSPEND_EN && \
|
||||||
|
!CPU_PM_DOMAIN_CORE_ONLY
|
||||||
|
struct pwr_toplogy tp;
|
||||||
|
|
||||||
|
if (state->pwr.afflv >= PLAT_MT_CPU_SUSPEND_CLUSTER) {
|
||||||
|
unsigned int fgmask;
|
||||||
|
|
||||||
|
if (state->info.cpuid >= PLATFORM_CORE_COUNT)
|
||||||
|
assert(0);
|
||||||
|
|
||||||
|
GET_GROUPMASK(state->info.cpuid, tp.cur_group_bit);
|
||||||
|
|
||||||
|
plat_pwr_lock();
|
||||||
|
if ((pwr == PWR_DOMAIN_OFF) || (pwr == PWR_DOMAIN_SMP_OFF)) {
|
||||||
|
tp.group = (cpu_groupmask | tp.cur_group_bit);
|
||||||
|
fgmask = tp.group;
|
||||||
|
} else {
|
||||||
|
tp.group = (cpu_groupmask & ~tp.cur_group_bit);
|
||||||
|
fgmask = cpu_groupmask;
|
||||||
|
}
|
||||||
|
fn(1, state, &tp);
|
||||||
|
cpu_groupmask = tp.group;
|
||||||
|
|
||||||
|
plat_pwr_unlock();
|
||||||
|
if (IS_ALL_GROUP_OFF(fgmask))
|
||||||
|
pstate |= MT_CPUPM_PWR_DOMAIN_CLUSTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip to process smp */
|
||||||
|
if (pwr > PWR_DOMAIN_OFF)
|
||||||
|
return pstate;
|
||||||
|
|
||||||
|
if (psci_get_pstate_pwrlvl(psci_state) >= PLAT_MT_CPU_SUSPEND_CLUSTER)
|
||||||
|
pstate |= MT_CPUPM_PWR_DOMAIN_PERCORE_DSU;
|
||||||
|
|
||||||
|
if (IS_PLAT_MCUSYSOFF_AFFLV(state->pwr.afflv)) {
|
||||||
|
int ret = MTK_CPUPM_E_OK;
|
||||||
|
|
||||||
|
if (fn)
|
||||||
|
ret = fn(state->pwr.afflv, state, &tp);
|
||||||
|
|
||||||
|
if (ret == MTK_CPUPM_E_OK)
|
||||||
|
pstate |= MT_CPUPM_PWR_DOMAIN_MCUSYS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return pstate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pwr_topology_init(void)
|
||||||
|
{
|
||||||
|
#if CONFIG_MTK_PM_SUPPORT && CONFIG_MTK_CPU_SUSPEND_EN && \
|
||||||
|
!CPU_PM_DOMAIN_CORE_ONLY
|
||||||
|
cpu_groupmask = GROUP_CPU_ALL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
plat_pwr_lock_init();
|
||||||
|
}
|
17
plat/mediatek/drivers/cpu_pm/topology/group_4_3_1/rules.mk
Normal file
17
plat/mediatek/drivers/cpu_pm/topology/group_4_3_1/rules.mk
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#
|
||||||
|
# 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 := pwr_topology_default
|
||||||
|
|
||||||
|
#Add your source code here
|
||||||
|
LOCAL_SRCS-y := ${LOCAL_DIR}/pwr.c
|
||||||
|
|
||||||
|
#Epilogue, build as module
|
||||||
|
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
|
35
plat/mediatek/drivers/cpu_pm/topology/inc/pwr_topology.h
Normal file
35
plat/mediatek/drivers/cpu_pm/topology/inc/pwr_topology.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PWR_TOPOLOGY_H
|
||||||
|
#define PWR_TOPOLOGY_H
|
||||||
|
|
||||||
|
#include <lib/pm/mtk_pm.h>
|
||||||
|
|
||||||
|
enum pwr_domain_status {
|
||||||
|
PWR_DOMAIN_ON,
|
||||||
|
PWR_DOMAIN_OFF,
|
||||||
|
PWR_DOMAIN_SMP_ON,
|
||||||
|
PWR_DOMAIN_SMP_OFF,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pwr_toplogy {
|
||||||
|
unsigned int cur_group_bit;
|
||||||
|
unsigned int group;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int (*afflv_prepare)(unsigned int,
|
||||||
|
const struct mtk_cpupm_pwrstate *,
|
||||||
|
const struct pwr_toplogy *);
|
||||||
|
|
||||||
|
void pwr_topology_init(void);
|
||||||
|
|
||||||
|
unsigned int pwr_domain_coordination(enum pwr_domain_status pwr,
|
||||||
|
const mtk_pstate_type psci_state,
|
||||||
|
const struct mtk_cpupm_pwrstate *state,
|
||||||
|
afflv_prepare fn);
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2022, MediaTek Inc. All rights reserved.
|
# Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
#
|
#
|
||||||
|
@ -8,7 +8,15 @@ LOCAL_DIR := $(call GET_LOCAL_DIR)
|
||||||
|
|
||||||
MODULE := mcusys
|
MODULE := mcusys
|
||||||
|
|
||||||
|
ifeq ($(MTK_SOC), mt8196)
|
||||||
|
PLAT_INCLUDES += -I${MTK_PLAT}/include/drivers/mcusys/$(MCUSYS_VERSION)
|
||||||
|
ifneq ($(MCUPM_VERSION),)
|
||||||
|
PLAT_INCLUDES += -I${MTK_PLAT}/include/drivers/mcusys/mcupm
|
||||||
|
CFLAGS += -DMCUPM_VERSION_${MCUPM_VERSION}
|
||||||
|
endif
|
||||||
|
else
|
||||||
PLAT_INCLUDES += -I$(LOCAL_DIR)/$(MCUSYS_VERSION)
|
PLAT_INCLUDES += -I$(LOCAL_DIR)/$(MCUSYS_VERSION)
|
||||||
|
endif
|
||||||
|
|
||||||
LOCAL_SRCS-y := $(LOCAL_DIR)/mcusys.c
|
LOCAL_SRCS-y := $(LOCAL_DIR)/mcusys.c
|
||||||
|
|
||||||
|
|
88
plat/mediatek/drivers/pmic/mt6363/mt6363_psc.c
Normal file
88
plat/mediatek/drivers/pmic/mt6363/mt6363_psc.c
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <common/debug.h>
|
||||||
|
#include <drivers/pmic/pmic_psc.h>
|
||||||
|
#include <drivers/spmi_api.h>
|
||||||
|
#include <lib/mtk_init/mtk_init.h>
|
||||||
|
|
||||||
|
#include "registers.h"
|
||||||
|
|
||||||
|
static struct spmi_device *sdev;
|
||||||
|
|
||||||
|
static const struct pmic_psc_reg mt6363_psc_regs[] = {
|
||||||
|
PMIC_PSC_REG(RG_PWRHOLD, MT6363_PPCCTL0, 0),
|
||||||
|
PMIC_PSC_REG(RG_CRST, MT6363_PPCCTL1, 0),
|
||||||
|
PMIC_PSC_REG(RG_SMART_RST_SDN_EN, MT6363_STRUP_CON12, 1),
|
||||||
|
PMIC_PSC_REG(RG_SMART_RST_MODE, MT6363_STRUP_CON12, 2),
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mt6363_psc_read_field(uint32_t reg, uint32_t *val, uint32_t mask, uint32_t shift)
|
||||||
|
{
|
||||||
|
uint8_t rdata = 0;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!val)
|
||||||
|
return -EINVAL;
|
||||||
|
if (!sdev)
|
||||||
|
return -ENODEV;
|
||||||
|
ret = spmi_ext_register_readl(sdev, reg, &rdata, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
rdata &= (mask << shift);
|
||||||
|
*val = (rdata >> shift);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mt6363_psc_write_field(uint32_t reg, uint32_t val, uint32_t mask, uint32_t shift)
|
||||||
|
{
|
||||||
|
uint8_t org = 0;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!sdev)
|
||||||
|
return -ENODEV;
|
||||||
|
ret = spmi_ext_register_readl(sdev, reg, &org, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
org &= ~(mask << shift);
|
||||||
|
org |= (val << shift);
|
||||||
|
|
||||||
|
ret = spmi_ext_register_writel(sdev, reg, &org, 1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pmic_psc_config mt6363_psc_config = {
|
||||||
|
.read_field = mt6363_psc_read_field,
|
||||||
|
.write_field = mt6363_psc_write_field,
|
||||||
|
.regs = mt6363_psc_regs,
|
||||||
|
.reg_size = ARRAY_SIZE(mt6363_psc_regs),
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mt6363_psc_init(void)
|
||||||
|
{
|
||||||
|
sdev = get_spmi_device(SPMI_MASTER_1, SPMI_SLAVE_4);
|
||||||
|
if (!sdev)
|
||||||
|
ERROR("%s: get spmi device fail\n", __func__);
|
||||||
|
return pmic_psc_register(&mt6363_psc_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
MTK_PLAT_SETUP_0_INIT(mt6363_psc_init);
|
||||||
|
|
||||||
|
#ifdef CONFIG_MTK_PMIC_SPT_SUPPORT
|
||||||
|
static int mt6363_spt_enable(void)
|
||||||
|
{
|
||||||
|
/* Enable PMIC Self-Protection Timer(SPT) */
|
||||||
|
return mt6363_psc_write_field(MT6363_RG_SELFWDT_EN_ADDR, MT6363_RG_SELFWDT_EN_MASK,
|
||||||
|
MT6363_RG_SELFWDT_EN_MASK, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
MTK_PLAT_RUNTIME_INIT(mt6363_spt_enable);
|
||||||
|
#endif
|
17
plat/mediatek/drivers/pmic/mt6363/registers.h
Normal file
17
plat/mediatek/drivers/pmic/mt6363/registers.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT6363_REGISTER_H
|
||||||
|
#define MT6363_REGISTER_H
|
||||||
|
|
||||||
|
/* PMIC Registers for PSC */
|
||||||
|
#define MT6363_PPCCTL0 0xA08
|
||||||
|
#define MT6363_PPCCTL1 0xA09
|
||||||
|
#define MT6363_STRUP_CON12 0xA0F
|
||||||
|
#define MT6363_RG_SELFWDT_EN_ADDR 0xA14
|
||||||
|
#define MT6363_RG_SELFWDT_EN_MASK 0x1
|
||||||
|
|
||||||
|
#endif /* MT6363_REGISTER_H */
|
17
plat/mediatek/drivers/pmic/mt6363/rules.mk
Normal file
17
plat/mediatek/drivers/pmic/mt6363/rules.mk
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#
|
||||||
|
# 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 := mt6363
|
||||||
|
|
||||||
|
#Add your source code here
|
||||||
|
LOCAL_SRCS-y := $(LOCAL_DIR)/${PMIC_CHIP}_psc.c
|
||||||
|
|
||||||
|
#Epilogue, build as module
|
||||||
|
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
|
73
plat/mediatek/drivers/pmic/mt8196/pmic_lowpower_init.c
Normal file
73
plat/mediatek/drivers/pmic/mt8196/pmic_lowpower_init.c
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <common/debug.h>
|
||||||
|
#include <drivers/pmic/pmic_set_lowpower.h>
|
||||||
|
#include <drivers/pmic/pmic_swap_api.h>
|
||||||
|
#include <drivers/spmi/spmi_common.h>
|
||||||
|
#include <lib/mtk_init/mtk_init.h>
|
||||||
|
|
||||||
|
#define MASTER_ID SPMI_MASTER_1
|
||||||
|
|
||||||
|
struct spmi_device *lowpower_sdev[SPMI_MAX_SLAVE_ID];
|
||||||
|
|
||||||
|
static const uint8_t lowpower_slvid_arr[] = {
|
||||||
|
MT6363_SLAVE,
|
||||||
|
MT6373_SLAVE,
|
||||||
|
MT6316_S6_SLAVE,
|
||||||
|
MT6316_S7_SLAVE,
|
||||||
|
MT6316_S8_SLAVE,
|
||||||
|
MT6316_S15_SLAVE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int pmic_lowpower_init(void)
|
||||||
|
{
|
||||||
|
uint8_t i, slvid;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(lowpower_slvid_arr); i++) {
|
||||||
|
slvid = lowpower_slvid_arr[i];
|
||||||
|
lowpower_sdev[slvid] = get_spmi_device(MASTER_ID, slvid);
|
||||||
|
if (!lowpower_sdev[slvid])
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MT6363 Deep idle, SODI3 */
|
||||||
|
/* VREQ config by SCP owner in LK2 */
|
||||||
|
PMIC_BUCK_SET_LP(MT6363, VBUCK4, HW2, true, OP_MODE_LP, HW_LP);
|
||||||
|
PMIC_BUCK_SET_LP(MT6363, VBUCK4, RC9, true, OP_MODE_MU, HW_ON);
|
||||||
|
PMIC_BUCK_SET_LP(MT6363, VS2, HW2, true, OP_MODE_LP, HW_LP);
|
||||||
|
PMIC_BUCK_SET_LP(MT6363, VS2, RC9, true, OP_MODE_MU, HW_ON);
|
||||||
|
PMIC_BUCK_SET_LP(MT6363, VS3, HW2, true, OP_MODE_LP, HW_LP);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VSRAM_CPUB, HW2, true, OP_MODE_LP, HW_LP);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VSRAM_CPUB, RC9, true, OP_MODE_MU, HW_ON);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VSRAM_CPUL, HW2, true, OP_MODE_LP, HW_LP);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VSRAM_CPUL, RC9, true, OP_MODE_MU, HW_ON);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VSRAM_APU, RC2, true, OP_MODE_MU, HW_OFF);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VSRAM_MODEM, HW2, true, OP_MODE_LP, HW_LP);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VSRAM_MODEM, RC9, true, OP_MODE_MU, HW_ON);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VA12_1, HW2, true, OP_MODE_LP, HW_LP);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VA12_1, RC9, true, OP_MODE_MU, HW_ON);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VA12_2, HW2, true, OP_MODE_LP, HW_LP);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VA12_2, RC9, true, OP_MODE_MU, HW_ON);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VUFS18, HW2, true, OP_MODE_LP, HW_LP);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VUFS18, RC9, true, OP_MODE_MU, HW_ON);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VUFS12, HW2, true, OP_MODE_LP, HW_LP);
|
||||||
|
|
||||||
|
/* MT6373 Deep idle, SODI3 */
|
||||||
|
PMIC_BUCK_SET_LP(MT6373, VBUCK4, HW2, true, OP_MODE_LP, HW_OFF);
|
||||||
|
PMIC_BUCK_SET_LP(MT6373, VBUCK5, HW2, true, OP_MODE_LP, HW_OFF);
|
||||||
|
PMIC_BUCK_SET_LP(MT6373, VBUCK6, HW2, true, OP_MODE_LP, HW_LP);
|
||||||
|
PMIC_LDO_SET_LP(MT6373, VUSB, HW2, true, OP_MODE_LP, HW_LP);
|
||||||
|
|
||||||
|
/* MT6316 Deep idle, SODI3 */
|
||||||
|
PMIC_SLVID_BUCK_SET_LP(MT6316, S8, VBUCK1, HW2, true, OP_MODE_LP, HW_LP);
|
||||||
|
PMIC_SLVID_BUCK_SET_LP(MT6316, S6, VBUCK3, HW2, true, OP_MODE_LP, HW_ONLV);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MTK_PLAT_SETUP_0_INIT(pmic_lowpower_init);
|
291
plat/mediatek/drivers/pmic/mt8196/pmic_shutdown_cfg.c
Normal file
291
plat/mediatek/drivers/pmic/mt8196/pmic_shutdown_cfg.c
Normal file
|
@ -0,0 +1,291 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <common/debug.h>
|
||||||
|
|
||||||
|
#include <drivers/pmic/pmic_shutdown_cfg.h>
|
||||||
|
#include <drivers/spmi/spmi_common.h>
|
||||||
|
#include <drivers/spmi_api.h>
|
||||||
|
#include <lib/mtk_init/mtk_init.h>
|
||||||
|
|
||||||
|
#define MASTER_ID SPMI_MASTER_1
|
||||||
|
|
||||||
|
#ifndef MT8678_PMIC_SUPPORT
|
||||||
|
/* MT6316 will automatically disable wdt in poffs */
|
||||||
|
#define MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR 0x408
|
||||||
|
#define MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_MASK 0x1
|
||||||
|
#define MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT 1
|
||||||
|
#else
|
||||||
|
/* MT6319 will automatically disable wdt in poffs */
|
||||||
|
#define MT6319_TOP_RST_MISC_CLR 0x128
|
||||||
|
#define MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR 0x138
|
||||||
|
#define MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_MASK 0x1
|
||||||
|
#define MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MT6373_TOP_RST_MISC1_CLR 0x13B
|
||||||
|
#define MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR 0x408
|
||||||
|
#define MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_MASK 0x1
|
||||||
|
#define MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT 1
|
||||||
|
|
||||||
|
#define MT6685_TOP_RST_MISC_CLR 0x129
|
||||||
|
#define MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR 0x408
|
||||||
|
#define MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_MASK 0x1
|
||||||
|
#define MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT 1
|
||||||
|
|
||||||
|
struct spmi_device *sdev_arr[SPMI_MAX_SLAVE_ID];
|
||||||
|
|
||||||
|
struct cfg_t {
|
||||||
|
uint8_t slvid;
|
||||||
|
uint32_t addr;
|
||||||
|
uint32_t shutdown_src_addr;
|
||||||
|
uint32_t shutdown_src_mask;
|
||||||
|
uint32_t shutdown_src_shift;
|
||||||
|
uint8_t val;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef MT8678_PMIC_SUPPORT
|
||||||
|
static const struct cfg_t cfg_arr[] = {
|
||||||
|
{
|
||||||
|
.slvid = SPMI_SLAVE_6,
|
||||||
|
.addr = 0,
|
||||||
|
.shutdown_src_addr = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
|
||||||
|
.shutdown_src_mask = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
|
||||||
|
.shutdown_src_shift = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
|
||||||
|
.val = 0x1
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_7,
|
||||||
|
.addr = 0,
|
||||||
|
.shutdown_src_addr = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
|
||||||
|
.shutdown_src_mask = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
|
||||||
|
.shutdown_src_shift = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
|
||||||
|
.val = 0x1
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_8,
|
||||||
|
.addr = 0,
|
||||||
|
.shutdown_src_addr = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
|
||||||
|
.shutdown_src_mask = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
|
||||||
|
.shutdown_src_shift = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
|
||||||
|
.val = 0x1
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_15,
|
||||||
|
.addr = 0,
|
||||||
|
.shutdown_src_addr = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
|
||||||
|
.shutdown_src_mask = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
|
||||||
|
.shutdown_src_shift = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
|
||||||
|
.val = 0x1
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_5,
|
||||||
|
.addr = MT6373_TOP_RST_MISC1_CLR,
|
||||||
|
.shutdown_src_addr = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
|
||||||
|
.shutdown_src_mask = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
|
||||||
|
.shutdown_src_shift = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
|
||||||
|
.val = 0x1
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_9,
|
||||||
|
.addr = MT6685_TOP_RST_MISC_CLR,
|
||||||
|
.shutdown_src_addr = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
|
||||||
|
.shutdown_src_mask = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
|
||||||
|
.shutdown_src_shift = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
|
||||||
|
.val = 0x1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#else /* MT8678_PMIC_SUPPORT */
|
||||||
|
static const struct cfg_t cfg_arr[] = {
|
||||||
|
{
|
||||||
|
.slvid = SPMI_SLAVE_6,
|
||||||
|
.addr = MT6319_TOP_RST_MISC_CLR,
|
||||||
|
.shutdown_src_addr = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
|
||||||
|
.shutdown_src_mask = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
|
||||||
|
.shutdown_src_shift = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
|
||||||
|
.val = 0x1
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_7,
|
||||||
|
.addr = MT6319_TOP_RST_MISC_CLR,
|
||||||
|
.shutdown_src_addr = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
|
||||||
|
.shutdown_src_mask = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
|
||||||
|
.shutdown_src_shift = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
|
||||||
|
.val = 0x1
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_8,
|
||||||
|
.addr = MT6319_TOP_RST_MISC_CLR,
|
||||||
|
.shutdown_src_addr = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
|
||||||
|
.shutdown_src_mask = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
|
||||||
|
.shutdown_src_shift = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
|
||||||
|
.val = 0x1
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_15,
|
||||||
|
.addr = MT6319_TOP_RST_MISC_CLR,
|
||||||
|
.shutdown_src_addr = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
|
||||||
|
.shutdown_src_mask = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
|
||||||
|
.shutdown_src_shift = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
|
||||||
|
.val = 0x1
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_5,
|
||||||
|
.addr = MT6373_TOP_RST_MISC1_CLR,
|
||||||
|
.shutdown_src_addr = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
|
||||||
|
.shutdown_src_mask = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
|
||||||
|
.shutdown_src_shift = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
|
||||||
|
.val = 0x1
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_9,
|
||||||
|
.addr = MT6685_TOP_RST_MISC_CLR,
|
||||||
|
.shutdown_src_addr = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
|
||||||
|
.shutdown_src_mask = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
|
||||||
|
.shutdown_src_shift = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
|
||||||
|
.val = 0x1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif /* MT8678_PMIC_SUPPORT */
|
||||||
|
|
||||||
|
#define MT6316_TOP_ANA_KEY 0x3AA
|
||||||
|
#define MT6316_PMIC_RG_VI075_SINK_CUR_ADDR 0x994
|
||||||
|
#define MT6316_PMIC_RG_VI075_SINK_CUR_MASK 0xF
|
||||||
|
#define MT6316_PMIC_RG_VI075_SINK_CUR_SHIFT 4
|
||||||
|
#define MT6316_PMIC_RG_PSEQ_ELR_RSV2_ADDR 0xA2C
|
||||||
|
#define MT6316_PMIC_RG_PSEQ_ELR_RSV2_MASK 0x7
|
||||||
|
#define MT6316_PMIC_RG_PSEQ_ELR_RSV2_SHIFT 5
|
||||||
|
#define PSEQ_ELR_RSV2_VAL_MASK_1 0x3
|
||||||
|
#define PSEQ_ELR_RSV2_VAL_MASK_2 0x1
|
||||||
|
#define VI075_SINK_CUR_SOURCE_1 0x5
|
||||||
|
#define VI075_SINK_CUR_SOURCE_2 0
|
||||||
|
#define VI075_SINK_CUR_SOURCE_3 0xB
|
||||||
|
#define ARRAY_LENGTH_MAX 2
|
||||||
|
|
||||||
|
#ifndef MT8678_PMIC_SUPPORT
|
||||||
|
static void mt6316_key_lock_check(struct spmi_device *mt6316_dev, uint16_t key)
|
||||||
|
{
|
||||||
|
int i, ret;
|
||||||
|
uint16_t rdata;
|
||||||
|
uint8_t work_val[ARRAY_LENGTH_MAX];
|
||||||
|
uint8_t wdata[ARRAY_LENGTH_MAX];
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
ret = spmi_ext_register_readl(mt6316_dev, key, &work_val[0], 2);
|
||||||
|
if (ret < 0) {
|
||||||
|
INFO("[%s]: read fail, addr = 0x%x, ret = %d\n"
|
||||||
|
, __func__, key, ret);
|
||||||
|
i = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rdata = work_val[0] | (work_val[1] << 8);
|
||||||
|
|
||||||
|
if (rdata != 0) {
|
||||||
|
INFO("[%s] lock fail, addr = 0x%x, rdata = 0x%x.\n"
|
||||||
|
, __func__, key, rdata);
|
||||||
|
wdata[0] = 0;
|
||||||
|
wdata[1] = 0;
|
||||||
|
spmi_ext_register_writel(mt6316_dev, key, &wdata[0], 2);
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wk_vio075_sink_cur(struct spmi_device *mt6316_dev, unsigned char en_seq_off)
|
||||||
|
{
|
||||||
|
uint8_t rval, wval;
|
||||||
|
int ret;
|
||||||
|
uint8_t buf[ARRAY_LENGTH_MAX];
|
||||||
|
|
||||||
|
ret = spmi_ext_register_readl(mt6316_dev, MT6316_PMIC_RG_PSEQ_ELR_RSV2_ADDR, &rval, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
return;
|
||||||
|
rval = (rval >> MT6316_PMIC_RG_PSEQ_ELR_RSV2_SHIFT) & MT6316_PMIC_RG_PSEQ_ELR_RSV2_MASK;
|
||||||
|
|
||||||
|
if (!(rval & PSEQ_ELR_RSV2_VAL_MASK_1)) {
|
||||||
|
wval = VI075_SINK_CUR_SOURCE_1;
|
||||||
|
} else if (rval & PSEQ_ELR_RSV2_VAL_MASK_2) {
|
||||||
|
if (en_seq_off)
|
||||||
|
wval = VI075_SINK_CUR_SOURCE_2;
|
||||||
|
else
|
||||||
|
wval = VI075_SINK_CUR_SOURCE_3;
|
||||||
|
} else {
|
||||||
|
wval = VI075_SINK_CUR_SOURCE_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = 0xDC;
|
||||||
|
buf[1] = 0xF1;
|
||||||
|
spmi_ext_register_writel(mt6316_dev,
|
||||||
|
MT6316_TOP_ANA_KEY,
|
||||||
|
&buf[0], 2); /* unlock TOP_ANA key */
|
||||||
|
spmi_ext_register_writel_field(mt6316_dev,
|
||||||
|
MT6316_PMIC_RG_VI075_SINK_CUR_ADDR, wval,
|
||||||
|
MT6316_PMIC_RG_VI075_SINK_CUR_MASK,
|
||||||
|
MT6316_PMIC_RG_VI075_SINK_CUR_SHIFT);
|
||||||
|
buf[0] = 0;
|
||||||
|
buf[1] = 0;
|
||||||
|
spmi_ext_register_writel(mt6316_dev,
|
||||||
|
MT6316_TOP_ANA_KEY,
|
||||||
|
&buf[0], 2); /* lock TOP_ANA key */
|
||||||
|
mt6316_key_lock_check(mt6316_dev, MT6316_TOP_ANA_KEY);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int pmic_shutdown_cfg_init(void)
|
||||||
|
{
|
||||||
|
uint8_t i, slvid;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(cfg_arr); i++) {
|
||||||
|
slvid = cfg_arr[i].slvid;
|
||||||
|
if (sdev_arr[slvid] != NULL)
|
||||||
|
continue;
|
||||||
|
sdev_arr[slvid] = get_spmi_device(MASTER_ID, slvid);
|
||||||
|
if (!sdev_arr[slvid])
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
MTK_PLAT_SETUP_0_INIT(pmic_shutdown_cfg_init);
|
||||||
|
|
||||||
|
int pmic_shutdown_cfg(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint8_t i, slvid;
|
||||||
|
uint32_t addr;
|
||||||
|
uint8_t val;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(cfg_arr); i++) {
|
||||||
|
slvid = cfg_arr[i].slvid;
|
||||||
|
if (!sdev_arr[slvid])
|
||||||
|
return -ENODEV;
|
||||||
|
/* mt6316 vio075 sink current adjustment */
|
||||||
|
if ((slvid >= SPMI_SLAVE_6 && slvid <= SPMI_SLAVE_8) || slvid == SPMI_SLAVE_15)
|
||||||
|
wk_vio075_sink_cur(sdev_arr[slvid], 1);
|
||||||
|
addr = cfg_arr[i].addr;
|
||||||
|
val = cfg_arr[i].val;
|
||||||
|
/* Disable WDTRSTB_EN */
|
||||||
|
if (addr) {
|
||||||
|
ret = spmi_ext_register_writel(sdev_arr[slvid], addr, &val, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set RG_SHUTDOWN_SRC_SEL to 1, shutdown PMIC by SPMI command */
|
||||||
|
spmi_ext_register_writel_field(sdev_arr[slvid],
|
||||||
|
cfg_arr[i].shutdown_src_addr, 1,
|
||||||
|
cfg_arr[i].shutdown_src_mask,
|
||||||
|
cfg_arr[i].shutdown_src_shift);
|
||||||
|
}
|
||||||
|
return 1; /* 1: use spmi_command_shutdown API */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* shutdown PMIC by SPMI command */
|
||||||
|
int spmi_shutdown(void)
|
||||||
|
{
|
||||||
|
struct spmi_device *mt6363_sdev = get_spmi_device(SPMI_MASTER_1, SPMI_SLAVE_4);
|
||||||
|
|
||||||
|
if (!mt6363_sdev)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
/* set RG_SHUTDOWN_SRC_SEL to 1 */
|
||||||
|
spmi_ext_register_writel_field(mt6363_sdev, 0x408, 1, 0x1, 1);
|
||||||
|
spmi_command_shutdown(SPMI_MASTER_P_1, mt6363_sdev, 0x800);
|
||||||
|
spmi_command_shutdown(SPMI_MASTER_1, mt6363_sdev, 0x800);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
15
plat/mediatek/drivers/pmic/mt8196/pmic_swap_api.c
Normal file
15
plat/mediatek/drivers/pmic/mt8196/pmic_swap_api.c
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <drivers/pmic/pmic_swap_api.h>
|
||||||
|
|
||||||
|
/* No need to check second pmic mt6373 */
|
||||||
|
bool is_second_pmic_pp_swap(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
15
plat/mediatek/drivers/pmic/pmic_common_swap_api.c
Normal file
15
plat/mediatek/drivers/pmic/pmic_common_swap_api.c
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <drivers/pmic/pmic_swap_api.h>
|
||||||
|
|
||||||
|
#pragma weak is_second_pmic_pp_swap
|
||||||
|
|
||||||
|
bool is_second_pmic_pp_swap(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
117
plat/mediatek/drivers/pmic/pmic_psc.c
Normal file
117
plat/mediatek/drivers/pmic/pmic_psc.c
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <common/debug.h>
|
||||||
|
#include <drivers/pmic/pmic_psc.h>
|
||||||
|
#ifdef CONFIG_MTK_PMIC_SHUTDOWN_CFG
|
||||||
|
#include <drivers/pmic/pmic_shutdown_cfg.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ERR_INVALID_ARGS -EINVAL
|
||||||
|
#define ERR_NOT_CONFIGURED -ENODEV
|
||||||
|
|
||||||
|
static const struct pmic_psc_config *pmic_psc;
|
||||||
|
|
||||||
|
static uint32_t read_pmic_psc_reg(enum pmic_psc_reg_name reg_name)
|
||||||
|
{
|
||||||
|
uint32_t val = 0;
|
||||||
|
const struct pmic_psc_reg *reg;
|
||||||
|
|
||||||
|
if (reg_name >= pmic_psc->reg_size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
reg = &pmic_psc->regs[reg_name];
|
||||||
|
pmic_psc->read_field(reg->reg_addr, &val, reg->reg_mask, reg->reg_shift);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_pmic_psc_reg(enum pmic_psc_reg_name reg_name)
|
||||||
|
{
|
||||||
|
const struct pmic_psc_reg *reg;
|
||||||
|
|
||||||
|
if (reg_name >= pmic_psc->reg_size)
|
||||||
|
return ERR_INVALID_ARGS;
|
||||||
|
|
||||||
|
reg = &pmic_psc->regs[reg_name];
|
||||||
|
pmic_psc->write_field(reg->reg_addr, 1, reg->reg_mask, reg->reg_shift);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int clr_pmic_psc_reg(enum pmic_psc_reg_name reg_name)
|
||||||
|
{
|
||||||
|
const struct pmic_psc_reg *reg;
|
||||||
|
|
||||||
|
if (reg_name >= pmic_psc->reg_size)
|
||||||
|
return ERR_INVALID_ARGS;
|
||||||
|
|
||||||
|
reg = &pmic_psc->regs[reg_name];
|
||||||
|
pmic_psc->write_field(reg->reg_addr, 0, reg->reg_mask, reg->reg_shift);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int enable_pmic_smart_reset(bool enable)
|
||||||
|
{
|
||||||
|
if (!pmic_psc)
|
||||||
|
return ERR_NOT_CONFIGURED;
|
||||||
|
if (enable)
|
||||||
|
set_pmic_psc_reg(RG_SMART_RST_MODE);
|
||||||
|
else
|
||||||
|
clr_pmic_psc_reg(RG_SMART_RST_MODE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int enable_pmic_smart_reset_shutdown(bool enable)
|
||||||
|
{
|
||||||
|
if (!pmic_psc)
|
||||||
|
return ERR_NOT_CONFIGURED;
|
||||||
|
if (enable)
|
||||||
|
set_pmic_psc_reg(RG_SMART_RST_SDN_EN);
|
||||||
|
else
|
||||||
|
clr_pmic_psc_reg(RG_SMART_RST_SDN_EN);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int platform_cold_reset(void)
|
||||||
|
{
|
||||||
|
if (!pmic_psc)
|
||||||
|
return ERR_NOT_CONFIGURED;
|
||||||
|
/* Some PMICs may not support cold reset */
|
||||||
|
if (!pmic_psc->regs[RG_CRST].reg_addr)
|
||||||
|
return ERR_NOT_CONFIGURED;
|
||||||
|
set_pmic_psc_reg(RG_CRST);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int platform_power_hold(bool hold)
|
||||||
|
{
|
||||||
|
int use_spmi_cmd_sdn = 0;
|
||||||
|
|
||||||
|
if (!pmic_psc)
|
||||||
|
return ERR_NOT_CONFIGURED;
|
||||||
|
if (hold)
|
||||||
|
set_pmic_psc_reg(RG_PWRHOLD);
|
||||||
|
else {
|
||||||
|
#ifdef CONFIG_MTK_PMIC_SHUTDOWN_CFG
|
||||||
|
use_spmi_cmd_sdn = pmic_shutdown_cfg();
|
||||||
|
#endif
|
||||||
|
if (use_spmi_cmd_sdn == 1)
|
||||||
|
spmi_shutdown();
|
||||||
|
else
|
||||||
|
clr_pmic_psc_reg(RG_PWRHOLD);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pmic_psc_register(const struct pmic_psc_config *psc)
|
||||||
|
{
|
||||||
|
if (!psc || !psc->regs || !psc->read_field || !psc->write_field)
|
||||||
|
return ERR_INVALID_ARGS;
|
||||||
|
pmic_psc = psc;
|
||||||
|
INFO("POWER_HOLD=0x%x\n", read_pmic_psc_reg(RG_PWRHOLD));
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2022, MediaTek Inc. All rights reserved.
|
# Copyright (c) 2022-2025, MediaTek Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
#
|
#
|
||||||
|
@ -8,8 +8,24 @@ LOCAL_DIR := $(call GET_LOCAL_DIR)
|
||||||
|
|
||||||
MODULE := pmic
|
MODULE := pmic
|
||||||
|
|
||||||
|
ifneq (${PMIC_CHIP}, mt6363)
|
||||||
LOCAL_SRCS-y += ${LOCAL_DIR}/pmic.c
|
LOCAL_SRCS-y += ${LOCAL_DIR}/pmic.c
|
||||||
|
|
||||||
PLAT_INCLUDES += -I${LOCAL_DIR}/
|
PLAT_INCLUDES += -I${LOCAL_DIR}/
|
||||||
|
else
|
||||||
|
LOCAL_SRCS-y := ${LOCAL_DIR}/pmic_psc.c
|
||||||
|
LOCAL_SRCS-y += ${LOCAL_DIR}/pmic_common_swap_api.c
|
||||||
|
LOCAL_SRCS-${CONFIG_MTK_PMIC_LOWPOWER} += ${LOCAL_DIR}/${MTK_SOC}/pmic_lowpower_init.c
|
||||||
|
LOCAL_SRCS-${CONFIG_MTK_PMIC_LOWPOWER} += ${LOCAL_DIR}/${MTK_SOC}/pmic_swap_api.c
|
||||||
|
LOCAL_SRCS-${CONFIG_MTK_PMIC_SHUTDOWN_CFG} += ${LOCAL_DIR}/${MTK_SOC}/pmic_shutdown_cfg.c
|
||||||
|
endif
|
||||||
|
|
||||||
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
|
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
|
||||||
|
$(eval $(call add_defined_option,CONFIG_MTK_PMIC_SPT_SUPPORT))
|
||||||
|
$(eval $(call add_defined_option,CONFIG_MTK_PMIC_SHUTDOWN_CFG))
|
||||||
|
|
||||||
|
#Include sub rules.mk
|
||||||
|
ifneq (${PMIC_CHIP},)
|
||||||
|
SUB_RULES-y := $(LOCAL_DIR)/$(PMIC_CHIP)
|
||||||
|
#Expand sub rules.mk
|
||||||
|
$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
|
||||||
|
endif
|
||||||
|
|
27
plat/mediatek/drivers/spm/common/dbg_ctrl.h
Normal file
27
plat/mediatek/drivers/spm/common/dbg_ctrl.h
Normal 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 */
|
53
plat/mediatek/drivers/spm/common/mt_spm_common.h
Normal file
53
plat/mediatek/drivers/spm/common/mt_spm_common.h
Normal 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 */
|
91
plat/mediatek/drivers/spm/common/mt_spm_constraint.h
Normal file
91
plat/mediatek/drivers/spm/common/mt_spm_constraint.h
Normal 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 */
|
100
plat/mediatek/drivers/spm/common/mt_spm_smc.h
Normal file
100
plat/mediatek/drivers/spm/common/mt_spm_smc.h
Normal 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 */
|
18
plat/mediatek/drivers/spm/common/rules.mk
Normal file
18
plat/mediatek/drivers/spm/common/rules.mk
Normal 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))
|
158
plat/mediatek/drivers/spm/mt8196/constraints/mt_spm_rc_api.c
Normal file
158
plat/mediatek/drivers/spm/mt8196/constraints/mt_spm_rc_api.c
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <constraints/mt_spm_rc_api.h>
|
||||||
|
#include <constraints/mt_spm_rc_internal.h>
|
||||||
|
#include <lpm_v2/mt_lpm_smc.h>
|
||||||
|
#include <mt_plat_spm_setting.h>
|
||||||
|
#include <mt_spm.h>
|
||||||
|
#include <mt_spm_common.h>
|
||||||
|
|
||||||
|
#define SPM_RC_VALID_SET(dest, src) ({ (dest) |= (src); })
|
||||||
|
#define SPM_RC_VALID_CLR(dest, src) ({ (dest) &= ~(src); })
|
||||||
|
|
||||||
|
int spm_rc_constraint_status_get(uint32_t id, uint32_t type,
|
||||||
|
uint32_t act,
|
||||||
|
enum mt_spm_rm_rc_type dest_rc_id,
|
||||||
|
struct constraint_status * const src,
|
||||||
|
struct constraint_status * const dest)
|
||||||
|
{
|
||||||
|
if (((id != MT_RM_CONSTRAINT_ID_ALL) &&
|
||||||
|
(id != dest_rc_id)) || !dest || !src)
|
||||||
|
return -1;
|
||||||
|
spm_lock_get();
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case CONSTRAINT_GET_ENTER_CNT:
|
||||||
|
if (id == MT_RM_CONSTRAINT_ID_ALL)
|
||||||
|
dest->enter_cnt += src->enter_cnt;
|
||||||
|
else
|
||||||
|
dest->enter_cnt = src->enter_cnt;
|
||||||
|
break;
|
||||||
|
case CONSTRAINT_GET_VALID:
|
||||||
|
dest->is_valid = src->is_valid;
|
||||||
|
break;
|
||||||
|
case CONSTRAINT_COND_BLOCK:
|
||||||
|
dest->is_cond_block = src->is_cond_block;
|
||||||
|
dest->all_pll_dump = src->all_pll_dump;
|
||||||
|
break;
|
||||||
|
case CONSTRAINT_GET_COND_BLOCK_DETAIL:
|
||||||
|
dest->cond_res = src->cond_res;
|
||||||
|
break;
|
||||||
|
case CONSTRAINT_GET_RESIDNECY:
|
||||||
|
dest->residency = src->residency;
|
||||||
|
if (act & MT_LPM_SMC_ACT_CLR)
|
||||||
|
src->residency = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
spm_lock_release();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_rc_constraint_status_set(uint32_t id, uint32_t type,
|
||||||
|
uint32_t act,
|
||||||
|
enum mt_spm_rm_rc_type dest_rc_id,
|
||||||
|
struct constraint_status * const src,
|
||||||
|
struct constraint_status * const dest)
|
||||||
|
{
|
||||||
|
if (((id != MT_RM_CONSTRAINT_ID_ALL) &&
|
||||||
|
(id != dest_rc_id)) || !dest)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
spm_lock_get();
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case CONSTRAINT_UPDATE_VALID:
|
||||||
|
if (src) {
|
||||||
|
if (act & MT_LPM_SMC_ACT_SET)
|
||||||
|
SPM_RC_VALID_SET(dest->is_valid, src->is_valid);
|
||||||
|
else if (act & MT_LPM_SMC_ACT_CLR)
|
||||||
|
SPM_RC_VALID_CLR(dest->is_valid, src->is_valid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CONSTRAINT_RESIDNECY:
|
||||||
|
if (act & MT_LPM_SMC_ACT_CLR)
|
||||||
|
dest->residency = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
spm_lock_release();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_rc_constraint_valid_set(enum mt_spm_rm_rc_type id,
|
||||||
|
enum mt_spm_rm_rc_type dest_rc_id,
|
||||||
|
uint32_t valid,
|
||||||
|
struct constraint_status * const dest)
|
||||||
|
{
|
||||||
|
if (((id != MT_RM_CONSTRAINT_ID_ALL) &&
|
||||||
|
(id != dest_rc_id)) || !dest)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
spm_lock_get();
|
||||||
|
SPM_RC_VALID_SET(dest->is_valid, valid);
|
||||||
|
spm_lock_release();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_rc_constraint_valid_clr(enum mt_spm_rm_rc_type id,
|
||||||
|
enum mt_spm_rm_rc_type dest_rc_id,
|
||||||
|
uint32_t valid,
|
||||||
|
struct constraint_status * const dest)
|
||||||
|
{
|
||||||
|
if (((id != MT_RM_CONSTRAINT_ID_ALL) &&
|
||||||
|
(id != dest_rc_id)) || !dest)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
spm_lock_get();
|
||||||
|
SPM_RC_VALID_CLR(dest->is_valid, valid);
|
||||||
|
spm_lock_release();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CIRQ will respresent interrupt which type is edge
|
||||||
|
* when gic mask. But if the 26 clk have turned off before
|
||||||
|
* then cirq won't work normally.
|
||||||
|
* So we need to set irq pending for specific wakeup source.
|
||||||
|
*/
|
||||||
|
#ifndef MTK_PLAT_CIRQ_UNSUPPORT
|
||||||
|
static void mt_spm_irq_remain_dump(struct mt_irqremain *irqs,
|
||||||
|
uint32_t irq_index,
|
||||||
|
struct wake_status *wakeup)
|
||||||
|
{
|
||||||
|
INFO("[SPM] r12=0x%08x(0x%08x), irq:%u(0x%08x) set pending\n",
|
||||||
|
wakeup->tr.comm.r12,
|
||||||
|
wakeup->md32pcm_wakeup_sta,
|
||||||
|
irqs->wakeupsrc[irq_index],
|
||||||
|
irqs->irqs[irq_index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_irqs_delivery(struct mt_irqremain *irqs,
|
||||||
|
struct wake_status *wakeup)
|
||||||
|
{
|
||||||
|
uint32_t idx;
|
||||||
|
|
||||||
|
if (!irqs || !wakeup)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (idx = 0; idx < irqs->count; idx++) {
|
||||||
|
if ((wakeup->tr.comm.raw_sta & irqs->wakeupsrc[idx]) ||
|
||||||
|
(wakeup->tr.comm.r12 & irqs->wakeupsrc[idx])) {
|
||||||
|
if ((irqs->wakeupsrc_cat[idx] & MT_IRQ_REMAIN_CAT_LOG))
|
||||||
|
mt_spm_irq_remain_dump(irqs, idx, wakeup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
84
plat/mediatek/drivers/spm/mt8196/constraints/mt_spm_rc_api.h
Normal file
84
plat/mediatek/drivers/spm/mt8196/constraints/mt_spm_rc_api.h
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_SPM_RC_API_H
|
||||||
|
#define MT_SPM_RC_API_H
|
||||||
|
|
||||||
|
#include <constraints/mt_spm_trace.h>
|
||||||
|
#include <mt_spm.h>
|
||||||
|
#include <mt_spm_constraint.h>
|
||||||
|
#include <mt_spm_internal.h>
|
||||||
|
|
||||||
|
enum mt_spm_rm_rc_type {
|
||||||
|
MT_RM_CONSTRAINT_ID_VCORE,
|
||||||
|
MT_RM_CONSTRAINT_ID_BUS26,
|
||||||
|
MT_RM_CONSTRAINT_ID_SYSPL,
|
||||||
|
MT_RM_CONSTRAINT_ID_ALL = 0xff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum mt_spm_rc_fp_type {
|
||||||
|
MT_SPM_RC_FP_INIT = 0,
|
||||||
|
MT_SPM_RC_FP_ENTER_START,
|
||||||
|
MT_SPM_RC_FP_ENTER_NOTIFY,
|
||||||
|
MT_SPM_RC_FP_ENTER_WAKE_SPM_BEFORE,
|
||||||
|
MT_SPM_RC_FP_ENTER_WAKE_SPM_AFTER,
|
||||||
|
MT_SPM_RC_FP_RESUME_START,
|
||||||
|
MT_SPM_RC_FP_RESUME_NOTIFY,
|
||||||
|
MT_SPM_RC_FP_RESUME_RESET_SPM_BEFORE,
|
||||||
|
MT_SPM_RC_FP_RESUME_BACKUP_EDGE_INT,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MT_SPM_RC_INFO(_cpu, _stateid, _rc_id) ({ \
|
||||||
|
MT_SPM_TRACE_COMMON_U32_WR(MT_SPM_TRACE_COMM_RC_INFO, \
|
||||||
|
((_cpu) << 28) | \
|
||||||
|
(((_stateid) & 0xffff) << 12) | \
|
||||||
|
((_rc_id) & 0xfff)); })
|
||||||
|
|
||||||
|
#define MT_SPM_RC_LAST_TIME(_time) ({ \
|
||||||
|
MT_SPM_TRACE_COMMON_U32_WR(MT_SPM_TRACE_COMM_RC_LAST_TIME_H, \
|
||||||
|
(uint32_t)((_time) >> 32)); \
|
||||||
|
MT_SPM_TRACE_COMMON_U32_WR(MT_SPM_TRACE_COMM_RC_LAST_TIME_L, \
|
||||||
|
(uint32_t)((_time) & 0xffffffff)); })
|
||||||
|
|
||||||
|
#define MT_SPM_RC_TAG(_cpu, _stateid, _rc_id) \
|
||||||
|
MT_SPM_RC_INFO(_cpu, _stateid, _rc_id)
|
||||||
|
|
||||||
|
#define MT_SPM_RC_FP(fp) ({ \
|
||||||
|
MT_SPM_TRACE_COMMON_U32_WR(MT_SPM_TRACE_COMM_RC_FP, fp); })
|
||||||
|
|
||||||
|
#define MT_SPM_RC_TAG_VALID(_valid) ({ \
|
||||||
|
MT_SPM_TRACE_COMMON_U32_WR(MT_SPM_TRACE_COMM_RC_VALID, _valid); })
|
||||||
|
|
||||||
|
int spm_rc_constraint_status_get(uint32_t id, uint32_t type,
|
||||||
|
uint32_t act,
|
||||||
|
enum mt_spm_rm_rc_type dest_rc_id,
|
||||||
|
struct constraint_status * const src,
|
||||||
|
struct constraint_status * const dest);
|
||||||
|
|
||||||
|
int spm_rc_constraint_status_set(uint32_t id, uint32_t type,
|
||||||
|
uint32_t act,
|
||||||
|
enum mt_spm_rm_rc_type dest_rc_id,
|
||||||
|
struct constraint_status * const src,
|
||||||
|
struct constraint_status * const dest);
|
||||||
|
|
||||||
|
int spm_rc_constraint_valid_set(enum mt_spm_rm_rc_type id,
|
||||||
|
enum mt_spm_rm_rc_type dest_rc_id,
|
||||||
|
uint32_t valid,
|
||||||
|
struct constraint_status * const dest);
|
||||||
|
|
||||||
|
int spm_rc_constraint_valid_clr(enum mt_spm_rm_rc_type id,
|
||||||
|
enum mt_spm_rm_rc_type dest_rc_id,
|
||||||
|
uint32_t valid,
|
||||||
|
struct constraint_status * const dest);
|
||||||
|
|
||||||
|
#ifdef MTK_PLAT_CIRQ_UNSUPPORT
|
||||||
|
#define do_irqs_delivery(_x, _w)
|
||||||
|
#else
|
||||||
|
void do_irqs_delivery(struct mt_irqremain *irqs,
|
||||||
|
struct wake_status *wakeup);
|
||||||
|
#endif /* MTK_PLAT_CIRQ_UNSUPPORT */
|
||||||
|
|
||||||
|
#endif /* MT_SPM_RC_API_H */
|
255
plat/mediatek/drivers/spm/mt8196/constraints/mt_spm_rc_bus26m.c
Normal file
255
plat/mediatek/drivers/spm/mt8196/constraints/mt_spm_rc_bus26m.c
Normal file
|
@ -0,0 +1,255 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <common/debug.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/pm/mtk_pm.h>
|
||||||
|
#include <lpm_v2/mt_lp_rm.h>
|
||||||
|
#include <mt_plat_spm_setting.h>
|
||||||
|
#include <mt_spm.h>
|
||||||
|
#include <mt_spm_conservation.h>
|
||||||
|
#include <mt_spm_constraint.h>
|
||||||
|
#include <mt_spm_idle.h>
|
||||||
|
#include <mt_spm_internal.h>
|
||||||
|
#include <mt_spm_pmic_lp.h>
|
||||||
|
#include <mt_spm_reg.h>
|
||||||
|
#include <mt_spm_suspend.h>
|
||||||
|
#include <notifier/inc/mt_spm_notifier.h>
|
||||||
|
|
||||||
|
#define CONSTRAINT_BUS26M_ALLOW (MT_RM_CONSTRAINT_ALLOW_CPU_BUCK_OFF | \
|
||||||
|
MT_RM_CONSTRAINT_ALLOW_DRAM_S0 | \
|
||||||
|
MT_RM_CONSTRAINT_ALLOW_DRAM_S1 | \
|
||||||
|
MT_RM_CONSTRAINT_ALLOW_VCORE_LP | \
|
||||||
|
MT_RM_CONSTRAINT_ALLOW_LVTS_STATE | \
|
||||||
|
MT_RM_CONSTRAINT_ALLOW_BUS26M_OFF)
|
||||||
|
|
||||||
|
#define CONSTRAINT_BUS26M_PCM_FLAG (SPM_FLAG_DISABLE_VCORE_DVS | \
|
||||||
|
SPM_FLAG_DISABLE_DDR_DFS | \
|
||||||
|
SPM_FLAG_DISABLE_EMI_DFS | \
|
||||||
|
SPM_FLAG_DISABLE_BUS_DFS | \
|
||||||
|
SPM_FLAG_ENABLE_AOV | \
|
||||||
|
SPM_FLAG_DISABLE_VLP_PDN | \
|
||||||
|
SPM_FLAG_SRAM_SLEEP_CTRL | \
|
||||||
|
SPM_FLAG_KEEP_CSYSPWRACK_HIGH)
|
||||||
|
|
||||||
|
#define CONSTRAINT_BUS26M_PCM_FLAG1 (SPM_FLAG1_ENABLE_ALCO_TRACE)
|
||||||
|
/*
|
||||||
|
* If sspm sram won't enter sleep voltage
|
||||||
|
* then vcore couldn't enter low power mode
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(MTK_PLAT_SPM_SRAM_SLP_UNSUPPORT) && SPM_SRAM_SLEEP_RC_RES_RESTRICT
|
||||||
|
#define CONSTRAINT_BUS26M_RESOURCE_REQ (MT_SPM_26M | MT_SPM_VCORE)
|
||||||
|
#else
|
||||||
|
#define CONSTRAINT_BUS26M_RESOURCE_REQ (MT_SPM_VCORE)
|
||||||
|
#endif
|
||||||
|
static uint32_t bus26m_ext_opand;
|
||||||
|
static struct mt_irqremain *refer2remain_irq;
|
||||||
|
static uint32_t cmd;
|
||||||
|
|
||||||
|
static struct constraint_status status = {
|
||||||
|
.id = MT_RM_CONSTRAINT_ID_BUS26,
|
||||||
|
.is_valid = (MT_SPM_RC_VALID_SW |
|
||||||
|
MT_SPM_RC_VALID_FW |
|
||||||
|
MT_SPM_RC_VALID_TRACE_TIME |
|
||||||
|
MT_SPM_RC_VALID_NOTIFY),
|
||||||
|
.enter_cnt = 0,
|
||||||
|
.all_pll_dump = 0,
|
||||||
|
.residency = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
int spm_bus26m_conduct(int state_id, struct spm_lp_scen *spm_lp,
|
||||||
|
uint32_t *resource_req)
|
||||||
|
{
|
||||||
|
if ((spm_lp == NULL) || (resource_req == NULL))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
struct pwr_ctrl *pwrctrl = spm_lp->pwrctrl;
|
||||||
|
|
||||||
|
pwrctrl->pcm_flags = CONSTRAINT_BUS26M_PCM_FLAG;
|
||||||
|
pwrctrl->pcm_flags1 = CONSTRAINT_BUS26M_PCM_FLAG1;
|
||||||
|
|
||||||
|
*resource_req |= CONSTRAINT_BUS26M_RESOURCE_REQ;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool spm_is_valid_rc_bus26m(uint32_t cpu, int state_id)
|
||||||
|
{
|
||||||
|
return (IS_MT_RM_RC_READY(status.is_valid) &&
|
||||||
|
!(bus26m_ext_opand & (MT_BUS26M_EXT_LP_26M_ON_MODE)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_update_rc_bus26m(int state_id, int type, const void *val)
|
||||||
|
{
|
||||||
|
int res = MT_RM_STATUS_OK;
|
||||||
|
uint32_t flag = *(uint32_t *)val;
|
||||||
|
|
||||||
|
if (type == PLAT_RC_UPDATE_REMAIN_IRQS) {
|
||||||
|
refer2remain_irq = (struct mt_irqremain *)val;
|
||||||
|
} else if (type == PLAT_RC_IS_FMAUDIO) {
|
||||||
|
if (flag)
|
||||||
|
bus26m_ext_opand |= MT_SPM_EX_OP_SET_IS_FM_AUDIO;
|
||||||
|
else
|
||||||
|
bus26m_ext_opand &= ~MT_SPM_EX_OP_SET_IS_FM_AUDIO;
|
||||||
|
} else if (type == PLAT_RC_IS_ADSP) {
|
||||||
|
if (flag)
|
||||||
|
bus26m_ext_opand |= MT_SPM_EX_OP_SET_IS_ADSP;
|
||||||
|
else
|
||||||
|
bus26m_ext_opand &= ~MT_SPM_EX_OP_SET_IS_ADSP;
|
||||||
|
} else if (type == PLAT_RC_IS_USB_HEADSET) {
|
||||||
|
if (flag)
|
||||||
|
bus26m_ext_opand |= MT_SPM_EX_OP_SET_IS_USB_HEADSET;
|
||||||
|
else
|
||||||
|
bus26m_ext_opand &= ~MT_SPM_EX_OP_SET_IS_USB_HEADSET;
|
||||||
|
} else if (type == PLAT_RC_STATUS) {
|
||||||
|
const struct rc_common_state *st;
|
||||||
|
|
||||||
|
st = (const struct rc_common_state *)val;
|
||||||
|
|
||||||
|
if (!st)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((st->type == CONSTRAINT_UPDATE_VALID) ||
|
||||||
|
(st->type == CONSTRAINT_RESIDNECY))
|
||||||
|
spm_rc_constraint_status_set(st->id,
|
||||||
|
st->type, st->act,
|
||||||
|
MT_RM_CONSTRAINT_ID_BUS26,
|
||||||
|
st->value,
|
||||||
|
&status);
|
||||||
|
else
|
||||||
|
INFO("[%s:%d] - Unknown type: 0x%x\n",
|
||||||
|
__func__, __LINE__, st->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t spm_allow_rc_bus26m(int state_id)
|
||||||
|
{
|
||||||
|
return CONSTRAINT_BUS26M_ALLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_run_rc_bus26m(uint32_t cpu, int state_id)
|
||||||
|
{
|
||||||
|
uint32_t ext_op = MT_SPM_EX_OP_HW_S1_DETECT |
|
||||||
|
MT_SPM_EX_OP_NOTIFY_INFRA_OFF;
|
||||||
|
uint32_t nb_type = MT_SPM_NOTIFY_IDLE_ENTER;
|
||||||
|
|
||||||
|
MT_SPM_RC_TAG(cpu, state_id, MT_RM_CONSTRAINT_ID_BUS26);
|
||||||
|
MT_SPM_RC_TAG_VALID(status.is_valid);
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_ENTER_START);
|
||||||
|
|
||||||
|
cmd = CONSTRAINT_BUS26M_ALLOW;
|
||||||
|
|
||||||
|
if (IS_PLAT_SUSPEND_ID(state_id)) {
|
||||||
|
cmd |= (MT_RM_CONSTRAINT_ALLOW_AP_PLAT_SUSPEND |
|
||||||
|
MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND);
|
||||||
|
ext_op |= (MT_SPM_EX_OP_CLR_26M_RECORD |
|
||||||
|
MT_SPM_EX_OP_SET_WDT);
|
||||||
|
|
||||||
|
if (IS_MT_SPM_RC_NOTIFY_ENABLE(status.is_valid))
|
||||||
|
mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_SUSPEND_VCORE, 0);
|
||||||
|
} else {
|
||||||
|
if (status.is_valid & MT_SPM_RC_VALID_TRACE_TIME)
|
||||||
|
ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MTK_SPM_PMIC_LP_SUPPORT
|
||||||
|
do_spm_low_power(SPM_LP_ENTER, cmd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_ENTER_NOTIFY);
|
||||||
|
|
||||||
|
if (IS_MT_SPM_RC_NOTIFY_ENABLE(status.is_valid))
|
||||||
|
mt_spm_sspm_notify_u32(nb_type, cmd);
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_ENTER_WAKE_SPM_BEFORE);
|
||||||
|
|
||||||
|
if (IS_PLAT_SUSPEND_ID(state_id))
|
||||||
|
mt_spm_suspend_enter(state_id, ext_op,
|
||||||
|
CONSTRAINT_BUS26M_RESOURCE_REQ);
|
||||||
|
else
|
||||||
|
mt_spm_idle_generic_enter(state_id, ext_op,
|
||||||
|
spm_bus26m_conduct);
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_ENTER_WAKE_SPM_AFTER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_reset_rc_bus26m(uint32_t cpu, int state_id)
|
||||||
|
{
|
||||||
|
struct wake_status *waken = NULL;
|
||||||
|
uint32_t ext_op = MT_SPM_EX_OP_HW_S1_DETECT |
|
||||||
|
MT_SPM_EX_OP_NOTIFY_INFRA_OFF;
|
||||||
|
uint32_t nb_type = MT_SPM_NOTIFY_IDLE_LEAVE;
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_RESUME_START);
|
||||||
|
|
||||||
|
if (IS_PLAT_SUSPEND_ID(state_id)) {
|
||||||
|
ext_op |= MT_SPM_EX_OP_SET_WDT;
|
||||||
|
} else {
|
||||||
|
if (status.is_valid & MT_SPM_RC_VALID_TRACE_TIME)
|
||||||
|
ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN;
|
||||||
|
|
||||||
|
if (spm_unlikely(status.is_valid &
|
||||||
|
MT_SPM_RC_VALID_TRACE_EVENT))
|
||||||
|
ext_op |= MT_SPM_EX_OP_TRACE_LP;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MTK_SPM_PMIC_LP_SUPPORT
|
||||||
|
do_spm_low_power(SPM_LP_RESUME, cmd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_RESUME_NOTIFY);
|
||||||
|
|
||||||
|
if (IS_MT_SPM_RC_NOTIFY_ENABLE(status.is_valid))
|
||||||
|
mt_spm_sspm_notify_u32(nb_type, 0);
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_RESUME_RESET_SPM_BEFORE);
|
||||||
|
|
||||||
|
if (IS_PLAT_SUSPEND_ID(state_id)) {
|
||||||
|
mt_spm_suspend_resume(state_id, ext_op, &waken);
|
||||||
|
bus26m_ext_opand = 0;
|
||||||
|
} else {
|
||||||
|
mt_spm_idle_generic_resume(state_id, ext_op, &waken, NULL);
|
||||||
|
status.enter_cnt++;
|
||||||
|
|
||||||
|
if (spm_unlikely(status.is_valid & MT_SPM_RC_VALID_RESIDNECY))
|
||||||
|
status.residency += waken ?
|
||||||
|
waken->tr.comm.timer_out : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_RESUME_BACKUP_EDGE_INT);
|
||||||
|
do_irqs_delivery(refer2remain_irq, waken);
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_INIT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_get_status_rc_bus26m(uint32_t type, void *priv)
|
||||||
|
{
|
||||||
|
int ret = MT_RM_STATUS_OK;
|
||||||
|
|
||||||
|
if (type == PLAT_RC_STATUS) {
|
||||||
|
struct rc_common_state *st = (struct rc_common_state *)priv;
|
||||||
|
|
||||||
|
if (!st)
|
||||||
|
return MT_RM_STATUS_BAD;
|
||||||
|
|
||||||
|
ret = spm_rc_constraint_status_get(st->id, st->type,
|
||||||
|
st->act,
|
||||||
|
MT_RM_CONSTRAINT_ID_BUS26,
|
||||||
|
&status,
|
||||||
|
st->value);
|
||||||
|
if (!ret && (st->id != MT_RM_CONSTRAINT_ID_ALL))
|
||||||
|
ret = MT_RM_STATUS_STOP;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_SPM_RC_INTERNAL_H
|
||||||
|
#define MT_SPM_RC_INTERNAL_H
|
||||||
|
|
||||||
|
#include <sleep_def.h>
|
||||||
|
|
||||||
|
#define SPM_SRAM_SLEEP_DEFAULT_FLAG (SPM_FLAG_DISABLE_SSPM_SRAM_SLEEP)
|
||||||
|
|
||||||
|
#ifdef MTK_PLAT_SPM_SRAM_SLP_UNSUPPORT
|
||||||
|
#define SPM_FLAG_SRAM_SLEEP_CTRL (SPM_FLAG_DISABLE_SSPM_SRAM_SLEEP)
|
||||||
|
#else
|
||||||
|
#define SPM_FLAG_SRAM_SLEEP_CTRL (SPM_SRAM_SLEEP_DEFAULT_FLAG)
|
||||||
|
#endif
|
||||||
|
#define SPM_SRAM_SLEEP_RC_RES_RESTRICT 0
|
||||||
|
|
||||||
|
#define SPM_RC_UPDATE_COND_ID_MASK 0xffff
|
||||||
|
#define SPM_RC_UPDATE_COND_RC_ID_MASK 0xffff
|
||||||
|
#define SPM_RC_UPDATE_COND_RC_ID_SHIFT 16
|
||||||
|
|
||||||
|
#define SPM_RC_UPDATE_COND_RC_ID_GET(val) \
|
||||||
|
(((val) >> SPM_RC_UPDATE_COND_RC_ID_SHIFT) & \
|
||||||
|
SPM_RC_UPDATE_COND_RC_ID_MASK)
|
||||||
|
|
||||||
|
#define SPM_RC_UPDATE_COND_ID_GET(val) \
|
||||||
|
((val) & SPM_RC_UPDATE_COND_ID_MASK)
|
||||||
|
|
||||||
|
/* CPU buck/ldo constraint function */
|
||||||
|
int spm_is_valid_rc_cpu_buck_ldo(int cpu, int state_id);
|
||||||
|
int spm_update_rc_cpu_buck_ldo(int state_id, int type,
|
||||||
|
const void *val);
|
||||||
|
uint32_t spm_allow_rc_cpu_buck_ldo(int state_id);
|
||||||
|
int spm_run_rc_cpu_buck_ldo(int cpu, int state_id);
|
||||||
|
int spm_reset_rc_cpu_buck_ldo(int cpu, int state_id);
|
||||||
|
int spm_get_status_rc_cpu_buck_ldo(uint32_t type, void *priv);
|
||||||
|
|
||||||
|
/* SPM resource syspll constraint function */
|
||||||
|
bool spm_is_valid_rc_syspll(uint32_t cpu, int state_id);
|
||||||
|
int spm_update_rc_syspll(int state_id, int type, const void *val);
|
||||||
|
uint32_t spm_allow_rc_syspll(int state_id);
|
||||||
|
int spm_run_rc_syspll(uint32_t cpu, int state_id);
|
||||||
|
int spm_reset_rc_syspll(uint32_t cpu, int state_id);
|
||||||
|
int spm_get_status_rc_syspll(uint32_t type, void *priv);
|
||||||
|
|
||||||
|
/* SPM resource bus26m constraint function */
|
||||||
|
bool spm_is_valid_rc_bus26m(uint32_t cpu, int state_id);
|
||||||
|
int spm_update_rc_bus26m(int state_id, int type, const void *val);
|
||||||
|
uint32_t spm_allow_rc_bus26m(int state_id);
|
||||||
|
int spm_run_rc_bus26m(uint32_t cpu, int state_id);
|
||||||
|
int spm_reset_rc_bus26m(uint32_t cpu, int state_id);
|
||||||
|
int spm_get_status_rc_bus26m(uint32_t type, void *priv);
|
||||||
|
|
||||||
|
/* SPM resource vcore constraint function */
|
||||||
|
bool spm_is_valid_rc_vcore(uint32_t cpu, int state_id);
|
||||||
|
int spm_update_rc_vcore(int state_id, int type, const void *val);
|
||||||
|
uint32_t spm_allow_rc_vcore(int state_id);
|
||||||
|
int spm_run_rc_vcore(uint32_t cpu, int state_id);
|
||||||
|
int spm_reset_rc_vcore(uint32_t cpu, int state_id);
|
||||||
|
int spm_get_status_rc_vcore(uint32_t type, void *priv);
|
||||||
|
|
||||||
|
#endif /* MT_SPM_RC_INTERNAL_H */
|
260
plat/mediatek/drivers/spm/mt8196/constraints/mt_spm_rc_syspll.c
Normal file
260
plat/mediatek/drivers/spm/mt8196/constraints/mt_spm_rc_syspll.c
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <common/debug.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/pm/mtk_pm.h>
|
||||||
|
#include <lpm_v2/mt_lp_api.h>
|
||||||
|
#include <lpm_v2/mt_lp_rm.h>
|
||||||
|
#include <mt_plat_spm_setting.h>
|
||||||
|
#include <mt_spm.h>
|
||||||
|
#include <mt_spm_conservation.h>
|
||||||
|
#include <mt_spm_constraint.h>
|
||||||
|
#include <mt_spm_idle.h>
|
||||||
|
#include <mt_spm_internal.h>
|
||||||
|
#include <mt_spm_pmic_lp.h>
|
||||||
|
#include <mt_spm_reg.h>
|
||||||
|
#include <mt_spm_suspend.h>
|
||||||
|
#include <notifier/inc/mt_spm_notifier.h>
|
||||||
|
|
||||||
|
#define CONSTRAINT_SYSPLL_ALLOW (MT_RM_CONSTRAINT_ALLOW_CPU_BUCK_OFF | \
|
||||||
|
MT_RM_CONSTRAINT_ALLOW_DRAM_S0 | \
|
||||||
|
MT_RM_CONSTRAINT_ALLOW_DRAM_S1 | \
|
||||||
|
MT_RM_CONSTRAINT_ALLOW_VCORE_LP | \
|
||||||
|
MT_RM_CONSTRAINT_ALLOW_LVTS_STATE)
|
||||||
|
|
||||||
|
#define CONSTRAINT_SYSPLL_PCM_FLAG (SPM_FLAG_DISABLE_VCORE_DVS | \
|
||||||
|
SPM_FLAG_DISABLE_DDR_DFS | \
|
||||||
|
SPM_FLAG_DISABLE_EMI_DFS | \
|
||||||
|
SPM_FLAG_DISABLE_BUS_DFS | \
|
||||||
|
SPM_FLAG_ENABLE_AOV | \
|
||||||
|
SPM_FLAG_DISABLE_VLP_PDN | \
|
||||||
|
SPM_FLAG_SRAM_SLEEP_CTRL | \
|
||||||
|
SPM_FLAG_KEEP_CSYSPWRACK_HIGH)
|
||||||
|
|
||||||
|
#define CONSTRAINT_SYSPLL_PCM_FLAG1 (SPM_FLAG1_ENABLE_ALCO_TRACE)
|
||||||
|
|
||||||
|
#define CONSTRAINT_SYSPLL_RESOURCE_REQ (MT_SPM_26M | \
|
||||||
|
MT_SPM_VCORE | MT_SPM_INFRA)
|
||||||
|
|
||||||
|
#define CHECK_VAL(val, sys_state) \
|
||||||
|
((val) ? !!(*((uint32_t *)(val)) == (sys_state)) : 0)
|
||||||
|
|
||||||
|
static uint32_t cmd;
|
||||||
|
|
||||||
|
static struct constraint_status status = {
|
||||||
|
.id = MT_RM_CONSTRAINT_ID_SYSPL,
|
||||||
|
.is_valid = (MT_SPM_RC_VALID_SW |
|
||||||
|
MT_SPM_RC_VALID_FW |
|
||||||
|
MT_SPM_RC_VALID_NOTIFY),
|
||||||
|
.enter_cnt = 0,
|
||||||
|
.residency = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
int spm_syspll_conduct(int state_id, struct spm_lp_scen *spm_lp,
|
||||||
|
uint32_t *resource_req)
|
||||||
|
{
|
||||||
|
if ((spm_lp == NULL) || (resource_req == NULL))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
struct pwr_ctrl *pwrctrl = spm_lp->pwrctrl;
|
||||||
|
|
||||||
|
pwrctrl->pcm_flags = CONSTRAINT_SYSPLL_PCM_FLAG;
|
||||||
|
pwrctrl->pcm_flags1 = CONSTRAINT_SYSPLL_PCM_FLAG1;
|
||||||
|
|
||||||
|
*resource_req |= CONSTRAINT_SYSPLL_RESOURCE_REQ;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool spm_is_valid_rc_syspll(uint32_t cpu, int state_id)
|
||||||
|
{
|
||||||
|
return IS_MT_RM_RC_READY(status.is_valid);
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_update_rc_syspll(int state_id, int type, const void *val)
|
||||||
|
{
|
||||||
|
int res = MT_RM_STATUS_OK;
|
||||||
|
|
||||||
|
if (type == PLAT_RC_CLKBUF_STATUS) {
|
||||||
|
bool is_flight = CHECK_VAL(val, FLIGHT_MODE_ON);
|
||||||
|
|
||||||
|
if (is_flight)
|
||||||
|
spm_rc_constraint_valid_set(MT_RM_CONSTRAINT_ID_SYSPL,
|
||||||
|
MT_RM_CONSTRAINT_ID_SYSPL,
|
||||||
|
MT_SPM_RC_VALID_FLIGHTMODE,
|
||||||
|
&status);
|
||||||
|
else
|
||||||
|
spm_rc_constraint_valid_clr(MT_RM_CONSTRAINT_ID_SYSPL,
|
||||||
|
MT_RM_CONSTRAINT_ID_SYSPL,
|
||||||
|
MT_SPM_RC_VALID_FLIGHTMODE,
|
||||||
|
&status);
|
||||||
|
} else if (type == PLAT_RC_UFS_STATUS) {
|
||||||
|
uint32_t is_ufs_h8 = CHECK_VAL(val, UFS_REF_CLK_OFF);
|
||||||
|
|
||||||
|
if (is_ufs_h8)
|
||||||
|
spm_rc_constraint_valid_set(MT_RM_CONSTRAINT_ID_SYSPL,
|
||||||
|
MT_RM_CONSTRAINT_ID_SYSPL,
|
||||||
|
MT_SPM_RC_VALID_UFS_H8,
|
||||||
|
&status);
|
||||||
|
else
|
||||||
|
spm_rc_constraint_valid_clr(MT_RM_CONSTRAINT_ID_SYSPL,
|
||||||
|
MT_RM_CONSTRAINT_ID_SYSPL,
|
||||||
|
MT_SPM_RC_VALID_UFS_H8,
|
||||||
|
&status);
|
||||||
|
} else if (type == PLAT_RC_STATUS) {
|
||||||
|
const struct rc_common_state *st;
|
||||||
|
|
||||||
|
st = (const struct rc_common_state *)val;
|
||||||
|
|
||||||
|
if (!st)
|
||||||
|
return 0;
|
||||||
|
if ((st->type == CONSTRAINT_UPDATE_VALID) ||
|
||||||
|
(st->type == CONSTRAINT_RESIDNECY))
|
||||||
|
spm_rc_constraint_status_set(st->id, st->type,
|
||||||
|
st->act,
|
||||||
|
MT_RM_CONSTRAINT_ID_SYSPL,
|
||||||
|
st->value,
|
||||||
|
&status);
|
||||||
|
else
|
||||||
|
INFO("[%s:%d] - Unknown type: 0x%x\n",
|
||||||
|
__func__, __LINE__, st->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t spm_allow_rc_syspll(int state_id)
|
||||||
|
{
|
||||||
|
return CONSTRAINT_SYSPLL_ALLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_run_rc_syspll(uint32_t cpu, int state_id)
|
||||||
|
{
|
||||||
|
uint32_t ext_op = MT_SPM_EX_OP_HW_S1_DETECT |
|
||||||
|
MT_SPM_EX_OP_NOTIFY_INFRA_OFF;
|
||||||
|
uint32_t nb_type = MT_SPM_NOTIFY_IDLE_ENTER;
|
||||||
|
|
||||||
|
MT_SPM_RC_TAG(cpu, state_id, MT_RM_CONSTRAINT_ID_SYSPL);
|
||||||
|
MT_SPM_RC_TAG_VALID(status.is_valid);
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_ENTER_START);
|
||||||
|
|
||||||
|
cmd = CONSTRAINT_SYSPLL_ALLOW;
|
||||||
|
|
||||||
|
if (IS_PLAT_SUSPEND_ID(state_id)) {
|
||||||
|
cmd |= MT_RM_CONSTRAINT_ALLOW_AP_PLAT_SUSPEND;
|
||||||
|
ext_op |= (MT_SPM_EX_OP_CLR_26M_RECORD |
|
||||||
|
MT_SPM_EX_OP_SET_WDT);
|
||||||
|
} else {
|
||||||
|
if (status.is_valid & MT_SPM_RC_VALID_TRACE_TIME)
|
||||||
|
ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN;
|
||||||
|
|
||||||
|
if (!IS_MT_PLAT_PWR_STATE(state_id,
|
||||||
|
MT_PLAT_PWR_STATE_SYSTEM_PLL)) {
|
||||||
|
nb_type = MT_SPM_NOTIFY_IDLE_ENTER;
|
||||||
|
ext_op &= ~MT_SPM_EX_OP_NOTIFY_INFRA_OFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MTK_SPM_PMIC_LP_SUPPORT
|
||||||
|
do_spm_low_power(SPM_LP_ENTER, cmd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_ENTER_NOTIFY);
|
||||||
|
|
||||||
|
if (IS_MT_SPM_RC_NOTIFY_ENABLE(status.is_valid))
|
||||||
|
mt_spm_sspm_notify_u32(nb_type, cmd);
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_ENTER_WAKE_SPM_BEFORE);
|
||||||
|
|
||||||
|
if (IS_PLAT_SUSPEND_ID(state_id))
|
||||||
|
mt_spm_suspend_enter(state_id, ext_op,
|
||||||
|
CONSTRAINT_SYSPLL_RESOURCE_REQ);
|
||||||
|
else
|
||||||
|
mt_spm_idle_generic_enter(state_id, ext_op, spm_syspll_conduct);
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_ENTER_WAKE_SPM_AFTER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_reset_rc_syspll(uint32_t cpu, int state_id)
|
||||||
|
{
|
||||||
|
uint32_t ext_op = MT_SPM_EX_OP_HW_S1_DETECT |
|
||||||
|
MT_SPM_EX_OP_NOTIFY_INFRA_OFF;
|
||||||
|
uint32_t nb_type = MT_SPM_NOTIFY_IDLE_LEAVE;
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_RESUME_START);
|
||||||
|
|
||||||
|
if (IS_PLAT_SUSPEND_ID(state_id)) {
|
||||||
|
ext_op |= (MT_SPM_EX_OP_SET_WDT);
|
||||||
|
} else {
|
||||||
|
if (status.is_valid & MT_SPM_RC_VALID_TRACE_TIME)
|
||||||
|
ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN;
|
||||||
|
|
||||||
|
if (spm_unlikely(status.is_valid &
|
||||||
|
MT_SPM_RC_VALID_TRACE_EVENT))
|
||||||
|
ext_op |= MT_SPM_EX_OP_TRACE_LP;
|
||||||
|
|
||||||
|
if (!IS_MT_PLAT_PWR_STATE(state_id,
|
||||||
|
MT_PLAT_PWR_STATE_SYSTEM_PLL)) {
|
||||||
|
nb_type = MT_SPM_NOTIFY_IDLE_LEAVE;
|
||||||
|
ext_op &= ~MT_SPM_EX_OP_NOTIFY_INFRA_OFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MTK_SPM_PMIC_LP_SUPPORT
|
||||||
|
do_spm_low_power(SPM_LP_RESUME, cmd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_RESUME_NOTIFY);
|
||||||
|
|
||||||
|
if (IS_MT_SPM_RC_NOTIFY_ENABLE(status.is_valid))
|
||||||
|
mt_spm_sspm_notify_u32(nb_type, cmd);
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_RESUME_RESET_SPM_BEFORE);
|
||||||
|
|
||||||
|
if (IS_PLAT_SUSPEND_ID(state_id))
|
||||||
|
mt_spm_suspend_resume(state_id, ext_op, NULL);
|
||||||
|
else {
|
||||||
|
struct wake_status *waken = NULL;
|
||||||
|
|
||||||
|
mt_spm_idle_generic_resume(state_id, ext_op, &waken, NULL);
|
||||||
|
status.enter_cnt++;
|
||||||
|
|
||||||
|
if (spm_unlikely(status.is_valid & MT_SPM_RC_VALID_RESIDNECY))
|
||||||
|
status.residency += waken ?
|
||||||
|
waken->tr.comm.timer_out : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_INIT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_get_status_rc_syspll(uint32_t type, void *priv)
|
||||||
|
{
|
||||||
|
int ret = MT_RM_STATUS_OK;
|
||||||
|
|
||||||
|
if (type == PLAT_RC_STATUS) {
|
||||||
|
int res = 0;
|
||||||
|
struct rc_common_state *st = (struct rc_common_state *)priv;
|
||||||
|
|
||||||
|
if (!st)
|
||||||
|
return MT_RM_STATUS_BAD;
|
||||||
|
|
||||||
|
res = spm_rc_constraint_status_get(st->id, st->type,
|
||||||
|
st->act,
|
||||||
|
MT_RM_CONSTRAINT_ID_SYSPL,
|
||||||
|
&status,
|
||||||
|
st->value);
|
||||||
|
if (!res && (st->id != MT_RM_CONSTRAINT_ID_ALL))
|
||||||
|
ret = MT_RM_STATUS_STOP;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
266
plat/mediatek/drivers/spm/mt8196/constraints/mt_spm_rc_vcore.c
Normal file
266
plat/mediatek/drivers/spm/mt8196/constraints/mt_spm_rc_vcore.c
Normal file
|
@ -0,0 +1,266 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <common/debug.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/pm/mtk_pm.h>
|
||||||
|
#include <lpm_v2/mt_lp_rm.h>
|
||||||
|
#include <lpm_v2/mt_lp_rqm.h>
|
||||||
|
#include <mt_plat_spm_setting.h>
|
||||||
|
#include <mt_spm.h>
|
||||||
|
#include <mt_spm_conservation.h>
|
||||||
|
#include <mt_spm_constraint.h>
|
||||||
|
#include <mt_spm_idle.h>
|
||||||
|
#include <mt_spm_internal.h>
|
||||||
|
#include <mt_spm_pmic_lp.h>
|
||||||
|
#include <mt_spm_reg.h>
|
||||||
|
#include <mt_spm_suspend.h>
|
||||||
|
#include <notifier/inc/mt_spm_notifier.h>
|
||||||
|
|
||||||
|
#define ERROW_TEST
|
||||||
|
|
||||||
|
#define CONSTRAINT_VCORE_ALLOW (MT_RM_CONSTRAINT_ALLOW_CPU_BUCK_OFF | \
|
||||||
|
MT_RM_CONSTRAINT_ALLOW_DRAM_S0 | \
|
||||||
|
MT_RM_CONSTRAINT_ALLOW_DRAM_S1 | \
|
||||||
|
MT_RM_CONSTRAINT_ALLOW_VCORE_LP | \
|
||||||
|
MT_RM_CONSTRAINT_ALLOW_LVTS_STATE | \
|
||||||
|
MT_RM_CONSTRAINT_ALLOW_BUS26M_OFF | \
|
||||||
|
MT_RM_CONSTRAINT_ALLOW_VCORE_OFF)
|
||||||
|
|
||||||
|
#define CONSTRAINT_VCORE_PCM_FLAG (SPM_FLAG_DISABLE_VCORE_DVS | \
|
||||||
|
SPM_FLAG_DISABLE_DDR_DFS | \
|
||||||
|
SPM_FLAG_DISABLE_EMI_DFS | \
|
||||||
|
SPM_FLAG_DISABLE_BUS_DFS | \
|
||||||
|
SPM_FLAG_DISABLE_VLP_PDN | \
|
||||||
|
SPM_FLAG_DISABLE_BUS_DFS | \
|
||||||
|
SPM_FLAG_ENABLE_AOV | \
|
||||||
|
SPM_FLAG_SRAM_SLEEP_CTRL)
|
||||||
|
|
||||||
|
#define CONSTRAINT_VCORE_PCM_FLAG1 (SPM_FLAG1_ENABLE_ALCO_TRACE)
|
||||||
|
|
||||||
|
#if defined(MTK_PLAT_SPM_SRAM_SLP_UNSUPPORT) && SPM_SRAM_SLEEP_RC_RES_RESTRICT
|
||||||
|
#define CONSTRAINT_VCORE_RESOURCE_REQ (MT_SPM_26M | MT_SPM_VCORE)
|
||||||
|
#else
|
||||||
|
#define CONSTRAINT_VCORE_RESOURCE_REQ 0
|
||||||
|
#endif
|
||||||
|
static uint32_t vcore_ext_opand;
|
||||||
|
static struct mt_irqremain *refer2remain_irq;
|
||||||
|
static uint32_t cmd;
|
||||||
|
|
||||||
|
static struct constraint_status status = {
|
||||||
|
.id = MT_RM_CONSTRAINT_ID_VCORE,
|
||||||
|
.is_valid = (MT_SPM_RC_VALID_SW |
|
||||||
|
MT_SPM_RC_VALID_FW |
|
||||||
|
MT_SPM_RC_VALID_TRACE_TIME |
|
||||||
|
MT_SPM_RC_VALID_NOTIFY),
|
||||||
|
.enter_cnt = 0,
|
||||||
|
.all_pll_dump = 0,
|
||||||
|
.residency = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
int spm_vcore_conduct(int state_id, struct spm_lp_scen *spm_lp,
|
||||||
|
uint32_t *resource_req)
|
||||||
|
{
|
||||||
|
if ((spm_lp == NULL) || (resource_req == NULL))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
struct pwr_ctrl *pwrctrl = spm_lp->pwrctrl;
|
||||||
|
|
||||||
|
pwrctrl->pcm_flags = CONSTRAINT_VCORE_PCM_FLAG;
|
||||||
|
pwrctrl->pcm_flags1 = CONSTRAINT_VCORE_PCM_FLAG1;
|
||||||
|
|
||||||
|
*resource_req |= CONSTRAINT_VCORE_RESOURCE_REQ;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool spm_is_valid_rc_vcore(uint32_t cpu, int state_id)
|
||||||
|
{
|
||||||
|
uint32_t vcore_ext = vcore_ext_opand &
|
||||||
|
(MT_VCORE_EXT_LP_VCORE_ON_MODE);
|
||||||
|
|
||||||
|
return (IS_MT_RM_RC_READY(status.is_valid) &&
|
||||||
|
IS_MT_PLAT_PWR_STATE(state_id,
|
||||||
|
MT_PLAT_PWR_STATE_SYSTEM_VCORE) &&
|
||||||
|
!vcore_ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_update_rc_vcore(int state_id, int type, const void *val)
|
||||||
|
{
|
||||||
|
int res = MT_RM_STATUS_OK;
|
||||||
|
uint32_t flag = *(uint32_t *)val;
|
||||||
|
|
||||||
|
if (type == PLAT_RC_UPDATE_REMAIN_IRQS) {
|
||||||
|
refer2remain_irq = (struct mt_irqremain *)val;
|
||||||
|
} else if (type == PLAT_RC_IS_FMAUDIO) {
|
||||||
|
if (flag)
|
||||||
|
vcore_ext_opand |= MT_SPM_EX_OP_SET_IS_FM_AUDIO;
|
||||||
|
else
|
||||||
|
vcore_ext_opand &= ~MT_SPM_EX_OP_SET_IS_FM_AUDIO;
|
||||||
|
} else if (type == PLAT_RC_IS_ADSP) {
|
||||||
|
if (flag)
|
||||||
|
vcore_ext_opand |= MT_SPM_EX_OP_SET_IS_ADSP;
|
||||||
|
else
|
||||||
|
vcore_ext_opand &= ~MT_SPM_EX_OP_SET_IS_ADSP;
|
||||||
|
} else if (type == PLAT_RC_IS_USB_HEADSET) {
|
||||||
|
if (flag)
|
||||||
|
vcore_ext_opand |= MT_SPM_EX_OP_SET_IS_USB_HEADSET;
|
||||||
|
else
|
||||||
|
vcore_ext_opand &= ~MT_SPM_EX_OP_SET_IS_USB_HEADSET;
|
||||||
|
} else if (type == PLAT_RC_STATUS) {
|
||||||
|
const struct rc_common_state *st;
|
||||||
|
|
||||||
|
st = (const struct rc_common_state *)val;
|
||||||
|
|
||||||
|
if (!st)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if ((st->type == CONSTRAINT_UPDATE_VALID) ||
|
||||||
|
(st->type == CONSTRAINT_RESIDNECY))
|
||||||
|
spm_rc_constraint_status_set(st->id,
|
||||||
|
st->type, st->act,
|
||||||
|
MT_RM_CONSTRAINT_ID_VCORE,
|
||||||
|
st->value,
|
||||||
|
&status);
|
||||||
|
else
|
||||||
|
INFO("[%s:%d] - Unknown type: 0x%x\n",
|
||||||
|
__func__, __LINE__, st->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t spm_allow_rc_vcore(int state_id)
|
||||||
|
{
|
||||||
|
return CONSTRAINT_VCORE_ALLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_run_rc_vcore(uint32_t cpu, int state_id)
|
||||||
|
{
|
||||||
|
uint32_t ext_op = (MT_SPM_EX_OP_HW_S1_DETECT |
|
||||||
|
MT_SPM_EX_OP_DEVICES_SAVE |
|
||||||
|
MT_SPM_EX_OP_TRACE_TIMESTAMP_EN |
|
||||||
|
MT_SPM_EX_OP_NOTIFY_INFRA_OFF);
|
||||||
|
|
||||||
|
uint32_t spm_lp_notify_mode;
|
||||||
|
|
||||||
|
MT_SPM_RC_TAG(cpu, state_id, MT_RM_CONSTRAINT_ID_VCORE);
|
||||||
|
MT_SPM_RC_TAG_VALID(status.is_valid);
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_ENTER_START);
|
||||||
|
|
||||||
|
cmd = CONSTRAINT_VCORE_ALLOW | MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND;
|
||||||
|
|
||||||
|
spm_lp_notify_mode = MT_SPM_NOTIFY_LP_ENTER;
|
||||||
|
|
||||||
|
if (IS_PLAT_SUSPEND_ID(state_id)) {
|
||||||
|
cmd |= (MT_RM_CONSTRAINT_ALLOW_AP_PLAT_SUSPEND);
|
||||||
|
ext_op |= (MT_SPM_EX_OP_CLR_26M_RECORD |
|
||||||
|
MT_SPM_EX_OP_SET_WDT);
|
||||||
|
|
||||||
|
if (IS_MT_SPM_RC_NOTIFY_ENABLE(status.is_valid))
|
||||||
|
mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_SUSPEND_VCORE, 0);
|
||||||
|
} else {
|
||||||
|
if (!(status.is_valid & MT_SPM_RC_VALID_TRACE_TIME))
|
||||||
|
ext_op &= ~MT_SPM_EX_OP_TRACE_TIMESTAMP_EN;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MTK_SPM_PMIC_LP_SUPPORT
|
||||||
|
do_spm_low_power(SPM_LP_ENTER, cmd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_ENTER_NOTIFY);
|
||||||
|
|
||||||
|
if (IS_MT_SPM_RC_NOTIFY_ENABLE(status.is_valid))
|
||||||
|
mt_spm_sspm_notify_u32(spm_lp_notify_mode, cmd);
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_ENTER_WAKE_SPM_BEFORE);
|
||||||
|
|
||||||
|
if (IS_PLAT_SUSPEND_ID(state_id))
|
||||||
|
mt_spm_suspend_enter(state_id, ext_op, 0);
|
||||||
|
else
|
||||||
|
mt_spm_idle_generic_enter(state_id, ext_op,
|
||||||
|
spm_vcore_conduct);
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_ENTER_WAKE_SPM_AFTER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_reset_rc_vcore(uint32_t cpu, int state_id)
|
||||||
|
{
|
||||||
|
struct wake_status *waken = NULL;
|
||||||
|
uint32_t ext_op = (MT_SPM_EX_OP_HW_S1_DETECT |
|
||||||
|
MT_SPM_EX_OP_DEVICES_SAVE |
|
||||||
|
MT_SPM_EX_OP_TRACE_LP |
|
||||||
|
MT_SPM_EX_OP_NOTIFY_INFRA_OFF);
|
||||||
|
uint32_t spm_lp_notify_mode;
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_RESUME_START);
|
||||||
|
|
||||||
|
spm_lp_notify_mode = MT_SPM_NOTIFY_LP_LEAVE;
|
||||||
|
|
||||||
|
if (IS_PLAT_SUSPEND_ID(state_id)) {
|
||||||
|
ext_op |= MT_SPM_EX_OP_SET_WDT;
|
||||||
|
} else {
|
||||||
|
if (status.is_valid & MT_SPM_RC_VALID_TRACE_TIME)
|
||||||
|
ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN;
|
||||||
|
|
||||||
|
if (spm_unlikely(!(status.is_valid &
|
||||||
|
MT_SPM_RC_VALID_TRACE_EVENT)))
|
||||||
|
ext_op &= ~MT_SPM_EX_OP_TRACE_LP;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MTK_SPM_PMIC_LP_SUPPORT
|
||||||
|
do_spm_low_power(SPM_LP_RESUME, cmd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_RESUME_NOTIFY);
|
||||||
|
|
||||||
|
if (IS_MT_SPM_RC_NOTIFY_ENABLE(status.is_valid))
|
||||||
|
mt_spm_sspm_notify_u32(spm_lp_notify_mode, 0);
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_RESUME_RESET_SPM_BEFORE);
|
||||||
|
|
||||||
|
if (IS_PLAT_SUSPEND_ID(state_id)) {
|
||||||
|
mt_spm_suspend_resume(state_id, ext_op, &waken);
|
||||||
|
vcore_ext_opand = 0;
|
||||||
|
} else {
|
||||||
|
mt_spm_idle_generic_resume(state_id, ext_op, &waken, NULL);
|
||||||
|
status.enter_cnt++;
|
||||||
|
|
||||||
|
if (spm_unlikely(status.is_valid & MT_SPM_RC_VALID_RESIDNECY))
|
||||||
|
status.residency += waken ?
|
||||||
|
waken->tr.comm.timer_out : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_RESUME_BACKUP_EDGE_INT);
|
||||||
|
do_irqs_delivery(refer2remain_irq, waken);
|
||||||
|
MT_SPM_RC_FP(MT_SPM_RC_FP_INIT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_get_status_rc_vcore(uint32_t type, void *priv)
|
||||||
|
{
|
||||||
|
int ret = MT_RM_STATUS_OK;
|
||||||
|
|
||||||
|
if (type == PLAT_RC_STATUS) {
|
||||||
|
struct rc_common_state *st = (struct rc_common_state *)priv;
|
||||||
|
|
||||||
|
if (!st)
|
||||||
|
return MT_RM_STATUS_BAD;
|
||||||
|
|
||||||
|
ret = spm_rc_constraint_status_get(st->id, st->type,
|
||||||
|
st->act,
|
||||||
|
MT_RM_CONSTRAINT_ID_VCORE,
|
||||||
|
&status,
|
||||||
|
st->value);
|
||||||
|
if (!ret && (st->id != MT_RM_CONSTRAINT_ID_ALL))
|
||||||
|
ret = MT_RM_STATUS_STOP;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
157
plat/mediatek/drivers/spm/mt8196/constraints/mt_spm_trace.h
Normal file
157
plat/mediatek/drivers/spm/mt8196/constraints/mt_spm_trace.h
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_SPM_TRACE_H
|
||||||
|
#define MT_SPM_TRACE_H
|
||||||
|
|
||||||
|
#include <lib/mmio.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
enum mt_spm_sysram_type {
|
||||||
|
MT_SPM_SYSRAM_COMMON,
|
||||||
|
MT_SPM_SYSRAM_SUSPEND,
|
||||||
|
MT_SPM_SYSRAM_LP,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* SPM trace common type */
|
||||||
|
enum mt_spm_trace_common_type {
|
||||||
|
MT_SPM_TRACE_COMM_HAED,
|
||||||
|
MT_SPM_TRACE_COMM_FP,
|
||||||
|
MT_SPM_TRACE_COMM_RC_LAST_TIME_H,
|
||||||
|
MT_SPM_TRACE_COMM_RC_LAST_TIME_L,
|
||||||
|
MT_SPM_TRACE_COMM_RC_INFO,
|
||||||
|
MT_SPM_TRACE_COMM_RC_FP,
|
||||||
|
MT_SPM_TRACE_COMM_RC_VALID,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* SPM trace suspend type */
|
||||||
|
enum mt_spm_trace_suspend_type {
|
||||||
|
MT_SPM_TRACE_SUSPEND_WAKE_SRC,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPM sram usage with mcdi sram
|
||||||
|
* start offset : 0x500
|
||||||
|
*/
|
||||||
|
#define MT_SPM_SYSRAM_BASE (MTK_LPM_SRAM_BASE + 0x500)
|
||||||
|
#define MT_SPM_SYSRAM_COMM_BASE MT_SPM_SYSRAM_BASE
|
||||||
|
#define MT_SPM_SYSRAM_COMM_SZ 0x20
|
||||||
|
|
||||||
|
#define MT_SPM_SYSRAM_SUSPEND_BASE \
|
||||||
|
(MT_SPM_SYSRAM_BASE + MT_SPM_SYSRAM_COMM_SZ)
|
||||||
|
#define MT_SPM_SYSRAM_SUSPEND_SZ 0xe0
|
||||||
|
|
||||||
|
#define MT_SPM_SYSRAM_LP_BASE \
|
||||||
|
(MT_SPM_SYSRAM_SUSPEND_BASE + MT_SPM_SYSRAM_SUSPEND_SZ)
|
||||||
|
|
||||||
|
#define MT_SPM_SYSRAM_SLOT(slot) ((slot) << 2u)
|
||||||
|
|
||||||
|
#ifndef MTK_PLAT_SPM_TRACE_UNSUPPORT
|
||||||
|
|
||||||
|
#define MT_SPM_SYSRAM_W(_s, type, val, _sz) \
|
||||||
|
mt_spm_sysram_write(_s, type, val, _sz)
|
||||||
|
|
||||||
|
#define MT_SPM_SYSRAM_R_U32(addr, val) ({ \
|
||||||
|
unsigned int *r_val = (unsigned int *)val; \
|
||||||
|
if (r_val) \
|
||||||
|
*r_val = mmio_read_32(addr); })
|
||||||
|
|
||||||
|
#define MT_SPM_SYSRAM_R(_s, type, val) \
|
||||||
|
mt_spm_sysram_read(_s, type, val)
|
||||||
|
|
||||||
|
/* SPM trace common */
|
||||||
|
#define MT_SPM_TRACE_INIT(_magic) ({ \
|
||||||
|
mt_spm_sysram_init(_magic); })
|
||||||
|
|
||||||
|
#define MT_SPM_TRACE_COMMON_U32_WR(_type, _val) ({ \
|
||||||
|
mmio_write_32((MT_SPM_SYSRAM_COMM_BASE + \
|
||||||
|
MT_SPM_SYSRAM_SLOT(_type)), _val); })
|
||||||
|
|
||||||
|
#define MT_SPM_TRACE_COMMON_WR(_type, val, _sz) ({ \
|
||||||
|
int ret = MT_SPM_SYSRAM_W(MT_SPM_SYSRAM_COMMON, \
|
||||||
|
_type, val, _sz); ret; })
|
||||||
|
|
||||||
|
#define MT_SPM_TRACE_COMMON_U32_RD(_type, _val) ({ \
|
||||||
|
MT_SPM_SYSRAM_R_U32((MT_SPM_SYSRAM_COMM_BASE + \
|
||||||
|
MT_SPM_SYSRAM_SLOT(_type)), _val); })
|
||||||
|
|
||||||
|
#define MT_SPM_TRACE_COMMON_RD(_type, _val) ({ \
|
||||||
|
int ret = MT_SPM_SYSRAM_R(MT_SPM_SYSRAM_COMMON, \
|
||||||
|
_type, _val); ret; })
|
||||||
|
|
||||||
|
/* SPM trace suspend */
|
||||||
|
#define MT_SPM_TRACE_SUSPEND_U32_WR(_type, _val) ({ \
|
||||||
|
mmio_write_32((MT_SPM_SYSRAM_SUSPEND_BASE + \
|
||||||
|
MT_SPM_SYSRAM_SLOT(_type)), _val); })
|
||||||
|
|
||||||
|
#define MT_SPM_TRACE_SUSPEND_WR(_type, _val, _sz) ({ \
|
||||||
|
int ret = MT_SPM_SYSRAM_W(MT_SPM_SYSRAM_SUSPEND, \
|
||||||
|
_type, _val, _sz); ret; })
|
||||||
|
|
||||||
|
#define MT_SPM_TRACE_SUSPEND_U32_RD(_type, _val) ({\
|
||||||
|
MT_SPM_SYSRAM_R_U32((MT_SPM_SYSRAM_SUSPEND_BASE + \
|
||||||
|
MT_SPM_SYSRAM_SLOT(_type)), _val); })
|
||||||
|
|
||||||
|
#define MT_SPM_TRACE_SUSPEND_RD(_type, _val) ({ \
|
||||||
|
int ret = MT_SPM_SYSRAM_R(MT_SPM_SYSRAM_SUSPEND, \
|
||||||
|
_type, _val); ret; })
|
||||||
|
|
||||||
|
/* SPM trace low power */
|
||||||
|
#define MT_SPM_TRACE_LP_U32_WR(_type, _val) ({ \
|
||||||
|
mmio_write_32((MT_SPM_SYSRAM_LP_BASE + \
|
||||||
|
MT_SPM_SYSRAM_SLOT(_type)), _val); })
|
||||||
|
|
||||||
|
#define MT_SPM_TRACE_LP_WR(_type, _val, _sz) ({ \
|
||||||
|
int ret = MT_SPM_SYSRAM_W(MT_SPM_SYSRAM_LP, \
|
||||||
|
_type, _val, _sz); ret; })
|
||||||
|
|
||||||
|
#define MT_SPM_TRACE_LP_U32_RD(_type, _val) ({ \
|
||||||
|
MT_SPM_SYSRAM_R_U32((MT_SPM_SYSRAM_LP_BASE + \
|
||||||
|
MT_SPM_SYSRAM_SLOT(_type)), _val); })
|
||||||
|
|
||||||
|
#define MT_SPM_TRACE_LP_RD(_type, _val) ({ \
|
||||||
|
int ret = MT_SPM_SYSRAM_R(MT_SPM_SYSRAM_LP, \
|
||||||
|
_type, _val); ret; })
|
||||||
|
|
||||||
|
#define MT_SPM_TRACE_LP_RINGBUF(_pval, _sz) ({ \
|
||||||
|
int ret = mt_spm_sysram_lp_ringbuf_add(_pval, _sz); ret; })
|
||||||
|
|
||||||
|
int mt_spm_sysram_lp_ringbuf_add(const void *val, unsigned int sz);
|
||||||
|
|
||||||
|
int mt_spm_sysram_write(int section, int type, const void *val,
|
||||||
|
unsigned int sz);
|
||||||
|
int mt_spm_sysram_read(int section, int type, void *val);
|
||||||
|
|
||||||
|
int mt_spm_sysram_init(unsigned int magic);
|
||||||
|
#else
|
||||||
|
/* SPM trace common */
|
||||||
|
#define MT_SPM_TRACE_INIT(_magic)
|
||||||
|
#define MT_SPM_TRACE_COMMON_U32_WR(type, val)
|
||||||
|
#define MT_SPM_TRACE_COMMON_WR(val)
|
||||||
|
#define MT_SPM_TRACE_COMMON_U32_RD(type, val)
|
||||||
|
#define MT_SPM_TRACE_COMMON_RD(val)
|
||||||
|
|
||||||
|
/* SPM trace suspend */
|
||||||
|
#define MT_SPM_TRACE_SUSPEND_U32_WR(type, val)
|
||||||
|
#define MT_SPM_TRACE_SUSPEND_WR(val)
|
||||||
|
#define MT_SPM_TRACE_SUSPEND_U32_RD(type, val)
|
||||||
|
#define MT_SPM_TRACE_SUSPEND_RD(val)
|
||||||
|
|
||||||
|
/* SPM trace low power */
|
||||||
|
#define MT_SPM_TRACE_LP_U32_WR(type, val)
|
||||||
|
#define MT_SPM_TRACE_LP_WR(val)
|
||||||
|
#define MT_SPM_TRACE_LP_U32_RD(type, val)
|
||||||
|
#define MT_SPM_TRACE_LP_RD(val)
|
||||||
|
#define MT_SPM_TRACE_LP_RINGBUF(pval, sz)
|
||||||
|
|
||||||
|
#define mt_spm_sysram_lp_ringbuf_add(_val, _sz)
|
||||||
|
#define mt_spm_sysram_write(_s, _type, _val, _sz)
|
||||||
|
#define mt_spm_sysram_read(_s, _type, _val)
|
||||||
|
#define mt_spm_sysram_init(_magic)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MT_SPM_TRACE_H */
|
||||||
|
|
114
plat/mediatek/drivers/spm/mt8196/mt_plat_spm_setting.c
Normal file
114
plat/mediatek/drivers/spm/mt8196/mt_plat_spm_setting.c
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <lib/mmio.h>
|
||||||
|
#include <platform_def.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>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BIT Operation
|
||||||
|
*/
|
||||||
|
#define CMD_DATA(h, l, v) ((GENMASK(h, l) & ((v) << (l))))
|
||||||
|
#define VOLT_DATA(v) CMD_DATA(7, 0, VOLT_TO_PMIC_VAL(v))
|
||||||
|
/*
|
||||||
|
* PMIC_WRAP
|
||||||
|
*/
|
||||||
|
#define VCORE_BASE_UV 0 /* PMIC MT6316 */
|
||||||
|
#define VOLT_TO_PMIC_VAL(volt) (((volt) - VCORE_BASE_UV + 500 - 1) / 500)
|
||||||
|
#define PMIC_VAL_TO_VOLT(pmic) (((pmic) * 500) + VCORE_BASE_UV)
|
||||||
|
|
||||||
|
#define NR_PMIC_WRAP_CMD NR_IDX_ALL
|
||||||
|
#define MAX_RETRY_COUNT 100
|
||||||
|
#define SPM_DATA_SHIFT 16
|
||||||
|
|
||||||
|
/* MT6316 */
|
||||||
|
#define MT6316_TOP_VRCTL_VOSEL_VBUCK1 0x1448
|
||||||
|
#define MT6316_VCORE_VBUCK1_ON 0x1441
|
||||||
|
#define MT6316_VCORE_VBUCK1_OFF 0x1442
|
||||||
|
|
||||||
|
static struct pmic_wrap_cmd_setting cmd_table[NR_PMIC_WRAP_CMD] = {
|
||||||
|
{SPM_PWRAP_CMD0, MT6316_TOP_VRCTL_VOSEL_VBUCK1, VOLT_DATA(57500)},
|
||||||
|
{SPM_PWRAP_CMD1, MT6316_TOP_VRCTL_VOSEL_VBUCK1, VOLT_DATA(57500)},
|
||||||
|
{SPM_PWRAP_CMD2, MT6316_TOP_VRCTL_VOSEL_VBUCK1, VOLT_DATA(60000)},
|
||||||
|
{SPM_PWRAP_CMD3, MT6316_TOP_VRCTL_VOSEL_VBUCK1, VOLT_DATA(65000)},
|
||||||
|
{SPM_PWRAP_CMD4, MT6316_TOP_VRCTL_VOSEL_VBUCK1, VOLT_DATA(72500)},
|
||||||
|
{SPM_PWRAP_CMD5, MT6316_TOP_VRCTL_VOSEL_VBUCK1, VOLT_DATA(72500)},
|
||||||
|
{SPM_PWRAP_CMD6, MT6316_TOP_VRCTL_VOSEL_VBUCK1, VOLT_DATA(82500)},
|
||||||
|
{SPM_PWRAP_CMD7, MT6316_TOP_VRCTL_VOSEL_VBUCK1, VOLT_DATA(87500)},
|
||||||
|
{SPM_PWRAP_CMD8, MT6316_TOP_VRCTL_VOSEL_VBUCK1, VOLT_DATA(87500)},
|
||||||
|
{SPM_PWRAP_CMD9, MT6316_TOP_VRCTL_VOSEL_VBUCK1, VOLT_DATA(57500)},
|
||||||
|
{SPM_PWRAP_CMD10, MT6316_TOP_VRCTL_VOSEL_VBUCK1, VOLT_DATA(60000)},
|
||||||
|
{SPM_PWRAP_CMD11, MT6316_TOP_VRCTL_VOSEL_VBUCK1, VOLT_DATA(65000)},
|
||||||
|
{SPM_PWRAP_CMD12, MT6316_TOP_VRCTL_VOSEL_VBUCK1, VOLT_DATA(72500)},
|
||||||
|
{SPM_PWRAP_CMD13, MT6316_TOP_VRCTL_VOSEL_VBUCK1, VOLT_DATA(82500)},
|
||||||
|
{SPM_PWRAP_CMD14, MT6316_TOP_VRCTL_VOSEL_VBUCK1, VOLT_DATA(87500)},
|
||||||
|
{SPM_PWRAP_CMD15, MT6316_VCORE_VBUCK1_ON, 1},
|
||||||
|
{SPM_PWRAP_CMD16, MT6316_VCORE_VBUCK1_OFF, 1},
|
||||||
|
{SPM_PWRAP_CMD17, MT6316_TOP_VRCTL_VOSEL_VBUCK1, VOLT_DATA(75000)},
|
||||||
|
{SPM_PWRAP_CMD18, 0, 0},
|
||||||
|
{SPM_PWRAP_CMD19, 0, 0},
|
||||||
|
{SPM_PWRAP_CMD20, 0, 0},
|
||||||
|
{SPM_PWRAP_CMD21, 0, 0},
|
||||||
|
{SPM_PWRAP_CMD22, 0, 0},
|
||||||
|
{SPM_PWRAP_CMD23, 0, 0},
|
||||||
|
{SPM_PWRAP_CMD24, 0, 0},
|
||||||
|
{SPM_PWRAP_CMD25, 0, 0},
|
||||||
|
{SPM_PWRAP_CMD26, 0, 0},
|
||||||
|
{SPM_PWRAP_CMD27, 0, 0},
|
||||||
|
{SPM_PWRAP_CMD28, 0, 0},
|
||||||
|
{SPM_PWRAP_CMD29, 0, 0},
|
||||||
|
{SPM_PWRAP_CMD30, 0, 0},
|
||||||
|
{SPM_PWRAP_CMD31, 0, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct pmic_wrap_phase_setting phase_table[NR_PMIC_WRAP_PHASE] = {
|
||||||
|
{
|
||||||
|
.cmd = cmd_table,
|
||||||
|
.nr_idx = NR_IDX_ALL,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct pmic_wrap_setting pmic_wrap_table = {
|
||||||
|
.phase = phase_table,
|
||||||
|
.phase_nr_idx = NR_PMIC_WRAP_PHASE,
|
||||||
|
};
|
||||||
|
|
||||||
|
void plat_spm_pmic_wrap_init(void)
|
||||||
|
{
|
||||||
|
mt_spm_pmic_wrap_set_table(&pmic_wrap_table);
|
||||||
|
mt_spm_pmic_wrap_set_phase(PMIC_WRAP_PHASE_ALLINONE);
|
||||||
|
}
|
||||||
|
#define PMIC_WRAP_REG_1 0x3E8
|
||||||
|
#define PMIC_WRAP_REG_STEP 0x4
|
||||||
|
#define PMIC_WRAP_REG_2 0xC28
|
||||||
|
#define PMIC_WRAP_REG_3 0xF54
|
||||||
|
|
||||||
|
#ifndef MTK_PLAT_SPM_PMIC_WRAP_DUMP_UNSUPPORT
|
||||||
|
void mt_spm_dump_pmic_warp_reg(void)
|
||||||
|
{
|
||||||
|
uint32_t temp;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i <= PMIC_WRAP_REG_1; i += PMIC_WRAP_REG_STEP) {
|
||||||
|
temp = mmio_read_32(PMIC_WRAP_BASE + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0xC00; i <= PMIC_WRAP_REG_2; i += PMIC_WRAP_REG_STEP) {
|
||||||
|
temp = mmio_read_32(PMIC_WRAP_BASE + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0xF00; i <= PMIC_WRAP_REG_3; i += PMIC_WRAP_REG_STEP) {
|
||||||
|
temp = mmio_read_32(PMIC_WRAP_BASE + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
61
plat/mediatek/drivers/spm/mt8196/mt_plat_spm_setting.h
Normal file
61
plat/mediatek/drivers/spm/mt8196/mt_plat_spm_setting.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_PLAT_SPM_SETTING_H
|
||||||
|
#define MT_PLAT_SPM_SETTING_H
|
||||||
|
|
||||||
|
#include <sleep_def.h>
|
||||||
|
|
||||||
|
enum plat_spm_cond {
|
||||||
|
PLAT_SPM_COND_MAX = 0,
|
||||||
|
};
|
||||||
|
enum pmic_wrap_phase_id {
|
||||||
|
PMIC_WRAP_PHASE_ALLINONE,
|
||||||
|
NR_PMIC_WRAP_PHASE,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* IDX mapping */
|
||||||
|
enum {
|
||||||
|
CMD_0,
|
||||||
|
CMD_1,
|
||||||
|
CMD_2,
|
||||||
|
CMD_3,
|
||||||
|
CMD_4,
|
||||||
|
CMD_5,
|
||||||
|
CMD_6,
|
||||||
|
CMD_7,
|
||||||
|
CMD_8,
|
||||||
|
CMD_9,
|
||||||
|
CMD_10,
|
||||||
|
CMD_11,
|
||||||
|
CMD_12,
|
||||||
|
CMD_13,
|
||||||
|
CMD_14,
|
||||||
|
CMD_15,
|
||||||
|
CMD_16,
|
||||||
|
CMD_17,
|
||||||
|
CMD_18,
|
||||||
|
CMD_19,
|
||||||
|
CMD_20,
|
||||||
|
CMD_21,
|
||||||
|
CMD_22,
|
||||||
|
CMD_23,
|
||||||
|
CMD_24,
|
||||||
|
CMD_25,
|
||||||
|
CMD_26,
|
||||||
|
CMD_27,
|
||||||
|
CMD_28,
|
||||||
|
CMD_29,
|
||||||
|
CMD_30,
|
||||||
|
CMD_31,
|
||||||
|
NR_IDX_ALL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* APIs */
|
||||||
|
void mt_spm_dump_pmic_warp_reg(void);
|
||||||
|
void plat_spm_pmic_wrap_init(void);
|
||||||
|
|
||||||
|
#endif /* MT_PLAT_SPM_SETTING_H */
|
464
plat/mediatek/drivers/spm/mt8196/mt_spm.c
Normal file
464
plat/mediatek/drivers/spm/mt8196/mt_spm.c
Normal 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);
|
146
plat/mediatek/drivers/spm/mt8196/mt_spm.h
Normal file
146
plat/mediatek/drivers/spm/mt8196/mt_spm.h
Normal 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 */
|
167
plat/mediatek/drivers/spm/mt8196/mt_spm_conservation.c
Normal file
167
plat/mediatek/drivers/spm/mt8196/mt_spm_conservation.c
Normal 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;
|
||||||
|
}
|
30
plat/mediatek/drivers/spm/mt8196/mt_spm_conservation.h
Normal file
30
plat/mediatek/drivers/spm/mt8196/mt_spm_conservation.h
Normal 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 */
|
93
plat/mediatek/drivers/spm/mt8196/mt_spm_dispatcher.c
Normal file
93
plat/mediatek/drivers/spm/mt8196/mt_spm_dispatcher.c
Normal file
|
@ -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;
|
||||||
|
}
|
11
plat/mediatek/drivers/spm/mt8196/mt_spm_dispatcher.h
Normal file
11
plat/mediatek/drivers/spm/mt8196/mt_spm_dispatcher.h
Normal file
|
@ -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 */
|
24
plat/mediatek/drivers/spm/mt8196/mt_spm_doe_resource_ctrl.h
Normal file
24
plat/mediatek/drivers/spm/mt8196/mt_spm_doe_resource_ctrl.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_SPM_DOE_RESOURCE_CTRL_H
|
||||||
|
#define MT_SPM_DOE_RESOURCE_CTRL_H
|
||||||
|
|
||||||
|
#include <mt_spm_internal.h>
|
||||||
|
|
||||||
|
enum resource_ctrl_enum {
|
||||||
|
MT_SPM_RESOURCE_CTRL_BUS26M,
|
||||||
|
MT_SPM_RESOURCE_CTRL_INFRA,
|
||||||
|
MT_SPM_RESOURCE_CTRL_SYSPLL,
|
||||||
|
MT_SPM_RESOURCE_CTRL_DRAM_S0,
|
||||||
|
MT_SPM_RESOURCE_CTRL_DRAM_S1,
|
||||||
|
MT_SPM_RESORUCE_CTRL_VCORE,
|
||||||
|
MT_SPM_RESOURCE_CTRL_EMI,
|
||||||
|
MT_SPM_RESOURCE_CTRL_PMIC,
|
||||||
|
MT_SPM_RESOURCE_CTRL_MAX_NUM,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* MT_SPM_DOE_RESOURCE_CTRL_H */
|
707
plat/mediatek/drivers/spm/mt8196/mt_spm_hwreq.c
Normal file
707
plat/mediatek/drivers/spm/mt8196/mt_spm_hwreq.c
Normal file
|
@ -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();
|
||||||
|
}
|
245
plat/mediatek/drivers/spm/mt8196/mt_spm_hwreq.h
Normal file
245
plat/mediatek/drivers/spm/mt8196/mt_spm_hwreq.h
Normal file
|
@ -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 */
|
607
plat/mediatek/drivers/spm/mt8196/mt_spm_idle.c
Normal file
607
plat/mediatek/drivers/spm/mt8196/mt_spm_idle.c
Normal file
|
@ -0,0 +1,607 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <common/debug.h>
|
||||||
|
#include <lib/mmio.h>
|
||||||
|
|
||||||
|
#include <drivers/spm/mt_spm_resource_req.h>
|
||||||
|
#include <lib/pm/mtk_pm.h>
|
||||||
|
#include <lpm_v2/mt_lp_api.h>
|
||||||
|
#include <mt_spm.h>
|
||||||
|
#include <mt_spm_conservation.h>
|
||||||
|
#include <mt_spm_idle.h>
|
||||||
|
#include <mt_spm_internal.h>
|
||||||
|
#include <mt_spm_reg.h>
|
||||||
|
#include <mt_spm_stats.h>
|
||||||
|
|
||||||
|
#define SPM_BYPASS_SYSPWREQ_GENERIC 1
|
||||||
|
|
||||||
|
/* Default will be the bus26m or deeper spm's low power mode*/
|
||||||
|
#define __WAKE_SRC_FOR_IDLE_COMMON__ ( \
|
||||||
|
(R12_PCM_TIMER_B) | \
|
||||||
|
(R12_KP_IRQ_B) | \
|
||||||
|
(R12_APWDT_EVENT_B) | \
|
||||||
|
(R12_APXGPT_EVENT_B) | \
|
||||||
|
(R12_CONN2AP_WAKEUP_B) | \
|
||||||
|
(R12_EINT_EVENT_B) | \
|
||||||
|
(R12_CONN_WDT_IRQ_B) | \
|
||||||
|
(R12_CCIF0_EVENT_B) | \
|
||||||
|
(R12_CCIF1_EVENT_B) | \
|
||||||
|
(R12_SSPM2SPM_WAKEUP_B) | \
|
||||||
|
(R12_SCP2SPM_WAKEUP_B) | \
|
||||||
|
(R12_ADSP2SPM_WAKEUP_B) | \
|
||||||
|
(R12_USB0_CDSC_B) | \
|
||||||
|
(R12_USB0_POWERDWN_B) | \
|
||||||
|
(R12_UART_EVENT_B) | \
|
||||||
|
(R12_SYS_TIMER_EVENT_B) | \
|
||||||
|
(R12_EINT_EVENT_SECURE_B) | \
|
||||||
|
(R12_AFE_IRQ_MCU_B) | \
|
||||||
|
(R12_SYS_CIRQ_IRQ_B) | \
|
||||||
|
(R12_MD_WDT_B) | \
|
||||||
|
(R12_AP2AP_PEER_WAKEUP_B) | \
|
||||||
|
(R12_CPU_WAKEUP) | \
|
||||||
|
(R12_APUSYS_WAKE_HOST_B) |\
|
||||||
|
(R12_PCIE_WAKE_B))
|
||||||
|
|
||||||
|
#if defined(CFG_MICROTRUST_TEE_SUPPORT)
|
||||||
|
#define WAKE_SRC_FOR_IDLE (__WAKE_SRC_FOR_IDLE_COMMON__)
|
||||||
|
#else
|
||||||
|
#define WAKE_SRC_FOR_IDLE \
|
||||||
|
(__WAKE_SRC_FOR_IDLE_COMMON__ | R12_SEJ_B)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct pwr_ctrl idle_spm_pwr = {
|
||||||
|
.wake_src = WAKE_SRC_FOR_IDLE,
|
||||||
|
|
||||||
|
/* SPM_SRC_REQ */
|
||||||
|
.reg_spm_adsp_mailbox_req = 0,
|
||||||
|
.reg_spm_apsrc_req = 1,
|
||||||
|
.reg_spm_ddren_req = 0,
|
||||||
|
.reg_spm_dvfs_req = 0,
|
||||||
|
.reg_spm_emi_req = 1,
|
||||||
|
.reg_spm_f26m_req = 0,
|
||||||
|
.reg_spm_infra_req = 0,
|
||||||
|
.reg_spm_pmic_req = 0,
|
||||||
|
.reg_spm_scp_mailbox_req = 0,
|
||||||
|
.reg_spm_sspm_mailbox_req = 0,
|
||||||
|
.reg_spm_sw_mailbox_req = 0,
|
||||||
|
.reg_spm_vcore_req = 0,
|
||||||
|
.reg_spm_vrf18_req = 0,
|
||||||
|
.adsp_mailbox_state = 0,
|
||||||
|
.apsrc_state = 0,
|
||||||
|
.ddren_state = 0,
|
||||||
|
.dvfs_state = 0,
|
||||||
|
.emi_state = 0,
|
||||||
|
.f26m_state = 0,
|
||||||
|
.infra_state = 0,
|
||||||
|
.pmic_state = 0,
|
||||||
|
.scp_mailbox_state = 0,
|
||||||
|
.sspm_mailbox_state = 0,
|
||||||
|
.sw_mailbox_state = 0,
|
||||||
|
.vcore_state = 0,
|
||||||
|
.vrf18_state = 0,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_0 */
|
||||||
|
.reg_apifr_apsrc_rmb = 0,
|
||||||
|
.reg_apifr_ddren_rmb = 0,
|
||||||
|
.reg_apifr_emi_rmb = 0,
|
||||||
|
.reg_apifr_infra_rmb = 0,
|
||||||
|
.reg_apifr_pmic_rmb = 0,
|
||||||
|
.reg_apifr_srcclkena_mb = 0,
|
||||||
|
.reg_apifr_vcore_rmb = 0,
|
||||||
|
.reg_apifr_vrf18_rmb = 0,
|
||||||
|
.reg_apu_apsrc_rmb = 1,
|
||||||
|
.reg_apu_ddren_rmb = 0,
|
||||||
|
.reg_apu_emi_rmb = 1,
|
||||||
|
.reg_apu_infra_rmb = 1,
|
||||||
|
.reg_apu_pmic_rmb = 1,
|
||||||
|
.reg_apu_srcclkena_mb = 1,
|
||||||
|
.reg_apu_vcore_rmb = 1,
|
||||||
|
.reg_apu_vrf18_rmb = 1,
|
||||||
|
.reg_audio_apsrc_rmb = 1,
|
||||||
|
.reg_audio_ddren_rmb = 0,
|
||||||
|
.reg_audio_emi_rmb = 1,
|
||||||
|
.reg_audio_infra_rmb = 1,
|
||||||
|
.reg_audio_pmic_rmb = 0,
|
||||||
|
.reg_audio_srcclkena_mb = 1,
|
||||||
|
.reg_audio_vcore_rmb = 1,
|
||||||
|
.reg_audio_vrf18_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_1 */
|
||||||
|
.reg_audio_dsp_apsrc_rmb = 1,
|
||||||
|
.reg_audio_dsp_ddren_rmb = 0,
|
||||||
|
.reg_audio_dsp_emi_rmb = 1,
|
||||||
|
.reg_audio_dsp_infra_rmb = 1,
|
||||||
|
.reg_audio_dsp_pmic_rmb = 1,
|
||||||
|
.reg_audio_dsp_srcclkena_mb = 1,
|
||||||
|
.reg_audio_dsp_vcore_rmb = 1,
|
||||||
|
.reg_audio_dsp_vrf18_rmb = 1,
|
||||||
|
.reg_cam_apsrc_rmb = 0,
|
||||||
|
.reg_cam_ddren_rmb = 0,
|
||||||
|
.reg_cam_emi_rmb = 0,
|
||||||
|
.reg_cam_infra_rmb = 0,
|
||||||
|
.reg_cam_pmic_rmb = 0,
|
||||||
|
.reg_cam_srcclkena_mb = 0,
|
||||||
|
.reg_cam_vrf18_rmb = 0,
|
||||||
|
.reg_ccif_apsrc_rmb = 0xfff,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_2 */
|
||||||
|
.reg_ccif_emi_rmb = 0xfff,
|
||||||
|
.reg_ccif_infra_rmb = 0xfff,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_3 */
|
||||||
|
.reg_ccif_pmic_rmb = 0xfff,
|
||||||
|
.reg_ccif_srcclkena_mb = 0xfff,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_4 */
|
||||||
|
.reg_ccif_vcore_rmb = 0xfff,
|
||||||
|
.reg_ccif_vrf18_rmb = 0xfff,
|
||||||
|
.reg_ccu_apsrc_rmb = 0,
|
||||||
|
.reg_ccu_ddren_rmb = 0,
|
||||||
|
.reg_ccu_emi_rmb = 0,
|
||||||
|
.reg_ccu_infra_rmb = 0,
|
||||||
|
.reg_ccu_pmic_rmb = 0,
|
||||||
|
.reg_ccu_srcclkena_mb = 0,
|
||||||
|
.reg_ccu_vrf18_rmb = 0,
|
||||||
|
.reg_cg_check_apsrc_rmb = 0,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_5 */
|
||||||
|
.reg_cg_check_ddren_rmb = 0,
|
||||||
|
.reg_cg_check_emi_rmb = 0,
|
||||||
|
.reg_cg_check_infra_rmb = 0,
|
||||||
|
.reg_cg_check_pmic_rmb = 0,
|
||||||
|
.reg_cg_check_srcclkena_mb = 0,
|
||||||
|
/* for UFS HWCG vcore req */
|
||||||
|
.reg_cg_check_vcore_rmb = 1,
|
||||||
|
.reg_cg_check_vrf18_rmb = 0,
|
||||||
|
.reg_cksys_apsrc_rmb = 1,
|
||||||
|
.reg_cksys_ddren_rmb = 0,
|
||||||
|
.reg_cksys_emi_rmb = 1,
|
||||||
|
.reg_cksys_infra_rmb = 1,
|
||||||
|
.reg_cksys_pmic_rmb = 1,
|
||||||
|
.reg_cksys_srcclkena_mb = 1,
|
||||||
|
.reg_cksys_vcore_rmb = 1,
|
||||||
|
.reg_cksys_vrf18_rmb = 1,
|
||||||
|
.reg_cksys_1_apsrc_rmb = 1,
|
||||||
|
.reg_cksys_1_ddren_rmb = 0,
|
||||||
|
.reg_cksys_1_emi_rmb = 1,
|
||||||
|
.reg_cksys_1_infra_rmb = 1,
|
||||||
|
.reg_cksys_1_pmic_rmb = 1,
|
||||||
|
.reg_cksys_1_srcclkena_mb = 1,
|
||||||
|
.reg_cksys_1_vcore_rmb = 1,
|
||||||
|
.reg_cksys_1_vrf18_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_6 */
|
||||||
|
.reg_cksys_2_apsrc_rmb = 1,
|
||||||
|
.reg_cksys_2_ddren_rmb = 0,
|
||||||
|
.reg_cksys_2_emi_rmb = 1,
|
||||||
|
.reg_cksys_2_infra_rmb = 1,
|
||||||
|
.reg_cksys_2_pmic_rmb = 1,
|
||||||
|
.reg_cksys_2_srcclkena_mb = 1,
|
||||||
|
.reg_cksys_2_vcore_rmb = 1,
|
||||||
|
.reg_cksys_2_vrf18_rmb = 1,
|
||||||
|
.reg_conn_apsrc_rmb = 1,
|
||||||
|
.reg_conn_ddren_rmb = 0,
|
||||||
|
.reg_conn_emi_rmb = 1,
|
||||||
|
.reg_conn_infra_rmb = 1,
|
||||||
|
.reg_conn_pmic_rmb = 1,
|
||||||
|
.reg_conn_srcclkena_mb = 1,
|
||||||
|
.reg_conn_srcclkenb_mb = 1,
|
||||||
|
.reg_conn_vcore_rmb = 1,
|
||||||
|
.reg_conn_vrf18_rmb = 1,
|
||||||
|
.reg_corecfg_apsrc_rmb = 0,
|
||||||
|
.reg_corecfg_ddren_rmb = 0,
|
||||||
|
.reg_corecfg_emi_rmb = 0,
|
||||||
|
.reg_corecfg_infra_rmb = 0,
|
||||||
|
.reg_corecfg_pmic_rmb = 0,
|
||||||
|
.reg_corecfg_srcclkena_mb = 0,
|
||||||
|
.reg_corecfg_vcore_rmb = 0,
|
||||||
|
.reg_corecfg_vrf18_rmb = 0,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_7 */
|
||||||
|
.reg_cpueb_apsrc_rmb = 1,
|
||||||
|
.reg_cpueb_ddren_rmb = 0,
|
||||||
|
.reg_cpueb_emi_rmb = 1,
|
||||||
|
.reg_cpueb_infra_rmb = 1,
|
||||||
|
.reg_cpueb_pmic_rmb = 1,
|
||||||
|
.reg_cpueb_srcclkena_mb = 1,
|
||||||
|
.reg_cpueb_vcore_rmb = 0,
|
||||||
|
.reg_cpueb_vrf18_rmb = 1,
|
||||||
|
.reg_disp0_apsrc_rmb = 0,
|
||||||
|
.reg_disp0_ddren_rmb = 0,
|
||||||
|
.reg_disp0_emi_rmb = 0,
|
||||||
|
.reg_disp0_infra_rmb = 0,
|
||||||
|
.reg_disp0_pmic_rmb = 0,
|
||||||
|
.reg_disp0_srcclkena_mb = 0,
|
||||||
|
.reg_disp0_vrf18_rmb = 0,
|
||||||
|
.reg_disp1_apsrc_rmb = 0,
|
||||||
|
.reg_disp1_ddren_rmb = 0,
|
||||||
|
.reg_disp1_emi_rmb = 0,
|
||||||
|
.reg_disp1_infra_rmb = 0,
|
||||||
|
.reg_disp1_pmic_rmb = 0,
|
||||||
|
.reg_disp1_srcclkena_mb = 0,
|
||||||
|
.reg_disp1_vrf18_rmb = 0,
|
||||||
|
.reg_dpm_apsrc_rmb = 0xf,
|
||||||
|
.reg_dpm_ddren_rmb = 0xf,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_8 */
|
||||||
|
.reg_dpm_emi_rmb = 0xf,
|
||||||
|
.reg_dpm_infra_rmb = 0xf,
|
||||||
|
.reg_dpm_pmic_rmb = 0xf,
|
||||||
|
.reg_dpm_srcclkena_mb = 0xf,
|
||||||
|
.reg_dpm_vcore_rmb = 0xf,
|
||||||
|
.reg_dpm_vrf18_rmb = 0xf,
|
||||||
|
.reg_dpmaif_apsrc_rmb = 1,
|
||||||
|
.reg_dpmaif_ddren_rmb = 0,
|
||||||
|
.reg_dpmaif_emi_rmb = 1,
|
||||||
|
.reg_dpmaif_infra_rmb = 1,
|
||||||
|
.reg_dpmaif_pmic_rmb = 1,
|
||||||
|
.reg_dpmaif_srcclkena_mb = 1,
|
||||||
|
.reg_dpmaif_vcore_rmb = 1,
|
||||||
|
.reg_dpmaif_vrf18_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_9 */
|
||||||
|
.reg_dvfsrc_level_rmb = 1,
|
||||||
|
.reg_emisys_apsrc_rmb = 0,
|
||||||
|
.reg_emisys_ddren_rmb = 0,
|
||||||
|
.reg_emisys_emi_rmb = 0,
|
||||||
|
.reg_emisys_infra_rmb = 0,
|
||||||
|
.reg_emisys_pmic_rmb = 0,
|
||||||
|
.reg_emisys_srcclkena_mb = 0,
|
||||||
|
.reg_emisys_vcore_rmb = 0,
|
||||||
|
.reg_emisys_vrf18_rmb = 0,
|
||||||
|
.reg_gce_apsrc_rmb = 0,
|
||||||
|
.reg_gce_ddren_rmb = 0,
|
||||||
|
.reg_gce_emi_rmb = 0,
|
||||||
|
.reg_gce_infra_rmb = 0,
|
||||||
|
.reg_gce_pmic_rmb = 0,
|
||||||
|
.reg_gce_srcclkena_mb = 0,
|
||||||
|
.reg_gce_vcore_rmb = 0,
|
||||||
|
.reg_gce_vrf18_rmb = 0,
|
||||||
|
.reg_gpueb_apsrc_rmb = 1,
|
||||||
|
.reg_gpueb_ddren_rmb = 0,
|
||||||
|
.reg_gpueb_emi_rmb = 1,
|
||||||
|
.reg_gpueb_infra_rmb = 1,
|
||||||
|
.reg_gpueb_pmic_rmb = 1,
|
||||||
|
.reg_gpueb_srcclkena_mb = 1,
|
||||||
|
.reg_gpueb_vcore_rmb = 1,
|
||||||
|
.reg_gpueb_vrf18_rmb = 1,
|
||||||
|
.reg_hwccf_apsrc_rmb = 1,
|
||||||
|
.reg_hwccf_ddren_rmb = 0,
|
||||||
|
.reg_hwccf_emi_rmb = 1,
|
||||||
|
.reg_hwccf_infra_rmb = 1,
|
||||||
|
.reg_hwccf_pmic_rmb = 1,
|
||||||
|
.reg_hwccf_srcclkena_mb = 1,
|
||||||
|
.reg_hwccf_vcore_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_10 */
|
||||||
|
.reg_hwccf_vrf18_rmb = 1,
|
||||||
|
.reg_img_apsrc_rmb = 0,
|
||||||
|
.reg_img_ddren_rmb = 0,
|
||||||
|
.reg_img_emi_rmb = 0,
|
||||||
|
.reg_img_infra_rmb = 0,
|
||||||
|
.reg_img_pmic_rmb = 0,
|
||||||
|
.reg_img_srcclkena_mb = 0,
|
||||||
|
.reg_img_vrf18_rmb = 0,
|
||||||
|
.reg_infrasys_apsrc_rmb = 0,
|
||||||
|
.reg_infrasys_ddren_rmb = 0,
|
||||||
|
.reg_infrasys_emi_rmb = 0,
|
||||||
|
.reg_infrasys_infra_rmb = 0,
|
||||||
|
.reg_infrasys_pmic_rmb = 0,
|
||||||
|
.reg_infrasys_srcclkena_mb = 0,
|
||||||
|
.reg_infrasys_vcore_rmb = 0,
|
||||||
|
.reg_infrasys_vrf18_rmb = 0,
|
||||||
|
.reg_ipic_infra_rmb = 1,
|
||||||
|
.reg_ipic_vrf18_rmb = 1,
|
||||||
|
.reg_mcu_apsrc_rmb = 1,
|
||||||
|
.reg_mcu_ddren_rmb = 0,
|
||||||
|
.reg_mcu_emi_rmb = 1,
|
||||||
|
.reg_mcu_infra_rmb = 1,
|
||||||
|
.reg_mcu_pmic_rmb = 1,
|
||||||
|
.reg_mcu_srcclkena_mb = 1,
|
||||||
|
.reg_mcu_vcore_rmb = 0,
|
||||||
|
.reg_mcu_vrf18_rmb = 1,
|
||||||
|
.reg_md_apsrc_rmb = 1,
|
||||||
|
.reg_md_ddren_rmb = 0,
|
||||||
|
.reg_md_emi_rmb = 1,
|
||||||
|
.reg_md_infra_rmb = 1,
|
||||||
|
.reg_md_pmic_rmb = 1,
|
||||||
|
.reg_md_srcclkena_mb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_11 */
|
||||||
|
.reg_md_srcclkena1_mb = 1,
|
||||||
|
.reg_md_vcore_rmb = 1,
|
||||||
|
.reg_md_vrf18_rmb = 1,
|
||||||
|
.reg_mm_proc_apsrc_rmb = 1,
|
||||||
|
.reg_mm_proc_ddren_rmb = 0,
|
||||||
|
.reg_mm_proc_emi_rmb = 1,
|
||||||
|
.reg_mm_proc_infra_rmb = 1,
|
||||||
|
.reg_mm_proc_pmic_rmb = 1,
|
||||||
|
.reg_mm_proc_srcclkena_mb = 1,
|
||||||
|
.reg_mm_proc_vcore_rmb = 1,
|
||||||
|
.reg_mm_proc_vrf18_rmb = 1,
|
||||||
|
.reg_mml0_apsrc_rmb = 0,
|
||||||
|
.reg_mml0_ddren_rmb = 0,
|
||||||
|
.reg_mml0_emi_rmb = 0,
|
||||||
|
.reg_mml0_infra_rmb = 0,
|
||||||
|
.reg_mml0_pmic_rmb = 0,
|
||||||
|
.reg_mml0_srcclkena_mb = 0,
|
||||||
|
.reg_mml0_vrf18_rmb = 0,
|
||||||
|
.reg_mml1_apsrc_rmb = 0,
|
||||||
|
.reg_mml1_ddren_rmb = 0,
|
||||||
|
.reg_mml1_emi_rmb = 0,
|
||||||
|
.reg_mml1_infra_rmb = 0,
|
||||||
|
.reg_mml1_pmic_rmb = 0,
|
||||||
|
.reg_mml1_srcclkena_mb = 0,
|
||||||
|
.reg_mml1_vrf18_rmb = 0,
|
||||||
|
.reg_ovl0_apsrc_rmb = 0,
|
||||||
|
.reg_ovl0_ddren_rmb = 0,
|
||||||
|
.reg_ovl0_emi_rmb = 0,
|
||||||
|
.reg_ovl0_infra_rmb = 0,
|
||||||
|
.reg_ovl0_pmic_rmb = 0,
|
||||||
|
.reg_ovl0_srcclkena_mb = 0,
|
||||||
|
.reg_ovl0_vrf18_rmb = 0,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_12 */
|
||||||
|
.reg_ovl1_apsrc_rmb = 0,
|
||||||
|
.reg_ovl1_ddren_rmb = 0,
|
||||||
|
.reg_ovl1_emi_rmb = 0,
|
||||||
|
.reg_ovl1_infra_rmb = 0,
|
||||||
|
.reg_ovl1_pmic_rmb = 0,
|
||||||
|
.reg_ovl1_srcclkena_mb = 0,
|
||||||
|
.reg_ovl1_vrf18_rmb = 0,
|
||||||
|
.reg_pcie0_apsrc_rmb = 1,
|
||||||
|
.reg_pcie0_ddren_rmb = 0,
|
||||||
|
.reg_pcie0_emi_rmb = 1,
|
||||||
|
.reg_pcie0_infra_rmb = 1,
|
||||||
|
.reg_pcie0_pmic_rmb = 1,
|
||||||
|
.reg_pcie0_srcclkena_mb = 1,
|
||||||
|
.reg_pcie0_vcore_rmb = 1,
|
||||||
|
.reg_pcie0_vrf18_rmb = 1,
|
||||||
|
.reg_pcie1_apsrc_rmb = 1,
|
||||||
|
.reg_pcie1_ddren_rmb = 0,
|
||||||
|
.reg_pcie1_emi_rmb = 1,
|
||||||
|
.reg_pcie1_infra_rmb = 1,
|
||||||
|
.reg_pcie1_pmic_rmb = 1,
|
||||||
|
.reg_pcie1_srcclkena_mb = 1,
|
||||||
|
.reg_pcie1_vcore_rmb = 1,
|
||||||
|
.reg_pcie1_vrf18_rmb = 1,
|
||||||
|
.reg_perisys_apsrc_rmb = 1,
|
||||||
|
.reg_perisys_ddren_rmb = 0,
|
||||||
|
.reg_perisys_emi_rmb = 1,
|
||||||
|
.reg_perisys_infra_rmb = 1,
|
||||||
|
.reg_perisys_pmic_rmb = 1,
|
||||||
|
.reg_perisys_srcclkena_mb = 1,
|
||||||
|
.reg_perisys_vcore_rmb = 1,
|
||||||
|
.reg_perisys_vrf18_rmb = 1,
|
||||||
|
.reg_pmsr_apsrc_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_13 */
|
||||||
|
.reg_pmsr_ddren_rmb = 0,
|
||||||
|
.reg_pmsr_emi_rmb = 1,
|
||||||
|
.reg_pmsr_infra_rmb = 1,
|
||||||
|
.reg_pmsr_pmic_rmb = 1,
|
||||||
|
.reg_pmsr_srcclkena_mb = 1,
|
||||||
|
.reg_pmsr_vcore_rmb = 1,
|
||||||
|
.reg_pmsr_vrf18_rmb = 1,
|
||||||
|
.reg_scp_apsrc_rmb = 1,
|
||||||
|
.reg_scp_ddren_rmb = 0,
|
||||||
|
.reg_scp_emi_rmb = 1,
|
||||||
|
.reg_scp_infra_rmb = 1,
|
||||||
|
.reg_scp_pmic_rmb = 1,
|
||||||
|
.reg_scp_srcclkena_mb = 1,
|
||||||
|
.reg_scp_vcore_rmb = 1,
|
||||||
|
.reg_scp_vrf18_rmb = 1,
|
||||||
|
.reg_spu_hwr_apsrc_rmb = 1,
|
||||||
|
.reg_spu_hwr_ddren_rmb = 0,
|
||||||
|
.reg_spu_hwr_emi_rmb = 1,
|
||||||
|
.reg_spu_hwr_infra_rmb = 1,
|
||||||
|
.reg_spu_hwr_pmic_rmb = 1,
|
||||||
|
.reg_spu_hwr_srcclkena_mb = 1,
|
||||||
|
.reg_spu_hwr_vcore_rmb = 1,
|
||||||
|
.reg_spu_hwr_vrf18_rmb = 1,
|
||||||
|
.reg_spu_ise_apsrc_rmb = 1,
|
||||||
|
.reg_spu_ise_ddren_rmb = 0,
|
||||||
|
.reg_spu_ise_emi_rmb = 1,
|
||||||
|
.reg_spu_ise_infra_rmb = 1,
|
||||||
|
.reg_spu_ise_pmic_rmb = 1,
|
||||||
|
.reg_spu_ise_srcclkena_mb = 1,
|
||||||
|
.reg_spu_ise_vcore_rmb = 1,
|
||||||
|
.reg_spu_ise_vrf18_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_14 */
|
||||||
|
.reg_srcclkeni_infra_rmb = 0x3,
|
||||||
|
.reg_srcclkeni_pmic_rmb = 0x3,
|
||||||
|
.reg_srcclkeni_srcclkena_mb = 0x3,
|
||||||
|
.reg_srcclkeni_vcore_rmb = 0x3,
|
||||||
|
.reg_sspm_apsrc_rmb = 1,
|
||||||
|
.reg_sspm_ddren_rmb = 0,
|
||||||
|
.reg_sspm_emi_rmb = 1,
|
||||||
|
.reg_sspm_infra_rmb = 1,
|
||||||
|
.reg_sspm_pmic_rmb = 1,
|
||||||
|
.reg_sspm_srcclkena_mb = 1,
|
||||||
|
.reg_sspm_vrf18_rmb = 1,
|
||||||
|
.reg_ssrsys_apsrc_rmb = 1,
|
||||||
|
.reg_ssrsys_ddren_rmb = 0,
|
||||||
|
.reg_ssrsys_emi_rmb = 1,
|
||||||
|
.reg_ssrsys_infra_rmb = 1,
|
||||||
|
.reg_ssrsys_pmic_rmb = 1,
|
||||||
|
.reg_ssrsys_srcclkena_mb = 1,
|
||||||
|
.reg_ssrsys_vcore_rmb = 1,
|
||||||
|
.reg_ssrsys_vrf18_rmb = 1,
|
||||||
|
.reg_ssusb_apsrc_rmb = 1,
|
||||||
|
.reg_ssusb_ddren_rmb = 0,
|
||||||
|
.reg_ssusb_emi_rmb = 1,
|
||||||
|
.reg_ssusb_infra_rmb = 1,
|
||||||
|
.reg_ssusb_pmic_rmb = 1,
|
||||||
|
.reg_ssusb_srcclkena_mb = 1,
|
||||||
|
.reg_ssusb_vcore_rmb = 1,
|
||||||
|
.reg_ssusb_vrf18_rmb = 1,
|
||||||
|
.reg_uart_hub_infra_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_15 */
|
||||||
|
.reg_uart_hub_pmic_rmb = 1,
|
||||||
|
.reg_uart_hub_srcclkena_mb = 1,
|
||||||
|
.reg_uart_hub_vcore_rmb = 1,
|
||||||
|
.reg_uart_hub_vrf18_rmb = 1,
|
||||||
|
.reg_ufs_apsrc_rmb = 1,
|
||||||
|
.reg_ufs_ddren_rmb = 0,
|
||||||
|
.reg_ufs_emi_rmb = 1,
|
||||||
|
.reg_ufs_infra_rmb = 1,
|
||||||
|
.reg_ufs_pmic_rmb = 1,
|
||||||
|
.reg_ufs_srcclkena_mb = 1,
|
||||||
|
.reg_ufs_vcore_rmb = 1,
|
||||||
|
.reg_ufs_vrf18_rmb = 1,
|
||||||
|
.reg_vdec_apsrc_rmb = 0,
|
||||||
|
.reg_vdec_ddren_rmb = 0,
|
||||||
|
.reg_vdec_emi_rmb = 0,
|
||||||
|
.reg_vdec_infra_rmb = 0,
|
||||||
|
.reg_vdec_pmic_rmb = 0,
|
||||||
|
.reg_vdec_srcclkena_mb = 0,
|
||||||
|
.reg_vdec_vrf18_rmb = 0,
|
||||||
|
.reg_venc_apsrc_rmb = 0,
|
||||||
|
.reg_venc_ddren_rmb = 0,
|
||||||
|
.reg_venc_emi_rmb = 0,
|
||||||
|
.reg_venc_infra_rmb = 0,
|
||||||
|
.reg_venc_pmic_rmb = 0,
|
||||||
|
.reg_venc_srcclkena_mb = 0,
|
||||||
|
.reg_venc_vrf18_rmb = 0,
|
||||||
|
.reg_vlpcfg_apsrc_rmb = 1,
|
||||||
|
.reg_vlpcfg_ddren_rmb = 0,
|
||||||
|
.reg_vlpcfg_emi_rmb = 1,
|
||||||
|
.reg_vlpcfg_infra_rmb = 1,
|
||||||
|
.reg_vlpcfg_pmic_rmb = 1,
|
||||||
|
.reg_vlpcfg_srcclkena_mb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_16 */
|
||||||
|
.reg_vlpcfg_vcore_rmb = 1,
|
||||||
|
.reg_vlpcfg_vrf18_rmb = 1,
|
||||||
|
.reg_vlpcfg1_apsrc_rmb = 1,
|
||||||
|
.reg_vlpcfg1_ddren_rmb = 0,
|
||||||
|
.reg_vlpcfg1_emi_rmb = 1,
|
||||||
|
.reg_vlpcfg1_infra_rmb = 1,
|
||||||
|
.reg_vlpcfg1_pmic_rmb = 0,
|
||||||
|
.reg_vlpcfg1_srcclkena_mb = 1,
|
||||||
|
.reg_vlpcfg1_vcore_rmb = 1,
|
||||||
|
.reg_vlpcfg1_vrf18_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_EVENT_CON_MISC */
|
||||||
|
.reg_srcclken_fast_resp = 0,
|
||||||
|
.reg_csyspwrup_ack_mask = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_17 */
|
||||||
|
.reg_spm_sw_vcore_rmb = 0x3,
|
||||||
|
.reg_spm_sw_pmic_rmb = 0,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_18 */
|
||||||
|
.reg_spm_sw_srcclkena_mb = 0,
|
||||||
|
|
||||||
|
/* SPM_WAKE_MASK*/
|
||||||
|
.reg_wake_mask = 0x81322012,
|
||||||
|
|
||||||
|
/* SPM_WAKEUP_EVENT_EXT_MASK */
|
||||||
|
.reg_ext_wake_mask = 0xFFFFFFFF,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct dbg_ctrl idle_spm_dbg = {
|
||||||
|
.count = 0,
|
||||||
|
.duration = 0,
|
||||||
|
.ext = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct spm_lp_stat idle_lp_stat;
|
||||||
|
|
||||||
|
static struct spm_lp_scen idle_spm_lp = {
|
||||||
|
.pwrctrl = &idle_spm_pwr,
|
||||||
|
.dbgctrl = &idle_spm_dbg,
|
||||||
|
.lpstat = &idle_lp_stat,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int determine_event_level(int state_id)
|
||||||
|
{
|
||||||
|
if (IS_MT_PLAT_PWR_STATE(state_id, MT_PLAT_PWR_STATE_SYSTEM_VCORE))
|
||||||
|
return MT_LP_SYSPOWER_LEVEL_VCORE0V;
|
||||||
|
else if (IS_MT_PLAT_PWR_STATE(state_id, MT_PLAT_PWR_STATE_SYSTEM_BUS))
|
||||||
|
return MT_LP_SYSPOWER_LEVEL_BUS26M;
|
||||||
|
else if (IS_MT_PLAT_PWR_STATE(state_id, MT_PLAT_PWR_STATE_SYSTEM_PLL))
|
||||||
|
return MT_LP_SYSPOWER_LEVEL_SYSPLL;
|
||||||
|
else if (IS_MT_PLAT_PWR_STATE(state_id, MT_PLAT_PWR_STATE_SYSTEM_MEM))
|
||||||
|
return MT_LP_SYSPOWER_LEVEL_DRAM;
|
||||||
|
else
|
||||||
|
return MT_LP_SYSPOWER_LEVEL_APMCU;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_spm_idle_generic_enter(int state_id, uint32_t ext_opand,
|
||||||
|
spm_idle_conduct fn)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
uint32_t src_req = 0;
|
||||||
|
struct mt_lp_publish_event event = {
|
||||||
|
.id = MT_LPM_PUBEVENTS_SYS_POWER_OFF,
|
||||||
|
.val.u32 = 0,
|
||||||
|
.level = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
event.level = determine_event_level(state_id);
|
||||||
|
|
||||||
|
if (fn)
|
||||||
|
fn(state_id, &idle_spm_lp, &src_req);
|
||||||
|
|
||||||
|
ret = spm_conservation(state_id, ext_opand, &idle_spm_lp, src_req);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
NOTICE("[%s:%d] - unknown issue !!\n", __func__, __LINE__);
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
mmio_write_32(SPM2SW_MAILBOX_0, 0x1);
|
||||||
|
|
||||||
|
if (ext_opand & MT_SPM_EX_OP_DEVICES_SAVE)
|
||||||
|
MT_LP_SUSPEND_PUBLISH_EVENT(&event);
|
||||||
|
else
|
||||||
|
MT_LP_PUBLISH_EVENT(&event);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt_spm_idle_generic_resume(int state_id, uint32_t ext_opand,
|
||||||
|
struct wake_status **status,
|
||||||
|
spm_idle_conduct_restore fn)
|
||||||
|
{
|
||||||
|
struct mt_lp_publish_event event = {
|
||||||
|
.id = MT_LPM_PUBEVENTS_SYS_POWER_ON,
|
||||||
|
.val.u32 = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
event.level = determine_event_level(state_id);
|
||||||
|
|
||||||
|
ext_opand |= (MT_SPM_EX_OP_TIME_CHECK | MT_SPM_EX_OP_TIME_OBS);
|
||||||
|
spm_conservation_finish(state_id, ext_opand, &idle_spm_lp, status);
|
||||||
|
|
||||||
|
mt_spm_update_lp_stat(&idle_lp_stat);
|
||||||
|
|
||||||
|
if (spm_unlikely(fn))
|
||||||
|
fn(state_id, &idle_spm_lp, *status);
|
||||||
|
|
||||||
|
if (ext_opand & MT_SPM_EX_OP_DEVICES_SAVE) {
|
||||||
|
mmio_write_32(SPM2SW_MAILBOX_0, 0x0);
|
||||||
|
MT_LP_SUSPEND_PUBLISH_EVENT(&event);
|
||||||
|
} else
|
||||||
|
MT_LP_PUBLISH_EVENT(&event);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_spm_idle_generic_get_spm_lp(struct spm_lp_scen **lp)
|
||||||
|
{
|
||||||
|
if (!lp)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*lp = &idle_spm_lp;
|
||||||
|
return 0;
|
||||||
|
}
|
27
plat/mediatek/drivers/spm/mt8196/mt_spm_idle.h
Normal file
27
plat/mediatek/drivers/spm/mt8196/mt_spm_idle.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_SPM_IDLE_H
|
||||||
|
#define MT_SPM_IDLE_H
|
||||||
|
|
||||||
|
#include <mt_spm_internal.h>
|
||||||
|
|
||||||
|
typedef int (*spm_idle_conduct)(int state_id, struct spm_lp_scen *spm_lp,
|
||||||
|
uint32_t *resource_req);
|
||||||
|
|
||||||
|
typedef int (*spm_idle_conduct_restore)(int state_id,
|
||||||
|
struct spm_lp_scen *spm_lp,
|
||||||
|
struct wake_status *status);
|
||||||
|
|
||||||
|
int mt_spm_idle_generic_enter(int state_id, uint32_t ext_opand,
|
||||||
|
spm_idle_conduct fn);
|
||||||
|
void mt_spm_idle_generic_resume(int state_id, uint32_t ext_opand,
|
||||||
|
struct wake_status **status,
|
||||||
|
spm_idle_conduct_restore fn);
|
||||||
|
|
||||||
|
int mt_spm_idle_generic_get_spm_lp(struct spm_lp_scen **lp);
|
||||||
|
|
||||||
|
#endif /* MT_SPM_IDLE_H */
|
825
plat/mediatek/drivers/spm/mt8196/mt_spm_internal.c
Normal file
825
plat/mediatek/drivers/spm/mt8196/mt_spm_internal.c
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
1206
plat/mediatek/drivers/spm/mt8196/mt_spm_internal.h
Normal file
1206
plat/mediatek/drivers/spm/mt8196/mt_spm_internal.h
Normal file
File diff suppressed because it is too large
Load diff
255
plat/mediatek/drivers/spm/mt8196/mt_spm_pmic_lp.c
Normal file
255
plat/mediatek/drivers/spm/mt8196/mt_spm_pmic_lp.c
Normal file
|
@ -0,0 +1,255 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <common/debug.h>
|
||||||
|
#include <lib/mmio.h>
|
||||||
|
|
||||||
|
#include <drivers/pmic/pmic_set_lowpower.h>
|
||||||
|
#include <drivers/spmi/spmi_common.h>
|
||||||
|
#include <lib/mtk_init/mtk_init.h>
|
||||||
|
#include <mt_spm_constraint.h>
|
||||||
|
#include <mt_spm_pmic_lp.h>
|
||||||
|
#include <mt_spm_reg.h>
|
||||||
|
|
||||||
|
/* SPMI_M: 6363, SPMI_P: 6373/6316 */
|
||||||
|
/* SPMI_M: 6363, SPMI_P: 6373/6316 */
|
||||||
|
static struct lp_pmic_cfg {
|
||||||
|
uint8_t slave;
|
||||||
|
uint8_t master;
|
||||||
|
char *name;
|
||||||
|
} pmics[] = {
|
||||||
|
[LP_MT6363] = {MT6363_SLAVE, SPMI_MASTER_1, "MT6363"},
|
||||||
|
[LP_MT6373] = {MT6373_SLAVE, SPMI_MASTER_P_1, "MT6373"},
|
||||||
|
[LP_MT6316_1] = {MT6316_S8_SLAVE, SPMI_MASTER_P_1, "MT6316_S8"},
|
||||||
|
[LP_MT6316_2] = {MT6316_S6_SLAVE, SPMI_MASTER_P_1, "MT6316_S6"},
|
||||||
|
[LP_MT6316_3] = {MT6316_S7_SLAVE, SPMI_MASTER_P_1, "MT6316_S7"},
|
||||||
|
[LP_MT6316_4] = {MT6316_S15_SLAVE, SPMI_MASTER_P_1, "MT6316_S15"},
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef MTK_SPM_PMIC_GS_DUMP
|
||||||
|
static struct pmic_gs_info pmic_gs_dump_info;
|
||||||
|
static char *pmic_str[] = {
|
||||||
|
[LP_MT6363] = "MT6363",
|
||||||
|
[LP_MT6373] = "MT6373",
|
||||||
|
[LP_MT6316_1] = "MT6316_1",
|
||||||
|
[LP_MT6316_2] = "MT6316_2",
|
||||||
|
[LP_MT6316_3] = "MT6316_3",
|
||||||
|
[LP_MT6316_4] = "MT6316_4",
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
struct spmi_device *lp_sdev[LP_PMIC_SLAVE_NUM];
|
||||||
|
|
||||||
|
#define VSRAM_CORE_0_35V 56
|
||||||
|
#define VSRAM_CORE_0_55V 88
|
||||||
|
#define VSRAM_CORE_0_75V 120
|
||||||
|
|
||||||
|
/* VSRAM_CORE Low bound */
|
||||||
|
#ifdef MTK_AGING_FLAVOR_LOAD
|
||||||
|
#define SUSPEND_AGING_VAL_SHIFT 3
|
||||||
|
#define SUSPEND_AGING_VAL_DEFAULT 85
|
||||||
|
#define VSRAM_CORE_LOWBOUND (74 - SUSPEND_AGING_VAL_SHIFT)
|
||||||
|
#else
|
||||||
|
#define VSRAM_CORE_LOWBOUND 74
|
||||||
|
#endif
|
||||||
|
#define MT6363_LP_REG 0x1687
|
||||||
|
#define MT6363_VIO18_SWITCH 0x53
|
||||||
|
#define MT6373_VIO18_SWITCH 0x58
|
||||||
|
|
||||||
|
static uint32_t vcore_sram_suspend_vol = VSRAM_CORE_0_55V;
|
||||||
|
static bool vcore_sram_lp_enable = true;
|
||||||
|
static bool vcore_lp_enable = true;
|
||||||
|
|
||||||
|
static uint32_t get_vcore_sram_suspend_vol(void)
|
||||||
|
{
|
||||||
|
uint8_t value;
|
||||||
|
/* Set vcore_sram to 0.55V by default */
|
||||||
|
value = VSRAM_CORE_0_55V;
|
||||||
|
|
||||||
|
#ifdef MTK_AGING_FLAVOR_LOAD
|
||||||
|
value -= SUSPEND_AGING_VAL_SHIFT;
|
||||||
|
if (value > SUSPEND_AGING_VAL_DEFAULT)
|
||||||
|
value = SUSPEND_AGING_VAL_DEFAULT;
|
||||||
|
INFO("%s(%d) enable aging with value: %u\n",
|
||||||
|
__func__, __LINE__, value);
|
||||||
|
#endif
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MTK_SPM_PMIC_GS_DUMP
|
||||||
|
static void mt_spm_dump_pmic_gs(uint32_t cmd)
|
||||||
|
{
|
||||||
|
#ifdef MTK_SPM_PMIC_GS_DUMP_SUSPEND
|
||||||
|
if (cmd & MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND) { /* Suspend enter */
|
||||||
|
mt_spm_pmic_gs_dump(SUSPEND, LP_MT6363);
|
||||||
|
mt_spm_pmic_gs_dump(SUSPEND, LP_MT6373);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (cmd & MT_RM_CONSTRAINT_ALLOW_VCORE_LP) {
|
||||||
|
if (cmd & MT_RM_CONSTRAINT_ALLOW_BUS26M_OFF) { /* SODI3 */
|
||||||
|
#ifdef MTK_SPM_PMIC_GS_DUMP_SODI3
|
||||||
|
mt_spm_pmic_gs_dump(SODI3, LP_MT6363);
|
||||||
|
mt_spm_pmic_gs_dump(SODI3, LP_MT6373);
|
||||||
|
#endif
|
||||||
|
} else { /* DPIDLE enter */
|
||||||
|
#ifdef MTK_SPM_PMIC_GS_DUMP_DPIDLE
|
||||||
|
mt_spm_pmic_gs_dump(DPIDLE, LP_MT6363);
|
||||||
|
mt_spm_pmic_gs_dump(DPIDLE, LP_MT6373);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int spm_lp_setting_init(void)
|
||||||
|
{
|
||||||
|
uint8_t i, slvid, spmi_master;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(pmics); i++) {
|
||||||
|
slvid = pmics[i].slave;
|
||||||
|
spmi_master = pmics[i].master;
|
||||||
|
lp_sdev[i] = get_spmi_device(spmi_master, slvid);
|
||||||
|
if (!lp_sdev[i])
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
PMIC_SLVID_BUCK_SET_LP(MT6316, S8, VBUCK1, RC8,
|
||||||
|
false, OP_MODE_LP, HW_OFF);
|
||||||
|
|
||||||
|
/* Get suspend case vcore_sram sleep voltage */
|
||||||
|
vcore_sram_suspend_vol = get_vcore_sram_suspend_vol();
|
||||||
|
|
||||||
|
#ifdef MTK_SPM_PMIC_GS_DUMP
|
||||||
|
pmic_gs_dump_info.lp_sdev = lp_sdev;
|
||||||
|
pmic_gs_dump_info.pmic_str = pmic_str;
|
||||||
|
pmic_gs_dump_info.pmic_num = LP_PMIC_SLAVE_NUM;
|
||||||
|
#ifdef MTK_SPM_PMIC_GS_DUMP_SUSPEND
|
||||||
|
pmic_gs_dump_info.scen_gs[SUSPEND].data = pmic_gs_suspend;
|
||||||
|
#endif
|
||||||
|
#ifdef MTK_SPM_PMIC_GS_DUMP_SODI3
|
||||||
|
pmic_gs_dump_info.scen_gs[SODI3].data = pmic_gs_sodi3;
|
||||||
|
#endif
|
||||||
|
#ifdef MTK_SPM_PMIC_GS_DUMP_DPIDLE
|
||||||
|
pmic_gs_dump_info.scen_gs[DPIDLE].data = pmic_gs_dpidle;
|
||||||
|
#endif
|
||||||
|
return register_pmic_gs_info(&pmic_gs_dump_info);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MTK_SPM_PMIC_LP_SUPPORT
|
||||||
|
MTK_PLAT_SETUP_0_INIT(spm_lp_setting_init);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void set_vcore_lp_enable(bool enable)
|
||||||
|
{
|
||||||
|
vcore_lp_enable = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_vcore_lp_enable(void)
|
||||||
|
{
|
||||||
|
return vcore_lp_enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_vsram_lp_enable(bool enable)
|
||||||
|
{
|
||||||
|
vcore_sram_lp_enable = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_vsram_lp_enable(void)
|
||||||
|
{
|
||||||
|
return vcore_sram_lp_enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_vsram_lp_volt(uint32_t volt)
|
||||||
|
{
|
||||||
|
/* Allow 0.35V ~ 0.75V */
|
||||||
|
if (volt < VSRAM_CORE_0_35V || volt > VSRAM_CORE_0_75V)
|
||||||
|
return;
|
||||||
|
vcore_sram_suspend_vol = volt;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t get_vsram_lp_volt(void)
|
||||||
|
{
|
||||||
|
return vcore_sram_suspend_vol;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pmic_lp_setting(uint8_t data)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (data != 0x0 && data != 0x1)
|
||||||
|
return -ENODEV;
|
||||||
|
/* SUSPEND:VS1 HW2&RC9 normal mode */
|
||||||
|
PMIC_BUCK_SET_LP(MT6363, VS1, HW2,
|
||||||
|
false, OP_MODE_LP, HW_LP);
|
||||||
|
PMIC_BUCK_SET_LP(MT6363, VS1, RC9,
|
||||||
|
false, OP_MODE_MU, HW_ON);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VIO18, HW2,
|
||||||
|
false, OP_MODE_LP, HW_LP);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VIO18, RC9,
|
||||||
|
false, OP_MODE_MU, HW_ON);
|
||||||
|
|
||||||
|
/* Switch DIG18 to VIO18 for power saving */
|
||||||
|
ret = spmi_ext_register_writel(lp_sdev[LP_MT6363], MT6363_VIO18_SWITCH, &data, 1);
|
||||||
|
if (ret)
|
||||||
|
INFO("MT6363 RG_VIO18 spmi failed\n");
|
||||||
|
|
||||||
|
ret = spmi_ext_register_writel(lp_sdev[LP_MT6373], MT6373_VIO18_SWITCH, &data, 1);
|
||||||
|
if (ret)
|
||||||
|
INFO("MT6373 RG_VIO18 spmi failed\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int do_spm_low_power(enum SPM_PWR_TYPE type, uint32_t cmd)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint8_t value;
|
||||||
|
bool enter_suspend, vcore_sram_lp = false;
|
||||||
|
|
||||||
|
if (type == SPM_LP_ENTER) {
|
||||||
|
enter_suspend = true;
|
||||||
|
vcore_sram_lp = vcore_sram_lp_enable;
|
||||||
|
|
||||||
|
if (cmd & MT_RM_CONSTRAINT_ALLOW_AP_PLAT_SUSPEND) {
|
||||||
|
value = vcore_sram_suspend_vol;
|
||||||
|
if (value < VSRAM_CORE_LOWBOUND ||
|
||||||
|
value > VSRAM_CORE_0_75V) {
|
||||||
|
INFO("Vsram_core voltage wrong\n");
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = VSRAM_CORE_0_55V;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
enter_suspend = false;
|
||||||
|
vcore_sram_lp = false;
|
||||||
|
value = VSRAM_CORE_0_75V;
|
||||||
|
}
|
||||||
|
/* Enable VA12_2/VSRAM_CPUL HW_LP for suspend/idle */
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VA12_2, HW2, enter_suspend, OP_MODE_LP, HW_LP);
|
||||||
|
PMIC_LDO_SET_LP(MT6363, VSRAM_CPUL, HW2,
|
||||||
|
enter_suspend, OP_MODE_LP, HW_LP);
|
||||||
|
|
||||||
|
if (!(cmd & MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND))
|
||||||
|
return 0;
|
||||||
|
PMIC_SLVID_BUCK_SET_LP(MT6316, S8, VBUCK1, HW2, vcore_lp_enable,
|
||||||
|
OP_MODE_LP, HW_LP);
|
||||||
|
PMIC_BUCK_SET_LP(MT6363, VBUCK4, HW0, vcore_sram_lp,
|
||||||
|
OP_MODE_LP, HW_LP);
|
||||||
|
PMIC_BUCK_SET_LP(MT6363, VBUCK4, HW2, !enter_suspend,
|
||||||
|
OP_MODE_LP, HW_LP);
|
||||||
|
ret = spmi_ext_register_writel(lp_sdev[LP_MT6363], MT6363_LP_REG, &value, 1);
|
||||||
|
if (ret)
|
||||||
|
INFO("BUCK(VSRAM_CORE) spmi write failed\n");
|
||||||
|
|
||||||
|
if (cmd & MT_RM_CONSTRAINT_ALLOW_AP_PLAT_SUSPEND)
|
||||||
|
pmic_lp_setting(enter_suspend ? 1 : 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
74
plat/mediatek/drivers/spm/mt8196/mt_spm_pmic_lp.h
Normal file
74
plat/mediatek/drivers/spm/mt8196/mt_spm_pmic_lp.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_SPM_PMIC_LP_H
|
||||||
|
#define MT_SPM_PMIC_LP_H
|
||||||
|
|
||||||
|
enum SPM_PWR_TYPE {
|
||||||
|
SPM_LP_ENTER,
|
||||||
|
SPM_LP_RESUME
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
LP_MT6363 = 0,
|
||||||
|
LP_MT6373,
|
||||||
|
LP_MT6316_1,
|
||||||
|
LP_MT6316_2,
|
||||||
|
LP_MT6316_3,
|
||||||
|
LP_MT6316_4,
|
||||||
|
LP_PMIC_SLAVE_NUM,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef MTK_SPM_PMIC_LP_SUPPORT
|
||||||
|
void set_vcore_lp_enable(bool enable);
|
||||||
|
bool get_vcore_lp_enable(void);
|
||||||
|
|
||||||
|
void set_vsram_lp_enable(bool enable);
|
||||||
|
bool get_vsram_lp_enable(void);
|
||||||
|
void set_vsram_lp_volt(uint32_t volt);
|
||||||
|
uint32_t get_vsram_lp_volt(void);
|
||||||
|
|
||||||
|
int do_spm_low_power(enum SPM_PWR_TYPE type, uint32_t cmd);
|
||||||
|
#else
|
||||||
|
static inline void set_vcore_lp_enable(bool enable)
|
||||||
|
{
|
||||||
|
(void)enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool get_vcore_lp_enable(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void set_vsram_lp_enable(bool enable)
|
||||||
|
{
|
||||||
|
(void)enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool get_vsram_lp_enable(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void set_vsram_lp_volt(uint32_t volt)
|
||||||
|
{
|
||||||
|
(void)volt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t get_vsram_lp_volt(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int do_spm_low_power(enum SPM_PWR_TYPE type, uint32_t cmd)
|
||||||
|
{
|
||||||
|
(void)type;
|
||||||
|
(void)cmd;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* MTK_SPM_PMIC_LP_SUPPORT */
|
||||||
|
|
||||||
|
#endif /* MT_SPM_PMIC_LP_H */
|
2099
plat/mediatek/drivers/spm/mt8196/mt_spm_reg.h
Normal file
2099
plat/mediatek/drivers/spm/mt8196/mt_spm_reg.h
Normal file
File diff suppressed because it is too large
Load diff
65
plat/mediatek/drivers/spm/mt8196/mt_spm_stats.c
Normal file
65
plat/mediatek/drivers/spm/mt8196/mt_spm_stats.c
Normal file
|
@ -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;
|
||||||
|
}
|
43
plat/mediatek/drivers/spm/mt8196/mt_spm_stats.h
Normal file
43
plat/mediatek/drivers/spm/mt8196/mt_spm_stats.h
Normal file
|
@ -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 */
|
711
plat/mediatek/drivers/spm/mt8196/mt_spm_suspend.c
Normal file
711
plat/mediatek/drivers/spm/mt8196/mt_spm_suspend.c
Normal file
|
@ -0,0 +1,711 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <common/debug.h>
|
||||||
|
#include <drivers/delay_timer.h>
|
||||||
|
#include <drivers/gpio.h>
|
||||||
|
#include <lib/mmio.h>
|
||||||
|
|
||||||
|
#include <constraints/mt_spm_rc_internal.h>
|
||||||
|
#include <drivers/spm/mt_spm_resource_req.h>
|
||||||
|
#include <lib/pm/mtk_pm.h>
|
||||||
|
#include <lpm_v2/mt_lp_api.h>
|
||||||
|
#include <lpm_v2/mt_lp_rqm.h>
|
||||||
|
#include <mt_spm.h>
|
||||||
|
#include <mt_spm_conservation.h>
|
||||||
|
#include <mt_spm_internal.h>
|
||||||
|
#include <mt_spm_reg.h>
|
||||||
|
#include <mt_spm_stats.h>
|
||||||
|
#include <mt_spm_suspend.h>
|
||||||
|
#if defined(CONFIG_MTK_VCOREDVFS_SUPPORT)
|
||||||
|
#include <mt_spm_vcorefs_exp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SPM_SUSPEND_SLEEP_PCM_FLAG (SPM_FLAG_DISABLE_DDR_DFS | \
|
||||||
|
SPM_FLAG_DISABLE_EMI_DFS | \
|
||||||
|
SPM_FLAG_DISABLE_VLP_PDN | \
|
||||||
|
SPM_FLAG_DISABLE_BUS_DFS | \
|
||||||
|
SPM_FLAG_KEEP_CSYSPWRACK_HIGH | \
|
||||||
|
SPM_FLAG_ENABLE_AOV | \
|
||||||
|
SPM_FLAG_ENABLE_MD_MUMTAS | \
|
||||||
|
SPM_FLAG_SRAM_SLEEP_CTRL)
|
||||||
|
|
||||||
|
#define SPM_SUSPEND_SLEEP_PCM_FLAG1 (SPM_FLAG1_ENABLE_ALCO_TRACE | \
|
||||||
|
SPM_FLAG1_ENABLE_SUSPEND_AVS)
|
||||||
|
|
||||||
|
#define SPM_SUSPEND_PCM_FLAG (SPM_FLAG_DISABLE_VCORE_DVS | \
|
||||||
|
SPM_FLAG_DISABLE_MCUPM_PDN | \
|
||||||
|
SPM_FLAG_DISABLE_VLP_PDN | \
|
||||||
|
SPM_FLAG_DISABLE_DDR_DFS | \
|
||||||
|
SPM_FLAG_DISABLE_EMI_DFS | \
|
||||||
|
SPM_FLAG_DISABLE_BUS_DFS | \
|
||||||
|
SPM_FLAG_ENABLE_MD_MUMTAS | \
|
||||||
|
SPM_FLAG_SRAM_SLEEP_CTRL)
|
||||||
|
|
||||||
|
#define SPM_SUSPEND_PCM_FLAG1 (SPM_FLAG1_ENABLE_ALCO_TRACE | \
|
||||||
|
SPM_FLAG1_ENABLE_SUSPEND_AVS | \
|
||||||
|
SPM_FLAG1_ENABLE_CSOPLU_OFF)
|
||||||
|
|
||||||
|
/* Suspend spm power control */
|
||||||
|
#define __WAKE_SRC_FOR_SUSPEND_COMMON__ ( \
|
||||||
|
(R12_KP_IRQ_B) | \
|
||||||
|
(R12_APWDT_EVENT_B) | \
|
||||||
|
(R12_CONN2AP_WAKEUP_B) | \
|
||||||
|
(R12_EINT_EVENT_B) | \
|
||||||
|
(R12_CONN_WDT_IRQ_B) | \
|
||||||
|
(R12_CCIF0_EVENT_B) | \
|
||||||
|
(R12_CCIF1_EVENT_B) | \
|
||||||
|
(R12_SCP2SPM_WAKEUP_B) | \
|
||||||
|
(R12_ADSP2SPM_WAKEUP_B) | \
|
||||||
|
(R12_USB0_CDSC_B) | \
|
||||||
|
(R12_USB0_POWERDWN_B) | \
|
||||||
|
(R12_UART_EVENT_B) |\
|
||||||
|
(R12_SYS_TIMER_EVENT_B) | \
|
||||||
|
(R12_EINT_EVENT_SECURE_B) | \
|
||||||
|
(R12_SYS_CIRQ_IRQ_B) | \
|
||||||
|
(R12_MD_WDT_B) | \
|
||||||
|
(R12_AP2AP_PEER_WAKEUP_B) | \
|
||||||
|
(R12_CPU_WAKEUP) | \
|
||||||
|
(R12_APUSYS_WAKE_HOST_B)|\
|
||||||
|
(R12_PCIE_WAKE_B))
|
||||||
|
|
||||||
|
#if defined(CFG_MICROTRUST_TEE_SUPPORT)
|
||||||
|
#define WAKE_SRC_FOR_SUSPEND \
|
||||||
|
(__WAKE_SRC_FOR_SUSPEND_COMMON__)
|
||||||
|
#else
|
||||||
|
#define WAKE_SRC_FOR_SUSPEND \
|
||||||
|
(__WAKE_SRC_FOR_SUSPEND_COMMON__ | \
|
||||||
|
R12_SEJ_B)
|
||||||
|
#endif
|
||||||
|
static uint32_t gpio_bk1;
|
||||||
|
static uint32_t gpio_bk2;
|
||||||
|
static uint32_t gpio_bk3;
|
||||||
|
|
||||||
|
static struct pwr_ctrl suspend_ctrl = {
|
||||||
|
.wake_src = WAKE_SRC_FOR_SUSPEND,
|
||||||
|
|
||||||
|
/* SPM_SRC_REQ */
|
||||||
|
.reg_spm_adsp_mailbox_req = 0,
|
||||||
|
.reg_spm_apsrc_req = 0,
|
||||||
|
.reg_spm_ddren_req = 0,
|
||||||
|
.reg_spm_dvfs_req = 0,
|
||||||
|
.reg_spm_emi_req = 0,
|
||||||
|
.reg_spm_f26m_req = 0,
|
||||||
|
.reg_spm_infra_req = 0,
|
||||||
|
.reg_spm_pmic_req = 0,
|
||||||
|
.reg_spm_scp_mailbox_req = 0,
|
||||||
|
.reg_spm_sspm_mailbox_req = 0,
|
||||||
|
.reg_spm_sw_mailbox_req = 0,
|
||||||
|
.reg_spm_vcore_req = 1,
|
||||||
|
.reg_spm_vrf18_req = 0,
|
||||||
|
.adsp_mailbox_state = 0,
|
||||||
|
.apsrc_state = 0,
|
||||||
|
.ddren_state = 0,
|
||||||
|
.dvfs_state = 0,
|
||||||
|
.emi_state = 0,
|
||||||
|
.f26m_state = 0,
|
||||||
|
.infra_state = 0,
|
||||||
|
.pmic_state = 0,
|
||||||
|
.scp_mailbox_state = 0,
|
||||||
|
.sspm_mailbox_state = 0,
|
||||||
|
.sw_mailbox_state = 0,
|
||||||
|
.vcore_state = 0,
|
||||||
|
.vrf18_state = 0,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_0 */
|
||||||
|
.reg_apifr_apsrc_rmb = 0,
|
||||||
|
.reg_apifr_ddren_rmb = 0,
|
||||||
|
.reg_apifr_emi_rmb = 0,
|
||||||
|
.reg_apifr_infra_rmb = 0,
|
||||||
|
.reg_apifr_pmic_rmb = 0,
|
||||||
|
.reg_apifr_srcclkena_mb = 0,
|
||||||
|
.reg_apifr_vcore_rmb = 0,
|
||||||
|
.reg_apifr_vrf18_rmb = 0,
|
||||||
|
.reg_apu_apsrc_rmb = 1,
|
||||||
|
.reg_apu_ddren_rmb = 0,
|
||||||
|
.reg_apu_emi_rmb = 1,
|
||||||
|
.reg_apu_infra_rmb = 1,
|
||||||
|
.reg_apu_pmic_rmb = 1,
|
||||||
|
.reg_apu_srcclkena_mb = 1,
|
||||||
|
.reg_apu_vcore_rmb = 1,
|
||||||
|
.reg_apu_vrf18_rmb = 1,
|
||||||
|
.reg_audio_apsrc_rmb = 1,
|
||||||
|
.reg_audio_ddren_rmb = 0,
|
||||||
|
.reg_audio_emi_rmb = 1,
|
||||||
|
.reg_audio_infra_rmb = 1,
|
||||||
|
.reg_audio_pmic_rmb = 0,
|
||||||
|
.reg_audio_srcclkena_mb = 1,
|
||||||
|
.reg_audio_vcore_rmb = 1,
|
||||||
|
.reg_audio_vrf18_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_1 */
|
||||||
|
.reg_audio_dsp_apsrc_rmb = 1,
|
||||||
|
.reg_audio_dsp_ddren_rmb = 0,
|
||||||
|
.reg_audio_dsp_emi_rmb = 1,
|
||||||
|
.reg_audio_dsp_infra_rmb = 1,
|
||||||
|
.reg_audio_dsp_pmic_rmb = 1,
|
||||||
|
.reg_audio_dsp_srcclkena_mb = 1,
|
||||||
|
.reg_audio_dsp_vcore_rmb = 1,
|
||||||
|
.reg_audio_dsp_vrf18_rmb = 1,
|
||||||
|
.reg_cam_apsrc_rmb = 0,
|
||||||
|
.reg_cam_ddren_rmb = 0,
|
||||||
|
.reg_cam_emi_rmb = 0,
|
||||||
|
.reg_cam_infra_rmb = 0,
|
||||||
|
.reg_cam_pmic_rmb = 0,
|
||||||
|
.reg_cam_srcclkena_mb = 0,
|
||||||
|
.reg_cam_vrf18_rmb = 0,
|
||||||
|
.reg_ccif_apsrc_rmb = 0xfff,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_2 */
|
||||||
|
.reg_ccif_emi_rmb = 0xfff,
|
||||||
|
.reg_ccif_infra_rmb = 0xfff,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_3 */
|
||||||
|
.reg_ccif_pmic_rmb = 0xfff,
|
||||||
|
.reg_ccif_srcclkena_mb = 0xfff,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_4 */
|
||||||
|
.reg_ccif_vcore_rmb = 0xfff,
|
||||||
|
.reg_ccif_vrf18_rmb = 0xfff,
|
||||||
|
.reg_ccu_apsrc_rmb = 0,
|
||||||
|
.reg_ccu_ddren_rmb = 0,
|
||||||
|
.reg_ccu_emi_rmb = 0,
|
||||||
|
.reg_ccu_infra_rmb = 0,
|
||||||
|
.reg_ccu_pmic_rmb = 0,
|
||||||
|
.reg_ccu_srcclkena_mb = 0,
|
||||||
|
.reg_ccu_vrf18_rmb = 0,
|
||||||
|
.reg_cg_check_apsrc_rmb = 0,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_5 */
|
||||||
|
.reg_cg_check_ddren_rmb = 0,
|
||||||
|
.reg_cg_check_emi_rmb = 0,
|
||||||
|
.reg_cg_check_infra_rmb = 0,
|
||||||
|
.reg_cg_check_pmic_rmb = 0,
|
||||||
|
.reg_cg_check_srcclkena_mb = 0,
|
||||||
|
.reg_cg_check_vcore_rmb = 1,
|
||||||
|
.reg_cg_check_vrf18_rmb = 0,
|
||||||
|
.reg_cksys_apsrc_rmb = 1,
|
||||||
|
.reg_cksys_ddren_rmb = 0,
|
||||||
|
.reg_cksys_emi_rmb = 1,
|
||||||
|
.reg_cksys_infra_rmb = 1,
|
||||||
|
.reg_cksys_pmic_rmb = 1,
|
||||||
|
.reg_cksys_srcclkena_mb = 1,
|
||||||
|
.reg_cksys_vcore_rmb = 1,
|
||||||
|
.reg_cksys_vrf18_rmb = 1,
|
||||||
|
.reg_cksys_1_apsrc_rmb = 1,
|
||||||
|
.reg_cksys_1_ddren_rmb = 0,
|
||||||
|
.reg_cksys_1_emi_rmb = 1,
|
||||||
|
.reg_cksys_1_infra_rmb = 1,
|
||||||
|
.reg_cksys_1_pmic_rmb = 1,
|
||||||
|
.reg_cksys_1_srcclkena_mb = 1,
|
||||||
|
.reg_cksys_1_vcore_rmb = 1,
|
||||||
|
.reg_cksys_1_vrf18_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_6 */
|
||||||
|
.reg_cksys_2_apsrc_rmb = 1,
|
||||||
|
.reg_cksys_2_ddren_rmb = 0,
|
||||||
|
.reg_cksys_2_emi_rmb = 1,
|
||||||
|
.reg_cksys_2_infra_rmb = 1,
|
||||||
|
.reg_cksys_2_pmic_rmb = 1,
|
||||||
|
.reg_cksys_2_srcclkena_mb = 1,
|
||||||
|
.reg_cksys_2_vcore_rmb = 1,
|
||||||
|
.reg_cksys_2_vrf18_rmb = 1,
|
||||||
|
.reg_conn_apsrc_rmb = 1,
|
||||||
|
.reg_conn_ddren_rmb = 0,
|
||||||
|
.reg_conn_emi_rmb = 1,
|
||||||
|
.reg_conn_infra_rmb = 1,
|
||||||
|
.reg_conn_pmic_rmb = 1,
|
||||||
|
.reg_conn_srcclkena_mb = 1,
|
||||||
|
.reg_conn_srcclkenb_mb = 1,
|
||||||
|
.reg_conn_vcore_rmb = 1,
|
||||||
|
.reg_conn_vrf18_rmb = 1,
|
||||||
|
.reg_corecfg_apsrc_rmb = 0,
|
||||||
|
.reg_corecfg_ddren_rmb = 0,
|
||||||
|
.reg_corecfg_emi_rmb = 0,
|
||||||
|
.reg_corecfg_infra_rmb = 0,
|
||||||
|
.reg_corecfg_pmic_rmb = 0,
|
||||||
|
.reg_corecfg_srcclkena_mb = 0,
|
||||||
|
.reg_corecfg_vcore_rmb = 0,
|
||||||
|
.reg_corecfg_vrf18_rmb = 0,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_7 */
|
||||||
|
.reg_cpueb_apsrc_rmb = 1,
|
||||||
|
.reg_cpueb_ddren_rmb = 0,
|
||||||
|
.reg_cpueb_emi_rmb = 1,
|
||||||
|
.reg_cpueb_infra_rmb = 1,
|
||||||
|
.reg_cpueb_pmic_rmb = 1,
|
||||||
|
.reg_cpueb_srcclkena_mb = 1,
|
||||||
|
.reg_cpueb_vcore_rmb = 0,
|
||||||
|
.reg_cpueb_vrf18_rmb = 1,
|
||||||
|
.reg_disp0_apsrc_rmb = 0,
|
||||||
|
.reg_disp0_ddren_rmb = 0,
|
||||||
|
.reg_disp0_emi_rmb = 0,
|
||||||
|
.reg_disp0_infra_rmb = 0,
|
||||||
|
.reg_disp0_pmic_rmb = 0,
|
||||||
|
.reg_disp0_srcclkena_mb = 0,
|
||||||
|
.reg_disp0_vrf18_rmb = 0,
|
||||||
|
.reg_disp1_apsrc_rmb = 0,
|
||||||
|
.reg_disp1_ddren_rmb = 0,
|
||||||
|
.reg_disp1_emi_rmb = 0,
|
||||||
|
.reg_disp1_infra_rmb = 0,
|
||||||
|
.reg_disp1_pmic_rmb = 0,
|
||||||
|
.reg_disp1_srcclkena_mb = 0,
|
||||||
|
.reg_disp1_vrf18_rmb = 0,
|
||||||
|
.reg_dpm_apsrc_rmb = 0xf,
|
||||||
|
.reg_dpm_ddren_rmb = 0xf,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_8 */
|
||||||
|
.reg_dpm_emi_rmb = 0xf,
|
||||||
|
.reg_dpm_infra_rmb = 0xf,
|
||||||
|
.reg_dpm_pmic_rmb = 0xf,
|
||||||
|
.reg_dpm_srcclkena_mb = 0xf,
|
||||||
|
.reg_dpm_vcore_rmb = 0xf,
|
||||||
|
.reg_dpm_vrf18_rmb = 0xf,
|
||||||
|
.reg_dpmaif_apsrc_rmb = 1,
|
||||||
|
.reg_dpmaif_ddren_rmb = 0,
|
||||||
|
.reg_dpmaif_emi_rmb = 1,
|
||||||
|
.reg_dpmaif_infra_rmb = 1,
|
||||||
|
.reg_dpmaif_pmic_rmb = 1,
|
||||||
|
.reg_dpmaif_srcclkena_mb = 1,
|
||||||
|
.reg_dpmaif_vcore_rmb = 1,
|
||||||
|
.reg_dpmaif_vrf18_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_9 */
|
||||||
|
.reg_dvfsrc_level_rmb = 1,
|
||||||
|
.reg_emisys_apsrc_rmb = 0,
|
||||||
|
.reg_emisys_ddren_rmb = 0,
|
||||||
|
.reg_emisys_emi_rmb = 0,
|
||||||
|
.reg_emisys_infra_rmb = 0,
|
||||||
|
.reg_emisys_pmic_rmb = 0,
|
||||||
|
.reg_emisys_srcclkena_mb = 0,
|
||||||
|
.reg_emisys_vcore_rmb = 0,
|
||||||
|
.reg_emisys_vrf18_rmb = 0,
|
||||||
|
.reg_gce_apsrc_rmb = 0,
|
||||||
|
.reg_gce_ddren_rmb = 0,
|
||||||
|
.reg_gce_emi_rmb = 0,
|
||||||
|
.reg_gce_infra_rmb = 0,
|
||||||
|
.reg_gce_pmic_rmb = 0,
|
||||||
|
.reg_gce_srcclkena_mb = 0,
|
||||||
|
.reg_gce_vcore_rmb = 0,
|
||||||
|
.reg_gce_vrf18_rmb = 0,
|
||||||
|
.reg_gpueb_apsrc_rmb = 1,
|
||||||
|
.reg_gpueb_ddren_rmb = 0,
|
||||||
|
.reg_gpueb_emi_rmb = 1,
|
||||||
|
.reg_gpueb_infra_rmb = 1,
|
||||||
|
.reg_gpueb_pmic_rmb = 1,
|
||||||
|
.reg_gpueb_srcclkena_mb = 1,
|
||||||
|
.reg_gpueb_vcore_rmb = 1,
|
||||||
|
.reg_gpueb_vrf18_rmb = 1,
|
||||||
|
.reg_hwccf_apsrc_rmb = 1,
|
||||||
|
.reg_hwccf_ddren_rmb = 0,
|
||||||
|
.reg_hwccf_emi_rmb = 1,
|
||||||
|
.reg_hwccf_infra_rmb = 1,
|
||||||
|
.reg_hwccf_pmic_rmb = 1,
|
||||||
|
.reg_hwccf_srcclkena_mb = 1,
|
||||||
|
.reg_hwccf_vcore_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_10 */
|
||||||
|
.reg_hwccf_vrf18_rmb = 1,
|
||||||
|
.reg_img_apsrc_rmb = 0,
|
||||||
|
.reg_img_ddren_rmb = 0,
|
||||||
|
.reg_img_emi_rmb = 0,
|
||||||
|
.reg_img_infra_rmb = 0,
|
||||||
|
.reg_img_pmic_rmb = 0,
|
||||||
|
.reg_img_srcclkena_mb = 0,
|
||||||
|
.reg_img_vrf18_rmb = 0,
|
||||||
|
.reg_infrasys_apsrc_rmb = 0,
|
||||||
|
.reg_infrasys_ddren_rmb = 0,
|
||||||
|
.reg_infrasys_emi_rmb = 0,
|
||||||
|
.reg_infrasys_infra_rmb = 0,
|
||||||
|
.reg_infrasys_pmic_rmb = 0,
|
||||||
|
.reg_infrasys_srcclkena_mb = 0,
|
||||||
|
.reg_infrasys_vcore_rmb = 0,
|
||||||
|
.reg_infrasys_vrf18_rmb = 0,
|
||||||
|
.reg_ipic_infra_rmb = 1,
|
||||||
|
.reg_ipic_vrf18_rmb = 1,
|
||||||
|
.reg_mcu_apsrc_rmb = 1,
|
||||||
|
.reg_mcu_ddren_rmb = 0,
|
||||||
|
.reg_mcu_emi_rmb = 1,
|
||||||
|
.reg_mcu_infra_rmb = 1,
|
||||||
|
.reg_mcu_pmic_rmb = 1,
|
||||||
|
.reg_mcu_srcclkena_mb = 1,
|
||||||
|
.reg_mcu_vcore_rmb = 0,
|
||||||
|
.reg_mcu_vrf18_rmb = 1,
|
||||||
|
.reg_md_apsrc_rmb = 1,
|
||||||
|
.reg_md_ddren_rmb = 0,
|
||||||
|
.reg_md_emi_rmb = 1,
|
||||||
|
.reg_md_infra_rmb = 1,
|
||||||
|
.reg_md_pmic_rmb = 1,
|
||||||
|
.reg_md_srcclkena_mb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_11 */
|
||||||
|
.reg_md_srcclkena1_mb = 1,
|
||||||
|
.reg_md_vcore_rmb = 1,
|
||||||
|
.reg_md_vrf18_rmb = 1,
|
||||||
|
.reg_mm_proc_apsrc_rmb = 1,
|
||||||
|
.reg_mm_proc_ddren_rmb = 0,
|
||||||
|
.reg_mm_proc_emi_rmb = 1,
|
||||||
|
.reg_mm_proc_infra_rmb = 1,
|
||||||
|
.reg_mm_proc_pmic_rmb = 1,
|
||||||
|
.reg_mm_proc_srcclkena_mb = 1,
|
||||||
|
.reg_mm_proc_vcore_rmb = 1,
|
||||||
|
.reg_mm_proc_vrf18_rmb = 1,
|
||||||
|
.reg_mml0_apsrc_rmb = 0,
|
||||||
|
.reg_mml0_ddren_rmb = 0,
|
||||||
|
.reg_mml0_emi_rmb = 0,
|
||||||
|
.reg_mml0_infra_rmb = 0,
|
||||||
|
.reg_mml0_pmic_rmb = 0,
|
||||||
|
.reg_mml0_srcclkena_mb = 0,
|
||||||
|
.reg_mml0_vrf18_rmb = 0,
|
||||||
|
.reg_mml1_apsrc_rmb = 0,
|
||||||
|
.reg_mml1_ddren_rmb = 0,
|
||||||
|
.reg_mml1_emi_rmb = 0,
|
||||||
|
.reg_mml1_infra_rmb = 0,
|
||||||
|
.reg_mml1_pmic_rmb = 0,
|
||||||
|
.reg_mml1_srcclkena_mb = 0,
|
||||||
|
.reg_mml1_vrf18_rmb = 0,
|
||||||
|
.reg_ovl0_apsrc_rmb = 0,
|
||||||
|
.reg_ovl0_ddren_rmb = 0,
|
||||||
|
.reg_ovl0_emi_rmb = 0,
|
||||||
|
.reg_ovl0_infra_rmb = 0,
|
||||||
|
.reg_ovl0_pmic_rmb = 0,
|
||||||
|
.reg_ovl0_srcclkena_mb = 0,
|
||||||
|
.reg_ovl0_vrf18_rmb = 0,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_12 */
|
||||||
|
.reg_ovl1_apsrc_rmb = 0,
|
||||||
|
.reg_ovl1_ddren_rmb = 0,
|
||||||
|
.reg_ovl1_emi_rmb = 0,
|
||||||
|
.reg_ovl1_infra_rmb = 0,
|
||||||
|
.reg_ovl1_pmic_rmb = 0,
|
||||||
|
.reg_ovl1_srcclkena_mb = 0,
|
||||||
|
.reg_ovl1_vrf18_rmb = 0,
|
||||||
|
.reg_pcie0_apsrc_rmb = 1,
|
||||||
|
.reg_pcie0_ddren_rmb = 0,
|
||||||
|
.reg_pcie0_emi_rmb = 1,
|
||||||
|
.reg_pcie0_infra_rmb = 1,
|
||||||
|
.reg_pcie0_pmic_rmb = 1,
|
||||||
|
.reg_pcie0_srcclkena_mb = 1,
|
||||||
|
.reg_pcie0_vcore_rmb = 1,
|
||||||
|
.reg_pcie0_vrf18_rmb = 1,
|
||||||
|
.reg_pcie1_apsrc_rmb = 1,
|
||||||
|
.reg_pcie1_ddren_rmb = 0,
|
||||||
|
.reg_pcie1_emi_rmb = 1,
|
||||||
|
.reg_pcie1_infra_rmb = 1,
|
||||||
|
.reg_pcie1_pmic_rmb = 1,
|
||||||
|
.reg_pcie1_srcclkena_mb = 1,
|
||||||
|
.reg_pcie1_vcore_rmb = 1,
|
||||||
|
.reg_pcie1_vrf18_rmb = 1,
|
||||||
|
.reg_perisys_apsrc_rmb = 1,
|
||||||
|
.reg_perisys_ddren_rmb = 0,
|
||||||
|
.reg_perisys_emi_rmb = 1,
|
||||||
|
.reg_perisys_infra_rmb = 1,
|
||||||
|
.reg_perisys_pmic_rmb = 1,
|
||||||
|
.reg_perisys_srcclkena_mb = 1,
|
||||||
|
.reg_perisys_vcore_rmb = 1,
|
||||||
|
.reg_perisys_vrf18_rmb = 1,
|
||||||
|
.reg_pmsr_apsrc_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_13 */
|
||||||
|
.reg_pmsr_ddren_rmb = 0,
|
||||||
|
.reg_pmsr_emi_rmb = 1,
|
||||||
|
.reg_pmsr_infra_rmb = 1,
|
||||||
|
.reg_pmsr_pmic_rmb = 1,
|
||||||
|
.reg_pmsr_srcclkena_mb = 1,
|
||||||
|
.reg_pmsr_vcore_rmb = 1,
|
||||||
|
.reg_pmsr_vrf18_rmb = 1,
|
||||||
|
.reg_scp_apsrc_rmb = 1,
|
||||||
|
.reg_scp_ddren_rmb = 0,
|
||||||
|
.reg_scp_emi_rmb = 1,
|
||||||
|
.reg_scp_infra_rmb = 1,
|
||||||
|
.reg_scp_pmic_rmb = 1,
|
||||||
|
.reg_scp_srcclkena_mb = 1,
|
||||||
|
.reg_scp_vcore_rmb = 1,
|
||||||
|
.reg_scp_vrf18_rmb = 1,
|
||||||
|
.reg_spu_hwr_apsrc_rmb = 1,
|
||||||
|
.reg_spu_hwr_ddren_rmb = 0,
|
||||||
|
.reg_spu_hwr_emi_rmb = 1,
|
||||||
|
.reg_spu_hwr_infra_rmb = 1,
|
||||||
|
.reg_spu_hwr_pmic_rmb = 1,
|
||||||
|
.reg_spu_hwr_srcclkena_mb = 1,
|
||||||
|
.reg_spu_hwr_vcore_rmb = 1,
|
||||||
|
.reg_spu_hwr_vrf18_rmb = 1,
|
||||||
|
.reg_spu_ise_apsrc_rmb = 1,
|
||||||
|
.reg_spu_ise_ddren_rmb = 0,
|
||||||
|
.reg_spu_ise_emi_rmb = 1,
|
||||||
|
.reg_spu_ise_infra_rmb = 1,
|
||||||
|
.reg_spu_ise_pmic_rmb = 1,
|
||||||
|
.reg_spu_ise_srcclkena_mb = 1,
|
||||||
|
.reg_spu_ise_vcore_rmb = 1,
|
||||||
|
.reg_spu_ise_vrf18_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_14 */
|
||||||
|
.reg_srcclkeni_infra_rmb = 0x3,
|
||||||
|
.reg_srcclkeni_pmic_rmb = 0x3,
|
||||||
|
.reg_srcclkeni_srcclkena_mb = 0x3,
|
||||||
|
.reg_srcclkeni_vcore_rmb = 0x3,
|
||||||
|
.reg_sspm_apsrc_rmb = 1,
|
||||||
|
.reg_sspm_ddren_rmb = 0,
|
||||||
|
.reg_sspm_emi_rmb = 1,
|
||||||
|
.reg_sspm_infra_rmb = 1,
|
||||||
|
.reg_sspm_pmic_rmb = 1,
|
||||||
|
.reg_sspm_srcclkena_mb = 1,
|
||||||
|
.reg_sspm_vrf18_rmb = 1,
|
||||||
|
.reg_ssrsys_apsrc_rmb = 1,
|
||||||
|
.reg_ssrsys_ddren_rmb = 0,
|
||||||
|
.reg_ssrsys_emi_rmb = 1,
|
||||||
|
.reg_ssrsys_infra_rmb = 1,
|
||||||
|
.reg_ssrsys_pmic_rmb = 1,
|
||||||
|
.reg_ssrsys_srcclkena_mb = 1,
|
||||||
|
.reg_ssrsys_vcore_rmb = 1,
|
||||||
|
.reg_ssrsys_vrf18_rmb = 1,
|
||||||
|
.reg_ssusb_apsrc_rmb = 1,
|
||||||
|
.reg_ssusb_ddren_rmb = 0,
|
||||||
|
.reg_ssusb_emi_rmb = 1,
|
||||||
|
.reg_ssusb_infra_rmb = 1,
|
||||||
|
.reg_ssusb_pmic_rmb = 1,
|
||||||
|
.reg_ssusb_srcclkena_mb = 1,
|
||||||
|
.reg_ssusb_vcore_rmb = 1,
|
||||||
|
.reg_ssusb_vrf18_rmb = 1,
|
||||||
|
.reg_uart_hub_infra_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_15 */
|
||||||
|
.reg_uart_hub_pmic_rmb = 1,
|
||||||
|
.reg_uart_hub_srcclkena_mb = 1,
|
||||||
|
.reg_uart_hub_vcore_rmb = 1,
|
||||||
|
.reg_uart_hub_vrf18_rmb = 1,
|
||||||
|
.reg_ufs_apsrc_rmb = 1,
|
||||||
|
.reg_ufs_ddren_rmb = 0,
|
||||||
|
.reg_ufs_emi_rmb = 1,
|
||||||
|
.reg_ufs_infra_rmb = 1,
|
||||||
|
.reg_ufs_pmic_rmb = 1,
|
||||||
|
.reg_ufs_srcclkena_mb = 1,
|
||||||
|
.reg_ufs_vcore_rmb = 1,
|
||||||
|
.reg_ufs_vrf18_rmb = 1,
|
||||||
|
.reg_vdec_apsrc_rmb = 0,
|
||||||
|
.reg_vdec_ddren_rmb = 0,
|
||||||
|
.reg_vdec_emi_rmb = 0,
|
||||||
|
.reg_vdec_infra_rmb = 0,
|
||||||
|
.reg_vdec_pmic_rmb = 0,
|
||||||
|
.reg_vdec_srcclkena_mb = 0,
|
||||||
|
.reg_vdec_vrf18_rmb = 0,
|
||||||
|
.reg_venc_apsrc_rmb = 0,
|
||||||
|
.reg_venc_ddren_rmb = 0,
|
||||||
|
.reg_venc_emi_rmb = 0,
|
||||||
|
.reg_venc_infra_rmb = 0,
|
||||||
|
.reg_venc_pmic_rmb = 0,
|
||||||
|
.reg_venc_srcclkena_mb = 0,
|
||||||
|
.reg_venc_vrf18_rmb = 0,
|
||||||
|
.reg_vlpcfg_apsrc_rmb = 1,
|
||||||
|
.reg_vlpcfg_ddren_rmb = 0,
|
||||||
|
.reg_vlpcfg_emi_rmb = 1,
|
||||||
|
.reg_vlpcfg_infra_rmb = 1,
|
||||||
|
.reg_vlpcfg_pmic_rmb = 1,
|
||||||
|
.reg_vlpcfg_srcclkena_mb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_16 */
|
||||||
|
.reg_vlpcfg_vcore_rmb = 1,
|
||||||
|
.reg_vlpcfg_vrf18_rmb = 1,
|
||||||
|
.reg_vlpcfg1_apsrc_rmb = 1,
|
||||||
|
.reg_vlpcfg1_ddren_rmb = 0,
|
||||||
|
.reg_vlpcfg1_emi_rmb = 1,
|
||||||
|
.reg_vlpcfg1_infra_rmb = 1,
|
||||||
|
.reg_vlpcfg1_pmic_rmb = 0,
|
||||||
|
.reg_vlpcfg1_srcclkena_mb = 1,
|
||||||
|
.reg_vlpcfg1_vcore_rmb = 1,
|
||||||
|
.reg_vlpcfg1_vrf18_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_EVENT_CON_MISC */
|
||||||
|
.reg_srcclken_fast_resp = 0,
|
||||||
|
.reg_csyspwrup_ack_mask = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_17 */
|
||||||
|
.reg_spm_sw_vcore_rmb = 0x3,
|
||||||
|
.reg_spm_sw_pmic_rmb = 0,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_18 */
|
||||||
|
.reg_spm_sw_srcclkena_mb = 0,
|
||||||
|
|
||||||
|
/* SPM_WAKE_MASK*/
|
||||||
|
.reg_wake_mask = 0x81322012,
|
||||||
|
|
||||||
|
/* SPM_WAKEUP_EVENT_EXT_MASK */
|
||||||
|
.reg_ext_wake_mask = 0xFFFFFFFF,
|
||||||
|
|
||||||
|
/*SW flag setting */
|
||||||
|
.pcm_flags = SPM_SUSPEND_PCM_FLAG,
|
||||||
|
.pcm_flags1 = SPM_SUSPEND_PCM_FLAG1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct suspend_dbg_ctrl suspend_spm_dbg_ext = {
|
||||||
|
.sleep_suspend_cnt = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct dbg_ctrl suspend_spm_dbg = {
|
||||||
|
.count = 0,
|
||||||
|
.duration = 0,
|
||||||
|
.ext = &suspend_spm_dbg_ext,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct spm_lp_stat suspend_lp_stat;
|
||||||
|
|
||||||
|
struct spm_lp_scen __spm_suspend = {
|
||||||
|
.pwrctrl = &suspend_ctrl,
|
||||||
|
.dbgctrl = &suspend_spm_dbg,
|
||||||
|
.lpstat = &suspend_lp_stat,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t bak_spm_vcore_req;
|
||||||
|
|
||||||
|
int mt_spm_suspend_mode_set(enum mt_spm_suspend_mode mode, void *prv)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (mode == MT_SPM_SUSPEND_SLEEP) {
|
||||||
|
suspend_ctrl.pcm_flags = SPM_SUSPEND_SLEEP_PCM_FLAG;
|
||||||
|
suspend_ctrl.pcm_flags1 = SPM_SUSPEND_SLEEP_PCM_FLAG1;
|
||||||
|
suspend_ctrl.reg_spm_vcore_req = 1;
|
||||||
|
} else {
|
||||||
|
suspend_ctrl.pcm_flags = SPM_SUSPEND_PCM_FLAG;
|
||||||
|
suspend_ctrl.pcm_flags1 = SPM_SUSPEND_PCM_FLAG1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void spm_CSOPLU_ctrl_leave_suspend(void)
|
||||||
|
{
|
||||||
|
mmio_setbits_32(SPM_RSV_CSOPLU_REQ, (0x1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mt_spm_suspend_ec_pin(void)
|
||||||
|
{
|
||||||
|
gpio_bk1 = mmio_read_32(MODE_BACKUP_REG);
|
||||||
|
gpio_bk2 = mmio_read_32(DIR_BACKUP_REG);
|
||||||
|
gpio_bk3 = mmio_read_32(DOUT_BACKUP_REG);
|
||||||
|
|
||||||
|
mmio_write_32(MODE_SET, SET_GPIO_MODE);
|
||||||
|
gpio_set_direction(EC_SUSPEND_BK_PIN, GPIO_DIR_OUT);
|
||||||
|
/* GPIO111 LOW */
|
||||||
|
gpio_set_value(EC_SUSPEND_BK_PIN, GPIO_LEVEL_LOW);
|
||||||
|
/* GPIO38 LOW */
|
||||||
|
gpio_set_value(EC_SUSPEND_PIN, GPIO_LEVEL_LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mt_spm_resume_ec_pin(void)
|
||||||
|
{
|
||||||
|
/* GPIO38 HIGH */
|
||||||
|
gpio_set_value(EC_SUSPEND_PIN, GPIO_LEVEL_HIGH);
|
||||||
|
/* GPIO111 HIGH */
|
||||||
|
gpio_set_value(EC_SUSPEND_BK_PIN, GPIO_LEVEL_HIGH);
|
||||||
|
udelay(10);
|
||||||
|
|
||||||
|
mmio_write_32(MODE_BACKUP_REG, gpio_bk1);
|
||||||
|
mmio_write_32(DIR_BACKUP_REG, gpio_bk2);
|
||||||
|
mmio_write_32(DOUT_BACKUP_REG, gpio_bk3);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_spm_suspend_enter(int state_id,
|
||||||
|
uint32_t ext_opand, uint32_t resource_req)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
bak_spm_vcore_req = suspend_ctrl.reg_spm_vcore_req;
|
||||||
|
|
||||||
|
/* if FMAudio, ADSP, USB headset is active, change to sleep mode */
|
||||||
|
if (ext_opand & MT_SPM_EX_OP_SET_SUSPEND_MODE)
|
||||||
|
mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SLEEP,
|
||||||
|
&resource_req);
|
||||||
|
else
|
||||||
|
mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SYSTEM_PDN,
|
||||||
|
&resource_req);
|
||||||
|
|
||||||
|
mmio_write_32(SPM2SW_MAILBOX_0, 0x1);
|
||||||
|
|
||||||
|
ext_opand |= MT_SPM_EX_OP_DEVICES_SAVE;
|
||||||
|
|
||||||
|
#if defined(CONFIG_MTK_VCOREDVFS_SUPPORT)
|
||||||
|
/* Notify vcoredvfs suspend enter */
|
||||||
|
spm_vcorefs_plat_suspend();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = spm_conservation(state_id, ext_opand,
|
||||||
|
&__spm_suspend, resource_req);
|
||||||
|
if (ret == 0) {
|
||||||
|
struct mt_lp_publish_event event = {
|
||||||
|
.id = MT_LPM_PUBEVENTS_SYS_POWER_OFF,
|
||||||
|
.val.u32 = 0,
|
||||||
|
.level = MT_LP_SYSPOWER_LEVEL_SUSPEND,
|
||||||
|
};
|
||||||
|
|
||||||
|
MT_LP_SUSPEND_PUBLISH_EVENT(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
mt_spm_suspend_ec_pin();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt_spm_suspend_resume(int state_id, uint32_t ext_opand,
|
||||||
|
struct wake_status **status)
|
||||||
|
{
|
||||||
|
struct mt_lp_publish_event event;
|
||||||
|
struct wake_status *st = NULL;
|
||||||
|
|
||||||
|
ext_opand |= MT_SPM_EX_OP_DEVICES_SAVE;
|
||||||
|
|
||||||
|
mt_spm_resume_ec_pin();
|
||||||
|
spm_conservation_finish(state_id, ext_opand, &__spm_suspend, &st);
|
||||||
|
|
||||||
|
spm_CSOPLU_ctrl_leave_suspend();
|
||||||
|
|
||||||
|
mt_spm_update_lp_stat(&suspend_lp_stat);
|
||||||
|
#if defined(CONFIG_MTK_VCOREDVFS_SUPPORT)
|
||||||
|
/* Notify vcoredvfs suspend enter */
|
||||||
|
spm_vcorefs_plat_resume();
|
||||||
|
mmio_write_32(SPM2SW_MAILBOX_0, 0x0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************
|
||||||
|
* If FMAudio, ADSP, USB headset is active,
|
||||||
|
* change back to suspend mode and counting in resume
|
||||||
|
*****************************************/
|
||||||
|
|
||||||
|
if (ext_opand & MT_SPM_EX_OP_SET_SUSPEND_MODE) {
|
||||||
|
mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SYSTEM_PDN, NULL);
|
||||||
|
suspend_spm_dbg_ext.sleep_suspend_cnt += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend_ctrl.reg_spm_vcore_req = bak_spm_vcore_req;
|
||||||
|
|
||||||
|
suspend_spm_dbg.count += 1;
|
||||||
|
event.id = MT_LPM_PUBEVENTS_SYS_POWER_ON;
|
||||||
|
event.val.u32 = 0;
|
||||||
|
event.level = MT_LP_SYSPOWER_LEVEL_SUSPEND;
|
||||||
|
|
||||||
|
if (st) {
|
||||||
|
if (st->tr.comm.r12 & R12_AP2AP_PEER_WAKEUP_B)
|
||||||
|
event.val.u32 = MT_LPM_WAKE_MD_WAKEUP_DPMAIF;
|
||||||
|
if (st->tr.comm.r12 & R12_CCIF0_EVENT_B)
|
||||||
|
event.val.u32 = MT_LPM_WAKE_MD_WAKEUP_CCIF0;
|
||||||
|
if (st->tr.comm.r12 & R12_CCIF1_EVENT_B)
|
||||||
|
event.val.u32 = MT_LPM_WAKE_MD_WAKEUP_CCIF1;
|
||||||
|
}
|
||||||
|
if (status)
|
||||||
|
*status = st;
|
||||||
|
MT_LP_SUSPEND_PUBLISH_EVENT(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_spm_suspend_get_spm_lp(struct spm_lp_scen **lp)
|
||||||
|
{
|
||||||
|
if (!lp)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*lp = &__spm_suspend;
|
||||||
|
return 0;
|
||||||
|
}
|
31
plat/mediatek/drivers/spm/mt8196/mt_spm_suspend.h
Normal file
31
plat/mediatek/drivers/spm/mt8196/mt_spm_suspend.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_SPM_SUSPEND_H
|
||||||
|
#define MT_SPM_SUSPEND_H
|
||||||
|
|
||||||
|
#include <mt_spm_internal.h>
|
||||||
|
|
||||||
|
struct suspend_dbg_ctrl {
|
||||||
|
uint32_t sleep_suspend_cnt;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum mt_spm_suspend_mode {
|
||||||
|
MT_SPM_SUSPEND_SYSTEM_PDN,
|
||||||
|
MT_SPM_SUSPEND_SLEEP,
|
||||||
|
};
|
||||||
|
|
||||||
|
int mt_spm_suspend_mode_set(enum mt_spm_suspend_mode mode, void *prv);
|
||||||
|
|
||||||
|
int mt_spm_suspend_enter(int state_id, uint32_t ext_opand,
|
||||||
|
uint32_t reosuce_req);
|
||||||
|
|
||||||
|
void mt_spm_suspend_resume(int state_id, uint32_t ext_opand,
|
||||||
|
struct wake_status **status);
|
||||||
|
|
||||||
|
int mt_spm_suspend_get_spm_lp(struct spm_lp_scen **lp);
|
||||||
|
|
||||||
|
#endif /* MT_SPM_SUSPEND_H */
|
609
plat/mediatek/drivers/spm/mt8196/mt_spm_vcorefs.c
Normal file
609
plat/mediatek/drivers/spm/mt8196/mt_spm_vcorefs.c
Normal file
|
@ -0,0 +1,609 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.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 <drivers/spmi_api.h>
|
||||||
|
#include <lib/pm/mtk_pm.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 VCORE_BASE_UV 0
|
||||||
|
#ifdef MT8196_VCORE_SUPPORT
|
||||||
|
#define VCORE_STEP_UV 6250
|
||||||
|
#else
|
||||||
|
#define VCORE_STEP_UV 5000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define VCORE_UV_TO_PMIC(uv) /* pmic >= uv */ \
|
||||||
|
((((uv) - VCORE_BASE_UV) + (VCORE_STEP_UV - 1)) / VCORE_STEP_UV)
|
||||||
|
#define VCORE_PMIC_TO_UV(pmic) \
|
||||||
|
(((pmic) * VCORE_STEP_UV) + VCORE_BASE_UV)
|
||||||
|
|
||||||
|
#define VSRAM_BASE_UV 0
|
||||||
|
#define VSRAM_STEP_UV 6250
|
||||||
|
|
||||||
|
#define VSRAM_UV_TO_PMIC(uv) /* pmic >= uv */ \
|
||||||
|
((((uv) - VSRAM_BASE_UV) + (VSRAM_STEP_UV - 1)) / VSRAM_STEP_UV)
|
||||||
|
#define VSRAM_PMIC_TO_UV(pmic) \
|
||||||
|
(((pmic) * VSRAM_STEP_UV) + VSRAM_BASE_UV)
|
||||||
|
|
||||||
|
static int spm_dvfs_init_done;
|
||||||
|
|
||||||
|
static struct pwr_ctrl vcorefs_ctrl = {
|
||||||
|
.wake_src = R12_CPU_WAKEUP,
|
||||||
|
|
||||||
|
/* default VCORE DVFS is disabled */
|
||||||
|
.pcm_flags = (SPM_FLAG_RUN_COMMON_SCENARIO |
|
||||||
|
SPM_FLAG_DISABLE_VCORE_DVS |
|
||||||
|
SPM_FLAG_DISABLE_DDR_DFS |
|
||||||
|
SPM_FLAG_DISABLE_EMI_DFS | SPM_FLAG_DISABLE_BUS_DFS),
|
||||||
|
|
||||||
|
/* SPM_SRC_REQ */
|
||||||
|
.reg_spm_adsp_mailbox_req = 0,
|
||||||
|
.reg_spm_apsrc_req = 0,
|
||||||
|
.reg_spm_ddren_req = 0,
|
||||||
|
.reg_spm_dvfs_req = 0,
|
||||||
|
.reg_spm_emi_req = 0,
|
||||||
|
.reg_spm_f26m_req = 0,
|
||||||
|
.reg_spm_infra_req = 0,
|
||||||
|
.reg_spm_pmic_req = 0,
|
||||||
|
.reg_spm_scp_mailbox_req = 0,
|
||||||
|
.reg_spm_sspm_mailbox_req = 0,
|
||||||
|
.reg_spm_sw_mailbox_req = 0,
|
||||||
|
.reg_spm_vcore_req = 1,
|
||||||
|
.reg_spm_vrf18_req = 0,
|
||||||
|
.adsp_mailbox_state = 0,
|
||||||
|
.apsrc_state = 0,
|
||||||
|
.ddren_state = 0,
|
||||||
|
.dvfs_state = 0,
|
||||||
|
.emi_state = 0,
|
||||||
|
.f26m_state = 0,
|
||||||
|
.infra_state = 0,
|
||||||
|
.pmic_state = 0,
|
||||||
|
.scp_mailbox_state = 0,
|
||||||
|
.sspm_mailbox_state = 0,
|
||||||
|
.sw_mailbox_state = 0,
|
||||||
|
.vcore_state = 0,
|
||||||
|
.vrf18_state = 0,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_0 */
|
||||||
|
.reg_apifr_apsrc_rmb = 0,
|
||||||
|
.reg_apifr_ddren_rmb = 0,
|
||||||
|
.reg_apifr_emi_rmb = 0,
|
||||||
|
.reg_apifr_infra_rmb = 0,
|
||||||
|
.reg_apifr_pmic_rmb = 0,
|
||||||
|
.reg_apifr_srcclkena_mb = 0,
|
||||||
|
.reg_apifr_vcore_rmb = 0,
|
||||||
|
.reg_apifr_vrf18_rmb = 0,
|
||||||
|
.reg_apu_apsrc_rmb = 1,
|
||||||
|
.reg_apu_ddren_rmb = 0,
|
||||||
|
.reg_apu_emi_rmb = 1,
|
||||||
|
.reg_apu_infra_rmb = 1,
|
||||||
|
.reg_apu_pmic_rmb = 1,
|
||||||
|
.reg_apu_srcclkena_mb = 1,
|
||||||
|
.reg_apu_vcore_rmb = 1,
|
||||||
|
.reg_apu_vrf18_rmb = 1,
|
||||||
|
.reg_audio_apsrc_rmb = 1,
|
||||||
|
.reg_audio_ddren_rmb = 0,
|
||||||
|
.reg_audio_emi_rmb = 1,
|
||||||
|
.reg_audio_infra_rmb = 1,
|
||||||
|
.reg_audio_pmic_rmb = 1,
|
||||||
|
.reg_audio_srcclkena_mb = 1,
|
||||||
|
.reg_audio_vcore_rmb = 1,
|
||||||
|
.reg_audio_vrf18_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_1 */
|
||||||
|
.reg_audio_dsp_apsrc_rmb = 1,
|
||||||
|
.reg_audio_dsp_ddren_rmb = 0,
|
||||||
|
.reg_audio_dsp_emi_rmb = 1,
|
||||||
|
.reg_audio_dsp_infra_rmb = 1,
|
||||||
|
.reg_audio_dsp_pmic_rmb = 1,
|
||||||
|
.reg_audio_dsp_srcclkena_mb = 1,
|
||||||
|
.reg_audio_dsp_vcore_rmb = 1,
|
||||||
|
.reg_audio_dsp_vrf18_rmb = 1,
|
||||||
|
.reg_cam_apsrc_rmb = 0,
|
||||||
|
.reg_cam_ddren_rmb = 0,
|
||||||
|
.reg_cam_emi_rmb = 0,
|
||||||
|
.reg_cam_infra_rmb = 0,
|
||||||
|
.reg_cam_pmic_rmb = 0,
|
||||||
|
.reg_cam_srcclkena_mb = 0,
|
||||||
|
.reg_cam_vrf18_rmb = 0,
|
||||||
|
.reg_ccif_apsrc_rmb = 0xfff,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_2 */
|
||||||
|
.reg_ccif_emi_rmb = 0xfff,
|
||||||
|
.reg_ccif_infra_rmb = 0xfff,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_3 */
|
||||||
|
.reg_ccif_pmic_rmb = 0xfff,
|
||||||
|
.reg_ccif_srcclkena_mb = 0xfff,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_4 */
|
||||||
|
.reg_ccif_vcore_rmb = 0xfff,
|
||||||
|
.reg_ccif_vrf18_rmb = 0xfff,
|
||||||
|
.reg_ccu_apsrc_rmb = 0,
|
||||||
|
.reg_ccu_ddren_rmb = 0,
|
||||||
|
.reg_ccu_emi_rmb = 0,
|
||||||
|
.reg_ccu_infra_rmb = 0,
|
||||||
|
.reg_ccu_pmic_rmb = 0,
|
||||||
|
.reg_ccu_srcclkena_mb = 0,
|
||||||
|
.reg_ccu_vrf18_rmb = 0,
|
||||||
|
.reg_cg_check_apsrc_rmb = 0,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_5 */
|
||||||
|
.reg_cg_check_ddren_rmb = 0,
|
||||||
|
.reg_cg_check_emi_rmb = 0,
|
||||||
|
.reg_cg_check_infra_rmb = 0,
|
||||||
|
.reg_cg_check_pmic_rmb = 0,
|
||||||
|
.reg_cg_check_srcclkena_mb = 0,
|
||||||
|
.reg_cg_check_vcore_rmb = 1,
|
||||||
|
.reg_cg_check_vrf18_rmb = 0,
|
||||||
|
.reg_cksys_apsrc_rmb = 1,
|
||||||
|
.reg_cksys_ddren_rmb = 0,
|
||||||
|
.reg_cksys_emi_rmb = 1,
|
||||||
|
.reg_cksys_infra_rmb = 1,
|
||||||
|
.reg_cksys_pmic_rmb = 1,
|
||||||
|
.reg_cksys_srcclkena_mb = 1,
|
||||||
|
.reg_cksys_vcore_rmb = 1,
|
||||||
|
.reg_cksys_vrf18_rmb = 1,
|
||||||
|
.reg_cksys_1_apsrc_rmb = 1,
|
||||||
|
.reg_cksys_1_ddren_rmb = 0,
|
||||||
|
.reg_cksys_1_emi_rmb = 1,
|
||||||
|
.reg_cksys_1_infra_rmb = 1,
|
||||||
|
.reg_cksys_1_pmic_rmb = 1,
|
||||||
|
.reg_cksys_1_srcclkena_mb = 1,
|
||||||
|
.reg_cksys_1_vcore_rmb = 1,
|
||||||
|
.reg_cksys_1_vrf18_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_6 */
|
||||||
|
.reg_cksys_2_apsrc_rmb = 1,
|
||||||
|
.reg_cksys_2_ddren_rmb = 0,
|
||||||
|
.reg_cksys_2_emi_rmb = 1,
|
||||||
|
.reg_cksys_2_infra_rmb = 1,
|
||||||
|
.reg_cksys_2_pmic_rmb = 1,
|
||||||
|
.reg_cksys_2_srcclkena_mb = 1,
|
||||||
|
.reg_cksys_2_vcore_rmb = 1,
|
||||||
|
.reg_cksys_2_vrf18_rmb = 1,
|
||||||
|
.reg_conn_apsrc_rmb = 1,
|
||||||
|
.reg_conn_ddren_rmb = 0,
|
||||||
|
.reg_conn_emi_rmb = 1,
|
||||||
|
.reg_conn_infra_rmb = 1,
|
||||||
|
.reg_conn_pmic_rmb = 1,
|
||||||
|
.reg_conn_srcclkena_mb = 1,
|
||||||
|
.reg_conn_srcclkenb_mb = 1,
|
||||||
|
.reg_conn_vcore_rmb = 1,
|
||||||
|
.reg_conn_vrf18_rmb = 1,
|
||||||
|
.reg_corecfg_apsrc_rmb = 0,
|
||||||
|
.reg_corecfg_ddren_rmb = 0,
|
||||||
|
.reg_corecfg_emi_rmb = 0,
|
||||||
|
.reg_corecfg_infra_rmb = 0,
|
||||||
|
.reg_corecfg_pmic_rmb = 0,
|
||||||
|
.reg_corecfg_srcclkena_mb = 0,
|
||||||
|
.reg_corecfg_vcore_rmb = 0,
|
||||||
|
.reg_corecfg_vrf18_rmb = 0,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_7 */
|
||||||
|
.reg_cpueb_apsrc_rmb = 1,
|
||||||
|
.reg_cpueb_ddren_rmb = 0,
|
||||||
|
.reg_cpueb_emi_rmb = 1,
|
||||||
|
.reg_cpueb_infra_rmb = 1,
|
||||||
|
.reg_cpueb_pmic_rmb = 1,
|
||||||
|
.reg_cpueb_srcclkena_mb = 1,
|
||||||
|
.reg_cpueb_vcore_rmb = 1,
|
||||||
|
.reg_cpueb_vrf18_rmb = 1,
|
||||||
|
.reg_disp0_apsrc_rmb = 0,
|
||||||
|
.reg_disp0_ddren_rmb = 0,
|
||||||
|
.reg_disp0_emi_rmb = 0,
|
||||||
|
.reg_disp0_infra_rmb = 0,
|
||||||
|
.reg_disp0_pmic_rmb = 0,
|
||||||
|
.reg_disp0_srcclkena_mb = 0,
|
||||||
|
.reg_disp0_vrf18_rmb = 0,
|
||||||
|
.reg_disp1_apsrc_rmb = 0,
|
||||||
|
.reg_disp1_ddren_rmb = 0,
|
||||||
|
.reg_disp1_emi_rmb = 0,
|
||||||
|
.reg_disp1_infra_rmb = 0,
|
||||||
|
.reg_disp1_pmic_rmb = 0,
|
||||||
|
.reg_disp1_srcclkena_mb = 0,
|
||||||
|
.reg_disp1_vrf18_rmb = 0,
|
||||||
|
.reg_dpm_apsrc_rmb = 0xf,
|
||||||
|
.reg_dpm_ddren_rmb = 0xf,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_8 */
|
||||||
|
.reg_dpm_emi_rmb = 0xf,
|
||||||
|
.reg_dpm_infra_rmb = 0xf,
|
||||||
|
.reg_dpm_pmic_rmb = 0xf,
|
||||||
|
.reg_dpm_srcclkena_mb = 0xf,
|
||||||
|
.reg_dpm_vcore_rmb = 0xf,
|
||||||
|
.reg_dpm_vrf18_rmb = 0xf,
|
||||||
|
.reg_dpmaif_apsrc_rmb = 1,
|
||||||
|
.reg_dpmaif_ddren_rmb = 0,
|
||||||
|
.reg_dpmaif_emi_rmb = 1,
|
||||||
|
.reg_dpmaif_infra_rmb = 1,
|
||||||
|
.reg_dpmaif_pmic_rmb = 1,
|
||||||
|
.reg_dpmaif_srcclkena_mb = 1,
|
||||||
|
.reg_dpmaif_vcore_rmb = 1,
|
||||||
|
.reg_dpmaif_vrf18_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_9 */
|
||||||
|
.reg_dvfsrc_level_rmb = 1,
|
||||||
|
.reg_emisys_apsrc_rmb = 0,
|
||||||
|
.reg_emisys_ddren_rmb = 0,
|
||||||
|
.reg_emisys_emi_rmb = 0,
|
||||||
|
.reg_emisys_infra_rmb = 0,
|
||||||
|
.reg_emisys_pmic_rmb = 0,
|
||||||
|
.reg_emisys_srcclkena_mb = 0,
|
||||||
|
.reg_emisys_vcore_rmb = 0,
|
||||||
|
.reg_emisys_vrf18_rmb = 0,
|
||||||
|
.reg_gce_apsrc_rmb = 0,
|
||||||
|
.reg_gce_ddren_rmb = 0,
|
||||||
|
.reg_gce_emi_rmb = 0,
|
||||||
|
.reg_gce_infra_rmb = 0,
|
||||||
|
.reg_gce_pmic_rmb = 0,
|
||||||
|
.reg_gce_srcclkena_mb = 0,
|
||||||
|
.reg_gce_vcore_rmb = 0,
|
||||||
|
.reg_gce_vrf18_rmb = 0,
|
||||||
|
.reg_gpueb_apsrc_rmb = 1,
|
||||||
|
.reg_gpueb_ddren_rmb = 0,
|
||||||
|
.reg_gpueb_emi_rmb = 1,
|
||||||
|
.reg_gpueb_infra_rmb = 1,
|
||||||
|
.reg_gpueb_pmic_rmb = 1,
|
||||||
|
.reg_gpueb_srcclkena_mb = 1,
|
||||||
|
.reg_gpueb_vcore_rmb = 1,
|
||||||
|
.reg_gpueb_vrf18_rmb = 1,
|
||||||
|
.reg_hwccf_apsrc_rmb = 1,
|
||||||
|
.reg_hwccf_ddren_rmb = 0,
|
||||||
|
.reg_hwccf_emi_rmb = 1,
|
||||||
|
.reg_hwccf_infra_rmb = 1,
|
||||||
|
.reg_hwccf_pmic_rmb = 1,
|
||||||
|
.reg_hwccf_srcclkena_mb = 1,
|
||||||
|
.reg_hwccf_vcore_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_10 */
|
||||||
|
.reg_hwccf_vrf18_rmb = 1,
|
||||||
|
.reg_img_apsrc_rmb = 0,
|
||||||
|
.reg_img_ddren_rmb = 0,
|
||||||
|
.reg_img_emi_rmb = 0,
|
||||||
|
.reg_img_infra_rmb = 0,
|
||||||
|
.reg_img_pmic_rmb = 0,
|
||||||
|
.reg_img_srcclkena_mb = 0,
|
||||||
|
.reg_img_vrf18_rmb = 0,
|
||||||
|
.reg_infrasys_apsrc_rmb = 0,
|
||||||
|
.reg_infrasys_ddren_rmb = 0,
|
||||||
|
.reg_infrasys_emi_rmb = 0,
|
||||||
|
.reg_infrasys_infra_rmb = 0,
|
||||||
|
.reg_infrasys_pmic_rmb = 0,
|
||||||
|
.reg_infrasys_srcclkena_mb = 0,
|
||||||
|
.reg_infrasys_vcore_rmb = 0,
|
||||||
|
.reg_infrasys_vrf18_rmb = 0,
|
||||||
|
.reg_ipic_infra_rmb = 1,
|
||||||
|
.reg_ipic_vrf18_rmb = 1,
|
||||||
|
.reg_mcu_apsrc_rmb = 1,
|
||||||
|
.reg_mcu_ddren_rmb = 0,
|
||||||
|
.reg_mcu_emi_rmb = 1,
|
||||||
|
.reg_mcu_infra_rmb = 1,
|
||||||
|
.reg_mcu_pmic_rmb = 1,
|
||||||
|
.reg_mcu_srcclkena_mb = 1,
|
||||||
|
.reg_mcu_vcore_rmb = 1,
|
||||||
|
.reg_mcu_vrf18_rmb = 1,
|
||||||
|
.reg_md_apsrc_rmb = 1,
|
||||||
|
.reg_md_ddren_rmb = 0,
|
||||||
|
.reg_md_emi_rmb = 1,
|
||||||
|
.reg_md_infra_rmb = 1,
|
||||||
|
.reg_md_pmic_rmb = 1,
|
||||||
|
.reg_md_srcclkena_mb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_11 */
|
||||||
|
.reg_md_srcclkena1_mb = 1,
|
||||||
|
.reg_md_vcore_rmb = 1,
|
||||||
|
.reg_md_vrf18_rmb = 1,
|
||||||
|
.reg_mm_proc_apsrc_rmb = 1,
|
||||||
|
.reg_mm_proc_ddren_rmb = 0,
|
||||||
|
.reg_mm_proc_emi_rmb = 1,
|
||||||
|
.reg_mm_proc_infra_rmb = 1,
|
||||||
|
.reg_mm_proc_pmic_rmb = 1,
|
||||||
|
.reg_mm_proc_srcclkena_mb = 1,
|
||||||
|
.reg_mm_proc_vcore_rmb = 1,
|
||||||
|
.reg_mm_proc_vrf18_rmb = 1,
|
||||||
|
.reg_mml0_apsrc_rmb = 0,
|
||||||
|
.reg_mml0_ddren_rmb = 0,
|
||||||
|
.reg_mml0_emi_rmb = 0,
|
||||||
|
.reg_mml0_infra_rmb = 0,
|
||||||
|
.reg_mml0_pmic_rmb = 0,
|
||||||
|
.reg_mml0_srcclkena_mb = 0,
|
||||||
|
.reg_mml0_vrf18_rmb = 0,
|
||||||
|
.reg_mml1_apsrc_rmb = 0,
|
||||||
|
.reg_mml1_ddren_rmb = 0,
|
||||||
|
.reg_mml1_emi_rmb = 0,
|
||||||
|
.reg_mml1_infra_rmb = 0,
|
||||||
|
.reg_mml1_pmic_rmb = 0,
|
||||||
|
.reg_mml1_srcclkena_mb = 0,
|
||||||
|
.reg_mml1_vrf18_rmb = 0,
|
||||||
|
.reg_ovl0_apsrc_rmb = 0,
|
||||||
|
.reg_ovl0_ddren_rmb = 0,
|
||||||
|
.reg_ovl0_emi_rmb = 0,
|
||||||
|
.reg_ovl0_infra_rmb = 0,
|
||||||
|
.reg_ovl0_pmic_rmb = 0,
|
||||||
|
.reg_ovl0_srcclkena_mb = 0,
|
||||||
|
.reg_ovl0_vrf18_rmb = 0,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_12 */
|
||||||
|
.reg_ovl1_apsrc_rmb = 0,
|
||||||
|
.reg_ovl1_ddren_rmb = 0,
|
||||||
|
.reg_ovl1_emi_rmb = 0,
|
||||||
|
.reg_ovl1_infra_rmb = 0,
|
||||||
|
.reg_ovl1_pmic_rmb = 0,
|
||||||
|
.reg_ovl1_srcclkena_mb = 0,
|
||||||
|
.reg_ovl1_vrf18_rmb = 0,
|
||||||
|
.reg_pcie0_apsrc_rmb = 1,
|
||||||
|
.reg_pcie0_ddren_rmb = 0,
|
||||||
|
.reg_pcie0_emi_rmb = 1,
|
||||||
|
.reg_pcie0_infra_rmb = 1,
|
||||||
|
.reg_pcie0_pmic_rmb = 1,
|
||||||
|
.reg_pcie0_srcclkena_mb = 1,
|
||||||
|
.reg_pcie0_vcore_rmb = 1,
|
||||||
|
.reg_pcie0_vrf18_rmb = 1,
|
||||||
|
.reg_pcie1_apsrc_rmb = 1,
|
||||||
|
.reg_pcie1_ddren_rmb = 0,
|
||||||
|
.reg_pcie1_emi_rmb = 1,
|
||||||
|
.reg_pcie1_infra_rmb = 1,
|
||||||
|
.reg_pcie1_pmic_rmb = 1,
|
||||||
|
.reg_pcie1_srcclkena_mb = 1,
|
||||||
|
.reg_pcie1_vcore_rmb = 1,
|
||||||
|
.reg_pcie1_vrf18_rmb = 1,
|
||||||
|
.reg_perisys_apsrc_rmb = 1,
|
||||||
|
.reg_perisys_ddren_rmb = 0,
|
||||||
|
.reg_perisys_emi_rmb = 1,
|
||||||
|
.reg_perisys_infra_rmb = 1,
|
||||||
|
.reg_perisys_pmic_rmb = 1,
|
||||||
|
.reg_perisys_srcclkena_mb = 1,
|
||||||
|
.reg_perisys_vcore_rmb = 1,
|
||||||
|
.reg_perisys_vrf18_rmb = 1,
|
||||||
|
.reg_pmsr_apsrc_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_13 */
|
||||||
|
.reg_pmsr_ddren_rmb = 0,
|
||||||
|
.reg_pmsr_emi_rmb = 1,
|
||||||
|
.reg_pmsr_infra_rmb = 1,
|
||||||
|
.reg_pmsr_pmic_rmb = 1,
|
||||||
|
.reg_pmsr_srcclkena_mb = 1,
|
||||||
|
.reg_pmsr_vcore_rmb = 1,
|
||||||
|
.reg_pmsr_vrf18_rmb = 1,
|
||||||
|
.reg_scp_apsrc_rmb = 1,
|
||||||
|
.reg_scp_ddren_rmb = 0,
|
||||||
|
.reg_scp_emi_rmb = 1,
|
||||||
|
.reg_scp_infra_rmb = 1,
|
||||||
|
.reg_scp_pmic_rmb = 1,
|
||||||
|
.reg_scp_srcclkena_mb = 1,
|
||||||
|
.reg_scp_vcore_rmb = 1,
|
||||||
|
.reg_scp_vrf18_rmb = 1,
|
||||||
|
.reg_spu_hwr_apsrc_rmb = 1,
|
||||||
|
.reg_spu_hwr_ddren_rmb = 0,
|
||||||
|
.reg_spu_hwr_emi_rmb = 1,
|
||||||
|
.reg_spu_hwr_infra_rmb = 1,
|
||||||
|
.reg_spu_hwr_pmic_rmb = 1,
|
||||||
|
.reg_spu_hwr_srcclkena_mb = 1,
|
||||||
|
.reg_spu_hwr_vcore_rmb = 1,
|
||||||
|
.reg_spu_hwr_vrf18_rmb = 1,
|
||||||
|
.reg_spu_ise_apsrc_rmb = 1,
|
||||||
|
.reg_spu_ise_ddren_rmb = 0,
|
||||||
|
.reg_spu_ise_emi_rmb = 1,
|
||||||
|
.reg_spu_ise_infra_rmb = 1,
|
||||||
|
.reg_spu_ise_pmic_rmb = 1,
|
||||||
|
.reg_spu_ise_srcclkena_mb = 1,
|
||||||
|
.reg_spu_ise_vcore_rmb = 1,
|
||||||
|
.reg_spu_ise_vrf18_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_14 */
|
||||||
|
.reg_srcclkeni_infra_rmb = 0x3,
|
||||||
|
.reg_srcclkeni_pmic_rmb = 0x3,
|
||||||
|
.reg_srcclkeni_srcclkena_mb = 0x3,
|
||||||
|
.reg_srcclkeni_vcore_rmb = 0x3,
|
||||||
|
.reg_sspm_apsrc_rmb = 1,
|
||||||
|
.reg_sspm_ddren_rmb = 0,
|
||||||
|
.reg_sspm_emi_rmb = 1,
|
||||||
|
.reg_sspm_infra_rmb = 1,
|
||||||
|
.reg_sspm_pmic_rmb = 1,
|
||||||
|
.reg_sspm_srcclkena_mb = 1,
|
||||||
|
.reg_sspm_vrf18_rmb = 1,
|
||||||
|
.reg_ssrsys_apsrc_rmb = 1,
|
||||||
|
.reg_ssrsys_ddren_rmb = 0,
|
||||||
|
.reg_ssrsys_emi_rmb = 1,
|
||||||
|
.reg_ssrsys_infra_rmb = 1,
|
||||||
|
.reg_ssrsys_pmic_rmb = 1,
|
||||||
|
.reg_ssrsys_srcclkena_mb = 1,
|
||||||
|
.reg_ssrsys_vcore_rmb = 1,
|
||||||
|
.reg_ssrsys_vrf18_rmb = 1,
|
||||||
|
.reg_ssusb_apsrc_rmb = 1,
|
||||||
|
.reg_ssusb_ddren_rmb = 0,
|
||||||
|
.reg_ssusb_emi_rmb = 1,
|
||||||
|
.reg_ssusb_infra_rmb = 1,
|
||||||
|
.reg_ssusb_pmic_rmb = 1,
|
||||||
|
.reg_ssusb_srcclkena_mb = 1,
|
||||||
|
.reg_ssusb_vcore_rmb = 1,
|
||||||
|
.reg_ssusb_vrf18_rmb = 1,
|
||||||
|
.reg_uart_hub_infra_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_15 */
|
||||||
|
.reg_uart_hub_pmic_rmb = 1,
|
||||||
|
.reg_uart_hub_srcclkena_mb = 1,
|
||||||
|
.reg_uart_hub_vcore_rmb = 1,
|
||||||
|
.reg_uart_hub_vrf18_rmb = 1,
|
||||||
|
.reg_ufs_apsrc_rmb = 1,
|
||||||
|
.reg_ufs_ddren_rmb = 0,
|
||||||
|
.reg_ufs_emi_rmb = 1,
|
||||||
|
.reg_ufs_infra_rmb = 1,
|
||||||
|
.reg_ufs_pmic_rmb = 1,
|
||||||
|
.reg_ufs_srcclkena_mb = 1,
|
||||||
|
.reg_ufs_vcore_rmb = 1,
|
||||||
|
.reg_ufs_vrf18_rmb = 1,
|
||||||
|
.reg_vdec_apsrc_rmb = 0,
|
||||||
|
.reg_vdec_ddren_rmb = 0,
|
||||||
|
.reg_vdec_emi_rmb = 0,
|
||||||
|
.reg_vdec_infra_rmb = 0,
|
||||||
|
.reg_vdec_pmic_rmb = 0,
|
||||||
|
.reg_vdec_srcclkena_mb = 0,
|
||||||
|
.reg_vdec_vrf18_rmb = 0,
|
||||||
|
.reg_venc_apsrc_rmb = 0,
|
||||||
|
.reg_venc_ddren_rmb = 0,
|
||||||
|
.reg_venc_emi_rmb = 0,
|
||||||
|
.reg_venc_infra_rmb = 0,
|
||||||
|
.reg_venc_pmic_rmb = 0,
|
||||||
|
.reg_venc_srcclkena_mb = 0,
|
||||||
|
.reg_venc_vrf18_rmb = 0,
|
||||||
|
.reg_vlpcfg_apsrc_rmb = 1,
|
||||||
|
.reg_vlpcfg_ddren_rmb = 0,
|
||||||
|
.reg_vlpcfg_emi_rmb = 1,
|
||||||
|
.reg_vlpcfg_infra_rmb = 1,
|
||||||
|
.reg_vlpcfg_pmic_rmb = 1,
|
||||||
|
.reg_vlpcfg_srcclkena_mb = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_16 */
|
||||||
|
.reg_vlpcfg_vcore_rmb = 1,
|
||||||
|
.reg_vlpcfg_vrf18_rmb = 1,
|
||||||
|
.reg_vlpcfg1_apsrc_rmb = 1,
|
||||||
|
.reg_vlpcfg1_ddren_rmb = 0,
|
||||||
|
.reg_vlpcfg1_emi_rmb = 1,
|
||||||
|
.reg_vlpcfg1_infra_rmb = 1,
|
||||||
|
.reg_vlpcfg1_pmic_rmb = 1,
|
||||||
|
.reg_vlpcfg1_srcclkena_mb = 1,
|
||||||
|
.reg_vlpcfg1_vcore_rmb = 1,
|
||||||
|
.reg_vlpcfg1_vrf18_rmb = 1,
|
||||||
|
|
||||||
|
/* SPM_EVENT_CON_MISC */
|
||||||
|
.reg_srcclken_fast_resp = 0,
|
||||||
|
.reg_csyspwrup_ack_mask = 1,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_17 */
|
||||||
|
/* SPM D7X WA for wakeup source */
|
||||||
|
.reg_spm_sw_vcore_rmb = 0x3,
|
||||||
|
.reg_spm_sw_pmic_rmb = 0,
|
||||||
|
|
||||||
|
/* SPM_SRC_MASK_18 */
|
||||||
|
.reg_spm_sw_srcclkena_mb = 0,
|
||||||
|
|
||||||
|
/* SPM_WAKE_MASK*/
|
||||||
|
#ifdef MT_SPM_COMMON_SODI_SUPPORT
|
||||||
|
#if defined(CFG_MICROTRUST_TEE_SUPPORT)
|
||||||
|
.reg_wake_mask = 0x81302012,
|
||||||
|
#else
|
||||||
|
.reg_wake_mask = 0x89302012,
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
.reg_wake_mask = 0xEFFFFFF7,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.reg_ext_wake_mask = 0xFFFFFFFF,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct spm_lp_scen __spm_vcorefs = {
|
||||||
|
.pwrctrl = &vcorefs_ctrl,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int get_vsram_pmic_voltage(void)
|
||||||
|
{
|
||||||
|
uint8_t vsram_pmic = 0x78;
|
||||||
|
int spmi_ret = 0;
|
||||||
|
#ifdef CONFIG_MTK_SPMI
|
||||||
|
struct spmi_device *spmi_dev;
|
||||||
|
|
||||||
|
spmi_dev = get_spmi_device(SPMI_MASTER_1, SPMI_SLAVE_4);
|
||||||
|
if (spmi_dev == NULL)
|
||||||
|
return vsram_pmic;
|
||||||
|
|
||||||
|
spmi_ret = spmi_ext_register_readl(spmi_dev, 0x250, &vsram_pmic, 1);
|
||||||
|
#endif
|
||||||
|
if (spmi_ret != 0)
|
||||||
|
vsram_pmic = 0x78;
|
||||||
|
|
||||||
|
return vsram_pmic;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_vcore_pmic_voltage(void)
|
||||||
|
{
|
||||||
|
uint8_t vcore_pmic = 0x91;
|
||||||
|
int spmi_ret = 0;
|
||||||
|
#ifdef CONFIG_MTK_SPMI
|
||||||
|
struct spmi_device *spmi_dev;
|
||||||
|
uint16_t vcore_addr;
|
||||||
|
|
||||||
|
vcore_addr = (uint16_t)((mmio_read_32(SPM_PWRAP_CMD0) >> 16) & 0xFFFF);
|
||||||
|
spmi_dev = get_spmi_device(SPMI_MASTER_P_1, SPMI_SLAVE_8);
|
||||||
|
if (spmi_dev == NULL)
|
||||||
|
return vcore_pmic;
|
||||||
|
|
||||||
|
spmi_ret = spmi_ext_register_readl(spmi_dev, vcore_addr, &vcore_pmic, 1);
|
||||||
|
#endif
|
||||||
|
if (spmi_ret != 0)
|
||||||
|
vcore_pmic = 0x91;
|
||||||
|
|
||||||
|
return vcore_pmic;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spm_dvfsfw_init(uint64_t boot_up_opp, uint64_t dram_issue)
|
||||||
|
{
|
||||||
|
uint32_t pmic_val;
|
||||||
|
|
||||||
|
pmic_val = get_vsram_pmic_voltage();
|
||||||
|
pmic_val = VCORE_UV_TO_PMIC(VSRAM_PMIC_TO_UV(pmic_val));
|
||||||
|
mt_spm_pmic_wrap_set_cmd(PMIC_WRAP_PHASE_ALLINONE, CMD_17, pmic_val);
|
||||||
|
pmic_val = get_vcore_pmic_voltage();
|
||||||
|
mmio_write_32(PCM_WDT_LATCH_SPARE_5, pmic_val);
|
||||||
|
|
||||||
|
if (spm_dvfs_init_done)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mmio_clrsetbits_32(SPM_DVFS_CON, SPM_DVFS_FORCE_ENABLE_LSB, SPM_DVFSRC_ENABLE_LSB);
|
||||||
|
|
||||||
|
mmio_write_32(SPM_SW_RSV_3, 0x08000000);
|
||||||
|
mmio_write_32(SPM_DVS_DFS_LEVEL, 0x10080080);
|
||||||
|
mmio_write_32(PCM_WDT_LATCH_SPARE_4, 0x08008002);
|
||||||
|
|
||||||
|
spm_dvfs_init_done = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __spm_sync_vcore_dvfs_pcm_flags(uint32_t *dest_pcm_flags,
|
||||||
|
const uint32_t *src_pcm_flags)
|
||||||
|
{
|
||||||
|
uint32_t dvfs_mask = SPM_FLAG_DISABLE_VCORE_DVS |
|
||||||
|
SPM_FLAG_DISABLE_DDR_DFS |
|
||||||
|
SPM_FLAG_DISABLE_EMI_DFS |
|
||||||
|
SPM_FLAG_DISABLE_BUS_DFS;
|
||||||
|
|
||||||
|
*dest_pcm_flags = (*dest_pcm_flags & (~dvfs_mask)) |
|
||||||
|
(*src_pcm_flags & dvfs_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __spm_sync_vcore_dvfs_power_control(struct pwr_ctrl *dest_pwr_ctrl,
|
||||||
|
const struct pwr_ctrl *src_pwr_ctrl)
|
||||||
|
{
|
||||||
|
|
||||||
|
__spm_sync_vcore_dvfs_pcm_flags(&dest_pwr_ctrl->pcm_flags,
|
||||||
|
&src_pwr_ctrl->pcm_flags);
|
||||||
|
|
||||||
|
if (dest_pwr_ctrl->pcm_flags_cust)
|
||||||
|
__spm_sync_vcore_dvfs_pcm_flags(&dest_pwr_ctrl->pcm_flags_cust,
|
||||||
|
&src_pwr_ctrl->pcm_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void spm_go_to_vcorefs(uint64_t spm_flags)
|
||||||
|
{
|
||||||
|
set_pwrctrl_pcm_flags(__spm_vcorefs.pwrctrl, spm_flags);
|
||||||
|
__spm_set_power_control(__spm_vcorefs.pwrctrl, 0);
|
||||||
|
__spm_set_wakeup_event(__spm_vcorefs.pwrctrl);
|
||||||
|
__spm_set_pcm_flags(__spm_vcorefs.pwrctrl);
|
||||||
|
__spm_send_cpu_wakeup_event();
|
||||||
|
}
|
12
plat/mediatek/drivers/spm/mt8196/mt_spm_vcorefs.h
Normal file
12
plat/mediatek/drivers/spm/mt8196/mt_spm_vcorefs.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_SPM_VCOREFS_H
|
||||||
|
#define MT_SPM_VCOREFS_H
|
||||||
|
|
||||||
|
void spm_go_to_vcorefs(uint64_t spm_flags);
|
||||||
|
|
||||||
|
#endif /* MT_SPM_VCOREFS_H */
|
14
plat/mediatek/drivers/spm/mt8196/mt_spm_vcorefs_ext.h
Normal file
14
plat/mediatek/drivers/spm/mt8196/mt_spm_vcorefs_ext.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_VCORE_DVFSRC_EXT_H
|
||||||
|
|
||||||
|
#define MT_VCORE_DVFSRC_EXT_H
|
||||||
|
#define MTK_VCORE_DVFS_RES_MEM
|
||||||
|
|
||||||
|
int spm_vcorefs_rsc_mem_req(bool request);
|
||||||
|
|
||||||
|
#endif /* MT_VCORE_DVFSRC_EXT_H */
|
598
plat/mediatek/drivers/spm/mt8196/mt_spm_vcorefs_reg.h
Normal file
598
plat/mediatek/drivers/spm/mt8196/mt_spm_vcorefs_reg.h
Normal file
|
@ -0,0 +1,598 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_SPM_VCOREFS_REG_6991_H
|
||||||
|
#define MT_SPM_VCOREFS_REG_6991_H
|
||||||
|
|
||||||
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* DVFSRC related constants
|
||||||
|
*************************************************************************/
|
||||||
|
#define DVFSRC_BASE (IO_PHYS + 0x0C013000)
|
||||||
|
#define EFUSEC_BASE (IO_PHYS + 0x03260000)
|
||||||
|
#define EFUSE_SIZE (0x1000)
|
||||||
|
#define DVFSRC_REG_SIZE (0x1000)
|
||||||
|
#define DVFSRC_BASIC_CONTROL (DVFSRC_BASE + 0x0)
|
||||||
|
#define DVFSRC_BASIC_CONTROL_4 (DVFSRC_BASE + 0xC)
|
||||||
|
#define DVFSRC_SW_REQ1 (DVFSRC_BASE + 0x10)
|
||||||
|
#define DVFSRC_SW_REQ2 (DVFSRC_BASE + 0x14)
|
||||||
|
#define DVFSRC_SW_REQ3 (DVFSRC_BASE + 0x18)
|
||||||
|
#define DVFSRC_SW_REQ4 (DVFSRC_BASE + 0x1C)
|
||||||
|
#define DVFSRC_SW_REQ5 (DVFSRC_BASE + 0x20)
|
||||||
|
#define DVFSRC_SW_REQ6 (DVFSRC_BASE + 0x24)
|
||||||
|
#define DVFSRC_SW_REQ7 (DVFSRC_BASE + 0x28)
|
||||||
|
#define DVFSRC_SW_REQ8 (DVFSRC_BASE + 0x2C)
|
||||||
|
#define DVFSRC_EMI_REQUEST (DVFSRC_BASE + 0x30)
|
||||||
|
#define DVFSRC_EMI_REQUEST3 (DVFSRC_BASE + 0x38)
|
||||||
|
#define DVFSRC_EMI_REQUEST5 (DVFSRC_BASE + 0x40)
|
||||||
|
#define DVFSRC_EMI_QOS0 (DVFSRC_BASE + 0x4C)
|
||||||
|
#define DVFSRC_EMI_QOS1 (DVFSRC_BASE + 0x50)
|
||||||
|
#define DVFSRC_EMI_QOS2 (DVFSRC_BASE + 0x54)
|
||||||
|
#define DVFSRC_EMI_QOS3 (DVFSRC_BASE + 0x58)
|
||||||
|
#define DVFSRC_EMI_QOS4 (DVFSRC_BASE + 0x5C)
|
||||||
|
#define DVFSRC_EMI_QOS5 (DVFSRC_BASE + 0x60)
|
||||||
|
#define DVFSRC_EMI_QOS6 (DVFSRC_BASE + 0x64)
|
||||||
|
#define DVFSRC_VCORE_REQUEST (DVFSRC_BASE + 0x80)
|
||||||
|
#define DVFSRC_VCORE_REQUEST3 (DVFSRC_BASE + 0x88)
|
||||||
|
#define DVFSRC_VCORE_QOS0 (DVFSRC_BASE + 0x94)
|
||||||
|
#define DVFSRC_VCORE_QOS1 (DVFSRC_BASE + 0x98)
|
||||||
|
#define DVFSRC_VCORE_QOS2 (DVFSRC_BASE + 0x9C)
|
||||||
|
#define DVFSRC_VCORE_QOS3 (DVFSRC_BASE + 0xA0)
|
||||||
|
#define DVFSRC_VCORE_QOS4 (DVFSRC_BASE + 0xA4)
|
||||||
|
#define DVFSRC_HALT_SW_CONTROL (DVFSRC_BASE + 0xC4)
|
||||||
|
#define DVFSRC_INT (DVFSRC_BASE + 0xC8)
|
||||||
|
#define DVFSRC_INT_EN (DVFSRC_BASE + 0xCC)
|
||||||
|
#define DVFSRC_INT_CLR (DVFSRC_BASE + 0xD0)
|
||||||
|
#define DVFSRC_BW_MON_WINDOW (DVFSRC_BASE + 0xD4)
|
||||||
|
#define DVFSRC_BW_MON_THRES_1 (DVFSRC_BASE + 0xD8)
|
||||||
|
#define DVFSRC_BW_MON_THRES_2 (DVFSRC_BASE + 0xDC)
|
||||||
|
#define DVFSRC_MD_TURBO (DVFSRC_BASE + 0xE0)
|
||||||
|
#define DVFSRC_PCIE_VCORE_REQ (DVFSRC_BASE + 0xE4)
|
||||||
|
#define DVFSRC_VCORE_USER_REQ (DVFSRC_BASE + 0xE8)
|
||||||
|
#define DVFSRC_BW_USER_REQ (DVFSRC_BASE + 0xEC)
|
||||||
|
#define DVFSRC_TIMEOUT_NEXTREQ (DVFSRC_BASE + 0xF8)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_0_1 (DVFSRC_BASE + 0xFC)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_2_3 (DVFSRC_BASE + 0x100)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_4_5 (DVFSRC_BASE + 0x104)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_6_7 (DVFSRC_BASE + 0x108)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_8_9 (DVFSRC_BASE + 0x10C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_10_11 (DVFSRC_BASE + 0x110)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_12_13 (DVFSRC_BASE + 0x114)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_14_15 (DVFSRC_BASE + 0x118)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_16_17 (DVFSRC_BASE + 0x11C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_18_19 (DVFSRC_BASE + 0x120)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_20_21 (DVFSRC_BASE + 0x124)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_22_23 (DVFSRC_BASE + 0x128)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_24_25 (DVFSRC_BASE + 0x12C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_26_27 (DVFSRC_BASE + 0x130)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_28_29 (DVFSRC_BASE + 0x134)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_30_31 (DVFSRC_BASE + 0x138)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_32_33 (DVFSRC_BASE + 0x13C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_34_35 (DVFSRC_BASE + 0x140)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_36_37 (DVFSRC_BASE + 0x144)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_38_39 (DVFSRC_BASE + 0x148)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_40_41 (DVFSRC_BASE + 0x14C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_42_43 (DVFSRC_BASE + 0x150)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_44_45 (DVFSRC_BASE + 0x154)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_46_47 (DVFSRC_BASE + 0x158)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_48_49 (DVFSRC_BASE + 0x15C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_50_51 (DVFSRC_BASE + 0x160)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_52_53 (DVFSRC_BASE + 0x164)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_54_55 (DVFSRC_BASE + 0x168)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_56_57 (DVFSRC_BASE + 0x16C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_58_59 (DVFSRC_BASE + 0x170)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_60_61 (DVFSRC_BASE + 0x174)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_62_63 (DVFSRC_BASE + 0x178)
|
||||||
|
#define DVFSRC_SW_BW_0 (DVFSRC_BASE + 0x1DC)
|
||||||
|
#define DVFSRC_SW_BW_1 (DVFSRC_BASE + 0x1E0)
|
||||||
|
#define DVFSRC_SW_BW_2 (DVFSRC_BASE + 0x1E4)
|
||||||
|
#define DVFSRC_SW_BW_3 (DVFSRC_BASE + 0x1E8)
|
||||||
|
#define DVFSRC_SW_BW_4 (DVFSRC_BASE + 0x1EC)
|
||||||
|
#define DVFSRC_SW_BW_5 (DVFSRC_BASE + 0x1F0)
|
||||||
|
#define DVFSRC_SW_BW_6 (DVFSRC_BASE + 0x1F4)
|
||||||
|
#define DVFSRC_SW_BW_7 (DVFSRC_BASE + 0x1F8)
|
||||||
|
#define DVFSRC_SW_BW_8 (DVFSRC_BASE + 0x1FC)
|
||||||
|
#define DVFSRC_SW_BW_9 (DVFSRC_BASE + 0x200)
|
||||||
|
#define DVFSRC_QOS_EN (DVFSRC_BASE + 0x204)
|
||||||
|
#define DVFSRC_ISP_HRT (DVFSRC_BASE + 0x20C)
|
||||||
|
#define DVFSRC_HRT_BW_BASE (DVFSRC_BASE + 0x210)
|
||||||
|
#define DVFSRC_SEC_SW_REQ (DVFSRC_BASE + 0x214)
|
||||||
|
#define DVFSRC_EMI_MON_DEBOUNCE_TIME (DVFSRC_BASE + 0x218)
|
||||||
|
#define DVFSRC_MD_LATENCY_IMPROVE (DVFSRC_BASE + 0x21C)
|
||||||
|
#define DVFSRC_DEBOUNCE_TIME (DVFSRC_BASE + 0x220)
|
||||||
|
#define DVFSRC_LEVEL_MASK_MD_1 (DVFSRC_BASE + 0x224)
|
||||||
|
#define DVFSRC_LEVEL_MASK_MD_2 (DVFSRC_BASE + 0x228)
|
||||||
|
#define DVFSRC_DEFAULT_OPP_1 (DVFSRC_BASE + 0x22C)
|
||||||
|
#define DVFSRC_DEFAULT_OPP_2 (DVFSRC_BASE + 0x230)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMI0 (DVFSRC_BASE + 0x234)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMI1 (DVFSRC_BASE + 0x238)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMI2 (DVFSRC_BASE + 0x23C)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMI3 (DVFSRC_BASE + 0x240)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMI0_T (DVFSRC_BASE + 0x244)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMI1_T (DVFSRC_BASE + 0x248)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMI2_T (DVFSRC_BASE + 0x24C)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMI3_T (DVFSRC_BASE + 0x250)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMIU (DVFSRC_BASE + 0x254)
|
||||||
|
#define DVFSRC_95MD_SCEN_BW0 (DVFSRC_BASE + 0x258)
|
||||||
|
#define DVFSRC_95MD_SCEN_BW1 (DVFSRC_BASE + 0x25C)
|
||||||
|
#define DVFSRC_95MD_SCEN_BW2 (DVFSRC_BASE + 0x260)
|
||||||
|
#define DVFSRC_95MD_SCEN_BW3 (DVFSRC_BASE + 0x264)
|
||||||
|
#define DVFSRC_95MD_SCEN_BW0_T (DVFSRC_BASE + 0x268)
|
||||||
|
#define DVFSRC_95MD_SCEN_BW1_T (DVFSRC_BASE + 0x26C)
|
||||||
|
#define DVFSRC_95MD_SCEN_BW2_T (DVFSRC_BASE + 0x270)
|
||||||
|
#define DVFSRC_95MD_SCEN_BW3_T (DVFSRC_BASE + 0x274)
|
||||||
|
#define DVFSRC_95MD_SCEN_BWU (DVFSRC_BASE + 0x278)
|
||||||
|
#define DVFSRC_MD_LEVEL_SW_REG (DVFSRC_BASE + 0x27C)
|
||||||
|
#define DVFSRC_RSRV_0 (DVFSRC_BASE + 0x280)
|
||||||
|
#define DVFSRC_RSRV_1 (DVFSRC_BASE + 0x284)
|
||||||
|
#define DVFSRC_RSRV_2 (DVFSRC_BASE + 0x288)
|
||||||
|
#define DVFSRC_RSRV_3 (DVFSRC_BASE + 0x28C)
|
||||||
|
#define DVFSRC_RSRV_4 (DVFSRC_BASE + 0x290)
|
||||||
|
#define DVFSRC_RSRV_5 (DVFSRC_BASE + 0x294)
|
||||||
|
#define DVFSRC_SPM_RESEND (DVFSRC_BASE + 0x298)
|
||||||
|
#define DVFSRC_DEBUG_STA_0 (DVFSRC_BASE + 0x29C)
|
||||||
|
#define DVFSRC_DEBUG_STA_1 (DVFSRC_BASE + 0x2A0)
|
||||||
|
#define DVFSRC_DEBUG_STA_2 (DVFSRC_BASE + 0x2A4)
|
||||||
|
#define DVFSRC_DEBUG_STA_3 (DVFSRC_BASE + 0x2A8)
|
||||||
|
#define DVFSRC_DEBUG_STA_4 (DVFSRC_BASE + 0x2AC)
|
||||||
|
#define DVFSRC_DEBUG_STA_5 (DVFSRC_BASE + 0x2B0)
|
||||||
|
#define DVFSRC_DEBUG_STA_6 (DVFSRC_BASE + 0x2B4)
|
||||||
|
#define DVFSRC_DEBUG_STA_8 (DVFSRC_BASE + 0x2BC)
|
||||||
|
#define DVFSRC_DEBUG_STA_9 (DVFSRC_BASE + 0x2C0)
|
||||||
|
#define DVFSRC_DEBUG_STA_10 (DVFSRC_BASE + 0x2C4)
|
||||||
|
#define DVFSRC_DDR_REQUEST (DVFSRC_BASE + 0x2C8)
|
||||||
|
#define DVFSRC_DDR_REQUEST3 (DVFSRC_BASE + 0x2D0)
|
||||||
|
#define DVFSRC_DDR_REQUEST5 (DVFSRC_BASE + 0x2D8)
|
||||||
|
#define DVFSRC_DDR_QOS0 (DVFSRC_BASE + 0x2E8)
|
||||||
|
#define DVFSRC_DDR_QOS1 (DVFSRC_BASE + 0x2EC)
|
||||||
|
#define DVFSRC_DDR_QOS2 (DVFSRC_BASE + 0x2F0)
|
||||||
|
#define DVFSRC_DDR_QOS3 (DVFSRC_BASE + 0x2F4)
|
||||||
|
#define DVFSRC_DDR_QOS4 (DVFSRC_BASE + 0x2F8)
|
||||||
|
#define DVFSRC_DDR_QOS5 (DVFSRC_BASE + 0x2FC)
|
||||||
|
#define DVFSRC_DDR_QOS6 (DVFSRC_BASE + 0x300)
|
||||||
|
#define DVFSRC_RSRV_6 (DVFSRC_BASE + 0x304)
|
||||||
|
#define DVFSRC_RSRV_7 (DVFSRC_BASE + 0x308)
|
||||||
|
#define DVFSRC_RSRV_8 (DVFSRC_BASE + 0x30C)
|
||||||
|
#define DVFSRC_RSRV_9 (DVFSRC_BASE + 0x310)
|
||||||
|
#define DVFSRC_RSRV_10 (DVFSRC_BASE + 0x314)
|
||||||
|
#define DVFSRC_RSRV_11 (DVFSRC_BASE + 0x318)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_URG (DVFSRC_BASE + 0x320)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_0 (DVFSRC_BASE + 0x324)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_1 (DVFSRC_BASE + 0x328)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_2 (DVFSRC_BASE + 0x32C)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_3 (DVFSRC_BASE + 0x330)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_4 (DVFSRC_BASE + 0x334)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_5 (DVFSRC_BASE + 0x338)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_6 (DVFSRC_BASE + 0x33C)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_7 (DVFSRC_BASE + 0x340)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_8 (DVFSRC_BASE + 0x344)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_9 (DVFSRC_BASE + 0x348)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_10 (DVFSRC_BASE + 0x34C)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_0 (DVFSRC_BASE + 0x350)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_1 (DVFSRC_BASE + 0x354)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_2 (DVFSRC_BASE + 0x358)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_3 (DVFSRC_BASE + 0x35C)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_4 (DVFSRC_BASE + 0x360)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_5 (DVFSRC_BASE + 0x364)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_6 (DVFSRC_BASE + 0x368)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_7 (DVFSRC_BASE + 0x36C)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_8 (DVFSRC_BASE + 0x370)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_9 (DVFSRC_BASE + 0x374)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_10 (DVFSRC_BASE + 0x378)
|
||||||
|
#define DVFSRC_HRT_REQUEST (DVFSRC_BASE + 0x380)
|
||||||
|
#define DVFSRC_HRT_HIGH_3 (DVFSRC_BASE + 0x384)
|
||||||
|
#define DVFSRC_HRT_HIGH_2 (DVFSRC_BASE + 0x388)
|
||||||
|
#define DVFSRC_HRT_HIGH_1 (DVFSRC_BASE + 0x38C)
|
||||||
|
#define DVFSRC_HRT_HIGH (DVFSRC_BASE + 0x390)
|
||||||
|
#define DVFSRC_HRT_LOW_3 (DVFSRC_BASE + 0x394)
|
||||||
|
#define DVFSRC_HRT_LOW_2 (DVFSRC_BASE + 0x398)
|
||||||
|
#define DVFSRC_HRT_LOW_1 (DVFSRC_BASE + 0x39C)
|
||||||
|
#define DVFSRC_HRT_LOW (DVFSRC_BASE + 0x3A0)
|
||||||
|
#define DVFSRC_DDR_ADD_REQUEST (DVFSRC_BASE + 0x3A4)
|
||||||
|
#define DVFSRC_EMI_ADD_REQUEST (DVFSRC_BASE + 0x3A8)
|
||||||
|
#define DVFSRC_LAST (DVFSRC_BASE + 0x3AC)
|
||||||
|
#define DVFSRC_LAST_L (DVFSRC_BASE + 0x3B0)
|
||||||
|
#define DVFSRC_MD_SCENARIO (DVFSRC_BASE + 0x3B4)
|
||||||
|
#define DVFSRC_RECORD_0_0 (DVFSRC_BASE + 0x3B8)
|
||||||
|
#define DVFSRC_RECORD_0_1 (DVFSRC_BASE + 0x3BC)
|
||||||
|
#define DVFSRC_RECORD_0_2 (DVFSRC_BASE + 0x3C0)
|
||||||
|
#define DVFSRC_RECORD_0_3 (DVFSRC_BASE + 0x3C4)
|
||||||
|
#define DVFSRC_RECORD_0_4 (DVFSRC_BASE + 0x3C8)
|
||||||
|
#define DVFSRC_RECORD_0_5 (DVFSRC_BASE + 0x3CC)
|
||||||
|
#define DVFSRC_RECORD_0_6 (DVFSRC_BASE + 0x3D0)
|
||||||
|
#define DVFSRC_RECORD_0_7 (DVFSRC_BASE + 0x3D4)
|
||||||
|
#define DVFSRC_RECORD_1_0 (DVFSRC_BASE + 0x3D8)
|
||||||
|
#define DVFSRC_RECORD_1_1 (DVFSRC_BASE + 0x3DC)
|
||||||
|
#define DVFSRC_RECORD_1_2 (DVFSRC_BASE + 0x3E0)
|
||||||
|
#define DVFSRC_RECORD_1_3 (DVFSRC_BASE + 0x3E4)
|
||||||
|
#define DVFSRC_RECORD_1_4 (DVFSRC_BASE + 0x3E8)
|
||||||
|
#define DVFSRC_RECORD_1_5 (DVFSRC_BASE + 0x3EC)
|
||||||
|
#define DVFSRC_RECORD_1_6 (DVFSRC_BASE + 0x3F0)
|
||||||
|
#define DVFSRC_RECORD_1_7 (DVFSRC_BASE + 0x3F4)
|
||||||
|
#define DVFSRC_RECORD_2_0 (DVFSRC_BASE + 0x3F8)
|
||||||
|
#define DVFSRC_RECORD_2_1 (DVFSRC_BASE + 0x3FC)
|
||||||
|
#define DVFSRC_RECORD_2_2 (DVFSRC_BASE + 0x400)
|
||||||
|
#define DVFSRC_RECORD_2_3 (DVFSRC_BASE + 0x404)
|
||||||
|
#define DVFSRC_RECORD_2_4 (DVFSRC_BASE + 0x408)
|
||||||
|
#define DVFSRC_RECORD_2_5 (DVFSRC_BASE + 0x40C)
|
||||||
|
#define DVFSRC_RECORD_2_6 (DVFSRC_BASE + 0x410)
|
||||||
|
#define DVFSRC_RECORD_2_7 (DVFSRC_BASE + 0x414)
|
||||||
|
#define DVFSRC_RECORD_3_0 (DVFSRC_BASE + 0x418)
|
||||||
|
#define DVFSRC_RECORD_3_1 (DVFSRC_BASE + 0x41C)
|
||||||
|
#define DVFSRC_RECORD_3_2 (DVFSRC_BASE + 0x420)
|
||||||
|
#define DVFSRC_RECORD_3_3 (DVFSRC_BASE + 0x424)
|
||||||
|
#define DVFSRC_RECORD_3_4 (DVFSRC_BASE + 0x428)
|
||||||
|
#define DVFSRC_RECORD_3_5 (DVFSRC_BASE + 0x42C)
|
||||||
|
#define DVFSRC_RECORD_3_6 (DVFSRC_BASE + 0x430)
|
||||||
|
#define DVFSRC_RECORD_3_7 (DVFSRC_BASE + 0x434)
|
||||||
|
#define DVFSRC_RECORD_4_0 (DVFSRC_BASE + 0x438)
|
||||||
|
#define DVFSRC_RECORD_4_1 (DVFSRC_BASE + 0x43C)
|
||||||
|
#define DVFSRC_RECORD_4_2 (DVFSRC_BASE + 0x440)
|
||||||
|
#define DVFSRC_RECORD_4_3 (DVFSRC_BASE + 0x444)
|
||||||
|
#define DVFSRC_RECORD_4_4 (DVFSRC_BASE + 0x448)
|
||||||
|
#define DVFSRC_RECORD_4_5 (DVFSRC_BASE + 0x44C)
|
||||||
|
#define DVFSRC_RECORD_4_6 (DVFSRC_BASE + 0x450)
|
||||||
|
#define DVFSRC_RECORD_4_7 (DVFSRC_BASE + 0x454)
|
||||||
|
#define DVFSRC_RECORD_5_0 (DVFSRC_BASE + 0x458)
|
||||||
|
#define DVFSRC_RECORD_5_1 (DVFSRC_BASE + 0x45C)
|
||||||
|
#define DVFSRC_RECORD_5_2 (DVFSRC_BASE + 0x460)
|
||||||
|
#define DVFSRC_RECORD_5_3 (DVFSRC_BASE + 0x464)
|
||||||
|
#define DVFSRC_RECORD_5_4 (DVFSRC_BASE + 0x468)
|
||||||
|
#define DVFSRC_RECORD_5_5 (DVFSRC_BASE + 0x46C)
|
||||||
|
#define DVFSRC_RECORD_5_6 (DVFSRC_BASE + 0x470)
|
||||||
|
#define DVFSRC_RECORD_5_7 (DVFSRC_BASE + 0x474)
|
||||||
|
#define DVFSRC_RECORD_6_0 (DVFSRC_BASE + 0x478)
|
||||||
|
#define DVFSRC_RECORD_6_1 (DVFSRC_BASE + 0x47C)
|
||||||
|
#define DVFSRC_RECORD_6_2 (DVFSRC_BASE + 0x480)
|
||||||
|
#define DVFSRC_RECORD_6_3 (DVFSRC_BASE + 0x484)
|
||||||
|
#define DVFSRC_RECORD_6_4 (DVFSRC_BASE + 0x488)
|
||||||
|
#define DVFSRC_RECORD_6_5 (DVFSRC_BASE + 0x48C)
|
||||||
|
#define DVFSRC_RECORD_6_6 (DVFSRC_BASE + 0x490)
|
||||||
|
#define DVFSRC_RECORD_6_7 (DVFSRC_BASE + 0x494)
|
||||||
|
#define DVFSRC_RECORD_7_0 (DVFSRC_BASE + 0x498)
|
||||||
|
#define DVFSRC_RECORD_7_1 (DVFSRC_BASE + 0x49C)
|
||||||
|
#define DVFSRC_RECORD_7_2 (DVFSRC_BASE + 0x4A0)
|
||||||
|
#define DVFSRC_RECORD_7_3 (DVFSRC_BASE + 0x4A4)
|
||||||
|
#define DVFSRC_RECORD_7_4 (DVFSRC_BASE + 0x4A8)
|
||||||
|
#define DVFSRC_RECORD_7_5 (DVFSRC_BASE + 0x4AC)
|
||||||
|
#define DVFSRC_RECORD_7_6 (DVFSRC_BASE + 0x4B0)
|
||||||
|
#define DVFSRC_RECORD_7_7 (DVFSRC_BASE + 0x4B4)
|
||||||
|
#define DVFSRC_RECORD_0_L_0 (DVFSRC_BASE + 0x4B8)
|
||||||
|
#define DVFSRC_RECORD_0_L_1 (DVFSRC_BASE + 0x4BC)
|
||||||
|
#define DVFSRC_RECORD_0_L_2 (DVFSRC_BASE + 0x4C0)
|
||||||
|
#define DVFSRC_RECORD_0_L_3 (DVFSRC_BASE + 0x4C4)
|
||||||
|
#define DVFSRC_RECORD_0_L_4 (DVFSRC_BASE + 0x4C8)
|
||||||
|
#define DVFSRC_RECORD_0_L_5 (DVFSRC_BASE + 0x4CC)
|
||||||
|
#define DVFSRC_RECORD_0_L_6 (DVFSRC_BASE + 0x4D0)
|
||||||
|
#define DVFSRC_RECORD_0_L_7 (DVFSRC_BASE + 0x4D4)
|
||||||
|
#define DVFSRC_RECORD_1_L_0 (DVFSRC_BASE + 0x4D8)
|
||||||
|
#define DVFSRC_RECORD_1_L_1 (DVFSRC_BASE + 0x4DC)
|
||||||
|
#define DVFSRC_RECORD_1_L_2 (DVFSRC_BASE + 0x4E0)
|
||||||
|
#define DVFSRC_RECORD_1_L_3 (DVFSRC_BASE + 0x4E4)
|
||||||
|
#define DVFSRC_RECORD_1_L_4 (DVFSRC_BASE + 0x4E8)
|
||||||
|
#define DVFSRC_RECORD_1_L_5 (DVFSRC_BASE + 0x4EC)
|
||||||
|
#define DVFSRC_RECORD_1_L_6 (DVFSRC_BASE + 0x4F0)
|
||||||
|
#define DVFSRC_RECORD_1_L_7 (DVFSRC_BASE + 0x4F4)
|
||||||
|
#define DVFSRC_RECORD_2_L_0 (DVFSRC_BASE + 0x4F8)
|
||||||
|
#define DVFSRC_RECORD_2_L_1 (DVFSRC_BASE + 0x4FC)
|
||||||
|
#define DVFSRC_RECORD_2_L_2 (DVFSRC_BASE + 0x500)
|
||||||
|
#define DVFSRC_RECORD_2_L_3 (DVFSRC_BASE + 0x504)
|
||||||
|
#define DVFSRC_RECORD_2_L_4 (DVFSRC_BASE + 0x508)
|
||||||
|
#define DVFSRC_RECORD_2_L_5 (DVFSRC_BASE + 0x50C)
|
||||||
|
#define DVFSRC_RECORD_2_L_6 (DVFSRC_BASE + 0x510)
|
||||||
|
#define DVFSRC_RECORD_2_L_7 (DVFSRC_BASE + 0x514)
|
||||||
|
#define DVFSRC_RECORD_3_L_0 (DVFSRC_BASE + 0x518)
|
||||||
|
#define DVFSRC_RECORD_3_L_1 (DVFSRC_BASE + 0x51C)
|
||||||
|
#define DVFSRC_RECORD_3_L_2 (DVFSRC_BASE + 0x520)
|
||||||
|
#define DVFSRC_RECORD_3_L_3 (DVFSRC_BASE + 0x524)
|
||||||
|
#define DVFSRC_RECORD_3_L_4 (DVFSRC_BASE + 0x528)
|
||||||
|
#define DVFSRC_RECORD_3_L_5 (DVFSRC_BASE + 0x52C)
|
||||||
|
#define DVFSRC_RECORD_3_L_6 (DVFSRC_BASE + 0x530)
|
||||||
|
#define DVFSRC_RECORD_3_L_7 (DVFSRC_BASE + 0x534)
|
||||||
|
#define DVFSRC_RECORD_4_L_0 (DVFSRC_BASE + 0x538)
|
||||||
|
#define DVFSRC_RECORD_4_L_1 (DVFSRC_BASE + 0x53C)
|
||||||
|
#define DVFSRC_RECORD_4_L_2 (DVFSRC_BASE + 0x540)
|
||||||
|
#define DVFSRC_RECORD_4_L_3 (DVFSRC_BASE + 0x544)
|
||||||
|
#define DVFSRC_RECORD_4_L_4 (DVFSRC_BASE + 0x548)
|
||||||
|
#define DVFSRC_RECORD_4_L_5 (DVFSRC_BASE + 0x54C)
|
||||||
|
#define DVFSRC_RECORD_4_L_6 (DVFSRC_BASE + 0x550)
|
||||||
|
#define DVFSRC_RECORD_4_L_7 (DVFSRC_BASE + 0x554)
|
||||||
|
#define DVFSRC_RECORD_5_L_0 (DVFSRC_BASE + 0x558)
|
||||||
|
#define DVFSRC_RECORD_5_L_1 (DVFSRC_BASE + 0x55C)
|
||||||
|
#define DVFSRC_RECORD_5_L_2 (DVFSRC_BASE + 0x560)
|
||||||
|
#define DVFSRC_RECORD_5_L_3 (DVFSRC_BASE + 0x564)
|
||||||
|
#define DVFSRC_RECORD_5_L_4 (DVFSRC_BASE + 0x568)
|
||||||
|
#define DVFSRC_RECORD_5_L_5 (DVFSRC_BASE + 0x56C)
|
||||||
|
#define DVFSRC_RECORD_5_L_6 (DVFSRC_BASE + 0x570)
|
||||||
|
#define DVFSRC_RECORD_5_L_7 (DVFSRC_BASE + 0x574)
|
||||||
|
#define DVFSRC_RECORD_6_L_0 (DVFSRC_BASE + 0x578)
|
||||||
|
#define DVFSRC_RECORD_6_L_1 (DVFSRC_BASE + 0x57C)
|
||||||
|
#define DVFSRC_RECORD_6_L_2 (DVFSRC_BASE + 0x580)
|
||||||
|
#define DVFSRC_RECORD_6_L_3 (DVFSRC_BASE + 0x584)
|
||||||
|
#define DVFSRC_RECORD_6_L_4 (DVFSRC_BASE + 0x588)
|
||||||
|
#define DVFSRC_RECORD_6_L_5 (DVFSRC_BASE + 0x58C)
|
||||||
|
#define DVFSRC_RECORD_6_L_6 (DVFSRC_BASE + 0x590)
|
||||||
|
#define DVFSRC_RECORD_6_L_7 (DVFSRC_BASE + 0x594)
|
||||||
|
#define DVFSRC_RECORD_7_L_0 (DVFSRC_BASE + 0x598)
|
||||||
|
#define DVFSRC_RECORD_7_L_1 (DVFSRC_BASE + 0x59C)
|
||||||
|
#define DVFSRC_RECORD_7_L_2 (DVFSRC_BASE + 0x5A0)
|
||||||
|
#define DVFSRC_RECORD_7_L_3 (DVFSRC_BASE + 0x5A4)
|
||||||
|
#define DVFSRC_RECORD_7_L_4 (DVFSRC_BASE + 0x5A8)
|
||||||
|
#define DVFSRC_RECORD_7_L_5 (DVFSRC_BASE + 0x5AC)
|
||||||
|
#define DVFSRC_RECORD_7_L_6 (DVFSRC_BASE + 0x5B0)
|
||||||
|
#define DVFSRC_RECORD_7_L_7 (DVFSRC_BASE + 0x5B4)
|
||||||
|
#define DVFSRC_CURRENT_LEVEL_1 (DVFSRC_BASE + 0x5C4)
|
||||||
|
#define DVFSRC_CURRENT_LEVEL_2 (DVFSRC_BASE + 0x5C8)
|
||||||
|
#define DVFSRC_TARGET_LEVEL_1 (DVFSRC_BASE + 0x5CC)
|
||||||
|
#define DVFSRC_TARGET_LEVEL_2 (DVFSRC_BASE + 0x5D0)
|
||||||
|
#define DVFSRC_CURRENT_FORCE_1 (DVFSRC_BASE + 0x5D4)
|
||||||
|
#define DVFSRC_CURRENT_FORCE_2 (DVFSRC_BASE + 0x5D8)
|
||||||
|
#define DVFSRC_TARGET_FORCE_1 (DVFSRC_BASE + 0x5DC)
|
||||||
|
#define DVFSRC_TARGET_FORCE_2 (DVFSRC_BASE + 0x5E0)
|
||||||
|
#define DVFSRC_MD_DDR_FLOOR_REQUEST (DVFSRC_BASE + 0x5E4)
|
||||||
|
#define DVFSRC_QOS_DDR_REQUEST (DVFSRC_BASE + 0x5E8)
|
||||||
|
#define DVFSRC_FORCE_MASK (DVFSRC_BASE + 0x5EC)
|
||||||
|
#define DVFSRC_LEVEL_HEX (DVFSRC_BASE + 0x5F0)
|
||||||
|
#define DVFSRC_AVS_RETRY (DVFSRC_BASE + 0x5F4)
|
||||||
|
#define DVFSRC_SW_REQ9 (DVFSRC_BASE + 0x5F8)
|
||||||
|
#define DVFSRC_SW_REQ10 (DVFSRC_BASE + 0x5FC)
|
||||||
|
#define DVFSRC_SW_REQ11 (DVFSRC_BASE + 0x600)
|
||||||
|
#define DVFSRC_SW_REQ12 (DVFSRC_BASE + 0x604)
|
||||||
|
#define DVFSRC_LEVEL_MASK_SW_1 (DVFSRC_BASE + 0x608)
|
||||||
|
#define DVFSRC_LEVEL_MASK_SW_2 (DVFSRC_BASE + 0x60C)
|
||||||
|
#define DVFSRC_ACCEPT_RETRY (DVFSRC_BASE + 0x610)
|
||||||
|
#define DVFSRC_TARGET_LEVEL_SPM_1 (DVFSRC_BASE + 0x614)
|
||||||
|
#define DVFSRC_TARGET_LEVEL_SPM_2 (DVFSRC_BASE + 0x618)
|
||||||
|
#define DVFSRC_EMI_REQUEST8 (DVFSRC_BASE + 0x620)
|
||||||
|
#define DVFSRC_DDR_REQUEST8 (DVFSRC_BASE + 0x62C)
|
||||||
|
#define DVFSRC_EMI_QOS7 (DVFSRC_BASE + 0x64C)
|
||||||
|
#define DVFSRC_EMI_QOS8 (DVFSRC_BASE + 0x650)
|
||||||
|
#define DVFSRC_EMI_QOS9 (DVFSRC_BASE + 0x654)
|
||||||
|
#define DVFSRC_EMI_QOS10 (DVFSRC_BASE + 0x658)
|
||||||
|
#define DVFSRC_DDR_QOS7 (DVFSRC_BASE + 0x65C)
|
||||||
|
#define DVFSRC_DDR_QOS8 (DVFSRC_BASE + 0x660)
|
||||||
|
#define DVFSRC_DDR_QOS9 (DVFSRC_BASE + 0x664)
|
||||||
|
#define DVFSRC_DDR_QOS10 (DVFSRC_BASE + 0x668)
|
||||||
|
#define DVFSRC_HRT_HIGH_7 (DVFSRC_BASE + 0x66C)
|
||||||
|
#define DVFSRC_HRT_HIGH_6 (DVFSRC_BASE + 0x670)
|
||||||
|
#define DVFSRC_HRT_HIGH_5 (DVFSRC_BASE + 0x674)
|
||||||
|
#define DVFSRC_HRT_HIGH_4 (DVFSRC_BASE + 0x678)
|
||||||
|
#define DVFSRC_HRT_LOW_7 (DVFSRC_BASE + 0x67C)
|
||||||
|
#define DVFSRC_HRT_LOW_6 (DVFSRC_BASE + 0x680)
|
||||||
|
#define DVFSRC_HRT_LOW_5 (DVFSRC_BASE + 0x684)
|
||||||
|
#define DVFSRC_HRT_LOW_4 (DVFSRC_BASE + 0x688)
|
||||||
|
#define DVFSRC_DDR_ADD_REQUEST_1 (DVFSRC_BASE + 0x68C)
|
||||||
|
#define DVFSRC_EMI_ADD_REQUEST_1 (DVFSRC_BASE + 0x690)
|
||||||
|
#define DVFSRC_HRT_REQUEST_1 (DVFSRC_BASE + 0x694)
|
||||||
|
#define DVFSRC_VCORE_QOS5 (DVFSRC_BASE + 0x69C)
|
||||||
|
#define DVFSRC_VCORE_QOS6 (DVFSRC_BASE + 0x6A0)
|
||||||
|
#define DVFSRC_VCORE_QOS7 (DVFSRC_BASE + 0x6A4)
|
||||||
|
#define DVFSRC_CEILING_SET (DVFSRC_BASE + 0x6A8)
|
||||||
|
#define DVFSRC_CUR_TARGET_GEAR (DVFSRC_BASE + 0x6AC)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_64_65 (DVFSRC_BASE + 0x6B0)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_66_67 (DVFSRC_BASE + 0x6B4)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_68_69 (DVFSRC_BASE + 0x6B8)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_70_71 (DVFSRC_BASE + 0x6BC)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_72_73 (DVFSRC_BASE + 0x6C0)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_74_75 (DVFSRC_BASE + 0x6C4)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_76_77 (DVFSRC_BASE + 0x6C8)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_78_79 (DVFSRC_BASE + 0x6CC)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_80_81 (DVFSRC_BASE + 0x6D0)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_82_83 (DVFSRC_BASE + 0x6D4)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_84_85 (DVFSRC_BASE + 0x6D8)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_86_87 (DVFSRC_BASE + 0x6DC)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_88_89 (DVFSRC_BASE + 0x6E0)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_90_91 (DVFSRC_BASE + 0x6E4)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_92_93 (DVFSRC_BASE + 0x6E8)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_94_95 (DVFSRC_BASE + 0x6EC)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_96_97 (DVFSRC_BASE + 0x6F0)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_98_99 (DVFSRC_BASE + 0x6F4)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_100_101 (DVFSRC_BASE + 0x6F8)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_102_103 (DVFSRC_BASE + 0x6FC)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_104_105 (DVFSRC_BASE + 0x700)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_106_107 (DVFSRC_BASE + 0x704)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_108_109 (DVFSRC_BASE + 0x708)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_110_111 (DVFSRC_BASE + 0x70C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_112_113 (DVFSRC_BASE + 0x710)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_114_115 (DVFSRC_BASE + 0x714)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_116_117 (DVFSRC_BASE + 0x718)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_118_119 (DVFSRC_BASE + 0x71C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_120_121 (DVFSRC_BASE + 0x720)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_122_123 (DVFSRC_BASE + 0x724)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_124_125 (DVFSRC_BASE + 0x728)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_126_127 (DVFSRC_BASE + 0x72C)
|
||||||
|
#define DVFSRC_LEVEL_MASK_MD_3 (DVFSRC_BASE + 0x738)
|
||||||
|
#define DVFSRC_LEVEL_MASK_MD_4 (DVFSRC_BASE + 0x73C)
|
||||||
|
#define DVFSRC_DEFAULT_OPP_3 (DVFSRC_BASE + 0x740)
|
||||||
|
#define DVFSRC_DEFAULT_OPP_4 (DVFSRC_BASE + 0x744)
|
||||||
|
#define DVFSRC_LEVEL_MASK_SW_3 (DVFSRC_BASE + 0x748)
|
||||||
|
#define DVFSRC_LEVEL_MASK_SW_4 (DVFSRC_BASE + 0x74C)
|
||||||
|
#define DVFSRC_TARGET_LEVEL_SPM_3 (DVFSRC_BASE + 0x750)
|
||||||
|
#define DVFSRC_TARGET_LEVEL_SPM_4 (DVFSRC_BASE + 0x754)
|
||||||
|
#define DVFSRC_CURRENT_LEVEL_3 (DVFSRC_BASE + 0x758)
|
||||||
|
#define DVFSRC_CURRENT_LEVEL_4 (DVFSRC_BASE + 0x75C)
|
||||||
|
#define DVFSRC_TARGET_LEVEL_3 (DVFSRC_BASE + 0x760)
|
||||||
|
#define DVFSRC_TARGET_LEVEL_4 (DVFSRC_BASE + 0x764)
|
||||||
|
#define DVFSRC_CURRENT_FORCE_3 (DVFSRC_BASE + 0x768)
|
||||||
|
#define DVFSRC_CURRENT_FORCE_4 (DVFSRC_BASE + 0x76C)
|
||||||
|
#define DVFSRC_TARGET_FORCE_3 (DVFSRC_BASE + 0x770)
|
||||||
|
#define DVFSRC_TARGET_FORCE_4 (DVFSRC_BASE + 0x774)
|
||||||
|
#define DVFSRC_DDR_REQUEST10 (DVFSRC_BASE + 0x778)
|
||||||
|
#define DVFSRC_EMI_REQUEST10 (DVFSRC_BASE + 0x77C)
|
||||||
|
#define DVFSRC_DDR_REQUEST11 (DVFSRC_BASE + 0x780)
|
||||||
|
#define DVFSRC_EMI_REQUEST11 (DVFSRC_BASE + 0x784)
|
||||||
|
#define DVFSRC_TARGET_FORCE_5 (DVFSRC_BASE + 0x788)
|
||||||
|
#define DVFSRC_TARGET_FORCE_6 (DVFSRC_BASE + 0x78C)
|
||||||
|
#define DVFSRC_TARGET_FORCE_7 (DVFSRC_BASE + 0x790)
|
||||||
|
#define DVFSRC_TARGET_FORCE_8 (DVFSRC_BASE + 0x794)
|
||||||
|
#define DVFSRC_PMQOS_HRT_UNIT_SW_BW (DVFSRC_BASE + 0x798)
|
||||||
|
#define DVFSRC_DISP_HRT_UNIT_SW_BW (DVFSRC_BASE + 0x79C)
|
||||||
|
#define DVFSRC_ISP_HRT_UNIT_SW_BW (DVFSRC_BASE + 0x7A0)
|
||||||
|
#define DVFSRC_MD_HRT_UNIT_SW_BW (DVFSRC_BASE + 0x7A4)
|
||||||
|
#define DVFSRC_HRT_BASE_HRT_UNIT_SW_BW (DVFSRC_BASE + 0x7A8)
|
||||||
|
#define DVFSRC_APU_HRT_UNIT_SW_BW (DVFSRC_BASE + 0x7AC)
|
||||||
|
#define DVFSRC_SMMU_HRT_UNIT_SW_BW (DVFSRC_BASE + 0x7B0)
|
||||||
|
#define DVFSRC_SMAP_CG_SET (DVFSRC_BASE + 0x814)
|
||||||
|
#define DVFSRC_LEVEL_MASK_MD_5 (DVFSRC_BASE + 0x818)
|
||||||
|
#define DVFSRC_LEVEL_MASK_MD_6 (DVFSRC_BASE + 0x81C)
|
||||||
|
#define DVFSRC_LEVEL_MASK_MD_7 (DVFSRC_BASE + 0x820)
|
||||||
|
#define DVFSRC_LEVEL_MASK_MD_8 (DVFSRC_BASE + 0x824)
|
||||||
|
#define DVFSRC_DEFAULT_OPP_5 (DVFSRC_BASE + 0x828)
|
||||||
|
#define DVFSRC_DEFAULT_OPP_6 (DVFSRC_BASE + 0x82C)
|
||||||
|
#define DVFSRC_DEFAULT_OPP_7 (DVFSRC_BASE + 0x830)
|
||||||
|
#define DVFSRC_DEFAULT_OPP_8 (DVFSRC_BASE + 0x834)
|
||||||
|
#define DVFSRC_LEVEL_MASK_SW_5 (DVFSRC_BASE + 0x838)
|
||||||
|
#define DVFSRC_LEVEL_MASK_SW_6 (DVFSRC_BASE + 0x83C)
|
||||||
|
#define DVFSRC_LEVEL_MASK_SW_7 (DVFSRC_BASE + 0x840)
|
||||||
|
#define DVFSRC_LEVEL_MASK_SW_8 (DVFSRC_BASE + 0x844)
|
||||||
|
#define DVFSRC_TARGET_LEVEL_SPM_5 (DVFSRC_BASE + 0x848)
|
||||||
|
#define DVFSRC_TARGET_LEVEL_SPM_6 (DVFSRC_BASE + 0x84C)
|
||||||
|
#define DVFSRC_TARGET_LEVEL_SPM_7 (DVFSRC_BASE + 0x850)
|
||||||
|
#define DVFSRC_TARGET_LEVEL_SPM_8 (DVFSRC_BASE + 0x854)
|
||||||
|
#define DVFSRC_CURRENT_LEVEL_5 (DVFSRC_BASE + 0x858)
|
||||||
|
#define DVFSRC_CURRENT_LEVEL_6 (DVFSRC_BASE + 0x85C)
|
||||||
|
#define DVFSRC_CURRENT_LEVEL_7 (DVFSRC_BASE + 0x860)
|
||||||
|
#define DVFSRC_CURRENT_LEVEL_8 (DVFSRC_BASE + 0x864)
|
||||||
|
#define DVFSRC_TARGET_LEVEL_5 (DVFSRC_BASE + 0x868)
|
||||||
|
#define DVFSRC_TARGET_LEVEL_6 (DVFSRC_BASE + 0x86C)
|
||||||
|
#define DVFSRC_TARGET_LEVEL_7 (DVFSRC_BASE + 0x870)
|
||||||
|
#define DVFSRC_TARGET_LEVEL_8 (DVFSRC_BASE + 0x874)
|
||||||
|
#define DVFSRC_CURRENT_FORCE_5 (DVFSRC_BASE + 0x878)
|
||||||
|
#define DVFSRC_CURRENT_FORCE_6 (DVFSRC_BASE + 0x87C)
|
||||||
|
#define DVFSRC_CURRENT_FORCE_7 (DVFSRC_BASE + 0x880)
|
||||||
|
#define DVFSRC_CURRENT_FORCE_8 (DVFSRC_BASE + 0x884)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_11 (DVFSRC_BASE + 0x88C)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_12 (DVFSRC_BASE + 0x890)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_13 (DVFSRC_BASE + 0x894)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_14 (DVFSRC_BASE + 0x898)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_15 (DVFSRC_BASE + 0x89C)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_16 (DVFSRC_BASE + 0x8A0)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_17 (DVFSRC_BASE + 0x8A4)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_18 (DVFSRC_BASE + 0x8A8)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_19 (DVFSRC_BASE + 0x8AC)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_20 (DVFSRC_BASE + 0x8B0)
|
||||||
|
#define DVFSRC_HRT_REQ_MD_BW_21 (DVFSRC_BASE + 0x8B4)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_11 (DVFSRC_BASE + 0x8B8)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_12 (DVFSRC_BASE + 0x8BC)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_13 (DVFSRC_BASE + 0x8C0)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_14 (DVFSRC_BASE + 0x8C4)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_15 (DVFSRC_BASE + 0x8C8)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_16 (DVFSRC_BASE + 0x8CC)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_17 (DVFSRC_BASE + 0x8D0)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_18 (DVFSRC_BASE + 0x8D4)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_19 (DVFSRC_BASE + 0x8D8)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_20 (DVFSRC_BASE + 0x8DC)
|
||||||
|
#define DVFSRC_HRT1_REQ_MD_BW_21 (DVFSRC_BASE + 0x8E0)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMI4 (DVFSRC_BASE + 0x904)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMI5 (DVFSRC_BASE + 0x908)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMI6 (DVFSRC_BASE + 0x90C)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMI7 (DVFSRC_BASE + 0x910)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMI4_T (DVFSRC_BASE + 0x914)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMI5_T (DVFSRC_BASE + 0x918)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMI6_T (DVFSRC_BASE + 0x91C)
|
||||||
|
#define DVFSRC_95MD_SCEN_EMI7_T (DVFSRC_BASE + 0x920)
|
||||||
|
#define DVFSRC_95MD_SCEN_BW4 (DVFSRC_BASE + 0x924)
|
||||||
|
#define DVFSRC_95MD_SCEN_BW5 (DVFSRC_BASE + 0x928)
|
||||||
|
#define DVFSRC_95MD_SCEN_BW6 (DVFSRC_BASE + 0x92C)
|
||||||
|
#define DVFSRC_95MD_SCEN_BW7 (DVFSRC_BASE + 0x930)
|
||||||
|
#define DVFSRC_95MD_SCEN_BW4_T (DVFSRC_BASE + 0x934)
|
||||||
|
#define DVFSRC_95MD_SCEN_BW5_T (DVFSRC_BASE + 0x938)
|
||||||
|
#define DVFSRC_95MD_SCEN_BW6_T (DVFSRC_BASE + 0x93C)
|
||||||
|
#define DVFSRC_95MD_SCEN_BW7_T (DVFSRC_BASE + 0x940)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_128_129 (DVFSRC_BASE + 0x944)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_130_131 (DVFSRC_BASE + 0x948)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_132_133 (DVFSRC_BASE + 0x94C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_134_135 (DVFSRC_BASE + 0x950)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_136_137 (DVFSRC_BASE + 0x954)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_138_139 (DVFSRC_BASE + 0x958)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_140_141 (DVFSRC_BASE + 0x95C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_142_143 (DVFSRC_BASE + 0x960)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_144_145 (DVFSRC_BASE + 0x964)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_146_147 (DVFSRC_BASE + 0x968)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_148_149 (DVFSRC_BASE + 0x96C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_150_151 (DVFSRC_BASE + 0x970)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_152_153 (DVFSRC_BASE + 0x974)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_154_155 (DVFSRC_BASE + 0x978)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_156_157 (DVFSRC_BASE + 0x97C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_158_159 (DVFSRC_BASE + 0x980)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_160_161 (DVFSRC_BASE + 0x984)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_162_163 (DVFSRC_BASE + 0x988)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_164_165 (DVFSRC_BASE + 0x98C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_166_167 (DVFSRC_BASE + 0x990)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_168_169 (DVFSRC_BASE + 0x994)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_170_171 (DVFSRC_BASE + 0x998)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_172_173 (DVFSRC_BASE + 0x99C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_174_175 (DVFSRC_BASE + 0x9A0)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_176_177 (DVFSRC_BASE + 0x9A4)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_178_179 (DVFSRC_BASE + 0x9A8)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_180_181 (DVFSRC_BASE + 0x9AC)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_182_183 (DVFSRC_BASE + 0x9B0)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_184_185 (DVFSRC_BASE + 0x9B4)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_186_187 (DVFSRC_BASE + 0x9B8)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_188_189 (DVFSRC_BASE + 0x9BC)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_190_191 (DVFSRC_BASE + 0x9C0)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_192_193 (DVFSRC_BASE + 0x9C4)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_194_195 (DVFSRC_BASE + 0x9C8)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_196_197 (DVFSRC_BASE + 0x9CC)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_198_199 (DVFSRC_BASE + 0x9D0)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_200_201 (DVFSRC_BASE + 0x9D4)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_202_203 (DVFSRC_BASE + 0x9D8)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_204_205 (DVFSRC_BASE + 0x9DC)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_206_207 (DVFSRC_BASE + 0x9E0)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_208_209 (DVFSRC_BASE + 0x9E4)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_210_211 (DVFSRC_BASE + 0x9E8)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_212_213 (DVFSRC_BASE + 0x9EC)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_214_215 (DVFSRC_BASE + 0x9F0)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_216_217 (DVFSRC_BASE + 0x9F4)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_218_219 (DVFSRC_BASE + 0x9F8)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_220_221 (DVFSRC_BASE + 0x9FC)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_222_223 (DVFSRC_BASE + 0xA00)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_224_225 (DVFSRC_BASE + 0xA04)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_226_227 (DVFSRC_BASE + 0xA08)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_228_229 (DVFSRC_BASE + 0xA0C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_230_231 (DVFSRC_BASE + 0xA10)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_232_233 (DVFSRC_BASE + 0xA14)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_234_235 (DVFSRC_BASE + 0xA18)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_236_237 (DVFSRC_BASE + 0xA1C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_238_239 (DVFSRC_BASE + 0xA20)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_240_241 (DVFSRC_BASE + 0xA24)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_242_243 (DVFSRC_BASE + 0xA28)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_244_245 (DVFSRC_BASE + 0xA2C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_246_247 (DVFSRC_BASE + 0xA30)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_248_249 (DVFSRC_BASE + 0xA34)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_250_251 (DVFSRC_BASE + 0xA38)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_252_253 (DVFSRC_BASE + 0xA3C)
|
||||||
|
#define DVFSRC_LEVEL_LABEL_254_255 (DVFSRC_BASE + 0xA40)
|
||||||
|
#define DVFSRC_HRT_HIGH_15 (DVFSRC_BASE + 0xA44)
|
||||||
|
#define DVFSRC_HRT_HIGH_14 (DVFSRC_BASE + 0xA48)
|
||||||
|
#define DVFSRC_HRT_HIGH_13 (DVFSRC_BASE + 0xA4C)
|
||||||
|
#define DVFSRC_HRT_HIGH_12 (DVFSRC_BASE + 0xA50)
|
||||||
|
#define DVFSRC_HRT_HIGH_11 (DVFSRC_BASE + 0xA54)
|
||||||
|
#define DVFSRC_HRT_HIGH_10 (DVFSRC_BASE + 0xA58)
|
||||||
|
#define DVFSRC_HRT_HIGH_9 (DVFSRC_BASE + 0xA5C)
|
||||||
|
#define DVFSRC_HRT_HIGH_8 (DVFSRC_BASE + 0xA60)
|
||||||
|
#define DVFSRC_HRT_LOW_15 (DVFSRC_BASE + 0xA64)
|
||||||
|
#define DVFSRC_HRT_LOW_14 (DVFSRC_BASE + 0xA68)
|
||||||
|
#define DVFSRC_HRT_LOW_13 (DVFSRC_BASE + 0xA6C)
|
||||||
|
#define DVFSRC_HRT_LOW_12 (DVFSRC_BASE + 0xA70)
|
||||||
|
#define DVFSRC_HRT_LOW_11 (DVFSRC_BASE + 0xA74)
|
||||||
|
#define DVFSRC_HRT_LOW_10 (DVFSRC_BASE + 0xA78)
|
||||||
|
#define DVFSRC_HRT_LOW_9 (DVFSRC_BASE + 0xA7C)
|
||||||
|
#define DVFSRC_HRT_LOW_8 (DVFSRC_BASE + 0xA80)
|
||||||
|
#define DVFSRC_DDR_QOS11 (DVFSRC_BASE + 0xA84)
|
||||||
|
#define DVFSRC_DDR_QOS12 (DVFSRC_BASE + 0xA88)
|
||||||
|
#define DVFSRC_DDR_QOS13 (DVFSRC_BASE + 0xA8C)
|
||||||
|
#define DVFSRC_DDR_QOS14 (DVFSRC_BASE + 0xA90)
|
||||||
|
#define DVFSRC_DDR_QOS15 (DVFSRC_BASE + 0xA94)
|
||||||
|
#define DVFSRC_EMI_QOS11 (DVFSRC_BASE + 0xA98)
|
||||||
|
#define DVFSRC_EMI_QOS12 (DVFSRC_BASE + 0xA9C)
|
||||||
|
#define DVFSRC_EMI_QOS13 (DVFSRC_BASE + 0xAA0)
|
||||||
|
#define DVFSRC_EMI_QOS14 (DVFSRC_BASE + 0xAA4)
|
||||||
|
#define DVFSRC_EMI_QOS15 (DVFSRC_BASE + 0xAA8)
|
||||||
|
#define DVFSRC_TARGET_REQ_MASK BIT(16)
|
||||||
|
#define DVFSRC_EN_MASK 1
|
||||||
|
#endif /* MT_SPM_VCOREFS_REG_6991_H */
|
463
plat/mediatek/drivers/spm/mt8196/mt_vcore_dvfsrc_plat.c
Normal file
463
plat/mediatek/drivers/spm/mt8196/mt_vcore_dvfsrc_plat.c
Normal file
|
@ -0,0 +1,463 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <common/debug.h>
|
||||||
|
#include <drivers/delay_timer.h>
|
||||||
|
#include <lib/mmio.h>
|
||||||
|
|
||||||
|
#include <drivers/dbgtop.h>
|
||||||
|
#include <drivers/dramc.h>
|
||||||
|
#include <drivers/spmi/spmi_common.h>
|
||||||
|
#include <drivers/spmi_api.h>
|
||||||
|
#include <drivers/sramrc.h>
|
||||||
|
#include <lib/mtk_init/mtk_init.h>
|
||||||
|
#include <mt_plat_spm_setting.h>
|
||||||
|
#include <mt_spm.h>
|
||||||
|
#include <mt_spm_reg.h>
|
||||||
|
#include <mt_spm_vcorefs.h>
|
||||||
|
#include <mt_spm_vcorefs_common.h>
|
||||||
|
#include <mt_spm_vcorefs_ext.h>
|
||||||
|
#include <mt_spm_vcorefs_reg.h>
|
||||||
|
#include <mt_vcore_dvfsrc_plat_def.h>
|
||||||
|
#include <mtk_mmap_pool.h>
|
||||||
|
#include <mtk_sip_svc.h>
|
||||||
|
#include <pmic_wrap/inc/mt_spm_pmic_wrap.h>
|
||||||
|
#include <sleep_def.h>
|
||||||
|
|
||||||
|
#define VCORE_SPM_INIT_PCM_FLAG (SPM_FLAG_RUN_COMMON_SCENARIO | \
|
||||||
|
SPM_FLAG_DISABLE_VLP_PDN)
|
||||||
|
|
||||||
|
#define V_VB_EN BIT(5)
|
||||||
|
#define V_DRM_ENABLE BIT(31)
|
||||||
|
#define V_B0_EN_SHIFT BIT(23)
|
||||||
|
|
||||||
|
#define V_VMODE_SHIFT 0
|
||||||
|
#define V_VMODE_MASK 0x3
|
||||||
|
#define V_OPP_TYPE_SHIFT 20
|
||||||
|
#define V_OPP_TYPE_SHIFT_MASK 0x3
|
||||||
|
|
||||||
|
#define DVFSRC_DISABLE_DVS 0x1
|
||||||
|
#define DVFSRC_DISABLE_DFS 0x2
|
||||||
|
|
||||||
|
#define CFG_DVFSRC_BW_ASYM_ENABLE
|
||||||
|
|
||||||
|
#ifdef MT8196_VCORE_SUPPORT
|
||||||
|
#define VCORE_MAX_OPP 6
|
||||||
|
#define DRAM_MAX_OPP 11
|
||||||
|
|
||||||
|
#define VCORE_OPP0_UV 850000
|
||||||
|
#define VCORE_OPP1_UV 750000
|
||||||
|
#define VCORE_OPP2_UV 675000
|
||||||
|
#define VCORE_OPP3_UV 625000
|
||||||
|
#define VCORE_OPP4_UV 600000
|
||||||
|
|
||||||
|
static unsigned int v_opp_uv[VCORE_MAX_OPP] = {
|
||||||
|
VCORE_OPP0_UV,
|
||||||
|
VCORE_OPP0_UV,
|
||||||
|
VCORE_OPP1_UV,
|
||||||
|
VCORE_OPP2_UV,
|
||||||
|
VCORE_OPP3_UV,
|
||||||
|
VCORE_OPP4_UV
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define VCORE_MAX_OPP 6
|
||||||
|
#define DRAM_MAX_OPP 11
|
||||||
|
|
||||||
|
#define VCORE_OPP0_UV 875000
|
||||||
|
#define VCORE_OPP1_UV 825000
|
||||||
|
#define VCORE_OPP2_UV 725000
|
||||||
|
#define VCORE_OPP3_UV 650000
|
||||||
|
#define VCORE_OPP4_UV 600000
|
||||||
|
#define VCORE_OPP5_UV 575000
|
||||||
|
|
||||||
|
static unsigned int v_opp_uv[VCORE_MAX_OPP] = {
|
||||||
|
VCORE_OPP0_UV,
|
||||||
|
VCORE_OPP1_UV,
|
||||||
|
VCORE_OPP2_UV,
|
||||||
|
VCORE_OPP3_UV,
|
||||||
|
VCORE_OPP4_UV,
|
||||||
|
VCORE_OPP5_UV,
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned int v_opp_df_uv[VCORE_MAX_OPP] = {
|
||||||
|
VCORE_OPP0_UV,
|
||||||
|
VCORE_OPP1_UV,
|
||||||
|
VCORE_OPP2_UV,
|
||||||
|
VCORE_OPP3_UV,
|
||||||
|
VCORE_OPP4_UV,
|
||||||
|
VCORE_OPP5_UV,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_MTK_VCOREDVFS_SUPPORT
|
||||||
|
static int opp_type;
|
||||||
|
static unsigned int b0_en;
|
||||||
|
|
||||||
|
static unsigned int v_roundup(unsigned int x, unsigned int y)
|
||||||
|
{
|
||||||
|
return round_up(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int v_rounddown(unsigned int x, unsigned int y)
|
||||||
|
{
|
||||||
|
return round_down(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void spm_vcorefs_pwarp_cmd(uint64_t cmd, uint64_t val)
|
||||||
|
{
|
||||||
|
if (cmd < NR_IDX_ALL)
|
||||||
|
mt_spm_pmic_wrap_set_cmd(PMIC_WRAP_PHASE_ALLINONE, cmd, val);
|
||||||
|
else
|
||||||
|
INFO("cmd out of range!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dvfsrc_init(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
static int dvfs_enable_done;
|
||||||
|
|
||||||
|
if (dvfs_enable_done)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(dvfsrc_init_configs); i++)
|
||||||
|
mmio_write_32(dvfsrc_init_configs[i].offset,
|
||||||
|
dvfsrc_init_configs[i].val);
|
||||||
|
|
||||||
|
#ifdef MT8196_VCORE_SUPPORT
|
||||||
|
for (i = 0; i < ARRAY_SIZE(lp5_8533_init_configs_auto); i++)
|
||||||
|
mmio_write_32(lp5_8533_init_configs_auto[i].offset,
|
||||||
|
lp5_8533_init_configs_auto[i].val);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (opp_type == 2) {
|
||||||
|
for (i = 0; i < ARRAY_SIZE(lp5_7500_init_configs); i++)
|
||||||
|
mmio_write_32(lp5_7500_init_configs[i].offset,
|
||||||
|
lp5_7500_init_configs[i].val);
|
||||||
|
} else if (opp_type == 0) {
|
||||||
|
for (i = 0; i < ARRAY_SIZE(lp5_8533_init_configs); i++)
|
||||||
|
mmio_write_32(lp5_8533_init_configs[i].offset,
|
||||||
|
lp5_8533_init_configs[i].val);
|
||||||
|
} else if (opp_type == 3) {
|
||||||
|
for (i = 0; i < ARRAY_SIZE(lp5_10677_init_configs); i++)
|
||||||
|
mmio_write_32(lp5_10677_init_configs[i].offset,
|
||||||
|
lp5_10677_init_configs[i].val);
|
||||||
|
}
|
||||||
|
#ifdef CFG_DVFSRC_BW_ASYM_ENABLE
|
||||||
|
if (b0_en) {
|
||||||
|
mmio_write_32(DVFSRC_LEVEL_LABEL_210_211, 0x20100000);
|
||||||
|
mmio_write_32(DVFSRC_LEVEL_LABEL_212_213, 0x00504030);
|
||||||
|
mmio_write_32(DVFSRC_LEVEL_LABEL_220_221, 0x00400000);
|
||||||
|
mmio_write_32(DVFSRC_LEVEL_LABEL_224_225, 0x00000050);
|
||||||
|
mmio_write_32(DVFSRC_LEVEL_LABEL_226_227, 0x00300000);
|
||||||
|
mmio_write_32(DVFSRC_LEVEL_LABEL_252_253, 0x000040F5);
|
||||||
|
mmio_write_32(DVFSRC_LEVEL_LABEL_248_249, 0x30450000);
|
||||||
|
mmio_write_32(DVFSRC_LEVEL_LABEL_246_247, 0x00002065);
|
||||||
|
mmio_write_32(DVFSRC_LEVEL_LABEL_242_243, 0x10960000);
|
||||||
|
mmio_write_32(DVFSRC_LEVEL_LABEL_202_203, 0x00010040);
|
||||||
|
mmio_write_32(DVFSRC_LEVEL_LABEL_200_201, 0xE0420030);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mmio_write_32(DVFSRC_SW_REQ4, 0x00000030);
|
||||||
|
/* ENABLE */
|
||||||
|
mmio_write_32(DVFSRC_CURRENT_FORCE_4, 0x00000001);
|
||||||
|
#ifdef MT8196_VCORE_SUPPORT
|
||||||
|
mmio_write_32(DVFSRC_BASIC_CONTROL, 0xD460213B);
|
||||||
|
mmio_write_32(DVFSRC_BASIC_CONTROL, 0xD46001BB);
|
||||||
|
#else
|
||||||
|
mmio_write_32(DVFSRC_BASIC_CONTROL, 0xD560213B);
|
||||||
|
mmio_write_32(DVFSRC_BASIC_CONTROL, 0xD56001BB);
|
||||||
|
#endif
|
||||||
|
mmio_write_32(DVFSRC_CURRENT_FORCE_4, 0x00000000);
|
||||||
|
|
||||||
|
#ifdef CONFIG_MTK_DBGTOP
|
||||||
|
mtk_dbgtop_cfg_dvfsrc(1);
|
||||||
|
#endif
|
||||||
|
dvfs_enable_done = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void spm_vcorefs_vcore_setting(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint32_t dvfs_v_mode, dvfsrc_rsrv;
|
||||||
|
#ifndef MT8196_VCORE_SUPPORT
|
||||||
|
uint32_t rsrv0, rsrv1;
|
||||||
|
|
||||||
|
rsrv0 = mmio_read_32(DVFSRC_RSRV_0);
|
||||||
|
rsrv1 = mmio_read_32(DVFSRC_RSRV_1);
|
||||||
|
#endif
|
||||||
|
dvfsrc_rsrv = mmio_read_32(DVFSRC_RSRV_4);
|
||||||
|
dvfs_v_mode = (dvfsrc_rsrv >> V_VMODE_SHIFT) & V_VMODE_MASK;
|
||||||
|
|
||||||
|
if (dvfs_v_mode == 3) { /* LV */
|
||||||
|
for (i = 0; i < VCORE_MAX_OPP; i++)
|
||||||
|
v_opp_uv[i] =
|
||||||
|
v_rounddown((v_opp_uv[i] * 95) / 100,
|
||||||
|
VCORE_STEP_UV);
|
||||||
|
} else if (dvfs_v_mode == 1) { /* HV */
|
||||||
|
for (i = 0; i < VCORE_MAX_OPP; i++)
|
||||||
|
v_opp_uv[i] =
|
||||||
|
v_roundup((v_opp_uv[i] * 105) / 100,
|
||||||
|
VCORE_STEP_UV);
|
||||||
|
}
|
||||||
|
#ifndef MT8196_VCORE_SUPPORT
|
||||||
|
else if (dvfsrc_rsrv & V_VB_EN) { /* NV & AVS1.0 */
|
||||||
|
v_opp_uv[5] = VCORE_PMIC_TO_UV(((rsrv1 >> 24) & 0xFF) + 7);
|
||||||
|
v_opp_uv[4] = VCORE_PMIC_TO_UV(((rsrv1 >> 16) & 0xFF) + 5);
|
||||||
|
v_opp_uv[3] = VCORE_PMIC_TO_UV(((rsrv1 >> 8) & 0xFF) + 4);
|
||||||
|
v_opp_uv[2] = VCORE_PMIC_TO_UV(((rsrv0 >> 24) & 0xFF) + 4);
|
||||||
|
v_opp_uv[1] = VCORE_PMIC_TO_UV(((rsrv0 >> 16) & 0xFF) + 3);
|
||||||
|
v_opp_uv[0] = VCORE_PMIC_TO_UV((rsrv0 & 0xFF) + 3);
|
||||||
|
for (i = 0; i < VCORE_MAX_OPP; i++)
|
||||||
|
v_opp_uv[i] = v_min(v_opp_uv[i], v_opp_df_uv[i]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef MT8196_VCORE_SUPPORT
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_0, VCORE_UV_TO_PMIC(v_opp_uv[5]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_1, VCORE_UV_TO_PMIC(v_opp_uv[5]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_2, VCORE_UV_TO_PMIC(v_opp_uv[4]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_3, VCORE_UV_TO_PMIC(v_opp_uv[3]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_4, VCORE_UV_TO_PMIC(v_opp_uv[2]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_5, VCORE_UV_TO_PMIC(v_opp_uv[2]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_6, VCORE_UV_TO_PMIC(v_opp_uv[1]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_7, VCORE_UV_TO_PMIC(v_opp_uv[1]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_8, VCORE_UV_TO_PMIC(v_opp_uv[0]));
|
||||||
|
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_9, VCORE_UV_TO_PMIC(v_opp_uv[5]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_10, VCORE_UV_TO_PMIC(v_opp_uv[4]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_11, VCORE_UV_TO_PMIC(v_opp_uv[3]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_12, VCORE_UV_TO_PMIC(v_opp_uv[2]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_13, VCORE_UV_TO_PMIC(v_opp_uv[1]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_14, VCORE_UV_TO_PMIC(v_opp_uv[0]));
|
||||||
|
#else
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_9, VCORE_UV_TO_PMIC(v_opp_uv[5]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_10, VCORE_UV_TO_PMIC(v_opp_uv[4]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_11, VCORE_UV_TO_PMIC(v_opp_uv[3]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_12, VCORE_UV_TO_PMIC(v_opp_uv[2]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_13, VCORE_UV_TO_PMIC(v_opp_uv[1]));
|
||||||
|
spm_vcorefs_pwarp_cmd(CMD_14, VCORE_UV_TO_PMIC(v_opp_uv[0]));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_vcorefs_plat_init(uint32_t dvfsrc_flag,
|
||||||
|
uint32_t dvfsrc_vmode, uint32_t *dram_type)
|
||||||
|
{
|
||||||
|
uint64_t spm_flags = VCORE_SPM_INIT_PCM_FLAG;
|
||||||
|
uint32_t dvfsrc_rsrv = 0;
|
||||||
|
|
||||||
|
if (mmio_read_32(MD32PCM_PC) == 0)
|
||||||
|
return MTK_SIP_E_NOT_SUPPORTED;
|
||||||
|
/* set high opp */
|
||||||
|
mmio_write_32(DVFSRC_SW_BW_9, 0x3FF);
|
||||||
|
spm_dvfsfw_init(0, 0);
|
||||||
|
spm_vcorefs_vcore_setting();
|
||||||
|
dvfsrc_rsrv = mmio_read_32(DVFSRC_RSRV_4);
|
||||||
|
opp_type = (dvfsrc_rsrv >> V_OPP_TYPE_SHIFT) & V_OPP_TYPE_SHIFT_MASK;
|
||||||
|
b0_en = dvfsrc_rsrv & V_B0_EN_SHIFT;
|
||||||
|
|
||||||
|
if (dvfsrc_flag & DVFSRC_DISABLE_DVS)
|
||||||
|
spm_flags |= SPM_FLAG_DISABLE_VCORE_DVS;
|
||||||
|
|
||||||
|
if (dvfsrc_flag & DVFSRC_DISABLE_DFS) {
|
||||||
|
spm_flags |= (SPM_FLAG_DISABLE_DDR_DFS |
|
||||||
|
SPM_FLAG_DISABLE_EMI_DFS |
|
||||||
|
SPM_FLAG_DISABLE_BUS_DFS);
|
||||||
|
mmio_write_32(DVFSRC_SW_BW_8, 0x3FF);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dvfsrc_rsrv & V_DRM_ENABLE) {
|
||||||
|
spm_flags |= (SPM_FLAG_DISABLE_VCORE_DVS |
|
||||||
|
SPM_FLAG_DISABLE_DDR_DFS |
|
||||||
|
SPM_FLAG_DISABLE_EMI_DFS |
|
||||||
|
SPM_FLAG_DISABLE_BUS_DFS);
|
||||||
|
return MTK_SIP_E_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
spm_go_to_vcorefs(spm_flags);
|
||||||
|
dvfsrc_init();
|
||||||
|
*dram_type = 0;
|
||||||
|
|
||||||
|
return VCOREFS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_vcorefs_plat_kick(void)
|
||||||
|
{
|
||||||
|
/* release high opp if not in drm mode*/
|
||||||
|
if (!(mmio_read_32(DVFSRC_RSRV_4) & V_DRM_ENABLE))
|
||||||
|
mmio_write_32(DVFSRC_SW_BW_9, 0);
|
||||||
|
|
||||||
|
mmio_write_32(DVFSRC_AVS_RETRY, 1);
|
||||||
|
mmio_write_32(DVFSRC_AVS_RETRY, 0);
|
||||||
|
|
||||||
|
return VCOREFS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spm_vcorefs_plat_suspend(void)
|
||||||
|
{
|
||||||
|
mmio_write_32(DVFSRC_MD_TURBO, 0x1FFF0000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void spm_vcorefs_plat_resume(void)
|
||||||
|
{
|
||||||
|
mmio_write_32(DVFSRC_MD_TURBO, 0x00000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
int spm_vcorefs_plat_kick(void)
|
||||||
|
{
|
||||||
|
return MTK_SIP_E_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_vcorefs_plat_init(uint32_t dvfsrc_flag,
|
||||||
|
uint32_t dvfsrc_vmode, uint32_t *dram_type)
|
||||||
|
{
|
||||||
|
return MTK_SIP_E_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spm_vcorefs_plat_suspend(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void spm_vcorefs_plat_resume(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int spm_vcorefs_get_vcore_uv(uint32_t gear, uint32_t *val)
|
||||||
|
{
|
||||||
|
if (gear < VCORE_MAX_OPP)
|
||||||
|
*val = v_opp_uv[VCORE_MAX_OPP - gear - 1];
|
||||||
|
else
|
||||||
|
*val = 0;
|
||||||
|
|
||||||
|
return VCOREFS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_vcorefs_get_dram_freq(uint32_t gear, uint32_t *val)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_MTK_DRAMC
|
||||||
|
if (gear < DRAM_MAX_OPP)
|
||||||
|
*val = get_dram_step_freq((DRAM_MAX_OPP - gear - 1)) * 1000;
|
||||||
|
else
|
||||||
|
*val = 0;
|
||||||
|
#else
|
||||||
|
*val = 0;
|
||||||
|
#endif
|
||||||
|
return VCOREFS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_vcorefs_get_vcore_opp_num(uint32_t *val)
|
||||||
|
{
|
||||||
|
*val = VCORE_MAX_OPP;
|
||||||
|
|
||||||
|
return VCOREFS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_vcorefs_get_dram_opp_num(uint32_t *val)
|
||||||
|
{
|
||||||
|
*val = DRAM_MAX_OPP;
|
||||||
|
|
||||||
|
return VCOREFS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_vcorefs_get_opp_type(uint32_t *val)
|
||||||
|
{
|
||||||
|
*val = 0;
|
||||||
|
|
||||||
|
return VCOREFS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_vcorefs_get_fw_type(uint32_t *val)
|
||||||
|
{
|
||||||
|
*val = 0;
|
||||||
|
|
||||||
|
return VCOREFS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_vcorefs_get_vcore_info(uint32_t idx, uint32_t *data)
|
||||||
|
{
|
||||||
|
if (idx == 0)
|
||||||
|
*data = mmio_read_32(VCORE_VB_INFO0);
|
||||||
|
else if (idx == 1)
|
||||||
|
*data = mmio_read_32(VCORE_VB_INFO1);
|
||||||
|
else if (idx == 2)
|
||||||
|
*data = mmio_read_32(VCORE_VB_INFO2);
|
||||||
|
else
|
||||||
|
*data = 0;
|
||||||
|
|
||||||
|
return VCOREFS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MMPC_FLAG 0x3333
|
||||||
|
int spm_vcorefs_qos_mode(uint32_t data)
|
||||||
|
{
|
||||||
|
#ifdef CFG_DVFSRC_BW_ASYM_ENABLE
|
||||||
|
uint32_t mode, value;
|
||||||
|
bool mm_flag;
|
||||||
|
|
||||||
|
mm_flag = (mmio_read_32(DVFSRC_VCORE_QOS7) == 0xFFFFFE);
|
||||||
|
mode = data >> 16;
|
||||||
|
|
||||||
|
if ((mode == 0x3333) && b0_en && mm_flag) {
|
||||||
|
value = data & 0xFFFF;
|
||||||
|
if (value == 1)
|
||||||
|
mmio_write_32(DVFSRC_QOS_EN, 0x00F3007C);
|
||||||
|
else
|
||||||
|
mmio_write_32(DVFSRC_QOS_EN, 0x20F1007C);
|
||||||
|
return VCOREFS_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return MTK_SIP_E_NOT_SUPPORTED;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_vcorefs_pause_enable(uint32_t enable)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_MTK_DBGTOP
|
||||||
|
mtk_dbgtop_dfd_pause_dvfsrc(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return VCOREFS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MTK_VCORE_DVFS_RES_MEM
|
||||||
|
static int vcorefs_rsc_ctrl(unsigned int rsc, bool hold)
|
||||||
|
{
|
||||||
|
static struct mt_lp_resource_user vcorefs_res_user;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (!vcorefs_res_user.uid) {
|
||||||
|
ret = mt_lp_resource_user_register("VCOREFS",
|
||||||
|
&vcorefs_res_user);
|
||||||
|
if (ret) {
|
||||||
|
WARN("%s: register lp resource failed", __func__);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hold)
|
||||||
|
ret = vcorefs_res_user.request(&vcorefs_res_user, rsc);
|
||||||
|
else
|
||||||
|
ret = vcorefs_res_user.release(&vcorefs_res_user);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
WARN("%s: RSC_%d %s failed",
|
||||||
|
__func__, rsc, hold ? "req" : "rel");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spm_vcorefs_rsc_mem_req(bool request)
|
||||||
|
{
|
||||||
|
vcorefs_rsc_ctrl(MT_LP_RQ_DRAM, request);
|
||||||
|
|
||||||
|
return VCOREFS_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
245
plat/mediatek/drivers/spm/mt8196/mt_vcore_dvfsrc_plat_def.h
Normal file
245
plat/mediatek/drivers/spm/mt8196/mt_vcore_dvfsrc_plat_def.h
Normal file
|
@ -0,0 +1,245 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_VCORE_DVFSRC_PLAT_DEF_H
|
||||||
|
#define MT_VCORE_DVFSRC_PLAT_DEF_H
|
||||||
|
|
||||||
|
#include <lib/utils_def.h>
|
||||||
|
|
||||||
|
#ifdef MT8196_VCORE_SUPPORT
|
||||||
|
#define VCORE_BASE_UV 0
|
||||||
|
#define VCORE_STEP_UV 6250
|
||||||
|
|
||||||
|
/* PMIC */
|
||||||
|
#define VCORE_PMIC_TO_UV(pmic) \
|
||||||
|
(((pmic) * VCORE_STEP_UV) + VCORE_BASE_UV)
|
||||||
|
#define VCORE_UV_TO_PMIC(uv) /* pmic >= uv */ \
|
||||||
|
((((uv) - VCORE_BASE_UV) + (VCORE_STEP_UV - 1)) / VCORE_STEP_UV)
|
||||||
|
#else
|
||||||
|
#define VCORE_BASE_UV 0
|
||||||
|
#define VCORE_STEP_UV 5000
|
||||||
|
|
||||||
|
/* PMIC */
|
||||||
|
#define VCORE_PMIC_TO_UV(pmic) \
|
||||||
|
(((pmic) * VCORE_STEP_UV) + VCORE_BASE_UV)
|
||||||
|
#define VCORE_UV_TO_PMIC(uv) /* pmic >= uv */ \
|
||||||
|
((((uv) - VCORE_BASE_UV) + (VCORE_STEP_UV - 1)) / VCORE_STEP_UV)
|
||||||
|
|
||||||
|
#ifndef v_min
|
||||||
|
#define v_min(a, b) MIN(a, b)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef v_max
|
||||||
|
#define v_max(a, b) MAZ(a, b)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define VCORE_VB_INFO0 (EFUSEC_BASE + 0xD24)
|
||||||
|
#define VCORE_VB_INFO1 (EFUSEC_BASE + 0xD28)
|
||||||
|
#define VCORE_VB_INFO2 (EFUSEC_BASE + 0xD84)
|
||||||
|
|
||||||
|
static const struct reg_config dvfsrc_init_configs[] = {
|
||||||
|
{ DVFSRC_TIMEOUT_NEXTREQ, 0x00001AFF },
|
||||||
|
{ DVFSRC_VCORE_USER_REQ, 0x00010F51 },
|
||||||
|
{ DVFSRC_BW_USER_REQ, 0x00010033 },
|
||||||
|
/* EMI MONITOR */
|
||||||
|
{ DVFSRC_DDR_REQUEST3, 0x44444321 },
|
||||||
|
{ DVFSRC_DDR_REQUEST10, 0x44444321 },
|
||||||
|
/* SW QOS */
|
||||||
|
{ DVFSRC_QOS_EN, 0x20F1007C },
|
||||||
|
{ DVFSRC_DDR_QOS0, 0x0000004B },
|
||||||
|
{ DVFSRC_DDR_QOS1, 0x0000009A },
|
||||||
|
{ DVFSRC_DDR_QOS2, 0x000000CE },
|
||||||
|
{ DVFSRC_DDR_QOS3, 0x00000134 },
|
||||||
|
{ DVFSRC_DDR_QOS4, 0x00000185 },
|
||||||
|
{ DVFSRC_DDR_QOS5, 0x000001F9 },
|
||||||
|
{ DVFSRC_DDR_QOS6, 0x0000024C },
|
||||||
|
{ DVFSRC_DDR_QOS7, 0x000002B4 },
|
||||||
|
{ DVFSRC_DDR_QOS8, 0x00000354 },
|
||||||
|
{ DVFSRC_DDR_REQUEST5, 0x87654321 },
|
||||||
|
{ DVFSRC_DDR_REQUEST8, 0x00000009 },
|
||||||
|
/* LEVEL */
|
||||||
|
{ DVFSRC_LEVEL_LABEL_0_1, 0x9055A055 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_2_3, 0x80458055 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_4_5, 0x70558044 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_6_7, 0x70447045 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_8_9, 0x60456055 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_10_11, 0x60446035 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_12_13, 0x60336034 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_14_15, 0x50455055 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_16_17, 0x50445035 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_18_19, 0x50335034 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_20_21, 0x40454055 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_22_23, 0x40254035 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_24_25, 0x40344044 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_26_27, 0x40334024 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_28_29, 0x40224023 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_30_31, 0x30453055 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_32_33, 0x30253035 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_34_35, 0x30443015 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_36_37, 0x30243034 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_38_39, 0x30333014 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_40_41, 0x30133023 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_42_43, 0x30123022 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_44_45, 0x20553011 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_46_47, 0x20352045 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_48_49, 0x20152025 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_50_51, 0x20442005 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_52_53, 0x20242034 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_54_55, 0x20042014 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_56_57, 0x20232033 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_58_59, 0x20032013 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_60_61, 0x20122022 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_62_63, 0x20112002 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_64_65, 0x20002001 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_66_67, 0x10451055 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_68_69, 0x10251035 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_70_71, 0x10051015 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_72_73, 0x10341044 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_74_75, 0x10141024 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_76_77, 0x10331004 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_78_79, 0x10131023 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_80_81, 0x10221003 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_82_83, 0x10021012 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_84_85, 0x10011011 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_86_87, 0x00001000 },
|
||||||
|
/* HRT */
|
||||||
|
{ DVFSRC_PMQOS_HRT_UNIT_SW_BW, 0x00000120 },
|
||||||
|
{ DVFSRC_ISP_HRT_UNIT_SW_BW, 0x0000010F },
|
||||||
|
{ DVFSRC_MD_HRT_UNIT_SW_BW, 0x0000010F },
|
||||||
|
{ DVFSRC_HRT_BASE_HRT_UNIT_SW_BW, 0x0000010F },
|
||||||
|
{ DVFSRC_HRT_REQUEST, 0x87654321 },
|
||||||
|
{ DVFSRC_HRT_REQUEST_1, 0x00000009 },
|
||||||
|
{ DVFSRC_HRT_HIGH, 0x000006A8 },
|
||||||
|
{ DVFSRC_HRT_HIGH_1, 0x00000DD7 },
|
||||||
|
{ DVFSRC_HRT_HIGH_2, 0x000012A8 },
|
||||||
|
{ DVFSRC_HRT_HIGH_3, 0x00001C0B },
|
||||||
|
{ DVFSRC_HRT_HIGH_4, 0x00002644 },
|
||||||
|
{ DVFSRC_HRT_HIGH_5, 0x000031AC },
|
||||||
|
{ DVFSRC_HRT_HIGH_6, 0x000039FD },
|
||||||
|
{ DVFSRC_HRT_HIGH_7, 0x00004435 },
|
||||||
|
{ DVFSRC_HRT_HIGH_8, 0x000053B6 },
|
||||||
|
{ DVFSRC_HRT_LOW, 0x000006A7 },
|
||||||
|
{ DVFSRC_HRT_LOW_1, 0x00000DD7 },
|
||||||
|
{ DVFSRC_HRT_LOW_2, 0x000012A8 },
|
||||||
|
{ DVFSRC_HRT_LOW_3, 0x00001C0B },
|
||||||
|
{ DVFSRC_HRT_LOW_4, 0x00002643 },
|
||||||
|
{ DVFSRC_HRT_LOW_5, 0x000031AB },
|
||||||
|
{ DVFSRC_HRT_LOW_6, 0x000039FD },
|
||||||
|
{ DVFSRC_HRT_LOW_7, 0x00004435 },
|
||||||
|
{ DVFSRC_HRT_LOW_8, 0x000053B6 },
|
||||||
|
/* MDDDR */
|
||||||
|
{ DVFSRC_HRT_REQ_MD_URG, 0x003FF3FF },
|
||||||
|
{ DVFSRC_95MD_SCEN_BW7, 0x90000000 },
|
||||||
|
{ DVFSRC_95MD_SCEN_BW7_T, 0x90000000 },
|
||||||
|
{ DVFSRC_95MD_SCEN_BWU, 0x00000009 },
|
||||||
|
{ DVFSRC_MD_LATENCY_IMPROVE, 0x00000021 },
|
||||||
|
{ DVFSRC_DEBOUNCE_TIME, 0x0000179E },
|
||||||
|
/* RISING */
|
||||||
|
{ DVFSRC_DDR_ADD_REQUEST, 0x76543210 },
|
||||||
|
{ DVFSRC_DDR_ADD_REQUEST_1, 0x99999998 },
|
||||||
|
{ DVFSRC_EMI_MON_DEBOUNCE_TIME, 0x4C2D0000 },
|
||||||
|
/* MISC */
|
||||||
|
{ DVFSRC_DEFAULT_OPP_1, 0x00000000 },
|
||||||
|
{ DVFSRC_DEFAULT_OPP_2, 0x00000000 },
|
||||||
|
{ DVFSRC_DEFAULT_OPP_3, 0x00000000 },
|
||||||
|
{ DVFSRC_DEFAULT_OPP_4, 0x00000000 },
|
||||||
|
{ DVFSRC_DEFAULT_OPP_5, 0x00000000 },
|
||||||
|
{ DVFSRC_DEFAULT_OPP_6, 0x00000000 },
|
||||||
|
{ DVFSRC_DEFAULT_OPP_7, 0x00000000 },
|
||||||
|
{ DVFSRC_DEFAULT_OPP_8, 0x00000001 },
|
||||||
|
{ DVFSRC_BASIC_CONTROL_4, 0x0000020F },
|
||||||
|
{ DVFSRC_INT_EN, 0x00000002 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct reg_config lp5_7500_init_configs[] = {
|
||||||
|
/* SW QOS */
|
||||||
|
{ DVFSRC_DDR_REQUEST5, 0x77654321 },
|
||||||
|
{ DVFSRC_DDR_REQUEST8, 0x00000007 },
|
||||||
|
/* HRT */
|
||||||
|
{ DVFSRC_HRT_REQUEST, 0x77654321 },
|
||||||
|
{ DVFSRC_HRT_REQUEST_1, 0x00000007 },
|
||||||
|
/* MDDDR */
|
||||||
|
{ DVFSRC_95MD_SCEN_BW7, 0x70000000 },
|
||||||
|
{ DVFSRC_95MD_SCEN_BW7_T, 0x70000000 },
|
||||||
|
{ DVFSRC_95MD_SCEN_BWU, 0x00000007 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct reg_config lp5_8533_init_configs[] = {
|
||||||
|
/* SW QOS */
|
||||||
|
{ DVFSRC_DDR_REQUEST5, 0x87654321 },
|
||||||
|
{ DVFSRC_DDR_REQUEST8, 0x00000008 },
|
||||||
|
/* HRT */
|
||||||
|
{ DVFSRC_HRT_REQUEST, 0x87654321 },
|
||||||
|
{ DVFSRC_HRT_REQUEST_1, 0x00000008 },
|
||||||
|
/* MDDDR */
|
||||||
|
{ DVFSRC_95MD_SCEN_BW7, 0x80000000 },
|
||||||
|
{ DVFSRC_95MD_SCEN_BW7_T, 0x80000000 },
|
||||||
|
{ DVFSRC_95MD_SCEN_BWU, 0x00000008 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct reg_config lp5_10677_init_configs[] = {
|
||||||
|
/* SW QOS */
|
||||||
|
{ DVFSRC_DDR_QOS9, 0x000003C0 },
|
||||||
|
{ DVFSRC_DDR_REQUEST5, 0x87654321 },
|
||||||
|
{ DVFSRC_DDR_REQUEST8, 0x000000A9 },
|
||||||
|
/* HRT */
|
||||||
|
{ DVFSRC_HRT_HIGH_9, 0x00005E80 },
|
||||||
|
{ DVFSRC_HRT_LOW_9, 0x00005E7F },
|
||||||
|
{ DVFSRC_HRT_REQUEST, 0x87654321 },
|
||||||
|
{ DVFSRC_HRT_REQUEST_1, 0x000000A9 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct reg_config lp5_8533_init_configs_auto[] = {
|
||||||
|
|
||||||
|
/* LEVEL */
|
||||||
|
{ DVFSRC_LEVEL_LABEL_0_1, 0x80449045 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_2_3, 0x70448044 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_4_5, 0x60346044 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_6_7, 0x50446033 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_8_9, 0x50335034 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_10_11, 0x40344044 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_12_13, 0x40334024 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_14_15, 0x40224023 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_16_17, 0x30343044 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_18_19, 0x30143024 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_20_21, 0x30233033 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_22_23, 0x30223013 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_24_25, 0x30113012 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_26_27, 0x20342044 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_28_29, 0x20142024 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_30_31, 0x20332004 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_32_33, 0x20132023 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_34_35, 0x20222003 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_36_37, 0x20022012 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_38_39, 0x20012011 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_40_41, 0x10442000 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_42_43, 0x10241034 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_44_45, 0x10041014 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_46_47, 0x10231033 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_48_49, 0x10031013 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_50_51, 0x10121022 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_52_53, 0x10111002 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_54_55, 0x10001001 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_56_57, 0x10341044 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_58_59, 0x10141024 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_60_61, 0x10331004 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_62_63, 0x10131023 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_64_65, 0x10221003 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_66_67, 0x10021012 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_68_69, 0x10011011 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_70_71, 0x00001000 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_72_73, 0x00000000 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_74_75, 0x00000000 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_76_77, 0x00000000 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_78_79, 0x00000000 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_80_81, 0x00000000 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_82_83, 0x00000000 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_84_85, 0x00000000 },
|
||||||
|
{ DVFSRC_LEVEL_LABEL_86_87, 0x00000000 },
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* MT_VCORE_DVFSRC_PLAT_DEF_H */
|
209
plat/mediatek/drivers/spm/mt8196/pcm_def.h
Normal file
209
plat/mediatek/drivers/spm/mt8196/pcm_def.h
Normal file
|
@ -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 */
|
117
plat/mediatek/drivers/spm/mt8196/plat_conf.mk
Normal file
117
plat/mediatek/drivers/spm/mt8196/plat_conf.mk
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
#
|
||||||
|
|
||||||
|
NOTIFIER_VER := v4
|
||||||
|
|
||||||
|
PMIC_WRAP_VER := v1
|
||||||
|
|
||||||
|
MTK_SPM_COMMON_DRV := y
|
||||||
|
|
||||||
|
# Enable or disable spm feature
|
||||||
|
MT_SPM_FEATURE_SUPPORT := y
|
||||||
|
|
||||||
|
# Enable or disable cirq restore
|
||||||
|
MT_SPM_CIRQ_FEATURE_SUPPORT := y
|
||||||
|
|
||||||
|
# Enable or disable get dram type from dramc
|
||||||
|
MT_SPMFW_LOAD_BY_DRAM_TYPE := n
|
||||||
|
|
||||||
|
# Enable or disable sspm sram
|
||||||
|
MT_SPMFW_SPM_SRAM_SLEEP_SUPPORT := n
|
||||||
|
|
||||||
|
# Enable or disable uart save/restore at tf-a spm driver
|
||||||
|
# mt8196 uart is restore by RTFF
|
||||||
|
MT_SPM_UART_SUSPEND_SUPPORT := n
|
||||||
|
|
||||||
|
# Enable or disable pmic wrap reg dump
|
||||||
|
MT_SPM_PMIC_WRAP_DUMP_SUPPORT := n
|
||||||
|
|
||||||
|
# spm timestamp support
|
||||||
|
MT_SPM_TIMESTAMP_SUPPORT := n
|
||||||
|
|
||||||
|
MTK_SPM_PMIC_LP_SUPPORT := y
|
||||||
|
|
||||||
|
MTK_SPM_LVTS_SUPPORT := FIXME
|
||||||
|
|
||||||
|
MT_SPM_COMMON_SODI_SUPPORT := n
|
||||||
|
|
||||||
|
#spm emi thermal threshold control
|
||||||
|
MT_SPM_EMI_THERMAL_CONTROL_SUPPORT := FIXME
|
||||||
|
|
||||||
|
# spm rgu workaround
|
||||||
|
MT_SPM_RGU_WA := y
|
||||||
|
|
||||||
|
CONSTRAINT_ID_ALL := 0xff
|
||||||
|
$(eval $(call add_defined_option,CONSTRAINT_ID_ALL))
|
||||||
|
|
||||||
|
ifneq (${PMIC_GS_DUMP_VER},)
|
||||||
|
$(eval $(call add_define,MTK_SPM_PMIC_GS_DUMP))
|
||||||
|
$(eval $(call add_define,MTK_SPM_PMIC_GS_DUMP_SUSPEND))
|
||||||
|
$(eval $(call add_define,MTK_SPM_PMIC_GS_DUMP_SODI3))
|
||||||
|
$(eval $(call add_define,MTK_SPM_PMIC_GS_DUMP_DPIDLE))
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (${MT_SPM_FEATURE_SUPPORT},n)
|
||||||
|
$(eval $(call add_define,MTK_PLAT_SPM_UNSUPPORT))
|
||||||
|
else
|
||||||
|
$(eval $(call add_define,MT_SPM_FEATURE_SUPPORT))
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (${MT_SPMFW_LOAD_BY_DRAM_TYPE},n)
|
||||||
|
$(eval $(call add_define,MTK_PLAT_DRAMC_UNSUPPORT))
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (${MT_SPM_CIRQ_FEATURE_SUPPORT},n)
|
||||||
|
$(eval $(call add_define,MTK_PLAT_CIRQ_UNSUPPORT))
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (${MT_SPMFW_SPM_SRAM_SLEEP_SUPPORT},n)
|
||||||
|
$(eval $(call add_define,MTK_PLAT_SPM_SRAM_SLP_UNSUPPORT))
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (${NOTIFIER_VER},)
|
||||||
|
$(eval $(call add_define,MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT))
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (${MT_SPM_UART_SUSPEND_SUPPORT},n)
|
||||||
|
$(eval $(call add_define,MTK_PLAT_SPM_UART_UNSUPPORT))
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (${MT_SPM_PMIC_WRAP_DUMP_SUPPORT},n)
|
||||||
|
$(eval $(call add_define,MTK_PLAT_SPM_PMIC_WRAP_DUMP_UNSUPPORT))
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (${TRACER_VER},)
|
||||||
|
$(eval $(call add_define,MTK_PLAT_SPM_TRACE_UNSUPPORT))
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (${MT_SPM_TIMESTAMP_SUPPORT},y)
|
||||||
|
$(eval $(call add_define,MT_SPM_TIMESTAMP_SUPPORT))
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(MTK_VOLTAGE_BIN_VCORE),y)
|
||||||
|
$(eval $(call add_define,MTK_VOLTAGE_BIN_VCORE_SUPPORT))
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (${MTK_SPM_PMIC_LP_SUPPORT},y)
|
||||||
|
$(eval $(call add_define,MTK_SPM_PMIC_LP_SUPPORT))
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (${MTK_SPM_LVTS_SUPPORT},y)
|
||||||
|
$(eval $(call add_define,MTK_SPM_LVTS_SUPPORT))
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (${MT_SPM_COMMON_SODI_SUPPORT},y)
|
||||||
|
$(eval $(call add_define,MT_SPM_COMMON_SODI_SUPPORT))
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (${MT_SPM_EMI_THERMAL_CONTROL_SUPPORT},y)
|
||||||
|
$(eval $(call add_define,MT_SPM_EMI_THERMAL_CONTROL_SUPPORT))
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (${MT_SPM_RGU_WA},y)
|
||||||
|
$(eval $(call add_define,MT_SPM_RGU_WA))
|
||||||
|
endif
|
37
plat/mediatek/drivers/spm/mt8196/rules.mk
Normal file
37
plat/mediatek/drivers/spm/mt8196/rules.mk
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#
|
||||||
|
# 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_${MTK_SOC}
|
||||||
|
|
||||||
|
#Add your source code here
|
||||||
|
|
||||||
|
LOCAL_SRCS-${CONFIG_MTK_SPM_SUPPORT} := ${LOCAL_DIR}/mt_spm.c
|
||||||
|
LOCAL_SRCS-${CONFIG_MTK_SPM_SUPPORT} += ${LOCAL_DIR}/mt_spm_conservation.c
|
||||||
|
LOCAL_SRCS-${CONFIG_MTK_SPM_SUPPORT} += ${LOCAL_DIR}/mt_spm_internal.c
|
||||||
|
LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/mt_plat_spm_setting.c
|
||||||
|
LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/mt_spm_dispatcher.c
|
||||||
|
LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/mt_spm_idle.c
|
||||||
|
LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/mt_spm_suspend.c
|
||||||
|
LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/mt_spm_stats.c
|
||||||
|
LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/constraints/mt_spm_rc_api.c
|
||||||
|
LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/constraints/mt_spm_rc_bus26m.c
|
||||||
|
LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/constraints/mt_spm_rc_vcore.c
|
||||||
|
LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/constraints/mt_spm_rc_syspll.c
|
||||||
|
LOCAL_SRCS-${MTK_SPM_PMIC_LP_SUPPORT} += ${LOCAL_DIR}/mt_spm_pmic_lp.c
|
||||||
|
LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/mt_spm_hwreq.c
|
||||||
|
LOCAL_SRCS-${CONFIG_MTK_VCOREDVFS_SUPPORT} += ${LOCAL_DIR}/mt_spm_vcorefs.c
|
||||||
|
LOCAL_SRCS-${CONFIG_MTK_VCOREDVFS_SUPPORT} += ${LOCAL_DIR}/mt_vcore_dvfsrc_plat.c
|
||||||
|
|
||||||
|
#Epilogue, build as module
|
||||||
|
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
|
||||||
|
$(eval $(call add_defined_option,CONFIG_MTK_VCOREDVFS_SUPPORT))
|
||||||
|
$(eval $(call add_defined_option,CONFIG_MTK_VCOREDVFS_LK_SUPPORT))
|
||||||
|
$(eval $(call add_defined_option,CONFIG_MTK_VCOREDVFS_PLAT_CMD))
|
||||||
|
$(eval $(call add_defined_option,MTK_VCORE_DVFS_PAUSE))
|
147
plat/mediatek/drivers/spm/mt8196/sleep_def.h
Normal file
147
plat/mediatek/drivers/spm/mt8196/sleep_def.h
Normal file
|
@ -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 */
|
57
plat/mediatek/drivers/spm/mt_spm_vcorefs_common.h
Normal file
57
plat/mediatek/drivers/spm/mt_spm_vcorefs_common.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_SPM_VCOREFS_COMMON_H
|
||||||
|
#define MT_SPM_VCOREFS_COMMON_H
|
||||||
|
|
||||||
|
#include <lib/utils_def.h>
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* DVFSRC Function Return Value & Other Macro Definition
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
#define VCOREFS_SUCCESS 0
|
||||||
|
#define VCOREFS_E_NOT_SUPPORTED -1
|
||||||
|
#define VCOREFS_E_SPMFW_NOT_READY 0
|
||||||
|
|
||||||
|
#define TAG "vcorefs: "
|
||||||
|
#define v_min(a, b) MAX(a, b)
|
||||||
|
#define v_max(a, b) MIN(a, b)
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* VCOREFS CMD
|
||||||
|
*
|
||||||
|
********************************************************************/
|
||||||
|
enum vcorefs_smc_cmd {
|
||||||
|
VCOREFS_SMC_VCORE_DVFS_INIT = 0,
|
||||||
|
VCOREFS_SMC_VCORE_DVFS_KICK = 1,
|
||||||
|
VCOREFS_SMC_CMD_OPP_TYPE = 2,
|
||||||
|
VCOREFS_SMC_CMD_FW_TYPE = 3,
|
||||||
|
VCOREFS_SMC_CMD_GET_UV = 4,
|
||||||
|
VCOREFS_SMC_CMD_GET_FREQ = 5,
|
||||||
|
VCOREFS_SMC_CMD_GET_NUM_V = 6,
|
||||||
|
VCOREFS_SMC_CMD_GET_NUM_F = 7,
|
||||||
|
|
||||||
|
/*chip specific setting */
|
||||||
|
VCOREFS_SMC_CMD_GET_VCORE_INFO = 18,
|
||||||
|
|
||||||
|
/*qos specific setting */
|
||||||
|
VCOREFS_SMC_CMD_QOS_MODE = 32,
|
||||||
|
VCOREFS_SMC_CMD_PAUSE_ENABLE = 33,
|
||||||
|
|
||||||
|
/*spm resource request */
|
||||||
|
VCOREFS_SMC_RSC_MEM_REQ = 64,
|
||||||
|
VCOREFS_SMC_RSC_MEM_REL = 65,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct reg_config {
|
||||||
|
uint32_t offset;
|
||||||
|
uint32_t val;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* MT_SPM_VCOREFS_COMMON_H */
|
25
plat/mediatek/drivers/spm/mt_spm_vcorefs_exp.h
Normal file
25
plat/mediatek/drivers/spm/mt_spm_vcorefs_exp.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_SPM_VCOREFS_EXP_H
|
||||||
|
#define MT_SPM_VCOREFS_EXP_H
|
||||||
|
|
||||||
|
int spm_vcorefs_plat_init(uint32_t dvfsrc_flag,
|
||||||
|
uint32_t dvfsrc_vmode, uint32_t *dram_type);
|
||||||
|
int spm_vcorefs_plat_kick(void);
|
||||||
|
int spm_vcorefs_get_opp_type(uint32_t *val);
|
||||||
|
int spm_vcorefs_get_fw_type(uint32_t *val);
|
||||||
|
int spm_vcorefs_get_dram_freq(uint32_t gear, uint32_t *freq);
|
||||||
|
int spm_vcorefs_get_vcore_opp_num(uint32_t *val);
|
||||||
|
int spm_vcorefs_get_dram_opp_num(uint32_t *val);
|
||||||
|
int spm_vcorefs_get_vcore_info(uint32_t idx, uint32_t *val);
|
||||||
|
int spm_vcorefs_qos_mode(uint32_t mode);
|
||||||
|
int spm_vcorefs_pause_enable(uint32_t enable);
|
||||||
|
void spm_vcorefs_plat_suspend(void);
|
||||||
|
void spm_vcorefs_plat_resume(void);
|
||||||
|
void dvfsrc_md_ddr_turbo(int is_turbo);
|
||||||
|
|
||||||
|
#endif /* MT_SPM_VCOREFS_EXP_H */
|
115
plat/mediatek/drivers/spm/mt_spm_vcorefs_smc.c
Normal file
115
plat/mediatek/drivers/spm/mt_spm_vcorefs_smc.c
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <common/debug.h>
|
||||||
|
|
||||||
|
#include <drivers/spm/mt_spm_vcorefs_api.h>
|
||||||
|
#include <mt_spm_vcorefs_common.h>
|
||||||
|
#include <mt_spm_vcorefs_exp.h>
|
||||||
|
#include <mt_spm_vcorefs_ext.h>
|
||||||
|
#include <mtk_sip_svc.h>
|
||||||
|
|
||||||
|
static u_register_t mtk_vcorefs_handler(u_register_t x1,
|
||||||
|
u_register_t x2,
|
||||||
|
u_register_t x3,
|
||||||
|
u_register_t x4,
|
||||||
|
void *handle,
|
||||||
|
struct smccc_res *smccc_ret)
|
||||||
|
{
|
||||||
|
uint64_t ret = VCOREFS_E_NOT_SUPPORTED;
|
||||||
|
uint64_t cmd = x1;
|
||||||
|
uint32_t val = 0;
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case VCOREFS_SMC_VCORE_DVFS_INIT:
|
||||||
|
ret = spm_vcorefs_plat_init(x2, x3, &val);
|
||||||
|
smccc_ret->a1 = val;
|
||||||
|
break;
|
||||||
|
case VCOREFS_SMC_VCORE_DVFS_KICK:
|
||||||
|
ret = spm_vcorefs_plat_kick();
|
||||||
|
break;
|
||||||
|
case VCOREFS_SMC_CMD_OPP_TYPE:
|
||||||
|
ret = spm_vcorefs_get_opp_type(&val);
|
||||||
|
smccc_ret->a1 = val;
|
||||||
|
break;
|
||||||
|
case VCOREFS_SMC_CMD_FW_TYPE:
|
||||||
|
ret = spm_vcorefs_get_fw_type(&val);
|
||||||
|
smccc_ret->a1 = val;
|
||||||
|
break;
|
||||||
|
case VCOREFS_SMC_CMD_GET_UV:
|
||||||
|
ret = spm_vcorefs_get_vcore_uv(x2, &val);
|
||||||
|
smccc_ret->a1 = val;
|
||||||
|
break;
|
||||||
|
case VCOREFS_SMC_CMD_GET_FREQ:
|
||||||
|
ret = spm_vcorefs_get_dram_freq(x2, &val);
|
||||||
|
smccc_ret->a1 = val;
|
||||||
|
break;
|
||||||
|
case VCOREFS_SMC_CMD_GET_NUM_V:
|
||||||
|
ret = spm_vcorefs_get_vcore_opp_num(&val);
|
||||||
|
smccc_ret->a1 = val;
|
||||||
|
break;
|
||||||
|
case VCOREFS_SMC_CMD_GET_NUM_F:
|
||||||
|
ret = spm_vcorefs_get_dram_opp_num(&val);
|
||||||
|
smccc_ret->a1 = val;
|
||||||
|
break;
|
||||||
|
case VCOREFS_SMC_CMD_GET_VCORE_INFO:
|
||||||
|
ret = spm_vcorefs_get_vcore_info(x2, &val);
|
||||||
|
smccc_ret->a1 = val;
|
||||||
|
break;
|
||||||
|
case VCOREFS_SMC_CMD_QOS_MODE:
|
||||||
|
ret = spm_vcorefs_qos_mode(x2);
|
||||||
|
break;
|
||||||
|
#ifdef MTK_VCORE_DVFS_PAUSE
|
||||||
|
case VCOREFS_SMC_CMD_PAUSE_ENABLE:
|
||||||
|
ret = spm_vcorefs_pause_enable(x2);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef MTK_VCORE_DVFS_RES_MEM
|
||||||
|
case VCOREFS_SMC_RSC_MEM_REQ:
|
||||||
|
ret = spm_vcorefs_rsc_mem_req(true);
|
||||||
|
break;
|
||||||
|
case VCOREFS_SMC_RSC_MEM_REL:
|
||||||
|
ret = spm_vcorefs_rsc_mem_req(false);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_SMC_HANDLER(MTK_SIP_VCORE_CONTROL, mtk_vcorefs_handler);
|
||||||
|
|
||||||
|
#ifdef CONFIG_MTK_VCOREDVFS_LK_SUPPORT
|
||||||
|
static u_register_t mtk_vcorefs_bl_handler(u_register_t x1,
|
||||||
|
u_register_t x2,
|
||||||
|
u_register_t x3,
|
||||||
|
u_register_t x4,
|
||||||
|
void *handle,
|
||||||
|
struct smccc_res *smccc_ret)
|
||||||
|
{
|
||||||
|
uint64_t = VCOREFS_E_NOT_SUPPORTED;
|
||||||
|
uint32_t val = 0;
|
||||||
|
|
||||||
|
switch (x1) {
|
||||||
|
case VCOREFS_SMC_VCORE_DVFS_INIT:
|
||||||
|
ret = spm_vcorefs_plat_init(x2, x3, &val);
|
||||||
|
smccc_ret->a1 = val;
|
||||||
|
break;
|
||||||
|
case VCOREFS_SMC_VCORE_DVFS_KICK:
|
||||||
|
ret = spm_vcorefs_plat_kick();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_SMC_HANDLER(MTK_SIP_BL_SPM_VCOREFS_CONTROL, mtk_vcorefs_bl_handler);
|
||||||
|
#endif
|
|
@ -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
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
#
|
#
|
||||||
|
@ -7,8 +7,6 @@
|
||||||
LOCAL_DIR := $(call GET_LOCAL_DIR)
|
LOCAL_DIR := $(call GET_LOCAL_DIR)
|
||||||
MODULE := spm
|
MODULE := spm
|
||||||
|
|
||||||
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
|
|
||||||
|
|
||||||
ifneq ($(CONFIG_MTK_SPM_VERSION),)
|
ifneq ($(CONFIG_MTK_SPM_VERSION),)
|
||||||
PLAT_INCLUDES += -I${LOCAL_DIR}/$(MTK_SOC)
|
PLAT_INCLUDES += -I${LOCAL_DIR}/$(MTK_SOC)
|
||||||
PLAT_INCLUDES += -I${LOCAL_DIR}/version/notifier/inc
|
PLAT_INCLUDES += -I${LOCAL_DIR}/version/notifier/inc
|
||||||
|
@ -17,4 +15,36 @@ SUB_RULES-y += ${LOCAL_DIR}/$(CONFIG_MTK_SPM_VERSION)
|
||||||
$(eval $(call add_define,SPM_PLAT_IMPL))
|
$(eval $(call add_define,SPM_PLAT_IMPL))
|
||||||
endif
|
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
|
||||||
|
|
||||||
|
LOCAL_SRCS-${CONFIG_MTK_VCOREDVFS_SUPPORT} += ${LOCAL_DIR}/mt_spm_vcorefs_smc.c
|
||||||
|
|
||||||
|
$(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)))
|
$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
|
||||||
|
|
74
plat/mediatek/drivers/spm/version/inc/mt_spm_ver.h
Normal file
74
plat/mediatek/drivers/spm/version/inc/mt_spm_ver.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_SPM_VER_H
|
||||||
|
#define MT_SPM_VER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
enum mt_plat_dram_to_spm_type {
|
||||||
|
SPMFW_DEFAULT_TYPE = 0,
|
||||||
|
SPMFW_LP4_2CH_3200,
|
||||||
|
SPMFW_LP4X_2CH_3600,
|
||||||
|
SPMFW_LP3_1CH_1866,
|
||||||
|
SPMFW_LP4X_2CH_3733,
|
||||||
|
SPMFW_LP4X_2CH_4266,
|
||||||
|
SPMFW_LP4X_2CH_3200,
|
||||||
|
SPMFW_LP5_2CH_6400,
|
||||||
|
SPMFW_LP5X_4CH_7500,
|
||||||
|
SPMFW_TYPE_NOT_FOUND,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum pwrctrl_selection {
|
||||||
|
SPM_INIT_PWRCTRL = 0,
|
||||||
|
SPM_VCOREDVFS_PWRCTRL,
|
||||||
|
SPM_IDLE_PWRCTRL,
|
||||||
|
SPM_SUSPEND_PWRCTRL,
|
||||||
|
SPM_PWRCTRL_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pcm_desc {
|
||||||
|
const char *version; /* PCM code version */
|
||||||
|
uint32_t *base; /* Binary array base */
|
||||||
|
uintptr_t base_dma; /* DMA addr of base */
|
||||||
|
uint32_t pmem_words;
|
||||||
|
uint32_t total_words;
|
||||||
|
uint32_t pmem_start;
|
||||||
|
uint32_t dmem_start;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DYNA_LOAD_PCM_PATH_SIZE 128
|
||||||
|
#define PCM_FIRMWARE_VERSION_SIZE 128
|
||||||
|
|
||||||
|
struct dyna_load_pcm_t {
|
||||||
|
char path[DYNA_LOAD_PCM_PATH_SIZE];
|
||||||
|
char version[PCM_FIRMWARE_VERSION_SIZE];
|
||||||
|
char *buf;
|
||||||
|
struct pcm_desc desc;
|
||||||
|
int ready;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct load_pcm_fw_t {
|
||||||
|
unsigned int fw_max_num;
|
||||||
|
char **pcm_name_str;
|
||||||
|
struct dyna_load_pcm_t *dyna_load_pcm;
|
||||||
|
unsigned int (*is_fw_running)(void);
|
||||||
|
unsigned int (*get_fw_index)(unsigned int fw_type);
|
||||||
|
int (*fw_init)(struct pcm_desc *desc);
|
||||||
|
int (*fw_run)(unsigned int first, void *pwrctrl);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* SPM firmware restart definition */
|
||||||
|
#define SPM_FW_FORCE_RESET BIT(0)
|
||||||
|
#define SPM_FW_FORCE_RESUME BIT(1)
|
||||||
|
int spm_firmware_restart(unsigned int force, void *pwrctrl);
|
||||||
|
int spm_firmware_type_get(void);
|
||||||
|
void spm_firmware_type_probe(unsigned int type);
|
||||||
|
void spm_firmware_init(uint64_t addr, uint64_t size);
|
||||||
|
uint64_t spm_load_firmware_status(void);
|
||||||
|
void register_load_fw(struct load_pcm_fw_t *info);
|
||||||
|
|
||||||
|
#endif /* MT_SPM_VER_H */
|
|
@ -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
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -10,7 +10,9 @@
|
||||||
enum mt_spm_sspm_notify_id {
|
enum mt_spm_sspm_notify_id {
|
||||||
MT_SPM_NOTIFY_LP_ENTER = 0,
|
MT_SPM_NOTIFY_LP_ENTER = 0,
|
||||||
MT_SPM_NOTIFY_LP_LEAVE,
|
MT_SPM_NOTIFY_LP_LEAVE,
|
||||||
MT_SPM_NOTIFY_SUSPEND_VCORE_VOLTAGE,
|
MT_SPM_NOTIFY_SUSPEND_VCORE,
|
||||||
|
MT_SPM_NOTIFY_IDLE_ENTER,
|
||||||
|
MT_SPM_NOTIFY_IDLE_LEAVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT
|
#ifdef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_SPM_SSPM_INTC_H
|
||||||
|
#define MT_SPM_SSPM_INTC_H
|
||||||
|
|
||||||
|
#define MT_SPM_SSPM_INTC_SEL_0 0x10
|
||||||
|
#define MT_SPM_SSPM_INTC_SEL_1 0x20
|
||||||
|
#define MT_SPM_SSPM_INTC_SEL_2 0x40
|
||||||
|
#define MT_SPM_SSPM_INTC_SEL_3 0x80
|
||||||
|
|
||||||
|
#define MT_SPM_SSPM_INTC_TRIGGER(id, sg) \
|
||||||
|
(((0x10 << (id)) | ((sg) << (id))) & 0xFF)
|
||||||
|
|
||||||
|
#define SSPM_CFGREG_ADDR(ofs) (SSPM_CFGREG_BASE + (ofs))
|
||||||
|
#define AP_SSPM_IRQ SSPM_CFGREG_ADDR(0x018)
|
||||||
|
|
||||||
|
#define DO_SPM_SSPM_LP_NOTIFY() mmio_write_32(AP_SSPM_IRQ, 1)
|
||||||
|
|
||||||
|
#endif /* MT_SPM_SSPM_INTC_H */
|
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <lib/libc/errno.h>
|
||||||
|
|
||||||
|
#include <lib/mmio.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
#include <mtk_mmap_pool.h>
|
||||||
|
#include <notifier/inc/mt_spm_notifier.h>
|
||||||
|
#include <notifier/v4/mt_spm_sspm_intc.h>
|
||||||
|
|
||||||
|
#define MT_SPM_SSPM_MBOX_OFF(x) (SSPM_MBOX_3_BASE + x)
|
||||||
|
#define MT_SPM_MBOX(slot) MT_SPM_SSPM_MBOX_OFF((slot<<2UL))
|
||||||
|
|
||||||
|
/* LOOKUP SSPM_MBOX_SPM_LP1 */
|
||||||
|
#define SSPM_MBOX_SPM_LP_LOOKUP1 MT_SPM_MBOX(0)
|
||||||
|
/* LOOKUP SSPM_MBOX_SPM_LP2 */
|
||||||
|
#define SSPM_MBOX_SPM_LP_LOOKUP2 MT_SPM_MBOX(1)
|
||||||
|
#define SSPM_MBOX_SPM_LP1 MT_SPM_MBOX(2)
|
||||||
|
#define SSPM_MBOX_SPM_LP2 MT_SPM_MBOX(3)
|
||||||
|
#define SSPM_MBOX_SPM_SIZE 16
|
||||||
|
/* 4 mbox is in usage */
|
||||||
|
#define MT_SPM_MBOX_OFFSET(slot) MT_SPM_MBOX((slot + 4))
|
||||||
|
|
||||||
|
enum SSPM_SLEEP_CMD {
|
||||||
|
SLP_TASK_NONE = 0,
|
||||||
|
SLP_TASK_AP_SUSPEND,
|
||||||
|
SLP_TASK_AP_RESUME,
|
||||||
|
SLP_TASK_APSRC_OFF,
|
||||||
|
SLP_TASK_APSRC_ON,
|
||||||
|
SLP_TASK_INFRA_OFF,
|
||||||
|
SLP_TASK_INFRA_ON,
|
||||||
|
SLP_TASK_VCORE_OFF,
|
||||||
|
SLP_TASK_VCORE_ON,
|
||||||
|
SLP_TASK_IDLE_OFF,
|
||||||
|
SLP_TASK_IDLE_ON,
|
||||||
|
SLP_TASK_INFRA_noPERI_OFF,
|
||||||
|
SLP_TASK_INFRA_noPERI_ON,
|
||||||
|
SLP_TASK_ERR = 32,
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned int cur_mbox_index;
|
||||||
|
|
||||||
|
static int __mt_spm_is_available_index(int cur_idx)
|
||||||
|
{
|
||||||
|
unsigned int val;
|
||||||
|
|
||||||
|
val = mmio_read_32(MT_SPM_MBOX_OFFSET(cur_idx));
|
||||||
|
val = (val >> 30);
|
||||||
|
if (val == 0 || val == 3)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __mt_spm_get_available_index(void)
|
||||||
|
{
|
||||||
|
unsigned int idx = cur_mbox_index;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (i = 0 ; i < SSPM_MBOX_SPM_SIZE ; i++) {
|
||||||
|
if (__mt_spm_is_available_index(idx)) {
|
||||||
|
cur_mbox_index = (idx + 1) % SSPM_MBOX_SPM_SIZE;
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
idx = (idx + 1) % SSPM_MBOX_SPM_SIZE;
|
||||||
|
}
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __mt_spm_sspm_write_cmd_queue(int idx, int value)
|
||||||
|
{
|
||||||
|
unsigned int val;
|
||||||
|
|
||||||
|
val = mmio_read_32(MT_SPM_MBOX_OFFSET(idx));
|
||||||
|
val = val ^ BIT(31);
|
||||||
|
val = (value & 0x3fffffff) | (val & 0xc0000000);
|
||||||
|
|
||||||
|
mmio_write_32(MT_SPM_MBOX_OFFSET(idx), val);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt_spm_sspm_cmd_enqueue(int cmd)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
idx = __mt_spm_get_available_index();
|
||||||
|
|
||||||
|
/* Block when queue full */
|
||||||
|
if (idx == -EBUSY) {
|
||||||
|
while (!__mt_spm_is_available_index(cur_mbox_index))
|
||||||
|
;
|
||||||
|
idx = cur_mbox_index;
|
||||||
|
cur_mbox_index = (cur_mbox_index+1) % SSPM_MBOX_SPM_SIZE;
|
||||||
|
}
|
||||||
|
__mt_spm_sspm_write_cmd_queue(idx, cmd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_spm_sspm_notify_u32(int type, unsigned int val)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case MT_SPM_NOTIFY_LP_ENTER:
|
||||||
|
mmio_write_32(SSPM_MBOX_SPM_LP1, val);
|
||||||
|
mt_spm_sspm_cmd_enqueue(SLP_TASK_AP_SUSPEND);
|
||||||
|
DO_SPM_SSPM_LP_NOTIFY();
|
||||||
|
break;
|
||||||
|
case MT_SPM_NOTIFY_LP_LEAVE:
|
||||||
|
mmio_write_32(SSPM_MBOX_SPM_LP1, val);
|
||||||
|
mt_spm_sspm_cmd_enqueue(SLP_TASK_AP_RESUME);
|
||||||
|
DO_SPM_SSPM_LP_NOTIFY();
|
||||||
|
break;
|
||||||
|
case MT_SPM_NOTIFY_IDLE_ENTER:
|
||||||
|
mmio_write_32(SSPM_MBOX_SPM_LP1, val);
|
||||||
|
mt_spm_sspm_cmd_enqueue(SLP_TASK_IDLE_OFF);
|
||||||
|
DO_SPM_SSPM_LP_NOTIFY();
|
||||||
|
break;
|
||||||
|
case MT_SPM_NOTIFY_IDLE_LEAVE:
|
||||||
|
mmio_write_32(SSPM_MBOX_SPM_LP1, val);
|
||||||
|
mt_spm_sspm_cmd_enqueue(SLP_TASK_IDLE_ON);
|
||||||
|
DO_SPM_SSPM_LP_NOTIFY();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MT_SPM_PMIC_WRAP_H
|
||||||
|
#define MT_SPM_PMIC_WRAP_H
|
||||||
|
|
||||||
|
struct pmic_wrap_cmd_setting {
|
||||||
|
uint32_t spm_pwrap_addr;
|
||||||
|
uint32_t cmd_addr;
|
||||||
|
uint32_t cmd_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pmic_wrap_phase_setting {
|
||||||
|
struct pmic_wrap_cmd_setting *cmd;
|
||||||
|
unsigned int nr_idx;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pmic_wrap_setting {
|
||||||
|
struct pmic_wrap_phase_setting *phase;
|
||||||
|
const unsigned int phase_nr_idx;
|
||||||
|
};
|
||||||
|
|
||||||
|
int mt_spm_pmic_wrap_set_phase(unsigned int phase);
|
||||||
|
int mt_spm_pmic_wrap_set_cmd(unsigned int phase,
|
||||||
|
unsigned int idx, unsigned int cmd_data);
|
||||||
|
unsigned long mt_spm_pmic_wrap_get_cmd(unsigned int phase, unsigned int idx);
|
||||||
|
void mt_spm_pmic_wrap_set_table(struct pmic_wrap_setting *pw);
|
||||||
|
|
||||||
|
#endif /* MT_SPM_PMIC_WRAP_H */
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <lib/libc/errno.h>
|
||||||
|
|
||||||
|
#include <lib/mmio.h>
|
||||||
|
|
||||||
|
#include <pmic_wrap/inc/mt_spm_pmic_wrap.h>
|
||||||
|
|
||||||
|
#define SPM_DATA_SHIFT 16
|
||||||
|
|
||||||
|
static struct pmic_wrap_setting *pmic_wrap;
|
||||||
|
|
||||||
|
int mt_spm_pmic_wrap_set_phase(unsigned int phase)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
uint32_t cmd_addr, cmd_data;
|
||||||
|
struct pmic_wrap_phase_setting *current_phase;
|
||||||
|
|
||||||
|
if (!pmic_wrap)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (phase >= pmic_wrap->phase_nr_idx)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
current_phase = &pmic_wrap->phase[phase];
|
||||||
|
|
||||||
|
for (idx = 0; idx < current_phase->nr_idx; idx++) {
|
||||||
|
cmd_addr = current_phase->cmd[idx].cmd_addr;
|
||||||
|
cmd_data = current_phase->cmd[idx].cmd_data;
|
||||||
|
|
||||||
|
mmio_write_32(current_phase->cmd[idx].spm_pwrap_addr,
|
||||||
|
(cmd_addr << SPM_DATA_SHIFT) | cmd_data);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt_spm_pmic_wrap_set_cmd(unsigned int phase,
|
||||||
|
unsigned int idx, unsigned int cmd_data)
|
||||||
|
{
|
||||||
|
uint32_t cmd_addr;
|
||||||
|
struct pmic_wrap_phase_setting *current_phase;
|
||||||
|
|
||||||
|
if (!pmic_wrap)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (phase >= pmic_wrap->phase_nr_idx)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (idx >= pmic_wrap->phase[phase].nr_idx)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
current_phase = &pmic_wrap->phase[phase];
|
||||||
|
current_phase->cmd[idx].cmd_data = cmd_data;
|
||||||
|
cmd_addr = current_phase->cmd[idx].cmd_addr;
|
||||||
|
|
||||||
|
mmio_write_32(current_phase->cmd[idx].spm_pwrap_addr,
|
||||||
|
(cmd_addr << SPM_DATA_SHIFT) | cmd_data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long mt_spm_pmic_wrap_get_cmd(unsigned int phase, unsigned int idx)
|
||||||
|
{
|
||||||
|
if (!pmic_wrap)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (phase >= pmic_wrap->phase_nr_idx)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (idx >= pmic_wrap->phase[phase].nr_idx)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return pmic_wrap->phase[phase].cmd[idx].cmd_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt_spm_pmic_wrap_set_table(struct pmic_wrap_setting *pw)
|
||||||
|
{
|
||||||
|
pmic_wrap = pw;
|
||||||
|
}
|
23
plat/mediatek/drivers/spm/version/rules.mk
Normal file
23
plat/mediatek/drivers/spm/version/rules.mk
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
#
|
||||||
|
|
||||||
|
LOCAL_DIR := $(call GET_LOCAL_DIR)
|
||||||
|
|
||||||
|
MODULE := spm_version
|
||||||
|
|
||||||
|
LOCAL_SRCS-y :=
|
||||||
|
ifneq (${NOTIFIER_VER},)
|
||||||
|
LOCAL_SRCS-y += ${LOCAL_DIR}/notifier/${NOTIFIER_VER}/mt_spm_sspm_notifier.c
|
||||||
|
endif
|
||||||
|
ifneq (${PMIC_GS_DUMP_VER},)
|
||||||
|
LOCAL_SRCS-y += ${LOCAL_DIR}/pmic_gs/${PMIC_GS_DUMP_VER}/mt_spm_pmic_gs_dump.c
|
||||||
|
endif
|
||||||
|
ifneq (${PMIC_WRAP_VER},)
|
||||||
|
LOCAL_SRCS-y += ${LOCAL_DIR}/pmic_wrap/${PMIC_WRAP_VER}/mt_spm_pmic_wrap.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
|
||||||
|
$(eval $(call add_defined_option,CONFIG_MTK_VCOREDVFS_SUPPORT))
|
290
plat/mediatek/drivers/spmi/mt8196/platform_pmif_spmi.c
Normal file
290
plat/mediatek/drivers/spmi/mt8196/platform_pmif_spmi.c
Normal file
|
@ -0,0 +1,290 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <lib/utils_def.h>
|
||||||
|
|
||||||
|
#include <drivers/spmi/pmif_common.h>
|
||||||
|
#include <drivers/spmi/pmif_v1/pmif.h>
|
||||||
|
#include <drivers/spmi/spmi_common.h>
|
||||||
|
#include <drivers/spmi/spmi_sw.h>
|
||||||
|
#include <drivers/spmi_api.h>
|
||||||
|
#include <lib/mtk_init/mtk_init.h>
|
||||||
|
#include <mtk_mmap_pool.h>
|
||||||
|
|
||||||
|
#define SPMI_GROUP_ID 0xB
|
||||||
|
#define SPMI_DEBUG 0
|
||||||
|
|
||||||
|
static const mmap_region_t pmif_spmi_mmap[] MTK_MMAP_SECTION = {
|
||||||
|
MAP_REGION_FLAT(PMIF_SPMI_M_BASE, PMIF_SPMI_SIZE,
|
||||||
|
MT_DEVICE | MT_RW | MT_NS),
|
||||||
|
MAP_REGION_FLAT(SPMI_MST_M_BASE, SPMI_MST_SIZE,
|
||||||
|
MT_DEVICE | MT_RW | MT_SECURE),
|
||||||
|
MAP_REGION_FLAT(PMIF_SPMI_P_BASE, PMIF_SPMI_SIZE,
|
||||||
|
MT_DEVICE | MT_RW | MT_NS),
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
DECLARE_MTK_MMAP_REGIONS(pmif_spmi_mmap);
|
||||||
|
|
||||||
|
static uint16_t mt6xxx_spmi_regs[] = {
|
||||||
|
[SPMI_OP_ST_CTRL] = 0x0000,
|
||||||
|
[SPMI_GRP_ID_EN] = 0x0004,
|
||||||
|
[SPMI_OP_ST_STA] = 0x0008,
|
||||||
|
[SPMI_MST_SAMPL] = 0x000C,
|
||||||
|
[SPMI_MST_REQ_EN] = 0x0010,
|
||||||
|
[SPMI_RCS_CTRL] = 0x0014,
|
||||||
|
[SPMI_SLV_3_0_EINT] = 0x0020,
|
||||||
|
[SPMI_SLV_7_4_EINT] = 0x0024,
|
||||||
|
[SPMI_SLV_B_8_EINT] = 0x0028,
|
||||||
|
[SPMI_SLV_F_C_EINT] = 0x002C,
|
||||||
|
[SPMI_REC_CTRL] = 0x0040,
|
||||||
|
[SPMI_REC0] = 0x0044,
|
||||||
|
[SPMI_REC1] = 0x0048,
|
||||||
|
[SPMI_REC2] = 0x004C,
|
||||||
|
[SPMI_REC3] = 0x0050,
|
||||||
|
[SPMI_REC4] = 0x0054,
|
||||||
|
[SPMI_REC_CMD_DEC] = 0x005C,
|
||||||
|
[SPMI_DEC_DBG] = 0x00F8,
|
||||||
|
[SPMI_MST_DBG] = 0x00FC,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t mt6xxx_regs[] = {
|
||||||
|
[PMIF_INIT_DONE] = 0x0000,
|
||||||
|
[PMIF_INF_EN] = 0x0024,
|
||||||
|
[PMIF_ARB_EN] = 0x0150,
|
||||||
|
[PMIF_IRQ_EVENT_EN_0] = 0x0420,
|
||||||
|
[PMIF_IRQ_FLAG_0] = 0x0428,
|
||||||
|
[PMIF_IRQ_CLR_0] = 0x042C,
|
||||||
|
[PMIF_IRQ_EVENT_EN_2] = 0x0440,
|
||||||
|
[PMIF_IRQ_FLAG_2] = 0x0448,
|
||||||
|
[PMIF_IRQ_CLR_2] = 0x044C,
|
||||||
|
[PMIF_WDT_CTRL] = 0x0470,
|
||||||
|
[PMIF_WDT_EVENT_EN_1] = 0x047C,
|
||||||
|
[PMIF_WDT_FLAG_1] = 0x0480,
|
||||||
|
[PMIF_SWINF_2_ACC] = 0x0880,
|
||||||
|
[PMIF_SWINF_2_WDATA_31_0] = 0x0884,
|
||||||
|
[PMIF_SWINF_2_WDATA_63_32] = 0x0888,
|
||||||
|
[PMIF_SWINF_2_RDATA_31_0] = 0x0894,
|
||||||
|
[PMIF_SWINF_2_RDATA_63_32] = 0x0898,
|
||||||
|
[PMIF_SWINF_2_VLD_CLR] = 0x08A4,
|
||||||
|
[PMIF_SWINF_2_STA] = 0x08A8,
|
||||||
|
[PMIF_SWINF_3_ACC] = 0x08C0,
|
||||||
|
[PMIF_SWINF_3_WDATA_31_0] = 0x08C4,
|
||||||
|
[PMIF_SWINF_3_WDATA_63_32] = 0x08C8,
|
||||||
|
[PMIF_SWINF_3_RDATA_31_0] = 0x08D4,
|
||||||
|
[PMIF_SWINF_3_RDATA_63_32] = 0x08D8,
|
||||||
|
[PMIF_SWINF_3_VLD_CLR] = 0x08E4,
|
||||||
|
[PMIF_SWINF_3_STA] = 0x08E8,
|
||||||
|
/* hw mpu */
|
||||||
|
[PMIF_PMIC_ALL_RGN_EN_1] = 0x09B0,
|
||||||
|
[PMIF_PMIC_ALL_RGN_EN_2] = 0x0D30,
|
||||||
|
[PMIF_PMIC_ALL_RGN_0_START] = 0x09B4,
|
||||||
|
[PMIF_PMIC_ALL_RGN_0_END] = 0x09B8,
|
||||||
|
[PMIF_PMIC_ALL_RGN_1_START] = 0x09BC,
|
||||||
|
[PMIF_PMIC_ALL_RGN_1_END] = 0x09C0,
|
||||||
|
[PMIF_PMIC_ALL_RGN_2_START] = 0x09C4,
|
||||||
|
[PMIF_PMIC_ALL_RGN_2_END] = 0x09C8,
|
||||||
|
[PMIF_PMIC_ALL_RGN_3_START] = 0x09CC,
|
||||||
|
[PMIF_PMIC_ALL_RGN_3_END] = 0x09D0,
|
||||||
|
[PMIF_PMIC_ALL_RGN_31_START] = 0x0D34,
|
||||||
|
[PMIF_PMIC_ALL_RGN_31_END] = 0x0D38,
|
||||||
|
[PMIF_PMIC_ALL_INVLD_SLVID] = 0x0AAC,
|
||||||
|
[PMIF_PMIC_ALL_RGN_0_PER0] = 0x0AB0,
|
||||||
|
[PMIF_PMIC_ALL_RGN_0_PER1] = 0x0AB4,
|
||||||
|
[PMIF_PMIC_ALL_RGN_1_PER0] = 0x0AB8,
|
||||||
|
[PMIF_PMIC_ALL_RGN_2_PER0] = 0x0AC0,
|
||||||
|
[PMIF_PMIC_ALL_RGN_3_PER0] = 0x0AC8,
|
||||||
|
[PMIF_PMIC_ALL_RGN_31_PER0] = 0x0DB4,
|
||||||
|
[PMIF_PMIC_ALL_RGN_31_PER1] = 0x0DB8,
|
||||||
|
[PMIF_PMIC_ALL_RGN_OTHERS_PER0] = 0x0BA8,
|
||||||
|
[PMIF_PMIC_ALL_RGN_OTHERS_PER1] = 0x0BAC,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pmif pmif_spmi_arb[] = {
|
||||||
|
{
|
||||||
|
.base = (void *)PMIF_SPMI_M_BASE,
|
||||||
|
.regs = mt6xxx_regs,
|
||||||
|
.spmimst_base = (void *)SPMI_MST_M_BASE,
|
||||||
|
.spmimst_regs = mt6xxx_spmi_regs,
|
||||||
|
.mstid = SPMI_MASTER_0,
|
||||||
|
.read_cmd = pmif_spmi_read_cmd,
|
||||||
|
.write_cmd = pmif_spmi_write_cmd,
|
||||||
|
}, {
|
||||||
|
.base = (void *)PMIF_SPMI_M_BASE,
|
||||||
|
.regs = mt6xxx_regs,
|
||||||
|
.spmimst_base = (void *)SPMI_MST_M_BASE,
|
||||||
|
.spmimst_regs = mt6xxx_spmi_regs,
|
||||||
|
.mstid = SPMI_MASTER_1,
|
||||||
|
.read_cmd = pmif_spmi_read_cmd,
|
||||||
|
.write_cmd = pmif_spmi_write_cmd,
|
||||||
|
}, {
|
||||||
|
.base = (void *)PMIF_SPMI_P_BASE,
|
||||||
|
.regs = mt6xxx_regs,
|
||||||
|
.spmimst_base = (void *)SPMI_MST_P_BASE,
|
||||||
|
.spmimst_regs = mt6xxx_spmi_regs,
|
||||||
|
.mstid = SPMI_MASTER_P_1,
|
||||||
|
.read_cmd = pmif_spmi_read_cmd,
|
||||||
|
.write_cmd = pmif_spmi_write_cmd,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct spmi_device spmi_dev[] = {
|
||||||
|
{
|
||||||
|
.slvid = SPMI_SLAVE_4,
|
||||||
|
.grpiden = 0x1 << SPMI_GROUP_ID,
|
||||||
|
.mstid = SPMI_MASTER_1,
|
||||||
|
.hwcid_addr = 0x09,
|
||||||
|
.hwcid_val = 0x63,
|
||||||
|
.swcid_addr = 0x0B,
|
||||||
|
.swcid_val = 0x63,
|
||||||
|
.wpk_key_addr = 0x3A7,
|
||||||
|
.wpk_key_val = 0x9C,
|
||||||
|
.wpk_key_h_val = 0x9C,
|
||||||
|
.tma_key_addr = 0x39E,
|
||||||
|
.tma_key_val = 0x9C,
|
||||||
|
.tma_key_h_val = 0x9C,
|
||||||
|
.pmif_arb = &pmif_spmi_arb[SPMI_MASTER_1],
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_9,
|
||||||
|
.grpiden = 0x1 << SPMI_GROUP_ID,
|
||||||
|
.mstid = SPMI_MASTER_1,
|
||||||
|
.hwcid_addr = 0x09,
|
||||||
|
.hwcid_val = 0x85,
|
||||||
|
.swcid_addr = 0x0B,
|
||||||
|
.swcid_val = 0x85,
|
||||||
|
.wpk_key_addr = 0x3AA,
|
||||||
|
.wpk_key_val = 0x30,
|
||||||
|
.wpk_key_h_val = 0x63,
|
||||||
|
.tma_key_addr = 0x39E,
|
||||||
|
.tma_key_val = 0x7A,
|
||||||
|
.tma_key_h_val = 0x99,
|
||||||
|
.pmif_arb = &pmif_spmi_arb[SPMI_MASTER_1],
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_5,
|
||||||
|
.grpiden = 0x800,
|
||||||
|
.mstid = SPMI_MASTER_1,/* spmi-m */
|
||||||
|
.hwcid_addr = 0x09,
|
||||||
|
.hwcid_val = 0x73,
|
||||||
|
.swcid_addr = 0x0B,
|
||||||
|
.swcid_val = 0x73,
|
||||||
|
.wpk_key_addr = 0x3A7,
|
||||||
|
.wpk_key_val = 0x8C,
|
||||||
|
.wpk_key_h_val = 0x9C,
|
||||||
|
.tma_key_addr = 0x39E,
|
||||||
|
.tma_key_val = 0x8C,
|
||||||
|
.tma_key_h_val = 0x9C,
|
||||||
|
.pmif_arb = &pmif_spmi_arb[SPMI_MASTER_1],
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_14, /* MT6379 */
|
||||||
|
.grpiden = 0x800,
|
||||||
|
.mstid = SPMI_MASTER_1,/* spmi-m */
|
||||||
|
.hwcid_addr = 0x00,
|
||||||
|
.hwcid_val = 0x70,
|
||||||
|
.hwcid_mask = 0xF0,
|
||||||
|
.pmif_arb = &pmif_spmi_arb[SPMI_MASTER_1],
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_6, /* MT6316 */
|
||||||
|
.grpiden = 0x800,
|
||||||
|
.mstid = SPMI_MASTER_P_1,/* spmi-m */
|
||||||
|
.hwcid_addr = 0x209,
|
||||||
|
.hwcid_val = 0x16,
|
||||||
|
.swcid_addr = 0x20B,
|
||||||
|
.swcid_val = 0x16,
|
||||||
|
.wpk_key_addr = 0x3B1,
|
||||||
|
.wpk_key_val = 0xE9,
|
||||||
|
.wpk_key_h_val = 0xE6,
|
||||||
|
.tma_key_addr = 0x3A8,
|
||||||
|
.tma_key_val = 0xE9,
|
||||||
|
.tma_key_h_val = 0xE6,
|
||||||
|
.pmif_arb = &pmif_spmi_arb[SPMI_MASTER_P_1],
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_7,
|
||||||
|
.grpiden = 0x800,
|
||||||
|
.mstid = SPMI_MASTER_P_1,/* spmi-m */
|
||||||
|
.hwcid_addr = 0x209,
|
||||||
|
.hwcid_val = 0x16,
|
||||||
|
.swcid_addr = 0x20B,
|
||||||
|
.swcid_val = 0x16,
|
||||||
|
.wpk_key_addr = 0x3B1,
|
||||||
|
.wpk_key_val = 0xE9,
|
||||||
|
.wpk_key_h_val = 0xE6,
|
||||||
|
.tma_key_addr = 0x3A8,
|
||||||
|
.tma_key_val = 0xE9,
|
||||||
|
.tma_key_h_val = 0xE6,
|
||||||
|
.pmif_arb = &pmif_spmi_arb[SPMI_MASTER_P_1],
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_8,
|
||||||
|
.grpiden = 0x800,
|
||||||
|
.mstid = SPMI_MASTER_P_1,/* spmi-m */
|
||||||
|
.hwcid_addr = 0x209,
|
||||||
|
.hwcid_val = 0x16,
|
||||||
|
.swcid_addr = 0x20B,
|
||||||
|
.swcid_val = 0x16,
|
||||||
|
.wpk_key_addr = 0x3B1,
|
||||||
|
.wpk_key_val = 0xE9,
|
||||||
|
.wpk_key_h_val = 0xE6,
|
||||||
|
.tma_key_addr = 0x3A8,
|
||||||
|
.tma_key_val = 0xE9,
|
||||||
|
.tma_key_h_val = 0xE6,
|
||||||
|
.pmif_arb = &pmif_spmi_arb[SPMI_MASTER_P_1],
|
||||||
|
}, {
|
||||||
|
.slvid = SPMI_SLAVE_15,
|
||||||
|
.grpiden = 0x800,
|
||||||
|
.mstid = SPMI_MASTER_P_1,/* spmi-m */
|
||||||
|
.hwcid_addr = 0x209,
|
||||||
|
.hwcid_val = 0x16,
|
||||||
|
.swcid_addr = 0x20B,
|
||||||
|
.swcid_val = 0x16,
|
||||||
|
.wpk_key_addr = 0x3B1,
|
||||||
|
.wpk_key_val = 0xE9,
|
||||||
|
.wpk_key_h_val = 0xE6,
|
||||||
|
.tma_key_addr = 0x3A8,
|
||||||
|
.tma_key_val = 0xE9,
|
||||||
|
.tma_key_h_val = 0xE6,
|
||||||
|
.pmif_arb = &pmif_spmi_arb[SPMI_MASTER_P_1],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#if SPMI_DEBUG
|
||||||
|
static void spmi_read_check(struct spmi_device *dev)
|
||||||
|
{
|
||||||
|
uint8_t rdata = 0;
|
||||||
|
|
||||||
|
spmi_ext_register_readl(dev, dev->hwcid_addr, &rdata, 1);
|
||||||
|
|
||||||
|
if (dev->hwcid_mask) {
|
||||||
|
if ((rdata & dev->hwcid_mask) == (dev->hwcid_val & dev->hwcid_mask))
|
||||||
|
SPMI_INFO("%s pass, slvid:%d rdata = 0x%x\n", __func__,
|
||||||
|
dev->slvid, rdata);
|
||||||
|
else
|
||||||
|
SPMI_ERR("%s fail, slvid:%d rdata = 0x%x\n", __func__,
|
||||||
|
dev->slvid, rdata);
|
||||||
|
} else {
|
||||||
|
if (rdata == dev->hwcid_val)
|
||||||
|
SPMI_INFO("%s pass, slvid:%d rdata = 0x%x\n", __func__,
|
||||||
|
dev->slvid, rdata);
|
||||||
|
else
|
||||||
|
SPMI_ERR("%s fail, slvid:%d rdata = 0x%x\n", __func__,
|
||||||
|
dev->slvid, rdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void spmi_test(void)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < ARRAY_SIZE(spmi_dev); k++)
|
||||||
|
spmi_read_check(&spmi_dev[k]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int platform_pmif_spmi_init(void)
|
||||||
|
{
|
||||||
|
spmi_device_register(spmi_dev, ARRAY_SIZE(spmi_dev));
|
||||||
|
|
||||||
|
#if SPMI_DEBUG
|
||||||
|
spmi_test();
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
MTK_ARCH_INIT(platform_pmif_spmi_init);
|
173
plat/mediatek/drivers/spmi/pmif_common.c
Normal file
173
plat/mediatek/drivers/spmi/pmif_common.c
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <lib/mmio.h>
|
||||||
|
#include <lib/spinlock.h>
|
||||||
|
|
||||||
|
#include <pmif.h>
|
||||||
|
#include "pmif_common.h"
|
||||||
|
#include "spmi_common.h"
|
||||||
|
#include "spmi_sw.h"
|
||||||
|
|
||||||
|
#define PMIF_CMD_REG_0 0
|
||||||
|
#define PMIF_CMD_REG 1
|
||||||
|
#define PMIF_CMD_EXT_REG 2
|
||||||
|
#define PMIF_CMD_EXT_REG_LONG 3
|
||||||
|
#define PMIF_READ_CMD_MIN 0x60
|
||||||
|
#define PMIF_READ_CMD_MAX 0x7F
|
||||||
|
#define PMIF_READ_CMD_EXT_MIN 0x20
|
||||||
|
#define PMIF_READ_CMD_EXT_MAX 0x2F
|
||||||
|
#define PMIF_READ_CMD_EXT_LONG_MIN 0x38
|
||||||
|
#define PMIF_READ_CMD_EXT_LONG_MAX 0x3F
|
||||||
|
#define PMIF_WRITE_CMD_MIN 0x40
|
||||||
|
#define PMIF_WRITE_CMD_MAX 0x5F
|
||||||
|
#define PMIF_WRITE_CMD_EXT_MAX 0xF
|
||||||
|
#define PMIF_WRITE_CMD_EXT_LONG_MIN 0x30
|
||||||
|
#define PMIF_WRITE_CMD_EXT_LONG_MAX 0x37
|
||||||
|
#define PMIF_WRITE_CMD_0_MIN 0x80
|
||||||
|
|
||||||
|
/* macro for SWINF_FSM */
|
||||||
|
#define SWINF_FSM_IDLE 0x00
|
||||||
|
#define SWINF_FSM_REQ 0x02
|
||||||
|
#define SWINF_FSM_WFDLE 0x04
|
||||||
|
#define SWINF_FSM_WFVLDCLR 0x06
|
||||||
|
|
||||||
|
#define GET_SWINF_FSM(x) (((x) >> 1) & 0x7)
|
||||||
|
#define GET_PMIF_INIT_DONE(x) (((x) >> 15) & 0x1)
|
||||||
|
#define TIMEOUT_WAIT_IDLE_US 10000 /* 10ms */
|
||||||
|
|
||||||
|
#define PMIF_RW_CMD_SET(opc, rw, sid, bc, addr) \
|
||||||
|
(((opc) << 30) | ((rw) << 29) | ((sid) << 24) | ((bc) << 16) | (addr))
|
||||||
|
|
||||||
|
static spinlock_t pmif_lock;
|
||||||
|
|
||||||
|
struct pmif *get_pmif_controller(int inf, int mstid)
|
||||||
|
{
|
||||||
|
return &pmif_spmi_arb[mstid];
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pmif_check_idle(int mstid)
|
||||||
|
{
|
||||||
|
struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
|
||||||
|
unsigned int reg_rdata, offset = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
offset = arb->regs[PMIF_SWINF_3_STA];
|
||||||
|
reg_rdata = mmio_read_32((uintptr_t)(arb->base + offset));
|
||||||
|
} while (GET_SWINF_FSM(reg_rdata) != SWINF_FSM_IDLE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pmif_check_vldclr(int mstid)
|
||||||
|
{
|
||||||
|
struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
|
||||||
|
unsigned int reg_rdata, offset = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
offset = arb->regs[PMIF_SWINF_3_STA];
|
||||||
|
reg_rdata = mmio_read_32((uintptr_t)(arb->base + offset));
|
||||||
|
} while (GET_SWINF_FSM(reg_rdata) != SWINF_FSM_WFVLDCLR);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pmif_spmi_read_cmd(struct pmif *arb, uint8_t opc, uint8_t sid,
|
||||||
|
uint16_t addr, uint8_t *buf, uint8_t len)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint32_t offset = 0, data = 0;
|
||||||
|
uint8_t bc = len - 1;
|
||||||
|
|
||||||
|
if (sid > SPMI_MAX_SLAVE_ID || len > PMIF_BYTECNT_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Check the opcode */
|
||||||
|
if (opc >= PMIF_READ_CMD_MIN && opc <= PMIF_READ_CMD_MAX)
|
||||||
|
opc = PMIF_CMD_REG;
|
||||||
|
else if (opc >= PMIF_READ_CMD_EXT_MIN && opc <= PMIF_READ_CMD_EXT_MAX)
|
||||||
|
opc = PMIF_CMD_EXT_REG;
|
||||||
|
else if (opc >= PMIF_READ_CMD_EXT_LONG_MIN && opc <= PMIF_READ_CMD_EXT_LONG_MAX)
|
||||||
|
opc = PMIF_CMD_EXT_REG_LONG;
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
spin_lock(&pmif_lock);
|
||||||
|
|
||||||
|
/* Wait for Software Interface FSM state to be IDLE. */
|
||||||
|
ret = pmif_check_idle(arb->mstid);
|
||||||
|
if (ret)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/* Send the command. */
|
||||||
|
offset = arb->regs[PMIF_SWINF_3_ACC];
|
||||||
|
mmio_write_32((uintptr_t)(arb->base + offset), PMIF_RW_CMD_SET(opc, 0, sid, bc, addr));
|
||||||
|
/*
|
||||||
|
* Wait for Software Interface FSM state to be WFVLDCLR,
|
||||||
|
* read the data and clear the valid flag.
|
||||||
|
*/
|
||||||
|
ret = pmif_check_vldclr(arb->mstid);
|
||||||
|
if (ret)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
offset = arb->regs[PMIF_SWINF_3_RDATA_31_0];
|
||||||
|
|
||||||
|
data = mmio_read_32((uintptr_t)(arb->base + offset));
|
||||||
|
memcpy(buf, &data, (bc & 3) + 1);
|
||||||
|
|
||||||
|
offset = arb->regs[PMIF_SWINF_3_VLD_CLR];
|
||||||
|
mmio_write_32((uintptr_t)(arb->base + offset), 0x1);
|
||||||
|
|
||||||
|
done:
|
||||||
|
spin_unlock(&pmif_lock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pmif_spmi_write_cmd(struct pmif *arb, uint8_t opc, uint8_t sid, uint16_t addr,
|
||||||
|
const uint8_t *buf, uint8_t len)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint32_t offset = 0, data = 0;
|
||||||
|
uint8_t bc = len - 1;
|
||||||
|
|
||||||
|
if (sid > SPMI_MAX_SLAVE_ID || len > PMIF_BYTECNT_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Check the opcode */
|
||||||
|
if (opc >= PMIF_WRITE_CMD_MIN && opc <= PMIF_WRITE_CMD_MAX)
|
||||||
|
opc = PMIF_CMD_REG;
|
||||||
|
else if (opc <= PMIF_WRITE_CMD_EXT_MAX)
|
||||||
|
opc = PMIF_CMD_EXT_REG;
|
||||||
|
else if (opc >= PMIF_WRITE_CMD_EXT_LONG_MIN && opc <= PMIF_WRITE_CMD_EXT_LONG_MAX)
|
||||||
|
opc = PMIF_CMD_EXT_REG_LONG;
|
||||||
|
else if (opc >= PMIF_WRITE_CMD_0_MIN)
|
||||||
|
opc = PMIF_CMD_REG_0;
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
spin_lock(&pmif_lock);
|
||||||
|
|
||||||
|
/* Wait for Software Interface FSM state to be IDLE. */
|
||||||
|
ret = pmif_check_idle(arb->mstid);
|
||||||
|
if (ret)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/* Set the write data. */
|
||||||
|
offset = arb->regs[PMIF_SWINF_3_WDATA_31_0];
|
||||||
|
memcpy(&data, buf, (bc & 3) + 1);
|
||||||
|
mmio_write_32((uintptr_t)(arb->base + offset), data);
|
||||||
|
/* Send the command. */
|
||||||
|
offset = arb->regs[PMIF_SWINF_3_ACC];
|
||||||
|
mmio_write_32((uintptr_t)(arb->base + offset), PMIF_RW_CMD_SET(opc, 1, sid, bc, addr));
|
||||||
|
|
||||||
|
done:
|
||||||
|
spin_unlock(&pmif_lock);
|
||||||
|
return ret;
|
||||||
|
}
|
42
plat/mediatek/drivers/spmi/pmif_common.h
Normal file
42
plat/mediatek/drivers/spmi/pmif_common.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PMIF_COMMON_H
|
||||||
|
#define PMIF_COMMON_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PMIF_CMD_REG_0,
|
||||||
|
PMIF_CMD_REG,
|
||||||
|
PMIF_CMD_EXT_REG,
|
||||||
|
PMIF_CMD_EXT_REG_LONG,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pmif {
|
||||||
|
void *base;
|
||||||
|
uint16_t *regs;
|
||||||
|
void *spmimst_base;
|
||||||
|
uint16_t *spmimst_regs;
|
||||||
|
uint32_t mstid;
|
||||||
|
int (*read_cmd)(struct pmif *arb, uint8_t opc, uint8_t sid, uint16_t addr, uint8_t *buf,
|
||||||
|
uint8_t len);
|
||||||
|
int (*write_cmd)(struct pmif *arb, uint8_t opc, uint8_t sid, uint16_t addr,
|
||||||
|
const uint8_t *buf, uint8_t len);
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PMIF_SPMI,
|
||||||
|
PMIF_SPI
|
||||||
|
};
|
||||||
|
|
||||||
|
int pmif_spmi_read_cmd(struct pmif *arb, uint8_t opc, uint8_t sid, uint16_t addr, uint8_t *buf,
|
||||||
|
uint8_t len);
|
||||||
|
int pmif_spmi_write_cmd(struct pmif *arb, uint8_t opc, uint8_t sid, uint16_t addr,
|
||||||
|
const uint8_t *buf, uint8_t len);
|
||||||
|
struct pmif *get_pmif_controller(int inf, int mstid);
|
||||||
|
extern struct pmif pmif_spmi_arb[];
|
||||||
|
#endif
|
68
plat/mediatek/drivers/spmi/pmif_v1/pmif.h
Normal file
68
plat/mediatek/drivers/spmi/pmif_v1/pmif.h
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PMIF_H
|
||||||
|
#define PMIF_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
#include <drivers/spmi/pmif_common.h>
|
||||||
|
#include <drivers/spmi/spmi_common.h>
|
||||||
|
|
||||||
|
enum pmif_regs {
|
||||||
|
PMIF_INIT_DONE,
|
||||||
|
PMIF_INF_EN,
|
||||||
|
PMIF_ARB_EN,
|
||||||
|
PMIF_IRQ_EVENT_EN_0,
|
||||||
|
PMIF_IRQ_FLAG_0,
|
||||||
|
PMIF_IRQ_CLR_0,
|
||||||
|
PMIF_IRQ_EVENT_EN_2,
|
||||||
|
PMIF_IRQ_FLAG_2,
|
||||||
|
PMIF_IRQ_CLR_2,
|
||||||
|
PMIF_WDT_CTRL,
|
||||||
|
PMIF_WDT_EVENT_EN_1,
|
||||||
|
PMIF_WDT_FLAG_1,
|
||||||
|
PMIF_SWINF_2_ACC,
|
||||||
|
PMIF_SWINF_2_WDATA_31_0,
|
||||||
|
PMIF_SWINF_2_WDATA_63_32,
|
||||||
|
PMIF_SWINF_2_RDATA_31_0,
|
||||||
|
PMIF_SWINF_2_RDATA_63_32,
|
||||||
|
PMIF_SWINF_2_VLD_CLR,
|
||||||
|
PMIF_SWINF_2_STA,
|
||||||
|
PMIF_SWINF_3_ACC,
|
||||||
|
PMIF_SWINF_3_WDATA_31_0,
|
||||||
|
PMIF_SWINF_3_WDATA_63_32,
|
||||||
|
PMIF_SWINF_3_RDATA_31_0,
|
||||||
|
PMIF_SWINF_3_RDATA_63_32,
|
||||||
|
PMIF_SWINF_3_VLD_CLR,
|
||||||
|
PMIF_SWINF_3_STA,
|
||||||
|
/* HW MPU */
|
||||||
|
PMIF_PMIC_ALL_RGN_EN_1,
|
||||||
|
PMIF_PMIC_ALL_RGN_EN_2,
|
||||||
|
PMIF_PMIC_ALL_RGN_0_START,
|
||||||
|
PMIF_PMIC_ALL_RGN_0_END,
|
||||||
|
PMIF_PMIC_ALL_RGN_1_START,
|
||||||
|
PMIF_PMIC_ALL_RGN_1_END,
|
||||||
|
PMIF_PMIC_ALL_RGN_2_START,
|
||||||
|
PMIF_PMIC_ALL_RGN_2_END,
|
||||||
|
PMIF_PMIC_ALL_RGN_3_START,
|
||||||
|
PMIF_PMIC_ALL_RGN_3_END,
|
||||||
|
PMIF_PMIC_ALL_RGN_31_START,
|
||||||
|
PMIF_PMIC_ALL_RGN_31_END,
|
||||||
|
PMIF_PMIC_ALL_INVLD_SLVID,
|
||||||
|
PMIF_PMIC_ALL_RGN_0_PER0,
|
||||||
|
PMIF_PMIC_ALL_RGN_0_PER1,
|
||||||
|
PMIF_PMIC_ALL_RGN_1_PER0,
|
||||||
|
PMIF_PMIC_ALL_RGN_2_PER0,
|
||||||
|
PMIF_PMIC_ALL_RGN_3_PER0,
|
||||||
|
PMIF_PMIC_ALL_RGN_31_PER0,
|
||||||
|
PMIF_PMIC_ALL_RGN_31_PER1,
|
||||||
|
PMIF_PMIC_ALL_RGN_OTHERS_PER0,
|
||||||
|
PMIF_PMIC_ALL_RGN_OTHERS_PER1,
|
||||||
|
};
|
||||||
|
#endif
|
19
plat/mediatek/drivers/spmi/rules.mk
Normal file
19
plat/mediatek/drivers/spmi/rules.mk
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
#
|
||||||
|
|
||||||
|
LOCAL_DIR := $(call GET_LOCAL_DIR)
|
||||||
|
|
||||||
|
MODULE := spmi
|
||||||
|
|
||||||
|
PLAT_INCLUDES += -I${MTK_PLAT}/drivers/spmi/pmif_v1
|
||||||
|
|
||||||
|
#Add your source code here
|
||||||
|
LOCAL_SRCS-y := ${LOCAL_DIR}/pmif_common.c
|
||||||
|
LOCAL_SRCS-y += ${LOCAL_DIR}/spmi_common.c
|
||||||
|
LOCAL_SRCS-y += ${LOCAL_DIR}/${MTK_SOC}/platform_pmif_spmi.c
|
||||||
|
|
||||||
|
#Epilogue, build as module
|
||||||
|
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
|
199
plat/mediatek/drivers/spmi/spmi_common.c
Normal file
199
plat/mediatek/drivers/spmi/spmi_common.c
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <lib/mmio.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
#include "spmi_common.h"
|
||||||
|
#include "spmi_sw.h"
|
||||||
|
|
||||||
|
/* SPMI Commands */
|
||||||
|
#define SPMI_CMD_EXT_WRITE 0x00
|
||||||
|
#define SPMI_CMD_EXT_READ 0x20
|
||||||
|
#define SPMI_CMD_EXT_WRITEL 0x30
|
||||||
|
#define SPMI_CMD_EXT_READL 0x38
|
||||||
|
#define SPMI_CMD_WRITE 0x40
|
||||||
|
#define SPMI_CMD_READ 0x60
|
||||||
|
#define SPMI_CMD_ZERO_WRITE 0x80
|
||||||
|
#define SPMI_READ_ADDR_MAX 0x1F
|
||||||
|
|
||||||
|
static struct spmi_device *spmi_dev[SPMI_MAX_SLAVE_ID];
|
||||||
|
|
||||||
|
int spmi_register_zero_write(struct spmi_device *dev, uint8_t data)
|
||||||
|
{
|
||||||
|
return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_ZERO_WRITE,
|
||||||
|
dev->slvid, 0, &data, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int spmi_register_read(struct spmi_device *dev, uint8_t addr, uint8_t *buf)
|
||||||
|
{
|
||||||
|
/* 5-bit register address */
|
||||||
|
if (addr > SPMI_READ_ADDR_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return dev->pmif_arb->read_cmd(dev->pmif_arb, SPMI_CMD_READ, dev->slvid, addr, buf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int spmi_register_write(struct spmi_device *dev, uint8_t addr, uint8_t data)
|
||||||
|
{
|
||||||
|
/* 5-bit register address */
|
||||||
|
if (addr > SPMI_READ_ADDR_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_WRITE,
|
||||||
|
dev->slvid, addr, &data, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int spmi_ext_register_read(struct spmi_device *dev, uint8_t addr, uint8_t *buf,
|
||||||
|
uint8_t len)
|
||||||
|
{
|
||||||
|
/* 8-bit register address, up to 16 bytes */
|
||||||
|
if (len == 0 || len > 16)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return dev->pmif_arb->read_cmd(dev->pmif_arb, SPMI_CMD_EXT_READ,
|
||||||
|
dev->slvid, addr, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int spmi_ext_register_write(struct spmi_device *dev, uint8_t addr,
|
||||||
|
const uint8_t *buf, uint8_t len)
|
||||||
|
{
|
||||||
|
/* 8-bit register address, up to 16 bytes */
|
||||||
|
if (len == 0 || len > 16)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_EXT_WRITE,
|
||||||
|
dev->slvid, addr, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int spmi_ext_register_readl(struct spmi_device *dev, uint16_t addr,
|
||||||
|
uint8_t *buf, uint8_t len)
|
||||||
|
{
|
||||||
|
/* 8-bit register address, up to 16 bytes */
|
||||||
|
if (len == 0 || len > 16)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return dev->pmif_arb->read_cmd(dev->pmif_arb, SPMI_CMD_EXT_READL,
|
||||||
|
dev->slvid, addr, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int spmi_ext_register_writel(struct spmi_device *dev, uint16_t addr,
|
||||||
|
const uint8_t *buf, uint8_t len)
|
||||||
|
{
|
||||||
|
/* 8-bit register address, up to 16 bytes */
|
||||||
|
if (len == 0 || len > 16)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_EXT_WRITEL,
|
||||||
|
dev->slvid, addr, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int spmi_ext_register_readl_field(struct spmi_device *dev, uint16_t addr,
|
||||||
|
uint8_t *buf, uint16_t mask, uint16_t shift)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint8_t rdata = 0;
|
||||||
|
|
||||||
|
ret = dev->pmif_arb->read_cmd(dev->pmif_arb, SPMI_CMD_EXT_READL,
|
||||||
|
dev->slvid, addr, &rdata, 1);
|
||||||
|
if (!ret)
|
||||||
|
*buf = (rdata >> shift) & mask;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spmi_ext_register_writel_field(struct spmi_device *dev, uint16_t addr,
|
||||||
|
uint8_t data, uint16_t mask, uint16_t shift)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint8_t tmp = 0;
|
||||||
|
|
||||||
|
ret = spmi_ext_register_readl(dev, addr, &tmp, 1);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
tmp &= ~(mask << shift);
|
||||||
|
tmp |= (data << shift);
|
||||||
|
return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_EXT_WRITEL,
|
||||||
|
dev->slvid, addr, &tmp, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct spmi_device *get_spmi_device(int mstid, int slvid)
|
||||||
|
{
|
||||||
|
if (slvid >= SPMI_MAX_SLAVE_ID || slvid < 0) {
|
||||||
|
SPMI_ERR("failed to get spmi_device with slave id %d\n", slvid);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return spmi_dev[slvid];
|
||||||
|
}
|
||||||
|
|
||||||
|
int spmi_device_register(struct spmi_device *platform_spmi_dev, unsigned int num_devs)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!platform_spmi_dev || num_devs == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
for (i = 0; i < num_devs; i++) {
|
||||||
|
if (platform_spmi_dev[i].slvid >= SPMI_MAX_SLAVE_ID ||
|
||||||
|
platform_spmi_dev[i].slvid < 0) {
|
||||||
|
SPMI_INFO("invalid slave id %d\n", platform_spmi_dev[i].slvid);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!spmi_dev[platform_spmi_dev[i].slvid])
|
||||||
|
spmi_dev[platform_spmi_dev[i].slvid] = &platform_spmi_dev[i];
|
||||||
|
else {
|
||||||
|
SPMI_INFO("duplicated slave id %d\n", platform_spmi_dev[i].slvid);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spmi_ctrl_op_st(int mstid, unsigned int grpiden, unsigned int sid,
|
||||||
|
unsigned int cmd)
|
||||||
|
{
|
||||||
|
struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
|
||||||
|
unsigned int rdata = 0x0;
|
||||||
|
uintptr_t spmi_grp_id_en_addr =
|
||||||
|
(uintptr_t)(arb->spmimst_base + arb->spmimst_regs[SPMI_GRP_ID_EN]);
|
||||||
|
uintptr_t spmi_op_st_ctrl_addr =
|
||||||
|
(uintptr_t)(arb->spmimst_base + arb->spmimst_regs[SPMI_OP_ST_CTRL]);
|
||||||
|
uintptr_t spmi_op_st_sta_addr =
|
||||||
|
(uintptr_t)(arb->spmimst_base + arb->spmimst_regs[SPMI_OP_ST_STA]);
|
||||||
|
|
||||||
|
/* gid is 0x800 */
|
||||||
|
mmio_write_32(spmi_grp_id_en_addr, grpiden);
|
||||||
|
|
||||||
|
if (grpiden == (1 << SPMI_GROUP_ID))
|
||||||
|
mmio_write_32(spmi_op_st_ctrl_addr, (cmd << 0x4) | SPMI_GROUP_ID);
|
||||||
|
else
|
||||||
|
mmio_write_32(spmi_op_st_ctrl_addr, (cmd << 0x4) | sid);
|
||||||
|
|
||||||
|
SPMI_INFO("%s 0x%x\n", __func__, mmio_read_32(spmi_op_st_ctrl_addr));
|
||||||
|
|
||||||
|
do {
|
||||||
|
rdata = mmio_read_32(spmi_op_st_sta_addr);
|
||||||
|
SPMI_INFO("%s 0x%x\n", __func__, rdata);
|
||||||
|
|
||||||
|
if (((rdata >> 0x1) & SPMI_OP_ST_NACK) == SPMI_OP_ST_NACK) {
|
||||||
|
SPMI_ERR("SPMI_OP_ST_NACK occurs! OP_ST_STA = 0x%x\n", rdata);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while ((rdata & SPMI_OP_ST_BUSY) == SPMI_OP_ST_BUSY);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spmi_command_shutdown(int mstid, struct spmi_device *dev, unsigned int grpiden)
|
||||||
|
{
|
||||||
|
if (grpiden != (1 << SPMI_GROUP_ID))
|
||||||
|
dev->slvid = grpiden;
|
||||||
|
|
||||||
|
return spmi_ctrl_op_st(mstid, grpiden, dev->slvid, SPMI_SHUTDOWN);
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue