1 /*
2  * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /*
8  * ZynqMP system level PM-API functions for ioctl.
9  */
10 
11 #include <arch_helpers.h>
12 #include <drivers/delay_timer.h>
13 #include <lib/mmio.h>
14 #include <plat/common/platform.h>
15 #include <zynqmp_def.h>
16 
17 #include "pm_api_clock.h"
18 #include "pm_api_ioctl.h"
19 #include "pm_api_sys.h"
20 #include "pm_client.h"
21 #include "pm_common.h"
22 #include "pm_ipi.h"
23 
24 /**
25  * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode
26  * @mode	Buffer to store value of oper mode(Split/Lock-step)
27  *
28  * This function provides current configured RPU operational mode.
29  *
30  * @return	Returns status, either success or error+reason
31  */
pm_ioctl_get_rpu_oper_mode(unsigned int * mode)32 static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(unsigned int *mode)
33 {
34 	unsigned int val;
35 
36 	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
37 	val &= ZYNQMP_SLSPLIT_MASK;
38 	if (val == 0)
39 		*mode = PM_RPU_MODE_LOCKSTEP;
40 	else
41 		*mode = PM_RPU_MODE_SPLIT;
42 
43 	return PM_RET_SUCCESS;
44 }
45 
46 /**
47  * pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode
48  * @mode	Value to set for oper mode(Split/Lock-step)
49  *
50  * This function configures RPU operational mode(Split/Lock-step).
51  * It also sets TCM combined mode in RPU lock-step and TCM non-combined
52  * mode for RPU split mode. In case of Lock step mode, RPU1's output is
53  * clamped.
54  *
55  * @return	Returns status, either success or error+reason
56  */
pm_ioctl_set_rpu_oper_mode(unsigned int mode)57 static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(unsigned int mode)
58 {
59 	unsigned int val;
60 
61 	if (mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET)
62 		return PM_RET_ERROR_ACCESS;
63 
64 	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
65 
66 	if (mode == PM_RPU_MODE_SPLIT) {
67 		val |= ZYNQMP_SLSPLIT_MASK;
68 		val &= ~ZYNQMP_TCM_COMB_MASK;
69 		val &= ~ZYNQMP_SLCLAMP_MASK;
70 	} else if (mode == PM_RPU_MODE_LOCKSTEP) {
71 		val &= ~ZYNQMP_SLSPLIT_MASK;
72 		val |= ZYNQMP_TCM_COMB_MASK;
73 		val |= ZYNQMP_SLCLAMP_MASK;
74 	} else {
75 		return PM_RET_ERROR_ARGS;
76 	}
77 
78 	mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
79 
80 	return PM_RET_SUCCESS;
81 }
82 
83 /**
84  * pm_ioctl_config_boot_addr() - Configure RPU boot address
85  * @nid		Node ID of RPU
86  * @value	Value to set for boot address (TCM/OCM)
87  *
88  * This function configures RPU boot address(memory).
89  *
90  * @return	Returns status, either success or error+reason
91  */
pm_ioctl_config_boot_addr(enum pm_node_id nid,unsigned int value)92 static enum pm_ret_status pm_ioctl_config_boot_addr(enum pm_node_id nid,
93 						    unsigned int value)
94 {
95 	unsigned int rpu_cfg_addr, val;
96 
97 	if (nid == NODE_RPU_0)
98 		rpu_cfg_addr = ZYNQMP_RPU0_CFG;
99 	else if (nid == NODE_RPU_1)
100 		rpu_cfg_addr = ZYNQMP_RPU1_CFG;
101 	else
102 		return PM_RET_ERROR_ARGS;
103 
104 	val = mmio_read_32(rpu_cfg_addr);
105 
106 	if (value == PM_RPU_BOOTMEM_LOVEC)
107 		val &= ~ZYNQMP_VINITHI_MASK;
108 	else if (value == PM_RPU_BOOTMEM_HIVEC)
109 		val |= ZYNQMP_VINITHI_MASK;
110 	else
111 		return PM_RET_ERROR_ARGS;
112 
113 	mmio_write_32(rpu_cfg_addr, val);
114 
115 	return PM_RET_SUCCESS;
116 }
117 
118 /**
119  * pm_ioctl_config_tcm_comb() - Configure TCM combined mode
120  * @value	Value to set (Split/Combined)
121  *
122  * This function configures TCM to be in split mode or combined
123  * mode.
124  *
125  * @return	Returns status, either success or error+reason
126  */
pm_ioctl_config_tcm_comb(unsigned int value)127 static enum pm_ret_status pm_ioctl_config_tcm_comb(unsigned int value)
128 {
129 	unsigned int val;
130 
131 	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
132 
133 	if (value == PM_RPU_TCM_SPLIT)
134 		val &= ~ZYNQMP_TCM_COMB_MASK;
135 	else if (value == PM_RPU_TCM_COMB)
136 		val |= ZYNQMP_TCM_COMB_MASK;
137 	else
138 		return PM_RET_ERROR_ARGS;
139 
140 	mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
141 
142 	return PM_RET_SUCCESS;
143 }
144 
145 /**
146  * pm_ioctl_set_tapdelay_bypass() -  Enable/Disable tap delay bypass
147  * @type	Type of tap delay to enable/disable (e.g. QSPI)
148  * @value	Enable/Disable
149  *
150  * This function enable/disable tap delay bypass.
151  *
152  * @return	Returns status, either success or error+reason
153  */
pm_ioctl_set_tapdelay_bypass(unsigned int type,unsigned int value)154 static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(unsigned int type,
155 						       unsigned int value)
156 {
157 	if ((value != PM_TAPDELAY_BYPASS_ENABLE &&
158 	     value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX)
159 		return PM_RET_ERROR_ARGS;
160 
161 	return pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK, value << type);
162 }
163 
164 /**
165  * pm_ioctl_set_sgmii_mode() -  Set SGMII mode for the GEM device
166  * @nid		Node ID of the device
167  * @value	Enable/Disable
168  *
169  * This function enable/disable SGMII mode for the GEM device.
170  * While enabling SGMII mode, it also ties the GEM PCS Signal
171  * Detect to 1 and selects EMIO for RX clock generation.
172  *
173  * @return	Returns status, either success or error+reason
174  */
pm_ioctl_set_sgmii_mode(enum pm_node_id nid,unsigned int value)175 static enum pm_ret_status pm_ioctl_set_sgmii_mode(enum pm_node_id nid,
176 						  unsigned int value)
177 {
178 	unsigned int val, mask, shift;
179 	enum pm_ret_status ret;
180 
181 	if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE)
182 		return PM_RET_ERROR_ARGS;
183 
184 	switch (nid) {
185 	case NODE_ETH_0:
186 		shift = 0;
187 		break;
188 	case NODE_ETH_1:
189 		shift = 1;
190 		break;
191 	case NODE_ETH_2:
192 		shift = 2;
193 		break;
194 	case NODE_ETH_3:
195 		shift = 3;
196 		break;
197 	default:
198 		return PM_RET_ERROR_ARGS;
199 	}
200 
201 	if (value == PM_SGMII_DISABLE) {
202 		mask = GEM_SGMII_MASK << GEM_CLK_CTRL_OFFSET * shift;
203 		ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, 0U);
204 	} else {
205 		/* Tie the GEM PCS Signal Detect to 1 */
206 		mask = SGMII_SD_MASK << SGMII_SD_OFFSET * shift;
207 		val = SGMII_PCS_SD_1 << SGMII_SD_OFFSET * shift;
208 		ret = pm_mmio_write(IOU_GEM_CTRL, mask, val);
209 		if (ret != PM_RET_SUCCESS)
210 			return ret;
211 
212 		/* Set the GEM to SGMII mode */
213 		mask = GEM_CLK_CTRL_MASK << GEM_CLK_CTRL_OFFSET * shift;
214 		val = GEM_RX_SRC_SEL_GTR | GEM_SGMII_MODE;
215 		val <<= GEM_CLK_CTRL_OFFSET * shift;
216 		ret =  pm_mmio_write(IOU_GEM_CLK_CTRL, mask, val);
217 	}
218 
219 	return ret;
220 }
221 
222 /**
223  * pm_ioctl_sd_dll_reset() -  Reset DLL logic
224  * @nid		Node ID of the device
225  * @type	Reset type
226  *
227  * This function resets DLL logic for the SD device.
228  *
229  * @return	Returns status, either success or error+reason
230  */
pm_ioctl_sd_dll_reset(enum pm_node_id nid,unsigned int type)231 static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid,
232 						unsigned int type)
233 {
234 	unsigned int mask, val;
235 	enum pm_ret_status ret;
236 
237 	if (nid == NODE_SD_0) {
238 		mask = ZYNQMP_SD0_DLL_RST_MASK;
239 		val = ZYNQMP_SD0_DLL_RST;
240 	} else if (nid == NODE_SD_1) {
241 		mask = ZYNQMP_SD1_DLL_RST_MASK;
242 		val = ZYNQMP_SD1_DLL_RST;
243 	} else {
244 		return PM_RET_ERROR_ARGS;
245 	}
246 
247 	switch (type) {
248 	case PM_DLL_RESET_ASSERT:
249 	case PM_DLL_RESET_PULSE:
250 		ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, val);
251 		if (ret != PM_RET_SUCCESS)
252 			return ret;
253 
254 		if (type == PM_DLL_RESET_ASSERT)
255 			break;
256 		mdelay(1);
257 		/* Fallthrough */
258 	case PM_DLL_RESET_RELEASE:
259 		ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, 0);
260 		break;
261 	default:
262 		ret = PM_RET_ERROR_ARGS;
263 		break;
264 	}
265 
266 	return ret;
267 }
268 
269 /**
270  * pm_ioctl_sd_set_tapdelay() -  Set tap delay for the SD device
271  * @nid		Node ID of the device
272  * @type	Type of tap delay to set (input/output)
273  * @value	Value to set fot the tap delay
274  *
275  * This function sets input/output tap delay for the SD device.
276  *
277  * @return	Returns status, either success or error+reason
278  */
pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,enum tap_delay_type type,unsigned int value)279 static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
280 						   enum tap_delay_type type,
281 						   unsigned int value)
282 {
283 	unsigned int shift;
284 	enum pm_ret_status ret;
285 	unsigned int val, mask;
286 
287 	if (nid == NODE_SD_0) {
288 		shift = 0;
289 		mask = ZYNQMP_SD0_DLL_RST_MASK;
290 	} else if (nid == NODE_SD_1) {
291 		shift = ZYNQMP_SD_TAP_OFFSET;
292 		mask = ZYNQMP_SD1_DLL_RST_MASK;
293 	} else {
294 		return PM_RET_ERROR_ARGS;
295 	}
296 
297 	ret = pm_mmio_read(ZYNQMP_SD_DLL_CTRL, &val);
298 	if (ret != PM_RET_SUCCESS) {
299 		return ret;
300 	}
301 
302 	if ((val & mask) == 0) {
303 		ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT);
304 		if (ret != PM_RET_SUCCESS) {
305 			return ret;
306 		}
307 	}
308 
309 	if (type == PM_TAPDELAY_INPUT) {
310 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
311 				    (ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
312 				    (ZYNQMP_SD_ITAPCHGWIN << shift));
313 		if (ret != PM_RET_SUCCESS)
314 			goto reset_release;
315 		if (value == 0)
316 			ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
317 					    (ZYNQMP_SD_ITAPDLYENA_MASK <<
318 					     shift), 0);
319 		else
320 			ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
321 					    (ZYNQMP_SD_ITAPDLYENA_MASK <<
322 					    shift), (ZYNQMP_SD_ITAPDLYENA <<
323 					    shift));
324 		if (ret != PM_RET_SUCCESS)
325 			goto reset_release;
326 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
327 				    (ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
328 				    (value << shift));
329 		if (ret != PM_RET_SUCCESS)
330 			goto reset_release;
331 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
332 				    (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
333 	} else if (type == PM_TAPDELAY_OUTPUT) {
334 		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
335 				    (ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0);
336 		if (ret != PM_RET_SUCCESS)
337 			goto reset_release;
338 		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
339 				    (ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
340 				    (value << shift));
341 	} else {
342 		ret = PM_RET_ERROR_ARGS;
343 	}
344 
345 reset_release:
346 	if ((val & mask) == 0) {
347 		(void)pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE);
348 	}
349 
350 	return ret;
351 }
352 
353 /**
354  * pm_ioctl_set_pll_frac_mode() -  Ioctl function for
355  *				   setting pll mode
356  * @pll     PLL clock id
357  * @mode    Mode fraction/integar
358  *
359  * This function sets PLL mode
360  *
361  * @return      Returns status, either success or error+reason
362  */
pm_ioctl_set_pll_frac_mode(unsigned int pll,unsigned int mode)363 static enum pm_ret_status pm_ioctl_set_pll_frac_mode
364 			(unsigned int pll, unsigned int mode)
365 {
366 	return pm_clock_set_pll_mode(pll, mode);
367 }
368 
369 /**
370  * pm_ioctl_get_pll_frac_mode() -  Ioctl function for
371  *				   getting pll mode
372  * @pll     PLL clock id
373  * @mode    Mode fraction/integar
374  *
375  * This function return current PLL mode
376  *
377  * @return      Returns status, either success or error+reason
378  */
pm_ioctl_get_pll_frac_mode(unsigned int pll,unsigned int * mode)379 static enum pm_ret_status pm_ioctl_get_pll_frac_mode
380 			(unsigned int pll, unsigned int *mode)
381 {
382 	return pm_clock_get_pll_mode(pll, mode);
383 }
384 
385 /**
386  * pm_ioctl_set_pll_frac_data() -  Ioctl function for
387  *				   setting pll fraction data
388  * @pll     PLL clock id
389  * @data    fraction data
390  *
391  * This function sets fraction data.
392  * It is valid for fraction mode only.
393  *
394  * @return      Returns status, either success or error+reason
395  */
pm_ioctl_set_pll_frac_data(unsigned int pll,unsigned int data)396 static enum pm_ret_status pm_ioctl_set_pll_frac_data
397 			(unsigned int pll, unsigned int data)
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 		return status;
406 
407 	return pm_pll_set_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
408 }
409 
410 /**
411  * pm_ioctl_get_pll_frac_data() -  Ioctl function for
412  *				   getting pll fraction data
413  * @pll     PLL clock id
414  * @data    fraction data
415  *
416  * This function returns fraction data value.
417  *
418  * @return      Returns status, either success or error+reason
419  */
pm_ioctl_get_pll_frac_data(unsigned int pll,unsigned int * data)420 static enum pm_ret_status pm_ioctl_get_pll_frac_data
421 			(unsigned int pll, unsigned int *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 	return pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
432 }
433 
434 /**
435  * pm_ioctl_write_ggs() - Ioctl function for writing
436  *			  global general storage (ggs)
437  * @index	GGS register index
438  * @value	Register value to be written
439  *
440  * This function writes value to GGS register.
441  *
442  * @return      Returns status, either success or error+reason
443  */
pm_ioctl_write_ggs(unsigned int index,unsigned int value)444 static enum pm_ret_status pm_ioctl_write_ggs(unsigned int index,
445 					     unsigned int value)
446 {
447 	if (index >= GGS_NUM_REGS)
448 		return PM_RET_ERROR_ARGS;
449 
450 	return pm_mmio_write(GGS_BASEADDR + (index << 2),
451 			     0xFFFFFFFFU, value);
452 }
453 
454 /**
455  * pm_ioctl_read_ggs() - Ioctl function for reading
456  *			 global general storage (ggs)
457  * @index	GGS register index
458  * @value	Register value
459  *
460  * This function returns GGS register value.
461  *
462  * @return      Returns status, either success or error+reason
463  */
pm_ioctl_read_ggs(unsigned int index,unsigned int * value)464 static enum pm_ret_status pm_ioctl_read_ggs(unsigned int index,
465 					    unsigned int *value)
466 {
467 	if (index >= GGS_NUM_REGS)
468 		return PM_RET_ERROR_ARGS;
469 
470 	return pm_mmio_read(GGS_BASEADDR + (index << 2), value);
471 }
472 
473 /**
474  * pm_ioctl_write_pggs() - Ioctl function for writing persistent
475  *			   global general storage (pggs)
476  * @index	PGGS register index
477  * @value	Register value to be written
478  *
479  * This function writes value to PGGS register.
480  *
481  * @return      Returns status, either success or error+reason
482  */
pm_ioctl_write_pggs(unsigned int index,unsigned int value)483 static enum pm_ret_status pm_ioctl_write_pggs(unsigned int index,
484 					      unsigned int value)
485 {
486 	if (index >= PGGS_NUM_REGS)
487 		return PM_RET_ERROR_ARGS;
488 
489 	return pm_mmio_write(PGGS_BASEADDR + (index << 2),
490 			     0xFFFFFFFFU, value);
491 }
492 
493 /**
494  * pm_ioctl_afi() - Ioctl function for writing afi values
495  *
496  * @index 	AFI register index
497  * @value	Register value to be written
498  *
499  *
500  * @return      Returns status, either success or error+reason
501  */
pm_ioctl_afi(unsigned int index,unsigned int value)502 static enum pm_ret_status pm_ioctl_afi(unsigned int index,
503 					      unsigned int value)
504 {
505 	unsigned int mask;
506 	unsigned int regarr[] = {0xFD360000,
507 				0xFD360014,
508 				0xFD370000,
509 				0xFD370014,
510 				0xFD380000,
511 				0xFD380014,
512 				0xFD390000,
513 				0xFD390014,
514 				0xFD3a0000,
515 				0xFD3a0014,
516 				0xFD3b0000,
517 				0xFD3b0014,
518 				0xFF9b0000,
519 				0xFF9b0014,
520 				0xFD615000,
521 				0xFF419000,
522 				};
523 
524 	if (index >= ARRAY_SIZE(regarr))
525 		return PM_RET_ERROR_ARGS;
526 
527 	if (index < AFIFM6_WRCTRL)
528 		mask = FABRIC_WIDTH;
529 	else
530 		mask = 0xf00;
531 
532 	return pm_mmio_write(regarr[index], mask, value);
533 }
534 
535 /**
536  * pm_ioctl_read_pggs() - Ioctl function for reading persistent
537  *			  global general storage (pggs)
538  * @index	PGGS register index
539  * @value	Register value
540  *
541  * This function returns PGGS register value.
542  *
543  * @return      Returns status, either success or error+reason
544  */
pm_ioctl_read_pggs(unsigned int index,unsigned int * value)545 static enum pm_ret_status pm_ioctl_read_pggs(unsigned int index,
546 					     unsigned int *value)
547 {
548 	if (index >= PGGS_NUM_REGS)
549 		return PM_RET_ERROR_ARGS;
550 
551 	return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
552 }
553 
554 /**
555  * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset
556  *
557  * This function peerforms the ULPI reset sequence for resetting
558  * the ULPI transceiver.
559  *
560  * @return      Returns status, either success or error+reason
561  */
pm_ioctl_ulpi_reset(void)562 static enum pm_ret_status pm_ioctl_ulpi_reset(void)
563 {
564 	enum pm_ret_status ret;
565 
566 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
567 			    ZYNQMP_ULPI_RESET_VAL_HIGH);
568 	if (ret != PM_RET_SUCCESS)
569 		return ret;
570 
571 	/* Drive ULPI assert for atleast 1ms */
572 	mdelay(1);
573 
574 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
575 			    ZYNQMP_ULPI_RESET_VAL_LOW);
576 	if (ret != PM_RET_SUCCESS)
577 		return ret;
578 
579 	/* Drive ULPI de-assert for atleast 1ms */
580 	mdelay(1);
581 
582 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
583 			    ZYNQMP_ULPI_RESET_VAL_HIGH);
584 
585 	return ret;
586 }
587 
588 /**
589  * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status
590  *
591  * This function sets healthy bit value to indicate boot health status
592  * to firmware.
593  *
594  * @return      Returns status, either success or error+reason
595  */
pm_ioctl_set_boot_health_status(unsigned int value)596 static enum pm_ret_status pm_ioctl_set_boot_health_status(unsigned int value)
597 {
598 	return pm_mmio_write(PMU_GLOBAL_GEN_STORAGE4,
599 			     PM_BOOT_HEALTH_STATUS_MASK, value);
600 }
601 
602 /**
603  * pm_api_ioctl() -  PM IOCTL API for device control and configs
604  * @node_id	Node ID of the device
605  * @ioctl_id	ID of the requested IOCTL
606  * @arg1	Argument 1 to requested IOCTL call
607  * @arg2	Argument 2 to requested IOCTL call
608  * @value	Returned output value
609  *
610  * This function calls IOCTL to firmware for device control and configuration.
611  *
612  * @return	Returns status, either success or error+reason
613  */
pm_api_ioctl(enum pm_node_id nid,unsigned int ioctl_id,unsigned int arg1,unsigned int arg2,unsigned int * value)614 enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
615 				unsigned int ioctl_id,
616 				unsigned int arg1,
617 				unsigned int arg2,
618 				unsigned int *value)
619 {
620 	enum pm_ret_status ret;
621 
622 	switch (ioctl_id) {
623 	case IOCTL_GET_RPU_OPER_MODE:
624 		ret = pm_ioctl_get_rpu_oper_mode(value);
625 		break;
626 	case IOCTL_SET_RPU_OPER_MODE:
627 		ret = pm_ioctl_set_rpu_oper_mode(arg1);
628 		break;
629 	case IOCTL_RPU_BOOT_ADDR_CONFIG:
630 		ret = pm_ioctl_config_boot_addr(nid, arg1);
631 		break;
632 	case IOCTL_TCM_COMB_CONFIG:
633 		ret = pm_ioctl_config_tcm_comb(arg1);
634 		break;
635 	case IOCTL_SET_TAPDELAY_BYPASS:
636 		ret = pm_ioctl_set_tapdelay_bypass(arg1, arg2);
637 		break;
638 	case IOCTL_SET_SGMII_MODE:
639 		ret = pm_ioctl_set_sgmii_mode(nid, arg1);
640 		break;
641 	case IOCTL_SD_DLL_RESET:
642 		ret = pm_ioctl_sd_dll_reset(nid, arg1);
643 		break;
644 	case IOCTL_SET_SD_TAPDELAY:
645 		ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2);
646 		break;
647 	case IOCTL_SET_PLL_FRAC_MODE:
648 		ret = pm_ioctl_set_pll_frac_mode(arg1, arg2);
649 		break;
650 	case IOCTL_GET_PLL_FRAC_MODE:
651 		ret = pm_ioctl_get_pll_frac_mode(arg1, value);
652 		break;
653 	case IOCTL_SET_PLL_FRAC_DATA:
654 		ret = pm_ioctl_set_pll_frac_data(arg1, arg2);
655 		break;
656 	case IOCTL_GET_PLL_FRAC_DATA:
657 		ret = pm_ioctl_get_pll_frac_data(arg1, value);
658 		break;
659 	case IOCTL_WRITE_GGS:
660 		ret = pm_ioctl_write_ggs(arg1, arg2);
661 		break;
662 	case IOCTL_READ_GGS:
663 		ret = pm_ioctl_read_ggs(arg1, value);
664 		break;
665 	case IOCTL_WRITE_PGGS:
666 		ret = pm_ioctl_write_pggs(arg1, arg2);
667 		break;
668 	case IOCTL_READ_PGGS:
669 		ret = pm_ioctl_read_pggs(arg1, value);
670 		break;
671 	case IOCTL_ULPI_RESET:
672 		ret = pm_ioctl_ulpi_reset();
673 		break;
674 	case IOCTL_SET_BOOT_HEALTH_STATUS:
675 		ret = pm_ioctl_set_boot_health_status(arg1);
676 		break;
677 	case IOCTL_AFI:
678 		ret = pm_ioctl_afi(arg1, arg2);
679 		break;
680 	case IOCTL_SET_FEATURE_CONFIG:
681 	case IOCTL_GET_FEATURE_CONFIG:
682 		ret = pm_feature_config(ioctl_id, arg1, arg2, value);
683 		break;
684 	default:
685 		ret = PM_RET_ERROR_NOTSUPPORTED;
686 		break;
687 	}
688 
689 	return ret;
690 }
691