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
spm_rc_constraint_status_get(uint32_t id,uint32_t type,uint32_t act,enum mt_spm_rm_rc_type dest_rc_id,struct constraint_status * const src,struct constraint_status * const dest)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
spm_rc_constraint_status_set(uint32_t id,uint32_t type,uint32_t act,enum mt_spm_rm_rc_type dest_rc_id,struct constraint_status * const src,struct constraint_status * const dest)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
spm_rc_constraint_valid_set(enum mt_spm_rm_rc_type id,enum mt_spm_rm_rc_type dest_rc_id,uint32_t valid,struct constraint_status * const dest)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
spm_rc_constraint_valid_clr(enum mt_spm_rm_rc_type id,enum mt_spm_rm_rc_type dest_rc_id,uint32_t valid,struct constraint_status * const dest)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
mt_spm_dump_pmic_warp_reg(void)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
spm_allow_rc_vcore(int state_id)147 uint32_t spm_allow_rc_vcore(int state_id)
148 {
149 return CONSTRAINT_VCORE_ALLOW;
150 }
151
spm_hwcg_name(uint32_t idex,char * name,size_t sz)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