aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/docg4.c
diff options
context:
space:
mode:
authorMike Dunn <mikedunn@newsguy.com>2012-12-07 15:07:21 -0500
committerArtem Bityutskiy <artem.bityutskiy@linux.intel.com>2012-12-12 10:03:21 -0500
commit5a90d41b693bda1318807a49d38ef1444f61dfdd (patch)
tree0561ee5b06aa18685036ab16238ff5b132fb1827 /drivers/mtd/nand/docg4.c
parent740bb0c4b0bbeb8970d62157685f6d4a261036a0 (diff)
mtd: nand/docg4: add support for writing in reliable mode
The controller on the docg4 has a "reliable" mode, where consecutive 2k pages are used in parallel. The initial program loader (IPL) on my Treo 680 expects the secondary program loader (SPL) to be written in this mode. This patch adds support for writing data in reliable mode, by way of a module parameter. Support for reading in this mode (as the IPL does) is not supported yet, but alternate (even-numbered) 2k pages written in reliable mode can be read normally (odd-numbered pages will contain junk and generate ecc errors). Signed-off-by: Mike Dunn <mikedunn@newsguy.com> Acked-by: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Diffstat (limited to 'drivers/mtd/nand/docg4.c')
-rw-r--r--drivers/mtd/nand/docg4.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
index 799da5d1c857..54b1e5e359b8 100644
--- a/drivers/mtd/nand/docg4.c
+++ b/drivers/mtd/nand/docg4.c
@@ -46,6 +46,25 @@
46#include <linux/bitrev.h> 46#include <linux/bitrev.h>
47 47
48/* 48/*
49 * In "reliable mode" consecutive 2k pages are used in parallel (in some
50 * fashion) to store the same data. The data can be read back from the
51 * even-numbered pages in the normal manner; odd-numbered pages will appear to
52 * contain junk. Systems that boot from the docg4 typically write the secondary
53 * program loader (SPL) code in this mode. The SPL is loaded by the initial
54 * program loader (IPL, stored in the docg4's 2k NOR-like region that is mapped
55 * to the reset vector address). This module parameter enables you to use this
56 * driver to write the SPL. When in this mode, no more than 2k of data can be
57 * written at a time, because the addresses do not increment in the normal
58 * manner, and the starting offset must be within an even-numbered 2k region;
59 * i.e., invalid starting offsets are 0x800, 0xa00, 0xc00, 0xe00, 0x1800,
60 * 0x1a00, ... Reliable mode is a special case and should not be used unless
61 * you know what you're doing.
62 */
63static bool reliable_mode;
64module_param(reliable_mode, bool, 0);
65MODULE_PARM_DESC(reliable_mode, "pages are programmed in reliable mode");
66
67/*
49 * You'll want to ignore badblocks if you're reading a partition that contains 68 * You'll want to ignore badblocks if you're reading a partition that contains
50 * data written by the TrueFFS library (i.e., by PalmOS, Windows, etc), since 69 * data written by the TrueFFS library (i.e., by PalmOS, Windows, etc), since
51 * it does not use mtd nand's method for marking bad blocks (using oob area). 70 * it does not use mtd nand's method for marking bad blocks (using oob area).
@@ -113,6 +132,7 @@ struct docg4_priv {
113#define DOCG4_SEQ_PAGEWRITE 0x16 132#define DOCG4_SEQ_PAGEWRITE 0x16
114#define DOCG4_SEQ_PAGEPROG 0x1e 133#define DOCG4_SEQ_PAGEPROG 0x1e
115#define DOCG4_SEQ_BLOCKERASE 0x24 134#define DOCG4_SEQ_BLOCKERASE 0x24
135#define DOCG4_SEQ_SETMODE 0x45
116 136
117/* DOC_FLASHCOMMAND register commands */ 137/* DOC_FLASHCOMMAND register commands */
118#define DOCG4_CMD_PAGE_READ 0x00 138#define DOCG4_CMD_PAGE_READ 0x00
@@ -122,6 +142,8 @@ struct docg4_priv {
122#define DOC_CMD_PROG_BLOCK_ADDR 0x60 142#define DOC_CMD_PROG_BLOCK_ADDR 0x60
123#define DOCG4_CMD_PAGEWRITE 0x80 143#define DOCG4_CMD_PAGEWRITE 0x80
124#define DOC_CMD_PROG_CYCLE2 0x10 144#define DOC_CMD_PROG_CYCLE2 0x10
145#define DOCG4_CMD_FAST_MODE 0xa3 /* functionality guessed */
146#define DOC_CMD_RELIABLE_MODE 0x22
125#define DOC_CMD_RESET 0xff 147#define DOC_CMD_RESET 0xff
126 148
127/* DOC_POWERMODE register bits */ 149/* DOC_POWERMODE register bits */
@@ -611,6 +633,14 @@ static void write_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr)
611 dev_dbg(doc->dev, 633 dev_dbg(doc->dev,
612 "docg4: %s: g4 addr: %x\n", __func__, docg4_addr); 634 "docg4: %s: g4 addr: %x\n", __func__, docg4_addr);
613 sequence_reset(mtd); 635 sequence_reset(mtd);
636
637 if (unlikely(reliable_mode)) {
638 writew(DOCG4_SEQ_SETMODE, docptr + DOC_FLASHSEQUENCE);
639 writew(DOCG4_CMD_FAST_MODE, docptr + DOC_FLASHCOMMAND);
640 writew(DOC_CMD_RELIABLE_MODE, docptr + DOC_FLASHCOMMAND);
641 write_nop(docptr);
642 }
643
614 writew(DOCG4_SEQ_PAGEWRITE, docptr + DOC_FLASHSEQUENCE); 644 writew(DOCG4_SEQ_PAGEWRITE, docptr + DOC_FLASHSEQUENCE);
615 writew(DOCG4_CMD_PAGEWRITE, docptr + DOC_FLASHCOMMAND); 645 writew(DOCG4_CMD_PAGEWRITE, docptr + DOC_FLASHCOMMAND);
616 write_nop(docptr); 646 write_nop(docptr);
@@ -691,6 +721,15 @@ static void docg4_command(struct mtd_info *mtd, unsigned command, int column,
691 break; 721 break;
692 722
693 case NAND_CMD_SEQIN: 723 case NAND_CMD_SEQIN:
724 if (unlikely(reliable_mode)) {
725 uint16_t g4_page = g4_addr >> 16;
726
727 /* writes to odd-numbered 2k pages are invalid */
728 if (g4_page & 0x01)
729 dev_warn(doc->dev,
730 "invalid reliable mode address\n");
731 }
732
694 write_page_prologue(mtd, g4_addr); 733 write_page_prologue(mtd, g4_addr);
695 734
696 /* hack for deferred write of oob bytes */ 735 /* hack for deferred write of oob bytes */