OSDN Git Service

sf.net enchancement #283166
authorMasaki Muranaka <monaka at monami-software.com>
Sun, 2 Aug 2009 09:49:19 +0000 (18:49 +0900)
committerMasaki Muranaka <monaka at monami-software.com>
Sun, 2 Aug 2009 09:49:19 +0000 (18:49 +0900)
jtag/include/flash/cfi.h
jtag/include/flash/jedec.h
jtag/src/flash/amd.c
jtag/src/flash/amd_flash.c
jtag/src/flash/flash.c
jtag/src/flash/jedec.c

index c8f6984..a895296 100644 (file)
@@ -70,6 +70,7 @@ typedef struct cfi_query_identification_string {
        void *pri_vendor_tbl;
        uint16_t alt_id_code;
        void *alt_vendor_tbl;
+       uint32_t _urjtag_manid_devid;
 } cfi_query_identification_string_t;
 #endif /* __ASSEMBLY__ */
 
index 1ac1ea7..a95f2dc 100644 (file)
@@ -51,6 +51,8 @@
 /* Atmel */
 #define FLASHDEVICE_AT49xV16x          0x00C0
 #define FLASHDEVICE_AT49xV16xT         0x00C2
+#define FLASHDEVICE_AT49BV322D         0x01C8
+#define FLASHDEVICE_AT49BV322DT                0x01C9
 
 /* Fujitsu */
 #define FLASHDEVICE_MBM29LV160TE       0x22C4
index 3731629..74fa0b4 100644 (file)
@@ -40,6 +40,7 @@
 #include <stdio.h>
 #include <flash/cfi.h>
 #include <flash/intel.h>
+#include <flash/jedec.h>
 #include <unistd.h>
 
 #include <flash.h>
@@ -47,6 +48,7 @@
 
 static int dbg = 0;
 
+static int amd_flash_erase_( cfi_array_t *cfi_array, uint32_t adr, int eraseall );
 static int amd_flash_erase_all( cfi_array_t *cfi_array );
 static int amd_flash_erase_block( cfi_array_t *cfi_array, uint32_t adr );
 static int amd_flash_unlock_block( cfi_array_t *cfi_array, uint32_t adr );
@@ -73,7 +75,7 @@ static void amd_flash_read_array( cfi_array_t *cfi_array );
  * that do address alignment themselves, such as the Samsung S3C4510B. The bus
  * driver has to deal with this. - kawk 2008-01 */
 
-static int
+static inline int
 amd_flash_address_shift( cfi_array_t *cfi_array )
 {
        if(cfi_array->bus_width == 4) return 2;
@@ -119,6 +121,35 @@ amd_flash_autodetect8( cfi_array_t *cfi_array )
        if(cfi_array->bus_width != 1) return 0;
        return (cfi_array->cfi_chips[0]->cfi.identification_string.pri_id_code == CFI_VENDOR_AMD_SCS);
 }
+
+
+#define MANID_DEVID(manid, devid) ((manid) << 16 | ((devid) & 0xff))
+
+static int
+amd_flash_autodetect_am29lv400b( cfi_array_t *cfi_array )
+{
+       uint32_t manid_devid;
+
+       if (cfi_array->cfi_chips[0]->cfi.identification_string.pri_id_code != CFI_VENDOR_AMD_SCS)
+               return 0;
+
+       manid_devid = cfi_array->cfi_chips[0]->cfi.identification_string._urjtag_manid_devid;
+       return ((manid_devid == MANID_DEVID(MANUFACTURER_AMD, FLASHDEVICE_AM29LV400BT)) ||
+               (manid_devid == MANID_DEVID(MANUFACTURER_AMD, FLASHDEVICE_AM29LV400BB)));
+}
+
+static int
+amd_flash_autodetect_am29lv081b( cfi_array_t *cfi_array )
+{
+       uint32_t manid_devid;
+
+       if (cfi_array->cfi_chips[0]->cfi.identification_string.pri_id_code != CFI_VENDOR_AMD_SCS ||
+               cfi_array->bus_width != 1) return 0;
+
+       manid_devid = cfi_array->cfi_chips[0]->cfi.identification_string._urjtag_manid_devid;
+       return (manid_devid == MANID_DEVID(MANUFACTURER_AMD, FLASHDEVICE_AM29LV081B));
+}
+
 /*
  * check device status
  *   1/true   PASS
@@ -372,20 +403,11 @@ amd_flash_print_info( cfi_array_t *cfi_array )
 }
 
 static int
-amd_flash_erase_all( cfi_array_t *cfi_array )
-{
-       printf("Error: not implemented.");
-       return FLASH_ERROR_UNKNOWN;
-}
-
-static int
-amd_flash_erase_block( cfi_array_t *cfi_array, uint32_t adr )
+amd_flash_erase_( cfi_array_t *cfi_array, uint32_t adr, int eraseall )
 {
        bus_t *bus = cfi_array->bus;
        int o = amd_flash_address_shift( cfi_array );
 
-       printf("flash_erase_block 0x%08X\n", adr);
-
        /*      printf("protected: %d\n", amdisprotected(ps, cfi_array, adr)); */
 
        bus_write( bus, cfi_array->address + (0x0555 << o), 0x00aa00aa ); /* autoselect p29, sector erase */
