/*
 * (C) 2006 Denx
 * Driver for NAND support, Rick Bronson
 * borrowed heavily from:
 * (c) 1999 Machine Vision Holdings, Inc.
 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
 *
 * Added 16-bit nand support
 * (C) 2004 Texas Instruments
 */

#include <common.h>
#include <command.h>
#include <malloc.h>
#include <asm/io.h>
#include <watchdog.h>
#include <linux/mtd/nand_legacy.h>
#include <linux/mtd/nand_ids.h>
#include <jffs2/jffs2.h>

#error Legacy NAND is deprecated.  Please convert to the current NAND interface.
#error This code will be removed outright in the next release.

#ifdef CONFIG_OMAP1510
void archflashwp(void *archdata, int wp);
#endif

#define ROUND_DOWN(value,boundary)      ((value) & (~((boundary)-1)))

#undef	PSYCHO_DEBUG
#undef	NAND_DEBUG

/* ****************** WARNING *********************
 * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will
 * erase (or at least attempt to erase) blocks that are marked
 * bad. This can be very handy if you are _sure_ that the block
 * is OK, say because you marked a good block bad to test bad
 * block handling and you are done testing, or if you have
 * accidentally marked blocks bad.
 *
 * Erasing factory marked bad blocks is a _bad_ idea. If the
 * erase succeeds there is no reliable way to find them again,
 * and attempting to program or erase bad blocks can affect
 * the data in _other_ (good) blocks.
 */
#define	 ALLOW_ERASE_BAD_DEBUG 0

#define CONFIG_MTD_NAND_ECC  /* enable ECC */
#define CONFIG_MTD_NAND_ECC_JFFS2

/* bits for nand_legacy_rw() `cmd'; or together as needed */
#define NANDRW_READ	0x01
#define NANDRW_WRITE	0x00
#define NANDRW_JFFS2	0x02
#define NANDRW_JFFS2_SKIP	0x04


/*
 * Exported variables etc.
 */

/* Definition of the out of band configuration structure */
struct nand_oob_config {
	/* position of ECC bytes inside oob */
	int ecc_pos[6];
	/* position of  bad blk flag inside oob -1 = inactive */
	int badblock_pos;
	/* position of ECC valid flag inside oob -1 = inactive */
	int eccvalid_pos;
} oob_config = { {0}, 0, 0};

struct nand_chip nand_dev_desc[CONFIG_SYS_MAX_NAND_DEVICE] = {{0}};

int curr_device = -1; /* Current NAND Device */


/*
 * Exported functionss
 */
int nand_legacy_erase(struct nand_chip* nand, size_t ofs,
		     size_t len, int clean);
int nand_legacy_rw(struct nand_chip* nand, int cmd,
		  size_t start, size_t len,
		  size_t * retlen, u_char * buf);
void nand_print(struct nand_chip *nand);
void nand_print_bad(struct nand_chip *nand);
int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
		 size_t * retlen, u_char * buf);
int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
		 size_t * retlen, const u_char * buf);

/*
 * Internals
 */
static int NanD_WaitReady(struct nand_chip *nand, int ale_wait);
static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
		 size_t * retlen, u_char *buf, u_char *ecc_code);
static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
			   size_t * retlen, const u_char * buf,
			   u_char * ecc_code);
#ifdef CONFIG_MTD_NAND_ECC
static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc);
static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code);
#endif


/*
 *
 * Function definitions
 *
 */

/* returns 0 if block containing pos is OK:
 *		valid erase block and
 *		not marked bad, or no bad mark position is specified
 * returns 1 if marked bad or otherwise invalid
 */
static int check_block (struct nand_chip *nand, unsigned long pos)
{
	size_t retlen;
	uint8_t oob_data;
	uint16_t oob_data16[6];
	int page0 = pos & (-nand->erasesize);
	int page1 = page0 + nand->oobblock;
	int badpos = oob_config.badblock_pos;

	if (pos >= nand->totlen)
		return 1;

	if (badpos < 0)
		return 0;	/* no way to check, assume OK */

	if (nand->bus16) {
		if (nand_read_oob(nand, (page0 + 0), 12, &retlen, (uint8_t *)oob_data16)
		    || (oob_data16[2] & 0xff00) != 0xff00)
			return 1;
		if (nand_read_oob(nand, (page1 + 0), 12, &retlen, (uint8_t *)oob_data16)
		    || (oob_data16[2] & 0xff00) != 0xff00)
			return 1;
	} else {
		/* Note - bad block marker can be on first or second page */
		if (nand_read_oob(nand, page0 + badpos, 1, &retlen, (unsigned char *)&oob_data)
		    || oob_data != 0xff
		    || nand_read_oob (nand, page1 + badpos, 1, &retlen, (unsigned char *)&oob_data)
		    || oob_data != 0xff)
			return 1;
	}

	return 0;
}

/* print bad blocks in NAND flash */
void nand_print_bad(struct nand_chip* nand)
{
	unsigned long pos;

	for (pos = 0; pos < nand->totlen; pos += nand->erasesize) {
		if (check_block(nand, pos))
			printf(" 0x%8.8lx\n", pos);
	}
	puts("\n");
}

/* cmd: 0: NANDRW_WRITE			write, fail on bad block
 *	1: NANDRW_READ			read, fail on bad block
 *	2: NANDRW_WRITE | NANDRW_JFFS2	write, skip bad blocks
 *	3: NANDRW_READ | NANDRW_JFFS2	read, data all 0xff for bad blocks
 *      7: NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP read, skip bad blocks
 */
