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

/*
 * ZynqMP system level PM-API functions and communication with PMU via
 * IPI interrupts
 */

#include <arch_helpers.h>
#include <plat/common/platform.h>

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

#define PM_QUERY_FEATURE_BITMASK ( \
	(1ULL << (uint64_t)PM_QID_CLOCK_GET_NAME) | \
	(1ULL << (uint64_t)PM_QID_CLOCK_GET_TOPOLOGY) |	\
	(1ULL << (uint64_t)PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS) | \
	(1ULL << (uint64_t)PM_QID_CLOCK_GET_PARENTS) | \
	(1ULL << (uint64_t)PM_QID_CLOCK_GET_ATTRIBUTES) | \
	(1ULL << (uint64_t)PM_QID_PINCTRL_GET_NUM_PINS) | \
	(1ULL << (uint64_t)PM_QID_PINCTRL_GET_NUM_FUNCTIONS) | \
	(1ULL << (uint64_t)PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS) | \
	(1ULL << (uint64_t)PM_QID_PINCTRL_GET_FUNCTION_NAME) | \
	(1ULL << (uint64_t)PM_QID_PINCTRL_GET_FUNCTION_GROUPS) | \
	(1ULL << (uint64_t)PM_QID_PINCTRL_GET_PIN_GROUPS) | \
	(1ULL << (uint64_t)PM_QID_CLOCK_GET_NUM_CLOCKS) | \
	(1ULL << (uint64_t)PM_QID_CLOCK_GET_MAX_DIVISOR))

/**
 * struct eemi_api_dependency - Dependent EEMI APIs which are implemented
 * on both the ATF and firmware
 *
 * @id:		EEMI API id or IOCTL id to be checked
 * @api_id:	Dependent EEMI API
 */
typedef struct __attribute__((packed)) {
	uint8_t id;
	uint8_t api_id;
} eemi_api_dependency;

/* Dependent APIs for ATF to check their version from firmware */
static const eemi_api_dependency api_dep_table[] = {
	{
		.id = PM_SELF_SUSPEND,
		.api_id = PM_SELF_SUSPEND,
	},
	{
		.id = PM_REQ_WAKEUP,
		.api_id = PM_REQ_WAKEUP,
	},
	{
		.id = PM_ABORT_SUSPEND,
		.api_id = PM_ABORT_SUSPEND,
	},
	{
		.id = PM_SET_WAKEUP_SOURCE,
		.api_id = PM_SET_WAKEUP_SOURCE,
	},
	{
		.id = PM_SYSTEM_SHUTDOWN,
		.api_id = PM_SYSTEM_SHUTDOWN,
	},
	{
		.id = PM_GET_API_VERSION,
		.api_id = PM_GET_API_VERSION,
	},
	{
		.id = PM_CLOCK_ENABLE,
		.api_id = PM_PLL_SET_MODE,
	},
	{
		.id = PM_CLOCK_ENABLE,
		.api_id = PM_CLOCK_ENABLE,
	},
	{
		.id = PM_CLOCK_DISABLE,
		.api_id = PM_PLL_SET_MODE,
	},
	{
		.id = PM_CLOCK_DISABLE,
		.api_id = PM_CLOCK_DISABLE,
	},
	{
		.id = PM_CLOCK_GETSTATE,
		.api_id = PM_PLL_GET_MODE,
	},
	{
		.id = PM_CLOCK_GETSTATE,
		.api_id = PM_CLOCK_GETSTATE,
	},
	{
		.id = PM_CLOCK_SETDIVIDER,
		.api_id = PM_PLL_SET_PARAMETER,
	},
	{
		.id = PM_CLOCK_SETDIVIDER,
		.api_id = PM_CLOCK_SETDIVIDER,
	},
	{
		.id = PM_CLOCK_GETDIVIDER,
		.api_id = PM_PLL_GET_PARAMETER,
	},
	{
		.id = PM_CLOCK_GETDIVIDER,
		.api_id = PM_CLOCK_GETDIVIDER,
	},
	{
		.id = PM_CLOCK_SETPARENT,
		.api_id = PM_PLL_SET_PARAMETER,
	},
	{
		.id = PM_CLOCK_SETPARENT,
		.api_id = PM_CLOCK_SETPARENT,
	},
	{
		.id = PM_CLOCK_GETPARENT,
		.api_id = PM_PLL_GET_PARAMETER,
	},
	{
		.id = PM_CLOCK_GETPARENT,
		.api_id = PM_CLOCK_GETPARENT,
	},
	{
		.id = PM_PLL_SET_PARAMETER,
		.api_id = PM_PLL_SET_PARAMETER,
	},
	{
		.id = PM_PLL_GET_PARAMETER,
		.api_id = PM_PLL_GET_PARAMETER,
	},
	{
		.id = PM_PLL_SET_MODE,
		.api_id = PM_PLL_SET_MODE,
	},
	{
		.id = PM_PLL_GET_MODE,
		.api_id = PM_PLL_GET_MODE,
	},
	{
		.id = PM_REGISTER_ACCESS,
		.api_id = PM_MMIO_WRITE,
	},
	{
		.id = PM_REGISTER_ACCESS,
		.api_id = PM_MMIO_READ,
	},
	{
		.id = PM_FEATURE_CHECK,
		.api_id = PM_FEATURE_CHECK,
	},
	{
		.id = IOCTL_SET_TAPDELAY_BYPASS,
		.api_id = PM_MMIO_WRITE,
	},
	{
		.id = IOCTL_SET_SGMII_MODE,
		.api_id = PM_MMIO_WRITE,
	},
	{
		.id = IOCTL_SD_DLL_RESET,
		.api_id = PM_MMIO_WRITE,
	},
	{
		.id = IOCTL_SET_SD_TAPDELAY,
		.api_id = PM_MMIO_WRITE,
	},
	{
		.id = IOCTL_SET_SD_TAPDELAY,
		.api_id = PM_MMIO_READ,
	},
	{
		.id = IOCTL_SET_PLL_FRAC_DATA,
		.api_id = PM_PLL_SET_PARAMETER,
	},
	{
		.id = IOCTL_GET_PLL_FRAC_DATA,
		.api_id = PM_PLL_GET_PARAMETER,
	},
	{
		.id = IOCTL_WRITE_GGS,
		.api_id = PM_MMIO_WRITE,
	},
	{
		.id = IOCTL_READ_GGS,
		.api_id = PM_MMIO_READ,
	},
	{
		.id = IOCTL_WRITE_PGGS,
		.api_id = PM_MMIO_WRITE,
	},
	{
		.id = IOCTL_READ_PGGS,
		.api_id = PM_MMIO_READ,
	},
	{
		.id = IOCTL_ULPI_RESET,
		.api_id = PM_MMIO_WRITE,
	},
	{
		.id = IOCTL_SET_BOOT_HEALTH_STATUS,
		.api_id = PM_MMIO_WRITE,
	},
	{
		.id = IOCTL_AFI,
		.api_id = PM_MMIO_WRITE,
	},
};

