/*
 * Linux driver for Disk-On-Chip Millennium Plus
 *
 * (c) 2002-2003 Greg Ungerer <gerg@snapgear.com>
 * (c) 2002-2003 SnapGear Inc
 * (c) 1999 Machine Vision Holdings, Inc.
 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
 *
 * $Id: doc2001plus.c,v 1.14 2005/11/07 11:14:24 gleixner Exp $
 *
 * Released under GPL
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/bitops.h>

#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/doc2000.h>

/* #define ECC_DEBUG */

/* I have no idea why some DoC chips can not use memcop_form|to_io().
 * This may be due to the different revisions of the ASIC controller built-in or
 * simplily a QA/Bug issue. Who knows ?? If you have trouble, please uncomment
 * this:*/
#undef USE_MEMCPY

static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
		size_t *retlen, u_char *buf);
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
		size_t *retlen, const u_char *buf);
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
			struct mtd_oob_ops *ops);
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
			 struct mtd_oob_ops *ops);
static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);

static struct mtd_info *docmilpluslist = NULL;


/* Perform the required delay cycles by writing to the NOP register */
static void DoC_Delay(void __iomem * docptr, int cycles)
{
	int i;

	for (i = 0; (i < cycles); i++)
		WriteDOC(0, docptr, Mplus_NOP);
}

#define	CDSN_CTRL_FR_B_MASK	(CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1)

/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
static int _DoC_WaitReady(void __iomem * docptr)
{
	unsigned int c = 0xffff;

	DEBUG(MTD_DEBUG_LEVEL3,
	      "_DoC_WaitReady called for out-of-line wait\n");

	/* Out-of-line routine to wait for chip response */
	while (((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) && --c)
		;

	if (c == 0)
		DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");

	return (c == 0);
}

static inline int DoC_WaitReady(void __iomem * docptr)
{
	/* This is inline, to optimise the common case, where it's ready instantly */
	int ret = 0;

	/* read form NOP register should be issued prior to the read from CDSNControl
	   see Software Requirement 11.4 item 2. */
	DoC_Delay(docptr, 4);

	if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK)
		/* Call the out-of-line routine to wait */
		ret = _DoC_WaitReady(docptr);

	return ret;
}

/* For some reason the Millennium Plus seems to occassionally put itself
 * into reset mode. For me this happens randomly, with no pattern that I
 * can detect. M-systems suggest always check this on any block level
 * operation and setting to normal mode if in reset mode.
 */
static inline void DoC_CheckASIC(void __iomem * docptr)
{
	/* Make sure the DoC is in normal mode */
	if ((ReadDOC(docptr, Mplus_DOCControl) & DOC_MODE_NORMAL) == 0) {
		WriteDOC((DOC_MODE_NORMAL | DOC_MODE_MDWREN), docptr, Mplus_DOCControl);
		WriteDOC(~(DOC_MODE_NORMAL | DOC_MODE_MDWREN), docptr, Mplus_CtrlConfirm);
	}
}

/* DoC_Command: Send a flash command to the flash chip through the Flash
 * command register. Need 2 Write Pipeline Terminates to complete send.
 */
static void DoC_Command(void __iomem * docptr, unsigned char command,
			       unsigned char xtraflags)
{
	WriteDOC(command, docptr, Mplus_FlashCmd);
	WriteDOC(command, docptr, Mplus_WritePipeTerm);
	WriteDOC(command, docptr, Mplus_WritePipeTerm);
}

/* DoC_Address: Set the current address for the flash chip through the Flash
 * Address register. Need 2 Write Pipeline Terminates to complete send.
 */
static inline void DoC_Address(struct DiskOnChip *doc, int numbytes,
			       unsigned long ofs, unsigned char xtraflags1,
			       unsigned char xtraflags2)
{
	void __iomem * docptr = doc->virtadr;

	/* Allow for possible Mill Plus internal flash interleaving */
	ofs >>= doc->interleave;

	switch (numbytes) {
	case 1:
		/* Send single byte, bits 0-7. */
		WriteDOC(ofs & 0xff, docptr, Mplus_FlashAddress);
		break;
	case 2:
		/* Send bits 9-16 followed by 17-23 */
		WriteDOC((ofs >> 9)  & 0xff, docptr, Mplus_FlashAddress);
		WriteDOC((ofs >> 17) & 0xff, docptr, Mplus_FlashAddress);
		break;
	case 3:
		/* Send 0-7, 9-16, then 17-23 */
		WriteDOC(ofs & 0xff, docptr, Mplus_FlashAddress);
		WriteDOC((ofs >> 9)  & 0xff, docptr, Mplus_FlashAddress);
		WriteDOC((ofs >> 17) & 0xff, docptr, Mplus_FlashAddress);
		break;
	default:
		return;
	}

	WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
	WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
}

