]> git.sur5r.net Git - u-boot/blobdiff - drivers/mtd/cfi_flash.c
sf: winbond: Update the names for W25Q 0x40XX ID's flash parts
[u-boot] / drivers / mtd / cfi_flash.c
index 2ca73f9623d1ccd509a8c1ee9270a5f57862e345..25f875202c337deafbda8f30b530325f21c5d88c 100644 (file)
@@ -38,6 +38,7 @@
 #include <asm/processor.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
+#include <asm/unaligned.h>
 #include <environment.h>
 #include <mtd/cfi_flash.h>
 #include <watchdog.h>
@@ -183,16 +184,16 @@ u64 flash_read64(void *addr)__attribute__((weak, alias("__flash_read64")));
 flash_info_t *flash_get_info(ulong base)
 {
        int i;
-       flash_info_t *info = NULL;
+       flash_info_t *info;
 
        for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
-               info = & flash_info[i];
+               info = &flash_info[i];
                if (info->size && info->start[0] <= base &&
                    base <= info->start[0] + info->size - 1)
-                       break;
+                       return info;
        }
 
-       return info;
+       return NULL;
 }
 #endif
 
@@ -1247,6 +1248,8 @@ void flash_print_info (flash_info_t * info)
                printf(info->chipwidth == FLASH_CFI_16BIT ? "%04X" : "%02X",
                info->device_id2);
        }
+       if ((info->vendor == CFI_CMDSET_AMD_STANDARD) && (info->legacy_unlock))
+               printf("\n  Advanced Sector Protection (PPB) enabled");
        printf ("\n  Erase timeout: %ld ms, write timeout: %ld ms\n",
                info->erase_blk_tout,
                info->write_tout);
@@ -1511,7 +1514,7 @@ int flash_real_protect (flash_info_t * info, long sector, int prot)
                                                        0, ATM_CMD_UNLOCK_SECT);
                                }
                        }
-                       if (manufact_match(info, AMD_MANUFACT)) {
+                       if (info->legacy_unlock) {
                                int flag = disable_interrupts();
                                int lock_flag;
 
@@ -1638,9 +1641,10 @@ static void cfi_reverse_geometry(struct cfi_qry *qry)
        u32 tmp;
 
        for (i = 0, j = qry->num_erase_regions - 1; i < j; i++, j--) {
-               tmp = qry->erase_region_info[i];
-               qry->erase_region_info[i] = qry->erase_region_info[j];
-               qry->erase_region_info[j] = tmp;
+               tmp = get_unaligned(&(qry->erase_region_info[i]));
+               put_unaligned(get_unaligned(&(qry->erase_region_info[j])),
+                             &(qry->erase_region_info[i]));
+               put_unaligned(tmp, &(qry->erase_region_info[j]));
        }
 }
 
@@ -1742,12 +1746,9 @@ static int cmdset_amd_init(flash_info_t *info, struct cfi_qry *qry)
        flash_write_cmd(info, 0, info->cfi_offset, FLASH_CMD_CFI);
 
 #ifdef CONFIG_SYS_FLASH_PROTECTION
-       if (info->ext_addr && manufact_match(info, AMD_MANUFACT)) {
-               ushort spus;
-
-               /* read sector protect/unprotect scheme */
-               spus = flash_read_uchar(info, info->ext_addr + 9);
-               if (spus == 0x8)
+       if (info->ext_addr) {
+               /* read sector protect/unprotect scheme (at 0x49) */
+               if (flash_read_uchar(info, info->ext_addr + 9) == 0x8)
                        info->legacy_unlock = 1;
        }
 #endif
@@ -2025,6 +2026,26 @@ static void flash_fixup_sst(flash_info_t *info, struct cfi_qry *qry)
        }
 }
 
+static void flash_fixup_num(flash_info_t *info, struct cfi_qry *qry)
+{
+       /*
+        * The M29EW devices seem to report the CFI information wrong
+        * when it's in 8 bit mode.
+        * There's an app note from Numonyx on this issue.
+        * So adjust the buffer size for M29EW while operating in 8-bit mode
+        */
+       if (((qry->max_buf_write_size) > 0x8) &&
+                       (info->device_id == 0x7E) &&
+                       (info->device_id2 == 0x2201 ||
+                       info->device_id2 == 0x2301 ||
+                       info->device_id2 == 0x2801 ||
+                       info->device_id2 == 0x4801)) {
+               debug("Adjusted buffer size on Numonyx flash"
+                       " M29EW family in 8 bit mode\n");
+               qry->max_buf_write_size = 0x8;
+       }
+}
+
 /*
  * The following code cannot be run from FLASH!
  *
@@ -2054,8 +2075,8 @@ ulong flash_get_size (phys_addr_t base, int banknum)
        info->start[0] = (ulong)map_physmem(base, info->portwidth, MAP_NOCACHE);
 
        if (flash_detect_cfi (info, &qry)) {
-               info->vendor = le16_to_cpu(qry.p_id);
-               info->ext_addr = le16_to_cpu(qry.p_adr);
+               info->vendor = le16_to_cpu(get_unaligned(&(qry.p_id)));
+               info->ext_addr = le16_to_cpu(get_unaligned(&(qry.p_adr)));
                num_erase_regions = qry.num_erase_regions;
 
                if (info->ext_addr) {
@@ -2106,6 +2127,9 @@ ulong flash_get_size (phys_addr_t base, int banknum)
                case 0x00bf: /* SST */
                        flash_fixup_sst(info, &qry);
                        break;
+               case 0x0089: /* Numonyx */
+                       flash_fixup_num(info, &qry);
+                       break;
                }
 
                debug ("manufacturer is %d\n", info->vendor);
@@ -2141,7 +2165,8 @@ ulong flash_get_size (phys_addr_t base, int banknum)
                                break;
                        }
 
-                       tmp = le32_to_cpu(qry.erase_region_info[i]);
+                       tmp = le32_to_cpu(get_unaligned(
+                                               &(qry.erase_region_info[i])));
                        debug("erase region %u: 0x%08lx\n", i, tmp);
 
                        erase_region_count = (tmp & 0xffff) + 1;
@@ -2185,7 +2210,7 @@ ulong flash_get_size (phys_addr_t base, int banknum)
                                        break;
                                case CFI_CMDSET_AMD_EXTENDED:
                                case CFI_CMDSET_AMD_STANDARD:
-                                       if (!manufact_match(info, AMD_MANUFACT)) {
+                                       if (!info->legacy_unlock) {
                                                /* default: not protected */
                                                info->protect[sect_cnt] = 0;
                                                break;