/*
 * Copyright (c) 2017, Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. Neither the name of the Intel Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "qm_common.h"
#include "qm_mailbox.h"
#include "qm_interrupt.h"
#include "qm_interrupt_router.h"

/**
 * The Active core can be either Lakemont or the Sensor Sub-System.
 * The active core depends on a compilation flag indicating which
 * core is being used.
 *
 * Core specific mailbox #defines are grouped here to prevent
 * duplication below.
 */

#if HAS_MAILBOX_LAKEMONT_DEST
#if QM_LAKEMONT
#define ACTIVE_CORE_DEST QM_MBOX_TO_LMT
#define MBOX_ACTIVE_CORE_ALL_INT_MASK QM_IR_MBOX_LMT_ALL_INT_MASK
#define MBOX_INT_LOCK_MASK(N) QM_IR_MBOX_LMT_INT_LOCK_MASK(N)
#define MBOX_INT_LOCK_HALT_MASK(N) QM_IR_MBOX_LMT_INT_LOCK_HALT_MASK(N)
#define MBOX_IS_INT_MASK_EN(N) QM_IR_MBOX_IS_LMT_INT_MASK_EN(N)
#define MBOX_ENABLE_INT_MASK(N) QM_IR_MBOX_ENABLE_LMT_INT_MASK(N)
#define MBOX_DISABLE_INT_MASK(N) QM_IR_MBOX_DISABLE_LMT_INT_MASK(N)
#endif /* QM_LAKEMONT */
#endif /* HAS_MAILBOX_LAKEMONT_DEST */

#if HAS_MAILBOX_SENSOR_SUB_SYSTEM_DEST
#if QM_SENSOR
#define ACTIVE_CORE_DEST QM_MBOX_TO_SS
#define MBOX_ACTIVE_CORE_ALL_INT_MASK QM_IR_MBOX_SS_ALL_INT_MASK
#define MBOX_INT_LOCK_MASK(N) QM_IR_MBOX_SS_INT_LOCK_HALT_MASK(N)
#define MBOX_INT_LOCK_HALT_MASK(N) QM_IR_MBOX_SS_INT_LOCK_MASK(N)
#define MBOX_IS_INT_MASK_EN(N) QM_IR_MBOX_IS_SS_INT_MASK_EN(N)
#define MBOX_ENABLE_INT_MASK(N) QM_IR_MBOX_ENABLE_SS_INT_MASK(N)
#define MBOX_DISABLE_INT_MASK(N) QM_IR_MBOX_DISABLE_SS_INT_MASK(N)
#endif /* QM_SENSOR */
#endif /* HAS_MAILBOX_SENSOR_SUB_SYSTEM_DEST */

#define MBOX_CHECK_DESTINATION(_dest) (ACTIVE_CORE_DEST == (_dest))
#define MBOX_CHECK_POLLING_MODE(_mode) (QM_MBOX_POLLING_MODE == (_mode))

static void mailbox_isr_handler(void);

/**
 * Private data structure maintained by the driver
 */
typedef struct {
	/** Destination of the mailbox channel. */
	qm_mbox_destination_t dest;
	/** Defines if the mailbox channel operates in interrupt
	 * mode or polling mode. */
	qm_mbox_mode_t mode;
	/** Callback function registered with the application. */
	qm_mbox_callback_t callback;
	/** Callback function data return via the callback function. */
	void *callback_data;
} qm_mailbox_info_t;

/* Mailbox channels private data structures */
static qm_mailbox_info_t mailbox_devs[NUM_MAILBOXES];

QM_ISR_DECLARE(qm_mailbox_0_isr)
{
	mailbox_isr_handler();
	QM_ISR_EOI(QM_IRQ_MAILBOX_0_INT_VECTOR);
}

static void mailbox_isr_handler(void)
{
	qm_mailbox_t *const mbox_reg = (qm_mailbox_t *)QM_MAILBOX;
	uint8_t i = 0;
	uint8_t mask;
	uint16_t chall_sts = QM_MAILBOX->mbox_chall_sts;

	mask = MBOX_ACTIVE_CORE_ALL_INT_MASK;
	for (i = 0; chall_sts; i++, chall_sts >>= 2) {
		if ((chall_sts & QM_MBOX_CH_STS_CTRL_INT) == 0) {
			continue;
		}
		if (mask & BIT(i)) {
			continue;
		}
		if (mbox_reg[i].ch_sts & QM_MBOX_CH_STS_CTRL_INT) {
			if (NULL != mailbox_devs[i].callback) {
				/* Callback */
				mailbox_devs[i].callback(
				    mailbox_devs[i].callback_data);
			}
			/* Clear the interrupt */
			mbox_reg[i].ch_sts = QM_MBOX_CH_STS_CTRL_INT;
		}
	}
}