/* Expected firmware API version to ATF */
static const uint8_t atf_expected_ver_id[] = {
	[PM_SELF_SUSPEND] = FW_API_BASE_VERSION,
	[PM_REQ_WAKEUP] = FW_API_BASE_VERSION,
	[PM_ABORT_SUSPEND] = FW_API_BASE_VERSION,
	[PM_SET_WAKEUP_SOURCE] = FW_API_BASE_VERSION,
	[PM_SYSTEM_SHUTDOWN] = FW_API_BASE_VERSION,
	[PM_GET_API_VERSION] = FW_API_BASE_VERSION,
	[PM_PLL_SET_MODE] = FW_API_BASE_VERSION,
	[PM_PLL_GET_MODE] = FW_API_BASE_VERSION,
	[PM_CLOCK_ENABLE] = FW_API_BASE_VERSION,
	[PM_CLOCK_DISABLE] = FW_API_BASE_VERSION,
	[PM_CLOCK_GETSTATE] = FW_API_BASE_VERSION,
	[PM_PLL_SET_PARAMETER] = FW_API_BASE_VERSION,
	[PM_PLL_GET_PARAMETER] = FW_API_BASE_VERSION,
	[PM_CLOCK_SETDIVIDER] = FW_API_BASE_VERSION,
	[PM_CLOCK_GETDIVIDER] = FW_API_BASE_VERSION,
	[PM_CLOCK_SETPARENT] = FW_API_BASE_VERSION,
	[PM_CLOCK_GETPARENT] = FW_API_BASE_VERSION,
	[PM_MMIO_WRITE] = FW_API_BASE_VERSION,
	[PM_MMIO_READ] = FW_API_BASE_VERSION,
	[PM_FEATURE_CHECK] = FW_API_VERSION_2,
};

/* default shutdown/reboot scope is system(2) */
static uint32_t pm_shutdown_scope = PMF_SHUTDOWN_SUBTYPE_SYSTEM;

/**
 * pm_get_shutdown_scope() - Get the currently set shutdown scope
 *
 * @return	Shutdown scope value
 */
uint32_t pm_get_shutdown_scope(void)
{
	return pm_shutdown_scope;
}

#define EM_PACK_PAYLOAD1(pl, arg0) {	\
	pl[0] = (uint16_t)(0xE) << 16 | (uint16_t)arg0;	\
}

/**
 * pm_self_suspend() - PM call for processor to suspend itself
 * @nid		Node id of the processor or subsystem
 * @latency	Requested maximum wakeup latency (not supported)
 * @state	Requested state
 * @address	Resume address
 *
 * This is a blocking call, it will return only once PMU has responded.
 * On a wakeup, resume address will be automatically set by PMU.
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_self_suspend(enum pm_node_id nid,
				   uint32_t latency,
				   uint32_t state,
				   uintptr_t address)
{
	uint32_t payload[PAYLOAD_ARG_CNT];
	uint32_t cpuid = plat_my_core_pos();
	const struct pm_proc *proc = pm_get_proc(cpuid);

	/*
	 * Do client specific suspend operations
	 * (e.g. set powerdown request bit)
	 */
	pm_client_suspend(proc, state);
	/* Send request to the PMU */
	PM_PACK_PAYLOAD6(payload, PM_SELF_SUSPEND, proc->node_id, latency,
			 state, address, (address >> 32));
	return pm_ipi_send_sync(proc, payload, NULL, 0);
}

/**
 * pm_req_suspend() - PM call to request for another PU or subsystem to
 *		      be suspended gracefully.
 * @target	Node id of the targeted PU or subsystem
 * @ack		Flag to specify whether acknowledge is requested
 * @latency	Requested wakeup latency (not supported)
 * @state	Requested state (not supported)
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_req_suspend(enum pm_node_id target,
				  enum pm_request_ack ack,
				  uint32_t latency, uint32_t state)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD5(payload, PM_REQ_SUSPEND, target, ack, latency, state);
	if (ack == REQ_ACK_BLOCKING) {
		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
	} else {
		return pm_ipi_send(primary_proc, payload);
	}
}

/**
 * pm_req_wakeup() - PM call for processor to wake up selected processor
 *		     or subsystem
 * @target	Node id of the processor or subsystem to wake up
 * @ack		Flag to specify whether acknowledge requested
 * @set_address	Resume address presence indicator
 *				1 resume address specified, 0 otherwise
 * @address	Resume address
 *
 * This API function is either used to power up another APU core for SMP
 * (by PSCI) or to power up an entirely different PU or subsystem, such
 * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
 * automatically set by PMU.
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_req_wakeup(enum pm_node_id target,
				 uint32_t set_address,
				 uintptr_t address,
				 enum pm_request_ack ack)
{
	uint32_t payload[PAYLOAD_ARG_CNT];
	uint64_t encoded_address;


	/* encode set Address into 1st bit of address */
	encoded_address = address;
	encoded_address |= !!set_address;

	/* Send request to the PMU to perform the wake of the PU */
	PM_PACK_PAYLOAD5(payload, PM_REQ_WAKEUP, target, encoded_address,
			 encoded_address >> 32, ack);

	if (ack == REQ_ACK_BLOCKING) {
		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
	} else {
		return pm_ipi_send(primary_proc, payload);
	}
}

/**
 * pm_force_powerdown() - PM call to request for another PU or subsystem to
 *			  be powered down forcefully
 * @target	Node id of the targeted PU or subsystem
 * @ack		Flag to specify whether acknowledge is requested
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_force_powerdown(enum pm_node_id target,
				      enum pm_request_ack ack)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD3(payload, PM_FORCE_POWERDOWN, target, ack);

	if (ack == REQ_ACK_BLOCKING) {
		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
	} else {
		return pm_ipi_send(primary_proc, payload);
	}
}

/**
 * pm_abort_suspend() - PM call to announce that a prior suspend request
 *			is to be aborted.
 * @reason	Reason for the abort
 *
 * Calling PU expects the PMU to abort the initiated suspend procedure.
 * This is a non-blocking call without any acknowledge.
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/*
	 * Do client specific abort suspend operations
	 * (e.g. enable interrupts and clear powerdown request bit)
	 */
	pm_client_abort_suspend();
	/* Send request to the PMU */
	/* TODO: allow passing the node ID of the affected CPU */
	PM_PACK_PAYLOAD3(payload, PM_ABORT_SUSPEND, reason,
			 primary_proc->node_id);
	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}

