/*
 * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

/*
 * ZynqMP system level PM-API functions for ioctl.
 */

#include <arch_helpers.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include <plat/common/platform.h>
#include <zynqmp_def.h>

#include "pm_api_clock.h"
#include "pm_api_ioctl.h"
#include "pm_api_sys.h"
#include "pm_client.h"
#include "pm_common.h"
#include "pm_ipi.h"

/**
 * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode
 * @mode	Buffer to store value of oper mode(Split/Lock-step)
 *
 * This function provides current configured RPU operational mode.
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(uint32_t *mode)
{
	uint32_t val;

	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
	val &= ZYNQMP_SLSPLIT_MASK;
	if (val == 0U) {
		*mode = PM_RPU_MODE_LOCKSTEP;
	} else {
		*mode = PM_RPU_MODE_SPLIT;
	}

	return PM_RET_SUCCESS;
}

/**
 * pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode
 * @mode	Value to set for oper mode(Split/Lock-step)
 *
 * This function configures RPU operational mode(Split/Lock-step).
 * It also sets TCM combined mode in RPU lock-step and TCM non-combined
 * mode for RPU split mode. In case of Lock step mode, RPU1's output is
 * clamped.
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(uint32_t mode)
{
	uint32_t val;

	if (mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET) {
		return PM_RET_ERROR_ACCESS;
	}

	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);

	if (mode == PM_RPU_MODE_SPLIT) {
		val |= ZYNQMP_SLSPLIT_MASK;
		val &= ~ZYNQMP_TCM_COMB_MASK;
		val &= ~ZYNQMP_SLCLAMP_MASK;
	} else if (mode == PM_RPU_MODE_LOCKSTEP) {
		val &= ~ZYNQMP_SLSPLIT_MASK;
		val |= ZYNQMP_TCM_COMB_MASK;
		val |= ZYNQMP_SLCLAMP_MASK;
	} else {
		return PM_RET_ERROR_ARGS;
	}

	mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);

	return PM_RET_SUCCESS;
}

/**
 * pm_ioctl_config_boot_addr() - Configure RPU boot address
 * @nid		Node ID of RPU
 * @value	Value to set for boot address (TCM/OCM)
 *
 * This function configures RPU boot address(memory).
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_config_boot_addr(enum pm_node_id nid,
						    uint32_t value)
{
	uint32_t rpu_cfg_addr, val;

	if (nid == NODE_RPU_0) {
		rpu_cfg_addr = ZYNQMP_RPU0_CFG;
	} else if (nid == NODE_RPU_1) {
		rpu_cfg_addr = ZYNQMP_RPU1_CFG;
	} else {
		return PM_RET_ERROR_ARGS;
	}

	val = mmio_read_32(rpu_cfg_addr);

	if (value == PM_RPU_BOOTMEM_LOVEC) {
		val &= ~ZYNQMP_VINITHI_MASK;
	} else if (value == PM_RPU_BOOTMEM_HIVEC) {
		val |= ZYNQMP_VINITHI_MASK;
	} else {
		return PM_RET_ERROR_ARGS;
	}

	mmio_write_32(rpu_cfg_addr, val);

	return PM_RET_SUCCESS;
}

/**
 * pm_ioctl_config_tcm_comb() - Configure TCM combined mode
 * @value	Value to set (Split/Combined)
 *
 * This function configures TCM to be in split mode or combined
 * mode.
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_config_tcm_comb(uint32_t value)
{
	uint32_t val;

	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);

	if (value == PM_RPU_TCM_SPLIT) {
		val &= ~ZYNQMP_TCM_COMB_MASK;
	} else if (value == PM_RPU_TCM_COMB) {
		val |= ZYNQMP_TCM_COMB_MASK;
	} else {
		return PM_RET_ERROR_ARGS;
	}

	mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);

	return PM_RET_SUCCESS;
}

/**
 * pm_ioctl_set_tapdelay_bypass() -  Enable/Disable tap delay bypass
 * @type	Type of tap delay to enable/disable (e.g. QSPI)
 * @value	Enable/Disable
 *
 * This function enable/disable tap delay bypass.
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(uint32_t type,
						       uint32_t value)
{
	if ((value != PM_TAPDELAY_BYPASS_ENABLE &&
	     value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX) {
		return PM_RET_ERROR_ARGS;
	}

	return pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK, value << type);
}

/**
 * pm_ioctl_set_sgmii_mode() -  Set SGMII mode for the GEM device
 * @nid		Node ID of the device
 * @value	Enable/Disable
 *
 * This function enable/disable SGMII mode for the GEM device.
 * While enabling SGMII mode, it also ties the GEM PCS Signal
 * Detect to 1 and selects EMIO for RX clock generation.
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_set_sgmii_mode(enum pm_node_id nid,
						  uint32_t value)
{
	uint32_t val, mask, shift;
	enum pm_ret_status ret;

	if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE) {
		return PM_RET_ERROR_ARGS;
	}

	switch (nid) {
	case NODE_ETH_0:
		shift = 0;
		break;
	case NODE_ETH_1:
		shift = 1;
		break;
	case NODE_ETH_2:
		shift = 2;
		break;
	case NODE_ETH_3:
		shift = 3;
		break;
	default:
		return PM_RET_ERROR_ARGS;
	}

	if (value == PM_SGMII_DISABLE) {
		mask = GEM_SGMII_MASK << GEM_CLK_CTRL_OFFSET * shift;
		ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, 0U);
	} else {
		/* Tie the GEM PCS Signal Detect to 1 */
		mask = SGMII_SD_MASK << SGMII_SD_OFFSET * shift;
		val = SGMII_PCS_SD_1 << SGMII_SD_OFFSET * shift;
		ret = pm_mmio_write(IOU_GEM_CTRL, mask, val);
		if (ret != PM_RET_SUCCESS) {
			return ret;
		}

		/* Set the GEM to SGMII mode */
		mask = GEM_CLK_CTRL_MASK << GEM_CLK_CTRL_OFFSET * shift;
		val = GEM_RX_SRC_SEL_GTR | GEM_SGMII_MODE;
		val <<= GEM_CLK_CTRL_OFFSET * shift;
		ret =  pm_mmio_write(IOU_GEM_CLK_CTRL, mask, val);
	}

	return ret;
}

