From: Markus Klotzbücher Date: Mon, 6 Mar 2006 12:45:42 +0000 (+0100) Subject: NAND finally working. Two bugs fixed: X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=f9e029184be5ef550d05262e0f150d31fb09d19b;p=u-boot.git NAND finally working. Two bugs fixed: * For READ_STATUS and READID commands always 8 bytes need to be read from NDDB. Otherwise they stay there and get send to flash as the first data word when writing. * In nand_base.c the oob variable is not reset so this->oob_buf is overwritten what eventually screws up the bad block descriptor table. --- diff --git a/board/delta/nand.c b/board/delta/nand.c index 9f882a52b9..88e190268e 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -31,8 +31,13 @@ /* mk@tbd move this to pxa-regs */ #define OSCR_CLK_FREQ 3.250 /* MHz */ +/* usefull */ #define CFG_DFC_DEBUG1 -#define CFG_DFC_DEBUG2 +/* noisy */ +#undef CFG_DFC_DEBUG2 +/* wild west */ +#undef CFG_DFC_DEBUG3 + #ifdef CFG_DFC_DEBUG1 # define DFC_DEBUG1(fmt, args...) printf(fmt, ##args) @@ -46,6 +51,12 @@ # define DFC_DEBUG2(fmt, args...) #endif +#ifdef CFG_DFC_DEBUG3 +# define DFC_DEBUG3(fmt, args...) printf(fmt, ##args) +#else +# define DFC_DEBUG3(fmt, args...) +#endif + static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; static struct nand_bbt_descr delta_bbt_descr = { @@ -56,7 +67,7 @@ static struct nand_bbt_descr delta_bbt_descr = { }; static struct nand_oobinfo delta_oob = { - .useecc = MTD_NANDECC_AUTOPLACE, + .useecc = MTD_NANDECC_AUTOPL_USR, /* MTD_NANDECC_PLACEONLY, */ .eccbytes = 6, .eccpos = {2, 3, 4, 5, 6, 7}, .oobfree = { {8, 2}, {12, 4} } @@ -90,7 +101,8 @@ static void delta_write_buf(struct mtd_info *mtd, const u_char *buf, int len) unsigned long rest = len & 0x3; unsigned long *long_buf; int i; - + + DFC_DEBUG2("delta_write_buf: writing %d bytes starting with 0x%x.\n", len, *((unsigned long*) buf)); if(bytes_multi) { for(i=0; ipriv pointer */ static unsigned long read_buf = 0; static int bytes_read = -1; +static unsigned long last_cmd = 0; /* read a byte from NDDB Because we can only read 4 bytes from NDDB at * a time, we buffer the remaining bytes. The buffer is reset when a @@ -176,16 +190,18 @@ static u_char delta_read_byte(struct mtd_info *mtd) { /* struct nand_chip *this = mtd->priv; */ unsigned char byte; + unsigned long dummy; if(bytes_read < 0) { read_buf = NDDB; + dummy = NDDB; bytes_read = 0; } byte = (unsigned char) (read_buf>>(8 * bytes_read++)); if(bytes_read >= 4) bytes_read = -1; - DFC_DEBUG2("delta_read_byte: byte %u: 0x%x of (0x%x).\n", bytes_read, byte, read_buf); + DFC_DEBUG2("delta_read_byte: byte %u: 0x%x of (0x%x).\n", bytes_read - 1, byte, read_buf); return byte; } @@ -330,13 +346,15 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, /* clear the ugly byte read buffer */ bytes_read = -1; read_buf = 0; - + last_cmd = 0; + /* if command is a double byte cmd, we set bit double cmd bit 19 */ /* command2 = (command>>8) & 0xFF; */ /* ndcb0 = command | ((command2 ? 1 : 0) << 19); *\/ */ switch (command) { case NAND_CMD_READ0: + DFC_DEBUG3("delta_cmdfunc: NAND_CMD_READ0, page_addr: 0x%x, column: 0x%x.\n", page_addr, (column>>1)); delta_new_cmd(); ndcb0 = (NAND_CMD_READ0 | (4<<16)); column >>= 1; /* adjust for 16 bit bus */ @@ -346,7 +364,14 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, ((page_addr<<8) & 0xff000000)); /* make this 0x01000000 ? */ event = NDSR_RDDREQ; goto write_cmd; + case NAND_CMD_READ1: + DFC_DEBUG2("delta_cmdfunc: NAND_CMD_READ1 unimplemented!\n"); + goto end; + case NAND_CMD_READOOB: + DFC_DEBUG1("delta_cmdfunc: NAND_CMD_READOOB unimplemented!\n"); + goto end; case NAND_CMD_READID: + last_cmd = NAND_CMD_READID; delta_new_cmd(); DFC_DEBUG2("delta_cmdfunc: NAND_CMD_READID.\n"); ndcb0 = (NAND_CMD_READID | (3 << 21) | (1 << 16)); /* addr cycles*/ @@ -357,7 +382,7 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, DFC_DEBUG2("delta_cmdfunc: NAND_CMD_PAGEPROG empty due to multicmd.\n"); goto end; case NAND_CMD_ERASE1: - DFC_DEBUG2("delta_cmdfunc: NAND_CMD_ERASE1.\n"); + DFC_DEBUG2("delta_cmdfunc: NAND_CMD_ERASE1, page_addr: 0x%x, column: 0x%x.\n", page_addr, (column>>1)); delta_new_cmd(); ndcb0 = (0xd060 | (1<<25) | (2<<21) | (1<<19) | (3<<16)); ndcb1 = (page_addr & 0x00ffffff); @@ -368,7 +393,7 @@ static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, case NAND_CMD_SEQIN: /* send PAGE_PROG command(0x1080) */ delta_new_cmd(); - DFC_DEBUG2("delta_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG.\n"); + DFC_DEBUG2("delta_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG, page_addr: 0x%x, column: 0x%x.\n", page_addr, (column>>1)); ndcb0 = (0x1080 | (1<<25) | (1<<21) | (1<<19) | (4<<16)); column >>= 1; /* adjust for 16 bit bus */ ndcb1 = (((column>>1) & 0xff) | @@ -562,6 +587,7 @@ void board_nand_init(struct nand_chip *nand) #define MIN(x, y) ((x < y) ? x : y) +#undef CFG_TIMING_TIGHT #ifndef CFG_TIMING_TIGHT tCH = MIN(((unsigned long) (NAND_TIMING_tCH * DFC_CLK_PER_US) + 1), DFC_MAX_tCH); @@ -646,7 +672,7 @@ void board_nand_init(struct nand_chip *nand) NDCR = (NDCR_SPARE_EN | /* use the spare area */ NDCR_DWIDTH_C | /* 16bit DFC data bus width */ NDCR_DWIDTH_M | /* 16 bit Flash device data bus width */ - (7 << 16) | /* read id count = 7 ???? mk@tbd */ + (2 << 16) | /* read id count = 7 ???? mk@tbd */ NDCR_ND_ARB_EN | /* enable bus arbiter */ NDCR_RDYM | /* flash device ready ir masked */ NDCR_CS0_PAGEDM | /* ND_nCSx page done ir masked */ diff --git a/drivers/nand/nand_base.c b/drivers/nand/nand_base.c index b039c3cd8c..a5792cfb52 100644 --- a/drivers/nand/nand_base.c +++ b/drivers/nand/nand_base.c @@ -489,6 +489,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) return nand_write_oob (mtd, ofs , 2, &retlen, buf); } +#if READ_STATUS_BUG /** * nand_check_wp - [GENERIC] check if the chip is write protected * @mtd: MTD device structure @@ -503,7 +504,12 @@ static int nand_check_wp (struct mtd_info *mtd) this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); return (this->read_byte(mtd) & 0x80) ? 0 : 1; } - +#else +static int nand_check_wp (struct mtd_info *mtd) +{ + return 0; +} +#endif /** * nand_block_checkbad - [GENERIC] Check if a block is marked bad * @mtd: MTD device structure @@ -1721,6 +1727,8 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, numpages = min (totalpages, ppblock); page &= this->pagemask; startpage = page; + oob = 0; + this->oobdirty = 1; oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, autoplace, numpages); /* Check, if we cross a chip boundary */ @@ -2145,13 +2153,14 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb instr->state = MTD_ERASING; while (len) { +#ifndef NAND_ALLOW_ERASE_ALL /* Check if we have a bad block, we do not erase bad blocks ! */ if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) { printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page); instr->state = MTD_ERASE_FAILED; goto erase_exit; } - +#endif /* Invalidate the page cache, if we erase the block which contains the current cached page */ if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block)) diff --git a/include/configs/delta.h b/include/configs/delta.h index 99ce0f621b..3a94661caf 100644 --- a/include/configs/delta.h +++ b/include/configs/delta.h @@ -43,7 +43,7 @@ /* * Size of malloc() pool */ -#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024) +#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 256*1024) #define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ /* @@ -164,7 +164,7 @@ */ /* Use the new NAND code. (BOARDLIBS = drivers/nand/libnand.a required) */ #define CONFIG_NEW_NAND_CODE -#define CFG_NAND0_BASE 0x43100040 /* 0x10000000 */ +#define CFG_NAND0_BASE 0x0 /* 0x43100040 */ /* 0x10000000 */ #undef CFG_NAND1_BASE #define CFG_NAND_BASE_LIST { CFG_NAND0_BASE } @@ -174,9 +174,13 @@ #define NAND_DELAY_US 25 /* mk@tbd: could be 0, I guess */ /* nand timeout values */ -#define CFG_NAND_PROG_ERASE_TO 300 +#define CFG_NAND_PROG_ERASE_TO 3000 #define CFG_NAND_OTHER_TO 100 #define CFG_NAND_SENDCMD_RETRY 3 +#define NAND_ALLOW_ERASE_ALL 1 + +#define CONFIG_MTD_DEBUG +#define CONFIG_MTD_DEBUG_VERBOSE 1 #define ADDR_COLUMN 1 #define ADDR_PAGE 2