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

#include <assert.h>
#include <errno.h>

#include <arch.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <denver.h>
#include <lib/mmio.h>
#include <plat/common/platform.h>

#include <mce_private.h>
#include <t18x_ari.h>

/*******************************************************************************
 * Register offsets for ARI request/results
 ******************************************************************************/
#define ARI_REQUEST			0x0U
#define ARI_REQUEST_EVENT_MASK		0x4U
#define ARI_STATUS			0x8U
#define ARI_REQUEST_DATA_LO		0xCU
#define ARI_REQUEST_DATA_HI		0x10U
#define ARI_RESPONSE_DATA_LO		0x14U
#define ARI_RESPONSE_DATA_HI		0x18U

/* Status values for the current request */
#define ARI_REQ_PENDING			1U
#define ARI_REQ_ONGOING			3U
#define ARI_REQUEST_VALID_BIT		(1U << 8)
#define ARI_EVT_MASK_STANDBYWFI_BIT	(1U << 7)

/* default timeout (ms) to wait for ARI completion */
#define ARI_MAX_RETRY_COUNT		2000

/*******************************************************************************
 * ARI helper functions
 ******************************************************************************/
static inline uint32_t ari_read_32(uint32_t ari_base, uint32_t reg)
{
	return mmio_read_32((uint64_t)ari_base + (uint64_t)reg);
}

static inline void ari_write_32(uint32_t ari_base, uint32_t val, uint32_t reg)
{
	mmio_write_32((uint64_t)ari_base + (uint64_t)reg, val);
}

static inline uint32_t ari_get_request_low(uint32_t ari_base)
{
	return ari_read_32(ari_base, ARI_REQUEST_DATA_LO);
}

static inline uint32_t ari_get_request_high(uint32_t ari_base)
{
	return ari_read_32(ari_base, ARI_REQUEST_DATA_HI);
}

static inline uint32_t ari_get_response_low(uint32_t ari_base)
{
	return ari_read_32(ari_base, ARI_RESPONSE_DATA_LO);
}

static inline uint32_t ari_get_response_high(uint32_t ari_base)
{
	return ari_read_32(ari_base, ARI_RESPONSE_DATA_HI);
}

static inline void ari_clobber_response(uint32_t ari_base)
{
	ari_write_32(ari_base, 0, ARI_RESPONSE_DATA_LO);
	ari_write_32(ari_base, 0, ARI_RESPONSE_DATA_HI);
}

static int32_t ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t req,
		uint32_t lo, uint32_t hi)
{
	uint32_t retries = ARI_MAX_RETRY_COUNT;
	uint32_t status;
	int32_t ret = 0;

	/* program the request, event_mask, hi and lo registers */
	ari_write_32(ari_base, lo, ARI_REQUEST_DATA_LO);
	ari_write_32(ari_base, hi, ARI_REQUEST_DATA_HI);
	ari_write_32(ari_base, evt_mask, ARI_REQUEST_EVENT_MASK);
	ari_write_32(ari_base, req | ARI_REQUEST_VALID_BIT, ARI_REQUEST);

	/*
	 * For commands that have an event trigger, we should bypass
	 * ARI_STATUS polling, since MCE is waiting for SW to trigger
	 * the event.
	 */
	if (evt_mask != 0U) {
		ret = 0;
	} else {
		/* For shutdown/reboot commands, we dont have to check for timeouts */
		if ((req == TEGRA_ARI_MISC_CCPLEX) &&
		    ((lo == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) ||
		     (lo == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT))) {
				ret = 0;
		} else {
			/*
			 * Wait for the command response for not more than the timeout
			 */
			while (retries != 0U) {

				/* read the command status */
				status = ari_read_32(ari_base, ARI_STATUS);
				if ((status & (ARI_REQ_ONGOING | ARI_REQ_PENDING)) == 0U) {
					break;
				}

				/* delay 1 ms */
				mdelay(1);

				/* decrement the retry count */
				retries--;
			}

			/* assert if the command timed out */
			if (retries == 0U) {
				ERROR("ARI request timed out: req %d on CPU %d\n",
					req, plat_my_core_pos());
				assert(retries != 0U);
			}
		}
	}

	return ret;
}

