base-files: define yes/no as valid boolean options
[openwrt/staging/mkresin.git] / target / linux / mvebu / patches-3.10 / 0153-mtd-nand-pxa3xx-Add-ECC-BCH-correctable-errors-detec.patch
1 From 26d82e0081aa6f0c7db5e4bb5b154b7c528cb8d6 Mon Sep 17 00:00:00 2001
2 From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
3 Date: Thu, 14 Nov 2013 18:25:39 -0300
4 Subject: [PATCH 153/203] mtd: nand: pxa3xx: Add ECC BCH correctable errors
5 detection
6
7 This commit extends the ECC correctable error detection to include
8 ECC BCH errors. The number of BCH correctable errors can be any up to 16,
9 and the actual value is exposed in the NDSR register.
10
11 Therefore, we change some symbol names to refer to correctable or
12 uncorrectable (instead of single-bit or double-bit as it was in the
13 Hamming case) and while at it, cleanup the detection code slightly.
14
15 Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
16 Tested-by: Daniel Mack <zonque@gmail.com>
17 Signed-off-by: Brian Norris <computersforpeace@gmail.com>
18 ---
19 drivers/mtd/nand/pxa3xx_nand.c | 57 ++++++++++++++++++++++++++----------------
20 1 file changed, 35 insertions(+), 22 deletions(-)
21
22 --- a/drivers/mtd/nand/pxa3xx_nand.c
23 +++ b/drivers/mtd/nand/pxa3xx_nand.c
24 @@ -85,6 +85,9 @@
25 #define NDCR_INT_MASK (0xFFF)
26
27 #define NDSR_MASK (0xfff)
28 +#define NDSR_ERR_CNT_OFF (16)
29 +#define NDSR_ERR_CNT_MASK (0x1f)
30 +#define NDSR_ERR_CNT(sr) ((sr >> NDSR_ERR_CNT_OFF) & NDSR_ERR_CNT_MASK)
31 #define NDSR_RDY (0x1 << 12)
32 #define NDSR_FLASH_RDY (0x1 << 11)
33 #define NDSR_CS0_PAGED (0x1 << 10)
34 @@ -93,8 +96,8 @@
35 #define NDSR_CS1_CMDD (0x1 << 7)
36 #define NDSR_CS0_BBD (0x1 << 6)
37 #define NDSR_CS1_BBD (0x1 << 5)
38 -#define NDSR_DBERR (0x1 << 4)
39 -#define NDSR_SBERR (0x1 << 3)
40 +#define NDSR_UNCORERR (0x1 << 4)
41 +#define NDSR_CORERR (0x1 << 3)
42 #define NDSR_WRDREQ (0x1 << 2)
43 #define NDSR_RDDREQ (0x1 << 1)
44 #define NDSR_WRCMDREQ (0x1)
45 @@ -135,9 +138,9 @@ enum {
46 ERR_NONE = 0,
47 ERR_DMABUSERR = -1,
48 ERR_SENDCMD = -2,
49 - ERR_DBERR = -3,
50 + ERR_UNCORERR = -3,
51 ERR_BBERR = -4,
52 - ERR_SBERR = -5,
53 + ERR_CORERR = -5,
54 };
55
56 enum {
57 @@ -221,6 +224,8 @@ struct pxa3xx_nand_info {
58 unsigned int oob_size;
59 unsigned int spare_size;
60 unsigned int ecc_size;
61 + unsigned int ecc_err_cnt;
62 + unsigned int max_bitflips;
63 int retcode;
64
65 /* cached register value */
66 @@ -571,10 +576,25 @@ static irqreturn_t pxa3xx_nand_irq(int i
67
68 status = nand_readl(info, NDSR);
69
70 - if (status & NDSR_DBERR)
71 - info->retcode = ERR_DBERR;
72 - if (status & NDSR_SBERR)
73 - info->retcode = ERR_SBERR;
74 + if (status & NDSR_UNCORERR)
75 + info->retcode = ERR_UNCORERR;
76 + if (status & NDSR_CORERR) {
77 + info->retcode = ERR_CORERR;
78 + if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 &&
79 + info->ecc_bch)
80 + info->ecc_err_cnt = NDSR_ERR_CNT(status);
81 + else
82 + info->ecc_err_cnt = 1;
83 +
84 + /*
85 + * Each chunk composing a page is corrected independently,
86 + * and we need to store maximum number of corrected bitflips
87 + * to return it to the MTD layer in ecc.read_page().
88 + */
89 + info->max_bitflips = max_t(unsigned int,
90 + info->max_bitflips,
91 + info->ecc_err_cnt);
92 + }
93 if (status & (NDSR_RDDREQ | NDSR_WRDREQ)) {
94 /* whether use dma to transfer data */
95 if (info->use_dma) {
96 @@ -672,6 +692,7 @@ static void prepare_start_command(struct
97 info->use_ecc = 0;
98 info->use_spare = 1;
99 info->retcode = ERR_NONE;
100 + info->ecc_err_cnt = 0;
101 info->ndcb3 = 0;
102
103 switch (command) {
104 @@ -1053,26 +1074,18 @@ static int pxa3xx_nand_read_page_hwecc(s
105 {
106 struct pxa3xx_nand_host *host = mtd->priv;
107 struct pxa3xx_nand_info *info = host->info_data;
108 - int max_bitflips = 0;
109
110 chip->read_buf(mtd, buf, mtd->writesize);
111 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
112
113 - if (info->retcode == ERR_SBERR) {
114 - switch (info->use_ecc) {
115 - case 1:
116 - max_bitflips = 1;
117 - mtd->ecc_stats.corrected++;
118 - break;
119 - case 0:
120 - default:
121 - break;
122 - }
123 - } else if (info->retcode == ERR_DBERR) {
124 + if (info->retcode == ERR_CORERR && info->use_ecc) {
125 + mtd->ecc_stats.corrected += info->ecc_err_cnt;
126 +
127 + } else if (info->retcode == ERR_UNCORERR) {
128 /*
129 * for blank page (all 0xff), HW will calculate its ECC as
130 * 0, which is different from the ECC information within
131 - * OOB, ignore such double bit errors
132 + * OOB, ignore such uncorrectable errors
133 */
134 if (is_buf_blank(buf, mtd->writesize))
135 info->retcode = ERR_NONE;
136 @@ -1080,7 +1093,7 @@ static int pxa3xx_nand_read_page_hwecc(s
137 mtd->ecc_stats.failed++;
138 }
139
140 - return max_bitflips;
141 + return info->max_bitflips;
142 }
143
144 static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd)