1 /* 2 * Copyright (c) 2025, MediaTek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <stddef.h> 8 9 #include <lpm_v2/mt_lp_rm.h> 10 11 struct platform_mt_resource_manager { 12 unsigned int count; 13 struct mt_resource_manager *plat_rm; 14 }; 15 16 static struct platform_mt_resource_manager plat_mt_rm; 17 18 int mt_lp_rm_register(struct mt_resource_manager *rm) 19 { 20 unsigned int i; 21 struct mt_resource_constraint *const *rc; 22 23 if ((rm == NULL) || (rm->consts == NULL) || 24 (plat_mt_rm.plat_rm != NULL)) { 25 return MT_RM_STATUS_BAD; 26 } 27 28 for (i = 0U, rc = rm->consts; *rc != NULL; i++, rc++) { 29 if ((*rc)->init != NULL) 30 (*rc)->init(); 31 } 32 33 plat_mt_rm.plat_rm = rm; 34 plat_mt_rm.count = i; 35 36 return MT_RM_STATUS_OK; 37 } 38 39 int mt_lp_rm_reset_constraint(unsigned int idx, unsigned int cpuid, int stateid) 40 { 41 struct mt_resource_constraint const *rc = NULL; 42 43 if ((plat_mt_rm.plat_rm == NULL) || (idx >= plat_mt_rm.count)) 44 return MT_RM_STATUS_BAD; 45 46 rc = plat_mt_rm.plat_rm->consts[idx]; 47 48 if ((rc == NULL) || (rc->reset == NULL)) 49 return MT_RM_STATUS_BAD; 50 51 return rc->reset(cpuid, stateid); 52 } 53 54 int mt_lp_rm_get_status(unsigned int type, void *priv) 55 { 56 int res = 0; 57 struct mt_resource_constraint *const *con; 58 struct mt_resource_manager *rm = plat_mt_rm.plat_rm; 59 60 if ((rm == NULL) || (type >= PLAT_RC_MAX)) 61 return -1; 62 63 for (con = rm->consts; *con != NULL; con++) { 64 if ((*con)->get_status == NULL) 65 continue; 66 67 res = (*con)->get_status(type, priv); 68 if (res == MT_RM_STATUS_STOP) 69 break; 70 } 71 72 return res; 73 } 74 75 int mt_lp_rm_do_constraint(unsigned int constraint_id, unsigned int cpuid, int stateid) 76 { 77 int res = MT_RM_STATUS_BAD; 78 struct mt_resource_constraint const *rc; 79 struct mt_resource_manager *rm = plat_mt_rm.plat_rm; 80 81 if ((rm == NULL) || (constraint_id >= plat_mt_rm.count)) 82 return res; 83 84 rc = rm->consts[constraint_id]; 85 if ((rc != NULL) && (rc->run != NULL)) 86 res = rc->run(cpuid, stateid); 87 88 return res; 89 } 90 91 int mt_lp_rm_find_constraint(unsigned int idx, unsigned int cpuid, 92 int stateid, void *priv) 93 { 94 unsigned int i; 95 int res = MT_RM_STATUS_BAD; 96 struct mt_resource_constraint *const *rc; 97 struct mt_resource_manager *rm = plat_mt_rm.plat_rm; 98 99 if ((rm == NULL) || (idx >= plat_mt_rm.count)) 100 return res; 101 102 /* If subsys clk/mtcmos is on, add block-resource-off flag */ 103 if (rm->update != NULL) { 104 res = rm->update(rm->consts, plat_mt_rm.count, stateid, priv); 105 if (res != 0) 106 return MT_RM_STATUS_BAD; 107 } 108 109 res = MT_RM_STATUS_BAD; 110 for (i = idx, rc = (rm->consts + idx); *rc != NULL; i++, rc++) { 111 if (((*rc)->is_valid != NULL) && 112 ((*rc)->is_valid(cpuid, stateid))) { 113 res = i; 114 break; 115 } 116 } 117 118 return res; 119 } 120 121 int mt_lp_rm_find_and_run_constraint(unsigned int idx, unsigned int cpuid, 122 int stateid, void *priv) 123 { 124 int res = MT_RM_STATUS_BAD; 125 126 res = mt_lp_rm_find_constraint(idx, cpuid, stateid, priv); 127 if (res != MT_RM_STATUS_BAD) 128 mt_lp_rm_do_constraint(res, cpuid, stateid); 129 130 return res; 131 } 132 133 int mt_lp_rm_do_update(int stateid, int type, void const *p) 134 { 135 int res = MT_RM_STATUS_BAD; 136 struct mt_resource_constraint *const *rc; 137 struct mt_resource_manager *rm = plat_mt_rm.plat_rm; 138 139 if (rm == NULL) 140 return res; 141 142 for (rc = rm->consts; *rc != NULL; rc++) { 143 if ((*rc)->update != NULL) { 144 res = (*rc)->update(stateid, type, p); 145 if (res != MT_RM_STATUS_OK) 146 break; 147 } 148 } 149 150 return res; 151 } 152 153 int mt_lp_rm_do_hwctrl(unsigned int type, int set, void *priv) 154 { 155 struct mt_resource_manager *rm = plat_mt_rm.plat_rm; 156 int res = 0; 157 158 if (!rm || !rm->hwctrl || (type >= PLAT_AP_HW_CTRL_MAX)) 159 return -1; 160 161 res = rm->hwctrl(type, set, priv); 162 163 return res; 164 } 165