]> git.sur5r.net Git - openocd/commitdiff
Michael Schwingen <rincewind@discworld.dascon.de> enhanced non-CFI flash support
authoroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Sun, 19 Apr 2009 12:06:49 +0000 (12:06 +0000)
committeroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Sun, 19 Apr 2009 12:06:49 +0000 (12:06 +0000)
git-svn-id: svn://svn.berlios.de/openocd/trunk@1469 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/flash/cfi.c
src/flash/cfi.h
src/flash/non_cfi.c
src/flash/non_cfi.h

index 6b777fa8e3d0459aeb73a06bb2800bb8ed08c9e3..0426fd2e6f144b3104f5ef6f57a30527f40df186 100644 (file)
@@ -1,6 +1,8 @@
 /***************************************************************************
  *   Copyright (C) 2005, 2007 by Dominic Rath                              *
  *   Dominic.Rath@gmx.de                                                   *
+ *   Copyright (C) 2009 Michael Schwingen                                  *
+ *   michael@schwingen.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -82,24 +84,6 @@ static void cfi_fixup_0002_erase_regions(flash_bank_t *flash, void *param);
 static void cfi_fixup_0002_unlock_addresses(flash_bank_t *flash, void *param);
 static void cfi_fixup_atmel_reversed_erase_regions(flash_bank_t *flash, void *param);
 
-/* fixup after identifying JEDEC manufactuer and ID */
-static cfi_fixup_t cfi_jedec_fixups[] = {
-       {CFI_MFR_SST, 0x00D4, cfi_fixup_non_cfi, NULL},
-       {CFI_MFR_SST, 0x00D5, cfi_fixup_non_cfi, NULL},
-       {CFI_MFR_SST, 0x00D6, cfi_fixup_non_cfi, NULL},
-       {CFI_MFR_SST, 0x00D7, cfi_fixup_non_cfi, NULL},
-       {CFI_MFR_SST, 0x2780, cfi_fixup_non_cfi, NULL},
-       {CFI_MFR_ST, 0x00D5, cfi_fixup_non_cfi, NULL},
-       {CFI_MFR_ST, 0x00D6, cfi_fixup_non_cfi, NULL},
-       {CFI_MFR_AMD, 0x2223, cfi_fixup_non_cfi, NULL},
-       {CFI_MFR_AMD, 0x22ab, cfi_fixup_non_cfi, NULL},
-       {CFI_MFR_FUJITSU, 0x226b, cfi_fixup_non_cfi, NULL},
-       {CFI_MFR_AMIC, 0xb31a, cfi_fixup_non_cfi, NULL},
-       {CFI_MFR_MX, 0x225b, cfi_fixup_non_cfi, NULL},
-       {CFI_MFR_AMD, 0x225b, cfi_fixup_non_cfi, NULL},
-       {0, 0, NULL, NULL}
-};
-
 /* fixup after reading cmdset 0002 primary query table */
 static cfi_fixup_t cfi_0002_fixups[] = {
        {CFI_MFR_SST, 0x00D4, cfi_fixup_0002_unlock_addresses, &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]},