/**
 * pm_ioctl_sd_dll_reset() -  Reset DLL logic
 * @nid		Node ID of the device
 * @type	Reset type
 *
 * This function resets DLL logic for the SD device.
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid,
						uint32_t type)
{
	uint32_t mask, val;
	enum pm_ret_status ret;

	if (nid == NODE_SD_0) {
		mask = ZYNQMP_SD0_DLL_RST_MASK;
		val = ZYNQMP_SD0_DLL_RST;
	} else if (nid == NODE_SD_1) {
		mask = ZYNQMP_SD1_DLL_RST_MASK;
		val = ZYNQMP_SD1_DLL_RST;
	} else {
		return PM_RET_ERROR_ARGS;
	}

	switch (type) {
	case PM_DLL_RESET_ASSERT:
	case PM_DLL_RESET_PULSE:
		ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, val);
		if (ret != PM_RET_SUCCESS) {
			return ret;
		}

		if (type == PM_DLL_RESET_ASSERT) {
			break;
		}
		mdelay(1);
		/* Fallthrough */
	case PM_DLL_RESET_RELEASE:
		ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, 0);
		break;
	default:
		ret = PM_RET_ERROR_ARGS;
		break;
	}

	return ret;
}

/**
 * pm_ioctl_sd_set_tapdelay() -  Set tap delay for the SD device
 * @nid		Node ID of the device
 * @type	Type of tap delay to set (input/output)
 * @value	Value to set fot the tap delay
 *
 * This function sets input/output tap delay for the SD device.
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
						   enum tap_delay_type type,
						   uint32_t value)
{
	uint32_t shift;
	enum pm_ret_status ret;
	uint32_t val, mask;

	if (nid == NODE_SD_0) {
		shift = 0;
		mask = ZYNQMP_SD0_DLL_RST_MASK;
	} else if (nid == NODE_SD_1) {
		shift = ZYNQMP_SD_TAP_OFFSET;
		mask = ZYNQMP_SD1_DLL_RST_MASK;
	} else {
		return PM_RET_ERROR_ARGS;
	}

	ret = pm_mmio_read(ZYNQMP_SD_DLL_CTRL, &val);
	if (ret != PM_RET_SUCCESS) {
		return ret;
	}

	if ((val & mask) == 0U) {
		ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT);
		if (ret != PM_RET_SUCCESS) {
			return ret;
		}
	}

	if (type == PM_TAPDELAY_INPUT) {
		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
				    (ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
				    (ZYNQMP_SD_ITAPCHGWIN << shift));

		if (ret != PM_RET_SUCCESS) {
			goto reset_release;
		}

		if (value == 0U) {
			ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
					    (ZYNQMP_SD_ITAPDLYENA_MASK <<
					     shift), 0);
		} else {
			ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
					    (ZYNQMP_SD_ITAPDLYENA_MASK <<
					    shift), (ZYNQMP_SD_ITAPDLYENA <<
					    shift));
		}

		if (ret != PM_RET_SUCCESS) {
			goto reset_release;
		}

		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
				    (ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
				    (value << shift));

		if (ret != PM_RET_SUCCESS) {
			goto reset_release;
		}

		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
				    (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
	} else if (type == PM_TAPDELAY_OUTPUT) {
		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
				    (ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0);

		if (ret != PM_RET_SUCCESS) {
			goto reset_release;
		}

		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
				    (ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
				    (value << shift));
	} else {
		ret = PM_RET_ERROR_ARGS;
	}

reset_release:
	if ((val & mask) == 0) {
		(void)pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE);
	}

	return ret;
}

/**
 * pm_ioctl_set_pll_frac_mode() -  Ioctl function for
 *				   setting pll mode
 * @pll     PLL clock id
 * @mode    Mode fraction/integar
 *
 * This function sets PLL mode
 *
 * @return      Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_set_pll_frac_mode
			(uint32_t pll, uint32_t mode)
{
	return pm_clock_set_pll_mode(pll, mode);
}

/**
 * pm_ioctl_get_pll_frac_mode() -  Ioctl function for
 *				   getting pll mode
 * @pll     PLL clock id
 * @mode    Mode fraction/integar
 *
 * This function return current PLL mode
 *
 * @return      Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_get_pll_frac_mode
			(uint32_t pll, uint32_t *mode)
{
	return pm_clock_get_pll_mode(pll, mode);
}

/**
 * pm_ioctl_set_pll_frac_data() -  Ioctl function for
 *				   setting pll fraction data
 * @pll     PLL clock id
 * @data    fraction data
 *
 * This function sets fraction data.
 * It is valid for fraction mode only.
 *
 * @return      Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_set_pll_frac_data
			(uint32_t pll, uint32_t data)
{
	enum pm_node_id pll_nid;
	enum pm_ret_status status;

	/* Get PLL node ID using PLL clock ID */
	status = pm_clock_get_pll_node_id(pll, &pll_nid);
	if (status != PM_RET_SUCCESS) {
		return status;
	}

	return pm_pll_set_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
}

