/* * Copyright (c) 2025, MediaTek Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include 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; }