int nand_legacy_rw (struct nand_chip* nand, int cmd,
		   size_t start, size_t len,
		   size_t * retlen, u_char * buf)
{
	int ret = 0, n, total = 0;
	char eccbuf[6];
	/* eblk (once set) is the start of the erase block containing the
	 * data being processed.
	 */
	unsigned long eblk = ~0;	/* force mismatch on first pass */
	unsigned long erasesize = nand->erasesize;

	while (len) {
		if ((start & (-erasesize)) != eblk) {
			/* have crossed into new erase block, deal with
			 * it if it is sure marked bad.
			 */
			eblk = start & (-erasesize); /* start of block */
			if (check_block(nand, eblk)) {
				if (cmd == (NANDRW_READ | NANDRW_JFFS2)) {
					while (len > 0 &&
					       start - eblk < erasesize) {
						*(buf++) = 0xff;
						++start;
						++total;
						--len;
					}
					continue;
				} else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) {
					start += erasesize;
					continue;
				} else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) {
					/* skip bad block */
					start += erasesize;
					continue;
				} else {
					ret = 1;
					break;
				}
			}
		}
		/* The ECC will not be calculated correctly if
		   less than 512 is written or read */
		/* Is request at least 512 bytes AND it starts on a proper boundry */
		if((start != ROUND_DOWN(start, 0x200)) || (len < 0x200))
			printf("Warning block writes should be at least 512 bytes and start on a 512 byte boundry\n");

		if (cmd & NANDRW_READ) {
			ret = nand_read_ecc(nand, start,
					   min(len, eblk + erasesize - start),
					   (size_t *)&n, (u_char*)buf, (u_char *)eccbuf);
		} else {
			ret = nand_write_ecc(nand, start,
					    min(len, eblk + erasesize - start),
					    (size_t *)&n, (u_char*)buf, (u_char *)eccbuf);
		}

		if (ret)
			break;

		start  += n;
		buf   += n;
		total += n;
		len   -= n;
	}
	if (retlen)
		*retlen = total;

	return ret;
}

void nand_print(struct nand_chip *nand)
{
	if (nand->numchips > 1) {
		printf("%s at 0x%lx,\n"
		       "\t  %d chips %s, size %d MB, \n"
		       "\t  total size %ld MB, sector size %ld kB\n",
		       nand->name, nand->IO_ADDR, nand->numchips,
		       nand->chips_name, 1 << (nand->chipshift - 20),
		       nand->totlen >> 20, nand->erasesize >> 10);
	}
	else {
		printf("%s at 0x%lx (", nand->chips_name, nand->IO_ADDR);
		print_size(nand->totlen, ", ");
		print_size(nand->erasesize, " sector)\n");
	}
}

/* ------------------------------------------------------------------------- */

static int NanD_WaitReady(struct nand_chip *nand, int ale_wait)
{
	/* This is inline, to optimise the common case, where it's ready instantly */
	int ret = 0;

#ifdef NAND_NO_RB	/* in config file, shorter delays currently wrap accesses */
	if(ale_wait)
		NAND_WAIT_READY(nand);	/* do the worst case 25us wait */
	else
		udelay(10);
#else	/* has functional r/b signal */
	NAND_WAIT_READY(nand);
#endif
	return ret;
}

/* NanD_Command: Send a flash command to the flash chip */

static inline int NanD_Command(struct nand_chip *nand, unsigned char command)
{
	unsigned long nandptr = nand->IO_ADDR;

	/* Assert the CLE (Command Latch Enable) line to the flash chip */
	NAND_CTL_SETCLE(nandptr);

	/* Send the command */
	WRITE_NAND_COMMAND(command, nandptr);

	/* Lower the CLE line */
	NAND_CTL_CLRCLE(nandptr);

#ifdef NAND_NO_RB
	if(command == NAND_CMD_RESET){
		u_char ret_val;
		NanD_Command(nand, NAND_CMD_STATUS);
		do {
			ret_val = READ_NAND(nandptr);/* wait till ready */
		} while((ret_val & 0x40) != 0x40);
	}
#endif
	return NanD_WaitReady(nand, 0);
}

/* NanD_Address: Set the current address for the flash chip */

static int NanD_Address(struct nand_chip *nand, int numbytes, unsigned long ofs)
{
	unsigned long nandptr;
	int i;

	nandptr = nand->IO_ADDR;

	/* Assert the ALE (Address Latch Enable) line to the flash chip */
	NAND_CTL_SETALE(nandptr);

	/* Send the address */
	/* Devices with 256-byte page are addressed as:
	 * Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
	 * there is no device on the market with page256
	 * and more than 24 bits.
	 * Devices with 512-byte page are addressed as:
	 * Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
	 * 25-31 is sent only if the chip support it.
	 * bit 8 changes the read command to be sent
	 * (NAND_CMD_READ0 or NAND_CMD_READ1).
	 */

	if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE)
		WRITE_NAND_ADDRESS(ofs, nandptr);

	ofs = ofs >> nand->page_shift;

	if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) {
		for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8) {
			WRITE_NAND_ADDRESS(ofs, nandptr);
		}
	}

	/* Lower the ALE line */
	NAND_CTL_CLRALE(nandptr);

	/* Wait for the chip to respond */
	return NanD_WaitReady(nand, 1);
}

/* NanD_SelectChip: Select a given flash chip within the current floor */

static inline int NanD_SelectChip(struct nand_chip *nand, int chip)
{
	/* Wait for it to be ready */
	return NanD_WaitReady(nand, 0);
}

/* NanD_IdentChip: Identify a given NAND chip given {floor,chip} */

