blob: c6603d4b25c8536efa9c8a44fed7e3aeb25393df [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * drivers/mtd/nand.c
3 *
4 * Overview:
5 * This is the generic MTD driver for NAND flash devices. It should be
6 * capable of working with almost all NAND chips currently available.
7 * Basic support for AG-AND chips is provided.
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00008 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 * Additional technical information is available on
maximilian attems8b2b4032007-07-28 13:07:16 +020010 * http://www.linux-mtd.infradead.org/doc/nand.html
Thomas Gleixner61b03bd2005-11-07 11:15:49 +000011 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070012 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +020013 * 2002-2006 Thomas Gleixner (tglx@linutronix.de)
Linus Torvalds1da177e2005-04-16 15:20:36 -070014 *
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +020015 * Credits:
Thomas Gleixner61b03bd2005-11-07 11:15:49 +000016 * David Woodhouse for adding multichip support
17 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 * Aleph One Ltd. and Toby Churchill Ltd. for supporting the
19 * rework for 2K page size chips
20 *
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +020021 * TODO:
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 * Enable cached programming for 2k page size chips
23 * Check, if mtd->ecctype should be set to MTD_ECC_HW
Brian Norris7854d3f2011-06-23 14:12:08 -070024 * if we have HW ECC support.
Linus Torvalds1da177e2005-04-16 15:20:36 -070025 * The AG-AND chips have nice features for speed improvement,
26 * which are not supported yet. Read / program 4 pages in one go.
Artem Bityutskiyc0b8ba72007-07-23 16:06:50 +030027 * BBT table is not serialized, has to be fixed
Linus Torvalds1da177e2005-04-16 15:20:36 -070028 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070029 * This program is free software; you can redistribute it and/or modify
30 * it under the terms of the GNU General Public License version 2 as
31 * published by the Free Software Foundation.
32 *
33 */
34
David Woodhouse552d9202006-05-14 01:20:46 +010035#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070036#include <linux/delay.h>
37#include <linux/errno.h>
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +020038#include <linux/err.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070039#include <linux/sched.h>
40#include <linux/slab.h>
41#include <linux/types.h>
42#include <linux/mtd/mtd.h>
43#include <linux/mtd/nand.h>
44#include <linux/mtd/nand_ecc.h>
Ivan Djelic193bd402011-03-11 11:05:33 +010045#include <linux/mtd/nand_bch.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070046#include <linux/interrupt.h>
47#include <linux/bitops.h>
Richard Purdie8fe833c2006-03-31 02:31:14 -080048#include <linux/leds.h>
Florian Fainelli7351d3a2010-09-07 13:23:45 +020049#include <linux/io.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070050#include <linux/mtd/partitions.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
52/* Define default oob placement schemes for large and small page devices */
Thomas Gleixner5bd34c02006-05-27 22:16:10 +020053static struct nand_ecclayout nand_oob_8 = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070054 .eccbytes = 3,
55 .eccpos = {0, 1, 2},
Thomas Gleixner5bd34c02006-05-27 22:16:10 +020056 .oobfree = {
57 {.offset = 3,
58 .length = 2},
59 {.offset = 6,
Florian Fainellif8ac0412010-09-07 13:23:43 +020060 .length = 2} }
Linus Torvalds1da177e2005-04-16 15:20:36 -070061};
62
Thomas Gleixner5bd34c02006-05-27 22:16:10 +020063static struct nand_ecclayout nand_oob_16 = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070064 .eccbytes = 6,
65 .eccpos = {0, 1, 2, 3, 6, 7},
Thomas Gleixner5bd34c02006-05-27 22:16:10 +020066 .oobfree = {
67 {.offset = 8,
Florian Fainellif8ac0412010-09-07 13:23:43 +020068 . length = 8} }
Linus Torvalds1da177e2005-04-16 15:20:36 -070069};
70
Thomas Gleixner5bd34c02006-05-27 22:16:10 +020071static struct nand_ecclayout nand_oob_64 = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 .eccbytes = 24,
73 .eccpos = {
David Woodhousee0c7d762006-05-13 18:07:53 +010074 40, 41, 42, 43, 44, 45, 46, 47,
75 48, 49, 50, 51, 52, 53, 54, 55,
76 56, 57, 58, 59, 60, 61, 62, 63},
Thomas Gleixner5bd34c02006-05-27 22:16:10 +020077 .oobfree = {
78 {.offset = 2,
Florian Fainellif8ac0412010-09-07 13:23:43 +020079 .length = 38} }
Linus Torvalds1da177e2005-04-16 15:20:36 -070080};
81
Thomas Gleixner81ec5362007-12-12 17:27:03 +010082static struct nand_ecclayout nand_oob_128 = {
83 .eccbytes = 48,
84 .eccpos = {
85 80, 81, 82, 83, 84, 85, 86, 87,
86 88, 89, 90, 91, 92, 93, 94, 95,
87 96, 97, 98, 99, 100, 101, 102, 103,
88 104, 105, 106, 107, 108, 109, 110, 111,
89 112, 113, 114, 115, 116, 117, 118, 119,
90 120, 121, 122, 123, 124, 125, 126, 127},
91 .oobfree = {
92 {.offset = 2,
Florian Fainellif8ac0412010-09-07 13:23:43 +020093 .length = 78} }
Thomas Gleixner81ec5362007-12-12 17:27:03 +010094};
95
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +020096static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd,
Thomas Gleixner2c0a2be2006-05-23 11:50:56 +020097 int new_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -070098
Thomas Gleixner8593fbc2006-05-29 03:26:58 +020099static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
100 struct mtd_oob_ops *ops);
101
Thomas Gleixnerd470a972006-05-23 23:48:57 +0200102/*
Joe Perches8e87d782008-02-03 17:22:34 +0200103 * For devices which display every fart in the system on a separate LED. Is
Thomas Gleixnerd470a972006-05-23 23:48:57 +0200104 * compiled away when LED support is disabled.
105 */
106DEFINE_LED_TRIGGER(nand_led_trigger);
107
Vimal Singh6fe5a6a2010-02-03 14:12:24 +0530108static int check_offs_len(struct mtd_info *mtd,
109 loff_t ofs, uint64_t len)
110{
111 struct nand_chip *chip = mtd->priv;
112 int ret = 0;
113
114 /* Start address must align on block boundary */
115 if (ofs & ((1 << chip->phys_erase_shift) - 1)) {
Brian Norris289c0522011-07-19 10:06:09 -0700116 pr_debug("%s: unaligned address\n", __func__);
Vimal Singh6fe5a6a2010-02-03 14:12:24 +0530117 ret = -EINVAL;
118 }
119
120 /* Length must align on block boundary */
121 if (len & ((1 << chip->phys_erase_shift) - 1)) {
Brian Norris289c0522011-07-19 10:06:09 -0700122 pr_debug("%s: length not block aligned\n", __func__);
Vimal Singh6fe5a6a2010-02-03 14:12:24 +0530123 ret = -EINVAL;
124 }
125
126 /* Do not allow past end of device */
127 if (ofs + len > mtd->size) {
Brian Norris289c0522011-07-19 10:06:09 -0700128 pr_debug("%s: past end of device\n", __func__);
Vimal Singh6fe5a6a2010-02-03 14:12:24 +0530129 ret = -EINVAL;
130 }
131
132 return ret;
133}
134
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135/**
136 * nand_release_device - [GENERIC] release chip
Brian Norris8b6e50c2011-05-25 14:59:01 -0700137 * @mtd: MTD device structure
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000138 *
Brian Norris8b6e50c2011-05-25 14:59:01 -0700139 * Deselect, release chip lock and wake up anyone waiting on the device.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 */
David Woodhousee0c7d762006-05-13 18:07:53 +0100141static void nand_release_device(struct mtd_info *mtd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200143 struct nand_chip *chip = mtd->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144
145 /* De-select the NAND device */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200146 chip->select_chip(mtd, -1);
Thomas Gleixner0dfc6242005-05-31 20:39:20 +0100147
Thomas Gleixnera36ed292006-05-23 11:37:03 +0200148 /* Release the controller and the chip */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200149 spin_lock(&chip->controller->lock);
150 chip->controller->active = NULL;
151 chip->state = FL_READY;
152 wake_up(&chip->controller->wq);
153 spin_unlock(&chip->controller->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154}
155
156/**
157 * nand_read_byte - [DEFAULT] read one byte from the chip
Brian Norris8b6e50c2011-05-25 14:59:01 -0700158 * @mtd: MTD device structure
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159 *
Brian Norris7854d3f2011-06-23 14:12:08 -0700160 * Default read function for 8bit buswidth
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 */
Thomas Gleixner58dd8f2b2006-05-23 11:52:35 +0200162static uint8_t nand_read_byte(struct mtd_info *mtd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200164 struct nand_chip *chip = mtd->priv;
165 return readb(chip->IO_ADDR_R);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166}
167
168/**
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169 * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
Brian Norris7854d3f2011-06-23 14:12:08 -0700170 * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip
Brian Norris8b6e50c2011-05-25 14:59:01 -0700171 * @mtd: MTD device structure
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 *
Brian Norris7854d3f2011-06-23 14:12:08 -0700173 * Default read function for 16bit buswidth with endianness conversion.
174 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175 */
Thomas Gleixner58dd8f2b2006-05-23 11:52:35 +0200176static uint8_t nand_read_byte16(struct mtd_info *mtd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200178 struct nand_chip *chip = mtd->priv;
179 return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180}
181
182/**
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183 * nand_read_word - [DEFAULT] read one word from the chip
Brian Norris8b6e50c2011-05-25 14:59:01 -0700184 * @mtd: MTD device structure
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 *
Brian Norris7854d3f2011-06-23 14:12:08 -0700186 * Default read function for 16bit buswidth without endianness conversion.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 */
188static u16 nand_read_word(struct mtd_info *mtd)
189{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200190 struct nand_chip *chip = mtd->priv;
191 return readw(chip->IO_ADDR_R);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192}
193
194/**
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195 * nand_select_chip - [DEFAULT] control CE line
Brian Norris8b6e50c2011-05-25 14:59:01 -0700196 * @mtd: MTD device structure
197 * @chipnr: chipnumber to select, -1 for deselect
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198 *
199 * Default select function for 1 chip devices.
200 */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200201static void nand_select_chip(struct mtd_info *mtd, int chipnr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200203 struct nand_chip *chip = mtd->priv;
204
205 switch (chipnr) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206 case -1:
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200207 chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 break;
209 case 0:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 break;
211
212 default:
213 BUG();
214 }
215}
216
217/**
218 * nand_write_buf - [DEFAULT] write buffer to chip
Brian Norris8b6e50c2011-05-25 14:59:01 -0700219 * @mtd: MTD device structure
220 * @buf: data buffer
221 * @len: number of bytes to write
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 *
Brian Norris7854d3f2011-06-23 14:12:08 -0700223 * Default write function for 8bit buswidth.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 */
Thomas Gleixner58dd8f2b2006-05-23 11:52:35 +0200225static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226{
227 int i;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200228 struct nand_chip *chip = mtd->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229
David Woodhousee0c7d762006-05-13 18:07:53 +0100230 for (i = 0; i < len; i++)
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200231 writeb(buf[i], chip->IO_ADDR_W);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232}
233
234/**
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000235 * nand_read_buf - [DEFAULT] read chip data into buffer
Brian Norris8b6e50c2011-05-25 14:59:01 -0700236 * @mtd: MTD device structure
237 * @buf: buffer to store date
238 * @len: number of bytes to read
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239 *
Brian Norris7854d3f2011-06-23 14:12:08 -0700240 * Default read function for 8bit buswidth.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241 */
Thomas Gleixner58dd8f2b2006-05-23 11:52:35 +0200242static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243{
244 int i;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200245 struct nand_chip *chip = mtd->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246
David Woodhousee0c7d762006-05-13 18:07:53 +0100247 for (i = 0; i < len; i++)
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200248 buf[i] = readb(chip->IO_ADDR_R);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249}
250
251/**
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000252 * nand_verify_buf - [DEFAULT] Verify chip data against buffer
Brian Norris8b6e50c2011-05-25 14:59:01 -0700253 * @mtd: MTD device structure
254 * @buf: buffer containing the data to compare
255 * @len: number of bytes to compare
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256 *
Brian Norris7854d3f2011-06-23 14:12:08 -0700257 * Default verify function for 8bit buswidth.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 */
Thomas Gleixner58dd8f2b2006-05-23 11:52:35 +0200259static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260{
261 int i;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200262 struct nand_chip *chip = mtd->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263
David Woodhousee0c7d762006-05-13 18:07:53 +0100264 for (i = 0; i < len; i++)
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200265 if (buf[i] != readb(chip->IO_ADDR_R))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 return 0;
268}
269
270/**
271 * nand_write_buf16 - [DEFAULT] write buffer to chip
Brian Norris8b6e50c2011-05-25 14:59:01 -0700272 * @mtd: MTD device structure
273 * @buf: data buffer
274 * @len: number of bytes to write
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275 *
Brian Norris7854d3f2011-06-23 14:12:08 -0700276 * Default write function for 16bit buswidth.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 */
Thomas Gleixner58dd8f2b2006-05-23 11:52:35 +0200278static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279{
280 int i;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200281 struct nand_chip *chip = mtd->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 u16 *p = (u16 *) buf;
283 len >>= 1;
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000284
David Woodhousee0c7d762006-05-13 18:07:53 +0100285 for (i = 0; i < len; i++)
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200286 writew(p[i], chip->IO_ADDR_W);
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000287
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288}
289
290/**
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000291 * nand_read_buf16 - [DEFAULT] read chip data into buffer
Brian Norris8b6e50c2011-05-25 14:59:01 -0700292 * @mtd: MTD device structure
293 * @buf: buffer to store date
294 * @len: number of bytes to read
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 *
Brian Norris7854d3f2011-06-23 14:12:08 -0700296 * Default read function for 16bit buswidth.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297 */
Thomas Gleixner58dd8f2b2006-05-23 11:52:35 +0200298static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299{
300 int i;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200301 struct nand_chip *chip = mtd->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 u16 *p = (u16 *) buf;
303 len >>= 1;
304
David Woodhousee0c7d762006-05-13 18:07:53 +0100305 for (i = 0; i < len; i++)
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200306 p[i] = readw(chip->IO_ADDR_R);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307}
308
309/**
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000310 * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
Brian Norris8b6e50c2011-05-25 14:59:01 -0700311 * @mtd: MTD device structure
312 * @buf: buffer containing the data to compare
313 * @len: number of bytes to compare
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314 *
Brian Norris7854d3f2011-06-23 14:12:08 -0700315 * Default verify function for 16bit buswidth.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316 */
Thomas Gleixner58dd8f2b2006-05-23 11:52:35 +0200317static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318{
319 int i;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200320 struct nand_chip *chip = mtd->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 u16 *p = (u16 *) buf;
322 len >>= 1;
323
David Woodhousee0c7d762006-05-13 18:07:53 +0100324 for (i = 0; i < len; i++)
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200325 if (p[i] != readw(chip->IO_ADDR_R))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 return -EFAULT;
327
328 return 0;
329}
330
331/**
332 * nand_block_bad - [DEFAULT] Read bad block marker from the chip
Brian Norris8b6e50c2011-05-25 14:59:01 -0700333 * @mtd: MTD device structure
334 * @ofs: offset from device start
335 * @getchip: 0, if the chip is already selected
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 *
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000337 * Check, if the block is bad.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338 */
339static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
340{
Brian Norriscdbec052012-01-13 18:11:48 -0800341 int page, chipnr, res = 0, i = 0;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200342 struct nand_chip *chip = mtd->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343 u16 bad;
344
Brian Norris5fb15492011-05-31 16:31:21 -0700345 if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
Kevin Cernekeeb60b08b2010-05-04 20:58:10 -0700346 ofs += mtd->erasesize - mtd->writesize;
347
Thomas Knobloch1a12f462007-05-03 07:39:37 +0100348 page = (int)(ofs >> chip->page_shift) & chip->pagemask;
349
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350 if (getchip) {
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200351 chipnr = (int)(ofs >> chip->chip_shift);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200353 nand_get_device(chip, mtd, FL_READING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354
355 /* Select the NAND device */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200356 chip->select_chip(mtd, chipnr);
Thomas Knobloch1a12f462007-05-03 07:39:37 +0100357 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358
Brian Norriscdbec052012-01-13 18:11:48 -0800359 do {
360 if (chip->options & NAND_BUSWIDTH_16) {
361 chip->cmdfunc(mtd, NAND_CMD_READOOB,
362 chip->badblockpos & 0xFE, page);
363 bad = cpu_to_le16(chip->read_word(mtd));
364 if (chip->badblockpos & 0x1)
365 bad >>= 8;
366 else
367 bad &= 0xFF;
368 } else {
369 chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos,
370 page);
371 bad = chip->read_byte(mtd);
372 }
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000373
Brian Norriscdbec052012-01-13 18:11:48 -0800374 if (likely(chip->badblockbits == 8))
375 res = bad != 0xFF;
376 else
377 res = hweight8(bad) < chip->badblockbits;
378 ofs += mtd->writesize;
379 page = (int)(ofs >> chip->page_shift) & chip->pagemask;
380 i++;
381 } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE));
Maxim Levitskye0b58d02010-02-22 20:39:38 +0200382
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200383 if (getchip)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 nand_release_device(mtd);
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000385
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 return res;
387}
388
389/**
390 * nand_default_block_markbad - [DEFAULT] mark a block bad
Brian Norris8b6e50c2011-05-25 14:59:01 -0700391 * @mtd: MTD device structure
392 * @ofs: offset from device start
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 *
Brian Norris8b6e50c2011-05-25 14:59:01 -0700394 * This is the default implementation, which can be overridden by a hardware
395 * specific driver.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396*/
397static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
398{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200399 struct nand_chip *chip = mtd->priv;
Thomas Gleixner58dd8f2b2006-05-23 11:52:35 +0200400 uint8_t buf[2] = { 0, 0 };
Brian Norris02ed70b2010-07-21 16:53:47 -0700401 int block, ret, i = 0;
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000402
Brian Norris00918422012-01-13 18:11:47 -0800403 if (!(chip->bbt_options & NAND_BBT_USE_FLASH)) {
404 struct erase_info einfo;
405
406 /* Attempt erase before marking OOB */
407 memset(&einfo, 0, sizeof(einfo));
408 einfo.mtd = mtd;
409 einfo.addr = ofs;
410 einfo.len = 1 << chip->phys_erase_shift;
411 nand_erase_nand(mtd, &einfo, 0);
412 }
413
Brian Norris5fb15492011-05-31 16:31:21 -0700414 if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
Kevin Cernekeeb60b08b2010-05-04 20:58:10 -0700415 ofs += mtd->erasesize - mtd->writesize;
416
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417 /* Get block number */
Andre Renaud4226b512007-04-17 13:50:59 -0400418 block = (int)(ofs >> chip->bbt_erase_shift);
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200419 if (chip->bbt)
420 chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421
Brian Norris8b6e50c2011-05-25 14:59:01 -0700422 /* Do we have a flash based bad block table? */
Brian Norrisbb9ebd42011-05-31 16:31:23 -0700423 if (chip->bbt_options & NAND_BBT_USE_FLASH)
Thomas Gleixnerf1a28c02006-05-30 00:37:34 +0200424 ret = nand_update_bbt(mtd, ofs);
425 else {
Brian Norris4a89ff82011-08-30 18:45:45 -0700426 struct mtd_oob_ops ops;
427
Artem Bityutskiyc0b8ba72007-07-23 16:06:50 +0300428 nand_get_device(chip, mtd, FL_WRITING);
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000429
Brian Norrisa0dc5522011-05-31 16:31:20 -0700430 /*
431 * Write to first two pages if necessary. If we write to more
432 * than one location, the first error encountered quits the
Brian Norris85443312012-01-13 18:11:49 -0800433 * procedure.
Brian Norris02ed70b2010-07-21 16:53:47 -0700434 */
Brian Norris4a89ff82011-08-30 18:45:45 -0700435 ops.datbuf = NULL;
436 ops.oobbuf = buf;
Brian Norris85443312012-01-13 18:11:49 -0800437 ops.ooboffs = chip->badblockpos;
438 if (chip->options & NAND_BUSWIDTH_16) {
439 ops.ooboffs &= ~0x01;
440 ops.len = ops.ooblen = 2;
441 } else {
442 ops.len = ops.ooblen = 1;
443 }
Brian Norris23b1a992011-10-14 20:09:33 -0700444 ops.mode = MTD_OPS_PLACE_OOB;
Brian Norris02ed70b2010-07-21 16:53:47 -0700445 do {
Brian Norris4a89ff82011-08-30 18:45:45 -0700446 ret = nand_do_write_oob(mtd, ofs, &ops);
Brian Norris02ed70b2010-07-21 16:53:47 -0700447
Brian Norris02ed70b2010-07-21 16:53:47 -0700448 i++;
449 ofs += mtd->writesize;
Brian Norris5fb15492011-05-31 16:31:21 -0700450 } while (!ret && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE) &&
Brian Norris02ed70b2010-07-21 16:53:47 -0700451 i < 2);
452
Artem Bityutskiyc0b8ba72007-07-23 16:06:50 +0300453 nand_release_device(mtd);
Thomas Gleixnerf1a28c02006-05-30 00:37:34 +0200454 }
455 if (!ret)
456 mtd->ecc_stats.badblocks++;
Artem Bityutskiyc0b8ba72007-07-23 16:06:50 +0300457
Thomas Gleixnerf1a28c02006-05-30 00:37:34 +0200458 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459}
460
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000461/**
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462 * nand_check_wp - [GENERIC] check if the chip is write protected
Brian Norris8b6e50c2011-05-25 14:59:01 -0700463 * @mtd: MTD device structure
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464 *
Brian Norris8b6e50c2011-05-25 14:59:01 -0700465 * Check, if the device is write protected. The function expects, that the
466 * device is already selected.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 */
David Woodhousee0c7d762006-05-13 18:07:53 +0100468static int nand_check_wp(struct mtd_info *mtd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200470 struct nand_chip *chip = mtd->priv;
Maxim Levitsky93edbad2010-02-22 20:39:40 +0200471
Brian Norris8b6e50c2011-05-25 14:59:01 -0700472 /* Broken xD cards report WP despite being writable */
Maxim Levitsky93edbad2010-02-22 20:39:40 +0200473 if (chip->options & NAND_BROKEN_XD)
474 return 0;
475
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 /* Check the WP bit */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200477 chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
478 return (chip->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479}
480
481/**
482 * nand_block_checkbad - [GENERIC] Check if a block is marked bad
Brian Norris8b6e50c2011-05-25 14:59:01 -0700483 * @mtd: MTD device structure
484 * @ofs: offset from device start
485 * @getchip: 0, if the chip is already selected
486 * @allowbbt: 1, if its allowed to access the bbt area
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 *
488 * Check, if the block is bad. Either by reading the bad block table or
489 * calling of the scan function.
490 */
Thomas Gleixner2c0a2be2006-05-23 11:50:56 +0200491static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
492 int allowbbt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200494 struct nand_chip *chip = mtd->priv;
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000495
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200496 if (!chip->bbt)
497 return chip->block_bad(mtd, ofs, getchip);
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000498
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 /* Return info from the table */
David Woodhousee0c7d762006-05-13 18:07:53 +0100500 return nand_isbad_bbt(mtd, ofs, allowbbt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501}
502
Simon Kagstrom2af7c652009-10-05 15:55:52 +0200503/**
504 * panic_nand_wait_ready - [GENERIC] Wait for the ready pin after commands.
Brian Norris8b6e50c2011-05-25 14:59:01 -0700505 * @mtd: MTD device structure
506 * @timeo: Timeout
Simon Kagstrom2af7c652009-10-05 15:55:52 +0200507 *
508 * Helper function for nand_wait_ready used when needing to wait in interrupt
509 * context.
510 */
511static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo)
512{
513 struct nand_chip *chip = mtd->priv;
514 int i;
515
516 /* Wait for the device to get ready */
517 for (i = 0; i < timeo; i++) {
518 if (chip->dev_ready(mtd))
519 break;
520 touch_softlockup_watchdog();
521 mdelay(1);
522 }
523}
524
Brian Norris7854d3f2011-06-23 14:12:08 -0700525/* Wait for the ready pin, after a command. The timeout is caught later. */
David Woodhouse4b648b02006-09-25 17:05:24 +0100526void nand_wait_ready(struct mtd_info *mtd)
Thomas Gleixner3b887752005-02-22 21:56:49 +0000527{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200528 struct nand_chip *chip = mtd->priv;
David Woodhousee0c7d762006-05-13 18:07:53 +0100529 unsigned long timeo = jiffies + 2;
Thomas Gleixner3b887752005-02-22 21:56:49 +0000530
Simon Kagstrom2af7c652009-10-05 15:55:52 +0200531 /* 400ms timeout */
532 if (in_interrupt() || oops_in_progress)
533 return panic_nand_wait_ready(mtd, 400);
534
Richard Purdie8fe833c2006-03-31 02:31:14 -0800535 led_trigger_event(nand_led_trigger, LED_FULL);
Brian Norris7854d3f2011-06-23 14:12:08 -0700536 /* Wait until command is processed or timeout occurs */
Thomas Gleixner3b887752005-02-22 21:56:49 +0000537 do {
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200538 if (chip->dev_ready(mtd))
Richard Purdie8fe833c2006-03-31 02:31:14 -0800539 break;
Ingo Molnar8446f1d2005-09-06 15:16:27 -0700540 touch_softlockup_watchdog();
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000541 } while (time_before(jiffies, timeo));
Richard Purdie8fe833c2006-03-31 02:31:14 -0800542 led_trigger_event(nand_led_trigger, LED_OFF);
Thomas Gleixner3b887752005-02-22 21:56:49 +0000543}
David Woodhouse4b648b02006-09-25 17:05:24 +0100544EXPORT_SYMBOL_GPL(nand_wait_ready);
Thomas Gleixner3b887752005-02-22 21:56:49 +0000545
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546/**
547 * nand_command - [DEFAULT] Send command to NAND device
Brian Norris8b6e50c2011-05-25 14:59:01 -0700548 * @mtd: MTD device structure
549 * @command: the command to be sent
550 * @column: the column address for this command, -1 if none
551 * @page_addr: the page address for this command, -1 if none
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 *
Brian Norris8b6e50c2011-05-25 14:59:01 -0700553 * Send command to NAND device. This function is used for small page devices
554 * (256/512 Bytes per page).
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 */
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200556static void nand_command(struct mtd_info *mtd, unsigned int command,
557 int column, int page_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200559 register struct nand_chip *chip = mtd->priv;
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200560 int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561
Brian Norris8b6e50c2011-05-25 14:59:01 -0700562 /* Write out the command to the device */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 if (command == NAND_CMD_SEQIN) {
564 int readcmd;
565
Joern Engel28318772006-05-22 23:18:05 +0200566 if (column >= mtd->writesize) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 /* OOB area */
Joern Engel28318772006-05-22 23:18:05 +0200568 column -= mtd->writesize;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 readcmd = NAND_CMD_READOOB;
570 } else if (column < 256) {
571 /* First 256 bytes --> READ0 */
572 readcmd = NAND_CMD_READ0;
573 } else {
574 column -= 256;
575 readcmd = NAND_CMD_READ1;
576 }
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200577 chip->cmd_ctrl(mtd, readcmd, ctrl);
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200578 ctrl &= ~NAND_CTRL_CHANGE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 }
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200580 chip->cmd_ctrl(mtd, command, ctrl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581
Brian Norris8b6e50c2011-05-25 14:59:01 -0700582 /* Address cycle, when necessary */
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200583 ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE;
584 /* Serially input address */
585 if (column != -1) {
586 /* Adjust columns for 16 bit buswidth */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200587 if (chip->options & NAND_BUSWIDTH_16)
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200588 column >>= 1;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200589 chip->cmd_ctrl(mtd, column, ctrl);
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200590 ctrl &= ~NAND_CTRL_CHANGE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591 }
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200592 if (page_addr != -1) {
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200593 chip->cmd_ctrl(mtd, page_addr, ctrl);
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200594 ctrl &= ~NAND_CTRL_CHANGE;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200595 chip->cmd_ctrl(mtd, page_addr >> 8, ctrl);
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200596 /* One more address cycle for devices > 32MiB */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200597 if (chip->chipsize > (32 << 20))
598 chip->cmd_ctrl(mtd, page_addr >> 16, ctrl);
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200599 }
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200600 chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000601
602 /*
Brian Norris8b6e50c2011-05-25 14:59:01 -0700603 * Program and erase have their own busy handlers status and sequential
604 * in needs no delay
David Woodhousee0c7d762006-05-13 18:07:53 +0100605 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 switch (command) {
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000607
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 case NAND_CMD_PAGEPROG:
609 case NAND_CMD_ERASE1:
610 case NAND_CMD_ERASE2:
611 case NAND_CMD_SEQIN:
612 case NAND_CMD_STATUS:
613 return;
614
615 case NAND_CMD_RESET:
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200616 if (chip->dev_ready)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617 break;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200618 udelay(chip->chip_delay);
619 chip->cmd_ctrl(mtd, NAND_CMD_STATUS,
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200620 NAND_CTRL_CLE | NAND_CTRL_CHANGE);
Thomas Gleixner12efdde2006-05-24 22:57:09 +0200621 chip->cmd_ctrl(mtd,
622 NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
Florian Fainellif8ac0412010-09-07 13:23:43 +0200623 while (!(chip->read_byte(mtd) & NAND_STATUS_READY))
624 ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 return;
626
David Woodhousee0c7d762006-05-13 18:07:53 +0100627 /* This applies to read commands */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 default:
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000629 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 * If we don't have access to the busy pin, we apply the given
631 * command delay
David Woodhousee0c7d762006-05-13 18:07:53 +0100632 */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200633 if (!chip->dev_ready) {
634 udelay(chip->chip_delay);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 return;
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000636 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 }
Brian Norris8b6e50c2011-05-25 14:59:01 -0700638 /*
639 * Apply this short delay always to ensure that we do wait tWB in
640 * any case on any machine.
641 */
David Woodhousee0c7d762006-05-13 18:07:53 +0100642 ndelay(100);
Thomas Gleixner3b887752005-02-22 21:56:49 +0000643
644 nand_wait_ready(mtd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645}
646
647/**
648 * nand_command_lp - [DEFAULT] Send command to NAND large page device
Brian Norris8b6e50c2011-05-25 14:59:01 -0700649 * @mtd: MTD device structure
650 * @command: the command to be sent
651 * @column: the column address for this command, -1 if none
652 * @page_addr: the page address for this command, -1 if none
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653 *
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200654 * Send command to NAND device. This is the version for the new large page
Brian Norris7854d3f2011-06-23 14:12:08 -0700655 * devices. We don't have the separate regions as we have in the small page
656 * devices. We must emulate NAND_CMD_READOOB to keep the code compatible.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 */
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200658static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
659 int column, int page_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200661 register struct nand_chip *chip = mtd->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662
663 /* Emulate NAND_CMD_READOOB */
664 if (command == NAND_CMD_READOOB) {
Joern Engel28318772006-05-22 23:18:05 +0200665 column += mtd->writesize;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 command = NAND_CMD_READ0;
667 }
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000668
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200669 /* Command latch cycle */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200670 chip->cmd_ctrl(mtd, command & 0xff,
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200671 NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672
673 if (column != -1 || page_addr != -1) {
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200674 int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675
676 /* Serially input address */
677 if (column != -1) {
678 /* Adjust columns for 16 bit buswidth */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200679 if (chip->options & NAND_BUSWIDTH_16)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 column >>= 1;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200681 chip->cmd_ctrl(mtd, column, ctrl);
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200682 ctrl &= ~NAND_CTRL_CHANGE;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200683 chip->cmd_ctrl(mtd, column >> 8, ctrl);
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000684 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685 if (page_addr != -1) {
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200686 chip->cmd_ctrl(mtd, page_addr, ctrl);
687 chip->cmd_ctrl(mtd, page_addr >> 8,
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200688 NAND_NCE | NAND_ALE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689 /* One more address cycle for devices > 128MiB */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200690 if (chip->chipsize > (128 << 20))
691 chip->cmd_ctrl(mtd, page_addr >> 16,
Thomas Gleixner7abd3ef2006-05-23 23:25:53 +0200692 NAND_NCE | NAND_ALE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694 }
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200695 chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000696
697 /*
Brian Norris8b6e50c2011-05-25 14:59:01 -0700698 * Program and erase have their own busy handlers status, sequential
699 * in, and deplete1 need no delay.
David A. Marlin30f464b2005-01-17 18:35:25 +0000700 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701 switch (command) {
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000702
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703 case NAND_CMD_CACHEDPROG:
704 case NAND_CMD_PAGEPROG:
705 case NAND_CMD_ERASE1:
706 case NAND_CMD_ERASE2:
707 case NAND_CMD_SEQIN:
Thomas Gleixner7bc33122006-06-20 20:05:05 +0200708 case NAND_CMD_RNDIN:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 case NAND_CMD_STATUS:
David A. Marlin30f464b2005-01-17 18:35:25 +0000710 case NAND_CMD_DEPLETE1:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 return;
712
David A. Marlin30f464b2005-01-17 18:35:25 +0000713 case NAND_CMD_STATUS_ERROR:
714 case NAND_CMD_STATUS_ERROR0:
715 case NAND_CMD_STATUS_ERROR1:
716 case NAND_CMD_STATUS_ERROR2:
717 case NAND_CMD_STATUS_ERROR3:
Brian Norris8b6e50c2011-05-25 14:59:01 -0700718 /* Read error status commands require only a short delay */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200719 udelay(chip->chip_delay);
David A. Marlin30f464b2005-01-17 18:35:25 +0000720 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721
722 case NAND_CMD_RESET:
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200723 if (chip->dev_ready)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 break;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200725 udelay(chip->chip_delay);
Thomas Gleixner12efdde2006-05-24 22:57:09 +0200726 chip->cmd_ctrl(mtd, NAND_CMD_STATUS,
727 NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
728 chip->cmd_ctrl(mtd, NAND_CMD_NONE,
729 NAND_NCE | NAND_CTRL_CHANGE);
Florian Fainellif8ac0412010-09-07 13:23:43 +0200730 while (!(chip->read_byte(mtd) & NAND_STATUS_READY))
731 ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732 return;
733
Thomas Gleixner7bc33122006-06-20 20:05:05 +0200734 case NAND_CMD_RNDOUT:
735 /* No ready / busy check necessary */
736 chip->cmd_ctrl(mtd, NAND_CMD_RNDOUTSTART,
737 NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
738 chip->cmd_ctrl(mtd, NAND_CMD_NONE,
739 NAND_NCE | NAND_CTRL_CHANGE);
740 return;
741
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742 case NAND_CMD_READ0:
Thomas Gleixner12efdde2006-05-24 22:57:09 +0200743 chip->cmd_ctrl(mtd, NAND_CMD_READSTART,
744 NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
745 chip->cmd_ctrl(mtd, NAND_CMD_NONE,
746 NAND_NCE | NAND_CTRL_CHANGE);
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000747
David Woodhousee0c7d762006-05-13 18:07:53 +0100748 /* This applies to read commands */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749 default:
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000750 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 * If we don't have access to the busy pin, we apply the given
Brian Norris8b6e50c2011-05-25 14:59:01 -0700752 * command delay.
David Woodhousee0c7d762006-05-13 18:07:53 +0100753 */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200754 if (!chip->dev_ready) {
755 udelay(chip->chip_delay);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 return;
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000757 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758 }
Thomas Gleixner3b887752005-02-22 21:56:49 +0000759
Brian Norris8b6e50c2011-05-25 14:59:01 -0700760 /*
761 * Apply this short delay always to ensure that we do wait tWB in
762 * any case on any machine.
763 */
David Woodhousee0c7d762006-05-13 18:07:53 +0100764 ndelay(100);
Thomas Gleixner3b887752005-02-22 21:56:49 +0000765
766 nand_wait_ready(mtd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767}
768
769/**
Simon Kagstrom2af7c652009-10-05 15:55:52 +0200770 * panic_nand_get_device - [GENERIC] Get chip for selected access
Brian Norris8b6e50c2011-05-25 14:59:01 -0700771 * @chip: the nand chip descriptor
772 * @mtd: MTD device structure
773 * @new_state: the state which is requested
Simon Kagstrom2af7c652009-10-05 15:55:52 +0200774 *
775 * Used when in panic, no locks are taken.
776 */
777static void panic_nand_get_device(struct nand_chip *chip,
778 struct mtd_info *mtd, int new_state)
779{
Brian Norris7854d3f2011-06-23 14:12:08 -0700780 /* Hardware controller shared among independent devices */
Simon Kagstrom2af7c652009-10-05 15:55:52 +0200781 chip->controller->active = chip;
782 chip->state = new_state;
783}
784
785/**
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786 * nand_get_device - [GENERIC] Get chip for selected access
Brian Norris8b6e50c2011-05-25 14:59:01 -0700787 * @chip: the nand chip descriptor
788 * @mtd: MTD device structure
789 * @new_state: the state which is requested
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 *
791 * Get the device and lock it for exclusive access
792 */
Thomas Gleixner2c0a2be2006-05-23 11:50:56 +0200793static int
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200794nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200796 spinlock_t *lock = &chip->controller->lock;
797 wait_queue_head_t *wq = &chip->controller->wq;
David Woodhousee0c7d762006-05-13 18:07:53 +0100798 DECLARE_WAITQUEUE(wait, current);
Florian Fainelli7351d3a2010-09-07 13:23:45 +0200799retry:
Thomas Gleixner0dfc6242005-05-31 20:39:20 +0100800 spin_lock(lock);
801
vimal singhb8b3ee92009-07-09 20:41:22 +0530802 /* Hardware controller shared among independent devices */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200803 if (!chip->controller->active)
804 chip->controller->active = chip;
Thomas Gleixnera36ed292006-05-23 11:37:03 +0200805
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200806 if (chip->controller->active == chip && chip->state == FL_READY) {
807 chip->state = new_state;
Thomas Gleixner0dfc6242005-05-31 20:39:20 +0100808 spin_unlock(lock);
Vitaly Wool962034f2005-09-15 14:58:53 +0100809 return 0;
810 }
811 if (new_state == FL_PM_SUSPENDED) {
Li Yang6b0d9a82009-11-17 14:45:49 -0800812 if (chip->controller->active->state == FL_PM_SUSPENDED) {
813 chip->state = FL_PM_SUSPENDED;
814 spin_unlock(lock);
815 return 0;
Li Yang6b0d9a82009-11-17 14:45:49 -0800816 }
Thomas Gleixner0dfc6242005-05-31 20:39:20 +0100817 }
818 set_current_state(TASK_UNINTERRUPTIBLE);
819 add_wait_queue(wq, &wait);
820 spin_unlock(lock);
821 schedule();
822 remove_wait_queue(wq, &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823 goto retry;
824}
825
826/**
Brian Norris8b6e50c2011-05-25 14:59:01 -0700827 * panic_nand_wait - [GENERIC] wait until the command is done
828 * @mtd: MTD device structure
829 * @chip: NAND chip structure
830 * @timeo: timeout
Simon Kagstrom2af7c652009-10-05 15:55:52 +0200831 *
832 * Wait for command done. This is a helper function for nand_wait used when
833 * we are in interrupt context. May happen when in panic and trying to write
Uwe Kleine-Königb5950762010-11-01 15:38:34 -0400834 * an oops through mtdoops.
Simon Kagstrom2af7c652009-10-05 15:55:52 +0200835 */
836static void panic_nand_wait(struct mtd_info *mtd, struct nand_chip *chip,
837 unsigned long timeo)
838{
839 int i;
840 for (i = 0; i < timeo; i++) {
841 if (chip->dev_ready) {
842 if (chip->dev_ready(mtd))
843 break;
844 } else {
845 if (chip->read_byte(mtd) & NAND_STATUS_READY)
846 break;
847 }
848 mdelay(1);
Florian Fainellif8ac0412010-09-07 13:23:43 +0200849 }
Simon Kagstrom2af7c652009-10-05 15:55:52 +0200850}
851
852/**
Brian Norris8b6e50c2011-05-25 14:59:01 -0700853 * nand_wait - [DEFAULT] wait until the command is done
854 * @mtd: MTD device structure
855 * @chip: NAND chip structure
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 *
Brian Norris8b6e50c2011-05-25 14:59:01 -0700857 * Wait for command done. This applies to erase and program only. Erase can
858 * take up to 400ms and program up to 20ms according to general NAND and
859 * SmartMedia specs.
Randy Dunlap844d3b42006-06-28 21:48:27 -0700860 */
Thomas Gleixner7bc33122006-06-20 20:05:05 +0200861static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862{
863
David Woodhousee0c7d762006-05-13 18:07:53 +0100864 unsigned long timeo = jiffies;
Thomas Gleixner7bc33122006-06-20 20:05:05 +0200865 int status, state = chip->state;
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000866
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 if (state == FL_ERASING)
David Woodhousee0c7d762006-05-13 18:07:53 +0100868 timeo += (HZ * 400) / 1000;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 else
David Woodhousee0c7d762006-05-13 18:07:53 +0100870 timeo += (HZ * 20) / 1000;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871
Richard Purdie8fe833c2006-03-31 02:31:14 -0800872 led_trigger_event(nand_led_trigger, LED_FULL);
873
Brian Norris8b6e50c2011-05-25 14:59:01 -0700874 /*
875 * Apply this short delay always to ensure that we do wait tWB in any
876 * case on any machine.
877 */
David Woodhousee0c7d762006-05-13 18:07:53 +0100878 ndelay(100);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200880 if ((state == FL_ERASING) && (chip->options & NAND_IS_AND))
881 chip->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1);
Thomas Gleixner61b03bd2005-11-07 11:15:49 +0000882 else
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200883 chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884
Simon Kagstrom2af7c652009-10-05 15:55:52 +0200885 if (in_interrupt() || oops_in_progress)
886 panic_nand_wait(mtd, chip, timeo);
887 else {
888 while (time_before(jiffies, timeo)) {
889 if (chip->dev_ready) {
890 if (chip->dev_ready(mtd))
891 break;
892 } else {
893 if (chip->read_byte(mtd) & NAND_STATUS_READY)
894 break;
895 }
896 cond_resched();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898 }
Richard Purdie8fe833c2006-03-31 02:31:14 -0800899 led_trigger_event(nand_led_trigger, LED_OFF);
900
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +0200901 status = (int)chip->read_byte(mtd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 return status;
903}
904
905/**
Randy Dunlapb6d676d2010-08-10 18:02:50 -0700906 * __nand_unlock - [REPLACEABLE] unlocks specified locked blocks
Randy Dunlapb6d676d2010-08-10 18:02:50 -0700907 * @mtd: mtd info
908 * @ofs: offset to start unlock from
909 * @len: length to unlock
Brian Norris8b6e50c2011-05-25 14:59:01 -0700910 * @invert: when = 0, unlock the range of blocks within the lower and
911 * upper boundary address
912 * when = 1, unlock the range of blocks outside the boundaries
913 * of the lower and upper boundary address
Vimal Singh7d70f332010-02-08 15:50:49 +0530914 *
Brian Norris8b6e50c2011-05-25 14:59:01 -0700915 * Returs unlock status.
Vimal Singh7d70f332010-02-08 15:50:49 +0530916 */
917static int __nand_unlock(struct mtd_info *mtd, loff_t ofs,
918 uint64_t len, int invert)
919{
920 int ret = 0;
921 int status, page;
922 struct nand_chip *chip = mtd->priv;
923
924 /* Submit address of first page to unlock */
925 page = ofs >> chip->page_shift;
926 chip->cmdfunc(mtd, NAND_CMD_UNLOCK1, -1, page & chip->pagemask);
927
928 /* Submit address of last page to unlock */
929 page = (ofs + len) >> chip->page_shift;
930 chip->cmdfunc(mtd, NAND_CMD_UNLOCK2, -1,
931 (page | invert) & chip->pagemask);
932
933 /* Call wait ready function */
934 status = chip->waitfunc(mtd, chip);
Vimal Singh7d70f332010-02-08 15:50:49 +0530935 /* See if device thinks it succeeded */
936 if (status & 0x01) {
Brian Norris289c0522011-07-19 10:06:09 -0700937 pr_debug("%s: error status = 0x%08x\n",
Vimal Singh7d70f332010-02-08 15:50:49 +0530938 __func__, status);
939 ret = -EIO;
940 }
941
942 return ret;
943}
944
945/**
Randy Dunlapb6d676d2010-08-10 18:02:50 -0700946 * nand_unlock - [REPLACEABLE] unlocks specified locked blocks
Randy Dunlapb6d676d2010-08-10 18:02:50 -0700947 * @mtd: mtd info
948 * @ofs: offset to start unlock from
949 * @len: length to unlock
Vimal Singh7d70f332010-02-08 15:50:49 +0530950 *
Brian Norris8b6e50c2011-05-25 14:59:01 -0700951 * Returns unlock status.
Vimal Singh7d70f332010-02-08 15:50:49 +0530952 */
953int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
954{
955 int ret = 0;
956 int chipnr;
957 struct nand_chip *chip = mtd->priv;
958
Brian Norris289c0522011-07-19 10:06:09 -0700959 pr_debug("%s: start = 0x%012llx, len = %llu\n",
Vimal Singh7d70f332010-02-08 15:50:49 +0530960 __func__, (unsigned long long)ofs, len);
961
962 if (check_offs_len(mtd, ofs, len))
963 ret = -EINVAL;
964
965 /* Align to last block address if size addresses end of the device */
966 if (ofs + len == mtd->size)
967 len -= mtd->erasesize;
968
969 nand_get_device(chip, mtd, FL_UNLOCKING);
970
971 /* Shift to get chip number */
972 chipnr = ofs >> chip->chip_shift;
973
974 chip->select_chip(mtd, chipnr);
975
976 /* Check, if it is write protected */
977 if (nand_check_wp(mtd)) {
Brian Norris289c0522011-07-19 10:06:09 -0700978 pr_debug("%s: device is write protected!\n",
Vimal Singh7d70f332010-02-08 15:50:49 +0530979 __func__);
980 ret = -EIO;
981 goto out;
982 }
983
984 ret = __nand_unlock(mtd, ofs, len, 0);
985
986out:
Vimal Singh7d70f332010-02-08 15:50:49 +0530987 nand_release_device(mtd);
988
989 return ret;
990}
Florian Fainelli7351d3a2010-09-07 13:23:45 +0200991EXPORT_SYMBOL(nand_unlock);
Vimal Singh7d70f332010-02-08 15:50:49 +0530992
993/**
Randy Dunlapb6d676d2010-08-10 18:02:50 -0700994 * nand_lock - [REPLACEABLE] locks all blocks present in the device
Randy Dunlapb6d676d2010-08-10 18:02:50 -0700995 * @mtd: mtd info
996 * @ofs: offset to start unlock from
997 * @len: length to unlock
Vimal Singh7d70f332010-02-08 15:50:49 +0530998 *
Brian Norris8b6e50c2011-05-25 14:59:01 -0700999 * This feature is not supported in many NAND parts. 'Micron' NAND parts do
1000 * have this feature, but it allows only to lock all blocks, not for specified
1001 * range for block. Implementing 'lock' feature by making use of 'unlock', for
1002 * now.
Vimal Singh7d70f332010-02-08 15:50:49 +05301003 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07001004 * Returns lock status.
Vimal Singh7d70f332010-02-08 15:50:49 +05301005 */
1006int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
1007{
1008 int ret = 0;
1009 int chipnr, status, page;
1010 struct nand_chip *chip = mtd->priv;
1011
Brian Norris289c0522011-07-19 10:06:09 -07001012 pr_debug("%s: start = 0x%012llx, len = %llu\n",
Vimal Singh7d70f332010-02-08 15:50:49 +05301013 __func__, (unsigned long long)ofs, len);
1014
1015 if (check_offs_len(mtd, ofs, len))
1016 ret = -EINVAL;
1017
1018 nand_get_device(chip, mtd, FL_LOCKING);
1019
1020 /* Shift to get chip number */
1021 chipnr = ofs >> chip->chip_shift;
1022
1023 chip->select_chip(mtd, chipnr);
1024
1025 /* Check, if it is write protected */
1026 if (nand_check_wp(mtd)) {
Brian Norris289c0522011-07-19 10:06:09 -07001027 pr_debug("%s: device is write protected!\n",
Vimal Singh7d70f332010-02-08 15:50:49 +05301028 __func__);
1029 status = MTD_ERASE_FAILED;
1030 ret = -EIO;
1031 goto out;
1032 }
1033
1034 /* Submit address of first page to lock */
1035 page = ofs >> chip->page_shift;
1036 chip->cmdfunc(mtd, NAND_CMD_LOCK, -1, page & chip->pagemask);
1037
1038 /* Call wait ready function */
1039 status = chip->waitfunc(mtd, chip);
Vimal Singh7d70f332010-02-08 15:50:49 +05301040 /* See if device thinks it succeeded */
1041 if (status & 0x01) {
Brian Norris289c0522011-07-19 10:06:09 -07001042 pr_debug("%s: error status = 0x%08x\n",
Vimal Singh7d70f332010-02-08 15:50:49 +05301043 __func__, status);
1044 ret = -EIO;
1045 goto out;
1046 }
1047
1048 ret = __nand_unlock(mtd, ofs, len, 0x1);
1049
1050out:
Vimal Singh7d70f332010-02-08 15:50:49 +05301051 nand_release_device(mtd);
1052
1053 return ret;
1054}
Florian Fainelli7351d3a2010-09-07 13:23:45 +02001055EXPORT_SYMBOL(nand_lock);
Vimal Singh7d70f332010-02-08 15:50:49 +05301056
1057/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001058 * nand_read_page_raw - [INTERN] read raw page data without ecc
Brian Norris8b6e50c2011-05-25 14:59:01 -07001059 * @mtd: mtd info structure
1060 * @chip: nand chip info structure
1061 * @buf: buffer to store read data
1062 * @page: page number to read
David Brownell52ff49d2009-03-04 12:01:36 -08001063 *
Brian Norris7854d3f2011-06-23 14:12:08 -07001064 * Not for syndrome calculating ECC controllers, which use a special oob layout.
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001065 */
1066static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
Sneha Narnakaje46a8cf22009-09-18 12:51:46 -07001067 uint8_t *buf, int page)
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001068{
1069 chip->read_buf(mtd, buf, mtd->writesize);
1070 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
1071 return 0;
1072}
1073
1074/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001075 * nand_read_page_raw_syndrome - [INTERN] read raw page data without ecc
Brian Norris8b6e50c2011-05-25 14:59:01 -07001076 * @mtd: mtd info structure
1077 * @chip: nand chip info structure
1078 * @buf: buffer to store read data
1079 * @page: page number to read
David Brownell52ff49d2009-03-04 12:01:36 -08001080 *
1081 * We need a special oob layout and handling even when OOB isn't used.
1082 */
Florian Fainelli7351d3a2010-09-07 13:23:45 +02001083static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
1084 struct nand_chip *chip,
1085 uint8_t *buf, int page)
David Brownell52ff49d2009-03-04 12:01:36 -08001086{
1087 int eccsize = chip->ecc.size;
1088 int eccbytes = chip->ecc.bytes;
1089 uint8_t *oob = chip->oob_poi;
1090 int steps, size;
1091
1092 for (steps = chip->ecc.steps; steps > 0; steps--) {
1093 chip->read_buf(mtd, buf, eccsize);
1094 buf += eccsize;
1095
1096 if (chip->ecc.prepad) {
1097 chip->read_buf(mtd, oob, chip->ecc.prepad);
1098 oob += chip->ecc.prepad;
1099 }
1100
1101 chip->read_buf(mtd, oob, eccbytes);
1102 oob += eccbytes;
1103
1104 if (chip->ecc.postpad) {
1105 chip->read_buf(mtd, oob, chip->ecc.postpad);
1106 oob += chip->ecc.postpad;
1107 }
1108 }
1109
1110 size = mtd->oobsize - (oob - chip->oob_poi);
1111 if (size)
1112 chip->read_buf(mtd, oob, size);
1113
1114 return 0;
1115}
1116
1117/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001118 * nand_read_page_swecc - [REPLACEABLE] software ECC based page read function
Brian Norris8b6e50c2011-05-25 14:59:01 -07001119 * @mtd: mtd info structure
1120 * @chip: nand chip info structure
1121 * @buf: buffer to store read data
1122 * @page: page number to read
David A. Marlin068e3c02005-01-24 03:07:46 +00001123 */
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001124static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
Sneha Narnakaje46a8cf22009-09-18 12:51:46 -07001125 uint8_t *buf, int page)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126{
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001127 int i, eccsize = chip->ecc.size;
1128 int eccbytes = chip->ecc.bytes;
1129 int eccsteps = chip->ecc.steps;
1130 uint8_t *p = buf;
David Woodhouse4bf63fc2006-09-25 17:08:04 +01001131 uint8_t *ecc_calc = chip->buffers->ecccalc;
1132 uint8_t *ecc_code = chip->buffers->ecccode;
Ben Dooks8b099a32007-05-28 19:17:54 +01001133 uint32_t *eccpos = chip->ecc.layout->eccpos;
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001134
Sneha Narnakaje46a8cf22009-09-18 12:51:46 -07001135 chip->ecc.read_page_raw(mtd, chip, buf, page);
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001136
1137 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
1138 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
1139
1140 for (i = 0; i < chip->ecc.total; i++)
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02001141 ecc_code[i] = chip->oob_poi[eccpos[i]];
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001142
1143 eccsteps = chip->ecc.steps;
1144 p = buf;
1145
1146 for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
1147 int stat;
1148
1149 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
Matt Reimerc32b8dc2007-10-17 14:33:23 -07001150 if (stat < 0)
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001151 mtd->ecc_stats.failed++;
1152 else
1153 mtd->ecc_stats.corrected += stat;
1154 }
1155 return 0;
Thomas Gleixner22c60f52005-04-04 19:56:32 +01001156}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001159 * nand_read_subpage - [REPLACEABLE] software ECC based sub-page read function
Brian Norris8b6e50c2011-05-25 14:59:01 -07001160 * @mtd: mtd info structure
1161 * @chip: nand chip info structure
1162 * @data_offs: offset of requested data within the page
1163 * @readlen: data length
1164 * @bufpoi: buffer to store read data
Alexey Korolev3d459552008-05-15 17:23:18 +01001165 */
Florian Fainelli7351d3a2010-09-07 13:23:45 +02001166static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
1167 uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi)
Alexey Korolev3d459552008-05-15 17:23:18 +01001168{
1169 int start_step, end_step, num_steps;
1170 uint32_t *eccpos = chip->ecc.layout->eccpos;
1171 uint8_t *p;
1172 int data_col_addr, i, gaps = 0;
1173 int datafrag_len, eccfrag_len, aligned_len, aligned_pos;
1174 int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1;
Florian Fainelli7351d3a2010-09-07 13:23:45 +02001175 int index = 0;
Alexey Korolev3d459552008-05-15 17:23:18 +01001176
Brian Norris7854d3f2011-06-23 14:12:08 -07001177 /* Column address within the page aligned to ECC size (256bytes) */
Alexey Korolev3d459552008-05-15 17:23:18 +01001178 start_step = data_offs / chip->ecc.size;
1179 end_step = (data_offs + readlen - 1) / chip->ecc.size;
1180 num_steps = end_step - start_step + 1;
1181
Brian Norris8b6e50c2011-05-25 14:59:01 -07001182 /* Data size aligned to ECC ecc.size */
Alexey Korolev3d459552008-05-15 17:23:18 +01001183 datafrag_len = num_steps * chip->ecc.size;
1184 eccfrag_len = num_steps * chip->ecc.bytes;
1185
1186 data_col_addr = start_step * chip->ecc.size;
1187 /* If we read not a page aligned data */
1188 if (data_col_addr != 0)
1189 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_col_addr, -1);
1190
1191 p = bufpoi + data_col_addr;
1192 chip->read_buf(mtd, p, datafrag_len);
1193
Brian Norris8b6e50c2011-05-25 14:59:01 -07001194 /* Calculate ECC */
Alexey Korolev3d459552008-05-15 17:23:18 +01001195 for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size)
1196 chip->ecc.calculate(mtd, p, &chip->buffers->ecccalc[i]);
1197
Brian Norris8b6e50c2011-05-25 14:59:01 -07001198 /*
1199 * The performance is faster if we position offsets according to
Brian Norris7854d3f2011-06-23 14:12:08 -07001200 * ecc.pos. Let's make sure that there are no gaps in ECC positions.
Brian Norris8b6e50c2011-05-25 14:59:01 -07001201 */
Alexey Korolev3d459552008-05-15 17:23:18 +01001202 for (i = 0; i < eccfrag_len - 1; i++) {
1203 if (eccpos[i + start_step * chip->ecc.bytes] + 1 !=
1204 eccpos[i + start_step * chip->ecc.bytes + 1]) {
1205 gaps = 1;
1206 break;
1207 }
1208 }
1209 if (gaps) {
1210 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
1211 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
1212 } else {
Brian Norris8b6e50c2011-05-25 14:59:01 -07001213 /*
Brian Norris7854d3f2011-06-23 14:12:08 -07001214 * Send the command to read the particular ECC bytes take care
Brian Norris8b6e50c2011-05-25 14:59:01 -07001215 * about buswidth alignment in read_buf.
1216 */
Florian Fainelli7351d3a2010-09-07 13:23:45 +02001217 index = start_step * chip->ecc.bytes;
1218
1219 aligned_pos = eccpos[index] & ~(busw - 1);
Alexey Korolev3d459552008-05-15 17:23:18 +01001220 aligned_len = eccfrag_len;
Florian Fainelli7351d3a2010-09-07 13:23:45 +02001221 if (eccpos[index] & (busw - 1))
Alexey Korolev3d459552008-05-15 17:23:18 +01001222 aligned_len++;
Florian Fainelli7351d3a2010-09-07 13:23:45 +02001223 if (eccpos[index + (num_steps * chip->ecc.bytes)] & (busw - 1))
Alexey Korolev3d459552008-05-15 17:23:18 +01001224 aligned_len++;
1225
Florian Fainelli7351d3a2010-09-07 13:23:45 +02001226 chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
1227 mtd->writesize + aligned_pos, -1);
Alexey Korolev3d459552008-05-15 17:23:18 +01001228 chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len);
1229 }
1230
1231 for (i = 0; i < eccfrag_len; i++)
Florian Fainelli7351d3a2010-09-07 13:23:45 +02001232 chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + index]];
Alexey Korolev3d459552008-05-15 17:23:18 +01001233
1234 p = bufpoi + data_col_addr;
1235 for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) {
1236 int stat;
1237
Florian Fainelli7351d3a2010-09-07 13:23:45 +02001238 stat = chip->ecc.correct(mtd, p,
1239 &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
Baruch Siach12c8eb92010-08-09 07:20:23 +03001240 if (stat < 0)
Alexey Korolev3d459552008-05-15 17:23:18 +01001241 mtd->ecc_stats.failed++;
1242 else
1243 mtd->ecc_stats.corrected += stat;
1244 }
1245 return 0;
1246}
1247
1248/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001249 * nand_read_page_hwecc - [REPLACEABLE] hardware ECC based page read function
Brian Norris8b6e50c2011-05-25 14:59:01 -07001250 * @mtd: mtd info structure
1251 * @chip: nand chip info structure
1252 * @buf: buffer to store read data
1253 * @page: page number to read
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001254 *
Brian Norris7854d3f2011-06-23 14:12:08 -07001255 * Not for syndrome calculating ECC controllers which need a special oob layout.
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001256 */
1257static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
Sneha Narnakaje46a8cf22009-09-18 12:51:46 -07001258 uint8_t *buf, int page)
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001259{
1260 int i, eccsize = chip->ecc.size;
1261 int eccbytes = chip->ecc.bytes;
1262 int eccsteps = chip->ecc.steps;
1263 uint8_t *p = buf;
David Woodhouse4bf63fc2006-09-25 17:08:04 +01001264 uint8_t *ecc_calc = chip->buffers->ecccalc;
1265 uint8_t *ecc_code = chip->buffers->ecccode;
Ben Dooks8b099a32007-05-28 19:17:54 +01001266 uint32_t *eccpos = chip->ecc.layout->eccpos;
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001267
1268 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
1269 chip->ecc.hwctl(mtd, NAND_ECC_READ);
1270 chip->read_buf(mtd, p, eccsize);
1271 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
1272 }
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02001273 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001274
1275 for (i = 0; i < chip->ecc.total; i++)
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02001276 ecc_code[i] = chip->oob_poi[eccpos[i]];
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001277
1278 eccsteps = chip->ecc.steps;
1279 p = buf;
1280
1281 for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
1282 int stat;
1283
1284 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
Matt Reimerc32b8dc2007-10-17 14:33:23 -07001285 if (stat < 0)
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001286 mtd->ecc_stats.failed++;
1287 else
1288 mtd->ecc_stats.corrected += stat;
1289 }
1290 return 0;
1291}
1292
1293/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001294 * nand_read_page_hwecc_oob_first - [REPLACEABLE] hw ecc, read oob first
Brian Norris8b6e50c2011-05-25 14:59:01 -07001295 * @mtd: mtd info structure
1296 * @chip: nand chip info structure
1297 * @buf: buffer to store read data
1298 * @page: page number to read
Sneha Narnakaje6e0cb132009-09-18 12:51:47 -07001299 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07001300 * Hardware ECC for large page chips, require OOB to be read first. For this
1301 * ECC mode, the write_page method is re-used from ECC_HW. These methods
1302 * read/write ECC from the OOB area, unlike the ECC_HW_SYNDROME support with
1303 * multiple ECC steps, follows the "infix ECC" scheme and reads/writes ECC from
1304 * the data area, by overwriting the NAND manufacturer bad block markings.
Sneha Narnakaje6e0cb132009-09-18 12:51:47 -07001305 */
1306static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
1307 struct nand_chip *chip, uint8_t *buf, int page)
1308{
1309 int i, eccsize = chip->ecc.size;
1310 int eccbytes = chip->ecc.bytes;
1311 int eccsteps = chip->ecc.steps;
1312 uint8_t *p = buf;
1313 uint8_t *ecc_code = chip->buffers->ecccode;
1314 uint32_t *eccpos = chip->ecc.layout->eccpos;
1315 uint8_t *ecc_calc = chip->buffers->ecccalc;
1316
1317 /* Read the OOB area first */
1318 chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
1319 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
1320 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
1321
1322 for (i = 0; i < chip->ecc.total; i++)
1323 ecc_code[i] = chip->oob_poi[eccpos[i]];
1324
1325 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
1326 int stat;
1327
1328 chip->ecc.hwctl(mtd, NAND_ECC_READ);
1329 chip->read_buf(mtd, p, eccsize);
1330 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
1331
1332 stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL);
1333 if (stat < 0)
1334 mtd->ecc_stats.failed++;
1335 else
1336 mtd->ecc_stats.corrected += stat;
1337 }
1338 return 0;
1339}
1340
1341/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001342 * nand_read_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page read
Brian Norris8b6e50c2011-05-25 14:59:01 -07001343 * @mtd: mtd info structure
1344 * @chip: nand chip info structure
1345 * @buf: buffer to store read data
1346 * @page: page number to read
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001347 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07001348 * The hw generator calculates the error syndrome automatically. Therefore we
1349 * need a special oob layout and handling.
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001350 */
1351static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
Sneha Narnakaje46a8cf22009-09-18 12:51:46 -07001352 uint8_t *buf, int page)
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001353{
1354 int i, eccsize = chip->ecc.size;
1355 int eccbytes = chip->ecc.bytes;
1356 int eccsteps = chip->ecc.steps;
1357 uint8_t *p = buf;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02001358 uint8_t *oob = chip->oob_poi;
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001359
1360 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
1361 int stat;
1362
1363 chip->ecc.hwctl(mtd, NAND_ECC_READ);
1364 chip->read_buf(mtd, p, eccsize);
1365
1366 if (chip->ecc.prepad) {
1367 chip->read_buf(mtd, oob, chip->ecc.prepad);
1368 oob += chip->ecc.prepad;
1369 }
1370
1371 chip->ecc.hwctl(mtd, NAND_ECC_READSYN);
1372 chip->read_buf(mtd, oob, eccbytes);
1373 stat = chip->ecc.correct(mtd, p, oob, NULL);
1374
Matt Reimerc32b8dc2007-10-17 14:33:23 -07001375 if (stat < 0)
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001376 mtd->ecc_stats.failed++;
1377 else
1378 mtd->ecc_stats.corrected += stat;
1379
1380 oob += eccbytes;
1381
1382 if (chip->ecc.postpad) {
1383 chip->read_buf(mtd, oob, chip->ecc.postpad);
1384 oob += chip->ecc.postpad;
1385 }
1386 }
1387
1388 /* Calculate remaining oob bytes */
Vitaly Wool7e4178f2006-06-07 09:34:37 +04001389 i = mtd->oobsize - (oob - chip->oob_poi);
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001390 if (i)
1391 chip->read_buf(mtd, oob, i);
1392
1393 return 0;
1394}
1395
1396/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001397 * nand_transfer_oob - [INTERN] Transfer oob to client buffer
Brian Norris8b6e50c2011-05-25 14:59:01 -07001398 * @chip: nand chip structure
1399 * @oob: oob destination address
1400 * @ops: oob ops structure
1401 * @len: size of oob to transfer
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001402 */
1403static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
Vitaly Wool70145682006-11-03 18:20:38 +03001404 struct mtd_oob_ops *ops, size_t len)
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001405{
Florian Fainellif8ac0412010-09-07 13:23:43 +02001406 switch (ops->mode) {
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001407
Brian Norris0612b9d2011-08-30 18:45:40 -07001408 case MTD_OPS_PLACE_OOB:
1409 case MTD_OPS_RAW:
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001410 memcpy(oob, chip->oob_poi + ops->ooboffs, len);
1411 return oob + len;
1412
Brian Norris0612b9d2011-08-30 18:45:40 -07001413 case MTD_OPS_AUTO_OOB: {
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001414 struct nand_oobfree *free = chip->ecc.layout->oobfree;
Thomas Gleixner7bc33122006-06-20 20:05:05 +02001415 uint32_t boffs = 0, roffs = ops->ooboffs;
1416 size_t bytes = 0;
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001417
Florian Fainellif8ac0412010-09-07 13:23:43 +02001418 for (; free->length && len; free++, len -= bytes) {
Brian Norris8b6e50c2011-05-25 14:59:01 -07001419 /* Read request not from offset 0? */
Thomas Gleixner7bc33122006-06-20 20:05:05 +02001420 if (unlikely(roffs)) {
1421 if (roffs >= free->length) {
1422 roffs -= free->length;
1423 continue;
1424 }
1425 boffs = free->offset + roffs;
1426 bytes = min_t(size_t, len,
1427 (free->length - roffs));
1428 roffs = 0;
1429 } else {
1430 bytes = min_t(size_t, len, free->length);
1431 boffs = free->offset;
1432 }
1433 memcpy(oob, chip->oob_poi + boffs, bytes);
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001434 oob += bytes;
1435 }
1436 return oob;
1437 }
1438 default:
1439 BUG();
1440 }
1441 return NULL;
1442}
1443
1444/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001445 * nand_do_read_ops - [INTERN] Read data with ECC
Brian Norris8b6e50c2011-05-25 14:59:01 -07001446 * @mtd: MTD device structure
1447 * @from: offset to read from
1448 * @ops: oob ops structure
David A. Marlin068e3c02005-01-24 03:07:46 +00001449 *
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001450 * Internal function. Called with chip held.
David A. Marlin068e3c02005-01-24 03:07:46 +00001451 */
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001452static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1453 struct mtd_oob_ops *ops)
David A. Marlin068e3c02005-01-24 03:07:46 +00001454{
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001455 int chipnr, page, realpage, col, bytes, aligned;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02001456 struct nand_chip *chip = mtd->priv;
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001457 struct mtd_ecc_stats stats;
1458 int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
1459 int sndcmd = 1;
1460 int ret = 0;
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001461 uint32_t readlen = ops->len;
Vitaly Wool70145682006-11-03 18:20:38 +03001462 uint32_t oobreadlen = ops->ooblen;
Brian Norris0612b9d2011-08-30 18:45:40 -07001463 uint32_t max_oobsize = ops->mode == MTD_OPS_AUTO_OOB ?
Maxim Levitsky9aca3342010-02-22 20:39:35 +02001464 mtd->oobavail : mtd->oobsize;
1465
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001466 uint8_t *bufpoi, *oob, *buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001468 stats = mtd->ecc_stats;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02001470 chipnr = (int)(from >> chip->chip_shift);
1471 chip->select_chip(mtd, chipnr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02001473 realpage = (int)(from >> chip->page_shift);
1474 page = realpage & chip->pagemask;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001476 col = (int)(from & (mtd->writesize - 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001478 buf = ops->datbuf;
1479 oob = ops->oobbuf;
1480
Florian Fainellif8ac0412010-09-07 13:23:43 +02001481 while (1) {
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001482 bytes = min(mtd->writesize - col, readlen);
1483 aligned = (bytes == mtd->writesize);
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00001484
Brian Norris8b6e50c2011-05-25 14:59:01 -07001485 /* Is the current page in the buffer? */
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001486 if (realpage != chip->pagebuf || oob) {
David Woodhouse4bf63fc2006-09-25 17:08:04 +01001487 bufpoi = aligned ? buf : chip->buffers->databuf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001489 if (likely(sndcmd)) {
1490 chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
1491 sndcmd = 0;
1492 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001494 /* Now read the page into the buffer */
Brian Norris0612b9d2011-08-30 18:45:40 -07001495 if (unlikely(ops->mode == MTD_OPS_RAW))
Sneha Narnakaje46a8cf22009-09-18 12:51:46 -07001496 ret = chip->ecc.read_page_raw(mtd, chip,
1497 bufpoi, page);
Alexey Korolev3d459552008-05-15 17:23:18 +01001498 else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob)
Florian Fainelli7351d3a2010-09-07 13:23:45 +02001499 ret = chip->ecc.read_subpage(mtd, chip,
1500 col, bytes, bufpoi);
David Woodhouse956e9442006-09-25 17:12:39 +01001501 else
Sneha Narnakaje46a8cf22009-09-18 12:51:46 -07001502 ret = chip->ecc.read_page(mtd, chip, bufpoi,
1503 page);
Brian Norris6d77b9d2011-09-07 13:13:40 -07001504 if (ret < 0) {
1505 if (!aligned)
1506 /* Invalidate page cache */
1507 chip->pagebuf = -1;
David Woodhousee0c7d762006-05-13 18:07:53 +01001508 break;
Brian Norris6d77b9d2011-09-07 13:13:40 -07001509 }
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001510
1511 /* Transfer not aligned data */
1512 if (!aligned) {
Artem Bityutskiyc1194c72010-09-03 22:01:16 +03001513 if (!NAND_SUBPAGE_READ(chip) && !oob &&
Brian Norris6d77b9d2011-09-07 13:13:40 -07001514 !(mtd->ecc_stats.failed - stats.failed) &&
1515 (ops->mode != MTD_OPS_RAW))
Alexey Korolev3d459552008-05-15 17:23:18 +01001516 chip->pagebuf = realpage;
Brian Norris6d77b9d2011-09-07 13:13:40 -07001517 else
1518 /* Invalidate page cache */
1519 chip->pagebuf = -1;
David Woodhouse4bf63fc2006-09-25 17:08:04 +01001520 memcpy(buf, chip->buffers->databuf + col, bytes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521 }
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00001522
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001523 buf += bytes;
1524
1525 if (unlikely(oob)) {
Maxim Levitsky9aca3342010-02-22 20:39:35 +02001526
Maxim Levitskyb64d39d2010-02-22 20:39:37 +02001527 int toread = min(oobreadlen, max_oobsize);
1528
1529 if (toread) {
1530 oob = nand_transfer_oob(chip,
1531 oob, ops, toread);
1532 oobreadlen -= toread;
1533 }
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001534 }
1535
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001536 if (!(chip->options & NAND_NO_READRDY)) {
1537 /*
1538 * Apply delay or wait for ready/busy pin. Do
1539 * this before the AUTOINCR check, so no
1540 * problems arise if a chip which does auto
1541 * increment is marked as NOAUTOINCR by the
1542 * board driver.
1543 */
1544 if (!chip->dev_ready)
1545 udelay(chip->chip_delay);
1546 else
1547 nand_wait_ready(mtd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548 }
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001549 } else {
David Woodhouse4bf63fc2006-09-25 17:08:04 +01001550 memcpy(buf, chip->buffers->databuf + col, bytes);
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001551 buf += bytes;
1552 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001554 readlen -= bytes;
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00001555
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001556 if (!readlen)
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00001557 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558
Brian Norris8b6e50c2011-05-25 14:59:01 -07001559 /* For subsequent reads align to page boundary */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560 col = 0;
1561 /* Increment page address */
1562 realpage++;
1563
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02001564 page = realpage & chip->pagemask;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565 /* Check, if we cross a chip boundary */
1566 if (!page) {
1567 chipnr++;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02001568 chip->select_chip(mtd, -1);
1569 chip->select_chip(mtd, chipnr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570 }
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001571
Brian Norris8b6e50c2011-05-25 14:59:01 -07001572 /*
1573 * Check, if the chip supports auto page increment or if we
1574 * have hit a block boundary.
David Woodhousee0c7d762006-05-13 18:07:53 +01001575 */
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001576 if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck))
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00001577 sndcmd = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578 }
1579
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001580 ops->retlen = ops->len - (size_t) readlen;
Vitaly Wool70145682006-11-03 18:20:38 +03001581 if (oob)
1582 ops->oobretlen = ops->ooblen - oobreadlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001584 if (ret)
1585 return ret;
1586
Thomas Gleixner9a1fcdf2006-05-29 14:56:39 +02001587 if (mtd->ecc_stats.failed - stats.failed)
1588 return -EBADMSG;
1589
1590 return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001591}
1592
1593/**
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001594 * nand_read - [MTD Interface] MTD compatibility function for nand_do_read_ecc
Brian Norris8b6e50c2011-05-25 14:59:01 -07001595 * @mtd: MTD device structure
1596 * @from: offset to read from
1597 * @len: number of bytes to read
1598 * @retlen: pointer to variable to store the number of read bytes
1599 * @buf: the databuffer to put data
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001600 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07001601 * Get hold of the chip and call nand_do_read.
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001602 */
1603static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
1604 size_t *retlen, uint8_t *buf)
1605{
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001606 struct nand_chip *chip = mtd->priv;
Brian Norris4a89ff82011-08-30 18:45:45 -07001607 struct mtd_oob_ops ops;
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001608 int ret;
1609
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001610 /* Do not allow reads past end of device */
1611 if ((from + len) > mtd->size)
1612 return -EINVAL;
1613 if (!len)
1614 return 0;
1615
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001616 nand_get_device(chip, mtd, FL_READING);
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001617
Brian Norris4a89ff82011-08-30 18:45:45 -07001618 ops.len = len;
1619 ops.datbuf = buf;
1620 ops.oobbuf = NULL;
Brian Norris23b1a992011-10-14 20:09:33 -07001621 ops.mode = 0;
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001622
Brian Norris4a89ff82011-08-30 18:45:45 -07001623 ret = nand_do_read_ops(mtd, from, &ops);
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001624
Brian Norris4a89ff82011-08-30 18:45:45 -07001625 *retlen = ops.retlen;
Richard Purdie7fd5aec2006-08-27 01:23:33 -07001626
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02001627 nand_release_device(mtd);
1628
1629 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630}
1631
1632/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001633 * nand_read_oob_std - [REPLACEABLE] the most common OOB data read function
Brian Norris8b6e50c2011-05-25 14:59:01 -07001634 * @mtd: mtd info structure
1635 * @chip: nand chip info structure
1636 * @page: page number to read
1637 * @sndcmd: flag whether to issue read command or not
Thomas Gleixner7bc33122006-06-20 20:05:05 +02001638 */
1639static int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
1640 int page, int sndcmd)
1641{
1642 if (sndcmd) {
1643 chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
1644 sndcmd = 0;
1645 }
1646 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
1647 return sndcmd;
1648}
1649
1650/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001651 * nand_read_oob_syndrome - [REPLACEABLE] OOB data read function for HW ECC
Thomas Gleixner7bc33122006-06-20 20:05:05 +02001652 * with syndromes
Brian Norris8b6e50c2011-05-25 14:59:01 -07001653 * @mtd: mtd info structure
1654 * @chip: nand chip info structure
1655 * @page: page number to read
1656 * @sndcmd: flag whether to issue read command or not
Thomas Gleixner7bc33122006-06-20 20:05:05 +02001657 */
1658static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
1659 int page, int sndcmd)
1660{
1661 uint8_t *buf = chip->oob_poi;
1662 int length = mtd->oobsize;
1663 int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
1664 int eccsize = chip->ecc.size;
1665 uint8_t *bufpoi = buf;
1666 int i, toread, sndrnd = 0, pos;
1667
1668 chip->cmdfunc(mtd, NAND_CMD_READ0, chip->ecc.size, page);
1669 for (i = 0; i < chip->ecc.steps; i++) {
1670 if (sndrnd) {
1671 pos = eccsize + i * (eccsize + chunk);
1672 if (mtd->writesize > 512)
1673 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, pos, -1);
1674 else
1675 chip->cmdfunc(mtd, NAND_CMD_READ0, pos, page);
1676 } else
1677 sndrnd = 1;
1678 toread = min_t(int, length, chunk);
1679 chip->read_buf(mtd, bufpoi, toread);
1680 bufpoi += toread;
1681 length -= toread;
1682 }
1683 if (length > 0)
1684 chip->read_buf(mtd, bufpoi, length);
1685
1686 return 1;
1687}
1688
1689/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001690 * nand_write_oob_std - [REPLACEABLE] the most common OOB data write function
Brian Norris8b6e50c2011-05-25 14:59:01 -07001691 * @mtd: mtd info structure
1692 * @chip: nand chip info structure
1693 * @page: page number to write
Thomas Gleixner7bc33122006-06-20 20:05:05 +02001694 */
1695static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
1696 int page)
1697{
1698 int status = 0;
1699 const uint8_t *buf = chip->oob_poi;
1700 int length = mtd->oobsize;
1701
1702 chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
1703 chip->write_buf(mtd, buf, length);
1704 /* Send command to program the OOB data */
1705 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1706
1707 status = chip->waitfunc(mtd, chip);
1708
Savin Zlobec0d420f92006-06-21 11:51:20 +02001709 return status & NAND_STATUS_FAIL ? -EIO : 0;
Thomas Gleixner7bc33122006-06-20 20:05:05 +02001710}
1711
1712/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001713 * nand_write_oob_syndrome - [REPLACEABLE] OOB data write function for HW ECC
Brian Norris8b6e50c2011-05-25 14:59:01 -07001714 * with syndrome - only for large page flash
1715 * @mtd: mtd info structure
1716 * @chip: nand chip info structure
1717 * @page: page number to write
Thomas Gleixner7bc33122006-06-20 20:05:05 +02001718 */
1719static int nand_write_oob_syndrome(struct mtd_info *mtd,
1720 struct nand_chip *chip, int page)
1721{
1722 int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
1723 int eccsize = chip->ecc.size, length = mtd->oobsize;
1724 int i, len, pos, status = 0, sndcmd = 0, steps = chip->ecc.steps;
1725 const uint8_t *bufpoi = chip->oob_poi;
1726
1727 /*
1728 * data-ecc-data-ecc ... ecc-oob
1729 * or
1730 * data-pad-ecc-pad-data-pad .... ecc-pad-oob
1731 */
1732 if (!chip->ecc.prepad && !chip->ecc.postpad) {
1733 pos = steps * (eccsize + chunk);
1734 steps = 0;
1735 } else
Vitaly Wool8b0036e2006-07-11 09:11:25 +02001736 pos = eccsize;
Thomas Gleixner7bc33122006-06-20 20:05:05 +02001737
1738 chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page);
1739 for (i = 0; i < steps; i++) {
1740 if (sndcmd) {
1741 if (mtd->writesize <= 512) {
1742 uint32_t fill = 0xFFFFFFFF;
1743
1744 len = eccsize;
1745 while (len > 0) {
1746 int num = min_t(int, len, 4);
1747 chip->write_buf(mtd, (uint8_t *)&fill,
1748 num);
1749 len -= num;
1750 }
1751 } else {
1752 pos = eccsize + i * (eccsize + chunk);
1753 chip->cmdfunc(mtd, NAND_CMD_RNDIN, pos, -1);
1754 }
1755 } else
1756 sndcmd = 1;
1757 len = min_t(int, length, chunk);
1758 chip->write_buf(mtd, bufpoi, len);
1759 bufpoi += len;
1760 length -= len;
1761 }
1762 if (length > 0)
1763 chip->write_buf(mtd, bufpoi, length);
1764
1765 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1766 status = chip->waitfunc(mtd, chip);
1767
1768 return status & NAND_STATUS_FAIL ? -EIO : 0;
1769}
1770
1771/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001772 * nand_do_read_oob - [INTERN] NAND read out-of-band
Brian Norris8b6e50c2011-05-25 14:59:01 -07001773 * @mtd: MTD device structure
1774 * @from: offset to read from
1775 * @ops: oob operations description structure
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07001777 * NAND read out-of-band data from the spare area.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 */
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001779static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1780 struct mtd_oob_ops *ops)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781{
Thomas Gleixner7bc33122006-06-20 20:05:05 +02001782 int page, realpage, chipnr, sndcmd = 1;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02001783 struct nand_chip *chip = mtd->priv;
Brian Norris041e4572011-06-23 16:45:24 -07001784 struct mtd_ecc_stats stats;
Thomas Gleixner7314e9e2006-05-25 09:51:54 +02001785 int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
Vitaly Wool70145682006-11-03 18:20:38 +03001786 int readlen = ops->ooblen;
1787 int len;
Thomas Gleixner7bc33122006-06-20 20:05:05 +02001788 uint8_t *buf = ops->oobbuf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789
Brian Norris289c0522011-07-19 10:06:09 -07001790 pr_debug("%s: from = 0x%08Lx, len = %i\n",
vimal singh20d8e242009-07-07 15:49:49 +05301791 __func__, (unsigned long long)from, readlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792
Brian Norris041e4572011-06-23 16:45:24 -07001793 stats = mtd->ecc_stats;
1794
Brian Norris0612b9d2011-08-30 18:45:40 -07001795 if (ops->mode == MTD_OPS_AUTO_OOB)
Vitaly Wool70145682006-11-03 18:20:38 +03001796 len = chip->ecc.layout->oobavail;
Adrian Hunter03736152007-01-31 17:58:29 +02001797 else
1798 len = mtd->oobsize;
1799
1800 if (unlikely(ops->ooboffs >= len)) {
Brian Norris289c0522011-07-19 10:06:09 -07001801 pr_debug("%s: attempt to start read outside oob\n",
1802 __func__);
Adrian Hunter03736152007-01-31 17:58:29 +02001803 return -EINVAL;
1804 }
1805
1806 /* Do not allow reads past end of device */
1807 if (unlikely(from >= mtd->size ||
1808 ops->ooboffs + readlen > ((mtd->size >> chip->page_shift) -
1809 (from >> chip->page_shift)) * len)) {
Brian Norris289c0522011-07-19 10:06:09 -07001810 pr_debug("%s: attempt to read beyond end of device\n",
1811 __func__);
Adrian Hunter03736152007-01-31 17:58:29 +02001812 return -EINVAL;
1813 }
Vitaly Wool70145682006-11-03 18:20:38 +03001814
Thomas Gleixner7314e9e2006-05-25 09:51:54 +02001815 chipnr = (int)(from >> chip->chip_shift);
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02001816 chip->select_chip(mtd, chipnr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817
Thomas Gleixner7314e9e2006-05-25 09:51:54 +02001818 /* Shift to get page */
1819 realpage = (int)(from >> chip->page_shift);
1820 page = realpage & chip->pagemask;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821
Florian Fainellif8ac0412010-09-07 13:23:43 +02001822 while (1) {
Brian Norris0612b9d2011-08-30 18:45:40 -07001823 if (ops->mode == MTD_OPS_RAW)
Brian Norrisc46f6482011-08-30 18:45:38 -07001824 sndcmd = chip->ecc.read_oob_raw(mtd, chip, page, sndcmd);
1825 else
1826 sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
Vitaly Wool70145682006-11-03 18:20:38 +03001827
1828 len = min(len, readlen);
1829 buf = nand_transfer_oob(chip, buf, ops, len);
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001830
Thomas Gleixner7314e9e2006-05-25 09:51:54 +02001831 if (!(chip->options & NAND_NO_READRDY)) {
1832 /*
1833 * Apply delay or wait for ready/busy pin. Do this
1834 * before the AUTOINCR check, so no problems arise if a
1835 * chip which does auto increment is marked as
1836 * NOAUTOINCR by the board driver.
Thomas Gleixner19870da2005-07-15 14:53:51 +01001837 */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02001838 if (!chip->dev_ready)
1839 udelay(chip->chip_delay);
Thomas Gleixner19870da2005-07-15 14:53:51 +01001840 else
1841 nand_wait_ready(mtd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842 }
Thomas Gleixner7314e9e2006-05-25 09:51:54 +02001843
Vitaly Wool70145682006-11-03 18:20:38 +03001844 readlen -= len;
Savin Zlobec0d420f92006-06-21 11:51:20 +02001845 if (!readlen)
1846 break;
1847
Thomas Gleixner7314e9e2006-05-25 09:51:54 +02001848 /* Increment page address */
1849 realpage++;
1850
1851 page = realpage & chip->pagemask;
1852 /* Check, if we cross a chip boundary */
1853 if (!page) {
1854 chipnr++;
1855 chip->select_chip(mtd, -1);
1856 chip->select_chip(mtd, chipnr);
1857 }
1858
Brian Norris8b6e50c2011-05-25 14:59:01 -07001859 /*
1860 * Check, if the chip supports auto page increment or if we
1861 * have hit a block boundary.
Thomas Gleixner7314e9e2006-05-25 09:51:54 +02001862 */
1863 if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck))
1864 sndcmd = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 }
1866
Vitaly Wool70145682006-11-03 18:20:38 +03001867 ops->oobretlen = ops->ooblen;
Brian Norris041e4572011-06-23 16:45:24 -07001868
1869 if (mtd->ecc_stats.failed - stats.failed)
1870 return -EBADMSG;
1871
1872 return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873}
1874
1875/**
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001876 * nand_read_oob - [MTD Interface] NAND read data and/or out-of-band
Brian Norris8b6e50c2011-05-25 14:59:01 -07001877 * @mtd: MTD device structure
1878 * @from: offset to read from
1879 * @ops: oob operation description structure
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07001881 * NAND read data and/or out-of-band data.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 */
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001883static int nand_read_oob(struct mtd_info *mtd, loff_t from,
1884 struct mtd_oob_ops *ops)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02001886 struct nand_chip *chip = mtd->priv;
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001887 int ret = -ENOTSUPP;
1888
1889 ops->retlen = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890
1891 /* Do not allow reads past end of device */
Vitaly Wool70145682006-11-03 18:20:38 +03001892 if (ops->datbuf && (from + ops->len) > mtd->size) {
Brian Norris289c0522011-07-19 10:06:09 -07001893 pr_debug("%s: attempt to read beyond end of device\n",
1894 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895 return -EINVAL;
1896 }
1897
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02001898 nand_get_device(chip, mtd, FL_READING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899
Florian Fainellif8ac0412010-09-07 13:23:43 +02001900 switch (ops->mode) {
Brian Norris0612b9d2011-08-30 18:45:40 -07001901 case MTD_OPS_PLACE_OOB:
1902 case MTD_OPS_AUTO_OOB:
1903 case MTD_OPS_RAW:
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001904 break;
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00001905
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001906 default:
1907 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908 }
1909
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001910 if (!ops->datbuf)
1911 ret = nand_do_read_oob(mtd, from, ops);
1912 else
1913 ret = nand_do_read_ops(mtd, from, ops);
1914
Florian Fainelli7351d3a2010-09-07 13:23:45 +02001915out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916 nand_release_device(mtd);
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001917 return ret;
1918}
1919
1920
1921/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001922 * nand_write_page_raw - [INTERN] raw page write function
Brian Norris8b6e50c2011-05-25 14:59:01 -07001923 * @mtd: mtd info structure
1924 * @chip: nand chip info structure
1925 * @buf: data buffer
David Brownell52ff49d2009-03-04 12:01:36 -08001926 *
Brian Norris7854d3f2011-06-23 14:12:08 -07001927 * Not for syndrome calculating ECC controllers, which use a special oob layout.
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001928 */
1929static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
1930 const uint8_t *buf)
1931{
1932 chip->write_buf(mtd, buf, mtd->writesize);
1933 chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934}
1935
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00001936/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001937 * nand_write_page_raw_syndrome - [INTERN] raw page write function
Brian Norris8b6e50c2011-05-25 14:59:01 -07001938 * @mtd: mtd info structure
1939 * @chip: nand chip info structure
1940 * @buf: data buffer
David Brownell52ff49d2009-03-04 12:01:36 -08001941 *
1942 * We need a special oob layout and handling even when ECC isn't checked.
1943 */
Florian Fainelli7351d3a2010-09-07 13:23:45 +02001944static void nand_write_page_raw_syndrome(struct mtd_info *mtd,
1945 struct nand_chip *chip,
1946 const uint8_t *buf)
David Brownell52ff49d2009-03-04 12:01:36 -08001947{
1948 int eccsize = chip->ecc.size;
1949 int eccbytes = chip->ecc.bytes;
1950 uint8_t *oob = chip->oob_poi;
1951 int steps, size;
1952
1953 for (steps = chip->ecc.steps; steps > 0; steps--) {
1954 chip->write_buf(mtd, buf, eccsize);
1955 buf += eccsize;
1956
1957 if (chip->ecc.prepad) {
1958 chip->write_buf(mtd, oob, chip->ecc.prepad);
1959 oob += chip->ecc.prepad;
1960 }
1961
1962 chip->read_buf(mtd, oob, eccbytes);
1963 oob += eccbytes;
1964
1965 if (chip->ecc.postpad) {
1966 chip->write_buf(mtd, oob, chip->ecc.postpad);
1967 oob += chip->ecc.postpad;
1968 }
1969 }
1970
1971 size = mtd->oobsize - (oob - chip->oob_poi);
1972 if (size)
1973 chip->write_buf(mtd, oob, size);
1974}
1975/**
Brian Norris7854d3f2011-06-23 14:12:08 -07001976 * nand_write_page_swecc - [REPLACEABLE] software ECC based page write function
Brian Norris8b6e50c2011-05-25 14:59:01 -07001977 * @mtd: mtd info structure
1978 * @chip: nand chip info structure
1979 * @buf: data buffer
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02001980 */
1981static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
1982 const uint8_t *buf)
1983{
1984 int i, eccsize = chip->ecc.size;
1985 int eccbytes = chip->ecc.bytes;
1986 int eccsteps = chip->ecc.steps;
David Woodhouse4bf63fc2006-09-25 17:08:04 +01001987 uint8_t *ecc_calc = chip->buffers->ecccalc;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02001988 const uint8_t *p = buf;
Ben Dooks8b099a32007-05-28 19:17:54 +01001989 uint32_t *eccpos = chip->ecc.layout->eccpos;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02001990
Brian Norris7854d3f2011-06-23 14:12:08 -07001991 /* Software ECC calculation */
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001992 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
1993 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02001994
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02001995 for (i = 0; i < chip->ecc.total; i++)
1996 chip->oob_poi[eccpos[i]] = ecc_calc[i];
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02001997
Thomas Gleixner90424de2007-04-05 11:44:05 +02001998 chip->ecc.write_page_raw(mtd, chip, buf);
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02001999}
2000
2001/**
Brian Norris7854d3f2011-06-23 14:12:08 -07002002 * nand_write_page_hwecc - [REPLACEABLE] hardware ECC based page write function
Brian Norris8b6e50c2011-05-25 14:59:01 -07002003 * @mtd: mtd info structure
2004 * @chip: nand chip info structure
2005 * @buf: data buffer
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002006 */
2007static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
2008 const uint8_t *buf)
2009{
2010 int i, eccsize = chip->ecc.size;
2011 int eccbytes = chip->ecc.bytes;
2012 int eccsteps = chip->ecc.steps;
David Woodhouse4bf63fc2006-09-25 17:08:04 +01002013 uint8_t *ecc_calc = chip->buffers->ecccalc;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002014 const uint8_t *p = buf;
Ben Dooks8b099a32007-05-28 19:17:54 +01002015 uint32_t *eccpos = chip->ecc.layout->eccpos;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002016
2017 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
2018 chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
David Woodhouse29da9ce2006-05-26 23:05:44 +01002019 chip->write_buf(mtd, p, eccsize);
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002020 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
2021 }
2022
2023 for (i = 0; i < chip->ecc.total; i++)
2024 chip->oob_poi[eccpos[i]] = ecc_calc[i];
2025
2026 chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
2027}
2028
2029/**
Brian Norris7854d3f2011-06-23 14:12:08 -07002030 * nand_write_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page write
Brian Norris8b6e50c2011-05-25 14:59:01 -07002031 * @mtd: mtd info structure
2032 * @chip: nand chip info structure
2033 * @buf: data buffer
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002034 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07002035 * The hw generator calculates the error syndrome automatically. Therefore we
2036 * need a special oob layout and handling.
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002037 */
2038static void nand_write_page_syndrome(struct mtd_info *mtd,
2039 struct nand_chip *chip, const uint8_t *buf)
2040{
2041 int i, eccsize = chip->ecc.size;
2042 int eccbytes = chip->ecc.bytes;
2043 int eccsteps = chip->ecc.steps;
2044 const uint8_t *p = buf;
2045 uint8_t *oob = chip->oob_poi;
2046
2047 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
2048
2049 chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
2050 chip->write_buf(mtd, p, eccsize);
2051
2052 if (chip->ecc.prepad) {
2053 chip->write_buf(mtd, oob, chip->ecc.prepad);
2054 oob += chip->ecc.prepad;
2055 }
2056
2057 chip->ecc.calculate(mtd, p, oob);
2058 chip->write_buf(mtd, oob, eccbytes);
2059 oob += eccbytes;
2060
2061 if (chip->ecc.postpad) {
2062 chip->write_buf(mtd, oob, chip->ecc.postpad);
2063 oob += chip->ecc.postpad;
2064 }
2065 }
2066
2067 /* Calculate remaining oob bytes */
Vitaly Wool7e4178f2006-06-07 09:34:37 +04002068 i = mtd->oobsize - (oob - chip->oob_poi);
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002069 if (i)
2070 chip->write_buf(mtd, oob, i);
2071}
2072
2073/**
David Woodhouse956e9442006-09-25 17:12:39 +01002074 * nand_write_page - [REPLACEABLE] write one page
Brian Norris8b6e50c2011-05-25 14:59:01 -07002075 * @mtd: MTD device structure
2076 * @chip: NAND chip descriptor
2077 * @buf: the data to write
2078 * @page: page number to write
2079 * @cached: cached programming
2080 * @raw: use _raw version of write_page
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002081 */
2082static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
David Woodhouse956e9442006-09-25 17:12:39 +01002083 const uint8_t *buf, int page, int cached, int raw)
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002084{
2085 int status;
2086
2087 chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
2088
David Woodhouse956e9442006-09-25 17:12:39 +01002089 if (unlikely(raw))
2090 chip->ecc.write_page_raw(mtd, chip, buf);
2091 else
2092 chip->ecc.write_page(mtd, chip, buf);
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002093
2094 /*
Brian Norris7854d3f2011-06-23 14:12:08 -07002095 * Cached progamming disabled for now. Not sure if it's worth the
Brian Norris8b6e50c2011-05-25 14:59:01 -07002096 * trouble. The speed gain is not very impressive. (2.3->2.6Mib/s).
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002097 */
2098 cached = 0;
2099
2100 if (!cached || !(chip->options & NAND_CACHEPRG)) {
2101
2102 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
Thomas Gleixner7bc33122006-06-20 20:05:05 +02002103 status = chip->waitfunc(mtd, chip);
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002104 /*
2105 * See if operation failed and additional status checks are
Brian Norris8b6e50c2011-05-25 14:59:01 -07002106 * available.
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002107 */
2108 if ((status & NAND_STATUS_FAIL) && (chip->errstat))
2109 status = chip->errstat(mtd, chip, FL_WRITING, status,
2110 page);
2111
2112 if (status & NAND_STATUS_FAIL)
2113 return -EIO;
2114 } else {
2115 chip->cmdfunc(mtd, NAND_CMD_CACHEDPROG, -1, -1);
Thomas Gleixner7bc33122006-06-20 20:05:05 +02002116 status = chip->waitfunc(mtd, chip);
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002117 }
2118
2119#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
2120 /* Send command to read back the data */
2121 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
2122
2123 if (chip->verify_buf(mtd, buf, mtd->writesize))
2124 return -EIO;
2125#endif
2126 return 0;
2127}
2128
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002129/**
Brian Norris7854d3f2011-06-23 14:12:08 -07002130 * nand_fill_oob - [INTERN] Transfer client buffer to oob
THOMSON, Adam (Adam)f7220132011-06-14 16:52:38 +02002131 * @mtd: MTD device structure
Brian Norris8b6e50c2011-05-25 14:59:01 -07002132 * @oob: oob data buffer
2133 * @len: oob data write length
2134 * @ops: oob ops structure
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002135 */
THOMSON, Adam (Adam)f7220132011-06-14 16:52:38 +02002136static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,
2137 struct mtd_oob_ops *ops)
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002138{
THOMSON, Adam (Adam)f7220132011-06-14 16:52:38 +02002139 struct nand_chip *chip = mtd->priv;
2140
2141 /*
2142 * Initialise to all 0xFF, to avoid the possibility of left over OOB
2143 * data from a previous OOB read.
2144 */
2145 memset(chip->oob_poi, 0xff, mtd->oobsize);
2146
Florian Fainellif8ac0412010-09-07 13:23:43 +02002147 switch (ops->mode) {
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002148
Brian Norris0612b9d2011-08-30 18:45:40 -07002149 case MTD_OPS_PLACE_OOB:
2150 case MTD_OPS_RAW:
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002151 memcpy(chip->oob_poi + ops->ooboffs, oob, len);
2152 return oob + len;
2153
Brian Norris0612b9d2011-08-30 18:45:40 -07002154 case MTD_OPS_AUTO_OOB: {
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002155 struct nand_oobfree *free = chip->ecc.layout->oobfree;
Thomas Gleixner7bc33122006-06-20 20:05:05 +02002156 uint32_t boffs = 0, woffs = ops->ooboffs;
2157 size_t bytes = 0;
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002158
Florian Fainellif8ac0412010-09-07 13:23:43 +02002159 for (; free->length && len; free++, len -= bytes) {
Brian Norris8b6e50c2011-05-25 14:59:01 -07002160 /* Write request not from offset 0? */
Thomas Gleixner7bc33122006-06-20 20:05:05 +02002161 if (unlikely(woffs)) {
2162 if (woffs >= free->length) {
2163 woffs -= free->length;
2164 continue;
2165 }
2166 boffs = free->offset + woffs;
2167 bytes = min_t(size_t, len,
2168 (free->length - woffs));
2169 woffs = 0;
2170 } else {
2171 bytes = min_t(size_t, len, free->length);
2172 boffs = free->offset;
2173 }
Vitaly Wool8b0036e2006-07-11 09:11:25 +02002174 memcpy(chip->oob_poi + boffs, oob, bytes);
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002175 oob += bytes;
2176 }
2177 return oob;
2178 }
2179 default:
2180 BUG();
2181 }
2182 return NULL;
2183}
2184
Florian Fainellif8ac0412010-09-07 13:23:43 +02002185#define NOTALIGNED(x) ((x & (chip->subpagesize - 1)) != 0)
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002186
2187/**
Brian Norris7854d3f2011-06-23 14:12:08 -07002188 * nand_do_write_ops - [INTERN] NAND write with ECC
Brian Norris8b6e50c2011-05-25 14:59:01 -07002189 * @mtd: MTD device structure
2190 * @to: offset to write to
2191 * @ops: oob operations description structure
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002192 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07002193 * NAND write with ECC.
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002194 */
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002195static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
2196 struct mtd_oob_ops *ops)
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002197{
Thomas Gleixner29072b92006-09-28 15:38:36 +02002198 int chipnr, realpage, page, blockmask, column;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002199 struct nand_chip *chip = mtd->priv;
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002200 uint32_t writelen = ops->len;
Maxim Levitsky782ce792010-02-22 20:39:36 +02002201
2202 uint32_t oobwritelen = ops->ooblen;
Brian Norris0612b9d2011-08-30 18:45:40 -07002203 uint32_t oobmaxlen = ops->mode == MTD_OPS_AUTO_OOB ?
Maxim Levitsky782ce792010-02-22 20:39:36 +02002204 mtd->oobavail : mtd->oobsize;
2205
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002206 uint8_t *oob = ops->oobbuf;
2207 uint8_t *buf = ops->datbuf;
Thomas Gleixner29072b92006-09-28 15:38:36 +02002208 int ret, subpage;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002209
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002210 ops->retlen = 0;
Thomas Gleixner29072b92006-09-28 15:38:36 +02002211 if (!writelen)
2212 return 0;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002213
Brian Norris8b6e50c2011-05-25 14:59:01 -07002214 /* Reject writes, which are not page aligned */
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002215 if (NOTALIGNED(to) || NOTALIGNED(ops->len)) {
Brian Norrisd0370212011-07-19 10:06:08 -07002216 pr_notice("%s: attempt to write non page aligned data\n",
2217 __func__);
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002218 return -EINVAL;
2219 }
2220
Thomas Gleixner29072b92006-09-28 15:38:36 +02002221 column = to & (mtd->writesize - 1);
2222 subpage = column || (writelen & (mtd->writesize - 1));
2223
2224 if (subpage && oob)
2225 return -EINVAL;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002226
Thomas Gleixner6a930962006-06-28 00:11:45 +02002227 chipnr = (int)(to >> chip->chip_shift);
2228 chip->select_chip(mtd, chipnr);
2229
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002230 /* Check, if it is write protected */
2231 if (nand_check_wp(mtd))
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002232 return -EIO;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002233
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002234 realpage = (int)(to >> chip->page_shift);
2235 page = realpage & chip->pagemask;
2236 blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
2237
2238 /* Invalidate the page cache, when we write to the cached page */
2239 if (to <= (chip->pagebuf << chip->page_shift) &&
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002240 (chip->pagebuf << chip->page_shift) < (to + ops->len))
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002241 chip->pagebuf = -1;
2242
Maxim Levitsky782ce792010-02-22 20:39:36 +02002243 /* Don't allow multipage oob writes with offset */
Jon Poveycdcf12b2010-09-30 20:41:34 +09002244 if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen))
Maxim Levitsky782ce792010-02-22 20:39:36 +02002245 return -EINVAL;
2246
Florian Fainellif8ac0412010-09-07 13:23:43 +02002247 while (1) {
Thomas Gleixner29072b92006-09-28 15:38:36 +02002248 int bytes = mtd->writesize;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002249 int cached = writelen > bytes && page != blockmask;
Thomas Gleixner29072b92006-09-28 15:38:36 +02002250 uint8_t *wbuf = buf;
2251
Brian Norris8b6e50c2011-05-25 14:59:01 -07002252 /* Partial page write? */
Thomas Gleixner29072b92006-09-28 15:38:36 +02002253 if (unlikely(column || writelen < (mtd->writesize - 1))) {
2254 cached = 0;
2255 bytes = min_t(int, bytes - column, (int) writelen);
2256 chip->pagebuf = -1;
2257 memset(chip->buffers->databuf, 0xff, mtd->writesize);
2258 memcpy(&chip->buffers->databuf[column], buf, bytes);
2259 wbuf = chip->buffers->databuf;
2260 }
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002261
Maxim Levitsky782ce792010-02-22 20:39:36 +02002262 if (unlikely(oob)) {
2263 size_t len = min(oobwritelen, oobmaxlen);
THOMSON, Adam (Adam)f7220132011-06-14 16:52:38 +02002264 oob = nand_fill_oob(mtd, oob, len, ops);
Maxim Levitsky782ce792010-02-22 20:39:36 +02002265 oobwritelen -= len;
THOMSON, Adam (Adam)f7220132011-06-14 16:52:38 +02002266 } else {
2267 /* We still need to erase leftover OOB data */
2268 memset(chip->oob_poi, 0xff, mtd->oobsize);
Maxim Levitsky782ce792010-02-22 20:39:36 +02002269 }
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002270
Thomas Gleixner29072b92006-09-28 15:38:36 +02002271 ret = chip->write_page(mtd, chip, wbuf, page, cached,
Brian Norris0612b9d2011-08-30 18:45:40 -07002272 (ops->mode == MTD_OPS_RAW));
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002273 if (ret)
2274 break;
2275
2276 writelen -= bytes;
2277 if (!writelen)
2278 break;
2279
Thomas Gleixner29072b92006-09-28 15:38:36 +02002280 column = 0;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002281 buf += bytes;
2282 realpage++;
2283
2284 page = realpage & chip->pagemask;
2285 /* Check, if we cross a chip boundary */
2286 if (!page) {
2287 chipnr++;
2288 chip->select_chip(mtd, -1);
2289 chip->select_chip(mtd, chipnr);
2290 }
2291 }
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002292
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002293 ops->retlen = ops->len - writelen;
Vitaly Wool70145682006-11-03 18:20:38 +03002294 if (unlikely(oob))
2295 ops->oobretlen = ops->ooblen;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002296 return ret;
2297}
2298
2299/**
Simon Kagstrom2af7c652009-10-05 15:55:52 +02002300 * panic_nand_write - [MTD Interface] NAND write with ECC
Brian Norris8b6e50c2011-05-25 14:59:01 -07002301 * @mtd: MTD device structure
2302 * @to: offset to write to
2303 * @len: number of bytes to write
2304 * @retlen: pointer to variable to store the number of written bytes
2305 * @buf: the data to write
Simon Kagstrom2af7c652009-10-05 15:55:52 +02002306 *
2307 * NAND write with ECC. Used when performing writes in interrupt context, this
2308 * may for example be called by mtdoops when writing an oops while in panic.
2309 */
2310static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
2311 size_t *retlen, const uint8_t *buf)
2312{
2313 struct nand_chip *chip = mtd->priv;
Brian Norris4a89ff82011-08-30 18:45:45 -07002314 struct mtd_oob_ops ops;
Simon Kagstrom2af7c652009-10-05 15:55:52 +02002315 int ret;
2316
2317 /* Do not allow reads past end of device */
2318 if ((to + len) > mtd->size)
2319 return -EINVAL;
2320 if (!len)
2321 return 0;
2322
Brian Norris8b6e50c2011-05-25 14:59:01 -07002323 /* Wait for the device to get ready */
Simon Kagstrom2af7c652009-10-05 15:55:52 +02002324 panic_nand_wait(mtd, chip, 400);
2325
Brian Norris8b6e50c2011-05-25 14:59:01 -07002326 /* Grab the device */
Simon Kagstrom2af7c652009-10-05 15:55:52 +02002327 panic_nand_get_device(chip, mtd, FL_WRITING);
2328
Brian Norris4a89ff82011-08-30 18:45:45 -07002329 ops.len = len;
2330 ops.datbuf = (uint8_t *)buf;
2331 ops.oobbuf = NULL;
Brian Norris23b1a992011-10-14 20:09:33 -07002332 ops.mode = 0;
Simon Kagstrom2af7c652009-10-05 15:55:52 +02002333
Brian Norris4a89ff82011-08-30 18:45:45 -07002334 ret = nand_do_write_ops(mtd, to, &ops);
Simon Kagstrom2af7c652009-10-05 15:55:52 +02002335
Brian Norris4a89ff82011-08-30 18:45:45 -07002336 *retlen = ops.retlen;
Simon Kagstrom2af7c652009-10-05 15:55:52 +02002337 return ret;
2338}
2339
2340/**
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002341 * nand_write - [MTD Interface] NAND write with ECC
Brian Norris8b6e50c2011-05-25 14:59:01 -07002342 * @mtd: MTD device structure
2343 * @to: offset to write to
2344 * @len: number of bytes to write
2345 * @retlen: pointer to variable to store the number of written bytes
2346 * @buf: the data to write
Linus Torvalds1da177e2005-04-16 15:20:36 -07002347 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07002348 * NAND write with ECC.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002349 */
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002350static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
Thomas Gleixner7314e9e2006-05-25 09:51:54 +02002351 size_t *retlen, const uint8_t *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002352{
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002353 struct nand_chip *chip = mtd->priv;
Brian Norris4a89ff82011-08-30 18:45:45 -07002354 struct mtd_oob_ops ops;
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002355 int ret;
2356
2357 /* Do not allow reads past end of device */
2358 if ((to + len) > mtd->size)
2359 return -EINVAL;
2360 if (!len)
2361 return 0;
2362
Thomas Gleixner7bc33122006-06-20 20:05:05 +02002363 nand_get_device(chip, mtd, FL_WRITING);
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002364
Brian Norris4a89ff82011-08-30 18:45:45 -07002365 ops.len = len;
2366 ops.datbuf = (uint8_t *)buf;
2367 ops.oobbuf = NULL;
Brian Norris23b1a992011-10-14 20:09:33 -07002368 ops.mode = 0;
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002369
Brian Norris4a89ff82011-08-30 18:45:45 -07002370 ret = nand_do_write_ops(mtd, to, &ops);
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002371
Brian Norris4a89ff82011-08-30 18:45:45 -07002372 *retlen = ops.retlen;
Richard Purdie7fd5aec2006-08-27 01:23:33 -07002373
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002374 nand_release_device(mtd);
2375
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002376 return ret;
2377}
2378
2379/**
2380 * nand_do_write_oob - [MTD Interface] NAND write out-of-band
Brian Norris8b6e50c2011-05-25 14:59:01 -07002381 * @mtd: MTD device structure
2382 * @to: offset to write to
2383 * @ops: oob operation description structure
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002384 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07002385 * NAND write out-of-band.
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002386 */
2387static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
2388 struct mtd_oob_ops *ops)
2389{
Adrian Hunter03736152007-01-31 17:58:29 +02002390 int chipnr, page, status, len;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002391 struct nand_chip *chip = mtd->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002392
Brian Norris289c0522011-07-19 10:06:09 -07002393 pr_debug("%s: to = 0x%08x, len = %i\n",
vimal singh20d8e242009-07-07 15:49:49 +05302394 __func__, (unsigned int)to, (int)ops->ooblen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002395
Brian Norris0612b9d2011-08-30 18:45:40 -07002396 if (ops->mode == MTD_OPS_AUTO_OOB)
Adrian Hunter03736152007-01-31 17:58:29 +02002397 len = chip->ecc.layout->oobavail;
2398 else
2399 len = mtd->oobsize;
2400
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401 /* Do not allow write past end of page */
Adrian Hunter03736152007-01-31 17:58:29 +02002402 if ((ops->ooboffs + ops->ooblen) > len) {
Brian Norris289c0522011-07-19 10:06:09 -07002403 pr_debug("%s: attempt to write past end of page\n",
2404 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405 return -EINVAL;
2406 }
2407
Adrian Hunter03736152007-01-31 17:58:29 +02002408 if (unlikely(ops->ooboffs >= len)) {
Brian Norris289c0522011-07-19 10:06:09 -07002409 pr_debug("%s: attempt to start write outside oob\n",
2410 __func__);
Adrian Hunter03736152007-01-31 17:58:29 +02002411 return -EINVAL;
2412 }
2413
Jason Liu775adc32011-02-25 13:06:18 +08002414 /* Do not allow write past end of device */
Adrian Hunter03736152007-01-31 17:58:29 +02002415 if (unlikely(to >= mtd->size ||
2416 ops->ooboffs + ops->ooblen >
2417 ((mtd->size >> chip->page_shift) -
2418 (to >> chip->page_shift)) * len)) {
Brian Norris289c0522011-07-19 10:06:09 -07002419 pr_debug("%s: attempt to write beyond end of device\n",
2420 __func__);
Adrian Hunter03736152007-01-31 17:58:29 +02002421 return -EINVAL;
2422 }
2423
Thomas Gleixner7314e9e2006-05-25 09:51:54 +02002424 chipnr = (int)(to >> chip->chip_shift);
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002425 chip->select_chip(mtd, chipnr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002426
Thomas Gleixner7314e9e2006-05-25 09:51:54 +02002427 /* Shift to get page */
2428 page = (int)(to >> chip->page_shift);
2429
2430 /*
2431 * Reset the chip. Some chips (like the Toshiba TC5832DC found in one
2432 * of my DiskOnChip 2000 test units) will clear the whole data page too
2433 * if we don't do this. I have no clue why, but I seem to have 'fixed'
2434 * it in the doc2000 driver in August 1999. dwmw2.
2435 */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002436 chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002437
2438 /* Check, if it is write protected */
2439 if (nand_check_wp(mtd))
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002440 return -EROFS;
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00002441
Linus Torvalds1da177e2005-04-16 15:20:36 -07002442 /* Invalidate the page cache, if we write to the cached page */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002443 if (page == chip->pagebuf)
2444 chip->pagebuf = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002445
THOMSON, Adam (Adam)f7220132011-06-14 16:52:38 +02002446 nand_fill_oob(mtd, ops->oobbuf, ops->ooblen, ops);
Brian Norris9ce244b2011-08-30 18:45:37 -07002447
Brian Norris0612b9d2011-08-30 18:45:40 -07002448 if (ops->mode == MTD_OPS_RAW)
Brian Norris9ce244b2011-08-30 18:45:37 -07002449 status = chip->ecc.write_oob_raw(mtd, chip, page & chip->pagemask);
2450 else
2451 status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002452
Thomas Gleixner7bc33122006-06-20 20:05:05 +02002453 if (status)
2454 return status;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002455
Vitaly Wool70145682006-11-03 18:20:38 +03002456 ops->oobretlen = ops->ooblen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002457
Thomas Gleixner7bc33122006-06-20 20:05:05 +02002458 return 0;
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002459}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002460
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002461/**
2462 * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band
Brian Norris8b6e50c2011-05-25 14:59:01 -07002463 * @mtd: MTD device structure
2464 * @to: offset to write to
2465 * @ops: oob operation description structure
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002466 */
2467static int nand_write_oob(struct mtd_info *mtd, loff_t to,
2468 struct mtd_oob_ops *ops)
2469{
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002470 struct nand_chip *chip = mtd->priv;
2471 int ret = -ENOTSUPP;
2472
2473 ops->retlen = 0;
2474
2475 /* Do not allow writes past end of device */
Vitaly Wool70145682006-11-03 18:20:38 +03002476 if (ops->datbuf && (to + ops->len) > mtd->size) {
Brian Norris289c0522011-07-19 10:06:09 -07002477 pr_debug("%s: attempt to write beyond end of device\n",
2478 __func__);
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002479 return -EINVAL;
2480 }
2481
Thomas Gleixner7bc33122006-06-20 20:05:05 +02002482 nand_get_device(chip, mtd, FL_WRITING);
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002483
Florian Fainellif8ac0412010-09-07 13:23:43 +02002484 switch (ops->mode) {
Brian Norris0612b9d2011-08-30 18:45:40 -07002485 case MTD_OPS_PLACE_OOB:
2486 case MTD_OPS_AUTO_OOB:
2487 case MTD_OPS_RAW:
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002488 break;
2489
2490 default:
2491 goto out;
2492 }
2493
2494 if (!ops->datbuf)
2495 ret = nand_do_write_oob(mtd, to, ops);
2496 else
2497 ret = nand_do_write_ops(mtd, to, ops);
2498
Florian Fainelli7351d3a2010-09-07 13:23:45 +02002499out:
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02002500 nand_release_device(mtd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501 return ret;
2502}
2503
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504/**
Brian Norris7854d3f2011-06-23 14:12:08 -07002505 * single_erase_cmd - [GENERIC] NAND standard block erase command function
Brian Norris8b6e50c2011-05-25 14:59:01 -07002506 * @mtd: MTD device structure
2507 * @page: the page address of the block which will be erased
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07002509 * Standard erase command for NAND chips.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002510 */
David Woodhousee0c7d762006-05-13 18:07:53 +01002511static void single_erase_cmd(struct mtd_info *mtd, int page)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002512{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002513 struct nand_chip *chip = mtd->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002514 /* Send commands to erase a block */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002515 chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
2516 chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002517}
2518
2519/**
Brian Norris7854d3f2011-06-23 14:12:08 -07002520 * multi_erase_cmd - [GENERIC] AND specific block erase command function
Brian Norris8b6e50c2011-05-25 14:59:01 -07002521 * @mtd: MTD device structure
2522 * @page: the page address of the block which will be erased
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07002524 * AND multi block erase command function. Erase 4 consecutive blocks.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525 */
David Woodhousee0c7d762006-05-13 18:07:53 +01002526static void multi_erase_cmd(struct mtd_info *mtd, int page)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002527{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002528 struct nand_chip *chip = mtd->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529 /* Send commands to erase a block */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002530 chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
2531 chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
2532 chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
2533 chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
2534 chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002535}
2536
2537/**
2538 * nand_erase - [MTD Interface] erase block(s)
Brian Norris8b6e50c2011-05-25 14:59:01 -07002539 * @mtd: MTD device structure
2540 * @instr: erase instruction
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07002542 * Erase one ore more blocks.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543 */
David Woodhousee0c7d762006-05-13 18:07:53 +01002544static int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002545{
David Woodhousee0c7d762006-05-13 18:07:53 +01002546 return nand_erase_nand(mtd, instr, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002547}
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00002548
David A. Marlin30f464b2005-01-17 18:35:25 +00002549#define BBT_PAGE_MASK 0xffffff3f
Linus Torvalds1da177e2005-04-16 15:20:36 -07002550/**
Brian Norris7854d3f2011-06-23 14:12:08 -07002551 * nand_erase_nand - [INTERN] erase block(s)
Brian Norris8b6e50c2011-05-25 14:59:01 -07002552 * @mtd: MTD device structure
2553 * @instr: erase instruction
2554 * @allowbbt: allow erasing the bbt area
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07002556 * Erase one ore more blocks.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557 */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002558int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
2559 int allowbbt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002560{
Adrian Hunter69423d92008-12-10 13:37:21 +00002561 int page, status, pages_per_block, ret, chipnr;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002562 struct nand_chip *chip = mtd->priv;
Florian Fainellif8ac0412010-09-07 13:23:43 +02002563 loff_t rewrite_bbt[NAND_MAX_CHIPS] = {0};
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002564 unsigned int bbt_masked_page = 0xffffffff;
Adrian Hunter69423d92008-12-10 13:37:21 +00002565 loff_t len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566
Brian Norris289c0522011-07-19 10:06:09 -07002567 pr_debug("%s: start = 0x%012llx, len = %llu\n",
2568 __func__, (unsigned long long)instr->addr,
2569 (unsigned long long)instr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570
Vimal Singh6fe5a6a2010-02-03 14:12:24 +05302571 if (check_offs_len(mtd, instr->addr, instr->len))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002572 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002573
Adrian Hunterbb0eb212008-08-12 12:40:50 +03002574 instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002575
2576 /* Grab the lock and see if the device is available */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002577 nand_get_device(chip, mtd, FL_ERASING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578
2579 /* Shift to get first page */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002580 page = (int)(instr->addr >> chip->page_shift);
2581 chipnr = (int)(instr->addr >> chip->chip_shift);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002582
2583 /* Calculate pages in each block */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002584 pages_per_block = 1 << (chip->phys_erase_shift - chip->page_shift);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002585
2586 /* Select the NAND device */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002587 chip->select_chip(mtd, chipnr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002588
Linus Torvalds1da177e2005-04-16 15:20:36 -07002589 /* Check, if it is write protected */
2590 if (nand_check_wp(mtd)) {
Brian Norris289c0522011-07-19 10:06:09 -07002591 pr_debug("%s: device is write protected!\n",
2592 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002593 instr->state = MTD_ERASE_FAILED;
2594 goto erase_exit;
2595 }
2596
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002597 /*
2598 * If BBT requires refresh, set the BBT page mask to see if the BBT
2599 * should be rewritten. Otherwise the mask is set to 0xffffffff which
2600 * can not be matched. This is also done when the bbt is actually
Brian Norris7854d3f2011-06-23 14:12:08 -07002601 * erased to avoid recursive updates.
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002602 */
2603 if (chip->options & BBT_AUTO_REFRESH && !allowbbt)
2604 bbt_masked_page = chip->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
David A. Marlin30f464b2005-01-17 18:35:25 +00002605
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606 /* Loop through the pages */
2607 len = instr->len;
2608
2609 instr->state = MTD_ERASING;
2610
2611 while (len) {
Wolfram Sang12183a22011-12-21 23:01:20 +01002612 /* Check if we have a bad block, we do not erase bad blocks! */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002613 if (nand_block_checkbad(mtd, ((loff_t) page) <<
2614 chip->page_shift, 0, allowbbt)) {
Brian Norrisd0370212011-07-19 10:06:08 -07002615 pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
2616 __func__, page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002617 instr->state = MTD_ERASE_FAILED;
2618 goto erase_exit;
2619 }
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00002620
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002621 /*
2622 * Invalidate the page cache, if we erase the block which
Brian Norris8b6e50c2011-05-25 14:59:01 -07002623 * contains the current cached page.
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002624 */
2625 if (page <= chip->pagebuf && chip->pagebuf <
2626 (page + pages_per_block))
2627 chip->pagebuf = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002628
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002629 chip->erase_cmd(mtd, page & chip->pagemask);
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00002630
Thomas Gleixner7bc33122006-06-20 20:05:05 +02002631 status = chip->waitfunc(mtd, chip);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002632
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002633 /*
2634 * See if operation failed and additional status checks are
2635 * available
2636 */
2637 if ((status & NAND_STATUS_FAIL) && (chip->errstat))
2638 status = chip->errstat(mtd, chip, FL_ERASING,
2639 status, page);
David A. Marlin068e3c02005-01-24 03:07:46 +00002640
Linus Torvalds1da177e2005-04-16 15:20:36 -07002641 /* See if block erase succeeded */
David A. Marlina4ab4c52005-01-23 18:30:53 +00002642 if (status & NAND_STATUS_FAIL) {
Brian Norris289c0522011-07-19 10:06:09 -07002643 pr_debug("%s: failed erase, page 0x%08x\n",
2644 __func__, page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002645 instr->state = MTD_ERASE_FAILED;
Adrian Hunter69423d92008-12-10 13:37:21 +00002646 instr->fail_addr =
2647 ((loff_t)page << chip->page_shift);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002648 goto erase_exit;
2649 }
David A. Marlin30f464b2005-01-17 18:35:25 +00002650
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002651 /*
2652 * If BBT requires refresh, set the BBT rewrite flag to the
Brian Norris8b6e50c2011-05-25 14:59:01 -07002653 * page being erased.
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002654 */
2655 if (bbt_masked_page != 0xffffffff &&
2656 (page & BBT_PAGE_MASK) == bbt_masked_page)
Adrian Hunter69423d92008-12-10 13:37:21 +00002657 rewrite_bbt[chipnr] =
2658 ((loff_t)page << chip->page_shift);
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00002659
Linus Torvalds1da177e2005-04-16 15:20:36 -07002660 /* Increment page address and decrement length */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002661 len -= (1 << chip->phys_erase_shift);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662 page += pages_per_block;
2663
2664 /* Check, if we cross a chip boundary */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002665 if (len && !(page & chip->pagemask)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666 chipnr++;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002667 chip->select_chip(mtd, -1);
2668 chip->select_chip(mtd, chipnr);
David A. Marlin30f464b2005-01-17 18:35:25 +00002669
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002670 /*
2671 * If BBT requires refresh and BBT-PERCHIP, set the BBT
Brian Norris8b6e50c2011-05-25 14:59:01 -07002672 * page mask to see if this BBT should be rewritten.
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002673 */
2674 if (bbt_masked_page != 0xffffffff &&
2675 (chip->bbt_td->options & NAND_BBT_PERCHIP))
2676 bbt_masked_page = chip->bbt_td->pages[chipnr] &
2677 BBT_PAGE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002678 }
2679 }
2680 instr->state = MTD_ERASE_DONE;
2681
Florian Fainelli7351d3a2010-09-07 13:23:45 +02002682erase_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683
2684 ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002685
2686 /* Deselect and wake up anyone waiting on the device */
2687 nand_release_device(mtd);
2688
David Woodhouse49defc02007-10-06 15:01:59 -04002689 /* Do call back function */
2690 if (!ret)
2691 mtd_erase_callback(instr);
2692
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002693 /*
2694 * If BBT requires refresh and erase was successful, rewrite any
Brian Norris8b6e50c2011-05-25 14:59:01 -07002695 * selected bad block tables.
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002696 */
2697 if (bbt_masked_page == 0xffffffff || ret)
2698 return ret;
2699
2700 for (chipnr = 0; chipnr < chip->numchips; chipnr++) {
2701 if (!rewrite_bbt[chipnr])
2702 continue;
Brian Norris8b6e50c2011-05-25 14:59:01 -07002703 /* Update the BBT for chip */
Brian Norris289c0522011-07-19 10:06:09 -07002704 pr_debug("%s: nand_update_bbt (%d:0x%0llx 0x%0x)\n",
2705 __func__, chipnr, rewrite_bbt[chipnr],
2706 chip->bbt_td->pages[chipnr]);
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002707 nand_update_bbt(mtd, rewrite_bbt[chipnr]);
David A. Marlin30f464b2005-01-17 18:35:25 +00002708 }
2709
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710 /* Return more or less happy */
2711 return ret;
2712}
2713
2714/**
2715 * nand_sync - [MTD Interface] sync
Brian Norris8b6e50c2011-05-25 14:59:01 -07002716 * @mtd: MTD device structure
Linus Torvalds1da177e2005-04-16 15:20:36 -07002717 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07002718 * Sync is actually a wait for chip ready function.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719 */
David Woodhousee0c7d762006-05-13 18:07:53 +01002720static void nand_sync(struct mtd_info *mtd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002721{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002722 struct nand_chip *chip = mtd->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723
Brian Norris289c0522011-07-19 10:06:09 -07002724 pr_debug("%s: called\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725
2726 /* Grab the lock and see if the device is available */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002727 nand_get_device(chip, mtd, FL_SYNCING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728 /* Release it and go back */
David Woodhousee0c7d762006-05-13 18:07:53 +01002729 nand_release_device(mtd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002730}
2731
Linus Torvalds1da177e2005-04-16 15:20:36 -07002732/**
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002733 * nand_block_isbad - [MTD Interface] Check if block at offset is bad
Brian Norris8b6e50c2011-05-25 14:59:01 -07002734 * @mtd: MTD device structure
2735 * @offs: offset relative to mtd start
Linus Torvalds1da177e2005-04-16 15:20:36 -07002736 */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002737static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002738{
2739 /* Check for invalid offset */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002740 if (offs > mtd->size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741 return -EINVAL;
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00002742
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002743 return nand_block_checkbad(mtd, offs, 1, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002744}
2745
2746/**
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002747 * nand_block_markbad - [MTD Interface] Mark block at the given offset as bad
Brian Norris8b6e50c2011-05-25 14:59:01 -07002748 * @mtd: MTD device structure
2749 * @ofs: offset relative to mtd start
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750 */
David Woodhousee0c7d762006-05-13 18:07:53 +01002751static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002752{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002753 struct nand_chip *chip = mtd->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002754 int ret;
2755
Florian Fainellif8ac0412010-09-07 13:23:43 +02002756 ret = nand_block_isbad(mtd, ofs);
2757 if (ret) {
Brian Norris8b6e50c2011-05-25 14:59:01 -07002758 /* If it was bad already, return success and do nothing */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002759 if (ret > 0)
2760 return 0;
David Woodhousee0c7d762006-05-13 18:07:53 +01002761 return ret;
2762 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002763
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002764 return chip->block_markbad(mtd, ofs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002765}
2766
2767/**
Vitaly Wool962034f2005-09-15 14:58:53 +01002768 * nand_suspend - [MTD Interface] Suspend the NAND flash
Brian Norris8b6e50c2011-05-25 14:59:01 -07002769 * @mtd: MTD device structure
Vitaly Wool962034f2005-09-15 14:58:53 +01002770 */
2771static int nand_suspend(struct mtd_info *mtd)
2772{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002773 struct nand_chip *chip = mtd->priv;
Vitaly Wool962034f2005-09-15 14:58:53 +01002774
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002775 return nand_get_device(chip, mtd, FL_PM_SUSPENDED);
Vitaly Wool962034f2005-09-15 14:58:53 +01002776}
2777
2778/**
2779 * nand_resume - [MTD Interface] Resume the NAND flash
Brian Norris8b6e50c2011-05-25 14:59:01 -07002780 * @mtd: MTD device structure
Vitaly Wool962034f2005-09-15 14:58:53 +01002781 */
2782static void nand_resume(struct mtd_info *mtd)
2783{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002784 struct nand_chip *chip = mtd->priv;
Vitaly Wool962034f2005-09-15 14:58:53 +01002785
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002786 if (chip->state == FL_PM_SUSPENDED)
Vitaly Wool962034f2005-09-15 14:58:53 +01002787 nand_release_device(mtd);
2788 else
Brian Norrisd0370212011-07-19 10:06:08 -07002789 pr_err("%s called for a chip which is not in suspended state\n",
2790 __func__);
Vitaly Wool962034f2005-09-15 14:58:53 +01002791}
2792
Brian Norris8b6e50c2011-05-25 14:59:01 -07002793/* Set default functions */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002794static void nand_set_defaults(struct nand_chip *chip, int busw)
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02002795{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002796 /* check for proper chip_delay setup, set 20us if not */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002797 if (!chip->chip_delay)
2798 chip->chip_delay = 20;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002799
2800 /* check, if a user supplied command function given */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002801 if (chip->cmdfunc == NULL)
2802 chip->cmdfunc = nand_command;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002803
2804 /* check, if a user supplied wait function given */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002805 if (chip->waitfunc == NULL)
2806 chip->waitfunc = nand_wait;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002807
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002808 if (!chip->select_chip)
2809 chip->select_chip = nand_select_chip;
2810 if (!chip->read_byte)
2811 chip->read_byte = busw ? nand_read_byte16 : nand_read_byte;
2812 if (!chip->read_word)
2813 chip->read_word = nand_read_word;
2814 if (!chip->block_bad)
2815 chip->block_bad = nand_block_bad;
2816 if (!chip->block_markbad)
2817 chip->block_markbad = nand_default_block_markbad;
2818 if (!chip->write_buf)
2819 chip->write_buf = busw ? nand_write_buf16 : nand_write_buf;
2820 if (!chip->read_buf)
2821 chip->read_buf = busw ? nand_read_buf16 : nand_read_buf;
2822 if (!chip->verify_buf)
2823 chip->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf;
2824 if (!chip->scan_bbt)
2825 chip->scan_bbt = nand_default_bbt;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02002826
2827 if (!chip->controller) {
2828 chip->controller = &chip->hwcontrol;
2829 spin_lock_init(&chip->controller->lock);
2830 init_waitqueue_head(&chip->controller->wq);
2831 }
2832
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02002833}
2834
Brian Norris8b6e50c2011-05-25 14:59:01 -07002835/* Sanitize ONFI strings so we can safely print them */
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02002836static void sanitize_string(uint8_t *s, size_t len)
2837{
2838 ssize_t i;
2839
Brian Norris8b6e50c2011-05-25 14:59:01 -07002840 /* Null terminate */
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02002841 s[len - 1] = 0;
2842
Brian Norris8b6e50c2011-05-25 14:59:01 -07002843 /* Remove non printable chars */
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02002844 for (i = 0; i < len - 1; i++) {
2845 if (s[i] < ' ' || s[i] > 127)
2846 s[i] = '?';
2847 }
2848
Brian Norris8b6e50c2011-05-25 14:59:01 -07002849 /* Remove trailing spaces */
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02002850 strim(s);
2851}
2852
2853static u16 onfi_crc16(u16 crc, u8 const *p, size_t len)
2854{
2855 int i;
2856 while (len--) {
2857 crc ^= *p++ << 8;
2858 for (i = 0; i < 8; i++)
2859 crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0);
2860 }
2861
2862 return crc;
2863}
2864
2865/*
Brian Norris8b6e50c2011-05-25 14:59:01 -07002866 * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise.
Florian Fainelli6fb277b2010-09-01 22:28:59 +02002867 */
2868static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
Matthieu CASTET08c248f2011-06-26 18:26:55 +02002869 int *busw)
Florian Fainelli6fb277b2010-09-01 22:28:59 +02002870{
2871 struct nand_onfi_params *p = &chip->onfi_params;
2872 int i;
2873 int val;
2874
Brian Norris7854d3f2011-06-23 14:12:08 -07002875 /* Try ONFI for unknown chip or LP */
Florian Fainelli6fb277b2010-09-01 22:28:59 +02002876 chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
2877 if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
2878 chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I')
2879 return 0;
2880
Brian Norris9a4d4d62011-07-19 10:06:07 -07002881 pr_info("ONFI flash detected\n");
Florian Fainelli6fb277b2010-09-01 22:28:59 +02002882 chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
2883 for (i = 0; i < 3; i++) {
2884 chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));
2885 if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
2886 le16_to_cpu(p->crc)) {
Brian Norris9a4d4d62011-07-19 10:06:07 -07002887 pr_info("ONFI param page %d valid\n", i);
Florian Fainelli6fb277b2010-09-01 22:28:59 +02002888 break;
2889 }
2890 }
2891
2892 if (i == 3)
2893 return 0;
2894
Brian Norris8b6e50c2011-05-25 14:59:01 -07002895 /* Check version */
Florian Fainelli6fb277b2010-09-01 22:28:59 +02002896 val = le16_to_cpu(p->revision);
Brian Norrisb7b1a292010-12-12 00:23:33 -08002897 if (val & (1 << 5))
2898 chip->onfi_version = 23;
2899 else if (val & (1 << 4))
Florian Fainelli6fb277b2010-09-01 22:28:59 +02002900 chip->onfi_version = 22;
2901 else if (val & (1 << 3))
2902 chip->onfi_version = 21;
2903 else if (val & (1 << 2))
2904 chip->onfi_version = 20;
Brian Norrisb7b1a292010-12-12 00:23:33 -08002905 else if (val & (1 << 1))
Florian Fainelli6fb277b2010-09-01 22:28:59 +02002906 chip->onfi_version = 10;
Brian Norrisb7b1a292010-12-12 00:23:33 -08002907 else
2908 chip->onfi_version = 0;
2909
2910 if (!chip->onfi_version) {
Brian Norrisd0370212011-07-19 10:06:08 -07002911 pr_info("%s: unsupported ONFI version: %d\n", __func__, val);
Brian Norrisb7b1a292010-12-12 00:23:33 -08002912 return 0;
2913 }
Florian Fainelli6fb277b2010-09-01 22:28:59 +02002914
2915 sanitize_string(p->manufacturer, sizeof(p->manufacturer));
2916 sanitize_string(p->model, sizeof(p->model));
2917 if (!mtd->name)
2918 mtd->name = p->model;
2919 mtd->writesize = le32_to_cpu(p->byte_per_page);
2920 mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize;
2921 mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
David Woodhouse4ccb3b42010-12-03 16:36:34 +00002922 chip->chipsize = (uint64_t)le32_to_cpu(p->blocks_per_lun) * mtd->erasesize;
Matthieu CASTET08c248f2011-06-26 18:26:55 +02002923 *busw = 0;
Florian Fainelli6fb277b2010-09-01 22:28:59 +02002924 if (le16_to_cpu(p->features) & 1)
Matthieu CASTET08c248f2011-06-26 18:26:55 +02002925 *busw = NAND_BUSWIDTH_16;
Florian Fainelli6fb277b2010-09-01 22:28:59 +02002926
2927 chip->options &= ~NAND_CHIPOPTIONS_MSK;
2928 chip->options |= (NAND_NO_READRDY |
2929 NAND_NO_AUTOINCR) & NAND_CHIPOPTIONS_MSK;
2930
2931 return 1;
2932}
2933
2934/*
Brian Norris8b6e50c2011-05-25 14:59:01 -07002935 * Get the flash and manufacturer id and lookup if the type is supported.
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02002936 */
2937static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002938 struct nand_chip *chip,
Florian Fainelli7351d3a2010-09-07 13:23:45 +02002939 int busw,
2940 int *maf_id, int *dev_id,
David Woodhouse5e81e882010-02-26 18:32:56 +00002941 struct nand_flash_dev *type)
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02002942{
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02002943 int i, maf_idx;
Kevin Cernekee426c4572010-05-04 20:58:03 -07002944 u8 id_data[8];
Florian Fainelli6fb277b2010-09-01 22:28:59 +02002945 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946
2947 /* Select the device */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002948 chip->select_chip(mtd, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949
Karl Beldanef89a882008-09-15 14:37:29 +02002950 /*
2951 * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)
Brian Norris8b6e50c2011-05-25 14:59:01 -07002952 * after power-up.
Karl Beldanef89a882008-09-15 14:37:29 +02002953 */
2954 chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
2955
Linus Torvalds1da177e2005-04-16 15:20:36 -07002956 /* Send the command for reading device ID */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002957 chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002958
2959 /* Read manufacturer and device IDs */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02002960 *maf_id = chip->read_byte(mtd);
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02002961 *dev_id = chip->read_byte(mtd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002962
Brian Norris8b6e50c2011-05-25 14:59:01 -07002963 /*
2964 * Try again to make sure, as some systems the bus-hold or other
Ben Dooksed8165c2008-04-14 14:58:58 +01002965 * interface concerns can cause random data which looks like a
2966 * possibly credible NAND flash to appear. If the two results do
2967 * not match, ignore the device completely.
2968 */
2969
2970 chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
2971
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02002972 for (i = 0; i < 2; i++)
Kevin Cernekee426c4572010-05-04 20:58:03 -07002973 id_data[i] = chip->read_byte(mtd);
Ben Dooksed8165c2008-04-14 14:58:58 +01002974
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02002975 if (id_data[0] != *maf_id || id_data[1] != *dev_id) {
Brian Norris9a4d4d62011-07-19 10:06:07 -07002976 pr_info("%s: second ID read did not match "
Brian Norrisd0370212011-07-19 10:06:08 -07002977 "%02x,%02x against %02x,%02x\n", __func__,
2978 *maf_id, *dev_id, id_data[0], id_data[1]);
Ben Dooksed8165c2008-04-14 14:58:58 +01002979 return ERR_PTR(-ENODEV);
2980 }
2981
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02002982 if (!type)
David Woodhouse5e81e882010-02-26 18:32:56 +00002983 type = nand_flash_ids;
2984
2985 for (; type->name != NULL; type++)
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02002986 if (*dev_id == type->id)
Florian Fainellif8ac0412010-09-07 13:23:43 +02002987 break;
David Woodhouse5e81e882010-02-26 18:32:56 +00002988
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02002989 chip->onfi_version = 0;
2990 if (!type->name || !type->pagesize) {
Florian Fainelli6fb277b2010-09-01 22:28:59 +02002991 /* Check is chip is ONFI compliant */
Matthieu CASTET08c248f2011-06-26 18:26:55 +02002992 ret = nand_flash_detect_onfi(mtd, chip, &busw);
Florian Fainelli6fb277b2010-09-01 22:28:59 +02002993 if (ret)
2994 goto ident_done;
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02002995 }
2996
2997 chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
2998
2999 /* Read entire ID string */
3000
3001 for (i = 0; i < 8; i++)
3002 id_data[i] = chip->read_byte(mtd);
3003
David Woodhouse5e81e882010-02-26 18:32:56 +00003004 if (!type->name)
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003005 return ERR_PTR(-ENODEV);
3006
Thomas Gleixnerba0251f2006-05-27 01:02:13 +02003007 if (!mtd->name)
3008 mtd->name = type->name;
3009
Adrian Hunter69423d92008-12-10 13:37:21 +00003010 chip->chipsize = (uint64_t)type->chipsize << 20;
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003011
Huang Shijie12a40a52010-09-27 10:43:53 +08003012 if (!type->pagesize && chip->init_size) {
Brian Norris8b6e50c2011-05-25 14:59:01 -07003013 /* Set the pagesize, oobsize, erasesize by the driver */
Huang Shijie12a40a52010-09-27 10:43:53 +08003014 busw = chip->init_size(mtd, chip, id_data);
3015 } else if (!type->pagesize) {
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003016 int extid;
Thomas Gleixner29072b92006-09-28 15:38:36 +02003017 /* The 3rd id byte holds MLC / multichip data */
Kevin Cernekee426c4572010-05-04 20:58:03 -07003018 chip->cellinfo = id_data[2];
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003019 /* The 4th id byte is the important one */
Kevin Cernekee426c4572010-05-04 20:58:03 -07003020 extid = id_data[3];
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003021
Kevin Cernekee426c4572010-05-04 20:58:03 -07003022 /*
3023 * Field definitions are in the following datasheets:
3024 * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
Brian Norris34c5bf62010-08-20 10:50:43 -07003025 * New style (6 byte ID): Samsung K9GBG08U0M (p.40)
Kevin Cernekee426c4572010-05-04 20:58:03 -07003026 *
3027 * Check for wraparound + Samsung ID + nonzero 6th byte
3028 * to decide what to do.
3029 */
3030 if (id_data[0] == id_data[6] && id_data[1] == id_data[7] &&
3031 id_data[0] == NAND_MFR_SAMSUNG &&
Tilman Sauerbeckcfe3fda2010-08-20 14:01:47 -07003032 (chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
Kevin Cernekee426c4572010-05-04 20:58:03 -07003033 id_data[5] != 0x00) {
3034 /* Calc pagesize */
3035 mtd->writesize = 2048 << (extid & 0x03);
3036 extid >>= 2;
3037 /* Calc oobsize */
Brian Norris34c5bf62010-08-20 10:50:43 -07003038 switch (extid & 0x03) {
3039 case 1:
3040 mtd->oobsize = 128;
3041 break;
3042 case 2:
3043 mtd->oobsize = 218;
3044 break;
3045 case 3:
3046 mtd->oobsize = 400;
3047 break;
3048 default:
3049 mtd->oobsize = 436;
3050 break;
3051 }
Kevin Cernekee426c4572010-05-04 20:58:03 -07003052 extid >>= 2;
3053 /* Calc blocksize */
3054 mtd->erasesize = (128 * 1024) <<
3055 (((extid >> 1) & 0x04) | (extid & 0x03));
3056 busw = 0;
3057 } else {
3058 /* Calc pagesize */
3059 mtd->writesize = 1024 << (extid & 0x03);
3060 extid >>= 2;
3061 /* Calc oobsize */
3062 mtd->oobsize = (8 << (extid & 0x01)) *
3063 (mtd->writesize >> 9);
3064 extid >>= 2;
3065 /* Calc blocksize. Blocksize is multiples of 64KiB */
3066 mtd->erasesize = (64 * 1024) << (extid & 0x03);
3067 extid >>= 2;
3068 /* Get buswidth information */
3069 busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
3070 }
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003071 } else {
3072 /*
Brian Norris8b6e50c2011-05-25 14:59:01 -07003073 * Old devices have chip data hardcoded in the device id table.
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003074 */
Thomas Gleixnerba0251f2006-05-27 01:02:13 +02003075 mtd->erasesize = type->erasesize;
3076 mtd->writesize = type->pagesize;
Thomas Gleixner4cbb9b82006-05-23 12:37:31 +02003077 mtd->oobsize = mtd->writesize / 32;
Thomas Gleixnerba0251f2006-05-27 01:02:13 +02003078 busw = type->options & NAND_BUSWIDTH_16;
Brian Norris2173bae2010-08-19 08:11:02 -07003079
3080 /*
3081 * Check for Spansion/AMD ID + repeating 5th, 6th byte since
3082 * some Spansion chips have erasesize that conflicts with size
Brian Norris8b6e50c2011-05-25 14:59:01 -07003083 * listed in nand_ids table.
Brian Norris2173bae2010-08-19 08:11:02 -07003084 * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
3085 */
3086 if (*maf_id == NAND_MFR_AMD && id_data[4] != 0x00 &&
3087 id_data[5] == 0x00 && id_data[6] == 0x00 &&
3088 id_data[7] == 0x00 && mtd->writesize == 512) {
3089 mtd->erasesize = 128 * 1024;
3090 mtd->erasesize <<= ((id_data[3] & 0x03) << 1);
3091 }
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003092 }
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02003093 /* Get chip options, preserve non chip based options */
3094 chip->options &= ~NAND_CHIPOPTIONS_MSK;
3095 chip->options |= type->options & NAND_CHIPOPTIONS_MSK;
3096
Brian Norris8b6e50c2011-05-25 14:59:01 -07003097 /*
3098 * Check if chip is not a Samsung device. Do not clear the
3099 * options for chips which do not have an extended id.
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02003100 */
3101 if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
3102 chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
3103ident_done:
3104
3105 /*
Brian Norris8b6e50c2011-05-25 14:59:01 -07003106 * Set chip as a default. Board drivers can override it, if necessary.
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02003107 */
3108 chip->options |= NAND_NO_AUTOINCR;
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003109
3110 /* Try to identify manufacturer */
David Woodhouse9a909862006-07-15 13:26:18 +01003111 for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) {
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003112 if (nand_manuf_ids[maf_idx].id == *maf_id)
3113 break;
3114 }
3115
3116 /*
3117 * Check, if buswidth is correct. Hardware drivers should set
Brian Norris8b6e50c2011-05-25 14:59:01 -07003118 * chip correct!
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003119 */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003120 if (busw != (chip->options & NAND_BUSWIDTH_16)) {
Brian Norris9a4d4d62011-07-19 10:06:07 -07003121 pr_info("NAND device: Manufacturer ID:"
Brian Norrisd0370212011-07-19 10:06:08 -07003122 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
3123 *dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
Brian Norris9a4d4d62011-07-19 10:06:07 -07003124 pr_warn("NAND bus width %d instead %d bit\n",
Brian Norrisd0370212011-07-19 10:06:08 -07003125 (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
3126 busw ? 16 : 8);
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003127 return ERR_PTR(-EINVAL);
3128 }
3129
3130 /* Calculate the address shift from the page size */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003131 chip->page_shift = ffs(mtd->writesize) - 1;
Brian Norris8b6e50c2011-05-25 14:59:01 -07003132 /* Convert chipsize to number of pages per chip -1 */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003133 chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003134
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003135 chip->bbt_erase_shift = chip->phys_erase_shift =
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003136 ffs(mtd->erasesize) - 1;
Adrian Hunter69423d92008-12-10 13:37:21 +00003137 if (chip->chipsize & 0xffffffff)
3138 chip->chip_shift = ffs((unsigned)chip->chipsize) - 1;
Florian Fainelli7351d3a2010-09-07 13:23:45 +02003139 else {
3140 chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32));
3141 chip->chip_shift += 32 - 1;
3142 }
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003143
Artem Bityutskiy26d9be12011-04-28 20:26:59 +03003144 chip->badblockbits = 8;
3145
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003146 /* Set the bad block position */
Brian Norris065a1ed2010-08-18 11:25:04 -07003147 if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16))
Brian Norrisc7b28e22010-07-13 15:13:00 -07003148 chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
Brian Norris065a1ed2010-08-18 11:25:04 -07003149 else
3150 chip->badblockpos = NAND_SMALL_BADBLOCK_POS;
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003151
Kevin Cernekeeb60b08b2010-05-04 20:58:10 -07003152 /*
3153 * Bad block marker is stored in the last page of each block
Brian Norrisc7b28e22010-07-13 15:13:00 -07003154 * on Samsung and Hynix MLC devices; stored in first two pages
3155 * of each block on Micron devices with 2KiB pages and on
Brian Norris8c342332011-11-02 13:34:44 -07003156 * SLC Samsung, Hynix, Toshiba, AMD/Spansion, and Macronix.
3157 * All others scan only the first page.
Kevin Cernekeeb60b08b2010-05-04 20:58:10 -07003158 */
3159 if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
3160 (*maf_id == NAND_MFR_SAMSUNG ||
3161 *maf_id == NAND_MFR_HYNIX))
Brian Norris5fb15492011-05-31 16:31:21 -07003162 chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
Brian Norrisc7b28e22010-07-13 15:13:00 -07003163 else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
3164 (*maf_id == NAND_MFR_SAMSUNG ||
3165 *maf_id == NAND_MFR_HYNIX ||
Brian Norris13ed7ae2010-08-20 12:36:12 -07003166 *maf_id == NAND_MFR_TOSHIBA ||
Brian Norris8c342332011-11-02 13:34:44 -07003167 *maf_id == NAND_MFR_AMD ||
3168 *maf_id == NAND_MFR_MACRONIX)) ||
Brian Norrisc7b28e22010-07-13 15:13:00 -07003169 (mtd->writesize == 2048 &&
3170 *maf_id == NAND_MFR_MICRON))
Brian Norris5fb15492011-05-31 16:31:21 -07003171 chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
Brian Norrisc7b28e22010-07-13 15:13:00 -07003172
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003173 /* Check for AND chips with 4 page planes */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003174 if (chip->options & NAND_4PAGE_ARRAY)
3175 chip->erase_cmd = multi_erase_cmd;
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003176 else
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003177 chip->erase_cmd = single_erase_cmd;
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003178
Brian Norris8b6e50c2011-05-25 14:59:01 -07003179 /* Do not replace user supplied command function! */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003180 if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
3181 chip->cmdfunc = nand_command_lp;
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003182
Brian Norris9a4d4d62011-07-19 10:06:07 -07003183 pr_info("NAND device: Manufacturer ID:"
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02003184 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id,
3185 nand_manuf_ids[maf_idx].name,
Brian Norris0b524fb2010-12-12 00:23:32 -08003186 chip->onfi_version ? chip->onfi_params.model : type->name);
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003187
3188 return type;
3189}
3190
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003191/**
David Woodhouse3b85c322006-09-25 17:06:53 +01003192 * nand_scan_ident - [NAND Interface] Scan for the NAND device
Brian Norris8b6e50c2011-05-25 14:59:01 -07003193 * @mtd: MTD device structure
3194 * @maxchips: number of chips to scan for
3195 * @table: alternative NAND ID table
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003196 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07003197 * This is the first phase of the normal nand_scan() function. It reads the
3198 * flash ID and sets up MTD fields accordingly.
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003199 *
David Woodhouse3b85c322006-09-25 17:06:53 +01003200 * The mtd->owner field must be set to the module of the caller.
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003201 */
David Woodhouse5e81e882010-02-26 18:32:56 +00003202int nand_scan_ident(struct mtd_info *mtd, int maxchips,
3203 struct nand_flash_dev *table)
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003204{
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02003205 int i, busw, nand_maf_id, nand_dev_id;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003206 struct nand_chip *chip = mtd->priv;
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003207 struct nand_flash_dev *type;
3208
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003209 /* Get buswidth to select the correct functions */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003210 busw = chip->options & NAND_BUSWIDTH_16;
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003211 /* Set the default functions */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003212 nand_set_defaults(chip, busw);
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003213
3214 /* Read the flash type */
Florian Fainelli7351d3a2010-09-07 13:23:45 +02003215 type = nand_get_flash_type(mtd, chip, busw,
3216 &nand_maf_id, &nand_dev_id, table);
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003217
3218 if (IS_ERR(type)) {
Ben Dooksb1c6e6d2009-11-02 18:12:33 +00003219 if (!(chip->options & NAND_SCAN_SILENT_NODEV))
Brian Norrisd0370212011-07-19 10:06:08 -07003220 pr_warn("No NAND device found\n");
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003221 chip->select_chip(mtd, -1);
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003222 return PTR_ERR(type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003223 }
3224
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003225 /* Check for a chip array */
David Woodhousee0c7d762006-05-13 18:07:53 +01003226 for (i = 1; i < maxchips; i++) {
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003227 chip->select_chip(mtd, i);
Karl Beldanef89a882008-09-15 14:37:29 +02003228 /* See comment in nand_get_flash_type for reset */
3229 chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003230 /* Send the command for reading device ID */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003231 chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003232 /* Read manufacturer and device IDs */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003233 if (nand_maf_id != chip->read_byte(mtd) ||
Florian Fainellid1e1f4e2010-08-30 18:32:24 +02003234 nand_dev_id != chip->read_byte(mtd))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003235 break;
3236 }
3237 if (i > 1)
Brian Norris9a4d4d62011-07-19 10:06:07 -07003238 pr_info("%d NAND chips detected\n", i);
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00003239
Linus Torvalds1da177e2005-04-16 15:20:36 -07003240 /* Store the number of chips and calc total size for mtd */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003241 chip->numchips = i;
3242 mtd->size = i * chip->chipsize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003243
David Woodhouse3b85c322006-09-25 17:06:53 +01003244 return 0;
3245}
Florian Fainelli7351d3a2010-09-07 13:23:45 +02003246EXPORT_SYMBOL(nand_scan_ident);
David Woodhouse3b85c322006-09-25 17:06:53 +01003247
3248
3249/**
3250 * nand_scan_tail - [NAND Interface] Scan for the NAND device
Brian Norris8b6e50c2011-05-25 14:59:01 -07003251 * @mtd: MTD device structure
David Woodhouse3b85c322006-09-25 17:06:53 +01003252 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07003253 * This is the second phase of the normal nand_scan() function. It fills out
3254 * all the uninitialized function pointers with the defaults and scans for a
3255 * bad block table if appropriate.
David Woodhouse3b85c322006-09-25 17:06:53 +01003256 */
3257int nand_scan_tail(struct mtd_info *mtd)
3258{
3259 int i;
3260 struct nand_chip *chip = mtd->priv;
3261
David Woodhouse4bf63fc2006-09-25 17:08:04 +01003262 if (!(chip->options & NAND_OWN_BUFFERS))
3263 chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL);
3264 if (!chip->buffers)
3265 return -ENOMEM;
3266
David Woodhouse7dcdcbef2006-10-21 17:09:53 +01003267 /* Set the internal oob buffer location, just after the page data */
David Woodhouse784f4d52006-10-22 01:47:45 +01003268 chip->oob_poi = chip->buffers->databuf + mtd->writesize;
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003269
3270 /*
Brian Norris8b6e50c2011-05-25 14:59:01 -07003271 * If no default placement scheme is given, select an appropriate one.
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003272 */
Ivan Djelic193bd402011-03-11 11:05:33 +01003273 if (!chip->ecc.layout && (chip->ecc.mode != NAND_ECC_SOFT_BCH)) {
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00003274 switch (mtd->oobsize) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003275 case 8:
Thomas Gleixner5bd34c02006-05-27 22:16:10 +02003276 chip->ecc.layout = &nand_oob_8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003277 break;
3278 case 16:
Thomas Gleixner5bd34c02006-05-27 22:16:10 +02003279 chip->ecc.layout = &nand_oob_16;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003280 break;
3281 case 64:
Thomas Gleixner5bd34c02006-05-27 22:16:10 +02003282 chip->ecc.layout = &nand_oob_64;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003283 break;
Thomas Gleixner81ec5362007-12-12 17:27:03 +01003284 case 128:
3285 chip->ecc.layout = &nand_oob_128;
3286 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003287 default:
Brian Norrisd0370212011-07-19 10:06:08 -07003288 pr_warn("No oob scheme defined for oobsize %d\n",
3289 mtd->oobsize);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003290 BUG();
3291 }
3292 }
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00003293
David Woodhouse956e9442006-09-25 17:12:39 +01003294 if (!chip->write_page)
3295 chip->write_page = nand_write_page;
3296
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003297 /*
Brian Norris8b6e50c2011-05-25 14:59:01 -07003298 * Check ECC mode, default to software if 3byte/512byte hardware ECC is
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003299 * selected and we have 256 byte pagesize fallback to software ECC
David Woodhousee0c7d762006-05-13 18:07:53 +01003300 */
David Woodhouse956e9442006-09-25 17:12:39 +01003301
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003302 switch (chip->ecc.mode) {
Sneha Narnakaje6e0cb132009-09-18 12:51:47 -07003303 case NAND_ECC_HW_OOB_FIRST:
3304 /* Similar to NAND_ECC_HW, but a separate read_page handle */
3305 if (!chip->ecc.calculate || !chip->ecc.correct ||
3306 !chip->ecc.hwctl) {
Brian Norris9a4d4d62011-07-19 10:06:07 -07003307 pr_warn("No ECC functions supplied; "
Brian Norrisd0370212011-07-19 10:06:08 -07003308 "hardware ECC not possible\n");
Sneha Narnakaje6e0cb132009-09-18 12:51:47 -07003309 BUG();
3310 }
3311 if (!chip->ecc.read_page)
3312 chip->ecc.read_page = nand_read_page_hwecc_oob_first;
3313
Thomas Gleixner6dfc6d22006-05-23 12:00:46 +02003314 case NAND_ECC_HW:
Brian Norris8b6e50c2011-05-25 14:59:01 -07003315 /* Use standard hwecc read page function? */
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02003316 if (!chip->ecc.read_page)
3317 chip->ecc.read_page = nand_read_page_hwecc;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02003318 if (!chip->ecc.write_page)
3319 chip->ecc.write_page = nand_write_page_hwecc;
David Brownell52ff49d2009-03-04 12:01:36 -08003320 if (!chip->ecc.read_page_raw)
3321 chip->ecc.read_page_raw = nand_read_page_raw;
3322 if (!chip->ecc.write_page_raw)
3323 chip->ecc.write_page_raw = nand_write_page_raw;
Thomas Gleixner7bc33122006-06-20 20:05:05 +02003324 if (!chip->ecc.read_oob)
3325 chip->ecc.read_oob = nand_read_oob_std;
3326 if (!chip->ecc.write_oob)
3327 chip->ecc.write_oob = nand_write_oob_std;
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02003328
Thomas Gleixner6dfc6d22006-05-23 12:00:46 +02003329 case NAND_ECC_HW_SYNDROME:
Scott Wood78b65172007-12-13 11:15:28 -06003330 if ((!chip->ecc.calculate || !chip->ecc.correct ||
3331 !chip->ecc.hwctl) &&
3332 (!chip->ecc.read_page ||
Scott Wood1c45f602008-01-16 10:36:03 -06003333 chip->ecc.read_page == nand_read_page_hwecc ||
Scott Wood78b65172007-12-13 11:15:28 -06003334 !chip->ecc.write_page ||
Scott Wood1c45f602008-01-16 10:36:03 -06003335 chip->ecc.write_page == nand_write_page_hwecc)) {
Brian Norris9a4d4d62011-07-19 10:06:07 -07003336 pr_warn("No ECC functions supplied; "
Brian Norrisd0370212011-07-19 10:06:08 -07003337 "hardware ECC not possible\n");
Thomas Gleixner6dfc6d22006-05-23 12:00:46 +02003338 BUG();
3339 }
Brian Norris8b6e50c2011-05-25 14:59:01 -07003340 /* Use standard syndrome read/write page function? */
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02003341 if (!chip->ecc.read_page)
3342 chip->ecc.read_page = nand_read_page_syndrome;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02003343 if (!chip->ecc.write_page)
3344 chip->ecc.write_page = nand_write_page_syndrome;
David Brownell52ff49d2009-03-04 12:01:36 -08003345 if (!chip->ecc.read_page_raw)
3346 chip->ecc.read_page_raw = nand_read_page_raw_syndrome;
3347 if (!chip->ecc.write_page_raw)
3348 chip->ecc.write_page_raw = nand_write_page_raw_syndrome;
Thomas Gleixner7bc33122006-06-20 20:05:05 +02003349 if (!chip->ecc.read_oob)
3350 chip->ecc.read_oob = nand_read_oob_syndrome;
3351 if (!chip->ecc.write_oob)
3352 chip->ecc.write_oob = nand_write_oob_syndrome;
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02003353
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003354 if (mtd->writesize >= chip->ecc.size)
Thomas Gleixner6dfc6d22006-05-23 12:00:46 +02003355 break;
Brian Norris9a4d4d62011-07-19 10:06:07 -07003356 pr_warn("%d byte HW ECC not possible on "
Brian Norrisd0370212011-07-19 10:06:08 -07003357 "%d byte page size, fallback to SW ECC\n",
3358 chip->ecc.size, mtd->writesize);
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003359 chip->ecc.mode = NAND_ECC_SOFT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003360
Thomas Gleixner6dfc6d22006-05-23 12:00:46 +02003361 case NAND_ECC_SOFT:
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003362 chip->ecc.calculate = nand_calculate_ecc;
3363 chip->ecc.correct = nand_correct_data;
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02003364 chip->ecc.read_page = nand_read_page_swecc;
Alexey Korolev3d459552008-05-15 17:23:18 +01003365 chip->ecc.read_subpage = nand_read_subpage;
Thomas Gleixnerf75e5092006-05-26 18:52:08 +02003366 chip->ecc.write_page = nand_write_page_swecc;
David Brownell52ff49d2009-03-04 12:01:36 -08003367 chip->ecc.read_page_raw = nand_read_page_raw;
3368 chip->ecc.write_page_raw = nand_write_page_raw;
Thomas Gleixner7bc33122006-06-20 20:05:05 +02003369 chip->ecc.read_oob = nand_read_oob_std;
3370 chip->ecc.write_oob = nand_write_oob_std;
Singh, Vimal9a732902008-12-12 00:10:57 +00003371 if (!chip->ecc.size)
3372 chip->ecc.size = 256;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003373 chip->ecc.bytes = 3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003374 break;
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00003375
Ivan Djelic193bd402011-03-11 11:05:33 +01003376 case NAND_ECC_SOFT_BCH:
3377 if (!mtd_nand_has_bch()) {
Brian Norris9a4d4d62011-07-19 10:06:07 -07003378 pr_warn("CONFIG_MTD_ECC_BCH not enabled\n");
Ivan Djelic193bd402011-03-11 11:05:33 +01003379 BUG();
3380 }
3381 chip->ecc.calculate = nand_bch_calculate_ecc;
3382 chip->ecc.correct = nand_bch_correct_data;
3383 chip->ecc.read_page = nand_read_page_swecc;
3384 chip->ecc.read_subpage = nand_read_subpage;
3385 chip->ecc.write_page = nand_write_page_swecc;
3386 chip->ecc.read_page_raw = nand_read_page_raw;
3387 chip->ecc.write_page_raw = nand_write_page_raw;
3388 chip->ecc.read_oob = nand_read_oob_std;
3389 chip->ecc.write_oob = nand_write_oob_std;
3390 /*
3391 * Board driver should supply ecc.size and ecc.bytes values to
3392 * select how many bits are correctable; see nand_bch_init()
Brian Norris8b6e50c2011-05-25 14:59:01 -07003393 * for details. Otherwise, default to 4 bits for large page
3394 * devices.
Ivan Djelic193bd402011-03-11 11:05:33 +01003395 */
3396 if (!chip->ecc.size && (mtd->oobsize >= 64)) {
3397 chip->ecc.size = 512;
3398 chip->ecc.bytes = 7;
3399 }
3400 chip->ecc.priv = nand_bch_init(mtd,
3401 chip->ecc.size,
3402 chip->ecc.bytes,
3403 &chip->ecc.layout);
3404 if (!chip->ecc.priv) {
Brian Norris9a4d4d62011-07-19 10:06:07 -07003405 pr_warn("BCH ECC initialization failed!\n");
Ivan Djelic193bd402011-03-11 11:05:33 +01003406 BUG();
3407 }
3408 break;
3409
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00003410 case NAND_ECC_NONE:
Brian Norris9a4d4d62011-07-19 10:06:07 -07003411 pr_warn("NAND_ECC_NONE selected by board driver. "
Brian Norrisd0370212011-07-19 10:06:08 -07003412 "This is not recommended!\n");
Thomas Gleixner8593fbc2006-05-29 03:26:58 +02003413 chip->ecc.read_page = nand_read_page_raw;
3414 chip->ecc.write_page = nand_write_page_raw;
Thomas Gleixner7bc33122006-06-20 20:05:05 +02003415 chip->ecc.read_oob = nand_read_oob_std;
David Brownell52ff49d2009-03-04 12:01:36 -08003416 chip->ecc.read_page_raw = nand_read_page_raw;
3417 chip->ecc.write_page_raw = nand_write_page_raw;
Thomas Gleixner7bc33122006-06-20 20:05:05 +02003418 chip->ecc.write_oob = nand_write_oob_std;
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003419 chip->ecc.size = mtd->writesize;
3420 chip->ecc.bytes = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003421 break;
David Woodhouse956e9442006-09-25 17:12:39 +01003422
Linus Torvalds1da177e2005-04-16 15:20:36 -07003423 default:
Brian Norrisd0370212011-07-19 10:06:08 -07003424 pr_warn("Invalid NAND_ECC_MODE %d\n", chip->ecc.mode);
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00003425 BUG();
3426 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003427
Brian Norris9ce244b2011-08-30 18:45:37 -07003428 /* For many systems, the standard OOB write also works for raw */
Brian Norrisc46f6482011-08-30 18:45:38 -07003429 if (!chip->ecc.read_oob_raw)
3430 chip->ecc.read_oob_raw = chip->ecc.read_oob;
Brian Norris9ce244b2011-08-30 18:45:37 -07003431 if (!chip->ecc.write_oob_raw)
3432 chip->ecc.write_oob_raw = chip->ecc.write_oob;
3433
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003434 /*
Thomas Gleixner5bd34c02006-05-27 22:16:10 +02003435 * The number of bytes available for a client to place data into
Brian Norris8b6e50c2011-05-25 14:59:01 -07003436 * the out of band area.
Thomas Gleixner5bd34c02006-05-27 22:16:10 +02003437 */
3438 chip->ecc.layout->oobavail = 0;
David Brownell81d19b02009-04-21 19:51:20 -07003439 for (i = 0; chip->ecc.layout->oobfree[i].length
3440 && i < ARRAY_SIZE(chip->ecc.layout->oobfree); i++)
Thomas Gleixner5bd34c02006-05-27 22:16:10 +02003441 chip->ecc.layout->oobavail +=
3442 chip->ecc.layout->oobfree[i].length;
Vitaly Wool1f922672007-03-06 16:56:34 +03003443 mtd->oobavail = chip->ecc.layout->oobavail;
Thomas Gleixner5bd34c02006-05-27 22:16:10 +02003444
3445 /*
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003446 * Set the number of read / write steps for one page depending on ECC
Brian Norris8b6e50c2011-05-25 14:59:01 -07003447 * mode.
Thomas Gleixner7aa65bf2006-05-23 11:54:38 +02003448 */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003449 chip->ecc.steps = mtd->writesize / chip->ecc.size;
Florian Fainellif8ac0412010-09-07 13:23:43 +02003450 if (chip->ecc.steps * chip->ecc.size != mtd->writesize) {
Brian Norris9a4d4d62011-07-19 10:06:07 -07003451 pr_warn("Invalid ECC parameters\n");
Thomas Gleixner6dfc6d22006-05-23 12:00:46 +02003452 BUG();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003453 }
Thomas Gleixnerf5bbdac2006-05-25 10:07:16 +02003454 chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00003455
Brian Norris8b6e50c2011-05-25 14:59:01 -07003456 /* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
Thomas Gleixner29072b92006-09-28 15:38:36 +02003457 if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
3458 !(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
Florian Fainellif8ac0412010-09-07 13:23:43 +02003459 switch (chip->ecc.steps) {
Thomas Gleixner29072b92006-09-28 15:38:36 +02003460 case 2:
3461 mtd->subpage_sft = 1;
3462 break;
3463 case 4:
3464 case 8:
Thomas Gleixner81ec5362007-12-12 17:27:03 +01003465 case 16:
Thomas Gleixner29072b92006-09-28 15:38:36 +02003466 mtd->subpage_sft = 2;
3467 break;
3468 }
3469 }
3470 chip->subpagesize = mtd->writesize >> mtd->subpage_sft;
3471
Thomas Gleixner04bbd0e2006-05-25 09:45:29 +02003472 /* Initialize state */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003473 chip->state = FL_READY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003474
3475 /* De-select the device */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003476 chip->select_chip(mtd, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003477
3478 /* Invalidate the pagebuffer reference */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003479 chip->pagebuf = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003480
3481 /* Fill in remaining MTD driver data */
3482 mtd->type = MTD_NANDFLASH;
Maxim Levitsky93edbad2010-02-22 20:39:40 +02003483 mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :
3484 MTD_CAP_NANDFLASH;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003485 mtd->erase = nand_erase;
3486 mtd->point = NULL;
3487 mtd->unpoint = NULL;
3488 mtd->read = nand_read;
3489 mtd->write = nand_write;
Simon Kagstrom2af7c652009-10-05 15:55:52 +02003490 mtd->panic_write = panic_nand_write;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003491 mtd->read_oob = nand_read_oob;
3492 mtd->write_oob = nand_write_oob;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003493 mtd->sync = nand_sync;
3494 mtd->lock = NULL;
3495 mtd->unlock = NULL;
Vitaly Wool962034f2005-09-15 14:58:53 +01003496 mtd->suspend = nand_suspend;
3497 mtd->resume = nand_resume;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003498 mtd->block_isbad = nand_block_isbad;
3499 mtd->block_markbad = nand_block_markbad;
Anatolij Gustschincbcab652010-12-16 23:42:16 +01003500 mtd->writebufsize = mtd->writesize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003501
Thomas Gleixner5bd34c02006-05-27 22:16:10 +02003502 /* propagate ecc.layout to mtd_info */
3503 mtd->ecclayout = chip->ecc.layout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003504
Thomas Gleixner0040bf32005-02-09 12:20:00 +00003505 /* Check, if we should skip the bad block table scan */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003506 if (chip->options & NAND_SKIP_BBTSCAN)
Thomas Gleixner0040bf32005-02-09 12:20:00 +00003507 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003508
3509 /* Build bad block table */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003510 return chip->scan_bbt(mtd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003511}
Florian Fainelli7351d3a2010-09-07 13:23:45 +02003512EXPORT_SYMBOL(nand_scan_tail);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003513
Brian Norris8b6e50c2011-05-25 14:59:01 -07003514/*
3515 * is_module_text_address() isn't exported, and it's mostly a pointless
Florian Fainelli7351d3a2010-09-07 13:23:45 +02003516 * test if this is a module _anyway_ -- they'd have to try _really_ hard
Brian Norris8b6e50c2011-05-25 14:59:01 -07003517 * to call us from in-kernel code if the core NAND support is modular.
3518 */
David Woodhouse3b85c322006-09-25 17:06:53 +01003519#ifdef MODULE
3520#define caller_is_module() (1)
3521#else
3522#define caller_is_module() \
Rusty Russella6e6abd2009-03-31 13:05:31 -06003523 is_module_text_address((unsigned long)__builtin_return_address(0))
David Woodhouse3b85c322006-09-25 17:06:53 +01003524#endif
3525
3526/**
3527 * nand_scan - [NAND Interface] Scan for the NAND device
Brian Norris8b6e50c2011-05-25 14:59:01 -07003528 * @mtd: MTD device structure
3529 * @maxchips: number of chips to scan for
David Woodhouse3b85c322006-09-25 17:06:53 +01003530 *
Brian Norris8b6e50c2011-05-25 14:59:01 -07003531 * This fills out all the uninitialized function pointers with the defaults.
3532 * The flash ID is read and the mtd/chip structures are filled with the
3533 * appropriate values. The mtd->owner field must be set to the module of the
3534 * caller.
David Woodhouse3b85c322006-09-25 17:06:53 +01003535 */
3536int nand_scan(struct mtd_info *mtd, int maxchips)
3537{
3538 int ret;
3539
3540 /* Many callers got this wrong, so check for it for a while... */
3541 if (!mtd->owner && caller_is_module()) {
Brian Norrisd0370212011-07-19 10:06:08 -07003542 pr_crit("%s called with NULL mtd->owner!\n", __func__);
David Woodhouse3b85c322006-09-25 17:06:53 +01003543 BUG();
3544 }
3545
David Woodhouse5e81e882010-02-26 18:32:56 +00003546 ret = nand_scan_ident(mtd, maxchips, NULL);
David Woodhouse3b85c322006-09-25 17:06:53 +01003547 if (!ret)
3548 ret = nand_scan_tail(mtd);
3549 return ret;
3550}
Florian Fainelli7351d3a2010-09-07 13:23:45 +02003551EXPORT_SYMBOL(nand_scan);
David Woodhouse3b85c322006-09-25 17:06:53 +01003552
Linus Torvalds1da177e2005-04-16 15:20:36 -07003553/**
Thomas Gleixner61b03bd2005-11-07 11:15:49 +00003554 * nand_release - [NAND Interface] Free resources held by the NAND device
Brian Norris8b6e50c2011-05-25 14:59:01 -07003555 * @mtd: MTD device structure
3556 */
David Woodhousee0c7d762006-05-13 18:07:53 +01003557void nand_release(struct mtd_info *mtd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003558{
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003559 struct nand_chip *chip = mtd->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003560
Ivan Djelic193bd402011-03-11 11:05:33 +01003561 if (chip->ecc.mode == NAND_ECC_SOFT_BCH)
3562 nand_bch_free((struct nand_bch_control *)chip->ecc.priv);
3563
Jamie Iles5ffcaf32011-05-23 10:22:46 +01003564 mtd_device_unregister(mtd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003565
Jesper Juhlfa671642005-11-07 01:01:27 -08003566 /* Free bad block table memory */
Thomas Gleixnerace4dfe2006-05-24 12:07:37 +02003567 kfree(chip->bbt);
David Woodhouse4bf63fc2006-09-25 17:08:04 +01003568 if (!(chip->options & NAND_OWN_BUFFERS))
3569 kfree(chip->buffers);
Brian Norris58373ff2010-07-15 12:15:44 -07003570
3571 /* Free bad block descriptor memory */
3572 if (chip->badblock_pattern && chip->badblock_pattern->options
3573 & NAND_BBT_DYNAMICSTRUCT)
3574 kfree(chip->badblock_pattern);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003575}
David Woodhousee0c7d762006-05-13 18:07:53 +01003576EXPORT_SYMBOL_GPL(nand_release);
Richard Purdie8fe833c2006-03-31 02:31:14 -08003577
3578static int __init nand_base_init(void)
3579{
3580 led_trigger_register_simple("nand-disk", &nand_led_trigger);
3581 return 0;
3582}
3583
3584static void __exit nand_base_exit(void)
3585{
3586 led_trigger_unregister_simple(nand_led_trigger);
3587}
3588
3589module_init(nand_base_init);
3590module_exit(nand_base_exit);
3591
David Woodhousee0c7d762006-05-13 18:07:53 +01003592MODULE_LICENSE("GPL");
Florian Fainelli7351d3a2010-09-07 13:23:45 +02003593MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>");
3594MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
David Woodhousee0c7d762006-05-13 18:07:53 +01003595MODULE_DESCRIPTION("Generic NAND flash driver code");