mtd/html/tech nand.html,1.18,1.19

gleixner at infradead.org gleixner at infradead.org
Tue Jun 1 17:11:00 EDT 2004


Update of /home/cvs/mtd/html/tech
In directory phoenix.infradead.org:/tmp/cvs-serv18692

Modified Files:
	nand.html 
Log Message:
move api stuff to docbook

Index: nand.html
===================================================================
RCS file: /home/cvs/mtd/html/tech/nand.html,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- nand.html	6 May 2004 09:09:27 -0000	1.18
+++ nand.html	1 Jun 2004 21:10:57 -0000	1.19
@@ -49,8 +49,8 @@
 		
 <p>As NAND Flash is cheaper than NOR Flash and has a very slim interface it was 
 selected as the optimum solution for large nonvolatile storage applications such 
-as solid state file storage, digital audio/voice recorder,
- digital still camera and portable applications requiring non-volatility.</p>
+as solid state file storage, digital audio/voice recorder, 
+digital still camera and portable applications requiring non-volatility.</p>
 
 <hr>
 		
@@ -69,7 +69,7 @@
 <hr>
 		
 <h2>NAND technical view</h2>
-<p>The memory is arranged as a array of pages. A page consists of 256 / 512 Byte data 
+<p>The memory is arranged as an array of pages. A page consists of 256 / 512 Byte data 
 and 8 / 16 Byte spare (out of band) area. Newer chips have 2048 Bytes data and and 64 
 Bytes spare area sizes. The spare area is used to store ECC (error correction code), 
 bad block information and filesystem dependend data.
@@ -79,7 +79,7 @@
 given by writing with the Address Latch Enable pin high.</p>
 
 <p>There are only a few lines neccecary to access NAND Flashmemory.</p>
-<p>16 bit buswidth chips are supported.</p>
+<p>16 bit buswidth chips are supported.</p>
 <table border="1" cellpadding="2" cellspacing="0">
 <tr><td><b>Pin(s) </b></td><td><b>Function </b></td></tr>
 <tr><td>I/O 0-7(15)</td><td>Data Inputs/Outputs </td></tr>
@@ -91,16 +91,16 @@
 <tr><td>/WP </td><td>Write Protect </td></tr>
 <tr><td>/SE </td><td>Spare area Enable </td></tr>
 <tr><td>R/B </td><td>Ready / Busy Output </td></tr>
-</table>
+</table>
 <p>As it is neccecary to use the spare area, the /SE (Spare area Enable) pin should 
 be tied to GND. /CE, CLE and ALE should be GPIO pins or latched signals. It's possible 
 to use address lines for ALE and CLE, but you have to take care about the timing 
-restrictions of the chip ! </p>
+restrictions of the chip ! </p>
 <p>/RE and /WE can be tied to the corresponding lines of the CPU. Make sure, that 
 they are logicaly combined with the corresponding chipselect. You can also use two 
 different chipselects for /RE and /WE, but be aware of data hold time constraints 
 of your NAND chip. Data hold time after rising edge of /WE is different to data hold 
-timeafter rising edge of chipselect lines!</p>
+time after rising edge of chipselect lines!</p>
 <p>I/O 0-7(15) are connected to the databus D0-D7(D15). The /WP pin can be used for write 
 protection or connected to VCC to enable writes unconditionally. As NAND flash uses 
 a command driven programming and erasing, an  accidential write or erase is not 
@@ -134,166 +134,13 @@
 <p> There is currently no support for the wide spread SmartMedia DOS-FAT filesystem, 
  mainly because it's not a reliable filesystem for industrial usage. It's ok for 
  multimedia applications. The hardware support layer is designed to support an 
- implementation of SmartMedia DOS-FAT, but nobody has made an attempt to implement 
- it really. There are a couple of SmartMedia Card adaptors for USB, PCMCIA, FireWire 
+ implementation of SmartMedia DOS-FAT. There are some efforts to implement it, but it's
+ in an early stage. There are a couple of SmartMedia Card adaptors for USB, PCMCIA, FireWire 
  ... with Linux drivers available, which support the SmartMedia DOS-FAT. </p>
 <p>JFFS2 and YAFFS include bad block management, wear leveling, error correction and provide
 reliable filesystems for industrial use on top of NAND Flash.</p>
 
 <hr>