@@ -633,6 +617,8 @@ static int cfi_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd,
 {
        cfi_flash_bank_t *cfi_info;
        int i;
+       (void) cmd_ctx;
+       (void) cmd;
 
        if (argc < 6)
        {
@@ -964,7 +950,7 @@ static int cfi_protect(struct flash_bank_s *bank, int set, int first, int last)
                        cfi_intel_protect(bank, set, first, last);
                        break;
                default:
-                       LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
+                       LOG_ERROR("protect: cfi primary command set %i unsupported", cfi_info->pri_id);
                        break;
        }
 
@@ -1843,7 +1829,7 @@ static int cfi_write_words(struct flash_bank_s *bank, u8 *word, u32 wordcount, u
                        return cfi_intel_write_words(bank, word, wordcount, address);
                        break;
                case 2:
-                       return cfi_spansion_write_words(bank, word, wordcount, address); 
+                       return cfi_spansion_write_words(bank, word, wordcount, address);
                        break;
                default:
                        LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
@@ -1965,7 +1951,7 @@ int cfi_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
                                LOG_ERROR("Unsupported chip width %d", bank->chip_width);
                                return ERROR_FLASH_OPERATION_FAILED;
                        }
-                       
+
                        bufferwsize/=(bank->bus_width / bank->chip_width);
 
                        /* fall back to memory writes */
@@ -2064,6 +2050,7 @@ int cfi_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
 
 static void cfi_fixup_atmel_reversed_erase_regions(flash_bank_t *bank, void *param)
 {
+       (void) param;
        cfi_flash_bank_t *cfi_info = bank->driver_priv;
        cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext;
 
@@ -2075,6 +2062,7 @@ static void cfi_fixup_0002_erase_regions(flash_bank_t *bank, void *param)
        int i;
        cfi_flash_bank_t *cfi_info = bank->driver_priv;
        cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext;
+       (void) param;
 
        if ((pri_ext->_reversed_geometry) || (pri_ext->TopBottom == 3))
        {
@@ -2110,7 +2098,6 @@ static int cfi_probe(struct flash_bank_s *bank)
        int num_sectors = 0;
        int i;
        int sector = 0;
-       u32 offset = 0;
        u32 unlock1 = 0x555;
        u32 unlock2 = 0x2aa;
        int retval;
@@ -2175,6 +2162,7 @@ static int cfi_probe(struct flash_bank_s *bank)
                }
        }
 
+       LOG_INFO("Flash Manufacturer/Device: 0x%04x 0x%04x", cfi_info->manufacturer, cfi_info->device_id);
        /* switch back to read array mode */
        cfi_command(bank, 0xf0, command);
        if((retval = target->type->write_memory(target, flash_address(bank, 0, 0x00), bank->bus_width, 1, command)) != ERROR_OK)
@@ -2187,7 +2175,8 @@ static int cfi_probe(struct flash_bank_s *bank)
                return retval;
        }
 
-       cfi_fixup(bank, cfi_jedec_fixups);
+       /* check device/manufacturer ID for known non-CFI flashes. */
+       cfi_fixup_non_cfi(bank);
 
        /* query only if this is a CFI compatible flash,
         * otherwise the relevant info has already been filled in
@@ -2225,7 +2214,7 @@ static int cfi_probe(struct flash_bank_s *bank)
                        {
                                return retval;
                        }
-                       LOG_ERROR("Could not probe bank");
+                       LOG_ERROR("Could not probe bank: no QRY");
                        return ERROR_FLASH_BANK_INVALID;
                }
 
@@ -2261,17 +2250,12 @@ static int cfi_probe(struct flash_bank_s *bank)
                        (1 << cfi_info->block_erase_timeout_max) * (1 << cfi_info->block_erase_timeout_typ),
                        (1 << cfi_info->chip_erase_timeout_max) * (1 << cfi_info->chip_erase_timeout_typ));
 
-               cfi_info->dev_size = cfi_query_u8(bank, 0, 0x27);
+               cfi_info->dev_size = 1<<cfi_query_u8(bank, 0, 0x27);
                cfi_info->interface_desc = cfi_query_u16(bank, 0, 0x28);
                cfi_info->max_buf_write_size = cfi_query_u16(bank, 0, 0x2a);
                cfi_info->num_erase_regions = cfi_query_u8(bank, 0, 0x2c);
 
-               LOG_DEBUG("size: 0x%x, interface desc: %i, max buffer write size: %x", 1 << cfi_info->dev_size, cfi_info->interface_desc, (1 << cfi_info->max_buf_write_size));
-
-               if ((u32)((1 << cfi_info->dev_size) * bank->bus_width / bank->chip_width) != bank->size)
-               {
-                       LOG_WARNING("configuration specifies 0x%x size, but a 0x%x size flash was found", bank->size, 1 << cfi_info->dev_size);
-               }
+               LOG_DEBUG("size: 0x%x, interface desc: %i, max buffer write size: %x", cfi_info->dev_size, cfi_info->interface_desc, (1 << cfi_info->max_buf_write_size));
 
                if (cfi_info->num_erase_regions)
                {
@@ -2338,6 +2322,11 @@ static int cfi_probe(struct flash_bank_s *bank)
                        break;
        }
 
+       if ((cfi_info->dev_size * bank->bus_width / bank->chip_width) != bank->size)
+       {
+               LOG_WARNING("configuration specifies 0x%x size, but a 0x%x size flash was found", bank->size, cfi_info->dev_size);
+       }
+
        if (cfi_info->num_erase_regions == 0)
        {
                /* a device might have only one erase block, spanning the whole device */
