/*
 * Copyright (c) 2016, NVIDIA CORPORATION.
 *
 * SPDX-License-Identifier: GPL-2.0
 */

#include <common.h>
#include <dm.h>
#include <dm/lists.h>
#include <dm/root.h>
#include <mailbox.h>
#include <misc.h>
#include <asm/arch-tegra/bpmp_abi.h>
#include <asm/arch-tegra/ivc.h>

#define BPMP_IVC_FRAME_COUNT 1
#define BPMP_IVC_FRAME_SIZE 128

#define BPMP_FLAG_DO_ACK	BIT(0)
#define BPMP_FLAG_RING_DOORBELL	BIT(1)

DECLARE_GLOBAL_DATA_PTR;

struct tegra186_bpmp {
	struct mbox_chan mbox;
	struct tegra_ivc ivc;
};

static int tegra186_bpmp_call(struct udevice *dev, int mrq, void *tx_msg,
			      int tx_size, void *rx_msg, int rx_size)
{
	struct tegra186_bpmp *priv = dev_get_priv(dev);
	int ret, err;
	void *ivc_frame;
	struct mrq_request *req;
	struct mrq_response *resp;
	ulong start_time;

	debug("%s(dev=%p, mrq=%u, tx_msg=%p, tx_size=%d, rx_msg=%p, rx_size=%d) (priv=%p)\n",
	      __func__, dev, mrq, tx_msg, tx_size, rx_msg, rx_size, priv);

	if ((tx_size > BPMP_IVC_FRAME_SIZE) || (rx_size > BPMP_IVC_FRAME_SIZE))
		return -EINVAL;

	ret = tegra_ivc_write_get_next_frame(&priv->ivc, &ivc_frame);
	if (ret) {
		error("tegra_ivc_write_get_next_frame() failed: %d\n", ret);
		return ret;
	}

	req = ivc_frame;
	req->mrq = mrq;
	req->flags = BPMP_FLAG_DO_ACK | BPMP_FLAG_RING_DOORBELL;
	memcpy(req + 1, tx_msg, tx_size);

	ret = tegra_ivc_write_advance(&priv->ivc);
	if (ret) {
		error("tegra_ivc_write_advance() failed: %d\n", ret);
		return ret;
	}

	start_time = timer_get_us();
	for (;;) {
		ret = tegra_ivc_channel_notified(&priv->ivc);
		if (ret) {
			error("tegra_ivc_channel_notified() failed: %d\n", ret);
			return ret;
		}

		ret = tegra_ivc_read_get_next_frame(&priv->ivc, &ivc_frame);
		if (!ret)
			break;

		/* Timeout 20ms; roughly 10x current max observed duration */
		if ((timer_get_us() - start_time) > 20 * 1000) {
			error("tegra_ivc_read_get_next_frame() timed out (%d)\n",
			      ret);
			return -ETIMEDOUT;
		}
	}

	resp = ivc_frame;
	err = resp->err;
	if (!err && rx_msg && rx_size)
		memcpy(rx_msg, resp + 1, rx_size);

	ret = tegra_ivc_read_advance(&priv->ivc);
	if (ret) {
		error("tegra_ivc_write_advance() failed: %d\n", ret);
		return ret;
	}

	if (err) {
		error("BPMP responded with error %d\n", err);
		/* err isn't a U-Boot error code, so don't that */
		return -EIO;
	}

	return rx_size;
}

/**
 * The BPMP exposes multiple different services. We create a sub-device for
 * each separate type of service, since each device must be of the appropriate
 * UCLASS.
 */
static int tegra186_bpmp_bind(struct udevice *dev)
{
	int ret;
	struct udevice *child;

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

	ret = device_bind_driver_to_node(dev, "tegra186_clk", "tegra186_clk",
					 dev->of_offset, &child);
	if (ret)
		return ret;

	ret = device_bind_driver_to_node(dev, "tegra186_reset",
					 "tegra186_reset", dev->of_offset,
					 &child);
	if (ret)
		return ret;

	ret = device_bind_driver_to_node(dev, "tegra186_power_domain",
					 "tegra186_power_domain",
					 dev->of_offset, &child);
	if (ret)
		return ret;

	ret = dm_scan_fdt_dev(dev);
	if (ret)
		return ret;

	return 0;
}

