/*
 * 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_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 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);
}
