/* SPDX-License-Identifier: GPL-2.0 */

/*
 * Message Handling Unit version 2 controller driver
 * Copyright (C) 2019-2020 ARM Ltd.
 *
 * Based on drivers/mailbox/arm_mhu.c
 *
 */

#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/amba/bus.h>
#include <linux/mailbox_controller.h>
#include <linux/of_device.h>
#include <linux/of_address.h>

#define MHU_V2_REG_STAT_OFS             0x0
#define MHU_V2_REG_CLR_OFS              0x8
#define MHU_V2_REG_SET_OFS              0xC
#define MHU_V2_REG_MSG_NO_CAP_OFS       0xF80
#define MHU_V2_REG_ACC_REQ_OFS          0xF88
#define MHU_V2_REG_ACC_RDY_OFS          0xF8C
#define MHU_V2_INT_EN_OFS               0xF98
#define MHU_V2_AIDR_OFS                 0xFCC

#define MHU_V2_CHCOMB                   BIT(2)
#define MHU_V2_AIDR_MINOR(_reg)         ((_reg) & 0xF)

#define MHU_V2_EACH_CHANNEL_SIZE        0x20

#define mbox_to_arm_mhuv2(c) container_of(c, struct arm_mhuv2, mbox)

struct mhuv2_link {
	unsigned int irq;
	void __iomem *tx_reg;
	void __iomem *rx_reg;
};

struct arm_mhuv2 {
	void __iomem           *base;
	struct mhuv2_link      *mlink;
	struct mbox_chan       *chan;
	struct mbox_controller mbox;
};

static irqreturn_t mhuv2_rx_interrupt(int irq,
				      void *p)
{
	struct mbox_chan *chan = p;
	struct mhuv2_link *mlink = chan->con_priv;
	u32 val;

	val = readl_relaxed(mlink->rx_reg + MHU_V2_REG_STAT_OFS);
	if (!val)
		return IRQ_NONE;

	mbox_chan_received_data(chan, (void *)&val);

	writel_relaxed(val, mlink->rx_reg + MHU_V2_REG_CLR_OFS);

	return IRQ_HANDLED;
}

static bool mhuv2_last_tx_done(struct mbox_chan *chan)
{
	struct mhuv2_link *mlink = chan->con_priv;
	u32 val = readl_relaxed(mlink->tx_reg + MHU_V2_REG_STAT_OFS);

	return (val == 0);
}

static int mhuv2_send_data(struct mbox_chan *chan,
			   void *data)
{
	struct mhuv2_link *mlink = chan->con_priv;
	struct arm_mhuv2 *mhuv2 = mbox_to_arm_mhuv2(chan->mbox);
	u32 *arg = data;
	u32 tmo = 100000;

	/* If ACCESS_REQUEST is low, we have to wait for the other side
	 * to relase ACCESS_READY before continuing. */
	if (!readl_relaxed(mhuv2->base + MHU_V2_REG_ACC_REQ_OFS)) {
		while (readl_relaxed(mhuv2->base + MHU_V2_REG_ACC_RDY_OFS) &&
		       --tmo != 0)
			continue;

		if (!tmo)
			goto err;

		/* Request access and wait for other side to ack */
		writel_relaxed(0x1, mhuv2->base + MHU_V2_REG_ACC_REQ_OFS);
		tmo = 100000;
		while (!readl_relaxed(mhuv2->base + MHU_V2_REG_ACC_RDY_OFS) &&
		       --tmo != 0)
			continue;

		if (!tmo)
			goto err;
	} else {
		while (!readl_relaxed(mhuv2->base + MHU_V2_REG_ACC_RDY_OFS) &&
		       --tmo != 0)
			continue;

		if (!tmo)
			goto err;
	}

	writel_relaxed(*arg, mlink->tx_reg + MHU_V2_REG_SET_OFS);

	return 0;

err:
	dev_err(chan->mbox->dev, "Failed to acquire access to mhu.\n");

	return 1;
}

static int mhuv2_startup(struct mbox_chan *chan)
{
	struct mhuv2_link *mlink = chan->con_priv;
	u32 val;
	int ret;
	struct arm_mhuv2 *mhuv2 = mbox_to_arm_mhuv2(chan->mbox);

	writel_relaxed(0x1, mhuv2->base + MHU_V2_REG_ACC_REQ_OFS);

	val = readl_relaxed(mlink->tx_reg + MHU_V2_REG_STAT_OFS);
	writel_relaxed(val, mlink->tx_reg + MHU_V2_REG_CLR_OFS);

	ret = request_irq(mlink->irq, mhuv2_rx_interrupt,
			  IRQF_SHARED, "mhuv2_link", chan);
	if (ret) {
		dev_err(chan->mbox->dev,
			"unable to acquire IRQ %d\n", mlink->irq);

		return ret;
	}

	return 0;
}

static void mhuv2_shutdown(struct mbox_chan *chan)
{
	struct mhuv2_link *mlink = chan->con_priv;
	struct arm_mhuv2 *mhuv2 = mbox_to_arm_mhuv2(chan->mbox);

	writel_relaxed(0x0, mhuv2->base + MHU_V2_REG_ACC_REQ_OFS);

	free_irq(mlink->irq, chan);
}

