// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2015-2016 Reinhard Pfau <reinhard.pfau@gdsys.cc>
 */

#include <config.h>
#include <common.h>
#include <errno.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/efuse.h>
#include <asm/arch/soc.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/mbus.h>

#if defined(CONFIG_MVEBU_EFUSE_FAKE)
#define DRY_RUN
#else
#undef DRY_RUN
#endif

#define MBUS_EFUSE_BASE 0xF6000000
#define MBUS_EFUSE_SIZE BIT(20)

#define MVEBU_EFUSE_CONTROL (MVEBU_REGISTER(0xE4008))

enum {
	MVEBU_EFUSE_CTRL_PROGRAM_ENABLE = (1 << 31),
	MVEBU_EFUSE_LD1_SELECT          = (1 <<  6),
};

struct mvebu_hd_efuse {
	u32 bits_31_0;
	u32 bits_63_32;
	u32 bit64;
	u32 reserved0;
};

#ifndef DRY_RUN
static struct mvebu_hd_efuse *efuses =
	(struct mvebu_hd_efuse *)(MBUS_EFUSE_BASE + 0xF9000);
static u32 *ld_efuses = (void *)MBUS_EFUSE_BASE + 0xF8F00;
#else
static struct mvebu_hd_efuse efuses[EFUSE_LINE_MAX + 1];
static u32 ld_efuses[EFUSE_LD_WORDS];
#endif

static int efuse_initialised;

static struct mvebu_hd_efuse *get_efuse_line(int nr)
{
	if (nr < 0 || nr > 63 || !efuse_initialised)
		return NULL;

	return efuses + nr;
}

static void enable_efuse_program(void)
{
#ifndef DRY_RUN
	setbits_le32(MVEBU_EFUSE_CONTROL, MVEBU_EFUSE_CTRL_PROGRAM_ENABLE);
#endif
}

static void disable_efuse_program(void)
{
#ifndef DRY_RUN
	clrbits_le32(MVEBU_EFUSE_CONTROL, MVEBU_EFUSE_CTRL_PROGRAM_ENABLE);
#endif
}

static int do_prog_efuse(struct mvebu_hd_efuse *efuse,
			 struct efuse_val *new_val, u32 mask0, u32 mask1)
{
	struct efuse_val val;

	val.dwords.d[0] = readl(&efuse->bits_31_0);
	val.dwords.d[1] = readl(&efuse->bits_63_32);
	val.lock = readl(&efuse->bit64);

	if (val.lock & 1)
		return -EPERM;

	val.dwords.d[0] |= (new_val->dwords.d[0] & mask0);
	val.dwords.d[1] |= (new_val->dwords.d[1] & mask1);
	val.lock |= new_val->lock;

	writel(val.dwords.d[0], &efuse->bits_31_0);
	mdelay(1);
	writel(val.dwords.d[1], &efuse->bits_63_32);
	mdelay(1);
	writel(val.lock, &efuse->bit64);
	mdelay(5);

	return 0;
}

static int prog_efuse(int nr, struct efuse_val *new_val, u32 mask0, u32 mask1)
{
	struct mvebu_hd_efuse *efuse;
	int res = 0;

	res = mvebu_efuse_init_hw();
	if (res)
		return res;

	efuse = get_efuse_line(nr);
	if (!efuse)
		return -ENODEV;

	if (!new_val)
		return -EINVAL;

	/* only write a fuse line with lock bit */
	if (!new_val->lock)
		return -EINVAL;

	/* according to specs ECC protection bits must be 0 on write */
	if (new_val->bytes.d[7] & 0xFE)
		return -EINVAL;

	if (!new_val->dwords.d[0] && !new_val->dwords.d[1] && (mask0 | mask1))
		return 0;

	enable_efuse_program();

	res = do_prog_efuse(efuse, new_val, mask0, mask1);

	disable_efuse_program();

	return res;
}

int mvebu_efuse_init_hw(void)
{
	int ret;

	if (efuse_initialised)
		return 0;

	ret = mvebu_mbus_add_window_by_id(
		CPU_TARGET_SATA23_DFX, 0xA, MBUS_EFUSE_BASE, MBUS_EFUSE_SIZE);

	if (ret)
		return ret;

	efuse_initialised = 1;

	return 0;
}

