| rjw | 1f88458 | 2022-01-06 17:20:42 +0800 | [diff] [blame] | 1 |  | 
 | 2 | About this document | 
 | 3 | =================== | 
 | 4 |  | 
 | 5 | Some notes about Marvell's NAND controller available in PXA and Armada 370/XP | 
 | 6 | SoC (aka NFCv1 and NFCv2), with an emphasis on the latter. | 
 | 7 |  | 
 | 8 | NFCv2 controller background | 
 | 9 | =========================== | 
 | 10 |  | 
 | 11 | The controller has a 2176 bytes FIFO buffer. Therefore, in order to support | 
 | 12 | larger pages, I/O operations on 4 KiB and 8 KiB pages is done with a set of | 
 | 13 | chunked transfers. | 
 | 14 |  | 
 | 15 | For instance, if we choose a 2048 data chunk and set "BCH" ECC (see below) | 
 | 16 | we'll have this layout in the pages: | 
 | 17 |  | 
 | 18 |   ------------------------------------------------------------------------------ | 
 | 19 |   | 2048B data | 32B spare | 30B ECC || 2048B data | 32B spare | 30B ECC | ... | | 
 | 20 |   ------------------------------------------------------------------------------ | 
 | 21 |  | 
 | 22 | The driver reads the data and spare portions independently and builds an internal | 
 | 23 | buffer with this layout (in the 4 KiB page case): | 
 | 24 |  | 
 | 25 |   ------------------------------------------ | 
 | 26 |   |     4096B data     |     64B spare     | | 
 | 27 |   ------------------------------------------ | 
 | 28 |  | 
 | 29 | Also, for the READOOB command the driver disables the ECC and reads a 'spare + ECC' | 
 | 30 | OOB, one per chunk read. | 
 | 31 |  | 
 | 32 |   ------------------------------------------------------------------- | 
 | 33 |   |     4096B data     |  32B spare | 30B ECC | 32B spare | 30B ECC | | 
 | 34 |   ------------------------------------------------------------------- | 
 | 35 |  | 
 | 36 | So, in order to achieve reading (for instance), we issue several READ0 commands | 
 | 37 | (with some additional controller-specific magic) and read two chunks of 2080B | 
 | 38 | (2048 data + 32 spare) each. | 
 | 39 | The driver accommodates this data to expose the NAND core a contiguous buffer | 
 | 40 | (4096 data + spare) or (4096 + spare + ECC + spare + ECC). | 
 | 41 |  | 
 | 42 | ECC | 
 | 43 | === | 
 | 44 |  | 
 | 45 | The controller has built-in hardware ECC capabilities. In addition it is | 
 | 46 | configurable between two modes: 1) Hamming, 2) BCH. | 
 | 47 |  | 
 | 48 | Note that the actual BCH mode: BCH-4 or BCH-8 will depend on the way | 
 | 49 | the controller is configured to transfer the data. | 
 | 50 |  | 
 | 51 | In the BCH mode the ECC code will be calculated for each transferred chunk | 
 | 52 | and expected to be located (when reading/programming) right after the spare | 
 | 53 | bytes as the figure above shows. | 
 | 54 |  | 
 | 55 | So, repeating the above scheme, a 2048B data chunk will be followed by 32B | 
 | 56 | spare, and then the ECC controller will read/write the ECC code (30B in | 
 | 57 | this case): | 
 | 58 |  | 
 | 59 |   ------------------------------------ | 
 | 60 |   | 2048B data | 32B spare | 30B ECC | | 
 | 61 |   ------------------------------------ | 
 | 62 |  | 
 | 63 | If the ECC mode is 'BCH' then the ECC is *always* 30 bytes long. | 
 | 64 | If the ECC mode is 'Hamming' the ECC is 6 bytes long, for each 512B block. | 
 | 65 | So in Hamming mode, a 2048B page will have a 24B ECC. | 
 | 66 |  | 
 | 67 | Despite all of the above, the controller requires the driver to only read or | 
 | 68 | write in multiples of 8-bytes, because the data buffer is 64-bits. | 
 | 69 |  | 
 | 70 | OOB | 
 | 71 | === | 
 | 72 |  | 
 | 73 | Because of the above scheme, and because the "spare" OOB is really located in | 
 | 74 | the middle of a page, spare OOB cannot be read or write independently of the | 
 | 75 | data area. In other words, in order to read the OOB (aka READOOB), the entire | 
 | 76 | page (aka READ0) has to be read. | 
 | 77 |  | 
 | 78 | In the same sense, in order to write to the spare OOB the driver has to write | 
 | 79 | an *entire* page. | 
 | 80 |  | 
 | 81 | Factory bad blocks handling | 
 | 82 | =========================== | 
 | 83 |  | 
 | 84 | Given the ECC BCH requires to layout the device's pages in a split | 
 | 85 | data/OOB/data/OOB way, the controller has a view of the flash page that's | 
 | 86 | different from the specified (aka the manufacturer's) view. In other words, | 
 | 87 |  | 
 | 88 | Factory view: | 
 | 89 |  | 
 | 90 |   ----------------------------------------------- | 
 | 91 |   |                    Data           |x  OOB   | | 
 | 92 |   ----------------------------------------------- | 
 | 93 |  | 
 | 94 | Driver's view: | 
 | 95 |  | 
 | 96 |   ----------------------------------------------- | 
 | 97 |   |      Data      | OOB |      Data   x  | OOB | | 
 | 98 |   ----------------------------------------------- | 
 | 99 |  | 
 | 100 | It can be seen from the above, that the factory bad block marker must be | 
 | 101 | searched within the 'data' region, and not in the usual OOB region. | 
 | 102 |  | 
 | 103 | In addition, this means under regular usage the driver will write such | 
 | 104 | position (since it belongs to the data region) and every used block is | 
 | 105 | likely to be marked as bad. | 
 | 106 |  | 
 | 107 | For this reason, marking the block as bad in the OOB is explicitly | 
 | 108 | disabled by using the NAND_BBT_NO_OOB_BBM option in the driver. The rationale | 
 | 109 | for this is that there's no point in marking a block as bad, because good | 
 | 110 | blocks are also 'marked as bad' (in the OOB BBM sense) under normal usage. | 
 | 111 |  | 
 | 112 | Instead, the driver relies on the bad block table alone, and should only perform | 
 | 113 | the bad block scan on the very first time (when the device hasn't been used). |