// SPDX-License-Identifier: GPL-2.0-only
// Copyright (C) 2016 Broadcom

#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/nvmem-provider.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>

/*
 * # of tries for OTP Status. The time to execute a command varies. The slowest
 * commands are writes which also vary based on the # of bits turned on. Writing
 * 0xffffffff takes ~3800 us.
 */
#define OTPC_RETRIES                 5000

/* Sequence to enable OTP program */
#define OTPC_PROG_EN_SEQ             { 0xf, 0x4, 0x8, 0xd }

/* OTPC Commands */
#define OTPC_CMD_READ                0x0
#define OTPC_CMD_OTP_PROG_ENABLE     0x2
#define OTPC_CMD_OTP_PROG_DISABLE    0x3
#define OTPC_CMD_PROGRAM             0x8

/* OTPC Status Bits */
#define OTPC_STAT_CMD_DONE           BIT(1)
#define OTPC_STAT_PROG_OK            BIT(2)

/* OTPC register definition */
#define OTPC_MODE_REG_OFFSET         0x0
#define OTPC_MODE_REG_OTPC_MODE      0
#define OTPC_COMMAND_OFFSET          0x4
#define OTPC_COMMAND_COMMAND_WIDTH   6
#define OTPC_CMD_START_OFFSET        0x8
#define OTPC_CMD_START_START         0
#define OTPC_CPU_STATUS_OFFSET       0xc
#define OTPC_CPUADDR_REG_OFFSET      0x28
#define OTPC_CPUADDR_REG_OTPC_CPU_ADDRESS_WIDTH 16
#define OTPC_CPU_WRITE_REG_OFFSET    0x2c

#define OTPC_CMD_MASK  (BIT(OTPC_COMMAND_COMMAND_WIDTH) - 1)
#define OTPC_ADDR_MASK (BIT(OTPC_CPUADDR_REG_OTPC_CPU_ADDRESS_WIDTH) - 1)


struct otpc_map {
	/* in words. */
	u32 otpc_row_size;
	/* 128 bit row / 4 words support. */
	u16 data_r_offset[4];
	/* 128 bit row / 4 words support. */
	u16 data_w_offset[4];
};

static struct otpc_map otp_map = {
	.otpc_row_size = 1,
	.data_r_offset = {0x10},
	.data_w_offset = {0x2c},
};

static struct otpc_map otp_map_v2 = {
	.otpc_row_size = 2,
	.data_r_offset = {0x10, 0x5c},
	.data_w_offset = {0x2c, 0x64},
};

struct otpc_priv {
	struct device *dev;
	void __iomem *base;
	const struct otpc_map *map;
	struct nvmem_config *config;
};

static inline void set_command(void __iomem *base, u32 command)
{
	writel(command & OTPC_CMD_MASK, base + OTPC_COMMAND_OFFSET);
}

static inline void set_cpu_address(void __iomem *base, u32 addr)
{
	writel(addr & OTPC_ADDR_MASK, base + OTPC_CPUADDR_REG_OFFSET);
}

static inline void set_start_bit(void __iomem *base)
{
	writel(1 << OTPC_CMD_START_START, base + OTPC_CMD_START_OFFSET);
}

static inline void reset_start_bit(void __iomem *base)
{
	writel(0, base + OTPC_CMD_START_OFFSET);
}

static inline void write_cpu_data(void __iomem *base, u32 value)
{
	writel(value, base + OTPC_CPU_WRITE_REG_OFFSET);
}

static int poll_cpu_status(void __iomem *base, u32 value)
{
	u32 status;
	u32 retries;

	for (retries = 0; retries < OTPC_RETRIES; retries++) {
		status = readl(base + OTPC_CPU_STATUS_OFFSET);
		if (status & value)
			break;
		udelay(1);
	}
	if (retries == OTPC_RETRIES)
		return -EAGAIN;

	return 0;
}

static int enable_ocotp_program(void __iomem *base)
{
	static const u32 vals[] = OTPC_PROG_EN_SEQ;
	int i;
	int ret;

	/* Write the magic sequence to enable programming */
	set_command(base, OTPC_CMD_OTP_PROG_ENABLE);
	for (i = 0; i < ARRAY_SIZE(vals); i++) {
		write_cpu_data(base, vals[i]);
		set_start_bit(base);
		ret = poll_cpu_status(base, OTPC_STAT_CMD_DONE);
		reset_start_bit(base);
		if (ret)
			return ret;
	}

	return poll_cpu_status(base, OTPC_STAT_PROG_OK);
}

static int disable_ocotp_program(void __iomem *base)
{
	int ret;

	set_command(base, OTPC_CMD_OTP_PROG_DISABLE);
	set_start_bit(base);
	ret = poll_cpu_status(base, OTPC_STAT_PROG_OK);
	reset_start_bit(base);

	return ret;
}