int mvebu_read_efuse(int nr, struct efuse_val *val)
{
	struct mvebu_hd_efuse *efuse;
	int res;

	res = mvebu_efuse_init_hw();
	if (res)
		return res;

	efuse = get_efuse_line(nr);
	if (!efuse)
		return -ENODEV;

	if (!val)
		return -EINVAL;

	val->dwords.d[0] = readl(&efuse->bits_31_0);
	val->dwords.d[1] = readl(&efuse->bits_63_32);
	val->lock = readl(&efuse->bit64);
	return 0;
}

void mvebu_read_ld_efuse(int ld1, u32 *line)
{
	int i;

#ifndef DRY_RUN
	if (ld1)
		setbits_le32(MVEBU_EFUSE_CONTROL, MVEBU_EFUSE_LD1_SELECT);
	else
		clrbits_le32(MVEBU_EFUSE_CONTROL, MVEBU_EFUSE_LD1_SELECT);
#endif

	for (i = 0; i < EFUSE_LD_WORDS; i++)
		line[i] = readl(ld_efuses + i);
}

int mvebu_write_efuse(int nr, struct efuse_val *val)
{
	return prog_efuse(nr, val, ~0, ~0);
}

int mvebu_lock_efuse(int nr)
{
	struct efuse_val val = {
		.lock = 1,
	};

	return prog_efuse(nr, &val, 0, 0);
}

/*
 * wrapper funcs providing the fuse API
 *
 * we use the following mapping:
 *   "bank" ->	eFuse line
 *   "word" ->	0: bits 0-31
 *		1: bits 32-63
 *		2: bit 64 (lock)
 */

static struct efuse_val prog_val;
static int valid_prog_words;

int fuse_read(u32 bank, u32 word, u32 *val)
{
	struct efuse_val fuse_line;
	u32 ld_line[EFUSE_LD_WORDS];
	int res;

	if ((bank == EFUSE_LD0_LINE || bank == EFUSE_LD1_LINE) && word < EFUSE_LD_WORDS) {
		res = mvebu_efuse_init_hw();
		if (res)
			return res;
		mvebu_read_ld_efuse(bank == EFUSE_LD1_LINE, ld_line);
		*val = ld_line[word];
		return 0;
	}

	if (bank < EFUSE_LINE_MIN || bank > EFUSE_LINE_MAX || word > 2)
		return -EINVAL;

	res = mvebu_read_efuse(bank, &fuse_line);
	if (res)
		return res;

	if (word < 2)
		*val = fuse_line.dwords.d[word];
	else
		*val = fuse_line.lock;

	return res;
}

int fuse_sense(u32 bank, u32 word, u32 *val)
{
	/* not supported */
	return -ENOSYS;
}

int fuse_prog(u32 bank, u32 word, u32 val)
{
	int res = 0;

	/*
	 * NOTE: Fuse line should be written as whole.
	 * So how can we do that with this API?
	 * For now: remember values for word == 0 and word == 1 and write the
	 * whole line when word == 2.
	 * This implies that we always require all 3 fuse prog cmds (one for
	 * for each word) to write a single fuse line.
	 * Exception is a single write to word 2 which will lock the fuse line.
	 *
	 * Hope that will be OK.
	 */

	if (bank < EFUSE_LINE_MIN || bank > EFUSE_LINE_MAX || word > 2)
		return -EINVAL;

	if (word < 2) {
		prog_val.dwords.d[word] = val;
		valid_prog_words |= (1 << word);
	} else if ((valid_prog_words & 3) == 0 && val) {
		res = mvebu_lock_efuse(bank);
		valid_prog_words = 0;
	} else if ((valid_prog_words & 3) != 3 || !val) {
		res = -EINVAL;
	} else {
		prog_val.lock = val != 0;
		res = mvebu_write_efuse(bank, &prog_val);
		valid_prog_words = 0;
	}

	return res;
}

int fuse_override(u32 bank, u32 word, u32 val)
{
	/* not supported */
	return -ENOSYS;
}
