• Thomas Petazzoni's avatar
    mtd: nand: pxa3xx_nand: add support for partial chunks · c2cdace7
    Thomas Petazzoni authored
    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: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
    Tested-by: default avatarRobert Jarzmik <robert.jarzmik@free.fr>
    Acked-by: default avatarEzequiel Garcia <ezequiel@vanguardiasur.com.ar>
    Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
    c2cdace7
pxa3xx_nand.c 53.7 KB