/*
 * S3C64XX/S5PC100 OneNAND driver at U-Boot
 *
 * Copyright (C) 2008-2009 Samsung Electronics
 * Kyungmin Park <kyungmin.park@samsung.com>
 *
 * Implementation:
 *	Emulate the pseudo BufferRAM
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <malloc.h>
#include <linux/mtd/compat.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h>
#include <linux/mtd/samsung_onenand.h>

#include <asm/io.h>
#include <asm/errno.h>

#ifdef ONENAND_DEBUG
#define DPRINTK(format, args...)					\
do {									\
	printf("%s[%d]: " format "\n", __func__, __LINE__, ##args);	\
} while (0)
#else
#define DPRINTK(...)			do { } while (0)
#endif

#define ONENAND_ERASE_STATUS		0x00
#define ONENAND_MULTI_ERASE_SET		0x01
#define ONENAND_ERASE_START		0x03
#define ONENAND_UNLOCK_START		0x08
#define ONENAND_UNLOCK_END		0x09
#define ONENAND_LOCK_START		0x0A
#define ONENAND_LOCK_END		0x0B
#define ONENAND_LOCK_TIGHT_START	0x0C
#define ONENAND_LOCK_TIGHT_END		0x0D
#define ONENAND_UNLOCK_ALL		0x0E
#define ONENAND_OTP_ACCESS		0x12
#define ONENAND_SPARE_ACCESS_ONLY	0x13
#define ONENAND_MAIN_ACCESS_ONLY	0x14
#define ONENAND_ERASE_VERIFY		0x15
#define ONENAND_MAIN_SPARE_ACCESS	0x16
#define ONENAND_PIPELINE_READ		0x4000

#if defined(CONFIG_S3C64XX)
#define MAP_00				(0x0 << 24)
#define MAP_01				(0x1 << 24)
#define MAP_10				(0x2 << 24)
#define MAP_11				(0x3 << 24)
#elif defined(CONFIG_S5PC1XX)
#define MAP_00				(0x0 << 26)
#define MAP_01				(0x1 << 26)
#define MAP_10				(0x2 << 26)
#define MAP_11				(0x3 << 26)
#endif

/* read/write of XIP buffer */
#define CMD_MAP_00(mem_addr)		(MAP_00 | ((mem_addr) << 1))
/* read/write to the memory device */
#define CMD_MAP_01(mem_addr)		(MAP_01 | (mem_addr))
/* control special functions of the memory device */
#define CMD_MAP_10(mem_addr)		(MAP_10 | (mem_addr))
/* direct interface(direct access) with the memory device */
#define CMD_MAP_11(mem_addr)		(MAP_11 | ((mem_addr) << 2))

struct s3c_onenand {
	struct mtd_info	*mtd;
	void __iomem	*base;
	void __iomem	*ahb_addr;
	int		bootram_command;
	void __iomem	*page_buf;
	void __iomem	*oob_buf;
	unsigned int	(*mem_addr)(int fba, int fpa, int fsa);
	struct samsung_onenand *reg;
};

static struct s3c_onenand *onenand;

static int s3c_read_cmd(unsigned int cmd)
{
	return readl(onenand->ahb_addr + cmd);
}

static void s3c_write_cmd(int value, unsigned int cmd)
{
	writel(value, onenand->ahb_addr + cmd);
}

/*
 * MEM_ADDR
 *
 * fba: flash block address
 * fpa: flash page address
 * fsa: flash sector address
 *
 * return the buffer address on the memory device
 * It will be combined with CMD_MAP_XX
 */
#if defined(CONFIG_S3C64XX)
static unsigned int s3c_mem_addr(int fba, int fpa, int fsa)
{
	return (fba << 12) | (fpa << 6) | (fsa << 4);
}
#elif defined(CONFIG_S5PC1XX)
static unsigned int s3c_mem_addr(int fba, int fpa, int fsa)
{
	return (fba << 13) | (fpa << 7) | (fsa << 5);
}
#endif

