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