// SPDX-License-Identifier: GPL-2.0-only
/*
 * Spreadtrum mailbox driver
 *
 * Copyright (c) 2020 Spreadtrum Communications Inc.
 */

#include <linux/delay.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/mailbox_controller.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/clk.h>

#define SPRD_MBOX_ID		0x0
#define SPRD_MBOX_MSG_LOW	0x4
#define SPRD_MBOX_MSG_HIGH	0x8
#define SPRD_MBOX_TRIGGER	0xc
#define SPRD_MBOX_FIFO_RST	0x10
#define SPRD_MBOX_FIFO_STS	0x14
#define SPRD_MBOX_IRQ_STS	0x18
#define SPRD_MBOX_IRQ_MSK	0x1c
#define SPRD_MBOX_LOCK		0x20
#define SPRD_MBOX_FIFO_DEPTH	0x24

/* Bit and mask definition for inbox's SPRD_MBOX_FIFO_STS register */
#define SPRD_INBOX_FIFO_DELIVER_MASK		GENMASK(23, 16)
#define SPRD_INBOX_FIFO_OVERLOW_MASK		GENMASK(15, 8)
#define SPRD_INBOX_FIFO_DELIVER_SHIFT		16
#define SPRD_INBOX_FIFO_BUSY_MASK		GENMASK(7, 0)

/* Bit and mask definition for SPRD_MBOX_IRQ_STS register */
#define SPRD_MBOX_IRQ_CLR			BIT(0)

/* Bit and mask definition for outbox's SPRD_MBOX_FIFO_STS register */
#define SPRD_OUTBOX_FIFO_FULL			BIT(2)
#define SPRD_OUTBOX_FIFO_WR_SHIFT		16
#define SPRD_OUTBOX_FIFO_RD_SHIFT		24
#define SPRD_OUTBOX_FIFO_POS_MASK		GENMASK(7, 0)

/* Bit and mask definition for inbox's SPRD_MBOX_IRQ_MSK register */
#define SPRD_INBOX_FIFO_BLOCK_IRQ		BIT(0)
#define SPRD_INBOX_FIFO_OVERFLOW_IRQ		BIT(1)
#define SPRD_INBOX_FIFO_DELIVER_IRQ		BIT(2)
#define SPRD_INBOX_FIFO_IRQ_MASK		GENMASK(2, 0)

/* Bit and mask definition for outbox's SPRD_MBOX_IRQ_MSK register */
#define SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ		BIT(0)
#define SPRD_OUTBOX_FIFO_IRQ_MASK		GENMASK(4, 0)

#define SPRD_OUTBOX_BASE_SPAN			0x1000
#define SPRD_MBOX_CHAN_MAX			8
#define SPRD_SUPP_INBOX_ID_SC9863A		7

struct sprd_mbox_priv {
	struct mbox_controller	mbox;
	struct device		*dev;
	void __iomem		*inbox_base;
	void __iomem		*outbox_base;
	/*  Base register address for supplementary outbox */
	void __iomem		*supp_base;
	struct clk		*clk;
	u32			outbox_fifo_depth;

	struct mutex		lock;
	u32			refcnt;
	struct mbox_chan	chan[SPRD_MBOX_CHAN_MAX];
};

static struct sprd_mbox_priv *to_sprd_mbox_priv(struct mbox_controller *mbox)
{
	return container_of(mbox, struct sprd_mbox_priv, mbox);
}

static u32 sprd_mbox_get_fifo_len(struct sprd_mbox_priv *priv, u32 fifo_sts)
{
	u32 wr_pos = (fifo_sts >> SPRD_OUTBOX_FIFO_WR_SHIFT) &
		SPRD_OUTBOX_FIFO_POS_MASK;
	u32 rd_pos = (fifo_sts >> SPRD_OUTBOX_FIFO_RD_SHIFT) &
		SPRD_OUTBOX_FIFO_POS_MASK;
	u32 fifo_len;

	/*
	 * If the read pointer is equal with write pointer, which means the fifo
	 * is full or empty.
	 */
	if (wr_pos == rd_pos) {
		if (fifo_sts & SPRD_OUTBOX_FIFO_FULL)
			fifo_len = priv->outbox_fifo_depth;
		else
			fifo_len = 0;
	} else if (wr_pos > rd_pos) {
		fifo_len = wr_pos - rd_pos;
	} else {
		fifo_len = priv->outbox_fifo_depth - rd_pos + wr_pos;
	}

	return fifo_len;
}

