blob: 57c4ed894dfb5b2f90c1fdb2b30f0cf3ba7de779 [file] [log] [blame]
Boris Brezillon01389b62016-06-08 10:30:18 +02001/*
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>
Boris Brezillon78f34822016-05-27 14:36:36 +020019#include <linux/sizes.h>
Boris Brezillon01389b62016-06-08 10:30:18 +020020
Boris Brezillon78f34822016-05-27 14:36:36 +020021static bool hynix_nand_has_valid_jedecid(struct nand_chip *chip)
Boris Brezillon01389b62016-06-08 10:30:18 +020022{
23 struct mtd_info *mtd = nand_to_mtd(chip);
Boris Brezillon78f34822016-05-27 14:36:36 +020024 u8 jedecid[6] = { };
25 int i = 0;
Boris Brezillon01389b62016-06-08 10:30:18 +020026
Boris Brezillon78f34822016-05-27 14:36:36 +020027 chip->cmdfunc(mtd, NAND_CMD_READID, 0x40, -1);
28 for (i = 0; i < 5; i++)
29 jedecid[i] = chip->read_byte(mtd);
Boris Brezillon01389b62016-06-08 10:30:18 +020030
Boris Brezillon78f34822016-05-27 14:36:36 +020031 return !strcmp("JEDEC", jedecid);
32}
Boris Brezillon01389b62016-06-08 10:30:18 +020033
Boris Brezillon78f34822016-05-27 14:36:36 +020034static 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) {
Boris Brezillon01389b62016-06-08 10:30:18 +020069 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;
Boris Brezillon78f34822016-05-27 14:36:36 +020087 case 6:
Boris Brezillon01389b62016-06-08 10:30:18 +020088 mtd->oobsize = 640;
89 break;
Boris Brezillon78f34822016-05-27 14:36:36 +020090 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;
Boris Brezillon01389b62016-06-08 10:30:18 +020099 }
Boris Brezillon01389b62016-06-08 10:30:18 +0200100 }
101}
102
Boris Brezillon78f34822016-05-27 14:36:36 +0200103static 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
188static 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
213static 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
Boris Brezillon01389b62016-06-08 10:30:18 +0200261static 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
271const struct nand_manufacturer_ops hynix_nand_manuf_ops = {
272 .detect = hynix_nand_decode_id,
273 .init = hynix_nand_init,
274};