static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)
{
	int mfr, id, i;

	NAND_ENABLE_CE(nand);  /* set pin low */
	/* Reset the chip */
	if (NanD_Command(nand, NAND_CMD_RESET)) {
#ifdef NAND_DEBUG
		printf("NanD_Command (reset) for %d,%d returned true\n",
		       floor, chip);
#endif
		NAND_DISABLE_CE(nand);  /* set pin high */
		return 0;
	}

	/* Read the NAND chip ID: 1. Send ReadID command */
	if (NanD_Command(nand, NAND_CMD_READID)) {
#ifdef NAND_DEBUG
		printf("NanD_Command (ReadID) for %d,%d returned true\n",
		       floor, chip);
#endif
		NAND_DISABLE_CE(nand);  /* set pin high */
		return 0;
	}

	/* Read the NAND chip ID: 2. Send address byte zero */
	NanD_Address(nand, ADDR_COLUMN, 0);

	/* Read the manufacturer and device id codes from the device */

	mfr = READ_NAND(nand->IO_ADDR);

	id = READ_NAND(nand->IO_ADDR);

	NAND_DISABLE_CE(nand);  /* set pin high */

#ifdef NAND_DEBUG
	printf("NanD_Command (ReadID) got %x %x\n", mfr, id);
#endif
	if (mfr == 0xff || mfr == 0) {
		/* No response - return failure */
		return 0;
	}

	/* Check it's the same as the first chip we identified.
	 * M-Systems say that any given nand_chip device should only
	 * contain _one_ type of flash part, although that's not a
	 * hardware restriction. */
	if (nand->mfr) {
		if (nand->mfr == mfr && nand->id == id) {
			return 1;	/* This is another the same the first */
		} else {
			printf("Flash chip at floor %d, chip %d is different:\n",
			       floor, chip);
		}
	}

	/* Print and store the manufacturer and ID codes. */
	for (i = 0; nand_flash_ids[i].name != NULL; i++) {
		if (mfr == nand_flash_ids[i].manufacture_id &&
		    id == nand_flash_ids[i].model_id) {
#ifdef NAND_DEBUG
			printf("Flash chip found:\n\t Manufacturer ID: 0x%2.2X, "
			       "Chip ID: 0x%2.2X (%s)\n", mfr, id,
			       nand_flash_ids[i].name);
#endif
			if (!nand->mfr) {
				nand->mfr = mfr;
				nand->id = id;
				nand->chipshift =
				    nand_flash_ids[i].chipshift;
				nand->page256 = nand_flash_ids[i].page256;
				nand->eccsize = 256;
				if (nand->page256) {
					nand->oobblock = 256;
					nand->oobsize = 8;
					nand->page_shift = 8;
				} else {
					nand->oobblock = 512;
					nand->oobsize = 16;
					nand->page_shift = 9;
				}
				nand->pageadrlen = nand_flash_ids[i].pageadrlen;
				nand->erasesize  = nand_flash_ids[i].erasesize;
				nand->chips_name = nand_flash_ids[i].name;
				nand->bus16	 = nand_flash_ids[i].bus16;
				return 1;
			}
			return 0;
		}
	}


#ifdef NAND_DEBUG
	/* We haven't fully identified the chip. Print as much as we know. */
	printf("Unknown flash chip found: %2.2X %2.2X\n",
	       id, mfr);
#endif

	return 0;
}

/* NanD_ScanChips: Find all NAND chips present in a nand_chip, and identify them */

static void NanD_ScanChips(struct nand_chip *nand)
{
	int floor, chip;
	int numchips[NAND_MAX_FLOORS];
	int maxchips = CONFIG_SYS_NAND_MAX_CHIPS;
	int ret = 1;

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


	/* For each floor, find the number of valid chips it contains */
	for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
		ret = 1;
		numchips[floor] = 0;
		for (chip = 0; chip < maxchips && ret != 0; chip++) {

			ret = NanD_IdentChip(nand, floor, chip);
			if (ret) {
				numchips[floor]++;
				nand->numchips++;
			}
		}
	}

	/* If there are none at all that we recognise, bail */
	if (!nand->numchips) {
#ifdef NAND_DEBUG
		puts ("No NAND flash chips recognised.\n");
#endif
		return;
	}

	/* Allocate an array to hold the information for each chip */
	nand->chips = malloc(sizeof(struct Nand) * nand->numchips);
	if (!nand->chips) {
		puts ("No memory for allocating chip info structures\n");
		return;
	}

	ret = 0;

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

	/* Calculate and print the total size of the device */
	nand->totlen = nand->numchips * (1 << nand->chipshift);

#ifdef NAND_DEBUG
	printf("%d flash chips found. Total nand_chip size: %ld MB\n",
	       nand->numchips, nand->totlen >> 20);
#endif
}

/* we need to be fast here, 1 us per read translates to 1 second per meg */
static void NanD_ReadBuf (struct nand_chip *nand, u_char * data_buf, int cntr)
{
	unsigned long nandptr = nand->IO_ADDR;

	NanD_Command (nand, NAND_CMD_READ0);

	if (nand->bus16) {
		u16 val;

		while (cntr >= 16) {
			val = READ_NAND (nandptr);
			*data_buf++ = val & 0xff;
			*data_buf++ = val >> 8;
			val = READ_NAND (nandptr);
			*data_buf++ = val & 0xff;
			*data_buf++ = val >> 8;
			val = READ_NAND (nandptr);
			*data_buf++ = val & 0xff;
			*data_buf++ = val >> 8;
			val = READ_NAND (nandptr);
			*data_buf++ = val & 0xff;
			*data_buf++ = val >> 8;
			val = READ_NAND (nandptr);
			*data_buf++ = val & 0xff;
			*data_buf++ = val >> 8;
			val = READ_NAND (nandptr);
			*data_buf++ = val & 0xff;
			*data_buf++ = val >> 8;
			val = READ_NAND (nandptr);
			*data_buf++ = val & 0xff;
			*data_buf++ = val >> 8;
			val = READ_NAND (nandptr);
			*data_buf++ = val & 0xff;
			*data_buf++ = val >> 8;
			cntr -= 16;
		}

		while (cntr > 0) {
			val = READ_NAND (nandptr);
			*data_buf++ = val & 0xff;
			*data_buf++ = val >> 8;
			cntr -= 2;
		}
	} else {
		while (cntr >= 16) {
			*data_buf++ = READ_NAND (nandptr);
			*data_buf++ = READ_NAND (nandptr);
			*data_buf++ = READ_NAND (nandptr);
			*data_buf++ = READ_NAND (nandptr);
			*data_buf++ = READ_NAND (nandptr);
			*data_buf++ = READ_NAND (nandptr);
			*data_buf++ = READ_NAND (nandptr);
			*data_buf++ = READ_NAND (nandptr);
			*data_buf++ = READ_NAND (nandptr);
			*data_buf++ = READ_NAND (nandptr);
			*data_buf++ = READ_NAND (nandptr);
			*data_buf++ = READ_NAND (nandptr);
			*data_buf++ = READ_NAND (nandptr);
			*data_buf++ = READ_NAND (nandptr);
			*data_buf++ = READ_NAND (nandptr);
			*data_buf++ = READ_NAND (nandptr);
			cntr -= 16;
		}

		while (cntr > 0) {
			*data_buf++ = READ_NAND (nandptr);
			cntr--;
		}
	}
}

/*
 * NAND read with ECC
 */
