/* Copyright (c) 2022 Intel Corporation
 * SPDX-License-Identifier: Apache-2.0
 */
#include <cavs_ipc.h>
#include <cavs-ipc-regs.h>
#include <zephyr/spinlock.h>

void cavs_ipc_set_message_handler(const struct device *dev,
				  cavs_ipc_handler_t fn, void *arg)
{
	struct cavs_ipc_data *devdata = dev->data;
	k_spinlock_key_t key = k_spin_lock(&devdata->lock);

	devdata->handle_message = fn;
	devdata->handler_arg = arg;
	k_spin_unlock(&devdata->lock, key);
}

void cavs_ipc_set_done_handler(const struct device *dev,
			       cavs_ipc_done_t fn, void *arg)
{
	struct cavs_ipc_data *devdata = dev->data;
	k_spinlock_key_t key = k_spin_lock(&devdata->lock);

	devdata->done_notify = fn;
	devdata->done_arg = arg;
	k_spin_unlock(&devdata->lock, key);
}

void z_cavs_ipc_isr(const void *devarg)
{
	const struct device *dev = devarg;
	const struct cavs_ipc_config *config = dev->config;
	struct cavs_ipc_data *devdata = dev->data;

	volatile struct cavs_ipc *regs = config->regs;
	k_spinlock_key_t key = k_spin_lock(&devdata->lock);

	if (regs->tdr & CAVS_IPC_BUSY) {
		bool done = true;

		if (devdata->handle_message != NULL) {
			uint32_t msg = regs->tdr & ~CAVS_IPC_BUSY;
			uint32_t ext = regs->tdd;

			done = devdata->handle_message(dev, devdata->handler_arg,
						       msg, ext);
		}

		regs->tdr = CAVS_IPC_BUSY;
		if (done && !IS_ENABLED(CONFIG_SOC_SERIES_INTEL_CAVS_V15)) {
			regs->tda = CAVS_IPC_DONE;
		}
	}

	/* Same signal, but on different bits in 1.5 */
	bool done = IS_ENABLED(CONFIG_SOC_SERIES_INTEL_CAVS_V15) ?
		(regs->idd & CAVS_IPC_IDD15_DONE) : (regs->ida & CAVS_IPC_DONE);

	if (done) {
		if (devdata->done_notify != NULL) {
			devdata->done_notify(dev, devdata->done_arg);
		}
		k_sem_give(&devdata->sem);
		if (IS_ENABLED(CONFIG_SOC_SERIES_INTEL_CAVS_V15)) {
			regs->idd = CAVS_IPC_IDD15_DONE;
		} else {
			regs->ida = CAVS_IPC_DONE;
		}
	}

	k_spin_unlock(&devdata->lock, key);
}

int cavs_ipc_init(const struct device *dev)
{
	struct cavs_ipc_data *devdata = dev->data;
	const struct cavs_ipc_config *config = dev->config;

	memset(devdata, 0, sizeof(*devdata));

	/* ACK any latched interrupts (including TDA to clear IDA on
	 * the other side!), then enable.
	 */
	config->regs->tdr = CAVS_IPC_BUSY;
	if (IS_ENABLED(CONFIG_SOC_SERIES_INTEL_CAVS_V15)) {
		config->regs->idd = CAVS_IPC_IDD15_DONE;
	} else {
		config->regs->ida = CAVS_IPC_DONE;
		config->regs->tda = CAVS_IPC_DONE;
	}
	config->regs->ctl |= (CAVS_IPC_CTL_IDIE | CAVS_IPC_CTL_TBIE);
	return 0;
}

void cavs_ipc_complete(const struct device *dev)
{
	const struct cavs_ipc_config *config = dev->config;

	config->regs->tda = CAVS_IPC_DONE;
}

bool cavs_ipc_is_complete(const struct device *dev)
{
	const struct cavs_ipc_config *config = dev->config;

	return (config->regs->idr & CAVS_IPC_BUSY) == 0;
}

bool cavs_ipc_send_message(const struct device *dev,
			   uint32_t data, uint32_t ext_data)
{
	const struct cavs_ipc_config *config = dev->config;
	struct cavs_ipc_data *devdata = dev->data;
	k_spinlock_key_t key = k_spin_lock(&devdata->lock);

	if ((config->regs->idr & CAVS_IPC_BUSY) != 0) {
		k_spin_unlock(&devdata->lock, key);
		return false;
	}

	k_sem_init(&devdata->sem, 0, 1);
	config->regs->idd = ext_data;
	config->regs->idr = data | CAVS_IPC_BUSY;
	k_spin_unlock(&devdata->lock, key);
	return true;
}

bool cavs_ipc_send_message_sync(const struct device *dev,
				uint32_t data, uint32_t ext_data,
				k_timeout_t timeout)
{
	struct cavs_ipc_data *devdata = dev->data;

	bool ret = cavs_ipc_send_message(dev, data, ext_data);

	if (ret) {
		k_sem_take(&devdata->sem, timeout);
	}
	return ret;
}

#if DT_NODE_EXISTS(CAVS_HOST_DTNODE)
static int dt_init(const struct device *dev)
{
	IRQ_CONNECT(DT_IRQN(CAVS_HOST_DTNODE), 0, z_cavs_ipc_isr, CAVS_HOST_DEV, 0);
	irq_enable(DT_IRQN(CAVS_HOST_DTNODE));
	return cavs_ipc_init(dev);
}

static const struct cavs_ipc_config ipc_host_config = {
	.regs = (void *)DT_REG_ADDR(CAVS_HOST_DTNODE),
};

static struct cavs_ipc_data ipc_host_data;

DEVICE_DT_DEFINE(CAVS_HOST_DTNODE, dt_init, NULL, &ipc_host_data, &ipc_host_config,
		 PRE_KERNEL_2, 0, NULL);
#endif