static void s3c_onenand_reset(void)
{
	unsigned long timeout = 0x10000;
	int stat;

	writel(ONENAND_MEM_RESET_COLD, &onenand->reg->mem_reset);
	while (timeout--) {
		stat = readl(&onenand->reg->int_err_stat);
		if (stat & RST_CMP)
			break;
	}
	stat = readl(&onenand->reg->int_err_stat);
	writel(stat, &onenand->reg->int_err_ack);

	/* Clear interrupt */
	writel(0x0, &onenand->reg->int_err_ack);
	/* Clear the ECC status */
	writel(0x0, &onenand->reg->ecc_err_stat);
}

static unsigned short s3c_onenand_readw(void __iomem *addr)
{
	struct onenand_chip *this = onenand->mtd->priv;
	int reg = addr - this->base;
	int word_addr = reg >> 1;
	int value;

	/* It's used for probing time */
	switch (reg) {
	case ONENAND_REG_MANUFACTURER_ID:
		return readl(&onenand->reg->manufact_id);
	case ONENAND_REG_DEVICE_ID:
		return readl(&onenand->reg->device_id);
	case ONENAND_REG_VERSION_ID:
		return readl(&onenand->reg->flash_ver_id);
	case ONENAND_REG_DATA_BUFFER_SIZE:
		return readl(&onenand->reg->data_buf_size);
	case ONENAND_REG_TECHNOLOGY:
		return readl(&onenand->reg->tech);
	case ONENAND_REG_SYS_CFG1:
		return readl(&onenand->reg->mem_cfg);

	/* Used at unlock all status */
	case ONENAND_REG_CTRL_STATUS:
		return 0;

	case ONENAND_REG_WP_STATUS:
		return ONENAND_WP_US;

	default:
		break;
	}

	/* BootRAM access control */
	if (reg < ONENAND_DATARAM && onenand->bootram_command) {
		if (word_addr == 0)
			return readl(&onenand->reg->manufact_id);
		if (word_addr == 1)
			return readl(&onenand->reg->device_id);
		if (word_addr == 2)
			return readl(&onenand->reg->flash_ver_id);
	}

	value = s3c_read_cmd(CMD_MAP_11(word_addr)) & 0xffff;
	printk(KERN_INFO "s3c_onenand_readw:  Illegal access"
		" at reg 0x%x, value 0x%x\n", word_addr, value);
	return value;
}

static void s3c_onenand_writew(unsigned short value, void __iomem *addr)
{
	struct onenand_chip *this = onenand->mtd->priv;
	int reg = addr - this->base;
	int word_addr = reg >> 1;

	/* It's used for probing time */
	switch (reg) {
	case ONENAND_REG_SYS_CFG1:
		writel(value, &onenand->reg->mem_cfg);
		return;

	case ONENAND_REG_START_ADDRESS1:
	case ONENAND_REG_START_ADDRESS2:
		return;

	/* Lock/lock-tight/unlock/unlock_all */
	case ONENAND_REG_START_BLOCK_ADDRESS:
		return;

	default:
		break;
	}

	/* BootRAM access control */
	if (reg < ONENAND_DATARAM) {
		if (value == ONENAND_CMD_READID) {
			onenand->bootram_command = 1;
			return;
		}
		if (value == ONENAND_CMD_RESET) {
			writel(ONENAND_MEM_RESET_COLD,
					&onenand->reg->mem_reset);
			onenand->bootram_command = 0;
			return;
		}
	}

	printk(KERN_INFO "s3c_onenand_writew: Illegal access"
		" at reg 0x%x, value 0x%x\n", word_addr, value);

	s3c_write_cmd(value, CMD_MAP_11(word_addr));
}

