/*
 * 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_S5P)
#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_S5P)
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;

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

	for (block = 0; block < end; block++) {
		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_S5P)
	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;
}
