/*
 *  U-Boot command for OneNAND support
 *
 *  Copyright (C) 2005-2008 Samsung Electronics
 *  Kyungmin Park <kyungmin.park@samsung.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

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

#include <linux/mtd/compat.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h>

#include <asm/io.h>

static struct mtd_info *mtd;

static loff_t next_ofs;
static loff_t skip_ofs;

static inline int str2long(char *p, ulong *num)
{
	char *endptr;

	*num = simple_strtoul(p, &endptr, 16);
	return (*p != '\0' && *endptr == '\0') ? 1 : 0;
}

static int arg_off_size(int argc, char * const argv[], ulong *off, size_t *size)
{
	if (argc >= 1) {
		if (!(str2long(argv[0], off))) {
			printf("'%s' is not a number\n", argv[0]);
			return -1;
		}
	} else {
		*off = 0;
	}

	if (argc >= 2) {
		if (!(str2long(argv[1], (ulong *)size))) {
			printf("'%s' is not a number\n", argv[1]);
			return -1;
		}
	} else {
		*size = mtd->size - *off;
	}

	if ((*off + *size) > mtd->size) {
		printf("total chip size (0x%llx) exceeded!\n", mtd->size);
		return -1;
	}

	if (*size == mtd->size)
		puts("whole chip\n");
	else
		printf("offset 0x%lx, size 0x%x\n", *off, *size);

	return 0;
}

static int onenand_block_read(loff_t from, size_t len,
			      size_t *retlen, u_char *buf, int oob)
{
	struct onenand_chip *this = mtd->priv;
	int blocks = (int) len >> this->erase_shift;
	int blocksize = (1 << this->erase_shift);
	loff_t ofs = from;
	struct mtd_oob_ops ops = {
		.retlen		= 0,
	};
	int ret;

	if (oob)
		ops.ooblen = blocksize;
	else
		ops.len = blocksize;

	while (blocks) {
		ret = mtd->block_isbad(mtd, ofs);
		if (ret) {
			printk("Bad blocks %d at 0x%x\n",
			       (u32)(ofs >> this->erase_shift), (u32)ofs);
			ofs += blocksize;
			continue;
		}

		if (oob)
			ops.oobbuf = buf;
		else
			ops.datbuf = buf;

		ops.retlen = 0;
		ret = mtd->read_oob(mtd, ofs, &ops);
		if (ret) {
			printk("Read failed 0x%x, %d\n", (u32)ofs, ret);
			ofs += blocksize;
			continue;
		}
		ofs += blocksize;
		buf += blocksize;
		blocks--;
		*retlen += ops.retlen;
	}

	return 0;
}

static int onenand_block_write(loff_t to, size_t len,
			       size_t *retlen, const u_char * buf)
{
	struct onenand_chip *this = mtd->priv;
	int blocks = len >> this->erase_shift;
	int blocksize = (1 << this->erase_shift);
	loff_t ofs;
	size_t _retlen = 0;
	int ret;

	if (to == next_ofs) {
		next_ofs = to + len;
		to += skip_ofs;
	} else {
		next_ofs = to + len;
		skip_ofs = 0;
	}
	ofs = to;

	while (blocks) {
		ret = mtd->block_isbad(mtd, ofs);
		if (ret) {
			printk("Bad blocks %d at 0x%x\n",
			       (u32)(ofs >> this->erase_shift), (u32)ofs);
			skip_ofs += blocksize;
			goto next;
		}

		ret = mtd->write(mtd, ofs, blocksize, &_retlen, buf);
		if (ret) {
			printk("Write failed 0x%x, %d", (u32)ofs, ret);
			skip_ofs += blocksize;
			goto next;
		}

		buf += blocksize;
		blocks--;
		*retlen += _retlen;
next:
		ofs += blocksize;
	}

	return 0;
}

static int onenand_block_erase(u32 start, u32 size, int force)
{
	struct onenand_chip *this = mtd->priv;
	struct erase_info instr = {
		.callback	= NULL,
	};
	loff_t ofs;
	int ret;
	int blocksize = 1 << this->erase_shift;

	for (ofs = start; ofs < (start + size); ofs += blocksize) {
		ret = mtd->block_isbad(mtd, ofs);
		if (ret && !force) {
			printf("Skip erase bad block %d at 0x%x\n",
			       (u32)(ofs >> this->erase_shift), (u32)ofs);
			continue;
		}

		instr.addr = ofs;
		instr.len = blocksize;
		instr.priv = force;
		instr.mtd = mtd;
		ret = mtd->erase(mtd, &instr);
		if (ret) {
			printf("erase failed block %d at 0x%x\n",
			       (u32)(ofs >> this->erase_shift), (u32)ofs);
			continue;
		}
	}

	return 0;
}

static int onenand_block_test(u32 start, u32 size)
{
	struct onenand_chip *this = mtd->priv;
	struct erase_info instr = {
		.callback	= NULL,
		.priv		= 0,
	};

	int blocks;
	loff_t ofs;
	int blocksize = 1 << this->erase_shift;
	int start_block, end_block;
	size_t retlen;
	u_char *buf;
	u_char *verify_buf;
	int ret;

	buf = malloc(blocksize);
	if (!buf) {
		printf("Not enough malloc space available!\n");
		return -1;
	}

	verify_buf = malloc(blocksize);
	if (!verify_buf) {
		printf("Not enough malloc space available!\n");
		return -1;
	}

	start_block = start >> this->erase_shift;
	end_block = (start + size) >> this->erase_shift;

	/* Protect boot-loader from badblock testing */
	if (start_block < 2)
		start_block = 2;

	if (end_block > (mtd->size >> this->erase_shift))
		end_block = mtd->size >> this->erase_shift;

	blocks = start_block;
	ofs = start;
	while (blocks < end_block) {
		printf("\rTesting block %d at 0x%x", (u32)(ofs >> this->erase_shift), (u32)ofs);

		ret = mtd->block_isbad(mtd, ofs);
		if (ret) {
			printf("Skip erase bad block %d at 0x%x\n",
			       (u32)(ofs >> this->erase_shift), (u32)ofs);
			goto next;
		}

		instr.addr = ofs;
		instr.len = blocksize;
		ret = mtd->erase(mtd, &instr);
		if (ret) {
			printk("Erase failed 0x%x, %d\n", (u32)ofs, ret);
			goto next;
		}

		ret = mtd->write(mtd, ofs, blocksize, &retlen, buf);
		if (ret) {
			printk("Write failed 0x%x, %d\n", (u32)ofs, ret);
			goto next;
		}

		ret = mtd->read(mtd, ofs, blocksize, &retlen, verify_buf);
		if (ret) {
			printk("Read failed 0x%x, %d\n", (u32)ofs, ret);
			goto next;
		}

		if (memcmp(buf, verify_buf, blocksize))
			printk("\nRead/Write test failed at 0x%x\n", (u32)ofs);

next:
		ofs += blocksize;
		blocks++;
	}
	printf("...Done\n");

	free(buf);
	free(verify_buf);

	return 0;
}

