forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/mtd/nand/raw/nand_ecc.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * This file contains an ECC algorithm that detects and corrects 1 bit
34 * errors in a 256 byte block of data.
....@@ -10,22 +11,7 @@
1011 * Thomas Gleixner (tglx@linutronix.de)
1112 *
1213 * Information on how this algorithm works and how it was developed
13
- * can be found in Documentation/mtd/nand_ecc.txt
14
- *
15
- * This file is free software; you can redistribute it and/or modify it
16
- * under the terms of the GNU General Public License as published by the
17
- * Free Software Foundation; either version 2 or (at your option) any
18
- * later version.
19
- *
20
- * This file is distributed in the hope that it will be useful, but WITHOUT
21
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23
- * for more details.
24
- *
25
- * You should have received a copy of the GNU General Public License along
26
- * with this file; if not, write to the Free Software Foundation, Inc.,
27
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
28
- *
14
+ * can be found in Documentation/driver-api/mtd/nand_ecc.rst
2915 */
3016
3117 #include <linux/types.h>
....@@ -132,9 +118,10 @@
132118 * @buf: input buffer with raw data
133119 * @eccsize: data bytes per ECC step (256 or 512)
134120 * @code: output buffer with ECC
121
+ * @sm_order: Smart Media byte ordering
135122 */
136123 void __nand_calculate_ecc(const unsigned char *buf, unsigned int eccsize,
137
- unsigned char *code)
124
+ unsigned char *code, bool sm_order)
138125 {
139126 int i;
140127 const uint32_t *bp = (uint32_t *)buf;
....@@ -144,7 +131,7 @@
144131 /* rp0..rp15..rp17 are the various accumulated parities (per byte) */
145132 uint32_t rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7;
146133 uint32_t rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15, rp16;
147
- uint32_t uninitialized_var(rp17); /* to make compiler happy */
134
+ uint32_t rp17;
148135 uint32_t par; /* the cumulative parity for all data */
149136 uint32_t tmppar; /* the cumulative parity for this iteration;
150137 for rp12, rp14 and rp16 at the end of the
....@@ -330,45 +317,26 @@
330317 * possible, but benchmarks showed that on the system this is developed
331318 * the code below is the fastest
332319 */
333
-#ifdef CONFIG_MTD_NAND_ECC_SMC
334
- code[0] =
335
- (invparity[rp7] << 7) |
336
- (invparity[rp6] << 6) |
337
- (invparity[rp5] << 5) |
338
- (invparity[rp4] << 4) |
339
- (invparity[rp3] << 3) |
340
- (invparity[rp2] << 2) |
341
- (invparity[rp1] << 1) |
342
- (invparity[rp0]);
343
- code[1] =
344
- (invparity[rp15] << 7) |
345
- (invparity[rp14] << 6) |
346
- (invparity[rp13] << 5) |
347
- (invparity[rp12] << 4) |
348
- (invparity[rp11] << 3) |
349
- (invparity[rp10] << 2) |
350
- (invparity[rp9] << 1) |
351
- (invparity[rp8]);
352
-#else
353
- code[1] =
354
- (invparity[rp7] << 7) |
355
- (invparity[rp6] << 6) |
356
- (invparity[rp5] << 5) |
357
- (invparity[rp4] << 4) |
358
- (invparity[rp3] << 3) |
359
- (invparity[rp2] << 2) |
360
- (invparity[rp1] << 1) |
361
- (invparity[rp0]);
362
- code[0] =
363
- (invparity[rp15] << 7) |
364
- (invparity[rp14] << 6) |
365
- (invparity[rp13] << 5) |
366
- (invparity[rp12] << 4) |
367
- (invparity[rp11] << 3) |
368
- (invparity[rp10] << 2) |
369
- (invparity[rp9] << 1) |
370
- (invparity[rp8]);
371
-#endif
320
+ if (sm_order) {
321
+ code[0] = (invparity[rp7] << 7) | (invparity[rp6] << 6) |
322
+ (invparity[rp5] << 5) | (invparity[rp4] << 4) |
323
+ (invparity[rp3] << 3) | (invparity[rp2] << 2) |
324
+ (invparity[rp1] << 1) | (invparity[rp0]);
325
+ code[1] = (invparity[rp15] << 7) | (invparity[rp14] << 6) |
326
+ (invparity[rp13] << 5) | (invparity[rp12] << 4) |
327
+ (invparity[rp11] << 3) | (invparity[rp10] << 2) |
328
+ (invparity[rp9] << 1) | (invparity[rp8]);
329
+ } else {
330
+ code[1] = (invparity[rp7] << 7) | (invparity[rp6] << 6) |
331
+ (invparity[rp5] << 5) | (invparity[rp4] << 4) |
332
+ (invparity[rp3] << 3) | (invparity[rp2] << 2) |
333
+ (invparity[rp1] << 1) | (invparity[rp0]);
334
+ code[0] = (invparity[rp15] << 7) | (invparity[rp14] << 6) |
335
+ (invparity[rp13] << 5) | (invparity[rp12] << 4) |
336
+ (invparity[rp11] << 3) | (invparity[rp10] << 2) |
337
+ (invparity[rp9] << 1) | (invparity[rp8]);
338
+ }
339
+
372340 if (eccsize_mult == 1)
373341 code[2] =
374342 (invparity[par & 0xf0] << 7) |
....@@ -394,15 +362,16 @@
394362 /**
395363 * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256/512-byte
396364 * block
397
- * @mtd: MTD block structure
365
+ * @chip: NAND chip object
398366 * @buf: input buffer with raw data
399367 * @code: output buffer with ECC
400368 */
401
-int nand_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf,
369
+int nand_calculate_ecc(struct nand_chip *chip, const unsigned char *buf,
402370 unsigned char *code)
403371 {
404
- __nand_calculate_ecc(buf,
405
- mtd_to_nand(mtd)->ecc.size, code);
372
+ bool sm_order = chip->ecc.options & NAND_ECC_SOFT_HAMMING_SM_ORDER;
373
+
374
+ __nand_calculate_ecc(buf, chip->ecc.size, code, sm_order);
406375
407376 return 0;
408377 }
....@@ -414,12 +383,13 @@
414383 * @read_ecc: ECC from the chip
415384 * @calc_ecc: the ECC calculated from raw data
416385 * @eccsize: data bytes per ECC step (256 or 512)
386
+ * @sm_order: Smart Media byte order
417387 *
418388 * Detect and correct a 1 bit error for eccsize byte block
419389 */
420390 int __nand_correct_data(unsigned char *buf,
421391 unsigned char *read_ecc, unsigned char *calc_ecc,
422
- unsigned int eccsize)
392
+ unsigned int eccsize, bool sm_order)
423393 {
424394 unsigned char b0, b1, b2, bit_addr;
425395 unsigned int byte_addr;
....@@ -431,13 +401,14 @@
431401 * we might need the xor result more than once,
432402 * so keep them in a local var
433403 */
434
-#ifdef CONFIG_MTD_NAND_ECC_SMC
435
- b0 = read_ecc[0] ^ calc_ecc[0];
436
- b1 = read_ecc[1] ^ calc_ecc[1];
437
-#else
438
- b0 = read_ecc[1] ^ calc_ecc[1];
439
- b1 = read_ecc[0] ^ calc_ecc[0];
440
-#endif
404
+ if (sm_order) {
405
+ b0 = read_ecc[0] ^ calc_ecc[0];
406
+ b1 = read_ecc[1] ^ calc_ecc[1];
407
+ } else {
408
+ b0 = read_ecc[1] ^ calc_ecc[1];
409
+ b1 = read_ecc[0] ^ calc_ecc[0];
410
+ }
411
+
441412 b2 = read_ecc[2] ^ calc_ecc[2];
442413
443414 /* check if there are any bitfaults */
....@@ -491,18 +462,20 @@
491462
492463 /**
493464 * nand_correct_data - [NAND Interface] Detect and correct bit error(s)
494
- * @mtd: MTD block structure
465
+ * @chip: NAND chip object
495466 * @buf: raw data read from the chip
496467 * @read_ecc: ECC from the chip
497468 * @calc_ecc: the ECC calculated from raw data
498469 *
499470 * Detect and correct a 1 bit error for 256/512 byte block
500471 */
501
-int nand_correct_data(struct mtd_info *mtd, unsigned char *buf,
472
+int nand_correct_data(struct nand_chip *chip, unsigned char *buf,
502473 unsigned char *read_ecc, unsigned char *calc_ecc)
503474 {
504
- return __nand_correct_data(buf, read_ecc, calc_ecc,
505
- mtd_to_nand(mtd)->ecc.size);
475
+ bool sm_order = chip->ecc.options & NAND_ECC_SOFT_HAMMING_SM_ORDER;
476
+
477
+ return __nand_correct_data(buf, read_ecc, calc_ecc, chip->ecc.size,
478
+ sm_order);
506479 }
507480 EXPORT_SYMBOL(nand_correct_data);
508481