[U-Boot] [PATCH] NAND: Update to support 64 bit device size

From: Sandeep Paulraj s-paulraj@ti.com
This patch adds support for NANDs greater than 2 GB. Patch is based on the MTD NAND driver in the kernel.
Signed-off-by: Sandeep Paulraj s-paulraj@ti.com --- Tested this on the DaVinci DM355 EVM. drivers/mtd/nand/nand_base.c | 29 +++++++++++++++++---------- drivers/mtd/nand/nand_bbt.c | 41 ++++++++++++++++++++++----------------- include/linux/mtd/nand.h | 2 +- include/linux/mtd/partitions.h | 4 +- 4 files changed, 44 insertions(+), 32 deletions(-)
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 426bb95..6848f28 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2211,13 +2211,15 @@ static int nand_erase(struct mtd_info *mtd, struct erase_info *instr) int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, int allowbbt) { - int page, len, status, pages_per_block, ret, chipnr; + int page, status, pages_per_block, ret, chipnr; struct nand_chip *chip = mtd->priv; - int rewrite_bbt[CONFIG_SYS_NAND_MAX_CHIPS]={0}; + loff_t rewrite_bbt[CONFIG_SYS_NAND_MAX_CHIPS] = {0}; unsigned int bbt_masked_page = 0xffffffff; + loff_t len;
- MTDDEBUG (MTD_DEBUG_LEVEL3, "nand_erase: start = 0x%08x, len = %i\n", - (unsigned int) instr->addr, (unsigned int) instr->len); + MTDDEBUG(MTD_DEBUG_LEVEL3, "nand_erase: start = 0x%012llx, " + "len = %llu\n", (unsigned long long) instr->addr, + (unsigned long long) instr->len);
/* Start address must align on block boundary */ if (instr->addr & ((1 << chip->phys_erase_shift) - 1)) { @@ -2313,7 +2315,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page); instr->state = MTD_ERASE_FAILED; - instr->fail_addr = (page << chip->page_shift); + instr->fail_addr = ((loff_t)page << chip->page_shift); goto erase_exit; }
@@ -2322,8 +2324,9 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, * page being erased */ if (bbt_masked_page != 0xffffffff && - (page & BBT_PAGE_MASK) == bbt_masked_page) - rewrite_bbt[chipnr] = (page << chip->page_shift); + (page & BBT_PAGE_MASK) == bbt_masked_page) + rewrite_bbt[chipnr] = ((loff_t)page << + chip->page_shift);
/* Increment page address and decrement length */ len -= (1 << chip->phys_erase_shift); @@ -2370,8 +2373,9 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, continue; /* update the BBT for chip */ MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt " - "(%d:0x%0x 0x%0x)\n", chipnr, rewrite_bbt[chipnr], - chip->bbt_td->pages[chipnr]); + "(%d:0x%0llx 0x%0x)\n", chipnr, + rewrite_bbt[chipnr], + chip->bbt_td->pages[chipnr]); nand_update_bbt(mtd, rewrite_bbt[chipnr]); }
@@ -2566,7 +2570,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, if (!mtd->name) mtd->name = type->name;
- chip->chipsize = type->chipsize << 20; + chip->chipsize = (uint64_t)type->chipsize << 20;
/* Newer devices have all the information in additional id bytes */ if (!type->pagesize) { @@ -2624,7 +2628,10 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
chip->bbt_erase_shift = chip->phys_erase_shift = ffs(mtd->erasesize) - 1; - chip->chip_shift = ffs(chip->chipsize) - 1; + if (chip->chipsize & 0xffffffff) + chip->chip_shift = ffs(chip->chipsize) - 1; + else + chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 31;
/* Set the bad block position */ chip->badblockpos = mtd->writesize > 512 ? diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index d68a315..1167c90 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -182,16 +182,19 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, if (tmp == msk) continue; if (reserved_block_code && (tmp == reserved_block_code)) { - printk(KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n", - ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); + printk(KERN_DEBUG "nand_read_bbt: Reserved block at 0x%012llx\n", + (loff_t)((offs << 2) + + (act >> 1)) << + this->bbt_erase_shift); this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06); mtd->ecc_stats.bbtblocks++; continue; } /* Leave it for now, if its matured we can move this * message to MTD_DEBUG_LEVEL0 */ - printk(KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n", - ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); + printk(KERN_DEBUG "nand_read_bbt: Bad block at 0x%012llx\n", + (loff_t)((offs << 2) + (act >> 1)) << + this->bbt_erase_shift); /* Factory marked bad or worn out ? */ if (tmp == 0) this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06); @@ -295,8 +298,8 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
/* Read the primary version, if available */ if (td->options & NAND_BBT_VERSION) { - scan_read_raw(mtd, buf, td->pages[0] << this->page_shift, - mtd->writesize); + scan_read_raw(mtd, buf, (loff_t)td->pages[0] << + this->page_shift, mtd->writesize); td->version[0] = buf[mtd->writesize + td->veroffs]; printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]); @@ -304,8 +307,8 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
/* Read the mirror version, if available */ if (md && (md->options & NAND_BBT_VERSION)) { - scan_read_raw(mtd, buf, md->pages[0] << this->page_shift, - mtd->writesize); + scan_read_raw(mtd, buf, (loff_t)md->pages[0] << + this->page_shift, mtd->writesize); md->version[0] = buf[mtd->writesize + md->veroffs]; printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]); @@ -422,7 +425,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, numblocks = this->chipsize >> (this->bbt_erase_shift - 1); startblock = chip * numblocks; numblocks += startblock; - from = startblock << (this->bbt_erase_shift - 1); + from = (loff_t)startblock << (this->bbt_erase_shift - 1); }
for (i = startblock; i < numblocks;) { @@ -440,8 +443,8 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, if (ret) { this->bbt[i >> 3] |= 0x03 << (i & 0x6); MTDDEBUG (MTD_DEBUG_LEVEL0, - "Bad eraseblock %d at 0x%08x\n", - i >> 1, (unsigned int)from); + "Bad eraseblock %d at 0x%012llx\n", + i >> 1, (unsigned long long)from); mtd->ecc_stats.badblocks++; }
@@ -507,7 +510,7 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr for (block = 0; block < td->maxblocks; block++) {
int actblock = startblock + dir * block; - loff_t offs = actblock << this->bbt_erase_shift; + loff_t offs = (loff_t)actblock << this->bbt_erase_shift;
/* Read first page */ scan_read_raw(mtd, buf, offs, mtd->writesize); @@ -731,7 +734,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
memset(&einfo, 0, sizeof(einfo)); einfo.mtd = mtd; - einfo.addr = (unsigned long)to; + einfo.addr = to; einfo.len = 1 << this->bbt_erase_shift; res = nand_erase_nand(mtd, &einfo, 1); if (res < 0) @@ -741,8 +744,9 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, if (res < 0) goto outerr;
- printk(KERN_DEBUG "Bad block table written to 0x%08x, version " - "0x%02X\n", (unsigned int)to, td->version[chip]); + printk(KERN_DEBUG "Bad block table written to 0x%012llx, " + "version 0x%02X\n", (unsigned long long)to, + td->version[chip]);
/* Mark it as used */ td->pages[chip] = page; @@ -922,7 +926,8 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) newval = oldval | (0x2 << (block & 0x06)); this->bbt[(block >> 3)] = newval; if ((oldval != newval) && td->reserved_block_code) - nand_update_bbt(mtd, block << (this->bbt_erase_shift - 1)); + nand_update_bbt(mtd, (loff_t)block << + (this->bbt_erase_shift - 1)); continue; } update = 0; @@ -943,7 +948,8 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) new ones have been marked, then we need to update the stored bbts. This should only happen once. */ if (update && td->reserved_block_code) - nand_update_bbt(mtd, (block - 2) << (this->bbt_erase_shift - 1)); + nand_update_bbt(mtd, (loff_t)(block - 2) << + (this->bbt_erase_shift - 1)); } }
@@ -1039,7 +1045,6 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs) if (!this->bbt || !td) return -EINVAL;
- len = mtd->size >> (this->bbt_erase_shift + 2); /* Allocate a temporary buffer for one eraseblock incl. oob */ len = (1 << this->bbt_erase_shift); len += (len >> this->page_shift) * mtd->oobsize; diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index cb7c19a..94ad0c0 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -397,7 +397,7 @@ struct nand_chip { int bbt_erase_shift; int chip_shift; int numchips; - unsigned long chipsize; + uint64_t chipsize; int pagemask; int pagebuf; int subpagesize; diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 1016675..d1d9a96 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -38,8 +38,8 @@
struct mtd_partition { char *name; /* identifier string */ - u_int32_t size; /* partition size */ - u_int32_t offset; /* offset within the master MTD space */ + uint64_t size; /* partition size */ + uint64_t offset; /* offset within the master MTD space */ u_int32_t mask_flags; /* master MTD flags to mask out for this partition */ struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/ struct mtd_info **mtdp; /* pointer to store the MTD object */

I referred to this
http://git.infradead.org/mtd-2.6.git?a=commit;h=69423d99fc182a81f3c5db3eb5c1...
and picked up the MTD NAND specific stuff
From: Sandeep Paulraj s-paulraj@ti.com
This patch adds support for NANDs greater than 2 GB. Patch is based on the MTD NAND driver in the kernel.
Signed-off-by: Sandeep Paulraj s-paulraj@ti.com
Tested this on the DaVinci DM355 EVM. drivers/mtd/nand/nand_base.c | 29 +++++++++++++++++---------- drivers/mtd/nand/nand_bbt.c | 41 ++++++++++++++++++++++-------------
include/linux/mtd/nand.h | 2 +- include/linux/mtd/partitions.h | 4 +- 4 files changed, 44 insertions(+), 32 deletions(-)
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 426bb95..6848f28 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2211,13 +2211,15 @@ static int nand_erase(struct mtd_info *mtd, struct erase_info *instr) int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, int allowbbt) {
- int page, len, status, pages_per_block, ret, chipnr;
- int page, status, pages_per_block, ret, chipnr; struct nand_chip *chip = mtd->priv;
- int rewrite_bbt[CONFIG_SYS_NAND_MAX_CHIPS]={0};
- loff_t rewrite_bbt[CONFIG_SYS_NAND_MAX_CHIPS] = {0}; unsigned int bbt_masked_page = 0xffffffff;
- loff_t len;
- MTDDEBUG (MTD_DEBUG_LEVEL3, "nand_erase: start = 0x%08x, len =
%i\n",
(unsigned int) instr->addr, (unsigned int) instr->len);
MTDDEBUG(MTD_DEBUG_LEVEL3, "nand_erase: start = 0x%012llx, "
"len = %llu\n", (unsigned long long) instr->addr,
(unsigned long long) instr->len);
/* Start address must align on block boundary */ if (instr->addr & ((1 << chip->phys_erase_shift) - 1)) {
@@ -2313,7 +2315,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page); instr->state = MTD_ERASE_FAILED;
instr->fail_addr = (page << chip->page_shift);
}instr->fail_addr = ((loff_t)page << chip->page_shift); goto erase_exit;
@@ -2322,8 +2324,9 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, * page being erased */ if (bbt_masked_page != 0xffffffff &&
(page & BBT_PAGE_MASK) == bbt_masked_page)
rewrite_bbt[chipnr] = (page << chip->page_shift);
(page & BBT_PAGE_MASK) == bbt_masked_page)
rewrite_bbt[chipnr] = ((loff_t)page <<
chip->page_shift);
/* Increment page address and decrement length */ len -= (1 << chip->phys_erase_shift);
@@ -2370,8 +2373,9 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, continue; /* update the BBT for chip */ MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt "
"(%d:0x%0x 0x%0x)\n", chipnr, rewrite_bbt[chipnr],
chip->bbt_td->pages[chipnr]);
"(%d:0x%0llx 0x%0x)\n", chipnr,
rewrite_bbt[chipnr],
nand_update_bbt(mtd, rewrite_bbt[chipnr]); }chip->bbt_td->pages[chipnr]);
@@ -2566,7 +2570,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, if (!mtd->name) mtd->name = type->name;
- chip->chipsize = type->chipsize << 20;
chip->chipsize = (uint64_t)type->chipsize << 20;
/* Newer devices have all the information in additional id bytes */ if (!type->pagesize) {
@@ -2624,7 +2628,10 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
chip->bbt_erase_shift = chip->phys_erase_shift = ffs(mtd->erasesize) - 1;
- chip->chip_shift = ffs(chip->chipsize) - 1;
if (chip->chipsize & 0xffffffff)
chip->chip_shift = ffs(chip->chipsize) - 1;
else
chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 31;
/* Set the bad block position */ chip->badblockpos = mtd->writesize > 512 ?
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index d68a315..1167c90 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -182,16 +182,19 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, if (tmp == msk) continue; if (reserved_block_code && (tmp == reserved_block_code)) {
printk(KERN_DEBUG "nand_read_bbt: Reserved
block at 0x%08x\n",
((offs << 2) + (act >> 1)) << this-
bbt_erase_shift);
printk(KERN_DEBUG "nand_read_bbt: Reserved
block at 0x%012llx\n",
(loff_t)((offs << 2) +
(act >> 1)) <<
this->bbt_erase_shift); this->bbt[offs + (act >> 3)] |= 0x2 << (act
& 0x06); mtd->ecc_stats.bbtblocks++; continue; } /* Leave it for now, if its matured we can move this * message to MTD_DEBUG_LEVEL0 */
printk(KERN_DEBUG "nand_read_bbt: Bad block at
0x%08x\n",
((offs << 2) + (act >> 1)) << this-
bbt_erase_shift);
printk(KERN_DEBUG "nand_read_bbt: Bad block at
0x%012llx\n",
(loff_t)((offs << 2) + (act >> 1)) <<
this->bbt_erase_shift); /* Factory marked bad or worn out ? */ if (tmp == 0) this->bbt[offs + (act >> 3)] |= 0x3 << (act
& 0x06); @@ -295,8 +298,8 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
/* Read the primary version, if available */ if (td->options & NAND_BBT_VERSION) {
scan_read_raw(mtd, buf, td->pages[0] << this->page_shift,
mtd->writesize);
scan_read_raw(mtd, buf, (loff_t)td->pages[0] <<
td->version[0] = buf[mtd->writesize + td->veroffs]; printk(KERN_DEBUG "Bad block table at page %d, versionthis->page_shift, mtd->writesize);
0x%02X\n", td->pages[0], td->version[0]); @@ -304,8 +307,8 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
/* Read the mirror version, if available */ if (md && (md->options & NAND_BBT_VERSION)) {
scan_read_raw(mtd, buf, md->pages[0] << this->page_shift,
mtd->writesize);
scan_read_raw(mtd, buf, (loff_t)md->pages[0] <<
md->version[0] = buf[mtd->writesize + md->veroffs]; printk(KERN_DEBUG "Bad block table at page %d, versionthis->page_shift, mtd->writesize);
0x%02X\n", md->pages[0], md->version[0]); @@ -422,7 +425,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, numblocks = this->chipsize >> (this->bbt_erase_shift - 1); startblock = chip * numblocks; numblocks += startblock;
from = startblock << (this->bbt_erase_shift - 1);
from = (loff_t)startblock << (this->bbt_erase_shift - 1);
}
for (i = startblock; i < numblocks;) {
@@ -440,8 +443,8 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, if (ret) { this->bbt[i >> 3] |= 0x03 << (i & 0x6); MTDDEBUG (MTD_DEBUG_LEVEL0,
"Bad eraseblock %d at 0x%08x\n",
i >> 1, (unsigned int)from);
"Bad eraseblock %d at 0x%012llx\n",
}i >> 1, (unsigned long long)from); mtd->ecc_stats.badblocks++;
@@ -507,7 +510,7 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr for (block = 0; block < td->maxblocks; block++) {
int actblock = startblock + dir * block;
loff_t offs = actblock << this->bbt_erase_shift;
loff_t offs = (loff_t)actblock << this->bbt_erase_shift; /* Read first page */ scan_read_raw(mtd, buf, offs, mtd->writesize);
@@ -731,7 +734,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
memset(&einfo, 0, sizeof(einfo)); einfo.mtd = mtd;
einfo.addr = (unsigned long)to;
einfo.len = 1 << this->bbt_erase_shift; res = nand_erase_nand(mtd, &einfo, 1); if (res < 0)einfo.addr = to;
@@ -741,8 +744,9 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, if (res < 0) goto outerr;
printk(KERN_DEBUG "Bad block table written to 0x%08x, version
"
"0x%02X\n", (unsigned int)to, td->version[chip]);
printk(KERN_DEBUG "Bad block table written to 0x%012llx, "
"version 0x%02X\n", (unsigned long long)to,
td->version[chip]);
/* Mark it as used */ td->pages[chip] = page;
@@ -922,7 +926,8 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) newval = oldval | (0x2 << (block & 0x06)); this->bbt[(block >> 3)] = newval; if ((oldval != newval) && td->reserved_block_code)
nand_update_bbt(mtd, block << (this-
bbt_erase_shift - 1));
nand_update_bbt(mtd, (loff_t)block <<
} update = 0;(this->bbt_erase_shift - 1)); continue;
@@ -943,7 +948,8 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) new ones have been marked, then we need to update the stored bbts. This should only happen once. */ if (update && td->reserved_block_code)
nand_update_bbt(mtd, (block - 2) << (this-
bbt_erase_shift - 1));
nand_update_bbt(mtd, (loff_t)(block - 2) <<
}(this->bbt_erase_shift - 1));
}
@@ -1039,7 +1045,6 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs) if (!this->bbt || !td) return -EINVAL;
- len = mtd->size >> (this->bbt_erase_shift + 2); /* Allocate a temporary buffer for one eraseblock incl. oob */ len = (1 << this->bbt_erase_shift); len += (len >> this->page_shift) * mtd->oobsize;
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index cb7c19a..94ad0c0 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -397,7 +397,7 @@ struct nand_chip { int bbt_erase_shift; int chip_shift; int numchips;
- unsigned long chipsize;
- uint64_t chipsize; int pagemask; int pagebuf; int subpagesize;
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 1016675..d1d9a96 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -38,8 +38,8 @@
struct mtd_partition { char *name; /* identifier string */
- u_int32_t size; /* partition size */
- u_int32_t offset; /* offset within the master MTD space */
- uint64_t size; /* partition size */
- uint64_t offset; /* offset within the master MTD space */ u_int32_t mask_flags; /* master MTD flags to mask out for
this partition */ struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/ struct mtd_info **mtdp; /* pointer to store the MTD object */ -- 1.6.0.4

On Fri, Oct 30, 2009 at 01:51:23PM -0400, s-paulraj@ti.com wrote:
From: Sandeep Paulraj s-paulraj@ti.com
This patch adds support for NANDs greater than 2 GB. Patch is based on the MTD NAND driver in the kernel.
Signed-off-by: Sandeep Paulraj s-paulraj@ti.com
Applied to u-boot-nand-flash/next, with a few whitespace changes that make it more like the upstream code (though it's still not identical, as upstream has some long lines that got wrapped in U-Boot). In particular, some things were double-tabbed, and existing alignment broken.
Here's the diff from the posted patch to what was applied:
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 6848f28..30a3e9e 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2218,8 +2218,8 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, loff_t len;
MTDDEBUG(MTD_DEBUG_LEVEL3, "nand_erase: start = 0x%012llx, " - "len = %llu\n", (unsigned long long) instr->addr, - (unsigned long long) instr->len); + "len = %llu\n", (unsigned long long) instr->addr, + (unsigned long long) instr->len);
/* Start address must align on block boundary */ if (instr->addr & ((1 << chip->phys_erase_shift) - 1)) { @@ -2324,9 +2324,9 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, * page being erased */ if (bbt_masked_page != 0xffffffff && - (page & BBT_PAGE_MASK) == bbt_masked_page) - rewrite_bbt[chipnr] = ((loff_t)page << - chip->page_shift); + (page & BBT_PAGE_MASK) == bbt_masked_page) + rewrite_bbt[chipnr] = + ((loff_t)page << chip->page_shift);
/* Increment page address and decrement length */ len -= (1 << chip->phys_erase_shift); @@ -2373,9 +2373,8 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, continue; /* update the BBT for chip */ MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt " - "(%d:0x%0llx 0x%0x)\n", chipnr, - rewrite_bbt[chipnr], - chip->bbt_td->pages[chipnr]); + "(%d:0x%0llx 0x%0x)\n", chipnr, rewrite_bbt[chipnr], + chip->bbt_td->pages[chipnr]); nand_update_bbt(mtd, rewrite_bbt[chipnr]); }
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 1167c90..2fe68ab 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -443,8 +443,8 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, if (ret) { this->bbt[i >> 3] |= 0x03 << (i & 0x6); MTDDEBUG (MTD_DEBUG_LEVEL0, - "Bad eraseblock %d at 0x%012llx\n", - i >> 1, (unsigned long long)from); + "Bad eraseblock %d at 0x%012llx\n", + i >> 1, (unsigned long long)from); mtd->ecc_stats.badblocks++; }
@@ -746,7 +746,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
printk(KERN_DEBUG "Bad block table written to 0x%012llx, " "version 0x%02X\n", (unsigned long long)to, - td->version[chip]); + td->version[chip]);
/* Mark it as used */ td->pages[chip] = page;

On Fri, Oct 30, 2009 at 01:51:23PM -0400, s-paulraj@ti.com wrote:
From: Sandeep Paulraj s-paulraj@ti.com
This patch adds support for NANDs greater than 2 GB. Patch is based on the MTD NAND driver in the kernel.
Signed-off-by: Sandeep Paulraj s-paulraj@ti.com
Applied to u-boot-nand-flash/next, with a few whitespace changes that make it more like the upstream code (though it's still not identical, as upstream has some long lines that got wrapped in U-Boot). In particular, some things were double-tabbed, and existing alignment broken.
Here's the diff from the posted patch to what was applied:
Scott,
Thanks for this. I have to update you and the list on some of my findings.
I had a 4GB SAMSUNG NAND and a 4GB MICRON NAND which earlier would not even get correctly detected by U-Boot and the DaVinci NAND driver. After adding this support I solved 2 issues
1) The above 2 NAND devices got correctly detected. 2) I believe due to incomplete 64 bit support while doing a "saveenv", the diagnostics were wrong. The env was getting saved but the address being displayed was obviously messed up. Adding this patch correctly displayed the address being saved to.
But we have other issues. Some of them are
1) doing a "nand bad" resulted in a kind of a continuous spin. U-boot correctly detects bad blocks but because we use 32 bit variables in cmd_nand.c it keeps finding the same bad blocks infinite times.
2) I fixed the above but then I had issues with nand read and write.
Basically to have fully functional NAND support we will need to completely update cmd_nand.c with 64 bit support I believe.
Its on my TODO list but if anybody beats me to this I'll be more than happy. My intention is to work on this the moment I get some free time (I wish I do get some soon but I cannot promise anything).
Also a quick look at the /common folder seems to suggest that we are not yet fully geared up for stuff more than 32 bit in general.
In any case its time we all started updating U-Boot for this.
Just though I'll update you and the list. Please do let me know if you have any issues as mentioned above. As always, I am always open to hear from anyone if any of my above observations are wrong.
Its my personal opinion that there is nothing wrong with my patch itself. I've just picked up the kernel's version. But there's still stuff to be done.
Thanks, Sandeep
participants (3)
-
Paulraj, Sandeep
-
s-paulraj@ti.com
-
Scott Wood