/* Copyright (c) 2022, Intel Corporation
 * SPDX-License-Identifier: Apache-2.0
 */
#include <kernel.h>
#include <drivers/ipm.h>
#include <cavs-mem.h>
#include <cavs-shim.h>
#include <cavs_ipc.h>

/* Matches SOF_IPC_MSG_MAX_SIZE, though in practice nothing anywhere
 * near that big is ever sent.  Should maybe consider making this a
 * kconfig to avoid waste.
 */
#define MAX_MSG 384

/* Note: these addresses aren't flexible!  We require that they match
 * current SOF ipc3/4 layout, which means that:
 *
 * + Buffer addresses are 4k-aligned (this is a hardware requirement)
 * + Inbuf must be 4k after outbuf, with no use of the intervening memory
 * + Outbuf must be 4k after the start of win0 (this is where the host driver looks)
 *
 * One side effect is that the word "before" MSG_INBUF is owned by our
 * code too, and can be used for a nice trick below.
 */
#define BUFPTR(ptr, off) ((uint32_t *) \
	arch_xtensa_uncached_ptr((void *)((uint32_t)ptr + off)))
#define MSG_INBUF BUFPTR(L2_SRAM_BASE, CONFIG_IPM_CAVS_HOST_INBOX_OFFSET)
#define MSG_OUTBUF BUFPTR(HP_SRAM_WIN0_BASE, CONFIG_IPM_CAVS_HOST_OUTBOX_OFFSET)

struct ipm_cavs_host_data {
	ipm_callback_t callback;
	void *user_data;
	bool enabled;
};

/* Note: this call is unsynchronized.  The IPM docs are silent as to
 * whether this is required, and the SOF code that will be using this
 * is externally synchronized already.
 */
static int send(const struct device *ipmdev, int wait, uint32_t id,
		const void *data, int size)
{
	if (!cavs_ipc_is_complete(CAVS_HOST_DEV)) {
		return -EBUSY;
	}

	if (size > MAX_MSG) {
		return -EMSGSIZE;
	}

	if ((id & 0xc0000000) != 0) {
		/* cAVS IDR register has only 30 usable bits */
		return -EINVAL;
	}

	uint32_t ext_data = 0;

	/* Protocol variant (used by SOF "ipc4"): store the first word
	 * of the message in the IPC scratch registers
	 */
	if (IS_ENABLED(CONFIG_IPM_CAVS_HOST_REGWORD) && size >= 4) {
		ext_data = ((uint32_t *)data)[0];
		data = &((const uint32_t *)data)[1];
		size -= 4;
	}

	memcpy(MSG_OUTBUF, data, size);

	bool ok = cavs_ipc_send_message(CAVS_HOST_DEV, id, ext_data);

	/* The IPM docs call for "busy waiting" here, but in fact
	 * there's a blocking synchronous call available that might be
	 * better.  But then we'd have to check whether we're in
	 * interrupt context, and it's not clear to me that SOF would
	 * benefit anyway as all its usage is async.  This is OK for
	 * now.
	 */
	if (ok && wait) {
		while (!cavs_ipc_is_complete(CAVS_HOST_DEV)) {
			k_busy_wait(1);
		}
	}

	return ok ? 0 : -EBUSY;
}

static bool ipc_handler(const struct device *dev, void *arg,
			uint32_t data, uint32_t ext_data)
{
	ARG_UNUSED(arg);
	struct device *ipmdev = arg;
	struct ipm_cavs_host_data *devdata = ipmdev->data;
	uint32_t *msg = MSG_INBUF;

	/* We play tricks to leave one word available before the
	 * beginning of the SRAM window, this way the host can see the
	 * same offsets it does with the original ipc4 protocol
	 * implementation, but here in the firmware we see a single
	 * contiguous buffer.  See above.
	 */
	if (IS_ENABLED(CONFIG_IPM_CAVS_HOST_REGWORD)) {
		msg = &msg[-1];
		msg[0] = ext_data;
	}

	if (devdata->enabled && (devdata->callback != NULL)) {
		devdata->callback(ipmdev, devdata->user_data,
				  data & 0x3fffffff, msg);
	}

	/* Return false for async handling */
	return !IS_ENABLED(IPM_CALLBACK_ASYNC);
}

static int max_data_size_get(const struct device *ipmdev)
{
	return MAX_MSG;
}

static uint32_t max_id_val_get(const struct device *ipmdev)
{
	/* 30 user-writable bits in cAVS IDR register */
	return 0x3fffffff;
}

static void register_callback(const struct device *port,
			      ipm_callback_t cb,
			      void *user_data)
{
	struct ipm_cavs_host_data *data = port->data;

	data->callback = cb;
	data->user_data = user_data;
}

static int set_enabled(const struct device *ipmdev, int enable)
{
	/* This protocol doesn't support any kind of queuing, and in
	 * fact will stall if a message goes unacknowledged.  Support
	 * it as best we can by gating the callbacks only.  That will
	 * allow the DONE notifications to proceed as normal, at the
	 * cost of dropping any messages received while not "enabled"
	 * of course.
	 */
	struct ipm_cavs_host_data *data = ipmdev->data;

	data->enabled = enable;
	return 0;
}

static void complete(const struct device *ipmdev)
{
	cavs_ipc_complete(CAVS_HOST_DEV);
}

static int init(const struct device *dev)
{
	struct ipm_cavs_host_data *data = dev->data;

	/* Initialize hardware SRAM window.  SOF will give the host 8k
	 * here, let's limit it to just the memory we're using for
	 * futureproofing.
	 */
	CAVS_WIN[1].dmwlo = ROUND_UP(MAX_MSG, 8);
	CAVS_WIN[1].dmwba = ((uint32_t) MSG_INBUF) | CAVS_DMWBA_ENABLE;

	cavs_ipc_set_message_handler(CAVS_HOST_DEV, ipc_handler, (void *)dev);

	data->enabled = true;
	return 0;
}

static const struct ipm_driver_api api = {
	.send = send,
	.max_data_size_get = max_data_size_get,
	.max_id_val_get = max_id_val_get,
	.register_callback = register_callback,
	.set_enabled = set_enabled,
	.complete = complete,
};

static struct ipm_cavs_host_data data;

DEVICE_DEFINE(ipm_cavs_host, "ipm_cavs_host", init, NULL, &data, NULL,
	      PRE_KERNEL_2, 1, &api);
