summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAnatolij Gustschin <agust@denx.de>2012-08-09 08:18:12 +0200
committerStefan Roese <sr@denx.de>2012-08-13 14:34:35 +0200
commit66863b0538d3667a0a4bb64b0eb9197aea27f855 (patch)
tree636fe1a955a7ff4884a164ab069b86668676a208 /drivers
parentb4f106be2d8a4eb34ce41c5306d5a4fcc37e60e3 (diff)
downloadu-boot-imx-66863b0538d3667a0a4bb64b0eb9197aea27f855.zip
u-boot-imx-66863b0538d3667a0a4bb64b0eb9197aea27f855.tar.gz
u-boot-imx-66863b0538d3667a0a4bb64b0eb9197aea27f855.tar.bz2
cfi_flash: add support for Spansion flash PPB sector protection
Erasing flash sectors protected with persistent protection bit (PPB) mechanism on Spansion flash chips doesn't work. Add sector protection status checking and sector lock and unlock commands to fix this. Signed-off-by: Anatolij Gustschin <agust@denx.de> Cc: Stefan Roese <sr@denx.de> Signed-off-by: Stefan Roese <sr@denx.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/cfi_flash.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 35294bc..50df9b0 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -1447,6 +1447,47 @@ int flash_real_protect (flash_info_t * info, long sector, int prot)
0, ATM_CMD_UNLOCK_SECT);
}
}
+ if (info->manufacturer_id == (uchar)AMD_MANUFACT) {
+ int flag = disable_interrupts();
+ int lock_flag;
+
+ flash_unlock_seq(info, 0);
+ flash_write_cmd(info, 0, info->addr_unlock1,
+ AMD_CMD_SET_PPB_ENTRY);
+ lock_flag = flash_isset(info, sector, 0, 0x01);
+ if (prot) {
+ if (lock_flag) {
+ flash_write_cmd(info, sector, 0,
+ AMD_CMD_PPB_LOCK_BC1);
+ flash_write_cmd(info, sector, 0,
+ AMD_CMD_PPB_LOCK_BC2);
+ }
+ debug("sector %ld %slocked\n", sector,
+ lock_flag ? "" : "already ");
+ } else {
+ if (!lock_flag) {
+ debug("unlock %ld\n", sector);
+ flash_write_cmd(info, 0, 0,
+ AMD_CMD_PPB_UNLOCK_BC1);
+ flash_write_cmd(info, 0, 0,
+ AMD_CMD_PPB_UNLOCK_BC2);
+ }
+ debug("sector %ld %sunlocked\n", sector,
+ !lock_flag ? "" : "already ");
+ }
+ if (flag)
+ enable_interrupts();
+
+ if (flash_status_check(info, sector,
+ info->erase_blk_tout,
+ prot ? "protect" : "unprotect"))
+ printf("status check error\n");
+
+ flash_write_cmd(info, 0, 0,
+ AMD_CMD_SET_PPB_EXIT_BC1);
+ flash_write_cmd(info, 0, 0,
+ AMD_CMD_SET_PPB_EXIT_BC2);
+ }
break;
#ifdef CONFIG_FLASH_CFI_LEGACY
case CFI_CMDSET_AMD_LEGACY:
@@ -1635,6 +1676,17 @@ static int cmdset_amd_init(flash_info_t *info, struct cfi_qry *qry)
cmdset_amd_read_jedec_ids(info);
flash_write_cmd(info, 0, info->cfi_offset, FLASH_CMD_CFI);
+#ifdef CONFIG_SYS_FLASH_PROTECTION
+ if (info->ext_addr && info->manufacturer_id == (uchar)AMD_MANUFACT) {
+ ushort spus;
+
+ /* read sector protect/unprotect scheme */
+ spus = flash_read_uchar(info, info->ext_addr + 9);
+ if (spus == 0x8)
+ info->legacy_unlock = 1;
+ }
+#endif
+
return 0;
}