/**
 * pm_set_wakeup_source() - PM call to specify the wakeup source while suspended
 * @target	Node id of the targeted PU or subsystem
 * @wkup_node	Node id of the wakeup peripheral
 * @enable	Enable or disable the specified peripheral as wake source
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_set_wakeup_source(enum pm_node_id target,
					enum pm_node_id wkup_node,
					uint32_t enable)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	PM_PACK_PAYLOAD4(payload, PM_SET_WAKEUP_SOURCE, target, wkup_node,
			 enable);
	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}

/**
 * pm_system_shutdown() - PM call to request a system shutdown or restart
 * @type	Shutdown or restart? 0=shutdown, 1=restart, 2=setscope
 * @subtype	Scope: 0=APU-subsystem, 1=PS, 2=system
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	if (type == PMF_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
		/* Setting scope for subsequent PSCI reboot or shutdown */
		pm_shutdown_scope = subtype;
		return PM_RET_SUCCESS;
	}

	PM_PACK_PAYLOAD3(payload, PM_SYSTEM_SHUTDOWN, type, subtype);
	return pm_ipi_send_non_blocking(primary_proc, payload);
}

/* APIs for managing PM slaves: */

/**
 * pm_req_node() - PM call to request a node with specific capabilities
 * @nid		Node id of the slave
 * @capabilities Requested capabilities of the slave
 * @qos		Quality of service (not supported)
 * @ack		Flag to specify whether acknowledge is requested
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_req_node(enum pm_node_id nid,
			       uint32_t capabilities,
			       uint32_t qos,
			       enum pm_request_ack ack)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	PM_PACK_PAYLOAD5(payload, PM_REQ_NODE, nid, capabilities, qos, ack);

	if (ack == REQ_ACK_BLOCKING) {
		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
	} else {
		return pm_ipi_send(primary_proc, payload);
	}
}

/**
 * pm_set_requirement() - PM call to set requirement for PM slaves
 * @nid		Node id of the slave
 * @capabilities Requested capabilities of the slave
 * @qos		Quality of service (not supported)
 * @ack		Flag to specify whether acknowledge is requested
 *
 * This API function is to be used for slaves a PU already has requested
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_set_requirement(enum pm_node_id nid,
				      uint32_t capabilities,
				      uint32_t qos,
				      enum pm_request_ack ack)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	PM_PACK_PAYLOAD5(payload, PM_SET_REQUIREMENT, nid, capabilities, qos,
			 ack);

	if (ack == REQ_ACK_BLOCKING) {
		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
	} else {
		return pm_ipi_send(primary_proc, payload);
	}
}

/* Miscellaneous API functions */

/**
 * pm_get_api_version() - Get version number of PMU PM firmware
 * @version	Returns 32-bit version number of PMU Power Management Firmware
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_get_api_version(uint32_t *version)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD1(payload, PM_GET_API_VERSION);
	return pm_ipi_send_sync(primary_proc, payload, version, 1);
}

/**
 * pm_get_node_status() - PM call to request a node's current status
 * @nid		Node id
 * @ret_buff	Buffer for the return values:
 *		[0] - Current power state of the node
 *		[1] - Current requirements for the node (slave nodes only)
 *		[2] - Current usage status for the node (slave nodes only)
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_get_node_status(enum pm_node_id nid,
				      uint32_t *ret_buff)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	PM_PACK_PAYLOAD2(payload, PM_GET_NODE_STATUS, nid);
	return pm_ipi_send_sync(primary_proc, payload, ret_buff, 3);
}

/**
 * pm_mmio_write() - Perform write to protected mmio
 * @address	Address to write to
 * @mask	Mask to apply
 * @value	Value to write
 *
 * This function provides access to PM-related control registers
 * that may not be directly accessible by a particular PU.
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_mmio_write(uintptr_t address,
				 uint32_t mask,
				 uint32_t value)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD4(payload, PM_MMIO_WRITE, address, mask, value);
	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}

/**
 * pm_mmio_read() - Read value from protected mmio
 * @address	Address to write to
 * @value	Value to write
 *
 * This function provides access to PM-related control registers
 * that may not be directly accessible by a particular PU.
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_mmio_read(uintptr_t address, uint32_t *value)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD2(payload, PM_MMIO_READ, address);
	return pm_ipi_send_sync(primary_proc, payload, value, 1);
}

/**
 * pm_fpga_load() - Load the bitstream into the PL.
 *
 * This function provides access to the xilfpga library to load
 * the Bit-stream into PL.
 *
 * address_low: lower 32-bit Linear memory space address
 *
 * address_high: higher 32-bit Linear memory space address
 *
 * size:	Number of 32bit words
 *
 * @return      Returns status, either success or error+reason
 */
enum pm_ret_status pm_fpga_load(uint32_t address_low,
				uint32_t address_high,
				uint32_t size,
				uint32_t flags)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD5(payload, PM_FPGA_LOAD, address_high, address_low,
						size, flags);
	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}

/**
 * pm_fpga_get_status() - Read value from fpga status register
 * @value       Value to read
 *
 * This function provides access to the xilfpga library to get
 * the fpga status
 * @return      Returns status, either success or error+reason
 */
enum pm_ret_status pm_fpga_get_status(uint32_t *value)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD1(payload, PM_FPGA_GET_STATUS);
	return pm_ipi_send_sync(primary_proc, payload, value, 1);
}

/**
 * pm_get_chipid() - Read silicon ID registers
 * @value       Buffer for return values. Must be large enough
 *		to hold 8 bytes.
 *
 * @return      Returns silicon ID registers
 */
enum pm_ret_status pm_get_chipid(uint32_t *value)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD1(payload, PM_GET_CHIPID);
	return pm_ipi_send_sync(primary_proc, payload, value, 2);
}

/**
 * pm_secure_rsaaes() - Load the secure images.
 *
 * This function provides access to the xilsecure library to load
 * the authenticated, encrypted, and authenicated/encrypted images.
 *
 * address_low: lower 32-bit Linear memory space address
 *
 * address_high: higher 32-bit Linear memory space address
 *
 * size:	Number of 32bit words
 *
 * @return      Returns status, either success or error+reason
 */
enum pm_ret_status pm_secure_rsaaes(uint32_t address_low,
				uint32_t address_high,
				uint32_t size,
				uint32_t flags)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD5(payload, PM_SECURE_RSA_AES, address_high, address_low,
			 size, flags);
	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}

/**
 * pm_aes_engine() - Aes data blob encryption/decryption
 * This function provides access to the xilsecure library to
 * encrypt/decrypt data blobs.
 *
 * address_low: lower 32-bit address of the AesParams structure
 *
 * address_high: higher 32-bit address of the AesParams structure
 *
 * value:        Returned output value
 *
 * @return       Returns status, either success or error+reason
 */
enum pm_ret_status pm_aes_engine(uint32_t address_high,
				 uint32_t address_low,
				 uint32_t *value)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD3(payload, PM_SECURE_AES, address_high, address_low);
	return pm_ipi_send_sync(primary_proc, payload, value, 1);
}

/**
 * pm_get_callbackdata() - Read from IPI response buffer
 * @data - array of PAYLOAD_ARG_CNT elements
 *
 * Read value from ipi buffer response buffer.
 */
