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

#include <assert.h>

#include <arch_features.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/arm/gicv3.h>
#include <drivers/arm/fvp/fvp_pwrc.h>
#include <lib/extensions/spe.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
#include <plat/arm/common/arm_config.h>
#include <plat/arm/common/plat_arm.h>
#include <platform_def.h>

#include "fvp_private.h"
#include "../drivers/arm/gic/v3/gicv3_private.h"


#if ARM_RECOM_STATE_ID_ENC
/*
 *  The table storing the valid idle power states. Ensure that the
 *  array entries are populated in ascending order of state-id to
 *  enable us to use binary search during power state validation.
 *  The table must be terminated by a NULL entry.
 */
const unsigned int arm_pm_idle_states[] = {
	/* State-id - 0x01 */
	arm_make_pwrstate_lvl1(ARM_LOCAL_STATE_RUN, ARM_LOCAL_STATE_RET,
			ARM_PWR_LVL0, PSTATE_TYPE_STANDBY),
	/* State-id - 0x02 */
	arm_make_pwrstate_lvl1(ARM_LOCAL_STATE_RUN, ARM_LOCAL_STATE_OFF,
			ARM_PWR_LVL0, PSTATE_TYPE_POWERDOWN),
	/* State-id - 0x22 */
	arm_make_pwrstate_lvl1(ARM_LOCAL_STATE_OFF, ARM_LOCAL_STATE_OFF,
			ARM_PWR_LVL1, PSTATE_TYPE_POWERDOWN),
	/* State-id - 0x222 */
	arm_make_pwrstate_lvl2(ARM_LOCAL_STATE_OFF, ARM_LOCAL_STATE_OFF,
		ARM_LOCAL_STATE_OFF, ARM_PWR_LVL2, PSTATE_TYPE_POWERDOWN),
	0,
};
#endif

/*******************************************************************************
 * Function which implements the common FVP specific operations to power down a
 * cluster in response to a CPU_OFF or CPU_SUSPEND request.
 ******************************************************************************/
static void fvp_cluster_pwrdwn_common(void)
{
	uint64_t mpidr = read_mpidr_el1();

	/*
	 * On power down we need to disable statistical profiling extensions
	 * before exiting coherency.
	 */
	if (is_feat_spe_supported()) {
		spe_disable();
	}

	/* Disable coherency if this cluster is to be turned off */
	fvp_interconnect_disable();

#if HW_ASSISTED_COHERENCY
	uint32_t reg;

	/*
	 * If we have determined this core to be the last man standing and we
	 * intend to power down the cluster proactively, we provide a hint to
	 * the power controller that cluster power is not required when all
	 * cores are powered down.
	 * Note that this is only an advisory to power controller and is supported
	 * by SoCs with DynamIQ Shared Units only.
	 */
	reg = read_clusterpwrdn();

	/* Clear and set bit 0 : Cluster power not required */
	reg &= ~DSU_CLUSTER_PWR_MASK;
	reg |= DSU_CLUSTER_PWR_OFF;
	write_clusterpwrdn(reg);
#endif

	/* Program the power controller to turn the cluster off */
	fvp_pwrc_write_pcoffr(mpidr);
}

/*
 * Empty implementation of these hooks avoid setting the GICR_WAKER.Sleep bit
 * on ARM GICv3 implementations on FVP. This is required, because FVP does not
 * support SYSTEM_SUSPEND and it is `faked` in firmware. Hence, for wake up
 * from `fake` system suspend the GIC must not be powered off.
 */
void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num)
{}

void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num)
{}