static int s3c_onenand_wait(struct mtd_info *mtd, int state)
{
	unsigned int flags = INT_ACT;
	unsigned int stat, ecc;
	unsigned long timeout = 0x100000;

	switch (state) {
	case FL_READING:
		flags |= BLK_RW_CMP | LOAD_CMP;
		break;
	case FL_WRITING:
		flags |= BLK_RW_CMP | PGM_CMP;
		break;
	case FL_ERASING:
		flags |= BLK_RW_CMP | ERS_CMP;
		break;
	case FL_LOCKING:
		flags |= BLK_RW_CMP;
		break;
	default:
		break;
	}

	while (timeout--) {
		stat = readl(&onenand->reg->int_err_stat);
		if (stat & flags)
			break;
	}

	/* To get correct interrupt status in timeout case */
	stat = readl(&onenand->reg->int_err_stat);
	writel(stat, &onenand->reg->int_err_ack);

	/*
	 * In the Spec. it checks the controller status first
	 * However if you get the correct information in case of
	 * power off recovery (POR) test, it should read ECC status first
	 */
	if (stat & LOAD_CMP) {
		ecc = readl(&onenand->reg->ecc_err_stat);
		if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) {
			printk(KERN_INFO "%s: ECC error = 0x%04x\n",
					__func__, ecc);
			mtd->ecc_stats.failed++;
			return -EBADMSG;
		}
	}

	if (stat & (LOCKED_BLK | ERS_FAIL | PGM_FAIL | LD_FAIL_ECC_ERR)) {
		printk(KERN_INFO "%s: controller error = 0x%04x\n",
				__func__, stat);
		if (stat & LOCKED_BLK)
			printk(KERN_INFO "%s: it's locked error = 0x%04x\n",
					__func__, stat);

		return -EIO;
	}

	return 0;
}

static int s3c_onenand_command(struct mtd_info *mtd, int cmd,
		loff_t addr, size_t len)
{
	struct onenand_chip *this = mtd->priv;
	unsigned int *m, *s;
	int fba, fpa, fsa = 0;
	unsigned int mem_addr;
	int i, mcount, scount;
	int index;

	fba = (int) (addr >> this->erase_shift);
	fpa = (int) (addr >> this->page_shift);
	fpa &= this->page_mask;

	mem_addr = onenand->mem_addr(fba, fpa, fsa);

	switch (cmd) {
	case ONENAND_CMD_READ:
	case ONENAND_CMD_READOOB:
	case ONENAND_CMD_BUFFERRAM:
		ONENAND_SET_NEXT_BUFFERRAM(this);
	default:
		break;
	}

	index = ONENAND_CURRENT_BUFFERRAM(this);

	/*
	 * Emulate Two BufferRAMs and access with 4 bytes pointer
	 */
	m = (unsigned int *) onenand->page_buf;
	s = (unsigned int *) onenand->oob_buf;

	if (index) {
		m += (this->writesize >> 2);
		s += (mtd->oobsize >> 2);
	}

	mcount = mtd->writesize >> 2;
	scount = mtd->oobsize >> 2;

	switch (cmd) {
	case ONENAND_CMD_READ:
		/* Main */
		for (i = 0; i < mcount; i++)
			*m++ = s3c_read_cmd(CMD_MAP_01(mem_addr));
		return 0;

	case ONENAND_CMD_READOOB:
		writel(TSRF, &onenand->reg->trans_spare);
		/* Main */
		for (i = 0; i < mcount; i++)
			*m++ = s3c_read_cmd(CMD_MAP_01(mem_addr));

		/* Spare */
		for (i = 0; i < scount; i++)
			*s++ = s3c_read_cmd(CMD_MAP_01(mem_addr));

		writel(0, &onenand->reg->trans_spare);
		return 0;

	case ONENAND_CMD_PROG:
		/* Main */
		for (i = 0; i < mcount; i++)
			s3c_write_cmd(*m++, CMD_MAP_01(mem_addr));
		return 0;

	case ONENAND_CMD_PROGOOB:
		writel(TSRF, &onenand->reg->trans_spare);

		/* Main - dummy write */
		for (i = 0; i < mcount; i++)
			s3c_write_cmd(0xffffffff, CMD_MAP_01(mem_addr));

		/* Spare */
		for (i = 0; i < scount; i++)
			s3c_write_cmd(*s++, CMD_MAP_01(mem_addr));

		writel(0, &onenand->reg->trans_spare);
		return 0;

	case ONENAND_CMD_UNLOCK_ALL:
		s3c_write_cmd(ONENAND_UNLOCK_ALL, CMD_MAP_10(mem_addr));
		return 0;

	case ONENAND_CMD_ERASE:
		s3c_write_cmd(ONENAND_ERASE_START, CMD_MAP_10(mem_addr));
		return 0;

	case ONENAND_CMD_MULTIBLOCK_ERASE:
		s3c_write_cmd(ONENAND_MULTI_ERASE_SET, CMD_MAP_10(mem_addr));
		return 0;

	case ONENAND_CMD_ERASE_VERIFY:
		s3c_write_cmd(ONENAND_ERASE_VERIFY, CMD_MAP_10(mem_addr));
		return 0;

	default:
		break;
	}

	return 0;
}