void pm_get_callbackdata(uint32_t *data, size_t count)
{
	/* Return if interrupt is not from PMU */
	if (!pm_ipi_irq_status(primary_proc)) {
		return;
	}

	pm_ipi_buff_read_callb(data, count);
	pm_ipi_irq_clear(primary_proc);
}

/**
 * pm_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
 * @out		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_ioctl(enum pm_node_id nid,
			    uint32_t ioctl_id,
			    uint32_t arg1,
			    uint32_t arg2,
			    uint32_t *value)
{
	return pm_api_ioctl(nid, ioctl_id, arg1, arg2, value);
}

/**
 * fw_api_version() - Returns API version implemented in firmware
 * @api_id	API ID to check
 * @version	Returned supported API version
 * @len		Number of words to be returned
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status fw_api_version(uint32_t id, uint32_t *version,
					 uint32_t len)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	PM_PACK_PAYLOAD2(payload, PM_FEATURE_CHECK, id);
	return pm_ipi_send_sync(primary_proc, payload, version, len);
}

/**
 * check_api_dependency() -  API to check dependent EEMI API version
 * @id		EEMI API ID to check
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status check_api_dependency(uint8_t id)
{
	uint8_t i;
	uint32_t version;
	int ret;

	for (i = 0U; i < ARRAY_SIZE(api_dep_table); i++) {
		if (api_dep_table[i].id == id) {
			if (api_dep_table[i].api_id == 0U) {
				break;
			}

			ret = fw_api_version(api_dep_table[i].api_id,
					     &version, 1);
			if (ret != PM_RET_SUCCESS) {
				return ret;
			}

			/* Check if fw version matches ATF expected version */
			if (version != atf_expected_ver_id[api_dep_table[i].api_id]) {
				return PM_RET_ERROR_NOTSUPPORTED;
			}
		}
	}

	return PM_RET_SUCCESS;
}

/**
 * feature_check_atf() - These are API's completely implemented in ATF
 * @api_id	API ID to check
 * @version	Returned supported API version
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status feature_check_atf(uint32_t api_id, uint32_t *version,
					    uint32_t *bit_mask)
{
	switch (api_id) {
	case PM_QUERY_DATA:
		*version = ATF_API_BASE_VERSION;
		bit_mask[0] = (uint32_t)(PM_QUERY_FEATURE_BITMASK);
		bit_mask[1] = (uint32_t)(PM_QUERY_FEATURE_BITMASK >> 32);
		return PM_RET_SUCCESS;
	case PM_GET_CALLBACK_DATA:
	case PM_GET_TRUSTZONE_VERSION:
	case PM_SET_SUSPEND_MODE:
		*version = ATF_API_BASE_VERSION;
		return PM_RET_SUCCESS;
	default:
		return PM_RET_ERROR_NO_FEATURE;
	}
}

/**
 * get_atf_version_for_partial_apis() - Return ATF version for partially
 * implemented APIs
 * @api_id	API ID to check
 * @version	Returned supported API version
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status get_atf_version_for_partial_apis(uint32_t api_id,
							   uint32_t *version)
{
	switch (api_id) {
	case PM_SELF_SUSPEND:
	case PM_REQ_WAKEUP:
	case PM_ABORT_SUSPEND:
	case PM_SET_WAKEUP_SOURCE:
	case PM_SYSTEM_SHUTDOWN:
	case PM_GET_API_VERSION:
	case PM_CLOCK_ENABLE:
	case PM_CLOCK_DISABLE:
	case PM_CLOCK_GETSTATE:
	case PM_CLOCK_SETDIVIDER:
	case PM_CLOCK_GETDIVIDER:
	case PM_CLOCK_SETPARENT:
	case PM_CLOCK_GETPARENT:
	case PM_PLL_SET_PARAMETER:
	case PM_PLL_GET_PARAMETER:
	case PM_PLL_SET_MODE:
	case PM_PLL_GET_MODE:
	case PM_REGISTER_ACCESS:
		*version = ATF_API_BASE_VERSION;
		return PM_RET_SUCCESS;
	case PM_FEATURE_CHECK:
		*version = FW_API_VERSION_2;
		return PM_RET_SUCCESS;
	default:
		return PM_RET_ERROR_ARGS;
	}
}

/**
 * feature_check_partial() - These are API's partially implemented in
 * ATF and firmware both
 * @api_id	API ID to check
 * @version	Returned supported API version
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status feature_check_partial(uint32_t api_id,
						uint32_t *version)
{
	uint32_t status;

	switch (api_id) {
	case PM_SELF_SUSPEND:
	case PM_REQ_WAKEUP:
	case PM_ABORT_SUSPEND:
	case PM_SET_WAKEUP_SOURCE:
	case PM_SYSTEM_SHUTDOWN:
	case PM_GET_API_VERSION:
	case PM_CLOCK_ENABLE:
	case PM_CLOCK_DISABLE:
	case PM_CLOCK_GETSTATE:
	case PM_CLOCK_SETDIVIDER:
	case PM_CLOCK_GETDIVIDER:
	case PM_CLOCK_SETPARENT:
	case PM_CLOCK_GETPARENT:
	case PM_PLL_SET_PARAMETER:
	case PM_PLL_GET_PARAMETER:
	case PM_PLL_SET_MODE:
	case PM_PLL_GET_MODE:
	case PM_REGISTER_ACCESS:
	case PM_FEATURE_CHECK:
		status = check_api_dependency(api_id);
		if (status != PM_RET_SUCCESS) {
			return status;
		}
		return get_atf_version_for_partial_apis(api_id, version);
	default:
		return PM_RET_ERROR_NO_FEATURE;
	}
}

/**
 * pm_feature_check() - Returns the supported API version if supported
 * @api_id	API ID to check
 * @version	Returned supported API version
 * @bit_mask	Returned supported IOCTL id version
 * @len		Number of bytes to be returned in bit_mask variable
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *version,
				    uint32_t *bit_mask, uint8_t len)
{
	uint32_t ret_payload[PAYLOAD_ARG_CNT] = {0U};
	uint32_t status;

	/* Get API version implemented in ATF */
	status = feature_check_atf(api_id, version, bit_mask);
	if (status != PM_RET_ERROR_NO_FEATURE) {
		return status;
	}

	/* Get API version implemented by firmware and ATF both */
	status = feature_check_partial(api_id, version);
	if (status != PM_RET_ERROR_NO_FEATURE) {
		return status;
	}

	/* Get API version implemented by firmware */
	status = fw_api_version(api_id, ret_payload, 3);
	/* IOCTL call may return failure whose ID is not implemented in
	 * firmware but implemented in ATF
	 */
	if ((api_id != PM_IOCTL) && (status != PM_RET_SUCCESS)) {
		return status;
	}

	*version = ret_payload[0];

	/* Update IOCTL bit mask which are implemented in ATF */
	if (api_id == PM_IOCTL) {
		if (len < 2) {
			return PM_RET_ERROR_ARGS;
		}
		bit_mask[0] = ret_payload[1];
		bit_mask[1] = ret_payload[2];
		/* Get IOCTL's implemented by ATF */
		status = atf_ioctl_bitmask(bit_mask);
	} else {
		/* Requires for MISRA */
	}

	return status;
}

