summaryrefslogtreecommitdiff
path: root/drivers/mtd/cfi_flash.c
diff options
context:
space:
mode:
authorHolger Brunck <holger.brunck@keymile.com>2012-08-09 10:22:41 +0200
committerStefan Roese <sr@denx.de>2012-08-13 14:34:44 +0200
commit81316a902a2c76bc880ab49c6d157e3e9754806d (patch)
treeea31154edcc7cc39e14b52ace0eb2840238df55b /drivers/mtd/cfi_flash.c
parent66863b0538d3667a0a4bb64b0eb9197aea27f855 (diff)
mtd/cfi_flash: fix write problems for Numonyx P33/30 32 MBit flashs
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>
Diffstat (limited to 'drivers/mtd/cfi_flash.c')
-rw-r--r--drivers/mtd/cfi_flash.c65
1 files changed, 43 insertions, 22 deletions
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 50df9b0dda..f0f301a460 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -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: