// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
 */

#include <common.h>
#include <asm/io.h>
#include <command.h>
#include <display_options.h>
#include <dm.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/iopoll.h>
#include <malloc.h>
#include <misc.h>

/* OTP Register Offsets */
#define OTPC_SBPI_CTRL			0x0020
#define OTPC_SBPI_CMD_VALID_PRE		0x0024
#define OTPC_SBPI_CS_VALID_PRE		0x0028
#define OTPC_SBPI_STATUS		0x002C
#define OTPC_USER_CTRL			0x0100
#define OTPC_USER_ADDR			0x0104
#define OTPC_USER_ENABLE		0x0108
#define OTPC_USER_QP			0x0120
#define OTPC_USER_Q			0x0124
#define OTPC_INT_STATUS			0x0304
#define OTPC_SBPI_CMD0_OFFSET		0x1000
#define OTPC_SBPI_CMD1_OFFSET		0x1004

/* OTP Register bits and masks */
#define OTPC_USER_ADDR_MASK		GENMASK(31, 16)
#define OTPC_USE_USER			BIT(0)
#define OTPC_USE_USER_MASK		GENMASK(16, 16)
#define OTPC_USER_FSM_ENABLE		BIT(0)
#define OTPC_USER_FSM_ENABLE_MASK	GENMASK(16, 16)
#define OTPC_SBPI_DONE			BIT(1)
#define OTPC_USER_DONE			BIT(2)

#define SBPI_DAP_ADDR			0x02
#define SBPI_DAP_ADDR_SHIFT		8
#define SBPI_DAP_ADDR_MASK		GENMASK(31, 24)
#define SBPI_CMD_VALID_MASK		GENMASK(31, 16)
#define SBPI_DAP_CMD_WRF		0xC0
#define SBPI_DAP_REG_ECC		0x3A
#define SBPI_ECC_ENABLE			0x00
#define SBPI_ECC_DISABLE		0x09
#define SBPI_ENABLE			BIT(0)
#define SBPI_ENABLE_MASK		GENMASK(16, 16)

#define OTPC_TIMEOUT			10000

#define RK3588_OTPC_AUTO_CTRL		0x0004
#define RK3588_ADDR_SHIFT		16
#define RK3588_ADDR(n)			((n) << RK3588_ADDR_SHIFT)
#define RK3588_BURST_SHIFT		8
#define RK3588_BURST(n)			((n) << RK3588_BURST_SHIFT)
#define RK3588_OTPC_AUTO_EN		0x0008
#define RK3588_AUTO_EN			BIT(0)
#define RK3588_OTPC_DOUT0		0x0020
#define RK3588_OTPC_INT_ST		0x0084
#define RK3588_RD_DONE			BIT(1)

struct rockchip_otp_plat {
	void __iomem *base;
};

struct rockchip_otp_data {
	int (*read)(struct udevice *dev, int offset, void *buf, int size);
	int offset;
	int size;
	int block_size;
};

#if defined(DEBUG)
static int dump_otp(struct cmd_tbl *cmdtp, int flag,
		    int argc, char *const argv[])
{
	struct udevice *dev;
	u8 data[4];
	int ret, i;

	ret = uclass_get_device_by_driver(UCLASS_MISC,
					  DM_DRIVER_GET(rockchip_otp), &dev);
	if (ret) {
		printf("%s: no misc-device found\n", __func__);
		return 0;
	}

	for (i = 0; true; i += sizeof(data)) {
		ret = misc_read(dev, i, &data, sizeof(data));
		if (ret <= 0)
			return 0;

		print_buffer(i, data, 1, sizeof(data), sizeof(data));
	}

	return 0;
}

U_BOOT_CMD(
	dump_otp, 1, 1, dump_otp,
	"Dump the content of the otp",
	""
);
#endif

static int rockchip_otp_poll_timeout(struct rockchip_otp_plat *otp,
				     u32 flag, u32 reg)
{
	u32 status;
	int ret;

	ret = readl_poll_sleep_timeout(otp->base + reg, status,
				       (status & flag), 1, OTPC_TIMEOUT);
	if (ret)
		return ret;

	/* Clear int flag */
	writel(flag, otp->base + reg);

	return 0;
}

static int rockchip_otp_ecc_enable(struct rockchip_otp_plat *otp, bool enable)
{
	writel(SBPI_DAP_ADDR_MASK | (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT),
	       otp->base + OTPC_SBPI_CTRL);

	writel(SBPI_CMD_VALID_MASK | 0x1, otp->base + OTPC_SBPI_CMD_VALID_PRE);
	writel(SBPI_DAP_CMD_WRF | SBPI_DAP_REG_ECC,
	       otp->base + OTPC_SBPI_CMD0_OFFSET);

	if (enable)
		writel(SBPI_ECC_ENABLE, otp->base + OTPC_SBPI_CMD1_OFFSET);
	else
		writel(SBPI_ECC_DISABLE, otp->base + OTPC_SBPI_CMD1_OFFSET);

	writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL);

	return rockchip_otp_poll_timeout(otp, OTPC_SBPI_DONE, OTPC_INT_STATUS);
}