static const struct mbox_chan_ops mhuv2_ops = {
	.send_data    = mhuv2_send_data,
	.startup      = mhuv2_startup,
	.shutdown     = mhuv2_shutdown,
	.last_tx_done = mhuv2_last_tx_done,
};

void mhuv2_check_enable_cmbint(struct mhuv2_link *link)
{
	const u32 aidr = readl_relaxed(link->rx_reg + MHU_V2_AIDR_OFS);

	if (MHU_V2_AIDR_MINOR(aidr) == 1)
		/* Enable combined receiver interrupt for MHUv2.1 */
		writel_relaxed(MHU_V2_CHCOMB, link->rx_reg + MHU_V2_INT_EN_OFS);
}

static int mhuv2_probe(struct amba_device *adev,
		       const struct amba_id *id)
{
	int i, err;
	struct arm_mhuv2 *mhuv2;
	struct device *dev = &adev->dev;
	void __iomem *rx_base, *tx_base;
	const struct device_node *np = dev->of_node;
	unsigned int pchans;
	struct mhuv2_link *mlink;
	struct mbox_chan *chan;

	/* Allocate memory for device */
	mhuv2 = devm_kzalloc(dev, sizeof(*mhuv2), GFP_KERNEL);
	if (!mhuv2)
		return -ENOMEM;

	tx_base = of_iomap((struct device_node *)np, 0);
	if (!tx_base) {
		dev_err(dev, "failed to map tx registers\n");
		return -ENOMEM;
	}

	rx_base = of_iomap((struct device_node *)np, 1);
	if (!rx_base) {
		dev_err(dev, "failed to map rx registers\n");
		iounmap(tx_base);
		return -ENOMEM;
	}

	pchans = readl_relaxed(tx_base + MHU_V2_REG_MSG_NO_CAP_OFS);
	if (pchans == 0 || pchans % 2) {
		dev_err(dev, "invalid number of channels %d\n", pchans);
		iounmap(rx_base);
		iounmap(tx_base);

		return -EINVAL;
	}

	mhuv2->mlink = devm_kcalloc(dev, pchans, sizeof(*mlink), GFP_KERNEL);
	if (!mhuv2->mlink) {
		iounmap(rx_base);
		iounmap(tx_base);

		return -ENOMEM;
	}

	mhuv2->chan = devm_kcalloc(dev, pchans, sizeof(*chan), GFP_KERNEL);
	if (!mhuv2->chan) {
		iounmap(rx_base);
		iounmap(tx_base);
		kfree(mhuv2->mlink);

		return -ENOMEM;
	}

	for (i = 0; i < pchans; i++) {
		mlink = mhuv2->mlink + i;
		chan = mhuv2->chan + i;
		chan->con_priv = mlink;
		mlink->rx_reg = rx_base + (i * MHU_V2_EACH_CHANNEL_SIZE);
		mlink->tx_reg = tx_base + (i * MHU_V2_EACH_CHANNEL_SIZE);
	}

	mhuv2->mlink->irq = adev->irq[0];
	mhuv2_check_enable_cmbint(mhuv2->mlink);

	mhuv2->base = tx_base;
	mhuv2->mbox.dev = dev;
	mhuv2->mbox.chans = mhuv2->chan;
	mhuv2->mbox.num_chans = pchans;
	mhuv2->mbox.ops = &mhuv2_ops;
	mhuv2->mbox.txdone_irq = false;
	mhuv2->mbox.txdone_poll = true;
	mhuv2->mbox.txpoll_period = 1;

	amba_set_drvdata(adev, mhuv2);

	err = mbox_controller_register(&mhuv2->mbox);
	if (err) {
		dev_err(dev, "failed to register mailboxes %d\n", err);
		iounmap(rx_base);
		iounmap(tx_base);
		kfree(mhuv2->mlink);
		kfree(mhuv2->chan);

		return err;
	}

	dev_info(dev, "ARM MHUv2 Mailbox driver registered\n");

	return 0;
}

static int mhuv2_remove(struct amba_device *adev)
{
	struct arm_mhuv2 *mhuv2 = amba_get_drvdata(adev);

	mbox_controller_unregister(&mhuv2->mbox);

	return 0;
}

static struct amba_id mhuv2_ids[] = {
	{
		.id = 0x4b0d1,
		.mask = 0xfffff,
	},
	{
		.id = 0xbb0d1,
		.mask = 0xfffff,
	},
	{
		.id = 0xbb076,
		.mask = 0xfffff,
	},
	{ 0, 0 },
};
MODULE_DEVICE_TABLE(amba, mhuv2_ids);

static struct amba_driver arm_mhuv2_driver = {
	.drv          = {
		.name = "mhuv2",
	},
	.id_table     = mhuv2_ids,
	.probe        = mhuv2_probe,
	.remove       = mhuv2_remove,
};
module_amba_driver(arm_mhuv2_driver);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("ARM MHUv2 Driver");
MODULE_AUTHOR("Samarth Parikh <samarthp@ymail.com>");
