xref: /rk3399_ARM-atf/plat/mediatek/drivers/spm/mt_spm_rc_api_common.c (revision cbf956ad0b4d62f7f93fd33d975a4d961009d83f)
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