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

#include <arch.h>
#include <arch_helpers.h>
#include <assert.h>
#include <drivers/arm/arm_gic.h>
#include <drivers/arm/gic_common.h>
#include <drivers/arm/gic_v2.h>
#include <mmio.h>
#include <platform.h>

/*
 * Data structure to store the GIC per CPU context before entering
 * system suspend. Only the GIC context of first 32 interrupts (SGIs and PPIs)
 * will be saved. The GIC SPI context needs to be restored by the respective
 * drivers. The GICC_PMR is not saved here as it will be reinitialized during
 * GIC restore.
 */
struct gicv2_pcpu_ctx {
	unsigned int gicc_ctlr;
	unsigned int gicd_isenabler0;
	unsigned int gicd_ipriorityr[NUM_PCPU_INTR >> IPRIORITYR_SHIFT];
	unsigned int gicd_icfgr;
};

static struct gicv2_pcpu_ctx pcpu_gic_ctx[PLATFORM_CORE_COUNT];

static uintptr_t gicc_base_addr;
static uintptr_t gicd_base_addr;

static unsigned int gic_cpu_id[PLATFORM_CORE_COUNT] = {UINT32_MAX};

/* Helper function to convert core pos to gic id */
static unsigned int core_pos_to_gic_id(unsigned int core_pos)
{
	assert(gic_cpu_id[core_pos] != UINT32_MAX);
	return gic_cpu_id[core_pos];
}

/*******************************************************************************
 * GIC Distributor interface accessors for reading entire registers
 ******************************************************************************/
uint8_t gicd_read_itargetsr_byte(unsigned int base, unsigned int interrupt_id)
{
	return mmio_read_8(base + GICD_ITARGETSR + interrupt_id);
}

unsigned int gicd_read_itargetsr(unsigned int base, unsigned int interrupt_id)
{
	unsigned n = interrupt_id >> ITARGETSR_SHIFT;
	return mmio_read_32(base + GICD_ITARGETSR + (n << 2));
}

unsigned int gicd_read_cpendsgir(unsigned int base, unsigned int interrupt_id)
{
	unsigned n = interrupt_id >> CPENDSGIR_SHIFT;
	return mmio_read_32(base + GICD_CPENDSGIR + (n << 2));
}

unsigned int gicd_read_spendsgir(unsigned int base, unsigned int interrupt_id)
{
	unsigned n = interrupt_id >> SPENDSGIR_SHIFT;
	return mmio_read_32(base + GICD_SPENDSGIR + (n << 2));
}

/*******************************************************************************
 * GIC Distributor interface accessors for writing entire registers
 ******************************************************************************/
void gicd_write_itargetsr(unsigned int base,
				unsigned int interrupt_id, unsigned int val)
{
	unsigned n = interrupt_id >> ITARGETSR_SHIFT;
	mmio_write_32(base + GICD_ITARGETSR + (n << 2), val);
}

void gicd_write_itargetsr_byte(unsigned int base,
				unsigned int interrupt_id, unsigned int val)
{
	mmio_write_8(base + GICD_ITARGETSR + interrupt_id, val);
}

void gicd_write_cpendsgir(unsigned int base,
				unsigned int interrupt_id, unsigned int val)
{
	unsigned n = interrupt_id >> CPENDSGIR_SHIFT;
	mmio_write_32(base + GICD_CPENDSGIR + (n << 2), val);
}

void gicd_write_spendsgir(unsigned int base,
				unsigned int interrupt_id, unsigned int val)
{
	unsigned n = interrupt_id >> SPENDSGIR_SHIFT;
	mmio_write_32(base + GICD_SPENDSGIR + (n << 2), val);
}

/*******************************************************************************
 * GIC Distributor interface accessors for individual interrupt manipulation
 ******************************************************************************/
void gicd_set_itargetsr(unsigned int base,
			unsigned int interrupt_id, unsigned int iface)
{
	mmio_write_8(base + GICD_ITARGETSR + interrupt_id, (1 << iface));
}

/******************************************************************************
 * GICv2 public driver API
 *****************************************************************************/

void gicv2_enable_cpuif(void)
{
	unsigned int gicc_ctlr;

	assert(gicc_base_addr);

	/* Enable the GICC and disable bypass */
	gicc_ctlr = GICC_CTLR_ENABLE | FIQ_BYP_DIS_GRP1
					 | IRQ_BYP_DIS_GRP1;
	gicc_write_ctlr(gicc_base_addr, gicc_ctlr);
}

