[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) */
|