// SPDX-License-Identifier: GPL-2.0+
/*
 * i.MX8 OCOTP fusebox driver
 *
 * Copyright 2019 NXP
 *
 * Peng Fan <peng.fan@nxp.com>
 */

#include <linux/arm-smccc.h>
#include <linux/firmware/imx/sci.h>
#include <linux/module.h>
#include <linux/nvmem-provider.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#define IMX_SIP_OTP_WRITE		0xc200000B

enum ocotp_devtype {
	IMX8QXP,
	IMX8QM,
};

#define ECC_REGION	BIT(0)
#define HOLE_REGION	BIT(1)

struct ocotp_region {
	u32 start;
	u32 end;
	u32 flag;
};

struct ocotp_devtype_data {
	int devtype;
	int nregs;
	u32 num_region;
	struct ocotp_region region[];
};

struct ocotp_priv {
	struct device *dev;
	const struct ocotp_devtype_data *data;
	struct imx_sc_ipc *nvmem_ipc;
};

struct imx_sc_msg_misc_fuse_read {
	struct imx_sc_rpc_msg hdr;
	u32 word;
} __packed;

static DEFINE_MUTEX(scu_ocotp_mutex);

static struct ocotp_devtype_data imx8qxp_data = {
	.devtype = IMX8QXP,
	.nregs = 800,
	.num_region = 3,
	.region = {
		{0x10, 0x10f, ECC_REGION},
		{0x110, 0x21F, HOLE_REGION},
		{0x220, 0x31F, ECC_REGION},
	},
};

static struct ocotp_devtype_data imx8qm_data = {
	.devtype = IMX8QM,
	.nregs = 800,
	.num_region = 2,
	.region = {
		{0x10, 0x10f, ECC_REGION},
		{0x1a0, 0x1ff, ECC_REGION},
	},
};

static bool in_hole(void *context, u32 index)
{
	struct ocotp_priv *priv = context;
	const struct ocotp_devtype_data *data = priv->data;
	int i;

	for (i = 0; i < data->num_region; i++) {
		if (data->region[i].flag & HOLE_REGION) {
			if ((index >= data->region[i].start) &&
			    (index <= data->region[i].end))
				return true;
		}
	}

	return false;
}

static bool in_ecc(void *context, u32 index)
{
	struct ocotp_priv *priv = context;
	const struct ocotp_devtype_data *data = priv->data;
	int i;

	for (i = 0; i < data->num_region; i++) {
		if (data->region[i].flag & ECC_REGION) {
			if ((index >= data->region[i].start) &&
			    (index <= data->region[i].end))
				return true;
		}
	}

	return false;
}

static int imx_sc_misc_otp_fuse_read(struct imx_sc_ipc *ipc, u32 word,
				     u32 *val)
{
	struct imx_sc_msg_misc_fuse_read msg;
	struct imx_sc_rpc_msg *hdr = &msg.hdr;
	int ret;

	hdr->ver = IMX_SC_RPC_VERSION;
	hdr->svc = IMX_SC_RPC_SVC_MISC;
	hdr->func = IMX_SC_MISC_FUNC_OTP_FUSE_READ;
	hdr->size = 2;

	msg.word = word;

	ret = imx_scu_call_rpc(ipc, &msg, true);
	if (ret)
		return ret;

	*val = msg.word;

	return 0;
}

static int imx_scu_ocotp_read(void *context, unsigned int offset,
			      void *val, size_t bytes)
{
	struct ocotp_priv *priv = context;
	u32 count, index, num_bytes;
	u32 *buf;
	void *p;
	int i, ret;

	index = offset;
	num_bytes = round_up(bytes, 4);
	count = num_bytes >> 2;

	if (count > (priv->data->nregs - index))
		count = priv->data->nregs - index;

	p = kzalloc(num_bytes, GFP_KERNEL);
	if (!p)
		return -ENOMEM;

	mutex_lock(&scu_ocotp_mutex);

	buf = p;

	for (i = index; i < (index + count); i++) {
		if (in_hole(context, i)) {
			*buf++ = 0;
			continue;
		}

		ret = imx_sc_misc_otp_fuse_read(priv->nvmem_ipc, i, buf);
		if (ret) {
			mutex_unlock(&scu_ocotp_mutex);
			kfree(p);
			return ret;
		}
		buf++;
	}

	memcpy(val, (u8 *)p, bytes);

	mutex_unlock(&scu_ocotp_mutex);

	kfree(p);

	return 0;
}

static int imx_scu_ocotp_write(void *context, unsigned int offset,
			       void *val, size_t bytes)
{
	struct ocotp_priv *priv = context;
	struct arm_smccc_res res;
	u32 *buf = val;
	u32 tmp;
	u32 index;
	int ret;

	/* allow only writing one complete OTP word at a time */
	if (bytes != 4)
		return -EINVAL;

	index = offset;

	if (in_hole(context, index))
		return -EINVAL;

	if (in_ecc(context, index)) {
		pr_warn("ECC region, only program once\n");
		mutex_lock(&scu_ocotp_mutex);
		ret = imx_sc_misc_otp_fuse_read(priv->nvmem_ipc, index, &tmp);
		mutex_unlock(&scu_ocotp_mutex);
		if (ret)
			return ret;
		if (tmp) {
			pr_warn("ECC region, already has value: %x\n", tmp);
			return -EIO;
		}
	}

	mutex_lock(&scu_ocotp_mutex);

	arm_smccc_smc(IMX_SIP_OTP_WRITE, index, *buf, 0, 0, 0, 0, 0, &res);

	mutex_unlock(&scu_ocotp_mutex);

	return res.a0;
}

static struct nvmem_config imx_scu_ocotp_nvmem_config = {
	.name = "imx-scu-ocotp",
	.add_legacy_fixed_of_cells = true,
	.read_only = false,
	.word_size = 4,
	.stride = 1,
	.owner = THIS_MODULE,
	.reg_read = imx_scu_ocotp_read,
	.reg_write = imx_scu_ocotp_write,
};

static const struct of_device_id imx_scu_ocotp_dt_ids[] = {
	{ .compatible = "fsl,imx8qxp-scu-ocotp", (void *)&imx8qxp_data },
	{ .compatible = "fsl,imx8qm-scu-ocotp", (void *)&imx8qm_data },
	{ },
};
MODULE_DEVICE_TABLE(of, imx_scu_ocotp_dt_ids);

static int imx_scu_ocotp_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct ocotp_priv *priv;
	struct nvmem_device *nvmem;
	int ret;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	ret = imx_scu_get_handle(&priv->nvmem_ipc);
	if (ret)
		return ret;

	priv->data = of_device_get_match_data(dev);
	priv->dev = dev;
	imx_scu_ocotp_nvmem_config.size = 4 * priv->data->nregs;
	imx_scu_ocotp_nvmem_config.dev = dev;
	imx_scu_ocotp_nvmem_config.priv = priv;
	nvmem = devm_nvmem_register(dev, &imx_scu_ocotp_nvmem_config);

	return PTR_ERR_OR_ZERO(nvmem);
}

static struct platform_driver imx_scu_ocotp_driver = {
	.probe	= imx_scu_ocotp_probe,
	.driver = {
		.name	= "imx_scu_ocotp",
		.of_match_table = imx_scu_ocotp_dt_ids,
	},
};
module_platform_driver(imx_scu_ocotp_driver);

MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
MODULE_DESCRIPTION("i.MX8 SCU OCOTP fuse box driver");
MODULE_LICENSE("GPL v2");
