• Masahiro Yamada's avatar
    mtd: nand: denali: fix raw and oob accessors for syndrome page layout · 26d266e1
    Masahiro Yamada authored
    The Denali IP adopts the syndrome page layout; payload and ECC are
    interleaved, with BBM area always placed at the beginning of OOB.
    
    The figure below shows the page organization for ecc->steps == 2:
    
      |----------------|    |-----------|
      |                |    |           |
      |                |    |           |
      |    Payload0    |    |           |
      |                |    |           |
      |                |    |           |
      |                |    |           |
      |----------------|    |  in-band  |
      |      ECC0      |    |   area    |
      |----------------|    |           |
      |                |    |           |
      |                |    |           |
      |    Payload1    |    |           |
      |                |    |           |
      |                |    |           |
      |----------------|    |-----------|
      |      BBM       |    |           |
      |----------------|    |           |
      |Payload1 (cont.)|    |           |
      |----------------|    |out-of-band|
      |      ECC1      |    |    area   |
      |----------------|    |           |
      |    OOB free    |    |           |
      |----------------|    |-----------|
    
    The current raw / oob accessors do not take that into consideration,
    so in-band and out-of-band data are transferred as stored in the
    device.  In the case above,
    
      in-band:      Payload0 + ECC0 + Payload1(partial)
      out-of-band:  BBM + Payload1(cont.) + ECC1 + OOB-free
    
    This is wrong.  As the comment block of struct nand_ecc_ctrl says,
    driver callbacks must hide the specific layout used by the hardware
    and always return contiguous in-band and out-of-band data.
    
    The current implementation is completely screwed-up, so read/write
    callbacks must be re-worked.
    
    Also, it is reasonable to support PIO transfer in case DMA may not
    work for some reasons.  Actually, the Data DMA may not be equipped
    depending on the configuration of the RTL.  This can be checked by
    reading the bit 4 of the FEATURES register.  Even if the controller
    has the DMA support, dma_set_mask() and dma_map_single() could fail.
    In either case, the driver can fall back to the PIO transfer.  Slower
    access would be better than giving up.
    Signed-off-by: default avatarMasahiro Yamada <yamada.masahiro@socionext.com>
    Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
    26d266e1
denali.c 39.3 KB