1 /* 2 * Copyright (c) 2023, MediaTek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <lpm/mt_lpm_smc.h> 8 #include <mt_spm.h> 9 #include "mt_spm_rc_api.h" 10 #include "mt_spm_rc_internal.h" 11 12 int spm_rc_condition_modifier(unsigned int id, unsigned int act, 13 const void *val, 14 enum mt_spm_rm_rc_type dest_rc_id, 15 struct mt_spm_cond_tables * const tlb) 16 { 17 unsigned int rc_id, cond_id, cond; 18 int res = 0; 19 20 spin_lock(&spm_lock); 21 rc_id = SPM_RC_UPDATE_COND_RC_ID_GET(id); 22 cond_id = SPM_RC_UPDATE_COND_ID_GET(id); 23 24 do { 25 if ((dest_rc_id != rc_id) || (val == NULL) || (tlb == NULL)) { 26 res = -1; 27 break; 28 } 29 30 cond = *((unsigned int *)val); 31 32 if (cond_id < PLAT_SPM_COND_MAX) { 33 if ((act & MT_LPM_SMC_ACT_SET) > 0U) { 34 SPM_RC_BITS_SET(tlb->table_cg[cond_id], cond); 35 } else if ((act & MT_LPM_SMC_ACT_CLR) > 0U) { 36 SPM_RC_BITS_CLR(tlb->table_cg[cond_id], cond); 37 } else { 38 res = -1; 39 } 40 } else if ((cond_id - PLAT_SPM_COND_MAX) < PLAT_SPM_COND_PLL_MAX) { 41 unsigned int pll_idx = cond_id - PLAT_SPM_COND_MAX; 42 43 cond = !!cond; 44 if ((act & MT_LPM_SMC_ACT_SET) > 0U) { 45 SPM_RC_BITS_SET(tlb->table_pll, (cond << pll_idx)); 46 } else if ((act & MT_LPM_SMC_ACT_CLR) > 0U) { 47 SPM_RC_BITS_CLR(tlb->table_pll, (cond << pll_idx)); 48 } else { 49 res = -1; 50 } 51 } else { 52 res = -1; 53 } 54 } while (0); 55 56 spin_unlock(&spm_lock); 57 58 return res; 59 } 60 61 int spm_rc_constraint_status_get(unsigned int id, unsigned int type, 62 unsigned int act, 63 enum mt_spm_rm_rc_type dest_rc_id, 64 struct constraint_status * const src, 65 struct constraint_status * const dest) 66 { 67 if (((id != MT_RM_CONSTRAINT_ID_ALL) && (id != dest_rc_id)) || (dest == NULL) || 68 (src == NULL)) { 69 return -1; 70 } 71 spin_lock(&spm_lock); 72 73 switch (type) { 74 case CONSTRAINT_GET_ENTER_CNT: 75 if (id == MT_RM_CONSTRAINT_ID_ALL) { 76 dest->enter_cnt += src->enter_cnt; 77 } else { 78 dest->enter_cnt = src->enter_cnt; 79 } 80 break; 81 case CONSTRAINT_GET_VALID: 82 dest->is_valid = src->is_valid; 83 break; 84 case CONSTRAINT_COND_BLOCK: 85 dest->is_cond_block = src->is_cond_block; 86 dest->all_pll_dump = src->all_pll_dump; 87 break; 88 case CONSTRAINT_GET_COND_BLOCK_DETAIL: 89 dest->cond_res = src->cond_res; 90 break; 91 case CONSTRAINT_GET_RESIDNECY: 92 dest->residency = src->residency; 93 if (act & MT_LPM_SMC_ACT_CLR) { 94 src->residency = 0; 95 } 96 break; 97 default: 98 break; 99 } 100 101 spin_unlock(&spm_lock); 102 return 0; 103 } 104 105 int spm_rc_constraint_status_set(unsigned int id, unsigned int type, 106 unsigned int act, 107 enum mt_spm_rm_rc_type dest_rc_id, 108 struct constraint_status * const src, 109 struct constraint_status * const dest) 110 { 111 if (((id != MT_RM_CONSTRAINT_ID_ALL) && (id != dest_rc_id)) || (dest == NULL)) { 112 return -1; 113 } 114 115 spin_lock(&spm_lock); 116 117 switch (type) { 118 case CONSTRAINT_UPDATE_VALID: 119 if (src != NULL) { 120 if ((act & MT_LPM_SMC_ACT_SET) > 0U) { 121 SPM_RC_BITS_SET(dest->is_valid, src->is_valid); 122 } else if ((act & MT_LPM_SMC_ACT_CLR) > 0U) { 123 SPM_RC_BITS_CLR(dest->is_valid, src->is_valid); 124 } 125 } 126 break; 127 case CONSTRAINT_RESIDNECY: 128 if (act & MT_LPM_SMC_ACT_CLR) { 129 dest->residency = 0; 130 } 131 break; 132 default: 133 break; 134 } 135 136 spin_unlock(&spm_lock); 137 138 return 0; 139 } 140 141 int spm_rc_constraint_valid_set(enum mt_spm_rm_rc_type id, 142 enum mt_spm_rm_rc_type dest_rc_id, 143 unsigned int valid, 144 struct constraint_status * const dest) 145 { 146 if (((id != MT_RM_CONSTRAINT_ID_ALL) && (id != dest_rc_id)) || (dest == NULL)) { 147 return -1; 148 } 149 150 spin_lock(&spm_lock); 151 SPM_RC_BITS_SET(dest->is_valid, valid); 152 spin_unlock(&spm_lock); 153 154 return 0; 155 } 156 157 int spm_rc_constraint_valid_clr(enum mt_spm_rm_rc_type id, 158 enum mt_spm_rm_rc_type dest_rc_id, 159 unsigned int valid, 160 struct constraint_status * const dest) 161 { 162 if (((id != MT_RM_CONSTRAINT_ID_ALL) && (id != dest_rc_id)) || (dest == NULL)) { 163 return -1; 164 } 165 166 spin_lock(&spm_lock); 167 SPM_RC_BITS_CLR(dest->is_valid, valid); 168 spin_unlock(&spm_lock); 169 170 return 0; 171 } 172