/**
 * pm_ioctl_get_pll_frac_data() -  Ioctl function for
 *				   getting pll fraction data
 * @pll     PLL clock id
 * @data    fraction data
 *
 * This function returns fraction data value.
 *
 * @return      Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_get_pll_frac_data
			(uint32_t pll, uint32_t *data)
{
	enum pm_node_id pll_nid;
	enum pm_ret_status status;

	/* Get PLL node ID using PLL clock ID */
	status = pm_clock_get_pll_node_id(pll, &pll_nid);
	if (status != PM_RET_SUCCESS) {
		return status;
	}

	return pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
}

/**
 * pm_ioctl_write_ggs() - Ioctl function for writing
 *			  global general storage (ggs)
 * @index	GGS register index
 * @value	Register value to be written
 *
 * This function writes value to GGS register.
 *
 * @return      Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_write_ggs(uint32_t index,
					     uint32_t value)
{
	if (index >= GGS_NUM_REGS) {
		return PM_RET_ERROR_ARGS;
	}

	return pm_mmio_write(GGS_BASEADDR + (index << 2),
			     0xFFFFFFFFU, value);
}

/**
 * pm_ioctl_read_ggs() - Ioctl function for reading
 *			 global general storage (ggs)
 * @index	GGS register index
 * @value	Register value
 *
 * This function returns GGS register value.
 *
 * @return      Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_read_ggs(uint32_t index,
					    uint32_t *value)
{
	if (index >= GGS_NUM_REGS) {
		return PM_RET_ERROR_ARGS;
	}

	return pm_mmio_read(GGS_BASEADDR + (index << 2), value);
}

/**
 * pm_ioctl_write_pggs() - Ioctl function for writing persistent
 *			   global general storage (pggs)
 * @index	PGGS register index
 * @value	Register value to be written
 *
 * This function writes value to PGGS register.
 *
 * @return      Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_write_pggs(uint32_t index,
					      uint32_t value)
{
	if (index >= PGGS_NUM_REGS) {
		return PM_RET_ERROR_ARGS;
	}

	return pm_mmio_write(PGGS_BASEADDR + (index << 2),
			     0xFFFFFFFFU, value);
}

/**
 * pm_ioctl_afi() - Ioctl function for writing afi values
 *
 * @index 	AFI register index
 * @value	Register value to be written
 *
 *
 * @return      Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_afi(uint32_t index,
					      uint32_t value)
{
	uint32_t mask;
	uint32_t regarr[] = {0xFD360000U,
				0xFD360014U,
				0xFD370000U,
				0xFD370014U,
				0xFD380000U,
				0xFD380014U,
				0xFD390000U,
				0xFD390014U,
				0xFD3a0000U,
				0xFD3a0014U,
				0xFD3b0000U,
				0xFD3b0014U,
				0xFF9b0000U,
				0xFF9b0014U,
				0xFD615000U,
				0xFF419000U,
				};

	if (index >= ARRAY_SIZE(regarr)) {
		return PM_RET_ERROR_ARGS;
	}

	if (index < AFIFM6_WRCTRL) {
		mask = FABRIC_WIDTH;
	} else {
		mask = 0xf00;
	}

	return pm_mmio_write(regarr[index], mask, value);
}

/**
 * pm_ioctl_read_pggs() - Ioctl function for reading persistent
 *			  global general storage (pggs)
 * @index	PGGS register index
 * @value	Register value
 *
 * This function returns PGGS register value.
 *
 * @return      Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_read_pggs(uint32_t index,
					     uint32_t *value)
{
	if (index >= PGGS_NUM_REGS) {
		return PM_RET_ERROR_ARGS;
	}

	return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
}

/**
 * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset
 *
 * This function peerforms the ULPI reset sequence for resetting
 * the ULPI transceiver.
 *
 * @return      Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_ulpi_reset(void)
{
	enum pm_ret_status ret;

	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
			    ZYNQMP_ULPI_RESET_VAL_HIGH);
	if (ret != PM_RET_SUCCESS) {
		return ret;
	}

	/* Drive ULPI assert for atleast 1ms */
	mdelay(1);

	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
			    ZYNQMP_ULPI_RESET_VAL_LOW);
	if (ret != PM_RET_SUCCESS) {
		return ret;
	}

	/* Drive ULPI de-assert for atleast 1ms */
	mdelay(1);

	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
			    ZYNQMP_ULPI_RESET_VAL_HIGH);

	return ret;
}