/* DoC_SelectChip: Select a given flash chip within the current floor */
static int DoC_SelectChip(void __iomem * docptr, int chip)
{
	/* No choice for flash chip on Millennium Plus */
	return 0;
}

/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
static int DoC_SelectFloor(void __iomem * docptr, int floor)
{
	WriteDOC((floor & 0x3), docptr, Mplus_DeviceSelect);
	return 0;
}

/*
 * Translate the given offset into the appropriate command and offset.
 * This does the mapping using the 16bit interleave layout defined by
 * M-Systems, and looks like this for a sector pair:
 *  +-----------+-------+-------+-------+--------------+---------+-----------+
 *  | 0 --- 511 |512-517|518-519|520-521| 522 --- 1033 |1034-1039|1040 - 1055|
 *  +-----------+-------+-------+-------+--------------+---------+-----------+
 *  | Data 0    | ECC 0 |Flags0 |Flags1 | Data 1       |ECC 1    | OOB 1 + 2 |
 *  +-----------+-------+-------+-------+--------------+---------+-----------+
 */
/* FIXME: This lives in INFTL not here. Other users of flash devices
   may not want it */
static unsigned int DoC_GetDataOffset(struct mtd_info *mtd, loff_t *from)
{
	struct DiskOnChip *this = mtd->priv;

	if (this->interleave) {
		unsigned int ofs = *from & 0x3ff;
		unsigned int cmd;

		if (ofs < 512) {
			cmd = NAND_CMD_READ0;
			ofs &= 0x1ff;
		} else if (ofs < 1014) {
			cmd = NAND_CMD_READ1;
			ofs = (ofs & 0x1ff) + 10;
		} else {
			cmd = NAND_CMD_READOOB;
			ofs = ofs - 1014;
		}

		*from = (*from & ~0x3ff) | ofs;
		return cmd;
	} else {
		/* No interleave */
		if ((*from) & 0x100)
			return NAND_CMD_READ1;
		return NAND_CMD_READ0;
	}
}

static unsigned int DoC_GetECCOffset(struct mtd_info *mtd, loff_t *from)
{
	unsigned int ofs, cmd;

	if (*from & 0x200) {
		cmd = NAND_CMD_READOOB;
		ofs = 10 + (*from & 0xf);
	} else {
		cmd = NAND_CMD_READ1;
		ofs = (*from & 0xf);
	}

	*from = (*from & ~0x3ff) | ofs;
	return cmd;
}

static unsigned int DoC_GetFlagsOffset(struct mtd_info *mtd, loff_t *from)
{
	unsigned int ofs, cmd;

	cmd = NAND_CMD_READ1;
	ofs = (*from & 0x200) ? 8 : 6;
	*from = (*from & ~0x3ff) | ofs;
	return cmd;
}

static unsigned int DoC_GetHdrOffset(struct mtd_info *mtd, loff_t *from)
{
	unsigned int ofs, cmd;

	cmd = NAND_CMD_READOOB;
	ofs = (*from & 0x200) ? 24 : 16;
	*from = (*from & ~0x3ff) | ofs;
	return cmd;
}

static inline void MemReadDOC(void __iomem * docptr, unsigned char *buf, int len)
{
#ifndef USE_MEMCPY
	int i;
	for (i = 0; i < len; i++)
		buf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
#else
	memcpy_fromio(buf, docptr + DoC_Mil_CDSN_IO, len);
#endif
}

static inline void MemWriteDOC(void __iomem * docptr, unsigned char *buf, int len)
{
#ifndef USE_MEMCPY
	int i;
	for (i = 0; i < len; i++)
		WriteDOC(buf[i], docptr, Mil_CDSN_IO + i);
#else
	memcpy_toio(docptr + DoC_Mil_CDSN_IO, buf, len);
#endif
}