@@ -2351,6 +2340,8 @@ static int cfi_probe(struct flash_bank_s *bank)
        }
        else
        {
+               u32 offset = 0;
+
                for (i = 0; i < cfi_info->num_erase_regions; i++)
                {
                        num_sectors += (cfi_info->erase_region_info[i] & 0xffff) + 1;
@@ -2372,8 +2363,12 @@ static int cfi_probe(struct flash_bank_s *bank)
                                sector++;
                        }
                }
+               if (offset != cfi_info->dev_size)
+               {
+                       LOG_WARNING("CFI size is 0x%x, but total sector size is 0x%x", cfi_info->dev_size, offset);
+               }
        }
-       
+
        cfi_info->probed = 1;
 
        return ERROR_OK;
@@ -2504,7 +2499,7 @@ static int cfi_info(struct flash_bank_s *bank, char *buf, int buf_size)
        }
 
        if (cfi_info->not_cfi == 0)
-       printed = snprintf(buf, buf_size, "\ncfi information:\n");
+               printed = snprintf(buf, buf_size, "\ncfi information:\n");
        else
                printed = snprintf(buf, buf_size, "\nnon-cfi flash:\n");
        buf += printed;
@@ -2546,7 +2541,7 @@ static int cfi_info(struct flash_bank_s *bank, char *buf, int buf_size)
        buf_size -= printed;
 
                printed = snprintf(buf, buf_size, "size: 0x%x, interface desc: %i, max buffer write size: %x\n",
-                                  1 << cfi_info->dev_size,
+                                  cfi_info->dev_size,
                                   cfi_info->interface_desc,
                                   1 << cfi_info->max_buf_write_size);
        buf += printed;
