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

/*
 * Driver for implementation defined features that are identical in ARM GICv3
* implementations (GIC-500 and GIC-600 for now). This driver only overrides
* APIs that are different to those generic ones in GICv3 driver.
 */

#include <arch_helpers.h>
#include <assert.h>
#include <gicv3.h>

#include "gicv3_private.h"
#include "arm_gicv3_common.h"

/*
 * Flush the internal GIC cache of the LPIs pending tables to memory before
 * saving the state of the Redistributor. This is required before powering off
 * the GIC when the pending status must be preserved.
 * `rdist_proc_num` is the processor number corresponding to the Redistributor of the
 * current CPU.
 */
void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num)
{
	uintptr_t gicr_base = 0;

	assert(gicv3_driver_data);
	assert(gicv3_driver_data->rdistif_base_addrs);

	/*
	 * The GICR_WAKER.Sleep bit should be set only when both
	 * GICR_WAKER.ChildrenAsleep and GICR_WAKER.ProcessorSleep are set on
	 * all the Redistributors.
	 */
	for (unsigned int i = 0; i < gicv3_driver_data->rdistif_num; i++) {
		gicr_base = gicv3_driver_data->rdistif_base_addrs[i];
		assert(gicr_base);
		assert(gicr_read_waker(gicr_base) & WAKER_CA_BIT);
		assert(gicr_read_waker(gicr_base) & WAKER_PS_BIT);
	}

	gicr_base = gicv3_driver_data->rdistif_base_addrs[rdist_proc_num];
	/*
	 * According to the TRM, there is only one instance of the
	 * GICR_WAKER.Sleep and GICR_WAKER.Quiescent bits that can be accessed
	 * through any of the Redistributor.
	 */

	/*
	 * Set GICR_WAKER.Sleep
	 * After this point, the system must be configured so that the
	 * wake_request signals for the right cores are asserted when a wakeup
	 * interrupt is detected. The GIC will not be able to do that anymore
	 * when the GICR_WAKER.Sleep bit is set to 1.
	 */
	gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) | WAKER_SL_BIT);

	/* Wait until the GICR_WAKER.Quiescent bit is set */
	while (!(gicr_read_waker(gicr_base) & WAKER_QSC_BIT))
		;
}

/*
 * Allow the LPIs pending state to be read back from the tables in memory after
 * having restored the state of the GIC Redistributor.
 */
void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num)
{
	uintptr_t gicr_base;

	assert(gicv3_driver_data);
	assert(gicv3_driver_data->rdistif_base_addrs);

	/*
	 * According to the TRM, there is only one instance of the
	 * GICR_WAKER.Sleep and GICR_WAKER.Quiescent bits that can be accessed
	 * through any of the Redistributor.
	 */
	gicr_base = gicv3_driver_data->rdistif_base_addrs[rdist_proc_num];
	assert(gicr_base);

	/*
	 * If the GIC had power removed, the GICR_WAKER state will be reset.
	 * Since the GICR_WAKER.Sleep and GICR_WAKER.Quiescent bits are cleared,
	 * we can exit early. This also prevents the following assert from
	 * erroneously triggering.
	 */
	if (!(gicr_read_waker(gicr_base) & WAKER_SL_BIT))
		return;

	/*
	 * Writes to GICR_WAKER.Sleep bit are ignored if GICR_WAKER.Quiescent
	 * bit is not set. We should be alright on power on path, therefore
	 * coming out of sleep and Quiescent should be set, but we assert in
	 * case.
	 */
	assert(gicr_read_waker(gicr_base) & WAKER_QSC_BIT);

	/* Clear GICR_WAKER.Sleep */
	gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_SL_BIT);

	/*
	 * We don't know if the effects of setting GICR_WAKER.Sleep bit is
	 * instantaneous, so we wait until the interface is not Quiescent
	 * anymore.
	 */
	while (gicr_read_waker(gicr_base) & WAKER_QSC_BIT)
		;
}

