]> git.sur5r.net Git - u-boot/blobdiff - drivers/mtd/altera_qspi.c
mtd: spi: Correct parameters for s25fs512s flash
[u-boot] / drivers / mtd / altera_qspi.c
index 617bf5d72de36b8f8353c8791e3d16ce9da1b917..1d32febe07c863f7fc7c71e423a54f535ea846c6 100644 (file)
@@ -1,10 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
+#include <console.h>
 #include <dm.h>
 #include <errno.h>
 #include <fdt_support.h>
@@ -52,6 +52,7 @@ struct altera_qspi_platdata {
        unsigned long size;
 };
 
+static uint flash_verbose;
 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];   /* FLASH chips info */
 
 static void altera_qspi_get_locked_range(struct mtd_info *mtd, loff_t *ofs,
@@ -74,6 +75,11 @@ void flash_print_info(flash_info_t *info)
        putc('\n');
 }
 
+void flash_set_verbose(uint v)
+{
+       flash_verbose = v;
+}
+
 int flash_erase(flash_info_t *info, int s_first, int s_last)
 {
        struct mtd_info *mtd = info->mtd;
@@ -81,12 +87,16 @@ int flash_erase(flash_info_t *info, int s_first, int s_last)
        int ret;
 
        memset(&instr, 0, sizeof(instr));
+       instr.mtd = mtd;
        instr.addr = mtd->erasesize * s_first;
        instr.len = mtd->erasesize * (s_last + 1 - s_first);
+       flash_set_verbose(1);
        ret = mtd_erase(mtd, &instr);
+       flash_set_verbose(0);
        if (ret)
                return ERR_PROTECTED;
 
+       puts(" done\n");
        return 0;
 }
 
@@ -130,23 +140,49 @@ 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, &regs->mem_op);
-               stat = readl(&regs->isr);
-               if (stat & QUADSPI_ISR_ILLEGAL_ERASE) {
-                       /* erase failed, sector might be protected */
-                       debug("erase %08x fail %x\n", sect, stat);
-                       writel(stat, &regs->isr); /* clear isr */
+               if (ctrlc()) {
+                       if (flash_verbose)
+                               putc('\n');
+                       instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
                        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, &regs->mem_op);
+                       stat = readl(&regs->isr);
+                       if (stat & QUADSPI_ISR_ILLEGAL_ERASE) {
+                               /* erase failed, sector might be protected */
+                               debug("erase %08x fail %x\n", sect, stat);
+                               writel(stat, &regs->isr); /* clear isr */
+                               instr->fail_addr = addr;
+                               instr->state = MTD_ERASE_FAILED;
+                               mtd_erase_callback(instr);
+                               return -EIO;
+                       }
+                       if (flash_verbose)
+                               putc('.');
+               } else {
+                       if (flash_verbose)
+                               putc(',');
+               }
                addr += mtd->erasesize;
        }
        instr->state = MTD_ERASE_DONE;
@@ -312,7 +348,7 @@ static int altera_qspi_ofdata_to_platdata(struct udevice *dev)
 {
        struct altera_qspi_platdata *pdata = dev_get_platdata(dev);
        void *blob = (void *)gd->fdt_blob;
-       int node = dev->of_offset;
+       int node = dev_of_offset(dev);
        const char *list, *end;
        const fdt32_t *cell;
        void *base;
@@ -325,7 +361,7 @@ static int altera_qspi_ofdata_to_platdata(struct udevice *dev)
         * match with reg-names.
         */
        parent = fdt_parent_offset(blob, node);
-       of_bus_default_count_cells(blob, parent, &addrc, &sizec);
+       fdt_support_default_count_cells(blob, parent, &addrc, &sizec);
        list = fdt_getprop(blob, node, "reg-names", &len);
        if (!list)
                return -ENOENT;