// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2018 NXP
 *
 * Peng Fan <peng.fan@nxp.com>
 */

#include <log.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <dm.h>
#include <dm/lists.h>
#include <dm/root.h>
#include <dm/device-internal.h>
#include <firmware/imx/sci/sci.h>
#include <linux/bitops.h>
#include <linux/iopoll.h>
#include <misc.h>

DECLARE_GLOBAL_DATA_PTR;

struct mu_type {
	u32 tr[4];
	u32 rr[4];
	u32 sr;
	u32 cr;
};

struct imx8_scu {
	struct mu_type *base;
};

#define MU_CR_GIE_MASK		0xF0000000u
#define MU_CR_RIE_MASK		0xF000000u
#define MU_CR_GIR_MASK		0xF0000u
#define MU_CR_TIE_MASK		0xF00000u
#define MU_CR_F_MASK		0x7u
#define MU_SR_TE0_MASK		BIT(23)
#define MU_SR_RF0_MASK		BIT(27)
#define MU_TR_COUNT		4
#define MU_RR_COUNT		4

static inline void mu_hal_init(struct mu_type *base)
{
	/* Clear GIEn, RIEn, TIEn, GIRn and ABFn. */
	clrbits_le32(&base->cr, MU_CR_GIE_MASK | MU_CR_RIE_MASK |
		     MU_CR_TIE_MASK | MU_CR_GIR_MASK | MU_CR_F_MASK);
}

static int mu_hal_sendmsg(struct mu_type *base, u32 reg_index, u32 msg)
{
	u32 mask = MU_SR_TE0_MASK >> reg_index;
	u32 val;
	int ret;

	assert(reg_index < MU_TR_COUNT);

	/* Wait TX register to be empty. */
	ret = readl_poll_timeout(&base->sr, val, val & mask, 10000);
	if (ret < 0) {
		printf("%s timeout\n", __func__);
		return -ETIMEDOUT;
	}

	writel(msg, &base->tr[reg_index]);

	return 0;
}

static int mu_hal_receivemsg(struct mu_type *base, u32 reg_index, u32 *msg)
{
	u32 mask = MU_SR_RF0_MASK >> reg_index;
	u32 val;
	int ret;

	assert(reg_index < MU_TR_COUNT);

	/* Wait RX register to be full. */
	ret = readl_poll_timeout(&base->sr, val, val & mask, 1000000);
	if (ret < 0) {
		printf("%s timeout\n", __func__);
		return -ETIMEDOUT;
	}

	*msg = readl(&base->rr[reg_index]);

	return 0;
}

static int sc_ipc_read(struct mu_type *base, void *data)
{
	struct sc_rpc_msg_s *msg = (struct sc_rpc_msg_s *)data;
	int ret;
	u8 count = 0;

	if (!msg)
		return -EINVAL;

	/* Read first word */
	ret = mu_hal_receivemsg(base, 0, (u32 *)msg);
	if (ret)
		return ret;
	count++;

	/* Check size */
	if (msg->size > SC_RPC_MAX_MSG) {
		*((u32 *)msg) = 0;
		return -EINVAL;
	}

	/* Read remaining words */
	while (count < msg->size) {
		ret = mu_hal_receivemsg(base, count % MU_RR_COUNT,
					&msg->DATA.u32[count - 1]);
		if (ret)
			return ret;
		count++;
	}

	return 0;
}

static int sc_ipc_write(struct mu_type *base, void *data)
{
	struct sc_rpc_msg_s *msg = (struct sc_rpc_msg_s *)data;
	int ret;
	u8 count = 0;

	if (!msg)
		return -EINVAL;

	/* Check size */
	if (msg->size > SC_RPC_MAX_MSG)
		return -EINVAL;

	/* Write first word */
	ret = mu_hal_sendmsg(base, 0, *((u32 *)msg));
	if (ret)
		return ret;
	count++;

	/* Write remaining words */
	while (count < msg->size) {
		ret = mu_hal_sendmsg(base, count % MU_TR_COUNT,
				     msg->DATA.u32[count - 1]);
		if (ret)
			return ret;
		count++;
	}

	return 0;
}

/*
 * Note the function prototype use msgid as the 2nd parameter, here
 * we take it as no_resp.
 */
static int imx8_scu_call(struct udevice *dev, int no_resp, void *tx_msg,
			 int tx_size, void *rx_msg, int rx_size)
{
	struct imx8_scu *plat = dev_get_plat(dev);
	sc_err_t result;
	int ret;

	/* Expect tx_msg, rx_msg are the same value */
	if (rx_msg && tx_msg != rx_msg)
		printf("tx_msg %p, rx_msg %p\n", tx_msg, rx_msg);

	ret = sc_ipc_write(plat->base, tx_msg);
	if (ret)
		return ret;
	if (!no_resp) {
		ret = sc_ipc_read(plat->base, rx_msg);
		if (ret)
			return ret;
	}

	result = RPC_R8((struct sc_rpc_msg_s *)tx_msg);

	return sc_err_to_linux(result);
}

static int imx8_scu_probe(struct udevice *dev)
{
	struct imx8_scu *plat = dev_get_plat(dev);
	fdt_addr_t addr;

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

	addr = dev_read_addr(dev);
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;

#ifdef CONFIG_SPL_BUILD
	plat->base = (struct mu_type *)CONFIG_MU_BASE_SPL;
#else
	plat->base = (struct mu_type *)addr;
#endif

	/* U-Boot not enable interrupts, so need to enable RX interrupts */
	mu_hal_init(plat->base);

	gd->arch.scu_dev = dev;

	return 0;
}

static int imx8_scu_remove(struct udevice *dev)
{
	return 0;
}

static int imx8_scu_bind(struct udevice *dev)
{
	int ret;
	struct udevice *child;
	ofnode node;

	debug("%s(dev=%p)\n", __func__, dev);
	ofnode_for_each_subnode(node, dev_ofnode(dev)) {
		ret = lists_bind_fdt(dev, node, &child, NULL, true);
		if (ret)
			return ret;
		debug("bind child dev %s\n", child->name);
	}

	return 0;
}

static struct misc_ops imx8_scu_ops = {
	.call = imx8_scu_call,
};

static const struct udevice_id imx8_scu_ids[] = {
	{ .compatible = "fsl,imx8qxp-mu" },
	{ .compatible = "fsl,imx8-mu" },
	{ }
};

U_BOOT_DRIVER(imx8_scu) = {
	.name		= "imx8_scu",
	.id		= UCLASS_MISC,
	.of_match	= imx8_scu_ids,
	.probe		= imx8_scu_probe,
	.bind		= imx8_scu_bind,
	.remove		= imx8_scu_remove,
	.ops		= &imx8_scu_ops,
	.plat_auto	= sizeof(struct imx8_scu),
	.flags		= DM_FLAG_PRE_RELOC,
};