void gicv2_probe_gic_cpu_id(void)
{
	unsigned int gicd_itargets_val, core_pos;

	assert(gicd_base_addr);
	core_pos = platform_get_core_pos(read_mpidr_el1());
	gicd_itargets_val = gicd_read_itargetsr(gicd_base_addr, 0);

	/* In a uniprocessor implementation the GICD_ITARGETSRs are RAZ/WI. */
	if (PLATFORM_CORE_COUNT > 1)
		assert(gicd_itargets_val);

	/* Convert the bit pos returned by read of ITARGETSR0 to GIC CPU ID */
	gic_cpu_id[core_pos] = __builtin_ctz(gicd_itargets_val);
}

void gicv2_setup_cpuif(void)
{
	assert(gicc_base_addr);

	/* Set the priority mask register to allow all interrupts to trickle in */
	gicc_write_pmr(gicc_base_addr, GIC_PRI_MASK);
	gicv2_enable_cpuif();
}

void gicv2_disable_cpuif(void)
{
	unsigned int gicc_ctlr;

	assert(gicc_base_addr);

	/* Disable non-secure interrupts and disable their bypass */
	gicc_ctlr = gicc_read_ctlr(gicc_base_addr);
	gicc_ctlr &= ~GICC_CTLR_ENABLE;
	gicc_ctlr |= FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1;
	gicc_write_ctlr(gicc_base_addr, gicc_ctlr);
}

void gicv2_save_cpuif_context(void)
{
	unsigned int core_pos = platform_get_core_pos(read_mpidr_el1());

	assert(gicc_base_addr);
	pcpu_gic_ctx[core_pos].gicc_ctlr =
				gicc_read_ctlr(gicc_base_addr);
}

void gicv2_restore_cpuif_context(void)
{
	unsigned int core_pos = platform_get_core_pos(read_mpidr_el1());

	assert(gicc_base_addr);

	/* The GICC_PMR is never modified, hence we initialize this register */
	gicc_write_pmr(gicc_base_addr, GIC_PRI_MASK);

	gicc_write_ctlr(gicc_base_addr,
			pcpu_gic_ctx[core_pos].gicc_ctlr);
}

void gicv2_setup_distif(void)
{
	unsigned int gicd_ctlr;

	assert(gicd_base_addr);

	/* Enable the forwarding of interrupts to CPU interface */
	gicd_ctlr = gicd_read_ctlr(gicd_base_addr);
	gicd_ctlr |= GICD_CTLR_ENABLE;
	gicd_write_ctlr(gicd_base_addr, gicd_ctlr);
}

/* Save the per-cpu GICD ISENABLER, IPRIORITYR and ICFGR registers */
void gicv2_save_sgi_ppi_context(void)
{
	unsigned int i;
	unsigned int core_pos = platform_get_core_pos(read_mpidr_el1());

	assert(gicd_base_addr);
	pcpu_gic_ctx[core_pos].gicd_isenabler0 =
				gicd_read_isenabler(gicd_base_addr, 0);

	/* Read the ipriority registers, 4 at a time */
	for (i = 0; i < (NUM_PCPU_INTR >> IPRIORITYR_SHIFT); i++)
		pcpu_gic_ctx[core_pos].gicd_ipriorityr[i] =
			gicd_read_ipriorityr(gicd_base_addr, i << IPRIORITYR_SHIFT);

	pcpu_gic_ctx[core_pos].gicd_icfgr =
			gicd_read_icfgr(gicd_base_addr, MIN_PPI_ID);
}

/* Restore the per-cpu GICD ISENABLER, IPRIORITYR and ICFGR registers */
void gicv2_restore_sgi_ppi_context(void)
{
	unsigned int i;
	unsigned int core_pos = platform_get_core_pos(read_mpidr_el1());

	assert(gicd_base_addr);

	/* Write the ipriority registers, 4 at a time */
	for (i = 0; i < (NUM_PCPU_INTR >> IPRIORITYR_SHIFT); i++)
		gicd_write_ipriorityr(gicd_base_addr, i << IPRIORITYR_SHIFT,
			pcpu_gic_ctx[core_pos].gicd_ipriorityr[i]);

	gicd_write_icfgr(gicd_base_addr, MIN_PPI_ID,
			pcpu_gic_ctx[core_pos].gicd_icfgr);

	gicd_write_isenabler(gicd_base_addr, 0,
			pcpu_gic_ctx[core_pos].gicd_isenabler0);
}

