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

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

#include <arch_helpers.h>
#include <platform.h>
#include "pm_api_clock.h"
#include "pm_api_ioctl.h"
#include "pm_api_pinctrl.h"
#include "pm_api_sys.h"
#include "pm_client.h"
#include "pm_common.h"
#include "pm_ipi.h"

/**
 * Assigning of argument values into array elements.
 */
#define PM_PACK_PAYLOAD1(pl, arg0) {	\
	pl[0] = (uint32_t)(arg0);	\
}

#define PM_PACK_PAYLOAD2(pl, arg0, arg1) {	\
	pl[1] = (uint32_t)(arg1);		\
	PM_PACK_PAYLOAD1(pl, arg0);		\
}

#define PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2) {	\
	pl[2] = (uint32_t)(arg2);			\
	PM_PACK_PAYLOAD2(pl, arg0, arg1);		\
}

#define PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3) {	\
	pl[3] = (uint32_t)(arg3);			\
	PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2);		\
}

#define PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4) {	\
	pl[4] = (uint32_t)(arg4);				\
	PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3);		\
}

#define PM_PACK_PAYLOAD6(pl, arg0, arg1, arg2, arg3, arg4, arg5) {	\
	pl[5] = (uint32_t)(arg5);					\
	PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4);		\
}

/**
 * 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,
				   unsigned int latency,
				   unsigned int state,
				   uintptr_t address)
{
	uint32_t payload[PAYLOAD_ARG_CNT];
	unsigned int 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,
				  unsigned int latency, unsigned int 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,
				 unsigned int set_address,
				 uintptr_t address,
				 enum pm_request_ack ack)
{
	uint32_t payload[PAYLOAD_ARG_CNT];
	uint64_t encoded_address;
	const struct pm_proc *proc = pm_get_proc_by_node(target);

	/* invoke APU-specific code for waking up another APU core */
	pm_client_wakeup(proc);

	/* 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(primary_proc, payload);
}

/**
 * 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,
					unsigned int enable)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	PM_PACK_PAYLOAD4(payload, PM_SET_WAKEUP_SOURCE, target, wkup_node,
			 enable);
	return pm_ipi_send(primary_proc, payload);
}

/**
 * pm_system_shutdown() - PM call to request a system shutdown or restart
 * @restart	Shutdown or restart? 0 for shutdown, 1 for restart
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_system_shutdown(unsigned int type, unsigned int subtype)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	PM_PACK_PAYLOAD3(payload, PM_SYSTEM_SHUTDOWN, type, subtype);
	return pm_ipi_send(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,
			       unsigned int capabilities,
			       unsigned int 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,
				      unsigned int capabilities,
				      unsigned int 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);
}

/**
 * pm_release_node() - PM call to release a node
 * @nid		Node id of the slave
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_release_node(enum pm_node_id nid)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	PM_PACK_PAYLOAD2(payload, PM_RELEASE_NODE, nid);
	return pm_ipi_send(primary_proc, payload);
}

/**
 * pm_set_max_latency() - PM call to set wakeup latency requirements
 * @nid		Node id of the slave
 * @latency	Requested maximum wakeup latency
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_set_max_latency(enum pm_node_id nid,
				      unsigned int latency)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	PM_PACK_PAYLOAD3(payload, PM_SET_MAX_LATENCY, nid, latency);
	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(unsigned int *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_set_configuration() - PM call to set system configuration
 * @phys_addr	Physical 32-bit address of data structure in memory
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_set_configuration(unsigned int phys_addr)
{
	return PM_RET_ERROR_NOTSUPPORTED;
}

/**
 * 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_register_notifier() - Register the PU to be notified of PM events
 * @nid		Node id of the slave
 * @event	The event to be notified about
 * @wake	Wake up on event
 * @enable	Enable or disable the notifier
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_register_notifier(enum pm_node_id nid,
					unsigned int event,
					unsigned int wake,
					unsigned int enable)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	PM_PACK_PAYLOAD5(payload, PM_REGISTER_NOTIFIER,
			 nid, event, wake, enable);

	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}

/**
 * pm_get_op_characteristic() - PM call to request operating characteristics
 *				of a node
 * @nid		Node id of the slave
 * @type	Type of the operating characteristic
 *		(power, temperature and latency)
 * @result	Returns the operating characteristic for the requested node,
 *		specified by the type
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_get_op_characteristic(enum pm_node_id nid,
					    enum pm_opchar_type type,
					    uint32_t *result)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD3(payload, PM_GET_OP_CHARACTERISTIC, nid, type);
	return pm_ipi_send_sync(primary_proc, payload, result, 1);
}

/* Direct-Control API functions */

