1 /* 2 * Copyright (c) 2025, MediaTek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <lpm_v2/mt_lpm_smc.h> 8 #include <mt_spm_common.h> 9 #include <mt_spm_hwreq.h> 10 #include <mt_spm_rc_api_common.h> 11 12 #define SPM_RC_VALID_SET(dest, src) ({ (dest) |= (src); }) 13 #define SPM_RC_VALID_CLR(dest, src) ({ (dest) &= ~(src); }) 14 15 int spm_rc_constraint_status_get(uint32_t id, uint32_t type, 16 uint32_t act, 17 enum mt_spm_rm_rc_type dest_rc_id, 18 struct constraint_status * const src, 19 struct constraint_status * const dest) 20 { 21 if (((id != MT_RM_CONSTRAINT_ID_ALL) && 22 (id != dest_rc_id)) || !dest || !src) 23 return -1; 24 spm_lock_get(); 25 26 switch (type) { 27 case CONSTRAINT_GET_ENTER_CNT: 28 if (id == MT_RM_CONSTRAINT_ID_ALL) 29 dest->enter_cnt += src->enter_cnt; 30 else 31 dest->enter_cnt = src->enter_cnt; 32 break; 33 case CONSTRAINT_GET_VALID: 34 dest->is_valid = src->is_valid; 35 break; 36 case CONSTRAINT_COND_BLOCK: 37 dest->is_cond_block = src->is_cond_block; 38 dest->all_pll_dump = src->all_pll_dump; 39 break; 40 case CONSTRAINT_GET_COND_BLOCK_DETAIL: 41 dest->cond_res = src->cond_res; 42 break; 43 case CONSTRAINT_GET_RESIDNECY: 44 dest->residency = src->residency; 45 if (act & MT_LPM_SMC_ACT_CLR) 46 src->residency = 0; 47 break; 48 default: 49 break; 50 } 51 52 spm_lock_release(); 53 return 0; 54 } 55 56 int spm_rc_constraint_status_set(uint32_t id, uint32_t type, 57 uint32_t act, 58 enum mt_spm_rm_rc_type dest_rc_id, 59 struct constraint_status * const src, 60 struct constraint_status * const dest) 61 { 62 if (((id != MT_RM_CONSTRAINT_ID_ALL) && 63 (id != dest_rc_id)) || !dest) 64 return -1; 65 66 spm_lock_get(); 67 68 switch (type) { 69 case CONSTRAINT_UPDATE_VALID: 70 if (src) { 71 if (act & MT_LPM_SMC_ACT_SET) 72 SPM_RC_VALID_SET(dest->is_valid, src->is_valid); 73 else if (act & MT_LPM_SMC_ACT_CLR) 74 SPM_RC_VALID_CLR(dest->is_valid, src->is_valid); 75 } 76 break; 77 case CONSTRAINT_RESIDNECY: 78 if (act & MT_LPM_SMC_ACT_CLR) 79 dest->residency = 0; 80 break; 81 default: 82 break; 83 } 84 85 spm_lock_release(); 86 87 return 0; 88 } 89 90 int spm_rc_constraint_valid_set(enum mt_spm_rm_rc_type id, 91 enum mt_spm_rm_rc_type dest_rc_id, 92 uint32_t valid, 93 struct constraint_status * const dest) 94 { 95 if (((id != MT_RM_CONSTRAINT_ID_ALL) && 96 (id != dest_rc_id)) || !dest) 97 return -1; 98 99 spm_lock_get(); 100 SPM_RC_VALID_SET(dest->is_valid, valid); 101 spm_lock_release(); 102 103 return 0; 104 } 105 106 int spm_rc_constraint_valid_clr(enum mt_spm_rm_rc_type id, 107 enum mt_spm_rm_rc_type dest_rc_id, 108 uint32_t valid, 109 struct constraint_status * const dest) 110 { 111 if (((id != MT_RM_CONSTRAINT_ID_ALL) && 112 (id != dest_rc_id)) || !dest) 113 return -1; 114 115 spm_lock_get(); 116 SPM_RC_VALID_CLR(dest->is_valid, valid); 117 spm_lock_release(); 118 119 return 0; 120 } 121 122 #define PMIC_WRAP_REG_1 0x3E8 123 #define PMIC_WRAP_REG_STEP 0x4 124 #define PMIC_WRAP_REG_2 0xC28 125 #define PMIC_WRAP_REG_3 0xF54 126 127 #ifndef MTK_PLAT_SPM_PMIC_WRAP_DUMP_UNSUPPORT 128 void mt_spm_dump_pmic_warp_reg(void) 129 { 130 uint32_t temp; 131 uint32_t i; 132 133 for (i = 0; i <= PMIC_WRAP_REG_1; i += PMIC_WRAP_REG_STEP) { 134 temp = mmio_read_32(PMIC_WRAP_BASE + i); 135 } 136 137 for (i = 0xC00; i <= PMIC_WRAP_REG_2; i += PMIC_WRAP_REG_STEP) { 138 temp = mmio_read_32(PMIC_WRAP_BASE + i); 139 } 140 141 for (i = 0xF00; i <= PMIC_WRAP_REG_3; i += PMIC_WRAP_REG_STEP) { 142 temp = mmio_read_32(PMIC_WRAP_BASE + i); 143 } 144 } 145 #endif 146 147 uint32_t spm_allow_rc_vcore(int state_id) 148 { 149 return CONSTRAINT_VCORE_ALLOW; 150 } 151 152 int spm_hwcg_name(uint32_t idex, char *name, size_t sz) 153 { 154 int ret = 0; 155 156 if (!name) 157 return -1; 158 159 switch (idex) { 160 case HWCG_DDREN: 161 ret = snprintf(name, sz - 1, "dram"); 162 break; 163 case HWCG_VRF18: 164 ret = snprintf(name, sz - 1, "vrf18"); 165 break; 166 case HWCG_INFRA: 167 ret = snprintf(name, sz - 1, "infra"); 168 break; 169 case HWCG_PMIC: 170 ret = snprintf(name, sz - 1, "pmic"); 171 break; 172 case HWCG_F26M: 173 ret = snprintf(name, sz - 1, "26m"); 174 break; 175 case HWCG_VCORE: 176 ret = snprintf(name, sz - 1, "vcore"); 177 break; 178 default: 179 ret = -1; 180 break; 181 } 182 183 if (ret < 0) 184 ret = -1; 185 186 name[sz - 1] = '\0'; 187 188 return ret; 189 } 190