static void fvp_power_domain_on_finish_common(const psci_power_state_t *target_state)
{
	unsigned long mpidr;

	assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
					ARM_LOCAL_STATE_OFF);

	/* Get the mpidr for this cpu */
	mpidr = read_mpidr_el1();

	/* Perform the common cluster specific operations */
	if (target_state->pwr_domain_state[ARM_PWR_LVL1] ==
					ARM_LOCAL_STATE_OFF) {
		/*
		 * This CPU might have woken up whilst the cluster was
		 * attempting to power down. In this case the FVP power
		 * controller will have a pending cluster power off request
		 * which needs to be cleared by writing to the PPONR register.
		 * This prevents the power controller from interpreting a
		 * subsequent entry of this cpu into a simple wfi as a power
		 * down request.
		 */
		fvp_pwrc_write_pponr(mpidr);

		/* Enable coherency if this cluster was off */
		fvp_interconnect_enable();
	}
	/* Perform the common system specific operations */
	if (target_state->pwr_domain_state[ARM_PWR_LVL2] ==
						ARM_LOCAL_STATE_OFF)
		arm_system_pwr_domain_resume();

	/*
	 * Clear PWKUPR.WEN bit to ensure interrupts do not interfere
	 * with a cpu power down unless the bit is set again
	 */
	fvp_pwrc_clr_wen(mpidr);
}

/*******************************************************************************
 * FVP handler called when a CPU is about to enter standby.
 ******************************************************************************/
static void fvp_cpu_standby(plat_local_state_t cpu_state)
{
	u_register_t scr = read_scr_el3();

	assert(cpu_state == ARM_LOCAL_STATE_RET);

	/*
	 * Enable the Non-secure interrupt to wake the CPU.
	 * In GICv3 affinity routing mode, the Non-secure Group 1 interrupts
	 * use Physical FIQ at EL3 whereas in GICv2, Physical IRQ is used.
	 * Enabling both the bits works for both GICv2 mode and GICv3 affinity
	 * routing mode.
	 */
	write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT);
	isb();

	/*
	 * Enter standby state.
	 * dsb is good practice before using wfi to enter low power states.
	 */
	dsb();
	wfi();

	/*
	 * Restore SCR_EL3 to the original value, synchronisation of SCR_EL3
	 * is done by eret in el3_exit() to save some execution cycles.
	 */
	write_scr_el3(scr);
}

/*******************************************************************************
 * FVP handler called when a power domain is about to be turned on. The
 * mpidr determines the CPU to be turned on.
 ******************************************************************************/
static int fvp_pwr_domain_on(u_register_t mpidr)
{
	int rc = PSCI_E_SUCCESS;
	unsigned int psysr;

	/*
	 * Ensure that we do not cancel an inflight power off request for the
	 * target cpu. That would leave it in a zombie wfi. Wait for it to power
	 * off and then program the power controller to turn that CPU on.
	 */
	do {
		psysr = fvp_pwrc_read_psysr(mpidr);
	} while ((psysr & PSYSR_AFF_L0) != 0U);

	fvp_pwrc_write_pponr(mpidr);
	return rc;
}

/*******************************************************************************
 * FVP handler called when a power domain is about to be turned off. The
 * target_state encodes the power state that each level should transition to.
 ******************************************************************************/
static void fvp_pwr_domain_off(const psci_power_state_t *target_state)
{
	assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
					ARM_LOCAL_STATE_OFF);

	/*
	 * If execution reaches this stage then this power domain will be
	 * suspended. Perform at least the cpu specific actions followed
	 * by the cluster specific operations if applicable.
	 */

	/* Prevent interrupts from spuriously waking up this cpu */
	plat_arm_gic_cpuif_disable();

	/* Turn redistributor off */
	plat_arm_gic_redistif_off();

	/* Program the power controller to power off this cpu. */
	fvp_pwrc_write_ppoffr(read_mpidr_el1());

	if (target_state->pwr_domain_state[ARM_PWR_LVL1] ==
					ARM_LOCAL_STATE_OFF)
		fvp_cluster_pwrdwn_common();

}

/*******************************************************************************
 * FVP handler called when a power domain is about to be suspended. The
 * target_state encodes the power state that each level should transition to.
 ******************************************************************************/
