/*
 * Copyright (c) 2014 Wind River Systems, Inc.
 * Copyright (c) 2020-2022 Synopsys.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief ARCv2 Interrupt Unit device driver
 *
 * The ARCv2 interrupt unit has 16 allocated exceptions associated with
 * vectors 0 to 15 and 240 interrupts associated with vectors 16 to 255.
 * The interrupt unit is optional in the ARCv2-based processors. When
 * building a processor, you can configure the processor to include an
 * interrupt unit. The ARCv2 interrupt unit is highly programmable.
 */

#include <zephyr/kernel.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/device.h>
#include <zephyr/init.h>

#ifdef CONFIG_ARC_CONNECT
static void arc_shared_intc_init(void)
{
	/*
	 * Initialize all IDU interrupts:
	 * - select round-robbin
	 * - disable all lines
	 */
	BUILD_ASSERT(CONFIG_NUM_IRQS > ARC_CONNECT_IDU_IRQ_START);
	__ASSERT(z_arc_v2_core_id() == ARC_MP_PRIMARY_CPU_ID,
		 "idu interrupts must be inited from primary core");

	z_arc_connect_idu_disable();

	for (uint32_t i = 0; i < (CONFIG_NUM_IRQS - ARC_CONNECT_IDU_IRQ_START); i++) {
		/*
		 * TODO: don't use z_arc_connect_idu* functions to avoid
		 * locking/unlocking every time.
		 */

		/* Disable (mask) line */
		z_arc_connect_idu_set_mask(i, 0x1);
		z_arc_connect_idu_set_mode(i, ARC_CONNECT_INTRPT_TRIGGER_LEVEL,
					   ARC_CONNECT_DISTRI_MODE_ROUND_ROBIN);

		/*
		 * Fake round-robin: we allow to distribute interrupts only to primary core as
		 * secondary cores may be not initialized yet.
		 */
		z_arc_connect_idu_set_dest(i, BIT(ARC_MP_PRIMARY_CPU_ID));
	}

	z_arc_connect_idu_enable();

}

/* Allow to schedule IRQ to all cores after we bring up all secondary cores */
static int arc_shared_intc_update_post_smp(void)
{
	__ASSERT(z_arc_v2_core_id() == ARC_MP_PRIMARY_CPU_ID,
		 "idu interrupts must be updated from primary core");

	z_arc_connect_idu_disable();

	for (uint32_t i = 0; i < (CONFIG_NUM_IRQS - ARC_CONNECT_IDU_IRQ_START); i++) {
		/* TODO: take arc_connect_spinlock one time to avoid locking/unlocking every time */
		z_arc_connect_idu_set_dest(i, BIT_MASK(arch_num_cpus()));
	}

	z_arc_connect_idu_enable();

	return 0;
}

SYS_INIT(arc_shared_intc_update_post_smp, SMP, 0);
#endif /* CONFIG_ARC_CONNECT */


/* lowest IRQ priority */
#ifdef CONFIG_ARC_SECURE_FIRMWARE
#define ARC_IRQ_DEFAULT_PRIORITY ((CONFIG_NUM_IRQ_PRIO_LEVELS - 1) | _ARC_V2_IRQ_PRIORITY_SECURE)
#else
#define ARC_IRQ_DEFAULT_PRIORITY (CONFIG_NUM_IRQ_PRIO_LEVELS - 1)
#endif

static inline void arc_core_intc_init_nolock(uint32_t irq, uint32_t state)
{
	z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
	z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY, ARC_IRQ_DEFAULT_PRIORITY);
	z_arc_v2_aux_reg_write(_ARC_V2_IRQ_TRIGGER, _ARC_V2_INT_LEVEL);
	z_arc_v2_aux_reg_write(_ARC_V2_IRQ_ENABLE, state);
}

/*
 * Initialize the core private interrupt controller.
 *
 * This function must be called on each CPU in case of SMP system.
 *
 * NOTE: core interrupts are still globally disabled at this point (STATUS32.IE = 0), so there is
 * no need to protect the window between a write to IRQ_SELECT and subsequent writes to the
 * selected IRQ's registers with locks.
 */
void arc_core_private_intc_init(void)
{
	/*
	 * Interrupts from 0 to 15 are exceptions and they are ignored by IRQ auxiliary registers.
	 * We skip those interrupt lines while setting up core private interrupt controller.
	 */
	BUILD_ASSERT(CONFIG_GEN_IRQ_START_VECTOR == 16);

	/*
	 * System with IDU case (most likely multi-core system):
	 *  - disable private IRQs: they will be enabled with irq_enable before usage
	 *  - enable shared (IDU) IRQs: their enabling / disabling is controlled via IDU, so we
	 *    always pass them via core private interrupt controller.
	 * System without IDU case (single-core system):
	 *  - disable all IRQs: they will be enabled with irq_enable before usage
	 */
#ifdef CONFIG_ARC_CONNECT
	for (uint32_t irq = CONFIG_GEN_IRQ_START_VECTOR; irq < ARC_CONNECT_IDU_IRQ_START; irq++) {
		arc_core_intc_init_nolock(irq, _ARC_V2_INT_DISABLE);
	}

	for (uint32_t irq = ARC_CONNECT_IDU_IRQ_START; irq < CONFIG_NUM_IRQS; irq++) {
		arc_core_intc_init_nolock(irq, _ARC_V2_INT_ENABLE);
	}
#else
	for (uint32_t irq = CONFIG_GEN_IRQ_START_VECTOR; irq < CONFIG_NUM_IRQS; irq++) {
		arc_core_intc_init_nolock(irq, _ARC_V2_INT_DISABLE);
	}
#endif /* CONFIG_ARC_CONNECT */
}

static int arc_irq_init(void)
{
#ifdef CONFIG_ARC_CONNECT
	arc_shared_intc_init();
#endif /* CONFIG_ARC_CONNECT */

	/*
	 * We initialize per-core part for core 0 here,
	 * for rest cores it will be initialized in slave_start.
	 */
	arc_core_private_intc_init();

	return 0;
}

SYS_INIT(arc_irq_init, PRE_KERNEL_1, 0);
