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