[Aesop-embedded-devel] u-boot-aesop/common cmd_nand.c
Status: Beta
Brought to you by:
linuxpark
From: jeenspa <je...@li...> - 2005-07-05 14:16:49
|
jeenspa 2005/07/05 07:16:43 Modified: common cmd_nand.c Log: usbdmass fixup, nand, mkyaffs Revision Changes Path 1.2 +94 -15 u-boot-aesop/common/cmd_nand.c Index: cmd_nand.c =================================================================== RCS file: /cvsroot/aesop-embedded/u-boot-aesop/common/cmd_nand.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- cmd_nand.c 27 Jun 2005 17:05:23 -0000 1.1 +++ cmd_nand.c 5 Jul 2005 14:16:43 -0000 1.2 @@ -24,6 +24,10 @@ #include <asm/arch/hardware.h> #endif +#ifdef CONFIG_S3C2440 +#include <s3c2440.h> +#endif + #include <linux/mtd/nand.h> #include <linux/mtd/nand_ids.h> #include <jffs2/jffs2.h> @@ -45,6 +49,8 @@ #undef NAND_DEBUG #undef PSYCHO_DEBUG +//#define NAND_DEBUG +//#define PSYCHO_DEBUG /* ****************** WARNING ********************* * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will @@ -83,9 +89,13 @@ 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); static void nand_print_bad(struct nand_chip *nand); -static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len, +/* static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len, + size_t * retlen, u_char * buf); */ +int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len, size_t * retlen, u_char * buf); -static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len, +/* static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len, + size_t * retlen, const u_char * buf); */ +int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len, size_t * retlen, const u_char * buf); static int NanD_WaitReady(struct nand_chip *nand, int ale_wait); #ifdef CONFIG_MTD_NAND_ECC @@ -553,8 +563,9 @@ static inline int NanD_Command(struct nand_chip *nand, unsigned char command) { +#ifndef CONFIG_S3C2440 unsigned long nandptr = nand->IO_ADDR; - +#endif /* Assert the CLE (Command Latch Enable) line to the flash chip */ NAND_CTL_SETCLE(nandptr); @@ -580,11 +591,10 @@ static int NanD_Address(struct nand_chip *nand, int numbytes, unsigned long ofs) { - unsigned long nandptr; int i; - - nandptr = nand->IO_ADDR; - +#ifndef CONFIG_S3C2440 + unsigned long nandptr = nand->IO_ADDR; +#endif /* Assert the ALE (Address Latch Enable) line to the flash chip */ NAND_CTL_SETALE(nandptr); @@ -741,7 +751,6 @@ 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; @@ -797,8 +806,9 @@ /* 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) { +#ifndef CONFIG_S3C2440 unsigned long nandptr = nand->IO_ADDR; - +#endif while (cntr >= 16) { *data_buf++ = READ_NAND(nandptr); *data_buf++ = READ_NAND(nandptr); @@ -975,7 +985,9 @@ { int i; +#ifndef CONFIG_S3C2440 unsigned long nandptr = nand->IO_ADDR; +#endif #ifdef CONFIG_MTD_NAND_ECC #ifdef CONFIG_MTD_NAND_VERIFY_WRITE int ecc_bytes = (nand->oobblock == 512) ? 6 : 3; @@ -1177,7 +1189,9 @@ /* read from the 16 bytes of oob data that correspond to a 512 byte * page or 2 256-byte pages. */ -static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len, +/* static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len, + size_t * retlen, u_char * buf) */ +int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len, size_t * retlen, u_char * buf) { int len256 = 0; @@ -1227,13 +1241,16 @@ /* write to the 16 bytes of oob data that correspond to a 512 byte * page or 2 256-byte pages. */ -static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len, +/* static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len, + size_t * retlen, const u_char * buf) */ +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; +#ifndef CONFIG_S3C2440 unsigned long nandptr = nand->IO_ADDR; - +#endif #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], @@ -1326,7 +1343,10 @@ JFFS2_NODETYPE_CLEANMARKER, 8 /* 8 bytes in this node */ }; - unsigned long nandptr; + +#ifndef CONFIG_S3C2440 + unsigned long nandptr = nand->IO_ADDR; +#endif struct Nand *mychip; int ret = 0; @@ -1336,8 +1356,6 @@ return -1; } - nandptr = nand->IO_ADDR; - /* Select the NAND device */ #ifdef CONFIG_OMAP1510 archflashwp(0,0); @@ -1693,5 +1711,66 @@ #endif /* CONFIG_JFFS2_NAND */ +#ifdef CONFIG_AESOP_YAFFS +/* + * NAND Flash Page write function for YAFFS image write + */ +int nand_write_page_yaffs (int, u_char *); +int nand_write_page_yaffs (int page, u_char *buff) +{ + + int i; + struct nand_chip *nand = &nand_dev_desc[curr_device]; + + NAND_ENABLE_CE(nand); /* set pin low */ + /* Send command to begin auto page programming */ + NanD_Command(nand, NAND_CMD_READ0); + NanD_Command(nand, NAND_CMD_SEQIN); + NanD_Address(nand, ADDR_COLUMN_PAGE, page << nand->page_shift); + + /* Write out complete page of data with OOB */ + for (i = 0; i < (nand->oobblock + nand->oobsize); i++) + WRITE_NAND(buff[i], nand->IO_ADDR); + + /* Send command to actually program the data */ + NanD_Command(nand, NAND_CMD_PAGEPROG); + NanD_Command(nand, NAND_CMD_STATUS); + + /* See if device thinks it succeeded */ + if (READ_NAND(nand->IO_ADDR) & 0x01) { + NAND_DISABLE_CE(nand); /* set pin high */ + printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__, page); + return -1; + } + + /* + * 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 */ + NanD_Command(nand, NAND_CMD_READ0); + NanD_Address(nand, ADDR_COLUMN_PAGE, page << nand->page_shift); + + /* Loop through and verify the data */ + for (i = 0; i < (nand->oobblock + nand->oobsize); i++) { + if (buff[i] != READ_NAND(nand->IO_ADDR)) { + NAND_DISABLE_CE(nand); /* set pin high */ + printf ("%s: Failed write verify, page 0x%08x ", __FUNCTION__, page); + return -1; + } + } + NAND_DISABLE_CE(nand); /* set pin high */ + return 0; +} +#endif /* CONFIG_AESOP_YAFFS */ #endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ |