/*
 * SPDX-FileCopyrightText: Copyright 2019-2021, 2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
 * SPDX-License-Identifier: GPL-2.0
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 * Message Handling Unit version 2 controller driver
 * 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>
#include <linux/version.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,
};

static 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;
}

#if KERNEL_VERSION(5, 12, 0) <= LINUX_VERSION_CODE
static void mhuv2_remove(struct amba_device *adev)
{
	struct arm_mhuv2 *mhuv2 = amba_get_drvdata(adev);

	mbox_controller_unregister(&mhuv2->mbox);
}

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

	mbox_controller_unregister(&mhuv2->mbox);

	return 0;
}

#endif

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>");