static int bcm_otpc_read(void *context, unsigned int offset, void *val,
	size_t bytes)
{
	struct otpc_priv *priv = context;
	u32 *buf = val;
	u32 bytes_read;
	u32 address = offset / priv->config->word_size;
	int i, ret;

	for (bytes_read = 0; bytes_read < bytes;) {
		set_command(priv->base, OTPC_CMD_READ);
		set_cpu_address(priv->base, address++);
		set_start_bit(priv->base);
		ret = poll_cpu_status(priv->base, OTPC_STAT_CMD_DONE);
		if (ret) {
			dev_err(priv->dev, "otp read error: 0x%x", ret);
			return -EIO;
		}

		for (i = 0; i < priv->map->otpc_row_size; i++) {
			*buf++ = readl(priv->base +
					priv->map->data_r_offset[i]);
			bytes_read += sizeof(*buf);
		}

		reset_start_bit(priv->base);
	}

	return 0;
}

static int bcm_otpc_write(void *context, unsigned int offset, void *val,
	size_t bytes)
{
	struct otpc_priv *priv = context;
	u32 *buf = val;
	u32 bytes_written;
	u32 address = offset / priv->config->word_size;
	int i, ret;

	if (offset % priv->config->word_size)
		return -EINVAL;

	ret = enable_ocotp_program(priv->base);
	if (ret)
		return -EIO;

	for (bytes_written = 0; bytes_written < bytes;) {
		set_command(priv->base, OTPC_CMD_PROGRAM);
		set_cpu_address(priv->base, address++);
		for (i = 0; i < priv->map->otpc_row_size; i++) {
			writel(*buf, priv->base + priv->map->data_w_offset[i]);
			buf++;
			bytes_written += sizeof(*buf);
		}
		set_start_bit(priv->base);
		ret = poll_cpu_status(priv->base, OTPC_STAT_CMD_DONE);
		reset_start_bit(priv->base);
		if (ret) {
			dev_err(priv->dev, "otp write error: 0x%x", ret);
			return -EIO;
		}
	}

	disable_ocotp_program(priv->base);

	return 0;
}

static struct nvmem_config bcm_otpc_nvmem_config = {
	.name = "bcm-ocotp",
	.read_only = false,
	.word_size = 4,
	.stride = 4,
	.reg_read = bcm_otpc_read,
	.reg_write = bcm_otpc_write,
};

static const struct of_device_id bcm_otpc_dt_ids[] = {
	{ .compatible = "brcm,ocotp", .data = &otp_map },
	{ .compatible = "brcm,ocotp-v2", .data = &otp_map_v2 },
	{ },
};
MODULE_DEVICE_TABLE(of, bcm_otpc_dt_ids);

static const struct acpi_device_id bcm_otpc_acpi_ids[] __maybe_unused = {
	{ .id = "BRCM0700", .driver_data = (kernel_ulong_t)&otp_map },
	{ .id = "BRCM0701", .driver_data = (kernel_ulong_t)&otp_map_v2 },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(acpi, bcm_otpc_acpi_ids);

static int bcm_otpc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct resource *res;
	struct otpc_priv *priv;
	struct nvmem_device *nvmem;
	int err;
	u32 num_words;

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

	priv->map = device_get_match_data(dev);
	if (!priv->map)
		return -ENODEV;

	/* Get OTP base address register. */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	priv->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(priv->base)) {
		dev_err(dev, "unable to map I/O memory\n");
		return PTR_ERR(priv->base);
	}

	/* Enable CPU access to OTPC. */
	writel(readl(priv->base + OTPC_MODE_REG_OFFSET) |
		BIT(OTPC_MODE_REG_OTPC_MODE),
		priv->base + OTPC_MODE_REG_OFFSET);
	reset_start_bit(priv->base);

	/* Read size of memory in words. */
	err = device_property_read_u32(dev, "brcm,ocotp-size", &num_words);
	if (err) {
		dev_err(dev, "size parameter not specified\n");
		return -EINVAL;
	} else if (num_words == 0) {
		dev_err(dev, "size must be > 0\n");
		return -EINVAL;
	}

	bcm_otpc_nvmem_config.size = 4 * num_words;
	bcm_otpc_nvmem_config.dev = dev;
	bcm_otpc_nvmem_config.priv = priv;

	if (priv->map == &otp_map_v2) {
		bcm_otpc_nvmem_config.word_size = 8;
		bcm_otpc_nvmem_config.stride = 8;
	}

	priv->config = &bcm_otpc_nvmem_config;

	nvmem = devm_nvmem_register(dev, &bcm_otpc_nvmem_config);
	if (IS_ERR(nvmem)) {
		dev_err(dev, "error registering nvmem config\n");
		return PTR_ERR(nvmem);
	}

	return 0;
}

static struct platform_driver bcm_otpc_driver = {
	.probe	= bcm_otpc_probe,
	.driver = {
		.name	= "brcm-otpc",
		.of_match_table = bcm_otpc_dt_ids,
		.acpi_match_table = ACPI_PTR(bcm_otpc_acpi_ids),
	},
};
module_platform_driver(bcm_otpc_driver);

MODULE_DESCRIPTION("Broadcom OTPC driver");
MODULE_LICENSE("GPL v2");
