/*
 * Copyright (c) 2019 Western Digital Corporation or its affiliates
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT swerv_pic

/**
 * @brief SweRV EH1 PIC driver
 */

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

#define SWERV_PIC_MAX_NUM	CONFIG_NUM_IRQS
#define SWERV_PIC_MAX_ID	(SWERV_PIC_MAX_NUM + RISCV_MAX_GENERIC_IRQ)
#define SWERV_PIC_MAX_PRIO		16

#define SWERV_PIC_mpiccfg		0x3000
#define SWERV_PIC_meipl(s)		(0x0 + (s)*4)
#define SWERV_PIC_meip(x)		(0x1000 + (x)*4)
#define SWERV_PIC_meie(s)		(0x2000 + (s)*4)
#define SWERV_PIC_meigwctrl(s)		(0x4000 + (s)*4)
#define SWERV_PIC_meigwclr(s)		(0x5000 + (s)*4)

#define SWERV_PIC_meivt			"0xBC8"
#define SWERV_PIC_meipt			"0xBC9"
#define SWERV_PIC_meicpct		"0xBCA"
#define SWERV_PIC_meicidpl		"0xBCB"
#define SWERV_PIC_meicurpl		"0xBCC"
#define SWERV_PIC_meihap		"0xFC8"

#define swerv_piccsr(csr) SWERV_PIC_##csr

#define swerv_pic_readcsr(csr, value) \
	volatile("csrr %0, "swerv_piccsr(csr) : "=r" (value))
#define swerv_pic_writecsr(csr, value) \
	volatile("csrw "swerv_piccsr(csr)", %0" :: "rK" (value))

static int save_irq;

static uint32_t swerv_pic_read(uint32_t reg)
{
	return *(volatile uint32_t *)(DT_INST_REG_ADDR(0) + reg);
}

static void swerv_pic_write(uint32_t reg, uint32_t val)
{
	*(volatile uint32_t *)(DT_INST_REG_ADDR(0) + reg) = val;
}

void swerv_pic_irq_enable(uint32_t irq)
{
	uint32_t key;

	if ((irq >= SWERV_PIC_MAX_ID) || (irq < RISCV_MAX_GENERIC_IRQ)) {
		return;
	}

	key = irq_lock();
	swerv_pic_write(SWERV_PIC_meie(irq - RISCV_MAX_GENERIC_IRQ), 1);
	irq_unlock(key);
}

void swerv_pic_irq_disable(uint32_t irq)
{
	uint32_t key;

	if ((irq >= SWERV_PIC_MAX_ID) || (irq < RISCV_MAX_GENERIC_IRQ)) {
		return;
	}

	key = irq_lock();
	swerv_pic_write(SWERV_PIC_meie(irq - RISCV_MAX_GENERIC_IRQ), 0);
	irq_unlock(key);
}

int swerv_pic_irq_is_enabled(uint32_t irq)
{
	if ((irq >= SWERV_PIC_MAX_ID) || (irq < RISCV_MAX_GENERIC_IRQ)) {
		return -1;
	}

	return swerv_pic_read(SWERV_PIC_meie(irq - RISCV_MAX_GENERIC_IRQ))
	  & 0x1;
}

void swerv_pic_set_priority(uint32_t irq, uint32_t priority)
{
	uint32_t key;

	if (irq <= RISCV_MAX_GENERIC_IRQ) {
		return;
	}

	if ((irq >= SWERV_PIC_MAX_ID) || (irq < RISCV_MAX_GENERIC_IRQ)) {
		return;
	}

	if (priority >= SWERV_PIC_MAX_PRIO) {
		return;
	}

	key = irq_lock();
	swerv_pic_write(SWERV_PIC_meipl(irq - RISCV_MAX_GENERIC_IRQ), priority);
	irq_unlock(key);
}

int swerv_pic_get_irq(void)
{
	return save_irq;
}

