// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
 * Apple mailbox driver
 *
 * Copyright (C) 2021 The Asahi Linux Contributors
 *
 * This driver adds support for two mailbox variants (called ASC and M3 by
 * Apple) found in Apple SoCs such as the M1. It consists of two FIFOs used to
 * exchange 64+32 bit messages between the main CPU and a co-processor.
 * Various coprocessors implement different IPC protocols based on these simple
 * messages and shared memory buffers.
 *
 * Both the main CPU and the co-processor see the same set of registers but
 * the first FIFO (A2I) is always used to transfer messages from the application
 * processor (us) to the I/O processor and the second one (I2A) for the
 * other direction.
 */

#include <linux/apple-mailbox.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/gfp.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/spinlock.h>
#include <linux/types.h>

#define APPLE_ASC_MBOX_CONTROL_FULL  BIT(16)
#define APPLE_ASC_MBOX_CONTROL_EMPTY BIT(17)

#define APPLE_ASC_MBOX_A2I_CONTROL 0x110
#define APPLE_ASC_MBOX_A2I_SEND0   0x800
#define APPLE_ASC_MBOX_A2I_SEND1   0x808
#define APPLE_ASC_MBOX_A2I_RECV0   0x810
#define APPLE_ASC_MBOX_A2I_RECV1   0x818

#define APPLE_ASC_MBOX_I2A_CONTROL 0x114
#define APPLE_ASC_MBOX_I2A_SEND0   0x820
#define APPLE_ASC_MBOX_I2A_SEND1   0x828
#define APPLE_ASC_MBOX_I2A_RECV0   0x830
#define APPLE_ASC_MBOX_I2A_RECV1   0x838

#define APPLE_M3_MBOX_CONTROL_FULL  BIT(16)
#define APPLE_M3_MBOX_CONTROL_EMPTY BIT(17)

#define APPLE_M3_MBOX_A2I_CONTROL 0x50
#define APPLE_M3_MBOX_A2I_SEND0	  0x60
#define APPLE_M3_MBOX_A2I_SEND1	  0x68
#define APPLE_M3_MBOX_A2I_RECV0	  0x70
#define APPLE_M3_MBOX_A2I_RECV1	  0x78

#define APPLE_M3_MBOX_I2A_CONTROL 0x80
#define APPLE_M3_MBOX_I2A_SEND0	  0x90
#define APPLE_M3_MBOX_I2A_SEND1	  0x98
#define APPLE_M3_MBOX_I2A_RECV0	  0xa0
#define APPLE_M3_MBOX_I2A_RECV1	  0xa8

#define APPLE_M3_MBOX_IRQ_ENABLE	0x48
#define APPLE_M3_MBOX_IRQ_ACK		0x4c
#define APPLE_M3_MBOX_IRQ_A2I_EMPTY	BIT(0)
#define APPLE_M3_MBOX_IRQ_A2I_NOT_EMPTY BIT(1)
#define APPLE_M3_MBOX_IRQ_I2A_EMPTY	BIT(2)
#define APPLE_M3_MBOX_IRQ_I2A_NOT_EMPTY BIT(3)

#define APPLE_MBOX_MSG1_OUTCNT GENMASK(56, 52)
#define APPLE_MBOX_MSG1_INCNT  GENMASK(51, 48)
#define APPLE_MBOX_MSG1_OUTPTR GENMASK(47, 44)
#define APPLE_MBOX_MSG1_INPTR  GENMASK(43, 40)
#define APPLE_MBOX_MSG1_MSG    GENMASK(31, 0)

struct apple_mbox_hw {
	unsigned int control_full;
	unsigned int control_empty;

	unsigned int a2i_control;
	unsigned int a2i_send0;
	unsigned int a2i_send1;

	unsigned int i2a_control;
	unsigned int i2a_recv0;
	unsigned int i2a_recv1;

	bool has_irq_controls;
	unsigned int irq_enable;
	unsigned int irq_ack;
	unsigned int irq_bit_recv_not_empty;
	unsigned int irq_bit_send_empty;
};

struct apple_mbox {
	void __iomem *regs;
	const struct apple_mbox_hw *hw;

	int irq_recv_not_empty;
	int irq_send_empty;

	struct mbox_chan chan;

