linux/drivers/mtd/nand
Thomas Petazzoni c2cdace755 mtd: nand: pxa3xx_nand: add support for partial chunks
This commit is needed to properly support the 8-bits ECC configuration
with 4KB pages.

When pages larger than 2 KB are used on platforms using the PXA3xx
NAND controller, the reading/programming operations need to be split
in chunks of 2 KBs or less because the controller FIFO is limited to
about 2 KB (i.e a bit more than 2 KB to accommodate OOB data). Due to
this requirement, the data layout on NAND is a bit strange, with ECC
interleaved with data, at the end of each chunk.

When a 4-bits ECC configuration is used with 4 KB pages, the physical
data layout on the NAND looks like this:

| 2048 data | 32 spare | 30 ECC | 2048 data | 32 spare | 30 ECC |

So the data chunks have an equal size, 2080 bytes for each chunk,
which the driver supports properly.

When a 8-bits ECC configuration is used with 4KB pages, the physical
data layout on the NAND looks like this:

| 1024 data | 30 ECC | 1024 data | 30 ECC | 1024 data | 30 ECC | 1024 data | 30 ECC | 64 spare | 30 ECC |

So, the spare area is stored in its own chunk, which has a different
size than the other chunks. Since OOB is not used by UBIFS, the initial
implementation of the driver has chosen to not support reading this
additional "spare" chunk of data.

Unfortunately, Marvell has chosen to store the BBT signature in the
OOB area. Therefore, if the driver doesn't read this spare area, Linux
has no way of finding the BBT. It thinks there is no BBT, and rewrites
one, which U-Boot does not recognize, causing compatibility problems
between the bootloader and the kernel in terms of NAND usage.

To fix this, this commit implements the support for reading a partial
last chunk. This support is currently only useful for the case of 8
bits ECC with 4 KB pages, but it will be useful in the future to
enable other configurations such as 12 bits and 16 bits ECC with 4 KB
pages, or 8 bits ECC with 8 KB pages, etc. All those configurations
have a "last" chunk that doesn't have the same size as the other
chunks.

In order to implement reading of the last chunk, this commit:

 - Adds a number of new fields to the pxa3xx_nand_info to describe how
   many full chunks and how many chunks we have, the size of full
   chunks and partial chunks, both in terms of data area and spare
   area.

 - Fills in the step_chunk_size and step_spare_size variables to
   describe how much data and spare should be read/written for the
   current read/program step.

 - Reworks the state machine to accommodate doing the additional read
   or program step when a last partial chunk is used.

