aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngelo Dureghello <sysamfw@gmail.com>2012-12-01 01:14:18 +0100
committerStefan Roese <sr@denx.de>2013-01-10 14:39:13 +0100
commit07b2c5c0e5abb8b6b996068471024410a7ef4bd4 (patch)
tree342e5c444db790da94d826f797cee723d9cfef21
parent642ef40bdc95bef829ae3aadc217f829c4c298c4 (diff)
mtd/cfi: add support for SST 4KB sector granularity
Add support for SST 4KB sector granularity. Many recent SST flashes, i.e. SST39VF3201B and similar of this family are declared CFI-conformant from SST. They support CFI query, but implement 2 different sector sizes in the same memory: a 64KB sector (they call it "block", std AMD erase cmd=0x30), and a 4KB sector (they call it "sector", erase cmd=0x50). Also, CFI query on these chips, reading from address 0x2dh of cfi query struct, detects a number of secotrs for the 4KB granularity (flinfo shows it). For all other aspects, they are CFI compliant, so, as Linux do, i think it's a good idea to handle these chips in the CFI driver, with a fixup to allow 4KB granularity, as should be expected, instead of 64KB. Signed-off-by: Angelo Dureghello <sysamfw@gmail.com> Signed-off-by: Stefan Rose <sr@denx.de>
-rw-r--r--drivers/mtd/cfi_flash.c25
-rw-r--r--include/flash.h1
2 files changed, 25 insertions, 1 deletions
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index b2dfc5369..c8099db14 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -1128,7 +1128,7 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
AMD_CMD_ERASE_START);
flash_unlock_seq (info, sect);
flash_write_cmd (info, sect, 0,
- AMD_CMD_ERASE_SECTOR);
+ info->cmd_erase_sector);
break;
#ifdef CONFIG_FLASH_CFI_LEGACY
case CFI_CMDSET_AMD_LEGACY:
@@ -1733,6 +1733,7 @@ static void cmdset_amd_read_jedec_ids(flash_info_t *info)
static int cmdset_amd_init(flash_info_t *info, struct cfi_qry *qry)
{
info->cmd_reset = AMD_CMD_RESET;
+ info->cmd_erase_sector = AMD_CMD_ERASE_SECTOR;
cmdset_amd_read_jedec_ids(info);
flash_write_cmd(info, 0, info->cfi_offset, FLASH_CMD_CFI);
@@ -2003,6 +2004,25 @@ static void flash_fixup_stm(flash_info_t *info, struct cfi_qry *qry)
}
}
+static void flash_fixup_sst(flash_info_t *info, struct cfi_qry *qry)
+{
+ /*
+ * SST, for many recent nor parallel flashes, says they are
+ * CFI-conformant. This is not true, since qry struct.
+ * reports a std. AMD command set (0x0002), while SST allows to
+ * erase two different sector sizes for the same memory.
+ * 64KB sector (SST call it block) needs 0x30 to be erased.
+ * 4KB sector (SST call it sector) needs 0x50 to be erased.
+ * Since CFI query detect the 4KB number of sectors, users expects
+ * a sector granularity of 4KB, and it is here set.
+ */
+ if (info->device_id == 0x5D23 || /* SST39VF3201B */
+ info->device_id == 0x5C23) { /* SST39VF3202B */
+ /* set sector granularity to 4KB */
+ info->cmd_erase_sector=0x50;
+ }
+}
+
/*
* The following code cannot be run from FLASH!
*
@@ -2081,6 +2101,9 @@ ulong flash_get_size (phys_addr_t base, int banknum)
case 0x0020:
flash_fixup_stm(info, &qry);
break;
+ case 0x00bf: /* SST */
+ flash_fixup_sst(info, &qry);
+ break;
}
debug ("manufacturer is %d\n", info->vendor);
diff --git a/include/flash.h b/include/flash.h
index 7db599e78..c7acc977e 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -44,6 +44,7 @@ typedef struct {
ulong buffer_write_tout; /* maximum buffer write timeout */
ushort vendor; /* the primary vendor id */
ushort cmd_reset; /* vendor specific reset command */
+ uchar cmd_erase_sector; /* vendor specific erase sect. command */
ushort interface; /* used for x8/x16 adjustments */
ushort legacy_unlock; /* support Intel legacy (un)locking */
ushort manufacturer_id; /* manufacturer id */