From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marek Vasut Date: Thu, 24 Dec 2015 02:28:39 +0100 Subject: [U-Boot] [PATCH 3/5] altera_qspi: skip erase if the sector is blank In-Reply-To: <1450918284-16174-3-git-send-email-thomas@wytron.com.tw> References: <1450918284-16174-1-git-send-email-thomas@wytron.com.tw> <1450918284-16174-3-git-send-email-thomas@wytron.com.tw> Message-ID: <201512240228.39571.marex@denx.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On Thursday, December 24, 2015 at 01:51:22 AM, Thomas Chou wrote: > 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 > --- > drivers/mtd/altera_qspi.c | 39 +++++++++++++++++++++++++-------------- > 1 file 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++; Shouldn't $last be divided by 4 ? $flash is u32 * afterall . > + } > + 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; > } Best regards, Marek Vasut