This commit has been tested on a Marvell Armada 398 DB board, with a
4KB page NAND, tested in both 4 bits ECC and 8 bits ECC
configurations. Robert Jarzmik has tested on some PXA platforms.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Tested-by: Robert Jarzmik <robert.jarzmik@free.fr>
Acked-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
2016-02-12 11:13:34 -08:00
..
bcm47xxnflash mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
brcmnand mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
gpmi-nand mtd: nand: gpmi: may use minimum required ecc for 744 oobsize NAND 2016-01-23 14:45:57 -08:00
ams-delta.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
atmel_nand_ecc.h mtd: atmel_nand: Support 32-bit ECC strength 2016-02-12 10:27:48 -08:00
atmel_nand_nfc.h mtd: atmel_nand: Support variable RB_EDGE interrupts 2016-02-12 10:27:46 -08:00
atmel_nand.c mtd: atmel_nand: Support 32-bit ECC strength 2016-02-12 10:27:48 -08:00
au1550nd.c mtd: nand: remove useless mtd->priv = chip assignments 2015-12-18 13:21:40 -08:00
bf5xx_nand.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
cafe_nand.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
cmx270_nand.c mtd: nand: remove useless mtd->priv = chip assignments 2015-12-18 13:21:40 -08:00
cs553x_nand.c mtd: nand: remove useless mtd->priv = chip assignments 2015-12-18 13:21:40 -08:00
davinci_nand.c mtd: nand: davinci: remove custom 'erased check' implementation 2016-01-06 18:53:46 -08:00
denali_dt.c mtd: nand: drop owner assignment from platform_drivers 2014-10-20 16:20:58 +02:00
denali_pci.c mtd: denali_pci: switch to dev_err() 2015-08-18 17:21:37 -07:00
denali.c mtd: nand: remove useless mtd->priv = chip assignments 2015-12-18 13:21:40 -08:00
denali.h mtd: nand: denali: use the mtd instance embedded in struct nand_chip 2015-12-18 13:13:50 -08:00
diskonchip.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
docg4.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
fsl_elbc_nand.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
fsl_ifc_nand.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
fsl_upm.c mtd: nand: remove useless mtd->priv = chip assignments 2015-12-18 13:21:40 -08:00
fsmc_nand.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
gpio.c mtd: nand: remove useless mtd->priv = chip assignments 2015-12-18 13:21:40 -08:00
hisi504_nand.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
jz4740_nand.c mtd: nand: jz4740: kill the ->ecc_layout field 2016-01-26 10:27:35 -08:00
jz4780_bch.c mtd: nand: jz4780: Update ecc correction error codes 2016-01-08 09:44:30 -08:00
jz4780_bch.h mtd: nand: jz4780: driver for NAND devices on JZ4780 SoCs 2016-01-07 09:35:11 -08:00
jz4780_nand.c mtd: jz4780_nand: replace if/else blocks with switch/case 2016-01-08 09:49:03 -08:00
Kconfig mtd: cs553x: Fix dependencies for !HAS_IOMEM archs 2016-02-01 09:37:03 -08:00
lpc32xx_mlc.c mtd: nand: lpc32xx_mlc: fix ecc.size 2016-01-26 10:27:37 -08:00
lpc32xx_slc.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
Makefile mtd: nand: jz4780: driver for NAND devices on JZ4780 SoCs 2016-01-07 09:35:11 -08:00
mpc5121_nfc.c mtd: nand: mpc5121: use 'of_machine_is_compatible' to simplify code 2016-01-22 16:35:25 -08:00
mxc_nand.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
nand_base.c mtd: nand: use nand_check_erased_ecc_chunk in default ECC read functions 2016-01-06 18:48:20 -08:00
nand_bbt.c mtd: nand: remove EXPORT_SYMBOL of nand_scan_bbt() 2016-01-23 14:00:14 -08:00
nand_bch.c mtd: nand: return consistent error codes in ecc.correct() implementations 2016-01-06 18:45:46 -08:00
nand_ecc.c mtd: nand: return consistent error codes in ecc.correct() implementations 2016-01-06 18:45:46 -08:00
nand_ids.c mtd: nand: add NAND_NEED_SCRAMBLING flag to the H27UCG8T2ATR-BC definition 2016-01-22 16:36:54 -08:00
nand_timings.c mtd: nand: Use ULL-suffix for big u64 constant 2014-08-19 11:53:09 -07:00
nandsim.c mtd: nandsim: use nand_get_controller_data() 2016-01-07 12:25:58 -08:00
ndfc.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
nuc900_nand.c mtd: nuc900_nand: read correct SMISR register 2016-01-15 10:02:09 -08:00
omap2.c mtd: nand: return consistent error codes in ecc.correct() implementations 2016-01-06 18:45:46 -08:00
omap_elm.c mtd: omap_elm: print interrupt resource using %pr 2015-12-18 10:16:17 -08:00
orion_nand.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
pasemi_nand.c mtd: nand: remove useless mtd->priv = chip assignments 2015-12-18 13:21:40 -08:00
plat_nand.c mtd: nand: kill unused ->ecclayout field in platform_nand_chip struct 2016-01-26 10:27:36 -08:00
pxa3xx_nand.c mtd: nand: pxa3xx_nand: add support for partial chunks 2016-02-12 11:13:34 -08:00
r852.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
r852.h mtd: nand: r852: use the mtd instance embedded in struct nand_chip 2015-12-18 10:54:41 -08:00
s3c2410.c mtd: nand: s3c2410: kill the ->ecc_layout field 2016-01-26 10:27:35 -08:00
sh_flctl.c mtd: sh_flctl: pass FIFO as physical address 2015-12-18 18:27:13 -08:00
sharpsl.c mtd: nand: remove useless mtd->priv = chip assignments 2015-12-18 13:21:40 -08:00
sm_common.c mtd: nand: make use of mtd_to_nand() in NAND drivers 2015-12-08 12:24:36 -08:00
sm_common.h mtd: use __packed shorthand 2014-08-19 11:53:08 -07:00
socrates_nand.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
sunxi_nand.c mtd: nand: sunxi: use mtd_div_by_ws() helper 2016-01-23 12:51:43 -08:00
tmio_nand.c mtd: nand: remove useless mtd->priv = chip assignments 2015-12-18 13:21:40 -08:00
txx9ndfmc.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
vf610_nfc.c mtd: nand: vf610: remove useless mtd->ecclayout assignment 2016-01-26 10:27:38 -08:00
xway_nand.c mtd: nand: make use of mtd_to_nand() in NAND drivers 2015-12-08 12:24:36 -08:00