	struct device *dev;
	struct mbox_controller controller;
	spinlock_t rx_lock;
};

static const struct of_device_id apple_mbox_of_match[];

static bool apple_mbox_hw_can_send(struct apple_mbox *apple_mbox)
{
	u32 mbox_ctrl =
		readl_relaxed(apple_mbox->regs + apple_mbox->hw->a2i_control);

	return !(mbox_ctrl & apple_mbox->hw->control_full);
}

static bool apple_mbox_hw_send_empty(struct apple_mbox *apple_mbox)
{
	u32 mbox_ctrl =
		readl_relaxed(apple_mbox->regs + apple_mbox->hw->a2i_control);

	return mbox_ctrl & apple_mbox->hw->control_empty;
}

static int apple_mbox_hw_send(struct apple_mbox *apple_mbox,
			      struct apple_mbox_msg *msg)
{
	if (!apple_mbox_hw_can_send(apple_mbox))
		return -EBUSY;

	dev_dbg(apple_mbox->dev, "> TX %016llx %08x\n", msg->msg0, msg->msg1);

	writeq_relaxed(msg->msg0, apple_mbox->regs + apple_mbox->hw->a2i_send0);
	writeq_relaxed(FIELD_PREP(APPLE_MBOX_MSG1_MSG, msg->msg1),
		       apple_mbox->regs + apple_mbox->hw->a2i_send1);

	return 0;
}

static bool apple_mbox_hw_can_recv(struct apple_mbox *apple_mbox)
{
	u32 mbox_ctrl =
		readl_relaxed(apple_mbox->regs + apple_mbox->hw->i2a_control);

	return !(mbox_ctrl & apple_mbox->hw->control_empty);
}

static int apple_mbox_hw_recv(struct apple_mbox *apple_mbox,
			      struct apple_mbox_msg *msg)
{
	if (!apple_mbox_hw_can_recv(apple_mbox))
		return -ENOMSG;

	msg->msg0 = readq_relaxed(apple_mbox->regs + apple_mbox->hw->i2a_recv0);
	msg->msg1 = FIELD_GET(
		APPLE_MBOX_MSG1_MSG,
		readq_relaxed(apple_mbox->regs + apple_mbox->hw->i2a_recv1));

	dev_dbg(apple_mbox->dev, "< RX %016llx %08x\n", msg->msg0, msg->msg1);

	return 0;
}

static int apple_mbox_chan_send_data(struct mbox_chan *chan, void *data)
{
	struct apple_mbox *apple_mbox = chan->con_priv;
	struct apple_mbox_msg *msg = data;
	int ret;

	ret = apple_mbox_hw_send(apple_mbox, msg);
	if (ret)
		return ret;

	/*
	 * The interrupt is level triggered and will keep firing as long as the
	 * FIFO is empty. It will also keep firing if the FIFO was empty
	 * at any point in the past until it has been acknowledged at the
	 * mailbox level. By acknowledging it here we can ensure that we will
	 * only get the interrupt once the FIFO has been cleared again.
	 * If the FIFO is already empty before the ack it will fire again
	 * immediately after the ack.
	 */
	if (apple_mbox->hw->has_irq_controls) {
		writel_relaxed(apple_mbox->hw->irq_bit_send_empty,
			       apple_mbox->regs + apple_mbox->hw->irq_ack);
	}
	enable_irq(apple_mbox->irq_send_empty);

	return 0;
}

static irqreturn_t apple_mbox_send_empty_irq(int irq, void *data)
{
	struct apple_mbox *apple_mbox = data;

	/*
	 * We don't need to acknowledge the interrupt at the mailbox level
	 * here even if supported by the hardware. It will keep firing but that
	 * doesn't matter since it's disabled at the main interrupt controller.
	 * apple_mbox_chan_send_data will acknowledge it before enabling
	 * it at the main controller again.
	 */
	disable_irq_nosync(apple_mbox->irq_send_empty);
	mbox_chan_txdone(&apple_mbox->chan, 0);
	return IRQ_HANDLED;
}

