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

 #include <zephyr/spinlock.h>

#include <cavs_ipc.h>
#include <cavs-ipc-regs.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_INTEL_CAVS_V15)) {
			regs->tda = CAVS_IPC_DONE;
		}
	}

	/* Same signal, but on different bits in 1.5 */
	bool done = IS_ENABLED(CONFIG_SOC_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_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_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