int32_t ari_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time)
{
	int32_t ret = 0;

	/* check for allowed power state */
	if ((state != TEGRA_ARI_CORE_C0) &&
	    (state != TEGRA_ARI_CORE_C1) &&
	    (state != TEGRA_ARI_CORE_C6) &&
	    (state != TEGRA_ARI_CORE_C7)) {
		ERROR("%s: unknown cstate (%d)\n", __func__, state);
		ret = EINVAL;
	} else {
		/* clean the previous response state */
		ari_clobber_response(ari_base);

		/* Enter the cstate, to be woken up after wake_time (TSC ticks) */
		ret = ari_request_wait(ari_base, ARI_EVT_MASK_STANDBYWFI_BIT,
		TEGRA_ARI_ENTER_CSTATE, state, wake_time);
	}

	return ret;
}

int32_t ari_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex,
	uint32_t system, uint8_t sys_state_force, uint32_t wake_mask,
	uint8_t update_wake_mask)
{
	uint64_t val = 0U;

	/* clean the previous response state */
	ari_clobber_response(ari_base);

	/* update CLUSTER_CSTATE? */
	if (cluster != 0U) {
		val |= (cluster & CLUSTER_CSTATE_MASK) |
			CLUSTER_CSTATE_UPDATE_BIT;
	}

	/* update CCPLEX_CSTATE? */
	if (ccplex != 0U) {
		val |= ((ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT) |
			CCPLEX_CSTATE_UPDATE_BIT;
	}

	/* update SYSTEM_CSTATE? */
	if (system != 0U) {
		val |= ((system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) |
		       (((uint64_t)sys_state_force << SYSTEM_CSTATE_FORCE_UPDATE_SHIFT) |
			SYSTEM_CSTATE_UPDATE_BIT);
	}

	/* update wake mask value? */
	if (update_wake_mask != 0U) {
		val |= CSTATE_WAKE_MASK_UPDATE_BIT;
	}

	/* set the updated cstate info */
	return ari_request_wait(ari_base, 0U, TEGRA_ARI_UPDATE_CSTATE_INFO,
				(uint32_t)val, wake_mask);
}

int32_t ari_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time)
{
	int32_t ret = 0;

	/* sanity check crossover type */
	if ((type == TEGRA_ARI_CROSSOVER_C1_C6) ||
	    (type > TEGRA_ARI_CROSSOVER_CCP3_SC1)) {
		ret = EINVAL;
	} else {
		/* clean the previous response state */
		ari_clobber_response(ari_base);

		/* update crossover threshold time */
		ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_UPDATE_CROSSOVER,
			type, time);
	}

	return ret;
}

uint64_t ari_read_cstate_stats(uint32_t ari_base, uint32_t state)
{
	int32_t ret;
	uint64_t result;

	/* sanity check crossover type */
	if (state == 0U) {
		result = EINVAL;
	} else {
		/* clean the previous response state */
		ari_clobber_response(ari_base);

		ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_CSTATE_STATS, state, 0U);
		if (ret != 0) {
			result = EINVAL;
		} else {
			result = (uint64_t)ari_get_response_low(ari_base);
		}
	}
	return result;
}

int32_t ari_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t stats)
{
	/* clean the previous response state */
	ari_clobber_response(ari_base);

	/* write the cstate stats */
	return ari_request_wait(ari_base, 0U, TEGRA_ARI_WRITE_CSTATE_STATS, state,
			stats);
}

uint64_t ari_enumeration_misc(uint32_t ari_base, uint32_t cmd, uint32_t data)
{
	uint64_t resp;
	int32_t ret;
	uint32_t local_data = data;

	/* clean the previous response state */
	ari_clobber_response(ari_base);

	/* ARI_REQUEST_DATA_HI is reserved for commands other than 'ECHO' */
	if (cmd != TEGRA_ARI_MISC_ECHO) {
		local_data = 0U;
	}

	ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_MISC, cmd, local_data);
	if (ret != 0) {
		resp = (uint64_t)ret;
	} else {
		/* get the command response */
		resp = ari_get_response_low(ari_base);
		resp |= ((uint64_t)ari_get_response_high(ari_base) << 32);
	}

	return resp;
}

int32_t ari_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time)
{
	int32_t ret;
	uint32_t result;

	/* clean the previous response state */
	ari_clobber_response(ari_base);

	ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_IS_CCX_ALLOWED, state & 0x7U,
			wake_time);
	if (ret != 0) {
		ERROR("%s: failed (%d)\n", __func__, ret);
		result = 0U;
	} else {
		result = ari_get_response_low(ari_base) & 0x1U;
	}

	/* 1 = CCx allowed, 0 = CCx not allowed */
	return (int32_t)result;
}

