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