static int onenand_dump(struct mtd_info *mtd, ulong off, int only_oob)
{
	int i;
	u_char *datbuf, *oobbuf, *p;
	struct mtd_oob_ops ops;
	loff_t addr;

	datbuf = malloc(mtd->writesize + mtd->oobsize);
	oobbuf = malloc(mtd->oobsize);
	if (!datbuf || !oobbuf) {
		puts("No memory for page buffer\n");
		return 1;
	}
	off &= ~(mtd->writesize - 1);
	addr = (loff_t) off;
	memset(&ops, 0, sizeof(ops));
	ops.datbuf = datbuf;
	ops.oobbuf = oobbuf;
	ops.len = mtd->writesize;
	ops.ooblen = mtd->oobsize;
	ops.retlen = 0;
	i = mtd->read_oob(mtd, addr, &ops);
	if (i < 0) {
		printf("Error (%d) reading page %08lx\n", i, off);
		free(datbuf);
		free(oobbuf);
		return 1;
	}
	printf("Page %08lx dump:\n", off);
	i = mtd->writesize >> 4;
	p = datbuf;

	while (i--) {
		if (!only_oob)
			printf("\t%02x %02x %02x %02x %02x %02x %02x %02x"
			       "  %02x %02x %02x %02x %02x %02x %02x %02x\n",
			       p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
			       p[8], p[9], p[10], p[11], p[12], p[13], p[14],
			       p[15]);
		p += 16;
	}
	puts("OOB:\n");
	i = mtd->oobsize >> 3;
	p = oobbuf;

	while (i--) {
		printf("\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
		       p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
		p += 8;
	}
	free(datbuf);
	free(oobbuf);

	return 0;
}

static int do_onenand_info(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	printf("%s\n", mtd->name);
	return 0;
}

static int do_onenand_bad(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	ulong ofs;

	mtd = &onenand_mtd;
	/* Currently only one OneNAND device is supported */
	printf("\nDevice %d bad blocks:\n", 0);
	for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) {
		if (mtd->block_isbad(mtd, ofs))
			printf("  %08x\n", (u32)ofs);
	}

	return 0;
}