int32_t ari_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time)
{
	int32_t ret, result;

	/* check for allowed power state */
	if ((state != TEGRA_ARI_CORE_C0) && (state != TEGRA_ARI_CORE_C1) &&
	    (state != TEGRA_ARI_CORE_C6) && (state != TEGRA_ARI_CORE_C7)) {
		ERROR("%s: unknown cstate (%d)\n", __func__, state);
		result = EINVAL;
	} else {
		/* clean the previous response state */
		ari_clobber_response(ari_base);

		ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_IS_SC7_ALLOWED, state,
				wake_time);
		if (ret != 0) {
			ERROR("%s: failed (%d)\n", __func__, ret);
			result = 0;
		} else {
			/* 1 = SC7 allowed, 0 = SC7 not allowed */
			result = (ari_get_response_low(ari_base) != 0U) ? 1 : 0;
		}
	}

	return result;
}

int32_t ari_online_core(uint32_t ari_base, uint32_t core)
{
	uint64_t cpu = read_mpidr() & (MPIDR_CPU_MASK);
	uint64_t cluster = (read_mpidr() & (MPIDR_CLUSTER_MASK)) >>
			   (MPIDR_AFFINITY_BITS);
	uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
	int32_t ret;

	/* construct the current CPU # */
	cpu |= (cluster << 2);

	/* sanity check target core id */
	if ((core >= MCE_CORE_ID_MAX) || (cpu == (uint64_t)core)) {
		ERROR("%s: unsupported core id (%d)\n", __func__, core);
		ret = EINVAL;
	} else {
		/*
		 * The Denver cluster has 2 CPUs only - 0, 1.
		 */
		if ((impl == DENVER_IMPL) && ((core == 2U) || (core == 3U))) {
			ERROR("%s: unknown core id (%d)\n", __func__, core);
			ret = EINVAL;
		} else {
			/* clean the previous response state */
			ari_clobber_response(ari_base);
			ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_ONLINE_CORE, core, 0U);
		}
	}

	return ret;
}

