/*
 * Copyright (c) 2022 Andes Technology Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/drivers/mbox.h>

#define LOG_LEVEL CONFIG_MBOX_LOG_LEVEL
#include <zephyr/logging/log.h>
#include <zephyr/irq.h>
LOG_MODULE_REGISTER(mbox_andes_plic_sw);

#define DT_DRV_COMPAT	andestech_plic_sw

#define IRQ_REG(n) (n >> 5)
#define PLIC_BASE(dev) \
	((const struct mbox_andes_conf * const)(dev)->config)->base

#define REG_PRIORITY(dev, irq) \
	(PLIC_BASE(dev) + 0x0 + (irq << 2))
#define REG_PENDING(dev, irq) \
	(PLIC_BASE(dev) + 0x1000 + (IRQ_REG(irq) << 2))
#define REG_ENABLE(dev, hart, irq) \
	(PLIC_BASE(dev) + 0x2000 + (hart << 7) + IRQ_REG(irq))
#define REG_CLAIM(dev, hart) \
	(PLIC_BASE(dev) + 0x200004 + (hart << 12))

#define IPI_NUM DT_INST_PROP(0, channel_max)

static struct mbox_andes_data {
	mbox_callback_t cb[IPI_NUM];
	void *user_data[IPI_NUM];
	uint32_t enabled_channel[CONFIG_MP_MAX_NUM_CPUS];
#ifdef CONFIG_SCHED_IPI_SUPPORTED
	uint32_t reg_cb_channel;
	uint32_t ipi_channel;
#endif
} andes_mbox_data;

static struct mbox_andes_conf {
	uint32_t base;
	uint32_t channel_max;
} andes_mbox_conf = {
	.base = DT_INST_REG_ADDR(0),
	.channel_max = IPI_NUM,
};

static struct k_spinlock mbox_syn;

static void plic_sw_irq_set_pending(const struct device *dev, uint32_t irq)
{
	uint32_t pend;
	k_spinlock_key_t key = k_spin_lock(&mbox_syn);

	pend = sys_read32(REG_PENDING(dev, irq));
	pend |= BIT(irq);
	sys_write32(pend, REG_PENDING(dev, irq));

	k_spin_unlock(&mbox_syn, key);
}

static inline bool is_channel_valid(const struct device *dev, uint32_t ch)
{
	const struct mbox_andes_conf *conf = dev->config;

	return (ch <= conf->channel_max);
}

static int mbox_andes_send(const struct device *dev, uint32_t ch,
			   const struct mbox_msg *msg)
{
	if (msg) {
		LOG_WRN("Sending data not supported");
	}

	if (!is_channel_valid(dev, ch)) {
		return -EINVAL;
	}

	/* Send IPI by triggering the pending register of PLIC SW. */
	plic_sw_irq_set_pending(dev, ch + 1);

	return 0;
}

static int mbox_andes_register_callback(const struct device *dev, uint32_t ch,
					mbox_callback_t cb, void *user_data)
{
	struct mbox_andes_data *data = dev->data;
	const struct mbox_andes_conf *conf = dev->config;
	int ret = 0;

	k_spinlock_key_t key = k_spin_lock(&mbox_syn);

	if (ch > conf->channel_max) {
		ret = -EINVAL;
		goto out;
	}

#ifdef CONFIG_SCHED_IPI_SUPPORTED
	if (ch & data->ipi_channel & data->reg_cb_channel) {
		ret = -EALREADY;
		goto out;
	}

	data->reg_cb_channel |= BIT(ch);
#endif
	data->cb[ch] = cb;
	data->user_data[ch] = user_data;

out:
	k_spin_unlock(&mbox_syn, key);

	return 0;
}

static int mbox_andes_mtu_get(const struct device *dev)
{
	/* We only support signalling */
	return 0;
}

static uint32_t mbox_andes_max_channels_get(const struct device *dev)
{
	const struct mbox_andes_conf *conf = dev->config;

	return conf->channel_max;
}

static int mbox_andes_set_enabled(const struct device *dev, uint32_t ch,
				  bool enable)
{
	uint32_t en, is_enabled_ch, hartid, cpu_id, irq;
	struct mbox_andes_data *data = dev->data;
	int ret = 0;

	k_spinlock_key_t key = k_spin_lock(&mbox_syn);

	if (!is_channel_valid(dev, ch)) {
		ret = -EINVAL;
		goto out;
	}

	irq = ch + 1;
	hartid = arch_proc_id();
	cpu_id = _current_cpu->id;

	is_enabled_ch = data->enabled_channel[cpu_id] & BIT(ch);

	if ((!enable && !is_enabled_ch) || (enable && is_enabled_ch)) {
		ret = -EALREADY;
		goto out;
	}

	if (enable && !(data->cb[ch])) {
		LOG_WRN("Enabling channel without a registered callback\n");
	}

	en = sys_read32(REG_ENABLE(dev, hartid, irq));

	if (enable) {
		data->enabled_channel[cpu_id] |= BIT(ch);
		sys_write32(1, REG_PRIORITY(dev, irq));
		en |= BIT(irq);
	} else {
		data->enabled_channel[cpu_id] &= ~BIT(ch);
		en &= ~BIT(irq);
	}

	sys_write32(en, REG_ENABLE(dev, hartid, irq));
out:
	k_spin_unlock(&mbox_syn, key);

	return ret;
}

static void andes_plic_sw_irq_handler(const struct device *dev)
{
	struct mbox_andes_data *data = dev->data;
	uint32_t irq, ch, hartid;

	hartid = arch_proc_id();

	/* PLIC claim: Get the SW IRQ number generating the interrupt. */
	irq = sys_read32(REG_CLAIM(dev, hartid));
	ch = irq - 1;

	if (irq) {
		sys_write32(irq, REG_CLAIM(dev, hartid));

		if (data->cb[ch]) {
			/* Only one MAILBOX, id is unused and set to 0 */
			data->cb[ch](dev, ch, data->user_data[ch], NULL);
		}
	}
}

static int mbox_andes_init(const struct device *dev)
{
	/* Setup IRQ handler for PLIC SW driver */
	IRQ_CONNECT(RISCV_IRQ_MSOFT, 1,
		    andes_plic_sw_irq_handler, DEVICE_DT_INST_GET(0), 0);

#ifndef CONFIG_SMP
	irq_enable(RISCV_IRQ_MSOFT);
#endif
	return 0;
}

static const struct mbox_driver_api mbox_andes_driver_api = {
	.send = mbox_andes_send,
	.register_callback = mbox_andes_register_callback,
	.mtu_get = mbox_andes_mtu_get,
	.max_channels_get = mbox_andes_max_channels_get,
	.set_enabled = mbox_andes_set_enabled,
};

DEVICE_DT_INST_DEFINE(0, mbox_andes_init, NULL, &andes_mbox_data,
		      &andes_mbox_conf, PRE_KERNEL_1, CONFIG_MBOX_INIT_PRIORITY,
		      &mbox_andes_driver_api);
