#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
#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];
int i;
char *cp;
- cp = (unsigned char *) &data;
+ cp = (char *) &data;
for (i = 0; i < 8; i++)
sprintf (&str[i * 2], "%2.2x", *cp++);
}
}
}
-/* 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;
}
{
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);
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;
}
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
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
- } else {
+ } else if (flash_verbose) {
putc ('\n');
}
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;
}
*/
#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)
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!
*
case 0x001f:
flash_fixup_atmel(info, &qry);
break;
+ case 0x0020:
+ flash_fixup_stm(info, &qry);
+ break;
}
debug ("manufacturer is %d\n", info->vendor);
return (info->size);
}
+void flash_set_verbose(uint v)
+{
+ flash_verbose = v;
+}
+
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
flash_get_info(apl[i].start));
}
#endif
+
+#ifdef CONFIG_FLASH_CFI_MTD
+ cfi_mtd_init();
+#endif
+
return (size);
}