-<h2>Technical information for filesystem implementation</h2>
-<h3>Multiple filesystems on different partitions</h3>
-You can mount different filesystems on different partitions of the same chip. 
-<h3>OOB usage</h3>
-<p>As the OOB usage of the filesystems differs, the OOB usage can be 
-selected on runtime from the filesystem driver. The parameter is given to the functions
-mtd->read_ecc and mtd->write_ecc. This parameter specifies the location
-of the ECC-data inside the oob area. The parameter is a structure named nand_oobinfo. <br>
-struct nand_oobconfig {<br>
-	int 	useecc;<br>
-	int	eccbytes<br>
-	int	eccpos[24];<br>
-	int	oobfree[8][2];<br>
-}<br>
-With this structure the usage of ecc and the position of ecc-data in the oob area are given.
-The content of useecc selects the ecc operation mode:
-<ul>
-<li>MTD_NANDECC_OFF<br>Do not use ECC</li>
-<li>MTD_NANDECC_PLACE<br>Use ECC and place the ECC bytes at the position given by the eccpos 
-array</li>
-<li>MTD_NANDECC_AUTOPLACE<br>Use ECC and place the ECC bytes at the position given by the
-autoplacement defaults in the nand driver</li>
-</ul>
-</p>
-<p>All non ecc functions like mtd->read and mtd->write use an internal structure, which can be set 
-by an ioctl. This structure is preset to the autoplacement default<br>
-ioctl (fd, MEMSETOOBSEL, oobsel);, where oobsel is a pointer to a user supplied structure of type
-oobconfig. The contents of this structure must match the criteria of the filesystem, which will
-be used. See an example in utils/nandwrite.c.
-</p>
-<h3>OOB autoplacement layout</h3>
-<h4>Nand chips with 256 byte pagesize and 8 byte OOB size</h4>
-<table border="1" cellpadding="2" cellspacing="0">
-<tr><td><b>Offset</b></td><td><b>Content</b></td><td><b>Comment</b></td></tr>
-<tr><td>0x00</td><td>ECC byte 0</td><td>Error correction code byte 0</td></tr>
-<tr><td>0x01</td><td>ECC byte 1</td><td>Error correction code byte 1</td></tr>
-<tr><td>0x02</td><td>ECC byte 2</td><td>Error correction code byte 2</td></tr>
-<tr><td>0x03</td><td>Autoplace 0</td><td></td></tr>
-<tr><td>0x04</td><td>Autoplace 1</td><td></td></tr>
-<tr><td>0x05</td><td>Bad block marker</td><td>If any bit in this byte is zero, 
-then this block is bad. This applies only to the first page in a block. 
-In the remaining pages this byte is reserved</td></tr>
-<tr><td>0x06</td><td>Autoplace 2</td><td></td></tr>
-<tr><td>0x07</td><td>Autoplace 3</td><td></td></tr>
-</table>
-		
-<h4>Nand chips with 512 byte pagesize and 16 byte OOB size</h4>
-		
-<table border="1" cellpadding="2" cellspacing="0">
-<tr><td><b>Offset</b></td><td><b>Content</b></td><td><b>Comment</b></td></tr>
-<tr><td>0x00</td><td>ECC byte 0</td><td>Error correction code byte 0 of the 
-lower 256 Byte data in this page</td></tr>
-<tr><td>0x01</td><td>ECC byte 1</td><td>Error correction code byte 1 of the 
-lower 256 Bytes of data in this page</td></tr>
-<tr><td>0x02</td><td>ECC byte 2</td><td>Error correction code byte 2 of the 
-lower 256 Bytes of data in this page</td></tr>
-<tr><td>0x03</td><td>ECC byte 3</td><td>Error correction code byte 0 of the 
-upper 256 Bytes of data in this page</td></tr>
-<tr><td>0x04</td><td>reserved</td><td>reserved</td></tr>
-<tr><td>0x05</td><td>Bad block marker</td><td>If any bit in this byte is zero, 
-then this block is bad. This applies only to the first page in a block. In the 
-remaining pages this byte is reserved</td></tr>
-<tr><td>0x06</td><td>ECC byte 4</td><td>Error correction code byte 1 of the 
-upper 256 Bytes of data in this page</td></tr>
-<tr><td>0x07</td><td>ECC byte 5</td><td>Error correction code byte 2 of the 
-upper 256 Bytes of data in this page</td></tr>
-<tr><td>0x08 - 0x0F</td><td>Autoplace 0 - 7</td><td></td></tr>
-</table>
-
-<h4>Nand chips with 2048 byte pagesize and 64 byte OOB size</h4>
-		
-<table border="1" cellpadding="2" cellspacing="0">
-<tr><td><b>Offset</b></td><td><b>Content</b></td><td><b>Comment</b></td></tr>
-<tr><td>0x00</td><td>Bad block marker</td><td>If any bit in this byte is zero, 
-then this block is bad. This applies only to the first page in a block. In the 
-remaining pages this byte is reserved</td></tr>
-<tr><td>0x01</td><td>Reserved</td><td>Reserved</td></tr>
-<tr><td>0x02-0x27</td><td>Autoplace 0 - 37</td><td></td></tr>
-<tr><td>0x28</td><td>ECC byte 0</td><td>Error correction code byte 0 of the 
-first 256 Byte data in this page</td></tr>
-<tr><td>0x29</td><td>ECC byte 1</td><td>Error correction code byte 1 of the first 256 Bytes of data in this page</td></tr>
-<tr><td>0x2A</td><td>ECC byte 2</td><td>Error correction code byte 2 of the 
-first 256 Bytes data in this page</td></tr>
-<tr><td>0x2B</td><td>ECC byte 3</td><td>Error correction code byte 0 of the 
-second 256 Bytes of data in this page</td></tr>
-<tr><td>0x2C</td><td>ECC byte 4</td><td>Error correction code byte 1 of the 
-second 256 Bytes of data in this page</td></tr>
-<tr><td>0x2D</td><td>ECC byte 5</td><td>Error correction code byte 2 of the 
-second 256 Bytes of data in this page</td></tr>
-<tr><td>0x2E</td><td>ECC byte 6</td><td>Error correction code byte 0 of the 
-third 256 Bytes of data in this page</td></tr>
-<tr><td>0x2F</td><td>ECC byte 7</td><td>Error correction code byte 1 of the 
-third 256 Bytes of data in this page</td></tr>
-<tr><td>0x30</td><td>ECC byte 8</td><td>Error correction code byte 2 of the 
-third 256 Bytes of data in this page</td></tr>
-<tr><td>0x31</td><td>ECC byte 9</td><td>Error correction code byte 0 of the 
-fourth 256 Bytes of data in this page</td></tr>
-<tr><td>0x32</td><td>ECC byte 10</td><td>Error correction code byte 1 of the 
-fourth 256 Bytes of data in this page</td></tr>
-<tr><td>0x33</td><td>ECC byte 11</td><td>Error correction code byte 2 of the 
-fourth 256 Bytes of data in this page</td></tr>
-<tr><td>0x34</td><td>ECC byte 12</td><td>Error correction code byte 0 of the 
-fifth 256 Bytes of data in this page</td></tr>
-<tr><td>0x35</td><td>ECC byte 13</td><td>Error correction code byte 1 of the 
-fifth 256 Bytes of data in this page</td></tr>
-<tr><td>0x36</td><td>ECC byte 14</td><td>Error correction code byte 2 of the 
-fifth 256 Bytes of data in this page</td></tr>
-<tr><td>0x37</td><td>ECC byte 15</td><td>Error correction code byte 0 of the 
-sixt 256 Bytes of data in this page</td></tr>
-<tr><td>0x38</td><td>ECC byte 16</td><td>Error correction code byte 1 of the 
-sixt 256 Bytes of data in this page</td></tr>
-<tr><td>0x39</td><td>ECC byte 17</td><td>Error correction code byte 2 of the 
-sixt 256 Bytes of data in this page</td></tr>
-<tr><td>0x3A</td><td>ECC byte 18</td><td>Error correction code byte 0 of the 
-seventh 256 Bytes of data in this page</td></tr>
-<tr><td>0x3B</td><td>ECC byte 19</td><td>Error correction code byte 1 of the 
-seventh 256 Bytes of data in this page</td></tr>
-<tr><td>0x3C</td><td>ECC byte 20</td><td>Error correction code byte 2 of the 
-seventh 256 Bytes of data in this page</td></tr>
-<tr><td>0x3D</td><td>ECC byte 21</td><td>Error correction code byte 0 of the 
-eigth 256 Bytes of data in this page</td></tr>
-<tr><td>0x3E</td><td>ECC byte 22</td><td>Error correction code byte 1 of the 
-eigth 256 Bytes of data in this page</td></tr>
-<tr><td>0x3F</td><td>ECC byte 23</td><td>Error correction code byte 2 of the 
-eigth 256 Bytes of data in this page</td></tr>
-</table>
-
-<h3>OOB access</h3>
-<h4>Read back OOB data together with main area </h4>
-<p>If the fs driver needs to read the oobdata together with the raw data, then the fs-driver has to
-supply a big enough buffer.  <br>
-size = 12 bytes * number of pages to read (256B pagesize) or 24 bytes* number of pages to read (512B pagesize) <br>
-The buffer contains 8/16 byte oobdata and 4/8 byte returncode from correct_ecc <br>
-oobbuf [0-15] oob-data 1st read page  <br>
-oobbuf [16-19] return code from correct_ecc byte 0-255 <br>
-oobbuf [20-23] return code from correct_ecc byte 256-511 <br>
-oobbuf [24-39] oob-data 2nd read page <br>
-oobbuf [40-31] return code from correct_ecc byte 0-255 <br>
-..... <br>
-The returnvalue of read_ecc is -EIO, if any correct_ecc returned -1. But
-retlen is equal to the requested length, so fs-driver can decide what to do. </p>
-       
-<h4>Write OOB data together with main area </h4>
-<p>Oob data can be given from filesystem to program them in one go together
-with the raw data. ECC codes are filled in at the place selected by oobsel.
-This supports multipage programming.  <br>
-oobbuf[0-15] 1st page to write <br>
-oobbuf[16-31] 2nd page to write <br>
-..... <br>
-ECC is filled in at the appropriate place selected by the above mentioned constants.
-</p>       
-  
-<hr>
 <h2>JFFS2 specific information </h2>
 <h3>JFFS2 Out of Band usage</h3>
 <p>JFFS2 uses the default autoplacement scheme. The only JFFS2 specific usage of the oob