static int do_onenand_read(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	char *s;
	int oob = 0;
	ulong addr, ofs;
	size_t len;
	int ret = 0;
	size_t retlen = 0;

	if (argc < 3)
		return cmd_usage(cmdtp);

	s = strchr(argv[0], '.');
	if ((s != NULL) && (!strcmp(s, ".oob")))
		oob = 1;

	addr = (ulong)simple_strtoul(argv[1], NULL, 16);

	printf("\nOneNAND read: ");
	if (arg_off_size(argc - 2, argv + 2, &ofs, &len) != 0)
		return 1;

	ret = onenand_block_read(ofs, len, &retlen, (u8 *)addr, oob);

	printf(" %d bytes read: %s\n", retlen, ret ? "ERROR" : "OK");

	return ret == 0 ? 0 : 1;
}

static int do_onenand_write(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	ulong addr, ofs;
	size_t len;
	int ret = 0;
	size_t retlen = 0;

	if (argc < 3)
		return cmd_usage(cmdtp);

	addr = (ulong)simple_strtoul(argv[1], NULL, 16);

	printf("\nOneNAND write: ");
	if (arg_off_size(argc - 2, argv + 2, &ofs, &len) != 0)
		return 1;

	ret = onenand_block_write(ofs, len, &retlen, (u8 *)addr);

	printf(" %d bytes written: %s\n", retlen, ret ? "ERROR" : "OK");

	return ret == 0 ? 0 : 1;
}

static int do_onenand_erase(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	ulong ofs;
	int ret = 0;
	size_t len;
	int force;

	/*
	 * Syntax is:
	 *   0       1     2       3    4
	 *   onenand erase [force] [off size]
	 */
	argc--;
	argv++;
	if (argc)
	{
		if (!strcmp("force", argv[0]))
		{
			force = 1;
			argc--;
			argv++;
		}
	}
	printf("\nOneNAND erase: ");

	/* skip first two or three arguments, look for offset and size */
	if (arg_off_size(argc, argv, &ofs, &len) != 0)
		return 1;

	ret = onenand_block_erase(ofs, len, force);

	printf("%s\n", ret ? "ERROR" : "OK");

	return ret == 0 ? 0 : 1;
}

