/*
 * cmd_otp.c - interface to Blackfin on-chip One-Time-Programmable memory
 *
 * Copyright (c) 2007-2008 Analog Devices Inc.
 *
 * Licensed under the GPL-2 or later.
 */

/* There are 512 128-bit "pages" (0x000 through 0x1FF).
 * The pages are accessable as 64-bit "halfpages" (an upper and lower half).
 * The pages are not part of the memory map.  There is an OTP controller which
 * handles scanning in/out of bits.  While access is done through OTP MMRs,
 * the bootrom provides C-callable helper functions to handle the interaction.
 */

#include <config.h>
#include <common.h>
#include <command.h>

#include <asm/blackfin.h>
#include <asm/mach-common/bits/otp.h>

static const char *otp_strerror(uint32_t err)
{
	switch (err) {
	case 0:                   return "no error";
	case OTP_WRITE_ERROR:     return "OTP fuse write error";
	case OTP_READ_ERROR:      return "OTP fuse read error";
	case OTP_ACC_VIO_ERROR:   return "invalid OTP address";
	case OTP_DATA_MULT_ERROR: return "multiple bad bits detected";
	case OTP_ECC_MULT_ERROR:  return "error in ECC bits";
	case OTP_PREV_WR_ERROR:   return "space already written";
	case OTP_DATA_SB_WARN:    return "single bad bit in half page";
	case OTP_ECC_SB_WARN:     return "single bad bit in ECC";
	default:                  return "unknown error";
	}
}

#define lowup(x) ((x) % 2 ? "upper" : "lower")

static int check_voltage(void)
{
	/* Make sure voltage limits are within datasheet spec */
	uint16_t vr_ctl = bfin_read_VR_CTL();

#ifdef __ADSPBF54x__
	/* 0.9V <= VDDINT <= 1.1V */
	if ((vr_ctl & 0xc) && (vr_ctl & 0xc0) == 0xc0)
		return 1;
#else
	/* for the parts w/out qualification yet */
	(void)vr_ctl;
#endif

	return 0;
}

static void set_otp_timing(bool write)
{
	static uint32_t timing;
	if (!timing) {
		uint32_t tp1, tp2, tp3;
		/* OTP_TP1 = 1000 / sclk_period (in nanoseconds)
		 * OTP_TP1 = 1000 / (1 / get_sclk() * 10^9)
		 * OTP_TP1 = (1000 * get_sclk()) / 10^9
		 * OTP_TP1 = get_sclk() / 10^6
		 */
		tp1 = get_sclk() / 1000000;
		/* OTP_TP2 = 400 / (2 * sclk_period)
		 * OTP_TP2 = 400 / (2 * 1 / get_sclk() * 10^9)
		 * OTP_TP2 = (400 * get_sclk()) / (2 * 10^9)
		 * OTP_TP2 = (2 * get_sclk()) / 10^7
		 */
		tp2 = (2 * get_sclk() / 10000000) << 8;
		/* OTP_TP3 = magic constant */
		tp3 = (0x1401) << 15;
		timing = tp1 | tp2 | tp3;
	}

	bfrom_OtpCommand(OTP_INIT, write ? timing : timing & ~(-1 << 15));
}

