Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs: mtd: convert to ReST

Rename the mtd documentation files to ReST, add an
index for them and adjust in order to produce a nice html
output via the Sphinx build system.

It should be noticed that Sphinx doesn't handle very well
URLs with dots in the middle. Thankfully, internally, the '.'
char is translated to %2E, so we can jus use %2E instead of
dots, and this will work fine on both text and processed files.

At its new index.rst, let's add a :orphan: while this is not linked to
the main index.rst file, in order to avoid build warnings.

Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>

+306 -242
+12
Documentation/mtd/index.rst
··· 1 + :orphan: 2 + 3 + ============================== 4 + Memory Technology Device (MTD) 5 + ============================== 6 + 7 + .. toctree:: 8 + :maxdepth: 1 9 + 10 + intel-spi 11 + nand_ecc 12 + spi-nor
+24 -22
Documentation/mtd/intel-spi.txt Documentation/mtd/intel-spi.rst
··· 1 + ============================== 1 2 Upgrading BIOS using intel-spi 2 - ------------------------------ 3 + ============================== 3 4 4 5 Many Intel CPUs like Baytrail and Braswell include SPI serial flash host 5 6 controller which is used to hold BIOS and other platform specific data. ··· 37 36 module parameter to modprobe). 38 37 39 38 4) Once the board is up and running again, find the right MTD partition 40 - (it is named as "BIOS"): 39 + (it is named as "BIOS"):: 41 40 42 - # cat /proc/mtd 43 - dev: size erasesize name 44 - mtd0: 00800000 00001000 "BIOS" 41 + # cat /proc/mtd 42 + dev: size erasesize name 43 + mtd0: 00800000 00001000 "BIOS" 45 44 46 45 So here it will be /dev/mtd0 but it may vary. 47 46 48 - 5) Make backup of the existing image first: 47 + 5) Make backup of the existing image first:: 49 48 50 - # dd if=/dev/mtd0ro of=bios.bak 51 - 16384+0 records in 52 - 16384+0 records out 53 - 8388608 bytes (8.4 MB) copied, 10.0269 s, 837 kB/s 49 + # dd if=/dev/mtd0ro of=bios.bak 50 + 16384+0 records in 51 + 16384+0 records out 52 + 8388608 bytes (8.4 MB) copied, 10.0269 s, 837 kB/s 54 53 55 - 6) Verify the backup 54 + 6) Verify the backup: 56 55 57 - # sha1sum /dev/mtd0ro bios.bak 58 - fdbb011920572ca6c991377c4b418a0502668b73 /dev/mtd0ro 59 - fdbb011920572ca6c991377c4b418a0502668b73 bios.bak 56 + # sha1sum /dev/mtd0ro bios.bak 57 + fdbb011920572ca6c991377c4b418a0502668b73 /dev/mtd0ro 58 + fdbb011920572ca6c991377c4b418a0502668b73 bios.bak 60 59 61 60 The SHA1 sums must match. Otherwise do not continue any further! 62 61 63 62 7) Erase the SPI serial flash. After this step, do not reboot the 64 - board! Otherwise it will not start anymore. 63 + board! Otherwise it will not start anymore:: 65 64 66 - # flash_erase /dev/mtd0 0 0 67 - Erasing 4 Kibyte @ 7ff000 -- 100 % complete 65 + # flash_erase /dev/mtd0 0 0 66 + Erasing 4 Kibyte @ 7ff000 -- 100 % complete 68 67 69 68 8) Once completed without errors you can write the new BIOS image: 70 69 71 70 # dd if=MNW2MAX1.X64.0092.R01.1605221712.bin of=/dev/mtd0 72 71 73 72 9) Verify that the new content of the SPI serial flash matches the new 74 - BIOS image: 73 + BIOS image:: 75 74 76 - # sha1sum /dev/mtd0ro MNW2MAX1.X64.0092.R01.1605221712.bin 77 - 9b4df9e4be2057fceec3a5529ec3d950836c87a2 /dev/mtd0ro 78 - 9b4df9e4be2057fceec3a5529ec3d950836c87a2 MNW2MAX1.X64.0092.R01.1605221712.bin 75 + # sha1sum /dev/mtd0ro MNW2MAX1.X64.0092.R01.1605221712.bin 76 + 9b4df9e4be2057fceec3a5529ec3d950836c87a2 /dev/mtd0ro 77 + 9b4df9e4be2057fceec3a5529ec3d950836c87a2 MNW2MAX1.X64.0092.R01.1605221712.bin 79 78 80 79 The SHA1 sums should match. 81 80 ··· 85 84 References 86 85 ---------- 87 86 88 - [1] https://firmware.intel.com/sites/default/files/MinnowBoard.MAX_.X64.92.R01.zip 87 + [1] https://firmware.intel.com/sites/default/files/MinnowBoard%2EMAX_%2EX64%2E92%2ER01%2Ezip 88 + 89 89 [2] http://www.linux-mtd.infradead.org/
+265 -216
Documentation/mtd/nand_ecc.txt Documentation/mtd/nand_ecc.rst
··· 1 + ========================== 2 + NAND Error-correction Code 3 + ========================== 4 + 1 5 Introduction 2 6 ============ 3 7 ··· 41 37 Back to ecc. 42 38 Let's give a small figure: 43 39 40 + ========= ==== ==== ==== ==== ==== ==== ==== ==== === === === === ==== 44 41 byte 0: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp0 rp2 rp4 ... rp14 45 42 byte 1: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp1 rp2 rp4 ... rp14 46 43 byte 2: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp0 rp3 rp4 ... rp14 47 44 byte 3: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp1 rp3 rp4 ... rp14 48 45 byte 4: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp0 rp2 rp5 ... rp14 49 - .... 46 + ... 50 47 byte 254: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp0 rp3 rp5 ... rp15 51 48 byte 255: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp1 rp3 rp5 ... rp15 52 49 cp1 cp0 cp1 cp0 cp1 cp0 cp1 cp0 53 50 cp3 cp3 cp2 cp2 cp3 cp3 cp2 cp2 54 51 cp5 cp5 cp5 cp5 cp4 cp4 cp4 cp4 52 + ========= ==== ==== ==== ==== ==== ==== ==== ==== === === === === ==== 55 53 56 54 This figure represents a sector of 256 bytes. 57 55 cp is my abbreviation for column parity, rp for row parity. 58 56 59 57 Let's start to explain column parity. 60 - cp0 is the parity that belongs to all bit0, bit2, bit4, bit6. 61 - so the sum of all bit0, bit2, bit4 and bit6 values + cp0 itself is even. 58 + 59 + - cp0 is the parity that belongs to all bit0, bit2, bit4, bit6. 60 + 61 + so the sum of all bit0, bit2, bit4 and bit6 values + cp0 itself is even. 62 + 62 63 Similarly cp1 is the sum of all bit1, bit3, bit5 and bit7. 63 - cp2 is the parity over bit0, bit1, bit4 and bit5 64 - cp3 is the parity over bit2, bit3, bit6 and bit7. 65 - cp4 is the parity over bit0, bit1, bit2 and bit3. 66 - cp5 is the parity over bit4, bit5, bit6 and bit7. 64 + 65 + - cp2 is the parity over bit0, bit1, bit4 and bit5 66 + - cp3 is the parity over bit2, bit3, bit6 and bit7. 67 + - cp4 is the parity over bit0, bit1, bit2 and bit3. 68 + - cp5 is the parity over bit4, bit5, bit6 and bit7. 69 + 67 70 Note that each of cp0 .. cp5 is exactly one bit. 68 71 69 72 Row parity actually works almost the same. 70 - rp0 is the parity of all even bytes (0, 2, 4, 6, ... 252, 254) 71 - rp1 is the parity of all odd bytes (1, 3, 5, 7, ..., 253, 255) 72 - rp2 is the parity of all bytes 0, 1, 4, 5, 8, 9, ... 73 - (so handle two bytes, then skip 2 bytes). 74 - rp3 is covers the half rp2 does not cover (bytes 2, 3, 6, 7, 10, 11, ...) 75 - for rp4 the rule is cover 4 bytes, skip 4 bytes, cover 4 bytes, skip 4 etc. 76 - so rp4 calculates parity over bytes 0, 1, 2, 3, 8, 9, 10, 11, 16, ...) 77 - and rp5 covers the other half, so bytes 4, 5, 6, 7, 12, 13, 14, 15, 20, .. 73 + 74 + - rp0 is the parity of all even bytes (0, 2, 4, 6, ... 252, 254) 75 + - rp1 is the parity of all odd bytes (1, 3, 5, 7, ..., 253, 255) 76 + - rp2 is the parity of all bytes 0, 1, 4, 5, 8, 9, ... 77 + (so handle two bytes, then skip 2 bytes). 78 + - rp3 is covers the half rp2 does not cover (bytes 2, 3, 6, 7, 10, 11, ...) 79 + - for rp4 the rule is cover 4 bytes, skip 4 bytes, cover 4 bytes, skip 4 etc. 80 + 81 + so rp4 calculates parity over bytes 0, 1, 2, 3, 8, 9, 10, 11, 16, ...) 82 + - and rp5 covers the other half, so bytes 4, 5, 6, 7, 12, 13, 14, 15, 20, .. 83 + 78 84 The story now becomes quite boring. I guess you get the idea. 79 - rp6 covers 8 bytes then skips 8 etc 80 - rp7 skips 8 bytes then covers 8 etc 81 - rp8 covers 16 bytes then skips 16 etc 82 - rp9 skips 16 bytes then covers 16 etc 83 - rp10 covers 32 bytes then skips 32 etc 84 - rp11 skips 32 bytes then covers 32 etc 85 - rp12 covers 64 bytes then skips 64 etc 86 - rp13 skips 64 bytes then covers 64 etc 87 - rp14 covers 128 bytes then skips 128 88 - rp15 skips 128 bytes then covers 128 85 + 86 + - rp6 covers 8 bytes then skips 8 etc 87 + - rp7 skips 8 bytes then covers 8 etc 88 + - rp8 covers 16 bytes then skips 16 etc 89 + - rp9 skips 16 bytes then covers 16 etc 90 + - rp10 covers 32 bytes then skips 32 etc 91 + - rp11 skips 32 bytes then covers 32 etc 92 + - rp12 covers 64 bytes then skips 64 etc 93 + - rp13 skips 64 bytes then covers 64 etc 94 + - rp14 covers 128 bytes then skips 128 95 + - rp15 skips 128 bytes then covers 128 89 96 90 97 In the end the parity bits are grouped together in three bytes as 91 98 follows: 99 + 100 + ===== ===== ===== ===== ===== ===== ===== ===== ===== 92 101 ECC Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 102 + ===== ===== ===== ===== ===== ===== ===== ===== ===== 93 103 ECC 0 rp07 rp06 rp05 rp04 rp03 rp02 rp01 rp00 94 104 ECC 1 rp15 rp14 rp13 rp12 rp11 rp10 rp09 rp08 95 105 ECC 2 cp5 cp4 cp3 cp2 cp1 cp0 1 1 106 + ===== ===== ===== ===== ===== ===== ===== ===== ===== 96 107 97 108 I detected after writing this that ST application note AN1823 98 109 (http://www.st.com/stonline/) gives a much 99 110 nicer picture.(but they use line parity as term where I use row parity) 100 111 Oh well, I'm graphically challenged, so suffer with me for a moment :-) 112 + 101 113 And I could not reuse the ST picture anyway for copyright reasons. 102 114 103 115 ··· 121 101 ========= 122 102 123 103 Implementing the parity calculation is pretty simple. 124 - In C pseudocode: 125 - for (i = 0; i < 256; i++) 126 - { 104 + In C pseudocode:: 105 + 106 + for (i = 0; i < 256; i++) 107 + { 127 108 if (i & 0x01) 128 109 rp1 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp1; 129 110 else ··· 163 142 cp3 = bit7 ^ bit6 ^ bit3 ^ bit2 ^ cp3 164 143 cp4 = bit3 ^ bit2 ^ bit1 ^ bit0 ^ cp4 165 144 cp5 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ cp5 166 - } 145 + } 167 146 168 147 169 148 Analysis 0 ··· 188 167 Attempt 1 189 168 ========= 190 169 191 - const char parity[256] = { 192 - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 193 - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 194 - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 195 - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 196 - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 197 - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 198 - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 199 - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 200 - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 201 - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 202 - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 203 - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 204 - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 205 - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 206 - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 207 - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 208 - }; 170 + :: 209 171 210 - void ecc1(const unsigned char *buf, unsigned char *code) 211 - { 212 - int i; 213 - const unsigned char *bp = buf; 214 - unsigned char cur; 215 - unsigned char rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7; 216 - unsigned char rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15; 217 - unsigned char par; 172 + const char parity[256] = { 173 + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 174 + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 175 + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 176 + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 177 + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 178 + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 179 + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 180 + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 181 + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 182 + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 183 + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 184 + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 185 + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 186 + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 187 + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 188 + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 189 + }; 218 190 219 - par = 0; 220 - rp0 = 0; rp1 = 0; rp2 = 0; rp3 = 0; 221 - rp4 = 0; rp5 = 0; rp6 = 0; rp7 = 0; 222 - rp8 = 0; rp9 = 0; rp10 = 0; rp11 = 0; 223 - rp12 = 0; rp13 = 0; rp14 = 0; rp15 = 0; 191 + void ecc1(const unsigned char *buf, unsigned char *code) 192 + { 193 + int i; 194 + const unsigned char *bp = buf; 195 + unsigned char cur; 196 + unsigned char rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7; 197 + unsigned char rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15; 198 + unsigned char par; 224 199 225 - for (i = 0; i < 256; i++) 226 - { 227 - cur = *bp++; 228 - par ^= cur; 229 - if (i & 0x01) rp1 ^= cur; else rp0 ^= cur; 230 - if (i & 0x02) rp3 ^= cur; else rp2 ^= cur; 231 - if (i & 0x04) rp5 ^= cur; else rp4 ^= cur; 232 - if (i & 0x08) rp7 ^= cur; else rp6 ^= cur; 233 - if (i & 0x10) rp9 ^= cur; else rp8 ^= cur; 234 - if (i & 0x20) rp11 ^= cur; else rp10 ^= cur; 235 - if (i & 0x40) rp13 ^= cur; else rp12 ^= cur; 236 - if (i & 0x80) rp15 ^= cur; else rp14 ^= cur; 237 - } 238 - code[0] = 239 - (parity[rp7] << 7) | 240 - (parity[rp6] << 6) | 241 - (parity[rp5] << 5) | 242 - (parity[rp4] << 4) | 243 - (parity[rp3] << 3) | 244 - (parity[rp2] << 2) | 245 - (parity[rp1] << 1) | 246 - (parity[rp0]); 247 - code[1] = 248 - (parity[rp15] << 7) | 249 - (parity[rp14] << 6) | 250 - (parity[rp13] << 5) | 251 - (parity[rp12] << 4) | 252 - (parity[rp11] << 3) | 253 - (parity[rp10] << 2) | 254 - (parity[rp9] << 1) | 255 - (parity[rp8]); 256 - code[2] = 257 - (parity[par & 0xf0] << 7) | 258 - (parity[par & 0x0f] << 6) | 259 - (parity[par & 0xcc] << 5) | 260 - (parity[par & 0x33] << 4) | 261 - (parity[par & 0xaa] << 3) | 262 - (parity[par & 0x55] << 2); 263 - code[0] = ~code[0]; 264 - code[1] = ~code[1]; 265 - code[2] = ~code[2]; 266 - } 200 + par = 0; 201 + rp0 = 0; rp1 = 0; rp2 = 0; rp3 = 0; 202 + rp4 = 0; rp5 = 0; rp6 = 0; rp7 = 0; 203 + rp8 = 0; rp9 = 0; rp10 = 0; rp11 = 0; 204 + rp12 = 0; rp13 = 0; rp14 = 0; rp15 = 0; 205 + 206 + for (i = 0; i < 256; i++) 207 + { 208 + cur = *bp++; 209 + par ^= cur; 210 + if (i & 0x01) rp1 ^= cur; else rp0 ^= cur; 211 + if (i & 0x02) rp3 ^= cur; else rp2 ^= cur; 212 + if (i & 0x04) rp5 ^= cur; else rp4 ^= cur; 213 + if (i & 0x08) rp7 ^= cur; else rp6 ^= cur; 214 + if (i & 0x10) rp9 ^= cur; else rp8 ^= cur; 215 + if (i & 0x20) rp11 ^= cur; else rp10 ^= cur; 216 + if (i & 0x40) rp13 ^= cur; else rp12 ^= cur; 217 + if (i & 0x80) rp15 ^= cur; else rp14 ^= cur; 218 + } 219 + code[0] = 220 + (parity[rp7] << 7) | 221 + (parity[rp6] << 6) | 222 + (parity[rp5] << 5) | 223 + (parity[rp4] << 4) | 224 + (parity[rp3] << 3) | 225 + (parity[rp2] << 2) | 226 + (parity[rp1] << 1) | 227 + (parity[rp0]); 228 + code[1] = 229 + (parity[rp15] << 7) | 230 + (parity[rp14] << 6) | 231 + (parity[rp13] << 5) | 232 + (parity[rp12] << 4) | 233 + (parity[rp11] << 3) | 234 + (parity[rp10] << 2) | 235 + (parity[rp9] << 1) | 236 + (parity[rp8]); 237 + code[2] = 238 + (parity[par & 0xf0] << 7) | 239 + (parity[par & 0x0f] << 6) | 240 + (parity[par & 0xcc] << 5) | 241 + (parity[par & 0x33] << 4) | 242 + (parity[par & 0xaa] << 3) | 243 + (parity[par & 0x55] << 2); 244 + code[0] = ~code[0]; 245 + code[1] = ~code[1]; 246 + code[2] = ~code[2]; 247 + } 267 248 268 249 Still pretty straightforward. The last three invert statements are there to 269 250 give a checksum of 0xff 0xff 0xff for an empty flash. In an empty flash ··· 316 293 Attempt 2 317 294 ========= 318 295 319 - extern const char parity[256]; 296 + :: 320 297 321 - void ecc2(const unsigned char *buf, unsigned char *code) 322 - { 323 - int i; 324 - const unsigned long *bp = (unsigned long *)buf; 325 - unsigned long cur; 326 - unsigned long rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7; 327 - unsigned long rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15; 328 - unsigned long par; 298 + extern const char parity[256]; 329 299 330 - par = 0; 331 - rp0 = 0; rp1 = 0; rp2 = 0; rp3 = 0; 332 - rp4 = 0; rp5 = 0; rp6 = 0; rp7 = 0; 333 - rp8 = 0; rp9 = 0; rp10 = 0; rp11 = 0; 334 - rp12 = 0; rp13 = 0; rp14 = 0; rp15 = 0; 300 + void ecc2(const unsigned char *buf, unsigned char *code) 301 + { 302 + int i; 303 + const unsigned long *bp = (unsigned long *)buf; 304 + unsigned long cur; 305 + unsigned long rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7; 306 + unsigned long rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15; 307 + unsigned long par; 335 308 336 - for (i = 0; i < 64; i++) 337 - { 338 - cur = *bp++; 339 - par ^= cur; 340 - if (i & 0x01) rp5 ^= cur; else rp4 ^= cur; 341 - if (i & 0x02) rp7 ^= cur; else rp6 ^= cur; 342 - if (i & 0x04) rp9 ^= cur; else rp8 ^= cur; 343 - if (i & 0x08) rp11 ^= cur; else rp10 ^= cur; 344 - if (i & 0x10) rp13 ^= cur; else rp12 ^= cur; 345 - if (i & 0x20) rp15 ^= cur; else rp14 ^= cur; 346 - } 347 - /* 348 - we need to adapt the code generation for the fact that rp vars are now 349 - long; also the column parity calculation needs to be changed. 350 - we'll bring rp4 to 15 back to single byte entities by shifting and 351 - xoring 352 - */ 353 - rp4 ^= (rp4 >> 16); rp4 ^= (rp4 >> 8); rp4 &= 0xff; 354 - rp5 ^= (rp5 >> 16); rp5 ^= (rp5 >> 8); rp5 &= 0xff; 355 - rp6 ^= (rp6 >> 16); rp6 ^= (rp6 >> 8); rp6 &= 0xff; 356 - rp7 ^= (rp7 >> 16); rp7 ^= (rp7 >> 8); rp7 &= 0xff; 357 - rp8 ^= (rp8 >> 16); rp8 ^= (rp8 >> 8); rp8 &= 0xff; 358 - rp9 ^= (rp9 >> 16); rp9 ^= (rp9 >> 8); rp9 &= 0xff; 359 - rp10 ^= (rp10 >> 16); rp10 ^= (rp10 >> 8); rp10 &= 0xff; 360 - rp11 ^= (rp11 >> 16); rp11 ^= (rp11 >> 8); rp11 &= 0xff; 361 - rp12 ^= (rp12 >> 16); rp12 ^= (rp12 >> 8); rp12 &= 0xff; 362 - rp13 ^= (rp13 >> 16); rp13 ^= (rp13 >> 8); rp13 &= 0xff; 363 - rp14 ^= (rp14 >> 16); rp14 ^= (rp14 >> 8); rp14 &= 0xff; 364 - rp15 ^= (rp15 >> 16); rp15 ^= (rp15 >> 8); rp15 &= 0xff; 365 - rp3 = (par >> 16); rp3 ^= (rp3 >> 8); rp3 &= 0xff; 366 - rp2 = par & 0xffff; rp2 ^= (rp2 >> 8); rp2 &= 0xff; 367 - par ^= (par >> 16); 368 - rp1 = (par >> 8); rp1 &= 0xff; 369 - rp0 = (par & 0xff); 370 - par ^= (par >> 8); par &= 0xff; 309 + par = 0; 310 + rp0 = 0; rp1 = 0; rp2 = 0; rp3 = 0; 311 + rp4 = 0; rp5 = 0; rp6 = 0; rp7 = 0; 312 + rp8 = 0; rp9 = 0; rp10 = 0; rp11 = 0; 313 + rp12 = 0; rp13 = 0; rp14 = 0; rp15 = 0; 371 314 372 - code[0] = 373 - (parity[rp7] << 7) | 374 - (parity[rp6] << 6) | 375 - (parity[rp5] << 5) | 376 - (parity[rp4] << 4) | 377 - (parity[rp3] << 3) | 378 - (parity[rp2] << 2) | 379 - (parity[rp1] << 1) | 380 - (parity[rp0]); 381 - code[1] = 382 - (parity[rp15] << 7) | 383 - (parity[rp14] << 6) | 384 - (parity[rp13] << 5) | 385 - (parity[rp12] << 4) | 386 - (parity[rp11] << 3) | 387 - (parity[rp10] << 2) | 388 - (parity[rp9] << 1) | 389 - (parity[rp8]); 390 - code[2] = 391 - (parity[par & 0xf0] << 7) | 392 - (parity[par & 0x0f] << 6) | 393 - (parity[par & 0xcc] << 5) | 394 - (parity[par & 0x33] << 4) | 395 - (parity[par & 0xaa] << 3) | 396 - (parity[par & 0x55] << 2); 397 - code[0] = ~code[0]; 398 - code[1] = ~code[1]; 399 - code[2] = ~code[2]; 400 - } 315 + for (i = 0; i < 64; i++) 316 + { 317 + cur = *bp++; 318 + par ^= cur; 319 + if (i & 0x01) rp5 ^= cur; else rp4 ^= cur; 320 + if (i & 0x02) rp7 ^= cur; else rp6 ^= cur; 321 + if (i & 0x04) rp9 ^= cur; else rp8 ^= cur; 322 + if (i & 0x08) rp11 ^= cur; else rp10 ^= cur; 323 + if (i & 0x10) rp13 ^= cur; else rp12 ^= cur; 324 + if (i & 0x20) rp15 ^= cur; else rp14 ^= cur; 325 + } 326 + /* 327 + we need to adapt the code generation for the fact that rp vars are now 328 + long; also the column parity calculation needs to be changed. 329 + we'll bring rp4 to 15 back to single byte entities by shifting and 330 + xoring 331 + */ 332 + rp4 ^= (rp4 >> 16); rp4 ^= (rp4 >> 8); rp4 &= 0xff; 333 + rp5 ^= (rp5 >> 16); rp5 ^= (rp5 >> 8); rp5 &= 0xff; 334 + rp6 ^= (rp6 >> 16); rp6 ^= (rp6 >> 8); rp6 &= 0xff; 335 + rp7 ^= (rp7 >> 16); rp7 ^= (rp7 >> 8); rp7 &= 0xff; 336 + rp8 ^= (rp8 >> 16); rp8 ^= (rp8 >> 8); rp8 &= 0xff; 337 + rp9 ^= (rp9 >> 16); rp9 ^= (rp9 >> 8); rp9 &= 0xff; 338 + rp10 ^= (rp10 >> 16); rp10 ^= (rp10 >> 8); rp10 &= 0xff; 339 + rp11 ^= (rp11 >> 16); rp11 ^= (rp11 >> 8); rp11 &= 0xff; 340 + rp12 ^= (rp12 >> 16); rp12 ^= (rp12 >> 8); rp12 &= 0xff; 341 + rp13 ^= (rp13 >> 16); rp13 ^= (rp13 >> 8); rp13 &= 0xff; 342 + rp14 ^= (rp14 >> 16); rp14 ^= (rp14 >> 8); rp14 &= 0xff; 343 + rp15 ^= (rp15 >> 16); rp15 ^= (rp15 >> 8); rp15 &= 0xff; 344 + rp3 = (par >> 16); rp3 ^= (rp3 >> 8); rp3 &= 0xff; 345 + rp2 = par & 0xffff; rp2 ^= (rp2 >> 8); rp2 &= 0xff; 346 + par ^= (par >> 16); 347 + rp1 = (par >> 8); rp1 &= 0xff; 348 + rp0 = (par & 0xff); 349 + par ^= (par >> 8); par &= 0xff; 350 + 351 + code[0] = 352 + (parity[rp7] << 7) | 353 + (parity[rp6] << 6) | 354 + (parity[rp5] << 5) | 355 + (parity[rp4] << 4) | 356 + (parity[rp3] << 3) | 357 + (parity[rp2] << 2) | 358 + (parity[rp1] << 1) | 359 + (parity[rp0]); 360 + code[1] = 361 + (parity[rp15] << 7) | 362 + (parity[rp14] << 6) | 363 + (parity[rp13] << 5) | 364 + (parity[rp12] << 4) | 365 + (parity[rp11] << 3) | 366 + (parity[rp10] << 2) | 367 + (parity[rp9] << 1) | 368 + (parity[rp8]); 369 + code[2] = 370 + (parity[par & 0xf0] << 7) | 371 + (parity[par & 0x0f] << 6) | 372 + (parity[par & 0xcc] << 5) | 373 + (parity[par & 0x33] << 4) | 374 + (parity[par & 0xaa] << 3) | 375 + (parity[par & 0x55] << 2); 376 + code[0] = ~code[0]; 377 + code[1] = ~code[1]; 378 + code[2] = ~code[2]; 379 + } 401 380 402 381 The parity array is not shown any more. Note also that for these 403 382 examples I kinda deviated from my regular programming style by allowing ··· 428 403 Attempt 3 429 404 ========= 430 405 431 - Odd replaced: 432 - if (i & 0x01) rp5 ^= cur; else rp4 ^= cur; 433 - if (i & 0x02) rp7 ^= cur; else rp6 ^= cur; 434 - if (i & 0x04) rp9 ^= cur; else rp8 ^= cur; 435 - if (i & 0x08) rp11 ^= cur; else rp10 ^= cur; 436 - if (i & 0x10) rp13 ^= cur; else rp12 ^= cur; 437 - if (i & 0x20) rp15 ^= cur; else rp14 ^= cur; 438 - with 439 - if (i & 0x01) rp5 ^= cur; 440 - if (i & 0x02) rp7 ^= cur; 441 - if (i & 0x04) rp9 ^= cur; 442 - if (i & 0x08) rp11 ^= cur; 443 - if (i & 0x10) rp13 ^= cur; 444 - if (i & 0x20) rp15 ^= cur; 406 + Odd replaced:: 445 407 446 - and outside the loop added: 447 - rp4 = par ^ rp5; 448 - rp6 = par ^ rp7; 449 - rp8 = par ^ rp9; 450 - rp10 = par ^ rp11; 451 - rp12 = par ^ rp13; 452 - rp14 = par ^ rp15; 408 + if (i & 0x01) rp5 ^= cur; else rp4 ^= cur; 409 + if (i & 0x02) rp7 ^= cur; else rp6 ^= cur; 410 + if (i & 0x04) rp9 ^= cur; else rp8 ^= cur; 411 + if (i & 0x08) rp11 ^= cur; else rp10 ^= cur; 412 + if (i & 0x10) rp13 ^= cur; else rp12 ^= cur; 413 + if (i & 0x20) rp15 ^= cur; else rp14 ^= cur; 414 + 415 + with:: 416 + 417 + if (i & 0x01) rp5 ^= cur; 418 + if (i & 0x02) rp7 ^= cur; 419 + if (i & 0x04) rp9 ^= cur; 420 + if (i & 0x08) rp11 ^= cur; 421 + if (i & 0x10) rp13 ^= cur; 422 + if (i & 0x20) rp15 ^= cur; 423 + 424 + and outside the loop added:: 425 + 426 + rp4 = par ^ rp5; 427 + rp6 = par ^ rp7; 428 + rp8 = par ^ rp9; 429 + rp10 = par ^ rp11; 430 + rp12 = par ^ rp13; 431 + rp14 = par ^ rp15; 453 432 454 433 And after that the code takes about 30% more time, although the number of 455 434 statements is reduced. This is also reflected in the assembly code. ··· 477 448 ========= 478 449 479 450 Unrolled the loop 1, 2, 3 and 4 times. 480 - For 4 the code starts with: 451 + For 4 the code starts with:: 481 452 482 453 for (i = 0; i < 4; i++) 483 454 { ··· 500 471 ========== 501 472 502 473 Unrolling once gains about 15% 474 + 503 475 Unrolling twice keeps the gain at about 15% 476 + 504 477 Unrolling three times gives a gain of 30% compared to attempt 2. 478 + 505 479 Unrolling four times gives a marginal improvement compared to unrolling 506 480 three times. 507 481 ··· 524 492 525 493 Effectively so all odd digit rp assignments in the loop were removed. 526 494 This included the else clause of the if statements. 527 - Of course after the loop we need to correct things by adding code like: 495 + Of course after the loop we need to correct things by adding code like:: 496 + 528 497 rp5 = par ^ rp4; 498 + 529 499 Also the initial assignments (rp5 = 0; etc) could be removed. 530 500 Along the line I also removed the initialisation of rp0/1/2/3. 531 501 ··· 547 513 Attempt 6 548 514 ========= 549 515 550 - THe code within the for loop was changed to: 516 + THe code within the for loop was changed to:: 551 517 552 518 for (i = 0; i < 4; i++) 553 519 { ··· 598 564 definitely seemed to be the jackpot! 599 565 600 566 There is a little bit more room for improvement though. There are three 601 - places with statements: 602 - rp4 ^= cur; rp6 ^= cur; 567 + places with statements:: 568 + 569 + rp4 ^= cur; rp6 ^= cur; 570 + 603 571 It seems more efficient to also maintain a variable rp4_6 in the while 604 572 loop; This eliminates 3 statements per loop. Of course after the loop we 605 - need to correct by adding: 606 - rp4 ^= rp4_6; 607 - rp6 ^= rp4_6 573 + need to correct by adding:: 574 + 575 + rp4 ^= rp4_6; 576 + rp6 ^= rp4_6 577 + 608 578 Furthermore there are 4 sequential assignments to rp8. This can be 609 579 encoded slightly more efficiently by saving tmppar before those 4 lines 610 580 and later do rp8 = rp8 ^ tmppar ^ notrp8; ··· 620 582 Attempt 7 621 583 ========= 622 584 623 - The new code now looks like: 585 + The new code now looks like:: 624 586 625 587 for (i = 0; i < 4; i++) 626 588 { ··· 682 644 further there is still room to optimize the generation of the ecc codes. 683 645 We can simply calculate the total parity. If this is 0 then rp4 = rp5 684 646 etc. If the parity is 1, then rp4 = !rp5; 647 + 685 648 But if rp4 = rp5 we do not need rp5 etc. We can just write the even bits 686 - in the result byte and then do something like 649 + in the result byte and then do something like:: 650 + 687 651 code[0] |= (code[0] << 1); 652 + 688 653 Lets test this. 689 654 690 655 ··· 698 657 kind of other things, like having dedicated parity arrays to avoid the 699 658 shift after parity[rp7] << 7; No gain. 700 659 Change the lookup using the parity array by using shift operators (e.g. 701 - replace parity[rp7] << 7 with: 702 - rp7 ^= (rp7 << 4); 703 - rp7 ^= (rp7 << 2); 704 - rp7 ^= (rp7 << 1); 705 - rp7 &= 0x80; 660 + replace parity[rp7] << 7 with:: 661 + 662 + rp7 ^= (rp7 << 4); 663 + rp7 ^= (rp7 << 2); 664 + rp7 ^= (rp7 << 1); 665 + rp7 &= 0x80; 666 + 706 667 No gain. 707 668 708 669 The only marginal change was inverting the parity bits, so we can remove ··· 726 683 727 684 For correcting errors I again used the ST application note as a starter, 728 685 but I also peeked at the existing code. 686 + 729 687 The algorithm itself is pretty straightforward. Just xor the given and 730 688 the calculated ecc. If all bytes are 0 there is no problem. If 11 bits 731 689 are 1 we have one correctable bit error. If there is 1 bit 1, we have an 732 690 error in the given ecc code. 691 + 733 692 It proved to be fastest to do some table lookups. Performance gain 734 693 introduced by this is about a factor 2 on my system when a repair had to 735 694 be done, and 1% or so if no repair had to be done. 695 + 736 696 Code size increased from 330 bytes to 686 bytes for this function. 737 697 (gcc 4.2, -O3) 738 698 ··· 746 700 The gain when calculating the ecc is tremendous. Om my development hardware 747 701 a speedup of a factor of 18 for ecc calculation was achieved. On a test on an 748 702 embedded system with a MIPS core a factor 7 was obtained. 703 + 749 704 On a test with a Linksys NSLU2 (ARMv5TE processor) the speedup was a factor 750 705 5 (big endian mode, gcc 4.1.2, -O3) 706 + 751 707 For correction not much gain could be obtained (as bitflips are rare). Then 752 708 again there are also much less cycles spent there. 753 709 ··· 759 711 this is very tricky (at least for intel hw). 760 712 761 713 Author: Frans Meulenbroeks 714 + 762 715 Copyright (C) 2008 Koninklijke Philips Electronics NV.
+4 -3
Documentation/mtd/spi-nor.txt Documentation/mtd/spi-nor.rst
··· 1 - SPI NOR framework 2 - ============================================ 1 + ================= 2 + SPI NOR framework 3 + ================= 3 4 4 5 Part I - Why do we need this framework? 5 6 --------------------------------------- ··· 24 23 With this new layer, the SPI NOR controller driver does not depend on the 25 24 m25p80 code anymore. 26 25 27 - Before this framework, the layer is like: 26 + Before this framework, the layer is like:: 28 27 29 28 MTD 30 29 ------------------------
+1 -1
drivers/mtd/nand/raw/nand_ecc.c
··· 11 11 * Thomas Gleixner (tglx@linutronix.de) 12 12 * 13 13 * Information on how this algorithm works and how it was developed 14 - * can be found in Documentation/mtd/nand_ecc.txt 14 + * can be found in Documentation/mtd/nand_ecc.rst 15 15 */ 16 16 17 17 #include <linux/types.h>