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