/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
{
	int mfr, id, i, j;
	volatile char dummy;
	void __iomem * docptr = doc->virtadr;

	/* Page in the required floor/chip */
	DoC_SelectFloor(docptr, floor);
	DoC_SelectChip(docptr, chip);

	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
	WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);

	/* Reset the chip, see Software Requirement 11.4 item 1. */
	DoC_Command(docptr, NAND_CMD_RESET, 0);
	DoC_WaitReady(docptr);

	/* Read the NAND chip ID: 1. Send ReadID command */
	DoC_Command(docptr, NAND_CMD_READID, 0);

	/* Read the NAND chip ID: 2. Send address byte zero */
	DoC_Address(doc, 1, 0x00, 0, 0x00);

	WriteDOC(0, docptr, Mplus_FlashControl);
	DoC_WaitReady(docptr);

	/* Read the manufacturer and device id codes of the flash device through
	   CDSN IO register see Software Requirement 11.4 item 5.*/
	dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
	dummy = ReadDOC(docptr, Mplus_ReadPipeInit);

	mfr = ReadDOC(docptr, Mil_CDSN_IO);
	if (doc->interleave)
		dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */

	id  = ReadDOC(docptr, Mil_CDSN_IO);
	if (doc->interleave)
		dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */

	dummy = ReadDOC(docptr, Mplus_LastDataRead);
	dummy = ReadDOC(docptr, Mplus_LastDataRead);

	/* Disable flash internally */
	WriteDOC(0, docptr, Mplus_FlashSelect);

	/* No response - return failure */
	if (mfr == 0xff || mfr == 0)
		return 0;

	for (i = 0; nand_flash_ids[i].name != NULL; i++) {
		if (id == nand_flash_ids[i].id) {
			/* Try to identify manufacturer */
			for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
				if (nand_manuf_ids[j].id == mfr)
					break;
			}
			printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, "
			       "Chip ID: %2.2X (%s:%s)\n", mfr, id,
			       nand_manuf_ids[j].name, nand_flash_ids[i].name);
			doc->mfr = mfr;
			doc->id = id;
			doc->chipshift = ffs((nand_flash_ids[i].chipsize << 20)) - 1;
			doc->erasesize = nand_flash_ids[i].erasesize << doc->interleave;
			break;
		}
	}

	if (nand_flash_ids[i].name == NULL)
		return 0;
	return 1;
}

/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
static void DoC_ScanChips(struct DiskOnChip *this)
{
	int floor, chip;
	int numchips[MAX_FLOORS_MPLUS];
	int ret;

	this->numchips = 0;
	this->mfr = 0;
	this->id = 0;

	/* Work out the intended interleave setting */
	this->interleave = 0;
	if (this->ChipID == DOC_ChipID_DocMilPlus32)
		this->interleave = 1;

	/* Check the ASIC agrees */
	if ( (this->interleave << 2) !=
	     (ReadDOC(this->virtadr, Mplus_Configuration) & 4)) {
		u_char conf = ReadDOC(this->virtadr, Mplus_Configuration);
		printk(KERN_NOTICE "Setting DiskOnChip Millennium Plus interleave to %s\n",
		       this->interleave?"on (16-bit)":"off (8-bit)");
		conf ^= 4;
		WriteDOC(conf, this->virtadr, Mplus_Configuration);
	}

	/* For each floor, find the number of valid chips it contains */
	for (floor = 0,ret = 1; floor < MAX_FLOORS_MPLUS; floor++) {
		numchips[floor] = 0;
		for (chip = 0; chip < MAX_CHIPS_MPLUS && ret != 0; chip++) {
			ret = DoC_IdentChip(this, floor, chip);
			if (ret) {
				numchips[floor]++;
				this->numchips++;
			}
		}
	}
	/* If there are none at all that we recognise, bail */
	if (!this->numchips) {
		printk("No flash chips recognised.\n");
		return;
	}

	/* Allocate an array to hold the information for each chip */
	this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL);
	if (!this->chips){
		printk("MTD: No memory for allocating chip info structures\n");
		return;
	}

	/* Fill out the chip array with {floor, chipno} for each
	 * detected chip in the device. */
	for (floor = 0, ret = 0; floor < MAX_FLOORS_MPLUS; floor++) {
		for (chip = 0 ; chip < numchips[floor] ; chip++) {
			this->chips[ret].floor = floor;
			this->chips[ret].chip = chip;
			this->chips[ret].curadr = 0;
			this->chips[ret].curmode = 0x50;
			ret++;
		}
	}

	/* Calculate and print the total size of the device */
	this->totlen = this->numchips * (1 << this->chipshift);
	printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld MiB\n",
	       this->numchips ,this->totlen >> 20);
}

