We have to read a whole page on large-page NAND chips, at least the chip installed on SMDK6400 can only read whole pages with READ0. Also activate chipselect before using the chip, and deactivate it afterwards.
Signed-off-by: Guennadi Liakhovetski <[EMAIL PROTECTED]> --- nand_spl/nand_boot.c | 69 +++++++++++++++++++++++++++---------------------- 1 files changed, 38 insertions(+), 31 deletions(-) diff --git a/nand_spl/nand_boot.c b/nand_spl/nand_boot.c index 0f56ba5..8cd0046 100644 --- a/nand_spl/nand_boot.c +++ b/nand_spl/nand_boot.c @@ -132,21 +132,6 @@ static int nand_command(struct mtd_info *mtd, int block, int page, int offs, u8 } #endif -static int nand_is_bad_block(struct mtd_info *mtd, int block) -{ - struct nand_chip *this = mtd->priv; - - nand_command(mtd, block, 0, CFG_NAND_BAD_BLOCK_POS, NAND_CMD_READOOB); - - /* - * Read one byte - */ - if (in_8(this->IO_ADDR_R) != 0xff) - return 1; - - return 0; -} - static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst) { struct nand_chip *this = mtd->priv; @@ -154,8 +139,6 @@ static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst) u_char *ecc_code; u_char *oob_data; int i; - int eccsize = CFG_NAND_ECCSIZE; - int eccbytes = CFG_NAND_ECCBYTES; int eccsteps = CFG_NAND_ECCSTEPS; uint8_t *p = dst; int stat; @@ -167,11 +150,12 @@ static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst) */ ecc_calc = (u_char *)(CFG_SDRAM_BASE + 0x10000); ecc_code = ecc_calc + 0x100; - oob_data = ecc_calc + 0x200; + oob_data = p + CFG_NAND_PAGE_SIZE; /* Append OOB to the page data */ - for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { + for (i = 0; eccsteps; + eccsteps--, i += CFG_NAND_ECCBYTES, p += CFG_NAND_ECCSIZE) { this->ecc.hwctl(mtd, NAND_ECC_READ); - this->read_buf(mtd, p, eccsize); + this->read_buf(mtd, p, CFG_NAND_ECCSIZE); this->ecc.calculate(mtd, p, &ecc_calc[i]); } this->read_buf(mtd, oob_data, CFG_NAND_OOBSIZE); @@ -183,7 +167,8 @@ static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst) eccsteps = CFG_NAND_ECCSTEPS; p = dst; - for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { + for (i = 0; eccsteps; + eccsteps--, i += CFG_NAND_ECCBYTES, p += CFG_NAND_ECCSIZE) { /* No chance to do something with the possible error message * from correct_data(). We just hope that all possible errors * are corrected by this routine. @@ -199,25 +184,41 @@ static int nand_load(struct mtd_info *mtd, int offs, int uboot_size, uchar *dst) int block; int blockcopy_count; int page; + unsigned int read = 0; /* - * offs has to be aligned to a block address! + * offs has to be aligned to a page address! */ block = offs / CFG_NAND_BLOCK_SIZE; + /* Recalculate offs as an offset inside a block */ + offs -= CFG_NAND_BLOCK_SIZE * block; blockcopy_count = 0; - while (blockcopy_count < (uboot_size / CFG_NAND_BLOCK_SIZE)) { - if (!nand_is_bad_block(mtd, block)) { - /* - * Skip bad blocks - */ - for (page = 0; page < CFG_NAND_PAGE_COUNT; page++) { - nand_read_page(mtd, block, page, dst); - dst += CFG_NAND_PAGE_SIZE; + while (blockcopy_count < ((uboot_size + CFG_NAND_BLOCK_SIZE - 1) / + CFG_NAND_BLOCK_SIZE)) { + /* + * Skip bad blocks + */ + int badblock = 0; + for (page = 0; page < CFG_NAND_PAGE_COUNT; page++) { + nand_read_page(mtd, block, page, dst); + if ((page == 0 +#ifdef CFG_NAND_BBT_2NDPAGE + || page == 1 +#endif + ) && dst[CFG_NAND_PAGE_SIZE + + CFG_NAND_BAD_BLOCK_POS] != 0xff) { + badblock = 1; + break; } + /* Overwrite skipped pages */ + if (read >= offs) + dst += CFG_NAND_PAGE_SIZE; + read += CFG_NAND_PAGE_SIZE; + } + if (!badblock) blockcopy_count++; - } block++; } @@ -245,12 +246,18 @@ void nand_boot(void) nand_chip.dev_ready = NULL; /* preset to NULL */ board_nand_init(&nand_chip); + if (nand_chip.select_chip) + nand_chip.select_chip(&nand_info, 0); + /* * Load U-Boot image from NAND into RAM */ ret = nand_load(&nand_info, CFG_NAND_U_BOOT_OFFS, CFG_NAND_U_BOOT_SIZE, (uchar *)CFG_NAND_U_BOOT_DST); + if (nand_chip.select_chip) + nand_chip.select_chip(&nand_info, -1); + /* * Jump to U-Boot image */ -- 1.5.4 ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ U-Boot-Users mailing list U-Boot-Users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/u-boot-users