mtd/drivers/mtd/devices doc2001plus.c,1.5,1.6
David Woodhouse
dwmw2 at infradead.org
Thu Jul 3 11:10:13 EDT 2003
Update of /home/cvs/mtd/drivers/mtd/devices
In directory phoenix.infradead.org:/tmp/cvs-serv4528/devices
Modified Files:
doc2001plus.c
Log Message:
Fix DiskOnChip Millennium Plus 16
Index: doc2001plus.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/devices/doc2001plus.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- doc2001plus.c 11 Jun 2003 09:45:19 -0000 1.5
+++ doc2001plus.c 3 Jul 2003 15:10:10 -0000 1.6
@@ -183,24 +183,35 @@
* | Data 0 | ECC 0 |Flags0 |Flags1 | Data 1 |ECC 1 | OOB 1 + 2 |
* +-----------+-------+-------+-------+--------------+---------+-----------+
*/
+/* FIXME: This lives in INFTL not here. Other users of flash devices
+ may not want it */
static unsigned int DoC_GetDataOffset(struct mtd_info *mtd, loff_t *from)
{
- unsigned int ofs = *from & 0x3ff;
- unsigned int cmd;
+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
- if (ofs < 512) {
- cmd = NAND_CMD_READ0;
- ofs &= 0x1ff;
- } else if (ofs < 1014) {
- cmd = NAND_CMD_READ1;
- ofs = (ofs & 0x1ff) + 10;
+ if (this->interleave) {
+ unsigned int ofs = *from & 0x3ff;
+ unsigned int cmd;
+
+ if (ofs < 512) {
+ cmd = NAND_CMD_READ0;
+ ofs &= 0x1ff;
+ } else if (ofs < 1014) {
+ cmd = NAND_CMD_READ1;
+ ofs = (ofs & 0x1ff) + 10;
+ } else {
+ cmd = NAND_CMD_READOOB;
+ ofs = ofs - 1014;
+ }
+
+ *from = (*from & ~0x3ff) | ofs;
+ return cmd;
} else {
- cmd = NAND_CMD_READOOB;
- ofs = ofs - 1014;
+ /* No interleave */
+ if ((*from) & 0x100)
+ return NAND_CMD_READ1;
+ return NAND_CMD_READ0;
}
-
- *from = (*from & ~0x3ff) | ofs;
- return cmd;
}
static unsigned int DoC_GetECCOffset(struct mtd_info *mtd, loff_t *from)
@@ -294,10 +305,12 @@
dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
mfr = ReadDOC(docptr, Mil_CDSN_IO);
- dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */
+ if (doc->interleave)
+ dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */
id = ReadDOC(docptr, Mil_CDSN_IO);
- dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */
+ if (doc->interleave)
+ dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */
dummy = ReadDOC(docptr, Mplus_LastDataRead);
dummy = ReadDOC(docptr, Mplus_LastDataRead);
@@ -321,9 +334,6 @@
nand_manuf_ids[j].name, nand_flash_ids[i].name);
doc->mfr = mfr;
doc->id = id;
- doc->interleave = 0;
- if (doc->ChipID == DOC_ChipID_DocMilPlus32)
- doc->interleave = 1;
doc->chipshift = nand_flash_ids[i].chipshift;
doc->erasesize = nand_flash_ids[i].erasesize << doc->interleave;
break;
@@ -346,6 +356,21 @@
this->mfr = 0;
this->id = 0;
+ /* Work out the intended interleave setting */
+ this->interleave = 0;
+ if (this->ChipID == DOC_ChipID_DocMilPlus32)
+ this->interleave = 1;
+
+ /* Check the ASIC agrees */
+ if ( (this->interleave << 2) !=
+ (ReadDOC(this->virtadr, Mplus_Configuration) & 4)) {
+ u_char conf = ReadDOC(this->virtadr, Mplus_Configuration);
+ printk(KERN_NOTICE "Setting DiskOnChip Millennium Plus interleave to %s\n",
+ this->interleave?"on (16-bit)":"off (8-bit)");
+ conf ^= 4;
+ WriteDOC(this->virtadr, conf, Mplus_Configuration);
+ }
+
/* For each floor, find the number of valid chips it contains */
for (floor = 0,ret = 1; floor < MAX_FLOORS_MPLUS; floor++) {
numchips[floor] = 0;
@@ -739,7 +764,7 @@
return -EINVAL;
/* Determine position of OOB flags, before or after data */
- before = to & 0x200;
+ before = (this->interleave && (to & 0x200));
DoC_CheckASIC(docptr);
@@ -886,7 +911,10 @@
/* Figure out which region we are accessing... */
fofs = ofs;
base = ofs & 0xf;
- if (base < 6) {
+ if (!this->interleave) {
+ DoC_Command(docptr, NAND_CMD_READOOB, 0);
+ size = 16 - base;
+ } else if (base < 6) {
DoC_Command(docptr, DoC_GetECCOffset(mtd, &fofs), 0);
size = 6 - base;
} else if (base < 8) {
@@ -963,7 +991,10 @@
/* Figure out which region we are accessing... */
fofs = ofs;
base = ofs & 0x0f;
- if (base < 6) {
+ if (!this->interleave) {
+ WriteDOC(NAND_CMD_READOOB, docptr, Mplus_FlashCmd);
+ size = 16 - base;
+ } else if (base < 6) {
WriteDOC(DoC_GetECCOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
size = 6 - base;
} else if (base < 8) {
More information about the linux-mtd-cvs
mailing list