/**
 * pm_clock_get_max_divisor - PM call to get max divisor
 * @clock_id	Clock ID
 * @div_type	Divisor ID (TYPE_DIV1 or TYPE_DIV2)
 * @max_div	Maximum supported divisor
 *
 * This function is used by master to get maximum supported value.
 *
 * Return: Returns status, either success or error+reason.
 */
static enum pm_ret_status pm_clock_get_max_divisor(uint32_t clock_id,
						   uint8_t div_type,
						   uint32_t *max_div)
{
	return pm_api_clock_get_max_divisor(clock_id, div_type, max_div);
}

/**
 * pm_clock_get_num_clocks - PM call to request number of clocks
 * @nclockss: Number of clocks
 *
 * This function is used by master to get number of clocks.
 *
 * Return: Returns status, either success or error+reason.
 */
static enum pm_ret_status pm_clock_get_num_clocks(uint32_t *nclocks)
{
	return pm_api_clock_get_num_clocks(nclocks);
}

/**
 * pm_clock_get_name() - PM call to request a clock's name
 * @clock_id	Clock ID
 * @name	Name of clock (max 16 bytes)
 *
 * This function is used by master to get nmae of clock specified
 * by given clock ID.
 */
static void pm_clock_get_name(uint32_t clock_id, char *name)
{
	pm_api_clock_get_name(clock_id, name);
}

/**
 * pm_clock_get_topology() - PM call to request a clock's topology
 * @clock_id	Clock ID
 * @index	Topology index for next toplogy node
 * @topology	Buffer to store nodes in topology and flags
 *
 * This function is used by master to get topology information for the
 * clock specified by given clock ID. Each response would return 3
 * topology nodes. To get next nodes, caller needs to call this API with
 * index of next node. Index starts from 0.
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status pm_clock_get_topology(uint32_t clock_id,
						uint32_t index,
						uint32_t *topology)
{
	return pm_api_clock_get_topology(clock_id, index, topology);
}

/**
 * pm_clock_get_fixedfactor_params() - PM call to request a clock's fixed factor
 *				 parameters for fixed clock
 * @clock_id	Clock ID
 * @mul		Multiplication value
 * @div		Divisor value
 *
 * This function is used by master to get fixed factor parameers for the
 * fixed clock. This API is application only for the fixed clock.
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status pm_clock_get_fixedfactor_params(uint32_t clock_id,
							  uint32_t *mul,
							  uint32_t *div)
{
	return pm_api_clock_get_fixedfactor_params(clock_id, mul, div);
}

/**
 * pm_clock_get_parents() - PM call to request a clock's first 3 parents
 * @clock_id	Clock ID
 * @index	Index of next parent
 * @parents	Parents of the given clock
 *
 * This function is used by master to get clock's parents information.
 * This API will return 3 parents with a single response. To get other
 * parents, master should call same API in loop with new parent index
 * till error is returned.
 *
 * E.g First call should have index 0 which will return parents 0, 1 and
 * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
 * so on.
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status pm_clock_get_parents(uint32_t clock_id,
					       uint32_t index,
					       uint32_t *parents)
{
	return pm_api_clock_get_parents(clock_id, index, parents);
}

/**
 * pm_clock_get_attributes() - PM call to request a clock's attributes
 * @clock_id	Clock ID
 * @attr	Clock attributes
 *
 * This function is used by master to get clock's attributes
 * (e.g. valid, clock type, etc).
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status pm_clock_get_attributes(uint32_t clock_id,
						  uint32_t *attr)
{
	return pm_api_clock_get_attributes(clock_id, attr);
}

/**
 * pm_clock_gate() - Configure clock gate
 * @clock_id	Id of the clock to be configured
 * @enable	Flag 0=disable (gate the clock), !0=enable (activate the clock)
 *
 * @return	Error if an argument is not valid or status as returned by the
 *		PM controller (PMU)
 */
static enum pm_ret_status pm_clock_gate(uint32_t clock_id,
					uint8_t enable)
{
	uint32_t payload[PAYLOAD_ARG_CNT];
	enum pm_ret_status status;
	enum pm_api_id api_id;

	/* Check if clock ID is valid and return an error if it is not */
	status = pm_clock_id_is_valid(clock_id);
	if (status != PM_RET_SUCCESS) {
		return status;
	}

	if (enable) {
		api_id = PM_CLOCK_ENABLE;
	} else {
		api_id = PM_CLOCK_DISABLE;
	}

	/* Send request to the PMU */
	PM_PACK_PAYLOAD2(payload, api_id, clock_id);
	status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);

	/* If action fails due to the lack of permissions filter the error */
	if (status == PM_RET_ERROR_ACCESS) {
		status = PM_RET_SUCCESS;
	}

	return status;
}

/**
 * pm_clock_enable() - Enable the clock for given id
 * @clock_id: Id of the clock to be enabled
 *
 * This function is used by master to enable the clock
 * including peripherals and PLL clocks.
 *
 * @return:	Error if an argument is not valid or status as returned by the
 *		pm_clock_gate
 */
enum pm_ret_status pm_clock_enable(uint32_t clock_id)
{
	struct pm_pll *pll;

	/* First try to handle it as a PLL */
	pll = pm_clock_get_pll(clock_id);
	if (pll) {
		return pm_clock_pll_enable(pll);
	}

	/* It's an on-chip clock, PMU should configure clock's gate */
	return pm_clock_gate(clock_id, 1);
}

/**
 * pm_clock_disable - Disable the clock for given id
 * @clock_id: Id of the clock to be disable
 *
 * This function is used by master to disable the clock
 * including peripherals and PLL clocks.
 *
 * @return:	Error if an argument is not valid or status as returned by the
 *		pm_clock_gate
 */
enum pm_ret_status pm_clock_disable(uint32_t clock_id)
{
	struct pm_pll *pll;

	/* First try to handle it as a PLL */
	pll = pm_clock_get_pll(clock_id);
	if (pll) {
		return pm_clock_pll_disable(pll);
	}

	/* It's an on-chip clock, PMU should configure clock's gate */
	return pm_clock_gate(clock_id, 0);
}

/**
 * pm_clock_getstate - Get the clock state for given id
 * @clock_id: Id of the clock to be queried
 * @state: 1/0 (Enabled/Disabled)
 *
 * This function is used by master to get the state of clock
 * including peripherals and PLL clocks.
 *
 * Return: Returns status, either success or error+reason.
 */