static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
		 size_t * retlen, u_char *buf, u_char *ecc_code)
{
	int col, page;
	int ecc_status = 0;
#ifdef CONFIG_MTD_NAND_ECC
	int j;
	int ecc_failed = 0;
	u_char *data_poi;
	u_char ecc_calc[6];
#endif

	/* Do not allow reads past end of device */
	if ((start + len) > nand->totlen) {
		printf ("%s: Attempt read beyond end of device %x %x %x\n",
			__FUNCTION__, (uint) start, (uint) len, (uint) nand->totlen);
		*retlen = 0;
		return -1;
	}

	/* First we calculate the starting page */
	/*page = shr(start, nand->page_shift);*/
	page = start >> nand->page_shift;

	/* Get raw starting column */
	col = start & (nand->oobblock - 1);

	/* Initialize return value */
	*retlen = 0;

	/* Select the NAND device */
	NAND_ENABLE_CE(nand);  /* set pin low */

	/* Loop until all data read */
	while (*retlen < len) {

#ifdef CONFIG_MTD_NAND_ECC
		/* Do we have this page in cache ? */
		if (nand->cache_page == page)
			goto readdata;
		/* Send the read command */
		NanD_Command(nand, NAND_CMD_READ0);
		if (nand->bus16) {
			NanD_Address(nand, ADDR_COLUMN_PAGE,
				     (page << nand->page_shift) + (col >> 1));
		} else {
			NanD_Address(nand, ADDR_COLUMN_PAGE,
				     (page << nand->page_shift) + col);
		}

		/* Read in a page + oob data */
		NanD_ReadBuf(nand, nand->data_buf, nand->oobblock + nand->oobsize);

		/* copy data into cache, for read out of cache and if ecc fails */
		if (nand->data_cache) {
			memcpy (nand->data_cache, nand->data_buf,
				nand->oobblock + nand->oobsize);
		}

		/* Pick the ECC bytes out of the oob data */
		for (j = 0; j < 6; j++) {
			ecc_code[j] = nand->data_buf[(nand->oobblock + oob_config.ecc_pos[j])];
		}

		/* Calculate the ECC and verify it */
		/* If block was not written with ECC, skip ECC */
		if (oob_config.eccvalid_pos != -1 &&
		    (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0x0f) != 0x0f) {

			nand_calculate_ecc (&nand->data_buf[0], &ecc_calc[0]);
			switch (nand_correct_data (&nand->data_buf[0], &ecc_code[0], &ecc_calc[0])) {
			case -1:
				printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
				ecc_failed++;
				break;
			case 1:
			case 2:	/* transfer ECC corrected data to cache */
				if (nand->data_cache)
					memcpy (nand->data_cache, nand->data_buf, 256);
				break;
			}
		}

		if (oob_config.eccvalid_pos != -1 &&
		    nand->oobblock == 512 && (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0xf0) != 0xf0) {

			nand_calculate_ecc (&nand->data_buf[256], &ecc_calc[3]);
			switch (nand_correct_data (&nand->data_buf[256], &ecc_code[3], &ecc_calc[3])) {
			case -1:
				printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
				ecc_failed++;
				break;
			case 1:
			case 2:	/* transfer ECC corrected data to cache */
				if (nand->data_cache)
					memcpy (&nand->data_cache[256], &nand->data_buf[256], 256);
				break;
			}
		}
readdata:
		/* Read the data from ECC data buffer into return buffer */
		data_poi = (nand->data_cache) ? nand->data_cache : nand->data_buf;
		data_poi += col;
		if ((*retlen + (nand->oobblock - col)) >= len) {
			memcpy (buf + *retlen, data_poi, len - *retlen);
			*retlen = len;
		} else {
			memcpy (buf + *retlen, data_poi,  nand->oobblock - col);
			*retlen += nand->oobblock - col;
		}
		/* Set cache page address, invalidate, if ecc_failed */
		nand->cache_page = (nand->data_cache && !ecc_failed) ? page : -1;

		ecc_status += ecc_failed;
		ecc_failed = 0;

#else
		/* Send the read command */
		NanD_Command(nand, NAND_CMD_READ0);
		if (nand->bus16) {
			NanD_Address(nand, ADDR_COLUMN_PAGE,
				     (page << nand->page_shift) + (col >> 1));
		} else {
			NanD_Address(nand, ADDR_COLUMN_PAGE,
				     (page << nand->page_shift) + col);
		}

		/* Read the data directly into the return buffer */
		if ((*retlen + (nand->oobblock - col)) >= len) {
			NanD_ReadBuf(nand, buf + *retlen, len - *retlen);
			*retlen = len;
			/* We're done */
			continue;
		} else {
			NanD_ReadBuf(nand, buf + *retlen, nand->oobblock - col);
			*retlen += nand->oobblock - col;
			}
#endif
		/* For subsequent reads align to page boundary. */
		col = 0;
		/* Increment page address */
		page++;
	}

	/* De-select the NAND device */
	NAND_DISABLE_CE(nand);  /* set pin high */

	/*
	 * Return success, if no ECC failures, else -EIO
	 * fs driver will take care of that, because
	 * retlen == desired len and result == -EIO
	 */
	return ecc_status ? -1 : 0;
}

/*
 *	Nand_page_program function is used for write and writev !
 */