static unsigned char *s3c_get_bufferram(struct mtd_info *mtd, int area)
{
	struct onenand_chip *this = mtd->priv;
	int index = ONENAND_CURRENT_BUFFERRAM(this);
	unsigned char *p;

	if (area == ONENAND_DATARAM) {
		p = (unsigned char *) onenand->page_buf;
		if (index == 1)
			p += this->writesize;
	} else {
		p = (unsigned char *) onenand->oob_buf;
		if (index == 1)
			p += mtd->oobsize;
	}

	return p;
}

static int onenand_read_bufferram(struct mtd_info *mtd, loff_t addr, int area,
				  unsigned char *buffer, int offset,
				  size_t count)
{
	unsigned char *p;

	p = s3c_get_bufferram(mtd, area);
	memcpy(buffer, p + offset, count);
	return 0;
}

static int onenand_write_bufferram(struct mtd_info *mtd, loff_t addr, int area,
				   const unsigned char *buffer, int offset,
				   size_t count)
{
	unsigned char *p;

	p = s3c_get_bufferram(mtd, area);
	memcpy(p + offset, buffer, count);
	return 0;
}

static int s3c_onenand_bbt_wait(struct mtd_info *mtd, int state)
{
	struct samsung_onenand *reg = (struct samsung_onenand *)onenand->base;
	unsigned int flags = INT_ACT | LOAD_CMP;
	unsigned int stat;
	unsigned long timeout = 0x10000;

	while (timeout--) {
		stat = readl(&reg->int_err_stat);
		if (stat & flags)
			break;
	}
	/* To get correct interrupt status in timeout case */
	stat = readl(&onenand->reg->int_err_stat);
	writel(stat, &onenand->reg->int_err_ack);

	if (stat & LD_FAIL_ECC_ERR) {
		s3c_onenand_reset();
		return ONENAND_BBT_READ_ERROR;
	}

	if (stat & LOAD_CMP) {
		int ecc = readl(&onenand->reg->ecc_err_stat);
		if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) {
			s3c_onenand_reset();
			return ONENAND_BBT_READ_ERROR;
		}
	}

	return 0;
}

static void s3c_onenand_check_lock_status(struct mtd_info *mtd)
{
	struct onenand_chip *this = mtd->priv;
	unsigned int block, end;
	int tmp;

	end = this->chipsize >> this->erase_shift;

	for (block = 0; block < end; block++) {
		tmp = s3c_read_cmd(CMD_MAP_01(onenand->mem_addr(block, 0, 0)));

		if (readl(&onenand->reg->int_err_stat) & LOCKED_BLK) {
			printf("block %d is write-protected!\n", block);
			writel(LOCKED_BLK, &onenand->reg->int_err_ack);
		}
	}
}

static void s3c_onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs,
		size_t len, int cmd)
{
	struct onenand_chip *this = mtd->priv;
	int start, end, start_mem_addr, end_mem_addr;

	start = ofs >> this->erase_shift;
	start_mem_addr = onenand->mem_addr(start, 0, 0);
	end = start + (len >> this->erase_shift) - 1;
	end_mem_addr = onenand->mem_addr(end, 0, 0);

	if (cmd == ONENAND_CMD_LOCK) {
		s3c_write_cmd(ONENAND_LOCK_START, CMD_MAP_10(start_mem_addr));
		s3c_write_cmd(ONENAND_LOCK_END, CMD_MAP_10(end_mem_addr));
	} else {
		s3c_write_cmd(ONENAND_UNLOCK_START, CMD_MAP_10(start_mem_addr));
		s3c_write_cmd(ONENAND_UNLOCK_END, CMD_MAP_10(end_mem_addr));
	}

	this->wait(mtd, FL_LOCKING);
}