static irqreturn_t do_outbox_isr(void __iomem *base, struct sprd_mbox_priv *priv)
{
	struct mbox_chan *chan;
	u32 fifo_sts, fifo_len, msg[2];
	int i, id;

	fifo_sts = readl(base + SPRD_MBOX_FIFO_STS);

	fifo_len = sprd_mbox_get_fifo_len(priv, fifo_sts);
	if (!fifo_len) {
		dev_warn_ratelimited(priv->dev, "spurious outbox interrupt\n");
		return IRQ_NONE;
	}

	for (i = 0; i < fifo_len; i++) {
		msg[0] = readl(base + SPRD_MBOX_MSG_LOW);
		msg[1] = readl(base + SPRD_MBOX_MSG_HIGH);
		id = readl(base + SPRD_MBOX_ID);

		chan = &priv->chan[id];
		if (chan->cl)
			mbox_chan_received_data(chan, (void *)msg);
		else
			dev_warn_ratelimited(priv->dev,
				    "message's been dropped at ch[%d]\n", id);

		/* Trigger to update outbox FIFO pointer */
		writel(0x1, base + SPRD_MBOX_TRIGGER);
	}

	/* Clear irq status after reading all message. */
	writel(SPRD_MBOX_IRQ_CLR, base + SPRD_MBOX_IRQ_STS);

	return IRQ_HANDLED;
}

static irqreturn_t sprd_mbox_outbox_isr(int irq, void *data)
{
	struct sprd_mbox_priv *priv = data;

	return do_outbox_isr(priv->outbox_base, priv);
}

static irqreturn_t sprd_mbox_supp_isr(int irq, void *data)
{
	struct sprd_mbox_priv *priv = data;

	return do_outbox_isr(priv->supp_base, priv);
}

static irqreturn_t sprd_mbox_inbox_isr(int irq, void *data)
{
	struct sprd_mbox_priv *priv = data;
	struct mbox_chan *chan;
	u32 fifo_sts, send_sts, busy, id;

	fifo_sts = readl(priv->inbox_base + SPRD_MBOX_FIFO_STS);

	/* Get the inbox data delivery status */
	send_sts = (fifo_sts & SPRD_INBOX_FIFO_DELIVER_MASK) >>
		SPRD_INBOX_FIFO_DELIVER_SHIFT;
	if (!send_sts) {
		dev_warn_ratelimited(priv->dev, "spurious inbox interrupt\n");
		return IRQ_NONE;
	}

	while (send_sts) {
		id = __ffs(send_sts);
		send_sts &= (send_sts - 1);

		chan = &priv->chan[id];

		/*
		 * Check if the message was fetched by remote target, if yes,
		 * that means the transmission has been completed.
		 */
		busy = fifo_sts & SPRD_INBOX_FIFO_BUSY_MASK;
		if (!(busy & BIT(id)))
			mbox_chan_txdone(chan, 0);
	}

	/* Clear FIFO delivery and overflow status */
	writel(fifo_sts &
	       (SPRD_INBOX_FIFO_DELIVER_MASK | SPRD_INBOX_FIFO_OVERLOW_MASK),
	       priv->inbox_base + SPRD_MBOX_FIFO_RST);

	/* Clear irq status */
	writel(SPRD_MBOX_IRQ_CLR, priv->inbox_base + SPRD_MBOX_IRQ_STS);

	return IRQ_HANDLED;
}

static int sprd_mbox_send_data(struct mbox_chan *chan, void *msg)
{
	struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox);
	unsigned long id = (unsigned long)chan->con_priv;
	u32 *data = msg;

	/* Write data into inbox FIFO, and only support 8 bytes every time */
	writel(data[0], priv->inbox_base + SPRD_MBOX_MSG_LOW);
	writel(data[1], priv->inbox_base + SPRD_MBOX_MSG_HIGH);

	/* Set target core id */
	writel(id, priv->inbox_base + SPRD_MBOX_ID);

	/* Trigger remote request */
	writel(0x1, priv->inbox_base + SPRD_MBOX_TRIGGER);

	return 0;
}