enum pm_ret_status pm_clock_getstate(uint32_t clock_id,
				     uint32_t *state)
{
	struct pm_pll *pll;
	uint32_t payload[PAYLOAD_ARG_CNT];
	enum pm_ret_status status;

	/* First try to handle it as a PLL */
	pll = pm_clock_get_pll(clock_id);
	if (pll)
		return pm_clock_pll_get_state(pll, state);

	/* Check if clock ID is a valid on-chip clock */
	status = pm_clock_id_is_valid(clock_id);
	if (status != PM_RET_SUCCESS) {
		return status;
	}

	/* Send request to the PMU */
	PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETSTATE, clock_id);
	return pm_ipi_send_sync(primary_proc, payload, state, 1);
}

/**
 * pm_clock_setdivider - Set the clock divider for given id
 * @clock_id: Id of the clock
 * @divider: divider value
 *
 * This function is used by master to set divider for any clock
 * to achieve desired rate.
 *
 * Return: Returns status, either success or error+reason.
 */
enum pm_ret_status pm_clock_setdivider(uint32_t clock_id,
				       uint32_t divider)
{
	enum pm_ret_status status;
	enum pm_node_id nid;
	enum pm_clock_div_id div_id;
	uint32_t payload[PAYLOAD_ARG_CNT];
	const uint32_t div0 = 0xFFFF0000;
	const uint32_t div1 = 0x0000FFFF;
	uint32_t val;

	/* Get PLL node ID using PLL clock ID */
	status = pm_clock_get_pll_node_id(clock_id, &nid);
	if (status == PM_RET_SUCCESS) {
		return pm_pll_set_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
	}

	/* Check if clock ID is a valid on-chip clock */
	status = pm_clock_id_is_valid(clock_id);
	if (status != PM_RET_SUCCESS) {
		return status;
	}

	if (div0 == (divider & div0)) {
		div_id = PM_CLOCK_DIV0_ID;
		val = divider & ~div0;
	} else if (div1 == (divider & div1)) {
		div_id = PM_CLOCK_DIV1_ID;
		val = (divider & ~div1) >> 16;
	} else {
		return PM_RET_ERROR_ARGS;
	}

	/* Send request to the PMU */
	PM_PACK_PAYLOAD4(payload, PM_CLOCK_SETDIVIDER, clock_id, div_id, val);
	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}

/**
 * pm_clock_getdivider - Get the clock divider for given id
 * @clock_id: Id of the clock
 * @divider: divider value
 *
 * This function is used by master to get divider values
 * for any clock.
 *
 * Return: Returns status, either success or error+reason.
 */
enum pm_ret_status pm_clock_getdivider(uint32_t clock_id,
				       uint32_t *divider)
{
	enum pm_ret_status status;
	enum pm_node_id nid;
	uint32_t payload[PAYLOAD_ARG_CNT];
	uint32_t val;

	/* Get PLL node ID using PLL clock ID */
	status = pm_clock_get_pll_node_id(clock_id, &nid);
	if (status == PM_RET_SUCCESS) {
		return pm_pll_get_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
	}

	/* Check if clock ID is a valid on-chip clock */
	status = pm_clock_id_is_valid(clock_id);
	if (status != PM_RET_SUCCESS) {
		return status;
	}

	if (pm_clock_has_div(clock_id, PM_CLOCK_DIV0_ID)) {
		/* Send request to the PMU to get div0 */
		PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
				 PM_CLOCK_DIV0_ID);
		status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
		if (status != PM_RET_SUCCESS) {
			return status;
		}
		*divider = val;
	}

	if (pm_clock_has_div(clock_id, PM_CLOCK_DIV1_ID)) {
		/* Send request to the PMU to get div1 */
		PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
				 PM_CLOCK_DIV1_ID);
		status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
		if (status != PM_RET_SUCCESS) {
			return status;
		}
		*divider |= val << 16;
	}

	return status;
}

/**
 * pm_clock_setrate - Set the clock rate for given id
 * @clock_id: Id of the clock
 * @rate: rate value in hz
 *
 * This function is used by master to set rate for any clock.
 *
 * Return: Returns status, either success or error+reason.
 */
enum pm_ret_status pm_clock_setrate(uint32_t clock_id,
				    uint64_t rate)
{
	return PM_RET_ERROR_NOTSUPPORTED;
}

/**
 * pm_clock_getrate - Get the clock rate for given id
 * @clock_id: Id of the clock
 * @rate: rate value in hz
 *
 * This function is used by master to get rate
 * for any clock.
 *
 * Return: Returns status, either success or error+reason.
 */
enum pm_ret_status pm_clock_getrate(uint32_t clock_id,
				    uint64_t *rate)
{
	return PM_RET_ERROR_NOTSUPPORTED;
}

/**
 * pm_clock_setparent - Set the clock parent for given id
 * @clock_id: Id of the clock
 * @parent_index: Index of the parent clock into clock's parents array
 *
 * This function is used by master to set parent for any clock.
 *
 * Return: Returns status, either success or error+reason.
 */
enum pm_ret_status pm_clock_setparent(uint32_t clock_id,
				      uint32_t parent_index)
{
	struct pm_pll *pll;
	uint32_t payload[PAYLOAD_ARG_CNT];
	enum pm_ret_status status;

	/* First try to handle it as a PLL */
	pll = pm_clock_get_pll_by_related_clk(clock_id);
	if (pll) {
		return pm_clock_pll_set_parent(pll, clock_id, parent_index);
	}

	/* Check if clock ID is a valid on-chip clock */
	status = pm_clock_id_is_valid(clock_id);
	if (status != PM_RET_SUCCESS) {
		return status;
	}

	/* Send request to the PMU */
	PM_PACK_PAYLOAD3(payload, PM_CLOCK_SETPARENT, clock_id, parent_index);
	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}

/**
 * pm_clock_getparent - Get the clock parent for given id
 * @clock_id: Id of the clock
 * @parent_index: parent index
 *
 * This function is used by master to get parent index
 * for any clock.
 *
 * Return: Returns status, either success or error+reason.
 */
enum pm_ret_status pm_clock_getparent(uint32_t clock_id,
				      uint32_t *parent_index)
{
	struct pm_pll *pll;
	uint32_t payload[PAYLOAD_ARG_CNT];
	enum pm_ret_status status;

	/* First try to handle it as a PLL */
	pll = pm_clock_get_pll_by_related_clk(clock_id);
	if (pll) {
		return pm_clock_pll_get_parent(pll, clock_id, parent_index);
	}

	/* Check if clock ID is a valid on-chip clock */
	status = pm_clock_id_is_valid(clock_id);
	if (status != PM_RET_SUCCESS) {
		return status;
	}

	/* Send request to the PMU */
	PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETPARENT, clock_id);
	return pm_ipi_send_sync(primary_proc, payload, parent_index, 1);
}

/**
 * pm_pinctrl_get_num_pins - PM call to request number of pins
 * @npins: Number of pins
 *
 * This function is used by master to get number of pins
 *
 * Return: Returns status, either success or error+reason.
 */