static ulong tegra186_bpmp_get_shmem(struct udevice *dev, int index)
{
	int ret;
	struct fdtdec_phandle_args args;
	fdt_addr_t reg;

	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
					      "shmem", NULL, 0, index, &args);
	if (ret < 0) {
		error("fdtdec_parse_phandle_with_args() failed: %d\n", ret);
		return ret;
	}

	reg = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, args.node,
						 "reg", 0, NULL, true);
	if (reg == FDT_ADDR_T_NONE) {
		error("fdtdec_get_addr_size_auto_noparent() failed\n");
		return -ENODEV;
	}

	return reg;
}

static void tegra186_bpmp_ivc_notify(struct tegra_ivc *ivc)
{
	struct tegra186_bpmp *priv =
		container_of(ivc, struct tegra186_bpmp, ivc);
	int ret;

	ret = mbox_send(&priv->mbox, NULL);
	if (ret)
		error("mbox_send() failed: %d\n", ret);
}

static int tegra186_bpmp_probe(struct udevice *dev)
{
	struct tegra186_bpmp *priv = dev_get_priv(dev);
	int ret;
	ulong tx_base, rx_base, start_time;

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

	ret = mbox_get_by_index(dev, 0, &priv->mbox);
	if (ret) {
		error("mbox_get_by_index() failed: %d\n", ret);
		return ret;
	}

	tx_base = tegra186_bpmp_get_shmem(dev, 0);
	if (IS_ERR_VALUE(tx_base)) {
		error("tegra186_bpmp_get_shmem failed for tx_base\n");
		return tx_base;
	}
	rx_base = tegra186_bpmp_get_shmem(dev, 1);
	if (IS_ERR_VALUE(rx_base)) {
		error("tegra186_bpmp_get_shmem failed for rx_base\n");
		return rx_base;
	}
	debug("shmem: rx=%lx, tx=%lx\n", rx_base, tx_base);

	ret = tegra_ivc_init(&priv->ivc, rx_base, tx_base, BPMP_IVC_FRAME_COUNT,
			     BPMP_IVC_FRAME_SIZE, tegra186_bpmp_ivc_notify);
	if (ret) {
		error("tegra_ivc_init() failed: %d\n", ret);
		return ret;
	}

	tegra_ivc_channel_reset(&priv->ivc);
	start_time = timer_get_us();
	for (;;) {
		ret = tegra_ivc_channel_notified(&priv->ivc);
		if (!ret)
			break;

		/* Timeout 100ms */
		if ((timer_get_us() - start_time) > 100 * 1000) {
			error("Initial IVC reset timed out (%d)\n", ret);
			ret = -ETIMEDOUT;
			goto err_free_mbox;
		}
	}

	return 0;

err_free_mbox:
	mbox_free(&priv->mbox);

	return ret;
}

static int tegra186_bpmp_remove(struct udevice *dev)
{
	struct tegra186_bpmp *priv = dev_get_priv(dev);

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

	mbox_free(&priv->mbox);

	return 0;
}

static struct misc_ops tegra186_bpmp_ops = {
	.call = tegra186_bpmp_call,
};

static const struct udevice_id tegra186_bpmp_ids[] = {
	{ .compatible = "nvidia,tegra186-bpmp" },
	{ }
};

U_BOOT_DRIVER(tegra186_bpmp) = {
	.name		= "tegra186_bpmp",
	.id		= UCLASS_MISC,
	.of_match	= tegra186_bpmp_ids,
	.bind		= tegra186_bpmp_bind,
	.probe		= tegra186_bpmp_probe,
	.remove		= tegra186_bpmp_remove,
	.ops		= &tegra186_bpmp_ops,
	.priv_auto_alloc_size = sizeof(struct tegra186_bpmp),
};
