blob: 1a5505ccbe54b24c7c6d46f727951666049db650 [file] [log] [blame]
Boris Brezillon10d4e752016-06-08 10:38:57 +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
Boris Brezillond4092d72017-08-04 17:29:10 +020018#include <linux/mtd/rawnand.h>
Boris Brezillon23017802018-07-18 10:42:19 +020019#include <linux/slab.h>
Boris Brezillon10d4e752016-06-08 10:38:57 +020020
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +020021/*
Chris Packham3ec7cb32018-07-18 10:42:16 +020022 * Special Micron status bit 3 indicates that the block has been
23 * corrected by on-die ECC and should be rewritten.
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +020024 */
Chris Packham3ec7cb32018-07-18 10:42:16 +020025#define NAND_ECC_STATUS_WRITE_RECOMMENDED BIT(3)
26
27/*
28 * On chips with 8-bit ECC and additional bit can be used to distinguish
29 * cases where a errors were corrected without needing a rewrite
30 *
31 * Bit 4 Bit 3 Bit 0 Description
32 * ----- ----- ----- -----------
33 * 0 0 0 No Errors
34 * 0 0 1 Multiple uncorrected errors
35 * 0 1 0 4 - 6 errors corrected, recommend rewrite
36 * 0 1 1 Reserved
37 * 1 0 0 1 - 3 errors corrected
38 * 1 0 1 Reserved
39 * 1 1 0 7 - 8 errors corrected, recommend rewrite
40 */
41#define NAND_ECC_STATUS_MASK (BIT(4) | BIT(3) | BIT(0))
42#define NAND_ECC_STATUS_UNCORRECTABLE BIT(0)
43#define NAND_ECC_STATUS_4_6_CORRECTED BIT(3)
44#define NAND_ECC_STATUS_1_3_CORRECTED BIT(4)
45#define NAND_ECC_STATUS_7_8_CORRECTED (BIT(4) | BIT(3))
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +020046
Boris Brezillon10d4e752016-06-08 10:38:57 +020047struct nand_onfi_vendor_micron {
48 u8 two_plane_read;
49 u8 read_cache;
50 u8 read_unique_id;
51 u8 dq_imped;
52 u8 dq_imped_num_settings;
53 u8 dq_imped_feat_addr;
54 u8 rb_pulldown_strength;
55 u8 rb_pulldown_strength_feat_addr;
56 u8 rb_pulldown_strength_num_settings;
57 u8 otp_mode;
58 u8 otp_page_start;
59 u8 otp_data_prot_addr;
60 u8 otp_num_pages;
61 u8 otp_feat_addr;
62 u8 read_retry_options;
63 u8 reserved[72];
64 u8 param_revision;
65} __packed;
66
Boris Brezillon23017802018-07-18 10:42:19 +020067struct micron_on_die_ecc {
Boris Brezillonef422e12018-07-18 10:42:20 +020068 bool forced;
Boris Brezillon317c6d92018-07-18 10:42:21 +020069 bool enabled;
Boris Brezillon23017802018-07-18 10:42:19 +020070 void *rawbuf;
71};
72
73struct micron_nand {
74 struct micron_on_die_ecc ecc;
75};
76
Boris Brezillon2e7f1ce2018-09-06 14:05:32 +020077static int micron_nand_setup_read_retry(struct nand_chip *chip, int retry_mode)
Boris Brezillon10d4e752016-06-08 10:38:57 +020078{
Boris Brezillon10d4e752016-06-08 10:38:57 +020079 u8 feature[ONFI_SUBFEATURE_PARAM_LEN] = {retry_mode};
80
Miquel Raynal97baea12018-03-19 14:47:20 +010081 return nand_set_features(chip, ONFI_FEATURE_ADDR_READ_RETRY, feature);
Boris Brezillon10d4e752016-06-08 10:38:57 +020082}
83
84/*
85 * Configure chip properties from Micron vendor-specific ONFI table
86 */
87static int micron_nand_onfi_init(struct nand_chip *chip)
88{
Miquel Raynala97421c2018-03-19 14:47:27 +010089 struct nand_parameters *p = &chip->parameters;
Boris Brezillon10d4e752016-06-08 10:38:57 +020090
Miquel Raynal3d3fe3c2018-07-25 15:31:52 +020091 if (p->onfi) {
92 struct nand_onfi_vendor_micron *micron = (void *)p->onfi->vendor;
93
Miquel Raynala97421c2018-03-19 14:47:27 +010094 chip->read_retries = micron->read_retry_options;
95 chip->setup_read_retry = micron_nand_setup_read_retry;
96 }
Boris Brezillon10d4e752016-06-08 10:38:57 +020097
Miquel Raynal789157e2018-03-19 14:47:28 +010098 if (p->supports_set_get_features) {
99 set_bit(ONFI_FEATURE_ADDR_READ_RETRY, p->set_feature_list);
Chris Packham12baf772018-06-19 17:31:24 +1200100 set_bit(ONFI_FEATURE_ON_DIE_ECC, p->set_feature_list);
Miquel Raynal789157e2018-03-19 14:47:28 +0100101 set_bit(ONFI_FEATURE_ADDR_READ_RETRY, p->get_feature_list);
Chris Packham12baf772018-06-19 17:31:24 +1200102 set_bit(ONFI_FEATURE_ON_DIE_ECC, p->get_feature_list);
Miquel Raynal789157e2018-03-19 14:47:28 +0100103 }
Boris Brezillon10d4e752016-06-08 10:38:57 +0200104
105 return 0;
106}
107
Chris Packham3ec7cb32018-07-18 10:42:16 +0200108static int micron_nand_on_die_4_ooblayout_ecc(struct mtd_info *mtd,
109 int section,
110 struct mtd_oob_region *oobregion)
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200111{
112 if (section >= 4)
113 return -ERANGE;
114
115 oobregion->offset = (section * 16) + 8;
116 oobregion->length = 8;
117
118 return 0;
119}
120
Chris Packham3ec7cb32018-07-18 10:42:16 +0200121static int micron_nand_on_die_4_ooblayout_free(struct mtd_info *mtd,
122 int section,
123 struct mtd_oob_region *oobregion)
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200124{
125 if (section >= 4)
126 return -ERANGE;
127
128 oobregion->offset = (section * 16) + 2;
129 oobregion->length = 6;
130
131 return 0;
132}
133
Chris Packham3ec7cb32018-07-18 10:42:16 +0200134static const struct mtd_ooblayout_ops micron_nand_on_die_4_ooblayout_ops = {
135 .ecc = micron_nand_on_die_4_ooblayout_ecc,
136 .free = micron_nand_on_die_4_ooblayout_free,
137};
138
139static int micron_nand_on_die_8_ooblayout_ecc(struct mtd_info *mtd,
140 int section,
141 struct mtd_oob_region *oobregion)
142{
143 struct nand_chip *chip = mtd_to_nand(mtd);
144
145 if (section)
146 return -ERANGE;
147
148 oobregion->offset = mtd->oobsize - chip->ecc.total;
149 oobregion->length = chip->ecc.total;
150
151 return 0;
152}
153
154static int micron_nand_on_die_8_ooblayout_free(struct mtd_info *mtd,
155 int section,
156 struct mtd_oob_region *oobregion)
157{
158 struct nand_chip *chip = mtd_to_nand(mtd);
159
160 if (section)
161 return -ERANGE;
162
163 oobregion->offset = 2;
164 oobregion->length = mtd->oobsize - chip->ecc.total - 2;
165
166 return 0;
167}
168
169static const struct mtd_ooblayout_ops micron_nand_on_die_8_ooblayout_ops = {
170 .ecc = micron_nand_on_die_8_ooblayout_ecc,
171 .free = micron_nand_on_die_8_ooblayout_free,
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200172};
173
174static int micron_nand_on_die_ecc_setup(struct nand_chip *chip, bool enable)
175{
Boris Brezillonef422e12018-07-18 10:42:20 +0200176 struct micron_nand *micron = nand_get_manufacturer_data(chip);
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200177 u8 feature[ONFI_SUBFEATURE_PARAM_LEN] = { 0, };
Boris Brezillon317c6d92018-07-18 10:42:21 +0200178 int ret;
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200179
Boris Brezillonef422e12018-07-18 10:42:20 +0200180 if (micron->ecc.forced)
181 return 0;
182
Boris Brezillon317c6d92018-07-18 10:42:21 +0200183 if (micron->ecc.enabled == enable)
184 return 0;
185
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200186 if (enable)
187 feature[0] |= ONFI_FEATURE_ON_DIE_ECC_EN;
188
Boris Brezillon317c6d92018-07-18 10:42:21 +0200189 ret = nand_set_features(chip, ONFI_FEATURE_ON_DIE_ECC, feature);
190 if (!ret)
191 micron->ecc.enabled = enable;
192
193 return ret;
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200194}
195
Boris Brezillon23017802018-07-18 10:42:19 +0200196static int micron_nand_on_die_ecc_status_4(struct nand_chip *chip, u8 status,
197 void *buf, int page,
198 int oob_required)
Chris Packham3ec7cb32018-07-18 10:42:16 +0200199{
Boris Brezillon23017802018-07-18 10:42:19 +0200200 struct micron_nand *micron = nand_get_manufacturer_data(chip);
Chris Packham3ec7cb32018-07-18 10:42:16 +0200201 struct mtd_info *mtd = nand_to_mtd(chip);
Boris Brezillon23017802018-07-18 10:42:19 +0200202 unsigned int step, max_bitflips = 0;
203 int ret;
Chris Packham3ec7cb32018-07-18 10:42:16 +0200204
Boris Brezillon23017802018-07-18 10:42:19 +0200205 if (!(status & NAND_ECC_STATUS_WRITE_RECOMMENDED)) {
206 if (status & NAND_STATUS_FAIL)
207 mtd->ecc_stats.failed++;
208
209 return 0;
Chris Packham3ec7cb32018-07-18 10:42:16 +0200210 }
211
Boris Brezillon23017802018-07-18 10:42:19 +0200212 /*
213 * The internal ECC doesn't tell us the number of bitflips that have
214 * been corrected, but tells us if it recommends to rewrite the block.
215 * If it's the case, we need to read the page in raw mode and compare
216 * its content to the corrected version to extract the actual number of
217 * bitflips.
218 * But before we do that, we must make sure we have all OOB bytes read
219 * in non-raw mode, even if the user did not request those bytes.
220 */
221 if (!oob_required) {
222 ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize,
223 false);
224 if (ret)
225 return ret;
226 }
227
228 micron_nand_on_die_ecc_setup(chip, false);
229
230 ret = nand_read_page_op(chip, page, 0, micron->ecc.rawbuf,
231 mtd->writesize + mtd->oobsize);
232 if (ret)
233 return ret;
234
235 for (step = 0; step < chip->ecc.steps; step++) {
236 unsigned int offs, i, nbitflips = 0;
237 u8 *rawbuf, *corrbuf;
238
239 offs = step * chip->ecc.size;
240 rawbuf = micron->ecc.rawbuf + offs;
241 corrbuf = buf + offs;
242
243 for (i = 0; i < chip->ecc.size; i++)
244 nbitflips += hweight8(corrbuf[i] ^ rawbuf[i]);
245
246 offs = (step * 16) + 4;
247 rawbuf = micron->ecc.rawbuf + mtd->writesize + offs;
248 corrbuf = chip->oob_poi + offs;
249
250 for (i = 0; i < chip->ecc.bytes + 4; i++)
251 nbitflips += hweight8(corrbuf[i] ^ rawbuf[i]);
252
253 if (WARN_ON(nbitflips > chip->ecc.strength))
254 return -EINVAL;
255
256 max_bitflips = max(nbitflips, max_bitflips);
257 mtd->ecc_stats.corrected += nbitflips;
258 }
259
260 return max_bitflips;
Chris Packham3ec7cb32018-07-18 10:42:16 +0200261}
262
263static int micron_nand_on_die_ecc_status_8(struct nand_chip *chip, u8 status)
264{
265 struct mtd_info *mtd = nand_to_mtd(chip);
266
267 /*
268 * With 8/512 we have more information but still don't know precisely
269 * how many bit-flips were seen.
270 */
271 switch (status & NAND_ECC_STATUS_MASK) {
272 case NAND_ECC_STATUS_UNCORRECTABLE:
273 mtd->ecc_stats.failed++;
274 return 0;
275 case NAND_ECC_STATUS_1_3_CORRECTED:
276 mtd->ecc_stats.corrected += 3;
277 return 3;
278 case NAND_ECC_STATUS_4_6_CORRECTED:
279 mtd->ecc_stats.corrected += 6;
280 /* rewrite recommended */
281 return 6;
282 case NAND_ECC_STATUS_7_8_CORRECTED:
283 mtd->ecc_stats.corrected += 8;
284 /* rewrite recommended */
285 return 8;
286 default:
287 return 0;
288 }
289}
290
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200291static int
Boris Brezillonb9761682018-09-06 14:05:20 +0200292micron_nand_read_page_on_die_ecc(struct nand_chip *chip, uint8_t *buf,
293 int oob_required, int page)
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200294{
Boris Brezillonb9761682018-09-06 14:05:20 +0200295 struct mtd_info *mtd = nand_to_mtd(chip);
Boris Brezillon97d90da2017-11-30 18:01:29 +0100296 u8 status;
297 int ret, max_bitflips = 0;
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200298
Boris Brezillon97d90da2017-11-30 18:01:29 +0100299 ret = micron_nand_on_die_ecc_setup(chip, true);
300 if (ret)
301 return ret;
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200302
Boris Brezillon97d90da2017-11-30 18:01:29 +0100303 ret = nand_read_page_op(chip, page, 0, NULL, 0);
304 if (ret)
305 goto out;
306
307 ret = nand_status_op(chip, &status);
308 if (ret)
309 goto out;
310
311 ret = nand_exit_status_op(chip);
312 if (ret)
313 goto out;
314
Boris Brezillon25f815f2017-11-30 18:01:30 +0100315 ret = nand_read_data_op(chip, buf, mtd->writesize, false);
316 if (!ret && oob_required)
317 ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize,
318 false);
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200319
Boris Brezillon23017802018-07-18 10:42:19 +0200320 if (chip->ecc.strength == 4)
321 max_bitflips = micron_nand_on_die_ecc_status_4(chip, status,
322 buf, page,
323 oob_required);
324 else
325 max_bitflips = micron_nand_on_die_ecc_status_8(chip, status);
326
Boris Brezillon97d90da2017-11-30 18:01:29 +0100327out:
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200328 micron_nand_on_die_ecc_setup(chip, false);
329
Boris Brezillon97d90da2017-11-30 18:01:29 +0100330 return ret ? ret : max_bitflips;
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200331}
332
333static int
Boris Brezillon767eb6f2018-09-06 14:05:21 +0200334micron_nand_write_page_on_die_ecc(struct nand_chip *chip, const uint8_t *buf,
335 int oob_required, int page)
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200336{
Boris Brezillon97d90da2017-11-30 18:01:29 +0100337 int ret;
Boris Brezillon41145642017-05-16 18:27:49 +0200338
Boris Brezillon97d90da2017-11-30 18:01:29 +0100339 ret = micron_nand_on_die_ecc_setup(chip, true);
340 if (ret)
341 return ret;
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200342
Boris Brezillon767eb6f2018-09-06 14:05:21 +0200343 ret = nand_write_page_raw(chip, buf, oob_required, page);
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200344 micron_nand_on_die_ecc_setup(chip, false);
345
Boris Brezillon97d90da2017-11-30 18:01:29 +0100346 return ret;
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200347}
348
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200349enum {
350 /* The NAND flash doesn't support on-die ECC */
351 MICRON_ON_DIE_UNSUPPORTED,
352
353 /*
354 * The NAND flash supports on-die ECC and it can be
355 * enabled/disabled by a set features command.
356 */
357 MICRON_ON_DIE_SUPPORTED,
358
359 /*
360 * The NAND flash supports on-die ECC, and it cannot be
361 * disabled.
362 */
363 MICRON_ON_DIE_MANDATORY,
364};
365
Boris Brezillondbc44ed2018-07-18 10:42:15 +0200366#define MICRON_ID_INTERNAL_ECC_MASK GENMASK(1, 0)
367#define MICRON_ID_ECC_ENABLED BIT(7)
368
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200369/*
370 * Try to detect if the NAND support on-die ECC. To do this, we enable
371 * the feature, and read back if it has been enabled as expected. We
372 * also check if it can be disabled, because some Micron NANDs do not
373 * allow disabling the on-die ECC and we don't support such NANDs for
374 * now.
375 *
376 * This function also has the side effect of disabling on-die ECC if
377 * it had been left enabled by the firmware/bootloader.
378 */
379static int micron_supports_on_die_ecc(struct nand_chip *chip)
380{
Boris Brezillondbc44ed2018-07-18 10:42:15 +0200381 u8 id[5];
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200382 int ret;
383
Miquel Raynal3d3fe3c2018-07-25 15:31:52 +0200384 if (!chip->parameters.onfi)
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200385 return MICRON_ON_DIE_UNSUPPORTED;
386
387 if (chip->bits_per_cell != 1)
388 return MICRON_ON_DIE_UNSUPPORTED;
389
Boris Brezillondbc44ed2018-07-18 10:42:15 +0200390 /*
391 * We only support on-die ECC of 4/512 or 8/512
392 */
393 if (chip->ecc_strength_ds != 4 && chip->ecc_strength_ds != 8)
394 return MICRON_ON_DIE_UNSUPPORTED;
395
396 /* 0x2 means on-die ECC is available. */
397 if (chip->id.len != 5 ||
398 (chip->id.data[4] & MICRON_ID_INTERNAL_ECC_MASK) != 0x2)
399 return MICRON_ON_DIE_UNSUPPORTED;
400
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200401 ret = micron_nand_on_die_ecc_setup(chip, true);
402 if (ret)
403 return MICRON_ON_DIE_UNSUPPORTED;
404
Boris Brezillondbc44ed2018-07-18 10:42:15 +0200405 ret = nand_readid_op(chip, 0, id, sizeof(id));
406 if (ret)
407 return MICRON_ON_DIE_UNSUPPORTED;
Miquel Raynal97baea12018-03-19 14:47:20 +0100408
Boris Brezillondbc44ed2018-07-18 10:42:15 +0200409 if (!(id[4] & MICRON_ID_ECC_ENABLED))
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200410 return MICRON_ON_DIE_UNSUPPORTED;
411
412 ret = micron_nand_on_die_ecc_setup(chip, false);
413 if (ret)
414 return MICRON_ON_DIE_UNSUPPORTED;
415
Boris Brezillondbc44ed2018-07-18 10:42:15 +0200416 ret = nand_readid_op(chip, 0, id, sizeof(id));
417 if (ret)
418 return MICRON_ON_DIE_UNSUPPORTED;
Miquel Raynal97baea12018-03-19 14:47:20 +0100419
Boris Brezillondbc44ed2018-07-18 10:42:15 +0200420 if (id[4] & MICRON_ID_ECC_ENABLED)
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200421 return MICRON_ON_DIE_MANDATORY;
422
423 /*
Chris Packham3ec7cb32018-07-18 10:42:16 +0200424 * We only support on-die ECC of 4/512 or 8/512
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200425 */
Chris Packham3ec7cb32018-07-18 10:42:16 +0200426 if (chip->ecc_strength_ds != 4 && chip->ecc_strength_ds != 8)
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200427 return MICRON_ON_DIE_UNSUPPORTED;
428
429 return MICRON_ON_DIE_SUPPORTED;
430}
431
Boris Brezillon10d4e752016-06-08 10:38:57 +0200432static int micron_nand_init(struct nand_chip *chip)
433{
434 struct mtd_info *mtd = nand_to_mtd(chip);
Boris Brezillon23017802018-07-18 10:42:19 +0200435 struct micron_nand *micron;
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200436 int ondie;
Boris Brezillon10d4e752016-06-08 10:38:57 +0200437 int ret;
438
Boris Brezillon23017802018-07-18 10:42:19 +0200439 micron = kzalloc(sizeof(*micron), GFP_KERNEL);
440 if (!micron)
441 return -ENOMEM;
442
443 nand_set_manufacturer_data(chip, micron);
444
Boris Brezillon10d4e752016-06-08 10:38:57 +0200445 ret = micron_nand_onfi_init(chip);
446 if (ret)
Boris Brezillon23017802018-07-18 10:42:19 +0200447 goto err_free_manuf_data;
Boris Brezillon10d4e752016-06-08 10:38:57 +0200448
449 if (mtd->writesize == 2048)
450 chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
451
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200452 ondie = micron_supports_on_die_ecc(chip);
453
Chris Packhamcb2bf402018-07-18 10:42:18 +0200454 if (ondie == MICRON_ON_DIE_MANDATORY &&
455 chip->ecc.mode != NAND_ECC_ON_DIE) {
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200456 pr_err("On-die ECC forcefully enabled, not supported\n");
Boris Brezillon23017802018-07-18 10:42:19 +0200457 ret = -EINVAL;
458 goto err_free_manuf_data;
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200459 }
460
461 if (chip->ecc.mode == NAND_ECC_ON_DIE) {
462 if (ondie == MICRON_ON_DIE_UNSUPPORTED) {
463 pr_err("On-die ECC selected but not supported\n");
Boris Brezillon23017802018-07-18 10:42:19 +0200464 ret = -EINVAL;
465 goto err_free_manuf_data;
466 }
467
Boris Brezillon317c6d92018-07-18 10:42:21 +0200468 if (ondie == MICRON_ON_DIE_MANDATORY) {
Boris Brezillonef422e12018-07-18 10:42:20 +0200469 micron->ecc.forced = true;
Boris Brezillon317c6d92018-07-18 10:42:21 +0200470 micron->ecc.enabled = true;
471 }
Boris Brezillonef422e12018-07-18 10:42:20 +0200472
Boris Brezillon23017802018-07-18 10:42:19 +0200473 /*
474 * In case of 4bit on-die ECC, we need a buffer to store a
475 * page dumped in raw mode so that we can compare its content
476 * to the same page after ECC correction happened and extract
477 * the real number of bitflips from this comparison.
478 * That's not needed for 8-bit ECC, because the status expose
479 * a better approximation of the number of bitflips in a page.
480 */
481 if (chip->ecc_strength_ds == 4) {
482 micron->ecc.rawbuf = kmalloc(mtd->writesize +
483 mtd->oobsize,
484 GFP_KERNEL);
485 if (!micron->ecc.rawbuf) {
486 ret = -ENOMEM;
487 goto err_free_manuf_data;
488 }
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200489 }
490
Chris Packham3ec7cb32018-07-18 10:42:16 +0200491 if (chip->ecc_strength_ds == 4)
492 mtd_set_ooblayout(mtd,
493 &micron_nand_on_die_4_ooblayout_ops);
494 else
495 mtd_set_ooblayout(mtd,
496 &micron_nand_on_die_8_ooblayout_ops);
497
498 chip->ecc.bytes = chip->ecc_strength_ds * 2;
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200499 chip->ecc.size = 512;
Chris Packham3ec7cb32018-07-18 10:42:16 +0200500 chip->ecc.strength = chip->ecc_strength_ds;
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200501 chip->ecc.algo = NAND_ECC_BCH;
502 chip->ecc.read_page = micron_nand_read_page_on_die_ecc;
503 chip->ecc.write_page = micron_nand_write_page_on_die_ecc;
Chris Packhamcb2bf402018-07-18 10:42:18 +0200504
505 if (ondie == MICRON_ON_DIE_MANDATORY) {
506 chip->ecc.read_page_raw = nand_read_page_raw_notsupp;
507 chip->ecc.write_page_raw = nand_write_page_raw_notsupp;
508 } else {
509 chip->ecc.read_page_raw = nand_read_page_raw;
510 chip->ecc.write_page_raw = nand_write_page_raw;
511 }
Thomas Petazzoni9748e1d2017-04-29 11:06:45 +0200512 }
513
Boris Brezillon10d4e752016-06-08 10:38:57 +0200514 return 0;
Boris Brezillon23017802018-07-18 10:42:19 +0200515
516err_free_manuf_data:
517 kfree(micron->ecc.rawbuf);
518 kfree(micron);
519
520 return ret;
521}
522
523static void micron_nand_cleanup(struct nand_chip *chip)
524{
525 struct micron_nand *micron = nand_get_manufacturer_data(chip);
526
527 kfree(micron->ecc.rawbuf);
528 kfree(micron);
Boris Brezillon10d4e752016-06-08 10:38:57 +0200529}
530
Chris Packham243f37c2018-06-25 10:44:46 +1200531static void micron_fixup_onfi_param_page(struct nand_chip *chip,
532 struct nand_onfi_params *p)
533{
534 /*
535 * MT29F1G08ABAFAWP-ITE:F and possibly others report 00 00 for the
536 * revision number field of the ONFI parameter page. Assume ONFI
537 * version 1.0 if the revision number is 00 00.
538 */
539 if (le16_to_cpu(p->revision) == 0)
540 p->revision = cpu_to_le16(ONFI_VERSION_1_0);
541}
542
Boris Brezillon10d4e752016-06-08 10:38:57 +0200543const struct nand_manufacturer_ops micron_nand_manuf_ops = {
544 .init = micron_nand_init,
Boris Brezillon23017802018-07-18 10:42:19 +0200545 .cleanup = micron_nand_cleanup,
Chris Packham243f37c2018-06-25 10:44:46 +1200546 .fixup_onfi_param_page = micron_fixup_onfi_param_page,
Boris Brezillon10d4e752016-06-08 10:38:57 +0200547};