/* Copyright (C) 2023 BeagleBoard.org Foundation
 * Copyright (C) 2023 S Prashanth
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ti_vim

#include <stdint.h>

#include <zephyr/arch/arm/irq.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/interrupt_controller/intc_vim.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/util_macro.h>

LOG_MODULE_REGISTER(vim);

unsigned int z_vim_irq_get_active(void)
{
	uint32_t irq_group_num, irq_bit_num;
	uint32_t actirq, vec_addr;

	/* Reading IRQVEC register, ACTIRQ gets loaded with valid IRQ values */
	vec_addr = sys_read32(VIM_IRQVEC);

	/* ACTIRQ register should be read only after reading IRQVEC register */
	actirq = sys_read32(VIM_ACTIRQ);

	/* Check if the irq number is valid, else return invalid irq number.
	 * which will be considered as spurious interrupt
	 */
	if ((actirq & (VIM_ACTIRQ_VALID_MASK)) == 0) {
		return CONFIG_NUM_IRQS + 1;
	}

	irq_group_num = VIM_GET_IRQ_GROUP_NUM(actirq & VIM_PRIIRQ_NUM_MASK);
	irq_bit_num = VIM_GET_IRQ_BIT_NUM(actirq & VIM_PRIIRQ_NUM_MASK);

	/* Ack the interrupt in IRQSTS register */
	sys_write32(BIT(irq_bit_num), VIM_IRQSTS(irq_group_num));

	if (irq_group_num > VIM_MAX_GROUP_NUM) {
		return (CONFIG_NUM_IRQS + 1);
	}

	return (actirq & VIM_ACTIRQ_NUM_MASK);
}

void z_vim_irq_eoi(unsigned int irq)
{
	sys_write32(0, VIM_IRQVEC);
}

void z_vim_irq_init(void)
{
	uint32_t num_of_irqs = sys_read32(VIM_INFO_INTERRUPTS_MASK);

	LOG_DBG("VIM: Number of IRQs = %u\n", num_of_irqs);
}

void z_vim_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags)
{
	uint32_t irq_group_num, irq_bit_num, regval;

	if (irq > CONFIG_NUM_IRQS || prio > VIM_PRI_INT_MAX ||
	    (flags != IRQ_TYPE_EDGE && flags != IRQ_TYPE_LEVEL)) {
		LOG_ERR("%s: Invalid argument irq = %u prio = %u flags = %u\n",
			__func__, irq, prio, flags);
		return;
	}

	sys_write8(prio, VIM_PRI_INT(irq));

	irq_group_num = VIM_GET_IRQ_GROUP_NUM(irq);
	irq_bit_num = VIM_GET_IRQ_BIT_NUM(irq);

	regval = sys_read32(VIM_INTTYPE(irq_group_num));

	if (flags == IRQ_TYPE_EDGE) {
		regval |= (BIT(irq_bit_num));
	} else {
		regval &= ~(BIT(irq_bit_num));
	}

	sys_write32(regval, VIM_INTTYPE(irq_group_num));
}

void z_vim_irq_enable(unsigned int irq)
{
	uint32_t irq_group_num, irq_bit_num;

	if (irq > CONFIG_NUM_IRQS) {
		LOG_ERR("%s: Invalid irq number = %u\n", __func__, irq);
		return;
	}

	irq_group_num = VIM_GET_IRQ_GROUP_NUM(irq);
	irq_bit_num = VIM_GET_IRQ_BIT_NUM(irq);

	sys_write32(BIT(irq_bit_num), VIM_INTR_EN_SET(irq_group_num));
}

void z_vim_irq_disable(unsigned int irq)
{
	uint32_t irq_group_num, irq_bit_num;

	if (irq > CONFIG_NUM_IRQS) {
		LOG_ERR("%s: Invalid irq number = %u\n", __func__, irq);
		return;
	}

	irq_group_num = VIM_GET_IRQ_GROUP_NUM(irq);
	irq_bit_num = VIM_GET_IRQ_BIT_NUM(irq);

	sys_write32(BIT(irq_bit_num), VIM_INTR_EN_CLR(irq_group_num));
}

int z_vim_irq_is_enabled(unsigned int irq)
{
	uint32_t irq_group_num, irq_bit_num, regval;

	if (irq > CONFIG_NUM_IRQS) {
		LOG_ERR("%s: Invalid irq number = %u\n", __func__, irq);
		return -EINVAL;
	}

	irq_group_num = VIM_GET_IRQ_GROUP_NUM(irq);
	irq_bit_num = VIM_GET_IRQ_BIT_NUM(irq);

	regval = sys_read32(VIM_INTR_EN_SET(irq_group_num));

	return !!(regval & (BIT(irq_bit_num)));
}

void z_vim_arm_enter_irq(int irq)
{
	uint32_t irq_group_num, irq_bit_num;

	if (irq > CONFIG_NUM_IRQS) {
		LOG_ERR("%s: Invalid irq number = %u\n", __func__, irq);
		return;
	}

	irq_group_num = VIM_GET_IRQ_GROUP_NUM(irq);
	irq_bit_num = VIM_GET_IRQ_BIT_NUM(irq);

	sys_write32(BIT(irq_bit_num), VIM_RAW(irq_group_num));
}