@@ -393,7 +415,11 @@ amd_flash_erase_block( cfi_array_t *cfi_array, uint32_t adr )
        bus_write( bus, cfi_array->address + (0x0555 << o), 0x00800080 );
        bus_write( bus, cfi_array->address + (0x0555 << o), 0x00aa00aa );
        bus_write( bus, cfi_array->address + (0x02aa << o), 0x00550055 );
-       bus_write( bus, adr, 0x00300030 );
+       if (eraseall) {
+               bus_write( bus, cfi_array->address + (0x0555 << o), 0x00100010 ); /* Chip erase */
+       } else {
+               bus_write( bus, adr, 0x00300030 ); /* Sector erase */
+       }
 
        if (amdstatus( cfi_array, adr, 0xffff )) {
                printf( "flash_erase_block 0x%08X DONE\n", adr );
@@ -408,6 +434,24 @@ amd_flash_erase_block( cfi_array_t *cfi_array, uint32_t adr )
 }
 
 static int
+amd_flash_erase_block( cfi_array_t *cfi_array, uint32_t adr )
+{
+       printf("flash_erase_block 0x%08X\n", adr);
+       return amd_flash_erase_( cfi_array, adr, 0 /* false */ );
+}
+
+static int
+amd_flash_erase_all( cfi_array_t *cfi_array )
+{
+       uint32_t adr;
+
+       adr = cfi_array->address;
+       printf("flash_erase_all 0x%08X\n", adr);
+
+       return amd_flash_erase_( cfi_array, adr, 1 /* true */ );
+}
+
+static int
 amd_flash_unlock_block( cfi_array_t *cfi_array, uint32_t adr )
 {
        printf( "flash_unlock_block 0x%08X IGNORE\n", adr );
@@ -556,6 +600,29 @@ amd_flash_program( cfi_array_t *cfi_array, uint32_t adr, uint32_t *buffer, int c
 }
 
 static int
+amd_flash_program_unbuffered( cfi_array_t *cfi_array, uint32_t adr, uint32_t *buffer, int count )
+{
+       cfi_query_structure_t *cfi = &(cfi_array->cfi_chips[0]->cfi);
+       int max_bytes_write = cfi->device_geometry.max_bytes_write;
+
+       if (max_bytes_write > 1) {
+         /* you can get more speed if you write a bufferd driver. */
+       }
+
+       /* unroll buffer to single writes */
+       int idx;
+
+       for (idx = 0; idx < count; idx++) {
+               int status = amd_flash_program_single( cfi_array, adr, buffer[idx] );
+               if (status)
+                       return status;
+               adr += cfi_array->bus_width;
+       }
+
+       return 0;
+}
+
+static int
 amd_flash_program32( cfi_array_t *cfi_array, uint32_t adr, uint32_t *buffer, int count )
 {
        /* Single byte programming is forced for 32 bit (2x16) flash configuration.
@@ -621,3 +688,30 @@ flash_driver_t amd_8_flash_driver = {
        amd_flash_program,
        amd_flash_read_array,
 };
+
+flash_driver_t amd_am29lv400b_flash_driver = {
+       1, /* or 2. buswidth but no used. */
+       N_("AMD/Fujitsu Standard Command Set"),
+       N_("supported: AMD 29LV400B; 1x8 Bit, 1x16 Bit"),
+       amd_flash_autodetect_am29lv400b,
+       amd_flash_print_info,
+       amd_flash_erase_all,
+       amd_flash_erase_block,
+       amd_flash_unlock_block,
+       amd_flash_program_unbuffered,
+       amd_flash_read_array,
+};
+
+flash_driver_t amd_am29lv081b_flash_driver = {
+       1, /* buswidth */
+       N_("AMD/Fujitsu Standard Command Set"),
+       N_("supported: AMD 29LV081B; 1x8 Bit"),
+       amd_flash_autodetect_am29lv081b,
+       amd_flash_print_info,
+       amd_flash_erase_all,
+       amd_flash_erase_block,
+       amd_flash_unlock_block,
+       amd_flash_program_unbuffered,
+       amd_flash_read_array,
+};
+
index 24bc810..40b59f5 100644 (file)
@@ -24,8 +24,6 @@
  * Documentation:
  * [1] Spansion, Am29F040B Data Sheet
  * [2] Spansion, Am29LV040B Data Sheet
- * [3] Spansion, Am29LV081B Data Sheet
- * [4] Spansion, Am29LV400D Data Sheet
 */
 
 #include "sysdep.h"
 #define AMD_UNDEFINED_MODE
 
 #define FLASH_ERASE_ERROR                      -5
-#define FLASH_ERASE_SUCCESS                    0
+#define ERASE_FLASH_SUCCESS                    1
 
-#define AMD_UNKNOWN_DEVICE     0
-#define AMD_29xx040B           1
-#define AMD_29xx081B           (0x38)
-#define AMD_29LV400B_TOP       (0xB9)
-#define AMD_29LV400B_BOTTOM    (0xBA)
+#define AMD_29xx040B   1
 
 #define AMD_BYPASS_UNLOCK_ALGORITHM            1
 #define AMD_STANDARD_WRITE_ALGORITHM           0
@@ -78,88 +72,20 @@ struct
        unsigned short algorithm;
        unsigned short unlock_bypass;
 }
-  var_forced_detection = { AMD_UNKNOWN_DEVICE, 0, 0};
+var_forced_detection;
 
 int amd_detect(bus_t *bus, uint32_t adr, cfi_array_t **cfi_array );
 static int amd_29xx040_autodetect( cfi_array_t *cfi_array );
 static int amd_29xx040_status( bus_t *bus, uint32_t adr, unsigned short data );
 static void amd_29xx040_print_info( cfi_array_t *cfi_array );
 static void amd_29xx040_read_array( cfi_array_t *cfi_array );
-static int _amd_29xx040_erase( cfi_array_t *cfi_array, uint32_t adr, int eraseall );
+static int amd_29xx040_erase_( cfi_array_t *cfi_array, uint32_t adr, int eraseall );
 static int amd_29xx040_erase_all( cfi_array_t *cfi_array );
 static int amd_29xx040_erase_block( cfi_array_t *cfi_array, uint32_t adr );
 static int amd_29xx040_program_single( cfi_array_t *cfi_array, uint32_t adr, uint32_t data );
 static int amd_29xx040_program( cfi_array_t *cfi_array, uint32_t adr, uint32_t *buffer, int count );
 static int amd_29xx040_unlock_block( cfi_array_t *cfi_array, uint32_t adr );
 
-static void amd_29xx040b_init_cfi( cfi_query_structure_t *cfi )
-{
-       cfi_erase_block_region_t *region;
-
-       region = malloc( sizeof (cfi_erase_block_region_t) );
-       cfi->device_geometry.erase_block_regions = region;
-       if (region == NULL) {
-               return;
-       }
-       cfi->device_geometry.number_of_erase_regions = 1;
-       region->erase_block_size = 64 * 1024;
-       region->number_of_erase_blocks = 8;
-}
-
-static void amd_29xx081b_init_cfi( cfi_query_structure_t *cfi )
-{
-       cfi_erase_block_region_t *region;
-
-       region = malloc( sizeof (cfi_erase_block_region_t) );
-       cfi->device_geometry.erase_block_regions = region;
-       if (region == NULL) {
-               return;
-       }
-       cfi->device_geometry.number_of_erase_regions = 1;
-       region->erase_block_size = 64 * 1024;
-       region->number_of_erase_blocks = 16;
-}
-
-static void amd_29lv400b_top_init_cfi( cfi_query_structure_t *cfi )
-{
-       cfi_erase_block_region_t *region;
-       const int region_number = 4;
-       region = malloc( sizeof (cfi_erase_block_region_t) * region_number);
-       cfi->device_geometry.erase_block_regions = region;
-       if (region == NULL) {
-               return;
-       }
-       cfi->device_geometry.number_of_erase_regions = region_number;
-       region[0].erase_block_size = 64 * 1024;
-       region[0].number_of_erase_blocks = 8;
-       region[1].erase_block_size = 32 * 1024;
-       region[1].number_of_erase_blocks = 1;
-       region[2].erase_block_size = 8 * 1024;
-       region[2].number_of_erase_blocks = 2;
-       region[3].erase_block_size = 16 * 1024;
-       region[3].number_of_erase_blocks = 1;
-}
-
-static void amd_29lv400b_bottom_init_cfi( cfi_query_structure_t *cfi )
-{
-       cfi_erase_block_region_t *region;
-       const int region_number = 4;
-       region = malloc( sizeof (cfi_erase_block_region_t) * region_number);
-       cfi->device_geometry.erase_block_regions = region;
-       if (region == NULL) {
-               return;
-       }
-       cfi->device_geometry.number_of_erase_regions = region_number;
-       region[0].erase_block_size = 16 * 1024;
-       region[0].number_of_erase_blocks = 1;
-       region[1].erase_block_size = 8 * 1024;
-       region[1].number_of_erase_blocks = 2;
-       region[2].erase_block_size = 32 * 1024;
-       region[2].number_of_erase_blocks = 1;
-       region[3].erase_block_size = 64 * 1024;
-       region[3].number_of_erase_blocks = 8;
-}
-
 int amd_detect(bus_t *bus, uint32_t adr, cfi_array_t **cfi_array )
 {
        int mid;
@@ -186,14 +112,8 @@ int amd_detect(bus_t *bus, uint32_t adr, cfi_array_t **cfi_array )
        if (mid != 0x01)
                return -1;
 
-       switch(did & 0xff)
+       switch(did)
        {
-               case 0xB9:
-                       var_forced_detection.flash = AMD_29LV400B_TOP;
-                       break;
-               case 0xBA:
-                       var_forced_detection.flash = AMD_29LV400B_BOTTOM;
-                       break;
                case 0xA4:
                        var_forced_detection.flash = AMD_29xx040B;
                        break;
@@ -201,9 +121,6 @@ int amd_detect(bus_t *bus, uint32_t adr, cfi_array_t **cfi_array )
                        var_forced_detection.flash = AMD_29xx040B;
                        var_forced_detection.algorithm = AMD_BYPASS_UNLOCK_ALGORITHM;
                        break;
-               case 0x38:
-                       var_forced_detection.flash = AMD_29xx081B;
-                       break;
                default:
                        break;
        }
@@ -236,24 +153,14 @@ int amd_detect(bus_t *bus, uint32_t adr, cfi_array_t **cfi_array )
                cfi->device_geometry.device_size = 512*1024;
                cfi->device_geometry.device_interface = 0;      // x 8
                cfi->device_geometry.max_bytes_write = 32;      //not used
-               switch (var_forced_detection.flash) {
-               case AMD_29xx040B:
-                 amd_29xx040b_init_cfi(cfi);
-                 break;
-               case AMD_29xx081B:
-                 amd_29xx081b_init_cfi(cfi);
-                 break;
-               case AMD_29LV400B_TOP:
-                 amd_29lv400b_top_init_cfi(cfi);
-                 break;
-               case AMD_29LV400B_BOTTOM:
-                 amd_29lv400b_bottom_init_cfi(cfi);
-                 break;
-               }
-
+               cfi->device_geometry.number_of_erase_regions = 1;
+               cfi->device_geometry.erase_block_regions =
+               malloc( cfi->device_geometry.number_of_erase_regions * sizeof (cfi_erase_block_region_t) );
                if (!cfi->device_geometry.erase_block_regions)
-                       return -2;      /* out of memory, or unsupported flash. */
+                       return -2;      /* out of memory */
 
+               cfi->device_geometry.erase_block_regions[0].erase_block_size = 64 * 1024;
+               cfi->device_geometry.erase_block_regions[0].number_of_erase_blocks = 8;
                //Add other details for info
        }
        return 0;
@@ -262,7 +169,7 @@ int amd_detect(bus_t *bus, uint32_t adr, cfi_array_t **cfi_array )
 
 static int amd_29xx040_autodetect( cfi_array_t *cfi_array )
 {
-       return (var_forced_detection.flash != AMD_UNKNOWN_DEVICE);
+       return(var_forced_detection.flash == AMD_29xx040B); //Non-CFI Am29xx040B flash
 }
 
 static int amd_29xx040_status( bus_t *bus, uint32_t adr, unsigned short data )
@@ -275,7 +182,7 @@ static int amd_29xx040_status( bus_t *bus, uint32_t adr, unsigned short data )
        dq5mask = (1 << 5);
        dq7bit = data & dq7mask;
 
-       for (timeout = 0; timeout < 70000; timeout++)   //typical sector erase time = 0.7 sec
+       for (timeout = 0; timeout < 1000; timeout++)    //typical sector erase time = 0.7 sec
        {
                data1 = (unsigned short)(bus_read( bus, adr ) & 0xFF);
                if((data1 & dq7mask) == dq7bit)
@@ -306,6 +213,7 @@ static void amd_29xx040_print_info( cfi_array_t *cfi_array )
        int mid, did, prot;
        bus_t *bus = cfi_array->bus;
 
+
        bus_write( bus, cfi_array->address + 0x0, 0xf0 );
        bus_write( bus, cfi_array->address + 0x555, 0xaa );
        bus_write( bus, cfi_array->address + 0x2AA, 0x55 );
@@ -329,14 +237,6 @@ static void amd_29xx040_print_info( cfi_array_t *cfi_array )
        }
        printf( _("\n\tChip: ") );
        switch (did) {
-               case 0xB9:
-                       printf( "Am29LV400B\t-\t" );
-                       printf( _("Top Boot Block\n") );
-                       break;
-               case 0xBA:
-                       printf( "Am29LV400B\t-\t" );
-                       printf( _("Bottom Boot Block\n") );
-                       break;
                case 0xA4:
                        printf( "Am29C040B\t-\t" );
                        printf( _("5V Flash\n") );
@@ -345,10 +245,6 @@ static void amd_29xx040_print_info( cfi_array_t *cfi_array )
                        printf( "Am29LV040B\t-\t" );
                        printf( _("3V Flash\n") );
                        break;
-               case 0x38:
-                       printf( "Am29LV081B\t-\t" );
-                       printf( _("3V Flash\n") );
-                       break;
                default:
                        printf ( _("Unknown (ID 0x%04x)"), did );
                        break;
@@ -371,10 +267,12 @@ static void amd_29xx040_read_array( cfi_array_t *cfi_array )
 
 
 
-static int _amd_29xx040_erase( cfi_array_t *cfi_array, uint32_t adr, int eraseall )
+static int amd_29xx040_erase_( cfi_array_t *cfi_array, uint32_t adr, int eraseall )
 {
        bus_t *bus = cfi_array->bus;
 
+       printf("flash_erase_block 0x%08X\n", adr);
+
        /*      printf("protected: %d\n", amdisprotected(ps, adr)); */
 
        if(var_forced_detection.unlock_bypass == AMD_BYPASS_UNLOCK_MODE)
@@ -391,7 +289,7 @@ static int _amd_29xx040_erase( cfi_array_t *cfi_array, uint32_t adr, int eraseal
        bus_write( bus, cfi_array->address + 0x555, 0x80 );
        bus_write( bus, cfi_array->address + 0x555, 0xaa );
        bus_write( bus, cfi_array->address + 0x2AA, 0x55 );
-       if (eraseall) {
+       if ( eraseall ) {
                bus_write( bus, cfi_array->address + 0x555, 0x10 );     //Chip Erase
        } else {
                bus_write( bus, adr, 0x30 );    //Sector erase
@@ -400,7 +298,7 @@ static int _amd_29xx040_erase( cfi_array_t *cfi_array, uint32_t adr, int eraseal
        if (amd_29xx040_status( bus, adr, 0xff )) {
                printf( "flash_erase_block 0x%08X DONE\n", adr );
                amd_29xx040_read_array( cfi_array );    /* AMD reset */
-               return FLASH_ERASE_SUCCESS;
+               return ERASE_FLASH_SUCCESS;
        }
        printf( "flash_erase_block 0x%08X FAILED\n", adr );
        /* Read Array */
@@ -409,21 +307,23 @@ static int _amd_29xx040_erase( cfi_array_t *cfi_array, uint32_t adr, int eraseal
        return FLASH_ERASE_ERROR;
 }
 
-static int amd_29xx040_erase_block( cfi_array_t *cfi_array, uint32_t adr)
+static int
+amd_29xx040_erase_block( cfi_array_t *cfi_array, uint32_t adr )
 {
        printf("flash_erase_block 0x%08X\n", adr);
-       return _amd_29xx040_erase( cfi_array, adr, 0 /* false */ );
+       return amd_29xx040_erase_( cfi_array, adr, 0 /* false */ );
 }
 
-static int amd_29xx040_erase_all( cfi_array_t *cfi_array)
+static int
+amd_29xx040_erase_all( cfi_array_t *cfi_array )
 {
        uint32_t adr;
+
        adr = cfi_array->address;
        printf("flash_erase_all 0x%08X\n", adr);
-       return _amd_29xx040_erase( cfi_array, adr, 1 /* true */ );
-}
-
 
+       return amd_29xx040_erase_( cfi_array, adr, 1 /* true */ );
+}
 
 static int amd_29xx040_program_single( cfi_array_t *cfi_array, uint32_t adr, uint32_t data )
 {
@@ -478,10 +378,11 @@ static int amd_29xx040_unlock_block( cfi_array_t *cfi_array, uint32_t adr )
        return 0;
 }
 
+
 flash_driver_t amd_29xx040_flash_driver = {
        1, /* buswidth */
        N_("AMD Standard Command Set"),
-       N_("supported: AMD 29LV040B, 29C040B, 29LV081B, 29LV400B 1x8 Bit"),
+       N_("supported: AMD 29LV040B, 29C040B, 1x8 Bit"),
        amd_29xx040_autodetect,
        amd_29xx040_print_info,
        amd_29xx040_erase_all,
index ec175f6..ee70115 100644 (file)
@@ -47,6 +47,9 @@
 #include "flash.h"
 #include "jtag.h"
 
+extern flash_driver_t amd_am29lv400b_flash_driver;
+extern flash_driver_t amd_am29lv081b_flash_driver;
+
 extern flash_driver_t amd_32_flash_driver;
 extern flash_driver_t amd_16_flash_driver;
 extern flash_driver_t amd_8_flash_driver;
@@ -56,6 +59,8 @@ extern flash_driver_t intel_8_flash_driver;
 extern flash_driver_t amd_29xx040_flash_driver;        //20/09/2006
 
 flash_driver_t *flash_drivers[] = {
+       &amd_am29lv400b_flash_driver,
+       &amd_am29lv081b_flash_driver,
        &amd_32_flash_driver,
        &amd_16_flash_driver,
        &amd_8_flash_driver,
index ed12f27..03072d0 100644 (file)
@@ -485,6 +485,7 @@ jedec_detect( bus_t *bus, uint32_t adr, cfi_array_t **cfi_array )
        cfi->identification_string.pri_vendor_tbl = NULL;
        cfi->identification_string.alt_id_code = 0;
        cfi->identification_string.alt_vendor_tbl = NULL;
+       cfi->identification_string._urjtag_manid_devid = (manid << 16) | devid;
 
        cfi->device_geometry.device_size = table[i].size;
        /* annotate chip width */