aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 */