diff options
Diffstat (limited to 'plat/mediatek/common/lpm/mt_lp_rm.c')
-rw-r--r-- | plat/mediatek/common/lpm/mt_lp_rm.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/plat/mediatek/common/lpm/mt_lp_rm.c b/plat/mediatek/common/lpm/mt_lp_rm.c new file mode 100644 index 0000000..0bafc66 --- /dev/null +++ b/plat/mediatek/common/lpm/mt_lp_rm.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <mt_lp_rm.h> +#include <stddef.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(int idx, unsigned int cpuid, int stateid) +{ + struct mt_resource_constraint const *rc = NULL; + + if ((plat_mt_rm.plat_rm == NULL) || (idx < 0) || + (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_find_and_run_constraint(int idx, unsigned int cpuid, + int stateid, void *priv) +{ + int i, 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 < 0) || (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, stateid, priv); + if (res != 0) { + return res; + } + } + + for (i = idx, rc = (rm->consts + idx); *rc != NULL; i++, rc++) { + if (((*rc)->is_valid != NULL) && + ((*rc)->is_valid(cpuid, stateid))) { + if (((*rc)->run != NULL) && + ((*rc)->run(cpuid, stateid) == 0)) { + res = i; + break; + } + } + } + + 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; +} |