[PATCH 00/21] Armada 370/XP NAND support
Ezequiel Garcia
ezequiel.garcia at free-electrons.com
Thu Sep 19 12:01:24 EDT 2013
Hi everyone,
As some of you know, I'm working on implementing the long-awaited NAND
support in Armada 370/XP SoCs.
The controller is the same as PXA3XX (NFCv1), plus some changes,
and therefore it's called NFCv2. As expected, it should be supported
by pxa3xx-nand, plus some changes.
First of all I'd like to introduce the controller and explain how it
expects the data, ECC and OOB layout within a page. We might add this
as documentation inside the driver or in Documentation/mtd, so feel free
to ask anything that looks suspicious or is not clear enough.
* Page layout
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 BCH ECC we will have
to use this layout in the pages:
------------------------------------------------------------------------------
| 2048B data | 32B spare | 30B ECC || 2048B data | 32B spare | 30B ECC | ... |
------------------------------------------------------------------------------
The last remaining area is unusable (i.e. wasted).
To match this, my current (already working!) implementation acts like
a layout "impedance matcher" to produce in an internal driver's buffer
this layout:
------------------------------------------
| 4096B data | 64B spare |
------------------------------------------
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 + 64 spare) each.
The driver accomodates this data to expose the NAND base a contiguous 4160B buffer
(4096 data + 64 spare).
* ECC
The controller has built-in hardware ECC capabilities. In addition it is completely
configurable, and we can choose between Hamming and BCH ECC. If we choose BCH ECC
then the ECC code will be calculated for each transfered chunk and expected to be
located (when reading/programming) at specific locations.
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 |
------------------------------------
* 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 (aka SEQIN,
column = 4096 + PAGEPROG) the driver has to read the entire page first to the
driver's buffer. Then it should fill the OOB, and finally program the entire page,
data and oob included.
Notice, that while this is possible, I haven't included OOB only write support
(i.e. OOB write without data write) in this first patchset. I'm not sure why
would we need it, so I'd like to know others opinion on this matter.
Of course, writing to the OOB is supported, as long as this write is done
*with* data. Following the examples above, writing an entire 4096 + OOB page
is supported.
* Clocking and timings
This first patchset adds a dummy nand-clock to the device tree just to allow
the driver to get it. Timings configuration is overriden for now using the
'keep-config' DT parameter. The next round will likely include proper clock
support plus timings configuration.
* About this patchset
This has been tested on Armada 370 Mirabox and Armada XP GP boards.
Currently nandtest, mtd_pagetest, mtd_readtest pass while mtd_oobtest fails
(due to lack of OOB write support). This means that JFFS2 is not supported,
and UBIFS is a must.
The patches are based in l2-mtd's master branch and I've pushed a branch
to our github in case anyone wants to test this:
https://github.com/MISL-EBU-System-SW/mainline-public/tree/pxa3xx-armada-nand-v1
The series is fairy complex and lengthy, so any feedback is more than welcome,
as well as questions, suggestions or flames. Also, if anyone has a PXA board
(Daniel?) to test possible regressions I would really appreciate it.
* A note about Mirabox testing
As this work is not considered completely stable, be extra careful when trying
on the Mirabox. The Mirabox has the bootloader at NAND, and there's some risk
to brick the board.
That said: I've been using the driver on my Mirabox all morning (with my own
Buildroot prepared UBIFS image) and so far everything works fine.
If despite this you happen to brick the board, Willy Tarreau has provided
excellent instructions to un-brick the Mirabox:
http://1wt.eu/articles/mirabox-vs-guruplug/
Thanks!
Ezequiel Garcia (21):
mtd: nand: pxa3xx: Allocate data buffer on detected flash size
mtd: nand: pxa3xx: Disable OOB on arbitrary length commands
mtd: nand: pxa3xx: Use a completion to signal device ready
mtd: nand: pxa3xx: Add bad block handling
mtd: nand: pxa3xx: Add driver-specific ECC BCH support
mtd: nand: pxa3xx: Configure detected pages-per-block
mtd: nand: pxa3xx: Clear cmd buffer #3 (NDCB3) on command start
mtd: nand: pxa3xx: Make config menu show supported platforms
mtd: nand: pxa3xx: Split FIFO size from to-be-read FIFO count
mtd: nand: pxa3xx: Replace host->page_size by mtd->writesize
mtd: nand: pxa3xx: Add helper function to set page address
mtd: nand: pxa3xx: Remove READ0 switch/case falltrough
mtd: nand: pxa3xx: Split prepare_command_pool() in two stages
mtd: nand: pxa3xx: Move the data buffer clean to
prepare_start_command()
mtd: nand: pxa3xx: Add a read/write buffers markers
mtd: nand: pxa3xx: Introduce multiple page I/O support
mtd: nand: pxa3xx: Add multiple chunk write support
ARM: mvebu: Add a fixed 0Hz clock to represent NAND clock
ARM: mvebu: Add support for NAND controller in Armada 370/XP
ARM: mvebu: Enable NAND controller in Armada XP GP board
ARM: mvebu: Enable NAND controller in Armada 370 Mirabox
arch/arm/boot/dts/armada-370-mirabox.dts | 21 +
arch/arm/boot/dts/armada-370-xp.dtsi | 19 +
arch/arm/boot/dts/armada-xp-gp.dts | 8 +
drivers/mtd/nand/Kconfig | 4 +-
drivers/mtd/nand/pxa3xx_nand.c | 546 +++++++++++++++++++++-----
include/linux/platform_data/mtd-nand-pxa3xx.h | 3 +
6 files changed, 493 insertions(+), 108 deletions(-)
--
1.8.1.5
More information about the linux-mtd
mailing list