static int nand_write_page (struct nand_chip *nand,
			    int page, int col, int last, u_char * ecc_code)
{

	int i;
	unsigned long nandptr = nand->IO_ADDR;

#ifdef CONFIG_MTD_NAND_ECC
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
	int ecc_bytes = (nand->oobblock == 512) ? 6 : 3;
#endif
#endif
	/* pad oob area */
	for (i = nand->oobblock; i < nand->oobblock + nand->oobsize; i++)
		nand->data_buf[i] = 0xff;

#ifdef CONFIG_MTD_NAND_ECC
	/* Zero out the ECC array */
	for (i = 0; i < 6; i++)
		ecc_code[i] = 0x00;

	/* Read back previous written data, if col > 0 */
	if (col) {
		NanD_Command (nand, NAND_CMD_READ0);
		if (nand->bus16) {
			NanD_Address (nand, ADDR_COLUMN_PAGE,
				      (page << nand->page_shift) + (col >> 1));
		} else {
			NanD_Address (nand, ADDR_COLUMN_PAGE,
				      (page << nand->page_shift) + col);
		}

		if (nand->bus16) {
			u16 val;

			for (i = 0; i < col; i += 2) {
				val = READ_NAND (nandptr);
				nand->data_buf[i] = val & 0xff;
				nand->data_buf[i + 1] = val >> 8;
			}
		} else {
			for (i = 0; i < col; i++)
				nand->data_buf[i] = READ_NAND (nandptr);
		}
	}

	/* Calculate and write the ECC if we have enough data */
	if ((col < nand->eccsize) && (last >= nand->eccsize)) {
		nand_calculate_ecc (&nand->data_buf[0], &(ecc_code[0]));
		for (i = 0; i < 3; i++) {
			nand->data_buf[(nand->oobblock +
					oob_config.ecc_pos[i])] = ecc_code[i];
		}
		if (oob_config.eccvalid_pos != -1) {
			nand->data_buf[nand->oobblock +
				       oob_config.eccvalid_pos] = 0xf0;
		}
	}

	/* Calculate and write the second ECC if we have enough data */
	if ((nand->oobblock == 512) && (last == nand->oobblock)) {
		nand_calculate_ecc (&nand->data_buf[256], &(ecc_code[3]));
		for (i = 3; i < 6; i++) {
			nand->data_buf[(nand->oobblock +
					oob_config.ecc_pos[i])] = ecc_code[i];
		}
		if (oob_config.eccvalid_pos != -1) {
			nand->data_buf[nand->oobblock +
				       oob_config.eccvalid_pos] &= 0x0f;
		}
	}
#endif
	/* Prepad for partial page programming !!! */
	for (i = 0; i < col; i++)
		nand->data_buf[i] = 0xff;

	/* Postpad for partial page programming !!! oob is already padded */
	for (i = last; i < nand->oobblock; i++)
		nand->data_buf[i] = 0xff;

	/* Send command to begin auto page programming */
	NanD_Command (nand, NAND_CMD_READ0);
	NanD_Command (nand, NAND_CMD_SEQIN);
	if (nand->bus16) {
		NanD_Address (nand, ADDR_COLUMN_PAGE,
			      (page << nand->page_shift) + (col >> 1));
	} else {
		NanD_Address (nand, ADDR_COLUMN_PAGE,
			      (page << nand->page_shift) + col);
	}

	/* Write out complete page of data */
	if (nand->bus16) {
		for (i = 0; i < (nand->oobblock + nand->oobsize); i += 2) {
			WRITE_NAND (nand->data_buf[i] +
				    (nand->data_buf[i + 1] << 8),
				    nand->IO_ADDR);
		}
	} else {
		for (i = 0; i < (nand->oobblock + nand->oobsize); i++)
			WRITE_NAND (nand->data_buf[i], nand->IO_ADDR);
	}

	/* Send command to actually program the data */
	NanD_Command (nand, NAND_CMD_PAGEPROG);
	NanD_Command (nand, NAND_CMD_STATUS);
#ifdef NAND_NO_RB
	{
		u_char ret_val;

		do {
			ret_val = READ_NAND (nandptr);	/* wait till ready */
		} while ((ret_val & 0x40) != 0x40);
	}
#endif
	/* See if device thinks it succeeded */
	if (READ_NAND (nand->IO_ADDR) & 0x01) {
		printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__,
			page);
		return -1;
	}
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
	/*
	 * The NAND device assumes that it is always writing to
	 * a cleanly erased page. Hence, it performs its internal
	 * write verification only on bits that transitioned from
	 * 1 to 0. The device does NOT verify the whole page on a
	 * byte by byte basis. It is possible that the page was
	 * not completely erased or the page is becoming unusable
	 * due to wear. The read with ECC would catch the error
	 * later when the ECC page check fails, but we would rather
	 * catch it early in the page write stage. Better to write
	 * no data than invalid data.
	 */

	/* Send command to read back the page */
	if (col < nand->eccsize)
		NanD_Command (nand, NAND_CMD_READ0);
	else
		NanD_Command (nand, NAND_CMD_READ1);
	if (nand->bus16) {
		NanD_Address (nand, ADDR_COLUMN_PAGE,
			      (page << nand->page_shift) + (col >> 1));
	} else {
		NanD_Address (nand, ADDR_COLUMN_PAGE,
			      (page << nand->page_shift) + col);
	}

	/* Loop through and verify the data */
	if (nand->bus16) {
		for (i = col; i < last; i = +2) {
			if ((nand->data_buf[i] +
			     (nand->data_buf[i + 1] << 8)) != READ_NAND (nand->IO_ADDR)) {
				printf ("%s: Failed write verify, page 0x%08x ",
					__FUNCTION__, page);
				return -1;
			}
		}
	} else {
		for (i = col; i < last; i++) {
			if (nand->data_buf[i] != READ_NAND (nand->IO_ADDR)) {
				printf ("%s: Failed write verify, page 0x%08x ",
					__FUNCTION__, page);
				return -1;
			}
		}
	}

#ifdef CONFIG_MTD_NAND_ECC
	/*
	 * We also want to check that the ECC bytes wrote
	 * correctly for the same reasons stated above.
	 */
	NanD_Command (nand, NAND_CMD_READOOB);
	if (nand->bus16) {
		NanD_Address (nand, ADDR_COLUMN_PAGE,
			      (page << nand->page_shift) + (col >> 1));
	} else {
		NanD_Address (nand, ADDR_COLUMN_PAGE,
			      (page << nand->page_shift) + col);
	}
	if (nand->bus16) {
		for (i = 0; i < nand->oobsize; i += 2) {
			u16 val;

			val = READ_NAND (nand->IO_ADDR);
			nand->data_buf[i] = val & 0xff;
			nand->data_buf[i + 1] = val >> 8;
		}
	} else {
		for (i = 0; i < nand->oobsize; i++) {
			nand->data_buf[i] = READ_NAND (nand->IO_ADDR);
		}
	}
	for (i = 0; i < ecc_bytes; i++) {
		if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) {
			printf ("%s: Failed ECC write "
				"verify, page 0x%08x, "
				"%6i bytes were succesful\n",
				__FUNCTION__, page, i);
			return -1;
		}
	}
#endif	/* CONFIG_MTD_NAND_ECC */
#endif	/* CONFIG_MTD_NAND_VERIFY_WRITE */
	return 0;
}

