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