]> git.ipfire.org Git - people/ms/u-boot.git/blame - drivers/mtd/nand/nand_base.c
ubi: Remove flash selection parameter (nor|nand|onenand) from "ubi part"
[people/ms/u-boot.git] / drivers / mtd / nand / nand_base.c
CommitLineData
932394ac
WD
1/*
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.
ac7eb8a3 8 *
932394ac 9 * Additional technical information is available on
c45912d8 10 * http://www.linux-mtd.infradead.org/doc/nand.html
ac7eb8a3 11 *
932394ac 12 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
cfa460ad 13 * 2002-2006 Thomas Gleixner (tglx@linutronix.de)
932394ac 14 *
cfa460ad 15 * Credits:
ac7eb8a3
WD
16 * David Woodhouse for adding multichip support
17 *
932394ac
WD
18 * Aleph One Ltd. and Toby Churchill Ltd. for supporting the
19 * rework for 2K page size chips
20 *
cfa460ad 21 * TODO:
932394ac
WD
22 * Enable cached programming for 2k page size chips
23 * Check, if mtd->ecctype should be set to MTD_ECC_HW
24 * if we have HW ecc support.
25 * The AG-AND chips have nice features for speed improvement,
26 * which are not supported yet. Read / program 4 pages in one go.
c45912d8 27 * BBT table is not serialized, has to be fixed
932394ac 28 *
932394ac
WD
29 * 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
35/* XXX U-BOOT XXX */
36#if 0
cfa460ad 37#include <linux/module.h>
932394ac
WD
38#include <linux/delay.h>
39#include <linux/errno.h>
cfa460ad 40#include <linux/err.h>
932394ac
WD
41#include <linux/sched.h>
42#include <linux/slab.h>
43#include <linux/types.h>
44#include <linux/mtd/mtd.h>
45#include <linux/mtd/nand.h>
46#include <linux/mtd/nand_ecc.h>
47#include <linux/mtd/compatmac.h>
48#include <linux/interrupt.h>
49#include <linux/bitops.h>
cfa460ad 50#include <linux/leds.h>
932394ac
WD
51#include <asm/io.h>
52
53#ifdef CONFIG_MTD_PARTITIONS
54#include <linux/mtd/partitions.h>
55#endif
56
ac7eb8a3 57#endif
932394ac
WD
58
59#include <common.h>
addb2e16 60
cfa460ad
WJ
61#define ENOTSUPP 524 /* Operation is not supported */
62
932394ac
WD
63#include <malloc.h>
64#include <watchdog.h>
cfa460ad 65#include <linux/err.h>
932394ac
WD
66#include <linux/mtd/compat.h>
67#include <linux/mtd/mtd.h>
68#include <linux/mtd/nand.h>
69#include <linux/mtd/nand_ecc.h>
70
71#include <asm/io.h>
72#include <asm/errno.h>
73
74#ifdef CONFIG_JFFS2_NAND
75#include <jffs2/jffs2.h>
76#endif
77
8da60128
PT
78/*
79 * CONFIG_SYS_NAND_RESET_CNT is used as a timeout mechanism when resetting
80 * a flash. NAND flash is initialized prior to interrupts so standard timers
81 * can't be used. CONFIG_SYS_NAND_RESET_CNT should be set to a value
82 * which is greater than (max NAND reset time / NAND status read time).
83 * A conservative default of 200000 (500 us / 25 ns) is used as a default.
84 */
85#ifndef CONFIG_SYS_NAND_RESET_CNT
86#define CONFIG_SYS_NAND_RESET_CNT 200000
87#endif
88
932394ac 89/* Define default oob placement schemes for large and small page devices */
cfa460ad 90static struct nand_ecclayout nand_oob_8 = {
932394ac
WD
91 .eccbytes = 3,
92 .eccpos = {0, 1, 2},
cfa460ad
WJ
93 .oobfree = {
94 {.offset = 3,
95 .length = 2},
96 {.offset = 6,
97 .length = 2}}
932394ac
WD
98};
99
cfa460ad 100static struct nand_ecclayout nand_oob_16 = {
932394ac
WD
101 .eccbytes = 6,
102 .eccpos = {0, 1, 2, 3, 6, 7},
cfa460ad
WJ
103 .oobfree = {
104 {.offset = 8,
105 . length = 8}}
932394ac
WD
106};
107
cfa460ad 108static struct nand_ecclayout nand_oob_64 = {
932394ac
WD
109 .eccbytes = 24,
110 .eccpos = {
cfa460ad
WJ
111 40, 41, 42, 43, 44, 45, 46, 47,
112 48, 49, 50, 51, 52, 53, 54, 55,
113 56, 57, 58, 59, 60, 61, 62, 63},
114 .oobfree = {
115 {.offset = 2,
116 .length = 38}}
932394ac
WD
117};
118
cfa460ad 119static struct nand_ecclayout nand_oob_128 = {
248ae5cf
SP
120 .eccbytes = 48,
121 .eccpos = {
cfa460ad
WJ
122 80, 81, 82, 83, 84, 85, 86, 87,
123 88, 89, 90, 91, 92, 93, 94, 95,
124 96, 97, 98, 99, 100, 101, 102, 103,
125 104, 105, 106, 107, 108, 109, 110, 111,
126 112, 113, 114, 115, 116, 117, 118, 119,
127 120, 121, 122, 123, 124, 125, 126, 127},
128 .oobfree = {
129 {.offset = 2,
130 .length = 78}}
932394ac
WD
131};
132
cfa460ad
WJ
133
134static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd,
135 int new_state);
136
137static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
138 struct mtd_oob_ops *ops);
139
140static int nand_wait(struct mtd_info *mtd, struct nand_chip *this);
248ae5cf 141
932394ac 142/*
c45912d8 143 * For devices which display every fart in the system on a separate LED. Is
cfa460ad 144 * compiled away when LED support is disabled.
932394ac 145 */
932394ac
WD
146/* XXX U-BOOT XXX */
147#if 0
cfa460ad 148DEFINE_LED_TRIGGER(nand_led_trigger);
932394ac 149#endif
ac7eb8a3 150
932394ac
WD
151/**
152 * nand_release_device - [GENERIC] release chip
153 * @mtd: MTD device structure
ac7eb8a3
WD
154 *
155 * Deselect, release chip lock and wake up anyone waiting on the device
932394ac
WD
156 */
157/* XXX U-BOOT XXX */
158#if 0
cfa460ad 159static void nand_release_device(struct mtd_info *mtd)
932394ac 160{
cfa460ad 161 struct nand_chip *chip = mtd->priv;
932394ac
WD
162
163 /* De-select the NAND device */
cfa460ad
WJ
164 chip->select_chip(mtd, -1);
165
166 /* Release the controller and the chip */
167 spin_lock(&chip->controller->lock);
168 chip->controller->active = NULL;
169 chip->state = FL_READY;
170 wake_up(&chip->controller->wq);
171 spin_unlock(&chip->controller->lock);
932394ac
WD
172}
173#else
8e9655f8
WD
174static void nand_release_device (struct mtd_info *mtd)
175{
176 struct nand_chip *this = mtd->priv;
177 this->select_chip(mtd, -1); /* De-select the NAND device */
178}
932394ac
WD
179#endif
180
181/**
182 * nand_read_byte - [DEFAULT] read one byte from the chip
183 * @mtd: MTD device structure
184 *
185 * Default read function for 8bit buswith
186 */
cfa460ad 187static uint8_t nand_read_byte(struct mtd_info *mtd)
932394ac 188{
cfa460ad
WJ
189 struct nand_chip *chip = mtd->priv;
190 return readb(chip->IO_ADDR_R);
932394ac
WD
191}
192
193/**
194 * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
195 * @mtd: MTD device structure
196 *
ac7eb8a3 197 * Default read function for 16bit buswith with
932394ac
WD
198 * endianess conversion
199 */
cfa460ad 200static uint8_t nand_read_byte16(struct mtd_info *mtd)
932394ac 201{
cfa460ad
WJ
202 struct nand_chip *chip = mtd->priv;
203 return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R));
932394ac
WD
204}
205
206/**
207 * nand_read_word - [DEFAULT] read one word from the chip
208 * @mtd: MTD device structure
209 *
ac7eb8a3 210 * Default read function for 16bit buswith without
932394ac
WD
211 * endianess conversion
212 */
213static u16 nand_read_word(struct mtd_info *mtd)
214{
cfa460ad
WJ
215 struct nand_chip *chip = mtd->priv;
216 return readw(chip->IO_ADDR_R);
932394ac
WD
217}
218
219/**
220 * nand_select_chip - [DEFAULT] control CE line
221 * @mtd: MTD device structure
cfa460ad 222 * @chipnr: chipnumber to select, -1 for deselect
932394ac
WD
223 *
224 * Default select function for 1 chip devices.
225 */
cfa460ad 226static void nand_select_chip(struct mtd_info *mtd, int chipnr)
932394ac 227{
cfa460ad
WJ
228 struct nand_chip *chip = mtd->priv;
229
230 switch (chipnr) {
932394ac 231 case -1:
cfa460ad 232 chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
932394ac
WD
233 break;
234 case 0:
932394ac
WD
235 break;
236
237 default:
238 BUG();
239 }
240}
241
242/**
243 * nand_write_buf - [DEFAULT] write buffer to chip
244 * @mtd: MTD device structure
245 * @buf: data buffer
246 * @len: number of bytes to write
247 *
248 * Default write function for 8bit buswith
249 */
cfa460ad 250static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
932394ac
WD
251{
252 int i;
cfa460ad 253 struct nand_chip *chip = mtd->priv;
932394ac 254
cfa460ad
WJ
255 for (i = 0; i < len; i++)
256 writeb(buf[i], chip->IO_ADDR_W);
932394ac
WD
257}
258
259/**
ac7eb8a3 260 * nand_read_buf - [DEFAULT] read chip data into buffer
932394ac
WD
261 * @mtd: MTD device structure
262 * @buf: buffer to store date
263 * @len: number of bytes to read
264 *
265 * Default read function for 8bit buswith
266 */
cfa460ad 267static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
932394ac
WD
268{
269 int i;
cfa460ad 270 struct nand_chip *chip = mtd->priv;
932394ac 271
cfa460ad
WJ
272 for (i = 0; i < len; i++)
273 buf[i] = readb(chip->IO_ADDR_R);
932394ac
WD
274}
275
276/**
ac7eb8a3 277 * nand_verify_buf - [DEFAULT] Verify chip data against buffer
932394ac
WD
278 * @mtd: MTD device structure
279 * @buf: buffer containing the data to compare
280 * @len: number of bytes to compare
281 *
282 * Default verify function for 8bit buswith
283 */
cfa460ad 284static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
932394ac
WD
285{
286 int i;
cfa460ad 287 struct nand_chip *chip = mtd->priv;
932394ac 288
cfa460ad
WJ
289 for (i = 0; i < len; i++)
290 if (buf[i] != readb(chip->IO_ADDR_R))
932394ac 291 return -EFAULT;
932394ac
WD
292 return 0;
293}
294
295/**
296 * nand_write_buf16 - [DEFAULT] write buffer to chip
297 * @mtd: MTD device structure
298 * @buf: data buffer
299 * @len: number of bytes to write
300 *
301 * Default write function for 16bit buswith
302 */
cfa460ad 303static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
932394ac
WD
304{
305 int i;
cfa460ad 306 struct nand_chip *chip = mtd->priv;
932394ac
WD
307 u16 *p = (u16 *) buf;
308 len >>= 1;
ac7eb8a3 309
cfa460ad
WJ
310 for (i = 0; i < len; i++)
311 writew(p[i], chip->IO_ADDR_W);
ac7eb8a3 312
932394ac
WD
313}
314
315/**
ac7eb8a3 316 * nand_read_buf16 - [DEFAULT] read chip data into buffer
932394ac
WD
317 * @mtd: MTD device structure
318 * @buf: buffer to store date
319 * @len: number of bytes to read
320 *
321 * Default read function for 16bit buswith
322 */
cfa460ad 323static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
932394ac
WD
324{
325 int i;
cfa460ad 326 struct nand_chip *chip = mtd->priv;
932394ac
WD
327 u16 *p = (u16 *) buf;
328 len >>= 1;
329
cfa460ad
WJ
330 for (i = 0; i < len; i++)
331 p[i] = readw(chip->IO_ADDR_R);
932394ac
WD
332}
333
334/**
ac7eb8a3 335 * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
932394ac
WD
336 * @mtd: MTD device structure
337 * @buf: buffer containing the data to compare
338 * @len: number of bytes to compare
339 *
340 * Default verify function for 16bit buswith
341 */
cfa460ad 342static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
932394ac
WD
343{
344 int i;
cfa460ad 345 struct nand_chip *chip = mtd->priv;
932394ac
WD
346 u16 *p = (u16 *) buf;
347 len >>= 1;
348
cfa460ad
WJ
349 for (i = 0; i < len; i++)
350 if (p[i] != readw(chip->IO_ADDR_R))
932394ac
WD
351 return -EFAULT;
352
353 return 0;
354}
355
356/**
357 * nand_block_bad - [DEFAULT] Read bad block marker from the chip
358 * @mtd: MTD device structure
359 * @ofs: offset from device start
360 * @getchip: 0, if the chip is already selected
361 *
ac7eb8a3 362 * Check, if the block is bad.
932394ac
WD
363 */
364static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
365{
366 int page, chipnr, res = 0;
cfa460ad 367 struct nand_chip *chip = mtd->priv;
932394ac
WD
368 u16 bad;
369
cfa460ad 370 page = (int)(ofs >> chip->page_shift) & chip->pagemask;
a7988659 371
932394ac 372 if (getchip) {
cfa460ad 373 chipnr = (int)(ofs >> chip->chip_shift);
932394ac 374
cfa460ad 375 nand_get_device(chip, mtd, FL_READING);
932394ac
WD
376
377 /* Select the NAND device */
cfa460ad 378 chip->select_chip(mtd, chipnr);
a7988659 379 }
932394ac 380
cfa460ad
WJ
381 if (chip->options & NAND_BUSWIDTH_16) {
382 chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos & 0xFE,
383 page);
384 bad = cpu_to_le16(chip->read_word(mtd));
385 if (chip->badblockpos & 0x1)
386 bad >>= 8;
932394ac
WD
387 if ((bad & 0xFF) != 0xff)
388 res = 1;
389 } else {
cfa460ad
WJ
390 chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos, page);
391 if (chip->read_byte(mtd) != 0xff)
932394ac
WD
392 res = 1;
393 }
ac7eb8a3 394
cfa460ad 395 if (getchip)
932394ac 396 nand_release_device(mtd);
ac7eb8a3 397
932394ac
WD
398 return res;
399}
400
401/**
402 * nand_default_block_markbad - [DEFAULT] mark a block bad
403 * @mtd: MTD device structure
404 * @ofs: offset from device start
405 *
406 * This is the default implementation, which can be overridden by
407 * a hardware specific driver.
408*/
409static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
410{
cfa460ad
WJ
411 struct nand_chip *chip = mtd->priv;
412 uint8_t buf[2] = { 0, 0 };
413 int block, ret;
ac7eb8a3 414
932394ac 415 /* Get block number */
cfa460ad
WJ
416 block = (int)(ofs >> chip->bbt_erase_shift);
417 if (chip->bbt)
418 chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
932394ac
WD
419
420 /* Do we have a flash based bad block table ? */
cfa460ad
WJ
421 if (chip->options & NAND_USE_FLASH_BBT)
422 ret = nand_update_bbt(mtd, ofs);
423 else {
424 /* We write two bytes, so we dont have to mess with 16 bit
425 * access
426 */
c45912d8 427 nand_get_device(chip, mtd, FL_WRITING);
cfa460ad
WJ
428 ofs += mtd->oobsize;
429 chip->ops.len = chip->ops.ooblen = 2;
430 chip->ops.datbuf = NULL;
431 chip->ops.oobbuf = buf;
432 chip->ops.ooboffs = chip->badblockpos & ~0x01;
ac7eb8a3 433
cfa460ad 434 ret = nand_do_write_oob(mtd, ofs, &chip->ops);
c45912d8 435 nand_release_device(mtd);
cfa460ad
WJ
436 }
437 if (!ret)
438 mtd->ecc_stats.badblocks++;
c45912d8 439
cfa460ad 440 return ret;
932394ac
WD
441}
442
ac7eb8a3 443/**
932394ac
WD
444 * nand_check_wp - [GENERIC] check if the chip is write protected
445 * @mtd: MTD device structure
ac7eb8a3 446 * Check, if the device is write protected
932394ac 447 *
ac7eb8a3 448 * The function expects, that the device is already selected
932394ac 449 */
cfa460ad 450static int nand_check_wp(struct mtd_info *mtd)
932394ac 451{
cfa460ad 452 struct nand_chip *chip = mtd->priv;
932394ac 453 /* Check the WP bit */
cfa460ad
WJ
454 chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
455 return (chip->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
932394ac 456}