static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
			   size_t * retlen, const u_char * buf, u_char * ecc_code)
{
	int i, page, col, cnt, ret = 0;

	/* Do not allow write past end of device */
	if ((to + len) > nand->totlen) {
		printf ("%s: Attempt to write past end of page\n", __FUNCTION__);
		return -1;
	}

	/* Shift to get page */
	page = ((int) to) >> nand->page_shift;

	/* Get the starting column */
	col = to & (nand->oobblock - 1);

	/* Initialize return length value */
	*retlen = 0;

	/* Select the NAND device */
#ifdef CONFIG_OMAP1510
	archflashwp(0,0);
#endif
#ifdef CONFIG_SYS_NAND_WP
	NAND_WP_OFF();
#endif

	NAND_ENABLE_CE(nand);  /* set pin low */

	/* Check the WP bit */
	NanD_Command(nand, NAND_CMD_STATUS);
	if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
		printf ("%s: Device is write protected!!!\n", __FUNCTION__);
		ret = -1;
		goto out;
	}

	/* Loop until all data is written */
	while (*retlen < len) {
		/* Invalidate cache, if we write to this page */
		if (nand->cache_page == page)
			nand->cache_page = -1;

		/* Write data into buffer */
		if ((col + len) >= nand->oobblock) {
			for (i = col, cnt = 0; i < nand->oobblock; i++, cnt++) {
				nand->data_buf[i] = buf[(*retlen + cnt)];
			}
		} else {
			for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++) {
				nand->data_buf[i] = buf[(*retlen + cnt)];
			}
		}
		/* We use the same function for write and writev !) */
		ret = nand_write_page (nand, page, col, i, ecc_code);
		if (ret)
			goto out;

		/* Next data start at page boundary */
		col = 0;

		/* Update written bytes count */
		*retlen += cnt;

		/* Increment page address */
		page++;
	}

	/* Return happy */
	*retlen = len;

out:
	/* De-select the NAND device */
	NAND_DISABLE_CE(nand);  /* set pin high */
#ifdef CONFIG_OMAP1510
	archflashwp(0,1);
#endif
#ifdef CONFIG_SYS_NAND_WP
	NAND_WP_ON();
#endif

	return ret;
}

/* read from the 16 bytes of oob data that correspond to a 512 byte
 * page or 2 256-byte pages.
 */
int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
			 size_t * retlen, u_char * buf)
{
	int len256 = 0;
	struct Nand *mychip;
	int ret = 0;

	mychip = &nand->chips[ofs >> nand->chipshift];

	/* update address for 2M x 8bit devices. OOB starts on the second */
	/* page to maintain compatibility with nand_read_ecc. */
	if (nand->page256) {
		if (!(ofs & 0x8))
			ofs += 0x100;
		else
			ofs -= 0x8;
	}

	NAND_ENABLE_CE(nand);  /* set pin low */
	NanD_Command(nand, NAND_CMD_READOOB);
	if (nand->bus16) {
		NanD_Address(nand, ADDR_COLUMN_PAGE,
			     ((ofs >> nand->page_shift) << nand->page_shift) +
				((ofs & (nand->oobblock - 1)) >> 1));
	} else {
		NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
	}

	/* treat crossing 8-byte OOB data for 2M x 8bit devices */
	/* Note: datasheet says it should automaticaly wrap to the */
	/*       next OOB block, but it didn't work here. mf.      */
	if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
		len256 = (ofs | 0x7) + 1 - ofs;
		NanD_ReadBuf(nand, buf, len256);

		NanD_Command(nand, NAND_CMD_READOOB);
		NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
	}

	NanD_ReadBuf(nand, &buf[len256], len - len256);

	*retlen = len;
	/* Reading the full OOB data drops us off of the end of the page,
	 * causing the flash device to go into busy mode, so we need
	 * to wait until ready 11.4.1 and Toshiba TC58256FT nands */

	ret = NanD_WaitReady(nand, 1);
	NAND_DISABLE_CE(nand);  /* set pin high */

	return ret;

}

/* write to the 16 bytes of oob data that correspond to a 512 byte
 * page or 2 256-byte pages.
 */
int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
		  size_t * retlen, const u_char * buf)
{
	int len256 = 0;
	int i;
	unsigned long nandptr = nand->IO_ADDR;

#ifdef PSYCHO_DEBUG
	printf("nand_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",
	       (long)ofs, len, buf[0], buf[1], buf[2], buf[3],
	       buf[8], buf[9], buf[14],buf[15]);
#endif

	NAND_ENABLE_CE(nand);  /* set pin low to enable chip */

	/* Reset the chip */
	NanD_Command(nand, NAND_CMD_RESET);

	/* issue the Read2 command to set the pointer to the Spare Data Area. */
	NanD_Command(nand, NAND_CMD_READOOB);
	if (nand->bus16) {
		NanD_Address(nand, ADDR_COLUMN_PAGE,
			     ((ofs >> nand->page_shift) << nand->page_shift) +
				((ofs & (nand->oobblock - 1)) >> 1));
	} else {
		NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
	}

	/* update address for 2M x 8bit devices. OOB starts on the second */
	/* page to maintain compatibility with nand_read_ecc. */
	if (nand->page256) {
		if (!(ofs & 0x8))
			ofs += 0x100;
		else
			ofs -= 0x8;
	}

	/* issue the Serial Data In command to initial the Page Program process */
	NanD_Command(nand, NAND_CMD_SEQIN);
	if (nand->bus16) {
		NanD_Address(nand, ADDR_COLUMN_PAGE,
			     ((ofs >> nand->page_shift) << nand->page_shift) +
				((ofs & (nand->oobblock - 1)) >> 1));
	} else {
		NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
	}

	/* treat crossing 8-byte OOB data for 2M x 8bit devices */
	/* Note: datasheet says it should automaticaly wrap to the */
	/*       next OOB block, but it didn't work here. mf.      */
	if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
		len256 = (ofs | 0x7) + 1 - ofs;
		for (i = 0; i < len256; i++)
			WRITE_NAND(buf[i], nandptr);

		NanD_Command(nand, NAND_CMD_PAGEPROG);
		NanD_Command(nand, NAND_CMD_STATUS);
#ifdef NAND_NO_RB
		{ u_char ret_val;
			do {
				ret_val = READ_NAND(nandptr); /* wait till ready */
			} while ((ret_val & 0x40) != 0x40);
		}
#endif
		if (READ_NAND(nandptr) & 1) {
			puts ("Error programming oob data\n");
			/* There was an error */
			NAND_DISABLE_CE(nand);  /* set pin high */
			*retlen = 0;
			return -1;
		}
		NanD_Command(nand, NAND_CMD_SEQIN);
		NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
	}

	if (nand->bus16) {
		for (i = len256; i < len; i += 2) {
			WRITE_NAND(buf[i] + (buf[i+1] << 8), nandptr);
		}
	} else {
		for (i = len256; i < len; i++)
			WRITE_NAND(buf[i], nandptr);
	}

	NanD_Command(nand, NAND_CMD_PAGEPROG);
	NanD_Command(nand, NAND_CMD_STATUS);