int32_t ari_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable)
{
	uint32_t val;

	/* clean the previous response state */
	ari_clobber_response(ari_base);

	/*
	 * If the enable bit is cleared, Auto-CC3 will be disabled by setting
	 * the SW visible voltage/frequency request registers for all non
	 * floorswept cores valid independent of StandbyWFI and disabling
	 * the IDLE voltage/frequency request register. If set, Auto-CC3
	 * will be enabled by setting the ARM SW visible voltage/frequency
	 * request registers for all non floorswept cores to be enabled by
	 * StandbyWFI or the equivalent signal, and always keeping the IDLE
	 * voltage/frequency request register enabled.
	 */
	val = (((freq & MCE_AUTO_CC3_FREQ_MASK) << MCE_AUTO_CC3_FREQ_SHIFT) |\
		((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\
		((enable != 0U) ? MCE_AUTO_CC3_ENABLE_BIT : 0U));

	return ari_request_wait(ari_base, 0U, TEGRA_ARI_CC3_CTRL, val, 0U);
}

int32_t ari_reset_vector_update(uint32_t ari_base)
{
	/* clean the previous response state */
	ari_clobber_response(ari_base);

	/*
	 * Need to program the CPU reset vector one time during cold boot
	 * and SC7 exit
	 */
	(void)ari_request_wait(ari_base, 0U, TEGRA_ARI_COPY_MISCREG_AA64_RST, 0U, 0U);

	return 0;
}

int32_t ari_roc_flush_cache_trbits(uint32_t ari_base)
{
	/* clean the previous response state */
	ari_clobber_response(ari_base);

	return ari_request_wait(ari_base, 0U, TEGRA_ARI_ROC_FLUSH_CACHE_TRBITS,
			0U, 0U);
}

int32_t ari_roc_flush_cache(uint32_t ari_base)
{
	/* clean the previous response state */
	ari_clobber_response(ari_base);

	return ari_request_wait(ari_base, 0U, TEGRA_ARI_ROC_FLUSH_CACHE_ONLY,
			0U, 0U);
}

int32_t ari_roc_clean_cache(uint32_t ari_base)
{
	/* clean the previous response state */
	ari_clobber_response(ari_base);

	return ari_request_wait(ari_base, 0U, TEGRA_ARI_ROC_CLEAN_CACHE_ONLY,
			0U, 0U);
}

uint64_t ari_read_write_mca(uint32_t ari_base, uint64_t cmd, uint64_t *data)
{
	uint64_t mca_arg_data, result = 0;
	uint32_t resp_lo, resp_hi;
	uint32_t mca_arg_err, mca_arg_finish;
	int32_t ret;

	/* Set data (write) */
	mca_arg_data = (data != NULL) ? *data : 0ULL;

	/* Set command */
	ari_write_32(ari_base, (uint32_t)cmd, ARI_RESPONSE_DATA_LO);
	ari_write_32(ari_base, (uint32_t)(cmd >> 32U), ARI_RESPONSE_DATA_HI);

	ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_MCA,
			       (uint32_t)mca_arg_data,
			       (uint32_t)(mca_arg_data >> 32U));
	if (ret == 0) {
		resp_lo = ari_get_response_low(ari_base);
		resp_hi = ari_get_response_high(ari_base);

		mca_arg_err = resp_lo & MCA_ARG_ERROR_MASK;
		mca_arg_finish = (resp_hi >> MCA_ARG_FINISH_SHIFT) &
				 MCA_ARG_FINISH_MASK;

		if (mca_arg_finish == 0U) {
			result = (uint64_t)mca_arg_err;
		} else {
			if (data != NULL) {
				resp_lo = ari_get_request_low(ari_base);
				resp_hi = ari_get_request_high(ari_base);
				*data = ((uint64_t)resp_hi << 32U) |
					 (uint64_t)resp_lo;
			}
		}
	}

	return result;
}

int32_t ari_update_ccplex_gsc(uint32_t ari_base, uint32_t gsc_idx)
{
	int32_t ret = 0;
	/* sanity check GSC ID */
	if (gsc_idx > TEGRA_ARI_GSC_VPR_IDX) {
		ret = EINVAL;
	} else {
		/* clean the previous response state */
		ari_clobber_response(ari_base);

		/*
		 * The MCE code will read the GSC carveout value, corrseponding to
		 * the ID, from the MC registers and update the internal GSC registers
		 * of the CCPLEX.
		 */
		(void)ari_request_wait(ari_base, 0U, TEGRA_ARI_UPDATE_CCPLEX_GSC, gsc_idx, 0U);
	}

	return ret;
}

void ari_enter_ccplex_state(uint32_t ari_base, uint32_t state_idx)
{
	/* clean the previous response state */
	ari_clobber_response(ari_base);

	/*
	 * The MCE will shutdown or restart the entire system
	 */
	(void)ari_request_wait(ari_base, 0U, TEGRA_ARI_MISC_CCPLEX, state_idx, 0U);
}

int32_t ari_read_write_uncore_perfmon(uint32_t ari_base, uint64_t req,
		uint64_t *data)
{
	int32_t ret, result;
	uint32_t val, req_status;
	uint8_t req_cmd;

	req_cmd = (uint8_t)(req >> UNCORE_PERFMON_CMD_SHIFT);

	/* clean the previous response state */
	ari_clobber_response(ari_base);

	/* sanity check input parameters */
	if ((req_cmd == UNCORE_PERFMON_CMD_READ) && (data == NULL)) {
		ERROR("invalid parameters\n");
		result = EINVAL;
	} else {
		/*
		 * For "write" commands get the value that has to be written
		 * to the uncore perfmon registers
		 */
		val = (req_cmd == UNCORE_PERFMON_CMD_WRITE) ?
			(uint32_t)*data : 0U;

		ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_PERFMON, val,
				       (uint32_t)req);
		if (ret != 0) {
			result = ret;
		} else {
			/* read the command status value */
			req_status = ari_get_response_high(ari_base) &
					 UNCORE_PERFMON_RESP_STATUS_MASK;

			/*
			 * For "read" commands get the data from the uncore
			 * perfmon registers
			 */
			req_status >>= UNCORE_PERFMON_RESP_STATUS_SHIFT;
			if ((req_status == 0U) && (req_cmd == UNCORE_PERFMON_CMD_READ)) {
				*data = ari_get_response_low(ari_base);
			}
			result = (int32_t)req_status;
		}
	}

	return result;
}

void ari_misc_ccplex(uint32_t ari_base, uint32_t index, uint32_t value)
{
	/*
	 * This invokes the ARI_MISC_CCPLEX commands. This can be
	 * used to enable/disable coresight clock gating.
	 */

	if ((index > TEGRA_ARI_MISC_CCPLEX_EDBGREQ) ||
		((index == TEGRA_ARI_MISC_CCPLEX_CORESIGHT_CG_CTRL) &&
		(value > 1U))) {
		ERROR("%s: invalid parameters \n", __func__);
	} else {
		/* clean the previous response state */
		ari_clobber_response(ari_base);
		(void)ari_request_wait(ari_base, 0U, TEGRA_ARI_MISC_CCPLEX, index, value);
	}
}
