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

/*
 * Copyright (c) 2015 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <nanokernel.h>
#include <stdint.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 uint32_t inbound_channels;

static uint32_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;
	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);
	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.ctrl,
			      &ipm->data);

	key = irq_lock();

	ipm->sts.irq = 1; /* Clear the interrupt bit */
	ipm->sts.sts = 1; /* Clear channel status 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, uint32_t id,
			const void *data, int size)
{
	struct quark_se_ipm_config_info *config = d->config->config_info;
	volatile struct quark_se_ipm *ipm = config->ipm;
	const uint8_t *data8;
	int i;
	int flags;

	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_BYTES) {
		return -EMSGSIZE;
	}

	flags = irq_lock();

	if (ipm->sts.sts != 0) {
		irq_unlock(flags);
		return -EBUSY;
	}

	/* Populate the data, memcpy doesn't take volatiles */
	data8 = (const uint8_t *)data;

	for (i = 0; i < size; ++i) {
		ipm->data[i] = data8[i];
	}
	ipm->ctrl.ctrl = id;

	/* Cause the interrupt to assert on the remote side */
	ipm->ctrl.irq = 1;

	/* Wait for HW to set the sts bit */
	while (ipm->sts.sts == 0) {
	}
	irq_unlock(flags);

	if (wait) {
		/* Loop until remote clears the status bit */
		while (ipm->sts.sts != 0) {
		}
	}
	return 0;
}


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

	return QUARK_SE_IPM_DATA_BYTES;
}


static uint32_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)
{
	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;
}

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)
{
	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.sts = 0;
		ipm->sts.irq = 0;
	}
#endif

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


int quark_se_ipm_initialize(struct device *d)
{
	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;
}


