xref: /rk3399_ARM-atf/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c (revision b47dddd061e92054c3b2096fc8aa9688bfef68d6)
1 /*
2  * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
3  * Copyright (c) 2022-2023, 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  *
167  * This function enable/disable tap delay bypass.
168  *
169  * Return: Returns status, either success or error+reason.
170  *
171  */
172 static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(uint32_t type,
173 						       uint32_t value)
174 {
175 	enum pm_ret_status status = PM_RET_SUCCESS;
176 
177 	if ((((value != PM_TAPDELAY_BYPASS_ENABLE) &&
178 	     (value != PM_TAPDELAY_BYPASS_DISABLE)) || (type >= PM_TAPDELAY_MAX))) {
179 		status = PM_RET_ERROR_ARGS;
180 	} else {
181 		status = pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK, value << type);
182 	}
183 
184 	return status;
185 }
186 
187 /**
188  * pm_ioctl_sd_dll_reset() -  Reset DLL logic.
189  * @nid: Node ID of the device.
190  * @type: Reset type.
191  *
192  * This function resets DLL logic for the SD device.
193  *
194  * Return: Returns status, either success or error+reason.
195  *
196  */
197 static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid,
198 						uint32_t type)
199 {
200 	uint32_t mask, val;
201 	enum pm_ret_status ret;
202 
203 	if (nid == NODE_SD_0) {
204 		mask = ZYNQMP_SD0_DLL_RST_MASK;
205 		val = ZYNQMP_SD0_DLL_RST;
206 	} else if (nid == NODE_SD_1) {
207 		mask = ZYNQMP_SD1_DLL_RST_MASK;
208 		val = ZYNQMP_SD1_DLL_RST;
209 	} else {
210 		return PM_RET_ERROR_ARGS;
211 	}
212 
213 	switch (type) {
214 	case PM_DLL_RESET_ASSERT:
215 	case PM_DLL_RESET_PULSE:
216 		ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, val);
217 		if (ret != PM_RET_SUCCESS) {
218 			return ret;
219 		}
220 
221 		if (type == PM_DLL_RESET_ASSERT) {
222 			break;
223 		}
224 		mdelay(1);
225 		/* Fallthrough */
226 	case PM_DLL_RESET_RELEASE:
227 		ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, 0);
228 		break;
229 	default:
230 		ret = PM_RET_ERROR_ARGS;
231 		break;
232 	}
233 
234 	return ret;
235 }
236 
237 /**
238  * pm_ioctl_sd_set_tapdelay() -  Set tap delay for the SD device.
239  * @nid: Node ID of the device.
240  * @type: Type of tap delay to set (input/output).
241  * @value: Value to set fot the tap delay.
242  *
243  * This function sets input/output tap delay for the SD device.
244  *
245  * Return: Returns status, either success or error+reason.
246  *
247  */
248 static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
249 						   enum tap_delay_type type,
250 						   uint32_t value)
251 {
252 	uint32_t shift;
253 	enum pm_ret_status ret;
254 	uint32_t val, mask;
255 
256 	if (nid == NODE_SD_0) {
257 		shift = 0;
258 		mask = ZYNQMP_SD0_DLL_RST_MASK;
259 	} else if (nid == NODE_SD_1) {
260 		shift = ZYNQMP_SD_TAP_OFFSET;
261 		mask = ZYNQMP_SD1_DLL_RST_MASK;
262 	} else {
263 		return PM_RET_ERROR_ARGS;
264 	}
265 
266 	ret = pm_mmio_read(ZYNQMP_SD_DLL_CTRL, &val);
267 	if (ret != PM_RET_SUCCESS) {
268 		return ret;
269 	}
270 
271 	if ((val & mask) == 0U) {
272 		ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT);
273 		if (ret != PM_RET_SUCCESS) {
274 			return ret;
275 		}
276 	}
277 
278 	if (type == PM_TAPDELAY_INPUT) {
279 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
280 				    (uint64_t)(ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
281 				    (ZYNQMP_SD_ITAPCHGWIN << shift));
282 
283 		if (ret != PM_RET_SUCCESS) {
284 			goto reset_release;
285 		}
286 
287 		if (value == 0U) {
288 			ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
289 					    (uint64_t)(ZYNQMP_SD_ITAPDLYENA_MASK <<
290 					     shift), 0);
291 		} else {
292 			ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
293 					    (uint64_t)(ZYNQMP_SD_ITAPDLYENA_MASK <<
294 					    shift), (uint64_t)(ZYNQMP_SD_ITAPDLYENA <<
295 					    shift));
296 		}
297 
298 		if (ret != PM_RET_SUCCESS) {
299 			goto reset_release;
300 		}
301 
302 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
303 				    (uint64_t)(ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
304 				    (value << shift));
305 
306 		if (ret != PM_RET_SUCCESS) {
307 			goto reset_release;
308 		}
309 
310 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
311 				    (uint64_t)(ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
312 	} else if (type == PM_TAPDELAY_OUTPUT) {
313 		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
314 				    (uint64_t)(ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0);
315 
316 		if (ret != PM_RET_SUCCESS) {
317 			goto reset_release;
318 		}
319 
320 		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
321 				    (uint64_t)(ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
322 				    (value << shift));
323 	} else {
324 		ret = PM_RET_ERROR_ARGS;
325 	}
326 
327 reset_release:
328 	if ((val & mask) == 0) {
329 		(void)pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE);
330 	}
331 
332 	return ret;
333 }
334 
335 /**
336  * pm_ioctl_set_pll_frac_mode() -  Ioctl function for setting pll mode.
337  * @pll: PLL clock id.
338  * @mode: Mode fraction/integar.
339  *
340  * This function sets PLL mode.
341  *
342  * Return: Returns status, either success or error+reason.
343  *
344  */
345 static enum pm_ret_status pm_ioctl_set_pll_frac_mode
346 			(uint32_t pll, uint32_t mode)
347 {
348 	return pm_clock_set_pll_mode(pll, mode);
349 }
350 
351 /**
352  * pm_ioctl_get_pll_frac_mode() -  Ioctl function for getting pll mode.
353  * @pll: PLL clock id.
354  * @mode: Mode fraction/integar.
355  *
356  * This function return current PLL mode.
357  *
358  * Return: Returns status, either success or error+reason.
359  *
360  */
361 static enum pm_ret_status pm_ioctl_get_pll_frac_mode
362 			(uint32_t pll, uint32_t *mode)
363 {
364 	return pm_clock_get_pll_mode(pll, mode);
365 }
366 
367 /**
368  * pm_ioctl_set_pll_frac_data() -  Ioctl function for setting pll fraction data.
369  * @pll: PLL clock id.
370  * @data: fraction data.
371  *
372  * This function sets fraction data.
373  * It is valid for fraction mode only.
374  *
375  * Return: Returns status, either success or error+reason.
376  *
377  */
378 static enum pm_ret_status pm_ioctl_set_pll_frac_data
379 			(uint32_t pll, uint32_t data)
380 {
381 	enum pm_node_id pll_nid;
382 	enum pm_ret_status status;
383 
384 	/* Get PLL node ID using PLL clock ID */
385 	status = pm_clock_get_pll_node_id(pll, &pll_nid);
386 	if (status == PM_RET_SUCCESS) {
387 		status = pm_pll_set_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
388 	}
389 
390 	return status;
391 }
392 
393 /**
394  * pm_ioctl_get_pll_frac_data() -  Ioctl function for getting pll fraction data.
395  * @pll: PLL clock id.
396  * @data: fraction data.
397  *
398  * This function returns fraction data value.
399  *
400  * Return: Returns status, either success or error+reason.
401  *
402  */
403 static enum pm_ret_status pm_ioctl_get_pll_frac_data
404 			(uint32_t pll, uint32_t *data)
405 {
406 	enum pm_node_id pll_nid;
407 	enum pm_ret_status status;
408 
409 	/* Get PLL node ID using PLL clock ID */
410 	status = pm_clock_get_pll_node_id(pll, &pll_nid);
411 	if (status == PM_RET_SUCCESS) {
412 		status = pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
413 	}
414 
415 	return status;
416 }
417 
418 /**
419  * pm_ioctl_write_ggs() - Ioctl function for writing global general storage
420  *                        (ggs).
421  * @index: GGS register index.
422  * @value: Register value to be written.
423  *
424  * This function writes value to GGS register.
425  *
426  * Return: Returns status, either success or error+reason.
427  *
428  */
429 static enum pm_ret_status pm_ioctl_write_ggs(uint32_t index,
430 					     uint32_t value)
431 {
432 	enum pm_ret_status ret_status = PM_RET_SUCCESS;
433 
434 	if (index >= GGS_NUM_REGS) {
435 		ret_status = PM_RET_ERROR_ARGS;
436 	} else {
437 		ret_status = pm_mmio_write((uint64_t)GGS_BASEADDR + (index << 2),
438 			     0xFFFFFFFFU, value);
439 	}
440 
441 	return ret_status;
442 }
443 
444 /**
445  * pm_ioctl_read_ggs() - Ioctl function for reading global general storage
446  *                       (ggs).
447  * @index: GGS register index.
448  * @value: Register value.
449  *
450  * This function returns GGS register value.
451  *
452  * Return: Returns status, either success or error+reason.
453  *
454  */
455 static enum pm_ret_status pm_ioctl_read_ggs(uint32_t index,
456 					    uint32_t *value)
457 {
458 	enum pm_ret_status ret_status = PM_RET_SUCCESS;
459 
460 	if (index >= GGS_NUM_REGS) {
461 		ret_status = PM_RET_ERROR_ARGS;
462 	} else {
463 		ret_status = pm_mmio_read((uint64_t)GGS_BASEADDR + (index << 2), value);
464 	}
465 
466 	return ret_status;
467 }
468 
469 /**
470  * pm_ioctl_write_pggs() - Ioctl function for writing persistent global general
471  *                         storage (pggs).
472  * @index: PGGS register index.
473  * @value: Register value to be written.
474  *
475  * This function writes value to PGGS register.
476  *
477  * Return: Returns status, either success or error+reason.
478  *
479  */
480 static enum pm_ret_status pm_ioctl_write_pggs(uint32_t index,
481 					      uint32_t value)
482 {
483 	enum pm_ret_status ret_status = PM_RET_SUCCESS;
484 
485 	if (index >= PGGS_NUM_REGS) {
486 		ret_status = PM_RET_ERROR_ARGS;
487 	} else {
488 		ret_status = pm_mmio_write((uint64_t)PGGS_BASEADDR + (index << 2),
489 			     0xFFFFFFFFU, value);
490 	}
491 
492 	return ret_status;
493 }
494 
495 /**
496  * pm_ioctl_afi() - Ioctl function for writing afi values.
497  * @index: AFI register index.
498  * @value: Register value to be written.
499  *
500  * Return: Returns status, either success or error+reason.
501  *
502  */
503 static enum pm_ret_status pm_ioctl_afi(uint32_t index,
504 					      uint32_t value)
505 {
506 	uint32_t mask;
507 	enum pm_ret_status status = PM_RET_ERROR_ARGS;
508 	const uint32_t regarr[] = {0xFD360000U,
509 				0xFD360014U,
510 				0xFD370000U,
511 				0xFD370014U,
512 				0xFD380000U,
513 				0xFD380014U,
514 				0xFD390000U,
515 				0xFD390014U,
516 				0xFD3a0000U,
517 				0xFD3a0014U,
518 				0xFD3b0000U,
519 				0xFD3b0014U,
520 				0xFF9b0000U,
521 				0xFF9b0014U,
522 				0xFD615000U,
523 				0xFF419000U,
524 				};
525 
526 	if (index < ARRAY_SIZE(regarr)) {
527 		if (index <= AFIFM6_WRCTRL) {
528 			mask = FABRIC_WIDTH;
529 		} else {
530 			mask = 0xf00;
531 		}
532 		status = pm_mmio_write(regarr[index], mask, value);
533 	}
534 
535 	return status;
536 }
537 
538 /**
539  * pm_ioctl_read_pggs() - Ioctl function for reading persistent global general
540  *                        storage (pggs).
541  * @index: PGGS register index.
542  * @value: Register value.
543  *
544  * This function returns PGGS register value.
545  *
546  * Return: Returns status, either success or error+reason.
547  *
548  */
549 static enum pm_ret_status pm_ioctl_read_pggs(uint32_t index,
550 					     uint32_t *value)
551 {
552 	enum pm_ret_status status = 0;
553 
554 	if (index >= PGGS_NUM_REGS) {
555 		status = PM_RET_ERROR_ARGS;
556 	} else {
557 		status = pm_mmio_read((uint64_t)PGGS_BASEADDR + (index << 2), value);
558 	}
559 
560 	return status;
561 }
562 
563 /**
564  * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset.
565  *
566  * Return: Returns status, either success or error+reason.
567  *
568  * This function peerforms the ULPI reset sequence for resetting
569  * the ULPI transceiver.
570  */
571 static enum pm_ret_status pm_ioctl_ulpi_reset(void)
572 {
573 	enum pm_ret_status ret;
574 
575 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
576 			    ZYNQMP_ULPI_RESET_VAL_HIGH);
577 	if (ret != PM_RET_SUCCESS) {
578 		goto exit_label;
579 	}
580 
581 	/* Drive ULPI assert for atleast 1ms */
582 	mdelay(1);
583 
584 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
585 			    ZYNQMP_ULPI_RESET_VAL_LOW);
586 	if (ret != PM_RET_SUCCESS) {
587 		goto exit_label;
588 	}
589 
590 	/* Drive ULPI de-assert for atleast 1ms */
591 	mdelay(1);
592 
593 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
594 			    ZYNQMP_ULPI_RESET_VAL_HIGH);
595 
596 exit_label:
597 	return ret;
598 }
599 
600 /**
601  * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status.
602  * @value: Value to write.
603  *
604  * This function sets healthy bit value to indicate boot health status
605  * to firmware.
606  *
607  * Return: Returns status, either success or error+reason.
608  *
609  */
610 static enum pm_ret_status pm_ioctl_set_boot_health_status(uint32_t value)
611 {
612 	return pm_mmio_write(PMU_GLOBAL_GEN_STORAGE4,
613 			     PM_BOOT_HEALTH_STATUS_MASK, value);
614 }
615 
616 /**
617  * pm_api_ioctl() -  PM IOCTL API for device control and configs.
618  * @nid: Node ID of the device.
619  * @ioctl_id: ID of the requested IOCTL.
620  * @arg1: Argument 1 to requested IOCTL call.
621  * @arg2: Argument 2 to requested IOCTL call.
622  * @value: Returned output value.
623  *
624  * This function calls IOCTL to firmware for device control and configuration.
625  *
626  * Return: Returns status, either success or error+reason.
627  *
628  */
629 enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
630 				uint32_t ioctl_id,
631 				uint32_t arg1,
632 				uint32_t arg2,
633 				uint32_t *value)
634 {
635 	enum pm_ret_status ret;
636 	uint32_t payload[PAYLOAD_ARG_CNT];
637 
638 	switch (ioctl_id) {
639 	case IOCTL_GET_RPU_OPER_MODE:
640 		ret = pm_ioctl_get_rpu_oper_mode(value);
641 		break;
642 	case IOCTL_SET_RPU_OPER_MODE:
643 		ret = pm_ioctl_set_rpu_oper_mode(arg1);
644 		break;
645 	case IOCTL_RPU_BOOT_ADDR_CONFIG:
646 		ret = pm_ioctl_config_boot_addr(nid, arg1);
647 		break;
648 	case IOCTL_TCM_COMB_CONFIG:
649 		ret = pm_ioctl_config_tcm_comb(arg1);
650 		break;
651 	case IOCTL_SET_TAPDELAY_BYPASS:
652 		ret = pm_ioctl_set_tapdelay_bypass(arg1, arg2);
653 		break;
654 	case IOCTL_SD_DLL_RESET:
655 		ret = pm_ioctl_sd_dll_reset(nid, arg1);
656 		break;
657 	case IOCTL_SET_SD_TAPDELAY:
658 		ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2);
659 		break;
660 	case IOCTL_SET_PLL_FRAC_MODE:
661 		ret = pm_ioctl_set_pll_frac_mode(arg1, arg2);
662 		break;
663 	case IOCTL_GET_PLL_FRAC_MODE:
664 		ret = pm_ioctl_get_pll_frac_mode(arg1, value);
665 		break;
666 	case IOCTL_SET_PLL_FRAC_DATA:
667 		ret = pm_ioctl_set_pll_frac_data(arg1, arg2);
668 		break;
669 	case IOCTL_GET_PLL_FRAC_DATA:
670 		ret = pm_ioctl_get_pll_frac_data(arg1, value);
671 		break;
672 	case IOCTL_WRITE_GGS:
673 		ret = pm_ioctl_write_ggs(arg1, arg2);
674 		break;
675 	case IOCTL_READ_GGS:
676 		ret = pm_ioctl_read_ggs(arg1, value);
677 		break;
678 	case IOCTL_WRITE_PGGS:
679 		ret = pm_ioctl_write_pggs(arg1, arg2);
680 		break;
681 	case IOCTL_READ_PGGS:
682 		ret = pm_ioctl_read_pggs(arg1, value);
683 		break;
684 	case IOCTL_ULPI_RESET:
685 		ret = pm_ioctl_ulpi_reset();
686 		break;
687 	case IOCTL_SET_BOOT_HEALTH_STATUS:
688 		ret = pm_ioctl_set_boot_health_status(arg1);
689 		break;
690 	case IOCTL_AFI:
691 		ret = pm_ioctl_afi(arg1, arg2);
692 		break;
693 	default:
694 		/* Send request to the PMU */
695 		PM_PACK_PAYLOAD5(payload, PM_IOCTL, nid, ioctl_id, arg1, arg2);
696 
697 		ret = pm_ipi_send_sync(primary_proc, payload, value, 1);
698 		break;
699 	}
700 
701 	return ret;
702 }
703 
704 /**
705  * tfa_ioctl_bitmask() -  API to get supported IOCTL ID mask.
706  * @bit_mask: Returned bit mask of supported IOCTL IDs.
707  *
708  * Return: 0 success, negative value for errors.
709  *
710  */
711 enum pm_ret_status tfa_ioctl_bitmask(uint32_t *bit_mask)
712 {
713 	const uint8_t supported_ids[] = {
714 		IOCTL_GET_RPU_OPER_MODE,
715 		IOCTL_SET_RPU_OPER_MODE,
716 		IOCTL_RPU_BOOT_ADDR_CONFIG,
717 		IOCTL_TCM_COMB_CONFIG,
718 		IOCTL_SET_TAPDELAY_BYPASS,
719 		IOCTL_SD_DLL_RESET,
720 		IOCTL_SET_SD_TAPDELAY,
721 		IOCTL_SET_PLL_FRAC_MODE,
722 		IOCTL_GET_PLL_FRAC_MODE,
723 		IOCTL_SET_PLL_FRAC_DATA,
724 		IOCTL_GET_PLL_FRAC_DATA,
725 		IOCTL_WRITE_GGS,
726 		IOCTL_READ_GGS,
727 		IOCTL_WRITE_PGGS,
728 		IOCTL_READ_PGGS,
729 		IOCTL_ULPI_RESET,
730 		IOCTL_SET_BOOT_HEALTH_STATUS,
731 		IOCTL_AFI,
732 	};
733 	uint8_t i, ioctl_id;
734 	enum pm_ret_status ret = PM_RET_SUCCESS;
735 
736 	for (i = 0U; i < ARRAY_SIZE(supported_ids); i++) {
737 		ioctl_id = supported_ids[i];
738 		if (ioctl_id >= 64U) {
739 			ret = PM_RET_ERROR_NOTSUPPORTED;
740 			break;
741 		}
742 		ret = check_api_dependency(ioctl_id);
743 		if (ret == PM_RET_SUCCESS) {
744 			bit_mask[ioctl_id / 32U] |= BIT(ioctl_id % 32U);
745 		}
746 	}
747 
748 	return ret;
749 }
750