/**
 * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status
 *
 * This function sets healthy bit value to indicate boot health status
 * to firmware.
 *
 * @return      Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_set_boot_health_status(uint32_t value)
{
	return pm_mmio_write(PMU_GLOBAL_GEN_STORAGE4,
			     PM_BOOT_HEALTH_STATUS_MASK, value);
}

/**
 * pm_api_ioctl() -  PM IOCTL API for device control and configs
 * @node_id	Node ID of the device
 * @ioctl_id	ID of the requested IOCTL
 * @arg1	Argument 1 to requested IOCTL call
 * @arg2	Argument 2 to requested IOCTL call
 * @value	Returned output value
 *
 * This function calls IOCTL to firmware for device control and configuration.
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
				uint32_t ioctl_id,
				uint32_t arg1,
				uint32_t arg2,
				uint32_t *value)
{
	enum pm_ret_status ret;
	uint32_t payload[PAYLOAD_ARG_CNT];

	switch (ioctl_id) {
	case IOCTL_GET_RPU_OPER_MODE:
		ret = pm_ioctl_get_rpu_oper_mode(value);
		break;
	case IOCTL_SET_RPU_OPER_MODE:
		ret = pm_ioctl_set_rpu_oper_mode(arg1);
		break;
	case IOCTL_RPU_BOOT_ADDR_CONFIG:
		ret = pm_ioctl_config_boot_addr(nid, arg1);
		break;
	case IOCTL_TCM_COMB_CONFIG:
		ret = pm_ioctl_config_tcm_comb(arg1);
		break;
	case IOCTL_SET_TAPDELAY_BYPASS:
		ret = pm_ioctl_set_tapdelay_bypass(arg1, arg2);
		break;
	case IOCTL_SET_SGMII_MODE:
		ret = pm_ioctl_set_sgmii_mode(nid, arg1);
		break;
	case IOCTL_SD_DLL_RESET:
		ret = pm_ioctl_sd_dll_reset(nid, arg1);
		break;
	case IOCTL_SET_SD_TAPDELAY:
		ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2);
		break;
	case IOCTL_SET_PLL_FRAC_MODE:
		ret = pm_ioctl_set_pll_frac_mode(arg1, arg2);
		break;
	case IOCTL_GET_PLL_FRAC_MODE:
		ret = pm_ioctl_get_pll_frac_mode(arg1, value);
		break;
	case IOCTL_SET_PLL_FRAC_DATA:
		ret = pm_ioctl_set_pll_frac_data(arg1, arg2);
		break;
	case IOCTL_GET_PLL_FRAC_DATA:
		ret = pm_ioctl_get_pll_frac_data(arg1, value);
		break;
	case IOCTL_WRITE_GGS:
		ret = pm_ioctl_write_ggs(arg1, arg2);
		break;
	case IOCTL_READ_GGS:
		ret = pm_ioctl_read_ggs(arg1, value);
		break;
	case IOCTL_WRITE_PGGS:
		ret = pm_ioctl_write_pggs(arg1, arg2);
		break;
	case IOCTL_READ_PGGS:
		ret = pm_ioctl_read_pggs(arg1, value);
		break;
	case IOCTL_ULPI_RESET:
		ret = pm_ioctl_ulpi_reset();
		break;
	case IOCTL_SET_BOOT_HEALTH_STATUS:
		ret = pm_ioctl_set_boot_health_status(arg1);
		break;
	case IOCTL_AFI:
		ret = pm_ioctl_afi(arg1, arg2);
		break;
	default:
		/* Send request to the PMU */
		PM_PACK_PAYLOAD5(payload, PM_IOCTL, nid, ioctl_id, arg1, arg2);

		ret = pm_ipi_send_sync(primary_proc, payload, value, 1);
		break;
	}

	return ret;
}

