/*
 *  linux/drivers/mtd/onenand/onenand_sim.c
 *
 *  The OneNAND simulator
 *
 *  Copyright © 2005-2007 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 <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/onenand.h>

#include <linux/io.h>

#ifndef CONFIG_ONENAND_SIM_MANUFACTURER
#define CONFIG_ONENAND_SIM_MANUFACTURER         0xec
#endif
#ifndef CONFIG_ONENAND_SIM_DEVICE_ID
#define CONFIG_ONENAND_SIM_DEVICE_ID            0x04
#endif
#ifndef CONFIG_ONENAND_SIM_VERSION_ID
#define CONFIG_ONENAND_SIM_VERSION_ID           0x1e
#endif

static int manuf_id	= CONFIG_ONENAND_SIM_MANUFACTURER;
static int device_id	= CONFIG_ONENAND_SIM_DEVICE_ID;
static int version_id	= CONFIG_ONENAND_SIM_VERSION_ID;

struct onenand_flash {
	void __iomem *base;
	void __iomem *data;
};

#define ONENAND_CORE(flash)		(flash->data)
#define ONENAND_CORE_SPARE(flash, this, offset)				\
	((flash->data) + (this->chipsize) + (offset >> 5))

#define ONENAND_MAIN_AREA(this, offset)					\
	(this->base + ONENAND_DATARAM + offset)

#define ONENAND_SPARE_AREA(this, offset)				\
	(this->base + ONENAND_SPARERAM + offset)

#define ONENAND_GET_WP_STATUS(this)					\
	(readw(this->base + ONENAND_REG_WP_STATUS))

#define ONENAND_SET_WP_STATUS(v, this)					\
	(writew(v, this->base + ONENAND_REG_WP_STATUS))

/* It has all 0xff chars */
#define MAX_ONENAND_PAGESIZE		(2048 + 64)
static unsigned char *ffchars;

static struct mtd_partition os_partitions[] = {
	{
		.name		= "OneNAND simulator partition",
		.offset		= 0,
		.size		= MTDPART_SIZ_FULL,
	},
};

/*
 * OneNAND simulator mtd
 */
struct onenand_info {
	struct mtd_info		mtd;
	struct mtd_partition	*parts;
	struct onenand_chip	onenand;
	struct onenand_flash	flash;
};

static struct onenand_info *info;