static int DoCMilPlus_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
{
	int tmp1, tmp2, retval;

	if (doc1->physadr == doc2->physadr)
		return 1;

	/* Use the alias resolution register which was set aside for this
	 * purpose. If it's value is the same on both chips, they might
	 * be the same chip, and we write to one and check for a change in
	 * the other. It's unclear if this register is usuable in the
	 * DoC 2000 (it's in the Millennium docs), but it seems to work. */
	tmp1 = ReadDOC(doc1->virtadr, Mplus_AliasResolution);
	tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
	if (tmp1 != tmp2)
		return 0;

	WriteDOC((tmp1+1) % 0xff, doc1->virtadr, Mplus_AliasResolution);
	tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
	if (tmp2 == (tmp1+1) % 0xff)
		retval = 1;
	else
		retval = 0;

	/* Restore register contents.  May not be necessary, but do it just to
	 * be safe. */
	WriteDOC(tmp1, doc1->virtadr, Mplus_AliasResolution);

	return retval;
}

/* This routine is found from the docprobe code by symbol_get(),
 * which will bump the use count of this module. */
void DoCMilPlus_init(struct mtd_info *mtd)
{
	struct DiskOnChip *this = mtd->priv;
	struct DiskOnChip *old = NULL;

	/* We must avoid being called twice for the same device. */
	if (docmilpluslist)
		old = docmilpluslist->priv;

	while (old) {
		if (DoCMilPlus_is_alias(this, old)) {
			printk(KERN_NOTICE "Ignoring DiskOnChip Millennium "
				"Plus at 0x%lX - already configured\n",
				this->physadr);
			iounmap(this->virtadr);
			kfree(mtd);
			return;
		}
		if (old->nextdoc)
			old = old->nextdoc->priv;
		else
			old = NULL;
	}

	mtd->name = "DiskOnChip Millennium Plus";
	printk(KERN_NOTICE "DiskOnChip Millennium Plus found at "
		"address 0x%lX\n", this->physadr);

	mtd->type = MTD_NANDFLASH;
	mtd->flags = MTD_CAP_NANDFLASH;
	mtd->size = 0;

	mtd->erasesize = 0;
	mtd->writesize = 512;
	mtd->oobsize = 16;
	mtd->owner = THIS_MODULE;
	mtd->erase = doc_erase;
	mtd->point = NULL;
	mtd->unpoint = NULL;
	mtd->read = doc_read;
	mtd->write = doc_write;
	mtd->read_oob = doc_read_oob;
	mtd->write_oob = doc_write_oob;
	mtd->sync = NULL;

	this->totlen = 0;
	this->numchips = 0;
	this->curfloor = -1;
	this->curchip = -1;

	/* Ident all the chips present. */
	DoC_ScanChips(this);

	if (!this->totlen) {
		kfree(mtd);
		iounmap(this->virtadr);
	} else {
		this->nextdoc = docmilpluslist;
		docmilpluslist = mtd;
		mtd->size  = this->totlen;
		mtd->erasesize = this->erasesize;
		add_mtd_device(mtd);
		return;
	}
}
EXPORT_SYMBOL_GPL(DoCMilPlus_init);

#if 0
static int doc_dumpblk(struct mtd_info *mtd, loff_t from)
{
	int i;
	loff_t fofs;
	struct DiskOnChip *this = mtd->priv;
	void __iomem * docptr = this->virtadr;
	struct Nand *mychip = &this->chips[from >> (this->chipshift)];
	unsigned char *bp, buf[1056];
	char c[32];

	from &= ~0x3ff;

	/* Don't allow read past end of device */
	if (from >= this->totlen)
		return -EINVAL;

	DoC_CheckASIC(docptr);

	/* Find the chip which is to be used and select it */
	if (this->curfloor != mychip->floor) {
		DoC_SelectFloor(docptr, mychip->floor);
		DoC_SelectChip(docptr, mychip->chip);
	} else if (this->curchip != mychip->chip) {
		DoC_SelectChip(docptr, mychip->chip);
	}
	this->curfloor = mychip->floor;
	this->curchip = mychip->chip;

	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
	WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);

	/* Reset the chip, see Software Requirement 11.4 item 1. */
	DoC_Command(docptr, NAND_CMD_RESET, 0);
	DoC_WaitReady(docptr);

	fofs = from;
	DoC_Command(docptr, DoC_GetDataOffset(mtd, &fofs), 0);
	DoC_Address(this, 3, fofs, 0, 0x00);
	WriteDOC(0, docptr, Mplus_FlashControl);
	DoC_WaitReady(docptr);

	/* disable the ECC engine */
	WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);

	ReadDOC(docptr, Mplus_ReadPipeInit);
	ReadDOC(docptr, Mplus_ReadPipeInit);

	/* Read the data via the internal pipeline through CDSN IO
	   register, see Pipelined Read Operations 11.3 */
	MemReadDOC(docptr, buf, 1054);
	buf[1054] = ReadDOC(docptr, Mplus_LastDataRead);
	buf[1055] = ReadDOC(docptr, Mplus_LastDataRead);

	memset(&c[0], 0, sizeof(c));
	printk("DUMP OFFSET=%x:\n", (int)from);

        for (i = 0, bp = &buf[0]; (i < 1056); i++) {
                if ((i % 16) == 0)
                        printk("%08x: ", i);
                printk(" %02x", *bp);
                c[(i & 0xf)] = ((*bp >= 0x20) && (*bp <= 0x7f)) ? *bp : '.';
                bp++;
                if (((i + 1) % 16) == 0)
                        printk("    %s\n", c);
        }
	printk("\n");

	/* Disable flash internally */
	WriteDOC(0, docptr, Mplus_FlashSelect);

	return 0;
}
#endif