int qm_mbox_ch_set_config(const qm_mbox_ch_t mbox_ch,
			  const qm_mbox_config_t *const config)
{

	QM_CHECK((QM_MBOX_CH_0 <= mbox_ch) && (mbox_ch < NUM_MAILBOXES),
		 -EINVAL);
	qm_mailbox_info_t *device = &mailbox_devs[mbox_ch];

	/* Block interrupts while configuring MBOX */
	QM_IR_MASK_INT(QM_IRQ_MAILBOX_0_INT);

	/* Store the device destination */
	device->dest = config->dest;

	/* Check if we are enabling or disabling the channel. */
	if (QM_MBOX_UNUSED != config->dest) {

		if (QM_MBOX_INTERRUPT_MODE == config->mode) {
			QM_CHECK(NULL != config->callback, -EINVAL);

			/* Register callback function */
			device->callback = config->callback;
			/* Register callback function data */
			device->callback_data = config->callback_data;
			/* Update the mode of operation for the mailbox channel.
			 */
			device->mode = QM_MBOX_INTERRUPT_MODE;

			/* Enable the mailbox interrupt if the lock is not set.
			 */
			if (!(MBOX_INT_LOCK_MASK(mbox_ch))) {
				/* Note: Routing is done now, cannot be done in
				 * irq_request! */
				MBOX_ENABLE_INT_MASK(mbox_ch);
			} else {
				/* The lock is set, but we need to check if the
				 * interrupt is routed */
				QM_CHECK(MBOX_IS_INT_MASK_EN(mbox_ch), -EIO);
			}
		} else {
			device->mode = QM_MBOX_POLLING_MODE;
			/* Disable the mailbox interrupt if the lock is not set.
			 */
			if (!(MBOX_INT_LOCK_MASK(mbox_ch))) {
				/* Note: Routing is done now, cannot be done in
				 * irq_request! */
				MBOX_DISABLE_INT_MASK(mbox_ch);
			}

			device->callback = NULL;
			device->callback_data = 0;
		}
	} else {
		/* Disable the mailbox interrupt if the lock is not set. */
		if (!(MBOX_INT_LOCK_MASK(mbox_ch))) {
			/* Note: Routing is done now, cannot be done in
			 * irq_request! */
			MBOX_DISABLE_INT_MASK(mbox_ch);
		}

		/* Set the mailbox channel to its default configuration. */
		device->dest = QM_MBOX_UNUSED;
		device->mode = QM_MBOX_INTERRUPT_MODE;
		device->callback = NULL;
		device->callback_data = 0;
	}

	/* UnBlock MBOX interrupts. */
	QM_IR_UNMASK_INT(QM_IRQ_MAILBOX_0_INT);
	return 0;
}

int qm_mbox_ch_write(const qm_mbox_ch_t mbox_ch, const qm_mbox_msg_t *const msg)
{
	QM_CHECK((QM_MBOX_CH_0 <= mbox_ch) && (mbox_ch < NUM_MAILBOXES),
		 -EINVAL);
	QM_CHECK(NULL != msg, -EINVAL);
	qm_mailbox_t *const mbox_reg = (qm_mailbox_t *)QM_MAILBOX + mbox_ch;

	uint32_t status = 0;

	status = QM_MAILBOX->mbox[mbox_ch].ch_sts;

	/* Check if the previous message has been consumed. */
	if (false == (status & (QM_MBOX_CH_STS_CTRL_INT | QM_MBOX_CH_STS))) {
		/* Write the payload data to the mailbox channel. */
		mbox_reg->ch_data[0] = msg->data[QM_MBOX_PAYLOAD_0];
		mbox_reg->ch_data[1] = msg->data[QM_MBOX_PAYLOAD_1];
		mbox_reg->ch_data[2] = msg->data[QM_MBOX_PAYLOAD_2];
		mbox_reg->ch_data[3] = msg->data[QM_MBOX_PAYLOAD_3];
		/* Write the control word and trigger the channel interrupt. */
		mbox_reg->ch_ctrl = msg->ctrl | QM_MBOX_CH_CTRL_INT;
		return 0;
	}

	/* Previous message has not been consumed. */
	return -EIO;
}

int qm_mbox_ch_read(const qm_mbox_ch_t mbox_ch, qm_mbox_msg_t *const msg)
{
	QM_CHECK((QM_MBOX_CH_0 <= mbox_ch) && (mbox_ch < NUM_MAILBOXES),
		 -EINVAL);
	QM_CHECK(NULL != msg, -EINVAL);

	int rc = 0;
	uint32_t status = 0;

	qm_mailbox_t *mbox_reg = &QM_MAILBOX->mbox[mbox_ch];

	if (MBOX_CHECK_DESTINATION(mailbox_devs[mbox_ch].dest)) {
		status = mbox_reg->ch_sts;

		/* If there is data pending consume it */
		if (status & QM_MBOX_CH_STS) {
			/* Read data from the mailbox channel and clear bit 31
			 * of the control word. */
			msg->ctrl = mbox_reg->ch_ctrl & (~QM_MBOX_CH_CTRL_INT);
			msg->data[0] = mbox_reg->ch_data[0];
			msg->data[1] = mbox_reg->ch_data[1];
			msg->data[2] = mbox_reg->ch_data[2];
			msg->data[3] = mbox_reg->ch_data[3];

			if (MBOX_CHECK_POLLING_MODE(
				mailbox_devs[mbox_ch].mode)) {
				/* In polling mode the interrupt status still
				 * needs to be cleared since we are not using
				 * the ISR. Note we write 1 to clear the bit.
				 */
				mbox_reg->ch_sts = QM_MBOX_CH_STS_CTRL_INT;
			}

			/* Clear data status bit. This indicates to others that
			 * the mailbox data has been consumed and a new message
			 * can be sent on the channel */
			mbox_reg->ch_sts = QM_MBOX_CH_STS;
		} else {
			/* there is no pending data in the mailbox */
			rc = -EIO;
		}
	} else {
		/* Active destination has not been configured to consume data
		 * from this channel */
		rc = -EINVAL;
	}

	return rc;
}

int qm_mbox_ch_get_status(const qm_mbox_ch_t mbox_ch,
			  qm_mbox_ch_status_t *const status)
{
	QM_CHECK((QM_MBOX_CH_0 <= mbox_ch) && (mbox_ch < NUM_MAILBOXES),
		 -EINVAL);
	QM_CHECK(NULL != status, -EINVAL);

	*status = QM_MAILBOX->mbox[mbox_ch].ch_sts;

	return 0;
}
