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

#include <arch.h>
#include <arch_helpers.h>
#include <assert.h>
#include <debug.h>
#include <delay_timer.h>
#include <denver.h>
#include <mmio.h>
#include <mce_private.h>
#include <platform.h>
#include <sys/errno.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 == (uint32_t)TEGRA_ARI_MISC_CCPLEX) &&
		    ((lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) ||
		     (lo == (uint32_t)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)
{
	uint32_t val = 0U;

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

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

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

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

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

	/* set the updated cstate info */
	return ari_request_wait(ari_base, 0U, TEGRA_ARI_UPDATE_CSTATE_INFO, 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() & (uint64_t)(MPIDR_CPU_MASK);
	uint64_t cluster = (read_mpidr() & (uint64_t)(MPIDR_CLUSTER_MASK)) >>
			   (uint64_t)(MPIDR_AFFINITY_BITS);
	uint64_t impl = (read_midr() >> (uint64_t)MIDR_IMPL_SHIFT) & (uint64_t)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 == (uint32_t)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 >> 32UL));
	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 << 32UL) |
					 (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 > (uint32_t)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;
	uint8_t req_cmd, req_status;

	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 : 0UL;

		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 = (uint8_t)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);
	}
}