@@ -410,159 +257,11 @@
 the hardware driver. They provide mainly the hardware access informations and
 functions for the generic NAND driver. For YAFFS applies the same.</p>
 
-<h3>Hardware driver</h3>
-<p>To implement it on your hardware, you will have to write a new hardware driver. 
-Copy one of the existing hardware drivers and modify it to fit your hardware. 
-These basic functions have to be modified:
-<ol>
-<li>Hardware specific control function</li>
-<li>Device ready function</li>
-<li>Init function</li>
-</ol>
-To provide enough flexibilty for all kind of devices, there can be supplied additional
-functions optionally. Almost everything can be overridden.
-<ol>
-<li>Hardware specific command function</li>
-<li>Hardware specific wait function</li>
-<li>Hardware ECC functions</li>
-<li>Hardware specific chip select function, which supports chiparrays</li>
-<li>Hardware specific read, write and verify functions</li>
-<li>Hardware specific bad block management</li>
-</ol></p>
-
-<h4>Hardware specific control function</h4>
-<p>This function sets and resets the control pins CLE, ALE and CE of the NAND device 
-depending on the function argument. The argument constants are defined in nand.h and 
-explained in the example function below.</p> 
-<p>void yourboard_hwcontrol(int cmd)<br>
-{<br>
-switch(cmd){<br>
-case NAND_CTL_SETCLE: <i>Hardware specific code to set CLE line to 1;</i> break;<br>
-case NAND_CTL_CLRCLE: <i>Hardware specific code to set CLE line to 0;</i> break;<br>
-case NAND_CTL_SETALE: <i>Hardware specific code to set ALE line to 1;</i> break;<br>
-case NAND_CTL_CLRALE: <i>Hardware specific code to set ALE line to 0;</i> break;<br>
-case NAND_CTL_SETNCE: <i>Hardware specific code to set CE line to 0;</i> break;<br>
-case NAND_CTL_CLRNCE: <i>Hardware specific code to set CE line to 1;</i> break;<br>
-}<br>
-}</p>
-
-<h4>Device ready function</h4>
-<p>If your hardware interface has the ready busy pin of the NAND chip connected to a
-GPIO or other accesible I/O pin, this function is used to read back the state of the
-pin. The function has no arguments and should return 0, if the device is busy (R/B pin 
-is low) and 1, if the device is ready (R/B pin is high).
-If your hardware interface does not give access to the ready busy pin, you can delete this
-function and set the function pointer this->dev_ready during init to NULL.</p>
-<p>int yourboard_device_ready(void)<br>
-{<br>
-return <i>The state of the ready/busy pin of the chip;</i><br>
-}</p>
-
-<h4>Init function</h4>
-This function is called, when the driver is initialized either on kernel boot or when you load
-your driver as a module. The function remaps the I/O area, through which your NAND chip can
-be accessed, allocates all neccecary memory chunks for the device structure and data cache.
-The structure of the device has to be <b>zeroed out first</b> and then filled with the neccecary 
-information about your device. See example code for the most important members of the
-device structure you have to set.</p>
-
-<p><b>int __init yourboard_init (void)</b><br>
-{<br>
-SNIP<br>
-/* Allocate memory for MTD device structure and private data */<br>
-yourboard_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),GFP_KERNEL);<br>
-SNIP<br>
-/* map physical adress */<br>
-yourboard_fio_base=(unsigned long)ioremap(yourboard_fio_pbase,SZ_1K);<br>
-SNIP<br>
-/* Set address of NAND IO lines */<br>
-this->IO_ADDR_R = yourboard_fio_base; <i>The address to read from the chip </i><br>
-this->IO_ADDR_W = yourboard_fio_base; <i>The address to write to the chip </i><br>
-this->hwcontrol = yourboard_hwcontrol;<i>Your function for accessing the controllines</i><br>
-this->dev_ready = yourboard_device_ready; <i>Your function for accessing the ready/busy 
-line or NULL, if you don't have one</i><br>
-this->chip_delay = 20;<i>The delay time (us), after writing a command to the chip, 
-according to datasheet (tR)</i><br>
-this-&gt;eccmode = NAND_ECC_XXX; <i>Set the correct ECC generator mode for your board. This
-defaults to NAND_ECC_SOFT. Notes about hardware ECC can be found below.<br>
-SNIP<br>
-}</p>
-
-<h4>Hardware specific command function</h4>
-
-<p>Some new CPU's like Samsungs ARM based S3SC2410 provide a hardware based NAND interface. 
-For them and ugly designed hardware interfaces it may be neccecary to have a customized 
-command write function. You can supply  such a function by setting <br>
-this-&gt;cmdfunc = yourboard_cmdfunc;<br>
-This must be done in yourboard_init before calling nand_scan.</p>
-<p>The function is defined as<br>
-void yourboard_cmdfunc (struct mtd_info *mtd, unsigned command, int column, int page_addr);</p>
-
-<h4>Hardware specific wait function</h4>
-<p>If you have connected the ready/busy pin to an interrupt line, you could supply a own
-interrupt driven waitfunction for erase and program wait for ready. In this case set</p>
-this-&gt;waitfunc = yourboard_waitfunction;<br>
-This must be done in yourboard_init before calling nand_scan.</p>
-<p>The function is defined as<br>
-int yourboard_waitfunction (struct mtd_info *mtd, struct nand_chip *this, int state);</br>
-Please take care of the functionality, which is in standard nand driver wait 
-function (nand_wait).</p>
-
-
-<h4>Hardware based ECC</h4>
-<p>If your hardware supplies a hardware based ECC&nbsp;generator, then fill 
-out the following. If not, skip this topic.</p>
-<p>this-&gt;eccmode =&nbsp;NAND_ECC_HW3_256; <br>
-or <br>
-this-&gt;eccmode = NAND_ECC_HW3_512;<br>
-or <br>
-this-&gt;eccmode = NAND_ECC_HW6_512;<br>
-</p>
-<p>NAND_ECC_HW3_256 is a hardware based ECC generator, which generates 3 byte ECC&nbsp;code 
-for 256 byte of data. Such a generator can be found on DOC devices and on passive SmartMedia 
-adaptors.<br>
-NAND_ECC_HW3_512 is a hardware based ECC&nbsp;generator, which generates 3 byte ECC&nbsp;code 
-for 512 byte of data. Such a generator can be found e.g. on Samsungs ARM based S3SC2410 CPU.<br>
-NAND_ECC_HW6_512 is a hardware based ECC&nbsp;generator, which generates 6 byte ECC&nbsp;code 
-for 512 byte of data.</p>
-
-<p>You have also to provide following functions:</p>
-<h5>Enable hardware ECC generator</h5>
-<p>void yourboard_enable_hwecc (int mode);</p>
-<p>Your function to enable (reset) the hardware ECC generator. This function is called from 
-the generic nand driver before reading or writing data from/to the chip. The function is 
-called with NAND_ECC_READ or NAND_ECC_WRITE as argument.<br>
-Set the function pointer in init to <br>
-this-&gt;enable_hwecc =&nbsp;yourboard_enable_hwecc;</p>
-
-<h5>Enable hardware ECC generator</h5>
-<p>void yourboard_readecc(const u_char *dat, u_char *ecc_code);</p>
-<p>Your function to read back the ECC
- bytes from your hardware ECC&nbsp;generator. Fill the data into the ecc_code array, which is 
- given as argument. Ignore the first argument of this function, which is neccecary for software 
- ecc only. Set the function pointer in init to<br>
- this-&gt;calculate_ecc =&nbsp;yourboard_readecc;&nbsp; </p>
- 
-<h5>Error detection and data correction function</h5>
-<p>int xxxx_correct_data(u_char *dat, u_char *read_ecc, u_char *calc_ecc);</p>
-<p>A function which implements  error detection and data correction corresponding 
-to your hardware ECC&nbsp;algorithm. This function should be incorporated into nand_ecc.c 
-with an appropriate function name, to make it public  available for similar hardware drivers. 
-Maybe the function you need is already there. If you  implement a new one, please contact NAND 
-driver maintainer to include it in the public source tree.  Please consult current implementations 
-in nand_ecc.c to provide a compatible solution. Set the  function pointer in init to<br>
-this-&gt;correct_data =&nbsp;xxxx_correct_data;</p>
-
-<p><b>All the function pointers must be set in yourboard_init before calling nand_scan.</b></p>
-
-<h4>Hardware specific chip select function for chip arrays</h4>
-<p>The driver supports chip arrays, which share the I/O lines and
-the controllines. There is no support for arrays which extend the
-buswidth.
-</p>
-<p>The hw specific chip select function is called with the chipnr (0 - n-1) or
-with -1. -1 indicates that the chips must be deselected. 
+<h3>API Documentation</h3>
+<p>A complete API documentation is available as DocBook template in the
+Documentation/DocBook directory of the MTD source tree. 
 </p>
+<p>Read the API documentation <a href="mtdnand/index.html">online</a>
 
 <h3>Supported chips</h3>
 <p>Most NAND chips actually available should be supported by the current code. 





More information about the linux-mtd-cvs mailing list