static int rockchip_px30_otp_read(struct udevice *dev, int offset,
				  void *buf, int size)
{
	struct rockchip_otp_plat *otp = dev_get_plat(dev);
	u8 *buffer = buf;
	int ret;

	ret = rockchip_otp_ecc_enable(otp, false);
	if (ret)
		return ret;

	writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
	udelay(5);

	while (size--) {
		writel(offset++ | OTPC_USER_ADDR_MASK,
		       otp->base + OTPC_USER_ADDR);
		writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
		       otp->base + OTPC_USER_ENABLE);

		ret = rockchip_otp_poll_timeout(otp, OTPC_USER_DONE,
						OTPC_INT_STATUS);
		if (ret)
			goto read_end;

		*buffer++ = (u8)(readl(otp->base + OTPC_USER_Q) & 0xFF);
	}

read_end:
	writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);

	return ret;
}

static int rockchip_rk3568_otp_read(struct udevice *dev, int offset,
				    void *buf, int size)
{
	struct rockchip_otp_plat *otp = dev_get_plat(dev);
	u16 *buffer = buf;
	int ret;

	ret = rockchip_otp_ecc_enable(otp, false);
	if (ret)
		return ret;

	writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
	udelay(5);

	while (size--) {
		writel(offset++ | OTPC_USER_ADDR_MASK,
		       otp->base + OTPC_USER_ADDR);
		writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
		       otp->base + OTPC_USER_ENABLE);

		ret = rockchip_otp_poll_timeout(otp, OTPC_USER_DONE,
						OTPC_INT_STATUS);
		if (ret)
			goto read_end;

		*buffer++ = (u16)(readl(otp->base + OTPC_USER_Q) & 0xFFFF);
	}

read_end:
	writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);

	return ret;
}

static int rockchip_rk3588_otp_read(struct udevice *dev, int offset,
				    void *buf, int size)
{
	struct rockchip_otp_plat *otp = dev_get_plat(dev);
	u32 *buffer = buf;
	int ret;

	while (size--) {
		writel(RK3588_ADDR(offset++) | RK3588_BURST(1),
		       otp->base + RK3588_OTPC_AUTO_CTRL);
		writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN);

		ret = rockchip_otp_poll_timeout(otp, RK3588_RD_DONE,
						RK3588_OTPC_INT_ST);
		if (ret)
			return ret;

		*buffer++ = readl(otp->base + RK3588_OTPC_DOUT0);
	}

	return 0;
}

static int rockchip_otp_read(struct udevice *dev, int offset,
			     void *buf, int size)
{
	const struct rockchip_otp_data *data =
		(void *)dev_get_driver_data(dev);
	u32 block_start, block_end, block_offset, blocks;
	u8 *buffer;
	int ret;

	if (offset < 0 || !buf || size <= 0 || offset + size > data->size)
		return -EINVAL;

	if (!data->read)
		return -ENOSYS;

	offset += data->offset;

	if (data->block_size <= 1) {
		ret = data->read(dev, offset, buf, size);
		goto done;
	}

	block_start = offset / data->block_size;
	block_offset = offset % data->block_size;
	block_end = DIV_ROUND_UP(offset + size, data->block_size);
	blocks = block_end - block_start;

	buffer = calloc(blocks, data->block_size);
	if (!buffer)
		return -ENOMEM;

	ret = data->read(dev, block_start, buffer, blocks);
	if (!ret)
		memcpy(buf, buffer + block_offset, size);

	free(buffer);

done:
	return ret < 0 ? ret : size;
}

static const struct misc_ops rockchip_otp_ops = {
	.read = rockchip_otp_read,
};

static int rockchip_otp_of_to_plat(struct udevice *dev)
{
	struct rockchip_otp_plat *plat = dev_get_plat(dev);

	plat->base = dev_read_addr_ptr(dev);

	return 0;
}

static const struct rockchip_otp_data px30_data = {
	.read = rockchip_px30_otp_read,
	.size = 0x40,
};

static const struct rockchip_otp_data rk3568_data = {
	.read = rockchip_rk3568_otp_read,
	.size = 0x80,
	.block_size = 2,
};

static const struct rockchip_otp_data rk3588_data = {
	.read = rockchip_rk3588_otp_read,
	.offset = 0xC00,
	.size = 0x400,
	.block_size = 4,
};

static const struct udevice_id rockchip_otp_ids[] = {
	{
		.compatible = "rockchip,px30-otp",
		.data = (ulong)&px30_data,
	},
	{
		.compatible = "rockchip,rk3308-otp",
		.data = (ulong)&px30_data,
	},
	{
		.compatible = "rockchip,rk3568-otp",
		.data = (ulong)&rk3568_data,
	},
	{
		.compatible = "rockchip,rk3588-otp",
		.data = (ulong)&rk3588_data,
	},
	{}
};

U_BOOT_DRIVER(rockchip_otp) = {
	.name = "rockchip_otp",
	.id = UCLASS_MISC,
	.of_match = rockchip_otp_ids,
	.of_to_plat = rockchip_otp_of_to_plat,
	.plat_auto = sizeof(struct rockchip_otp_plat),
	.ops = &rockchip_otp_ops,
};