static int do_onenand_test(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	ulong ofs;
	int ret = 0;
	size_t len;

	/*
	 * Syntax is:
	 *   0       1     2       3    4
	 *   onenand test [force] [off size]
	 */

	printf("\nOneNAND test: ");

	/* skip first two or three arguments, look for offset and size */
	if (arg_off_size(argc - 1, argv + 1, &ofs, &len) != 0)
		return 1;

	ret = onenand_block_test(ofs, len);

	printf("%s\n", ret ? "ERROR" : "OK");

	return ret == 0 ? 0 : 1;
}

static int do_onenand_dump(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	ulong ofs;
	int ret = 0;
	char *s;

	if (argc < 2)
		return cmd_usage(cmdtp);

	s = strchr(argv[0], '.');
	ofs = (int)simple_strtoul(argv[1], NULL, 16);

	if (s != NULL && strcmp(s, ".oob") == 0)
		ret = onenand_dump(mtd, ofs, 1);
	else
		ret = onenand_dump(mtd, ofs, 0);

	return ret == 0 ? 1 : 0;
}

static int do_onenand_markbad(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	int ret = 0;
	ulong addr;

	argc -= 2;
	argv += 2;

	if (argc <= 0)
		return cmd_usage(cmdtp);

	while (argc > 0) {
		addr = simple_strtoul(*argv, NULL, 16);

		if (mtd->block_markbad(mtd, addr)) {
			printf("block 0x%08lx NOT marked "
				"as bad! ERROR %d\n",
				addr, ret);
			ret = 1;
		} else {
			printf("block 0x%08lx successfully "
				"marked as bad\n",
				addr);
		}
		--argc;
		++argv;
	}
	return ret;
}

static cmd_tbl_t cmd_onenand_sub[] = {
	U_BOOT_CMD_MKENT(info, 1, 0, do_onenand_info, "", ""),
	U_BOOT_CMD_MKENT(bad, 1, 0, do_onenand_bad, "", ""),
	U_BOOT_CMD_MKENT(read, 4, 0, do_onenand_read, "", ""),
	U_BOOT_CMD_MKENT(write, 4, 0, do_onenand_write, "", ""),
	U_BOOT_CMD_MKENT(erase, 3, 0, do_onenand_erase, "", ""),
	U_BOOT_CMD_MKENT(test, 3, 0, do_onenand_test, "", ""),
	U_BOOT_CMD_MKENT(dump, 2, 0, do_onenand_dump, "", ""),
	U_BOOT_CMD_MKENT(markbad, CONFIG_SYS_MAXARGS, 0, do_onenand_markbad, "", ""),
};

#ifdef CONFIG_NEEDS_MANUAL_RELOC
void onenand_reloc(void) {
	fixup_cmdtable(cmd_onenand_sub, ARRAY_SIZE(cmd_onenand_sub));
}
#endif

static int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	cmd_tbl_t *c;

	if (argc < 2)
		return cmd_usage(cmdtp);

	mtd = &onenand_mtd;

	/* Strip off leading 'onenand' command argument */
	argc--;
	argv++;

	c = find_cmd_tbl(argv[0], &cmd_onenand_sub[0], ARRAY_SIZE(cmd_onenand_sub));

	if (c)
		return c->cmd(cmdtp, flag, argc, argv);
	else
		return cmd_usage(cmdtp);
}

U_BOOT_CMD(
	onenand,	CONFIG_SYS_MAXARGS,	1,	do_onenand,
	"OneNAND sub-system",
	"info - show available OneNAND devices\n"
	"onenand bad - show bad blocks\n"
	"onenand read[.oob] addr off size\n"
	"onenand write addr off size\n"
	"    read/write 'size' bytes starting at offset 'off'\n"
	"    to/from memory address 'addr', skipping bad blocks.\n"
	"onenand erase [force] [off size] - erase 'size' bytes from\n"
	"onenand test [off size] - test 'size' bytes from\n"
	"    offset 'off' (entire device if not specified)\n"
	"onenand dump[.oob] off - dump page\n"
	"onenand markbad off [...] - mark bad block(s) at offset (UNSAFE)"
);
