/*
 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of ARM nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <assert.h>
#include <debug.h>
#include <platform.h>
#include <platform_def.h>
#include "psci_private.h"

#ifndef PLAT_MAX_PWR_LVL_STATES
#define PLAT_MAX_PWR_LVL_STATES 2
#endif

/* Ticks elapsed in one second by a signal of 1 MHz */
#define MHZ_TICKS_PER_SEC 1000000

/* Following structure is used for PSCI STAT */
typedef struct psci_stat {
	u_register_t residency;
	u_register_t count;
} psci_stat_t;

/*
 * Following is used to keep track of the last cpu
 * that goes to power down in non cpu power domains.
 */
static int last_cpu_in_non_cpu_pd[PSCI_NUM_NON_CPU_PWR_DOMAINS] = {-1};

/*
 * Following are used to store PSCI STAT values for
 * CPU and non CPU power domains.
 */
static psci_stat_t psci_cpu_stat[PLATFORM_CORE_COUNT]
				[PLAT_MAX_PWR_LVL_STATES];
static psci_stat_t psci_non_cpu_stat[PSCI_NUM_NON_CPU_PWR_DOMAINS]
				[PLAT_MAX_PWR_LVL_STATES];

/* Register PMF PSCI service */
PMF_REGISTER_SERVICE(psci_svc, PMF_PSCI_STAT_SVC_ID,
	 PSCI_STAT_TOTAL_IDS, PMF_STORE_ENABLE)

/* The divisor to use to convert raw timestamp into microseconds */
u_register_t residency_div;

/*
 * This macro calculates the stats residency in microseconds,
 * taking in account the wrap around condition.
 */
#define calc_stat_residency(_pwrupts, _pwrdnts, _res)		\
	do {							\
		if (_pwrupts < _pwrdnts)			\
			_res = UINT64_MAX - _pwrdnts + _pwrupts;\
		else						\
			_res = _pwrupts - _pwrdnts;		\
		/* Convert timestamp into microseconds */	\
		_res = _res/residency_div;			\
	} while (0)

/*
 * This functions returns the index into the `psci_stat_t` array given the
 * local power state and power domain level. If the platform implements the
 * `get_pwr_lvl_state_idx` pm hook, then that will be used to return the index.
 */
static int get_stat_idx(plat_local_state_t local_state, int pwr_lvl)
{
	int idx;

	if (psci_plat_pm_ops->get_pwr_lvl_state_idx == NULL) {
		assert(PLAT_MAX_PWR_LVL_STATES == 2);
		if (is_local_state_retn(local_state))
			return 0;

		assert(is_local_state_off(local_state));
		return 1;
	}

	idx = psci_plat_pm_ops->get_pwr_lvl_state_idx(local_state, pwr_lvl);
	assert((idx >= 0) && (idx < PLAT_MAX_PWR_LVL_STATES));
	return idx;
}

/*******************************************************************************
 * This function is passed the target local power states for each power
 * domain (state_info) between the current CPU domain and its ancestors until
 * the target power level (end_pwrlvl).
 *
 * Then, for each level (apart from the CPU level) until the 'end_pwrlvl', it
 * updates the `last_cpu_in_non_cpu_pd[]` with last power down cpu id.
 *
 * This function will only be invoked with data cache enabled and while
 * powering down a core.
 ******************************************************************************/
void psci_stats_update_pwr_down(unsigned int end_pwrlvl,
			const psci_power_state_t *state_info)
{
	int lvl, parent_idx, cpu_idx = plat_my_core_pos();

	assert(end_pwrlvl <= PLAT_MAX_PWR_LVL);
	assert(state_info);

	parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node;

	for (lvl = PSCI_CPU_PWR_LVL + 1; lvl <= end_pwrlvl; lvl++) {

		/* Break early if the target power state is RUN */
		if (is_local_state_run(state_info->pwr_domain_state[lvl]))
			break;

		/*
		 * The power domain is entering a low power state, so this is
		 * the last CPU for this power domain
		 */
		last_cpu_in_non_cpu_pd[parent_idx] = cpu_idx;

		parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
	}

}

/*******************************************************************************
 * This function updates the PSCI STATS(residency time and count) for CPU
 * and NON-CPU power domains.
 * It is called with caches enabled and locks acquired(for NON-CPU domain)
 ******************************************************************************/
