xref: /rk3399_ARM-atf/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c (revision a15f38cf4f9c52870b9ab47aca9f3d4c1f8bfc64)
1 /*
2  * Copyright (c) 2018, 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 
16 #include "pm_api_clock.h"
17 #include "pm_api_ioctl.h"
18 #include "pm_api_sys.h"
19 #include "pm_client.h"
20 #include "pm_common.h"
21 #include "pm_ipi.h"
22 #include "../zynqmp_def.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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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 
286 	if (nid == NODE_SD_0)
287 		shift = 0;
288 	else if (nid == NODE_SD_1)
289 		shift = ZYNQMP_SD_TAP_OFFSET;
290 	else
291 		return PM_RET_ERROR_ARGS;
292 
293 	ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT);
294 	if (ret != PM_RET_SUCCESS)
295 		return ret;
296 
297 	if (type == PM_TAPDELAY_INPUT) {
298 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
299 				    (ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
300 				    (ZYNQMP_SD_ITAPCHGWIN << shift));
301 		if (ret != PM_RET_SUCCESS)
302 			goto reset_release;
303 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
304 				    (ZYNQMP_SD_ITAPDLYENA_MASK << shift),
305 				    (ZYNQMP_SD_ITAPDLYENA << shift));
306 		if (ret != PM_RET_SUCCESS)
307 			goto reset_release;
308 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
309 				    (ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
310 				    (value << shift));
311 		if (ret != PM_RET_SUCCESS)
312 			goto reset_release;
313 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
314 				    (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
315 	} else if (type == PM_TAPDELAY_OUTPUT) {
316 		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
317 				    (ZYNQMP_SD_OTAPDLYENA_MASK << shift),
318 				    (ZYNQMP_SD_OTAPDLYENA << shift));
319 		if (ret != PM_RET_SUCCESS)
320 			goto reset_release;
321 		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
322 				    (ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
323 				    (value << shift));
324 	} else {
325 		ret = PM_RET_ERROR_ARGS;
326 	}
327 
328 reset_release:
329 	pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE);
330 	return ret;
331 }
332 
333 /**
334  * pm_ioctl_set_pll_frac_mode() -  Ioctl function for
335  *				   setting pll mode
336  * @pll     PLL id
337  * @mode    Mode fraction/integar
338  *
339  * This function sets PLL mode
340  *
341  * @return      Returns status, either success or error+reason
342  */
343 static enum pm_ret_status pm_ioctl_set_pll_frac_mode
344 			(unsigned int pll, unsigned int mode)
345 {
346 	return pm_api_clk_set_pll_mode(pll, mode);
347 }
348 
349 /**
350  * pm_ioctl_get_pll_frac_mode() -  Ioctl function for
351  *				   getting pll mode
352  * @pll     PLL id
353  * @mode    Mode fraction/integar
354  *
355  * This function return current PLL mode
356  *
357  * @return      Returns status, either success or error+reason
358  */
359 static enum pm_ret_status pm_ioctl_get_pll_frac_mode
360 			(unsigned int pll, unsigned int *mode)
361 {
362 	return pm_api_clk_get_pll_mode(pll, mode);
363 }
364 
365 /**
366  * pm_ioctl_set_pll_frac_data() -  Ioctl function for
367  *				   setting pll fraction data
368  * @pll     PLL id
369  * @data    fraction data
370  *
371  * This function sets fraction data.
372  * It is valid for fraction mode only.
373  *
374  * @return      Returns status, either success or error+reason
375  */
376 static enum pm_ret_status pm_ioctl_set_pll_frac_data
377 			(unsigned int pll, unsigned int data)
378 {
379 	return pm_api_clk_set_pll_frac_data(pll, data);
380 }
381 
382 /**
383  * pm_ioctl_get_pll_frac_data() -  Ioctl function for
384  *				   getting pll fraction data
385  * @pll     PLL id
386  * @data    fraction data
387  *
388  * This function returns fraction data value.
389  *
390  * @return      Returns status, either success or error+reason
391  */
392 static enum pm_ret_status pm_ioctl_get_pll_frac_data
393 			(unsigned int pll, unsigned int *data)
394 {
395 	return pm_api_clk_get_pll_frac_data(pll, data);
396 }
397 
398 /**
399  * pm_ioctl_write_ggs() - Ioctl function for writing
400  *			  global general storage (ggs)
401  * @index	GGS register index
402  * @value	Register value to be written
403  *
404  * This function writes value to GGS register.
405  *
406  * @return      Returns status, either success or error+reason
407  */
408 static enum pm_ret_status pm_ioctl_write_ggs(unsigned int index,
409 					     unsigned int value)
410 {
411 	if (index >= GGS_NUM_REGS)
412 		return PM_RET_ERROR_ARGS;
413 
414 	return pm_mmio_write(GGS_BASEADDR + (index << 2),
415 			     0xFFFFFFFFU, value);
416 }
417 
418 /**
419  * pm_ioctl_read_ggs() - Ioctl function for reading
420  *			 global general storage (ggs)
421  * @index	GGS register index
422  * @value	Register value
423  *
424  * This function returns GGS register value.
425  *
426  * @return      Returns status, either success or error+reason
427  */
428 static enum pm_ret_status pm_ioctl_read_ggs(unsigned int index,
429 					    unsigned int *value)
430 {
431 	if (index >= GGS_NUM_REGS)
432 		return PM_RET_ERROR_ARGS;
433 
434 	return pm_mmio_read(GGS_BASEADDR + (index << 2), value);
435 }
436 
437 /**
438  * pm_ioctl_write_pggs() - Ioctl function for writing persistent
439  *			   global general storage (pggs)
440  * @index	PGGS register index
441  * @value	Register value to be written
442  *
443  * This function writes value to PGGS register.
444  *
445  * @return      Returns status, either success or error+reason
446  */
447 static enum pm_ret_status pm_ioctl_write_pggs(unsigned int index,
448 					      unsigned int value)
449 {
450 	if (index >= PGGS_NUM_REGS)
451 		return PM_RET_ERROR_ARGS;
452 
453 	return pm_mmio_write(PGGS_BASEADDR + (index << 2),
454 			     0xFFFFFFFFU, value);
455 }
456 
457 /**
458  * pm_ioctl_afi() - Ioctl function for writing afi values
459  *
460  * @index 	AFI register index
461  * @value	Register value to be written
462  *
463  *
464  * @return      Returns status, either success or error+reason
465  */
466 static enum pm_ret_status pm_ioctl_afi(unsigned int index,
467 					      unsigned int value)
468 {
469 	unsigned int mask;
470 	unsigned int regarr[] = {0xFD360000,
471 				0xFD360014,
472 				0xFD370000,
473 				0xFD370014,
474 				0xFD380000,
475 				0xFD380014,
476 				0xFD390000,
477 				0xFD390014,
478 				0xFD3a0000,
479 				0xFD3a0014,
480 				0xFD3b0000,
481 				0xFD3b0014,
482 				0xFF9b0000,
483 				0xFF9b0014,
484 				0xFD615000,
485 				0xFF419000,
486 				};
487 
488 	if (index >= ARRAY_SIZE(regarr))
489 		return PM_RET_ERROR_ARGS;
490 
491 	if (index < AFIFM6_WRCTRL)
492 		mask = FABRIC_WIDTH;
493 	else
494 		mask = 0xf00;
495 
496 	return pm_mmio_write(regarr[index], mask, value);
497 }
498 
499 /**
500  * pm_ioctl_read_pggs() - Ioctl function for reading persistent
501  *			  global general storage (pggs)
502  * @index	PGGS register index
503  * @value	Register value
504  *
505  * This function returns PGGS register value.
506  *
507  * @return      Returns status, either success or error+reason
508  */
509 static enum pm_ret_status pm_ioctl_read_pggs(unsigned int index,
510 					     unsigned int *value)
511 {
512 	if (index >= PGGS_NUM_REGS)
513 		return PM_RET_ERROR_ARGS;
514 
515 	return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
516 }
517 
518 /**
519  * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset
520  *
521  * This function peerforms the ULPI reset sequence for resetting
522  * the ULPI transceiver.
523  *
524  * @return      Returns status, either success or error+reason
525  */
526 static enum pm_ret_status pm_ioctl_ulpi_reset(void)
527 {
528 	enum pm_ret_status ret;
529 
530 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
531 			    ZYNQMP_ULPI_RESET_VAL_HIGH);
532 	if (ret != PM_RET_SUCCESS)
533 		return ret;
534 
535 	/* Drive ULPI assert for atleast 1ms */
536 	mdelay(1);
537 
538 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
539 			    ZYNQMP_ULPI_RESET_VAL_LOW);
540 	if (ret != PM_RET_SUCCESS)
541 		return ret;
542 
543 	/* Drive ULPI de-assert for atleast 1ms */
544 	mdelay(1);
545 
546 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
547 			    ZYNQMP_ULPI_RESET_VAL_HIGH);
548 
549 	return ret;
550 }
551 
552 /**
553  * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status
554  *
555  * This function sets healthy bit value to indicate boot health status
556  * to firmware.
557  *
558  * @return      Returns status, either success or error+reason
559  */
560 static enum pm_ret_status pm_ioctl_set_boot_health_status(unsigned int value)
561 {
562 	return pm_mmio_write(PM_BOOT_HEALTH_STATUS_REG,
563 			     PM_BOOT_HEALTH_STATUS_MASK, value);
564 }
565 
566 /**
567  * pm_api_ioctl() -  PM IOCTL API for device control and configs
568  * @node_id	Node ID of the device
569  * @ioctl_id	ID of the requested IOCTL
570  * @arg1	Argument 1 to requested IOCTL call
571  * @arg2	Argument 2 to requested IOCTL call
572  * @value	Returned output value
573  *
574  * This function calls IOCTL to firmware for device control and configuration.
575  *
576  * @return	Returns status, either success or error+reason
577  */
578 enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
579 				unsigned int ioctl_id,
580 				unsigned int arg1,
581 				unsigned int arg2,
582 				unsigned int *value)
583 {
584 	enum pm_ret_status ret;
585 
586 	switch (ioctl_id) {
587 	case IOCTL_GET_RPU_OPER_MODE:
588 		ret = pm_ioctl_get_rpu_oper_mode(value);
589 		break;
590 	case IOCTL_SET_RPU_OPER_MODE:
591 		ret = pm_ioctl_set_rpu_oper_mode(arg1);
592 		break;
593 	case IOCTL_RPU_BOOT_ADDR_CONFIG:
594 		ret = pm_ioctl_config_boot_addr(nid, arg1);
595 		break;
596 	case IOCTL_TCM_COMB_CONFIG:
597 		ret = pm_ioctl_config_tcm_comb(arg1);
598 		break;
599 	case IOCTL_SET_TAPDELAY_BYPASS:
600 		ret = pm_ioctl_set_tapdelay_bypass(arg1, arg2);
601 		break;
602 	case IOCTL_SET_SGMII_MODE:
603 		ret = pm_ioctl_set_sgmii_mode(nid, arg1);
604 		break;
605 	case IOCTL_SD_DLL_RESET:
606 		ret = pm_ioctl_sd_dll_reset(nid, arg1);
607 		break;
608 	case IOCTL_SET_SD_TAPDELAY:
609 		ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2);
610 		break;
611 	case IOCTL_SET_PLL_FRAC_MODE:
612 		ret = pm_ioctl_set_pll_frac_mode(arg1, arg2);
613 		break;
614 	case IOCTL_GET_PLL_FRAC_MODE:
615 		ret = pm_ioctl_get_pll_frac_mode(arg1, value);
616 		break;
617 	case IOCTL_SET_PLL_FRAC_DATA:
618 		ret = pm_ioctl_set_pll_frac_data(arg1, arg2);
619 		break;
620 	case IOCTL_GET_PLL_FRAC_DATA:
621 		ret = pm_ioctl_get_pll_frac_data(arg1, value);
622 		break;
623 	case IOCTL_WRITE_GGS:
624 		ret = pm_ioctl_write_ggs(arg1, arg2);
625 		break;
626 	case IOCTL_READ_GGS:
627 		ret = pm_ioctl_read_ggs(arg1, value);
628 		break;
629 	case IOCTL_WRITE_PGGS:
630 		ret = pm_ioctl_write_pggs(arg1, arg2);
631 		break;
632 	case IOCTL_READ_PGGS:
633 		ret = pm_ioctl_read_pggs(arg1, value);
634 		break;
635 	case IOCTL_ULPI_RESET:
636 		ret = pm_ioctl_ulpi_reset();
637 		break;
638 	case IOCTL_SET_BOOT_HEALTH_STATUS:
639 		ret = pm_ioctl_set_boot_health_status(arg1);
640 		break;
641 	case IOCTL_AFI:
642 		ret = pm_ioctl_afi(arg1, arg2);
643 		break;
644 	default:
645 		ret = PM_RET_ERROR_NOTSUPPORTED;
646 		break;
647 	}
648 
649 	return ret;
650 }
651