/*
 * Copyright (c) 2019 Synopsys.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief ARCv2 ARC CONNECT driver
 *
 */

#include <zephyr/kernel.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/spinlock.h>
#include <kernel_internal.h>

static struct k_spinlock arc_connect_spinlock;

/* Generate an inter-core interrupt to the target core */
void z_arc_connect_ici_generate(uint32_t core)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_INTRPT_GENERATE_IRQ, core);
	}
}

/* Acknowledge the inter-core interrupt raised by core */
void z_arc_connect_ici_ack(uint32_t core)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_INTRPT_GENERATE_ACK, core);
	}
}

/* Read inter-core interrupt status */
uint32_t z_arc_connect_ici_read_status(uint32_t core)
{
	uint32_t ret = 0;

	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_INTRPT_READ_STATUS, core);
		ret = z_arc_connect_cmd_readback();
	}

	return ret;
}

/* Check the source of inter-core interrupt */
uint32_t z_arc_connect_ici_check_src(void)
{
	uint32_t ret = 0;

	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_INTRPT_CHECK_SOURCE, 0);
		ret = z_arc_connect_cmd_readback();
	}

	return ret;
}

/* Clear the inter-core interrupt */
void z_arc_connect_ici_clear(void)
{
	uint32_t cpu, c;

	K_SPINLOCK(&arc_connect_spinlock) {

		z_arc_connect_cmd(ARC_CONNECT_CMD_INTRPT_CHECK_SOURCE, 0);
		cpu = z_arc_connect_cmd_readback(); /* 1,2,4,8... */
	/*
	 * In rare case, multiple concurrent ICIs sent to same target can
	 * possibly be coalesced by MCIP into 1 asserted IRQ, so @cpu can be
	 * "vectored" (multiple bits sets) as opposed to typical single bit
	 */
		while (cpu) {
			c = find_lsb_set(cpu) - 1;
			z_arc_connect_cmd(
				ARC_CONNECT_CMD_INTRPT_GENERATE_ACK, c);
			cpu &= ~(1U << c);
		}
	}
}

/* Reset the cores in core_mask */
void z_arc_connect_debug_reset(uint32_t core_mask)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd_data(ARC_CONNECT_CMD_DEBUG_RESET,
			0, core_mask);
	}
}

/* Halt the cores in core_mask */
void z_arc_connect_debug_halt(uint32_t core_mask)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd_data(ARC_CONNECT_CMD_DEBUG_HALT,
			0, core_mask);
	}
}

/* Run the cores in core_mask */
void z_arc_connect_debug_run(uint32_t core_mask)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd_data(ARC_CONNECT_CMD_DEBUG_RUN,
			0, core_mask);
	}
}

/* Set core mask */
void z_arc_connect_debug_mask_set(uint32_t core_mask, uint32_t mask)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd_data(ARC_CONNECT_CMD_DEBUG_SET_MASK,
			mask, core_mask);
	}
}

/* Read core mask */
uint32_t z_arc_connect_debug_mask_read(uint32_t core_mask)
{
	uint32_t ret = 0;

	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd_data(ARC_CONNECT_CMD_DEBUG_READ_MASK,
			0, core_mask);
		ret = z_arc_connect_cmd_readback();
	}

	return ret;
}

/*
 * Select cores that should be halted if the core issuing the command is halted
 */
void z_arc_connect_debug_select_set(uint32_t core_mask)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd_data(ARC_CONNECT_CMD_DEBUG_SET_SELECT,
			0, core_mask);
	}
}

/* Read the select value */
uint32_t z_arc_connect_debug_select_read(void)
{
	uint32_t ret = 0;

	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_DEBUG_READ_SELECT, 0);
		ret = z_arc_connect_cmd_readback();
	}

	return ret;
}

/* Read the status, halt or run of all cores in the system */
uint32_t z_arc_connect_debug_en_read(void)
{
	uint32_t ret = 0;

	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_DEBUG_READ_EN, 0);
		ret = z_arc_connect_cmd_readback();
	}

	return ret;
}

/* Read the last command sent */
uint32_t z_arc_connect_debug_cmd_read(void)
{
	uint32_t ret = 0;

	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_DEBUG_READ_CMD, 0);
		ret = z_arc_connect_cmd_readback();
	}

	return ret;
}

/* Read the value of internal MCD_CORE register */
uint32_t z_arc_connect_debug_core_read(void)
{
	uint32_t ret = 0;

	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_DEBUG_READ_CORE, 0);
		ret = z_arc_connect_cmd_readback();
	}

	return ret;
}

/* Clear global free running counter */
void z_arc_connect_gfrc_clear(void)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_GFRC_CLEAR, 0);
	}
}

/* Read total 64 bits of global free running counter */
uint64_t z_arc_connect_gfrc_read(void)
{
	uint32_t low;
	uint32_t high;
	uint32_t key;

	/*
	 * each core has its own arc connect interface, i.e.,
	 * CMD/READBACK. So several concurrent commands to ARC
	 * connect are of if they are trying to access different
	 * sub-components. For GFRC, HW allows simultaneously accessing to
	 * counters. So an irq lock is enough.
	 */
	key = arch_irq_lock();

	z_arc_connect_cmd(ARC_CONNECT_CMD_GFRC_READ_LO, 0);
	low = z_arc_connect_cmd_readback();

	z_arc_connect_cmd(ARC_CONNECT_CMD_GFRC_READ_HI, 0);
	high = z_arc_connect_cmd_readback();

	arch_irq_unlock(key);

	return (((uint64_t)high) << 32) | low;
}

