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

#include <common.h>
#include <log.h>
#include <malloc.h>
#include <asm/io.h>
#include <dm.h>
#include <mailbox-uclass.h>
#include <dt-bindings/mailbox/tegra186-hsp.h>

#define TEGRA_HSP_INT_DIMENSIONING		0x380
#define TEGRA_HSP_INT_DIMENSIONING_NSI_SHIFT	16
#define TEGRA_HSP_INT_DIMENSIONING_NSI_MASK	0xf
#define TEGRA_HSP_INT_DIMENSIONING_NDB_SHIFT	12
#define TEGRA_HSP_INT_DIMENSIONING_NDB_MASK	0xf
#define TEGRA_HSP_INT_DIMENSIONING_NAS_SHIFT	8
#define TEGRA_HSP_INT_DIMENSIONING_NAS_MASK	0xf
#define TEGRA_HSP_INT_DIMENSIONING_NSS_SHIFT	4
#define TEGRA_HSP_INT_DIMENSIONING_NSS_MASK	0xf
#define TEGRA_HSP_INT_DIMENSIONING_NSM_SHIFT	0
#define TEGRA_HSP_INT_DIMENSIONING_NSM_MASK	0xf

#define TEGRA_HSP_DB_REG_TRIGGER	0x0
#define TEGRA_HSP_DB_REG_ENABLE		0x4
#define TEGRA_HSP_DB_REG_RAW		0x8
#define TEGRA_HSP_DB_REG_PENDING	0xc

#define TEGRA_HSP_DB_ID_CCPLEX		1
#define TEGRA_HSP_DB_ID_BPMP		3
#define TEGRA_HSP_DB_ID_NUM		7

struct tegra_hsp {
	fdt_addr_t regs;
	uint32_t db_base;
};

static uint32_t *tegra_hsp_reg(struct tegra_hsp *thsp, uint32_t db_id,
			       uint32_t reg)
{
	return (uint32_t *)(thsp->regs + thsp->db_base + (db_id * 0x100) + reg);
}

static uint32_t tegra_hsp_readl(struct tegra_hsp *thsp, uint32_t db_id,
				uint32_t reg)
{
	uint32_t *r = tegra_hsp_reg(thsp, db_id, reg);
	return readl(r);
}

static void tegra_hsp_writel(struct tegra_hsp *thsp, uint32_t val,
			     uint32_t db_id, uint32_t reg)
{
	uint32_t *r = tegra_hsp_reg(thsp, db_id, reg);

	writel(val, r);
	readl(r);
}

static int tegra_hsp_db_id(ulong chan_id)
{
	switch (chan_id) {
	case (HSP_MBOX_TYPE_DB << 16) | HSP_DB_MASTER_BPMP:
		return TEGRA_HSP_DB_ID_BPMP;
	default:
		debug("Invalid channel ID\n");
		return -EINVAL;
	}
}

static int tegra_hsp_of_xlate(struct mbox_chan *chan,
			      struct ofnode_phandle_args *args)
{
	debug("%s(chan=%p)\n", __func__, chan);

	if (args->args_count != 2) {
		debug("Invaild args_count: %d\n", args->args_count);
		return -EINVAL;
	}

	chan->id = (args->args[0] << 16) | args->args[1];

	return 0;
}

static int tegra_hsp_request(struct mbox_chan *chan)
{
	int db_id;

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

	db_id = tegra_hsp_db_id(chan->id);
	if (db_id < 0) {
		debug("tegra_hsp_db_id() failed: %d\n", db_id);
		return -EINVAL;
	}

	return 0;
}

static int tegra_hsp_free(struct mbox_chan *chan)
{
	debug("%s(chan=%p)\n", __func__, chan);

	return 0;
}

static int tegra_hsp_send(struct mbox_chan *chan, const void *data)
{
	struct tegra_hsp *thsp = dev_get_priv(chan->dev);
	int db_id;

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

	db_id = tegra_hsp_db_id(chan->id);
	tegra_hsp_writel(thsp, 1, db_id, TEGRA_HSP_DB_REG_TRIGGER);

	return 0;
}

static int tegra_hsp_recv(struct mbox_chan *chan, void *data)
{
	struct tegra_hsp *thsp = dev_get_priv(chan->dev);
	uint32_t db_id = TEGRA_HSP_DB_ID_CCPLEX;
	uint32_t val;

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

	val = tegra_hsp_readl(thsp, db_id, TEGRA_HSP_DB_REG_RAW);
	if (!(val & BIT(chan->id)))
		return -ENODATA;

	tegra_hsp_writel(thsp, BIT(chan->id), db_id, TEGRA_HSP_DB_REG_RAW);

	return 0;
}

static int tegra_hsp_bind(struct udevice *dev)
{
	debug("%s(dev=%p)\n", __func__, dev);

	return 0;
}

static int tegra_hsp_probe(struct udevice *dev)
{
	struct tegra_hsp *thsp = dev_get_priv(dev);
	u32 val;
	int nr_sm, nr_ss, nr_as;

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

	thsp->regs = devfdt_get_addr(dev);
	if (thsp->regs == FDT_ADDR_T_NONE)
		return -ENODEV;

	val = readl(thsp->regs + TEGRA_HSP_INT_DIMENSIONING);
	nr_sm = (val >> TEGRA_HSP_INT_DIMENSIONING_NSM_SHIFT) &
		TEGRA_HSP_INT_DIMENSIONING_NSM_MASK;
	nr_ss = (val >> TEGRA_HSP_INT_DIMENSIONING_NSS_SHIFT) &
		TEGRA_HSP_INT_DIMENSIONING_NSS_MASK;
	nr_as = (val >> TEGRA_HSP_INT_DIMENSIONING_NAS_SHIFT) &
		TEGRA_HSP_INT_DIMENSIONING_NAS_MASK;

	thsp->db_base = (1 + (nr_sm >> 1) + nr_ss + nr_as) << 16;

	return 0;
}

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

struct mbox_ops tegra_hsp_mbox_ops = {
	.of_xlate = tegra_hsp_of_xlate,
	.request = tegra_hsp_request,
	.rfree = tegra_hsp_free,
	.send = tegra_hsp_send,
	.recv = tegra_hsp_recv,
};

U_BOOT_DRIVER(tegra_hsp) = {
	.name = "tegra-hsp",
	.id = UCLASS_MAILBOX,
	.of_match = tegra_hsp_ids,
	.bind = tegra_hsp_bind,
	.probe = tegra_hsp_probe,
	.priv_auto_alloc_size = sizeof(struct tegra_hsp),
	.ops = &tegra_hsp_mbox_ops,
};
