[U-Boot] [PATCH] OneNAND: Runtime badblock support

At bootloader, we don't need to read full page. It takes too long time. Instead it only read pages required for boot. Of course, this patch reduces the boot time
Signed-off-by: Kyungmin Park kyungmin.park@samsung.com --- diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c index c4bdb57..8bc9e8a 100644 --- a/drivers/mtd/onenand/onenand_bbt.c +++ b/drivers/mtd/onenand/onenand_bbt.c @@ -48,6 +48,43 @@ static int check_short_pattern(uint8_t * buf, int len, int paglen, return 0; }
+static int read_page_oob(struct mtd_info *mtd, loff_t from, u_char *buf) +{ + struct onenand_chip *this = mtd->priv; + struct bbm_info *bbm = this->bbm; + struct nand_bbt_descr *bd = bbm->badblock_pattern; + struct mtd_oob_ops ops; + int ret, scanlen, block, j, res; + + scanlen = 0; + + ops.mode = MTD_OOB_PLACE; + ops.ooblen = 16; + ops.oobbuf = buf; + ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0; + + /* Get block number * 2 */ + block = (int)(from >> (bbm->bbt_erase_shift - 1)); + + /* Set as normal block */ + res = 0x00; + bbm->bbt[block >> 3] |= 0x00 << (block & 0x6); + + for (j = 0; j < 2; j++) { + ret = onenand_bbt_read_oob(mtd, from + j * mtd->writesize + bd->offs, &ops); + if (ret || check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) { + bbm->bbt[block >> 3] |= 0x03 << (block & 0x6); + res = 0x03; + printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n", + block >> 1, (unsigned int) from); + mtd->ecc_stats.badblocks++; + break; + } + } + + return ret; +} + /** * create_bbt - [GENERIC] Create a bad block table by scanning the device * @param mtd MTD device structure @@ -155,6 +192,11 @@ static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) block = (int)(offs >> (bbm->bbt_erase_shift - 1)); res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
+ if (this->options & ONENAND_RUNTIME_BADBLOCK_CHECK) { + if (res == 0x02) + res = read_page_oob(mtd, offs, this->oob_buf); + } + MTDDEBUG (MTD_DEBUG_LEVEL2, "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n", (unsigned int)offs, block >> 1, res); @@ -210,6 +252,12 @@ int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) if (!bbm->isbad_bbt) bbm->isbad_bbt = onenand_isbad_bbt;
+ if (this->options & ONENAND_RUNTIME_BADBLOCK_CHECK) { + printk(KERN_INFO "Scanning device for bad blocks (skipped)\n"); + memset(bbm->bbt, 0xaa, len); + return 0; + } + /* Scan the device to build a memory based bad block table */ if ((ret = onenand_memory_bbt(mtd, bd))) { printk(KERN_ERR diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index 4b0c923..76dfce4 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h @@ -135,6 +135,7 @@ struct onenand_chip { #define ONENAND_HAS_CONT_LOCK (0x0001) #define ONENAND_HAS_UNLOCK_ALL (0x0002) #define ONENAND_HAS_2PLANE (0x0004) +#define ONENAND_RUNTIME_BADBLOCK_CHECK (0x0200) #define ONENAND_PAGEBUF_ALLOC (0x1000) #define ONENAND_OOBBUF_ALLOC (0x2000)

Dear Kyungmin Park,
In message 20090721095528.GA23408@july you wrote:
At bootloader, we don't need to read full page. It takes too long time. Instead it only read pages required for boot. Of course, this patch reduces the boot time
What does "don't need to read full page" mean? when we read pages, we always read fullpages, don't we?
@@ -155,6 +192,11 @@ static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) block = (int)(offs >> (bbm->bbt_erase_shift - 1)); res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
- if (this->options & ONENAND_RUNTIME_BADBLOCK_CHECK) {
if (res == 0x02)
res = read_page_oob(mtd, offs, this->oob_buf);
- }
ONENAND_RUNTIME_BADBLOCK_CHECK is a new #define, right? It should be documented (for example in the README, or even better in doc/README.OneNand or so).
Best regards,
Wolfgang Denk

Hi,
On Tue, Jul 21, 2009 at 7:50 PM, Wolfgang Denkwd@denx.de wrote:
Dear Kyungmin Park,
In message 20090721095528.GA23408@july you wrote:
At bootloader, we don't need to read full page. It takes too long time. Instead it only read pages required for boot. Of course, this patch reduces the boot time
What does "don't need to read full page" mean?
It means all blocks at scanning time.
when we read pages, we always read fullpages, don't we?
@@ -155,6 +192,11 @@ static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) block = (int)(offs >> (bbm->bbt_erase_shift - 1)); res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
- if (this->options & ONENAND_RUNTIME_BADBLOCK_CHECK) {
- if (res == 0x02)
- res = read_page_oob(mtd, offs, this->oob_buf);
- }
ONENAND_RUNTIME_BADBLOCK_CHECK is a new #define, right? It should be documented (for example in the README, or even better in doc/README.OneNand or so).
It's OneNAND specific option. Umm I'll try to describe it
Thank you, Kyungmin Park
participants (2)
-
Kyungmin Park
-
Wolfgang Denk