/* Enable global free running counter */
void z_arc_connect_gfrc_enable(void)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_GFRC_ENABLE, 0);
	}
}

/* Disable global free running counter */
void z_arc_connect_gfrc_disable(void)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_GFRC_DISABLE, 0);
	}
}

/* Disable global free running counter */
void z_arc_connect_gfrc_core_set(uint32_t core_mask)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd_data(ARC_CONNECT_CMD_GFRC_SET_CORE,
			0, core_mask);
	}
}

/* Set the relevant cores to halt global free running counter */
uint32_t z_arc_connect_gfrc_halt_read(void)
{
	uint32_t ret = 0;

	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_GFRC_READ_HALT, 0);
		ret = z_arc_connect_cmd_readback();
	}

	return ret;
}

/* Read the internal CORE register */
uint32_t z_arc_connect_gfrc_core_read(void)
{
	uint32_t ret = 0;

	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_GFRC_READ_CORE, 0);
		ret = z_arc_connect_cmd_readback();
	}

	return ret;
}

/* Enable interrupt distribute unit */
void z_arc_connect_idu_enable(void)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_ENABLE, 0);
	}
}

/* Disable interrupt distribute unit */
void z_arc_connect_idu_disable(void)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_DISABLE, 0);
	}
}

/* Read enable status of interrupt distribute unit */
uint32_t z_arc_connect_idu_read_enable(void)
{
	uint32_t ret = 0;

	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_READ_ENABLE, 0);
		ret = z_arc_connect_cmd_readback();
	}

	return ret;
}

/*
 * Set the triggering mode and distribution mode for the specified common
 * interrupt
 */
void z_arc_connect_idu_set_mode(uint32_t irq_num,
	uint16_t trigger_mode, uint16_t distri_mode)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd_data(ARC_CONNECT_CMD_IDU_SET_MODE,
			irq_num, (distri_mode | (trigger_mode << 4)));
	}
}

/* Read the internal MODE register of the specified common interrupt */
uint32_t z_arc_connect_idu_read_mode(uint32_t irq_num)
{
	uint32_t ret = 0;

	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_READ_MODE, irq_num);
		ret = z_arc_connect_cmd_readback();
	}

	return ret;
}

/*
 * Set the target cores to receive the specified common interrupt
 * when it is triggered
 */
void z_arc_connect_idu_set_dest(uint32_t irq_num, uint32_t core_mask)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd_data(ARC_CONNECT_CMD_IDU_SET_DEST,
			irq_num, core_mask);
	}
}

/* Read the internal DEST register of the specified common interrupt */
uint32_t z_arc_connect_idu_read_dest(uint32_t irq_num)
{
	uint32_t ret = 0;

	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_READ_DEST, irq_num);
		ret = z_arc_connect_cmd_readback();
	}

	return ret;
}

/* Assert the specified common interrupt */
void z_arc_connect_idu_gen_cirq(uint32_t irq_num)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_GEN_CIRQ, irq_num);
	}
}

/* Acknowledge the specified common interrupt */
void z_arc_connect_idu_ack_cirq(uint32_t irq_num)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_ACK_CIRQ, irq_num);
	}
}

/* Read the internal STATUS register of the specified common interrupt */
uint32_t z_arc_connect_idu_check_status(uint32_t irq_num)
{
	uint32_t ret = 0;

	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_CHECK_STATUS, irq_num);
		ret = z_arc_connect_cmd_readback();
	}

	return ret;
}

/* Read the internal SOURCE register of the specified common interrupt */
uint32_t z_arc_connect_idu_check_source(uint32_t irq_num)
{
	uint32_t ret = 0;

	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_CHECK_SOURCE, irq_num);
		ret = z_arc_connect_cmd_readback();
	}

	return ret;
}

/* Mask or unmask the specified common interrupt */
void z_arc_connect_idu_set_mask(uint32_t irq_num, uint32_t mask)
{
	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd_data(ARC_CONNECT_CMD_IDU_SET_MASK,
			irq_num, mask);
	}
}

/* Read the internal MASK register of the specified common interrupt */
uint32_t z_arc_connect_idu_read_mask(uint32_t irq_num)
{
	uint32_t ret = 0;

	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_READ_MASK, irq_num);
		ret = z_arc_connect_cmd_readback();
	}

	return ret;
}

/*
 * Check if it is the first-acknowledging core to the common interrupt
 * if IDU is programmed in the first-acknowledged mode
 */
uint32_t z_arc_connect_idu_check_first(uint32_t irq_num)
{
	uint32_t ret = 0;

	K_SPINLOCK(&arc_connect_spinlock) {
		z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_CHECK_FIRST, irq_num);
		ret = z_arc_connect_cmd_readback();
	}

	return ret;

}
