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