]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/mtd/nand/nand_hynix.c
mtd: nand: hynix: Rework NAND ID decoding to extract more information
[karo-tx-linux.git] / drivers / mtd / nand / nand_hynix.c
1 /*
2  * Copyright (C) 2017 Free Electrons
3  * Copyright (C) 2017 NextThing Co
4  *
5  * Author: Boris Brezillon <boris.brezillon@free-electrons.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  */
17
18 #include <linux/mtd/nand.h>
19 #include <linux/sizes.h>
20
21 static bool hynix_nand_has_valid_jedecid(struct nand_chip *chip)
22 {
23         struct mtd_info *mtd = nand_to_mtd(chip);
24         u8 jedecid[6] = { };
25         int i = 0;
26
27         chip->cmdfunc(mtd, NAND_CMD_READID, 0x40, -1);
28         for (i = 0; i < 5; i++)
29                 jedecid[i] = chip->read_byte(mtd);
30
31         return !strcmp("JEDEC", jedecid);
32 }
33
34 static void hynix_nand_extract_oobsize(struct nand_chip *chip,
35                                        bool valid_jedecid)
36 {
37         struct mtd_info *mtd = nand_to_mtd(chip);
38         u8 oobsize;
39
40         oobsize = ((chip->id.data[3] >> 2) & 0x3) |
41                   ((chip->id.data[3] >> 4) & 0x4);
42
43         if (valid_jedecid) {
44                 switch (oobsize) {
45                 case 0:
46                         mtd->oobsize = 2048;
47                         break;
48                 case 1:
49                         mtd->oobsize = 1664;
50                         break;
51                 case 2:
52                         mtd->oobsize = 1024;
53                         break;
54                 case 3:
55                         mtd->oobsize = 640;
56                         break;
57                 default:
58                         /*
59                          * We should never reach this case, but if that
60                          * happens, this probably means Hynix decided to use
61                          * a different extended ID format, and we should find
62                          * a way to support it.
63                          */
64                         WARN(1, "Invalid OOB size");
65                         break;
66                 }
67         } else {
68                 switch (oobsize) {
69                 case 0:
70                         mtd->oobsize = 128;
71                         break;
72                 case 1:
73                         mtd->oobsize = 224;
74                         break;
75                 case 2:
76                         mtd->oobsize = 448;
77                         break;
78                 case 3:
79                         mtd->oobsize = 64;
80                         break;
81                 case 4:
82                         mtd->oobsize = 32;
83                         break;
84                 case 5:
85                         mtd->oobsize = 16;
86                         break;
87                 case 6:
88                         mtd->oobsize = 640;
89                         break;
90                 default:
91                         /*
92                          * We should never reach this case, but if that
93                          * happens, this probably means Hynix decided to use
94                          * a different extended ID format, and we should find
95                          * a way to support it.
96                          */
97                         WARN(1, "Invalid OOB size");
98                         break;
99                 }
100         }
101 }
102
103 static void hynix_nand_extract_ecc_requirements(struct nand_chip *chip,
104                                                 bool valid_jedecid)
105 {
106         u8 ecc_level = (chip->id.data[4] >> 4) & 0x7;
107
108         if (valid_jedecid) {
109                 /* Reference: H27UCG8T2E datasheet */
110                 chip->ecc_step_ds = 1024;
111
112                 switch (ecc_level) {
113                 case 0:
114                         chip->ecc_step_ds = 0;
115                         chip->ecc_strength_ds = 0;
116                         break;
117                 case 1:
118                         chip->ecc_strength_ds = 4;
119                         break;
120                 case 2:
121                         chip->ecc_strength_ds = 24;
122                         break;
123                 case 3:
124                         chip->ecc_strength_ds = 32;
125                         break;
126                 case 4:
127                         chip->ecc_strength_ds = 40;
128                         break;
129                 case 5:
130                         chip->ecc_strength_ds = 50;
131                         break;
132                 case 6:
133                         chip->ecc_strength_ds = 60;
134                         break;
135                 default:
136                         /*
137                          * We should never reach this case, but if that
138                          * happens, this probably means Hynix decided to use
139                          * a different extended ID format, and we should find
140                          * a way to support it.
141                          */
142                         WARN(1, "Invalid ECC requirements");
143                 }
144         } else {
145                 /*
146                  * The ECC requirements field meaning depends on the
147                  * NAND technology.
148                  */
149                 u8 nand_tech = chip->id.data[5] & 0x3;
150
151                 if (nand_tech < 3) {
152                         /* > 26nm, reference: H27UBG8T2A datasheet */
153                         if (ecc_level < 5) {
154                                 chip->ecc_step_ds = 512;
155                                 chip->ecc_strength_ds = 1 << ecc_level;
156                         } else if (ecc_level < 7) {
157                                 if (ecc_level == 5)
158                                         chip->ecc_step_ds = 2048;
159                                 else
160                                         chip->ecc_step_ds = 1024;
161                                 chip->ecc_strength_ds = 24;
162                         } else {
163                                 /*
164                                  * We should never reach this case, but if that
165                                  * happens, this probably means Hynix decided
166                                  * to use a different extended ID format, and
167                                  * we should find a way to support it.
168                                  */
169                                 WARN(1, "Invalid ECC requirements");
170                         }
171                 } else {
172                         /* <= 26nm, reference: H27UBG8T2B datasheet */
173                         if (!ecc_level) {
174                                 chip->ecc_step_ds = 0;
175                                 chip->ecc_strength_ds = 0;
176                         } else if (ecc_level < 5) {
177                                 chip->ecc_step_ds = 512;
178                                 chip->ecc_strength_ds = 1 << (ecc_level - 1);
179                         } else {
180                                 chip->ecc_step_ds = 1024;
181                                 chip->ecc_strength_ds = 24 +
182                                                         (8 * (ecc_level - 5));
183                         }
184                 }
185         }
186 }
187
188 static void hynix_nand_extract_scrambling_requirements(struct nand_chip *chip,
189                                                        bool valid_jedecid)
190 {
191         u8 nand_tech;
192
193         /* We need scrambling on all TLC NANDs*/
194         if (chip->bits_per_cell > 2)
195                 chip->options |= NAND_NEED_SCRAMBLING;
196
197         /* And on MLC NANDs with sub-3xnm process */
198         if (valid_jedecid) {
199                 nand_tech = chip->id.data[5] >> 4;
200
201                 /* < 3xnm */
202                 if (nand_tech > 0)
203                         chip->options |= NAND_NEED_SCRAMBLING;
204         } else {
205                 nand_tech = chip->id.data[5] & 0x3;
206
207                 /* < 32nm */
208                 if (nand_tech > 2)
209                         chip->options |= NAND_NEED_SCRAMBLING;
210         }
211 }
212
213 static void hynix_nand_decode_id(struct nand_chip *chip)
214 {
215         struct mtd_info *mtd = nand_to_mtd(chip);
216         bool valid_jedecid;
217         u8 tmp;
218
219         /*
220          * Exclude all SLC NANDs from this advanced detection scheme.
221          * According to the ranges defined in several datasheets, it might
222          * appear that even SLC NANDs could fall in this extended ID scheme.
223          * If that the case rework the test to let SLC NANDs go through the
224          * detection process.
225          */
226         if (chip->id.len < 6 || nand_is_slc(chip)) {
227                 nand_decode_ext_id(chip);
228                 return;
229         }
230
231         /* Extract pagesize */
232         mtd->writesize = 2048 << (chip->id.data[3] & 0x03);
233
234         tmp = (chip->id.data[3] >> 4) & 0x3;
235         /*
236          * When bit7 is set that means we start counting at 1MiB, otherwise
237          * we start counting at 128KiB and shift this value the content of
238          * ID[3][4:5].
239          * The only exception is when ID[3][4:5] == 3 and ID[3][7] == 0, in
240          * this case the erasesize is set to 768KiB.
241          */
242         if (chip->id.data[3] & 0x80)
243                 mtd->erasesize = SZ_1M << tmp;
244         else if (tmp == 3)
245                 mtd->erasesize = SZ_512K + SZ_256K;
246         else
247                 mtd->erasesize = SZ_128K << tmp;
248
249         /*
250          * Modern Toggle DDR NANDs have a valid JEDECID even though they are
251          * not exposing a valid JEDEC parameter table.
252          * These NANDs use a different NAND ID scheme.
253          */
254         valid_jedecid = hynix_nand_has_valid_jedecid(chip);
255
256         hynix_nand_extract_oobsize(chip, valid_jedecid);
257         hynix_nand_extract_ecc_requirements(chip, valid_jedecid);
258         hynix_nand_extract_scrambling_requirements(chip, valid_jedecid);
259 }
260
261 static int hynix_nand_init(struct nand_chip *chip)
262 {
263         if (!nand_is_slc(chip))
264                 chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
265         else
266                 chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
267
268         return 0;
269 }
270
271 const struct nand_manufacturer_ops hynix_nand_manuf_ops = {
272         .detect = hynix_nand_decode_id,
273         .init = hynix_nand_init,
274 };