The ST/Numonix M29W128G has an issue when a 0xff cmd is sent,
it cause an internal undefined state. The workaround according
to the Numonyx is to send another 0xf0 reset cmd.

Objections ?

Cheers
Spen
>From 2cff3cc5c0d50adfa53db7daeb3c1661e94890a5 Mon Sep 17 00:00:00 2001
From: Spencer Oliver <[email protected]>
Date: Mon, 10 May 2010 12:23:41 +0100
Subject: [PATCH] cfi: add Numonyx M29W128G reset workaround

The ST/Numonix M29W128G has an issue when a 0xff cmd is sent,
it cause an internal undefined state. The workaround according
to the Numonyx is to send another 0xf0 reset cmd

Signed-off-by: Spencer Oliver <[email protected]>
---
 src/flash/nor/cfi.c |   67 ++++++++++++++++++++++++++------------------------
 1 files changed, 35 insertions(+), 32 deletions(-)

diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c
index 4ef41b9..aa4540a 100644
--- a/src/flash/nor/cfi.c
+++ b/src/flash/nor/cfi.c
@@ -104,7 +104,6 @@ static __inline__ uint32_t flash_address(struct flash_bank 
*bank, int sector, ui
                }
                return bank->base + bank->sectors[sector].offset + offset * 
bank->bus_width;
        }
-
 }
 
 static void cfi_command(struct flash_bank *bank, uint8_t cmd, uint8_t *cmd_buf)
@@ -232,6 +231,35 @@ static uint32_t cfi_query_u32(struct flash_bank *bank, int 
sector, uint32_t offs
                                data[(3 * bank->bus_width) - 1] << 16 | data[(4 
* bank->bus_width) - 1] << 24;
 }
 
+static int cfi_reset(struct flash_bank *bank)
+{
+       struct cfi_flash_bank *cfi_info = bank->driver_priv;
+       int retval = ERROR_OK;
+
+       if ((retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 
0x0))) != ERROR_OK)
+       {
+               return retval;
+       }
+
+       if ((retval = cfi_send_command(bank, 0xff, flash_address(bank, 0, 
0x0))) != ERROR_OK)
+       {
+               return retval;
+       }
+
+       if (cfi_info->manufacturer == 0x20 &&
+                       (cfi_info->device_id == 0x227E || cfi_info->device_id 
== 0x7E))
+       {
+               /* Numonix M29W128G is cmd 0xFF intolerant - causes internal 
undefined state
+                * so we send an extra 0xF0 reset to fix the bug */
+               if ((retval = cfi_send_command(bank, 0xf0, flash_address(bank, 
0, 0x00))) != ERROR_OK)
+               {
+                       return retval;
+               }
+       }
+
+       return retval;
+}
+
 static void cfi_intel_clear_status_register(struct flash_bank *bank)
 {
        struct target *target = bank->target;
@@ -335,11 +363,7 @@ static int cfi_read_intel_pri_ext(struct flash_bank *bank)
 
        if ((pri_ext->pri[0] != 'P') || (pri_ext->pri[1] != 'R') || 
(pri_ext->pri[2] != 'I'))
        {
-               if ((retval = cfi_send_command(bank, 0xf0, flash_address(bank, 
0, 0x0))) != ERROR_OK)
-               {
-                       return retval;
-               }
-               if ((retval = cfi_send_command(bank, 0xff, flash_address(bank, 
0, 0x0))) != ERROR_OK)
+               if ((retval = cfi_reset(bank)) != ERROR_OK)
                {
                        return retval;
                }
@@ -1977,11 +2001,7 @@ static int cfi_write(struct flash_bank *bank, uint8_t 
*buffer, uint32_t offset,
        }
 
        /* return to read array mode, so we can read from flash again for 
padding */
-       if ((retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 
0x0))) != ERROR_OK)
-       {
-               return retval;
-       }
-       if ((retval = cfi_send_command(bank, 0xff, flash_address(bank, 0, 
0x0))) != ERROR_OK)
+       if ((retval = cfi_reset(bank)) != ERROR_OK)
        {
                return retval;
        }
@@ -2015,11 +2035,7 @@ static int cfi_write(struct flash_bank *bank, uint8_t 
*buffer, uint32_t offset,
        }
 
        /* return to read array mode */
-       if ((retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 
0x0))) != ERROR_OK)
-       {
-               return retval;
-       }
-       return cfi_send_command(bank, 0xff, flash_address(bank, 0, 0x0));
+       return cfi_reset(bank);
 }
 
 static void cfi_fixup_atmel_reversed_erase_regions(struct flash_bank *bank, 
void *param)
@@ -2083,11 +2099,7 @@ static int cfi_query_string(struct flash_bank *bank, int 
address)
 
        if ((cfi_info->qry[0] != 'Q') || (cfi_info->qry[1] != 'R') || 
(cfi_info->qry[2] != 'Y'))
        {
-               if ((retval = cfi_send_command(bank, 0xf0, flash_address(bank, 
0, 0x0))) != ERROR_OK)
-               {
-                       return retval;
-               }
-               if ((retval = cfi_send_command(bank, 0xff, flash_address(bank, 
0, 0x0))) != ERROR_OK)
+               if ((retval = cfi_reset(bank)) != ERROR_OK)
                {
                        return retval;
                }
@@ -2168,11 +2180,7 @@ static int cfi_probe(struct flash_bank *bank)
 
        LOG_INFO("Flash Manufacturer/Device: 0x%04x 0x%04x", 
cfi_info->manufacturer, cfi_info->device_id);
        /* switch back to read array mode */
-       if ((retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 
0x00))) != ERROR_OK)
-       {
-               return retval;
-       }
-       if ((retval = cfi_send_command(bank, 0xff, flash_address(bank, 0, 
0x00))) != ERROR_OK)
+       if ((retval = cfi_reset(bank)) != ERROR_OK)
        {
                return retval;
        }
@@ -2289,11 +2297,7 @@ static int cfi_probe(struct flash_bank *bank)
                /* return to read array mode
                 * we use both reset commands, as some Intel flashes fail to 
recognize the 0xF0 command
                 */
-               if ((retval = cfi_send_command(bank, 0xf0, flash_address(bank, 
0, 0x0))) != ERROR_OK)
-               {
-                       return retval;
-               }
-               if ((retval = cfi_send_command(bank, 0xff, flash_address(bank, 
0, 0x0))) != ERROR_OK)
+               if ((retval = cfi_reset(bank)) != ERROR_OK)
                {
                        return retval;
                }
@@ -2377,7 +2381,6 @@ static int cfi_auto_probe(struct flash_bank *bank)
        return cfi_probe(bank);
 }
 
-
 static int cfi_intel_protect_check(struct flash_bank *bank)
 {
        int retval;
-- 
1.6.6.1

_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to