]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/mtd/cfi_flash.c
Fix compiler warning
[karo-tx-uboot.git] / drivers / mtd / cfi_flash.c
index f10d5fea18f0a13baac8b9ac7fb6a9817d9ba24b..bfb1f9f3b5f13759c8d06c2a33a871161a83e9b6 100644 (file)
@@ -158,6 +158,7 @@ typedef union {
 #define NUM_ERASE_REGIONS      4 /* max. number of erase regions */
 
 static uint flash_offset_cfi[2] = { FLASH_OFFSET_CFI, FLASH_OFFSET_CFI_ALT };
+static uint flash_verbose = 1;
 
 /* use CONFIG_SYS_MAX_FLASH_BANKS_DETECT if defined */
 #ifdef CONFIG_SYS_MAX_FLASH_BANKS_DETECT
@@ -175,8 +176,6 @@ flash_info_t flash_info[CFI_MAX_FLASH_BANKS];       /* FLASH chips info */
 #define CONFIG_SYS_FLASH_CFI_WIDTH     FLASH_CFI_8BIT
 #endif
 
-typedef unsigned long flash_sect_t;
-
 /* CFI standard query structure */
 struct cfi_qry {
        u8      qry[3];
@@ -355,7 +354,7 @@ static void print_longlong (char *str, unsigned long long data)
        int i;
        char *cp;
 
-       cp = (unsigned char *) &data;
+       cp = (char *) &data;
        for (i = 0; i < 8; i++)
                sprintf (&str[i * 2], "%2.2x", *cp++);
 }
@@ -775,17 +774,26 @@ static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)
        }
 }
 
-/* loop through the sectors from the highest address when the passed
- * address is greater or equal to the sector address we have a match
+/*
+ * Loop through the sector table starting from the previously found sector.
+ * Searches forwards or backwards, dependent on the passed address.
  */
 static flash_sect_t find_sector (flash_info_t * info, ulong addr)
 {
-       flash_sect_t sector;
+       static flash_sect_t saved_sector = 0; /* previously found sector */
+       flash_sect_t sector = saved_sector;
 
-       for (sector = info->sector_count - 1; sector >= 0; sector--) {
-               if (addr >= info->start[sector])
-                       break;
-       }
+       while ((info->start[sector] < addr)
+                       && (sector < info->sector_count - 1))
+               sector++;
+       while ((info->start[sector] > addr) && (sector > 0))
+               /*
+                * also decrements the sector in case of an overshot
+                * in the first loop
+                */
+               sector--;
+
+       saved_sector = sector;
        return sector;
 }
 
@@ -796,7 +804,8 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
 {
        void *dstaddr;
        int flag;
-       flash_sect_t sect;
+       flash_sect_t sect = 0;
+       char sect_found = 0;
 
        dstaddr = map_physmem(dest, info->portwidth, MAP_NOCACHE);
 
@@ -841,6 +850,7 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
                sect = find_sector(info, dest);
                flash_unlock_seq (info, sect);
                flash_write_cmd (info, sect, info->addr_unlock1, AMD_CMD_WRITE);
+               sect_found = 1;
                break;
        }
 
@@ -865,8 +875,10 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
 
        unmap_physmem(dstaddr, info->portwidth);
 
-       return flash_full_status_check (info, find_sector (info, dest),
-                                       info->write_tout, "write");
+       if (!sect_found)
+               sect = find_sector (info, dest);
+
+       return flash_full_status_check (info, sect, info->write_tout, "write");
 }
 
 #ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
@@ -1072,7 +1084,7 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
        if (prot) {
                printf ("- Warning: %d protected sectors will not be erased!\n",
                        prot);
-       } else {
+       } else if (flash_verbose) {
                putc ('\n');
        }
 
@@ -1119,11 +1131,14 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
                        if (flash_full_status_check
                            (info, sect, info->erase_blk_tout, "erase")) {
                                rcode = 1;
-                       } else
+                       } else if (flash_verbose)
                                putc ('.');
                }
        }
-       puts (" done\n");
+
+       if (flash_verbose)
+               puts (" done\n");
+
        return rcode;
 }
 
@@ -1235,14 +1250,16 @@ void flash_print_info (flash_info_t * info)
  */
 #ifdef CONFIG_FLASH_SHOW_PROGRESS
 #define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub) \
-       dots -= dots_sub; \
-       if ((scale > 0) && (dots <= 0)) { \
-               if ((digit % 5) == 0) \
-                       printf ("%d", digit / 5); \
-               else \
-                       putc ('.'); \
-               digit--; \
-               dots += scale; \
+       if (flash_verbose) { \
+               dots -= dots_sub; \
+               if ((scale > 0) && (dots <= 0)) { \
+                       if ((digit % 5) == 0) \
+                               printf ("%d", digit / 5); \
+                       else \
+                               putc ('.'); \
+                       digit--; \
+                       dots += scale; \
+               } \
        }
 #else
 #define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub)
@@ -1791,6 +1808,20 @@ static void flash_fixup_atmel(flash_info_t *info, struct cfi_qry *qry)
                cfi_reverse_geometry(qry);
 }
 
+static void flash_fixup_stm(flash_info_t *info, struct cfi_qry *qry)
+{
+       /* check if flash geometry needs reversal */
+       if (qry->num_erase_regions > 1) {
+               /* reverse geometry if top boot part */
+               if (info->cfi_version < 0x3131) {
+                       /* CFI < 1.1, guess by device id (only M29W320ET now) */
+                       if (info->device_id == 0x2256) {
+                               cfi_reverse_geometry(qry);
+                       }
+               }
+       }
+}
+
 /*
  * The following code cannot be run from FLASH!
  *
@@ -1864,6 +1895,9 @@ ulong flash_get_size (ulong base, int banknum)
                case 0x001f:
                        flash_fixup_atmel(info, &qry);
                        break;
+               case 0x0020:
+                       flash_fixup_stm(info, &qry);
+                       break;
                }
 
                debug ("manufacturer is %d\n", info->vendor);
@@ -1960,6 +1994,11 @@ ulong flash_get_size (ulong base, int banknum)
        return (info->size);
 }
 
+void flash_set_verbose(uint v)
+{
+       flash_verbose = v;
+}
+
 /*-----------------------------------------------------------------------
  */
 unsigned long flash_init (void)
@@ -2078,5 +2117,10 @@ unsigned long flash_init (void)
                               flash_get_info(apl[i].start));
        }
 #endif
+
+#ifdef CONFIG_FLASH_CFI_MTD
+       cfi_mtd_init();
+#endif
+
        return (size);
 }