summaryrefslogtreecommitdiff
path: root/drivers/mtd
diff options
context:
space:
mode:
authorHelmut Raiger <helmut.raiger@hale.at>2011-07-06 19:04:41 +0200
committerScott Wood <scottwood@freescale.com>2011-10-03 18:35:12 -0500
commitb4b1e769b8f6e80219da576d45a10c9e0ca5446b (patch)
treed18583a288952707e8e1f613fabed66489b5b606 /drivers/mtd
parent780f30b642177793a984cf0a3c428994a0564f88 (diff)
mxc_nand: fix a problem writing more than 32MB
When writing 0x4000 to the unlockend_blkaddr register, large writes to a 2k page NAND sometimes fail. The current kernel driver writes 0xFFFF to this register for V2 of the nand controller. However on an i.MX31 this also fixes writes larger than 32MB. The datasheet is very unspecific, but (0x4000=16384)*2000 roughly fits the limits we're encountering with NAND writes. This problem might be NAND chip specific. Signed-off-by: Helmut Raiger <helmut.raiger@hale.at> Signed-off-by: Scott Wood <scottwood@freescale.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/mxc_nand.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 78e07cc7f7b..35e89a0f4d6 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -1371,7 +1371,18 @@ int board_nand_init(struct nand_chip *this)
/* Blocks to be unlocked */
writew(0x0, &host->regs->nfc_unlockstart_blkaddr);
- writew(0x4000, &host->regs->nfc_unlockend_blkaddr);
+ /* Originally (Freescale LTIB 2.6.21) 0x4000 was written to the
+ * unlockend_blkaddr, but the magic 0x4000 does not always work
+ * when writing more than some 32 megabytes (on 2k page nands)
+ * However 0xFFFF doesn't seem to have this kind
+ * of limitation (tried it back and forth several times).
+ * The linux kernel driver sets this to 0xFFFF for the v2 controller
+ * only, but probably this was not tested there for v1.
+ * The very same limitation seems to apply to this kernel driver.
+ * This might be NAND chip specific and the i.MX31 datasheet is
+ * extremely vague about the semantics of this register.
+ */
+ writew(0xFFFF, &host->regs->nfc_unlockend_blkaddr);
/* Unlock Block Command for given address range */
writew(0x4, &host->regs->nfc_wrprot);