xref: /rk3399_ARM-atf/plat/mediatek/drivers/spm/mt8196/constraints/mt_spm_rc_bus26m.c (revision cf2df874cd09305ac7282fadb0fef6be597dfffb)
1 /*
2  * Copyright (c) 2025, Mediatek Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <stdint.h>
8 
9 #include <common/debug.h>
10 
11 #include <constraints/mt_spm_rc_api.h>
12 #include <constraints/mt_spm_rc_internal.h>
13 #include <drivers/spm/mt_spm_resource_req.h>
14 #include <lib/pm/mtk_pm.h>
15 #include <lpm_v2/mt_lp_rm.h>
16 #include <mt_plat_spm_setting.h>
17 #include <mt_spm.h>
18 #include <mt_spm_conservation.h>
19 #include <mt_spm_constraint.h>
20 #include <mt_spm_idle.h>
21 #include <mt_spm_internal.h>
22 #include <mt_spm_pmic_lp.h>
23 #include <mt_spm_reg.h>
24 #include <mt_spm_suspend.h>
25 #include <notifier/inc/mt_spm_notifier.h>
26 
27 #define CONSTRAINT_BUS26M_ALLOW (MT_RM_CONSTRAINT_ALLOW_CPU_BUCK_OFF | \
28 				 MT_RM_CONSTRAINT_ALLOW_DRAM_S0 | \
29 				 MT_RM_CONSTRAINT_ALLOW_DRAM_S1 | \
30 				 MT_RM_CONSTRAINT_ALLOW_VCORE_LP | \
31 				 MT_RM_CONSTRAINT_ALLOW_LVTS_STATE | \
32 				 MT_RM_CONSTRAINT_ALLOW_BUS26M_OFF)
33 
34 #define CONSTRAINT_BUS26M_PCM_FLAG (SPM_FLAG_DISABLE_VCORE_DVS | \
35 				    SPM_FLAG_DISABLE_DDR_DFS | \
36 				    SPM_FLAG_DISABLE_EMI_DFS | \
37 				    SPM_FLAG_DISABLE_BUS_DFS | \
38 				    SPM_FLAG_ENABLE_AOV | \
39 				    SPM_FLAG_DISABLE_VLP_PDN | \
40 				    SPM_FLAG_SRAM_SLEEP_CTRL | \
41 				    SPM_FLAG_KEEP_CSYSPWRACK_HIGH)
42 
43 #define CONSTRAINT_BUS26M_PCM_FLAG1 (SPM_FLAG1_ENABLE_ALCO_TRACE)
44 /*
45  * If sspm sram won't enter  sleep voltage
46  * then vcore couldn't enter low power mode
47  */
48 
49 #if defined(MTK_PLAT_SPM_SRAM_SLP_UNSUPPORT) && SPM_SRAM_SLEEP_RC_RES_RESTRICT
50 #define CONSTRAINT_BUS26M_RESOURCE_REQ	(MT_SPM_26M | MT_SPM_VCORE)
51 #else
52 #define CONSTRAINT_BUS26M_RESOURCE_REQ	(MT_SPM_VCORE)
53 #endif
54 static uint32_t bus26m_ext_opand;
55 static struct mt_irqremain *refer2remain_irq;
56 static uint32_t cmd;
57 
58 static struct constraint_status status = {
59 	.id = MT_RM_CONSTRAINT_ID_BUS26,
60 	.is_valid = (MT_SPM_RC_VALID_SW |
61 		     MT_SPM_RC_VALID_FW |
62 		     MT_SPM_RC_VALID_TRACE_TIME |
63 		     MT_SPM_RC_VALID_NOTIFY),
64 	.enter_cnt = 0,
65 	.all_pll_dump = 0,
66 	.residency = 0,
67 };
68 
spm_bus26m_conduct(int state_id,struct spm_lp_scen * spm_lp,uint32_t * resource_req)69 int spm_bus26m_conduct(int state_id, struct spm_lp_scen *spm_lp,
70 		       uint32_t *resource_req)
71 {
72 	if ((spm_lp == NULL) || (resource_req == NULL))
73 		return -1;
74 
75 	struct pwr_ctrl *pwrctrl = spm_lp->pwrctrl;
76 
77 	pwrctrl->pcm_flags = CONSTRAINT_BUS26M_PCM_FLAG;
78 	pwrctrl->pcm_flags1 = CONSTRAINT_BUS26M_PCM_FLAG1;
79 
80 	*resource_req |= CONSTRAINT_BUS26M_RESOURCE_REQ;
81 	return 0;
82 }
83 
spm_is_valid_rc_bus26m(uint32_t cpu,int state_id)84 bool spm_is_valid_rc_bus26m(uint32_t cpu, int state_id)
85 {
86 	return (IS_MT_RM_RC_READY(status.is_valid) &&
87 		!(bus26m_ext_opand & (MT_BUS26M_EXT_LP_26M_ON_MODE)));
88 }
89 
spm_update_rc_bus26m(int state_id,int type,const void * val)90 int spm_update_rc_bus26m(int state_id, int type, const void *val)
91 {
92 	int res = MT_RM_STATUS_OK;
93 	uint32_t flag = *(uint32_t *)val;
94 
95 	if (type == PLAT_RC_UPDATE_REMAIN_IRQS) {
96 		refer2remain_irq = (struct mt_irqremain *)val;
97 	} else if (type == PLAT_RC_IS_FMAUDIO) {
98 		if (flag)
99 			bus26m_ext_opand |= MT_SPM_EX_OP_SET_IS_FM_AUDIO;
100 		else
101 			bus26m_ext_opand &= ~MT_SPM_EX_OP_SET_IS_FM_AUDIO;
102 	} else if (type == PLAT_RC_IS_ADSP) {
103 		if (flag)
104 			bus26m_ext_opand |= MT_SPM_EX_OP_SET_IS_ADSP;
105 		else
106 			bus26m_ext_opand &= ~MT_SPM_EX_OP_SET_IS_ADSP;
107 	} else if (type == PLAT_RC_IS_USB_HEADSET) {
108 		if (flag)
109 			bus26m_ext_opand |= MT_SPM_EX_OP_SET_IS_USB_HEADSET;
110 		else
111 			bus26m_ext_opand &= ~MT_SPM_EX_OP_SET_IS_USB_HEADSET;
112 	} else if (type == PLAT_RC_STATUS) {
113 		const struct rc_common_state *st;
114 
115 		st = (const struct rc_common_state *)val;
116 
117 		if (!st)
118 			return 0;
119 
120 		if ((st->type == CONSTRAINT_UPDATE_VALID) ||
121 			(st->type == CONSTRAINT_RESIDNECY))
122 			spm_rc_constraint_status_set(st->id,
123 						     st->type, st->act,
124 						     MT_RM_CONSTRAINT_ID_BUS26,
125 						     st->value,
126 						     &status);
127 		else
128 			INFO("[%s:%d] - Unknown type: 0x%x\n",
129 			     __func__, __LINE__, st->type);
130 	}
131 
132 	return res;
133 }
134 
spm_allow_rc_bus26m(int state_id)135 uint32_t spm_allow_rc_bus26m(int state_id)
136 {
137 	return CONSTRAINT_BUS26M_ALLOW;
138 }
139 
spm_run_rc_bus26m(uint32_t cpu,int state_id)140 int spm_run_rc_bus26m(uint32_t cpu, int state_id)
141 {
142 	uint32_t ext_op = MT_SPM_EX_OP_HW_S1_DETECT |
143 			  MT_SPM_EX_OP_NOTIFY_INFRA_OFF;
144 	uint32_t nb_type = MT_SPM_NOTIFY_IDLE_ENTER;
145 
146 	MT_SPM_RC_TAG(cpu, state_id, MT_RM_CONSTRAINT_ID_BUS26);
147 	MT_SPM_RC_TAG_VALID(status.is_valid);
148 	MT_SPM_RC_FP(MT_SPM_RC_FP_ENTER_START);
149 
150 	cmd = CONSTRAINT_BUS26M_ALLOW;
151 
152 	if (IS_PLAT_SUSPEND_ID(state_id)) {
153 		cmd |= (MT_RM_CONSTRAINT_ALLOW_AP_PLAT_SUSPEND |
154 			MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND);
155 		ext_op |= (MT_SPM_EX_OP_CLR_26M_RECORD |
156 			   MT_SPM_EX_OP_SET_WDT);
157 
158 		if (IS_MT_SPM_RC_NOTIFY_ENABLE(status.is_valid))
159 			mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_SUSPEND_VCORE, 0);
160 	} else {
161 		if (status.is_valid & MT_SPM_RC_VALID_TRACE_TIME)
162 			ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN;
163 	}
164 
165 #ifdef MTK_SPM_PMIC_LP_SUPPORT
166 	do_spm_low_power(SPM_LP_ENTER, cmd);
167 #endif
168 
169 	MT_SPM_RC_FP(MT_SPM_RC_FP_ENTER_NOTIFY);
170 
171 	if (IS_MT_SPM_RC_NOTIFY_ENABLE(status.is_valid))
172 		mt_spm_sspm_notify_u32(nb_type, cmd);
173 
174 	MT_SPM_RC_FP(MT_SPM_RC_FP_ENTER_WAKE_SPM_BEFORE);
175 
176 	if (IS_PLAT_SUSPEND_ID(state_id))
177 		mt_spm_suspend_enter(state_id, ext_op,
178 				     CONSTRAINT_BUS26M_RESOURCE_REQ);
179 	else
180 		mt_spm_idle_generic_enter(state_id, ext_op,
181 					  spm_bus26m_conduct);
182 
183 	MT_SPM_RC_FP(MT_SPM_RC_FP_ENTER_WAKE_SPM_AFTER);
184 	return 0;
185 }
186 
spm_reset_rc_bus26m(uint32_t cpu,int state_id)187 int spm_reset_rc_bus26m(uint32_t cpu, int state_id)
188 {
189 	struct wake_status *waken = NULL;
190 	uint32_t ext_op = MT_SPM_EX_OP_HW_S1_DETECT |
191 			  MT_SPM_EX_OP_NOTIFY_INFRA_OFF;
192 	uint32_t nb_type = MT_SPM_NOTIFY_IDLE_LEAVE;
193 
194 	MT_SPM_RC_FP(MT_SPM_RC_FP_RESUME_START);
195 
196 	if (IS_PLAT_SUSPEND_ID(state_id)) {
197 		ext_op |= MT_SPM_EX_OP_SET_WDT;
198 	} else {
199 		if (status.is_valid & MT_SPM_RC_VALID_TRACE_TIME)
200 			ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN;
201 
202 		if (spm_unlikely(status.is_valid &
203 				 MT_SPM_RC_VALID_TRACE_EVENT))
204 			ext_op |= MT_SPM_EX_OP_TRACE_LP;
205 	}
206 
207 #ifdef MTK_SPM_PMIC_LP_SUPPORT
208 	do_spm_low_power(SPM_LP_RESUME, cmd);
209 #endif
210 
211 	MT_SPM_RC_FP(MT_SPM_RC_FP_RESUME_NOTIFY);
212 
213 	if (IS_MT_SPM_RC_NOTIFY_ENABLE(status.is_valid))
214 		mt_spm_sspm_notify_u32(nb_type, 0);
215 
216 	MT_SPM_RC_FP(MT_SPM_RC_FP_RESUME_RESET_SPM_BEFORE);
217 
218 	if (IS_PLAT_SUSPEND_ID(state_id)) {
219 		mt_spm_suspend_resume(state_id, ext_op, &waken);
220 		bus26m_ext_opand = 0;
221 	} else {
222 		mt_spm_idle_generic_resume(state_id, ext_op, &waken, NULL);
223 		status.enter_cnt++;
224 
225 		if (spm_unlikely(status.is_valid & MT_SPM_RC_VALID_RESIDNECY))
226 			status.residency += waken ?
227 					    waken->tr.comm.timer_out : 0;
228 	}
229 
230 	MT_SPM_RC_FP(MT_SPM_RC_FP_RESUME_BACKUP_EDGE_INT);
231 	do_irqs_delivery(refer2remain_irq, waken);
232 	MT_SPM_RC_FP(MT_SPM_RC_FP_INIT);
233 	return 0;
234 }
235 
spm_get_status_rc_bus26m(uint32_t type,void * priv)236 int spm_get_status_rc_bus26m(uint32_t type, void *priv)
237 {
238 	int ret = MT_RM_STATUS_OK;
239 
240 	if (type == PLAT_RC_STATUS) {
241 		struct rc_common_state *st = (struct rc_common_state *)priv;
242 
243 		if (!st)
244 			return MT_RM_STATUS_BAD;
245 
246 		ret = spm_rc_constraint_status_get(st->id, st->type,
247 						   st->act,
248 						   MT_RM_CONSTRAINT_ID_BUS26,
249 						   &status,
250 						   st->value);
251 		if (!ret && (st->id != MT_RM_CONSTRAINT_ID_ALL))
252 			ret = MT_RM_STATUS_STOP;
253 	}
254 	return ret;
255 }
256