/**
 * pm_update_ioctl_bitmask() -  API to get supported IOCTL ID mask
 * @bit_mask		Returned bit mask of supported IOCTL IDs
 */
enum pm_ret_status atf_ioctl_bitmask(uint32_t *bit_mask)
{
	uint8_t supported_ids[] = {
		IOCTL_GET_RPU_OPER_MODE,
		IOCTL_SET_RPU_OPER_MODE,
		IOCTL_RPU_BOOT_ADDR_CONFIG,
		IOCTL_TCM_COMB_CONFIG,
		IOCTL_SET_TAPDELAY_BYPASS,
		IOCTL_SET_SGMII_MODE,
		IOCTL_SD_DLL_RESET,
		IOCTL_SET_SD_TAPDELAY,
		IOCTL_SET_PLL_FRAC_MODE,
		IOCTL_GET_PLL_FRAC_MODE,
		IOCTL_SET_PLL_FRAC_DATA,
		IOCTL_GET_PLL_FRAC_DATA,
		IOCTL_WRITE_GGS,
		IOCTL_READ_GGS,
		IOCTL_WRITE_PGGS,
		IOCTL_READ_PGGS,
		IOCTL_ULPI_RESET,
		IOCTL_SET_BOOT_HEALTH_STATUS,
		IOCTL_AFI,
	};
	uint8_t i, ioctl_id;
	int32_t ret;

	for (i = 0U; i < ARRAY_SIZE(supported_ids); i++) {
		ioctl_id = supported_ids[i];
		if (ioctl_id >= 64U) {
			return PM_RET_ERROR_NOTSUPPORTED;
		}
		ret = check_api_dependency(ioctl_id);
		if (ret == PM_RET_SUCCESS) {
			bit_mask[ioctl_id / 32] |= BIT(ioctl_id % 32);
		}
	}

	return PM_RET_SUCCESS;
}