static enum pm_ret_status pm_pinctrl_get_num_pins(uint32_t *npins)
{
	return pm_api_pinctrl_get_num_pins(npins);
}

/**
 * pm_pinctrl_get_num_functions - PM call to request number of functions
 * @nfuncs: Number of functions
 *
 * This function is used by master to get number of functions
 *
 * Return: Returns status, either success or error+reason.
 */
static enum pm_ret_status pm_pinctrl_get_num_functions(uint32_t *nfuncs)
{
	return pm_api_pinctrl_get_num_functions(nfuncs);
}

/**
 * pm_pinctrl_get_num_function_groups - PM call to request number of
 *					function groups
 * @fid: Id of function
 * @ngroups: Number of function groups
 *
 * This function is used by master to get number of function groups specified
 * by given function Id
 *
 * Return: Returns status, either success or error+reason.
 */
static enum pm_ret_status pm_pinctrl_get_num_function_groups(uint32_t fid,
							     uint32_t *ngroups)
{
	return pm_api_pinctrl_get_num_func_groups(fid, ngroups);
}

/**
 * pm_pinctrl_get_function_name - PM call to request function name
 * @fid: Id of function
 * @name: Name of function
 *
 * This function is used by master to get name of function specified
 * by given function Id
 */
static void pm_pinctrl_get_function_name(uint32_t fid, char *name)
{
	pm_api_pinctrl_get_function_name(fid, name);
}

/**
 * pm_pinctrl_get_function_groups - PM call to request function groups
 * @fid: Id of function
 * @index: Index of next function groups
 * @groups: Function groups
 *
 * This function is used by master to get function groups specified
 * by given function Id. This API will return 6 function groups with
 * a single response. To get other function groups, master should call
 * same API in loop with new function groups index till error is returned.
 *
 * E.g First call should have index 0 which will return function groups
 * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
 * function groups 6, 7, 8, 9, 10 and 11 and so on.
 *
 * Return: Returns status, either success or error+reason.
 */
static enum pm_ret_status pm_pinctrl_get_function_groups(uint32_t fid,
							 uint32_t index,
							 uint16_t *groups)
{
	return pm_api_pinctrl_get_function_groups(fid, index, groups);
}

/**
 * pm_pinctrl_get_pin_groups - PM call to request pin groups
 * @pin_id: Id of pin
 * @index: Index of next pin groups
 * @groups: pin groups
 *
 * This function is used by master to get pin groups specified
 * by given pin Id. This API will return 6 pin groups with
 * a single response. To get other pin groups, master should call
 * same API in loop with new pin groups index till error is returned.
 *
 * E.g First call should have index 0 which will return pin groups
 * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
 * pin groups 6, 7, 8, 9, 10 and 11 and so on.
 *
 * Return: Returns status, either success or error+reason.
 */
static enum pm_ret_status pm_pinctrl_get_pin_groups(uint32_t pin_id,
						    uint32_t index,
						    uint16_t *groups)
{
	return pm_api_pinctrl_get_pin_groups(pin_id, index, groups);
}

/**
 * pm_query_data() -  PM API for querying firmware data
 * @arg1	Argument 1 to requested IOCTL call
 * @arg2	Argument 2 to requested IOCTL call
 * @arg3	Argument 3 to requested IOCTL call
 * @arg4	Argument 4 to requested IOCTL call
 * @data	Returned output data
 *
 * This function returns requested data.
 */
void pm_query_data(enum pm_query_id qid, uint32_t arg1, uint32_t arg2,
		   uint32_t arg3, uint32_t *data)
{
	switch (qid) {
	case PM_QID_CLOCK_GET_NAME:
		pm_clock_get_name(arg1, (char *)data);
		break;
	case PM_QID_CLOCK_GET_TOPOLOGY:
		data[0] = pm_clock_get_topology(arg1, arg2, &data[1]);
		break;
	case PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS:
		data[0] = pm_clock_get_fixedfactor_params(arg1, &data[1],
							  &data[2]);
		break;
	case PM_QID_CLOCK_GET_PARENTS:
		data[0] = pm_clock_get_parents(arg1, arg2, &data[1]);
		break;
	case PM_QID_CLOCK_GET_ATTRIBUTES:
		data[0] = pm_clock_get_attributes(arg1, &data[1]);
		break;
	case PM_QID_PINCTRL_GET_NUM_PINS:
		data[0] = pm_pinctrl_get_num_pins(&data[1]);
		break;
	case PM_QID_PINCTRL_GET_NUM_FUNCTIONS:
		data[0] = pm_pinctrl_get_num_functions(&data[1]);
		break;
	case PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS:
		data[0] = pm_pinctrl_get_num_function_groups(arg1, &data[1]);
		break;
	case PM_QID_PINCTRL_GET_FUNCTION_NAME:
		pm_pinctrl_get_function_name(arg1, (char *)data);
		break;
	case PM_QID_PINCTRL_GET_FUNCTION_GROUPS:
		data[0] = pm_pinctrl_get_function_groups(arg1, arg2,
							 (uint16_t *)&data[1]);
		break;
	case PM_QID_PINCTRL_GET_PIN_GROUPS:
		data[0] = pm_pinctrl_get_pin_groups(arg1, arg2,
						    (uint16_t *)&data[1]);
		break;
	case PM_QID_CLOCK_GET_NUM_CLOCKS:
		data[0] = pm_clock_get_num_clocks(&data[1]);
		break;

	case PM_QID_CLOCK_GET_MAX_DIVISOR:
		data[0] = pm_clock_get_max_divisor(arg1, arg2, &data[1]);
		break;
	default:
		data[0] = PM_RET_ERROR_ARGS;
		WARN("Unimplemented query service call: 0x%x\n", qid);
		break;
	}
}

enum pm_ret_status pm_sha_hash(uint32_t address_high,
				    uint32_t address_low,
				    uint32_t size,
				    uint32_t flags)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD5(payload, PM_SECURE_SHA, address_high, address_low,
				 size, flags);
	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}

enum pm_ret_status pm_rsa_core(uint32_t address_high,
				    uint32_t address_low,
				    uint32_t size,
				    uint32_t flags)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD5(payload, PM_SECURE_RSA, address_high, address_low,
				 size, flags);
	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}

enum pm_ret_status pm_secure_image(uint32_t address_low,
				   uint32_t address_high,
				   uint32_t key_lo,
				   uint32_t key_hi,
				   uint32_t *value)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD5(payload, PM_SECURE_IMAGE, address_high, address_low,
			 key_hi, key_lo);
	return pm_ipi_send_sync(primary_proc, payload, value, 2);
}

