INFTL problems
Dave Dillow
ddillow at idleaire.com
Tue Oct 28 16:34:39 EST 2003
On Tue, 2003-10-28 at 12:32, Chris Ellec wrote:
> Hello,
>
> I have a WinSystems devel board with a DOC on it. Dinfo from MSystems
> reports a DOC 2000 at address D800 with 256 MB and an INFTL format.
>
Try this -- it's my current hack to get my 128MB recoginzed. When I get
time, I plan to work on nand/diskonchip.c, per dwmw2's suggestion.
--
Dave Dillow <ddillow at idleaire.com>
-------------- next part --------------
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1191 -> 1.1192
# drivers/mtd/devices/doc2000.c 1.6 -> 1.7
# include/linux/mtd/doc2000.h 1.5 -> 1.6
# drivers/mtd/devices/docprobe.c 1.7 -> 1.8
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/10/13 ddillow at idleaire.com 1.1192
# Add support for DoC 2000 TSOP
# --------------------------------------------
#
diff -Nru a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
--- a/drivers/mtd/devices/doc2000.c Tue Oct 28 16:32:43 2003
+++ b/drivers/mtd/devices/doc2000.c Tue Oct 28 16:32:43 2003
@@ -25,6 +25,7 @@
#include <linux/mtd/doc2000.h>
#define DOC_SUPPORT_2000
+#define DOC_SUPPORT_2000TSOP
#define DOC_SUPPORT_MILLENNIUM
#ifdef DOC_SUPPORT_2000
@@ -33,6 +34,12 @@
#define DoC_is_2000(doc) (0)
#endif
+#ifdef DOC_SUPPORT_2000TSOP
+#define DoC_is_2000TSOP(doc) (doc->ChipID == DOC_ChipID_Doc2kTSOP)
+#else
+#define DoC_is_2000TSOP(doc) (0)
+#endif
+
#ifdef DOC_SUPPORT_MILLENNIUM
#define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil)
#else
@@ -76,7 +83,7 @@
int i;
for (i = 0; i < cycles; i++) {
- if (DoC_is_Millennium(doc))
+ if (DoC_is_Millennium(doc) || DoC_is_2000TSOP(doc))
dummy = ReadDOC(doc->virtadr, NOP);
else
dummy = ReadDOC(doc->virtadr, DOCStatus);
@@ -95,6 +102,10 @@
/* Out-of-line routine to wait for chip response */
while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
+ /* issue 2 read from NOP register after reading from CDSNControl register
+ see Software Requirement 11.4 item 2. */
+ DoC_Delay(doc, 2);
+
if (time_after(jiffies, timeo)) {
DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
return -EIO;
@@ -136,18 +147,20 @@
{
unsigned long docptr = doc->virtadr;
- if (DoC_is_2000(doc))
+ if (DoC_is_2000(doc) || DoC_is_2000TSOP(doc))
xtraflags |= CDSN_CTRL_FLASH_IO;
/* Assert the CLE (Command Latch Enable) line to the flash chip */
WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl);
DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
- if (DoC_is_Millennium(doc))
+ if (DoC_is_Millennium(doc) || DoC_is_2000TSOP(doc))
WriteDOC(command, docptr, CDSNSlowIO);
/* Send the command */
WriteDOC_(command, docptr, doc->ioreg);
+ if (DoC_is_Millennium(doc) || DoC_is_2000TSOP(doc))
+ WriteDOC(command, docptr, WritePipeTerm);
/* Lower the CLE line */
WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
@@ -169,7 +182,7 @@
docptr = doc->virtadr;
- if (DoC_is_2000(doc))
+ if (DoC_is_2000(doc) || DoC_is_2000TSOP(doc))
xtraflags1 |= CDSN_CTRL_FLASH_IO;
/* Assert the ALE (Address Latch Enable) line to the flash chip */
@@ -190,7 +203,7 @@
*/
if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) {
- if (DoC_is_Millennium(doc))
+ if (DoC_is_Millennium(doc) || DoC_is_2000TSOP(doc))
WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
}
@@ -203,12 +216,15 @@
if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) {
for (i = 0; i < doc->pageadrlen; i++, ofs = ofs >> 8) {
- if (DoC_is_Millennium(doc))
+ if (DoC_is_Millennium(doc) || DoC_is_2000TSOP(doc))
WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
}
}
+ if (DoC_is_Millennium(doc) || DoC_is_2000TSOP(doc))
+ WriteDOC(ofs & 0xff, docptr, WritePipeTerm);
+
DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */
/* FIXME: The SlowIO's for millennium could be replaced by
@@ -237,7 +253,7 @@
if (len <= 0)
return;
- if (DoC_is_Millennium(doc)) {
+ if (DoC_is_Millennium(doc) || DoC_is_2000TSOP(doc)) {
/* Read the data via the internal pipeline through CDSN IO register,
see Pipelined Read Operations 11.3 */
dummy = ReadDOC(docptr, ReadPipeInit);
@@ -252,7 +268,7 @@
for (i = 0; i < len; i++)
buf[i] = ReadDOC_(docptr, doc->ioreg + (i & modulus));
- if (DoC_is_Millennium(doc)) {
+ if (DoC_is_Millennium(doc) || DoC_is_2000TSOP(doc)) {
buf[i] = ReadDOC(docptr, LastDataRead);
}
}
@@ -271,7 +287,7 @@
for (i = 0; i < len; i++)
WriteDOC_(buf[i], docptr, doc->ioreg + i);
- if (DoC_is_Millennium(doc)) {
+ if (DoC_is_Millennium(doc) || DoC_is_2000TSOP(doc)) {
WriteDOC(0x00, docptr, WritePipeTerm);
}
}
@@ -347,15 +363,27 @@
/* Read the manufacturer and device id codes from the device */
- /* CDSN Slow IO register see Software Requirement 11.4 item 5. */
- dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
- DoC_Delay(doc, 2);
- mfr = ReadDOC_(doc->virtadr, doc->ioreg);
+ if (DoC_is_Millennium(doc) || DoC_is_2000TSOP(doc)) {
+ DoC_Delay(doc, 2);
+ dummy = ReadDOC(doc->virtadr, ReadPipeInit);
+ mfr = ReadDOC(doc->virtadr, LastDataRead);
+
+ DoC_Delay(doc, 2);
+ dummy = ReadDOC(doc->virtadr, ReadPipeInit);
+ id = ReadDOC(doc->virtadr, LastDataRead);
+ } else {
+ /* CDSN Slow IO register see Software Req 11.4 item 5. */
+ dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
+ DoC_Delay(doc, 2);
+ mfr = ReadDOC_(doc->virtadr, doc->ioreg);
+
+ /* CDSN Slow IO register see Software Req 11.4 item 5. */
+ dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
+ DoC_Delay(doc, 2);
+ id = ReadDOC_(doc->virtadr, doc->ioreg);
+ }
- /* CDSN Slow IO register see Software Requirement 11.4 item 5. */
- dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
- DoC_Delay(doc, 2);
- id = ReadDOC_(doc->virtadr, doc->ioreg);
+ printk("IdentChip checking floor %d chip %d id 0x%02x mfr 0x%02x\n", floor, chip, id, mfr);
/* No response - return failure */
if (mfr == 0xff || mfr == 0)
@@ -541,6 +569,10 @@
switch (this->ChipID) {
+ case DOC_ChipID_Doc2kTSOP:
+ mtd->name = "DiskOnChip 2000 TSOP";
+ this->ioreg = DoC_Mil_CDSN_IO;
+ break;
case DOC_ChipID_Doc2k:
mtd->name = "DiskOnChip 2000";
this->ioreg = DoC_2k_CDSN_IO;
@@ -692,7 +724,7 @@
DoC_ReadBuf(this, eccbuf, 6);
/* Flush the pipeline */
- if (DoC_is_Millennium(this)) {
+ if (DoC_is_Millennium(this) || DoC_is_2000TSOP(this)) {
dummy = ReadDOC(docptr, ECCConf);
dummy = ReadDOC(docptr, ECCConf);
i = ReadDOC(docptr, ECCConf);
@@ -773,6 +805,7 @@
int len256 = 0;
struct Nand *mychip;
size_t left = len;
+ int status;
docptr = this->virtadr;
@@ -865,7 +898,7 @@
WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr,
CDSNControl);
- if (DoC_is_Millennium(this)) {
+ if (DoC_is_Millennium(this) || DoC_is_2000TSOP(this)) {
WriteDOC(0, docptr, NOP);
WriteDOC(0, docptr, NOP);
WriteDOC(0, docptr, NOP);
@@ -875,6 +908,9 @@
WriteDOC_(0, docptr, this->ioreg);
}
+ WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_FLASH_IO | CDSN_CTRL_CE, docptr,
+ CDSNControl);
+
/* Read the ECC data through the DiskOnChip ECC logic */
for (di = 0; di < 6; di++) {
eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
@@ -896,10 +932,16 @@
DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
/* There's an implicit DoC_WaitReady() in DoC_Command */
- dummy = ReadDOC(docptr, CDSNSlowIO);
- DoC_Delay(this, 2);
+ if (DoC_is_Millennium(this) || DoC_is_2000TSOP(this)) {
+ ReadDOC(docptr, ReadPipeInit);
+ status = ReadDOC(docptr, LastDataRead);
+ } else {
+ dummy = ReadDOC(docptr, CDSNSlowIO);
+ DoC_Delay(this, 2);
+ status = ReadDOC_(docptr, this->ioreg);
+ }
- if (ReadDOC_(docptr, this->ioreg) & 1) {
+ if (status & 1) {
printk(KERN_ERR "Error programming flash\n");
/* Error in programming */
*retlen = 0;
@@ -1067,6 +1109,7 @@
unsigned long docptr = this->virtadr;
struct Nand *mychip = &this->chips[ofs >> this->chipshift];
volatile int dummy;
+ int status;
// printk("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",(long)ofs, len,
// buf[0], buf[1], buf[2], buf[3], buf[8], buf[9], buf[14],buf[15]);
@@ -1115,10 +1158,16 @@
DoC_Command(this, NAND_CMD_STATUS, 0);
/* DoC_WaitReady() is implicit in DoC_Command */
- dummy = ReadDOC(docptr, CDSNSlowIO);
- DoC_Delay(this, 2);
+ if (DoC_is_Millennium(this) || DoC_is_2000TSOP(this)) {
+ ReadDOC(docptr, ReadPipeInit);
+ status = ReadDOC(docptr, LastDataRead);
+ } else {
+ dummy = ReadDOC(docptr, CDSNSlowIO);
+ DoC_Delay(this, 2);
+ status = ReadDOC_(docptr, this->ioreg);
+ }
- if (ReadDOC_(docptr, this->ioreg) & 1) {
+ if (status & 1) {
printk(KERN_ERR "Error programming oob data\n");
/* There was an error */
*retlen = 0;
@@ -1134,10 +1183,16 @@
DoC_Command(this, NAND_CMD_STATUS, 0);
/* DoC_WaitReady() is implicit in DoC_Command */
- dummy = ReadDOC(docptr, CDSNSlowIO);
- DoC_Delay(this, 2);
+ if (DoC_is_Millennium(this) || DoC_is_2000TSOP(this)) {
+ ReadDOC(docptr, ReadPipeInit);
+ status = ReadDOC(docptr, LastDataRead);
+ } else {
+ dummy = ReadDOC(docptr, CDSNSlowIO);
+ DoC_Delay(this, 2);
+ status = ReadDOC_(docptr, this->ioreg);
+ }
- if (ReadDOC_(docptr, this->ioreg) & 1) {
+ if (status & 1) {
printk(KERN_ERR "Error programming oob data\n");
/* There was an error */
*retlen = 0;
@@ -1170,6 +1225,7 @@
volatile int dummy;
unsigned long docptr;
struct Nand *mychip;
+ int status;
down(&this->lock);
@@ -1201,10 +1257,16 @@
DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
- dummy = ReadDOC(docptr, CDSNSlowIO);
- DoC_Delay(this, 2);
-
- if (ReadDOC_(docptr, this->ioreg) & 1) {
+ if (DoC_is_Millennium(this) || DoC_is_2000TSOP(this)) {
+ ReadDOC(docptr, ReadPipeInit);
+ status = ReadDOC(docptr, LastDataRead);
+ } else {
+ dummy = ReadDOC(docptr, CDSNSlowIO);
+ DoC_Delay(this, 2);
+ status = ReadDOC_(docptr, this->ioreg);
+ }
+
+ if (status & 1) {
printk(KERN_ERR "Error erasing at 0x%x\n", ofs);
/* There was an error */
instr->state = MTD_ERASE_FAILED;
diff -Nru a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c
--- a/drivers/mtd/devices/docprobe.c Tue Oct 28 16:32:43 2003
+++ b/drivers/mtd/devices/docprobe.c Tue Oct 28 16:32:43 2003
@@ -97,10 +97,11 @@
static inline int __init doccheck(unsigned long potential, unsigned long physadr)
{
unsigned long window=potential;
- unsigned char tmp, tmpb, tmpc, ChipID;
+ unsigned char tmp, tmpb, tmpc;
#ifndef DOC_PASSIVE_PROBE
unsigned char tmp2;
#endif
+ unsigned char ChipID;
/* Routine copied from the Linux DOC driver */
@@ -138,10 +139,16 @@
/* We need to read the ChipID register four times. For some
newer DiskOnChip 2000 units, the first three reads will
return the DiskOnChip Millennium ident. Don't ask. */
- ReadDOC(window, ChipID);
- ReadDOC(window, ChipID);
- ReadDOC(window, ChipID);
ChipID = ReadDOC(window, ChipID);
+#if 1
+ if(ChipID == DOC_ChipID_DocMil) {
+ ReadDOC(window, ChipID);
+ ReadDOC(window, ChipID);
+ ChipID = ReadDOC(window, ChipID);
+ if(ChipID != DOC_ChipID_DocMil)
+ ChipID = DOC_ChipID_Doc2kTSOP;
+ }
+#endif
switch (ChipID) {
case DOC_ChipID_Doc2k:
@@ -153,6 +160,7 @@
return ChipID;
break;
+ case DOC_ChipID_Doc2kTSOP:
case DOC_ChipID_DocMil:
/* Check the TOGGLE bit in the ECC register */
tmp = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
@@ -267,6 +275,12 @@
sprintf(namebuf, "with ChipID %2.2X", ChipID);
switch(ChipID) {
+ case DOC_ChipID_Doc2kTSOP:
+ name="2000 TSOP";
+ im_funcname = "DoC2k_init";
+ im_modname = "doc2000";
+ break;
+
case DOC_ChipID_Doc2k:
name="2000";
im_funcname = "DoC2k_init";
diff -Nru a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h
--- a/include/linux/mtd/doc2000.h Tue Oct 28 16:32:43 2003
+++ b/include/linux/mtd/doc2000.h Tue Oct 28 16:32:43 2003
@@ -114,6 +114,7 @@
#define DOC_MODE_MDWREN 0x04
#define DOC_ChipID_Doc2k 0x20
+#define DOC_ChipID_Doc2kTSOP 0x21 /* internal number for MTD */
#define DOC_ChipID_DocMil 0x30
#define DOC_ChipID_DocMilPlus32 0x40
#define DOC_ChipID_DocMilPlus16 0x41
@@ -169,7 +170,7 @@
unsigned long physadr;
unsigned long virtadr;
unsigned long totlen;
- char ChipID; /* Type of DiskOnChip */
+ unsigned char ChipID; /* Type of DiskOnChip */
int ioreg;
unsigned long mfr; /* Flash IDs - only one type of flash per device */
More information about the linux-mtd
mailing list