/* ipm_quark_se.c - Quark SE mailbox driver */

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

#include <kernel.h>
#include <zephyr/types.h>
#include <string.h>
#include <device.h>
#include <init.h>
#include <ipm.h>
#include <arch/cpu.h>
#include <misc/printk.h>
#include <misc/__assert.h>
#include <errno.h>
#include "ipm_quark_se.h"


/* We have a single ISR for all channels, so in order to properly handle
 * messages we need to figure out which device object corresponds to
 * in incoming channel
 */
static struct device *device_by_channel[QUARK_SE_IPM_CHANNELS];
static u32_t inbound_channels;

static u32_t quark_se_ipm_sts_get(void)
{
	return sys_read32(QUARK_SE_IPM_CHALL_STS) & inbound_channels;
}

static void set_channel_irq_state(int channel, int enable)
{
	mem_addr_t addr = QUARK_SE_IPM_MASK;
	int bit = channel + QUARK_SE_IPM_MASK_START_BIT;

	if (enable) {
		sys_clear_bit(addr, bit);
	} else {
		sys_set_bit(addr, bit);
	}
}


/* Interrupt handler, gets messages on all incoming enabled mailboxes */
void quark_se_ipm_isr(void *param)
{
	int channel;
	int sts, bit;
	struct device *d;
	const struct quark_se_ipm_config_info *config;
	struct quark_se_ipm_driver_data *driver_data;
	volatile struct quark_se_ipm *ipm;
	unsigned int key;

	ARG_UNUSED(param);

	while ((sts = quark_se_ipm_sts_get())) {
		__ASSERT(sts, "spurious IPM interrupt");
		bit = find_msb_set(sts) - 1;
		channel = bit / 2;
		d = device_by_channel[channel];

		__ASSERT(d, "got IRQ on channel with no IPM device");
		config = d->config->config_info;
		driver_data = d->driver_data;
		ipm = config->ipm;

		__ASSERT(driver_data->callback,
			 "enabled IPM channel with no callback");
		driver_data->callback(driver_data->callback_ctx,
				      ipm->ctrl & QUARK_SE_IPM_CTRL_CTRL_MASK,
				      &ipm->data);

		key = irq_lock();

		/* Clear the interrupt bit */
		ipm->sts = QUARK_SE_IPM_STS_IRQ_BIT;
		/* Clear channel status bit */
		ipm->sts = QUARK_SE_IPM_STS_STS_BIT;

		/* Wait for the above register writes to clear the channel
		 * to propagate to the global channel status register
		 */
		while (quark_se_ipm_sts_get() & (0x3 << (channel * 2))) {
			/* Busy-wait */
		}
		irq_unlock(key);
	}
}

static int quark_se_ipm_send(struct device *d, int wait, u32_t id,
			const void *data, int size)
{
	const struct quark_se_ipm_config_info *config = d->config->config_info;
	volatile struct quark_se_ipm *ipm = config->ipm;
	u32_t data32[4]; /* Until we change API to u32_t array */
	int flags;
	int i;

	if (id > QUARK_SE_IPM_MAX_ID_VAL) {
		return -EINVAL;
	}

	if (config->direction != QUARK_SE_IPM_OUTBOUND) {
		return -EINVAL;
	}

	if (size > QUARK_SE_IPM_DATA_REGS * sizeof(u32_t)) {
		return -EMSGSIZE;
	}

	flags = irq_lock();

	if (ipm->sts & QUARK_SE_IPM_STS_STS_BIT) {
		irq_unlock(flags);
		return -EBUSY;
	}

	/* Actual message is passing using 32 bits registers */
	memcpy(data32, data, size);

	for (i = 0; i < ARRAY_SIZE(data32); ++i) {
		ipm->data[i] = data32[i];
	}

	ipm->ctrl = id | QUARK_SE_IPM_CTRL_IRQ_BIT;

	/* Wait for HW to set the sts bit */
	while (!(ipm->sts & QUARK_SE_IPM_STS_STS_BIT)) {
	}

	irq_unlock(flags);

	if (wait) {
		/* Loop until remote clears the status bit */
		while (ipm->sts & QUARK_SE_IPM_STS_STS_BIT) {
		}
	}

	return 0;
}


static int quark_se_ipm_max_data_size_get(struct device *d)
{
	ARG_UNUSED(d);

	return QUARK_SE_IPM_DATA_REGS * sizeof(u32_t);
}


static u32_t quark_se_ipm_max_id_val_get(struct device *d)
{
	ARG_UNUSED(d);

	return QUARK_SE_IPM_MAX_ID_VAL;
}

static void quark_se_ipm_register_callback(struct device *d, ipm_callback_t cb,
				       void *context)
{
	struct quark_se_ipm_driver_data *driver_data = d->driver_data;

	driver_data->callback = cb;
	driver_data->callback_ctx = context;
}


static int quark_se_ipm_set_enabled(struct device *d, int enable)
{
	const struct quark_se_ipm_config_info *config_info =
		d->config->config_info;

	if (config_info->direction != QUARK_SE_IPM_INBOUND) {
		return -EINVAL;
	}
	set_channel_irq_state(config_info->channel, enable);
	return 0;
}

const struct ipm_driver_api ipm_quark_se_api_funcs = {
	.send = quark_se_ipm_send,
	.register_callback = quark_se_ipm_register_callback,
	.max_data_size_get = quark_se_ipm_max_data_size_get,
	.max_id_val_get = quark_se_ipm_max_id_val_get,
	.set_enabled = quark_se_ipm_set_enabled
};

int quark_se_ipm_controller_initialize(struct device *d)
{
	const struct quark_se_ipm_controller_config_info *config =
		d->config->config_info;
#if CONFIG_IPM_QUARK_SE_MASTER
	int i;

	/* Mask all mailbox interrupts, we'll enable them
	 * individually later. Clear out any pending messages
	 */
	sys_write32(0xFFFFFFFF, QUARK_SE_IPM_MASK);
	for (i = 0; i < QUARK_SE_IPM_CHANNELS; ++i) {
		volatile struct quark_se_ipm *ipm = QUARK_SE_IPM(i);

		ipm->sts = 0;
	}
#endif

	if (config->controller_init) {
		return config->controller_init();
	}
	return 0;
}


int quark_se_ipm_initialize(struct device *d)
{
	const struct quark_se_ipm_config_info *config = d->config->config_info;

	device_by_channel[config->channel] = d;
	if (config->direction == QUARK_SE_IPM_INBOUND) {
		inbound_channels |= (0x3 << (config->channel * 2));
	}

	return 0;
}
