/*
 * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
 * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. 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_client.h"
#include "pm_common.h"
#include "pm_ipi.h"
#include "zynqmp_pm_api_sys.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))

/**
 * typedef eemi_api_dependency - Dependent EEMI APIs which are implemented
 *                               on both the TF-A 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 TF-A 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_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 TF-A */
static const uint8_t tfa_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;
}

/**
 * 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.
 * @flags: Additional flags or settings for the fpga operation.
 *
 * 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.
 * @address_low: lower 32-bit Linear memory space address.
 * @address_high: higher 32-bit Linear memory space address.
 * @size: Number of 32bit words.
 * @flags: Additional flags or settings for the fpga operation.
 *
 * This function provides access to the xilsecure library to load the
 * authenticated, encrypted, and authenticated/encrypted images.
 *
 * 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.
 * @address_low: lower 32-bit address of the AesParams structure.
 * @address_high: higher 32-bit address of the AesParams structure.
 * @value: Returned output value.
 *
 * This function provides access to the xilsecure library to
 * encrypt/decrypt data blobs.
 *
 * 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.
 * @count: Number of values to return.
 *
 * Read value from ipi buffer response buffer.
 * Return: Returns status, either success or error.
 *
 */
enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count)
{
	enum pm_ret_status ret = PM_RET_SUCCESS;
	/* Return if interrupt is not from PMU */
	if (!pm_ipi_irq_status(primary_proc)) {
		return ret;
	}

	ret = pm_ipi_buff_read_callb(data, count);
	pm_ipi_irq_clear(primary_proc);
	return ret;
}

/**
 * pm_ioctl() - PM IOCTL API for device control and configs.
 * @nid: 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_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.
 * @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 TF-A expected version */
			if (version != tfa_expected_ver_id[api_dep_table[i].api_id]) {
				return PM_RET_ERROR_NOTSUPPORTED;
			}
		}
	}

	return PM_RET_SUCCESS;
}

/**
 * feature_check_tfa() - These are API's completely implemented in TF-A.
 * @api_id: API ID to check.
 * @version: Returned supported API version.
 * @bit_mask: Returned supported IOCTL id version.
 *
 * Return: Returns status, either success or error+reason.
 *
 */
static enum pm_ret_status feature_check_tfa(uint32_t api_id, uint32_t *version,
					    uint32_t *bit_mask)
{
	switch (api_id) {
	case PM_QUERY_DATA:
		*version = TFA_API_QUERY_DATA_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 = TFA_API_BASE_VERSION;
		return PM_RET_SUCCESS;
	default:
		return PM_RET_ERROR_NO_FEATURE;
	}
}

/**
 * get_tfa_version_for_partial_apis() - Return TF-A 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_tfa_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 = TFA_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
 *                           TF-A 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_tfa_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 TF-A */
	status = feature_check_tfa(api_id, version, bit_mask);
	if (status != PM_RET_ERROR_NO_FEATURE) {
		return status;
	}

	/* Get API version implemented by firmware and TF-A 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 TF-A
	 */
	if ((api_id != PM_IOCTL) && (status != PM_RET_SUCCESS)) {
		return status;
	}

	*version = ret_payload[0];

	/* Update IOCTL bit mask which are implemented in TF-A */
	if ((api_id == PM_IOCTL) || (api_id == PM_GET_OP_CHARACTERISTIC)) {
		if (len < 2) {
			return PM_RET_ERROR_ARGS;
		}
		bit_mask[0] = ret_payload[1];
		bit_mask[1] = ret_payload[2];
		if (api_id == PM_IOCTL) {
			/* Get IOCTL's implemented by TF-A */
			status = tfa_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.
 * @nclocks: 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_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.
 * @qid:  represents the query identifiers for PM.
 * @arg1: Argument 1 to requested IOCTL call.
 * @arg2: Argument 2 to requested IOCTL call.
 * @arg3: Argument 3 to requested IOCTL call.
 * @data: Returned output data.
 *
 * This function returns requested data.
 *
 */
void pm_query_data(enum pm_query_ids 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);
}