unsigned int gicv2_gicd_get_ipriorityr(unsigned int interrupt_id)
{
	assert(gicd_base_addr);
	assert(IS_VALID_INTR_ID(interrupt_id));

	return gicd_get_ipriorityr(gicd_base_addr, interrupt_id);
}

void gicv2_gicd_set_ipriorityr(unsigned int interrupt_id,
				unsigned int priority)
{
	assert(gicd_base_addr);
	assert(IS_VALID_INTR_ID(interrupt_id));

	gicd_set_ipriorityr(gicd_base_addr, interrupt_id, priority);
}

void gicv2_send_sgi(unsigned int sgi_id, unsigned int core_pos)
{
	unsigned int sgir_val;

	assert(gicd_base_addr);
	assert(IS_SGI(sgi_id));

	sgir_val = sgi_id << GICD_SGIR_INTID_SHIFT;
	sgir_val |= (1 << core_pos_to_gic_id(core_pos)) << GICD_SGIR_CPUTL_SHIFT;

	gicd_write_sgir(gicd_base_addr, sgir_val);
}

void gicv2_set_itargetsr(unsigned int num, unsigned int core_pos)
{
	unsigned int gic_cpu_id;
	assert(gicd_base_addr);
	assert(IS_SPI(num));

	gic_cpu_id = core_pos_to_gic_id(core_pos);
	gicd_set_itargetsr(gicd_base_addr, num, gic_cpu_id);
}

uint8_t gicv2_read_itargetsr_value(unsigned int num)
{
	return gicd_read_itargetsr_byte(gicd_base_addr, num);
}

void gicv2_set_itargetsr_value(unsigned int num, unsigned int val)
{
	assert(gicd_base_addr);
	assert(IS_SPI(num));

	gicd_write_itargetsr_byte(gicd_base_addr, num, val);

	assert(gicv2_read_itargetsr_value(num) == val);
}

unsigned int gicv2_gicd_get_isenabler(unsigned int num)
{
	assert(gicd_base_addr);
	assert(IS_VALID_INTR_ID(num));

	return gicd_get_isenabler(gicd_base_addr, num);
}

void gicv2_gicd_set_isenabler(unsigned int num)
{
	assert(gicd_base_addr);
	assert(IS_VALID_INTR_ID(num));

	gicd_set_isenabler(gicd_base_addr, num);
}

void gicv2_gicd_set_icenabler(unsigned int num)
{
	assert(gicd_base_addr);
	assert(IS_VALID_INTR_ID(num));

	gicd_set_icenabler(gicd_base_addr, num);
}

unsigned int gicv2_gicc_read_iar(void)
{
	assert(gicc_base_addr);
	return gicc_read_iar(gicc_base_addr);
}

unsigned int gicv2_gicd_get_ispendr(unsigned int interrupt_id)
{
	unsigned int ispendr;
	unsigned int bit_pos;

	assert(gicd_base_addr);
	assert(IS_VALID_INTR_ID(interrupt_id));

	ispendr = gicd_read_ispendr(gicd_base_addr, interrupt_id);
	bit_pos = interrupt_id % (1 << ISPENDR_SHIFT);

	return !!(ispendr & (1 << bit_pos));
}

void gicv2_gicd_set_ispendr(unsigned int interrupt_id)
{
	assert(gicd_base_addr);
	assert(IS_PPI(interrupt_id) || IS_SPI(interrupt_id));
	gicd_set_ispendr(gicd_base_addr, interrupt_id);
}

void gicv2_gicd_set_icpendr(unsigned int interrupt_id)
{
	assert(gicd_base_addr);
	assert(IS_PPI(interrupt_id) || IS_SPI(interrupt_id));

	gicd_set_icpendr(gicd_base_addr, interrupt_id);
}

void gicv2_gicc_write_eoir(unsigned int val)
{
	assert(gicc_base_addr);

	gicc_write_eoir(gicc_base_addr, val);
}

void gicv2_init(uintptr_t gicc_base,
		uintptr_t gicd_base)
{
	assert(gicc_base);
	assert(gicd_base);

	/* Assert that this is a GICv2 system */
	assert(!is_gicv3_mode());
	gicc_base_addr = gicc_base;
	gicd_base_addr = gicd_base;
}