static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
		    size_t *retlen, u_char *buf)
{
	int ret, i;
	volatile char dummy;
	loff_t fofs;
	unsigned char syndrome[6], eccbuf[6];
	struct DiskOnChip *this = mtd->priv;
	void __iomem * docptr = this->virtadr;
	struct Nand *mychip = &this->chips[from >> (this->chipshift)];

	/* Don't allow read past end of device */
	if (from >= this->totlen)
		return -EINVAL;

	/* Don't allow a single read to cross a 512-byte block boundary */
	if (from + len > ((from | 0x1ff) + 1))
		len = ((from | 0x1ff) + 1) - from;

	DoC_CheckASIC(docptr);

	/* Find the chip which is to be used and select it */
	if (this->curfloor != mychip->floor) {
		DoC_SelectFloor(docptr, mychip->floor);
		DoC_SelectChip(docptr, mychip->chip);
	} else if (this->curchip != mychip->chip) {
		DoC_SelectChip(docptr, mychip->chip);
	}
	this->curfloor = mychip->floor;
	this->curchip = mychip->chip;

	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
	WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);

	/* Reset the chip, see Software Requirement 11.4 item 1. */
	DoC_Command(docptr, NAND_CMD_RESET, 0);
	DoC_WaitReady(docptr);

	fofs = from;
	DoC_Command(docptr, DoC_GetDataOffset(mtd, &fofs), 0);
	DoC_Address(this, 3, fofs, 0, 0x00);
	WriteDOC(0, docptr, Mplus_FlashControl);
	DoC_WaitReady(docptr);

	/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
	WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
	WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);

	/* Let the caller know we completed it */
	*retlen = len;
	ret = 0;

	ReadDOC(docptr, Mplus_ReadPipeInit);
	ReadDOC(docptr, Mplus_ReadPipeInit);

	/* Read the data via the internal pipeline through CDSN IO
	   register, see Pipelined Read Operations 11.3 */
	MemReadDOC(docptr, buf, len);

	/* Read the ECC data following raw data */
	MemReadDOC(docptr, eccbuf, 4);
	eccbuf[4] = ReadDOC(docptr, Mplus_LastDataRead);
	eccbuf[5] = ReadDOC(docptr, Mplus_LastDataRead);

	/* Flush the pipeline */
	dummy = ReadDOC(docptr, Mplus_ECCConf);
	dummy = ReadDOC(docptr, Mplus_ECCConf);

	/* Check the ECC Status */
	if (ReadDOC(docptr, Mplus_ECCConf) & 0x80) {
		int nb_errors;
		/* There was an ECC error */
#ifdef ECC_DEBUG
		printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
#endif
		/* Read the ECC syndrom through the DiskOnChip ECC logic.
		   These syndrome will be all ZERO when there is no error */
		for (i = 0; i < 6; i++)
			syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);

		nb_errors = doc_decode_ecc(buf, syndrome);
#ifdef ECC_DEBUG
		printk("ECC Errors corrected: %x\n", nb_errors);
