/*
 * Hisilicon's Hi6220 mailbox driver
 *
 * Copyright (c) 2015 Hisilicon Limited.
 * Copyright (c) 2015 Linaro Limited.
 *
 * Author: Leo Yan <leo.yan@linaro.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <linux/device.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kfifo.h>
#include <linux/mailbox_controller.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#define MBOX_CHAN_MAX			32

#define MBOX_TX				0x1

/* Mailbox message length: 8 words */
#define MBOX_MSG_LEN			8

/* Mailbox Registers */
#define MBOX_OFF(m)			(0x40 * (m))
#define MBOX_MODE_REG(m)		(MBOX_OFF(m) + 0x0)
#define MBOX_DATA_REG(m)		(MBOX_OFF(m) + 0x4)

#define MBOX_STATE_MASK			(0xF << 4)
#define MBOX_STATE_IDLE			(0x1 << 4)
#define MBOX_STATE_TX			(0x2 << 4)
#define MBOX_STATE_RX			(0x4 << 4)
#define MBOX_STATE_ACK			(0x8 << 4)
#define MBOX_ACK_CONFIG_MASK		(0x1 << 0)
#define MBOX_ACK_AUTOMATIC		(0x1 << 0)
#define MBOX_ACK_IRQ			(0x0 << 0)

/* IPC registers */
#define ACK_INT_RAW_REG(i)		((i) + 0x400)
#define ACK_INT_MSK_REG(i)		((i) + 0x404)
#define ACK_INT_STAT_REG(i)		((i) + 0x408)
#define ACK_INT_CLR_REG(i)		((i) + 0x40c)
#define ACK_INT_ENA_REG(i)		((i) + 0x500)
#define ACK_INT_DIS_REG(i)		((i) + 0x504)
#define DST_INT_RAW_REG(i)		((i) + 0x420)


struct hi6220_mbox_chan {

	/*
	 * Description for channel's hardware info:
	 *  - direction: tx or rx
	 *  - dst irq: peer core's irq number
	 *  - ack irq: local irq number
	 *  - slot number
	 */
	unsigned int dir, dst_irq, ack_irq;
	unsigned int slot;

	struct hi6220_mbox *parent;
};

struct hi6220_mbox {
	struct device *dev;

	int irq;

	/* flag of enabling tx's irq mode */
	bool tx_irq_mode;

	/* region for ipc event */
	void __iomem *ipc;

	/* region for mailbox */
	void __iomem *base;

	unsigned int chan_num;
	struct hi6220_mbox_chan *mchan;

	void *irq_map_chan[MBOX_CHAN_MAX];
	struct mbox_chan *chan;
	struct mbox_controller controller;
};

static void mbox_set_state(struct hi6220_mbox *mbox,
			   unsigned int slot, u32 val)
{
	u32 status;

	status = readl(mbox->base + MBOX_MODE_REG(slot));
	status = (status & ~MBOX_STATE_MASK) | val;
	writel(status, mbox->base + MBOX_MODE_REG(slot));
}

static void mbox_set_mode(struct hi6220_mbox *mbox,
			  unsigned int slot, u32 val)
{
	u32 mode;

	mode = readl(mbox->base + MBOX_MODE_REG(slot));
	mode = (mode & ~MBOX_ACK_CONFIG_MASK) | val;
	writel(mode, mbox->base + MBOX_MODE_REG(slot));
}

static bool hi6220_mbox_last_tx_done(struct mbox_chan *chan)
{
	struct hi6220_mbox_chan *mchan = chan->con_priv;
	struct hi6220_mbox *mbox = mchan->parent;
	u32 state;

	/* Only set idle state for polling mode */
	BUG_ON(mbox->tx_irq_mode);

	state = readl(mbox->base + MBOX_MODE_REG(mchan->slot));
	return ((state & MBOX_STATE_MASK) == MBOX_STATE_IDLE);
}