static int apple_mbox_poll(struct apple_mbox *apple_mbox)
{
	struct apple_mbox_msg msg;
	int ret = 0;

	while (apple_mbox_hw_recv(apple_mbox, &msg) == 0) {
		mbox_chan_received_data(&apple_mbox->chan, (void *)&msg);
		ret++;
	}

	/*
	 * The interrupt will keep firing even if there are no more messages
	 * unless we also acknowledge it at the mailbox level here.
	 * There's no race if a message comes in between the check in the while
	 * loop above and the ack below: If a new messages arrives inbetween
	 * those two the interrupt will just fire again immediately after the
	 * ack since it's level triggered.
	 */
	if (apple_mbox->hw->has_irq_controls) {
		writel_relaxed(apple_mbox->hw->irq_bit_recv_not_empty,
			       apple_mbox->regs + apple_mbox->hw->irq_ack);
	}

	return ret;
}

static irqreturn_t apple_mbox_recv_irq(int irq, void *data)
{
	struct apple_mbox *apple_mbox = data;

	spin_lock(&apple_mbox->rx_lock);
	apple_mbox_poll(apple_mbox);
	spin_unlock(&apple_mbox->rx_lock);

	return IRQ_HANDLED;
}

static bool apple_mbox_chan_peek_data(struct mbox_chan *chan)
{
	struct apple_mbox *apple_mbox = chan->con_priv;
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&apple_mbox->rx_lock, flags);
	ret = apple_mbox_poll(apple_mbox);
	spin_unlock_irqrestore(&apple_mbox->rx_lock, flags);

	return ret > 0;
}

static int apple_mbox_chan_flush(struct mbox_chan *chan, unsigned long timeout)
{
	struct apple_mbox *apple_mbox = chan->con_priv;
	unsigned long deadline = jiffies + msecs_to_jiffies(timeout);

	while (time_before(jiffies, deadline)) {
		if (apple_mbox_hw_send_empty(apple_mbox)) {
			mbox_chan_txdone(&apple_mbox->chan, 0);
			return 0;
		}

		udelay(1);
	}

	return -ETIME;
}

static int apple_mbox_chan_startup(struct mbox_chan *chan)
{
	struct apple_mbox *apple_mbox = chan->con_priv;

	/*
	 * Only some variants of this mailbox HW provide interrupt control
	 * at the mailbox level. We therefore need to handle enabling/disabling
	 * interrupts at the main interrupt controller anyway for hardware that
	 * doesn't. Just always keep the interrupts we care about enabled at
	 * the mailbox level so that both hardware revisions behave almost
	 * the same.
	 */
	if (apple_mbox->hw->has_irq_controls) {
		writel_relaxed(apple_mbox->hw->irq_bit_recv_not_empty |
				       apple_mbox->hw->irq_bit_send_empty,
			       apple_mbox->regs + apple_mbox->hw->irq_enable);
	}

	enable_irq(apple_mbox->irq_recv_not_empty);
	return 0;
}

static void apple_mbox_chan_shutdown(struct mbox_chan *chan)
{
	struct apple_mbox *apple_mbox = chan->con_priv;

	disable_irq(apple_mbox->irq_recv_not_empty);
}

static const struct mbox_chan_ops apple_mbox_ops = {
	.send_data = apple_mbox_chan_send_data,
	.peek_data = apple_mbox_chan_peek_data,
	.flush = apple_mbox_chan_flush,
	.startup = apple_mbox_chan_startup,
	.shutdown = apple_mbox_chan_shutdown,
};

static struct mbox_chan *apple_mbox_of_xlate(struct mbox_controller *mbox,
					     const struct of_phandle_args *args)
{
	if (args->args_count != 0)
		return ERR_PTR(-EINVAL);

	return &mbox->chans[0];
}

