xref: /rk3399_ARM-atf/plat/mediatek/drivers/spm/mt8196/mt_spm_hwreq.c (revision b47dddd061e92054c3b2096fc8aa9688bfef68d6)
1 /*
2  * Copyright (c) 2025, Mediatek Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <common/debug.h>
8 #include <lib/mmio.h>
9 #include <platform_def.h>
10 
11 #include <mt_spm_hwreq.h>
12 #include <mt_spm_reg.h>
13 
14 /* Ddren, apsrc and emi resource have become hw resource_req.
15  * So we don't need to use HW CG for request resource.
16  */
17 #define SPM_HWCG_DDREN_PWR_MB		0
18 #define SPM_HWCG_DDREN_PWR_MSB_MB	0
19 #define SPM_HWCG_DDREN_MODULE_BUSY_MB	0
20 
21 /* VRF18 */
22 #define SPM_HWCG_VRF18_PWR_MB		0
23 #define SPM_HWCG_VRF18_PWR_MSB_MB	0
24 #define SPM_HWCG_VRF18_MODULE_BUSY_MB	0
25 
26 /* INFRA */
27 #define SPM_HWCG_INFRA_PWR_MB		SPM_HWCG_VRF18_PWR_MB
28 #define SPM_HWCG_INFRA_PWR_MSB_MB	SPM_HWCG_VRF18_PWR_MSB_MB
29 #define SPM_HWCG_INFRA_MODULE_BUSY_MB	0
30 
31 /* PMIC */
32 #define SPM_HWCG_PMIC_PWR_MB		SPM_HWCG_VRF18_PWR_MB
33 #define SPM_HWCG_PMIC_PWR_MSB_MB	SPM_HWCG_VRF18_PWR_MSB_MB
34 #define SPM_HWCG_PMIC_MODULE_BUSY_MB	0
35 
36 /* F26M */
37 #define SPM_HWCG_F26M_PWR_MB		SPM_HWCG_PMIC_PWR_MB
38 #define SPM_HWCG_F26M_PWR_MSB_MB	SPM_HWCG_PMIC_PWR_MSB_MB
39 #define SPM_HWCG_F26M_MODULE_BUSY_MB	0
40 
41 /* VCORE */
42 #define SPM_HWCG_VCORE_PWR_MB		SPM_HWCG_F26M_PWR_MB
43 #define SPM_HWCG_VCORE_PWR_MSB_MB	SPM_HWCG_F26M_PWR_MSB_MB
44 #define SPM_HWCG_VCORE_MODULE_BUSY_MB	SPM_HWCG_F26M_MODULE_BUSY_MB
45 
46 #define INFRA_SW_CG_MB			0
47 
48 struct spm_hwcg_info {
49 	uint32_t pwr;
50 	uint32_t pwr_msb;
51 	uint32_t module_busy;
52 };
53 
54 #define HWCG_INFO_INIT(_info) ({ \
55 	_info.pwr = _info.pwr_msb = _info.module_busy = 0; })
56 
57 #define DECLARE_HWCG_REG(_name_, _info) ({ \
58 	_info.pwr = REG_PWR_STATUS_##_name_##_REQ_MASK; \
59 	_info.pwr_msb = REG_PWR_STATUS_MSB_##_name_##_REQ_MASK; \
60 	_info.module_busy = REG_MODULE_BUSY_##_name_##_REQ_MASK; })
61 
62 #define DECLARE_HWCG_DEFAULT(_name_, _info) ({ \
63 	_info.pwr = SPM_HWCG_##_name_##_PWR_MB; \
64 	_info.pwr_msb = SPM_HWCG_##_name_##_PWR_MSB_MB; \
65 	_info.module_busy = SPM_HWCG_##_name_##_MODULE_BUSY_MB; })
66 
67 #define PERI_REQ_EN_INFO_INIT(_info) ({_info.req_en = 0; })
68 
69 #define PERI_REQ_STA_INFO_INIT(_info) ({_info.req_sta = 0; })
70 
71 #define DECLARE_PERI_REQ_EN_REG(_offset, _info) ({ \
72 	_info.req_en = REG_PERI_REQ_EN(_offset); })
73 
74 #define DECLARE_PERI_REQ_STA_REG(_offset, _info) ({ \
75 	_info.req_sta = REG_PERI_REQ_STA(_offset); })
76 
77 #define DECLARE_PERI_REQ_DEFAULT(_name_, _info) ({ \
78 	_info.req_en = PERI_REQ_##_name_##_MB; })
79 
80 #define PERI_REQ_EN_MASK		0x3FFFFF
81 
82 static uint32_t spm_hwcg_index2res(uint32_t idx)
83 {
84 	uint32_t res;
85 
86 	if (idx >= HWCG_MAX)
87 		return 0;
88 
89 	switch (idx) {
90 	case HWCG_DDREN:
91 		res = (MT_SPM_DRAM_S0 | MT_SPM_DRAM_S1 | MT_SPM_EMI);
92 		break;
93 	case HWCG_VRF18:
94 		res = MT_SPM_SYSPLL;
95 		break;
96 	case HWCG_INFRA:
97 		res = MT_SPM_INFRA;
98 		break;
99 	case HWCG_PMIC:
100 		res = MT_SPM_PMIC;
101 		break;
102 	case HWCG_F26M:
103 		res = MT_SPM_26M;
104 		break;
105 	case HWCG_VCORE:
106 		res = MT_SPM_VCORE;
107 		break;
108 	default:
109 		res = 0;
110 	}
111 	return res;
112 }
113 
114 static uint32_t spm_hwcg_ctrl_get(struct spm_hwcg_info *info,
115 				  enum spm_hwcg_setting type)
116 {
117 	uint32_t reg = 0;
118 
119 	if (!info)
120 		return 0;
121 
122 	switch (type) {
123 	case HWCG_PWR:
124 		reg = info->pwr;
125 		break;
126 	case HWCG_PWR_MSB:
127 		reg = info->pwr_msb;
128 		break;
129 	default:
130 		reg = info->module_busy;
131 		break;
132 	}
133 	return reg;
134 }
135 
136 static void __spm_hwcg_ctrl(struct spm_hwcg_info *info,
137 			    enum spm_hwcg_setting type,
138 			    uint32_t is_set, uint32_t val)
139 {
140 	uint32_t reg;
141 
142 	reg = spm_hwcg_ctrl_get(info, type);
143 
144 	if (!reg)
145 		return;
146 
147 	if (is_set)
148 		mmio_setbits_32(reg, val);
149 	else
150 		mmio_clrbits_32(reg, val);
151 }
152 
153 void spm_hwcg_ctrl(uint32_t res, enum spm_hwcg_setting type,
154 		   uint32_t is_set, uint32_t val)
155 {
156 	struct spm_hwcg_info info;
157 
158 	if (res & (MT_SPM_DRAM_S0 | MT_SPM_DRAM_S1 | MT_SPM_EMI))
159 		DECLARE_HWCG_REG(DDREN, info);
160 	else if (res & MT_SPM_SYSPLL)
161 		DECLARE_HWCG_REG(VRF18, info);
162 	else if (res & MT_SPM_INFRA)
163 		DECLARE_HWCG_REG(INFRA, info);
164 	else if (res & MT_SPM_PMIC)
165 		DECLARE_HWCG_REG(PMIC, info);
166 	else if (res & MT_SPM_26M)
167 		DECLARE_HWCG_REG(F26M, info);
168 	else if (res & MT_SPM_VCORE)
169 		DECLARE_HWCG_REG(VCORE, info);
170 	else
171 		HWCG_INFO_INIT(info);
172 
173 	if (info.pwr)
174 		__spm_hwcg_ctrl(&info, type, is_set, val);
175 }
176 
177 void spm_hwcg_ctrl_by_index(uint32_t idx, enum spm_hwcg_setting type,
178 			    uint32_t is_set, uint32_t val)
179 {
180 	uint32_t res = spm_hwcg_index2res(idx);
181 
182 	if (res)
183 		spm_hwcg_ctrl(res, type, is_set, val);
184 }
185 
186 static uint32_t spm_hwcg_mask_get(uint32_t res, enum spm_hwcg_setting type)
187 {
188 	struct spm_hwcg_info info;
189 	uint32_t raw_val = 0, reg = 0;
190 
191 	if (res & (MT_SPM_DRAM_S0 | MT_SPM_DRAM_S1 | MT_SPM_EMI))
192 		DECLARE_HWCG_REG(DDREN, info);
193 	else if (res & MT_SPM_SYSPLL)
194 		DECLARE_HWCG_REG(VRF18, info);
195 	else if (res & MT_SPM_INFRA)
196 		DECLARE_HWCG_REG(INFRA, info);
197 	else if (res & MT_SPM_PMIC)
198 		DECLARE_HWCG_REG(PMIC, info);
199 	else if (res & MT_SPM_26M)
200 		DECLARE_HWCG_REG(F26M, info);
201 	else if (res & MT_SPM_VCORE)
202 		DECLARE_HWCG_REG(VCORE, info);
203 	else
204 		HWCG_INFO_INIT(info);
205 
206 	if (!info.pwr)
207 		return 0;
208 
209 	reg = spm_hwcg_ctrl_get(&info, type);
210 
211 	if (!reg)
212 		return 0;
213 
214 	raw_val = ~mmio_read_32(reg);
215 
216 	return raw_val;
217 }
218 
219 static uint32_t spm_hwcg_get_default(uint32_t res, enum spm_hwcg_setting type)
220 {
221 	struct spm_hwcg_info info;
222 
223 	if (res & (MT_SPM_DRAM_S0 | MT_SPM_DRAM_S1 | MT_SPM_EMI))
224 		DECLARE_HWCG_DEFAULT(DDREN, info);
225 	else if (res & MT_SPM_SYSPLL)
226 		DECLARE_HWCG_DEFAULT(VRF18, info);
227 	else if (res & MT_SPM_INFRA)
228 		DECLARE_HWCG_DEFAULT(INFRA, info);
229 	else if (res & MT_SPM_PMIC)
230 		DECLARE_HWCG_DEFAULT(PMIC, info);
231 	else if (res & MT_SPM_26M)
232 		DECLARE_HWCG_DEFAULT(F26M, info);
233 	else if (res & MT_SPM_VCORE)
234 		DECLARE_HWCG_DEFAULT(VCORE, info);
235 	else
236 		HWCG_INFO_INIT(info);
237 
238 	if (!info.pwr)
239 		return 0;
240 
241 	return spm_hwcg_ctrl_get(&info, type);
242 }
243 
244 uint32_t spm_hwcg_get_status(uint32_t idx, enum spm_hwcg_setting type)
245 {
246 	uint32_t val = 0;
247 
248 	switch (type) {
249 	case HWCG_PWR:
250 		val = mmio_read_32(PWR_STATUS);
251 		break;
252 	case HWCG_PWR_MSB:
253 		val = mmio_read_32(PWR_STATUS_MSB);
254 		break;
255 	default:
256 		break;
257 	}
258 	return val;
259 }
260 
261 int spm_hwcg_get_setting(uint32_t res, enum spm_hwcg_sta_type sta_type,
262 			 enum spm_hwcg_setting type,
263 			 struct spm_hwcg_sta *sta)
264 {
265 	int ret = 0;
266 
267 	if (!sta)
268 		return -1;
269 
270 	switch (sta_type) {
271 	case HWCG_STA_DEFAULT_MASK:
272 		sta->sta = spm_hwcg_get_default(res, type);
273 		break;
274 	case HWCG_STA_MASK:
275 		sta->sta = spm_hwcg_mask_get(res, type);
276 		break;
277 	default:
278 		ret = -1;
279 		MT_SPM_HW_CG_STA_INIT(sta);
280 		break;
281 	}
282 	return ret;
283 }
284 
285 int spm_hwcg_get_setting_by_index(uint32_t idx,
286 				  enum spm_hwcg_sta_type sta_type,
287 				  enum spm_hwcg_setting type,
288 				  struct spm_hwcg_sta *sta)
289 {
290 	uint32_t res = spm_hwcg_index2res(idx);
291 
292 	return spm_hwcg_get_setting(res, sta_type, type, sta);
293 }
294 
295 int spm_hwcg_name(uint32_t idex, char *name, size_t sz)
296 {
297 	int ret = 0;
298 
299 	if (!name)
300 		return -1;
301 
302 	switch (idex) {
303 	case HWCG_DDREN:
304 		ret = snprintf(name, sz - 1, "dram");
305 		break;
306 	case HWCG_VRF18:
307 		ret = snprintf(name, sz - 1, "vrf18");
308 		break;
309 	case HWCG_INFRA:
310 		ret = snprintf(name, sz - 1, "infra");
311 		break;
312 	case HWCG_PMIC:
313 		ret = snprintf(name, sz - 1, "pmic");
314 		break;
315 	case HWCG_F26M:
316 		ret = snprintf(name, sz - 1, "26m");
317 		break;
318 	case HWCG_VCORE:
319 		ret = snprintf(name, sz - 1, "vcore");
320 		break;
321 	default:
322 		ret = -1;
323 		break;
324 	}
325 
326 	if (ret < 0)
327 		ret = -1;
328 
329 	name[sz-1] = '\0';
330 
331 	return ret;
332 }
333 
334 static void spm_infra_swcg_init(void)
335 {
336 	mmio_write_32(INFRA_SW_CG_MASK, ~INFRA_SW_CG_MB);
337 }
338 
339 static void spm_hwcg_init(void)
340 {
341 	/* HW CG for ddren, apsrc, emi resource req */
342 	mmio_write_32(REG_PWR_STATUS_DDREN_REQ_MASK,
343 		      ~SPM_HWCG_DDREN_PWR_MB);
344 	mmio_write_32(REG_PWR_STATUS_MSB_DDREN_REQ_MASK,
345 		      ~SPM_HWCG_DDREN_PWR_MSB_MB);
346 	mmio_write_32(REG_MODULE_BUSY_DDREN_REQ_MASK,
347 		      ~SPM_HWCG_DDREN_MODULE_BUSY_MB);
348 
349 	/* HW CG for vrf18 resource req */
350 	mmio_write_32(REG_PWR_STATUS_VRF18_REQ_MASK,
351 		      ~SPM_HWCG_VRF18_PWR_MB);
352 	mmio_write_32(REG_PWR_STATUS_MSB_VRF18_REQ_MASK,
353 		      ~SPM_HWCG_VRF18_PWR_MSB_MB);
354 	mmio_write_32(REG_MODULE_BUSY_VRF18_REQ_MASK,
355 		      ~SPM_HWCG_VRF18_MODULE_BUSY_MB);
356 
357 	/* HW CG for infra resource req */
358 	mmio_write_32(REG_PWR_STATUS_INFRA_REQ_MASK,
359 		      ~SPM_HWCG_INFRA_PWR_MB);
360 	mmio_write_32(REG_PWR_STATUS_MSB_INFRA_REQ_MASK,
361 		      ~SPM_HWCG_INFRA_PWR_MSB_MB);
362 	mmio_write_32(REG_MODULE_BUSY_INFRA_REQ_MASK,
363 		      ~SPM_HWCG_INFRA_MODULE_BUSY_MB);
364 
365 	/* HW CG for pmic resource req */
366 	mmio_write_32(REG_PWR_STATUS_PMIC_REQ_MASK,
367 		      ~SPM_HWCG_PMIC_PWR_MB);
368 	mmio_write_32(REG_PWR_STATUS_MSB_PMIC_REQ_MASK,
369 		      ~SPM_HWCG_PMIC_PWR_MSB_MB);
370 	mmio_write_32(REG_MODULE_BUSY_PMIC_REQ_MASK,
371 		      ~SPM_HWCG_PMIC_MODULE_BUSY_MB);
372 
373 	/* HW CG for f26m resource req */
374 	mmio_write_32(REG_PWR_STATUS_F26M_REQ_MASK,
375 		      ~SPM_HWCG_F26M_PWR_MB);
376 	mmio_write_32(REG_PWR_STATUS_MSB_F26M_REQ_MASK,
377 		      ~SPM_HWCG_F26M_PWR_MSB_MB);
378 	mmio_write_32(REG_MODULE_BUSY_F26M_REQ_MASK,
379 		      ~SPM_HWCG_F26M_MODULE_BUSY_MB);
380 
381 	/* HW CG for vcore resource req */
382 	mmio_write_32(REG_PWR_STATUS_VCORE_REQ_MASK,
383 		      ~SPM_HWCG_VCORE_PWR_MB);
384 	mmio_write_32(REG_PWR_STATUS_MSB_VCORE_REQ_MASK,
385 		      ~SPM_HWCG_VCORE_PWR_MSB_MB);
386 	mmio_write_32(REG_MODULE_BUSY_VCORE_REQ_MASK,
387 		      ~SPM_HWCG_VCORE_MODULE_BUSY_MB);
388 }
389 
390 #define PERI_CG(ofs)		(PERICFG_AO_BASE + 0x10 + (0x4 * (ofs)))
391 #define PERI_REQ_DEFAULT_MB	(BIT(PERI_REQ_EN_FLASHIF) | \
392 				 BIT(PERI_REQ_EN_AP_DMA) | \
393 				 BIT(PERI_REQ_EN_UART1) | \
394 				 BIT(PERI_REQ_EN_UART2) | \
395 				 BIT(PERI_REQ_EN_UART4) | \
396 				 BIT(PERI_REQ_EN_UART5) | \
397 				 BIT(PERI_REQ_EN_PWM) | \
398 				 BIT(PERI_REQ_EN_SPI0) | \
399 				 BIT(PERI_REQ_EN_SPI0_INCR16) | \
400 				 BIT(PERI_REQ_EN_SPI1) | \
401 				 BIT(PERI_REQ_EN_SPI2) | \
402 				 BIT(PERI_REQ_EN_SPI3) | \
403 				 BIT(PERI_REQ_EN_SPI4) | \
404 				 BIT(PERI_REQ_EN_SPI5) | \
405 				 BIT(PERI_REQ_EN_SPI6) | \
406 				 BIT(PERI_REQ_EN_SPI7) | \
407 				 BIT(PERI_REQ_EN_IMP_IIC))
408 
409 /* For MSDC reqesut WA: PERI_REQ_EN_RSV_FOR_MSDC */
410 #define PERI_REQ_APSRC_MB		(PERI_REQ_DEFAULT_MB | \
411 					 BIT(PERI_REQ_EN_RSV_FOR_MSDC))
412 
413 #define PERI_REQ_DDREN_MB		(PERI_REQ_DEFAULT_MB | \
414 					 BIT(PERI_REQ_EN_USB) | \
415 					 BIT(PERI_REQ_EN_UFS0) | \
416 					 BIT(PERI_REQ_EN_PEXTP1) | \
417 					 BIT(PERI_REQ_EN_PEXTP0) | \
418 					 BIT(PERI_REQ_EN_PERI_BUS_TRAFFIC))
419 #define PERI_REQ_EMI_MB		(PERI_REQ_DEFAULT_MB)
420 #define PERI_REQ_INFRA_MB	(PERI_REQ_DEFAULT_MB)
421 #define PERI_REQ_SYSPLL_MB	(PERI_REQ_DEFAULT_MB)
422 #define PERI_REQ_F26M_MB	(PERI_REQ_DEFAULT_MB)
423 
424 uint32_t spm_peri_req_get_status(uint32_t idx, enum spm_peri_req_status type)
425 {
426 	uint32_t val = 0, reg = 0;
427 	struct spm_peri_req_info info;
428 
429 	switch (type) {
430 	case PERI_RES_REQ_EN:
431 
432 		switch (idx) {
433 		case PERI_REQ_DDREN:
434 			DECLARE_PERI_REQ_STA_REG(PERI_REQ_DDREN, info);
435 
436 			break;
437 		case PERI_REQ_EMI:
438 			DECLARE_PERI_REQ_STA_REG(PERI_REQ_EMI, info);
439 
440 			break;
441 		case PERI_REQ_APSRC:
442 			DECLARE_PERI_REQ_STA_REG(PERI_REQ_APSRC, info);
443 
444 			break;
445 		case PERI_REQ_SYSPLL:
446 			DECLARE_PERI_REQ_STA_REG(PERI_REQ_SYSPLL, info);
447 
448 			break;
449 		case PERI_REQ_INFRA:
450 			DECLARE_PERI_REQ_STA_REG(PERI_REQ_INFRA, info);
451 
452 			break;
453 		case PERI_REQ_F26M:
454 			DECLARE_PERI_REQ_STA_REG(PERI_REQ_F26M, info);
455 
456 			break;
457 		default:
458 			PERI_REQ_STA_INFO_INIT(info);
459 			break;
460 		}
461 
462 		if (!info.req_sta)
463 			return 0;
464 
465 		reg = info.req_sta;
466 		val = (mmio_read_32(reg) & PERI_REQ_EN_MASK);
467 
468 		break;
469 	default:
470 		break;
471 	}
472 	return val;
473 }
474 
475 int spm_peri_req_name(uint32_t idex, char *name, size_t sz)
476 {
477 	int ret = 0;
478 
479 	if (!name)
480 		return -1;
481 
482 	switch (idex) {
483 	case PERI_REQ_DDREN:
484 		ret = snprintf(name, sz - 1, "ddren");
485 		break;
486 	case PERI_REQ_EMI:
487 		ret = snprintf(name, sz - 1, "emi");
488 		break;
489 	case PERI_REQ_APSRC:
490 		ret = snprintf(name, sz - 1, "apsrc");
491 		break;
492 	case PERI_REQ_SYSPLL:
493 		ret = snprintf(name, sz - 1, "syspll");
494 		break;
495 	case PERI_REQ_INFRA:
496 		ret = snprintf(name, sz - 1, "infra");
497 		break;
498 	case PERI_REQ_F26M:
499 		ret = snprintf(name, sz - 1, "26m_pmic_vcore");
500 		break;
501 	default:
502 		ret = -1;
503 		break;
504 	}
505 
506 	if (ret < 0)
507 		ret = -1;
508 
509 	name[sz-1] = '\0';
510 
511 	return ret;
512 }
513 
514 uint32_t spm_peri_req_get_status_raw(enum spm_peri_req_status_raw type,
515 				     uint32_t idx,
516 				     char *name, size_t sz)
517 {
518 	return 0;
519 }
520 
521 static uint32_t spm_peri_req_get_default(uint32_t res)
522 {
523 	struct spm_peri_req_info info;
524 
525 	if (res & MT_SPM_DRAM_S1)
526 		DECLARE_PERI_REQ_DEFAULT(DDREN, info);
527 	else if (res & MT_SPM_EMI)
528 		DECLARE_PERI_REQ_DEFAULT(EMI, info);
529 	else if (res & MT_SPM_DRAM_S0)
530 		DECLARE_PERI_REQ_DEFAULT(APSRC, info);
531 	else if (res & MT_SPM_SYSPLL)
532 		DECLARE_PERI_REQ_DEFAULT(SYSPLL, info);
533 	else if (res & MT_SPM_INFRA)
534 		DECLARE_PERI_REQ_DEFAULT(INFRA, info);
535 	else if (res & (MT_SPM_PMIC | MT_SPM_26M | MT_SPM_VCORE))
536 		DECLARE_PERI_REQ_DEFAULT(F26M, info);
537 	else
538 		PERI_REQ_EN_INFO_INIT(info);
539 
540 	return info.req_en;
541 }
542 
543 static uint32_t spm_peri_req_mask_get(uint32_t res)
544 {
545 	struct spm_peri_req_info info;
546 	uint32_t raw_val = 0, reg = 0;
547 
548 	if (res & MT_SPM_DRAM_S1)
549 		DECLARE_PERI_REQ_EN_REG(PERI_REQ_DDREN, info);
550 	else if (res & MT_SPM_EMI)
551 		DECLARE_PERI_REQ_EN_REG(PERI_REQ_EMI, info);
552 	else if (res & MT_SPM_DRAM_S0)
553 		DECLARE_PERI_REQ_EN_REG(PERI_REQ_APSRC, info);
554 	else if (res & MT_SPM_SYSPLL)
555 		DECLARE_PERI_REQ_EN_REG(PERI_REQ_SYSPLL, info);
556 	else if (res & MT_SPM_INFRA)
557 		DECLARE_PERI_REQ_EN_REG(PERI_REQ_INFRA, info);
558 	else if (res & (MT_SPM_PMIC | MT_SPM_26M | MT_SPM_VCORE))
559 		DECLARE_PERI_REQ_EN_REG(PERI_REQ_F26M, info);
560 	else
561 		PERI_REQ_EN_INFO_INIT(info);
562 
563 	if (!info.req_en)
564 		return 0;
565 
566 	reg = info.req_en;
567 
568 	raw_val = (mmio_read_32(reg) & PERI_REQ_EN_MASK);
569 
570 	return raw_val;
571 }
572 
573 int spm_peri_req_get_setting(uint32_t res,
574 			     enum spm_peri_req_sta_type sta_type,
575 			     struct spm_peri_req_sta *sta)
576 {
577 	int ret = 0;
578 
579 	if (!sta)
580 		return -1;
581 
582 	switch (sta_type) {
583 	case PERI_REQ_STA_DEFAULT_MASK:
584 		sta->sta = spm_peri_req_get_default(res);
585 		break;
586 	case PERI_REQ_STA_MASK:
587 		sta->sta = spm_peri_req_mask_get(res);
588 		break;
589 	default:
590 		ret = -1;
591 		MT_SPM_HW_CG_STA_INIT(sta);
592 		break;
593 	}
594 	return ret;
595 }
596 
597 static uint32_t spm_peri_req_index2res(uint32_t idx)
598 {
599 	uint32_t res;
600 
601 	if (idx >= PERI_REQ_MAX)
602 		return 0;
603 
604 	switch (idx) {
605 	case PERI_REQ_DDREN:
606 		res = MT_SPM_DRAM_S1;
607 		break;
608 	case PERI_REQ_EMI:
609 		res = MT_SPM_EMI;
610 		break;
611 	case PERI_REQ_APSRC:
612 		res = MT_SPM_DRAM_S0;
613 		break;
614 	case PERI_REQ_SYSPLL:
615 		res = MT_SPM_SYSPLL;
616 		break;
617 	case PERI_REQ_INFRA:
618 		res = MT_SPM_INFRA;
619 		break;
620 	case PERI_REQ_F26M:
621 		res = (MT_SPM_PMIC | MT_SPM_26M | MT_SPM_VCORE);
622 		break;
623 	default:
624 		res = 0;
625 	}
626 	return res;
627 
628 }
629 
630 int spm_peri_req_get_setting_by_index(uint32_t idx,
631 				      enum spm_peri_req_sta_type sta_type,
632 				      struct spm_peri_req_sta *sta)
633 {
634 	uint32_t res = spm_peri_req_index2res(idx);
635 
636 	return spm_peri_req_get_setting(res, sta_type, sta);
637 }
638 
639 static void __spm_peri_req_ctrl(struct spm_peri_req_info *info,
640 				uint32_t is_set, uint32_t val)
641 {
642 	uint32_t raw_val, reg;
643 
644 	reg = info->req_en;
645 
646 	if (!reg)
647 		return;
648 
649 	raw_val = (mmio_read_32(reg) & PERI_REQ_EN_MASK);
650 
651 	if (is_set)
652 		raw_val |= val;
653 	else
654 		raw_val &= ~val;
655 
656 	mmio_write_32(reg, raw_val);
657 }
658 
659 void spm_peri_req_ctrl(uint32_t res,
660 		       uint32_t is_set, uint32_t val)
661 {
662 	struct spm_peri_req_info info;
663 
664 	if (res & MT_SPM_DRAM_S1)
665 		DECLARE_PERI_REQ_EN_REG(PERI_REQ_DDREN, info);
666 	else if (res & MT_SPM_EMI)
667 		DECLARE_PERI_REQ_EN_REG(PERI_REQ_EMI, info);
668 	else if (res & MT_SPM_DRAM_S0)
669 		DECLARE_PERI_REQ_EN_REG(PERI_REQ_APSRC, info);
670 	else if (res & MT_SPM_SYSPLL)
671 		DECLARE_PERI_REQ_EN_REG(PERI_REQ_SYSPLL, info);
672 	else if (res & MT_SPM_INFRA)
673 		DECLARE_PERI_REQ_EN_REG(PERI_REQ_INFRA, info);
674 	else if (res & (MT_SPM_PMIC | MT_SPM_26M | MT_SPM_VCORE))
675 		DECLARE_PERI_REQ_EN_REG(PERI_REQ_F26M, info);
676 	else
677 		PERI_REQ_EN_INFO_INIT(info);
678 
679 	if (info.req_en)
680 		__spm_peri_req_ctrl(&info, is_set, val);
681 }
682 
683 void spm_peri_req_ctrl_by_index(uint32_t idx,
684 				uint32_t is_set, uint32_t val)
685 {
686 	uint32_t res = spm_peri_req_index2res(idx);
687 
688 	if (res)
689 		spm_peri_req_ctrl(res, is_set, val);
690 }
691 
692 static void spm_peri_req_init(void)
693 {
694 	mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_DDREN), PERI_REQ_DDREN_MB);
695 	mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_EMI), PERI_REQ_EMI_MB);
696 	mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_APSRC), PERI_REQ_APSRC_MB);
697 	mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_INFRA), PERI_REQ_INFRA_MB);
698 	mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_SYSPLL), PERI_REQ_SYSPLL_MB);
699 	mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_F26M), PERI_REQ_F26M_MB);
700 }
701 
702 void spm_hwreq_init(void)
703 {
704 	spm_infra_swcg_init();
705 	spm_hwcg_init();
706 	spm_peri_req_init();
707 }
708