diff options
author | Thomas Chou <thomas@wytron.com.tw> | 2015-12-23 10:33:52 +0800 |
---|---|---|
committer | Thomas Chou <thomas@wytron.com.tw> | 2015-12-28 09:32:43 +0800 |
commit | f81a673ec4505553ce8d0362f9b8371a8e51c015 (patch) | |
tree | 4376eca3a3e084f9dec6bb224b958393dab8be05 | |
parent | a1b1d7eceb033c256ae661d65732323809fb9101 (diff) | |
download | u-boot-imx-f81a673ec4505553ce8d0362f9b8371a8e51c015.zip u-boot-imx-f81a673ec4505553ce8d0362f9b8371a8e51c015.tar.gz u-boot-imx-f81a673ec4505553ce8d0362f9b8371a8e51c015.tar.bz2 |
altera_qspi: skip erase if the sector is blank
Skip erase if the sector is blank. The sector erase is slow, and
may take 0.7 sec typically or up to 3 sec worst-case.
Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
-rw-r--r-- | drivers/mtd/altera_qspi.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/drivers/mtd/altera_qspi.c b/drivers/mtd/altera_qspi.c index b0d4f2c..8a630a6 100644 --- a/drivers/mtd/altera_qspi.c +++ b/drivers/mtd/altera_qspi.c @@ -131,24 +131,35 @@ static int altera_qspi_erase(struct mtd_info *mtd, struct erase_info *instr) size_t end = addr + len; u32 sect; u32 stat; + u32 *flash, *last; instr->state = MTD_ERASING; addr &= ~(mtd->erasesize - 1); /* get lower aligned address */ while (addr < end) { - sect = addr / mtd->erasesize; - sect <<= 8; - sect |= QUADSPI_MEM_OP_SECTOR_ERASE; - debug("erase %08x\n", sect); - writel(sect, ®s->mem_op); - stat = readl(®s->isr); - if (stat & QUADSPI_ISR_ILLEGAL_ERASE) { - /* erase failed, sector might be protected */ - debug("erase %08x fail %x\n", sect, stat); - writel(stat, ®s->isr); /* clear isr */ - instr->fail_addr = addr; - instr->state = MTD_ERASE_FAILED; - mtd_erase_callback(instr); - return -EIO; + flash = pdata->base + addr; + last = pdata->base + addr + mtd->erasesize; + /* skip erase if sector is blank */ + while (flash < last) { + if (readl(flash) != 0xffffffff) + break; + flash++; + } + if (flash < last) { + sect = addr / mtd->erasesize; + sect <<= 8; + sect |= QUADSPI_MEM_OP_SECTOR_ERASE; + debug("erase %08x\n", sect); + writel(sect, ®s->mem_op); + stat = readl(®s->isr); + if (stat & QUADSPI_ISR_ILLEGAL_ERASE) { + /* erase failed, sector might be protected */ + debug("erase %08x fail %x\n", sect, stat); + writel(stat, ®s->isr); /* clear isr */ + instr->fail_addr = addr; + instr->state = MTD_ERASE_FAILED; + mtd_erase_callback(instr); + return -EIO; + } } addr += mtd->erasesize; } |