static int hi6220_mbox_send_data(struct mbox_chan *chan, void *msg)
{
	struct hi6220_mbox_chan *mchan = chan->con_priv;
	struct hi6220_mbox *mbox = mchan->parent;
	unsigned int slot = mchan->slot;
	u32 *buf = msg;
	int i;

	/* indicate as a TX channel */
	mchan->dir = MBOX_TX;

	mbox_set_state(mbox, slot, MBOX_STATE_TX);

	if (mbox->tx_irq_mode)
		mbox_set_mode(mbox, slot, MBOX_ACK_IRQ);
	else
		mbox_set_mode(mbox, slot, MBOX_ACK_AUTOMATIC);

	for (i = 0; i < MBOX_MSG_LEN; i++)
		writel(buf[i], mbox->base + MBOX_DATA_REG(slot) + i * 4);

	/* trigger remote request */
	writel(BIT(mchan->dst_irq), DST_INT_RAW_REG(mbox->ipc));
	return 0;
}

static irqreturn_t hi6220_mbox_interrupt(int irq, void *p)
{
	struct hi6220_mbox *mbox = p;
	struct hi6220_mbox_chan *mchan;
	struct mbox_chan *chan;
	unsigned int state, intr_bit, i;
	u32 msg[MBOX_MSG_LEN];

	state = readl(ACK_INT_STAT_REG(mbox->ipc));
	if (!state) {
		dev_warn(mbox->dev, "%s: spurious interrupt\n",
			 __func__);
		return IRQ_HANDLED;
	}

	while (state) {
		intr_bit = __ffs(state);
		state &= (state - 1);

		chan = mbox->irq_map_chan[intr_bit];
		if (!chan) {
			dev_warn(mbox->dev, "%s: unexpected irq vector %d\n",
				 __func__, intr_bit);
			continue;
		}

		mchan = chan->con_priv;
		if (mchan->dir == MBOX_TX)
			mbox_chan_txdone(chan, 0);
		else {
			for (i = 0; i < MBOX_MSG_LEN; i++)
				msg[i] = readl(mbox->base +
					MBOX_DATA_REG(mchan->slot) + i * 4);

			mbox_chan_received_data(chan, (void *)msg);
		}

		/* clear IRQ source */
		writel(BIT(mchan->ack_irq), ACK_INT_CLR_REG(mbox->ipc));
		mbox_set_state(mbox, mchan->slot, MBOX_STATE_IDLE);
	}

	return IRQ_HANDLED;
}

static int hi6220_mbox_startup(struct mbox_chan *chan)
{
	struct hi6220_mbox_chan *mchan = chan->con_priv;
	struct hi6220_mbox *mbox = mchan->parent;

	mchan->dir = 0;

	/* enable interrupt */
	writel(BIT(mchan->ack_irq), ACK_INT_ENA_REG(mbox->ipc));
	return 0;
}

static void hi6220_mbox_shutdown(struct mbox_chan *chan)
{
	struct hi6220_mbox_chan *mchan = chan->con_priv;
	struct hi6220_mbox *mbox = mchan->parent;

	/* disable interrupt */
	writel(BIT(mchan->ack_irq), ACK_INT_DIS_REG(mbox->ipc));
	mbox->irq_map_chan[mchan->ack_irq] = NULL;
}

static const struct mbox_chan_ops hi6220_mbox_ops = {
	.send_data    = hi6220_mbox_send_data,
	.startup      = hi6220_mbox_startup,
	.shutdown     = hi6220_mbox_shutdown,
	.last_tx_done = hi6220_mbox_last_tx_done,
};

static struct mbox_chan *hi6220_mbox_xlate(struct mbox_controller *controller,
					   const struct of_phandle_args *spec)
{
	struct hi6220_mbox *mbox = dev_get_drvdata(controller->dev);
	struct hi6220_mbox_chan *mchan;
	struct mbox_chan *chan;
	unsigned int i = spec->args[0];
	unsigned int dst_irq = spec->args[1];
	unsigned int ack_irq = spec->args[2];

	/* Bounds checking */
	if (i >= mbox->chan_num || dst_irq >= mbox->chan_num ||
	    ack_irq >= mbox->chan_num) {
		dev_err(mbox->dev,
			"Invalid channel idx %d dst_irq %d ack_irq %d\n",
			i, dst_irq, ack_irq);
		return ERR_PTR(-EINVAL);
	}

	/* Is requested channel free? */
	chan = &mbox->chan[i];
	if (mbox->irq_map_chan[ack_irq] == (void *)chan) {
		dev_err(mbox->dev, "Channel in use\n");
		return ERR_PTR(-EBUSY);
	}

	mchan = chan->con_priv;
	mchan->dst_irq = dst_irq;
	mchan->ack_irq = ack_irq;

	mbox->irq_map_chan[ack_irq] = (void *)chan;
	return chan;
}

static const struct of_device_id hi6220_mbox_of_match[] = {
	{ .compatible = "hisilicon,hi6220-mbox", },
	{},
};
MODULE_DEVICE_TABLE(of, hi6220_mbox_of_match);

static int hi6220_mbox_probe(struct platform_device *pdev)
{
	struct device_node *node = pdev->dev.of_node;
	struct device *dev = &pdev->dev;
	struct hi6220_mbox *mbox;
	struct resource *res;
	int i, err;

	mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
	if (!mbox)
		return -ENOMEM;

	mbox->dev = dev;
	mbox->chan_num = MBOX_CHAN_MAX;
	mbox->mchan = devm_kzalloc(dev,
		mbox->chan_num * sizeof(*mbox->mchan), GFP_KERNEL);
	if (!mbox->mchan)
		return -ENOMEM;

	mbox->chan = devm_kzalloc(dev,
		mbox->chan_num * sizeof(*mbox->chan), GFP_KERNEL);
	if (!mbox->chan)
		return -ENOMEM;

	mbox->irq = platform_get_irq(pdev, 0);
	if (mbox->irq < 0)
		return mbox->irq;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	mbox->ipc = devm_ioremap_resource(dev, res);
	if (IS_ERR(mbox->ipc)) {
		dev_err(dev, "ioremap ipc failed\n");
		return PTR_ERR(mbox->ipc);
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	mbox->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(mbox->base)) {
		dev_err(dev, "ioremap buffer failed\n");
		return PTR_ERR(mbox->base);
	}

	err = devm_request_irq(dev, mbox->irq, hi6220_mbox_interrupt, 0,
			dev_name(dev), mbox);
	if (err) {
		dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n",
			err);
		return -ENODEV;
	}

	mbox->controller.dev = dev;
	mbox->controller.chans = &mbox->chan[0];
	mbox->controller.num_chans = mbox->chan_num;
	mbox->controller.ops = &hi6220_mbox_ops;
	mbox->controller.of_xlate = hi6220_mbox_xlate;

	for (i = 0; i < mbox->chan_num; i++) {
		mbox->chan[i].con_priv = &mbox->mchan[i];
		mbox->irq_map_chan[i] = NULL;

		mbox->mchan[i].parent = mbox;
		mbox->mchan[i].slot   = i;
	}

	/* mask and clear all interrupt vectors */
	writel(0x0,  ACK_INT_MSK_REG(mbox->ipc));
	writel(~0x0, ACK_INT_CLR_REG(mbox->ipc));

	/* use interrupt for tx's ack */
	if (of_find_property(node, "hi6220,mbox-tx-noirq", NULL))
		mbox->tx_irq_mode = false;
	else
		mbox->tx_irq_mode = true;

	if (mbox->tx_irq_mode)
		mbox->controller.txdone_irq = true;
	else {
		mbox->controller.txdone_poll = true;
		mbox->controller.txpoll_period = 5;
	}

	err = mbox_controller_register(&mbox->controller);
	if (err) {
		dev_err(dev, "Failed to register mailbox %d\n", err);
		return err;
	}

	platform_set_drvdata(pdev, mbox);
	dev_info(dev, "Mailbox enabled\n");
	return 0;
}

static int hi6220_mbox_remove(struct platform_device *pdev)
{
	struct hi6220_mbox *mbox = platform_get_drvdata(pdev);

	mbox_controller_unregister(&mbox->controller);
	return 0;
}

static struct platform_driver hi6220_mbox_driver = {
	.driver = {
		.name = "hi6220-mbox",
		.owner = THIS_MODULE,
		.of_match_table = hi6220_mbox_of_match,
	},
	.probe	= hi6220_mbox_probe,
	.remove	= hi6220_mbox_remove,
};

static int __init hi6220_mbox_init(void)
{
	return platform_driver_register(&hi6220_mbox_driver);
}
core_initcall(hi6220_mbox_init);

static void __exit hi6220_mbox_exit(void)
{
	platform_driver_unregister(&hi6220_mbox_driver);
}
module_exit(hi6220_mbox_exit);

MODULE_AUTHOR("Leo Yan <leo.yan@linaro.org>");
MODULE_DESCRIPTION("Hi6220 mailbox driver");
MODULE_LICENSE("GPL v2");