static void fvp_pwr_domain_suspend(const psci_power_state_t *target_state)
{
	unsigned long mpidr;

	/*
	 * FVP has retention only at cpu level. Just return
	 * as nothing is to be done for retention.
	 */
	if (target_state->pwr_domain_state[ARM_PWR_LVL0] ==
					ARM_LOCAL_STATE_RET)
		return;

	assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
					ARM_LOCAL_STATE_OFF);

	/* Get the mpidr for this cpu */
	mpidr = read_mpidr_el1();

	/* Program the power controller to enable wakeup interrupts. */
	fvp_pwrc_set_wen(mpidr);

	/* Prevent interrupts from spuriously waking up this cpu */
	plat_arm_gic_cpuif_disable();

	/*
	 * The Redistributor is not powered off as it can potentially prevent
	 * wake up events reaching the CPUIF and/or might lead to losing
	 * register context.
	 */

	/* Perform the common cluster specific operations */
	if (target_state->pwr_domain_state[ARM_PWR_LVL1] ==
					ARM_LOCAL_STATE_OFF)
		fvp_cluster_pwrdwn_common();

	/* Perform the common system specific operations */
	if (target_state->pwr_domain_state[ARM_PWR_LVL2] ==
						ARM_LOCAL_STATE_OFF)
		arm_system_pwr_domain_save();

	/* Program the power controller to power off this cpu. */
	fvp_pwrc_write_ppoffr(read_mpidr_el1());
}

/*******************************************************************************
 * FVP handler called when a power domain has just been powered on after
 * being turned off earlier. The target_state encodes the low power state that
 * each level has woken up from.
 ******************************************************************************/
static void fvp_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
	fvp_power_domain_on_finish_common(target_state);

}

/*******************************************************************************
 * FVP handler called when a power domain has just been powered on and the cpu
 * and its cluster are fully participating in coherent transaction on the
 * interconnect. Data cache must be enabled for CPU at this point.
 ******************************************************************************/
static void fvp_pwr_domain_on_finish_late(const psci_power_state_t *target_state)
{
	/* Program GIC per-cpu distributor or re-distributor interface */
	plat_arm_gic_pcpu_init();

	/* Enable GIC CPU interface */
	plat_arm_gic_cpuif_enable();
}

/*******************************************************************************
 * FVP handler called when a power domain has just been powered on after
 * having been suspended earlier. The target_state encodes the low power state
 * that each level has woken up from.
 * TODO: At the moment we reuse the on finisher and reinitialize the secure
 * context. Need to implement a separate suspend finisher.
 ******************************************************************************/
static void fvp_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
{
	/*
	 * Nothing to be done on waking up from retention from CPU level.
	 */
	if (target_state->pwr_domain_state[ARM_PWR_LVL0] ==
					ARM_LOCAL_STATE_RET)
		return;

	fvp_power_domain_on_finish_common(target_state);

	/* Enable GIC CPU interface */
	plat_arm_gic_cpuif_enable();
}

/*******************************************************************************
 * FVP handlers to shutdown/reboot the system
 ******************************************************************************/
static void __dead2 fvp_system_off(void)
{
	/* Write the System Configuration Control Register */
	mmio_write_32(V2M_SYSREGS_BASE + V2M_SYS_CFGCTRL,
		V2M_CFGCTRL_START |
		V2M_CFGCTRL_RW |
		V2M_CFGCTRL_FUNC(V2M_FUNC_SHUTDOWN));
	wfi();
	ERROR("FVP System Off: operation not handled.\n");
	panic();
}

static void __dead2 fvp_system_reset(void)
{
	/* Write the System Configuration Control Register */
	mmio_write_32(V2M_SYSREGS_BASE + V2M_SYS_CFGCTRL,
		V2M_CFGCTRL_START |
		V2M_CFGCTRL_RW |
		V2M_CFGCTRL_FUNC(V2M_FUNC_REBOOT));
	wfi();
	ERROR("FVP System Reset: operation not handled.\n");
	panic();
}

static int fvp_node_hw_state(u_register_t target_cpu,
			     unsigned int power_level)
{
	unsigned int psysr;
	int ret;

	/*
	 * The format of 'power_level' is implementation-defined, but 0 must
	 * mean a CPU. We also allow 1 to denote the cluster
	 */
	if ((power_level != ARM_PWR_LVL0) && (power_level != ARM_PWR_LVL1))
		return PSCI_E_INVALID_PARAMS;

	/*
	 * Read the status of the given MPDIR from FVP power controller. The
	 * power controller only gives us on/off status, so map that to expected
	 * return values of the PSCI call
	 */
	psysr = fvp_pwrc_read_psysr(target_cpu);
	if (psysr == PSYSR_INVALID)
		return PSCI_E_INVALID_PARAMS;

	if (power_level == ARM_PWR_LVL0) {
		ret = ((psysr & PSYSR_AFF_L0) != 0U) ? HW_ON : HW_OFF;
	} else {
		/* power_level == ARM_PWR_LVL1 */
		ret = ((psysr & PSYSR_AFF_L1) != 0U) ? HW_ON : HW_OFF;
	}

	return ret;
}

