// SPDX-License-Identifier: GPL-2.0+
/*
 * Xilinx Zynq MPSoC Mailbox driver
 *
 * Copyright (C) 2018-2019 Xilinx, Inc.
 */

#include <common.h>
#include <log.h>
#include <asm/io.h>
#include <dm.h>
#include <mailbox-uclass.h>
#include <dm/device_compat.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <wait_bit.h>
#include <zynqmp_firmware.h>

/* IPI bitmasks, register base */
/* TODO: move reg base to DT */
#define IPI_BIT_MASK_PMU0     0x10000
#define IPI_INT_REG_BASE_APU  0xFF300000

struct ipi_int_regs {
	u32 trig; /* 0x0  */
	u32 obs;  /* 0x4  */
	u32 dummy0;
	u32 dummy1;
	u32 isr;  /* 0x10  */
	u32 imr;  /* 0x14  */
	u32 ier;  /* 0x18 */
	u32 idr;  /* 0x1C */
};

#define ipi_int_apu ((struct ipi_int_regs *)IPI_INT_REG_BASE_APU)

struct zynqmp_ipi {
	void __iomem *local_req_regs;
	void __iomem *local_res_regs;
	void __iomem *remote_req_regs;
	void __iomem *remote_res_regs;
};

static int zynqmp_ipi_send(struct mbox_chan *chan, const void *data)
{
	const struct zynqmp_ipi_msg *msg = (struct zynqmp_ipi_msg *)data;
	struct zynqmp_ipi *zynqmp = dev_get_priv(chan->dev);
	u32 ret;
	u32 *mbx = (u32 *)zynqmp->local_req_regs;

	for (size_t i = 0; i < msg->len; i++)
		writel(msg->buf[i], &mbx[i]);

	/* Write trigger interrupt */
	writel(IPI_BIT_MASK_PMU0, &ipi_int_apu->trig);

	/* Wait until observation bit is cleared */
	ret = wait_for_bit_le32(&ipi_int_apu->obs, IPI_BIT_MASK_PMU0, false,
				1000, false);

	debug("%s, send %ld bytes\n", __func__, msg->len);
	return ret;
};

static int zynqmp_ipi_recv(struct mbox_chan *chan, void *data)
{
	struct zynqmp_ipi_msg *msg = (struct zynqmp_ipi_msg *)data;
	struct zynqmp_ipi *zynqmp = dev_get_priv(chan->dev);
	u32 *mbx = (u32 *)zynqmp->local_res_regs;

	/*
	 * PMU Firmware does not trigger IPI interrupt for API call responses so
	 * there is no need to check ISR flags
	 */
	for (size_t i = 0; i < msg->len; i++)
		msg->buf[i] = readl(&mbx[i]);

	debug("%s, recv %ld bytes\n", __func__, msg->len);
	return 0;
};

static int zynqmp_ipi_probe(struct udevice *dev)
{
	struct zynqmp_ipi *zynqmp = dev_get_priv(dev);
	struct resource res;
	ofnode node;

	debug("%s(dev=%p)\n", __func__, dev);

	/* Get subnode where the regs are defined */
	/* Note IPI mailbox node needs to be the first one in DT */
	node = ofnode_first_subnode(dev_ofnode(dev));

	if (ofnode_read_resource_byname(node, "local_request_region", &res)) {
		dev_err(dev, "No reg property for local_request_region\n");
		return -EINVAL;
	};
	zynqmp->local_req_regs = devm_ioremap(dev, res.start,
					      (res.start - res.end));

	if (ofnode_read_resource_byname(node, "local_response_region", &res)) {
		dev_err(dev, "No reg property for local_response_region\n");
		return -EINVAL;
	};
	zynqmp->local_res_regs = devm_ioremap(dev, res.start,
					      (res.start - res.end));

	if (ofnode_read_resource_byname(node, "remote_request_region", &res)) {
		dev_err(dev, "No reg property for remote_request_region\n");
		return -EINVAL;
	};
	zynqmp->remote_req_regs = devm_ioremap(dev, res.start,
					       (res.start - res.end));

	if (ofnode_read_resource_byname(node, "remote_response_region", &res)) {
		dev_err(dev, "No reg property for remote_response_region\n");
		return -EINVAL;
	};
	zynqmp->remote_res_regs = devm_ioremap(dev, res.start,
					       (res.start - res.end));

	return 0;
};

static const struct udevice_id zynqmp_ipi_ids[] = {
	{ .compatible = "xlnx,zynqmp-ipi-mailbox" },
	{ }
};

struct mbox_ops zynqmp_ipi_mbox_ops = {
	.send = zynqmp_ipi_send,
	.recv = zynqmp_ipi_recv,
};

U_BOOT_DRIVER(zynqmp_ipi) = {
	.name = "zynqmp_ipi",
	.id = UCLASS_MAILBOX,
	.of_match = zynqmp_ipi_ids,
	.probe = zynqmp_ipi_probe,
	.priv_auto	= sizeof(struct zynqmp_ipi),
	.ops = &zynqmp_ipi_mbox_ops,
};