static void s3c_onenand_unlock_all(struct mtd_info *mtd)
{
	struct onenand_chip *this = mtd->priv;
	loff_t ofs = 0;
	size_t len = this->chipsize;

	/* FIXME workaround */
	this->subpagesize = mtd->writesize;
	mtd->subpage_sft = 0;

	if (this->options & ONENAND_HAS_UNLOCK_ALL) {
		/* Write unlock command */
		this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);

		/* No need to check return value */
		this->wait(mtd, FL_LOCKING);

		/* Workaround for all block unlock in DDP */
		if (!ONENAND_IS_DDP(this)) {
			s3c_onenand_check_lock_status(mtd);
			return;
		}

		/* All blocks on another chip */
		ofs = this->chipsize >> 1;
		len = this->chipsize >> 1;
	}

	s3c_onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
	s3c_onenand_check_lock_status(mtd);
}

#ifdef CONFIG_S3C64XX
static void s3c_set_width_regs(struct onenand_chip *this)
{
	int dev_id, density;
	int fba, fpa, fsa;
	int dbs_dfs;

	dev_id = DEVICE_ID0_REG;

	density = (dev_id >> ONENAND_DEVICE_DENSITY_SHIFT) & 0xf;
	dbs_dfs = !!(dev_id & ONENAND_DEVICE_IS_DDP);

	fba = density + 7;
	if (dbs_dfs)
		fba--;		/* Decrease the fba */
	fpa = 6;
	if (density >= ONENAND_DEVICE_DENSITY_512Mb)
		fsa = 2;
	else
		fsa = 1;

	DPRINTK("FBA %lu, FPA %lu, FSA %lu, DDP %lu",
		FBA_WIDTH0_REG, FPA_WIDTH0_REG, FSA_WIDTH0_REG,
		DDP_DEVICE_REG);

	DPRINTK("mem_cfg0 0x%lx, sync mode %lu, "
		"dev_page_size %lu, BURST LEN %lu",
		MEM_CFG0_REG, SYNC_MODE_REG,
		DEV_PAGE_SIZE_REG, BURST_LEN0_REG);

	DEV_PAGE_SIZE_REG = 0x1;

	FBA_WIDTH0_REG = fba;
	FPA_WIDTH0_REG = fpa;
	FSA_WIDTH0_REG = fsa;
	DBS_DFS_WIDTH0_REG = dbs_dfs;
}
#endif

void s3c_onenand_init(struct mtd_info *mtd)
{
	struct onenand_chip *this = mtd->priv;
	u32 size = (4 << 10);	/* 4 KiB */

	onenand = malloc(sizeof(struct s3c_onenand));
	if (!onenand)
		return;

	onenand->page_buf = malloc(size * sizeof(char));
	if (!onenand->page_buf)
		return;
	memset(onenand->page_buf, 0xff, size);

	onenand->oob_buf = malloc(128 * sizeof(char));
	if (!onenand->oob_buf)
		return;
	memset(onenand->oob_buf, 0xff, 128);

	onenand->mtd = mtd;

#if defined(CONFIG_S3C64XX)
	onenand->base = (void *)0x70100000;
	onenand->ahb_addr = (void *)0x20000000;
#elif defined(CONFIG_S5PC1XX)
	onenand->base = (void *)0xE7100000;
	onenand->ahb_addr = (void *)0xB0000000;
#endif
	onenand->mem_addr = s3c_mem_addr;
	onenand->reg = (struct samsung_onenand *)onenand->base;

	this->read_word = s3c_onenand_readw;
	this->write_word = s3c_onenand_writew;

	this->wait = s3c_onenand_wait;
	this->bbt_wait = s3c_onenand_bbt_wait;
	this->unlock_all = s3c_onenand_unlock_all;
	this->command = s3c_onenand_command;

	this->read_bufferram = onenand_read_bufferram;
	this->write_bufferram = onenand_write_bufferram;

	this->options |= ONENAND_RUNTIME_BADBLOCK_CHECK;
}