static int sprd_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
{
	struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox);
	unsigned long id = (unsigned long)chan->con_priv;
	u32 busy;

	timeout = jiffies + msecs_to_jiffies(timeout);

	while (time_before(jiffies, timeout)) {
		busy = readl(priv->inbox_base + SPRD_MBOX_FIFO_STS) &
			SPRD_INBOX_FIFO_BUSY_MASK;
		if (!(busy & BIT(id))) {
			mbox_chan_txdone(chan, 0);
			return 0;
		}

		udelay(1);
	}

	return -ETIME;
}

static int sprd_mbox_startup(struct mbox_chan *chan)
{
	struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox);
	u32 val;

	mutex_lock(&priv->lock);
	if (priv->refcnt++ == 0) {
		/* Select outbox FIFO mode and reset the outbox FIFO status */
		writel(0x0, priv->outbox_base + SPRD_MBOX_FIFO_RST);

		/* Enable inbox FIFO overflow and delivery interrupt */
		val = readl(priv->inbox_base + SPRD_MBOX_IRQ_MSK);
		val &= ~(SPRD_INBOX_FIFO_OVERFLOW_IRQ | SPRD_INBOX_FIFO_DELIVER_IRQ);
		writel(val, priv->inbox_base + SPRD_MBOX_IRQ_MSK);

		/* Enable outbox FIFO not empty interrupt */
		val = readl(priv->outbox_base + SPRD_MBOX_IRQ_MSK);
		val &= ~SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ;
		writel(val, priv->outbox_base + SPRD_MBOX_IRQ_MSK);

		/* Enable supplementary outbox as the fundamental one */
		if (priv->supp_base) {
			writel(0x0, priv->supp_base + SPRD_MBOX_FIFO_RST);
			val = readl(priv->supp_base + SPRD_MBOX_IRQ_MSK);
			val &= ~SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ;
			writel(val, priv->supp_base + SPRD_MBOX_IRQ_MSK);
		}
	}
	mutex_unlock(&priv->lock);

	return 0;
}

static void sprd_mbox_shutdown(struct mbox_chan *chan)
{
	struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox);

	mutex_lock(&priv->lock);
	if (--priv->refcnt == 0) {
		/* Disable inbox & outbox interrupt */
		writel(SPRD_INBOX_FIFO_IRQ_MASK, priv->inbox_base + SPRD_MBOX_IRQ_MSK);
		writel(SPRD_OUTBOX_FIFO_IRQ_MASK, priv->outbox_base + SPRD_MBOX_IRQ_MSK);

		if (priv->supp_base)
			writel(SPRD_OUTBOX_FIFO_IRQ_MASK,
			       priv->supp_base + SPRD_MBOX_IRQ_MSK);
	}
	mutex_unlock(&priv->lock);
}

static const struct mbox_chan_ops sprd_mbox_ops = {
	.send_data	= sprd_mbox_send_data,
	.flush		= sprd_mbox_flush,
	.startup	= sprd_mbox_startup,
	.shutdown	= sprd_mbox_shutdown,
};

static void sprd_mbox_disable(void *data)
{
	struct sprd_mbox_priv *priv = data;

	clk_disable_unprepare(priv->clk);
}