index ae6ae28ef8695fa1869b5b1a8c5239c68469d775..5eab7efdd9bf47a1e6938a880a17c66952b3736a 100644 (file)
@@ -26,7 +26,7 @@
 typedef struct cfi_flash_bank_s
 {
        working_area_t *write_algorithm;
-       
+
 
        int x16_as_x8;
        int jedec_probe;
@@ -59,7 +59,7 @@ typedef struct cfi_flash_bank_s
        u8 chip_erase_timeout_max;
 
        /* flash geometry */
-       u8 dev_size;
+       u32 dev_size;
        u16 interface_desc;
        u16 max_buf_write_size;
        u8 num_erase_regions;
index 632ae7e97c68874c981a2222e486532f2cac2c6c..b9ef1127331c435c364b908ef311d77787abdcf7 100644 (file)
@@ -1,6 +1,8 @@
 /***************************************************************************
  *   Copyright (C) 2007 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
+ *   Copyright (C) 2009 Michael Schwingen                                  *
+ *   michael@schwingen.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
 #include "cfi.h"
 #include "non_cfi.h"
 
+#define KB 1024
+#define MB (1024*1024)
+#define ERASE_REGION(num, size) (((size/256)<<16)|(num-1))
+
 /* non-CFI compatible flashes */
 non_cfi_t non_cfi_flashes[] = {
        {
                .mfr = CFI_MFR_SST,
                .id = 0xd4,
                .pri_id = 0x02,
-               .dev_size = 0x10,                       /* 2^16 = 64KB */
+               .dev_size = 64*KB,
                .interface_desc = 0x0,          /* x8 only device */
                .max_buf_write_size = 0x0,
                .num_erase_regions = 1,
                .erase_region_info =
                {
-                       0x0010000f,                             /* 16x  4KB */
-                       0x00000000
+                       ERASE_REGION(16, 4*KB)
                }
        },
        {
                .mfr = CFI_MFR_SST,
                .id = 0xd5,
                .pri_id = 0x02,
-               .dev_size = 0x11,                       /* 2^17 = 128KB */
+               .dev_size = 128*KB,
                .interface_desc = 0x0,          /* x8 only device */
                .max_buf_write_size = 0x0,
                .num_erase_regions = 1,
                .erase_region_info =
                {
-                       0x0010001f,
-                       0x00000000
+                       ERASE_REGION(32, 4*KB)
                }
        },
        {
                .mfr = CFI_MFR_SST,
                .id = 0xd6,
                .pri_id = 0x02,
-               .dev_size = 0x12,                       /* 2^18 = 256KB */
+               .dev_size = 256*KB,
                .interface_desc = 0x0,          /* x8 only device */
                .max_buf_write_size = 0x0,
                .num_erase_regions = 1,
                .erase_region_info =
                {
-                       0x0010003f,
-                       0x00000000
+                       ERASE_REGION(64, 4*KB)
                }
        },
        {
                .mfr = CFI_MFR_SST,
                .id = 0xd7,
                .pri_id = 0x02,
-               .dev_size = 0x13,                       /* 2^19 = 512KB */
+               .dev_size = 512*KB,
                .interface_desc = 0x0,          /* x8 only device */
                .max_buf_write_size = 0x0,
                .num_erase_regions = 1,
                .erase_region_info =
                {
-                       0x0010007f,
-                       0x00000000
+                       ERASE_REGION(128, 4*KB)
                }
        },
        {
                .mfr = CFI_MFR_SST,
                .id = 0x2780,
                .pri_id = 0x02,
-               .dev_size = 0x13,                       /* 2^19 = 512KB */
+               .dev_size = 512*KB,
                .interface_desc = 0x2,          /* x8 or x16 device */
                .max_buf_write_size = 0x0,
                .num_erase_regions = 1,
                .erase_region_info =
                {
-                       0x0010007f,
-                       0x00000000
+                       ERASE_REGION(128, 4*KB)
                }
        },
        {
                .mfr = CFI_MFR_ST,
                .id = 0xd6,                                     /* ST29F400BB */
                .pri_id = 0x02,
-               .dev_size = 0x13,                       /* 2^19 = 512KB */
+               .dev_size = 512*KB,
                .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
                .max_buf_write_size = 0x0,
                .num_erase_regions = 4,
                .erase_region_info =
                {
-                       0x00400000,             /* 1x 16KB */
-                       0x00200001,             /* 2x  8KB */
-                       0x00800000,             /* 1x 32KB */
-                       0x01000006,             /* 7x 64KB */
-                       0x00000000
+                       ERASE_REGION( 1, 16*KB),
+                       ERASE_REGION( 2,  8*KB),
+                       ERASE_REGION( 1, 32*KB),
+                       ERASE_REGION( 7, 64*KB)
                }
        },
        {
                .mfr = CFI_MFR_ST,
                .id = 0xd5,                                     /* ST29F400BT */
                .pri_id = 0x02,
-               .dev_size = 0x13,                       /* 2^19 = 512KB */
+               .dev_size = 512*KB,
                .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
                .max_buf_write_size = 0x0,
                .num_erase_regions = 4,
                .erase_region_info =
                {
-                       0x01000006,             /* 7x 64KB */
-                       0x00800000,             /* 1x 32KB */
-                       0x00200001,             /* 2x  8KB */
-                       0x00400000,             /* 1x 16KB */
-                       0x00000000
+                       ERASE_REGION( 7, 64*KB),
+                       ERASE_REGION( 1, 32*KB),
+                       ERASE_REGION( 2,  8*KB),
+                       ERASE_REGION( 1, 16*KB)
                }
        },
        {
                .mfr = CFI_MFR_AMD,
                .id = 0x22ab,                           /* AM29F400BB */
                .pri_id = 0x02,
-               .dev_size = 0x13,                       /* 2^19 = 512KB */
+               .dev_size = 512*KB,
                .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
                .max_buf_write_size = 0x0,
                .num_erase_regions = 4,
                .erase_region_info =
                {
-                       0x00400000,             /* 1x 16KB */
-                       0x00200001,             /* 2x  8KB */
-                       0x00800000,             /* 1x 32KB */
-                       0x01000006,             /* 7x 64KB */
-                       0x00000000
+                       ERASE_REGION( 1, 16*KB),
+                       ERASE_REGION( 2,  8*KB),
+                       ERASE_REGION( 1, 32*KB),
+                       ERASE_REGION( 7, 64*KB)
                }
        },
        {
                .mfr = CFI_MFR_AMD,
                .id = 0x2223,                           /* AM29F400BT */
                .pri_id = 0x02,
-               .dev_size = 0x13,                       /* 2^19 = 512KB */
+               .dev_size = 512*KB,
                .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
                .max_buf_write_size = 0x0,
                .num_erase_regions = 4,
                .erase_region_info =
                {
-                       0x01000006,             /* 7x 64KB */
-                       0x00800000,             /* 1x 32KB */
-                       0x00200001,             /* 2x  8KB */
-                       0x00400000,             /* 1x 16KB */
-                       0x00000000
+                       ERASE_REGION( 7, 64*KB),
+                       ERASE_REGION( 1, 32*KB),
+                       ERASE_REGION( 2,  8*KB),
+                       ERASE_REGION( 1, 16*KB)
                }
        },
        {
                .mfr = CFI_MFR_FUJITSU,
                .id = 0x226b,                           /* AM29SL800DB */
                .pri_id = 0x02,
-               .dev_size = 0x14,                       /* 2^20 = 1MB */
+               .dev_size = 1*MB,
                .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
                .max_buf_write_size = 0x0,
                .num_erase_regions = 4,
                .erase_region_info =
                {
-                       0x00400000,                             /* 1x 16KB */
-                       0x00200001,                             /* 2x 8KB */
-                       0x00800000,                             /* 1x 32KB */
-                       0x0100000e,                             /* 15x 64KB */
-                       0x00000000
+                       ERASE_REGION( 1, 16*KB),
+                       ERASE_REGION( 2,  8*KB),
+                       ERASE_REGION( 1, 32*KB),
+                       ERASE_REGION(15, 64*KB)
                }
        },
        {
                .mfr = CFI_MFR_AMIC,
                .id = 0xb31a,                           /* A29L800A */
                .pri_id = 0x02,
-               .dev_size = 0x14,
+               .dev_size = 1*MB,
                .interface_desc = 0x2,
                .max_buf_write_size = 0x0,
                .num_erase_regions = 4,
                .erase_region_info =
                {
-                       0x00400000,                             /* 1x 16KB */
-                       0x00200001,                             /* 2x 8KB */
-                       0x00800000,                             /* 1x 32KB */
-                       0x0100000e,                             /* 15x 64KB */
-                       0x00000000
+                       ERASE_REGION( 1, 16*KB),
+                       ERASE_REGION( 2,  8*KB),
+                       ERASE_REGION( 1, 32*KB),
+                       ERASE_REGION(15, 64*KB)
                }
        },
        {
                .mfr = CFI_MFR_MX,
                .id = 0x225b,                           /* MX29LV800B */
                .pri_id = 0x02,
-               .dev_size = 0x14,                       /* 2^20 = 1MB */
+               .dev_size = 1*MB,
+               .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
+               .max_buf_write_size = 0x0,
+               .num_erase_regions = 4,
+               .erase_region_info =
+               {
+                       ERASE_REGION( 1, 16*KB),
+                       ERASE_REGION( 2, 8*KB),
+                       ERASE_REGION( 1, 32*KB),
+                       ERASE_REGION(15, 64*KB)
+               }
+       },
+
+       {
+               .mfr = CFI_MFR_MX,
+               .id = 0x2249,                           /* MX29LV160AB: 2MB */
+               .pri_id = 0x02,
+               .dev_size = 2*MB,
+               .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
+               .max_buf_write_size = 0x0,
+               .num_erase_regions = 4,
+               .erase_region_info =
+               {
+                       ERASE_REGION( 1, 16*KB),
+                       ERASE_REGION( 2, 8*KB),
+                       ERASE_REGION( 1, 32*KB),
+                       ERASE_REGION(31, 64*KB)
+               }
+       },
+       {
+               .mfr = CFI_MFR_MX,
+               .id = 0x22C4,                           /* MX29LV160AT: 2MB */
+               .pri_id = 0x02,
+               .dev_size = 2*MB,
                .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
                .max_buf_write_size = 0x0,
                .num_erase_regions = 4,
                .erase_region_info =
                {
-                        0x00400000,             /* 1x 16KB */
-                        0x00200001,             /* 2x 8KB */
-                        0x00800000,             /* 1x 32KB */
-                        0x0100000e,             /* 15x 64KB */
-                       0x00000000
+                       ERASE_REGION(31, 64*KB),
+                       ERASE_REGION( 1, 32*KB),
+                       ERASE_REGION( 2, 8*KB),
+                       ERASE_REGION( 1, 16*KB)
+               }
+       },
+       {
+               .mfr = CFI_MFR_SST,
+               .id = 0x2782,                           /* SST39xF160 */
+               .pri_id = 0x02,
+               .dev_size = 2*MB,
+               .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
+               .max_buf_write_size = 0x0,
+               .num_erase_regions = 1,
+               .erase_region_info =
+               {
+                       ERASE_REGION(512, 4*KB)
+               }
+       },
+       {
+               .mfr = CFI_MFR_ATMEL,
+               .id = 0x00c0,                           /* Atmel 49BV1614 */
+               .pri_id = 0x02,
+               .dev_size = 2*MB,
+               .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
+               .max_buf_write_size = 0x0,
+               .num_erase_regions = 3,
+               .erase_region_info =
+               {
+                       ERASE_REGION( 8,  8*KB),
+                       ERASE_REGION( 2, 32*KB),
+                       ERASE_REGION(30, 64*KB)
+               }
+       },
+       {
+               .mfr = CFI_MFR_ATMEL,
+               .id = 0xC2,                                     /* Atmel 49BV1614T */
+               .pri_id = 0x02,
+               .dev_size = 2*MB,
+               .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
+               .max_buf_write_size = 0x0,
+               .num_erase_regions = 3,
+               .erase_region_info =
+               {
+                       ERASE_REGION(30, 64*KB),
+                       ERASE_REGION( 2, 32*KB),
+                       ERASE_REGION( 8,  8*KB)
                }
        },
        {
                .mfr = CFI_MFR_AMD,
                .id = 0x225b,                           /* S29AL008D */
                .pri_id = 0x02,
-               .dev_size = 0x14,                       /* 2^20 = 1MB */
+               .dev_size = 1*MB,
                .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
                .max_buf_write_size = 0x0,
                .num_erase_regions = 4,
                .erase_region_info =
                {
-                        0x00400000,             /* 1x 16KB */
-                        0x00200001,             /* 2x 8KB */
-                        0x00800000,             /* 1x 32KB */
-                        0x0100000e,             /* 15x 64KB */
-                       0x00000000
+                       ERASE_REGION( 1, 16*KB),
+                       ERASE_REGION( 2, 8*KB),
+                       ERASE_REGION( 1, 32*KB),
+                       ERASE_REGION(15, 64*KB)
                }
        },
        {
@@ -243,23 +312,26 @@ non_cfi_t non_cfi_flashes[] = {
        }
 };
 
-void cfi_fixup_non_cfi(flash_bank_t *bank, void *param)
+void cfi_fixup_non_cfi(flash_bank_t *bank)
 {
        cfi_flash_bank_t *cfi_info = bank->driver_priv;
        non_cfi_t *non_cfi = non_cfi_flashes;
-       
-       while (non_cfi->mfr)
+
+       for (non_cfi = non_cfi_flashes; non_cfi->mfr; non_cfi++)
        {
                if ((cfi_info->manufacturer == non_cfi->mfr)
                        && (cfi_info->device_id == non_cfi->id))
                {
                        break;
                }
-               non_cfi++;
        }
-       
+
+       /* only fixup jedec flashs found in table */
+       if (!non_cfi->mfr)
+               return;
+
        cfi_info->not_cfi = 1;
-       
+
        /* fill in defaults for non-critical data */
        cfi_info->vcc_min = 0x0;
        cfi_info->vcc_max = 0x0;
@@ -273,22 +345,23 @@ void cfi_fixup_non_cfi(flash_bank_t *bank, void *param)
        cfi_info->buf_write_timeout_max = 0x0;
        cfi_info->block_erase_timeout_max = 0x0;
        cfi_info->chip_erase_timeout_max = 0x0;
-       
+
        cfi_info->qry[0] = 'Q';
        cfi_info->qry[1] = 'R';
        cfi_info->qry[2] = 'Y';
-       
+
        cfi_info->pri_id = non_cfi->pri_id;
        cfi_info->pri_addr = 0x0;
        cfi_info->alt_id = 0x0;
        cfi_info->alt_addr = 0x0;
        cfi_info->alt_ext = NULL;
-       
+
        cfi_info->interface_desc = non_cfi->interface_desc;
        cfi_info->max_buf_write_size = non_cfi->max_buf_write_size;
        cfi_info->num_erase_regions = non_cfi->num_erase_regions;
        cfi_info->erase_region_info = non_cfi->erase_region_info;
-       
+       cfi_info->dev_size = non_cfi->dev_size;
+
        if (cfi_info->pri_id == 0x2)
        {
                cfi_spansion_pri_ext_t *pri_ext = malloc(sizeof(cfi_spansion_pri_ext_t));
@@ -296,10 +369,10 @@ void cfi_fixup_non_cfi(flash_bank_t *bank, void *param)
                pri_ext->pri[0] = 'P';
                pri_ext->pri[1] = 'R';
                pri_ext->pri[2] = 'I';
-               
+
                pri_ext->major_version = '1';
                pri_ext->minor_version = '0';
-               
+
                pri_ext->SiliconRevision = 0x0;
                pri_ext->EraseSuspend = 0x0;
                pri_ext->EraseSuspend = 0x0;
@@ -312,9 +385,11 @@ void cfi_fixup_non_cfi(flash_bank_t *bank, void *param)
                pri_ext->VppMin = 0x0;
                pri_ext->VppMax = 0x0;
                pri_ext->TopBottom = 0x0;
-       
+
+               pri_ext->_unlock1 = 0x5555;
+               pri_ext->_unlock2 = 0x2AAA;
                pri_ext->_reversed_geometry = 0;
-               
+
                cfi_info->pri_ext = pri_ext;
        } else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3))
        {
index bfd6ab2dea157648b7daa0f140cf4366e6c06fd9..19fef85302c96bb8cb9b6329e18cbc4b8f301147 100644 (file)
@@ -27,7 +27,7 @@ typedef struct non_cfi_s
        u16 mfr;
        u16 id;
        u16 pri_id;
-       u8 dev_size;
+       u32 dev_size;
        u16 interface_desc;
        u16 max_buf_write_size;
        u8 num_erase_regions;
@@ -35,6 +35,6 @@ typedef struct non_cfi_s
 } non_cfi_t;
 
 extern non_cfi_t non_cfi_flashes[];
-extern void cfi_fixup_non_cfi(flash_bank_t *bank, void *param);
+extern void cfi_fixup_non_cfi(flash_bank_t *bank);
 
 #endif /* NON_CFI_H */