#ifdef NAND_NO_RB
	{	u_char ret_val;
		do {
			ret_val = READ_NAND(nandptr); /* wait till ready */
		} while ((ret_val & 0x40) != 0x40);
	}
#endif
	if (READ_NAND(nandptr) & 1) {
		puts ("Error programming oob data\n");
		/* There was an error */
		NAND_DISABLE_CE(nand);  /* set pin high */
		*retlen = 0;
		return -1;
	}

	NAND_DISABLE_CE(nand);  /* set pin high */
	*retlen = len;
	return 0;

}

int nand_legacy_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean)
{
	/* This is defined as a structure so it will work on any system
	 * using native endian jffs2 (the default).
	 */
	static struct jffs2_unknown_node clean_marker = {
		JFFS2_MAGIC_BITMASK,
		JFFS2_NODETYPE_CLEANMARKER,
		8		/* 8 bytes in this node */
	};
	unsigned long nandptr;
	struct Nand *mychip;
	int ret = 0;

	if (ofs & (nand->erasesize-1) || len & (nand->erasesize-1)) {
		printf ("Offset and size must be sector aligned, erasesize = %d\n",
			(int) nand->erasesize);
		return -1;
	}

	nandptr = nand->IO_ADDR;

	/* Select the NAND device */
#ifdef CONFIG_OMAP1510
	archflashwp(0,0);
#endif
#ifdef CONFIG_SYS_NAND_WP
	NAND_WP_OFF();
#endif
    NAND_ENABLE_CE(nand);  /* set pin low */

	/* Check the WP bit */
	NanD_Command(nand, NAND_CMD_STATUS);
	if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
		printf ("nand_write_ecc: Device is write protected!!!\n");
		ret = -1;
		goto out;
	}

	/* Check the WP bit */
	NanD_Command(nand, NAND_CMD_STATUS);
	if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
		printf ("%s: Device is write protected!!!\n", __FUNCTION__);
		ret = -1;
		goto out;
	}

	/* FIXME: Do nand in the background. Use timers or schedule_task() */
	while(len) {
		/*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/
		mychip = &nand->chips[ofs >> nand->chipshift];

		/* always check for bad block first, genuine bad blocks
		 * should _never_  be erased.
		 */
		if (ALLOW_ERASE_BAD_DEBUG || !check_block(nand, ofs)) {
			/* Select the NAND device */
			NAND_ENABLE_CE(nand);  /* set pin low */

			NanD_Command(nand, NAND_CMD_ERASE1);
			NanD_Address(nand, ADDR_PAGE, ofs);
			NanD_Command(nand, NAND_CMD_ERASE2);

			NanD_Command(nand, NAND_CMD_STATUS);

#ifdef NAND_NO_RB
			{	u_char ret_val;
				do {
					ret_val = READ_NAND(nandptr); /* wait till ready */
				} while ((ret_val & 0x40) != 0x40);
			}
#endif
			if (READ_NAND(nandptr) & 1) {
				printf ("%s: Error erasing at 0x%lx\n",
					__FUNCTION__, (long)ofs);
				/* There was an error */
				ret = -1;
				goto out;
			}
			if (clean) {
				int n;	/* return value not used */
				int p, l;

				/* clean marker position and size depend
				 * on the page size, since 256 byte pages
				 * only have 8 bytes of oob data
				 */
				if (nand->page256) {
					p = NAND_JFFS2_OOB8_FSDAPOS;
					l = NAND_JFFS2_OOB8_FSDALEN;
				} else {
					p = NAND_JFFS2_OOB16_FSDAPOS;
					l = NAND_JFFS2_OOB16_FSDALEN;
				}

				ret = nand_write_oob(nand, ofs + p, l, (size_t *)&n,
						     (u_char *)&clean_marker);
				/* quit here if write failed */
				if (ret)
					goto out;
			}
		}
		ofs += nand->erasesize;
		len -= nand->erasesize;
	}

out:
	/* De-select the NAND device */
	NAND_DISABLE_CE(nand);  /* set pin high */
#ifdef CONFIG_OMAP1510
	archflashwp(0,1);
#endif
#ifdef CONFIG_SYS_NAND_WP
	NAND_WP_ON();
#endif

	return ret;
}


static inline int nandcheck(unsigned long potential, unsigned long physadr)
{
	return 0;
}

unsigned long nand_probe(unsigned long physadr)
{
	struct nand_chip *nand = NULL;
	int i = 0, ChipID = 1;

#ifdef CONFIG_MTD_NAND_ECC_JFFS2
	oob_config.ecc_pos[0] = NAND_JFFS2_OOB_ECCPOS0;
	oob_config.ecc_pos[1] = NAND_JFFS2_OOB_ECCPOS1;
	oob_config.ecc_pos[2] = NAND_JFFS2_OOB_ECCPOS2;
	oob_config.ecc_pos[3] = NAND_JFFS2_OOB_ECCPOS3;
	oob_config.ecc_pos[4] = NAND_JFFS2_OOB_ECCPOS4;
	oob_config.ecc_pos[5] = NAND_JFFS2_OOB_ECCPOS5;
	oob_config.eccvalid_pos = 4;
#else
	oob_config.ecc_pos[0] = NAND_NOOB_ECCPOS0;
	oob_config.ecc_pos[1] = NAND_NOOB_ECCPOS1;
	oob_config.ecc_pos[2] = NAND_NOOB_ECCPOS2;
	oob_config.ecc_pos[3] = NAND_NOOB_ECCPOS3;
	oob_config.ecc_pos[4] = NAND_NOOB_ECCPOS4;
	oob_config.ecc_pos[5] = NAND_NOOB_ECCPOS5;
	oob_config.eccvalid_pos = NAND_NOOB_ECCVPOS;
#endif
	oob_config.badblock_pos = 5;

	for (i=0; i<CONFIG_SYS_MAX_NAND_DEVICE; i++) {
		if (nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN) {
			nand = &nand_dev_desc[i];
			break;
		}
	}
	if (!nand)
		return (0);

	memset((char *)nand, 0, sizeof(struct nand_chip));

	nand->IO_ADDR = physadr;
	nand->cache_page = -1;  /* init the cache page */
	NanD_ScanChips(nand);

	if (nand->totlen == 0) {
		/* no chips found, clean up and quit */
		memset((char *)nand, 0, sizeof(struct nand_chip));
		nand->ChipID = NAND_ChipID_UNKNOWN;
		return (0);
	}

	nand->ChipID = ChipID;
	if (curr_device == -1)
		curr_device = i;

	nand->data_buf = malloc (nand->oobblock + nand->oobsize);
	if (!nand->data_buf) {
		puts ("Cannot allocate memory for data structures.\n");
		return (0);
	}

	return (nand->totlen);
}