static void swerv_pic_irq_handler(const void *arg)
{
	uint32_t tmp;
	uint32_t irq;
	struct _isr_table_entry *ite;

	/* trigger the capture of the interrupt source ID */
	__asm__ swerv_pic_writecsr(meicpct, 0);

	__asm__ swerv_pic_readcsr(meihap, tmp);
	irq = (tmp >> 2) & 0xff;

	save_irq = irq;

	if (irq == 0U || irq >= 64) {
		z_irq_spurious(NULL);
	}
	irq += RISCV_MAX_GENERIC_IRQ;

	/* Call the corresponding IRQ handler in _sw_isr_table */
	ite = (struct _isr_table_entry *)&_sw_isr_table[irq];
	if (ite->isr)
		ite->isr(ite->arg);

	swerv_pic_write(SWERV_PIC_meigwclr(irq), 0);
}

static int swerv_pic_init(const struct device *dev)
{
	ARG_UNUSED(dev);
	int i;

	/* Init priority order to 0, 0=lowest to 15=highest */
	swerv_pic_write(SWERV_PIC_mpiccfg, 0);

	/* Ensure that all interrupts are disabled initially */
	for (i = 1; i < SWERV_PIC_MAX_ID; i++) {
		swerv_pic_write(SWERV_PIC_meie(i), 0);
	}

	/* Set priority of each interrupt line to 0 initially */
	for (i = 1; i < SWERV_PIC_MAX_ID; i++) {
		swerv_pic_write(SWERV_PIC_meipl(i), 15);
	}

	/* Set property of each interrupt line to level-triggered/high */
	for (i = 1; i < SWERV_PIC_MAX_ID; i++) {
		swerv_pic_write(SWERV_PIC_meigwctrl(i), (0<<1)|(0<<0));
	}

	/* clear pending of each interrupt line */
	for (i = 1; i < SWERV_PIC_MAX_ID; i++) {
		swerv_pic_write(SWERV_PIC_meigwclr(i), 0);
	}

	/* No interrupts masked */
	__asm__ swerv_pic_writecsr(meipt, 0);
	__asm__ swerv_pic_writecsr(meicidpl, 0);
	__asm__ swerv_pic_writecsr(meicurpl, 0);

	/* Setup IRQ handler for SweRV PIC driver */
	IRQ_CONNECT(RISCV_MACHINE_EXT_IRQ,
		    0,
		    swerv_pic_irq_handler,
		    NULL,
		    0);

	/* Enable IRQ for SweRV PIC driver */
	irq_enable(RISCV_MACHINE_EXT_IRQ);

	return 0;
}

void arch_irq_enable(unsigned int irq)
{
	uint32_t mie;

	if (irq > RISCV_MAX_GENERIC_IRQ) {
		swerv_pic_irq_enable(irq);
		return;
	}

	/*
	 * CSR mie register is updated using atomic instruction csrrs
	 * (atomic read and set bits in CSR register)
	 */
	__asm__ volatile ("csrrs %0, mie, %1\n"
			  : "=r" (mie)
			  : "r" (1 << irq));
}

void arch_irq_disable(unsigned int irq)
{
	uint32_t mie;

	if (irq > RISCV_MAX_GENERIC_IRQ) {
		swerv_pic_irq_disable(irq);
		return;
	}

	/*
	 * Use atomic instruction csrrc to disable device interrupt in mie CSR.
	 * (atomic read and clear bits in CSR register)
	 */
	__asm__ volatile ("csrrc %0, mie, %1\n"
			  : "=r" (mie)
			  : "r" (1 << irq));
};

int arch_irq_is_enabled(unsigned int irq)
{
	uint32_t mie;

	if (irq > RISCV_MAX_GENERIC_IRQ)
		return swerv_pic_irq_is_enabled(irq);

	__asm__ volatile ("csrr %0, mie" : "=r" (mie));

	return !!(mie & (1 << irq));
}

SYS_INIT(swerv_pic_init, PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY);