#define DPRINTK(format, args...)					\
do {									\
	printk(KERN_DEBUG "%s[%d]: " format "\n", __func__,		\
			   __LINE__, ##args);				\
} while (0)

/**
 * onenand_lock_handle - Handle Lock scheme
 * @this:		OneNAND device structure
 * @cmd:		The command to be sent
 *
 * Send lock command to OneNAND device.
 * The lock scheme depends on chip type.
 */
static void onenand_lock_handle(struct onenand_chip *this, int cmd)
{
	int block_lock_scheme;
	int status;

	status = ONENAND_GET_WP_STATUS(this);
	block_lock_scheme = !(this->options & ONENAND_HAS_CONT_LOCK);

	switch (cmd) {
	case ONENAND_CMD_UNLOCK:
		if (block_lock_scheme)
			ONENAND_SET_WP_STATUS(ONENAND_WP_US, this);
		else
			ONENAND_SET_WP_STATUS(status | ONENAND_WP_US, this);
		break;

	case ONENAND_CMD_LOCK:
		if (block_lock_scheme)
			ONENAND_SET_WP_STATUS(ONENAND_WP_LS, this);
		else
			ONENAND_SET_WP_STATUS(status | ONENAND_WP_LS, this);
		break;

	case ONENAND_CMD_LOCK_TIGHT:
		if (block_lock_scheme)
			ONENAND_SET_WP_STATUS(ONENAND_WP_LTS, this);
		else
			ONENAND_SET_WP_STATUS(status | ONENAND_WP_LTS, this);
		break;

	default:
		break;
	}
}

/**
 * onenand_bootram_handle - Handle BootRAM area
 * @this:		OneNAND device structure
 * @cmd:		The command to be sent
 *
 * Emulate BootRAM area. It is possible to do basic operation using BootRAM.
 */
static void onenand_bootram_handle(struct onenand_chip *this, int cmd)
{
	switch (cmd) {
	case ONENAND_CMD_READID:
		writew(manuf_id, this->base);
		writew(device_id, this->base + 2);
		writew(version_id, this->base + 4);
		break;

	default:
		/* REVIST: Handle other commands */
		break;
	}
}

/**
 * onenand_update_interrupt - Set interrupt register
 * @this:         OneNAND device structure
 * @cmd:          The command to be sent
 *
 * Update interrupt register. The status depends on command.
 */
static void onenand_update_interrupt(struct onenand_chip *this, int cmd)
{
	int interrupt = ONENAND_INT_MASTER;

	switch (cmd) {
	case ONENAND_CMD_READ:
	case ONENAND_CMD_READOOB:
		interrupt |= ONENAND_INT_READ;
		break;

	case ONENAND_CMD_PROG:
	case ONENAND_CMD_PROGOOB:
		interrupt |= ONENAND_INT_WRITE;
		break;

	case ONENAND_CMD_ERASE:
		interrupt |= ONENAND_INT_ERASE;
		break;

	case ONENAND_CMD_RESET:
		interrupt |= ONENAND_INT_RESET;
		break;

	default:
		break;
	}

	writew(interrupt, this->base + ONENAND_REG_INTERRUPT);
}

/**
 * onenand_check_overwrite - Check if over-write happened
 * @dest:		The destination pointer
 * @src:		The source pointer
 * @count:		The length to be check
 *
 * Returns:		0 on same, otherwise 1
 *
 * Compare the source with destination
 */
static int onenand_check_overwrite(void *dest, void *src, size_t count)
{
	unsigned int *s = (unsigned int *) src;
	unsigned int *d = (unsigned int *) dest;
	int i;

	count >>= 2;
	for (i = 0; i < count; i++)
		if ((*s++ ^ *d++) != 0)
			return 1;

	return 0;
}

/**
 * onenand_data_handle - Handle OneNAND Core and DataRAM
 * @this:		OneNAND device structure
 * @cmd:		The command to be sent
 * @dataram:		Which dataram used
 * @offset:		The offset to OneNAND Core
 *
 * Copy data from OneNAND Core to DataRAM (read)
 * Copy data from DataRAM to OneNAND Core (write)
 * Erase the OneNAND Core (erase)
 */
static void onenand_data_handle(struct onenand_chip *this, int cmd,
				int dataram, unsigned int offset)
{
	struct mtd_info *mtd = &info->mtd;
	struct onenand_flash *flash = this->priv;
	int main_offset, spare_offset;
	void __iomem *src;
	void __iomem *dest;
	unsigned int i;

	if (dataram) {
		main_offset = mtd->writesize;
		spare_offset = mtd->oobsize;
	} else {
		main_offset = 0;
		spare_offset = 0;
	}

	switch (cmd) {
	case ONENAND_CMD_READ:
		src = ONENAND_CORE(flash) + offset;
		dest = ONENAND_MAIN_AREA(this, main_offset);
		memcpy(dest, src, mtd->writesize);
		/* Fall through */

	case ONENAND_CMD_READOOB:
		src = ONENAND_CORE_SPARE(flash, this, offset);
		dest = ONENAND_SPARE_AREA(this, spare_offset);
		memcpy(dest, src, mtd->oobsize);
		break;

	case ONENAND_CMD_PROG:
		src = ONENAND_MAIN_AREA(this, main_offset);
		dest = ONENAND_CORE(flash) + offset;
		/* To handle partial write */
		for (i = 0; i < (1 << mtd->subpage_sft); i++) {
			int off = i * this->subpagesize;
			if (!memcmp(src + off, ffchars, this->subpagesize))
				continue;
			if (memcmp(dest + off, ffchars, this->subpagesize) &&
			    onenand_check_overwrite(dest + off, src + off, this->subpagesize))
				printk(KERN_ERR "over-write happend at 0x%08x\n", offset);
			memcpy(dest + off, src + off, this->subpagesize);
		}
		/* Fall through */

	case ONENAND_CMD_PROGOOB:
		src = ONENAND_SPARE_AREA(this, spare_offset);
		/* Check all data is 0xff chars */
		if (!memcmp(src, ffchars, mtd->oobsize))
			break;

		dest = ONENAND_CORE_SPARE(flash, this, offset);
		if (memcmp(dest, ffchars, mtd->oobsize) &&
		    onenand_check_overwrite(dest, src, mtd->oobsize))
			printk(KERN_ERR "OOB: over-write happend at 0x%08x\n",
			       offset);
		memcpy(dest, src, mtd->oobsize);
		break;

	case ONENAND_CMD_ERASE:
		memset(ONENAND_CORE(flash) + offset, 0xff, mtd->erasesize);
		memset(ONENAND_CORE_SPARE(flash, this, offset), 0xff,
		       (mtd->erasesize >> 5));
		break;

	default:
		break;
	}
}

/**
 * onenand_command_handle - Handle command
 * @this:		OneNAND device structure
 * @cmd:		The command to be sent
 *
 * Emulate OneNAND command.
 */
static void onenand_command_handle(struct onenand_chip *this, int cmd)
{
	unsigned long offset = 0;
	int block = -1, page = -1, bufferram = -1;
	int dataram = 0;

	switch (cmd) {
	case ONENAND_CMD_UNLOCK:
	case ONENAND_CMD_LOCK:
	case ONENAND_CMD_LOCK_TIGHT:
	case ONENAND_CMD_UNLOCK_ALL:
		onenand_lock_handle(this, cmd);
		break;

	case ONENAND_CMD_BUFFERRAM:
		/* Do nothing */
		return;

	default:
		block = (int) readw(this->base + ONENAND_REG_START_ADDRESS1);
		if (block & (1 << ONENAND_DDP_SHIFT)) {
			block &= ~(1 << ONENAND_DDP_SHIFT);
			/* The half of chip block */
			block += this->chipsize >> (this->erase_shift + 1);
		}
		if (cmd == ONENAND_CMD_ERASE)
			break;

		page = (int) readw(this->base + ONENAND_REG_START_ADDRESS8);
		page = (page >> ONENAND_FPA_SHIFT);
		bufferram = (int) readw(this->base + ONENAND_REG_START_BUFFER);
		bufferram >>= ONENAND_BSA_SHIFT;
		bufferram &= ONENAND_BSA_DATARAM1;
		dataram = (bufferram == ONENAND_BSA_DATARAM1) ? 1 : 0;
		break;
	}

	if (block != -1)
		offset += block << this->erase_shift;

	if (page != -1)
		offset += page << this->page_shift;

	onenand_data_handle(this, cmd, dataram, offset);

	onenand_update_interrupt(this, cmd);
}

/**
 * onenand_writew - [OneNAND Interface] Emulate write operation
 * @value:		value to write
 * @addr:		address to write
 *
 * Write OneNAND register with value
 */
static void onenand_writew(unsigned short value, void __iomem * addr)
{
	struct onenand_chip *this = info->mtd.priv;

	/* BootRAM handling */
	if (addr < this->base + ONENAND_DATARAM) {
		onenand_bootram_handle(this, value);
		return;
	}
	/* Command handling */
	if (addr == this->base + ONENAND_REG_COMMAND)
		onenand_command_handle(this, value);

	writew(value, addr);
}

/**
 * flash_init - Initialize OneNAND simulator
 * @flash:		OneNAND simulator data strucutres
 *
 * Initialize OneNAND simulator.
 */
static int __init flash_init(struct onenand_flash *flash)
{
	int density, size;
	int buffer_size;

	flash->base = kzalloc(131072, GFP_KERNEL);
	if (!flash->base) {
		printk(KERN_ERR "Unable to allocate base address.\n");
		return -ENOMEM;
	}

	density = device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
	size = ((16 << 20) << density);

	ONENAND_CORE(flash) = vmalloc(size + (size >> 5));
	if (!ONENAND_CORE(flash)) {
		printk(KERN_ERR "Unable to allocate nand core address.\n");
		kfree(flash->base);
		return -ENOMEM;
	}

	memset(ONENAND_CORE(flash), 0xff, size + (size >> 5));

	/* Setup registers */
	writew(manuf_id, flash->base + ONENAND_REG_MANUFACTURER_ID);
	writew(device_id, flash->base + ONENAND_REG_DEVICE_ID);
	writew(version_id, flash->base + ONENAND_REG_VERSION_ID);

	if (density < 2)
		buffer_size = 0x0400;	/* 1KiB page */
	else
		buffer_size = 0x0800;	/* 2KiB page */
	writew(buffer_size, flash->base + ONENAND_REG_DATA_BUFFER_SIZE);

	return 0;
}

/**
 * flash_exit - Clean up OneNAND simulator
 * @flash:		OneNAND simulator data structures
 *
 * Clean up OneNAND simulator.
 */
static void flash_exit(struct onenand_flash *flash)
{
	vfree(ONENAND_CORE(flash));
	kfree(flash->base);
}

static int __init onenand_sim_init(void)
{
	/* Allocate all 0xff chars pointer */
	ffchars = kmalloc(MAX_ONENAND_PAGESIZE, GFP_KERNEL);
	if (!ffchars) {
		printk(KERN_ERR "Unable to allocate ff chars.\n");
		return -ENOMEM;
	}
	memset(ffchars, 0xff, MAX_ONENAND_PAGESIZE);

	/* Allocate OneNAND simulator mtd pointer */
	info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL);
	if (!info) {
		printk(KERN_ERR "Unable to allocate core structures.\n");
		kfree(ffchars);
		return -ENOMEM;
	}

	/* Override write_word function */
	info->onenand.write_word = onenand_writew;

	if (flash_init(&info->flash)) {
		printk(KERN_ERR "Unable to allocate flash.\n");
		kfree(ffchars);
		kfree(info);
		return -ENOMEM;
	}

	info->parts = os_partitions;

	info->onenand.base = info->flash.base;
	info->onenand.priv = &info->flash;

	info->mtd.name = "OneNAND simulator";
	info->mtd.priv = &info->onenand;
	info->mtd.owner = THIS_MODULE;

	if (onenand_scan(&info->mtd, 1)) {
		flash_exit(&info->flash);
		kfree(ffchars);
		kfree(info);
		return -ENXIO;
	}

	add_mtd_partitions(&info->mtd, info->parts, ARRAY_SIZE(os_partitions));

	return 0;
}

static void __exit onenand_sim_exit(void)
{
	struct onenand_chip *this = info->mtd.priv;
	struct onenand_flash *flash = this->priv;

	onenand_release(&info->mtd);
	flash_exit(flash);
	kfree(ffchars);
	kfree(info);
}

module_init(onenand_sim_init);
module_exit(onenand_sim_exit);

MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
MODULE_DESCRIPTION("The OneNAND flash simulator");
MODULE_LICENSE("GPL");
