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(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 < 0) || 44 (idx >= plat_mt_rm.count)) { 45 return MT_RM_STATUS_BAD; 46 } 47 48 rc = plat_mt_rm.plat_rm->consts[idx]; 49 50 if ((rc == NULL) || (rc->reset == NULL)) { 51 return MT_RM_STATUS_BAD; 52 } 53 54 return rc->reset(cpuid, stateid); 55 } 56 57 int mt_lp_rm_get_status(unsigned int type, void *priv) 58 { 59 int res = 0; 60 struct mt_resource_constraint *const *con; 61 struct mt_resource_manager *rm = plat_mt_rm.plat_rm; 62 63 if ((rm == NULL) || (type >= PLAT_RC_MAX)) { 64 return -1; 65 } 66 67 for (con = rm->consts; *con != NULL; con++) { 68 if ((*con)->get_status == NULL) { 69 continue; 70 } 71 res = (*con)->get_status(type, priv); 72 if (res == MT_RM_STATUS_STOP) { 73 break; 74 } 75 } 76 77 return res; 78 } 79 80 int mt_lp_rm_find_and_run_constraint(int idx, unsigned int cpuid, 81 int stateid, void *priv) 82 { 83 int i, res = MT_RM_STATUS_BAD; 84 struct mt_resource_constraint *const *rc; 85 struct mt_resource_manager *rm = plat_mt_rm.plat_rm; 86 87 if ((rm == NULL) || (idx < 0) || (idx >= plat_mt_rm.count)) { 88 return res; 89 } 90 91 /* If subsys clk/mtcmos is on, add block-resource-off flag */ 92 if (rm->update != NULL) { 93 res = rm->update(rm->consts, stateid, priv); 94 if (res != 0) { 95 return res; 96 } 97 } 98 99 for (i = idx, rc = (rm->consts + idx); *rc != NULL; i++, rc++) { 100 if (((*rc)->is_valid != NULL) && 101 ((*rc)->is_valid(cpuid, stateid))) { 102 if (((*rc)->run != NULL) && 103 ((*rc)->run(cpuid, stateid) == 0)) { 104 res = i; 105 break; 106 } 107 } 108 } 109 110 return res; 111 } 112 113 int mt_lp_rm_do_update(int stateid, int type, void const *p) 114 { 115 int res = MT_RM_STATUS_BAD; 116 struct mt_resource_constraint *const *rc; 117 struct mt_resource_manager *rm = plat_mt_rm.plat_rm; 118 119 if (rm == NULL) { 120 return res; 121 } 122 123 for (rc = rm->consts; *rc != NULL; rc++) { 124 if ((*rc)->update != NULL) { 125 res = (*rc)->update(stateid, type, p); 126 if (res != MT_RM_STATUS_OK) { 127 break; 128 } 129 } 130 } 131 132 return res; 133 } 134