mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 09:34:18 +00:00

LPM means low power module, it will connect idle and SPM to achieve lower power consumption in some scenarios, and this patch is LPM second version Signed-off-by: Wenzhen Yu <wenzhen.yu@mediatek.corp-partner.google.com> Change-Id: I6ae5b5b4c2056d08c29efab5116be3a92351d8f1
164 lines
3.5 KiB
C
164 lines
3.5 KiB
C
/*
|
|
* 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;
|
|
}
|