/**
 * pm_reset_assert() - Assert reset
 * @reset	Reset ID
 * @assert	Assert (1) or de-assert (0)
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_reset_assert(unsigned int reset,
				   unsigned int assert)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD3(payload, PM_RESET_ASSERT, reset, assert);
	return pm_ipi_send(primary_proc, payload);
}

/**
 * pm_reset_get_status() - Get current status of a reset line
 * @reset	Reset ID
 * @reset_status Returns current status of selected reset line
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_reset_get_status(unsigned int reset,
				       unsigned int *reset_status)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

	/* Send request to the PMU */
	PM_PACK_PAYLOAD2(payload, PM_RESET_GET_STATUS, reset);
	return pm_ipi_send_sync(primary_proc, payload, reset_status, 1);
}

/**
 * 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,
				 unsigned int mask,
				 unsigned int 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, unsigned int *value)
{
	uint32_t payload[PAYLOAD_ARG_CNT];

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

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

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

/**
 * 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(unsigned int *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_get_callbackdata() - Read from IPI response buffer
 * @data - array of PAYLOAD_ARG_CNT elements
 *
 * Read value from ipi buffer response buffer.
 */
void pm_get_callbackdata(uint32_t *data, size_t count)
{
	pm_ipi_buff_read_callb(data, count);
	pm_ipi_irq_clear(primary_proc);
}

/**
 * pm_pinctrl_request() - Request Pin from firmware
 * @pin		Pin number to request
 *
 * This function requests pin from firmware.
 *
 * @return	Returns status, either success or error+reason.
 */
enum pm_ret_status pm_pinctrl_request(unsigned int pin)
{
	return PM_RET_SUCCESS;
}

/**
 * pm_pinctrl_release() - Release Pin from firmware
 * @pin		Pin number to release
 *
 * This function releases pin from firmware.
 *
 * @return	Returns status, either success or error+reason.
 */
enum pm_ret_status pm_pinctrl_release(unsigned int pin)
{
	return PM_RET_SUCCESS;
}

/**
 * pm_pinctrl_get_function() - Read function id set for the given pin
 * @pin		Pin number
 * @nid		Node ID of function currently set for given pin
 *
 * This function provides the function currently set for the given pin.
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_pinctrl_get_function(unsigned int pin,
					   enum pm_node_id *nid)
{
	return pm_api_pinctrl_get_function(pin, nid);
}

/**
 * pm_pinctrl_set_function() - Set function id set for the given pin
 * @pin		Pin number
 * @nid		Node ID of function to set for given pin
 *
 * This function provides the function currently set for the given pin.
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_pinctrl_set_function(unsigned int pin,
					   enum pm_node_id nid)
{
	return pm_api_pinctrl_set_function(pin, (unsigned int)nid);
}

/**
 * pm_pinctrl_get_config() - Read value of requested config param for given pin
 * @pin		Pin number
 * @param	Parameter values to be read
 * @value	Buffer for configuration Parameter value
 *
 * This function provides the configuration parameter value for the given pin.
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_pinctrl_get_config(unsigned int pin,
					 unsigned int param,
					 unsigned int *value)
{
	return pm_api_pinctrl_get_config(pin, param, value);
}

/**
 * pm_pinctrl_set_config() - Read value of requested config param for given pin
 * @pin		Pin number
 * @param	Parameter to set
 * @value	Parameter value to set
 *
 * This function provides the configuration parameter value for the given pin.
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_pinctrl_set_config(unsigned int pin,
					 unsigned int param,
					 unsigned int value)
{
	return pm_api_pinctrl_set_config(pin, param, value);
}

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

/**
 * 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.
 *
 * @return	Returns status, either success or error+reason
 */
