Ezequiel Garcia | de484a3 | 2013-11-07 12:17:10 -0300 | [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 | |
Carlos Garcia | c98be0c | 2014-04-04 22:31:00 -0400 | [diff] [blame] | 51 | In the BCH mode the ECC code will be calculated for each transferred chunk |
Ezequiel Garcia | de484a3 | 2013-11-07 12:17:10 -0300 | [diff] [blame] | 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). |