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

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

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

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

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

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

	return PM_RET_SUCCESS;
}

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

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

	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);

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

	mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);

	return PM_RET_SUCCESS;
}

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

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

	val = mmio_read_32(rpu_cfg_addr);

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

	mmio_write_32(rpu_cfg_addr, val);

	return PM_RET_SUCCESS;
}

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

	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);

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

	mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);

	return PM_RET_SUCCESS;
}

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

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

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

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

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

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

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

	return ret;
}

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

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

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

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

	return ret;
}

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

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

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

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

	if (type == PM_TAPDELAY_INPUT) {
		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
				    (ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
				    (ZYNQMP_SD_ITAPCHGWIN << shift));
		if (ret != PM_RET_SUCCESS)
			goto reset_release;
		if (value == 0)
			ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
					    (ZYNQMP_SD_ITAPDLYENA_MASK <<
					     shift), 0);
		else
			ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
					    (ZYNQMP_SD_ITAPDLYENA_MASK <<
					    shift), (ZYNQMP_SD_ITAPDLYENA <<
					    shift));
		if (ret != PM_RET_SUCCESS)
			goto reset_release;
		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
				    (ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
				    (value << shift));
		if (ret != PM_RET_SUCCESS)
			goto reset_release;
		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
				    (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
	} else if (type == PM_TAPDELAY_OUTPUT) {
		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
				    (ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0);
		if (ret != PM_RET_SUCCESS)
			goto reset_release;
		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
				    (ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
				    (value << shift));
	} else {
		ret = PM_RET_ERROR_ARGS;
	}

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

	return ret;
}

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

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

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

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

	return pm_pll_set_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
}

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

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

	return pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
}

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

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

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

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

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

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

/**
 * pm_ioctl_afi() - Ioctl function for writing afi values
 *
 * @index 	AFI register index
 * @value	Register value to be written
 *
 *
 * @return      Returns status, either success or error+reason
 */
static enum pm_ret_status pm_ioctl_afi(unsigned int index,
					      unsigned int value)
{
	unsigned int mask;
	unsigned int regarr[] = {0xFD360000,
				0xFD360014,
				0xFD370000,
				0xFD370014,
				0xFD380000,
				0xFD380014,
				0xFD390000,
				0xFD390014,
				0xFD3a0000,
				0xFD3a0014,
				0xFD3b0000,
				0xFD3b0014,
				0xFF9b0000,
				0xFF9b0014,
				0xFD615000,
				0xFF419000,
				};

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

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

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

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

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

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

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

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

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

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

	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
			    ZYNQMP_ULPI_RESET_VAL_HIGH);

	return ret;
}

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

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

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

	return ret;
}
