[U-Boot-Users] [PATCH 2/7 v5] Simplify reading of the bad-block marker, use chipselect
Guennadi Liakhovetski
lg at denx.de
Tue Aug 5 15:36:43 CEST 2008
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 <lg at denx.de>
---
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
More information about the U-Boot
mailing list