static int apple_mbox_probe(struct platform_device *pdev)
{
	int ret;
	const struct of_device_id *match;
	char *irqname;
	struct apple_mbox *mbox;
	struct device *dev = &pdev->dev;

	match = of_match_node(apple_mbox_of_match, pdev->dev.of_node);
	if (!match)
		return -EINVAL;
	if (!match->data)
		return -EINVAL;

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

	mbox->dev = dev;
	mbox->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(mbox->regs))
		return PTR_ERR(mbox->regs);

	mbox->hw = match->data;
	mbox->irq_recv_not_empty =
		platform_get_irq_byname(pdev, "recv-not-empty");
	if (mbox->irq_recv_not_empty < 0)
		return -ENODEV;

	mbox->irq_send_empty = platform_get_irq_byname(pdev, "send-empty");
	if (mbox->irq_send_empty < 0)
		return -ENODEV;

	mbox->controller.dev = mbox->dev;
	mbox->controller.num_chans = 1;
	mbox->controller.chans = &mbox->chan;
	mbox->controller.ops = &apple_mbox_ops;
	mbox->controller.txdone_irq = true;
	mbox->controller.of_xlate = apple_mbox_of_xlate;
	mbox->chan.con_priv = mbox;
	spin_lock_init(&mbox->rx_lock);

	irqname = devm_kasprintf(dev, GFP_KERNEL, "%s-recv", dev_name(dev));
	if (!irqname)
		return -ENOMEM;

	ret = devm_request_threaded_irq(dev, mbox->irq_recv_not_empty, NULL,
					apple_mbox_recv_irq,
					IRQF_NO_AUTOEN | IRQF_ONESHOT, irqname,
					mbox);
	if (ret)
		return ret;

	irqname = devm_kasprintf(dev, GFP_KERNEL, "%s-send", dev_name(dev));
	if (!irqname)
		return -ENOMEM;

	ret = devm_request_irq(dev, mbox->irq_send_empty,
			       apple_mbox_send_empty_irq, IRQF_NO_AUTOEN,
			       irqname, mbox);
	if (ret)
		return ret;

	return devm_mbox_controller_register(dev, &mbox->controller);
}

static const struct apple_mbox_hw apple_mbox_asc_hw = {
	.control_full = APPLE_ASC_MBOX_CONTROL_FULL,
	.control_empty = APPLE_ASC_MBOX_CONTROL_EMPTY,

	.a2i_control = APPLE_ASC_MBOX_A2I_CONTROL,
	.a2i_send0 = APPLE_ASC_MBOX_A2I_SEND0,
	.a2i_send1 = APPLE_ASC_MBOX_A2I_SEND1,

	.i2a_control = APPLE_ASC_MBOX_I2A_CONTROL,
	.i2a_recv0 = APPLE_ASC_MBOX_I2A_RECV0,
	.i2a_recv1 = APPLE_ASC_MBOX_I2A_RECV1,

	.has_irq_controls = false,
};

static const struct apple_mbox_hw apple_mbox_m3_hw = {
	.control_full = APPLE_M3_MBOX_CONTROL_FULL,
	.control_empty = APPLE_M3_MBOX_CONTROL_EMPTY,

	.a2i_control = APPLE_M3_MBOX_A2I_CONTROL,
	.a2i_send0 = APPLE_M3_MBOX_A2I_SEND0,
	.a2i_send1 = APPLE_M3_MBOX_A2I_SEND1,

	.i2a_control = APPLE_M3_MBOX_I2A_CONTROL,
	.i2a_recv0 = APPLE_M3_MBOX_I2A_RECV0,
	.i2a_recv1 = APPLE_M3_MBOX_I2A_RECV1,

	.has_irq_controls = true,
	.irq_enable = APPLE_M3_MBOX_IRQ_ENABLE,
	.irq_ack = APPLE_M3_MBOX_IRQ_ACK,
	.irq_bit_recv_not_empty = APPLE_M3_MBOX_IRQ_I2A_NOT_EMPTY,
	.irq_bit_send_empty = APPLE_M3_MBOX_IRQ_A2I_EMPTY,
};

static const struct of_device_id apple_mbox_of_match[] = {
	{ .compatible = "apple,asc-mailbox-v4", .data = &apple_mbox_asc_hw },
	{ .compatible = "apple,m3-mailbox-v2", .data = &apple_mbox_m3_hw },
	{}
};
MODULE_DEVICE_TABLE(of, apple_mbox_of_match);

static struct platform_driver apple_mbox_driver = {
	.driver = {
		.name = "apple-mailbox",
		.of_match_table = apple_mbox_of_match,
	},
	.probe = apple_mbox_probe,
};
module_platform_driver(apple_mbox_driver);

MODULE_LICENSE("Dual MIT/GPL");
MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>");
MODULE_DESCRIPTION("Apple Mailbox driver");
