Signed-off-by: John McCarthy <jg...@ma...>
---
src/flash/cfi.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 71 insertions(+), 1 deletions(-)
diff --git src/flash/cfi.c src/flash/cfi.c
index 5801109..4f87463 100644
--- src/flash/cfi.c
+++ src/flash/cfi.c
@@ -1595,7 +1595,7 @@ int cfi_spansion_write_word(struct flash_bank_s *bank, u8 *word, u32 address)
return ERROR_OK;
}
-int cfi_spansion_write_words(struct flash_bank_s *bank, u8 *word, u32 wordcount, u32 address)
+int cfi_spansion_write_words_Buffered(struct flash_bank_s *bank, u8 *word, u32 wordcount, u32 address)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
target_t *target = bank->target;
@@ -1663,6 +1663,66 @@ int cfi_spansion_write_words(struct flash_bank_s *bank, u8 *word, u32 wordcount,
return ERROR_OK;
}
+int cfi_spansion_write_words_UnlockBypass(struct flash_bank_s *bank, u8 *word, u32 wordcount, u32 address)
+{
+ u32 i;
+ int retval = ERROR_OK;
+ cfi_flash_bank_t *cfi_info = bank->driver_priv;
+ cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext;
+ target_t *target = bank->target;
+ u8 command[8];
+
+ /* Enter Unlock Bypass mode */
+ cfi_command(bank, 0xaa, command);
+ target->type->write_memory(target, flash_address(bank, 0, pri_ext->_unlock1), bank->bus_width, 1, command);
+
+ cfi_command(bank, 0x55, command);
+ target->type->write_memory(target, flash_address(bank, 0, pri_ext->_unlock2), bank->bus_width, 1, command);
+
+ cfi_command(bank, 0x20, command);
+ target->type->write_memory(target, flash_address(bank, 0, 0), bank->bus_width, 1, command);
+
+ for (i=0; i<wordcount; i++) {
+ cfi_command(bank, 0xA0, command);
+ target->type->write_memory(target, flash_address(bank, 0, 0), bank->bus_width, 1, command);
+
+ target->type->write_memory(target, address, bank->bus_width, 1, word);
+
+ if (cfi_spansion_wait_status_busy(bank, 1000 * (1 << cfi_info->word_write_timeout_max)) != ERROR_OK)
+ {
+ LOG_ERROR("couldn't write word at base 0x%x, address %x", bank->base, address);
+ retval = ERROR_FLASH_OPERATION_FAILED;
+ break;
+ }
+
+ word += bank->bus_width;
+ address += bank->bus_width;
+ }
+
+ /* Exit Unlock Bypass mode */
+ cfi_command(bank, 0x90, command);
+ target->type->write_memory(target, flash_address(bank, 0, 0), bank->bus_width, 1, command);
+
+ cfi_command(bank, 0x00, command);
+ target->type->write_memory(target, flash_address(bank, 0, 0), bank->bus_width, 1, command);
+
+ return retval;
+}
+
+int cfi_spansion_write_words(struct flash_bank_s *bank, u8 *word, u32 wordcount, u32 address)
+{
+ cfi_flash_bank_t *cfi_info = bank->driver_priv;
+
+ /*
+ * TODO: detect flash parts with support for neither Buffered
+ * nor UnlockBypass and return ERROR_FLASH_OPERATION_FAILED.
+ */
+ if(cfi_info->max_buf_write_size == 0)
+ return cif_spansion_write_words_UnlockBypass(bank, word, wordcount, address);
+ else
+ return cif_spansion_write_words_Buffered(bank, word, wordcount, address);
+}
+
int cfi_write_word(struct flash_bank_s *bank, u8 *word, u32 address)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
@@ -1801,6 +1861,15 @@ int cfi_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
u32 buffermask = buffersize-1;
u32 bufferwsize;
+ if(cfi_info->max_buf_write_size == 0 && cfi_info->pri_id == 2) {
+ /*
+ * Spansion hack to allow Unlock Bypass writes on chips
+ * that don't support buffered writes
+ */
+ buffersize = 1UL << 10;
+ buffermask = buffersize-1;
+ }
+
switch(bank->chip_width)
{
case 4 : bufferwsize = buffersize / 4; break;
@@ -1810,6 +1879,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;
}
+ LOG_INFO("Using cfi_write_words with buffer size %u words (%u bytes)", bufferwsize, buffersize);
/* fall back to memory writes */
while (count >= bank->bus_width)
--
1.5.4.3
--=-uPA0ZKWhAY2SZc0vwnSX
Content-Disposition: attachment; filename=0007-Fix-typo-in-cfi_spansion_write_words-wrapper.patch
Content-Type: application/mbox; name=0007-Fix-typo-in-cfi_spansion_write_words-wrapper.patch
Content-Transfer-Encoding: 7bit
|