/*
 * Copyright (c) 2020 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT intel_cavs_idc

#include <stdint.h>
#include <device.h>
#include <init.h>
#include <drivers/ipm.h>
#include <arch/common/sys_io.h>

#include <soc.h>
#include <soc/shim.h>
#ifndef CONFIG_SOC_INTEL_S1000
#include <adsp/io.h>
#endif

#include "ipm_cavs_idc.h"

#ifdef CONFIG_SCHED_IPI_SUPPORTED
extern void z_sched_ipi(void);
#endif

struct cavs_idc_data {
	ipm_callback_t	cb;
	void		*user_data;
};

static struct cavs_idc_data cavs_idc_device_data;

static void cavs_idc_isr(const struct device *dev)
{
	struct cavs_idc_data *drv_data = dev->data;

	uint32_t i, id;
	void *ext;
	uint32_t idctfc;
	uint32_t curr_cpu_id = arch_curr_cpu()->id;
#ifdef CONFIG_SCHED_IPI_SUPPORTED
	bool do_sched_ipi = false;
#endif

	for (i = 0; i < CONFIG_MP_NUM_CPUS; i++) {
		if (i == curr_cpu_id) {
			/* skip current core */
			continue;
		}

		idctfc = idc_read(IPC_IDCTFC(i), curr_cpu_id);

		if ((idctfc & IPC_IDCTFC_BUSY) == 0) {
			/* No message from this core */
			continue;
		}

		/* Extract the message */
		id = idctfc & IPC_IDCTFC_MSG_MASK;

		switch (id) {
#ifdef CONFIG_SCHED_IPI_SUPPORTED
		case IPM_CAVS_IDC_MSG_SCHED_IPI_ID:
			do_sched_ipi = true;
			break;
#endif
		default:
			if (drv_data->cb != NULL) {
				ext = UINT_TO_POINTER(
					idc_read(IPC_IDCTEFC(i), curr_cpu_id) &
					IPC_IDCTEFC_MSG_MASK);
			drv_data->cb(dev, drv_data->user_data, id, ext);
			}
			break;
		}

		/* Reset busy bit by writing to it */
		idctfc |= IPC_IDCTFC_BUSY;
		idc_write(IPC_IDCTFC(i), curr_cpu_id, idctfc);
	}
#ifdef CONFIG_SCHED_IPI_SUPPORTED
	if (do_sched_ipi) {
		z_sched_ipi();
	}
#endif
}

static int cavs_idc_send(const struct device *dev, int wait, uint32_t id,
			 const void *data, int size)
{
	uint32_t curr_cpu_id = arch_curr_cpu()->id;
	uint32_t ext = POINTER_TO_UINT(data);
	uint32_t reg;
	bool busy;
	int i;

	if ((wait != 0) || (size != 0)) {
		return -ENOTSUP;
	}

	/* Check if any core is still busy */
	busy = false;
	for (i = 0; i < CONFIG_MP_NUM_CPUS; i++) {
		if (i == curr_cpu_id) {
			/* skip current core */
			continue;
		}

		reg = idc_read(IPC_IDCITC(i), curr_cpu_id);
		if ((reg & IPC_IDCITC_BUSY) != 0) {
			busy = true;
			break;
		}
	}

	/* Can't send if busy */
	if (busy) {
		return -EBUSY;
	}

	id &= IPC_IDCITC_MSG_MASK;
	ext &= IPC_IDCIETC_MSG_MASK;
	ext |= IPC_IDCIETC_DONE; /* always clear DONE bit */

	for (i = 0; i < CONFIG_MP_NUM_CPUS; i++) {
		if (i == curr_cpu_id) {
			/* skip current core */
			continue;
		}

		idc_write(IPC_IDCIETC(i), curr_cpu_id, ext);
		idc_write(IPC_IDCITC(i), curr_cpu_id, id | IPC_IDCITC_BUSY);
	}

	return 0;
}

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

	/* IDC can send an ID (of 31 bits, the header) and
	 * another data of 30 bits (the extension). It cannot
	 * send a whole message over. Best we can do is send
	 * a 4-byte aligned pointer.
	 *
	 * So return 0 here for max data size.
	 */

	return 0;
}

static uint32_t cavs_idc_max_id_val_get(const struct device *dev)
{
	ARG_UNUSED(dev);

	return IPM_CAVS_IDC_ID_MASK;
}

static void cavs_idc_register_callback(const struct device *dev,
				       ipm_callback_t cb,
				       void *user_data)
{
	struct cavs_idc_data *drv_data = dev->data;

	drv_data->cb = cb;
	drv_data->user_data = user_data;
}

static int cavs_idc_set_enabled(const struct device *dev, int enable)
{
	int i, j;
	uint32_t mask;

#ifdef CONFIG_SCHED_IPI_SUPPORTED
	/* With scheduler IPI, IDC must always be enabled. */
	if (enable == 0) {
		return -ENOTSUP;
	}
#endif

	for (i = 0; i < CONFIG_MP_NUM_CPUS; i++) {
		mask = 0;

		if (enable) {
			for (j = 0; j < CONFIG_MP_NUM_CPUS; j++) {
				if (i == j) {
					continue;
				}

				mask |= IPC_IDCCTL_IDCTBIE(j);
			}
		}

		idc_write(IPC_IDCCTL, i, mask);

		/* FIXME: when we have API to enable IRQ on specific core. */
		sys_set_bit(DT_REG_ADDR(DT_NODELABEL(cavs0)) + 0x04 +
			    CAVS_ICTL_INT_CPU_OFFSET(i),
			    CAVS_IRQ_NUMBER(DT_INST_IRQN(0)));
	}

	return 0;
}

static int cavs_idc_init(const struct device *dev)
{
	IRQ_CONNECT(DT_INST_IRQN(0),
		    DT_INST_IRQ(0, priority),
		    cavs_idc_isr, DEVICE_DT_INST_GET(0), 0);

	irq_enable(DT_INST_IRQN(0));

	return 0;
}

static const struct ipm_driver_api cavs_idc_driver_api = {
	.send = cavs_idc_send,
	.register_callback = cavs_idc_register_callback,
	.max_data_size_get = cavs_idc_max_data_size_get,
	.max_id_val_get = cavs_idc_max_id_val_get,
	.set_enabled = cavs_idc_set_enabled,
};

DEVICE_DT_INST_DEFINE(0, &cavs_idc_init, device_pm_control_nop,
		    &cavs_idc_device_data, NULL,
		    PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
		    &cavs_idc_driver_api);

#ifdef CONFIG_SCHED_IPI_SUPPORTED
static int cavs_idc_smp_init(const struct device *dev)
{
	/* Enable IDC for scheduler IPI */
	cavs_idc_set_enabled(dev, 1);

	return 0;
}

SYS_INIT(cavs_idc_smp_init, SMP, 0);
#endif