void psci_stats_update_pwr_up(unsigned int end_pwrlvl,
			const psci_power_state_t *state_info,
			unsigned int flags)
{
	int parent_idx, cpu_idx = plat_my_core_pos();
	int lvl, stat_idx;
	plat_local_state_t local_state;
	unsigned long long pwrup_ts = 0, pwrdn_ts = 0;
	u_register_t residency;

	assert(end_pwrlvl <= PLAT_MAX_PWR_LVL);
	assert(state_info);

	/* Initialize the residency divisor if not already initialized */
	if (!residency_div) {
		/* Pre-calculate divisor so that it can be directly used to
		   convert time-stamp into microseconds */
		residency_div = read_cntfrq_el0() / MHZ_TICKS_PER_SEC;
		assert(residency_div);
	}

	/* Get power down time-stamp for current CPU */
	PMF_GET_TIMESTAMP_BY_INDEX(psci_svc, PSCI_STAT_ID_ENTER_LOW_PWR,
			cpu_idx, flags, pwrdn_ts);

	/* In the case of 1st power on just return */
	if (!pwrdn_ts)
		return;

	/* Get power up time-stamp for current CPU */
	PMF_GET_TIMESTAMP_BY_INDEX(psci_svc, PSCI_STAT_ID_EXIT_LOW_PWR,
			cpu_idx, flags, pwrup_ts);

	/* Get the index into the stats array */
	local_state = state_info->pwr_domain_state[PSCI_CPU_PWR_LVL];
	stat_idx = get_stat_idx(local_state, PSCI_CPU_PWR_LVL);

	/* Calculate stats residency */
	calc_stat_residency(pwrup_ts, pwrdn_ts, residency);

	/* Update CPU stats. */
	psci_cpu_stat[cpu_idx][stat_idx].residency += residency;
	psci_cpu_stat[cpu_idx][stat_idx].count++;

	/*
	 * Check what power domains above CPU were off
	 * prior to this CPU powering on.
	 */
	parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node;
	for (lvl = PSCI_CPU_PWR_LVL + 1; lvl <= end_pwrlvl; lvl++) {
		local_state = state_info->pwr_domain_state[lvl];
		if (is_local_state_run(local_state)) {
			/* Break early */
			break;
		}

		assert(last_cpu_in_non_cpu_pd[parent_idx] != -1);

		/* Get power down time-stamp for last CPU */
		PMF_GET_TIMESTAMP_BY_INDEX(psci_svc, PSCI_STAT_ID_ENTER_LOW_PWR,
				last_cpu_in_non_cpu_pd[parent_idx],
				flags, pwrdn_ts);

		/* Initialize back to reset value */
		last_cpu_in_non_cpu_pd[parent_idx] = -1;

		/* Get the index into the stats array */
		stat_idx = get_stat_idx(local_state, lvl);

		/* Calculate stats residency */
		calc_stat_residency(pwrup_ts, pwrdn_ts, residency);

		/* Update non cpu stats */
		psci_non_cpu_stat[parent_idx][stat_idx].residency += residency;
		psci_non_cpu_stat[parent_idx][stat_idx].count++;

		parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
	}

}

/*******************************************************************************
 * This function returns the appropriate count and residency time of the
 * local state for the highest power level expressed in the `power_state`
 * for the node represented by `target_cpu`.
 ******************************************************************************/
int psci_get_stat(u_register_t target_cpu, unsigned int power_state,
			 psci_stat_t *psci_stat)
{
	int rc, pwrlvl, lvl, parent_idx, stat_idx, target_idx;
	psci_power_state_t state_info = { {PSCI_LOCAL_STATE_RUN} };
	plat_local_state_t local_state;

	/* Validate the target_cpu parameter and determine the cpu index */
	target_idx = plat_core_pos_by_mpidr(target_cpu);
	if (target_idx == -1)
		return PSCI_E_INVALID_PARAMS;

	/* Validate the power_state parameter */
	if (!psci_plat_pm_ops->translate_power_state_by_mpidr)
		rc = psci_validate_power_state(power_state, &state_info);
	else
		rc = psci_plat_pm_ops->translate_power_state_by_mpidr(
				target_cpu, power_state, &state_info);

	if (rc != PSCI_E_SUCCESS)
		return PSCI_E_INVALID_PARAMS;

	/* Find the highest power level */
	pwrlvl = psci_find_target_suspend_lvl(&state_info);
	if (pwrlvl == PSCI_INVALID_PWR_LVL)
		return PSCI_E_INVALID_PARAMS;

	/* Get the index into the stats array */
	local_state = state_info.pwr_domain_state[pwrlvl];
	stat_idx = get_stat_idx(local_state, pwrlvl);

	if (pwrlvl > PSCI_CPU_PWR_LVL) {
		/* Get the power domain index */
		parent_idx = psci_cpu_pd_nodes[target_idx].parent_node;
		for (lvl = PSCI_CPU_PWR_LVL + 1; lvl < pwrlvl; lvl++)
			parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;

		/* Get the non cpu power domain stats */
		*psci_stat = psci_non_cpu_stat[parent_idx][stat_idx];
	} else {
		/* Get the cpu power domain stats */
		*psci_stat = psci_cpu_stat[target_idx][stat_idx];
	}

	return PSCI_E_SUCCESS;
}

/* This is the top level function for PSCI_STAT_RESIDENCY SMC. */
u_register_t psci_stat_residency(u_register_t target_cpu,
		unsigned int power_state)
{
	psci_stat_t psci_stat;

	int rc = psci_get_stat(target_cpu, power_state, &psci_stat);
	if (rc == PSCI_E_SUCCESS)
		return psci_stat.residency;
	else
		return 0;
}

/* This is the top level function for PSCI_STAT_COUNT SMC. */
u_register_t psci_stat_count(u_register_t target_cpu,
	unsigned int power_state)
{
	psci_stat_t psci_stat;

	int rc = psci_get_stat(target_cpu, power_state, &psci_stat);
	if (rc == PSCI_E_SUCCESS)
		return psci_stat.count;
	else
		return 0;
}
