xref: /arm-trusted-firmware/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_api.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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