/**
 * pm_fpga_read - Perform the fpga configuration readback
 *
 * @reg_numframes: Configuration register offset (or) Number of frames to read
 * @address_low: lower 32-bit Linear memory space address
 * @address_high: higher 32-bit Linear memory space address
 * @readback_type: Type of fpga readback operation
 *		   0 -- Configuration Register readback
 *		   1 -- Configuration Data readback
 * @value:	Value to read
 *
 * This function provides access to the xilfpga library to read
 * the PL configuration.
 *
 * Return: Returns status, either success or error+reason.
 */
enum pm_ret_status pm_fpga_read(uint32_t reg_numframes,
				uint32_t address_low,
				uint32_t address_high,
				uint32_t readback_type,
				uint32_t *value)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD5(payload, PM_FPGA_READ, reg_numframes, address_low,
			 address_high, readback_type);
	return pm_ipi_send_sync(primary_proc, payload, value, 1);
}

/*
 * pm_pll_set_parameter() - Set the PLL parameter value
 * @nid		Node id of the target PLL
 * @param_id	ID of the PLL parameter
 * @value	Parameter value to be set
 *
 * Setting the parameter will have physical effect once the PLL mode is set to
 * integer or fractional.
 *
 * @return	Error if an argument is not valid or status as returned by the
 *		PM controller (PMU)
 */
enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid,
					enum pm_pll_param param_id,
					uint32_t value)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Check if given node ID is a PLL node */
	if (nid < NODE_APLL || nid > NODE_IOPLL) {
		return PM_RET_ERROR_ARGS;
	}

	/* Check if parameter ID is valid and return an error if it's not */
	if (param_id >= PM_PLL_PARAM_MAX) {
		return PM_RET_ERROR_ARGS;
	}

	/* Send request to the PMU */
	PM_PACK_PAYLOAD4(payload, PM_PLL_SET_PARAMETER, nid, param_id, value);
	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}

/**
 * pm_pll_get_parameter() - Get the PLL parameter value
 * @nid		Node id of the target PLL
 * @param_id	ID of the PLL parameter
 * @value	Location to store the parameter value
 *
 * @return	Error if an argument is not valid or status as returned by the
 *		PM controller (PMU)
 */
enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid,
					enum pm_pll_param param_id,
					uint32_t *value)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Check if given node ID is a PLL node */
	if (nid < NODE_APLL || nid > NODE_IOPLL) {
		return PM_RET_ERROR_ARGS;
	}

	/* Check if parameter ID is valid and return an error if it's not */
	if (param_id >= PM_PLL_PARAM_MAX) {
		return PM_RET_ERROR_ARGS;
	}

	/* Send request to the PMU */
	PM_PACK_PAYLOAD3(payload, PM_PLL_GET_PARAMETER, nid, param_id);
	return pm_ipi_send_sync(primary_proc, payload, value, 1);
}

/**
 * pm_pll_set_mode() - Set the PLL mode
 * @nid		Node id of the target PLL
 * @mode	PLL mode to be set
 *
 * If reset mode is set the PM controller will first bypass the PLL and then
 * assert the reset. If integer or fractional mode is set the PM controller will
 * ensure that the complete PLL programming sequence is satisfied. After this
 * function returns success the PLL is locked and its bypass is deasserted.
 *
 * @return	Error if an argument is not valid or status as returned by the
 *		PM controller (PMU)
 */
enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Check if given node ID is a PLL node */
	if (nid < NODE_APLL || nid > NODE_IOPLL) {
		return PM_RET_ERROR_ARGS;
	}

	/* Check if PLL mode is valid */
	if (mode >= PM_PLL_MODE_MAX) {
		return PM_RET_ERROR_ARGS;
	}

	/* Send request to the PMU */
	PM_PACK_PAYLOAD3(payload, PM_PLL_SET_MODE, nid, mode);
	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}

/**
 * pm_pll_get_mode() - Get the PLL mode
 * @nid		Node id of the target PLL
 * @mode	Location to store the mode of the PLL
 *
 * @return	Error if an argument is not valid or status as returned by the
 *		PM controller (PMU)
 */
enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Check if given node ID is a PLL node */
	if (nid < NODE_APLL || nid > NODE_IOPLL) {
		return PM_RET_ERROR_ARGS;
	}

	/* Send request to the PMU */
	PM_PACK_PAYLOAD2(payload, PM_PLL_GET_MODE, nid);
	return pm_ipi_send_sync(primary_proc, payload, mode, 1);
}

/**
 * pm_register_access() -  PM API for register read/write access data
 *
 * @register_access_id	Register_access_id which says register read/write
 *
 * @address		Address of the register to be accessed
 *
 * @mask		Mask value to be used while writing value
 *
 * @value		Value to be written to register
 *
 * @out			Returned output data
 *
 * This function returns requested data.
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_register_access(uint32_t register_access_id,
				      uint32_t address,
				      uint32_t mask,
				      uint32_t value,
				      uint32_t *out)
{
	enum pm_ret_status ret;

	if (((ZYNQMP_CSU_BASEADDR & address) != ZYNQMP_CSU_BASEADDR) &&
			((CSUDMA_BASE & address) != CSUDMA_BASE) &&
			((RSA_CORE_BASE & address) != RSA_CORE_BASE) &&
			((PMU_GLOBAL_BASE & address) != PMU_GLOBAL_BASE)) {
		return PM_RET_ERROR_ACCESS;
	}

	switch (register_access_id) {
	case CONFIG_REG_WRITE:
		ret = pm_mmio_write(address, mask, value);
		break;
	case CONFIG_REG_READ:
		ret = pm_mmio_read(address, out);
		break;
	default:
		ret = PM_RET_ERROR_ARGS;
		WARN("Unimplemented register_access call\n\r");
		break;
	}
	return ret;
}

/**
 * pm_efuse_access() - To program or read efuse bits.
 *
 * This function provides access to the xilskey library to program/read
 * efuse bits.
 *
 * address_low: lower 32-bit Linear memory space address
 * address_high: higher 32-bit Linear memory space address
 *
 * value: Returned output value
 *
 * @return  Returns status, either success or error+reason
 *
 */
enum pm_ret_status pm_efuse_access(uint32_t address_high,
				   uint32_t address_low,
				   uint32_t *value)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD3(payload, PM_EFUSE_ACCESS, address_high, address_low);

	return pm_ipi_send_sync(primary_proc, payload, value, 1);
}

enum pm_ret_status em_set_action(uint32_t *value)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	EM_PACK_PAYLOAD1(payload, EM_SET_ACTION);
	return pm_ipi_send_sync(primary_proc, payload, value, 1);
}

enum pm_ret_status em_remove_action(uint32_t *value)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	EM_PACK_PAYLOAD1(payload, EM_REMOVE_ACTION);
	return pm_ipi_send_sync(primary_proc, payload, value, 1);
}

enum pm_ret_status em_send_errors(uint32_t *value)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	EM_PACK_PAYLOAD1(payload, EM_SEND_ERRORS);
	return pm_ipi_send_sync(primary_proc, payload, value, 1);
}