#ifdef CONFIG_MTD_NAND_ECC
/*
 * Pre-calculated 256-way 1 byte column parity
 */
static const u_char nand_ecc_precalc_table[] = {
	0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
	0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
	0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
	0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
	0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
	0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
	0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
	0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
	0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
	0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
	0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
	0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
	0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
	0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
	0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
	0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
	0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
	0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
	0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
	0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
	0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
	0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
	0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
	0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
	0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
	0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
	0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
	0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
	0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
	0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
	0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
	0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
};


/*
 * Creates non-inverted ECC code from line parity
 */
static void nand_trans_result(u_char reg2, u_char reg3,
	u_char *ecc_code)
{
	u_char a, b, i, tmp1, tmp2;

	/* Initialize variables */
	a = b = 0x80;
	tmp1 = tmp2 = 0;

	/* Calculate first ECC byte */
	for (i = 0; i < 4; i++) {
		if (reg3 & a)		/* LP15,13,11,9 --> ecc_code[0] */
			tmp1 |= b;
		b >>= 1;
		if (reg2 & a)		/* LP14,12,10,8 --> ecc_code[0] */
			tmp1 |= b;
		b >>= 1;
		a >>= 1;
	}

	/* Calculate second ECC byte */
	b = 0x80;
	for (i = 0; i < 4; i++) {
		if (reg3 & a)		/* LP7,5,3,1 --> ecc_code[1] */
			tmp2 |= b;
		b >>= 1;
		if (reg2 & a)		/* LP6,4,2,0 --> ecc_code[1] */
			tmp2 |= b;
		b >>= 1;
		a >>= 1;
	}

	/* Store two of the ECC bytes */
	ecc_code[0] = tmp1;
	ecc_code[1] = tmp2;
}

/*
 * Calculate 3 byte ECC code for 256 byte block
 */
static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code)
{
	u_char idx, reg1, reg3;
	int j;

	/* Initialize variables */
	reg1 = reg3 = 0;
	ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;

	/* Build up column parity */
	for(j = 0; j < 256; j++) {

		/* Get CP0 - CP5 from table */
		idx = nand_ecc_precalc_table[dat[j]];
		reg1 ^= idx;

		/* All bit XOR = 1 ? */
		if (idx & 0x40) {
			reg3 ^= (u_char) j;
		}
	}

	/* Create non-inverted ECC code from line parity */
	nand_trans_result((reg1 & 0x40) ? ~reg3 : reg3, reg3, ecc_code);

	/* Calculate final ECC code */
	ecc_code[0] = ~ecc_code[0];
	ecc_code[1] = ~ecc_code[1];
	ecc_code[2] = ((~reg1) << 2) | 0x03;
}

/*
 * Detect and correct a 1 bit error for 256 byte block
 */
static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc)
{
	u_char a, b, c, d1, d2, d3, add, bit, i;

	/* Do error detection */
	d1 = calc_ecc[0] ^ read_ecc[0];
	d2 = calc_ecc[1] ^ read_ecc[1];
	d3 = calc_ecc[2] ^ read_ecc[2];

	if ((d1 | d2 | d3) == 0) {
		/* No errors */
		return 0;
	} else {
		a = (d1 ^ (d1 >> 1)) & 0x55;
		b = (d2 ^ (d2 >> 1)) & 0x55;
		c = (d3 ^ (d3 >> 1)) & 0x54;

		/* Found and will correct single bit error in the data */
		if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
			c = 0x80;
			add = 0;
			a = 0x80;
			for (i=0; i<4; i++) {
				if (d1 & c)
					add |= a;
				c >>= 2;
				a >>= 1;
			}
			c = 0x80;
			for (i=0; i<4; i++) {
				if (d2 & c)
					add |= a;
				c >>= 2;
				a >>= 1;
			}
			bit = 0;
			b = 0x04;
			c = 0x80;
			for (i=0; i<3; i++) {
				if (d3 & c)
					bit |= b;
				c >>= 2;
				b >>= 1;
			}
			b = 0x01;
			a = dat[add];
			a ^= (b << bit);
			dat[add] = a;
			return 1;
		}
		else {
			i = 0;
			while (d1) {
				if (d1 & 0x01)
					++i;
				d1 >>= 1;
			}
			while (d2) {
				if (d2 & 0x01)
					++i;
				d2 >>= 1;
			}
			while (d3) {
				if (d3 & 0x01)
					++i;
				d3 >>= 1;
			}
			if (i == 1) {
				/* ECC Code Error Correction */
				read_ecc[0] = calc_ecc[0];
				read_ecc[1] = calc_ecc[1];
				read_ecc[2] = calc_ecc[2];
				return 2;
			}
			else {
				/* Uncorrectable Error */
				return -1;
			}
		}
	}

	/* Should never happen */
	return -1;
}

#endif

#ifdef CONFIG_JFFS2_NAND
int read_jffs2_nand(size_t start, size_t len,
		size_t * retlen, u_char * buf, int nanddev)
{
	return nand_legacy_rw(nand_dev_desc + nanddev, NANDRW_READ | NANDRW_JFFS2,
			start, len, retlen, buf);
}
#endif /* CONFIG_JFFS2_NAND */
