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