/*
 * The FVP doesn't truly support power management at SYSTEM power domain. The
 * SYSTEM_SUSPEND will be down-graded to the cluster level within the platform
 * layer. The `fake` SYSTEM_SUSPEND allows us to validate some of the driver
 * save and restore sequences on FVP.
 */
#if !ARM_BL31_IN_DRAM
static void fvp_get_sys_suspend_power_state(psci_power_state_t *req_state)
{
	unsigned int i;

	for (i = ARM_PWR_LVL0; i <= PLAT_MAX_PWR_LVL; i++)
		req_state->pwr_domain_state[i] = ARM_LOCAL_STATE_OFF;
}
#endif

/*******************************************************************************
 * Handler to filter PSCI requests.
 ******************************************************************************/
/*
 * The system power domain suspend is only supported only via
 * PSCI SYSTEM_SUSPEND API. PSCI CPU_SUSPEND request to system power domain
 * will be downgraded to the lower level.
 */
static int fvp_validate_power_state(unsigned int power_state,
			    psci_power_state_t *req_state)
{
	int rc;
	rc = arm_validate_power_state(power_state, req_state);

	/*
	 * Ensure that the system power domain level is never suspended
	 * via PSCI CPU SUSPEND API. Currently system suspend is only
	 * supported via PSCI SYSTEM SUSPEND API.
	 */
	req_state->pwr_domain_state[ARM_PWR_LVL2] = ARM_LOCAL_STATE_RUN;
	return rc;
}

/*
 * Custom `translate_power_state_by_mpidr` handler for FVP. Unlike in the
 * `fvp_validate_power_state`, we do not downgrade the system power
 * domain level request in `power_state` as it will be used to query the
 * PSCI_STAT_COUNT/RESIDENCY at the system power domain level.
 */
static int fvp_translate_power_state_by_mpidr(u_register_t mpidr,
		unsigned int power_state,
		psci_power_state_t *output_state)
{
	return arm_validate_power_state(power_state, output_state);
}

/*******************************************************************************
 * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
 * platform layer will take care of registering the handlers with PSCI.
 ******************************************************************************/
plat_psci_ops_t plat_arm_psci_pm_ops = {
	.cpu_standby = fvp_cpu_standby,
	.pwr_domain_on = fvp_pwr_domain_on,
	.pwr_domain_off = fvp_pwr_domain_off,
	.pwr_domain_suspend = fvp_pwr_domain_suspend,
	.pwr_domain_on_finish = fvp_pwr_domain_on_finish,
	.pwr_domain_on_finish_late = fvp_pwr_domain_on_finish_late,
	.pwr_domain_suspend_finish = fvp_pwr_domain_suspend_finish,
	.system_off = fvp_system_off,
	.system_reset = fvp_system_reset,
	.validate_power_state = fvp_validate_power_state,
	.validate_ns_entrypoint = arm_validate_psci_entrypoint,
	.translate_power_state_by_mpidr = fvp_translate_power_state_by_mpidr,
	.get_node_hw_state = fvp_node_hw_state,
#if !ARM_BL31_IN_DRAM
	/*
	 * The TrustZone Controller is set up during the warmboot sequence after
	 * resuming the CPU from a SYSTEM_SUSPEND. If BL31 is located in SRAM
	 * this is  not a problem but, if it is in TZC-secured DRAM, it tries to
	 * reconfigure the same memory it is running on, causing an exception.
	 */
	.get_sys_suspend_power_state = fvp_get_sys_suspend_power_state,
#endif
	.mem_protect_chk	= arm_psci_mem_protect_chk,
	.read_mem_protect	= arm_psci_read_mem_protect,
	.write_mem_protect	= arm_nor_psci_write_mem_protect,
};

const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
{
	return ops;
}
