]> git.sur5r.net Git - u-boot/blobdiff - drivers/mtd/cfi_flash.c
Merge branch 'master' of git://git.denx.de/u-boot-mpc85xx
[u-boot] / drivers / mtd / cfi_flash.c
index 04a9a925868f5f5ad9eca2c6a91654b836826ac4..6eea49a11ea752c1b77ccade8447ea8b9a601984 100644 (file)
 #define ATM_CMD_SOFTLOCK_START         0x80
 #define ATM_CMD_LOCK_SECT              0x40
 
+#define FLASH_CONTINUATION_CODE                0x7F
+
 #define FLASH_OFFSET_MANUFACTURER_ID   0x00
 #define FLASH_OFFSET_DEVICE_ID         0x01
 #define FLASH_OFFSET_DEVICE_ID2                0x0E
@@ -273,7 +275,7 @@ u64 flash_read64(void *addr)__attribute__((weak, alias("__flash_read64")));
 /*-----------------------------------------------------------------------
  */
 #if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
-static flash_info_t *flash_get_info(ulong base)
+flash_info_t *flash_get_info(ulong base)
 {
        int i;
        flash_info_t * info = 0;
@@ -835,14 +837,19 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
                break;
        case CFI_CMDSET_AMD_EXTENDED:
        case CFI_CMDSET_AMD_STANDARD:
-#ifdef CONFIG_FLASH_CFI_LEGACY
-       case CFI_CMDSET_AMD_LEGACY:
-#endif
                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;
+#ifdef CONFIG_FLASH_CFI_LEGACY
+       case CFI_CMDSET_AMD_LEGACY:
+               sect = find_sector(info, dest);
+               flash_unlock_seq (info, 0);
+               flash_write_cmd (info, 0, info->addr_unlock1, AMD_CMD_WRITE);
+               sect_found = 1;
+               break;
+#endif
        }
 
        switch (info->portwidth) {
@@ -996,7 +1003,7 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
 #endif
                flash_write_cmd(info, sector, offset, AMD_CMD_WRITE_TO_BUFFER);
                cnt = len >> shift;
-               flash_write_cmd(info, sector, offset, (uchar)cnt - 1);
+               flash_write_cmd(info, sector, offset, cnt - 1);
 
                switch (info->portwidth) {
                case FLASH_CFI_8BIT:
@@ -1536,13 +1543,22 @@ static int cmdset_intel_init(flash_info_t *info, struct cfi_qry *qry)
 
 static void cmdset_amd_read_jedec_ids(flash_info_t *info)
 {
+       ushort bankId = 0;
+       uchar  manuId;
+
        flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
        flash_unlock_seq(info, 0);
        flash_write_cmd(info, 0, info->addr_unlock1, FLASH_CMD_READ_ID);
        udelay(1000); /* some flash are slow to respond */
 
-       info->manufacturer_id = flash_read_uchar (info,
-                                       FLASH_OFFSET_MANUFACTURER_ID);
+       manuId = flash_read_uchar (info, FLASH_OFFSET_MANUFACTURER_ID);
+       /* JEDEC JEP106Z specifies ID codes up to bank 7 */
+       while (manuId == FLASH_CONTINUATION_CODE && bankId < 0x800) {
+               bankId += 0x100;
+               manuId = flash_read_uchar (info,
+                       bankId | FLASH_OFFSET_MANUFACTURER_ID);
+       }
+       info->manufacturer_id = manuId;
 
        switch (info->chipwidth){
        case FLASH_CFI_8BIT:
@@ -1788,13 +1804,10 @@ static void flash_fixup_atmel(flash_info_t *info, struct cfi_qry *qry)
 
        /* AT49BV6416(T) list the erase regions in the wrong order.
         * However, the device ID is identical with the non-broken
-        * AT49BV642D since u-boot only reads the low byte (they
-        * differ in the high byte.) So leave out this fixup for now.
+        * AT49BV642D they differ in the high byte.
         */
-#if 0
        if (info->device_id == 0xd6 || info->device_id == 0xd2)
                reverse_geometry = !reverse_geometry;
-#endif
 
        if (reverse_geometry)
                cfi_reverse_geometry(qry);
@@ -1806,8 +1819,9 @@ static void flash_fixup_stm(flash_info_t *info, struct cfi_qry *qry)
        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 < 1.1, guess by device id (M29W320{DT,ET} only) */
+                       if (info->device_id == 0x22CA ||
+                           info->device_id == 0x2256) {
                                cfi_reverse_geometry(qry);
                        }
                }
@@ -2008,7 +2022,9 @@ unsigned long flash_init (void)
 #endif
 
 #ifdef CONFIG_SYS_FLASH_PROTECTION
-       char *s = getenv("unlock");
+       /* read environment from EEPROM */
+       char s[64];
+       getenv_r ("unlock", s, sizeof(s));
 #endif
 
 #define BANK_BASE(i)   (((phys_addr_t [CFI_MAX_FLASH_BANKS])CONFIG_SYS_FLASH_BANKS_LIST)[i])
@@ -2098,7 +2114,7 @@ unsigned long flash_init (void)
 #ifdef CONFIG_ENV_ADDR_REDUND
        flash_protect (FLAG_PROTECT_SET,
                       CONFIG_ENV_ADDR_REDUND,
-                      CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SIZE_REDUND - 1,
+                      CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1,
                       flash_get_info(CONFIG_ENV_ADDR_REDUND));
 #endif