Comments

Given there's no public specification to this date, and in order
to capture some important details and singularities about the
controller let's document them once and for good.
Cc: linux-doc@vger.kernel.org
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
---
Documentation/mtd/nand/pxa3xx-nand.txt | 113 +++++++++++++++++++++++++++++++++
drivers/mtd/nand/pxa3xx_nand.c | 2 +
2 files changed, 115 insertions(+)
create mode 100644 Documentation/mtd/nand/pxa3xx-nand.txt

Patch

diff --git a/Documentation/mtd/nand/pxa3xx-nand.txt b/Documentation/mtd/nand/pxa3xx-nand.txt
new file mode 100644
index 0000000..00e601c--- /dev/null+++ b/Documentation/mtd/nand/pxa3xx-nand.txt@@ -0,0 +1,113 @@++About this document+===================++Some notes about Marvell's NAND controller available in PXA and Armada 370/XP+SoC (aka NFCv1 and NFCv2), with an emphasis on the latter.++NFCv2 controller background+===========================++The controller has a 2176 bytes FIFO buffer. Therefore, in order to support+larger pages, I/O operations on 4 KiB and 8 KiB pages is done with a set of+chunked transfers.++For instance, if we choose a 2048 data chunk and set "BCH" ECC (see below)+we'll have this layout in the pages:++ ------------------------------------------------------------------------------+ | 2048B data | 32B spare | 30B ECC || 2048B data | 32B spare | 30B ECC | ... |+ ------------------------------------------------------------------------------++The driver reads the data and spare portions independently and builds an internal+buffer with this layout (in the 4 KiB page case):++ ------------------------------------------+ | 4096B data | 64B spare |+ ------------------------------------------++Also, for the READOOB command the driver disables the ECC and reads a 'spare + ECC'+OOB, one per chunk read.++ -------------------------------------------------------------------+ | 4096B data | 32B spare | 30B ECC | 32B spare | 30B ECC |+ -------------------------------------------------------------------++So, in order to achieve reading (for instance), we issue several READ0 commands+(with some additional controller-specific magic) and read two chunks of 2080B+(2048 data + 32 spare) each.+The driver accomodates this data to expose the NAND core a contiguous buffer+(4096 data + spare) or (4096 + spare + ECC + spare + ECC).++ECC+===++The controller has built-in hardware ECC capabilities. In addition it is+configurable between two modes: 1) Hamming, 2) BCH.++Note that the actual BCH mode: BCH-4 or BCH-8 will depend on the way+the controller is configured to transfer the data.++In the BCH mode the ECC code will be calculated for each transfered chunk+and expected to be located (when reading/programming) right after the spare+bytes as the figure above shows.++So, repeating the above scheme, a 2048B data chunk will be followed by 32B+spare, and then the ECC controller will read/write the ECC code (30B in+this case):++ ------------------------------------+ | 2048B data | 32B spare | 30B ECC |+ ------------------------------------++If the ECC mode is 'BCH' then the ECC is *always* 30 bytes long.+If the ECC mode is 'Hamming' the ECC is 6 bytes long, for each 512B block.+So in Hamming mode, a 2048B page will have a 24B ECC.++Despite all of the above, the controller requires the driver to only read or+write in multiples of 8-bytes, because the data buffer is 64-bits.++OOB+===++Because of the above scheme, and because the "spare" OOB is really located in+the middle of a page, spare OOB cannot be read or write independently of the+data area. In other words, in order to read the OOB (aka READOOB), the entire+page (aka READ0) has to be read.++In the same sense, in order to write to the spare OOB the driver has to write+an *entire* page.++Factory bad blocks handling+===========================++Given the ECC BCH requires to layout the device's pages in a splitted+data/OOB/data/OOB way, the controller has a view of the flash page that's+different from the specified (aka the manufacturer's) view. In other words,++Factory view:++ -----------------------------------------------+ | Data |x OOB |+ -----------------------------------------------++Driver's view:++ -----------------------------------------------+ | Data | OOB | Data x | OOB |+ -----------------------------------------------++It can be seen from the above, that the factory bad block marker must be+searched within the 'data' region, and not in the usual OOB region.++In addition, this means under regular usage the driver will write such+position (since it belongs to the data region) and every used block is+likely to be marked as bad.++For this reason, marking the block as bad in the OOB is explicitly+disabled by using the NAND_BBT_NO_OOB_BBM option in the driver. The rationale+for this is that there's no point in marking a block as bad, because good+blocks are also 'marked as bad' (in the OOB BBM sense) under normal usage.++Instead, the drive relies in the bad block table alone, and should only perform+the bad block scan on the very first time (when the device hasn't been used).diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.cindex 64c258e..3359047 100644--- a/drivers/mtd/nand/pxa3xx_nand.c+++ b/drivers/mtd/nand/pxa3xx_nand.c@@ -7,6 +7,8 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
+ *+ * See Documentation/mtd/nand/pxa3xx-nand.txt for more details.
*/
#include <linux/kernel.h>