diff --git a/jtag/ChangeLog b/jtag/ChangeLog index af4e4b3c..bb21eb27 100644 --- a/jtag/ChangeLog +++ b/jtag/ChangeLog @@ -1,3 +1,12 @@ +2008-12-02 Arnim Laeuger + + * include/flash/intel.h, src/flash/intel.c: + support for multi-byte write mode + chips must match the following criteria to qualify + - CFI data specifies multi-byte write mode supported + - handled by intel.c + - 8 or 16 bit interface + 2008-12-01 Arnim Laeuger * include/flash.h, src/flash/amd_flash.c, src/flash/amd.c, src/flash/intel.c, src/flash/flash.c, configure.ac: diff --git a/jtag/include/flash/intel.h b/jtag/include/flash/intel.h index febdb482..995a9f32 100644 --- a/jtag/include/flash/intel.h +++ b/jtag/include/flash/intel.h @@ -56,6 +56,7 @@ #define CFI_INTEL_CMD_BLOCK_ERASE 0x20 /* 28FxxxJ3A, 28FxxxK3, 28FxxxK18 */ #define CFI_INTEL_CMD_SUSPEND 0xB0 /* 28FxxxJ3A, 28FxxxK3, 28FxxxK18 */ #define CFI_INTEL_CMD_RESUME 0xD0 /* 28FxxxJ3A, 28FxxxK3, 28FxxxK18 */ +#define CFI_INTEL_CMD_WRITE_CONFIRM 0xD0 /* 28FxxxJ3A, 28FxxxK3, 28FxxxK18 */ #define CFI_INTEL_CMD_LOCK_SETUP 0x60 /* 28FxxxJ3A, 28FxxxK3, 28FxxxK18 */ #define CFI_INTEL_CMD_LOCK_BLOCK 0x01 /* 28FxxxJ3A, 28FxxxK3, 28FxxxK18 */ #define CFI_INTEL_CMD_UNLOCK_BLOCK 0xD0 /* 28FxxxJ3A - unlocks all blocks, 28FFxxxK3, 28FxxxK18 */ diff --git a/jtag/src/flash/intel.c b/jtag/src/flash/intel.c index 5cb8180b..10802855 100644 --- a/jtag/src/flash/intel.c +++ b/jtag/src/flash/intel.c @@ -113,6 +113,9 @@ _intel_flash_print_info( cfi_array_t *cfi_array, int o ) case STD_MIC_MITSUBISHI: printf( _("Manufacturer: %s\n"), STD_MICN_MITSUBISHI ); break; + case STD_MIC_MICRON_TECHNOLOGY: + printf( _("Manufacturer: %s\n"), STD_MICN_MICRON_TECHNOLOGY ); + break; default: printf( _("Unknown manufacturer (0x%04X)!\n"), mid); break; @@ -282,6 +285,41 @@ intel_flash_program( cfi_array_t *cfi_array, uint32_t adr, uint32_t data ) return 0; } +static int +intel_flash_program_buffer( cfi_array_t *cfi_array, uint32_t adr, uint32_t *buffer, int count ) +{ + uint16_t sr; + bus_t *bus = cfi_array->bus; + int idx; + uint32_t block_adr = adr; + + /* issue command WRITE_TO_BUFFER */ + bus_write( bus, cfi_array->address, CFI_INTEL_CMD_CLEAR_STATUS_REGISTER ); + bus_write( bus, adr, CFI_INTEL_CMD_WRITE_TO_BUFFER ); + /* poll XSR7 == 1 */ + while (!((sr = bus_read( bus, cfi_array->address ) & 0xFE) & CFI_INTEL_SR_READY)) ; /* TODO: add timeout */ + + /* write count value (number of upcoming writes - 1) */ + bus_write( bus, adr, count-1 ); + + /* write payload to buffer */ + for (idx = 0; idx < count; idx++) { + bus_write( bus, adr, buffer[idx] ); + adr += cfi_array->bus_width; + } + + /* issued command WRITE_CONFIRM */ + bus_write( bus, block_adr, CFI_INTEL_CMD_WRITE_CONFIRM ); + + /* poll SR7 == 1 */ + while (!((sr = bus_read( bus, cfi_array->address ) & 0xFE) & CFI_INTEL_SR_READY)) ; /* TODO: add timeout */ + if (sr != CFI_INTEL_SR_READY) { + printf( _("flash: unknown error while programming\n") ); + return FLASH_ERROR_UNKNOWN; + } else + return 0; +} + static int intel_flash_erase_block32( cfi_array_t *cfi_array, uint32_t adr ) { @@ -375,7 +413,7 @@ flash_driver_t intel_16_flash_driver = { intel_flash_erase_block, intel_flash_unlock_block, intel_flash_program, - NULL, + intel_flash_program_buffer, intel_flash_readarray, }; @@ -388,6 +426,6 @@ flash_driver_t intel_8_flash_driver = { intel_flash_erase_block, intel_flash_unlock_block, intel_flash_program, - NULL, + intel_flash_program_buffer, intel_flash_readarray, };