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