I referred to this http://git.infradead.org/mtd-2.6.git?a=commit;h=69423d99fc182a81f3c5db3eb5c140acc6fc64be
and picked up the MTD NAND specific stuff > From: Sandeep Paulraj <s-paul...@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-paul...@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 */ > -- > 1.6.0.4 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot