From: Masaki Muranaka Date: Wed, 15 Jul 2009 08:51:54 +0000 (+0900) Subject: Prepare for ADFE-FlashWriter 1.0.4 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=b471a78acb644f8b6b71c3d0e27dc924f0ca072f;p=pf3gnuchains%2Furjtag.git Prepare for ADFE-FlashWriter 1.0.4 --- diff --git a/jtag/src/flash/amd_flash.c b/jtag/src/flash/amd_flash.c index a3c56ba..22de3ec 100644 --- a/jtag/src/flash/amd_flash.c +++ b/jtag/src/flash/amd_flash.c @@ -24,6 +24,8 @@ * Documentation: * [1] Spansion, Am29F040B Data Sheet * [2] Spansion, Am29LV040B Data Sheet + * [3] Spansion, Am29LV081B Data Sheet + * [4] Spansion, Am29LV400D Data Sheet */ #include "sysdep.h" @@ -57,9 +59,13 @@ #define AMD_UNDEFINED_MODE #define FLASH_ERASE_ERROR -5 -#define ERASE_FLASH_SUCCESS 1 +#define FLASH_ERASE_SUCCESS 0 -#define AMD_29xx040B 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_BYPASS_UNLOCK_ALGORITHM 1 #define AMD_STANDARD_WRITE_ALGORITHM 0 @@ -72,19 +78,88 @@ struct unsigned short algorithm; unsigned short unlock_bypass; } -var_forced_detection; + var_forced_detection = { AMD_UNKNOWN_DEVICE, 0, 0}; 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_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; @@ -111,8 +186,14 @@ int amd_detect(bus_t *bus, uint32_t adr, cfi_array_t **cfi_array ) if (mid != 0x01) return -1; - switch(did) + switch(did & 0xff) { + 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; @@ -120,13 +201,16 @@ 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; } (*cfi_array)->bus = bus; - (*cfi_array)->address = 0; - if (bus_area( bus, adr+0, &area ) != URJTAG_STATUS_OK) + (*cfi_array)->address = adr; + if (bus_area( bus, adr, &area ) != URJTAG_STATUS_OK) return -8; /* bus width detection failed */ unsigned int bw = area.width; int ba,i; @@ -152,14 +236,24 @@ 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 - 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) ); + 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; + } + if (!cfi->device_geometry.erase_block_regions) - return -2; /* out of memory */ + return -2; /* out of memory, or unsupported flash. */ - cfi->device_geometry.erase_block_regions[i].erase_block_size = 64 * 1024; - cfi->device_geometry.erase_block_regions[i].number_of_erase_blocks = 8; //Add other details for info } return 0; @@ -168,7 +262,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_29xx040B); //Non-CFI Am29xx040B flash + return (var_forced_detection.flash != AMD_UNKNOWN_DEVICE); } static int amd_29xx040_status( bus_t *bus, uint32_t adr, unsigned short data ) @@ -181,7 +275,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 < 1000; timeout++) //typical sector erase time = 0.7 sec + for (timeout = 0; timeout < 70000; timeout++) //typical sector erase time = 0.7 sec { data1 = (unsigned short)(bus_read( bus, adr ) & 0xFF); if((data1 & dq7mask) == dq7bit) @@ -212,7 +306,6 @@ 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 ); @@ -236,6 +329,14 @@ 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") ); @@ -244,6 +345,10 @@ 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; @@ -266,12 +371,10 @@ static void amd_29xx040_read_array( cfi_array_t *cfi_array ) -static int amd_29xx040_erase_block( cfi_array_t *cfi_array, uint32_t adr ) +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) @@ -288,14 +391,16 @@ static int amd_29xx040_erase_block( cfi_array_t *cfi_array, uint32_t adr ) bus_write( bus, cfi_array->address + 0x555, 0x80 ); bus_write( bus, cfi_array->address + 0x555, 0xaa ); bus_write( bus, cfi_array->address + 0x2AA, 0x55 ); -// bus_write( bus, cfi_array->address + 0x555, 0x10 ); //Chip Erase - bus_write( bus, adr, 0x30 ); //Sector erase - + if (eraseall) { + bus_write( bus, cfi_array->address + 0x555, 0x10 ); //Chip Erase + } else { + bus_write( bus, adr, 0x30 ); //Sector erase + } 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 ERASE_FLASH_SUCCESS; + return FLASH_ERASE_SUCCESS; } printf( "flash_erase_block 0x%08X FAILED\n", adr ); /* Read Array */ @@ -304,6 +409,22 @@ static int amd_29xx040_erase_block( cfi_array_t *cfi_array, uint32_t adr ) return FLASH_ERASE_ERROR; } +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 */ ); +} + +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 */ ); +} + + + static int amd_29xx040_program_single( cfi_array_t *cfi_array, uint32_t adr, uint32_t data ) { int status; @@ -357,19 +478,10 @@ static int amd_29xx040_unlock_block( cfi_array_t *cfi_array, uint32_t adr ) return 0; } -static int -amd_29xx040_erase_all( cfi_array_t *cfi_array ) -{ - printf("Error: not implemented."); - return FLASH_ERROR_UNKNOWN; -} - - - flash_driver_t amd_29xx040_flash_driver = { 1, /* buswidth */ N_("AMD Standard Command Set"), - N_("supported: AMD 29LV040B, 29C040B, 1x8 Bit"), + N_("supported: AMD 29LV040B, 29C040B, 29LV081B, 29LV400B 1x8 Bit"), amd_29xx040_autodetect, amd_29xx040_print_info, amd_29xx040_erase_all,