#endif
		if (nb_errors < 0) {
			/* We return error, but have actually done the
			   read. Not that this can be told to user-space, via
			   sys_read(), but at least MTD-aware stuff can know
			   about it by checking *retlen */
#ifdef ECC_DEBUG
			printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n",
				__FILE__, __LINE__, (int)from);
			printk("        syndrome= %02x:%02x:%02x:%02x:%02x:"
				"%02x\n",
				syndrome[0], syndrome[1], syndrome[2],
				syndrome[3], syndrome[4], syndrome[5]);
			printk("          eccbuf= %02x:%02x:%02x:%02x:%02x:"
				"%02x\n",
				eccbuf[0], eccbuf[1], eccbuf[2],
				eccbuf[3], eccbuf[4], eccbuf[5]);
#endif
				ret = -EIO;
		}
	}

#ifdef PSYCHO_DEBUG
	printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
	       (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
	       eccbuf[4], eccbuf[5]);
#endif
	/* disable the ECC engine */
	WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf);

	/* Disable flash internally */
	WriteDOC(0, docptr, Mplus_FlashSelect);

	return ret;
}

static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
		     size_t *retlen, const u_char *buf)
{
	int i, before, ret = 0;
	loff_t fto;
	volatile char dummy;
	char eccbuf[6];
	struct DiskOnChip *this = mtd->priv;
	void __iomem * docptr = this->virtadr;
	struct Nand *mychip = &this->chips[to >> (this->chipshift)];

	/* Don't allow write past end of device */
	if (to >= this->totlen)
		return -EINVAL;

	/* Don't allow writes which aren't exactly one block (512 bytes) */
	if ((to & 0x1ff) || (len != 0x200))
		return -EINVAL;

	/* Determine position of OOB flags, before or after data */
	before = (this->interleave && (to & 0x200));

	DoC_CheckASIC(docptr);

	/* Find the chip which is to be used and select it */
	if (this->curfloor != mychip->floor) {
		DoC_SelectFloor(docptr, mychip->floor);
		DoC_SelectChip(docptr, mychip->chip);
	} else if (this->curchip != mychip->chip) {
		DoC_SelectChip(docptr, mychip->chip);
	}
	this->curfloor = mychip->floor;
	this->curchip = mychip->chip;

	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
	WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);

	/* Reset the chip, see Software Requirement 11.4 item 1. */
	DoC_Command(docptr, NAND_CMD_RESET, 0);
	DoC_WaitReady(docptr);

	/* Set device to appropriate plane of flash */
	fto = to;
	WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd);

	/* On interleaved devices the flags for 2nd half 512 are before data */
	if (before)
		fto -= 2;

	/* issue the Serial Data In command to initial the Page Program process */
	DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
	DoC_Address(this, 3, fto, 0x00, 0x00);

	/* Disable the ECC engine */
	WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);

	if (before) {
		/* Write the block status BLOCK_USED (0x5555) */
		WriteDOC(0x55, docptr, Mil_CDSN_IO);
		WriteDOC(0x55, docptr, Mil_CDSN_IO);
	}

	/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
	WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);

	MemWriteDOC(docptr, (unsigned char *) buf, len);

	/* Write ECC data to flash, the ECC info is generated by
	   the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */
	DoC_Delay(docptr, 3);

	/* Read the ECC data through the DiskOnChip ECC logic */
	for (i = 0; i < 6; i++)
		eccbuf[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);

	/* disable the ECC engine */
	WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);

	/* Write the ECC data to flash */
	MemWriteDOC(docptr, eccbuf, 6);

	if (!before) {
		/* Write the block status BLOCK_USED (0x5555) */
		WriteDOC(0x55, docptr, Mil_CDSN_IO+6);
		WriteDOC(0x55, docptr, Mil_CDSN_IO+7);
	}

#ifdef PSYCHO_DEBUG
	printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
	       (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
	       eccbuf[4], eccbuf[5]);
#endif

	WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
	WriteDOC(0x00, docptr, Mplus_WritePipeTerm);

	/* Commit the Page Program command and wait for ready
	   see Software Requirement 11.4 item 1.*/
	DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
	DoC_WaitReady(docptr);

	/* Read the status of the flash device through CDSN IO register
	   see Software Requirement 11.4 item 5.*/
	DoC_Command(docptr, NAND_CMD_STATUS, 0);
	dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
	dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
	DoC_Delay(docptr, 2);
	if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
		printk("MTD: Error 0x%x programming at 0x%x\n", dummy, (int)to);
		/* Error in programming
		   FIXME: implement Bad Block Replacement (in nftl.c ??) */
		*retlen = 0;
		ret = -EIO;
	}
	dummy = ReadDOC(docptr, Mplus_LastDataRead);

	/* Disable flash internally */
	WriteDOC(0, docptr, Mplus_FlashSelect);

	/* Let the caller know we completed it */
	*retlen = len;

	return ret;
}