static enum pm_ret_status pm_clock_get_name(unsigned int clock_id, char *name)
{
	return 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(unsigned int clock_id,
						unsigned int 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(unsigned int 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(unsigned int clock_id,
					       unsigned int 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(unsigned int clock_id,
						  uint32_t *attr)
{
	return pm_api_clock_get_attributes(clock_id, attr);
}

/**
 * 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: Returns status, either success or error+reason.
 */

enum pm_ret_status pm_clock_enable(unsigned int clock_id)
{
	return pm_api_clock_enable(clock_id);
}

/**
 * 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: Returns status, either success or error+reason.
 */

enum pm_ret_status pm_clock_disable(unsigned int clock_id)
{
	return pm_api_clock_disable(clock_id);
}

/**
 * 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(unsigned int clock_id,
				     unsigned int *state)
{
	return pm_api_clock_getstate(clock_id, state);
}

/**
 * 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(unsigned int clock_id,
				       unsigned int divider)
{
	return pm_api_clock_setdivider(clock_id, divider);
}

/**
 * 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(unsigned int clock_id,
				       unsigned int *divider)
{
	return pm_api_clock_getdivider(clock_id, divider);
}

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

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

/**
 * pm_clock_setparent - Set the clock parent for given id
 * @clock_id: Id of the clock
 * @parent_id: parent id
 *
 * 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(unsigned int clock_id,
				      unsigned int parent_id)
{
	return pm_api_clock_setparent(clock_id, parent_id);
}

/**
 * pm_clock_getparent - Get the clock parent for given id
 * @clock_id: Id of the clock
 * @parent_id: parent id
 *
 * 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(unsigned int clock_id,
				      unsigned int *parent_id)
{
	return pm_api_clock_getparent(clock_id, parent_id);
}

/**
 * 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(unsigned int 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
 *
 * Return: Returns status, either success or error+reason.
 */
static enum pm_ret_status pm_pinctrl_get_function_name(unsigned int fid,
						       char *name)
{
	return 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(unsigned int fid,
							 unsigned int 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(unsigned int pin_id,
						    unsigned int index,
						    uint16_t *groups)
{
	return pm_api_pinctrl_get_pin_groups(pin_id, index, groups);
}

/**
 * pm_query_data() -  PM API for querying firmware data
 * @arg1	Argument 1 to requested IOCTL call
 * @arg2	Argument 2 to requested IOCTL call
 * @arg3	Argument 3 to requested IOCTL call
 * @arg4	Argument 4 to requested IOCTL call
 * @data	Returned output data
 *
 * This function returns requested data.
 *
 * @return	Returns status, either success or error+reason
 */
enum pm_ret_status pm_query_data(enum pm_query_id qid,
				 unsigned int arg1,
				 unsigned int arg2,
				 unsigned int arg3,
				 unsigned int *data)
{
	enum pm_ret_status ret;

	switch (qid) {
	case PM_QID_CLOCK_GET_NAME:
		ret = pm_clock_get_name(arg1, (char *)data);
		break;
	case PM_QID_CLOCK_GET_TOPOLOGY:
		ret = pm_clock_get_topology(arg1, arg2, &data[1]);
		data[0] = (unsigned int)ret;
		break;
	case PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS:
		ret = pm_clock_get_fixedfactor_params(arg1, &data[1], &data[2]);
		data[0] = (unsigned int)ret;
		break;
	case PM_QID_CLOCK_GET_PARENTS:
		ret = pm_clock_get_parents(arg1, arg2, &data[1]);
		data[0] = (unsigned int)ret;
		break;
	case PM_QID_CLOCK_GET_ATTRIBUTES:
		ret = pm_clock_get_attributes(arg1, &data[1]);
		data[0] = (unsigned int)ret;
		break;
	case PM_QID_PINCTRL_GET_NUM_PINS:
		ret = pm_pinctrl_get_num_pins(&data[1]);
		data[0] = (unsigned int)ret;
		break;
	case PM_QID_PINCTRL_GET_NUM_FUNCTIONS:
		ret = pm_pinctrl_get_num_functions(&data[1]);
		data[0] = (unsigned int)ret;
		break;
	case PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS:
		ret = pm_pinctrl_get_num_function_groups(arg1, &data[1]);
		data[0] = (unsigned int)ret;
		break;
	case PM_QID_PINCTRL_GET_FUNCTION_NAME:
		ret = pm_pinctrl_get_function_name(arg1, (char *)data);
		break;
	case PM_QID_PINCTRL_GET_FUNCTION_GROUPS:
		ret = pm_pinctrl_get_function_groups(arg1, arg2,
						     (uint16_t *)&data[1]);
		data[0] = (unsigned int)ret;
		break;
	case PM_QID_PINCTRL_GET_PIN_GROUPS:
		ret = pm_pinctrl_get_pin_groups(arg1, arg2,
						(uint16_t *)&data[1]);
		data[0] = (unsigned int)ret;
		break;
	default:
		ret = PM_RET_ERROR_ARGS;
		WARN("Unimplemented query service call: 0x%x\n", qid);
		break;
	}

	return ret;
}