int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	uint32_t ret, base_flags;
	bool prompt_user, force_read;
	uint32_t (*otp_func)(uint32_t page, uint32_t flags, uint64_t *page_content);

	if (argc < 4) {
 usage:
		return cmd_usage(cmdtp);
	}

	prompt_user = false;
	base_flags = 0;
	if (!strcmp(argv[1], "read"))
		otp_func = bfrom_OtpRead;
	else if (!strcmp(argv[1], "dump")) {
		otp_func = bfrom_OtpRead;
		force_read = true;
	} else if (!strcmp(argv[1], "write")) {
		otp_func = bfrom_OtpWrite;
		base_flags = OTP_CHECK_FOR_PREV_WRITE;
		if (!strcmp(argv[2], "--force")) {
			argv[2] = argv[1];
			argv++;
			--argc;
		} else
			prompt_user = false;
	} else if (!strcmp(argv[1], "lock")) {
		if (argc != 4)
			goto usage;
		otp_func = bfrom_OtpWrite;
		base_flags = OTP_LOCK;
	} else
		goto usage;

	uint64_t *addr = (uint64_t *)simple_strtoul(argv[2], NULL, 16);
	uint32_t page = simple_strtoul(argv[3], NULL, 16);
	uint32_t flags;
	size_t i, count;
	ulong half;

	if (argc > 4)
		count = simple_strtoul(argv[4], NULL, 16);
	else
		count = 2;

	if (argc > 5) {
		half = simple_strtoul(argv[5], NULL, 16);
		if (half != 0 && half != 1) {
			puts("Error: 'half' can only be '0' or '1'\n");
			goto usage;
		}
	} else
		half = 0;

	/* "otp lock" has slightly different semantics */
	if (base_flags & OTP_LOCK) {
		count = page;
		page = (uint32_t)addr;
		addr = NULL;
	}

	/* do to the nature of OTP, make sure users are sure */
	if (prompt_user) {
		printf(
			"Writing one time programmable memory\n"
			"Make sure your operating voltages and temperature are within spec\n"
			"   source address:  0x%p\n"
			"   OTP destination: %s page 0x%03X - %s page 0x%03lX\n"
			"   number to write: %lu halfpages\n"
			" type \"YES\" (no quotes) to confirm: ",
			addr,
			lowup(half), page,
			lowup(half + count - 1), page + (half + count - 1) / 2,
			half + count
		);

		i = 0;
		while (1) {
			if (tstc()) {
				const char exp_ans[] = "YES\r";
				char c;
				putc(c = getc());
				if (exp_ans[i++] != c) {
					printf(" Aborting\n");
					return 1;
				} else if (!exp_ans[i]) {
					puts("\n");
					break;
				}
			}
		}
	}

	printf("OTP memory %s: addr 0x%p  page 0x%03X  count %zu ... ",
		argv[1], addr, page, count);

	set_otp_timing(otp_func == bfrom_OtpWrite);
	if (otp_func == bfrom_OtpWrite && check_voltage()) {
		puts("ERROR: VDDINT voltage is out of spec for writing\n");
		return -1;
	}

	/* Do the actual reading/writing stuff */
	ret = 0;
	for (i = half; i < count + half; ++i) {
		flags = base_flags | (i % 2 ? OTP_UPPER_HALF : OTP_LOWER_HALF);
 try_again:
		ret = otp_func(page, flags, addr);
		if (ret & OTP_MASTER_ERROR) {
			if (force_read) {
				if (flags & OTP_NO_ECC)
					break;
				else
					flags |= OTP_NO_ECC;
				puts("E");
				goto try_again;
			} else
				break;
		} else if (ret)
			puts("W");
		else
			puts(".");
		if (!(base_flags & OTP_LOCK)) {
			++addr;
			if (i % 2)
				++page;
		} else
			++page;
	}
	if (ret & 0x1)
		printf("\nERROR at page 0x%03X (%s-halfpage): 0x%03X: %s\n",
			page, lowup(i), ret, otp_strerror(ret));
	else
		puts(" done\n");

	/* Make sure we disable writing */
	set_otp_timing(false);
	bfrom_OtpCommand(OTP_CLOSE, 0);

	return ret;
}

U_BOOT_CMD(
	otp, 7, 0, do_otp,
	"One-Time-Programmable sub-system",
	"read <addr> <page> [count] [half]\n"
	" - read 'count' half-pages starting at 'page' (offset 'half') to 'addr'\n"
	"otp dump <addr> <page> [count] [half]\n"
	" - like 'otp read', but skip read errors\n"
	"otp write [--force] <addr> <page> [count] [half]\n"
	" - write 'count' half-pages starting at 'page' (offset 'half') from 'addr'\n"
	"otp lock <page> <count>\n"
	" - lock 'count' pages starting at 'page'"
);