static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
			struct mtd_oob_ops *ops)
{
	loff_t fofs, base;
	struct DiskOnChip *this = mtd->priv;
	void __iomem * docptr = this->virtadr;
	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
	size_t i, size, got, want;
	uint8_t *buf = ops->oobbuf;
	size_t len = ops->len;

	BUG_ON(ops->mode != MTD_OOB_PLACE);

	ofs += ops->ooboffs;

	DoC_CheckASIC(docptr);

	/* Find the chip which is to be used and select it */
	if (this->curfloor != mychip->floor) {
		DoC_SelectFloor(docptr, mychip->floor);
		DoC_SelectChip(docptr, mychip->chip);
	} else if (this->curchip != mychip->chip) {
		DoC_SelectChip(docptr, mychip->chip);
	}
	this->curfloor = mychip->floor;
	this->curchip = mychip->chip;

	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
	WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);

	/* disable the ECC engine */
	WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
	DoC_WaitReady(docptr);

	/* Maximum of 16 bytes in the OOB region, so limit read to that */
	if (len > 16)
		len = 16;
	got = 0;
	want = len;

	for (i = 0; ((i < 3) && (want > 0)); i++) {
		/* Figure out which region we are accessing... */
		fofs = ofs;
		base = ofs & 0xf;
		if (!this->interleave) {
			DoC_Command(docptr, NAND_CMD_READOOB, 0);
			size = 16 - base;
		} else if (base < 6) {
			DoC_Command(docptr, DoC_GetECCOffset(mtd, &fofs), 0);
			size = 6 - base;
		} else if (base < 8) {
			DoC_Command(docptr, DoC_GetFlagsOffset(mtd, &fofs), 0);
			size = 8 - base;
		} else {
			DoC_Command(docptr, DoC_GetHdrOffset(mtd, &fofs), 0);
			size = 16 - base;
		}
		if (size > want)
			size = want;

		/* Issue read command */
		DoC_Address(this, 3, fofs, 0, 0x00);
		WriteDOC(0, docptr, Mplus_FlashControl);
		DoC_WaitReady(docptr);

		ReadDOC(docptr, Mplus_ReadPipeInit);
		ReadDOC(docptr, Mplus_ReadPipeInit);
		MemReadDOC(docptr, &buf[got], size - 2);
		buf[got + size - 2] = ReadDOC(docptr, Mplus_LastDataRead);
		buf[got + size - 1] = ReadDOC(docptr, Mplus_LastDataRead);

		ofs += size;
		got += size;
		want -= size;
	}

	/* Disable flash internally */
	WriteDOC(0, docptr, Mplus_FlashSelect);

	ops->retlen = len;
	return 0;
}

static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
			 struct mtd_oob_ops *ops)
{
	volatile char dummy;
	loff_t fofs, base;
	struct DiskOnChip *this = mtd->priv;
	void __iomem * docptr = this->virtadr;
	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
	size_t i, size, got, want;
	int ret = 0;
	uint8_t *buf = ops->oobbuf;
	size_t len = ops->len;

	BUG_ON(ops->mode != MTD_OOB_PLACE);

	ofs += ops->ooboffs;

	DoC_CheckASIC(docptr);

