aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrent Piepho <tpiepho@freescale.com>2008-03-31 00:19:30 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2008-04-22 16:17:27 -0400
commit70b072550a59e787b46030ab104ac64e25fcc732 (patch)
tree41e3b0ffe47a5e134342625217d8a08c1531e4d6
parentfecb8865def541ff38f59ef3caf0cbd09f4fc9fd (diff)
[MTD] [NOR] Fixup for incorrect CFI data in Spansion S29GL064/32N flash chips
This is a known erratum confirmed by Spansion. I have an errata document, but I can't find a link to it anywhere on their site to include here. Some of the S29GL064N chips report 64 sectors when they should report 128, and some of S29GL032N chips report 127 sectors when they should report 63. Note that when the chip dies are fixed by Spansion, they will still have the same id. The fix is done in such a way that it won't affect corrected chips. The fixups use the extended id made available by a previous patch. Without that, virtually all newer AMD/Spansion chips will have the same ID (0x227e) and it's not possible to apply the fixup to the correct chips. Signed-off-by: Trent Piepho <tpiepho@freescale.com> Signed-off-by: David Woodhouse <dwmw2@infradead.org>
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 5cd657322bc4..f7fcc6389533 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -220,6 +220,28 @@ static void fixup_use_atmel_lock(struct mtd_info *mtd, void *param)
220 mtd->flags |= MTD_POWERUP_LOCK; 220 mtd->flags |= MTD_POWERUP_LOCK;
221} 221}
222 222
223static void fixup_s29gl064n_sectors(struct mtd_info *mtd, void *param)
224{
225 struct map_info *map = mtd->priv;
226 struct cfi_private *cfi = map->fldrv_priv;
227
228 if ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0x003f) {
229 cfi->cfiq->EraseRegionInfo[0] |= 0x0040;
230 pr_warning("%s: Bad S29GL064N CFI data, adjust from 64 to 128 sectors\n", mtd->name);
231 }
232}
233
234static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param)
235{
236 struct map_info *map = mtd->priv;
237 struct cfi_private *cfi = map->fldrv_priv;
238
239 if ((cfi->cfiq->EraseRegionInfo[1] & 0xffff) == 0x007e) {
240 cfi->cfiq->EraseRegionInfo[1] &= ~0x0040;
241 pr_warning("%s: Bad S29GL032N CFI data, adjust from 127 to 63 sectors\n", mtd->name);
242 }
243}
244
223static struct cfi_fixup cfi_fixup_table[] = { 245static struct cfi_fixup cfi_fixup_table[] = {
224 { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, 246 { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
225#ifdef AMD_BOOTLOC_BUG 247#ifdef AMD_BOOTLOC_BUG
@@ -231,6 +253,10 @@ static struct cfi_fixup cfi_fixup_table[] = {
231 { CFI_MFR_AMD, 0x0056, fixup_use_secsi, NULL, }, 253 { CFI_MFR_AMD, 0x0056, fixup_use_secsi, NULL, },
232 { CFI_MFR_AMD, 0x005C, fixup_use_secsi, NULL, }, 254 { CFI_MFR_AMD, 0x005C, fixup_use_secsi, NULL, },
233 { CFI_MFR_AMD, 0x005F, fixup_use_secsi, NULL, }, 255 { CFI_MFR_AMD, 0x005F, fixup_use_secsi, NULL, },
256 { CFI_MFR_AMD, 0x0c01, fixup_s29gl064n_sectors, NULL, },
257 { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, },
258 { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, },
259 { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, },
234#if !FORCE_WORD_WRITE 260#if !FORCE_WORD_WRITE
235 { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, 261 { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, },
236#endif 262#endif