static int sprd_mbox_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct sprd_mbox_priv *priv;
	int ret, inbox_irq, outbox_irq, supp_irq;
	unsigned long id, supp;

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

	priv->dev = dev;
	mutex_init(&priv->lock);

	/*
	 * Unisoc mailbox uses an inbox to send messages to the target
	 * core, and uses (an) outbox(es) to receive messages from other
	 * cores.
	 *
	 * Thus in general the mailbox controller supplies 2 different
	 * register addresses and IRQ numbers for inbox and outbox.
	 *
	 * If necessary, a supplementary inbox could be enabled optionally
	 * with an independent FIFO and an extra interrupt.
	 */
	priv->inbox_base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(priv->inbox_base))
		return PTR_ERR(priv->inbox_base);

	priv->outbox_base = devm_platform_ioremap_resource(pdev, 1);
	if (IS_ERR(priv->outbox_base))
		return PTR_ERR(priv->outbox_base);

	priv->clk = devm_clk_get(dev, "enable");
	if (IS_ERR(priv->clk)) {
		dev_err(dev, "failed to get mailbox clock\n");
		return PTR_ERR(priv->clk);
	}

	ret = clk_prepare_enable(priv->clk);
	if (ret)
		return ret;

	ret = devm_add_action_or_reset(dev, sprd_mbox_disable, priv);
	if (ret) {
		dev_err(dev, "failed to add mailbox disable action\n");
		return ret;
	}

	inbox_irq = platform_get_irq_byname(pdev, "inbox");
	if (inbox_irq < 0)
		return inbox_irq;

	ret = devm_request_irq(dev, inbox_irq, sprd_mbox_inbox_isr,
			       IRQF_NO_SUSPEND, dev_name(dev), priv);
	if (ret) {
		dev_err(dev, "failed to request inbox IRQ: %d\n", ret);
		return ret;
	}

	outbox_irq = platform_get_irq_byname(pdev, "outbox");
	if (outbox_irq < 0)
		return outbox_irq;

	ret = devm_request_irq(dev, outbox_irq, sprd_mbox_outbox_isr,
			       IRQF_NO_SUSPEND, dev_name(dev), priv);
	if (ret) {
		dev_err(dev, "failed to request outbox IRQ: %d\n", ret);
		return ret;
	}

	/* Supplementary outbox IRQ is optional */
	supp_irq = platform_get_irq_byname(pdev, "supp-outbox");
	if (supp_irq > 0) {
		ret = devm_request_irq(dev, supp_irq, sprd_mbox_supp_isr,
				       IRQF_NO_SUSPEND, dev_name(dev), priv);
		if (ret) {
			dev_err(dev, "failed to request outbox IRQ: %d\n", ret);
			return ret;
		}

		supp = (unsigned long) of_device_get_match_data(dev);
		if (!supp) {
			dev_err(dev, "no supplementary outbox specified\n");
			return -ENODEV;
		}
		priv->supp_base = priv->outbox_base + (SPRD_OUTBOX_BASE_SPAN * supp);
	}

	/* Get the default outbox FIFO depth */
	priv->outbox_fifo_depth =
		readl(priv->outbox_base + SPRD_MBOX_FIFO_DEPTH) + 1;
	priv->mbox.dev = dev;
	priv->mbox.chans = &priv->chan[0];
	priv->mbox.num_chans = SPRD_MBOX_CHAN_MAX;
	priv->mbox.ops = &sprd_mbox_ops;
	priv->mbox.txdone_irq = true;

	for (id = 0; id < SPRD_MBOX_CHAN_MAX; id++)
		priv->chan[id].con_priv = (void *)id;

	ret = devm_mbox_controller_register(dev, &priv->mbox);
	if (ret) {
		dev_err(dev, "failed to register mailbox: %d\n", ret);
		return ret;
	}

	return 0;
}

static const struct of_device_id sprd_mbox_of_match[] = {
	{ .compatible = "sprd,sc9860-mailbox" },
	{ .compatible = "sprd,sc9863a-mailbox",
	  .data = (void *)SPRD_SUPP_INBOX_ID_SC9863A },
	{ },
};
MODULE_DEVICE_TABLE(of, sprd_mbox_of_match);

static struct platform_driver sprd_mbox_driver = {
	.driver = {
		.name = "sprd-mailbox",
		.of_match_table = sprd_mbox_of_match,
	},
	.probe	= sprd_mbox_probe,
};
module_platform_driver(sprd_mbox_driver);

MODULE_AUTHOR("Baolin Wang <baolin.wang@unisoc.com>");
MODULE_DESCRIPTION("Spreadtrum mailbox driver");
MODULE_LICENSE("GPL v2");