	/* Find the chip which is to be used and select it */
	if (this->curfloor != mychip->floor) {
		DoC_SelectFloor(docptr, mychip->floor);
		DoC_SelectChip(docptr, mychip->chip);
	} else if (this->curchip != mychip->chip) {
		DoC_SelectChip(docptr, mychip->chip);
	}
	this->curfloor = mychip->floor;
	this->curchip = mychip->chip;

	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
	WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);


	/* Maximum of 16 bytes in the OOB region, so limit write to that */
	if (len > 16)
		len = 16;
	got = 0;
	want = len;

	for (i = 0; ((i < 3) && (want > 0)); i++) {
		/* Reset the chip, see Software Requirement 11.4 item 1. */
		DoC_Command(docptr, NAND_CMD_RESET, 0);
		DoC_WaitReady(docptr);

		/* Figure out which region we are accessing... */
		fofs = ofs;
		base = ofs & 0x0f;
		if (!this->interleave) {
			WriteDOC(NAND_CMD_READOOB, docptr, Mplus_FlashCmd);
			size = 16 - base;
		} else if (base < 6) {
			WriteDOC(DoC_GetECCOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
			size = 6 - base;
		} else if (base < 8) {
			WriteDOC(DoC_GetFlagsOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
			size = 8 - base;
		} else {
			WriteDOC(DoC_GetHdrOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
			size = 16 - base;
		}
		if (size > want)
			size = want;

		/* Issue the Serial Data In command to initial the Page Program process */
		DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
		DoC_Address(this, 3, fofs, 0, 0x00);

		/* Disable the ECC engine */
		WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);

		/* Write the data via the internal pipeline through CDSN IO
		   register, see Pipelined Write Operations 11.2 */
		MemWriteDOC(docptr, (unsigned char *) &buf[got], size);
		WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
		WriteDOC(0x00, docptr, Mplus_WritePipeTerm);

		/* Commit the Page Program command and wait for ready
	 	   see Software Requirement 11.4 item 1.*/
		DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
		DoC_WaitReady(docptr);

		/* Read the status of the flash device through CDSN IO register
		   see Software Requirement 11.4 item 5.*/
		DoC_Command(docptr, NAND_CMD_STATUS, 0x00);
		dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
		dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
		DoC_Delay(docptr, 2);
		if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
			printk("MTD: Error 0x%x programming oob at 0x%x\n",
				dummy, (int)ofs);
			/* FIXME: implement Bad Block Replacement */
			ops->retlen = 0;
			ret = -EIO;
		}
		dummy = ReadDOC(docptr, Mplus_LastDataRead);

		ofs += size;
		got += size;
		want -= size;
	}

	/* Disable flash internally */
	WriteDOC(0, docptr, Mplus_FlashSelect);

	ops->retlen = len;
	return ret;
}

int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
{
	volatile char dummy;
	struct DiskOnChip *this = mtd->priv;
	__u32 ofs = instr->addr;
	__u32 len = instr->len;
	void __iomem * docptr = this->virtadr;
	struct Nand *mychip = &this->chips[ofs >> this->chipshift];

	DoC_CheckASIC(docptr);

	if (len != mtd->erasesize)
		printk(KERN_WARNING "MTD: Erase not right size (%x != %x)n",
		       len, mtd->erasesize);

	/* Find the chip which is to be used and select it */
	if (this->curfloor != mychip->floor) {
		DoC_SelectFloor(docptr, mychip->floor);
		DoC_SelectChip(docptr, mychip->chip);
	} else if (this->curchip != mychip->chip) {
		DoC_SelectChip(docptr, mychip->chip);
	}
	this->curfloor = mychip->floor;
	this->curchip = mychip->chip;

	instr->state = MTD_ERASE_PENDING;

	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
	WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);

	DoC_Command(docptr, NAND_CMD_RESET, 0x00);
	DoC_WaitReady(docptr);

	DoC_Command(docptr, NAND_CMD_ERASE1, 0);
	DoC_Address(this, 2, ofs, 0, 0x00);
	DoC_Command(docptr, NAND_CMD_ERASE2, 0);
	DoC_WaitReady(docptr);
	instr->state = MTD_ERASING;

	/* Read the status of the flash device through CDSN IO register
	   see Software Requirement 11.4 item 5. */
	DoC_Command(docptr, NAND_CMD_STATUS, 0);
	dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
	dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
	if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
		printk("MTD: Error 0x%x erasing at 0x%x\n", dummy, ofs);
		/* FIXME: implement Bad Block Replacement (in nftl.c ??) */
		instr->state = MTD_ERASE_FAILED;
	} else {
		instr->state = MTD_ERASE_DONE;
	}
	dummy = ReadDOC(docptr, Mplus_LastDataRead);

	/* Disable flash internally */
	WriteDOC(0, docptr, Mplus_FlashSelect);

	mtd_erase_callback(instr);

	return 0;
}

/****************************************************************************
 *
 * Module stuff
 *
 ****************************************************************************/

static void __exit cleanup_doc2001plus(void)
{
	struct mtd_info *mtd;
	struct DiskOnChip *this;

	while ((mtd=docmilpluslist)) {
		this = mtd->priv;
		docmilpluslist = this->nextdoc;

		del_mtd_device(mtd);

		iounmap(this->virtadr);
		kfree(this->chips);
		kfree(mtd);
	}
}

module_exit(cleanup_doc2001plus);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com> et al.");
MODULE_DESCRIPTION("Driver for DiskOnChip Millennium Plus");
