xref: /rk3399_ARM-atf/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c (revision b67e984664a8644d6cfd1812cabaa02cf24f09c9)
1 /*
2  * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
3  * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 /*
9  * ZynqMP system level PM-API functions for ioctl.
10  */
11 
12 #include <arch_helpers.h>
13 #include <drivers/delay_timer.h>
14 #include <lib/mmio.h>
15 #include <plat/common/platform.h>
16 
17 #include "pm_api_clock.h"
18 #include "pm_api_ioctl.h"
19 #include "pm_client.h"
20 #include "pm_common.h"
21 #include "pm_ipi.h"
22 #include <zynqmp_def.h>
23 #include "zynqmp_pm_api_sys.h"
24 
25 /**
26  * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode.
27  * @mode: Buffer to store value of oper mode(Split/Lock-step)
28  *
29  * This function provides current configured RPU operational mode.
30  *
31  * Return: Returns status, either success or error+reason.
32  *
33  */
34 static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(uint32_t *mode)
35 {
36 	uint32_t val;
37 
38 	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
39 	val &= ZYNQMP_SLSPLIT_MASK;
40 	if (val == 0U) {
41 		*mode = PM_RPU_MODE_LOCKSTEP;
42 	} else {
43 		*mode = PM_RPU_MODE_SPLIT;
44 	}
45 
46 	return PM_RET_SUCCESS;
47 }
48 
49 /**
50  * pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode.
51  * @mode: Value to set for oper mode(Split/Lock-step).
52  *
53  * This function configures RPU operational mode(Split/Lock-step).
54  * It also sets TCM combined mode in RPU lock-step and TCM non-combined
55  * mode for RPU split mode. In case of Lock step mode, RPU1's output is
56  * clamped.
57  *
58  * Return: Returns status, either success or error+reason.
59  *
60  */
61 static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(uint32_t mode)
62 {
63 	uint32_t val;
64 	enum pm_ret_status status = PM_RET_SUCCESS;
65 
66 	if ((mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET) != 0U) {
67 		status = PM_RET_ERROR_ACCESS;
68 		goto exit_label;
69 	}
70 
71 	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
72 
73 	if (mode == PM_RPU_MODE_SPLIT) {
74 		val |= ZYNQMP_SLSPLIT_MASK;
75 		val &= ~ZYNQMP_TCM_COMB_MASK;
76 		val &= ~ZYNQMP_SLCLAMP_MASK;
77 	} else if (mode == PM_RPU_MODE_LOCKSTEP) {
78 		val &= ~ZYNQMP_SLSPLIT_MASK;
79 		val |= ZYNQMP_TCM_COMB_MASK;
80 		val |= ZYNQMP_SLCLAMP_MASK;
81 	} else {
82 		status = PM_RET_ERROR_ARGS;
83 		goto exit_label;
84 	}
85 
86 	mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
87 
88 exit_label:
89 	return status;
90 }
91 
92 /**
93  * pm_ioctl_config_boot_addr() - Configure RPU boot address.
94  * @nid: Node ID of RPU.
95  * @value: Value to set for boot address (TCM/OCM).
96  *
97  * This function configures RPU boot address(memory).
98  *
99  * Return: Returns status, either success or error+reason.
100  *
101  */
102 static enum pm_ret_status pm_ioctl_config_boot_addr(enum pm_node_id nid,
103 						    uint32_t value)
104 {
105 	uint32_t rpu_cfg_addr, val;
106 
107 	if (nid == NODE_RPU_0) {
108 		rpu_cfg_addr = ZYNQMP_RPU0_CFG;
109 	} else if (nid == NODE_RPU_1) {
110 		rpu_cfg_addr = ZYNQMP_RPU1_CFG;
111 	} else {
112 		return PM_RET_ERROR_ARGS;
113 	}
114 
115 	val = mmio_read_32(rpu_cfg_addr);
116 
117 	if (value == PM_RPU_BOOTMEM_LOVEC) {
118 		val &= ~ZYNQMP_VINITHI_MASK;
119 	} else if (value == PM_RPU_BOOTMEM_HIVEC) {
120 		val |= ZYNQMP_VINITHI_MASK;
121 	} else {
122 		return PM_RET_ERROR_ARGS;
123 	}
124 
125 	mmio_write_32(rpu_cfg_addr, val);
126 
127 	return PM_RET_SUCCESS;
128 }
129 
130 /**
131  * pm_ioctl_config_tcm_comb() - Configure TCM combined mode.
132  * @value: Value to set (Split/Combined).
133  *
134  * This function configures TCM to be in split mode or combined
135  * mode.
136  *
137  * Return: Returns status, either success or error+reason.
138  *
139  */
140 static enum pm_ret_status pm_ioctl_config_tcm_comb(uint32_t value)
141 {
142 	uint32_t val;
143 	enum pm_ret_status status = PM_RET_SUCCESS;
144 
145 	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
146 
147 	if (value == PM_RPU_TCM_SPLIT) {
148 		val &= ~ZYNQMP_TCM_COMB_MASK;
149 	} else if (value == PM_RPU_TCM_COMB) {
150 		val |= ZYNQMP_TCM_COMB_MASK;
151 	} else {
152 		status = PM_RET_ERROR_ARGS;
153 		goto exit_label;
154 	}
155 
156 	mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
157 
158 exit_label:
159 	return status;
160 }
161 
162 /**
163  * pm_ioctl_set_tapdelay_bypass() -  Enable/Disable tap delay bypass.
164  * @type: Type of tap delay to enable/disable (e.g. QSPI).
165  * @value: Enable/Disable.
166  * @flag: 0 - Call from secure source.
167  *	  1 - Call from non-secure source.
168  *
169  * This function enable/disable tap delay bypass.
170  *
171  * Return: Returns status, either success or error+reason.
172  *
173  */
174 static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(uint32_t type,
175 						       uint32_t value,
176 						       uint32_t flag)
177 {
178 	enum pm_ret_status status = PM_RET_SUCCESS;
179 
180 	if ((((value != PM_TAPDELAY_BYPASS_ENABLE) &&
181 	     (value != PM_TAPDELAY_BYPASS_DISABLE)) || (type >= PM_TAPDELAY_MAX))) {
182 		status = PM_RET_ERROR_ARGS;
183 	} else {
184 		status = pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK,
185 				       value << type, flag);
186 	}
187 
188 	return status;
189 }
190 
191 /**
192  * pm_ioctl_sd_dll_reset() -  Reset DLL logic.
193  * @nid: Node ID of the device.
194  * @type: Reset type.
195  * @flag: 0 - Call from secure source.
196  *	  1 - Call from non-secure source.
197  *
198  * This function resets DLL logic for the SD device.
199  *
200  * Return: Returns status, either success or error+reason.
201  *
202  */
203 static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid,
204 						uint32_t type,
205 						uint32_t flag)
206 {
207 	uint32_t mask, val;
208 	enum pm_ret_status ret;
209 
210 	if (nid == NODE_SD_0) {
211 		mask = ZYNQMP_SD0_DLL_RST_MASK;
212 		val = ZYNQMP_SD0_DLL_RST;
213 	} else if (nid == NODE_SD_1) {
214 		mask = ZYNQMP_SD1_DLL_RST_MASK;
215 		val = ZYNQMP_SD1_DLL_RST;
216 	} else {
217 		return PM_RET_ERROR_ARGS;
218 	}
219 
220 	switch (type) {
221 	case PM_DLL_RESET_ASSERT:
222 	case PM_DLL_RESET_PULSE:
223 		ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, val, flag);
224 		if (ret != PM_RET_SUCCESS) {
225 			return ret;
226 		}
227 
228 		if (type == PM_DLL_RESET_ASSERT) {
229 			break;
230 		}
231 		mdelay(1);
232 		/* Fallthrough */
233 	case PM_DLL_RESET_RELEASE:
234 		ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, 0, flag);
235 		break;
236 	default:
237 		ret = PM_RET_ERROR_ARGS;
238 		break;
239 	}
240 
241 	return ret;
242 }
243 
244 /**
245  * pm_ioctl_sd_set_tapdelay() -  Set tap delay for the SD device.
246  * @nid: Node ID of the device.
247  * @type: Type of tap delay to set (input/output).
248  * @value: Value to set fot the tap delay.
249  * @flag: 0 - Call from secure source.
250  *	  1 - Call from non-secure source.
251  *
252  * This function sets input/output tap delay for the SD device.
253  *
254  * Return: Returns status, either success or error+reason.
255  *
256  */
257 static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
258 						   enum tap_delay_type type,
259 						   uint32_t value,
260 						   uint32_t flag)
261 {
262 	uint32_t shift;
263 	enum pm_ret_status ret;
264 	uint32_t val, mask;
265 
266 	if (nid == NODE_SD_0) {
267 		shift = 0;
268 		mask = ZYNQMP_SD0_DLL_RST_MASK;
269 	} else if (nid == NODE_SD_1) {
270 		shift = ZYNQMP_SD_TAP_OFFSET;
271 		mask = ZYNQMP_SD1_DLL_RST_MASK;
272 	} else {
273 		return PM_RET_ERROR_ARGS;
274 	}
275 
276 	ret = pm_mmio_read(ZYNQMP_SD_DLL_CTRL, &val, flag);
277 	if (ret != PM_RET_SUCCESS) {
278 		return ret;
279 	}
280 
281 	if ((val & mask) == 0U) {
282 		ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT, flag);
283 		if (ret != PM_RET_SUCCESS) {
284 			return ret;
285 		}
286 	}
287 
288 	if (type == PM_TAPDELAY_INPUT) {
289 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
290 				    (uint64_t)(ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
291 				    (ZYNQMP_SD_ITAPCHGWIN << shift),
292 				    flag);
293 
294 		if (ret != PM_RET_SUCCESS) {
295 			goto reset_release;
296 		}
297 
298 		if (value == 0U) {
299 			ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
300 					    (uint64_t)(ZYNQMP_SD_ITAPDLYENA_MASK <<
301 					     shift), 0, flag);
302 		} else {
303 			ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
304 					    (uint64_t)(ZYNQMP_SD_ITAPDLYENA_MASK <<
305 					    shift), (uint64_t)(ZYNQMP_SD_ITAPDLYENA <<
306 					    shift), flag);
307 		}
308 
309 		if (ret != PM_RET_SUCCESS) {
310 			goto reset_release;
311 		}
312 
313 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
314 				    (uint64_t)(ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
315 				    (value << shift),
316 				    flag);
317 
318 		if (ret != PM_RET_SUCCESS) {
319 			goto reset_release;
320 		}
321 
322 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
323 				    (uint64_t)(ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0,
324 				    flag);
325 	} else if (type == PM_TAPDELAY_OUTPUT) {
326 		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
327 				    (uint64_t)(ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0,
328 				    flag);
329 
330 		if (ret != PM_RET_SUCCESS) {
331 			goto reset_release;
332 		}
333 
334 		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
335 				    (uint64_t)(ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
336 				    (value << shift),
337 				    flag);
338 	} else {
339 		ret = PM_RET_ERROR_ARGS;
340 	}
341 
342 reset_release:
343 	if ((val & mask) == 0) {
344 		(void)pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE, flag);
345 	}
346 
347 	return ret;
348 }
349 
350 /**
351  * pm_ioctl_set_pll_frac_mode() -  Ioctl function for setting pll mode.
352  * @pll: PLL clock id.
353  * @mode: Mode fraction/integar.
354  *
355  * This function sets PLL mode.
356  *
357  * Return: Returns status, either success or error+reason.
358  *
359  */
360 static enum pm_ret_status pm_ioctl_set_pll_frac_mode
361 			(uint32_t pll, uint32_t mode)
362 {
363 	return pm_clock_set_pll_mode(pll, mode);
364 }
365 
366 /**
367  * pm_ioctl_get_pll_frac_mode() -  Ioctl function for getting pll mode.
368  * @pll: PLL clock id.
369  * @mode: Mode fraction/integar.
370  *
371  * This function return current PLL mode.
372  *
373  * Return: Returns status, either success or error+reason.
374  *
375  */
376 static enum pm_ret_status pm_ioctl_get_pll_frac_mode
377 			(uint32_t pll, uint32_t *mode)
378 {
379 	return pm_clock_get_pll_mode(pll, mode);
380 }
381 
382 /**
383  * pm_ioctl_set_pll_frac_data() -  Ioctl function for setting pll fraction data.
384  * @pll: PLL clock id.
385  * @data: fraction data.
386  * @flag: 0 - Call from secure source.
387  *	  1 - Call from non-secure source.
388  *
389  * This function sets fraction data.
390  * It is valid for fraction mode only.
391  *
392  * Return: Returns status, either success or error+reason.
393  *
394  */
395 static enum pm_ret_status pm_ioctl_set_pll_frac_data
396 			(uint32_t pll, uint32_t data, uint32_t flag)
397 {
398 	enum pm_node_id pll_nid;
399 	enum pm_ret_status status;
400 
401 	/* Get PLL node ID using PLL clock ID */
402 	status = pm_clock_get_pll_node_id(pll, &pll_nid);
403 	if (status == PM_RET_SUCCESS) {
404 		status = pm_pll_set_parameter(pll_nid, PM_PLL_PARAM_DATA,
405 					      data, flag);
406 	}
407 
408 	return status;
409 }
410 
411 /**
412  * pm_ioctl_get_pll_frac_data() -  Ioctl function for getting pll fraction data.
413  * @pll: PLL clock id.
414  * @data: fraction data.
415  * @flag: 0 - Call from secure source.
416  *	  1 - Call from non-secure source.
417  *
418  * This function returns fraction data value.
419  *
420  * Return: Returns status, either success or error+reason.
421  *
422  */
423 static enum pm_ret_status pm_ioctl_get_pll_frac_data
424 			(uint32_t pll, uint32_t *data, uint32_t flag)
425 {
426 	enum pm_node_id pll_nid;
427 	enum pm_ret_status status;
428 
429 	/* Get PLL node ID using PLL clock ID */
430 	status = pm_clock_get_pll_node_id(pll, &pll_nid);
431 	if (status == PM_RET_SUCCESS) {
432 		status = pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA,
433 					      data, flag);
434 	}
435 
436 	return status;
437 }
438 
439 /**
440  * pm_ioctl_write_ggs() - Ioctl function for writing global general storage
441  *                        (ggs).
442  * @index: GGS register index.
443  * @value: Register value to be written.
444  * @flag: 0 - Call from secure source.
445  *	  1 - Call from non-secure source.
446  *
447  * This function writes value to GGS register.
448  *
449  * Return: Returns status, either success or error+reason.
450  *
451  */
452 static enum pm_ret_status pm_ioctl_write_ggs(uint32_t index,
453 					     uint32_t value,
454 					     uint32_t flag)
455 {
456 	enum pm_ret_status ret_status = PM_RET_SUCCESS;
457 
458 	if (index >= GGS_NUM_REGS) {
459 		ret_status = PM_RET_ERROR_ARGS;
460 	} else {
461 		ret_status = pm_mmio_write((uint64_t)GGS_BASEADDR + (index << 2),
462 			     0xFFFFFFFFU, value, flag);
463 	}
464 
465 	return ret_status;
466 }
467 
468 /**
469  * pm_ioctl_read_ggs() - Ioctl function for reading global general storage
470  *                       (ggs).
471  * @index: GGS register index.
472  * @value: Register value.
473  * @flag: 0 - Call from secure source.
474  *	  1 - Call from non-secure source.
475  *
476  * This function returns GGS register value.
477  *
478  * Return: Returns status, either success or error+reason.
479  *
480  */
481 static enum pm_ret_status pm_ioctl_read_ggs(uint32_t index,
482 					    uint32_t *value,
483 					    uint32_t flag)
484 {
485 	enum pm_ret_status ret_status = PM_RET_SUCCESS;
486 
487 	if (index >= GGS_NUM_REGS) {
488 		ret_status = PM_RET_ERROR_ARGS;
489 	} else {
490 		ret_status = pm_mmio_read((uint64_t)GGS_BASEADDR + (index << 2),
491 					  value, flag);
492 	}
493 
494 	return ret_status;
495 }
496 
497 /**
498  * pm_ioctl_write_pggs() - Ioctl function for writing persistent global general
499  *                         storage (pggs).
500  * @index: PGGS register index.
501  * @value: Register value to be written.
502  * @flag: 0 - Call from secure source.
503  *	  1 - Call from non-secure source.
504  *
505  * This function writes value to PGGS register.
506  *
507  * Return: Returns status, either success or error+reason.
508  *
509  */
510 static enum pm_ret_status pm_ioctl_write_pggs(uint32_t index,
511 					      uint32_t value,
512 					      uint32_t flag)
513 {
514 	enum pm_ret_status ret_status = PM_RET_SUCCESS;
515 
516 	if (index >= PGGS_NUM_REGS) {
517 		ret_status = PM_RET_ERROR_ARGS;
518 	} else {
519 		ret_status = pm_mmio_write((uint64_t)PGGS_BASEADDR + (index << 2),
520 			     0xFFFFFFFFU, value, flag);
521 	}
522 
523 	return ret_status;
524 }
525 
526 /**
527  * pm_ioctl_afi() - Ioctl function for writing afi values.
528  * @index: AFI register index.
529  * @value: Register value to be written.
530  * @flag: 0 - Call from secure source.
531  *	  1 - Call from non-secure source.
532  *
533  * Return: Returns status, either success or error+reason.
534  *
535  */
536 static enum pm_ret_status pm_ioctl_afi(uint32_t index,
537 				       uint32_t value,
538 				       uint32_t flag)
539 {
540 	uint32_t mask;
541 	enum pm_ret_status status = PM_RET_ERROR_ARGS;
542 	const uint32_t regarr[] = {0xFD360000U,
543 				0xFD360014U,
544 				0xFD370000U,
545 				0xFD370014U,
546 				0xFD380000U,
547 				0xFD380014U,
548 				0xFD390000U,
549 				0xFD390014U,
550 				0xFD3a0000U,
551 				0xFD3a0014U,
552 				0xFD3b0000U,
553 				0xFD3b0014U,
554 				0xFF9b0000U,
555 				0xFF9b0014U,
556 				0xFD615000U,
557 				0xFF419000U,
558 				};
559 
560 	if (index < ARRAY_SIZE(regarr)) {
561 		if (index <= AFIFM6_WRCTRL) {
562 			mask = FABRIC_WIDTH;
563 		} else {
564 			mask = 0xf00;
565 		}
566 		status = pm_mmio_write(regarr[index], mask, value, flag);
567 	}
568 
569 	return status;
570 }
571 
572 /**
573  * pm_ioctl_read_pggs() - Ioctl function for reading persistent global general
574  *                        storage (pggs).
575  * @index: PGGS register index.
576  * @value: Register value.
577  * @flag: 0 - Call from secure source.
578  *	  1 - Call from non-secure source.
579  *
580  * This function returns PGGS register value.
581  *
582  * Return: Returns status, either success or error+reason.
583  *
584  */
585 static enum pm_ret_status pm_ioctl_read_pggs(uint32_t index,
586 					     uint32_t *value,
587 					     uint32_t flag)
588 {
589 	enum pm_ret_status status = 0;
590 
591 	if (index >= PGGS_NUM_REGS) {
592 		status = PM_RET_ERROR_ARGS;
593 	} else {
594 		status = pm_mmio_read((uint64_t)PGGS_BASEADDR + (index << 2),
595 				      value, flag);
596 	}
597 
598 	return status;
599 }
600 
601 /**
602  * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset.
603  *
604  * @flag: 0 - Call from secure source.
605  *	  1 - Call from non-secure source.
606  *
607  * Return: Returns status, either success or error+reason.
608  *
609  * This function peerforms the ULPI reset sequence for resetting
610  * the ULPI transceiver.
611  */
612 static enum pm_ret_status pm_ioctl_ulpi_reset(uint32_t flag)
613 {
614 	enum pm_ret_status ret;
615 
616 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
617 			    ZYNQMP_ULPI_RESET_VAL_HIGH, flag);
618 	if (ret != PM_RET_SUCCESS) {
619 		goto exit_label;
620 	}
621 
622 	/* Drive ULPI assert for atleast 1ms */
623 	mdelay(1);
624 
625 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
626 			    ZYNQMP_ULPI_RESET_VAL_LOW, flag);
627 	if (ret != PM_RET_SUCCESS) {
628 		goto exit_label;
629 	}
630 
631 	/* Drive ULPI de-assert for atleast 1ms */
632 	mdelay(1);
633 
634 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
635 			    ZYNQMP_ULPI_RESET_VAL_HIGH, flag);
636 
637 exit_label:
638 	return ret;
639 }
640 
641 /**
642  * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status.
643  * @value: Value to write.
644  * @flag: 0 - Call from secure source.
645  *	  1 - Call from non-secure source.
646  *
647  * This function sets healthy bit value to indicate boot health status
648  * to firmware.
649  *
650  * Return: Returns status, either success or error+reason.
651  *
652  */
653 static enum pm_ret_status pm_ioctl_set_boot_health_status(uint32_t value,
654 							  uint32_t flag)
655 {
656 	return pm_mmio_write(PMU_GLOBAL_GEN_STORAGE4,
657 			     PM_BOOT_HEALTH_STATUS_MASK, value, flag);
658 }
659 
660 /**
661  * pm_api_ioctl() -  PM IOCTL API for device control and configs.
662  * @nid: Node ID of the device.
663  * @ioctl_id: ID of the requested IOCTL.
664  * @arg1: Argument 1 to requested IOCTL call.
665  * @arg2: Argument 2 to requested IOCTL call.
666  * @value: Returned output value.
667  * @flag: 0 - Call from secure source.
668  *	  1 - Call from non-secure source.
669  *
670  * This function calls IOCTL to firmware for device control and configuration.
671  *
672  * Return: Returns status, either success or error+reason.
673  *
674  */
675 enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
676 				uint32_t ioctl_id,
677 				uint32_t arg1,
678 				uint32_t arg2,
679 				uint32_t *value,
680 				uint32_t flag)
681 {
682 	enum pm_ret_status ret;
683 	uint32_t payload[PAYLOAD_ARG_CNT];
684 
685 	switch (ioctl_id) {
686 	case IOCTL_GET_RPU_OPER_MODE:
687 		ret = pm_ioctl_get_rpu_oper_mode(value);
688 		break;
689 	case IOCTL_SET_RPU_OPER_MODE:
690 		ret = pm_ioctl_set_rpu_oper_mode(arg1);
691 		break;
692 	case IOCTL_RPU_BOOT_ADDR_CONFIG:
693 		ret = pm_ioctl_config_boot_addr(nid, arg1);
694 		break;
695 	case IOCTL_TCM_COMB_CONFIG:
696 		ret = pm_ioctl_config_tcm_comb(arg1);
697 		break;
698 	case IOCTL_SET_TAPDELAY_BYPASS:
699 		ret = pm_ioctl_set_tapdelay_bypass(arg1, arg2, flag);
700 		break;
701 	case IOCTL_SD_DLL_RESET:
702 		ret = pm_ioctl_sd_dll_reset(nid, arg1, flag);
703 		break;
704 	case IOCTL_SET_SD_TAPDELAY:
705 		ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2, flag);
706 		break;
707 	case IOCTL_SET_PLL_FRAC_MODE:
708 		ret = pm_ioctl_set_pll_frac_mode(arg1, arg2);
709 		break;
710 	case IOCTL_GET_PLL_FRAC_MODE:
711 		ret = pm_ioctl_get_pll_frac_mode(arg1, value);
712 		break;
713 	case IOCTL_SET_PLL_FRAC_DATA:
714 		ret = pm_ioctl_set_pll_frac_data(arg1, arg2, flag);
715 		break;
716 	case IOCTL_GET_PLL_FRAC_DATA:
717 		ret = pm_ioctl_get_pll_frac_data(arg1, value, flag);
718 		break;
719 	case IOCTL_WRITE_GGS:
720 		ret = pm_ioctl_write_ggs(arg1, arg2, flag);
721 		break;
722 	case IOCTL_READ_GGS:
723 		ret = pm_ioctl_read_ggs(arg1, value, flag);
724 		break;
725 	case IOCTL_WRITE_PGGS:
726 		ret = pm_ioctl_write_pggs(arg1, arg2, flag);
727 		break;
728 	case IOCTL_READ_PGGS:
729 		ret = pm_ioctl_read_pggs(arg1, value, flag);
730 		break;
731 	case IOCTL_ULPI_RESET:
732 		ret = pm_ioctl_ulpi_reset(flag);
733 		break;
734 	case IOCTL_SET_BOOT_HEALTH_STATUS:
735 		ret = pm_ioctl_set_boot_health_status(arg1, flag);
736 		break;
737 	case IOCTL_AFI:
738 		ret = pm_ioctl_afi(arg1, arg2, flag);
739 		break;
740 	default:
741 		/* Send request to the PMU */
742 		PM_PACK_PAYLOAD5(payload, flag, PM_IOCTL, nid, ioctl_id, arg1, arg2);
743 
744 		ret = pm_ipi_send_sync(primary_proc, payload, value, 1);
745 		break;
746 	}
747 
748 	return ret;
749 }
750 
751 /**
752  * tfa_ioctl_bitmask() -  API to get supported IOCTL ID mask.
753  * @bit_mask: Returned bit mask of supported IOCTL IDs.
754  * @flag: 0 - Call from secure source.
755  *	  1 - Call from non-secure source.
756  *
757  * Return: 0 success, negative value for errors.
758  *
759  */
760 enum pm_ret_status tfa_ioctl_bitmask(uint32_t *bit_mask, uint32_t flag)
761 {
762 	const uint8_t supported_ids[] = {
763 		IOCTL_GET_RPU_OPER_MODE,
764 		IOCTL_SET_RPU_OPER_MODE,
765 		IOCTL_RPU_BOOT_ADDR_CONFIG,
766 		IOCTL_TCM_COMB_CONFIG,
767 		IOCTL_SET_TAPDELAY_BYPASS,
768 		IOCTL_SD_DLL_RESET,
769 		IOCTL_SET_SD_TAPDELAY,
770 		IOCTL_SET_PLL_FRAC_MODE,
771 		IOCTL_GET_PLL_FRAC_MODE,
772 		IOCTL_SET_PLL_FRAC_DATA,
773 		IOCTL_GET_PLL_FRAC_DATA,
774 		IOCTL_WRITE_GGS,
775 		IOCTL_READ_GGS,
776 		IOCTL_WRITE_PGGS,
777 		IOCTL_READ_PGGS,
778 		IOCTL_ULPI_RESET,
779 		IOCTL_SET_BOOT_HEALTH_STATUS,
780 		IOCTL_AFI,
781 	};
782 	uint8_t i, ioctl_id;
783 	enum pm_ret_status ret = PM_RET_SUCCESS;
784 
785 	for (i = 0U; i < ARRAY_SIZE(supported_ids); i++) {
786 		ioctl_id = supported_ids[i];
787 		if (ioctl_id >= 64U) {
788 			ret = PM_RET_ERROR_NOTSUPPORTED;
789 			break;
790 		}
791 		ret = check_api_dependency(ioctl_id, flag);
792 		if (ret == PM_RET_SUCCESS) {
793 			bit_mask[ioctl_id / 32U] |= BIT(ioctl_id % 32U);
794 		}
795 	}
796 
797 	return ret;
798 }
799