mtd/cfi_flash: fix write problems for Numonyx P33/30 32 MBit flashs
authorHolger Brunck <holger.brunck@keymile.com>
Thu, 9 Aug 2012 08:22:41 +0000 (10:22 +0200)
committerStefan Roese <sr@denx.de>
Mon, 13 Aug 2012 12:34:44 +0000 (14:34 +0200)
commit 54652991
Work around bug in Numonyx P33/P30 256-Mbit 65nm flash chips

fixes a problem for Numonyx P33/P30 flashes for 256-Mbit, but this leads
to problems for smaller versions of this chip e.g. the 32Mbit version
with deviceid 0x16 on mgcoge. So move the code for this work around to
an own function and check previously manufacturer id and device id to
not break other flashes which don't need this work around.

Signed-off-by: Holger Brunck <holger.brunck@keymile.com>
Signed-off-by: Heiko Schocher <hs@denx.de>
cc: Stefan Roese <sr@denx.de>
cc: Philippe De Muyter <phdm@macqel.be>
cc: Gerlando Falauto <gerlando.falauto@keymile.com>
Signed-off-by: Stefan Roese <sr@denx.de>
drivers/mtd/cfi_flash.c
include/flash.h

index 50df9b0dda44059f782567afb3ccaf83026d8a3c..f0f301a46023e67c952b5dd7f65790f835fd28a8 100644 (file)
@@ -1391,6 +1391,40 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
  */
 #ifdef CONFIG_SYS_FLASH_PROTECTION
 
+static int cfi_protect_bugfix(flash_info_t *info, long sector, int prot)
+{
+       if ((info->manufacturer_id == (uchar)INTEL_MANUFACT) &&
+               (info->device_id == NUMONYX_256MBIT)) {
+               /*
+                * see errata called
+                * "Numonyx Axcell P33/P30 Specification Update" :)
+                */
+               flash_write_cmd(info, sector, 0, FLASH_CMD_READ_ID);
+               if (!flash_isequal(info, sector, FLASH_OFFSET_PROTECT,
+                                  prot)) {
+                       /*
+                        * cmd must come before FLASH_CMD_PROTECT + 20us
+                        * Disable interrupts which might cause a timeout here.
+                        */
+                       int flag = disable_interrupts();
+                       unsigned short cmd;
+
+                       if (prot)
+                               cmd = FLASH_CMD_PROTECT_SET;
+                       else
+                               cmd = FLASH_CMD_PROTECT_CLEAR;
+                               flash_write_cmd(info, sector, 0,
+                                         FLASH_CMD_PROTECT);
+                       flash_write_cmd(info, sector, 0, cmd);
+                       /* re-enable interrupts if necessary */
+                       if (flag)
+                               enable_interrupts();
+               }
+               return 1;
+       }
+       return 0;
+}
+
 int flash_real_protect (flash_info_t * info, long sector, int prot)
 {
        int retcode = 0;
@@ -1399,31 +1433,18 @@ int flash_real_protect (flash_info_t * info, long sector, int prot)
                case CFI_CMDSET_INTEL_PROG_REGIONS:
                case CFI_CMDSET_INTEL_STANDARD:
                case CFI_CMDSET_INTEL_EXTENDED:
-                       /*
-                        * see errata called
-                        * "Numonyx Axcell P33/P30 Specification Update" :)
-                        */
-                       flash_write_cmd (info, sector, 0, FLASH_CMD_READ_ID);
-                       if (!flash_isequal (info, sector, FLASH_OFFSET_PROTECT,
-                                           prot)) {
-                               /*
-                                * cmd must come before FLASH_CMD_PROTECT + 20us
-                                * Disable interrupts which might cause a timeout here.
-                                */
-                               int flag = disable_interrupts ();
-                               unsigned short cmd;
-
+                       if (!cfi_protect_bugfix(info, sector, prot)) {
+                               flash_write_cmd(info, sector, 0,
+                                        FLASH_CMD_CLEAR_STATUS);
+                               flash_write_cmd(info, sector, 0,
+                                       FLASH_CMD_PROTECT);
                                if (prot)
-                                       cmd = FLASH_CMD_PROTECT_SET;
+                                       flash_write_cmd(info, sector, 0,
+                                               FLASH_CMD_PROTECT_SET);
                                else
-                                       cmd = FLASH_CMD_PROTECT_CLEAR;
+                                       flash_write_cmd(info, sector, 0,
+                                               FLASH_CMD_PROTECT_CLEAR);
 
-                               flash_write_cmd (info, sector, 0,
-                                                 FLASH_CMD_PROTECT);
-                               flash_write_cmd (info, sector, 0, cmd);
-                               /* re-enable interrupts if necessary */
-                               if (flag)
-                                       enable_interrupts ();
                        }
                        break;
                case CFI_CMDSET_AMD_EXTENDED:
index 0ca70d9c9cc632bb87e0d3d2e02669d0598c87e5..e614d07dfa90187ca32835ff751755e5eb23db29 100644 (file)
@@ -348,6 +348,7 @@ extern flash_info_t *flash_get_info(ulong base);
 #define TOSH_ID_FVT160 0xC2            /* TC58FVT160 ID (16 M, top )           */
 #define TOSH_ID_FVB160 0x43            /* TC58FVT160 ID (16 M, bottom )        */
 #define PHILIPS_LPC2292 0x0401FF13  /* LPC2292 internal FLASH                  */
+#define NUMONYX_256MBIT        0x8922          /* Numonyx P33/30 256MBit 65nm  */
 
 /*-----------------------------------------------------------------------
  * Internal FLASH identification codes